-package org.ibex.mail.filter;
-import org.ibex.mail.*;
+package org.ibex.mail;
/** generic superclass for processing elements that recieve a message and "usually" pass it on */
public class Filter {
public Message process(Message m) { return null; }
import java.net.*;
import java.io.*;
-// NOTE: always use Win32 line endings
-// hard line limit: 998 chars
-// soft line limit (suggested): 78 chars
-// header fields: ascii 33-126 (but no colon)
-// field body: anything ASCII except CRLF
+// soft line limit (suggested): 78 chars / hard line limit: 998 chars
// folded headers: can insert CRLF anywhere that whitespace appears (before the whitespace)
-// body needs CRLF; one or the other alone is not acceptable
// date/time parsing: see 3.3
// FEATURE: MIME RFC2045, 2046, 2049
public final Address envelopeFrom;
public final Address[] envelopeTo;
+ public Date arrival = null; // when the message first arrived at this machine
+
public void dump(OutputStream os) throws IOException {
Writer w = new OutputStreamWriter(os);
w.write(allHeaders);
}
if (s.indexOf(':') == -1) throw new Malformed("Header line does not contain colon: " + s);
key = s.substring(0, s.indexOf(':'));
+ for(int i=0; i<s.length(); i++)
+ if (s.charAt(i) < 33 || s.charAt(i) > 126)
+ throw new Malformed("Header key contains invalid character \"" + s.charAt(i) + "\"");
String val = s.substring(0, s.indexOf(':') + 1);
while(Character.isSpace(val.charAt(0))) val = val.substring(1);
}
private static final Random random = new Random();
+
+ public String summary() {
+ return
+ " Subject: " + m.subject + "\n" +
+ " EnvelopeFrom: " + m.envelopeFrom + "\n" +
+ " EnvelopeTo: " + m.envelopeTo + "\n" +
+ " MessageId: " + m.messageid;
+ }
+
+ public Message bounce(String reason) {
+ // use null-sender for error messages (don't send errors to the null addr)
+ // FIXME
+ return null;
+ }
}
-package org.ibex.mail.target;
-import org.ibex.mail.*;
+package org.ibex.mail;
import java.io.*;
import org.ibex.js.*;
package org.ibex.mail.protocol;
import org.ibex.mail.*;
-import org.ibex.mail.store.*;
import org.ibex.mail.target.*;
import java.io.*;
public class Incoming {
protected void accept(Message m) throws IOException, MailException {
- MessageStore.transcript.add(m); // currently, we write all inbound messages to the transcript
+ FileSystem.transcript.add(m); // currently, we write all inbound messages to the transcript
Target.root.accept(m);
}
}
package org.ibex.mail.protocol;
import org.ibex.mail.*;
-import org.ibex.mail.store.*;
import org.ibex.mail.target.*;
import org.ibex.util.*;
import java.net.*;
import java.io.*;
import java.util.*;
import java.text.*;
+import javax.naming.*;
+import javax.naming.directory.*;
public class SMTP extends MessageProtocol {
+ static { new Thread() { public void run() { Outgoing.runq(); } }.start(); }
public static String convdir = null;
public static void main(String[] s) throws Exception {
String logto = System.getProperty("ibex.mail.root", File.separatorChar + "var" + File.separatorChar + "org.ibex.mail");
public void handle(Socket s) { new Listener(s, "megacz.com").handleRequest(); }
+ // FEATURE: exponential backoff on retry time?
public static class Outgoing {
- // recommended retry interval is 30 minutes
- // give up after 4-5 days
- // should keep per-host success/failure so we don't retry on every message
- // exponential backoff on retry time?
- // check DNS resolvability as soon as domain is provided
- // only use implicit A-record if there are no MX-records
- // use null-sender for error messages (don't send errors to the null addr)
- // to prevent mail loops, drop messages with >100 Recieved headers
- private final org.ibex.util.Queue queue = new org.ibex.util.Queue(100);
- public static void send(Message m) { }
- public static void enqueue(Message m) { }
- public static void bounce(Message m, String reason) { }
- private void runq() {
- /*
- MessageStore store = MessageStore.root.slash("smtp").slash("outgoing");
+ private static final HashSet deadHosts = new HashSet();
+ private static final org.ibex.util.Queue queue = new org.ibex.util.Queue(100);
+ private static FileSystem store = FileSystem.root.slash("outgoing");
+
+ public static void send(Message m) {
+ if (m.traces.length >= 100) {
+ Log.warn("Message with " + m.traces.length + " trace hops; silently dropping\n" + m.summary());
+ return;
+ }
+ synchronized(Outgoing.class) {
+ store.add(m);
+ queue.append(m);
+ Outgoing.class.notify();
+ }
+ }
+
+ private static boolean attempt(Message m) {
+ InetAddress[] mx = getMailExchangerIPs(m.envelopeTo.host);
+ if (mx.length == 0) {
+ Log.warn("could not resolve " + m.envelopeTo.host + "; bouncing it\n" + m.summary());
+ send(m.bounce("could not resolve " + m.envelopeTo.host));
+ return true;
+ }
+ if (new Date().getTime() - m.arrival.getTime() > 1000 * 60 * 60 * 24 * 5) {
+ Log.warn("could not send message after 5 days; bouncing it\n" + m.summary());
+ send(m.bounce("could not send for 5 days"));
+ return true;
+ }
+ for(int i=0; i<mx.length; i++) {
+ if (deadHosts.contains(mx[i])) continue;
+ if (attempt(m, mx[i])) { queue.remove(m); return true; }
+ }
+ return false;
+ }
+
+ private static boolean attempt(Message m, InetAddress mx) {
+ try {
+ String conversationId = getConversation();
+ PrintWriter logf = new PrintWriter(new OutputStreamWriter(new FileOutputStream(convdir+File.separatorChar+cid)));
+ Log.setThreadAnnotation("[outgoing smtp: " + mx + " / " + cid + "] ");
+ Log.info(SMTP.Outgoing.class, "connecting...");
+ Socket s = new Socket(mx, 25);
+ Log.info(SMTP.Outgoing.class, "connected");
+ LineReader r = new LoggedLineReader(new InputStreamReader(conn.getInputStream()), logf);
+ PrintWriter w = new LoggedPrintWriter(new OutputStreamWriter(conn.getOutputStream()), logf);
+ check(r.readLine()); // banner
+ w.print("HELO " + vhost + "\r\n"); check(r.readLine());
+ w.print("MAIL FROM: " + m.envelopeFrom + "\r\n"); check(r.readLine());
+ w.print("RCPT TO: " + m.envelopeTo + "\r\n"); check(r.readLine());
+ w.print("DATA\r\n"); check(r.readLine());
+ w.print(m.body);
+ w.print(".\r\n");
+ check(r.readLine());
+ Log.info(SMTP.Outgoing.class, "message accepted by " + mx);
+ m.delete();
+ s.close();
+ return true;
+ } catch (Exception e) {
+ Log.warn(SMTP.Outgoing.class, "unable to send; error=" + e);
+ Log.warn(SMTP.Outgoing.class, e);
+ return false;
+ } finally {
+ Log.setThreadAnnotation("[outgoing smtp] ");
+ }
+ }
+
+ static void runq() {
+ Log.setThreadAnnotation("[outgoing smtp] ");
int[] outgoing = store.list();
+ Log.info("outgoing thread started; " + outgoing.length + " messages to send");
for(int i=0; i<outgoing.length; i++) queue.append(store.get(outgoing[i]));
while(true) {
- Message next = queue.remove(true);
- // FIXME
+ int num = queue.size();
+ for(int i=0; i<num; i++) {
+ Message next = queue.remove(true);
+ if (!attempt(next)) queue.append(next);
+ }
+ synchronized(Outgoing.class) {
+ Log.info("outgoing thread going to sleep");
+ Outgoing.class.wait(10 * 60 * 1000);
+ deadHosts.clear();
+ Log.info("outgoing thread woke up; " + queue.size() + " messages in queue");
+ }
}
- */
}
}
try {
conn.setSoTimeout(5 * 60 * 1000);
StringBuffer logMessage = new StringBuffer();
- String time = new SimpleDateFormat("yy.MMM.dd-hh:mm:ss").format(new Date());
- synchronized (SMTP.class) {
- if (lastTime != null && lastTime.equals(time)) {
- time += "." + (++lastCounter);
- } else {
- lastTime = time;
- }
- }
- String conversationId = time;
+ String conversationId = getConversation();
Log.setThreadAnnotation("[conversation/" + conversationId + "] ");
InetSocketAddress remote = (InetSocketAddress)conn.getRemoteSocketAddress();
Log.info(this, "connection from " + remote.getHostName() + ":" + remote.getPort() +
}
return false;
}
+
+ static String getConversation() {
+ String time = new SimpleDateFormat("yy.MMM.dd-hh:mm:ss").format(new Date());
+ synchronized (SMTP.class) {
+ if (lastTime != null && lastTime.equals(time)) {
+ time += "." + (++lastCounter);
+ } else {
+ lastTime = time;
+ }
+ }
+ return time;
+ }
private class LoggedLineReader extends LineReader {
PrintWriter log;
ws.println("503 MAIL FROM must precede RCPT TO");
continue;
}
- // FIXME: 551 = no, i won't forward that
command = command.substring(9).trim();
if(command.indexOf(' ') != -1) command = command.substring(0, command.indexOf(' '));
Address addr = new Address(command);
+ // FIXME: 551 = no, i won't forward that
to.addElement(addr);
ws.println("250 " + addr + " is syntactically correct");
return s;
}
}
+
+ public InetAddress[] getMailExchangerIPs(String domainName) {
+ InetAddress ret;
+ try {
+ Hashtable env = new Hashtable();
+ env.put("java.naming.factory.initial", "com.sun.jndi.dns.DnsContextFactory");
+ DirContext ictx = new InitialDirContext(env);
+ Attributes attrs = ictx.getAttributes(hostName, new String[] { "MX" });
+ Attribute attr = attrs.get("MX");
+ if (attr == null) {
+ ret = new InetAddress[1];
+ try {
+ ret[0] = InetAddress.getByName(domainName);
+ return ret;
+ } catch (UnknownHostException uhe) {
+ Log.warn(SMTP.class, "no MX hosts or A record for " + domainName);
+ return new InetAddress[0];
+ }
+ } else {
+ ret = new InetAddress[attr.size()];
+ NamingEnumeration ne = attr.getAll();
+ for(int i=0; ne.hasMore(); i++) ret[i] = (InetAddress)ne.next();
+ }
+ } catch (Exception e) {
+ Log.warn(SMTP.class, "couldn't find MX host for " + domainName + " due to");
+ Log.warn(SMTP.class, e);
+ return new InetAddress[0];
+ }
+ return ret;
+ }
+
+
}
-package org.ibex.mail.store;
+package org.ibex.mail.target;
import org.ibex.util.*;
import org.ibex.mail.*;
import java.io.*;
import java.text.*;
// FIXME: appallingly inefficient
-public class MessageStore {
+public class FileSystem {
private static final String STORAGE_ROOT =
System.getProperty("ibex.mail.root", File.separatorChar + "var" + File.separatorChar + "org.ibex.mail");
}
}
- public MessageStore slash(String name) throws IOException {
+ public FileSystem slash(String name) throws IOException {
throw new Error(this.getClass().getName() + " does not support the slash() method"); }
public int[] list() { throw new Error(this.getClass().getName() + " does not support the list() method"); }
public int add(Message message) throws IOException {
throw new Error(this.getClass().getName() + " does not support the query() method"); }
/** a fast-write, slow-read place to stash all messages we touch -- in case of a major f*ckup */
- public static class Transcript extends MessageStore {
+ public static class Transcript extends FileSystem {
private String path;
public Transcript(String path) throws IOException { new File(this.path = path).mkdirs(); }
private static String lastTime = null;
OutputStream os = new FileOutputStream(target);
message.dump(os);
os.close();
- return -1; // FIXME
+ return -1;
}
}
- public static class FileBased extends MessageStore {
+ public static class FileBased extends FileSystem {
private String path;
private FileBased(String path) throws IOException { new File(this.path = path).mkdirs(); }
- public MessageStore slash(String name) throws IOException { return new FileBased(path + "/" + name); }
+ public FileSystem slash(String name) throws IOException { return new FileBased(path + "/" + name); }
public int[] list() {
String[] names = new File(path).list();
File f = new File(path + File.separatorChar + messagenum + ".");
if (!f.exists()) throw new FileNotFoundException(f.toString());
try {
- Message.StoredMessage ret = new Message.StoredMessage(new LineReader(new InputStreamReader(new FileInputStream(f))));
+ Message.StoredMessage ret =
+ new Message.StoredMessage(new LineReader(new InputStreamReader(new FileInputStream(f))));
// FIXME: set answered/read/etc here
return ret;
} catch (MailException.Malformed malf) {
import org.ibex.util.*;
import org.ibex.mail.filter.*;
import org.ibex.mail.target.*;
-import org.ibex.mail.store.*;
import java.io.*;
import java.util.*;
public class Script extends Target {
- public static Script root = null;
- static {
- try {
- root = new Script(System.getProperty("ibex.mail.conf",
- File.separatorChar + "etc" + File.separatorChar + "org.ibex.mail.conf"));
- } catch (Exception e) {
- e.printStackTrace();
- }
+ private static Script root = null;
+ private static final String DEFAULT_CONF = File.separatorChar + "etc" + File.separatorChar + "org.ibex.mail.conf";
+ public static Script root() throws JSExn, IOException {
+ if (root == null) root = new Script(System.getProperty("ibex.mail.conf", DEFAULT_CONF));
+ return root;
}
final JS js;
js = JS.cloneWithNewParentScope(JS.fromReader(filePath, 0, new InputStreamReader(new FileInputStream(filePath))),
new ScriptScope(null)); }
- private static class ScriptScope extends JSScope {
- Message m;
+ private class ScriptScope extends JSScope {
ScriptEnv env = new ScriptEnv();
- public ScriptScope(Message m) { super(null); this.m = m; }
+ public ScriptScope() { super(null); }
public Object get(Object o) {
if (o.equals("m")) return m;
if (o.equals("ibex")) return env;
}
}
- public void accept(Message m) throws IOException {
+ public synchronized void accept(Message m) throws IOException {
+ this.m = m;
try {
- // currently, we write all inbound messages to the transcript
- // FIXME
Object ret = js.call(m, null, null, null, 1);
- if (ret instanceof Target) {
- ((Target)ret).accept(m);
- } else if (ret instanceof Filter) {
- // FIXME: return value?
- ((Filter)ret).process(m);
- } else {
- if (ret == null) throw new IOException("configuration script returned null");
- else throw new IOException("configuration script returned a " + ret.getClass().getName());
- }
+ if (ret == null) throw new IOException("configuration script returned null");
+ if (ret instanceof Target) ((Target)ret).accept(m);
+ //else if (ret instanceof Filter) ((Filter)ret).process(m);
+ else throw new IOException("configuration script returned a " + ret.getClass().getName());
} catch (JSExn e) {
- e.printStackTrace();
+ Log.warn(this, e);
+ throw new IOException("configuration script threw an exception");
}
}
// FIXME: this should extend org.ibex.core.Ibex
public static class ScriptEnv extends JS {
- // FIXME: duplicated code with org.ibex.core.Ibex; lift?
/** lets us put multi-level get/put/call keys all in the same method */
private class Sub extends JS {
String key;
if (name.equals("regexp")) {return new JSRegexp(a, b); }
}
} catch (RuntimeException e) {
- // FIXME: maybe JSExn should take a second argument, Exception
Log.warn(this, "ibex."+name+"() threw: " + e);
throw new JSExn("invalid argument for ibex object method "+name+"()");
}
--- /dev/null
+
+[megacz] Adam Megacz <adam@ibex.org>
+ - Original Architect
+ - Ibex Engine
+ - Most of the widget set
+
+[david] David Crawshaw <david@zentus.com>
+ - Widget Czar
+ - Fixes to slider.ibex
+
+[corey] Corey Jewett <cj@syntheticplayground.com>
+ - Patch to make build.xml not depend on <bash> task
+
+[ejones] Evan Jones <ejones@uwaterloo.ca>
+ - Google demo
+ - Dynamic Trees
+
--- /dev/null
+
+== 2002 =================================================================
+
+10-Apr megacz Box.java, Surface.java: fixed rendering glitch caused by
+ lastDirtiedTimeStamp hack.
+
+10-Apr megacz org/xwt/html/p.xwt: Improved flow performance.
+
+10-Apr megacz org/xwt/Box.java: fixed a bug that prevented regions from being
+ dirtied properly when boxes are removed from the tree and then
+ re-added.
+
+10-Apr megacz org/xwt/Box.java, org/xwt/SpecialBoxProperties.java:
+ hshrink/vshrink are no longer implemented by
+ manipulating dmax; the prerender pass understands them
+ natively.
+
+11-Apr megacz org/xwt/server/HTTP.java: fixed some CDATA misbehaviors.
+
+11-Apr megacz org/xwt/html/p.xwt, org/xwt/html/test.xwt: improved HTML
+ rendering; we can now render pretty much any <p> tag
+
+13-Apr megacz README: updated to note that build process requires
+ libgcj.jar even for jvm builds.
+
+21-Apr megacz src/org/xwt/plat/GCJ.xml: removed -fno-rtti
+
+21-Apr megacz src/org/xwt/Surface.java: workaround for GCJ PR java/6393
+
+22-Apr megacz src/org/xwt/plat/Java2.java: fixed bug that caused
+ RasterFormatException on jdk1.4
+
+22-Apr megacz README: included instructions on how to build without gcc.
+
+26-Apr megacz src/org/xwt/Main.java: included text description on splash screen
+
+26-Apr megacz src/org/xwt/plat/Win32.xml, src/org/xwt/plat/Java2.xml:
+ adjusted dist / signature process.
+
+26-Apr megacz README: included printStackTrace() patch
+
+26-Apr megacz src/org/xwt/XWT.java: fixed bug 53
+
+26-Apr megacz src/org/xwt/TinySSL.java: fixed PKCS1 bug
+
+26-Apr megacz build.xml: staging/production push process
+
+26-Apr megacz src/org/xwt/tasks/BashTask.java: now checks exit codes
+
+26-Apr megacz src/org/xwt/tasks/BashTask.java: added ssh support
+
+27-Apr megacz README: added file locking patch
+
+27-Apr megacz [lots of files]: introduced notion of buildid's, to make
+ XWT upgrades work more smoothly, and to prevent problems
+ with browser/plugin caches.
+
+27-Apr megacz JSObject.java: added extra debugging info
+
+27-Apr megacz XWT.java, Platform.java, Main.java, Java2.java,
+ Win32.java, Win32.cc, faq.html: added support for
+ xwt.newBrowserWindow()
+
+27-Apr megacz Surface.java, Box.java: nuked dirtiedTimeStamp
+ altogether; it caused more problems than it solved.
+
+27-Apr megacz reference.html: Changed capitalization of
+ faultstring/faultcode for xwt.soap() to match SOAP spec.
+
+27-Apr megacz XWT.java, Box.java: fixed ConversionError bug
+
+27-Apr megacz Platform.java: added a 3-pixel minimum for a font's
+ descent -- ensures that we have space for underlining.
+
+28-Apr megacz Template.java: fixed a bug where <redirect/> would
+ misbehave if used on a scriptless <template/>
+
+28-Apr megacz SOAP.java, XMLRPC.java: Base64 elements are now decoded
+ and returned as String's.
+
+28-Apr megacz Platform.java: fixed bug that caused italicized text to
+ automatically become bold.
+
+29-Apr megacz Box.java: moved underline up by one pixel (goes with
+ last change).
+
+29-Apr megacz Main.java: new splashscreen, upped the gamma, broke off
+ SplashScreen.create() into its own Message
+
+29-Apr megacz Surface.java: took blitDirtyScreenRegions() out of
+ Dirty(); replaced with Refresh(). This was causing a
+ thread hazard on Win32, resulting in Bug 21 (closed)
+
+29-Apr megacz Win32.cc: removed redundant Refresh(), removed debugging
+ statement.
+
+29-Apr megacz JSObject.java: added debugging output for an error I've
+ been seeing.
+
+29-Apr megacz src/org/xwt/themes/monopoly: overhauled the menu and
+ tree widgets.
+
+29-Apr megacz Main.java: fixed splashscreen refresh bug.
+
+30-Apr megacz window_manager_interaction.xwt: added UnMinimize/UnMaximize
+
+30-Apr megacz Chess.java, XServer.java: removed unused imports
+
+30-Apr megacz AWT.java: only create reserve Component if an
+ AWTDoubleBuffer gets created, prep for Java14, broke out
+ InnerFrame/InnerWindow and added exception handler to
+ cope with new Java1.4 HeadlessException.
+
+30-Apr megacz Java12.java, Java12.xml, Java14.java: added Java14 support
+
+30-Apr megacz Box.java: made dirty() public for Java14
+
+30-Apr megacz Platform.java: updated to detect Java14
+
+03-Apr megacz Main.java: fixed a bug that could cause >100% instantiation
+
+03-Apr megacz HTTP.java, Main.java, Platform.java, SOAP.java,
+ XMLRPC.java, Java12.java, Win32.cc, Win32.java: new HTTP
+ architecture, first implementation of proxy support.
+
+05-Apr megacz HTTP.java, Main.java, Platform.java, SOAP.java,
+ TinySSL.java, XMLRPC.java, Java12.java, Win32.java:
+ improved proxy support.
+
+06-Apr megacz Box.java: fixed a bug relating to shrink
+
+07-Apr megacz Box.java: thisbox[n] = null wasn't doing anything
+
+15-May megacz Template.java, Static.java: fixed bug where xwt.static
+ wouldn't work for packages whose name included the token
+ "xwt".
+
+15-May megacz XWT.java: added xwt.screen{Width,Height}
+
+15-May megacz JSObject.java: added extra logic to discriminate between
+ public and private puts.
+
+15-May megacz Box.java: added setLimits() call, refined cmin-updating
+ logic, added extra logging in the event of a
+ PosChange/SizeChange infinite loop.
+
+15-May megacz HTTP.java: fixed Host: bug
+
+15-May megacz Platform.java: added GCJ-Linux platform detection logic,
+ setLimits() logic.
+
+15-May megacz Resources.java: fixed a bug in download-size calculation.
+
+15-May megacz SpecialBoxProperty.java: added required extra dirty()
+ call, extra checking on textcolor.
+
+15-May megacz Surface.java: key presses/releases only go to visible
+ children, setLimits()
+
+15-May megacz XMLRPC.java: call() is now synchronized
+
+15-May megacz Win32.xml, GCJ.xml, GCJHTask.java: ${gcc-prefix} now ends
+ with a dash.
+
+15-May megacz Win32.java: handled the oddball all-protocol proxy case
+
+18-May megacz Static.java: removed redundant debug message
+
+18-May megacz JSObject.java: fixed a public/private bug
+
+28-May megacz HTTP.java: ugly hack to cope with Microsoft CARP PAC scripts
+
+28-May megacz Main.java: spelling fix
+
+01-Jun megacz Platform.java: extra checks on URL well-formedness
+
+01-Jun megacz AWT.java: file dialog suggestion bugfix
+
+01-Jun megacz Main.java: custom splash screen support
+
+01-Jun megacz POSIX.cc, POSIX.java: finally completed POSIX support
+
+01-Jun megacz Win32.cc: attempted fix for international keyboards
+
+05-Jun megacz Box.java: bugfix to ensure that negative regions are never filled
+
+05-Jun megacz Main.java: now require filename to end with .xwar
+
+05-Jun megacz Ibex.java: ibex.fileSeparator, ibex.homeDir, ibex.tempDir,
+ ibex.recursivePrintObject
+
+05-Jun megacz AWT.java: fix for non-US keyboards
+
+14-Jun megacz HTML.java, Ibex.java: introduced ibex.parseHTML()
+
+16-Jun megacz Resources.java: eliminated some annoying warning messages
+
+16-Jun megacz Template.java: fixed erroneous attribute checks for numbers and image/border
+
+16-Jun megacz HTTP.java: diabled ibex-httpProxy, etc
+
+23-Jun megacz Box.java: JPEG hack, fastpath rendering bugfix,
+ fixedaspect, improved >500 Pos/SizeChange loop breakout
+
+23-Jun megacz HTTP.java: removed System.out.println()
+
+23-Jun megacz Main.java: lightened splash screen
+
+23-Jun megacz Platform.java: no longer invokes System.exit() from
+ applet, setTcpNoDelay() in Platform.getSocket()
+
+23-Jun megacz SOAP.java, XMLRPC.java: bugfix for CDATA content in random elements
+
+23-Jun megacz SpecialBoxProperty.java: fixedaspect, warning about non-self-redirect root boxes
+
+23-Jun megacz Java12.java: removed wierd BufferedImage hackaround;
+ jdk1.4 doesn't need it and it was causing wierd rendering glitches
+
+23-Jun megacz POSIX.cc: hackaround for wierd XFreeColormap() failure
+
+23-Jun megacz Win32.java: fix for YET ANOTHER wacky Win32 proxy string format
+
+24-Jun megacz MessageQueue.java: fix to MessageQueue to improve
+ XML-RPC/SOAP performance
+
+01-Jul megacz DERObjectIdentifier.java: fix to work around GCC compiler bug
+
+01-Jul megacz XWF.java: fixed an int[] sharing problem
+
+01-Jul megacz XMLRPC.java, NativeDate.java: XMLRPC can now send dateTime's
+
+01-Jul megacz POSIX.java, POSIX.cc: initial window size, DISPLAY
+ string logging, http_proxy environment variable checking, font fixes
+
+01-Jul megacz Platform.java: initial window size fixes
+
+01-Jul megacz HTTP.java: we no longer insert the IP into the URL.
+
+01-Jul megacz TinySSL.java, HTTP.java: fixed SSL-over-Proxy
+
+01-Jul megacz AWT.java: added dialog for critical aborts
+
+01-Jul megacz Main.java: added browser detection output
+
+02-Jul david bevel.ibex: hpad/vpad must be greater than thickness
+
+02-Jul david colorpicker.ibex, slider.ibex, slider_base.ibex: Implemented
+ slider.ibex (limits, value display, quantization) and made
+ major improvements/fixed to colorpicker.
+
+15-Jul megacz HTTP.java: implemented isInNet(), weekdayRange(), now
+ checks environment vars for proxies
+
+15-Jul megacz PNG.java: fixed 8bpp bug
+
+15-Jul megacz Platform.java, Win32.cc, Win32.java, POSIX.java:
+ getEnv(), engine knows its own build-id
+
+15-Jul megacz POSIX.cc: ignore SIGPIPE in case the browser that
+ launched us closes
+
+15-Jul megacz SpecialBoxProperty.java: redirect property,
+ color/textcolor error message tweak.
+
+15-Jul megacz TinySSL.java: speed improvement on certificate checks
+
+15-Jul megacz XMLRPC.java: workaround for bug in Zope XML-RPC server
+
+15-Jul megacz AWT.java: print out color depth
+
+15-Jul megacz BashTask: print everything on stdout
+
+15-Jul megacz JSObject.java: added JSFunction helper
+
+15-Jul megacz GCJ.xml, Ibex.java, Template.java, Static.java,
+ Resources.java, splash.ibex, lithium.png, Main.java,
+ Box.java: builtin.xwar, loadArchive(), prefetchImage()
+
+18-Jul megacz XMLRPC.java, MessageQueue.java: attempted to improve
+ responsiveness of UI by yielding on network ops if
+ non-thread events are in the queue.
+
+18-Jul megacz Platform.java: never create or permit windows smaller
+ than the scar.
+
+18-Jul megacz Surface.java: improved shift modifier handling,
+ prohibited windows smaller than scar.
+
+18-Jul megacz Ibex.java: added write-only 'proxyAuthorization' field.
+
+18-Jul megacz AWT.java: boosted font size by 2 points on Java12
+
+18-Jul megacz GCJ.xml: builtin.xwar support
+
+18-Jul megacz POSIX.cc: better capslock handling
+
+18-Jul megacz Win32.cc: fixed MINMAXINFO bug
+
+18-Jul megacz Win32.java: changed dialog mapping to MS Sans Serif
+
+18-Jul megacz Platform.java: don't try to getEnv() on Win w/ jdk<1.4
+
+18-Jul megacz HTTP.java: Basic Proxy-Authorization support
+
+19-Jul megacz POSIX.java: font fix
+
+19-Jul megacz TinySSL.java: workaround for a GCJ bug
+
+20-Jul megacz PNG.java: ignore transparency chunk if encountered
+ before palette chunk
+
+25-Jul megacz Box.java: fixed bug related to adding/removing boxes
+
+30-Jul corey build.xml: patch to make build.xml not depend on <bash/>
+
+06-Aug megacz Context.java: workaround for GCJ bug which causes
+ MessageFormatter to choke on { and }
+
+06-Aug megacz MessageQueue.java: fixed MessageQueueWatcher so that it
+ works even when an infinite loop occurs in a _SizeChange
+ or _PosChange trap.
+
+06-Aug megacz Platform.java: removed WPAD detection, HTTP.Proxy => Proxy.
+
+06-Aug megacz Static.java, Resources.java: fixed ibex.static bug.
+
+06-Aug megacz SpecialBoxProperty.java: thisbox.root now returns null
+ if thisbox is a root box.
+
+06-Aug megacz Surface.java: fixed button 1/3 swapping bug
+
+06-Aug megacz TinySSL.java: option to ignore untrusted certs, fixed GCJ bug
+
+06-Aug megacz AWT.java: removed blitDirtyScreenRegions() due to
+ deadlock, compensated for MacOSX button-swapping bug.
+
+06-Aug megacz Java12.java: disabled focusmanager so we can recieve tab
+ keypresses.
+
+06-Aug megacz Win32.java: HTTP.ProxyInfo => Proxy
+
+06-Aug megacz JSObject.java: constructor now takes sealed argument
+
+06-Aug megacz POSIX.java: font mapper now prefers ISO_8559-1 fonts
+
+06-Aug megacz Box.java: use new HTTP interface, getIds() only returns children
+
+06-Aug megacz Ibex.java: encodeURI, decodeURI, new HTTP stack, calling
+ newBox in the foreground thread is deprecated.
+
+06-Aug megacz XMLRPC.java: new HTTP stack, better verbose output
+
+06-Aug megacz SOAP.java: new HTTP stack
+
+06-Aug megacz HTTP.java: total rewrite: BasicAuth, DigestAuth, KeepAlive, Pipelining.
+
+09-Aug megacz SpecialBoxProperty.java: changed behavior of thisbox.root
+
+09-Aug megacz Win32.java, Win32.cc: hack to avoid strange race condition in Win32 GDI
+
+10-Aug megacz HTML.java, html.ibex: fixed HTML widget to handle unclosed <li> tags
+
+10-Aug megacz TinySSL.java: fixed vulnerability to Mike Benham's attack
+
+16-Aug megacz Box.java: fixed a bug that was causing lockups on Win32...
+
+16-Aug megacz Surface.java, Main.java: don't scar the splash screen
+
+16-Aug megacz AWT.java, Java12.java, Java14.java: fixed jdk1.4 bug
+ with keypresses and frameless windows.
+
+16-Aug megacz Ibex.java, SpecialBoxProperty.java: box.apply()
+
+17-Aug megacz Box.java, SpecialBoxProperty.java, Surface.java: code to
+ prevent engine from quitting when changing the last
+ remaining surface from a frame to a window or vice
+ versa.
+
+17-Aug megacz Vec.java: fixed infinite loop
+
+17-Aug megacz Trap.java: switched allTraps from a Vector to a Hashtable
+
+17-Aug megacz Main.java: initial instantiation now happens in a background thread
+
+17-Aug megacz Template.java: fixed a bug that was keeping retheme() from working
+
+20-Aug megacz Box.java: fixed rounding error
+
+21-Aug megacz PalmOS.java, PalmOS.xml, jump.jar: began work on PalmOS port.
+
+24-Aug megacz HTTP.java, SOAP.java: fixed bug which caused
+ miscalculation of the Content-Length header.
+
+24-Aug megacz POSIX.java: fixed cut/paste bug
+
+02-Sep megacz AWT.java: report corner of window, not corner of decorative frame
+
+02-Sep megacz Surface.java, Main.java: don't quit due to disposal of
+ last surface unless initialization is complete.
+
+03-Sep megacz XWF.java: code to handle .xwf's that don't include the
+ underscore character.
+
+15-Sep megacz Box.java: committed a change that I forgot to commit
+ dealing with box removal.
+
+15-Sep megacz HTTP.java: fixed end-of-header detection
+
+15-Sep megacz Platform.java: disable 2d acceleration on Mac OS X 10.2
+
+15-Sep megacz Template.java: added callback for retheme operation
+
+15-Sep megacz Ibex.java: new retheme() syntax
+
+23-Sep megacz SpecialBoxProperty.java: invisible now returns true if
+ any of the box's ancestors is invisible.
+
+23-Sep megacz SpecialBoxProperty.java, Box.java, Surface.java:
+ expanded dimensions to 32 bits, fixed bug in behavior of
+ hshrink/vshrink, don't deliver events to root first.
+
+23-Sep megacz HTTP.java: never skip(0)
+
+03-Oct megacz ByteStream.java: fixed null pointer problem
+
+03-Oct megacz Proxy.java: fixed bug in shMatchExp()
+
+03-Oct megacz Box.java, SpecialBoxProperty.java: fixed shrink
+ behavior, deliver clicks to box first (not root), id is
+ a readable attribute
+
+03-Oct megacz Ibex.java: made recursivePrintObject public so we can
+ access it.
+
+11-Oct megacz POSIX.cc: fixed a bug that was causing phantom messages
+ after window deletion
+
+11-Oct megacz README, Resources.java, GCJ.xml, jazz/*: upgraded to gcj
+ 3.3; eliminated jazzlib; introduced compile hack because
+ 3.3 miscompiles Trap.java
+
+15-Oct megacz Resources.java: hackaround for broken libgcj java.util.zip
+
+15-Oct megacz Arguments.java, Trap.java: arguments.trapname
+
+30-Oct megacz SpecialBoxProperty.java: fixed mouse event propagation
+
+05-Feb megacz X11.cc X11.java POSIX.cc POSIX.java Linux.xml: separated
+ POSIX from X11.
+
+06-Feb megacz X11.java: fixed a typo
+
+11-Feb megacz org/bouncycastle/*: upgraded bouncycastle
+
+11-Feb megacz README: updated gcc instructions and patches
+
+11-Feb megacz Log.java: refactored printing code in prep for inline logging
+
+11-Feb megacz X11.java: bugfix for stupid typos
+
+11-Feb megacz Picture.java, DoubleBuffer.java, Win32.java, AWT.java:
+ made Picture and DoubleBuffer abstract classes rather
+ than interfaces
+
+11-Feb megacz Trap.java: changed System.out.println to Log.log
+
+11-Feb megacz TinySSL.java: changed System.out.println to Log.log
+
+11-Feb megacz PNG.java: changed System.out.println to Log.log
+
+11-Feb megacz splash.ibex: added "press Esc to quit" message
+
+11-Feb megacz Resources.java: removed libgcj hack; 3.3 fixed the problem
+
+11-Feb megacz Platform.java: System.out->System.err, POSIX->X11
+
+11-Feb megacz GCJ.xml: added optimizations, linker path
+
+11-Feb megacz POSIX.java: removed extra debugging output
+
+11-Feb megacz POSIX.cc: added required #includes
+
+11-Feb megacz Linux.xml: removed needless -ldl
+
+11-Feb megacz Main.java: System.out->System.err
+
+11-Feb megacz DoubleBuffer.java: added 'abstract' keyword
+
+11-Feb megacz Picture.java: added 'abstract' keyword
+
+15-Feb megacz GCJ.xml, Linux.xml, Win32.xml: fixed linkage bug
+
+25-Feb megacz README: switched build process from ant to make
+
+25-Feb megacz Makefile, README: merged Java12 and Java14 into Java2
+
+25-Feb megacz README, Makefile: added next.build and next-build target
+
+25-Feb megacz Makefile: added new-release target
+
+25-Feb megacz Makefile: added nice -n 19 for new-release builds
+
+25-Feb megacz Makefile: fixed typo
+
+26-Feb megacz Makefile: added dist, nohup-dist targets; removed new-release
+
+27-Feb megacz ant: removed ant script
+
+27-Feb megacz Makefile: corrected spacing of build messages
+
+27-Feb megacz Makefile, Makefile: tweaked make dist
+
+27-Feb =========== build 02B6 ================================================
+27-Feb megacz Makefile: limited cvs emails to 200 lines
+
+
+27-Feb =========== build 02B7 ================================================
+
+27-Feb =========== build 02B8 ================================================
+
+27-Feb =========== build 0272 ================================================
+27-Feb megacz Makefile: simplified host detection
+
+27-Feb megacz Makefile: typo fix
+
+
+27-Feb =========== build 0273 ================================================
+27-Feb megacz Makefile: strip binaries in make dist
+
+
+27-Feb =========== build 0274 ================================================
+27-Feb megacz Makefile: master.dist.ibex.org
+
+27-Feb megacz Makefile, Makefile, Makefile: none
+
+
+27-Feb =========== build 0275 ================================================
+27-Feb megacz Makefile: added neglected shell keyword
+
+01-Mar megacz Makefile: gcj doesn\'t need a target prefix
+
+04-Mar megacz Makefile, Makefile: preliminary Darwin support
+
+10-Mar megacz Makefile: autotag on make dist
+
+10-Mar megacz Makefile: autotag on make dist
+
+10-Mar megacz Makefile: make dist now creates source tarballs
+
+10-Mar megacz Makefile: make dist now creates source tarballs
+
+
+10-Mar =========== build 0700 ================================================
+10-Mar megacz Makefile: fixed Makefile to make source tarballs
+
+10-Mar megacz Makefile: fixed Makefile to make source tarballs
+
+11-Mar megacz Makefile: lithium shouldn't support darwin
+
+11-Mar megacz Makefile: HEAD shouldn't support Darwin yet
+
+11-Mar megacz Makefile: none
+
+12-Mar megacz Makefile: bootclasspath and fastjar auto-detection
+
+12-Mar megacz Makefile: bootclasspath and fastjar auto-detection
+
+13-Mar megacz Makefile: jikes autodetection, jikes optional
+ build, javac fallback
+
+17-Mar megacz Makefile: added propose-patch makefile target
+
+17-Mar megacz Makefile: added propose-patch makefile target
+19-Mar david README: test
+
+19-Mar david Makefile: jikes compile on stock os x install
+
+24-Mar megacz Makefile: added Davids jikes patch
+
+24-Mar megacz Makefile: added v option to tar
+
+26-Mar andrew XML.java: applied <!-- .. --> comment counter fix
+ patch (commentcountfix1.diff)
+
+26-Mar megacz Makefile: gosset -> serverbeach
+
+26-Mar megacz Makefile: added Darwin precomp header hack
+
+26-Mar megacz Makefile: added Darwin precomp header hack
+
+26-Mar megacz Makefile: gosset -> serverbeach
+
+26-Mar megacz Makefile: tab bug
+
+26-Mar megacz Makefile: fixed bug for compatability with BSD make
+
+26-Mar megacz Makefile: fixed bug for compatability with BSD make
+
+26-Mar megacz Makefile: removed the fancy single-line build
+ outputs
+
+26-Mar megacz Makefile: removed the fancy single-line build
+ outputs
+
+26-Mar megacz Makefile: Removed -O9; will add later
+
+26-Mar megacz Makefile: tried O2
+
+29-Mar megacz Main.java: ignore argument to -l
+
+29-Mar megacz Makefile: correct use of -m in jar invocation
+
+29-Mar megacz Main.java: ignore argument to -l
+
+29-Mar megacz Makefile: correct use of -m in jar invocation
+
+29-Mar megacz Java2.java: weakened binding of Java14Surface to
+ keep 1.3.x working
+
+29-Mar megacz Java2.java: weakened binding of Java14Surface to
+ keep 1.3.x working
+
+30-Mar megacz Makefile: trying -O0 since we're still getting
+ faults
+
+30-Mar megacz Makefile: harmonized self-contradictory
+ optimization settings
+
+30-Mar megacz Makefile: harmonized self-contradictory
+ optimization settings
+
+31-Mar megacz Makefile: rolled back to gcj 19-Oct-2002
+
+31-Mar megacz Makefile: rolled back to gcj 19-Oct-2002
+
+31-Mar megacz Makefile: trying to fix cvs update
+
+31-Mar megacz Makefile: more attempts at solving the cvs update
+ problem
+
+31-Mar megacz Makefile: fixed gcjh so that it can be found before
+ gcc-linux is built
+
+31-Mar megacz Makefile: fixed gcjh so that it can be found before
+ gcc-linux is built
+
+09-Apr megacz jpegsrc.v6b.tar.gz: added ijg jpeg decoder source
+ tarball
+
+09-Apr megacz HTTP.java: fixed a bug that prevented
+ HTTPInputStream from signalling EOF
+
+09-Apr megacz Makefile: fixed gcc update script
+
+09-Apr megacz Makefile: fixed gcc update script
+
+09-Apr megacz Makefile, jmorecfg.h.patch, Box.java, Platform.java, Resources.java, AWT.java, GCJ.cc, GCJ.java, Win32.cc:
+ added jpeg support
+
+09-Apr megacz Makefile: fixed make dist
+
+09-Apr megacz Makefile: fixed make dist again
+
+
+09-Apr =========== build 0701 ================================================
+09-Apr megacz Makefile: fixed make dist
+
+
+09-Apr =========== build 0702 ================================================
+
+09-Apr =========== build 0703 ================================================
+10-Apr megacz Makefile: fixed linkage problem
+
+
+10-Apr =========== build 0704 ================================================
+
+10-Apr =========== build 0705 ================================================
+10-Apr megacz GCJ.cc: forgot extern C for jpeglib
+
+
+10-Apr =========== build 0706 ================================================
+19-Apr megacz Makefile, README, Main.java, Platform.java, XML.java, GCJ.cc, GCJ.java, Java2.java, POSIX.cc, Win32.cc, X11.cc:
+ finally -- working Darwin support
+
+19-Apr megacz Darwin.cc, Darwin.java, Linux.java: added more plat
+ files
+
+19-Apr megacz Makefile, Makefile, jmorecfg.h.patch, jpegsrc.v6b.tar.gz, Box.java, HTTP.java, Platform.java, Resources.java, AWT.java, GCJ.cc, GCJ.java, Win32.cc, X11.cc:
+ merged in HEAD
+
+19-Apr megacz Makefile, Main.java, Platform.java, Darwin.cc, Darwin.java, GCJ.cc, GCJ.java, Linux.java, POSIX.cc, Win32.cc, X11.cc:
+ merge from Darwin branch
+
+19-Apr megacz gcc.patch: added Brian Alliets gcc patch
+
+19-Apr megacz JS.java, Resources.java: GUT_branch
+
+19-Apr megacz Makefile: added line to apply gcc.patch; updated
+ gcc3.3 to 08-Apr-2003
+
+20-Apr megacz gcc.patch: fixed the patch so it applies properly
+
+22-Apr megacz Lexer.java: added the Lexer for org.ibex.js
+
+24-Apr megacz Makefile, Carbon.cc, Carbon.java: added Carbon
+ skeleton code
+
+24-Apr megacz Carbon.java: bugfix to make it compile
+
+24-Apr megacz Parser.java, Lexer.java: parser
+
+24-Apr david ByteStream.java, Resources.java, Template.java, XML.java, XMLRPC.java, Vec.java, XML.java, ByteStream.java, Resources.java, Template.java, XML.java, XMLRPC.java, Vec.java, XML.java, ByteStream.java, Resources.java, Template.java, XML.java, XMLRPC.java, Vec.java, XML.java:
+ new xml parser
+
+27-Apr megacz Makefile: fixed host/target detection problem
+
+28-Apr megacz Template.java: removed 150-char line length
+ restriction
+
+28-Apr megacz Template.java: removed 150-char line length
+ restriction
+
+29-Apr david Box.java: check for a moving redirect target
+
+29-Apr megacz Makefile: updated ibex cvs url
+
+29-Apr david Parser.java, TokenStream.java: HACKS for
+ 'and'/anonymous functions
+
+29-Apr megacz JS.java: New JS interface
+
+29-Apr megacz Vec.java: added push/pop
+
+29-Apr megacz Lexer.java, Parser.java: fixed lots of parser/lexer
+ bugs
+
+29-Apr megacz Box.java: font inheritance
+
+29-Apr megacz Makefile: don't build awt; speeds up gcj builds
+
+01-May megacz Makefile: forgot to disable hashsync on darwin
+
+01-May david Makefile: fix for non-linux build environments
+
+02-May megacz Lexer.java, Parser.java: parser now parses
+ splash.ibex
+
+02-May megacz JS.java, Parser.java: removed all FIXMES
+
+03-May megacz JS.java, Parser.java: more fixups
+
+03-May megacz COPYING: cleaned up the copyright declarations
+
+03-May megacz README: major cleanup of the README
+
+03-May megacz JS.java, Lexer.java, Parser.java: lexer, parser,
+ and interpreter complete but untested
+
+05-May megacz Makefile: enable-threads=posix on Darwin
+
+06-May megacz Expr.java: added expr
+
+06-May megacz Makefile: upstream: co -> head
+
+07-May megacz Expr.java: typo
+
+07-May david .cvsignore, .cvsignore, .cvsignore: added cvsignore
+ files
+
+08-May ejones Makefile, Main.java, Platform.java, Carbon.cc, Carbon.java, Win32.java:
+ Native Carbon Port: - Add Carbon implementation - Fix the
+ Makefile to build it correctly - Fix Main and Platform to call a
+ method running on the Platform class when Ibex is running. -
+ Fixed Win32 to block the main thread forever in its running
+ method.
+
+09-May david Makefile: fixes for upstream references
+
+11-May megacz Vec.java: made Vec final so methods get inlined
+
+11-May megacz Java2.java: removed references to Main.applet,
+ re-enabled dirtying on Java1.4-for-OSX
+
+11-May megacz Expr.java, JS.java, Lexer.java, Parser.java, package.html:
+ more JS code
+
+11-May megacz edit.ibex: updated to David's latest edit widget
+
+11-May megacz scar.png: scar image now lives in org.ibex.builtin
+
+11-May megacz Main.java: removed applet support, moved scar to
+ org.ibex.builtin
+
+11-May megacz edit_lib.ibex: added Davids ibex.standard.lib.edit
+
+11-May megacz Arguments.java, BaseFunction.java, BinaryDigitReader.java, ClassDefinitionException.java, ClassNameHelper.java, ClassOutput.java, Context.java, ContextListener.java, DToA.java, DebuggableEngineImpl.java, DefaultErrorReporter.java, Delegator.java, EcmaError.java, ErrorReporter.java, EvaluatorException.java, FlattenedObject.java, Function.java, FunctionNode.java, FunctionObject.java, IRFactory.java, IdFunction.java, IdFunctionMaster.java, IdScriptable.java, ImporterTopLevel.java, InterpretedFunction.java, InterpretedScript.java, Interpreter.java, InterpreterData.java, InterpreterFrame.java, Invoker.java, JavaMembers.java, JavaScriptException.java, Label.java, LabelTable.java, LazilyLoadedCtor.java, LineBuffer.java, ListenerArray.java, LocalVariable.java, NativeArray.java, NativeBoolean.java, NativeCall.java, NativeDate.java, NativeError.java, NativeFunction.java, NativeGlobal.java, NativeJavaArray.java, NativeJavaClass.java, NativeJavaConstructor.java, NativeJavaMethod.java, NativeJavaObject.java, NativeJavaPackage.java, NativeMath.java, NativeNumber.java, NativeObject.java, NativeScript.java, NativeString.java, NativeWith.java, Node.java, NodeTransformer.java, NotAFunctionException.java, Parser.java, PreorderNodeIterator.java, PropertyException.java, RegExpProxy.java, Script.java, ScriptRuntime.java, Scriptable.java, ScriptableObject.java, SecuritySupport.java, ShallowNodeIterator.java, SourceTextItem.java, SourceTextManager.java, Synchronizer.java, TokenStream.java, UintMap.java, Undefined.java, VariableTable.java, WrapHandler.java, WrappedException.java, Wrapper.java, DebugFrame.java, DebugReader.java, DebuggableEngine.java, DebuggableScript.java, Debugger.java, NativeRegExp.java, NativeRegExpCtor.java, RegExpImpl.java, SubString.java, Box.java, ByteStream.java, HTML.java, HTTP.java, MessageQueue.java, Platform.java, Proxy.java, Resources.java, SOAP.java, SpecialBoxProperty.java, Static.java, Surface.java, Template.java, ThreadMessage.java, Trap.java, XMLRPC.java, Ibex.java, AWT.java, Java12.java, JSObject.java:
+ goodbye org.mozilla.javascript, hello org.ibex.js
+
+11-May megacz msjvm.jar, netscape.jar: removing
+ msjvm.jar/netscape.jar; use reflection instead
+
+26-May megacz Box.java, Resources.java, SpecialBoxProperty.java, Static.java, Ibex.java, JS.java, Parser.java:
+ lots of progress on org.ibex.js
+
+
+26-May =========== build 0707 ================================================
+
+26-May =========== build 0708 ================================================
+02-Jun megacz Ibex.java, Lexer.java, Parser.java: more js
+ improvements
+
+03-Jun megacz JS.java, Lexer.java, Parser.java: nearly finished
+ switching to a bytecode architecture
+
+03-Jun megacz Parser.java: more js improvements
+
+03-Jun megacz Parser.java: almost done moving to bytecode
+
+03-Jun megacz Parser.java: completely switched over to bytecode
+
+
+16-Jun =========== build 0710 ================================================
+
+16-Jun =========== build 0711 ================================================
+
+16-Jun =========== build 0712 ================================================
+
+16-Jun =========== build 0713 ================================================
+
+16-Jun =========== build 0714 ================================================
+
+16-Jun =========== build 0715 ================================================
+
+17-Jun =========== build 0716 ================================================
+
+17-Jun =========== build 0717 ================================================
+
+17-Jun =========== build 0718 ================================================
+
+17-Jun =========== build 0719 ================================================
+
+17-Jun =========== build 071A ================================================
+
+17-Jun =========== build 071B ================================================
+
+17-Jun =========== build 071C ================================================
+
+17-Jun =========== build 071D ================================================
+
+17-Jun =========== build 071E ================================================
+
+17-Jun =========== build 071F ================================================
+
+17-Jun =========== build 0720 ================================================
+
+17-Jun =========== build 0721 ================================================
+
+17-Jun =========== build 0722 ================================================
+
+17-Jun =========== build 0723 ================================================
+
+17-Jun =========== build 0724 ================================================
+
+17-Jun =========== build 0725 ================================================
+
+17-Jun =========== build 0726 ================================================
+
+17-Jun =========== build 0727 ================================================
+
+17-Jun =========== build 0728 ================================================
+
+17-Jun =========== build 0729 ================================================
+
+17-Jun =========== build 072A ================================================
+
+17-Jun =========== build 072B ================================================
+
+17-Jun =========== build 072C ================================================
+
+17-Jun =========== build 072D ================================================
+
+17-Jun =========== build 072E ================================================
+
+17-Jun =========== build 072F ================================================
+
+17-Jun =========== build 0730 ================================================
+
+17-Jun =========== build 0731 ================================================
+
+18-Jun =========== build 0732 ================================================
+
+18-Jun =========== build 0733 ================================================
+
+18-Jun =========== build 0734 ================================================
+
+18-Jun =========== build 0735 ================================================
+
+18-Jun =========== build 0736 ================================================
+
+18-Jun =========== build 0737 ================================================
+
+18-Jun =========== build 0738 ================================================
+
+18-Jun =========== build 0739 ================================================
+
+18-Jun =========== build 073A ================================================
+
+05-Jul =========== build 073B ================================================
+
+05-Jul =========== build 073C ================================================
+
+05-Jul =========== build 073D ================================================
+
+05-Jul =========== build 073E ================================================
+
+05-Jul =========== build 073F ================================================
+
+05-Jul =========== build 0740 ================================================
+
+05-Jul =========== build 0741 ================================================
+
+05-Jul =========== build 0742 ================================================
+
+05-Jul =========== build 0743 ================================================
+
+05-Jul =========== build 0744 ================================================
+
+07-Jul =========== build 0745 ================================================
+
+07-Jul =========== build 0746 ================================================
+
+09-Jul =========== build 0747 ================================================
+
+09-Jul =========== build 0748 ================================================
+
+09-Jul =========== build 0749 ================================================
+
+15-Jul =========== build 074A ================================================
+
+15-Jul =========== build 074B ================================================
+
+15-Jul =========== build 074C ================================================
+
+21-Jul =========== build 074D ================================================
+
+21-Jul =========== build 074E ================================================
+
+27-Jul =========== build 074F ================================================
+
+27-Jul =========== build 0750 ================================================
+
+27-Jul =========== build 0751 ================================================
+
+25-Sep =========== build 07a0 ================================================
+
+25-Sep =========== build 07A1 ================================================
+
+25-Sep =========== build 07A2 ================================================
+
+25-Sep =========== build 07A3 ================================================
+
+25-Sep =========== build 07A4 ================================================
+
+25-Sep =========== build 07A5 ================================================
+
+25-Sep =========== build 07A6 ================================================
+
+26-Sep =========== build 07A7 ================================================
+
+26-Sep =========== build 07A8 ================================================
+
+26-Sep =========== build 07A9 ================================================
+
+26-Sep =========== build 07AA ================================================
+
+26-Sep =========== build 07AB ================================================
+
+26-Sep =========== build 07AC ================================================
+
+27-Sep =========== build 07AD ================================================
+
+27-Sep =========== build 07AE ================================================
+
+27-Sep =========== build 07AF ================================================
+
+27-Sep =========== build 07AE ================================================
+
+27-Sep =========== build 07B0 ================================================
+
+27-Sep =========== build 07B1 ================================================
+
+14-Oct =========== build 07B2 ================================================
+
+14-Oct =========== build 07B3 ================================================
+
+15-Oct =========== build 07B4 ================================================
+
+16-Oct =========== build 07B5 ================================================
+
+16-Oct =========== build 07B6 ================================================
+
+16-Oct =========== build 07B7 ================================================
+
+16-Oct =========== build 07B8 ================================================
+
+16-Oct =========== build 07B9 ================================================
+
+16-Oct =========== build 07BA ================================================
+
+18-Oct =========== build 07BB ================================================
+
+18-Oct =========== build 07BC ================================================
+
+18-Oct =========== build 07BD ================================================
+
+18-Oct =========== build 07BE ================================================
+
+19-Oct =========== build 07BF ================================================
+
+19-Oct =========== build 07C0 ================================================
+
+21-Oct =========== build 07C1 ================================================
+
+21-Oct =========== build 07C2 ================================================
+
+21-Oct =========== build 07C3 ================================================
+
+21-Oct =========== build 07C4 ================================================
+
+27-Oct =========== build 07C5 ================================================
+
+28-Oct =========== build 07C6 ================================================
+
+28-Oct =========== build 07C7 ================================================
+
+28-Oct =========== build 07C8 ================================================
+
+28-Oct =========== build 07C9 ================================================
+
+28-Oct =========== build 07CA ================================================
+
+28-Oct =========== build 07CB ================================================
+
+28-Oct =========== build 07CC ================================================
+
+28-Oct =========== build 07CD ================================================
+
+28-Oct =========== build 07CE ================================================
+
+28-Oct =========== build 07CF ================================================
+
+28-Oct =========== build 07D0 ================================================
+
+28-Oct =========== build 07D0 ================================================
+
+18-Jan =========== build 07D2 ================================================
+n18-Jan =========== build 07D3 ================
+n19-Jan =========== build 07D4 ================
+n19-Jan =========== build 07D5 ================
+n20-Jan =========== build 07D6 ================
+n20-Jan =========== build 07D7 ================
+n20-Jan =========== build 07D8 ================
+n20-Jan =========== build 07D9 ================
+n20-Jan =========== build 07DA ================
+n20-Jan =========== build 07DB ================
+n20-Jan =========== build 07DC ================
--- /dev/null
+================================================================================
+The contents of this distribution are copyrighted and licensed as follows:
+================================================================================
+
+ - src/org/ibex/TinySSL.java is Copyright 2002 Adam Megacz, and is
+ licensed under the GNU Library General Public License; you may
+ reuse it in closed source applications under certain conditions;
+ see the LGPL (attached below).
+
+ - src/org/ibex/js/Lexer.java was partially derived from the Rhino
+ JavaScript interpreter; hence is covered by the Netscape Public
+ License.
+
+ - src/org/mozilla/** contains the Rhino JavaScript Interpreter,
+ which is Copyright Netscape Communications Corporation, and is
+ licensed under the Netscape Public License.
+
+ - lib/netscape.jar and lib/signtool are Copyright Netscape
+ Communications Corporation
+
+ - lib/msjvm.jar, lib/cabarc.exe, lib/signcode.exe, and
+ lib/guidgen.exe are Copyright Microsoft Corporation
+
+ - lib/javago is a compiled binary copy of the JavaGO global
+ optimizer, written by Konstantin Knizhnik and "is freeware and is
+ distributed without any restrictions on its usage"
+
+ - src/org/ibex/PNG.java is Copyright (c) 1997, Jason
+ Marshall. All Rights Reserved. Additional licensing terms are
+ contained in that file.
+
+ - src/org/ibex/GIF.java is Copyright D. J. Hagberg, Jr. Additional
+ licensing terms are contained in that file.
+
+ - the contents of src/org/bouncycastle is Copyright (c) 2000-2002 The
+ Legion Of The Bouncy Castle (http://www.bouncycastle.org); licensing
+ terms are available at http://www.bouncycastle.org/license.html
+
+ - All other files are Copyright 2003 Adam Megacz, all rights
+ reserved, all disclaimable warranties disclaimed.
+
+ You may redistribute and/or modify the Ibex engine (src/org/ibex/
+ and all subdirectories) under the GNU General Public License
+ ("GPL", included below), version 2 ONLY (not any prior or later
+ versions), subject to the following two clarifications:
+
+ As a clarification to the General Public License, any data files
+ (.ibex, .gif, .png) loaded into a running copy of the Ibex Engine,
+ are specifically NOT considered "derivitave works" of the engine,
+ so long as they do not contain any code copied from the engine.
+
+ - The Bitstream Vera Font (upstream/vera) is under its own copyright
+
+
+========================================================================
+The GNU General Public License
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
+
+
+
+========================================================================
+The GNU Lesser General Public License
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
+
+
+============================================================================
+The Apache Software License, Version 1.1
+
+/*
+ * ============================================================================
+ * The Apache Software License, Version 1.1
+ * ============================================================================
+ *
+ * Copyright (C) 1999 The Apache Software Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modifica-
+ * tion, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ * include the following acknowledgment: "This product includes software
+ * developed by the Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgment may appear in the software itself, if
+ * and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Ant" and "Apache Software Foundation" must not be used to
+ * endorse or promote products derived from this software without prior
+ * written permission. For written permission, please contact
+ * apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache", nor may
+ * "Apache" appear in their name, without prior written permission of the
+ * Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
+ * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * on behalf of the Apache Software Foundation. For more information on the
+ * Apache Software Foundation, please see <http://www.apache.org/>.
+ *
+ */
+
+
+
+
+=============================================================================
+The ZLIB License
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any
+damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute
+it freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must
+ not claim that you wrote the original software. If you use this
+ software in a product, an acknowledgment in the product
+ documentation would be appreciated but is not required.
+
+2. Altered source versions must be plainly marked as such, and must
+ not be misrepresented as being the original software.
+
+3. This notice may not be removed or altered from any source
+ distribution.
+
+
+
+================================================================================
+The Netscape Public License
+
+
+ AMENDMENTS
+
+ The Netscape Public License Version 1.1 ("NPL") consists of the
+ Mozilla Public License Version 1.1 with the following Amendments,
+ including Exhibit A-Netscape Public License. Files identified with
+ "Exhibit A-Netscape Public License" are governed by the Netscape
+ Public License Version 1.1.
+
+ Additional Terms applicable to the Netscape Public License.
+ I. Effect.
+ These additional terms described in this Netscape Public
+ License -- Amendments shall apply to the Mozilla Communicator
+ client code and to all Covered Code under this License.
+
+ II. "Netscape's Branded Code" means Covered Code that Netscape
+ distributes and/or permits others to distribute under one or more
+ trademark(s) which are controlled by Netscape but which are not
+ licensed for use under this License.
+
+ III. Netscape and logo.
+ This License does not grant any rights to use the trademarks
+ "Netscape", the "Netscape N and horizon" logo or the "Netscape
+ lighthouse" logo, "Netcenter", "Gecko", "Java" or "JavaScript",
+ "Smart Browsing" even if such marks are included in the Original
+ Code or Modifications.
+
+ IV. Inability to Comply Due to Contractual Obligation.
+ Prior to licensing the Original Code under this License, Netscape
+ has licensed third party code for use in Netscape's Branded Code.
+ To the extent that Netscape is limited contractually from making
+ such third party code available under this License, Netscape may
+ choose to reintegrate such code into Covered Code without being
+ required to distribute such code in Source Code form, even if
+ such code would otherwise be considered "Modifications" under
+ this License.
+
+ V. Use of Modifications and Covered Code by Initial Developer.
+ V.1. In General.
+ The obligations of Section 3 apply to Netscape, except to
+ the extent specified in this Amendment, Section V.2 and V.3.
+
+ V.2. Other Products.
+ Netscape may include Covered Code in products other than the
+ Netscape's Branded Code which are released by Netscape
+ during the two (2) years following the release date of the
+ Original Code, without such additional products becoming
+ subject to the terms of this License, and may license such
+ additional products on different terms from those contained
+ in this License.
+
+ V.3. Alternative Licensing.
+ Netscape may license the Source Code of Netscape's Branded
+ Code, including Modifications incorporated therein, without
+ such Netscape Branded Code becoming subject to the terms of
+ this License, and may license such Netscape Branded Code on
+ different terms from those contained in this License.
+
+ VI. Litigation.
+ Notwithstanding the limitations of Section 11 above, the
+ provisions regarding litigation in Section 11(a), (b) and (c) of
+ the License shall apply to all disputes relating to this License.
+
+ EXHIBIT A-Netscape Public License.
+
+ "The contents of this file are subject to the Netscape Public
+ License Version 1.1 (the "License"); you may not use this file
+ except in compliance with the License. You may obtain a copy of
+ the License at http://www.mozilla.org/NPL/
+
+ Software distributed under the License is distributed on an "AS
+ IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ rights and limitations under the License.
+
+ The Original Code is Mozilla Communicator client code, released
+ March 31, 1998.
+
+ The Initial Developer of the Original Code is Netscape
+ Communications Corporation. Portions created by Netscape are
+ Copyright (C) 1998-1999 Netscape Communications Corporation. All
+ Rights Reserved.
+
+ Contributor(s): ______________________________________.
+
+ Alternatively, the contents of this file may be used under the
+ terms of the _____ license (the "[___] License"), in which case
+ the provisions of [______] License are applicable instead of
+ those above. If you wish to allow use of your version of this
+ file only under the terms of the [____] License and not to allow
+ others to use your version of this file under the NPL, indicate
+ your decision by deleting the provisions above and replace them
+ with the notice and other provisions required by the [___]
+ License. If you do not delete the provisions above, a recipient
+ may use your version of this file under either the NPL or the
+ [___] License."
+
+ ----------------------------------------------------------------------
+
+ MOZILLA PUBLIC LICENSE
+ Version 1.1
+
+ ---------------
+
+1. Definitions.
+
+ 1.0.1. "Commercial Use" means distribution or otherwise making the
+ Covered Code available to a third party.
+
+ 1.1. "Contributor" means each entity that creates or contributes to
+ the creation of Modifications.
+
+ 1.2. "Contributor Version" means the combination of the Original
+ Code, prior Modifications used by a Contributor, and the Modifications
+ made by that particular Contributor.
+
+ 1.3. "Covered Code" means the Original Code or Modifications or the
+ combination of the Original Code and Modifications, in each case
+ including portions thereof.
+
+ 1.4. "Electronic Distribution Mechanism" means a mechanism generally
+ accepted in the software development community for the electronic
+ transfer of data.
+
+ 1.5. "Executable" means Covered Code in any form other than Source
+ Code.
+
+ 1.6. "Initial Developer" means the individual or entity identified
+ as the Initial Developer in the Source Code notice required by Exhibit
+ A.
+
+ 1.7. "Larger Work" means a work which combines Covered Code or
+ portions thereof with code not governed by the terms of this License.
+
+ 1.8. "License" means this document.
+
+ 1.8.1. "Licensable" means having the right to grant, to the maximum
+ extent possible, whether at the time of the initial grant or
+ subsequently acquired, any and all of the rights conveyed herein.
+
+ 1.9. "Modifications" means any addition to or deletion from the
+ substance or structure of either the Original Code or any previous
+ Modifications. When Covered Code is released as a series of files, a
+ Modification is:
+ A. Any addition to or deletion from the contents of a file
+ containing Original Code or previous Modifications.
+
+ B. Any new file that contains any part of the Original Code or
+ previous Modifications.
+
+ 1.10. "Original Code" means Source Code of computer software code
+ which is described in the Source Code notice required by Exhibit A as
+ Original Code, and which, at the time of its release under this
+ License is not already Covered Code governed by this License.
+
+ 1.10.1. "Patent Claims" means any patent claim(s), now owned or
+ hereafter acquired, including without limitation, method, process,
+ and apparatus claims, in any patent Licensable by grantor.
+
+ 1.11. "Source Code" means the preferred form of the Covered Code for
+ making modifications to it, including all modules it contains, plus
+ any associated interface definition files, scripts used to control
+ compilation and installation of an Executable, or source code
+ differential comparisons against either the Original Code or another
+ well known, available Covered Code of the Contributor's choice. The
+ Source Code can be in a compressed or archival form, provided the
+ appropriate decompression or de-archiving software is widely available
+ for no charge.
+
+ 1.12. "You" (or "Your") means an individual or a legal entity
+ exercising rights under, and complying with all of the terms of, this
+ License or a future version of this License issued under Section 6.1.
+ For legal entities, "You" includes any entity which controls, is
+ controlled by, or is under common control with You. For purposes of
+ this definition, "control" means (a) the power, direct or indirect,
+ to cause the direction or management of such entity, whether by
+ contract or otherwise, or (b) ownership of more than fifty percent
+ (50%) of the outstanding shares or beneficial ownership of such
+ entity.
+
+2. Source Code License.
+
+ 2.1. The Initial Developer Grant.
+ The Initial Developer hereby grants You a world-wide, royalty-free,
+ non-exclusive license, subject to third party intellectual property
+ claims:
+ (a) under intellectual property rights (other than patent or
+ trademark) Licensable by Initial Developer to use, reproduce,
+ modify, display, perform, sublicense and distribute the Original
+ Code (or portions thereof) with or without Modifications, and/or
+ as part of a Larger Work; and
+
+ (b) under Patents Claims infringed by the making, using or
+ selling of Original Code, to make, have made, use, practice,
+ sell, and offer for sale, and/or otherwise dispose of the
+ Original Code (or portions thereof).
+
+ (c) the licenses granted in this Section 2.1(a) and (b) are
+ effective on the date Initial Developer first distributes
+ Original Code under the terms of this License.
+
+ (d) Notwithstanding Section 2.1(b) above, no patent license is
+ granted: 1) for code that You delete from the Original Code; 2)
+ separate from the Original Code; or 3) for infringements caused
+ by: i) the modification of the Original Code or ii) the
+ combination of the Original Code with other software or devices.
+
+ 2.2. Contributor Grant.
+ Subject to third party intellectual property claims, each Contributor
+ hereby grants You a world-wide, royalty-free, non-exclusive license
+
+ (a) under intellectual property rights (other than patent or
+ trademark) Licensable by Contributor, to use, reproduce, modify,
+ display, perform, sublicense and distribute the Modifications
+ created by such Contributor (or portions thereof) either on an
+ unmodified basis, with other Modifications, as Covered Code
+ and/or as part of a Larger Work; and
+
+ (b) under Patent Claims infringed by the making, using, or
+ selling of Modifications made by that Contributor either alone
+ and/or in combination with its Contributor Version (or portions
+ of such combination), to make, use, sell, offer for sale, have
+ made, and/or otherwise dispose of: 1) Modifications made by that
+ Contributor (or portions thereof); and 2) the combination of
+ Modifications made by that Contributor with its Contributor
+ Version (or portions of such combination).
+
+ (c) the licenses granted in Sections 2.2(a) and 2.2(b) are
+ effective on the date Contributor first makes Commercial Use of
+ the Covered Code.
+
+ (d) Notwithstanding Section 2.2(b) above, no patent license is
+ granted: 1) for any code that Contributor has deleted from the
+ Contributor Version; 2) separate from the Contributor Version;
+ 3) for infringements caused by: i) third party modifications of
+ Contributor Version or ii) the combination of Modifications made
+ by that Contributor with other software (except as part of the
+ Contributor Version) or other devices; or 4) under Patent Claims
+ infringed by Covered Code in the absence of Modifications made by
+ that Contributor.
+
+3. Distribution Obligations.
+
+ 3.1. Application of License.
+ The Modifications which You create or to which You contribute are
+ governed by the terms of this License, including without limitation
+ Section 2.2. The Source Code version of Covered Code may be
+ distributed only under the terms of this License or a future version
+ of this License released under Section 6.1, and You must include a
+ copy of this License with every copy of the Source Code You
+ distribute. You may not offer or impose any terms on any Source Code
+ version that alters or restricts the applicable version of this
+ License or the recipients' rights hereunder. However, You may include
+ an additional document offering the additional rights described in
+ Section 3.5.
+
+ 3.2. Availability of Source Code.
+ Any Modification which You create or to which You contribute must be
+ made available in Source Code form under the terms of this License
+ either on the same media as an Executable version or via an accepted
+ Electronic Distribution Mechanism to anyone to whom you made an
+ Executable version available; and if made available via Electronic
+ Distribution Mechanism, must remain available for at least twelve (12)
+ months after the date it initially became available, or at least six
+ (6) months after a subsequent version of that particular Modification
+ has been made available to such recipients. You are responsible for
+ ensuring that the Source Code version remains available even if the
+ Electronic Distribution Mechanism is maintained by a third party.
+
+ 3.3. Description of Modifications.
+ You must cause all Covered Code to which You contribute to contain a
+ file documenting the changes You made to create that Covered Code and
+ the date of any change. You must include a prominent statement that
+ the Modification is derived, directly or indirectly, from Original
+ Code provided by the Initial Developer and including the name of the
+ Initial Developer in (a) the Source Code, and (b) in any notice in an
+ Executable version or related documentation in which You describe the
+ origin or ownership of the Covered Code.
+
+ 3.4. Intellectual Property Matters
+ (a) Third Party Claims.
+ If Contributor has knowledge that a license under a third party's
+ intellectual property rights is required to exercise the rights
+ granted by such Contributor under Sections 2.1 or 2.2,
+ Contributor must include a text file with the Source Code
+ distribution titled "LEGAL" which describes the claim and the
+ party making the claim in sufficient detail that a recipient will
+ know whom to contact. If Contributor obtains such knowledge after
+ the Modification is made available as described in Section 3.2,
+ Contributor shall promptly modify the LEGAL file in all copies
+ Contributor makes available thereafter and shall take other steps
+ (such as notifying appropriate mailing lists or newsgroups)
+ reasonably calculated to inform those who received the Covered
+ Code that new knowledge has been obtained.
+
+ (b) Contributor APIs.
+ If Contributor's Modifications include an application programming
+ interface and Contributor has knowledge of patent licenses which
+ are reasonably necessary to implement that API, Contributor must
+ also include this information in the LEGAL file.
+
+ (c) Representations.
+ Contributor represents that, except as disclosed pursuant to
+ Section 3.4(a) above, Contributor believes that Contributor's
+ Modifications are Contributor's original creation(s) and/or
+ Contributor has sufficient rights to grant the rights conveyed by
+ this License.
+
+ 3.5. Required Notices.
+ You must duplicate the notice in Exhibit A in each file of the Source
+ Code. If it is not possible to put such notice in a particular Source
+ Code file due to its structure, then You must include such notice in a
+ location (such as a relevant directory) where a user would be likely
+ to look for such a notice. If You created one or more Modification(s)
+ You may add your name as a Contributor to the notice described in
+ Exhibit A. You must also duplicate this License in any documentation
+ for the Source Code where You describe recipients' rights or ownership
+ rights relating to Covered Code. You may choose to offer, and to
+ charge a fee for, warranty, support, indemnity or liability
+ obligations to one or more recipients of Covered Code. However, You
+ may do so only on Your own behalf, and not on behalf of the Initial
+ Developer or any Contributor. You must make it absolutely clear than
+ any such warranty, support, indemnity or liability obligation is
+ offered by You alone, and You hereby agree to indemnify the Initial
+ Developer and every Contributor for any liability incurred by the
+ Initial Developer or such Contributor as a result of warranty,
+ support, indemnity or liability terms You offer.
+
+ 3.6. Distribution of Executable Versions.
+ You may distribute Covered Code in Executable form only if the
+ requirements of Section 3.1-3.5 have been met for that Covered Code,
+ and if You include a notice stating that the Source Code version of
+ the Covered Code is available under the terms of this License,
+ including a description of how and where You have fulfilled the
+ obligations of Section 3.2. The notice must be conspicuously included
+ in any notice in an Executable version, related documentation or
+ collateral in which You describe recipients' rights relating to the
+ Covered Code. You may distribute the Executable version of Covered
+ Code or ownership rights under a license of Your choice, which may
+ contain terms different from this License, provided that You are in
+ compliance with the terms of this License and that the license for the
+ Executable version does not attempt to limit or alter the recipient's
+ rights in the Source Code version from the rights set forth in this
+ License. If You distribute the Executable version under a different
+ license You must make it absolutely clear that any terms which differ
+ from this License are offered by You alone, not by the Initial
+ Developer or any Contributor. You hereby agree to indemnify the
+ Initial Developer and every Contributor for any liability incurred by
+ the Initial Developer or such Contributor as a result of any such
+ terms You offer.
+
+ 3.7. Larger Works.
+ You may create a Larger Work by combining Covered Code with other code
+ not governed by the terms of this License and distribute the Larger
+ Work as a single product. In such a case, You must make sure the
+ requirements of this License are fulfilled for the Covered Code.
+
+4. Inability to Comply Due to Statute or Regulation.
+
+ If it is impossible for You to comply with any of the terms of this
+ License with respect to some or all of the Covered Code due to
+ statute, judicial order, or regulation then You must: (a) comply with
+ the terms of this License to the maximum extent possible; and (b)
+ describe the limitations and the code they affect. Such description
+ must be included in the LEGAL file described in Section 3.4 and must
+ be included with all distributions of the Source Code. Except to the
+ extent prohibited by statute or regulation, such description must be
+ sufficiently detailed for a recipient of ordinary skill to be able to
+ understand it.
+
+5. Application of this License.
+
+ This License applies to code to which the Initial Developer has
+ attached the notice in Exhibit A and to related Covered Code.
+
+6. Versions of the License.
+
+ 6.1. New Versions.
+ Netscape Communications Corporation ("Netscape") may publish revised
+ and/or new versions of the License from time to time. Each version
+ will be given a distinguishing version number.
+
+ 6.2. Effect of New Versions.
+ Once Covered Code has been published under a particular version of the
+ License, You may always continue to use it under the terms of that
+ version. You may also choose to use such Covered Code under the terms
+ of any subsequent version of the License published by Netscape. No one
+ other than Netscape has the right to modify the terms applicable to
+ Covered Code created under this License.
+
+ 6.3. Derivative Works.
+ If You create or use a modified version of this License (which you may
+ only do in order to apply it to code which is not already Covered Code
+ governed by this License), You must (a) rename Your license so that
+ the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape",
+ "MPL", "NPL" or any confusingly similar phrase do not appear in your
+ license (except to note that your license differs from this License)
+ and (b) otherwise make it clear that Your version of the license
+ contains terms which differ from the Mozilla Public License and
+ Netscape Public License. (Filling in the name of the Initial
+ Developer, Original Code or Contributor in the notice described in
+ Exhibit A shall not of themselves be deemed to be modifications of
+ this License.)
+
+7. DISCLAIMER OF WARRANTY.
+
+ COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF
+ DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING.
+ THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE
+ IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT,
+ YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE
+ COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER
+ OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF
+ ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
+
+8. TERMINATION.
+
+ 8.1. This License and the rights granted hereunder will terminate
+ automatically if You fail to comply with terms herein and fail to cure
+ such breach within 30 days of becoming aware of the breach. All
+ sublicenses to the Covered Code which are properly granted shall
+ survive any termination of this License. Provisions which, by their
+ nature, must remain in effect beyond the termination of this License
+ shall survive.
+
+ 8.2. If You initiate litigation by asserting a patent infringement
+ claim (excluding declatory judgment actions) against Initial Developer
+ or a Contributor (the Initial Developer or Contributor against whom
+ You file such action is referred to as "Participant") alleging that:
+
+ (a) such Participant's Contributor Version directly or indirectly
+ infringes any patent, then any and all rights granted by such
+ Participant to You under Sections 2.1 and/or 2.2 of this License
+ shall, upon 60 days notice from Participant terminate prospectively,
+ unless if within 60 days after receipt of notice You either: (i)
+ agree in writing to pay Participant a mutually agreeable reasonable
+ royalty for Your past and future use of Modifications made by such
+ Participant, or (ii) withdraw Your litigation claim with respect to
+ the Contributor Version against such Participant. If within 60 days
+ of notice, a reasonable royalty and payment arrangement are not
+ mutually agreed upon in writing by the parties or the litigation claim
+ is not withdrawn, the rights granted by Participant to You under
+ Sections 2.1 and/or 2.2 automatically terminate at the expiration of
+ the 60 day notice period specified above.
+
+ (b) any software, hardware, or device, other than such Participant's
+ Contributor Version, directly or indirectly infringes any patent, then
+ any rights granted to You by such Participant under Sections 2.1(b)
+ and 2.2(b) are revoked effective as of the date You first made, used,
+ sold, distributed, or had made, Modifications made by that
+ Participant.
+
+ 8.3. If You assert a patent infringement claim against Participant
+ alleging that such Participant's Contributor Version directly or
+ indirectly infringes any patent where such claim is resolved (such as
+ by license or settlement) prior to the initiation of patent
+ infringement litigation, then the reasonable value of the licenses
+ granted by such Participant under Sections 2.1 or 2.2 shall be taken
+ into account in determining the amount or value of any payment or
+ license.
+
+ 8.4. In the event of termination under Sections 8.1 or 8.2 above,
+ all end user license agreements (excluding distributors and resellers)
+ which have been validly granted by You or any distributor hereunder
+ prior to termination shall survive termination.
+
+9. LIMITATION OF LIABILITY.
+
+ UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT
+ (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL
+ DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE,
+ OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR
+ ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY
+ CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL,
+ WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER
+ COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN
+ INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF
+ LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY
+ RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW
+ PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE
+ EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO
+ THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU.
+
+10. U.S. GOVERNMENT END USERS.
+
+ The Covered Code is a "commercial item," as that term is defined in
+ 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer
+ software" and "commercial computer software documentation," as such
+ terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48
+ C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995),
+ all U.S. Government End Users acquire Covered Code with only those
+ rights set forth herein.
+
+11. MISCELLANEOUS.
+
+ This License represents the complete agreement concerning subject
+ matter hereof. If any provision of this License is held to be
+ unenforceable, such provision shall be reformed only to the extent
+ necessary to make it enforceable. This License shall be governed by
+ California law provisions (except to the extent applicable law, if
+ any, provides otherwise), excluding its conflict-of-law provisions.
+ With respect to disputes in which at least one party is a citizen of,
+ or an entity chartered or registered to do business in the United
+ States of America, any litigation relating to this License shall be
+ subject to the jurisdiction of the Federal Courts of the Northern
+ District of California, with venue lying in Santa Clara County,
+ California, with the losing party responsible for costs, including
+ without limitation, court costs and reasonable attorneys' fees and
+ expenses. The application of the United Nations Convention on
+ Contracts for the International Sale of Goods is expressly excluded.
+ Any law or regulation which provides that the language of a contract
+ shall be construed against the drafter shall not apply to this
+ License.
+
+12. RESPONSIBILITY FOR CLAIMS.
+
+ As between Initial Developer and the Contributors, each party is
+ responsible for claims and damages arising, directly or indirectly,
+ out of its utilization of rights under this License and You agree to
+ work with Initial Developer and Contributors to distribute such
+ responsibility on an equitable basis. Nothing herein is intended or
+ shall be deemed to constitute any admission of liability.
+
+13. MULTIPLE-LICENSED CODE.
+
+ Initial Developer may designate portions of the Covered Code as
+ "Multiple-Licensed". "Multiple-Licensed" means that the Initial
+ Developer permits you to utilize portions of the Covered Code under
+ Your choice of the NPL or the alternative licenses, if any, specified
+ by the Initial Developer in the file described in Exhibit A.
+
+EXHIBIT A -Mozilla Public License.
+
+ ``The contents of this file are subject to the Mozilla Public License
+ Version 1.1 (the "License"); you may not use this file except in
+ compliance with the License. You may obtain a copy of the License at
+ http://www.mozilla.org/MPL/
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+ License for the specific language governing rights and limitations
+ under the License.
+
+ The Original Code is ______________________________________.
+
+ The Initial Developer of the Original Code is ________________________.
+ Portions created by ______________________ are Copyright (C) ______
+ _______________________. All Rights Reserved.
+
+ Contributor(s): ______________________________________.
+
+ Alternatively, the contents of this file may be used under the terms
+ of the _____ license (the "[___] License"), in which case the
+ provisions of [______] License are applicable instead of those
+ above. If you wish to allow use of your version of this file only
+ under the terms of the [____] License and not to allow others to use
+ your version of this file under the MPL, indicate your decision by
+ deleting the provisions above and replace them with the notice and
+ other provisions required by the [___] License. If you do not delete
+ the provisions above, a recipient may use your version of this file
+ under either the MPL or the [___] License."
+
+ [NOTE: The text of this Exhibit A may differ slightly from the text of
+ the notices in the Source Code files of the Original Code. You should
+ use the text of this Exhibit A rather than the text found in the
+ Original Code Source Code for Your Modifications.]
+
+
+
+================================================================================
+The Mozilla Public License
+
+ MOZILLA PUBLIC LICENSE
+ Version 1.1
+
+ ---------------
+
+1. Definitions.
+
+ 1.0.1. "Commercial Use" means distribution or otherwise making the
+ Covered Code available to a third party.
+
+ 1.1. "Contributor" means each entity that creates or contributes to
+ the creation of Modifications.
+
+ 1.2. "Contributor Version" means the combination of the Original
+ Code, prior Modifications used by a Contributor, and the Modifications
+ made by that particular Contributor.
+
+ 1.3. "Covered Code" means the Original Code or Modifications or the
+ combination of the Original Code and Modifications, in each case
+ including portions thereof.
+
+ 1.4. "Electronic Distribution Mechanism" means a mechanism generally
+ accepted in the software development community for the electronic
+ transfer of data.
+
+ 1.5. "Executable" means Covered Code in any form other than Source
+ Code.
+
+ 1.6. "Initial Developer" means the individual or entity identified
+ as the Initial Developer in the Source Code notice required by Exhibit
+ A.
+
+ 1.7. "Larger Work" means a work which combines Covered Code or
+ portions thereof with code not governed by the terms of this License.
+
+ 1.8. "License" means this document.
+
+ 1.8.1. "Licensable" means having the right to grant, to the maximum
+ extent possible, whether at the time of the initial grant or
+ subsequently acquired, any and all of the rights conveyed herein.
+
+ 1.9. "Modifications" means any addition to or deletion from the
+ substance or structure of either the Original Code or any previous
+ Modifications. When Covered Code is released as a series of files, a
+ Modification is:
+ A. Any addition to or deletion from the contents of a file
+ containing Original Code or previous Modifications.
+
+ B. Any new file that contains any part of the Original Code or
+ previous Modifications.
+
+ 1.10. "Original Code" means Source Code of computer software code
+ which is described in the Source Code notice required by Exhibit A as
+ Original Code, and which, at the time of its release under this
+ License is not already Covered Code governed by this License.
+
+ 1.10.1. "Patent Claims" means any patent claim(s), now owned or
+ hereafter acquired, including without limitation, method, process,
+ and apparatus claims, in any patent Licensable by grantor.
+
+ 1.11. "Source Code" means the preferred form of the Covered Code for
+ making modifications to it, including all modules it contains, plus
+ any associated interface definition files, scripts used to control
+ compilation and installation of an Executable, or source code
+ differential comparisons against either the Original Code or another
+ well known, available Covered Code of the Contributor's choice. The
+ Source Code can be in a compressed or archival form, provided the
+ appropriate decompression or de-archiving software is widely available
+ for no charge.
+
+ 1.12. "You" (or "Your") means an individual or a legal entity
+ exercising rights under, and complying with all of the terms of, this
+ License or a future version of this License issued under Section 6.1.
+ For legal entities, "You" includes any entity which controls, is
+ controlled by, or is under common control with You. For purposes of
+ this definition, "control" means (a) the power, direct or indirect,
+ to cause the direction or management of such entity, whether by
+ contract or otherwise, or (b) ownership of more than fifty percent
+ (50%) of the outstanding shares or beneficial ownership of such
+ entity.
+
+2. Source Code License.
+
+ 2.1. The Initial Developer Grant.
+ The Initial Developer hereby grants You a world-wide, royalty-free,
+ non-exclusive license, subject to third party intellectual property
+ claims:
+ (a) under intellectual property rights (other than patent or
+ trademark) Licensable by Initial Developer to use, reproduce,
+ modify, display, perform, sublicense and distribute the Original
+ Code (or portions thereof) with or without Modifications, and/or
+ as part of a Larger Work; and
+
+ (b) under Patents Claims infringed by the making, using or
+ selling of Original Code, to make, have made, use, practice,
+ sell, and offer for sale, and/or otherwise dispose of the
+ Original Code (or portions thereof).
+
+ (c) the licenses granted in this Section 2.1(a) and (b) are
+ effective on the date Initial Developer first distributes
+ Original Code under the terms of this License.
+
+ (d) Notwithstanding Section 2.1(b) above, no patent license is
+ granted: 1) for code that You delete from the Original Code; 2)
+ separate from the Original Code; or 3) for infringements caused
+ by: i) the modification of the Original Code or ii) the
+ combination of the Original Code with other software or devices.
+
+ 2.2. Contributor Grant.
+ Subject to third party intellectual property claims, each Contributor
+ hereby grants You a world-wide, royalty-free, non-exclusive license
+
+ (a) under intellectual property rights (other than patent or
+ trademark) Licensable by Contributor, to use, reproduce, modify,
+ display, perform, sublicense and distribute the Modifications
+ created by such Contributor (or portions thereof) either on an
+ unmodified basis, with other Modifications, as Covered Code
+ and/or as part of a Larger Work; and
+
+ (b) under Patent Claims infringed by the making, using, or
+ selling of Modifications made by that Contributor either alone
+ and/or in combination with its Contributor Version (or portions
+ of such combination), to make, use, sell, offer for sale, have
+ made, and/or otherwise dispose of: 1) Modifications made by that
+ Contributor (or portions thereof); and 2) the combination of
+ Modifications made by that Contributor with its Contributor
+ Version (or portions of such combination).
+
+ (c) the licenses granted in Sections 2.2(a) and 2.2(b) are
+ effective on the date Contributor first makes Commercial Use of
+ the Covered Code.
+
+ (d) Notwithstanding Section 2.2(b) above, no patent license is
+ granted: 1) for any code that Contributor has deleted from the
+ Contributor Version; 2) separate from the Contributor Version;
+ 3) for infringements caused by: i) third party modifications of
+ Contributor Version or ii) the combination of Modifications made
+ by that Contributor with other software (except as part of the
+ Contributor Version) or other devices; or 4) under Patent Claims
+ infringed by Covered Code in the absence of Modifications made by
+ that Contributor.
+
+3. Distribution Obligations.
+
+ 3.1. Application of License.
+ The Modifications which You create or to which You contribute are
+ governed by the terms of this License, including without limitation
+ Section 2.2. The Source Code version of Covered Code may be
+ distributed only under the terms of this License or a future version
+ of this License released under Section 6.1, and You must include a
+ copy of this License with every copy of the Source Code You
+ distribute. You may not offer or impose any terms on any Source Code
+ version that alters or restricts the applicable version of this
+ License or the recipients' rights hereunder. However, You may include
+ an additional document offering the additional rights described in
+ Section 3.5.
+
+ 3.2. Availability of Source Code.
+ Any Modification which You create or to which You contribute must be
+ made available in Source Code form under the terms of this License
+ either on the same media as an Executable version or via an accepted
+ Electronic Distribution Mechanism to anyone to whom you made an
+ Executable version available; and if made available via Electronic
+ Distribution Mechanism, must remain available for at least twelve (12)
+ months after the date it initially became available, or at least six
+ (6) months after a subsequent version of that particular Modification
+ has been made available to such recipients. You are responsible for
+ ensuring that the Source Code version remains available even if the
+ Electronic Distribution Mechanism is maintained by a third party.
+
+ 3.3. Description of Modifications.
+ You must cause all Covered Code to which You contribute to contain a
+ file documenting the changes You made to create that Covered Code and
+ the date of any change. You must include a prominent statement that
+ the Modification is derived, directly or indirectly, from Original
+ Code provided by the Initial Developer and including the name of the
+ Initial Developer in (a) the Source Code, and (b) in any notice in an
+ Executable version or related documentation in which You describe the
+ origin or ownership of the Covered Code.
+
+ 3.4. Intellectual Property Matters
+ (a) Third Party Claims.
+ If Contributor has knowledge that a license under a third party's
+ intellectual property rights is required to exercise the rights
+ granted by such Contributor under Sections 2.1 or 2.2,
+ Contributor must include a text file with the Source Code
+ distribution titled "LEGAL" which describes the claim and the
+ party making the claim in sufficient detail that a recipient will
+ know whom to contact. If Contributor obtains such knowledge after
+ the Modification is made available as described in Section 3.2,
+ Contributor shall promptly modify the LEGAL file in all copies
+ Contributor makes available thereafter and shall take other steps
+ (such as notifying appropriate mailing lists or newsgroups)
+ reasonably calculated to inform those who received the Covered
+ Code that new knowledge has been obtained.
+
+ (b) Contributor APIs.
+ If Contributor's Modifications include an application programming
+ interface and Contributor has knowledge of patent licenses which
+ are reasonably necessary to implement that API, Contributor must
+ also include this information in the LEGAL file.
+
+ (c) Representations.
+ Contributor represents that, except as disclosed pursuant to
+ Section 3.4(a) above, Contributor believes that Contributor's
+ Modifications are Contributor's original creation(s) and/or
+ Contributor has sufficient rights to grant the rights conveyed by
+ this License.
+
+ 3.5. Required Notices.
+ You must duplicate the notice in Exhibit A in each file of the Source
+ Code. If it is not possible to put such notice in a particular Source
+ Code file due to its structure, then You must include such notice in a
+ location (such as a relevant directory) where a user would be likely
+ to look for such a notice. If You created one or more Modification(s)
+ You may add your name as a Contributor to the notice described in
+ Exhibit A. You must also duplicate this License in any documentation
+ for the Source Code where You describe recipients' rights or ownership
+ rights relating to Covered Code. You may choose to offer, and to
+ charge a fee for, warranty, support, indemnity or liability
+ obligations to one or more recipients of Covered Code. However, You
+ may do so only on Your own behalf, and not on behalf of the Initial
+ Developer or any Contributor. You must make it absolutely clear than
+ any such warranty, support, indemnity or liability obligation is
+ offered by You alone, and You hereby agree to indemnify the Initial
+ Developer and every Contributor for any liability incurred by the
+ Initial Developer or such Contributor as a result of warranty,
+ support, indemnity or liability terms You offer.
+
+ 3.6. Distribution of Executable Versions.
+ You may distribute Covered Code in Executable form only if the
+ requirements of Section 3.1-3.5 have been met for that Covered Code,
+ and if You include a notice stating that the Source Code version of
+ the Covered Code is available under the terms of this License,
+ including a description of how and where You have fulfilled the
+ obligations of Section 3.2. The notice must be conspicuously included
+ in any notice in an Executable version, related documentation or
+ collateral in which You describe recipients' rights relating to the
+ Covered Code. You may distribute the Executable version of Covered
+ Code or ownership rights under a license of Your choice, which may
+ contain terms different from this License, provided that You are in
+ compliance with the terms of this License and that the license for the
+ Executable version does not attempt to limit or alter the recipient's
+ rights in the Source Code version from the rights set forth in this
+ License. If You distribute the Executable version under a different
+ license You must make it absolutely clear that any terms which differ
+ from this License are offered by You alone, not by the Initial
+ Developer or any Contributor. You hereby agree to indemnify the
+ Initial Developer and every Contributor for any liability incurred by
+ the Initial Developer or such Contributor as a result of any such
+ terms You offer.
+
+ 3.7. Larger Works.
+ You may create a Larger Work by combining Covered Code with other code
+ not governed by the terms of this License and distribute the Larger
+ Work as a single product. In such a case, You must make sure the
+ requirements of this License are fulfilled for the Covered Code.
+
+4. Inability to Comply Due to Statute or Regulation.
+
+ If it is impossible for You to comply with any of the terms of this
+ License with respect to some or all of the Covered Code due to
+ statute, judicial order, or regulation then You must: (a) comply with
+ the terms of this License to the maximum extent possible; and (b)
+ describe the limitations and the code they affect. Such description
+ must be included in the LEGAL file described in Section 3.4 and must
+ be included with all distributions of the Source Code. Except to the
+ extent prohibited by statute or regulation, such description must be
+ sufficiently detailed for a recipient of ordinary skill to be able to
+ understand it.
+
+5. Application of this License.
+
+ This License applies to code to which the Initial Developer has
+ attached the notice in Exhibit A and to related Covered Code.
+
+6. Versions of the License.
+
+ 6.1. New Versions.
+ Netscape Communications Corporation ("Netscape") may publish revised
+ and/or new versions of the License from time to time. Each version
+ will be given a distinguishing version number.
+
+ 6.2. Effect of New Versions.
+ Once Covered Code has been published under a particular version of the
+ License, You may always continue to use it under the terms of that
+ version. You may also choose to use such Covered Code under the terms
+ of any subsequent version of the License published by Netscape. No one
+ other than Netscape has the right to modify the terms applicable to
+ Covered Code created under this License.
+
+ 6.3. Derivative Works.
+ If You create or use a modified version of this License (which you may
+ only do in order to apply it to code which is not already Covered Code
+ governed by this License), You must (a) rename Your license so that
+ the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape",
+ "MPL", "NPL" or any confusingly similar phrase do not appear in your
+ license (except to note that your license differs from this License)
+ and (b) otherwise make it clear that Your version of the license
+ contains terms which differ from the Mozilla Public License and
+ Netscape Public License. (Filling in the name of the Initial
+ Developer, Original Code or Contributor in the notice described in
+ Exhibit A shall not of themselves be deemed to be modifications of
+ this License.)
+
+7. DISCLAIMER OF WARRANTY.
+
+ COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF
+ DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING.
+ THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE
+ IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT,
+ YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE
+ COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER
+ OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF
+ ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
+
+8. TERMINATION.
+
+ 8.1. This License and the rights granted hereunder will terminate
+ automatically if You fail to comply with terms herein and fail to cure
+ such breach within 30 days of becoming aware of the breach. All
+ sublicenses to the Covered Code which are properly granted shall
+ survive any termination of this License. Provisions which, by their
+ nature, must remain in effect beyond the termination of this License
+ shall survive.
+
+ 8.2. If You initiate litigation by asserting a patent infringement
+ claim (excluding declatory judgment actions) against Initial Developer
+ or a Contributor (the Initial Developer or Contributor against whom
+ You file such action is referred to as "Participant") alleging that:
+
+ (a) such Participant's Contributor Version directly or indirectly
+ infringes any patent, then any and all rights granted by such
+ Participant to You under Sections 2.1 and/or 2.2 of this License
+ shall, upon 60 days notice from Participant terminate prospectively,
+ unless if within 60 days after receipt of notice You either: (i)
+ agree in writing to pay Participant a mutually agreeable reasonable
+ royalty for Your past and future use of Modifications made by such
+ Participant, or (ii) withdraw Your litigation claim with respect to
+ the Contributor Version against such Participant. If within 60 days
+ of notice, a reasonable royalty and payment arrangement are not
+ mutually agreed upon in writing by the parties or the litigation claim
+ is not withdrawn, the rights granted by Participant to You under
+ Sections 2.1 and/or 2.2 automatically terminate at the expiration of
+ the 60 day notice period specified above.
+
+ (b) any software, hardware, or device, other than such Participant's
+ Contributor Version, directly or indirectly infringes any patent, then
+ any rights granted to You by such Participant under Sections 2.1(b)
+ and 2.2(b) are revoked effective as of the date You first made, used,
+ sold, distributed, or had made, Modifications made by that
+ Participant.
+
+ 8.3. If You assert a patent infringement claim against Participant
+ alleging that such Participant's Contributor Version directly or
+ indirectly infringes any patent where such claim is resolved (such as
+ by license or settlement) prior to the initiation of patent
+ infringement litigation, then the reasonable value of the licenses
+ granted by such Participant under Sections 2.1 or 2.2 shall be taken
+ into account in determining the amount or value of any payment or
+ license.
+
+ 8.4. In the event of termination under Sections 8.1 or 8.2 above,
+ all end user license agreements (excluding distributors and resellers)
+ which have been validly granted by You or any distributor hereunder
+ prior to termination shall survive termination.
+
+9. LIMITATION OF LIABILITY.
+
+ UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT
+ (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL
+ DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE,
+ OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR
+ ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY
+ CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL,
+ WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER
+ COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN
+ INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF
+ LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY
+ RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW
+ PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE
+ EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO
+ THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU.
+
+10. U.S. GOVERNMENT END USERS.
+
+ The Covered Code is a "commercial item," as that term is defined in
+ 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer
+ software" and "commercial computer software documentation," as such
+ terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48
+ C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995),
+ all U.S. Government End Users acquire Covered Code with only those
+ rights set forth herein.
+
+11. MISCELLANEOUS.
+
+ This License represents the complete agreement concerning subject
+ matter hereof. If any provision of this License is held to be
+ unenforceable, such provision shall be reformed only to the extent
+ necessary to make it enforceable. This License shall be governed by
+ California law provisions (except to the extent applicable law, if
+ any, provides otherwise), excluding its conflict-of-law provisions.
+ With respect to disputes in which at least one party is a citizen of,
+ or an entity chartered or registered to do business in the United
+ States of America, any litigation relating to this License shall be
+ subject to the jurisdiction of the Federal Courts of the Northern
+ District of California, with venue lying in Santa Clara County,
+ California, with the losing party responsible for costs, including
+ without limitation, court costs and reasonable attorneys' fees and
+ expenses. The application of the United Nations Convention on
+ Contracts for the International Sale of Goods is expressly excluded.
+ Any law or regulation which provides that the language of a contract
+ shall be construed against the drafter shall not apply to this
+ License.
+
+12. RESPONSIBILITY FOR CLAIMS.
+
+ As between Initial Developer and the Contributors, each party is
+ responsible for claims and damages arising, directly or indirectly,
+ out of its utilization of rights under this License and You agree to
+ work with Initial Developer and Contributors to distribute such
+ responsibility on an equitable basis. Nothing herein is intended or
+ shall be deemed to constitute any admission of liability.
+
+13. MULTIPLE-LICENSED CODE.
+
+ Initial Developer may designate portions of the Covered Code as
+ "Multiple-Licensed". "Multiple-Licensed" means that the Initial
+ Developer permits you to utilize portions of the Covered Code under
+ Your choice of the NPL or the alternative licenses, if any, specified
+ by the Initial Developer in the file described in Exhibit A.
+
+EXHIBIT A -Mozilla Public License.
+
+ ``The contents of this file are subject to the Mozilla Public License
+ Version 1.1 (the "License"); you may not use this file except in
+ compliance with the License. You may obtain a copy of the License at
+ http://www.mozilla.org/MPL/
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+ License for the specific language governing rights and limitations
+ under the License.
+
+ The Original Code is ______________________________________.
+
+ The Initial Developer of the Original Code is ________________________.
+ Portions created by ______________________ are Copyright (C) ______
+ _______________________. All Rights Reserved.
+
+ Contributor(s): ______________________________________.
+
+ Alternatively, the contents of this file may be used under the terms
+ of the _____ license (the "[___] License"), in which case the
+ provisions of [______] License are applicable instead of those
+ above. If you wish to allow use of your version of this file only
+ under the terms of the [____] License and not to allow others to use
+ your version of this file under the MPL, indicate your decision by
+ deleting the provisions above and replace them with the notice and
+ other provisions required by the [___] License. If you do not delete
+ the provisions above, a recipient may use your version of this file
+ under either the MPL or the [___] License."
+
+ [NOTE: The text of this Exhibit A may differ slightly from the text of
+ the notices in the Source Code files of the Original Code. You should
+ use the text of this Exhibit A rather than the text found in the
+ Original Code Source Code for Your Modifications.]
+
--- /dev/null
+#############################################################################
+#
+# The Ibex Makefile
+#
+
+# auto directory creation with %/%: %?
+
+ifeq ($(platform),)
+# default
+platform := Java2
+endif
+
+target_Darwin := powerpc-apple-darwin
+target_Win32 := i686-pc-mingw32
+target_Solaris := sparc-sun-solaris2.7
+target_Linux := i686-pc-linux-gnu
+target := $(target_$(platform))
+
+all: Java2 Linux Win32 Darwin Solaris
+
+clean: ; rm -rf build
+dist-clean:
+ rm -rf .configure* .install* build .compile .build*
+ find upstream -name config.cache -exec rm -f {} \;
+ test -e upstream/org.ibex.nestedvm && make -C upstream/org.ibex.nestedvm clean
+ rm -f .install_org.ibex.nestedvm
+
+libwing_Linux := -Lupstream/install/i686-pc-linux-gnu/lib/
+libwing_Linux += upstream/install/i686-pc-linux-gnu/lib/libWINGs.a
+libwing_Linux += upstream/install/i686-pc-linux-gnu/lib/libwraster.a
+
+libwing_Solaris := -Lupstream/install/sparc-sun-solaris2.7/lib/
+libwing_Solaris += upstream/install/sparc-sun-solaris2.7/lib/libWINGs.a
+libwing_Solaris += upstream/install/sparc-sun-solaris2.7/lib/libwraster.a
+
+Java2: build/Java2/ibex.jar
+JVM:; @make Java2
+Linux: ; @make gcj platform=Linux link_flags="$(libwing_Linux) -lXpm -lX11 -lXext"
+Solaris: ; @make gcj platform=Solaris link_flags="$(libwing_Solaris) -lXpm -lX11 -lXext -lpthread"
+Win32: ; @make gcj platform=Win32 link_flags="-Wl,--subsystem,windows -lcomdlg32"
+Darwin: ; @make gcj platform=Darwin link_flags="$(darwin_linker_flags)"
+
+libjava_dir := $(shell pwd)/upstream/gcc-3.3/build-$(target)/$(target)/libjava
+darwin_libdir := upstream/install/powerpc-apple-darwin/lib
+darwin_ogl_libdir := /System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries
+
+target_bin_extension_$(platform) := $(shell echo $(platform) | tr A-Z a-z)
+target_bin_extension_Win32 := exe
+target_bin_extension_Java2 := jar
+target_bin_extension := $(target_bin_extension_$(platform))
+target_bin := ibex.$(target_bin_extension)
+
+ifeq ($(platform),Darwin)
+gcc_optimizations := -O0
+else
+gcc_optimizations := -Os
+endif
+#gcc_optimizations := -O9 -ffast-math -fomit-frame-pointer -foptimize-sibling-calls
+#gcc_optimizations += -finline-functions -funroll-loops -ffunction-sections -fdata-sections
+gcc_flags := -nostdinc $(gcc_optimizations) -Ibuild/h -Iupstream/jpeg-6b/src -Iupstream/jpeg-6b/build-$(target) -g
+gcc_flags += -Iupstream/install/lib/gcc-lib/$(target)/3.3/include -Iupstream/install/$(target)/include
+#gcc_flags += -ffunction-sections -fdata-sections -fno-omit-frame-pointer
+gcj := CLASSPATH=build/java upstream/install/bin/$(target)-gcj $(gcc_flags)
+ifneq ($(platform),Darwin)
+gcj += -finhibit-reflection
+endif
+#gcj += -fassume-compiled -fmerge-all-constants
+#gcj += -foptimize-static-class-initialization -feliminate-dwarf2-dups -w
+gcjh := $(shell pwd)/upstream/install/bin/$(shell test -e upstream/install/bin/$(target)-gcjh && echo $(target)-)gcjh
+g++ := upstream/install/bin/$(target)-gcj $(gcc_flags) -Iupstream/install/include -Wno-multichar
+gcc := upstream/install/bin/$(target)-gcc $(gcc_flags)
+nm := upstream/install/$(target)/bin/nm
+jar := $(shell ((type fastjar &>/dev/null) && echo fastjar) || echo jar)
+ifeq ($(platform),Java2)
+javac := javac -classpath upstream/bcel-5.1/src/bcel-5.1.jar -d build/class/ -sourcepath build/java/
+else
+javac := $(gcj) -fCLASSPATH=upstream/bcel-5.1/src/bcel-5.1.jar -d build/class/ -Ibuild/java -Iupstream/gnu.regexp-1.1.4/src/src -C
+endif
+
+gcj: .install_gcc-3.3_$(target)
+ @make build/$(platform)/$(target_bin) link_flags="$(link_flags)" platform=$(platform)
+
+include Makefile.upstream
+
+# find the superclasses of a platform class
+#superclass_%:
+# @if [ "$*" = "org.ibex.plat.Darwin" ]; then echo org.ibex.plat.OpenGL; fi
+# @echo $*
+# @grep -s extends src/$(subst .,/,$*).java | sed s_.\*extends\ __ | head -n 1 | sed s_\ .\*__ |\
+# xargs --replace make -s superclass_org.ibex.plat.{}
+
+plat_classes_Platform := org.ibex.plat.Platform
+plat_classes_AWT := org.ibex.plat.AWT $(plat_classes_Platform)
+plat_classes_Java2 := org.ibex.plat.Java2 org.ibex.plat.JVM $(plat_classes_AWT)
+plat_classes_GCJ := org.ibex.plat.GCJ $(plat_classes_Platform)
+plat_classes_Win32 := org.ibex.plat.Win32 $(plat_classes_GCJ)
+plat_classes_POSIX := org.ibex.plat.POSIX $(plat_classes_GCJ)
+plat_classes_X11 := org.ibex.plat.X11 $(plat_classes_POSIX)
+plat_classes_Linux := org.ibex.plat.Linux $(plat_classes_X11)
+plat_classes_Solaris := org.ibex.plat.Solaris $(plat_classes_X11)
+plat_classes_Darwin := org.ibex.plat.Darwin org.ibex.plat.OpenGL $(plat_classes_POSIX)
+
+plat_java_src_sources := $(patsubst %,build/java/%.java,$(subst .,/,$(plat_classes_$(platform))))
+java_src_sources := $(shell find src -name '*.java' | grep -v NanoGoat | grep -v Preprocessor | grep -v /plat/)
+java_src_sources += $(plat_java_src_sources)
+java_sources := $(patsubst src/%.java, build/java/%.java, $(java_src_sources))
+
+java_sources += build/java/org/xwt/mips/util/SeekableByteArray.java
+java_sources += build/java/org/xwt/mips/util/SeekableData.java
+java_sources += build/java/org/xwt/mips/util/SeekableFile.java
+java_sources += build/java/org/xwt/mips/util/SeekableInputStream.java
+java_sources += build/java/org/xwt/mips/Registers.java
+java_sources += build/java/org/xwt/mips/Runtime.java
+java_sources += build/java/org/xwt/mips/UsermodeConstants.java
+
+java_sources += build/java/org/ibex/crypto/DER.java
+java_sources += build/java/org/ibex/crypto/Digest.java
+java_sources += build/java/org/ibex/crypto/HMAC.java
+java_sources += build/java/org/ibex/crypto/MD2.java
+java_sources += build/java/org/ibex/crypto/MD5.java
+java_sources += build/java/org/ibex/crypto/PKCS1.java
+java_sources += build/java/org/ibex/crypto/RC4.java
+java_sources += build/java/org/ibex/crypto/RSA.java
+java_sources += build/java/org/ibex/crypto/SHA1.java
+java_sources += build/java/org/ibex/crypto/X509.java
+java_sources += build/java/org/ibex/crypto/Base64.java
+java_sources += build/java/org/ibex/net/ssl/RootCerts.java
+java_sources += build/java/org/ibex/net/SSL.java
+
+java_sources += build/java/gnu/regexp/CharIndexed.java
+java_sources += build/java/gnu/regexp/CharIndexedCharArray.java
+java_sources += build/java/gnu/regexp/CharIndexedInputStream.java
+java_sources += build/java/gnu/regexp/CharIndexedString.java
+java_sources += build/java/gnu/regexp/CharIndexedStringBuffer.java
+java_sources += build/java/gnu/regexp/RE.java
+java_sources += build/java/gnu/regexp/REException.java
+java_sources += build/java/gnu/regexp/REFilterInputStream.java
+java_sources += build/java/gnu/regexp/REMatch.java
+java_sources += build/java/gnu/regexp/REMatchEnumeration.java
+java_sources += build/java/gnu/regexp/RESyntax.java
+java_sources += build/java/gnu/regexp/REToken.java
+java_sources += build/java/gnu/regexp/RETokenAny.java
+java_sources += build/java/gnu/regexp/RETokenBackRef.java
+java_sources += build/java/gnu/regexp/RETokenChar.java
+java_sources += build/java/gnu/regexp/RETokenEnd.java
+java_sources += build/java/gnu/regexp/RETokenEndSub.java
+java_sources += build/java/gnu/regexp/RETokenLookAhead.java
+java_sources += build/java/gnu/regexp/RETokenWordBoundary.java
+java_sources += build/java/gnu/regexp/RETokenOneOf.java
+java_sources += build/java/gnu/regexp/RETokenPOSIX.java
+java_sources += build/java/gnu/regexp/RETokenRange.java
+java_sources += build/java/gnu/regexp/RETokenRepeated.java
+java_sources += build/java/gnu/regexp/RETokenStart.java
+java_sources += build/java/gnu/regexp/UncheckedRE.java
+java_sources += build/java/gnu/regexp/CharIndexedReader.java
+java_sources += build/java/gnu/regexp/REFilterReader.java
+
+java_classes := $(java_sources:build/java/%.java=build/class/%.class)
+java_classes += build/class/gnu/regexp/CharUnit.class build/class/gnu/regexp/IntPair.class
+java_classes += build/class/org/ibex/util/MIPSApps.class
+
+### Java Source Files ##############################################################################
+
+$(java_sources):: .download_org.ibex.crypto .download_org.ibex.nestedvm .download_gnu.regexp-1.1.4
+link_upstream = build/java/$(1):: $(2)/$(1) $(3); \
+ @echo -e "\033[1mlinking .java -> .java: $$@\033[0m"; \
+ mkdir -p $$(@D); ln -fs `echo $$(@D)/ | sed 's_[^/]*//*_../_g'`/$$< $$@
+build/cc/%.cc: src/%.c ; @echo linking $@; mkdir -p $(@D); ln -fs `echo $(@D)/ | sed 's_[^/]*//*_../_g'`/$< $@
+build/res/%: src/% ; @echo linking $@; mkdir -p $(@D); ln -fs `echo $(@D)/ | sed 's_[^/]*//*_../_g'`/$< $@
+$(call link_upstream,org/xwt/mips/%.java,upstream/org.ibex.nestedvm/src,.download_org.ibex.nestedvm)
+$(call link_upstream,org/ibex/crypto/%.java,upstream/org.ibex.crypto/src,.download_org.ibex.crypto)
+$(call link_upstream,org/ibex/net/ssl/%.java,upstream/org.ibex.crypto/src,.download_org.ibex.crypto)
+$(call link_upstream,org/ibex/net/SSL.java,upstream/org.ibex.crypto/src,.download_org.ibex.crypto)
+$(call link_upstream,gnu/regexp/%.java,upstream/gnu.regexp-1.1.4/src/src)
+build/java/org/ibex/%.java: src/org/ibex/%.java .download_gnu.regexp-1.1.4 build/class/org/ibex/util/Preprocessor.class
+ @echo -e "\033[1mpreprocessing .java -> .java: $<\033[0m"
+ mkdir -p `dirname $@`; java -cp build/class:upstream/gnu.regexp-1.1.4/src/src org.ibex.util.Preprocessor < $< > $@
+$(call link_upstream,%.java,src)
+$(call link_upstream,%.cc,src)
+
+
+### Java Class Files ##############################################################################
+
+build/class/org/ibex/util/Preprocessor.class: src/org/ibex/util/Preprocessor.java
+ @mkdir -p build/class/gnu/regexp build/class/org/ibex/util
+ $(javac) $< src/org/ibex/util/Vec.java upstream/gnu.regexp-1.1.4/src/src/gnu/regexp/*.java
+
+compile: .compile
+.compile: $(java_sources)
+ @echo -e "\n\033[1mcompiling .java -> .class\033[0m"
+ @echo $(java_sources) | tr ' ' '\n' | sed 's_build/java/_ _' | sed 's_/_._g' | sed 's_.java$$__g'
+ @make -s $(java_sources)
+ $(javac) $(java_sources)
+ touch $@
+
+build/class/org/ibex/util/MIPSApps.class: build/mips/mipsapps.mips .install_org.ibex.nestedvm
+ @mkdir -p build/java/org/ibex/util
+ @echo -e "\n\033[1mtranslating .mips -> .class: $<\033[0m"
+ java -cp upstream/org.ibex.nestedvm/build:upstream/org.ibex.nestedvm/upstream/build/bcel-5.1/bcel-5.1.jar \
+ org.xwt.mips.Compiler org.ibex.util.MIPSApps $< -outfile $@
+
+build/Java2/ibex.jar: compile build/res/builtin.jar build/class/org/ibex/util/MIPSApps.class
+ @echo -e "\n\033[1marchiving .class -> .jar: build/Java2/ibex.jar\033[0m"
+ mkdir -p build/Java2
+ echo -e "Manifest-Version: 1.0\nMain-Class: org.ibex.core.Main\n" > build/Java2/.manifest
+ cd build/class/org/ibex; ln -sf ../../../res/builtin.jar
+ cd build/class; $(jar) cfm ../Java2/ibex.jar ../Java2/.manifest `find . -name \*.class -or -name \*.jar`
+
+
+### Headers ##################################################################################
+
+java_headers := $(java_sources:build/java/%.java=build/h/%.h)
+build/h/%.h: build/class/%.class .compile
+ @echo -e "\n\033[1mextracting .class -> .h: $<\033[0m"
+ mkdir -p `dirname $@`
+ ls `echo $< | sed s/.class\$$//`*.class |\
+ sed s_build/class/__ | sed s/.class\$$//g | sed s_/_._g | (cd build/class; xargs $(gcjh) -d ../h --classpath .)
+
+
+### Native Code ##############################################################################
+
+# a hack since we've disabled gcj's awt implementation
+build/$(platform)/org/ibex/plat/Linux.cc.o: .install_WindowMaker-0.80.2_$(target)
+build/$(platform)/org/ibex/plat/Solaris.cc.o: .install_WindowMaker-0.80.2_$(target)
+
+nat_libjava_files_ := boehm.o exception.o posix-threads.o posix.o prims.o resolve.o java/net/natInetAddress.o
+nat_libjava_files_ += java/net/natPlainSocketImpl.o java/util/zip/nat*.o gnu/gcj/runtime/natFirstThread.o
+nat_libjava_files_ += gnu/gcj/runtime/natNameFinder.o gnu/gcj/runtime/natStackTrace.o gnu/gcj/runtime/natSharedLibLoader.o
+nat_libjava_files_ += gnu/gcj/runtime/natStringBuffer.o gnu/gcj/runtime/natVMClassLoader.o gnu/gcj/runtime/natFinalizerThread.o
+nat_libjava_files_ += $(shell cd $(libjava_dir) 2>/dev/null; find java/lang -name \*.o -not -name '*[A-Z]*' 2>/dev/null)
+nat_libjava_files_ += $(shell cd $(libjava_dir) 2>/dev/null; find java/lang -name nat\*.o 2>/dev/null)
+nat_libjava_files := $(nat_libjava_files_:%=$(libjava_dir)/%)
+nat_libjava_files += $(libjava_dir)/java/io/natFile.o $(libjava_dir)/java/io/natFileDescriptor.o
+
+build/$(platform)/org/ibex/plat/$(platform).cc.o: src/org/ibex/plat/$(platform).cc src/org/ibex/plat/*.cc .configure_jpeg-6b_$(target)
+ @make $(java_headers)
+ @echo -e "\n\033[1mcompiling .cc -> .o: $<\033[0m"
+ mkdir -p `dirname $@`
+ $(g++) -Iupstream/gcc-3.3/build-$(target)/$(target)/libjava -c $< -o $@
+
+
+bcel_jar := upstream/bcel-5.1/src/bcel-5.1.jar
+build/$(platform)/ibex.pruned.jar: .compile $(java_classes) .install_jpeg-6b_$(target) build/$(platform)/builtin.o build/$(platform)/org/ibex/plat/$(platform).cc.o
+ @echo -e "\n\033[1mpruning .jar -> .jar\033[0m"
+ifneq ($(platform),Darwin)
+ cp upstream/install/share/java/libgcj-3.3.jar build/$(platform)/ibex.jar
+ cd build/class; jar uf ../$(platform)/ibex.jar $(java_classes:build/class/%.class=%*.class)
+ ($(nm) $(nat_libjava_files) build/$(platform)/org/ibex/plat/$(platform).cc.o; echo org.ibex.plat.$(platform).main) |\
+ grep _ZN | c++filt --format java | grep " U " | sed 's_ * U __' | sed 's_(.*__' \
+ | java -cp $(bcel_jar):build/class org.ibex.util.NanoGoat build/$(platform)/ibex.jar | tee nanogoat.log
+ mkdir tmp; cd tmp; fastjar xvf ../build/$(platform)/ibex.jar.pruned; rm gnu/gcj/runtime/FirstThread*; cp ../build/class/org/ibex/plat/GCJ* org/ibex/plat/; cp -r ../build/class/org/xwt/mips/* org/xwt/mips/; mkdir -p $(shell pwd)/build/$(platform)/java/lang; mv java/lang/Class.class $(shell pwd)/build/$(platform)/java/lang; fastjar cvf ../build/$(platform)/ibex.jar.pruned .; cd ..; rm -rf tmp
+ mv build/$(platform)/ibex.jar.pruned $@
+endif
+ifeq ($(platform),Darwin)
+ cd build/class; jar cf ../$(platform)/ibex.pruned.jar \
+ org/ibex/plat/Platform*.class \
+ $(filter-out org/ibex/util/NanoGoat%,$(java_classes:build/class/%.class=%*.class))
+endif
+
+ifeq ($(platform),Win32)
+filedes := $(shell pwd)/upstream/gcc-3.3/src/libjava/java/io/natFileWin32.cc
+filedes += $(shell pwd)/upstream/gcc-3.3/src/libjava/java/io/natFileDescriptorWin32.cc
+else
+filedes := $(shell pwd)/upstream/gcc-3.3/src/libjava/java/io/natFilePosix.cc
+filedes += $(shell pwd)/upstream/gcc-3.3/src/libjava/java/io/natFileDescriptorPosix.cc
+endif
+
+final_compile := --main=org.ibex.plat.$(platform)
+final_compile += -Dfile.encoding=UTF8
+final_compile += -DPREFIX=\"\"
+final_compile += -Lupstream/install/$(target)/lib -Lupstream/install/lib
+final_compile += -g -save-temps -w -v
+final_compile += -Iupstream/jpeg-6b/build-$(target)/
+final_compile += -Iupstream/jpeg-6b/src
+final_compile += -Ibuild/h
+final_compile += -Iupstream/gcc-3.3/src/gcc
+final_compile += -Iupstream/gcc-3.3/build-$(target)/$(target)/boehm-gc/
+final_compile += -Iupstream/gcc-3.3/build-$(target)/$(target)/boehm-gc/include
+final_compile += -Iupstream/gcc-3.3/src/boehm-gc
+final_compile += -Iupstream/gcc-3.3/src/boehm-gc/include
+final_compile += -Iupstream/gcc-3.3/src/libjava
+final_compile += -Iupstream/gcc-3.3/src/libjava/include
+final_compile += -Iupstream/gcc-3.3/build-$(target)/$(target)/libjava/
+final_compile += -Iupstream/gcc-3.3/build-$(target)/$(target)/libjava/include
+final_compile += -Ufile
+final_compile += src/org/ibex/plat/$(platform).cc
+final_compile += upstream/jpeg-6b/build-$(target)/libjpeg.a
+final_compile += build/$(platform)/builtin.o
+final_compile += build/$(platform)/ibex.pruned.jar
+ifneq ($(platform),Darwin)
+final_compile += $(libjava_dir)/../boehm-gc/.libs/libgcjgc.a
+final_compile += -fno-store-check
+final_compile += -finhibit-reflection
+final_compile += $(nat_libjava_files_:%.o=$(shell pwd)/upstream/gcc-3.3/src/libjava/%.c*)
+final_compile += $(filedes)
+final_compile += build/$(platform)/Class.o
+final_compile += $(libjava_dir)/gnu/gcj/runtime/FirstThread.o
+final_compile += -Wl,-O2,--relax,--gc-sections,--noinhibit-exec,--no-whole-archive
+final_compile += -lz
+else
+final_compile += -Wl,-dylib_file,/usr/lib/libSystem.B.dylib:$(darwin_libdir)/libSystem.B.dylib
+final_compile += -Wl,-dylib_file,/usr/lib/system/libmathCommon.A.dylib:$(darwin_libdir)/libmathCommon.A.dylib
+final_compile += -Wl,-dylib_file,$(darwin_ogl_libdir)/libGL.dylib:$(darwin_libdir)/libGL.dylib
+final_compile += -Wl,-dylib_file,$(darwin_ogl_libdir):$(darwin_libdir)/libGLU.dylib
+final_compile += -lSystem.B -lmathCommon.A -lGL -lGLU
+#final_compile += $(libjava_dir)/.libs/libgcj.a
+#final_compile += $(libjava_dir)/../boehm-gc/.libs/libgcjgc.a
+#final_compile += -lgcc
+#final_compile += -lm
+#final_compile += -lpthread
+#final_compile += -lgcc
+#final_compile += -lcrt1.o
+#final_compile += -lcrt2.o
+#final_compile += -lSystem
+endif
+
+
+ifneq ($(target_bin_extension),jar)
+build/$(platform)/$(target_bin): build/$(platform)/ibex.pruned.jar src/org/ibex/plat/*.cc build/$(platform)/builtin.o $(java_headers)
+
+ @echo -e "\n\033[1mlinking .jar -> $(target_bin).phat\033[0m"
+ifneq ($(platform),Darwin)
+# -Os
+ cd build/$(platform); $(shell pwd)/upstream/install/bin/$(target)-gcj \
+ -fCLASSPATH=$(shell pwd)/upstream/install/share/java/libgcj-3.3.jar \
+ -finhibit-reflection \
+ -fno-store-check \
+ -c java/lang/Class.class
+ cd upstream/gcc-3.3/src/libjava/java/lang;\
+ ln -sf ../../../../build-$(target)/$(target)/libjava/java/lang/natConcreteProcess.cc
+endif
+# we need -fno-store-check since we can't dynamically resolve references to array classes
+ PATH=upstream/install/bin:$$PATH upstream/install/bin/$(target)-gcj $(final_compile) -o $@.phat
+
+ifneq ($(platform),Darwin)
+ @echo; ls -l $@.phat
+
+ @echo -e "\n\033[1mstripping $(target_bin).phat -> $(target_bin)\033[0m"
+ strip $@.phat -o $@
+ @echo; ls -l $@.phat
+
+ @echo -e "\n\033[1mcompressing $(target_bin) -> $(target_bin)\033[0m"
+ upx-ucl-beta $@
+ @echo; ls -l $@.phat
+else
+ mv $@.phat $@
+endif
+endif
+
+### Builtin Resources ##############################################################################
+
+builtin_src := $(shell find src/org/ibex/core/builtin -name '*.*' \! -name '*.xcf')
+build/res/fonts/vera: .download_vera-1.10
+ mkdir -p build/res/fonts/vera
+ cd build/res/fonts/vera; ln -fs ../../../../upstream/vera-1.10/ttf-bitstream-vera-1.10/Vera.ttf
+ cd build/res/fonts/vera; ln -fs ../../../../upstream/vera-1.10/ttf-bitstream-vera-1.10/VeraMono.ttf
+ cd build/res/fonts/vera; ln -fs ../../../../upstream/vera-1.10/ttf-bitstream-vera-1.10/VeraSe.ttf
+build/res/builtin.jar: $(builtin_src:src/%=build/res/%) build/res/fonts/vera
+ @echo -e "\n\033[1mzipping res/* -> .jar: builtin.jar\033[0m"
+ cd build/res; $(jar) cf builtin.jar org/ibex/core/builtin/scar.png fonts
+build/$(platform)/builtin.o: build/res/builtin.jar
+ @echo -e "\n\033[1mwrapping .jar -> .o: resources.o\033[0m"
+ @mkdir -p $(@D)
+ @(echo "unsigned int builtin_length = "; \
+ (wc -c build/res/builtin.jar | sed "s_build.*__"); \
+ echo \;; \
+ echo "unsigned char builtin_bytes[] = {"; \
+ hexdump -ve '"0x" 1/1 "%x,\n"' build/res/builtin.jar; \
+ echo "};") > .builtin.c
+ $(gcc) -c .builtin.c -o build/$(platform)/builtin.o
+
+build/mips/%.c.o: src/%.c .download_libmspack-20030726 .install_org.ibex.nestedvm
+ make .install_freetype-2.1.4_mips-unknown-elf target=mips-unknown-elf
+ make .install_libmspack-20030726_mips-unknown-elf target=mips-unknown-elf
+ mkdir -p $(@D)
+ echo -e "\n\033[1mcompiling $< -> $@ (mips)\033[0m"
+ upstream/install/bin/mips-unknown-elf-gcc -march=r3000 \
+ -Iupstream/freetype-2.1.4/src/include \
+ -Iupstream/libmspack-20030726/src/mspack \
+ -c -o $@ $<
+
+build/mips/mipsapps.mips: build/mips/org/ibex/graphics/Freetype.c.o build/mips/org/ibex/util/MSPack.c.o
+ make .install_freetype-2.1.4_mips-unknown-elf target=mips-unknown-elf
+ make .install_libmspack-20030726_mips-unknown-elf target=mips-unknown-elf
+ @echo -e "\n\033[1mlinking .o -> .mips: $@\033[0m"
+ mkdir -p build/mips build/res
+ upstream/install/bin/mips-unknown-elf-gcc \
+ --static \
+ -march=mips1 \
+ -T upstream/org.ibex.nestedvm/src/org/xwt/mips/linker.ld \
+ -L upstream/org.ibex.nestedvm/build/org/xwt/mips/ \
+ -L upstream/freetype-2.1.4/src/objs \
+ -L upstream/libmspack-20030726/build-mips-unknown-elf/ \
+ -o $@ \
+ $^ \
+ -lfreetype \
+ -lmspack \
+ -Wl,--gc-sections
+
+
+### Maintainer ######################################################################################
+
+current_build := $(shell cat next.build)
+strip_$(platform) := upstream/install/$(target)/bin/strip build/$(platform)/$(target_bin) -o
+strip_Java2 := cp build/$(platform)/$(target_bin)
+install-dist:; $(strip_$(platform)) /var/www/org/xwt/dist/master/ibex-$(current_build).$(target_bin_extension).unsigned
+dist: compile
+ (echo -n 0000; (echo "10k16o16i"; cat next.build | tr a-z A-Z; echo "1+f") | dc) | tail --bytes=5 > next.build-
+ mv next.build- next.build
+ echo -n "Next build will be "; cat next.build
+ nice -n 19 make all
+ make install-dist platform=Win32
+ make install-dist platform=Linux
+ make install-dist platform=Solaris
+ make install-dist platform=Darwin
+ make install-dist platform=Java2
+ echo -e "\n\n\n*** DONE ******************************************"
+
+propose-patch:
+ @darcs send --edit-description -o .darcspatch -T patches@xwt.org http://core.ibex.org/
+ @(echo "To: patches@xwt.org";\
+ SUB=`grep -A10000 New.patches .darcspatch | grep '^\\[' | cut -b 2- | tr \\\n , | sed s_,_,\ _g | sed "s_, *\\$$__"`;\
+ echo "Subject: $$SUB";\
+ echo;\
+ cat .darcspatch) | /usr/sbin/sendmail -bm -f $(USER)@xwt.org patches@xwt.org;
+ @rm .darcspatch
+
+commit: propose-patch
+ darcs push xwt@xwt.org:/var/www/org/ibex/core/
+
+upstream/org.ibex.doc/src/org/ibex/doc/Doc.java: .download_org.ibex.doc
+build/class/org/ibex/doc/Doc.class: upstream/org.ibex.doc/src/org/ibex/doc/Doc.java
+ $(javac) upstream/org.ibex.doc/src/org/ibex/doc/Doc.java
+doc/%.pdf: build/class/org/ibex/util/XML.class build/class/org/ibex/doc/Doc.class
+ cd doc/$*; java -cp ../../build/class org.ibex.doc.Doc < $*.xml > $*.tex
+ cd doc/$*; pdflatex $*.tex
+ mv doc/$*/$*.pdf doc/$*.pdf
+ test `uname` == Darwin && open doc/$*.pdf
+reference: ; rm -f doc/reference.pdf; make doc/reference.pdf
\ No newline at end of file
--- /dev/null
+#############################################################################
+#
+# The Ibex upstream code Makefile
+#
+
+# deal with Apple's brokenness
+setcc := $(shell test `uname` = Darwin && echo "CC=\"/usr/bin/gcc3 -no-cpp-precomp\"")
+
+# where to get stuff
+url_binutils-2.13.2.1 := ftp://ftp.gnu.org/gnu/binutils/binutils-2.13.2.1.tar.gz
+url_w32api-2.3 := http://unc.dl.sourceforge.net/sourceforge/mingw/w32api-2.3.tar.gz
+url_mingw-runtime-3.0 := http://unc.dl.sourceforge.net/sourceforge/mingw/mingw-runtime-3.0.tar.gz
+url_freetype-2.1.4 := http://unc.dl.sourceforge.net/sourceforge/freetype/freetype-2.1.4.tar.gz
+url_gcc-3.3 := http://mirrors.rcn.net/pub/sourceware/gcc/releases/gcc-3.3/gcc-3.3.tar.gz
+url_jpeg-6b := http://www.ijg.org/files/jpegsrc.v6b.tar.gz
+url_libmspack-20030726 := http://www.kyz.uklinux.net/downloads/libmspack-20030726.tar.gz
+url_vera-1.10 := http://fgo-temp.acc.umu.se/pub/GNOME/sources/ttf-bitstream-vera/1.10/ttf-bitstream-vera-1.10.tar.gz
+url_WindowMaker-0.80.2 := http://windowmaker.org/pub/source/release/WindowMaker-0.80.2.tar.gz
+url_bcel-5.1 := http://www.apache.org/dist/jakarta/bcel/binaries/bcel-5.1.tar.gz
+url_gnu.regexp-1.1.4 := ftp://ftp.tralfamadore.com/pub/java/gnu.regexp-1.1.4.tar.gz
+
+.install_binutils-2.13.2.1_powerpc-apple-darwin: .vendor
+ rm -rf upstream/darwin-linker/src
+ cd upstream/darwin-linker; tar xvzf ../install/powerpc-apple-darwin/cctools-478.tgz
+ifneq ($(shell uname),Darwin)
+ cd upstream/darwin-linker/src/cctools; for A in ../../patches/*.patch; do patch -p0 < $$A; done
+ cp upstream/darwin-linker/src/cctools/ld/fake-mach.c upstream/darwin-linker/src/cctools/libstuff
+ cd upstream/darwin-linker/src/; mkdir macosx-include; cd macosx-include; chmod +x ../../links.sh; ../../links.sh
+endif
+ make -C upstream/darwin-linker/src/cctools/libstuff
+ make -C upstream/darwin-linker/src/cctools/misc
+ touch upstream/darwin-linker/src/cctools/misc/makeUser.c upstream/darwin-linker/src/cctools/misc/make.h
+ make -C upstream/darwin-linker/src/cctools/misc libtool.NEW
+ make -C upstream/darwin-linker/src/cctools/ld; true
+ make -C upstream/darwin-linker/src/cctools/as
+ make -C upstream/darwin-linker/src/cctools/ar
+ mkdir -p upstream/install/powerpc-apple-darwin/bin
+ cp upstream/darwin-linker/src/cctools/ld/ld_dir/ld.NEW upstream/install/powerpc-apple-darwin/bin/ld.NEW
+ echo -e "#!/bin/sh\n"`pwd`"/upstream/install/powerpc-apple-darwin/bin/ld.NEW -dylib_file /usr/lib/system/libmathCommon.A.dylib:"`pwd`"/upstream/install/powerpc-apple-darwin/lib/libmathCommon.A.dylib -L"`pwd`"/upstream/install/powerpc-apple-darwin/lib \$$@\n" > upstream/install/powerpc-apple-darwin/bin/ld
+ chmod +x upstream/install/powerpc-apple-darwin/bin/ld
+ echo -e "#!/bin/sh\n"`pwd`"/upstream/install/powerpc-apple-darwin/bin/apple-libtool \$$1 -o \$$1\n" > upstream/install/powerpc-apple-darwin/bin/ranlib
+ chmod +x upstream/install/powerpc-apple-darwin/bin/ranlib
+ cp upstream/darwin-linker/src/cctools/misc/libtool.NEW upstream/install/powerpc-apple-darwin/bin/apple-libtool
+ cp upstream/darwin-linker/src/cctools/misc/strip.NEW upstream/install/powerpc-apple-darwin/bin/strip
+ cp upstream/darwin-linker/src/cctools/as/appc_dir/as upstream/install/powerpc-apple-darwin/bin/as
+ cp upstream/darwin-linker/src/cctools/ar/ar.NEW upstream/install/powerpc-apple-darwin/bin/ar.NEW
+ echo -e "#!/bin/sh\n"`pwd`"/upstream/install/powerpc-apple-darwin/bin/ar.NEW \$$@\n"`pwd`"/upstream/install/powerpc-apple-darwin/bin/ranlib \$$2\n" > upstream/install/powerpc-apple-darwin/bin/ar
+ chmod +x upstream/install/powerpc-apple-darwin/bin/ar
+ mkdir -p upstream/install/bin
+ cd upstream/install/bin; ln -sf ../powerpc-apple-darwin/bin/ld powerpc-apple-darwin-ld
+ cd upstream/install/bin; ln -sf ../powerpc-apple-darwin/bin/as powerpc-apple-darwin-as
+ cd upstream/install/bin; ln -sf ../powerpc-apple-darwin/bin/ar powerpc-apple-darwin-ar
+ cd upstream/install/bin; ln -sf ../powerpc-apple-darwin/bin/ranlib powerpc-apple-darwin-ranlib
+ cd upstream/install/bin; ln -sf ../powerpc-apple-darwin/bin/strip powerpc-apple-darwin-strip
+ echo -e "#!/bin/sh\nc++filt \$$@\n" > upstream/install/bin/c++filt3; chmod +x upstream/install/bin/c++filt3
+ cd upstream/install/powerpc-apple-darwin/bin; ln -sf ../../bin/c++filt3
+ touch $@
+
+
+# how to configure it
+ifneq ($(shell uname),$(platform))
+configure_gcc-3.3 += --with-headers=$(shell pwd)/upstream/install/$(target)/include
+endif
+configure_gcc-3.3 += --enable-languages=c,c++,java --enable-gc-type=boehm --disable-jvmpi --without-libffi
+configure_gcc-3.3 += --with-ld=$(shell pwd)/upstream/install/bin/$(target)-ld
+configure_gcc-3.3 += --with-as=$(shell pwd)/upstream/install/bin/$(target)-as
+ifneq ($(platform),Darwin)
+configure_gcc-3.3 += --with-gnu-ld --with-gnu-as
+endif
+configure_gcc-3.3 += --disable-java-awt --disable-interpreter --enable-libgcj
+configure_gcc-3.3 += --disable-shared --enable-static --disable-jni
+configure_binutils-2.13.2.1 += --disable-shared --enable-static
+configure_gcc-3.3_powerpc-apple-darwin += --enable-threads=posix --disable-hash-synchronization --disable-multilib
+configure_gcc-3.3_i686-pc-mingw32 += --enable-threads=win32 --enable-hash-synchronization
+configure_gcc-3.3_i686-pc-linux-gnu += --enable-threads=posix --enable-hash-synchronization
+configure_gcc-3.3_sparc-sun-solaris2.7 += --enable-threads=posix --disable-hash-synchronization --disable-multilib
+
+configure_WindowMaker-0.80.2_$(target) += --prefix=$(shell pwd)/upstream/install/$(target)
+configure_WindowMaker-0.80.2_$(target) += --host=i686-pc-linux-gnu --x-libraries=$(shell pwd)/upstream/install/$(target)/lib
+
+#environment_gcc-3.3_i686-pc-linux-gnu += CFLAGS="-Wl,-ldl"
+
+# libjpeg's configury doesn't obey --target
+environment_jpeg-6b_$(target) += PATH=$(shell pwd)/upstream/install/$(target)/bin:$$PATH
+environment_jpeg-6b_$(target) += CC=$(shell pwd)/upstream/install/bin/$(target)-gcc
+environment_jpeg-6b_$(target) += CFLAGS="-Os -ffunction-sections -fdata-sections -I ."
+environment_jpeg-6b_$(target) += AR="$(shell pwd)/upstream/install/$(target)/bin/ar rc"
+environment_jpeg-6b_$(target) += AR2=$(shell pwd)/upstream/install/$(target)/bin/ranlib
+
+# libmspack configury doesn't obey --target
+environment_libmspack-20030726_$(target) += PATH=$(shell pwd)/upstream/install/$(target)/bin:$$PATH
+environment_libmspack-20030726_$(target) += CC=$(shell pwd)/upstream/install/bin/$(target)-gcc
+environment_libmspack-20030726_$(target) += AR="$(shell pwd)/upstream/install/$(target)/bin/ar"
+environment_libmspack-20030726_$(target) += AR2=$(shell pwd)/upstream/install/$(target)/bin/ranlib
+environment_libmspack-20030726_$(target) += OPTIM="-ffunction-sections -fdata-sections -O3"
+
+# WindowMaker configury doesn't obey --target
+environment_WindowMaker-0.80.2_$(target) += PATH=$(shell pwd)/upstream/install/$(target)/bin:$$PATH
+environment_WindowMaker-0.80.2_$(target) += CC=$(shell pwd)/upstream/install/bin/$(target)-gcc
+environment_WindowMaker-0.80.2_$(target) += AR="$(shell pwd)/upstream/install/$(target)/bin/ar"
+environment_WindowMaker-0.80.2_$(target) += AR2=$(shell pwd)/upstream/install/$(target)/bin/ranlib
+environment_WindowMaker-0.80.2_$(target) += LDFLAGS="-lXext -ldl"
+make_install_WindowMaker-0.80.2_$(target) := -C WINGs install; make -C wrlib
+make_WindowMaker-0.80.2_$(target) := WINGs
+
+environment_gcc_3.3_$(target) += PATH=$(shell pwd)/upstream/install/bin:$$PATH
+
+.PRECIOUS: .vendor .download_% .configure_%_$(target) .install_%_$(target)
+
+.download_org.ibex.%:
+ @echo -e "\033[1mfetching repository org.ibex.$*\033[0m"
+ @mkdir -p upstream; cd upstream; rm -rf org.ibex.$*; rm -rf org.ibex.$*_*
+ @cd upstream; darcs get --verbose --partial --repo-name=org.ibex.$* http://$*.ibex.org
+ @touch $@
+
+.build_org.ibex.nestedvm: .vendor .download_org.ibex.nestedvm
+ cd upstream/org.ibex.nestedvm; make usr=$(shell pwd)/upstream/install all env.sh
+ touch $@
+
+.install_org.ibex.nestedvm: .build_org.ibex.nestedvm
+ touch $@
+
+# vendor-supplied binaries and headers; this is stuff that comes with various OSes
+vendor: .vendor; @true
+.vendor:
+ @echo -e "\n\033[1mdownloading vendor-supplied headers and libraries...\033[0m"
+ mkdir -p upstream/install
+ curl http://www.megacz.com/vendor.tgz | tar xzf - -C upstream/install
+ mkdir -p upstream/install/i686-pc-mingw32
+ curl $(url_w32api-2.3) | tar xzf - -C upstream/install/i686-pc-mingw32
+ curl $(url_mingw-runtime-3.0) | tar xzf - -C upstream/install/i686-pc-mingw32
+ifeq ($(shell uname),Linux)
+ cd upstream/install/i686-pc-linux-gnu/include; rm -rf *; ln -sf /usr/include/* .
+endif
+ touch .vendor
+
+.download_gcc-3.3_powerpc-apple-darwin:
+ @echo -e "\n\033[1mdownloading $*...\033[0m"
+ mkdir -p upstream/gcc-3.3
+ curl $(url_gcc-3.3) | tar xzf - -C upstream/gcc-3.3
+ mv upstream/gcc-3.3/gcc-3.3 upstream/gcc-3.3/src-darwin; true
+ mv upstream/gcc-3.3/libmspack upstream/gcc-3.3/src-darwin; true
+ (cd upstream/gcc-3.3/src-darwin && for A in ../patches/[a-y]*.patch; do patch -p0 -l < $$A; done); true
+ (cd upstream/gcc-3.3/src-darwin && for A in ../patches-darwin/*.patch; do patch -p0 -l < $$A; done); true
+ touch $@
+
+.download_%:
+ @echo -e "\n\033[1mdownloading $*...\033[0m"
+ mkdir -p upstream/$*
+ curl $(url_$*) | tar xzf - -C upstream/$*
+ mv upstream/$*/$* upstream/$*/src; true
+ mv upstream/$*/libmspack upstream/$*/src; true
+ (test -e upstream/$*/patches && cd upstream/$*/src && for A in ../patches/*.patch; do patch -p0 -l < $$A; done); true
+ touch $@
+
+.configure_gcc-3.3_powerpc-apple-darwin: .download_gcc-3.3_powerpc-apple-darwin .install_binutils-2.13.2.1_powerpc-apple-darwin
+ @echo -e "\n\033[1mconfiguring gcc...\033[0m"
+ mkdir -p upstream/gcc-3.3/build-$(target)
+ cd upstream/gcc-3.3/build-$(target); \
+ $(setcc) $(environment_gcc-3.3_$(target)) ../src-darwin/configure \
+ --target=$(target) \
+ --prefix=`cd ../..; pwd`/install \
+ $(configure_gcc-3.3) \
+ $(configure_gcc-3.3_$(target))
+ touch $@
+
+.configure_gcc-3.3_$(target): .install_binutils-2.13.2.1_$(target)
+
+.configure_%_$(target): .vendor .download_%
+ @echo -e "\n\033[1mconfiguring $*...\033[0m"
+ mkdir -p upstream/$*/build-$(target)
+ cd upstream/$*/build-$(target); \
+ $(setcc) $(environment_$*_$(target)) ../src/configure \
+ --target=$(target) \
+ --prefix=`cd ../..; pwd`/install \
+ $(configure_$*) \
+ $(configure_$*_$(target))
+ touch $@
+
+.configure_libmspack-20030726_$(target): .download_libmspack-20030726 .install_gcc-3.3_$(target)
+ mkdir -p upstream/libmspack-20030726/build-$(target)
+ cd upstream/libmspack-20030726/build-$(target); ln -sf ../src/mspack/* .
+ touch $@
+
+.install_freetype-2.1.4_mips-unknown-elf: .install_org.ibex.nestedvm .download_freetype-2.1.4
+ cd upstream/freetype-2.1.4/src; \
+ make setup ansi; \
+ PATH=$$PATH:`pwd`/../../install/bin make \
+ CC=mips-unknown-elf-gcc \
+ AR=mips-unknown-elf-ar \
+ CFLAGS="-c -ffunction-sections -fdata-sections -O3"
+ upstream/install/bin/mips-unknown-elf-ranlib upstream/freetype-2.1.4/src/objs/libfreetype.a
+ touch $@
+
+.build_%_$(target): .configure_%_$(target)
+ @echo -e "\n\033[1mbuilding $*...\033[0m"
+ cd upstream/$*/build-$(target); \
+ $(setcc) PATH=$$PATH:`pwd`/../../install/bin \
+ $(environment_$*_$(target)) \
+ make $(make_$*_$(target)) $(setcc) $(environment_$*_$(target))
+ touch $@
+
+.install_libmspack-20030726_$(target): .build_libmspack-20030726_$(target); true
+
+.install_gcc-3.3_mips-unknown-elf: .install_org.ibex.nestedvm
+ touch $@
+
+.install_%_$(target): .build_%_$(target)
+ @echo -e "\n\033[1minstalling $*...\033[0m"
+ cd upstream/$*/build-$(target); \
+ $(setcc) PATH=$$PATH:`pwd`/../../install/bin \
+ $(environment_$*_$(target)) \
+ make $(make_install_$*_$(target)) install $(setcc) $(environment_$*_$(target))
+ touch $@
+
+
+
--- /dev/null
+==============================================================================
+Ibex README
+
+Test
+
+______________________________________________________________________________
+Documentation
+
+If you're new to Ibex, you should read the documentation in the order
+presented below:
+
+- README [this file]
+
+ Start here. Includes a map of all other documentation and a
+ description of the directory strucure
+
+- The Ibex home page [http://www.ibex.org/]
+
+- The Ibex tutorials [http://www.ibex.org/tutorials.html]
+
+ Gentle introduction to what Ibex is, and how to write
+ .ibex's. Good for anybody who wants to write Ibex applications.
+
+- The Ibex reference [http://www.ibex.org/reference.html]
+
+ Precise, technical spec of exactly how Ibex works. Assumes
+ familiarity with Ibex (ie, you've read the tutorial). This is the
+ authoritative source for how an Ibex engine should
+ behave.
+
+
+______________________________________________________________________________
+Directory Structure
+
+/
+ AUTHORS - people involved in developing Ibex
+ README - this file
+ COPYING - copyright information for all files in this distro
+ CHANGES - the changelot
+ TM - trademark information for Ibex
+ Makefile - build file for gcc 3.3
+ next.build - the build id of the next build to be generated
+
+ build/ - anything generated by the build process winds up here
+ h/ - header files generated by gcjh
+ java/ - auto-generated .java source files
+ class/ - java .class files
+ xwar/ - generated xwars (mainly builtin.xwar)
+ mips/ - mips binaries (interpreted on all platforms)
+ JVM/ - java Jar archives
+ Linux/ - Linux binaries
+ Win32/ - Win32 binaries
+ Darwin/ - Darwin binaries
+ Solaris/ - Solaris binaries
+
+ Makefile.upstream - build/download/install instructions for upstream packages
+ upstream/ - download, build, and install area for upstream packages
+ install/ - this is the --prefix for all configure invocations
+ gcc-3.3/ - build/download area for gcc
+ jpeg-6b/ - build/download area for libjpeg
+ freetype-2.1.4/ - build/download area for freetype
+ newlib-1.11.0/ - build/download area for newlib
+ darwin-linker/ - build/download area for a hacked version of Apple's binutils
+
+ lib/ - any third-party binary stuff needed during the build process
+ javago - a copy of the javago post-compilation bytecode inliner
+ jump.jar - the jump2 bytecode-to-palmos translator
+ libgcj-minimal.jar - a tiny portion of libgcj.jar; allows java->bytecode compilation without gcj
+
+ src/ - all java source files and ibex sources go here
+ edu/stanford/ejalbr - source code for BrowserLauncher
+ gnu/regexp/ - source code for the GNU regexp library for Java
+ org/
+ bouncycastle/ - the BouncyCastle Crypto Library
+ ibex/
+ translators/ - .ibex's and .png's that are essential to bootstrapping the engine
+ plat/ - platform-specific code
+ util/ - misc utilities
+ js/ - the Ibex JavaScript Interpreter
+ mips/ - the Ibex MIPS interpreter/recompiler
+ builtin/ - content for the core builtin resource
+
+
+______________________________________________________________________________
+Build Requirements
+
+There are pre-built, digitally signed binaries on http://dist.ibex.org/
+for every supported platform. Please consider using those unless
+you're absolutely certain you need to go through the trouble of trying
+to get Ibex to build.
+
+Requirements:
+ - jdk 1.3+
+ - the standard set of POSIX utilities (wc, grep, find, make, etc)
+
+Build Targets:
+ - compile: compiles all .java files into build/class/
+ - JVM: Any true Java JVM (ie not GCJ)
+ - Win32: Win95 OSR2 or later
+ - Linux: Linux 2.2 or later
+ - Darwin: Any Darwin-based OS (Mac OS X, OpenDarwin)
+ - Solaris: Solaris 2.7+
+ - clean: always run this after doing a 'cvs update'
+
--- /dev/null
+// FIXME
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.core;
+
+// FIXME: are traps on x/y meaningful?
+// FIXME: if we trap on cols, then set rows to 0 (forcing cols to 1), does the cols trap get triggered?
+// FIXME: if we change min{width/height}, thereby forcing a change to max{min/height}, does a trap on those get triggered?
+// FIXME: trap on numchildren? replaces ChildChanged?
+// FIXME: trap on visible, trigger when parent visibility changes
+
+// FIXME: ax/ay nonsense
+// FIXME: mouse move/release still needs to propagate to boxen in which the mouse was pressed and is still held down
+
+// FEATURE: mark to reflow starting with a certain child
+// FEATURE: reintroduce surface.abort
+
+import java.util.*;
+import org.ibex.js.*;
+import org.ibex.util.*;
+import org.ibex.graphics.*;
+
+/**
+ * <p>
+ * Encapsulates the data for a single Ibex box as well as all layout
+ * rendering logic.
+ * </p>
+ *
+ * <p>The rendering process consists of four phases; each requires
+ * one DFS pass over the tree</p>
+ * <ol><li> <b>pack()</b>: each box sets its childrens' row/col
+ * <ol><li> <b>constrain()</b>: contentwidth is computed
+ * <li> <b>resize()</b>: width/height and x/y positions are set
+ * <li> <b>render()</b>: children draw their content onto the PixelBuffer.
+ * </ol>
+ *
+ * The first three passes together are called the <i>reflow</i>
+ * phase. Reflowing is done in a seperate pass since SizeChanges
+ * trigger a Surface.abort; if rendering were done in the same pass,
+ * rendering work done prior to the Surface.abort would be wasted.
+ */
+public final class Box extends JSScope implements Task {
+
+ // Macros //////////////////////////////////////////////////////////////////////
+
+ final void REPLACE() { for(Box b2 = this; b2 != null && !b2.test(REPLACE); b2 = b2.parent) b2.set(REPLACE); }
+ final void RECONSTRAIN() { for(Box b2 = this; b2 != null && !b2.test(RECONSTRAIN); b2 = b2.parent) b2.set(RECONSTRAIN); }
+ final void REPACK() { for(Box b2 = this; b2 != null && !b2.test(REPACK); b2 = b2.parent) b2.set(REPACK); }
+
+
+
+
+
+
+
+ public Box() { super(null); }
+
+ // FIXME memory leak
+ static Hash boxToCursor = new Hash(500, 3);
+
+ static final Font DEFAULT_FONT = Font.getFont((Stream)Main.builtin.get("fonts/vera/Vera.ttf"), 10);
+
+
+ // Flags //////////////////////////////////////////////////////////////////////
+
+ static final int MOUSEINSIDE = 0x00000001;
+ static final int VISIBLE = 0x00000002;
+ static final int PACKED = 0x00000004;
+ public static final int HSHRINK = 0x00000008;
+ public static final int VSHRINK = 0x00000010;
+ static final int BLACK = 0x00000020; // for red-black code
+
+ static final int FIXED = 0x00000040;
+ static final boolean ROWS = true;
+ static final boolean COLS = false;
+
+ static final int ISROOT = 0x00000080;
+ static final int REPACK = 0x00000100;
+ static final int RECONSTRAIN = 0x00000200;
+ static final int REPLACE = 0x00000400;
+
+ static final int ALIGN_TOP = 0x00001000;
+ static final int ALIGN_BOTTOM = 0x00002000;
+ static final int ALIGN_LEFT = 0x00004000;
+ static final int ALIGN_RIGHT = 0x00008000;
+ static final int ALIGNS = 0x0000f000;
+ static final int CURSOR = 0x00010000; // if true, this box has a cursor in the cursor hash; FEATURE: GC issues?
+ static final int CLIP = 0x00020000;
+ static final int STOP_UPWARD_PROPAGATION = 0x00040000;
+ static final int MOVED = 0x00080000;
+
+
+ // Instance Data //////////////////////////////////////////////////////////////////////
+
+ Box parent = null;
+ Box redirect = this;
+ int flags = VISIBLE | PACKED | REPACK | RECONSTRAIN | REPLACE | FIXED | STOP_UPWARD_PROPAGATION | CLIP | MOVED;
+
+ private String text = null;
+ private Font font = DEFAULT_FONT;
+ private Picture texture = null;
+ private short strokewidth = 1;
+ public int fillcolor = 0x00000000;
+ private int strokecolor = 0xFF000000;
+
+ private int aspect = 0;
+
+ // specified directly by user
+ public int minwidth = 0;
+ public int maxwidth = Integer.MAX_VALUE;
+ public int minheight = 0;
+ public int maxheight = Integer.MAX_VALUE;
+ private short rows = 1;
+ private short cols = 0;
+ private short rowspan = 1;
+ private short colspan = 1;
+
+ // computed during reflow
+ private short row = 0;
+ private short col = 0;
+ public int x = 0;
+ public int y = 0;
+ public int ax = 0; // FEATURE: roll these into x/y; requires lots of changes
+ public int ay = 0; // FEATURE: roll these into x/y; requires lots of changes; perhaps y()?
+ public int width = 0;
+ public int height = 0;
+ public int contentwidth = 0; // == max(minwidth, textwidth, sum(child.contentwidth))
+ public int contentheight = 0;
+
+ private Path path = null;
+ /*
+ private Affine transform = null;
+ private VectorGraphics.RasterPath rpath = null;
+ private Affine rtransform = null;
+ */
+
+ // Instance Methods /////////////////////////////////////////////////////////////////////
+
+ public final int fontSize() { return font == null ? DEFAULT_FONT.pointsize : font.pointsize; }
+
+ /** invoked when a resource needed to render ourselves finishes loading */
+ public void perform() throws JSExn {
+ if (texture == null) { Log.warn(Box.class, "perform() called with null texture"); return; }
+ if (texture.isLoaded) {
+ setWidth(max(texture.width, minwidth), maxwidth);
+ setHeight(max(texture.height, minheight), maxheight);
+ dirty(); }
+ else { JS res = texture.stream; texture = null; throw new JSExn("image not found: "+res.unclone()); }
+ }
+
+ // FEATURE: use cx2/cy2 format
+ /** Adds the intersection of (x,y,w,h) and the node's current actual geometry to the Surface's dirty list */
+ public void dirty() { dirty(0, 0, width, height); }
+ public void dirty(int x, int y, int w, int h) {
+ for(Box cur = this; cur != null; cur = cur.parent) {
+ // x and y have a different meaning on the root box
+ if (cur.parent != null && cur.test(CLIP)) {
+ w = min(x + w, cur.width) - max(x, 0);
+ h = min(y + h, cur.height) - max(y, 0);
+ x = max(x, 0);
+ y = max(y, 0);
+ }
+ if (w <= 0 || h <= 0) return;
+ if (cur.parent == null && cur.getSurface() != null) cur.getSurface().dirty(x, y, w, h);
+ x += cur.x;
+ y += cur.y;
+ }
+ }
+
+
+ // Reflow ////////////////////////////////////////////////////////////////////////////////////////
+
+ /** should only be invoked on the root box */
+ public void reflow() {
+ pack();
+ resize(x, y,
+ test(HSHRINK) ? contentwidth : maxwidth,
+ test(VSHRINK) ? contentheight : maxheight);
+ place();
+ }
+
+ private static Box[] frontier = new Box[65535];
+ /** pack the boxes into rows and columns, compute contentwidth */
+ public void pack() {
+ if (!test(REPACK)) { constrain(); return; }
+ boolean haskid = false;
+ for(Box child = getChild(0); child != null; child = child.nextSibling()) { haskid = true; child.pack(); }
+ if (!haskid) { clear(REPACK); constrain(); return; }
+ int frontier_size = 0;
+
+
+ if (test(FIXED) == COLS) {
+ rows = 0;
+ for(Box child = getChild(0); child != null; child = child.nextSibling()) {
+ if (!child.test(PACKED) || !child.test(VISIBLE)) continue;
+ if (cols == 1) { child.row = rows; rows += child.rowspan; child.col = 0; continue; }
+ child.col = (short)(frontier_size <= 0 ? 0 : (frontier[frontier_size-1].col + frontier[frontier_size-1].colspan));
+ child.row = (short)(frontier_size <= 0 ? 0 : frontier[frontier_size-1].row);
+ if (child.col + min(cols,child.colspan) > cols) { child.col = 0; child.row++; }
+ for(int i=0; i<frontier_size; i++)
+ if (frontier[i].row + frontier[i].rowspan <= child.row) {
+ frontier[i--] = frontier[--frontier_size]; frontier[frontier_size] = null;
+ } else if (frontier[i].col<child.col+min(cols,child.colspan)&&frontier[i].col+frontier[i].colspan>child.col) {
+ child.col = (short)(frontier[i].col + frontier[i].colspan);
+ if (child.col + min(cols,child.colspan) > cols) {
+ child.row = (short)(frontier[i].row + frontier[i].rowspan);
+ for(i--; i>0; i--) child.row = (short)min(row, frontier[i].row + frontier[i].rowspan);
+ child.col = (short)0;
+ }
+ i = -1;
+ } else break;
+ frontier[frontier_size++] = child;
+ }
+ for(int i=0; i<frontier_size; i++){ rows=(short)max(rows, frontier[i].row + frontier[i].rowspan); frontier[i] = null; }
+ }
+
+ if (test(FIXED) == ROWS) { cols = 0; for(Box child = getChild(0); child != null; child = child.nextSibling()) { if (!child.test(PACKED) || !child.test(VISIBLE)) continue; if (rows == 1) { child.col = cols; cols += child.colspan; child.row = 0; continue; } child.row = (short)(frontier_size <= 0 ? 0 : (frontier[frontier_size-1].row + frontier[frontier_size-1].rowspan)); child.col = (short)(frontier_size <= 0 ? 0 : frontier[frontier_size-1].col); if (child.row + min(rows,child.rowspan) > rows) { child.row = 0; child.col++; } for(int i=0; i<frontier_size; i++) if (frontier[i].col + frontier[i].colspan <= child.col) { frontier[i--] = frontier[--frontier_size]; frontier[frontier_size] = null; } else if (frontier[i].row<child.row+min(rows,child.rowspan)&&frontier[i].row+frontier[i].rowspan>child.row) { child.row = (short)(frontier[i].row + frontier[i].rowspan); if (child.row + min(rows,child.rowspan) > rows) { child.col = (short)(frontier[i].col + frontier[i].colspan); for(i--; i>0; i--) child.col = (short)min(col, frontier[i].col + frontier[i].colspan); child.row = (short)0; } i = -1; } else break; frontier[frontier_size++] = child; } for(int i=0; i<frontier_size; i++){ cols=(short)max(cols, frontier[i].col + frontier[i].colspan); frontier[i] = null; } } clear(REPACK);
+ set(RECONSTRAIN); // FIXME: be smarter / more incremental
+ constrain();
+ }
+
+ public void constrain() {
+ if (!test(RECONSTRAIN)) return;
+ solve(true);
+
+
+ contentwidth = bound(minwidth,
+ max(contentwidth, font == null || text == null ? 0 : font.textwidth(text)),
+ maxwidth);
+
+ contentheight = bound(minheight, max(contentheight, font == null || text == null ? 0 : font.textheight(text)), maxheight); set(REPLACE); // FIXME: be smarter / more incremental
+ }
+
+ void resize(int x, int y, int width, int height) {
+ if (x == this.x && y == this.y && width == this.width && height == this.height) return;
+ boolean sizechange = (this.width != width || this.height != height) && getTrap("SizeChange") != null;
+ int thisx = parent == null ? 0 : this.x;
+ int thisy = parent == null ? 0 : this.y;
+ Box who = (parent == null ? this : parent);
+ if (this.x != x || this.y != y) set(MOVED);
+ if (texture == null && (text == null || text.equals("")) && !test(MOVED)) {
+ if ((fillcolor & 0xff000000) != 0 || parent == null) {
+ who.dirty(thisx+min(this.width,width), thisy, Math.abs(width-this.width), max(this.height, height));
+ who.dirty(thisx, thisy+min(this.height,height), max(this.width, width), Math.abs(height-this.height));
+ }
+ this.width = width; this.height = height; this.x = x; this.y = y;
+ } else {
+ who.dirty(thisx, thisy, this.width, this.height);
+ this.width = width; this.height = height; this.x = x; this.y = y;
+ dirty();
+ }
+ if (sizechange) putAndTriggerTrapsAndCatchExceptions("SizeChange", T);
+ }
+
+ private float targetColumnSize = (float)0.0;
+ private float targetRowSize = (float)0.0;
+ private static float[] sizes = new float[65535];
+ private static float[] sizes_v = new float[65535];
+ private static int[] regions = new int[65535];
+ private static int[] regions_v = new int[65535];
+ private static int numregions = 0;
+ private static int numregions_v = 0;
+
+ void solve(boolean findMinimum) {
+ int numkids = 0; for(Box c = firstPackedChild(); c != null; c = c.nextPackedSibling()) numkids++;
+
+
+
+ if (numkids == 0) {
+ if (findMinimum) contentwidth = 0;
+ else targetColumnSize = 0;
+ } else if (cols == 1) {
+ if (findMinimum) {
+ contentwidth = 0;
+ for(Box c = firstPackedChild(); c != null; c = c.nextPackedSibling())
+ contentwidth = max(contentwidth, c.contentwidth);
+ } else {
+ targetColumnSize = width;
+ }
+ } else if (cols > 1) do {
+
+ // FIXME: cache these?
+ // compute regions
+ numregions = 0;
+ for(Box c = firstPackedChild(); c != null; c = c.nextPackedSibling()) {
+ regions[numregions++] = c.col;
+ regions[numregions++] = min(cols, c.col+c.colspan);
+ }
+ Vec.sortInts(regions, 0, numregions);
+ int j = 0;
+ int newnumregions = numregions;
+ for(int i=1; i<numregions; i++) {
+ if (regions[j] != regions[i]) j++;
+ else newnumregions--;
+ regions[j] = regions[i];
+ }
+ numregions = newnumregions;
+ if (regions[numregions-1] == cols) numregions--;
+ else regions[numregions] = cols;
+
+ int target = findMinimum ? 0 : Math.max(width, contentwidth);
+ // priority 0: (inviolable) honor minwidths
+ // priority 1: sum of columns no greater than parent
+ // priority 2: honor maxwidths
+ // priority 3: equalize columns
+ float targetColumnSize = target == 0 ? 0 : this.targetColumnSize;
+ float last_columnsize = 0;
+ float last_total = 0;
+ float total;
+ boolean first = true;
+ while(true) {
+ total = (float)0.0;
+ for(int r=0; r<numregions; r++) total += (sizes[r] = (float)(targetColumnSize * (regions[r+1]-regions[r])));
+ int minregion = 0;
+ for(Box child = firstPackedChild(); child != null; child = child.nextPackedSibling())
+ for(int r=(child.col==0?0:minregion); r<numregions; r++) {
+ if (regions[r+1] < child.col) continue;
+ if (regions[r] >= min(child.col+child.colspan,cols)) { minregion = r; break; }
+ total -= sizes[r];
+ int child_maxwidth = child.test(HSHRINK)?child.contentwidth:child.maxwidth;
+ if (sizes[r] <= (float)(targetColumnSize*(regions[r+1]-regions[r])))
+ if ((child.colspan * targetColumnSize) > (child_maxwidth + (float)0.5))
+ sizes[r] = (float)Math.min(sizes[r], (regions[r+1]-regions[r])*(child_maxwidth/child.colspan));
+ if ((child.colspan * targetColumnSize) < (child.contentwidth - (float)0.5))
+ sizes[r] = (float)Math.max(sizes[r], (regions[r+1]-regions[r])*(child.contentwidth/child.colspan));
+ total += sizes[r];
+ }
+ float save = targetColumnSize;
+ if (Math.abs(total - target) <= (float)1.0) break;
+ if (!first) {
+ if (Math.abs(total - last_total) <= (float)1.0) break;
+ } else {
+ last_columnsize = ((total - target) / (float)cols) + targetColumnSize;
+ }
+ if (total < target) targetColumnSize += Math.abs((last_columnsize - targetColumnSize) / (float)1.1);
+ else if (total > target) targetColumnSize -= Math.abs((last_columnsize - targetColumnSize) / (float)1.1);
+ last_columnsize = save;
+ last_total = total;
+ first = false;
+ }
+ if (findMinimum) contentwidth = Math.round(total);
+ else this.targetColumnSize = targetColumnSize;
+ } while(false);
+
+ if (numkids == 0) { if (findMinimum) contentheight = 0; else targetRowSize = 0; } else if (rows == 1) { if (findMinimum) { contentheight = 0; for(Box c = firstPackedChild(); c != null; c = c.nextPackedSibling()) contentheight = max(contentheight, c.contentheight); } else { targetRowSize = height; } } else if (rows > 1) do { numregions_v = 0; for(Box c = firstPackedChild(); c != null; c = c.nextPackedSibling()) { regions_v[numregions_v++] = c.row; regions_v[numregions_v++] = min(rows, c.row+c.rowspan); } Vec.sortInts(regions_v, 0, numregions_v); int j = 0; int newnumregions = numregions_v; for(int i=1; i<numregions_v; i++) { if (regions_v[j] != regions_v[i]) j++; else newnumregions--; regions_v[j] = regions_v[i]; } numregions_v = newnumregions; if (regions_v[numregions_v-1] == rows) numregions_v--; else regions_v[numregions_v] = rows; int target = findMinimum ? 0 : Math.max(height, contentheight); float targetRowSize = target == 0 ? 0 : this.targetRowSize; float last_columnsize = 0; float last_total = 0; float total; boolean first = true; while(true) { total = (float)0.0; for(int r=0; r<numregions_v; r++) total += (sizes_v[r] = (float)(targetRowSize * (regions_v[r+1]-regions_v[r]))); int minregion = 0; for(Box child = firstPackedChild(); child != null; child = child.nextPackedSibling()) for(int r=(child.row==0?0:minregion); r<numregions_v; r++) { if (regions_v[r+1] < child.row) continue; if (regions_v[r] >= min(child.row+child.rowspan,rows)) { minregion = r; break; } total -= sizes_v[r]; int child_maxwidth = child.test(VSHRINK)?child.contentheight:child.maxheight; if (sizes_v[r] <= (float)(targetRowSize*(regions_v[r+1]-regions_v[r]))) if ((child.rowspan * targetRowSize) > (child_maxwidth + (float)0.5)) sizes_v[r] = (float)Math.min(sizes_v[r], (regions_v[r+1]-regions_v[r])*(child_maxwidth/child.rowspan)); if ((child.rowspan * targetRowSize) < (child.contentheight - (float)0.5)) sizes_v[r] = (float)Math.max(sizes_v[r], (regions_v[r+1]-regions_v[r])*(child.contentheight/child.rowspan)); total += sizes_v[r]; } float save = targetRowSize; if (Math.abs(total - target) <= (float)1.0) break; if (!first) { if (Math.abs(total - last_total) <= (float)1.0) break; } else { last_columnsize = ((total - target) / (float)rows) + targetRowSize; } if (total < target) targetRowSize += Math.abs((last_columnsize - targetRowSize) / (float)1.1); else if (total > target) targetRowSize -= Math.abs((last_columnsize - targetRowSize) / (float)1.1); last_columnsize = save; last_total = total; first = false; } if (findMinimum) contentheight = Math.round(total); else this.targetRowSize = targetRowSize; } while(false); }
+
+ void place() {
+ solve(false);
+ for(Box child = getChild(0); child != null; child = child.nextSibling()) {
+ if (!child.test(VISIBLE)) continue;
+ if (!child.test(REPLACE)) continue;
+ int child_width, child_height, child_x, child_y;
+ if (!child.test(PACKED)) {
+ child_width = child.test(HSHRINK) ? child.contentwidth : min(child.maxwidth, width - Math.abs(child.ax));
+ child_height = child.test(VSHRINK) ? child.contentheight : min(child.maxheight, height - Math.abs(child.ay));
+ child_width = max(child.minwidth, child_width);
+ child_height = max(child.minheight, child_height);
+ int gap_x = width - child_width;
+ int gap_y = height - child_height;
+ child_x = child.ax + (child.test(ALIGN_RIGHT) ? gap_x : !child.test(ALIGN_LEFT) ? gap_x / 2 : 0);
+ child_y = child.ay + (child.test(ALIGN_BOTTOM) ? gap_y : !child.test(ALIGN_TOP) ? gap_y / 2 : 0);
+ } else {
+ int diff;
+
+
+
+
+ child_x = 0;
+ if (cols == 1) {
+ child_width = width;
+ } else {
+ child_width = 0;
+ for(int r=0; r<numregions; r++) {
+ if (regions[r] < child.col) child_x += Math.round(sizes[r]);
+ else if (regions[r] < child.col+child.colspan) child_width += Math.round(sizes[r]);
+ }
+ }
+ diff = (child_width - (child.test(HSHRINK) ? child.contentwidth : min(child_width, child.maxwidth)));
+ child_x += (child.test(ALIGN_RIGHT) ? diff : child.test(ALIGN_LEFT) ? 0 : diff / 2);
+ child_width -= diff;
+
+ child_y = 0; if (rows == 1) { child_height = height; } else { child_height = 0; for(int r=0; r<numregions_v; r++) { if (regions_v[r] < child.row) child_y += Math.round(sizes_v[r]); else if (regions_v[r] < child.row+child.rowspan) child_height += Math.round(sizes_v[r]); } } diff = (child_height - (child.test(VSHRINK) ? child.contentheight : min(child_height, child.maxheight))); child_y += (child.test(ALIGN_BOTTOM) ? diff : child.test(ALIGN_TOP) ? 0 : diff / 2); child_height -= diff; }
+ if (test(MOVED)) child.set(MOVED);
+ child.resize(child_x, child_y, child_width, child_height);
+ }
+ clear(MOVED);
+
+ for(Box child = getChild(0); child != null; child = child.nextSibling())
+ if (child.test(VISIBLE) && child.treeSize() > 0)
+ child.place();
+ }
+
+
+
+ // Rendering Pipeline /////////////////////////////////////////////////////////////////////
+
+ /** Renders self and children within the specified region. All rendering operations are clipped to xIn,yIn,wIn,hIn */
+ public void render(int parentx, int parenty, int cx1, int cy1, int cx2, int cy2, PixelBuffer buf, Affine a) {
+ if (!test(VISIBLE)) return;
+ int globalx = parentx + (parent == null ? 0 : x);
+ int globaly = parenty + (parent == null ? 0 : y);
+
+ // intersect the x,y,w,h rendering window with ourselves; quit if it's empty
+ if (test(CLIP)) {
+ cx1 = max(cx1, globalx);
+ cy1 = max(cy1, globaly);
+ cx2 = min(cx2, globalx + width);
+ cy2 = min(cy2, globaly + height);
+ if (cx2 <= cx1 || cy2 <= cy1) return;
+ }
+
+ if ((fillcolor & 0xFF000000) != 0x00000000 || parent == null)
+ buf.fillTrapezoid(cx1, cx2, cy1, cx1, cx2, cy2, (fillcolor & 0xFF000000) == 0 ? 0xffffffff : fillcolor);
+
+ if (texture != null && texture.isLoaded)
+ for(int x = globalx; x < cx2; x += texture.width)
+ for(int y = globaly; y < cy2; y += texture.height)
+ buf.drawPicture(texture, x, y, cx1, cy1, cx2, cy2);
+
+ if (text != null && !text.equals("") && font != null) {
+ int gap_x = width - font.textwidth(text);
+ int gap_y = height - font.textheight(text);
+ int text_x = globalx + (test(ALIGN_RIGHT) ? gap_x : !test(ALIGN_LEFT) ? gap_x/2 : 0);
+ int text_y = globaly + (test(ALIGN_BOTTOM) ? gap_y : !test(ALIGN_TOP) ? gap_y/2 : 0);
+ font.rasterizeGlyphs(text, buf, strokecolor, text_x, text_y, cx1, cy1, cx2, cy2);
+ }
+
+ if (path != null) path.realize(Affine.translate(globalx, globaly)).stroke(buf, 1, strokecolor);
+
+ for(Box b = getChild(0); b != null; b = b.nextSibling())
+ b.render(globalx, globaly, cx1, cy1, cx2, cy2, buf, null);
+ }
+
+
+ // Methods to implement org.ibex.js.JS //////////////////////////////////////
+
+
+ public Object callMethod(Object method, Object a0, Object a1, Object a2, Object[] rest, int nargs) throws JSExn {
+ switch (nargs) {
+ case 1: {
+final String ccSwitch0 = (String)(method); SUCCESS:do { switch(ccSwitch0.length()) {
+case 7: { switch(ccSwitch0.charAt(0)) { case 'i': if ("indexof".equals(ccSwitch0)) { if (true) do {
+Box b = (Box)a0;
+if (b.parent != this)
+return (redirect == null || redirect == this) ?
+N(-1) :
+redirect.callMethod(method, a0, a1, a2, rest, nargs);
+return N(b.getIndexInParent());
+
+ } while(false); break SUCCESS; } break; }; break; } case 10: { switch(ccSwitch0.charAt(0)) { case 'd': if ("distanceto".equals(ccSwitch0)) { if (true) do {
+Box b = (Box)a0;
+JS ret = new JS();
+ret.put("x", N(b.localToGlobalX(0) - localToGlobalX(0)));
+ret.put("y", N(b.localToGlobalY(0) - localToGlobalY(0)));
+return ret;
+
+ } while(false); break SUCCESS; } break; }; break; } } /* switch */ } while(false); /* OUTER */
+ }
+ }
+ return super.callMethod(method, a0, a1, a2, rest, nargs);
+ }
+
+ public Object get(Object name) throws JSExn {
+ if (name instanceof Number)
+ return redirect == null ? null : redirect == this ? getChild(toInt(name)) : redirect.get(name);
+
+final String ccSwitch1 = (String)(name); SUCCESS:do { switch(ccSwitch1.length()) {
+case 1: { switch(ccSwitch1.charAt(0)) { case 'x': if ("x".equals(ccSwitch1)) { if (true) do { return (parent == null || !test(VISIBLE)) ? N(0) : test(PACKED) ? N(x) : N(ax);
+ } while(false); break SUCCESS; } break; case 'y': if ("y".equals(ccSwitch1)) { if (true) do { return (parent == null || !test(VISIBLE)) ? N(0) : test(PACKED) ? N(y) : N(ay);
+ } while(false); break SUCCESS; } break; }; break; } case 4: { switch(ccSwitch1.charAt(0)) { case 'c': { switch(ccSwitch1.charAt(1)) { case 'l': if ("clip".equals(ccSwitch1)) { if (true) do { return B(test(CLIP));
+ } while(false); break SUCCESS; } break; case 'o': if ("cols".equals(ccSwitch1)) { if (true) do { return test(FIXED) == COLS ? N(cols) : N(0);
+ } while(false); break SUCCESS; } break; } break; } case 'f': { switch(ccSwitch1.charAt(1)) { case 'i': if ("fill".equals(ccSwitch1)) { if (true) do { return Color.colorToString(fillcolor);
+ } while(false); break SUCCESS; } break; case 'o': if ("font".equals(ccSwitch1)) { if (true) do { return font == null ? null : font.stream;
+ } while(false); break SUCCESS; } break; } break; } case 'p': if ("path".equals(ccSwitch1)) { if (true) do {
+if (path != null) return path.toString();
+if (text == null) return null;
+if (font == null) return null;
+String ret = "";
+for(int i=0; i<text.length(); i++) ret += font.glyphs[text.charAt(i)].path;
+return ret;
+ } while(false); break SUCCESS; } break; case 'r': if ("rows".equals(ccSwitch1)) { if (true) do { return test(FIXED) == ROWS ? N(rows) : N(0);
+ } while(false); break SUCCESS; } break; case 't': if ("text".equals(ccSwitch1)) { if (true) do { return text;
+ } while(false); break SUCCESS; } break; }; break; } case 5: { switch(ccSwitch1.charAt(0)) { case 'a': if ("align".equals(ccSwitch1)) { if (true) do { return alignToString();
+ } while(false); break SUCCESS; } break; case 'm': if ("mouse".equals(ccSwitch1)) { if (true) do {
+if (getSurface() == null) return null;
+if (getSurface()._mousex == Integer.MAX_VALUE)
+throw new JSExn("you cannot read from the box.mouse property in background thread context");
+return new Mouse();
+ } while(false); break SUCCESS; } break; case 'w': if ("width".equals(ccSwitch1)) { if (true) do { getRoot().reflow(); return N(width);
+ } while(false); break SUCCESS; } break; }; break; } case 6: { switch(ccSwitch1.charAt(0)) { case 'a': if ("aspect".equals(ccSwitch1)) { if (true) do { return N(aspect);
+ } while(false); break SUCCESS; } break; case 'c': if ("cursor".equals(ccSwitch1)) { if (true) do { return test(CURSOR) ? boxToCursor.get(this) : null;
+ } while(false); break SUCCESS; } break; case 'h': if ("height".equals(ccSwitch1)) { if (true) do { getRoot().reflow(); return N(height);
+ } while(false); break SUCCESS; } break; case 'p': if ("packed".equals(ccSwitch1)) { if (true) do { return B(test(PACKED));
+ } while(false); break SUCCESS; } break; case 's': if ("shrink".equals(ccSwitch1)) { if (true) do { return B(test(HSHRINK) || test(VSHRINK));
+ } while(false); break SUCCESS; } break; }; break; } case 7: { switch(ccSwitch1.charAt(0)) { case 'c': if ("colspan".equals(ccSwitch1)) { if (true) do { return N(colspan);
+ } while(false); break SUCCESS; } break; case 'g': { switch(ccSwitch1.charAt(1)) { case 'l': { switch(ccSwitch1.charAt(2)) { case 'o': { switch(ccSwitch1.charAt(3)) { case 'b': { switch(ccSwitch1.charAt(4)) { case 'a': { switch(ccSwitch1.charAt(5)) { case 'l': { switch(ccSwitch1.charAt(6)) { case 'x': if ("globalx".equals(ccSwitch1)) { if (true) do { return N(localToGlobalX(0));
+ } while(false); break SUCCESS; } break; case 'y': if ("globaly".equals(ccSwitch1)) { if (true) do { return N(localToGlobalY(0));
+ } while(false); break SUCCESS; } break; } break; } } break; } } break; } } break; } } break; } } break; } case 'h': if ("hshrink".equals(ccSwitch1)) { if (true) do { return B(test(HSHRINK));
+ } while(false); break SUCCESS; } break; case 'i': if ("indexof".equals(ccSwitch1)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 'r': if ("rowspan".equals(ccSwitch1)) { if (true) do { return N(rowspan);
+ } while(false); break SUCCESS; } break; case 's': if ("surface".equals(ccSwitch1)) { if (true) do { return parent == null ? null : parent.getAndTriggerTraps("surface");
+ } while(false); break SUCCESS; } break; case 't': if ("thisbox".equals(ccSwitch1)) { if (true) do { return this;
+ } while(false); break SUCCESS; } break; case 'v': { switch(ccSwitch1.charAt(1)) { case 'i': if ("visible".equals(ccSwitch1)) { if (true) do { return B(test(VISIBLE) && (parent == null || (parent.get("visible") == T)));
+ } while(false); break SUCCESS; } break; case 's': if ("vshrink".equals(ccSwitch1)) { if (true) do { return B(test(VSHRINK));
+ } while(false); break SUCCESS; } break; } break; } }; break; } case 8: { switch(ccSwitch1.charAt(0)) { case 'f': if ("fontsize".equals(ccSwitch1)) { if (true) do { return font == null ? N(10) : N(font.pointsize);
+ } while(false); break SUCCESS; } break; case 'm': { switch(ccSwitch1.charAt(1)) { case 'a': if ("maxwidth".equals(ccSwitch1)) { if (true) do { return N(maxwidth);
+ } while(false); break SUCCESS; } break; case 'i': if ("minwidth".equals(ccSwitch1)) { if (true) do { return N(minwidth);
+ } while(false); break SUCCESS; } break; } break; } case 'r': if ("redirect".equals(ccSwitch1)) { if (true) do { return redirect == null ? null : redirect == this ? T : redirect.get("redirect");
+ } while(false); break SUCCESS; } break; }; break; } case 9: { switch(ccSwitch1.charAt(0)) { case 'M': if ("Minimized".equals(ccSwitch1)) { if (true) do { if (parent == null && getSurface() != null) return B(getSurface().minimized);
+ } while(false); break SUCCESS; } break; case 'm': { switch(ccSwitch1.charAt(1)) { case 'a': if ("maxheight".equals(ccSwitch1)) { if (true) do { return N(maxheight);
+ } while(false); break SUCCESS; } break; case 'i': if ("minheight".equals(ccSwitch1)) { if (true) do { return N(minheight);
+ } while(false); break SUCCESS; } break; } break; } case 't': if ("textcolor".equals(ccSwitch1)) { if (true) do { return Color.colorToString(strokecolor);
+ } while(false); break SUCCESS; } break; }; break; } case 10: { switch(ccSwitch1.charAt(0)) { case 'd': if ("distanceto".equals(ccSwitch1)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; }; break; } case 11: { switch(ccSwitch1.charAt(0)) { case 'n': if ("numchildren".equals(ccSwitch1)) { if (true) do { return redirect == null ? N(0) : redirect == this ? N(treeSize()) : redirect.get("numchildren");
+ } while(false); break SUCCESS; } break; case 's': { switch(ccSwitch1.charAt(1)) { case 't': { switch(ccSwitch1.charAt(2)) { case 'r': { switch(ccSwitch1.charAt(3)) { case 'o': { switch(ccSwitch1.charAt(4)) { case 'k': { switch(ccSwitch1.charAt(5)) { case 'e': { switch(ccSwitch1.charAt(6)) { case 'c': if ("strokecolor".equals(ccSwitch1)) { if (true) do { return Color.colorToString(strokecolor);
+ } while(false); break SUCCESS; } break; case 'w': if ("strokewidth".equals(ccSwitch1)) { if (true) do { return N(strokewidth);
+ } while(false); break SUCCESS; } break; } break; } } break; } } break; } } break; } } break; } } break; } }; break; } } /* switch */ return super.get(name);
+ } while(false); /* OUTER */
+ throw new Error("unreachable"); // unreachable
+ }
+
+ private class Mouse extends JS.Cloneable {
+ public Object get(Object key) {
+final String ccSwitch2 = (String)(key); SUCCESS:do { switch(ccSwitch2.length()) {
+case 1: { switch(ccSwitch2.charAt(0)) { case 'x': if ("x".equals(ccSwitch2)) { if (true) do { return N(globalToLocalX(getSurface()._mousex));
+ } while(false); break SUCCESS; } break; case 'y': if ("y".equals(ccSwitch2)) { if (true) do { return N(globalToLocalY(getSurface()._mousey));
+
+
+ } while(false); break SUCCESS; } break; }; break; } case 6: { switch(ccSwitch2.charAt(0)) { case 'i': if ("inside".equals(ccSwitch2)) { if (true) do { return B(test(MOUSEINSIDE));
+ } while(false); break SUCCESS; } break; }; break; } } /* switch */ } while(false); /* OUTER */
+ return null;
+ }
+ }
+
+
+ public void setWidth(int min, int max) {
+ // FIXME: deal with conflicting min/max
+ if (this.minwidth == min && this.maxwidth == max) return;
+ this.minwidth = min;
+ this.maxwidth = max;
+ RECONSTRAIN();
+ if (parent != null || getSurface() == null) return;
+ getSurface().pendingWidth = maxwidth;
+
+ // FIXME: the repeat doesn't work right here
+ getSurface().setMinimumSize(minwidth, minheight, minwidth != maxwidth || minheight != maxheight);
+ }
+
+ public void setHeight(int min, int max) { if (this.minheight == min && this.maxheight == max) return; this.minheight = min; this.maxheight = max; RECONSTRAIN(); if (parent != null || getSurface() == null) return; getSurface().pendingHeight = maxheight; getSurface().setMinimumSize(minheight, minheight, minheight != maxheight || minheight != maxheight); }
+ public void put(Object name, Object value) throws JSExn {
+ if (name instanceof Number) { put(toInt(name), value); return; }
+final String ccSwitch3 = (String)(name); SUCCESS:do { switch(ccSwitch3.length()) {
+case 1: { switch(ccSwitch3.charAt(0)) { case 'x': if ("x".equals(ccSwitch3)) { if (true) do { if (parent==null && Surface.fromBox(this)!=null) {
+int nu = toInt(value); if (nu == x) break; x = nu;;
+} else {
+if (test(PACKED) && parent != null) return;
+int nu = toInt(value); if (nu == ax) break; ax = nu;;
+REPLACE();
+}
+ } while(false); break SUCCESS; } break; case 'y': if ("y".equals(ccSwitch3)) { if (true) do { if (parent==null && Surface.fromBox(this)!=null) {
+int nu = toInt(value); if (nu == y) break; y = nu;;
+} else {
+if (test(PACKED) && parent != null) return;
+int nu = toInt(value); if (nu == ay) break; ay = nu;;
+REPLACE();
+}
+ } while(false); break SUCCESS; } break; }; break; } case 4: { switch(ccSwitch3.charAt(0)) { case 'M': if ("Move".equals(ccSwitch3)) { if (true) do { if (!test(STOP_UPWARD_PROPAGATION) && parent != null) parent.putAndTriggerTraps(name, value);
+ } while(false); break SUCCESS; } break; case 'c': { switch(ccSwitch3.charAt(1)) { case 'l': if ("clip".equals(ccSwitch3)) { if (true) do { boolean nu = toBoolean(value); if (nu == test(CLIP)) break; if (nu) set(CLIP); else clear(CLIP);; if (parent == null) dirty(); else parent.dirty();
+ } while(false); break SUCCESS; } break; case 'o': if ("cols".equals(ccSwitch3)) { if (true) do { short nu = (short)toInt(value); if (nu == cols) break; cols = nu;; if (cols==0){set(FIXED, ROWS);if(rows==0)rows=1;} else set(FIXED, COLS); REPACK();
+
+
+ } while(false); break SUCCESS; } break; } break; } case 'f': { switch(ccSwitch3.charAt(1)) { case 'i': if ("fill".equals(ccSwitch3)) { if (true) do { setFill(value);
+ } while(false); break SUCCESS; } break; case 'o': if ("font".equals(ccSwitch3)) { if (true) do {
+if(!(value instanceof Stream)) throw new JSExn("You can only put streams to the font property");
+if (font == value) return;
+font = value == null ? null : Font.getFont((Stream)value, font == null ? 10 : font.pointsize);
+RECONSTRAIN();
+dirty();
+ } while(false); break SUCCESS; } break; } break; } case 'p': if ("path".equals(ccSwitch3)) { if (true) do { path = Path.parse(toString(value)); RECONSTRAIN(); dirty();
+ } while(false); break SUCCESS; } break; case 'r': if ("rows".equals(ccSwitch3)) { if (true) do { short nu = (short)toInt(value); if (nu == rows) break; rows = nu;; if (rows==0){set(FIXED, COLS);if(cols==0)cols=1;} else set(FIXED, ROWS); REPACK();
+ } while(false); break SUCCESS; } break; case 't': if ("text".equals(ccSwitch3)) { if (true) do { if (value == null) value = ""; if ((value==null&&text==null)||(value!=null&&JS.toString(value).equals(text))) break; text=JS.toString(value);; RECONSTRAIN(); dirty();
+ } while(false); break SUCCESS; } break; }; break; } case 5: { switch(ccSwitch3.charAt(0)) { case 'C': if ("Close".equals(ccSwitch3)) { if (true) do { if (parent == null && getSurface() != null) getSurface().dispose(true);
+ } while(false); break SUCCESS; } break; case 'E': if ("Enter".equals(ccSwitch3)) { if (true) do { return;
+ } while(false); break SUCCESS; } break; case 'L': if ("Leave".equals(ccSwitch3)) { if (true) do { return;
+
+ } while(false); break SUCCESS; } break; case '_': if ("_Move".equals(ccSwitch3)) { if (true) do { propagateDownward(name, value, false);
+ } while(false); break SUCCESS; } break; case 'a': if ("align".equals(ccSwitch3)) { if (true) do { clear(ALIGNS); setAlign(value == null ? "center" : value); REPLACE();
+ } while(false); break SUCCESS; } break; case 'm': if ("mouse".equals(ccSwitch3)) { if (true) do {
+int mousex = toInt(((JS)value).get("x"));
+int mousey = toInt(((JS)value).get("y"));
+getSurface()._mousex = localToGlobalX(mousex);
+getSurface()._mousey = localToGlobalY(mousey);
+
+ } while(false); break SUCCESS; } break; case 'w': if ("width".equals(ccSwitch3)) { if (true) do { setWidth(toInt(value), toInt(value));
+ } while(false); break SUCCESS; } break; }; break; } case 6: { switch(ccSwitch3.charAt(0)) { case 'C': { switch(ccSwitch3.charAt(1)) { case 'l': { switch(ccSwitch3.charAt(2)) { case 'i': { switch(ccSwitch3.charAt(3)) { case 'c': { switch(ccSwitch3.charAt(4)) { case 'k': { switch(ccSwitch3.charAt(5)) { case '1': if ("Click1".equals(ccSwitch3)) { if (true) do { if (!test(STOP_UPWARD_PROPAGATION) && parent != null) parent.putAndTriggerTraps(name, value);
+ } while(false); break SUCCESS; } break; case '2': if ("Click2".equals(ccSwitch3)) { if (true) do { if (!test(STOP_UPWARD_PROPAGATION) && parent != null) parent.putAndTriggerTraps(name, value);
+ } while(false); break SUCCESS; } break; case '3': if ("Click3".equals(ccSwitch3)) { if (true) do { if (!test(STOP_UPWARD_PROPAGATION) && parent != null) parent.putAndTriggerTraps(name, value);
+ } while(false); break SUCCESS; } break; } break; } } break; } } break; } } break; } } break; } case 'P': { switch(ccSwitch3.charAt(1)) { case 'r': { switch(ccSwitch3.charAt(2)) { case 'e': { switch(ccSwitch3.charAt(3)) { case 's': { switch(ccSwitch3.charAt(4)) { case 's': { switch(ccSwitch3.charAt(5)) { case '1': if ("Press1".equals(ccSwitch3)) { if (true) do { if (!test(STOP_UPWARD_PROPAGATION) && parent != null) parent.putAndTriggerTraps(name, value);
+ } while(false); break SUCCESS; } break; case '2': if ("Press2".equals(ccSwitch3)) { if (true) do { if (!test(STOP_UPWARD_PROPAGATION) && parent != null) parent.putAndTriggerTraps(name, value);
+ } while(false); break SUCCESS; } break; case '3': if ("Press3".equals(ccSwitch3)) { if (true) do { if (!test(STOP_UPWARD_PROPAGATION) && parent != null) parent.putAndTriggerTraps(name, value);
+ } while(false); break SUCCESS; } break; } break; } } break; } } break; } } break; } } break; } case 'c': if ("cursor".equals(ccSwitch3)) { if (true) do { setCursor(value);
+ } while(false); break SUCCESS; } break; case 'h': if ("height".equals(ccSwitch3)) { if (true) do { setHeight(toInt(value), toInt(value));
+ } while(false); break SUCCESS; } break; case 'p': if ("packed".equals(ccSwitch3)) { if (true) do { boolean nu = toBoolean(value); if (nu == test(PACKED)) break; if (nu) set(PACKED); else clear(PACKED);; if (parent != null) { parent.REPACK(); } else { REPACK(); }
+ } while(false); break SUCCESS; } break; case 's': if ("shrink".equals(ccSwitch3)) { if (true) do { boolean nu = toBoolean(value); if (nu == test(HSHRINK | VSHRINK)) break; if (nu) set(HSHRINK | VSHRINK); else clear(HSHRINK | VSHRINK);; RECONSTRAIN();
+ } while(false); break SUCCESS; } break; }; break; } case 7: { switch(ccSwitch3.charAt(0)) { case 'H': if ("HScroll".equals(ccSwitch3)) { if (true) do { if (!test(STOP_UPWARD_PROPAGATION) && parent != null)
+parent.putAndTriggerTraps(name, N(((Number)value).floatValue() * ((float)parent.fontSize()) / ((float)fontSize())));
+ } while(false); break SUCCESS; } break; case 'V': if ("VScroll".equals(ccSwitch3)) { if (true) do { if (!test(STOP_UPWARD_PROPAGATION) && parent != null)
+parent.putAndTriggerTraps(name, N(((Number)value).floatValue() * ((float)parent.fontSize()) / ((float)fontSize())));
+
+ } while(false); break SUCCESS; } break; case '_': { switch(ccSwitch3.charAt(1)) { case 'C': { switch(ccSwitch3.charAt(2)) { case 'l': { switch(ccSwitch3.charAt(3)) { case 'i': { switch(ccSwitch3.charAt(4)) { case 'c': { switch(ccSwitch3.charAt(5)) { case 'k': { switch(ccSwitch3.charAt(6)) { case '1': if ("_Click1".equals(ccSwitch3)) { if (true) do { propagateDownward(name, value, false);
+ } while(false); break SUCCESS; } break; case '2': if ("_Click2".equals(ccSwitch3)) { if (true) do { propagateDownward(name, value, false);
+ } while(false); break SUCCESS; } break; case '3': if ("_Click3".equals(ccSwitch3)) { if (true) do { propagateDownward(name, value, false);
+ } while(false); break SUCCESS; } break; } break; } } break; } } break; } } break; } } break; } case 'P': { switch(ccSwitch3.charAt(2)) { case 'r': { switch(ccSwitch3.charAt(3)) { case 'e': { switch(ccSwitch3.charAt(4)) { case 's': { switch(ccSwitch3.charAt(5)) { case 's': { switch(ccSwitch3.charAt(6)) { case '1': if ("_Press1".equals(ccSwitch3)) { if (true) do { propagateDownward(name, value, false);
+ } while(false); break SUCCESS; } break; case '2': if ("_Press2".equals(ccSwitch3)) { if (true) do { propagateDownward(name, value, false);
+ } while(false); break SUCCESS; } break; case '3': if ("_Press3".equals(ccSwitch3)) { if (true) do { propagateDownward(name, value, false);
+ } while(false); break SUCCESS; } break; } break; } } break; } } break; } } break; } } break; } } break; } case 'c': if ("colspan".equals(ccSwitch3)) { if (true) do { if (toInt(value) > 0) { short nu = (short)toInt(value); if (nu == colspan) break; colspan = nu;; if (parent != null) parent.REPACK(); }
+ } while(false); break SUCCESS; } break; case 'h': if ("hshrink".equals(ccSwitch3)) { if (true) do { boolean nu = toBoolean(value); if (nu == test(HSHRINK)) break; if (nu) set(HSHRINK); else clear(HSHRINK);; RECONSTRAIN();
+ } while(false); break SUCCESS; } break; case 'r': if ("rowspan".equals(ccSwitch3)) { if (true) do { if (toInt(value) > 0) { short nu = (short)toInt(value); if (nu == rowspan) break; rowspan = nu;; if (parent != null) parent.REPACK(); }
+ } while(false); break SUCCESS; } break; case 't': if ("thisbox".equals(ccSwitch3)) { if (true) do { if (value == null) removeSelf();
+ } while(false); break SUCCESS; } break; case 'v': { switch(ccSwitch3.charAt(1)) { case 'i': if ("visible".equals(ccSwitch3)) { if (true) do { boolean nu = toBoolean(value); if (nu == test(VISIBLE)) break; if (nu) set(VISIBLE); else clear(VISIBLE);; RECONSTRAIN(); dirty();
+ } while(false); break SUCCESS; } break; case 's': if ("vshrink".equals(ccSwitch3)) { if (true) do { boolean nu = toBoolean(value); if (nu == test(VSHRINK)) break; if (nu) set(VSHRINK); else clear(VSHRINK);; RECONSTRAIN();
+ } while(false); break SUCCESS; } break; } break; } }; break; } case 8: { switch(ccSwitch3.charAt(0)) { case 'R': { switch(ccSwitch3.charAt(1)) { case 'e': { switch(ccSwitch3.charAt(2)) { case 'l': { switch(ccSwitch3.charAt(3)) { case 'e': { switch(ccSwitch3.charAt(4)) { case 'a': { switch(ccSwitch3.charAt(5)) { case 's': { switch(ccSwitch3.charAt(6)) { case 'e': { switch(ccSwitch3.charAt(7)) { case '1': if ("Release1".equals(ccSwitch3)) { if (true) do { if (!test(STOP_UPWARD_PROPAGATION) && parent != null) parent.putAndTriggerTraps(name, value);
+ } while(false); break SUCCESS; } break; case '2': if ("Release2".equals(ccSwitch3)) { if (true) do { if (!test(STOP_UPWARD_PROPAGATION) && parent != null) parent.putAndTriggerTraps(name, value);
+ } while(false); break SUCCESS; } break; case '3': if ("Release3".equals(ccSwitch3)) { if (true) do { if (!test(STOP_UPWARD_PROPAGATION) && parent != null) parent.putAndTriggerTraps(name, value);
+ } while(false); break SUCCESS; } break; } break; } } break; } } break; } } break; } } break; } } break; } } break; } case '_': { switch(ccSwitch3.charAt(1)) { case 'H': if ("_HScroll".equals(ccSwitch3)) { if (true) do { propagateDownward(name, value, false);
+ } while(false); break SUCCESS; } break; case 'V': if ("_VScroll".equals(ccSwitch3)) { if (true) do { propagateDownward(name, value, false);
+
+ } while(false); break SUCCESS; } break; } break; } case 'f': if ("fontsize".equals(ccSwitch3)) { if (true) do { font = Font.getFont(font == null ? null : font.stream, toInt(value)); RECONSTRAIN(); dirty();
+ } while(false); break SUCCESS; } break; case 'm': { switch(ccSwitch3.charAt(1)) { case 'a': if ("maxwidth".equals(ccSwitch3)) { if (true) do { setWidth(minwidth, toInt(value));
+ } while(false); break SUCCESS; } break; case 'i': if ("minwidth".equals(ccSwitch3)) { if (true) do { setWidth(toInt(value), maxwidth);
+ } while(false); break SUCCESS; } break; } break; } case 'r': if ("redirect".equals(ccSwitch3)) { if (true) do {
+for(Box cur = (Box)value; cur != null || cur == redirect; cur = cur.parent)
+if (cur == redirect) { redirect = (Box)value; return; }
+JS.error("redirect can only be set to a descendant of its current value");
+ } while(false); break SUCCESS; } break; case 't': if ("titlebar".equals(ccSwitch3)) { if (true) do { if (getSurface()!=null) getSurface().setTitleBarText(toString(value)); super.put(name,value);
+
+
+ } while(false); break SUCCESS; } break; }; break; } case 9: { switch(ccSwitch3.charAt(0)) { case 'M': { switch(ccSwitch3.charAt(1)) { case 'a': if ("Maximized".equals(ccSwitch3)) { if (true) do { if (parent == null && getSurface() != null) getSurface().maximized = toBoolean(value);
+ } while(false); break SUCCESS; } break; case 'i': if ("Minimized".equals(ccSwitch3)) { if (true) do { if (parent == null && getSurface() != null) getSurface().minimized = toBoolean(value);
+ } while(false); break SUCCESS; } break; } break; } case '_': { switch(ccSwitch3.charAt(1)) { case 'R': { switch(ccSwitch3.charAt(2)) { case 'e': { switch(ccSwitch3.charAt(3)) { case 'l': { switch(ccSwitch3.charAt(4)) { case 'e': { switch(ccSwitch3.charAt(5)) { case 'a': { switch(ccSwitch3.charAt(6)) { case 's': { switch(ccSwitch3.charAt(7)) { case 'e': { switch(ccSwitch3.charAt(8)) { case '1': if ("_Release1".equals(ccSwitch3)) { if (true) do { propagateDownward(name, value, false);
+ } while(false); break SUCCESS; } break; case '2': if ("_Release2".equals(ccSwitch3)) { if (true) do { propagateDownward(name, value, false);
+ } while(false); break SUCCESS; } break; case '3': if ("_Release3".equals(ccSwitch3)) { if (true) do { propagateDownward(name, value, false);
+ } while(false); break SUCCESS; } break; } break; } } break; } } break; } } break; } } break; } } break; } } break; } } break; } case 'm': { switch(ccSwitch3.charAt(1)) { case 'a': if ("maxheight".equals(ccSwitch3)) { if (true) do { setHeight(minheight, toInt(value));
+ } while(false); break SUCCESS; } break; case 'i': if ("minheight".equals(ccSwitch3)) { if (true) do { setHeight(toInt(value), maxheight);
+ } while(false); break SUCCESS; } break; } break; } case 't': if ("textcolor".equals(ccSwitch3)) { if (true) do { value = N(Color.stringToColor((String)value)); int nu = toInt(value); if (nu == strokecolor) break; strokecolor = nu;; dirty();
+ } while(false); break SUCCESS; } break; }; break; } case 10: { switch(ccSwitch3.charAt(0)) { case 'K': if ("KeyPressed".equals(ccSwitch3)) { if (true) do { if (!test(STOP_UPWARD_PROPAGATION) && parent != null) parent.putAndTriggerTraps(name, value);
+ } while(false); break SUCCESS; } break; case 'S': if ("SizeChange".equals(ccSwitch3)) { if (true) do { return;
+ } while(false); break SUCCESS; } break; }; break; } case 11: { switch(ccSwitch3.charAt(0)) { case 'C': if ("ChildChange".equals(ccSwitch3)) { if (true) do { return;
+ } while(false); break SUCCESS; } break; case 'K': if ("KeyReleased".equals(ccSwitch3)) { if (true) do { if (!test(STOP_UPWARD_PROPAGATION) && parent != null) parent.putAndTriggerTraps(name, value);
+ } while(false); break SUCCESS; } break; case '_': if ("_KeyPressed".equals(ccSwitch3)) { if (true) do { propagateDownward(name, value, false);
+ } while(false); break SUCCESS; } break; case 's': { switch(ccSwitch3.charAt(1)) { case 't': { switch(ccSwitch3.charAt(2)) { case 'r': { switch(ccSwitch3.charAt(3)) { case 'o': { switch(ccSwitch3.charAt(4)) { case 'k': { switch(ccSwitch3.charAt(5)) { case 'e': { switch(ccSwitch3.charAt(6)) { case 'c': if ("strokecolor".equals(ccSwitch3)) { if (true) do { value = N(Color.stringToColor((String)value)); int nu = toInt(value); if (nu == strokecolor) break; strokecolor = nu;; dirty();
+ } while(false); break SUCCESS; } break; case 'w': if ("strokewidth".equals(ccSwitch3)) { if (true) do { short nu = (short)toInt(value); if (nu == strokewidth) break; strokewidth = nu;; dirty();
+ } while(false); break SUCCESS; } break; } break; } } break; } } break; } } break; } } break; } } break; } }; break; } case 12: { switch(ccSwitch3.charAt(0)) { case 'D': { switch(ccSwitch3.charAt(1)) { case 'o': { switch(ccSwitch3.charAt(2)) { case 'u': { switch(ccSwitch3.charAt(3)) { case 'b': { switch(ccSwitch3.charAt(4)) { case 'l': { switch(ccSwitch3.charAt(5)) { case 'e': { switch(ccSwitch3.charAt(6)) { case 'C': { switch(ccSwitch3.charAt(7)) { case 'l': { switch(ccSwitch3.charAt(8)) { case 'i': { switch(ccSwitch3.charAt(9)) { case 'c': { switch(ccSwitch3.charAt(10)) { case 'k': { switch(ccSwitch3.charAt(11)) { case '1': if ("DoubleClick1".equals(ccSwitch3)) { if (true) do { if (!test(STOP_UPWARD_PROPAGATION) && parent != null) parent.putAndTriggerTraps(name, value);
+ } while(false); break SUCCESS; } break; case '2': if ("DoubleClick2".equals(ccSwitch3)) { if (true) do { if (!test(STOP_UPWARD_PROPAGATION) && parent != null) parent.putAndTriggerTraps(name, value);
+ } while(false); break SUCCESS; } break; case '3': if ("DoubleClick3".equals(ccSwitch3)) { if (true) do { if (!test(STOP_UPWARD_PROPAGATION) && parent != null) parent.putAndTriggerTraps(name, value);
+ } while(false); break SUCCESS; } break; } break; } } break; } } break; } } break; } } break; } } break; } } break; } } break; } } break; } } break; } } break; } case '_': if ("_KeyReleased".equals(ccSwitch3)) { if (true) do { propagateDownward(name, value, false);
+ } while(false); break SUCCESS; } break; }; break; } case 13: { switch(ccSwitch3.charAt(0)) { case '_': { switch(ccSwitch3.charAt(1)) { case 'D': { switch(ccSwitch3.charAt(2)) { case 'o': { switch(ccSwitch3.charAt(3)) { case 'u': { switch(ccSwitch3.charAt(4)) { case 'b': { switch(ccSwitch3.charAt(5)) { case 'l': { switch(ccSwitch3.charAt(6)) { case 'e': { switch(ccSwitch3.charAt(7)) { case 'C': { switch(ccSwitch3.charAt(8)) { case 'l': { switch(ccSwitch3.charAt(9)) { case 'i': { switch(ccSwitch3.charAt(10)) { case 'c': { switch(ccSwitch3.charAt(11)) { case 'k': { switch(ccSwitch3.charAt(12)) { case '1': if ("_DoubleClick1".equals(ccSwitch3)) { if (true) do { propagateDownward(name, value, false);
+ } while(false); break SUCCESS; } break; case '2': if ("_DoubleClick2".equals(ccSwitch3)) { if (true) do { propagateDownward(name, value, false);
+ } while(false); break SUCCESS; } break; case '3': if ("_DoubleClick3".equals(ccSwitch3)) { if (true) do { propagateDownward(name, value, false);
+ } while(false); break SUCCESS; } break; } break; } } break; } } break; } } break; } } break; } } break; } } break; } } break; } } break; } } break; } } break; } } break; } }; break; } } /* switch */ super.put(name, value);
+ } while(false); /* OUTER */
+ }
+
+ private String alignToString() {
+ switch(flags & ALIGNS) {
+ case (ALIGN_TOP | ALIGN_LEFT): return "topleft";
+ case (ALIGN_BOTTOM | ALIGN_LEFT): return "bottomleft";
+ case (ALIGN_TOP | ALIGN_RIGHT): return "topright";
+ case (ALIGN_BOTTOM | ALIGN_RIGHT): return "bottomright";
+ case ALIGN_TOP: return "top";
+ case ALIGN_BOTTOM: return "bottom";
+ case ALIGN_LEFT: return "left";
+ case ALIGN_RIGHT: return "right";
+ case 0: return "center";
+ default: throw new Error("invalid alignment flags: " + (flags & ALIGNS));
+ }
+ }
+
+ private void setAlign(Object value) {
+ clear(ALIGNS);
+final String ccSwitch4 = (String)(value); SUCCESS:do { switch(ccSwitch4.length()) {
+case 3: { switch(ccSwitch4.charAt(0)) { case 't': if ("top".equals(ccSwitch4)) { if (true) do { set(ALIGN_TOP);
+ } while(false); break SUCCESS; } break; }; break; } case 4: { switch(ccSwitch4.charAt(0)) { case 'l': if ("left".equals(ccSwitch4)) { if (true) do { set(ALIGN_LEFT);
+ } while(false); break SUCCESS; } break; }; break; } case 5: { switch(ccSwitch4.charAt(0)) { case 'r': if ("right".equals(ccSwitch4)) { if (true) do { set(ALIGN_RIGHT);
+ } while(false); break SUCCESS; } break; }; break; } case 6: { switch(ccSwitch4.charAt(0)) { case 'b': if ("bottom".equals(ccSwitch4)) { if (true) do { set(ALIGN_BOTTOM);
+ } while(false); break SUCCESS; } break; }; break; } case 7: { switch(ccSwitch4.charAt(0)) { case 't': if ("topleft".equals(ccSwitch4)) { if (true) do { set(ALIGN_TOP | ALIGN_LEFT);
+ } while(false); break SUCCESS; } break; }; break; } case 8: { switch(ccSwitch4.charAt(0)) { case 't': if ("topright".equals(ccSwitch4)) { if (true) do { set(ALIGN_TOP | ALIGN_RIGHT);
+ } while(false); break SUCCESS; } break; }; break; } case 10: { switch(ccSwitch4.charAt(0)) { case 'b': if ("bottomleft".equals(ccSwitch4)) { if (true) do { set(ALIGN_BOTTOM | ALIGN_LEFT);
+ } while(false); break SUCCESS; } break; }; break; } case 11: { switch(ccSwitch4.charAt(0)) { case 'b': if ("bottomright".equals(ccSwitch4)) { if (true) do { set(ALIGN_BOTTOM | ALIGN_RIGHT);
+ } while(false); break SUCCESS; } break; }; break; } } /* switch */ JS.log("invalid alignment \"" + value + "\"");
+ } while(false); /* OUTER */
+ }
+
+ private void setCursor(Object value) {
+ if (value == null) { clear(CURSOR); boxToCursor.remove(this); return; }
+ if (value.equals(boxToCursor.get(this))) return;
+ set(CURSOR);
+ boxToCursor.put(this, value);
+ Surface surface = getSurface();
+ if (surface == null) return;
+ String tempcursor = surface.cursor;
+ propagateDownward(null, null, false);
+ if (surface.cursor != tempcursor) surface.syncCursor();
+ }
+
+ private void setFill(Object value) throws JSExn {
+ if (value == null) {
+ if (texture == null && fillcolor == 0) return;
+ texture = null;
+ fillcolor = 0;
+ } else if (value instanceof String) {
+ int newfillcolor = Color.stringToColor((String)value);
+ if (newfillcolor == fillcolor) return;
+ fillcolor = newfillcolor;
+ texture = null;
+ } else if (value instanceof JS) {
+ Picture newtex = Picture.load((JS)value, this);
+ if (texture == newtex) return;
+ texture = newtex;
+ fillcolor = 0;
+ if (texture != null && texture.isLoaded) perform();
+ } else {
+ throw new JSExn("fill must be null, a String, or a stream, not a " + value.getClass());
+ }
+ dirty();
+ }
+
+ /**
+ * Handles events which propagate down the box tree. If obscured
+ * is set, then we merely check for Enter/Leave.
+ */
+ private void propagateDownward(Object name_, Object value, boolean obscured) {
+
+ String name = (String)name_;
+ if (getSurface() == null) return;
+ int x = globalToLocalX(getSurface()._mousex);
+ int y = globalToLocalY(getSurface()._mousey);
+ boolean wasinside = test(MOUSEINSIDE);
+ boolean isinside = test(VISIBLE) && inside(x, y) && !obscured;
+ if (!wasinside && isinside) {
+ set(MOUSEINSIDE);
+ putAndTriggerTrapsAndCatchExceptions("Enter", T);
+ }
+ if (isinside && test(CURSOR)) getSurface().cursor = (String)boxToCursor.get(this);
+ if (wasinside && !isinside) {
+ clear(MOUSEINSIDE);
+ putAndTriggerTrapsAndCatchExceptions("Leave", T);
+ }
+
+ boolean found = false;
+ if (wasinside || isinside)
+ for(Box child = getChild(treeSize() - 1); child != null; child = child.prevSibling()) {
+ boolean save_stop = child.test(STOP_UPWARD_PROPAGATION);
+ Object value2 = value;
+ if (name.equals("_HScroll") || name.equals("_VScroll"))
+ value2 = N(((Number)value).floatValue() * ((float)child.fontSize()) / (float)fontSize());
+ if (obscured || !child.inside(x - child.x, y - child.y)) {
+ child.propagateDownward(name, value2, true);
+ } else try {
+ found = true;
+ child.clear(STOP_UPWARD_PROPAGATION);
+ if (name != null) child.putAndTriggerTrapsAndCatchExceptions(name, value2);
+ else child.propagateDownward(name, value2, obscured);
+ } finally {
+ if (save_stop) child.set(STOP_UPWARD_PROPAGATION); else child.clear(STOP_UPWARD_PROPAGATION);
+ }
+ if (child.inside(x - child.x, y - child.y))
+ if (name != null && name.equals("_Move")) obscured = true;
+ else break;
+ }
+
+ if (!obscured && !found)
+ if ("_Move".equals(name) || name.startsWith("_Release") || wasinside)
+ if (name != null)
+ putAndTriggerTrapsAndCatchExceptions(name.substring(1), value);
+ }
+
+ /** figures out what box in this subtree of the Box owns the pixel at x,y relitave to the Surface */
+ public static Box whoIs(Box cur, int x, int y) {
+
+ if (cur.parent != null) throw new Error("whoIs may only be invoked on the root box of a surface");
+ int globalx = 0;
+ int globaly = 0;
+
+ // WARNING: this method is called from the event-queueing thread -- it may run concurrently with
+ // ANY part of Ibex, and is UNSYNCHRONIZED for performance reasons. BE CAREFUL HERE.
+
+ if (!cur.test(VISIBLE)) return null;
+ if (!cur.inside(x - globalx, y - globaly)) return cur.parent == null ? cur : null;
+ OUTER: while(true) {
+ for(int i=cur.treeSize() - 1; i>=0; i--) {
+ Box child = cur.getChild(i);
+ if (child == null) continue; // since this method is unsynchronized, we have to double-check
+ globalx += child.x;
+ globaly += child.y;
+ if (child.test(VISIBLE) && child.inside(x - globalx, y - globaly)) { cur = child; continue OUTER; }
+ globalx -= child.x;
+ globaly -= child.y;
+ }
+ break;
+ }
+ return cur;
+ }
+
+
+ // Trivial Helper Methods (should be inlined) /////////////////////////////////////////
+
+ void mark_for_repack() { REPACK(); }
+ public Enumeration keys() { throw new Error("you cannot apply for..in to a " + this.getClass().getName()); }
+ public Box getRoot() { return parent == null ? this : parent.getRoot(); }
+ public Surface getSurface() { return Surface.fromBox(getRoot()); }
+ Box nextPackedSibling() { Box b = nextSibling(); return b == null || (b.test(PACKED | VISIBLE)) ? b : b.nextPackedSibling(); }
+ Box firstPackedChild() { Box b = getChild(0); return b == null || (b.test(PACKED | VISIBLE)) ? b : b.nextPackedSibling(); }
+ public int globalToLocalX(int x) { return parent == null ? x : parent.globalToLocalX(x - this.x); }
+ public int globalToLocalY(int y) { return parent == null ? y : parent.globalToLocalY(y - this.y); }
+ public int localToGlobalX(int x) { return parent == null ? x : parent.globalToLocalX(x + this.x); }
+ public int localToGlobalY(int y) { return parent == null ? y : parent.globalToLocalY(y + this.y); }
+
+ static short min(short a, short b) { if (a<b) return a; else return b; }
+ static int min(int a, int b) { if (a<b) return a; else return b; }
+ static float min(float a, float b) { if (a<b) return a; else return b; }
+
+ static short max(short a, short b) { if (a>b) return a; else return b; }
+ static int max(int a, int b) { if (a>b) return a; else return b; }
+ static float max(float a, float b) { if (a>b) return a; else return b; }
+
+ static int min(int a, int b, int c) { if (a<=b && a<=c) return a; else if (b<=c && b<=a) return b; else return c; }
+ static int max(int a, int b, int c) { if (a>=b && a>=c) return a; else if (b>=c && b>=a) return b; else return c; }
+ static int bound(int a, int b, int c) { if (c < b) return c; if (a > b) return a; return b; }
+ final boolean inside(int x, int y) { return test(VISIBLE) && x >= 0 && y >= 0 && x < width && y < height; }
+
+ void set(int mask) { flags |= mask; }
+ void set(int mask, boolean setclear) { if (setclear) set(mask); else clear(mask); }
+ void clear(int mask) { flags &= ~mask; }
+ public boolean test(int mask) { return ((flags & mask) == mask); }
+
+
+ // Tree Handling //////////////////////////////////////////////////////////////////////
+
+ public final int getIndexInParent() { return parent == null ? 0 : parent.indexNode(this); }
+ public final Box nextSibling() { return parent == null ? null : parent.getChild(parent.indexNode(this) + 1); }
+ public final Box prevSibling() { return parent == null ? null : parent.getChild(parent.indexNode(this) - 1); }
+ public final Box getChild(int i) {
+ if (i < 0) return null;
+ if (i >= treeSize()) return null;
+ return (Box)getNode(i);
+ }
+
+ // Tree Manipulation /////////////////////////////////////////////////////////////////////
+
+ public void removeSelf() {
+ if (parent != null) { parent.removeChild(parent.indexNode(this)); return; }
+ Surface surface = Surface.fromBox(this);
+ if (surface != null) surface.dispose(true);
+ }
+
+ /** remove the i^th child */
+ public void removeChild(int i) {
+ Box b = getChild(i);
+ b.RECONSTRAIN();
+ b.dirty();
+ b.clear(MOUSEINSIDE);
+ deleteNode(i);
+ b.parent = null;
+ REPACK();
+ putAndTriggerTrapsAndCatchExceptions("ChildChange", b);
+ }
+
+ public void put(int i, Object value) throws JSExn {
+ if (i < 0) return;
+
+ if (value != null && !(value instanceof Box)) {
+ if (Log.on) JS.warn("attempt to set a numerical property on a box to a non-box");
+ return;
+ }
+
+ if (redirect == null) {
+ if (value == null) putAndTriggerTrapsAndCatchExceptions("ChildChange", getChild(i));
+ else JS.warn("attempt to add/remove children to/from a node with a null redirect");
+
+ } else if (redirect != this) {
+ if (value != null) putAndTriggerTrapsAndCatchExceptions("ChildChange", value);
+ redirect.put(i, value);
+ if (value == null) {
+ Box b = (Box)redirect.get(new Integer(i));
+ if (b != null) putAndTriggerTrapsAndCatchExceptions("ChildChange", b);
+ }
+
+ } else if (value == null) {
+ if (i < 0 || i > treeSize()) return;
+ Box b = getChild(i);
+ removeChild(i);
+ putAndTriggerTrapsAndCatchExceptions("ChildChange", b);
+
+ } else {
+ Box b = (Box)value;
+
+ // check if box being moved is currently target of a redirect
+ for(Box cur = b.parent; cur != null; cur = cur.parent)
+ if (cur.redirect == b) {
+ if (Log.on) JS.warn("attempt to move a box that is the target of a redirect");
+ return;
+ }
+
+ // check for recursive ancestor violation
+ for(Box cur = this; cur != null; cur = cur.parent)
+ if (cur == b) {
+ if (Log.on) JS.warn("attempt to make a node a parent of its own ancestor");
+ if (Log.on) Log.info(this, "box == " + this + " ancestor == " + b);
+ return;
+ }
+
+ if (b.parent != null) b.parent.removeChild(b.parent.indexNode(b));
+ insertNode(i, b);
+ b.parent = this;
+
+ // need both of these in case child was already uncalc'ed
+ b.REPACK();
+ REPACK();
+
+ b.dirty();
+ putAndTriggerTrapsAndCatchExceptions("ChildChange", b);
+ }
+ }
+
+ public void putAndTriggerTrapsAndCatchExceptions(Object name, Object val) {
+ try {
+ putAndTriggerTraps(name, val);
+ } catch (JSExn e) {
+ JS.log("caught js exception while putting to trap \""+name+"\"");
+ JS.log(e);
+ } catch (Exception e) {
+ JS.log("caught exception while putting to trap \""+name+"\"");
+ JS.log(e);
+ }
+ }
+
+}
+
+
+
+
+
+
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.core;
+
+import java.io.*;
+import org.ibex.js.*;
+import org.ibex.util.*;
+import org.ibex.graphics.*;
+import org.ibex.plat.*;
+import org.ibex.net.*;
+import org.ibex.crypto.*;
+
+/** Singleton class that provides all functionality in the ibex.* namespace */
+public final class Ibex extends JS.Cloneable {
+
+ // FIXME remove this
+ private final JS rr;
+
+ public Ibex(Stream rr) { this.rr = bless(rr); }
+
+ public JS resolveString(String str, boolean permitAbsolute) throws JSExn {
+ if (str.indexOf("://") != -1) {
+ if (permitAbsolute) return (Stream)url2res(str);
+ throw new JSExn("absolute URL " + str + " not permitted here");
+ }
+ // root-relative
+ //JS ret = (JS)getAndTriggerTraps("");
+ //FIXME
+ JS ret = rr;
+ while(str.indexOf('.') != -1) {
+ String path = str.substring(0, str.indexOf('.'));
+ str = str.substring(str.indexOf('.') + 1);
+ ret = (JS)ret.get(path);
+ }
+ if (!"".equals(str)) ret = (JS)ret.get(str);
+ return ret;
+ }
+
+ /** lets us put multi-level get/put/call keys all in the same method */
+ private class Sub extends JS {
+ String key;
+ Sub(String key) { this.key = key; }
+ public void put(Object key, Object val) throws JSExn { Ibex.this.put(this.key + "." + key, val); }
+ public Object get(Object key) throws JSExn { return Ibex.this.get(this.key + "." + key); }
+ public Object call(Object a0, Object a1, Object a2, Object[] rest, int nargs) throws JSExn {
+ return Ibex.this.callMethod(this.key, a0, a1, a2, rest, nargs);
+ }
+ public Object callMethod(Object method, Object a0, Object a1, Object a2, Object[] rest, int nargs) throws JSExn {
+ return Ibex.this.callMethod(this.key + "." + method, a0, a1, a2, rest, nargs);
+ }
+ }
+ private Cache subCache = new Cache(20);
+ private Sub getSub(String s) {
+ Sub ret = (Sub)subCache.get(s);
+ if (ret == null) subCache.put(s, ret = new Sub(s));
+ return ret;
+ }
+
+ public Object get(Object name) throws JSExn {
+ if (name instanceof String && ((String)name).length() == 0) return rr;
+final String ccSwitch0 = (String)(name); SUCCESS:do { switch(ccSwitch0.length()) {
+case 2: { switch(ccSwitch0.charAt(0)) { case 'u': if ("ui".equals(ccSwitch0)) { if (true) do { return getSub("ui");
+ } while(false); break SUCCESS; } break; }; break; } case 3: { switch(ccSwitch0.charAt(0)) { case 'b': if ("box".equals(ccSwitch0)) { if (true) do { return new Box();
+ } while(false); break SUCCESS; } break; case 'l': if ("log".equals(ccSwitch0)) { if (true) do { return getSub("log");
+ } while(false); break SUCCESS; } break; case 'n': if ("net".equals(ccSwitch0)) { if (true) do { return getSub("net");
+ } while(false); break SUCCESS; } break; }; break; } case 4: { switch(ccSwitch0.charAt(0)) { case 'd': if ("date".equals(ccSwitch0)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 'm': if ("math".equals(ccSwitch0)) { if (true) do { return ibexMath;
+ } while(false); break SUCCESS; } break; }; break; } case 5: { switch(ccSwitch0.charAt(0)) { case 'b': if ("bless".equals(ccSwitch0)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 'c': if ("clone".equals(ccSwitch0)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; }; break; } case 6: { switch(ccSwitch0.charAt(0)) { case 'c': if ("crypto".equals(ccSwitch0)) { if (true) do { return getSub("crypto");
+ } while(false); break SUCCESS; } break; case 'r': if ("regexp".equals(ccSwitch0)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 's': { switch(ccSwitch0.charAt(1)) { case 't': { switch(ccSwitch0.charAt(2)) { case 'r': { switch(ccSwitch0.charAt(3)) { case 'e': if ("stream".equals(ccSwitch0)) { if (true) do { return getSub("stream");
+ } while(false); break SUCCESS; } break; case 'i': if ("string".equals(ccSwitch0)) { if (true) do { return ibexString;
+ } while(false); break SUCCESS; } break; } break; } } break; } } break; } case 't': if ("thread".equals(ccSwitch0)) { if (true) do { return getSub("thread");
+ } while(false); break SUCCESS; } break; case 'u': if ("ui.key".equals(ccSwitch0)) { if (true) do { return getSub("ui.key");
+ } while(false); break SUCCESS; } break; }; break; } case 7: { switch(ccSwitch0.charAt(0)) { case 'n': if ("net.rpc".equals(ccSwitch0)) { if (true) do { return getSub("net.rpc");
+ } while(false); break SUCCESS; } break; case 'u': if ("ui.font".equals(ccSwitch0)) { if (true) do { return getSub("ui.font");
+ } while(false); break SUCCESS; } break; }; break; } case 8: { switch(ccSwitch0.charAt(0)) { case 'l': { switch(ccSwitch0.charAt(1)) { case 'o': { switch(ccSwitch0.charAt(2)) { case 'g': { switch(ccSwitch0.charAt(3)) { case '.': { switch(ccSwitch0.charAt(4)) { case 'i': if ("log.info".equals(ccSwitch0)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 'w': if ("log.warn".equals(ccSwitch0)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; } break; } } break; } } break; } } break; } case 'u': if ("ui.mouse".equals(ccSwitch0)) { if (true) do { return getSub("ui.mouse");
+ } while(false); break SUCCESS; } break; }; break; } case 9: { switch(ccSwitch0.charAt(0)) { case 'l': { switch(ccSwitch0.charAt(1)) { case 'o': { switch(ccSwitch0.charAt(2)) { case 'g': { switch(ccSwitch0.charAt(3)) { case '.': { switch(ccSwitch0.charAt(4)) { case 'd': if ("log.debug".equals(ccSwitch0)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 'e': if ("log.error".equals(ccSwitch0)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; } break; } } break; } } break; } } break; } case 'u': { switch(ccSwitch0.charAt(1)) { case 'i': { switch(ccSwitch0.charAt(2)) { case '.': { switch(ccSwitch0.charAt(3)) { case 'm': if ("ui.maxdim".equals(ccSwitch0)) { if (true) do { return N(Short.MAX_VALUE);
+ } while(false); break SUCCESS; } break; case 's': if ("ui.screen".equals(ccSwitch0)) { if (true) do { return getSub("ui.screen");
+ } while(false); break SUCCESS; } break; } break; } } break; } } break; } }; break; } case 10: { switch(ccSwitch0.charAt(0)) { case 'c': { switch(ccSwitch0.charAt(1)) { case 'r': { switch(ccSwitch0.charAt(2)) { case 'y': { switch(ccSwitch0.charAt(3)) { case 'p': { switch(ccSwitch0.charAt(4)) { case 't': { switch(ccSwitch0.charAt(5)) { case 'o': { switch(ccSwitch0.charAt(6)) { case '.': { switch(ccSwitch0.charAt(7)) { case 'm': if ("crypto.md5".equals(ccSwitch0)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 'r': { switch(ccSwitch0.charAt(8)) { case 'c': if ("crypto.rc4".equals(ccSwitch0)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 's': if ("crypto.rsa".equals(ccSwitch0)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; } break; } } break; } } break; } } break; } } break; } } break; } } break; } } break; } case 's': if ("stream.url".equals(ccSwitch0)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 'u': { switch(ccSwitch0.charAt(1)) { case 'i': { switch(ccSwitch0.charAt(2)) { case '.': { switch(ccSwitch0.charAt(3)) { case 'b': if ("ui.browser".equals(ccSwitch0)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 'k': if ("ui.key.alt".equals(ccSwitch0)) { if (true) do { return Surface.alt ? T : F;
+ } while(false); break SUCCESS; } break; } break; } } break; } } break; } }; break; } case 11: { switch(ccSwitch0.charAt(0)) { case 'c': if ("crypto.sha1".equals(ccSwitch0)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 'n': if ("net.rpc.xml".equals(ccSwitch0)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 'u': if ("ui.key.name".equals(ccSwitch0)) { if (true) do { return getSub("ui.key.name");
+ } while(false); break SUCCESS; } break; }; break; } case 12: { switch(ccSwitch0.charAt(0)) { case 'n': if ("net.rpc.soap".equals(ccSwitch0)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 's': { switch(ccSwitch0.charAt(1)) { case 't': { switch(ccSwitch0.charAt(2)) { case 'r': { switch(ccSwitch0.charAt(3)) { case 'e': { switch(ccSwitch0.charAt(4)) { case 'a': { switch(ccSwitch0.charAt(5)) { case 'm': { switch(ccSwitch0.charAt(6)) { case '.': { switch(ccSwitch0.charAt(7)) { case 'c': if ("stream.cache".equals(ccSwitch0)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 'u': { switch(ccSwitch0.charAt(8)) { case 'n': { switch(ccSwitch0.charAt(9)) { case 'c': if ("stream.uncab".equals(ccSwitch0)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 'z': if ("stream.unzip".equals(ccSwitch0)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; } break; } } break; } case 'w': if ("stream.watch".equals(ccSwitch0)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; } break; } } break; } } break; } } break; } } break; } } break; } } break; } case 't': { switch(ccSwitch0.charAt(1)) { case 'h': { switch(ccSwitch0.charAt(2)) { case 'r': { switch(ccSwitch0.charAt(3)) { case 'e': { switch(ccSwitch0.charAt(4)) { case 'a': { switch(ccSwitch0.charAt(5)) { case 'd': { switch(ccSwitch0.charAt(6)) { case '.': { switch(ccSwitch0.charAt(7)) { case 's': if ("thread.sleep".equals(ccSwitch0)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 'y': if ("thread.yield".equals(ccSwitch0)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; } break; } } break; } } break; } } break; } } break; } } break; } } break; } case 'u': { switch(ccSwitch0.charAt(1)) { case 'i': { switch(ccSwitch0.charAt(2)) { case '.': { switch(ccSwitch0.charAt(3)) { case 'c': if ("ui.clipboard".equals(ccSwitch0)) { if (true) do { return Platform.getClipBoard();
+ } while(false); break SUCCESS; } break; case 'f': if ("ui.font.wait".equals(ccSwitch0)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 'k': if ("ui.key.shift".equals(ccSwitch0)) { if (true) do { return Surface.shift ? T : F;
+ } while(false); break SUCCESS; } break; } break; } } break; } case 'n': if ("undocumented".equals(ccSwitch0)) { if (true) do { return getSub("undocumented");
+ } while(false); break SUCCESS; } break; } break; } }; break; } case 13: { switch(ccSwitch0.charAt(0)) { case 'u': { switch(ccSwitch0.charAt(1)) { case 'i': { switch(ccSwitch0.charAt(2)) { case '.': { switch(ccSwitch0.charAt(3)) { case 'f': { switch(ccSwitch0.charAt(4)) { case 'o': { switch(ccSwitch0.charAt(5)) { case 'n': { switch(ccSwitch0.charAt(6)) { case 't': { switch(ccSwitch0.charAt(7)) { case '.': { switch(ccSwitch0.charAt(8)) { case 's': if ("ui.font.serif".equals(ccSwitch0)) { if (true) do { return Main.builtin.get("fonts/vera/VeraSe.ttf");
+ } while(false); break SUCCESS; } break; case 'w': if ("ui.font.width".equals(ccSwitch0)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; } break; } } break; } } break; } } break; } } break; } } break; } } break; } } break; } }; break; } case 14: { switch(ccSwitch0.charAt(0)) { case 's': { switch(ccSwitch0.charAt(1)) { case 't': { switch(ccSwitch0.charAt(2)) { case 'r': { switch(ccSwitch0.charAt(3)) { case 'e': { switch(ccSwitch0.charAt(4)) { case 'a': { switch(ccSwitch0.charAt(5)) { case 'm': { switch(ccSwitch0.charAt(6)) { case '.': { switch(ccSwitch0.charAt(7)) { case 'h': if ("stream.homedir".equals(ccSwitch0)) { if (true) do { return url2res("file:" + System.getProperty("user.home"));
+ } while(false); break SUCCESS; } break; case 't': if ("stream.tempdir".equals(ccSwitch0)) { if (true) do { return url2res("file:" + System.getProperty("java.io.tempdir"));
+ } while(false); break SUCCESS; } break; } break; } } break; } } break; } } break; } } break; } } break; } } break; } case 'u': { switch(ccSwitch0.charAt(1)) { case 'i': { switch(ccSwitch0.charAt(2)) { case '.': { switch(ccSwitch0.charAt(3)) { case 'f': if ("ui.font.height".equals(ccSwitch0)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 'k': if ("ui.key.control".equals(ccSwitch0)) { if (true) do { return Surface.control ? T : F;
+ } while(false); break SUCCESS; } break; } break; } } break; } } break; } }; break; } case 15: { switch(ccSwitch0.charAt(0)) { case 'u': { switch(ccSwitch0.charAt(1)) { case 'i': { switch(ccSwitch0.charAt(2)) { case '.': { switch(ccSwitch0.charAt(3)) { case 'k': if ("ui.key.name.alt".equals(ccSwitch0)) { if (true) do { return Platform.altKeyName();
+ } while(false); break SUCCESS; } break; case 'm': if ("ui.mouse.button".equals(ccSwitch0)) { if (true) do {
+if (Surface.button1 && !Surface.button2 && !Surface.button3) return N(1);
+else if (!Surface.button1 && Surface.button2 && !Surface.button3) return N(2);
+else if (!Surface.button1 && !Surface.button2 && Surface.button3) return N(3);
+else return ZERO;
+ } while(false); break SUCCESS; } break; case 's': if ("ui.screen.width".equals(ccSwitch0)) { if (true) do { return N(Platform.getScreenWidth());
+ } while(false); break SUCCESS; } break; } break; } } break; } } break; } }; break; } case 16: { switch(ccSwitch0.charAt(0)) { case 's': if ("stream.parse.xml".equals(ccSwitch0)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 'u': if ("ui.screen.height".equals(ccSwitch0)) { if (true) do { return N(Platform.getScreenHeight());
+ } while(false); break SUCCESS; } break; }; break; } case 17: { switch(ccSwitch0.charAt(0)) { case 's': { switch(ccSwitch0.charAt(1)) { case 't': { switch(ccSwitch0.charAt(2)) { case 'r': { switch(ccSwitch0.charAt(3)) { case 'e': { switch(ccSwitch0.charAt(4)) { case 'a': { switch(ccSwitch0.charAt(5)) { case 'm': { switch(ccSwitch0.charAt(6)) { case '.': { switch(ccSwitch0.charAt(7)) { case 'p': { switch(ccSwitch0.charAt(8)) { case 'a': { switch(ccSwitch0.charAt(9)) { case 'r': { switch(ccSwitch0.charAt(10)) { case 's': { switch(ccSwitch0.charAt(11)) { case 'e': { switch(ccSwitch0.charAt(12)) { case '.': { switch(ccSwitch0.charAt(13)) { case 'h': if ("stream.parse.html".equals(ccSwitch0)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 'u': if ("stream.parse.utf8".equals(ccSwitch0)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; } break; } } break; } } break; } } break; } } break; } } break; } } break; } } break; } } break; } } break; } } break; } } break; } } break; } case 'u': { switch(ccSwitch0.charAt(1)) { case 'i': { switch(ccSwitch0.charAt(2)) { case '.': { switch(ccSwitch0.charAt(3)) { case 'f': { switch(ccSwitch0.charAt(4)) { case 'o': { switch(ccSwitch0.charAt(5)) { case 'n': { switch(ccSwitch0.charAt(6)) { case 't': { switch(ccSwitch0.charAt(7)) { case '.': { switch(ccSwitch0.charAt(8)) { case 'm': if ("ui.font.monospace".equals(ccSwitch0)) { if (true) do { return Main.builtin.get("fonts/vera/VeraMono.ttf");
+ } while(false); break SUCCESS; } break; case 's': if ("ui.font.sansserif".equals(ccSwitch0)) { if (true) do { return Main.builtin.get("fonts/vera/Vera.ttf");
+ } while(false); break SUCCESS; } break; } break; } } break; } } break; } } break; } } break; } } break; } } break; } } break; } }; break; } case 26: { switch(ccSwitch0.charAt(0)) { case 'u': if ("undocumented.initialOrigin".equals(ccSwitch0)) { if (true) do { return Main.origin;
+ } while(false); break SUCCESS; } break; }; break; } case 28: { switch(ccSwitch0.charAt(0)) { case 'u': if ("undocumented.initialTemplate".equals(ccSwitch0)) { if (true) do { return Main.initialTemplate;
+ } while(false); break SUCCESS; } break; }; break; } } /* switch */ } while(false); /* OUTER */
+ return super.get(name);
+ }
+
+ public void put(Object name, final Object value) throws JSExn {
+final String ccSwitch1 = (String)(name); SUCCESS:do { switch(ccSwitch1.length()) {
+case 6: { switch(ccSwitch1.charAt(0)) { case 't': if ("thread".equals(ccSwitch1)) { if (true) do { Scheduler.add((Task)value); return;
+ } while(false); break SUCCESS; } break; }; break; } case 8: { switch(ccSwitch1.charAt(0)) { case 'u': if ("ui.frame".equals(ccSwitch1)) { if (true) do { Platform.createSurface((Box)value, true, true); return;
+ } while(false); break SUCCESS; } break; }; break; } case 9: { switch(ccSwitch1.charAt(0)) { case 'u': if ("ui.window".equals(ccSwitch1)) { if (true) do { Platform.createSurface((Box)value, false, true); return;
+ } while(false); break SUCCESS; } break; }; break; } case 12: { switch(ccSwitch1.charAt(0)) { case 'u': if ("ui.clipboard".equals(ccSwitch1)) { if (true) do { Platform.setClipBoard((String)value); return;
+ } while(false); break SUCCESS; } break; }; break; } case 31: { switch(ccSwitch1.charAt(0)) { case 'u': if ("undocumented.proxyAuthorization".equals(ccSwitch1)) { if (true) do {
+HTTP.Proxy.Authorization.authorization = value.toString();
+HTTP.Proxy.Authorization.waitingForUser.release();
+return;
+ } while(false); break SUCCESS; } break; }; break; } } /* switch */ } while(false); /* OUTER */
+ throw new JSExn("attempted to put unknown property: ibex."+name);
+ }
+
+ public Object callMethod(Object name, Object a, Object b, Object c, Object[] rest, int nargs) throws JSExn {
+ try {
+final String ccSwitch2 = (String)(name); SUCCESS:do { switch(ccSwitch2.length()) {
+case 4: { switch(ccSwitch2.charAt(0)) { case 'd': if ("date".equals(ccSwitch2)) { if (true) do { return new JSDate(a, b, c, rest, nargs);
+ } while(false); break SUCCESS; } break; }; break; } case 8: { switch(ccSwitch2.charAt(0)) { case 'l': { switch(ccSwitch2.charAt(1)) { case 'o': { switch(ccSwitch2.charAt(2)) { case 'g': { switch(ccSwitch2.charAt(3)) { case '.': { switch(ccSwitch2.charAt(4)) { case 'i': if ("log.info".equals(ccSwitch2)) { if (true) do { JS.info(a== null ? "**null**" : a.toString()); return null;
+ } while(false); break SUCCESS; } break; case 'w': if ("log.warn".equals(ccSwitch2)) { if (true) do { JS.warn(a== null ? "**null**" : a.toString()); return null;
+ } while(false); break SUCCESS; } break; } break; } } break; } } break; } } break; } }; break; } case 9: { switch(ccSwitch2.charAt(0)) { case 'l': { switch(ccSwitch2.charAt(1)) { case 'o': { switch(ccSwitch2.charAt(2)) { case 'g': { switch(ccSwitch2.charAt(3)) { case '.': { switch(ccSwitch2.charAt(4)) { case 'd': if ("log.debug".equals(ccSwitch2)) { if (true) do { JS.debug(a== null ? "**null**" : a.toString()); return null;
+ } while(false); break SUCCESS; } break; case 'e': if ("log.error".equals(ccSwitch2)) { if (true) do { JS.error(a== null ? "**null**" : a.toString()); return null;
+ } while(false); break SUCCESS; } break; } break; } } break; } } break; } } break; } }; break; } case 12: { switch(ccSwitch2.charAt(0)) { case 'n': if ("net.rpc.soap".equals(ccSwitch2)) { if (true) do { return new SOAP((String)a, "", (String)b, (String)c);
+
+ } while(false); break SUCCESS; } break; }; break; } } /* switch */ } while(false); /* OUTER */
+
+ switch (nargs) {
+ case 0:
+final String ccSwitch3 = (String)(name); SUCCESS:do { switch(ccSwitch3.length()) {
+case 12: { switch(ccSwitch3.charAt(0)) { case 't': if ("thread.yield".equals(ccSwitch3)) { if (true) do { sleep(0); return null;
+ } while(false); break SUCCESS; } break; }; break; } } /* switch */ } while(false); /* OUTER */
+ break;
+ case 1:
+final String ccSwitch4 = (String)(name); SUCCESS:do { switch(ccSwitch4.length()) {
+case 5: { switch(ccSwitch4.charAt(0)) { case 'b': if ("bless".equals(ccSwitch4)) { if (true) do { return bless((JS)a);
+ } while(false); break SUCCESS; } break; case 'c': if ("clone".equals(ccSwitch4)) { if (true) do {
+if (!(a instanceof JS.Cloneable)) throw new JSExn("cannot clone a " + a.getClass().getName());
+return ((JS.Cloneable)a).jsclone();
+ } while(false); break SUCCESS; } break; }; break; } case 6: { switch(ccSwitch4.charAt(0)) { case 'r': if ("regexp".equals(ccSwitch4)) { if (true) do { return new JSRegexp(a, null);
+ } while(false); break SUCCESS; } break; }; break; } case 10: { switch(ccSwitch4.charAt(0)) { case 'c': { switch(ccSwitch4.charAt(1)) { case 'r': { switch(ccSwitch4.charAt(2)) { case 'y': { switch(ccSwitch4.charAt(3)) { case 'p': { switch(ccSwitch4.charAt(4)) { case 't': { switch(ccSwitch4.charAt(5)) { case 'o': { switch(ccSwitch4.charAt(6)) { case '.': { switch(ccSwitch4.charAt(7)) { case 'm': if ("crypto.md5".equals(ccSwitch4)) { if (true) do { /* FEATURE */ return null;
+ } while(false); break SUCCESS; } break; case 'r': { switch(ccSwitch4.charAt(8)) { case 'c': if ("crypto.rc4".equals(ccSwitch4)) { if (true) do { /* FEATURE */ return null;
+ } while(false); break SUCCESS; } break; case 's': if ("crypto.rsa".equals(ccSwitch4)) { if (true) do { /* FEATURE */ return null;
+ } while(false); break SUCCESS; } break; } break; } } break; } } break; } } break; } } break; } } break; } } break; } } break; } case 's': if ("stream.url".equals(ccSwitch4)) { if (true) do { {
+String url = (String)a;
+if (url.startsWith("http://")) return new Stream.HTTP(url);
+else if (url.startsWith("https://")) return new Stream.HTTP(url);
+else if (url.startsWith("data:")) return new Stream.ByteArray(Base64.decode(url.substring(5)), null);
+else if (url.startsWith("utf8:")) return new Stream.ByteArray(url.substring(5).getBytes(), null);
+else if (url.startsWith("file:")) {
+
+Platform.fileDialog(url.substring(5), false);
+}
+throw new JSExn("invalid resource specifier " + url);
+}
+ } while(false); break SUCCESS; } break; case 'u': if ("ui.browser".equals(ccSwitch4)) { if (true) do { Platform.newBrowserWindow((String)a); return null;
+ } while(false); break SUCCESS; } break; }; break; } case 11: { switch(ccSwitch4.charAt(0)) { case 'c': if ("crypto.sha1".equals(ccSwitch4)) { if (true) do { /* FEATURE */ return null;
+ } while(false); break SUCCESS; } break; case 'n': if ("net.rpc.xml".equals(ccSwitch4)) { if (true) do { return new XMLRPC((String)a, "");
+ } while(false); break SUCCESS; } break; }; break; } case 12: { switch(ccSwitch4.charAt(0)) { case 's': { switch(ccSwitch4.charAt(1)) { case 't': { switch(ccSwitch4.charAt(2)) { case 'r': { switch(ccSwitch4.charAt(3)) { case 'e': { switch(ccSwitch4.charAt(4)) { case 'a': { switch(ccSwitch4.charAt(5)) { case 'm': { switch(ccSwitch4.charAt(6)) { case '.': { switch(ccSwitch4.charAt(7)) { case 'c': if ("stream.cache".equals(ccSwitch4)) { if (true) do {
+try { return new Stream.CachedStream((Stream)a, "resources", true); }
+catch (Stream.NotCacheableException e) { throw new JSExn("this resource cannot be cached"); }
+ } while(false); break SUCCESS; } break; case 'u': { switch(ccSwitch4.charAt(8)) { case 'n': { switch(ccSwitch4.charAt(9)) { case 'c': if ("stream.uncab".equals(ccSwitch4)) { if (true) do { return new Stream.Cab((Stream)a);
+ } while(false); break SUCCESS; } break; case 'z': if ("stream.unzip".equals(ccSwitch4)) { if (true) do { return new Stream.Zip((Stream)a);
+ } while(false); break SUCCESS; } break; } break; } } break; } } break; } } break; } } break; } } break; } } break; } } break; } } break; } case 't': if ("thread.sleep".equals(ccSwitch4)) { if (true) do { sleep(JS.toInt(a)); return null;
+ } while(false); break SUCCESS; } break; }; break; } case 16: { switch(ccSwitch4.charAt(0)) { case 's': if ("stream.parse.xml".equals(ccSwitch4)) { if (true) do { new XMLHelper((JS)b).doParse((JS)a); return null;
+
+ } while(false); break SUCCESS; } break; }; break; } case 17: { switch(ccSwitch4.charAt(0)) { case 's': { switch(ccSwitch4.charAt(1)) { case 't': { switch(ccSwitch4.charAt(2)) { case 'r': { switch(ccSwitch4.charAt(3)) { case 'e': { switch(ccSwitch4.charAt(4)) { case 'a': { switch(ccSwitch4.charAt(5)) { case 'm': { switch(ccSwitch4.charAt(6)) { case '.': { switch(ccSwitch4.charAt(7)) { case 'p': { switch(ccSwitch4.charAt(8)) { case 'a': { switch(ccSwitch4.charAt(9)) { case 'r': { switch(ccSwitch4.charAt(10)) { case 's': { switch(ccSwitch4.charAt(11)) { case 'e': { switch(ccSwitch4.charAt(12)) { case '.': { switch(ccSwitch4.charAt(13)) { case 'h': if ("stream.parse.html".equals(ccSwitch4)) { if (true) do { throw new JSExn("not implemented yet");
+ } while(false); break SUCCESS; } break; case 'u': if ("stream.parse.utf8".equals(ccSwitch4)) { if (true) do { try { return new String(InputStreamToByteArray.convert(Stream.getInputStream(a))); }
+catch (Exception e) { Log.warn(this, e); }
+ } while(false); break SUCCESS; } break; } break; } } break; } } break; } } break; } } break; } } break; } } break; } } break; } } break; } } break; } } break; } } break; } } break; } }; break; } } /* switch */ } while(false); /* OUTER */
+ break;
+ case 2:
+final String ccSwitch5 = (String)(name); SUCCESS:do { switch(ccSwitch5.length()) {
+case 6: { switch(ccSwitch5.charAt(0)) { case 'r': if ("regexp".equals(ccSwitch5)) { if (true) do { return new JSRegexp(a, b);
+ } while(false); break SUCCESS; } break; }; break; } case 12: { switch(ccSwitch5.charAt(0)) { case 's': if ("stream.watch".equals(ccSwitch5)) { if (true) do { return new Stream.ProgressWatcher((Stream)a, (JS)b);
+ } while(false); break SUCCESS; } break; }; break; } } /* switch */ } while(false); /* OUTER */
+ case 3:
+final String ccSwitch6 = (String)(name); SUCCESS:do { switch(ccSwitch6.length()) {
+case 12: { switch(ccSwitch6.charAt(0)) { case 'u': if ("ui.font.wait".equals(ccSwitch6)) { if (true) do { throw new Error("FIXME: ibex.ui.font.wait not implemented");
+ } while(false); break SUCCESS; } break; }; break; } case 13: { switch(ccSwitch6.charAt(0)) { case 'u': if ("ui.font.width".equals(ccSwitch6)) { if (true) do { return N(Font.getFont((Stream)a, JS.toInt(b)).textwidth((String)c));
+ } while(false); break SUCCESS; } break; }; break; } case 14: { switch(ccSwitch6.charAt(0)) { case 'u': if ("ui.font.height".equals(ccSwitch6)) { if (true) do { return N(Font.getFont((Stream)a, JS.toInt(b)).textheight((String)c));
+ } while(false); break SUCCESS; } break; }; break; } } /* switch */ } while(false); /* OUTER */
+ break;
+ }
+ } catch (RuntimeException e) {
+ // FIXME: maybe JSExn should take a second argument, Exception
+ Log.warn(this, "ibex."+name+"() threw: " + e);
+ throw new JSExn("invalid argument for ibex object method "+name+"()");
+ }
+
+ throw new JSExn("invalid number of arguments ("+nargs+") for ibex object method "+name+"()");
+ }
+
+ public Stream url2res(String url) throws JSExn {
+ if (url.startsWith("http://")) return new Stream.HTTP(url);
+ else if (url.startsWith("https://")) return new Stream.HTTP(url);
+ else if (url.startsWith("data:")) return new Stream.ByteArray(Base64.decode(url.substring(5)), null);
+ else if (url.startsWith("utf8:")) return new Stream.ByteArray(url.substring(5).getBytes(), null);
+ else throw new JSExn("invalid resource specifier " + url);
+ // FIXME support file:// via dialog boxes
+ }
+
+ public static void sleep(final int i) throws JSExn {
+ try {
+ final JS.UnpauseCallback callback = JS.pause();
+ // FEATURE use a single sleeper thread
+ new Thread() { public void run() {
+ try { Thread.sleep(i); } catch (InterruptedException e) { }
+ Scheduler.add(callback);
+ } }.start();
+ } catch (JS.NotPauseableException npe) {
+ throw new JSExn("you cannot sleep or yield in the foreground thread");
+ }
+ }
+
+ public static final JSMath ibexMath = new JSMath() {
+ private JS gs = new JSScope.Global();
+ public Object get(Object key) throws JSExn {
+final String ccSwitch7 = (String)(key); SUCCESS:do { switch(ccSwitch7.length()) {
+case 3: { switch(ccSwitch7.charAt(0)) { case 'N': if ("NaN".equals(ccSwitch7)) { if (true) do { return gs.get("NaN");
+ } while(false); break SUCCESS; } break; }; break; } case 5: { switch(ccSwitch7.charAt(0)) { case 'i': if ("isNaN".equals(ccSwitch7)) { if (true) do { return gs.get("isNaN");
+ } while(false); break SUCCESS; } break; }; break; } case 8: { switch(ccSwitch7.charAt(0)) { case 'I': if ("Infinity".equals(ccSwitch7)) { if (true) do { return gs.get("Infinity");
+ } while(false); break SUCCESS; } break; case 'i': if ("isFinite".equals(ccSwitch7)) { if (true) do { return gs.get("isFinite");
+ } while(false); break SUCCESS; } break; }; break; } } /* switch */ } while(false); /* OUTER */
+ return super.get(key);
+ }
+ };
+
+ public static final JS ibexString = new JS() {
+ private JS gs = new JSScope.Global();
+ public void put(Object key, Object val) { }
+ public Object get(Object key) throws JSExn {
+final String ccSwitch8 = (String)(key); SUCCESS:do { switch(ccSwitch8.length()) {
+case 6: { switch(ccSwitch8.charAt(0)) { case 'e': if ("escape".equals(ccSwitch8)) { if (true) do { return gs.get("escape");
+ } while(false); break SUCCESS; } break; }; break; } case 8: { switch(ccSwitch8.charAt(0)) { case 'p': if ("parseInt".equals(ccSwitch8)) { if (true) do { return gs.get("parseInt");
+ } while(false); break SUCCESS; } break; case 'u': if ("unescape".equals(ccSwitch8)) { if (true) do { return gs.get("unescape");
+ } while(false); break SUCCESS; } break; }; break; } case 9: { switch(ccSwitch8.charAt(0)) { case 'd': if ("decodeURI".equals(ccSwitch8)) { if (true) do { return gs.get("decodeURI");
+ } while(false); break SUCCESS; } break; case 'e': if ("encodeURI".equals(ccSwitch8)) { if (true) do { return gs.get("encodeURI");
+ } while(false); break SUCCESS; } break; }; break; } case 10: { switch(ccSwitch8.charAt(0)) { case 'p': if ("parseFloat".equals(ccSwitch8)) { if (true) do { return gs.get("parseFloat");
+ } while(false); break SUCCESS; } break; }; break; } case 12: { switch(ccSwitch8.charAt(0)) { case 'f': if ("fromCharCode".equals(ccSwitch8)) { if (true) do { return gs.get("stringFromCharCode");
+ } while(false); break SUCCESS; } break; }; break; } case 18: { switch(ccSwitch8.charAt(0)) { case 'd': if ("decodeURIComponent".equals(ccSwitch8)) { if (true) do { return gs.get("decodeURIComponent");
+ } while(false); break SUCCESS; } break; case 'e': if ("encodeURIComponent".equals(ccSwitch8)) { if (true) do { return gs.get("encodeURIComponent");
+ } while(false); break SUCCESS; } break; }; break; } } /* switch */ } while(false); /* OUTER */
+ return null;
+ }
+ };
+
+ private class XMLHelper extends XML {
+ private class Wrapper extends XML.Exn { public JSExn wrapee; public Wrapper(JSExn jse) { super(""); wrapee = jse; } }
+ private JS characters, whitespace, endElement, startElement;
+ public XMLHelper(JS b) throws JSExn {
+ super(BUFFER_SIZE);
+ startElement = (JS)b.getAndTriggerTraps("startElement");
+ endElement = (JS)b.getAndTriggerTraps("endElement");
+ characters = (JS)b.getAndTriggerTraps("characters");
+ whitespace = (JS)b.getAndTriggerTraps("whitespace");
+ }
+
+ public void startElement(XML.Element c) throws XML.Exn { try {
+ JS attrs = new JS();
+ // FIXME attribute URIs? add an additional hash?
+ for(int i=0; i<c.getAttrLen(); i++) attrs.put(c.getAttrKey(i), c.getAttrVal(i));
+ startElement.call(c.getLocalName(), attrs, c.getUri(), null, 3);
+ } catch (JSExn jse) { throw new Wrapper(jse); } }
+
+ public void endElement(XML.Element c) throws XML.Exn { try {
+ endElement.call(c.getLocalName(), c.getUri(), null, null, 2);
+ } catch (JSExn jse) { throw new Wrapper(jse); } }
+
+ public void characters(char[] ch, int start, int length) throws XML.Exn { try {
+ characters.call(new String(ch, start, length), null, null, null, 1);
+ } catch (JSExn jse) { throw new Wrapper(jse); } }
+
+ public void whitespace(char[] ch, int start, int length) throws XML.Exn { try {
+ whitespace.call(new String(ch, start, length), null, null, null, 1);
+ } catch (JSExn jse) { throw new Wrapper(jse); } }
+
+ public void doParse(JS s) throws JSExn {
+ try {
+ parse(new BufferedReader(new InputStreamReader(Stream.getInputStream(s))));
+ } catch (Wrapper e) {
+ throw e.wrapee;
+ } catch (XML.Exn e) {
+ throw new JSExn("error parsing XML: " + e.toString());
+ } catch (IOException e) {
+ if (Log.on) Log.info(this, "IO Exception while reading from file");
+ if (Log.on) Log.info(this, e);
+ throw new JSExn("error reading from Resource");
+ }
+ }
+ }
+
+ // FEATURE: move this into builtin.xwar
+ public Blessing bless(JS b) { return new Ibex.Blessing((JS.Cloneable)b, this, null, null); }
+ public static class Blessing extends JS.Clone {
+ private Ibex ibex;
+ private Template t = null;
+ public Object parentkey = null;
+ public Blessing parent = null;
+ private Hash cache = new Hash();
+ public Blessing(JS.Cloneable clonee, Ibex ibex, Blessing parent, Object parentkey) {
+ super(clonee); this.ibex = ibex; this.parentkey = parentkey; this.parent = parent; }
+ public Object get(Object key) throws JSExn {
+ if (key.equals("")) return ((Object)getStatic());
+ if (cache.get(key) != null) return cache.get(key);
+ Object ret = new Blessing((JS.Cloneable)clonee.get(key), ibex, this, key);
+ cache.put(key, ret);
+ return ret;
+ }
+ public static Blessing getBlessing(Object o) {
+ if (!(o instanceof JS)) return null;
+ JS js = (JS)o;
+ while (js instanceof JS.Clone && !(js instanceof Blessing)) js = ((JS.Clone)js).getClonee();
+ if (!(js instanceof Blessing)) return null;
+ return (Blessing)js;
+ }
+ public InputStream getImage() throws JSExn {
+ try {
+ InputStream in = Stream.getInputStream(this);
+ if (in != null) return in;
+ } catch (IOException e) { /* DELIBERATE */ }
+ String[] exts = new String[] { ".png", ".jpeg", ".gif" };
+ for (int i=0; i < exts.length; i++)
+ try {
+ InputStream in = Stream.getInputStream(parent.get(parentkey + exts[i]));
+ if (in != null) return in;
+ } catch (IOException f) { /* DELIBERATE */ }
+ return null;
+ }
+ public JSScope getStatic() {
+ try {
+ if (t == null) {
+ JS res = (JS) parent.get(parentkey + ".t");
+ t = Template.buildTemplate(res.unclone().toString(), res, ibex);
+ }
+ return t.staticScope;
+ } catch (Exception e) {
+ Log.error(this, e);
+ return null;
+ }
+ }
+ public Object call(Object a, Object b, Object c, Object[] rest, int nargs) throws JSExn {
+ // GROSS hack
+ if (nargs != 1 && nargs != 9999) throw new JSExn("FIXME can only call with one arg");
+ getStatic();
+ if (t == null) throw new JSExn("No such template " + parentkey);
+ if (nargs == 9999) return t;
+ t.apply((Box)a);
+ return a;
+ }
+ }
+
+}
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.core;
+
+import java.io.*;
+import org.ibex.util.*;
+import org.ibex.crypto.*;
+
+/** Manages access to ~/.ibex */
+public class LocalStorage {
+
+ static String ibexDirName = System.getProperty("user.home") + java.io.File.separatorChar + ".ibex";
+
+ static java.io.File ibexDir = null;
+ static java.io.File cacheDir = null;
+
+ static {
+ try {
+ ibexDir = new java.io.File(ibexDirName);
+ if (!ibexDir.mkdirs()) ibexDir = null;
+ try {
+ cacheDir = new java.io.File(ibexDirName + java.io.File.separatorChar + "cache");
+ if (!cacheDir.mkdirs()) cacheDir = null;
+ } catch (Exception e) {
+ Log.warn(LocalStorage.class, "unable to create cache directory " +
+ ibexDirName + java.io.File.separatorChar + "cache");
+ }
+ } catch (Exception e) {
+ Log.warn(LocalStorage.class, "unable to create ibex directory " + ibexDirName);
+ }
+ }
+
+ // FEATURE: we ought to be able to do stuff like sha1-checking and date checking on cached resources
+ public static class Cache {
+
+ private static void delTree(java.io.File f) throws IOException {
+ if (f.isDirectory()) {
+ String[] s = f.list();
+ for(int i=0; i<s.length; i++)
+ delTree(new java.io.File(f.getPath() + java.io.File.separatorChar + s[i]));
+ }
+ f.delete();
+ }
+
+ public static void flush() throws IOException {
+ delTree(cacheDir);
+ cacheDir.mkdirs();
+ }
+
+ public static java.io.File getCacheFileForKey(String key) {
+ // FEATURE: be smarter here
+ return new java.io.File(cacheDir.getPath() + File.separatorChar + new String(Base64.encode(key.getBytes())));
+ }
+
+ }
+}
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.core;
+
+import java.net.*;
+import java.io.*;
+import java.util.*;
+import org.ibex.js.*;
+import org.ibex.util.*;
+import org.ibex.plat.*;
+import org.ibex.graphics.*;
+
+/** Entry point for the Ibex Engine; handles splash screen, initial xwar loading, and argument processing */
+public class Main {
+
+ /**
+ * FEATURE: this should be implemented using self-emulation
+ * Used for security checks. If this is null, it means that only
+ * scripts originating from the local filesystem are loaded in
+ * the engine (maximum permissions). If scripts have been loaded
+ * from multiple locations, this will be 0.0.0.0 (the invalid
+ * IP).
+ */
+ public static java.net.InetAddress originAddr = null;
+ public static String originHost = null;
+ public static String origin = null;
+ public static String initialTemplate = null;
+
+ public static final Stream builtin = new Stream.Zip(new Stream.Builtin());
+
+ public static void printUsage() {
+ System.err.println("Usage: ibex [-lawp] [ url | file | directory ]");
+ System.err.println("");
+ System.err.println(" -l <level> set logging level to { debug, info (default), warn, error, silent }");
+ System.err.println(" -l rpc log all XML-RPC and SOAP conversations");
+ System.err.println(" -l user@host email log to user@host");
+ System.err.println(" -l host:port emit log to TCP socket");
+ System.err.println(" -l <file> write log to a file on disk");
+ System.err.println(" -a check assertions");
+ System.err.println(" -w <window-id> reserved for libibex");
+ System.err.println(" -p dump profiling information [not yet supported]");
+ Runtime.getRuntime().exit(-1);
+ }
+
+ public static void main(String[] args) throws UnknownHostException, JSExn, IOException {
+ int startargs = 0;
+ while (true) {
+ if (startargs > args.length - 1) printUsage();
+ else if (args[startargs].equals("-a")) JS.checkAssertions = true;
+ else if (args[startargs].equals("-l")) {
+ startargs++;
+ StringTokenizer opts = new StringTokenizer(args[startargs], ",");
+ while(opts.hasMoreTokens()) {
+ String opt = opts.nextToken();
+ if (opt.indexOf('@') != -1) Log.email(opt);
+ else if (opt.indexOf(':') != -1)
+ Log.tcp(opt.substring(0, opt.indexOf(':')),
+ Integer.parseInt(opt.substring(opt.indexOf(':') + 1)));
+ else if (opt.equals("debug")) Log.level = Log.DEBUG;
+ else if (opt.equals("info")) Log.level = Log.INFO;
+ else if (opt.equals("warn")) Log.level = Log.WARN;
+ else if (opt.equals("error")) Log.level = Log.ERROR;
+ else if (opt.equals("silent")) Log.level = Log.SILENT;
+ else if (opt.equals("rpc")) Log.rpc = true;
+ else Log.file(opt);
+ }
+ }
+ else break;
+ startargs++;
+ }
+
+ org.ibex.plat.Platform.forceLoad();
+ if (Log.on) for(int i=0; i<args.length; i++) Log.info(Main.class, "argument " + i + ": " + args[i]);
+
+ initialTemplate = args.length > startargs + 1 ? args[startargs + 1] : "main";
+ origin = args[startargs];
+
+ Stream rr;
+ final String startupTemplate;
+ if (origin.startsWith("http://") || origin.startsWith("https://")) {
+ originHost = origin.substring(origin.indexOf('/') + 2);
+ originHost = originHost.substring(0, originHost.indexOf('/') == -1 ? originHost.length() : originHost.indexOf('/'));
+ if (originHost.indexOf('@') != -1) originHost = originHost.substring(originHost.indexOf('@') + 1);
+ originAddr = InetAddress.getByName(originHost);
+ rr = builtin;
+ startupTemplate = "org.ibex.builtin.splash";
+ } else {
+ rr = new Stream.File(origin);
+ if (!new File(origin).isDirectory()) rr = new Stream.Zip(rr);
+ startupTemplate = initialTemplate;
+ }
+
+ if (Log.on) Log.info(Main.class, "loading xwar");
+ final Ibex ibex = new Ibex(rr);
+
+ org.ibex.graphics.Surface.scarImage =
+ Picture.load((Stream)Main.builtin.get("org/ibex/core/builtin/scar.png"),
+ new Task() { public void perform() throws JSExn, UnknownHostException {
+ if (Log.on) Log.info(Main.class, "invoking initial template");
+ ibex.resolveString(startupTemplate, false).call(new Box(), null, null, null, 1);
+ } });
+
+ Scheduler.init();
+ }
+}
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.core;
+
+import java.io.*;
+import java.util.*;
+import org.ibex.js.*;
+import org.ibex.util.*;
+
+/**
+ * Encapsulates a template node (the <template/> element of a
+ * .ibex file, or any child element thereof).
+ *
+ * Note that the Template instance corresponding to the
+ * <template/> node carries all the header information -- hence
+ * some of the instance members are not meaningful on non-root
+ * Template instances. We refer to these non-root instances as
+ * <i>anonymous templates</i>.
+ *
+ * See the Ibex reference for information on the order in which
+ * templates are applied, attributes are put, and scripts are run.
+ */
+public class Template {
+
+ // Instance Members ///////////////////////////////////////////////////////
+
+ String id = null; ///< the id of this box
+ String redirect = null; ///< the id of the redirect target; only meaningful on a root node
+ private String[] keys; ///< keys to be "put" to instances of this template; elements correspond to those of vals
+ private Object[] vals; ///< values to be "put" to instances of this template; elements correspond to those of keys
+ private String[] urikeys;
+ private String[] urivals;
+ private Vec children = new Vec(); ///< during XML parsing, this holds the list of currently-parsed children; null otherwise
+ private JS script = null; ///< the script on this node
+ Template prev;
+ Template prev2;
+ JSScope staticScope = null; ///< the scope in which the static block is executed
+ JS staticObject = null;
+
+
+ // Only used during parsing /////////////////////////////////////////////////////////////////
+
+ private StringBuffer content = null; ///< during XML parsing, this holds partially-read character data; null otherwise
+ private int content_start = 0; ///< line number of the first line of <tt>content</tt>
+ private int startLine = -1; ///< the line number that this element starts on
+ private Ibex ibex;
+
+
+ // Static data/methods ///////////////////////////////////////////////////////////////////
+
+ // for non-root nodes
+ private Template(Template t, int startLine) { prev = t; this.ibex = t.ibex; this.startLine = startLine; }
+ private Template(Ibex ibex) { this.ibex = ibex; }
+
+
+ // Methods to apply templates ////////////////////////////////////////////////////////
+
+
+ /** Applies the template to Box b
+ * @param pboxes a vector of all box parents on which to put $-references
+ * @param ptemplates a vector of the fileNames to recieve private references on the pboxes
+ */
+ public void apply(Box b) throws JSExn {
+ try {
+ apply(b, null);
+ } catch (IOException e) {
+ b.clear(Box.VISIBLE);
+ b.mark_for_repack();
+ Log.warn(this, e);
+ throw new JSExn(e.toString());
+ } catch (JSExn e) {
+ b.clear(Box.VISIBLE);
+ b.mark_for_repack();
+ Log.warn(this, e);
+ throw e;
+ }
+ }
+
+ private void apply(Box b, PerInstantiationScope parentPis) throws JSExn, IOException {
+ if (prev != null) prev.apply(b, null);
+ if (prev2 != null) prev2.apply(b, null);
+
+ // FIXME this dollar stuff is all wrong
+ if (id != null) parentPis.putDollar(id, b);
+
+ PerInstantiationScope pis = new PerInstantiationScope(b, ibex, parentPis, staticObject);
+ for(int i=0; i<urikeys.length; i++) {
+ if (urikeys[i] == null) continue;
+ pis.declare(urikeys[i]);
+ pis.put(urikeys[i], ibex.resolveString(urivals[i], true));
+ }
+
+ // FIXME needs to obey the new application-ordering rules
+ for (int i=0; children != null && i<children.size(); i++) {
+ Box kid = new Box();
+ ((Template)children.elementAt(i)).apply(kid, pis);
+ b.putAndTriggerTraps(b.get("numchildren"), kid);
+ }
+
+ if (script != null) JS.cloneWithNewParentScope(script, pis).call(null, null, null, null, 0);
+
+ Object key, val;
+ for(int i=0; keys != null && i < keys.length; i++) {
+ if (keys[i] == null) continue;
+ key = keys[i];
+ val = vals[i];
+
+ if ("null".equals(val)) val = null;
+
+ if (val != null && val instanceof String && ((String)val).length() > 0) {
+ switch (((String)val).charAt(0)) {
+ case '$':
+ val = pis.get(val);
+ if (val == null) throw new JSExn("unknown box id '"+vals[i]+"' referenced in XML attribute");
+ break;
+ case '.':
+ val = ibex.resolveString(((String)val).substring(1), false);
+ // FIXME: url case
+ // FIXME: should we be resolving all of these in the XML-parsing code?
+ }
+ }
+ b.putAndTriggerTraps(key, val);
+ }
+ }
+
+
+
+ // XML Parsing /////////////////////////////////////////////////////////////////
+
+ public static Template buildTemplate(String sourceName, Object s, Ibex ibex) {
+ try {
+ return new TemplateHelper(sourceName, s, ibex).t;
+ } catch (Exception e) {
+ Log.error(Template.class, e);
+ return null;
+ }
+ }
+
+ /** handles XML parsing; builds a Template tree as it goes */
+ static final class TemplateHelper extends XML {
+
+ String sourceName;
+ private int state = STATE_INITIAL;
+ private static final int STATE_INITIAL = 0;
+ private static final int STATE_IN_ROOT_NODE = 1;
+ private static final int STATE_IN_TEMPLATE_NODE = 2;
+ private static final int STATE_IN_META_NODE = 3;
+
+ StringBuffer static_content = null;
+ int static_content_start = 0;
+ Vec nodeStack = new Vec();
+ Template t = null;
+ int meta = 0;
+ Ibex ibex;
+
+ String initial_uri = "";
+
+ public TemplateHelper(String sourceName, Object s, Ibex ibex) throws XML.Exn, IOException, JSExn {
+ this.sourceName = sourceName;
+ this.ibex = ibex;
+ InputStream is = Stream.getInputStream(s);
+ Ibex.Blessing b = Ibex.Blessing.getBlessing(s).parent;
+ while(b != null) {
+ if(b.parentkey != null) initial_uri = b.parentkey + (initial_uri.equals("") ? "" : "." + initial_uri);
+ b = b.parent;
+ }
+ initial_uri = "";
+ parse(new InputStreamReader(is));
+ JS staticScript = parseScript(static_content, static_content_start);
+ t.staticObject = new JS();
+ t.staticScope = new PerInstantiationScope(null, ibex, null, t.staticObject);
+ if (staticScript != null) JS.cloneWithNewParentScope(staticScript, t.staticScope).call(null, null, null, null, 0);
+ }
+
+ private JS parseScript(StringBuffer content, int content_start) throws IOException {
+ if (content == null) return null;
+ String contentString = content.toString();
+ if (contentString.trim().length() > 0) return JS.fromReader(sourceName, content_start, new StringReader(contentString));
+ return null;
+ }
+
+ public void startElement(XML.Element c) throws XML.Exn {
+ switch(state) {
+ case STATE_IN_META_NODE: { meta++; return; }
+ case STATE_INITIAL:
+ if (!"ibex".equals(c.getLocalName()))
+ throw new XML.Exn("root element was not <ibex>", XML.Exn.SCHEMA, getLine(), getCol());
+ if (c.getAttrLen() != 0)
+ throw new XML.Exn("root element must not have attributes", XML.Exn.SCHEMA, getLine(), getCol());
+ if (c.getUri("ui") == null || "".equals(c.getUri("ui"))) c.addUri("ui", "ibex://ui");
+ if (c.getUri("meta") == null || "".equals(c.getUri("meta"))) c.addUri("meta", "ibex://meta");
+ if (c.getUri("") == null || "".equals(c.getUri(""))) c.addUri("", initial_uri);
+ state = STATE_IN_ROOT_NODE;
+ return;
+ case STATE_IN_ROOT_NODE:
+ if ("ibex://meta".equals(c.getUri())) { state = STATE_IN_META_NODE; meta = 0; return; }
+ state = STATE_IN_TEMPLATE_NODE;
+ t = (t == null) ? new Template(ibex) : new Template(t, getLine());
+ break;
+ case STATE_IN_TEMPLATE_NODE:
+ nodeStack.addElement(t);
+ t = new Template(ibex);
+ break;
+ }
+
+ if (!("ibex://ui".equals(c.getUri()) && "box".equals(c.getLocalName()))) {
+ String tagname = (c.getUri().equals("") ? "" : (c.getUri() + ".")) + c.getLocalName();
+ // GROSS hack
+ try {
+ // GROSSER hack
+ t.prev2 = (Template)t.ibex.resolveString(tagname, false).call(null, null, null, null, 9999);
+ } catch (Exception e) {
+ Log.error(Template.class, e);
+ }
+ }
+
+ Hash urimap = c.getUriMap();
+ t.urikeys = new String[urimap.size()];
+ t.urivals = new String[urimap.size()];
+ Enumeration uriEnumeration = urimap.keys();
+ int ii = 0;
+ while(uriEnumeration.hasMoreElements()) {
+ String key = (String)uriEnumeration.nextElement();
+ String val = (String)urimap.get(key);
+ if (val.equals("ibex://ui")) continue;
+ if (val.equals("ibex://meta")) continue;
+ t.urikeys[ii] = key;
+ if (val.length() > 0 && val.charAt(0) == '.') val = val.substring(1);
+ t.urivals[ii] = val;
+ ii++;
+ }
+
+ Vec keys = new Vec(c.getAttrLen());
+ Vec vals = new Vec(c.getAttrLen());
+
+ // process attributes into Vecs, dealing with any XML Namespaces in the process
+ ATTR: for (int i=0; i < c.getAttrLen(); i++) {
+ if (c.getAttrKey(i).equals("id")) {
+ t.id = c.getAttrVal(i).toString().intern();
+ continue ATTR;
+ }
+
+ // treat value starting with '.' as resource reference
+ String uri = c.getAttrUri(i); if (!uri.equals("")) uri = '.' + uri;
+ keys.addElement(c.getAttrKey(i));
+ vals.addElement((c.getAttrVal(i).startsWith(".") ? uri : "") + c.getAttrVal(i));
+ }
+
+ if (keys.size() == 0) return;
+
+ // sort the attributes lexicographically
+ Vec.sort(keys, vals, new Vec.CompareFunc() { public int compare(Object a, Object b) {
+ return ((String)a).compareTo((String)b);
+ } });
+
+ t.keys = new String[keys.size()];
+ t.vals = new Object[vals.size()];
+ keys.copyInto(t.keys);
+ vals.copyInto(t.vals);
+
+ // convert attributes to appropriate types and intern strings
+ for(int i=0; i<t.keys.length; i++) {
+ t.keys[i] = t.keys[i].intern();
+
+ String valString = t.vals[i].toString();
+
+ if (valString.equals("true")) t.vals[i] = Boolean.TRUE;
+ else if (valString.equals("false")) t.vals[i] = Boolean.FALSE;
+ else if (valString.equals("null")) t.vals[i] = null;
+ else {
+ boolean hasNonNumeral = false;
+ boolean periodUsed = false;
+ for(int j=0; j<valString.length(); j++)
+ if (j == 0 && valString.charAt(j) == '-') {
+ } else if (valString.charAt(j) == '.' && !periodUsed && j != valString.length() - 1) {
+ periodUsed = true;
+ } else if (!Character.isDigit(valString.charAt(j))) {
+ hasNonNumeral = true;
+ break;
+ }
+ if (valString.length() > 0 && !hasNonNumeral) t.vals[i] = new Double(valString);
+ else t.vals[i] = valString.intern();
+ }
+ }
+ }
+
+ public void endElement(XML.Element c) throws XML.Exn, IOException {
+ switch(state) {
+ case STATE_IN_META_NODE: if (--meta < 0) state = STATE_IN_ROOT_NODE; return;
+ case STATE_IN_ROOT_NODE: return;
+ case STATE_IN_TEMPLATE_NODE: {
+ if (t.content != null) { t.script = parseScript(t.content, t.content_start); t.content = null; }
+ if (nodeStack.size() == 0) { state = STATE_IN_ROOT_NODE; return; }
+ Template oldt = t;
+ t = (Template)nodeStack.lastElement();
+ nodeStack.setSize(nodeStack.size() - 1);
+ t.children.addElement(oldt);
+ int oldt_lines = getLine() - oldt.startLine;
+ if (t.content == null) t.content = new StringBuffer();
+ for (int i=0; oldt_lines > i; i++) t.content.append('\n');
+ }
+ }
+ }
+
+ public void characters(char[] ch, int start, int length) throws XML.Exn {
+ for (int i=0; length >i; i++) if (ch[start+i] == '\t')
+ Log.error(Template.class, "tabs are not allowed in Ibex files ("+getLine()+":"+getCol()+")");
+ switch(state) {
+ case STATE_IN_TEMPLATE_NODE:
+ if (t.content == null) {
+ t.content_start = getLine();
+ t.content = new StringBuffer();
+ }
+ t.content.append(ch, start, length);
+ return;
+ case STATE_IN_ROOT_NODE:
+ if (static_content == null) {
+ static_content_start = getLine();
+ static_content = new StringBuffer();
+ }
+ static_content.append(ch, start, length);
+ return;
+ }
+ }
+
+ public void whitespace(char[] ch, int start, int length) throws XML.Exn { }
+ }
+
+ private static class PerInstantiationScope extends JSScope {
+ Ibex ibex = null;
+ PerInstantiationScope parentBoxPis = null;
+ JS myStatic = null;
+ void putDollar(String key, Box target) throws JSExn {
+ if (parentBoxPis != null) parentBoxPis.putDollar(key, target);
+ declare("$" + key);
+ put("$" + key, target);
+ }
+ public PerInstantiationScope(JSScope parentScope, Ibex ibex, PerInstantiationScope parentBoxPis, JS myStatic) {
+ super(parentScope);
+ this.parentBoxPis = parentBoxPis;
+ this.ibex = ibex;
+ this.myStatic = myStatic;
+ }
+ public Object get(Object key) throws JSExn {
+ if (super.has(key)) return super.get(key);
+ if (key.equals("ibex")) return ibex;
+ if (key.equals("")) return ibex.get("");
+ if (key.equals("static")) return myStatic;
+ return super.get(key);
+ }
+ }
+
+}
+
+
--- /dev/null
+// FIXME
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.graphics;
+import java.util.*;
+
+/** an affine transform; all operations are destructive */
+public final class Affine {
+
+ // [ a b e ]
+ // [ c d f ]
+ // [ 0 0 1 ]
+ public float a, b, c, d, e, f;
+
+ Affine(float _a, float _b, float _c, float _d, float _e, float _f) { a = _a; b = _b; c = _c; d = _d; e = _e; f = _f; }
+ public String toString() { return "[ " + a + ", " + b + ", " + c + ", " + d + ", " + e + ", " + f + " ]"; }
+ public Affine copy() { return new Affine(a, b, c, d, e, f); }
+ public static Affine identity() { return new Affine(1, 0, 0, 1, 0, 0); }
+ public static Affine scale(float sx, float sy) { return new Affine(sx, 0, 0, sy, 0, 0); }
+ public static Affine shear(float degrees) {
+ return new Affine(1, 0, (float)Math.tan(degrees * (float)(Math.PI / 180.0)), 1, 0, 0); }
+ public static Affine translate(float tx, float ty) { return new Affine(1, 0, 0, 1, tx, ty); }
+ public static Affine flip(boolean horiz, boolean vert) { return new Affine(horiz ? -1 : 1, 0, 0, vert ? -1 : 1, 0, 0); }
+ public float multiply_px(float x, float y) { return x * a + y * c + e; }
+ public float multiply_py(float x, float y) { return x * b + y * d + f; }
+ public boolean equalsIgnoringTranslation(Affine x) { return a == x.a && b == x.b && c == x.c && d == x.d; }
+
+ public boolean equals(Object o) {
+ if (!(o instanceof Affine)) return false;
+ Affine x = (Affine)o;
+ return a == x.a && b == x.b && c == x.c && d == x.d && e == x.e && f == x.f;
+ }
+
+ public static Affine rotate(float degrees) {
+ float s = (float)Math.sin(degrees * (float)(Math.PI / 180.0));
+ float c = (float)Math.cos(degrees * (float)(Math.PI / 180.0));
+ return new Affine(c, s, -s, c, 0, 0);
+ }
+
+ /** this = this * a */
+ public Affine multiply(Affine A) {
+ float _a = this.a * A.a + this.b * A.c;
+ float _b = this.a * A.b + this.b * A.d;
+ float _c = this.c * A.a + this.d * A.c;
+ float _d = this.c * A.b + this.d * A.d;
+ float _e = this.e * A.a + this.f * A.c + A.e;
+ float _f = this.e * A.b + this.f * A.d + A.f;
+ a = _a; b = _b; c = _c; d = _d; e = _e; f = _f;
+ return this;
+ }
+
+ /** this = a * this */
+ public Affine premultiply(Affine A) {
+ float _a = A.a * this.a + A.b * this.c;
+ float _b = A.a * this.b + A.b * this.d;
+ float _c = A.c * this.a + A.d * this.c;
+ float _d = A.c * this.b + A.d * this.d;
+ float _e = A.e * this.a + A.f * this.c + this.e;
+ float _f = A.e * this.b + A.f * this.d + this.f;
+ a = _a; b = _b; c = _c; d = _d; e = _e; f = _f;
+ return this;
+ }
+
+ public void invert() {
+ float det = 1 / (a * d - b * c);
+ float _a = d * det;
+ float _b = -1 * b * det;
+ float _c = -1 * c * det;
+ float _d = a * det;
+ float _e = -1 * e * a - f * c;
+ float _f = -1 * e * b - f * d;
+ a = _a; b = _b; c = _c; d = _d; e = _e; f = _f;
+ }
+
+ public static Affine parse(String t) {
+ if (t == null) return null;
+ t = t.trim();
+ Affine ret = Affine.identity();
+ while (t.length() > 0) {
+ if (t.startsWith("skewX(")) {
+ // FIXME
+
+ } else if (t.startsWith("shear(")) {
+ // FIXME: nonstandard; remove this
+ ret.multiply(Affine.shear(Float.parseFloat(t.substring(t.indexOf('(') + 1, t.indexOf(')')))));
+
+ } else if (t.startsWith("skewY(")) {
+ // FIXME
+
+ } else if (t.startsWith("rotate(")) {
+ String sub = t.substring(t.indexOf('(') + 1, t.indexOf(')'));
+ if (sub.indexOf(',') != -1) {
+ float angle = Float.parseFloat(sub.substring(0, sub.indexOf(',')));
+ sub = sub.substring(sub.indexOf(',') + 1);
+ float cx = Float.parseFloat(sub.substring(0, sub.indexOf(',')));
+ sub = sub.substring(sub.indexOf(',') + 1);
+ float cy = Float.parseFloat(sub);
+ ret.multiply(Affine.translate(cx, cy));
+ ret.multiply(Affine.rotate(angle));
+ ret.multiply(Affine.translate(-1 * cx, -1 * cy));
+ } else {
+ ret.multiply(Affine.rotate(Float.parseFloat(t.substring(t.indexOf('(') + 1, t.indexOf(')')))));
+ }
+
+ } else if (t.startsWith("translate(")) {
+ String sub = t.substring(t.indexOf('(') + 1, t.indexOf(')'));
+ if (sub.indexOf(',') > -1) {
+ ret.multiply(Affine.translate(Float.parseFloat(t.substring(t.indexOf('(') + 1, t.indexOf(','))),
+ Float.parseFloat(t.substring(t.indexOf(',') + 1, t.indexOf(')')))));
+ } else {
+ ret.multiply(Affine.translate(Float.parseFloat(t.substring(t.indexOf('(') + 1, t.indexOf(','))), 0));
+ }
+
+ } else if (t.startsWith("flip(")) {
+ String which = t.substring(t.indexOf('(') + 1, t.indexOf(')'));
+ ret.multiply(Affine.flip(which.equals("horizontal"), which.equals("vertical")));
+
+ } else if (t.startsWith("scale(")) {
+ String sub = t.substring(t.indexOf('(') + 1, t.indexOf(')'));
+ if (sub.indexOf(',') > -1) {
+ ret.multiply(Affine.scale(Float.parseFloat(t.substring(t.indexOf('(') + 1, t.indexOf(','))),
+ Float.parseFloat(t.substring(t.indexOf(',') + 1, t.indexOf(')')))));
+ } else {
+ ret.multiply(Affine.scale(Float.parseFloat(t.substring(t.indexOf('(') + 1, t.indexOf(','))),
+ Float.parseFloat(t.substring(t.indexOf('(') + 1, t.indexOf(',')))));
+ }
+
+ } else if (t.startsWith("matrix(")) {
+ // FIXME: is this mapped right?
+ float d[] = new float[6];
+ StringTokenizer st = new StringTokenizer(t, ",", false);
+ for(int i=0; i<6; i++)
+ d[i] = Float.parseFloat(st.nextToken());
+ ret.multiply(new Affine(d[0], d[1], d[2], d[3], d[4], d[5]));
+ }
+ t = t.substring(t.indexOf(')') + 1).trim();
+ }
+ return ret;
+ }
+
+}
--- /dev/null
+// Copyright 2002 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.graphics;
+import java.util.*;
+import org.ibex.util.*;
+
+public class Color {
+
+ public static int stringToColor(String s) {
+ // FIXME support three-char strings by doubling digits
+ if (s == null) return 0x00000000;
+ else if (standard.get(s) != null) return 0xFF000000 | org.ibex.js.JS.toInt(standard.get(s));
+ else if (s.length() == 7 && s.charAt(0) == '#') try {
+ // FEATURE alpha
+ return 0xFF000000 |
+ (Integer.parseInt(s.substring(1, 3), 16) << 16) |
+ (Integer.parseInt(s.substring(3, 5), 16) << 8) |
+ Integer.parseInt(s.substring(5, 7), 16);
+ } catch (NumberFormatException e) {
+ Log.info(Color.class, "invalid color " + s);
+ return 0;
+ }
+ else return 0; // FEATURE: error?
+ }
+
+ public static String colorToString(int argb) {
+ if ((argb & 0xFF000000) == 0) return null;
+ String red = Integer.toHexString((argb & 0x00FF0000) >> 16);
+ String green = Integer.toHexString((argb & 0x0000FF00) >> 8);
+ String blue = Integer.toHexString(argb & 0x000000FF);
+ if (red.length() < 2) red = "0" + red;
+ if (blue.length() < 2) blue = "0" + blue;
+ if (green.length() < 2) green = "0" + green;
+ return "#" + red + green + blue;
+ }
+
+ /** Copied verbatim from the SVG specification */
+ private static Hashtable standard = new Hashtable(400);
+ static {
+ standard.put("aliceblue", new Integer((240 << 16) | (248 << 8) | 255));
+ standard.put("antiquewhite", new Integer((250 << 16) | (235 << 8) | 215));
+ standard.put("aqua", new Integer((0 << 16) | (255 << 8) | 255));
+ standard.put("aquamarine", new Integer((127 << 16) | (255 << 8) | 212));
+ standard.put("azure", new Integer((240 << 16) | (255 << 8) | 255));
+ standard.put("beige", new Integer((245 << 16) | (245 << 8) | 220));
+ standard.put("bisque", new Integer((255 << 16) | (228 << 8) | 196));
+ standard.put("black", new Integer((0 << 16) | (0 << 8) | 0));
+ standard.put("blanchedalmond", new Integer((255 << 16) | (235 << 8) | 205));
+ standard.put("blue", new Integer((0 << 16) | (0 << 8) | 255));
+ standard.put("blueviolet", new Integer((138 << 16) | (43 << 8) | 226));
+ standard.put("brown", new Integer((165 << 16) | (42 << 8) | 42));
+ standard.put("burlywood", new Integer((222 << 16) | (184 << 8) | 135));
+ standard.put("cadetblue", new Integer((95 << 16) | (158 << 8) | 160));
+ standard.put("chartreuse", new Integer((127 << 16) | (255 << 8) | 0));
+ standard.put("chocolate", new Integer((210 << 16) | (105 << 8) | 30));
+ standard.put("coral", new Integer((255 << 16) | (127 << 8) | 80));
+ standard.put("cornflowerblue", new Integer((100 << 16) | (149 << 8) | 237));
+ standard.put("cornsilk", new Integer((255 << 16) | (248 << 8) | 220));
+ standard.put("crimson", new Integer((220 << 16) | (20 << 8) | 60));
+ standard.put("cyan", new Integer((0 << 16) | (255 << 8) | 255));
+ standard.put("darkblue", new Integer((0 << 16) | (0 << 8) | 139));
+ standard.put("darkcyan", new Integer((0 << 16) | (139 << 8) | 139));
+ standard.put("darkgoldenrod", new Integer((184 << 16) | (134 << 8) | 11));
+ standard.put("darkgray", new Integer((169 << 16) | (169 << 8) | 169));
+ standard.put("darkgreen", new Integer((0 << 16) | (100 << 8) | 0));
+ standard.put("darkgrey", new Integer((169 << 16) | (169 << 8) | 169));
+ standard.put("darkkhaki", new Integer((189 << 16) | (183 << 8) | 107));
+ standard.put("darkmagenta", new Integer((139 << 16) | (0 << 8) | 139));
+ standard.put("darkolivegreen", new Integer((85 << 16) | (107 << 8) | 47));
+ standard.put("darkorange", new Integer((255 << 16) | (140 << 8) | 0));
+ standard.put("darkorchid", new Integer((153 << 16) | (50 << 8) | 204));
+ standard.put("darkred", new Integer((139 << 16) | (0 << 8) | 0));
+ standard.put("darksalmon", new Integer((233 << 16) | (150 << 8) | 122));
+ standard.put("darkseagreen", new Integer((143 << 16) | (188 << 8) | 143));
+ standard.put("darkslateblue", new Integer((72 << 16) | (61 << 8) | 139));
+ standard.put("darkslategray", new Integer((47 << 16) | (79 << 8) | 79));
+ standard.put("darkslategrey", new Integer((47 << 16) | (79 << 8) | 79));
+ standard.put("darkturquoise", new Integer((0 << 16) | (206 << 8) | 209));
+ standard.put("darkviolet", new Integer((148 << 16) | (0 << 8) | 211));
+ standard.put("deeppink", new Integer((255 << 16) | (20 << 8) | 147));
+ standard.put("deepskyblue", new Integer((0 << 16) | (191 << 8) | 255));
+ standard.put("dimgray", new Integer((105 << 16) | (105 << 8) | 105));
+ standard.put("dimgrey", new Integer((105 << 16) | (105 << 8) | 105));
+ standard.put("dodgerblue", new Integer((30 << 16) | (144 << 8) | 255));
+ standard.put("firebrick", new Integer((178 << 16) | (34 << 8) | 34));
+ standard.put("floralwhite", new Integer((255 << 16) | (250 << 8) | 240));
+ standard.put("forestgreen", new Integer((34 << 16) | (139 << 8) | 34));
+ standard.put("fuchsia", new Integer((255 << 16) | (0 << 8) | 255));
+ standard.put("gainsboro", new Integer((220 << 16) | (220 << 8) | 220));
+ standard.put("ghostwhite", new Integer((248 << 16) | (248 << 8) | 255));
+ standard.put("gold", new Integer((255 << 16) | (215 << 8) | 0));
+ standard.put("goldenrod", new Integer((218 << 16) | (165 << 8) | 32));
+ standard.put("gray", new Integer((128 << 16) | (128 << 8) | 128));
+ standard.put("grey", new Integer((128 << 16) | (128 << 8) | 128));
+ standard.put("green", new Integer((0 << 16) | (128 << 8) | 0));
+ standard.put("greenyellow", new Integer((173 << 16) | (255 << 8) | 47));
+ standard.put("honeydew", new Integer((240 << 16) | (255 << 8) | 240));
+ standard.put("hotpink", new Integer((255 << 16) | (105 << 8) | 180));
+ standard.put("indianred", new Integer((205 << 16) | (92 << 8) | 92));
+ standard.put("indigo", new Integer((75 << 16) | (0 << 8) | 130));
+ standard.put("ivory", new Integer((255 << 16) | (255 << 8) | 240));
+ standard.put("khaki", new Integer((240 << 16) | (230 << 8) | 140));
+ standard.put("lavender", new Integer((230 << 16) | (230 << 8) | 250));
+ standard.put("lavenderblush", new Integer((255 << 16) | (240 << 8) | 245));
+ standard.put("lawngreen", new Integer((124 << 16) | (252 << 8) | 0));
+ standard.put("lemonchiffon", new Integer((255 << 16) | (250 << 8) | 205));
+ standard.put("lightblue", new Integer((173 << 16) | (216 << 8) | 230));
+ standard.put("lightcoral", new Integer((240 << 16) | (128 << 8) | 128));
+ standard.put("lightcyan", new Integer((224 << 16) | (255 << 8) | 255));
+ standard.put("lightgoldenrodyellow", new Integer((250 << 16) | (250 << 8) | 210));
+ standard.put("lightgray", new Integer((211 << 16) | (211 << 8) | 211));
+ standard.put("lightgreen", new Integer((144 << 16) | (238 << 8) | 144));
+ standard.put("lightgrey", new Integer((211 << 16) | (211 << 8) | 211));
+ standard.put("lightpink", new Integer((255 << 16) | (182 << 8) | 193));
+ standard.put("lightsalmon", new Integer((255 << 16) | (160 << 8) | 122));
+ standard.put("lightseagreen", new Integer((32 << 16) | (178 << 8) | 170));
+ standard.put("lightskyblue", new Integer((135 << 16) | (206 << 8) | 250));
+ standard.put("lightslategray", new Integer((119 << 16) | (136 << 8) | 153));
+ standard.put("lightslategrey", new Integer((119 << 16) | (136 << 8) | 153));
+ standard.put("lightsteelblue", new Integer((176 << 16) | (196 << 8) | 222));
+ standard.put("lightyellow", new Integer((255 << 16) | (255 << 8) | 224));
+ standard.put("lime", new Integer((0 << 16) | (255 << 8) | 0));
+ standard.put("limegreen", new Integer((50 << 16) | (205 << 8) | 50));
+ standard.put("linen", new Integer((250 << 16) | (240 << 8) | 230));
+ standard.put("magenta", new Integer((255 << 16) | (0 << 8) | 255));
+ standard.put("maroon", new Integer((128 << 16) | (0 << 8) | 0));
+ standard.put("mediumaquamarine", new Integer((102 << 16) | (205 << 8) | 170));
+ standard.put("mediumblue", new Integer((0 << 16) | (0 << 8) | 205));
+ standard.put("mediumorchid", new Integer((186 << 16) | (85 << 8) | 211));
+ standard.put("mediumpurple", new Integer((147 << 16) | (112 << 8) | 219));
+ standard.put("mediumseagreen", new Integer((60 << 16) | (179 << 8) | 113));
+ standard.put("mediumslateblue", new Integer((123 << 16) | (104 << 8) | 238));
+ standard.put("mediumspringgreen", new Integer((0 << 16) | (250 << 8) | 154));
+ standard.put("mediumturquoise", new Integer((72 << 16) | (209 << 8) | 204));
+ standard.put("mediumvioletred", new Integer((199 << 16) | (21 << 8) | 133));
+ standard.put("midnightblue", new Integer((25 << 16) | (25 << 8) | 112));
+ standard.put("mintcream", new Integer((245 << 16) | (255 << 8) | 250));
+ standard.put("mistyrose", new Integer((255 << 16) | (228 << 8) | 225));
+ standard.put("moccasin", new Integer((255 << 16) | (228 << 8) | 181));
+ standard.put("navajowhite", new Integer((255 << 16) | (222 << 8) | 173));
+ standard.put("navy", new Integer((0 << 16) | (0 << 8) | 128));
+ standard.put("oldlace", new Integer((253 << 16) | (245 << 8) | 230));
+ standard.put("olive", new Integer((128 << 16) | (128 << 8) | 0));
+ standard.put("olivedrab", new Integer((107 << 16) | (142 << 8) | 35));
+ standard.put("orange", new Integer((255 << 16) | (165 << 8) | 0));
+ standard.put("orangered", new Integer((255 << 16) | (69 << 8) | 0));
+ standard.put("orchid", new Integer((218 << 16) | (112 << 8) | 214));
+ standard.put("palegoldenrod", new Integer((238 << 16) | (232 << 8) | 170));
+ standard.put("palegreen", new Integer((152 << 16) | (251 << 8) | 152));
+ standard.put("paleturquoise", new Integer((175 << 16) | (238 << 8) | 238));
+ standard.put("palevioletred", new Integer((219 << 16) | (112 << 8) | 147));
+ standard.put("papayawhip", new Integer((255 << 16) | (239 << 8) | 213));
+ standard.put("peachpuff", new Integer((255 << 16) | (218 << 8) | 185));
+ standard.put("peru", new Integer((205 << 16) | (133 << 8) | 63));
+ standard.put("pink", new Integer((255 << 16) | (192 << 8) | 203));
+ standard.put("plum", new Integer((221 << 16) | (160 << 8) | 221));
+ standard.put("powderblue", new Integer((176 << 16) | (224 << 8) | 230));
+ standard.put("purple", new Integer((128 << 16) | (0 << 8) | 128));
+ standard.put("red", new Integer((255 << 16) | (0 << 8) | 0));
+ standard.put("rosybrown", new Integer((188 << 16) | (143 << 8) | 143));
+ standard.put("royalblue", new Integer((65 << 16) | (105 << 8) | 225));
+ standard.put("saddlebrown", new Integer((139 << 16) | (69 << 8) | 19));
+ standard.put("salmon", new Integer((250 << 16) | (128 << 8) | 114));
+ standard.put("sandybrown", new Integer((244 << 16) | (164 << 8) | 96));
+ standard.put("seagreen", new Integer((46 << 16) | (139 << 8) | 87));
+ standard.put("seashell", new Integer((255 << 16) | (245 << 8) | 238));
+ standard.put("sienna", new Integer((160 << 16) | (82 << 8) | 45));
+ standard.put("silver", new Integer((192 << 16) | (192 << 8) | 192));
+ standard.put("skyblue", new Integer((135 << 16) | (206 << 8) | 235));
+ standard.put("slateblue", new Integer((106 << 16) | (90 << 8) | 205));
+ standard.put("slategray", new Integer((112 << 16) | (128 << 8) | 144));
+ standard.put("slategrey", new Integer((112 << 16) | (128 << 8) | 144));
+ standard.put("snow", new Integer((255 << 16) | (250 << 8) | 250));
+ standard.put("springgreen", new Integer((0 << 16) | (255 << 8) | 127));
+ standard.put("steelblue", new Integer((70 << 16) | (130 << 8) | 180));
+ standard.put("tan", new Integer((210 << 16) | (180 << 8) | 140));
+ standard.put("teal", new Integer((0 << 16) | (128 << 8) | 128));
+ standard.put("thistle", new Integer((216 << 16) | (191 << 8) | 216));
+ standard.put("tomato", new Integer((255 << 16) | (99 << 8) | 71));
+ standard.put("turquoise", new Integer((64 << 16) | (224 << 8) | 208));
+ standard.put("violet", new Integer((238 << 16) | (130 << 8) | 238));
+ standard.put("wheat", new Integer((245 << 16) | (222 << 8) | 179));
+ standard.put("white", new Integer((255 << 16) | (255 << 8) | 255));
+ standard.put("whitesmoke", new Integer((245 << 16) | (245 << 8) | 245));
+ standard.put("yellow", new Integer((255 << 16) | (255 << 8) | 0));
+ standard.put("yellowgreen", new Integer((154 << 16) | (205 << 8) | 50));
+ }
+}
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.graphics;
+import org.ibex.util.*;
+import java.io.*;
+import java.util.Hashtable;
+import org.ibex.js.*;
+import org.xwt.mips.*;
+import org.ibex.plat.*;
+import org.xwt.mips.Runtime;
+
+// FEATURE: this could be cleaner
+/** encapsulates a single font (a set of Glyphs) */
+public class Font {
+
+ private Font(Stream stream, int pointsize) { this.stream = stream; this.pointsize = pointsize; }
+
+ private static boolean glyphRenderingTaskIsScheduled = false;
+
+ public final int pointsize; ///< the size of the font
+ public final Stream stream; ///< the stream from which this font was loaded
+ public int max_ascent; ///< the maximum ascent, in pixels
+ public int max_descent; ///< the maximum descent, in pixels
+ boolean latinCharsPreloaded = false; ///< true if a request to preload ASCII 32-127 has begun
+ public Glyph[] glyphs = new Glyph[65535]; ///< the glyphs that comprise this font
+
+ public abstract static class Glyph {
+ protected Glyph(Font font, char c) { this.font = font; this.c = c; }
+ public final Font font;
+ public final char c;
+ public int baseline; ///< within the alphamask, this is the y-coordinate of the baseline
+ public int advance; ///< amount to increment the x-coordinate
+ public boolean isLoaded = false; ///< true iff the glyph is loaded
+ public int width = -1; ///< the width of the glyph
+ public int height = -1; ///< the height of the glyph
+ public byte[] data = null; ///< the alpha channel samples for this font
+ public String path = null; // FIXME this should be shared across point sizes
+ void render() {
+ if (!isLoaded) try { renderGlyph(this); } catch (IOException e) { Log.info(Font.class, e); }
+ isLoaded = true;
+ }
+ }
+
+
+ // Statics //////////////////////////////////////////////////////////////////////
+
+ static final Hashtable glyphsToBeCached = new Hashtable();
+ static final Hashtable glyphsToBeDisplayed = new Hashtable();
+ private static Cache fontCache = new Cache(100);
+ public static Font getFont(Stream stream, int pointsize) {
+ Font ret = (Font)fontCache.get(stream, new Integer(pointsize));
+ if (ret == null) fontCache.put(stream, new Integer(pointsize), ret = new Font(stream, pointsize));
+ return ret;
+ }
+
+
+ // Methods //////////////////////////////////////////////////////////////////////
+
+ /**
+ * Rasterize the glyphs of <code>text</code>.
+ * @returns <code>(width<<32)|height</code>
+ */
+ public long rasterizeGlyphs(String text, PixelBuffer pb, int textcolor, int x, int y, int cx1, int cy1, int cx2, int cy2) {
+ int width = 0, height = 0;
+ if (!latinCharsPreloaded) { // preload the Latin-1 charset with low priority (we'll probably want it)
+ for(int i=48; i<57; i++) if (glyphs[i]==null) glyphsToBeCached.put(glyphs[i]=Platform.createGlyph(this, (char)i),"");
+ for(int i=32; i<47; i++) if (glyphs[i]==null) glyphsToBeCached.put(glyphs[i]=Platform.createGlyph(this, (char)i),"");
+ for(int i=57; i<128; i++) if (glyphs[i]==null) glyphsToBeCached.put(glyphs[i]=Platform.createGlyph(this, (char)i),"");
+ if (!glyphRenderingTaskIsScheduled) {
+ Scheduler.add(glyphRenderingTask);
+ glyphRenderingTaskIsScheduled = true;
+ }
+ latinCharsPreloaded = true;
+ }
+ for(int i=0; i<text.length(); i++) {
+ final char c = text.charAt(i);
+ Glyph g = glyphs[c];
+ if (g == null) glyphs[c] = g = Platform.createGlyph(this, c);
+ g.render();
+ if (pb != null) pb.drawGlyph(g, x + width, y + g.font.max_ascent - g.baseline, cx1, cy1, cx2, cy2, textcolor);
+ width += g.advance;
+ height = java.lang.Math.max(height, max_ascent + max_descent);
+ }
+ return ((((long)width) << 32) | (long)(height & 0xffffffffL));
+ }
+
+ // FEATURE do we really need to be caching sizes?
+ private static Cache sizeCache = new Cache(1000);
+ public int textwidth(String s) { return (int)((textsize(s) >>> 32) & 0xffffffff); }
+ public int textheight(String s) { return (int)(textsize(s) & 0xffffffffL); }
+ public long textsize(String s) {
+ Long l = (Long)sizeCache.get(s);
+ if (l != null) return ((Long)l).longValue();
+ long ret = rasterizeGlyphs(s, null, 0, 0, 0, 0, 0, 0, 0);
+ sizeCache.put(s, new Long(ret));
+ return ret;
+ }
+
+ static final Task glyphRenderingTask = new Task() { public void perform() {
+ // FIXME: this should be a low-priority task
+ glyphRenderingTaskIsScheduled = false;
+ if (glyphsToBeCached.isEmpty()) return;
+ Glyph g = (Glyph)glyphsToBeCached.keys().nextElement();
+ if (g == null) return;
+ glyphsToBeCached.remove(g);
+ Log.debug(Font.class, "glyphRenderingTask rendering " + g.c + " of " + g.font);
+ g.render();
+ Log.debug(Glyph.class, " done rendering glyph " + g.c);
+ glyphRenderingTaskIsScheduled = true;
+ Scheduler.add(this);
+ } };
+
+
+ // FreeType Interface //////////////////////////////////////////////////////////////////////////////
+
+ // FEATURE: use streams, not memoryfont's
+ // FEATURE: kerning pairs
+ private static final Runtime rt;
+ private static Stream loadedStream;
+ private static int loadedStreamAddr;
+
+ static {
+ try {
+ rt = (Runtime)Class.forName("org.ibex.util.MIPSApps").newInstance();
+ } catch(Exception e) {
+ throw new Error("Error instantiating freetype: " + e);
+ }
+ rt.start(new String[]{"freetype"});
+ rt.execute();
+ rtCheck();
+ }
+
+ private static void rtCheck() { if(rt.getState() != Runtime.PAUSED) throw new Error("Freetype exited " + rt.exitStatus()); }
+
+ private static void loadFontByteStream(Stream res) {
+ if(loadedStream == res) return;
+
+ try {
+ Log.info(Font.class, "loading font " + res);
+ InputStream is = Stream.getInputStream(res);
+ byte[] fontstream = InputStreamToByteArray.convert(is);
+ rt.free(loadedStreamAddr);
+ loadedStreamAddr = rt.xmalloc(fontstream.length);
+ rt.copyout(fontstream, loadedStreamAddr, fontstream.length);
+ if(rt.call("load_font", loadedStreamAddr, fontstream.length) != 0)
+ throw new RuntimeException("load_font failed"); // FEATURE: better error
+ rtCheck();
+ loadedStream = res;
+ } catch (Exception e) {
+ // FEATURE: Better error reporting (thow an exception?)
+ Log.info(Font.class, e);
+ }
+ }
+
+ private static synchronized void renderGlyph(Font.Glyph glyph) throws IOException {
+ try {
+ Log.debug(Font.class, "rasterizing glyph " + glyph.c + " of font " + glyph.font);
+ if (loadedStream != glyph.font.stream) loadFontByteStream(glyph.font.stream);
+
+ long start = System.currentTimeMillis();
+
+ rt.call("render",glyph.c,glyph.font.pointsize);
+ rtCheck();
+
+ glyph.font.max_ascent = rt.getUserInfo(3);
+ glyph.font.max_descent = rt.getUserInfo(4);
+ glyph.baseline = rt.getUserInfo(5);
+ glyph.advance = rt.getUserInfo(6);
+
+ glyph.width = rt.getUserInfo(1);
+ glyph.height = rt.getUserInfo(2);
+
+ glyph.data = new byte[glyph.width * glyph.height];
+ int addr = rt.getUserInfo(0);
+ rt.copyin(addr, glyph.data, glyph.width * glyph.height);
+
+ byte[] path = new byte[rt.getUserInfo(8)];
+ rt.copyin(rt.getUserInfo(7), path, rt.getUserInfo(8));
+ glyph.path = new String(path);
+ glyph.path += " m " + (64 * glyph.advance) + " 0 ";
+
+ glyph.isLoaded = true;
+ } catch (Exception e) {
+ // FEATURE: Better error reporting (thow an exception?)
+ Log.info(Font.class, e);
+ }
+ }
+}
--- /dev/null
+/*
+ * This file was adapted from D J Hagberg's GifDecoder.java
+ *
+ * This software is copyrighted by D. J. Hagberg, Jr., and other parties.
+ * The following terms apply to all files associated with the software
+ * unless explicitly disclaimed in individual files.
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ *
+ * IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
+ * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
+ * DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE
+ * IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
+ * NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
+ * MODIFICATIONS.
+ *
+ * GOVERNMENT USE: If you are acquiring this software on behalf of the
+ * U.S. government, the Government shall have only "Restricted Rights"
+ * in the software and related documentation as defined in the Federal
+ * Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you
+ * are acquiring the software on behalf of the Department of Defense, the
+ * software shall be classified as "Commercial Computer Software" and the
+ * Government shall have only "Restricted Rights" as defined in Clause
+ * 252.227-7013 (c) (1) of DFARs. Notwithstanding the foregoing, the
+ * authors grant the U.S. Government and others acting in its behalf
+ * permission to use and distribute the software in accordance with the
+ * terms specified in this license.
+ *
+ */
+package org.ibex.graphics;
+
+import org.ibex.util.*;
+import java.io.BufferedInputStream;
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+
+/** Converts an InputStream carrying a GIF image into an ARGB int[] */
+public class GIF {
+
+ // Public Methods /////////////////////////////////////////////////////////
+
+ private GIF() { }
+
+ private static Queue instances = new Queue(10);
+
+ public static void load(InputStream is, Picture p) {
+ GIF g = (GIF)instances.remove(false);
+ if (g == null) g = new GIF();
+ try {
+ g._load(is, p);
+ } catch (Exception e) {
+ if (Log.on) Log.info(GIF.class, e);
+ return;
+ }
+ // FIXME: must reset fields
+ // if (instances.size() < 10) instances.append(g);
+ }
+
+ private void _load(InputStream is, Picture p) throws IOException {
+ this.p = p;
+ if (is instanceof BufferedInputStream) _in = (BufferedInputStream)is;
+ else _in = new BufferedInputStream(is);
+ decodeAsBufferedImage(0);
+ p.isLoaded = true;
+ p = null;
+ _in = null;
+ }
+
+
+ /** Decode a particular frame from the GIF file. Frames must be decoded in order, starting with 0. */
+ private void decodeAsBufferedImage(int page) throws IOException, IOException {
+
+ // If the user requested a page already decoded, we cannot go back.
+ if (page <= index ) return;
+
+ // If we just started reading this stream, initialize the global info.
+ if (index < 0 ) {
+ if (!readIntoBuf(6) || _buf[0] != 'G' || _buf[1] != 'I' || _buf[2] != 'F' ||
+ _buf[3] != '8' || !(_buf[4] == '7' || _buf[4] == '9') || _buf[5] != 'a')
+ throw new IOException("Not a GIF8Xa file.");
+ if (!readGlobalImageDescriptor()) throw new IOException("Unable to read GIF header.");
+ }
+
+ // Loop through the blocks in the image.
+ int block_identifier;
+ while (true) {
+ if(!readIntoBuf(1)) throw new IOException("Unexpected EOF(1)");
+ block_identifier = _buf[0];
+ if (block_identifier == ';') throw new IOException("No image data");
+ if (block_identifier == '!') {
+ if (!readExtensionBlock()) throw new IOException("Unexpected EOF(2)");
+ continue;
+ }
+
+ // not a valid start character -- ignore it.
+ if (block_identifier != ',') continue;
+
+ if (!readLocalImageDescriptor()) throw new IOException("Unexpected EOF(3)");
+ p.data = new int[p.width * p.height];
+ readImage();
+
+ // If we did not decode the requested index, need to go on
+ // to the next one (future implementations should consider
+ // caching already-decoded images here to allow for random
+ // access to animated GIF pages).
+ index++;
+ if (index < page) continue;
+
+ // If we did decode the requested index, we can return.
+ break;
+ }
+
+ // Return the image thus-far decoded
+ return;
+ }
+
+ /** Actually read the image data */
+ private void readImage()
+ throws IOException, IOException {
+ int len = p.width;
+ int rows = p.height;
+ int initialCodeSize;
+ int v;
+ int xpos = 0, ypos = 0, pass = 0, i;
+ int prefix[] = new int[(1 << MAX_LWZ_BITS)];
+ int append[] = new int[(1 << MAX_LWZ_BITS)];
+ int stack[] = new int[(1 << MAX_LWZ_BITS)*2];
+ int top_idx;
+ int codeSize, clearCode, inCode, endCode, oldCode, maxCode, code, firstCode;
+
+ // Initialize the decoder
+ if (!readIntoBuf(1)) throw new IOException("Unexpected EOF decoding image");
+ initialCodeSize = _buf[0];
+
+ // Look at the right color map, setting up transparency if called for.
+ int[] cmap = global_color_map;
+ if (hascmap) cmap = color_map;
+ if (trans_idx >= 0) cmap[trans_idx] = 0x00000000;
+
+ /* Initialize the decoder */
+ /* Set values for "special" numbers:
+ * clear code reset the decoder
+ * end code stop decoding
+ * code size size of the next code to retrieve
+ * max code next available table position
+ */
+ clearCode = 1 << initialCodeSize;
+ endCode = clearCode + 1;
+ codeSize = initialCodeSize + 1;
+ maxCode = clearCode + 2;
+ oldCode = -1;
+ firstCode = -1;
+
+ for (i = 0; i < clearCode; i++) append[i] = i;
+ top_idx = 0; // top of stack.
+
+ bitsInWindow = 0;
+ bytes = 0;
+ window = 0L;
+ done = false;
+ c = -1;
+
+ /* Read until we finish the image */
+ ypos = 0;
+ for (i = 0; i < rows; i++) {
+ for (xpos = 0; xpos < len;) {
+
+ if (top_idx == 0) {
+ /* Bummer -- our stack is empty. Now we have to work! */
+ code = getCode(codeSize);
+ if (code < 0) return;
+
+ if (code > maxCode || code == endCode) return;
+ if (code == clearCode) {
+ codeSize = initialCodeSize + 1;
+ maxCode = clearCode + 2;
+ oldCode = -1;
+ continue;
+ }
+
+ // Last pass reset the decoder, so the first code we
+ // see must be a singleton. Seed the stack with it,
+ // and set up the old/first code pointers for
+ // insertion into the string table. We can't just
+ // roll this into the clearCode test above, because
+ // at that point we have not yet read the next code.
+ if (oldCode == -1) {
+ stack[top_idx++] = append[code];
+ oldCode = code;
+ firstCode = code;
+ continue;
+ }
+
+ inCode = code;
+
+ // maxCode is always one bigger than our
+ // highest assigned code. If the code we see
+ // is equal to maxCode, then we are about to
+ // add a new string to the table. ???
+ if (code == maxCode) {
+ stack[top_idx++] = firstCode;
+ code = oldCode;
+ }
+
+ // Populate the stack by tracing the string in the
+ // string table from its tail to its head
+ while (code > clearCode) {
+ stack[top_idx++] = append[code];
+ code = prefix[code];
+ }
+ firstCode = append[code];
+
+ // If there's no more room in our string table, quit.
+ // Otherwise, add a new string to the table
+ if (maxCode >= (1 << MAX_LWZ_BITS)) return;
+
+ // Push the head of the string onto the stack
+ stack[top_idx++] = firstCode;
+
+ // Add a new string to the string table
+ prefix[maxCode] = oldCode;
+ append[maxCode] = firstCode;
+ maxCode++;
+
+ // maxCode tells us the maximum code value we can accept.
+ // If we see that we need more bits to represent it than
+ // we are requesting from the unpacker, we need to increase
+ // the number we ask for.
+ if ((maxCode >= (1 << codeSize)) && (maxCode < (1<<MAX_LWZ_BITS))) codeSize++;
+ oldCode = inCode;
+ }
+
+ // Pop the next color index off the stack
+ v = stack[--top_idx];
+ if (v < 0) return;
+
+ // Finally, we can set a pixel! Joy!
+ p.data[xpos + ypos * p.width] = cmap[v];
+ xpos++;
+ }
+
+ // If interlacing, the next ypos is not just +1
+ if (interlaced) {
+ ypos += _interlaceStep[pass];
+ while (ypos >= rows) {
+ pass++;
+ if (pass > 3) return;
+ ypos = _interlaceStart[pass];
+ }
+ } else ypos++;
+ }
+ return;
+ }
+
+ /** Extract the next compression code from the file. */
+ private int getCode(int code_size) throws IOException {
+ int ret;
+
+ while (bitsInWindow < code_size) {
+ // Not enough bits in our window to cover the request
+ if (done) return -1;
+
+ if (bytes == 0) {
+ // Not enough bytes in our buffer to add to the window
+ bytes = getDataBlock();
+ c = 0;
+ if (bytes <= 0) {
+ done = true;
+ break;
+ }
+ }
+ // Tack another byte onto the window, see if that's enough
+ window += (_buf[c]) << bitsInWindow;
+ ++c;
+ bitsInWindow += 8;
+ bytes--;
+ }
+
+
+ // The next code will always be the last code_size bits of the window
+ ret = ((int)window) & ((1 << code_size) - 1);
+
+ // Shift data in the window to put the next code at the end
+ window >>= code_size;
+ bitsInWindow -= code_size;
+ return ret;
+ }
+
+ /** Read the global image descriptor and optional global color map. Sets global_* variables. */
+ private boolean readGlobalImageDescriptor() throws IOException {
+ int packed;
+ int aspect; // we ignore this.
+ int ofs;
+
+ if (!readIntoBuf(7) ) return false;
+ global_width = _buf[0] | (_buf[1] << 8);
+ global_height = _buf[2] | (_buf[3] << 8);
+ packed = _buf[4];
+ global_bgcolor = _buf[5];
+ aspect = _buf[6];
+ global_cmapsize = 2 << (packed & 0x07);
+ global_hascmap = (packed & GLOBALCOLORMAP) == GLOBALCOLORMAP;
+ global_color_map = null;
+
+ // Read the color map, if we have one.
+ if (global_hascmap) {
+ if (!readColorMap(global_cmapsize,true)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /** Read a local image descriptor and optional local color map. */
+ private boolean readLocalImageDescriptor() throws IOException {
+ int packed;
+
+ if (!readIntoBuf(9) ) return false;
+
+ left = _buf[0] | (_buf[1] << 8);
+ top = _buf[2] | (_buf[3] << 8);
+ p.width = _buf[4] | (_buf[5] << 8);
+ p.height = _buf[6] | (_buf[7] << 8);
+ packed = _buf[8];
+ hascmap = (packed & LOCALCOLORMAP) == LOCALCOLORMAP;
+ cmapsize = 2 << (packed & 0x07);
+ interlaced = (packed & INTERLACE) == INTERLACE;
+ color_map = null;
+
+ // Read the local color table, if there is one.
+ return !(hascmap && !readColorMap(cmapsize,false));
+ }
+
+ /** Read a color map (global or local). */
+ private boolean readColorMap(int nColors, boolean isGlobal)
+ throws IOException {
+ int[] map = new int[nColors];
+ for( int i=0; i < nColors; ++i) {
+ if (!readIntoBuf(3) ) return false;
+ map[i] = (_buf[0] << 16) | (_buf[1] << 8) | _buf[2] | 0xFF000000;
+ }
+ if (isGlobal) global_color_map = map;
+ else color_map = map;
+ return true;
+ }
+
+ /** Read the contents of a GIF89a Graphical Extension Block. */
+ private boolean readExtensionBlock() throws IOException {
+ if (!readIntoBuf(1) ) return false;
+ int label = _buf[0];
+ int count = -1;
+ switch (label) {
+ case 0x01: // Plain Text Extension
+ case 0xff: // Application Extension
+ case 0xfe: // Comment Extension
+ break;
+ case 0xf9: // Graphic Control Extension
+ count = getDataBlock();
+ if (count < 0) return true;
+ // Check for transparency setting.
+ if ((_buf[0] & HASTRANSPARENCY) != 0) trans_idx = _buf[3];
+ else trans_idx = -1;
+ }
+ do { count = getDataBlock(); } while (count > 0);
+ return true;
+ }
+
+ /** Read a block of data from the GIF file. */
+ private int getDataBlock() throws IOException {
+ if (!readIntoBuf(1) ) return -1;
+ int count = _buf[0];
+ if (count != 0) if (!readIntoBuf(count) ) return -1;
+ return count;
+ }
+
+ /** Read the indicated number of bytes into _buf, our instance-wide buffer. */
+ private boolean readIntoBuf(int count) throws IOException {
+ for(int i = 0; i < count; i++) if ((_buf[i] = _in.read()) == -1) return false;
+ return true;
+ }
+
+ // Private Data //////////////////////////////////////////////////////////
+
+ private Picture p;
+
+ // State management stuff
+ private int index = -1;
+ private BufferedInputStream _in = null;
+ private int[] _buf = new int[BUFSIZE];
+
+ // Transparency settings
+ private int trans_idx = -1;
+
+ // Global image descriptor contents
+ private int global_width = 0;
+ private int global_height = 0;
+ private int global_bgcolor = 0;
+ private int global_cmapsize = 0;
+ private boolean global_hascmap = false;
+ private int[] global_color_map = null;
+
+ // Local image descriptor contents
+ private int left = 0;
+ private int top = 0;
+ private int cmapsize = 0;
+ private boolean hascmap = false;
+ private boolean interlaced = false;
+ private int[] color_map = null;
+
+ // Variables used in getCode(...) to track sliding bit-window.
+ private int bytes = 0;
+ private boolean done;
+ private int c;
+ private long window;
+ private int bitsInWindow = 0;
+
+ // Class-wide constants.
+ private static final int INTERLACE = 0x40;
+ private static final int GLOBALCOLORMAP = 0x80;
+ private static final int LOCALCOLORMAP = 0x80;
+ private static final int HASTRANSPARENCY = 0x01;
+ private static final int MAX_LWZ_BITS = 12;
+ private static final int BUFSIZE = 280;
+ private static final int[] _interlaceStep = { 8, 8, 4, 2 };
+ private static final int[] _interlaceStart = { 0, 4, 2, 1 };
+}
+
+
+
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.graphics;
+
+import java.util.*;
+import java.net.*;
+import java.io.*;
+import org.ibex.js.*;
+import org.ibex.util.*;
+
+/*
+ * While entities are limited to a subset of Unicode characters ,
+ * numeric character references can specify any character. Numeric
+ * character references may be given in decimal or hexadecimal, though
+ * browser support is stronger for decimal references. Decimal
+ * references are of the form &#number; while hexadecimal references
+ * take the case-insensitive form &#xnumber;. Examples of numeric
+ * character references include © or © for the copyright
+ * symbol, Α or Α for the Greek capital letter alpha, and
+ * ا or ا for the Arabic letter ALEF.
+ *
+ * http://www.htmlhelp.com/reference/html40/entities/special.html
+ * http://www.htmlhelp.com/reference/html40/entities/symbols.html
+ * http://www.htmlhelp.com/reference/html40/entities/latin1.html
+ */
+
+/**
+ * This class parses an InputStream containing HTML and returns it
+ * as an XWT DOM tree. Each HTML Element is returned as a struct,
+ * with the following members:
+ *
+ * Since HTML may have multiple top level elements (unlike XML),
+ * this class will search all top level elements for one with a tag
+ * name 'html'. If such a node is found, only it is returned. If no
+ * top-level element has the tag name 'html', such a node is
+ * fabricated, and all top level elements become the children of
+ * that node, which is then returned.
+ */
+public class HTML {
+
+ private final static String[] noEndTag =
+ new String[] { "area", "base", "basefont", "br", "col", "frame", "hr", "img",
+ "input", "isindex", "link", "meta", "param" };
+
+ /** we keep a char[] around for use by removeRedundantWhitespace() */
+ private static char[] cbuf = null;
+
+ /** we keep a StringBuffer around for use by removeRedundantWhitespace() */
+ private static StringBuffer sbuf = null;
+
+ /** true iff we have encountered an LI more recently than the last OL/UL */
+ private static boolean withinLI = false;
+
+ public static synchronized JS parseReader(Reader r) throws IOException, JSExn {
+ CharStream cs = new CharStream(r);
+ JS h = new JS();
+
+ withinLI = false;
+ h.put("$name", "html");
+
+ try {
+ while (true) parseBody(cs, h, null);
+ } catch (EOFException e) {
+ // continue until we get an EOFException
+ }
+
+ /* FIXME
+ Object[] ids = h.keys();
+ for(int i=0; i<ids.length; i++) {
+ Object el = h.get((String)ids[i]);
+ if (el instanceof JS && "html".equals(((JS)el).get("$name")))
+ return (JS)el;
+ }
+ */
+ return h;
+ }
+
+ /**
+ * Parses a single element and stores it in <tt>h</tt>. The
+ * CharStream should be positioned immediately <i>after</i> the
+ * open bracket.
+ *
+ * If a close tag not matching this open tag is found, the
+ * tagname on the close tag will be returned in order to
+ * facilitate correcting broken HTML. Otherwise, this returns
+ * null.
+ */
+ private static String parseElement(CharStream cs, JS h) throws IOException, JSExn {
+ // scan element name
+ while(Character.isSpace(cs.peek())) cs.get();
+ String elementName = parseElementName(cs);
+
+ boolean saveWithinLI = withinLI;
+ if (elementName.equals("li")) {
+ if (withinLI) {
+ cs.unread(new char[] { '<', 'l', 'i', ' ' });
+ return "li";
+ } else {
+ withinLI = true;
+ }
+ } else if (elementName.equals("ol") || elementName.equals("ul")) {
+ withinLI = false;
+ }
+
+ h.put("$name", elementName);
+ if (elementName.equals("!--")) {
+ h.put("0", parseComment(cs));
+ h.put("$numchildren", new Integer(0));
+ return null;
+ }
+
+ // scan attributes
+ while (cs.peek() != '>') {
+ String name = parseAttributeName(cs);
+ if (name.equals("")) break;
+ String value = expandEntities(parseAttributeValue(cs));
+ h.put(name, value);
+ }
+
+ // eat the close-angle bracket
+ cs.get();
+
+ // bodyless tags return here
+ for(int i=0; i<noEndTag.length; i++)
+ if (noEndTag[i].equals(elementName))
+ return null;
+
+ // scan body
+ String ret = parseBody(cs, h, elementName);
+ withinLI = saveWithinLI;
+ return ret;
+ }
+
+ /**
+ * Parses the body of an element. The CharStream should be
+ * positioned at the character immediately after the right
+ * bracket closing the start-tag
+ */
+ private static String parseBody(CharStream cs, JS h, String elementName) throws IOException, JSExn {
+ String cdata = "";
+ int length = h.get("$numchildren") == null ? 0 : Integer.parseInt(h.get("$numchildren").toString());
+ while(true) {
+ String closetag = null;
+
+ try {
+ char c = cs.get();
+ if (c != '<') { cdata += c; continue; }
+ String expanded = removeRedundantWhitespace(expandEntities(cdata));
+ if (expanded.length() > 0) {
+ h.put(String.valueOf(length), expanded);
+ h.put("$numchildren", new Integer(++length));
+ }
+ cdata = "";
+
+ } catch (EOFException e) {
+ String expanded = removeRedundantWhitespace(expandEntities(cdata));
+ if (expanded.length() > 0) {
+ h.put(String.valueOf(length), expanded);
+ h.put("$numchildren", new Integer(++length));
+ }
+ throw e;
+ }
+
+ try {
+ // scan subelement
+ if (cs.peek() != '/') {
+ JS kid = new JS();
+ closetag = parseElement(cs, kid);
+ h.put(String.valueOf(length), kid);
+ h.put("$numchildren", new Integer(++length));
+
+ // scan close-tag
+ } else {
+ cs.get(); // drop the slash
+ closetag = parseElementName(cs);
+ while(cs.get() != '>');
+ }
+ } catch (EOFException e) {
+ throw e;
+
+ }
+
+ if (closetag != null)
+ return closetag.equals(elementName) ? null : closetag;
+ }
+ }
+
+ /** Parses an element name and returns it. The CharStream should
+ * be positioned at the first character of the name.
+ */
+ private static String parseElementName(CharStream cs) throws IOException, JSExn {
+ String ret = "";
+ while (cs.peek() != '>' && !Character.isSpace(cs.peek())) ret += cs.get();
+ return ret.toLowerCase();
+ }
+
+ /** Parses an attribute name and returns it. The CharStream should
+ * be positioned at the first character of the name, possibly
+ * with intervening whitespace.
+ */
+ private static String parseAttributeName(CharStream cs) throws IOException, JSExn {
+ while(Character.isSpace(cs.peek())) cs.get();
+ String ret = "";
+ while(!Character.isSpace(cs.peek()) && cs.peek() != '=' && cs.peek() != '>') ret += cs.get();
+ return ret.toLowerCase();
+ }
+
+ /** Parses an attribute value and returns it. The CharStream
+ * should be positioned at the equals sign, possibly with
+ * intervening whitespace.
+ */
+ private static String parseAttributeValue(CharStream cs) throws IOException, JSExn {
+
+ // eat whitespace and equals sign
+ while(Character.isSpace(cs.peek())) cs.get();
+ if (cs.peek() != '=') return "";
+ cs.get();
+ while(Character.isSpace(cs.peek())) cs.get();
+
+ boolean doublequoted = false;
+ boolean singlequoted = false;
+ String ret = "";
+
+ if (cs.peek() == '\"') { doublequoted = true; cs.get(); }
+ else if (cs.peek() == '\'') { singlequoted = true; cs.get(); }
+
+ while(true) {
+ char c = cs.peek();
+ if (!doublequoted && !singlequoted && (Character.isSpace(c) || c == '>')) break;
+ if (singlequoted && c == '\'') { cs.get(); break; }
+ if (doublequoted && c == '\"') { cs.get(); break; }
+ ret += cs.get();
+ }
+ return ret;
+ }
+
+ /** Parses a comment and returns its body. The CharStream should
+ * be positioned immediately after the <!--
+ */
+ private static String parseComment(CharStream cs) throws IOException, JSExn {
+ int dashes = 0;
+ String ret = "";
+ while(true) {
+ char c = cs.get();
+ if (c == '>' && dashes == 2) return ret.substring(0, ret.length() - 2);
+ if (c == '-') dashes++;
+ else dashes = 0;
+ ret += c;
+ }
+ }
+
+ /** Expands all SGML entities in string <tt>s</tt> */
+ public static String expandEntities(String s) throws IOException, JSExn {
+ if (s.indexOf('&') == -1) return s;
+ StringBuffer sb = new StringBuffer();
+ int i=0;
+ int nextamp = 0;
+ while(nextamp != -1) {
+ nextamp = s.indexOf('&', i);
+ sb.append(nextamp == -1 ? s.substring(i) : s.substring(i, nextamp));
+ if (nextamp == -1) break;
+ if (s.regionMatches(nextamp, "&", 0, 5)) {
+ sb.append("&");
+ i = nextamp + 5;
+ } else if (s.regionMatches(nextamp, ">", 0, 4)) {
+ sb.append(">");
+ i = nextamp + 4;
+ } else if (s.regionMatches(nextamp, "<", 0, 4)) {
+ sb.append("<");
+ i = nextamp + 4;
+ } else if (s.regionMatches(nextamp, """, 0, 6)) {
+ sb.append("\"");
+ i = nextamp + 6;
+ } else if (s.regionMatches(nextamp, " ", 0, 6)) {
+ // FEATURE: perhaps we should distinguish this somehow
+ sb.append(" ");
+ i = nextamp + 6;
+ } else {
+ sb.append("&");
+ i = nextamp + 1;
+ }
+ }
+ return sb.toString();
+ }
+
+ /** removes all redundant whitespace */
+ private static String removeRedundantWhitespace(String s) throws JSExn {
+
+ if (s.indexOf(' ') == -1 && s.indexOf('\n') == -1 && s.indexOf('\t') == -1 && s.indexOf('\r') == -1) return s;
+
+ int len = s.length();
+ if (cbuf == null || cbuf.length < len) {
+ cbuf = new char[len * 2];
+ sbuf = new StringBuffer(len * 2);
+ }
+ sbuf.setLength(0);
+ s.getChars(0, len, cbuf, 0);
+
+ int last = 0;
+ boolean lastWasWhitespace = false;
+ for(int i=0; i<len; i++) {
+ boolean lastlast = lastWasWhitespace;
+ switch(cbuf[i]) {
+ case '\n': case '\r': case '\t':
+ cbuf[i] = ' ';
+ case ' ':
+ lastWasWhitespace = true;
+ break;
+ default:
+ lastWasWhitespace = false;
+ break;
+ }
+ if (lastWasWhitespace && lastlast) {
+ if (last != i) sbuf.append(cbuf, last, i - last);
+ last = i+1;
+ }
+ }
+
+ if (last != len) sbuf.append(cbuf, last, len - last);
+ return sbuf.toString().trim();
+ }
+
+ // CharStream /////////////////////////////////////////////////////////////////////
+
+ private static class CharStream extends PushbackReader {
+ public CharStream(Reader r) { super(r, 1024); }
+
+ public char peek() throws IOException {
+ char c = get();
+ unread(c);
+ return c;
+ }
+
+ public char get() throws IOException {
+ int i = read();
+ if (i == -1) throw new EOFException();
+ return (char)i;
+ }
+ }
+
+}
+
--- /dev/null
+/*
+ * This file was adapted from Jason Marshall's PNGImageProducer.java
+ *
+ * Copyright (c) 1997, Jason Marshall. All Rights Reserved
+ *
+ * The author makes no representations or warranties regarding the suitability,
+ * reliability or stability of this code. This code is provided AS IS. The
+ * author shall not be liable for any damages suffered as a result of using,
+ * modifying or redistributing this software or any derivitives thereof.
+ * Permission to use, reproduce, modify and/or (re)distribute this software is
+ * hereby granted.
+ */
+
+package org.ibex.graphics;
+
+import org.ibex.util.*;
+import java.io.*;
+import java.util.Hashtable;
+import java.util.Vector;
+import java.util.Enumeration;
+import java.util.zip.*;
+
+/** Converts an InputStream carrying a PNG image into an ARGB int[] */
+public class PNG {
+
+ public PNG() { }
+
+ private static Queue instances = new Queue(10);
+ private Picture p;
+
+ public static void load(InputStream is, Picture p) {
+ PNG g = (PNG)instances.remove(false);
+ if (g == null) g = new PNG();
+ try {
+ g._load(is, p);
+ p.data = g.data;
+ } catch (Exception e) {
+ if (Log.on) Log.info(PNG.class, e);
+ return;
+ }
+ // FIXME: must reset fields
+ // if (instances.size() < 10) instances.append(g);
+ }
+
+ // Public Methods ///////////////////////////////////////////////////////////////////////////////
+
+ /** process a PNG as an inputstream; returns null if there is an error
+ @param name A string describing the image, to be used when logging errors
+ */
+ private void _load(InputStream is, Picture pic) throws IOException {
+ p = pic;
+ if (is instanceof BufferedInputStream) underlyingStream = (BufferedInputStream)is;
+ else underlyingStream = new BufferedInputStream(is);
+ target_offset = 0;
+ inputStream = new DataInputStream(underlyingStream);
+
+ // consume the header
+ if ((inputStream.read() != 137) || (inputStream.read() != 80) || (inputStream.read() != 78) || (inputStream.read() != 71) ||
+ (inputStream.read() != 13) || (inputStream.read() != 10) || (inputStream.read() != 26) || (inputStream.read() != 10)) {
+ Log.info(this, "PNG: error: input file is not a PNG file");
+ data = p.data = new int[] { };
+ p.width = p.height = 0;
+ return;
+ }
+
+
+ while (!error) {
+ if (needChunkInfo) {
+ chunkLength = inputStream.readInt();
+ chunkType = inputStream.readInt();
+ needChunkInfo = false;
+ }
+
+ // I rewrote this as an if/else to work around a JODE bug with switch() blocks
+ if (chunkType == CHUNK_bKGD) inputStream.skip(chunkLength);
+ else if (chunkType == CHUNK_cHRM) inputStream.skip(chunkLength);
+ else if (chunkType == CHUNK_gAMA) inputStream.skip(chunkLength);
+ else if (chunkType == CHUNK_hIST) inputStream.skip(chunkLength);
+ else if (chunkType == CHUNK_pHYs) inputStream.skip(chunkLength);
+ else if (chunkType == CHUNK_sBIT) inputStream.skip(chunkLength);
+ else if (chunkType == CHUNK_tEXt) inputStream.skip(chunkLength);
+ else if (chunkType == CHUNK_zTXt) inputStream.skip(chunkLength);
+ else if (chunkType == CHUNK_tIME) inputStream.skip(chunkLength);
+ else if (chunkType == CHUNK_IHDR) handleIHDR();
+ else if (chunkType == CHUNK_PLTE) handlePLTE();
+ else if (chunkType == CHUNK_tRNS) handletRNS();
+ else if (chunkType == CHUNK_IDAT) handleIDAT();
+ else if (chunkType == CHUNK_IEND) break;
+ else {
+ System.err.println("unrecognized chunk type " + Integer.toHexString(chunkType) + ". skipping");
+ inputStream.skip(chunkLength);
+ }
+
+ int crc = inputStream.readInt();
+ needChunkInfo = true;
+ }
+ p.isLoaded = true;
+ }
+
+ // Chunk Handlers ///////////////////////////////////////////////////////////////////////
+
+ /** handle data chunk */
+ private void handleIDAT() throws IOException {
+ if (p.width == -1 || p.height == -1) throw new IOException("never got image width/height");
+ switch (depth) {
+ case 1: mask = 0x1; break;
+ case 2: mask = 0x3; break;
+ case 4: mask = 0xf; break;
+ case 8: case 16: mask = 0xff; break;
+ default: mask = 0x0; break;
+ }
+ if (depth < 8) smask = mask << depth;
+ else smask = mask << 8;
+
+ int count = p.width * p.height;
+
+ switch (colorType) {
+ case 0:
+ case 2:
+ case 6:
+ case 4:
+ ipixels = new int[count];
+ pixels = ipixels;
+ break;
+ case 3:
+ bpixels = new byte[count];
+ pixels = bpixels;
+ break;
+ default:
+ throw new IOException("Image has unknown color type");
+ }
+ if (interlaceMethod != 0) multipass = true;
+ readImageData();
+ }
+
+ /** handle header chunk */
+ private void handleIHDR() throws IOException {
+ if (headerFound) throw new IOException("Extraneous IHDR chunk encountered.");
+ if (chunkLength != 13) throw new IOException("IHDR chunk length wrong: " + chunkLength);
+ p.width = inputStream.readInt();
+ p.height = inputStream.readInt();
+ depth = inputStream.read();
+ colorType = inputStream.read();
+ compressionMethod = inputStream.read();
+ filterMethod = inputStream.read();
+ interlaceMethod = inputStream.read();
+ }
+
+ /** handle pallette chunk */
+ private void handlePLTE() throws IOException {
+ if (colorType == 3) {
+ palette = new byte[chunkLength];
+ inputStream.readFully(palette);
+ } else {
+ // Ignore suggested palette
+ inputStream.skip(chunkLength);
+ }
+ }
+
+ /** handle transparency chunk; modifies palette */
+ private void handletRNS() throws IOException {
+ int chunkLen = chunkLength;
+ if (palette == null) {
+ if (Log.on) Log.info(this, "warning: tRNS chunk encountered before pLTE; ignoring alpha channel");
+ inputStream.skip(chunkLength);
+ return;
+ }
+ int len = palette.length;
+ if (colorType == 3) {
+ transparency = true;
+
+ int transLength = len/3;
+ byte[] trans = new byte[transLength];
+ for (int i = 0; i < transLength; i++) trans[i] = (byte) 0xff;
+ inputStream.readFully(trans, 0, chunkLength);
+
+ byte[] newPalette = new byte[len + transLength];
+ for (int i = newPalette.length; i > 0;) {
+ newPalette[--i] = trans[--transLength];
+ newPalette[--i] = palette[--len];
+ newPalette[--i] = palette[--len];
+ newPalette[--i] = palette[--len];
+ }
+ palette = newPalette;
+
+ } else {
+ inputStream.skip(chunkLength);
+ }
+ }
+
+ /// Helper functions for IDAT ///////////////////////////////////////////////////////////////////////////////////////////
+
+ /** Read Image data in off of a compression stream */
+ private void readImageData() throws IOException {
+ InputStream dataStream = new SequenceInputStream(new IDATEnumeration(this));
+ DataInputStream dis = new DataInputStream(new BufferedInputStream(new InflaterInputStream(dataStream, new Inflater())));
+ int bps, filterOffset;
+ switch (colorType) {
+ case 0: case 3: bps = depth; break;
+ case 2: bps = 3 * depth; break;
+ case 4: bps = depth<<1; break;
+ case 6: bps = depth<<2; break;
+ default: throw new IOException("Unknown color type encountered.");
+ }
+
+ filterOffset = (bps + 7) >> 3;
+
+ for (pass = (multipass ? 1 : 0); pass < 8; pass++) {
+ int pass = this.pass;
+ int rInc = rowInc[pass];
+ int cInc = colInc[pass];
+ int sCol = startingCol[pass];
+ int val = (p.width - sCol + cInc - 1) / cInc;
+ int samples = val * filterOffset;
+ int rowSize = (val * bps)>>3;
+ int sRow = startingRow[pass];
+ if (p.height <= sRow || rowSize == 0) continue;
+ int sInc = rInc * p.width;
+ byte inbuf[] = new byte[rowSize];
+ int pix[] = new int[rowSize];
+ int upix[] = null;
+ int temp[] = new int[rowSize];
+ int nextY = sRow; // next Y value and number of rows to report to sendPixels
+ int rows = 0;
+ int rowStart = sRow * p.width;
+
+ for (int y = sRow; y < p.height; y += rInc, rowStart += sInc) {
+ rows += rInc;
+ int rowFilter = dis.read();
+ dis.readFully(inbuf);
+ if (!filterRow(inbuf, pix, upix, rowFilter, filterOffset)) throw new IOException("Unknown filter type: " + rowFilter);
+ insertPixels(pix, rowStart + sCol, samples);
+ if (multipass && (pass < 6)) blockFill(rowStart);
+ upix = pix;
+ pix = temp;
+ temp = upix;
+ }
+ if (!multipass) break;
+ }
+ while(dis.read() != -1) System.err.println("Leftover data encountered.");
+
+ // 24-bit color is our native format
+ if (colorType == 2 || colorType == 6) {
+ data = (int[])pixels;
+ if (colorType == 2) {
+ for(int i=0; i<data.length; i++)
+ data[i] |= 0xFF000000;
+ }
+
+ } else if (colorType == 3) {
+ byte[] pix = (byte[])pixels;
+ data = new int[pix.length];
+ for(int i=0; i<pix.length; i++) {
+ if (transparency) {
+ data[i] =
+ ((palette[4 * (pix[i] & 0xff) + 3] & 0xff) << 24) |
+ ((palette[4 * (pix[i] & 0xff) + 0] & 0xff) << 16) |
+ ((palette[4 * (pix[i] & 0xff) + 1] & 0xff) << 8) |
+ (palette[4 * (pix[i] & 0xff) + 2] & 0xff);
+ } else {
+ data[i] =
+ 0xFF000000 |
+ ((palette[3 * (pix[i] & 0xff) + 0] & 0xff) << 16) |
+ ((palette[3 * (pix[i] & 0xff) + 1] & 0xff) << 8) |
+ (palette[3 * (pix[i] & 0xff) + 2] & 0xff);
+ }
+ }
+
+ } else if (colorType == 0 || colorType == 4) {
+ if (depth == 16) depth = 8;
+ int[] pix = (int[])pixels;
+ data = new int[pix.length];
+ for(int i=0; i<pix.length; i ++) {
+ if (colorType == 0) {
+ int val = (pix[i] & 0xff) << (8 - depth);
+ data[i] =
+ 0xFF000000 |
+ (val << 16) |
+ (val << 8) |
+ val;
+ } else {
+ int alpha = (pix[i] & mask) << (8 - depth);
+ int val = ((pix[i] & smask) >> depth) << (8 - depth);
+ data[i] =
+ (alpha << 24) |
+ (val << 16) |
+ (val << 8) |
+ val;
+ }
+ }
+ }
+
+ }
+
+ private void insertGreyPixels(int pix[], int offset, int samples) {
+ int p = pix[0];
+ int ipix[] = ipixels;
+ int cInc = colInc[pass];
+ int rs = 0;
+
+ if (colorType == 0) {
+ switch (depth) {
+ case 1:
+ for (int j = 0; j < samples; j++, offset += cInc) {
+ if (rs != 0) rs--;
+ else { rs = 7; p = pix[j>>3]; }
+ ipix[offset] = (p>>rs) & 0x1;
+ }
+ break;
+ case 2:
+ for (int j = 0; j < samples; j++, offset += cInc) {
+ if (rs != 0) rs -= 2;
+ else { rs = 6; p = pix[j>>2]; }
+ ipix[offset] = (p>>rs) & 0x3;
+ }
+ break;
+ case 4:
+ for (int j = 0; j < samples; j++, offset += cInc) {
+ if (rs != 0) rs = 0;
+ else { rs = 4; p = pix[j>>1]; }
+ ipix[offset] = (p>>rs) & 0xf;
+ }
+ break;
+ case 8:
+ for (int j = 0; j < samples; offset += cInc) ipix[offset] = (byte) pix[j++];
+ break;
+ case 16:
+ samples = samples<<1;
+ for (int j = 0; j < samples; j += 2, offset += cInc) ipix[offset] = pix[j];
+ break;
+ default: break;
+ }
+ } else if (colorType == 4) {
+ if (depth == 8) {
+ for (int j = 0; j < samples; offset += cInc) ipix[offset] = (pix[j++]<<8) | pix[j++];
+ } else {
+ samples = samples<<1;
+ for (int j = 0; j < samples; j += 2, offset += cInc) ipix[offset] = (pix[j]<<8) | pix[j+=2];
+ }
+ }
+ }
+
+ private void insertPalettedPixels(int pix[], int offset, int samples) {
+ int rs = 0;
+ int p = pix[0];
+ byte bpix[] = bpixels;
+ int cInc = colInc[pass];
+
+ switch (depth) {
+ case 1:
+ for (int j = 0; j < samples; j++, offset += cInc) {
+ if (rs != 0) rs--;
+ else { rs = 7; p = pix[j>>3]; }
+ bpix[offset] = (byte) ((p>>rs) & 0x1);
+ }
+ break;
+ case 2:
+ for (int j = 0; j < samples; j++, offset += cInc) {
+ if (rs != 0) rs -= 2;
+ else { rs = 6; p = pix[j>>2]; }
+ bpix[offset] = (byte) ((p>>rs) & 0x3);
+ }
+ break;
+ case 4:
+ for (int j = 0; j < samples; j++, offset += cInc) {
+ if (rs != 0) rs = 0;
+ else { rs = 4; p = pix[j>>1]; }
+ bpix[offset] = (byte) ((p>>rs) & 0xf);
+ }
+ break;
+ case 8:
+ for (int j = 0; j < samples; j++, offset += cInc) bpix[offset] = (byte) pix[j];
+ break;
+ }
+ }
+
+ private void insertPixels(int pix[], int offset, int samples) {
+ switch (colorType) {
+ case 0:
+ case 4:
+ insertGreyPixels(pix, offset, samples);
+ break;
+ case 2: {
+ int j = 0;
+ int ipix[] = ipixels;
+ int cInc = colInc[pass];
+ if (depth == 8) {
+ for (j = 0; j < samples; offset += cInc)
+ ipix[offset] = (pix[j++]<<16) | (pix[j++]<<8) | pix[j++];
+ } else {
+ samples = samples<<1;
+ for (j = 0; j < samples; j += 2, offset += cInc)
+ ipix[offset] = (pix[j]<<16) | (pix[j+=2]<<8) | pix[j+=2];
+ }
+ break; }
+ case 3:
+ insertPalettedPixels(pix, offset, samples);
+ break;
+ case 6: {
+ int j = 0;
+ int ipix[] = ipixels;
+ int cInc = colInc[pass];
+ if (depth == 8) {
+ for (j = 0; j < samples; offset += cInc) {
+ ipix[offset] = (pix[j++]<<16) | (pix[j++]<<8) | pix[j++] |
+ (pix[j++]<<24);
+ }
+ } else {
+ samples = samples<<1;
+ for (j = 0; j < samples; j += 2, offset += cInc) {
+ ipix[offset] = (pix[j]<<16) | (pix[j+=2]<<8) | pix[j+=2] |
+ (pix[j+=2]<<24);
+ }
+ }
+ break; }
+ default:
+ break;
+ }
+ }
+
+ private void blockFill(int rowStart) {
+ int counter;
+ int dw = p.width;
+ int pass = this.pass;
+ int w = blockWidth[pass];
+ int sCol = startingCol[pass];
+ int cInc = colInc[pass];
+ int wInc = cInc - w;
+ int maxW = rowStart + dw - w;
+ int len;
+ int h = blockHeight[pass];
+ int maxH = rowStart + (dw * h);
+ int startPos = rowStart + sCol;
+ counter = startPos;
+
+ if (colorType == 3) {
+ byte bpix[] = bpixels;
+ byte pixel;
+ len = bpix.length;
+ for (; counter <= maxW;) {
+ int end = counter + w;
+ pixel = bpix[counter++];
+ for (; counter < end; counter++) bpix[counter] = pixel;
+ counter += wInc;
+ }
+ maxW += w;
+ if (counter < maxW)
+ for (pixel = bpix[counter++]; counter < maxW; counter++)
+ bpix[counter] = pixel;
+ if (len < maxH) maxH = len;
+ for (counter = startPos + dw; counter < maxH; counter += dw)
+ System.arraycopy(bpix, startPos, bpix, counter, dw - sCol);
+ } else {
+ int ipix[] = ipixels;
+ int pixel;
+ len = ipix.length;
+ for (; counter <= maxW;) {
+ int end = counter + w;
+ pixel = ipix[counter++];
+ for (; counter < end; counter++)
+ ipix[counter] = pixel;
+ counter += wInc;
+ }
+ maxW += w;
+ if (counter < maxW)
+ for (pixel = ipix[counter++]; counter < maxW; counter++)
+ ipix[counter] = pixel;
+ if (len < maxH) maxH = len;
+ for (counter = startPos + dw; counter < maxH; counter += dw)
+ System.arraycopy(ipix, startPos, ipix, counter, dw - sCol);
+ }
+ }
+
+ private boolean filterRow(byte inbuf[], int pix[], int upix[], int rowFilter, int boff) {
+ int rowWidth = pix.length;
+ switch (rowFilter) {
+ case 0: {
+ for (int x = 0; x < rowWidth; x++) pix[x] = 0xff & inbuf[x];
+ break; }
+ case 1: {
+ int x = 0;
+ for ( ; x < boff; x++) pix[x] = 0xff & inbuf[x];
+ for ( ; x < rowWidth; x++) pix[x] = 0xff & (inbuf[x] + pix[x - boff]);
+ break; }
+ case 2: {
+ if (upix != null) {
+ for (int x = 0; x < rowWidth; x++)
+ pix[x] = 0xff & (upix[x] + inbuf[x]);
+ } else {
+ for (int x = 0; x < rowWidth; x++)
+ pix[x] = 0xff & inbuf[x];
+ }
+ break; }
+ case 3: {
+ if (upix != null) {
+ int x = 0;
+ for ( ; x < boff; x++) {
+ int rval = upix[x];
+ pix[x] = 0xff & ((rval>>1) + inbuf[x]);
+ }
+ for ( ; x < rowWidth; x++) {
+ int rval = upix[x] + pix[x - boff];
+ pix[x] = 0xff & ((rval>>1) + inbuf[x]);
+ }
+ } else {
+ int x = 0;
+ for ( ; x < boff; x++) pix[x] = 0xff & inbuf[x];
+ for ( ; x < rowWidth; x++) {
+ int rval = pix[x - boff];
+ pix[x] = 0xff & ((rval>>1) + inbuf[x]);
+ }
+ }
+ break; }
+ case 4: {
+ if (upix != null) {
+ int x = 0;
+ for ( ; x < boff; x++) pix[x] = 0xff & (upix[x] + inbuf[x]);
+ for ( ; x < rowWidth; x++) {
+ int a, b, c, p, pa, pb, pc, rval;
+ a = pix[x - boff];
+ b = upix[x];
+ c = upix[x - boff];
+ p = a + b - c;
+ pa = p > a ? p - a : a - p;
+ pb = p > b ? p - b : b - p;
+ pc = p > c ? p - c : c - p;
+ if ((pa <= pb) && (pa <= pc)) rval = a;
+ else if (pb <= pc) rval = b;
+ else rval = c;
+ pix[x] = 0xff & (rval + inbuf[x]);
+ }
+ } else {
+ int x = 0;
+ for ( ; x < boff; x++) pix[x] = 0xff & inbuf[x];
+ for ( ; x < rowWidth; x++) {
+ int rval = pix[x - boff];
+ pix[x] = 0xff & (rval + inbuf[x]);
+ }
+ }
+ break; }
+ default: return false;
+ }
+ return true;
+ }
+
+ // Private Data ///////////////////////////////////////////////////////////////////////////////////////
+
+ private int target_offset = 0;
+ private int sigmask = 0xffff;
+ private Object pixels = null;
+ private int ipixels[] = null;
+ private byte bpixels[] = null;
+ private boolean multipass = false;
+ private boolean complete = false;
+ private boolean error = false;
+
+ int[] data = null;
+
+ private InputStream underlyingStream = null;
+ private DataInputStream inputStream = null;
+ private Thread controlThread = null;
+ private boolean infoAvailable = false;
+ private int updateDelay = 750;
+
+ // Image decoding state variables
+ private boolean headerFound = false;
+ private int compressionMethod = -1;
+ private int depth = -1;
+ private int colorType = -1;
+ private int filterMethod = -1;
+ private int interlaceMethod = -1;
+ private int pass = 0;
+ private byte palette[] = null;
+ private int mask = 0x0;
+ private int smask = 0x0;
+ private boolean transparency = false;
+
+ private int chunkLength = 0;
+ private int chunkType = 0;
+ private boolean needChunkInfo = true;
+
+ private static final int CHUNK_bKGD = 0x624B4744; // "bKGD"
+ private static final int CHUNK_cHRM = 0x6348524D; // "cHRM"
+ private static final int CHUNK_gAMA = 0x67414D41; // "gAMA"
+ private static final int CHUNK_hIST = 0x68495354; // "hIST"
+ private static final int CHUNK_IDAT = 0x49444154; // "IDAT"
+ private static final int CHUNK_IEND = 0x49454E44; // "IEND"
+ private static final int CHUNK_IHDR = 0x49484452; // "IHDR"
+ private static final int CHUNK_PLTE = 0x504C5445; // "PLTE"
+ private static final int CHUNK_pHYs = 0x70485973; // "pHYs"
+ private static final int CHUNK_sBIT = 0x73424954; // "sBIT"
+ private static final int CHUNK_tEXt = 0x74455874; // "tEXt"
+ private static final int CHUNK_tIME = 0x74494D45; // "tIME"
+ private static final int CHUNK_tRNS = 0x74524E53; // "tIME"
+ private static final int CHUNK_zTXt = 0x7A545874; // "zTXt"
+
+ private static final int startingRow[] = { 0, 0, 0, 4, 0, 2, 0, 1 };
+ private static final int startingCol[] = { 0, 0, 4, 0, 2, 0, 1, 0 };
+ private static final int rowInc[] = { 1, 8, 8, 8, 4, 4, 2, 2 };
+ private static final int colInc[] = { 1, 8, 8, 4, 4, 2, 2, 1 };
+ private static final int blockHeight[] = { 1, 8, 8, 4, 4, 2, 2, 1 };
+ private static final int blockWidth[] = { 1, 8, 4, 4, 2, 2, 1, 1 };
+
+ // Helper Classes ////////////////////////////////////////////////////////////////////
+
+ private static class MeteredInputStream extends FilterInputStream {
+ int bytesLeft;
+ int marked;
+
+ public MeteredInputStream(InputStream in, int size) {
+ super(in);
+ bytesLeft = size;
+ }
+
+ public final int read() throws IOException {
+ if (bytesLeft > 0) {
+ int val = in.read();
+ if (val != -1) bytesLeft--;
+ return val;
+ }
+ return -1;
+ }
+
+ public final int read(byte b[]) throws IOException {
+ return read(b, 0, b.length);
+ }
+
+ public final int read(byte b[], int off, int len) throws IOException {
+ if (bytesLeft > 0) {
+ len = (len > bytesLeft ? bytesLeft : len);
+ int read = in.read(b, off, len);
+ if (read > 0) bytesLeft -= read;
+ return read;
+ }
+ return -1;
+ }
+
+ public final long skip(long n) throws IOException {
+ n = (n > bytesLeft ? bytesLeft : n);
+ long skipped = in.skip(n);
+ if (skipped > 0) bytesLeft -= skipped;
+ return skipped;
+ }
+
+ public final int available() throws IOException {
+ int n = in.available();
+ return (n > bytesLeft ? bytesLeft : n);
+ }
+
+ public final void close() throws IOException { /* Eat this */ }
+
+ public final void mark(int readlimit) {
+ marked = bytesLeft;
+ in.mark(readlimit);
+ }
+
+ public final void reset() throws IOException {
+ in.reset();
+ bytesLeft = marked;
+ }
+
+ public final boolean markSupported() { return in.markSupported(); }
+ }
+
+ /** Support class, used to eat the IDAT headers dividing up the deflated stream */
+ private static class IDATEnumeration implements Enumeration {
+ InputStream underlyingStream;
+ PNG owner;
+ boolean firstStream = true;
+
+ public IDATEnumeration(PNG owner) {
+ this.owner = owner;
+ this.underlyingStream = owner.underlyingStream;
+ }
+
+ public Object nextElement() {
+ firstStream = false;
+ return new MeteredInputStream(underlyingStream, owner.chunkLength);
+ }
+
+ public boolean hasMoreElements() {
+ DataInputStream dis = new DataInputStream(underlyingStream);
+ if (!firstStream) {
+ try {
+ int crc = dis.readInt();
+ owner.needChunkInfo = false;
+ owner.chunkLength = dis.readInt();
+ owner.chunkType = dis.readInt();
+ } catch (IOException ioe) {
+ return false;
+ }
+ }
+ if (owner.chunkType == PNG.CHUNK_IDAT) return true;
+ return false;
+ }
+ }
+
+}
--- /dev/null
+// FIXME
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.graphics;
+import java.util.*;
+
+public abstract class Paint {
+ public abstract void fillTrapezoid(int tx1, int tx2, int ty1, int tx3, int tx4, int ty2, PixelBuffer buf);
+
+ public static class SingleColorPaint extends Paint {
+ int color;
+ public SingleColorPaint(int color) { this.color = color; }
+ public void fillTrapezoid(int x1, int x2, int y1, int x3, int x4, int y2, PixelBuffer buf) {
+ buf.fillTrapezoid(x1, x2, y1, x3, x4, y2, color);
+ }
+ }
+
+
+ /*
+ public static abstract class GradientPaint extends Paint {
+ public GradientPaint(boolean reflect, boolean repeat, Affine gradientTransform,
+ int[] stop_colors, float[] stop_offsets) {
+ this.reflect = reflect; this.repeat = repeat;
+ this.gradientTransform = gradientTransform;
+ this.stop_colors = stop_colors;
+ this.stop_offsets = stop_offsets;
+ }
+ Affine gradientTransform = Affine.identity();
+ boolean useBoundingBox = false; // FIXME not supported
+ boolean patternUseBoundingBox = false; // FIXME not supported
+
+ // it's invalid for both of these to be true
+ boolean reflect = false; // FIXME not supported
+ boolean repeat = false; // FIXME not supported
+ int[] stop_colors;
+ float[] stop_offsets;
+
+ public void fillTrapezoid(float tx1, float tx2, float ty1, float tx3, float tx4, float ty2, PixelBuffer buf) {
+ Affine a = buf.a;
+ Affine inverse = a.copy().invert();
+ float slope1 = (tx3 - tx1) / (ty2 - ty1);
+ float slope2 = (tx4 - tx2) / (ty2 - ty1);
+ for(float y=ty1; y<ty2; y++) {
+ float _x1 = (y - ty1) * slope1 + tx1;
+ float _x2 = (y - ty1) * slope2 + tx2;
+ if (_x1 > _x2) { float _x0 = _x1; _x1 = _x2; _x2 = _x0; }
+
+ for(float x=_x1; x<_x2; x++) {
+
+ float distance = isLinear ?
+ // length of projection of <x,y> onto the gradient vector == {<x,y> \dot {grad \over |grad|}}
+ (x * (x2 - x1) + y * (y2 - y1)) / (float)Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)) :
+
+ // radial form is simple! FIXME, not quite right
+ (float)Math.sqrt((x - cx) * (x - cx) + (y - cy) * (y - cy));
+
+ // FIXME: offsets are 0..1, not 0..length(gradient)
+ int i = 0; for(; i<stop_offsets.length; i++) if (distance < stop_offsets[i]) break;
+
+ // FIXME: handle points beyond the bounds
+ if (i < 0 || i >= stop_offsets.length) continue;
+
+ // gradate from offsets[i - 1] to offsets[i]
+ float percentage = ((distance - stop_offsets[i - 1]) / (stop_offsets[i] - stop_offsets[i - 1]));
+
+ int a = (int)((((stop_colors[i] >> 24) & 0xff) - ((stop_colors[i - 1] >> 24) & 0xff)) * percentage) +
+ ((stop_colors[i - 1] >> 24) & 0xff);
+ int r = (int)((((stop_colors[i] >> 16) & 0xff) - ((stop_colors[i - 1] >> 16) & 0xff)) * percentage) +
+ ((stop_colors[i - 1] >> 16) & 0xff);
+ int g = (int)((((stop_colors[i] >> 8) & 0xff) - ((stop_colors[i - 1] >> 8) & 0xff)) * percentage) +
+ ((stop_colors[i - 1] >> 8) & 0xff);
+ int b = (int)((((stop_colors[i] >> 0) & 0xff) - ((stop_colors[i - 1] >> 0) & 0xff)) * percentage) +
+ ((stop_colors[i - 1] >> 0) & 0xff);
+ int argb = (a << 24) | (r << 16) | (g << 8) | b;
+ buf.drawPoint((int)x, (int)Math.floor(y), argb);
+ }
+ }
+ }
+ }
+
+ public static class LinearGradientPaint extends GradientPaint {
+ public LinearGradientPaint(float x1, float y1, float x2, float y2, boolean reflect, boolean repeat,
+ Affine gradientTransform, int[] stop_colors, float[] stop_offsets) {
+ super(reflect, repeat, gradientTransform, stop_colors, stop_offsets);
+ this.x1 = x1; this.x2 = x2; this.y1 = y1; this.y2 = y2;
+ }
+ float x1 = 0, y1 = 0, x2 = 300, y2 = 300;
+ }
+
+ public static class RadialGradientPaint extends GradientPaint {
+ public RadialGradientPaint(float cx, float cy, float fx, float fy, float r, boolean reflect, boolean repeat,
+ Affine gradientTransform, int[] stop_colors, float[] stop_offsets) {
+ super(reflect, repeat, gradientTransform, stop_colors, stop_offsets);
+ this.cx = cx; this.cy = cy; this.fx = fx; this.fy = fy; this.r = r;
+ }
+
+ float cx, cy, r, fx, fy;
+
+ }
+ */
+
+
+}
--- /dev/null
+// FIXME
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.graphics;
+import java.util.*;
+
+/** an abstract path; may contain splines and arcs */
+public class Path {
+
+ public static final float PX_PER_INCH = 72;
+ public static final float INCHES_PER_CM = (float)0.3937;
+ public static final float INCHES_PER_MM = INCHES_PER_CM / 10;
+ private static final int DEFAULT_PATHLEN = 1000;
+ private static final float PI = (float)Math.PI;
+
+ // the number of vertices on this path
+ int numvertices = 0;
+
+ // the vertices of the path
+ float[] x = new float[DEFAULT_PATHLEN];
+ float[] y = new float[DEFAULT_PATHLEN];
+
+ // the type of each edge; type[i] is the type of the edge from x[i],y[i] to x[i+1],y[i+1]
+ byte[] type = new byte[DEFAULT_PATHLEN];
+
+ // bezier control points
+ float[] c1x = new float[DEFAULT_PATHLEN]; // or rx (arcto)
+ float[] c1y = new float[DEFAULT_PATHLEN]; // or ry (arcto)
+ float[] c2x = new float[DEFAULT_PATHLEN]; // or x-axis-rotation (arcto)
+ float[] c2y = new float[DEFAULT_PATHLEN]; // or large-arc << 1 | sweep (arcto)
+
+ boolean closed = false;
+
+ static final byte TYPE_MOVETO = 0;
+ static final byte TYPE_LINETO = 1;
+ static final byte TYPE_ARCTO = 2;
+ static final byte TYPE_CUBIC = 3;
+ static final byte TYPE_QUADRADIC = 4;
+
+ public static Path parse(String s) { return Tokenizer.parse(s); }
+
+ // FIXME: hack
+ private String toString;
+ private Path(String s) { this.toString = s; }
+ public String toString() { return toString; }
+
+ public static class Tokenizer {
+ // FIXME: check array bounds exception for improperly terminated string
+ String s;
+ int i = 0;
+ char lastCommand = 'M';
+ public Tokenizer(String s) { this.s = s; }
+
+ public static Path parse(String s) {
+ if (s == null) return null;
+ Tokenizer t = new Tokenizer(s);
+ Path ret = new Path(s);
+ char last_command = 'M';
+ boolean first = true;
+ while(t.hasMoreTokens()) {
+ char command = t.parseCommand();
+ if (first && command != 'M') throw new RuntimeException("the first command of a path must be 'M'");
+ first = false;
+ boolean relative = Character.toLowerCase(command) == command;
+ command = Character.toLowerCase(command);
+ ret.parseSingleCommandAndArguments(t, command, relative);
+ last_command = command;
+ }
+ return ret;
+ }
+
+ private void consumeWhitespace() {
+ while(i < s.length() && (Character.isWhitespace(s.charAt(i)))) i++;
+ if (i < s.length() && s.charAt(i) == ',') i++;
+ while(i < s.length() && (Character.isWhitespace(s.charAt(i)))) i++;
+ }
+ public boolean hasMoreTokens() { consumeWhitespace(); return i < s.length(); }
+ public char parseCommand() {
+ consumeWhitespace();
+ char c = s.charAt(i);
+ if (!Character.isLetter(c)) return lastCommand;
+ i++;
+ return lastCommand = c;
+ }
+ public float parseFloat() {
+ consumeWhitespace();
+ int start = i;
+ float multiplier = 1;
+ for(; i < s.length(); i++) {
+ char c = s.charAt(i);
+ if (Character.isWhitespace(c) || c == ',' || (c == '-' && i != start)) break;
+ if (!((c >= '0' && c <= '9') || c == '.' || c == 'e' || c == 'E' || c == '-')) {
+ if (c == '%') { // FIXME
+ } else if (s.regionMatches(i, "pt", 0, i+2)) { // FIXME
+ } else if (s.regionMatches(i, "em", 0, i+2)) { // FIXME
+ } else if (s.regionMatches(i, "pc", 0, i+2)) { // FIXME
+ } else if (s.regionMatches(i, "ex", 0, i+2)) { // FIXME
+ } else if (s.regionMatches(i, "mm", 0, i+2)) { i += 2; multiplier = INCHES_PER_MM * PX_PER_INCH; break;
+ } else if (s.regionMatches(i, "cm", 0, i+2)) { i += 2; multiplier = INCHES_PER_CM * PX_PER_INCH; break;
+ } else if (s.regionMatches(i, "in", 0, i+2)) { i += 2; multiplier = PX_PER_INCH; break;
+ } else if (s.regionMatches(i, "px", 0, i+2)) { i += 2; break;
+ } else if (Character.isLetter(c)) break;
+ throw new RuntimeException("didn't expect character \"" + c + "\" in a numeric constant");
+ }
+ }
+ if (start == i) throw new RuntimeException("FIXME");
+ return Float.parseFloat(s.substring(start, i)) * multiplier;
+ }
+ }
+
+ /** Creates a concrete vector path transformed through the given matrix. */
+ public Raster realize(Affine a) {
+
+ Raster ret = new Raster();
+ int NUMSTEPS = 5; // FIXME
+ ret.numvertices = 1;
+ ret.x[0] = (int)Math.round(a.multiply_px(x[0], y[0]));
+ ret.y[0] = (int)Math.round(a.multiply_py(x[0], y[0]));
+
+ for(int i=1; i<numvertices; i++) {
+ if (type[i] == TYPE_LINETO) {
+ float rx = x[i];
+ float ry = y[i];
+ ret.x[ret.numvertices] = (int)Math.round(a.multiply_px(rx, ry));
+ ret.y[ret.numvertices] = (int)Math.round(a.multiply_py(rx, ry));
+ ret.edges[ret.numedges++] = ret.numvertices - 1; ret.numvertices++;
+
+ } else if (type[i] == TYPE_MOVETO) {
+ float rx = x[i];
+ float ry = y[i];
+ ret.x[ret.numvertices] = (int)Math.round(a.multiply_px(rx, ry));
+ ret.y[ret.numvertices] = (int)Math.round(a.multiply_py(rx, ry));
+ ret.numvertices++;
+
+ } else if (type[i] == TYPE_ARCTO) {
+ float rx = c1x[i];
+ float ry = c1y[i];
+ float phi = c2x[i];
+ float fa = ((int)c2y[i]) >> 1;
+ float fs = ((int)c2y[i]) & 1;
+ float x1 = x[i];
+ float y1 = y[i];
+ float x2 = x[i+1];
+ float y2 = y[i+1];
+
+ // F.6.5: given x1,y1,x2,y2,fa,fs, compute cx,cy,theta1,dtheta
+ float x1_ = (float)Math.cos(phi) * (x1 - x2) / 2 + (float)Math.sin(phi) * (y1 - y2) / 2;
+ float y1_ = -1 * (float)Math.sin(phi) * (x1 - x2) / 2 + (float)Math.cos(phi) * (y1 - y2) / 2;
+ float tmp = (float)Math.sqrt((rx * rx * ry * ry - rx * rx * y1_ * y1_ - ry * ry * x1_ * x1_) /
+ (rx * rx * y1_ * y1_ + ry * ry * x1_ * x1_));
+ float cx_ = (fa == fs ? -1 : 1) * tmp * (rx * y1_ / ry);
+ float cy_ = (fa == fs ? -1 : 1) * -1 * tmp * (ry * x1_ / rx);
+ float cx = (float)Math.cos(phi) * cx_ - (float)Math.sin(phi) * cy_ + (x1 + x2) / 2;
+ float cy = (float)Math.sin(phi) * cx_ + (float)Math.cos(phi) * cy_ + (y1 + y2) / 2;
+
+ // F.6.4 Conversion from center to endpoint parameterization
+ float ux = 1, uy = 0, vx = (x1_ - cx_) / rx, vy = (y1_ - cy_) / ry;
+ float det = ux * vy - uy * vx;
+ float theta1 = (det < 0 ? -1 : 1) *
+ (float)Math.acos((ux * vx + uy * vy) /
+ ((float)Math.sqrt(ux * ux + uy * uy) * (float)Math.sqrt(vx * vx + vy * vy)));
+ ux = (x1_ - cx_) / rx; uy = (y1_ - cy_) / ry;
+ vx = (-1 * x1_ - cx_) / rx; vy = (-1 * y1_ - cy_) / ry;
+ det = ux * vy - uy * vx;
+ float dtheta = (det < 0 ? -1 : 1) *
+ (float)Math.acos((ux * vx + uy * vy) /
+ ((float)Math.sqrt(ux * ux + uy * uy) * (float)Math.sqrt(vx * vx + vy * vy)));
+ dtheta = dtheta % (float)(2 * Math.PI);
+
+ if (fs == 0 && dtheta > 0) theta1 -= 2 * PI;
+ if (fs == 1 && dtheta < 0) theta1 += 2 * PI;
+
+ if (fa == 1 && dtheta < 0) dtheta = 2 * PI + dtheta;
+ else if (fa == 1 && dtheta > 0) dtheta = -1 * (2 * PI - dtheta);
+
+ // FIXME: integrate F.6.6
+ // FIXME: isn't quite ending where it should...
+
+ // F.6.3: Parameterization alternatives
+ float theta = theta1;
+ for(int j=0; j<NUMSTEPS; j++) {
+ float rasterx = rx * (float)Math.cos(theta) * (float)Math.cos(phi) -
+ ry * (float)Math.sin(theta) * (float)Math.sin(phi) + cx;
+ float rastery = rx * (float)Math.cos(theta) * (float)Math.sin(phi) +
+ ry * (float)Math.cos(phi) * (float)Math.sin(theta) + cy;
+ ret.x[ret.numvertices] = (int)Math.round(a.multiply_px(rasterx, rastery));
+ ret.y[ret.numvertices] = (int)Math.round(a.multiply_py(rasterx, rastery));
+ ret.edges[ret.numedges++] = ret.numvertices - 1; ret.numvertices++;
+ theta += dtheta / NUMSTEPS;
+ }
+
+ } else if (type[i] == TYPE_CUBIC) {
+
+ float ax = x[i+1] - 3 * c2x[i] + 3 * c1x[i] - x[i];
+ float bx = 3 * c2x[i] - 6 * c1x[i] + 3 * x[i];
+ float cx = 3 * c1x[i] - 3 * x[i];
+ float dx = x[i];
+ float ay = y[i+1] - 3 * c2y[i] + 3 * c1y[i] - y[i];
+ float by = 3 * c2y[i] - 6 * c1y[i] + 3 * y[i];
+ float cy = 3 * c1y[i] - 3 * y[i];
+ float dy = y[i];
+
+ for(float t=0; t<1; t += 1 / (float)NUMSTEPS) {
+ float rx = ax * t * t * t + bx * t * t + cx * t + dx;
+ float ry = ay * t * t * t + by * t * t + cy * t + dy;
+ ret.x[ret.numvertices] = (int)Math.round(a.multiply_px(rx, ry));
+ ret.y[ret.numvertices] = (int)Math.round(a.multiply_py(rx, ry));
+ ret.edges[ret.numedges++] = ret.numvertices - 1; ret.numvertices++;
+ }
+
+
+ } else if (type[i] == TYPE_QUADRADIC) {
+
+ float bx = x[i+1] - 2 * c1x[i] + x[i];
+ float cx = 2 * c1x[i] - 2 * x[i];
+ float dx = x[i];
+ float by = y[i+1] - 2 * c1y[i] + y[i];
+ float cy = 2 * c1y[i] - 2 * y[i];
+ float dy = y[i];
+
+ for(float t=0; t<1; t += 1 / (float)NUMSTEPS) {
+ float rx = bx * t * t + cx * t + dx;
+ float ry = by * t * t + cy * t + dy;
+ ret.x[ret.numvertices] = (int)Math.round(a.multiply_px(rx, ry));
+ ret.y[ret.numvertices] = (int)Math.round(a.multiply_py(rx, ry));
+ ret.edges[ret.numedges++] = ret.numvertices - 1; ret.numvertices++;
+ }
+
+ }
+
+ }
+
+ if (ret.numedges > 0) ret.sort(0, ret.numedges - 1, false);
+ return ret;
+ }
+
+ protected void parseSingleCommandAndArguments(Tokenizer t, char command, boolean relative) {
+ if (numvertices == 0 && command != 'm') throw new RuntimeException("first command MUST be an 'm'");
+ if (numvertices > x.length - 2) {
+ float[] new_x = new float[x.length * 2]; System.arraycopy(x, 0, new_x, 0, x.length); x = new_x;
+ float[] new_y = new float[y.length * 2]; System.arraycopy(y, 0, new_y, 0, y.length); y = new_y;
+ }
+ switch(command) {
+ case 'z': {
+ int where;
+ type[numvertices-1] = TYPE_LINETO;
+ for(where = numvertices - 1; where > 0; where--)
+ if (type[where - 1] == TYPE_MOVETO) break;
+ x[numvertices] = x[where];
+ y[numvertices] = y[where];
+ numvertices++;
+ closed = true;
+ break;
+ }
+
+ case 'm': {
+ if (numvertices > 0) type[numvertices-1] = TYPE_MOVETO;
+ x[numvertices] = t.parseFloat() + (relative ? x[numvertices - 1] : 0);
+ y[numvertices] = t.parseFloat() + (relative ? y[numvertices - 1] : 0);
+ numvertices++;
+ break;
+ }
+
+ case 'l': case 'h': case 'v': {
+ type[numvertices-1] = TYPE_LINETO;
+ float first = t.parseFloat(), second;
+ if (command == 'h') {
+ second = relative ? 0 : y[numvertices - 1];
+ } else if (command == 'v') {
+ second = first; first = relative ? 0 : x[numvertices - 1];
+ } else {
+ second = t.parseFloat();
+ }
+ x[numvertices] = first + (relative ? x[numvertices - 1] : 0);
+ y[numvertices] = second + (relative ? y[numvertices - 1] : 0);
+ numvertices++;
+ break;
+ }
+
+ case 'a': {
+ type[numvertices-1] = TYPE_ARCTO;
+ c1x[numvertices-1] = t.parseFloat() + (relative ? x[numvertices - 1] : 0);
+ c1y[numvertices-1] = t.parseFloat() + (relative ? y[numvertices - 1] : 0);
+ c2x[numvertices-1] = (t.parseFloat() / 360) * 2 * PI;
+ c2y[numvertices-1] = (((int)t.parseFloat()) << 1) | (int)t.parseFloat();
+ x[numvertices] = t.parseFloat() + (relative ? x[numvertices - 1] : 0);
+ y[numvertices] = t.parseFloat() + (relative ? y[numvertices - 1] : 0);
+ numvertices++;
+ break;
+ }
+
+ case 's': case 'c': {
+ type[numvertices-1] = TYPE_CUBIC;
+ if (command == 'c') {
+ c1x[numvertices-1] = t.parseFloat() + (relative ? x[numvertices - 1] : 0);
+ c1y[numvertices-1] = t.parseFloat() + (relative ? y[numvertices - 1] : 0);
+ } else if (numvertices > 1 && type[numvertices-2] == TYPE_CUBIC) {
+ c1x[numvertices-1] = 2 * x[numvertices - 1] - c2x[numvertices-2];
+ c1y[numvertices-1] = 2 * y[numvertices - 1] - c2y[numvertices-2];
+ } else {
+ c1x[numvertices-1] = x[numvertices-1];
+ c1y[numvertices-1] = y[numvertices-1];
+ }
+ c2x[numvertices-1] = t.parseFloat() + (relative ? x[numvertices - 1] : 0);
+ c2y[numvertices-1] = t.parseFloat() + (relative ? y[numvertices - 1] : 0);
+ x[numvertices] = t.parseFloat() + (relative ? x[numvertices - 1] : 0);
+ y[numvertices] = t.parseFloat() + (relative ? y[numvertices - 1] : 0);
+ numvertices++;
+ break;
+ }
+
+ case 't': case 'q': {
+ type[numvertices-1] = TYPE_QUADRADIC;
+ if (command == 'q') {
+ c1x[numvertices-1] = t.parseFloat() + (relative ? x[numvertices - 1] : 0);
+ c1y[numvertices-1] = t.parseFloat() + (relative ? y[numvertices - 1] : 0);
+ } else if (numvertices > 1 && type[numvertices-2] == TYPE_QUADRADIC) {
+ c1x[numvertices-1] = 2 * x[numvertices - 1] - c1x[numvertices-2];
+ c1y[numvertices-1] = 2 * y[numvertices - 1] - c1y[numvertices-2];
+ } else {
+ c1x[numvertices-1] = x[numvertices-1];
+ c1y[numvertices-1] = y[numvertices-1];
+ }
+ x[numvertices] = t.parseFloat() + (relative ? x[numvertices - 1] : 0);
+ y[numvertices] = t.parseFloat() + (relative ? y[numvertices - 1] : 0);
+ numvertices++;
+ break;
+ }
+
+ default:
+ // FIXME
+ }
+
+ /*
+ // invariant: after this loop, no two lines intersect other than at a vertex
+ // FIXME: cleanup
+ int index = numvertices - 2;
+ for(int i=0; i<Math.min(numvertices - 3, index); i++) {
+ for(int j = index; j < numvertices - 1; j++) {
+
+ // I'm not sure how to deal with vertical lines...
+ if (x[i+1] == x[i] || x[j+1] == x[j]) continue;
+
+ float islope = (y[i+1] - y[i]) / (x[i+1] - x[i]);
+ float jslope = (y[j+1] - y[j]) / (x[j+1] - x[j]);
+ if (islope == jslope) continue; // parallel lines can't intersect
+
+ float _x = (islope * x[i] - jslope * x[j] + y[j] - y[i]) / (islope - jslope);
+ float _y = islope * (_x - x[i]) + y[i];
+
+ if (_x > Math.min(x[i+1], x[i]) && _x < Math.max(x[i+1], x[i]) &&
+ _x > Math.min(x[j+1], x[j]) && _x < Math.max(x[j+1], x[j])) {
+ // FIXME: something's not right in here. See if we can do without fracturing line 'i'.
+ for(int k = ++numvertices; k>i; k--) { x[k] = x[k - 1]; y[k] = y[k - 1]; }
+ x[i+1] = _x;
+ y[i+1] = _y;
+ x[numvertices] = x[numvertices - 1]; x[numvertices - 1] = _x;
+ y[numvertices] = y[numvertices - 1]; y[numvertices - 1] = _y;
+ edges[numedges++] = numvertices - 1; numvertices++;
+ index++;
+ break; // actually 'continue' the outermost loop
+ }
+ }
+ }
+ */
+
+ }
+
+
+ // Rasterized Vector Path //////////////////////////////////////////////////////////////////////////////
+
+ /** a vector path */
+ public static class Raster {
+
+ // the vertices of this path
+ int[] x = new int[DEFAULT_PATHLEN];
+ int[] y = new int[DEFAULT_PATHLEN];
+ int numvertices = 0;
+
+ /**
+ * A list of the vertices on this path which *start* an *edge* (rather than a moveto), sorted by increasing y.
+ * example: x[edges[1]],y[edges[1]] - x[edges[i]+1],y[edges[i]+1] is the second-topmost edge
+ * note that if x[i],y[i] - x[i+1],y[i+1] is a MOVETO, then no element in edges will be equal to i
+ */
+ int[] edges = new int[DEFAULT_PATHLEN];
+ int numedges = 0;
+
+ /** translate a rasterized path */
+ public void translate(int dx, int dy) { for(int i=0; i<numvertices; i++) { x[i] += dx; y[i] += dy; } }
+
+ /** simple quicksort, from http://sourceforge.net/snippet/detail.php?type=snippet&id=100240 */
+ int sort(int left, int right, boolean partition) {
+ if (partition) {
+ int i, j, middle;
+ middle = (left + right) / 2;
+ int s = edges[right]; edges[right] = edges[middle]; edges[middle] = s;
+ for (i = left - 1, j = right; ; ) {
+ while (y[edges[++i]] < y[edges[right]]);
+ while (j > left && y[edges[--j]] > y[edges[right]]);
+ if (i >= j) break;
+ s = edges[i]; edges[i] = edges[j]; edges[j] = s;
+ }
+ s = edges[right]; edges[right] = edges[i]; edges[i] = s;
+ return i;
+ } else {
+ if (left >= right) return 0;
+ int p = sort(left, right, true);
+ sort(left, p - 1, false);
+ sort(p + 1, right, false);
+ return 0;
+ }
+ }
+
+ /** finds the x value at which the line intercepts the line y=_y */
+ private int intercept(int i, float _y, boolean includeTop, boolean includeBottom) {
+ if (includeTop ? (_y < Math.min(y[i], y[i+1])) : (_y <= Math.min(y[i], y[i+1])))
+ return Integer.MIN_VALUE;
+ if (includeBottom ? (_y > Math.max(y[i], y[i+1])) : (_y >= Math.max(y[i], y[i+1])))
+ return Integer.MIN_VALUE;
+ return (int)Math.round((((float)(x[i + 1] - x[i])) /
+ ((float)(y[i + 1] - y[i])) ) * ((float)(_y - y[i])) + x[i]);
+ }
+
+ /** fill the interior of the path */
+ public void fill(PixelBuffer buf, Paint paint) {
+ if (numedges == 0) return;
+ int y0 = y[edges[0]], y1 = y0;
+ boolean useEvenOdd = false;
+
+ // we iterate over all endpoints in increasing y-coordinate order
+ for(int index = 1; index<numedges; index++) {
+ int count = 0;
+
+ // we now examine the horizontal band between y=y0 and y=y1
+ y0 = y1;
+ y1 = y[edges[index]];
+ if (y0 == y1) continue;
+
+ // within this band, we iterate over all edges
+ int x0 = Integer.MIN_VALUE;
+ int leftSegment = -1;
+ while(true) {
+ int x1 = Integer.MAX_VALUE;
+ int rightSegment = Integer.MAX_VALUE;
+ for(int i=0; i<numedges; i++) {
+ if (y[edges[i]] == y[edges[i]+1]) continue; // ignore horizontal lines; they are irrelevant.
+ // we order the segments by the x-coordinate of their midpoint;
+ // since segments cannot intersect, this is a well-ordering
+ int i0 = intercept(edges[i], y0, true, false);
+ int i1 = intercept(edges[i], y1, false, true);
+ if (i0 == Integer.MIN_VALUE || i1 == Integer.MIN_VALUE) continue;
+ int midpoint = i0 + i1;
+ if (midpoint < x0) continue;
+ if (midpoint == x0 && i <= leftSegment) continue;
+ if (midpoint > x1) continue;
+ if (midpoint == x1 && i >= rightSegment) continue;
+ rightSegment = i;
+ x1 = midpoint;
+ }
+ if (leftSegment == rightSegment || rightSegment == Integer.MAX_VALUE) break;
+ if (leftSegment != -1)
+ if ((useEvenOdd && count % 2 != 0) || (!useEvenOdd && count != 0))
+ paint.fillTrapezoid(intercept(edges[leftSegment], y0, true, true),
+ intercept(edges[rightSegment], y0, true, true), y0,
+ intercept(edges[leftSegment], y1, true, true),
+ intercept(edges[rightSegment], y1, true, true), y1,
+ buf);
+ if (useEvenOdd) count++;
+ else count += (y[edges[rightSegment]] < y[edges[rightSegment]+1]) ? -1 : 1;
+ leftSegment = rightSegment; x0 = x1;
+ }
+ }
+ }
+
+ /** stroke the outline of the path */
+ public void stroke(PixelBuffer buf, int width, int color) { stroke(buf, width, color, null, 0, 0); }
+ public void stroke(PixelBuffer buf, int width, int color, String dashArray, int dashOffset, float segLength) {
+
+ if (dashArray == null) {
+ for(int i=0; i<numedges; i++)
+ buf.drawLine((int)x[edges[i]],
+ (int)y[edges[i]], (int)x[edges[i]+1], (int)y[edges[i]+1], width, color, false);
+ return;
+ }
+
+ float ratio = 1;
+ if (segLength > 0) {
+ float actualLength = 0;
+ for(int i=0; i<numvertices; i++) {
+ // skip over MOVETOs -- they do not contribute to path length
+ if (x[i] == x[i+1] && y[i] == y[i+1]) continue;
+ if (x[i+1] == x[i+2] && y[i+1] == y[i+2]) continue;
+ int x1 = x[i];
+ int x2 = x[i + 1];
+ int y1 = y[i];
+ int y2 = y[i + 1];
+ actualLength += java.lang.Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
+ }
+ ratio = actualLength / segLength;
+ }
+ Tokenizer pt = new Tokenizer(dashArray);
+ Vector v = new Vector();
+ while (pt.hasMoreTokens()) v.addElement(new Float(pt.parseFloat()));
+ float[] dashes = new float[v.size() % 2 == 0 ? v.size() : 2 * v.size()];
+ for(int i=0; i<dashes.length; i++) dashes[i] = ((Float)v.elementAt(i % v.size())).floatValue();
+ int dashpos = dashOffset;
+ boolean on = dashpos % 2 == 0;
+ for(int i=0; i<numvertices; i++) {
+ // skip over MOVETOs -- they do not contribute to path length
+ if (x[i] == x[i+1] && y[i] == y[i+1]) continue;
+ if (x[i+1] == x[i+2] && y[i+1] == y[i+2]) continue;
+ int x1 = (int)x[i];
+ int x2 = (int)x[i + 1];
+ int y1 = (int)y[i];
+ int y2 = (int)y[i + 1];
+ float segmentLength = (float)java.lang.Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
+ int _x1 = x1, _y1 = y1;
+ float pos = 0;
+ do {
+ pos = Math.min(segmentLength, pos + dashes[dashpos] * ratio);
+ if (pos != segmentLength) dashpos = (dashpos + 1) % dashes.length;
+ int _x2 = (int)((x2 * pos + x1 * (segmentLength - pos)) / segmentLength);
+ int _y2 = (int)((y2 * pos + y1 * (segmentLength - pos)) / segmentLength);
+ if (on) buf.drawLine(_x1, _y1, _x2, _y2, width, color, false);
+ on = !on;
+ _x1 = _x2; _y1 = _y2;
+ } while(pos < segmentLength);
+ }
+ }
+
+ // FEATURE: make this faster and cache it; also deal with negative coordinates
+ public int boundingBoxWidth() {
+ int ret = 0;
+ for(int i=0; i<numvertices; i++) ret = Math.max(ret, x[i]);
+ return ret;
+ }
+
+ // FEATURE: make this faster and cache it; also deal with negative coordinates
+ public int boundingBoxHeight() {
+ int ret = 0;
+ for(int i=0; i<numvertices; i++) ret = Math.max(ret, y[i]);
+ return ret;
+ }
+ }
+}
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.graphics;
+import java.io.*;
+import org.ibex.js.*;
+import org.ibex.plat.*;
+import org.ibex.util.*;
+import org.ibex.core.*;
+
+/**
+ * The in-memory representation of a PNG or GIF image. It is
+ * read-only. It is usually passed to PixelBuffer.drawPicture()
+ *
+ * Implementations of the Platform class should return objects
+ * supporting this interface from the createPicture() method. These
+ * implementations may choose to implement caching strategies (for
+ * example, using a Pixmap on X11).
+ */
+public class Picture {
+
+ public Picture() { this.stream = null; }
+ public Picture(JS r) { this.stream = r; }
+ private static Cache cache = new Cache(100); ///< Picture, keyed by the Stream that loaded them
+
+ public JS stream = null; ///< the stream we were loaded from
+ public int width = -1; ///< the width of the image
+ public int height = -1; ///< the height of the image
+ public int[] data = null; ///< argb samples
+ public boolean isLoaded = false; ///< true iff the image is fully loaded
+
+ /** invoked when an image is fully loaded; subclasses can use this to initialize platform-specific constructs */
+ protected void loaded() { isLoaded = true; }
+
+ /** turns a stream into a Picture.Source and passes it to the callback */
+ public static Picture load(final JS stream, final Task callback) {
+ Picture ret = (Picture)cache.get(stream);
+ if (ret == null) cache.put(stream, ret = Platform.createPicture(stream));
+ final Picture p = ret;
+ if (!ret.isLoaded && callback != null) {
+ final Ibex.Blessing b = Ibex.Blessing.getBlessing(stream);
+ new java.lang.Thread() { public void run() {
+ InputStream in = null;
+ try {
+ in = b == null ? Stream.getInputStream(stream) : b.getImage();
+ } catch (IOException e) { Log.error(Picture.class, e);
+ } catch (JSExn e) { Log.error(Picture.class, e);
+ }
+ if (in == null) { Log.warn(Picture.class, "couldn't load image for stream " + stream.unclone()); return; }
+ try {
+ PushbackInputStream pbis = new PushbackInputStream(in);
+ int firstByte = pbis.read();
+ if (firstByte == -1) throw new JSExn("empty stream reading image");
+ pbis.unread(firstByte);
+ if ((firstByte & 0xff) == 'G') GIF.load(pbis, p);
+ else if ((firstByte & 0xff) == 137) PNG.load(pbis, p);
+ else if ((firstByte & 0xff) == 0xff) Platform.decodeJPEG(pbis, p);
+ else throw new JSExn("couldn't figure out image type from first byte");
+ p.loaded();
+ Scheduler.add(callback);
+ } catch (Exception e) {
+ Log.info(this, "exception while loading image");
+ Log.info(this, e);
+ }
+ } }.start();
+ }
+ return ret;
+ }
+}
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.graphics;
+
+/**
+ * <p>
+ * A block of pixels which can be drawn on.
+ * </p>
+ *
+ * <p>
+ * Implementations of the Platform class should return objects
+ * supporting this interface from the _createPixelBuffer()
+ * method. These implementations may choose to use off-screen video
+ * ram for this purpose (for example, a Pixmap on X11).
+ * </p>
+ *
+ * <p>
+ * Many of these functions come in pairs, one that uses ints and one
+ * that uses floats. The int functions are intended for situations
+ * in which the CTM is the identity transform.
+ * </p>
+ */
+public abstract class PixelBuffer {
+
+ /** draw the picture at (dx1, dy1), cropping to (cx1, cy1, cx2, cy2) */
+ public abstract void drawPicture(Picture source, int dx1, int dy1, int cx1, int cy1, int cx2, int cy2);
+
+ /** fill a trapezoid whose top and bottom edges are horizontal */
+ public abstract void fillTrapezoid(int x1, int x2, int y1, int x3, int x4, int y2, int color);
+
+ /**
+ * Same as drawPicture, but only uses the alpha channel of the Picture, and is allowed to destructively modify the RGB
+ * channels of the Picture in the process. This method may assume that the RGB channels of the image are all zero IFF it
+ * restores this invariant before returning.
+ */
+ public abstract void drawGlyph(Font.Glyph source, int dx1, int dy1, int cx1, int cy1, int cx2, int cy2, int rgb);
+
+ // FEATURE: we want floats (inter-pixel spacing) for antialiasing, but this hoses the fastpath line drawing... argh!
+ /** draws a line of width <tt>w</tt>; note that the coordinates here are <i>post-transform</i> */
+ public void drawLine(int x1, int y1, int x2, int y2, int w, int color, boolean capped) {
+
+ if (y1 > y2) { int t = x1; x1 = x2; x2 = t; t = y1; y1 = y2; y2 = t; }
+
+ if (x1 == x2) {
+ fillTrapezoid(x1 - w / 2, x2 + w / 2, y1 - (capped ? w / 2 : 0),
+ x1 - w / 2, x2 + w / 2, y2 + (capped ? w / 2 : 0), color);
+ return;
+ }
+
+ // fastpath for single-pixel width lines
+ if (w == 1) {
+ float slope = (float)(y2 - y1) / (float)(x2 - x1);
+ int last_x = x1;
+ for(int y=y1; y<=y2; y++) {
+ int new_x = (int)((float)(y - y1) / slope) + x1;
+ if (slope >= 0) fillTrapezoid(last_x + 1, y != y2 ? new_x + 1 : new_x, y,
+ last_x + 1, y != y2 ? new_x + 1 : new_x, y + 1, color);
+ else fillTrapezoid(y != y2 ? new_x : new_x + 1, last_x, y,
+ y != y2 ? new_x : new_x + 1, last_x, y + 1, color);
+ last_x = new_x;
+ }
+ return;
+ }
+
+ // actually half-width
+ float width = (float)w / 2;
+ float phi = (float)Math.atan((y2 - y1) / (x2 - x1));
+ if (phi < 0.0) phi += (float)Math.PI * 2;
+ float theta = (float)Math.PI / 2 - phi;
+
+ // dx and dy are the x and y distance between each endpoint and the corner of the stroke
+ int dx = (int)(width * Math.cos(theta));
+ int dy = (int)(width * Math.sin(theta));
+
+ // slice is the longest possible length of a horizontal line across the stroke
+ int slice = (int)(2 * width / Math.cos(theta));
+
+ if (capped) {
+ x1 -= width * Math.cos(phi);
+ x2 += width * Math.cos(phi);
+ y1 -= width * Math.sin(phi);
+ y2 += width * Math.sin(phi);
+ }
+
+ fillTrapezoid(x1 + dx, x1 + dx, y1 - dy, x1 - dx, x1 - dx + slice, y1 + dy, color); // top corner
+ fillTrapezoid(x2 + dx - slice, x2 + dx, y2 - dy, x2 - dx, x2 - dx, y2 + dy, color); // bottom corner
+ fillTrapezoid(x1 - dx, x1 - dx + slice, y1 + dy, x2 + dx - slice, x2 + dx, y2 - dy, color); // middle
+ }
+
+}
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.graphics;
+import java.util.*;
+
+
+// FIXME: offer a "subpixel" mode where we pass floats to the Platform and don't do any snapping
+// FIXME: fracture when realizing instead of when parsing?
+
+/*
+ v1.0
+ - textpath
+ - gradients
+ - patterns
+ - clipping/masking
+ - filters (filtering of a group must be performed AFTER the group is assembled; sep. canvas)
+
+ v1.1
+ - bump caps [requires Paint that can fill circles...] [remember to distinguish between closed/unclosed]
+ - line joins
+ - mitre (hard)
+ - bevel (easy)
+ - bump (easy, but requires 'round' Paint)
+ - subtree sharing? otherwise the memory consumption might be outrageous... clone="" attribute?
+ - better clipping
+ - intersect clip regions (linearity)
+ - clip on trapezoids, not pixels
+ - faster gradients and patterns:
+ - transform each corner of the trapezoid and then interpolate
+*/
+
+// FIXME: need to support style sheets and the 'style=' attribute
+// FIXME: need to convert markers into subboxes
+public class SVG {
+
+ /*
+ public static void parseNode(String name, String[] keys, Object[] vals, Template t) {
+ Hash h = new Hash();
+ for(int i=0; i<keys.length; i++) if (vals[i] != null) h.put(keys[i], vals[i]);
+
+ Hash props = new Hash();
+ props.put("transform", h.get("transform"));
+ props.put("fill", h.get("fill"));
+ props.put("stroke", h.get("stroke"));
+ if ("visible".equals(h.get("overflow")) || "auto".equals(h.get("overflow")))
+ Log.info(VectorGraphics.class, "warning: overflow={auto|visible} not supported; ignoring");
+ if (h.get("display") != null) props.put("invisible", new Boolean("none".equals(h.get("display"))));
+
+
+ // FIXME: "the automatic transformation that is created due to
+ // a viewBox does not affect the x, y, width and height
+ // attributes". Also, transform+viewbox together?
+
+ if (h.get("preserveAspectRatio") != null) {
+ StringTokenizer st = new StringTokenizer((String)h.get("preserveAspectRatio"), " ");
+ String align = st.nextToken();
+ if ("defer".equals(align)) align = st.nextToken();
+ if (!align.equals("none")) {
+ // FIXME, need to beef up XWT's align property
+ align = "";
+ if (align.startsWith("yMin")) align = "top";
+ else if (align.startsWith("yMax")) align = "bottom";
+ if (align.startsWith("xMin")) align += "left";
+ else if (align.startsWith("xMax")) align += "right";
+ props.put("align", align);
+ }
+ // FIXME: need to implement scaling property on boxes, also size-to-viewbox
+ props.put("scaling", "uniform");
+ if (st.hasMoreTokens()) {
+ String meetOrSlice = st.nextToken();
+ if (meetOrSlice.equals("meet")) props.put("scaling", "meet"); // keep within viewport
+ else if (meetOrSlice.equals("slice")) props.put("scaling", "slice"); // expand beyond viewport
+ }
+ }
+
+ // FIXME: insert an extra layer of boxen and put this transform on the inner layer
+ if (h.get("viewBox") != null) {
+ PathTokenizer pt = new PathTokenizer(h.get("viewBox").toString());
+ String transform = (String)props.get("transform");
+ if (transform == null) transform = "";
+ transform = "translate(" + (-1 * pt.parseFloat()) + ", " + (-1 * pt.parseFloat()) + ") " +
+ "scale(" + pt.parseFloat() + "%, " + pt.parseFloat() + "%) ";
+ }
+
+ String path = (String)h.get("d");
+ if (name.equals("g")) {
+ path = null;
+
+ } else if (name.equals("font")) {
+ VectorGraphics.Font f = currentFont = new VectorGraphics.Font();
+ if (h.get("horiz-origin-x") != null) f.horiz_origin_x = Float.parseFloat(h.get("horiz-origin-x").toString());
+ if (h.get("horiz-origin-y") != null) f.horiz_origin_y = Float.parseFloat(h.get("horiz-origin-y").toString());
+ if (h.get("horiz-adv-x") != null) f.horiz_adv_x = Float.parseFloat(h.get("horiz-adv-x").toString());
+ if (h.get("vert-origin-x") != null) f.vert_origin_x = Float.parseFloat(h.get("vert-origin-x").toString());
+ if (h.get("vert-origin-y") != null) f.vert_origin_y = Float.parseFloat(h.get("vert-origin_y").toString());
+ if (h.get("vert-adv-y") != null) f.vert_adv_y = Float.parseFloat(h.get("vert-adv-y").toString());
+
+ } else if (name.equals("hkern")) {
+ //FIXME
+
+ } else if (name.equals("vkern")) {
+ //FIXME
+
+ } else if (name.equals("font-face")) {
+ //FIXME
+
+ } else if (name.equals("glyph") || name.equals("missing-glyph")) {
+ String glyphName = name.equals("missing-glyph") ? "missing-glyph" : (String)h.get("glyph-name");
+ VectorGraphics.Font.Glyph g = new VectorGraphics.Font.Glyph(glyphName, (String)h.get("unicode"), t, currentFont);
+ if (h.get("horiz-adv-x") != null) g.horiz_adv_x = Float.parseFloat(h.get("horiz-adv-x").toString());
+ if (h.get("vert-origin-x") != null) g.vert_origin_x = Float.parseFloat(h.get("vert-origin-x").toString());
+ if (h.get("vert-origin-y") != null) g.vert_origin_y = Float.parseFloat(h.get("vert-origin-y").toString());
+ if (h.get("vert-adv-y") != null) g.vert_adv_y = Float.parseFloat(h.get("vert-adv-y").toString());
+ if ("v".equals(h.get("orientation"))) g.isVerticallyOriented = true;
+
+ } else if (name.equals("svg")) {
+ // FIXME: handle percentages
+ // FIXME: what if these aren't provided?
+ // FIXME (in general)
+ float x = Float.parseFloat(h.get("x").toString());
+ float y = Float.parseFloat(h.get("y").toString());
+ float width = Float.parseFloat(h.get("width").toString());
+ float height = Float.parseFloat(h.get("height").toString());
+ h.put("viewBox", x + ", " + y + ", " + (x + width) + ", " + (y + height));
+ path = "";
+
+ } else if (name.equals("path")) {
+ path = h.get("d").toString();
+
+ } else if (name.equals("rect")) {
+ float x = Float.parseFloat(h.get("x").toString());
+ float y = Float.parseFloat(h.get("y").toString());
+ float width = Float.parseFloat(h.get("width").toString());
+ float height = Float.parseFloat(h.get("height").toString());
+ float rx = Float.parseFloat(h.get("rx").toString());
+ float ry = Float.parseFloat(h.get("ry").toString());
+ path =
+ "M" + (x + rx) + "," + y +
+ "H" + (x + width - rx) +
+ "A" + rx + "," + rx + ",0,0,1," + (x + width) + "," + (y + ry) +
+ "V" + (y + width - ry) +
+ "A" + rx + "," + rx + ",0,0,1," + (x + width - rx) + "," +
+ (y + height) +
+ "H" + (x + rx) +
+ "A" + rx + "," + rx + ",0,0,1," + x + "," + (y + height - ry) +
+ "V" + (y + ry) +
+ "A" + rx + "," + rx + ",0,0,1," + (x + rx) + "," + (y + ry) +
+ "Z";
+
+ } else if (name.equals("circle")) {
+ float r = Float.parseFloat(h.get("r").toString());
+ float cx = Float.parseFloat(h.get("cx").toString());
+ float cy = Float.parseFloat(h.get("cy").toString());
+ path = "A " + r + " " + r + " 1 1 " + cx + " " + cy;
+
+ } else if (name.equals("ellipse")) {
+ float rx = Float.parseFloat(h.get("rx").toString());
+ float ry = Float.parseFloat(h.get("ry").toString());
+ float cx = Float.parseFloat(h.get("cx").toString());
+ float cy = Float.parseFloat(h.get("cy").toString());
+ path = "A " + rx + " " + ry + " 1 1 " + cx + " " + cy;
+
+ } else if (name.equals("line")) {
+ float x1 = Float.parseFloat(h.get("x1").toString());
+ float y1 = Float.parseFloat(h.get("y1").toString());
+ float x2 = Float.parseFloat(h.get("x2").toString());
+ float y2 = Float.parseFloat(h.get("y2").toString());
+ path = "M " + x1 + " " + y1 + " L " + x2 + " " + y2;
+
+ } else if (name.equals("polyline") || name.equals("polygon")) {
+ StringTokenizer st = new StringTokenizer(h.get("points").toString(), ", ", false);
+ String s = "M ";
+ while(st.hasMoreTokens()) s += st.nextToken() + " " + st.nextToken() + " ";
+ path = s + (name.equals("polygon") ? "z" : "");
+
+ } else {
+ Log.info(VectorGraphics.class, "unknown element in VectorGraphics namespace: " + name);
+ }
+ props.put("path", path);
+ t.keys = new String[props.size()];
+ System.arraycopy(props.keys(), 0, t.keys, 0, t.keys.length);
+ t.vals = new String[props.size()];
+ for(int i=0; i<t.keys.length; i++) t.vals[i] = props.get(t.keys[i]);
+
+
+ // FIXME!!!!
+ if (h.get("viewBox") != null) {
+ StringTokenizer st = new StringTokenizer(h.get("viewBox").toString(), ", ", false);
+ if (t.transform == null) t.transform = "";
+ Point p1, p2;
+ VectorGraphics.RasterPath.fromString(path).getBoundingBox(p1, p2);
+
+ float minx = st.parseFloat();
+ float miny = st.parseFloat();
+ float width = st.parseFloat();
+ float height = st.parseFloat();
+ t.transform += "translate(" + (-1 * p1.x) + ", " + (-1 * p1.y) + ") " +
+ "scale(" + ((p2.x - p1.x) / width) + ", " + ((p2.y - p1.y) / height) + ") " +
+ "translate(" + minx + ", " + miny + ") ";
+
+ // FIXME: preserveAspectRatio
+ }
+
+ }
+ */
+
+ /*
+ public static class Font {
+ Font() { }
+ float horiz_origin_x = 0, horiz_origin_y = 0, horiz_adv_x = 0;
+ float vert_origin_x = 0, vert_origin_y = 0, vert_adv_y = 0;
+
+ // FIXME: avoid using substring() in here ore creating any objects
+ public void render(String text, DoubleBuffer buf, int x, int y, int fillcolor, int strokecolor, int size) {
+ // FIXME: points, not pixels
+ Affine a = buf.a;
+ float scaleFactor = (float)(1.0/1000.0) * (float)size;
+ for(int pos=0; pos<text.length(); pos++) {
+ Glyph g;
+ for(g = (Glyph)glyphByUnicode.get(text.substring(pos, pos+1));
+ g != null && !g.unicode.equals(text.substring(pos, pos + g.unicode.length()));
+ g = g.next);
+ if (g == null) {
+ g = (Glyph)glyphByName.get("missing-glyph");
+ } else {
+ pos += g.unicode.length() - 1;
+ }
+ if (g != null) {
+ System.out.println(" " + g.unicode);
+ g.render(buf, x, y, fillcolor, strokecolor, scaleFactor);
+ x += (int)(g.horiz_adv_x * size / 1000.0);
+ } else {
+ x += (int)(horiz_adv_x * size / 1000.0);
+ }
+ }
+ buf.setTransform(a);
+ }
+
+ / ** all glyphs, keyed by their <tt>name</tt> property * /
+ Hashtable glyphByName = new Hashtable();
+
+ / ** linked list of glyphs, stored by the first character of their <tt>unicode</tt> property * /
+ Hashtable glyphByUnicode = new Hashtable();
+
+ // a Glyph in an VectorGraphics font
+ public static class Glyph {
+
+ // FIXME: lang attribute
+ boolean isVerticallyOriented = false;
+ Template t = null;
+ Box b = null;
+
+ float horiz_adv_x = 0;
+ float vert_origin_x = 0;
+ float vert_origin_y = 0;
+ float vert_adv_y = 0;
+
+ String unicode = null;
+
+ // forms the linked list in glyphByUnicode; glyphs appear in the order specified in the font
+ public Glyph next = null;
+
+ Glyph(String name, String unicode, Template t, VectorGraphics.Font f) {
+ if (unicode != null)
+ if (f.glyphByUnicode.get(unicode.substring(0, 1)) == null) {
+ f.glyphByUnicode.put(unicode.substring(0, 1), this);
+ } else {
+ Glyph g;
+ for(g = (Glyph)f.glyphByUnicode.get(unicode.substring(0, 1)); g.next != null; g = g.next);
+ g.next = this;
+ }
+ if (name != null) f.glyphByUnicode.put(name, this);
+ this.unicode = unicode;
+ this.t = t;
+ horiz_adv_x = f.horiz_adv_x;
+ vert_origin_x = f.vert_origin_x;
+ vert_origin_y = f.vert_origin_y;
+ vert_adv_y = f.vert_adv_y;
+ }
+ public void render(DoubleBuffer buf, int x, int y, int fillcolor, int strokecolor, float scaleFactor) {
+ // FEATURE: make b double-buffered for increased performance
+ if (b == null) {
+ b = new Box(t, new org.ibex.util.Vec(), new org.ibex.util.Vec(), null, 0, 0);
+ b.put("absolute", Boolean.TRUE);
+ b.prerender();
+ t = null;
+ }
+ // FIXME
+ b.put("width", new Integer(1000));
+ b.put("height", new Integer(1000));
+ b.fillcolor = fillcolor;
+ b.strokecolor = strokecolor;
+
+ // we toss an extra flip on the ctm so that fonts stick "up" instead of down
+ b.render(0, 0, buf.getWidth(), buf.getHeight(), buf,
+ Affine.flip(false, true).multiply(Affine.scale(scaleFactor, scaleFactor).multiply(Affine.translate(x, y))).multiply(buf.a));
+ }
+ }
+ }
+ */
+
+}
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.graphics;
+
+import org.ibex.js.*;
+import org.ibex.util.*;
+import org.ibex.plat.*;
+
+import org.ibex.core.*; // FIXME
+
+/**
+ * A Surface, as described in the Ibex Reference.
+ *
+ * Platform subclasses should include an inner class subclass of
+ * Surface to return from the Platform._createSurface() method
+ */
+public abstract class Surface extends PixelBuffer implements Task {
+
+ // Static Data ////////////////////////////////////////////////////////////////////////////////
+
+ private static Boolean T = Boolean.TRUE;
+ private static Boolean F = Boolean.FALSE;
+
+ /** all instances of Surface which need to be refreshed by the Scheduler */
+ public static Vec allSurfaces = new Vec();
+
+ /** When set to true, render() should abort as soon as possible and restart the rendering process */
+ public volatile boolean abort = false;
+
+ // these three variables are used to ensure that user resizes trump programmatic resizes
+ public volatile boolean syncRootBoxToSurface = false;
+ public volatile int pendingWidth = 0;
+ public volatile int pendingHeight = 0;
+
+ public static boolean alt = false; ///< true iff the alt button is pressed down
+ public static boolean control = false; ///< true iff the control button is pressed down
+ public static boolean shift = false; ///< true iff the shift button is pressed down
+ public static boolean button1 = false; ///< true iff button 1 is depressed
+ public static boolean button2 = false; ///< true iff button 2 is depressed
+ public static boolean button3 = false; ///< true iff button 3 is depressed
+
+
+ // Instance Data ///////////////////////////////////////////////////////////////////////
+
+ public Box root; ///< The Box at the root of this surface
+ public String cursor = "default"; ///< The active cursor to switch to when syncCursor() is called
+ public int mousex; ///< x position of the mouse
+ public int mousey; ///< y position of the mouse
+ public int _mousex; ///< x position of the mouse FIXME
+ public int _mousey; ///< y position of the mouse FIXME
+ public int newmousex = -1; ///< x position of the mouse, in real time; this lets us collapse Move's
+ public int newmousey = -1; ///< y position of the mouse, in real time; this lets us collapse Move's
+ public boolean minimized = false; ///< True iff this surface is minimized, in real time
+ public boolean maximized = false; ///< True iff this surface is maximized, in real time
+ public boolean unrendered = true; ///< True iff this surface has not yet been rendered
+ DirtyList dirtyRegions = new DirtyList(); ///< Dirty regions on the surface
+
+ // Used For Simulating Clicks and DoubleClicks /////////////////////////////////////////////////
+
+ int last_press_x = Integer.MAX_VALUE; ///< the x-position of the mouse the last time a Press message was enqueued
+ int last_press_y = Integer.MAX_VALUE; ///< the y-position of the mouse the last time a Press message was enqueued
+ static int lastClickButton = 0; ///< the last button to recieve a Click message; used for simulating DoubleClick's
+ static long lastClickTime = 0; ///< the last time a Click message was processed; used for simulating DoubleClick's
+
+
+ // Methods to be overridden by subclasses ///////////////////////////////////////////////////////
+
+ public abstract void toBack(); ///< should push surface to the back of the stacking order
+ public abstract void toFront(); ///< should pull surface to the front of the stacking order
+ public abstract void syncCursor(); ///< set the actual cursor to this.cursor if they do not match
+ public abstract void setInvisible(boolean b); ///< If <tt>b</tt>, make window invisible; otherwise, make it non-invisible.
+ protected abstract void _setMaximized(boolean b); ///< If <tt>b</tt>, maximize the surface; otherwise, un-maximize it.
+ protected abstract void _setMinimized(boolean b); ///< If <tt>b</tt>, minimize the surface; otherwise, un-minimize it.
+ public abstract void setLocation(); ///< Set the surface's x/y position to that of the root box
+ protected abstract void _setSize(int w, int h); ///< set the actual size of the surface
+ public abstract void setTitleBarText(String s); ///< Sets the surface's title bar text, if applicable
+ public abstract void setIcon(Picture i); ///< Sets the surface's title bar text, if applicable
+ public abstract void _dispose(); ///< Destroy the surface
+ public void setMinimumSize(int minx, int miny, boolean resizable) { }
+ protected void setSize(int w, int h) { _setSize(w, h); }
+
+ public static Picture scarImage = null;
+
+ // Helper methods for subclasses ////////////////////////////////////////////////////////////
+
+ protected final void Press(final int button) {
+ last_press_x = mousex;
+ last_press_y = mousey;
+
+ if (button == 1) button1 = true;
+ else if (button == 2) button2 = true;
+ else if (button == 3) button3 = true;
+
+ if (button == 1) new Message("_Press1", T, root);
+ else if (button == 2) new Message("_Press2", T, root);
+ else if (button == 3) {
+ Scheduler.add(new Task() { public void perform() throws JSExn {
+ Platform.clipboardReadEnabled = true;
+ try {
+ root.putAndTriggerTraps("_Press3", T);
+ } finally {
+ Platform.clipboardReadEnabled = false;
+ }
+ }});
+ }
+ }
+
+ protected final void Release(int button) {
+ if (button == 1) button1 = false;
+ else if (button == 2) button2 = false;
+ else if (button == 3) button3 = false;
+
+ if (button == 1) new Message("_Release1", T, root);
+ else if (button == 2) new Message("_Release2", T, root);
+ else if (button == 3) new Message("_Release3", T, root);
+
+ if (Platform.needsAutoClick() && Math.abs(last_press_x - mousex) < 5 && Math.abs(last_press_y - mousey) < 5) Click(button);
+ last_press_x = Integer.MAX_VALUE;
+ last_press_y = Integer.MAX_VALUE;
+ }
+
+ protected final void Click(int button) {
+ if (button == 1) new Message("_Click1", T, root);
+ else if (button == 2) new Message("_Click2", T, root);
+ else if (button == 3) new Message("_Click3", T, root);
+ if (Platform.needsAutoDoubleClick()) {
+ long now = System.currentTimeMillis();
+ if (lastClickButton == button && now - lastClickTime < 350) DoubleClick(button);
+ lastClickButton = button;
+ lastClickTime = now;
+ }
+ }
+
+ /** we enqueue ourselves in the Scheduler when we have a Move message to deal with */
+ private Task mover = new Task() {
+ public void perform() {
+ if (mousex == newmousex && mousey == newmousey) return;
+ int oldmousex = mousex; mousex = newmousex;
+ int oldmousey = mousey; mousey = newmousey;
+ String oldcursor = cursor; cursor = "default";
+ // FIXME: Root (ONLY) gets motion events outside itself (if trapped)
+ if (oldmousex != mousex || oldmousey != mousey)
+ root.putAndTriggerTrapsAndCatchExceptions("_Move", T);
+ if (!cursor.equals(oldcursor)) syncCursor();
+ } };
+
+ /**
+ * Notify Ibex that the mouse has moved. If the mouse leaves the
+ * surface, but the host windowing system does not provide its new
+ * position (for example, a Java MouseListener.mouseExited()
+ * message), the subclass should use (-1,-1).
+ */
+ protected final void Move(final int newmousex, final int newmousey) {
+ this.newmousex = newmousex;
+ this.newmousey = newmousey;
+ Scheduler.add(mover);
+ }
+
+ protected final void HScroll(int pixels) { new Message("_HScroll", new Integer(pixels), root); }
+ protected final void VScroll(int pixels) { new Message("_VScroll", new Integer(pixels), root); }
+ protected final void HScroll(float lines) { new Message("_HScroll", new Float(lines), root); }
+ protected final void VScroll(float lines) { new Message("_VScroll", new Float(lines), root); }
+
+ /** subclasses should invoke this method when the user resizes the window */
+ protected final void SizeChange(final int width, final int height) {
+ if (unrendered || (pendingWidth == width && pendingHeight == height)) return;
+ pendingWidth = width;
+ pendingHeight = height;
+ syncRootBoxToSurface = true;
+ abort = true;
+ Scheduler.renderAll();
+ }
+
+ // FEATURE: can we avoid creating objects here?
+ protected final void PosChange(final int x, final int y) {
+ Scheduler.add(new Task() { public void perform() throws JSExn {
+ root.x = x;
+ root.y = y;
+ root.putAndTriggerTrapsAndCatchExceptions("PosChange", T);
+ }});
+ }
+
+ private final String[] doubleClick = new String[] { null, "_DoubleClick1", "_DoubleClick2", "_DoubleClick3" };
+ protected final void DoubleClick(int button) { new Message(doubleClick[button], T, root); }
+ protected final void KeyPressed(String key) { new Message("_KeyPressed", key, root); }
+ protected final void KeyReleased(String key) { new Message("_KeyReleased", key, root); }
+ protected final void Close() { new Message("Close", T, root); }
+ protected final void Minimized(boolean b) { minimized = b; new Message("Minimized", b ? T : F, root); }
+ protected final void Maximized(boolean b) { maximized = b; new Message("Maximized", b ? T : F, root); }
+ protected final void Focused(boolean b) { new Message("Focused", b ? T : F, root); }
+
+ private boolean scheduled = false;
+ public void Refresh() { if (!scheduled) Scheduler.add(this); scheduled = true; }
+ public void perform() { scheduled = false; Scheduler.renderAll(); }
+
+ public final void setMaximized(boolean b) { if (b != maximized) _setMaximized(maximized = b); }
+ public final void setMinimized(boolean b) { if (b != minimized) _setMinimized(minimized = b); }
+
+
+ // Other Methods ///////////////////////////////////////////////////////////////////////////////
+
+ /** Indicates that the Surface is no longer needed */
+ public final void dispose(boolean quitIfAllSurfacesGone) {
+ if (Log.on) Log.info(this, "disposing " + this);
+ allSurfaces.removeElement(this);
+ _dispose();
+ if (allSurfaces.size() == 0) {
+ if (Log.on) Log.info(this, "exiting because last surface was destroyed");
+ System.exit(0);
+ }
+ }
+
+ public void dirty(int x, int y, int w, int h) {
+ dirtyRegions.dirty(x, y, w, h);
+ Refresh();
+ }
+
+ public static Surface fromBox(Box b) {
+ // FIXME use a hash table here
+ for(int i=0; i<allSurfaces.size(); i++) {
+ Surface s = (Surface)allSurfaces.elementAt(i);
+ if (s.root == b) return s;
+ }
+ return null;
+ }
+
+ public Surface(Box root) {
+ this.root = root;
+ // FIXME: document this in the reference
+ if (!root.test(root.HSHRINK) && root.maxwidth == Integer.MAX_VALUE)
+ root.maxwidth = Platform.getScreenWidth() / 2;
+ if (!root.test(root.VSHRINK) && root.maxheight == Integer.MAX_VALUE)
+ root.maxheight = Platform.getScreenHeight() / 2;
+ root.setWidth(root.minwidth,
+ root.test(root.HSHRINK)
+ ? Math.max(root.minwidth, root.contentwidth)
+ : Math.min(Platform.getScreenWidth(), root.maxwidth));
+ root.setHeight(root.minheight,
+ root.test(root.VSHRINK)
+ ? Math.max(root.minheight, root.contentheight)
+ : Math.min(Platform.getScreenHeight(), root.maxheight));
+ Surface old = fromBox(root);
+ if (old != null) old.dispose(false);
+ else root.removeSelf();
+ Refresh();
+ }
+
+ private static Affine identity = Affine.identity();
+
+ /** runs the prerender() and render() pipelines in the root Box to regenerate the backbuffer, then blits it to the screen */
+ public synchronized void render() {
+ scheduled = false;
+ // make sure the root is properly sized
+ do {
+ abort = false;
+ root.pack();
+ if (syncRootBoxToSurface) {
+ root.setWidth(root.minwidth, pendingWidth);
+ root.setHeight(root.minheight, pendingHeight);
+ syncRootBoxToSurface = false;
+ }
+ int rootwidth = root.test(root.HSHRINK) ? root.contentwidth : root.maxwidth;
+ int rootheight = root.test(root.VSHRINK) ? root.contentheight : root.maxheight;
+ if (rootwidth != root.width || rootheight != root.height) {
+ // dirty the place where the scar used to be and where it is now
+ dirty(0, root.height - scarImage.height, scarImage.width, scarImage.height);
+ dirty(0, rootheight - scarImage.height, scarImage.width, scarImage.height);
+ }
+ root.reflow();
+ setSize(rootwidth, rootheight);
+ /*String oldcursor = cursor;
+ cursor = "default";
+ root.putAndTriggerTrapsAndCatchExceptions("_Move", JS.T);
+ if (!cursor.equals(oldcursor)) syncCursor();*/
+ } while(abort);
+
+ int[][] dirt = dirtyRegions.flush();
+ for(int i = 0; dirt != null && i < dirt.length; i++) {
+ if (dirt[i] == null) continue;
+ int x = dirt[i][0], y = dirt[i][1], w = dirt[i][2], h = dirt[i][3];
+ if (x < 0) x = 0;
+ if (y < 0) y = 0;
+ if (x+w > root.width) w = root.width - x;
+ if (y+h > root.height) h = root.height - y;
+ if (w <= 0 || h <= 0) continue;
+
+ root.render(0, 0, x, y, x + w, y + h, this, identity);
+ drawPicture(scarImage, 0, root.height - scarImage.height, x, y, x+w, y+h);
+
+ if (abort) {
+ // x,y,w,h is only partially reconstructed, so we must be careful not to re-blit it
+ dirtyRegions.dirty(x, y, w, h);
+ // put back all the dirty regions we haven't yet processed (including the current one)
+ for(int j=i; j<dirt.length; j++)
+ if (dirt[j] != null)
+ dirtyRegions.dirty(dirt[j][0], dirt[j][1], dirt[j][2], dirt[j][3]);
+ return;
+ }
+ }
+
+ unrendered = false;
+ }
+
+ // FEATURE: reinstate recycler
+ public class Message implements Task {
+
+ private Box boxContainingMouse;
+ private Object value;
+ public String name;
+
+ Message(String name, Object value, Box boxContainingMouse) {
+ this.boxContainingMouse = boxContainingMouse;
+ this.name = name;
+ this.value = value;
+ Scheduler.add(this);
+ }
+
+ public void perform() {
+ if (name.equals("_KeyPressed")) {
+ String value = (String)this.value;
+ if (value.toLowerCase().endsWith("shift")) shift = true; else if (shift) value = value.toUpperCase();
+ if (value.toLowerCase().equals("alt")) alt = true; else if (alt) value = "A-" + value;
+ if (value.toLowerCase().endsWith("control")) control = true; else if (control) value = "C-" + value;
+ if (value.equals("C-v") || value.equals("A-v")) Platform.clipboardReadEnabled = true;
+ this.value = value;
+ } else if (name.equals("_KeyReleased")) {
+ String value = (String)this.value;
+ if (value.toLowerCase().equals("alt")) alt = false;
+ else if (value.toLowerCase().equals("control")) control = false;
+ else if (value.toLowerCase().equals("shift")) shift = false;
+ this.value = value;
+ } else if (name.equals("_HScroll") || name.equals("_VScroll")) {
+ // FIXME: technically points != pixels
+ if (value instanceof Integer)
+ value = new Float(((Integer)value).intValue() * root.fontSize());
+ }
+ try {
+ boxContainingMouse.putAndTriggerTrapsAndCatchExceptions(name, value);
+ } finally {
+ Platform.clipboardReadEnabled = false;
+ }
+ }
+ public String toString() { return "Message [name=" + name + ", value=" + value + "]"; }
+ }
+
+
+ // Default PixelBuffer implementation /////////////////////////////////////////////////////////
+
+ public static abstract class DoubleBufferedSurface extends Surface {
+
+ public DoubleBufferedSurface(Box root) { super(root); }
+ PixelBuffer backbuffer = Platform.createPixelBuffer(Platform.getScreenWidth(), Platform.getScreenHeight(), this);
+ DirtyList screenDirtyRegions = new DirtyList();
+
+ public void drawPicture(Picture source, int dx, int dy, int cx1, int cy1, int cx2, int cy2) {
+ screenDirtyRegions.dirty(cx1, cy1, cx2 - cx1, cy2 - cy1);
+ backbuffer.drawPicture(source, dx, dy, cx1, cy1, cx2, cy2);
+ }
+
+ public void drawGlyph(Font.Glyph source, int dx, int dy, int cx1, int cy1, int cx2, int cy2, int argb) {
+ screenDirtyRegions.dirty(cx1, cy1, cx2 - cx1, cy2 - cy1);
+ backbuffer.drawGlyph(source, dx, dy, cx1, cy1, cx2, cy2, argb);
+ }
+
+ public void fillTrapezoid(int x1, int x2, int y1, int x3, int x4, int y2, int color) {
+ screenDirtyRegions.dirty(Math.min(x1, x3), y1, Math.max(x2, x4) - Math.min(x1, x3), y2 - y1);
+ backbuffer.fillTrapezoid(x1, x2, y1, x3, x4, y2, color);
+ }
+
+ public void render() {
+ super.render();
+ if (abort) return;
+ int[][] dirt = screenDirtyRegions.flush();
+ for(int i = 0; dirt != null && i < dirt.length; i++) {
+ if (dirt[i] == null) continue;
+ int x = dirt[i][0];
+ int y = dirt[i][1];
+ int w = dirt[i][2];
+ int h = dirt[i][3];
+ if (x < 0) x = 0;
+ if (y < 0) y = 0;
+ if (x+w > root.width) w = root.width - x;
+ if (y+h > root.height) h = root.height - y;
+ if (w <= 0 || h <= 0) continue;
+ if (abort) return;
+ blit(backbuffer, x, y, x, y, w + x, h + y);
+ }
+ }
+
+ /** This is how subclasses signal a 'shallow dirty', indicating that although the backbuffer is valid, the screen is not */
+ public final void Dirty(int x, int y, int w, int h) {
+ screenDirtyRegions.dirty(x, y, w, h);
+ Scheduler.renderAll();
+ }
+
+ public void dirty(int x, int y, int w, int h) {
+ screenDirtyRegions.dirty(x, y, w, h);
+ super.dirty(x, y, w, h);
+ }
+
+ /** copies a region from the doublebuffer to this surface */
+ public abstract void blit(PixelBuffer source, int sx, int sy, int dx, int dy, int dx2, int dy2);
+
+ }
+
+}
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.js;
+
+/**
+ * Constants for the various JavaScript ByteCode operations.
+ *
+ * Each instruction is an opcode and an optional literal literal;
+ * some Tokens are also valid; see Tokens.java
+ */
+interface ByteCodes {
+
+ /** push the literal onto the stack */
+ public static final byte LITERAL = -2;
+
+ /** push a new array onto the stack with length equal to the literal */
+ public static final byte ARRAY = -3;
+
+ /** push an empty object onto the stack */
+ public static final byte OBJECT = -4;
+
+ /** create a new instance; literal is a reference to the corresponding ForthBlock */
+ public static final byte NEWFUNCTION = -5;
+
+ /** if given a non-null argument declare its argument in the current scope and push
+ it to the stack, else, declares the element on the top of the stack and leaves it
+ there */
+ public static final byte DECLARE = -6;
+
+ /** push a reference to the current scope onto the stack */
+ public static final byte TOPSCOPE = -7;
+
+ /** if given a null literal pop two elements off the stack; push stack[-1].get(stack[top])
+ else pop one element off the stack, push stack[top].get(literal) */
+ public static final byte GET = -8;
+
+ /** push stack[-1].get(stack[top]) */
+ public static final byte GET_PRESERVE = -9;
+
+ /** pop two elements off the stack; stack[-2].put(stack[-1], stack[top]); push stack[top] */
+ public static final byte PUT = -10;
+
+ /** literal is a relative address; pop stacktop and jump if the value is true */
+ public static final byte JT = -11;
+
+ /** literal is a relative address; pop stacktop and jump if the value is false */
+ public static final byte JF = -12;
+
+ /** literal is a relative address; jump to it */
+ public static final byte JMP = -13;
+
+ /** discard the top stack element */
+ static public final byte POP = -14;
+
+ /** pop element; call stack[top](stack[-n], stack[-n+1]...) where n is the number of args to the function */
+ public static final byte CALL = -15;
+
+ /** pop an element; push a JS.JSArray containing the keys of the popped element */
+ public static final byte PUSHKEYS = -16;
+
+ /** push the top element down so that (arg) elements are on top of it; all other elements retain ordering */
+ public static final byte SWAP = -17;
+
+ /** execute the bytecode block pointed to by the literal in a fresh scope with parentScope==THIS */
+ public static final byte NEWSCOPE = -18;
+
+ /** execute the bytecode block pointed to by the literal in a fresh scope with parentScope==THIS */
+ public static final byte OLDSCOPE = -19;
+
+ /** push a copy of the top stack element */
+ public static final byte DUP = -20;
+
+ /** a NOP; confers a label upon the following instruction */
+ public static final byte LABEL = -21;
+
+ /** execute the ForthBlock pointed to by the literal until BREAK encountered; push TRUE onto the stack for the first iteration
+ * and FALSE for all subsequent iterations */
+ public static final byte LOOP = -22;
+
+ /** similar effect a a GET followed by a CALL */
+ public static final byte CALLMETHOD = -23;
+
+ /** finish a finally block and carry out whatever instruction initiated the finally block */
+ public static final byte FINALLY_DONE = -24;
+
+ /** finish a finally block and carry out whatever instruction initiated the finally block */
+ public static final byte MAKE_GRAMMAR = -25;
+
+ public static final String[] bytecodeToString = new String[] {
+ "", "", "LITERAL", "ARRAY", "OBJECT", "NEWFUNCTION", "DECLARE", "TOPSCOPE",
+ "GET", "GET_PRESERVE", "PUT", "JT", "JF", "JMP", "POP", "CALL", "PUSHKEYS",
+ "SWAP", "NEWSCOPE", "OLDSCOPE", "DUP", "LABEL", "LOOP", "CALLMETHOD",
+ "FINALLY_DONE", "MAKE_GRAMMAR"
+ };
+}
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.js;
+
+import org.ibex.util.*;
+import java.util.*;
+
+/** Encapsulates a single JS interpreter (ie call stack) */
+class Interpreter implements ByteCodes, Tokens {
+
+
+ // Thread-Interpreter Mapping /////////////////////////////////////////////////////////////////////////
+
+ static Interpreter current() { return (Interpreter)threadToInterpreter.get(Thread.currentThread()); }
+ private static Hashtable threadToInterpreter = new Hashtable();
+
+
+ // Instance members and methods //////////////////////////////////////////////////////////////////////
+
+ int pausecount; ///< the number of times pause() has been invoked; -1 indicates unpauseable
+ JSFunction f = null; ///< the currently-executing JSFunction
+ JSScope scope; ///< the current top-level scope (LIFO stack via NEWSCOPE/OLDSCOPE)
+ Vec stack = new Vec(); ///< the object stack
+ int pc = 0; ///< the program counter
+
+ Interpreter(JSFunction f, boolean pauseable, JSArray args) {
+ stack.push(new Interpreter.CallMarker(this)); // the "root function returned" marker -- f==null
+ this.f = f;
+ this.pausecount = pauseable ? 0 : -1;
+ this.scope = new JSScope(f.parentScope);
+ stack.push(args);
+ }
+
+ /** this is the only synchronization point we need in order to be threadsafe */
+ synchronized Object resume() throws JSExn {
+ Thread t = Thread.currentThread();
+ Interpreter old = (Interpreter)threadToInterpreter.get(t);
+ threadToInterpreter.put(t, this);
+ try {
+ return run();
+ } finally {
+ if (old == null) threadToInterpreter.remove(t);
+ else threadToInterpreter.put(t, old);
+ }
+ }
+
+ static int getLine() {
+ Interpreter c = Interpreter.current();
+ return c == null || c.f == null || c.pc < 0 || c.pc >= c.f.size ? -1 : c.f.line[c.pc];
+ }
+
+ static String getSourceName() {
+ Interpreter c = Interpreter.current();
+ return c == null || c.f == null ? null : c.f.sourceName;
+ }
+
+ private static JSExn je(String s) { return new JSExn(getSourceName() + ":" + getLine() + " " + s); }
+
+ // FIXME: double check the trap logic
+ private Object run() throws JSExn {
+
+ // if pausecount changes after a get/put/call, we know we've been paused
+ final int initialPauseCount = pausecount;
+
+ OUTER: for(;; pc++) {
+ try {
+ if (f == null) return stack.pop();
+ int op = f.op[pc];
+ Object arg = f.arg[pc];
+ if(op == FINALLY_DONE) {
+ FinallyData fd = (FinallyData) stack.pop();
+ if(fd == null) continue OUTER; // NOP
+ if(fd.exn != null) throw fd.exn;
+ op = fd.op;
+ arg = fd.arg;
+ }
+ switch(op) {
+ case LITERAL: stack.push(arg); break;
+ case OBJECT: stack.push(new JS()); break;
+ case ARRAY: stack.push(new JSArray(JS.toNumber(arg).intValue())); break;
+ case DECLARE: scope.declare((String)(arg==null ? stack.peek() : arg)); if(arg != null) stack.push(arg); break;
+ case TOPSCOPE: stack.push(scope); break;
+ case JT: if (JS.toBoolean(stack.pop())) pc += JS.toNumber(arg).intValue() - 1; break;
+ case JF: if (!JS.toBoolean(stack.pop())) pc += JS.toNumber(arg).intValue() - 1; break;
+ case JMP: pc += JS.toNumber(arg).intValue() - 1; break;
+ case POP: stack.pop(); break;
+ case SWAP: {
+ int depth = (arg == null ? 1 : JS.toInt(arg));
+ Object save = stack.elementAt(stack.size() - 1);
+ for(int i=stack.size() - 1; i > stack.size() - 1 - depth; i--)
+ stack.setElementAt(stack.elementAt(i-1), i);
+ stack.setElementAt(save, stack.size() - depth - 1);
+ break; }
+ case DUP: stack.push(stack.peek()); break;
+ case NEWSCOPE: scope = new JSScope(scope); break;
+ case OLDSCOPE: scope = scope.getParentScope(); break;
+ case ASSERT:
+ if (JS.checkAssertions && !JS.toBoolean(stack.pop()))
+ throw je("ibex.assertion.failed" /*FEATURE: line number*/); break;
+ case BITNOT: stack.push(JS.N(~JS.toLong(stack.pop()))); break;
+ case BANG: stack.push(JS.B(!JS.toBoolean(stack.pop()))); break;
+ case NEWFUNCTION: stack.push(((JSFunction)arg)._cloneWithNewParentScope(scope)); break;
+ case LABEL: break;
+
+ case TYPEOF: {
+ Object o = stack.pop();
+ if (o == null) stack.push(null);
+ else if (o instanceof JS) stack.push("object");
+ else if (o instanceof String) stack.push("string");
+ else if (o instanceof Number) stack.push("number");
+ else if (o instanceof Boolean) stack.push("boolean");
+ else throw new Error("this should not happen");
+ break;
+ }
+
+ case PUSHKEYS: {
+ Object o = stack.peek();
+ Enumeration e = ((JS)o).keys();
+ JSArray a = new JSArray();
+ while(e.hasMoreElements()) a.addElement(e.nextElement());
+ stack.push(a);
+ break;
+ }
+
+ case LOOP:
+ stack.push(new LoopMarker(pc, pc > 0 && f.op[pc - 1] == LABEL ? (String)f.arg[pc - 1] : (String)null, scope));
+ stack.push(Boolean.TRUE);
+ break;
+
+ case BREAK:
+ case CONTINUE:
+ while(stack.size() > 0) {
+ Object o = stack.pop();
+ if (o instanceof CallMarker) je("break or continue not within a loop");
+ if (o instanceof TryMarker) {
+ if(((TryMarker)o).finallyLoc < 0) continue; // no finally block, keep going
+ stack.push(new FinallyData(op, arg));
+ scope = ((TryMarker)o).scope;
+ pc = ((TryMarker)o).finallyLoc - 1;
+ continue OUTER;
+ }
+ if (o instanceof LoopMarker) {
+ if (arg == null || arg.equals(((LoopMarker)o).label)) {
+ int loopInstructionLocation = ((LoopMarker)o).location;
+ int endOfLoop = ((Integer)f.arg[loopInstructionLocation]).intValue() + loopInstructionLocation;
+ scope = ((LoopMarker)o).scope;
+ if (op == CONTINUE) { stack.push(o); stack.push(Boolean.FALSE); }
+ pc = op == BREAK ? endOfLoop - 1 : loopInstructionLocation;
+ continue OUTER;
+ }
+ }
+ }
+ throw new Error("CONTINUE/BREAK invoked but couldn't find LoopMarker at " +
+ getSourceName() + ":" + getLine());
+
+ case TRY: {
+ int[] jmps = (int[]) arg;
+ // jmps[0] is how far away the catch block is, jmps[1] is how far away the finally block is
+ // each can be < 0 if the specified block does not exist
+ stack.push(new TryMarker(jmps[0] < 0 ? -1 : pc + jmps[0], jmps[1] < 0 ? -1 : pc + jmps[1], this));
+ break;
+ }
+
+ case RETURN: {
+ Object retval = stack.pop();
+ while(stack.size() > 0) {
+ Object o = stack.pop();
+ if (o instanceof TryMarker) {
+ if(((TryMarker)o).finallyLoc < 0) continue;
+ stack.push(retval);
+ stack.push(new FinallyData(RETURN));
+ scope = ((TryMarker)o).scope;
+ pc = ((TryMarker)o).finallyLoc - 1;
+ continue OUTER;
+ } else if (o instanceof CallMarker) {
+ if (scope instanceof Trap.TrapScope) { // handles return component of a read trap
+ Trap.TrapScope ts = (Trap.TrapScope)scope;
+ if (retval != null && retval instanceof Boolean && ((Boolean)retval).booleanValue())
+ ts.cascadeHappened = true;
+ if (!ts.cascadeHappened) {
+ ts.cascadeHappened = true;
+ Trap t = ts.t.next;
+ while (t != null && t.f.numFormalArgs == 0) t = t.next;
+ if (t == null) {
+ ((JS)ts.t.trapee).put(ts.t.name, ts.val);
+ if (pausecount > initialPauseCount) { pc++; return null; } // we were paused
+ } else {
+ stack.push(o);
+ JSArray args = new JSArray();
+ args.addElement(ts.val);
+ stack.push(args);
+ f = t.f;
+ scope = new Trap.TrapScope(f.parentScope, t, ts.val);
+ pc = -1;
+ continue OUTER;
+ }
+ }
+ }
+ scope = ((CallMarker)o).scope;
+ pc = ((CallMarker)o).pc - 1;
+ f = (JSFunction)((CallMarker)o).f;
+ stack.push(retval);
+ continue OUTER;
+ }
+ }
+ throw new Error("error: RETURN invoked but couldn't find a CallMarker!");
+ }
+
+ case PUT: {
+ Object val = stack.pop();
+ Object key = stack.pop();
+ Object target = stack.peek();
+ if (target == null)
+ throw je("tried to put a value to the " + key + " property on the null value");
+ if (!(target instanceof JS))
+ throw je("tried to put a value to the " + key + " property on a " + target.getClass().getName());
+ if (key == null)
+ throw je("tried to assign \"" + (val==null?"(null)":val.toString()) + "\" to the null key");
+
+ Trap t = null;
+ if (target instanceof JSScope && key.equals("cascade")) {
+ Trap.TrapScope ts = null;
+ JSScope p = (JSScope)target; // search the scope-path for the trap
+ if (target instanceof Trap.TrapScope) {
+ ts = (Trap.TrapScope)target;
+ }
+ else {
+ while (ts == null && p.getParentScope() != null) {
+ p = p.getParentScope();
+ if (p instanceof Trap.TrapScope) {
+ ts = (Trap.TrapScope)p;
+ }
+ }
+ }
+ t = ts.t.next;
+ ts.cascadeHappened = true;
+ while (t != null && t.f.numFormalArgs == 0) t = t.next;
+ if (t == null) { target = ts.t.trapee; key = ts.t.name; }
+
+ } else if (target instanceof Trap.TrapScope && key.equals(((Trap.TrapScope)target).t.name)) {
+ throw je("tried to put to " + key + " inside a trap it owns; use cascade instead");
+
+ } else if (target instanceof JS) {
+ if (target instanceof JSScope) {
+ JSScope p = (JSScope)target; // search the scope-path for the trap
+ t = p.getTrap(key);
+ while (t == null && p.getParentScope() != null) { p = p.getParentScope(); t = p.getTrap(key); }
+ } else {
+ t = ((JS)target).getTrap(key);
+ }
+ while (t != null && t.f.numFormalArgs == 0) t = t.next; // find the first write trap
+ }
+ if (t != null) {
+ stack.push(new CallMarker(this));
+ JSArray args = new JSArray();
+ args.addElement(val);
+ stack.push(args);
+ f = t.f;
+ scope = new Trap.TrapScope(f.parentScope, t, val);
+ pc = -1;
+ break;
+ }
+ ((JS)target).put(key, val);
+ if (pausecount > initialPauseCount) { pc++; return null; } // we were paused
+ stack.push(val);
+ break;
+ }
+
+ case GET:
+ case GET_PRESERVE: {
+ Object o, v;
+ if (op == GET) {
+ v = arg == null ? stack.pop() : arg;
+ o = stack.pop();
+ } else {
+ v = stack.pop();
+ o = stack.peek();
+ stack.push(v);
+ }
+ Object ret = null;
+ if (v == null) throw je("tried to get the null key from " + o);
+ if (o == null) throw je("tried to get property \"" + v + "\" from the null object");
+ if (o instanceof String || o instanceof Number || o instanceof Boolean) {
+ ret = getFromPrimitive(o,v);
+ stack.push(ret);
+ break;
+ } else if (o instanceof JS) {
+ Trap t = null;
+ if (o instanceof Trap.TrapScope && v.equals("cascade")) {
+ t = ((Trap.TrapScope)o).t.next;
+ while (t != null && t.f.numFormalArgs != 0) t = t.next;
+ if (t == null) { v = ((Trap.TrapScope)o).t.name; o = ((Trap.TrapScope)o).t.trapee; }
+
+ } else if (o instanceof JS) {
+ if (o instanceof JSScope) {
+ JSScope p = (JSScope)o; // search the scope-path for the trap
+ t = p.getTrap(v);
+ while (t == null && p.getParentScope() != null) { p = p.getParentScope(); t = p.getTrap(v); }
+ } else {
+ t = ((JS)o).getTrap(v);
+ }
+ while (t != null && t.f.numFormalArgs != 0) t = t.next; // get first read trap
+ }
+ if (t != null) {
+ stack.push(new CallMarker(this));
+ JSArray args = new JSArray();
+ stack.push(args);
+ f = t.f;
+ scope = new Trap.TrapScope(f.parentScope, t, null);
+ ((Trap.TrapScope)scope).cascadeHappened = true;
+ pc = -1;
+ break;
+ }
+ ret = ((JS)o).get(v);
+ if (ret == JS.METHOD) ret = new Stub((JS)o, v);
+ if (pausecount > initialPauseCount) { pc++; return null; } // we were paused
+ stack.push(ret);
+ break;
+ }
+ throw je("tried to get property " + v + " from a " + o.getClass().getName());
+ }
+
+ case CALL: case CALLMETHOD: {
+ int numArgs = JS.toInt(arg);
+ Object method = null;
+ Object ret = null;
+ Object object = stack.pop();
+
+ if (op == CALLMETHOD) {
+ if (object == JS.METHOD) {
+ method = stack.pop();
+ object = stack.pop();
+ } else if (object == null) {
+ Object name = stack.pop();
+ stack.pop();
+ throw new JSExn("function '"+name+"' not found");
+ } else {
+ stack.pop();
+ stack.pop();
+ }
+ }
+ Object[] rest = numArgs > 3 ? new Object[numArgs - 3] : null;
+ for(int i=numArgs - 1; i>2; i--) rest[i-3] = stack.pop();
+ Object a2 = numArgs <= 2 ? null : stack.pop();
+ Object a1 = numArgs <= 1 ? null : stack.pop();
+ Object a0 = numArgs <= 0 ? null : stack.pop();
+
+ if (object instanceof String || object instanceof Number || object instanceof Boolean) {
+ ret = callMethodOnPrimitive(object, method, a0, a1, a2, null, numArgs);
+
+ } else if (object instanceof JSFunction) {
+ // FIXME: use something similar to call0/call1/call2 here
+ JSArray arguments = new JSArray();
+ for(int i=0; i<numArgs; i++) arguments.addElement(i==0?a0:i==1?a1:i==2?a2:rest[i-3]);
+ stack.push(new CallMarker(this));
+ stack.push(arguments);
+ f = (JSFunction)object;
+ scope = new JSScope(f.parentScope);
+ pc = -1;
+ break;
+
+ } else if (object instanceof JS) {
+ JS c = (JS)object;
+ ret = method == null ? c.call(a0, a1, a2, rest, numArgs) : c.callMethod(method, a0, a1, a2, rest, numArgs);
+
+ } else {
+ throw new JSExn("can't call a " + object + " @" + pc + "\n" + f.dump());
+
+ }
+ if (pausecount > initialPauseCount) { pc++; return null; }
+ stack.push(ret);
+ break;
+ }
+
+ case THROW:
+ throw new JSExn(stack.pop(), stack, f, pc, scope);
+
+ /* FIXME
+ case MAKE_GRAMMAR: {
+ final Grammar r = (Grammar)arg;
+ final JSScope final_scope = scope;
+ Grammar r2 = new Grammar() {
+ public int match(String s, int start, Hash v, JSScope scope) throws JSExn {
+ return r.match(s, start, v, final_scope);
+ }
+ public int matchAndWrite(String s, int start, Hash v, JSScope scope, String key) throws JSExn {
+ return r.matchAndWrite(s, start, v, final_scope, key);
+ }
+ public Object call(Object a0, Object a1, Object a2, Object[] rest, int nargs) throws JSExn {
+ Hash v = new Hash();
+ r.matchAndWrite((String)a0, 0, v, final_scope, "foo");
+ return v.get("foo");
+ }
+ };
+ Object obj = stack.pop();
+ if (obj != null && obj instanceof Grammar) r2 = new Grammar.Alternative((Grammar)obj, r2);
+ stack.push(r2);
+ break;
+ }
+ */
+ case ADD_TRAP: case DEL_TRAP: {
+ Object val = stack.pop();
+ Object key = stack.pop();
+ Object obj = stack.peek();
+ // A trap addition/removal
+ JS js = obj instanceof JSScope ? ((JSScope)obj).top() : (JS) obj;
+ if(op == ADD_TRAP) js.addTrap(key, (JSFunction)val);
+ else js.delTrap(key, (JSFunction)val);
+ break;
+ }
+
+ case ASSIGN_SUB: case ASSIGN_ADD: {
+ Object val = stack.pop();
+ Object key = stack.pop();
+ Object obj = stack.peek();
+ // The following setup is VERY important. The generated bytecode depends on the stack
+ // being setup like this (top to bottom) KEY, OBJ, VAL, KEY, OBJ
+ stack.push(key);
+ stack.push(val);
+ stack.push(obj);
+ stack.push(key);
+ break;
+ }
+
+ case ADD: {
+ int count = ((Number)arg).intValue();
+ if(count < 2) throw new Error("this should never happen");
+ if(count == 2) {
+ // common case
+ Object right = stack.pop();
+ Object left = stack.pop();
+ if(left instanceof String || right instanceof String)
+ stack.push(JS.toString(left).concat(JS.toString(right)));
+ else stack.push(JS.N(JS.toDouble(left) + JS.toDouble(right)));
+ } else {
+ Object[] args = new Object[count];
+ while(--count >= 0) args[count] = stack.pop();
+ if(args[0] instanceof String) {
+ StringBuffer sb = new StringBuffer(64);
+ for(int i=0;i<args.length;i++) sb.append(JS.toString(args[i]));
+ stack.push(sb.toString());
+ } else {
+ int numStrings = 0;
+ for(int i=0;i<args.length;i++) if(args[i] instanceof String) numStrings++;
+ if(numStrings == 0) {
+ double d = 0.0;
+ for(int i=0;i<args.length;i++) d += JS.toDouble(args[i]);
+ stack.push(JS.N(d));
+ } else {
+ int i=0;
+ StringBuffer sb = new StringBuffer(64);
+ if(!(args[0] instanceof String || args[1] instanceof String)) {
+ double d=0.0;
+ do {
+ d += JS.toDouble(args[i++]);
+ } while(!(args[i] instanceof String));
+ sb.append(JS.toString(JS.N(d)));
+ }
+ while(i < args.length) sb.append(JS.toString(args[i++]));
+ stack.push(sb.toString());
+ }
+ }
+ }
+ break;
+ }
+
+ default: {
+ Object right = stack.pop();
+ Object left = stack.pop();
+ switch(op) {
+
+ case BITOR: stack.push(JS.N(JS.toLong(left) | JS.toLong(right))); break;
+ case BITXOR: stack.push(JS.N(JS.toLong(left) ^ JS.toLong(right))); break;
+ case BITAND: stack.push(JS.N(JS.toLong(left) & JS.toLong(right))); break;
+
+ case SUB: stack.push(JS.N(JS.toDouble(left) - JS.toDouble(right))); break;
+ case MUL: stack.push(JS.N(JS.toDouble(left) * JS.toDouble(right))); break;
+ case DIV: stack.push(JS.N(JS.toDouble(left) / JS.toDouble(right))); break;
+ case MOD: stack.push(JS.N(JS.toDouble(left) % JS.toDouble(right))); break;
+
+ case LSH: stack.push(JS.N(JS.toLong(left) << JS.toLong(right))); break;
+ case RSH: stack.push(JS.N(JS.toLong(left) >> JS.toLong(right))); break;
+ case URSH: stack.push(JS.N(JS.toLong(left) >>> JS.toLong(right))); break;
+
+ case LT: case LE: case GT: case GE: {
+ if (left == null) left = JS.N(0);
+ if (right == null) right = JS.N(0);
+ int result = 0;
+ if (left instanceof String || right instanceof String) {
+ result = left.toString().compareTo(right.toString());
+ } else {
+ result = (int)java.lang.Math.ceil(JS.toDouble(left) - JS.toDouble(right));
+ }
+ stack.push(JS.B((op == LT && result < 0) || (op == LE && result <= 0) ||
+ (op == GT && result > 0) || (op == GE && result >= 0)));
+ break;
+ }
+
+ case EQ:
+ case NE: {
+ Object l = left;
+ Object r = right;
+ boolean ret;
+ if (l == null) { Object tmp = r; r = l; l = tmp; }
+ if (l == null && r == null) ret = true;
+ else if (r == null) ret = false; // l != null, so its false
+ else if (l instanceof Boolean) ret = JS.B(JS.toBoolean(r)).equals(l);
+ else if (l instanceof Number) ret = JS.toNumber(r).doubleValue() == JS.toNumber(l).doubleValue();
+ else if (l instanceof String) ret = r != null && l.equals(r.toString());
+ else ret = l.equals(r);
+ stack.push(JS.B(op == EQ ? ret : !ret)); break;
+ }
+
+ default: throw new Error("unknown opcode " + op);
+ } }
+ }
+
+ } catch(JSExn e) {
+ while(stack.size() > 0) {
+ Object o = stack.pop();
+ if (o instanceof CatchMarker || o instanceof TryMarker) {
+ boolean inCatch = o instanceof CatchMarker;
+ if(inCatch) {
+ o = stack.pop();
+ if(((TryMarker)o).finallyLoc < 0) continue; // no finally block, keep going
+ }
+ if(!inCatch && ((TryMarker)o).catchLoc >= 0) {
+ // run the catch block, this will implicitly run the finally block, if it exists
+ stack.push(o);
+ stack.push(catchMarker);
+ stack.push(e.getObject());
+ f = ((TryMarker)o).f;
+ scope = ((TryMarker)o).scope;
+ pc = ((TryMarker)o).catchLoc - 1;
+ continue OUTER;
+ } else {
+ stack.push(new FinallyData(e));
+ f = ((TryMarker)o).f;
+ scope = ((TryMarker)o).scope;
+ pc = ((TryMarker)o).finallyLoc - 1;
+ continue OUTER;
+ }
+ }
+ }
+ throw e;
+ } // end try/catch
+ } // end for
+ }
+
+
+
+ // Markers //////////////////////////////////////////////////////////////////////
+
+ public static class CallMarker {
+ int pc;
+ JSScope scope;
+ JSFunction f;
+ public CallMarker(Interpreter cx) { pc = cx.pc + 1; scope = cx.scope; f = cx.f; }
+ }
+
+ public static class CatchMarker { }
+ private static CatchMarker catchMarker = new CatchMarker();
+
+ public static class LoopMarker {
+ public int location;
+ public String label;
+ public JSScope scope;
+ public LoopMarker(int location, String label, JSScope scope) {
+ this.location = location;
+ this.label = label;
+ this.scope = scope;
+ }
+ }
+ public static class TryMarker {
+ public int catchLoc;
+ public int finallyLoc;
+ public JSScope scope;
+ public JSFunction f;
+ public TryMarker(int catchLoc, int finallyLoc, Interpreter cx) {
+ this.catchLoc = catchLoc;
+ this.finallyLoc = finallyLoc;
+ this.scope = cx.scope;
+ this.f = cx.f;
+ }
+ }
+ public static class FinallyData {
+ public int op;
+ public Object arg;
+ public JSExn exn;
+ public FinallyData(int op) { this(op,null); }
+ public FinallyData(int op, Object arg) { this.op = op; this.arg = arg; }
+ public FinallyData(JSExn exn) { this.exn = exn; } // Just throw this exn
+ }
+
+
+ // Operations on Primitives //////////////////////////////////////////////////////////////////////
+
+ static Object callMethodOnPrimitive(Object o, Object method, Object arg0, Object arg1, Object arg2, Object[] rest, int alength) throws JSExn {
+ if (method == null || !(method instanceof String) || "".equals(method))
+ throw new JSExn("attempt to call a non-existant method on a primitive");
+
+ if (o instanceof Number) {
+final String ccSwitch0 = (String)(method); SUCCESS:do { switch(ccSwitch0.length()) {
+case 7: { switch(ccSwitch0.charAt(0)) { case 't': if ("toFixed".equals(ccSwitch0)) { if (true) do { throw new JSExn("toFixed() not implemented");
+ } while(false); break SUCCESS; } break; }; break; } case 8: { switch(ccSwitch0.charAt(0)) { case 't': if ("toString".equals(ccSwitch0)) { if (true) do { {
+int radix = alength >= 1 ? JS.toInt(arg0) : 10;
+return Long.toString(((Number)o).longValue(),radix);
+}
+ } while(false); break SUCCESS; } break; }; break; } case 11: { switch(ccSwitch0.charAt(0)) { case 't': if ("toPrecision".equals(ccSwitch0)) { if (true) do { throw new JSExn("toPrecision() not implemented");
+ } while(false); break SUCCESS; } break; }; break; } case 13: { switch(ccSwitch0.charAt(0)) { case 't': if ("toExponential".equals(ccSwitch0)) { if (true) do { throw new JSExn("toExponential() not implemented");
+ } while(false); break SUCCESS; } break; }; break; } } /* switch */ } while(false); /* OUTER */
+ } else if (o instanceof Boolean) {
+ // No methods for Booleans
+ throw new JSExn("attempt to call a method on a Boolean");
+ }
+
+ String s = JS.toString(o);
+ int slength = s.length();
+final String ccSwitch1 = (String)(method); SUCCESS:do { switch(ccSwitch1.length()) {
+case 5: { switch(ccSwitch1.charAt(0)) { case 'm': if ("match".equals(ccSwitch1)) { if (true) do { return JSRegexp.stringMatch(s,arg0);
+ } while(false); break SUCCESS; } break; case 's': { switch(ccSwitch1.charAt(1)) { case 'l': if ("slice".equals(ccSwitch1)) { if (true) do { {
+int a = alength >= 1 ? JS.toInt(arg0) : 0;
+int b = alength >= 2 ? JS.toInt(arg1) : slength;
+if (a < 0) a = slength + a;
+if (b < 0) b = slength + b;
+if (a < 0) a = 0;
+if (b < 0) b = 0;
+if (a > slength) a = slength;
+if (b > slength) b = slength;
+if (a > b) return "";
+return s.substring(a,b);
+}
+ } while(false); break SUCCESS; } break; case 'p': if ("split".equals(ccSwitch1)) { if (true) do { return JSRegexp.stringSplit(s,arg0,arg1,alength);
+ } while(false); break SUCCESS; } break; } break; } }; break; } case 6: { switch(ccSwitch1.charAt(0)) { case 'c': { switch(ccSwitch1.charAt(1)) { case 'h': if ("charAt".equals(ccSwitch1)) { if (true) do { {
+int p = alength >= 1 ? JS.toInt(arg0) : 0;
+if (p < 0 || p >= slength) return "";
+return s.substring(p,p+1);
+}
+ } while(false); break SUCCESS; } break; case 'o': if ("concat".equals(ccSwitch1)) { if (true) do { {
+StringBuffer sb = new StringBuffer(slength*2).append(s);
+for(int i=0;i<alength;i++) sb.append(i==0?arg0:i==1?arg1:i==2?arg2:rest[i-3]);
+return sb.toString();
+}
+ } while(false); break SUCCESS; } break; } break; } case 's': { switch(ccSwitch1.charAt(1)) { case 'e': if ("search".equals(ccSwitch1)) { if (true) do { return JSRegexp.stringSearch(s,arg0);
+ } while(false); break SUCCESS; } break; case 'u': if ("substr".equals(ccSwitch1)) { if (true) do { {
+int start = alength >= 1 ? JS.toInt(arg0) : 0;
+int len = alength >= 2 ? JS.toInt(arg1) : Integer.MAX_VALUE;
+if (start < 0) start = slength + start;
+if (start < 0) start = 0;
+if (len < 0) len = 0;
+if (len > slength - start) len = slength - start;
+if (len <= 0) return "";
+return s.substring(start,start+len);
+}
+ } while(false); break SUCCESS; } break; } break; } }; break; } case 7: { switch(ccSwitch1.charAt(0)) { case 'i': if ("indexOf".equals(ccSwitch1)) { if (true) do { {
+String search = alength >= 1 ? arg0.toString() : "null";
+int start = alength >= 2 ? JS.toInt(arg1) : 0;
+
+return JS.N(s.indexOf(search,start));
+}
+ } while(false); break SUCCESS; } break; case 'r': if ("replace".equals(ccSwitch1)) { if (true) do { return JSRegexp.stringReplace(s,arg0,arg1);
+ } while(false); break SUCCESS; } break; }; break; } case 8: { switch(ccSwitch1.charAt(0)) { case 't': if ("toString".equals(ccSwitch1)) { if (true) do { return s;
+ } while(false); break SUCCESS; } break; }; break; } case 9: { switch(ccSwitch1.charAt(0)) { case 's': if ("substring".equals(ccSwitch1)) { if (true) do { {
+int a = alength >= 1 ? JS.toInt(arg0) : 0;
+int b = alength >= 2 ? JS.toInt(arg1) : slength;
+if (a > slength) a = slength;
+if (b > slength) b = slength;
+if (a < 0) a = 0;
+if (b < 0) b = 0;
+if (a > b) { int tmp = a; a = b; b = tmp; }
+return s.substring(a,b);
+}
+ } while(false); break SUCCESS; } break; }; break; } case 10: { switch(ccSwitch1.charAt(0)) { case 'c': if ("charCodeAt".equals(ccSwitch1)) { if (true) do { {
+int p = alength >= 1 ? JS.toInt(arg0) : 0;
+if (p < 0 || p >= slength) return JS.N(Double.NaN);
+return JS.N(s.charAt(p));
+}
+ } while(false); break SUCCESS; } break; }; break; } case 11: { switch(ccSwitch1.charAt(0)) { case 'l': if ("lastIndexOf".equals(ccSwitch1)) { if (true) do { {
+String search = alength >= 1 ? arg0.toString() : "null";
+int start = alength >= 2 ? JS.toInt(arg1) : 0;
+
+return JS.N(s.lastIndexOf(search,start));
+}
+ } while(false); break SUCCESS; } break; case 't': { switch(ccSwitch1.charAt(1)) { case 'o': { switch(ccSwitch1.charAt(2)) { case 'L': if ("toLowerCase".equals(ccSwitch1)) { if (true) do { return s.toLowerCase();
+ } while(false); break SUCCESS; } break; case 'U': if ("toUpperCase".equals(ccSwitch1)) { if (true) do { return s.toUpperCase();
+ } while(false); break SUCCESS; } break; } break; } } break; } }; break; } } /* switch */ } while(false); /* OUTER */
+ throw new JSExn("Attempted to call non-existent method: " + method);
+ }
+
+ static Object getFromPrimitive(Object o, Object key) throws JSExn {
+ boolean returnJS = false;
+ if (o instanceof Boolean) {
+ throw new JSExn("Booleans do not have properties");
+ } else if (o instanceof Number) {
+ if (key.equals("toPrecision") || key.equals("toExponential") || key.equals("toFixed"))
+ returnJS = true;
+ }
+ if (!returnJS) {
+ // the string stuff applies to everything
+ String s = o.toString();
+
+ // this is sort of ugly, but this list should never change
+ // These should provide a complete (enough) implementation of the ECMA-262 String object
+
+final String ccSwitch2 = (String)(key); SUCCESS:do { switch(ccSwitch2.length()) {
+case 5: { switch(ccSwitch2.charAt(0)) { case 'm': if ("match".equals(ccSwitch2)) { if (true) do { returnJS = true; break;
+ } while(false); break SUCCESS; } break; case 's': { switch(ccSwitch2.charAt(1)) { case 'l': if ("slice".equals(ccSwitch2)) { if (true) do { returnJS = true; break;
+ } while(false); break SUCCESS; } break; case 'p': if ("split".equals(ccSwitch2)) { if (true) do { returnJS = true; break;
+ } while(false); break SUCCESS; } break; } break; } }; break; } case 6: { switch(ccSwitch2.charAt(0)) { case 'c': { switch(ccSwitch2.charAt(1)) { case 'h': if ("charAt".equals(ccSwitch2)) { if (true) do { returnJS = true; break;
+ } while(false); break SUCCESS; } break; case 'o': if ("concat".equals(ccSwitch2)) { if (true) do { returnJS = true; break;
+ } while(false); break SUCCESS; } break; } break; } case 'l': if ("length".equals(ccSwitch2)) { if (true) do { return JS.N(s.length());
+ } while(false); break SUCCESS; } break; case 's': { switch(ccSwitch2.charAt(1)) { case 'e': if ("seatch".equals(ccSwitch2)) { if (true) do { returnJS = true; break;
+ } while(false); break SUCCESS; } break; case 'u': if ("substr".equals(ccSwitch2)) { if (true) do { returnJS = true; break;
+ } while(false); break SUCCESS; } break; } break; } }; break; } case 7: { switch(ccSwitch2.charAt(0)) { case 'i': if ("indexOf".equals(ccSwitch2)) { if (true) do { returnJS = true; break;
+ } while(false); break SUCCESS; } break; case 'r': if ("replace".equals(ccSwitch2)) { if (true) do { returnJS = true; break;
+ } while(false); break SUCCESS; } break; }; break; } case 8: { switch(ccSwitch2.charAt(0)) { case 't': if ("toString".equals(ccSwitch2)) { if (true) do { returnJS = true; break;
+ } while(false); break SUCCESS; } break; }; break; } case 9: { switch(ccSwitch2.charAt(0)) { case 's': if ("substring".equals(ccSwitch2)) { if (true) do { returnJS = true; break;
+ } while(false); break SUCCESS; } break; }; break; } case 10: { switch(ccSwitch2.charAt(0)) { case 'c': if ("charCodeAt".equals(ccSwitch2)) { if (true) do { returnJS = true; break;
+ } while(false); break SUCCESS; } break; }; break; } case 11: { switch(ccSwitch2.charAt(0)) { case 'l': if ("lastIndexOf".equals(ccSwitch2)) { if (true) do { returnJS = true; break;
+ } while(false); break SUCCESS; } break; case 't': { switch(ccSwitch2.charAt(1)) { case 'o': { switch(ccSwitch2.charAt(2)) { case 'L': if ("toLowerCase".equals(ccSwitch2)) { if (true) do { returnJS = true; break;
+ } while(false); break SUCCESS; } break; case 'U': if ("toUpperCase".equals(ccSwitch2)) { if (true) do { returnJS = true; break;
+ } while(false); break SUCCESS; } break; } break; } } break; } }; break; } } /* switch */ } while(false); /* OUTER */
+ }
+ if (returnJS) {
+ final Object target = o;
+ final String method = key.toString();
+ return new JS() {
+ public Object call(Object a0, Object a1, Object a2, Object[] rest, int nargs) throws JSExn {
+ if (nargs > 2) throw new JSExn("cannot call that method with that many arguments");
+ return callMethodOnPrimitive(target, method, a0, a1, a2, rest, nargs);
+ }
+ };
+ }
+ return null;
+ }
+
+ private static class Stub extends JS {
+ private Object method;
+ JS obj;
+ public Stub(JS obj, Object method) { this.obj = obj; this.method = method; }
+ public Object call(Object a0, Object a1, Object a2, Object[] rest, int nargs) throws JSExn {
+ return ((JS)obj).callMethod(method, a0, a1, a2, rest, nargs);
+ }
+ }
+}
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.js;
+
+import org.ibex.util.*;
+import java.io.*;
+import java.util.*;
+
+/** The minimum set of functionality required for objects which are manipulated by JavaScript */
+public class JS extends org.ibex.util.BalancedTree {
+
+ public static boolean checkAssertions = false;
+
+ public static final Object METHOD = new Object();
+ public final JS unclone() { return _unclone(); }
+ public Enumeration keys() throws JSExn { return entries == null ? emptyEnumeration : entries.keys(); }
+ public Object get(Object key) throws JSExn { return entries == null ? null : entries.get(key, null); }
+ public void put(Object key, Object val) throws JSExn { (entries==null?entries=new Hash():entries).put(key,null,val); }
+ public Object callMethod(Object method, Object a0, Object a1, Object a2, Object[] rest, int nargs) throws JSExn {
+ throw new JSExn("attempted to call the null value (method "+method+")");
+ }
+ public Object call(Object a0, Object a1, Object a2, Object[] rest, int nargs) throws JSExn {
+ throw new JSExn("you cannot call this object (class=" + this.getClass().getName() +")");
+ }
+
+ JS _unclone() { return this; }
+ public static class Cloneable extends JS {
+ public Object jsclone() throws JSExn {
+ return new Clone(this);
+ }
+ }
+
+ public static class Clone extends JS.Cloneable {
+ protected JS.Cloneable clonee = null;
+ JS _unclone() { return clonee.unclone(); }
+ public JS.Cloneable getClonee() { return clonee; }
+ public Clone(JS.Cloneable clonee) { this.clonee = clonee; }
+ public boolean equals(Object o) {
+ if (!(o instanceof JS)) return false;
+ return unclone() == ((JS)o).unclone();
+ }
+ public Enumeration keys() throws JSExn { return clonee.keys(); }
+ public Object get(Object key) throws JSExn { return clonee.get(key); }
+ public void put(Object key, Object val) throws JSExn { clonee.put(key, val); }
+ public Object callMethod(Object method, Object a0, Object a1, Object a2, Object[] rest, int nargs) throws JSExn {
+ return clonee.callMethod(method, a0, a1, a2, rest, nargs);
+ }
+ public Object call(Object a0, Object a1, Object a2, Object[] rest, int nargs) throws JSExn {
+ return clonee.call(a0, a1, a2, rest, nargs);
+ }
+ }
+
+ // Static Interpreter Control Methods ///////////////////////////////////////////////////////////////
+
+ /** log a message with the current JavaScript sourceName/line */
+ public static void log(Object message) { info(message); }
+ public static void debug(Object message) { Log.debug(Interpreter.getSourceName() + ":" + Interpreter.getLine(), message); }
+ public static void info(Object message) { Log.info(Interpreter.getSourceName() + ":" + Interpreter.getLine(), message); }
+ public static void warn(Object message) { Log.warn(Interpreter.getSourceName() + ":" + Interpreter.getLine(), message); }
+ public static void error(Object message) { Log.error(Interpreter.getSourceName() + ":" + Interpreter.getLine(), message); }
+
+ public static class NotPauseableException extends Exception { NotPauseableException() { } }
+
+ /** returns a callback which will restart the context; expects a value to be pushed onto the stack when unpaused */
+ public static UnpauseCallback pause() throws NotPauseableException {
+ Interpreter i = Interpreter.current();
+ if (i.pausecount == -1) throw new NotPauseableException();
+ i.pausecount++;
+ return new JS.UnpauseCallback(i);
+ }
+
+ public static class UnpauseCallback implements Task {
+ Interpreter i;
+ UnpauseCallback(Interpreter i) { this.i = i; }
+ public void perform() throws JSExn { unpause(null); }
+ public void unpause(Object o) throws JSExn {
+ // FIXME: if o instanceof JSExn, throw it into the JSworld
+ i.stack.push(o);
+ i.resume();
+ }
+ }
+
+
+
+ // Static Helper Methods ///////////////////////////////////////////////////////////////////////////////////
+
+ /** coerce an object to a Boolean */
+ public static boolean toBoolean(Object o) {
+ if (o == null) return false;
+ if (o instanceof Boolean) return ((Boolean)o).booleanValue();
+ if (o instanceof Long) return ((Long)o).longValue() != 0;
+ if (o instanceof Integer) return ((Integer)o).intValue() != 0;
+ if (o instanceof Number) {
+ double d = ((Number) o).doubleValue();
+ // NOTE: d == d is a test for NaN. It should be faster than Double.isNaN()
+ return d != 0.0 && d == d;
+ }
+ if (o instanceof String) return ((String)o).length() != 0;
+ return true;
+ }
+
+ /** coerce an object to a Long */
+ public static long toLong(Object o) { return toNumber(o).longValue(); }
+
+ /** coerce an object to an Int */
+ public static int toInt(Object o) { return toNumber(o).intValue(); }
+
+ /** coerce an object to a Double */
+ public static double toDouble(Object o) { return toNumber(o).doubleValue(); }
+
+ /** coerce an object to a Number */
+ public static Number toNumber(Object o) {
+ if (o == null) return ZERO;
+ if (o instanceof Number) return ((Number)o);
+
+ // NOTE: There are about 3 pages of rules in ecma262 about string to number conversions
+ // We aren't even close to following all those rules. We probably never will be.
+ if (o instanceof String) try { return N((String)o); } catch (NumberFormatException e) { return N(Double.NaN); }
+ if (o instanceof Boolean) return ((Boolean)o).booleanValue() ? N(1) : ZERO;
+ throw new Error("toNumber() got object of type " + o.getClass().getName() + " which we don't know how to handle");
+ }
+
+ /** coerce an object to a String */
+ public static String toString(Object o) {
+ if(o == null) return "null";
+ if(o instanceof String) return (String) o;
+ if(o instanceof Integer || o instanceof Long || o instanceof Boolean) return o.toString();
+ if(o instanceof JSArray) return o.toString();
+ if(o instanceof JSDate) return o.toString();
+ if(o instanceof Double || o instanceof Float) {
+ double d = ((Number)o).doubleValue();
+ if((int)d == d) return Integer.toString((int)d);
+ return o.toString();
+ }
+ throw new RuntimeException("can't coerce "+o+" [" + o.getClass().getName() + "] to type String.");
+ }
+
+ // Instance Methods ////////////////////////////////////////////////////////////////////
+
+ public static final Integer ZERO = new Integer(0);
+
+ // this gets around a wierd fluke in the Java type checking rules for ?..:
+ public static final Object T = Boolean.TRUE;
+ public static final Object F = Boolean.FALSE;
+
+ public static final Boolean B(boolean b) { return b ? Boolean.TRUE : Boolean.FALSE; }
+ public static final Boolean B(int i) { return i==0 ? Boolean.FALSE : Boolean.TRUE; }
+ public static final Number N(String s) { return s.indexOf('.') == -1 ? N(Integer.parseInt(s)) : new Double(s); }
+ public static final Number N(double d) { return (int)d == d ? N((int)d) : new Double(d); }
+ public static final Number N(long l) { return N((int)l); }
+
+ private static final Integer[] smallIntCache = new Integer[65535 / 4];
+ private static final Integer[] largeIntCache = new Integer[65535 / 4];
+ public static final Number N(int i) {
+ Integer ret = null;
+ int idx = i + smallIntCache.length / 2;
+ if (idx < smallIntCache.length && idx > 0) {
+ ret = smallIntCache[idx];
+ if (ret != null) return ret;
+ }
+ else ret = largeIntCache[Math.abs(idx % largeIntCache.length)];
+ if (ret == null || ret.intValue() != i) {
+ ret = new Integer(i);
+ if (idx < smallIntCache.length && idx > 0) smallIntCache[idx] = ret;
+ else largeIntCache[Math.abs(idx % largeIntCache.length)] = ret;
+ }
+ return ret;
+ }
+
+ private static Enumeration emptyEnumeration = new Enumeration() {
+ public boolean hasMoreElements() { return false; }
+ public Object nextElement() { throw new NoSuchElementException(); }
+ };
+
+ private Hash entries = null;
+
+ public static JS fromReader(String sourceName, int firstLine, Reader sourceCode) throws IOException {
+ return JSFunction._fromReader(sourceName, firstLine, sourceCode);
+ }
+
+ // HACK: caller can't know if the argument is a JSFunction or not...
+ public static JS cloneWithNewParentScope(JS j, JSScope s) {
+ return ((JSFunction)j)._cloneWithNewParentScope(s);
+ }
+
+
+ // Trap support //////////////////////////////////////////////////////////////////////////////
+
+ /** override and return true to allow placing traps on this object.
+ * if isRead true, this is a read trap, otherwise write trap
+ **/
+ protected boolean isTrappable(Object name, boolean isRead) { return true; }
+
+ /** performs a put, triggering traps if present; traps are run in an unpauseable interpreter */
+ public void putAndTriggerTraps(Object key, Object value) throws JSExn {
+ Trap t = getTrap(key);
+ if (t != null) t.invoke(value);
+ else put(key, value);
+ }
+
+ /** performs a get, triggering traps if present; traps are run in an unpauseable interpreter */
+ public Object getAndTriggerTraps(Object key) throws JSExn {
+ Trap t = getTrap(key);
+ if (t != null) return t.invoke();
+ else return get(key);
+ }
+
+ /** retrieve a trap from the entries hash */
+ protected final Trap getTrap(Object key) {
+ return entries == null ? null : (Trap)entries.get(key, Trap.class);
+ }
+
+ /** retrieve a trap from the entries hash */
+ protected final void putTrap(Object key, Trap value) {
+ if (entries == null) entries = new Hash();
+ entries.put(key, Trap.class, value);
+ }
+
+ /** adds a trap, avoiding duplicates */
+ protected final void addTrap(Object name, JSFunction f) throws JSExn {
+ if (f.numFormalArgs > 1) throw new JSExn("traps must take either one argument (write) or no arguments (read)");
+ boolean isRead = f.numFormalArgs == 0;
+ if (!isTrappable(name, isRead)) throw new JSExn("not allowed "+(isRead?"read":"write")+" trap on property: "+name);
+ for(Trap t = getTrap(name); t != null; t = t.next) if (t.f == f) return;
+ putTrap(name, new Trap(this, name.toString(), f, (Trap)getTrap(name)));
+ }
+
+ /** deletes a trap, if present */
+ protected final void delTrap(Object name, JSFunction f) {
+ Trap t = (Trap)getTrap(name);
+ if (t == null) return;
+ if (t.f == f) { putTrap(t.name, t.next); return; }
+ for(; t.next != null; t = t.next) if (t.next.f == f) { t.next = t.next.next; return; }
+ }
+
+
+}
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.js;
+
+import org.ibex.util.*;
+import java.util.*;
+
+/** A JavaScript JSArray */
+public class JSArray extends JS {
+ private static final Object NULL = new Object();
+
+ public JSArray() { }
+ public JSArray(int size) { setSize(size); }
+
+ private static int intVal(Object o) {
+ if (o instanceof Number) {
+ int intVal = ((Number)o).intValue();
+ if (intVal == ((Number)o).doubleValue()) return intVal;
+ return Integer.MIN_VALUE;
+ }
+ if (!(o instanceof String)) return Integer.MIN_VALUE;
+ String s = (String)o;
+ for(int i=0; i<s.length(); i++) if (s.charAt(i) < '0' || s.charAt(i) > '9') return Integer.MIN_VALUE;
+ return Integer.parseInt(s);
+ }
+
+ public Object callMethod(Object method, Object a0, Object a1, Object a2, Object[] rest, int nargs) throws JSExn {
+final String ccSwitch0 = (String)(method); SUCCESS:do { switch(ccSwitch0.length()) {
+case 3: { switch(ccSwitch0.charAt(0)) { case 'p': if ("pop".equals(ccSwitch0)) { if (true) do { {
+int oldSize = size();
+if(oldSize == 0) return null;
+return removeElementAt(oldSize-1);
+}
+ } while(false); break SUCCESS; } break; }; break; } case 4: { switch(ccSwitch0.charAt(0)) { case 'j': if ("join".equals(ccSwitch0)) { if (true) do {
+return join(nargs == 0 ? "," : JS.toString(a0));
+ } while(false); break SUCCESS; } break; case 'p': if ("push".equals(ccSwitch0)) { if (true) do { {
+int oldSize = size();
+for(int i=0; i<nargs; i++) insertElementAt(i==0?a0:i==1?a1:i==2?a2:rest[i-3],oldSize+i);
+return N(oldSize + nargs);
+}
+ } while(false); break SUCCESS; } break; case 's': if ("sort".equals(ccSwitch0)) { if (true) do {
+return sort(nargs < 1 ? null : a0);
+ } while(false); break SUCCESS; } break; }; break; } case 5: { switch(ccSwitch0.charAt(0)) { case 's': { switch(ccSwitch0.charAt(1)) { case 'h': if ("shift".equals(ccSwitch0)) { if (true) do {
+if(length() == 0) return null;
+return removeElementAt(0);
+ } while(false); break SUCCESS; } break; case 'l': if ("slice".equals(ccSwitch0)) { if (true) do {
+int start = toInt(nargs < 1 ? null : a0);
+int end = nargs < 2 ? length() : toInt(a1);
+return slice(start, end);
+ } while(false); break SUCCESS; } break; } break; } }; break; } case 6: { switch(ccSwitch0.charAt(0)) { case 's': if ("splice".equals(ccSwitch0)) { if (true) do {
+JSArray array = new JSArray();
+for(int i=0; i<nargs; i++) array.addElement(i==0?a0:i==1?a1:i==2?a2:rest[i-3]);
+return splice(array);
+ } while(false); break SUCCESS; } break; }; break; } case 7: { switch(ccSwitch0.charAt(0)) { case 'r': if ("reverse".equals(ccSwitch0)) { if (true) do { return reverse();
+ } while(false); break SUCCESS; } break; case 'u': if ("unshift".equals(ccSwitch0)) { if (true) do {
+for(int i=0; i<nargs; i++) insertElementAt(i==0?a0:i==1?a1:i==2?a2:rest[i-3],i);
+return N(size());
+ } while(false); break SUCCESS; } break; }; break; } case 8: { switch(ccSwitch0.charAt(0)) { case 't': if ("toString".equals(ccSwitch0)) { if (true) do { return join(",");
+ } while(false); break SUCCESS; } break; }; break; } } /* switch */ } while(false); /* OUTER */
+ return super.callMethod(method, a0, a1, a2, rest, nargs);
+ }
+
+ public Object get(Object key) throws JSExn {
+ int i = intVal(key);
+ if (i != Integer.MIN_VALUE) {
+ if (i < 0 || i >= size()) return null;
+ return elementAt(i);
+ }
+final String ccSwitch1 = (String)(key); SUCCESS:do { switch(ccSwitch1.length()) {
+case 3: { switch(ccSwitch1.charAt(0)) { case 'p': if ("pop".equals(ccSwitch1)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; }; break; } case 4: { switch(ccSwitch1.charAt(0)) { case 'j': if ("join".equals(ccSwitch1)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 'p': if ("push".equals(ccSwitch1)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 's': if ("sort".equals(ccSwitch1)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; }; break; } case 5: { switch(ccSwitch1.charAt(0)) { case 's': { switch(ccSwitch1.charAt(1)) { case 'h': if ("shift".equals(ccSwitch1)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 'l': if ("slice".equals(ccSwitch1)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; } break; } }; break; } case 6: { switch(ccSwitch1.charAt(0)) { case 'l': if ("length".equals(ccSwitch1)) { if (true) do { return N(size());
+ } while(false); break SUCCESS; } break; case 's': if ("splice".equals(ccSwitch1)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; }; break; } case 7: { switch(ccSwitch1.charAt(0)) { case 'r': if ("reverse".equals(ccSwitch1)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 'u': if ("unshift".equals(ccSwitch1)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; }; break; } case 8: { switch(ccSwitch1.charAt(0)) { case 't': if ("toString".equals(ccSwitch1)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; }; break; } } /* switch */ } while(false); /* OUTER */
+ return super.get(key);
+ }
+
+ public void put(Object key, Object val) throws JSExn {
+ if (key.equals("length")) setSize(toInt(val));
+ int i = intVal(key);
+ if (i == Integer.MIN_VALUE)
+ super.put(key, val);
+ else {
+ int oldSize = size();
+ if(i < oldSize) {
+ setElementAt(val,i);
+ } else {
+ if(i > oldSize) setSize(i);
+ insertElementAt(val,i);
+ }
+ }
+ }
+
+ public Enumeration keys() {
+ return new Enumeration() {
+ private int n = size();
+ public boolean hasMoreElements() { return n > 0; }
+ public Object nextElement() {
+ if(n == 0) throw new NoSuchElementException();
+ return new Integer(--n);
+ }
+ };
+ }
+
+ public final void setSize(int newSize) {
+ // FEATURE: This could be done a lot more efficiently in BalancedTree
+ int oldSize = size();
+ for(int i=oldSize;i<newSize;i++) insertElementAt(null,i);
+ for(int i=oldSize-1;i>=newSize;i--) removeElementAt(i);
+ }
+
+ public final int length() { return size(); }
+ public final Object elementAt(int i) {
+ if(i < 0 || i >= size()) throw new ArrayIndexOutOfBoundsException(i);
+ Object o = getNode(i);
+ return o == NULL ? null : o;
+ }
+ public final void addElement(Object o) {
+ insertNode(size(),o==null ? NULL : o);
+ }
+ public final void setElementAt(Object o, int i) {
+ if(i < 0 || i >= size()) throw new ArrayIndexOutOfBoundsException(i);
+ replaceNode(i,o==null ? NULL : o);
+ }
+ public final void insertElementAt(Object o, int i) {
+ if(i < 0 || i > size()) throw new ArrayIndexOutOfBoundsException(i);
+ insertNode(i,o==null ? NULL : o);
+ }
+ public final Object removeElementAt(int i) {
+ if(i < 0 || i >= size()) throw new ArrayIndexOutOfBoundsException(i);
+ Object o = deleteNode(i);
+ return o == NULL ? null : o;
+ }
+
+ public final int size() { return treeSize(); }
+ public String typeName() { return "array"; }
+
+ private Object join(String sep) {
+ int length = size();
+ if(length == 0) return "";
+ StringBuffer sb = new StringBuffer(64);
+ int i=0;
+ while(true) {
+ Object o = elementAt(i);
+ if(o != null) sb.append(JS.toString(o));
+ if(++i == length) break;
+ sb.append(sep);
+ }
+ return sb.toString();
+ }
+
+ // FEATURE: Implement this more efficiently
+ private Object reverse() {
+ int size = size();
+ if(size < 2) return this;
+ Vec vec = toVec();
+ clear();
+ for(int i=size-1,j=0;i>=0;i--,j++) insertElementAt(vec.elementAt(i),j);
+ return this;
+ }
+
+ private Object slice(int start, int end) {
+ int length = length();
+ if(start < 0) start = length+start;
+ if(end < 0) end = length+end;
+ if(start < 0) start = 0;
+ if(end < 0) end = 0;
+ if(start > length) start = length;
+ if(end > length) end = length;
+ JSArray a = new JSArray(end-start);
+ for(int i=0;i<end-start;i++)
+ a.setElementAt(elementAt(start+i),i);
+ return a;
+ }
+
+ private static final Vec.CompareFunc defaultSort = new Vec.CompareFunc() {
+ public int compare(Object a, Object b) {
+ return JS.toString(a).compareTo(JS.toString(b));
+ }
+ };
+ private Object sort(Object tmp) throws JSExn {
+ Vec vec = toVec();
+ if(tmp instanceof JS) {
+ final JSArray funcArgs = new JSArray(2);
+ final JS jsFunc = (JS) tmp;
+ vec.sort(new Vec.CompareFunc() {
+ public int compare(Object a, Object b) {
+ try {
+ funcArgs.setElementAt(a,0);
+ funcArgs.setElementAt(b,1);
+ return JS.toInt(jsFunc.call(a, b, null, null, 2));
+ } catch (Exception e) {
+ // FIXME
+ throw new JSRuntimeExn(e.toString());
+ }
+ }
+ });
+ } else {
+ vec.sort(defaultSort);
+ }
+ setFromVec(vec);
+ return this;
+ }
+
+ private Object splice(JSArray args) {
+ int oldLength = length();
+ int start = JS.toInt(args.length() < 1 ? null : args.elementAt(0));
+ int deleteCount = JS.toInt(args.length() < 2 ? null : args.elementAt(1));
+ int newCount = args.length() - 2;
+ if(newCount < 0) newCount = 0;
+ if(start < 0) start = oldLength+start;
+ if(start < 0) start = 0;
+ if(start > oldLength) start = oldLength;
+ if(deleteCount < 0) deleteCount = 0;
+ if(deleteCount > oldLength-start) deleteCount = oldLength-start;
+ int newLength = oldLength - deleteCount + newCount;
+ int lengthChange = newLength - oldLength;
+ JSArray ret = new JSArray(deleteCount);
+ for(int i=0;i<deleteCount;i++)
+ ret.setElementAt(elementAt(start+i),i);
+ if(lengthChange > 0) {
+ setSize(newLength);
+ for(int i=newLength-1;i>=start+newCount;i--)
+ setElementAt(elementAt(i-lengthChange),i);
+ } else if(lengthChange < 0) {
+ for(int i=start+newCount;i<newLength;i++)
+ setElementAt(elementAt(i-lengthChange),i);
+ setSize(newLength);
+ }
+ for(int i=0;i<newCount;i++)
+ setElementAt(args.elementAt(i+2),start+i);
+ return ret;
+ }
+
+ protected Vec toVec() {
+ int count = size();
+ Vec vec = new Vec();
+ vec.setSize(count);
+ for(int i=0;i<count;i++) {
+ Object o = getNode(i);
+ vec.setElementAt(o == NULL ? null : o,i);
+ }
+ return vec;
+ }
+
+ protected void setFromVec(Vec vec) {
+ int count = vec.size();
+ clear();
+ for(int i=0;i<count;i++) {
+ Object o = vec.elementAt(i);
+ insertNode(i,o==null ? NULL : o);
+ }
+ }
+
+ public String toString() { return JS.toString(join(",")); }
+}
--- /dev/null
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * The contents of this file are subject to the Netscape Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/NPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1997-1999 Netscape Communications Corporation. All
+ * Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ * Mike McCabe
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU Public License (the "GPL"), in which case the
+ * provisions of the GPL are applicable instead of those above.
+ * If you wish to allow use of your version of this file only
+ * under the terms of the GPL and not to allow others to use your
+ * version of this file under the NPL, indicate your decision by
+ * deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL. If you do not delete
+ * the provisions above, a recipient may use your version of this
+ * file under either the NPL or the GPL.
+ */
+
+package org.ibex.js;
+
+import java.text.DateFormat;
+
+/**
+ * This class implements the Date native object.
+ * See ECMA 15.9.
+ * @author Mike McCabe
+ * @author Adam Megacz (many modifications
+ */
+public class JSDate extends JS {
+
+ public JSDate() {
+ if (thisTimeZone == null) {
+ // j.u.TimeZone is synchronized, so setting class statics from it
+ // should be OK.
+ thisTimeZone = java.util.TimeZone.getDefault();
+ LocalTZA = thisTimeZone.getRawOffset();
+ }
+ }
+
+ public String toString() { return date_format(date, FORMATSPEC_FULL); }
+
+ public Object callMethod(Object method, Object a0, Object a1, Object a2, Object[] rest, int nargs) throws JSExn {
+ switch(nargs) {
+ case 0: {
+final String ccSwitch0 = (String)(method); SUCCESS:do { switch(ccSwitch0.length()) {
+case 6: { switch(ccSwitch0.charAt(0)) { case 'g': if ("getDay".equals(ccSwitch0)) { if (true) do { return N(WeekDay(LocalTime(date)));
+ } while(false); break SUCCESS; } break; }; break; } case 7: { switch(ccSwitch0.charAt(0)) { case 'g': { switch(ccSwitch0.charAt(1)) { case 'e': { switch(ccSwitch0.charAt(2)) { case 't': { switch(ccSwitch0.charAt(3)) { case 'D': if ("getDate".equals(ccSwitch0)) { if (true) do { return N(DateFromTime(LocalTime(date)));
+ } while(false); break SUCCESS; } break; case 'T': if ("getTime".equals(ccSwitch0)) { if (true) do { return N(this.date);
+ } while(false); break SUCCESS; } break; case 'Y': if ("getYear".equals(ccSwitch0)) { if (true) do { return N(getYear(date));
+ } while(false); break SUCCESS; } break; } break; } } break; } } break; } case 'v': if ("valueOf".equals(ccSwitch0)) { if (true) do { return N(this.date);
+ } while(false); break SUCCESS; } break; }; break; } case 8: { switch(ccSwitch0.charAt(0)) { case 'g': { switch(ccSwitch0.charAt(1)) { case 'e': { switch(ccSwitch0.charAt(2)) { case 't': { switch(ccSwitch0.charAt(3)) { case 'H': if ("getHours".equals(ccSwitch0)) { if (true) do { return N(HourFromTime(LocalTime(date)));
+ } while(false); break SUCCESS; } break; case 'M': if ("getMonth".equals(ccSwitch0)) { if (true) do { return N(MonthFromTime(LocalTime(date)));
+ } while(false); break SUCCESS; } break; } break; } } break; } } break; } case 't': if ("toString".equals(ccSwitch0)) { if (true) do { return date_format(date, FORMATSPEC_FULL);
+ } while(false); break SUCCESS; } break; }; break; } case 9: { switch(ccSwitch0.charAt(0)) { case 'g': if ("getUTCDay".equals(ccSwitch0)) { if (true) do { return N(WeekDay(date));
+ } while(false); break SUCCESS; } break; }; break; } case 10: { switch(ccSwitch0.charAt(0)) { case 'g': { switch(ccSwitch0.charAt(1)) { case 'e': { switch(ccSwitch0.charAt(2)) { case 't': { switch(ccSwitch0.charAt(3)) { case 'M': if ("getMinutes".equals(ccSwitch0)) { if (true) do { return N(MinFromTime(LocalTime(date)));
+ } while(false); break SUCCESS; } break; case 'S': if ("getSeconds".equals(ccSwitch0)) { if (true) do { return N(SecFromTime(LocalTime(date)));
+ } while(false); break SUCCESS; } break; case 'U': if ("getUTCDate".equals(ccSwitch0)) { if (true) do { return N(DateFromTime(date));
+ } while(false); break SUCCESS; } break; } break; } } break; } } break; } }; break; } case 11: { switch(ccSwitch0.charAt(0)) { case 'g': { switch(ccSwitch0.charAt(1)) { case 'e': { switch(ccSwitch0.charAt(2)) { case 't': { switch(ccSwitch0.charAt(3)) { case 'F': if ("getFullYear".equals(ccSwitch0)) { if (true) do { return N(YearFromTime(LocalTime(date)));
+ } while(false); break SUCCESS; } break; case 'U': { switch(ccSwitch0.charAt(4)) { case 'T': { switch(ccSwitch0.charAt(5)) { case 'C': { switch(ccSwitch0.charAt(6)) { case 'H': if ("getUTCHours".equals(ccSwitch0)) { if (true) do { return N(HourFromTime(date));
+ } while(false); break SUCCESS; } break; case 'M': if ("getUTCMonth".equals(ccSwitch0)) { if (true) do { return N(MonthFromTime(date));
+ } while(false); break SUCCESS; } break; } break; } } break; } } break; } } break; } } break; } } break; } case 't': if ("toUTCString".equals(ccSwitch0)) { if (true) do { return toUTCString(date);
+ } while(false); break SUCCESS; } break; }; break; } case 12: { switch(ccSwitch0.charAt(0)) { case 't': { switch(ccSwitch0.charAt(1)) { case 'o': { switch(ccSwitch0.charAt(2)) { case 'D': if ("toDateString".equals(ccSwitch0)) { if (true) do { return date_format(date, FORMATSPEC_DATE);
+ } while(false); break SUCCESS; } break; case 'T': if ("toTimeString".equals(ccSwitch0)) { if (true) do { return date_format(date, FORMATSPEC_TIME);
+ } while(false); break SUCCESS; } break; } break; } } break; } }; break; } case 13: { switch(ccSwitch0.charAt(0)) { case 'g': { switch(ccSwitch0.charAt(1)) { case 'e': { switch(ccSwitch0.charAt(2)) { case 't': { switch(ccSwitch0.charAt(3)) { case 'U': { switch(ccSwitch0.charAt(4)) { case 'T': { switch(ccSwitch0.charAt(5)) { case 'C': { switch(ccSwitch0.charAt(6)) { case 'M': if ("getUTCMinutes".equals(ccSwitch0)) { if (true) do { return N(MinFromTime(date));
+ } while(false); break SUCCESS; } break; case 'S': if ("getUTCSeconds".equals(ccSwitch0)) { if (true) do { return N(SecFromTime(date));
+ } while(false); break SUCCESS; } break; } break; } } break; } } break; } } break; } } break; } } break; } }; break; } case 14: { switch(ccSwitch0.charAt(0)) { case 'g': if ("getUTCFullYear".equals(ccSwitch0)) { if (true) do { return N(YearFromTime(date));
+ } while(false); break SUCCESS; } break; case 't': if ("toLocaleString".equals(ccSwitch0)) { if (true) do { return toLocaleString(date);
+ } while(false); break SUCCESS; } break; }; break; } case 15: { switch(ccSwitch0.charAt(0)) { case 'g': if ("getMilliseconds".equals(ccSwitch0)) { if (true) do { return N(msFromTime(LocalTime(date)));
+ } while(false); break SUCCESS; } break; }; break; } case 17: { switch(ccSwitch0.charAt(0)) { case 'g': if ("getTimezoneOffset".equals(ccSwitch0)) { if (true) do { return N(getTimezoneOffset(date));
+ } while(false); break SUCCESS; } break; }; break; } case 18: { switch(ccSwitch0.charAt(0)) { case 'g': if ("getUTCMilliseconds".equals(ccSwitch0)) { if (true) do { return N(msFromTime(date));
+ } while(false); break SUCCESS; } break; case 't': { switch(ccSwitch0.charAt(1)) { case 'o': { switch(ccSwitch0.charAt(2)) { case 'L': { switch(ccSwitch0.charAt(3)) { case 'o': { switch(ccSwitch0.charAt(4)) { case 'c': { switch(ccSwitch0.charAt(5)) { case 'a': { switch(ccSwitch0.charAt(6)) { case 'l': { switch(ccSwitch0.charAt(7)) { case 'e': { switch(ccSwitch0.charAt(8)) { case 'D': if ("toLocaleDateString".equals(ccSwitch0)) { if (true) do { return toLocaleDateString(date);
+ } while(false); break SUCCESS; } break; case 'T': if ("toLocaleTimeString".equals(ccSwitch0)) { if (true) do { return toLocaleTimeString(date);
+ } while(false); break SUCCESS; } break; } break; } } break; } } break; } } break; } } break; } } break; } } break; } } break; } }; break; } } /* switch */ } while(false); /* OUTER */
+ return super.callMethod(method, a0, a1, a2, rest, nargs);
+ }
+ case 1: {
+final String ccSwitch1 = (String)(method); SUCCESS:do { switch(ccSwitch1.length()) {
+case 7: { switch(ccSwitch1.charAt(0)) { case 's': { switch(ccSwitch1.charAt(1)) { case 'e': { switch(ccSwitch1.charAt(2)) { case 't': { switch(ccSwitch1.charAt(3)) { case 'T': if ("setTime".equals(ccSwitch1)) { if (true) do { return N(this.setTime(toDouble(a0)));
+ } while(false); break SUCCESS; } break; case 'Y': if ("setYear".equals(ccSwitch1)) { if (true) do { return N(this.setYear(toDouble(a0)));
+ } while(false); break SUCCESS; } break; } break; } } break; } } break; } }; break; } } /* switch */ } while(false); /* OUTER */
+ // fall through
+ }
+ default: {
+ Object[] args = new Object[nargs];
+ for(int i=0; i<nargs; i++) args[i] = i==0 ? a0 : i==1 ? a1 : i==2 ? a2 : rest[i-3];
+final String ccSwitch2 = (String)(method); SUCCESS:do { switch(ccSwitch2.length()) {
+case 7: { switch(ccSwitch2.charAt(0)) { case 's': if ("setDate".equals(ccSwitch2)) { if (true) do { return N(this.makeDate(args, 1, true));
+ } while(false); break SUCCESS; } break; }; break; } case 8: { switch(ccSwitch2.charAt(0)) { case 's': { switch(ccSwitch2.charAt(1)) { case 'e': { switch(ccSwitch2.charAt(2)) { case 't': { switch(ccSwitch2.charAt(3)) { case 'H': if ("setHours".equals(ccSwitch2)) { if (true) do { return N(this.makeTime(args, 4, true));
+ } while(false); break SUCCESS; } break; case 'M': if ("setMonth".equals(ccSwitch2)) { if (true) do { return N(this.makeDate(args, 2, true));
+ } while(false); break SUCCESS; } break; } break; } } break; } } break; } }; break; } case 10: { switch(ccSwitch2.charAt(0)) { case 's': { switch(ccSwitch2.charAt(1)) { case 'e': { switch(ccSwitch2.charAt(2)) { case 't': { switch(ccSwitch2.charAt(3)) { case 'M': if ("setMinutes".equals(ccSwitch2)) { if (true) do { return N(this.makeTime(args, 3, true));
+ } while(false); break SUCCESS; } break; case 'S': if ("setSeconds".equals(ccSwitch2)) { if (true) do { return N(this.makeTime(args, 2, true));
+ } while(false); break SUCCESS; } break; case 'U': if ("setUTCDate".equals(ccSwitch2)) { if (true) do { return N(this.makeDate(args, 1, false));
+ } while(false); break SUCCESS; } break; } break; } } break; } } break; } }; break; } case 11: { switch(ccSwitch2.charAt(0)) { case 's': { switch(ccSwitch2.charAt(1)) { case 'e': { switch(ccSwitch2.charAt(2)) { case 't': { switch(ccSwitch2.charAt(3)) { case 'F': if ("setFullYear".equals(ccSwitch2)) { if (true) do { return N(this.makeDate(args, 3, true));
+ } while(false); break SUCCESS; } break; case 'U': { switch(ccSwitch2.charAt(4)) { case 'T': { switch(ccSwitch2.charAt(5)) { case 'C': { switch(ccSwitch2.charAt(6)) { case 'H': if ("setUTCHours".equals(ccSwitch2)) { if (true) do { return N(this.makeTime(args, 4, false));
+ } while(false); break SUCCESS; } break; case 'M': if ("setUTCMonth".equals(ccSwitch2)) { if (true) do { return N(this.makeDate(args, 2, false));
+ } while(false); break SUCCESS; } break; } break; } } break; } } break; } } break; } } break; } } break; } }; break; } case 13: { switch(ccSwitch2.charAt(0)) { case 's': { switch(ccSwitch2.charAt(1)) { case 'e': { switch(ccSwitch2.charAt(2)) { case 't': { switch(ccSwitch2.charAt(3)) { case 'U': { switch(ccSwitch2.charAt(4)) { case 'T': { switch(ccSwitch2.charAt(5)) { case 'C': { switch(ccSwitch2.charAt(6)) { case 'M': if ("setUTCMinutes".equals(ccSwitch2)) { if (true) do { return N(this.makeTime(args, 3, false));
+ } while(false); break SUCCESS; } break; case 'S': if ("setUTCSeconds".equals(ccSwitch2)) { if (true) do { return N(this.makeTime(args, 2, false));
+ } while(false); break SUCCESS; } break; } break; } } break; } } break; } } break; } } break; } } break; } }; break; } case 14: { switch(ccSwitch2.charAt(0)) { case 's': if ("setUTCFullYear".equals(ccSwitch2)) { if (true) do { return N(this.makeDate(args, 3, false));
+ } while(false); break SUCCESS; } break; }; break; } case 15: { switch(ccSwitch2.charAt(0)) { case 's': if ("setMilliseconds".equals(ccSwitch2)) { if (true) do { return N(this.makeTime(args, 1, true));
+ } while(false); break SUCCESS; } break; }; break; } case 18: { switch(ccSwitch2.charAt(0)) { case 's': if ("setUTCMilliseconds".equals(ccSwitch2)) { if (true) do { return N(this.makeTime(args, 1, false));
+ } while(false); break SUCCESS; } break; }; break; } } /* switch */ } while(false); /* OUTER */
+ }
+ }
+ return super.callMethod(method, a0, a1, a2, rest, nargs);
+ }
+
+ public Object get(Object key) throws JSExn {
+final String ccSwitch3 = (String)(key); SUCCESS:do { switch(ccSwitch3.length()) {
+case 6: { switch(ccSwitch3.charAt(0)) { case 'g': if ("getDay".equals(ccSwitch3)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; }; break; } case 7: { switch(ccSwitch3.charAt(0)) { case 'g': { switch(ccSwitch3.charAt(1)) { case 'e': { switch(ccSwitch3.charAt(2)) { case 't': { switch(ccSwitch3.charAt(3)) { case 'D': if ("getDate".equals(ccSwitch3)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 'T': if ("getTime".equals(ccSwitch3)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 'Y': if ("getYear".equals(ccSwitch3)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; } break; } } break; } } break; } case 's': { switch(ccSwitch3.charAt(1)) { case 'e': { switch(ccSwitch3.charAt(2)) { case 't': { switch(ccSwitch3.charAt(3)) { case 'D': if ("setDate".equals(ccSwitch3)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 'T': if ("setTime".equals(ccSwitch3)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 'Y': if ("setYear".equals(ccSwitch3)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; } break; } } break; } } break; } case 'v': if ("valueOf".equals(ccSwitch3)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; }; break; } case 8: { switch(ccSwitch3.charAt(0)) { case 'g': { switch(ccSwitch3.charAt(1)) { case 'e': { switch(ccSwitch3.charAt(2)) { case 't': { switch(ccSwitch3.charAt(3)) { case 'H': if ("getHours".equals(ccSwitch3)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 'M': if ("getMonth".equals(ccSwitch3)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; } break; } } break; } } break; } case 's': { switch(ccSwitch3.charAt(1)) { case 'e': { switch(ccSwitch3.charAt(2)) { case 't': { switch(ccSwitch3.charAt(3)) { case 'H': if ("setHours".equals(ccSwitch3)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 'M': if ("setMonth".equals(ccSwitch3)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; } break; } } break; } } break; } case 't': if ("toString".equals(ccSwitch3)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; }; break; } case 9: { switch(ccSwitch3.charAt(0)) { case 'g': if ("getUTCDay".equals(ccSwitch3)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; }; break; } case 10: { switch(ccSwitch3.charAt(0)) { case 'g': { switch(ccSwitch3.charAt(1)) { case 'e': { switch(ccSwitch3.charAt(2)) { case 't': { switch(ccSwitch3.charAt(3)) { case 'M': if ("getMinutes".equals(ccSwitch3)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 'S': if ("getSeconds".equals(ccSwitch3)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 'U': if ("getUTCDate".equals(ccSwitch3)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; } break; } } break; } } break; } case 's': { switch(ccSwitch3.charAt(1)) { case 'e': { switch(ccSwitch3.charAt(2)) { case 't': { switch(ccSwitch3.charAt(3)) { case 'M': if ("setMinutes".equals(ccSwitch3)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 'S': if ("setSeconds".equals(ccSwitch3)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 'U': if ("setUTCDate".equals(ccSwitch3)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; } break; } } break; } } break; } }; break; } case 11: { switch(ccSwitch3.charAt(0)) { case 'g': { switch(ccSwitch3.charAt(1)) { case 'e': { switch(ccSwitch3.charAt(2)) { case 't': { switch(ccSwitch3.charAt(3)) { case 'F': if ("getFullYear".equals(ccSwitch3)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 'U': { switch(ccSwitch3.charAt(4)) { case 'T': { switch(ccSwitch3.charAt(5)) { case 'C': { switch(ccSwitch3.charAt(6)) { case 'H': if ("getUTCHours".equals(ccSwitch3)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 'M': if ("getUTCMonth".equals(ccSwitch3)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; } break; } } break; } } break; } } break; } } break; } } break; } case 's': { switch(ccSwitch3.charAt(1)) { case 'e': { switch(ccSwitch3.charAt(2)) { case 't': { switch(ccSwitch3.charAt(3)) { case 'F': if ("setFullYear".equals(ccSwitch3)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 'U': { switch(ccSwitch3.charAt(4)) { case 'T': { switch(ccSwitch3.charAt(5)) { case 'C': { switch(ccSwitch3.charAt(6)) { case 'H': if ("setUTCHours".equals(ccSwitch3)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 'M': if ("setUTCMonth".equals(ccSwitch3)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; } break; } } break; } } break; } } break; } } break; } } break; } case 't': if ("toUTCString".equals(ccSwitch3)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; }; break; } case 12: { switch(ccSwitch3.charAt(0)) { case 't': { switch(ccSwitch3.charAt(1)) { case 'o': { switch(ccSwitch3.charAt(2)) { case 'D': if ("toDateString".equals(ccSwitch3)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 'T': if ("toTimeString".equals(ccSwitch3)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; } break; } } break; } }; break; } case 13: { switch(ccSwitch3.charAt(0)) { case 'g': { switch(ccSwitch3.charAt(1)) { case 'e': { switch(ccSwitch3.charAt(2)) { case 't': { switch(ccSwitch3.charAt(3)) { case 'U': { switch(ccSwitch3.charAt(4)) { case 'T': { switch(ccSwitch3.charAt(5)) { case 'C': { switch(ccSwitch3.charAt(6)) { case 'M': if ("getUTCMinutes".equals(ccSwitch3)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 'S': if ("getUTCSeconds".equals(ccSwitch3)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; } break; } } break; } } break; } } break; } } break; } } break; } case 's': { switch(ccSwitch3.charAt(1)) { case 'e': { switch(ccSwitch3.charAt(2)) { case 't': { switch(ccSwitch3.charAt(3)) { case 'U': { switch(ccSwitch3.charAt(4)) { case 'T': { switch(ccSwitch3.charAt(5)) { case 'C': { switch(ccSwitch3.charAt(6)) { case 'M': if ("setUTCMinutes".equals(ccSwitch3)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 'S': if ("setUTCSeconds".equals(ccSwitch3)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; } break; } } break; } } break; } } break; } } break; } } break; } }; break; } case 14: { switch(ccSwitch3.charAt(0)) { case 'g': if ("getUTCFullYear".equals(ccSwitch3)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 's': if ("setUTCFullYear".equals(ccSwitch3)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 't': if ("toLocaleString".equals(ccSwitch3)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; }; break; } case 15: { switch(ccSwitch3.charAt(0)) { case 'g': if ("getMilliseconds".equals(ccSwitch3)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 's': if ("setMilliseconds".equals(ccSwitch3)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; }; break; } case 17: { switch(ccSwitch3.charAt(0)) { case 'g': if ("getTimezoneOffset".equals(ccSwitch3)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; }; break; } case 18: { switch(ccSwitch3.charAt(0)) { case 'g': if ("getUTCMilliseconds".equals(ccSwitch3)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 's': if ("setUTCMilliseconds".equals(ccSwitch3)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 't': { switch(ccSwitch3.charAt(1)) { case 'o': { switch(ccSwitch3.charAt(2)) { case 'L': { switch(ccSwitch3.charAt(3)) { case 'o': { switch(ccSwitch3.charAt(4)) { case 'c': { switch(ccSwitch3.charAt(5)) { case 'a': { switch(ccSwitch3.charAt(6)) { case 'l': { switch(ccSwitch3.charAt(7)) { case 'e': { switch(ccSwitch3.charAt(8)) { case 'D': if ("toLocaleDateString".equals(ccSwitch3)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 'T': if ("toLocaleTimeString".equals(ccSwitch3)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; } break; } } break; } } break; } } break; } } break; } } break; } } break; } } break; } }; break; } } /* switch */ } while(false); /* OUTER */
+ return super.get(key);
+ }
+
+ /* ECMA helper functions */
+
+ private static final double HalfTimeDomain = 8.64e15;
+ private static final double HoursPerDay = 24.0;
+ private static final double MinutesPerHour = 60.0;
+ private static final double SecondsPerMinute = 60.0;
+ private static final double msPerSecond = 1000.0;
+ private static final double MinutesPerDay = (HoursPerDay * MinutesPerHour);
+ private static final double SecondsPerDay = (MinutesPerDay * SecondsPerMinute);
+ private static final double SecondsPerHour = (MinutesPerHour * SecondsPerMinute);
+ private static final double msPerDay = (SecondsPerDay * msPerSecond);
+ private static final double msPerHour = (SecondsPerHour * msPerSecond);
+ private static final double msPerMinute = (SecondsPerMinute * msPerSecond);
+
+ private static double Day(double t) {
+ return java.lang.Math.floor(t / msPerDay);
+ }
+
+ private static double TimeWithinDay(double t) {
+ double result;
+ result = t % msPerDay;
+ if (result < 0)
+ result += msPerDay;
+ return result;
+ }
+
+ private static int DaysInYear(int y) {
+ if (y % 4 == 0 && (y % 100 != 0 || y % 400 == 0))
+ return 366;
+ else
+ return 365;
+ }
+
+
+ /* math here has to be f.p, because we need
+ * floor((1968 - 1969) / 4) == -1
+ */
+ private static double DayFromYear(double y) {
+ return ((365 * ((y)-1970) + java.lang.Math.floor(((y)-1969)/4.0)
+ - java.lang.Math.floor(((y)-1901)/100.0) + java.lang.Math.floor(((y)-1601)/400.0)));
+ }
+
+ private static double TimeFromYear(double y) {
+ return DayFromYear(y) * msPerDay;
+ }
+
+ private static int YearFromTime(double t) {
+ int lo = (int) java.lang.Math.floor((t / msPerDay) / 366) + 1970;
+ int hi = (int) java.lang.Math.floor((t / msPerDay) / 365) + 1970;
+ int mid;
+
+ /* above doesn't work for negative dates... */
+ if (hi < lo) {
+ int temp = lo;
+ lo = hi;
+ hi = temp;
+ }
+
+ /* Use a simple binary search algorithm to find the right
+ year. This seems like brute force... but the computation
+ of hi and lo years above lands within one year of the
+ correct answer for years within a thousand years of
+ 1970; the loop below only requires six iterations
+ for year 270000. */
+ while (hi > lo) {
+ mid = (hi + lo) / 2;
+ if (TimeFromYear(mid) > t) {
+ hi = mid - 1;
+ } else {
+ if (TimeFromYear(mid) <= t) {
+ int temp = mid + 1;
+ if (TimeFromYear(temp) > t) {
+ return mid;
+ }
+ lo = mid + 1;
+ }
+ }
+ }
+ return lo;
+ }
+
+ private static boolean InLeapYear(double t) {
+ return DaysInYear(YearFromTime(t)) == 366;
+ }
+
+ private static int DayWithinYear(double t) {
+ int year = YearFromTime(t);
+ return (int) (Day(t) - DayFromYear(year));
+ }
+ /*
+ * The following array contains the day of year for the first day of
+ * each month, where index 0 is January, and day 0 is January 1.
+ */
+
+ private static double DayFromMonth(int m, boolean leap) {
+ int day = m * 30;
+
+ if (m >= 7) { day += m / 2 - 1; }
+ else if (m >= 2) { day += (m - 1) / 2 - 1; }
+ else { day += m; }
+
+ if (leap && m >= 2) { ++day; }
+
+ return day;
+ }
+
+ private static int MonthFromTime(double t) {
+ int d, step;
+
+ d = DayWithinYear(t);
+
+ if (d < (step = 31))
+ return 0;
+
+ // Originally coded as step += (InLeapYear(t) ? 29 : 28);
+ // but some jits always returned 28!
+ if (InLeapYear(t))
+ step += 29;
+ else
+ step += 28;
+
+ if (d < step)
+ return 1;
+ if (d < (step += 31))
+ return 2;
+ if (d < (step += 30))
+ return 3;
+ if (d < (step += 31))
+ return 4;
+ if (d < (step += 30))
+ return 5;
+ if (d < (step += 31))
+ return 6;
+ if (d < (step += 31))
+ return 7;
+ if (d < (step += 30))
+ return 8;
+ if (d < (step += 31))
+ return 9;
+ if (d < (step += 30))
+ return 10;
+ return 11;
+ }
+
+ private static int DateFromTime(double t) {
+ int d, step, next;
+
+ d = DayWithinYear(t);
+ if (d <= (next = 30))
+ return d + 1;
+ step = next;
+
+ // Originally coded as next += (InLeapYear(t) ? 29 : 28);
+ // but some jits always returned 28!
+ if (InLeapYear(t))
+ next += 29;
+ else
+ next += 28;
+
+ if (d <= next)
+ return d - step;
+ step = next;
+ if (d <= (next += 31))
+ return d - step;
+ step = next;
+ if (d <= (next += 30))
+ return d - step;
+ step = next;
+ if (d <= (next += 31))
+ return d - step;
+ step = next;
+ if (d <= (next += 30))
+ return d - step;
+ step = next;
+ if (d <= (next += 31))
+ return d - step;
+ step = next;
+ if (d <= (next += 31))
+ return d - step;
+ step = next;
+ if (d <= (next += 30))
+ return d - step;
+ step = next;
+ if (d <= (next += 31))
+ return d - step;
+ step = next;
+ if (d <= (next += 30))
+ return d - step;
+ step = next;
+
+ return d - step;
+ }
+
+ private static int WeekDay(double t) {
+ double result;
+ result = Day(t) + 4;
+ result = result % 7;
+ if (result < 0)
+ result += 7;
+ return (int) result;
+ }
+
+ private static double Now() {
+ return (double) System.currentTimeMillis();
+ }
+
+ /* Should be possible to determine the need for this dynamically
+ * if we go with the workaround... I'm not using it now, because I
+ * can't think of any clean way to make toLocaleString() and the
+ * time zone (comment) in toString match the generated string
+ * values. Currently it's wrong-but-consistent in all but the
+ * most recent betas of the JRE - seems to work in 1.1.7.
+ */
+ private final static boolean TZO_WORKAROUND = false;
+ private static double DaylightSavingTA(double t) {
+ if (!TZO_WORKAROUND) {
+ java.util.Date date = new java.util.Date((long) t);
+ if (thisTimeZone.inDaylightTime(date))
+ return msPerHour;
+ else
+ return 0;
+ } else {
+ /* Use getOffset if inDaylightTime() is broken, because it
+ * seems to work acceptably. We don't switch over to it
+ * entirely, because it requires (expensive) exploded date arguments,
+ * and the api makes it impossible to handle dst
+ * changeovers cleanly.
+ */
+
+ // Hardcode the assumption that the changeover always
+ // happens at 2:00 AM:
+ t += LocalTZA + (HourFromTime(t) <= 2 ? msPerHour : 0);
+
+ int year = YearFromTime(t);
+ double offset = thisTimeZone.getOffset(year > 0 ? 1 : 0,
+ year,
+ MonthFromTime(t),
+ DateFromTime(t),
+ WeekDay(t),
+ (int)TimeWithinDay(t));
+
+ if ((offset - LocalTZA) != 0)
+ return msPerHour;
+ else
+ return 0;
+ // return offset - LocalTZA;
+ }
+ }
+
+ private static double LocalTime(double t) {
+ return t + LocalTZA + DaylightSavingTA(t);
+ }
+
+ public static double internalUTC(double t) {
+ return t - LocalTZA - DaylightSavingTA(t - LocalTZA);
+ }
+
+ private static int HourFromTime(double t) {
+ double result;
+ result = java.lang.Math.floor(t / msPerHour) % HoursPerDay;
+ if (result < 0)
+ result += HoursPerDay;
+ return (int) result;
+ }
+
+ private static int MinFromTime(double t) {
+ double result;
+ result = java.lang.Math.floor(t / msPerMinute) % MinutesPerHour;
+ if (result < 0)
+ result += MinutesPerHour;
+ return (int) result;
+ }
+
+ private static int SecFromTime(double t) {
+ double result;
+ result = java.lang.Math.floor(t / msPerSecond) % SecondsPerMinute;
+ if (result < 0)
+ result += SecondsPerMinute;
+ return (int) result;
+ }
+
+ private static int msFromTime(double t) {
+ double result;
+ result = t % msPerSecond;
+ if (result < 0)
+ result += msPerSecond;
+ return (int) result;
+ }
+
+ private static double MakeTime(double hour, double min,
+ double sec, double ms)
+ {
+ return ((hour * MinutesPerHour + min) * SecondsPerMinute + sec)
+ * msPerSecond + ms;
+ }
+
+ private static double MakeDay(double year, double month, double date) {
+ double result;
+ boolean leap;
+ double yearday;
+ double monthday;
+
+ year += java.lang.Math.floor(month / 12);
+
+ month = month % 12;
+ if (month < 0)
+ month += 12;
+
+ leap = (DaysInYear((int) year) == 366);
+
+ yearday = java.lang.Math.floor(TimeFromYear(year) / msPerDay);
+ monthday = DayFromMonth((int) month, leap);
+
+ result = yearday
+ + monthday
+ + date - 1;
+ return result;
+ }
+
+ private static double MakeDate(double day, double time) {
+ return day * msPerDay + time;
+ }
+
+ private static double TimeClip(double d) {
+ if (d != d ||
+ d == Double.POSITIVE_INFINITY ||
+ d == Double.NEGATIVE_INFINITY ||
+ java.lang.Math.abs(d) > HalfTimeDomain)
+ {
+ return Double.NaN;
+ }
+ if (d > 0.0)
+ return java.lang.Math.floor(d + 0.);
+ else
+ return java.lang.Math.ceil(d + 0.);
+ }
+
+ /* end of ECMA helper functions */
+
+ /* find UTC time from given date... no 1900 correction! */
+ public static double date_msecFromDate(double year, double mon,
+ double mday, double hour,
+ double min, double sec,
+ double msec)
+ {
+ double day;
+ double time;
+ double result;
+
+ day = MakeDay(year, mon, mday);
+ time = MakeTime(hour, min, sec, msec);
+ result = MakeDate(day, time);
+ return result;
+ }
+
+
+ private static final int MAXARGS = 7;
+ private static double jsStaticJSFunction_UTC(Object[] args) {
+ double array[] = new double[MAXARGS];
+ int loop;
+ double d;
+
+ for (loop = 0; loop < MAXARGS; loop++) {
+ if (loop < args.length) {
+ d = _toNumber(args[loop]);
+ if (d != d || Double.isInfinite(d)) {
+ return Double.NaN;
+ }
+ array[loop] = toDouble(args[loop]);
+ } else {
+ array[loop] = 0;
+ }
+ }
+
+ /* adjust 2-digit years into the 20th century */
+ if (array[0] >= 0 && array[0] <= 99)
+ array[0] += 1900;
+
+ /* if we got a 0 for 'date' (which is out of range)
+ * pretend it's a 1. (So Date.UTC(1972, 5) works) */
+ if (array[2] < 1)
+ array[2] = 1;
+
+ d = date_msecFromDate(array[0], array[1], array[2],
+ array[3], array[4], array[5], array[6]);
+ d = TimeClip(d);
+ return d;
+ // return N(d);
+ }
+
+ /*
+ * Use ported code from jsdate.c rather than the locale-specific
+ * date-parsing code from Java, to keep js and rhino consistent.
+ * Is this the right strategy?
+ */
+
+ /* for use by date_parse */
+
+ /* replace this with byte arrays? Cheaper? */
+ private static String wtb[] = {
+ "am", "pm",
+ "monday", "tuesday", "wednesday", "thursday", "friday",
+ "saturday", "sunday",
+ "january", "february", "march", "april", "may", "june",
+ "july", "august", "september", "october", "november", "december",
+ "gmt", "ut", "utc", "est", "edt", "cst", "cdt",
+ "mst", "mdt", "pst", "pdt"
+ /* time zone table needs to be expanded */
+ };
+
+ private static int ttb[] = {
+ -1, -2, 0, 0, 0, 0, 0, 0, 0, /* AM/PM */
+ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
+ 10000 + 0, 10000 + 0, 10000 + 0, /* UT/UTC */
+ 10000 + 5 * 60, 10000 + 4 * 60, /* EDT */
+ 10000 + 6 * 60, 10000 + 5 * 60,
+ 10000 + 7 * 60, 10000 + 6 * 60,
+ 10000 + 8 * 60, 10000 + 7 * 60
+ };
+
+ /* helper for date_parse */
+ private static boolean date_regionMatches(String s1, int s1off,
+ String s2, int s2off,
+ int count)
+ {
+ boolean result = false;
+ /* return true if matches, otherwise, false */
+ int s1len = s1.length();
+ int s2len = s2.length();
+
+ while (count > 0 && s1off < s1len && s2off < s2len) {
+ if (Character.toLowerCase(s1.charAt(s1off)) !=
+ Character.toLowerCase(s2.charAt(s2off)))
+ break;
+ s1off++;
+ s2off++;
+ count--;
+ }
+
+ if (count == 0) {
+ result = true;
+ }
+ return result;
+ }
+
+ private static double date_parseString(String s) {
+ double msec;
+
+ int year = -1;
+ int mon = -1;
+ int mday = -1;
+ int hour = -1;
+ int min = -1;
+ int sec = -1;
+ char c = 0;
+ char si = 0;
+ int i = 0;
+ int n = -1;
+ double tzoffset = -1;
+ char prevc = 0;
+ int limit = 0;
+ boolean seenplusminus = false;
+
+ if (s == null) // ??? Will s be null?
+ return Double.NaN;
+ limit = s.length();
+ while (i < limit) {
+ c = s.charAt(i);
+ i++;
+ if (c <= ' ' || c == ',' || c == '-') {
+ if (i < limit) {
+ si = s.charAt(i);
+ if (c == '-' && '0' <= si && si <= '9') {
+ prevc = c;
+ }
+ }
+ continue;
+ }
+ if (c == '(') { /* comments) */
+ int depth = 1;
+ while (i < limit) {
+ c = s.charAt(i);
+ i++;
+ if (c == '(')
+ depth++;
+ else if (c == ')')
+ if (--depth <= 0)
+ break;
+ }
+ continue;
+ }
+ if ('0' <= c && c <= '9') {
+ n = c - '0';
+ while (i < limit && '0' <= (c = s.charAt(i)) && c <= '9') {
+ n = n * 10 + c - '0';
+ i++;
+ }
+
+ /* allow TZA before the year, so
+ * 'Wed Nov 05 21:49:11 GMT-0800 1997'
+ * works */
+
+ /* uses of seenplusminus allow : in TZA, so Java
+ * no-timezone style of GMT+4:30 works
+ */
+ if ((prevc == '+' || prevc == '-')/* && year>=0 */) {
+ /* make ':' case below change tzoffset */
+ seenplusminus = true;
+
+ /* offset */
+ if (n < 24)
+ n = n * 60; /* EG. "GMT-3" */
+ else
+ n = n % 100 + n / 100 * 60; /* eg "GMT-0430" */
+ if (prevc == '+') /* plus means east of GMT */
+ n = -n;
+ if (tzoffset != 0 && tzoffset != -1)
+ return Double.NaN;
+ tzoffset = n;
+ } else if (n >= 70 ||
+ (prevc == '/' && mon >= 0 && mday >= 0 && year < 0)) {
+ if (year >= 0)
+ return Double.NaN;
+ else if (c <= ' ' || c == ',' || c == '/' || i >= limit)
+ year = n < 100 ? n + 1900 : n;
+ else
+ return Double.NaN;
+ } else if (c == ':') {
+ if (hour < 0)
+ hour = /*byte*/ n;
+ else if (min < 0)
+ min = /*byte*/ n;
+ else
+ return Double.NaN;
+ } else if (c == '/') {
+ if (mon < 0)
+ mon = /*byte*/ n-1;
+ else if (mday < 0)
+ mday = /*byte*/ n;
+ else
+ return Double.NaN;
+ } else if (i < limit && c != ',' && c > ' ' && c != '-') {
+ return Double.NaN;
+ } else if (seenplusminus && n < 60) { /* handle GMT-3:30 */
+ if (tzoffset < 0)
+ tzoffset -= n;
+ else
+ tzoffset += n;
+ } else if (hour >= 0 && min < 0) {
+ min = /*byte*/ n;
+ } else if (min >= 0 && sec < 0) {
+ sec = /*byte*/ n;
+ } else if (mday < 0) {
+ mday = /*byte*/ n;
+ } else {
+ return Double.NaN;
+ }
+ prevc = 0;
+ } else if (c == '/' || c == ':' || c == '+' || c == '-') {
+ prevc = c;
+ } else {
+ int st = i - 1;
+ int k;
+ while (i < limit) {
+ c = s.charAt(i);
+ if (!(('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z')))
+ break;
+ i++;
+ }
+ if (i <= st + 1)
+ return Double.NaN;
+ for (k = wtb.length; --k >= 0;)
+ if (date_regionMatches(wtb[k], 0, s, st, i-st)) {
+ int action = ttb[k];
+ if (action != 0) {
+ if (action < 0) {
+ /*
+ * AM/PM. Count 12:30 AM as 00:30, 12:30 PM as
+ * 12:30, instead of blindly adding 12 if PM.
+ */
+ if (hour > 12 || hour < 0) {
+ return Double.NaN;
+ } else {
+ if (action == -1 && hour == 12) { // am
+ hour = 0;
+ } else if (action == -2 && hour != 12) {// pm
+ hour += 12;
+ }
+ }
+ } else if (action <= 13) { /* month! */
+ if (mon < 0) {
+ mon = /*byte*/ (action - 2);
+ } else {
+ return Double.NaN;
+ }
+ } else {
+ tzoffset = action - 10000;
+ }
+ }
+ break;
+ }
+ if (k < 0)
+ return Double.NaN;
+ prevc = 0;
+ }
+ }
+ if (year < 0 || mon < 0 || mday < 0)
+ return Double.NaN;
+ if (sec < 0)
+ sec = 0;
+ if (min < 0)
+ min = 0;
+ if (hour < 0)
+ hour = 0;
+ if (tzoffset == -1) { /* no time zone specified, have to use local */
+ double time;
+ time = date_msecFromDate(year, mon, mday, hour, min, sec, 0);
+ return internalUTC(time);
+ }
+
+ msec = date_msecFromDate(year, mon, mday, hour, min, sec, 0);
+ msec += tzoffset * msPerMinute;
+ return msec;
+ }
+
+ private static double jsStaticJSFunction_parse(String s) {
+ return date_parseString(s);
+ }
+
+ private static final int FORMATSPEC_FULL = 0;
+ private static final int FORMATSPEC_DATE = 1;
+ private static final int FORMATSPEC_TIME = 2;
+
+ private static String date_format(double t, int format) {
+ if (t != t)
+ return NaN_date_str;
+
+ StringBuffer result = new StringBuffer(60);
+ double local = LocalTime(t);
+
+ /* offset from GMT in minutes. The offset includes daylight savings,
+ if it applies. */
+ int minutes = (int) java.lang.Math.floor((LocalTZA + DaylightSavingTA(t))
+ / msPerMinute);
+ /* map 510 minutes to 0830 hours */
+ int offset = (minutes / 60) * 100 + minutes % 60;
+
+ String dateStr = Integer.toString(DateFromTime(local));
+ String hourStr = Integer.toString(HourFromTime(local));
+ String minStr = Integer.toString(MinFromTime(local));
+ String secStr = Integer.toString(SecFromTime(local));
+ String offsetStr = Integer.toString(offset > 0 ? offset : -offset);
+ int year = YearFromTime(local);
+ String yearStr = Integer.toString(year > 0 ? year : -year);
+
+ /* Tue Oct 31 09:41:40 GMT-0800 (PST) 2000 */
+ /* Tue Oct 31 2000 */
+ /* 09:41:40 GMT-0800 (PST) */
+
+ if (format != FORMATSPEC_TIME) {
+ result.append(days[WeekDay(local)]);
+ result.append(' ');
+ result.append(months[MonthFromTime(local)]);
+ if (dateStr.length() == 1)
+ result.append(" 0");
+ else
+ result.append(' ');
+ result.append(dateStr);
+ result.append(' ');
+ }
+
+ if (format != FORMATSPEC_DATE) {
+ if (hourStr.length() == 1)
+ result.append('0');
+ result.append(hourStr);
+ if (minStr.length() == 1)
+ result.append(":0");
+ else
+ result.append(':');
+ result.append(minStr);
+ if (secStr.length() == 1)
+ result.append(":0");
+ else
+ result.append(':');
+ result.append(secStr);
+ if (offset > 0)
+ result.append(" GMT+");
+ else
+ result.append(" GMT-");
+ for (int i = offsetStr.length(); i < 4; i++)
+ result.append('0');
+ result.append(offsetStr);
+
+ if (timeZoneFormatter == null)
+ timeZoneFormatter = new java.text.SimpleDateFormat("zzz");
+
+ if (timeZoneFormatter != null) {
+ result.append(" (");
+ java.util.Date date = new java.util.Date((long) t);
+ result.append(timeZoneFormatter.format(date));
+ result.append(')');
+ }
+ if (format != FORMATSPEC_TIME)
+ result.append(' ');
+ }
+
+ if (format != FORMATSPEC_TIME) {
+ if (year < 0)
+ result.append('-');
+ for (int i = yearStr.length(); i < 4; i++)
+ result.append('0');
+ result.append(yearStr);
+ }
+
+ return result.toString();
+ }
+
+ private static double _toNumber(Object o) { return JS.toDouble(o); }
+ private static double _toNumber(Object[] o, int index) { return JS.toDouble(o[index]); }
+ private static double toDouble(double d) { return d; }
+
+ public JSDate(Object a0, Object a1, Object a2, Object[] rest, int nargs) {
+
+ JSDate obj = this;
+ switch (nargs) {
+ case 0: {
+ obj.date = Now();
+ return;
+ }
+ case 1: {
+ double date;
+ if (a0 instanceof JS)
+ a0 = ((JS) a0).toString();
+ if (!(a0 instanceof String)) {
+ // if it's not a string, use it as a millisecond date
+ date = _toNumber(a0);
+ } else {
+ // it's a string; parse it.
+ String str = (String) a0;
+ date = date_parseString(str);
+ }
+ obj.date = TimeClip(date);
+ return;
+ }
+ default: {
+ // multiple arguments; year, month, day etc.
+ double array[] = new double[MAXARGS];
+ array[0] = toDouble(a0);
+ array[1] = toDouble(a1);
+ if (nargs >= 2) array[2] = toDouble(a2);
+ for(int i=0; i<nargs; i++) {
+ double d = _toNumber(i==0?a0:i==1?a1:i==2?a2:rest[i-3]);
+ if (d != d || Double.isInfinite(d)) {
+ obj.date = Double.NaN;
+ return;
+ }
+ array[i] = d;
+ }
+
+ /* adjust 2-digit years into the 20th century */
+ if (array[0] >= 0 && array[0] <= 99)
+ array[0] += 1900;
+
+ /* if we got a 0 for 'date' (which is out of range)
+ * pretend it's a 1 */
+ if (array[2] < 1)
+ array[2] = 1;
+
+ double day = MakeDay(array[0], array[1], array[2]);
+ double time = MakeTime(array[3], array[4], array[5], array[6]);
+ time = MakeDate(day, time);
+ time = internalUTC(time);
+ obj.date = TimeClip(time);
+
+ return;
+ }
+ }
+ }
+
+ /* constants for toString, toUTCString */
+ private static String NaN_date_str = "Invalid Date";
+
+ private static String[] days = {
+ "Sun","Mon","Tue","Wed","Thu","Fri","Sat"
+ };
+
+ private static String[] months = {
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+ };
+
+ private static String toLocale_helper(double t,
+ java.text.DateFormat formatter)
+ {
+ if (t != t)
+ return NaN_date_str;
+
+ java.util.Date tempdate = new java.util.Date((long) t);
+ return formatter.format(tempdate);
+ }
+
+ private static String toLocaleString(double date) {
+ if (localeDateTimeFormatter == null)
+ localeDateTimeFormatter =
+ DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG);
+
+ return toLocale_helper(date, localeDateTimeFormatter);
+ }
+
+ private static String toLocaleTimeString(double date) {
+ if (localeTimeFormatter == null)
+ localeTimeFormatter = DateFormat.getTimeInstance(DateFormat.LONG);
+
+ return toLocale_helper(date, localeTimeFormatter);
+ }
+
+ private static String toLocaleDateString(double date) {
+ if (localeDateFormatter == null)
+ localeDateFormatter = DateFormat.getDateInstance(DateFormat.LONG);
+
+ return toLocale_helper(date, localeDateFormatter);
+ }
+
+ private static String toUTCString(double date) {
+ StringBuffer result = new StringBuffer(60);
+
+ String dateStr = Integer.toString(DateFromTime(date));
+ String hourStr = Integer.toString(HourFromTime(date));
+ String minStr = Integer.toString(MinFromTime(date));
+ String secStr = Integer.toString(SecFromTime(date));
+ int year = YearFromTime(date);
+ String yearStr = Integer.toString(year > 0 ? year : -year);
+
+ result.append(days[WeekDay(date)]);
+ result.append(", ");
+ if (dateStr.length() == 1)
+ result.append('0');
+ result.append(dateStr);
+ result.append(' ');
+ result.append(months[MonthFromTime(date)]);
+ if (year < 0)
+ result.append(" -");
+ else
+ result.append(' ');
+ int i;
+ for (i = yearStr.length(); i < 4; i++)
+ result.append('0');
+ result.append(yearStr);
+
+ if (hourStr.length() == 1)
+ result.append(" 0");
+ else
+ result.append(' ');
+ result.append(hourStr);
+ if (minStr.length() == 1)
+ result.append(":0");
+ else
+ result.append(':');
+ result.append(minStr);
+ if (secStr.length() == 1)
+ result.append(":0");
+ else
+ result.append(':');
+ result.append(secStr);
+
+ result.append(" GMT");
+ return result.toString();
+ }
+
+ private static double getYear(double date) {
+ int result = YearFromTime(LocalTime(date));
+ result -= 1900;
+ return result;
+ }
+
+ private static double getTimezoneOffset(double date) {
+ return (date - LocalTime(date)) / msPerMinute;
+ }
+
+ public double setTime(double time) {
+ this.date = TimeClip(time);
+ return this.date;
+ }
+
+ private double makeTime(Object[] args, int maxargs, boolean local) {
+ int i;
+ double conv[] = new double[4];
+ double hour, min, sec, msec;
+ double lorutime; /* Local or UTC version of date */
+
+ double time;
+ double result;
+
+ double date = this.date;
+
+ /* just return NaN if the date is already NaN */
+ if (date != date)
+ return date;
+
+ /* Satisfy the ECMA rule that if a function is called with
+ * fewer arguments than the specified formal arguments, the
+ * remaining arguments are set to undefined. Seems like all
+ * the Date.setWhatever functions in ECMA are only varargs
+ * beyond the first argument; this should be set to undefined
+ * if it's not given. This means that "d = new Date();
+ * d.setMilliseconds()" returns NaN. Blech.
+ */
+ if (args.length == 0)
+ args = new Object[] { null };
+
+ for (i = 0; i < args.length && i < maxargs; i++) {
+ conv[i] = _toNumber(args[i]);
+
+ // limit checks that happen in MakeTime in ECMA.
+ if (conv[i] != conv[i] || Double.isInfinite(conv[i])) {
+ this.date = Double.NaN;
+ return this.date;
+ }
+ conv[i] = toDouble(conv[i]);
+ }
+
+ if (local)
+ lorutime = LocalTime(date);
+ else
+ lorutime = date;
+
+ i = 0;
+ int stop = args.length;
+
+ if (maxargs >= 4 && i < stop)
+ hour = conv[i++];
+ else
+ hour = HourFromTime(lorutime);
+
+ if (maxargs >= 3 && i < stop)
+ min = conv[i++];
+ else
+ min = MinFromTime(lorutime);
+
+ if (maxargs >= 2 && i < stop)
+ sec = conv[i++];
+ else
+ sec = SecFromTime(lorutime);
+
+ if (maxargs >= 1 && i < stop)
+ msec = conv[i++];
+ else
+ msec = msFromTime(lorutime);
+
+ time = MakeTime(hour, min, sec, msec);
+ result = MakeDate(Day(lorutime), time);
+
+ if (local)
+ result = internalUTC(result);
+ date = TimeClip(result);
+
+ this.date = date;
+ return date;
+ }
+
+ private double setHours(Object[] args) {
+ return makeTime(args, 4, true);
+ }
+
+ private double setUTCHours(Object[] args) {
+ return makeTime(args, 4, false);
+ }
+
+ private double makeDate(Object[] args, int maxargs, boolean local) {
+ int i;
+ double conv[] = new double[3];
+ double year, month, day;
+ double lorutime; /* local or UTC version of date */
+ double result;
+
+ double date = this.date;
+
+ /* See arg padding comment in makeTime.*/
+ if (args.length == 0)
+ args = new Object[] { null };
+
+ for (i = 0; i < args.length && i < maxargs; i++) {
+ conv[i] = _toNumber(args[i]);
+
+ // limit checks that happen in MakeDate in ECMA.
+ if (conv[i] != conv[i] || Double.isInfinite(conv[i])) {
+ this.date = Double.NaN;
+ return this.date;
+ }
+ conv[i] = toDouble(conv[i]);
+ }
+
+ /* return NaN if date is NaN and we're not setting the year,
+ * If we are, use 0 as the time. */
+ if (date != date) {
+ if (args.length < 3) {
+ return Double.NaN;
+ } else {
+ lorutime = 0;
+ }
+ } else {
+ if (local)
+ lorutime = LocalTime(date);
+ else
+ lorutime = date;
+ }
+
+ i = 0;
+ int stop = args.length;
+
+ if (maxargs >= 3 && i < stop)
+ year = conv[i++];
+ else
+ year = YearFromTime(lorutime);
+
+ if (maxargs >= 2 && i < stop)
+ month = conv[i++];
+ else
+ month = MonthFromTime(lorutime);
+
+ if (maxargs >= 1 && i < stop)
+ day = conv[i++];
+ else
+ day = DateFromTime(lorutime);
+
+ day = MakeDay(year, month, day); /* day within year */
+ result = MakeDate(day, TimeWithinDay(lorutime));
+
+ if (local)
+ result = internalUTC(result);
+
+ date = TimeClip(result);
+
+ this.date = date;
+ return date;
+ }
+
+ private double setYear(double year) {
+ double day, result;
+ if (year != year || Double.isInfinite(year)) {
+ this.date = Double.NaN;
+ return this.date;
+ }
+
+ if (this.date != this.date) {
+ this.date = 0;
+ } else {
+ this.date = LocalTime(this.date);
+ }
+
+ if (year >= 0 && year <= 99)
+ year += 1900;
+
+ day = MakeDay(year, MonthFromTime(this.date), DateFromTime(this.date));
+ result = MakeDate(day, TimeWithinDay(this.date));
+ result = internalUTC(result);
+
+ this.date = TimeClip(result);
+ return this.date;
+ }
+
+
+ // private static final int
+ // Id_toGMTString = Id_toUTCString; // Alias, see Ecma B.2.6
+// #/string_id_map#
+
+ /* cached values */
+ private static java.util.TimeZone thisTimeZone;
+ private static double LocalTZA;
+ private static java.text.DateFormat timeZoneFormatter;
+ private static java.text.DateFormat localeDateTimeFormatter;
+ private static java.text.DateFormat localeDateFormatter;
+ private static java.text.DateFormat localeTimeFormatter;
+
+ private double date;
+
+ public long getRawTime() { return (long)this.date; }
+}
+
+
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.js;
+
+import org.ibex.util.*;
+import java.io.*;
+
+/** An exception which can be thrown and caught by JavaScript code */
+public class JSExn extends Exception {
+ private Vec backtrace = new Vec();
+ private Object js = null;
+ public JSExn(Object js) {
+ this.js = js;
+ if (Interpreter.current() != null)
+ fill(Interpreter.current().stack, Interpreter.current().f, Interpreter.current().pc, Interpreter.current().scope);
+ }
+ public JSExn(Object js, Vec stack, JSFunction f, int pc, JSScope scope) { this.js = js; fill(stack, f, pc, scope); }
+ private void fill(Vec stack, JSFunction f, int pc, JSScope scope) {
+ addBacktrace(f.sourceName + ":" + f.line[pc]);
+ if (scope != null && scope instanceof Trap.TrapScope)
+ addBacktrace("trap on property \"" + ((Trap.TrapScope)scope).t.name + "\"");
+ for(int i=stack.size()-1; i>=0; i--) {
+ Object element = stack.elementAt(i);
+ if (element instanceof Interpreter.CallMarker) {
+ Interpreter.CallMarker cm = (Interpreter.CallMarker)element;
+ if (cm.f != null)
+ addBacktrace(cm.f.sourceName + ":" + cm.f.line[cm.pc-1]);
+ if (cm.scope != null && cm.scope instanceof Trap.TrapScope)
+ addBacktrace("trap on property \"" + ((Trap.TrapScope)cm.scope).t.name + "\"");
+ }
+ }
+ }
+ public void printStackTrace() { printStackTrace(System.err); }
+ public void printStackTrace(PrintWriter pw) {
+ for(int i=0; i<backtrace.size(); i++) pw.println(" at " + (String) backtrace.elementAt(i));
+ super.printStackTrace(pw);
+ }
+ public void printStackTrace(PrintStream ps) {
+ for(int i=0; i<backtrace.size(); i++) ps.println(" at " + (String) backtrace.elementAt(i));
+ super.printStackTrace(ps);
+ }
+ public String toString() { return "JSExn: " + js; }
+ public String getMessage() { return toString(); }
+ public Object getObject() { return js; }
+ public void addBacktrace(String line) { backtrace.addElement(line); }
+}
+
+/** should only be used for failed coercions */
+class JSRuntimeExn extends RuntimeException {
+ private Object js = null;
+ public JSRuntimeExn(Object js) { this.js = js; }
+ public String toString() { return "JSRuntimeExn: " + js; }
+ public String getMessage() { return toString(); }
+ public Object getObject() { return js; }
+}
+
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.js;
+
+import java.io.*;
+import org.ibex.util.*;
+
+/** A JavaScript function, compiled into bytecode */
+class JSFunction extends JS implements ByteCodes, Tokens, Task {
+
+
+ // Fields and Accessors ///////////////////////////////////////////////
+
+ int numFormalArgs = 0; ///< the number of formal arguments
+
+ String sourceName; ///< the source code file that this block was drawn from
+ private int firstLine = -1; ///< the first line of this script
+
+ int[] line = new int[10]; ///< the line numbers
+ int[] op = new int[10]; ///< the instructions
+ Object[] arg = new Object[10]; ///< the arguments to the instructions
+ int size = 0; ///< the number of instruction/argument pairs
+
+ JSScope parentScope; ///< the default scope to use as a parent scope when executing this
+
+
+ // Public //////////////////////////////////////////////////////////////////////////////
+
+ // FEATURE: make sure that this can only be called from the Scheduler...
+ /** if you enqueue a function, it gets invoked in its own pauseable context */
+ public void perform() throws JSExn {
+ Interpreter i = new Interpreter(this, true, new JSArray());
+ i.resume();
+ }
+
+ /** parse and compile a function */
+ public static JSFunction _fromReader(String sourceName, int firstLine, Reader sourceCode) throws IOException {
+ JSFunction ret = new JSFunction(sourceName, firstLine, null);
+ if (sourceCode == null) return ret;
+ Parser p = new Parser(sourceCode, sourceName, firstLine);
+ while(true) {
+ int s = ret.size;
+ p.parseStatement(ret, null);
+ if (s == ret.size) break;
+ }
+ ret.add(-1, LITERAL, null);
+ ret.add(-1, RETURN);
+ return ret;
+ }
+
+ public JSFunction _cloneWithNewParentScope(JSScope s) {
+ JSFunction ret = new JSFunction(sourceName, firstLine, s);
+ // Reuse the same op, arg, line, and size variables for the new "instance" of the function
+ // NOTE: Neither *this* function nor the new function should be modified after this call
+ ret.op = this.op;
+ ret.arg = this.arg;
+ ret.line = this.line;
+ ret.size = this.size;
+ ret.numFormalArgs = this.numFormalArgs;
+ return ret;
+ }
+
+ /** Note: code gets run in an <i>unpauseable</i> context. */
+ public Object call(Object a0, Object a1, Object a2, Object[] rest, int nargs) throws JSExn {
+ JSArray args = new JSArray();
+ if (nargs > 0) args.addElement(a0);
+ if (nargs > 1) args.addElement(a1);
+ if (nargs > 2) args.addElement(a2);
+ for(int i=3; i<nargs; i++) args.addElement(rest[i-3]);
+ Interpreter cx = new Interpreter(this, false, args);
+ return cx.resume();
+ }
+
+ public JSScope getParentScope() { return parentScope; }
+
+ // Adding and Altering Bytecodes ///////////////////////////////////////////////////
+
+ JSFunction(String sourceName, int firstLine, JSScope parentScope) {
+ this.sourceName = sourceName;
+ this.firstLine = firstLine;
+ this.parentScope = parentScope;
+ }
+
+ int get(int pos) { return op[pos]; }
+ Object getArg(int pos) { return arg[pos]; }
+ void set(int pos, int op_, Object arg_) { op[pos] = op_; arg[pos] = arg_; }
+ void set(int pos, Object arg_) { arg[pos] = arg_; }
+ int pop() { size--; arg[size] = null; return op[size]; }
+ void paste(JSFunction other) { for(int i=0; i<other.size; i++) add(other.line[i], other.op[i], other.arg[i]); }
+ JSFunction add(int line, int op_) { return add(line, op_, null); }
+ JSFunction add(int line, int op_, Object arg_) {
+ if (size == op.length - 1) {
+ int[] line2 = new int[op.length * 2]; System.arraycopy(this.line, 0, line2, 0, op.length); this.line = line2;
+ Object[] arg2 = new Object[op.length * 2]; System.arraycopy(arg, 0, arg2, 0, arg.length); arg = arg2;
+ int[] op2 = new int[op.length * 2]; System.arraycopy(op, 0, op2, 0, op.length); op = op2;
+ }
+ this.line[size] = line;
+ op[size] = op_;
+ arg[size] = arg_;
+ size++;
+ return this;
+ }
+
+
+ // Debugging //////////////////////////////////////////////////////////////////////
+
+ public String toString() { return "JSFunction [" + sourceName + ":" + firstLine + "]"; }
+
+ public String dump() {
+ StringBuffer sb = new StringBuffer(1024);
+ sb.append("\n" + sourceName + ": " + firstLine + "\n");
+ for (int i=0; i < size; i++) {
+ sb.append(i).append(" (").append(line[i]).append(") :");
+ if (op[i] < 0) sb.append(bytecodeToString[-op[i]]);
+ else sb.append(codeToString[op[i]]);
+ sb.append(" ");
+ sb.append(arg[i] == null ? "(no arg)" : arg[i]);
+ if((op[i] == JF || op[i] == JT || op[i] == JMP) && arg[i] != null && arg[i] instanceof Number) {
+ sb.append(" jump to ").append(i+((Number) arg[i]).intValue());
+ } else if(op[i] == TRY) {
+ int[] jmps = (int[]) arg[i];
+ sb.append(" catch: ").append(jmps[0] < 0 ? "No catch block" : ""+(i+jmps[0]));
+ sb.append(" finally: ").append(jmps[1] < 0 ? "No finally block" : ""+(i+jmps[1]));
+ }
+ sb.append("\n");
+ }
+ return sb.toString();
+ }
+
+
+}
+
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL ]
+
+package org.ibex.js;
+
+/** The JavaScript Math object */
+public class JSMath extends JS {
+
+ public static JSMath singleton = new JSMath();
+
+ private static final Double E = new Double(java.lang.Math.E);
+ private static final Double PI = new Double(java.lang.Math.PI);
+ private static final Double LN10 = new Double(java.lang.Math.log(10));
+ private static final Double LN2 = new Double(java.lang.Math.log(2));
+ private static final Double LOG10E = new Double(1/java.lang.Math.log(10));
+ private static final Double LOG2E = new Double(1/java.lang.Math.log(2));
+ private static final Double SQRT1_2 = new Double(1/java.lang.Math.sqrt(2));
+ private static final Double SQRT2 = new Double(java.lang.Math.sqrt(2));
+
+ public Object callMethod(Object method, Object a0, Object a1, Object a2, Object[] rest, int nargs) throws JSExn {
+ switch(nargs) {
+ case 0: {
+final String ccSwitch0 = (String)(method); SUCCESS:do { switch(ccSwitch0.length()) {
+case 6: { switch(ccSwitch0.charAt(0)) { case 'r': if ("random".equals(ccSwitch0)) { if (true) do { return new Double(java.lang.Math.random());
+ } while(false); break SUCCESS; } break; }; break; } } /* switch */ } while(false); /* OUTER */
+ break;
+ }
+ case 1: {
+final String ccSwitch1 = (String)(method); SUCCESS:do { switch(ccSwitch1.length()) {
+case 3: { switch(ccSwitch1.charAt(0)) { case 'a': if ("abs".equals(ccSwitch1)) { if (true) do { return new Double(java.lang.Math.abs(toDouble(a0)));
+ } while(false); break SUCCESS; } break; case 'c': if ("cos".equals(ccSwitch1)) { if (true) do { return new Double(java.lang.Math.cos(toDouble(a0)));
+ } while(false); break SUCCESS; } break; case 'e': if ("exp".equals(ccSwitch1)) { if (true) do { return new Double(java.lang.Math.exp(toDouble(a0)));
+ } while(false); break SUCCESS; } break; case 'l': if ("log".equals(ccSwitch1)) { if (true) do { return new Double(java.lang.Math.log(toDouble(a0)));
+ } while(false); break SUCCESS; } break; case 's': if ("sin".equals(ccSwitch1)) { if (true) do { return new Double(java.lang.Math.sin(toDouble(a0)));
+ } while(false); break SUCCESS; } break; case 't': if ("tan".equals(ccSwitch1)) { if (true) do { return new Double(java.lang.Math.tan(toDouble(a0)));
+ } while(false); break SUCCESS; } break; }; break; } case 4: { switch(ccSwitch1.charAt(0)) { case 'a': { switch(ccSwitch1.charAt(1)) { case 'c': if ("acos".equals(ccSwitch1)) { if (true) do { return new Double(java.lang.Math.acos(toDouble(a0)));
+ } while(false); break SUCCESS; } break; case 's': if ("asin".equals(ccSwitch1)) { if (true) do { return new Double(java.lang.Math.asin(toDouble(a0)));
+ } while(false); break SUCCESS; } break; case 't': if ("atan".equals(ccSwitch1)) { if (true) do { return new Double(java.lang.Math.atan(toDouble(a0)));
+ } while(false); break SUCCESS; } break; } break; } case 'c': if ("ceil".equals(ccSwitch1)) { if (true) do { return new Long((long)java.lang.Math.ceil(toDouble(a0)));
+ } while(false); break SUCCESS; } break; case 's': if ("sqrt".equals(ccSwitch1)) { if (true) do { return new Double(java.lang.Math.sqrt(toDouble(a0)));
+ } while(false); break SUCCESS; } break; }; break; } case 5: { switch(ccSwitch1.charAt(0)) { case 'f': if ("floor".equals(ccSwitch1)) { if (true) do { return new Long((long)java.lang.Math.floor(toDouble(a0)));
+ } while(false); break SUCCESS; } break; case 'r': if ("round".equals(ccSwitch1)) { if (true) do { return new Long((long)java.lang.Math.round(toDouble(a0)));
+ } while(false); break SUCCESS; } break; }; break; } } /* switch */ } while(false); /* OUTER */
+ break;
+ }
+ case 2: {
+final String ccSwitch2 = (String)(method); SUCCESS:do { switch(ccSwitch2.length()) {
+case 3: { switch(ccSwitch2.charAt(0)) { case 'm': { switch(ccSwitch2.charAt(1)) { case 'a': if ("max".equals(ccSwitch2)) { if (true) do { return new Double(java.lang.Math.max(toDouble(a0), toDouble(a1)));
+ } while(false); break SUCCESS; } break; case 'i': if ("min".equals(ccSwitch2)) { if (true) do { return new Double(java.lang.Math.min(toDouble(a0), toDouble(a1)));
+ } while(false); break SUCCESS; } break; } break; } case 'p': if ("pow".equals(ccSwitch2)) { if (true) do { return new Double(java.lang.Math.pow(toDouble(a0), toDouble(a1)));
+ } while(false); break SUCCESS; } break; }; break; } case 5: { switch(ccSwitch2.charAt(0)) { case 'a': if ("atan2".equals(ccSwitch2)) { if (true) do { return new Double(java.lang.Math.atan2(toDouble(a0), toDouble(a1)));
+ } while(false); break SUCCESS; } break; }; break; } } /* switch */ } while(false); /* OUTER */
+ break;
+ }
+ }
+ return super.callMethod(method, a0, a1, a2, rest, nargs);
+ }
+
+ public void put(Object key, Object val) { }
+
+ public Object get(Object key) throws JSExn {
+final String ccSwitch3 = (String)(key); SUCCESS:do { switch(ccSwitch3.length()) {
+case 1: { switch(ccSwitch3.charAt(0)) { case 'E': if ("E".equals(ccSwitch3)) { if (true) do { return E;
+ } while(false); break SUCCESS; } break; }; break; } case 2: { switch(ccSwitch3.charAt(0)) { case 'P': if ("PI".equals(ccSwitch3)) { if (true) do { return PI;
+ } while(false); break SUCCESS; } break; }; break; } case 3: { switch(ccSwitch3.charAt(0)) { case 'L': if ("LN2".equals(ccSwitch3)) { if (true) do { return LN2;
+ } while(false); break SUCCESS; } break; case 'a': if ("abs".equals(ccSwitch3)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 'c': if ("cos".equals(ccSwitch3)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 'e': if ("exp".equals(ccSwitch3)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 'l': if ("log".equals(ccSwitch3)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 'm': { switch(ccSwitch3.charAt(1)) { case 'a': if ("max".equals(ccSwitch3)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 'i': if ("min".equals(ccSwitch3)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; } break; } case 'p': if ("pow".equals(ccSwitch3)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 's': if ("sin".equals(ccSwitch3)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 't': if ("tan".equals(ccSwitch3)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; }; break; } case 4: { switch(ccSwitch3.charAt(0)) { case 'L': if ("LN10".equals(ccSwitch3)) { if (true) do { return LN10;
+ } while(false); break SUCCESS; } break; case 'a': { switch(ccSwitch3.charAt(1)) { case 'c': if ("acos".equals(ccSwitch3)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 's': if ("asin".equals(ccSwitch3)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 't': if ("atan".equals(ccSwitch3)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; } break; } case 'c': if ("ceil".equals(ccSwitch3)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 's': if ("sqrt".equals(ccSwitch3)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; }; break; } case 5: { switch(ccSwitch3.charAt(0)) { case 'L': if ("LOG2E".equals(ccSwitch3)) { if (true) do { return LOG2E;
+ } while(false); break SUCCESS; } break; case 'S': if ("SQRT2".equals(ccSwitch3)) { if (true) do { return SQRT2;
+ } while(false); break SUCCESS; } break; case 'a': if ("atan2".equals(ccSwitch3)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 'f': if ("floor".equals(ccSwitch3)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 'r': if ("round".equals(ccSwitch3)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; }; break; } case 6: { switch(ccSwitch3.charAt(0)) { case 'L': if ("LOG10E".equals(ccSwitch3)) { if (true) do { return LOG10E;
+ } while(false); break SUCCESS; } break; case 'r': if ("random".equals(ccSwitch3)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; }; break; } case 7: { switch(ccSwitch3.charAt(0)) { case 'S': if ("SQRT1_2".equals(ccSwitch3)) { if (true) do { return SQRT1_2;
+ } while(false); break SUCCESS; } break; }; break; } } /* switch */ } while(false); /* OUTER */
+ return super.get(key);
+ }
+}
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.js;
+
+import org.ibex.util.*;
+import java.io.*;
+import java.util.*;
+import java.lang.reflect.*;
+
+/** Automatic JS-ification via Reflection (not for use in the core) */
+public class JSReflection extends JS {
+
+ public static Object wrap(Object o) throws JSExn {
+ if (o instanceof String) return o;
+ if (o instanceof Boolean) return o;
+ if (o instanceof Number) return o;
+ if (o instanceof JS) return o;
+ if (o instanceof Object[]) {
+ // FIXME: get element type here
+ }
+ throw new JSExn("Reflection object tried to return a " + o.getClass().getName());
+ }
+
+ public static class Array extends JS {
+ final Object[] arr;
+ public Array(Object[] arr) { this.arr = arr; }
+ public Enumeration keys() throws JSExn { return new CounterEnumeration(arr.length); }
+ public Object get(Object key) throws JSExn { return wrap(arr[toInt(key)]); }
+ public void put(Object key, Object val) throws JSExn { throw new JSExn("can't write to org.ibex.js.Reflection.Array's"); }
+ }
+
+ // FIXME public static class Hash { }
+ // FIXME public Enumeration keys() throws JSExn { }
+
+ public Object get(Object key) throws JSExn {
+ String k = toString(key);
+ try {
+ Field f = this.getClass().getField(k);
+ return wrap(f.get(this));
+ } catch (NoSuchFieldException nfe) {
+ } catch (IllegalAccessException nfe) {
+ } catch (SecurityException nfe) { }
+
+ try {
+ Method[] methods = this.getClass().getMethods();
+ for(int i=0; i<methods.length; i++) if (methods[i].getName().equals(k)) return METHOD;
+ } catch (SecurityException nfe) { }
+ return null;
+ }
+
+ public void put(Object key, Object val) throws JSExn {
+ throw new JSExn("put() not supported yet");
+ }
+
+ public Object callMethod(Object method, Object a0, Object a1, Object a2, Object[] rest, int nargs) throws JSExn {
+ String k = toString(method);
+ try {
+ Method[] methods = this.getClass().getMethods();
+ for(int j=0; j<methods.length; j++) {
+ if (methods[j].getName().equals(k) && methods[j].getParameterTypes().length == nargs) {
+ Object[] args = new Object[nargs];
+ for(int i = 0; i<args.length; i++) {
+ if (i==0) args[i] = a0;
+ else if (i==1) args[i] = a1;
+ else if (i==2) args[i] = a2;
+ else args[i] = rest[i-3];
+ }
+ return wrap(methods[j].invoke(this, args));
+ }
+ }
+ } catch (IllegalAccessException nfe) {
+ } catch (InvocationTargetException it) {
+ Throwable ite = it.getTargetException();
+ if (ite instanceof JSExn) throw ((JSExn)ite);
+ JS.warn(ite);
+ throw new JSExn("unhandled reflected exception: " + ite.toString());
+ } catch (SecurityException nfe) { }
+ throw new JSExn("called a reflection method with the wrong number of arguments");
+ }
+}
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.js;
+
+import gnu.regexp.*;
+
+/** A JavaScript regular expression object */
+public class JSRegexp extends JS {
+ private boolean global;
+ private RE re;
+ private int lastIndex;
+
+ public JSRegexp(Object arg0, Object arg1) throws JSExn {
+ if(arg0 instanceof JSRegexp) {
+ JSRegexp r = (JSRegexp) arg0;
+ this.global = r.global;
+ this.re = r.re;
+ this.lastIndex = r.lastIndex;
+ } else {
+ String pattern = (String)arg0;
+ String sFlags = null;
+ int flags = 0;
+ if(arg1 != null) sFlags = (String)arg1;
+ if(sFlags == null) sFlags = "";
+ for(int i=0;i<sFlags.length();i++) {
+ switch(sFlags.charAt(i)) {
+ case 'i': flags |= RE.REG_ICASE; break;
+ case 'm': flags |= RE.REG_MULTILINE; break;
+ case 'g': global = true; break;
+ default: throw new JSExn("Invalid flag in regexp \"" + sFlags.charAt(i) + "\"");
+ }
+ }
+ re = newRE(pattern,flags);
+ put("source", pattern);
+ put("global", B(global));
+ put("ignoreCase", B(flags & RE.REG_ICASE));
+ put("multiline", B(flags & RE.REG_MULTILINE));
+ }
+ }
+
+ public Object callMethod(Object method, Object a0, Object a1, Object a2, Object[] rest, int nargs) throws JSExn {
+ switch(nargs) {
+ case 1: {
+final String ccSwitch0 = (String)(method); SUCCESS:do { switch(ccSwitch0.length()) {
+case 4: { switch(ccSwitch0.charAt(0)) { case 'e': if ("exec".equals(ccSwitch0)) { if (true) do { {
+String s = (String)a0;
+int start = global ? lastIndex : 0;
+if(start < 0 || start >= s.length()) { lastIndex = 0; return null; }
+REMatch match = re.getMatch(s,start);
+if(global) lastIndex = match == null ? s.length() : match.getEndIndex();
+return match == null ? null : matchToExecResult(match,re,s);
+}
+ } while(false); break SUCCESS; } break; case 't': if ("test".equals(ccSwitch0)) { if (true) do { {
+String s = (String)a0;
+if (!global) return B(re.getMatch(s) != null);
+int start = global ? lastIndex : 0;
+if(start < 0 || start >= s.length()) { lastIndex = 0; return null; }
+REMatch match = re.getMatch(s,start);
+lastIndex = match != null ? s.length() : match.getEndIndex();
+return B(match != null);
+}
+ } while(false); break SUCCESS; } break; }; break; } case 8: { switch(ccSwitch0.charAt(0)) { case 't': if ("toString".equals(ccSwitch0)) { if (true) do { return toString(a0);
+ } while(false); break SUCCESS; } break; }; break; } case 11: { switch(ccSwitch0.charAt(0)) { case 's': if ("stringMatch".equals(ccSwitch0)) { if (true) do { return stringMatch(a0,a1);
+ } while(false); break SUCCESS; } break; }; break; } case 12: { switch(ccSwitch0.charAt(0)) { case 's': if ("stringSearch".equals(ccSwitch0)) { if (true) do { return stringSearch(a0,a1);
+ } while(false); break SUCCESS; } break; }; break; } } /* switch */ } while(false); /* OUTER */
+ break;
+ }
+ case 2: {
+final String ccSwitch1 = (String)(method); SUCCESS:do { switch(ccSwitch1.length()) {
+case 13: { switch(ccSwitch1.charAt(0)) { case 's': if ("stringReplace".equals(ccSwitch1)) { if (true) do { return stringReplace(a0, a1,a2);
+ } while(false); break SUCCESS; } break; }; break; } } /* switch */ } while(false); /* OUTER */
+ break;
+ }
+ }
+ return super.callMethod(method, a0, a1, a2, rest, nargs);
+ }
+
+ public Object get(Object key) throws JSExn {
+final String ccSwitch2 = (String)(key); SUCCESS:do { switch(ccSwitch2.length()) {
+case 4: { switch(ccSwitch2.charAt(0)) { case 'e': if ("exec".equals(ccSwitch2)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 't': if ("test".equals(ccSwitch2)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; }; break; } case 8: { switch(ccSwitch2.charAt(0)) { case 't': if ("toString".equals(ccSwitch2)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; }; break; } case 9: { switch(ccSwitch2.charAt(0)) { case 'l': if ("lastIndex".equals(ccSwitch2)) { if (true) do { return N(lastIndex);
+ } while(false); break SUCCESS; } break; }; break; } } /* switch */ } while(false); /* OUTER */
+ return super.get(key);
+ }
+
+ public void put(Object key, Object value) throws JSExn {
+ if(key.equals("lastIndex")) lastIndex = JS.toNumber(value).intValue();
+ super.put(key,value);
+ }
+
+ private static Object matchToExecResult(REMatch match, RE re, String s) {
+ try {
+ JS ret = new JS();
+ ret.put("index", N(match.getStartIndex()));
+ ret.put("input",s);
+ int n = re.getNumSubs();
+ ret.put("length", N(n+1));
+ ret.put("0",match.toString());
+ for(int i=1;i<=n;i++) ret.put(Integer.toString(i),match.toString(i));
+ return ret;
+ } catch (JSExn e) {
+ throw new Error("this should never happen");
+ }
+ }
+
+ public String toString() {
+ try {
+ StringBuffer sb = new StringBuffer();
+ sb.append('/');
+ sb.append(get("source"));
+ sb.append('/');
+ if(global) sb.append('g');
+ if(Boolean.TRUE.equals(get("ignoreCase"))) sb.append('i');
+ if(Boolean.TRUE.equals(get("multiline"))) sb.append('m');
+ return sb.toString();
+ } catch (JSExn e) {
+ throw new Error("this should never happen");
+ }
+ }
+
+ public static Object stringMatch(Object o, Object arg0) throws JSExn {
+ String s = o.toString();
+ RE re;
+ JSRegexp regexp = null;
+ if(arg0 instanceof JSRegexp) {
+ regexp = (JSRegexp) arg0;
+ re = regexp.re;
+ } else {
+ re = newRE(arg0.toString(),0);
+ }
+
+ if(regexp == null) {
+ REMatch match = re.getMatch(s);
+ return matchToExecResult(match,re,s);
+ }
+ if(!regexp.global) return regexp.callMethod("exec", s, null, null, null, 1);
+
+ JSArray ret = new JSArray();
+ REMatch[] matches = re.getAllMatches(s);
+ for(int i=0;i<matches.length;i++) ret.addElement(matches[i].toString());
+ regexp.lastIndex = matches.length > 0 ? matches[matches.length-1].getEndIndex() : s.length();
+ return ret;
+ }
+
+ public static Object stringSearch(Object o, Object arg0) throws JSExn {
+ String s = o.toString();
+ RE re = arg0 instanceof JSRegexp ? ((JSRegexp)arg0).re : newRE(arg0.toString(),0);
+ REMatch match = re.getMatch(s);
+ return match == null ? N(-1) : N(match.getStartIndex());
+ }
+
+ public static Object stringReplace(Object o, Object arg0, Object arg1) throws JSExn {
+ String s = o.toString();
+ RE re;
+ JSFunction replaceFunc = null;
+ String replaceString = null;
+ JSRegexp regexp = null;
+ if(arg0 instanceof JSRegexp) {
+ regexp = (JSRegexp) arg0;
+ re = regexp.re;
+ } else {
+ re = newRE(arg0.toString(),0);
+ }
+ if(arg1 instanceof JSFunction)
+ replaceFunc = (JSFunction) arg1;
+ else
+ replaceString = JS.toString(arg1.toString());
+ REMatch[] matches;
+ if(regexp != null && regexp.global) {
+ matches = re.getAllMatches(s);
+ if(regexp != null) {
+ if(matches.length > 0)
+ regexp.lastIndex = matches[matches.length-1].getEndIndex();
+ else
+ regexp.lastIndex = s.length();
+ }
+ } else {
+ REMatch match = re.getMatch(s);
+ if(match != null)
+ matches = new REMatch[]{ match };
+ else
+ matches = new REMatch[0];
+ }
+
+ StringBuffer sb = new StringBuffer(s.length());
+ int pos = 0;
+ char[] sa = s.toCharArray();
+ for(int i=0;i<matches.length;i++) {
+ REMatch match = matches[i];
+ sb.append(sa,pos,match.getStartIndex()-pos);
+ pos = match.getEndIndex();
+ if(replaceFunc != null) {
+ int n = (regexp == null ? 0 : re.getNumSubs());
+ int numArgs = 3 + n;
+ Object[] rest = new Object[numArgs - 3];
+ Object a0 = match.toString();
+ Object a1 = null;
+ Object a2 = null;
+ for(int j=1;j<=n;j++)
+ switch(j) {
+ case 1: a1 = match.toString(j); break;
+ case 2: a2 = match.toString(j); break;
+ default: rest[j - 3] = match.toString(j); break;
+ }
+ switch(numArgs) {
+ case 3:
+ a1 = N(match.getStartIndex());
+ a2 = s;
+ break;
+ case 4:
+ a2 = N(match.getStartIndex());
+ rest[0] = s;
+ break;
+ default:
+ rest[rest.length - 2] = N(match.getStartIndex());
+ rest[rest.length - 1] = s;
+ }
+
+ // note: can't perform pausing operations in here
+ sb.append((String)replaceFunc.call(a0, a1, a2, rest, numArgs));
+
+ } else {
+ sb.append(mySubstitute(match,replaceString,s));
+ }
+ }
+ int end = matches.length == 0 ? 0 : matches[matches.length-1].getEndIndex();
+ sb.append(sa,end,sa.length-end);
+ return sb.toString();
+ }
+
+ private static String mySubstitute(REMatch match, String s, String source) {
+ StringBuffer sb = new StringBuffer();
+ int i,n;
+ char c,c2;
+ for(i=0;i<s.length()-1;i++) {
+ c = s.charAt(i);
+ if(c != '$') {
+ sb.append(c);
+ continue;
+ }
+ i++;
+ c = s.charAt(i);
+ switch(c) {
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ if(i < s.length()-1 && (c2 = s.charAt(i+1)) >= '0' && c2 <= '9') {
+ n = (c - '0') * 10 + (c2 - '0');
+ i++;
+ } else {
+ n = c - '0';
+ }
+ if(n > 0)
+ sb.append(match.toString(n));
+ break;
+ case '$':
+ sb.append('$'); break;
+ case '&':
+ sb.append(match.toString()); break;
+ case '`':
+ sb.append(source.substring(0,match.getStartIndex())); break;
+ case '\'':
+ sb.append(source.substring(match.getEndIndex())); break;
+ default:
+ sb.append('$');
+ sb.append(c);
+ }
+ }
+ if(i < s.length()) sb.append(s.charAt(i));
+ return sb.toString();
+ }
+
+
+ public static Object stringSplit(String s, Object arg0, Object arg1, int nargs) {
+ int limit = nargs < 2 ? Integer.MAX_VALUE : JS.toInt(arg1);
+ if(limit < 0) limit = Integer.MAX_VALUE;
+ if(limit == 0) return new JSArray();
+
+ RE re = null;
+ JSRegexp regexp = null;
+ String sep = null;
+ JSArray ret = new JSArray();
+ int p = 0;
+
+ if(arg0 instanceof JSRegexp) {
+ regexp = (JSRegexp) arg0;
+ re = regexp.re;
+ } else {
+ sep = arg0.toString();
+ }
+
+ // special case this for speed. additionally, the code below doesn't properly handle
+ // zero length strings
+ if(sep != null && sep.length()==0) {
+ int len = s.length();
+ for(int i=0;i<len;i++)
+ ret.addElement(s.substring(i,i+1));
+ return ret;
+ }
+
+ OUTER: while(p < s.length()) {
+ if(re != null) {
+ REMatch m = re.getMatch(s,p);
+ if(m == null) break OUTER;
+ boolean zeroLength = m.getStartIndex() == m.getEndIndex();
+ ret.addElement(s.substring(p,zeroLength ? m.getStartIndex()+1 : m.getStartIndex()));
+ p = zeroLength ? p + 1 : m.getEndIndex();
+ if(!zeroLength) {
+ for(int i=1;i<=re.getNumSubs();i++) {
+ ret.addElement(m.toString(i));
+ if(ret.length() == limit) break OUTER;
+ }
+ }
+ } else {
+ int x = s.indexOf(sep,p);
+ if(x == -1) break OUTER;
+ ret.addElement(s.substring(p,x));
+ p = x + sep.length();
+ }
+ if(ret.length() == limit) break;
+ }
+ if(p < s.length() && ret.length() != limit)
+ ret.addElement(s.substring(p));
+ return ret;
+ }
+
+ public static RE newRE(String pattern, int flags) throws JSExn {
+ try {
+ return new RE(pattern,flags,RESyntax.RE_SYNTAX_PERL5);
+ } catch(REException e) {
+ throw new JSExn(e.toString());
+ }
+ }
+
+ public String typeName() { return "regexp"; }
+}
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.js;
+
+// FIXME: should allow parentScope to be a JS, not a JSScope
+/** Implementation of a JavaScript Scope */
+public class JSScope extends JS {
+
+ private JSScope parentScope;
+
+ private static final Object NULL_PLACEHOLDER = new Object();
+
+ public JSScope(JSScope parentScope) { this.parentScope = parentScope; }
+ public void declare(String s) throws JSExn { super.put(s, NULL_PLACEHOLDER); }
+ public JSScope getParentScope() { return parentScope; }
+
+ public Object get(Object key) throws JSExn {
+ Object o = super.get(key);
+ if (o != null) return o == NULL_PLACEHOLDER ? null : o;
+ else return parentScope == null ? null : parentScope.get(key);
+ }
+
+ public boolean has(Object key) throws JSExn { return super.get(key) != null; }
+ public void put(Object key, Object val) throws JSExn {
+ if (parentScope != null && !has(key)) parentScope.put(key, val);
+ else super.put(key, val == null ? NULL_PLACEHOLDER : val);
+ }
+
+ public JSScope top() {
+ JSScope s = this;
+ while(s.parentScope != null) s = s.parentScope;
+ return s;
+ }
+
+ public static class Global extends JSScope {
+ private final static Double NaN = new Double(Double.NaN);
+ private final static Double POSITIVE_INFINITY = new Double(Double.POSITIVE_INFINITY);
+
+ public Global() { super(null); }
+ public Object get(Object key) throws JSExn {
+final String ccSwitch0 = (String)(key); SUCCESS:do { switch(ccSwitch0.length()) {
+case 3: { switch(ccSwitch0.charAt(0)) { case 'N': if ("NaN".equals(ccSwitch0)) { if (true) do { return NaN;
+ } while(false); break SUCCESS; } break; }; break; } case 5: { switch(ccSwitch0.charAt(0)) { case 'i': if ("isNaN".equals(ccSwitch0)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; }; break; } case 6: { switch(ccSwitch0.charAt(0)) { case 'e': if ("escape".equals(ccSwitch0)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; }; break; } case 8: { switch(ccSwitch0.charAt(0)) { case 'I': if ("Infinity".equals(ccSwitch0)) { if (true) do { return POSITIVE_INFINITY;
+ } while(false); break SUCCESS; } break; case 'i': if ("isFinite".equals(ccSwitch0)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 'p': if ("parseInt".equals(ccSwitch0)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 'u': if ("unescape".equals(ccSwitch0)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; }; break; } case 9: { switch(ccSwitch0.charAt(0)) { case 'd': if ("decodeURI".equals(ccSwitch0)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 'e': if ("encodeURI".equals(ccSwitch0)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 'u': if ("undefined".equals(ccSwitch0)) { if (true) do { return null;
+ } while(false); break SUCCESS; } break; }; break; } case 18: { switch(ccSwitch0.charAt(0)) { case 'd': if ("decodeURIComponent".equals(ccSwitch0)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 'e': if ("encodeURIComponent".equals(ccSwitch0)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 's': if ("stringFromCharCode".equals(ccSwitch0)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; }; break; } } /* switch */ } while(false); /* OUTER */
+ return super.get(key);
+ }
+
+ public Object callMethod(Object method, Object a0, Object a1, Object a2, Object[] rest, int nargs) throws JSExn {
+ switch(nargs) {
+ case 0: {
+final String ccSwitch1 = (String)(method); SUCCESS:do { switch(ccSwitch1.length()) {
+case 18: { switch(ccSwitch1.charAt(0)) { case 's': if ("stringFromCharCode".equals(ccSwitch1)) { if (true) do {
+char buf[] = new char[nargs];
+for(int i=0; i<nargs; i++) buf[i] = (char)(JS.toInt(i==0?a0:i==1?a1:i==2?a2:rest[i-3]) & 0xffff);
+return new String(buf);
+ } while(false); break SUCCESS; } break; }; break; } } /* switch */ } while(false); /* OUTER */
+ break;
+ }
+ case 1: {
+final String ccSwitch2 = (String)(method); SUCCESS:do { switch(ccSwitch2.length()) {
+case 5: { switch(ccSwitch2.charAt(0)) { case 'i': if ("isNaN".equals(ccSwitch2)) { if (true) do { { double d = toDouble(a0); return d == d ? F : T; }
+ } while(false); break SUCCESS; } break; }; break; } case 6: { switch(ccSwitch2.charAt(0)) { case 'e': if ("escape".equals(ccSwitch2)) { if (true) do { throw new JSExn("unimplemented");
+ } while(false); break SUCCESS; } break; }; break; } case 8: { switch(ccSwitch2.charAt(0)) { case 'i': if ("isFinite".equals(ccSwitch2)) { if (true) do { { double d = toDouble(a0); return (d == d && !Double.isInfinite(d)) ? T : F; }
+ } while(false); break SUCCESS; } break; case 'p': if ("parseInt".equals(ccSwitch2)) { if (true) do { return parseInt(a0, N(0));
+ } while(false); break SUCCESS; } break; case 'u': if ("unescape".equals(ccSwitch2)) { if (true) do { throw new JSExn("unimplemented");
+ } while(false); break SUCCESS; } break; }; break; } case 9: { switch(ccSwitch2.charAt(0)) { case 'd': if ("decodeURI".equals(ccSwitch2)) { if (true) do { throw new JSExn("unimplemented");
+ } while(false); break SUCCESS; } break; case 'e': if ("encodeURI".equals(ccSwitch2)) { if (true) do { throw new JSExn("unimplemented");
+ } while(false); break SUCCESS; } break; }; break; } case 18: { switch(ccSwitch2.charAt(0)) { case 'd': if ("decodeURIComponent".equals(ccSwitch2)) { if (true) do { throw new JSExn("unimplemented");
+ } while(false); break SUCCESS; } break; case 'e': if ("encodeURIComponent".equals(ccSwitch2)) { if (true) do { throw new JSExn("unimplemented");
+ } while(false); break SUCCESS; } break; }; break; } } /* switch */ } while(false); /* OUTER */
+ break;
+ }
+ case 2: {
+final String ccSwitch3 = (String)(method); SUCCESS:do { switch(ccSwitch3.length()) {
+case 8: { switch(ccSwitch3.charAt(0)) { case 'p': if ("parseInt".equals(ccSwitch3)) { if (true) do { return parseInt(a0, a1);
+ } while(false); break SUCCESS; } break; }; break; } } /* switch */ } while(false); /* OUTER */
+ break;
+ }
+ }
+ return super.callMethod(method, a0, a1, a2, rest, nargs);
+ }
+
+ private Object parseInt(Object arg, Object r) {
+ int radix = JS.toInt(r);
+ String s = (String)arg;
+ int start = 0;
+ int length = s.length();
+ int sign = 1;
+ long n = 0;
+ if(radix != 0 && (radix < 2 || radix > 36)) return NaN;
+ while(start < length && Character.isWhitespace(s.charAt(start))) start++;
+ if((length >= start+1) && (s.charAt(start) == '+' || s.charAt(start) == '-')) {
+ sign = s.charAt(start) == '+' ? 1 : -1;
+ start++;
+ }
+ if(radix == 0 && length >= start+1 && s.charAt(start) == '0') {
+ start++;
+ if(length >= start+1 && (s.charAt(start) == 'x' || s.charAt(start) == 'X')) {
+ start++;
+ radix = 16;
+ } else {
+ radix = 8;
+ if(length == start || Character.digit(s.charAt(start+1),8)==-1) return JS.ZERO;
+ }
+ }
+ if(radix == 0) radix = 10;
+ if(length == start || Character.digit(s.charAt(start),radix) == -1) return NaN;
+ // try the fast way first
+ try {
+ String s2 = start == 0 ? s : s.substring(start);
+ return JS.N(sign*Integer.parseInt(s2,radix));
+ } catch(NumberFormatException e) { }
+ // fall through to a slower but emca-compliant method
+ for(int i=start;i<length;i++) {
+ int digit = Character.digit(s.charAt(i),radix);
+ if(digit < 0) break;
+ n = n*radix + digit;
+ if(n < 0) return NaN; // overflow;
+ }
+ if(n <= Integer.MAX_VALUE) return JS.N(sign*(int)n);
+ return JS.N((long)sign*n);
+ }
+
+ private Object parseFloat(Object arg) {
+ String s = (String)arg;
+ int start = 0;
+ int length = s.length();
+ while(start < length && Character.isWhitespace(s.charAt(0))) start++;
+ int end = length;
+ // as long as the string has no trailing garbage,this is fast, its slow with
+ // trailing garbage
+ while(start < end) {
+ try {
+ return JS.N(s.substring(start,length));
+ } catch(NumberFormatException e) { }
+ end--;
+ }
+ return NaN;
+ }
+ }
+}
+
--- /dev/null
+// Derived from org.mozilla.javascript.TokenStream [NPL]
+
+/**
+ * The contents of this file are subject to the Netscape Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/NPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * The Initial Developer of the Original Code is Netscape
+ * Communications Corporation.
+ *
+ * Contributor(s): Roger Lawrence, Mike McCabe
+ */
+
+package org.ibex.js;
+import java.io.*;
+
+/** Lexes a stream of characters into a stream of Tokens */
+class Lexer implements Tokens {
+
+ /** for debugging */
+ public static void main(String[] s) throws IOException {
+ Lexer l = new Lexer(new InputStreamReader(System.in), "stdin", 0);
+ int tok = 0;
+ while((tok = l.getToken()) != -1) System.out.println(codeToString[tok]);
+ }
+
+ /** the token that was just parsed */
+ protected int op;
+
+ /** the most recently parsed token, <i>regardless of pushbacks</i> */
+ protected int mostRecentlyReadToken;
+
+ /** if the token just parsed was a NUMBER, this is the numeric value */
+ protected Number number = null;
+
+ /** if the token just parsed was a NAME or STRING, this is the string value */
+ protected String string = null;
+
+ /** the line number of the most recently <i>lexed</i> token */
+ protected int line = 0;
+
+ /** the line number of the most recently <i>parsed</i> token */
+ protected int parserLine = 0;
+
+ /** the column number of the current token */
+ protected int col = 0;
+
+ /** the name of the source code file being lexed */
+ protected String sourceName;
+
+ private SmartReader in;
+ public Lexer(Reader r, String sourceName, int line) throws IOException {
+ this.sourceName = sourceName;
+ this.line = line;
+ this.parserLine = line;
+ in = new SmartReader(r);
+ }
+
+
+ // Predicates ///////////////////////////////////////////////////////////////////////
+
+ private static boolean isAlpha(int c) { return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')); }
+ private static boolean isDigit(int c) { return (c >= '0' && c <= '9'); }
+ private static int xDigitToInt(int c) {
+ if ('0' <= c && c <= '9') return c - '0';
+ else if ('a' <= c && c <= 'f') return c - ('a' - 10);
+ else if ('A' <= c && c <= 'F') return c - ('A' - 10);
+ else return -1;
+ }
+
+
+ // Token Subtype Handlers /////////////////////////////////////////////////////////
+
+ private int getKeyword(String name) throws IOException {
+final String ccSwitch0 = (String)(name); SUCCESS:do { switch(ccSwitch0.length()) {
+case 2: { switch(ccSwitch0.charAt(0)) { case 'd': if ("do".equals(ccSwitch0)) { if (true) do { return DO;
+ } while(false); break SUCCESS; } break; case 'g': if ("gt".equals(ccSwitch0)) { if (true) do { return GT;
+ } while(false); break SUCCESS; } break; case 'i': { switch(ccSwitch0.charAt(1)) { case 'f': if ("if".equals(ccSwitch0)) { if (true) do { return IF;
+ } while(false); break SUCCESS; } break; case 'n': if ("in".equals(ccSwitch0)) { if (true) do { return IN;
+ } while(false); break SUCCESS; } break; } break; } case 'l': if ("lt".equals(ccSwitch0)) { if (true) do { return LT;
+ } while(false); break SUCCESS; } break; case 'o': if ("or".equals(ccSwitch0)) { if (true) do { return OR;
+ } while(false); break SUCCESS; } break; }; break; } case 3: { switch(ccSwitch0.charAt(0)) { case 'a': if ("and".equals(ccSwitch0)) { if (true) do { return AND;
+ } while(false); break SUCCESS; } break; case 'f': if ("for".equals(ccSwitch0)) { if (true) do { return FOR;
+ } while(false); break SUCCESS; } break; case 'i': if ("int".equals(ccSwitch0)) { if (true) do { return RESERVED;
+ } while(false); break SUCCESS; } break; case 'n': if ("new".equals(ccSwitch0)) { if (true) do { return RESERVED;
+ } while(false); break SUCCESS; } break; case 't': if ("try".equals(ccSwitch0)) { if (true) do { return TRY;
+ } while(false); break SUCCESS; } break; case 'v': if ("var".equals(ccSwitch0)) { if (true) do { return VAR;
+ } while(false); break SUCCESS; } break; }; break; } case 4: { switch(ccSwitch0.charAt(0)) { case 'b': if ("byte".equals(ccSwitch0)) { if (true) do { return RESERVED;
+ } while(false); break SUCCESS; } break; case 'c': { switch(ccSwitch0.charAt(1)) { case 'a': if ("case".equals(ccSwitch0)) { if (true) do { return CASE;
+ } while(false); break SUCCESS; } break; case 'h': if ("char".equals(ccSwitch0)) { if (true) do { return RESERVED;
+ } while(false); break SUCCESS; } break; } break; } case 'e': { switch(ccSwitch0.charAt(1)) { case 'l': if ("else".equals(ccSwitch0)) { if (true) do { return ELSE;
+ } while(false); break SUCCESS; } break; case 'n': if ("enum".equals(ccSwitch0)) { if (true) do { return RESERVED;
+ } while(false); break SUCCESS; } break; } break; } case 'g': if ("goto".equals(ccSwitch0)) { if (true) do { return RESERVED;
+ } while(false); break SUCCESS; } break; case 'l': if ("long".equals(ccSwitch0)) { if (true) do { return RESERVED;
+ } while(false); break SUCCESS; } break; case 'n': if ("null".equals(ccSwitch0)) { if (true) do { return NULL;
+ } while(false); break SUCCESS; } break; case 't': if ("true".equals(ccSwitch0)) { if (true) do { return TRUE;
+ } while(false); break SUCCESS; } break; case 'v': if ("void".equals(ccSwitch0)) { if (true) do { return RESERVED;
+ } while(false); break SUCCESS; } break; case 'w': if ("with".equals(ccSwitch0)) { if (true) do { return RESERVED;
+ } while(false); break SUCCESS; } break; }; break; } case 5: { switch(ccSwitch0.charAt(0)) { case 'b': if ("break".equals(ccSwitch0)) { if (true) do { return BREAK;
+ } while(false); break SUCCESS; } break; case 'c': { switch(ccSwitch0.charAt(1)) { case 'a': if ("catch".equals(ccSwitch0)) { if (true) do { return CATCH;
+ } while(false); break SUCCESS; } break; case 'l': if ("class".equals(ccSwitch0)) { if (true) do { return RESERVED;
+ } while(false); break SUCCESS; } break; case 'o': if ("const".equals(ccSwitch0)) { if (true) do { return RESERVED;
+ } while(false); break SUCCESS; } break; } break; } case 'f': { switch(ccSwitch0.charAt(1)) { case 'a': if ("false".equals(ccSwitch0)) { if (true) do { return FALSE;
+ } while(false); break SUCCESS; } break; case 'i': if ("final".equals(ccSwitch0)) { if (true) do { return RESERVED;
+ } while(false); break SUCCESS; } break; } break; } case 's': if ("super".equals(ccSwitch0)) { if (true) do { return RESERVED;
+ } while(false); break SUCCESS; } break; case 't': if ("throw".equals(ccSwitch0)) { if (true) do { return THROW;
+ } while(false); break SUCCESS; } break; case 'w': if ("while".equals(ccSwitch0)) { if (true) do { return WHILE;
+ } while(false); break SUCCESS; } break; }; break; } case 6: { switch(ccSwitch0.charAt(0)) { case 'a': if ("assert".equals(ccSwitch0)) { if (true) do { return ASSERT;
+ } while(false); break SUCCESS; } break; case 'd': { switch(ccSwitch0.charAt(1)) { case 'e': if ("delete".equals(ccSwitch0)) { if (true) do { return RESERVED;
+ } while(false); break SUCCESS; } break; case 'o': if ("double".equals(ccSwitch0)) { if (true) do { return RESERVED;
+ } while(false); break SUCCESS; } break; } break; } case 'p': if ("public".equals(ccSwitch0)) { if (true) do { return RESERVED;
+ } while(false); break SUCCESS; } break; case 'r': if ("return".equals(ccSwitch0)) { if (true) do { return RETURN;
+ } while(false); break SUCCESS; } break; case 's': if ("switch".equals(ccSwitch0)) { if (true) do { return SWITCH;
+ } while(false); break SUCCESS; } break; case 't': { switch(ccSwitch0.charAt(1)) { case 'h': if ("throws".equals(ccSwitch0)) { if (true) do { return RESERVED;
+ } while(false); break SUCCESS; } break; case 'y': if ("typeof".equals(ccSwitch0)) { if (true) do { return TYPEOF;
+ } while(false); break SUCCESS; } break; } break; } }; break; } case 7: { switch(ccSwitch0.charAt(0)) { case 'b': if ("boolean".equals(ccSwitch0)) { if (true) do { return RESERVED;
+ } while(false); break SUCCESS; } break; case 'd': if ("default".equals(ccSwitch0)) { if (true) do { return DEFAULT;
+ } while(false); break SUCCESS; } break; case 'e': if ("extends".equals(ccSwitch0)) { if (true) do { return RESERVED;
+ } while(false); break SUCCESS; } break; case 'f': if ("finally".equals(ccSwitch0)) { if (true) do { return FINALLY;
+ } while(false); break SUCCESS; } break; case 'p': { switch(ccSwitch0.charAt(1)) { case 'a': if ("package".equals(ccSwitch0)) { if (true) do { return RESERVED;
+ } while(false); break SUCCESS; } break; case 'r': if ("private".equals(ccSwitch0)) { if (true) do { return RESERVED;
+ } while(false); break SUCCESS; } break; } break; } }; break; } case 8: { switch(ccSwitch0.charAt(0)) { case 'a': if ("abstract".equals(ccSwitch0)) { if (true) do { return RESERVED;
+ } while(false); break SUCCESS; } break; case 'c': if ("continue".equals(ccSwitch0)) { if (true) do { return CONTINUE;
+ } while(false); break SUCCESS; } break; case 'd': if ("debugger".equals(ccSwitch0)) { if (true) do { return RESERVED;
+ } while(false); break SUCCESS; } break; case 'f': if ("function".equals(ccSwitch0)) { if (true) do { return FUNCTION;
+ } while(false); break SUCCESS; } break; case 'v': if ("volatile".equals(ccSwitch0)) { if (true) do { return RESERVED;
+ } while(false); break SUCCESS; } break; }; break; } case 9: { switch(ccSwitch0.charAt(0)) { case 'i': if ("interface".equals(ccSwitch0)) { if (true) do { return RESERVED;
+ } while(false); break SUCCESS; } break; case 'p': if ("protected".equals(ccSwitch0)) { if (true) do { return RESERVED;
+ } while(false); break SUCCESS; } break; case 't': if ("transient".equals(ccSwitch0)) { if (true) do { return RESERVED;
+ } while(false); break SUCCESS; } break; }; break; } case 10: { switch(ccSwitch0.charAt(0)) { case 'i': { switch(ccSwitch0.charAt(1)) { case 'm': if ("implements".equals(ccSwitch0)) { if (true) do { return RESERVED;
+ } while(false); break SUCCESS; } break; case 'n': if ("instanceof".equals(ccSwitch0)) { if (true) do { return RESERVED;
+ } while(false); break SUCCESS; } break; } break; } }; break; } case 12: { switch(ccSwitch0.charAt(0)) { case 's': if ("synchronized".equals(ccSwitch0)) { if (true) do { return RESERVED;
+ } while(false); break SUCCESS; } break; }; break; } } /* switch */ } while(false); /* OUTER */
+ return -1;
+ }
+
+ private int getIdentifier(int c) throws IOException {
+ in.startString();
+ while (Character.isJavaIdentifierPart((char)(c = in.read())));
+ in.unread();
+ String str = in.getString();
+ int result = getKeyword(str);
+ if (result == RESERVED) throw new LexerException("The reserved word \"" + str + "\" is not permitted in Ibex scripts");
+ if (result != -1) return result;
+ this.string = str.intern();
+ return NAME;
+ }
+
+ private int getNumber(int c) throws IOException {
+ int base = 10;
+ in.startString();
+ double dval = Double.NaN;
+ long longval = 0;
+ boolean isInteger = true;
+
+ // figure out what base we're using
+ if (c == '0') {
+ if (Character.toLowerCase((char)(c = in.read())) == 'x') { base = 16; in.startString(); }
+ else if (isDigit(c)) base = 8;
+ }
+
+ while (0 <= xDigitToInt(c) && !(base < 16 && isAlpha(c))) c = in.read();
+ if (base == 10 && (c == '.' || c == 'e' || c == 'E')) {
+ isInteger = false;
+ if (c == '.') do { c = in.read(); } while (isDigit(c));
+ if (c == 'e' || c == 'E') {
+ c = in.read();
+ if (c == '+' || c == '-') c = in.read();
+ if (!isDigit(c)) throw new LexerException("float listeral did not have an exponent value");
+ do { c = in.read(); } while (isDigit(c));
+ }
+ }
+ in.unread();
+
+ String numString = in.getString();
+ if (base == 10 && !isInteger) {
+ try { dval = (Double.valueOf(numString)).doubleValue(); }
+ catch (NumberFormatException ex) { throw new LexerException("invalid numeric literal: \"" + numString + "\""); }
+ } else {
+ if (isInteger) {
+ longval = Long.parseLong(numString, base);
+ dval = (double)longval;
+ } else {
+ dval = Double.parseDouble(numString);
+ longval = (long) dval;
+ if (longval == dval) isInteger = true;
+ }
+ }
+
+ if (!isInteger) this.number = JS.N(dval);
+ else this.number = JS.N(longval);
+ return NUMBER;
+ }
+
+ private int getString(int c) throws IOException {
+ StringBuffer stringBuf = null;
+ int quoteChar = c;
+ c = in.read();
+ in.startString(); // start after the first "
+ while(c != quoteChar) {
+ if (c == '\n' || c == -1) throw new LexerException("unterminated string literal");
+ if (c == '\\') {
+ if (stringBuf == null) {
+ in.unread(); // Don't include the backslash
+ stringBuf = new StringBuffer(in.getString());
+ in.read();
+ }
+ switch (c = in.read()) {
+ case 'b': c = '\b'; break;
+ case 'f': c = '\f'; break;
+ case 'n': c = '\n'; break;
+ case 'r': c = '\r'; break;
+ case 't': c = '\t'; break;
+ case 'v': c = '\u000B'; break;
+ case '\\': c = '\\'; break;
+ case 'u': {
+ int v = 0;
+ for(int i=0; i<4; i++) {
+ int ci = in.read();
+ if (!((ci >= '0' && ci <= '9') || (ci >= 'a' && ci <= 'f') || (ci >= 'A' && ci <= 'F')))
+ throw new LexerException("illegal character '" + ((char)c) + "' in \\u unicode escape sequence");
+ v = (v << 8) | Integer.parseInt(ci + "", 16);
+ }
+ c = (char)v;
+ break;
+ }
+ default:
+ // just use the character that was escaped
+ break;
+ }
+ }
+ if (stringBuf != null) stringBuf.append((char) c);
+ c = in.read();
+ }
+ if (stringBuf != null) this.string = stringBuf.toString().intern();
+ else {
+ in.unread(); // miss the trailing "
+ this.string = in.getString().intern();
+ in.read();
+ }
+ return STRING;
+ }
+
+ private int _getToken() throws IOException {
+ int c;
+ do { c = in.read(); } while (c == '\u0020' || c == '\u0009' || c == '\u000C' || c == '\u000B' || c == '\n' );
+ if (c == -1) return -1;
+ if (c == '\\' || Character.isJavaIdentifierStart((char)c)) return getIdentifier(c);
+ if (isDigit(c) || (c == '.' && isDigit(in.peek()))) return getNumber(c);
+ if (c == '"' || c == '\'') return getString(c);
+ switch (c) {
+ case ';': return SEMI;
+ case '[': return LB;
+ case ']': return RB;
+ case '{': return LC;
+ case '}': return RC;
+ case '(': return LP;
+ case ')': return RP;
+ case ',': return COMMA;
+ case '?': return HOOK;
+ case ':': return !in.match(':') ? COLON : in.match('=') ? GRAMMAR : le(":: is not a valid token");
+ case '.': return DOT;
+ case '|': return in.match('|') ? OR : (in.match('=') ? ASSIGN_BITOR : BITOR);
+ case '^': return in.match('=') ? ASSIGN_BITXOR : BITXOR;
+ case '&': return in.match('&') ? AND : in.match('=') ? ASSIGN_BITAND : BITAND;
+ case '=': return !in.match('=') ? ASSIGN : in.match('=') ? SHEQ : EQ;
+ case '!': return !in.match('=') ? BANG : in.match('=') ? SHNE : NE;
+ case '%': return in.match('=') ? ASSIGN_MOD : MOD;
+ case '~': return BITNOT;
+ case '+': return in.match('=') ? ASSIGN_ADD : in.match('+') ? (in.match('=') ? ADD_TRAP : INC) : ADD;
+ case '-': return in.match('=') ? ASSIGN_SUB: in.match('-') ? (in.match('=') ? DEL_TRAP : DEC) : SUB;
+ case '*': return in.match('=') ? ASSIGN_MUL : MUL;
+ case '<': return !in.match('<') ? (in.match('=') ? LE : LT) : in.match('=') ? ASSIGN_LSH : LSH;
+ case '>': return !in.match('>') ? (in.match('=') ? GE : GT) :
+ in.match('>') ? (in.match('=') ? ASSIGN_URSH : URSH) : (in.match('=') ? ASSIGN_RSH : RSH);
+ case '/':
+ if (in.match('=')) return ASSIGN_DIV;
+ if (in.match('/')) { while ((c = in.read()) != -1 && c != '\n'); in.unread(); return getToken(); }
+ if (!in.match('*')) return DIV;
+ while ((c = in.read()) != -1 && !(c == '*' && in.match('/'))) {
+ if (c == '\n' || c != '/' || !in.match('*')) continue;
+ if (in.match('/')) return getToken();
+ throw new LexerException("nested comments are not permitted");
+ }
+ if (c == -1) throw new LexerException("unterminated comment");
+ return getToken(); // `goto retry'
+ default: throw new LexerException("illegal character: \'" + ((char)c) + "\'");
+ }
+ }
+
+ private int le(String s) throws LexerException { if (true) throw new LexerException(s); return 0; }
+
+ // SmartReader ////////////////////////////////////////////////////////////////
+
+ /** a Reader that tracks line numbers and can push back tokens */
+ private class SmartReader {
+ PushbackReader reader = null;
+ int lastread = -1;
+
+ public SmartReader(Reader r) { reader = new PushbackReader(r); }
+ public void unread() throws IOException { unread((char)lastread); }
+ public void unread(char c) throws IOException {
+ reader.unread(c);
+ if(c == '\n') col = -1;
+ else col--;
+ if (accumulator != null) accumulator.setLength(accumulator.length() - 1);
+ }
+ public boolean match(char c) throws IOException { if (peek() == c) { reader.read(); return true; } else return false; }
+ public int peek() throws IOException {
+ int peeked = reader.read();
+ if (peeked != -1) reader.unread((char)peeked);
+ return peeked;
+ }
+ public int read() throws IOException {
+ lastread = reader.read();
+ if (accumulator != null) accumulator.append((char)lastread);
+ if (lastread != '\n' && lastread != '\r') col++;
+ if (lastread == '\n') {
+ // col is -1 if we just unread a newline, this is sort of ugly
+ if (col != -1) parserLine = ++line;
+ col = 0;
+ }
+ return lastread;
+ }
+
+ // FEATURE: could be much more efficient
+ StringBuffer accumulator = null;
+ public void startString() {
+ accumulator = new StringBuffer();
+ accumulator.append((char)lastread);
+ }
+ public String getString() throws IOException {
+ String ret = accumulator.toString().intern();
+ accumulator = null;
+ return ret;
+ }
+ }
+
+
+ // Token PushBack code ////////////////////////////////////////////////////////////
+
+ private int pushBackDepth = 0;
+ private int[] pushBackInts = new int[10];
+ private Object[] pushBackObjects = new Object[10];
+
+ /** push back a token */
+ public final void pushBackToken(int op, Object obj) {
+ if (pushBackDepth >= pushBackInts.length - 1) {
+ int[] newInts = new int[pushBackInts.length * 2];
+ System.arraycopy(pushBackInts, 0, newInts, 0, pushBackInts.length);
+ pushBackInts = newInts;
+ Object[] newObjects = new Object[pushBackObjects.length * 2];
+ System.arraycopy(pushBackObjects, 0, newObjects, 0, pushBackObjects.length);
+ pushBackObjects = newObjects;
+ }
+ pushBackInts[pushBackDepth] = op;
+ pushBackObjects[pushBackDepth] = obj;
+ pushBackDepth++;
+ }
+
+ /** push back the most recently read token */
+ public final void pushBackToken() { pushBackToken(op, number != null ? (Object)number : (Object)string); }
+
+ /** read a token but leave it in the stream */
+ public final int peekToken() throws IOException {
+ int ret = getToken();
+ pushBackToken();
+ return ret;
+ }
+
+ /** read a token */
+ public final int getToken() throws IOException {
+ number = null;
+ string = null;
+ if (pushBackDepth == 0) {
+ mostRecentlyReadToken = op;
+ return op = _getToken();
+ }
+ pushBackDepth--;
+ op = pushBackInts[pushBackDepth];
+ if (pushBackObjects[pushBackDepth] != null) {
+ number = pushBackObjects[pushBackDepth] instanceof Number ? (Number)pushBackObjects[pushBackDepth] : null;
+ string = pushBackObjects[pushBackDepth] instanceof String ? (String)pushBackObjects[pushBackDepth] : null;
+ }
+ return op;
+ }
+
+ class LexerException extends IOException {
+ public LexerException(String s) { super(sourceName + ":" + line + "," + col + ": " + s); }
+ }
+}
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.js;
+
+import org.ibex.util.*;
+import java.io.*;
+
+/**
+ * Parses a stream of lexed tokens into a tree of JSFunction's.
+ *
+ * There are three kinds of things we parse: blocks, statements, and
+ * expressions.
+ *
+ * - Expressions are a special type of statement that evaluates to a
+ * value (for example, "break" is not an expression, * but "3+2"
+ * is). Some tokens sequences start expressions (for * example,
+ * literal numbers) and others continue an expression which * has
+ * already been begun (for example, '+'). Finally, some *
+ * expressions are valid targets for an assignment operation; after
+ * * each of these expressions, continueExprAfterAssignable() is
+ * called * to check for an assignment operation.
+ *
+ * - A statement ends with a semicolon and does not return a value.
+ *
+ * - A block is a single statement or a sequence of statements
+ * surrounded by curly braces.
+ *
+ * Each parsing method saves the parserLine before doing its actual
+ * work and restores it afterwards. This ensures that parsing a
+ * subexpression does not modify the line number until a token
+ * *after* the subexpression has been consumed by the parent
+ * expression.
+ *
+ * Technically it would be a better design for this class to build an
+ * intermediate parse tree and use that to emit bytecode. Here's the
+ * tradeoff:
+ *
+ * Advantages of building a parse tree:
+ * - easier to apply optimizations
+ * - would let us handle more sophisticated languages than JavaScript
+ *
+ * Advantages of leaving out the parse tree
+ * - faster compilation
+ * - less load on the garbage collector
+ * - much simpler code, easier to understand
+ * - less error-prone
+ *
+ * Fortunately JS is such a simple language that we can get away with
+ * the half-assed approach and still produce a working, complete
+ * compiler.
+ *
+ * The bytecode language emitted doesn't really cause any appreciable
+ * semantic loss, and is itself a parseable language very similar to
+ * Forth or a postfix variant of LISP. This means that the bytecode
+ * can be transformed into a parse tree, which can be manipulated.
+ * So if we ever want to add an optimizer, it could easily be done by
+ * producing a parse tree from the bytecode, optimizing that tree,
+ * and then re-emitting the bytecode. The parse tree node class
+ * would also be much simpler since the bytecode language has so few
+ * operators.
+ *
+ * Actually, the above paragraph is slightly inaccurate -- there are
+ * places where we push a value and then perform an arbitrary number
+ * of operations using it before popping it; this doesn't parse well.
+ * But these cases are clearly marked and easy to change if we do
+ * need to move to a parse tree format.
+ */
+class Parser extends Lexer implements ByteCodes {
+
+
+ // Constructors //////////////////////////////////////////////////////
+
+ public Parser(Reader r, String sourceName, int line) throws IOException { super(r, sourceName, line); }
+
+ /** for debugging */
+ public static void main(String[] s) throws IOException {
+ JS block = JS.fromReader("stdin", 0, new InputStreamReader(System.in));
+ if (block == null) return;
+ System.out.println(block);
+ }
+
+
+ // Statics ////////////////////////////////////////////////////////////
+
+ static byte[] precedence = new byte[MAX_TOKEN + 1];
+ static boolean[] isRightAssociative = new boolean[MAX_TOKEN + 1];
+ // Use this as the precedence when we want anything up to the comma
+ private final static int NO_COMMA = 2;
+ static {
+ isRightAssociative[ASSIGN] =
+ isRightAssociative[ASSIGN_BITOR] =
+ isRightAssociative[ASSIGN_BITXOR] =
+ isRightAssociative[ASSIGN_BITAND] =
+ isRightAssociative[ASSIGN_LSH] =
+ isRightAssociative[ASSIGN_RSH] =
+ isRightAssociative[ASSIGN_URSH] =
+ isRightAssociative[ASSIGN_ADD] =
+ isRightAssociative[ASSIGN_SUB] =
+ isRightAssociative[ASSIGN_MUL] =
+ isRightAssociative[ASSIGN_DIV] =
+ isRightAssociative[ASSIGN_MOD] =
+ isRightAssociative[ADD_TRAP] =
+ isRightAssociative[DEL_TRAP] =
+ true;
+
+ precedence[COMMA] = 1;
+ // 2 is intentionally left unassigned. we use minPrecedence==2 for comma separated lists
+ precedence[ASSIGN] =
+ precedence[ASSIGN_BITOR] =
+ precedence[ASSIGN_BITXOR] =
+ precedence[ASSIGN_BITAND] =
+ precedence[ASSIGN_LSH] =
+ precedence[ASSIGN_RSH] =
+ precedence[ASSIGN_URSH] =
+ precedence[ASSIGN_ADD] =
+ precedence[ASSIGN_SUB] =
+ precedence[ASSIGN_MUL] =
+ precedence[ASSIGN_DIV] =
+ precedence[ADD_TRAP] =
+ precedence[DEL_TRAP] =
+ precedence[ASSIGN_MOD] = 3;
+ precedence[HOOK] = 4;
+ precedence[OR] = 5;
+ precedence[AND] = 6;
+ precedence[BITOR] = 7;
+ precedence[BITXOR] = 8;
+ precedence[BITAND] = 9;
+ precedence[EQ] = precedence[NE] = precedence[SHEQ] = precedence[SHNE] = 10;
+ precedence[LT] = precedence[LE] = precedence[GT] = precedence[GE] = 11;
+ precedence[LSH] = precedence[RSH] = precedence[URSH] = 12;
+ precedence[ADD] = precedence[SUB] = 12;
+ precedence[MUL] = precedence[DIV] = precedence[MOD] = 13;
+ precedence[BITNOT] = precedence[BANG] = precedence[TYPEOF] = 14;
+ precedence[DOT] = precedence[LB] = precedence[LP] = precedence[INC] = precedence[DEC] = 15;
+ }
+
+
+ // Parsing Logic /////////////////////////////////////////////////////////
+
+ /** gets a token and throws an exception if it is not <tt>code</tt> */
+ private void consume(int code) throws IOException {
+ if (getToken() != code) {
+ if(code == NAME) switch(op) {
+ case RETURN: case TYPEOF: case BREAK: case CONTINUE: case TRY: case THROW:
+ case ASSERT: case NULL: case TRUE: case FALSE: case IN: case IF: case ELSE:
+ case SWITCH: case CASE: case DEFAULT: case WHILE: case VAR: case WITH:
+ case CATCH: case FINALLY:
+ throw pe("Bad variable name; '" + codeToString[op].toLowerCase() + "' is a javascript keyword");
+ }
+ throw pe("expected " + codeToString[code] + ", got " + (op == -1 ? "EOF" : codeToString[op]));
+ }
+ }
+
+ /**
+ * Parse the largest possible expression containing no operators
+ * of precedence below <tt>minPrecedence</tt> and append the
+ * bytecodes for that expression to <tt>appendTo</tt>; the
+ * appended bytecodes MUST grow the stack by exactly one element.
+ */
+ private void startExpr(JSFunction appendTo, int minPrecedence) throws IOException {
+ int saveParserLine = parserLine;
+ _startExpr(appendTo, minPrecedence);
+ parserLine = saveParserLine;
+ }
+ private void _startExpr(JSFunction appendTo, int minPrecedence) throws IOException {
+ int tok = getToken();
+ JSFunction b = appendTo;
+
+ switch (tok) {
+ case -1: throw pe("expected expression");
+
+ // all of these simply push values onto the stack
+ case NUMBER: b.add(parserLine, LITERAL, number); break;
+ case STRING: b.add(parserLine, LITERAL, string); break;
+ case NULL: b.add(parserLine, LITERAL, null); break;
+ case TRUE: case FALSE: b.add(parserLine, LITERAL, JS.B(tok == TRUE)); break;
+
+ // (.foo) syntax
+ case DOT: {
+ consume(NAME);
+ b.add(parserLine, TOPSCOPE);
+ b.add(parserLine, LITERAL, "");
+ b.add(parserLine, GET);
+ b.add(parserLine, LITERAL, string);
+ b.add(parserLine, GET);
+ continueExpr(b, minPrecedence);
+ break;
+ }
+
+ case LB: {
+ b.add(parserLine, ARRAY, JS.ZERO); // push an array onto the stack
+ int size0 = b.size;
+ int i = 0;
+ if (peekToken() != RB)
+ while(true) { // iterate over the initialization values
+ b.add(parserLine, LITERAL, JS.N(i++)); // push the index in the array to place it into
+ if (peekToken() == COMMA || peekToken() == RB)
+ b.add(parserLine, LITERAL, null); // for stuff like [1,,2,]
+ else
+ startExpr(b, NO_COMMA); // push the value onto the stack
+ b.add(parserLine, PUT); // put it into the array
+ b.add(parserLine, POP); // discard the value remaining on the stack
+ if (peekToken() == RB) break;
+ consume(COMMA);
+ }
+ b.set(size0 - 1, JS.N(i)); // back at the ARRAY instruction, write the size of the array
+ consume(RB);
+ break;
+ }
+ case SUB: { // negative literal (like "3 * -1")
+ consume(NUMBER);
+ b.add(parserLine, LITERAL, JS.N(number.doubleValue() * -1));
+ break;
+ }
+ case LP: { // grouping (not calling)
+ startExpr(b, -1);
+ consume(RP);
+ break;
+ }
+ case INC: case DEC: { // prefix (not postfix)
+ startExpr(b, precedence[tok]);
+ int prev = b.size - 1;
+ if (b.get(prev) == GET && b.getArg(prev) != null)
+ b.set(prev, LITERAL, b.getArg(prev));
+ else if(b.get(prev) == GET)
+ b.pop();
+ else
+ throw pe("prefixed increment/decrement can only be performed on a valid assignment target");
+ b.add(parserLine, GET_PRESERVE, Boolean.TRUE);
+ b.add(parserLine, LITERAL, JS.N(1));
+ b.add(parserLine, tok == INC ? ADD : SUB, JS.N(2));
+ b.add(parserLine, PUT, null);
+ b.add(parserLine, SWAP, null);
+ b.add(parserLine, POP, null);
+ break;
+ }
+ case BANG: case BITNOT: case TYPEOF: {
+ startExpr(b, precedence[tok]);
+ b.add(parserLine, tok);
+ break;
+ }
+ case LC: { // object constructor
+ b.add(parserLine, OBJECT, null); // put an object on the stack
+ if (peekToken() != RC)
+ while(true) {
+ if (peekToken() != NAME && peekToken() != STRING)
+ throw pe("expected NAME or STRING");
+ getToken();
+ b.add(parserLine, LITERAL, string); // grab the key
+ consume(COLON);
+ startExpr(b, NO_COMMA); // grab the value
+ b.add(parserLine, PUT); // put the value into the object
+ b.add(parserLine, POP); // discard the remaining value
+ if (peekToken() == RC) break;
+ consume(COMMA);
+ if (peekToken() == RC) break; // we permit {,,} -- I'm not sure if ECMA does
+ }
+ consume(RC);
+ break;
+ }
+ case NAME: {
+ b.add(parserLine, TOPSCOPE);
+ b.add(parserLine, LITERAL, string);
+ continueExprAfterAssignable(b,minPrecedence);
+ break;
+ }
+ case FUNCTION: {
+ consume(LP);
+ int numArgs = 0;
+ JSFunction b2 = new JSFunction(sourceName, parserLine, null);
+ b.add(parserLine, NEWFUNCTION, b2);
+
+ // function prelude; arguments array is already on the stack
+ b2.add(parserLine, TOPSCOPE);
+ b2.add(parserLine, SWAP);
+ b2.add(parserLine, DECLARE, "arguments"); // declare arguments (equivalent to 'var arguments;')
+ b2.add(parserLine, SWAP); // set this.arguments and leave the value on the stack
+ b2.add(parserLine, PUT);
+
+ while(peekToken() != RP) { // run through the list of argument names
+ numArgs++;
+ if (peekToken() == NAME) {
+ consume(NAME); // a named argument
+ String varName = string;
+
+ b2.add(parserLine, DUP); // dup the args array
+ b2.add(parserLine, GET, JS.N(numArgs - 1)); // retrieve it from the arguments array
+ b2.add(parserLine, TOPSCOPE);
+ b2.add(parserLine, SWAP);
+ b2.add(parserLine, DECLARE, varName); // declare the name
+ b2.add(parserLine, SWAP);
+ b2.add(parserLine, PUT);
+ b2.add(parserLine, POP); // pop the value
+ b2.add(parserLine, POP); // pop the scope
+ }
+ if (peekToken() == RP) break;
+ consume(COMMA);
+ }
+ consume(RP);
+
+ b2.numFormalArgs = numArgs;
+ b2.add(parserLine, POP); // pop off the arguments array
+ b2.add(parserLine, POP); // pop off TOPSCOPE
+
+ if(peekToken() != LC)
+ throw pe("JSFunctions must have a block surrounded by curly brackets");
+
+ parseBlock(b2, null); // the function body
+
+ b2.add(parserLine, LITERAL, null); // in case we "fall out the bottom", return NULL
+ b2.add(parserLine, RETURN);
+
+ break;
+ }
+ default: throw pe("expected expression, found " + codeToString[tok] + ", which cannot start an expression");
+ }
+
+ // attempt to continue the expression
+ continueExpr(b, minPrecedence);
+ }
+ /*
+ private Grammar parseGrammar(Grammar g) throws IOException {
+ int tok = getToken();
+ if (g != null)
+ switch(tok) {
+ case BITOR: return new Grammar.Alternative(g, parseGrammar(null));
+ case ADD: return parseGrammar(new Grammar.Repetition(g, 1, Integer.MAX_VALUE));
+ case MUL: return parseGrammar(new Grammar.Repetition(g, 0, Integer.MAX_VALUE));
+ case HOOK: return parseGrammar(new Grammar.Repetition(g, 0, 1));
+ }
+ Grammar g0 = null;
+ switch(tok) {
+ //case NUMBER: g0 = new Grammar.Literal(number); break;
+ case NAME: g0 = new Grammar.Reference(string); break;
+ case STRING:
+ g0 = new Grammar.Literal(string);
+ if (peekToken() == DOT) {
+ String old = string;
+ consume(DOT);
+ consume(DOT);
+ consume(STRING);
+ if (old.length() != 1 || string.length() != 1) throw pe("literal ranges must be single-char strings");
+ g0 = new Grammar.Range(old.charAt(0), string.charAt(0));
+ }
+ break;
+ case LP: g0 = parseGrammar(null); consume(RP); break;
+ default: pushBackToken(); return g;
+ }
+ if (g == null) return parseGrammar(g0);
+ return parseGrammar(new Grammar.Juxtaposition(g, g0));
+ }
+ */
+ /**
+ * Assuming that a complete assignable (lvalue) has just been
+ * parsed and the object and key are on the stack,
+ * <tt>continueExprAfterAssignable</tt> will attempt to parse an
+ * expression that modifies the assignable. This method always
+ * decreases the stack depth by exactly one element.
+ */
+ private void continueExprAfterAssignable(JSFunction b,int minPrecedence) throws IOException {
+ int saveParserLine = parserLine;
+ _continueExprAfterAssignable(b,minPrecedence);
+ parserLine = saveParserLine;
+ }
+ private void _continueExprAfterAssignable(JSFunction b,int minPrecedence) throws IOException {
+ if (b == null) throw new Error("got null b; this should never happen");
+ int tok = getToken();
+ if (minPrecedence != -1 && (precedence[tok] < minPrecedence || (precedence[tok] == minPrecedence && !isRightAssociative[tok])))
+ // force the default case
+ tok = -1;
+ switch(tok) {
+ /*
+ case GRAMMAR: {
+ b.add(parserLine, GET_PRESERVE);
+ Grammar g = parseGrammar(null);
+ if (peekToken() == LC) {
+ g.action = new JSFunction(sourceName, parserLine, null);
+ parseBlock((JSFunction)g.action);
+ ((JSFunction)g.action).add(parserLine, LITERAL, null); // in case we "fall out the bottom", return NULL
+ ((JSFunction)g.action).add(parserLine, RETURN);
+ }
+ b.add(parserLine, MAKE_GRAMMAR, g);
+ b.add(parserLine, PUT);
+ break;
+ }
+ */
+ case ASSIGN_BITOR: case ASSIGN_BITXOR: case ASSIGN_BITAND: case ASSIGN_LSH: case ASSIGN_RSH: case ASSIGN_URSH:
+ case ASSIGN_MUL: case ASSIGN_DIV: case ASSIGN_MOD: case ASSIGN_ADD: case ASSIGN_SUB: case ADD_TRAP: case DEL_TRAP: {
+ if (tok != ADD_TRAP && tok != DEL_TRAP) b.add(parserLine, GET_PRESERVE);
+
+ startExpr(b, precedence[tok]);
+
+ if (tok != ADD_TRAP && tok != DEL_TRAP) {
+ // tok-1 is always s/^ASSIGN_// (0 is BITOR, 1 is ASSIGN_BITOR, etc)
+ b.add(parserLine, tok - 1, tok-1==ADD ? JS.N(2) : null);
+ b.add(parserLine, PUT);
+ b.add(parserLine, SWAP);
+ b.add(parserLine, POP);
+ } else {
+ b.add(parserLine, tok);
+ }
+ break;
+ }
+ case INC: case DEC: { // postfix
+ b.add(parserLine, GET_PRESERVE, Boolean.TRUE);
+ b.add(parserLine, LITERAL, JS.N(1));
+ b.add(parserLine, tok == INC ? ADD : SUB, JS.N(2));
+ b.add(parserLine, PUT, null);
+ b.add(parserLine, SWAP, null);
+ b.add(parserLine, POP, null);
+ b.add(parserLine, LITERAL, JS.N(1));
+ b.add(parserLine, tok == INC ? SUB : ADD, JS.N(2)); // undo what we just did, since this is postfix
+ break;
+ }
+ case ASSIGN: {
+ startExpr(b, precedence[tok]);
+ b.add(parserLine, PUT);
+ b.add(parserLine, SWAP);
+ b.add(parserLine, POP);
+ break;
+ }
+ case LP: {
+
+ // Method calls are implemented by doing a GET_PRESERVE
+ // first. If the object supports method calls, it will
+ // return JS.METHOD
+ int n = parseArgs(b, 2);
+ b.add(parserLine, GET_PRESERVE);
+ b.add(parserLine, CALLMETHOD, JS.N(n));
+ break;
+ }
+ default: {
+ pushBackToken();
+ if(b.get(b.size-1) == LITERAL && b.getArg(b.size-1) != null)
+ b.set(b.size-1,GET,b.getArg(b.size-1));
+ else
+ b.add(parserLine, GET);
+ return;
+ }
+ }
+ }
+
+
+ /**
+ * Assuming that a complete expression has just been parsed,
+ * <tt>continueExpr</tt> will attempt to extend this expression by
+ * parsing additional tokens and appending additional bytecodes.
+ *
+ * No operators with precedence less than <tt>minPrecedence</tt>
+ * will be parsed.
+ *
+ * If any bytecodes are appended, they will not alter the stack
+ * depth.
+ */
+ private void continueExpr(JSFunction b, int minPrecedence) throws IOException {
+ int saveParserLine = parserLine;
+ _continueExpr(b, minPrecedence);
+ parserLine = saveParserLine;
+ }
+ private void _continueExpr(JSFunction b, int minPrecedence) throws IOException {
+ if (b == null) throw new Error("got null b; this should never happen");
+ int tok = getToken();
+ if (tok == -1) return;
+ if (minPrecedence != -1 && (precedence[tok] < minPrecedence || (precedence[tok] == minPrecedence && !isRightAssociative[tok]))) {
+ pushBackToken();
+ return;
+ }
+
+ switch (tok) {
+ case LP: { // invocation (not grouping)
+ int n = parseArgs(b, 1);
+ b.add(parserLine, CALL, JS.N(n));
+ break;
+ }
+ case BITOR: case BITXOR: case BITAND: case SHEQ: case SHNE: case LSH:
+ case RSH: case URSH: case MUL: case DIV: case MOD:
+ case GT: case GE: case EQ: case NE: case LT: case LE: case SUB: {
+ startExpr(b, precedence[tok]);
+ b.add(parserLine, tok);
+ break;
+ }
+ case ADD: {
+ int count=1;
+ int nextTok;
+ do {
+ startExpr(b,precedence[tok]);
+ count++;
+ nextTok = getToken();
+ } while(nextTok == tok);
+ pushBackToken();
+ b.add(parserLine, tok, JS.N(count));
+ break;
+ }
+ case OR: case AND: {
+ b.add(parserLine, tok == AND ? JSFunction.JF : JSFunction.JT, JS.ZERO); // test to see if we can short-circuit
+ int size = b.size;
+ startExpr(b, precedence[tok]); // otherwise check the second value
+ b.add(parserLine, JMP, JS.N(2)); // leave the second value on the stack and jump to the end
+ b.add(parserLine, LITERAL, tok == AND ?
+ JS.B(false) : JS.B(true)); // target of the short-circuit jump is here
+ b.set(size - 1, JS.N(b.size - size)); // write the target of the short-circuit jump
+ break;
+ }
+ case DOT: {
+ // support foo..bar syntax for foo[""].bar
+ if (peekToken() == DOT) {
+ string = "";
+ } else {
+ consume(NAME);
+ }
+ b.add(parserLine, LITERAL, string);
+ continueExprAfterAssignable(b,minPrecedence);
+ break;
+ }
+ case LB: { // subscripting (not array constructor)
+ startExpr(b, -1);
+ consume(RB);
+ continueExprAfterAssignable(b,minPrecedence);
+ break;
+ }
+ case HOOK: {
+ b.add(parserLine, JF, JS.ZERO); // jump to the if-false expression
+ int size = b.size;
+ startExpr(b, minPrecedence); // write the if-true expression
+ b.add(parserLine, JMP, JS.ZERO); // if true, jump *over* the if-false expression
+ b.set(size - 1, JS.N(b.size - size + 1)); // now we know where the target of the jump is
+ consume(COLON);
+ size = b.size;
+ startExpr(b, minPrecedence); // write the if-false expression
+ b.set(size - 1, JS.N(b.size - size + 1)); // this is the end; jump to here
+ break;
+ }
+ case COMMA: {
+ // pop the result of the previous expression, it is ignored
+ b.add(parserLine,POP);
+ startExpr(b,-1);
+ break;
+ }
+ default: {
+ pushBackToken();
+ return;
+ }
+ }
+
+ continueExpr(b, minPrecedence); // try to continue the expression
+ }
+
+ // parse a set of comma separated function arguments, assume LP has already been consumed
+ // if swap is true, (because the function is already on the stack) we will SWAP after each argument to keep it on top
+ private int parseArgs(JSFunction b, int pushdown) throws IOException {
+ int i = 0;
+ while(peekToken() != RP) {
+ i++;
+ if (peekToken() != COMMA) {
+ startExpr(b, NO_COMMA);
+ b.add(parserLine, SWAP, JS.N(pushdown));
+ if (peekToken() == RP) break;
+ }
+ consume(COMMA);
+ }
+ consume(RP);
+ return i;
+ }
+
+ /** Parse a block of statements which must be surrounded by LC..RC. */
+ void parseBlock(JSFunction b) throws IOException { parseBlock(b, null); }
+ void parseBlock(JSFunction b, String label) throws IOException {
+ int saveParserLine = parserLine;
+ _parseBlock(b, label);
+ parserLine = saveParserLine;
+ }
+ void _parseBlock(JSFunction b, String label) throws IOException {
+ if (peekToken() == -1) return;
+ else if (peekToken() != LC) parseStatement(b, null);
+ else {
+ consume(LC);
+ while(peekToken() != RC && peekToken() != -1) parseStatement(b, null);
+ consume(RC);
+ }
+ }
+
+ /** Parse a single statement, consuming the RC or SEMI which terminates it. */
+ void parseStatement(JSFunction b, String label) throws IOException {
+ int saveParserLine = parserLine;
+ _parseStatement(b, label);
+ parserLine = saveParserLine;
+ }
+ void _parseStatement(JSFunction b, String label) throws IOException {
+ int tok = peekToken();
+ if (tok == -1) return;
+ switch(tok = getToken()) {
+
+ case THROW: case ASSERT: case RETURN: {
+ if (tok == RETURN && peekToken() == SEMI)
+ b.add(parserLine, LITERAL, null);
+ else
+ startExpr(b, -1);
+ b.add(parserLine, tok);
+ consume(SEMI);
+ break;
+ }
+ case BREAK: case CONTINUE: {
+ if (peekToken() == NAME) consume(NAME);
+ b.add(parserLine, tok, string);
+ consume(SEMI);
+ break;
+ }
+ case VAR: {
+ b.add(parserLine, TOPSCOPE); // push the current scope
+ while(true) {
+ consume(NAME);
+ b.add(parserLine, DECLARE, string); // declare it
+ if (peekToken() == ASSIGN) { // if there is an '=' after the variable name
+ consume(ASSIGN);
+ startExpr(b, NO_COMMA);
+ b.add(parserLine, PUT); // assign it
+ b.add(parserLine, POP); // clean the stack
+ } else {
+ b.add(parserLine, POP); // pop the string pushed by declare
+ }
+ if (peekToken() != COMMA) break;
+ consume(COMMA);
+ }
+ b.add(parserLine, POP); // pop off the topscope
+ if ((mostRecentlyReadToken != RC || peekToken() == SEMI) && peekToken() != -1 && mostRecentlyReadToken != SEMI) consume(SEMI);
+ break;
+ }
+ case IF: {
+ consume(LP);
+ startExpr(b, -1);
+ consume(RP);
+
+ b.add(parserLine, JF, JS.ZERO); // if false, jump to the else-block
+ int size = b.size;
+ parseStatement(b, null);
+
+ if (peekToken() == ELSE) {
+ consume(ELSE);
+ b.add(parserLine, JMP, JS.ZERO); // if we took the true-block, jump over the else-block
+ b.set(size - 1, JS.N(b.size - size + 1));
+ size = b.size;
+ parseStatement(b, null);
+ }
+ b.set(size - 1, JS.N(b.size - size + 1)); // regardless of which branch we took, b[size] needs to point here
+ break;
+ }
+ case WHILE: {
+ consume(LP);
+ if (label != null) b.add(parserLine, LABEL, label);
+ b.add(parserLine, LOOP);
+ int size = b.size;
+ b.add(parserLine, POP); // discard the first-iteration indicator
+ startExpr(b, -1);
+ b.add(parserLine, JT, JS.N(2)); // if the while() clause is true, jump over the BREAK
+ b.add(parserLine, BREAK);
+ consume(RP);
+ parseStatement(b, null);
+ b.add(parserLine, CONTINUE); // if we fall out of the end, definately continue
+ b.set(size - 1, JS.N(b.size - size + 1)); // end of the loop
+ break;
+ }
+ case SWITCH: {
+ consume(LP);
+ if (label != null) b.add(parserLine, LABEL, label);
+ b.add(parserLine, LOOP);
+ int size0 = b.size;
+ startExpr(b, -1);
+ consume(RP);
+ consume(LC);
+ while(true)
+ if (peekToken() == CASE) { // we compile CASE statements like a bunch of if..else's
+ consume(CASE);
+ b.add(parserLine, DUP); // duplicate the switch() value; we'll consume one copy
+ startExpr(b, -1);
+ consume(COLON);
+ b.add(parserLine, EQ); // check if we should do this case-block
+ b.add(parserLine, JF, JS.ZERO); // if not, jump to the next one
+ int size = b.size;
+ while(peekToken() != CASE && peekToken() != DEFAULT && peekToken() != RC) parseStatement(b, null);
+ b.set(size - 1, JS.N(1 + b.size - size));
+ } else if (peekToken() == DEFAULT) {
+ consume(DEFAULT);
+ consume(COLON);
+ while(peekToken() != CASE && peekToken() != DEFAULT && peekToken() != RC) parseStatement(b, null);
+ } else if (peekToken() == RC) {
+ consume(RC);
+ b.add(parserLine, BREAK); // break out of the loop if we 'fall through'
+ break;
+ } else {
+ throw pe("expected CASE, DEFAULT, or RC; got " + codeToString[peekToken()]);
+ }
+ b.set(size0 - 1, JS.N(b.size - size0 + 1)); // end of the loop
+ break;
+ }
+
+ case DO: {
+ if (label != null) b.add(parserLine, LABEL, label);
+ b.add(parserLine, LOOP);
+ int size = b.size;
+ parseStatement(b, null);
+ consume(WHILE);
+ consume(LP);
+ startExpr(b, -1);
+ b.add(parserLine, JT, JS.N(2)); // check the while() clause; jump over the BREAK if true
+ b.add(parserLine, BREAK);
+ b.add(parserLine, CONTINUE);
+ consume(RP);
+ consume(SEMI);
+ b.set(size - 1, JS.N(b.size - size + 1)); // end of the loop; write this location to the LOOP instruction
+ break;
+ }
+
+ case TRY: {
+ b.add(parserLine, TRY); // try bytecode causes a TryMarker to be pushed
+ int tryInsn = b.size - 1;
+ // parse the expression to be TRYed
+ parseStatement(b, null);
+ // pop the try marker. this is pushed when the TRY bytecode is executed
+ b.add(parserLine, POP);
+ // jump forward to the end of the catch block, start of the finally block
+ b.add(parserLine, JMP);
+ int successJMPInsn = b.size - 1;
+
+ if (peekToken() != CATCH && peekToken() != FINALLY)
+ throw pe("try without catch or finally");
+
+ int catchJMPDistance = -1;
+ if (peekToken() == CATCH) {
+ Vec catchEnds = new Vec();
+ boolean catchAll = false;
+
+ catchJMPDistance = b.size - tryInsn;
+
+ while(peekToken() == CATCH && !catchAll) {
+ String exceptionVar;
+ getToken();
+ consume(LP);
+ consume(NAME);
+ exceptionVar = string;
+ int[] writebacks = new int[] { -1, -1, -1 };
+ if (peekToken() != RP) {
+ // extended Ibex catch block: catch(e faultCode "foo.bar.baz")
+ consume(NAME);
+ b.add(parserLine, DUP);
+ b.add(parserLine, LITERAL, string);
+ b.add(parserLine, GET);
+ b.add(parserLine, DUP);
+ b.add(parserLine, LITERAL, null);
+ b.add(parserLine, EQ);
+ b.add(parserLine, JT);
+ writebacks[0] = b.size - 1;
+ if (peekToken() == STRING) {
+ consume(STRING);
+ b.add(parserLine, DUP);
+ b.add(parserLine, LITERAL, string);
+ b.add(parserLine, LT);
+ b.add(parserLine, JT);
+ writebacks[1] = b.size - 1;
+ b.add(parserLine, DUP);
+ b.add(parserLine, LITERAL, string + "/"); // (slash is ASCII after dot)
+ b.add(parserLine, GE);
+ b.add(parserLine, JT);
+ writebacks[2] = b.size - 1;
+ } else {
+ consume(NUMBER);
+ b.add(parserLine, DUP);
+ b.add(parserLine, LITERAL, number);
+ b.add(parserLine, EQ);
+ b.add(parserLine, JF);
+ writebacks[1] = b.size - 1;
+ }
+ b.add(parserLine, POP); // pop the element thats on the stack from the compare
+ } else {
+ catchAll = true;
+ }
+ consume(RP);
+ // the exception is on top of the stack; put it to the chosen name
+ b.add(parserLine, NEWSCOPE);
+ b.add(parserLine, TOPSCOPE);
+ b.add(parserLine, SWAP);
+ b.add(parserLine, LITERAL,exceptionVar);
+ b.add(parserLine, DECLARE);
+ b.add(parserLine, SWAP);
+ b.add(parserLine, PUT);
+ b.add(parserLine, POP);
+ b.add(parserLine, POP);
+ parseBlock(b, null);
+ b.add(parserLine, OLDSCOPE);
+
+ b.add(parserLine, JMP);
+ catchEnds.addElement(new Integer(b.size-1));
+
+ for(int i=0; i<3; i++) if (writebacks[i] != -1) b.set(writebacks[i], JS.N(b.size-writebacks[i]));
+ b.add(parserLine, POP); // pop the element thats on the stack from the compare
+ }
+
+ if(!catchAll)
+ b.add(parserLine, THROW);
+
+ for(int i=0;i<catchEnds.size();i++) {
+ int n = ((Integer)catchEnds.elementAt(i)).intValue();
+ b.set(n, JS.N(b.size-n));
+ }
+
+ // pop the try and catch markers
+ b.add(parserLine,POP);
+ b.add(parserLine,POP);
+ }
+
+ // jump here if no exception was thrown
+ b.set(successJMPInsn, JS.N(b.size - successJMPInsn));
+
+ int finallyJMPDistance = -1;
+ if (peekToken() == FINALLY) {
+ b.add(parserLine, LITERAL, null); // null FinallyData
+ finallyJMPDistance = b.size - tryInsn;
+ consume(FINALLY);
+ parseStatement(b, null);
+ b.add(parserLine,FINALLY_DONE);
+ }
+
+ // setup the TRY arguments
+ b.set(tryInsn, new int[] { catchJMPDistance, finallyJMPDistance });
+
+ break;
+ }
+
+ case FOR: {
+ consume(LP);
+
+ tok = getToken();
+ boolean hadVar = false; // if it's a for..in, we ignore the VAR
+ if (tok == VAR) { hadVar = true; tok = getToken(); }
+ String varName = string;
+ boolean forIn = peekToken() == IN; // determine if this is a for..in loop or not
+ pushBackToken(tok, varName);
+
+ if (forIn) {
+ consume(NAME);
+ consume(IN);
+ startExpr(b,-1);
+ consume(RP);
+
+ b.add(parserLine, PUSHKEYS);
+ b.add(parserLine, DUP);
+ b.add(parserLine, LITERAL, "length");
+ b.add(parserLine, GET);
+ // Stack is now: n, keys, obj, ...
+
+ int size = b.size;
+ b.add(parserLine, LOOP);
+ b.add(parserLine, POP);
+ // Stack is now: LoopMarker, n, keys, obj, ...
+ // NOTE: This will break if the interpreter ever becomes more strict
+ // and prevents bytecode from messing with the Markers
+ b.add(parserLine, SWAP, JS.N(3));
+ // Stack is now: Tn, keys, obj, LoopMarker, ...
+
+ b.add(parserLine, LITERAL, JS.N(1));
+ b.add(parserLine, SUB);
+ b.add(parserLine, DUP);
+ // Stack is now: index, keys, obj, LoopMarker
+ b.add(parserLine, LITERAL, JS.ZERO);
+ b.add(parserLine, LT);
+ // Stack is now index<0, index, keys, obj, LoopMarker, ...
+
+ b.add(parserLine, JF, JS.N(5)); // if we're >= 0 jump 5 down (to NEWSCOPE)
+ // Move the LoopMarker back into place - this is sort of ugly
+ b.add(parserLine, SWAP, JS.N(3));
+ b.add(parserLine, SWAP, JS.N(3));
+ b.add(parserLine, SWAP, JS.N(3));
+ // Stack is now: LoopMarker, -1, keys, obj, ...
+ b.add(parserLine, BREAK);
+
+ b.add(parserLine, NEWSCOPE);
+ if(hadVar) {
+ b.add(parserLine, DECLARE, varName);
+ b.add(parserLine, POP);
+ }
+
+ // Stack is now: index, keys, obj, LoopMarker, ...
+ b.add(parserLine, GET_PRESERVE); // key, index, keys, obj, LoopMarker, ...
+ b.add(parserLine, TOPSCOPE); // scope, key, index, keys, obj, LoopMarker, ...
+ b.add(parserLine, SWAP); // key, scope, index, keys, obj, LoopMarker, ...
+ b.add(parserLine, LITERAL, varName); // varName, key, scope, index, keys, obj, LoopMaker, ...
+ b.add(parserLine, SWAP); // key, varName, scope, index, keys, obj, LoopMarker, ...
+ b.add(parserLine, PUT); // key, scope, index, keys, obj, LoopMarker, ...
+ b.add(parserLine, POP); // scope, index, keys, obj, LoopMarker
+ b.add(parserLine, POP); // index, keys, obj, LoopMarker, ...
+ // Move the LoopMarker back into place - this is sort of ugly
+ b.add(parserLine, SWAP, JS.N(3));
+ b.add(parserLine, SWAP, JS.N(3));
+ b.add(parserLine, SWAP, JS.N(3));
+
+ parseStatement(b, null);
+
+ b.add(parserLine, OLDSCOPE);
+ b.add(parserLine, CONTINUE);
+ // jump here on break
+ b.set(size, JS.N(b.size - size));
+
+ b.add(parserLine, POP); // N
+ b.add(parserLine, POP); // KEYS
+ b.add(parserLine, POP); // OBJ
+
+ } else {
+ if (hadVar) pushBackToken(VAR, null); // yeah, this actually matters
+ b.add(parserLine, NEWSCOPE); // grab a fresh scope
+
+ parseStatement(b, null); // initializer
+ JSFunction e2 = // we need to put the incrementor before the test
+ new JSFunction(sourceName, parserLine, null); // so we save the test here
+ if (peekToken() != SEMI)
+ startExpr(e2, -1);
+ else
+ e2.add(parserLine, JSFunction.LITERAL, Boolean.TRUE); // handle the for(foo;;foo) case
+ consume(SEMI);
+ if (label != null) b.add(parserLine, LABEL, label);
+ b.add(parserLine, LOOP);
+ int size2 = b.size;
+
+ b.add(parserLine, JT, JS.ZERO); // if we're on the first iteration, jump over the incrementor
+ int size = b.size;
+ if (peekToken() != RP) { // do the increment thing
+ startExpr(b, -1);
+ b.add(parserLine, POP);
+ }
+ b.set(size - 1, JS.N(b.size - size + 1));
+ consume(RP);
+
+ b.paste(e2); // ok, *now* test if we're done yet
+ b.add(parserLine, JT, JS.N(2)); // break out if we don't meet the test
+ b.add(parserLine, BREAK);
+ parseStatement(b, null);
+ b.add(parserLine, CONTINUE); // if we fall out the bottom, CONTINUE
+ b.set(size2 - 1, JS.N(b.size - size2 + 1)); // end of the loop
+
+ b.add(parserLine, OLDSCOPE); // get our scope back
+ }
+ break;
+ }
+
+ case NAME: { // either a label or an identifier; this is the one place we're not LL(1)
+ String possiblyTheLabel = string;
+ if (peekToken() == COLON) { // label
+ consume(COLON);
+ parseStatement(b, possiblyTheLabel);
+ break;
+ } else { // expression
+ pushBackToken(NAME, possiblyTheLabel);
+ startExpr(b, -1);
+ b.add(parserLine, POP);
+ if ((mostRecentlyReadToken != RC || peekToken() == SEMI) && peekToken() != -1 && mostRecentlyReadToken != SEMI) consume(SEMI);
+ break;
+ }
+ }
+
+ case SEMI: return; // yep, the null statement is valid
+
+ case LC: { // blocks are statements too
+ pushBackToken();
+ b.add(parserLine, NEWSCOPE);
+ parseBlock(b, label);
+ b.add(parserLine, OLDSCOPE);
+ break;
+ }
+
+ default: { // hope that it's an expression
+ pushBackToken();
+ startExpr(b, -1);
+ b.add(parserLine, POP);
+ if ((mostRecentlyReadToken != RC || peekToken() == SEMI) && peekToken() != -1 && mostRecentlyReadToken != SEMI) consume(SEMI);
+ break;
+ }
+ }
+ }
+
+
+ // ParserException //////////////////////////////////////////////////////////////////////
+ private IOException pe(String s) { return new IOException(sourceName + ":" + line + " " + s); }
+
+}
+
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.js;
+
+import java.io.*;
+import java.util.zip.*;
+import org.ibex.util.*;
+import org.ibex.plat.*;
+import org.ibex.net.*;
+
+/**
+ * Essentiall an InputStream "factory". You can repeatedly ask a
+ * Stream for an InputStream, and each InputStream you get back will
+ * be totally independent of the others (ie separate stream position
+ * and state) although they draw from the same data source.
+ */
+public abstract class Stream extends JS.Cloneable {
+
+ // Public Interface //////////////////////////////////////////////////////////////////////////////
+
+ public static InputStream getInputStream(Object js) throws IOException { return ((Stream)((JS)js).unclone()).getInputStream();}
+ public static class NotCacheableException extends Exception { }
+
+ // streams are "sealed" by default to prevent accidental object leakage
+ public void put(Object key, Object val) { }
+ private Cache getCache = new Cache(100);
+ protected Object _get(Object key) { return null; }
+ public final Object get(Object key) {
+ Object ret = getCache.get(key);
+ if (ret == null) getCache.put(key, ret = _get(key));
+ return ret;
+ }
+
+ // Private Interface //////////////////////////////////////////////////////////////////////////////
+
+ public abstract InputStream getInputStream() throws IOException;
+ protected String getCacheKey() throws NotCacheableException { throw new NotCacheableException(); }
+
+ /** HTTP or HTTPS resource */
+ public static class HTTP extends Stream {
+ private String url;
+ public String toString() { return "Stream.HTTP:" + url; }
+ public HTTP(String url) { while (url.endsWith("/")) url = url.substring(0, url.length() - 1); this.url = url; }
+ public Object _get(Object key) { return new HTTP(url + "/" + (String)key); }
+ public String getCacheKey(Vec path) throws NotCacheableException { return url; }
+ public InputStream getInputStream() throws IOException { return new org.ibex.net.HTTP(url).GET(); }
+ }
+
+ /** byte arrays */
+ public static class ByteArray extends Stream {
+ private byte[] bytes;
+ private String cacheKey;
+ public ByteArray(byte[] bytes, String cacheKey) { this.bytes = bytes; this.cacheKey = cacheKey; }
+ public String getCacheKey() throws NotCacheableException {
+ if (cacheKey == null) throw new NotCacheableException(); return cacheKey; }
+ public InputStream getInputStream() throws IOException { return new ByteArrayInputStream(bytes); }
+ }
+
+ /** a file */
+ public static class File extends Stream {
+ private String path;
+ public File(String path) { this.path = path; }
+ public String toString() { return "file:" + path; }
+ public String getCacheKey() throws NotCacheableException { throw new NotCacheableException(); /* already on disk */ }
+ public InputStream getInputStream() throws IOException { return new FileInputStream(path); }
+ public Object _get(Object key) { return new File(path + java.io.File.separatorChar + (String)key); }
+ }
+
+ /** "unwrap" a Zip archive */
+ public static class Zip extends Stream {
+ private Stream parent;
+ private String path;
+ public Zip(Stream parent) { this(parent, null); }
+ public Zip(Stream parent, String path) {
+ while(path != null && path.startsWith("/")) path = path.substring(1);
+ this.parent = parent;
+ this.path = path;
+ }
+ public String getCacheKey() throws NotCacheableException { return parent.getCacheKey() + "!zip:"; }
+ public Object _get(Object key) { return new Zip(parent, path==null?(String)key:path+'/'+(String)key); }
+ public InputStream getInputStream() throws IOException {
+ InputStream pis = parent.getInputStream();
+ ZipInputStream zis = new ZipInputStream(pis);
+ ZipEntry ze = zis.getNextEntry();
+ while(ze != null && !ze.getName().equals(path)) ze = zis.getNextEntry();
+ if (ze == null) throw new IOException("requested file (" + path + ") not found in archive");
+ return new KnownLength.KnownLengthInputStream(zis, (int)ze.getSize());
+ }
+ }
+
+ /** "unwrap" a Cab archive */
+ public static class Cab extends Stream {
+ private Stream parent;
+ private String path;
+ public Cab(Stream parent) { this(parent, null); }
+ public Cab(Stream parent, String path) { this.parent = parent; this.path = path; }
+ public String getCacheKey() throws NotCacheableException { return parent.getCacheKey() + "!cab:"; }
+ public Object _get(Object key) { return new Cab(parent, path==null?(String)key:path+'/'+(String)key); }
+ public InputStream getInputStream() throws IOException { return new MSPack(parent.getInputStream()).getInputStream(path); }
+ }
+
+ /** the Builtin resource */
+ public static class Builtin extends Stream {
+ public String getCacheKey() throws NotCacheableException { throw new NotCacheableException(); }
+ public InputStream getInputStream() throws IOException { return Platform.getBuiltinInputStream(); }
+ }
+
+ /** shadow resource which replaces the graft */
+ public static class ProgressWatcher extends Stream {
+ final Stream watchee;
+ JS callback;
+ public ProgressWatcher(Stream watchee, JS callback) { this.watchee = watchee; this.callback = callback; }
+ public String getCacheKey() throws NotCacheableException { return watchee.getCacheKey(); }
+ public InputStream getInputStream() throws IOException {
+ final InputStream is = watchee.getInputStream();
+ return new FilterInputStream(is) {
+ int bytesDownloaded = 0;
+ public int read() throws IOException {
+ int ret = super.read();
+ if (ret != -1) bytesDownloaded++;
+ return ret;
+ }
+ public int read(byte[] b, int off, int len) throws IOException {
+ int ret = super.read(b, off, len);
+ if (ret != 1) bytesDownloaded += ret;
+ Scheduler.add(new Task() { public void perform() throws IOException, JSExn {
+ callback.call(N(bytesDownloaded),
+ N(is instanceof KnownLength ? ((KnownLength)is).getLength() : 0), null, null, 2);
+ } });
+ return ret;
+ }
+ };
+ }
+ }
+
+ /** subclass from this if you want a CachedInputStream for each path */
+ public static class CachedStream extends Stream {
+ private Stream parent;
+ private boolean disk = false;
+ private String key;
+ public String getCacheKey() throws NotCacheableException { return key; }
+ CachedInputStream cis = null;
+ public CachedStream(Stream p, String s, boolean d) throws NotCacheableException {
+ this.parent = p; this.disk = d; this.key = p.getCacheKey();
+ }
+ public InputStream getInputStream() throws IOException {
+ if (cis != null) return cis.getInputStream();
+ if (!disk) {
+ cis = new CachedInputStream(parent.getInputStream());
+ } else {
+ java.io.File f = org.ibex.core.LocalStorage.Cache.getCacheFileForKey(key);
+ if (f.exists()) return new FileInputStream(f);
+ cis = new CachedInputStream(parent.getInputStream(), f);
+ }
+ return cis.getInputStream();
+ }
+ }
+}
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.js;
+
+/** this class contains a <tt>public static final int</tt> for each valid token */
+interface Tokens {
+
+ // Token Constants //////////////////////////////////////////////////////////
+
+ // arithmetic operations; also valid as bytecodes
+ public static final int BITOR = 0; // |
+ public static final int ASSIGN_BITOR = 1; // |=
+ public static final int BITXOR = 2; // ^
+ public static final int ASSIGN_BITXOR = 3; // ^=
+ public static final int BITAND = 4; // &
+ public static final int ASSIGN_BITAND = 5; // &=
+ public static final int LSH = 6; // <<
+ public static final int ASSIGN_LSH = 7; // <<=
+ public static final int RSH = 8; // >>
+ public static final int ASSIGN_RSH = 9; // >>=
+ public static final int URSH = 10; // >>>
+ public static final int ASSIGN_URSH = 11; // >>>=
+ public static final int ADD = 12; // +
+ public static final int ASSIGN_ADD = 13; // +=
+ public static final int SUB = 14; // -
+ public static final int ASSIGN_SUB = 15; // -=
+ public static final int MUL = 16; // *
+ public static final int ASSIGN_MUL = 17; // *=
+ public static final int DIV = 18; // /
+ public static final int ASSIGN_DIV = 19; // /=
+ public static final int MOD = 20; // %
+ public static final int ASSIGN_MOD = 21; // %=
+ public static final int BITNOT = 22; // ~
+ public static final int ASSIGN_BITNOT = 23; // ~=
+
+ // logical operations; also valid as bytecodes
+ public static final int OR = 24; // ||
+ public static final int AND = 25; // &&
+ public static final int BANG = 26; // !
+
+ // equality operations; also valid as bytecodes
+ public static final int EQ = 27; // ==
+ public static final int NE = 28; // !=
+ public static final int LT = 29; // <
+ public static final int LE = 30; // <=
+ public static final int GT = 31; // >
+ public static final int GE = 32; // >=
+ public static final int SHEQ = 33; // ===
+ public static final int SHNE = 34; // !==
+
+ // other permissible bytecode tokens
+ public static final int RETURN = 35; // return
+ public static final int TYPEOF = 36; // typeof
+ public static final int BREAK = 37; // break keyword
+ public static final int CONTINUE = 38; // continue keyword
+ public static final int TRY = 39; // try
+ public static final int THROW = 40; // throw
+ public static final int ASSERT = 41; // assert keyword
+
+ public static final int NAME = 42; // *** identifiers ***
+ public static final int NUMBER = 43; // *** numeric literals ***
+ public static final int STRING = 44; // *** string literals ***
+ public static final int NULL = 45; // null
+ public static final int THIS = 46; // this
+ public static final int FALSE = 47; // false
+ public static final int TRUE = 48; // true
+ public static final int IN = 49; // in
+
+ public static final int SEMI = 50; // ;
+ public static final int LB = 51; // [
+ public static final int RB = 52; // ]
+ public static final int LC = 53; // {
+ public static final int RC = 54; // }
+ public static final int LP = 55; // (
+ public static final int RP = 56; // )
+ public static final int COMMA = 57; // ,
+ public static final int ASSIGN = 58; // =
+ public static final int HOOK = 59; // ?
+ public static final int COLON = 60; // :
+ public static final int INC = 61; // ++
+ public static final int DEC = 62; // --
+ public static final int DOT = 63; // .
+ public static final int FUNCTION = 64; // function
+ public static final int IF = 65; // if keyword
+ public static final int ELSE = 66; // else keyword
+ public static final int SWITCH = 67; // switch keyword
+ public static final int CASE = 68; // case keyword
+ public static final int DEFAULT = 69; // default keyword
+ public static final int WHILE = 70; // while keyword
+ public static final int DO = 71; // do keyword
+ public static final int FOR = 72; // for keyword
+ public static final int VAR = 73; // var keyword
+ public static final int WITH = 74; // with keyword
+ public static final int CATCH = 75; // catch keyword
+ public static final int FINALLY = 76; // finally keyword
+ public static final int RESERVED = 77; // reserved keyword
+ public static final int GRAMMAR = 78; // the grammar-definition operator (::=)
+ public static final int ADD_TRAP = 79; // the add-trap operator (++=)
+ public static final int DEL_TRAP = 80; // the del-trap operator (--=)
+
+ public static final int MAX_TOKEN = DEL_TRAP;
+
+ public final static String[] codeToString = new String[] {
+ "BITOR", "ASSIGN_BITOR", "BITXOR", "ASSIGN_BITXOR", "BITAND",
+ "ASSIGN_BITAND", "LSH", "ASSIGN_LSH", "RSH", "ASSIGN_RSH",
+ "URSH", "ASSIGN_URSH", "ADD", "ASSIGN_ADD", "SUB",
+ "ASSIGN_SUB", "MUL", "ASSIGN_MUL", "DIV", "ASSIGN_DIV", "MOD",
+ "ASSIGN_MOD", "BITNOT", "ASSIGN_BITNOT", "OR", "AND", "BANG",
+ "EQ", "NE", "LT", "LE", "GT", "GE", "SHEQ", "SHNE", "RETURN",
+ "TYPEOF", "BREAK", "CONTINUE", "TRY", "THROW", "ASSERT", "NAME",
+ "NUMBER", "STRING", "NULL", "THIS", "FALSE", "TRUE", "IN",
+ "SEMI", "LB", "RB", "LC", "RC", "LP", "RP", "COMMA", "ASSIGN",
+ "HOOK", "COLON", "INC", "DEC", "DOT", "FUNCTION", "IF",
+ "ELSE", "SWITCH", "CASE", "DEFAULT", "WHILE", "DO", "FOR",
+ "VAR", "WITH", "CATCH", "FINALLY", "RESERVED", "GRAMMAR",
+ "ADD_TRAP", "DEL_TRAP"
+ };
+
+}
+
+
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.js;
+
+/**
+ * This class encapsulates a single trap placed on a given node. The
+ * traps for a given property name on a given box are maintained as a
+ * linked list stack, with the most recently placed trap at the head
+ * of the list.
+ */
+class Trap {
+
+ JS trapee = null; ///< the box on which this trap was placed
+ Object name = null; ///< the property that the trap was placed on
+
+ JSFunction f = null; ///< the function for this trap
+ Trap next = null; ///< the next trap down the trap stack
+
+ Trap(JS b, String n, JSFunction f, Trap nx) {
+ trapee = b; name = n; this.f = f; this.next = nx;
+ }
+
+ static final JSFunction putInvoker = new JSFunction("putInvoker", 0, null);
+ static final JSFunction getInvoker = new JSFunction("getInvoker", 0, null);
+
+ static {
+ putInvoker.add(1, ByteCodes.PUT, null);
+ putInvoker.add(2, Tokens.RETURN, null);
+ getInvoker.add(1, ByteCodes.GET, null);
+ getInvoker.add(2, Tokens.RETURN, null);
+ }
+
+ void invoke(Object value) throws JSExn {
+ Interpreter i = new Interpreter(putInvoker, false, null);
+ i.stack.push(trapee);
+ i.stack.push(name);
+ i.stack.push(value);
+ i.resume();
+ }
+
+ Object invoke() throws JSExn {
+ Interpreter i = new Interpreter(getInvoker, false, null);
+ i.stack.push(trapee);
+ i.stack.push(name);
+ return i.resume();
+ }
+
+ // FIXME: review; is necessary?
+ static class TrapScope extends JSScope {
+ Trap t;
+ Object val = null;
+ boolean cascadeHappened = false;
+ public TrapScope(JSScope parent, Trap t, Object val) { super(parent); this.t = t; this.val = val; }
+ public Object get(Object key) throws JSExn {
+ if (key.equals("trapee")) return t.trapee;
+ if (key.equals("callee")) return t.f;
+ if (key.equals("trapname")) return t.name;
+ return super.get(key);
+ }
+ }
+}
+
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.net;
+
+import java.net.*;
+import java.io.*;
+import java.util.*;
+import org.ibex.js.*;
+import org.ibex.util.*;
+import org.ibex.plat.*;
+import org.ibex.core.*;
+import org.ibex.crypto.*;
+
+/**
+ * This object encapsulates a *single* HTTP connection. Multiple requests may be pipelined over a connection (thread-safe),
+ * although any IOException encountered in a request will invalidate all later requests.
+ */
+public class HTTP {
+
+
+ // Public Methods ////////////////////////////////////////////////////////////////////////////////////////
+
+ public HTTP(String url) { this(url, false); }
+ public HTTP(String url, boolean skipResolveCheck) { originalUrl = url; this.skipResolveCheck = skipResolveCheck; }
+
+ /** Performs an HTTP GET request */
+ public InputStream GET() throws IOException { return makeRequest(null, null); }
+
+ /** Performs an HTTP POST request; content is additional headers, blank line, and body */
+ public InputStream POST(String contentType, String content) throws IOException { return makeRequest(contentType, content); }
+
+ public static class HTTPException extends IOException { public HTTPException(String s) { super(s); } }
+
+ public static HTTP stdio = new HTTP("stdio:");
+
+
+ // Statics ///////////////////////////////////////////////////////////////////////////////////////////////
+
+ static Hash resolvedHosts = new Hash(); ///< cache for resolveAndCheckIfFirewalled()
+ private static Hash authCache = new Hash(); ///< cache of userInfo strings, keyed on originalUrl
+
+
+ // Instance Data ///////////////////////////////////////////////////////////////////////////////////////////////
+
+ final String originalUrl; ///< the URL as passed to the original constructor; this is never changed
+ String url = null; ///< the URL to connect to; this is munged when the url is parsed */
+ String host = null; ///< the host to connect to
+ int port = -1; ///< the port to connect on
+ boolean ssl = false; ///< true if SSL (HTTPS) should be used
+ String path = null; ///< the path (URI) to retrieve on the server
+ Socket sock = null; ///< the socket
+ InputStream in = null; ///< the socket's inputstream
+ String userInfo = null; ///< the username and password portions of the URL
+ boolean firstRequest = true; ///< true iff this is the first request to be made on this socket
+ boolean skipResolveCheck = false; ///< allowed to skip the resolve check when downloading PAC script
+ boolean proxied = false; ///< true iff we're using a proxy
+
+ /** this is null if the current request is the first request on
+ * this HTTP connection; otherwise it is a Semaphore which will be
+ * released once the request ahead of us has recieved its response
+ */
+ Semaphore okToRecieve = null;
+
+ /**
+ * This method isn't synchronized; however, only one thread can be in the inner synchronized block at a time, and the rest of
+ * the method is protected by in-order one-at-a-time semaphore lock-steps
+ */
+ private InputStream makeRequest(String contentType, String content) throws IOException {
+
+ // Step 1: send the request and establish a semaphore to stop any requests that pipeline after us
+ Semaphore blockOn = null;
+ Semaphore releaseMe = null;
+ synchronized(this) {
+ try {
+ connect();
+ sendRequest(contentType, content);
+ } catch (IOException e) {
+ reset();
+ throw e;
+ }
+ blockOn = okToRecieve;
+ releaseMe = okToRecieve = new Semaphore();
+ }
+
+ // Step 2: wait for requests ahead of us to complete, then read the reply off the stream
+ boolean doRelease = true;
+ try {
+ if (blockOn != null) blockOn.block();
+
+ // previous call wrecked the socket connection, but we already sent our request, so we can't just retry --
+ // this could cause the server to receive the request twice, which could be bad (think of the case where the
+ // server call causes Amazon.com to ship you an item with one-click purchasing).
+ if (in == null)
+ throw new HTTPException("a previous pipelined call messed up the socket");
+
+ Hashtable h = in == null ? null : parseHeaders(in);
+ if (h == null) {
+ if (firstRequest) throw new HTTPException("server closed the socket with no response");
+ // sometimes the server chooses to close the stream between requests
+ reset();
+ releaseMe.release();
+ return makeRequest(contentType, content);
+ }
+
+ String reply = h.get("STATUSLINE").toString();
+
+ if (reply.startsWith("407") || reply.startsWith("401")) {
+
+ if (reply.startsWith("407")) doProxyAuth(h, content == null ? "GET" : "POST");
+ else doWebAuth(h, content == null ? "GET" : "POST");
+
+ if (h.get("HTTP").equals("1.0") && h.get("content-length") == null) {
+ if (Log.on) Log.info(this, "proxy returned an HTTP/1.0 reply with no content-length...");
+ reset();
+ } else {
+ int cl = h.get("content-length") == null ? -1 : Integer.parseInt(h.get("content-length").toString());
+ new HTTPInputStream(in, cl, releaseMe).close();
+ }
+ releaseMe.release();
+ return makeRequest(contentType, content);
+
+ } else if (reply.startsWith("2")) {
+ if (h.get("HTTP").equals("1.0") && h.get("content-length") == null)
+ throw new HTTPException("Ibex does not support HTTP/1.0 servers which fail to return the Content-Length header");
+ int cl = h.get("content-length") == null ? -1 : Integer.parseInt(h.get("content-length").toString());
+ InputStream ret = new HTTPInputStream(in, cl, releaseMe);
+ if ("gzip".equals(h.get("content-encoding"))) ret = new java.util.zip.GZIPInputStream(ret);
+ doRelease = false;
+ return ret;
+
+ } else {
+ throw new HTTPException("HTTP Error: " + reply);
+
+ }
+
+ } catch (IOException e) { reset(); throw e;
+ } finally { if (doRelease) releaseMe.release();
+ }
+ }
+
+
+ // Safeguarded DNS Resolver ///////////////////////////////////////////////////////////////////////////
+
+ /**
+ * resolves the hostname and returns it as a string in the form "x.y.z.w"
+ * @throws HTTPException if the host falls within a firewalled netblock
+ */
+ private void resolveAndCheckIfFirewalled(String host) throws HTTPException {
+
+ // cached
+ if (resolvedHosts.get(host) != null) return;
+
+ // if all scripts are trustworthy (local FS), continue
+ if (Main.originAddr == null) return;
+
+ // resolve using DNS
+ try {
+ InetAddress addr = InetAddress.getByName(host);
+ byte[] quadbyte = addr.getAddress();
+ if ((quadbyte[0] == 10 ||
+ (quadbyte[0] == 192 && quadbyte[1] == 168) ||
+ (quadbyte[0] == 172 && (quadbyte[1] & 0xF0) == 16)) && !addr.equals(Main.originAddr))
+ throw new HTTPException("security violation: " + host + " [" + addr.getHostAddress() +
+ "] is in a firewalled netblock");
+ return;
+ } catch (UnknownHostException uhe) { }
+
+ if (Platform.detectProxy() == null)
+ throw new HTTPException("could not resolve hostname \"" + host + "\" and no proxy configured");
+ }
+
+
+ // Methods to attempt socket creation /////////////////////////////////////////////////////////////////
+
+ private Socket getSocket(String host, int port, boolean ssl, boolean negotiate) throws IOException {
+ Socket ret = ssl ? new SSL(host, port, negotiate) : new Socket(java.net.InetAddress.getByName(host), port);
+ ret.setTcpNoDelay(true);
+ return ret;
+ }
+
+ /** Attempts a direct connection */
+ private Socket attemptDirect() {
+ try {
+ Log.info(this, "attempting to create unproxied socket to " +
+ host + ":" + port + (ssl ? " [ssl]" : ""));
+ return getSocket(host, port, ssl, true);
+ } catch (IOException e) {
+ if (Log.on) Log.info(this, "exception in attemptDirect(): " + e);
+ return null;
+ }
+ }
+
+ /** Attempts to use an HTTP proxy, employing the CONNECT method if HTTPS is requested */
+ private Socket attemptHttpProxy(String proxyHost, int proxyPort) {
+ try {
+ if (Log.verbose) Log.info(this, "attempting to create HTTP proxied socket using proxy " + proxyHost + ":" + proxyPort);
+ Socket sock = getSocket(proxyHost, proxyPort, ssl, false);
+
+ if (!ssl) {
+ if (!path.startsWith("http://")) path = "http://" + host + ":" + port + path;
+ return sock;
+ }
+
+ PrintWriter pw = new PrintWriter(new OutputStreamWriter(sock.getOutputStream()));
+ BufferedReader br = new BufferedReader(new InputStreamReader(sock.getInputStream()));
+ pw.print("CONNECT " + host + ":" + port + " HTTP/1.1\r\n\r\n");
+ pw.flush();
+ String s = br.readLine();
+ if (s.charAt(9) != '2') throw new HTTPException("proxy refused CONNECT method: \"" + s + "\"");
+ while (br.readLine().length() > 0) { };
+ ((SSL)sock).negotiate();
+ return sock;
+
+ } catch (IOException e) {
+ if (Log.on) Log.info(this, "exception in attemptHttpProxy(): " + e);
+ return null;
+ }
+ }
+
+ /**
+ * Implements SOCKSv4 with v4a DNS extension
+ * @see http://www.socks.nec.com/protocol/socks4.protocol
+ * @see http://www.socks.nec.com/protocol/socks4a.protocol
+ */
+ private Socket attemptSocksProxy(String proxyHost, int proxyPort) {
+
+ // even if host is already a "x.y.z.w" string, we use this to parse it into bytes
+ InetAddress addr = null;
+ try { addr = InetAddress.getByName(host); } catch (Exception e) { }
+
+ if (Log.verbose) Log.info(this, "attempting to create SOCKSv4" + (addr == null ? "" : "a") +
+ " proxied socket using proxy " + proxyHost + ":" + proxyPort);
+
+ try {
+ Socket sock = getSocket(proxyHost, proxyPort, ssl, false);
+
+ DataOutputStream dos = new DataOutputStream(sock.getOutputStream());
+ dos.writeByte(0x04); // SOCKSv4(a)
+ dos.writeByte(0x01); // CONNECT
+ dos.writeShort(port & 0xffff); // port
+ if (addr == null) dos.writeInt(0x00000001); // bogus IP
+ else dos.write(addr.getAddress()); // actual IP
+ dos.writeByte(0x00); // no userid
+ if (addr == null) {
+ PrintWriter pw = new PrintWriter(new OutputStreamWriter(dos));
+ pw.print(host);
+ pw.flush();
+ dos.writeByte(0x00); // hostname null terminator
+ }
+ dos.flush();
+
+ DataInputStream dis = new DataInputStream(sock.getInputStream());
+ dis.readByte(); // reply version
+ byte success = dis.readByte(); // success/fail
+ dis.skip(6); // ip/port
+
+ if ((int)(success & 0xff) == 90) {
+ if (ssl) ((SSL)sock).negotiate();
+ return sock;
+ }
+ if (Log.on) Log.info(this, "SOCKS server denied access, code " + (success & 0xff));
+ return null;
+
+ } catch (IOException e) {
+ if (Log.on) Log.info(this, "exception in attemptSocksProxy(): " + e);
+ return null;
+ }
+ }
+
+ /** executes the PAC script and dispatches a call to one of the other attempt methods based on the result */
+ private Socket attemptPAC(org.ibex.js.JS pacFunc) {
+ if (Log.verbose) Log.info(this, "evaluating PAC script");
+ String pac = null;
+ try {
+ Object obj = pacFunc.call(url, host, null, null, 2);
+ if (Log.verbose) Log.info(this, " PAC script returned \"" + obj + "\"");
+ pac = obj.toString();
+ } catch (Throwable e) {
+ if (Log.on) Log.info(this, "PAC script threw exception " + e);
+ return null;
+ }
+
+ StringTokenizer st = new StringTokenizer(pac, ";", false);
+ while (st.hasMoreTokens()) {
+ String token = st.nextToken().trim();
+ if (Log.verbose) Log.info(this, " trying \"" + token + "\"...");
+ try {
+ Socket ret = null;
+ if (token.startsWith("DIRECT"))
+ ret = attemptDirect();
+ else if (token.startsWith("PROXY"))
+ ret = attemptHttpProxy(token.substring(token.indexOf(' ') + 1, token.indexOf(':')),
+ Integer.parseInt(token.substring(token.indexOf(':') + 1)));
+ else if (token.startsWith("SOCKS"))
+ ret = attemptSocksProxy(token.substring(token.indexOf(' ') + 1, token.indexOf(':')),
+ Integer.parseInt(token.substring(token.indexOf(':') + 1)));
+ if (ret != null) return ret;
+ } catch (Throwable e) {
+ if (Log.on) Log.info(this, "attempt at \"" + token + "\" failed due to " + e + "; trying next token");
+ }
+ }
+ if (Log.on) Log.info(this, "all PAC results exhausted");
+ return null;
+ }
+
+
+ // Everything Else ////////////////////////////////////////////////////////////////////////////
+
+ private synchronized void connect() throws IOException {
+ if (originalUrl.equals("stdio:")) { in = new BufferedInputStream(System.in); return; }
+ if (sock != null) {
+ if (in == null) in = new BufferedInputStream(sock.getInputStream());
+ return;
+ }
+ // grab the userinfo; gcj doesn't have java.net.URL.getUserInfo()
+ String url = originalUrl;
+ userInfo = url.substring(url.indexOf("://") + 3);
+ userInfo = userInfo.indexOf('/') == -1 ? userInfo : userInfo.substring(0, userInfo.indexOf('/'));
+ if (userInfo.indexOf('@') != -1) {
+ userInfo = userInfo.substring(0, userInfo.indexOf('@'));
+ url = url.substring(0, url.indexOf("://") + 3) + url.substring(url.indexOf('@') + 1);
+ } else {
+ userInfo = null;
+ }
+
+ if (url.startsWith("https:")) {
+ ssl = true;
+ } else if (!url.startsWith("http:")) {
+ throw new IOException("HTTP only supports http/https urls");
+ }
+ if (url.indexOf("://") == -1) throw new IOException("URLs must contain a ://");
+ String temphost = url.substring(url.indexOf("://") + 3);
+ path = temphost.substring(temphost.indexOf('/'));
+ temphost = temphost.substring(0, temphost.indexOf('/'));
+ if (temphost.indexOf(':') != -1) {
+ port = Integer.parseInt(temphost.substring(temphost.indexOf(':')+1));
+ temphost = temphost.substring(0, temphost.indexOf(':'));
+ } else {
+ port = ssl ? 443 : 80;
+ }
+ if (!skipResolveCheck) resolveAndCheckIfFirewalled(temphost);
+ host = temphost;
+ if (Log.verbose) Log.info(this, "creating HTTP object for connection to " + host + ":" + port);
+
+ Proxy pi = Platform.detectProxy();
+ OUTER: do {
+ if (pi != null) {
+ for(int i=0; i<pi.excluded.length; i++) if (host.equals(pi.excluded[i])) break OUTER;
+ if (sock == null && pi.proxyAutoConfigFunction != null) sock = attemptPAC(pi.proxyAutoConfigFunction);
+ if (sock == null && ssl && pi.httpsProxyHost != null) sock = attemptHttpProxy(pi.httpsProxyHost,pi.httpsProxyPort);
+ if (sock == null && pi.httpProxyHost != null) sock = attemptHttpProxy(pi.httpProxyHost, pi.httpProxyPort);
+ if (sock == null && pi.socksProxyHost != null) sock = attemptSocksProxy(pi.socksProxyHost, pi.socksProxyPort);
+ }
+ } while (false);
+ proxied = sock != null;
+ if (sock == null) sock = attemptDirect();
+ if (sock == null) throw new HTTPException("unable to contact host " + host);
+ if (in == null) in = new BufferedInputStream(sock.getInputStream());
+ }
+
+ private void sendRequest(String contentType, String content) throws IOException {
+ PrintWriter pw = new PrintWriter(new OutputStreamWriter(originalUrl.equals("stdio:") ?
+ System.out : sock.getOutputStream()));
+ if (content != null) {
+ pw.print("POST " + path + " HTTP/1.0\r\n"); // FIXME chunked encoding
+ int contentLength = content.substring(0, 2).equals("\r\n") ?
+ content.length() - 2 :
+ (content.length() - content.indexOf("\r\n\r\n") - 4);
+ pw.print("Content-Length: " + contentLength + "\r\n");
+ if (contentType != null) pw.print("Content-Type: " + contentType + "\r\n");
+ } else {
+ pw.print("GET " + path + " HTTP/1.1\r\n");
+ }
+
+ pw.print("User-Agent: Ibex\r\n");
+ pw.print("Accept-encoding: gzip\r\n");
+ pw.print("Host: " + (host + (port == 80 ? "" : (":" + port))) + "\r\n");
+ if (proxied) pw.print("X-RequestOrigin: " + Main.originHost + "\r\n");
+
+ if (Proxy.Authorization.authorization != null) pw.print("Proxy-Authorization: "+Proxy.Authorization.authorization2+"\r\n");
+ if (authCache.get(originalUrl) != null) pw.print("Authorization: " + authCache.get(originalUrl) + "\r\n");
+
+ pw.print(content == null ? "\r\n" : content);
+ pw.print("\r\n");
+ pw.flush();
+ }
+
+ private void doWebAuth(Hashtable h0, String method) throws IOException {
+ if (userInfo == null) throw new HTTPException("web server demanded username/password, but none were supplied");
+ Hashtable h = parseAuthenticationChallenge(h0.get("www-authenticate").toString());
+
+ if (h.get("AUTHTYPE").equals("Basic")) {
+ if (authCache.get(originalUrl) != null) throw new HTTPException("username/password rejected");
+ authCache.put(originalUrl, "Basic " + new String(Base64.encode(userInfo.getBytes("UTF8"))));
+
+ } else if (h.get("AUTHTYPE").equals("Digest")) {
+ if (authCache.get(originalUrl) != null && !"true".equals(h.get("stale")))
+ throw new HTTPException("username/password rejected");
+ String path2 = path;
+ if (path2.startsWith("http://") || path2.startsWith("https://")) {
+ path2 = path2.substring(path2.indexOf("://") + 3);
+ path2 = path2.substring(path2.indexOf('/'));
+ }
+ String A1 = userInfo.substring(0, userInfo.indexOf(':')) + ":" + h.get("realm") + ":" +
+ userInfo.substring(userInfo.indexOf(':') + 1);
+ String A2 = method + ":" + path2;
+ authCache.put(originalUrl,
+ "Digest " +
+ "username=\"" + userInfo.substring(0, userInfo.indexOf(':')) + "\", " +
+ "realm=\"" + h.get("realm") + "\", " +
+ "nonce=\"" + h.get("nonce") + "\", " +
+ "uri=\"" + path2 + "\", " +
+ (h.get("opaque") == null ? "" : ("opaque=\"" + h.get("opaque") + "\", ")) +
+ "response=\"" + H(H(A1) + ":" + h.get("nonce") + ":" + H(A2)) + "\", " +
+ "algorithm=MD5"
+ );
+
+ } else {
+ throw new HTTPException("unknown authentication type: " + h.get("AUTHTYPE"));
+ }
+ }
+
+ private void doProxyAuth(Hashtable h0, String method) throws IOException {
+ if (Log.on) Log.info(this, "Proxy AuthChallenge: " + h0.get("proxy-authenticate"));
+ Hashtable h = parseAuthenticationChallenge(h0.get("proxy-authenticate").toString());
+ String style = h.get("AUTHTYPE").toString();
+ String realm = (String)h.get("realm");
+
+ if (style.equals("NTLM") && Proxy.Authorization.authorization2 == null) {
+ Log.info(this, "Proxy identified itself as NTLM, sending Type 1 packet");
+ Proxy.Authorization.authorization2 = "NTLM " + Base64.encode(Proxy.NTLM.type1);
+ return;
+ }
+
+ if (!realm.equals("Digest") || Proxy.Authorization.authorization2 == null || !"true".equals(h.get("stale")))
+ Proxy.Authorization.getPassword(realm, style, sock.getInetAddress().getHostAddress(),
+ Proxy.Authorization.authorization);
+
+ if (style.equals("Basic")) {
+ Proxy.Authorization.authorization2 =
+ "Basic " + new String(Base64.encode(Proxy.Authorization.authorization.getBytes("UTF8")));
+
+ } else if (style.equals("Digest")) {
+ String A1 = Proxy.Authorization.authorization.substring(0, userInfo.indexOf(':')) + ":" + h.get("realm") + ":" +
+ Proxy.Authorization.authorization.substring(Proxy.Authorization.authorization.indexOf(':') + 1);
+ String A2 = method + ":" + path;
+ Proxy.Authorization.authorization2 =
+ "Digest " +
+ "username=\"" + Proxy.Authorization.authorization.substring(0, Proxy.Authorization.authorization.indexOf(':')) +
+ "\", " +
+ "realm=\"" + h.get("realm") + "\", " +
+ "nonce=\"" + h.get("nonce") + "\", " +
+ "uri=\"" + path + "\", " +
+ (h.get("opaque") == null ? "" : ("opaque=\"" + h.get("opaque") + "\", ")) +
+ "response=\"" + H(H(A1) + ":" + h.get("nonce") + ":" + H(A2)) + "\", " +
+ "algorithm=MD5";
+
+ } else if (style.equals("NTLM")) {
+ Log.info(this, "Proxy identified itself as NTLM, got Type 2 packet");
+ byte[] type2 = Base64.decode(((String)h0.get("proxy-authenticate")).substring(5).trim());
+ for(int i=0; i<type2.length; i += 4) {
+ String log = "";
+ if (i<type2.length) log += Integer.toString(type2[i] & 0xff, 16) + " ";
+ if (i+1<type2.length) log += Integer.toString(type2[i+1] & 0xff, 16) + " ";
+ if (i+2<type2.length) log += Integer.toString(type2[i+2] & 0xff, 16) + " ";
+ if (i+3<type2.length) log += Integer.toString(type2[i+3] & 0xff, 16) + " ";
+ Log.info(this, log);
+ }
+ // FEATURE: need to keep the connection open between type1 and type3
+ // FEATURE: finish this
+ //byte[] type3 = Proxy.NTLM.getResponse(
+ //Proxy.Authorization.authorization2 = "NTLM " + Base64.encode(type3));
+ }
+ }
+
+
+ // HTTPInputStream ///////////////////////////////////////////////////////////////////////////////////
+
+ /** An input stream that represents a subset of a longer input stream. Supports HTTP chunking as well */
+ public class HTTPInputStream extends FilterInputStream implements KnownLength {
+
+ private int length = 0; ///< if chunking, numbytes left in this subset; else the remainder of the chunk
+ private Semaphore releaseMe = null; ///< this semaphore will be released when the stream is closed
+ boolean chunkedDone = false; ///< indicates that we have encountered the zero-length terminator chunk
+ boolean firstChunk = true; ///< if we're on the first chunk, we don't pre-read a CRLF
+ private int contentLength = 0; ///< the length of the entire content body; -1 if chunked
+
+ HTTPInputStream(InputStream in, int length, Semaphore releaseMe) throws IOException {
+ super(in);
+ this.releaseMe = releaseMe;
+ this.contentLength = length;
+ this.length = length == -1 ? 0 : length;
+ }
+
+ public int getLength() { return contentLength; }
+ public boolean markSupported() { return false; }
+ public int read(byte[] b) throws IOException { return read(b, 0, b.length); }
+ public long skip(long n) throws IOException { return read(null, -1, (int)n); }
+ public int available() throws IOException {
+ if (contentLength == -1) return java.lang.Math.min(super.available(), length);
+ return super.available();
+ }
+
+ public int read() throws IOException {
+ byte[] b = new byte[1];
+ int ret = read(b, 0, 1);
+ return ret == -1 ? -1 : b[0] & 0xff;
+ }
+
+ private void readChunk() throws IOException {
+ if (chunkedDone) return;
+ if (!firstChunk) super.skip(2); // CRLF
+ firstChunk = false;
+ String chunkLen = "";
+ while(true) {
+ int i = super.read();
+ if (i == -1) throw new HTTPException("encountered end of stream while reading chunk length");
+
+ // FEATURE: handle chunking extensions
+ if (i == '\r') {
+ super.read(); // LF
+ break;
+ } else {
+ chunkLen += (char)i;
+ }
+ }
+ length = Integer.parseInt(chunkLen.trim(), 16);
+ if (length == 0) chunkedDone = true;
+ }
+
+ public int read(byte[] b, int off, int len) throws IOException {
+ boolean good = false;
+ try {
+ if (length == 0 && contentLength == -1) {
+ readChunk();
+ if (chunkedDone) { good = true; return -1; }
+ } else {
+ if (length == 0) { good = true; return -1; }
+ }
+ if (len > length) len = length;
+ int ret = b == null ? (int)super.skip(len) : super.read(b, off, len);
+ if (ret >= 0) {
+ length -= ret;
+ good = true;
+ }
+ return ret;
+ } finally {
+ if (!good) reset();
+ }
+ }
+
+ public void close() throws IOException {
+ if (contentLength == -1) {
+ while(!chunkedDone) {
+ if (length != 0) skip(length);
+ readChunk();
+ }
+ skip(2);
+ } else {
+ if (length != 0) skip(length);
+ }
+ if (releaseMe != null) releaseMe.release();
+ }
+ }
+
+ void reset() {
+ firstRequest = true;
+ in = null;
+ sock = null;
+ }
+
+
+ // Misc Helpers ///////////////////////////////////////////////////////////////////////////////////
+
+ /** reads a set of HTTP headers off of the input stream, returning null if the stream is already at its end */
+ private Hashtable parseHeaders(InputStream in) throws IOException {
+ Hashtable ret = new Hashtable();
+
+ // we can't use a BufferedReader directly on the input stream, since it will buffer past the end of the headers
+ byte[] buf = new byte[4096];
+ int buflen = 0;
+ while(true) {
+ int read = in.read();
+ if (read == -1 && buflen == 0) return null;
+ if (read == -1) throw new HTTPException("stream closed while reading headers");
+ buf[buflen++] = (byte)read;
+ if (buflen >= 4 && buf[buflen - 4] == '\r' && buf[buflen - 3] == '\n' &&
+ buf[buflen - 2] == '\r' && buf[buflen - 1] == '\n')
+ break;
+ if (buflen >=2 && buf[buflen - 1] == '\n' && buf[buflen - 2] == '\n')
+ break; // nice for people using stdio
+ if (buflen == buf.length) {
+ byte[] newbuf = new byte[buf.length * 2];
+ System.arraycopy(buf, 0, newbuf, 0, buflen);
+ buf = newbuf;
+ }
+ }
+
+ BufferedReader br = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(buf, 0, buflen)));
+ String s = br.readLine();
+ if (!s.startsWith("HTTP/")) throw new HTTPException("Expected reply to start with \"HTTP/\", got: " + s);
+ ret.put("STATUSLINE", s.substring(s.indexOf(' ') + 1));
+ ret.put("HTTP", s.substring(5, s.indexOf(' ')));
+
+ while((s = br.readLine()) != null && s.length() > 0) {
+ String front = s.substring(0, s.indexOf(':')).toLowerCase();
+ String back = s.substring(s.indexOf(':') + 1).trim();
+ // ugly hack: we never replace a Digest-auth with a Basic-auth (proxy + www)
+ if (front.endsWith("-authenticate") && ret.get(front) != null && !back.equals("Digest")) continue;
+ ret.put(front, back);
+ }
+ return ret;
+ }
+
+ private Hashtable parseAuthenticationChallenge(String s) {
+ Hashtable ret = new Hashtable();
+
+ s = s.trim();
+ ret.put("AUTHTYPE", s.substring(0, s.indexOf(' ')));
+ s = s.substring(s.indexOf(' ')).trim();
+
+ while (s.length() > 0) {
+ String val = null;
+ String key = s.substring(0, s.indexOf('='));
+ s = s.substring(s.indexOf('=') + 1);
+ if (s.charAt(0) == '\"') {
+ s = s.substring(1);
+ val = s.substring(0, s.indexOf('\"'));
+ s = s.substring(s.indexOf('\"') + 1);
+ } else {
+ val = s.indexOf(',') == -1 ? s : s.substring(0, s.indexOf(','));
+ s = s.indexOf(',') == -1 ? "" : s.substring(s.indexOf(',') + 1);
+ }
+ if (s.length() > 0 && s.charAt(0) == ',') s = s.substring(1);
+ s = s.trim();
+ ret.put(key, val);
+ }
+ return ret;
+ }
+
+ private String H(String s) throws IOException {
+ byte[] b = s.getBytes("UTF8");
+ MD5 md5 = new MD5();
+ md5.update(b, 0, b.length);
+ byte[] out = new byte[md5.getDigestSize()];
+ md5.doFinal(out, 0);
+ String ret = "";
+ for(int i=0; i<out.length; i++) {
+ ret += "0123456789abcdef".charAt((out[i] & 0xf0) >> 4);
+ ret += "0123456789abcdef".charAt(out[i] & 0x0f);
+ }
+ return ret;
+ }
+
+
+ // Proxy ///////////////////////////////////////////////////////////
+
+ /** encapsulates most of the proxy logic; some is shared in HTTP.java */
+ public static class Proxy {
+
+ public String httpProxyHost = null; ///< the HTTP Proxy host to use
+ public int httpProxyPort = -1; ///< the HTTP Proxy port to use
+ public String httpsProxyHost = null; ///< seperate proxy for HTTPS
+ public int httpsProxyPort = -1;
+ public String socksProxyHost = null; ///< the SOCKS Proxy Host to use
+ public int socksProxyPort = -1; ///< the SOCKS Proxy Port to use
+ public String[] excluded = new String[] { }; ///< hosts to be excluded from proxy use; wildcards permitted
+ public JS proxyAutoConfigFunction = null; ///< the PAC script
+
+ public static Proxy detectProxyViaManual() {
+ Proxy ret = new Proxy();
+
+ ret.httpProxyHost = Platform.getEnv("http_proxy");
+ if (ret.httpProxyHost != null) {
+ if (ret.httpProxyHost.startsWith("http://")) ret.httpProxyHost = ret.httpProxyHost.substring(7);
+ if (ret.httpProxyHost.endsWith("/"))
+ ret.httpProxyHost = ret.httpProxyHost.substring(0, ret.httpProxyHost.length() - 1);
+ if (ret.httpProxyHost.indexOf(':') != -1) {
+ ret.httpProxyPort = Integer.parseInt(ret.httpProxyHost.substring(ret.httpProxyHost.indexOf(':') + 1));
+ ret.httpProxyHost = ret.httpProxyHost.substring(0, ret.httpProxyHost.indexOf(':'));
+ } else {
+ ret.httpProxyPort = 80;
+ }
+ }
+
+ ret.httpsProxyHost = Platform.getEnv("https_proxy");
+ if (ret.httpsProxyHost != null) {
+ if (ret.httpsProxyHost.startsWith("https://")) ret.httpsProxyHost = ret.httpsProxyHost.substring(7);
+ if (ret.httpsProxyHost.endsWith("/"))
+ ret.httpsProxyHost = ret.httpsProxyHost.substring(0, ret.httpsProxyHost.length() - 1);
+ if (ret.httpsProxyHost.indexOf(':') != -1) {
+ ret.httpsProxyPort = Integer.parseInt(ret.httpsProxyHost.substring(ret.httpsProxyHost.indexOf(':') + 1));
+ ret.httpsProxyHost = ret.httpsProxyHost.substring(0, ret.httpsProxyHost.indexOf(':'));
+ } else {
+ ret.httpsProxyPort = 80;
+ }
+ }
+
+ ret.socksProxyHost = Platform.getEnv("socks_proxy");
+ if (ret.socksProxyHost != null) {
+ if (ret.socksProxyHost.startsWith("socks://")) ret.socksProxyHost = ret.socksProxyHost.substring(7);
+ if (ret.socksProxyHost.endsWith("/"))
+ ret.socksProxyHost = ret.socksProxyHost.substring(0, ret.socksProxyHost.length() - 1);
+ if (ret.socksProxyHost.indexOf(':') != -1) {
+ ret.socksProxyPort = Integer.parseInt(ret.socksProxyHost.substring(ret.socksProxyHost.indexOf(':') + 1));
+ ret.socksProxyHost = ret.socksProxyHost.substring(0, ret.socksProxyHost.indexOf(':'));
+ } else {
+ ret.socksProxyPort = 80;
+ }
+ }
+
+ String noproxy = Platform.getEnv("no_proxy");
+ if (noproxy != null) {
+ StringTokenizer st = new StringTokenizer(noproxy, ",");
+ ret.excluded = new String[st.countTokens()];
+ for(int i=0; st.hasMoreTokens(); i++) ret.excluded[i] = st.nextToken();
+ }
+
+ if (ret.httpProxyHost == null && ret.socksProxyHost == null) return null;
+ return ret;
+ }
+
+ public static JSScope proxyAutoConfigRootScope = new ProxyAutoConfigRootScope();
+ public static JS getProxyAutoConfigFunction(String url) {
+ try {
+ BufferedReader br = new BufferedReader(new InputStreamReader(new HTTP(url, true).GET()));
+ String s = null;
+ String script = "";
+ while((s = br.readLine()) != null) script += s + "\n";
+ if (Log.on) Log.info(Proxy.class, "successfully retrieved WPAD PAC:");
+ if (Log.on) Log.info(Proxy.class, script);
+
+ // MS CARP hack
+ Vector carpHosts = new Vector();
+ for(int i=0; i<script.length(); i++)
+ if (script.regionMatches(i, "new Node(", 0, 9)) {
+ String host = script.substring(i + 10, script.indexOf('\"', i + 11));
+ if (Log.on) Log.info(Proxy.class, "Detected MS Proxy Server CARP Script, Host=" + host);
+ carpHosts.addElement(host);
+ }
+ if (carpHosts.size() > 0) {
+ script = "function FindProxyForURL(url, host) {\nreturn \"";
+ for(int i=0; i<carpHosts.size(); i++)
+ script += "PROXY " + carpHosts.elementAt(i) + "; ";
+ script += "\";\n}";
+ if (Log.on) Log.info(Proxy.class, "DeCARPed PAC script:");
+ if (Log.on) Log.info(Proxy.class, script);
+ }
+
+ JS scr = JS.fromReader("PAC script at " + url, 0, new StringReader(script));
+ JS.cloneWithNewParentScope(scr, proxyAutoConfigRootScope).call(null, null, null, null, 0);
+ return (JS)proxyAutoConfigRootScope.get("FindProxyForURL");
+ } catch (Exception e) {
+ if (Log.on) {
+ Log.info(Platform.class, "WPAD detection failed due to:");
+ if (e instanceof JSExn) {
+ try {
+ org.ibex.js.JSArray arr = new org.ibex.js.JSArray();
+ arr.addElement(((JSExn)e).getObject());
+ } catch (Exception e2) {
+ Log.info(Platform.class, e);
+ }
+ }
+ else Log.info(Platform.class, e);
+ }
+ return null;
+ }
+ }
+
+
+ // Authorization ///////////////////////////////////////////////////////////////////////////////////
+
+ public static class Authorization {
+
+ static public String authorization = null;
+ static public String authorization2 = null;
+ static public Semaphore waitingForUser = new Semaphore();
+
+ public static synchronized void getPassword(final String realm, final String style,
+ final String proxyIP, String oldAuth) throws IOException {
+
+ // this handles cases where multiple threads hit the proxy auth at the same time -- all but one will block on the
+ // synchronized keyword. If 'authorization' changed while the thread was blocked, it means that the user entered
+ // a password, so we should reattempt authorization.
+
+ if (authorization != oldAuth) return;
+ if (Log.on) Log.info(Authorization.class, "displaying proxy authorization dialog");
+ Scheduler.add(new Task() {
+ public void perform() throws IOException, JSExn {
+ Box b = new Box();
+ Template t = null;
+ // FIXME
+ //Template.buildTemplate("org/ibex/builtin/proxy_authorization.ibex", Stream.getInputStream((JS)Main.builtin.get("org/ibex/builtin/proxy_authorization.ibex")), new Ibex(null));
+ t.apply(b);
+ b.put("realm", realm);
+ b.put("proxyIP", proxyIP);
+ }
+ });
+
+ waitingForUser.block();
+ if (Log.on) Log.info(Authorization.class, "got proxy authorization info; re-attempting connection");
+ }
+ }
+
+
+ // ProxyAutoConfigRootJSScope ////////////////////////////////////////////////////////////////////
+
+ public static class ProxyAutoConfigRootScope extends JSScope.Global {
+
+ public ProxyAutoConfigRootScope() { super(); }
+
+ public Object get(Object name) throws JSExn {
+final String ccSwitch0 = (String)(name); SUCCESS:do { switch(ccSwitch0.length()) {
+case 7: { switch(ccSwitch0.charAt(0)) { case 'i': if ("isInNet".equals(ccSwitch0)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; }; break; } case 9: { switch(ccSwitch0.charAt(0)) { case 'd': if ("dateRange".equals(ccSwitch0)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 't': if ("timeRange".equals(ccSwitch0)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; }; break; } case 10: { switch(ccSwitch0.charAt(0)) { case 'd': if ("dnsResolve".equals(ccSwitch0)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 's': if ("shExpMatch".equals(ccSwitch0)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; }; break; } case 11: { switch(ccSwitch0.charAt(0)) { case 'P': if ("ProxyConfig".equals(ccSwitch0)) { if (true) do { return ProxyConfig;
+ } while(false); break SUCCESS; } break; case 'd': if ("dnsDomainIs".equals(ccSwitch0)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 'm': if ("myIpAddress".equals(ccSwitch0)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; }; break; } case 12: { switch(ccSwitch0.charAt(0)) { case 'i': if ("isResolvable".equals(ccSwitch0)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 'w': if ("weekdayRange".equals(ccSwitch0)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; }; break; } case 15: { switch(ccSwitch0.charAt(0)) { case 'd': if ("dnsDomainLevels".equals(ccSwitch0)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; case 'i': if ("isPlainHostName".equals(ccSwitch0)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; }; break; } case 19: { switch(ccSwitch0.charAt(0)) { case 'l': if ("localHostOrDomainIs".equals(ccSwitch0)) { if (true) do { return METHOD;
+ } while(false); break SUCCESS; } break; }; break; } } /* switch */ } while(false); /* OUTER */
+ return super.get(name);
+ }
+
+ private static final JS proxyConfigBindings = new JS();
+ private static final JS ProxyConfig = new JS() {
+ public Object get(Object name) {
+ if (name.equals("bindings")) return proxyConfigBindings;
+ return null;
+ }
+ };
+
+ public Object callMethod(Object method, Object a0, Object a1, Object a2, Object[] rest, int nargs) throws JSExn {
+final String ccSwitch1 = (String)(method); SUCCESS:do { switch(ccSwitch1.length()) {
+case 7: { switch(ccSwitch1.charAt(0)) { case 'i': if ("isInNet".equals(ccSwitch1)) { if (true) do {
+if (nargs != 3) return Boolean.FALSE;
+try {
+byte[] host = InetAddress.getByName(a0.toString()).getAddress();
+byte[] net = InetAddress.getByName(a1.toString()).getAddress();
+byte[] mask = InetAddress.getByName(a2.toString()).getAddress();
+return ((host[0] & mask[0]) == net[0] &&
+(host[1] & mask[1]) == net[1] &&
+(host[2] & mask[2]) == net[2] &&
+(host[3] & mask[3]) == net[3]) ?
+Boolean.TRUE : Boolean.FALSE;
+} catch (Exception e) {
+throw new JSExn("exception in isInNet(): " + e);
+}
+ } while(false); break SUCCESS; } break; }; break; } case 9: { switch(ccSwitch1.charAt(0)) { case 'd': if ("dateRange".equals(ccSwitch1)) { if (true) do { throw new JSExn("Ibex does not support dateRange() in PAC scripts");
+ } while(false); break SUCCESS; } break; case 't': if ("timeRange".equals(ccSwitch1)) { if (true) do { throw new JSExn("Ibex does not support timeRange() in PAC scripts");
+ } while(false); break SUCCESS; } break; }; break; } case 10: { switch(ccSwitch1.charAt(0)) { case 'd': if ("dnsResolve".equals(ccSwitch1)) { if (true) do {
+try {
+return InetAddress.getByName(a0.toString()).getHostAddress();
+} catch (UnknownHostException e) {
+return null;
+}
+ } while(false); break SUCCESS; } break; case 's': if ("shExpMatch".equals(ccSwitch1)) { if (true) do {
+StringTokenizer st = new StringTokenizer(a1.toString(), "*", false);
+String[] arr = new String[st.countTokens()];
+String s = a0.toString();
+for (int i=0; st.hasMoreTokens(); i++) arr[i] = st.nextToken();
+return match(arr, s, 0) ? Boolean.TRUE : Boolean.FALSE;
+ } while(false); break SUCCESS; } break; }; break; } case 11: { switch(ccSwitch1.charAt(0)) { case 'd': if ("dnsDomainIs".equals(ccSwitch1)) { if (true) do { return (a0.toString().endsWith(a1.toString())) ? Boolean.TRUE : Boolean.FALSE;
+ } while(false); break SUCCESS; } break; case 'm': if ("myIpAddress".equals(ccSwitch1)) { if (true) do {
+try {
+return InetAddress.getLocalHost().getHostAddress();
+} catch (UnknownHostException e) {
+if (Log.on) Log.info(this, "strange... host does not know its own address");
+return null;
+}
+ } while(false); break SUCCESS; } break; }; break; } case 12: { switch(ccSwitch1.charAt(0)) { case 'i': if ("isResolvable".equals(ccSwitch1)) { if (true) do { try {
+return (InetAddress.getByName(a0.toString()) != null) ? Boolean.TRUE : Boolean.FALSE;
+} catch (UnknownHostException e) { return F; }
+ } while(false); break SUCCESS; } break; case 'w': if ("weekdayRange".equals(ccSwitch1)) { if (true) do {
+TimeZone tz = (nargs < 3 || a2 == null || !a2.equals("GMT")) ?
+TimeZone.getTimeZone("UTC") : TimeZone.getDefault();
+Calendar c = new GregorianCalendar();
+c.setTimeZone(tz);
+c.setTime(new java.util.Date());
+java.util.Date d = c.getTime();
+int day = d.getDay();
+String d1s = a0.toString().toUpperCase();
+int d1 = 0, d2 = 0;
+for(int i=0; i<days.length; i++) if (days[i].equals(d1s)) d1 = i;
+
+if (nargs == 1)
+return d1 == day ? Boolean.TRUE : Boolean.FALSE;
+
+String d2s = a1.toString().toUpperCase();
+for(int i=0; i<days.length; i++) if (days[i].equals(d2s)) d2 = i;
+
+return ((d1 <= d2 && day >= d1 && day <= d2) || (d1 > d2 && (day >= d1 || day <= d2))) ? T : F;
+
+ } while(false); break SUCCESS; } break; }; break; } case 15: { switch(ccSwitch1.charAt(0)) { case 'd': if ("dnsDomainLevels".equals(ccSwitch1)) { if (true) do {
+String s = a0.toString();
+int i = 0;
+while((i = s.indexOf('.', i)) != -1) i++;
+return new Integer(i);
+ } while(false); break SUCCESS; } break; case 'i': if ("isPlainHostName".equals(ccSwitch1)) { if (true) do { return (a0.toString().indexOf('.') == -1) ? Boolean.TRUE : Boolean.FALSE;
+ } while(false); break SUCCESS; } break; }; break; } case 19: { switch(ccSwitch1.charAt(0)) { case 'l': if ("localHostOrDomainIs".equals(ccSwitch1)) { if (true) do {
+return (a0.equals(a1) || (a0.toString().indexOf('.') == -1 && a1.toString().startsWith(a0.toString()))) ? T:F;
+ } while(false); break SUCCESS; } break; }; break; } } /* switch */ } while(false); /* OUTER */
+ return super.callMethod(method, a0, a1, a2, rest, nargs);
+ }
+ private static boolean match(String[] arr, String s, int index) {
+ if (index >= arr.length) return true;
+ for(int i=0; i<s.length(); i++) {
+ String s2 = s.substring(i);
+ if (s2.startsWith(arr[index]) && match(arr, s2.substring(arr[index].length()), index + 1)) return true;
+ }
+ return false;
+ }
+ public static String[] days = { "SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT" };
+ }
+
+
+ /**
+ * An implementation of Microsoft's proprietary NTLM authentication protocol. This code was derived from Eric
+ * Glass's work, and is copyright as follows:
+ *
+ * Copyright (c) 2003 Eric Glass (eglass1 at comcast.net).
+ *
+ * Permission to use, copy, modify, and distribute this document for any purpose and without any fee is hereby
+ * granted, provided that the above copyright notice and this list of conditions appear in all copies.
+ * The most current version of this document may be obtained from http://davenport.sourceforge.net/ntlm.html .
+ */
+ public static class NTLM {
+
+ public static final byte[] type1 = new byte[] { 0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00 };
+
+ /**
+ * Calculates the NTLM Response for the given challenge, using the
+ * specified password.
+ *
+ * @param password The user's password.
+ * @param challenge The Type 2 challenge from the server.
+ *
+ * @return The NTLM Response.
+ */
+ public static byte[] getNTLMResponse(String password, byte[] challenge)
+ throws UnsupportedEncodingException {
+ byte[] ntlmHash = ntlmHash(password);
+ return lmResponse(ntlmHash, challenge);
+ }
+
+ /**
+ * Calculates the LM Response for the given challenge, using the specified
+ * password.
+ *
+ * @param password The user's password.
+ * @param challenge The Type 2 challenge from the server.
+ *
+ * @return The LM Response.
+ */
+ public static byte[] getLMResponse(String password, byte[] challenge)
+ {
+ byte[] lmHash = lmHash(password);
+ return lmResponse(lmHash, challenge);
+ }
+
+ /**
+ * Calculates the NTLMv2 Response for the given challenge, using the
+ * specified authentication target, username, password, target information
+ * block, and client challenge.
+ *
+ * @param target The authentication target (i.e., domain).
+ * @param user The username.
+ * @param password The user's password.
+ * @param targetInformation The target information block from the Type 2
+ * message.
+ * @param challenge The Type 2 challenge from the server.
+ * @param clientChallenge The random 8-byte client challenge.
+ *
+ * @return The NTLMv2 Response.
+ */
+ public static byte[] getNTLMv2Response(String target, String user,
+ String password, byte[] targetInformation, byte[] challenge,
+ byte[] clientChallenge) throws UnsupportedEncodingException {
+ byte[] ntlmv2Hash = ntlmv2Hash(target, user, password);
+ byte[] blob = createBlob(targetInformation, clientChallenge);
+ return lmv2Response(ntlmv2Hash, blob, challenge);
+ }
+
+ /**
+ * Calculates the LMv2 Response for the given challenge, using the
+ * specified authentication target, username, password, and client
+ * challenge.
+ *
+ * @param target The authentication target (i.e., domain).
+ * @param user The username.
+ * @param password The user's password.
+ * @param challenge The Type 2 challenge from the server.
+ * @param clientChallenge The random 8-byte client challenge.
+ *
+ * @return The LMv2 Response.
+ */
+ public static byte[] getLMv2Response(String target, String user,
+ String password, byte[] challenge, byte[] clientChallenge)
+ throws UnsupportedEncodingException {
+ byte[] ntlmv2Hash = ntlmv2Hash(target, user, password);
+ return lmv2Response(ntlmv2Hash, clientChallenge, challenge);
+ }
+
+ /**
+ * Calculates the NTLM2 Session Response for the given challenge, using the
+ * specified password and client challenge.
+ *
+ * @param password The user's password.
+ * @param challenge The Type 2 challenge from the server.
+ * @param clientChallenge The random 8-byte client challenge.
+ *
+ * @return The NTLM2 Session Response. This is placed in the NTLM
+ * response field of the Type 3 message; the LM response field contains
+ * the client challenge, null-padded to 24 bytes.
+ */
+ public static byte[] getNTLM2SessionResponse(String password,
+ byte[] challenge, byte[] clientChallenge) throws UnsupportedEncodingException {
+ byte[] ntlmHash = ntlmHash(password);
+ MD5 md5 = new MD5();
+ md5.update(challenge, 0, challenge.length);
+ md5.update(clientChallenge, 0, clientChallenge.length);
+ byte[] sessionHash = new byte[8];
+ byte[] md5_out = new byte[md5.getDigestSize()];
+ md5.doFinal(md5_out, 0);
+ System.arraycopy(md5_out, 0, sessionHash, 0, 8);
+ return lmResponse(ntlmHash, sessionHash);
+ }
+
+ /**
+ * Creates the LM Hash of the user's password.
+ *
+ * @param password The password.
+ *
+ * @return The LM Hash of the given password, used in the calculation
+ * of the LM Response.
+ */
+ private static byte[] lmHash(String password) {
+ /*
+ byte[] oemPassword = password.toUpperCase().getBytes("UTF8");
+ int length = java.lang.Math.min(oemPassword.length, 14);
+ byte[] keyBytes = new byte[14];
+ System.arraycopy(oemPassword, 0, keyBytes, 0, length);
+ Key lowKey = createDESKey(keyBytes, 0);
+ Key highKey = createDESKey(keyBytes, 7);
+ byte[] magicConstant = "KGS!@#$%".getBytes("UTF8");
+ Cipher des = Cipher.getInstance("DES/ECB/NoPadding");
+ des.init(Cipher.ENCRYPT_MODE, lowKey);
+ byte[] lowHash = des.doFinal(magicConstant);
+ des.init(Cipher.ENCRYPT_MODE, highKey);
+ byte[] highHash = des.doFinal(magicConstant);
+ byte[] lmHash = new byte[16];
+ System.arraycopy(lowHash, 0, lmHash, 0, 8);
+ System.arraycopy(highHash, 0, lmHash, 8, 8);
+ return lmHash;
+ */
+ return null;
+ }
+
+ /**
+ * Creates the NTLM Hash of the user's password.
+ *
+ * @param password The password.
+ *
+ * @return The NTLM Hash of the given password, used in the calculation
+ * of the NTLM Response and the NTLMv2 and LMv2 Hashes.
+ */
+ private static byte[] ntlmHash(String password) throws UnsupportedEncodingException {
+ // FIXME
+ /*
+ byte[] unicodePassword = password.getBytes("UnicodeLittleUnmarked");
+ MD4 md4 = new MD4();
+ md4.update(unicodePassword, 0, unicodePassword.length);
+ byte[] ret = new byte[md4.getDigestSize()];
+ return ret;
+ */
+ return null;
+ }
+
+ /**
+ * Creates the NTLMv2 Hash of the user's password.
+ *
+ * @param target The authentication target (i.e., domain).
+ * @param user The username.
+ * @param password The password.
+ *
+ * @return The NTLMv2 Hash, used in the calculation of the NTLMv2
+ * and LMv2 Responses.
+ */
+ private static byte[] ntlmv2Hash(String target, String user,
+ String password) throws UnsupportedEncodingException {
+ byte[] ntlmHash = ntlmHash(password);
+ String identity = user.toUpperCase() + target.toUpperCase();
+ return hmacMD5(identity.getBytes("UnicodeLittleUnmarked"), ntlmHash);
+ }
+
+ /**
+ * Creates the LM Response from the given hash and Type 2 challenge.
+ *
+ * @param hash The LM or NTLM Hash.
+ * @param challenge The server challenge from the Type 2 message.
+ *
+ * @return The response (either LM or NTLM, depending on the provided
+ * hash).
+ */
+ private static byte[] lmResponse(byte[] hash, byte[] challenge)
+ {
+ /*
+ byte[] keyBytes = new byte[21];
+ System.arraycopy(hash, 0, keyBytes, 0, 16);
+ Key lowKey = createDESKey(keyBytes, 0);
+ Key middleKey = createDESKey(keyBytes, 7);
+ Key highKey = createDESKey(keyBytes, 14);
+ Cipher des = Cipher.getInstance("DES/ECB/NoPadding");
+ des.init(Cipher.ENCRYPT_MODE, lowKey);
+ byte[] lowResponse = des.doFinal(challenge);
+ des.init(Cipher.ENCRYPT_MODE, middleKey);
+ byte[] middleResponse = des.doFinal(challenge);
+ des.init(Cipher.ENCRYPT_MODE, highKey);
+ byte[] highResponse = des.doFinal(challenge);
+ byte[] lmResponse = new byte[24];
+ System.arraycopy(lowResponse, 0, lmResponse, 0, 8);
+ System.arraycopy(middleResponse, 0, lmResponse, 8, 8);
+ System.arraycopy(highResponse, 0, lmResponse, 16, 8);
+ return lmResponse;
+ */
+ return null;
+ }
+
+ /**
+ * Creates the LMv2 Response from the given hash, client data, and
+ * Type 2 challenge.
+ *
+ * @param hash The NTLMv2 Hash.
+ * @param clientData The client data (blob or client challenge).
+ * @param challenge The server challenge from the Type 2 message.
+ *
+ * @return The response (either NTLMv2 or LMv2, depending on the
+ * client data).
+ */
+ private static byte[] lmv2Response(byte[] hash, byte[] clientData,
+ byte[] challenge) {
+ byte[] data = new byte[challenge.length + clientData.length];
+ System.arraycopy(challenge, 0, data, 0, challenge.length);
+ System.arraycopy(clientData, 0, data, challenge.length,
+ clientData.length);
+ byte[] mac = hmacMD5(data, hash);
+ byte[] lmv2Response = new byte[mac.length + clientData.length];
+ System.arraycopy(mac, 0, lmv2Response, 0, mac.length);
+ System.arraycopy(clientData, 0, lmv2Response, mac.length,
+ clientData.length);
+ return lmv2Response;
+ }
+
+ /**
+ * Creates the NTLMv2 blob from the given target information block and
+ * client challenge.
+ *
+ * @param targetInformation The target information block from the Type 2
+ * message.
+ * @param clientChallenge The random 8-byte client challenge.
+ *
+ * @return The blob, used in the calculation of the NTLMv2 Response.
+ */
+ private static byte[] createBlob(byte[] targetInformation,
+ byte[] clientChallenge) {
+ byte[] blobSignature = new byte[] {
+ (byte) 0x01, (byte) 0x01, (byte) 0x00, (byte) 0x00
+ };
+ byte[] reserved = new byte[] {
+ (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00
+ };
+ byte[] unknown1 = new byte[] {
+ (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00
+ };
+ byte[] unknown2 = new byte[] {
+ (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00
+ };
+ long time = System.currentTimeMillis();
+ time += 11644473600000l; // milliseconds from January 1, 1601 -> epoch.
+ time *= 10000; // tenths of a microsecond.
+ // convert to little-endian byte array.
+ byte[] timestamp = new byte[8];
+ for (int i = 0; i < 8; i++) {
+ timestamp[i] = (byte) time;
+ time >>>= 8;
+ }
+ byte[] blob = new byte[blobSignature.length + reserved.length +
+ timestamp.length + clientChallenge.length +
+ unknown1.length + targetInformation.length +
+ unknown2.length];
+ int offset = 0;
+ System.arraycopy(blobSignature, 0, blob, offset, blobSignature.length);
+ offset += blobSignature.length;
+ System.arraycopy(reserved, 0, blob, offset, reserved.length);
+ offset += reserved.length;
+ System.arraycopy(timestamp, 0, blob, offset, timestamp.length);
+ offset += timestamp.length;
+ System.arraycopy(clientChallenge, 0, blob, offset,
+ clientChallenge.length);
+ offset += clientChallenge.length;
+ System.arraycopy(unknown1, 0, blob, offset, unknown1.length);
+ offset += unknown1.length;
+ System.arraycopy(targetInformation, 0, blob, offset,
+ targetInformation.length);
+ offset += targetInformation.length;
+ System.arraycopy(unknown2, 0, blob, offset, unknown2.length);
+ return blob;
+ }
+
+ /**
+ * Calculates the HMAC-MD5 hash of the given data using the specified
+ * hashing key.
+ *
+ * @param data The data for which the hash will be calculated.
+ * @param key The hashing key.
+ *
+ * @return The HMAC-MD5 hash of the given data.
+ */
+ private static byte[] hmacMD5(byte[] data, byte[] key) {
+ byte[] ipad = new byte[64];
+ byte[] opad = new byte[64];
+ for (int i = 0; i < 64; i++) {
+ ipad[i] = (byte) 0x36;
+ opad[i] = (byte) 0x5c;
+ }
+ for (int i = key.length - 1; i >= 0; i--) {
+ ipad[i] ^= key[i];
+ opad[i] ^= key[i];
+ }
+ byte[] content = new byte[data.length + 64];
+ System.arraycopy(ipad, 0, content, 0, 64);
+ System.arraycopy(data, 0, content, 64, data.length);
+ MD5 md5 = new MD5();
+ md5.update(content, 0, content.length);
+ data = new byte[md5.getDigestSize()];
+ md5.doFinal(data, 0);
+ content = new byte[data.length + 64];
+ System.arraycopy(opad, 0, content, 0, 64);
+ System.arraycopy(data, 0, content, 64, data.length);
+ md5 = new MD5();
+ md5.update(content, 0, content.length);
+ byte[] ret = new byte[md5.getDigestSize()];
+ md5.doFinal(ret, 0);
+ return ret;
+ }
+
+ /**
+ * Creates a DES encryption key from the given key material.
+ *
+ * @param bytes A byte array containing the DES key material.
+ * @param offset The offset in the given byte array at which
+ * the 7-byte key material starts.
+ *
+ * @return A DES encryption key created from the key material
+ * starting at the specified offset in the given byte array.
+ */
+ /*
+ private static Key createDESKey(byte[] bytes, int offset) {
+ byte[] keyBytes = new byte[7];
+ System.arraycopy(bytes, offset, keyBytes, 0, 7);
+ byte[] material = new byte[8];
+ material[0] = keyBytes[0];
+ material[1] = (byte) (keyBytes[0] << 7 | (keyBytes[1] & 0xff) >>> 1);
+ material[2] = (byte) (keyBytes[1] << 6 | (keyBytes[2] & 0xff) >>> 2);
+ material[3] = (byte) (keyBytes[2] << 5 | (keyBytes[3] & 0xff) >>> 3);
+ material[4] = (byte) (keyBytes[3] << 4 | (keyBytes[4] & 0xff) >>> 4);
+ material[5] = (byte) (keyBytes[4] << 3 | (keyBytes[5] & 0xff) >>> 5);
+ material[6] = (byte) (keyBytes[5] << 2 | (keyBytes[6] & 0xff) >>> 6);
+ material[7] = (byte) (keyBytes[6] << 1);
+ oddParity(material);
+ return new SecretKeySpec(material, "DES");
+ }
+ */
+
+ /**
+ * Applies odd parity to the given byte array.
+ *
+ * @param bytes The data whose parity bits are to be adjusted for
+ * odd parity.
+ */
+ private static void oddParity(byte[] bytes) {
+ for (int i = 0; i < bytes.length; i++) {
+ byte b = bytes[i];
+ boolean needsParity = (((b >>> 7) ^ (b >>> 6) ^ (b >>> 5) ^
+ (b >>> 4) ^ (b >>> 3) ^ (b >>> 2) ^
+ (b >>> 1)) & 0x01) == 0;
+ if (needsParity) {
+ bytes[i] |= (byte) 0x01;
+ } else {
+ bytes[i] &= (byte) 0xfe;
+ }
+ }
+ }
+
+ }
+ }
+}
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.net;
+
+import java.io.*;
+import java.util.*;
+import org.ibex.js.*;
+import org.ibex.util.*;
+import org.ibex.crypto.*;
+
+/**
+ * A partial RPC-style SOAP 1.1 client. Implemented from the SOAP 1.1
+ * Spec and Dave Winer's "SOAP for Busy Developers". This class
+ * extends XMLRPC in order to share some networking logic.
+ *
+ * Currently unsupported features/hacks:
+ * <ul><li> Multi-ref data and circular references
+ * <li> 'Document Style'
+ * <li> WSDL support
+ * </ul>
+ */
+public class SOAP extends XMLRPC {
+
+ /** the desired content of the SOAPAction header */
+ String action = null;
+
+ /** the namespace to use */
+ String nameSpace = null;
+
+ /** When you get a property from an SOAP, it just returns another SOAP with the property name tacked onto methodname. */
+ public Object get(Object name) {
+ return new SOAP(url, (method.equals("") ? "" : method + ".") + name.toString(), this, action, nameSpace); }
+
+
+ // Methods to Recieve and parse SOAP Responses ////////////////////////////////////////////////////
+
+ public void startElement(String name, String[] keys, Object[] vals, int line, int col) {
+
+ content.reset();
+ if (name.equals("SOAP-ENV:Envelope")) return;
+ if (name.equals("SOAP-ENV:Body")) return;
+ if (name.equals("SOAP-ENV:Fault")) fault = true;
+
+ // add a generic struct; we'll change this if our type is different
+ objects.addElement(new JS());
+
+ for(int i=0; i<keys.length; i++) {
+ String key = keys[i];
+ String value = vals[i].toString();
+ if (key.endsWith("ype")) {
+ if (value.endsWith("boolean")) {
+ objects.removeElementAt(objects.size() - 1);
+ objects.addElement(Boolean.FALSE);
+ } else if (value.endsWith("int")) {
+ objects.removeElementAt(objects.size() - 1);
+ objects.addElement(new Integer(0));
+ } else if (value.endsWith("double")) {
+ objects.removeElementAt(objects.size() - 1);
+ objects.addElement(new Double(0.0));
+ } else if (value.endsWith("string")) {
+ objects.removeElementAt(objects.size() - 1);
+ objects.addElement("");
+ } else if (value.endsWith("base64")) {
+ objects.removeElementAt(objects.size() - 1);
+ objects.addElement(new byte[] { });
+ } else if (value.endsWith("null")) {
+ objects.removeElementAt(objects.size() - 1);
+ objects.addElement(null);
+ } else if (value.endsWith("arrayType") || value.endsWith("JSArray") || key.endsWith("arrayType")) {
+ objects.removeElementAt(objects.size() - 1);
+ objects.addElement(new JSArray());
+ }
+ }
+ }
+ }
+
+ public void endElement(String name, int line, int col) {
+
+ if (name.equals("SOAP-ENV:Envelope")) return;
+ if (name.equals("SOAP-ENV:Body")) return;
+
+ if (content.size() > 0 && content.toString().trim().length() > 0) {
+
+ // remove ourselves
+ Object me = objects.elementAt(objects.size() - 1);
+
+ if (fault || me instanceof String) {
+ objects.removeElementAt(objects.size() - 1);
+ objects.addElement(new String(content.getBuf(), 0, content.size()).intern());
+ content.reset();
+
+ } else if (me instanceof byte[]) {
+ objects.removeElementAt(objects.size() - 1);
+ objects.addElement(new Stream.ByteArray(Base64.decode(new String(content.getBuf(), 0, content.size())), null));
+ content.reset();
+
+ } else if (me instanceof Integer) {
+ objects.removeElementAt(objects.size() - 1);
+ objects.addElement(new Integer(new String(content.getBuf(), 0, content.size())));
+ content.reset();
+
+ } else if (me instanceof Boolean) {
+ objects.removeElementAt(objects.size() - 1);
+ String s = new String(content.getBuf(), 0, content.size()).trim();
+ if (s.equals("1") || s.equals("true")) objects.addElement(Boolean.TRUE);
+ else objects.addElement(Boolean.FALSE);
+ content.reset();
+
+ } else if (me instanceof Double) {
+ objects.removeElementAt(objects.size() - 1);
+ objects.addElement(new Double(new String(content.getBuf(), 0, content.size())));
+ content.reset();
+
+ } else {
+ // okay, we got PCDATA for what is supposedly a
+ // struct... somebody's not adding their type info...
+ String s = new String(content.getBuf(), 0, content.size()).trim();
+ boolean hasdot = false;
+ for(int i=0; i<s.length(); i++) {
+ if (s.charAt(i) == '.') hasdot = true;
+ if (!Character.isDigit(s.charAt(i))) {
+ objects.removeElementAt(objects.size() - 1);
+ objects.addElement(s);
+ return;
+ }
+ }
+ if (hasdot) {
+ objects.removeElementAt(objects.size() - 1);
+ objects.addElement(new Double(s));
+ } else {
+ objects.removeElementAt(objects.size() - 1);
+ objects.addElement(new Integer(s));
+ }
+ content.reset();
+ }
+
+ }
+
+ // remove ourselves
+ Object me = objects.elementAt(objects.size() - 1);
+
+ // find our parent
+ Object parent = objects.size() > 1 ? objects.elementAt(objects.size() - 2) : null;
+
+ // we want to fold stuff back into the fault object
+ if (objects.size() < 2) return;
+
+ // our parent "should" be an aggregate type -- add ourselves to it.
+ if (parent != null && parent instanceof JSArray) {
+ objects.removeElementAt(objects.size() - 1);
+ ((JSArray)parent).addElement(me);
+
+ } else if (parent != null && parent instanceof JS) {
+ objects.removeElementAt(objects.size() - 1);
+ try {
+ ((JS)parent).put(name, me);
+ } catch (JSExn e) {
+ throw new Error("this should never happen");
+ }
+
+ }
+
+ }
+
+ /** Appends the SOAP representation of <code>o</code> to <code>sb</code> */
+ void appendObject(String name, Object o, StringBuffer sb) throws JSExn {
+ if (o instanceof Number) {
+ if ((double)((Number)o).intValue() == ((Number)o).doubleValue()) {
+ sb.append(" <" + name + " xsi:type=\"xsd:int\">");
+ sb.append(((Number)o).intValue());
+ sb.append("</" + name + ">\r\n");
+ } else {
+ sb.append(" <" + name + " xsi:type=\"xsd:double\">");
+ sb.append(o);
+ sb.append("</" + name + ">\r\n");
+ }
+
+ } else if (o instanceof Boolean) {
+ sb.append(" <" + name + " xsi:type=\"xsd:boolean\">");
+ sb.append(((Boolean)o).booleanValue() ? "true" : "false");
+ sb.append("</" + name + ">\r\n");
+
+ } else if (o instanceof Stream) {
+ try {
+ sb.append(" <" + name + " xsi:type=\"SOAP-ENC:base64\">\r\n");
+ InputStream is = ((Stream)o).getInputStream();
+ byte[] buf = new byte[54];
+ while(true) {
+ int numread = is.read(buf, 0, 54);
+ if (numread == -1) break;
+ byte[] writebuf = buf;
+ if (numread < buf.length) {
+ writebuf = new byte[numread];
+ System.arraycopy(buf, 0, writebuf, 0, numread);
+ }
+ sb.append(" ");
+ sb.append(new String(Base64.encode(writebuf)));
+ sb.append("\r\n");
+ }
+ sb.append(((Boolean)o).booleanValue() ? "1" : "0");
+ sb.append("</" + name + ">\r\n");
+ } catch (IOException e) {
+ if (Log.on) Log.info(this, "caught IOException while attempting to send a ByteStream via SOAP");
+ if (Log.on) Log.info(this, e);
+ throw new JSExn("caught IOException while attempting to send a ByteStream via SOAP");
+ }
+
+ } else if (o instanceof String) {
+ sb.append(" <" + name + " xsi:type=\"xsd:string\">");
+ String s = (String)o;
+ if (s.indexOf('<') == -1 && s.indexOf('&') == -1) {
+ sb.append(s);
+ } else {
+ char[] cbuf = s.toCharArray();
+ while(true) {
+ int oldi = 0, i=0;
+ while(i < cbuf.length && cbuf[i] != '<' && cbuf[i] != '&') i++;
+ sb.append(cbuf, oldi, i);
+ if (i == cbuf.length) break;
+ if (cbuf[i] == '<') sb.append("<");
+ else if (cbuf[i] == '&') sb.append("&");
+ i = oldi = i + 1;
+ }
+ }
+ sb.append("</" + name + ">\r\n");
+
+ } else if (o instanceof JSArray) {
+ JSArray a = (JSArray)o;
+ sb.append(" <" + name + " SOAP-ENC:arrayType=\"xsd:ur-type[" + a.length() + "]\">");
+ for(int i=0; i<a.length(); i++) appendObject("item", a.elementAt(i), sb);
+ sb.append("</" + name + ">\r\n");
+
+ } else if (o instanceof JS) {
+ JS j = (JS)o;
+ sb.append(" <" + name + ">");
+ Enumeration e = j.keys();
+ while(e.hasMoreElements()) {
+ Object key = e.nextElement();
+ appendObject((String)key, j.get(key), sb);
+ }
+ sb.append("</" + name + ">\r\n");
+
+ }
+ }
+
+ protected String buildRequest(JSArray args) throws JSExn, IOException {
+ // build up the request
+ StringBuffer content = new StringBuffer();
+ content.append("SOAPAction: " + action + "\r\n\r\n");
+ content.append("<?xml version=\"1.0\"?>\r\n");
+ content.append("<SOAP-ENV:Envelope SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"\r\n");
+ content.append(" xmlns:SOAP-ENC=\"http://schemas.xmlsoap.org/soap/encoding/\"\r\n");
+ content.append(" xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\"\r\n");
+ content.append(" xmlns:xsd=\"http://www.w3.org/1999/XMLSchema\"\r\n");
+ content.append(" xmlns:xsi=\"http://www.w3.org/1999/XMLSchema-instance\">\r\n");
+ content.append("<SOAP-ENV:Body>\r\n");
+ content.append(" <");
+ content.append(method);
+ content.append(nameSpace != null ? " xmlns=\"" + nameSpace + "\"" : "");
+ content.append(">\r\n");
+ if (args.length() > 0) {
+ Enumeration e = ((JS)args.elementAt(0)).keys();
+ while(e.hasMoreElements()) {
+ Object key = e.nextElement();
+ appendObject((String)key, ((JS)args.elementAt(0)).get(key), content);
+ }
+ }
+ content.append(" </" + method + "></SOAP-ENV:Body></SOAP-ENV:Envelope>\r\n");
+ return content.toString();
+ }
+
+ public SOAP(String url, String methodname, String action, String nameSpace) {
+ super(url, methodname);
+ this.action = action;
+ this.nameSpace = nameSpace;
+ }
+ public SOAP(String url, String methodname, SOAP httpSource, String action, String nameSpace) {
+ super(url, methodname, httpSource);
+ this.action = action;
+ this.nameSpace = nameSpace;
+ }
+
+}
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.net;
+
+import java.io.*;
+import java.util.*;
+import org.ibex.js.*;
+import org.ibex.util.*;
+import org.ibex.crypto.*;
+
+/**
+ * An XML-RPC client implemented as a JavaScript Host Object. See the
+ * Ibex spec for information on its behavior.
+ *
+ * NOTE: this client is EXTREMELY lenient in the responses it will
+ * accept; there are many, many invalid responses that it will
+ * successfully parse and return. Do NOT use this to determine the
+ * validity of your server.
+ *
+ * This client conforms to <a href="http://www.xmlrpc.com/spec">The
+ * XML-RPC Spec</a>, subject to these limitations:
+ * <ol>
+ * <li> XMLRPC cannot invoke methods that require a <base64/> argument
+ * <li> if a return value contains a <base64/>, it will be returned as a string
+ * <li> The decision to pass a number as <i4/> or <double/> is based
+ * entirely on whether or not the argument is fractional. Thus, it
+ * is impossible to pass a non-fractional number to an xmlrpc
+ * method that insists on being called with a <double/> element. We
+ * hope that most xml-rpc servers will be able to automatically
+ * convert.
+ * </ol>
+ */
+public class XMLRPC extends JS {
+
+ public XMLRPC(String url, String method) {
+ this.http = url.startsWith("stdio:") ? HTTP.stdio : new HTTP(url);
+ this.url = url;
+ this.method = method;
+ }
+ public XMLRPC(String url, String method, XMLRPC httpSource) {
+ this.http = httpSource.http; this.url = url; this.method = method; }
+ public Object get(Object name) {
+ return new XMLRPC(url, (method.equals("") ? "" : method + ".") + name.toString(), this); }
+
+
+ /** this holds character content as we read it in -- since there is only one per instance, we don't support mixed content */
+ protected AccessibleCharArrayWriter content = new AccessibleCharArrayWriter(100);
+ protected String url = null; ///< the url to connect to
+ protected String method = null; ///< the method name to invoke on the remove server
+ protected HTTP http = null; ///< the HTTP connection to use
+ private Hash tracker; ///< used to detect multi-ref data
+ protected boolean fault = false; ///< True iff the return value is a fault (and should be thrown as an exception)
+
+
+ /** The object stack. As we process xml elements, pieces of the
+ * return value are pushed onto and popped off of this stack.
+ *
+ * The general protocol is that any time a <value> tag is
+ * encountered, an empty String ("") is pushed onto the stack. If
+ * the <value/> node has content (either an anonymous
+ * string or some other XML node), that content replaces the
+ * empty string.
+ *
+ * If an <array> tag is encountered, a null is pushed onto the
+ * stack. When a </data> is encountered, we search back on the
+ * stack to the last null, replace it with a NativeJSArray, and
+ * insert into it all elements above it on the stack.
+ *
+ * If a <struct> tag is encountered, a JSect is pushed
+ * onto the stack. If a <name> tag is encountered, its CDATA is
+ * pushed onto the stack. When a </member> is encountered, the
+ * name (second element on stack) and value (top of stack) are
+ * popped off the stack and inserted into the struct (third
+ * element on stack).
+ */
+ protected Vec objects = null;
+
+
+ // Recieve ////////////////////////////////////////////////////////////////
+
+ private class Helper extends XML {
+ public Helper() { super(BUFFER_SIZE); }
+
+ public void startElement(XML.Element c) {
+ content.reset();
+final String ccSwitch0 = (String)(c.getLocalName()); SUCCESS:do { switch(ccSwitch0.length()) {
+case 5: { switch(ccSwitch0.charAt(0)) { case 'a': if ("array".equals(ccSwitch0)) { if (true) do { objects.setElementAt(null, objects.size() - 1);
+ } while(false); break SUCCESS; } break; case 'f': if ("fault".equals(ccSwitch0)) { if (true) do { fault = true;
+ } while(false); break SUCCESS; } break; case 'v': if ("value".equals(ccSwitch0)) { if (true) do { objects.addElement("");
+ } while(false); break SUCCESS; } break; }; break; } case 6: { switch(ccSwitch0.charAt(0)) { case 's': if ("struct".equals(ccSwitch0)) { if (true) do { objects.setElementAt(new JS(), objects.size() - 1);
+ } while(false); break SUCCESS; } break; }; break; } } /* switch */ } while(false); /* OUTER */
+ }
+
+ public void endElement(XML.Element c) {
+final String ccSwitch1 = (String)(c.getLocalName()); SUCCESS:do { switch(ccSwitch1.length()) {
+case 2: { switch(ccSwitch1.charAt(0)) { case 'i': if ("i4".equals(ccSwitch1)) { if (true) do { objects.setElementAt(new Integer(new String(content.getBuf(), 0, content.size())), objects.size() - 1);
+ } while(false); break SUCCESS; } break; }; break; } case 3: { switch(ccSwitch1.charAt(0)) { case 'i': if ("int".equals(ccSwitch1)) { if (true) do { objects.setElementAt(new Integer(new String(content.getBuf(), 0, content.size())), objects.size() - 1);
+ } while(false); break SUCCESS; } break; }; break; } case 4: { switch(ccSwitch1.charAt(0)) { case 'd': if ("data".equals(ccSwitch1)) { if (true) do {
+int i;
+for(i=objects.size() - 1; objects.elementAt(i) != null; i--);
+JSArray arr = new JSArray();
+try {
+for(int j = i + 1; j<objects.size(); j++) arr.put(new Integer(j - i - 1), objects.elementAt(j));
+} catch (JSExn e) {
+throw new Error("this should never happen");
+}
+objects.setElementAt(arr, i);
+objects.setSize(i + 1);
+ } while(false); break SUCCESS; } break; case 'n': if ("name".equals(ccSwitch1)) { if (true) do { objects.addElement(new String(content.getBuf(), 0, content.size()));
+ } while(false); break SUCCESS; } break; }; break; } case 5: { switch(ccSwitch1.charAt(0)) { case 'v': if ("value".equals(ccSwitch1)) { if (true) do { if ("".equals(objects.lastElement()))
+objects.setElementAt(new String(content.getBuf(), 0, content.size()), objects.size() - 1);
+ } while(false); break SUCCESS; } break; }; break; } case 6: { switch(ccSwitch1.charAt(0)) { case 'b': if ("base64".equals(ccSwitch1)) { if (true) do {
+objects.setElementAt(new Stream.ByteArray(Base64.decode(new String(content.getBuf(), 0, content.size())),
+null), objects.size() - 1);
+ } while(false); break SUCCESS; } break; case 'd': if ("double".equals(ccSwitch1)) { if (true) do { objects.setElementAt(new Double(new String(content.getBuf(), 0, content.size())), objects.size() - 1);
+ } while(false); break SUCCESS; } break; case 'm': if ("member".equals(ccSwitch1)) { if (true) do {
+Object memberValue = objects.elementAt(objects.size() - 1);
+String memberName = (String)objects.elementAt(objects.size() - 2);
+JS struct = (JS)objects.elementAt(objects.size() - 3);
+try {
+struct.put(memberName, memberValue);
+} catch (JSExn e) {
+throw new Error("this should never happen");
+}
+objects.setSize(objects.size() - 2);
+ } while(false); break SUCCESS; } break; case 's': if ("string".equals(ccSwitch1)) { if (true) do { objects.setElementAt(new String(content.getBuf(), 0, content.size()), objects.size() - 1);
+ } while(false); break SUCCESS; } break; }; break; } case 7: { switch(ccSwitch1.charAt(0)) { case 'b': if ("boolean".equals(ccSwitch1)) { if (true) do { objects.setElementAt(content.getBuf()[0] == '1' ? Boolean.TRUE : Boolean.FALSE, objects.size() - 1);
+ } while(false); break SUCCESS; } break; }; break; } case 16: { switch(ccSwitch1.charAt(0)) { case 'd': if ("dateTime.iso8601".equals(ccSwitch1)) { if (true) do {
+String s = new String(content.getBuf(), 0, content.size());
+
+
+int i=0;
+while(Character.isWhitespace(s.charAt(i))) i++;
+if (i > 0) s = s.substring(i);
+
+try {
+JSDate nd = new JSDate();
+double date = JSDate.date_msecFromDate(Double.valueOf(s.substring(0, 4)).doubleValue(),
+Double.valueOf(s.substring(4, 6)).doubleValue() - 1,
+Double.valueOf(s.substring(6, 8)).doubleValue(),
+Double.valueOf(s.substring(9, 11)).doubleValue(),
+Double.valueOf(s.substring(12, 14)).doubleValue(),
+Double.valueOf(s.substring(15, 17)).doubleValue(),
+(double)0
+);
+nd.setTime(JSDate.internalUTC(date));
+objects.setElementAt(nd, objects.size() - 1);
+
+} catch (Exception e) {
+throw new RuntimeException("ibex.net.rpc.xml.recieve.malformedDateTag" +
+"the server sent a <dateTime.iso8601> tag which was malformed: " + s);
+}
+ } while(false); break SUCCESS; } break; }; break; } } /* switch */ } while(false); /* OUTER */
+ content.reset();
+ }
+
+ public void characters(char[] ch, int start, int length) {
+ try { content.write(ch, start, length); }
+ catch (Exception e) {
+ if (Log.on) Log.info(this, "Exception in XMLRPC.content() -- this should never happen");
+ if (Log.on) Log.info(this, e);
+ }
+ }
+
+ public void whitespace(char[] ch, int start, int length) {}
+ }
+
+ // Send ///////////////////////////////////////////////////////////////////////////
+
+ protected String buildRequest(JSArray args) throws JSExn, IOException {
+ StringBuffer content = new StringBuffer();
+ content.append("\r\n");
+ content.append("<?xml version=\"1.0\"?>\n");
+ content.append(" <methodCall>\n");
+ content.append(" <methodName>");
+ content.append(method);
+ content.append("</methodName>\n");
+ content.append(" <params>\n");
+ for(int i=0; i<args.length(); i++) {
+ content.append(" <param>\n");
+ appendObject(args.elementAt(i), content);
+ content.append(" </param>\n");
+ }
+ content.append(" </params>\n");
+ content.append(" </methodCall>");
+ return content.toString();
+ }
+
+ /** Appends the XML-RPC representation of <code>o</code> to <code>sb</code> */
+ void appendObject(Object o, StringBuffer sb) throws JSExn {
+
+ if (o == null) {
+ throw new JSExn("attempted to send a null value via XML-RPC");
+
+ } else if (o instanceof Number) {
+ if ((double)((Number)o).intValue() == ((Number)o).doubleValue()) {
+ sb.append(" <value><i4>");
+ sb.append(((Number)o).intValue());
+ sb.append("</i4></value>\n");
+ } else {
+ sb.append(" <value><double>");
+ sb.append(o);
+ sb.append("</double></value>\n");
+ }
+
+ } else if (o instanceof Boolean) {
+ sb.append(" <value><boolean>");
+ sb.append(((Boolean)o).booleanValue() ? "1" : "0");
+ sb.append("</boolean></value>\n");
+
+ } else if (o instanceof Stream) {
+ try {
+ sb.append(" <value><base64>\n");
+ InputStream is = ((Stream)o).getInputStream();
+ byte[] buf = new byte[54];
+ while(true) {
+ int numread = is.read(buf, 0, 54);
+ if (numread == -1) break;
+ byte[] writebuf = buf;
+ if (numread < buf.length) {
+ writebuf = new byte[numread];
+ System.arraycopy(buf, 0, writebuf, 0, numread);
+ }
+ sb.append(" ");
+ sb.append(new String(Base64.encode(writebuf)));
+ sb.append("\n");
+ }
+ sb.append("\n </base64></value>\n");
+ } catch (IOException e) {
+ if (Log.on) Log.info(this, "caught IOException while attempting to send a ByteStream via XML-RPC");
+ if (Log.on) Log.info(this, e);
+ throw new JSExn("caught IOException while attempting to send a ByteStream via XML-RPC");
+ }
+
+ } else if (o instanceof String) {
+ sb.append(" <value><string>");
+ String s = (String)o;
+ if (s.indexOf('<') == -1 && s.indexOf('&') == -1) {
+ sb.append(s);
+ } else {
+ char[] cbuf = s.toCharArray();
+ int oldi = 0, i=0;
+ while(true) {
+ while(i < cbuf.length && cbuf[i] != '<' && cbuf[i] != '&') i++;
+ sb.append(cbuf, oldi, i - oldi);
+ if (i >= cbuf.length) break;
+ if (cbuf[i] == '<') sb.append("<");
+ else if (cbuf[i] == '&') sb.append("&");
+ i = oldi = i + 1;
+ if (i >= cbuf.length) break;
+ }
+ }
+ sb.append("</string></value>\n");
+
+ } else if (o instanceof JSDate) {
+ sb.append(" <value><dateTime.iso8601>");
+ java.util.Date d = new java.util.Date(((JSDate)o).getRawTime());
+ sb.append(d.getYear() + 1900);
+ if (d.getMonth() + 1 < 10) sb.append('0');
+ sb.append(d.getMonth() + 1);
+ if (d.getDate() < 10) sb.append('0');
+ sb.append(d.getDate());
+ sb.append('T');
+ if (d.getHours() < 10) sb.append('0');
+ sb.append(d.getHours());
+ sb.append(':');
+ if (d.getMinutes() < 10) sb.append('0');
+ sb.append(d.getMinutes());
+ sb.append(':');
+ if (d.getSeconds() < 10) sb.append('0');
+ sb.append(d.getSeconds());
+ sb.append("</dateTime.iso8601></value>\n");
+
+ } else if (o instanceof JSArray) {
+ if (tracker.get(o) != null) throw new JSExn("attempted to send multi-ref data structure via XML-RPC");
+ tracker.put(o, Boolean.TRUE);
+ sb.append(" <value><array><data>\n");
+ JSArray a = (JSArray)o;
+ for(int i=0; i<a.length(); i++) appendObject(a.elementAt(i), sb);
+ sb.append(" </data></array></value>\n");
+
+ } else if (o instanceof JS) {
+ if (tracker.get(o) != null) throw new JSExn("attempted to send multi-ref data structure via XML-RPC");
+ tracker.put(o, Boolean.TRUE);
+ JS j = (JS)o;
+ sb.append(" <value><struct>\n");
+ Enumeration e = j.keys();
+ while(e.hasMoreElements()) {
+ Object key = e.nextElement();
+ sb.append(" <member><name>" + key + "</name>\n");
+ appendObject(j.get(key), sb);
+ sb.append(" </member>\n");
+ }
+ sb.append(" </struct></value>\n");
+
+ } else {
+ throw new JSExn("attempt to send object of type " + o.getClass().getName() + " via XML-RPC");
+
+ }
+ }
+
+
+ // Call Sequence //////////////////////////////////////////////////////////////////////////
+
+ public final Object call(Object a0, Object a1, Object a2, Object[] rest, int nargs) throws JSExn {
+ JSArray args = new JSArray();
+ for(int i=0; i<nargs; i++) args.addElement(i==0?a0:i==1?a1:i==2?a2:rest[i-3]);
+ return call(args);
+ }
+
+ public final Object call(final JSArray args) throws JSExn {
+ try {
+ final JS.UnpauseCallback callback = JS.pause();
+ new java.lang.Thread() { public void run() { call(callback, args); } }.start();
+ return null; // doesn't matter since we paused
+ } catch (NotPauseableException npe) {
+ throw new JSExn("cannot invoke an XML-RPC call in the foreground thread");
+ }
+ }
+
+ final void call(final JS.UnpauseCallback callback, final JSArray args) {
+ try {
+ if (Log.rpc) Log.info(this, "call to " + url + " : " + method);
+ if (tracker == null) tracker = new Hash();
+ if (objects == null) objects = new Vec();
+ String request = buildRequest(args);
+ if (Log.rpc) Log.info(this, "send:\n" + request);
+ InputStream is = http.POST("text/xml", request);
+ BufferedReader br = new BufferedReader(new InputStreamReader(is));
+ try {
+ new Helper().parse(br);
+ final Object result = fault ? new JSExn(objects.elementAt(0)) : objects.size() == 0 ? null : objects.elementAt(0);
+ Scheduler.add(new Task() { public void perform() throws JSExn { callback.unpause(result); }});
+ } finally {
+ tracker.clear();
+ objects.setSize(0);
+ }
+ } catch (final JSExn e) {
+ final Exception e2 = e;
+ Scheduler.add(new Task() { public void perform() throws JSExn { callback.unpause(e2); }});
+ } catch (final IOException e) {
+ final Exception e2 = e;
+ Scheduler.add(new Task() { public void perform() throws JSExn { callback.unpause(new JSExn(e2)); }});
+ } catch (final XML.Exn e) {
+ final Exception e2 = e;
+ Scheduler.add(new Task() { public void perform() throws JSExn { callback.unpause(new JSExn(e2)); }});
+ }
+ }
+}
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.plat;
+
+import org.ibex.util.*;
+import java.io.*;
+import org.ibex.js.*;
+import java.awt.*;
+import java.awt.datatransfer.*;
+import java.awt.image.*;
+import java.awt.event.*;
+import org.ibex.graphics.*;
+import org.ibex.core.*;
+import org.ibex.net.*;
+
+/** Platform subclass for all VM's providing AWT 1.1 functionality */
+public class AWT extends JVM {
+
+ protected String getDescriptiveName() { return "Generic JDK 1.1+ with AWT"; }
+ protected PixelBuffer _createPixelBuffer(int w, int h, Surface owner) { return new AWTPixelBuffer(w, h); }
+ protected Picture _createPicture(JS r) { return new AWTPicture(r); }
+ protected int _getScreenWidth() { return Toolkit.getDefaultToolkit().getScreenSize().width; }
+ protected int _getScreenHeight() { return Toolkit.getDefaultToolkit().getScreenSize().height; }
+ protected Surface _createSurface(Box b, boolean framed) { return new AWTSurface(b, framed); }
+
+ protected void postInit() {
+ if (Log.on) Log.diag(Platform.class, " color depth = " +
+ Toolkit.getDefaultToolkit().getColorModel().getPixelSize() + "bpp");
+ }
+
+ protected void _criticalAbort(String message) {
+ if (Log.on) Log.info(this, message);
+ final Dialog d = new Dialog(new Frame(), "Ibex Cannot Continue");
+ d.setLayout(new BorderLayout());
+ TextArea ta = new TextArea("Ibex cannot continue because:\n\n" + message, 10, 80);
+ ta.setEditable(false);
+ d.add(ta, "Center");
+ Button b = new Button("OK");
+ b.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ d.dispose();
+ }
+ });
+ d.add(b, "South");
+ d.setModal(true);
+ d.pack();
+ d.show();
+ new Semaphore().block();
+ }
+
+ protected String _getClipBoard() {
+ Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard();
+ if (cb == null) return null;
+ Transferable clipdata = cb.getContents(null);
+ try { return (String)clipdata.getTransferData(DataFlavor.stringFlavor); } catch (Exception ex) { return null; }
+ }
+
+ protected void _setClipBoard(String s) {
+ Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
+ if (clipboard == null) return;
+ StringSelection clipString = new StringSelection(s);
+ clipboard.setContents(clipString, clipString);
+ }
+
+ /** some platforms (cough, cough, NetscapeVM) have totally broken modifier masks; they will need to override this */
+ protected static int modifiersToButtonNumber(int modifiers) {
+ if ((modifiers & InputEvent.BUTTON1_MASK) == InputEvent.BUTTON1_MASK) return 1;
+ if ((modifiers & InputEvent.BUTTON2_MASK) == InputEvent.BUTTON2_MASK) {
+ // ugh, MacOSX reports the right mouse button as BUTTON2_MASK...
+ if (System.getProperty("os.name", "").startsWith("Mac OS X")) return 2;
+ return 3;
+ }
+ if ((modifiers & InputEvent.BUTTON3_MASK) == InputEvent.BUTTON3_MASK) {
+ // ugh, MacOSX reports the right mouse button as BUTTON2_MASK...
+ if (System.getProperty("os.name", "").startsWith("Mac OS X")) return 3;
+ return 2;
+ }
+ return 0;
+ }
+
+ static class FileDialogHelper extends FileDialog implements WindowListener, ComponentListener {
+ Semaphore s;
+ public FileDialogHelper(String suggestedFileName, Semaphore s, boolean write) {
+ super(new Frame(), write ? "Save" : "Open", write ? FileDialog.SAVE : FileDialog.LOAD);
+ this.s = s;
+ addWindowListener(this);
+ addComponentListener(this);
+ if (suggestedFileName.indexOf(File.separatorChar) == -1) {
+ setFile(suggestedFileName);
+ } else {
+ setDirectory(suggestedFileName.substring(0, suggestedFileName.lastIndexOf(File.separatorChar)));
+ setFile(suggestedFileName.substring(suggestedFileName.lastIndexOf(File.separatorChar) + 1));
+ }
+ show();
+ }
+ public void windowActivated(WindowEvent e) { }
+ public void windowClosed(WindowEvent e) { s.release(); }
+ public void windowClosing(WindowEvent e) { }
+ public void windowDeactivated(WindowEvent e) { }
+ public void windowDeiconified(WindowEvent e) { }
+ public void windowIconified(WindowEvent e) { }
+ public void windowOpened(WindowEvent e) { }
+ public void componentHidden(ComponentEvent e) { s.release(); }
+ public void componentMoved(ComponentEvent e) { }
+ public void componentResized(ComponentEvent e) { }
+ public void componentShown(ComponentEvent e) { }
+ };
+
+ protected String _fileDialog(String suggestedFileName, boolean write) {
+ final Semaphore s = new Semaphore();
+ FileDialogHelper fd = new FileDialogHelper(suggestedFileName, s, write);
+ s.block();
+ return fd.getDirectory() == null ? null : (fd.getDirectory() + File.separatorChar + fd.getFile());
+ }
+
+
+ // Inner Classes /////////////////////////////////////////////////////////////////////////////////////
+
+ protected org.ibex.graphics.Font.Glyph _createGlyph(org.ibex.graphics.Font f, char c) { return new AWTGlyph(f, c); }
+ protected static class AWTGlyph extends org.ibex.graphics.Font.Glyph {
+ private Image i = null;
+ private static ColorModel cmodel = new DirectColorModel(32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000);
+
+ // this doesn't work on Win32 because the JVM is broken
+ /*
+ static final ColorModel cmodel = new ColorModel(8) {
+ public int getRed(int p) { return 0; }
+ public int getGreen(int p) { return 0; }
+ public int getBlue(int p) { return 0; }
+ public int getAlpha(int p) { return p & 0xFF; }
+ };
+ */
+
+ public AWTGlyph(org.ibex.graphics.Font f, char c) { super(f, c); }
+ Image getImage() {
+ if (i == null && isLoaded) {
+
+ int[] data2 = new int[data.length];
+ for(int i=0; i<data2.length; i++) data2[i] = ((data[i]) & 0xff) << 24;
+
+ MemoryImageSource mis = new MemoryImageSource(width, height, cmodel, data2, 0, width);
+ mis.setAnimated(true);
+ i = Toolkit.getDefaultToolkit().createImage(mis);
+ MediaTracker mediatracker = new MediaTracker(new Canvas());
+ mediatracker.addImage(i, 1);
+ try { mediatracker.waitForAll(); } catch (InterruptedException e) { }
+ mediatracker.removeImage(i);
+ synchronized(AWTPixelBuffer.class) {
+ if (AWTPixelBuffer.component == null) {
+ AWTPixelBuffer.component = new Frame();
+ AWTPixelBuffer.component.setVisible(false);
+ AWTPixelBuffer.component.addNotify();
+ }
+ }
+ data = null;
+ }
+ return i;
+ }
+ }
+
+ protected static class AWTPicture extends Picture {
+ public Image i = null;
+ private static ColorModel cmodel = new DirectColorModel(32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000);
+
+ boolean initialized = false;
+ public AWTPicture(JS r) { super(r); }
+ public void init() {
+ if (initialized) return;
+ initialized = true;
+ MemoryImageSource mis = new MemoryImageSource(width, height, cmodel, data, 0, width);
+ mis.setAnimated(true);
+ i = Toolkit.getDefaultToolkit().createImage(mis);
+ MediaTracker mediatracker = new MediaTracker(new Canvas());
+ mediatracker.addImage(i, 1);
+ try { mediatracker.waitForAll(); } catch (InterruptedException e) { }
+ mediatracker.removeImage(i);
+ synchronized(AWTPixelBuffer.class) {
+ if (AWTPixelBuffer.component == null) {
+ AWTPixelBuffer.component = new Frame();
+ AWTPixelBuffer.component.setVisible(false);
+ AWTPixelBuffer.component.addNotify();
+ }
+ }
+ }
+ }
+
+ protected static class AWTPixelBuffer extends PixelBuffer {
+
+ protected Image i = null;
+ protected Graphics g = null;
+
+ /** JDK1.1 platforms require that a component be associated with each off-screen buffer */
+ static Component component = null;
+
+ protected AWTPixelBuffer() { }
+ public AWTPixelBuffer(int w, int h) {
+ synchronized(AWTPixelBuffer.class) {
+ if (component == null) {
+ component = new Frame();
+ component.setVisible(false);
+ component.addNotify();
+ }
+ }
+ i = component.createImage(w, h);
+ g = i.getGraphics();
+ }
+
+ public int getHeight() { return i == null ? 0 : i.getHeight(null); }
+ public int getWidth() { return i == null ? 0 : i.getWidth(null); }
+
+ public void drawPicture(Picture source, int dx, int dy, int cx1, int cy1, int cx2, int cy2) {
+ ((AWTPicture)source).init();
+ g.setClip(cx1, cy1, cx2 - cx1, cy2 - cy1);
+ g.drawImage(((AWTPicture)source).i, dx, dy, null);
+ g.setClip(0, 0, i.getWidth(null), i.getHeight(null));
+ }
+
+ /** implemented with java.awt 1.1's setXORMode() */
+ public void drawGlyph(org.ibex.graphics.Font.Glyph source, int dx, int dy, int cx1, int cy1, int cx2, int cy2, int rgb) {
+
+ // XOR the target region
+ g.setXORMode(new java.awt.Color((rgb & 0x00ff0000) >> 16, (rgb & 0x0000ff00) >> 8, rgb & 0x000000ff));
+ g.setColor(new java.awt.Color(0x0, 0x0, 0x0));
+ g.fillRect(cx1, cy1, cx2 - cx1, cy2 - cy1);
+
+ // blacken the area we want the glyph to cover
+ g.setPaintMode();
+ g.setClip(cx1, cy1, cx2 - cx1, cy2 - cy1);
+ g.drawImage(((AWTGlyph)source).getImage(), dx, dy, null);
+ g.setClip(0, 0, i.getWidth(null), i.getHeight(null));
+
+ // XOR back, turning black into the chosen rgb color
+ g.setXORMode(new java.awt.Color((rgb & 0x00ff0000) >> 16, (rgb & 0x0000ff00) >> 8, rgb & 0x000000ff));
+ g.setColor(new java.awt.Color(0x0, 0x0, 0x0));
+ g.fillRect(cx1, cy1, cx2 - cx1, cy2 - cy1);
+
+ // restore the graphics context
+ g.setPaintMode();
+ }
+
+ // FIXME: try to use os acceleration
+ public void fillTrapezoid(int x1, int x2, int y1, int x3, int x4, int y2, int argb) {
+ g.setColor(new java.awt.Color((argb & 0x00FF0000) >> 16, (argb & 0x0000FF00) >> 8, (argb & 0x000000FF)));
+ if (x1 == x3 && x2 == x4) {
+ g.fillRect(x1, y1, x4 - x1, y2 - y1);
+ } else for(int y=y1; y<y2; y++) {
+ int _x1 = (int)Math.floor((y - y1) * (x3 - x1) / (y2 - y1) + x1);
+ int _y1 = (int)Math.floor(y);
+ int _x2 = (int)Math.ceil((y - y1) * (x4 - x2) / (y2 - y1) + x2);
+ int _y2 = (int)Math.floor(y) + 1;
+ if (_x1 > _x2) { int _x0 = _x1; _x1 = _x2; _x2 = _x0; }
+ g.fillRect(_x1, _y1, _x2 - _x1, _y2 - _y1);
+ }
+ }
+ }
+
+
+ protected static class AWTSurface extends Surface.DoubleBufferedSurface
+ implements MouseListener, MouseMotionListener, KeyListener, ComponentListener, WindowListener {
+
+ public void blit(PixelBuffer s, int sx, int sy, int dx, int dy, int dx2, int dy2) {
+ insets = (frame == null ? window : frame).getInsets();
+ window.getGraphics().drawImage(((AWTPixelBuffer)s).i,
+ dx + insets.left,
+ dy + insets.top,
+ dx2 + insets.left,
+ dy2 + insets.top,
+ sx, sy, sx + (dx2 - dx), sy + (dy2 - dy), null);
+ }
+
+ /** if (component instanceof Frame) then frame == window else frame == null */
+ Frame frame = null;
+ Window window = null;
+
+ /** our component's insets */
+ protected Insets insets = new Insets(0, 0, 0, 0);
+
+ /** some JDKs let us recycle a single Dimension object when calling getSize() */
+ Dimension singleSize = new Dimension();
+
+ public void toBack() { if (window != null) window.toBack(); }
+ public void toFront() { if (window != null) window.toFront(); }
+ public void setLocation() { window.setLocation(root.x, root.y); }
+ public void setTitleBarText(String s) { if (frame != null) frame.setTitle(s); }
+ public void setIcon(Picture i) { if (frame != null) frame.setIconImage(((AWTPicture)i).i); }
+ public void _setSize(int width, int height) { window.setSize(width + (insets.left + insets.right), height + (insets.top + insets.bottom)); }
+ public void setInvisible(boolean b) { window.setVisible(!b); }
+ protected void _setMinimized(boolean b) { if (Log.on) Log.info(this, "JDK 1.1 platforms cannot minimize or unminimize windows"); }
+ protected void _setMaximized(boolean b) {
+ if (!b) {
+ if (Log.on) Log.info(this, "JDK 1.1 platforms cannot unmaximize windows");
+ return;
+ }
+ window.setLocation(new Point(0, 0));
+ window.setSize(Toolkit.getDefaultToolkit().getScreenSize());
+ }
+
+ class InnerFrame extends Frame {
+ public InnerFrame() throws java.lang.UnsupportedOperationException { }
+ public Dimension getMinimumSize() {
+ return new Dimension(root == null ? 0 : root.minwidth, root == null ? 0 : root.minheight); }
+ public void update(Graphics gr) { paint(gr); }
+ public void paint(Graphics gr) {
+ Rectangle r = gr.getClipBounds();
+
+ // ugly hack for Java1.4 dynamicLayout on Win32 -- this catches expansions during smooth resize
+ int newwidth = Math.max(r.x - insets.left + r.width, root.width);
+ int newheight = Math.max(r.y - insets.top + r.height, root.height);
+ if (newwidth > root.width || newheight > root.height)
+ componentResized(window.getWidth() - insets.left - insets.right,
+ window.getHeight() - insets.top - insets.bottom);
+
+ Dirty(r.x - insets.left, r.y - insets.top, r.width, r.height);
+ }
+ }
+
+ class InnerWindow extends Window {
+ public InnerWindow() throws java.lang.UnsupportedOperationException { super(new Frame()); }
+ public Dimension getMinimumSize() {
+ return new Dimension(root == null ? 0 : root.minwidth, root == null ? 0 : root.minheight); }
+ public void update(Graphics gr) { paint(gr); }
+ public void paint(Graphics gr) {
+ Rectangle r = gr.getClipBounds();
+ Dirty(r.x - insets.left, r.y - insets.top, r.width, r.height);
+ }
+ }
+
+ public void setMinimumSize(int minx, int miny, boolean resizable) { if (frame != null) frame.setResizable(resizable); }
+
+ private int oldfill = 0x0;
+ public void render() {
+ // useful optimizatin;
+ if (oldfill != root.fillcolor) {
+ oldfill = root.fillcolor;
+ window.setBackground((root.fillcolor & 0xFF000000) == 0 ?
+ java.awt.Color.white :
+ new java.awt.Color((root.fillcolor >> 16) & 0xff,
+ (root.fillcolor >> 8) & 0xff,
+ (root.fillcolor) & 0xff));
+ }
+ super.render();
+ }
+
+ AWTSurface(Box root, boolean framed) {
+ super(root);
+ try {
+ if (framed) window = frame = new InnerFrame();
+ else window = new InnerWindow();
+
+ // this is here to catch HeadlessException on jdk1.4
+ } catch (java.lang.UnsupportedOperationException e) {
+ if (Log.on) Log.info(this, "Exception thrown in AWTSurface$InnerFrame() -- this should never happen");
+ if (Log.on) Log.info(this, e);
+ }
+
+ insets = window.getInsets();
+
+ window.addMouseListener(this);
+ window.addKeyListener(this);
+ window.addComponentListener(this);
+ window.addMouseMotionListener(this);
+ window.addWindowListener(this);
+
+ // IMPORTANT: this must be called before render() to ensure
+ // that our peer has been created
+ makeVisible();
+ }
+
+ protected void makeVisible() { window.setVisible(true); }
+
+ public void _dispose() {
+ window.removeMouseListener(this);
+
+ // removed to work around a jdk1.3 bug
+ /* window.removeKeyListener(this); */
+
+ window.removeComponentListener(this);
+ window.removeMouseMotionListener(this);
+ window.removeWindowListener(this);
+ window.dispose();
+ }
+
+ public void syncCursor() {
+ if (cursor.equals("crosshair")) window.setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
+ else if (cursor.equals("east")) window.setCursor(Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR));
+ else if (cursor.equals("move")) window.setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
+ else if (cursor.equals("north")) window.setCursor(Cursor.getPredefinedCursor(Cursor.N_RESIZE_CURSOR));
+ else if (cursor.equals("northeast")) window.setCursor(Cursor.getPredefinedCursor(Cursor.NE_RESIZE_CURSOR));
+ else if (cursor.equals("northwest")) window.setCursor(Cursor.getPredefinedCursor(Cursor.NW_RESIZE_CURSOR));
+ else if (cursor.equals("south")) window.setCursor(Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR));
+ else if (cursor.equals("southeast")) window.setCursor(Cursor.getPredefinedCursor(Cursor.SE_RESIZE_CURSOR));
+ else if (cursor.equals("southwest")) window.setCursor(Cursor.getPredefinedCursor(Cursor.SW_RESIZE_CURSOR));
+ else if (cursor.equals("text")) window.setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR));
+ else if (cursor.equals("west")) window.setCursor(Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR));
+ else if (cursor.equals("wait")) window.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
+ else if (cursor.equals("hand")) window.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
+ else window.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
+ }
+
+ // AWT Message translation ////////////////////////////////////////////////////////////////
+
+ // these functions are all executed in the AWT thread, not the
+ // MessageQueue thread. As a result, they must be *extremely*
+ // careful about invoking methods on instances of Box. Currently,
+ // they should only enqueue messages, use Box.whoIs()
+ // (unsynchronized but thought to be safe), and modify members of
+ // Surface.
+
+ public void componentHidden(ComponentEvent e) { }
+ public void componentShown(ComponentEvent e) { }
+ public void windowOpened(WindowEvent e) { }
+ public void windowClosed(WindowEvent e) { }
+ public void windowClosing(WindowEvent e) { Close(); }
+ public void windowIconified(WindowEvent e) { Minimized(true); }
+ public void windowDeiconified(WindowEvent e) { dirty(0, 0, root.width, root.height); Minimized(false); }
+ public void windowActivated(WindowEvent e) { Focused(true); }
+ public void windowDeactivated(WindowEvent e) { Focused(false); }
+ public void componentMoved(ComponentEvent e) { PosChange(window.getLocation().x + insets.left, window.getLocation().y + insets.top); }
+
+ public void componentResized(ComponentEvent e) {
+ // we have to periodically do this; I don't know why
+ insets = window.getInsets();
+ componentResized(window.getWidth() - insets.left - insets.right, window.getHeight() - insets.top - insets.bottom);
+ }
+
+ public void componentResized(int newwidth, int newheight) { SizeChange(newwidth, newheight); }
+
+ public void keyTyped(KeyEvent k) { }
+ public void keyPressed(KeyEvent k) { KeyPressed(translateKey(k)); }
+ public void keyReleased(KeyEvent k) { KeyReleased(translateKey(k)); }
+ public void mouseExited(MouseEvent m) { mouseMoved(m); }
+ public void mouseEntered(MouseEvent m) { mouseMoved(m); }
+ public void mouseDragged(MouseEvent m) { mouseMoved(m); }
+ public void mouseMoved(MouseEvent m) {
+
+ // ugly hack for Java1.4 dynamicLayout on Win32 -- this catches contractions during smooth resize
+ int newwidth = window.getWidth() - insets.left - insets.right;
+ int newheight = window.getHeight() - insets.top - insets.bottom;
+ if (newwidth != root.width || newheight != root.height) componentResized(newwidth, newheight);
+
+ Move(m.getX() - insets.left, m.getY() - insets.top);
+ }
+ public void mousePressed(MouseEvent m) { Press(modifiersToButtonNumber(m.getModifiers())); }
+ public void mouseReleased(MouseEvent m) { Release(modifiersToButtonNumber(m.getModifiers())); }
+ public void mouseClicked(MouseEvent m) {
+ if (m.getClickCount() == 2) DoubleClick(modifiersToButtonNumber(m.getModifiers()));
+ else Click(modifiersToButtonNumber(m.getModifiers()));
+ }
+
+ String translateKey(KeyEvent k) {
+ switch (k.getKeyCode()) {
+ case KeyEvent.VK_ALT: return "alt";
+ case KeyEvent.VK_BACK_SPACE: return "back_space";
+ case KeyEvent.VK_CONTROL: return "control";
+ case KeyEvent.VK_DELETE: return "delete";
+ case KeyEvent.VK_DOWN: return "down";
+ case KeyEvent.VK_END: return "end";
+ case KeyEvent.VK_ENTER: return "enter";
+ case KeyEvent.VK_ESCAPE: return "escape";
+ case KeyEvent.VK_F1: return "f1";
+ case KeyEvent.VK_F10: return "f10";
+ case KeyEvent.VK_F11: return "f11";
+ case KeyEvent.VK_F12: return "f12";
+ case KeyEvent.VK_F2: return "f2";
+ case KeyEvent.VK_F3: return "f3";
+ case KeyEvent.VK_F4: return "f4";
+ case KeyEvent.VK_F5: return "f5";
+ case KeyEvent.VK_F6: return "f6";
+ case KeyEvent.VK_F7: return "f7";
+ case KeyEvent.VK_F8: return "f8";
+ case KeyEvent.VK_F9: return "f9";
+ case KeyEvent.VK_HOME: return "home";
+ case KeyEvent.VK_INSERT: return "insert";
+ case KeyEvent.VK_LEFT: return "left";
+ case KeyEvent.VK_META: return "alt";
+ case KeyEvent.VK_PAGE_DOWN: return "page_down";
+ case KeyEvent.VK_PAGE_UP: return "page_up";
+ case KeyEvent.VK_PAUSE: return "pause";
+ case KeyEvent.VK_PRINTSCREEN: return "printscreen";
+ case KeyEvent.VK_RIGHT: return "right";
+ case KeyEvent.VK_SHIFT: return "shift";
+ case KeyEvent.VK_TAB: return "tab";
+ case KeyEvent.VK_UP: return "up";
+ default:
+ char c = k.getKeyChar();
+ if (c >= 1 && c <= 26) c = (char)('a' + c - 1);
+ return String.valueOf(c);
+ }
+ }
+ }
+
+ protected void _decodeJPEG(InputStream is, Picture p) {
+ try {
+ Image i = Toolkit.getDefaultToolkit().createImage(InputStreamToByteArray.convert(is));
+ MediaTracker mediatracker = new MediaTracker(new Canvas());
+ mediatracker.addImage(i, 1);
+ try { mediatracker.waitForAll(); } catch (InterruptedException e) { }
+ mediatracker.removeImage(i);
+ final int width = i.getWidth(null);
+ final int height = i.getHeight(null);
+ final int[] data = new int[width * height];
+ PixelGrabber pg = new PixelGrabber(i, 0, 0, width, height, data, 0, width);
+ pg.grabPixels();
+ if ((pg.getStatus() & ImageObserver.ABORT) != 0)
+ Log.info(this, "PixelGrabber reported an error while decoding JPEG image");
+ p.width = width;
+ p.height = height;
+ p.data = data;
+ } catch (Exception e) {
+ Log.info(this, "Exception caught while decoding JPEG image");
+ Log.info(this, e);
+ }
+ }
+}
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.plat;
+
+import org.ibex.graphics.*;
+import org.ibex.core.*;
+import org.ibex.net.*;
+
+/** common superclass for all platforms that run in a "real" JVM */
+public abstract class JVM extends Platform {
+
+}
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.plat;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.awt.image.*;
+import java.net.*;
+import java.util.*;
+import org.ibex.util.*;
+import java.lang.reflect.*;
+import org.ibex.graphics.*;
+import org.ibex.core.*;
+import org.ibex.net.*;
+
+/** Platform class for most reasonable Java1.2+ Java2s */
+public class Java2 extends AWT {
+
+ private boolean isJava14 = false;
+
+ public Java2() {
+ // disable the focus manager so we can intercept the tab key
+ String versionString = System.getProperty("java.version", "");
+ int secondDecimal = versionString.substring(versionString.indexOf('.') + 1).indexOf('.');
+ if (secondDecimal != -1) versionString = versionString.substring(0, versionString.indexOf('.') + 1 + secondDecimal);
+ double version = Double.parseDouble(versionString);
+ if (version >= 1.4) {
+ isJava14 = true;
+ try {
+ Toolkit t = java.awt.Toolkit.getDefaultToolkit();
+ Method m = java.awt.Toolkit.class.getMethod("setDynamicLayout", new Class[] { Boolean.TYPE });
+ m.invoke(t, new Object[] { Boolean.TRUE });
+ } catch (Exception e) {
+ Log.info(this, "Exception while trying to enable AWT Dynamic Layout");
+ Log.info(this, e);
+ }
+ }
+ javax.swing.FocusManager.setCurrentManager(new javax.swing.FocusManager() {
+ public void processKeyEvent(Component focusedComponent, KeyEvent anEvent) { }
+ public void focusPreviousComponent(Component aComponent) { }
+ public void focusNextComponent(Component aComponent) { }
+ });
+ }
+
+ /** this is done with reflection in case a new version of the plugin comes out that doesn't let us pull the sun.plugin.* trick */
+ protected synchronized org.ibex.net.HTTP.Proxy _detectProxy() {
+ return (org.ibex.net.HTTP.Proxy)java.security.AccessController.doPrivileged(new java.security.PrivilegedAction() {
+ public Object run() {
+ try {
+ org.ibex.net.HTTP.Proxy pi = new org.ibex.net.HTTP.Proxy();
+
+ Class PluginProxyHandler = Class.forName("sun.plugin.protocol.PluginProxyHandler");
+ Method getDefaultProxyHandler = PluginProxyHandler.getMethod("getDefaultProxyHandler", new Class[] { });
+ Object proxyHandler = getDefaultProxyHandler.invoke(null, new Object[] { });
+
+ Class ProxyHandler = Class.forName("sun.plugin.protocol.ProxyHandler");
+ Method getProxyInfo = ProxyHandler.getMethod("getProxyInfo", new Class[] { URL.class });
+ Object proxyInfo = getProxyInfo.invoke(proxyHandler, new Object[] { new URL("http://www.ibex.org") });
+
+ Class ProxyInfo = Class.forName("sun.plugin.protocol.ProxyInfo");
+
+ if (((Boolean)ProxyInfo.getMethod("isSocksUsed", new Class[] { }).invoke(proxyInfo, new Object[] { })).booleanValue()) {
+ pi.socksProxyHost =
+ (String)ProxyInfo.getMethod("getSocksProxy", new Class[] { }).invoke(proxyInfo, new Object[] { });
+ pi.socksProxyPort =
+ ((Integer)ProxyInfo.getMethod("getSocksPort", new Class[] { }).invoke(proxyInfo, new Object[] { })).intValue();
+ }
+
+ if (((Boolean)ProxyInfo.getMethod("isProxyUsed", new Class[] { }).invoke(proxyInfo, new Object[] { })).booleanValue()) {
+ pi.httpProxyHost =
+ (String)ProxyInfo.getMethod("getProxy", new Class[] { }).invoke(proxyInfo, new Object[] { });
+ pi.httpProxyPort =
+ ((Integer)ProxyInfo.getMethod("getPort", new Class[] { }).invoke(proxyInfo, new Object[] { })).intValue();
+ }
+
+ if (pi.httpProxyHost != null || pi.socksProxyHost != null) return pi;
+ else return null;
+
+ } catch (Throwable e) {
+ if (Log.on) Log.info(this, "No proxy information found in Java Plugin classes");
+ return null;
+ }
+ }});
+ }
+
+ protected PixelBuffer _createPixelBuffer(int w, int h, Surface owner) { return new Java2PixelBuffer(w, h); }
+ protected Surface _createSurface(final Box root, final boolean framed) {
+ return (Surface)java.security.AccessController.doPrivileged(new java.security.PrivilegedAction() {
+ public Object run() {
+ if (isJava14) {
+ try {
+ // weaken the binding here to avoid link errors on 1.3.x
+ Class java14SurfaceClass = Class.forName(Java2.class.getName() + "$Java14Surface");
+ Constructor ctor = java14SurfaceClass.getConstructor(new Class[] { Box.class, Boolean.TYPE });
+ return (Surface)ctor.newInstance(new Object[] { root, Boolean.valueOf(framed) });
+ } catch (Exception e) {
+ Log.info(this, e);
+ throw new LinkageError("error: " + e);
+ }
+ } else {
+ return new Java2Surface(root, framed);
+ }
+ }
+ });
+ }
+
+ // Inner Classes //////////////////////////////////////////////////////////////////
+
+ private static Cursor invisibleCursor =
+ Toolkit.getDefaultToolkit().createCustomCursor(new BufferedImage(2, 2, BufferedImage.TYPE_INT_ARGB),
+ new Point(1, 1), "invisible");
+
+ protected static class Java2Surface extends AWTSurface {
+
+ public Java2Surface(Box root, boolean framed) { super(root, framed); }
+
+ protected void _setMinimized(boolean b) {
+ if (frame == null) Log.info(this, "JDK 1.2 can only minimize frames, not windows");
+ else if (b) frame.setState(java.awt.Frame.ICONIFIED);
+ else frame.setState(java.awt.Frame.NORMAL);
+ }
+
+ public void syncCursor() {
+ if (cursor.equals("invisible")) window.setCursor(invisibleCursor);
+ else super.syncCursor();
+ }
+ }
+
+ protected static class Java14Surface extends Java2Surface implements WindowStateListener, MouseWheelListener {
+ public Java14Surface(Box root, boolean framed) {
+ super(root, true);
+ // JDK1.4 doesn't like java.lang.Window's...
+ if (!framed) ((Frame)window).setUndecorated(true);
+ window.addWindowStateListener(this);
+ window.addMouseWheelListener(this);
+ window.setVisible(true);
+ }
+
+ protected void makeVisible() { }
+
+ protected void _setMaximized(boolean m) {
+ if (frame == null) {
+ if (Log.on) Log.info(this, "JDK 1.4 can only maximize frames, not windows");
+ return;
+ }
+ frame.setExtendedState(m ? Frame.MAXIMIZED_BOTH : (minimized ? Frame.ICONIFIED : Frame.NORMAL));
+ }
+ protected void _setMinimized(boolean m) {
+ if (frame == null) {
+ if (Log.on) Log.info(this, "JDK 1.4 can only minimize frames, not windows");
+ return;
+ }
+ frame.setExtendedState(m ? Frame.ICONIFIED : (maximized ? Frame.MAXIMIZED_BOTH : Frame.NORMAL));
+ }
+ public void windowStateChanged(WindowEvent e) {
+ if (e.getOldState() != e.getNewState()) {
+ if ((e.getNewState() & Frame.MAXIMIZED_BOTH) != 0) Maximized(true);
+ else if (((e.getOldState() & Frame.MAXIMIZED_BOTH) != 0) && (e.getNewState() & Frame.MAXIMIZED_BOTH) == 0)
+ Maximized(false);
+ }
+ }
+
+ public void mouseWheelMoved(MouseWheelEvent m) {
+ if (m.getScrollType() == MouseWheelEvent.WHEEL_UNIT_SCROLL)
+ VScroll(m.getUnitsToScroll());
+ }
+ }
+
+ protected static class Java2PixelBuffer extends AWTPixelBuffer {
+ private static ColorModel cm = Toolkit.getDefaultToolkit().getColorModel();
+ private static Hashtable emptyHashtable = new Hashtable();
+ private static short[] sbank = null;
+ private static int[] ibank = null;
+ private static byte[] bbank = null;
+ private static int bank_start = 0;
+ private WritableRaster raster = null;
+ private SampleModel sm = null;
+ private DataBuffer buf = null;
+
+ // this doens't seem to work on Windows
+ public void drawGlyph(org.ibex.graphics.Font.Glyph source, int dx, int dy, int cx1, int cy1, int cx2, int cy2, int rgb) {
+ Image i2 = ((AWTGlyph)source).getImage();
+ Graphics2D g2 = (Graphics2D)i.getGraphics();
+ g2.setComposite(AlphaComposite.DstOut);
+ g2.setClip(cx1, cy1, cx2 - cx1, cy2 - cy1);
+ g2.drawImage(i2, dx, dy, null);
+ g2.setComposite(AlphaComposite.DstOver);
+ g2.setColor(new java.awt.Color((rgb & 0x00FF0000) >> 16, (rgb & 0x0000FF00) >> 8, (rgb & 0x000000FF)));
+ g2.fillRect(dx, dy, cx2 - dx, cy2 - dy);
+ g2.drawImage(i2, 0, 0, null);
+ g2.setClip(0, 0, i.getWidth(null), i.getHeight(null));
+ }
+
+ public Java2PixelBuffer(int w, int h) {
+ sm = cm.createCompatibleSampleModel(w, h);
+ int numSamples = w * h * sm.getNumDataElements();
+ if (sm.getDataType() == DataBuffer.TYPE_USHORT) {
+ if (sbank == null || numSamples > 512 * 512 / 3) {
+ buf = new DataBufferUShort(numSamples);
+ } else {
+ if (numSamples > sbank.length - bank_start) {
+ bank_start = 0;
+ sbank = new short[512 * 512];
+ }
+ buf = new DataBufferUShort(sbank, numSamples, bank_start);
+ bank_start += numSamples;
+ }
+ } else if (sm.getDataType() == DataBuffer.TYPE_BYTE) {
+ if (bbank == null || numSamples > 512 * 512 / 3) {
+ buf = new DataBufferByte(numSamples);
+ } else {
+ if (numSamples > bbank.length - bank_start) {
+ bank_start = 0;
+ bbank = new byte[512 * 512];
+ }
+ buf = new DataBufferByte(bbank, numSamples, bank_start);
+ bank_start += numSamples;
+ }
+ } else if (sm.getDataType() == DataBuffer.TYPE_INT) {
+ if (ibank == null || numSamples > 512 * 512 / 3) {
+ buf = new DataBufferInt(numSamples);
+ } else {
+ if (numSamples > ibank.length - bank_start) {
+ bank_start = 0;
+ ibank = new int[512 * 512];
+ }
+ buf = new DataBufferInt(ibank, numSamples, bank_start);
+ bank_start += numSamples;
+ }
+ }
+ raster = Raster.createWritableRaster(sm, buf, null);
+ i = new BufferedImage(cm, raster, false, emptyHashtable);
+ g = i.getGraphics();
+ }
+ }
+
+ protected String getDescriptiveName() { return isJava14 ? "Java 1.4+ JVM" : "Java 1.2+ JVM"; }
+
+}
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.plat;
+
+import java.lang.reflect.*;
+import java.net.*;
+import java.io.*;
+import org.ibex.js.*;
+import org.ibex.util.*;
+import org.ibex.graphics.*;
+import org.ibex.core.*;
+import org.ibex.graphics.*;
+import org.ibex.core.*;
+import org.ibex.net.*;
+
+/**
+ * Abstracts away the small irregularities in JVM implementations.
+ *
+ * The default Platform class supports a vanilla JDK 1.1
+ * JVM. Subclasses are provided for other VMs. Methods whose names
+ * start with an underscore are meant to be overridden by
+ * subclasses. If you create a subclass of Platform, you should put
+ * it in the org.ibex.plat package, and add code to this file's static
+ * block to detect the new platform.
+ */
+public abstract class Platform {
+
+ public Platform() { platform = this; }
+
+ // Static Data /////////////////////////////////////////////////////////////////////////////////////
+
+ public static boolean clipboardReadEnabled = false; ///< true iff inside a C-v/A-v/Press3 trap handler
+ public static Platform platform = null; ///< The appropriate Platform object for this JVM
+ public static boolean alreadyDetectedProxy = false; ///< true if proxy autodetection has already been run
+ public static org.ibex.net.HTTP.Proxy cachedProxyInfo = null; ///< the result of proxy autodetection
+ public static String build = "unknown"; ///< the current build
+
+ // VM Detection Logic /////////////////////////////////////////////////////////////////////
+
+ // If you create a new subclass of Platform, you should add logic
+ // here to detect it. Do not reference your class directly -- use
+ // reflection.
+
+ public static void forceLoad() {
+ System.err.print("Detecting JVM...");
+ try {
+ String vendor = System.getProperty("java.vendor", "");
+ String version = System.getProperty("java.version", "");
+ String os_name = System.getProperty("os.name", "");
+ String os_version = System.getProperty("os.version", "");
+ String platform_class = null;
+
+ if (vendor.startsWith("Free Software Foundation")) {
+ if (os_name.startsWith("Window")) platform_class = "Win32";
+ else if (os_name.startsWith("Linux")) platform_class = "Linux";
+ else if (os_name.startsWith("SunOS")) platform_class = "Solaris";
+ else if (os_name.startsWith("Solaris")) platform_class = "Solaris";
+ else if (os_name.startsWith("Darwin")) platform_class = "Darwin";
+ else platform_class = "X11";
+ }
+ else if (!version.startsWith("1.0") && !version.startsWith("1.1")) platform_class = "Java2";
+
+ if (platform_class == null) {
+ Log.error(Platform.class, "Unable to detect JVM");
+ criticalAbort("Unable to detect JVM");
+ }
+
+ System.err.println(" " + os_name + " ==> org.ibex.plat." + platform_class);
+ try {
+ if (platform_class != null) Class.forName("org.ibex.plat." + platform_class).newInstance();
+ } catch (InstantiationException e) {
+ throw e.getCause();
+ }
+
+ String term = Platform.getEnv("TERM");
+ Log.color = term != null && term.length() != 0 && !term.equals("cygwin");
+
+ try {
+ build = (String)Class.forName("org.ibex.Build").getField("build").get(null);
+ Log.diag(Platform.class, "Ibex build: " + build);
+ } catch (ClassNotFoundException cnfe) {
+ Log.warn(Platform.class, "Ibex build: unknown");
+ } catch (Exception e) {
+ Log.info(Platform.class, "exception while detecting build:");
+ Log.info(Platform.class, e);
+ }
+
+ Log.diag(Platform.class, "Ibex VM detection: vendor = " + vendor);
+ Log.diag(Platform.class, " version = " + version);
+ Log.diag(Platform.class, " os = " + os_name + " [version " + os_version + "]");
+ Log.diag(Platform.class, " platform = " + platform.getDescriptiveName());
+ Log.diag(Platform.class, " class = " + platform.getClass().getName());
+ platform.postInit();
+
+ } catch (Throwable e) {
+ Log.error(Platform.class, "Exception while trying to detect JVM");
+ Log.error(Platform.class, e);
+ criticalAbort("Unable to detect JVM");
+ }
+
+ }
+
+
+ // Methods to be Overridden ///////////////////////////////////////////////////////////////////
+
+ protected Surface _createSurface(Box b, boolean framed) { return null; }
+ protected Picture _createPicture(JS r) { return null; }
+ protected PixelBuffer _createPixelBuffer(int w, int h, Surface owner) { return null; }
+ protected Font.Glyph _createGlyph(org.ibex.graphics.Font f, char c) { return new DefaultGlyph(f, c); }
+
+ public static PixelBuffer createPixelBuffer(int w, int h, Surface s) { return platform._createPixelBuffer(w, h, s); }
+ public static Picture createPicture(JS r) { return platform._createPicture(r); }
+ public static Font.Glyph createGlyph(org.ibex.graphics.Font f, char c) { return platform._createGlyph(f, c); }
+ public static Surface createSurface(Box b, boolean framed, boolean refreshable) {
+ Surface ret = platform._createSurface(b, framed);
+ ret.setInvisible(false);
+ if (refreshable) {
+ Surface.allSurfaces.addElement(ret);
+ ret.dirty(0, 0, b.width, b.height);
+ ret.Refresh();
+ }
+ try {
+ if (b.get("titlebar") != null) ret.setTitleBarText((String)b.get("titlebar"));
+ } catch (JSExn e) {
+ Log.warn(Platform.class, e);
+ }
+ return ret;
+ }
+
+ /** a string describing the VM */
+ protected String getDescriptiveName() { return "Generic Java 1.1 VM"; }
+
+ /** invoked after initialization messages have been printed; useful for additional platform detection log messages */
+ protected void postInit() { }
+
+ /** the human-readable name of the key mapped to Ibex's 'alt' key */
+ public static String altKeyName() { return platform._altKeyName(); }
+ protected String _altKeyName() { return "alt"; }
+
+ /** returns the contents of the clipboard */
+ public static Object getClipBoard() { return clipboardReadEnabled ? platform._getClipBoard() : null; }
+ protected String _getClipBoard() { return null; }
+
+ /** sets the contents of the clipboard */
+ public static void setClipBoard(String s) { platform._setClipBoard(s); }
+ protected void _setClipBoard(String s) { }
+
+ /** returns the width of the screen, in pixels */
+ public static int getScreenWidth() { return platform._getScreenWidth(); }
+ protected int _getScreenWidth() { return 640; }
+
+ /** returns the height of the screen, in pixels */
+ public static int getScreenHeight() { return platform._getScreenHeight(); }
+ protected int _getScreenHeight() { return 480; }
+
+ /** used to notify the user of very serious failures; usually used when logging is not working or unavailable */
+ protected void _criticalAbort(String message) { System.exit(-1); }
+ public static void criticalAbort(String message) {
+ Log.info(Platform.class, "Critical Abort:");
+ Log.info(Platform.class, message);
+ platform._criticalAbort(message);
+ }
+
+ /** if true, org.ibex.Surface will generate a Click automatically after a press and a release */
+ public static boolean needsAutoClick() { return platform._needsAutoClick(); }
+ protected boolean _needsAutoClick() { return false; }
+
+ /** if true, org.ibex.Surface will generate a DoubleClick automatically after recieving two clicks in a short period of time */
+ public static boolean needsAutoDoubleClick() { return platform._needsAutoDoubleClick(); }
+ protected boolean _needsAutoDoubleClick() { return false; }
+
+ /** returns true iff the platform has a case-sensitive filesystem */
+ public static boolean isCaseSensitive() { return platform._isCaseSensitive(); }
+ protected boolean _isCaseSensitive() { return true; }
+
+ /** returns an InputStream to the builtin xwar */
+ public static InputStream getBuiltinInputStream() { return platform._getBuiltinInputStream(); }
+ protected InputStream _getBuiltinInputStream() {return getClass().getClassLoader().getResourceAsStream("org/ibex/builtin.jar");}
+
+ /** returns the value of the environment variable key, or null if no such key exists */
+ public static String getEnv(String key) { return platform._getEnv(key); }
+ protected String _getEnv(String key) {
+ try {
+ String os = System.getProperty("os.name").toLowerCase();
+ Process p;
+ if (os.indexOf("windows 9") != -1 || os.indexOf("windows me") != -1) {
+ // hack -- jdk1.2/1.3 on Win32 pop open an ugly DOS box; 1.4 does not
+ if (platform.getClass().getName().endsWith("Java12")) return null;
+ p = Runtime.getRuntime().exec("command.com /c set");
+ } else if (os.indexOf("windows") > -1) {
+ // hack -- jdk1.2/1.3 on Win32 pop open an ugly DOS box; 1.4 does not
+ if (platform.getClass().getName().endsWith("Java12")) return null;
+ p = Runtime.getRuntime().exec("cmd.exe /c set");
+ } else {
+ p = Runtime.getRuntime().exec("env");
+ }
+ BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
+ String s;
+ while ((s = br.readLine()) != null)
+ if (s.startsWith(key + "="))
+ return s.substring(key.length() + 1);
+ } catch (Exception e) {
+ Log.info(this, "Exception while reading from environment:");
+ Log.info(this, e);
+ }
+ return null;
+ }
+
+ /** convert a JPEG into an Image */
+ public static synchronized void decodeJPEG(InputStream is, Picture p) { platform._decodeJPEG(is, p); }
+ protected abstract void _decodeJPEG(InputStream is, Picture p);
+
+ /** displays a platform-specific "open file" dialog and returns the chosen filename, or null if the user hit cancel */
+ protected String _fileDialog(String suggestedFileName, boolean write) { return null; }
+ public static String fileDialog(String suggestedFileName, boolean write) throws org.ibex.js.JSExn {
+ return platform._fileDialog(suggestedFileName, write);
+ }
+
+ /** default implementation is Eric Albert's BrowserLauncher.java */
+ protected void _newBrowserWindow(String url) {
+ try {
+ Class c = Class.forName("edu.stanford.ejalbert.BrowserLauncher");
+ Method m = c.getMethod("openURL", new Class[] { String.class });
+ m.invoke(null, new String[] { url });
+ } catch (Exception e) {
+ Log.warn(this, "exception trying to open a browser window");
+ Log.warn(this, e);
+ }
+ }
+
+ /** opens a new browser window */
+ public static void newBrowserWindow(String url) {
+ if (!(url.startsWith("https://") || url.startsWith("http://") || url.startsWith("ftp://") || url.startsWith("mailto:"))) {
+ Log.info(Platform.class, "ibex.newBrowserWindow() only supports http and https urls");
+ return;
+ }
+ // check the URL for well-formedness, as a defense against buffer overflow attacks
+ // FIXME check URL without using URL class
+ /*
+ try {
+ String u = url;
+ if (u.startsWith("https")) u = "http" + u.substring(5);
+ new URL(u);
+ } catch (MalformedURLException e) {
+ Log.info(Platform.class, "URL " + url + " is not well-formed");
+ Log.info(Platform.class, e);
+ }
+ */
+ Log.info(Platform.class, "newBrowserWindow, url = " + url);
+ platform._newBrowserWindow(url);
+ }
+
+ /** detects proxy settings */
+ protected synchronized org.ibex.net.HTTP.Proxy _detectProxy() { return null; }
+ public static synchronized org.ibex.net.HTTP.Proxy detectProxy() {
+
+ if (cachedProxyInfo != null) return cachedProxyInfo;
+ if (alreadyDetectedProxy) return null;
+ alreadyDetectedProxy = true;
+
+ Log.info(Platform.class, "attempting environment-variable DNS proxy detection");
+ cachedProxyInfo = org.ibex.net.HTTP.Proxy.detectProxyViaManual();
+ if (cachedProxyInfo != null) return cachedProxyInfo;
+
+ Log.info(Platform.class, "attempting " + platform.getClass().getName() + " proxy detection");
+ cachedProxyInfo = platform._detectProxy();
+ if (cachedProxyInfo != null) return cachedProxyInfo;
+
+ return cachedProxyInfo;
+ }
+
+ /** returns a Scheduler instance; used to implement platform-specific schedulers */
+ protected Scheduler _getScheduler() { return new Scheduler(); }
+ public static Scheduler getScheduler() { return platform._getScheduler(); }
+
+ // FEATURE: be more efficient for many of the subclasses
+ public static class DefaultGlyph extends Font.Glyph {
+ private Picture p = null;
+ public DefaultGlyph(org.ibex.graphics.Font f, char c) { super(f, c); }
+ public Picture getPicture() {
+ if (p == null && isLoaded) {
+ Picture p = createPicture(null);
+ p.data = new int[data.length];
+ for(int i=0; i<data.length; i++) p.data[i] = (data[i] & 0xff) << 24;
+ this.data = null;
+ p.width = this.width;
+ p.height = this.height;
+ p.isLoaded = true;
+ this.p = p;
+ }
+ return p;
+ }
+ }
+}
+
+
--- /dev/null
+package org.ibex.util;
+
+import java.io.*;
+
+public class AccessibleCharArrayWriter extends CharArrayWriter {
+ public char[] getBuf() { return buf; }
+ public AccessibleCharArrayWriter(int i) { super(i); }
+}
+
--- /dev/null
+// Copyright (C) 2003 Adam Megacz <adam@ibex.org> all rights reserved.
+//
+// You may modify, copy, and redistribute this code under the terms of
+// the GNU Library Public License version 2.1, with the exception of
+// the portion of clause 6a after the semicolon (aka the "obnoxious
+// relink clause")
+
+package org.ibex.util;
+
+// FEATURE: private void intersection() { }
+// FEATURE: private void union() { }
+// FEATURE: private void subset() { }
+// FEATURE: grow if we run out of slots
+
+/** a weight-balanced tree with fake leaves */
+public class BalancedTree {
+
+
+ // Instance Variables ///////////////////////////////////////////////////////////////////
+
+ private int root = 0; ///< the slot of the root element
+
+ private int cached_index = -1;
+ private int cached_slot = -1;
+
+ // Public API //////////////////////////////////////////////////////////////////////////
+
+ /** the number of elements in the tree */
+ public final int treeSize() {
+ synchronized(BalancedTree.class) {
+ return root == 0 ? 0 : size[root];
+ }
+ }
+
+ /** clamps index to [0..treeSize()] and inserts object o *before* the specified index */
+ public final void insertNode(int index, Object o) {
+ synchronized(BalancedTree.class) {
+ if(o == null) throw new Error("can't insert nulls in the balanced tree");
+ cached_slot = cached_index = -1;
+ if (index < 0) index = 0;
+ if (index > treeSize()) index = treeSize();
+ int arg = allocateSlot(o);
+ if (root != 0) {
+ insert(index, arg, root, 0, false, false);
+ } else {
+ root = arg;
+ left[arg] = right[arg] = parent[arg] = 0;
+ size[arg] = 1;
+ }
+ }
+ }
+
+ /** clamps index to [0..treeSize()-1] and replaces the object at that index with object o */
+ public final void replaceNode(int index, Object o) {
+ synchronized(BalancedTree.class) {
+ if(o == null) throw new Error("can't insert nulls in the balanced tree");
+ cached_slot = cached_index = -1;
+ if(root == 0) throw new Error("called replaceNode() on an empty tree");
+ if (index < 0) index = 0;
+ if (index >= treeSize()) index = treeSize() - 1;
+ int arg = allocateSlot(o);
+ insert(index, arg, root, 0, true, false);
+ }
+ }
+
+ /** returns the index of o; runs in O((log n)^2) time unless cache hit */
+ public final int indexNode(Object o) {
+ synchronized(BalancedTree.class) {
+ if(o == null) return -1;
+ if (cached_slot != -1 && objects[cached_slot] == o) return cached_index;
+
+ int slot = getSlot(o);
+ if(slot == -1) return -1;
+
+ int index = 0;
+ while(true) {
+ // everything to the left is before us so add that to the index
+ index += sizeof(left[slot]);
+ // we are before anything on the right
+ while(left[parent[slot]] == slot) slot = parent[slot];
+ // we end of the first node who isn't on the left, go to the node that has as its child
+ slot = parent[slot];
+ // if we just processed the root we're done
+ if(slot == 0) break;
+ // count the node we're currently on towards the index
+ index++;
+ }
+ return index;
+ }
+ }
+
+ /** returns the object at index; runs in O(log n) time unless cache hit */
+ public final Object getNode(int index) {
+ synchronized(BalancedTree.class) {
+ if (index == cached_index) return objects[cached_slot];
+
+ if (cached_index != -1) {
+ int distance = Math.abs(index - cached_index);
+ // if the in-order distance between the cached node and the
+ // target node is less than log(n), it's probably faster to
+ // search directly.
+ if ((distance < 16) && ((2 << distance) < treeSize())) {
+ while(cached_index > index) { cached_slot = prev(cached_slot); cached_index--; }
+ while(cached_index < index) { cached_slot = next(cached_slot); cached_index++; }
+ return objects[cached_slot];
+ }
+ }
+ /*
+ cached_index = index;
+ cached_slot = get(index, root);
+ return objects[cached_slot];
+ */
+ return objects[get(index, root)];
+ }
+ }
+
+ /** deletes the object at index, returning the deleted object */
+ public final Object deleteNode(int index) {
+ synchronized(BalancedTree.class) {
+ cached_slot = cached_index = -1;
+ // FIXME: left[], right[], size[], and parent[] aren't getting cleared properly somewhere in here where a node had two children
+ int del = delete(index, root, 0);
+ left[del] = right[del] = size[del] = parent[del] = 0;
+ Object ret = objects[del];
+ objects[del] = null;
+ return ret;
+ }
+ }
+
+ public final void clear() {
+ synchronized(BalancedTree.class) {
+ if(root == 0) return;
+ int i = leftmost(root);
+ do {
+ int next = next(i);
+ objects[i] = null;
+ left[i] = right[i] = size[i] = parent[i] = 0;
+ i = next;
+ } while(i != 0);
+ root = 0;
+ }
+ }
+
+ protected void finalize() { clear(); }
+
+
+ // Node Data /////////////////////////////////////////////////////////////////////////
+
+ private final static int NUM_SLOTS = 64 * 1024;
+ // FEATURE: GROW - private final static int MAX_SLOT_DISTANCE = 32;
+
+ /**
+ * Every object inserted into *any* tree gets a "slot" in this
+ * array. The slot is determined by hashcode modulo the length of
+ * the array, with quadradic probing to resolve collisions. NOTE
+ * that the "slot" of a node is NOT the same as its index.
+ * Furthermore, if an object is inserted into multiple trees, that
+ * object will have multiple slots.
+ */
+ private static Object[] objects = new Object[NUM_SLOTS];
+
+ /// These two arrays hold the left and right children of each
+ /// slot; in other words, left[x] is the *slot* of the left child
+ /// of the node in slot x.
+ ///
+ /// If x has no left child, then left[x] is -1 multiplied by the
+ /// slot of the node that precedes x; if x is the first node, then
+ /// left[x] is 0. The right[] array works the same way.
+ ///
+ private static int[] left = new int[NUM_SLOTS];
+ private static int[] right = new int[NUM_SLOTS];
+
+ /// The parent of this node (0 if it is the root node)
+ private static int[] parent = new int[NUM_SLOTS];
+
+ ///< the number of descendants of this node *including the node itself*
+ private static int[] size = new int[NUM_SLOTS];
+
+
+ // Slot Management //////////////////////////////////////////////////////////////////////
+
+ /** if alloc == false returns the slot holding object o. if alloc is true returns a new slot for obejct o */
+ private int getSlot(Object o, boolean alloc) {
+ // we XOR with our own hashcode so that we don't get tons of
+ // collisions when a single Object is inserted into multiple
+ // trees
+ int dest = Math.abs(o.hashCode() ^ this.hashCode()) % objects.length;
+ Object search = alloc ? null : o;
+ int odest = dest;
+ boolean plus = true;
+ int tries = 1;
+ if(dest == 0) dest=1;
+ while (objects[dest] != search || !(alloc || root(dest) == root)) {
+ dest = Math.abs((odest + (plus ? 1 : -1) * tries * tries) % objects.length);
+ if (dest == 0) dest=1;
+ if (plus) tries++;
+ plus = !plus;
+ // FEATURE: GROW - if(tries > MAX_SLOT_DISTANCE) return -1;
+ }
+ return dest;
+ }
+
+ /** returns the slots holding object o */
+ private int getSlot(Object o) { return getSlot(o,false); }
+
+ /** allocates a new slot holding object o*/
+ private int allocateSlot(Object o) {
+ int slot = getSlot(o, true);
+ // FEATURE: GROW - if(slot == -1) throw new Error("out of slots");
+ objects[slot] = o;
+ return slot;
+ }
+
+
+
+ // Helpers /////////////////////////////////////////////////////////////////////////
+
+ private final int leftmost(int slot) { return left[slot] <= 0 ? slot : leftmost(left[slot]); }
+ private final int rightmost(int slot) { return right[slot] <= 0 ? slot : rightmost(right[slot]); }
+ private final int next(int slot) { return right[slot] <= 0 ? -1 * right[slot] : leftmost(right[slot]); }
+ private final int prev(int slot) { return left[slot] <= 0 ? -1 * left[slot] : rightmost(left[slot]); }
+ private final int sizeof(int slot) { return slot <= 0 ? 0 : size[slot]; }
+ private final int root(int slot) { return parent[slot] == 0 ? slot : root(parent[slot]); }
+
+
+ // Rotation and Balancing /////////////////////////////////////////////////////////////
+
+ // p p
+ // | |
+ // b d
+ // / \ / \
+ // a d < == > b e
+ // / \ / \
+ // c e a c
+ // FIXME might be doing too much work here
+ private void rotate(boolean toTheLeft, int b, int p) {
+ int[] left = toTheLeft ? BalancedTree.left : BalancedTree.right;
+ int[] right = toTheLeft ? BalancedTree.right : BalancedTree.left;
+ int d = right[b];
+ int c = left[d];
+ if (d <= 0) throw new Error("rotation error");
+ left[d] = b;
+ right[b] = c <= 0 ? -d : c;
+
+ parent[b] = d;
+ parent[d] = p;
+ if(c > 0) parent[c] = b;
+ if (p == 0) root = d;
+ else if (left[p] == b) left[p] = d;
+ else if (right[p] == b) right[p] = d;
+ else throw new Error("rotate called with invalid parent");
+ size[b] = 1 + sizeof(left[b]) + sizeof(right[b]);
+ size[d] = 1 + sizeof(left[d]) + sizeof(right[d]);
+ }
+
+ private void balance(int slot, int p) {
+ if (slot <= 0) return;
+ size[slot] = 1 + sizeof(left[slot]) + sizeof(right[slot]);
+ if (sizeof(left[slot]) - 1 > 2 * sizeof(right[slot])) rotate(false, slot, p);
+ else if (sizeof(left[slot]) * 2 < sizeof(right[slot]) - 1) rotate(true, slot, p);
+ }
+
+
+
+ // Insert /////////////////////////////////////////////////////////////////////////
+
+ private void insert(int index, int arg, int slot, int p, boolean replace, boolean wentLeft) {
+ int diff = slot <= 0 ? 0 : index - sizeof(left[slot]);
+ if (slot > 0 && diff != 0) {
+ if (diff < 0) insert(index, arg, left[slot], slot, replace, true);
+ else insert(index - sizeof(left[slot]) - 1, arg, right[slot], slot, replace, false);
+ balance(slot, p);
+ return;
+ }
+
+ if (size[arg] != 0) throw new Error("double insertion");
+
+ // we are replacing an existing node
+ if (replace) {
+ if (diff != 0) throw new Error("this should never happen"); // since we already clamped the index
+ if (p == 0) root = arg;
+ else if (left[p] == slot) left[p] = arg;
+ else if (right[p] == slot) right[p] = arg;
+ left[arg] = left[slot];
+ right[arg] = right[slot];
+ size[arg] = size[slot];
+ parent[arg] = parent[slot];
+ if(left[slot] > 0) parent[left[slot]] = arg;
+ if(right[slot] > 0) parent[right[slot]] = arg;
+ objects[slot] = null;
+ left[slot] = right[slot] = size[slot] = parent[slot] = 0;
+
+ // we become the child of a former leaf
+ } else if (slot <= 0) {
+ int[] left = wentLeft ? BalancedTree.left : BalancedTree.right;
+ int[] right = wentLeft ? BalancedTree.right : BalancedTree.left;
+ left[arg] = slot;
+ left[p] = arg;
+ right[arg] = -1 * p;
+ parent[arg] = p;
+ balance(arg, p);
+
+ // we take the place of a preexisting node
+ } else {
+ left[arg] = left[slot]; // steal slot's left subtree
+ left[slot] = -1 * arg;
+ right[arg] = slot; // make slot our right subtree
+ parent[arg] = parent[slot];
+ parent[slot] = arg;
+ if (slot == root) {
+ root = arg;
+ balance(slot, arg);
+ balance(arg, 0);
+ } else {
+ if (left[p] == slot) left[p] = arg;
+ else if (right[p] == slot) right[p] = arg;
+ else throw new Error("should never happen");
+ balance(slot, arg);
+ balance(arg, p);
+ }
+ }
+ }
+
+
+ // Retrieval //////////////////////////////////////////////////////////////////////
+
+ private int get(int index, int slot) {
+ int diff = index - sizeof(left[slot]);
+ if (diff > 0) return get(diff - 1, right[slot]);
+ else if (diff < 0) return get(index, left[slot]);
+ else return slot;
+ }
+
+
+ // Deletion //////////////////////////////////////////////////////////////////////
+
+ private int delete(int index, int slot, int p) {
+ int diff = index - sizeof(left[slot]);
+ if (diff < 0) {
+ int ret = delete(index, left[slot], slot);
+ balance(slot, p);
+ return ret;
+
+ } else if (diff > 0) {
+ int ret = delete(diff - 1, right[slot], slot);
+ balance(slot, p);
+ return ret;
+
+ // we found the node to delete
+ } else {
+
+ // fast path: it has no children
+ if (left[slot] <= 0 && right[slot] <= 0) {
+ if (p == 0) root = 0;
+ else {
+ int[] side = left[p] == slot ? left : right;
+ side[p] = side[slot]; // fix parent's pointer
+ }
+
+ // fast path: it has no left child, so we replace it with its right child
+ } else if (left[slot] <= 0) {
+ if (p == 0) root = right[slot];
+ else (left[p] == slot ? left : right)[p] = right[slot]; // fix parent's pointer
+ parent[right[slot]] = p;
+ left[leftmost(right[slot])] = left[slot]; // fix our successor-leaf's fake right ptr
+ balance(right[slot], p);
+
+ // fast path; it has no right child, so we replace it with its left child
+ } else if (right[slot] <= 0) {
+ if (p == 0) root = left[slot];
+ else (left[p] == slot ? left : right)[p] = left[slot]; // fix parent's pointer
+ parent[left[slot]] = p;
+ right[rightmost(left[slot])] = right[slot]; // fix our successor-leaf's fake right ptr
+ balance(left[slot], p);
+
+ // node to be deleted has two children, so we replace it with its left child's rightmost descendant
+ } else {
+ int left_childs_rightmost = delete(sizeof(left[slot]) - 1, left[slot], slot);
+ left[left_childs_rightmost] = left[slot];
+ right[left_childs_rightmost] = right[slot];
+ if(left[slot] > 0) parent[left[slot]] = left_childs_rightmost;
+ if(right[slot] > 0) parent[right[slot]] = left_childs_rightmost;
+ parent[left_childs_rightmost] = parent[slot];
+ if (p == 0) root = left_childs_rightmost;
+ else (left[p] == slot ? left : right)[p] = left_childs_rightmost; // fix parent's pointer
+ balance(left_childs_rightmost, p);
+ }
+
+ return slot;
+ }
+ }
+
+ // Debugging ///////////////////////////////////////////////////////////////////////////
+
+ public void printTree() {
+ if(root == 0) System.err.println("Tree is empty");
+ else printTree(root,0,false);
+ }
+ private void printTree(int node,int indent,boolean l) {
+ for(int i=0;i<indent;i++) System.err.print(" ");
+ if(node < 0) System.err.println((l?"Prev: " : "Next: ") + -node);
+ else if(node == 0) System.err.println(l ? "Start" : "End");
+ else {
+ System.err.print("" + node + ": " + objects[node]);
+ System.err.println(" Parent: " + parent[node]);
+ printTree(left[node],indent+1,true);
+ printTree(right[node],indent+1,false);
+ }
+ }
+}
--- /dev/null
+// Copyright (C) 2003 Adam Megacz <adam@ibex.org> all rights reserved.
+//
+// You may modify, copy, and redistribute this code under the terms of
+// the GNU Library Public License version 2.1, with the exception of
+// the portion of clause 6a after the semicolon (aka the "obnoxious
+// relink clause")
+
+package org.ibex.util;
+
+import java.io.*;
+import java.util.*;
+import java.util.zip.*;
+
+/** Reads a CAB file structure */
+public class CAB {
+
+ /** reads a CAB file, parses it, and returns an InputStream representing the named file */
+ public static InputStream getFileInputStream(InputStream is, String fileName) throws IOException, EOFException {
+ return getFileInputStream(is, 0, fileName);
+ }
+
+ public static InputStream getFileInputStream(InputStream is, int skipHeaders, String fileName) throws IOException, EOFException {
+ DataInputStream dis = new DataInputStream(is);
+ CFHEADER h = new CFHEADER();
+
+ while (skipHeaders > 0) { CFHEADER.seekMSCF(dis); skipHeaders--; }
+
+ try {
+ h.read(dis);
+ } catch (CFHEADER.BogusHeaderException bhe) {
+ throw new EOFException();
+ }
+
+ for(int i=0; i<h.folders.length; i++) {
+ CFFOLDER f = new CFFOLDER(h);
+ try {
+ f.read(dis);
+ } catch (CFFOLDER.UnsupportedCompressionTypeException ucte) {
+ throw ucte;
+ }
+ }
+
+ for(int i=0; i<h.files.length; i++) {
+ CFFILE f = new CFFILE(h);
+ f.read(dis);
+ }
+
+ for(int i=0; i<h.folders.length; i++) {
+ InputStream is2 = new CFFOLDERInputStream(h.folders[i], dis);
+ for(int j=0; j<h.folders[i].files.size(); j++) {
+ CFFILE file = (CFFILE)h.folders[i].files.elementAt(j);
+ if (file.fileName.equals(fileName)) return new LimitStream(is2, file.fileSize);
+ byte[] b = new byte[file.fileSize];
+ }
+ }
+
+ return null;
+ }
+
+ private static class LimitStream extends FilterInputStream {
+ int limit;
+ public LimitStream(InputStream is, int limit) {
+ super(is);
+ this.limit = limit;
+ }
+ public int read() throws IOException {
+ if (limit == 0) return -1;
+ int ret = super.read();
+ if (ret != -1) limit--;
+ return ret;
+ }
+ public int read(byte[] b, int off, int len) throws IOException {
+ if (len > limit) len = limit;
+ if (limit == 0) return -1;
+ int ret = super.read(b, off, len);
+ limit -= ret;
+ return ret;
+ }
+ }
+
+ /** Encapsulates a CFHEADER entry */
+ public static class CFHEADER {
+ byte[] reserved1 = new byte[4]; // reserved
+ int fileSize = 0; // size of this cabinet file in bytes
+ byte[] reserved2 = new byte[4]; // reserved
+ int offsetOfFirstCFFILEEntry; // offset of the first CFFILE entry
+ byte[] reserved3 = new byte[4]; // reserved
+ byte versionMinor = 3; // cabinet file format version, minor
+ byte versionMajor = 1; // cabinet file format version, major
+ boolean prevCAB = false; // true iff there is a cabinet before this one in a sequence
+ boolean nextCAB = false; // true iff there is a cabinet after this one in a sequence
+ boolean hasReserved = false; // true iff the cab has per-{cabinet, folder, block} reserved areas
+ int setID = 0; // must be the same for all cabinets in a set
+ int indexInCabinetSet = 0; // number of this cabinet file in a set
+ byte perCFFOLDERReservedSize = 0; // (optional) size of per-folder reserved area
+ byte perDatablockReservedSize = 0; // (optional) size of per-datablock reserved area
+ byte[] perCabinetReservedArea = null; // per-cabinet reserved area
+ String previousCabinet = null; // name of previous cabinet file in a set
+ String previousDisk = null; // name of previous disk in a set
+ String nextCabinet = null; // name of next cabinet in a set
+ String nextDisk = null; // name of next disk in a set
+
+ CFFOLDER[] folders = new CFFOLDER[0];
+ CFFILE[] files = new CFFILE[0];
+
+ int readCFFOLDERs = 0; // the number of folders read in so far
+ int readCFFILEs = 0; // the number of folders read in so far
+
+ public void print(PrintStream ps) {
+ ps.println("CAB CFFILE CFHEADER v" + ((int)versionMajor) + "." + ((int)versionMinor));
+ ps.println(" total file size = " + fileSize);
+ ps.println(" offset of first file = " + offsetOfFirstCFFILEEntry);
+ ps.println(" total folders = " + folders.length);
+ ps.println(" total files = " + files.length);
+ ps.println(" flags = 0x" +
+ Integer.toString((prevCAB ? 0x1 : 0x0) |
+ (nextCAB ? 0x2 : 0x0) |
+ (hasReserved ? 0x4 : 0x0), 16) + " [ " +
+ (prevCAB ? "prev " : "") +
+ (nextCAB ? "next " : "") +
+ (hasReserved ? "reserve_present " : "") + "]");
+ ps.println(" set id = " + setID);
+ ps.println(" index in set = " + indexInCabinetSet);
+ ps.println(" header reserved area #1 =" +
+ " 0x" + Integer.toString(reserved1[0], 16) +
+ " 0x" + Integer.toString(reserved1[1], 16) +
+ " 0x" + Integer.toString(reserved1[2], 16) +
+ " 0x" + Integer.toString(reserved1[3], 16));
+ ps.println(" header reserved area #2 =" +
+ " 0x" + Integer.toString(reserved2[0], 16) +
+ " 0x" + Integer.toString(reserved2[1], 16) +
+ " 0x" + Integer.toString(reserved2[2], 16) +
+ " 0x" + Integer.toString(reserved2[3], 16));
+ ps.println(" header reserved area #3 =" +
+ " 0x" + Integer.toString(reserved3[0], 16) +
+ " 0x" + Integer.toString(reserved3[1], 16) +
+ " 0x" + Integer.toString(reserved3[2], 16) +
+ " 0x" + Integer.toString(reserved3[3], 16));
+ if (hasReserved) {
+ if (perCabinetReservedArea != null) {
+ ps.print(" per-cabinet reserved area = ");
+ for(int i=0; i<perCabinetReservedArea.length; i++)
+ ps.print(((perCabinetReservedArea[i] & 0xff) < 16 ? "0" : "") +
+ Integer.toString(perCabinetReservedArea[i] & 0xff, 16) + " ");
+ ps.println();
+ }
+ ps.println(" per folder reserved area = " + perCFFOLDERReservedSize + " bytes");
+ ps.println(" per block reserved area = " + perDatablockReservedSize + " bytes");
+ }
+ }
+
+ public String toString() {
+ return
+ "[ CAB CFFILE CFHEADER v" +
+ ((int)versionMajor) + "." + ((int)versionMinor) + ", " +
+ fileSize + " bytes, " +
+ folders.length + " folders, " +
+ files.length + " files] ";
+ }
+
+ /** fills in all fields in the header and positions the stream at the first folder */
+ public void read(DataInputStream dis) throws IOException, BogusHeaderException {
+ seekMSCF(dis);
+ dis.readFully(reserved1);
+
+ byte[] headerHashable = new byte[28];
+ dis.readFully(headerHashable);
+ DataInputStream hhis = new DataInputStream(new ByteArrayInputStream(headerHashable));
+
+ fileSize = readLittleInt(hhis);
+ hhis.readFully(reserved2);
+ offsetOfFirstCFFILEEntry = readLittleInt(hhis);
+ hhis.readFully(reserved3);
+ versionMinor = hhis.readByte();
+ versionMajor = hhis.readByte();
+ folders = new CFFOLDER[readLittleShort(hhis)];
+ files = new CFFILE[readLittleShort(hhis)];
+ int flags = readLittleShort(hhis);
+ prevCAB = (flags & 0x0001) != 0;
+ nextCAB = (flags & 0x0002) != 0;
+ hasReserved = (flags & 0x0004) != 0;
+ setID = readLittleShort(hhis);
+ indexInCabinetSet = readLittleShort(hhis);
+
+ if (offsetOfFirstCFFILEEntry < 0 || fileSize < 0) {
+ throw new BogusHeaderException();
+ }
+
+ if (hasReserved) {
+ perCabinetReservedArea = new byte[readLittleShort(dis)];
+ perCFFOLDERReservedSize = dis.readByte();
+ perDatablockReservedSize = dis.readByte();
+ if (perCabinetReservedArea.length > 0)
+ dis.readFully(perCabinetReservedArea);
+ }
+
+ try {
+ if (prevCAB) {
+ previousCabinet = readZeroTerminatedString(dis);
+ previousDisk = readZeroTerminatedString(dis);
+ }
+ if (nextCAB) {
+ nextCabinet = readZeroTerminatedString(dis);
+ nextDisk = readZeroTerminatedString(dis);
+ }
+ } catch (ArrayIndexOutOfBoundsException e) {
+ throw new BogusHeaderException();
+ }
+ }
+
+ public static void seekMSCF(DataInputStream dis) throws EOFException, IOException
+ {
+ int state;
+ // skip up to and including the 'MSCF' signature
+ state = 0;
+ while (state != 4) {
+ // M
+ while (state == 0 && dis.readByte() != 0x4D) { }
+ state = 1;
+ // S
+ switch (dis.readByte()) {
+ case 0x53 : state = 2; break;
+ case 0x4D : state = 1; continue;
+ default : state = 0; continue;
+ }
+ // C
+ if (dis.readByte() == 0x43) { state = 3; }
+ else { state = 0; continue; }
+ // F
+ if (dis.readByte() == 0x46) { state = 4; }
+ else { state = 0; }
+ }
+ }
+
+ public static class BogusHeaderException extends IOException {}
+ }
+
+ /** Encapsulates a CFFOLDER entry */
+ public static class CFFOLDER {
+ public static final int COMPRESSION_NONE = 0;
+ public static final int COMPRESSION_MSZIP = 1;
+ public static final int COMPRESSION_QUANTUM = 2;
+ public static final int COMPRESSION_LZX = 3;
+
+ int firstBlockOffset = 0; // offset of first data block within this folder
+ int numBlocks = 0; // number of data blocks
+ int compressionType = 0; // compression type for this folder
+ byte[] reservedArea = null; // per-folder reserved area
+ int indexInCFHEADER = 0; // our index in CFHEADER.folders
+ Vector files = new Vector();
+
+ private CFHEADER header = null;
+
+ public CFFOLDER(CFHEADER header) { this.header = header; }
+
+ public String toString() {
+ return "[ CAB CFFOLDER, " + numBlocks + " data blocks, compression type " +
+ compressionName(compressionType) +
+ ", " + reservedArea.length + " bytes of reserved data ]";
+ }
+
+ public void read(DataInputStream dis) throws IOException, UnsupportedCompressionTypeException {
+ firstBlockOffset = readLittleInt(dis);
+ numBlocks = readLittleShort(dis);
+ compressionType = readLittleShort(dis) & 0x000F;
+ if (compressionType != COMPRESSION_MSZIP) {
+ throw new UnsupportedCompressionTypeException(compressionType);
+ }
+ reservedArea = new byte[header.perCFFOLDERReservedSize];
+ if (reservedArea.length > 0) dis.readFully(reservedArea);
+ indexInCFHEADER = header.readCFFOLDERs++;
+ header.folders[indexInCFHEADER] = this;
+ }
+
+ public static String compressionName(int type) {
+ switch (type) {
+ case COMPRESSION_NONE:
+ return "NONE";
+ case COMPRESSION_MSZIP:
+ return "MSZIP";
+ case COMPRESSION_QUANTUM:
+ return "QUANTUM";
+ case COMPRESSION_LZX:
+ return "LZX";
+ default:
+ return "<Unknown type " + type + ">";
+ }
+ }
+
+ public static class UnsupportedCompressionTypeException extends IOException {
+ private int compressionType;
+
+ UnsupportedCompressionTypeException(int type) {
+ compressionType = type;
+ }
+ public String toString() {
+ return "UnsupportedCompressionTypeException: no support for compression type " + compressionName(compressionType);
+ }
+ }
+ }
+
+ /** Encapsulates a CFFILE entry */
+ public static class CFFILE {
+ int fileSize = 0; // size of this file
+ int uncompressedOffsetInCFFOLDER = 0; // offset of this file within the folder, not accounting for compression
+ int folderIndex = 0; // index of the CFFOLDER we belong to
+ Date date = null; // modification date
+ int attrs = 0; // attrs
+ boolean readOnly = false; // read-only flag
+ boolean hidden = false; // hidden flag
+ boolean system = false; // system flag
+ boolean arch = false; // archive flag
+ boolean runAfterExec = false; // true if file should be run during extraction
+ boolean UTFfileName = false; // true if filename is UTF-encoded
+ String fileName = null; // filename
+ int indexInCFHEADER = 0; // our index in CFHEADER.files
+ CFFOLDER folder = null; // the folder we belong to
+ private CFHEADER header = null;
+ File myFile;
+
+ public CFFILE(CFHEADER header) { this.header = header; }
+
+ public CFFILE(File f, String pathName) throws IOException {
+ fileSize = (int)f.length();
+ folderIndex = 0;
+ date = new java.util.Date(f.lastModified());
+ fileName = pathName;
+ myFile = f;
+ }
+
+ public String toString() {
+ return "[ CAB CFFILE: " + fileName + ", " + fileSize + " bytes [ " +
+ (readOnly ? "readonly " : "") +
+ (system ? "system " : "") +
+ (hidden ? "hidden " : "") +
+ (arch ? "arch " : "") +
+ (runAfterExec ? "run_after_exec " : "") +
+ (UTFfileName ? "UTF_filename " : "") +
+ "]";
+ }
+
+ public void read(DataInputStream dis) throws IOException {
+ fileSize = readLittleInt(dis);
+ uncompressedOffsetInCFFOLDER = readLittleInt(dis);
+ folderIndex = readLittleShort(dis);
+ readLittleShort(dis); // date
+ readLittleShort(dis); // time
+ attrs = readLittleShort(dis);
+ readOnly = (attrs & 0x1) != 0;
+ hidden = (attrs & 0x2) != 0;
+ system = (attrs & 0x4) != 0;
+ arch = (attrs & 0x20) != 0;
+ runAfterExec = (attrs & 0x40) != 0;
+ UTFfileName = (attrs & 0x80) != 0;
+ fileName = readZeroTerminatedString(dis);
+
+ indexInCFHEADER = header.readCFFILEs++;
+ header.files[indexInCFHEADER] = this;
+ folder = header.folders[folderIndex];
+ folder.files.addElement(this);
+ }
+ }
+
+
+
+
+ // Compressing Input and Output Streams ///////////////////////////////////////////////
+
+ /** an InputStream that decodes CFDATA blocks belonging to a CFFOLDER */
+ private static class CFFOLDERInputStream extends InputStream {
+ CFFOLDER folder;
+ DataInputStream dis;
+ InputStream iis = null;
+
+ byte[] compressed = new byte[128 * 1024];
+ byte[] uncompressed = new byte[256 * 1024];
+
+ public CFFOLDERInputStream(CFFOLDER f, DataInputStream dis) {
+ this.folder = f;
+ this.dis = dis;
+ }
+
+ InputStream readBlock() throws IOException {
+ int compressedBytes = readLittleShort(dis);
+ int unCompressedBytes = readLittleShort(dis);
+ byte[] reserved = new byte[/*folder.header.perDatablockReservedSize*/0];
+ if (reserved.length > 0) dis.readFully(reserved);
+ if (dis.readByte() != 0x43) throw new CABException("malformed block header");
+ if (dis.readByte() != 0x4B) throw new CABException("malformed block header");
+
+ dis.readFully(compressed, 0, compressedBytes - 2);
+
+ Inflater i = new Inflater(true);
+ i.setInput(compressed, 0, compressedBytes - 2);
+
+ if (unCompressedBytes > uncompressed.length) uncompressed = new byte[unCompressedBytes];
+ try { i.inflate(uncompressed, 0, uncompressed.length);
+ } catch (DataFormatException dfe) {
+ dfe.printStackTrace();
+ throw new CABException(dfe.toString());
+ }
+ return new ByteArrayInputStream(uncompressed, 0, unCompressedBytes);
+ }
+
+ public int available() throws IOException { return iis == null ? 0 : iis.available(); }
+ public void close() throws IOException { iis.close(); }
+ public void mark(int i) { }
+ public boolean markSupported() { return false; }
+ public void reset() { }
+
+ public long skip(long l) throws IOException {
+ if (iis == null) iis = readBlock();
+ int ret = 0;
+ while (l > ret) {
+ long numread = iis.skip(l - ret);
+ if (numread == 0 || numread == -1) iis = readBlock();
+ else ret += numread;
+ }
+ return ret;
+ }
+
+ public int read(byte[] b, int off, int len) throws IOException {
+ if (iis == null) iis = readBlock();
+ int ret = 0;
+ while (len > ret) {
+ int numread = iis.read(b, off + ret, len - ret);
+ if (numread == 0 || numread == -1) iis = readBlock();
+ else ret += numread;
+ }
+ return ret;
+ }
+
+ public int read() throws IOException {
+ if (iis == null) iis = readBlock();
+ int ret = iis.read();
+ if (ret == -1) {
+ iis = readBlock();
+ ret = iis.read();
+ }
+ return ret;
+ }
+ }
+
+
+
+ // Misc Stuff //////////////////////////////////////////////////////////////
+
+ public static String readZeroTerminatedString(DataInputStream dis) throws IOException {
+ int numBytes = 0;
+ byte[] b = new byte[256];
+ while(true) {
+ byte next = dis.readByte();
+ if (next == 0x0) return new String(b, 0, numBytes);
+ b[numBytes++] = next;
+ }
+ }
+
+ public static int readLittleInt(DataInputStream dis) throws IOException {
+ int lowest = (int)(dis.readByte() & 0xff);
+ int low = (int)(dis.readByte() & 0xff);
+ int high = (int)(dis.readByte() & 0xff);
+ int highest = (int)(dis.readByte() & 0xff);
+ return (highest << 24) | (high << 16) | (low << 8) | lowest;
+ }
+
+ public static int readLittleShort(DataInputStream dis) throws IOException {
+ int low = (int)(dis.readByte() & 0xff);
+ int high = (int)(dis.readByte() & 0xff);
+ return (high << 8) | low;
+ }
+
+ public static class CABException extends IOException {
+ public CABException(String s) { super(s); }
+ }
+
+
+ /** scratch space for isToByteArray() */
+ static byte[] workspace = new byte[16 * 1024];
+
+ /** Trivial method to completely read an InputStream */
+ public static synchronized byte[] isToByteArray(InputStream is) throws IOException {
+ int pos = 0;
+ while (true) {
+ int numread = is.read(workspace, pos, workspace.length - pos);
+ if (numread == -1) break;
+ else if (pos + numread < workspace.length) pos += numread;
+ else {
+ pos += numread;
+ byte[] temp = new byte[workspace.length * 2];
+ System.arraycopy(workspace, 0, temp, 0, workspace.length);
+ workspace = temp;
+ }
+ }
+ byte[] ret = new byte[pos];
+ System.arraycopy(workspace, 0, ret, 0, pos);
+ return ret;
+ }
+
+
+}
+
--- /dev/null
+// Copyright (C) 2003 Adam Megacz <adam@ibex.org> all rights reserved.
+//
+// You may modify, copy, and redistribute this code under the terms of
+// the GNU Library Public License version 2.1, with the exception of
+// the portion of clause 6a after the semicolon (aka the "obnoxious
+// relink clause")
+
+/*
+
+Bug report from a user:
+
+I looked at your Cache.java and tried to make good use of it, but I was
+out of luck - it wouldn't run here. Digging deeper into the code, I came
+across something that might be considered a bug. But maybe it's just a
+feature :-)
+
+
+Starting with an empty cache, Cache.put() immediately followed by
+Cache.get() on same keys / same object will set Node lru back to null in
+Node.remove() which is called in get().
+
+Assuming this put()-get() sequence is fixed, it will fill the cache, but
+lru will remain null.
+
+When cache is filled 100%, we have, at the end of the get(), where
+size>maxSize is checked, a state that mru == lru == n (from
+if(lru==null) thus deleteting the newly inserted object. Oops.
+
+
+Hope I made this clear enough. Maybe it's not a problem in xwt due to a
+different usage scheme of the cache.
+
+
+
+*/
+
+package org.ibex.util;
+
+// FIXME needs to be a weak hash
+
+/**
+ * A Hash table with a fixed size; drops extraneous elements. Uses
+ * LRU strategy.
+ */
+public class Cache extends Hash {
+
+ /** head of list is the mru; tail is the lru */
+ Node mru = null;
+ Node lru = null;
+
+ private int maxSize;
+ private Cache() { }
+ public Cache(int maxSize) {
+ super(maxSize * 2, 3);
+ this.maxSize = maxSize;
+ }
+
+ /** A doubly-linked list */
+ private class Node {
+ final Object val;
+ final Object k1;
+ final Object k2;
+ public Node(Object k1, Object k2, Object val) { this.k1 = k1; this.k2 = k2; this.val = val; }
+ Node next = null;
+ Node prev = null;
+ void remove() {
+ if (this == lru) lru = prev;
+ if (this == mru) mru = next;
+ if (next != null) next.prev = prev;
+ if (prev != null) prev.next = next;
+ next = prev = null;
+ }
+ void placeAfter(Node n) {
+ remove();
+ if (n == null) return;
+ next = n.next;
+ if (n.next != null) n.next.prev = this;
+ n.next = this;
+ prev = n;
+ }
+ void placeBefore(Node n) {
+ remove();
+ if (n == null) return;
+ next = n;
+ prev = n.prev;
+ n.prev = this;
+ if (prev != null) prev.next = this;
+ }
+ }
+
+ public void clear() {
+ lru = null;
+ super.clear();
+ }
+
+ public void remove(Object k1, Object k2) {
+ Object o = super.get(k1, k2);
+ if (o != null) ((Node)o).remove();
+ super.remove(k1, k2);
+ }
+
+ public Object get(Object k1, Object k2) {
+ Node n = (Node)super.get(k1, k2);
+ if (n == null) return null;
+ n.remove();
+ n.placeBefore(mru);
+ mru = n;
+ return n.val;
+ }
+
+ public void put(Object k1, Object k2, Object v) {
+ Node n = new Node(k1, k2, v);
+ if (lru == null) {
+ lru = mru = n;
+ } else {
+ n.placeBefore(mru);
+ mru = n;
+ }
+ if (super.get(k1, k2) != null) remove(k1, k2);
+ super.put(k1, k2, n);
+ if (size > maxSize) remove(lru.k1, lru.k2);
+ }
+
+}
+
+
--- /dev/null
+// Copyright (C) 2003 Adam Megacz <adam@ibex.org> all rights reserved.
+//
+// You may modify, copy, and redistribute this code under the terms of
+// the GNU Library Public License version 2.1, with the exception of
+// the portion of clause 6a after the semicolon (aka the "obnoxious
+// relink clause")
+
+package org.ibex.util;
+import java.io.*;
+
+// FEATURE: don't use a byte[] if we have a diskCache file
+/**
+ * Wraps around an InputStream, caching the stream in a byte[] as it
+ * is read and permitting multiple simultaneous readers
+ */
+public class CachedInputStream {
+
+ boolean filling = false; ///< true iff some thread is blocked on us waiting for input
+ boolean eof = false; ///< true iff end of stream has been reached
+ byte[] cache = new byte[1024 * 128];
+ int size = 0;
+ final InputStream is;
+ File diskCache;
+
+ public CachedInputStream(InputStream is) { this(is, null); }
+ public CachedInputStream(InputStream is, File diskCache) {
+ this.is = is;
+ this.diskCache = diskCache;
+ }
+ public InputStream getInputStream() throws IOException {
+ if (diskCache != null && diskCache.exists()) return new FileInputStream(diskCache);
+ return new SubStream();
+ }
+
+ public void grow(int newLength) {
+ if (newLength < cache.length) return;
+ byte[] newCache = new byte[cache.length + 2 * (newLength - cache.length)];
+ System.arraycopy(cache, 0, newCache, 0, size);
+ cache = newCache;
+ }
+
+ synchronized void fillCache(int howMuch) throws IOException {
+ if (filling) { try { wait(); } catch (InterruptedException e) { }; return; }
+ filling = true;
+ grow(size + howMuch);
+ int ret = is.read(cache, size, howMuch);
+ if (ret == -1) {
+ eof = true;
+ // FIXME: probably a race here
+ if (diskCache != null && !diskCache.exists())
+ try {
+ File cacheFile = new File(diskCache + ".incomplete");
+ FileOutputStream cacheFileStream = new FileOutputStream(cacheFile);
+ cacheFileStream.write(cache, 0, size);
+ cacheFileStream.close();
+ cacheFile.renameTo(diskCache);
+ } catch (IOException e) {
+ Log.info(this, "exception thrown while writing disk cache");
+ Log.info(this, e);
+ }
+ }
+ else size += ret;
+ filling = false;
+ notifyAll();
+ }
+
+ private class SubStream extends InputStream implements KnownLength {
+ int pos = 0;
+ public int available() { return Math.max(0, size - pos); }
+ public long skip(long n) throws IOException { pos += (int)n; return n; } // FEATURE: don't skip past EOF
+ public int getLength() { return eof ? size : is instanceof KnownLength ? ((KnownLength)is).getLength() : 0; }
+ public int read() throws IOException { // FEATURE: be smarter here
+ byte[] b = new byte[1];
+ int ret = read(b, 0, 1);
+ return ret == -1 ? -1 : b[0]&0xff;
+ }
+ public int read(byte[] b, int off, int len) throws IOException {
+ synchronized(CachedInputStream.this) {
+ while (pos >= size && !eof) fillCache(pos + len - size);
+ if (eof && pos == size) return -1;
+ int count = Math.min(size - pos, len);
+ System.arraycopy(cache, pos, b, off, count);
+ pos += count;
+ return count;
+ }
+ }
+ }
+}
--- /dev/null
+// Copyright (C) 2003 Adam Megacz <adam@ibex.org> all rights reserved.
+//
+// You may modify, copy, and redistribute this code under the terms of
+// the GNU Library Public License version 2.1, with the exception of
+// the portion of clause 6a after the semicolon (aka the "obnoxious
+// relink clause")
+
+package org.ibex.util;
+
+/** a simple interface for callbacks*/
+public interface Callback {
+
+ public abstract Object call(Object arg);
+
+}
--- /dev/null
+// Copyright (C) 2004 Adam Megacz <adam@ibex.org> all rights reserved.
+//
+// You may modify, copy, and redistribute this code under the terms of
+// the GNU Library Public License version 2.1, with the exception of
+// the portion of clause 6a after the semicolon (aka the "obnoxious
+// relink clause")
+package org.ibex.util;
+import java.util.*;
+
+public class CounterEnumeration implements Enumeration {
+ public final int max;
+ private int cur = 0;
+ public CounterEnumeration(int i) { max = i; }
+ public void reset() { cur = 0; }
+ public boolean hasMoreElements() { return cur < max; }
+ public Object nextElement() { return new Integer(cur++); }
+}
--- /dev/null
+// Copyright (C) 2003 Adam Megacz <adam@ibex.org> all rights reserved.
+//
+// You may modify, copy, and redistribute this code under the terms of
+// the GNU Library Public License version 2.1, with the exception of
+// the portion of clause 6a after the semicolon (aka the "obnoxious
+// relink clause")
+
+package org.ibex.util;
+
+/**
+ * A general-purpose data structure for holding a list of rectangular
+ * regions that need to be repainted, with intelligent coalescing.
+ *
+ * DirtyList will unify two regions A and B if the smallest rectangle
+ * enclosing both A and B occupies no more than epsilon + Area_A +
+ * Area_B. Failing this, if two corners of A fall within B, A will be
+ * shrunk to exclude the union of A and B.
+ */
+public class DirtyList {
+
+ /** The dirty regions (each one is an int[4]). */
+ private int[][] dirties = new int[10][];
+
+ /** The number of dirty regions */
+ private int numdirties = 0;
+
+ /** See class comment */
+ private static final int epsilon = 50 * 50;
+
+ public int num() { return numdirties; }
+
+ /** grows the array */
+ private void grow() {
+ int[][] newdirties = new int[dirties.length * 2][];
+ System.arraycopy(dirties, 0, newdirties, 0, numdirties);
+ dirties = newdirties;
+ }
+
+ /** Add a new rectangle to the dirty list; returns false if the
+ * region fell completely within an existing rectangle or set of
+ * rectangles (ie did not expand the dirty area)
+ */
+ public synchronized boolean dirty(int x, int y, int w, int h) {
+ if (numdirties == dirties.length) grow();
+
+ // we attempt the "lossless" combinations first
+ for(int i=0; i<numdirties; i++) {
+ int[] cur = dirties[i];
+
+ // new region falls completely within existing region
+ if (x >= cur[0] && y >= cur[1] && x + w <= cur[0] + cur[2] && y + h <= cur[1] + cur[3]) {
+ return false;
+
+ // existing region falls completely within new region
+ } else if (x <= cur[0] && y <= cur[1] && x + w >= cur[0] + cur[2] && y + h >= cur[1] + cur[3]) {
+ dirties[i][2] = 0;
+ dirties[i][3] = 0;
+
+ // left end of new region falls within existing region
+ } else if (x >= cur[0] && x < cur[0] + cur[2] && y >= cur[1] && y + h <= cur[1] + cur[3]) {
+ w = x + w - (cur[0] + cur[2]);
+ x = cur[0] + cur[2];
+ i = -1; continue;
+
+ // right end of new region falls within existing region
+ } else if (x + w > cur[0] && x + w <= cur[0] + cur[2] && y >= cur[1] && y + h <= cur[1] + cur[3]) {
+ w = cur[0] - x;
+ i = -1; continue;
+
+ // top end of new region falls within existing region
+ } else if (x >= cur[0] && x + w <= cur[0] + cur[2] && y >= cur[1] && y < cur[1] + cur[3]) {
+ h = y + h - (cur[1] + cur[3]);
+ y = cur[1] + cur[3];
+ i = -1; continue;
+
+ // bottom end of new region falls within existing region
+ } else if (x >= cur[0] && x + w <= cur[0] + cur[2] && y + h > cur[1] && y + h <= cur[1] + cur[3]) {
+ h = cur[1] - y;
+ i = -1; continue;
+
+ // left end of existing region falls within new region
+ } else if (dirties[i][0] >= x && dirties[i][0] < x + w && dirties[i][1] >= y && dirties[i][1] + dirties[i][3] <= y + h) {
+ dirties[i][2] = dirties[i][2] - (x + w - dirties[i][0]);
+ dirties[i][0] = x + w;
+ i = -1; continue;
+
+ // right end of existing region falls within new region
+ } else if (dirties[i][0] + dirties[i][2] > x && dirties[i][0] + dirties[i][2] <= x + w &&
+ dirties[i][1] >= y && dirties[i][1] + dirties[i][3] <= y + h) {
+ dirties[i][2] = x - dirties[i][0];
+ i = -1; continue;
+
+ // top end of existing region falls within new region
+ } else if (dirties[i][0] >= x && dirties[i][0] + dirties[i][2] <= x + w && dirties[i][1] >= y && dirties[i][1] < y + h) {
+ dirties[i][3] = dirties[i][3] - (y + h - dirties[i][1]);
+ dirties[i][1] = y + h;
+ i = -1; continue;
+
+ // bottom end of existing region falls within new region
+ } else if (dirties[i][0] >= x && dirties[i][0] + dirties[i][2] <= x + w &&
+ dirties[i][1] + dirties[i][3] > y && dirties[i][1] + dirties[i][3] <= y + h) {
+ dirties[i][3] = y - dirties[i][1];
+ i = -1; continue;
+ }
+
+ }
+
+ // then we attempt the "lossy" combinations
+ for(int i=0; i<numdirties; i++) {
+ int[] cur = dirties[i];
+ if (w > 0 && h > 0 && cur[2] > 0 && cur[3] > 0 &&
+ ((max(x + w, cur[0] + cur[2]) - min(x, cur[0])) *
+ (max(y + h, cur[1] + cur[3]) - min(y, cur[1])) <
+ w * h + cur[2] * cur[3] + epsilon)) {
+ int a = min(cur[0], x);
+ int b = min(cur[1], y);
+ int c = max(x + w, cur[0] + cur[2]) - min(cur[0], x);
+ int d = max(y + h, cur[1] + cur[3]) - min(cur[1], y);
+ dirties[i][2] = 0;
+ dirties[i][3] = 0;
+ return dirty(a, b, c, d);
+ }
+ }
+
+ dirties[numdirties++] = new int[] { x, y, w, h };
+ return true;
+ }
+
+ /** Returns true if there are no regions that need repainting */
+ public boolean empty() { return (numdirties == 0); }
+
+ /**
+ * Atomically returns the list of dirty rectangles as an array of
+ * four-int arrays and clears the internal dirty-rectangle
+ * list. Note that some of the regions returned may be null, or
+ * may have zero height or zero width, and do not need to be
+ * repainted.
+ */
+ public synchronized int[][] flush() {
+ if (numdirties == 0) return null;
+ int[][] ret = dirties;
+ for(int i=numdirties; i<ret.length; i++) ret[i] = null;
+ dirties = new int[dirties.length][];
+ numdirties = 0;
+ return ret;
+ }
+
+ /** included here so that it can be inlined */
+ private static final int min(int a, int b) {
+ if (a<b) return a;
+ else return b;
+ }
+
+ /** included here so that it can be inlined */
+ private static final int max(int a, int b) {
+ if (a>b) return a;
+ else return b;
+ }
+
+ /** included here so that it can be inlined */
+ private static final int min(int a, int b, int c) {
+ if (a<=b && a<=c) return a;
+ else if (b<=c && b<=a) return b;
+ else return c;
+ }
+
+ /** included here so that it can be inlined */
+ private static final int max(int a, int b, int c) {
+ if (a>=b && a>=c) return a;
+ else if (b>=c && b>=a) return b;
+ else return c;
+ }
+
+ /** included here so that it can be inlined */
+ private static final int bound(int a, int b, int c) {
+ if (a > b) return a;
+ if (c < b) return c;
+ return b;
+ }
+
+}
--- /dev/null
+package org.ibex.util;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ * BrowserLauncher is a class that provides one static method, openURL, which opens the default
+ * web browser for the current user of the system to the given URL. It may support other
+ * protocols depending on the system -- mailto, ftp, etc. -- but that has not been rigorously
+ * tested and is not guaranteed to work.
+ * <p>
+ * Yes, this is platform-specific code, and yes, it may rely on classes on certain platforms
+ * that are not part of the standard JDK. What we're trying to do, though, is to take something
+ * that's frequently desirable but inherently platform-specific -- opening a default browser --
+ * and allow programmers (you, for example) to do so without worrying about dropping into native
+ * code or doing anything else similarly evil.
+ * <p>
+ * Anyway, this code is completely in Java and will run on all JDK 1.1-compliant systems without
+ * modification or a need for additional libraries. All classes that are required on certain
+ * platforms to allow this to run are dynamically loaded at runtime via reflection and, if not
+ * found, will not cause this to do anything other than returning an error when opening the
+ * browser.
+ * <p>
+ * There are certain system requirements for this class, as it's running through Runtime.exec(),
+ * which is Java's way of making a native system call. Currently, this requires that a Macintosh
+ * have a Finder which supports the GURL event, which is true for Mac OS 8.0 and 8.1 systems that
+ * have the Internet Scripting AppleScript dictionary installed in the Scripting Additions folder
+ * in the Extensions folder (which is installed by default as far as I know under Mac OS 8.0 and
+ * 8.1), and for all Mac OS 8.5 and later systems. On Windows, it only runs under Win32 systems
+ * (Windows 95, 98, and NT 4.0, as well as later versions of all). On other systems, this drops
+ * back from the inherently platform-sensitive concept of a default browser and simply attempts
+ * to launch Netscape via a shell command.
+ * <p>
+ * This code is Copyright 1999-2001 by Eric Albert (ejalbert@cs.stanford.edu) and may be
+ * redistributed or modified in any form without restrictions as long as the portion of this
+ * comment from this paragraph through the end of the comment is not removed. The author
+ * requests that he be notified of any application, applet, or other binary that makes use of
+ * this code, but that's more out of curiosity than anything and is not required. This software
+ * includes no warranty. The author is not repsonsible for any loss of data or functionality
+ * or any adverse or unexpected effects of using this software.
+ * <p>
+ * Credits:
+ * <br>Steven Spencer, JavaWorld magazine (<a href="http://www.javaworld.com/javaworld/javatips/jw-javatip66.html">Java Tip 66</a>)
+ * <br>Thanks also to Ron B. Yeh, Eric Shapiro, Ben Engber, Paul Teitlebaum, Andrea Cantatore,
+ * Larry Barowski, Trevor Bedzek, Frank Miedrich, and Ron Rabakukk
+ *
+ * @author Eric Albert (<a href="mailto:ejalbert@cs.stanford.edu">ejalbert@cs.stanford.edu</a>)
+ * @version 1.4b1 (Released June 20, 2001)
+ */
+public class EjAlbertBrowserLauncher {
+
+ /**
+ * The Java virtual machine that we are running on. Actually, in most cases we only care
+ * about the operating system, but some operating systems require us to switch on the VM. */
+ private static int jvm;
+
+ /** The browser for the system */
+ private static Object browser;
+
+ /**
+ * Caches whether any classes, methods, and fields that are not part of the JDK and need to
+ * be dynamically loaded at runtime loaded successfully.
+ * <p>
+ * Note that if this is <code>false</code>, <code>openURL()</code> will always return an
+ * IOException.
+ */
+ private static boolean loadedWithoutErrors;
+
+ /** The com.apple.mrj.MRJFileUtils class */
+ private static Class mrjFileUtilsClass;
+
+ /** The com.apple.mrj.MRJOSType class */
+ private static Class mrjOSTypeClass;
+
+ /** The com.apple.MacOS.AEDesc class */
+ private static Class aeDescClass;
+
+ /** The <init>(int) method of com.apple.MacOS.AETarget */
+ private static Constructor aeTargetConstructor;
+
+ /** The <init>(int, int, int) method of com.apple.MacOS.AppleEvent */
+ private static Constructor appleEventConstructor;
+
+ /** The <init>(String) method of com.apple.MacOS.AEDesc */
+ private static Constructor aeDescConstructor;
+
+ /** The findFolder method of com.apple.mrj.MRJFileUtils */
+ private static Method findFolder;
+
+ /** The getFileCreator method of com.apple.mrj.MRJFileUtils */
+ private static Method getFileCreator;
+
+ /** The getFileType method of com.apple.mrj.MRJFileUtils */
+ private static Method getFileType;
+
+ /** The openURL method of com.apple.mrj.MRJFileUtils */
+ private static Method openURLm;
+
+ /** The makeOSType method of com.apple.MacOS.OSUtils */
+ private static Method makeOSType;
+
+ /** The putParameter method of com.apple.MacOS.AppleEvent */
+ private static Method putParameter;
+
+ /** The sendNoReply method of com.apple.MacOS.AppleEvent */
+ private static Method sendNoReply;
+
+ /** Actually an MRJOSType pointing to the System Folder on a Macintosh */
+ private static Object kSystemFolderType;
+
+ /** The keyDirectObject AppleEvent parameter type */
+ private static Integer keyDirectObject;
+
+ /** The kAutoGenerateReturnID AppleEvent code */
+ private static Integer kAutoGenerateReturnID;
+
+ /** The kAnyTransactionID AppleEvent code */
+ private static Integer kAnyTransactionID;
+
+ /** The linkage object required for JDirect 3 on Mac OS X. */
+ private static Object linkage;
+
+ /** The framework to reference on Mac OS X */
+ private static final String JDirect_MacOSX = "/System/Library/Frameworks/Carbon.framework/Frameworks/HIToolbox.framework/HIToolbox";
+
+ /** JVM constant for MRJ 2.0 */
+ private static final int MRJ_2_0 = 0;
+
+ /** JVM constant for MRJ 2.1 or later */
+ private static final int MRJ_2_1 = 1;
+
+ /** JVM constant for Java on Mac OS X 10.0 (MRJ 3.0) */
+ private static final int MRJ_3_0 = 3;
+
+ /** JVM constant for MRJ 3.1 */
+ private static final int MRJ_3_1 = 4;
+
+ /** JVM constant for any Windows NT JVM */
+ private static final int WINDOWS_NT = 5;
+
+ /** JVM constant for any Windows 9x JVM */
+ private static final int WINDOWS_9x = 6;
+
+ /** JVM constant for any other platform */
+ private static final int OTHER = -1;
+
+ /**
+ * The file type of the Finder on a Macintosh. Hardcoding "Finder" would keep non-U.S. English
+ * systems from working properly.
+ */
+ private static final String FINDER_TYPE = "FNDR";
+
+ /**
+ * The creator code of the Finder on a Macintosh, which is needed to send AppleEvents to the
+ * application.
+ */
+ private static final String FINDER_CREATOR = "MACS";
+
+ /** The name for the AppleEvent type corresponding to a GetURL event. */
+ private static final String GURL_EVENT = "GURL";
+
+ /**
+ * The first parameter that needs to be passed into Runtime.exec() to open the default web
+ * browser on Windows.
+ */
+ private static final String FIRST_WINDOWS_PARAMETER = "/c";
+
+ /** The second parameter for Runtime.exec() on Windows. */
+ private static final String SECOND_WINDOWS_PARAMETER = "start";
+
+ /**
+ * The third parameter for Runtime.exec() on Windows. This is a "title"
+ * parameter that the command line expects. Setting this parameter allows
+ * URLs containing spaces to work.
+ */
+ private static final String THIRD_WINDOWS_PARAMETER = "\"\"";
+
+ /**
+ * The shell parameters for Netscape that opens a given URL in an already-open copy of Netscape
+ * on many command-line systems.
+ */
+ private static final String NETSCAPE_REMOTE_PARAMETER = "-remote";
+ private static final String NETSCAPE_OPEN_PARAMETER_START = "'openURL(";
+ private static final String NETSCAPE_OPEN_PARAMETER_END = ")'";
+
+ /**
+ * The message from any exception thrown throughout the initialization process.
+ */
+ private static String errorMessage;
+
+ /**
+ * An initialization block that determines the operating system and loads the necessary
+ * runtime data.
+ */
+ static {
+ loadedWithoutErrors = true;
+ String osName = System.getProperty("os.name");
+ if (osName.startsWith("Mac OS")) {
+ String mrjVersion = System.getProperty("mrj.version");
+ String majorMRJVersion = mrjVersion.substring(0, 3);
+ try {
+ double version = Double.valueOf(majorMRJVersion).doubleValue();
+ if (version == 2) {
+ jvm = MRJ_2_0;
+ } else if (version >= 2.1 && version < 3) {
+ // Assume that all 2.x versions of MRJ work the same. MRJ 2.1 actually
+ // works via Runtime.exec() and 2.2 supports that but has an openURL() method
+ // as well that we currently ignore.
+ jvm = MRJ_2_1;
+ } else if (version == 3.0) {
+ jvm = MRJ_3_0;
+ } else if (version >= 3.1) {
+ // Assume that all 3.1 and later versions of MRJ work the same.
+ jvm = MRJ_3_1;
+ } else {
+ loadedWithoutErrors = false;
+ errorMessage = "Unsupported MRJ version: " + version;
+ }
+ } catch (NumberFormatException nfe) {
+ loadedWithoutErrors = false;
+ errorMessage = "Invalid MRJ version: " + mrjVersion;
+ }
+ } else if (osName.startsWith("Windows")) {
+ if (osName.indexOf("9") != -1) {
+ jvm = WINDOWS_9x;
+ } else {
+ jvm = WINDOWS_NT;
+ }
+ } else {
+ jvm = OTHER;
+ }
+
+ if (loadedWithoutErrors) { // if we haven't hit any errors yet
+ loadedWithoutErrors = loadClasses();
+ }
+ }
+
+ /**
+ * This class should be never be instantiated; this just ensures so.
+ */
+ private EjAlbertBrowserLauncher() { }
+
+ /**
+ * Called by a static initializer to load any classes, fields, and methods required at runtime
+ * to locate the user's web browser.
+ * @return <code>true</code> if all intialization succeeded
+ * <code>false</code> if any portion of the initialization failed
+ */
+ private static boolean loadClasses() {
+ switch (jvm) {
+ case MRJ_2_0:
+ try {
+ Class aeTargetClass = Class.forName("com.apple.MacOS.AETarget");
+ Class osUtilsClass = Class.forName("com.apple.MacOS.OSUtils");
+ Class appleEventClass = Class.forName("com.apple.MacOS.AppleEvent");
+ Class aeClass = Class.forName("com.apple.MacOS.ae");
+ aeDescClass = Class.forName("com.apple.MacOS.AEDesc");
+
+ aeTargetConstructor = aeTargetClass.getDeclaredConstructor(new Class [] { int.class });
+ appleEventConstructor = appleEventClass.getDeclaredConstructor(new Class[] { int.class, int.class, aeTargetClass, int.class, int.class });
+ aeDescConstructor = aeDescClass.getDeclaredConstructor(new Class[] { String.class });
+
+ makeOSType = osUtilsClass.getDeclaredMethod("makeOSType", new Class [] { String.class });
+ putParameter = appleEventClass.getDeclaredMethod("putParameter", new Class[] { int.class, aeDescClass });
+ sendNoReply = appleEventClass.getDeclaredMethod("sendNoReply", new Class[] { });
+
+ Field keyDirectObjectField = aeClass.getDeclaredField("keyDirectObject");
+ keyDirectObject = (Integer) keyDirectObjectField.get(null);
+ Field autoGenerateReturnIDField = appleEventClass.getDeclaredField("kAutoGenerateReturnID");
+ kAutoGenerateReturnID = (Integer) autoGenerateReturnIDField.get(null);
+ Field anyTransactionIDField = appleEventClass.getDeclaredField("kAnyTransactionID");
+ kAnyTransactionID = (Integer) anyTransactionIDField.get(null);
+ } catch (ClassNotFoundException cnfe) {
+ errorMessage = cnfe.getMessage();
+ return false;
+ } catch (NoSuchMethodException nsme) {
+ errorMessage = nsme.getMessage();
+ return false;
+ } catch (NoSuchFieldException nsfe) {
+ errorMessage = nsfe.getMessage();
+ return false;
+ } catch (IllegalAccessException iae) {
+ errorMessage = iae.getMessage();
+ return false;
+ }
+ break;
+ case MRJ_2_1:
+ try {
+ mrjFileUtilsClass = Class.forName("com.apple.mrj.MRJFileUtils");
+ mrjOSTypeClass = Class.forName("com.apple.mrj.MRJOSType");
+ Field systemFolderField = mrjFileUtilsClass.getDeclaredField("kSystemFolderType");
+ kSystemFolderType = systemFolderField.get(null);
+ findFolder = mrjFileUtilsClass.getDeclaredMethod("findFolder", new Class[] { mrjOSTypeClass });
+ getFileCreator = mrjFileUtilsClass.getDeclaredMethod("getFileCreator", new Class[] { File.class });
+ getFileType = mrjFileUtilsClass.getDeclaredMethod("getFileType", new Class[] { File.class });
+ } catch (ClassNotFoundException cnfe) {
+ errorMessage = cnfe.getMessage();
+ return false;
+ } catch (NoSuchFieldException nsfe) {
+ errorMessage = nsfe.getMessage();
+ return false;
+ } catch (NoSuchMethodException nsme) {
+ errorMessage = nsme.getMessage();
+ return false;
+ } catch (SecurityException se) {
+ errorMessage = se.getMessage();
+ return false;
+ } catch (IllegalAccessException iae) {
+ errorMessage = iae.getMessage();
+ return false;
+ }
+ break;
+ case MRJ_3_0:
+ try {
+ Class linker = Class.forName("com.apple.mrj.jdirect.Linker");
+ Constructor constructor = linker.getConstructor(new Class[]{ Class.class });
+ linkage = constructor.newInstance(new Object[] { EjAlbertBrowserLauncher.class });
+ } catch (ClassNotFoundException cnfe) {
+ errorMessage = cnfe.getMessage();
+ return false;
+ } catch (NoSuchMethodException nsme) {
+ errorMessage = nsme.getMessage();
+ return false;
+ } catch (InvocationTargetException ite) {
+ errorMessage = ite.getMessage();
+ return false;
+ } catch (InstantiationException ie) {
+ errorMessage = ie.getMessage();
+ return false;
+ } catch (IllegalAccessException iae) {
+ errorMessage = iae.getMessage();
+ return false;
+ }
+ break;
+ case MRJ_3_1:
+ try {
+ mrjFileUtilsClass = Class.forName("com.apple.mrj.MRJFileUtils");
+ openURLm = mrjFileUtilsClass.getDeclaredMethod("openURL", new Class[] { String.class });
+ } catch (ClassNotFoundException cnfe) {
+ errorMessage = cnfe.getMessage();
+ return false;
+ } catch (NoSuchMethodException nsme) {
+ errorMessage = nsme.getMessage();
+ return false;
+ }
+ break;
+ default:
+ break;
+ }
+ return true;
+ }
+
+ /**
+ * Attempts to locate the default web browser on the local system. Caches results so it
+ * only locates the browser once for each use of this class per JVM instance.
+ * @return The browser for the system. Note that this may not be what you would consider
+ * to be a standard web browser; instead, it's the application that gets called to
+ * open the default web browser. In some cases, this will be a non-String object
+ * that provides the means of calling the default browser.
+ */
+ private static Object locateBrowser() {
+ if (browser != null) {
+ return browser;
+ }
+ switch (jvm) {
+ case MRJ_2_0:
+ try {
+ Integer finderCreatorCode = (Integer) makeOSType.invoke(null, new Object[] { FINDER_CREATOR });
+ Object aeTarget = aeTargetConstructor.newInstance(new Object[] { finderCreatorCode });
+ Integer gurlType = (Integer) makeOSType.invoke(null, new Object[] { GURL_EVENT });
+ Object appleEvent = appleEventConstructor.newInstance(new Object[] { gurlType, gurlType, aeTarget, kAutoGenerateReturnID, kAnyTransactionID });
+ // Don't set browser = appleEvent because then the next time we call
+ // locateBrowser(), we'll get the same AppleEvent, to which we'll already have
+ // added the relevant parameter. Instead, regenerate the AppleEvent every time.
+ // There's probably a way to do this better; if any has any ideas, please let
+ // me know.
+ return appleEvent;
+ } catch (IllegalAccessException iae) {
+ browser = null;
+ errorMessage = iae.getMessage();
+ return browser;
+ } catch (InstantiationException ie) {
+ browser = null;
+ errorMessage = ie.getMessage();
+ return browser;
+ } catch (InvocationTargetException ite) {
+ browser = null;
+ errorMessage = ite.getMessage();
+ return browser;
+ }
+ case MRJ_2_1:
+ File systemFolder;
+ try {
+ systemFolder = (File) findFolder.invoke(null, new Object[] { kSystemFolderType });
+ } catch (IllegalArgumentException iare) {
+ browser = null;
+ errorMessage = iare.getMessage();
+ return browser;
+ } catch (IllegalAccessException iae) {
+ browser = null;
+ errorMessage = iae.getMessage();
+ return browser;
+ } catch (InvocationTargetException ite) {
+ browser = null;
+ errorMessage = ite.getTargetException().getClass() + ": " + ite.getTargetException().getMessage();
+ return browser;
+ }
+ String[] systemFolderFiles = systemFolder.list();
+ // Avoid a FilenameFilter because that can't be stopped mid-list
+ for(int i = 0; i < systemFolderFiles.length; i++) {
+ try {
+ File file = new File(systemFolder, systemFolderFiles[i]);
+ if (!file.isFile()) {
+ continue;
+ }
+ // We're looking for a file with a creator code of 'MACS' and
+ // a type of 'FNDR'. Only requiring the type results in non-Finder
+ // applications being picked up on certain Mac OS 9 systems,
+ // especially German ones, and sending a GURL event to those
+ // applications results in a logout under Multiple Users.
+ Object fileType = getFileType.invoke(null, new Object[] { file });
+ if (FINDER_TYPE.equals(fileType.toString())) {
+ Object fileCreator = getFileCreator.invoke(null, new Object[] { file });
+ if (FINDER_CREATOR.equals(fileCreator.toString())) {
+ browser = file.toString(); // Actually the Finder, but that's OK
+ return browser;
+ }
+ }
+ } catch (IllegalArgumentException iare) {
+ browser = browser;
+ errorMessage = iare.getMessage();
+ return null;
+ } catch (IllegalAccessException iae) {
+ browser = null;
+ errorMessage = iae.getMessage();
+ return browser;
+ } catch (InvocationTargetException ite) {
+ browser = null;
+ errorMessage = ite.getTargetException().getClass() + ": " + ite.getTargetException().getMessage();
+ return browser;
+ }
+ }
+ browser = null;
+ break;
+ case MRJ_3_0:
+ case MRJ_3_1:
+ browser = ""; // Return something non-null
+ break;
+ case WINDOWS_NT:
+ browser = "cmd.exe";
+ break;
+ case WINDOWS_9x:
+ browser = "command.com";
+ break;
+ case OTHER:
+ default:
+ browser = "netscape";
+ break;
+ }
+ return browser;
+ }
+
+ /**
+ * Attempts to open the default web browser to the given URL.
+ * @param url The URL to open
+ * @throws IOException If the web browser could not be located or does not run
+ */
+ public static void openURL(String url) throws IOException {
+ if (!loadedWithoutErrors) {
+ throw new IOException("Exception in finding browser: " + errorMessage);
+ }
+ Object browser = locateBrowser();
+ if (browser == null) {
+ throw new IOException("Unable to locate browser: " + errorMessage);
+ }
+
+ switch (jvm) {
+ case MRJ_2_0:
+ Object aeDesc = null;
+ try {
+ aeDesc = aeDescConstructor.newInstance(new Object[] { url });
+ putParameter.invoke(browser, new Object[] { keyDirectObject, aeDesc });
+ sendNoReply.invoke(browser, new Object[] { });
+ } catch (InvocationTargetException ite) {
+ throw new IOException("InvocationTargetException while creating AEDesc: " + ite.getMessage());
+ } catch (IllegalAccessException iae) {
+ throw new IOException("IllegalAccessException while building AppleEvent: " + iae.getMessage());
+ } catch (InstantiationException ie) {
+ throw new IOException("InstantiationException while creating AEDesc: " + ie.getMessage());
+ } finally {
+ aeDesc = null; // Encourage it to get disposed if it was created
+ browser = null; // Ditto
+ }
+ break;
+ case MRJ_2_1:
+ Runtime.getRuntime().exec(new String[] { (String) browser, url } );
+ break;
+ case MRJ_3_0:
+ int[] instance = new int[1];
+ int result = ICStart(instance, 0);
+ if (result == 0) {
+ int[] selectionStart = new int[] { 0 };
+ byte[] urlBytes = url.getBytes();
+ int[] selectionEnd = new int[] { urlBytes.length };
+ result = ICLaunchURL(instance[0], new byte[] { 0 }, urlBytes,
+ urlBytes.length, selectionStart,
+ selectionEnd);
+ if (result == 0) {
+ // Ignore the return value; the URL was launched successfully
+ // regardless of what happens here.
+ ICStop(instance);
+ } else {
+ throw new IOException("Unable to launch URL: " + result);
+ }
+ } else {
+ throw new IOException("Unable to create an Internet Config instance: " + result);
+ }
+ break;
+ case MRJ_3_1:
+ try {
+ openURLm.invoke(null, new Object[] { url });
+ } catch (InvocationTargetException ite) {
+ throw new IOException("InvocationTargetException while calling openURL: " + ite.getMessage());
+ } catch (IllegalAccessException iae) {
+ throw new IOException("IllegalAccessException while calling openURL: " + iae.getMessage());
+ }
+ break;
+ case WINDOWS_NT:
+ case WINDOWS_9x:
+ // Add quotes around the URL to allow ampersands and other special
+ // characters to work.
+ Process process = Runtime.getRuntime().exec(new String[] { (String) browser,
+ FIRST_WINDOWS_PARAMETER,
+ SECOND_WINDOWS_PARAMETER,
+ THIRD_WINDOWS_PARAMETER,
+ '"' + url + '"' });
+ // This avoids a memory leak on some versions of Java on Windows.
+ // That's hinted at in <http://developer.java.sun.com/developer/qow/archive/68/>.
+ try {
+ process.waitFor();
+ process.exitValue();
+ } catch (InterruptedException ie) {
+ throw new IOException("InterruptedException while launching browser: " + ie.getMessage());
+ }
+ break;
+ case OTHER:
+ // Assume that we're on Unix and that Netscape is installed
+
+ // First, attempt to open the URL in a currently running session of Netscape
+ process = Runtime.getRuntime().exec(new String[] { (String) browser,
+ NETSCAPE_REMOTE_PARAMETER,
+ NETSCAPE_OPEN_PARAMETER_START +
+ url +
+ NETSCAPE_OPEN_PARAMETER_END });
+ try {
+ int exitCode = process.waitFor();
+ if (exitCode != 0) { // if Netscape was not open
+ Runtime.getRuntime().exec(new String[] { (String) browser, url });
+ }
+ } catch (InterruptedException ie) {
+ throw new IOException("InterruptedException while launching browser: " + ie.getMessage());
+ }
+ break;
+ default:
+ // This should never occur, but if it does, we'll try the simplest thing possible
+ Runtime.getRuntime().exec(new String[] { (String) browser, url });
+ break;
+ }
+ }
+
+ /**
+ * Methods required for Mac OS X. The presence of native methods does not cause
+ * any problems on other platforms.
+ */
+ /*
+ private native static int ICStart(int[] instance, int signature);
+ private native static int ICStop(int[] instance);
+ private native static int ICLaunchURL(int instance, byte[] hint, byte[] data, int len,
+ int[] selectionStart, int[] selectionEnd);
+ */
+ private static int ICStart(int[] instance, int signature) { return 0; }
+ private static int ICStop(int[] instance) { return 0; }
+ private static int ICLaunchURL(int instance, byte[] hint, byte[] data, int len,
+ int[] selectionStart, int[] selectionEnd) { return 0; }
+}
--- /dev/null
+package org.ibex.util;
+
+import org.ibex.js.*;
+
+public abstract class Grammar extends JS {
+
+ public JS action = null;
+
+ // means we call()ed a Grammar that hasn't been bound to a scope yet
+ public Object call(Object a0, Object a1, Object a2, Object[] rest, int nargs) throws JSExn {
+ throw new Error("this should never happen");
+ }
+
+ private static Object NULL = new Object();
+
+ public abstract int match(String s, int start, Hash v, JSScope scope) throws JSExn;
+ public int matchAndWrite(final String s, final int start, Hash v, JSScope scope, String key) throws JSExn {
+ final Hash v2 = new Hash();
+ final int ret = match(s, start, v2, scope);
+ Object result = ret == -1 ? NULL : action == null ?
+ s.substring(start, ret) :
+ JS.cloneWithNewParentScope(action, new JSScope(scope) {
+ public Object get(Object key) throws JSExn {
+ Object val = v2.get(key);
+ if (val == NULL) return null;
+ if (val != null) return val;
+ if (key.equals("whole")) return s.substring(start, ret);
+ return super.get(key);
+ }
+ }).call(null, null, null, null, 0);
+ if (key != null) {
+ Object old = v.get(key);
+ if (old == null || old == NULL) { }
+ else if (old instanceof JSArray) { if (result != NULL) { ((JSArray)old).addElement(result); result = old; } }
+ else if (result != NULL) { JSArray j = new JSArray(); j.addElement(old); j.addElement(result); result = j; }
+ v.put(key, result);
+ }
+ return ret;
+ }
+
+ public static class Alternative extends Grammar {
+ private Grammar r1, r2;
+ public Alternative(Grammar r1, Grammar r2) { this.r1 = r1; this.r2 = r2; }
+ public int match(String s, int start, Hash v, JSScope r) throws JSExn {
+ int s1 = r1.match(s, start, v, r);
+ if (s1 != -1) return s1;
+ int s2 = r2.match(s, start, v, r);
+ if (s2 != -1) return s2;
+ return -1;
+ }
+ }
+
+ public static class Juxtaposition extends Grammar {
+ private Grammar r1, r2;
+ public Juxtaposition(Grammar r1, Grammar r2) { this.r1 = r1; this.r2 = r2; }
+ public int match(String s, int start, Hash v, JSScope r) throws JSExn {
+ int s1 = r1.match(s, start, v, r);
+ if (s1 == -1) return -1;
+ int s2 = r2.match(s, s1, v, r);
+ if (s2 == -1) return -1;
+ return s2;
+ }
+ }
+
+ public static class Repetition extends Grammar {
+ private Grammar r1;
+ private int min, max;
+ public Repetition(Grammar r1, int min, int max) { this.r1 = r1; this.min = min; this.max = max; }
+ public int match(String s, int start, Hash v, JSScope r) throws JSExn {
+ int i;
+ for(i=0; i<max; i++) {
+ start = r1.match(s, start, v, r);
+ if (start == -1) return -1;
+ }
+ if (i < min) return -1;
+ return start;
+ }
+ }
+
+ public static class Literal extends Grammar {
+ String str;
+ public Literal(String str) { this.str = str; }
+ public int match(String s, int start, Hash v, JSScope r) {
+ if (!s.regionMatches(start, str, 0, str.length())) return -1;
+ return start + str.length();
+ }
+ }
+
+ public static class Range extends Grammar {
+ char min, max;
+ public Range(char min, char max) { this.min = min; this.max = max; }
+ public int match(String s, int start, Hash v, JSScope r) throws JSExn {
+ if (!(s.charAt(start) >= min && s.charAt(start) <= max)) return -1;
+ return start + 1;
+ }
+ }
+
+ public static class Reference extends Grammar {
+ String key;
+ public Reference(String key) { this.key = key; }
+ public int match(String s, int start, Hash v, JSScope scope) throws JSExn {
+ return ((Grammar)scope.get(key)).matchAndWrite(s, start, v, scope, key);
+ }
+ }
+}
--- /dev/null
+// Copyright (C) 2003 Adam Megacz <adam@ibex.org> all rights reserved.
+//
+// You may modify, copy, and redistribute this code under the terms of
+// the GNU Library Public License version 2.1, with the exception of
+// the portion of clause 6a after the semicolon (aka the "obnoxious
+// relink clause")
+
+package org.ibex.util;
+
+import java.util.*;
+
+/** Implementation of an unsynchronized hash table, with one or two
+ * keys, using Radke's quadradic residue linear probing instead of
+ * buckets to minimize object count (less allocations, faster GC).
+ * See C. Radke, Communications of the ACM, 1970, 103-105
+ *
+ * Not threadsafe.
+ */
+public class Hash {
+ /** this object is inserted as key in a slot when the
+ * corresponding value is removed -- this ensures that the
+ * probing sequence for any given key remains the same even if
+ * other keys are removed.
+ */
+ private static Object placeholder = new Object();
+
+ /** the number of entries with at least one non-null key */
+ private int usedslots = 0;
+
+ /** the number of entries with non-null values */
+ protected int size = 0;
+
+ /** when num_slots < loadFactor * size, rehash into a bigger table */
+ private final int loadFactor;
+
+ /** primary keys */
+ private Object[] keys1 = null;
+
+ /** secondary keys; null if no secondary key has ever been added */
+ private Object[] keys2 = null;
+
+ /** the values for the table */
+ private Object[] vals = null;
+
+ /** the number of entries with a non-null value */
+ public int size() { return size; }
+
+ /** empties the table */
+ public void clear() {
+ size = 0;
+ usedslots = 0;
+ for(int i=0; i<vals.length; i++) {
+ vals[i] = null;
+ keys1[i] = null;
+ if (keys2 != null) keys2[i] = null;
+ }
+ }
+
+ /** returns all the primary keys in the table */
+ public Enumeration keys() { return new HashEnum(); }
+
+ public Hash() { this(25, 3); }
+ public Hash(int initialcapacity, int loadFactor) {
+ // using a pseudoprime in the form 4x+3 ensures full coverage
+ initialcapacity = initialcapacity / 4;
+ initialcapacity = 4 * initialcapacity + 3;
+ keys1 = new Object[initialcapacity];
+ vals = new Object[initialcapacity];
+ this.loadFactor = loadFactor;
+ }
+
+ public void remove(Object k1) { remove(k1, null); }
+ public void remove(Object k1, Object k2) { put_(k1, k2, null); }
+
+ private void rehash() {
+ Object[] oldkeys1 = keys1;
+ Object[] oldkeys2 = keys2;
+ Object[] oldvals = vals;
+ keys1 = new Object[oldvals.length * 2];
+ keys2 = oldkeys2 == null ? null : new Object[oldvals.length * 2];
+ vals = new Object[oldvals.length * 2];
+ size = 0;
+ usedslots = 0;
+ for(int i=0; i<oldvals.length; i++)
+ if (((oldkeys1[i] != null && oldkeys1[i] != placeholder) || (oldkeys2 != null && oldkeys2[i] != null)) && oldvals[i] != null)
+ put_(oldkeys1[i], oldkeys2 == null ? null : oldkeys2[i], oldvals[i]);
+ }
+
+ public Object get(Object k1) { return get(k1, null); }
+ public Object get(Object k1, Object k2) {
+ if (k2 != null && keys2 == null) return null;
+ int hash = (k1 == null ? 0 : k1.hashCode()) ^ (k2 == null ? 0 : k2.hashCode());
+ int dest = Math.abs(hash) % vals.length;
+ int odest = dest;
+ int tries = 1;
+ boolean plus = true;
+ while (keys1[dest] != null || (keys2 != null && keys2[dest] != null)) {
+ Object hk1 = keys1[dest];
+ Object hk2 = keys2 == null ? null : keys2[dest];
+ if ((k1 == hk1 || (k1 != null && hk1 != null && k1.equals(hk1))) &&
+ (k2 == hk2 || (k2 != null && hk2 != null && k2.equals(hk2)))) {
+ return vals[dest];
+ }
+ dest = Math.abs((odest + (plus ? 1 : -1 ) * tries * tries) % vals.length);
+ if (plus) tries++;
+ plus = !plus;
+ }
+ return null;
+ }
+
+ public void put(Object k1, Object v) { put(k1, null, v); }
+ public void put(Object k1, Object k2, Object v) { put_(k1, k2, v); }
+ private void put_(Object k1, Object k2, Object v) {
+ if (usedslots * loadFactor > vals.length) rehash();
+ int hash = (k1 == null ? 0 : k1.hashCode()) ^ (k2 == null ? 0 : k2.hashCode());
+ int dest = Math.abs(hash) % vals.length;
+ int odest = dest;
+ boolean plus = true;
+ int tries = 1;
+ while (true) {
+ Object hk1 = keys1[dest];
+ Object hk2 = keys2 == null ? null : keys2[dest];
+ if (hk1 == null && hk2 == null) { // empty slot
+ if (v == null) return;
+ size++;
+ usedslots++;
+ break;
+ }
+
+ if ((k1 == hk1 || (k1 != null && hk1 != null && k1.equals(hk1))) && // replacing former entry
+ (k2 == hk2 || (k2 != null && hk2 != null && k2.equals(hk2)))) {
+
+ // we don't actually remove things from the table; rather, we insert a placeholder
+ if (v == null) {
+ k1 = placeholder;
+ k2 = null;
+ size--;
+ }
+ break;
+ }
+
+ dest = Math.abs((odest + (plus ? 1 : -1 ) * tries * tries) % vals.length);
+ if (plus) tries++;
+ plus = !plus;
+ }
+
+ keys1[dest] = k1;
+ if (k2 != null && keys2 == null) keys2 = new Object[keys1.length];
+ if (keys2 != null) keys2[dest] = k2;
+ vals[dest] = v;
+ }
+
+ private class HashEnum implements java.util.Enumeration {
+ private int iterator = 0;
+ private int found = 0;
+
+ public boolean hasMoreElements() {
+ return found < usedslots;
+ }
+
+ public Object nextElement() {
+ if (!hasMoreElements()) throw new java.util.NoSuchElementException();
+
+ Object o = null;
+ while (o == null) o = keys1[iterator++];
+ if (o == null) throw new IllegalStateException("Didn't find an element, when I should have.");
+ found++;
+
+ return o;
+ }
+ }
+}
+
+
--- /dev/null
+// Copyright (C) 2003 Adam Megacz <adam@ibex.org> all rights reserved.
+//
+// You may modify, copy, and redistribute this code under the terms of
+// the GNU Library Public License version 2.1, with the exception of
+// the portion of clause 6a after the semicolon (aka the "obnoxious
+// relink clause")
+
+package org.ibex.util;
+import java.io.*;
+
+public class InputStreamToByteArray {
+
+ /** scratch space for isToByteArray() */
+ private static byte[] workspace = new byte[16 * 1024];
+
+ /** Trivial method to completely read an InputStream */
+ public static synchronized byte[] convert(InputStream is) throws IOException {
+ int pos = 0;
+ while (true) {
+ int numread = is.read(workspace, pos, workspace.length - pos);
+ if (numread == -1) break;
+ else if (pos + numread < workspace.length) pos += numread;
+ else {
+ pos += numread;
+ byte[] temp = new byte[workspace.length * 2];
+ System.arraycopy(workspace, 0, temp, 0, workspace.length);
+ workspace = temp;
+ }
+ }
+ byte[] ret = new byte[pos];
+ System.arraycopy(workspace, 0, ret, 0, pos);
+ return ret;
+ }
+
+}
--- /dev/null
+// Copyright (C) 2003 Adam Megacz <adam@ibex.org> all rights reserved.
+//
+// You may modify, copy, and redistribute this code under the terms of
+// the GNU Library Public License version 2.1, with the exception of
+// the portion of clause 6a after the semicolon (aka the "obnoxious
+// relink clause")
+
+package org.ibex.util;
+import java.io.*;
+
+/** a generic interface for things that "know" their length */
+public interface KnownLength {
+
+ public abstract int getLength();
+
+ public static class KnownLengthInputStream extends FilterInputStream implements KnownLength {
+ int length;
+ public int getLength() { return length; }
+ public KnownLengthInputStream(java.io.InputStream parent, int length) {
+ super(parent);
+ this.length = length;
+ }
+ }
+
+}
--- /dev/null
+package org.ibex.util;
+import java.io.*;
+
+public class LineReader {
+
+ private static int MAXBUF = 1024 * 16;
+ char[] buf = new char[MAXBUF];
+ int buflen = 0;
+ Reader r;
+ Vec pushback = new Vec();
+
+ public LineReader(Reader r) { this.r = r; }
+
+ public void pushback(String s) { pushback.push(s); }
+
+ public String readLine() throws IOException {
+ while(true) {
+ if (pushback.size() > 0) return (String)pushback.pop();
+ for(int i=0; i<buflen; i++) {
+ if (buf[i] == '\n') {
+ String ret;
+ if (buf[i-1] == '\r') ret = new String(buf, 0, i-1);
+ else ret = new String(buf, 0, i);
+ System.arraycopy(buf, i+1, buf, 0, buflen - (i+1));
+ buflen -= i+1;
+ return ret;
+ }
+ }
+ int numread = r.read(buf, buflen, MAXBUF - buflen);
+ if (numread == -1) {
+ if (buflen == 0) return null;
+ String ret = new String(buf, 0, buflen);
+ buflen = 0;
+ return ret;
+ } else {
+ buflen += numread;
+ }
+ }
+ }
+}
--- /dev/null
+// Copyright (C) 2003 Adam Megacz <adam@ibex.org> all rights reserved.
+//
+// You may modify, copy, and redistribute this code under the terms of
+// the GNU Library Public License version 2.1, with the exception of
+// the portion of clause 6a after the semicolon (aka the "obnoxious
+// relink clause")
+
+package org.ibex.util;
+import org.ibex.js.*;
+import java.io.*;
+import java.util.*;
+import java.net.*;
+
+/** easy to use logger */
+public class Log {
+
+ public static boolean on = true;
+ public static boolean rpc = false;
+ public static boolean color = false;
+ public static boolean verbose = false;
+ public static boolean logDates = false;
+ public static Date lastDate = null;
+
+ public static PrintStream logstream = System.err;
+
+ public static void email(String address) { throw new Error("FIXME not supported"); }
+ public static void file(String filename) throws IOException {
+ // FIXME security
+ logstream = new PrintStream(new FileOutputStream(filename));
+ }
+ public static void tcp(String host, int port) throws IOException {
+ // FIXME security
+ logstream = new PrintStream(new Socket(InetAddress.getByName(host), port).getOutputStream());
+ }
+
+ private static Hashtable threadAnnotations = new Hashtable();
+ public static void setThreadAnnotation(String s) { threadAnnotations.put(Thread.currentThread(), s); }
+
+ /** true iff nothing has yet been logged */
+ public static boolean firstMessage = true;
+
+ /** message can be a String or a Throwable */
+ public static synchronized void echo(Object o, Object message) { log(o, message, ECHO); }
+ public static synchronized void diag(Object o, Object message) { log(o, message, DIAGNOSTIC); }
+ public static synchronized void debug(Object o, Object message) { log(o, message, DEBUG); }
+ public static synchronized void info(Object o, Object message) { log(o, message, INFO); }
+ public static synchronized void warn(Object o, Object message) { log(o, message, WARN); }
+ public static synchronized void error(Object o, Object message) { log(o, message, ERROR); }
+
+ // these two logging levels serve ONLY to change the color; semantically they are the same as DEBUG
+ private static final int DIAGNOSTIC = -2;
+ private static final int ECHO = -1;
+
+ // the usual log4j levels, minus FAIL (we just throw an Error in that case)
+ public static final int DEBUG = 0;
+ public static final int INFO = 1;
+ public static final int WARN = 2;
+ public static final int ERROR = 3;
+ public static final int SILENT = Integer.MAX_VALUE;
+ public static int level = INFO;
+
+ private static final int BLUE = 34;
+ private static final int GREEN = 32;
+ private static final int CYAN = 36;
+ private static final int RED = 31;
+ private static final int PURPLE = 35;
+ private static final int BROWN = 33;
+ private static final int GRAY = 37;
+
+ private static String colorize(int color, boolean bright, String s) {
+ if (!Log.color) return s;
+ return
+ "\033[40;" + (bright?"1;":"") + color + "m" +
+ s +
+ "\033[0m";
+ }
+
+ private static String lastClassName = null;
+ private static synchronized void log(Object o, Object message, int level) {
+ if (level < Log.level) return;
+ if (firstMessage && !logDates) {
+ firstMessage = false;
+ logstream.println(colorize(GREEN, false, "==========================================================================="));
+
+ // FIXME later: causes problems with method pruning
+ //diag(Log.class, "Logging enabled at " + new java.util.Date());
+
+ if (color) diag(Log.class, "logging messages in " +
+ colorize(BLUE, true, "c") +
+ colorize(RED, true, "o") +
+ colorize(CYAN, true, "l") +
+ colorize(GREEN, true, "o") +
+ colorize(PURPLE, true, "r"));
+ }
+
+ String classname;
+ if (o instanceof Class) {
+ classname = ((Class)o).getName();
+ if (classname.indexOf('.') != -1) classname = classname.substring(classname.lastIndexOf('.') + 1);
+ }
+ else if (o instanceof String) classname = (String)o;
+ else classname = o.getClass().getName();
+
+ if (classname.equals(lastClassName)) classname = "";
+ else lastClassName = classname;
+
+ if (classname.length() > (logDates ? 14 : 20)) classname = classname.substring(0, (logDates ? 14 : 20));
+ while (classname.length() < (logDates ? 14 : 20)) classname = " " + classname;
+ classname = classname + (classname.trim().length() == 0 ? " " : ": ");
+ classname = colorize(GRAY, true, classname);
+ classname = classname.replace('$', '.');
+
+ if (logDates) {
+ Date d = new Date();
+ if (lastDate == null || d.getYear() != lastDate.getYear() || d.getMonth() != lastDate.getMonth() || d.getDay() != lastDate.getDay()) {
+ String now = new java.text.SimpleDateFormat("EEE dd MMM yyyy").format(d);
+ logstream.println();
+ logstream.println(colorize(GRAY, false, "=== " + now + " =========================================================="));
+ }
+ java.text.DateFormat df = new java.text.SimpleDateFormat("[EEE HH:mm:ss] ");
+ classname = df.format(d) + classname;
+ lastDate = d;
+ }
+
+ String annot = (String)threadAnnotations.get(Thread.currentThread());
+ if (annot != null) classname += annot;
+
+ if (message instanceof Throwable) {
+ if (level < ERROR) level = WARN;
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ((Throwable)message).printStackTrace(new PrintStream(baos));
+ byte[] b = baos.toByteArray();
+ BufferedReader br = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(b)));
+ String s = null;
+ try {
+ String m = "";
+ while((s = br.readLine()) != null) m += s + "\n";
+ if (m.length() > 0) log(o, m.substring(0, m.length() - 1), level);
+ } catch (IOException e) {
+ logstream.println(colorize(RED, true, "Logger: exception thrown by ByteArrayInputStream -- this should not happen"));
+ }
+ lastClassName = "";
+ return;
+ }
+
+ String str = message.toString();
+ if (str.indexOf('\n') != -1) lastClassName = "";
+ while(str.indexOf('\t') != -1)
+ str = str.substring(0, str.indexOf('\t')) + " " + str.substring(str.indexOf('\t') + 1);
+
+ classname = colorize(GRAY, false, classname);
+ int levelcolor = GRAY;
+ boolean bright = true;
+ switch (level) {
+ case DIAGNOSTIC: levelcolor = GREEN; bright = false; break;
+ case ECHO: levelcolor = BLUE; bright = true; break;
+ case DEBUG: levelcolor = BROWN; bright = true; break;
+ case INFO: levelcolor = GRAY; bright = false; break;
+ case WARN: levelcolor = BROWN; bright = false; break;
+ case ERROR: levelcolor = RED; bright = true; break;
+ }
+
+ while(str.indexOf('\n') != -1) {
+ logstream.println(classname + colorize(levelcolor, bright, str.substring(0, str.indexOf('\n'))));
+ classname = logDates ? " " : " ";
+ classname = colorize(GRAY,false,classname);
+ str = str.substring(str.indexOf('\n') + 1);
+ }
+ logstream.println(classname + colorize(levelcolor, bright, str));
+ }
+
+ public static void recursiveLog(String indent, String name, Object o) throws JSExn {
+ if (!name.equals("")) name += " : ";
+
+ if (o == null) {
+ JS.log(indent + name + "<null>");
+
+ } else if (o instanceof JSArray) {
+ JS.log(indent + name + "<array>");
+ JSArray na = (JSArray)o;
+ for(int i=0; i<na.length(); i++)
+ recursiveLog(indent + " ", i + "", na.elementAt(i));
+
+ } else if (o instanceof JS) {
+ JS.log(indent + name + "<object>");
+ JS s = (JS)o;
+ Enumeration e = s.keys();
+ while(e.hasMoreElements()) {
+ Object key = e.nextElement();
+ if (key != null)
+ recursiveLog(indent + " ", key.toString(),
+ (key instanceof Integer) ?
+ s.get(((Integer)key)) : s.get(key.toString()));
+ }
+ } else {
+ JS.log(indent + name + o);
+
+ }
+ }
+
+}
--- /dev/null
+package org.ibex.util;
+
+import org.ibex.core.Main;
+import org.ibex.util.*;
+import org.xwt.mips.*;
+import java.io.*;
+
+import org.xwt.mips.Runtime;
+
+public class MSPack {
+ private static byte[] image;
+
+ private String[] fileNames;
+ private int[] lengths;
+ private byte[][] data;
+
+ public static class MSPackException extends IOException { public MSPackException(String s) { super(s); } }
+
+ public MSPack(InputStream cabIS) throws IOException {
+ try {
+ Runtime vm = (Runtime)Class.forName("org.ibex.util.MIPSApps").newInstance();
+ byte[] cab = InputStreamToByteArray.convert(cabIS);
+ int cabAddr = vm.sbrk(cab.length);
+ if(cabAddr < 0) throw new MSPackException("sbrk failed");
+
+ vm.copyout(cab,cabAddr,cab.length);
+
+ vm.setUserInfo(0,cabAddr);
+ vm.setUserInfo(1,cab.length);
+
+ int status = vm.run(new String[]{ "mspack"} );
+ if(status != 0) throw new MSPackException("mspack.mips failed (" + status + ")");
+
+ /*static struct {
+ char *filename;
+ char *data;
+ int length;
+ } output_table[MAX_MEMBERS+1]; */
+
+ int filesTable = vm.getUserInfo(2);
+ int count=0;
+ while(vm.memRead(filesTable+count*12) != 0) count++;
+
+ fileNames = new String[count];
+ data = new byte[count][];
+ lengths = new int[count];
+
+ for(int i=0,addr=filesTable;i<count;i++,addr+=12) {
+ int length = vm.memRead(addr+8);
+ data[i] = new byte[length];
+ lengths[i] = length;
+ fileNames[i] = vm.cstring(vm.memRead(addr));
+ System.out.println("" + fileNames[i]);
+ vm.copyin(vm.memRead(addr+4),data[i],length);
+ }
+ } catch(Runtime.ExecutionException e) {
+ e.printStackTrace();
+ throw new MSPackException("mspack.mips crashed");
+ } catch(Exception e) {
+ throw new MSPackException(e.toString());
+ }
+ }
+
+ public String[] getFileNames() { return fileNames; }
+ public int[] getLengths() { return lengths; }
+ public InputStream getInputStream(int index) {
+ return new KnownLength.KnownLengthInputStream(new ByteArrayInputStream(data[index]), data[index].length);
+ }
+ public InputStream getInputStream(String fileName) {
+ for(int i=0;i<fileNames.length;i++) {
+ if(fileName.equalsIgnoreCase(fileNames[i])) return getInputStream(i);
+ }
+ return null;
+ }
+
+ public static void main(String[] args) throws IOException {
+ MSPack pack = new MSPack(new FileInputStream(args[0]));
+ String[] files = pack.getFileNames();
+ for(int i=0;i<files.length;i++)
+ System.out.println(i + ": " + files[i] + ": " + pack.getLengths()[i]);
+ System.out.println("Writing " + files[files.length-1]);
+ InputStream is = pack.getInputStream(files.length-1);
+ OutputStream os = new FileOutputStream(files[files.length-1]);
+ int n;
+ byte[] buf = new byte[4096];
+ while((n = is.read(buf)) != -1) os.write(buf,0,n);
+ os.close();
+ is.close();
+ }
+}
+
--- /dev/null
+// Copyright (C) 2003 Adam Megacz <adam@ibex.org> all rights reserved.
+//
+// You may modify, copy, and redistribute this code under the terms of
+// the GNU Library Public License version 2.1, with the exception of
+// the portion of clause 6a after the semicolon (aka the "obnoxious
+// relink clause")
+
+package org.ibex.util;
+
+/** packs 8-bit bytes into a String of 7-bit chars (to avoid the UTF-8 non-ASCII penalty) */
+public class PackBytesIntoString {
+
+ public static String pack(byte[] b, int off, int len) throws IllegalArgumentException {
+ if (len % 7 != 0) throw new IllegalArgumentException("len must be a multiple of 7");
+ StringBuffer ret = new StringBuffer();
+ for(int i=off; i<off+len; i += 7) {
+ long l = 0;
+ for(int j=6; j>=0; j--) {
+ l <<= 8;
+ l |= (b[i + j] & 0xff);
+ }
+ for(int j=0; j<8; j++) {
+ ret.append((char)(l & 0x7f));
+ l >>= 7;
+ }
+ }
+ return ret.toString();
+ }
+
+ public static byte[] unpack(String s) throws IllegalArgumentException {
+ if (s.length() % 8 != 0) throw new IllegalArgumentException("string length must be a multiple of 8");
+ byte[] ret = new byte[(s.length() / 8) * 7];
+ for(int i=0; i<s.length(); i += 8) {
+ long l = 0;
+ for(int j=7; j>=0; j--) {
+ l <<= 7;
+ l |= (s.charAt(i + j) & 0x7fL);
+ }
+ for(int j=0; j<7; j++) {
+ ret[(i / 8) * 7 + j] = (byte)(l & 0xff);
+ l >>= 8;
+ }
+ }
+ return ret;
+ }
+}
+
--- /dev/null
+// Copyright (C) 2003 Adam Megacz <adam@ibex.org> all rights reserved.
+//
+// You may modify, copy, and redistribute this code under the terms of
+// the GNU Library Public License version 2.1, with the exception of
+// the portion of clause 6a after the semicolon (aka the "obnoxious
+// relink clause")
+
+package org.ibex.util;
+
+/** A simple synchronized queue, implemented as an array */
+public class Queue {
+
+ public Queue(int initiallength) { vec = new Object[initiallength]; }
+
+ /** The store */
+ private Object[] vec;
+
+ /** The index of the first node in the queue */
+ private int first = 0;
+
+ /** The number of elements in the queue; INVARAINT: size <= vec.length */
+ private int size = 0;
+
+ /** Grow the queue, if needed */
+ private void grow(int newlength) {
+ Object[] newvec = new Object[newlength];
+ if (first + size > vec.length) {
+ System.arraycopy(vec, first, newvec, 0, vec.length - first);
+ System.arraycopy(vec, 0, newvec, vec.length - first, size - (vec.length - first));
+ } else {
+ System.arraycopy(vec, first, newvec, 0, size);
+ }
+ first = 0;
+ vec = newvec;
+ }
+
+ /** The number of elements in the queue */
+ public int size() { return size; }
+
+ /** Empties the queue */
+ public synchronized void flush() {
+ first = 0;
+ size = 0;
+ for(int i=0; i<vec.length; i++) vec[i] = null;
+ }
+
+ /** Add an element to the front of the queue */
+ public synchronized void prepend(Object o) {
+ if (size == vec.length) grow(vec.length * 2);
+ first--;
+ if (first < 0) first += vec.length;
+ vec[first] = o;
+ size++;
+ if (size == 1) notify();
+ }
+
+ /** Add an element to the back of the queue */
+ public synchronized void append(Object o) {
+ if (size == vec.length) grow(vec.length * 2);
+ if (first + size >= vec.length) vec[first + size - vec.length] = o;
+ else vec[first + size] = o;
+ size++;
+ if (size == 1) notify();
+ }
+
+ /** Remove and return and element from the queue, blocking if empty. */
+ public Object remove() { return remove(true); }
+
+ /** Remove and return an element from the queue, blocking if
+ <tt>block</tt> is true and the queue is empty. */
+ public synchronized Object remove(boolean block) {
+
+ while (size == 0 && block) {
+ try { wait(); } catch (InterruptedException e) { }
+ }
+
+ if (!block && size == 0) return null;
+ Object ret = vec[first];
+ first++;
+ size--;
+ if (first >= vec.length) first = 0;
+ return ret;
+ }
+
+ /** Returns the top element in the queue without removing it */
+ public synchronized Object peek() {
+ if (size == 0) return null;
+ return vec[first];
+ }
+
+}
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.util;
+
+import java.io.IOException;
+
+import org.ibex.js.*;
+import org.ibex.util.*;
+import org.ibex.graphics.*;
+import org.ibex.plat.*;
+
+/** Implements cooperative multitasking */
+public class Scheduler {
+
+ // Public API Exposed to org.ibex /////////////////////////////////////////////////
+
+ private static Scheduler singleton;
+ public static void add(Task t) { Log.debug(Scheduler.class, "scheduling " + t); Scheduler.runnable.append(t); }
+ public static void init() { if (singleton == null) (singleton = Platform.getScheduler()).run(); }
+
+ private static Task current = null;
+
+ private static volatile boolean rendering = false;
+ private static volatile boolean again = false;
+
+ /** synchronizd so that we can safely call it from an event-delivery thread, in-context */
+ public static void renderAll() {
+ if (rendering) { again = true; return; }
+ synchronized(Scheduler.class) {
+ try {
+ rendering = true;
+ do {
+ // FEATURE: this could be cleaner
+ again = false;
+ for(int i=0; i<Surface.allSurfaces.size(); i++) {
+ Surface s = ((Surface)Surface.allSurfaces.elementAt(i));
+ do { s.render(); } while(s.abort);
+ }
+ } while(again);
+ } finally {
+ rendering = false;
+ }
+ }
+ }
+
+
+
+ // API which must be supported by subclasses /////////////////////////////////////
+
+ /**
+ * SCHEDULER INVARIANT: all scheduler implementations MUST invoke
+ * Surface.renderAll() after performing a Task if no tasks remain
+ * in the queue. A scheduler may choose to invoke
+ * Surface.renderAll() more often than that if it so chooses.
+ */
+ public void run() { defaultRun(); }
+ public Scheduler() { }
+
+
+ // Default Implementation //////////////////////////////////////////////////////
+
+ protected static Queue runnable = new Queue(50);
+ public void defaultRun() {
+ while(true) {
+ current = (Task)runnable.remove(true);
+ try {
+ // FIXME hideous
+ synchronized(this) {
+ for(int i=0; i<Surface.allSurfaces.size(); i++) {
+ Surface s = (Surface)Surface.allSurfaces.elementAt(i);
+ if (current instanceof JS) {
+ s._mousex = Integer.MAX_VALUE;
+ s._mousey = Integer.MAX_VALUE;
+ } else {
+ s._mousex = s.mousex;
+ s._mousey = s.mousey;
+ }
+ }
+ Log.debug(Scheduler.class, "performing " + current);
+ current.perform();
+ }
+ renderAll();
+ } catch (JSExn e) {
+ Log.info(Scheduler.class, "a JavaScript thread spawned with ibex.thread() threw an exception:");
+ Log.info(Scheduler.class,e);
+ } catch (Exception e) {
+ Log.info(Scheduler.class, "a Task threw an exception which was caught by the scheduler:");
+ Log.info(Scheduler.class, e);
+ } catch (Throwable t) {
+ t.printStackTrace();
+ }
+ // if an Error is thrown it will cause the engine to quit
+ }
+ }
+}
--- /dev/null
+// Copyright (C) 2003 Adam Megacz <adam@ibex.org> all rights reserved.
+//
+// You may modify, copy, and redistribute this code under the terms of
+// the GNU Library Public License version 2.1, with the exception of
+// the portion of clause 6a after the semicolon (aka the "obnoxious
+// relink clause")
+
+package org.ibex.util;
+
+/** Simple implementation of a blocking, counting semaphore. */
+public class Semaphore {
+
+ private int val = 0;
+
+ /** Decrement the counter, blocking if zero. */
+ public synchronized void block() {
+ while(val == 0) {
+ try {
+ wait();
+ } catch (InterruptedException e) {
+ } catch (Throwable e) {
+ if (Log.on) Log.info(this, "Exception in Semaphore.block(); this should never happen");
+ if (Log.on) Log.info(this, e);
+ }
+ }
+ val--;
+ }
+
+ /** Incremenet the counter. */
+ public synchronized void release() {
+ val++;
+ notify();
+ }
+
+}
--- /dev/null
+package org.ibex.util;
+import java.io.* ;
+import java.util.* ;
+
+public class Simplex {
+
+ public final static short FAIL = -1;
+
+ public final static short NULL = 0;
+ public final static short FALSE = 0;
+ public final static short TRUE = 1;
+
+ public final static short DEFNUMINV = 50;
+
+ /* solve status values */
+ public final static short OPTIMAL = 0;
+ public final static short MILP_FAIL = 1;
+ public final static short INFEASIBLE = 2;
+ public final static short UNBOUNDED = 3;
+ public final static short FAILURE = 4;
+ public final static short RUNNING = 5;
+
+ /* lag_solve extra status values */
+ public final static short FEAS_FOUND = 6;
+ public final static short NO_FEAS_FOUND = 7;
+ public final static short BREAK_BB = 8;
+
+ public final static short FIRST_NI = 0;
+ public final static short RAND_NI = 1;
+
+ public final static short LE = 0;
+ public final static short EQ = 1;
+ public final static short GE = 2;
+ public final static short OF = 3;
+
+ public final static short MAX_WARN_COUNT = 20;
+
+ public final static float DEF_INFINITE = (float)1e24; /* limit for dynamic range */
+ public final static float DEF_EPSB = (float)5.01e-7; /* for rounding RHS values to 0 determine
+ infeasibility basis */
+ public final static float DEF_EPSEL = (float)1e-8; /* for rounding other values (vectors) to 0 */
+ public final static float DEF_EPSD = (float)1e-6; /* for rounding reduced costs to zero */
+ public final static float DEF_EPSILON = (float)1e-3; /* to determine if a float value is integer */
+
+ public final static float PREJ = (float)1e-3; /* pivot reject (try others first) */
+
+ public final static int ETA_START_SIZE = 10000; /* start size of array Eta. Realloced if needed */
+
+ static class Ref {
+ float value;
+ public Ref(float v) { value = v; }
+ }
+
+ //public static class Simplex {
+ /* Globals used by solver */
+ short JustInverted;
+ short Status;
+ short Doiter;
+ short DoInvert;
+ short Break_bb;
+
+ public short active; /*TRUE if the globals point to this structure*/
+ public short debug; /* ## Print B&B information */
+ public short trace; /* ## Print information on pivot selection */
+ public int rows; /* Nr of constraint rows in the problem */
+ int rows_alloc; /* The allocated memory for Rows sized data */
+ int columns_alloc;
+ int sum; /* The size of the variables + the slacks */
+ int sum_alloc;
+ int non_zeros; /* The number of elements in the sparce matrix*/
+ int mat_alloc; /* The allocated size for matrix sized
+ structures */
+ MatrixArray mat; /* mat_alloc :The sparse matrix */
+ MatrixArray alternate_mat; /* mat_alloc :The sparse matrix */
+ int[] col_end; /* columns_alloc+1 :Cend[i] is the index of the
+ first element after column i.
+ column[i] is stored in elements
+ col_end[i-1] to col_end[i]-1 */
+ int[] col_no; /* mat_alloc :From Row 1 on, col_no contains the
+ column nr. of the
+ nonzero elements, row by row */
+ short row_end_valid; /* true if row_end & col_no are valid */
+ int[] row_end; /* rows_alloc+1 :row_end[i] is the index of the
+ first element in Colno after row i */
+ float[] orig_rh; /* rows_alloc+1 :The RHS after scaling & sign
+ changing, but before `Bound transformation' */
+ float[] rh; /* rows_alloc+1 :As orig_rh, but after Bound
+ transformation */
+ float[] rhs; /* rows_alloc+1 :The RHS of the curent simplex
+ tableau */
+ float[] orig_upbo; /* sum_alloc+1 :Bound before transformations */
+ float[] orig_lowbo; /* " " */
+ float[] upbo; /* " " :Upper bound after transformation
+ & B&B work*/
+ float[] lowbo; /* " " :Lower bound after transformation
+ & B&B work */
+
+ short basis_valid; /* TRUE is the basis is still valid */
+ int[] bas; /* rows_alloc+1 :The basis column list */
+ short[] basis; /* sum_alloc+1 : basis[i] is TRUE if the column
+ is in the basis */
+ short[] lower; /* " " :TRUE is the variable is at its
+ lower bound (or in the basis), it is FALSE
+ if the variable is at its upper bound */
+
+ short eta_valid; /* TRUE if current Eta structures are valid */
+ int eta_alloc; /* The allocated memory for Eta */
+ int eta_size; /* The number of Eta columns */
+ int num_inv; /* The number of float pivots */
+ int max_num_inv; /* ## The number of float pivots between
+ reinvertions */
+ float[] eta_value; /* eta_alloc :The Structure containing the
+ values of Eta */
+ int[] eta_row_nr; /* " " :The Structure containing the Row
+ indexes of Eta */
+ int[] eta_col_end; /* rows_alloc + MaxNumInv : eta_col_end[i] is
+ the start index of the next Eta column */
+
+ short bb_rule; /* what rule for selecting B&B variables */
+
+ short break_at_int; /* TRUE if stop at first integer better than
+ break_value */
+ float break_value;
+
+ float obj_bound; /* ## Objective function bound for speedup of
+ B&B */
+ int iter; /* The number of iterations in the simplex
+ solver () */
+ int total_iter; /* The total number of iterations (B&B) (ILP)*/
+ int max_level; /* The Deepest B&B level of the last solution */
+ int total_nodes; /* total number of nodes processed in b&b */
+ public float[] solution; /* sum_alloc+1 :The Solution of the last LP,
+ 0 = The Optimal Value,
+ 1..rows The Slacks,
+ rows+1..sum The Variables */
+ public float[] best_solution; /* " " :The Best 'Integer' Solution */
+ float[] duals; /* rows_alloc+1 :The dual variables of the
+ last LP */
+
+ short maximise; /* TRUE if the goal is to maximise the
+ objective function */
+ short floor_first; /* TRUE if B&B does floor bound first */
+ short[] ch_sign; /* rows_alloc+1 :TRUE if the Row in the matrix
+ has changed sign
+ (a`x > b, x>=0) is translated to
+ s + -a`x = -b with x>=0, s>=0) */
+
+ int nr_lagrange; /* Nr. of Langrangian relaxation constraints */
+ float[][]lag_row; /* NumLagrange, columns+1:Pointer to pointer of
+ rows */
+ float[] lag_rhs; /* NumLagrange :Pointer to pointer of Rhs */
+ float[] lambda; /* NumLagrange :Lambda Values */
+ short[] lag_con_type; /* NumLagrange :TRUE if constraint type EQ */
+ float lag_bound; /* the lagrangian lower bound */
+
+ short valid; /* Has this lp pased the 'test' */
+ float infinite; /* ## numercal stuff */
+ float epsilon; /* ## */
+ float epsb; /* ## */
+ float epsd; /* ## */
+ float epsel; /* ## */
+
+ int Rows;
+ int columns;
+ int Sum;
+ int Non_zeros;
+ int Level;
+ MatrixArray Mat;
+ int[] Col_no;
+ int[] Col_end;
+ int[] Row_end;
+ float[] Orig_rh;
+ float[] Rh;
+ float[] Rhs;
+ float[] Orig_upbo;
+ float[] Orig_lowbo;
+ float[] Upbo;
+ float[] Lowbo;
+ int[] Bas;
+ short[] Basis;
+ short[] Lower;
+ int Eta_alloc;
+ int Eta_size;
+ float[] Eta_value;
+ int[] Eta_row_nr;
+ int[] Eta_col_end;
+ int Num_inv;
+ float[] Solution;
+ public float[] Best_solution;
+ float Infinite;
+ float Epsilon;
+ float Epsb;
+ float Epsd;
+ float Epsel;
+
+ float TREJ;
+ float TINV;
+
+ short Maximise;
+ short Floor_first;
+ float Extrad;
+
+ int Warn_count; /* used in CHECK version of rounding macro */
+
+ public Simplex (int nrows, int ncolumns, int matalloc) {
+ int nsum;
+ nsum=nrows+ncolumns;
+ rows=nrows;
+ columns=ncolumns;
+ sum=nsum;
+ rows_alloc=rows;
+ columns_alloc=columns;
+ sum_alloc=sum;
+ mat_alloc=matalloc;
+ eta_alloc=10000;
+ max_num_inv=DEFNUMINV;
+ col_no = new int[mat_alloc];
+ col_end = new int[columns + 1];
+ row_end = new int[rows + 1];
+ orig_rh = new float[rows + 1];
+ rh = new float[rows + 1];
+ rhs = new float[rows + 1];
+ orig_upbo = new float[sum + 1];
+ upbo = new float[sum + 1];
+ orig_lowbo = new float[sum + 1];
+ lowbo = new float[sum + 1];
+ bas = new int[rows+1];
+ basis = new short[sum + 1];
+ lower = new short[sum + 1];
+ eta_value = new float[eta_alloc];
+ eta_row_nr = new int[eta_alloc];
+ eta_col_end = new int[rows_alloc + max_num_inv];
+ solution = new float[sum + 1];
+ best_solution = new float[sum + 1];
+ duals = new float[rows + 1];
+ ch_sign = new short[rows + 1];
+ mat = new MatrixArray(mat_alloc);
+ alternate_mat = new MatrixArray(mat_alloc);
+ }
+
+ public void init(int ncolumns) {
+ int nsum;
+ int nrows = 0;
+ nsum=nrows+ncolumns;
+ active=FALSE;
+ debug=FALSE;
+ trace=FALSE;
+ rows=nrows;
+ columns=ncolumns;
+ sum=nsum;
+ obj_bound=DEF_INFINITE;
+ infinite=DEF_INFINITE;
+ epsilon=DEF_EPSILON;
+ epsb=DEF_EPSB;
+ epsd=DEF_EPSD;
+ epsel=DEF_EPSEL;
+ non_zeros=0;
+
+ for(int i = 0; i < col_end.length; i++) col_end[i] = 0;
+ for(int i = 0; i < rows + 1; i++) row_end[i] = 0;
+ for(int i = 0; i < rows + 1; i++) orig_rh[i] = 0;
+ for(int i = 0; i < rows + 1; i++) rh[i] = 0;
+ for(int i = 0; i < rows + 1; i++) rhs[i] = 0;
+ for(int i = 0; i <= sum; i++) orig_upbo[i]=infinite;
+ for(int i = 0; i < sum + 1; i++) upbo[i] = 0;
+ for(int i = 0; i < sum + 1; i++) orig_lowbo[i] = 0;
+ for(int i = 0; i < sum + 1; i++) lowbo[i] = 0;
+ for(int i = 0; i <= rows; i++) bas[i] = 0;
+ for(int i = 0; i <= sum; i++) basis[i] = 0;
+ for(int i = 0; i <= rows; i++) { bas[i]=i; basis[i]=TRUE; }
+ for(int i = rows + 1; i <= sum; i++) basis[i]=FALSE;
+ for(int i = 0 ; i <= sum; i++) lower[i]=TRUE;
+ for(int i = 0; i <= sum; i++) solution[i] = 0;
+ for(int i = 0; i <= sum; i++) best_solution[i] = 0;
+ for(int i = 0; i <= rows; i++) duals[i] = 0;
+ for(int i = 0; i <= rows; i++) ch_sign[i] = FALSE;
+
+ row_end_valid=FALSE;
+ bb_rule=FIRST_NI;
+ break_at_int=FALSE;
+ break_value=0;
+ iter=0;
+ total_iter=0;
+ basis_valid=TRUE;
+ eta_valid=TRUE;
+ eta_size=0;
+ nr_lagrange=0;
+ maximise = FALSE;
+ floor_first = TRUE;
+ valid = FALSE;
+ }
+
+ public void setObjective(float[] row, boolean maximize) {
+ for(int i=row.length-1; i>0; i--) row[i] = row[i-1];
+ row[0] = (float)0.0;
+ for(int j = 1; j <= columns; j++) {
+ int Row = 0;
+ int column = j;
+ float Value = row[j];
+ int elmnr, lastelm;
+
+ if(Row > rows || Row < 0) throw new Error("row out of range");
+ if(column > columns || column < 1) throw new Error("column out of range");
+
+ if (basis[column] == TRUE && Row > 0) basis_valid = FALSE;
+ eta_valid = FALSE;
+ elmnr = col_end[column-1];
+ while((elmnr < col_end[column]) ? (get_row_nr(mat, elmnr) != Row) : false) elmnr++;
+ if((elmnr != col_end[column]) ? (get_row_nr(mat, elmnr) == Row) : false ) {
+ if (ch_sign[Row] != FALSE) set_value(mat, elmnr, -Value);
+ else set_value(mat, elmnr, Value);
+ } else {
+ /* check if more space is needed for matrix */
+ if (non_zeros + 1 > mat_alloc) throw new Error("not enough mat space; this should not happen");
+ /* Shift the matrix */
+ lastelm=non_zeros;
+ for(int i = lastelm; i > elmnr ; i--) {
+ set_row_nr(mat,i,get_row_nr(mat,i-1));
+ set_value(mat,i,get_value(mat,i-1));
+ }
+ for(int i = column; i <= columns; i++) col_end[i]++;
+ /* Set new element */
+ set_row_nr(mat,elmnr, Row);
+ if (ch_sign[Row] != FALSE) set_value(mat, elmnr, -Value);
+ else set_value(mat, elmnr, Value);
+ row_end_valid=FALSE;
+ non_zeros++;
+ if (active != FALSE) Non_zeros=non_zeros;
+ }
+ }
+ if (maximize) {
+ if (maximise == FALSE) {
+ for(int i = 0; i < non_zeros; i++)
+ if(get_row_nr(mat, i)==0)
+ set_value(mat, i, get_value(mat,i)* (float)-1.0);
+ eta_valid=FALSE;
+ }
+ maximise=TRUE;
+ ch_sign[0]=TRUE;
+ if (active != FALSE) Maximise=TRUE;
+ } else {
+ if (maximise==TRUE) {
+ for(int i = 0; i < non_zeros; i++)
+ if(get_row_nr(mat, i)==0)
+ set_value(mat, i, get_value(mat,i) * (float)-1.0);
+ eta_valid=FALSE;
+ }
+ maximise=FALSE;
+ ch_sign[0]=FALSE;
+ if (active != FALSE) Maximise=FALSE;
+ }
+ }
+
+ public void add_constraint(float[] row, short constr_type, float rh) {
+ for(int i=row.length-1; i>0; i--) row[i] = row[i-1];
+ row[0] = (float)0.0;
+
+ MatrixArray newmat;
+ int elmnr;
+ int stcol;
+
+ newmat = alternate_mat;
+ for(int i = 0; i < non_zeros; i++) { set_row_nr(newmat,i, 0); set_value(newmat, i, 0); }
+ for(int i = 1; i <= columns; i++) if (row[i]!=0) non_zeros++;
+ if (non_zeros > mat_alloc) throw new Error("not enough mat space; this should not happen");
+ rows++;
+ sum++;
+ if(rows > rows_alloc) throw new Error("not enough rows; this should never happen");
+ if(constr_type==GE) ch_sign[rows] = TRUE;
+ else ch_sign[rows] = FALSE;
+
+ elmnr = 0;
+ stcol = 0;
+ for(int i = 1; i <= columns; i++) {
+ for(int j = stcol; j < col_end[i]; j++) {
+ set_row_nr(newmat,elmnr, get_row_nr(mat, j));
+ set_value(newmat, elmnr, get_value(mat,j));
+ elmnr++;
+ }
+ if(((i>=1 && i< columns && row[i]!=0)?TRUE:FALSE) != FALSE) {
+ if(ch_sign[rows] != FALSE) set_value(newmat, elmnr, -row[i]);
+ else set_value(newmat, elmnr, row[i]);
+ set_row_nr(newmat,elmnr, rows);
+ elmnr++;
+ }
+ stcol=col_end[i];
+ col_end[i]=elmnr;
+ }
+
+ alternate_mat = mat;
+ mat = newmat;
+
+ for(int i = sum ; i > rows; i--) {
+ orig_upbo[i]=orig_upbo[i-1];
+ orig_lowbo[i]=orig_lowbo[i-1];
+ basis[i]=basis[i-1];
+ lower[i]=lower[i-1];
+ }
+
+ for(int i = 1 ; i <= rows; i++) if(bas[i] >= rows) bas[i]++;
+
+ if(constr_type==LE || constr_type==GE) orig_upbo[rows]=infinite;
+ else if(constr_type==EQ) orig_upbo[rows]=0;
+ else throw new Error("Wrong constraint type\n");
+ orig_lowbo[rows]=0;
+
+ if(constr_type==GE && rh != 0) orig_rh[rows]=-rh;
+ else orig_rh[rows]=rh;
+
+ row_end_valid=FALSE;
+
+ bas[rows]=rows;
+ basis[rows]=TRUE;
+ lower[rows]=TRUE;
+
+ if (active != FALSE) set_globals();
+ eta_valid=FALSE;
+ }
+
+ public void bound_sum(int column1, int column2, float bound, short type, float[] scratch) {
+ for(int i=0; i<scratch.length; i++) scratch[i] = (float)0.0;
+ scratch[column1] = (float)1.0;
+ scratch[column2] = (float)1.0;
+ add_constraint(scratch, type, bound);
+ for(int i=0; i<scratch.length; i++) scratch[i] = (float)0.0;
+ }
+
+ public void bound_difference(int column1, int column2, float bound, short type, float[] scratch) {
+ for(int i=0; i<scratch.length; i++) scratch[i] = (float)0.0;
+ scratch[column1] = (float)1.0;
+ scratch[column2] = (float)-1.0;
+ add_constraint(scratch, type, bound);
+ for(int i=0; i<scratch.length; i++) scratch[i] = (float)0.0;
+ }
+
+ public void set_upbo(int column, float value) {
+ if(column > columns || column < 1) throw new Error("column out of range");
+ if(value < orig_lowbo[rows + column]) throw new Error("UpperBound must be >= lowerBound");
+ eta_valid = FALSE;
+ orig_upbo[rows+column] = value;
+ }
+
+ public void set_lowbo(int column, float value) {
+ if(column > columns || column < 1) throw new Error("column out of range");
+ if(value > orig_upbo[rows + column]) throw new Error("UpperBound must be >= lowerBound");
+ eta_valid = FALSE;
+ orig_lowbo[rows+column] = value;
+ }
+
+ public void set_rh(int row, float value) {
+ if(row > rows || row < 0) throw new Error("Row out of Range");
+ if(row == 0) throw new Error("Warning: attempt to set RHS of objective function, ignored");
+ if (ch_sign[row] != FALSE) orig_rh[row] = -value;
+ else orig_rh[row] = value;
+ eta_valid = FALSE;
+ }
+
+ public void set_rh_vec(float[] rh) {
+ for(int i=1; i <= rows; i++)
+ if (ch_sign[i] != FALSE) orig_rh[i]=-rh[i];
+ else orig_rh[i]=rh[i];
+ eta_valid=FALSE;
+ }
+
+
+ public void set_constr_type(int row, short con_type) {
+ if (row > rows || row < 1) throw new Error("Row out of Range");
+ switch(con_type) {
+ case EQ:
+ orig_upbo[row]=0;
+ basis_valid=FALSE;
+ if (ch_sign[row] != FALSE) {
+ for(int i = 0; i < non_zeros; i++)
+ if (get_row_nr(mat, i)==row) set_value(mat, i, get_value(mat,i) * (float)-1);
+ eta_valid=FALSE;
+ ch_sign[row]=FALSE;
+ if (orig_rh[row]!=0) orig_rh[row]*=-1;
+ }
+ break;
+ case LE:
+ orig_upbo[row]=infinite;
+ basis_valid=FALSE;
+ if (ch_sign[row] != FALSE) {
+ for(int i = 0; i < non_zeros; i++)
+ if (get_row_nr(mat, i)==row) set_value(mat, i, get_value(mat,i) * (float)-1);
+ eta_valid=FALSE;
+ ch_sign[row]=FALSE;
+ if (orig_rh[row]!=0) orig_rh[row]*=-1;
+ }
+ break;
+ case GE:
+ orig_upbo[row]=infinite;
+ basis_valid=FALSE;
+ if (ch_sign[row] == FALSE) {
+ for(int i = 0; i < non_zeros; i++)
+ if (get_row_nr(mat, i)==row) set_value(mat, i, get_value(mat,i) * (float)-1);
+ eta_valid=FALSE;
+ ch_sign[row]=TRUE;
+ if (orig_rh[row]!=0) orig_rh[row]*=-1;
+ }
+ break;
+ default: throw new Error("Constraint type not (yet) implemented");
+ }
+ }
+
+ void set_globals() {
+ Rows = rows;
+ columns = columns;
+ Sum = Rows + columns;
+ Non_zeros = non_zeros;
+ Mat = mat;
+ Col_no = col_no;
+ Col_end = col_end;
+ Row_end = row_end;
+ Rh = rh;
+ Rhs = rhs;
+ Orig_rh = orig_rh;
+ Orig_upbo = orig_upbo;
+ Orig_lowbo = orig_lowbo;
+ Upbo = upbo;
+ Lowbo = lowbo;
+ Bas = bas;
+ Basis = basis;
+ Lower = lower;
+ Eta_alloc = eta_alloc;
+ Eta_size = eta_size;
+ Num_inv = num_inv;
+ Eta_value = eta_value;
+ Eta_row_nr = eta_row_nr;
+ Eta_col_end = eta_col_end;
+ Solution = solution;
+ Best_solution = best_solution;
+ Infinite = infinite;
+ Epsilon = epsilon;
+ Epsb = epsb;
+ Epsd = epsd;
+ Epsel = epsel;
+ TREJ = TREJ;
+ TINV = TINV;
+ Maximise = maximise;
+ Floor_first = floor_first;
+ active = TRUE;
+ }
+
+ private void ftran(int start, int end, float[] pcol) {
+ int k, r;
+ float theta;
+ for(int i = start; i <= end; i++) {
+ k = Eta_col_end[i] - 1;
+ r = Eta_row_nr[k];
+ theta = pcol[r];
+ if (theta != 0) for(int j = Eta_col_end[i - 1]; j < k; j++)
+ pcol[Eta_row_nr[j]] += theta * Eta_value[j];
+ pcol[r] *= Eta_value[k];
+ }
+ for(int i = 0; i <= Rows; i++) round(pcol[i], Epsel);
+ }
+
+ private void btran(float[] row) {
+ int k;
+ float f;
+ for(int i = Eta_size; i >= 1; i--) {
+ f = 0;
+ k = Eta_col_end[i] - 1;
+ for(int j = Eta_col_end[i - 1]; j <= k; j++) f += row[Eta_row_nr[j]] * Eta_value[j];
+ f = round(f, Epsel);
+ row[Eta_row_nr[k]] = f;
+ }
+ }
+
+ static int[] num = new int[65535];
+ static int[] rownum = new int[65535];
+ static int[] colnum = new int[65535];
+
+ short Isvalid() {
+ int row_nr;
+ if (row_end_valid == FALSE) {
+ for(int i = 0; i <= rows; i++) { num[i] = 0; rownum[i] = 0; }
+ for(int i = 0; i < non_zeros; i++) rownum[get_row_nr(mat, i)]++;
+ row_end[0] = 0;
+ for(int i = 1; i <= rows; i++) row_end[i] = row_end[i - 1] + rownum[i];
+ for(int i = 1; i <= columns; i++)
+ for(int j = col_end[i - 1]; j < col_end[i]; j++) {
+ row_nr = get_row_nr(mat, j);
+ if (row_nr != 0) {
+ num[row_nr]++;
+ col_no[row_end[row_nr - 1] + num[row_nr]] = i;
+ }
+ }
+ row_end_valid = TRUE;
+ }
+ if (valid != FALSE) return(TRUE);
+ for(int i = 0; i <= rows; i++) rownum[i] = 0;
+ for(int i = 0; i <= columns; i++) colnum[i] = 0;
+ for(int i = 1 ; i <= columns; i++)
+ for(int j = col_end[i - 1]; j < col_end[i]; j++) {
+ colnum[i]++;
+ rownum[get_row_nr(mat, j)]++;
+ }
+ for(int i = 1; i <= columns; i++)
+ if (colnum[i] == 0)
+ throw new Error("Warning: Variable " + i + " not used in any constaints\n");
+ valid = TRUE;
+ return(TRUE);
+ }
+
+ private void resize_eta() {
+ Eta_alloc *= 2;
+ throw new Error("eta undersized; this should never happen");
+ /*
+ float[] db_ptr = Eta_value;
+ Eta_value = new float[Eta_alloc];
+ System.arraycopy(db_ptr, 0, Eta_value, 0, db_ptr.length);
+ eta_value = Eta_value;
+
+ int[] int_ptr = Eta_row_nr;
+ Eta_row_nr = new int[Eta_alloc];
+ System.arraycopy(int_ptr, 0, Eta_row_nr, 0, int_ptr.length);
+ eta_row_nr = Eta_row_nr;
+ */
+ }
+
+ private void condensecol(int row_nr, float[] pcol) {
+ int elnr;
+ elnr = Eta_col_end[Eta_size];
+ if (elnr + Rows + 2 > Eta_alloc) resize_eta();
+ for(int i = 0; i <= Rows; i++)
+ if (i != row_nr && pcol[i] != 0) {
+ Eta_row_nr[elnr] = i;
+ Eta_value[elnr] = pcol[i];
+ elnr++;
+ }
+ Eta_row_nr[elnr] = row_nr;
+ Eta_value[elnr] = pcol[row_nr];
+ elnr++;
+ Eta_col_end[Eta_size + 1] = elnr;
+ }
+
+ private void addetacol() {
+ int k;
+ float theta;
+ int j = Eta_col_end[Eta_size];
+ Eta_size++;
+ k = Eta_col_end[Eta_size];
+ theta = 1 / (float) Eta_value[k - 1];
+ Eta_value[k - 1] = theta;
+ for(int i = j; i < k - 1; i++) Eta_value[i] *= -theta;
+ JustInverted = FALSE;
+ }
+
+ private void setpivcol(short lower, int varin, float[] pcol) {
+ int colnr;
+ float f;
+ if (lower != FALSE) f = 1;
+ else f = -1;
+ for(int i = 0; i <= Rows; i++) pcol[i] = 0;
+ if (varin > Rows) {
+ colnr = varin - Rows;
+ for(int i = Col_end[colnr - 1]; i < Col_end[colnr]; i++) pcol[get_row_nr(Mat, i)] = get_value(Mat,i) * f;
+ pcol[0] -= Extrad * f;
+ } else {
+ if (lower != FALSE) pcol[varin] = 1;
+ else pcol[varin] = -1;
+ }
+ ftran(1, Eta_size, pcol);
+ }
+
+ private void minoriteration(int colnr, int row_nr) {
+ int k, wk, varin, varout, elnr;
+ float piv = 0, theta;
+ varin = colnr + Rows;
+ elnr = Eta_col_end[Eta_size];
+ wk = elnr;
+ Eta_size++;
+ if (Extrad != 0) {
+ Eta_row_nr[elnr] = 0;
+ Eta_value[elnr] = -Extrad;
+ elnr++;
+ }
+ for(int j = Col_end[colnr - 1] ; j < Col_end[colnr]; j++) {
+ k = get_row_nr(Mat, j);
+ if (k == 0 && Extrad != 0) Eta_value[Eta_col_end[Eta_size -1]] += get_value(Mat,j);
+ else if (k != row_nr) {
+ Eta_row_nr[elnr] = k;
+ Eta_value[elnr] = get_value(Mat,j);
+ elnr++;
+ } else {
+ piv = get_value(Mat,j);
+ }
+ }
+ Eta_row_nr[elnr] = row_nr;
+ Eta_value[elnr] = 1 / (float) piv;
+ elnr++;
+ theta = Rhs[row_nr] / (float) piv;
+ Rhs[row_nr] = theta;
+ for(int i = wk; i < elnr - 1; i++) Rhs[Eta_row_nr[i]] -= theta * Eta_value[i];
+ varout = Bas[row_nr];
+ Bas[row_nr] = varin;
+ Basis[varout] = FALSE;
+ Basis[varin] = TRUE;
+ for(int i = wk; i < elnr - 1; i++) Eta_value[i] /= - (float) piv;
+ Eta_col_end[Eta_size] = elnr;
+ }
+
+ private void rhsmincol(float theta, int row_nr, int varin) {
+ int varout;
+ float f;
+ if (row_nr > Rows + 1) {
+ System.err.println("Error: rhsmincol called with row_nr: " + row_nr + ", rows: " + Rows + "\n");
+ System.err.println("This indicates numerical instability\n");
+ }
+ int j = Eta_col_end[Eta_size];
+ int k = Eta_col_end[Eta_size + 1];
+ for(int i = j; i < k; i++) {
+ f = Rhs[Eta_row_nr[i]] - theta * Eta_value[i];
+ f = round(f, Epsb);
+ Rhs[Eta_row_nr[i]] = f;
+ }
+ Rhs[row_nr] = theta;
+ varout = Bas[row_nr];
+ Bas[row_nr] = varin;
+ Basis[varout] = FALSE;
+ Basis[varin] = TRUE;
+ }
+
+ private static int[] rownum_ = new int[65535];
+ private static int[] colnum_ = new int[65535];
+ private static int[] col = new int[65535];
+ private static int[] row = new int[65535];
+ private static float[] pcol = new float[65535];
+ private static short[] frow = new short[65535];
+ private static short[] fcol = new short[65535];
+
+ void invert() {
+ int v, wk, numit, varnr, row_nr, colnr, varin;
+ float theta;
+
+ for(int i = 0; i <= Rows; i++) rownum_[i] = 0;
+ for(int i = 0; i <= Rows; i++) col[i] = 0;
+ for(int i = 0; i <= Rows; i++) row[i] = 0;
+ for(int i = 0; i <= Rows; i++) pcol[i] = 0;
+ for(int i = 0; i <= Rows; i++) frow[i] = TRUE;
+ for(int i = 0; i < columns; i++) fcol[i] = FALSE;
+ for(int i = 0; i <= columns; i++) colnum_[i] = 0;
+
+ for(int i = 0; i <= Rows; i++)
+ if (Bas[i] > Rows) fcol[Bas[i] - Rows - 1] = TRUE;
+ else frow[Bas[i]] = FALSE;
+
+ for(int i = 1; i <= Rows; i++)
+ if (frow[i] != FALSE)
+ for(int j = Row_end[i - 1] + 1; j <= Row_end[i]; j++) {
+ wk = Col_no[j];
+ if (fcol[wk - 1] != FALSE) {
+ colnum_[wk]++;
+ rownum_[i - 1]++;
+ }
+ }
+
+ for(int i = 1; i <= Rows; i++) Bas[i] = i;
+ for(int i = 1; i <= Rows; i++) Basis[i] = TRUE;
+ for(int i = 1; i <= columns; i++) Basis[i + Rows] = FALSE;
+ for(int i = 0; i <= Rows; i++) Rhs[i] = Rh[i];
+ for(int i = 1; i <= columns; i++) {
+ varnr = Rows + i;
+ if (Lower[varnr] == FALSE) {
+ theta = Upbo[varnr];
+ for(int j = Col_end[i - 1]; j < Col_end[i]; j++)
+ Rhs[get_row_nr(Mat, j)] -= theta * get_value(Mat,j);
+ }
+ }
+ for(int i = 1; i <= Rows; i++) if (Lower[i] == FALSE) Rhs[i] -= Upbo[i];
+ Eta_size = 0;
+ v = 0;
+ row_nr = 0;
+ Num_inv = 0;
+ numit = 0;
+ while(v < Rows) {
+ int j;
+ row_nr++;
+ if (row_nr > Rows) row_nr = 1;
+ v++;
+ if (rownum_[row_nr - 1] == 1)
+ if (frow[row_nr] != FALSE) {
+ v = 0;
+ j = Row_end[row_nr - 1] + 1;
+ while(fcol[Col_no[j] - 1] == FALSE) j++;
+ colnr = Col_no[j];
+ fcol[colnr - 1] = FALSE;
+ colnum_[colnr] = 0;
+ for(j = Col_end[colnr - 1]; j < Col_end[colnr]; j++)
+ if (frow[get_row_nr(Mat, j)] != FALSE)
+ rownum_[get_row_nr(Mat, j) - 1]--;
+ frow[row_nr] = FALSE;
+ minoriteration(colnr, row_nr);
+ }
+ }
+ v = 0;
+ colnr = 0;
+ while(v < columns) {
+ int j;
+ colnr++;
+ if (colnr > columns) colnr = 1;
+ v++;
+ if (colnum_[colnr] == 1)
+ if (fcol[colnr - 1] != FALSE) {
+ v = 0;
+ j = Col_end[colnr - 1] + 1;
+ while(frow[get_row_nr(Mat, j - 1)] == FALSE) j++;
+ row_nr = get_row_nr(Mat, j - 1);
+ frow[row_nr] = FALSE;
+ rownum_[row_nr - 1] = 0;
+ for(j = Row_end[row_nr - 1] + 1; j <= Row_end[row_nr]; j++)
+ if (fcol[Col_no[j] - 1] != FALSE)
+ colnum_[Col_no[j]]--;
+ fcol[colnr - 1] = FALSE;
+ numit++;
+ col[numit - 1] = colnr;
+ row[numit - 1] = row_nr;
+ }
+ }
+ for(int j = 1; j <= columns; j++)
+ if (fcol[j - 1] != FALSE) {
+ fcol[j - 1] = FALSE;
+ setpivcol(Lower[Rows + j], j + Rows, pcol);
+ row_nr = 1;
+ while((frow[row_nr] == FALSE || pcol[row_nr] == FALSE) && row_nr <= Rows)
+ row_nr++; /* this sometimes sets row_nr to Rows + 1 and makes
+ rhsmincol crash. Solved in 2.0? MB */
+ if (row_nr == Rows + 1) throw new Error("Inverting failed");
+ frow[row_nr] = FALSE;
+ condensecol(row_nr, pcol);
+ theta = Rhs[row_nr] / (float) pcol[row_nr];
+ rhsmincol(theta, row_nr, Rows + j);
+ addetacol();
+ }
+ for(int i = numit - 1; i >= 0; i--) {
+ colnr = col[i];
+ row_nr = row[i];
+ varin = colnr + Rows;
+ for(int j = 0; j <= Rows; j++) pcol[j] = 0;
+ for(int j = Col_end[colnr - 1]; j < Col_end[colnr]; j++) pcol[get_row_nr(Mat, j)] = get_value(Mat,j);
+ pcol[0] -= Extrad;
+ condensecol(row_nr, pcol);
+ theta = Rhs[row_nr] / (float) pcol[row_nr];
+ rhsmincol(theta, row_nr, varin);
+ addetacol();
+ }
+ for(int i = 1; i <= Rows; i++) Rhs[i] = round(Rhs[i], Epsb);
+ JustInverted = TRUE;
+ DoInvert = FALSE;
+ }
+
+ private short colprim(Ref colnr, short minit, float[] drow) {
+ int varnr;
+ float f, dpiv;
+ dpiv = -Epsd;
+ colnr.value = 0;
+ if (minit == FALSE) {
+ for(int i = 1; i <= Sum; i++) drow[i] = 0;
+ drow[0] = 1;
+ btran(drow);
+ for(int i = 1; i <= columns; i++) {
+ varnr = Rows + i;
+ if (Basis[varnr] == FALSE)
+ if (Upbo[varnr] > 0) {
+ f = 0;
+ for(int j = Col_end[i - 1]; j < Col_end[i]; j++) f += drow[get_row_nr(Mat, j)] * get_value(Mat,j);
+ drow[varnr] = f;
+ }
+ }
+ for(int i = 1; i <= Sum; i++) drow[i] = round(drow[i], Epsd);
+ }
+ for(int i = 1; i <= Sum; i++)
+ if (Basis[i] == FALSE)
+ if (Upbo[i] > 0) {
+ if (Lower[i] != FALSE) f = drow[i];
+ else f = -drow[i];
+ if (f < dpiv) {
+ dpiv = f;
+ colnr.value = i;
+ }
+ }
+ if (colnr.value == 0) {
+ Doiter = FALSE;
+ DoInvert = FALSE;
+ Status = OPTIMAL;
+ }
+ return(colnr.value > 0 ? (short)1 : (short)0);
+ }
+
+ private short rowprim(int colnr, Ref row_nr, Ref theta, float[] pcol) {
+ float f = 0, quot;
+ row_nr.value = 0;
+ theta.value = Infinite;
+ for(int i = 1; i <= Rows; i++) {
+ f = pcol[i];
+ if (Math.abs(f) < TREJ) f = 0;
+ if (f != 0) {
+ quot = 2 * Infinite;
+ if (f > 0) quot = Rhs[i] / (float) f;
+ else if (Upbo[Bas[i]] < Infinite) quot = (Rhs[i] - Upbo[Bas[i]]) / (float) f;
+ round(quot, Epsel);
+ if (quot < theta.value) {
+ theta.value = quot;
+ row_nr.value = i;
+ }
+ }
+ }
+ if (row_nr.value == 0)
+ for(int i = 1; i <= Rows; i++) {
+ f = pcol[i];
+ if (f != 0) {
+ quot = 2 * Infinite;
+ if (f > 0) quot = Rhs[i] / (float) f;
+ else if (Upbo[Bas[i]] < Infinite) quot = (Rhs[i] - Upbo[Bas[i]]) / (float) f;
+ quot = round(quot, Epsel);
+ if (quot < theta.value) {
+ theta.value = quot;
+ row_nr.value = i;
+ }
+ }
+ }
+
+ if (theta.value < 0) throw new Error("Warning: Numerical instability, qout = " + theta.value);
+ if (row_nr.value == 0) {
+ if (Upbo[colnr] == Infinite) {
+ Doiter = FALSE;
+ DoInvert = FALSE;
+ Status = UNBOUNDED;
+ } else {
+ int i = 1;
+ while(pcol[i] >= 0 && i <= Rows) i++;
+ if (i > Rows) {
+ Lower[colnr] = FALSE;
+ Rhs[0] += Upbo[colnr]*pcol[0];
+ Doiter = FALSE;
+ DoInvert = FALSE;
+ } else if (pcol[i]<0) {
+ row_nr.value = i;
+ }
+ }
+ }
+ if (row_nr.value > 0) Doiter = TRUE;
+ return((row_nr.value > 0) ? (short)1 : (short)0);
+ }
+
+ private short rowdual(Ref row_nr) {
+ int i;
+ float f, g, minrhs;
+ short artifs;
+ row_nr.value = 0;
+ minrhs = -Epsb;
+ i = 0;
+ artifs = FALSE;
+ while(i < Rows && artifs == FALSE) {
+ i++;
+ f = Upbo[Bas[i]];
+ if (f == 0 && (Rhs[i] != 0)) {
+ artifs = TRUE;
+ row_nr.value = i;
+ } else {
+ if (Rhs[i] < f - Rhs[i]) g = Rhs[i];
+ else g = f - Rhs[i];
+ if (g < minrhs) {
+ minrhs = g;
+ row_nr.value = i;
+ }
+ }
+ }
+ return(row_nr.value > 0 ? (short)1 : (short)0);
+ }
+
+ private short coldual(int row_nr, Ref colnr, short minit, float[] prow, float[] drow) {
+ int r, varnr;
+ float theta, quot, pivot, d, f, g;
+ Doiter = FALSE;
+ if (minit == FALSE) {
+ for(int i = 0; i <= Rows; i++) {
+ prow[i] = 0;
+ drow[i] = 0;
+ }
+ drow[0] = 1;
+ prow[row_nr] = 1;
+ for(int i = Eta_size; i >= 1; i--) {
+ d = 0;
+ f = 0;
+ r = Eta_row_nr[Eta_col_end[i] - 1];
+ for(int j = Eta_col_end[i - 1]; j < Eta_col_end[i]; j++) {
+ /* this is where the program consumes most cpu time */
+ f += prow[Eta_row_nr[j]] * Eta_value[j];
+ d += drow[Eta_row_nr[j]] * Eta_value[j];
+ }
+ f = round(f, Epsel);
+ prow[r] = f;
+ d = round(d, Epsel);
+ drow[r] = d;
+ }
+ for(int i = 1; i <= columns; i++) {
+ varnr = Rows + i;
+ if (Basis[varnr] == FALSE) {
+ d = - Extrad * drow[0];
+ f = 0;
+ for(int j = Col_end[i - 1]; j < Col_end[i]; j++) {
+ d = d + drow[get_row_nr(Mat, j)] * get_value(Mat,j);
+ f = f + prow[get_row_nr(Mat, j)] * get_value(Mat,j);
+ }
+ drow[varnr] = d;
+ prow[varnr] = f;
+ }
+ }
+ for(int i = 0; i <= Sum; i++) {
+ prow[i] = round(prow[i], Epsel);
+ drow[i] = round(drow[i], Epsd);
+ }
+ }
+ if (Rhs[row_nr] > Upbo[Bas[row_nr]]) g = -1;
+ else g = 1;
+ pivot = 0;
+ colnr.value = 0;
+ theta = Infinite;
+ for(int i = 1; i <= Sum; i++) {
+ if (Lower[i] != FALSE) d = prow[i] * g;
+ else d = -prow[i] * g;
+ if ((d < 0) && (Basis[i] == FALSE) && (Upbo[i] > 0)) {
+ if (Lower[i] == FALSE) quot = -drow[i] / (float) d;
+ else quot = drow[i] / (float) d;
+ if (quot < theta) {
+ theta = quot;
+ pivot = d;
+ colnr.value = i;
+ } else if ((quot == theta) && (Math.abs(d) > Math.abs(pivot))) {
+ pivot = d;
+ colnr.value = i;
+ }
+ }
+ }
+ if (colnr.value > 0) Doiter = TRUE;
+ return(colnr.value > 0 ? (short)1 : (short)0);
+ }
+
+ private void iteration(int row_nr, int varin, Ref theta, float up, Ref minit, Ref low, short primal,float[] pcol) {
+ int k, varout;
+ float f;
+ float pivot;
+ iter++;
+ minit.value = theta.value > (up + Epsb) ? 1 : 0;
+ if (minit.value != 0) {
+ theta.value = up;
+ low.value = low.value == 0 ? 1 : 0;
+ }
+ k = Eta_col_end[Eta_size + 1];
+ pivot = Eta_value[k - 1];
+ for(int i = Eta_col_end[Eta_size]; i < k; i++) {
+ f = Rhs[Eta_row_nr[i]] - theta.value * Eta_value[i];
+ f = round(f, Epsb);
+ Rhs[Eta_row_nr[i]] = f;
+ }
+ if (minit.value == 0) {
+ Rhs[row_nr] = theta.value;
+ varout = Bas[row_nr];
+ Bas[row_nr] = varin;
+ Basis[varout] = FALSE;
+ Basis[varin] = TRUE;
+ if (primal != FALSE && pivot < 0) Lower[varout] = FALSE;
+ if (low.value == 0 && up < Infinite) {
+ low.value = TRUE;
+ Rhs[row_nr] = up - Rhs[row_nr];
+ for(int i = Eta_col_end[Eta_size]; i < k; i++) Eta_value[i] = -Eta_value[i];
+ }
+ addetacol();
+ Num_inv++;
+ }
+ }
+
+ static float[] drow = new float[65535];
+ static float[] prow = new float[65535];
+ static float[] Pcol = new float[65535];
+
+ private int solvelp() {
+ int varnr;
+ float f = 0, theta = 0;
+ short primal;
+ short minit;
+ int colnr, row_nr;
+ colnr = 0;
+ row_nr = 0;
+ short flag;
+ Ref ref1, ref2, ref3;
+ ref1 = new Ref(0);
+ ref2 = new Ref(0);
+ ref3 = new Ref(0);
+
+ for(int i = 0; i <= Sum; i++) { drow[i] = 0; prow[i] = 0; }
+ for(int i = 0; i <= Rows; i++) Pcol[i] = 0;
+ iter = 0;
+ minit = FALSE;
+ Status = RUNNING;
+ DoInvert = FALSE;
+ Doiter = FALSE;
+ primal = TRUE;
+ for(int i = 0; i != Rows && primal != FALSE;) {
+ i++;
+ primal = (Rhs[i] >= 0 && Rhs[i] <= Upbo[Bas[i]]) ? (short)1: (short)0;
+ }
+ if (primal == FALSE) {
+ drow[0] = 1;
+ for(int i = 1; i <= Rows; i++) drow[i] = 0;
+ Extrad = 0;
+ for(int i = 1; i <= columns; i++) {
+ varnr = Rows + i;
+ drow[varnr] = 0;
+ for(int j = Col_end[i - 1]; j < Col_end[i]; j++)
+ if (drow[get_row_nr(Mat, j)] != 0)
+ drow[varnr] += drow[get_row_nr(Mat, j)] * get_value(Mat,j);
+ if (drow[varnr] < Extrad) Extrad = drow[varnr];
+ }
+ } else {
+ Extrad = 0;
+ }
+ minit = FALSE;
+ while(Status == RUNNING) {
+ Doiter = FALSE;
+ DoInvert = FALSE;
+ construct_solution(Solution);
+ if (primal != FALSE) {
+ ref1.value = colnr;
+ flag = colprim(ref1, minit, drow);
+ colnr = (int)ref1.value;
+ if (flag != FALSE) {
+ setpivcol(Lower[colnr], colnr, Pcol);
+ ref1.value = row_nr;
+ ref2.value = theta;
+ flag = rowprim(colnr, ref1, ref2, Pcol);
+ row_nr = (int)ref1.value;
+ theta = ref2.value;
+ if (flag != FALSE) condensecol(row_nr, Pcol);
+ }
+ } else {
+ if (minit == FALSE) {
+ ref1.value = row_nr;
+ flag = rowdual(ref1);
+ row_nr = (int)ref1.value;
+ }
+ if (row_nr > 0) {
+ ref1.value = colnr;
+ flag = coldual(row_nr, ref1, minit, prow, drow);
+ colnr = (int)ref1.value;
+ if (flag != FALSE) {
+ setpivcol(Lower[colnr], colnr, Pcol);
+ /* getting div by zero here ... MB */
+ if (Pcol[row_nr] == 0) {
+ throw new Error("An attempt was made to divide by zero (Pcol[" + row_nr + "])");
+ } else {
+ condensecol(row_nr, Pcol);
+ f = Rhs[row_nr] - Upbo[Bas[row_nr]];
+ if (f > 0) {
+ theta = f / (float) Pcol[row_nr];
+ if (theta <= Upbo[colnr])
+ Lower[Bas[row_nr]] = (Lower[Bas[row_nr]] == FALSE)? (short)1:(short)0;
+ } else theta = Rhs[row_nr] / (float) Pcol[row_nr];
+ }
+ } else Status = INFEASIBLE;
+ } else {
+ primal = TRUE;
+ Doiter = FALSE;
+ Extrad = 0;
+ DoInvert = TRUE;
+ }
+ }
+ if (Doiter != FALSE) {
+ ref1.value = theta;
+ ref2.value = minit;
+ ref3.value = Lower[colnr];
+ iteration(row_nr, colnr, ref1, Upbo[colnr], ref2, ref3, primal, Pcol);
+ theta = ref1.value;
+ minit = (short)ref2.value;
+ Lower[colnr] = (short)ref3.value;
+ }
+ if (Num_inv >= max_num_inv) DoInvert = TRUE;
+ if (DoInvert != FALSE) invert();
+ }
+ total_iter += iter;
+ return(Status);
+ }
+
+ private void construct_solution(float[] sol) {
+ float f;
+ int basi;
+ for(int i = 0; i <= Rows; i++) sol[i] = 0;
+ for(int i = Rows + 1; i <= Sum; i++) sol[i] = Lowbo[i];
+ for(int i = 1; i <= Rows; i++) {
+ basi = Bas[i];
+ if (basi > Rows) sol[basi] += Rhs[i];
+ }
+ for(int i = Rows + 1; i <= Sum; i++)
+ if (Basis[i] == FALSE && Lower[i] == FALSE)
+ sol[i] += Upbo[i];
+ for(int j = 1; j <= columns; j++) {
+ f = sol[Rows + j];
+ if (f != 0)
+ for(int i = Col_end[j - 1]; i < Col_end[j]; i++)
+ sol[get_row_nr(Mat, i)] += f * get_value(Mat,i);
+ }
+ for(int i = 0; i <= Rows; i++) {
+ if (Math.abs(sol[i]) < Epsb) sol[i] = 0;
+ else if (ch_sign[i] != FALSE) sol[i] = -sol[i];
+ }
+ }
+
+ private void calculate_duals() {
+ for(int i = 1; i <= Rows; i++) duals[i] = 0;
+ duals[0] = 1;
+ btran(duals);
+ for(int i = 1; i <= Rows; i++) {
+ if (basis[i] != FALSE) duals[i] = 0;
+ else if ( ch_sign[0] == ch_sign[i]) duals[i] = -duals[i];
+ }
+ }
+
+ private static Random rdm = new Random();
+
+ private int milpsolve(float[] upbo, float[] lowbo, short[] sbasis, short[] slower, int[] sbas) {
+ int failure, notint, is_worse;
+ float theta, tmpfloat;
+ notint = 0;
+
+ if (Break_bb != FALSE) return(BREAK_BB);
+ Level++;
+ total_nodes++;
+ if (Level > max_level) max_level = Level;
+ System.arraycopy(upbo, 0, Upbo, 0, Sum + 1);
+ System.arraycopy(lowbo, 0, Lowbo, 0, Sum + 1);
+ System.arraycopy(sbasis, 0, Basis, 0, Sum + 1);
+ System.arraycopy(slower, 0, Lower, 0, Sum + 1);
+ System.arraycopy(sbas, 0, Bas, 0, Rows + 1);
+ System.arraycopy(Orig_rh, 0, Rh, 0, Rows + 1);
+ if (eta_valid == FALSE) {
+ for(int i = 1; i <= columns; i++)
+ if (Lowbo[Rows + i] != 0) {
+ theta = Lowbo[ Rows + i];
+ if (Upbo[Rows + i]<Infinite) Upbo[Rows + i] -= theta;
+ for(int j = Col_end[i - 1]; j < Col_end[i]; j++) Rh[get_row_nr(Mat, j)] -= theta * get_value(Mat,j);
+ }
+ invert();
+ eta_valid = TRUE;
+ }
+ failure = solvelp();
+ if (failure == OPTIMAL) {
+ construct_solution(Solution);
+ /* if this solution is worse than the best sofar, this branch must die */
+ if (Maximise != FALSE) is_worse = (Solution[0] <= Best_solution[0]) ? 1:0;
+ else is_worse = (Solution[0] >= Best_solution[0]) ? 1:0;
+ if (is_worse != FALSE) {
+ Level--;
+ return(MILP_FAIL);
+ }
+ /* check if solution contains enough ints */
+ if (bb_rule == FIRST_NI) {
+ notint = 0;
+ int i = Rows + 1;
+ while(i <= Sum && notint == 0) i++;
+ }
+ if (bb_rule == RAND_NI) {
+ int nr_not_int, select_not_int;
+ nr_not_int = 0;
+ for(int i = Rows + 1; i <= Sum; i++)
+ if (nr_not_int == 0) notint = 0;
+ else {
+ select_not_int=(rdm.nextInt() % nr_not_int) + 1;
+ i = Rows + 1;
+ while(select_not_int > 0) i++;
+ notint = i - 1;
+ }
+ }
+ if (notint != FALSE) throw new Error("integer linear programming not supported");
+ if (Maximise != FALSE) is_worse = (Solution[0] < Best_solution[0]) ? 1:0;
+ else is_worse = (Solution[0] > Best_solution[0]) ? 1:0;
+ if (is_worse == FALSE) {
+ System.arraycopy(Solution, 0, Best_solution, 0, Sum + 1);
+ calculate_duals();
+ if (break_at_int != FALSE) {
+ if (Maximise != FALSE && (Best_solution[0] > break_value)) Break_bb = TRUE;
+ if (Maximise == FALSE && (Best_solution[0] < break_value)) Break_bb = TRUE;
+ }
+ }
+ }
+ Level--;
+ return(failure);
+ }
+
+ public int solve() {
+ int result = FAILURE;
+ if (active == FALSE) set_globals();
+ total_iter = 0;
+ max_level = 1;
+ total_nodes = 0;
+ if (Isvalid() != FALSE) {
+ if (Maximise != FALSE && obj_bound == Infinite) Best_solution[0]=-Infinite;
+ else if (Maximise == FALSE && obj_bound==-Infinite) Best_solution[0] = Infinite;
+ else Best_solution[0] = obj_bound;
+ Level = 0;
+ if (basis_valid == FALSE) {
+ for(int i = 0; i <= rows; i++) {
+ basis[i] = TRUE;
+ bas[i] = i;
+ }
+ for(int i = rows+1; i <= sum; i++) basis[i] = FALSE;
+ for(int i = 0; i <= sum; i++) lower[i] = TRUE;
+ basis_valid = TRUE;
+ }
+ eta_valid = FALSE;
+ Break_bb = FALSE;
+ result = milpsolve(Orig_upbo, Orig_lowbo, Basis, Lower, Bas);
+ eta_size = Eta_size;
+ eta_alloc = Eta_alloc;
+ num_inv = Num_inv;
+ }
+ for(int i = 0; i < maxmat; i++) { set_row_nr(mat,i, 0); set_value(mat, i, 0); }
+ for(int i = 0; i < maxmat; i++) col_no[i] = 0;
+
+ // FIXME: not sure about this
+ for(int i = 0; i < Eta_size; i++) eta_value[i] = 0;
+ for(int i = 0; i < Eta_size; i++) eta_row_nr[i] = 0;
+ for(int i = 0; i < Eta_size; i++) eta_col_end[i] = 0;
+
+ maxmat = 0;
+ return(result);
+ }
+
+ private int maxmat = 0;
+ private final static float round( float val, float eps) { return (Math.abs(val) < eps) ? 0 : val; }
+ int get_row_nr(MatrixArray m, int i) { return m.row_nr[i]; }
+ void set_row_nr(MatrixArray m, int i, int val) { m.row_nr[i] = val; maxmat = Math.max(i, maxmat); }
+ float get_value(MatrixArray m, int i) { return m.value[i]; }
+ void set_value(MatrixArray m, int i, float val) { m.value[i] = val; maxmat = Math.max(i, maxmat); }
+ public static class MatrixArray {
+ public int[] row_nr;
+ public float[] value;
+ public final int length;
+ public MatrixArray(int length) { row_nr = new int[length]; value = new float[length]; this.length = length; }
+ }
+
+}
+
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.util;
+import java.io.IOException;
+import org.ibex.js.*;
+
+public interface Task {
+ public abstract void perform() throws IOException, JSExn;
+}
--- /dev/null
+// Copyright (C) 2003 Adam Megacz <adam@ibex.org> all rights reserved.
+//
+// You may modify, copy, and redistribute this code under the terms of
+// the GNU Library Public License version 2.1, with the exception of
+// the portion of clause 6a after the semicolon (aka the "obnoxious
+// relink clause")
+
+package org.ibex.util;
+
+import java.io.*;
+
+/**
+ * An unsynchronized Vector implementation; same semantics as
+ * java.util.Vector. Useful for JDK1.1 platforms that don't have
+ * java.util.ArrayList.
+ *
+ * May contain nulls.
+ *
+ * @see java.util.Vector
+ */
+public final class Vec implements Serializable {
+
+ private Object[] store;
+ private int size = 0;
+
+ public Vec() { this(10); }
+ public Vec(int i) { store = new Object[i]; }
+ public Vec(int i, Object[] store) { size = i; this.store = store; }
+
+ private void grow() { grow(store.length * 2); }
+ private void grow(int newsize) {
+ Object[] newstore = new Object[newsize];
+ System.arraycopy(store, 0, newstore, 0, size);
+ store = newstore;
+ }
+
+ public void removeAllElements() {
+ for(int i=0; i<size; i++) store[i] = null;
+ size = 0;
+ }
+
+ public void toArray(Object[] o) {
+ for(int i=0; i<size; i++)
+ o[i] = store[i];
+ }
+
+ public int indexOf(Object o) {
+ for(int i=0; i<size; i++)
+ if (o == null ? store[i] == null : store[i].equals(o)) return i;
+
+ return -1;
+ }
+
+ public void addElement(Object o) {
+ if (size >= store.length - 1) grow();
+ store[size++] = o;
+ }
+
+ public Object peek() {
+ return lastElement();
+ }
+
+ public Object elementAt(int i) {
+ return store[i];
+ }
+
+ public Object lastElement() {
+ if (size == 0) return null;
+ return store[size - 1];
+ }
+
+ public void push(Object o) { addElement(o); }
+ public Object pop() {
+ Object ret = lastElement();
+ if (size > 0) store[size--] = null;
+ return ret;
+ }
+
+ public int size() { return size; }
+
+ public void setSize(int newSize) {
+ if (newSize < 0) throw new RuntimeException("tried to set size to negative value");
+ if (newSize > store.length) grow(newSize * 2);
+ if (newSize < size)
+ for(int i=newSize; i<size; i++)
+ store[i] = null;
+ size = newSize;
+ }
+
+ public void copyInto(Object[] out) {
+ for(int i=0; i<size; i++)
+ out[i] = store[i];
+ }
+
+ public void fromArray(Object[] in) {
+ setSize(in.length);
+ for(int i=0; i<size; i++)
+ store[i] = in[i];
+ }
+
+ public void removeElementAt(int i) {
+ if (i >= size || i < 0) throw new RuntimeException("tried to remove an element outside the vector's limits");
+ for(int j=i; j<size - 1; j++)
+ store[j] = store[j + 1];
+ setSize(size - 1);
+ }
+
+ public void setElementAt(Object o, int i) {
+ if (i >= size) setSize(i);
+ store[i] = o;
+ }
+
+ public void removeElement(Object o) {
+ int idx = indexOf(o);
+ if (idx != -1) removeElementAt(idx);
+ }
+
+ public void insertElementAt(Object o, int at) {
+ if (size == store.length) grow();
+ for(int i=size; i>at; i--)
+ store[i] = store[i-1];
+ store[at] = o;
+ size++;
+ }
+
+ public interface CompareFunc {
+ public int compare(Object a, Object b);
+ }
+
+ public void sort(CompareFunc c) {
+ sort(this, null, c, 0, size-1);
+ }
+
+ public static void sort(Vec a, Vec b, CompareFunc c) {
+ if (b != null && a.size != b.size) throw new IllegalArgumentException("Vec a and b must be of equal size");
+ sort(a, b, c, 0, a.size-1);
+ }
+
+ private static final void sort(Vec a, Vec b, CompareFunc c, int start, int end) {
+ Object tmpa, tmpb = null;
+ if(start >= end) return;
+ if(end-start <= 6) {
+ for(int i=start+1;i<=end;i++) {
+ tmpa = a.store[i];
+ if (b != null) tmpb = b.store[i];
+ int j;
+ for(j=i-1;j>=start;j--) {
+ if(c.compare(a.store[j],tmpa) <= 0) break;
+ a.store[j+1] = a.store[j];
+ if (b != null) b.store[j+1] = b.store[j];
+ }
+ a.store[j+1] = tmpa;
+ if (b != null) b.store[j+1] = tmpb;
+ }
+ return;
+ }
+
+ Object pivot = a.store[end];
+ int lo = start - 1;
+ int hi = end;
+
+ do {
+ while(c.compare(a.store[++lo],pivot) < 0) { }
+ while((hi > lo) && c.compare(a.store[--hi],pivot) > 0) { }
+ swap(a, lo,hi);
+ if (b != null) swap(b, lo,hi);
+ } while(lo < hi);
+
+ swap(a, lo,end);
+ if (b != null) swap(b, lo,end);
+
+ sort(a, b, c, start, lo-1);
+ sort(a, b, c, lo+1, end);
+ }
+
+ private static final void swap(Vec vec, int a, int b) {
+ if(a != b) {
+ Object tmp = vec.store[a];
+ vec.store[a] = vec.store[b];
+ vec.store[b] = tmp;
+ }
+ }
+
+ public static final void sortInts(int[] a, int start, int end) {
+ int tmpa;
+ if(start >= end) return;
+ if(end-start <= 6) {
+ for(int i=start+1;i<=end;i++) {
+ tmpa = a[i];
+ int j;
+ for(j=i-1;j>=start;j--) {
+ if(a[j] <= tmpa) break;
+ a[j+1] = a[j];
+ }
+ a[j+1] = tmpa;
+ }
+ return;
+ }
+
+ int pivot = a[end];
+ int lo = start - 1;
+ int hi = end;
+
+ do {
+ while(a[++lo] < pivot) { }
+ while((hi > lo) && a[--hi] > pivot) { }
+ swapInts(a, lo, hi);
+ } while(lo < hi);
+ swapInts(a, lo, end);
+ sortInts(a, start, lo-1);
+ sortInts(a, lo+1, end);
+ }
+
+ private static final void swapInts(int[] vec, int a, int b) {
+ if(a != b) {
+ int tmp = vec[a];
+ vec[a] = vec[b];
+ vec[b] = tmp;
+ }
+ }
+}
--- /dev/null
+// Copyright (C) 2003 Adam Megacz <adam@ibex.org> all rights reserved.
+//
+// You may modify, copy, and redistribute this code under the terms of
+// the GNU Library Public License version 2.1, with the exception of
+// the portion of clause 6a after the semicolon (aka the "obnoxious
+// relink clause")
+
+package org.ibex.util;
+
+import java.io.Reader;
+import java.io.IOException;
+import java.io.EOFException;
+
+/**
+ * An Event-Driving, Non-Validating XML Parser with Namespace support.
+ *
+ * A subclass can implement the abstract functions for receiving details
+ * about an xml file as it is parsed. To initate a parse, use the parse()
+ * function.
+ *
+ * <h3>Implementation Notes</h3>
+ * <p>As the parser traverses into an element, it adds it to the linked list
+ * called <tt>elements</tt>. However, <tt>elements</tt> has been pre-filled
+ * with instances of the Element inner class. So in the vast majority of
+ * cases, the pointer current is moved along one, and the values for the
+ * new element are filled into the current object.</p>
+ *
+ * <p>This parser supports all the unicode ranges required by the XML
+ * Specification. However, it is optimised for well-formed ASCII documents.
+ * Documents containing unicode Names and Attributes will take much longer
+ * to process, and invalid documents (badly formed Names or invalid attributes)
+ * will be run through a test on every single unicode character range before
+ * being declared invalid.</p>
+ *
+ * <ul>
+ * <li>Each time the buffer offset <tt>off</tt> is moved, the length
+ * <tt>len</tt> must be decreased.</li>
+ * <li>Each time the buffer length is decreased, it must be checked to make
+ * sure it is >0.</li>
+ * <li><i>error</i> is defined as a Validity Constraint Violation and
+ * is recoverable</li>
+ * <li><i>fatal error</i> is defined as a Well-formedness Constraint
+ * Violation and is not recoverable</li>
+ * </ul>
+ *
+ * @author David Crawshaw
+ * @see <a href="http://w3.org/TR/REC-xml">XML Specification</a>
+ * @see <a href="http://w3.org/TR/REC-xml-names">XML Namespaces</a>
+ */
+public abstract class XML
+{
+ /////////////////////////////////////////////////////////////////////////////////////////////
+ // XML Parser
+ /////////////////////////////////////////////////////////////////////////////////////////////
+
+ public static final int BUFFER_SIZE = 255;
+
+ /** static pool of XML.Element instances shared by all XML Parsers. */
+ private static final Queue elements = new Queue(30);
+
+ private static final char[] single_amp = new char[] { '&' };
+ private static final char[] single_apos = new char[] { '\'' };
+ private static final char[] single_gt = new char[] { '>' };
+ private static final char[] single_lt = new char[] { '<' };
+ private static final char[] single_quot = new char[] { '"' };
+
+ private int line;
+ private int col;
+
+ private Reader in;
+ private char[] buf;
+ private int off;
+ private int base; // base+off == distance into the stream
+ private int len;
+
+ private Element current;
+
+ // used in readEntity() to process a single character without creating a new array
+ private char[] singlechar = new char[1];
+
+
+ public XML() { this(BUFFER_SIZE); }
+
+ public XML(int bSize) {
+ buf = new char[bSize];
+
+ current = (Element)elements.remove(false);
+ if (current == null) current = new Element();
+ }
+
+ /** Returns the line number at the beginning of the last process call. */
+ public int getLine() { return line; }
+
+ /** Returns the column number at the beginning of the last process call. */
+ public int getCol() { return col; }
+
+ /** Returns the global file offset at the beginning of the last process call. */
+ public int getGlobalOffset() { return base + off; }
+
+ /**
+ * Parse given input and call the abstract event functions.
+ *
+ * Careful with threading, as this function is not synchronized.
+ */
+ public final void parse(Reader reader) throws IOException, Exn {
+ in = reader;
+ off = len = 0;
+ line = col = 1;
+
+ clear(); // clean up possible mid-way linked-list element
+
+ try {
+ // process the stream
+ while (true) {
+ if (!buffer(1)) {
+ if (current.qName == null) break;
+ throw new Exn("reached eof without closing <"+current.qName+"> element", Exn.WFC, getLine(), getCol());
+ }
+
+ if (buf[off] == '<') readTag();
+ readChars(current.qName != null);
+ }
+ } finally { clear(); } // clean up elements
+ }
+
+ /** remove any leftover elements from the linked list and queue them */
+ private final void clear() {
+ for (Element last = current; current.parent != null; ) {
+ current = current.parent;
+ last.clear();
+ elements.append(last);
+ }
+ current.clear();
+ }
+
+ /** reads in a tag. expects <tt>buf[off] == '<'</tt> */
+ private final void readTag() throws IOException, Exn {
+ // Start Tag '<' Name (S Attribute)* S? '>'
+ boolean starttag = true;
+
+ // End Tag '</' Name S? '>'
+ boolean endtag = false;
+
+ // if (starttag & endtag) then: EmptyElemTag '<' Name (S Attribute)* S? '/>'
+
+ // Position in the name of the ':' namespace prefix
+ int prefix = -1;
+
+ int namelen = 0;
+
+ col++; off++; len--;
+ if (!buffer(1)) throw new EOFException("Unexpected EOF processing element tag");
+
+ // work out what we can from the beginning of the tag
+ char s = buf[off];
+ if (s == '!') {
+ // definitions here don't necessarily conform to xml spec (as DTDs not yet implemented)
+ col++; off++; len--;
+ if (!buffer(4)) throw new EOFException("Unexpected EOF processing <! element");
+
+ boolean bad = false;
+ switch (buf[off]) {
+ case '-':
+ if (buf[off+1] != '-') { bad = true; break; }
+ col += 2; off += 2; len -= 2;
+
+ // Comment '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
+ readChars(false, "-->", false);
+ col += 3; off += 3; len -= 3;
+ break;
+
+ // we don't care about the following definitions
+
+ case 'A':
+ if (!buffer(7)
+ || buf[off+1] != 'T' || buf[off+2] != 'T' || buf[off+3] != 'L'
+ || buf[off+4] != 'I' || buf[off+5] != 'S' || buf[off+6] != 'T') {
+ bad = true; break;
+ }
+ col += 7; off += 7; len -= 7;
+
+ // ATTLIST '<!ATTLIST' (Char* - '>') '>'
+ readChars(false, ">", true);
+ col++; off++; len--;
+ break;
+ case 'D':
+ if (!buffer(7)
+ || buf[off+1] != 'O' || buf[off+2] != 'C' || buf[off+3] != 'T'
+ || buf[off+4] != 'Y' || buf[off+5] != 'P' || buf[off+6] != 'E') {
+ bad = true; break;
+ }
+ col += 7; off += 7; len -= 7;
+
+ // DTD '<!DOCTYPE' (Char* - '>') '>'
+ readChars(false, ">", true);
+ col++; off++; len--;
+ break;
+ case 'E':
+ if (!buffer(7)) {
+ bad = true;
+ } else if (buf[off+1] == 'L' && buf[off+2] == 'E' && buf[off+3] == 'M'
+ && buf[off+4] == 'E' && buf[off+5] == 'N' && buf[off+6] == 'T') {
+ // ELEMENT '<!ELEMENT' (Char* - '>') '>'
+ readChars(false, ">", true);
+ col++; off++; len--;
+
+ } else if (buf[off+1] == 'N' && buf[off+2] == 'T' && buf[off+3] == 'I'
+ && buf[off+4] == 'T' && buf[off+5] == 'Y') {
+ // ENTITY '<!ENTITY' (Char* - '>') '>'
+ readChars(false, ">", true);
+ col++; off++; len--;
+
+ } else {
+ bad = true;
+ }
+ break;
+
+ case 'N':
+ if (!buffer(8)
+ || buf[off+1] != 'O' || buf[off+2] != 'T' || buf[off+3] != 'A' || buf[off+4] != 'T'
+ || buf[off+5] != 'I' || buf[off+6] != 'O' || buf[off+7] != 'N') {
+ bad = true; break;
+ }
+ col += 8; off += 8; len -= 8;
+ // NOTATION '<!NOTATION' (Char* - '>') '>'
+ readChars(false, ">", true);
+ col++; off++; len--;
+
+ break;
+ default: bad = true;
+ }
+
+ if (bad) throw new Exn("element tag start character is invalid", Exn.MARKUP, getLine(), getCol());
+
+ } else if (s == '?') {
+ // PI (Ignored) '<?' (Char* - (Char* '?>' Char*)) '?>'
+ col++; off++; len--;
+ readChars(false, "?>", true);
+ if (!buffer(2)) throw new EOFException("Unexpected EOF at end of Processing Instruction");
+ col += 2; off += 2; len -= 2;
+
+ } else if (s == '[') {
+ if (!buffer(7)
+ || buf[off+1] != 'C' || buf[off+2] != 'D' || buf[off+3] != 'A'
+ || buf[off+4] != 'T' || buf[off+5] != 'A' || buf[off+6] != '[') {
+ col++; off--; len++;
+ // Conditional '<![' (Char* - (Char* ']]>' Char*)) ']]>'
+ readChars(false, "]]>", false);
+ } else {
+ col += 7; off += 7; len -=7;
+ // CDATA '<![CDATA[' (Char* - (Char* ']]>' Char*)) ']]>'
+ readChars(true, "]]>", false);
+ }
+ col += 3; off += 3; len -= 3;
+ } else {
+ if (s == '/') {
+ // End Tag '</' Name S? '>'
+ starttag = false;
+ endtag = true;
+
+ col++; off++; len--;
+ if (!buffer(1)) throw new EOFException("Unexpected EOF processing end tag");
+ s = buf[off];
+ }
+
+ if (!Name(s)) throw new Exn("invalid starting character in element name", Exn.MARKUP, getLine(), getCol());
+
+ // find the element name (defined in XML Spec: section 2.3)
+ for (namelen = 0; ; namelen++) {
+ if (!buffer(namelen+1)) throw new EOFException("Unexpected EOF in element tag name");
+
+ s = buf[off+namelen];
+
+ if (S(s) || s == '>') {
+ break;
+ } else if (s == '/') {
+ endtag = true;
+ break;
+ } else if (s == ':' && namelen > 0 && prefix < 1) {
+ // we have a definition of the prefix range available
+ prefix = namelen;
+ } else if (!NameChar(s)) {
+ throw new Exn("element name contains invalid character", Exn.MARKUP, getLine(), getCol());
+ }
+ }
+
+ // process name (based on calculated region)
+ if (namelen < 1) throw new Exn("element name is null", Exn.MARKUP, getLine(), getCol());
+
+ // we have marked out the name region, so turn it into a string and move on
+ String qName = new String(buf, off, namelen);
+
+ col += namelen; off += namelen; len -= namelen;
+
+ if (starttag) {
+ // create the in-memory element representation of this beast
+ // if current.qName == null then this is the root element we're dealing with
+ if (current.qName != null) {
+ Element next = (Element)elements.remove(false);
+ if (next == null) next = new Element();
+ //next.clear(); // TODO: remove as elements now checked as they're added to the queue
+ next.parent = current;
+ current = next;
+ }
+
+ current.qName = qName;
+
+ if (prefix > 0) {
+ current.prefix = current.qName.substring(0, prefix);
+ current.localName = current.qName.substring(prefix+1);
+ } else {
+ current.prefix = null;
+ current.localName = current.qName;
+ }
+
+ // process attributes
+ readWhitespace();
+ if (!buffer(1)) throw new EOFException("Unexpected EOF - processing attributes part 1");
+ while (buf[off] != '/' && buf[off] != '>') {
+ readAttribute();
+ if (!buffer(1)) throw new EOFException("Unexpected EOF - processing attributes part 2");
+ readWhitespace();
+ }
+
+ // work out the uri of this element
+ current.uri = current.getUri(current.getPrefix());
+ if (current.getUri().equals("") && current.getPrefix() != null)
+ current.addError(new Exn("undefined prefix '"+current.getPrefix()+"'", Exn.NC, getLine(), getCol()));
+
+ } else {
+ // this is an end-of-element tag
+ if (!qName.equals(current.getQName())) throw new Exn(
+ "end tag </"+qName+"> does not line up with start tag <"+current.getQName()+">", Exn.WFC, getLine(), getCol()
+ );
+ }
+
+ // deal with whitespace
+ readWhitespace();
+
+ // process tag close
+ if (!buffer(1)) throw new EOFException("Unexpected EOF before end of tag");
+ if (buf[off] == '/') {
+ endtag = true;
+ off++; len--; col++;
+ }
+ if (!buffer(1)) throw new EOFException("Unexpected EOF before end of endtag");
+ if (buf[off] == '>') {
+ off++; len--; col++;
+ } else {
+ throw new Exn("missing '>' character from element '"+qName+"'", Exn.MARKUP, getLine(), getCol());
+ }
+
+ // send element signals
+ if (starttag) startElement(current);
+ if (endtag) {
+ endElement(current);
+
+ // we just closed an element, so remove it from the element 'stack'
+ if (current.getParent() == null) {
+ // we just finished the root element
+ current.clear();
+ } else {
+ Element last = current;
+ current = current.parent;
+ last.clear();
+ elements.append(last);
+ }
+ }
+ }
+ }
+
+ /** reads in an attribute of an element. expects Name(buf[off]) */
+ private final void readAttribute() throws IOException, Exn {
+ int ref = 0;
+ int prefix = 0;
+ String n, v, p, u; // attribute name, value, prefix and uri respectively
+ n = v = p = u = null;
+ char s;
+
+ // find the element name (defined in XML Spec: section 2.3)
+ for (ref= 0; ; ref++) {
+ if (!buffer(ref+1)) throw new EOFException("Unexpected EOF in read attribute loop part 1");
+
+ s = buf[off+ref];
+
+ if (s == '=' || S(s)) {
+ break;
+ } else if (s == ':' && ref > 0 && prefix < 1) {
+ // we have a definition of the prefix range available
+ prefix = ref+1;
+ } else if (!NameChar(s)) {
+ throw new Exn("attribute name contains invalid characters", Exn.MARKUP, getLine(), getCol());
+ }
+ }
+
+ // determine prefix and key name
+ if (prefix > 0) {
+ p = new String(buf, off, prefix-1);
+ col += prefix; off += prefix; len -= prefix; ref -= prefix;
+ }
+ n = new String(buf, off, ref);
+ col += ref; off += ref; len -= ref;
+
+ // find name/value divider ('=')
+ readWhitespace();
+ if (!buffer(1)) throw new EOFException("Unexpected EOF before attribute '=' divider");
+ if (buf[off] != '=') throw new Exn("attribute name not followed by '=' sign", Exn.MARKUP, getLine(), getCol());
+
+ col++; off++; len--;
+ readWhitespace();
+
+ if (!buffer(1)) throw new EOFException("Unexpected EOF after attribute '=' divider");
+
+ char wrap;
+ if (buf[off] == '\'' || buf[off] == '"') {
+ wrap = buf[off];
+ } else {
+ throw new Exn("attribute '"+n+"' must have attribute wrapped in ' or \"", Exn.MARKUP, getLine(), getCol());
+ }
+ col++; off++; len--;
+
+ // find the attribute value
+ attval: for (ref = 0; ; ref++) {
+ if (!buffer(ref+1)) throw new EOFException("Unexpected EOF in attribute value");
+
+ if (buf[off+ref] == wrap) {
+ break attval;
+ } else if (buf[off+ref] == '<') {
+ throw new Exn("attribute value for '"+n+"' must not contain '<'", Exn.WFC, getLine(), getCol());
+ }
+ }
+
+ v = new String(buf, off, ref);
+ col += ref; off += ref; len -= ref;
+
+ // remove end wrapper character
+ col++; off++; len--;
+
+ // process attribute
+ if (p != null && p.equals("xmlns")) {
+ current.addUri(n, v);
+ } else if (n.equals("xmlns")) {
+ if (current.getUri().equals("")) {
+ current.addUri("", v);
+ } else {
+ current.addError(new Exn("default namespace definition repeated", Exn.NC, getLine(), getCol()));
+ }
+ } else {
+ // find attribute uri
+ u = current.getUri(p);
+ if (p != null && u.equals("")) current.addError(new Exn("undefined attribute prefix '"+p+"'", Exn.NC, getLine(), getCol()));
+
+ // check to see if attribute is a repeat
+ for (int i=0; current.len > i; i++) if (n.equals(current.getAttrKey(i)) && u.equals(current.getAttrUri(i))) throw new Exn(
+ "attribute name '"+n+"' may not appear more than once in the same element tag", Exn.WFC, getLine(), getCol()
+ );
+
+ current.addAttr(n, v, u);
+ }
+ }
+
+ /** reads an entity and processes out its value. expects buf[off] == '&' */
+ private final void readEntity() throws IOException, Exn {
+ off++; len--;
+ if (!buffer(2)) throw new EOFException("Unexpected EOF reading entity");
+
+ boolean unknown = false;
+ switch (buf[off]) {
+ case '#':
+ off++; len--;
+
+ int radix;
+ if (buf[off] == 'x') { off++; len--; radix = 16; } else { radix = 10; }
+ int c = 0;
+
+ // read in each char, then shift total value to the left and add the extra
+ // style of loop is slightly different from all the others, as this should run a limited number of times
+ findchar: while (true) {
+ if (!buffer(1)) throw new EOFException("Unexpected EOF reading entity");
+ int d = Character.digit(buf[off], radix);
+ if (d == -1) {
+ if (buf[off] != ';') throw new Exn("illegal characters in entity reference", Exn.WFC, getLine(), getCol());
+ off++; len--; col++;
+ break findchar;
+ }
+ c = (c * radix) + d;
+
+ off++; len--;
+ }
+
+ singlechar[0] = Character.forDigit(c, radix);
+ characters(singlechar, 0, 1);
+ break;
+
+ case 'a':
+ if (buffer(4) && buf[off+1] == 'm' && buf[off+2] == 'p' && buf[off+3] == ';') {
+ characters(single_amp, 0, 1); // &
+ off += 4; len -= 4; col++;
+ } else if (buffer(5) && buf[off+1] == 'p' && buf[off+2] == 'o' && buf[off+3] == 's' && buf[off+4] == ';') {
+ characters(single_apos, 0, 1); // '
+ off += 5; len -= 5; col++;
+ } else {
+ unknown = true;
+ }
+ break;
+
+ case 'g':
+ if (buffer(3) && buf[off+1] == 't' && buf[off+2] == ';') {
+ characters(single_gt, 0, 1); // >
+ off += 3; len -= 3; col++;
+ } else {
+ unknown = true;
+ }
+ break;
+
+ case 'l':
+ if (buffer(3) && buf[off+1] == 't' && buf[off+2] == ';') {
+ characters(single_lt, 0, 1); // <
+ off += 3; len -= 3; col++;
+ } else {
+ unknown = true;
+ }
+ break;
+
+ case 'q':
+ if (buffer(5) && buf[off+1] == 'u' && buf[off+2] == 'o' && buf[off+3] == 't' && buf[off+4] == ';') {
+ characters(single_quot, 0, 1); // "
+ off += 5; len -= 5; col++;
+ } else {
+ unknown = true;
+ }
+ break;
+
+ // TODO: check a parser-level Hash of defined entities
+ }
+
+ if (unknown) throw new Exn("unknown entity (<!ENTITY> not supported)", Exn.WFC, getLine(), getCol());
+ }
+
+ /** reads until the passed string is encountered. */
+ private final void readChars(boolean p, String match, boolean entities) throws IOException, Exn {
+ int ref;
+ char[] end = match.toCharArray();
+
+ for (boolean more = true; more;) {
+ if (!buffer(1)) return;
+
+ buf: for (ref = 0; ref < len; ref++) {
+ switch (buf[off+ref]) {
+ case '\r': // windows or macos9 newline
+ // normalise and process
+ buf[off+ref] = '\n'; ref++;
+ if (p) characters(buf, off, ref);
+ off += ref; len -= ref; ref = -1;
+ line++; col = 1;
+
+ // windows double-char newline; skip the next char
+ if (!buffer(1)) return;
+ if (buf[off] == '\n') { off++; len--; }
+ break;
+
+ case '\n': // unix newline
+ ref++;
+ if (p) characters(buf, off, ref);
+ off += ref; len -= ref; ref = -1;
+ line++; col = 1;
+ break;
+
+ case '&': // entity
+ if (entities) {
+ if (p) {
+ if (ref > 0) characters(buf, off, ref);
+ off += ref; len -= ref; ref = -1;
+ readEntity();
+ }
+ break;
+ }
+
+ default:
+ if (!buffer(ref+end.length)) continue buf;
+ for (int i=0; end.length > i; i++) if (end[i] != buf[off+ref+i]) continue buf;
+ more = false;
+ break buf;
+ }
+ }
+
+ if (p && ref > 0) characters(buf, off, ref);
+ off += ref; len -= ref; col += ref;
+ }
+ }
+
+ /**
+ * reads until a <tt><</tt> symbol is encountered
+ * @param p If true call the characters(char[],int,int) funciton for the processed characters
+ */
+ private final void readChars(boolean p) throws IOException, Exn {
+ int ref;
+
+ for (boolean more = true; more;) {
+ if (!buffer(1)) return;
+
+ buf: for (ref = 0; ref < len; ref++) {
+ switch (buf[off+ref]) {
+ case '\r': // windows or macos9 newline
+ // normalise and process
+ buf[off+ref] = '\n'; ref++;
+ if (p) characters(buf, off, ref);
+ off += ref; len -= ref; ref = -1;
+ line++; col = 1;
+
+ // windows double-char newline; skip the next char
+ if (!buffer(1)) return;
+ if (buf[off] == '\n') { off++; len--; }
+ break;
+
+ case '\n': // unix newline
+ ref++;
+ if (p) characters(buf, off, ref);
+ off += ref; len -= ref; ref = -1;
+ line++; col = 1;
+ break;
+
+ case '&': // entity
+ if (p) {
+ if (ref > 0) characters(buf, off, ref);
+ off += ref; len -= ref; ref = -1;
+ readEntity();
+ }
+ break;
+
+ case '<': // end of chars section
+ more = false;
+ break buf;
+ }
+ }
+
+ if (p && ref > 0) characters(buf, off, ref);
+ off += ref; len -= ref; col += ref;
+ }
+ }
+
+ /** reads until a non-whitespace symbol is encountered */
+ private final void readWhitespace() throws IOException, Exn {
+ int ref;
+
+ for (boolean more = true; more;) {
+ if (!buffer(1)) return;
+
+ buf: for (ref = 0; ref < len; ref++) {
+ switch (buf[off+ref]) {
+ case '\r': // windows or macos9 newline
+ // normalise and process
+ buf[off+ref] = '\n';
+ whitespace(buf, off, ++ref);
+ off += ref; len -= ref; ref = -1;
+ line++; col = 1;
+
+ // windows double-char newline; skip the next char
+ if (!buffer(1)) return;
+ if (buf[off] == '\n') { off++; len--; }
+ break;
+
+ case '\n': // unix newline
+ whitespace(buf, off, ++ref);
+ off += ref; len -= ref; ref = -1;
+ line++; col = 1;
+ break;
+
+ case ' ': // space
+ case '\t': // tab
+ break;
+
+ default: // end of whitespace
+ more = false;
+ break buf;
+ }
+ }
+
+ off += ref; len -= ref; col += ref;
+ }
+ }
+
+ /**
+ * attempt to fill the buffer.
+ *
+ * @param min Minimum number of characters to read (even if we have to block to do it).
+ * @return return false if min can't be reached.
+ */
+ private final boolean buffer(int min) throws IOException {
+ if (len > min) return true;
+
+ if (buf.length - (off+len) >= min) {
+ // plenty of space left on the end of the buffer
+ } else if (off >= min) {
+ // moving offset data to start will leave enough free space on the end
+ System.arraycopy(buf, off, buf, 0, len);
+ base += off;
+ off = 0;
+ } else {
+ // buffer size will have to be increased
+ char[] newbuf = new char[buf.length * 2];
+ System.arraycopy(buf, off, newbuf, 0, len);
+ buf = newbuf;
+ base += off;
+ off = 0;
+ }
+
+ while (min > len) {
+ int newlen = in.read(buf, off+len, buf.length-(off+len));
+ if (newlen < 0) return false;
+ len += newlen;
+ }
+
+ return true;
+ }
+
+
+ /////////////////////////////////////////////////////////////////////////////////////////////
+ // Abstract SAX-Like Interface
+ /////////////////////////////////////////////////////////////////////////////////////////////
+
+ /**
+ * Called when the start of an element is processed.
+ *
+ * <p><b>DO NOT</b> store a reference to the Element object, as
+ * they are reused by XML Parser.</p>
+ */
+ public abstract void startElement(Element e) throws Exn;
+
+ /**
+ * Represents up to a line of character data.
+ *
+ * <p>Newlines are all normalised to the Unix \n as per the XML Spec,
+ * and a newline will only appear as the last character in the passed
+ * array segment.</p>
+ *
+ * <p>XML.getLine() and XML.getCol() report the position at the
+ * beginning of this character segment, which can be processed in a
+ * line-by-line fashion due to the above newline restriction.</p>
+ */
+ public abstract void characters(char[] ch, int start, int length) throws Exn, IOException;
+
+ /** Represents up to a line of ignorable whitespace. */
+ public abstract void whitespace(char[] ch, int start, int length) throws Exn, IOException;
+
+ /** Represents the end of an Element. */
+ public abstract void endElement(Element e) throws Exn, IOException;
+
+
+ /////////////////////////////////////////////////////////////////////////////////////////////
+ // Inner Classes for Parser Support
+ /////////////////////////////////////////////////////////////////////////////////////////////
+
+ /**
+ * Represents an element in an XML document. Stores a reference to its
+ * parent, forming a one-way linked list.
+ *
+ * Element objects are reused, so client code making use of them must
+ * drop their references after the specific element process function
+ * has returned.
+ */
+ public static final class Element {
+
+ private static final int DEFAULT_ATTR_SIZE = 10;
+
+ protected Element parent = null;
+
+ protected String uri = null;
+ protected String localName = null;
+ protected String qName = null;
+ protected String prefix = null;
+
+ protected Hash urimap = new Hash(3,3);
+
+ protected String[] keys = new String[DEFAULT_ATTR_SIZE];
+ protected String[] vals = new String[DEFAULT_ATTR_SIZE];
+ protected String[] uris = new String[DEFAULT_ATTR_SIZE];
+ protected int len = 0;
+
+ protected Exn[] errors = new Exn[] {};
+
+ /** Parent of current element. */
+ public Element getParent() { return parent; }
+
+ /** Qualified Name of current element. XML Namespace Spec 14-Jan-1999 [6] */
+ public String getQName() { return qName; }
+
+ /** LocalPart of current element. XML Namespace Spec 14-Jan-1999 [8] */
+ public String getLocalName() { return localName; }
+
+ /** Prefix of current element. Substring of qName. XML Namespace Spec 14-Jan-1999 [7] */
+ public String getPrefix() { return prefix; }
+
+ // HACK
+ public Hash getUriMap() {
+ Hash map = new Hash();
+ for (Element e = this; e != null; e = e.getParent()) {
+ java.util.Enumeration en = e.urimap.keys();
+ while(en.hasMoreElements()) {
+ String key = (String)en.nextElement();
+ String val = getUri(key);
+ map.put(key, val);
+ }
+ }
+ return map;
+ }
+
+ /** URI of current tag. XML Namespace Spec 14-Jan-1999 section 1 */
+ public String getUri() { return getUri(prefix); }
+
+ /** URI of a given prefix. Never returns null, instead gives "". */
+ public String getUri(String p) {
+ String ret = null;
+ for (Element e = this; e != null && ret == null; e = e.getParent()) {
+ ret = (String)e.urimap.get(p == null ? "" : p);
+ }
+ return ret == null ? "" : ret;
+ }
+
+ /** An array of attribute names. */
+ public String getAttrKey(int pos) { return len > pos ? keys[pos] : null; }
+
+ /** An array of attribute values. */
+ public String getAttrVal(int pos) { return len > pos ? vals[pos] : null; }
+
+ /** An array of attribute uris. */
+ public String getAttrUri(int pos) { return len > pos ? uris[pos] : null; }
+
+ /** Current number of attributes in the element. */
+ public int getAttrLen() { return len; }
+
+ /** Poor performance, but easier to use when speed is not a concern */
+ public Hash getAttrHash() {
+ Hash ret = new Hash(getAttrLen() * 2, 3);
+ for(int i=0; i<len; i++)
+ ret.put(getAttrKey(i), getAttrVal(i));
+ return ret;
+ }
+
+ /** Poor performance, but easier to use */
+ public String getAttrVal(String key) {
+ for(int i=0; i<len; i++) if (keys[i].equals(key)) return vals[i];
+ return null;
+ }
+
+ /** An array of non-fatal errors related to this element. */
+ public Exn[] getErrors() { return errors; }
+
+ protected Element() { }
+
+ /** Add (replace if exists in current element) a Namespace prefix/uri map. */
+ public void addUri(String name, String value) {
+ urimap.put(name, value);
+ }
+
+ /** Add an attribute. */
+ protected void addAttr(String key, String val, String uri) {
+ if (len == keys.length) {
+ // increase the size of the attributes arrays
+ String[] newkeys = new String[keys.length*2];
+ String[] newvals = new String[vals.length*2];
+ String[] newuris = new String[uris.length*2];
+ System.arraycopy(keys, 0, newkeys, 0, keys.length);
+ System.arraycopy(vals, 0, newvals, 0, vals.length);
+ System.arraycopy(uris, 0, newuris, 0, uris.length);
+ keys = newkeys; vals = newvals; uris = newuris;
+ }
+
+ keys[len] = key;
+ vals[len] = val;
+ uris[len] = uri;
+ len++;
+ }
+
+ /** Add an error. */
+ protected void addError(Exn e) {
+ // it doesn't really matter about continually expanding the array, as this case is quite rare
+ Exn[] newe = new Exn[errors.length+1];
+ System.arraycopy(errors, 0, newe, 0, errors.length);
+ newe[errors.length] = e;
+ errors = newe;
+ }
+
+ /** Empty out all the data from the Element. */
+ protected void clear() {
+ parent = null;
+ uri = localName = qName = prefix = null;
+ urimap.clear();
+
+ if (keys.length != vals.length || vals.length != uris.length) {
+ keys = new String[DEFAULT_ATTR_SIZE];
+ vals = new String[DEFAULT_ATTR_SIZE];
+ uris = new String[DEFAULT_ATTR_SIZE];
+ } else {
+ for (int i=0; keys.length > i; i++) { keys[i] = null; vals[i] = null; uris[i] = null; };
+ }
+ len = 0;
+
+ errors = new Exn[] {};
+ }
+ }
+
+ /** Parse or Structural Error */
+ public static class Exn extends Exception {
+ /** Violation of Markup restrictions in XML Specification - Fatal Error */
+ public static final int MARKUP = 1;
+
+ /** Well-Formedness Constraint Violation - Fatal Error */
+ public static final int WFC = 2;
+
+ /** Namespace Constraint Violation - Recoverable Error */
+ public static final int NC = 3;
+
+ /** Schema Violation - Fatal Error */
+ public static final int SCHEMA = 4;
+
+ private String error;
+ private int type;
+ private int line;
+ private int col;
+
+ public Exn(String e) { this(e, MARKUP, -1, -1); }
+
+ public Exn(String e, int type, int line, int col) {
+ this.error = e;
+ this.type = type;
+ this.line = line;
+ this.col = col;
+ }
+
+ public int getType() { return this.type; }
+ public int getLine() { return this.line; }
+ public int getCol() { return this.col; }
+ public String getMessage() { return this.error + (line >= 0 && col >= 0 ? " at " + line + ":" + col: ""); }
+ }
+
+
+ /////////////////////////////////////////////////////////////////////////////////////////////
+ // Static Support Functions for the XML Specification
+ /////////////////////////////////////////////////////////////////////////////////////////////
+
+ // attempt to avoid these functions unless you *expect* the input to fall in the given range.
+
+ /** First Character of Name - XML Specification 1.0 [5] */
+ private static final boolean Name(char c) {
+ return BaseCharAscii(c) || c == '_' || c == ':' || Letter(c);
+ }
+
+ /** NameChar - XML Specification 1.0 [4] */
+ private static final boolean NameChar(char c) {
+ return BaseCharAscii(c) || c == '.' || c == '-' || c == '_' || c == ':'
+ || Digit(c) || Letter(c) || Extender(c); // TODO: || CombiningChar(c);
+ }
+
+ /** BaseChar - XMl Specification 1.0 [84] */
+ private static final boolean Letter(char c) {
+ return BaseChar(c) || Ideographic(c);
+ }
+
+ /** Elements of BaseChar that exist in ASCII. */
+ private static final boolean BaseCharAscii(char c) {
+ return (c >= '\u0041' && c <= '\u005A') || (c >= '\u0061' && c <= '\u007A');
+ }
+
+ /** Char - XML Specification 1.0 [2] */
+ private static final boolean Char(char c) {
+ // u000A == r and u000D == n, but the javac compiler can't handle the \ u form
+ return c == '\u0009' || c == '\r' || c == '\n'
+ || (c >= '\u0020' && c <= '\uD7FF')
+ || (c >= '\uE000' && c <= '\uFFFD');
+ }
+
+ /** BaseChar - XML Specification 1.0 [85] */
+ private static final boolean BaseChar(char c) {
+ return BaseCharAscii(c) || (c >= '\u00C0' && c <= '\u00D6')
+ || (c >= '\u00D8' && c <= '\u00F6') || (c >= '\u00F8' && c <= '\u00FF') || (c >= '\u0100' && c <= '\u0131')
+ || (c >= '\u0134' && c <= '\u013E') || (c >= '\u0141' && c <= '\u0148') || (c >= '\u014A' && c <= '\u017E')
+ || (c >= '\u0180' && c <= '\u01C3') || (c >= '\u01CD' && c <= '\u01F0') || (c >= '\u01F4' && c <= '\u01F5')
+ || (c >= '\u01FA' && c <= '\u0217') || (c >= '\u0250' && c <= '\u02A8') || (c >= '\u02BB' && c <= '\u02C1')
+ || (c == '\u0386') || (c >= '\u0388' && c <= '\u038A') || (c == '\u038C')
+ || (c >= '\u038E' && c <= '\u03A1') || (c >= '\u03A3' && c <= '\u03CE') || (c >= '\u03D0' && c <= '\u03D6')
+ || (c == '\u03DA') || (c == '\u03DC') || (c == '\u03DE')
+ || (c == '\u03E0')
+ || (c >= '\u03E2' && c <= '\u03F3') || (c >= '\u0401' && c <= '\u040C') || (c >= '\u040E' && c <= '\u044F')
+ || (c >= '\u0451' && c <= '\u045C') || (c >= '\u045E' && c <= '\u0481') || (c >= '\u0490' && c <= '\u04C4')
+ || (c >= '\u04C7' && c <= '\u04C8') || (c >= '\u04CB' && c <= '\u04CC') || (c >= '\u04D0' && c <= '\u04EB')
+ || (c >= '\u04EE' && c <= '\u04F5') || (c >= '\u04F8' && c <= '\u04F9') || (c >= '\u0531' && c <= '\u0556')
+ || (c == '\u0559')
+ || (c >= '\u0561' && c <= '\u0586') || (c >= '\u05D0' && c <= '\u05EA') || (c >= '\u05F0' && c <= '\u05F2')
+ || (c >= '\u0621' && c <= '\u063A') || (c >= '\u0641' && c <= '\u064A') || (c >= '\u0671' && c <= '\u06B7')
+ || (c >= '\u06BA' && c <= '\u06BE') || (c >= '\u06C0' && c <= '\u06CE') || (c >= '\u06D0' && c <= '\u06D3')
+ || (c == '\u06D5')
+ || (c >= '\u06E5' && c <= '\u06E6') || (c >= '\u0905' && c <= '\u0939')
+ || (c == '\u093D')
+ || (c >= '\u0958' && c <= '\u0961') || (c >= '\u0985' && c <= '\u098C') || (c >= '\u098F' && c <= '\u0990')
+ || (c >= '\u0993' && c <= '\u09A8') || (c >= '\u09AA' && c <= '\u09B0')
+ || (c == '\u09B2')
+ || (c >= '\u09B6' && c <= '\u09B9') || (c >= '\u09DF' && c <= '\u09E1') || (c >= '\u09F0' && c <= '\u09F1')
+ || (c >= '\u0A05' && c <= '\u0A0A') || (c >= '\u0A0F' && c <= '\u0A10') || (c >= '\u0A13' && c <= '\u0A28')
+ || (c >= '\u0A2A' && c <= '\u0A30') || (c >= '\u0A32' && c <= '\u0A33') || (c >= '\u0A35' && c <= '\u0A36')
+ || (c >= '\u0A38' && c <= '\u0A39') || (c >= '\u0A59' && c <= '\u0A5C')
+ || (c == '\u0A5E')
+ || (c >= '\u0A72' && c <= '\u0A74') || (c >= '\u0A85' && c <= '\u0A8B')
+ || (c == '\u0A8D')
+ || (c >= '\u0A8F' && c <= '\u0A91') || (c >= '\u0A93' && c <= '\u0AA8') || (c >= '\u0AAA' && c <= '\u0AB0')
+ || (c >= '\u0AB2' && c <= '\u0AB3') || (c >= '\u0AB5' && c <= '\u0AB9')
+ || (c == '\u0ABD')
+ || (c == '\u0AE0')
+ || (c >= '\u0B05' && c <= '\u0B0C') || (c >= '\u0B0F' && c <= '\u0B10') || (c >= '\u0B13' && c <= '\u0B28')
+ || (c >= '\u0B2A' && c <= '\u0B30') || (c >= '\u0B32' && c <= '\u0B33') || (c >= '\u0B36' && c <= '\u0B39')
+ || (c == '\u0B3D')
+ || (c >= '\u0B5C' && c <= '\u0B5D') || (c >= '\u0B5F' && c <= '\u0B61') || (c >= '\u0B85' && c <= '\u0B8A')
+ || (c >= '\u0B8E' && c <= '\u0B90') || (c >= '\u0B92' && c <= '\u0B95') || (c >= '\u0B99' && c <= '\u0B9A')
+ || (c == '\u0B9C')
+ || (c >= '\u0B9E' && c <= '\u0B9F') || (c >= '\u0BA3' && c <= '\u0BA4') || (c >= '\u0BA8' && c <= '\u0BAA')
+ || (c >= '\u0BAE' && c <= '\u0BB5') || (c >= '\u0BB7' && c <= '\u0BB9') || (c >= '\u0C05' && c <= '\u0C0C')
+ || (c >= '\u0C0E' && c <= '\u0C10') || (c >= '\u0C12' && c <= '\u0C28') || (c >= '\u0C2A' && c <= '\u0C33')
+ || (c >= '\u0C35' && c <= '\u0C39') || (c >= '\u0C60' && c <= '\u0C61') || (c >= '\u0C85' && c <= '\u0C8C')
+ || (c >= '\u0C8E' && c <= '\u0C90') || (c >= '\u0C92' && c <= '\u0CA8') || (c >= '\u0CAA' && c <= '\u0CB3')
+ || (c >= '\u0CB5' && c <= '\u0CB9')
+ || (c == '\u0CDE')
+ || (c >= '\u0CE0' && c <= '\u0CE1') || (c >= '\u0D05' && c <= '\u0D0C') || (c >= '\u0D0E' && c <= '\u0D10')
+ || (c >= '\u0D12' && c <= '\u0D28') || (c >= '\u0D2A' && c <= '\u0D39') || (c >= '\u0D60' && c <= '\u0D61')
+ || (c >= '\u0E01' && c <= '\u0E2E')
+ || (c == '\u0E30')
+ || (c >= '\u0E32' && c <= '\u0E33') || (c >= '\u0E40' && c <= '\u0E45') || (c >= '\u0E81' && c <= '\u0E82')
+ || (c == '\u0E84')
+ || (c >= '\u0E87' && c <= '\u0E88')
+ || (c == '\u0E8A')
+ || (c == '\u0E8D')
+ || (c >= '\u0E94' && c <= '\u0E97') || (c >= '\u0E99' && c <= '\u0E9F') || (c >= '\u0EA1' && c <= '\u0EA3')
+ || (c == '\u0EA5')
+ || (c == '\u0EA7')
+ || (c >= '\u0EAA' && c <= '\u0EAB') || (c >= '\u0EAD' && c <= '\u0EAE')
+ || (c == '\u0EB0')
+ || (c >= '\u0EB2' && c <= '\u0EB3')
+ || (c == '\u0EBD')
+ || (c >= '\u0EC0' && c <= '\u0EC4') || (c >= '\u0F40' && c <= '\u0F47') || (c >= '\u0F49' && c <= '\u0F69')
+ || (c >= '\u10A0' && c <= '\u10C5') || (c >= '\u10D0' && c <= '\u10F6')
+ || (c == '\u1100')
+ || (c >= '\u1102' && c <= '\u1103') || (c >= '\u1105' && c <= '\u1107')
+ || (c == '\u1109')
+ || (c >= '\u110B' && c <= '\u110C') || (c >= '\u110E' && c <= '\u1112')
+ || (c == '\u113C')
+ || (c == '\u113E')
+ || (c == '\u1140')
+ || (c == '\u114C')
+ || (c == '\u114E')
+ || (c == '\u1150')
+ || (c >= '\u1154' && c <= '\u1155')
+ || (c == '\u1159')
+ || (c >= '\u115F' && c <= '\u1161')
+ || (c == '\u1163')
+ || (c == '\u1165')
+ || (c == '\u1167')
+ || (c == '\u1169')
+ || (c >= '\u116D' && c <= '\u116E') || (c >= '\u1172' && c <= '\u1173')
+ || (c == '\u1175')
+ || (c == '\u119E')
+ || (c == '\u11A8')
+ || (c == '\u11AB')
+ || (c >= '\u11AE' && c <= '\u11AF') || (c >= '\u11B7' && c <= '\u11B8')
+ || (c == '\u11BA')
+ || (c >= '\u11BC' && c <= '\u11C2')
+ || (c == '\u11EB')
+ || (c == '\u11F0')
+ || (c == '\u11F9')
+ || (c >= '\u1E00' && c <= '\u1E9B') || (c >= '\u1EA0' && c <= '\u1EF9') || (c >= '\u1F00' && c <= '\u1F15')
+ || (c >= '\u1F18' && c <= '\u1F1D') || (c >= '\u1F20' && c <= '\u1F45') || (c >= '\u1F48' && c <= '\u1F4D')
+ || (c >= '\u1F50' && c <= '\u1F57')
+ || (c == '\u1F59')
+ || (c == '\u1F5B')
+ || (c == '\u1F5D')
+ || (c >= '\u1F5F' && c <= '\u1F7D') || (c >= '\u1F80' && c <= '\u1FB4') || (c >= '\u1FB6' && c <= '\u1FBC')
+ || (c == '\u1FBE')
+ || (c >= '\u1FC2' && c <= '\u1FC4') || (c >= '\u1FC6' && c <= '\u1FCC') || (c >= '\u1FD0' && c <= '\u1FD3')
+ || (c >= '\u1FD6' && c <= '\u1FDB') || (c >= '\u1FE0' && c <= '\u1FEC') || (c >= '\u1FF2' && c <= '\u1FF4')
+ || (c >= '\u1FF6' && c <= '\u1FFC')
+ || (c == '\u2126')
+ || (c >= '\u212A' && c <= '\u212B')
+ || (c == '\u212E')
+ || (c >= '\u2180' && c <= '\u2182') || (c >= '\u3041' && c <= '\u3094') || (c >= '\u30A1' && c <= '\u30FA')
+ || (c >= '\u3105' && c <= '\u312C') || (c >= '\uAC00' && c <= '\uD7A3');
+ }
+
+ /** BaseChar - XMl Specification 1.0 [86] */
+ private static final boolean Ideographic(char c) {
+ return (c >= '\u4E00' && c <= '\u9FA5') || c == '\u3007' || (c >= '\u3021' && c <= '\u3029');
+ }
+
+ /** CombiningChar - XMl Specification 1.0 [87] */
+ /*private static final boolean CombiningChar(char c) {
+ return (c >= '\u0300' && c <= '\u0345')
+ || (c >= '\u0360' && c <= '\u0361') || (c >= '\u0483' && c <= '\u0486') || (c >= '\u0591' && c <= '\u05A1')
+ || (c >= '\u05A3' && c <= '\u05B9') || (c >= '\u05BB' && c <= '\u05BD')
+ || (c == '\u05BF')
+ || (c >= '\u05C1' && c <= '\u05C2')
+ || (c == '\u05C4')
+ || (c >= '\u064B' && c <= '\u0652')
+ || (c == '\u0670')
+ || (c >= '\u06D6' && c <= '\u06DC') || (c >= '\u06DD' && c <= '\u06DF') || (c >= '\u06E0' && c <= '\u06E4')
+ || (c >= '\u06E7' && c <= '\u06E8') || (c >= '\u06EA' && c <= '\u06ED') || (c >= '\u0901' && c <= '\u0903')
+ || (c == '\u093C')
+ || (c >= '\u093E' && c <= '\u094C')
+ || (c == '\u094D')
+ || (c >= '\u0951' && c <= '\u0954') || (c >= '\u0962' && c <= '\u0963') || (c >= '\u0981' && c <= '\u0983')
+ || (c == '\u09BC')
+ || (c == '\u09BE')
+ || (c == '\u09BF')
+ || (c >= '\u09C0' && c <= '\u09C4') || (c >= '\u09C7' && c <= '\u09C8') || (c >= '\u09CB' && c <= '\u09CD')
+ || (c == '\u09D7')
+ || (c >= '\u09E2' && c <= '\u09E3')
+ || (c == '\u0A02')
+ || (c == '\u0A3C')
+ || (c == '\u0A3E')
+ || (c == '\u0A3F')
+ || (c >= '\u0A40' && c <= '\u0A42') || (c >= '\u0A47' && c <= '\u0A48') || (c >= '\u0A4B' && c <= '\u0A4D')
+ || (c >= '\u0A70' && c <= '\u0A71') || (c >= '\u0A81' && c <= '\u0A83')
+ || (c == '\u0ABC')
+ || (c >= '\u0ABE' && c <= '\u0AC5') || (c >= '\u0AC7' && c <= '\u0AC9') || (c >= '\u0ACB' && c <= '\u0ACD')
+ || (c >= '\u0B01' && c <= '\u0B03')
+ || (c == '\u0B3C')
+ || (c >= '\u0B3E' && c <= '\u0B43') || (c >= '\u0B47' && c <= '\u0B48') || (c >= '\u0B4B' && c <= '\u0B4D')
+ || (c >= '\u0B56' && c <= '\u0B57') || (c >= '\u0B82' && c <= '\u0B83') || (c >= '\u0BBE' && c <= '\u0BC2')
+ || (c >= '\u0BC6' && c <= '\u0BC8') || (c >= '\u0BCA' && c <= '\u0BCD')
+ || (c == '\u0BD7')
+ || (c >= '\u0C01' && c <= '\u0C03') || (c >= '\u0C3E' && c <= '\u0C44') || (c >= '\u0C46' && c <= '\u0C48')
+ || (c >= '\u0C4A' && c <= '\u0C4D') || (c >= '\u0C55' && c <= '\u0C56') || (c >= '\u0C82' && c <= '\u0C83')
+ || (c >= '\u0CBE' && c <= '\u0CC4') || (c >= '\u0CC6' && c <= '\u0CC8') || (c >= '\u0CCA' && c <= '\u0CCD')
+ || (c >= '\u0CD5' && c <= '\u0CD6') || (c >= '\u0D02' && c <= '\u0D03') || (c >= '\u0D3E' && c <= '\u0D43')
+ || (c >= '\u0D46' && c <= '\u0D48') || (c >= '\u0D4A' && c <= '\u0D4D')
+ || (c == '\u0D57')
+ || (c == '\u0E31')
+ || (c >= '\u0E34' && c <= '\u0E3A') || (c >= '\u0E47' && c <= '\u0E4E')
+ || (c == '\u0EB1')
+ || (c >= '\u0EB4' && c <= '\u0EB9') || (c >= '\u0EBB' && c <= '\u0EBC') || (c >= '\u0EC8' && c <= '\u0ECD')
+ || (c >= '\u0F18' && c <= '\u0F19')
+ || (c == '\u0F35')
+ || (c == '\u0F37')
+ || (c == '\u0F39')
+ || (c == '\u0F3E')
+ || (c == '\u0F3F')
+ || (c >= '\u0F71' && c <= '\u0F84') || (c >= '\u0F86' && c <= '\u0F8B') || (c >= '\u0F90' && c <= '\u0F95')
+ || (c == '\u0F97')
+ || (c >= '\u0F99' && c <= '\u0FAD') || (c >= '\u0FB1' && c <= '\u0FB7')
+ || (c == '\u0FB9')
+ || (c >= '\u20D0' && c <= '\u20DC')
+ || (c == '\u20E1')
+ || (c >= '\u302A' && c <= '\u302F')
+ || (c == '\u3099')
+ || (c == '\u309A');
+ }*/
+
+ /** Digit - XMl Specification 1.0 [88] */
+ private static final boolean Digit(char c) {
+ return (c >= '\u0030' && c <= '\u0039') || (c >= '\u0660' && c <= '\u0669') || (c >= '\u06F0' && c <= '\u06F9')
+ || (c >= '\u0966' && c <= '\u096F') || (c >= '\u09E6' && c <= '\u09EF') || (c >= '\u0A66' && c <= '\u0A6F')
+ || (c >= '\u0AE6' && c <= '\u0AEF') || (c >= '\u0B66' && c <= '\u0B6F') || (c >= '\u0BE7' && c <= '\u0BEF')
+ || (c >= '\u0C66' && c <= '\u0C6F') || (c >= '\u0CE6' && c <= '\u0CEF') || (c >= '\u0D66' && c <= '\u0D6F')
+ || (c >= '\u0E50' && c <= '\u0E59') || (c >= '\u0ED0' && c <= '\u0ED9') || (c >= '\u0F20' && c <= '\u0F29');
+ }
+
+ /** Extender - XMl Specification 1.0 [89] */
+ private static final boolean Extender(char c) {
+ return c == '\u00B7' || c == '\u02D0' || c == '\u02D1' || c == '\u0387'
+ || c == '\u0640' || c == '\u0E46' || c == '\u0EC6' || c == '\u3005'
+ || (c >= '\u3031' && c <= '\u3035') || (c >= '\u309D' && c <= '\u309E') || (c >= '\u30FC' && c <= '\u30FE');
+ }
+
+ /** Whitespace - XML Specification 1.0 [3] */
+ private static final boolean S(char c) {
+ return c == '\u0020' || c == '\u0009' || c == '\r' || c == '\n';
+ }
+}
--- /dev/null
+<ibex-doc title="The Ibex Documentation Format" author="Adam Megacz" email="adam@ibex.org">
+
+<section title="Introduction">
+
+ <section title="Another Document Format?">
+
+ Foo.
+
+ </section>
+
+ <section title="Goals">
+
+ <heading title="Applications"/>
+
+ IbexDoc targets four primary documentation tasks:
+
+ <list>
+
+ Books, Manuals and references
+
+ Articles
+
+ Literate Programming (documentation embedded in source code)
+
+ Presentation Slides
+
+ Web pages, including WikiWebs
+
+ </list>
+
+ <heading title="Separating Semantics from Aesthetics"/>
+
+ The goal of separating <i>markup</i> from <i>content</i> has been
+ around for a long time in the document world. For some reason it
+ never succeeded. The problem is that:
+
+ <list>
+ The purpose of content is to convey semantic meaning.
+
+ Some markup and formatting carries semantic meaning.
+ </list>
+
+ For example, consider italicization. Adding or removing
+ italicization can actually affect the meaning of a piece of text.
+ Therefor italicization (or rather "emphasis") is part of the
+ <i>content</i> of a document.
+
+ IbexDoc recognizes this and does not attempt to use XML for
+ anything that might carry semantic meaning. Effectively, you can
+ remove all XML tags from an IbexDoc file without altering the
+ meaning of the text (although it might be rather hard to discern
+ the meaning with all the text jumbled together!)
+
+ </section>
+</section>
+ <section title="Tags">
+
+ <definition term="doc">
+ (title subtitle logo license options(toc,index) logo)
+ </definition>
+
+ <definition term="author">
+ (email, name)
+ </definition>
+
+ <definition term="abstract">
+ changes
+ </definition>
+
+ <definition term="appendix">
+ (contains sections, must appear once at EOF)
+ </definition>
+
+ <definition term="section">
+ (title)
+ </definition>
+
+ <definition term="heading">
+ ..
+ </definition>
+
+ <definition term="definition">
+ ..
+ </definition>
+
+ <definition term="property">
+ (a different kind of list?)
+ </definition>
+
+ <definition term="remark">
+ ..
+ </definition>
+
+ <definition term="image">
+ ..
+ </definition>
+
+ <definition term="figure">
+ ..
+ </definition>
+
+ <definition term="code">
+ ..
+ </definition>
+
+ <definition term="pre">
+ ..
+ </definition>
+
+ <definition term="link">
+ ..
+ </definition>
+
+ <definition term="math">
+ ..
+ </definition>
+
+ <definition term="define">
+ ..
+ </definition>
+
+ <definition term="footnote">
+ ..
+ </definition>
+
+ </section>
+
+ <section title="Text Formatting">
+
+ <pre>
+
+ **italics**
+ __boldface__
+ ||typewriter||
+
+ blank lines become paragraph breaks
+
+ # 1
+ # 1.1
+ # 1.1.1
+
+ -
+ -
+ -
+
+ \\ - backslash
+ \0x?? - unicode
+ \amp
+ \lt
+ \gt
+ \quot
+ \apos
+
+ </pre>
+
+ </section>
+
+ <section title="To Do">
+ <list>
+ tables
+
+ plugins (charts, graphs, diagrams)
+
+ wiki-style links
+
+ slides
+ <list>
+ slide breaks
+
+ overlays
+
+ 2-column
+
+ different diagram layouts
+
+ color
+
+ persistent outline
+
+ watermark/logo
+ </list>
+ </list>
+
+ <heading title="JavaDoc Features We Like"/>
+ <pre>
+
+ /** */
+ ///
+ ///<
+ @param
+ @throws
+ @see
+ @link, autolinking (wiki-style?) of other classes/modules
+ @return
+ @deprecated
+ @since
+ @author?
+ package-level overview (but it's lame to put it in a separate file)
+ inheritance
+
+ </pre>
+ </section>
+
+</ibex-doc>
\ No newline at end of file
--- /dev/null
+%
+% pdftricks.sty
+%
+% Copyright (c) 2001, Radhakrishnan CV <cvr@river-valley.com>
+% Rajagopal CV <cvr3@river-valley.com>
+% http://www.river-valley.com
+%
+% River Valley Technologies, Software Technology Park,
+% Trivandrum, India 695034
+%
+% Tel: +91 471 33 7501/7502
+%
+% Antoine Chambert-Loir
+% <chambert@math.polytechnique.fr>
+% http://www.math.polytechnique.fr/~chambert
+%
+% Ecole polytechnique, Palaiseau Cedex, France
+%
+%
+% This program is free software; you can redistribute it and/or
+% modify it under the terms of the GNU General Public License
+% as published by the Free Software Foundation; either version 2
+% of the License, or (at your option) any later version.
+%
+% This program is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with this program (gpl.txt); if not, write to the Free
+% Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+% MA 02111-1307, USA.
+%
+% $Id: pdftricks.sty,v 1.15 2001/09/30 11:21:23 cvr Exp $
+%
+\NeedsTeXFormat{LaTeX2e}
+\def\Fileversion$#1: #2 ${\gdef\fileversion{#2}}
+\def\Filedate$#1: #2 #3 ${\gdef\filedate{#2}}
+\Fileversion$Revision: 1.15 $
+\Filedate$Date: 2001/09/30 11:21:23 $
+\ProvidesPackage{pdftricks}
+ [\filedate\space\fileversion\space psTricks support in PDF (CVRACL)]
+\PackageWarningNoLine{pdftricks}
+ {****************************************\MessageBreak
+ Package pdftricks v,\fileversion\space loaded\MessageBreak
+ [psTricks support in PDF (CVR, ACL)]\MessageBreak
+ ****************************************}
+\RequirePackage{graphicx,color}
+\newif\if@debug\@debugfalse
+\newif\ifPDFTshell
+\newif\ifPDFTnopdf
+\newif\ifnoprocess \noprocessfalse
+\newif\ifmiktex \miktexfalse
+\DeclareOption{debug}{\@debugtrue}
+\DeclareOption{noshell}{\PDFTshellfalse}
+\DeclareOption{shell}{\PDFTshelltrue}
+\DeclareOption{miktex}{\global\miktextrue}
+\ExecuteOptions{shell}
+\ProcessOptions\relax
+\ifPDFTshell
+% we must set it to false if \write18 doesn't work.
+% Hack given by Thierry Bouche (Thanks !)
+\def\tmpfile{/tmp/w18-test-\the\year\the\month\the\day\the\time}
+\ifmiktex%
+ \immediate\write18{rem >"\tmpfile"}%%%%%% LDL-2
+\else
+ \immediate\write18{touch \tmpfile} %%%%%% LDL-1
+\fi
+\ifmiktex
+ \IfFileExists{\tmpfile.}{\PDFTshelltrue}{\PDFTshellfalse} %%%%%% LDL-4
+\else
+ \IfFileExists{\tmpfile}{\PDFTshelltrue}{\PDFTshellfalse} %%%%%% LDL-3
+\fi
+\fi
+\ifPDFTshell
+ \PackageWarningNoLine{pdftricks}
+ {****************************************\MessageBreak
+ Using \csname write\endcsname18 capability \MessageBreak
+ for producing PDF-figures. \MessageBreak
+ ****************************************}
+\else
+ \PackageWarningNoLine{pdftricks}
+ {****************************************\MessageBreak
+ No \csname write\endcsname18 capability.\MessageBreak
+ You'll have to run a script by yourself!\MessageBreak
+ ****************************************}
+\fi
+
+% warning! the definition of FIGURES if pst2pdf must be set accordingly !!
+\def\PDFTfigname{\jobname-fig\thepsfig}
+\def\PDFTWarning#1#2{\if@debug\PackageWarning{#1}{#2}\fi}
+\def\PDFTWarningNoLine#1#2{\if@debug\PackageWarningNoLine{#1}{#2}\fi}
+\def\makeinnocent#1{\catcode`#1=12 }
+\def\csarg#1#2{\expandafter#1\csname#2\endcsname}
+\def\latexname{lplain}\def\latexename{LaTeX2e}
+\newwrite\PDFStream
+
+\long\def\ProcessStream#1% start it all of
+ {\begingroup%
+ \def\CurrentStream{#1}%
+ \let\do\makeinnocent \dospecials
+ \makeinnocent\^^L% and whatever other special cases
+ \endlinechar`\^^M \catcode`\^^M=12 \xStream}
+{\catcode`\^^M=12 \endlinechar=-1 %
+ \gdef\xStream#1^^M{%
+ \expandafter\ProcessStreamLine}
+ \gdef\ProcessStreamLine#1^^M{\def\test{#1}
+ \csarg\ifx{End\CurrentStream Test}\test
+ \edef\next{\noexpand\EndOfStream{\CurrentStream}}%
+ \else \ThisStream{#1}\let\next\ProcessStreamLine
+ \fi \next}
+}
+\long\def\streaminfo{\string\end{document}}
+\def\CSstringmeaning#1{\expandafter\CSgobblearrow\meaning#1}
+\def\CSstringcsnoescape#1{\expandafter\CSgobbleescape\string#1}
+{\escapechar-1
+\expandafter\expandafter\expandafter\gdef
+ \expandafter\expandafter\expandafter\CSgobblearrow
+ \expandafter\string\csname macro:->\endcsname{}
+}
+\def\CSgobbleescape#1{\ifnum`\\=`#1 \else #1\fi}
+\def\WriteStreamLine#1{\def\CStmp{#1}%
+ \immediate\write\PDFStream{\CSstringmeaning\CStmp}}
+
+\def\AfterIncludedStream
+ {\immediate\closeout\PDFStream %changed on 2001/1/20
+ \relax
+ }%
+\def\BeforeIncludedStream
+ {\stepcounter{psfig}\xdef\PDFCutFile{\PDFTfigname.tex}%
+ \message{Opening PDFStream=\PDFCutFile}%
+ \immediate\openout\PDFStream=\PDFCutFile
+ \immediate\write\PDFStream{\string\documentclass{article}}
+ \immediate\write\PDFStream{\string\input\space tmp.inputs}
+ \immediate\write\PDFStream{\string\pagestyle{empty}}
+ \immediate\write\PDFStream{\string\usepackage{amssymb,amsbsy}}
+ \immediate\write\PDFStream{\string\begin{document}}
+ \let\ThisStream\WriteStreamLine}
+\long\def\specialstream #1#2#3{%
+ \message{Special stream '#1'}%
+ \csarg\def{After#1Stream}{#2\AfterIncludedStream#3}%
+ \csarg\def{#1}{\BeforeIncludedStream\relax
+ \ProcessStream{#1}}%
+ \PDFEndDef{#1}}
+\def\EndOfStream#1{\endgroup\end{#1}%
+ \csname After#1Stream\endcsname}
+\def\PDFEndDef#1{{\escapechar=-1\relax
+ \csarg\xdef{End#1Test}{\string\\end\string\{#1\string\}}%
+ }}
+%%
+%% The real meat of psfile manipulation starts here.
+%%
+%%
+\AtEndDocument{\endPShook%
+ \ifPDFTnopdf
+ \PackageWarningNoLine{pdftricks}
+ {******************************************\MessageBreak
+ Some PDF files of images were not found.\MessageBreak
+ Run the script `pst2pdf' before the next\MessageBreak
+ run of pdfLaTeX\MessageBreak
+ ******************************************}
+ \fi
+}
+\gdef\endPShook{}
+\def\noprocess{\global\noprocesstrue
+ \PackageWarning{pdftricks}
+ {******************************************\MessageBreak
+ Figure Number: \PDFTfigname\space is not processed \MessageBreak
+ ******************************************\MessageBreak}
+}
+\specialstream{pdfpic}{%
+ \immediate\write\PDFStream{\streaminfo}}
+ {\psgraphicsinclude\global\noprocessfalse}
+\newcounter{psfig}
+\newif\if@pdfGINwidth
+\newif\if@pdfGINheight
+\newif\if@pdfGINscale
+\long\gdef\psgraphicsinclude{%
+ \@ifundefined{Fig\thepsfig}
+ {\PDFTWarningNoLine{pdftricks}
+ {******************************************\MessageBreak
+ ************ Processing Fig: \thepsfig\space**********\MessageBreak
+ ******************************************}
+ }
+ {\noprocess}
+ \ifPDFTshell\ifnoprocess\relax\else
+ \IfFileExists{\PDFTfigname.tex}{%
+ \immediate\write18{latex -interaction=batchmode \PDFTfigname}
+ \PDFTWarningNoLine{pdftricks}
+ {******************************************\MessageBreak
+ \PDFTfigname.tex converted to \PDFTfigname.dvi\MessageBreak
+ ******************************************}
+ }{}
+ \IfFileExists{\PDFTfigname.dvi}{%
+ \immediate\write18{dvips -o \PDFTfigname.ps \PDFTfigname}
+ \immediate\write18{ps2eps -f \PDFTfigname.ps}
+ \PDFTWarningNoLine{pdftricks}
+ {******************************************\MessageBreak
+ \PDFTfigname.eps generated\MessageBreak
+ ******************************************}
+ }{}
+ \IfFileExists{\PDFTfigname.eps}{%
+ \immediate\write18{epstopdf \PDFTfigname.eps}
+ \PDFTWarningNoLine{pdftricks}
+ {******************************************\MessageBreak
+ \PDFTfigname.eps converted to \PDFTfigname.pdf\MessageBreak
+ ******************************************}
+ }{}
+ \ifmiktex%
+ \immediate\write18{del \PDFTfigname.aux \PDFTfigname.dvi \PDFTfigname.log \PDFTfigname.eps} %%%%%% LDL-6
+ \else
+ \immediate\write18{rm \PDFTfigname.aux \PDFTfigname.dvi \PDFTfigname.log \PDFTfigname.eps} %%%%%% LDL-5
+ \fi\fi
+ \fi
+ \IfFileExists{\PDFTfigname.pdf}%
+ {\begin{center}
+ \bgroup\fboxsep\@PDFboxsep\fboxrule\@PDFboxrule%
+ \color{\@PDFgraphiccolor}%
+ \fcolorbox{\@PDFgraphiclinecolor}{\@PDFgraphicbackground}%
+ {\if@pdfGINwidth%
+ \includegraphics[width=\@PDFgraphicwidth]{\PDFTfigname}\else%
+ \if@pdfGINheight%
+ \includegraphics[height=\@PDFgraphicheight]{\PDFTfigname}\else%
+ \if@pdfGINscale%
+ \includegraphics[scale=\@PDFgraphicscale]{\PDFTfigname}\else%
+ \includegraphics{\PDFTfigname}\fi\fi\fi%
+ }\egroup\end{center}%
+ \global\@pdfGINwidthfalse\let\@PDFgraphicwidth\relax
+ \global\@pdfGINheightfalse\let\@PDFgraphicheight\relax
+ \global\@pdfGINscalefalse\let\@PDFgraphicscale\relax
+ }{\PDFTnopdftrue}
+ \gdef\@PDFgraphiclinecolor{white}
+ \gdef\@PDFgraphicbackground{white}
+ \gdef\@PDFboxsep{0pt}
+ \gdef\@PDFboxrule{0pt}
+}
+\definecolor{gray30}{gray}{.70}
+\definecolor{gray10}{gray}{.90}
+\RequirePackage{keyval}
+\def\configure[#1][#2]{\setkeys{#1}{#2}
+ \PDFTWarning{pdftricks}{Reconfigured #1 parameter(s)\MessageBreak #2\MessageBreak}
+ }
+\define@key{pdfgraphic}{width} {\gdef\@PDFgraphicwidth{#1}\global\@pdfGINwidthtrue}
+\define@key{pdfgraphic}{height} {\gdef\@PDFgraphicheight{#1}\global\@pdfGINheighttrue}
+\define@key{pdfgraphic}{scale} {\gdef\@PDFgraphicscale{#1}\global\@pdfGINscaletrue}
+\define@key{pdfgraphic}{color} {\gdef\@PDFgraphiccolor{#1}}
+\define@key{pdfgraphic}{linecolor} {\gdef\@PDFgraphiclinecolor{#1}}
+\define@key{pdfgraphic}{background}{\gdef\@PDFgraphicbackground{#1}}
+\define@key{pdfgraphic}{linewidth} {\gdef\@PDFboxrule{#1}}
+\define@key{pdfgraphic}{rulesep} {\gdef\@PDFboxsep{#1}}
+\gdef\@PDFgraphiccolor{black}
+\gdef\@PDFgraphiclinecolor{white}
+\gdef\@PDFgraphicbackground{white}
+\gdef\@PDFboxrule{0pt}
+\gdef\@PDFboxsep{0pt}
+%%
+%% Tweak to grab all the packages used in the master doc.
+%% This forces you to load pdftricks as the first package.
+%%
+\newenvironment{psinputs}{\begingroup
+ \newwrite\CVinputs
+ \immediate\openout\CVinputs=tmp.inputs
+ \def\usepackage{\@ifnextchar[\@CVUsepackage\@@CVUsepackage}
+ \def\@CVUsepackage[##1]##2{\immediate\write\CVinputs%
+ {\string\usepackage[##1]{##2}}}
+ \def\@@CVUsepackage##1{\immediate\write\CVinputs%
+ {\string\usepackage{##1}}}
+ }
+ {\endgroup\immediate\closeout\CVinputs}
+%%
+%% Arrays to keep the fig numbers
+%%
+\newcounter{arraylength}%
+\newcounter{ArrayIndex}%
+\newcounter{zeroCtr}%
+\newcounter{recordCtr}
+\setcounter{recordCtr}{1}
+\newcounter{Ctr}
+\def\DeclareArray#1{\Array{#1}[0]{}}%
+%
+\def\Array#1[#2]#3{%
+ \expandafter\gdef\csname #1#2\endcsname{#3}%
+ \expandafter\gdef\csname #1\endcsname[##1]{\csname #1##1\endcsname}}%
+%
+\def\getArraylength#1{\setcounter{arraylength}{0}%
+ \loop\expandafter\ifx\csname #1\thearraylength\endcsname\relax%
+ \else\stepcounter{arraylength}\repeat}%
+%
+\def\addToArray#1#2{\setcounter{arraylength}{0}%
+ \loop\expandafter\ifx\csname #1\thearraylength\endcsname\relax%
+ \else\stepcounter{arraylength}\repeat%
+ \Array{#1}[\thearraylength]{#2}}%
+%
+\def\clearArray#1{\getArraylength{#1}%
+ \loop\ifnum\c@arraylength >0%
+ \global\expandafter\let\csname #1\thearraylength\endcsname\relax%
+ \addtocounter{arraylength}{-1}\repeat}%
+%
+\long\def\ArrayIterator#1#2{%
+ \setcounter{ArrayIndex}{1}\getArraylength{#1}%
+ \setcounter{zeroCtr}{\c@arraylength}%
+ \loop\ifnum\c@ArrayIndex<\c@zeroCtr{#2}%
+ \stepcounter{ArrayIndex}\repeat%
+}%
+\def\@nnil{\@nil}
+\def\@empty{}
+\def\@cvrstop#1\@@#2{}
+%%
+%% Equivalent of \@tfor and \@for where any delimiter can be
+%% provided instead of LaTeX's default comma character
+%%
+\long\def\cvr@delimfor#1#2#3{\DeclareArray{#1}\clearArray{#1}%
+ \long\def\@icvrloop##1#2##2\@@##3{\def##3{##1}\ifx ##3\@nnil%
+ \expandafter\@cvrstop \else\addToArray{#1}{##1}%
+ \relax\expandafter\@icvrloop\fi##2\@@##3}%
+ \long\def\@cvrloop##1#2##2#2##3\@@##4{\addToArray{#1}{##1}%
+ \def##4{##1}\ifx ##4\@nnil \else%
+ \def##4{##2}\def\y@y{##2}\ifx\y@y\@nnil\else%
+ \addToArray{#1}{##2}\fi\ifx ##4\@nnil \else%
+ \@icvrloop ##3\@@##4\fi\fi}%
+ \expandafter\def\expandafter\@fortmp\expandafter{#3}%
+ \ifx\@fortmp\@empty \else%
+ \expandafter\@cvrloop#3#2\@nil#2\@nil\@@\@ee@\fi}%
+%
+% Dont look into the following code. It is harmful
+% for your eyes and brain as well.
+%
+\newcounter{f@irstCtr}
+\newcounter{s@econdCtr}
+\long\gdef\NoProcess[#1]{%
+ \long\def\@i@@noprocess##1,##2\@@##3{\def##3{##1}\ifx ##3\@nnil%
+ \expandafter\@cvrstop \else
+ \expandafter\hyphencheck##1-@-*[*]
+ \relax\expandafter\@i@@noprocess\fi##2\@@##3}%
+ \long\def\@@@noprocess##1,##2,##3\@@##4{
+ \expandafter\hyphencheck##1-@-*[*]
+ \def##4{##1}\ifx ##4\@nnil \else%
+ \def##4{##2}\def\y@y{##2}\ifx\y@y\@nnil\else%
+ \expandafter\hyphencheck##2-@-*[*]
+ \fi\ifx ##4\@nnil \else%
+ \@i@@noprocess ##3\@@##4\fi\fi}%
+ \expandafter\def\expandafter\@fortmp\expandafter{#1}%
+ \ifx\@fortmp\@empty \else%
+ \expandafter\@@@noprocess#1,\@nil,\@nil\@@\@ee@\fi}%
+\def\d@d#1[*]{}
+\def\hyphencheck#1-#2-#3{\def\r@r{@}\def\s@s{*}\edef\c@c{#3}
+ \ifx\c@c\r@r
+ \setcounter{f@irstCtr}{#1}
+ \setcounter{s@econdCtr}{#2}
+ \stepcounter{s@econdCtr}
+ \loop\ifnum\thes@econdCtr > \thef@irstCtr%
+ \expandafter\edef\csname Fig\thef@irstCtr\endcsname{TRUE}
+ \stepcounter{f@irstCtr}
+ \repeat%
+ \else\ifx\c@c\s@s%
+ \expandafter\edef\csname Fig#1\endcsname{TRUE}
+ \fi\fi\d@d}
+
+%%
+%%
+%% End of file `pdftricks.sty'
+%%
--- /dev/null
+<ibex-doc title="The Ibex Reference" subtitle="Nitrogen Release" author="Adam Megacz" email="adam@ibex.org">
+
+<!-- ----------------------------------------------------------------------- -->
+<section title="Introduction">
+
+ **
+ If you are reading the html version of this document and are
+ thinking of printing it out, you might be interested in the nicely
+ typeset <link url="reference.pdf" text="pdf version"/> produced
+ with LaTeX.
+ **
+
+ This document is a __reference__. It is not a
+ __specification__ or a
+ __tutorial__.
+
+ This document does not guide the user gently through examples (as a
+ tutorial would), and it doesn't provide enough detail and formality
+ for a third party to construct a compatible re-implementation of the
+ Ibex Core (as a specification would).
+
+ Rather, the goal of this document is to completely describe every
+ aspect of the environment that the Ibex Core provides to client
+ applications, from the bottom up. If you want to be an Ibex expert,
+ this is the right document to read. It is assumed that you are already
+ familiar with XML and with either JavaScript or ECMAscript.
+
+ If you need to use or rely on some behavior you notice in the Ibex
+ Core, but which is not clearly defined here, please post to <link
+ url="http://lists.ibex.org/listinfo/users" text="the users mailing list"/>.
+
+ <section title="Key Concepts">
+
+ <definition term="The Core">
+ Ibex itself; the native code (or Java bytecode) that runs on
+ the client. This term does not include the **Wildebeest**
+ or the **UI**</definition>
+
+ <definition term="The UI / The Application">
+ A set of files (mostly XML, JavaScript, and PNG images)
+ bundled up in a zip archive, ending with the "[[.ibex]]"
+ extension. Together, these files specify the appearance and
+ behavior of the application's user interface.
+ </definition>
+
+ <definition term="The Server">
+ We will use the term "the server" to refer to any other
+ computer which the client makes XML-RPC or SOAP calls
+ to. Note that it is possible for the client and server to be
+ the same machine.</definition>
+
+ <definition term="Wildebeest">
+ This is a very small piece of code that is downloaded the
+ first time a client uses Ibex. It downloads the Ibex core,
+ verifies its signature, and launches it with the appropriate
+ parameters indicating where to find the initial UI.
+ Wildebeest works differently on every platform, and is outside
+ the scope of this document.</definition>
+
+ <definition term="put/write">
+ In ECMAscript, when you change the value of a property on an
+ object, you are **putting** to that property, or
+ **writing** to it. For example, the ECMAscript expression
+ "[[foo.bar = 5]]" **puts** the value 5 to the bar
+ property on object foo.</definition>
+
+ <definition term="get/read">
+ In ECMAscript, when you access the value of a property on an
+ object, you are **getting** that property, or
+ **reading** from it. For example, the ECMAscript
+ expression "[[return (3 + foo.bar)]]" **gets** the
+ value of bar property on object foo and then adds 3 to it
+ before returning the result.</definition>
+
+ <definition term="JavaScript">
+ We will use the terms JavaScript and ECMAScript
+ interchangeably in this document. The Ibex interpreter is not
+ completely ECMA-compliant, however (see <link
+ appendix="ECMAscript compliance"/> for details).
+ </definition>
+
+ </section>
+
+ <section title="Life Cycle of an Ibex Application">
+
+ <image url="lifecycle.pdf" caption="The Lifecycle of an Ibex Application"/>
+
+ A user typically begins an Ibex session by clicking on a link to
+ an Ibex application. This link serves the {\tt launch.html} file
+ to the user's browser, which in turn downloads the appropriate
+ {\it Wildebeest} -- currently either an ActiveX Control
+ (Win32/MSIE), XPInstaller (Mozilla), or Signed Applet (all
+ others).
+
+ The Wildebeest downloads the appropriate core for the user's
+ machine and verifies its digital signature. It then launches the
+ core, which downloads the UI (an [[.ibex]] archive), loads it,
+ applies the [[main.t]] template (found in the archive), and
+ renders it onto the screen, running any associated JavaScript
+ code.
+
+ The user interacts with the application by clicking and moving the
+ mouse, and by pressing keys on the keyboard. These actions trigger
+ fragments of JavaScript code which are designated to handle events.
+ This JavaScript code can then relay important information back to the
+ server using XML-RPC or SOAP, or it can modify the structure and
+ properties of the user interface to change its appearance, thereby
+ giving feedback to the user.
+
+ The Ibex core quits when the last remaining surface has been destroyed.
+
+ </section>
+
+
+ <section title="Surfaces">
+
+ <image url="offscreen.pdf" width="2in"
+ caption="An Ibex surface positioned at (83,0)"/>
+ Each top-level window in an Ibex UI is called a
+ **surface**. There are two kinds of surfaces: **frames**,
+ which usually have a platform-specific titlebar and border, and
+ **windows**, which never have any additional platform-specific
+ decorations.
+
+ Whenever we refer to the size or position
+ of a surface, we are referring to the size or position of the
+ UI-accessible portion of the surface; this does not include any
+ platform-specific decorations. This means that if you set the
+ position of a frame to (0,0), the platform-specific titlebar will
+ actually be off the screen on most platforms (it will be above and
+ to the left of the top-left corner of the screen).
+
+ Surfaces are not actual JavaScript objects; you cannot obtain a
+ reference to a surface. However, each surface is uniquely identified
+ by its **root box**, described in the next section.
+
+ </section>
+
+ <section title="Boxes">
+
+ A **box** is the fundamental unit from which all Ibex user
+ interfaces are built. Boxes can contain other boxes (referred to as
+ its **children**). Each surface has a single box associated with
+ it called the **root box**; the root box and its children (and
+ its children's children, and so on) form the surface's **box
+ tree**.
+
+ There are three ways to think of a box:
+ <list>
+
+ As a rendered visualization on the screen (the "**Visual Representation**")
+
+ As a JavaScript object (the "**Object Representation**")
+
+ As as an XML tag (the "XML Template Representation").
+
+ </list>
+
+ <image url="threeviews.pdf" caption="The three representations of an Ibex box"/>
+
+ All three representations are equally valid, and being able to
+ figure out what an action in one representation would mean in terms
+ of the other two representations is crucial to a solid understanding
+ of Ibex.
+
+ </section>
+</section>
+
+<section title="The XML Template Representation">
+
+ A template (discussed in the next section) is an XML file which acts
+ as a blueprint for constructing a tree of boxes. We call this
+ construction process **applying**, since unlike
+ **instantiation** in object-oriented programming systems, you
+ always apply a template to a pre-existing box, and you can apply
+ multiple templates to the same box.
+
+ Each XML tag corresponds to a single box, or to another template
+ which will be applied to that box. For example, a [[scrollbar]]
+ template, when applied, will construct a tree of boxes which has the
+ visual appearance and behavior of a scrollbar.
+
+ Although it is useful to think of the XML tags as being boxes, keep
+ in mind that the XML representation is only a blueprint for
+ constructing a tree of JavaScript objects. Once the template has
+ been instantiated, the XML is effectively "thrown away", and
+ JavaScript code is free to alter the boxes. Once the process of
+ applying a template is complete, Ibex completely forgets the fact
+ that it has applied a particular template to a particular box. One
+ consequence of this approach is that if you think of templates as
+ classes, then Ibex has no equivalent for Java's [[instanceof]]
+ operator.
+
+ Each template is an XML document whose root element is
+ [[<ibex>]]. Here is a sample template file:
+
+ <pre>
+ <ibex xmlns:lib="ibex.lib">
+
+ <meta:doc>
+ This is a cool widget.
+ </meta:doc>
+
+ // this code is executed only once
+ static = { instances : [] };
+
+ // this element applies the ibex.lib.focusable template
+ <lib:focusable/>
+
+ <ui:box cols="5">
+ static.instances.push(thisbox);
+ <ui:box id="container"/>
+ <ui:checkbox/>
+ <ui:box>
+ <lib:scrollbar/>
+ </ui:box>
+ </ui:box>
+ </ibex>
+ </pre>
+
+ The following two namespaces are predefined and need not be declared
+ using [[xmlns]]:
+
+ <definition term="meta">
+ [[http://xmlns.ibex.org/meta]]
+
+ This will be referred to as the "[[meta]] namespace" in the
+ remainder of this document.
+ </definition>
+
+ <definition term="ui">
+ [[http://xmlns.ibex.org/ui]]
+
+ This will be referred to as the "[[ui]] namespace" in the
+ remainder of this document.
+ </definition>
+
+ Additionally, the default namespace for the document will be set to
+ the template's package FIXME.
+
+ <section title="Static Code">
+
+ If the root [[<ibex>]] element contains any non-whitespace
+ text content, this text is interpreted as JavaScript code and is
+ executed the first time the template is referenced. This code is
+ executed in a fresh scope containing two predefined properties:
+
+ <definition term="ibex">
+ The Ibex Object (described in <ref section="The Ibex Object"/>)
+ </definition>
+
+ <definition term="static">
+ A reference to this template's **static object**, which is
+ initially [[null]]. The static object can be accessed (read
+ and written) from both static scripts as well as instance
+ scripts in a particular template. FIXME
+ </definition>
+ </section>
+
+ <section title="Metadata">
+
+ Any immediate children of the root element which are in the
+ [[meta]] namespace are treated as metadata and are exempted from
+ the rest of the template application process. Currently only one
+ type of metadata element is defined:
+
+ <list>
+ [[<meta:doc>]]: structured documentation for the
+ template.
+ </list>
+
+ </section>
+
+ <section title="Other Elements">
+
+ All remaining children of the root element are treated as elements
+ to be **applied** to the box, in the order in which they appear
+ in the file using the following procedure.
+
+ <remark text="While this process outlined below sounds very
+ complex, it actually works pretty intuitively. The
+ description below is given in great detail since
+ most applications will wind up being unintentionally
+ dependent on subtle features of this process.
+ However, most of the time you can just pretend that
+ the XML tags and the boxes are the same thing."/>
+
+ <heading title="Intuitive Description"/>
+
+ ... FIXME
+
+ During a box initialization, script-private references to a
+ box's descendants with [[id]] attributes are placed on the
+ box. These references allow scripts on that box to easily refer
+ to descendant nodes created by the template in which the script
+ appears. For example, these two blocks of code have exactly the
+ same effect:
+
+ <pre>
+ <ui:box> <ui:box>
+ <ui:box id="foo"/> <ui:box/>
+ $foo.color = "red"; var $foo = this[0];
+ $foo.color = "red";
+ </ui:box> </ui:box>
+ </pre>
+
+ <heading title="Precise Description"/>
+
+ To apply an XML tag [[__x__]] to a box [[__b__]], perform the following
+ operations, in this order:
+
+ <list type="ordered">
+
+ Allocate a fresh scope [[__s__]] whose parent scope is
+ [[__b__]].
+
+ Process each child element or text segment of [[__x__]]
+ in the order they appear in the document:
+
+ <list>
+
+ Treat each text segment [[__t__]] as JavaScript code
+ and execute it with [[__s__]] as the root scope.
+
+ For each child element [[__x'__]] of [[__x__]]:
+
+ <list>
+ Create a new box [[__b'__]].
+
+ If the name of tag [[__x'__]] is not
+ "[[box]]" in the [[ui]] namespace, prepend the
+ tag's namespace identifier uri (if any) to the name of
+ the tag, and use the result as a key to retrieve a
+ property from the root stream (defined later).
+ Interpret the resulting stream as a template and apply
+ that template to [[__b'__]].
+
+ (recursively) apply [[__x'__]] to [[__b'__]].
+
+ If [[__x'__]] has an [[id]] attribute, declare a variable
+ in [[__s__]] whose name is the value of the [[id]]
+ attribute, prefixed with the [[$]] character, and whose
+ value is [[__b'__]]
+
+ Copy any [[$]]-variables created during the application
+ of [[__x'__]] into scope [[__s__]].
+
+ Append [[__b'__]] as the last child of [[__b__]].
+ </list>
+ </list>
+
+ Apply any attributes on [[__x__]] to [[__b__]], except for
+ [[id]]. Since XML specifies that the order of attributes
+ cannot be significant, Ibex processes attributes in
+ alphabetical order by attribute name. For example, if
+ [[__x__]] has the attribute [[foo="bar"]], then the
+ equivalent of the statement [[B.foo="bar";]] will be
+ performed, with the following exceptions:
+
+ <list>
+ If the value portion of the attribute is the string
+ "[[true]]", put the boolean [[true]]. If the
+ value is "[[false]]", put the boolean [[false]].
+
+ If the value is a valid ECMAscript number, put it as a
+ number (instead of a string).
+
+ If the value begins with a dollar sign ([[$]]),
+ retrieve the value of the corresponding variable in
+ [[__s__]] and use that value instead.
+
+ If the value begins with a dot ([[.]]), prepend the
+ attributes' namespace identifier uri (if any) and
+ interpret the remainder as a property to be retrieved from
+ the root stream (defined later).
+ </list>
+ </list>
+
+ <heading title="Initialization Invariants"/>
+
+ The last two steps are referred to as the **initialization** of the
+ node. There are two important aspects of this ordering to be aware of:
+
+ <list type="unordered">
+
+ A given box will be fully initialized before its parent is
+ given a reference to that box. This way, parents can be
+ certain that they will never wind up accessing a box when it
+ is in a partially-initialized state.
+
+ Attributes are applied **after** scripts are run so that
+ the attributes will trigger any **traps** (defined later)
+ placed by the script.
+
+ </list>
+
+ </section>
+
+</section>
+
+<!-- ----------------------------------------------------------------------- -->
+<section title="Layout and Rendering">
+
+ Each box occupies a rectangular region on the surface. The visual
+ appearance of a surface is created by rendering each box in its tree.
+ Unless the [[clip]] attribute is [[false]], each box will
+ clip its childrens' visual representations to its own, so that the
+ children appear "confined to" the parent. Children are rendered after
+ their parents so they appear "on top of" their parents.
+
+ Each box has two major visual components, each with subcomponents:
+
+ FIXME: diagram
+
+ <definition term="path">
+
+ A box's [[path]] consists of zero or more lines and curves.
+ The path may be filled with a color, gradient, or texture, and
+ may be stroked with a line of a given thickness and color. If
+ the path is not specified, it defaults to the perimiter of the
+ box. [**Note: Vector Graphics support (including the ability
+ to set the [[path]] property to anything other than the
+ default) is currently not implemented**].
+
+ A path also has:
+
+ <list>
+ an associated [[strokecolor]], which is a color
+
+ an associated [[strokewidth]], which is a number
+ specifying the width of the stroke. [**Note: Vector
+ Graphics support (including the [[strokewidth]]
+ property) is currently not implemented**]
+
+ a [[fill]], which is either a color, gradient, or
+ texture
+ </list>
+ </definition>
+
+ <definition term="text">
+
+ Each box also has a single line of [[text]], whose
+ appearance is determined by its:
+
+ <list>
+ associated [[font]], which can be any font supported by
+ the <link url="http://www.freetype.org" text="FreeType2"/>
+ library.
+
+ an associated [[fontsize]] in **pixels**
+
+ an associated [[textcolor]]
+ </list>
+ </definition>
+
+ These eight components plus the size of a box fully specify its
+ appearance. Every single box you see in Ibex is drawn only on the
+ basis of these components and its size.
+
+ The size and position of every box is determined by its
+ properties, its childrens' sizes, and its parent's size and
+ position. Box layout and rendering happens in four phases:
+ **packing**, **constraining**, **placing**, and
+ **rendering**. The Core is careful to only perform a phase on
+ a box if the box has changed in a way that invalidates the work
+ done the last time that phase was performed. The packing and
+ constraining phases are performed in a single traversal of the
+ tree (packing is preorder, constraining is postorder), and the
+ placing and rendering phases are performed in a second traversal
+ of the tree (first placing, then rendering, both preorder).
+
+ For brevity, the rest of this chapter deals only with width and
+ columns. Height and rows is treated identically and independently.
+ Also, it is important to note that the term **minimum width** is
+ not the same thing as the property [[minwidth]], although they
+ are closely related.
+
+ <heading title="The Size of the Root Box"/>
+
+ When the user resizes a window, Ibex changes the root box's
+ [[maxwidth]] and [[maxheight]] to match the size chosen by
+ the user and then determines the root box's size using the same sizing
+ rules it uses for other boxes.
+
+ Ibex will always attempt to prevent the
+ user from making the surface smaller than the root box's
+ [[minwidth]] and [[minheight]]. If the [[hshrink]] or
+ [[vshrink]] flag is set, Ibex will try to prevent the user from
+ resizing the surface at all. However, not all platforms give Ibex
+ enough control to do this.
+
+ <heading title="The alignment point"/>
+
+ When talking about positioning, we will often refer to the
+ **alignment point**.
+
+ If the [[align]] property is "[[center]]", then the
+ alignment point is the center of the box.
+
+ If the [[align]] property is "[[topleft]]",
+ "[[bottomleft]]", "[[topright]]", or
+ "[[bottomright]]", then the alignment point is
+ corresponding corner of the box.
+
+ If the [[align]] property is "[[top]]",
+ "[[bottom]]", "[[right]]", or "[[left]]", then
+ the alignment point is middle of the corresponding edge of the
+ box.
+
+ <section title="Packing">
+
+ A grid of **cells** is created within the parent. If the
+ parent's [[cols]] property is set to 0, the cell grid has an
+ infinite number of columns. Either [[cols]] or [[rows]]
+ must be zero, but not both.
+
+ If a child's [[visible]] property is [[false]], it does
+ not occupy any cells (and is not rendered). Otherwise, each child
+ occupies a rectangular set of cells [[child.colspan]] cells
+ wide and [[child.rowspan]] cells high.
+
+ The Core iterates over the cells in the grid in the following
+ order: if [[rows]] is 0, the Core iterates across each column
+ before proceeding to the next row; otherwise rows come before
+ columns. At each cell, the Core attempts to place the **first
+ remaining unplaced child's** top-left corner in that cell
+ (with the child occupying some set of cells extending down and
+ to the right of that cell). If the parent has a fixed number of
+ columns and the child's [[colspan]] exceeds that limit, the
+ child is placed in column zero regardless, but only occupies the
+ available set of cells (it does not "hang off the end" of the
+ box). <image url="layout.pdf" width="1in"/>
+
+ <pre>
+ <ui:box cols="3">
+ <ui:box id="1" />
+ <ui:box id="2" rowspan="2" />
+ <ui:box id="3" colspan="2" />
+ <ui:box id="4" />
+ <ui:box id="5" colspan="2" />
+ </ui:box>
+ </pre>
+
+ </section>
+
+ <section title="Constraining">
+
+ Each box's minimum width is computed recursively as the
+ maximum of:
+
+ <list>
+ Its [[minwidth]]
+
+ The width of the box's [[text]] (after applying the
+ box's [[transform]]) [**Note: Vector Graphics support
+ (including the [[transform]] property) is currently not
+ implemented**].
+
+ The width of the box's path (after applying the box's
+ [[transform]]) **if the box is [[packed]]**.
+
+ The minimum width of the children in each row.
+ </list>
+
+ If a box's [[hshrink]] property is set to
+ [[true]], the box's maximum width is the same as its
+ minimum width; otherwise it is the box's
+ [[maxwidth]].
+
+ </section>
+
+ <section title="Placing">
+
+ <heading title="Non-Packed Boxes"/>
+
+ Each non-packed box is transformed according to the parent's
+ [[transform]] property and then positioned so that its alignment
+ point is [[(child.x, child.y)]] pixels from the corresponding
+ edge/corner/center of its parent.
+
+ <heading title="Packed Boxes"/>
+
+ Ibex formulates a set of constraints for placing a box's
+ **packed** children as follows:
+
+ <list>
+ - A box's width can be no greater than the sum of the
+ columns it occupies
+ - The sum of a set of colums cannot be smaller than the
+ minimum width of a box that spans them.
+ - The sum of the widths of the parents' columns will be at
+ least as large as the parent's width is (but possibly
+ larger).
+ </list>
+
+ Subject to these two unbreakable constraints, Ibex searches for
+ a solution which will optimize the following three goals,
+ prioritized from most important to least important:
+
+ <list>
+ - (__Most Important__) The sum of all columns will be a close
+ to the parent's with as possible (ie as small as possible)
+ - Ibex will attempt to make a set of columns no wider than
+ the [[maxwidth]] of a box spanning them.
+ - (__Least Important__) Ibex will attempt to make all
+ columns the same width.
+ </list>
+
+ Each packed box is then placed within the set of cells that it
+ spans. Usually the box will exactly fill this rectangle; if it
+ does not (due to [[maxwidth]] or minimum width constraints), the
+ box's will be placed so that its alignment point coincides with
+ the alignment point of that rectangle of cells.
+
+ </section>
+
+ <section title="Rendering">
+
+ Boxes are rendered in a depth-first, pre-order traversal. Note that
+ this may cause a non-packed box to overlap its siblings.
+
+ <list type="ordered">
+
+ If the box's [[transform]] property is non-null, the
+ coordinate space is transformed accordingly for the rest of
+ this phase and for the rendering of all children. [**Note:
+ Vector Graphics support (including the [[transform]]
+ property) is currently not implemented**].
+
+ If the box is packed and has a non-[[null]] path, the
+ path is translated such that the alignment point of the path's
+ bounding box coincides with the box's alignment point (both
+ alignment points are determined by the box's [[align]]
+ property).
+
+ If a box has a path, that path is filled with the color,
+ gradient, or image specified by the [[fill]] property and
+ stroked with the color and width specified by the
+ [[strokecolor]] and [[strokewidth]] properties.
+
+ If the box has a non-null [[text]] attribute,
+ the text is rendered in [[font]] with size
+ [[fontsize]] and color [[textcolor]]. The text is
+ then translated such that the alignment point of the text's
+ bounding box coincides with the box's alignment point (both
+ alignment points are determined by the box's [[align]]
+ property).
+
+ The box's children are rendered (pre-order traversal).
+
+ </list>
+
+ </section>
+</section>
+
+<!-- ----------------------------------------------------------------------- -->
+<section title="Box Properties">
+
+ Each box is a full-fledged ECMAscript object, and can store
+ key-value pairs as properties. Some of these keys have special
+ meaning, which will be explained later. Each box's numeric
+ properties hold its **child boxes**.
+
+ <section title="Rendering Properties">
+
+ Every box has several special properties which control how it is
+ drawn. In general, if you put an
+ invalid value to a special property, no action will be taken -- the
+ put will be ignored.
+
+ <property name="strokecolor" type="string" default="clear">
+
+ If the value is a 5-character hex string ([[#RGB]]),
+ 7-character hex string ([[#RRGGBB]]), 9-character hex
+ string ([[#AARRGGBB]]), the box's stroke color will be set
+ to that color.
+
+ If the value is one of the <link
+ url="http://www.color.org/ICC-1A_1999-04.PDF"
+ text="ICC"/> colors (the same set of color names
+ supported by SVG), the stroke color be set to that color.
+
+ If the value is [[null]], the stroke color will be set
+ to clear ([[#00000000]]).
+ </property>
+
+ <property name="strokewidth" type="int" default="1">
+ The width (in pixels) to stroke the path with.
+ </property>
+
+ <property name="fill">
+ This property can be set to any of the values specified for
+ [[strokecolor]].
+ Alternatively, if the value written is an object, its stream
+ will be read and interpreted as a PNG, GIF, or JPEG image,
+ which will become the texture for this box, and the box's
+ [[minwidth]] and [[minheight]] properties will be
+ automatically set to the dimensions of the image.
+ </property>
+
+ <property name="path" type="string" default='""'>
+ The box's path. The grammar and feature set supported are
+ identical to that specified in <link
+ url="http://www.w3.org/TR/SVG11/paths.html" text="SVG 1.1,
+ section 8"/>.
+ </property>
+
+ <property name="text" type="string" default='""'>
+ The box's text; writing [[null]] to this property sets it
+ to [[""]].
+ </property>
+
+ <property name="textcolor" type="number" default="black">
+ The color in which to render the font; accepts the same values as [[strokecolor]].
+ </property>
+
+ <property name="font" type="stream" default=".ibex.ui.font.sansserif">
+ When an object is written to this property, its stream is read
+ using the <link url="http://www.freetype.org" text="FreeType 2 library"/>,
+ and the resulting font is used to render the
+ box's [[text]].
+ </property>
+
+ <property name="fontsize" type="number" default="10">
+ The size (in points) to render the text.
+ </property>
+
+ </section>
+
+ <section title="Layout Properties">
+
+ <property name="shrink" type="boolean" default="false">
+ If set to [[true]], this box will shrink
+ (horizontally/vertically/both) to the smallest size allowed by
+ its children and the bounding box of its path.
+ </property>
+
+ <property name="x y" type="integer" default="varies">
+ If the box is a root box, this is the (x/y)-coordinate of the
+ surface; otherwise it is the distance between the parent's
+ alignment point and the corresponding corner/edge/center of
+ its parent.
+ </property>
+
+ <property name="minwidth minheight" type="integer" default="0">
+ The desired minimum width and height.
+ </property>
+
+ <property name="maxwidth maxheight" type="integer" default="ibex.ui.maxdim">
+ The desired maximum width and height.
+ </property>
+
+ <property name="width height" type="integer">
+ When read, this is the current (width/height) of this box.
+ Writing to this property is equivalent to writing to
+ **both** the minimum and maximum (width/height).
+ </property>
+
+ <property name="cols rows" type="integer" default="0">
+ The number of (columns/rows) in which to lay out the children of this
+ box. If set to zero, the number of (columns/rows) is unconstrained.
+ Either [[rows]] or [[cols]] must be zero. If
+ [[0]] is written to [[cols]] when [[rows]] is
+ [[0]], the write is ignored. If a nonzero value is
+ written to [[cols]] when [[rows]] is nonzero,
+ [[rows]] is set to [[0]], and vice versa.
+ </property>
+
+ <property name="colspan rowspan" type="integer" default="1">
+ The number of (columns/rows) that this box spans within its parent.
+ </property>
+
+ <property name="align" type="string" default="center">
+ Determines the box's alignment point for positioning its text,
+ texture, path, and children.
+ </property>
+
+ <property name="visible" type="boolean" default="true">
+ If set to [[false]], this box will be rendered as if its
+ width and height were zero. If this is a root box, the
+ associated surface will be hidden.
+
+ When reading from this property, the value [[false]] will
+ be returned if this box **or any of its ancestors** is not
+ visible. Thus it is possible to write [[true]] to a box's
+ [[visible]] property and then read back [[false]].
+ </property>
+
+ <property name="packed" type="boolean" default="true">
+ The layout strategy for this box. If set to [[true]], the
+ box occupies no cells and is laid out independently of its
+ siblings.
+ </property>
+
+ </section>
+
+ <section title="Child Control Properties">
+
+ <property name="redirect" type="box" default="thisbox">
+ Writing to this property sets the box's redirect target. This
+ property cannot be read from, and can only be written to if
+ the value being written is a **descendant** of the current
+ value.
+
+ If a box has a non-null redirect target, reads and writes to
+ any of the other properties in this section will be forwarded
+ to the redirect target.
+
+ The [[redirect]] attribute is very useful for hiding the
+ internal structure of a widget, and for allowing widgets to act as
+ "smart" containers for other widgets. For example, a menu widget might
+ have an invisible child as its redirect target; this way, when boxes
+ representing items on the menu are added as children of the menu
+ widget, they do not appear until the menu is pulled down.
+ </property>
+
+ <property name="numeric properties" type="int" default="">
+ The **n**th child of box [[b]] can be accessed by reading from
+ [[b[n]]]. The **n**th child can be removed by writing
+ [[null]] to [[b[n]]] (the child will become parentless). A
+ new child can be inserted **before** the **n**th child by
+ writing it to [[b[n]]]; if the value written is already a child of
+ [[b]], it will be removed from [[b]] first. It is important
+ to note that this behavior is different from ECMAscript arrays --
+ writing a non-[[null]] value to [[b[n]]] does not eliminate
+ the **n**th child; it merely shifts it over one position.
+ __Note:__ Unlike most JavaScript objects, enumerating a Box's
+ properties with the JavaScript [[for..in]] construct will
+ enumerate **only** the box's children and not any other properties.
+ </property>
+
+ <property name="clip" type="boolean" default="true">
+ If [[true]], the visual representation of this box's
+ children will be clipped to the boundaries of this box.
+ __Note:__ setting this property to [[false]] imposes a
+ substantial performance penalty.
+ </property>
+
+ <property name="numchildren" type="integer" default="0">
+ The number of children this box has.
+ </property>
+
+
+ <property name="surface" type="" default="null">
+ FIXME
+ If this box has a parent, this property returns
+ [[**parent**.surface]]; otherwise it returns null.
+ This property is a simple building block that the widget
+ library uses to implement more complex functionality such as
+ focus control and popups.
+ </property>
+
+ </section>
+
+ <section title="Other Box Properties">
+
+ <property name="cursor" type="string" default="null">
+ The shape that the cursor should take when inside this
+ box. Valid values are: "[[default]]" , "[[wait]]",
+ "[[crosshair]]", "[[text]]", "[[hand]]", and
+ "[[move]]", as well as resizing cursors"[[east]]",
+ "[[west]]", "[[north]]", "[[south]]",
+ "[[northwest]]", "[[northeast]]",
+ "[[southwest]]", and "[[southeast]]". Note that on
+ some platforms, resize cursors for opposite directions (such
+ as [[northwest]] and [[southeast]] are the
+ same).
+ If a box's cursor is [[null]], its parent's cursor will
+ be used. If the root box's cursor is null, the
+ "[[default]]" cursor will be used.
+ </property>
+
+ <property name="static" type="object" default="N/A">
+ Reading from this property will return the parent scope used
+ to execute the [[<static/>]] block of the template
+ in which the currently-executing code resides.
+ </property>
+
+ <property name="thisbox" type="box" default=" ">
+ Returns a reference to the box itself.
+ If [[null]] is written to this property, and this box is
+ the root box of a surface, the box will be detached and the
+ surface destroyed. If this box has a parent, it will be
+ detached from its parent.
+ </property>
+
+ <property name="indexof()" type="function" default=" ">
+ This property is actually a function; invoking
+ [[parent.indexof(child)]] will return the numerical index
+ of [[child]] in [[parent]] if [[child]] is a
+ child of [[parent]] (or [[parent]]'s redirect
+ target), and [[-1]] otherwise. Writing to this property
+ has no effect.
+ </property>
+
+ <property name="distanceto()" type="function" default=" ">
+ This property is actually a function; invoking
+ [[box.distanceto(otherbox)]] will return an object with two
+ properties, [[x]] and [[y]], containing the horizontal
+ and vertical distance between the two boxes (negative if
+ [[otherbox]] is to the left of / above [[box]]). This
+ can be used to determine the relative placement of two boxes
+ on different branches of the box tree.
+ </property>
+
+ </section>
+
+ <section title="Root Box Properties">
+
+ The following special properties are only meaningful on the root box
+ of a surface.
+
+ <property name="Focused">
+ The value [[true]] is put to this property on the root box
+ when the surface gains the input focus, and [[false]] when
+ the surface loses the input focus. Reading from this value will
+ return [[true]] if the surface is focused and [[false]]
+ if it is not. Putting [[true]] to this property will
+ **not** cause the surface to "steal" the input focus from other
+ windows.
+ </property>
+
+ <property name="Maximized">
+ The value [[true]] is put to this property on the root box
+ when the surface is maximized, and [[false]] when the surface
+ is un-maximized. Reading from this value will return [[true]]
+ if the surface is maximized and [[false]] if it is
+ not. Putting [[true]] to this property will maximize the
+ window, and putting [[false]] to this property will
+ unmaximize the window.
+ Note that not all platforms support maximization.
+ </property>
+
+ <property name="Minimized">
+ The value [[true]] is put to this property on the root box
+ when the surface is minimized, and [[false]] when the surface
+ is unminimized. Reading from this value will return [[true]]
+ if the surface is minimized and [[false]] if it is
+ not. Putting [[true]] to this property will minimize the
+ window, and putting [[false]] will unminimize it.
+ </property>
+
+ <property name="Close">
+ When the user attempts to close a surface, the value
+ [[true]] will be put to this property. Scripts may trap
+ this property to prevent the window from closing. Putting the
+ value
+ [[true]] to this property on a root box has the same
+ effect as putting [[null]] to the [[thisbox]]
+ property.
+ </property>
+
+ <property name="icon">
+ The surface's icon. This is usually displayed on the titlebar of a
+ window. The value should be an object whose stream is a PNG image. Note
+ that not all platforms support this property.
+ </property>
+
+ <property name="titlebar">
+ The surface's titlebar text. Note that not all platforms support
+ this property. Only ASCII characters 0x20-0x7F are permitted.
+ </property>
+
+ </section>
+
+ </section>
+
+<!-- ----------------------------------------------------------------------- -->
+<section title="Streams">
+
+ <heading title="Every object has a stream..."/>
+
+ Every object has a **stream** associated with it. A stream is a
+ sequence of bytes that can be read or written to.
+
+ By default an object has an empty stream (zero bytes). However, some objects
+ (returned from special methods on the [[ibex]] object) have
+ streams yielding data read from an url, file, or a component of a zip
+ archive. In a future release, the stream associated with a box will
+ be an .ibex template which, when applied, will fully reconstitute the
+ box's state.
+
+ <heading title="...but streams are not objects"/>
+
+ Despite the ubiquity of streams, you cannot actually reference a
+ stream, since it is not an object. Instead, you simply reference the
+ object it belongs to. If you are familiar with Java, this is similar
+ to how every Java object has a monitor associated with it, but you
+ cannot directly manipulate the monitor (you can't pass around a
+ reference to just the monitor).
+
+ In the rest of the section we will sometimes refer to "getting
+ properties from a stream" or "passing a stream to a function"; this is
+ just shorthand for saying to perform those actions on the object the
+ stream belongs to.
+
+ <section title="Creating Streams from URLs">
+
+ You can create a stream from a URL by calling
+
+ <pre>
+ var r = ibex.stream.url("http://...");
+ </pre>
+
+ This will return an object whose stream draws data from the specified
+ URL. Streams are loaded lazily whenever possible.
+
+ </section>
+
+ <section title="Getting Substreams">
+
+ Most stream objects let you access
+ substreams using the usual JavaScript operators [[[]]] and
+ [[.]], as well as the [[for..in]] syntax.
+
+ <pre>
+ // r1 and r2 are equivalent but not equal (!=)
+ var r1 = ibex.stream.url("http://www.ibex.org/foo/bar.html");
+ var r2 = ibex.stream.url("http://www.ibex.org/foo")["bar.html"];
+ </pre>
+
+ </section>
+
+ <section title="The Root Stream">
+
+ The empty-string property on the [[ibex]] object is called the
+ **root stream**. You can access this object as [[ibex..]] or
+ [[ibex[""]]]. Additionally, any expression which starts with a
+ dot is treated as property to be retrieved from the root stream. The
+ following three expressions are equivalent:
+
+ <pre>
+ ibex..foo
+ ibex[""].foo
+ .foo
+ </pre>
+
+ </section>
+
+ <section title="Static Blocks">
+
+ FIXME
+
+ You can access variables within the static block of a template by
+ appending a double period ([[..]]) and the variable name to the
+ stream used to load that template:
+
+ <pre>
+ <!-- org/ibex/themes/linux/scrollbar.ibex -->
+ foo = 12;
+ ...
+ // elsewhere
+ ibex.log.print(org.ibex.themes.linux.scrollbar..foo); // prints "12"
+ </pre>
+
+ </section>
+
+ <section title="Formatting Streams">
+
+ If you attempt to send a stream as part of an XML-RPC call, the
+ stream will be read in its entirity, Base64-encoded, and transmitted
+ as a [[<base64/>]] element.
+
+ Ibex supports two special URL protocols. The first is [[data:]],
+ which inteprets the rest of the URL as a Base64 encoded sequence of
+ bytes to use as a source. The other is [[utf8:]] which
+ interpretets the rest of the string as a Unicode character sequence to
+ be UTF-8 encoded as a string of bytes to use as a source.
+
+ <pre>
+ var r5 = ibex.stream.url("data:WFWE876WEh99sd76f");
+ var r6 = ibex.stream.url("utf8:this is a test");
+ </pre>
+
+ You can read a UTF-8 encoded string from a stream like this:
+
+ <pre>
+ var myString = ibex.stream.fromUTF(ibex.stream.url("utf8:testing..."));
+ </pre>
+ You can also parse XML from a stream using SAX like this:
+
+ <pre>
+ ibex.stream.xml.sax(
+ ibex.stream.url("http://foo.com/foo.xml"),
+ { beginElement : function(tagname, attributeKeyValuePairs) { ... },
+ endElement : function(tagname) { ... },
+ content : function(contentString) { ... }
+ whitespace : function(whitespaceString) { ... }
+ });
+ </pre>
+
+ </section>
+
+ </section>
+
+<!-- ----------------------------------------------------------------------- -->
+<section title="The Ibex object">
+
+ The [[ibex]] object is present in the top-level scope of every
+ script. It has the following properties:
+
+ <heading title="General"/>
+
+ <property name="ibex.box">
+ reading from this property returns a new box
+ </property>
+ <property name="ibex.clone(o)">
+ creates a clone of object
+ </property>
+ <property name="ibex.bless(s)">
+ returns a blessed clone of stream
+ </property>
+
+ <heading title="ECMA Library Objects"/>
+
+ <property name="ibex.date">
+ reading from this property returns a new date
+ </property>
+ <property name="ibex.math">
+ this object contains the ECMA math functions
+ </property>
+ <property name="ibex.regexp(s)">
+ return a regexp object corresponding to string **s**
+ </property>
+ <property name="ibex.string">
+ this object contains the ECMA string manipulation functions
+ </property>
+
+ <heading title="Logging"/>
+
+ <property name="ibex.log.debug(m1, ... mn)">
+ log the debug messages **m1** through **mn**.
+ **o**
+ </property>
+
+ <property name="ibex.log.info(m1, ... mn)">
+ log the info messages **m1** through **mn**.
+ </property>
+
+ <property name="ibex.log.warn(m1, ... mn)">
+ log the warning messages **m1** through **mn**.
+ </property>
+
+ <property name="ibex.log.error(m1, ... mn)">
+ log the error messages **m1** through **mn**.
+ </property>
+
+ <heading title="User Interface"/>
+
+ <property name="ibex.ui.browser(u)">
+ opens a new browser window with URL **u**
+ </property>
+
+ <property name="ibex.ui.key.control">
+ true if the control key is depressed
+ </property>
+
+ <property name="ibex.ui.key.shift">
+ true if the shift key is depressed
+ </property>
+
+ <property name="ibex.ui.key.alt">
+ true if the alt key is depressed
+ </property>
+
+ <property name="ibex.ui.key.name.alt">
+ the name of the "alt" key (usually either "alt", "meta", or
+ "option")
+ </property>
+
+ <property name="ibex.ui.clipboard">
+ the contents of the clipboard; can be read and written to
+ </property>
+
+ <property name="ibex.ui.maxdim">
+ the maximum dimension of any UI element; usually
+ 2<sup>31</sup>, but may be smaller
+ </property>
+
+ <property name="ibex.ui.screen.width">
+ the width of the screen, in pixels
+ </property>
+
+ <property name="ibex.ui.screen.height">
+ the height of the screen, in pixels
+ </property>
+
+ <property name="ibex.ui.mouse.button">
+ either 0, 1, 2, or 3, indicating the mouse button currently
+ being pressed
+ </property>
+
+ <property name="ibex.ui.frame">
+ when a box is written to this property, it becomes the root
+ box of a new window
+ </property>
+
+ <property name="ibex.ui.window">
+ when a box is written to this property, it becomes the root
+ box of a new frame
+ </property>
+
+ <property name="ibex.ui.font.serif">
+ an object whose stream is a a builtin serif font
+ </property>
+
+ <property name="ibex.ui.font.sansserif">
+ an object whose stream is a builtin sans-serif font
+ </property>
+
+ <property name="ibex.ui.font.monospace">
+ an object whose stream is a a builtin fixed-width font
+ </property>
+
+ <heading title="Networking"/>
+
+ <property name="ibex.net.rpc.xml(u)">
+ return an XML-RPC call object with endpoint URL **u**
+ </property>
+
+ <property name="ibex.net.rpc.soap(u,">
+ return a SOAP call object with endpoint URL **u**,
+ SoapAction **a**, and XML Namespace **n**
+ </property>
+
+ <heading title="Threads"/>
+
+ <property name="ibex.thread">
+ when a function is written to this property, a new thread is
+ forked to call it
+ </property>
+
+ <property name="ibex.thread.yield()">
+ yield the current thread
+ </property>
+
+ <property name="ibex.thread.sleep(n)">
+ sleep for **n** milliseconds
+ </property>
+
+ <heading title="Streams"/>
+
+ <property name="ibex.stream.url(u)">
+ returns a new object whose stream is drawn from URL **u**
+ </property>
+
+ <property name="ibex.stream.unzip(s)">
+ unpacks a zip archive from **s**'s stream
+ </property>
+
+ <property name="ibex.stream.uncab(s)">
+ unpacks a cab archive from **s**'s stream
+ </property>
+
+ <property name="ibex.stream.cache(s,k)">
+ valign=top>wraps a disk-backed read cache keyed on **k**
+ around **s**'s stream
+ </property>
+
+ <property name="ibex.stream.watch(s,f)">
+ returns an object whose stream is drawn from **s**'s
+ stream, but invokes **f(n,d)** as it is read from.
+ </property>
+
+ <property name="ibex.stream.parse.xml(s, h)">
+ Use SAX to parse the XML document on stream **s** with
+ handler **h**
+ </property>
+
+ <property name="ibex.stream.parse.html(s, h)">
+ Same as [[parse.xml()]], but tries to fix broken HTML.
+ </property>
+
+ <property name="ibex.stream.parse.utf8(s)">
+ treat **s**'s stream as a string encoded as a UTF-8 byte stream and return the string
+ </property>
+
+ <property name="ibex.stream.homedir">
+ [[ibex.stream.tempdir]]
+ </property>
+
+ <heading title="Cryptography"/>
+
+ <property name="ibex.crypto.rsa(k,s)">
+ **not implemented yet:** return a
+ stream which rsa-decrypts stream **s** with key **k**
+ </property>
+
+ <property name="ibex.crypto.rc4(k,s)">
+ **not implemented yet:** return a
+ stream which rc4-decrypts stream **s** with key **k**
+ </property>
+
+ <property name="ibex.crypto.md5(s)">
+ **not implemented yet:** immediately
+ MD5-hash stream **s**
+ </property>
+
+ <property name="ibex.crypto.sha1(s)">
+ **not implemented yet:** immediately
+ SHA1-hash stream **s**
+ </property>
+
+</section>
+<!-- ----------------------------------------------------------------------- -->
+<section title="Traps">
+
+ You can add a trap to a property by applying the [[++=]] operator
+ to a function with one argument. The trap will be invoked whenever
+ that property is written to.
+
+ <pre>
+ <ui:box>
+ foo ++= function(z) {
+ ibex.log.info("foo is " + z);
+ }
+ </ui:box>
+ </pre>
+
+ If another script were to set the property "[[foo]]"
+ on the box above to the value [[5]], the function above would be
+ invoked with the argument [[5]]. The function would then log
+ the string "[[foo is 5]]".
+
+ Within a trap, the expression [[trapee]] can be used to
+ get a reference to the box on which the trap was placed.
+
+ The expression [[trapname]] returns the name of the
+ trap executing the current function. This is useful when a function
+ is applied to multiple traps. For example:
+
+ <pre>
+ <ui:box>
+ func ++= function(z) {
+ ibex.log.info("called trap " + trapname);
+ }
+ foo ++= func;
+ bar ++= func;
+ </ui:box>
+ </pre>
+
+ <section title="Removing Traps">
+
+ You can remove a trap by using the [[--=]] operator with the same
+ function you added as a trap:
+
+ <pre>
+ <ui:box>
+ var myfunc = function(z) { /* ... */ }
+ // add the trap
+ func ++= myfunc;
+ // ...
+ // remove the trap
+ func --= myfunc;
+ </ui:box>
+ </pre>
+
+ </section>
+
+ <heading title="Multiple Traps on the Same Property"/>
+
+ When the trapped property is **written** to, each of the trap
+ functions placed on it will be invoked in the opposite order that
+ they were placed on the box -- the most recently placed trap will
+ execute first. This last-to-first execution of traps is called
+ **cascading**. After the last trap is invoked, the value is
+ stored on the box (remember, boxes are objects, so they can hold
+ properties just like all other ECMAscript objects).
+
+ <section title="Manual Cascades">
+
+ There are two additional tricks you can use when placing traps. The
+ first is a **manual cascade**. If you want to cascade to lower
+ traps in the middle of a function, or you want to cascade with a
+ different value than the value passed to you (in effect "lying" to
+ lower traps), you can use [[cascade]]. For example:
+
+ <pre>
+ <ui:box color="black">
+ color ++= function(c) {
+ ibex.log.info("refusing to change colors!");
+ cascade = "black";
+ }
+ </ui:box>
+ </pre>
+
+ This effectively creates a box whose color cannot be changed, and
+ which complains loudly if you try to do so.
+
+ Do **not** try to do something like this:
+
+ <pre>
+ <ui:box color="black">
+ color ++= function(z) {
+ color = "black"; // INFINITE LOOP! BAD!!!
+ }
+ </ui:box>
+ </pre>
+ To prevent automatic cascading, return [[true]] from your function:
+
+ <pre>
+ <ui:box color="black">
+ color ++= function(z) {
+ return true; // the box's color will not change
+ }
+ </ui:box>
+ </pre>
+
+ </section>
+
+ <section title="Read Traps">
+
+ The other trick is a **read-trap**. Read traps are just like normal
+ traps, except that you use a function that takes zero arguments instead of one. Read traps
+ also do not automatically cascade.
+
+ <pre>
+ <ui:box>
+ doublewidth [[++=]] function() { return 2 * width; }
+ </ui:box>
+ </pre>
+
+ If another script attempts to read from the [[doublewidth]]
+ property on this box, the value it gets will be twice the actual width
+ of the box. Note that
+ the actual [[doublewidth]] property on the box never gets written
+ to, since the trap does not cascade.
+
+ You can manually cascade on read traps as well:
+
+ <pre>
+ <ui:box>
+ text [[++=]] function() { return "my text is " + cascade; }
+ </ui:box>
+ </pre>
+
+ Read traps are only rarely needed -- most of the time a write trap
+ should be enough.
+
+ </section>
+
+ <heading title="Prohibited Traps"/>
+
+ To prevent confusing and hard-to-debug behaviors, scripts may not
+ place traps on any of the properties described in the sections
+ <link text="Box Layout Properties" section="Layout Properties"/>, <link
+ section="Child-Control Properties"/>, or <link section="Other Box
+ Properties"/> except for [[childadded]],
+ [[childremoved]] and [[surface]]. FIXME: remove?
+
+ <heading title="Exceptions and Traps"/>
+
+ If an uncaught exception is thrown from a trap, Ibex will log the
+ exception, but will **not** propagate it to the code which
+ triggered the trap. If the trap was a read trap, the value
+ [[null]] will be returned.
+ FIXME: is this right?
+
+ <heading title="Architectural Significance of Traps"/>
+
+ Traps are the backbone of Ibex. Since almost all UI programming is
+ event/demand driven, traps eliminate the need for separate
+ member/getter/setter declarations, often cutting the amount of typing
+ you have to do to a third of what it would normally be.
+
+ <section title="Cloning">
+
+ **Cloning** is a companion technique for traps; together they can
+ be used to simulate any sort of environment you might need. When you
+ call [[ibex.clone(o)]], Ibex returns a new object (called the
+ **clone**) which compares with equality ([[==]]) to the
+ original object. Furthermore, both objects are "equal" as keys in
+ hashtables, so:
+
+ <pre>
+ var hash = {};
+ var theclone = ibex.clone(o);
+ hash[o] = 5;
+ ibex.log.info(hash[theclone]); // prints "5"
+ </pre>
+
+ Any writes to properties on the clone will actually write to
+ properties on the original object, and reads from properties on the
+ clone will read properties on the original object. In fact, the only
+ thing that can be used to distinguish the original from the clone is
+ traps -- a trap placed on the clone is **not** placed on the
+ original object as well.
+
+ </section>
+
+
+<!-- ----------------------------------------------------------------------- -->
+<section title="Threads">
+
+ <section title="Contexts">
+
+ From the perspective of an application writer, Ibex is strictly
+ single-threaded. Ibex is always in exactly one of the following three
+ **contexts**:
+
+ <list type="unordered">
+
+ __Rendering Context__ -- (redrawing the screen)
+
+ __Event Context__ (executing javascript traps triggered by an event)
+
+ __Thread Context__ (executing a background thread spawned with [[ibex.thread]])
+
+ </list>
+
+ There are two important restrictions on what can be done in particular contexts:
+
+ <list type="unordered">
+
+ The [[box.mouse]] property and its subproperties
+ ([[x]], [[y]], and [[inside]]) can only be read
+ from within the Event Context, or in a thread context
+ **after** a the [[box.mouse]] property on this box or
+ an ancestor box has been written to.
+
+ Blocking operations (anything that accesses the network or
+ disk) can only be performed in the Thread Context.
+
+ </list>
+
+ </section>
+
+ <section title="Background Threads">
+
+ Ibex offers easy access to threads. Spawning a background thread is as
+ simple as writing a function to the [[ibex.thread]] property:
+
+ <pre>
+ ibex.thread = function() {
+ ibex.log.info("this is happening in a background thread!");
+ }
+ </pre>
+
+ The argument set passed to the function is currently undefined and is
+ reserved for use in future versions of Ibex. Scripts should not
+ depend on the number or content of these arguments.
+
+ Ibex is **cooperatively multitasked**, so threads must not process
+ for too long. This was a deliberate choice; cooperatively
+ multitasked environments do not require complex locking primitives
+ like mutexes and semaphores which are difficult for novices to
+ understand. The disadvantage of cooperative multitasking is that one
+ thread can hog the CPU. This is unlikely to happen in Ibex for two reasons:
+ first, all blocking I/O operations **automatically** yield the CPU,
+ so the overall user interface never becomes unresponsive because it is
+ waiting for a disk or network transfer. Second, since Ibex is strictly
+ a user interface platform, Ibex scripts are unlikely to perform highly
+ compute-intensive operations that keep the CPU busy for more than a
+ few milliseconds.
+
+ </section>
+</section>
+
+<section title="Events">
+
+ Every execution of the Event Context begins with an event, which
+ consists of a key/value pair, and a mouse position, which consists of
+ an x and y coordinate. The possible keys are [[_Press[1-3]]],
+ [[_Release[1-3]]], [[_Click[1-3]]], [[_DoubleClick[1-3]]],
+ [[_Move]], [[_KeyPressed]], and [[_KeyReleased]].
+
+ Here are two example events:
+
+ An event is triggered by writing the key to the value on a box. This
+ triggers any trap handlers which may be present. Once these handlers
+ have executed, Ibex figures out which child of the current box contains
+ the mouse (taking into account that some boxes may cover up others)
+ and writes the key and value to that box. If none of the box's
+ children contain the mouse position, Ibex removes the leading
+ underscore from the key name and writes the value to
+ **that** property. Once all the traps on that property have
+ executed, the value is written to the box's parent.
+
+ Intuitively, Ibex delivers the underscored event to every box from the
+ root to the target, and then delivers the non-underscored event to
+ that same set of boxes in reverse order. So the event travels down
+ the tree to the target, and then back up to the root. The following
+ example prints out "first second third fourth" in that order.
+
+ <pre>
+ <ui:box>
+ _Press1 ++= function(b) { ibex.log.info("first"); }
+ Press1 ++= function(b) { ibex.log.info("fourth"); }
+ <ui:box>
+ _Press1 ++= function(b) { ibex.log.info("second"); }
+ Press1 ++= function(b) { ibex.log.info("third"); }
+ </ui:box>
+ </ui:box>
+ </pre>
+
+ In general, you should use the **non-underscore** names to respond
+ to user input and use the underscored names when you want to override
+ child boxes' behavior or route events to particular boxes (for
+ example, when implementing a focus protocol). This is why the
+ underscored elements are delivered to parents before children (so
+ parents can override their childrens' behavior), but non-underscored
+ events are delivered to children before parents (since, visually, a
+ mouse click is usually "intended" for the leaf box underneath the
+ cursor).
+
+ </section>
+
+ <heading title="Stopping the Process"/>
+
+ At any point in this sequence, a trap handler can choose not to
+ cascade (by returning [[true]] from the trap handler function).
+ This will immediately cease the propagation of the event. This is how
+ you would indicate that an event has been "handled".
+
+ <heading title="Non-Propagating Events"/>
+
+ Ibex uses the following events to notify a box about changes that
+ only matter to that particular box. These events do not propagate
+ either up or down the tree.
+
+ <property name="Enter Leave">
+ The value [[true]] is written to this property when the mouse (enters/leaves) the box.
+ </property>
+
+ <property name="SizeChange">
+ The value [[true]] is put to this property after the size
+ of this box changes.
+ </property>
+
+ <property name="ChildChange">
+ When a child is added or removed, that child is written to
+ this property. The write is always performed **after** the
+ addition or removal, so these two cases can be distinguished
+ by checking [[indexof(child)]].
+
+ Note that if the parent's redirect target is set to another
+ box, this trap will only be invoked when children are
+ manipulated by reading and writing to the parent. Reads and
+ writes directly to the redirect target will **not** trigger
+ this trap.
+
+ Note also that this traps is still triggered if a box's
+ [[redirect]] target is **null**. This is useful for
+ boxes that need to accept children and then relocate them
+ elsewhere.
+ </property>
+
+ <section title="Listing of Events">
+
+ <property name="Press1 Press2 Press3">
+ Indicates that the use has pressed a mouse button. On
+ platforms with three mouse buttons, the **middle** button
+ is button 3 -- this ensures that applications written to only
+ use two buttons (1 and 2) will work intuitively on three button
+ platforms.
+ </property>
+
+ <property name="Release1 Release2 Release3">
+ Indicates that the use has released a mouse button.
+ </property>
+
+ <property name="Click1 Click2 Click3">
+ Indicates that the user has pressed and released the
+ mouse button without moving the mouse much (exactly how
+ much is platform-dependent).
+ </property>
+
+ <property name="DoubleClick1 DoubleClick2 DoubleClick3">
+ Indicates that the user has clicked the
+ mouse button twice within a short period of time (exactly how long is platform-dependent).
+ </property>
+
+ <property name="Move">
+ Indicates that the mouse has moved while within this box, or that
+ the mouse while outside this box **if a button was pressed while within this box and has not yet been released**
+ </property>
+
+ <property name="KeyPressed KeyReleased">
+
+ A string is written to this property when a key is pressed or
+ released If the key was any other key, a multi-character
+ string describing the key will be put. For simplicity, we use
+ the VK_ constants in the <link
+ url="http://java.sun.com/products/jdk/1.1/docs/api/java.awt.event.KeyEvent.html#VK_0"
+ text=" Java 1.1 API java.awt.event.KeyEvent class"/>. When a
+ key is pressed or released, the string put will be the portion
+ of its VK_ constant after the underscore, all in lower case.
+
+ <list>
+ If the shift key was depressed immediately before the
+ event took place, then the string will be capitalized. Special
+ keynames are also capitalized; shift+home is reported as
+ "[[HOME]]". Symbols are capitalized as they appear on the
+ keyboard; for example, on an American QWERTY keyboard, shift+2
+ is reported as "[[@]]".
+
+ If the alt, meta, or command key was depressed immediately
+ before this key was pressed, then the string will be prefixed
+ with the string "[[A-]]". If the control key was depressed
+ while this key was pressed, then the string will be prefixed
+ with the string "[[C-]]". If both alt and control are
+ depressed, the string is prefixed with "[[C-A-]]".
+
+ Ibex does not distinguish between a key press resulting from
+ the user physically pushing down a key, and a 'key press'
+ resulting from the keyboard's typematic repeat. In the rare
+ case that an application needs to distinguish between these
+ two events, it should watch for KeyReleased messages and
+ maintain an internal key-state vector.
+ </list>
+ </property>
+
+ </section>
+
+</section>
+
+<!-- ----------------------------------------------------------------------- -->
+<section title="Networking">
+
+ <section title="XML-RPC">
+
+ XML-RPC objects can be created by calling [[ibex.net.rpc.xml(**XML-RPC
+ URL**)]], and then invoking methods on that object. For example,
+
+ <pre>
+ Press1 += function(v) {
+ ibex.thread = function() {
+ color = ibex.net.rpc.xml("http://xmlrpc.ibex.org/RPC2/").
+ color.getTodaysColor("Friday");
+ }
+ }
+ </pre>
+
+ When the user clicks the first mouse button on this box, it will
+ contact the server [[xmlrpc.ibex.org]], route to the
+ [[/RPC2/]] handler and invoke the [[getTodaysColor()]]
+ method on the [[color]] object with a single string argument
+ "[[Friday]]". The return value will be used to change the color
+ of the box the user clicked on.
+
+ Note that in this example we spawned a background thread to handle the
+ request -- the [[Press1]] event is delivered in the foreground
+ thread, and XML-RPC methods may only be invoked in background
+ threads. This is to prevent the UI from "locking up" if the server
+ takes a long time to reply.
+
+ If the XML-RPC method faults, an object will be thrown with two
+ properties: [[faultCode]] and [[faultString]], as defined in
+ the <link url="http://www.xmlrpc.org/spec" text="XML-RPC specification"/>. If
+ Ibex encounters a network, transport, or session-layer error, it will
+ throw a [[String]] object describing the error in a
+ human-readable format. Scripts should not rely on the contents of
+ this string having any special structure or significance.
+
+ If an object with an associated non-empty stream is passed as an
+ argument to an XML-RPC method, it will be sent as a <base64/>
+ element. If a <base64/> element is found in the XML-RPC reply, it
+ will be returned as an object with a stream drawn from that byte sequence.
+
+ Each object returned by [[ibex.net.rpc.xml()]] represents a
+ single HTTP connection. The connection will be held open until
+ the object is garbage collected or the server closes the
+ connection. If a second call is issued on the object before the
+ first one returns (usually from a seperate thread), the two calls
+ will be <link
+ url="http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html#sec8.1.2.2"
+ text="pipelined"/>. This can dramatically improve performance.
+
+ Ibex supports HTTP Basic and Digest authentication. To use
+ authentication, pass [[ibex.net.rpc.xml()]] a URL in the form
+
+ <pre>
+ http[s]://user:password@hostname/
+ </pre>
+
+ Ibex will use Digest authentication if the server supports it;
+ otherwise it will use Basic authentication. Please be aware that
+ many XML-RPC server implementations contain a <link
+ url="http://www.ibex.org/faq.html#auth" text="broken
+ implementation of Basic authentication"/>.
+
+ </section>
+
+ <section title="SOAP">
+
+ SOAP methods are invoked the same way as XML-RPC methods, but with three differences:
+
+ <list type="ordered">
+
+ [[ibex.net.rpc.soap()]] is used instead of
+ [[ibex.net.rpc.xml()]]
+
+ Instead of specifying just the URL of the service itself, you
+ must specify the URL, the SOAPAction argument, and the
+ namespace to use.
+
+ The actual method invocation takes only one argument, which
+ must be an object. This is necessary since SOAP arguments are
+ specified by name, rather than ordering.
+
+ </list>
+
+ SOAP faults are handled the same way as XML-RPC faults except that the
+ capitalization of the [[faultstring]] and [[faultcode]]
+ members is all lower-case, to match the SOAP spec. Here is a
+ SOAP example:
+
+ <pre>
+ Press1 ++= function(v) {
+ ibex.thread = function() {
+ color = ibex.net.rpc.soap("http://soap.ibex.org/SOAP",
+ "GETTODAYSCOLOR",
+ "http://ibex.org/namespace"
+ ).color.getTodaysColor( {
+ whichday : Friday
+ } );
+ }
+ }
+ </pre>
+
+ As you can see, SOAP is much more verbose, yet does not offer
+ substantially improved functionality. We recommend that XML-RPC be
+ used whenever possible, and that SOAP be reserved for legacy
+ applications.
+
+ The current Ibex SOAP stack does not support 'document style' or
+ multi-ref ([[href]]) data structures.
+
+ </section>
+
+ <section title="Security">
+
+ Applications downloaded from the network (as opposed to those loaded
+ from the filesystem) may only make certain kinds of connections to
+ certain hosts. See Appendix A for a detailed description of the
+ security policy.
+
+ </section>
+
+ </section>
+<!-- ----------------------------------------------------------------------- -->
+<section title="Error Handling">
+
+ If the Ibex Core encounters an error while servicing a function call
+ originating in JavaScript, the core will throw a string consisting of
+ an error code followed by a colon, a space, and a descriptive message.
+ For example:
+
+ <pre>
+ "ibex.net.dns.unknownhostexception: unable to resolve host foo.com"
+ </pre>
+
+ The code should be used to determine how the program should respond to
+ an error. The codes are organized in a hierarchy, so the
+ string.startsWith() method can be used to determine if an error lies
+ within a particular subhierarchy. The descriptive message portion of
+ the string may be shown to the user.
+
+ <property name="ibex.assertion.failed">
+ an assertion failed
+ </property>
+ <property name="ibex.io">
+ General I/O exceptions
+ </property>
+ <property name="ibex.io.encoding">
+ Error translating between character encodings.
+ </property>
+ <property name="ibex.io.zip">
+ Attempted to access a corrupt zip archive.
+ </property>
+ <property name="ibex.io.eof">
+ End of file encountered unexpectedly
+ </property>
+ <property name="ibex.net.security.prohibitedHost">
+ A piece of untrusted Ibex code attempted to contact a
+ restricted host. See <link appendix="Security Architecture and Considerations"/> for details.
+ </property>
+ <property name="ibex.net.dns.temporaryFailure">
+ An attempt to resolve a hostname failed but it is not known
+ for certain that the hostname is invalid.
+ </property>
+ <property name="ibex.net.dns.unknownHost">
+ An attempt to resolve a hostname failed because the hostname
+ was invalid.
+ </property>
+ <property name="ibex.net.socket.closed">
+ A socket was closed unexpectedly.
+ </property>
+ <property name="ibex.net.socket.connectionFailed">
+ A connection could not be made to the remote host.
+ </property>
+ <property name="ibex.net.url.malformed">
+ Tried to parse a malformed URL.
+ </property>
+ <property name="ibex.net.ssl">
+ General SSL protocol errors.
+ </property>
+ <property name="ibex.net.ssl.untrustedCertificate">
+ The server's certificate was not signed by a CA trusted by Ibex.
+ </property>
+ <property name="ibex.net.http.">
+ Thrown when an HTTP error code is returned during an
+ operation. The three characters [[**xyz**]] will be
+ the three-digit HTTP status code.
+ </property>
+ <property name="ibex.net.xmlrpc.null">
+ The caller attempted to transmit the [[null]] value via XML-RPC.
+ </property>
+ <property name="ibex.net.xmlrpc.circular">
+ The caller attempted to transmit a circular data structure via XML-RPC.
+ </property>
+ <property name="ibex.net.xmlrpc.specialObject">
+ The caller attempted to transmit a "special" object via
+ XML-RPC (for example, a Box or the Ibex object).
+ </property>
+ <property name="ibex.null.put">
+ A JavaScript attempted to put to a property on the [[null]] value
+ </property>
+ <property name="ibex.null.get">
+ A JavaScript attempted to get from a property on the [[null]] value
+ </property>
+ <property name="ibex.null.call">
+ A JavaScript attempted to call the [[null]] value
+ </property>
+
+ If an exception is thrown inside a trap, the exception will propagate
+ to the script that triggered the trap.
+
+ If an uncaught exception is thrown while applying a template, or the
+ requested template could not be found, an error will be logged and the
+ box to which the template was being applied will be made invisible
+ ([[visible = false]]). This ensures that half-applied widgets are
+ never shown to the user.
+
+ </section>
+
+<!-- ----------------------------------------------------------------------- -->
+<section title="Advanced Topics">
+
+ <section title="Re-routing events">
+
+ At any point in the Event Context, you can write to the [[mouse]]
+ property on any box. The value written should be an object with two
+ properties, [[x]] and [[y]]. For example:
+
+ <pre>
+ _Press1 ++= function(p) {
+ mouse = { x: 32, y: 77 };
+ }
+ </pre>
+
+ The coordinates specified are relative to the box whose [[mouse]]
+ property is being written to. There is no need to supply the
+ [[inside]] property; it is computed automatically. Writing to
+ the [[mouse]] property causes Ibex to recompute the eventual
+ target box, and also alter the values returned by [[mouse.x]],
+ [[mouse.y]], and [[mouse.inside]] for any **descendants**
+ of the current box. Writing to the [[mouse]] property also
+ automatically prevents the event from returning to the box's parents
+ -- it is equivalent to not cascading on the non-underscored event.
+ This ensures that child boxes cannot trick their parent boxes into
+ thinking that the mouse has moved.
+
+ If you want the event to "skip over" the boxes between the trapee
+ and the target, or if you want to re-route an event to a box which
+ is not a descendant of the current box, simply write the value to
+ the proper key on the target box.
+
+ <pre>
+ <ui:box>
+ _KeyPressed = function(k) { ibex.log.info("first"); }
+ KeyPressed = function(k) { ibex.log.info("sixth"); }
+ $recipient.target = $target;
+ <ui:box id="recipient">
+ _KeyPressed = function(k) {
+ ibex.log.info("second");
+ thisbox.target.KeyPressed = k;
+ // inhibit cascade; keep event from going to $excluded
+ return true;
+ }
+ KeyPressed = function(k) { ibex.log.info("fifth"); }
+ <ui:box id="excluded">
+ _KeyPressed = function(k) {
+ ibex.log.info("this never happens");
+ }
+ </ui:box>
+ </ui:box>
+ <ui:box id="target">
+ _KeyPressed = function(k) { ibex.log.info("third"); }
+ KeyPressed = function(k) { ibex.log.info("fourth"); }
+ </ui:box>
+ </ui:box>
+ </pre>
+
+ </section>
+
+ <section title="Synthesizing Your Own Events">
+
+ You can create "fake events" by simply writing to the [[mouse]]
+ property and then writing a value to one of the underscored properties
+ on a box. This will have exactly the same effect as if the use had
+ actually pressed a key, clicked a button, or moved the mouse -- they
+ are indistinguishable.
+
+ </section>
+
+ <section title="Ibex self-emulation">
+
+ When the core first starts up, it clones the [[ibex]] object,
+ creates a stream for the initial .ibex, and then places a trap on the
+ cloned [[ibex]] object so that its empty-string property returns
+ the .ibex stream. The cloned Ibex object is then passed as the third
+ (optional) argument to [[ibex.apply()]], making it the default
+ [[ibex]] object for the scripts that are executed as part of the
+ template instantiation.
+
+ <pre>
+ var new_ibex = ibex.clone(ibex);
+ var stream = ibex.bless(ibex.stream.url("http://..."));
+ new_ibex[""] ++= function() { return stream; }
+ ibex.apply(ibex.box, new_ibex..main, new_ibex);
+ </pre>
+
+ Note that we called [[ibex.bless()]] on the stream before tacking
+ it on to the new Ibex object. The bless function returns a clone of
+ the object passed to it, with a few traps which are explained below.
+ Additionally, any sub-streams retrieved by accessing properties of the
+ blessed stream will also automatically be blessed (blessed streams are
+ **monadic**).
+
+ Blessing a stream serves three purposes:
+
+ <list type="unordered">
+
+ Blessed clones always return the appropriate static block when
+ their empty property is accessed; this ensures that references
+ to the static blocks of other templates work properly.
+
+ Blessed substreams can return their parent stream by accessing
+ a hidden property which is reserved for internal use by Ibex.
+ This ensures that Ibex can automatically add filename
+ extensions where needed, according to the following rules:
+
+ <list>
+ If the stream is a template to be applied, the string
+ "[[.ibex]]" is appended.
+
+ If the stream is an image, the string "[[.png]]" is
+ appended. If no stream is found, "[[.jpeg]]" and
+ "[[.gif]]" are tried, in that order.
+
+ If the stream is an font, the string "[[.ttf]]" is
+ appended.
+ </list>
+
+ Every call to [[ibex.bless()]] returns a different object
+ (which happens to be a clone of the object passed to it) with
+ a completely separate set of static blocks.
+
+ </list>
+
+ Ibex can self-emulate by using [[ibex.clone()]] on the Ibex object;
+ this technique is very similar to the use of ClassLoaders in
+ Java. This is useful for a number of applications, including
+ debuggers, IDEs, sandboxing untrusted code, remote-control, and
+ others. For example:
+
+ <pre>
+ var newLoadFunction = function(url) { /* ... */ };
+ var new_ibex = ibex.clone(ibex);
+ new_ibex.load ++= function() { return newLoadFunction; }
+ ibex.apply(ibex.box, .main, new_ibex);
+ </pre>
+ </section>
+</section>
+
+<!-- ----------------------------------------------------------------------- -->
+<appendix title="Security Architecture and Considerations">
+
+ Due to the expense and hassle imposed by the commercial PKI code
+ signing architecture, and the fact that it <link
+ url="http://www.counterpane.com/pki-risks-ft.txt" text="doesn't
+ really provide any security anyways"/>, Ibex user interfaces are
+ distributed as unsigned, untrusted code. As such, they are handled
+ very carefully by the Ibex Core, and assumed to be potentially
+ malicious.
+
+ Ibex's security architecture is divided into defenses against four
+ major classes of attacks:
+
+ <heading title="Malicious UI attempts to acquire or alter data on the client"/>
+
+ Ibex user interfaces are run in an extremely restrictive sandbox. The
+ environment does not provide primitives for accessing any data outside
+ the Ibex core except via XML-RPC and SOAP calls. There are no
+ facilities to allow Ibex user interfaces to access the client's
+ operating system or to interact with other applications on the same
+ host (unless they provide a public XML-RPC or SOAP interface).
+ An Ibex script may only access a file on the user's hard disk if the
+ user explicitly chooses that file from an "open file" or "save file"
+ dialog. There is one exception to this rule: if all templates
+ currently loaded in the Ibex core originated from the local
+ filesystem, those templates can load additional .ibexs from the local
+ filesystem.
+
+ The Ibex Core is written in Java, so it is not possible for
+ scripts to perform buffer overflow attacks against the core
+ itself.
+
+ Ibex applications may only read from the clipboard when the user
+ middle-clicks (X11 paste), presses control-V (Windows paste), or
+ presses alt-V (Macintosh paste; the command key is mapped to Ibex
+ "alt"). This ensures that Ibex applications are only granted access to
+ data that other applications have placed on the clipboard when the user
+ specifically indicates that that information should be made available
+ to the Ibex application.
+
+ <heading title="Malicious UI attempts to use client to circumvent firewalls"/>
+
+ Ibex user interfaces may only make XML-RPC or SOAP calls and load .ibex
+ archives via HTTP; they cannot execute arbitrary HTTP GET's or open
+ regular TCP sockets.
+
+ Ibex will not allow a script to connect to a non-public IP address
+ (10.0.0.0/8, 172.16.0.0/12, or 192.168.0.0/16, as specified in <link
+ url="http://www.cis.ohio-state.edu/cgi-bin/rfc/rfc1918.html" text="RFC
+ 1918"/>). There is one exception -- if all templates currently loaded
+ in the core originated from the same IP address, those scripts may
+ make calls to that IP address regardless of whether or not it is
+ firewalled. If Ibex does not have access to a DNS resolver (because it
+ is using a proxy which performs DNS lookups), Ibex will provide the
+ proxy with the appropriate <link
+ url="http://www.ibex.org/x-requestorigin.html"
+ text="X-RequestOrigin"/> header that the proxy needs in order
+ to maintain security.
+
+ The only remaining possible attack is against a XML-RPC or SOAP
+ service running on a firewalled host with a public address. Assigning
+ such machines public IP addresses is a poor network security policy,
+ and doing so squanders scarce public IPv4 addresses. As such, the onus
+ is on the administrators of such machines to explicitly block access
+ to clients reporting a [[User-Agent:]] header beginning with the
+ four characters "[[IBEX]]".
+
+ <heading title="Malicious UI attempts to trick user into divulging secret information"/>
+
+ All top-level windows created by Ibex are **scarred** -- a stripe
+ and a lock is drawn across the corner of the window. There is no way
+ for a user interface to remove this scar. Ibex user interfaces may not
+ create windows smaller than the size of the scar.
+
+ <heading title="Malicious network attempts to snoop or man-in-the-middle transactions"/>
+
+ Ibex user interfaces may transmit network data using HTTPS (SSL 3.0)
+ for encryption. Ibex will attempt 128-bit encryption, but will
+ negotiate down to 40-bit if the server does not support strong
+ crypto. Ibex's SSL implementation is currently provided by <link
+ url="http://www.ibex.org/tinyssl" text="TinySSL"/> and <link
+ url="http://www.bouncycastle.org" text="The Legion of the Bouncy
+ Castle."/>
+
+ All HTTPS connections must be authenticated by the server using a
+ certificate whose name matches the domain name of the HTTPS URL. The
+ certificate must be signed by a trusted root CA. Ibex trusts the same
+ 93 root CAs whose certificates are included as "trusted" in Microsoft
+ Internet Explorer 5.5 SP2. This provides a minimal level of protection
+ against man-in-the-middle attacks; you should not trust this
+ connection with any data you would not normally trust an SSL-enabled
+ web browser with.
+
+</appendix>
+
+<!-- ----------------------------------------------------------------------- -->
+<appendix title="ECMAscript compliance">
+
+ Ibex's scripts are written in a modified subset of ECMA-262, revision 3
+ (aka JavaScript 1.5). The interpreter strays from the spec in a few
+ ways.
+
+ <section title="Omissions">
+
+ The following ECMA features are not supported:
+
+ <list type="unordered">
+
+ The [[undefined]] value, [[===]], and [[!==]]
+
+ The [[new]] keyword (and ECMAScript object inheritance)
+ [[eval]]
+
+ [[getter]] and [[setter]]
+
+ The ECMA [[this]] keyword.
+
+ The [[String]], [[Number]], and [[Boolean]]
+ classes. Note that [[string]], [[number]], and
+ [[boolean]] values are supported, however.
+
+ You may not [[throw]] the [[null]] value.
+
+ </list>
+
+ Additionally, you must declare all root-scope variables (with
+ [[var]]) before using them; failure to do so will result in an
+ exception. Box properties are pre-defined in the scope that scripts
+ are executed in.
+
+ </section>
+
+ <section title="Extensions">
+
+ <list type="unordered">
+
+ The token [[..]] is equivalent to [[[""]]].
+
+ Trapping
+
+ Cloning
+
+ Extended [[catch]] syntax. The following code:
+ <pre>
+ } catch(e propname "foo.bar.baz") {
+ // ...
+ }
+ </pre>
+ Is equivalent to:
+ <pre>
+ } catch(e) {
+ if (e.propname != null and e.propname >= "foo.bar.baz" and
+ "foo.bar.baz/" > e.propname) {
+ // ...
+ }
+ }
+ </pre>
+ Multiple extended-catch blocks can appear at the end of a single try
+ block. However, at most one non-extended catch block may appear, and
+ if it does appear, it must be the last one.
+
+ Since Ibex ECMAscripts are wrapped in XML, the lexical token
+ "[[lt]]" is be interpreted as [[<]], the lexical
+ token "[[gt]]" is be interpreted as [[>]], and the
+ token "[[and]]" is interpreted as [[&&]].
+ Thus these tokens cannot be used as variable names.
+
+ The identifier [[static]] is a reserved word in
+ ECMAScript, but not in Ibex.
+
+ Ibex defines an additional reserved word, "[[assert]]",
+ which will evaluate the expression which follows it, throwing
+ a [[ibex.assertion.failed]] exception if the expression
+ evaluates to [[false]].
+
+ To ensure that Ibex files appear the same in all text editors, tab
+ characters are not allowed in Ibex files.
+
+ </list>
+
+ Some useful tutorials include:
+
+ <list type="unordered">
+
+ Netscape's <link
+ url="http://developer.netscape.com/docs/manuals/communicator/jsref/index.htm"
+ text=" JavaScript 1.2 Reference"/>. Although this document is
+ out of date, it is arguably the best guide available for free
+ on the Internet. The changes from JavaScript 1.2 (aka ECMA-262
+ r1) to 1.5 were minimal, and many of them were <link
+ url="ecmascriptcompliance" text="omitted"/> from Ibex.
+
+ O'Reilly's <link
+ url="http://search.barnesandnoble.com/booksearch/isbnInquiry.asp?isbn=0596000480"
+ text=" JavaScript: The Definitive Guide"/>, by David Flanagan
+ and Paula Ferguson. The latest edition of this book covers
+ JavaScript 1.5 (ECMA-262 r3).
+
+ The official <link
+ url="http://www.ecma.ch/ecma1/STAND/ECMA-262.HTM"
+ text="ECMA-262"/> specification. This is an extremely
+ technical document.
+
+ </list>
+ </section>
+</appendix>
+
+<!-- ----------------------------------------------------------------------- -->
+<appendix title="Logging and Command Line Invocation">
+
+ <pre>
+ Usage: ibex [-lawp] [ url | file | directory ]
+ -l [level] set logging level to { debug, info (default), warn, error, silent }
+ -l rpc log all XML-RPC and SOAP conversations
+ -l user@host email log to user@host
+ -l host:port emit log to TCP socket
+ -l [file] write log to a file on disk
+ -a check assertions
+ -w [window-id] reserved for libibex
+ -p dump profiling information [not yet supported]
+ </pre>
+
+ If Ibex encounters a serious problem before it starts logging
+ information, or if it is unable to open the log file, it will abort
+ immediately with a critical abort, which will be displayed on the
+ console for POSIX-native cores and in a dialog box for JVM-based and
+ Win32-native cores.
+
+ Note that Microsoft Windows does not provide any mechanism for
+ redirecting standard input/output of an application which is not
+ compiled as a "console application". Therefore, Ibex is compiled
+ as a "console application", and will open a console window when
+ invoked. To inhibit this console window, provide a logging
+ destination (file, port, etc).
+
+ The [[**source-location**]] parameter can be either the path
+ to an [[.ibex]] archive, the http url of an [[.ibex]]
+ archive, or the path to a directory comprising an unpacked
+ [[.ibex]] archive.
+
+ The [[**initial-template**]] parameter is the stream name of
+ a template to be used as the initial template. If ommitted, it
+ defaults to [[main]].
+
+ The [[-v]] option causes Ibex to enable verbose logging; this will
+ cause it to log **lots** of information to the log file. This
+ option will also substantially decrease Ibex's performance.
+
+ </appendix>
+
+<!-- ----------------------------------------------------------------------- -->
+ <!--
+<appendix title="Grammars">
+
+ **Grammar support is experimental in this release
+ and may not work properly. It may change in incompatible ways or
+ disappear completely from future releases**
+
+ Grammars are defined with a statement in the following form:
+
+ <pre>
+ a ::= b { c }
+ </pre>
+ A grammar is really just another function; once defined you can't tell
+ it apart from an ordinary function. A grammar takes one argument,
+ which can be a string or stream. The argument is parsed and the
+ result of executing the code block 'c' is returned.
+
+ The property 'a' is read; if the value is a grammar, a new production
+ rule (ie a new alternative, as with '[[|]]') is added to that grammar
+ (this is a destructive update). This allows you to add productions to
+ pre-existing grammars (for example, adding a new type of expression to
+ a programming language by extending the 'expr' grammar). If the old
+ value is not a grammar, the value is discarded and a new grammar
+ object is created.
+
+ The value 'b' is a pattern, which may consist of seven simple
+ primitives:
+
+ <list type="unordered">
+ string literals
+
+ grouping parens [[()]]
+
+ combinators: [[ | + * ?]]
+
+ references to other grammars
+ </list>
+
+ The value 'c' and the braces surrounding it are an *optional* code
+ block, in which the following identifiers are bound:
+
+ <list type="unordered">
+
+ The identifier 'whole' is bound to the string matched by the
+ entire expression. If the code block is omitted it behaves
+ as if it were "[[{ return whole; }]]".
+
+ For every reference to another grammar which was matched in the
+ pattern, the *name used to reference that other grammar* will
+ be bound to the value returned by its code block. Here's an
+ example of this important distinction:
+
+ <pre>
+ var foo ::= 'a' | 'b';
+ var bar ::= foo;
+ var baz ::= 'c' | bar { /* foo is not defined here, but bar is */ };
+ </pre>
+
+ On the last line, the identifier 'bar' serves two purposes: it
+ pulls in the definition of the pattern *and* acts as a binder
+ within the scope of the braces.
+
+ If a reference is matched multiple times (either because it
+ appears multiple times in the pattern or because the * or +
+ operator was applied to it) then its name will be bound to an
+ array containing the matches.
+
+ </list>
+
+ Here is the metacircular definition of the grammar facility:
+
+ <pre>
+ grammar ::= identifier '::=' pattern (';' | '{' code '}' ';'?)
+ identifier ::= ('a'..'z' | 'A'..'Z' | '_' | '$') (identifier | '0'..'9')*
+ char ::= '\0x0000'..'\0xffff'
+ literal ::= '\'' char+ '\''
+ | '\'' char '\'' '..' '\'' char '\''
+ pattern ::= identifier
+ | literal
+ | '(' pattern ')'
+ | pattern '+'
+ | pattern '?'
+ | pattern '*'
+ | pattern pattern
+ | pattern '|' pattern
+ </pre>
+ -->
+
+**
+Copyright (C) 2004 Adam Megacz, verbatim redistribution permitted.
+Ibex is a trademark of Adam Megacz
+**
+
+</ibex-doc>
\ No newline at end of file
--- /dev/null
+// FIXME
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.core;
+
+// FIXME: are traps on x/y meaningful?
+// FIXME: if we trap on cols, then set rows to 0 (forcing cols to 1), does the cols trap get triggered?
+// FIXME: if we change min{width/height}, thereby forcing a change to max{min/height}, does a trap on those get triggered?
+// FIXME: trap on numchildren? replaces ChildChanged?
+// FIXME: trap on visible, trigger when parent visibility changes
+
+// FIXME: ax/ay nonsense
+// FIXME: mouse move/release still needs to propagate to boxen in which the mouse was pressed and is still held down
+
+// FEATURE: mark to reflow starting with a certain child
+// FEATURE: reintroduce surface.abort
+
+import java.util.*;
+import org.ibex.js.*;
+import org.ibex.util.*;
+import org.ibex.graphics.*;
+
+/**
+ * <p>
+ * Encapsulates the data for a single Ibex box as well as all layout
+ * rendering logic.
+ * </p>
+ *
+ * <p>The rendering process consists of four phases; each requires
+ * one DFS pass over the tree</p>
+ * <ol><li> <b>pack()</b>: each box sets its childrens' row/col
+ * <ol><li> <b>constrain()</b>: contentwidth is computed
+ * <li> <b>resize()</b>: width/height and x/y positions are set
+ * <li> <b>render()</b>: children draw their content onto the PixelBuffer.
+ * </ol>
+ *
+ * The first three passes together are called the <i>reflow</i>
+ * phase. Reflowing is done in a seperate pass since SizeChanges
+ * trigger a Surface.abort; if rendering were done in the same pass,
+ * rendering work done prior to the Surface.abort would be wasted.
+ */
+public final class Box extends JSScope implements Task {
+
+ // Macros //////////////////////////////////////////////////////////////////////
+
+ final void REPLACE() { for(Box b2 = this; b2 != null && !b2.test(REPLACE); b2 = b2.parent) b2.set(REPLACE); }
+ final void RECONSTRAIN() { for(Box b2 = this; b2 != null && !b2.test(RECONSTRAIN); b2 = b2.parent) b2.set(RECONSTRAIN); }
+ final void REPACK() { for(Box b2 = this; b2 != null && !b2.test(REPACK); b2 = b2.parent) b2.set(REPACK); }
+
+ //#define CHECKSET_SHORT(prop) short nu = (short)toInt(value); if (nu == prop) break; prop = nu;
+ //#define CHECKSET_INT(prop) int nu = toInt(value); if (nu == prop) break; prop = nu;
+ //#define CHECKSET_FLAG(flag) boolean nu = toBoolean(value); if (nu == test(flag)) break; if (nu) set(flag); else clear(flag);
+ //#define CHECKSET_BOOLEAN(prop) boolean nu = toBoolean(value); if (nu == prop) break; prop = nu;
+ //#define CHECKSET_STRING(prop) if ((value==null&&prop==null)||(value!=null&&JS.toString(value).equals(prop))) break; prop=JS.toString(value);
+
+ public Box() { super(null); }
+
+ // FIXME memory leak
+ static Hash boxToCursor = new Hash(500, 3);
+
+ static final Font DEFAULT_FONT = Font.getFont((Stream)Main.builtin.get("fonts/vera/Vera.ttf"), 10);
+
+
+ // Flags //////////////////////////////////////////////////////////////////////
+
+ static final int MOUSEINSIDE = 0x00000001;
+ static final int VISIBLE = 0x00000002;
+ static final int PACKED = 0x00000004;
+ public static final int HSHRINK = 0x00000008;
+ public static final int VSHRINK = 0x00000010;
+ static final int BLACK = 0x00000020; // for red-black code
+
+ static final int FIXED = 0x00000040;
+ static final boolean ROWS = true;
+ static final boolean COLS = false;
+
+ static final int ISROOT = 0x00000080;
+ static final int REPACK = 0x00000100;
+ static final int RECONSTRAIN = 0x00000200;
+ static final int REPLACE = 0x00000400;
+
+ static final int ALIGN_TOP = 0x00001000;
+ static final int ALIGN_BOTTOM = 0x00002000;
+ static final int ALIGN_LEFT = 0x00004000;
+ static final int ALIGN_RIGHT = 0x00008000;
+ static final int ALIGNS = 0x0000f000;
+ static final int CURSOR = 0x00010000; // if true, this box has a cursor in the cursor hash; FEATURE: GC issues?
+ static final int CLIP = 0x00020000;
+ static final int STOP_UPWARD_PROPAGATION = 0x00040000;
+ static final int MOVED = 0x00080000;
+
+
+ // Instance Data //////////////////////////////////////////////////////////////////////
+
+ Box parent = null;
+ Box redirect = this;
+ int flags = VISIBLE | PACKED | REPACK | RECONSTRAIN | REPLACE | FIXED | STOP_UPWARD_PROPAGATION | CLIP | MOVED;
+
+ private String text = null;
+ private Font font = DEFAULT_FONT;
+ private Picture texture = null;
+ private short strokewidth = 1;
+ public int fillcolor = 0x00000000;
+ private int strokecolor = 0xFF000000;
+
+ private int aspect = 0;
+
+ // specified directly by user
+ public int minwidth = 0;
+ public int maxwidth = Integer.MAX_VALUE;
+ public int minheight = 0;
+ public int maxheight = Integer.MAX_VALUE;
+ private short rows = 1;
+ private short cols = 0;
+ private short rowspan = 1;
+ private short colspan = 1;
+
+ // computed during reflow
+ private short row = 0;
+ private short col = 0;
+ public int x = 0;
+ public int y = 0;
+ public int ax = 0; // FEATURE: roll these into x/y; requires lots of changes
+ public int ay = 0; // FEATURE: roll these into x/y; requires lots of changes; perhaps y()?
+ public int width = 0;
+ public int height = 0;
+ public int contentwidth = 0; // == max(minwidth, textwidth, sum(child.contentwidth))
+ public int contentheight = 0;
+
+ private Path path = null;
+ /*
+ private Affine transform = null;
+ private VectorGraphics.RasterPath rpath = null;
+ private Affine rtransform = null;
+ */
+
+ // Instance Methods /////////////////////////////////////////////////////////////////////
+
+ public final int fontSize() { return font == null ? DEFAULT_FONT.pointsize : font.pointsize; }
+
+ /** invoked when a resource needed to render ourselves finishes loading */
+ public void perform() throws JSExn {
+ if (texture == null) { Log.warn(Box.class, "perform() called with null texture"); return; }
+ if (texture.isLoaded) {
+ setWidth(max(texture.width, minwidth), maxwidth);
+ setHeight(max(texture.height, minheight), maxheight);
+ dirty(); }
+ else { JS res = texture.stream; texture = null; throw new JSExn("image not found: "+res.unclone()); }
+ }
+
+ // FEATURE: use cx2/cy2 format
+ /** Adds the intersection of (x,y,w,h) and the node's current actual geometry to the Surface's dirty list */
+ public void dirty() { dirty(0, 0, width, height); }
+ public void dirty(int x, int y, int w, int h) {
+ for(Box cur = this; cur != null; cur = cur.parent) {
+ // x and y have a different meaning on the root box
+ if (cur.parent != null && cur.test(CLIP)) {
+ w = min(x + w, cur.width) - max(x, 0);
+ h = min(y + h, cur.height) - max(y, 0);
+ x = max(x, 0);
+ y = max(y, 0);
+ }
+ if (w <= 0 || h <= 0) return;
+ if (cur.parent == null && cur.getSurface() != null) cur.getSurface().dirty(x, y, w, h);
+ x += cur.x;
+ y += cur.y;
+ }
+ }
+
+
+ // Reflow ////////////////////////////////////////////////////////////////////////////////////////
+
+ /** should only be invoked on the root box */
+ public void reflow() {
+ pack();
+ resize(x, y,
+ test(HSHRINK) ? contentwidth : maxwidth,
+ test(VSHRINK) ? contentheight : maxheight);
+ place();
+ }
+
+ private static Box[] frontier = new Box[65535];
+ /** pack the boxes into rows and columns, compute contentwidth */
+ public void pack() {
+ if (!test(REPACK)) { constrain(); return; }
+ boolean haskid = false;
+ for(Box child = getChild(0); child != null; child = child.nextSibling()) { haskid = true; child.pack(); }
+ if (!haskid) { clear(REPACK); constrain(); return; }
+ int frontier_size = 0;
+ //#repeat COLS/ROWS rows/cols cols/rows col/row row/col colspan/rowspan rowspan/colspan \
+ // contentheight/contentwidth contentwidth/contentheight
+ if (test(FIXED) == COLS) {
+ rows = 0;
+ for(Box child = getChild(0); child != null; child = child.nextSibling()) {
+ if (!child.test(PACKED) || !child.test(VISIBLE)) continue;
+ if (cols == 1) { child.row = rows; rows += child.rowspan; child.col = 0; continue; }
+ child.col = (short)(frontier_size <= 0 ? 0 : (frontier[frontier_size-1].col + frontier[frontier_size-1].colspan));
+ child.row = (short)(frontier_size <= 0 ? 0 : frontier[frontier_size-1].row);
+ if (child.col + min(cols,child.colspan) > cols) { child.col = 0; child.row++; }
+ for(int i=0; i<frontier_size; i++)
+ if (frontier[i].row + frontier[i].rowspan <= child.row) {
+ frontier[i--] = frontier[--frontier_size]; frontier[frontier_size] = null;
+ } else if (frontier[i].col<child.col+min(cols,child.colspan)&&frontier[i].col+frontier[i].colspan>child.col) {
+ child.col = (short)(frontier[i].col + frontier[i].colspan);
+ if (child.col + min(cols,child.colspan) > cols) {
+ child.row = (short)(frontier[i].row + frontier[i].rowspan);
+ for(i--; i>0; i--) child.row = (short)min(row, frontier[i].row + frontier[i].rowspan);
+ child.col = (short)0;
+ }
+ i = -1;
+ } else break;
+ frontier[frontier_size++] = child;
+ }
+ for(int i=0; i<frontier_size; i++){ rows=(short)max(rows, frontier[i].row + frontier[i].rowspan); frontier[i] = null; }
+ }
+ //#end
+ clear(REPACK);
+ set(RECONSTRAIN); // FIXME: be smarter / more incremental
+ constrain();
+ }
+
+ public void constrain() {
+ if (!test(RECONSTRAIN)) return;
+ solve(true);
+ //#repeat contentwidth/contentheight contentheight/contentwidth minwidth/minheight row/col col/row \
+ // textwidth/textheight maxwidth/maxheight cols/rows rows/cols colspan/rowspan rowspan/colspan
+ contentwidth = bound(minwidth,
+ max(contentwidth, font == null || text == null ? 0 : font.textwidth(text)),
+ maxwidth);
+ //#end
+ set(REPLACE); // FIXME: be smarter / more incremental
+ }
+
+ void resize(int x, int y, int width, int height) {
+ if (x == this.x && y == this.y && width == this.width && height == this.height) return;
+ boolean sizechange = (this.width != width || this.height != height) && getTrap("SizeChange") != null;
+ int thisx = parent == null ? 0 : this.x;
+ int thisy = parent == null ? 0 : this.y;
+ Box who = (parent == null ? this : parent);
+ if (this.x != x || this.y != y) set(MOVED);
+ if (texture == null && (text == null || text.equals("")) && !test(MOVED)) {
+ if ((fillcolor & 0xff000000) != 0 || parent == null) {
+ who.dirty(thisx+min(this.width,width), thisy, Math.abs(width-this.width), max(this.height, height));
+ who.dirty(thisx, thisy+min(this.height,height), max(this.width, width), Math.abs(height-this.height));
+ }
+ this.width = width; this.height = height; this.x = x; this.y = y;
+ } else {
+ who.dirty(thisx, thisy, this.width, this.height);
+ this.width = width; this.height = height; this.x = x; this.y = y;
+ dirty();
+ }
+ if (sizechange) putAndTriggerTrapsAndCatchExceptions("SizeChange", T);
+ }
+
+ private float targetColumnSize = (float)0.0;
+ private float targetRowSize = (float)0.0;
+ private static float[] sizes = new float[65535];
+ private static float[] sizes_v = new float[65535];
+ private static int[] regions = new int[65535];
+ private static int[] regions_v = new int[65535];
+ private static int numregions = 0;
+ private static int numregions_v = 0;
+
+ void solve(boolean findMinimum) {
+ int numkids = 0; for(Box c = firstPackedChild(); c != null; c = c.nextPackedSibling()) numkids++;
+ //#repeat col/row colspan/rowspan contentwidth/contentheight width/height HSHRINK/VSHRINK numregions/numregions_v \
+ // maxwidth/maxheight cols/rows minwidth/minheight regions/regions_v targetColumnSize/targetRowSize sizes/sizes_v \
+ // HSHRINK/VSHRINK
+ if (numkids == 0) {
+ if (findMinimum) contentwidth = 0;
+ else targetColumnSize = 0;
+ } else if (cols == 1) {
+ if (findMinimum) {
+ contentwidth = 0;
+ for(Box c = firstPackedChild(); c != null; c = c.nextPackedSibling())
+ contentwidth = max(contentwidth, c.contentwidth);
+ } else {
+ targetColumnSize = width;
+ }
+ } else if (cols > 1) do {
+
+ // FIXME: cache these?
+ // compute regions
+ numregions = 0;
+ for(Box c = firstPackedChild(); c != null; c = c.nextPackedSibling()) {
+ regions[numregions++] = c.col;
+ regions[numregions++] = min(cols, c.col+c.colspan);
+ }
+ Vec.sortInts(regions, 0, numregions);
+ int j = 0;
+ int newnumregions = numregions;
+ for(int i=1; i<numregions; i++) {
+ if (regions[j] != regions[i]) j++;
+ else newnumregions--;
+ regions[j] = regions[i];
+ }
+ numregions = newnumregions;
+ if (regions[numregions-1] == cols) numregions--;
+ else regions[numregions] = cols;
+
+ int target = findMinimum ? 0 : Math.max(width, contentwidth);
+ // priority 0: (inviolable) honor minwidths
+ // priority 1: sum of columns no greater than parent
+ // priority 2: honor maxwidths
+ // priority 3: equalize columns
+ float targetColumnSize = target == 0 ? 0 : this.targetColumnSize;
+ float last_columnsize = 0;
+ float last_total = 0;
+ float total;
+ boolean first = true;
+ while(true) {
+ total = (float)0.0;
+ for(int r=0; r<numregions; r++) total += (sizes[r] = (float)(targetColumnSize * (regions[r+1]-regions[r])));
+ int minregion = 0;
+ for(Box child = firstPackedChild(); child != null; child = child.nextPackedSibling())
+ for(int r=(child.col==0?0:minregion); r<numregions; r++) {
+ if (regions[r+1] < child.col) continue;
+ if (regions[r] >= min(child.col+child.colspan,cols)) { minregion = r; break; }
+ total -= sizes[r];
+ int child_maxwidth = child.test(HSHRINK)?child.contentwidth:child.maxwidth;
+ if (sizes[r] <= (float)(targetColumnSize*(regions[r+1]-regions[r])))
+ if ((child.colspan * targetColumnSize) > (child_maxwidth + (float)0.5))
+ sizes[r] = (float)Math.min(sizes[r], (regions[r+1]-regions[r])*(child_maxwidth/child.colspan));
+ if ((child.colspan * targetColumnSize) < (child.contentwidth - (float)0.5))
+ sizes[r] = (float)Math.max(sizes[r], (regions[r+1]-regions[r])*(child.contentwidth/child.colspan));
+ total += sizes[r];
+ }
+ float save = targetColumnSize;
+ if (Math.abs(total - target) <= (float)1.0) break;
+ if (!first) {
+ if (Math.abs(total - last_total) <= (float)1.0) break;
+ } else {
+ last_columnsize = ((total - target) / (float)cols) + targetColumnSize;
+ }
+ if (total < target) targetColumnSize += Math.abs((last_columnsize - targetColumnSize) / (float)1.1);
+ else if (total > target) targetColumnSize -= Math.abs((last_columnsize - targetColumnSize) / (float)1.1);
+ last_columnsize = save;
+ last_total = total;
+ first = false;
+ }
+ if (findMinimum) contentwidth = Math.round(total);
+ else this.targetColumnSize = targetColumnSize;
+ } while(false);
+ //#end
+ }
+
+ void place() {
+ solve(false);
+ for(Box child = getChild(0); child != null; child = child.nextSibling()) {
+ if (!child.test(VISIBLE)) continue;
+ if (!child.test(REPLACE)) continue;
+ int child_width, child_height, child_x, child_y;
+ if (!child.test(PACKED)) {
+ child_width = child.test(HSHRINK) ? child.contentwidth : min(child.maxwidth, width - Math.abs(child.ax));
+ child_height = child.test(VSHRINK) ? child.contentheight : min(child.maxheight, height - Math.abs(child.ay));
+ child_width = max(child.minwidth, child_width);
+ child_height = max(child.minheight, child_height);
+ int gap_x = width - child_width;
+ int gap_y = height - child_height;
+ child_x = child.ax + (child.test(ALIGN_RIGHT) ? gap_x : !child.test(ALIGN_LEFT) ? gap_x / 2 : 0);
+ child_y = child.ay + (child.test(ALIGN_BOTTOM) ? gap_y : !child.test(ALIGN_TOP) ? gap_y / 2 : 0);
+ } else {
+ int diff;
+ //#repeat col/row colspan/rowspan contentwidth/contentheight width/height colMaxWidth/rowMaxHeight \
+ // child_x/child_y x/y HSHRINK/VSHRINK maxwidth/maxheight cols/rows minwidth/minheight x_slack/y_slack \
+ // child_width/child_height ALIGN_RIGHT/ALIGN_BOTTOM ALIGN_LEFT/ALIGN_TOP lp_h/lp \
+ // numregions/numregions_v regions/regions_v targetColumnSize/targetRowSize sizes/sizes_v
+ child_x = 0;
+ if (cols == 1) {
+ child_width = width;
+ } else {
+ child_width = 0;
+ for(int r=0; r<numregions; r++) {
+ if (regions[r] < child.col) child_x += Math.round(sizes[r]);
+ else if (regions[r] < child.col+child.colspan) child_width += Math.round(sizes[r]);
+ }
+ }
+ diff = (child_width - (child.test(HSHRINK) ? child.contentwidth : min(child_width, child.maxwidth)));
+ child_x += (child.test(ALIGN_RIGHT) ? diff : child.test(ALIGN_LEFT) ? 0 : diff / 2);
+ child_width -= diff;
+ //#end
+ }
+ if (test(MOVED)) child.set(MOVED);
+ child.resize(child_x, child_y, child_width, child_height);
+ }
+ clear(MOVED);
+
+ for(Box child = getChild(0); child != null; child = child.nextSibling())
+ if (child.test(VISIBLE) && child.treeSize() > 0)
+ child.place();
+ }
+
+
+
+ // Rendering Pipeline /////////////////////////////////////////////////////////////////////
+
+ /** Renders self and children within the specified region. All rendering operations are clipped to xIn,yIn,wIn,hIn */
+ public void render(int parentx, int parenty, int cx1, int cy1, int cx2, int cy2, PixelBuffer buf, Affine a) {
+ if (!test(VISIBLE)) return;
+ int globalx = parentx + (parent == null ? 0 : x);
+ int globaly = parenty + (parent == null ? 0 : y);
+
+ // intersect the x,y,w,h rendering window with ourselves; quit if it's empty
+ if (test(CLIP)) {
+ cx1 = max(cx1, globalx);
+ cy1 = max(cy1, globaly);
+ cx2 = min(cx2, globalx + width);
+ cy2 = min(cy2, globaly + height);
+ if (cx2 <= cx1 || cy2 <= cy1) return;
+ }
+
+ if ((fillcolor & 0xFF000000) != 0x00000000 || parent == null)
+ buf.fillTrapezoid(cx1, cx2, cy1, cx1, cx2, cy2, (fillcolor & 0xFF000000) == 0 ? 0xffffffff : fillcolor);
+
+ if (texture != null && texture.isLoaded)
+ for(int x = globalx; x < cx2; x += texture.width)
+ for(int y = globaly; y < cy2; y += texture.height)
+ buf.drawPicture(texture, x, y, cx1, cy1, cx2, cy2);
+
+ if (text != null && !text.equals("") && font != null) {
+ int gap_x = width - font.textwidth(text);
+ int gap_y = height - font.textheight(text);
+ int text_x = globalx + (test(ALIGN_RIGHT) ? gap_x : !test(ALIGN_LEFT) ? gap_x/2 : 0);
+ int text_y = globaly + (test(ALIGN_BOTTOM) ? gap_y : !test(ALIGN_TOP) ? gap_y/2 : 0);
+ font.rasterizeGlyphs(text, buf, strokecolor, text_x, text_y, cx1, cy1, cx2, cy2);
+ }
+
+ if (path != null) path.realize(Affine.translate(globalx, globaly)).stroke(buf, 1, strokecolor);
+
+ for(Box b = getChild(0); b != null; b = b.nextSibling())
+ b.render(globalx, globaly, cx1, cy1, cx2, cy2, buf, null);
+ }
+
+
+ // Methods to implement org.ibex.js.JS //////////////////////////////////////
+
+
+ public Object callMethod(Object method, Object a0, Object a1, Object a2, Object[] rest, int nargs) throws JSExn {
+ switch (nargs) {
+ case 1: {
+ //#switch(method)
+ case "indexof":
+ Box b = (Box)a0;
+ if (b.parent != this)
+ return (redirect == null || redirect == this) ?
+ N(-1) :
+ redirect.callMethod(method, a0, a1, a2, rest, nargs);
+ return N(b.getIndexInParent());
+
+ case "distanceto":
+ Box b = (Box)a0;
+ JS ret = new JS();
+ ret.put("x", N(b.localToGlobalX(0) - localToGlobalX(0)));
+ ret.put("y", N(b.localToGlobalY(0) - localToGlobalY(0)));
+ return ret;
+
+ //#end
+ }
+ }
+ return super.callMethod(method, a0, a1, a2, rest, nargs);
+ }
+
+ public Object get(Object name) throws JSExn {
+ if (name instanceof Number)
+ return redirect == null ? null : redirect == this ? getChild(toInt(name)) : redirect.get(name);
+
+ //#switch(name)
+ case "surface": return parent == null ? null : parent.getAndTriggerTraps("surface");
+ case "indexof": return METHOD;
+ case "distanceto": return METHOD;
+ case "text": return text;
+ case "path":
+ if (path != null) return path.toString();
+ if (text == null) return null;
+ if (font == null) return null;
+ String ret = "";
+ for(int i=0; i<text.length(); i++) ret += font.glyphs[text.charAt(i)].path;
+ return ret;
+ case "fill": return Color.colorToString(fillcolor);
+ case "strokecolor": return Color.colorToString(strokecolor);
+ case "textcolor": return Color.colorToString(strokecolor);
+ case "font": return font == null ? null : font.stream;
+ case "fontsize": return font == null ? N(10) : N(font.pointsize);
+ case "strokewidth": return N(strokewidth);
+ case "align": return alignToString();
+ case "thisbox": return this;
+ case "shrink": return B(test(HSHRINK) || test(VSHRINK));
+ case "hshrink": return B(test(HSHRINK));
+ case "vshrink": return B(test(VSHRINK));
+ case "aspect": return N(aspect);
+ case "x": return (parent == null || !test(VISIBLE)) ? N(0) : test(PACKED) ? N(x) : N(ax);
+ case "y": return (parent == null || !test(VISIBLE)) ? N(0) : test(PACKED) ? N(y) : N(ay);
+ case "cols": return test(FIXED) == COLS ? N(cols) : N(0);
+ case "rows": return test(FIXED) == ROWS ? N(rows) : N(0);
+ case "colspan": return N(colspan);
+ case "rowspan": return N(rowspan);
+ case "width": getRoot().reflow(); return N(width);
+ case "height": getRoot().reflow(); return N(height);
+ case "minwidth": return N(minwidth);
+ case "maxwidth": return N(maxwidth);
+ case "minheight": return N(minheight);
+ case "maxheight": return N(maxheight);
+ case "clip": return B(test(CLIP));
+ case "visible": return B(test(VISIBLE) && (parent == null || (parent.get("visible") == T)));
+ case "packed": return B(test(PACKED));
+ case "globalx": return N(localToGlobalX(0));
+ case "globaly": return N(localToGlobalY(0));
+ case "cursor": return test(CURSOR) ? boxToCursor.get(this) : null;
+ case "mouse":
+ if (getSurface() == null) return null;
+ if (getSurface()._mousex == Integer.MAX_VALUE)
+ throw new JSExn("you cannot read from the box.mouse property in background thread context");
+ return new Mouse();
+ case "numchildren": return redirect == null ? N(0) : redirect == this ? N(treeSize()) : redirect.get("numchildren");
+ case "redirect": return redirect == null ? null : redirect == this ? T : redirect.get("redirect");
+ case "Minimized": if (parent == null && getSurface() != null) return B(getSurface().minimized);
+ default: return super.get(name);
+ //#end
+ throw new Error("unreachable"); // unreachable
+ }
+
+ private class Mouse extends JS.Cloneable {
+ public Object get(Object key) {
+ //#switch(key)
+ case "x": return N(globalToLocalX(getSurface()._mousex));
+ case "y": return N(globalToLocalY(getSurface()._mousey));
+
+ // this might not get recomputed if we change mousex/mousey...
+ case "inside": return B(test(MOUSEINSIDE));
+ //#end
+ return null;
+ }
+ }
+
+ //#repeat setWidth/setHeight minwidth/minheight maxwidth/maxheight pendingWidth/pendingHeight
+ public void setWidth(int min, int max) {
+ // FIXME: deal with conflicting min/max
+ if (this.minwidth == min && this.maxwidth == max) return;
+ this.minwidth = min;
+ this.maxwidth = max;
+ RECONSTRAIN();
+ if (parent != null || getSurface() == null) return;
+ getSurface().pendingWidth = maxwidth;
+
+ // FIXME: the repeat doesn't work right here
+ getSurface().setMinimumSize(minwidth, minheight, minwidth != maxwidth || minheight != maxheight);
+ }
+ //#end
+
+ public void put(Object name, Object value) throws JSExn {
+ if (name instanceof Number) { put(toInt(name), value); return; }
+ //#switch(name)
+ case "thisbox": if (value == null) removeSelf();
+ case "text": if (value == null) value = ""; CHECKSET_STRING(text); RECONSTRAIN(); dirty();
+ case "strokecolor": value = N(Color.stringToColor((String)value)); CHECKSET_INT(strokecolor); dirty();
+ case "textcolor": value = N(Color.stringToColor((String)value)); CHECKSET_INT(strokecolor); dirty();
+ case "strokewidth": CHECKSET_SHORT(strokewidth); dirty();
+ case "shrink": CHECKSET_FLAG(HSHRINK | VSHRINK); RECONSTRAIN();
+ case "hshrink": CHECKSET_FLAG(HSHRINK); RECONSTRAIN();
+ case "vshrink": CHECKSET_FLAG(VSHRINK); RECONSTRAIN();
+ case "path": path = Path.parse(toString(value)); RECONSTRAIN(); dirty();
+ case "width": setWidth(toInt(value), toInt(value));
+ case "height": setHeight(toInt(value), toInt(value));
+ case "maxwidth": setWidth(minwidth, toInt(value));
+ case "minwidth": setWidth(toInt(value), maxwidth);
+ case "maxheight": setHeight(minheight, toInt(value));
+ case "minheight": setHeight(toInt(value), maxheight);
+ case "colspan": if (toInt(value) > 0) { CHECKSET_SHORT(colspan); if (parent != null) parent.REPACK(); }
+ case "rowspan": if (toInt(value) > 0) { CHECKSET_SHORT(rowspan); if (parent != null) parent.REPACK(); }
+ case "visible": CHECKSET_FLAG(VISIBLE); RECONSTRAIN(); dirty();
+ case "packed": CHECKSET_FLAG(PACKED); if (parent != null) { parent.REPACK(); } else { REPACK(); }
+ case "align": clear(ALIGNS); setAlign(value == null ? "center" : value); REPLACE();
+ case "cursor": setCursor(value);
+ case "fill": setFill(value);
+ case "clip": CHECKSET_FLAG(CLIP); if (parent == null) dirty(); else parent.dirty();
+ case "rows": CHECKSET_SHORT(rows); if (rows==0){set(FIXED, COLS);if(cols==0)cols=1;} else set(FIXED, ROWS); REPACK();
+ case "cols": CHECKSET_SHORT(cols); if (cols==0){set(FIXED, ROWS);if(rows==0)rows=1;} else set(FIXED, COLS); REPACK();
+
+ // FIXME: remove
+ case "mouse":
+ int mousex = toInt(((JS)value).get("x"));
+ int mousey = toInt(((JS)value).get("y"));
+ getSurface()._mousex = localToGlobalX(mousex);
+ getSurface()._mousey = localToGlobalY(mousey);
+
+ case "Minimized": if (parent == null && getSurface() != null) getSurface().minimized = toBoolean(value); // FEATURE
+ case "Maximized": if (parent == null && getSurface() != null) getSurface().maximized = toBoolean(value); // FEATURE
+ case "Close": if (parent == null && getSurface() != null) getSurface().dispose(true);
+ case "redirect":
+ for(Box cur = (Box)value; cur != null || cur == redirect; cur = cur.parent)
+ if (cur == redirect) { redirect = (Box)value; return; }
+ JS.error("redirect can only be set to a descendant of its current value");
+ case "fontsize": font = Font.getFont(font == null ? null : font.stream, toInt(value)); RECONSTRAIN(); dirty();
+ case "font":
+ if(!(value instanceof Stream)) throw new JSExn("You can only put streams to the font property");
+ if (font == value) return; // FIXME: unclone()
+ font = value == null ? null : Font.getFont((Stream)value, font == null ? 10 : font.pointsize);
+ RECONSTRAIN();
+ dirty();
+ case "x": if (parent==null && Surface.fromBox(this)!=null) {
+ CHECKSET_INT(x);
+ } else {
+ if (test(PACKED) && parent != null) return;
+ CHECKSET_INT(ax);
+ REPLACE();
+ }
+ case "y": if (parent==null && Surface.fromBox(this)!=null) {
+ CHECKSET_INT(y);
+ } else {
+ if (test(PACKED) && parent != null) return;
+ CHECKSET_INT(ay);
+ REPLACE();
+ }
+ case "titlebar": if (getSurface()!=null) getSurface().setTitleBarText(toString(value)); super.put(name,value);
+ // FIXME: icon
+
+ case "Press1": if (!test(STOP_UPWARD_PROPAGATION) && parent != null) parent.putAndTriggerTraps(name, value);
+ case "Press2": if (!test(STOP_UPWARD_PROPAGATION) && parent != null) parent.putAndTriggerTraps(name, value);
+ case "Press3": if (!test(STOP_UPWARD_PROPAGATION) && parent != null) parent.putAndTriggerTraps(name, value);
+ case "Release1": if (!test(STOP_UPWARD_PROPAGATION) && parent != null) parent.putAndTriggerTraps(name, value);
+ case "Release2": if (!test(STOP_UPWARD_PROPAGATION) && parent != null) parent.putAndTriggerTraps(name, value);
+ case "Release3": if (!test(STOP_UPWARD_PROPAGATION) && parent != null) parent.putAndTriggerTraps(name, value);
+ case "Click1": if (!test(STOP_UPWARD_PROPAGATION) && parent != null) parent.putAndTriggerTraps(name, value);
+ case "Click2": if (!test(STOP_UPWARD_PROPAGATION) && parent != null) parent.putAndTriggerTraps(name, value);
+ case "Click3": if (!test(STOP_UPWARD_PROPAGATION) && parent != null) parent.putAndTriggerTraps(name, value);
+ case "DoubleClick1": if (!test(STOP_UPWARD_PROPAGATION) && parent != null) parent.putAndTriggerTraps(name, value);
+ case "DoubleClick2": if (!test(STOP_UPWARD_PROPAGATION) && parent != null) parent.putAndTriggerTraps(name, value);
+ case "DoubleClick3": if (!test(STOP_UPWARD_PROPAGATION) && parent != null) parent.putAndTriggerTraps(name, value);
+ case "KeyPressed": if (!test(STOP_UPWARD_PROPAGATION) && parent != null) parent.putAndTriggerTraps(name, value);
+ case "KeyReleased": if (!test(STOP_UPWARD_PROPAGATION) && parent != null) parent.putAndTriggerTraps(name, value);
+ case "Move": if (!test(STOP_UPWARD_PROPAGATION) && parent != null) parent.putAndTriggerTraps(name, value);
+ case "HScroll": if (!test(STOP_UPWARD_PROPAGATION) && parent != null)
+ parent.putAndTriggerTraps(name, N(((Number)value).floatValue() * ((float)parent.fontSize()) / ((float)fontSize())));
+ case "VScroll": if (!test(STOP_UPWARD_PROPAGATION) && parent != null)
+ parent.putAndTriggerTraps(name, N(((Number)value).floatValue() * ((float)parent.fontSize()) / ((float)fontSize())));
+
+ case "_Move": propagateDownward(name, value, false);
+ case "_Press1": propagateDownward(name, value, false);
+ case "_Press2": propagateDownward(name, value, false);
+ case "_Press3": propagateDownward(name, value, false);
+ case "_Release1": propagateDownward(name, value, false);
+ case "_Release2": propagateDownward(name, value, false);
+ case "_Release3": propagateDownward(name, value, false);
+ case "_Click1": propagateDownward(name, value, false);
+ case "_Click2": propagateDownward(name, value, false);
+ case "_Click3": propagateDownward(name, value, false);
+ case "_DoubleClick1": propagateDownward(name, value, false);
+ case "_DoubleClick2": propagateDownward(name, value, false);
+ case "_DoubleClick3": propagateDownward(name, value, false);
+ case "_KeyPressed": propagateDownward(name, value, false);
+ case "_KeyReleased": propagateDownward(name, value, false);
+ case "_HScroll": propagateDownward(name, value, false);
+ case "_VScroll": propagateDownward(name, value, false);
+
+ case "SizeChange": return;
+ case "ChildChange": return;
+ case "Enter": return;
+ case "Leave": return;
+
+ default: super.put(name, value);
+ //#end
+ }
+
+ private String alignToString() {
+ switch(flags & ALIGNS) {
+ case (ALIGN_TOP | ALIGN_LEFT): return "topleft";
+ case (ALIGN_BOTTOM | ALIGN_LEFT): return "bottomleft";
+ case (ALIGN_TOP | ALIGN_RIGHT): return "topright";
+ case (ALIGN_BOTTOM | ALIGN_RIGHT): return "bottomright";
+ case ALIGN_TOP: return "top";
+ case ALIGN_BOTTOM: return "bottom";
+ case ALIGN_LEFT: return "left";
+ case ALIGN_RIGHT: return "right";
+ case 0: return "center";
+ default: throw new Error("invalid alignment flags: " + (flags & ALIGNS));
+ }
+ }
+
+ private void setAlign(Object value) {
+ clear(ALIGNS);
+ //#switch(value)
+ case "topleft": set(ALIGN_TOP | ALIGN_LEFT);
+ case "bottomleft": set(ALIGN_BOTTOM | ALIGN_LEFT);
+ case "topright": set(ALIGN_TOP | ALIGN_RIGHT);
+ case "bottomright": set(ALIGN_BOTTOM | ALIGN_RIGHT);
+ case "top": set(ALIGN_TOP);
+ case "bottom": set(ALIGN_BOTTOM);
+ case "left": set(ALIGN_LEFT);
+ case "right": set(ALIGN_RIGHT);
+ default: JS.log("invalid alignment \"" + value + "\"");
+ //#end
+ }
+
+ private void setCursor(Object value) {
+ if (value == null) { clear(CURSOR); boxToCursor.remove(this); return; }
+ if (value.equals(boxToCursor.get(this))) return;
+ set(CURSOR);
+ boxToCursor.put(this, value);
+ Surface surface = getSurface();
+ if (surface == null) return;
+ String tempcursor = surface.cursor;
+ propagateDownward(null, null, false);
+ if (surface.cursor != tempcursor) surface.syncCursor();
+ }
+
+ private void setFill(Object value) throws JSExn {
+ if (value == null) {
+ if (texture == null && fillcolor == 0) return;
+ texture = null;
+ fillcolor = 0;
+ } else if (value instanceof String) {
+ int newfillcolor = Color.stringToColor((String)value);
+ if (newfillcolor == fillcolor) return;
+ fillcolor = newfillcolor;
+ texture = null;
+ } else if (value instanceof JS) {
+ Picture newtex = Picture.load((JS)value, this);
+ if (texture == newtex) return;
+ texture = newtex;
+ fillcolor = 0;
+ if (texture != null && texture.isLoaded) perform();
+ } else {
+ throw new JSExn("fill must be null, a String, or a stream, not a " + value.getClass());
+ }
+ dirty();
+ }
+
+ /**
+ * Handles events which propagate down the box tree. If obscured
+ * is set, then we merely check for Enter/Leave.
+ */
+ private void propagateDownward(Object name_, Object value, boolean obscured) {
+
+ String name = (String)name_;
+ if (getSurface() == null) return;
+ int x = globalToLocalX(getSurface()._mousex);
+ int y = globalToLocalY(getSurface()._mousey);
+ boolean wasinside = test(MOUSEINSIDE);
+ boolean isinside = test(VISIBLE) && inside(x, y) && !obscured;
+ if (!wasinside && isinside) {
+ set(MOUSEINSIDE);
+ putAndTriggerTrapsAndCatchExceptions("Enter", T);
+ }
+ if (isinside && test(CURSOR)) getSurface().cursor = (String)boxToCursor.get(this);
+ if (wasinside && !isinside) {
+ clear(MOUSEINSIDE);
+ putAndTriggerTrapsAndCatchExceptions("Leave", T);
+ }
+
+ boolean found = false;
+ if (wasinside || isinside)
+ for(Box child = getChild(treeSize() - 1); child != null; child = child.prevSibling()) {
+ boolean save_stop = child.test(STOP_UPWARD_PROPAGATION);
+ Object value2 = value;
+ if (name.equals("_HScroll") || name.equals("_VScroll"))
+ value2 = N(((Number)value).floatValue() * ((float)child.fontSize()) / (float)fontSize());
+ if (obscured || !child.inside(x - child.x, y - child.y)) {
+ child.propagateDownward(name, value2, true);
+ } else try {
+ found = true;
+ child.clear(STOP_UPWARD_PROPAGATION);
+ if (name != null) child.putAndTriggerTrapsAndCatchExceptions(name, value2);
+ else child.propagateDownward(name, value2, obscured);
+ } finally {
+ if (save_stop) child.set(STOP_UPWARD_PROPAGATION); else child.clear(STOP_UPWARD_PROPAGATION);
+ }
+ if (child.inside(x - child.x, y - child.y))
+ if (name != null && name.equals("_Move")) obscured = true;
+ else break;
+ }
+
+ if (!obscured && !found)
+ if ("_Move".equals(name) || name.startsWith("_Release") || wasinside)
+ if (name != null)
+ putAndTriggerTrapsAndCatchExceptions(name.substring(1), value);
+ }
+
+ /** figures out what box in this subtree of the Box owns the pixel at x,y relitave to the Surface */
+ public static Box whoIs(Box cur, int x, int y) {
+
+ if (cur.parent != null) throw new Error("whoIs may only be invoked on the root box of a surface");
+ int globalx = 0;
+ int globaly = 0;
+
+ // WARNING: this method is called from the event-queueing thread -- it may run concurrently with
+ // ANY part of Ibex, and is UNSYNCHRONIZED for performance reasons. BE CAREFUL HERE.
+
+ if (!cur.test(VISIBLE)) return null;
+ if (!cur.inside(x - globalx, y - globaly)) return cur.parent == null ? cur : null;
+ OUTER: while(true) {
+ for(int i=cur.treeSize() - 1; i>=0; i--) {
+ Box child = cur.getChild(i);
+ if (child == null) continue; // since this method is unsynchronized, we have to double-check
+ globalx += child.x;
+ globaly += child.y;
+ if (child.test(VISIBLE) && child.inside(x - globalx, y - globaly)) { cur = child; continue OUTER; }
+ globalx -= child.x;
+ globaly -= child.y;
+ }
+ break;
+ }
+ return cur;
+ }
+
+
+ // Trivial Helper Methods (should be inlined) /////////////////////////////////////////
+
+ void mark_for_repack() { REPACK(); }
+ public Enumeration keys() { throw new Error("you cannot apply for..in to a " + this.getClass().getName()); }
+ public Box getRoot() { return parent == null ? this : parent.getRoot(); }
+ public Surface getSurface() { return Surface.fromBox(getRoot()); }
+ Box nextPackedSibling() { Box b = nextSibling(); return b == null || (b.test(PACKED | VISIBLE)) ? b : b.nextPackedSibling(); }
+ Box firstPackedChild() { Box b = getChild(0); return b == null || (b.test(PACKED | VISIBLE)) ? b : b.nextPackedSibling(); }
+ public int globalToLocalX(int x) { return parent == null ? x : parent.globalToLocalX(x - this.x); }
+ public int globalToLocalY(int y) { return parent == null ? y : parent.globalToLocalY(y - this.y); }
+ public int localToGlobalX(int x) { return parent == null ? x : parent.globalToLocalX(x + this.x); }
+ public int localToGlobalY(int y) { return parent == null ? y : parent.globalToLocalY(y + this.y); }
+
+ static short min(short a, short b) { if (a<b) return a; else return b; }
+ static int min(int a, int b) { if (a<b) return a; else return b; }
+ static float min(float a, float b) { if (a<b) return a; else return b; }
+
+ static short max(short a, short b) { if (a>b) return a; else return b; }
+ static int max(int a, int b) { if (a>b) return a; else return b; }
+ static float max(float a, float b) { if (a>b) return a; else return b; }
+
+ static int min(int a, int b, int c) { if (a<=b && a<=c) return a; else if (b<=c && b<=a) return b; else return c; }
+ static int max(int a, int b, int c) { if (a>=b && a>=c) return a; else if (b>=c && b>=a) return b; else return c; }
+ static int bound(int a, int b, int c) { if (c < b) return c; if (a > b) return a; return b; }
+ final boolean inside(int x, int y) { return test(VISIBLE) && x >= 0 && y >= 0 && x < width && y < height; }
+
+ void set(int mask) { flags |= mask; }
+ void set(int mask, boolean setclear) { if (setclear) set(mask); else clear(mask); }
+ void clear(int mask) { flags &= ~mask; }
+ public boolean test(int mask) { return ((flags & mask) == mask); }
+
+
+ // Tree Handling //////////////////////////////////////////////////////////////////////
+
+ public final int getIndexInParent() { return parent == null ? 0 : parent.indexNode(this); }
+ public final Box nextSibling() { return parent == null ? null : parent.getChild(parent.indexNode(this) + 1); }
+ public final Box prevSibling() { return parent == null ? null : parent.getChild(parent.indexNode(this) - 1); }
+ public final Box getChild(int i) {
+ if (i < 0) return null;
+ if (i >= treeSize()) return null;
+ return (Box)getNode(i);
+ }
+
+ // Tree Manipulation /////////////////////////////////////////////////////////////////////
+
+ public void removeSelf() {
+ if (parent != null) { parent.removeChild(parent.indexNode(this)); return; }
+ Surface surface = Surface.fromBox(this);
+ if (surface != null) surface.dispose(true);
+ }
+
+ /** remove the i^th child */
+ public void removeChild(int i) {
+ Box b = getChild(i);
+ b.RECONSTRAIN();
+ b.dirty();
+ b.clear(MOUSEINSIDE);
+ deleteNode(i);
+ b.parent = null;
+ REPACK();
+ putAndTriggerTrapsAndCatchExceptions("ChildChange", b);
+ }
+
+ public void put(int i, Object value) throws JSExn {
+ if (i < 0) return;
+
+ if (value != null && !(value instanceof Box)) {
+ if (Log.on) JS.warn("attempt to set a numerical property on a box to a non-box");
+ return;
+ }
+
+ if (redirect == null) {
+ if (value == null) putAndTriggerTrapsAndCatchExceptions("ChildChange", getChild(i));
+ else JS.warn("attempt to add/remove children to/from a node with a null redirect");
+
+ } else if (redirect != this) {
+ if (value != null) putAndTriggerTrapsAndCatchExceptions("ChildChange", value);
+ redirect.put(i, value);
+ if (value == null) {
+ Box b = (Box)redirect.get(new Integer(i));
+ if (b != null) putAndTriggerTrapsAndCatchExceptions("ChildChange", b);
+ }
+
+ } else if (value == null) {
+ if (i < 0 || i > treeSize()) return;
+ Box b = getChild(i);
+ removeChild(i);
+ putAndTriggerTrapsAndCatchExceptions("ChildChange", b);
+
+ } else {
+ Box b = (Box)value;
+
+ // check if box being moved is currently target of a redirect
+ for(Box cur = b.parent; cur != null; cur = cur.parent)
+ if (cur.redirect == b) {
+ if (Log.on) JS.warn("attempt to move a box that is the target of a redirect");
+ return;
+ }
+
+ // check for recursive ancestor violation
+ for(Box cur = this; cur != null; cur = cur.parent)
+ if (cur == b) {
+ if (Log.on) JS.warn("attempt to make a node a parent of its own ancestor");
+ if (Log.on) Log.info(this, "box == " + this + " ancestor == " + b);
+ return;
+ }
+
+ if (b.parent != null) b.parent.removeChild(b.parent.indexNode(b));
+ insertNode(i, b);
+ b.parent = this;
+
+ // need both of these in case child was already uncalc'ed
+ b.REPACK();
+ REPACK();
+
+ b.dirty();
+ putAndTriggerTrapsAndCatchExceptions("ChildChange", b);
+ }
+ }
+
+ public void putAndTriggerTrapsAndCatchExceptions(Object name, Object val) {
+ try {
+ putAndTriggerTraps(name, val);
+ } catch (JSExn e) {
+ JS.log("caught js exception while putting to trap \""+name+"\"");
+ JS.log(e);
+ } catch (Exception e) {
+ JS.log("caught exception while putting to trap \""+name+"\"");
+ JS.log(e);
+ }
+ }
+
+}
+
+
+
+
+
+
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.core;
+
+import java.io.*;
+import org.ibex.js.*;
+import org.ibex.util.*;
+import org.ibex.graphics.*;
+import org.ibex.plat.*;
+import org.ibex.net.*;
+import org.ibex.crypto.*;
+
+/** Singleton class that provides all functionality in the ibex.* namespace */
+public final class Ibex extends JS.Cloneable {
+
+ // FIXME remove this
+ private final JS rr;
+
+ public Ibex(Stream rr) { this.rr = bless(rr); }
+
+ public JS resolveString(String str, boolean permitAbsolute) throws JSExn {
+ if (str.indexOf("://") != -1) {
+ if (permitAbsolute) return (Stream)url2res(str);
+ throw new JSExn("absolute URL " + str + " not permitted here");
+ }
+ // root-relative
+ //JS ret = (JS)getAndTriggerTraps("");
+ //FIXME
+ JS ret = rr;
+ while(str.indexOf('.') != -1) {
+ String path = str.substring(0, str.indexOf('.'));
+ str = str.substring(str.indexOf('.') + 1);
+ ret = (JS)ret.get(path);
+ }
+ if (!"".equals(str)) ret = (JS)ret.get(str);
+ return ret;
+ }
+
+ /** lets us put multi-level get/put/call keys all in the same method */
+ private class Sub extends JS {
+ String key;
+ Sub(String key) { this.key = key; }
+ public void put(Object key, Object val) throws JSExn { Ibex.this.put(this.key + "." + key, val); }
+ public Object get(Object key) throws JSExn { return Ibex.this.get(this.key + "." + key); }
+ public Object call(Object a0, Object a1, Object a2, Object[] rest, int nargs) throws JSExn {
+ return Ibex.this.callMethod(this.key, a0, a1, a2, rest, nargs);
+ }
+ public Object callMethod(Object method, Object a0, Object a1, Object a2, Object[] rest, int nargs) throws JSExn {
+ return Ibex.this.callMethod(this.key + "." + method, a0, a1, a2, rest, nargs);
+ }
+ }
+ private Cache subCache = new Cache(20);
+ private Sub getSub(String s) {
+ Sub ret = (Sub)subCache.get(s);
+ if (ret == null) subCache.put(s, ret = new Sub(s));
+ return ret;
+ }
+
+ public Object get(Object name) throws JSExn {
+ if (name instanceof String && ((String)name).length() == 0) return rr;
+ //#switch(name)
+ case "math": return ibexMath;
+ case "string": return ibexString;
+ case "date": return METHOD;
+ case "box": return new Box();
+ case "clone": return METHOD;
+ case "bless": return METHOD;
+ case "regexp": return METHOD;
+ case "ui": return getSub("ui");
+ case "ui.font": return getSub("ui.font");
+ case "ui.font.wait": return METHOD;
+ case "ui.font.width": return METHOD;
+ case "ui.font.height": return METHOD;
+ case "ui.font.sansserif": return Main.builtin.get("fonts/vera/Vera.ttf");
+ case "ui.font.monospace": return Main.builtin.get("fonts/vera/VeraMono.ttf");
+ case "ui.font.serif": return Main.builtin.get("fonts/vera/VeraSe.ttf");
+ case "ui.browser": return METHOD;
+ case "ui.mouse": return getSub("ui.mouse");
+ case "ui.mouse.button":
+ if (Surface.button1 && !Surface.button2 && !Surface.button3) return N(1);
+ else if (!Surface.button1 && Surface.button2 && !Surface.button3) return N(2);
+ else if (!Surface.button1 && !Surface.button2 && Surface.button3) return N(3);
+ else return ZERO;
+ case "ui.key": return getSub("ui.key");
+ case "ui.key.name": return getSub("ui.key.name");
+ case "ui.key.name.alt": return Platform.altKeyName();
+ case "ui.key.alt": return Surface.alt ? T : F;
+ case "ui.key.control": return Surface.control ? T : F;
+ case "ui.key.shift": return Surface.shift ? T : F;
+ case "ui.clipboard": return Platform.getClipBoard();
+ case "ui.maxdim": return N(Short.MAX_VALUE);
+ case "ui.screen": return getSub("ui.screen");
+ case "ui.screen.width": return N(Platform.getScreenWidth());
+ case "ui.screen.height": return N(Platform.getScreenHeight());
+ case "undocumented": return getSub("undocumented");
+ case "undocumented.initialOrigin": return Main.origin;
+ case "undocumented.initialTemplate": return Main.initialTemplate;
+ case "thread": return getSub("thread");
+ case "thread.yield": return METHOD;
+ case "thread.sleep": return METHOD;
+ case "stream": return getSub("stream");
+ case "stream.homedir": return url2res("file:" + System.getProperty("user.home"));
+ case "stream.tempdir": return url2res("file:" + System.getProperty("java.io.tempdir"));
+ case "stream.watch": return METHOD;
+ case "stream.unzip": return METHOD;
+ case "stream.uncab": return METHOD;
+ case "stream.cache": return METHOD;
+ case "stream.url": return METHOD;
+ case "stream.parse.html": return METHOD;
+ case "stream.parse.xml": return METHOD;
+ case "stream.parse.utf8": return METHOD;
+ case "net": return getSub("net");
+ case "net.rpc": return getSub("net.rpc");
+ case "net.rpc.xml": return METHOD;
+ case "net.rpc.soap": return METHOD;
+ case "log": return getSub("log");
+ case "log.debug": return METHOD;
+ case "log.info": return METHOD;
+ case "log.warn": return METHOD;
+ case "log.error": return METHOD;
+ case "crypto": return getSub("crypto");
+ case "crypto.rsa": return METHOD;
+ case "crypto.md5": return METHOD;
+ case "crypto.sha1": return METHOD;
+ case "crypto.rc4": return METHOD;
+ //#end
+ return super.get(name);
+ }
+
+ public void put(Object name, final Object value) throws JSExn {
+ //#switch(name)
+ case "thread": Scheduler.add((Task)value); return;
+ case "ui.clipboard": Platform.setClipBoard((String)value); return;
+ case "ui.frame": Platform.createSurface((Box)value, true, true); return;
+ case "ui.window": Platform.createSurface((Box)value, false, true); return;
+ case "undocumented.proxyAuthorization":
+ HTTP.Proxy.Authorization.authorization = value.toString();
+ HTTP.Proxy.Authorization.waitingForUser.release();
+ return;
+ //#end
+ throw new JSExn("attempted to put unknown property: ibex."+name);
+ }
+
+ public Object callMethod(Object name, Object a, Object b, Object c, Object[] rest, int nargs) throws JSExn {
+ try {
+ //#switch(name)
+ case "date": return new JSDate(a, b, c, rest, nargs);
+ case "net.rpc.soap": return new SOAP((String)a, "", (String)b, (String)c);
+ // FIXME support object dumping
+ case "log.debug": JS.debug(a== null ? "**null**" : a.toString()); return null;
+ case "log.info": JS.info(a== null ? "**null**" : a.toString()); return null;
+ case "log.warn": JS.warn(a== null ? "**null**" : a.toString()); return null;
+ case "log.error": JS.error(a== null ? "**null**" : a.toString()); return null;
+ //#end
+
+ switch (nargs) {
+ case 0:
+ //#switch(name)
+ case "thread.yield": sleep(0); return null;
+ //#end
+ break;
+ case 1:
+ //#switch(name)
+ case "clone":
+ if (!(a instanceof JS.Cloneable)) throw new JSExn("cannot clone a " + a.getClass().getName());
+ return ((JS.Cloneable)a).jsclone();
+ case "bless": return bless((JS)a);
+ case "ui.browser": Platform.newBrowserWindow((String)a); return null;
+ case "stream.unzip": return new Stream.Zip((Stream)a);
+ case "stream.uncab": return new Stream.Cab((Stream)a);
+ case "stream.cache":
+ try { return new Stream.CachedStream((Stream)a, "resources", true); }
+ catch (Stream.NotCacheableException e) { throw new JSExn("this resource cannot be cached"); }
+ case "stream.url": {
+ String url = (String)a;
+ if (url.startsWith("http://")) return new Stream.HTTP(url);
+ else if (url.startsWith("https://")) return new Stream.HTTP(url);
+ else if (url.startsWith("data:")) return new Stream.ByteArray(Base64.decode(url.substring(5)), null);
+ else if (url.startsWith("utf8:")) return new Stream.ByteArray(url.substring(5).getBytes(), null);
+ else if (url.startsWith("file:")) {
+ // FIXME
+ Platform.fileDialog(url.substring(5), false);
+ }
+ throw new JSExn("invalid resource specifier " + url);
+ }
+ case "thread.sleep": sleep(JS.toInt(a)); return null;
+ case "regexp": return new JSRegexp(a, null);
+ case "net.rpc.xml": return new XMLRPC((String)a, "");
+ case "crypto.rsa": /* FEATURE */ return null;
+ case "crypto.md5": /* FEATURE */ return null;
+ case "crypto.sha1": /* FEATURE */ return null;
+ case "crypto.rc4": /* FEATURE */ return null;
+ case "stream.parse.html": throw new JSExn("not implemented yet"); //return null;
+ case "stream.parse.xml": new XMLHelper((JS)b).doParse((JS)a); return null;
+ // FIXME backgrounding
+ case "stream.parse.utf8": try { return new String(InputStreamToByteArray.convert(Stream.getInputStream(a))); }
+ catch (Exception e) { Log.warn(this, e); }
+ //#end
+ break;
+ case 2:
+ //#switch(name)
+ case "stream.watch": return new Stream.ProgressWatcher((Stream)a, (JS)b);
+ case "regexp": return new JSRegexp(a, b);
+ //#end
+ case 3:
+ //#switch(name)
+ case "ui.font.height": return N(Font.getFont((Stream)a, JS.toInt(b)).textheight((String)c));
+ case "ui.font.wait": throw new Error("FIXME: ibex.ui.font.wait not implemented");
+ case "ui.font.width": return N(Font.getFont((Stream)a, JS.toInt(b)).textwidth((String)c));
+ //#end
+ break;
+ }
+ } catch (RuntimeException e) {
+ // FIXME: maybe JSExn should take a second argument, Exception
+ Log.warn(this, "ibex."+name+"() threw: " + e);
+ throw new JSExn("invalid argument for ibex object method "+name+"()");
+ }
+
+ throw new JSExn("invalid number of arguments ("+nargs+") for ibex object method "+name+"()");
+ }
+
+ public Stream url2res(String url) throws JSExn {
+ if (url.startsWith("http://")) return new Stream.HTTP(url);
+ else if (url.startsWith("https://")) return new Stream.HTTP(url);
+ else if (url.startsWith("data:")) return new Stream.ByteArray(Base64.decode(url.substring(5)), null);
+ else if (url.startsWith("utf8:")) return new Stream.ByteArray(url.substring(5).getBytes(), null);
+ else throw new JSExn("invalid resource specifier " + url);
+ // FIXME support file:// via dialog boxes
+ }
+
+ public static void sleep(final int i) throws JSExn {
+ try {
+ final JS.UnpauseCallback callback = JS.pause();
+ // FEATURE use a single sleeper thread
+ new Thread() { public void run() {
+ try { Thread.sleep(i); } catch (InterruptedException e) { }
+ Scheduler.add(callback);
+ } }.start();
+ } catch (JS.NotPauseableException npe) {
+ throw new JSExn("you cannot sleep or yield in the foreground thread");
+ }
+ }
+
+ public static final JSMath ibexMath = new JSMath() {
+ private JS gs = new JSScope.Global();
+ public Object get(Object key) throws JSExn {
+ //#switch(key)
+ case "isNaN": return gs.get("isNaN");
+ case "isFinite": return gs.get("isFinite");
+ case "NaN": return gs.get("NaN");
+ case "Infinity": return gs.get("Infinity");
+ //#end
+ return super.get(key);
+ }
+ };
+
+ public static final JS ibexString = new JS() {
+ private JS gs = new JSScope.Global();
+ public void put(Object key, Object val) { }
+ public Object get(Object key) throws JSExn {
+ //#switch(key)
+ case "parseInt": return gs.get("parseInt");
+ case "parseFloat": return gs.get("parseFloat");
+ case "decodeURI": return gs.get("decodeURI");
+ case "decodeURIComponent": return gs.get("decodeURIComponent");
+ case "encodeURI": return gs.get("encodeURI");
+ case "encodeURIComponent": return gs.get("encodeURIComponent");
+ case "escape": return gs.get("escape");
+ case "unescape": return gs.get("unescape");
+ case "fromCharCode": return gs.get("stringFromCharCode");
+ //#end
+ return null;
+ }
+ };
+
+ private class XMLHelper extends XML {
+ private class Wrapper extends XML.Exn { public JSExn wrapee; public Wrapper(JSExn jse) { super(""); wrapee = jse; } }
+ private JS characters, whitespace, endElement, startElement;
+ public XMLHelper(JS b) throws JSExn {
+ super(BUFFER_SIZE);
+ startElement = (JS)b.getAndTriggerTraps("startElement");
+ endElement = (JS)b.getAndTriggerTraps("endElement");
+ characters = (JS)b.getAndTriggerTraps("characters");
+ whitespace = (JS)b.getAndTriggerTraps("whitespace");
+ }
+
+ public void startElement(XML.Element c) throws XML.Exn { try {
+ JS attrs = new JS();
+ // FIXME attribute URIs? add an additional hash?
+ for(int i=0; i<c.getAttrLen(); i++) attrs.put(c.getAttrKey(i), c.getAttrVal(i));
+ startElement.call(c.getLocalName(), attrs, c.getUri(), null, 3);
+ } catch (JSExn jse) { throw new Wrapper(jse); } }
+
+ public void endElement(XML.Element c) throws XML.Exn { try {
+ endElement.call(c.getLocalName(), c.getUri(), null, null, 2);
+ } catch (JSExn jse) { throw new Wrapper(jse); } }
+
+ public void characters(char[] ch, int start, int length) throws XML.Exn { try {
+ characters.call(new String(ch, start, length), null, null, null, 1);
+ } catch (JSExn jse) { throw new Wrapper(jse); } }
+
+ public void whitespace(char[] ch, int start, int length) throws XML.Exn { try {
+ whitespace.call(new String(ch, start, length), null, null, null, 1);
+ } catch (JSExn jse) { throw new Wrapper(jse); } }
+
+ public void doParse(JS s) throws JSExn {
+ try {
+ parse(new BufferedReader(new InputStreamReader(Stream.getInputStream(s))));
+ } catch (Wrapper e) {
+ throw e.wrapee;
+ } catch (XML.Exn e) {
+ throw new JSExn("error parsing XML: " + e.toString());
+ } catch (IOException e) {
+ if (Log.on) Log.info(this, "IO Exception while reading from file");
+ if (Log.on) Log.info(this, e);
+ throw new JSExn("error reading from Resource");
+ }
+ }
+ }
+
+ // FEATURE: move this into builtin.xwar
+ public Blessing bless(JS b) { return new Ibex.Blessing((JS.Cloneable)b, this, null, null); }
+ public static class Blessing extends JS.Clone {
+ private Ibex ibex;
+ private Template t = null;
+ public Object parentkey = null;
+ public Blessing parent = null;
+ private Hash cache = new Hash();
+ public Blessing(JS.Cloneable clonee, Ibex ibex, Blessing parent, Object parentkey) {
+ super(clonee); this.ibex = ibex; this.parentkey = parentkey; this.parent = parent; }
+ public Object get(Object key) throws JSExn {
+ if (key.equals("")) return ((Object)getStatic());
+ if (cache.get(key) != null) return cache.get(key);
+ Object ret = new Blessing((JS.Cloneable)clonee.get(key), ibex, this, key);
+ cache.put(key, ret);
+ return ret;
+ }
+ public static Blessing getBlessing(Object o) {
+ if (!(o instanceof JS)) return null;
+ JS js = (JS)o;
+ while (js instanceof JS.Clone && !(js instanceof Blessing)) js = ((JS.Clone)js).getClonee();
+ if (!(js instanceof Blessing)) return null;
+ return (Blessing)js;
+ }
+ public InputStream getImage() throws JSExn {
+ try {
+ InputStream in = Stream.getInputStream(this);
+ if (in != null) return in;
+ } catch (IOException e) { /* DELIBERATE */ }
+ String[] exts = new String[] { ".png", ".jpeg", ".gif" };
+ for (int i=0; i < exts.length; i++)
+ try {
+ InputStream in = Stream.getInputStream(parent.get(parentkey + exts[i]));
+ if (in != null) return in;
+ } catch (IOException f) { /* DELIBERATE */ }
+ return null;
+ }
+ public JSScope getStatic() {
+ try {
+ if (t == null) {
+ JS res = (JS) parent.get(parentkey + ".t");
+ t = Template.buildTemplate(res.unclone().toString(), res, ibex);
+ }
+ return t.staticScope;
+ } catch (Exception e) {
+ Log.error(this, e);
+ return null;
+ }
+ }
+ public Object call(Object a, Object b, Object c, Object[] rest, int nargs) throws JSExn {
+ // GROSS hack
+ if (nargs != 1 && nargs != 9999) throw new JSExn("FIXME can only call with one arg");
+ getStatic();
+ if (t == null) throw new JSExn("No such template " + parentkey);
+ if (nargs == 9999) return t;
+ t.apply((Box)a);
+ return a;
+ }
+ }
+
+}
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.core;
+
+import java.io.*;
+import org.ibex.util.*;
+import org.ibex.crypto.*;
+
+/** Manages access to ~/.ibex */
+public class LocalStorage {
+
+ static String ibexDirName = System.getProperty("user.home") + java.io.File.separatorChar + ".ibex";
+
+ static java.io.File ibexDir = null;
+ static java.io.File cacheDir = null;
+
+ static {
+ try {
+ ibexDir = new java.io.File(ibexDirName);
+ if (!ibexDir.mkdirs()) ibexDir = null;
+ try {
+ cacheDir = new java.io.File(ibexDirName + java.io.File.separatorChar + "cache");
+ if (!cacheDir.mkdirs()) cacheDir = null;
+ } catch (Exception e) {
+ Log.warn(LocalStorage.class, "unable to create cache directory " +
+ ibexDirName + java.io.File.separatorChar + "cache");
+ }
+ } catch (Exception e) {
+ Log.warn(LocalStorage.class, "unable to create ibex directory " + ibexDirName);
+ }
+ }
+
+ // FEATURE: we ought to be able to do stuff like sha1-checking and date checking on cached resources
+ public static class Cache {
+
+ private static void delTree(java.io.File f) throws IOException {
+ if (f.isDirectory()) {
+ String[] s = f.list();
+ for(int i=0; i<s.length; i++)
+ delTree(new java.io.File(f.getPath() + java.io.File.separatorChar + s[i]));
+ }
+ f.delete();
+ }
+
+ public static void flush() throws IOException {
+ delTree(cacheDir);
+ cacheDir.mkdirs();
+ }
+
+ public static java.io.File getCacheFileForKey(String key) {
+ // FEATURE: be smarter here
+ return new java.io.File(cacheDir.getPath() + File.separatorChar + new String(Base64.encode(key.getBytes())));
+ }
+
+ }
+}
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.core;
+
+import java.net.*;
+import java.io.*;
+import java.util.*;
+import org.ibex.js.*;
+import org.ibex.util.*;
+import org.ibex.plat.*;
+import org.ibex.graphics.*;
+
+/** Entry point for the Ibex Engine; handles splash screen, initial xwar loading, and argument processing */
+public class Main {
+
+ /**
+ * FEATURE: this should be implemented using self-emulation
+ * Used for security checks. If this is null, it means that only
+ * scripts originating from the local filesystem are loaded in
+ * the engine (maximum permissions). If scripts have been loaded
+ * from multiple locations, this will be 0.0.0.0 (the invalid
+ * IP).
+ */
+ public static java.net.InetAddress originAddr = null;
+ public static String originHost = null;
+ public static String origin = null;
+ public static String initialTemplate = null;
+
+ public static final Stream builtin = new Stream.Zip(new Stream.Builtin());
+
+ public static void printUsage() {
+ System.err.println("Usage: ibex [-lawp] [ url | file | directory ]");
+ System.err.println("");
+ System.err.println(" -l <level> set logging level to { debug, info (default), warn, error, silent }");
+ System.err.println(" -l rpc log all XML-RPC and SOAP conversations");
+ System.err.println(" -l user@host email log to user@host");
+ System.err.println(" -l host:port emit log to TCP socket");
+ System.err.println(" -l <file> write log to a file on disk");
+ System.err.println(" -a check assertions");
+ System.err.println(" -w <window-id> reserved for libibex");
+ System.err.println(" -p dump profiling information [not yet supported]");
+ Runtime.getRuntime().exit(-1);
+ }
+
+ public static void main(String[] args) throws UnknownHostException, JSExn, IOException {
+ int startargs = 0;
+ while (true) {
+ if (startargs > args.length - 1) printUsage();
+ else if (args[startargs].equals("-a")) JS.checkAssertions = true;
+ else if (args[startargs].equals("-l")) {
+ startargs++;
+ StringTokenizer opts = new StringTokenizer(args[startargs], ",");
+ while(opts.hasMoreTokens()) {
+ String opt = opts.nextToken();
+ if (opt.indexOf('@') != -1) Log.email(opt);
+ else if (opt.indexOf(':') != -1)
+ Log.tcp(opt.substring(0, opt.indexOf(':')),
+ Integer.parseInt(opt.substring(opt.indexOf(':') + 1)));
+ else if (opt.equals("debug")) Log.level = Log.DEBUG;
+ else if (opt.equals("info")) Log.level = Log.INFO;
+ else if (opt.equals("warn")) Log.level = Log.WARN;
+ else if (opt.equals("error")) Log.level = Log.ERROR;
+ else if (opt.equals("silent")) Log.level = Log.SILENT;
+ else if (opt.equals("rpc")) Log.rpc = true;
+ else Log.file(opt);
+ }
+ }
+ else break;
+ startargs++;
+ }
+
+ org.ibex.plat.Platform.forceLoad();
+ if (Log.on) for(int i=0; i<args.length; i++) Log.info(Main.class, "argument " + i + ": " + args[i]);
+
+ initialTemplate = args.length > startargs + 1 ? args[startargs + 1] : "main";
+ origin = args[startargs];
+
+ Stream rr;
+ final String startupTemplate;
+ if (origin.startsWith("http://") || origin.startsWith("https://")) {
+ originHost = origin.substring(origin.indexOf('/') + 2);
+ originHost = originHost.substring(0, originHost.indexOf('/') == -1 ? originHost.length() : originHost.indexOf('/'));
+ if (originHost.indexOf('@') != -1) originHost = originHost.substring(originHost.indexOf('@') + 1);
+ originAddr = InetAddress.getByName(originHost);
+ rr = builtin;
+ startupTemplate = "org.ibex.builtin.splash";
+ } else {
+ rr = new Stream.File(origin);
+ if (!new File(origin).isDirectory()) rr = new Stream.Zip(rr);
+ startupTemplate = initialTemplate;
+ }
+
+ if (Log.on) Log.info(Main.class, "loading xwar");
+ final Ibex ibex = new Ibex(rr);
+
+ org.ibex.graphics.Surface.scarImage =
+ Picture.load((Stream)Main.builtin.get("org/ibex/core/builtin/scar.png"),
+ new Task() { public void perform() throws JSExn, UnknownHostException {
+ if (Log.on) Log.info(Main.class, "invoking initial template");
+ ibex.resolveString(startupTemplate, false).call(new Box(), null, null, null, 1);
+ } });
+
+ Scheduler.init();
+ }
+}
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.core;
+
+import java.io.*;
+import java.util.*;
+import org.ibex.js.*;
+import org.ibex.util.*;
+
+/**
+ * Encapsulates a template node (the <template/> element of a
+ * .ibex file, or any child element thereof).
+ *
+ * Note that the Template instance corresponding to the
+ * <template/> node carries all the header information -- hence
+ * some of the instance members are not meaningful on non-root
+ * Template instances. We refer to these non-root instances as
+ * <i>anonymous templates</i>.
+ *
+ * See the Ibex reference for information on the order in which
+ * templates are applied, attributes are put, and scripts are run.
+ */
+public class Template {
+
+ // Instance Members ///////////////////////////////////////////////////////
+
+ String id = null; ///< the id of this box
+ String redirect = null; ///< the id of the redirect target; only meaningful on a root node
+ private String[] keys; ///< keys to be "put" to instances of this template; elements correspond to those of vals
+ private Object[] vals; ///< values to be "put" to instances of this template; elements correspond to those of keys
+ private String[] urikeys;
+ private String[] urivals;
+ private Vec children = new Vec(); ///< during XML parsing, this holds the list of currently-parsed children; null otherwise
+ private JS script = null; ///< the script on this node
+ Template prev;
+ Template prev2;
+ JSScope staticScope = null; ///< the scope in which the static block is executed
+ JS staticObject = null;
+
+
+ // Only used during parsing /////////////////////////////////////////////////////////////////
+
+ private StringBuffer content = null; ///< during XML parsing, this holds partially-read character data; null otherwise
+ private int content_start = 0; ///< line number of the first line of <tt>content</tt>
+ private int startLine = -1; ///< the line number that this element starts on
+ private Ibex ibex;
+
+
+ // Static data/methods ///////////////////////////////////////////////////////////////////
+
+ // for non-root nodes
+ private Template(Template t, int startLine) { prev = t; this.ibex = t.ibex; this.startLine = startLine; }
+ private Template(Ibex ibex) { this.ibex = ibex; }
+
+
+ // Methods to apply templates ////////////////////////////////////////////////////////
+
+
+ /** Applies the template to Box b
+ * @param pboxes a vector of all box parents on which to put $-references
+ * @param ptemplates a vector of the fileNames to recieve private references on the pboxes
+ */
+ public void apply(Box b) throws JSExn {
+ try {
+ apply(b, null);
+ } catch (IOException e) {
+ b.clear(Box.VISIBLE);
+ b.mark_for_repack();
+ Log.warn(this, e);
+ throw new JSExn(e.toString());
+ } catch (JSExn e) {
+ b.clear(Box.VISIBLE);
+ b.mark_for_repack();
+ Log.warn(this, e);
+ throw e;
+ }
+ }
+
+ private void apply(Box b, PerInstantiationScope parentPis) throws JSExn, IOException {
+ if (prev != null) prev.apply(b, null);
+ if (prev2 != null) prev2.apply(b, null);
+
+ // FIXME this dollar stuff is all wrong
+ if (id != null) parentPis.putDollar(id, b);
+
+ PerInstantiationScope pis = new PerInstantiationScope(b, ibex, parentPis, staticObject);
+ for(int i=0; i<urikeys.length; i++) {
+ if (urikeys[i] == null) continue;
+ pis.declare(urikeys[i]);
+ pis.put(urikeys[i], ibex.resolveString(urivals[i], true));
+ }
+
+ // FIXME needs to obey the new application-ordering rules
+ for (int i=0; children != null && i<children.size(); i++) {
+ Box kid = new Box();
+ ((Template)children.elementAt(i)).apply(kid, pis);
+ b.putAndTriggerTraps(b.get("numchildren"), kid);
+ }
+
+ if (script != null) JS.cloneWithNewParentScope(script, pis).call(null, null, null, null, 0);
+
+ Object key, val;
+ for(int i=0; keys != null && i < keys.length; i++) {
+ if (keys[i] == null) continue;
+ key = keys[i];
+ val = vals[i];
+
+ if ("null".equals(val)) val = null;
+
+ if (val != null && val instanceof String && ((String)val).length() > 0) {
+ switch (((String)val).charAt(0)) {
+ case '$':
+ val = pis.get(val);
+ if (val == null) throw new JSExn("unknown box id '"+vals[i]+"' referenced in XML attribute");
+ break;
+ case '.':
+ val = ibex.resolveString(((String)val).substring(1), false);
+ // FIXME: url case
+ // FIXME: should we be resolving all of these in the XML-parsing code?
+ }
+ }
+ b.putAndTriggerTraps(key, val);
+ }
+ }
+
+
+
+ // XML Parsing /////////////////////////////////////////////////////////////////
+
+ public static Template buildTemplate(String sourceName, Object s, Ibex ibex) {
+ try {
+ return new TemplateHelper(sourceName, s, ibex).t;
+ } catch (Exception e) {
+ Log.error(Template.class, e);
+ return null;
+ }
+ }
+
+ /** handles XML parsing; builds a Template tree as it goes */
+ static final class TemplateHelper extends XML {
+
+ String sourceName;
+ private int state = STATE_INITIAL;
+ private static final int STATE_INITIAL = 0;
+ private static final int STATE_IN_ROOT_NODE = 1;
+ private static final int STATE_IN_TEMPLATE_NODE = 2;
+ private static final int STATE_IN_META_NODE = 3;
+
+ StringBuffer static_content = null;
+ int static_content_start = 0;
+ Vec nodeStack = new Vec();
+ Template t = null;
+ int meta = 0;
+ Ibex ibex;
+
+ String initial_uri = "";
+
+ public TemplateHelper(String sourceName, Object s, Ibex ibex) throws XML.Exn, IOException, JSExn {
+ this.sourceName = sourceName;
+ this.ibex = ibex;
+ InputStream is = Stream.getInputStream(s);
+ Ibex.Blessing b = Ibex.Blessing.getBlessing(s).parent;
+ while(b != null) {
+ if(b.parentkey != null) initial_uri = b.parentkey + (initial_uri.equals("") ? "" : "." + initial_uri);
+ b = b.parent;
+ }
+ initial_uri = "";
+ parse(new InputStreamReader(is));
+ JS staticScript = parseScript(static_content, static_content_start);
+ t.staticObject = new JS();
+ t.staticScope = new PerInstantiationScope(null, ibex, null, t.staticObject);
+ if (staticScript != null) JS.cloneWithNewParentScope(staticScript, t.staticScope).call(null, null, null, null, 0);
+ }
+
+ private JS parseScript(StringBuffer content, int content_start) throws IOException {
+ if (content == null) return null;
+ String contentString = content.toString();
+ if (contentString.trim().length() > 0) return JS.fromReader(sourceName, content_start, new StringReader(contentString));
+ return null;
+ }
+
+ public void startElement(XML.Element c) throws XML.Exn {
+ switch(state) {
+ case STATE_IN_META_NODE: { meta++; return; }
+ case STATE_INITIAL:
+ if (!"ibex".equals(c.getLocalName()))
+ throw new XML.Exn("root element was not <ibex>", XML.Exn.SCHEMA, getLine(), getCol());
+ if (c.getAttrLen() != 0)
+ throw new XML.Exn("root element must not have attributes", XML.Exn.SCHEMA, getLine(), getCol());
+ if (c.getUri("ui") == null || "".equals(c.getUri("ui"))) c.addUri("ui", "ibex://ui");
+ if (c.getUri("meta") == null || "".equals(c.getUri("meta"))) c.addUri("meta", "ibex://meta");
+ if (c.getUri("") == null || "".equals(c.getUri(""))) c.addUri("", initial_uri);
+ state = STATE_IN_ROOT_NODE;
+ return;
+ case STATE_IN_ROOT_NODE:
+ if ("ibex://meta".equals(c.getUri())) { state = STATE_IN_META_NODE; meta = 0; return; }
+ state = STATE_IN_TEMPLATE_NODE;
+ t = (t == null) ? new Template(ibex) : new Template(t, getLine());
+ break;
+ case STATE_IN_TEMPLATE_NODE:
+ nodeStack.addElement(t);
+ t = new Template(ibex);
+ break;
+ }
+
+ if (!("ibex://ui".equals(c.getUri()) && "box".equals(c.getLocalName()))) {
+ String tagname = (c.getUri().equals("") ? "" : (c.getUri() + ".")) + c.getLocalName();
+ // GROSS hack
+ try {
+ // GROSSER hack
+ t.prev2 = (Template)t.ibex.resolveString(tagname, false).call(null, null, null, null, 9999);
+ } catch (Exception e) {
+ Log.error(Template.class, e);
+ }
+ }
+
+ Hash urimap = c.getUriMap();
+ t.urikeys = new String[urimap.size()];
+ t.urivals = new String[urimap.size()];
+ Enumeration uriEnumeration = urimap.keys();
+ int ii = 0;
+ while(uriEnumeration.hasMoreElements()) {
+ String key = (String)uriEnumeration.nextElement();
+ String val = (String)urimap.get(key);
+ if (val.equals("ibex://ui")) continue;
+ if (val.equals("ibex://meta")) continue;
+ t.urikeys[ii] = key;
+ if (val.length() > 0 && val.charAt(0) == '.') val = val.substring(1);
+ t.urivals[ii] = val;
+ ii++;
+ }
+
+ Vec keys = new Vec(c.getAttrLen());
+ Vec vals = new Vec(c.getAttrLen());
+
+ // process attributes into Vecs, dealing with any XML Namespaces in the process
+ ATTR: for (int i=0; i < c.getAttrLen(); i++) {
+ if (c.getAttrKey(i).equals("id")) {
+ t.id = c.getAttrVal(i).toString().intern();
+ continue ATTR;
+ }
+
+ // treat value starting with '.' as resource reference
+ String uri = c.getAttrUri(i); if (!uri.equals("")) uri = '.' + uri;
+ keys.addElement(c.getAttrKey(i));
+ vals.addElement((c.getAttrVal(i).startsWith(".") ? uri : "") + c.getAttrVal(i));
+ }
+
+ if (keys.size() == 0) return;
+
+ // sort the attributes lexicographically
+ Vec.sort(keys, vals, new Vec.CompareFunc() { public int compare(Object a, Object b) {
+ return ((String)a).compareTo((String)b);
+ } });
+
+ t.keys = new String[keys.size()];
+ t.vals = new Object[vals.size()];
+ keys.copyInto(t.keys);
+ vals.copyInto(t.vals);
+
+ // convert attributes to appropriate types and intern strings
+ for(int i=0; i<t.keys.length; i++) {
+ t.keys[i] = t.keys[i].intern();
+
+ String valString = t.vals[i].toString();
+
+ if (valString.equals("true")) t.vals[i] = Boolean.TRUE;
+ else if (valString.equals("false")) t.vals[i] = Boolean.FALSE;
+ else if (valString.equals("null")) t.vals[i] = null;
+ else {
+ boolean hasNonNumeral = false;
+ boolean periodUsed = false;
+ for(int j=0; j<valString.length(); j++)
+ if (j == 0 && valString.charAt(j) == '-') {
+ } else if (valString.charAt(j) == '.' && !periodUsed && j != valString.length() - 1) {
+ periodUsed = true;
+ } else if (!Character.isDigit(valString.charAt(j))) {
+ hasNonNumeral = true;
+ break;
+ }
+ if (valString.length() > 0 && !hasNonNumeral) t.vals[i] = new Double(valString);
+ else t.vals[i] = valString.intern();
+ }
+ }
+ }
+
+ public void endElement(XML.Element c) throws XML.Exn, IOException {
+ switch(state) {
+ case STATE_IN_META_NODE: if (--meta < 0) state = STATE_IN_ROOT_NODE; return;
+ case STATE_IN_ROOT_NODE: return;
+ case STATE_IN_TEMPLATE_NODE: {
+ if (t.content != null) { t.script = parseScript(t.content, t.content_start); t.content = null; }
+ if (nodeStack.size() == 0) { state = STATE_IN_ROOT_NODE; return; }
+ Template oldt = t;
+ t = (Template)nodeStack.lastElement();
+ nodeStack.setSize(nodeStack.size() - 1);
+ t.children.addElement(oldt);
+ int oldt_lines = getLine() - oldt.startLine;
+ if (t.content == null) t.content = new StringBuffer();
+ for (int i=0; oldt_lines > i; i++) t.content.append('\n');
+ }
+ }
+ }
+
+ public void characters(char[] ch, int start, int length) throws XML.Exn {
+ for (int i=0; length >i; i++) if (ch[start+i] == '\t')
+ Log.error(Template.class, "tabs are not allowed in Ibex files ("+getLine()+":"+getCol()+")");
+ switch(state) {
+ case STATE_IN_TEMPLATE_NODE:
+ if (t.content == null) {
+ t.content_start = getLine();
+ t.content = new StringBuffer();
+ }
+ t.content.append(ch, start, length);
+ return;
+ case STATE_IN_ROOT_NODE:
+ if (static_content == null) {
+ static_content_start = getLine();
+ static_content = new StringBuffer();
+ }
+ static_content.append(ch, start, length);
+ return;
+ }
+ }
+
+ public void whitespace(char[] ch, int start, int length) throws XML.Exn { }
+ }
+
+ private static class PerInstantiationScope extends JSScope {
+ Ibex ibex = null;
+ PerInstantiationScope parentBoxPis = null;
+ JS myStatic = null;
+ void putDollar(String key, Box target) throws JSExn {
+ if (parentBoxPis != null) parentBoxPis.putDollar(key, target);
+ declare("$" + key);
+ put("$" + key, target);
+ }
+ public PerInstantiationScope(JSScope parentScope, Ibex ibex, PerInstantiationScope parentBoxPis, JS myStatic) {
+ super(parentScope);
+ this.parentBoxPis = parentBoxPis;
+ this.ibex = ibex;
+ this.myStatic = myStatic;
+ }
+ public Object get(Object key) throws JSExn {
+ if (super.has(key)) return super.get(key);
+ if (key.equals("ibex")) return ibex;
+ if (key.equals("")) return ibex.get("");
+ if (key.equals("static")) return myStatic;
+ return super.get(key);
+ }
+ }
+
+}
+
+
--- /dev/null
+<!-- Copyright 2002 Adam Megacz, see the COPYING file for licensing [LGPL] -->
+<ibex>
+
+ <redirect target="self"/>
+ <template thickness="2" depth="up" hpad="2" vpad="2">
+
+ var bar = 5;
+
+ _depth = function(d) {
+ arguments.cascade(d);
+ sync();
+ }
+
+ var sync = function() {
+ if (thickness > hpad) hpad = thickness;
+ if (thickness > vpad) vpad = thickness;
+
+ if (depth == "up") border = "org.ibex.builtin.bevel_2_up";
+ else if (depth == "down") border = "org.ibex.builtin.bevel_2_down";
+ else if (depth == "flat") border = "org.ibex.builtin.bevel_2_flat";
+ else border = null;
+ }
+
+ </template>
+
+</ibex>
--- /dev/null
+<!-- Copyright 2002 Adam Megacz, see the COPYING file for licensing [LGPL] -->
+<ibex>
+
+ <redirect target="self"/>
+ <preapply name="org.ibex.builtin.bevel"/>
+ <template hot="false">
+
+ var owned = false;
+
+ _holdfrequency = function() { }
+
+ // FIXME: I don't know why I can't use an attribute for this; causes infinite loops
+ holdfrequency = 250;
+
+ __Press1 = function(message) {
+ owned = true;
+ press = true;
+
+ ibex.thread = function() {
+ ibex.sleep(holdfrequency);
+ while (owned) {
+ if (ibex.button == 1 and mouseinside) hold = true;
+ ibex.sleep(holdfrequency);
+ }
+ }
+ root._Release1 = function() {
+ if (mouseinside and owned) click = true;
+ owned = false;
+ root.__Release1 = null;
+ release = true;
+ }
+ }
+
+ var owned = false;
+
+ _style = function(s) { arguments.cascade(s); sync_(); }
+
+ _Enter = function() { sync_(); }
+ _Leave = function() { sync_(); }
+ _press = function() { owned = true; sync_(); }
+ _release = function() { owned = false; sync_(); }
+
+ var sync_ = function() {
+ if (mouseinside and owned) depth = "flat";
+ else if (mouseinside) depth = "up";
+ else depth = "up";
+ }
+
+ sync_();
+
+ </template>
+
+</ibex>
--- /dev/null
+<!-- Copyright 2002 NeuronForge Pty Ltd, see COPYING file for licensing [LGPL] -->
+<ibex>
+ A single-line or multi-line edit widget. Only handles text with one font and one color, and is capable of line or word wrapping.
+
+ TRAPS:
+
+ - multiline : boolean -- If true, edit widget will expand vertically to handle newlines.
+ - editable : boolean -- If true, the user can insert, paste and delete text.
+ - disabled : boolean -- If false, user can select text and copy to clipboard.
+ - wrap : string -- Either "none", "line" or "word", specifing the form of text wrap to use.
+ - selection : string -- Returns the currently selected text. Putting values does nothing, see FUNCTIONS, selectText().
+ - text : string -- Represents the complete text of this edit widget. Can be read and written to.
+ - limit : int -- A limit imposed on the total number of characters in the edit widget. 0 > limit means no limit.
+ - textcolor : color -- Color of the text.
+ - selectcolor : color -- Background Color of the currently selected text.
+ - selecttextcolor : color -- Color of the currently selected text.
+ - textChanged : boolean -- Set to true when the contents of the edit widget has changed.
+
+
+ FUNCTIONS:
+
+ If you wish to directly manipulate the contents of the edit widget consider using these functions to speed up manipulation.
+ All line references are based on hard carrige returns. You do not have to consider soft line wraps when making calculations.
+
+ - insertText(line, index, text) - Insert text at given char index on given line.
+ - deleteText(startline, startindex, endline, endindex) - Delete text in given range.
+ - selectText(startline, startindex, endline, endindex) - Select text in given range.
+ - clearSelection() - Deselect any current selection.
+ - deleteSelection() - Delete the text within the current selection range.
+ - moveCursor(line, index) - Move the cursor to the given position.
+
+
+ THEME NOTES:
+
+ - Most of the implementation of this widget does not need to be considered in a theme, however a particular theme may wish
+ to override _KeyPressed to add extra theme features (eg. Monopoly word skip on Ctrl+Left Arrow).
+
+
+ IMPLEMENTATION NOTES:
+
+ - In the implementation of the edit widget, there are two systems (loosely similar to model-view) used to reference text.
+
+ The first, referencing each 'hard' line (from one carrige return to the next) as a box inside $content
+ with the string property fulltext representing the contents of the row is used as the text model.
+ Text is inserted, removed and read using the $content[cl].fulltext properties.
+
+ The second is the on screen reprsentation of the text. Each $content[cl] box can have any number of children ( must be > 0)
+ called 'soft' lines. These softlines are created/managed at the discretion of the $content[cl]._fulltext trap. This means
+ different wrapping systems can be completely isolated inside the _fulltext trap. The only components of the system that
+ work outside of the model are cursor and selection positioning. The functions that manipulate these features have public
+ functions that mimic the 'model' style functions, but also have private internal functions that use cy and px variables
+ to reference location.
+
+ - A reference to each cursor is stored in the static area, and a global thread is used to call the _blink trap on cursors.
+
+ - Boxes are also stored in a static array when unused, however the effective value of this is questionable, and should be
+ properly benchmarked.
+
+ - If moving the cursor to a different cl line after changing the structure of the edit box, be sure to call the funciton from
+ a background thread. Otherwise, the position x,y values will be wrong.
+
+
+ TODO:
+ - keep length value up to date so limit checking works.
+ - insert key
+
+ <preapply name="org.ibex.builtin.edit_lib"/>
+
+ <template multiline="false" disabled="false" editable="true" wrap="none" font="sansserif"
+ selectcolor="blue" selecttextcolor="#FFFFFF" color="#FFFFFF" orient="vertical">
+
+ content = $content;
+ curs = $curs;
+ sel1 = $sel1;
+ sel2 = $sel2;
+
+ // Handles key events that occur in the surrounding whitespace.
+ $vspace._Press1 = function(v) { ref_press(content[content.numchildren -1]); }
+ $hspace._Press1 = function(v) {
+ for (var i=0; content.numchildren > i; i++) {
+ if (content[i].y + content[i].height >= content.mousey) { ref_press(content[i]); return; }
+ }
+ ref_press(content[content.numchildren -1]);
+ }
+
+ _focused = function(f) {
+ curs.focused = f; arguments.cascade(f); curs.blink = false;
+ if (!f) { clearSelection(); }
+ }
+
+ _disabled = function(d) { if (d) { cursor = "default"; } else { cursor = "text"; } }
+
+ _keypress = function(k) {
+ if (k == null || disabled) return;
+
+ var key = k.substring(k.lastIndexOf('-')+1).toLowerCase();
+
+ if (key.length == 1) {
+ if (ibex.control) {
+ if (key == 'a') {
+ selectText(0, 0, content.numchildren -1, content[content.numchildren -1].fulltext.length);
+ arguments.cascade(null);
+ } else if (key == 'x') {
+ ibex.clipboard = selection; deleteSelection();
+ arguments.cascade(null);
+ } else if (key == 'c') {
+ ibex.clipboard = selection;
+ arguments.cascade(null);
+ } else if (key == 'v') {
+ deleteSelection(); insertText(curs.cl, curs.cx, ibex.clipboard);
+ textChangd = true;
+ arguments.cascade(null);
+ } else {
+ arguments.cascade(k);
+ }
+ } else {
+ arguments.cascade(k);
+ }
+ } else if (key == "left") {
+ var cl, cx;
+
+ if (ibex.control) {
+ // Skip word algorithm. Ugly to look at.
+ cl = curs.cl; cx = curs.cx;
+
+ while (true) {
+ for (cx--; cx >= 0; cx--) { if (content[cl].fulltext.charAt(cx) != ' ') break; }
+ if (0 > cx) { if (cl > 0) { cl--; cx = content[cl].fulltext.length; } else { break; } }
+
+ findendchar: for (cx--; cx >= 0; cx--) {
+ switch (content[cl].fulltext.charAt(cx)) {
+ case ' ': break findendchar;
+ case '-': break findendchar;
+ }
+ }
+ cx++; break;
+ }
+ } else {
+ // Use right boundry of selection, otherwise use the cursor.
+ if (sel1.cl != -1) { cl = sel1.cl; cx = calcCx(cl, sel1.cy, sel1.px) -1; }
+ else { cl = curs.cl; cx = curs.cx -1; }
+ }
+
+ if (ibex.shift) { updateSelectionCx(cl, cx); }
+ else { clearSelection(); moveCursor(cl, cx); }
+ arguments.cascade(null);
+
+ } else if (key == "right") {
+ var cl, cx;
+
+ if (ibex.control) {
+ // Skip word algorithm. Ugly to look at.
+ cl = curs.cl; cx = curs.cx;
+
+ while (true) {
+ for (cx++; content[cl].fulltext.length > cx; cx++) { if (content[cl].fulltext.charAt(cx) != ' ') break; }
+ if (cx > content[cl].fulltext.length) { if (content.numchildren > cl) { cl++; cx = 0; } else { break; } }
+
+ findendchar: for (cx++; content[cl].fulltext.length > cx; cx++) {
+ switch (content[cl].fulltext.charAt(cx)) {
+ case ' ': break findendchar;
+ case '-': break findendchar;
+ }
+ }
+ break;
+ }
+ } else {
+ // Use right boundry of selection, otherwise use the cursor.
+ if (sel2.cl != -1) { cl = sel2.cl; cx = calcCx(cl, sel2.cy, sel2.px) +1; }
+ else { cl = curs.cl; cx = curs.cx +1; }
+ }
+
+ if (ibex.shift) { updateSelectionCx(cl, cx); }
+ else { clearSelection(); moveCursor(cl, cx); }
+ arguments.cascade(null);
+
+ } else if (key == "down") {
+ var cl, cy;
+ if (ibex.control) { cl = content.numchildren -1; cy = content[cl].numchildren -1; }
+ else { if (curs.cy == content[curs.cl].numchildren -1) { cl = curs.cl +1; cy = 0; } else { cl = curs.cl; cy = curs.cy + 1; } }
+
+ if (ibex.shift) { updateSelection(cl, cy, curs.px); }
+ else { var px = curs.px; clearSelection(); moveCursorToCy(cl, cy, px); }
+ arguments.cascade(null);
+
+ } else if (key == "up") {
+ var cl, cy;
+ if (ibex.control) { cl = 0; cy = content[0].numchildren -1; }
+ else {
+ if (curs.cy == 0) { if (curs.cl == 0) { cl=0; cy=0; } else { cl = curs.cl -1; cy = content[cl].numchildren -1; } }
+ else { cl = curs.cl; cy = curs.cy -1; }
+ }
+
+ if (ibex.shift) { updateSelection(cl, cy, curs.px); }
+ else { var px = curs.px; clearSelection(); moveCursorToCy(cl, cy, px); }
+ arguments.cascade(null);
+
+ } else if (key == "home") {
+ var cy;
+ if (ibex.control) { cy = 0; }
+ else { cy = curs.cy; }
+
+ if (ibex.shift) { updateSelection(curs.cl, cy, 0); }
+ else { var cl = curs.cl; clearSelection(); moveCursorToCy(cl, cy, 0); }
+ arguments.cascade(null);
+
+ } else if (key == "end") {
+ var cy;
+ if (ibex.control) { cy = content[curs.cl].numchildren -1; }
+ else { cy = curs.cy; }
+
+ if (ibex.shift) { updateSelection(curs.cl, cy, content[curs.cl][cy].text.length); }
+ else { var cl = curs.cl; clearSelection(); moveCursorToCy(cl, cy, content[cl][cy].text.length); }
+ arguments.cascade(null);
+
+ } else if (key == "insert") {
+ ibex.println("NOT YET IMPLEMENTED: insert key"); // TODO
+ arguments.cascade(null);
+ }
+ }
+
+ <box orient="horizontal">
+ <box id="content" hpad="0" vpad="0" align="topleft" orient="vertical" shrink="true"/>
+ <box id="hspace"/>
+ </box>
+ <box id="vspace"/>
+
+ <box absolute="true" id="sel1" cl="0" cy="0" px="0" shrink="true"/>
+ <box absolute="true" id="sel2" cl="0" cy="0" px="0" shrink="true"/>
+ <box absolute="true" id="curs" cl="0" cx="0" cy="0" px="0" width="1" blink="false" color="black">
+ _blink = function(v) { invisible = (focused and !disabled) ? v : true; }
+ </box>
+ </template>
+</ibex>
--- /dev/null
+<!-- Copyright 2002 NeuronForge Pty Ltd, see COPYING file for licensing [LGPL] -->
+<ibex>
+ <static>
+ var cursors = [];
+ var worddivider = [' ', '-'];
+
+ ibex.thread = function() {
+ while (true) { ibex.sleep(1000); for (var i=0; cursors.length > i; i++) { cursors[i].blink = !cursors[i].blink; } }
+ }
+
+ // Returns the number of characters the pixel position pos is into text t. end is the pixel with of t.
+ // t : string -- basis for character counting.
+ // pxpos : int -- pixel position on the text from string t.
+ // pxlen : int -- pixel width of text t (known in form of box length, so passed for speed).
+ // tfont : string -- name of font used for width of text.
+ var getpos = function(t, pxpos, pxlen, tfont) {
+ // Short circuit extremes.
+ if (0 >= pxpos) return 0;
+ if (pxpos >= pxlen) return t.length;
+
+ // Inital guess based on average character width.
+ var guessch = ibex.math.min(t.length, ibex.math.floor(pxpos / (pxlen / t.length)));
+ var guesspx = ibex.textwidth(tfont, t.substring(0, guessch));
+
+ if (guesspx > pxpos) {
+ while (guesspx > pxpos) {
+ // Textwidth of individual character must account for font kerning.
+ guesspx -= ibex.textwidth(tfont, t.substring(guessch -1, guessch +1)) - ibex.textwidth(tfont, t.charAt(guessch));
+ guessch--;
+ }
+ } else if (pxpos > guesspx) {
+ while (pxpos > guesspx) {
+ guessch++;
+ if (guessch >= t.length) break;
+ guesspx += ibex.textwidth(tfont, t.substring(guessch -1, guessch+1)) - ibex.textwidth(tfont, t.charAt(guessch));
+ }
+ guessch--; // Round down.
+ }
+
+ return guessch;
+ }
+ </static>
+
+
+ <template>
+ _multiline = function(v) {
+ if (!v) {
+ while (content.numchildren > 1) { reapLine(content[content.numchildren -1]); }
+ wrap = null;
+ }
+ }
+
+ _disabled = function(v) {
+ curs.disabled = v;
+ }
+
+ _editable = function(v) {
+ }
+
+ _wrap = function(v) {
+ // Used on _SizeChange if wrap needs to know.
+ var resize = function() {
+ ibex.thread = function() {
+ // TODO: Only run this change if the width is different.
+ for (var i = 0; content.numchildren > i; i++) { content[i].fulltext = content[i].fulltext; }
+ };
+ };
+
+ if (multiline and v == "line") {
+ content.vshrink = true;
+ content.hshrink = false;
+ content.maxwidth = ibex.maxdim; // Must reset maxwidth after shrink = true.
+ ref_fulltext = fulltext_linewrap;
+ _SizeChange = resize;
+
+ } else if (multiline and v == "word") {
+ content.vshrink = true;
+ content.hshrink = false;
+ content.maxwidth = ibex.maxdim;
+ ref_fulltext = fulltext_wordwrap;
+ _SizeChange = resize;
+
+ } else {
+ content.shrink = true;
+ ref_fulltext = fulltext_nowrap;
+ _SizeChange = null;
+ }
+
+ // Reset functions on current lines.
+ for (var i = 0; content.numchildren > i; i++) {
+ content[i]._fulltext = ref_fulltext;
+ content[i].fulltext = content[i].fulltext;
+ }
+ }
+
+ _selectcolor = function(v) { sel1.color = sel2.color = v; }
+ _selecttextcolor = function(v) { sel1.textcolor = sel2.textcolor = v; }
+
+ _font = function(f) {
+ lineheight = ibex.textheight(f);
+ if (lineheight > 0) { minheight = content.minheight = linecount * lineheight; }
+ for (var i=0; content.numchildren > i; i++) { content[i].font = f; }
+ sel1.font = sel2.font = curs.font = f;
+ }
+
+ __text = function(t) {
+ if (arguments.length == 0) {
+ var s = content[0].fulltext;
+ for (var i=1; content.numchildren > i; i++) { s = s + '\n' + content[i].fulltext; }
+ return s;
+ }
+
+ deleteText(0, 0, content.numchildren - 1, content[content.numchildren - 1].fulltext.length);
+ insertText(0, 0, t);
+ }
+
+ __selection = function(t) {
+ if (arguments.length == 0) {
+ if (sel1.cl == -1) return "";
+
+ var s = sel1.text;
+
+ if (sel1.cl == sel2.cl) {
+ for (var i=sel1.cy+1; sel2.cy > i; i++) { s += content[sel1.cl][i].text; }
+ } else {
+ for (var i=sel1.cy+1; content[sel1.cl].numchildren > i; i++) { s += content[sel1.cl][i].text; }
+ for (var i=sel1.cl+1; sel2.cl > i; i++) { s += '\n' + content[i].fulltext; }
+ s += '\n';
+ for (var i=0; sel2.cy > i; i++) { s += content[sel2.cl][i].text; }
+ s += sel2.text;
+ }
+
+ return s;
+ }
+
+ deleteSelection();
+ insertText(curs.cl, curs.cx, t);
+ }
+
+
+ // PRIVATE VARIABLES //////////////////////////////////////////////////////////////////////////////////////////
+
+ // Stores the inital point of the current selection.
+ var sel = { cl : 0, cy : 0, px : 0 };
+
+ // The pixel height of the current font.
+ var _lineheight = function(l) { curs.height = sel1.height = sel2.height = l; }
+
+ // Number of soft lines currently in this edit widget. Controlled by newLine() and reapLine().
+ var _linecount = function(l) {
+ arguments.cascade(l); if (l == 0) l = 1;
+ if (lineheight > 0) { minheight = content.minheight = l * lineheight; }
+ }
+
+ // Total number of characters stored in this text field.
+ var length = 0;
+
+
+ // PUBLIC FUNCTIONS //////////////////////////////////////////////////////////////////////////////////////////
+
+ // Insert the given text at the given position.
+ insertText = function(cl, cx, t) {
+ // Check passed string.
+ if (t == null || 1 > t.length) return;
+ t = t.toString();
+
+ // Limit checking.
+ if (limit > 0 and length + t.length > limit) {
+ ibex.println("WARNING: Limit applied on inserted text.");
+ t = t.substring(0, limit - length);
+ }
+
+ // Make sure there are enough lines before hand.
+ for (var i=content.numchildren; cl >= i; i++) { content[i] = newLine(); }
+
+ // Parse the carridge returns out of t.
+ var newT = t.split("\n");
+
+ if (newT.length == 0) {
+ return;
+ } else if (newT.length == 1) {
+ content[cl].fulltext = content[cl].fulltext.substring(0, cx) + t + content[cl].fulltext.substring(cx);
+ length += t.length;
+
+ moveCursor(cl, cx+t.length);
+ } else {
+ if (multiline) {
+ // Add extra lines required by passed text.
+ for (var i = newT.length - 1; i > 0; i--) { content[cl+1] = newLine(); }
+
+ // Add the new text
+ var lastline = newT[newT.length - 1] + content[cl].fulltext.substring(cx);
+ content[cl].fulltext = content[cl].fulltext.substring(0, cx) + newT[0];
+ for (var i=1; newT.length-1 > i; i++) { content[cl+i].fulltext = newT[i]; }
+ content[cl + newT.length - 1].fulltext = lastline;
+
+ moveCursor(cl + newT.length - 1, newT[newT.length -1].length);
+ } else {
+ ibex.println("WARNING: Single line edit, ignoring all text after the carrige return.");
+ content[0].fulltext = content[0].fulltext.substring(0, cx) + newT[0] + content[0].fulltext.substring(cx);
+
+ moveCursor(0, cx + newT[0].length);
+ }
+ }
+ }
+
+ // Delete the text within the given range.
+ deleteText = function(cl1, cx1, cl2, cx2) {
+ content[cl1].fulltext = content[cl1].fulltext.substring(0, cx1) + content[cl2].fulltext.substring(cx2);
+ for (; cl2 > cl1; cl2--) { reapLine(content[cl2]); }
+ }
+
+ // Select the text within the given range.
+ selectText = function(cl1, cx1, cl2, cx2) {
+ // Find cy1 and px1.
+ var cy1 = 0;
+ var px1 = cx1;
+ for (; content[cl1].numchildren > cy1; cy1++) {
+ if (content[cl1][cy1].text.length > px1) { break; }
+ else { px1 -= content[cl1][cy1].text.length; }
+ }
+
+ // Find cy2 and px2.
+ var cy2 = 0;
+ var px2 = cx2;
+ for (; content[cl2].numchildren > cy2; cy2++) {
+ if (content[cl2][cy2].text.length >= px2) { break; }
+ else { px2 -= content[cl2][cy2].text.length; }
+ }
+
+ // Call the internal select function.
+ sel.cl = cl1; sel.cy = cy1; sel.px = px1;
+ select(cl1, cy1, px1, cl2, cy2, px2);
+ moveCursorToCy(cl2, cy2, px2);
+ }
+
+ // Clear the current selection.
+ clearSelection = function() {
+ if (sel.cl == -1 || sel1.cl == -1) return;
+ moveCursorToCy(sel1.cl, sel1.cy, sel1.px);
+
+ // Clear any selected lines.
+ for (var i=sel1.cl; sel2.cl >= i; i++) { if (content[i] != null) content[i].selected = false; }
+
+ // Clear the selection values
+ sel.cl = sel.px = sel.cy = sel1.cl = sel1.cx = sel1.cy = sel2.cl = sel2.cx = sel2.cy = -1;
+ sel1.text = sel2.text = "";
+ }
+
+ // Delete the text currently within the selected range.
+ deleteSelection = function() {
+ if (sel1.cl == -1 || sel2.cl == -1) return;
+ deleteText(sel1.cl, calcCx(sel1.cl, sel1.cy, sel1.px), sel2.cl, calcCx(sel2.cl, sel2.cy, sel2.px));
+ clearSelection();
+ }
+
+ // External interface for moving the mouse cursor.
+ moveCursor = function(cl, cx) {
+ // Work out what subline cx is on.
+ var cy, px;
+
+ if (cl >= content.numchildren) return;
+
+ if (cx > content[cl].fulltext.length) {
+ if (content.numchildren -1 > cl) {
+ cl++; cx = 0; cy = 0; px = 0;
+ } else {
+ cx = content[cl].fulltext.length;
+ cy = content[cl].numchildren -1;
+ px = content[cl][cy].text.length;
+ }
+ } else {
+ px = cx;
+
+ for (cy = 0; content[cl].numchildren > cy; cy++) {
+ if (content[cl][cy].text.length >= px) break;
+ px -= content[cl][cy].text.length;
+ }
+ }
+
+ // Call internal move function.
+ moveCursorToPos(cl, cx, cy, px);
+ }
+
+
+ // PRIVATE FUNCTIONS //////////////////////////////////////////////////////////////////////////////////////////
+
+ var updateSelectionCx = function(cl, cx) {
+ if (cl >= content.numchildren) {
+ var t = content[content.numchildren -1];
+ updateSelection(content.numchildren -1, t.numchildren, t[t.numchildren -1].text.length);
+ return;
+ } else if (cx > content[cl].fulltext.length) {
+ updateSelection(cl, content[cl].numchildren -1, content[cl][content[cl].numchildren -1].text.length);
+ return;
+ }
+
+ var cy;
+ for (cy = 0; cx > 0; cy++) {
+ cx -= content[cl][cy].text.length;
+ }
+ cy--;
+
+ updateSelection(cl, cy, content[cl][cy].text.length + cx);
+ }
+
+ // Used in the _KeyPress trap to literally update a current selection. The new 'floating point' is passed, and
+ // the original value stored in the private property sel is used to balance with.
+ var updateSelection = function(cl, cy, px) {
+ // Very very very padentic checking. I dare you to do more checking. :-)
+ if (0 > px || 0 > cy || 0 > cl) {
+ if (cy - 1 >= 0) { cy--; px = content[cl][cy].text.length; }
+ else if (cl - 1 >= 0) { cl--; cy = content[cl].numchildren - 1; px = content[cl][cy].text.length; }
+ else { cl = 0; cy = 0; px = 0; }
+ } else if (cl >= content.numchildren) {
+ cl = content.numchildren - 1;
+ cy = content[cl].numchildren - 1;
+ px = content[cl][cy].text.length;
+ } else if (cy >= content[cl].numchildren || px > content[cl][cy].text.length) {
+ if (content[cl].numchildren > cy + 1) { cy++; px = 0; }
+ else if (content.numchildren > cl + 1) { cl++; cy = 0; px = 0; }
+ else { cl = content.numchildren - 1; cy = content[cl].numchildren - 1; px = content[cl][cy].text.length; }
+ }
+
+ // If there is no current selection, set to current mouse position.
+ if (sel.cl == -1) { sel.cl = curs.cl; sel.cy = curs.cy; sel.px = curs.px; }
+
+ // Decide on dominant point and call internal select function.
+ if (cl > sel.cl || (cl == sel.cl and cy > sel.cy) || (cl == sel.cl and cy == sel.cy and px > sel.px)) {
+ select(sel.cl, sel.cy, sel.px, cl, cy, px);
+ } else {
+ select(cl, cy, px, sel.cl, sel.cy, sel.px);
+ }
+
+ // Update cursor position.
+ moveCursorToCy(cl, cy, px);
+ }
+
+ // The meat behind all select calls. This function draws the select boxes on top of the edit widget.
+ var select = function(cl1, cy1, px1, cl2, cy2, px2) {
+ if (disabled) return;
+
+ // Deselect the current full-selection lines that are outside the new selection area.
+ if (sel1.cl == cl1) {
+ for (var i=sel1.cy+1; cy1 >= i; i++) { content[cl1][i].selected = false; }
+ } else if (cl1 > sel1.cl) {
+ for (var i=ibex.math.max(0, sel1.cl); cl1 >= i; i++) { content[i].selected = false; }
+ }
+ if (sel2.cl == cl2) {
+ for (var i=sel2.cy-1; i >= cy2; i--) { content[cl2][i].selected = false; }
+ } else if (sel2.cl > cl2) {
+ for (var i=ibex.math.max(0, sel2.cl); i >= cl2; i--) { content[i].selected = false; }
+ }
+
+ // Store point data.
+ sel1.cl = cl1; sel1.cy = cy1; sel1.px = px1;
+ sel2.cl = cl2; sel2.cy = cy2; sel2.px = px2;
+
+ // Place first select box.
+ sel1.y = content[cl1].y + content[cl1][cy1].y;
+ sel1.x = ibex.textwidth(font, content[cl1][cy1].text.substring(0, px1));
+
+ if (cl1 == cl2 and cy1 == cy2) {
+ // Only the first select box is required.
+ sel1.text = content[cl1][cy1].text.substring(px1, px2);
+ sel2.text = "";
+ } else {
+ sel1.text = content[cl1][cy1].text.substring(px1);
+ sel2.y = content[cl2].y + content[cl2][cy2].y;
+ sel2.x = 0;
+ sel2.text = content[cl2][cy2].text.substring(0, px2);
+
+ // Mark middle lines.
+ if (cl1 == cl2) {
+ for (var i=cy1+1; cy2 > i; i++) { content[cl1][i].selected = true; }
+ } else {
+ for (var i=cy1+1; content[cl1].numchildren > i; i++) { content[cl1][i].selected = true; }
+ for (var i=cl1+1; cl2 > i; i++) { content[i].selected = true; }
+ for (var i=0; cy2 > i; i++) { content[cl2][i].selected = true; }
+ }
+ }
+ }
+
+ // Internal reference function. Calculates the cx position of the cursor based on cl, cy and px,
+ // and then passes it to the primary internal function moveCursorToPos() for movement.
+ var moveCursorToCy = function(cl, cy, px) { moveCursorToPos(cl, calcCx(cl, cy, px), cy, px); }
+
+ var calcCx = function(cl, cy, px) { for (cy--; cy >= 0; cy--) { px += content[cl][cy].text.length; } return px; }
+
+ // Internal function for moving the mouse cursor. px represents number of characters over in specified subline.
+ // NOTE: The mouse cursor is the closest the external functions get to affecting the internal structure of a line.
+ var moveCursorToPos = function(cl, cx, cy, px) {
+ // Check the passed values are within reasonable constaints.
+ if (cl >= content.numchildren) { cl = content.numchildren - 1; }
+ if (cy >= content[cl].numchildren) {
+ if (content.numchildren - 1 > cl) { cl++; cy = 0; cx = calcCx(cl, cy, px); }
+ else { cy = content[cl].numchildren -1; cx = calcCx(cl, cy, px); }
+ } else if (0 > cy) {
+ if (cl > 0) { cl--; cy = content[cl].numchildren - 1; cx = calcCx(cl, cy, px); }
+ else { cy = 0; cx = calcCx(cl, cy, px); }
+ }
+ if (0 > px) { px = 0; cx = calcCx(cl, cy, px); }
+ else if (px > content[cl][cy].text.length) { px = content[cl][cy].text.length; cx = calcCx(cl, cy, px); }
+
+ // Move the cursor.
+ curs.cl = cl; curs.cx = cx; curs.cy = cy; curs.px = px;
+ curs.y = content.y + content[cl].y + (lineheight * cy);
+ curs.x = content.x + ibex.textwidth(font, content[cl][cy].text.substring(0, px)) -1;
+ curs.blink = false;
+
+ // Speed Hack: As the cursor has values that match the names used by the focusarea variable, we
+ // simply pass the curs reference as the focusarea.
+ focusarea = curs;
+
+ if (0 > curs.x) curs.x = 0;
+ }
+
+ // Returns a box ready to be a full line, armed with the current fulltext trap.
+ var newLine = function() {
+ var b = ibex.newBox();
+
+ b.color = color;
+ b.align = "topleft";
+ b.invisible = false;
+
+ b[0] = newSoftline();
+ b._Press1 = function() { ref_press(arguments.trapee); }
+ b._selected = function(s) { for (var i=0; b.numchildren > i; i++) { b[i].selected = s; } }
+ b._font = function(f) { for (var i=0; b.numchildren > i; i++) { b[i].font = f; } }
+ b._fulltext = ref_fulltext;
+ b.fulltext = "";
+ b.orient = "vertical";
+ b.vshrink = true;
+
+ return b;
+ }
+
+ // Returns a box ready to be a soft line; one of the components of a line.
+ var newSoftline = function() {
+ var b = ibex.newBox();
+
+ b._selected = function(s) {
+ arguments.trapee.color = s ? selectcolor : color;
+ arguments.trapee.textcolor = s ? selecttextcolor : textcolor;
+ };
+ b.minheight = lineheight;
+ b.shrink = true;
+ b.color = color;
+ b.textcolor = textcolor;
+ b.font = font;
+ b.align = "topleft";
+ b.invisible = false;
+
+ linecount++;
+
+ return b;
+ }
+
+ // Takes the given line and strips it of traps and returns it to the static stack.
+ var reapLine = function(toReap) {
+ if (content.indexof(toReap) == -1) {
+ // Soft-line
+ linecount--;
+ } else {
+ // Hard-line, count all softline children.
+ linecount -= toReap.numchildren;
+ }
+
+ toReap.thisbox = null;
+ }
+
+
+ // SUBLINE FUNCTIONS //////////////////////////////////////////////
+
+ var fulltext_nowrap = function(t) {
+ arguments.trapee[0].text = t;
+ }
+ var fulltext_linewrap = function(t) {
+ var cw = width;
+
+ if (cw == 0) return;
+
+ var i = 0;
+ if (t.length == 0) arguments.trapee[0].text = "";
+
+ for (; t.length > 0; i++) {
+ if (i == arguments.trapee.numchildren) { arguments.trapee[i] = newSoftline(); }
+
+ // TODO: Switch to getpos
+ var nl = static.getpos(t, cw, ibex.textwidth(font, t), font);
+ arguments.trapee[i].text = t.substring(0, nl);
+ t = t.substring(nl);
+ }
+
+ // Remove any excess lines.
+ if (i == 0) i++;
+ while (arguments.trapee.numchildren > i) { reapLine(arguments.trapee[i]); }
+ }
+ var fulltext_wordwrap = function(t) {
+ var cw = width;
+
+ if (cw == 0) return;
+
+ var i = 0;
+ if (t.length == 0) arguments.trapee[0].text = "";
+
+ for (; t.length > 0; i++) {
+ if (i == arguments.trapee.numchildren) { arguments.trapee[i] = newSoftline(); }
+
+ var nl = static.getpos(t, cw, ibex.textwidth(font, t), font);
+
+ var rl = nl;
+ if (t.length > nl) {
+ // TODO: Clean up, make it work off a static array of possible break points.
+ // TODO: Make it themeable as well.
+ for (; rl > 0; rl--) {
+ if (t.charAt(rl) == ' ' || t.charAt(rl) == '-') { rl++; break; }
+ }
+ if (0 >= rl || rl > nl) rl = nl;
+ }
+
+ arguments.trapee[i].text = t.substring(0, rl);
+ t = t.substring(rl);
+ }
+
+ // Remove any excess lines.
+ if (i == 0) i++;
+ while (arguments.trapee.numchildren > i) { reapLine(arguments.trapee[i]); }
+ }
+
+ // Reference to the current function to use for the fulltext trap.
+ var ref_fulltext = fulltext_nowrap;
+
+ // Handles selection/cursor movement from mouse events.
+ // The passed value is a reference to the selected hard line.
+ var ref_press = function(refline) {
+ if (disabled) return;
+
+ root._Move = function() {
+ // Update Selection.
+ var linediff = ibex.math.floor((content.mousey - (content[sel.cl].y + content[sel.cl][sel.cy].y)) / lineheight);
+
+ var cl = sel.cl;
+ var cy = sel.cy;
+
+ // End of selection comes after start.
+ while (linediff > 0) {
+ cy++;
+ if (cy >= content[cl].numchildren) { cl++; cy = 0; }
+ if (cl >= content.numchildren) { cl--; break; }
+ linediff--;
+ }
+
+ // End of selection comes before start.
+ while (0 > linediff) {
+ cy--;
+ if (0 > cy) { cl--; cy = content[cl].numchildren -1; }
+ if (0 > cl) { cl=0; cy = 0; break; }
+ linediff++;
+ }
+
+ var px = static.getpos(content[cl][cy].text, content[cl][cy].mousex, content[cl][cy].width, font);
+
+ updateSelection(cl, cy, px);
+ }
+
+ root._Release1 = function() {
+ root._Move = root._Release1 = null;
+ // TODO: Put selection to clipboard.
+ }
+
+ // Set selection root position.
+ clearSelection();
+ sel.cl = content.indexof(refline);
+ sel.cy = ibex.math.floor(refline.mousey / lineheight);
+
+ if (sel.cy >= refline.numchildren) sel.cy = refline.numchildren -1;
+ else if (0 > sel.cy) sel.cy = 0;
+
+ sel.px = static.getpos(refline[sel.cy].text, refline[sel.cy].mousex, refline[sel.cy].width, font);
+
+ moveCursorToCy(sel.cl, sel.cy, sel.px);
+ }
+
+
+ // HELPER FUNCTIONS //////////////////////////////////////////////
+
+ // Nessesary for when a used clicks in the middle of a current selection.
+ _sel1 = _sel2 = function(s) {
+ if (s != null) {
+ s._Press1 = function(t) { if (arguments.trapee.cl >= 0) content[arguments.trapee.cl].Press1 = t; };
+ s._Release1 = function(t) { if (arguments.trapee.cl >= 0) content[arguments.trapee.cl].Release1 = t; };
+ }
+ }
+
+ _content = function(c) { if (c != null and c.numchildren == 0) c[0] = newLine(); }
+
+ _curs = function(c) {
+ if (c == null) {
+ for (var i=0; static.cursors.length > i; i++) {
+ if (static.cursors[i] == arguments.cascade()) { static.cursors[i] = null; break; }
+ }
+ } else {
+ // Add cursor to static array for 'blinking'.
+ static.cursors[static.cursors.length] = c;
+ }
+ }
+
+ key_enter = function() {
+ if (!multiline) return;
+ content[curs.cl +1] = newLine();
+ content[curs.cl +1].fulltext = content[curs.cl].fulltext.substring(curs.cx);
+ content[curs.cl].fulltext = content[curs.cl].fulltext.substring(0, curs.cx);
+ ibex.thread = function() { moveCursor(curs.cl +1, 0); }
+ }
+
+ key_back_space = function() {
+ if (curs.cx == 0) {
+ if (curs.cl > 0) {
+ var px = content[curs.cl -1].fulltext.length;
+ content[curs.cl -1].fulltext = content[curs.cl -1].fulltext + content[curs.cl].fulltext;
+ reapLine(content[curs.cl]);
+ moveCursor(curs.cl -1, px); // Safe, moving up not down.
+ }
+ } else {
+ content[curs.cl].fulltext = content[curs.cl].fulltext.substring(0, curs.cx -1) + content[curs.cl].fulltext.substring(curs.cx);
+ moveCursor(curs.cl, curs.cx -1); // Safe, not moving cl.
+ }
+ }
+
+ key_delete = function() {
+ if (curs.cx == content[curs.cl].fulltext.length) {
+ if (content.numchildren > 1) {
+ content[curs.cl].fulltext = content[curs.cl].fulltext + content[curs.cl +1].fulltext;
+ reapLine(content[curs.cl +1]);
+ }
+ } else {
+ content[curs.cl].fulltext = content[curs.cl].fulltext.substring(0, curs.cx) + content[curs.cl].fulltext.substring(curs.cx +1);
+ }
+ }
+
+ // KEY HANDLER //////////////////////////////////////////////
+ _keypress = function(k) {
+ if (k == null || !editable || disabled) return;
+
+ // Process shortcut for single character entries.
+ if (k.length == 1) {
+ deleteSelection();
+
+ if (k.charAt(0) == '\n') {
+ insertText(curs.cl, curs.cx, k);
+ } else {
+ content[curs.cl].fulltext = content[curs.cl].fulltext.substring(0, curs.cx)
+ + k + content[curs.cl].fulltext.substring(curs.cx);
+ ibex.thread = function() { moveCursor(curs.cl, curs.cx+1); }
+ textChanged = true;
+ }
+
+ return;
+ }
+
+ k = k.substring(k.lastIndexOf('-')+1);
+
+ // Process movement commands.
+ if (k == "enter") {
+ deleteSelection(); key_enter();
+ textChanged = true;
+ } else if (k == "back_space") {
+ if (sel1.cl > -1) { deleteSelection(); }
+ else { key_back_space(); }
+ textChanged = true;
+ } else if (k == "delete") {
+ if (sel1.cl > -1) { deleteSelection(); }
+ else { key_delete(); }
+ textChanged = true;
+ }
+ }
+
+ </template>
+</ibex>
--- /dev/null
+<ibex>
+
+ <import name="org.ibex.builtin.*"/>
+ <template thisbox="frame" minwidth="397" maxwidth="397" minheight="243" maxheight="243"
+ vpad="20" hpad="10" titlebar="Enter Network Password">
+
+ _KeyPressed = function(k) {
+ if (k == "tab") {
+ if ($password.focused) $user.focused = true;
+ else $password.focused = true;
+ } else if (k == "enter") {
+ $ok.click = true;
+ }
+ }
+
+ $cancel._click = function() { thisbox = null; }
+
+ $user._focused = function(f) {
+ ibex.println("user.focused = " + f);
+ if (f) $password.focused = false;
+ }
+
+ $password._focused = function(f) {
+ ibex.println("password.focused = " + f);
+ if (f) $user.focused = false;
+ }
+
+ _proxyIP = function(p) { $firewall.text = p; }
+ _realm = function(r) { $realm.text = r; }
+ $user._SizeChange = function() { $password.height = $user.height; }
+
+ $ok._click = function() {
+ ibex.proxyAuthorization = $user.text + ":" + $password.text;
+ thisbox = null;
+ }
+
+ <box hshrink="true">
+ <box width="10"/>
+ <box>
+ <box sizetoimage="true" image="key" align="topleft"/>
+ </box>
+ <box width="10"/>
+ </box>
+
+ <box orient="vertical">
+ <box font="dialog8" text="Please type your user name and password." vshrink="true"/>
+ <box height="13"/>
+ <box>
+ <box width="75" font="dialog8" text="Firewall:" vshrink="true"/>
+ <box vshrink="true" font="dialog8" text="unknown" id="firewall"/>
+ </box>
+ <box height="13"/>
+ <box>
+ <box width="75" font="dialog8" text="Realm" vshrink="true"/>
+ <box vshrink="true" font="dialog8" text="unknown" id="realm"/>
+ </box>
+ <box height="22"/>
+ <box>
+ <box width="75" font="dialog8" text="User Name" vshrink="true"/>
+ <box border="bevel_2_down" hpad="2" vpad="2">
+ <edit color="white" id="user" focused="true"/>
+ </box>
+ </box>
+ <box height="10"/>
+ <box>
+ <box width="75" font="dialog8" text="Password" vshrink="true"/>
+ <box border="bevel_2_down" hpad="2" vpad="2">
+ <edit color="white" id="password" font="org.ibex.builtin.password12" focused="false"/>
+ </box>
+ </box>
+ <box height="30"/>
+ <box>
+ <box/>
+ <button width="75" height="24" id="ok">
+ <box font="dialog8" text="OK" shrink="true"/>
+ </button>
+ <box width="20"/>
+ <button width="75" height="24" id="cancel">
+ <box font="dialog8" text="Cancel" shrink="true"/>
+ </button>
+ </box>
+ <box/>
+ </box>
+
+ </template>
+
+</ibex>
--- /dev/null
+// FIXME
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.graphics;
+import java.util.*;
+
+/** an affine transform; all operations are destructive */
+public final class Affine {
+
+ // [ a b e ]
+ // [ c d f ]
+ // [ 0 0 1 ]
+ public float a, b, c, d, e, f;
+
+ Affine(float _a, float _b, float _c, float _d, float _e, float _f) { a = _a; b = _b; c = _c; d = _d; e = _e; f = _f; }
+ public String toString() { return "[ " + a + ", " + b + ", " + c + ", " + d + ", " + e + ", " + f + " ]"; }
+ public Affine copy() { return new Affine(a, b, c, d, e, f); }
+ public static Affine identity() { return new Affine(1, 0, 0, 1, 0, 0); }
+ public static Affine scale(float sx, float sy) { return new Affine(sx, 0, 0, sy, 0, 0); }
+ public static Affine shear(float degrees) {
+ return new Affine(1, 0, (float)Math.tan(degrees * (float)(Math.PI / 180.0)), 1, 0, 0); }
+ public static Affine translate(float tx, float ty) { return new Affine(1, 0, 0, 1, tx, ty); }
+ public static Affine flip(boolean horiz, boolean vert) { return new Affine(horiz ? -1 : 1, 0, 0, vert ? -1 : 1, 0, 0); }
+ public float multiply_px(float x, float y) { return x * a + y * c + e; }
+ public float multiply_py(float x, float y) { return x * b + y * d + f; }
+ public boolean equalsIgnoringTranslation(Affine x) { return a == x.a && b == x.b && c == x.c && d == x.d; }
+
+ public boolean equals(Object o) {
+ if (!(o instanceof Affine)) return false;
+ Affine x = (Affine)o;
+ return a == x.a && b == x.b && c == x.c && d == x.d && e == x.e && f == x.f;
+ }
+
+ public static Affine rotate(float degrees) {
+ float s = (float)Math.sin(degrees * (float)(Math.PI / 180.0));
+ float c = (float)Math.cos(degrees * (float)(Math.PI / 180.0));
+ return new Affine(c, s, -s, c, 0, 0);
+ }
+
+ /** this = this * a */
+ public Affine multiply(Affine A) {
+ float _a = this.a * A.a + this.b * A.c;
+ float _b = this.a * A.b + this.b * A.d;
+ float _c = this.c * A.a + this.d * A.c;
+ float _d = this.c * A.b + this.d * A.d;
+ float _e = this.e * A.a + this.f * A.c + A.e;
+ float _f = this.e * A.b + this.f * A.d + A.f;
+ a = _a; b = _b; c = _c; d = _d; e = _e; f = _f;
+ return this;
+ }
+
+ /** this = a * this */
+ public Affine premultiply(Affine A) {
+ float _a = A.a * this.a + A.b * this.c;
+ float _b = A.a * this.b + A.b * this.d;
+ float _c = A.c * this.a + A.d * this.c;
+ float _d = A.c * this.b + A.d * this.d;
+ float _e = A.e * this.a + A.f * this.c + this.e;
+ float _f = A.e * this.b + A.f * this.d + this.f;
+ a = _a; b = _b; c = _c; d = _d; e = _e; f = _f;
+ return this;
+ }
+
+ public void invert() {
+ float det = 1 / (a * d - b * c);
+ float _a = d * det;
+ float _b = -1 * b * det;
+ float _c = -1 * c * det;
+ float _d = a * det;
+ float _e = -1 * e * a - f * c;
+ float _f = -1 * e * b - f * d;
+ a = _a; b = _b; c = _c; d = _d; e = _e; f = _f;
+ }
+
+ public static Affine parse(String t) {
+ if (t == null) return null;
+ t = t.trim();
+ Affine ret = Affine.identity();
+ while (t.length() > 0) {
+ if (t.startsWith("skewX(")) {
+ // FIXME
+
+ } else if (t.startsWith("shear(")) {
+ // FIXME: nonstandard; remove this
+ ret.multiply(Affine.shear(Float.parseFloat(t.substring(t.indexOf('(') + 1, t.indexOf(')')))));
+
+ } else if (t.startsWith("skewY(")) {
+ // FIXME
+
+ } else if (t.startsWith("rotate(")) {
+ String sub = t.substring(t.indexOf('(') + 1, t.indexOf(')'));
+ if (sub.indexOf(',') != -1) {
+ float angle = Float.parseFloat(sub.substring(0, sub.indexOf(',')));
+ sub = sub.substring(sub.indexOf(',') + 1);
+ float cx = Float.parseFloat(sub.substring(0, sub.indexOf(',')));
+ sub = sub.substring(sub.indexOf(',') + 1);
+ float cy = Float.parseFloat(sub);
+ ret.multiply(Affine.translate(cx, cy));
+ ret.multiply(Affine.rotate(angle));
+ ret.multiply(Affine.translate(-1 * cx, -1 * cy));
+ } else {
+ ret.multiply(Affine.rotate(Float.parseFloat(t.substring(t.indexOf('(') + 1, t.indexOf(')')))));
+ }
+
+ } else if (t.startsWith("translate(")) {
+ String sub = t.substring(t.indexOf('(') + 1, t.indexOf(')'));
+ if (sub.indexOf(',') > -1) {
+ ret.multiply(Affine.translate(Float.parseFloat(t.substring(t.indexOf('(') + 1, t.indexOf(','))),
+ Float.parseFloat(t.substring(t.indexOf(',') + 1, t.indexOf(')')))));
+ } else {
+ ret.multiply(Affine.translate(Float.parseFloat(t.substring(t.indexOf('(') + 1, t.indexOf(','))), 0));
+ }
+
+ } else if (t.startsWith("flip(")) {
+ String which = t.substring(t.indexOf('(') + 1, t.indexOf(')'));
+ ret.multiply(Affine.flip(which.equals("horizontal"), which.equals("vertical")));
+
+ } else if (t.startsWith("scale(")) {
+ String sub = t.substring(t.indexOf('(') + 1, t.indexOf(')'));
+ if (sub.indexOf(',') > -1) {
+ ret.multiply(Affine.scale(Float.parseFloat(t.substring(t.indexOf('(') + 1, t.indexOf(','))),
+ Float.parseFloat(t.substring(t.indexOf(',') + 1, t.indexOf(')')))));
+ } else {
+ ret.multiply(Affine.scale(Float.parseFloat(t.substring(t.indexOf('(') + 1, t.indexOf(','))),
+ Float.parseFloat(t.substring(t.indexOf('(') + 1, t.indexOf(',')))));
+ }
+
+ } else if (t.startsWith("matrix(")) {
+ // FIXME: is this mapped right?
+ float d[] = new float[6];
+ StringTokenizer st = new StringTokenizer(t, ",", false);
+ for(int i=0; i<6; i++)
+ d[i] = Float.parseFloat(st.nextToken());
+ ret.multiply(new Affine(d[0], d[1], d[2], d[3], d[4], d[5]));
+ }
+ t = t.substring(t.indexOf(')') + 1).trim();
+ }
+ return ret;
+ }
+
+}
--- /dev/null
+// Copyright 2002 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.graphics;
+import java.util.*;
+import org.ibex.util.*;
+
+public class Color {
+
+ public static int stringToColor(String s) {
+ // FIXME support three-char strings by doubling digits
+ if (s == null) return 0x00000000;
+ else if (standard.get(s) != null) return 0xFF000000 | org.ibex.js.JS.toInt(standard.get(s));
+ else if (s.length() == 7 && s.charAt(0) == '#') try {
+ // FEATURE alpha
+ return 0xFF000000 |
+ (Integer.parseInt(s.substring(1, 3), 16) << 16) |
+ (Integer.parseInt(s.substring(3, 5), 16) << 8) |
+ Integer.parseInt(s.substring(5, 7), 16);
+ } catch (NumberFormatException e) {
+ Log.info(Color.class, "invalid color " + s);
+ return 0;
+ }
+ else return 0; // FEATURE: error?
+ }
+
+ public static String colorToString(int argb) {
+ if ((argb & 0xFF000000) == 0) return null;
+ String red = Integer.toHexString((argb & 0x00FF0000) >> 16);
+ String green = Integer.toHexString((argb & 0x0000FF00) >> 8);
+ String blue = Integer.toHexString(argb & 0x000000FF);
+ if (red.length() < 2) red = "0" + red;
+ if (blue.length() < 2) blue = "0" + blue;
+ if (green.length() < 2) green = "0" + green;
+ return "#" + red + green + blue;
+ }
+
+ /** Copied verbatim from the SVG specification */
+ private static Hashtable standard = new Hashtable(400);
+ static {
+ standard.put("aliceblue", new Integer((240 << 16) | (248 << 8) | 255));
+ standard.put("antiquewhite", new Integer((250 << 16) | (235 << 8) | 215));
+ standard.put("aqua", new Integer((0 << 16) | (255 << 8) | 255));
+ standard.put("aquamarine", new Integer((127 << 16) | (255 << 8) | 212));
+ standard.put("azure", new Integer((240 << 16) | (255 << 8) | 255));
+ standard.put("beige", new Integer((245 << 16) | (245 << 8) | 220));
+ standard.put("bisque", new Integer((255 << 16) | (228 << 8) | 196));
+ standard.put("black", new Integer((0 << 16) | (0 << 8) | 0));
+ standard.put("blanchedalmond", new Integer((255 << 16) | (235 << 8) | 205));
+ standard.put("blue", new Integer((0 << 16) | (0 << 8) | 255));
+ standard.put("blueviolet", new Integer((138 << 16) | (43 << 8) | 226));
+ standard.put("brown", new Integer((165 << 16) | (42 << 8) | 42));
+ standard.put("burlywood", new Integer((222 << 16) | (184 << 8) | 135));
+ standard.put("cadetblue", new Integer((95 << 16) | (158 << 8) | 160));
+ standard.put("chartreuse", new Integer((127 << 16) | (255 << 8) | 0));
+ standard.put("chocolate", new Integer((210 << 16) | (105 << 8) | 30));
+ standard.put("coral", new Integer((255 << 16) | (127 << 8) | 80));
+ standard.put("cornflowerblue", new Integer((100 << 16) | (149 << 8) | 237));
+ standard.put("cornsilk", new Integer((255 << 16) | (248 << 8) | 220));
+ standard.put("crimson", new Integer((220 << 16) | (20 << 8) | 60));
+ standard.put("cyan", new Integer((0 << 16) | (255 << 8) | 255));
+ standard.put("darkblue", new Integer((0 << 16) | (0 << 8) | 139));
+ standard.put("darkcyan", new Integer((0 << 16) | (139 << 8) | 139));
+ standard.put("darkgoldenrod", new Integer((184 << 16) | (134 << 8) | 11));
+ standard.put("darkgray", new Integer((169 << 16) | (169 << 8) | 169));
+ standard.put("darkgreen", new Integer((0 << 16) | (100 << 8) | 0));
+ standard.put("darkgrey", new Integer((169 << 16) | (169 << 8) | 169));
+ standard.put("darkkhaki", new Integer((189 << 16) | (183 << 8) | 107));
+ standard.put("darkmagenta", new Integer((139 << 16) | (0 << 8) | 139));
+ standard.put("darkolivegreen", new Integer((85 << 16) | (107 << 8) | 47));
+ standard.put("darkorange", new Integer((255 << 16) | (140 << 8) | 0));
+ standard.put("darkorchid", new Integer((153 << 16) | (50 << 8) | 204));
+ standard.put("darkred", new Integer((139 << 16) | (0 << 8) | 0));
+ standard.put("darksalmon", new Integer((233 << 16) | (150 << 8) | 122));
+ standard.put("darkseagreen", new Integer((143 << 16) | (188 << 8) | 143));
+ standard.put("darkslateblue", new Integer((72 << 16) | (61 << 8) | 139));
+ standard.put("darkslategray", new Integer((47 << 16) | (79 << 8) | 79));
+ standard.put("darkslategrey", new Integer((47 << 16) | (79 << 8) | 79));
+ standard.put("darkturquoise", new Integer((0 << 16) | (206 << 8) | 209));
+ standard.put("darkviolet", new Integer((148 << 16) | (0 << 8) | 211));
+ standard.put("deeppink", new Integer((255 << 16) | (20 << 8) | 147));
+ standard.put("deepskyblue", new Integer((0 << 16) | (191 << 8) | 255));
+ standard.put("dimgray", new Integer((105 << 16) | (105 << 8) | 105));
+ standard.put("dimgrey", new Integer((105 << 16) | (105 << 8) | 105));
+ standard.put("dodgerblue", new Integer((30 << 16) | (144 << 8) | 255));
+ standard.put("firebrick", new Integer((178 << 16) | (34 << 8) | 34));
+ standard.put("floralwhite", new Integer((255 << 16) | (250 << 8) | 240));
+ standard.put("forestgreen", new Integer((34 << 16) | (139 << 8) | 34));
+ standard.put("fuchsia", new Integer((255 << 16) | (0 << 8) | 255));
+ standard.put("gainsboro", new Integer((220 << 16) | (220 << 8) | 220));
+ standard.put("ghostwhite", new Integer((248 << 16) | (248 << 8) | 255));
+ standard.put("gold", new Integer((255 << 16) | (215 << 8) | 0));
+ standard.put("goldenrod", new Integer((218 << 16) | (165 << 8) | 32));
+ standard.put("gray", new Integer((128 << 16) | (128 << 8) | 128));
+ standard.put("grey", new Integer((128 << 16) | (128 << 8) | 128));
+ standard.put("green", new Integer((0 << 16) | (128 << 8) | 0));
+ standard.put("greenyellow", new Integer((173 << 16) | (255 << 8) | 47));
+ standard.put("honeydew", new Integer((240 << 16) | (255 << 8) | 240));
+ standard.put("hotpink", new Integer((255 << 16) | (105 << 8) | 180));
+ standard.put("indianred", new Integer((205 << 16) | (92 << 8) | 92));
+ standard.put("indigo", new Integer((75 << 16) | (0 << 8) | 130));
+ standard.put("ivory", new Integer((255 << 16) | (255 << 8) | 240));
+ standard.put("khaki", new Integer((240 << 16) | (230 << 8) | 140));
+ standard.put("lavender", new Integer((230 << 16) | (230 << 8) | 250));
+ standard.put("lavenderblush", new Integer((255 << 16) | (240 << 8) | 245));
+ standard.put("lawngreen", new Integer((124 << 16) | (252 << 8) | 0));
+ standard.put("lemonchiffon", new Integer((255 << 16) | (250 << 8) | 205));
+ standard.put("lightblue", new Integer((173 << 16) | (216 << 8) | 230));
+ standard.put("lightcoral", new Integer((240 << 16) | (128 << 8) | 128));
+ standard.put("lightcyan", new Integer((224 << 16) | (255 << 8) | 255));
+ standard.put("lightgoldenrodyellow", new Integer((250 << 16) | (250 << 8) | 210));
+ standard.put("lightgray", new Integer((211 << 16) | (211 << 8) | 211));
+ standard.put("lightgreen", new Integer((144 << 16) | (238 << 8) | 144));
+ standard.put("lightgrey", new Integer((211 << 16) | (211 << 8) | 211));
+ standard.put("lightpink", new Integer((255 << 16) | (182 << 8) | 193));
+ standard.put("lightsalmon", new Integer((255 << 16) | (160 << 8) | 122));
+ standard.put("lightseagreen", new Integer((32 << 16) | (178 << 8) | 170));
+ standard.put("lightskyblue", new Integer((135 << 16) | (206 << 8) | 250));
+ standard.put("lightslategray", new Integer((119 << 16) | (136 << 8) | 153));
+ standard.put("lightslategrey", new Integer((119 << 16) | (136 << 8) | 153));
+ standard.put("lightsteelblue", new Integer((176 << 16) | (196 << 8) | 222));
+ standard.put("lightyellow", new Integer((255 << 16) | (255 << 8) | 224));
+ standard.put("lime", new Integer((0 << 16) | (255 << 8) | 0));
+ standard.put("limegreen", new Integer((50 << 16) | (205 << 8) | 50));
+ standard.put("linen", new Integer((250 << 16) | (240 << 8) | 230));
+ standard.put("magenta", new Integer((255 << 16) | (0 << 8) | 255));
+ standard.put("maroon", new Integer((128 << 16) | (0 << 8) | 0));
+ standard.put("mediumaquamarine", new Integer((102 << 16) | (205 << 8) | 170));
+ standard.put("mediumblue", new Integer((0 << 16) | (0 << 8) | 205));
+ standard.put("mediumorchid", new Integer((186 << 16) | (85 << 8) | 211));
+ standard.put("mediumpurple", new Integer((147 << 16) | (112 << 8) | 219));
+ standard.put("mediumseagreen", new Integer((60 << 16) | (179 << 8) | 113));
+ standard.put("mediumslateblue", new Integer((123 << 16) | (104 << 8) | 238));
+ standard.put("mediumspringgreen", new Integer((0 << 16) | (250 << 8) | 154));
+ standard.put("mediumturquoise", new Integer((72 << 16) | (209 << 8) | 204));
+ standard.put("mediumvioletred", new Integer((199 << 16) | (21 << 8) | 133));
+ standard.put("midnightblue", new Integer((25 << 16) | (25 << 8) | 112));
+ standard.put("mintcream", new Integer((245 << 16) | (255 << 8) | 250));
+ standard.put("mistyrose", new Integer((255 << 16) | (228 << 8) | 225));
+ standard.put("moccasin", new Integer((255 << 16) | (228 << 8) | 181));
+ standard.put("navajowhite", new Integer((255 << 16) | (222 << 8) | 173));
+ standard.put("navy", new Integer((0 << 16) | (0 << 8) | 128));
+ standard.put("oldlace", new Integer((253 << 16) | (245 << 8) | 230));
+ standard.put("olive", new Integer((128 << 16) | (128 << 8) | 0));
+ standard.put("olivedrab", new Integer((107 << 16) | (142 << 8) | 35));
+ standard.put("orange", new Integer((255 << 16) | (165 << 8) | 0));
+ standard.put("orangered", new Integer((255 << 16) | (69 << 8) | 0));
+ standard.put("orchid", new Integer((218 << 16) | (112 << 8) | 214));
+ standard.put("palegoldenrod", new Integer((238 << 16) | (232 << 8) | 170));
+ standard.put("palegreen", new Integer((152 << 16) | (251 << 8) | 152));
+ standard.put("paleturquoise", new Integer((175 << 16) | (238 << 8) | 238));
+ standard.put("palevioletred", new Integer((219 << 16) | (112 << 8) | 147));
+ standard.put("papayawhip", new Integer((255 << 16) | (239 << 8) | 213));
+ standard.put("peachpuff", new Integer((255 << 16) | (218 << 8) | 185));
+ standard.put("peru", new Integer((205 << 16) | (133 << 8) | 63));
+ standard.put("pink", new Integer((255 << 16) | (192 << 8) | 203));
+ standard.put("plum", new Integer((221 << 16) | (160 << 8) | 221));
+ standard.put("powderblue", new Integer((176 << 16) | (224 << 8) | 230));
+ standard.put("purple", new Integer((128 << 16) | (0 << 8) | 128));
+ standard.put("red", new Integer((255 << 16) | (0 << 8) | 0));
+ standard.put("rosybrown", new Integer((188 << 16) | (143 << 8) | 143));
+ standard.put("royalblue", new Integer((65 << 16) | (105 << 8) | 225));
+ standard.put("saddlebrown", new Integer((139 << 16) | (69 << 8) | 19));
+ standard.put("salmon", new Integer((250 << 16) | (128 << 8) | 114));
+ standard.put("sandybrown", new Integer((244 << 16) | (164 << 8) | 96));
+ standard.put("seagreen", new Integer((46 << 16) | (139 << 8) | 87));
+ standard.put("seashell", new Integer((255 << 16) | (245 << 8) | 238));
+ standard.put("sienna", new Integer((160 << 16) | (82 << 8) | 45));
+ standard.put("silver", new Integer((192 << 16) | (192 << 8) | 192));
+ standard.put("skyblue", new Integer((135 << 16) | (206 << 8) | 235));
+ standard.put("slateblue", new Integer((106 << 16) | (90 << 8) | 205));
+ standard.put("slategray", new Integer((112 << 16) | (128 << 8) | 144));
+ standard.put("slategrey", new Integer((112 << 16) | (128 << 8) | 144));
+ standard.put("snow", new Integer((255 << 16) | (250 << 8) | 250));
+ standard.put("springgreen", new Integer((0 << 16) | (255 << 8) | 127));
+ standard.put("steelblue", new Integer((70 << 16) | (130 << 8) | 180));
+ standard.put("tan", new Integer((210 << 16) | (180 << 8) | 140));
+ standard.put("teal", new Integer((0 << 16) | (128 << 8) | 128));
+ standard.put("thistle", new Integer((216 << 16) | (191 << 8) | 216));
+ standard.put("tomato", new Integer((255 << 16) | (99 << 8) | 71));
+ standard.put("turquoise", new Integer((64 << 16) | (224 << 8) | 208));
+ standard.put("violet", new Integer((238 << 16) | (130 << 8) | 238));
+ standard.put("wheat", new Integer((245 << 16) | (222 << 8) | 179));
+ standard.put("white", new Integer((255 << 16) | (255 << 8) | 255));
+ standard.put("whitesmoke", new Integer((245 << 16) | (245 << 8) | 245));
+ standard.put("yellow", new Integer((255 << 16) | (255 << 8) | 0));
+ standard.put("yellowgreen", new Integer((154 << 16) | (205 << 8) | 50));
+ }
+}
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.graphics;
+import org.ibex.util.*;
+import java.io.*;
+import java.util.Hashtable;
+import org.ibex.js.*;
+import org.xwt.mips.*;
+import org.ibex.plat.*;
+import org.xwt.mips.Runtime;
+
+// FEATURE: this could be cleaner
+/** encapsulates a single font (a set of Glyphs) */
+public class Font {
+
+ private Font(Stream stream, int pointsize) { this.stream = stream; this.pointsize = pointsize; }
+
+ private static boolean glyphRenderingTaskIsScheduled = false;
+
+ public final int pointsize; ///< the size of the font
+ public final Stream stream; ///< the stream from which this font was loaded
+ public int max_ascent; ///< the maximum ascent, in pixels
+ public int max_descent; ///< the maximum descent, in pixels
+ boolean latinCharsPreloaded = false; ///< true if a request to preload ASCII 32-127 has begun
+ public Glyph[] glyphs = new Glyph[65535]; ///< the glyphs that comprise this font
+
+ public abstract static class Glyph {
+ protected Glyph(Font font, char c) { this.font = font; this.c = c; }
+ public final Font font;
+ public final char c;
+ public int baseline; ///< within the alphamask, this is the y-coordinate of the baseline
+ public int advance; ///< amount to increment the x-coordinate
+ public boolean isLoaded = false; ///< true iff the glyph is loaded
+ public int width = -1; ///< the width of the glyph
+ public int height = -1; ///< the height of the glyph
+ public byte[] data = null; ///< the alpha channel samples for this font
+ public String path = null; // FIXME this should be shared across point sizes
+ void render() {
+ if (!isLoaded) try { renderGlyph(this); } catch (IOException e) { Log.info(Font.class, e); }
+ isLoaded = true;
+ }
+ }
+
+
+ // Statics //////////////////////////////////////////////////////////////////////
+
+ static final Hashtable glyphsToBeCached = new Hashtable();
+ static final Hashtable glyphsToBeDisplayed = new Hashtable();
+ private static Cache fontCache = new Cache(100);
+ public static Font getFont(Stream stream, int pointsize) {
+ Font ret = (Font)fontCache.get(stream, new Integer(pointsize));
+ if (ret == null) fontCache.put(stream, new Integer(pointsize), ret = new Font(stream, pointsize));
+ return ret;
+ }
+
+
+ // Methods //////////////////////////////////////////////////////////////////////
+
+ /**
+ * Rasterize the glyphs of <code>text</code>.
+ * @returns <code>(width<<32)|height</code>
+ */
+ public long rasterizeGlyphs(String text, PixelBuffer pb, int textcolor, int x, int y, int cx1, int cy1, int cx2, int cy2) {
+ int width = 0, height = 0;
+ if (!latinCharsPreloaded) { // preload the Latin-1 charset with low priority (we'll probably want it)
+ for(int i=48; i<57; i++) if (glyphs[i]==null) glyphsToBeCached.put(glyphs[i]=Platform.createGlyph(this, (char)i),"");
+ for(int i=32; i<47; i++) if (glyphs[i]==null) glyphsToBeCached.put(glyphs[i]=Platform.createGlyph(this, (char)i),"");
+ for(int i=57; i<128; i++) if (glyphs[i]==null) glyphsToBeCached.put(glyphs[i]=Platform.createGlyph(this, (char)i),"");
+ if (!glyphRenderingTaskIsScheduled) {
+ Scheduler.add(glyphRenderingTask);
+ glyphRenderingTaskIsScheduled = true;
+ }
+ latinCharsPreloaded = true;
+ }
+ for(int i=0; i<text.length(); i++) {
+ final char c = text.charAt(i);
+ Glyph g = glyphs[c];
+ if (g == null) glyphs[c] = g = Platform.createGlyph(this, c);
+ g.render();
+ if (pb != null) pb.drawGlyph(g, x + width, y + g.font.max_ascent - g.baseline, cx1, cy1, cx2, cy2, textcolor);
+ width += g.advance;
+ height = java.lang.Math.max(height, max_ascent + max_descent);
+ }
+ return ((((long)width) << 32) | (long)(height & 0xffffffffL));
+ }
+
+ // FEATURE do we really need to be caching sizes?
+ private static Cache sizeCache = new Cache(1000);
+ public int textwidth(String s) { return (int)((textsize(s) >>> 32) & 0xffffffff); }
+ public int textheight(String s) { return (int)(textsize(s) & 0xffffffffL); }
+ public long textsize(String s) {
+ Long l = (Long)sizeCache.get(s);
+ if (l != null) return ((Long)l).longValue();
+ long ret = rasterizeGlyphs(s, null, 0, 0, 0, 0, 0, 0, 0);
+ sizeCache.put(s, new Long(ret));
+ return ret;
+ }
+
+ static final Task glyphRenderingTask = new Task() { public void perform() {
+ // FIXME: this should be a low-priority task
+ glyphRenderingTaskIsScheduled = false;
+ if (glyphsToBeCached.isEmpty()) return;
+ Glyph g = (Glyph)glyphsToBeCached.keys().nextElement();
+ if (g == null) return;
+ glyphsToBeCached.remove(g);
+ Log.debug(Font.class, "glyphRenderingTask rendering " + g.c + " of " + g.font);
+ g.render();
+ Log.debug(Glyph.class, " done rendering glyph " + g.c);
+ glyphRenderingTaskIsScheduled = true;
+ Scheduler.add(this);
+ } };
+
+
+ // FreeType Interface //////////////////////////////////////////////////////////////////////////////
+
+ // FEATURE: use streams, not memoryfont's
+ // FEATURE: kerning pairs
+ private static final Runtime rt;
+ private static Stream loadedStream;
+ private static int loadedStreamAddr;
+
+ static {
+ try {
+ rt = (Runtime)Class.forName("org.ibex.util.MIPSApps").newInstance();
+ } catch(Exception e) {
+ throw new Error("Error instantiating freetype: " + e);
+ }
+ rt.start(new String[]{"freetype"});
+ rt.execute();
+ rtCheck();
+ }
+
+ private static void rtCheck() { if(rt.getState() != Runtime.PAUSED) throw new Error("Freetype exited " + rt.exitStatus()); }
+
+ private static void loadFontByteStream(Stream res) {
+ if(loadedStream == res) return;
+
+ try {
+ Log.info(Font.class, "loading font " + res);
+ InputStream is = Stream.getInputStream(res);
+ byte[] fontstream = InputStreamToByteArray.convert(is);
+ rt.free(loadedStreamAddr);
+ loadedStreamAddr = rt.xmalloc(fontstream.length);
+ rt.copyout(fontstream, loadedStreamAddr, fontstream.length);
+ if(rt.call("load_font", loadedStreamAddr, fontstream.length) != 0)
+ throw new RuntimeException("load_font failed"); // FEATURE: better error
+ rtCheck();
+ loadedStream = res;
+ } catch (Exception e) {
+ // FEATURE: Better error reporting (thow an exception?)
+ Log.info(Font.class, e);
+ }
+ }
+
+ private static synchronized void renderGlyph(Font.Glyph glyph) throws IOException {
+ try {
+ Log.debug(Font.class, "rasterizing glyph " + glyph.c + " of font " + glyph.font);
+ if (loadedStream != glyph.font.stream) loadFontByteStream(glyph.font.stream);
+
+ long start = System.currentTimeMillis();
+
+ rt.call("render",glyph.c,glyph.font.pointsize);
+ rtCheck();
+
+ glyph.font.max_ascent = rt.getUserInfo(3);
+ glyph.font.max_descent = rt.getUserInfo(4);
+ glyph.baseline = rt.getUserInfo(5);
+ glyph.advance = rt.getUserInfo(6);
+
+ glyph.width = rt.getUserInfo(1);
+ glyph.height = rt.getUserInfo(2);
+
+ glyph.data = new byte[glyph.width * glyph.height];
+ int addr = rt.getUserInfo(0);
+ rt.copyin(addr, glyph.data, glyph.width * glyph.height);
+
+ byte[] path = new byte[rt.getUserInfo(8)];
+ rt.copyin(rt.getUserInfo(7), path, rt.getUserInfo(8));
+ glyph.path = new String(path);
+ glyph.path += " m " + (64 * glyph.advance) + " 0 ";
+
+ glyph.isLoaded = true;
+ } catch (Exception e) {
+ // FEATURE: Better error reporting (thow an exception?)
+ Log.info(Font.class, e);
+ }
+ }
+}
--- /dev/null
+// Copyright 2003 Adam Megacz, see the COPYING file for licensing [GPL]
+
+#include <unistd.h>
+#include <freetype/freetype.h>
+
+/* NOTE: _user_info is defined in crt0.c. It points to a 4096 byte
+ block of memory that contains 1024 32-bit values that can be set
+ with the setUserInfo() method of MIPSEmu.
+
+ The VM will pause after initialization. When unpaused, it expects
+ that:
+
+ user_info[0] = ptr to font byte stream in memory
+ user_info[1] = length of font stream
+ user_info[2] = unicode index of first glyph to render
+ user_info[3] = unicode index of last glyph to render
+ user_info[4] = point size to render in
+
+ The VM will then iterate over the requested glyphs, performing the
+ following actions for each glyph:
+
+ - render the glyph
+ - store the address of the glyph bitmap in user_info[5]
+ - store the width of the glyph bitmap in user_info[6]
+ - store the height of the glyph bitmap in user_info[7]
+ - store the font's ascender into user_info[8]
+ - store the font's height into user_info[9]
+ - store the glyph's ascender into user_info[10]
+ - store the glyph's advance into user_info[11]
+
+ The VM will then pause after each glyph. The VM should not be
+ unpaused after the last glyph until the next glyph set has been
+ configured in user_info (ie it does not pause twice).
+
+*/
+
+#if 0
+extern int user_info[1024];
+#else
+/* HACK: This really doesn't belong here... */
+int user_info[1024];
+
+extern int mspack_main();
+int freetype_main();
+
+int main(int argc, char **argv) {
+ if(argc < 1) return 1;
+ if(strcmp(argv[0],"mspack")==0) return mspack_main();
+ if(strcmp(argv[0],"freetype")==0) return freetype_main();
+ return 1;
+}
+#endif
+
+
+#define FT_Check(expr) do { \
+ if((expr) != 0) { \
+ errprint(#expr " failed\n"); \
+ exit(EXIT_FAILURE); \
+ } \
+} while(0)
+
+#define max(a, b) ((a) > (b) ? (a) : (b))
+#define min(a, b) ((a) < (b) ? (a) : (b))
+
+static int errprint(const char *s) {
+ int l = strlen(s);
+ int n;
+ while(l) {
+ n = write(STDERR_FILENO,s,l);
+ if(n < 0) return n;
+ l -= n;
+ s += n;
+ }
+ return 0;
+}
+
+extern void _pause();
+
+static FT_Library library; /* handle to library */
+static FT_Face face; /* handle to face object */
+
+int freetype_main() {
+ FT_Check(FT_Init_FreeType(&library));
+ _pause();
+
+ /*char *fontdata;
+ int glyph_index;
+ short charcode;
+
+
+ FT_Check(FT_Init_FreeType(&library));
+
+ for(;;) {
+
+ _pause();
+ FT_Check(FT_Set_Char_Size(face, 0, ((int)user_info[4]) * 64, 72, 72));
+ for(charcode = (int)user_info[2]; charcode <= (int)user_info[3]; charcode++) {
+
+ glyph_index = FT_Get_Char_Index(face, charcode);
+ FT_Check(FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT | FT_LOAD_FORCE_AUTOHINT));
+ FT_Check(FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL));
+
+ user_info[5] = (char*)face->glyph->bitmap.buffer;
+ user_info[6] = (char*)face->glyph->bitmap.width;
+ user_info[7] = (char*)face->glyph->bitmap.rows;
+ user_info[8] = (char*)(face->size->metrics.ascender >> 6);
+ user_info[9] = (char*)((-1 * face->size->metrics.descender) >> 6);
+ user_info[10] = (char*)(face->glyph->metrics.horiBearingY >> 6);
+ user_info[11] = (char*)(face->glyph->advance.x >> 6);
+
+ }
+ }*/
+}
+
+int load_font(char *buf, int length) __attribute__((section(".text")));
+int load_font(char *buf, int length) {
+ if(face != NULL) FT_Check(FT_Done_Face(face));
+ face = NULL;
+ return FT_New_Memory_Face(library, buf, length, 0, &face);
+}
+
+// if the path is more than 16k chars long, we're screwed anyways...
+static char path[1024 * 16];
+static int pathlen = 0;
+static int current_x;
+static int current_y;
+
+static void append(FT_Pos x, FT_Pos y) {
+ sprintf(path + pathlen, "%d,%d ", x - current_x, y - current_y);
+ pathlen += strlen(path + pathlen);
+}
+static int moveto(FT_Vector* to, void* user) {
+ if (pathlen > 0) {
+ path[pathlen++] = 'z';
+ path[pathlen++] = ' ';
+ }
+ path[pathlen++] = 'm';
+ path[pathlen++] = ' ';
+ append(to->x, to->y);
+ current_x = to->x; current_y = to->y;
+ return 0;
+}
+static int lineto(FT_Vector* to, void* user) {
+ path[pathlen++] = 'l';
+ path[pathlen++] = ' ';
+ append(to->x, to->y);
+ current_x = to->x; current_y = to->y;
+ return 0;
+}
+static int conicto(FT_Vector* control, FT_Vector* to, void* user) {
+ path[pathlen++] = 'q';
+ path[pathlen++] = ' ';
+ append(control->x, control->y);
+ append(to->x, to->y);
+ current_x = to->x; current_y = to->y;
+ return 0;
+}
+static int cubicto(FT_Vector* control1, FT_Vector* control2, FT_Vector* to, void* user) {
+ path[pathlen++] = 'c';
+ path[pathlen++] = ' ';
+ append(control1->x, control1->y);
+ append(control2->x, control2->y);
+ append(to->x, to->y);
+ current_x = to->x; current_y = to->y;
+ return 0;
+}
+static FT_Outline_Funcs buildPath = { &moveto, &lineto, &conicto, &cubicto, 0, 0 };
+
+int render(int charcode, int size) __attribute__((section(".text")));
+int render(int charcode, int size) {
+ int glyph_index;
+
+ FT_Check(FT_Set_Char_Size(face, 0, size * 64, 72, 72));
+
+ glyph_index = FT_Get_Char_Index(face, charcode);
+ FT_Check(FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT | FT_LOAD_FORCE_AUTOHINT));
+ FT_Check(FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL));
+
+ user_info[0] = (int)face->glyph->bitmap.buffer;
+ user_info[1] = face->glyph->bitmap.width;
+ user_info[2] = face->glyph->bitmap.rows;
+ user_info[3] = face->size->metrics.ascender >> 6;
+ user_info[4] = (-1 * face->size->metrics.descender) >> 6;
+ user_info[5] = face->glyph->metrics.horiBearingY >> 6;
+ user_info[6] = face->glyph->advance.x >> 6;
+
+ pathlen = 0; current_x = 0; current_y = 0;
+ FT_Outline_Decompose(&face->glyph->outline, &buildPath, NULL);
+ path[pathlen++] = 'z';
+ path[pathlen++] = ' ';
+ path[pathlen++] = 'm';
+ path[pathlen++] = ' ';
+ append(0, 0);
+ path[pathlen++] = ' ';
+ user_info[7] = (int)&path;
+ user_info[8] = pathlen;
+}
+
+// Kerning code; add back in later
+/*
+if (old_glyph_index != -1) {
+ if (FT_HAS_KERNING(face)) {
+ FT_Check(FT_Get_Kerning(face, old_glyph_index, glyph_index, 0, &kerning));
+ x += kerning.x >> 6;
+ } else {
+ x += face->glyph->advance.x >> 6;
+ }
+}
+old_glyph_index = glyph_index;
+*/
--- /dev/null
+/*
+ * This file was adapted from D J Hagberg's GifDecoder.java
+ *
+ * This software is copyrighted by D. J. Hagberg, Jr., and other parties.
+ * The following terms apply to all files associated with the software
+ * unless explicitly disclaimed in individual files.
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ *
+ * IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
+ * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
+ * DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE
+ * IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
+ * NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
+ * MODIFICATIONS.
+ *
+ * GOVERNMENT USE: If you are acquiring this software on behalf of the
+ * U.S. government, the Government shall have only "Restricted Rights"
+ * in the software and related documentation as defined in the Federal
+ * Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you
+ * are acquiring the software on behalf of the Department of Defense, the
+ * software shall be classified as "Commercial Computer Software" and the
+ * Government shall have only "Restricted Rights" as defined in Clause
+ * 252.227-7013 (c) (1) of DFARs. Notwithstanding the foregoing, the
+ * authors grant the U.S. Government and others acting in its behalf
+ * permission to use and distribute the software in accordance with the
+ * terms specified in this license.
+ *
+ */
+package org.ibex.graphics;
+
+import org.ibex.util.*;
+import java.io.BufferedInputStream;
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+
+/** Converts an InputStream carrying a GIF image into an ARGB int[] */
+public class GIF {
+
+ // Public Methods /////////////////////////////////////////////////////////
+
+ private GIF() { }
+
+ private static Queue instances = new Queue(10);
+
+ public static void load(InputStream is, Picture p) {
+ GIF g = (GIF)instances.remove(false);
+ if (g == null) g = new GIF();
+ try {
+ g._load(is, p);
+ } catch (Exception e) {
+ if (Log.on) Log.info(GIF.class, e);
+ return;
+ }
+ // FIXME: must reset fields
+ // if (instances.size() < 10) instances.append(g);
+ }
+
+ private void _load(InputStream is, Picture p) throws IOException {
+ this.p = p;
+ if (is instanceof BufferedInputStream) _in = (BufferedInputStream)is;
+ else _in = new BufferedInputStream(is);
+ decodeAsBufferedImage(0);
+ p.isLoaded = true;
+ p = null;
+ _in = null;
+ }
+
+
+ /** Decode a particular frame from the GIF file. Frames must be decoded in order, starting with 0. */
+ private void decodeAsBufferedImage(int page) throws IOException, IOException {
+
+ // If the user requested a page already decoded, we cannot go back.
+ if (page <= index ) return;
+
+ // If we just started reading this stream, initialize the global info.
+ if (index < 0 ) {
+ if (!readIntoBuf(6) || _buf[0] != 'G' || _buf[1] != 'I' || _buf[2] != 'F' ||
+ _buf[3] != '8' || !(_buf[4] == '7' || _buf[4] == '9') || _buf[5] != 'a')
+ throw new IOException("Not a GIF8Xa file.");
+ if (!readGlobalImageDescriptor()) throw new IOException("Unable to read GIF header.");
+ }
+
+ // Loop through the blocks in the image.
+ int block_identifier;
+ while (true) {
+ if(!readIntoBuf(1)) throw new IOException("Unexpected EOF(1)");
+ block_identifier = _buf[0];
+ if (block_identifier == ';') throw new IOException("No image data");
+ if (block_identifier == '!') {
+ if (!readExtensionBlock()) throw new IOException("Unexpected EOF(2)");
+ continue;
+ }
+
+ // not a valid start character -- ignore it.
+ if (block_identifier != ',') continue;
+
+ if (!readLocalImageDescriptor()) throw new IOException("Unexpected EOF(3)");
+ p.data = new int[p.width * p.height];
+ readImage();
+
+ // If we did not decode the requested index, need to go on
+ // to the next one (future implementations should consider
+ // caching already-decoded images here to allow for random
+ // access to animated GIF pages).
+ index++;
+ if (index < page) continue;
+
+ // If we did decode the requested index, we can return.
+ break;
+ }
+
+ // Return the image thus-far decoded
+ return;
+ }
+
+ /** Actually read the image data */
+ private void readImage()
+ throws IOException, IOException {
+ int len = p.width;
+ int rows = p.height;
+ int initialCodeSize;
+ int v;
+ int xpos = 0, ypos = 0, pass = 0, i;
+ int prefix[] = new int[(1 << MAX_LWZ_BITS)];
+ int append[] = new int[(1 << MAX_LWZ_BITS)];
+ int stack[] = new int[(1 << MAX_LWZ_BITS)*2];
+ int top_idx;
+ int codeSize, clearCode, inCode, endCode, oldCode, maxCode, code, firstCode;
+
+ // Initialize the decoder
+ if (!readIntoBuf(1)) throw new IOException("Unexpected EOF decoding image");
+ initialCodeSize = _buf[0];
+
+ // Look at the right color map, setting up transparency if called for.
+ int[] cmap = global_color_map;
+ if (hascmap) cmap = color_map;
+ if (trans_idx >= 0) cmap[trans_idx] = 0x00000000;
+
+ /* Initialize the decoder */
+ /* Set values for "special" numbers:
+ * clear code reset the decoder
+ * end code stop decoding
+ * code size size of the next code to retrieve
+ * max code next available table position
+ */
+ clearCode = 1 << initialCodeSize;
+ endCode = clearCode + 1;
+ codeSize = initialCodeSize + 1;
+ maxCode = clearCode + 2;
+ oldCode = -1;
+ firstCode = -1;
+
+ for (i = 0; i < clearCode; i++) append[i] = i;
+ top_idx = 0; // top of stack.
+
+ bitsInWindow = 0;
+ bytes = 0;
+ window = 0L;
+ done = false;
+ c = -1;
+
+ /* Read until we finish the image */
+ ypos = 0;
+ for (i = 0; i < rows; i++) {
+ for (xpos = 0; xpos < len;) {
+
+ if (top_idx == 0) {
+ /* Bummer -- our stack is empty. Now we have to work! */
+ code = getCode(codeSize);
+ if (code < 0) return;
+
+ if (code > maxCode || code == endCode) return;
+ if (code == clearCode) {
+ codeSize = initialCodeSize + 1;
+ maxCode = clearCode + 2;
+ oldCode = -1;
+ continue;
+ }
+
+ // Last pass reset the decoder, so the first code we
+ // see must be a singleton. Seed the stack with it,
+ // and set up the old/first code pointers for
+ // insertion into the string table. We can't just
+ // roll this into the clearCode test above, because
+ // at that point we have not yet read the next code.
+ if (oldCode == -1) {
+ stack[top_idx++] = append[code];
+ oldCode = code;
+ firstCode = code;
+ continue;
+ }
+
+ inCode = code;
+
+ // maxCode is always one bigger than our
+ // highest assigned code. If the code we see
+ // is equal to maxCode, then we are about to
+ // add a new string to the table. ???
+ if (code == maxCode) {
+ stack[top_idx++] = firstCode;
+ code = oldCode;
+ }
+
+ // Populate the stack by tracing the string in the
+ // string table from its tail to its head
+ while (code > clearCode) {
+ stack[top_idx++] = append[code];
+ code = prefix[code];
+ }
+ firstCode = append[code];
+
+ // If there's no more room in our string table, quit.
+ // Otherwise, add a new string to the table
+ if (maxCode >= (1 << MAX_LWZ_BITS)) return;
+
+ // Push the head of the string onto the stack
+ stack[top_idx++] = firstCode;
+
+ // Add a new string to the string table
+ prefix[maxCode] = oldCode;
+ append[maxCode] = firstCode;
+ maxCode++;
+
+ // maxCode tells us the maximum code value we can accept.
+ // If we see that we need more bits to represent it than
+ // we are requesting from the unpacker, we need to increase
+ // the number we ask for.
+ if ((maxCode >= (1 << codeSize)) && (maxCode < (1<<MAX_LWZ_BITS))) codeSize++;
+ oldCode = inCode;
+ }
+
+ // Pop the next color index off the stack
+ v = stack[--top_idx];
+ if (v < 0) return;
+
+ // Finally, we can set a pixel! Joy!
+ p.data[xpos + ypos * p.width] = cmap[v];
+ xpos++;
+ }
+
+ // If interlacing, the next ypos is not just +1
+ if (interlaced) {
+ ypos += _interlaceStep[pass];
+ while (ypos >= rows) {
+ pass++;
+ if (pass > 3) return;
+ ypos = _interlaceStart[pass];
+ }
+ } else ypos++;
+ }
+ return;
+ }
+
+ /** Extract the next compression code from the file. */
+ private int getCode(int code_size) throws IOException {
+ int ret;
+
+ while (bitsInWindow < code_size) {
+ // Not enough bits in our window to cover the request
+ if (done) return -1;
+
+ if (bytes == 0) {
+ // Not enough bytes in our buffer to add to the window
+ bytes = getDataBlock();
+ c = 0;
+ if (bytes <= 0) {
+ done = true;
+ break;
+ }
+ }
+ // Tack another byte onto the window, see if that's enough
+ window += (_buf[c]) << bitsInWindow;
+ ++c;
+ bitsInWindow += 8;
+ bytes--;
+ }
+
+
+ // The next code will always be the last code_size bits of the window
+ ret = ((int)window) & ((1 << code_size) - 1);
+
+ // Shift data in the window to put the next code at the end
+ window >>= code_size;
+ bitsInWindow -= code_size;
+ return ret;
+ }
+
+ /** Read the global image descriptor and optional global color map. Sets global_* variables. */
+ private boolean readGlobalImageDescriptor() throws IOException {
+ int packed;
+ int aspect; // we ignore this.
+ int ofs;
+
+ if (!readIntoBuf(7) ) return false;
+ global_width = _buf[0] | (_buf[1] << 8);
+ global_height = _buf[2] | (_buf[3] << 8);
+ packed = _buf[4];
+ global_bgcolor = _buf[5];
+ aspect = _buf[6];
+ global_cmapsize = 2 << (packed & 0x07);
+ global_hascmap = (packed & GLOBALCOLORMAP) == GLOBALCOLORMAP;
+ global_color_map = null;
+
+ // Read the color map, if we have one.
+ if (global_hascmap) {
+ if (!readColorMap(global_cmapsize,true)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /** Read a local image descriptor and optional local color map. */
+ private boolean readLocalImageDescriptor() throws IOException {
+ int packed;
+
+ if (!readIntoBuf(9) ) return false;
+
+ left = _buf[0] | (_buf[1] << 8);
+ top = _buf[2] | (_buf[3] << 8);
+ p.width = _buf[4] | (_buf[5] << 8);
+ p.height = _buf[6] | (_buf[7] << 8);
+ packed = _buf[8];
+ hascmap = (packed & LOCALCOLORMAP) == LOCALCOLORMAP;
+ cmapsize = 2 << (packed & 0x07);
+ interlaced = (packed & INTERLACE) == INTERLACE;
+ color_map = null;
+
+ // Read the local color table, if there is one.
+ return !(hascmap && !readColorMap(cmapsize,false));
+ }
+
+ /** Read a color map (global or local). */
+ private boolean readColorMap(int nColors, boolean isGlobal)
+ throws IOException {
+ int[] map = new int[nColors];
+ for( int i=0; i < nColors; ++i) {
+ if (!readIntoBuf(3) ) return false;
+ map[i] = (_buf[0] << 16) | (_buf[1] << 8) | _buf[2] | 0xFF000000;
+ }
+ if (isGlobal) global_color_map = map;
+ else color_map = map;
+ return true;
+ }
+
+ /** Read the contents of a GIF89a Graphical Extension Block. */
+ private boolean readExtensionBlock() throws IOException {
+ if (!readIntoBuf(1) ) return false;
+ int label = _buf[0];
+ int count = -1;
+ switch (label) {
+ case 0x01: // Plain Text Extension
+ case 0xff: // Application Extension
+ case 0xfe: // Comment Extension
+ break;
+ case 0xf9: // Graphic Control Extension
+ count = getDataBlock();
+ if (count < 0) return true;
+ // Check for transparency setting.
+ if ((_buf[0] & HASTRANSPARENCY) != 0) trans_idx = _buf[3];
+ else trans_idx = -1;
+ }
+ do { count = getDataBlock(); } while (count > 0);
+ return true;
+ }
+
+ /** Read a block of data from the GIF file. */
+ private int getDataBlock() throws IOException {
+ if (!readIntoBuf(1) ) return -1;
+ int count = _buf[0];
+ if (count != 0) if (!readIntoBuf(count) ) return -1;
+ return count;
+ }
+
+ /** Read the indicated number of bytes into _buf, our instance-wide buffer. */
+ private boolean readIntoBuf(int count) throws IOException {
+ for(int i = 0; i < count; i++) if ((_buf[i] = _in.read()) == -1) return false;
+ return true;
+ }
+
+ // Private Data //////////////////////////////////////////////////////////
+
+ private Picture p;
+
+ // State management stuff
+ private int index = -1;
+ private BufferedInputStream _in = null;
+ private int[] _buf = new int[BUFSIZE];
+
+ // Transparency settings
+ private int trans_idx = -1;
+
+ // Global image descriptor contents
+ private int global_width = 0;
+ private int global_height = 0;
+ private int global_bgcolor = 0;
+ private int global_cmapsize = 0;
+ private boolean global_hascmap = false;
+ private int[] global_color_map = null;
+
+ // Local image descriptor contents
+ private int left = 0;
+ private int top = 0;
+ private int cmapsize = 0;
+ private boolean hascmap = false;
+ private boolean interlaced = false;
+ private int[] color_map = null;
+
+ // Variables used in getCode(...) to track sliding bit-window.
+ private int bytes = 0;
+ private boolean done;
+ private int c;
+ private long window;
+ private int bitsInWindow = 0;
+
+ // Class-wide constants.
+ private static final int INTERLACE = 0x40;
+ private static final int GLOBALCOLORMAP = 0x80;
+ private static final int LOCALCOLORMAP = 0x80;
+ private static final int HASTRANSPARENCY = 0x01;
+ private static final int MAX_LWZ_BITS = 12;
+ private static final int BUFSIZE = 280;
+ private static final int[] _interlaceStep = { 8, 8, 4, 2 };
+ private static final int[] _interlaceStart = { 0, 4, 2, 1 };
+}
+
+
+
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.graphics;
+
+import java.util.*;
+import java.net.*;
+import java.io.*;
+import org.ibex.js.*;
+import org.ibex.util.*;
+
+/*
+ * While entities are limited to a subset of Unicode characters ,
+ * numeric character references can specify any character. Numeric
+ * character references may be given in decimal or hexadecimal, though
+ * browser support is stronger for decimal references. Decimal
+ * references are of the form &#number; while hexadecimal references
+ * take the case-insensitive form &#xnumber;. Examples of numeric
+ * character references include © or © for the copyright
+ * symbol, Α or Α for the Greek capital letter alpha, and
+ * ا or ا for the Arabic letter ALEF.
+ *
+ * http://www.htmlhelp.com/reference/html40/entities/special.html
+ * http://www.htmlhelp.com/reference/html40/entities/symbols.html
+ * http://www.htmlhelp.com/reference/html40/entities/latin1.html
+ */
+
+/**
+ * This class parses an InputStream containing HTML and returns it
+ * as an XWT DOM tree. Each HTML Element is returned as a struct,
+ * with the following members:
+ *
+ * Since HTML may have multiple top level elements (unlike XML),
+ * this class will search all top level elements for one with a tag
+ * name 'html'. If such a node is found, only it is returned. If no
+ * top-level element has the tag name 'html', such a node is
+ * fabricated, and all top level elements become the children of
+ * that node, which is then returned.
+ */
+public class HTML {
+
+ private final static String[] noEndTag =
+ new String[] { "area", "base", "basefont", "br", "col", "frame", "hr", "img",
+ "input", "isindex", "link", "meta", "param" };
+
+ /** we keep a char[] around for use by removeRedundantWhitespace() */
+ private static char[] cbuf = null;
+
+ /** we keep a StringBuffer around for use by removeRedundantWhitespace() */
+ private static StringBuffer sbuf = null;
+
+ /** true iff we have encountered an LI more recently than the last OL/UL */
+ private static boolean withinLI = false;
+
+ public static synchronized JS parseReader(Reader r) throws IOException, JSExn {
+ CharStream cs = new CharStream(r);
+ JS h = new JS();
+
+ withinLI = false;
+ h.put("$name", "html");
+
+ try {
+ while (true) parseBody(cs, h, null);
+ } catch (EOFException e) {
+ // continue until we get an EOFException
+ }
+
+ /* FIXME
+ Object[] ids = h.keys();
+ for(int i=0; i<ids.length; i++) {
+ Object el = h.get((String)ids[i]);
+ if (el instanceof JS && "html".equals(((JS)el).get("$name")))
+ return (JS)el;
+ }
+ */
+ return h;
+ }
+
+ /**
+ * Parses a single element and stores it in <tt>h</tt>. The
+ * CharStream should be positioned immediately <i>after</i> the
+ * open bracket.
+ *
+ * If a close tag not matching this open tag is found, the
+ * tagname on the close tag will be returned in order to
+ * facilitate correcting broken HTML. Otherwise, this returns
+ * null.
+ */
+ private static String parseElement(CharStream cs, JS h) throws IOException, JSExn {
+ // scan element name
+ while(Character.isSpace(cs.peek())) cs.get();
+ String elementName = parseElementName(cs);
+
+ boolean saveWithinLI = withinLI;
+ if (elementName.equals("li")) {
+ if (withinLI) {
+ cs.unread(new char[] { '<', 'l', 'i', ' ' });
+ return "li";
+ } else {
+ withinLI = true;
+ }
+ } else if (elementName.equals("ol") || elementName.equals("ul")) {
+ withinLI = false;
+ }
+
+ h.put("$name", elementName);
+ if (elementName.equals("!--")) {
+ h.put("0", parseComment(cs));
+ h.put("$numchildren", new Integer(0));
+ return null;
+ }
+
+ // scan attributes
+ while (cs.peek() != '>') {
+ String name = parseAttributeName(cs);
+ if (name.equals("")) break;
+ String value = expandEntities(parseAttributeValue(cs));
+ h.put(name, value);
+ }
+
+ // eat the close-angle bracket
+ cs.get();
+
+ // bodyless tags return here
+ for(int i=0; i<noEndTag.length; i++)
+ if (noEndTag[i].equals(elementName))
+ return null;
+
+ // scan body
+ String ret = parseBody(cs, h, elementName);
+ withinLI = saveWithinLI;
+ return ret;
+ }
+
+ /**
+ * Parses the body of an element. The CharStream should be
+ * positioned at the character immediately after the right
+ * bracket closing the start-tag
+ */
+ private static String parseBody(CharStream cs, JS h, String elementName) throws IOException, JSExn {
+ String cdata = "";
+ int length = h.get("$numchildren") == null ? 0 : Integer.parseInt(h.get("$numchildren").toString());
+ while(true) {
+ String closetag = null;
+
+ try {
+ char c = cs.get();
+ if (c != '<') { cdata += c; continue; }
+ String expanded = removeRedundantWhitespace(expandEntities(cdata));
+ if (expanded.length() > 0) {
+ h.put(String.valueOf(length), expanded);
+ h.put("$numchildren", new Integer(++length));
+ }
+ cdata = "";
+
+ } catch (EOFException e) {
+ String expanded = removeRedundantWhitespace(expandEntities(cdata));
+ if (expanded.length() > 0) {
+ h.put(String.valueOf(length), expanded);
+ h.put("$numchildren", new Integer(++length));
+ }
+ throw e;
+ }
+
+ try {
+ // scan subelement
+ if (cs.peek() != '/') {
+ JS kid = new JS();
+ closetag = parseElement(cs, kid);
+ h.put(String.valueOf(length), kid);
+ h.put("$numchildren", new Integer(++length));
+
+ // scan close-tag
+ } else {
+ cs.get(); // drop the slash
+ closetag = parseElementName(cs);
+ while(cs.get() != '>');
+ }
+ } catch (EOFException e) {
+ throw e;
+
+ }
+
+ if (closetag != null)
+ return closetag.equals(elementName) ? null : closetag;
+ }
+ }
+
+ /** Parses an element name and returns it. The CharStream should
+ * be positioned at the first character of the name.
+ */
+ private static String parseElementName(CharStream cs) throws IOException, JSExn {
+ String ret = "";
+ while (cs.peek() != '>' && !Character.isSpace(cs.peek())) ret += cs.get();
+ return ret.toLowerCase();
+ }
+
+ /** Parses an attribute name and returns it. The CharStream should
+ * be positioned at the first character of the name, possibly
+ * with intervening whitespace.
+ */
+ private static String parseAttributeName(CharStream cs) throws IOException, JSExn {
+ while(Character.isSpace(cs.peek())) cs.get();
+ String ret = "";
+ while(!Character.isSpace(cs.peek()) && cs.peek() != '=' && cs.peek() != '>') ret += cs.get();
+ return ret.toLowerCase();
+ }
+
+ /** Parses an attribute value and returns it. The CharStream
+ * should be positioned at the equals sign, possibly with
+ * intervening whitespace.
+ */
+ private static String parseAttributeValue(CharStream cs) throws IOException, JSExn {
+
+ // eat whitespace and equals sign
+ while(Character.isSpace(cs.peek())) cs.get();
+ if (cs.peek() != '=') return "";
+ cs.get();
+ while(Character.isSpace(cs.peek())) cs.get();
+
+ boolean doublequoted = false;
+ boolean singlequoted = false;
+ String ret = "";
+
+ if (cs.peek() == '\"') { doublequoted = true; cs.get(); }
+ else if (cs.peek() == '\'') { singlequoted = true; cs.get(); }
+
+ while(true) {
+ char c = cs.peek();
+ if (!doublequoted && !singlequoted && (Character.isSpace(c) || c == '>')) break;
+ if (singlequoted && c == '\'') { cs.get(); break; }
+ if (doublequoted && c == '\"') { cs.get(); break; }
+ ret += cs.get();
+ }
+ return ret;
+ }
+
+ /** Parses a comment and returns its body. The CharStream should
+ * be positioned immediately after the <!--
+ */
+ private static String parseComment(CharStream cs) throws IOException, JSExn {
+ int dashes = 0;
+ String ret = "";
+ while(true) {
+ char c = cs.get();
+ if (c == '>' && dashes == 2) return ret.substring(0, ret.length() - 2);
+ if (c == '-') dashes++;
+ else dashes = 0;
+ ret += c;
+ }
+ }
+
+ /** Expands all SGML entities in string <tt>s</tt> */
+ public static String expandEntities(String s) throws IOException, JSExn {
+ if (s.indexOf('&') == -1) return s;
+ StringBuffer sb = new StringBuffer();
+ int i=0;
+ int nextamp = 0;
+ while(nextamp != -1) {
+ nextamp = s.indexOf('&', i);
+ sb.append(nextamp == -1 ? s.substring(i) : s.substring(i, nextamp));
+ if (nextamp == -1) break;
+ if (s.regionMatches(nextamp, "&", 0, 5)) {
+ sb.append("&");
+ i = nextamp + 5;
+ } else if (s.regionMatches(nextamp, ">", 0, 4)) {
+ sb.append(">");
+ i = nextamp + 4;
+ } else if (s.regionMatches(nextamp, "<", 0, 4)) {
+ sb.append("<");
+ i = nextamp + 4;
+ } else if (s.regionMatches(nextamp, """, 0, 6)) {
+ sb.append("\"");
+ i = nextamp + 6;
+ } else if (s.regionMatches(nextamp, " ", 0, 6)) {
+ // FEATURE: perhaps we should distinguish this somehow
+ sb.append(" ");
+ i = nextamp + 6;
+ } else {
+ sb.append("&");
+ i = nextamp + 1;
+ }
+ }
+ return sb.toString();
+ }
+
+ /** removes all redundant whitespace */
+ private static String removeRedundantWhitespace(String s) throws JSExn {
+
+ if (s.indexOf(' ') == -1 && s.indexOf('\n') == -1 && s.indexOf('\t') == -1 && s.indexOf('\r') == -1) return s;
+
+ int len = s.length();
+ if (cbuf == null || cbuf.length < len) {
+ cbuf = new char[len * 2];
+ sbuf = new StringBuffer(len * 2);
+ }
+ sbuf.setLength(0);
+ s.getChars(0, len, cbuf, 0);
+
+ int last = 0;
+ boolean lastWasWhitespace = false;
+ for(int i=0; i<len; i++) {
+ boolean lastlast = lastWasWhitespace;
+ switch(cbuf[i]) {
+ case '\n': case '\r': case '\t':
+ cbuf[i] = ' ';
+ case ' ':
+ lastWasWhitespace = true;
+ break;
+ default:
+ lastWasWhitespace = false;
+ break;
+ }
+ if (lastWasWhitespace && lastlast) {
+ if (last != i) sbuf.append(cbuf, last, i - last);
+ last = i+1;
+ }
+ }
+
+ if (last != len) sbuf.append(cbuf, last, len - last);
+ return sbuf.toString().trim();
+ }
+
+ // CharStream /////////////////////////////////////////////////////////////////////
+
+ private static class CharStream extends PushbackReader {
+ public CharStream(Reader r) { super(r, 1024); }
+
+ public char peek() throws IOException {
+ char c = get();
+ unread(c);
+ return c;
+ }
+
+ public char get() throws IOException {
+ int i = read();
+ if (i == -1) throw new EOFException();
+ return (char)i;
+ }
+ }
+
+}
+
--- /dev/null
+/*
+ * This file was adapted from Jason Marshall's PNGImageProducer.java
+ *
+ * Copyright (c) 1997, Jason Marshall. All Rights Reserved
+ *
+ * The author makes no representations or warranties regarding the suitability,
+ * reliability or stability of this code. This code is provided AS IS. The
+ * author shall not be liable for any damages suffered as a result of using,
+ * modifying or redistributing this software or any derivitives thereof.
+ * Permission to use, reproduce, modify and/or (re)distribute this software is
+ * hereby granted.
+ */
+
+package org.ibex.graphics;
+
+import org.ibex.util.*;
+import java.io.*;
+import java.util.Hashtable;
+import java.util.Vector;
+import java.util.Enumeration;
+import java.util.zip.*;
+
+/** Converts an InputStream carrying a PNG image into an ARGB int[] */
+public class PNG {
+
+ public PNG() { }
+
+ private static Queue instances = new Queue(10);
+ private Picture p;
+
+ public static void load(InputStream is, Picture p) {
+ PNG g = (PNG)instances.remove(false);
+ if (g == null) g = new PNG();
+ try {
+ g._load(is, p);
+ p.data = g.data;
+ } catch (Exception e) {
+ if (Log.on) Log.info(PNG.class, e);
+ return;
+ }
+ // FIXME: must reset fields
+ // if (instances.size() < 10) instances.append(g);
+ }
+
+ // Public Methods ///////////////////////////////////////////////////////////////////////////////
+
+ /** process a PNG as an inputstream; returns null if there is an error
+ @param name A string describing the image, to be used when logging errors
+ */
+ private void _load(InputStream is, Picture pic) throws IOException {
+ p = pic;
+ if (is instanceof BufferedInputStream) underlyingStream = (BufferedInputStream)is;
+ else underlyingStream = new BufferedInputStream(is);
+ target_offset = 0;
+ inputStream = new DataInputStream(underlyingStream);
+
+ // consume the header
+ if ((inputStream.read() != 137) || (inputStream.read() != 80) || (inputStream.read() != 78) || (inputStream.read() != 71) ||
+ (inputStream.read() != 13) || (inputStream.read() != 10) || (inputStream.read() != 26) || (inputStream.read() != 10)) {
+ Log.info(this, "PNG: error: input file is not a PNG file");
+ data = p.data = new int[] { };
+ p.width = p.height = 0;
+ return;
+ }
+
+
+ while (!error) {
+ if (needChunkInfo) {
+ chunkLength = inputStream.readInt();
+ chunkType = inputStream.readInt();
+ needChunkInfo = false;
+ }
+
+ // I rewrote this as an if/else to work around a JODE bug with switch() blocks
+ if (chunkType == CHUNK_bKGD) inputStream.skip(chunkLength);
+ else if (chunkType == CHUNK_cHRM) inputStream.skip(chunkLength);
+ else if (chunkType == CHUNK_gAMA) inputStream.skip(chunkLength);
+ else if (chunkType == CHUNK_hIST) inputStream.skip(chunkLength);
+ else if (chunkType == CHUNK_pHYs) inputStream.skip(chunkLength);
+ else if (chunkType == CHUNK_sBIT) inputStream.skip(chunkLength);
+ else if (chunkType == CHUNK_tEXt) inputStream.skip(chunkLength);
+ else if (chunkType == CHUNK_zTXt) inputStream.skip(chunkLength);
+ else if (chunkType == CHUNK_tIME) inputStream.skip(chunkLength);
+ else if (chunkType == CHUNK_IHDR) handleIHDR();
+ else if (chunkType == CHUNK_PLTE) handlePLTE();
+ else if (chunkType == CHUNK_tRNS) handletRNS();
+ else if (chunkType == CHUNK_IDAT) handleIDAT();
+ else if (chunkType == CHUNK_IEND) break;
+ else {
+ System.err.println("unrecognized chunk type " + Integer.toHexString(chunkType) + ". skipping");
+ inputStream.skip(chunkLength);
+ }
+
+ int crc = inputStream.readInt();
+ needChunkInfo = true;
+ }
+ p.isLoaded = true;
+ }
+
+ // Chunk Handlers ///////////////////////////////////////////////////////////////////////
+
+ /** handle data chunk */
+ private void handleIDAT() throws IOException {
+ if (p.width == -1 || p.height == -1) throw new IOException("never got image width/height");
+ switch (depth) {
+ case 1: mask = 0x1; break;
+ case 2: mask = 0x3; break;
+ case 4: mask = 0xf; break;
+ case 8: case 16: mask = 0xff; break;
+ default: mask = 0x0; break;
+ }
+ if (depth < 8) smask = mask << depth;
+ else smask = mask << 8;
+
+ int count = p.width * p.height;
+
+ switch (colorType) {
+ case 0:
+ case 2:
+ case 6:
+ case 4:
+ ipixels = new int[count];
+ pixels = ipixels;
+ break;
+ case 3:
+ bpixels = new byte[count];
+ pixels = bpixels;
+ break;
+ default:
+ throw new IOException("Image has unknown color type");
+ }
+ if (interlaceMethod != 0) multipass = true;
+ readImageData();
+ }
+
+ /** handle header chunk */
+ private void handleIHDR() throws IOException {
+ if (headerFound) throw new IOException("Extraneous IHDR chunk encountered.");
+ if (chunkLength != 13) throw new IOException("IHDR chunk length wrong: " + chunkLength);
+ p.width = inputStream.readInt();
+ p.height = inputStream.readInt();
+ depth = inputStream.read();
+ colorType = inputStream.read();
+ compressionMethod = inputStream.read();
+ filterMethod = inputStream.read();
+ interlaceMethod = inputStream.read();
+ }
+
+ /** handle pallette chunk */
+ private void handlePLTE() throws IOException {
+ if (colorType == 3) {
+ palette = new byte[chunkLength];
+ inputStream.readFully(palette);
+ } else {
+ // Ignore suggested palette
+ inputStream.skip(chunkLength);
+ }
+ }
+
+ /** handle transparency chunk; modifies palette */
+ private void handletRNS() throws IOException {
+ int chunkLen = chunkLength;
+ if (palette == null) {
+ if (Log.on) Log.info(this, "warning: tRNS chunk encountered before pLTE; ignoring alpha channel");
+ inputStream.skip(chunkLength);
+ return;
+ }
+ int len = palette.length;
+ if (colorType == 3) {
+ transparency = true;
+
+ int transLength = len/3;
+ byte[] trans = new byte[transLength];
+ for (int i = 0; i < transLength; i++) trans[i] = (byte) 0xff;
+ inputStream.readFully(trans, 0, chunkLength);
+
+ byte[] newPalette = new byte[len + transLength];
+ for (int i = newPalette.length; i > 0;) {
+ newPalette[--i] = trans[--transLength];
+ newPalette[--i] = palette[--len];
+ newPalette[--i] = palette[--len];
+ newPalette[--i] = palette[--len];
+ }
+ palette = newPalette;
+
+ } else {
+ inputStream.skip(chunkLength);
+ }
+ }
+
+ /// Helper functions for IDAT ///////////////////////////////////////////////////////////////////////////////////////////
+
+ /** Read Image data in off of a compression stream */
+ private void readImageData() throws IOException {
+ InputStream dataStream = new SequenceInputStream(new IDATEnumeration(this));
+ DataInputStream dis = new DataInputStream(new BufferedInputStream(new InflaterInputStream(dataStream, new Inflater())));
+ int bps, filterOffset;
+ switch (colorType) {
+ case 0: case 3: bps = depth; break;
+ case 2: bps = 3 * depth; break;
+ case 4: bps = depth<<1; break;
+ case 6: bps = depth<<2; break;
+ default: throw new IOException("Unknown color type encountered.");
+ }
+
+ filterOffset = (bps + 7) >> 3;
+
+ for (pass = (multipass ? 1 : 0); pass < 8; pass++) {
+ int pass = this.pass;
+ int rInc = rowInc[pass];
+ int cInc = colInc[pass];
+ int sCol = startingCol[pass];
+ int val = (p.width - sCol + cInc - 1) / cInc;
+ int samples = val * filterOffset;
+ int rowSize = (val * bps)>>3;
+ int sRow = startingRow[pass];
+ if (p.height <= sRow || rowSize == 0) continue;
+ int sInc = rInc * p.width;
+ byte inbuf[] = new byte[rowSize];
+ int pix[] = new int[rowSize];
+ int upix[] = null;
+ int temp[] = new int[rowSize];
+ int nextY = sRow; // next Y value and number of rows to report to sendPixels
+ int rows = 0;
+ int rowStart = sRow * p.width;
+
+ for (int y = sRow; y < p.height; y += rInc, rowStart += sInc) {
+ rows += rInc;
+ int rowFilter = dis.read();
+ dis.readFully(inbuf);
+ if (!filterRow(inbuf, pix, upix, rowFilter, filterOffset)) throw new IOException("Unknown filter type: " + rowFilter);
+ insertPixels(pix, rowStart + sCol, samples);
+ if (multipass && (pass < 6)) blockFill(rowStart);
+ upix = pix;
+ pix = temp;
+ temp = upix;
+ }
+ if (!multipass) break;
+ }
+ while(dis.read() != -1) System.err.println("Leftover data encountered.");
+
+ // 24-bit color is our native format
+ if (colorType == 2 || colorType == 6) {
+ data = (int[])pixels;
+ if (colorType == 2) {
+ for(int i=0; i<data.length; i++)
+ data[i] |= 0xFF000000;
+ }
+
+ } else if (colorType == 3) {
+ byte[] pix = (byte[])pixels;
+ data = new int[pix.length];
+ for(int i=0; i<pix.length; i++) {
+ if (transparency) {
+ data[i] =
+ ((palette[4 * (pix[i] & 0xff) + 3] & 0xff) << 24) |
+ ((palette[4 * (pix[i] & 0xff) + 0] & 0xff) << 16) |
+ ((palette[4 * (pix[i] & 0xff) + 1] & 0xff) << 8) |
+ (palette[4 * (pix[i] & 0xff) + 2] & 0xff);
+ } else {
+ data[i] =
+ 0xFF000000 |
+ ((palette[3 * (pix[i] & 0xff) + 0] & 0xff) << 16) |
+ ((palette[3 * (pix[i] & 0xff) + 1] & 0xff) << 8) |
+ (palette[3 * (pix[i] & 0xff) + 2] & 0xff);
+ }
+ }
+
+ } else if (colorType == 0 || colorType == 4) {
+ if (depth == 16) depth = 8;
+ int[] pix = (int[])pixels;
+ data = new int[pix.length];
+ for(int i=0; i<pix.length; i ++) {
+ if (colorType == 0) {
+ int val = (pix[i] & 0xff) << (8 - depth);
+ data[i] =
+ 0xFF000000 |
+ (val << 16) |
+ (val << 8) |
+ val;
+ } else {
+ int alpha = (pix[i] & mask) << (8 - depth);
+ int val = ((pix[i] & smask) >> depth) << (8 - depth);
+ data[i] =
+ (alpha << 24) |
+ (val << 16) |
+ (val << 8) |
+ val;
+ }
+ }
+ }
+
+ }
+
+ private void insertGreyPixels(int pix[], int offset, int samples) {
+ int p = pix[0];
+ int ipix[] = ipixels;
+ int cInc = colInc[pass];
+ int rs = 0;
+
+ if (colorType == 0) {
+ switch (depth) {
+ case 1:
+ for (int j = 0; j < samples; j++, offset += cInc) {
+ if (rs != 0) rs--;
+ else { rs = 7; p = pix[j>>3]; }
+ ipix[offset] = (p>>rs) & 0x1;
+ }
+ break;
+ case 2:
+ for (int j = 0; j < samples; j++, offset += cInc) {
+ if (rs != 0) rs -= 2;
+ else { rs = 6; p = pix[j>>2]; }
+ ipix[offset] = (p>>rs) & 0x3;
+ }
+ break;
+ case 4:
+ for (int j = 0; j < samples; j++, offset += cInc) {
+ if (rs != 0) rs = 0;
+ else { rs = 4; p = pix[j>>1]; }
+ ipix[offset] = (p>>rs) & 0xf;
+ }
+ break;
+ case 8:
+ for (int j = 0; j < samples; offset += cInc) ipix[offset] = (byte) pix[j++];
+ break;
+ case 16:
+ samples = samples<<1;
+ for (int j = 0; j < samples; j += 2, offset += cInc) ipix[offset] = pix[j];
+ break;
+ default: break;
+ }
+ } else if (colorType == 4) {
+ if (depth == 8) {
+ for (int j = 0; j < samples; offset += cInc) ipix[offset] = (pix[j++]<<8) | pix[j++];
+ } else {
+ samples = samples<<1;
+ for (int j = 0; j < samples; j += 2, offset += cInc) ipix[offset] = (pix[j]<<8) | pix[j+=2];
+ }
+ }
+ }
+
+ private void insertPalettedPixels(int pix[], int offset, int samples) {
+ int rs = 0;
+ int p = pix[0];
+ byte bpix[] = bpixels;
+ int cInc = colInc[pass];
+
+ switch (depth) {
+ case 1:
+ for (int j = 0; j < samples; j++, offset += cInc) {
+ if (rs != 0) rs--;
+ else { rs = 7; p = pix[j>>3]; }
+ bpix[offset] = (byte) ((p>>rs) & 0x1);
+ }
+ break;
+ case 2:
+ for (int j = 0; j < samples; j++, offset += cInc) {
+ if (rs != 0) rs -= 2;
+ else { rs = 6; p = pix[j>>2]; }
+ bpix[offset] = (byte) ((p>>rs) & 0x3);
+ }
+ break;
+ case 4:
+ for (int j = 0; j < samples; j++, offset += cInc) {
+ if (rs != 0) rs = 0;
+ else { rs = 4; p = pix[j>>1]; }
+ bpix[offset] = (byte) ((p>>rs) & 0xf);
+ }
+ break;
+ case 8:
+ for (int j = 0; j < samples; j++, offset += cInc) bpix[offset] = (byte) pix[j];
+ break;
+ }
+ }
+
+ private void insertPixels(int pix[], int offset, int samples) {
+ switch (colorType) {
+ case 0:
+ case 4:
+ insertGreyPixels(pix, offset, samples);
+ break;
+ case 2: {
+ int j = 0;
+ int ipix[] = ipixels;
+ int cInc = colInc[pass];
+ if (depth == 8) {
+ for (j = 0; j < samples; offset += cInc)
+ ipix[offset] = (pix[j++]<<16) | (pix[j++]<<8) | pix[j++];
+ } else {
+ samples = samples<<1;
+ for (j = 0; j < samples; j += 2, offset += cInc)
+ ipix[offset] = (pix[j]<<16) | (pix[j+=2]<<8) | pix[j+=2];
+ }
+ break; }
+ case 3:
+ insertPalettedPixels(pix, offset, samples);
+ break;
+ case 6: {
+ int j = 0;
+ int ipix[] = ipixels;
+ int cInc = colInc[pass];
+ if (depth == 8) {
+ for (j = 0; j < samples; offset += cInc) {
+ ipix[offset] = (pix[j++]<<16) | (pix[j++]<<8) | pix[j++] |
+ (pix[j++]<<24);
+ }
+ } else {
+ samples = samples<<1;
+ for (j = 0; j < samples; j += 2, offset += cInc) {
+ ipix[offset] = (pix[j]<<16) | (pix[j+=2]<<8) | pix[j+=2] |
+ (pix[j+=2]<<24);
+ }
+ }
+ break; }
+ default:
+ break;
+ }
+ }
+
+ private void blockFill(int rowStart) {
+ int counter;
+ int dw = p.width;
+ int pass = this.pass;
+ int w = blockWidth[pass];
+ int sCol = startingCol[pass];
+ int cInc = colInc[pass];
+ int wInc = cInc - w;
+ int maxW = rowStart + dw - w;
+ int len;
+ int h = blockHeight[pass];
+ int maxH = rowStart + (dw * h);
+ int startPos = rowStart + sCol;
+ counter = startPos;
+
+ if (colorType == 3) {
+ byte bpix[] = bpixels;
+ byte pixel;
+ len = bpix.length;
+ for (; counter <= maxW;) {
+ int end = counter + w;
+ pixel = bpix[counter++];
+ for (; counter < end; counter++) bpix[counter] = pixel;
+ counter += wInc;
+ }
+ maxW += w;
+ if (counter < maxW)
+ for (pixel = bpix[counter++]; counter < maxW; counter++)
+ bpix[counter] = pixel;
+ if (len < maxH) maxH = len;
+ for (counter = startPos + dw; counter < maxH; counter += dw)
+ System.arraycopy(bpix, startPos, bpix, counter, dw - sCol);
+ } else {
+ int ipix[] = ipixels;
+ int pixel;
+ len = ipix.length;
+ for (; counter <= maxW;) {
+ int end = counter + w;
+ pixel = ipix[counter++];
+ for (; counter < end; counter++)
+ ipix[counter] = pixel;
+ counter += wInc;
+ }
+ maxW += w;
+ if (counter < maxW)
+ for (pixel = ipix[counter++]; counter < maxW; counter++)
+ ipix[counter] = pixel;
+ if (len < maxH) maxH = len;
+ for (counter = startPos + dw; counter < maxH; counter += dw)
+ System.arraycopy(ipix, startPos, ipix, counter, dw - sCol);
+ }
+ }
+
+ private boolean filterRow(byte inbuf[], int pix[], int upix[], int rowFilter, int boff) {
+ int rowWidth = pix.length;
+ switch (rowFilter) {
+ case 0: {
+ for (int x = 0; x < rowWidth; x++) pix[x] = 0xff & inbuf[x];
+ break; }
+ case 1: {
+ int x = 0;
+ for ( ; x < boff; x++) pix[x] = 0xff & inbuf[x];
+ for ( ; x < rowWidth; x++) pix[x] = 0xff & (inbuf[x] + pix[x - boff]);
+ break; }
+ case 2: {
+ if (upix != null) {
+ for (int x = 0; x < rowWidth; x++)
+ pix[x] = 0xff & (upix[x] + inbuf[x]);
+ } else {
+ for (int x = 0; x < rowWidth; x++)
+ pix[x] = 0xff & inbuf[x];
+ }
+ break; }
+ case 3: {
+ if (upix != null) {
+ int x = 0;
+ for ( ; x < boff; x++) {
+ int rval = upix[x];
+ pix[x] = 0xff & ((rval>>1) + inbuf[x]);
+ }
+ for ( ; x < rowWidth; x++) {
+ int rval = upix[x] + pix[x - boff];
+ pix[x] = 0xff & ((rval>>1) + inbuf[x]);
+ }
+ } else {
+ int x = 0;
+ for ( ; x < boff; x++) pix[x] = 0xff & inbuf[x];
+ for ( ; x < rowWidth; x++) {
+ int rval = pix[x - boff];
+ pix[x] = 0xff & ((rval>>1) + inbuf[x]);
+ }
+ }
+ break; }
+ case 4: {
+ if (upix != null) {
+ int x = 0;
+ for ( ; x < boff; x++) pix[x] = 0xff & (upix[x] + inbuf[x]);
+ for ( ; x < rowWidth; x++) {
+ int a, b, c, p, pa, pb, pc, rval;
+ a = pix[x - boff];
+ b = upix[x];
+ c = upix[x - boff];
+ p = a + b - c;
+ pa = p > a ? p - a : a - p;
+ pb = p > b ? p - b : b - p;
+ pc = p > c ? p - c : c - p;
+ if ((pa <= pb) && (pa <= pc)) rval = a;
+ else if (pb <= pc) rval = b;
+ else rval = c;
+ pix[x] = 0xff & (rval + inbuf[x]);
+ }
+ } else {
+ int x = 0;
+ for ( ; x < boff; x++) pix[x] = 0xff & inbuf[x];
+ for ( ; x < rowWidth; x++) {
+ int rval = pix[x - boff];
+ pix[x] = 0xff & (rval + inbuf[x]);
+ }
+ }
+ break; }
+ default: return false;
+ }
+ return true;
+ }
+
+ // Private Data ///////////////////////////////////////////////////////////////////////////////////////
+
+ private int target_offset = 0;
+ private int sigmask = 0xffff;
+ private Object pixels = null;
+ private int ipixels[] = null;
+ private byte bpixels[] = null;
+ private boolean multipass = false;
+ private boolean complete = false;
+ private boolean error = false;
+
+ int[] data = null;
+
+ private InputStream underlyingStream = null;
+ private DataInputStream inputStream = null;
+ private Thread controlThread = null;
+ private boolean infoAvailable = false;
+ private int updateDelay = 750;
+
+ // Image decoding state variables
+ private boolean headerFound = false;
+ private int compressionMethod = -1;
+ private int depth = -1;
+ private int colorType = -1;
+ private int filterMethod = -1;
+ private int interlaceMethod = -1;
+ private int pass = 0;
+ private byte palette[] = null;
+ private int mask = 0x0;
+ private int smask = 0x0;
+ private boolean transparency = false;
+
+ private int chunkLength = 0;
+ private int chunkType = 0;
+ private boolean needChunkInfo = true;
+
+ private static final int CHUNK_bKGD = 0x624B4744; // "bKGD"
+ private static final int CHUNK_cHRM = 0x6348524D; // "cHRM"
+ private static final int CHUNK_gAMA = 0x67414D41; // "gAMA"
+ private static final int CHUNK_hIST = 0x68495354; // "hIST"
+ private static final int CHUNK_IDAT = 0x49444154; // "IDAT"
+ private static final int CHUNK_IEND = 0x49454E44; // "IEND"
+ private static final int CHUNK_IHDR = 0x49484452; // "IHDR"
+ private static final int CHUNK_PLTE = 0x504C5445; // "PLTE"
+ private static final int CHUNK_pHYs = 0x70485973; // "pHYs"
+ private static final int CHUNK_sBIT = 0x73424954; // "sBIT"
+ private static final int CHUNK_tEXt = 0x74455874; // "tEXt"
+ private static final int CHUNK_tIME = 0x74494D45; // "tIME"
+ private static final int CHUNK_tRNS = 0x74524E53; // "tIME"
+ private static final int CHUNK_zTXt = 0x7A545874; // "zTXt"
+
+ private static final int startingRow[] = { 0, 0, 0, 4, 0, 2, 0, 1 };
+ private static final int startingCol[] = { 0, 0, 4, 0, 2, 0, 1, 0 };
+ private static final int rowInc[] = { 1, 8, 8, 8, 4, 4, 2, 2 };
+ private static final int colInc[] = { 1, 8, 8, 4, 4, 2, 2, 1 };
+ private static final int blockHeight[] = { 1, 8, 8, 4, 4, 2, 2, 1 };
+ private static final int blockWidth[] = { 1, 8, 4, 4, 2, 2, 1, 1 };
+
+ // Helper Classes ////////////////////////////////////////////////////////////////////
+
+ private static class MeteredInputStream extends FilterInputStream {
+ int bytesLeft;
+ int marked;
+
+ public MeteredInputStream(InputStream in, int size) {
+ super(in);
+ bytesLeft = size;
+ }
+
+ public final int read() throws IOException {
+ if (bytesLeft > 0) {
+ int val = in.read();
+ if (val != -1) bytesLeft--;
+ return val;
+ }
+ return -1;
+ }
+
+ public final int read(byte b[]) throws IOException {
+ return read(b, 0, b.length);
+ }
+
+ public final int read(byte b[], int off, int len) throws IOException {
+ if (bytesLeft > 0) {
+ len = (len > bytesLeft ? bytesLeft : len);
+ int read = in.read(b, off, len);
+ if (read > 0) bytesLeft -= read;
+ return read;
+ }
+ return -1;
+ }
+
+ public final long skip(long n) throws IOException {
+ n = (n > bytesLeft ? bytesLeft : n);
+ long skipped = in.skip(n);
+ if (skipped > 0) bytesLeft -= skipped;
+ return skipped;
+ }
+
+ public final int available() throws IOException {
+ int n = in.available();
+ return (n > bytesLeft ? bytesLeft : n);
+ }
+
+ public final void close() throws IOException { /* Eat this */ }
+
+ public final void mark(int readlimit) {
+ marked = bytesLeft;
+ in.mark(readlimit);
+ }
+
+ public final void reset() throws IOException {
+ in.reset();
+ bytesLeft = marked;
+ }
+
+ public final boolean markSupported() { return in.markSupported(); }
+ }
+
+ /** Support class, used to eat the IDAT headers dividing up the deflated stream */
+ private static class IDATEnumeration implements Enumeration {
+ InputStream underlyingStream;
+ PNG owner;
+ boolean firstStream = true;
+
+ public IDATEnumeration(PNG owner) {
+ this.owner = owner;
+ this.underlyingStream = owner.underlyingStream;
+ }
+
+ public Object nextElement() {
+ firstStream = false;
+ return new MeteredInputStream(underlyingStream, owner.chunkLength);
+ }
+
+ public boolean hasMoreElements() {
+ DataInputStream dis = new DataInputStream(underlyingStream);
+ if (!firstStream) {
+ try {
+ int crc = dis.readInt();
+ owner.needChunkInfo = false;
+ owner.chunkLength = dis.readInt();
+ owner.chunkType = dis.readInt();
+ } catch (IOException ioe) {
+ return false;
+ }
+ }
+ if (owner.chunkType == PNG.CHUNK_IDAT) return true;
+ return false;
+ }
+ }
+
+}
--- /dev/null
+// FIXME
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.graphics;
+import java.util.*;
+
+public abstract class Paint {
+ public abstract void fillTrapezoid(int tx1, int tx2, int ty1, int tx3, int tx4, int ty2, PixelBuffer buf);
+
+ public static class SingleColorPaint extends Paint {
+ int color;
+ public SingleColorPaint(int color) { this.color = color; }
+ public void fillTrapezoid(int x1, int x2, int y1, int x3, int x4, int y2, PixelBuffer buf) {
+ buf.fillTrapezoid(x1, x2, y1, x3, x4, y2, color);
+ }
+ }
+
+
+ /*
+ public static abstract class GradientPaint extends Paint {
+ public GradientPaint(boolean reflect, boolean repeat, Affine gradientTransform,
+ int[] stop_colors, float[] stop_offsets) {
+ this.reflect = reflect; this.repeat = repeat;
+ this.gradientTransform = gradientTransform;
+ this.stop_colors = stop_colors;
+ this.stop_offsets = stop_offsets;
+ }
+ Affine gradientTransform = Affine.identity();
+ boolean useBoundingBox = false; // FIXME not supported
+ boolean patternUseBoundingBox = false; // FIXME not supported
+
+ // it's invalid for both of these to be true
+ boolean reflect = false; // FIXME not supported
+ boolean repeat = false; // FIXME not supported
+ int[] stop_colors;
+ float[] stop_offsets;
+
+ public void fillTrapezoid(float tx1, float tx2, float ty1, float tx3, float tx4, float ty2, PixelBuffer buf) {
+ Affine a = buf.a;
+ Affine inverse = a.copy().invert();
+ float slope1 = (tx3 - tx1) / (ty2 - ty1);
+ float slope2 = (tx4 - tx2) / (ty2 - ty1);
+ for(float y=ty1; y<ty2; y++) {
+ float _x1 = (y - ty1) * slope1 + tx1;
+ float _x2 = (y - ty1) * slope2 + tx2;
+ if (_x1 > _x2) { float _x0 = _x1; _x1 = _x2; _x2 = _x0; }
+
+ for(float x=_x1; x<_x2; x++) {
+
+ float distance = isLinear ?
+ // length of projection of <x,y> onto the gradient vector == {<x,y> \dot {grad \over |grad|}}
+ (x * (x2 - x1) + y * (y2 - y1)) / (float)Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)) :
+
+ // radial form is simple! FIXME, not quite right
+ (float)Math.sqrt((x - cx) * (x - cx) + (y - cy) * (y - cy));
+
+ // FIXME: offsets are 0..1, not 0..length(gradient)
+ int i = 0; for(; i<stop_offsets.length; i++) if (distance < stop_offsets[i]) break;
+
+ // FIXME: handle points beyond the bounds
+ if (i < 0 || i >= stop_offsets.length) continue;
+
+ // gradate from offsets[i - 1] to offsets[i]
+ float percentage = ((distance - stop_offsets[i - 1]) / (stop_offsets[i] - stop_offsets[i - 1]));
+
+ int a = (int)((((stop_colors[i] >> 24) & 0xff) - ((stop_colors[i - 1] >> 24) & 0xff)) * percentage) +
+ ((stop_colors[i - 1] >> 24) & 0xff);
+ int r = (int)((((stop_colors[i] >> 16) & 0xff) - ((stop_colors[i - 1] >> 16) & 0xff)) * percentage) +
+ ((stop_colors[i - 1] >> 16) & 0xff);
+ int g = (int)((((stop_colors[i] >> 8) & 0xff) - ((stop_colors[i - 1] >> 8) & 0xff)) * percentage) +
+ ((stop_colors[i - 1] >> 8) & 0xff);
+ int b = (int)((((stop_colors[i] >> 0) & 0xff) - ((stop_colors[i - 1] >> 0) & 0xff)) * percentage) +
+ ((stop_colors[i - 1] >> 0) & 0xff);
+ int argb = (a << 24) | (r << 16) | (g << 8) | b;
+ buf.drawPoint((int)x, (int)Math.floor(y), argb);
+ }
+ }
+ }
+ }
+
+ public static class LinearGradientPaint extends GradientPaint {
+ public LinearGradientPaint(float x1, float y1, float x2, float y2, boolean reflect, boolean repeat,
+ Affine gradientTransform, int[] stop_colors, float[] stop_offsets) {
+ super(reflect, repeat, gradientTransform, stop_colors, stop_offsets);
+ this.x1 = x1; this.x2 = x2; this.y1 = y1; this.y2 = y2;
+ }
+ float x1 = 0, y1 = 0, x2 = 300, y2 = 300;
+ }
+
+ public static class RadialGradientPaint extends GradientPaint {
+ public RadialGradientPaint(float cx, float cy, float fx, float fy, float r, boolean reflect, boolean repeat,
+ Affine gradientTransform, int[] stop_colors, float[] stop_offsets) {
+ super(reflect, repeat, gradientTransform, stop_colors, stop_offsets);
+ this.cx = cx; this.cy = cy; this.fx = fx; this.fy = fy; this.r = r;
+ }
+
+ float cx, cy, r, fx, fy;
+
+ }
+ */
+
+
+}
--- /dev/null
+// FIXME
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.graphics;
+import java.util.*;
+
+/** an abstract path; may contain splines and arcs */
+public class Path {
+
+ public static final float PX_PER_INCH = 72;
+ public static final float INCHES_PER_CM = (float)0.3937;
+ public static final float INCHES_PER_MM = INCHES_PER_CM / 10;
+ private static final int DEFAULT_PATHLEN = 1000;
+ private static final float PI = (float)Math.PI;
+
+ // the number of vertices on this path
+ int numvertices = 0;
+
+ // the vertices of the path
+ float[] x = new float[DEFAULT_PATHLEN];
+ float[] y = new float[DEFAULT_PATHLEN];
+
+ // the type of each edge; type[i] is the type of the edge from x[i],y[i] to x[i+1],y[i+1]
+ byte[] type = new byte[DEFAULT_PATHLEN];
+
+ // bezier control points
+ float[] c1x = new float[DEFAULT_PATHLEN]; // or rx (arcto)
+ float[] c1y = new float[DEFAULT_PATHLEN]; // or ry (arcto)
+ float[] c2x = new float[DEFAULT_PATHLEN]; // or x-axis-rotation (arcto)
+ float[] c2y = new float[DEFAULT_PATHLEN]; // or large-arc << 1 | sweep (arcto)
+
+ boolean closed = false;
+
+ static final byte TYPE_MOVETO = 0;
+ static final byte TYPE_LINETO = 1;
+ static final byte TYPE_ARCTO = 2;
+ static final byte TYPE_CUBIC = 3;
+ static final byte TYPE_QUADRADIC = 4;
+
+ public static Path parse(String s) { return Tokenizer.parse(s); }
+
+ // FIXME: hack
+ private String toString;
+ private Path(String s) { this.toString = s; }
+ public String toString() { return toString; }
+
+ public static class Tokenizer {
+ // FIXME: check array bounds exception for improperly terminated string
+ String s;
+ int i = 0;
+ char lastCommand = 'M';
+ public Tokenizer(String s) { this.s = s; }
+
+ public static Path parse(String s) {
+ if (s == null) return null;
+ Tokenizer t = new Tokenizer(s);
+ Path ret = new Path(s);
+ char last_command = 'M';
+ boolean first = true;
+ while(t.hasMoreTokens()) {
+ char command = t.parseCommand();
+ if (first && command != 'M') throw new RuntimeException("the first command of a path must be 'M'");
+ first = false;
+ boolean relative = Character.toLowerCase(command) == command;
+ command = Character.toLowerCase(command);
+ ret.parseSingleCommandAndArguments(t, command, relative);
+ last_command = command;
+ }
+ return ret;
+ }
+
+ private void consumeWhitespace() {
+ while(i < s.length() && (Character.isWhitespace(s.charAt(i)))) i++;
+ if (i < s.length() && s.charAt(i) == ',') i++;
+ while(i < s.length() && (Character.isWhitespace(s.charAt(i)))) i++;
+ }
+ public boolean hasMoreTokens() { consumeWhitespace(); return i < s.length(); }
+ public char parseCommand() {
+ consumeWhitespace();
+ char c = s.charAt(i);
+ if (!Character.isLetter(c)) return lastCommand;
+ i++;
+ return lastCommand = c;
+ }
+ public float parseFloat() {
+ consumeWhitespace();
+ int start = i;
+ float multiplier = 1;
+ for(; i < s.length(); i++) {
+ char c = s.charAt(i);
+ if (Character.isWhitespace(c) || c == ',' || (c == '-' && i != start)) break;
+ if (!((c >= '0' && c <= '9') || c == '.' || c == 'e' || c == 'E' || c == '-')) {
+ if (c == '%') { // FIXME
+ } else if (s.regionMatches(i, "pt", 0, i+2)) { // FIXME
+ } else if (s.regionMatches(i, "em", 0, i+2)) { // FIXME
+ } else if (s.regionMatches(i, "pc", 0, i+2)) { // FIXME
+ } else if (s.regionMatches(i, "ex", 0, i+2)) { // FIXME
+ } else if (s.regionMatches(i, "mm", 0, i+2)) { i += 2; multiplier = INCHES_PER_MM * PX_PER_INCH; break;
+ } else if (s.regionMatches(i, "cm", 0, i+2)) { i += 2; multiplier = INCHES_PER_CM * PX_PER_INCH; break;
+ } else if (s.regionMatches(i, "in", 0, i+2)) { i += 2; multiplier = PX_PER_INCH; break;
+ } else if (s.regionMatches(i, "px", 0, i+2)) { i += 2; break;
+ } else if (Character.isLetter(c)) break;
+ throw new RuntimeException("didn't expect character \"" + c + "\" in a numeric constant");
+ }
+ }
+ if (start == i) throw new RuntimeException("FIXME");
+ return Float.parseFloat(s.substring(start, i)) * multiplier;
+ }
+ }
+
+ /** Creates a concrete vector path transformed through the given matrix. */
+ public Raster realize(Affine a) {
+
+ Raster ret = new Raster();
+ int NUMSTEPS = 5; // FIXME
+ ret.numvertices = 1;
+ ret.x[0] = (int)Math.round(a.multiply_px(x[0], y[0]));
+ ret.y[0] = (int)Math.round(a.multiply_py(x[0], y[0]));
+
+ for(int i=1; i<numvertices; i++) {
+ if (type[i] == TYPE_LINETO) {
+ float rx = x[i];
+ float ry = y[i];
+ ret.x[ret.numvertices] = (int)Math.round(a.multiply_px(rx, ry));
+ ret.y[ret.numvertices] = (int)Math.round(a.multiply_py(rx, ry));
+ ret.edges[ret.numedges++] = ret.numvertices - 1; ret.numvertices++;
+
+ } else if (type[i] == TYPE_MOVETO) {
+ float rx = x[i];
+ float ry = y[i];
+ ret.x[ret.numvertices] = (int)Math.round(a.multiply_px(rx, ry));
+ ret.y[ret.numvertices] = (int)Math.round(a.multiply_py(rx, ry));
+ ret.numvertices++;
+
+ } else if (type[i] == TYPE_ARCTO) {
+ float rx = c1x[i];
+ float ry = c1y[i];
+ float phi = c2x[i];
+ float fa = ((int)c2y[i]) >> 1;
+ float fs = ((int)c2y[i]) & 1;
+ float x1 = x[i];
+ float y1 = y[i];
+ float x2 = x[i+1];
+ float y2 = y[i+1];
+
+ // F.6.5: given x1,y1,x2,y2,fa,fs, compute cx,cy,theta1,dtheta
+ float x1_ = (float)Math.cos(phi) * (x1 - x2) / 2 + (float)Math.sin(phi) * (y1 - y2) / 2;
+ float y1_ = -1 * (float)Math.sin(phi) * (x1 - x2) / 2 + (float)Math.cos(phi) * (y1 - y2) / 2;
+ float tmp = (float)Math.sqrt((rx * rx * ry * ry - rx * rx * y1_ * y1_ - ry * ry * x1_ * x1_) /
+ (rx * rx * y1_ * y1_ + ry * ry * x1_ * x1_));
+ float cx_ = (fa == fs ? -1 : 1) * tmp * (rx * y1_ / ry);
+ float cy_ = (fa == fs ? -1 : 1) * -1 * tmp * (ry * x1_ / rx);
+ float cx = (float)Math.cos(phi) * cx_ - (float)Math.sin(phi) * cy_ + (x1 + x2) / 2;
+ float cy = (float)Math.sin(phi) * cx_ + (float)Math.cos(phi) * cy_ + (y1 + y2) / 2;
+
+ // F.6.4 Conversion from center to endpoint parameterization
+ float ux = 1, uy = 0, vx = (x1_ - cx_) / rx, vy = (y1_ - cy_) / ry;
+ float det = ux * vy - uy * vx;
+ float theta1 = (det < 0 ? -1 : 1) *
+ (float)Math.acos((ux * vx + uy * vy) /
+ ((float)Math.sqrt(ux * ux + uy * uy) * (float)Math.sqrt(vx * vx + vy * vy)));
+ ux = (x1_ - cx_) / rx; uy = (y1_ - cy_) / ry;
+ vx = (-1 * x1_ - cx_) / rx; vy = (-1 * y1_ - cy_) / ry;
+ det = ux * vy - uy * vx;
+ float dtheta = (det < 0 ? -1 : 1) *
+ (float)Math.acos((ux * vx + uy * vy) /
+ ((float)Math.sqrt(ux * ux + uy * uy) * (float)Math.sqrt(vx * vx + vy * vy)));
+ dtheta = dtheta % (float)(2 * Math.PI);
+
+ if (fs == 0 && dtheta > 0) theta1 -= 2 * PI;
+ if (fs == 1 && dtheta < 0) theta1 += 2 * PI;
+
+ if (fa == 1 && dtheta < 0) dtheta = 2 * PI + dtheta;
+ else if (fa == 1 && dtheta > 0) dtheta = -1 * (2 * PI - dtheta);
+
+ // FIXME: integrate F.6.6
+ // FIXME: isn't quite ending where it should...
+
+ // F.6.3: Parameterization alternatives
+ float theta = theta1;
+ for(int j=0; j<NUMSTEPS; j++) {
+ float rasterx = rx * (float)Math.cos(theta) * (float)Math.cos(phi) -
+ ry * (float)Math.sin(theta) * (float)Math.sin(phi) + cx;
+ float rastery = rx * (float)Math.cos(theta) * (float)Math.sin(phi) +
+ ry * (float)Math.cos(phi) * (float)Math.sin(theta) + cy;
+ ret.x[ret.numvertices] = (int)Math.round(a.multiply_px(rasterx, rastery));
+ ret.y[ret.numvertices] = (int)Math.round(a.multiply_py(rasterx, rastery));
+ ret.edges[ret.numedges++] = ret.numvertices - 1; ret.numvertices++;
+ theta += dtheta / NUMSTEPS;
+ }
+
+ } else if (type[i] == TYPE_CUBIC) {
+
+ float ax = x[i+1] - 3 * c2x[i] + 3 * c1x[i] - x[i];
+ float bx = 3 * c2x[i] - 6 * c1x[i] + 3 * x[i];
+ float cx = 3 * c1x[i] - 3 * x[i];
+ float dx = x[i];
+ float ay = y[i+1] - 3 * c2y[i] + 3 * c1y[i] - y[i];
+ float by = 3 * c2y[i] - 6 * c1y[i] + 3 * y[i];
+ float cy = 3 * c1y[i] - 3 * y[i];
+ float dy = y[i];
+
+ for(float t=0; t<1; t += 1 / (float)NUMSTEPS) {
+ float rx = ax * t * t * t + bx * t * t + cx * t + dx;
+ float ry = ay * t * t * t + by * t * t + cy * t + dy;
+ ret.x[ret.numvertices] = (int)Math.round(a.multiply_px(rx, ry));
+ ret.y[ret.numvertices] = (int)Math.round(a.multiply_py(rx, ry));
+ ret.edges[ret.numedges++] = ret.numvertices - 1; ret.numvertices++;
+ }
+
+
+ } else if (type[i] == TYPE_QUADRADIC) {
+
+ float bx = x[i+1] - 2 * c1x[i] + x[i];
+ float cx = 2 * c1x[i] - 2 * x[i];
+ float dx = x[i];
+ float by = y[i+1] - 2 * c1y[i] + y[i];
+ float cy = 2 * c1y[i] - 2 * y[i];
+ float dy = y[i];
+
+ for(float t=0; t<1; t += 1 / (float)NUMSTEPS) {
+ float rx = bx * t * t + cx * t + dx;
+ float ry = by * t * t + cy * t + dy;
+ ret.x[ret.numvertices] = (int)Math.round(a.multiply_px(rx, ry));
+ ret.y[ret.numvertices] = (int)Math.round(a.multiply_py(rx, ry));
+ ret.edges[ret.numedges++] = ret.numvertices - 1; ret.numvertices++;
+ }
+
+ }
+
+ }
+
+ if (ret.numedges > 0) ret.sort(0, ret.numedges - 1, false);
+ return ret;
+ }
+
+ protected void parseSingleCommandAndArguments(Tokenizer t, char command, boolean relative) {
+ if (numvertices == 0 && command != 'm') throw new RuntimeException("first command MUST be an 'm'");
+ if (numvertices > x.length - 2) {
+ float[] new_x = new float[x.length * 2]; System.arraycopy(x, 0, new_x, 0, x.length); x = new_x;
+ float[] new_y = new float[y.length * 2]; System.arraycopy(y, 0, new_y, 0, y.length); y = new_y;
+ }
+ switch(command) {
+ case 'z': {
+ int where;
+ type[numvertices-1] = TYPE_LINETO;
+ for(where = numvertices - 1; where > 0; where--)
+ if (type[where - 1] == TYPE_MOVETO) break;
+ x[numvertices] = x[where];
+ y[numvertices] = y[where];
+ numvertices++;
+ closed = true;
+ break;
+ }
+
+ case 'm': {
+ if (numvertices > 0) type[numvertices-1] = TYPE_MOVETO;
+ x[numvertices] = t.parseFloat() + (relative ? x[numvertices - 1] : 0);
+ y[numvertices] = t.parseFloat() + (relative ? y[numvertices - 1] : 0);
+ numvertices++;
+ break;
+ }
+
+ case 'l': case 'h': case 'v': {
+ type[numvertices-1] = TYPE_LINETO;
+ float first = t.parseFloat(), second;
+ if (command == 'h') {
+ second = relative ? 0 : y[numvertices - 1];
+ } else if (command == 'v') {
+ second = first; first = relative ? 0 : x[numvertices - 1];
+ } else {
+ second = t.parseFloat();
+ }
+ x[numvertices] = first + (relative ? x[numvertices - 1] : 0);
+ y[numvertices] = second + (relative ? y[numvertices - 1] : 0);
+ numvertices++;
+ break;
+ }
+
+ case 'a': {
+ type[numvertices-1] = TYPE_ARCTO;
+ c1x[numvertices-1] = t.parseFloat() + (relative ? x[numvertices - 1] : 0);
+ c1y[numvertices-1] = t.parseFloat() + (relative ? y[numvertices - 1] : 0);
+ c2x[numvertices-1] = (t.parseFloat() / 360) * 2 * PI;
+ c2y[numvertices-1] = (((int)t.parseFloat()) << 1) | (int)t.parseFloat();
+ x[numvertices] = t.parseFloat() + (relative ? x[numvertices - 1] : 0);
+ y[numvertices] = t.parseFloat() + (relative ? y[numvertices - 1] : 0);
+ numvertices++;
+ break;
+ }
+
+ case 's': case 'c': {
+ type[numvertices-1] = TYPE_CUBIC;
+ if (command == 'c') {
+ c1x[numvertices-1] = t.parseFloat() + (relative ? x[numvertices - 1] : 0);
+ c1y[numvertices-1] = t.parseFloat() + (relative ? y[numvertices - 1] : 0);
+ } else if (numvertices > 1 && type[numvertices-2] == TYPE_CUBIC) {
+ c1x[numvertices-1] = 2 * x[numvertices - 1] - c2x[numvertices-2];
+ c1y[numvertices-1] = 2 * y[numvertices - 1] - c2y[numvertices-2];
+ } else {
+ c1x[numvertices-1] = x[numvertices-1];
+ c1y[numvertices-1] = y[numvertices-1];
+ }
+ c2x[numvertices-1] = t.parseFloat() + (relative ? x[numvertices - 1] : 0);
+ c2y[numvertices-1] = t.parseFloat() + (relative ? y[numvertices - 1] : 0);
+ x[numvertices] = t.parseFloat() + (relative ? x[numvertices - 1] : 0);
+ y[numvertices] = t.parseFloat() + (relative ? y[numvertices - 1] : 0);
+ numvertices++;
+ break;
+ }
+
+ case 't': case 'q': {
+ type[numvertices-1] = TYPE_QUADRADIC;
+ if (command == 'q') {
+ c1x[numvertices-1] = t.parseFloat() + (relative ? x[numvertices - 1] : 0);
+ c1y[numvertices-1] = t.parseFloat() + (relative ? y[numvertices - 1] : 0);
+ } else if (numvertices > 1 && type[numvertices-2] == TYPE_QUADRADIC) {
+ c1x[numvertices-1] = 2 * x[numvertices - 1] - c1x[numvertices-2];
+ c1y[numvertices-1] = 2 * y[numvertices - 1] - c1y[numvertices-2];
+ } else {
+ c1x[numvertices-1] = x[numvertices-1];
+ c1y[numvertices-1] = y[numvertices-1];
+ }
+ x[numvertices] = t.parseFloat() + (relative ? x[numvertices - 1] : 0);
+ y[numvertices] = t.parseFloat() + (relative ? y[numvertices - 1] : 0);
+ numvertices++;
+ break;
+ }
+
+ default:
+ // FIXME
+ }
+
+ /*
+ // invariant: after this loop, no two lines intersect other than at a vertex
+ // FIXME: cleanup
+ int index = numvertices - 2;
+ for(int i=0; i<Math.min(numvertices - 3, index); i++) {
+ for(int j = index; j < numvertices - 1; j++) {
+
+ // I'm not sure how to deal with vertical lines...
+ if (x[i+1] == x[i] || x[j+1] == x[j]) continue;
+
+ float islope = (y[i+1] - y[i]) / (x[i+1] - x[i]);
+ float jslope = (y[j+1] - y[j]) / (x[j+1] - x[j]);
+ if (islope == jslope) continue; // parallel lines can't intersect
+
+ float _x = (islope * x[i] - jslope * x[j] + y[j] - y[i]) / (islope - jslope);
+ float _y = islope * (_x - x[i]) + y[i];
+
+ if (_x > Math.min(x[i+1], x[i]) && _x < Math.max(x[i+1], x[i]) &&
+ _x > Math.min(x[j+1], x[j]) && _x < Math.max(x[j+1], x[j])) {
+ // FIXME: something's not right in here. See if we can do without fracturing line 'i'.
+ for(int k = ++numvertices; k>i; k--) { x[k] = x[k - 1]; y[k] = y[k - 1]; }
+ x[i+1] = _x;
+ y[i+1] = _y;
+ x[numvertices] = x[numvertices - 1]; x[numvertices - 1] = _x;
+ y[numvertices] = y[numvertices - 1]; y[numvertices - 1] = _y;
+ edges[numedges++] = numvertices - 1; numvertices++;
+ index++;
+ break; // actually 'continue' the outermost loop
+ }
+ }
+ }
+ */
+
+ }
+
+
+ // Rasterized Vector Path //////////////////////////////////////////////////////////////////////////////
+
+ /** a vector path */
+ public static class Raster {
+
+ // the vertices of this path
+ int[] x = new int[DEFAULT_PATHLEN];
+ int[] y = new int[DEFAULT_PATHLEN];
+ int numvertices = 0;
+
+ /**
+ * A list of the vertices on this path which *start* an *edge* (rather than a moveto), sorted by increasing y.
+ * example: x[edges[1]],y[edges[1]] - x[edges[i]+1],y[edges[i]+1] is the second-topmost edge
+ * note that if x[i],y[i] - x[i+1],y[i+1] is a MOVETO, then no element in edges will be equal to i
+ */
+ int[] edges = new int[DEFAULT_PATHLEN];
+ int numedges = 0;
+
+ /** translate a rasterized path */
+ public void translate(int dx, int dy) { for(int i=0; i<numvertices; i++) { x[i] += dx; y[i] += dy; } }
+
+ /** simple quicksort, from http://sourceforge.net/snippet/detail.php?type=snippet&id=100240 */
+ int sort(int left, int right, boolean partition) {
+ if (partition) {
+ int i, j, middle;
+ middle = (left + right) / 2;
+ int s = edges[right]; edges[right] = edges[middle]; edges[middle] = s;
+ for (i = left - 1, j = right; ; ) {
+ while (y[edges[++i]] < y[edges[right]]);
+ while (j > left && y[edges[--j]] > y[edges[right]]);
+ if (i >= j) break;
+ s = edges[i]; edges[i] = edges[j]; edges[j] = s;
+ }
+ s = edges[right]; edges[right] = edges[i]; edges[i] = s;
+ return i;
+ } else {
+ if (left >= right) return 0;
+ int p = sort(left, right, true);
+ sort(left, p - 1, false);
+ sort(p + 1, right, false);
+ return 0;
+ }
+ }
+
+ /** finds the x value at which the line intercepts the line y=_y */
+ private int intercept(int i, float _y, boolean includeTop, boolean includeBottom) {
+ if (includeTop ? (_y < Math.min(y[i], y[i+1])) : (_y <= Math.min(y[i], y[i+1])))
+ return Integer.MIN_VALUE;
+ if (includeBottom ? (_y > Math.max(y[i], y[i+1])) : (_y >= Math.max(y[i], y[i+1])))
+ return Integer.MIN_VALUE;
+ return (int)Math.round((((float)(x[i + 1] - x[i])) /
+ ((float)(y[i + 1] - y[i])) ) * ((float)(_y - y[i])) + x[i]);
+ }
+
+ /** fill the interior of the path */
+ public void fill(PixelBuffer buf, Paint paint) {
+ if (numedges == 0) return;
+ int y0 = y[edges[0]], y1 = y0;
+ boolean useEvenOdd = false;
+
+ // we iterate over all endpoints in increasing y-coordinate order
+ for(int index = 1; index<numedges; index++) {
+ int count = 0;
+
+ // we now examine the horizontal band between y=y0 and y=y1
+ y0 = y1;
+ y1 = y[edges[index]];
+ if (y0 == y1) continue;
+
+ // within this band, we iterate over all edges
+ int x0 = Integer.MIN_VALUE;
+ int leftSegment = -1;
+ while(true) {
+ int x1 = Integer.MAX_VALUE;
+ int rightSegment = Integer.MAX_VALUE;
+ for(int i=0; i<numedges; i++) {
+ if (y[edges[i]] == y[edges[i]+1]) continue; // ignore horizontal lines; they are irrelevant.
+ // we order the segments by the x-coordinate of their midpoint;
+ // since segments cannot intersect, this is a well-ordering
+ int i0 = intercept(edges[i], y0, true, false);
+ int i1 = intercept(edges[i], y1, false, true);
+ if (i0 == Integer.MIN_VALUE || i1 == Integer.MIN_VALUE) continue;
+ int midpoint = i0 + i1;
+ if (midpoint < x0) continue;
+ if (midpoint == x0 && i <= leftSegment) continue;
+ if (midpoint > x1) continue;
+ if (midpoint == x1 && i >= rightSegment) continue;
+ rightSegment = i;
+ x1 = midpoint;
+ }
+ if (leftSegment == rightSegment || rightSegment == Integer.MAX_VALUE) break;
+ if (leftSegment != -1)
+ if ((useEvenOdd && count % 2 != 0) || (!useEvenOdd && count != 0))
+ paint.fillTrapezoid(intercept(edges[leftSegment], y0, true, true),
+ intercept(edges[rightSegment], y0, true, true), y0,
+ intercept(edges[leftSegment], y1, true, true),
+ intercept(edges[rightSegment], y1, true, true), y1,
+ buf);
+ if (useEvenOdd) count++;
+ else count += (y[edges[rightSegment]] < y[edges[rightSegment]+1]) ? -1 : 1;
+ leftSegment = rightSegment; x0 = x1;
+ }
+ }
+ }
+
+ /** stroke the outline of the path */
+ public void stroke(PixelBuffer buf, int width, int color) { stroke(buf, width, color, null, 0, 0); }
+ public void stroke(PixelBuffer buf, int width, int color, String dashArray, int dashOffset, float segLength) {
+
+ if (dashArray == null) {
+ for(int i=0; i<numedges; i++)
+ buf.drawLine((int)x[edges[i]],
+ (int)y[edges[i]], (int)x[edges[i]+1], (int)y[edges[i]+1], width, color, false);
+ return;
+ }
+
+ float ratio = 1;
+ if (segLength > 0) {
+ float actualLength = 0;
+ for(int i=0; i<numvertices; i++) {
+ // skip over MOVETOs -- they do not contribute to path length
+ if (x[i] == x[i+1] && y[i] == y[i+1]) continue;
+ if (x[i+1] == x[i+2] && y[i+1] == y[i+2]) continue;
+ int x1 = x[i];
+ int x2 = x[i + 1];
+ int y1 = y[i];
+ int y2 = y[i + 1];
+ actualLength += java.lang.Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
+ }
+ ratio = actualLength / segLength;
+ }
+ Tokenizer pt = new Tokenizer(dashArray);
+ Vector v = new Vector();
+ while (pt.hasMoreTokens()) v.addElement(new Float(pt.parseFloat()));
+ float[] dashes = new float[v.size() % 2 == 0 ? v.size() : 2 * v.size()];
+ for(int i=0; i<dashes.length; i++) dashes[i] = ((Float)v.elementAt(i % v.size())).floatValue();
+ int dashpos = dashOffset;
+ boolean on = dashpos % 2 == 0;
+ for(int i=0; i<numvertices; i++) {
+ // skip over MOVETOs -- they do not contribute to path length
+ if (x[i] == x[i+1] && y[i] == y[i+1]) continue;
+ if (x[i+1] == x[i+2] && y[i+1] == y[i+2]) continue;
+ int x1 = (int)x[i];
+ int x2 = (int)x[i + 1];
+ int y1 = (int)y[i];
+ int y2 = (int)y[i + 1];
+ float segmentLength = (float)java.lang.Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
+ int _x1 = x1, _y1 = y1;
+ float pos = 0;
+ do {
+ pos = Math.min(segmentLength, pos + dashes[dashpos] * ratio);
+ if (pos != segmentLength) dashpos = (dashpos + 1) % dashes.length;
+ int _x2 = (int)((x2 * pos + x1 * (segmentLength - pos)) / segmentLength);
+ int _y2 = (int)((y2 * pos + y1 * (segmentLength - pos)) / segmentLength);
+ if (on) buf.drawLine(_x1, _y1, _x2, _y2, width, color, false);
+ on = !on;
+ _x1 = _x2; _y1 = _y2;
+ } while(pos < segmentLength);
+ }
+ }
+
+ // FEATURE: make this faster and cache it; also deal with negative coordinates
+ public int boundingBoxWidth() {
+ int ret = 0;
+ for(int i=0; i<numvertices; i++) ret = Math.max(ret, x[i]);
+ return ret;
+ }
+
+ // FEATURE: make this faster and cache it; also deal with negative coordinates
+ public int boundingBoxHeight() {
+ int ret = 0;
+ for(int i=0; i<numvertices; i++) ret = Math.max(ret, y[i]);
+ return ret;
+ }
+ }
+}
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.graphics;
+import java.io.*;
+import org.ibex.js.*;
+import org.ibex.plat.*;
+import org.ibex.util.*;
+import org.ibex.core.*;
+
+/**
+ * The in-memory representation of a PNG or GIF image. It is
+ * read-only. It is usually passed to PixelBuffer.drawPicture()
+ *
+ * Implementations of the Platform class should return objects
+ * supporting this interface from the createPicture() method. These
+ * implementations may choose to implement caching strategies (for
+ * example, using a Pixmap on X11).
+ */
+public class Picture {
+
+ public Picture() { this.stream = null; }
+ public Picture(JS r) { this.stream = r; }
+ private static Cache cache = new Cache(100); ///< Picture, keyed by the Stream that loaded them
+
+ public JS stream = null; ///< the stream we were loaded from
+ public int width = -1; ///< the width of the image
+ public int height = -1; ///< the height of the image
+ public int[] data = null; ///< argb samples
+ public boolean isLoaded = false; ///< true iff the image is fully loaded
+
+ /** invoked when an image is fully loaded; subclasses can use this to initialize platform-specific constructs */
+ protected void loaded() { isLoaded = true; }
+
+ /** turns a stream into a Picture.Source and passes it to the callback */
+ public static Picture load(final JS stream, final Task callback) {
+ Picture ret = (Picture)cache.get(stream);
+ if (ret == null) cache.put(stream, ret = Platform.createPicture(stream));
+ final Picture p = ret;
+ if (!ret.isLoaded && callback != null) {
+ final Ibex.Blessing b = Ibex.Blessing.getBlessing(stream);
+ new java.lang.Thread() { public void run() {
+ InputStream in = null;
+ try {
+ in = b == null ? Stream.getInputStream(stream) : b.getImage();
+ } catch (IOException e) { Log.error(Picture.class, e);
+ } catch (JSExn e) { Log.error(Picture.class, e);
+ }
+ if (in == null) { Log.warn(Picture.class, "couldn't load image for stream " + stream.unclone()); return; }
+ try {
+ PushbackInputStream pbis = new PushbackInputStream(in);
+ int firstByte = pbis.read();
+ if (firstByte == -1) throw new JSExn("empty stream reading image");
+ pbis.unread(firstByte);
+ if ((firstByte & 0xff) == 'G') GIF.load(pbis, p);
+ else if ((firstByte & 0xff) == 137) PNG.load(pbis, p);
+ else if ((firstByte & 0xff) == 0xff) Platform.decodeJPEG(pbis, p);
+ else throw new JSExn("couldn't figure out image type from first byte");
+ p.loaded();
+ Scheduler.add(callback);
+ } catch (Exception e) {
+ Log.info(this, "exception while loading image");
+ Log.info(this, e);
+ }
+ } }.start();
+ }
+ return ret;
+ }
+}
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.graphics;
+
+/**
+ * <p>
+ * A block of pixels which can be drawn on.
+ * </p>
+ *
+ * <p>
+ * Implementations of the Platform class should return objects
+ * supporting this interface from the _createPixelBuffer()
+ * method. These implementations may choose to use off-screen video
+ * ram for this purpose (for example, a Pixmap on X11).
+ * </p>
+ *
+ * <p>
+ * Many of these functions come in pairs, one that uses ints and one
+ * that uses floats. The int functions are intended for situations
+ * in which the CTM is the identity transform.
+ * </p>
+ */
+public abstract class PixelBuffer {
+
+ /** draw the picture at (dx1, dy1), cropping to (cx1, cy1, cx2, cy2) */
+ public abstract void drawPicture(Picture source, int dx1, int dy1, int cx1, int cy1, int cx2, int cy2);
+
+ /** fill a trapezoid whose top and bottom edges are horizontal */
+ public abstract void fillTrapezoid(int x1, int x2, int y1, int x3, int x4, int y2, int color);
+
+ /**
+ * Same as drawPicture, but only uses the alpha channel of the Picture, and is allowed to destructively modify the RGB
+ * channels of the Picture in the process. This method may assume that the RGB channels of the image are all zero IFF it
+ * restores this invariant before returning.
+ */
+ public abstract void drawGlyph(Font.Glyph source, int dx1, int dy1, int cx1, int cy1, int cx2, int cy2, int rgb);
+
+ // FEATURE: we want floats (inter-pixel spacing) for antialiasing, but this hoses the fastpath line drawing... argh!
+ /** draws a line of width <tt>w</tt>; note that the coordinates here are <i>post-transform</i> */
+ public void drawLine(int x1, int y1, int x2, int y2, int w, int color, boolean capped) {
+
+ if (y1 > y2) { int t = x1; x1 = x2; x2 = t; t = y1; y1 = y2; y2 = t; }
+
+ if (x1 == x2) {
+ fillTrapezoid(x1 - w / 2, x2 + w / 2, y1 - (capped ? w / 2 : 0),
+ x1 - w / 2, x2 + w / 2, y2 + (capped ? w / 2 : 0), color);
+ return;
+ }
+
+ // fastpath for single-pixel width lines
+ if (w == 1) {
+ float slope = (float)(y2 - y1) / (float)(x2 - x1);
+ int last_x = x1;
+ for(int y=y1; y<=y2; y++) {
+ int new_x = (int)((float)(y - y1) / slope) + x1;
+ if (slope >= 0) fillTrapezoid(last_x + 1, y != y2 ? new_x + 1 : new_x, y,
+ last_x + 1, y != y2 ? new_x + 1 : new_x, y + 1, color);
+ else fillTrapezoid(y != y2 ? new_x : new_x + 1, last_x, y,
+ y != y2 ? new_x : new_x + 1, last_x, y + 1, color);
+ last_x = new_x;
+ }
+ return;
+ }
+
+ // actually half-width
+ float width = (float)w / 2;
+ float phi = (float)Math.atan((y2 - y1) / (x2 - x1));
+ if (phi < 0.0) phi += (float)Math.PI * 2;
+ float theta = (float)Math.PI / 2 - phi;
+
+ // dx and dy are the x and y distance between each endpoint and the corner of the stroke
+ int dx = (int)(width * Math.cos(theta));
+ int dy = (int)(width * Math.sin(theta));
+
+ // slice is the longest possible length of a horizontal line across the stroke
+ int slice = (int)(2 * width / Math.cos(theta));
+
+ if (capped) {
+ x1 -= width * Math.cos(phi);
+ x2 += width * Math.cos(phi);
+ y1 -= width * Math.sin(phi);
+ y2 += width * Math.sin(phi);
+ }
+
+ fillTrapezoid(x1 + dx, x1 + dx, y1 - dy, x1 - dx, x1 - dx + slice, y1 + dy, color); // top corner
+ fillTrapezoid(x2 + dx - slice, x2 + dx, y2 - dy, x2 - dx, x2 - dx, y2 + dy, color); // bottom corner
+ fillTrapezoid(x1 - dx, x1 - dx + slice, y1 + dy, x2 + dx - slice, x2 + dx, y2 - dy, color); // middle
+ }
+
+}
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.graphics;
+import java.util.*;
+
+
+// FIXME: offer a "subpixel" mode where we pass floats to the Platform and don't do any snapping
+// FIXME: fracture when realizing instead of when parsing?
+
+/*
+ v1.0
+ - textpath
+ - gradients
+ - patterns
+ - clipping/masking
+ - filters (filtering of a group must be performed AFTER the group is assembled; sep. canvas)
+
+ v1.1
+ - bump caps [requires Paint that can fill circles...] [remember to distinguish between closed/unclosed]
+ - line joins
+ - mitre (hard)
+ - bevel (easy)
+ - bump (easy, but requires 'round' Paint)
+ - subtree sharing? otherwise the memory consumption might be outrageous... clone="" attribute?
+ - better clipping
+ - intersect clip regions (linearity)
+ - clip on trapezoids, not pixels
+ - faster gradients and patterns:
+ - transform each corner of the trapezoid and then interpolate
+*/
+
+// FIXME: need to support style sheets and the 'style=' attribute
+// FIXME: need to convert markers into subboxes
+public class SVG {
+
+ /*
+ public static void parseNode(String name, String[] keys, Object[] vals, Template t) {
+ Hash h = new Hash();
+ for(int i=0; i<keys.length; i++) if (vals[i] != null) h.put(keys[i], vals[i]);
+
+ Hash props = new Hash();
+ props.put("transform", h.get("transform"));
+ props.put("fill", h.get("fill"));
+ props.put("stroke", h.get("stroke"));
+ if ("visible".equals(h.get("overflow")) || "auto".equals(h.get("overflow")))
+ Log.info(VectorGraphics.class, "warning: overflow={auto|visible} not supported; ignoring");
+ if (h.get("display") != null) props.put("invisible", new Boolean("none".equals(h.get("display"))));
+
+
+ // FIXME: "the automatic transformation that is created due to
+ // a viewBox does not affect the x, y, width and height
+ // attributes". Also, transform+viewbox together?
+
+ if (h.get("preserveAspectRatio") != null) {
+ StringTokenizer st = new StringTokenizer((String)h.get("preserveAspectRatio"), " ");
+ String align = st.nextToken();
+ if ("defer".equals(align)) align = st.nextToken();
+ if (!align.equals("none")) {
+ // FIXME, need to beef up XWT's align property
+ align = "";
+ if (align.startsWith("yMin")) align = "top";
+ else if (align.startsWith("yMax")) align = "bottom";
+ if (align.startsWith("xMin")) align += "left";
+ else if (align.startsWith("xMax")) align += "right";
+ props.put("align", align);
+ }
+ // FIXME: need to implement scaling property on boxes, also size-to-viewbox
+ props.put("scaling", "uniform");
+ if (st.hasMoreTokens()) {
+ String meetOrSlice = st.nextToken();
+ if (meetOrSlice.equals("meet")) props.put("scaling", "meet"); // keep within viewport
+ else if (meetOrSlice.equals("slice")) props.put("scaling", "slice"); // expand beyond viewport
+ }
+ }
+
+ // FIXME: insert an extra layer of boxen and put this transform on the inner layer
+ if (h.get("viewBox") != null) {
+ PathTokenizer pt = new PathTokenizer(h.get("viewBox").toString());
+ String transform = (String)props.get("transform");
+ if (transform == null) transform = "";
+ transform = "translate(" + (-1 * pt.parseFloat()) + ", " + (-1 * pt.parseFloat()) + ") " +
+ "scale(" + pt.parseFloat() + "%, " + pt.parseFloat() + "%) ";
+ }
+
+ String path = (String)h.get("d");
+ if (name.equals("g")) {
+ path = null;
+
+ } else if (name.equals("font")) {
+ VectorGraphics.Font f = currentFont = new VectorGraphics.Font();
+ if (h.get("horiz-origin-x") != null) f.horiz_origin_x = Float.parseFloat(h.get("horiz-origin-x").toString());
+ if (h.get("horiz-origin-y") != null) f.horiz_origin_y = Float.parseFloat(h.get("horiz-origin-y").toString());
+ if (h.get("horiz-adv-x") != null) f.horiz_adv_x = Float.parseFloat(h.get("horiz-adv-x").toString());
+ if (h.get("vert-origin-x") != null) f.vert_origin_x = Float.parseFloat(h.get("vert-origin-x").toString());
+ if (h.get("vert-origin-y") != null) f.vert_origin_y = Float.parseFloat(h.get("vert-origin_y").toString());
+ if (h.get("vert-adv-y") != null) f.vert_adv_y = Float.parseFloat(h.get("vert-adv-y").toString());
+
+ } else if (name.equals("hkern")) {
+ //FIXME
+
+ } else if (name.equals("vkern")) {
+ //FIXME
+
+ } else if (name.equals("font-face")) {
+ //FIXME
+
+ } else if (name.equals("glyph") || name.equals("missing-glyph")) {
+ String glyphName = name.equals("missing-glyph") ? "missing-glyph" : (String)h.get("glyph-name");
+ VectorGraphics.Font.Glyph g = new VectorGraphics.Font.Glyph(glyphName, (String)h.get("unicode"), t, currentFont);
+ if (h.get("horiz-adv-x") != null) g.horiz_adv_x = Float.parseFloat(h.get("horiz-adv-x").toString());
+ if (h.get("vert-origin-x") != null) g.vert_origin_x = Float.parseFloat(h.get("vert-origin-x").toString());
+ if (h.get("vert-origin-y") != null) g.vert_origin_y = Float.parseFloat(h.get("vert-origin-y").toString());
+ if (h.get("vert-adv-y") != null) g.vert_adv_y = Float.parseFloat(h.get("vert-adv-y").toString());
+ if ("v".equals(h.get("orientation"))) g.isVerticallyOriented = true;
+
+ } else if (name.equals("svg")) {
+ // FIXME: handle percentages
+ // FIXME: what if these aren't provided?
+ // FIXME (in general)
+ float x = Float.parseFloat(h.get("x").toString());
+ float y = Float.parseFloat(h.get("y").toString());
+ float width = Float.parseFloat(h.get("width").toString());
+ float height = Float.parseFloat(h.get("height").toString());
+ h.put("viewBox", x + ", " + y + ", " + (x + width) + ", " + (y + height));
+ path = "";
+
+ } else if (name.equals("path")) {
+ path = h.get("d").toString();
+
+ } else if (name.equals("rect")) {
+ float x = Float.parseFloat(h.get("x").toString());
+ float y = Float.parseFloat(h.get("y").toString());
+ float width = Float.parseFloat(h.get("width").toString());
+ float height = Float.parseFloat(h.get("height").toString());
+ float rx = Float.parseFloat(h.get("rx").toString());
+ float ry = Float.parseFloat(h.get("ry").toString());
+ path =
+ "M" + (x + rx) + "," + y +
+ "H" + (x + width - rx) +
+ "A" + rx + "," + rx + ",0,0,1," + (x + width) + "," + (y + ry) +
+ "V" + (y + width - ry) +
+ "A" + rx + "," + rx + ",0,0,1," + (x + width - rx) + "," +
+ (y + height) +
+ "H" + (x + rx) +
+ "A" + rx + "," + rx + ",0,0,1," + x + "," + (y + height - ry) +
+ "V" + (y + ry) +
+ "A" + rx + "," + rx + ",0,0,1," + (x + rx) + "," + (y + ry) +
+ "Z";
+
+ } else if (name.equals("circle")) {
+ float r = Float.parseFloat(h.get("r").toString());
+ float cx = Float.parseFloat(h.get("cx").toString());
+ float cy = Float.parseFloat(h.get("cy").toString());
+ path = "A " + r + " " + r + " 1 1 " + cx + " " + cy;
+
+ } else if (name.equals("ellipse")) {
+ float rx = Float.parseFloat(h.get("rx").toString());
+ float ry = Float.parseFloat(h.get("ry").toString());
+ float cx = Float.parseFloat(h.get("cx").toString());
+ float cy = Float.parseFloat(h.get("cy").toString());
+ path = "A " + rx + " " + ry + " 1 1 " + cx + " " + cy;
+
+ } else if (name.equals("line")) {
+ float x1 = Float.parseFloat(h.get("x1").toString());
+ float y1 = Float.parseFloat(h.get("y1").toString());
+ float x2 = Float.parseFloat(h.get("x2").toString());
+ float y2 = Float.parseFloat(h.get("y2").toString());
+ path = "M " + x1 + " " + y1 + " L " + x2 + " " + y2;
+
+ } else if (name.equals("polyline") || name.equals("polygon")) {
+ StringTokenizer st = new StringTokenizer(h.get("points").toString(), ", ", false);
+ String s = "M ";
+ while(st.hasMoreTokens()) s += st.nextToken() + " " + st.nextToken() + " ";
+ path = s + (name.equals("polygon") ? "z" : "");
+
+ } else {
+ Log.info(VectorGraphics.class, "unknown element in VectorGraphics namespace: " + name);
+ }
+ props.put("path", path);
+ t.keys = new String[props.size()];
+ System.arraycopy(props.keys(), 0, t.keys, 0, t.keys.length);
+ t.vals = new String[props.size()];
+ for(int i=0; i<t.keys.length; i++) t.vals[i] = props.get(t.keys[i]);
+
+
+ // FIXME!!!!
+ if (h.get("viewBox") != null) {
+ StringTokenizer st = new StringTokenizer(h.get("viewBox").toString(), ", ", false);
+ if (t.transform == null) t.transform = "";
+ Point p1, p2;
+ VectorGraphics.RasterPath.fromString(path).getBoundingBox(p1, p2);
+
+ float minx = st.parseFloat();
+ float miny = st.parseFloat();
+ float width = st.parseFloat();
+ float height = st.parseFloat();
+ t.transform += "translate(" + (-1 * p1.x) + ", " + (-1 * p1.y) + ") " +
+ "scale(" + ((p2.x - p1.x) / width) + ", " + ((p2.y - p1.y) / height) + ") " +
+ "translate(" + minx + ", " + miny + ") ";
+
+ // FIXME: preserveAspectRatio
+ }
+
+ }
+ */
+
+ /*
+ public static class Font {
+ Font() { }
+ float horiz_origin_x = 0, horiz_origin_y = 0, horiz_adv_x = 0;
+ float vert_origin_x = 0, vert_origin_y = 0, vert_adv_y = 0;
+
+ // FIXME: avoid using substring() in here ore creating any objects
+ public void render(String text, DoubleBuffer buf, int x, int y, int fillcolor, int strokecolor, int size) {
+ // FIXME: points, not pixels
+ Affine a = buf.a;
+ float scaleFactor = (float)(1.0/1000.0) * (float)size;
+ for(int pos=0; pos<text.length(); pos++) {
+ Glyph g;
+ for(g = (Glyph)glyphByUnicode.get(text.substring(pos, pos+1));
+ g != null && !g.unicode.equals(text.substring(pos, pos + g.unicode.length()));
+ g = g.next);
+ if (g == null) {
+ g = (Glyph)glyphByName.get("missing-glyph");
+ } else {
+ pos += g.unicode.length() - 1;
+ }
+ if (g != null) {
+ System.out.println(" " + g.unicode);
+ g.render(buf, x, y, fillcolor, strokecolor, scaleFactor);
+ x += (int)(g.horiz_adv_x * size / 1000.0);
+ } else {
+ x += (int)(horiz_adv_x * size / 1000.0);
+ }
+ }
+ buf.setTransform(a);
+ }
+
+ / ** all glyphs, keyed by their <tt>name</tt> property * /
+ Hashtable glyphByName = new Hashtable();
+
+ / ** linked list of glyphs, stored by the first character of their <tt>unicode</tt> property * /
+ Hashtable glyphByUnicode = new Hashtable();
+
+ // a Glyph in an VectorGraphics font
+ public static class Glyph {
+
+ // FIXME: lang attribute
+ boolean isVerticallyOriented = false;
+ Template t = null;
+ Box b = null;
+
+ float horiz_adv_x = 0;
+ float vert_origin_x = 0;
+ float vert_origin_y = 0;
+ float vert_adv_y = 0;
+
+ String unicode = null;
+
+ // forms the linked list in glyphByUnicode; glyphs appear in the order specified in the font
+ public Glyph next = null;
+
+ Glyph(String name, String unicode, Template t, VectorGraphics.Font f) {
+ if (unicode != null)
+ if (f.glyphByUnicode.get(unicode.substring(0, 1)) == null) {
+ f.glyphByUnicode.put(unicode.substring(0, 1), this);
+ } else {
+ Glyph g;
+ for(g = (Glyph)f.glyphByUnicode.get(unicode.substring(0, 1)); g.next != null; g = g.next);
+ g.next = this;
+ }
+ if (name != null) f.glyphByUnicode.put(name, this);
+ this.unicode = unicode;
+ this.t = t;
+ horiz_adv_x = f.horiz_adv_x;
+ vert_origin_x = f.vert_origin_x;
+ vert_origin_y = f.vert_origin_y;
+ vert_adv_y = f.vert_adv_y;
+ }
+ public void render(DoubleBuffer buf, int x, int y, int fillcolor, int strokecolor, float scaleFactor) {
+ // FEATURE: make b double-buffered for increased performance
+ if (b == null) {
+ b = new Box(t, new org.ibex.util.Vec(), new org.ibex.util.Vec(), null, 0, 0);
+ b.put("absolute", Boolean.TRUE);
+ b.prerender();
+ t = null;
+ }
+ // FIXME
+ b.put("width", new Integer(1000));
+ b.put("height", new Integer(1000));
+ b.fillcolor = fillcolor;
+ b.strokecolor = strokecolor;
+
+ // we toss an extra flip on the ctm so that fonts stick "up" instead of down
+ b.render(0, 0, buf.getWidth(), buf.getHeight(), buf,
+ Affine.flip(false, true).multiply(Affine.scale(scaleFactor, scaleFactor).multiply(Affine.translate(x, y))).multiply(buf.a));
+ }
+ }
+ }
+ */
+
+}
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.graphics;
+
+import org.ibex.js.*;
+import org.ibex.util.*;
+import org.ibex.plat.*;
+
+import org.ibex.core.*; // FIXME
+
+/**
+ * A Surface, as described in the Ibex Reference.
+ *
+ * Platform subclasses should include an inner class subclass of
+ * Surface to return from the Platform._createSurface() method
+ */
+public abstract class Surface extends PixelBuffer implements Task {
+
+ // Static Data ////////////////////////////////////////////////////////////////////////////////
+
+ private static Boolean T = Boolean.TRUE;
+ private static Boolean F = Boolean.FALSE;
+
+ /** all instances of Surface which need to be refreshed by the Scheduler */
+ public static Vec allSurfaces = new Vec();
+
+ /** When set to true, render() should abort as soon as possible and restart the rendering process */
+ public volatile boolean abort = false;
+
+ // these three variables are used to ensure that user resizes trump programmatic resizes
+ public volatile boolean syncRootBoxToSurface = false;
+ public volatile int pendingWidth = 0;
+ public volatile int pendingHeight = 0;
+
+ public static boolean alt = false; ///< true iff the alt button is pressed down
+ public static boolean control = false; ///< true iff the control button is pressed down
+ public static boolean shift = false; ///< true iff the shift button is pressed down
+ public static boolean button1 = false; ///< true iff button 1 is depressed
+ public static boolean button2 = false; ///< true iff button 2 is depressed
+ public static boolean button3 = false; ///< true iff button 3 is depressed
+
+
+ // Instance Data ///////////////////////////////////////////////////////////////////////
+
+ public Box root; ///< The Box at the root of this surface
+ public String cursor = "default"; ///< The active cursor to switch to when syncCursor() is called
+ public int mousex; ///< x position of the mouse
+ public int mousey; ///< y position of the mouse
+ public int _mousex; ///< x position of the mouse FIXME
+ public int _mousey; ///< y position of the mouse FIXME
+ public int newmousex = -1; ///< x position of the mouse, in real time; this lets us collapse Move's
+ public int newmousey = -1; ///< y position of the mouse, in real time; this lets us collapse Move's
+ public boolean minimized = false; ///< True iff this surface is minimized, in real time
+ public boolean maximized = false; ///< True iff this surface is maximized, in real time
+ public boolean unrendered = true; ///< True iff this surface has not yet been rendered
+ DirtyList dirtyRegions = new DirtyList(); ///< Dirty regions on the surface
+
+ // Used For Simulating Clicks and DoubleClicks /////////////////////////////////////////////////
+
+ int last_press_x = Integer.MAX_VALUE; ///< the x-position of the mouse the last time a Press message was enqueued
+ int last_press_y = Integer.MAX_VALUE; ///< the y-position of the mouse the last time a Press message was enqueued
+ static int lastClickButton = 0; ///< the last button to recieve a Click message; used for simulating DoubleClick's
+ static long lastClickTime = 0; ///< the last time a Click message was processed; used for simulating DoubleClick's
+
+
+ // Methods to be overridden by subclasses ///////////////////////////////////////////////////////
+
+ public abstract void toBack(); ///< should push surface to the back of the stacking order
+ public abstract void toFront(); ///< should pull surface to the front of the stacking order
+ public abstract void syncCursor(); ///< set the actual cursor to this.cursor if they do not match
+ public abstract void setInvisible(boolean b); ///< If <tt>b</tt>, make window invisible; otherwise, make it non-invisible.
+ protected abstract void _setMaximized(boolean b); ///< If <tt>b</tt>, maximize the surface; otherwise, un-maximize it.
+ protected abstract void _setMinimized(boolean b); ///< If <tt>b</tt>, minimize the surface; otherwise, un-minimize it.
+ public abstract void setLocation(); ///< Set the surface's x/y position to that of the root box
+ protected abstract void _setSize(int w, int h); ///< set the actual size of the surface
+ public abstract void setTitleBarText(String s); ///< Sets the surface's title bar text, if applicable
+ public abstract void setIcon(Picture i); ///< Sets the surface's title bar text, if applicable
+ public abstract void _dispose(); ///< Destroy the surface
+ public void setMinimumSize(int minx, int miny, boolean resizable) { }
+ protected void setSize(int w, int h) { _setSize(w, h); }
+
+ public static Picture scarImage = null;
+
+ // Helper methods for subclasses ////////////////////////////////////////////////////////////
+
+ protected final void Press(final int button) {
+ last_press_x = mousex;
+ last_press_y = mousey;
+
+ if (button == 1) button1 = true;
+ else if (button == 2) button2 = true;
+ else if (button == 3) button3 = true;
+
+ if (button == 1) new Message("_Press1", T, root);
+ else if (button == 2) new Message("_Press2", T, root);
+ else if (button == 3) {
+ Scheduler.add(new Task() { public void perform() throws JSExn {
+ Platform.clipboardReadEnabled = true;
+ try {
+ root.putAndTriggerTraps("_Press3", T);
+ } finally {
+ Platform.clipboardReadEnabled = false;
+ }
+ }});
+ }
+ }
+
+ protected final void Release(int button) {
+ if (button == 1) button1 = false;
+ else if (button == 2) button2 = false;
+ else if (button == 3) button3 = false;
+
+ if (button == 1) new Message("_Release1", T, root);
+ else if (button == 2) new Message("_Release2", T, root);
+ else if (button == 3) new Message("_Release3", T, root);
+
+ if (Platform.needsAutoClick() && Math.abs(last_press_x - mousex) < 5 && Math.abs(last_press_y - mousey) < 5) Click(button);
+ last_press_x = Integer.MAX_VALUE;
+ last_press_y = Integer.MAX_VALUE;
+ }
+
+ protected final void Click(int button) {
+ if (button == 1) new Message("_Click1", T, root);
+ else if (button == 2) new Message("_Click2", T, root);
+ else if (button == 3) new Message("_Click3", T, root);
+ if (Platform.needsAutoDoubleClick()) {
+ long now = System.currentTimeMillis();
+ if (lastClickButton == button && now - lastClickTime < 350) DoubleClick(button);
+ lastClickButton = button;
+ lastClickTime = now;
+ }
+ }
+
+ /** we enqueue ourselves in the Scheduler when we have a Move message to deal with */
+ private Task mover = new Task() {
+ public void perform() {
+ if (mousex == newmousex && mousey == newmousey) return;
+ int oldmousex = mousex; mousex = newmousex;
+ int oldmousey = mousey; mousey = newmousey;
+ String oldcursor = cursor; cursor = "default";
+ // FIXME: Root (ONLY) gets motion events outside itself (if trapped)
+ if (oldmousex != mousex || oldmousey != mousey)
+ root.putAndTriggerTrapsAndCatchExceptions("_Move", T);
+ if (!cursor.equals(oldcursor)) syncCursor();
+ } };
+
+ /**
+ * Notify Ibex that the mouse has moved. If the mouse leaves the
+ * surface, but the host windowing system does not provide its new
+ * position (for example, a Java MouseListener.mouseExited()
+ * message), the subclass should use (-1,-1).
+ */
+ protected final void Move(final int newmousex, final int newmousey) {
+ this.newmousex = newmousex;
+ this.newmousey = newmousey;
+ Scheduler.add(mover);
+ }
+
+ protected final void HScroll(int pixels) { new Message("_HScroll", new Integer(pixels), root); }
+ protected final void VScroll(int pixels) { new Message("_VScroll", new Integer(pixels), root); }
+ protected final void HScroll(float lines) { new Message("_HScroll", new Float(lines), root); }
+ protected final void VScroll(float lines) { new Message("_VScroll", new Float(lines), root); }
+
+ /** subclasses should invoke this method when the user resizes the window */
+ protected final void SizeChange(final int width, final int height) {
+ if (unrendered || (pendingWidth == width && pendingHeight == height)) return;
+ pendingWidth = width;
+ pendingHeight = height;
+ syncRootBoxToSurface = true;
+ abort = true;
+ Scheduler.renderAll();
+ }
+
+ // FEATURE: can we avoid creating objects here?
+ protected final void PosChange(final int x, final int y) {
+ Scheduler.add(new Task() { public void perform() throws JSExn {
+ root.x = x;
+ root.y = y;
+ root.putAndTriggerTrapsAndCatchExceptions("PosChange", T);
+ }});
+ }
+
+ private final String[] doubleClick = new String[] { null, "_DoubleClick1", "_DoubleClick2", "_DoubleClick3" };
+ protected final void DoubleClick(int button) { new Message(doubleClick[button], T, root); }
+ protected final void KeyPressed(String key) { new Message("_KeyPressed", key, root); }
+ protected final void KeyReleased(String key) { new Message("_KeyReleased", key, root); }
+ protected final void Close() { new Message("Close", T, root); }
+ protected final void Minimized(boolean b) { minimized = b; new Message("Minimized", b ? T : F, root); }
+ protected final void Maximized(boolean b) { maximized = b; new Message("Maximized", b ? T : F, root); }
+ protected final void Focused(boolean b) { new Message("Focused", b ? T : F, root); }
+
+ private boolean scheduled = false;
+ public void Refresh() { if (!scheduled) Scheduler.add(this); scheduled = true; }
+ public void perform() { scheduled = false; Scheduler.renderAll(); }
+
+ public final void setMaximized(boolean b) { if (b != maximized) _setMaximized(maximized = b); }
+ public final void setMinimized(boolean b) { if (b != minimized) _setMinimized(minimized = b); }
+
+
+ // Other Methods ///////////////////////////////////////////////////////////////////////////////
+
+ /** Indicates that the Surface is no longer needed */
+ public final void dispose(boolean quitIfAllSurfacesGone) {
+ if (Log.on) Log.info(this, "disposing " + this);
+ allSurfaces.removeElement(this);
+ _dispose();
+ if (allSurfaces.size() == 0) {
+ if (Log.on) Log.info(this, "exiting because last surface was destroyed");
+ System.exit(0);
+ }
+ }
+
+ public void dirty(int x, int y, int w, int h) {
+ dirtyRegions.dirty(x, y, w, h);
+ Refresh();
+ }
+
+ public static Surface fromBox(Box b) {
+ // FIXME use a hash table here
+ for(int i=0; i<allSurfaces.size(); i++) {
+ Surface s = (Surface)allSurfaces.elementAt(i);
+ if (s.root == b) return s;
+ }
+ return null;
+ }
+
+ public Surface(Box root) {
+ this.root = root;
+ // FIXME: document this in the reference
+ if (!root.test(root.HSHRINK) && root.maxwidth == Integer.MAX_VALUE)
+ root.maxwidth = Platform.getScreenWidth() / 2;
+ if (!root.test(root.VSHRINK) && root.maxheight == Integer.MAX_VALUE)
+ root.maxheight = Platform.getScreenHeight() / 2;
+ root.setWidth(root.minwidth,
+ root.test(root.HSHRINK)
+ ? Math.max(root.minwidth, root.contentwidth)
+ : Math.min(Platform.getScreenWidth(), root.maxwidth));
+ root.setHeight(root.minheight,
+ root.test(root.VSHRINK)
+ ? Math.max(root.minheight, root.contentheight)
+ : Math.min(Platform.getScreenHeight(), root.maxheight));
+ Surface old = fromBox(root);
+ if (old != null) old.dispose(false);
+ else root.removeSelf();
+ Refresh();
+ }
+
+ private static Affine identity = Affine.identity();
+
+ /** runs the prerender() and render() pipelines in the root Box to regenerate the backbuffer, then blits it to the screen */
+ public synchronized void render() {
+ scheduled = false;
+ // make sure the root is properly sized
+ do {
+ abort = false;
+ root.pack();
+ if (syncRootBoxToSurface) {
+ root.setWidth(root.minwidth, pendingWidth);
+ root.setHeight(root.minheight, pendingHeight);
+ syncRootBoxToSurface = false;
+ }
+ int rootwidth = root.test(root.HSHRINK) ? root.contentwidth : root.maxwidth;
+ int rootheight = root.test(root.VSHRINK) ? root.contentheight : root.maxheight;
+ if (rootwidth != root.width || rootheight != root.height) {
+ // dirty the place where the scar used to be and where it is now
+ dirty(0, root.height - scarImage.height, scarImage.width, scarImage.height);
+ dirty(0, rootheight - scarImage.height, scarImage.width, scarImage.height);
+ }
+ root.reflow();
+ setSize(rootwidth, rootheight);
+ /*String oldcursor = cursor;
+ cursor = "default";
+ root.putAndTriggerTrapsAndCatchExceptions("_Move", JS.T);
+ if (!cursor.equals(oldcursor)) syncCursor();*/
+ } while(abort);
+
+ int[][] dirt = dirtyRegions.flush();
+ for(int i = 0; dirt != null && i < dirt.length; i++) {
+ if (dirt[i] == null) continue;
+ int x = dirt[i][0], y = dirt[i][1], w = dirt[i][2], h = dirt[i][3];
+ if (x < 0) x = 0;
+ if (y < 0) y = 0;
+ if (x+w > root.width) w = root.width - x;
+ if (y+h > root.height) h = root.height - y;
+ if (w <= 0 || h <= 0) continue;
+
+ root.render(0, 0, x, y, x + w, y + h, this, identity);
+ drawPicture(scarImage, 0, root.height - scarImage.height, x, y, x+w, y+h);
+
+ if (abort) {
+ // x,y,w,h is only partially reconstructed, so we must be careful not to re-blit it
+ dirtyRegions.dirty(x, y, w, h);
+ // put back all the dirty regions we haven't yet processed (including the current one)
+ for(int j=i; j<dirt.length; j++)
+ if (dirt[j] != null)
+ dirtyRegions.dirty(dirt[j][0], dirt[j][1], dirt[j][2], dirt[j][3]);
+ return;
+ }
+ }
+
+ unrendered = false;
+ }
+
+ // FEATURE: reinstate recycler
+ public class Message implements Task {
+
+ private Box boxContainingMouse;
+ private Object value;
+ public String name;
+
+ Message(String name, Object value, Box boxContainingMouse) {
+ this.boxContainingMouse = boxContainingMouse;
+ this.name = name;
+ this.value = value;
+ Scheduler.add(this);
+ }
+
+ public void perform() {
+ if (name.equals("_KeyPressed")) {
+ String value = (String)this.value;
+ if (value.toLowerCase().endsWith("shift")) shift = true; else if (shift) value = value.toUpperCase();
+ if (value.toLowerCase().equals("alt")) alt = true; else if (alt) value = "A-" + value;
+ if (value.toLowerCase().endsWith("control")) control = true; else if (control) value = "C-" + value;
+ if (value.equals("C-v") || value.equals("A-v")) Platform.clipboardReadEnabled = true;
+ this.value = value;
+ } else if (name.equals("_KeyReleased")) {
+ String value = (String)this.value;
+ if (value.toLowerCase().equals("alt")) alt = false;
+ else if (value.toLowerCase().equals("control")) control = false;
+ else if (value.toLowerCase().equals("shift")) shift = false;
+ this.value = value;
+ } else if (name.equals("_HScroll") || name.equals("_VScroll")) {
+ // FIXME: technically points != pixels
+ if (value instanceof Integer)
+ value = new Float(((Integer)value).intValue() * root.fontSize());
+ }
+ try {
+ boxContainingMouse.putAndTriggerTrapsAndCatchExceptions(name, value);
+ } finally {
+ Platform.clipboardReadEnabled = false;
+ }
+ }
+ public String toString() { return "Message [name=" + name + ", value=" + value + "]"; }
+ }
+
+
+ // Default PixelBuffer implementation /////////////////////////////////////////////////////////
+
+ public static abstract class DoubleBufferedSurface extends Surface {
+
+ public DoubleBufferedSurface(Box root) { super(root); }
+ PixelBuffer backbuffer = Platform.createPixelBuffer(Platform.getScreenWidth(), Platform.getScreenHeight(), this);
+ DirtyList screenDirtyRegions = new DirtyList();
+
+ public void drawPicture(Picture source, int dx, int dy, int cx1, int cy1, int cx2, int cy2) {
+ screenDirtyRegions.dirty(cx1, cy1, cx2 - cx1, cy2 - cy1);
+ backbuffer.drawPicture(source, dx, dy, cx1, cy1, cx2, cy2);
+ }
+
+ public void drawGlyph(Font.Glyph source, int dx, int dy, int cx1, int cy1, int cx2, int cy2, int argb) {
+ screenDirtyRegions.dirty(cx1, cy1, cx2 - cx1, cy2 - cy1);
+ backbuffer.drawGlyph(source, dx, dy, cx1, cy1, cx2, cy2, argb);
+ }
+
+ public void fillTrapezoid(int x1, int x2, int y1, int x3, int x4, int y2, int color) {
+ screenDirtyRegions.dirty(Math.min(x1, x3), y1, Math.max(x2, x4) - Math.min(x1, x3), y2 - y1);
+ backbuffer.fillTrapezoid(x1, x2, y1, x3, x4, y2, color);
+ }
+
+ public void render() {
+ super.render();
+ if (abort) return;
+ int[][] dirt = screenDirtyRegions.flush();
+ for(int i = 0; dirt != null && i < dirt.length; i++) {
+ if (dirt[i] == null) continue;
+ int x = dirt[i][0];
+ int y = dirt[i][1];
+ int w = dirt[i][2];
+ int h = dirt[i][3];
+ if (x < 0) x = 0;
+ if (y < 0) y = 0;
+ if (x+w > root.width) w = root.width - x;
+ if (y+h > root.height) h = root.height - y;
+ if (w <= 0 || h <= 0) continue;
+ if (abort) return;
+ blit(backbuffer, x, y, x, y, w + x, h + y);
+ }
+ }
+
+ /** This is how subclasses signal a 'shallow dirty', indicating that although the backbuffer is valid, the screen is not */
+ public final void Dirty(int x, int y, int w, int h) {
+ screenDirtyRegions.dirty(x, y, w, h);
+ Scheduler.renderAll();
+ }
+
+ public void dirty(int x, int y, int w, int h) {
+ screenDirtyRegions.dirty(x, y, w, h);
+ super.dirty(x, y, w, h);
+ }
+
+ /** copies a region from the doublebuffer to this surface */
+ public abstract void blit(PixelBuffer source, int sx, int sy, int dx, int dy, int dx2, int dy2);
+
+ }
+
+}
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.js;
+
+/**
+ * Constants for the various JavaScript ByteCode operations.
+ *
+ * Each instruction is an opcode and an optional literal literal;
+ * some Tokens are also valid; see Tokens.java
+ */
+interface ByteCodes {
+
+ /** push the literal onto the stack */
+ public static final byte LITERAL = -2;
+
+ /** push a new array onto the stack with length equal to the literal */
+ public static final byte ARRAY = -3;
+
+ /** push an empty object onto the stack */
+ public static final byte OBJECT = -4;
+
+ /** create a new instance; literal is a reference to the corresponding ForthBlock */
+ public static final byte NEWFUNCTION = -5;
+
+ /** if given a non-null argument declare its argument in the current scope and push
+ it to the stack, else, declares the element on the top of the stack and leaves it
+ there */
+ public static final byte DECLARE = -6;
+
+ /** push a reference to the current scope onto the stack */
+ public static final byte TOPSCOPE = -7;
+
+ /** if given a null literal pop two elements off the stack; push stack[-1].get(stack[top])
+ else pop one element off the stack, push stack[top].get(literal) */
+ public static final byte GET = -8;
+
+ /** push stack[-1].get(stack[top]) */
+ public static final byte GET_PRESERVE = -9;
+
+ /** pop two elements off the stack; stack[-2].put(stack[-1], stack[top]); push stack[top] */
+ public static final byte PUT = -10;
+
+ /** literal is a relative address; pop stacktop and jump if the value is true */
+ public static final byte JT = -11;
+
+ /** literal is a relative address; pop stacktop and jump if the value is false */
+ public static final byte JF = -12;
+
+ /** literal is a relative address; jump to it */
+ public static final byte JMP = -13;
+
+ /** discard the top stack element */
+ static public final byte POP = -14;
+
+ /** pop element; call stack[top](stack[-n], stack[-n+1]...) where n is the number of args to the function */
+ public static final byte CALL = -15;
+
+ /** pop an element; push a JS.JSArray containing the keys of the popped element */
+ public static final byte PUSHKEYS = -16;
+
+ /** push the top element down so that (arg) elements are on top of it; all other elements retain ordering */
+ public static final byte SWAP = -17;
+
+ /** execute the bytecode block pointed to by the literal in a fresh scope with parentScope==THIS */
+ public static final byte NEWSCOPE = -18;
+
+ /** execute the bytecode block pointed to by the literal in a fresh scope with parentScope==THIS */
+ public static final byte OLDSCOPE = -19;
+
+ /** push a copy of the top stack element */
+ public static final byte DUP = -20;
+
+ /** a NOP; confers a label upon the following instruction */
+ public static final byte LABEL = -21;
+
+ /** execute the ForthBlock pointed to by the literal until BREAK encountered; push TRUE onto the stack for the first iteration
+ * and FALSE for all subsequent iterations */
+ public static final byte LOOP = -22;
+
+ /** similar effect a a GET followed by a CALL */
+ public static final byte CALLMETHOD = -23;
+
+ /** finish a finally block and carry out whatever instruction initiated the finally block */
+ public static final byte FINALLY_DONE = -24;
+
+ /** finish a finally block and carry out whatever instruction initiated the finally block */
+ public static final byte MAKE_GRAMMAR = -25;
+
+ public static final String[] bytecodeToString = new String[] {
+ "", "", "LITERAL", "ARRAY", "OBJECT", "NEWFUNCTION", "DECLARE", "TOPSCOPE",
+ "GET", "GET_PRESERVE", "PUT", "JT", "JF", "JMP", "POP", "CALL", "PUSHKEYS",
+ "SWAP", "NEWSCOPE", "OLDSCOPE", "DUP", "LABEL", "LOOP", "CALLMETHOD",
+ "FINALLY_DONE", "MAKE_GRAMMAR"
+ };
+}
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.js;
+
+import org.ibex.util.*;
+import java.util.*;
+
+/** Encapsulates a single JS interpreter (ie call stack) */
+class Interpreter implements ByteCodes, Tokens {
+
+
+ // Thread-Interpreter Mapping /////////////////////////////////////////////////////////////////////////
+
+ static Interpreter current() { return (Interpreter)threadToInterpreter.get(Thread.currentThread()); }
+ private static Hashtable threadToInterpreter = new Hashtable();
+
+
+ // Instance members and methods //////////////////////////////////////////////////////////////////////
+
+ int pausecount; ///< the number of times pause() has been invoked; -1 indicates unpauseable
+ JSFunction f = null; ///< the currently-executing JSFunction
+ JSScope scope; ///< the current top-level scope (LIFO stack via NEWSCOPE/OLDSCOPE)
+ Vec stack = new Vec(); ///< the object stack
+ int pc = 0; ///< the program counter
+
+ Interpreter(JSFunction f, boolean pauseable, JSArray args) {
+ stack.push(new Interpreter.CallMarker(this)); // the "root function returned" marker -- f==null
+ this.f = f;
+ this.pausecount = pauseable ? 0 : -1;
+ this.scope = new JSScope(f.parentScope);
+ stack.push(args);
+ }
+
+ /** this is the only synchronization point we need in order to be threadsafe */
+ synchronized Object resume() throws JSExn {
+ Thread t = Thread.currentThread();
+ Interpreter old = (Interpreter)threadToInterpreter.get(t);
+ threadToInterpreter.put(t, this);
+ try {
+ return run();
+ } finally {
+ if (old == null) threadToInterpreter.remove(t);
+ else threadToInterpreter.put(t, old);
+ }
+ }
+
+ static int getLine() {
+ Interpreter c = Interpreter.current();
+ return c == null || c.f == null || c.pc < 0 || c.pc >= c.f.size ? -1 : c.f.line[c.pc];
+ }
+
+ static String getSourceName() {
+ Interpreter c = Interpreter.current();
+ return c == null || c.f == null ? null : c.f.sourceName;
+ }
+
+ private static JSExn je(String s) { return new JSExn(getSourceName() + ":" + getLine() + " " + s); }
+
+ // FIXME: double check the trap logic
+ private Object run() throws JSExn {
+
+ // if pausecount changes after a get/put/call, we know we've been paused
+ final int initialPauseCount = pausecount;
+
+ OUTER: for(;; pc++) {
+ try {
+ if (f == null) return stack.pop();
+ int op = f.op[pc];
+ Object arg = f.arg[pc];
+ if(op == FINALLY_DONE) {
+ FinallyData fd = (FinallyData) stack.pop();
+ if(fd == null) continue OUTER; // NOP
+ if(fd.exn != null) throw fd.exn;
+ op = fd.op;
+ arg = fd.arg;
+ }
+ switch(op) {
+ case LITERAL: stack.push(arg); break;
+ case OBJECT: stack.push(new JS()); break;
+ case ARRAY: stack.push(new JSArray(JS.toNumber(arg).intValue())); break;
+ case DECLARE: scope.declare((String)(arg==null ? stack.peek() : arg)); if(arg != null) stack.push(arg); break;
+ case TOPSCOPE: stack.push(scope); break;
+ case JT: if (JS.toBoolean(stack.pop())) pc += JS.toNumber(arg).intValue() - 1; break;
+ case JF: if (!JS.toBoolean(stack.pop())) pc += JS.toNumber(arg).intValue() - 1; break;
+ case JMP: pc += JS.toNumber(arg).intValue() - 1; break;
+ case POP: stack.pop(); break;
+ case SWAP: {
+ int depth = (arg == null ? 1 : JS.toInt(arg));
+ Object save = stack.elementAt(stack.size() - 1);
+ for(int i=stack.size() - 1; i > stack.size() - 1 - depth; i--)
+ stack.setElementAt(stack.elementAt(i-1), i);
+ stack.setElementAt(save, stack.size() - depth - 1);
+ break; }
+ case DUP: stack.push(stack.peek()); break;
+ case NEWSCOPE: scope = new JSScope(scope); break;
+ case OLDSCOPE: scope = scope.getParentScope(); break;
+ case ASSERT:
+ if (JS.checkAssertions && !JS.toBoolean(stack.pop()))
+ throw je("ibex.assertion.failed" /*FEATURE: line number*/); break;
+ case BITNOT: stack.push(JS.N(~JS.toLong(stack.pop()))); break;
+ case BANG: stack.push(JS.B(!JS.toBoolean(stack.pop()))); break;
+ case NEWFUNCTION: stack.push(((JSFunction)arg)._cloneWithNewParentScope(scope)); break;
+ case LABEL: break;
+
+ case TYPEOF: {
+ Object o = stack.pop();
+ if (o == null) stack.push(null);
+ else if (o instanceof JS) stack.push("object");
+ else if (o instanceof String) stack.push("string");
+ else if (o instanceof Number) stack.push("number");
+ else if (o instanceof Boolean) stack.push("boolean");
+ else throw new Error("this should not happen");
+ break;
+ }
+
+ case PUSHKEYS: {
+ Object o = stack.peek();
+ Enumeration e = ((JS)o).keys();
+ JSArray a = new JSArray();
+ while(e.hasMoreElements()) a.addElement(e.nextElement());
+ stack.push(a);
+ break;
+ }
+
+ case LOOP:
+ stack.push(new LoopMarker(pc, pc > 0 && f.op[pc - 1] == LABEL ? (String)f.arg[pc - 1] : (String)null, scope));
+ stack.push(Boolean.TRUE);
+ break;
+
+ case BREAK:
+ case CONTINUE:
+ while(stack.size() > 0) {
+ Object o = stack.pop();
+ if (o instanceof CallMarker) je("break or continue not within a loop");
+ if (o instanceof TryMarker) {
+ if(((TryMarker)o).finallyLoc < 0) continue; // no finally block, keep going
+ stack.push(new FinallyData(op, arg));
+ scope = ((TryMarker)o).scope;
+ pc = ((TryMarker)o).finallyLoc - 1;
+ continue OUTER;
+ }
+ if (o instanceof LoopMarker) {
+ if (arg == null || arg.equals(((LoopMarker)o).label)) {
+ int loopInstructionLocation = ((LoopMarker)o).location;
+ int endOfLoop = ((Integer)f.arg[loopInstructionLocation]).intValue() + loopInstructionLocation;
+ scope = ((LoopMarker)o).scope;
+ if (op == CONTINUE) { stack.push(o); stack.push(Boolean.FALSE); }
+ pc = op == BREAK ? endOfLoop - 1 : loopInstructionLocation;
+ continue OUTER;
+ }
+ }
+ }
+ throw new Error("CONTINUE/BREAK invoked but couldn't find LoopMarker at " +
+ getSourceName() + ":" + getLine());
+
+ case TRY: {
+ int[] jmps = (int[]) arg;
+ // jmps[0] is how far away the catch block is, jmps[1] is how far away the finally block is
+ // each can be < 0 if the specified block does not exist
+ stack.push(new TryMarker(jmps[0] < 0 ? -1 : pc + jmps[0], jmps[1] < 0 ? -1 : pc + jmps[1], this));
+ break;
+ }
+
+ case RETURN: {
+ Object retval = stack.pop();
+ while(stack.size() > 0) {
+ Object o = stack.pop();
+ if (o instanceof TryMarker) {
+ if(((TryMarker)o).finallyLoc < 0) continue;
+ stack.push(retval);
+ stack.push(new FinallyData(RETURN));
+ scope = ((TryMarker)o).scope;
+ pc = ((TryMarker)o).finallyLoc - 1;
+ continue OUTER;
+ } else if (o instanceof CallMarker) {
+ if (scope instanceof Trap.TrapScope) { // handles return component of a read trap
+ Trap.TrapScope ts = (Trap.TrapScope)scope;
+ if (retval != null && retval instanceof Boolean && ((Boolean)retval).booleanValue())
+ ts.cascadeHappened = true;
+ if (!ts.cascadeHappened) {
+ ts.cascadeHappened = true;
+ Trap t = ts.t.next;
+ while (t != null && t.f.numFormalArgs == 0) t = t.next;
+ if (t == null) {
+ ((JS)ts.t.trapee).put(ts.t.name, ts.val);
+ if (pausecount > initialPauseCount) { pc++; return null; } // we were paused
+ } else {
+ stack.push(o);
+ JSArray args = new JSArray();
+ args.addElement(ts.val);
+ stack.push(args);
+ f = t.f;
+ scope = new Trap.TrapScope(f.parentScope, t, ts.val);
+ pc = -1;
+ continue OUTER;
+ }
+ }
+ }
+ scope = ((CallMarker)o).scope;
+ pc = ((CallMarker)o).pc - 1;
+ f = (JSFunction)((CallMarker)o).f;
+ stack.push(retval);
+ continue OUTER;
+ }
+ }
+ throw new Error("error: RETURN invoked but couldn't find a CallMarker!");
+ }
+
+ case PUT: {
+ Object val = stack.pop();
+ Object key = stack.pop();
+ Object target = stack.peek();
+ if (target == null)
+ throw je("tried to put a value to the " + key + " property on the null value");
+ if (!(target instanceof JS))
+ throw je("tried to put a value to the " + key + " property on a " + target.getClass().getName());
+ if (key == null)
+ throw je("tried to assign \"" + (val==null?"(null)":val.toString()) + "\" to the null key");
+
+ Trap t = null;
+ if (target instanceof JSScope && key.equals("cascade")) {
+ Trap.TrapScope ts = null;
+ JSScope p = (JSScope)target; // search the scope-path for the trap
+ if (target instanceof Trap.TrapScope) {
+ ts = (Trap.TrapScope)target;
+ }
+ else {
+ while (ts == null && p.getParentScope() != null) {
+ p = p.getParentScope();
+ if (p instanceof Trap.TrapScope) {
+ ts = (Trap.TrapScope)p;
+ }
+ }
+ }
+ t = ts.t.next;
+ ts.cascadeHappened = true;
+ while (t != null && t.f.numFormalArgs == 0) t = t.next;
+ if (t == null) { target = ts.t.trapee; key = ts.t.name; }
+
+ } else if (target instanceof Trap.TrapScope && key.equals(((Trap.TrapScope)target).t.name)) {
+ throw je("tried to put to " + key + " inside a trap it owns; use cascade instead");
+
+ } else if (target instanceof JS) {
+ if (target instanceof JSScope) {
+ JSScope p = (JSScope)target; // search the scope-path for the trap
+ t = p.getTrap(key);
+ while (t == null && p.getParentScope() != null) { p = p.getParentScope(); t = p.getTrap(key); }
+ } else {
+ t = ((JS)target).getTrap(key);
+ }
+ while (t != null && t.f.numFormalArgs == 0) t = t.next; // find the first write trap
+ }
+ if (t != null) {
+ stack.push(new CallMarker(this));
+ JSArray args = new JSArray();
+ args.addElement(val);
+ stack.push(args);
+ f = t.f;
+ scope = new Trap.TrapScope(f.parentScope, t, val);
+ pc = -1;
+ break;
+ }
+ ((JS)target).put(key, val);
+ if (pausecount > initialPauseCount) { pc++; return null; } // we were paused
+ stack.push(val);
+ break;
+ }
+
+ case GET:
+ case GET_PRESERVE: {
+ Object o, v;
+ if (op == GET) {
+ v = arg == null ? stack.pop() : arg;
+ o = stack.pop();
+ } else {
+ v = stack.pop();
+ o = stack.peek();
+ stack.push(v);
+ }
+ Object ret = null;
+ if (v == null) throw je("tried to get the null key from " + o);
+ if (o == null) throw je("tried to get property \"" + v + "\" from the null object");
+ if (o instanceof String || o instanceof Number || o instanceof Boolean) {
+ ret = getFromPrimitive(o,v);
+ stack.push(ret);
+ break;
+ } else if (o instanceof JS) {
+ Trap t = null;
+ if (o instanceof Trap.TrapScope && v.equals("cascade")) {
+ t = ((Trap.TrapScope)o).t.next;
+ while (t != null && t.f.numFormalArgs != 0) t = t.next;
+ if (t == null) { v = ((Trap.TrapScope)o).t.name; o = ((Trap.TrapScope)o).t.trapee; }
+
+ } else if (o instanceof JS) {
+ if (o instanceof JSScope) {
+ JSScope p = (JSScope)o; // search the scope-path for the trap
+ t = p.getTrap(v);
+ while (t == null && p.getParentScope() != null) { p = p.getParentScope(); t = p.getTrap(v); }
+ } else {
+ t = ((JS)o).getTrap(v);
+ }
+ while (t != null && t.f.numFormalArgs != 0) t = t.next; // get first read trap
+ }
+ if (t != null) {
+ stack.push(new CallMarker(this));
+ JSArray args = new JSArray();
+ stack.push(args);
+ f = t.f;
+ scope = new Trap.TrapScope(f.parentScope, t, null);
+ ((Trap.TrapScope)scope).cascadeHappened = true;
+ pc = -1;
+ break;
+ }
+ ret = ((JS)o).get(v);
+ if (ret == JS.METHOD) ret = new Stub((JS)o, v);
+ if (pausecount > initialPauseCount) { pc++; return null; } // we were paused
+ stack.push(ret);
+ break;
+ }
+ throw je("tried to get property " + v + " from a " + o.getClass().getName());
+ }
+
+ case CALL: case CALLMETHOD: {
+ int numArgs = JS.toInt(arg);
+ Object method = null;
+ Object ret = null;
+ Object object = stack.pop();
+
+ if (op == CALLMETHOD) {
+ if (object == JS.METHOD) {
+ method = stack.pop();
+ object = stack.pop();
+ } else if (object == null) {
+ Object name = stack.pop();
+ stack.pop();
+ throw new JSExn("function '"+name+"' not found");
+ } else {
+ stack.pop();
+ stack.pop();
+ }
+ }
+ Object[] rest = numArgs > 3 ? new Object[numArgs - 3] : null;
+ for(int i=numArgs - 1; i>2; i--) rest[i-3] = stack.pop();
+ Object a2 = numArgs <= 2 ? null : stack.pop();
+ Object a1 = numArgs <= 1 ? null : stack.pop();
+ Object a0 = numArgs <= 0 ? null : stack.pop();
+
+ if (object instanceof String || object instanceof Number || object instanceof Boolean) {
+ ret = callMethodOnPrimitive(object, method, a0, a1, a2, null, numArgs);
+
+ } else if (object instanceof JSFunction) {
+ // FIXME: use something similar to call0/call1/call2 here
+ JSArray arguments = new JSArray();
+ for(int i=0; i<numArgs; i++) arguments.addElement(i==0?a0:i==1?a1:i==2?a2:rest[i-3]);
+ stack.push(new CallMarker(this));
+ stack.push(arguments);
+ f = (JSFunction)object;
+ scope = new JSScope(f.parentScope);
+ pc = -1;
+ break;
+
+ } else if (object instanceof JS) {
+ JS c = (JS)object;
+ ret = method == null ? c.call(a0, a1, a2, rest, numArgs) : c.callMethod(method, a0, a1, a2, rest, numArgs);
+
+ } else {
+ throw new JSExn("can't call a " + object + " @" + pc + "\n" + f.dump());
+
+ }
+ if (pausecount > initialPauseCount) { pc++; return null; }
+ stack.push(ret);
+ break;
+ }
+
+ case THROW:
+ throw new JSExn(stack.pop(), stack, f, pc, scope);
+
+ /* FIXME
+ case MAKE_GRAMMAR: {
+ final Grammar r = (Grammar)arg;
+ final JSScope final_scope = scope;
+ Grammar r2 = new Grammar() {
+ public int match(String s, int start, Hash v, JSScope scope) throws JSExn {
+ return r.match(s, start, v, final_scope);
+ }
+ public int matchAndWrite(String s, int start, Hash v, JSScope scope, String key) throws JSExn {
+ return r.matchAndWrite(s, start, v, final_scope, key);
+ }
+ public Object call(Object a0, Object a1, Object a2, Object[] rest, int nargs) throws JSExn {
+ Hash v = new Hash();
+ r.matchAndWrite((String)a0, 0, v, final_scope, "foo");
+ return v.get("foo");
+ }
+ };
+ Object obj = stack.pop();
+ if (obj != null && obj instanceof Grammar) r2 = new Grammar.Alternative((Grammar)obj, r2);
+ stack.push(r2);
+ break;
+ }
+ */
+ case ADD_TRAP: case DEL_TRAP: {
+ Object val = stack.pop();
+ Object key = stack.pop();
+ Object obj = stack.peek();
+ // A trap addition/removal
+ JS js = obj instanceof JSScope ? ((JSScope)obj).top() : (JS) obj;
+ if(op == ADD_TRAP) js.addTrap(key, (JSFunction)val);
+ else js.delTrap(key, (JSFunction)val);
+ break;
+ }
+
+ case ASSIGN_SUB: case ASSIGN_ADD: {
+ Object val = stack.pop();
+ Object key = stack.pop();
+ Object obj = stack.peek();
+ // The following setup is VERY important. The generated bytecode depends on the stack
+ // being setup like this (top to bottom) KEY, OBJ, VAL, KEY, OBJ
+ stack.push(key);
+ stack.push(val);
+ stack.push(obj);
+ stack.push(key);
+ break;
+ }
+
+ case ADD: {
+ int count = ((Number)arg).intValue();
+ if(count < 2) throw new Error("this should never happen");
+ if(count == 2) {
+ // common case
+ Object right = stack.pop();
+ Object left = stack.pop();
+ if(left instanceof String || right instanceof String)
+ stack.push(JS.toString(left).concat(JS.toString(right)));
+ else stack.push(JS.N(JS.toDouble(left) + JS.toDouble(right)));
+ } else {
+ Object[] args = new Object[count];
+ while(--count >= 0) args[count] = stack.pop();
+ if(args[0] instanceof String) {
+ StringBuffer sb = new StringBuffer(64);
+ for(int i=0;i<args.length;i++) sb.append(JS.toString(args[i]));
+ stack.push(sb.toString());
+ } else {
+ int numStrings = 0;
+ for(int i=0;i<args.length;i++) if(args[i] instanceof String) numStrings++;
+ if(numStrings == 0) {
+ double d = 0.0;
+ for(int i=0;i<args.length;i++) d += JS.toDouble(args[i]);
+ stack.push(JS.N(d));
+ } else {
+ int i=0;
+ StringBuffer sb = new StringBuffer(64);
+ if(!(args[0] instanceof String || args[1] instanceof String)) {
+ double d=0.0;
+ do {
+ d += JS.toDouble(args[i++]);
+ } while(!(args[i] instanceof String));
+ sb.append(JS.toString(JS.N(d)));
+ }
+ while(i < args.length) sb.append(JS.toString(args[i++]));
+ stack.push(sb.toString());
+ }
+ }
+ }
+ break;
+ }
+
+ default: {
+ Object right = stack.pop();
+ Object left = stack.pop();
+ switch(op) {
+
+ case BITOR: stack.push(JS.N(JS.toLong(left) | JS.toLong(right))); break;
+ case BITXOR: stack.push(JS.N(JS.toLong(left) ^ JS.toLong(right))); break;
+ case BITAND: stack.push(JS.N(JS.toLong(left) & JS.toLong(right))); break;
+
+ case SUB: stack.push(JS.N(JS.toDouble(left) - JS.toDouble(right))); break;
+ case MUL: stack.push(JS.N(JS.toDouble(left) * JS.toDouble(right))); break;
+ case DIV: stack.push(JS.N(JS.toDouble(left) / JS.toDouble(right))); break;
+ case MOD: stack.push(JS.N(JS.toDouble(left) % JS.toDouble(right))); break;
+
+ case LSH: stack.push(JS.N(JS.toLong(left) << JS.toLong(right))); break;
+ case RSH: stack.push(JS.N(JS.toLong(left) >> JS.toLong(right))); break;
+ case URSH: stack.push(JS.N(JS.toLong(left) >>> JS.toLong(right))); break;
+
+ case LT: case LE: case GT: case GE: {
+ if (left == null) left = JS.N(0);
+ if (right == null) right = JS.N(0);
+ int result = 0;
+ if (left instanceof String || right instanceof String) {
+ result = left.toString().compareTo(right.toString());
+ } else {
+ result = (int)java.lang.Math.ceil(JS.toDouble(left) - JS.toDouble(right));
+ }
+ stack.push(JS.B((op == LT && result < 0) || (op == LE && result <= 0) ||
+ (op == GT && result > 0) || (op == GE && result >= 0)));
+ break;
+ }
+
+ case EQ:
+ case NE: {
+ Object l = left;
+ Object r = right;
+ boolean ret;
+ if (l == null) { Object tmp = r; r = l; l = tmp; }
+ if (l == null && r == null) ret = true;
+ else if (r == null) ret = false; // l != null, so its false
+ else if (l instanceof Boolean) ret = JS.B(JS.toBoolean(r)).equals(l);
+ else if (l instanceof Number) ret = JS.toNumber(r).doubleValue() == JS.toNumber(l).doubleValue();
+ else if (l instanceof String) ret = r != null && l.equals(r.toString());
+ else ret = l.equals(r);
+ stack.push(JS.B(op == EQ ? ret : !ret)); break;
+ }
+
+ default: throw new Error("unknown opcode " + op);
+ } }
+ }
+
+ } catch(JSExn e) {
+ while(stack.size() > 0) {
+ Object o = stack.pop();
+ if (o instanceof CatchMarker || o instanceof TryMarker) {
+ boolean inCatch = o instanceof CatchMarker;
+ if(inCatch) {
+ o = stack.pop();
+ if(((TryMarker)o).finallyLoc < 0) continue; // no finally block, keep going
+ }
+ if(!inCatch && ((TryMarker)o).catchLoc >= 0) {
+ // run the catch block, this will implicitly run the finally block, if it exists
+ stack.push(o);
+ stack.push(catchMarker);
+ stack.push(e.getObject());
+ f = ((TryMarker)o).f;
+ scope = ((TryMarker)o).scope;
+ pc = ((TryMarker)o).catchLoc - 1;
+ continue OUTER;
+ } else {
+ stack.push(new FinallyData(e));
+ f = ((TryMarker)o).f;
+ scope = ((TryMarker)o).scope;
+ pc = ((TryMarker)o).finallyLoc - 1;
+ continue OUTER;
+ }
+ }
+ }
+ throw e;
+ } // end try/catch
+ } // end for
+ }
+
+
+
+ // Markers //////////////////////////////////////////////////////////////////////
+
+ public static class CallMarker {
+ int pc;
+ JSScope scope;
+ JSFunction f;
+ public CallMarker(Interpreter cx) { pc = cx.pc + 1; scope = cx.scope; f = cx.f; }
+ }
+
+ public static class CatchMarker { }
+ private static CatchMarker catchMarker = new CatchMarker();
+
+ public static class LoopMarker {
+ public int location;
+ public String label;
+ public JSScope scope;
+ public LoopMarker(int location, String label, JSScope scope) {
+ this.location = location;
+ this.label = label;
+ this.scope = scope;
+ }
+ }
+ public static class TryMarker {
+ public int catchLoc;
+ public int finallyLoc;
+ public JSScope scope;
+ public JSFunction f;
+ public TryMarker(int catchLoc, int finallyLoc, Interpreter cx) {
+ this.catchLoc = catchLoc;
+ this.finallyLoc = finallyLoc;
+ this.scope = cx.scope;
+ this.f = cx.f;
+ }
+ }
+ public static class FinallyData {
+ public int op;
+ public Object arg;
+ public JSExn exn;
+ public FinallyData(int op) { this(op,null); }
+ public FinallyData(int op, Object arg) { this.op = op; this.arg = arg; }
+ public FinallyData(JSExn exn) { this.exn = exn; } // Just throw this exn
+ }
+
+
+ // Operations on Primitives //////////////////////////////////////////////////////////////////////
+
+ static Object callMethodOnPrimitive(Object o, Object method, Object arg0, Object arg1, Object arg2, Object[] rest, int alength) throws JSExn {
+ if (method == null || !(method instanceof String) || "".equals(method))
+ throw new JSExn("attempt to call a non-existant method on a primitive");
+
+ if (o instanceof Number) {
+ //#switch(method)
+ case "toFixed": throw new JSExn("toFixed() not implemented");
+ case "toExponential": throw new JSExn("toExponential() not implemented");
+ case "toPrecision": throw new JSExn("toPrecision() not implemented");
+ case "toString": {
+ int radix = alength >= 1 ? JS.toInt(arg0) : 10;
+ return Long.toString(((Number)o).longValue(),radix);
+ }
+ //#end
+ } else if (o instanceof Boolean) {
+ // No methods for Booleans
+ throw new JSExn("attempt to call a method on a Boolean");
+ }
+
+ String s = JS.toString(o);
+ int slength = s.length();
+ //#switch(method)
+ case "substring": {
+ int a = alength >= 1 ? JS.toInt(arg0) : 0;
+ int b = alength >= 2 ? JS.toInt(arg1) : slength;
+ if (a > slength) a = slength;
+ if (b > slength) b = slength;
+ if (a < 0) a = 0;
+ if (b < 0) b = 0;
+ if (a > b) { int tmp = a; a = b; b = tmp; }
+ return s.substring(a,b);
+ }
+ case "substr": {
+ int start = alength >= 1 ? JS.toInt(arg0) : 0;
+ int len = alength >= 2 ? JS.toInt(arg1) : Integer.MAX_VALUE;
+ if (start < 0) start = slength + start;
+ if (start < 0) start = 0;
+ if (len < 0) len = 0;
+ if (len > slength - start) len = slength - start;
+ if (len <= 0) return "";
+ return s.substring(start,start+len);
+ }
+ case "charAt": {
+ int p = alength >= 1 ? JS.toInt(arg0) : 0;
+ if (p < 0 || p >= slength) return "";
+ return s.substring(p,p+1);
+ }
+ case "charCodeAt": {
+ int p = alength >= 1 ? JS.toInt(arg0) : 0;
+ if (p < 0 || p >= slength) return JS.N(Double.NaN);
+ return JS.N(s.charAt(p));
+ }
+ case "concat": {
+ StringBuffer sb = new StringBuffer(slength*2).append(s);
+ for(int i=0;i<alength;i++) sb.append(i==0?arg0:i==1?arg1:i==2?arg2:rest[i-3]);
+ return sb.toString();
+ }
+ case "indexOf": {
+ String search = alength >= 1 ? arg0.toString() : "null";
+ int start = alength >= 2 ? JS.toInt(arg1) : 0;
+ // Java's indexOf handles an out of bounds start index, it'll return -1
+ return JS.N(s.indexOf(search,start));
+ }
+ case "lastIndexOf": {
+ String search = alength >= 1 ? arg0.toString() : "null";
+ int start = alength >= 2 ? JS.toInt(arg1) : 0;
+ // Java's indexOf handles an out of bounds start index, it'll return -1
+ return JS.N(s.lastIndexOf(search,start));
+ }
+ case "match": return JSRegexp.stringMatch(s,arg0);
+ case "replace": return JSRegexp.stringReplace(s,arg0,arg1);
+ case "search": return JSRegexp.stringSearch(s,arg0);
+ case "split": return JSRegexp.stringSplit(s,arg0,arg1,alength);
+ case "toLowerCase": return s.toLowerCase();
+ case "toUpperCase": return s.toUpperCase();
+ case "toString": return s;
+ case "slice": {
+ int a = alength >= 1 ? JS.toInt(arg0) : 0;
+ int b = alength >= 2 ? JS.toInt(arg1) : slength;
+ if (a < 0) a = slength + a;
+ if (b < 0) b = slength + b;
+ if (a < 0) a = 0;
+ if (b < 0) b = 0;
+ if (a > slength) a = slength;
+ if (b > slength) b = slength;
+ if (a > b) return "";
+ return s.substring(a,b);
+ }
+ //#end
+ throw new JSExn("Attempted to call non-existent method: " + method);
+ }
+
+ static Object getFromPrimitive(Object o, Object key) throws JSExn {
+ boolean returnJS = false;
+ if (o instanceof Boolean) {
+ throw new JSExn("Booleans do not have properties");
+ } else if (o instanceof Number) {
+ if (key.equals("toPrecision") || key.equals("toExponential") || key.equals("toFixed"))
+ returnJS = true;
+ }
+ if (!returnJS) {
+ // the string stuff applies to everything
+ String s = o.toString();
+
+ // this is sort of ugly, but this list should never change
+ // These should provide a complete (enough) implementation of the ECMA-262 String object
+
+ //#switch(key)
+ case "length": return JS.N(s.length());
+ case "substring": returnJS = true; break;
+ case "charAt": returnJS = true; break;
+ case "charCodeAt": returnJS = true; break;
+ case "concat": returnJS = true; break;
+ case "indexOf": returnJS = true; break;
+ case "lastIndexOf": returnJS = true; break;
+ case "match": returnJS = true; break;
+ case "replace": returnJS = true; break;
+ case "seatch": returnJS = true; break;
+ case "slice": returnJS = true; break;
+ case "split": returnJS = true; break;
+ case "toLowerCase": returnJS = true; break;
+ case "toUpperCase": returnJS = true; break;
+ case "toString": returnJS = true; break;
+ case "substr": returnJS = true; break;
+ //#end
+ }
+ if (returnJS) {
+ final Object target = o;
+ final String method = key.toString();
+ return new JS() {
+ public Object call(Object a0, Object a1, Object a2, Object[] rest, int nargs) throws JSExn {
+ if (nargs > 2) throw new JSExn("cannot call that method with that many arguments");
+ return callMethodOnPrimitive(target, method, a0, a1, a2, rest, nargs);
+ }
+ };
+ }
+ return null;
+ }
+
+ private static class Stub extends JS {
+ private Object method;
+ JS obj;
+ public Stub(JS obj, Object method) { this.obj = obj; this.method = method; }
+ public Object call(Object a0, Object a1, Object a2, Object[] rest, int nargs) throws JSExn {
+ return ((JS)obj).callMethod(method, a0, a1, a2, rest, nargs);
+ }
+ }
+}
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.js;
+
+import org.ibex.util.*;
+import java.io.*;
+import java.util.*;
+
+/** The minimum set of functionality required for objects which are manipulated by JavaScript */
+public class JS extends org.ibex.util.BalancedTree {
+
+ public static boolean checkAssertions = false;
+
+ public static final Object METHOD = new Object();
+ public final JS unclone() { return _unclone(); }
+ public Enumeration keys() throws JSExn { return entries == null ? emptyEnumeration : entries.keys(); }
+ public Object get(Object key) throws JSExn { return entries == null ? null : entries.get(key, null); }
+ public void put(Object key, Object val) throws JSExn { (entries==null?entries=new Hash():entries).put(key,null,val); }
+ public Object callMethod(Object method, Object a0, Object a1, Object a2, Object[] rest, int nargs) throws JSExn {
+ throw new JSExn("attempted to call the null value (method "+method+")");
+ }
+ public Object call(Object a0, Object a1, Object a2, Object[] rest, int nargs) throws JSExn {
+ throw new JSExn("you cannot call this object (class=" + this.getClass().getName() +")");
+ }
+
+ JS _unclone() { return this; }
+ public static class Cloneable extends JS {
+ public Object jsclone() throws JSExn {
+ return new Clone(this);
+ }
+ }
+
+ public static class Clone extends JS.Cloneable {
+ protected JS.Cloneable clonee = null;
+ JS _unclone() { return clonee.unclone(); }
+ public JS.Cloneable getClonee() { return clonee; }
+ public Clone(JS.Cloneable clonee) { this.clonee = clonee; }
+ public boolean equals(Object o) {
+ if (!(o instanceof JS)) return false;
+ return unclone() == ((JS)o).unclone();
+ }
+ public Enumeration keys() throws JSExn { return clonee.keys(); }
+ public Object get(Object key) throws JSExn { return clonee.get(key); }
+ public void put(Object key, Object val) throws JSExn { clonee.put(key, val); }
+ public Object callMethod(Object method, Object a0, Object a1, Object a2, Object[] rest, int nargs) throws JSExn {
+ return clonee.callMethod(method, a0, a1, a2, rest, nargs);
+ }
+ public Object call(Object a0, Object a1, Object a2, Object[] rest, int nargs) throws JSExn {
+ return clonee.call(a0, a1, a2, rest, nargs);
+ }
+ }
+
+ // Static Interpreter Control Methods ///////////////////////////////////////////////////////////////
+
+ /** log a message with the current JavaScript sourceName/line */
+ public static void log(Object message) { info(message); }
+ public static void debug(Object message) { Log.debug(Interpreter.getSourceName() + ":" + Interpreter.getLine(), message); }
+ public static void info(Object message) { Log.info(Interpreter.getSourceName() + ":" + Interpreter.getLine(), message); }
+ public static void warn(Object message) { Log.warn(Interpreter.getSourceName() + ":" + Interpreter.getLine(), message); }
+ public static void error(Object message) { Log.error(Interpreter.getSourceName() + ":" + Interpreter.getLine(), message); }
+
+ public static class NotPauseableException extends Exception { NotPauseableException() { } }
+
+ /** returns a callback which will restart the context; expects a value to be pushed onto the stack when unpaused */
+ public static UnpauseCallback pause() throws NotPauseableException {
+ Interpreter i = Interpreter.current();
+ if (i.pausecount == -1) throw new NotPauseableException();
+ i.pausecount++;
+ return new JS.UnpauseCallback(i);
+ }
+
+ public static class UnpauseCallback implements Task {
+ Interpreter i;
+ UnpauseCallback(Interpreter i) { this.i = i; }
+ public void perform() throws JSExn { unpause(null); }
+ public void unpause(Object o) throws JSExn {
+ // FIXME: if o instanceof JSExn, throw it into the JSworld
+ i.stack.push(o);
+ i.resume();
+ }
+ }
+
+
+
+ // Static Helper Methods ///////////////////////////////////////////////////////////////////////////////////
+
+ /** coerce an object to a Boolean */
+ public static boolean toBoolean(Object o) {
+ if (o == null) return false;
+ if (o instanceof Boolean) return ((Boolean)o).booleanValue();
+ if (o instanceof Long) return ((Long)o).longValue() != 0;
+ if (o instanceof Integer) return ((Integer)o).intValue() != 0;
+ if (o instanceof Number) {
+ double d = ((Number) o).doubleValue();
+ // NOTE: d == d is a test for NaN. It should be faster than Double.isNaN()
+ return d != 0.0 && d == d;
+ }
+ if (o instanceof String) return ((String)o).length() != 0;
+ return true;
+ }
+
+ /** coerce an object to a Long */
+ public static long toLong(Object o) { return toNumber(o).longValue(); }
+
+ /** coerce an object to an Int */
+ public static int toInt(Object o) { return toNumber(o).intValue(); }
+
+ /** coerce an object to a Double */
+ public static double toDouble(Object o) { return toNumber(o).doubleValue(); }
+
+ /** coerce an object to a Number */
+ public static Number toNumber(Object o) {
+ if (o == null) return ZERO;
+ if (o instanceof Number) return ((Number)o);
+
+ // NOTE: There are about 3 pages of rules in ecma262 about string to number conversions
+ // We aren't even close to following all those rules. We probably never will be.
+ if (o instanceof String) try { return N((String)o); } catch (NumberFormatException e) { return N(Double.NaN); }
+ if (o instanceof Boolean) return ((Boolean)o).booleanValue() ? N(1) : ZERO;
+ throw new Error("toNumber() got object of type " + o.getClass().getName() + " which we don't know how to handle");
+ }
+
+ /** coerce an object to a String */
+ public static String toString(Object o) {
+ if(o == null) return "null";
+ if(o instanceof String) return (String) o;
+ if(o instanceof Integer || o instanceof Long || o instanceof Boolean) return o.toString();
+ if(o instanceof JSArray) return o.toString();
+ if(o instanceof JSDate) return o.toString();
+ if(o instanceof Double || o instanceof Float) {
+ double d = ((Number)o).doubleValue();
+ if((int)d == d) return Integer.toString((int)d);
+ return o.toString();
+ }
+ throw new RuntimeException("can't coerce "+o+" [" + o.getClass().getName() + "] to type String.");
+ }
+
+ // Instance Methods ////////////////////////////////////////////////////////////////////
+
+ public static final Integer ZERO = new Integer(0);
+
+ // this gets around a wierd fluke in the Java type checking rules for ?..:
+ public static final Object T = Boolean.TRUE;
+ public static final Object F = Boolean.FALSE;
+
+ public static final Boolean B(boolean b) { return b ? Boolean.TRUE : Boolean.FALSE; }
+ public static final Boolean B(int i) { return i==0 ? Boolean.FALSE : Boolean.TRUE; }
+ public static final Number N(String s) { return s.indexOf('.') == -1 ? N(Integer.parseInt(s)) : new Double(s); }
+ public static final Number N(double d) { return (int)d == d ? N((int)d) : new Double(d); }
+ public static final Number N(long l) { return N((int)l); }
+
+ private static final Integer[] smallIntCache = new Integer[65535 / 4];
+ private static final Integer[] largeIntCache = new Integer[65535 / 4];
+ public static final Number N(int i) {
+ Integer ret = null;
+ int idx = i + smallIntCache.length / 2;
+ if (idx < smallIntCache.length && idx > 0) {
+ ret = smallIntCache[idx];
+ if (ret != null) return ret;
+ }
+ else ret = largeIntCache[Math.abs(idx % largeIntCache.length)];
+ if (ret == null || ret.intValue() != i) {
+ ret = new Integer(i);
+ if (idx < smallIntCache.length && idx > 0) smallIntCache[idx] = ret;
+ else largeIntCache[Math.abs(idx % largeIntCache.length)] = ret;
+ }
+ return ret;
+ }
+
+ private static Enumeration emptyEnumeration = new Enumeration() {
+ public boolean hasMoreElements() { return false; }
+ public Object nextElement() { throw new NoSuchElementException(); }
+ };
+
+ private Hash entries = null;
+
+ public static JS fromReader(String sourceName, int firstLine, Reader sourceCode) throws IOException {
+ return JSFunction._fromReader(sourceName, firstLine, sourceCode);
+ }
+
+ // HACK: caller can't know if the argument is a JSFunction or not...
+ public static JS cloneWithNewParentScope(JS j, JSScope s) {
+ return ((JSFunction)j)._cloneWithNewParentScope(s);
+ }
+
+
+ // Trap support //////////////////////////////////////////////////////////////////////////////
+
+ /** override and return true to allow placing traps on this object.
+ * if isRead true, this is a read trap, otherwise write trap
+ **/
+ protected boolean isTrappable(Object name, boolean isRead) { return true; }
+
+ /** performs a put, triggering traps if present; traps are run in an unpauseable interpreter */
+ public void putAndTriggerTraps(Object key, Object value) throws JSExn {
+ Trap t = getTrap(key);
+ if (t != null) t.invoke(value);
+ else put(key, value);
+ }
+
+ /** performs a get, triggering traps if present; traps are run in an unpauseable interpreter */
+ public Object getAndTriggerTraps(Object key) throws JSExn {
+ Trap t = getTrap(key);
+ if (t != null) return t.invoke();
+ else return get(key);
+ }
+
+ /** retrieve a trap from the entries hash */
+ protected final Trap getTrap(Object key) {
+ return entries == null ? null : (Trap)entries.get(key, Trap.class);
+ }
+
+ /** retrieve a trap from the entries hash */
+ protected final void putTrap(Object key, Trap value) {
+ if (entries == null) entries = new Hash();
+ entries.put(key, Trap.class, value);
+ }
+
+ /** adds a trap, avoiding duplicates */
+ protected final void addTrap(Object name, JSFunction f) throws JSExn {
+ if (f.numFormalArgs > 1) throw new JSExn("traps must take either one argument (write) or no arguments (read)");
+ boolean isRead = f.numFormalArgs == 0;
+ if (!isTrappable(name, isRead)) throw new JSExn("not allowed "+(isRead?"read":"write")+" trap on property: "+name);
+ for(Trap t = getTrap(name); t != null; t = t.next) if (t.f == f) return;
+ putTrap(name, new Trap(this, name.toString(), f, (Trap)getTrap(name)));
+ }
+
+ /** deletes a trap, if present */
+ protected final void delTrap(Object name, JSFunction f) {
+ Trap t = (Trap)getTrap(name);
+ if (t == null) return;
+ if (t.f == f) { putTrap(t.name, t.next); return; }
+ for(; t.next != null; t = t.next) if (t.next.f == f) { t.next = t.next.next; return; }
+ }
+
+
+}
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.js;
+
+import org.ibex.util.*;
+import java.util.*;
+
+/** A JavaScript JSArray */
+public class JSArray extends JS {
+ private static final Object NULL = new Object();
+
+ public JSArray() { }
+ public JSArray(int size) { setSize(size); }
+
+ private static int intVal(Object o) {
+ if (o instanceof Number) {
+ int intVal = ((Number)o).intValue();
+ if (intVal == ((Number)o).doubleValue()) return intVal;
+ return Integer.MIN_VALUE;
+ }
+ if (!(o instanceof String)) return Integer.MIN_VALUE;
+ String s = (String)o;
+ for(int i=0; i<s.length(); i++) if (s.charAt(i) < '0' || s.charAt(i) > '9') return Integer.MIN_VALUE;
+ return Integer.parseInt(s);
+ }
+
+ public Object callMethod(Object method, Object a0, Object a1, Object a2, Object[] rest, int nargs) throws JSExn {
+ //#switch(method)
+ case "pop": {
+ int oldSize = size();
+ if(oldSize == 0) return null;
+ return removeElementAt(oldSize-1);
+ }
+ case "reverse": return reverse();
+ case "toString": return join(",");
+ case "shift":
+ if(length() == 0) return null;
+ return removeElementAt(0);
+ case "join":
+ return join(nargs == 0 ? "," : JS.toString(a0));
+ case "sort":
+ return sort(nargs < 1 ? null : a0);
+ case "slice":
+ int start = toInt(nargs < 1 ? null : a0);
+ int end = nargs < 2 ? length() : toInt(a1);
+ return slice(start, end);
+ case "push": {
+ int oldSize = size();
+ for(int i=0; i<nargs; i++) insertElementAt(i==0?a0:i==1?a1:i==2?a2:rest[i-3],oldSize+i);
+ return N(oldSize + nargs);
+ }
+ case "unshift":
+ for(int i=0; i<nargs; i++) insertElementAt(i==0?a0:i==1?a1:i==2?a2:rest[i-3],i);
+ return N(size());
+ case "splice":
+ JSArray array = new JSArray();
+ for(int i=0; i<nargs; i++) array.addElement(i==0?a0:i==1?a1:i==2?a2:rest[i-3]);
+ return splice(array);
+ //#end
+ return super.callMethod(method, a0, a1, a2, rest, nargs);
+ }
+
+ public Object get(Object key) throws JSExn {
+ int i = intVal(key);
+ if (i != Integer.MIN_VALUE) {
+ if (i < 0 || i >= size()) return null;
+ return elementAt(i);
+ }
+ //#switch(key)
+ case "pop": return METHOD;
+ case "reverse": return METHOD;
+ case "toString": return METHOD;
+ case "shift": return METHOD;
+ case "join": return METHOD;
+ case "sort": return METHOD;
+ case "slice": return METHOD;
+ case "push": return METHOD;
+ case "unshift": return METHOD;
+ case "splice": return METHOD;
+ case "length": return N(size());
+ //#end
+ return super.get(key);
+ }
+
+ public void put(Object key, Object val) throws JSExn {
+ if (key.equals("length")) setSize(toInt(val));
+ int i = intVal(key);
+ if (i == Integer.MIN_VALUE)
+ super.put(key, val);
+ else {
+ int oldSize = size();
+ if(i < oldSize) {
+ setElementAt(val,i);
+ } else {
+ if(i > oldSize) setSize(i);
+ insertElementAt(val,i);
+ }
+ }
+ }
+
+ public Enumeration keys() {
+ return new Enumeration() {
+ private int n = size();
+ public boolean hasMoreElements() { return n > 0; }
+ public Object nextElement() {
+ if(n == 0) throw new NoSuchElementException();
+ return new Integer(--n);
+ }
+ };
+ }
+
+ public final void setSize(int newSize) {
+ // FEATURE: This could be done a lot more efficiently in BalancedTree
+ int oldSize = size();
+ for(int i=oldSize;i<newSize;i++) insertElementAt(null,i);
+ for(int i=oldSize-1;i>=newSize;i--) removeElementAt(i);
+ }
+
+ public final int length() { return size(); }
+ public final Object elementAt(int i) {
+ if(i < 0 || i >= size()) throw new ArrayIndexOutOfBoundsException(i);
+ Object o = getNode(i);
+ return o == NULL ? null : o;
+ }
+ public final void addElement(Object o) {
+ insertNode(size(),o==null ? NULL : o);
+ }
+ public final void setElementAt(Object o, int i) {
+ if(i < 0 || i >= size()) throw new ArrayIndexOutOfBoundsException(i);
+ replaceNode(i,o==null ? NULL : o);
+ }
+ public final void insertElementAt(Object o, int i) {
+ if(i < 0 || i > size()) throw new ArrayIndexOutOfBoundsException(i);
+ insertNode(i,o==null ? NULL : o);
+ }
+ public final Object removeElementAt(int i) {
+ if(i < 0 || i >= size()) throw new ArrayIndexOutOfBoundsException(i);
+ Object o = deleteNode(i);
+ return o == NULL ? null : o;
+ }
+
+ public final int size() { return treeSize(); }
+ public String typeName() { return "array"; }
+
+ private Object join(String sep) {
+ int length = size();
+ if(length == 0) return "";
+ StringBuffer sb = new StringBuffer(64);
+ int i=0;
+ while(true) {
+ Object o = elementAt(i);
+ if(o != null) sb.append(JS.toString(o));
+ if(++i == length) break;
+ sb.append(sep);
+ }
+ return sb.toString();
+ }
+
+ // FEATURE: Implement this more efficiently
+ private Object reverse() {
+ int size = size();
+ if(size < 2) return this;
+ Vec vec = toVec();
+ clear();
+ for(int i=size-1,j=0;i>=0;i--,j++) insertElementAt(vec.elementAt(i),j);
+ return this;
+ }
+
+ private Object slice(int start, int end) {
+ int length = length();
+ if(start < 0) start = length+start;
+ if(end < 0) end = length+end;
+ if(start < 0) start = 0;
+ if(end < 0) end = 0;
+ if(start > length) start = length;
+ if(end > length) end = length;
+ JSArray a = new JSArray(end-start);
+ for(int i=0;i<end-start;i++)
+ a.setElementAt(elementAt(start+i),i);
+ return a;
+ }
+
+ private static final Vec.CompareFunc defaultSort = new Vec.CompareFunc() {
+ public int compare(Object a, Object b) {
+ return JS.toString(a).compareTo(JS.toString(b));
+ }
+ };
+ private Object sort(Object tmp) throws JSExn {
+ Vec vec = toVec();
+ if(tmp instanceof JS) {
+ final JSArray funcArgs = new JSArray(2);
+ final JS jsFunc = (JS) tmp;
+ vec.sort(new Vec.CompareFunc() {
+ public int compare(Object a, Object b) {
+ try {
+ funcArgs.setElementAt(a,0);
+ funcArgs.setElementAt(b,1);
+ return JS.toInt(jsFunc.call(a, b, null, null, 2));
+ } catch (Exception e) {
+ // FIXME
+ throw new JSRuntimeExn(e.toString());
+ }
+ }
+ });
+ } else {
+ vec.sort(defaultSort);
+ }
+ setFromVec(vec);
+ return this;
+ }
+
+ private Object splice(JSArray args) {
+ int oldLength = length();
+ int start = JS.toInt(args.length() < 1 ? null : args.elementAt(0));
+ int deleteCount = JS.toInt(args.length() < 2 ? null : args.elementAt(1));
+ int newCount = args.length() - 2;
+ if(newCount < 0) newCount = 0;
+ if(start < 0) start = oldLength+start;
+ if(start < 0) start = 0;
+ if(start > oldLength) start = oldLength;
+ if(deleteCount < 0) deleteCount = 0;
+ if(deleteCount > oldLength-start) deleteCount = oldLength-start;
+ int newLength = oldLength - deleteCount + newCount;
+ int lengthChange = newLength - oldLength;
+ JSArray ret = new JSArray(deleteCount);
+ for(int i=0;i<deleteCount;i++)
+ ret.setElementAt(elementAt(start+i),i);
+ if(lengthChange > 0) {
+ setSize(newLength);
+ for(int i=newLength-1;i>=start+newCount;i--)
+ setElementAt(elementAt(i-lengthChange),i);
+ } else if(lengthChange < 0) {
+ for(int i=start+newCount;i<newLength;i++)
+ setElementAt(elementAt(i-lengthChange),i);
+ setSize(newLength);
+ }
+ for(int i=0;i<newCount;i++)
+ setElementAt(args.elementAt(i+2),start+i);
+ return ret;
+ }
+
+ protected Vec toVec() {
+ int count = size();
+ Vec vec = new Vec();
+ vec.setSize(count);
+ for(int i=0;i<count;i++) {
+ Object o = getNode(i);
+ vec.setElementAt(o == NULL ? null : o,i);
+ }
+ return vec;
+ }
+
+ protected void setFromVec(Vec vec) {
+ int count = vec.size();
+ clear();
+ for(int i=0;i<count;i++) {
+ Object o = vec.elementAt(i);
+ insertNode(i,o==null ? NULL : o);
+ }
+ }
+
+ public String toString() { return JS.toString(join(",")); }
+}
--- /dev/null
+/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * The contents of this file are subject to the Netscape Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/NPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * The Original Code is Rhino code, released
+ * May 6, 1999.
+ *
+ * The Initial Developer of the Original Code is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1997-1999 Netscape Communications Corporation. All
+ * Rights Reserved.
+ *
+ * Contributor(s):
+ * Norris Boyd
+ * Mike McCabe
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU Public License (the "GPL"), in which case the
+ * provisions of the GPL are applicable instead of those above.
+ * If you wish to allow use of your version of this file only
+ * under the terms of the GPL and not to allow others to use your
+ * version of this file under the NPL, indicate your decision by
+ * deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL. If you do not delete
+ * the provisions above, a recipient may use your version of this
+ * file under either the NPL or the GPL.
+ */
+
+package org.ibex.js;
+
+import java.text.DateFormat;
+
+/**
+ * This class implements the Date native object.
+ * See ECMA 15.9.
+ * @author Mike McCabe
+ * @author Adam Megacz (many modifications
+ */
+public class JSDate extends JS {
+
+ public JSDate() {
+ if (thisTimeZone == null) {
+ // j.u.TimeZone is synchronized, so setting class statics from it
+ // should be OK.
+ thisTimeZone = java.util.TimeZone.getDefault();
+ LocalTZA = thisTimeZone.getRawOffset();
+ }
+ }
+
+ public String toString() { return date_format(date, FORMATSPEC_FULL); }
+
+ public Object callMethod(Object method, Object a0, Object a1, Object a2, Object[] rest, int nargs) throws JSExn {
+ switch(nargs) {
+ case 0: {
+ //#switch(method)
+ case "toString": return date_format(date, FORMATSPEC_FULL);
+ case "toTimeString": return date_format(date, FORMATSPEC_TIME);
+ case "toDateString": return date_format(date, FORMATSPEC_DATE);
+ case "toLocaleString": return toLocaleString(date);
+ case "toLocaleTimeString": return toLocaleTimeString(date);
+ case "toLocaleDateString": return toLocaleDateString(date);
+ case "toUTCString": return toUTCString(date);
+ case "valueOf": return N(this.date);
+ case "getTime": return N(this.date);
+ case "getYear": return N(getYear(date));
+ case "getFullYear": return N(YearFromTime(LocalTime(date)));
+ case "getUTCFullYear": return N(YearFromTime(date));
+ case "getMonth": return N(MonthFromTime(LocalTime(date)));
+ case "getUTCMonth": return N(MonthFromTime(date));
+ case "getDate": return N(DateFromTime(LocalTime(date)));
+ case "getUTCDate": return N(DateFromTime(date));
+ case "getDay": return N(WeekDay(LocalTime(date)));
+ case "getUTCDay": return N(WeekDay(date));
+ case "getHours": return N(HourFromTime(LocalTime(date)));
+ case "getUTCHours": return N(HourFromTime(date));
+ case "getMinutes": return N(MinFromTime(LocalTime(date)));
+ case "getUTCMinutes": return N(MinFromTime(date));
+ case "getSeconds": return N(SecFromTime(LocalTime(date)));
+ case "getUTCSeconds": return N(SecFromTime(date));
+ case "getMilliseconds": return N(msFromTime(LocalTime(date)));
+ case "getUTCMilliseconds": return N(msFromTime(date));
+ case "getTimezoneOffset": return N(getTimezoneOffset(date));
+ //#end
+ return super.callMethod(method, a0, a1, a2, rest, nargs);
+ }
+ case 1: {
+ //#switch(method)
+ case "setTime": return N(this.setTime(toDouble(a0)));
+ case "setYear": return N(this.setYear(toDouble(a0)));
+ //#end
+ // fall through
+ }
+ default: {
+ Object[] args = new Object[nargs];
+ for(int i=0; i<nargs; i++) args[i] = i==0 ? a0 : i==1 ? a1 : i==2 ? a2 : rest[i-3];
+ //#switch(method)
+ case "setMilliseconds": return N(this.makeTime(args, 1, true));
+ case "setUTCMilliseconds": return N(this.makeTime(args, 1, false));
+ case "setSeconds": return N(this.makeTime(args, 2, true));
+ case "setUTCSeconds": return N(this.makeTime(args, 2, false));
+ case "setMinutes": return N(this.makeTime(args, 3, true));
+ case "setUTCMinutes": return N(this.makeTime(args, 3, false));
+ case "setHours": return N(this.makeTime(args, 4, true));
+ case "setUTCHours": return N(this.makeTime(args, 4, false));
+ case "setDate": return N(this.makeDate(args, 1, true));
+ case "setUTCDate": return N(this.makeDate(args, 1, false));
+ case "setMonth": return N(this.makeDate(args, 2, true));
+ case "setUTCMonth": return N(this.makeDate(args, 2, false));
+ case "setFullYear": return N(this.makeDate(args, 3, true));
+ case "setUTCFullYear": return N(this.makeDate(args, 3, false));
+ //#end
+ }
+ }
+ return super.callMethod(method, a0, a1, a2, rest, nargs);
+ }
+
+ public Object get(Object key) throws JSExn {
+ //#switch(key)
+ case "toString": return METHOD;
+ case "toTimeString": return METHOD;
+ case "toDateString": return METHOD;
+ case "toLocaleString": return METHOD;
+ case "toLocaleTimeString": return METHOD;
+ case "toLocaleDateString": return METHOD;
+ case "toUTCString": return METHOD;
+ case "valueOf": return METHOD;
+ case "getTime": return METHOD;
+ case "getYear": return METHOD;
+ case "getFullYear": return METHOD;
+ case "getUTCFullYear": return METHOD;
+ case "getMonth": return METHOD;
+ case "getUTCMonth": return METHOD;
+ case "getDate": return METHOD;
+ case "getUTCDate": return METHOD;
+ case "getDay": return METHOD;
+ case "getUTCDay": return METHOD;
+ case "getHours": return METHOD;
+ case "getUTCHours": return METHOD;
+ case "getMinutes": return METHOD;
+ case "getUTCMinutes": return METHOD;
+ case "getSeconds": return METHOD;
+ case "getUTCSeconds": return METHOD;
+ case "getMilliseconds": return METHOD;
+ case "getUTCMilliseconds": return METHOD;
+ case "getTimezoneOffset": return METHOD;
+ case "setTime": return METHOD;
+ case "setYear": return METHOD;
+ case "setMilliseconds": return METHOD;
+ case "setUTCMilliseconds": return METHOD;
+ case "setSeconds": return METHOD;
+ case "setUTCSeconds": return METHOD;
+ case "setMinutes": return METHOD;
+ case "setUTCMinutes": return METHOD;
+ case "setHours": return METHOD;
+ case "setUTCHours": return METHOD;
+ case "setDate": return METHOD;
+ case "setUTCDate": return METHOD;
+ case "setMonth": return METHOD;
+ case "setUTCMonth": return METHOD;
+ case "setFullYear": return METHOD;
+ case "setUTCFullYear": return METHOD;
+ //#end
+ return super.get(key);
+ }
+
+ /* ECMA helper functions */
+
+ private static final double HalfTimeDomain = 8.64e15;
+ private static final double HoursPerDay = 24.0;
+ private static final double MinutesPerHour = 60.0;
+ private static final double SecondsPerMinute = 60.0;
+ private static final double msPerSecond = 1000.0;
+ private static final double MinutesPerDay = (HoursPerDay * MinutesPerHour);
+ private static final double SecondsPerDay = (MinutesPerDay * SecondsPerMinute);
+ private static final double SecondsPerHour = (MinutesPerHour * SecondsPerMinute);
+ private static final double msPerDay = (SecondsPerDay * msPerSecond);
+ private static final double msPerHour = (SecondsPerHour * msPerSecond);
+ private static final double msPerMinute = (SecondsPerMinute * msPerSecond);
+
+ private static double Day(double t) {
+ return java.lang.Math.floor(t / msPerDay);
+ }
+
+ private static double TimeWithinDay(double t) {
+ double result;
+ result = t % msPerDay;
+ if (result < 0)
+ result += msPerDay;
+ return result;
+ }
+
+ private static int DaysInYear(int y) {
+ if (y % 4 == 0 && (y % 100 != 0 || y % 400 == 0))
+ return 366;
+ else
+ return 365;
+ }
+
+
+ /* math here has to be f.p, because we need
+ * floor((1968 - 1969) / 4) == -1
+ */
+ private static double DayFromYear(double y) {
+ return ((365 * ((y)-1970) + java.lang.Math.floor(((y)-1969)/4.0)
+ - java.lang.Math.floor(((y)-1901)/100.0) + java.lang.Math.floor(((y)-1601)/400.0)));
+ }
+
+ private static double TimeFromYear(double y) {
+ return DayFromYear(y) * msPerDay;
+ }
+
+ private static int YearFromTime(double t) {
+ int lo = (int) java.lang.Math.floor((t / msPerDay) / 366) + 1970;
+ int hi = (int) java.lang.Math.floor((t / msPerDay) / 365) + 1970;
+ int mid;
+
+ /* above doesn't work for negative dates... */
+ if (hi < lo) {
+ int temp = lo;
+ lo = hi;
+ hi = temp;
+ }
+
+ /* Use a simple binary search algorithm to find the right
+ year. This seems like brute force... but the computation
+ of hi and lo years above lands within one year of the
+ correct answer for years within a thousand years of
+ 1970; the loop below only requires six iterations
+ for year 270000. */
+ while (hi > lo) {
+ mid = (hi + lo) / 2;
+ if (TimeFromYear(mid) > t) {
+ hi = mid - 1;
+ } else {
+ if (TimeFromYear(mid) <= t) {
+ int temp = mid + 1;
+ if (TimeFromYear(temp) > t) {
+ return mid;
+ }
+ lo = mid + 1;
+ }
+ }
+ }
+ return lo;
+ }
+
+ private static boolean InLeapYear(double t) {
+ return DaysInYear(YearFromTime(t)) == 366;
+ }
+
+ private static int DayWithinYear(double t) {
+ int year = YearFromTime(t);
+ return (int) (Day(t) - DayFromYear(year));
+ }
+ /*
+ * The following array contains the day of year for the first day of
+ * each month, where index 0 is January, and day 0 is January 1.
+ */
+
+ private static double DayFromMonth(int m, boolean leap) {
+ int day = m * 30;
+
+ if (m >= 7) { day += m / 2 - 1; }
+ else if (m >= 2) { day += (m - 1) / 2 - 1; }
+ else { day += m; }
+
+ if (leap && m >= 2) { ++day; }
+
+ return day;
+ }
+
+ private static int MonthFromTime(double t) {
+ int d, step;
+
+ d = DayWithinYear(t);
+
+ if (d < (step = 31))
+ return 0;
+
+ // Originally coded as step += (InLeapYear(t) ? 29 : 28);
+ // but some jits always returned 28!
+ if (InLeapYear(t))
+ step += 29;
+ else
+ step += 28;
+
+ if (d < step)
+ return 1;
+ if (d < (step += 31))
+ return 2;
+ if (d < (step += 30))
+ return 3;
+ if (d < (step += 31))
+ return 4;
+ if (d < (step += 30))
+ return 5;
+ if (d < (step += 31))
+ return 6;
+ if (d < (step += 31))
+ return 7;
+ if (d < (step += 30))
+ return 8;
+ if (d < (step += 31))
+ return 9;
+ if (d < (step += 30))
+ return 10;
+ return 11;
+ }
+
+ private static int DateFromTime(double t) {
+ int d, step, next;
+
+ d = DayWithinYear(t);
+ if (d <= (next = 30))
+ return d + 1;
+ step = next;
+
+ // Originally coded as next += (InLeapYear(t) ? 29 : 28);
+ // but some jits always returned 28!
+ if (InLeapYear(t))
+ next += 29;
+ else
+ next += 28;
+
+ if (d <= next)
+ return d - step;
+ step = next;
+ if (d <= (next += 31))
+ return d - step;
+ step = next;
+ if (d <= (next += 30))
+ return d - step;
+ step = next;
+ if (d <= (next += 31))
+ return d - step;
+ step = next;
+ if (d <= (next += 30))
+ return d - step;
+ step = next;
+ if (d <= (next += 31))
+ return d - step;
+ step = next;
+ if (d <= (next += 31))
+ return d - step;
+ step = next;
+ if (d <= (next += 30))
+ return d - step;
+ step = next;
+ if (d <= (next += 31))
+ return d - step;
+ step = next;
+ if (d <= (next += 30))
+ return d - step;
+ step = next;
+
+ return d - step;
+ }
+
+ private static int WeekDay(double t) {
+ double result;
+ result = Day(t) + 4;
+ result = result % 7;
+ if (result < 0)
+ result += 7;
+ return (int) result;
+ }
+
+ private static double Now() {
+ return (double) System.currentTimeMillis();
+ }
+
+ /* Should be possible to determine the need for this dynamically
+ * if we go with the workaround... I'm not using it now, because I
+ * can't think of any clean way to make toLocaleString() and the
+ * time zone (comment) in toString match the generated string
+ * values. Currently it's wrong-but-consistent in all but the
+ * most recent betas of the JRE - seems to work in 1.1.7.
+ */
+ private final static boolean TZO_WORKAROUND = false;
+ private static double DaylightSavingTA(double t) {
+ if (!TZO_WORKAROUND) {
+ java.util.Date date = new java.util.Date((long) t);
+ if (thisTimeZone.inDaylightTime(date))
+ return msPerHour;
+ else
+ return 0;
+ } else {
+ /* Use getOffset if inDaylightTime() is broken, because it
+ * seems to work acceptably. We don't switch over to it
+ * entirely, because it requires (expensive) exploded date arguments,
+ * and the api makes it impossible to handle dst
+ * changeovers cleanly.
+ */
+
+ // Hardcode the assumption that the changeover always
+ // happens at 2:00 AM:
+ t += LocalTZA + (HourFromTime(t) <= 2 ? msPerHour : 0);
+
+ int year = YearFromTime(t);
+ double offset = thisTimeZone.getOffset(year > 0 ? 1 : 0,
+ year,
+ MonthFromTime(t),
+ DateFromTime(t),
+ WeekDay(t),
+ (int)TimeWithinDay(t));
+
+ if ((offset - LocalTZA) != 0)
+ return msPerHour;
+ else
+ return 0;
+ // return offset - LocalTZA;
+ }
+ }
+
+ private static double LocalTime(double t) {
+ return t + LocalTZA + DaylightSavingTA(t);
+ }
+
+ public static double internalUTC(double t) {
+ return t - LocalTZA - DaylightSavingTA(t - LocalTZA);
+ }
+
+ private static int HourFromTime(double t) {
+ double result;
+ result = java.lang.Math.floor(t / msPerHour) % HoursPerDay;
+ if (result < 0)
+ result += HoursPerDay;
+ return (int) result;
+ }
+
+ private static int MinFromTime(double t) {
+ double result;
+ result = java.lang.Math.floor(t / msPerMinute) % MinutesPerHour;
+ if (result < 0)
+ result += MinutesPerHour;
+ return (int) result;
+ }
+
+ private static int SecFromTime(double t) {
+ double result;
+ result = java.lang.Math.floor(t / msPerSecond) % SecondsPerMinute;
+ if (result < 0)
+ result += SecondsPerMinute;
+ return (int) result;
+ }
+
+ private static int msFromTime(double t) {
+ double result;
+ result = t % msPerSecond;
+ if (result < 0)
+ result += msPerSecond;
+ return (int) result;
+ }
+
+ private static double MakeTime(double hour, double min,
+ double sec, double ms)
+ {
+ return ((hour * MinutesPerHour + min) * SecondsPerMinute + sec)
+ * msPerSecond + ms;
+ }
+
+ private static double MakeDay(double year, double month, double date) {
+ double result;
+ boolean leap;
+ double yearday;
+ double monthday;
+
+ year += java.lang.Math.floor(month / 12);
+
+ month = month % 12;
+ if (month < 0)
+ month += 12;
+
+ leap = (DaysInYear((int) year) == 366);
+
+ yearday = java.lang.Math.floor(TimeFromYear(year) / msPerDay);
+ monthday = DayFromMonth((int) month, leap);
+
+ result = yearday
+ + monthday
+ + date - 1;
+ return result;
+ }
+
+ private static double MakeDate(double day, double time) {
+ return day * msPerDay + time;
+ }
+
+ private static double TimeClip(double d) {
+ if (d != d ||
+ d == Double.POSITIVE_INFINITY ||
+ d == Double.NEGATIVE_INFINITY ||
+ java.lang.Math.abs(d) > HalfTimeDomain)
+ {
+ return Double.NaN;
+ }
+ if (d > 0.0)
+ return java.lang.Math.floor(d + 0.);
+ else
+ return java.lang.Math.ceil(d + 0.);
+ }
+
+ /* end of ECMA helper functions */
+
+ /* find UTC time from given date... no 1900 correction! */
+ public static double date_msecFromDate(double year, double mon,
+ double mday, double hour,
+ double min, double sec,
+ double msec)
+ {
+ double day;
+ double time;
+ double result;
+
+ day = MakeDay(year, mon, mday);
+ time = MakeTime(hour, min, sec, msec);
+ result = MakeDate(day, time);
+ return result;
+ }
+
+
+ private static final int MAXARGS = 7;
+ private static double jsStaticJSFunction_UTC(Object[] args) {
+ double array[] = new double[MAXARGS];
+ int loop;
+ double d;
+
+ for (loop = 0; loop < MAXARGS; loop++) {
+ if (loop < args.length) {
+ d = _toNumber(args[loop]);
+ if (d != d || Double.isInfinite(d)) {
+ return Double.NaN;
+ }
+ array[loop] = toDouble(args[loop]);
+ } else {
+ array[loop] = 0;
+ }
+ }
+
+ /* adjust 2-digit years into the 20th century */
+ if (array[0] >= 0 && array[0] <= 99)
+ array[0] += 1900;
+
+ /* if we got a 0 for 'date' (which is out of range)
+ * pretend it's a 1. (So Date.UTC(1972, 5) works) */
+ if (array[2] < 1)
+ array[2] = 1;
+
+ d = date_msecFromDate(array[0], array[1], array[2],
+ array[3], array[4], array[5], array[6]);
+ d = TimeClip(d);
+ return d;
+ // return N(d);
+ }
+
+ /*
+ * Use ported code from jsdate.c rather than the locale-specific
+ * date-parsing code from Java, to keep js and rhino consistent.
+ * Is this the right strategy?
+ */
+
+ /* for use by date_parse */
+
+ /* replace this with byte arrays? Cheaper? */
+ private static String wtb[] = {
+ "am", "pm",
+ "monday", "tuesday", "wednesday", "thursday", "friday",
+ "saturday", "sunday",
+ "january", "february", "march", "april", "may", "june",
+ "july", "august", "september", "october", "november", "december",
+ "gmt", "ut", "utc", "est", "edt", "cst", "cdt",
+ "mst", "mdt", "pst", "pdt"
+ /* time zone table needs to be expanded */
+ };
+
+ private static int ttb[] = {
+ -1, -2, 0, 0, 0, 0, 0, 0, 0, /* AM/PM */
+ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
+ 10000 + 0, 10000 + 0, 10000 + 0, /* UT/UTC */
+ 10000 + 5 * 60, 10000 + 4 * 60, /* EDT */
+ 10000 + 6 * 60, 10000 + 5 * 60,
+ 10000 + 7 * 60, 10000 + 6 * 60,
+ 10000 + 8 * 60, 10000 + 7 * 60
+ };
+
+ /* helper for date_parse */
+ private static boolean date_regionMatches(String s1, int s1off,
+ String s2, int s2off,
+ int count)
+ {
+ boolean result = false;
+ /* return true if matches, otherwise, false */
+ int s1len = s1.length();
+ int s2len = s2.length();
+
+ while (count > 0 && s1off < s1len && s2off < s2len) {
+ if (Character.toLowerCase(s1.charAt(s1off)) !=
+ Character.toLowerCase(s2.charAt(s2off)))
+ break;
+ s1off++;
+ s2off++;
+ count--;
+ }
+
+ if (count == 0) {
+ result = true;
+ }
+ return result;
+ }
+
+ private static double date_parseString(String s) {
+ double msec;
+
+ int year = -1;
+ int mon = -1;
+ int mday = -1;
+ int hour = -1;
+ int min = -1;
+ int sec = -1;
+ char c = 0;
+ char si = 0;
+ int i = 0;
+ int n = -1;
+ double tzoffset = -1;
+ char prevc = 0;
+ int limit = 0;
+ boolean seenplusminus = false;
+
+ if (s == null) // ??? Will s be null?
+ return Double.NaN;
+ limit = s.length();
+ while (i < limit) {
+ c = s.charAt(i);
+ i++;
+ if (c <= ' ' || c == ',' || c == '-') {
+ if (i < limit) {
+ si = s.charAt(i);
+ if (c == '-' && '0' <= si && si <= '9') {
+ prevc = c;
+ }
+ }
+ continue;
+ }
+ if (c == '(') { /* comments) */
+ int depth = 1;
+ while (i < limit) {
+ c = s.charAt(i);
+ i++;
+ if (c == '(')
+ depth++;
+ else if (c == ')')
+ if (--depth <= 0)
+ break;
+ }
+ continue;
+ }
+ if ('0' <= c && c <= '9') {
+ n = c - '0';
+ while (i < limit && '0' <= (c = s.charAt(i)) && c <= '9') {
+ n = n * 10 + c - '0';
+ i++;
+ }
+
+ /* allow TZA before the year, so
+ * 'Wed Nov 05 21:49:11 GMT-0800 1997'
+ * works */
+
+ /* uses of seenplusminus allow : in TZA, so Java
+ * no-timezone style of GMT+4:30 works
+ */
+ if ((prevc == '+' || prevc == '-')/* && year>=0 */) {
+ /* make ':' case below change tzoffset */
+ seenplusminus = true;
+
+ /* offset */
+ if (n < 24)
+ n = n * 60; /* EG. "GMT-3" */
+ else
+ n = n % 100 + n / 100 * 60; /* eg "GMT-0430" */
+ if (prevc == '+') /* plus means east of GMT */
+ n = -n;
+ if (tzoffset != 0 && tzoffset != -1)
+ return Double.NaN;
+ tzoffset = n;
+ } else if (n >= 70 ||
+ (prevc == '/' && mon >= 0 && mday >= 0 && year < 0)) {
+ if (year >= 0)
+ return Double.NaN;
+ else if (c <= ' ' || c == ',' || c == '/' || i >= limit)
+ year = n < 100 ? n + 1900 : n;
+ else
+ return Double.NaN;
+ } else if (c == ':') {
+ if (hour < 0)
+ hour = /*byte*/ n;
+ else if (min < 0)
+ min = /*byte*/ n;
+ else
+ return Double.NaN;
+ } else if (c == '/') {
+ if (mon < 0)
+ mon = /*byte*/ n-1;
+ else if (mday < 0)
+ mday = /*byte*/ n;
+ else
+ return Double.NaN;
+ } else if (i < limit && c != ',' && c > ' ' && c != '-') {
+ return Double.NaN;
+ } else if (seenplusminus && n < 60) { /* handle GMT-3:30 */
+ if (tzoffset < 0)
+ tzoffset -= n;
+ else
+ tzoffset += n;
+ } else if (hour >= 0 && min < 0) {
+ min = /*byte*/ n;
+ } else if (min >= 0 && sec < 0) {
+ sec = /*byte*/ n;
+ } else if (mday < 0) {
+ mday = /*byte*/ n;
+ } else {
+ return Double.NaN;
+ }
+ prevc = 0;
+ } else if (c == '/' || c == ':' || c == '+' || c == '-') {
+ prevc = c;
+ } else {
+ int st = i - 1;
+ int k;
+ while (i < limit) {
+ c = s.charAt(i);
+ if (!(('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z')))
+ break;
+ i++;
+ }
+ if (i <= st + 1)
+ return Double.NaN;
+ for (k = wtb.length; --k >= 0;)
+ if (date_regionMatches(wtb[k], 0, s, st, i-st)) {
+ int action = ttb[k];
+ if (action != 0) {
+ if (action < 0) {
+ /*
+ * AM/PM. Count 12:30 AM as 00:30, 12:30 PM as
+ * 12:30, instead of blindly adding 12 if PM.
+ */
+ if (hour > 12 || hour < 0) {
+ return Double.NaN;
+ } else {
+ if (action == -1 && hour == 12) { // am
+ hour = 0;
+ } else if (action == -2 && hour != 12) {// pm
+ hour += 12;
+ }
+ }
+ } else if (action <= 13) { /* month! */
+ if (mon < 0) {
+ mon = /*byte*/ (action - 2);
+ } else {
+ return Double.NaN;
+ }
+ } else {
+ tzoffset = action - 10000;
+ }
+ }
+ break;
+ }
+ if (k < 0)
+ return Double.NaN;
+ prevc = 0;
+ }
+ }
+ if (year < 0 || mon < 0 || mday < 0)
+ return Double.NaN;
+ if (sec < 0)
+ sec = 0;
+ if (min < 0)
+ min = 0;
+ if (hour < 0)
+ hour = 0;
+ if (tzoffset == -1) { /* no time zone specified, have to use local */
+ double time;
+ time = date_msecFromDate(year, mon, mday, hour, min, sec, 0);
+ return internalUTC(time);
+ }
+
+ msec = date_msecFromDate(year, mon, mday, hour, min, sec, 0);
+ msec += tzoffset * msPerMinute;
+ return msec;
+ }
+
+ private static double jsStaticJSFunction_parse(String s) {
+ return date_parseString(s);
+ }
+
+ private static final int FORMATSPEC_FULL = 0;
+ private static final int FORMATSPEC_DATE = 1;
+ private static final int FORMATSPEC_TIME = 2;
+
+ private static String date_format(double t, int format) {
+ if (t != t)
+ return NaN_date_str;
+
+ StringBuffer result = new StringBuffer(60);
+ double local = LocalTime(t);
+
+ /* offset from GMT in minutes. The offset includes daylight savings,
+ if it applies. */
+ int minutes = (int) java.lang.Math.floor((LocalTZA + DaylightSavingTA(t))
+ / msPerMinute);
+ /* map 510 minutes to 0830 hours */
+ int offset = (minutes / 60) * 100 + minutes % 60;
+
+ String dateStr = Integer.toString(DateFromTime(local));
+ String hourStr = Integer.toString(HourFromTime(local));
+ String minStr = Integer.toString(MinFromTime(local));
+ String secStr = Integer.toString(SecFromTime(local));
+ String offsetStr = Integer.toString(offset > 0 ? offset : -offset);
+ int year = YearFromTime(local);
+ String yearStr = Integer.toString(year > 0 ? year : -year);
+
+ /* Tue Oct 31 09:41:40 GMT-0800 (PST) 2000 */
+ /* Tue Oct 31 2000 */
+ /* 09:41:40 GMT-0800 (PST) */
+
+ if (format != FORMATSPEC_TIME) {
+ result.append(days[WeekDay(local)]);
+ result.append(' ');
+ result.append(months[MonthFromTime(local)]);
+ if (dateStr.length() == 1)
+ result.append(" 0");
+ else
+ result.append(' ');
+ result.append(dateStr);
+ result.append(' ');
+ }
+
+ if (format != FORMATSPEC_DATE) {
+ if (hourStr.length() == 1)
+ result.append('0');
+ result.append(hourStr);
+ if (minStr.length() == 1)
+ result.append(":0");
+ else
+ result.append(':');
+ result.append(minStr);
+ if (secStr.length() == 1)
+ result.append(":0");
+ else
+ result.append(':');
+ result.append(secStr);
+ if (offset > 0)
+ result.append(" GMT+");
+ else
+ result.append(" GMT-");
+ for (int i = offsetStr.length(); i < 4; i++)
+ result.append('0');
+ result.append(offsetStr);
+
+ if (timeZoneFormatter == null)
+ timeZoneFormatter = new java.text.SimpleDateFormat("zzz");
+
+ if (timeZoneFormatter != null) {
+ result.append(" (");
+ java.util.Date date = new java.util.Date((long) t);
+ result.append(timeZoneFormatter.format(date));
+ result.append(')');
+ }
+ if (format != FORMATSPEC_TIME)
+ result.append(' ');
+ }
+
+ if (format != FORMATSPEC_TIME) {
+ if (year < 0)
+ result.append('-');
+ for (int i = yearStr.length(); i < 4; i++)
+ result.append('0');
+ result.append(yearStr);
+ }
+
+ return result.toString();
+ }
+
+ private static double _toNumber(Object o) { return JS.toDouble(o); }
+ private static double _toNumber(Object[] o, int index) { return JS.toDouble(o[index]); }
+ private static double toDouble(double d) { return d; }
+
+ public JSDate(Object a0, Object a1, Object a2, Object[] rest, int nargs) {
+
+ JSDate obj = this;
+ switch (nargs) {
+ case 0: {
+ obj.date = Now();
+ return;
+ }
+ case 1: {
+ double date;
+ if (a0 instanceof JS)
+ a0 = ((JS) a0).toString();
+ if (!(a0 instanceof String)) {
+ // if it's not a string, use it as a millisecond date
+ date = _toNumber(a0);
+ } else {
+ // it's a string; parse it.
+ String str = (String) a0;
+ date = date_parseString(str);
+ }
+ obj.date = TimeClip(date);
+ return;
+ }
+ default: {
+ // multiple arguments; year, month, day etc.
+ double array[] = new double[MAXARGS];
+ array[0] = toDouble(a0);
+ array[1] = toDouble(a1);
+ if (nargs >= 2) array[2] = toDouble(a2);
+ for(int i=0; i<nargs; i++) {
+ double d = _toNumber(i==0?a0:i==1?a1:i==2?a2:rest[i-3]);
+ if (d != d || Double.isInfinite(d)) {
+ obj.date = Double.NaN;
+ return;
+ }
+ array[i] = d;
+ }
+
+ /* adjust 2-digit years into the 20th century */
+ if (array[0] >= 0 && array[0] <= 99)
+ array[0] += 1900;
+
+ /* if we got a 0 for 'date' (which is out of range)
+ * pretend it's a 1 */
+ if (array[2] < 1)
+ array[2] = 1;
+
+ double day = MakeDay(array[0], array[1], array[2]);
+ double time = MakeTime(array[3], array[4], array[5], array[6]);
+ time = MakeDate(day, time);
+ time = internalUTC(time);
+ obj.date = TimeClip(time);
+
+ return;
+ }
+ }
+ }
+
+ /* constants for toString, toUTCString */
+ private static String NaN_date_str = "Invalid Date";
+
+ private static String[] days = {
+ "Sun","Mon","Tue","Wed","Thu","Fri","Sat"
+ };
+
+ private static String[] months = {
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+ };
+
+ private static String toLocale_helper(double t,
+ java.text.DateFormat formatter)
+ {
+ if (t != t)
+ return NaN_date_str;
+
+ java.util.Date tempdate = new java.util.Date((long) t);
+ return formatter.format(tempdate);
+ }
+
+ private static String toLocaleString(double date) {
+ if (localeDateTimeFormatter == null)
+ localeDateTimeFormatter =
+ DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG);
+
+ return toLocale_helper(date, localeDateTimeFormatter);
+ }
+
+ private static String toLocaleTimeString(double date) {
+ if (localeTimeFormatter == null)
+ localeTimeFormatter = DateFormat.getTimeInstance(DateFormat.LONG);
+
+ return toLocale_helper(date, localeTimeFormatter);
+ }
+
+ private static String toLocaleDateString(double date) {
+ if (localeDateFormatter == null)
+ localeDateFormatter = DateFormat.getDateInstance(DateFormat.LONG);
+
+ return toLocale_helper(date, localeDateFormatter);
+ }
+
+ private static String toUTCString(double date) {
+ StringBuffer result = new StringBuffer(60);
+
+ String dateStr = Integer.toString(DateFromTime(date));
+ String hourStr = Integer.toString(HourFromTime(date));
+ String minStr = Integer.toString(MinFromTime(date));
+ String secStr = Integer.toString(SecFromTime(date));
+ int year = YearFromTime(date);
+ String yearStr = Integer.toString(year > 0 ? year : -year);
+
+ result.append(days[WeekDay(date)]);
+ result.append(", ");
+ if (dateStr.length() == 1)
+ result.append('0');
+ result.append(dateStr);
+ result.append(' ');
+ result.append(months[MonthFromTime(date)]);
+ if (year < 0)
+ result.append(" -");
+ else
+ result.append(' ');
+ int i;
+ for (i = yearStr.length(); i < 4; i++)
+ result.append('0');
+ result.append(yearStr);
+
+ if (hourStr.length() == 1)
+ result.append(" 0");
+ else
+ result.append(' ');
+ result.append(hourStr);
+ if (minStr.length() == 1)
+ result.append(":0");
+ else
+ result.append(':');
+ result.append(minStr);
+ if (secStr.length() == 1)
+ result.append(":0");
+ else
+ result.append(':');
+ result.append(secStr);
+
+ result.append(" GMT");
+ return result.toString();
+ }
+
+ private static double getYear(double date) {
+ int result = YearFromTime(LocalTime(date));
+ result -= 1900;
+ return result;
+ }
+
+ private static double getTimezoneOffset(double date) {
+ return (date - LocalTime(date)) / msPerMinute;
+ }
+
+ public double setTime(double time) {
+ this.date = TimeClip(time);
+ return this.date;
+ }
+
+ private double makeTime(Object[] args, int maxargs, boolean local) {
+ int i;
+ double conv[] = new double[4];
+ double hour, min, sec, msec;
+ double lorutime; /* Local or UTC version of date */
+
+ double time;
+ double result;
+
+ double date = this.date;
+
+ /* just return NaN if the date is already NaN */
+ if (date != date)
+ return date;
+
+ /* Satisfy the ECMA rule that if a function is called with
+ * fewer arguments than the specified formal arguments, the
+ * remaining arguments are set to undefined. Seems like all
+ * the Date.setWhatever functions in ECMA are only varargs
+ * beyond the first argument; this should be set to undefined
+ * if it's not given. This means that "d = new Date();
+ * d.setMilliseconds()" returns NaN. Blech.
+ */
+ if (args.length == 0)
+ args = new Object[] { null };
+
+ for (i = 0; i < args.length && i < maxargs; i++) {
+ conv[i] = _toNumber(args[i]);
+
+ // limit checks that happen in MakeTime in ECMA.
+ if (conv[i] != conv[i] || Double.isInfinite(conv[i])) {
+ this.date = Double.NaN;
+ return this.date;
+ }
+ conv[i] = toDouble(conv[i]);
+ }
+
+ if (local)
+ lorutime = LocalTime(date);
+ else
+ lorutime = date;
+
+ i = 0;
+ int stop = args.length;
+
+ if (maxargs >= 4 && i < stop)
+ hour = conv[i++];
+ else
+ hour = HourFromTime(lorutime);
+
+ if (maxargs >= 3 && i < stop)
+ min = conv[i++];
+ else
+ min = MinFromTime(lorutime);
+
+ if (maxargs >= 2 && i < stop)
+ sec = conv[i++];
+ else
+ sec = SecFromTime(lorutime);
+
+ if (maxargs >= 1 && i < stop)
+ msec = conv[i++];
+ else
+ msec = msFromTime(lorutime);
+
+ time = MakeTime(hour, min, sec, msec);
+ result = MakeDate(Day(lorutime), time);
+
+ if (local)
+ result = internalUTC(result);
+ date = TimeClip(result);
+
+ this.date = date;
+ return date;
+ }
+
+ private double setHours(Object[] args) {
+ return makeTime(args, 4, true);
+ }
+
+ private double setUTCHours(Object[] args) {
+ return makeTime(args, 4, false);
+ }
+
+ private double makeDate(Object[] args, int maxargs, boolean local) {
+ int i;
+ double conv[] = new double[3];
+ double year, month, day;
+ double lorutime; /* local or UTC version of date */
+ double result;
+
+ double date = this.date;
+
+ /* See arg padding comment in makeTime.*/
+ if (args.length == 0)
+ args = new Object[] { null };
+
+ for (i = 0; i < args.length && i < maxargs; i++) {
+ conv[i] = _toNumber(args[i]);
+
+ // limit checks that happen in MakeDate in ECMA.
+ if (conv[i] != conv[i] || Double.isInfinite(conv[i])) {
+ this.date = Double.NaN;
+ return this.date;
+ }
+ conv[i] = toDouble(conv[i]);
+ }
+
+ /* return NaN if date is NaN and we're not setting the year,
+ * If we are, use 0 as the time. */
+ if (date != date) {
+ if (args.length < 3) {
+ return Double.NaN;
+ } else {
+ lorutime = 0;
+ }
+ } else {
+ if (local)
+ lorutime = LocalTime(date);
+ else
+ lorutime = date;
+ }
+
+ i = 0;
+ int stop = args.length;
+
+ if (maxargs >= 3 && i < stop)
+ year = conv[i++];
+ else
+ year = YearFromTime(lorutime);
+
+ if (maxargs >= 2 && i < stop)
+ month = conv[i++];
+ else
+ month = MonthFromTime(lorutime);
+
+ if (maxargs >= 1 && i < stop)
+ day = conv[i++];
+ else
+ day = DateFromTime(lorutime);
+
+ day = MakeDay(year, month, day); /* day within year */
+ result = MakeDate(day, TimeWithinDay(lorutime));
+
+ if (local)
+ result = internalUTC(result);
+
+ date = TimeClip(result);
+
+ this.date = date;
+ return date;
+ }
+
+ private double setYear(double year) {
+ double day, result;
+ if (year != year || Double.isInfinite(year)) {
+ this.date = Double.NaN;
+ return this.date;
+ }
+
+ if (this.date != this.date) {
+ this.date = 0;
+ } else {
+ this.date = LocalTime(this.date);
+ }
+
+ if (year >= 0 && year <= 99)
+ year += 1900;
+
+ day = MakeDay(year, MonthFromTime(this.date), DateFromTime(this.date));
+ result = MakeDate(day, TimeWithinDay(this.date));
+ result = internalUTC(result);
+
+ this.date = TimeClip(result);
+ return this.date;
+ }
+
+
+ // private static final int
+ // Id_toGMTString = Id_toUTCString; // Alias, see Ecma B.2.6
+// #/string_id_map#
+
+ /* cached values */
+ private static java.util.TimeZone thisTimeZone;
+ private static double LocalTZA;
+ private static java.text.DateFormat timeZoneFormatter;
+ private static java.text.DateFormat localeDateTimeFormatter;
+ private static java.text.DateFormat localeDateFormatter;
+ private static java.text.DateFormat localeTimeFormatter;
+
+ private double date;
+
+ public long getRawTime() { return (long)this.date; }
+}
+
+
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.js;
+
+import org.ibex.util.*;
+import java.io.*;
+
+/** An exception which can be thrown and caught by JavaScript code */
+public class JSExn extends Exception {
+ private Vec backtrace = new Vec();
+ private Object js = null;
+ public JSExn(Object js) {
+ this.js = js;
+ if (Interpreter.current() != null)
+ fill(Interpreter.current().stack, Interpreter.current().f, Interpreter.current().pc, Interpreter.current().scope);
+ }
+ public JSExn(Object js, Vec stack, JSFunction f, int pc, JSScope scope) { this.js = js; fill(stack, f, pc, scope); }
+ private void fill(Vec stack, JSFunction f, int pc, JSScope scope) {
+ addBacktrace(f.sourceName + ":" + f.line[pc]);
+ if (scope != null && scope instanceof Trap.TrapScope)
+ addBacktrace("trap on property \"" + ((Trap.TrapScope)scope).t.name + "\"");
+ for(int i=stack.size()-1; i>=0; i--) {
+ Object element = stack.elementAt(i);
+ if (element instanceof Interpreter.CallMarker) {
+ Interpreter.CallMarker cm = (Interpreter.CallMarker)element;
+ if (cm.f != null)
+ addBacktrace(cm.f.sourceName + ":" + cm.f.line[cm.pc-1]);
+ if (cm.scope != null && cm.scope instanceof Trap.TrapScope)
+ addBacktrace("trap on property \"" + ((Trap.TrapScope)cm.scope).t.name + "\"");
+ }
+ }
+ }
+ public void printStackTrace() { printStackTrace(System.err); }
+ public void printStackTrace(PrintWriter pw) {
+ for(int i=0; i<backtrace.size(); i++) pw.println(" at " + (String) backtrace.elementAt(i));
+ super.printStackTrace(pw);
+ }
+ public void printStackTrace(PrintStream ps) {
+ for(int i=0; i<backtrace.size(); i++) ps.println(" at " + (String) backtrace.elementAt(i));
+ super.printStackTrace(ps);
+ }
+ public String toString() { return "JSExn: " + js; }
+ public String getMessage() { return toString(); }
+ public Object getObject() { return js; }
+ public void addBacktrace(String line) { backtrace.addElement(line); }
+}
+
+/** should only be used for failed coercions */
+class JSRuntimeExn extends RuntimeException {
+ private Object js = null;
+ public JSRuntimeExn(Object js) { this.js = js; }
+ public String toString() { return "JSRuntimeExn: " + js; }
+ public String getMessage() { return toString(); }
+ public Object getObject() { return js; }
+}
+
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.js;
+
+import java.io.*;
+import org.ibex.util.*;
+
+/** A JavaScript function, compiled into bytecode */
+class JSFunction extends JS implements ByteCodes, Tokens, Task {
+
+
+ // Fields and Accessors ///////////////////////////////////////////////
+
+ int numFormalArgs = 0; ///< the number of formal arguments
+
+ String sourceName; ///< the source code file that this block was drawn from
+ private int firstLine = -1; ///< the first line of this script
+
+ int[] line = new int[10]; ///< the line numbers
+ int[] op = new int[10]; ///< the instructions
+ Object[] arg = new Object[10]; ///< the arguments to the instructions
+ int size = 0; ///< the number of instruction/argument pairs
+
+ JSScope parentScope; ///< the default scope to use as a parent scope when executing this
+
+
+ // Public //////////////////////////////////////////////////////////////////////////////
+
+ // FEATURE: make sure that this can only be called from the Scheduler...
+ /** if you enqueue a function, it gets invoked in its own pauseable context */
+ public void perform() throws JSExn {
+ Interpreter i = new Interpreter(this, true, new JSArray());
+ i.resume();
+ }
+
+ /** parse and compile a function */
+ public static JSFunction _fromReader(String sourceName, int firstLine, Reader sourceCode) throws IOException {
+ JSFunction ret = new JSFunction(sourceName, firstLine, null);
+ if (sourceCode == null) return ret;
+ Parser p = new Parser(sourceCode, sourceName, firstLine);
+ while(true) {
+ int s = ret.size;
+ p.parseStatement(ret, null);
+ if (s == ret.size) break;
+ }
+ ret.add(-1, LITERAL, null);
+ ret.add(-1, RETURN);
+ return ret;
+ }
+
+ public JSFunction _cloneWithNewParentScope(JSScope s) {
+ JSFunction ret = new JSFunction(sourceName, firstLine, s);
+ // Reuse the same op, arg, line, and size variables for the new "instance" of the function
+ // NOTE: Neither *this* function nor the new function should be modified after this call
+ ret.op = this.op;
+ ret.arg = this.arg;
+ ret.line = this.line;
+ ret.size = this.size;
+ ret.numFormalArgs = this.numFormalArgs;
+ return ret;
+ }
+
+ /** Note: code gets run in an <i>unpauseable</i> context. */
+ public Object call(Object a0, Object a1, Object a2, Object[] rest, int nargs) throws JSExn {
+ JSArray args = new JSArray();
+ if (nargs > 0) args.addElement(a0);
+ if (nargs > 1) args.addElement(a1);
+ if (nargs > 2) args.addElement(a2);
+ for(int i=3; i<nargs; i++) args.addElement(rest[i-3]);
+ Interpreter cx = new Interpreter(this, false, args);
+ return cx.resume();
+ }
+
+ public JSScope getParentScope() { return parentScope; }
+
+ // Adding and Altering Bytecodes ///////////////////////////////////////////////////
+
+ JSFunction(String sourceName, int firstLine, JSScope parentScope) {
+ this.sourceName = sourceName;
+ this.firstLine = firstLine;
+ this.parentScope = parentScope;
+ }
+
+ int get(int pos) { return op[pos]; }
+ Object getArg(int pos) { return arg[pos]; }
+ void set(int pos, int op_, Object arg_) { op[pos] = op_; arg[pos] = arg_; }
+ void set(int pos, Object arg_) { arg[pos] = arg_; }
+ int pop() { size--; arg[size] = null; return op[size]; }
+ void paste(JSFunction other) { for(int i=0; i<other.size; i++) add(other.line[i], other.op[i], other.arg[i]); }
+ JSFunction add(int line, int op_) { return add(line, op_, null); }
+ JSFunction add(int line, int op_, Object arg_) {
+ if (size == op.length - 1) {
+ int[] line2 = new int[op.length * 2]; System.arraycopy(this.line, 0, line2, 0, op.length); this.line = line2;
+ Object[] arg2 = new Object[op.length * 2]; System.arraycopy(arg, 0, arg2, 0, arg.length); arg = arg2;
+ int[] op2 = new int[op.length * 2]; System.arraycopy(op, 0, op2, 0, op.length); op = op2;
+ }
+ this.line[size] = line;
+ op[size] = op_;
+ arg[size] = arg_;
+ size++;
+ return this;
+ }
+
+
+ // Debugging //////////////////////////////////////////////////////////////////////
+
+ public String toString() { return "JSFunction [" + sourceName + ":" + firstLine + "]"; }
+
+ public String dump() {
+ StringBuffer sb = new StringBuffer(1024);
+ sb.append("\n" + sourceName + ": " + firstLine + "\n");
+ for (int i=0; i < size; i++) {
+ sb.append(i).append(" (").append(line[i]).append(") :");
+ if (op[i] < 0) sb.append(bytecodeToString[-op[i]]);
+ else sb.append(codeToString[op[i]]);
+ sb.append(" ");
+ sb.append(arg[i] == null ? "(no arg)" : arg[i]);
+ if((op[i] == JF || op[i] == JT || op[i] == JMP) && arg[i] != null && arg[i] instanceof Number) {
+ sb.append(" jump to ").append(i+((Number) arg[i]).intValue());
+ } else if(op[i] == TRY) {
+ int[] jmps = (int[]) arg[i];
+ sb.append(" catch: ").append(jmps[0] < 0 ? "No catch block" : ""+(i+jmps[0]));
+ sb.append(" finally: ").append(jmps[1] < 0 ? "No finally block" : ""+(i+jmps[1]));
+ }
+ sb.append("\n");
+ }
+ return sb.toString();
+ }
+
+
+}
+
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL ]
+
+package org.ibex.js;
+
+/** The JavaScript Math object */
+public class JSMath extends JS {
+
+ public static JSMath singleton = new JSMath();
+
+ private static final Double E = new Double(java.lang.Math.E);
+ private static final Double PI = new Double(java.lang.Math.PI);
+ private static final Double LN10 = new Double(java.lang.Math.log(10));
+ private static final Double LN2 = new Double(java.lang.Math.log(2));
+ private static final Double LOG10E = new Double(1/java.lang.Math.log(10));
+ private static final Double LOG2E = new Double(1/java.lang.Math.log(2));
+ private static final Double SQRT1_2 = new Double(1/java.lang.Math.sqrt(2));
+ private static final Double SQRT2 = new Double(java.lang.Math.sqrt(2));
+
+ public Object callMethod(Object method, Object a0, Object a1, Object a2, Object[] rest, int nargs) throws JSExn {
+ switch(nargs) {
+ case 0: {
+ //#switch(method)
+ case "random": return new Double(java.lang.Math.random());
+ //#end
+ break;
+ }
+ case 1: {
+ //#switch(method)
+ case "ceil": return new Long((long)java.lang.Math.ceil(toDouble(a0)));
+ case "floor": return new Long((long)java.lang.Math.floor(toDouble(a0)));
+ case "round": return new Long((long)java.lang.Math.round(toDouble(a0)));
+ case "abs": return new Double(java.lang.Math.abs(toDouble(a0)));
+ case "sin": return new Double(java.lang.Math.sin(toDouble(a0)));
+ case "cos": return new Double(java.lang.Math.cos(toDouble(a0)));
+ case "tan": return new Double(java.lang.Math.tan(toDouble(a0)));
+ case "asin": return new Double(java.lang.Math.asin(toDouble(a0)));
+ case "acos": return new Double(java.lang.Math.acos(toDouble(a0)));
+ case "atan": return new Double(java.lang.Math.atan(toDouble(a0)));
+ case "sqrt": return new Double(java.lang.Math.sqrt(toDouble(a0)));
+ case "exp": return new Double(java.lang.Math.exp(toDouble(a0)));
+ case "log": return new Double(java.lang.Math.log(toDouble(a0)));
+ //#end
+ break;
+ }
+ case 2: {
+ //#switch(method)
+ case "min": return new Double(java.lang.Math.min(toDouble(a0), toDouble(a1)));
+ case "max": return new Double(java.lang.Math.max(toDouble(a0), toDouble(a1)));
+ case "pow": return new Double(java.lang.Math.pow(toDouble(a0), toDouble(a1)));
+ case "atan2": return new Double(java.lang.Math.atan2(toDouble(a0), toDouble(a1)));
+ //#end
+ break;
+ }
+ }
+ return super.callMethod(method, a0, a1, a2, rest, nargs);
+ }
+
+ public void put(Object key, Object val) { }
+
+ public Object get(Object key) throws JSExn {
+ //#switch(key)
+ case "E": return E;
+ case "LN10": return LN10;
+ case "LN2": return LN2;
+ case "LOG10E": return LOG10E;
+ case "LOG2E": return LOG2E;
+ case "PI": return PI;
+ case "SQRT1_2": return SQRT1_2;
+ case "SQRT2": return SQRT2;
+ case "ceil": return METHOD;
+ case "floor": return METHOD;
+ case "round": return METHOD;
+ case "min": return METHOD;
+ case "max": return METHOD;
+ case "pow": return METHOD;
+ case "atan2": return METHOD;
+ case "abs": return METHOD;
+ case "sin": return METHOD;
+ case "cos": return METHOD;
+ case "tan": return METHOD;
+ case "asin": return METHOD;
+ case "acos": return METHOD;
+ case "atan": return METHOD;
+ case "sqrt": return METHOD;
+ case "exp": return METHOD;
+ case "log": return METHOD;
+ case "random": return METHOD;
+ //#end
+ return super.get(key);
+ }
+}
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.js;
+
+import org.ibex.util.*;
+import java.io.*;
+import java.util.*;
+import java.lang.reflect.*;
+
+/** Automatic JS-ification via Reflection (not for use in the core) */
+public class JSReflection extends JS {
+
+ public static Object wrap(Object o) throws JSExn {
+ if (o instanceof String) return o;
+ if (o instanceof Boolean) return o;
+ if (o instanceof Number) return o;
+ if (o instanceof JS) return o;
+ if (o instanceof Object[]) {
+ // FIXME: get element type here
+ }
+ throw new JSExn("Reflection object tried to return a " + o.getClass().getName());
+ }
+
+ public static class Array extends JS {
+ final Object[] arr;
+ public Array(Object[] arr) { this.arr = arr; }
+ public Enumeration keys() throws JSExn { return new CounterEnumeration(arr.length); }
+ public Object get(Object key) throws JSExn { return wrap(arr[toInt(key)]); }
+ public void put(Object key, Object val) throws JSExn { throw new JSExn("can't write to org.ibex.js.Reflection.Array's"); }
+ }
+
+ // FIXME public static class Hash { }
+ // FIXME public Enumeration keys() throws JSExn { }
+
+ public Object get(Object key) throws JSExn {
+ String k = toString(key);
+ try {
+ Field f = this.getClass().getField(k);
+ return wrap(f.get(this));
+ } catch (NoSuchFieldException nfe) {
+ } catch (IllegalAccessException nfe) {
+ } catch (SecurityException nfe) { }
+
+ try {
+ Method[] methods = this.getClass().getMethods();
+ for(int i=0; i<methods.length; i++) if (methods[i].getName().equals(k)) return METHOD;
+ } catch (SecurityException nfe) { }
+ return null;
+ }
+
+ public void put(Object key, Object val) throws JSExn {
+ throw new JSExn("put() not supported yet");
+ }
+
+ public Object callMethod(Object method, Object a0, Object a1, Object a2, Object[] rest, int nargs) throws JSExn {
+ String k = toString(method);
+ try {
+ Method[] methods = this.getClass().getMethods();
+ for(int j=0; j<methods.length; j++) {
+ if (methods[j].getName().equals(k) && methods[j].getParameterTypes().length == nargs) {
+ Object[] args = new Object[nargs];
+ for(int i = 0; i<args.length; i++) {
+ if (i==0) args[i] = a0;
+ else if (i==1) args[i] = a1;
+ else if (i==2) args[i] = a2;
+ else args[i] = rest[i-3];
+ }
+ return wrap(methods[j].invoke(this, args));
+ }
+ }
+ } catch (IllegalAccessException nfe) {
+ } catch (InvocationTargetException it) {
+ Throwable ite = it.getTargetException();
+ if (ite instanceof JSExn) throw ((JSExn)ite);
+ JS.warn(ite);
+ throw new JSExn("unhandled reflected exception: " + ite.toString());
+ } catch (SecurityException nfe) { }
+ throw new JSExn("called a reflection method with the wrong number of arguments");
+ }
+}
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.js;
+
+import gnu.regexp.*;
+
+/** A JavaScript regular expression object */
+public class JSRegexp extends JS {
+ private boolean global;
+ private RE re;
+ private int lastIndex;
+
+ public JSRegexp(Object arg0, Object arg1) throws JSExn {
+ if(arg0 instanceof JSRegexp) {
+ JSRegexp r = (JSRegexp) arg0;
+ this.global = r.global;
+ this.re = r.re;
+ this.lastIndex = r.lastIndex;
+ } else {
+ String pattern = (String)arg0;
+ String sFlags = null;
+ int flags = 0;
+ if(arg1 != null) sFlags = (String)arg1;
+ if(sFlags == null) sFlags = "";
+ for(int i=0;i<sFlags.length();i++) {
+ switch(sFlags.charAt(i)) {
+ case 'i': flags |= RE.REG_ICASE; break;
+ case 'm': flags |= RE.REG_MULTILINE; break;
+ case 'g': global = true; break;
+ default: throw new JSExn("Invalid flag in regexp \"" + sFlags.charAt(i) + "\"");
+ }
+ }
+ re = newRE(pattern,flags);
+ put("source", pattern);
+ put("global", B(global));
+ put("ignoreCase", B(flags & RE.REG_ICASE));
+ put("multiline", B(flags & RE.REG_MULTILINE));
+ }
+ }
+
+ public Object callMethod(Object method, Object a0, Object a1, Object a2, Object[] rest, int nargs) throws JSExn {
+ switch(nargs) {
+ case 1: {
+ //#switch(method)
+ case "exec": {
+ String s = (String)a0;
+ int start = global ? lastIndex : 0;
+ if(start < 0 || start >= s.length()) { lastIndex = 0; return null; }
+ REMatch match = re.getMatch(s,start);
+ if(global) lastIndex = match == null ? s.length() : match.getEndIndex();
+ return match == null ? null : matchToExecResult(match,re,s);
+ }
+ case "test": {
+ String s = (String)a0;
+ if (!global) return B(re.getMatch(s) != null);
+ int start = global ? lastIndex : 0;
+ if(start < 0 || start >= s.length()) { lastIndex = 0; return null; }
+ REMatch match = re.getMatch(s,start);
+ lastIndex = match != null ? s.length() : match.getEndIndex();
+ return B(match != null);
+ }
+ case "toString": return toString(a0);
+ case "stringMatch": return stringMatch(a0,a1);
+ case "stringSearch": return stringSearch(a0,a1);
+ //#end
+ break;
+ }
+ case 2: {
+ //#switch(method)
+ case "stringReplace": return stringReplace(a0, a1,a2);
+ //#end
+ break;
+ }
+ }
+ return super.callMethod(method, a0, a1, a2, rest, nargs);
+ }
+
+ public Object get(Object key) throws JSExn {
+ //#switch(key)
+ case "exec": return METHOD;
+ case "test": return METHOD;
+ case "toString": return METHOD;
+ case "lastIndex": return N(lastIndex);
+ //#end
+ return super.get(key);
+ }
+
+ public void put(Object key, Object value) throws JSExn {
+ if(key.equals("lastIndex")) lastIndex = JS.toNumber(value).intValue();
+ super.put(key,value);
+ }
+
+ private static Object matchToExecResult(REMatch match, RE re, String s) {
+ try {
+ JS ret = new JS();
+ ret.put("index", N(match.getStartIndex()));
+ ret.put("input",s);
+ int n = re.getNumSubs();
+ ret.put("length", N(n+1));
+ ret.put("0",match.toString());
+ for(int i=1;i<=n;i++) ret.put(Integer.toString(i),match.toString(i));
+ return ret;
+ } catch (JSExn e) {
+ throw new Error("this should never happen");
+ }
+ }
+
+ public String toString() {
+ try {
+ StringBuffer sb = new StringBuffer();
+ sb.append('/');
+ sb.append(get("source"));
+ sb.append('/');
+ if(global) sb.append('g');
+ if(Boolean.TRUE.equals(get("ignoreCase"))) sb.append('i');
+ if(Boolean.TRUE.equals(get("multiline"))) sb.append('m');
+ return sb.toString();
+ } catch (JSExn e) {
+ throw new Error("this should never happen");
+ }
+ }
+
+ public static Object stringMatch(Object o, Object arg0) throws JSExn {
+ String s = o.toString();
+ RE re;
+ JSRegexp regexp = null;
+ if(arg0 instanceof JSRegexp) {
+ regexp = (JSRegexp) arg0;
+ re = regexp.re;
+ } else {
+ re = newRE(arg0.toString(),0);
+ }
+
+ if(regexp == null) {
+ REMatch match = re.getMatch(s);
+ return matchToExecResult(match,re,s);
+ }
+ if(!regexp.global) return regexp.callMethod("exec", s, null, null, null, 1);
+
+ JSArray ret = new JSArray();
+ REMatch[] matches = re.getAllMatches(s);
+ for(int i=0;i<matches.length;i++) ret.addElement(matches[i].toString());
+ regexp.lastIndex = matches.length > 0 ? matches[matches.length-1].getEndIndex() : s.length();
+ return ret;
+ }
+
+ public static Object stringSearch(Object o, Object arg0) throws JSExn {
+ String s = o.toString();
+ RE re = arg0 instanceof JSRegexp ? ((JSRegexp)arg0).re : newRE(arg0.toString(),0);
+ REMatch match = re.getMatch(s);
+ return match == null ? N(-1) : N(match.getStartIndex());
+ }
+
+ public static Object stringReplace(Object o, Object arg0, Object arg1) throws JSExn {
+ String s = o.toString();
+ RE re;
+ JSFunction replaceFunc = null;
+ String replaceString = null;
+ JSRegexp regexp = null;
+ if(arg0 instanceof JSRegexp) {
+ regexp = (JSRegexp) arg0;
+ re = regexp.re;
+ } else {
+ re = newRE(arg0.toString(),0);
+ }
+ if(arg1 instanceof JSFunction)
+ replaceFunc = (JSFunction) arg1;
+ else
+ replaceString = JS.toString(arg1.toString());
+ REMatch[] matches;
+ if(regexp != null && regexp.global) {
+ matches = re.getAllMatches(s);
+ if(regexp != null) {
+ if(matches.length > 0)
+ regexp.lastIndex = matches[matches.length-1].getEndIndex();
+ else
+ regexp.lastIndex = s.length();
+ }
+ } else {
+ REMatch match = re.getMatch(s);
+ if(match != null)
+ matches = new REMatch[]{ match };
+ else
+ matches = new REMatch[0];
+ }
+
+ StringBuffer sb = new StringBuffer(s.length());
+ int pos = 0;
+ char[] sa = s.toCharArray();
+ for(int i=0;i<matches.length;i++) {
+ REMatch match = matches[i];
+ sb.append(sa,pos,match.getStartIndex()-pos);
+ pos = match.getEndIndex();
+ if(replaceFunc != null) {
+ int n = (regexp == null ? 0 : re.getNumSubs());
+ int numArgs = 3 + n;
+ Object[] rest = new Object[numArgs - 3];
+ Object a0 = match.toString();
+ Object a1 = null;
+ Object a2 = null;
+ for(int j=1;j<=n;j++)
+ switch(j) {
+ case 1: a1 = match.toString(j); break;
+ case 2: a2 = match.toString(j); break;
+ default: rest[j - 3] = match.toString(j); break;
+ }
+ switch(numArgs) {
+ case 3:
+ a1 = N(match.getStartIndex());
+ a2 = s;
+ break;
+ case 4:
+ a2 = N(match.getStartIndex());
+ rest[0] = s;
+ break;
+ default:
+ rest[rest.length - 2] = N(match.getStartIndex());
+ rest[rest.length - 1] = s;
+ }
+
+ // note: can't perform pausing operations in here
+ sb.append((String)replaceFunc.call(a0, a1, a2, rest, numArgs));
+
+ } else {
+ sb.append(mySubstitute(match,replaceString,s));
+ }
+ }
+ int end = matches.length == 0 ? 0 : matches[matches.length-1].getEndIndex();
+ sb.append(sa,end,sa.length-end);
+ return sb.toString();
+ }
+
+ private static String mySubstitute(REMatch match, String s, String source) {
+ StringBuffer sb = new StringBuffer();
+ int i,n;
+ char c,c2;
+ for(i=0;i<s.length()-1;i++) {
+ c = s.charAt(i);
+ if(c != '$') {
+ sb.append(c);
+ continue;
+ }
+ i++;
+ c = s.charAt(i);
+ switch(c) {
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ if(i < s.length()-1 && (c2 = s.charAt(i+1)) >= '0' && c2 <= '9') {
+ n = (c - '0') * 10 + (c2 - '0');
+ i++;
+ } else {
+ n = c - '0';
+ }
+ if(n > 0)
+ sb.append(match.toString(n));
+ break;
+ case '$':
+ sb.append('$'); break;
+ case '&':
+ sb.append(match.toString()); break;
+ case '`':
+ sb.append(source.substring(0,match.getStartIndex())); break;
+ case '\'':
+ sb.append(source.substring(match.getEndIndex())); break;
+ default:
+ sb.append('$');
+ sb.append(c);
+ }
+ }
+ if(i < s.length()) sb.append(s.charAt(i));
+ return sb.toString();
+ }
+
+
+ public static Object stringSplit(String s, Object arg0, Object arg1, int nargs) {
+ int limit = nargs < 2 ? Integer.MAX_VALUE : JS.toInt(arg1);
+ if(limit < 0) limit = Integer.MAX_VALUE;
+ if(limit == 0) return new JSArray();
+
+ RE re = null;
+ JSRegexp regexp = null;
+ String sep = null;
+ JSArray ret = new JSArray();
+ int p = 0;
+
+ if(arg0 instanceof JSRegexp) {
+ regexp = (JSRegexp) arg0;
+ re = regexp.re;
+ } else {
+ sep = arg0.toString();
+ }
+
+ // special case this for speed. additionally, the code below doesn't properly handle
+ // zero length strings
+ if(sep != null && sep.length()==0) {
+ int len = s.length();
+ for(int i=0;i<len;i++)
+ ret.addElement(s.substring(i,i+1));
+ return ret;
+ }
+
+ OUTER: while(p < s.length()) {
+ if(re != null) {
+ REMatch m = re.getMatch(s,p);
+ if(m == null) break OUTER;
+ boolean zeroLength = m.getStartIndex() == m.getEndIndex();
+ ret.addElement(s.substring(p,zeroLength ? m.getStartIndex()+1 : m.getStartIndex()));
+ p = zeroLength ? p + 1 : m.getEndIndex();
+ if(!zeroLength) {
+ for(int i=1;i<=re.getNumSubs();i++) {
+ ret.addElement(m.toString(i));
+ if(ret.length() == limit) break OUTER;
+ }
+ }
+ } else {
+ int x = s.indexOf(sep,p);
+ if(x == -1) break OUTER;
+ ret.addElement(s.substring(p,x));
+ p = x + sep.length();
+ }
+ if(ret.length() == limit) break;
+ }
+ if(p < s.length() && ret.length() != limit)
+ ret.addElement(s.substring(p));
+ return ret;
+ }
+
+ public static RE newRE(String pattern, int flags) throws JSExn {
+ try {
+ return new RE(pattern,flags,RESyntax.RE_SYNTAX_PERL5);
+ } catch(REException e) {
+ throw new JSExn(e.toString());
+ }
+ }
+
+ public String typeName() { return "regexp"; }
+}
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.js;
+
+// FIXME: should allow parentScope to be a JS, not a JSScope
+/** Implementation of a JavaScript Scope */
+public class JSScope extends JS {
+
+ private JSScope parentScope;
+
+ private static final Object NULL_PLACEHOLDER = new Object();
+
+ public JSScope(JSScope parentScope) { this.parentScope = parentScope; }
+ public void declare(String s) throws JSExn { super.put(s, NULL_PLACEHOLDER); }
+ public JSScope getParentScope() { return parentScope; }
+
+ public Object get(Object key) throws JSExn {
+ Object o = super.get(key);
+ if (o != null) return o == NULL_PLACEHOLDER ? null : o;
+ else return parentScope == null ? null : parentScope.get(key);
+ }
+
+ public boolean has(Object key) throws JSExn { return super.get(key) != null; }
+ public void put(Object key, Object val) throws JSExn {
+ if (parentScope != null && !has(key)) parentScope.put(key, val);
+ else super.put(key, val == null ? NULL_PLACEHOLDER : val);
+ }
+
+ public JSScope top() {
+ JSScope s = this;
+ while(s.parentScope != null) s = s.parentScope;
+ return s;
+ }
+
+ public static class Global extends JSScope {
+ private final static Double NaN = new Double(Double.NaN);
+ private final static Double POSITIVE_INFINITY = new Double(Double.POSITIVE_INFINITY);
+
+ public Global() { super(null); }
+ public Object get(Object key) throws JSExn {
+ //#switch(key)
+ case "NaN": return NaN;
+ case "Infinity": return POSITIVE_INFINITY;
+ case "undefined": return null;
+ case "stringFromCharCode": return METHOD;
+ case "parseInt": return METHOD;
+ case "isNaN": return METHOD;
+ case "isFinite": return METHOD;
+ case "decodeURI": return METHOD;
+ case "decodeURIComponent": return METHOD;
+ case "encodeURI": return METHOD;
+ case "encodeURIComponent": return METHOD;
+ case "escape": return METHOD;
+ case "unescape": return METHOD;
+ case "parseInt": return METHOD;
+ //#end
+ return super.get(key);
+ }
+
+ public Object callMethod(Object method, Object a0, Object a1, Object a2, Object[] rest, int nargs) throws JSExn {
+ switch(nargs) {
+ case 0: {
+ //#switch(method)
+ case "stringFromCharCode":
+ char buf[] = new char[nargs];
+ for(int i=0; i<nargs; i++) buf[i] = (char)(JS.toInt(i==0?a0:i==1?a1:i==2?a2:rest[i-3]) & 0xffff);
+ return new String(buf);
+ //#end
+ break;
+ }
+ case 1: {
+ //#switch(method)
+ case "parseInt": return parseInt(a0, N(0));
+ case "isNaN": { double d = toDouble(a0); return d == d ? F : T; }
+ case "isFinite": { double d = toDouble(a0); return (d == d && !Double.isInfinite(d)) ? T : F; }
+ case "decodeURI": throw new JSExn("unimplemented");
+ case "decodeURIComponent": throw new JSExn("unimplemented");
+ case "encodeURI": throw new JSExn("unimplemented");
+ case "encodeURIComponent": throw new JSExn("unimplemented");
+ case "escape": throw new JSExn("unimplemented");
+ case "unescape": throw new JSExn("unimplemented");
+ //#end
+ break;
+ }
+ case 2: {
+ //#switch(method)
+ case "parseInt": return parseInt(a0, a1);
+ //#end
+ break;
+ }
+ }
+ return super.callMethod(method, a0, a1, a2, rest, nargs);
+ }
+
+ private Object parseInt(Object arg, Object r) {
+ int radix = JS.toInt(r);
+ String s = (String)arg;
+ int start = 0;
+ int length = s.length();
+ int sign = 1;
+ long n = 0;
+ if(radix != 0 && (radix < 2 || radix > 36)) return NaN;
+ while(start < length && Character.isWhitespace(s.charAt(start))) start++;
+ if((length >= start+1) && (s.charAt(start) == '+' || s.charAt(start) == '-')) {
+ sign = s.charAt(start) == '+' ? 1 : -1;
+ start++;
+ }
+ if(radix == 0 && length >= start+1 && s.charAt(start) == '0') {
+ start++;
+ if(length >= start+1 && (s.charAt(start) == 'x' || s.charAt(start) == 'X')) {
+ start++;
+ radix = 16;
+ } else {
+ radix = 8;
+ if(length == start || Character.digit(s.charAt(start+1),8)==-1) return JS.ZERO;
+ }
+ }
+ if(radix == 0) radix = 10;
+ if(length == start || Character.digit(s.charAt(start),radix) == -1) return NaN;
+ // try the fast way first
+ try {
+ String s2 = start == 0 ? s : s.substring(start);
+ return JS.N(sign*Integer.parseInt(s2,radix));
+ } catch(NumberFormatException e) { }
+ // fall through to a slower but emca-compliant method
+ for(int i=start;i<length;i++) {
+ int digit = Character.digit(s.charAt(i),radix);
+ if(digit < 0) break;
+ n = n*radix + digit;
+ if(n < 0) return NaN; // overflow;
+ }
+ if(n <= Integer.MAX_VALUE) return JS.N(sign*(int)n);
+ return JS.N((long)sign*n);
+ }
+
+ private Object parseFloat(Object arg) {
+ String s = (String)arg;
+ int start = 0;
+ int length = s.length();
+ while(start < length && Character.isWhitespace(s.charAt(0))) start++;
+ int end = length;
+ // as long as the string has no trailing garbage,this is fast, its slow with
+ // trailing garbage
+ while(start < end) {
+ try {
+ return JS.N(s.substring(start,length));
+ } catch(NumberFormatException e) { }
+ end--;
+ }
+ return NaN;
+ }
+ }
+}
+
--- /dev/null
+// Derived from org.mozilla.javascript.TokenStream [NPL]
+
+/**
+ * The contents of this file are subject to the Netscape Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/NPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * The Initial Developer of the Original Code is Netscape
+ * Communications Corporation.
+ *
+ * Contributor(s): Roger Lawrence, Mike McCabe
+ */
+
+package org.ibex.js;
+import java.io.*;
+
+/** Lexes a stream of characters into a stream of Tokens */
+class Lexer implements Tokens {
+
+ /** for debugging */
+ public static void main(String[] s) throws IOException {
+ Lexer l = new Lexer(new InputStreamReader(System.in), "stdin", 0);
+ int tok = 0;
+ while((tok = l.getToken()) != -1) System.out.println(codeToString[tok]);
+ }
+
+ /** the token that was just parsed */
+ protected int op;
+
+ /** the most recently parsed token, <i>regardless of pushbacks</i> */
+ protected int mostRecentlyReadToken;
+
+ /** if the token just parsed was a NUMBER, this is the numeric value */
+ protected Number number = null;
+
+ /** if the token just parsed was a NAME or STRING, this is the string value */
+ protected String string = null;
+
+ /** the line number of the most recently <i>lexed</i> token */
+ protected int line = 0;
+
+ /** the line number of the most recently <i>parsed</i> token */
+ protected int parserLine = 0;
+
+ /** the column number of the current token */
+ protected int col = 0;
+
+ /** the name of the source code file being lexed */
+ protected String sourceName;
+
+ private SmartReader in;
+ public Lexer(Reader r, String sourceName, int line) throws IOException {
+ this.sourceName = sourceName;
+ this.line = line;
+ this.parserLine = line;
+ in = new SmartReader(r);
+ }
+
+
+ // Predicates ///////////////////////////////////////////////////////////////////////
+
+ private static boolean isAlpha(int c) { return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')); }
+ private static boolean isDigit(int c) { return (c >= '0' && c <= '9'); }
+ private static int xDigitToInt(int c) {
+ if ('0' <= c && c <= '9') return c - '0';
+ else if ('a' <= c && c <= 'f') return c - ('a' - 10);
+ else if ('A' <= c && c <= 'F') return c - ('A' - 10);
+ else return -1;
+ }
+
+
+ // Token Subtype Handlers /////////////////////////////////////////////////////////
+
+ private int getKeyword(String name) throws IOException {
+ //#switch(name)
+ case "if": return IF;
+ case "lt": return LT;
+ case "gt": return GT;
+ case "in": return IN;
+ case "do": return DO;
+ case "and": return AND;
+ case "or": return OR;
+ case "for": return FOR;
+ case "int": return RESERVED;
+ case "new": return RESERVED;
+ case "try": return TRY;
+ case "var": return VAR;
+ case "byte": return RESERVED;
+ case "case": return CASE;
+ case "char": return RESERVED;
+ case "else": return ELSE;
+ case "enum": return RESERVED;
+ case "goto": return RESERVED;
+ case "long": return RESERVED;
+ case "null": return NULL;
+ case "true": return TRUE;
+ case "with": return RESERVED;
+ case "void": return RESERVED;
+ case "class": return RESERVED;
+ case "break": return BREAK;
+ case "while": return WHILE;
+ case "false": return FALSE;
+ case "const": return RESERVED;
+ case "final": return RESERVED;
+ case "super": return RESERVED;
+ case "throw": return THROW;
+ case "catch": return CATCH;
+ case "class": return RESERVED;
+ case "delete": return RESERVED;
+ case "return": return RETURN;
+ case "throws": return RESERVED;
+ case "double": return RESERVED;
+ case "assert": return ASSERT;
+ case "public": return RESERVED;
+ case "switch": return SWITCH;
+ case "typeof": return TYPEOF;
+ case "package": return RESERVED;
+ case "default": return DEFAULT;
+ case "finally": return FINALLY;
+ case "boolean": return RESERVED;
+ case "private": return RESERVED;
+ case "extends": return RESERVED;
+ case "abstract": return RESERVED;
+ case "continue": return CONTINUE;
+ case "debugger": return RESERVED;
+ case "function": return FUNCTION;
+ case "volatile": return RESERVED;
+ case "interface": return RESERVED;
+ case "protected": return RESERVED;
+ case "transient": return RESERVED;
+ case "implements": return RESERVED;
+ case "instanceof": return RESERVED;
+ case "synchronized": return RESERVED;
+ //#end
+ return -1;
+ }
+
+ private int getIdentifier(int c) throws IOException {
+ in.startString();
+ while (Character.isJavaIdentifierPart((char)(c = in.read())));
+ in.unread();
+ String str = in.getString();
+ int result = getKeyword(str);
+ if (result == RESERVED) throw new LexerException("The reserved word \"" + str + "\" is not permitted in Ibex scripts");
+ if (result != -1) return result;
+ this.string = str.intern();
+ return NAME;
+ }
+
+ private int getNumber(int c) throws IOException {
+ int base = 10;
+ in.startString();
+ double dval = Double.NaN;
+ long longval = 0;
+ boolean isInteger = true;
+
+ // figure out what base we're using
+ if (c == '0') {
+ if (Character.toLowerCase((char)(c = in.read())) == 'x') { base = 16; in.startString(); }
+ else if (isDigit(c)) base = 8;
+ }
+
+ while (0 <= xDigitToInt(c) && !(base < 16 && isAlpha(c))) c = in.read();
+ if (base == 10 && (c == '.' || c == 'e' || c == 'E')) {
+ isInteger = false;
+ if (c == '.') do { c = in.read(); } while (isDigit(c));
+ if (c == 'e' || c == 'E') {
+ c = in.read();
+ if (c == '+' || c == '-') c = in.read();
+ if (!isDigit(c)) throw new LexerException("float listeral did not have an exponent value");
+ do { c = in.read(); } while (isDigit(c));
+ }
+ }
+ in.unread();
+
+ String numString = in.getString();
+ if (base == 10 && !isInteger) {
+ try { dval = (Double.valueOf(numString)).doubleValue(); }
+ catch (NumberFormatException ex) { throw new LexerException("invalid numeric literal: \"" + numString + "\""); }
+ } else {
+ if (isInteger) {
+ longval = Long.parseLong(numString, base);
+ dval = (double)longval;
+ } else {
+ dval = Double.parseDouble(numString);
+ longval = (long) dval;
+ if (longval == dval) isInteger = true;
+ }
+ }
+
+ if (!isInteger) this.number = JS.N(dval);
+ else this.number = JS.N(longval);
+ return NUMBER;
+ }
+
+ private int getString(int c) throws IOException {
+ StringBuffer stringBuf = null;
+ int quoteChar = c;
+ c = in.read();
+ in.startString(); // start after the first "
+ while(c != quoteChar) {
+ if (c == '\n' || c == -1) throw new LexerException("unterminated string literal");
+ if (c == '\\') {
+ if (stringBuf == null) {
+ in.unread(); // Don't include the backslash
+ stringBuf = new StringBuffer(in.getString());
+ in.read();
+ }
+ switch (c = in.read()) {
+ case 'b': c = '\b'; break;
+ case 'f': c = '\f'; break;
+ case 'n': c = '\n'; break;
+ case 'r': c = '\r'; break;
+ case 't': c = '\t'; break;
+ case 'v': c = '\u000B'; break;
+ case '\\': c = '\\'; break;
+ case 'u': {
+ int v = 0;
+ for(int i=0; i<4; i++) {
+ int ci = in.read();
+ if (!((ci >= '0' && ci <= '9') || (ci >= 'a' && ci <= 'f') || (ci >= 'A' && ci <= 'F')))
+ throw new LexerException("illegal character '" + ((char)c) + "' in \\u unicode escape sequence");
+ v = (v << 8) | Integer.parseInt(ci + "", 16);
+ }
+ c = (char)v;
+ break;
+ }
+ default:
+ // just use the character that was escaped
+ break;
+ }
+ }
+ if (stringBuf != null) stringBuf.append((char) c);
+ c = in.read();
+ }
+ if (stringBuf != null) this.string = stringBuf.toString().intern();
+ else {
+ in.unread(); // miss the trailing "
+ this.string = in.getString().intern();
+ in.read();
+ }
+ return STRING;
+ }
+
+ private int _getToken() throws IOException {
+ int c;
+ do { c = in.read(); } while (c == '\u0020' || c == '\u0009' || c == '\u000C' || c == '\u000B' || c == '\n' );
+ if (c == -1) return -1;
+ if (c == '\\' || Character.isJavaIdentifierStart((char)c)) return getIdentifier(c);
+ if (isDigit(c) || (c == '.' && isDigit(in.peek()))) return getNumber(c);
+ if (c == '"' || c == '\'') return getString(c);
+ switch (c) {
+ case ';': return SEMI;
+ case '[': return LB;
+ case ']': return RB;
+ case '{': return LC;
+ case '}': return RC;
+ case '(': return LP;
+ case ')': return RP;
+ case ',': return COMMA;
+ case '?': return HOOK;
+ case ':': return !in.match(':') ? COLON : in.match('=') ? GRAMMAR : le(":: is not a valid token");
+ case '.': return DOT;
+ case '|': return in.match('|') ? OR : (in.match('=') ? ASSIGN_BITOR : BITOR);
+ case '^': return in.match('=') ? ASSIGN_BITXOR : BITXOR;
+ case '&': return in.match('&') ? AND : in.match('=') ? ASSIGN_BITAND : BITAND;
+ case '=': return !in.match('=') ? ASSIGN : in.match('=') ? SHEQ : EQ;
+ case '!': return !in.match('=') ? BANG : in.match('=') ? SHNE : NE;
+ case '%': return in.match('=') ? ASSIGN_MOD : MOD;
+ case '~': return BITNOT;
+ case '+': return in.match('=') ? ASSIGN_ADD : in.match('+') ? (in.match('=') ? ADD_TRAP : INC) : ADD;
+ case '-': return in.match('=') ? ASSIGN_SUB: in.match('-') ? (in.match('=') ? DEL_TRAP : DEC) : SUB;
+ case '*': return in.match('=') ? ASSIGN_MUL : MUL;
+ case '<': return !in.match('<') ? (in.match('=') ? LE : LT) : in.match('=') ? ASSIGN_LSH : LSH;
+ case '>': return !in.match('>') ? (in.match('=') ? GE : GT) :
+ in.match('>') ? (in.match('=') ? ASSIGN_URSH : URSH) : (in.match('=') ? ASSIGN_RSH : RSH);
+ case '/':
+ if (in.match('=')) return ASSIGN_DIV;
+ if (in.match('/')) { while ((c = in.read()) != -1 && c != '\n'); in.unread(); return getToken(); }
+ if (!in.match('*')) return DIV;
+ while ((c = in.read()) != -1 && !(c == '*' && in.match('/'))) {
+ if (c == '\n' || c != '/' || !in.match('*')) continue;
+ if (in.match('/')) return getToken();
+ throw new LexerException("nested comments are not permitted");
+ }
+ if (c == -1) throw new LexerException("unterminated comment");
+ return getToken(); // `goto retry'
+ default: throw new LexerException("illegal character: \'" + ((char)c) + "\'");
+ }
+ }
+
+ private int le(String s) throws LexerException { if (true) throw new LexerException(s); return 0; }
+
+ // SmartReader ////////////////////////////////////////////////////////////////
+
+ /** a Reader that tracks line numbers and can push back tokens */
+ private class SmartReader {
+ PushbackReader reader = null;
+ int lastread = -1;
+
+ public SmartReader(Reader r) { reader = new PushbackReader(r); }
+ public void unread() throws IOException { unread((char)lastread); }
+ public void unread(char c) throws IOException {
+ reader.unread(c);
+ if(c == '\n') col = -1;
+ else col--;
+ if (accumulator != null) accumulator.setLength(accumulator.length() - 1);
+ }
+ public boolean match(char c) throws IOException { if (peek() == c) { reader.read(); return true; } else return false; }
+ public int peek() throws IOException {
+ int peeked = reader.read();
+ if (peeked != -1) reader.unread((char)peeked);
+ return peeked;
+ }
+ public int read() throws IOException {
+ lastread = reader.read();
+ if (accumulator != null) accumulator.append((char)lastread);
+ if (lastread != '\n' && lastread != '\r') col++;
+ if (lastread == '\n') {
+ // col is -1 if we just unread a newline, this is sort of ugly
+ if (col != -1) parserLine = ++line;
+ col = 0;
+ }
+ return lastread;
+ }
+
+ // FEATURE: could be much more efficient
+ StringBuffer accumulator = null;
+ public void startString() {
+ accumulator = new StringBuffer();
+ accumulator.append((char)lastread);
+ }
+ public String getString() throws IOException {
+ String ret = accumulator.toString().intern();
+ accumulator = null;
+ return ret;
+ }
+ }
+
+
+ // Token PushBack code ////////////////////////////////////////////////////////////
+
+ private int pushBackDepth = 0;
+ private int[] pushBackInts = new int[10];
+ private Object[] pushBackObjects = new Object[10];
+
+ /** push back a token */
+ public final void pushBackToken(int op, Object obj) {
+ if (pushBackDepth >= pushBackInts.length - 1) {
+ int[] newInts = new int[pushBackInts.length * 2];
+ System.arraycopy(pushBackInts, 0, newInts, 0, pushBackInts.length);
+ pushBackInts = newInts;
+ Object[] newObjects = new Object[pushBackObjects.length * 2];
+ System.arraycopy(pushBackObjects, 0, newObjects, 0, pushBackObjects.length);
+ pushBackObjects = newObjects;
+ }
+ pushBackInts[pushBackDepth] = op;
+ pushBackObjects[pushBackDepth] = obj;
+ pushBackDepth++;
+ }
+
+ /** push back the most recently read token */
+ public final void pushBackToken() { pushBackToken(op, number != null ? (Object)number : (Object)string); }
+
+ /** read a token but leave it in the stream */
+ public final int peekToken() throws IOException {
+ int ret = getToken();
+ pushBackToken();
+ return ret;
+ }
+
+ /** read a token */
+ public final int getToken() throws IOException {
+ number = null;
+ string = null;
+ if (pushBackDepth == 0) {
+ mostRecentlyReadToken = op;
+ return op = _getToken();
+ }
+ pushBackDepth--;
+ op = pushBackInts[pushBackDepth];
+ if (pushBackObjects[pushBackDepth] != null) {
+ number = pushBackObjects[pushBackDepth] instanceof Number ? (Number)pushBackObjects[pushBackDepth] : null;
+ string = pushBackObjects[pushBackDepth] instanceof String ? (String)pushBackObjects[pushBackDepth] : null;
+ }
+ return op;
+ }
+
+ class LexerException extends IOException {
+ public LexerException(String s) { super(sourceName + ":" + line + "," + col + ": " + s); }
+ }
+}
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.js;
+
+import org.ibex.util.*;
+import java.io.*;
+
+/**
+ * Parses a stream of lexed tokens into a tree of JSFunction's.
+ *
+ * There are three kinds of things we parse: blocks, statements, and
+ * expressions.
+ *
+ * - Expressions are a special type of statement that evaluates to a
+ * value (for example, "break" is not an expression, * but "3+2"
+ * is). Some tokens sequences start expressions (for * example,
+ * literal numbers) and others continue an expression which * has
+ * already been begun (for example, '+'). Finally, some *
+ * expressions are valid targets for an assignment operation; after
+ * * each of these expressions, continueExprAfterAssignable() is
+ * called * to check for an assignment operation.
+ *
+ * - A statement ends with a semicolon and does not return a value.
+ *
+ * - A block is a single statement or a sequence of statements
+ * surrounded by curly braces.
+ *
+ * Each parsing method saves the parserLine before doing its actual
+ * work and restores it afterwards. This ensures that parsing a
+ * subexpression does not modify the line number until a token
+ * *after* the subexpression has been consumed by the parent
+ * expression.
+ *
+ * Technically it would be a better design for this class to build an
+ * intermediate parse tree and use that to emit bytecode. Here's the
+ * tradeoff:
+ *
+ * Advantages of building a parse tree:
+ * - easier to apply optimizations
+ * - would let us handle more sophisticated languages than JavaScript
+ *
+ * Advantages of leaving out the parse tree
+ * - faster compilation
+ * - less load on the garbage collector
+ * - much simpler code, easier to understand
+ * - less error-prone
+ *
+ * Fortunately JS is such a simple language that we can get away with
+ * the half-assed approach and still produce a working, complete
+ * compiler.
+ *
+ * The bytecode language emitted doesn't really cause any appreciable
+ * semantic loss, and is itself a parseable language very similar to
+ * Forth or a postfix variant of LISP. This means that the bytecode
+ * can be transformed into a parse tree, which can be manipulated.
+ * So if we ever want to add an optimizer, it could easily be done by
+ * producing a parse tree from the bytecode, optimizing that tree,
+ * and then re-emitting the bytecode. The parse tree node class
+ * would also be much simpler since the bytecode language has so few
+ * operators.
+ *
+ * Actually, the above paragraph is slightly inaccurate -- there are
+ * places where we push a value and then perform an arbitrary number
+ * of operations using it before popping it; this doesn't parse well.
+ * But these cases are clearly marked and easy to change if we do
+ * need to move to a parse tree format.
+ */
+class Parser extends Lexer implements ByteCodes {
+
+
+ // Constructors //////////////////////////////////////////////////////
+
+ public Parser(Reader r, String sourceName, int line) throws IOException { super(r, sourceName, line); }
+
+ /** for debugging */
+ public static void main(String[] s) throws IOException {
+ JS block = JS.fromReader("stdin", 0, new InputStreamReader(System.in));
+ if (block == null) return;
+ System.out.println(block);
+ }
+
+
+ // Statics ////////////////////////////////////////////////////////////
+
+ static byte[] precedence = new byte[MAX_TOKEN + 1];
+ static boolean[] isRightAssociative = new boolean[MAX_TOKEN + 1];
+ // Use this as the precedence when we want anything up to the comma
+ private final static int NO_COMMA = 2;
+ static {
+ isRightAssociative[ASSIGN] =
+ isRightAssociative[ASSIGN_BITOR] =
+ isRightAssociative[ASSIGN_BITXOR] =
+ isRightAssociative[ASSIGN_BITAND] =
+ isRightAssociative[ASSIGN_LSH] =
+ isRightAssociative[ASSIGN_RSH] =
+ isRightAssociative[ASSIGN_URSH] =
+ isRightAssociative[ASSIGN_ADD] =
+ isRightAssociative[ASSIGN_SUB] =
+ isRightAssociative[ASSIGN_MUL] =
+ isRightAssociative[ASSIGN_DIV] =
+ isRightAssociative[ASSIGN_MOD] =
+ isRightAssociative[ADD_TRAP] =
+ isRightAssociative[DEL_TRAP] =
+ true;
+
+ precedence[COMMA] = 1;
+ // 2 is intentionally left unassigned. we use minPrecedence==2 for comma separated lists
+ precedence[ASSIGN] =
+ precedence[ASSIGN_BITOR] =
+ precedence[ASSIGN_BITXOR] =
+ precedence[ASSIGN_BITAND] =
+ precedence[ASSIGN_LSH] =
+ precedence[ASSIGN_RSH] =
+ precedence[ASSIGN_URSH] =
+ precedence[ASSIGN_ADD] =
+ precedence[ASSIGN_SUB] =
+ precedence[ASSIGN_MUL] =
+ precedence[ASSIGN_DIV] =
+ precedence[ADD_TRAP] =
+ precedence[DEL_TRAP] =
+ precedence[ASSIGN_MOD] = 3;
+ precedence[HOOK] = 4;
+ precedence[OR] = 5;
+ precedence[AND] = 6;
+ precedence[BITOR] = 7;
+ precedence[BITXOR] = 8;
+ precedence[BITAND] = 9;
+ precedence[EQ] = precedence[NE] = precedence[SHEQ] = precedence[SHNE] = 10;
+ precedence[LT] = precedence[LE] = precedence[GT] = precedence[GE] = 11;
+ precedence[LSH] = precedence[RSH] = precedence[URSH] = 12;
+ precedence[ADD] = precedence[SUB] = 12;
+ precedence[MUL] = precedence[DIV] = precedence[MOD] = 13;
+ precedence[BITNOT] = precedence[BANG] = precedence[TYPEOF] = 14;
+ precedence[DOT] = precedence[LB] = precedence[LP] = precedence[INC] = precedence[DEC] = 15;
+ }
+
+
+ // Parsing Logic /////////////////////////////////////////////////////////
+
+ /** gets a token and throws an exception if it is not <tt>code</tt> */
+ private void consume(int code) throws IOException {
+ if (getToken() != code) {
+ if(code == NAME) switch(op) {
+ case RETURN: case TYPEOF: case BREAK: case CONTINUE: case TRY: case THROW:
+ case ASSERT: case NULL: case TRUE: case FALSE: case IN: case IF: case ELSE:
+ case SWITCH: case CASE: case DEFAULT: case WHILE: case VAR: case WITH:
+ case CATCH: case FINALLY:
+ throw pe("Bad variable name; '" + codeToString[op].toLowerCase() + "' is a javascript keyword");
+ }
+ throw pe("expected " + codeToString[code] + ", got " + (op == -1 ? "EOF" : codeToString[op]));
+ }
+ }
+
+ /**
+ * Parse the largest possible expression containing no operators
+ * of precedence below <tt>minPrecedence</tt> and append the
+ * bytecodes for that expression to <tt>appendTo</tt>; the
+ * appended bytecodes MUST grow the stack by exactly one element.
+ */
+ private void startExpr(JSFunction appendTo, int minPrecedence) throws IOException {
+ int saveParserLine = parserLine;
+ _startExpr(appendTo, minPrecedence);
+ parserLine = saveParserLine;
+ }
+ private void _startExpr(JSFunction appendTo, int minPrecedence) throws IOException {
+ int tok = getToken();
+ JSFunction b = appendTo;
+
+ switch (tok) {
+ case -1: throw pe("expected expression");
+
+ // all of these simply push values onto the stack
+ case NUMBER: b.add(parserLine, LITERAL, number); break;
+ case STRING: b.add(parserLine, LITERAL, string); break;
+ case NULL: b.add(parserLine, LITERAL, null); break;
+ case TRUE: case FALSE: b.add(parserLine, LITERAL, JS.B(tok == TRUE)); break;
+
+ // (.foo) syntax
+ case DOT: {
+ consume(NAME);
+ b.add(parserLine, TOPSCOPE);
+ b.add(parserLine, LITERAL, "");
+ b.add(parserLine, GET);
+ b.add(parserLine, LITERAL, string);
+ b.add(parserLine, GET);
+ continueExpr(b, minPrecedence);
+ break;
+ }
+
+ case LB: {
+ b.add(parserLine, ARRAY, JS.ZERO); // push an array onto the stack
+ int size0 = b.size;
+ int i = 0;
+ if (peekToken() != RB)
+ while(true) { // iterate over the initialization values
+ b.add(parserLine, LITERAL, JS.N(i++)); // push the index in the array to place it into
+ if (peekToken() == COMMA || peekToken() == RB)
+ b.add(parserLine, LITERAL, null); // for stuff like [1,,2,]
+ else
+ startExpr(b, NO_COMMA); // push the value onto the stack
+ b.add(parserLine, PUT); // put it into the array
+ b.add(parserLine, POP); // discard the value remaining on the stack
+ if (peekToken() == RB) break;
+ consume(COMMA);
+ }
+ b.set(size0 - 1, JS.N(i)); // back at the ARRAY instruction, write the size of the array
+ consume(RB);
+ break;
+ }
+ case SUB: { // negative literal (like "3 * -1")
+ consume(NUMBER);
+ b.add(parserLine, LITERAL, JS.N(number.doubleValue() * -1));
+ break;
+ }
+ case LP: { // grouping (not calling)
+ startExpr(b, -1);
+ consume(RP);
+ break;
+ }
+ case INC: case DEC: { // prefix (not postfix)
+ startExpr(b, precedence[tok]);
+ int prev = b.size - 1;
+ if (b.get(prev) == GET && b.getArg(prev) != null)
+ b.set(prev, LITERAL, b.getArg(prev));
+ else if(b.get(prev) == GET)
+ b.pop();
+ else
+ throw pe("prefixed increment/decrement can only be performed on a valid assignment target");
+ b.add(parserLine, GET_PRESERVE, Boolean.TRUE);
+ b.add(parserLine, LITERAL, JS.N(1));
+ b.add(parserLine, tok == INC ? ADD : SUB, JS.N(2));
+ b.add(parserLine, PUT, null);
+ b.add(parserLine, SWAP, null);
+ b.add(parserLine, POP, null);
+ break;
+ }
+ case BANG: case BITNOT: case TYPEOF: {
+ startExpr(b, precedence[tok]);
+ b.add(parserLine, tok);
+ break;
+ }
+ case LC: { // object constructor
+ b.add(parserLine, OBJECT, null); // put an object on the stack
+ if (peekToken() != RC)
+ while(true) {
+ if (peekToken() != NAME && peekToken() != STRING)
+ throw pe("expected NAME or STRING");
+ getToken();
+ b.add(parserLine, LITERAL, string); // grab the key
+ consume(COLON);
+ startExpr(b, NO_COMMA); // grab the value
+ b.add(parserLine, PUT); // put the value into the object
+ b.add(parserLine, POP); // discard the remaining value
+ if (peekToken() == RC) break;
+ consume(COMMA);
+ if (peekToken() == RC) break; // we permit {,,} -- I'm not sure if ECMA does
+ }
+ consume(RC);
+ break;
+ }
+ case NAME: {
+ b.add(parserLine, TOPSCOPE);
+ b.add(parserLine, LITERAL, string);
+ continueExprAfterAssignable(b,minPrecedence);
+ break;
+ }
+ case FUNCTION: {
+ consume(LP);
+ int numArgs = 0;
+ JSFunction b2 = new JSFunction(sourceName, parserLine, null);
+ b.add(parserLine, NEWFUNCTION, b2);
+
+ // function prelude; arguments array is already on the stack
+ b2.add(parserLine, TOPSCOPE);
+ b2.add(parserLine, SWAP);
+ b2.add(parserLine, DECLARE, "arguments"); // declare arguments (equivalent to 'var arguments;')
+ b2.add(parserLine, SWAP); // set this.arguments and leave the value on the stack
+ b2.add(parserLine, PUT);
+
+ while(peekToken() != RP) { // run through the list of argument names
+ numArgs++;
+ if (peekToken() == NAME) {
+ consume(NAME); // a named argument
+ String varName = string;
+
+ b2.add(parserLine, DUP); // dup the args array
+ b2.add(parserLine, GET, JS.N(numArgs - 1)); // retrieve it from the arguments array
+ b2.add(parserLine, TOPSCOPE);
+ b2.add(parserLine, SWAP);
+ b2.add(parserLine, DECLARE, varName); // declare the name
+ b2.add(parserLine, SWAP);
+ b2.add(parserLine, PUT);
+ b2.add(parserLine, POP); // pop the value
+ b2.add(parserLine, POP); // pop the scope
+ }
+ if (peekToken() == RP) break;
+ consume(COMMA);
+ }
+ consume(RP);
+
+ b2.numFormalArgs = numArgs;
+ b2.add(parserLine, POP); // pop off the arguments array
+ b2.add(parserLine, POP); // pop off TOPSCOPE
+
+ if(peekToken() != LC)
+ throw pe("JSFunctions must have a block surrounded by curly brackets");
+
+ parseBlock(b2, null); // the function body
+
+ b2.add(parserLine, LITERAL, null); // in case we "fall out the bottom", return NULL
+ b2.add(parserLine, RETURN);
+
+ break;
+ }
+ default: throw pe("expected expression, found " + codeToString[tok] + ", which cannot start an expression");
+ }
+
+ // attempt to continue the expression
+ continueExpr(b, minPrecedence);
+ }
+ /*
+ private Grammar parseGrammar(Grammar g) throws IOException {
+ int tok = getToken();
+ if (g != null)
+ switch(tok) {
+ case BITOR: return new Grammar.Alternative(g, parseGrammar(null));
+ case ADD: return parseGrammar(new Grammar.Repetition(g, 1, Integer.MAX_VALUE));
+ case MUL: return parseGrammar(new Grammar.Repetition(g, 0, Integer.MAX_VALUE));
+ case HOOK: return parseGrammar(new Grammar.Repetition(g, 0, 1));
+ }
+ Grammar g0 = null;
+ switch(tok) {
+ //case NUMBER: g0 = new Grammar.Literal(number); break;
+ case NAME: g0 = new Grammar.Reference(string); break;
+ case STRING:
+ g0 = new Grammar.Literal(string);
+ if (peekToken() == DOT) {
+ String old = string;
+ consume(DOT);
+ consume(DOT);
+ consume(STRING);
+ if (old.length() != 1 || string.length() != 1) throw pe("literal ranges must be single-char strings");
+ g0 = new Grammar.Range(old.charAt(0), string.charAt(0));
+ }
+ break;
+ case LP: g0 = parseGrammar(null); consume(RP); break;
+ default: pushBackToken(); return g;
+ }
+ if (g == null) return parseGrammar(g0);
+ return parseGrammar(new Grammar.Juxtaposition(g, g0));
+ }
+ */
+ /**
+ * Assuming that a complete assignable (lvalue) has just been
+ * parsed and the object and key are on the stack,
+ * <tt>continueExprAfterAssignable</tt> will attempt to parse an
+ * expression that modifies the assignable. This method always
+ * decreases the stack depth by exactly one element.
+ */
+ private void continueExprAfterAssignable(JSFunction b,int minPrecedence) throws IOException {
+ int saveParserLine = parserLine;
+ _continueExprAfterAssignable(b,minPrecedence);
+ parserLine = saveParserLine;
+ }
+ private void _continueExprAfterAssignable(JSFunction b,int minPrecedence) throws IOException {
+ if (b == null) throw new Error("got null b; this should never happen");
+ int tok = getToken();
+ if (minPrecedence != -1 && (precedence[tok] < minPrecedence || (precedence[tok] == minPrecedence && !isRightAssociative[tok])))
+ // force the default case
+ tok = -1;
+ switch(tok) {
+ /*
+ case GRAMMAR: {
+ b.add(parserLine, GET_PRESERVE);
+ Grammar g = parseGrammar(null);
+ if (peekToken() == LC) {
+ g.action = new JSFunction(sourceName, parserLine, null);
+ parseBlock((JSFunction)g.action);
+ ((JSFunction)g.action).add(parserLine, LITERAL, null); // in case we "fall out the bottom", return NULL
+ ((JSFunction)g.action).add(parserLine, RETURN);
+ }
+ b.add(parserLine, MAKE_GRAMMAR, g);
+ b.add(parserLine, PUT);
+ break;
+ }
+ */
+ case ASSIGN_BITOR: case ASSIGN_BITXOR: case ASSIGN_BITAND: case ASSIGN_LSH: case ASSIGN_RSH: case ASSIGN_URSH:
+ case ASSIGN_MUL: case ASSIGN_DIV: case ASSIGN_MOD: case ASSIGN_ADD: case ASSIGN_SUB: case ADD_TRAP: case DEL_TRAP: {
+ if (tok != ADD_TRAP && tok != DEL_TRAP) b.add(parserLine, GET_PRESERVE);
+
+ startExpr(b, precedence[tok]);
+
+ if (tok != ADD_TRAP && tok != DEL_TRAP) {
+ // tok-1 is always s/^ASSIGN_// (0 is BITOR, 1 is ASSIGN_BITOR, etc)
+ b.add(parserLine, tok - 1, tok-1==ADD ? JS.N(2) : null);
+ b.add(parserLine, PUT);
+ b.add(parserLine, SWAP);
+ b.add(parserLine, POP);
+ } else {
+ b.add(parserLine, tok);
+ }
+ break;
+ }
+ case INC: case DEC: { // postfix
+ b.add(parserLine, GET_PRESERVE, Boolean.TRUE);
+ b.add(parserLine, LITERAL, JS.N(1));
+ b.add(parserLine, tok == INC ? ADD : SUB, JS.N(2));
+ b.add(parserLine, PUT, null);
+ b.add(parserLine, SWAP, null);
+ b.add(parserLine, POP, null);
+ b.add(parserLine, LITERAL, JS.N(1));
+ b.add(parserLine, tok == INC ? SUB : ADD, JS.N(2)); // undo what we just did, since this is postfix
+ break;
+ }
+ case ASSIGN: {
+ startExpr(b, precedence[tok]);
+ b.add(parserLine, PUT);
+ b.add(parserLine, SWAP);
+ b.add(parserLine, POP);
+ break;
+ }
+ case LP: {
+
+ // Method calls are implemented by doing a GET_PRESERVE
+ // first. If the object supports method calls, it will
+ // return JS.METHOD
+ int n = parseArgs(b, 2);
+ b.add(parserLine, GET_PRESERVE);
+ b.add(parserLine, CALLMETHOD, JS.N(n));
+ break;
+ }
+ default: {
+ pushBackToken();
+ if(b.get(b.size-1) == LITERAL && b.getArg(b.size-1) != null)
+ b.set(b.size-1,GET,b.getArg(b.size-1));
+ else
+ b.add(parserLine, GET);
+ return;
+ }
+ }
+ }
+
+
+ /**
+ * Assuming that a complete expression has just been parsed,
+ * <tt>continueExpr</tt> will attempt to extend this expression by
+ * parsing additional tokens and appending additional bytecodes.
+ *
+ * No operators with precedence less than <tt>minPrecedence</tt>
+ * will be parsed.
+ *
+ * If any bytecodes are appended, they will not alter the stack
+ * depth.
+ */
+ private void continueExpr(JSFunction b, int minPrecedence) throws IOException {
+ int saveParserLine = parserLine;
+ _continueExpr(b, minPrecedence);
+ parserLine = saveParserLine;
+ }
+ private void _continueExpr(JSFunction b, int minPrecedence) throws IOException {
+ if (b == null) throw new Error("got null b; this should never happen");
+ int tok = getToken();
+ if (tok == -1) return;
+ if (minPrecedence != -1 && (precedence[tok] < minPrecedence || (precedence[tok] == minPrecedence && !isRightAssociative[tok]))) {
+ pushBackToken();
+ return;
+ }
+
+ switch (tok) {
+ case LP: { // invocation (not grouping)
+ int n = parseArgs(b, 1);
+ b.add(parserLine, CALL, JS.N(n));
+ break;
+ }
+ case BITOR: case BITXOR: case BITAND: case SHEQ: case SHNE: case LSH:
+ case RSH: case URSH: case MUL: case DIV: case MOD:
+ case GT: case GE: case EQ: case NE: case LT: case LE: case SUB: {
+ startExpr(b, precedence[tok]);
+ b.add(parserLine, tok);
+ break;
+ }
+ case ADD: {
+ int count=1;
+ int nextTok;
+ do {
+ startExpr(b,precedence[tok]);
+ count++;
+ nextTok = getToken();
+ } while(nextTok == tok);
+ pushBackToken();
+ b.add(parserLine, tok, JS.N(count));
+ break;
+ }
+ case OR: case AND: {
+ b.add(parserLine, tok == AND ? JSFunction.JF : JSFunction.JT, JS.ZERO); // test to see if we can short-circuit
+ int size = b.size;
+ startExpr(b, precedence[tok]); // otherwise check the second value
+ b.add(parserLine, JMP, JS.N(2)); // leave the second value on the stack and jump to the end
+ b.add(parserLine, LITERAL, tok == AND ?
+ JS.B(false) : JS.B(true)); // target of the short-circuit jump is here
+ b.set(size - 1, JS.N(b.size - size)); // write the target of the short-circuit jump
+ break;
+ }
+ case DOT: {
+ // support foo..bar syntax for foo[""].bar
+ if (peekToken() == DOT) {
+ string = "";
+ } else {
+ consume(NAME);
+ }
+ b.add(parserLine, LITERAL, string);
+ continueExprAfterAssignable(b,minPrecedence);
+ break;
+ }
+ case LB: { // subscripting (not array constructor)
+ startExpr(b, -1);
+ consume(RB);
+ continueExprAfterAssignable(b,minPrecedence);
+ break;
+ }
+ case HOOK: {
+ b.add(parserLine, JF, JS.ZERO); // jump to the if-false expression
+ int size = b.size;
+ startExpr(b, minPrecedence); // write the if-true expression
+ b.add(parserLine, JMP, JS.ZERO); // if true, jump *over* the if-false expression
+ b.set(size - 1, JS.N(b.size - size + 1)); // now we know where the target of the jump is
+ consume(COLON);
+ size = b.size;
+ startExpr(b, minPrecedence); // write the if-false expression
+ b.set(size - 1, JS.N(b.size - size + 1)); // this is the end; jump to here
+ break;
+ }
+ case COMMA: {
+ // pop the result of the previous expression, it is ignored
+ b.add(parserLine,POP);
+ startExpr(b,-1);
+ break;
+ }
+ default: {
+ pushBackToken();
+ return;
+ }
+ }
+
+ continueExpr(b, minPrecedence); // try to continue the expression
+ }
+
+ // parse a set of comma separated function arguments, assume LP has already been consumed
+ // if swap is true, (because the function is already on the stack) we will SWAP after each argument to keep it on top
+ private int parseArgs(JSFunction b, int pushdown) throws IOException {
+ int i = 0;
+ while(peekToken() != RP) {
+ i++;
+ if (peekToken() != COMMA) {
+ startExpr(b, NO_COMMA);
+ b.add(parserLine, SWAP, JS.N(pushdown));
+ if (peekToken() == RP) break;
+ }
+ consume(COMMA);
+ }
+ consume(RP);
+ return i;
+ }
+
+ /** Parse a block of statements which must be surrounded by LC..RC. */
+ void parseBlock(JSFunction b) throws IOException { parseBlock(b, null); }
+ void parseBlock(JSFunction b, String label) throws IOException {
+ int saveParserLine = parserLine;
+ _parseBlock(b, label);
+ parserLine = saveParserLine;
+ }
+ void _parseBlock(JSFunction b, String label) throws IOException {
+ if (peekToken() == -1) return;
+ else if (peekToken() != LC) parseStatement(b, null);
+ else {
+ consume(LC);
+ while(peekToken() != RC && peekToken() != -1) parseStatement(b, null);
+ consume(RC);
+ }
+ }
+
+ /** Parse a single statement, consuming the RC or SEMI which terminates it. */
+ void parseStatement(JSFunction b, String label) throws IOException {
+ int saveParserLine = parserLine;
+ _parseStatement(b, label);
+ parserLine = saveParserLine;
+ }
+ void _parseStatement(JSFunction b, String label) throws IOException {
+ int tok = peekToken();
+ if (tok == -1) return;
+ switch(tok = getToken()) {
+
+ case THROW: case ASSERT: case RETURN: {
+ if (tok == RETURN && peekToken() == SEMI)
+ b.add(parserLine, LITERAL, null);
+ else
+ startExpr(b, -1);
+ b.add(parserLine, tok);
+ consume(SEMI);
+ break;
+ }
+ case BREAK: case CONTINUE: {
+ if (peekToken() == NAME) consume(NAME);
+ b.add(parserLine, tok, string);
+ consume(SEMI);
+ break;
+ }
+ case VAR: {
+ b.add(parserLine, TOPSCOPE); // push the current scope
+ while(true) {
+ consume(NAME);
+ b.add(parserLine, DECLARE, string); // declare it
+ if (peekToken() == ASSIGN) { // if there is an '=' after the variable name
+ consume(ASSIGN);
+ startExpr(b, NO_COMMA);
+ b.add(parserLine, PUT); // assign it
+ b.add(parserLine, POP); // clean the stack
+ } else {
+ b.add(parserLine, POP); // pop the string pushed by declare
+ }
+ if (peekToken() != COMMA) break;
+ consume(COMMA);
+ }
+ b.add(parserLine, POP); // pop off the topscope
+ if ((mostRecentlyReadToken != RC || peekToken() == SEMI) && peekToken() != -1 && mostRecentlyReadToken != SEMI) consume(SEMI);
+ break;
+ }
+ case IF: {
+ consume(LP);
+ startExpr(b, -1);
+ consume(RP);
+
+ b.add(parserLine, JF, JS.ZERO); // if false, jump to the else-block
+ int size = b.size;
+ parseStatement(b, null);
+
+ if (peekToken() == ELSE) {
+ consume(ELSE);
+ b.add(parserLine, JMP, JS.ZERO); // if we took the true-block, jump over the else-block
+ b.set(size - 1, JS.N(b.size - size + 1));
+ size = b.size;
+ parseStatement(b, null);
+ }
+ b.set(size - 1, JS.N(b.size - size + 1)); // regardless of which branch we took, b[size] needs to point here
+ break;
+ }
+ case WHILE: {
+ consume(LP);
+ if (label != null) b.add(parserLine, LABEL, label);
+ b.add(parserLine, LOOP);
+ int size = b.size;
+ b.add(parserLine, POP); // discard the first-iteration indicator
+ startExpr(b, -1);
+ b.add(parserLine, JT, JS.N(2)); // if the while() clause is true, jump over the BREAK
+ b.add(parserLine, BREAK);
+ consume(RP);
+ parseStatement(b, null);
+ b.add(parserLine, CONTINUE); // if we fall out of the end, definately continue
+ b.set(size - 1, JS.N(b.size - size + 1)); // end of the loop
+ break;
+ }
+ case SWITCH: {
+ consume(LP);
+ if (label != null) b.add(parserLine, LABEL, label);
+ b.add(parserLine, LOOP);
+ int size0 = b.size;
+ startExpr(b, -1);
+ consume(RP);
+ consume(LC);
+ while(true)
+ if (peekToken() == CASE) { // we compile CASE statements like a bunch of if..else's
+ consume(CASE);
+ b.add(parserLine, DUP); // duplicate the switch() value; we'll consume one copy
+ startExpr(b, -1);
+ consume(COLON);
+ b.add(parserLine, EQ); // check if we should do this case-block
+ b.add(parserLine, JF, JS.ZERO); // if not, jump to the next one
+ int size = b.size;
+ while(peekToken() != CASE && peekToken() != DEFAULT && peekToken() != RC) parseStatement(b, null);
+ b.set(size - 1, JS.N(1 + b.size - size));
+ } else if (peekToken() == DEFAULT) {
+ consume(DEFAULT);
+ consume(COLON);
+ while(peekToken() != CASE && peekToken() != DEFAULT && peekToken() != RC) parseStatement(b, null);
+ } else if (peekToken() == RC) {
+ consume(RC);
+ b.add(parserLine, BREAK); // break out of the loop if we 'fall through'
+ break;
+ } else {
+ throw pe("expected CASE, DEFAULT, or RC; got " + codeToString[peekToken()]);
+ }
+ b.set(size0 - 1, JS.N(b.size - size0 + 1)); // end of the loop
+ break;
+ }
+
+ case DO: {
+ if (label != null) b.add(parserLine, LABEL, label);
+ b.add(parserLine, LOOP);
+ int size = b.size;
+ parseStatement(b, null);
+ consume(WHILE);
+ consume(LP);
+ startExpr(b, -1);
+ b.add(parserLine, JT, JS.N(2)); // check the while() clause; jump over the BREAK if true
+ b.add(parserLine, BREAK);
+ b.add(parserLine, CONTINUE);
+ consume(RP);
+ consume(SEMI);
+ b.set(size - 1, JS.N(b.size - size + 1)); // end of the loop; write this location to the LOOP instruction
+ break;
+ }
+
+ case TRY: {
+ b.add(parserLine, TRY); // try bytecode causes a TryMarker to be pushed
+ int tryInsn = b.size - 1;
+ // parse the expression to be TRYed
+ parseStatement(b, null);
+ // pop the try marker. this is pushed when the TRY bytecode is executed
+ b.add(parserLine, POP);
+ // jump forward to the end of the catch block, start of the finally block
+ b.add(parserLine, JMP);
+ int successJMPInsn = b.size - 1;
+
+ if (peekToken() != CATCH && peekToken() != FINALLY)
+ throw pe("try without catch or finally");
+
+ int catchJMPDistance = -1;
+ if (peekToken() == CATCH) {
+ Vec catchEnds = new Vec();
+ boolean catchAll = false;
+
+ catchJMPDistance = b.size - tryInsn;
+
+ while(peekToken() == CATCH && !catchAll) {
+ String exceptionVar;
+ getToken();
+ consume(LP);
+ consume(NAME);
+ exceptionVar = string;
+ int[] writebacks = new int[] { -1, -1, -1 };
+ if (peekToken() != RP) {
+ // extended Ibex catch block: catch(e faultCode "foo.bar.baz")
+ consume(NAME);
+ b.add(parserLine, DUP);
+ b.add(parserLine, LITERAL, string);
+ b.add(parserLine, GET);
+ b.add(parserLine, DUP);
+ b.add(parserLine, LITERAL, null);
+ b.add(parserLine, EQ);
+ b.add(parserLine, JT);
+ writebacks[0] = b.size - 1;
+ if (peekToken() == STRING) {
+ consume(STRING);
+ b.add(parserLine, DUP);
+ b.add(parserLine, LITERAL, string);
+ b.add(parserLine, LT);
+ b.add(parserLine, JT);
+ writebacks[1] = b.size - 1;
+ b.add(parserLine, DUP);
+ b.add(parserLine, LITERAL, string + "/"); // (slash is ASCII after dot)
+ b.add(parserLine, GE);
+ b.add(parserLine, JT);
+ writebacks[2] = b.size - 1;
+ } else {
+ consume(NUMBER);
+ b.add(parserLine, DUP);
+ b.add(parserLine, LITERAL, number);
+ b.add(parserLine, EQ);
+ b.add(parserLine, JF);
+ writebacks[1] = b.size - 1;
+ }
+ b.add(parserLine, POP); // pop the element thats on the stack from the compare
+ } else {
+ catchAll = true;
+ }
+ consume(RP);
+ // the exception is on top of the stack; put it to the chosen name
+ b.add(parserLine, NEWSCOPE);
+ b.add(parserLine, TOPSCOPE);
+ b.add(parserLine, SWAP);
+ b.add(parserLine, LITERAL,exceptionVar);
+ b.add(parserLine, DECLARE);
+ b.add(parserLine, SWAP);
+ b.add(parserLine, PUT);
+ b.add(parserLine, POP);
+ b.add(parserLine, POP);
+ parseBlock(b, null);
+ b.add(parserLine, OLDSCOPE);
+
+ b.add(parserLine, JMP);
+ catchEnds.addElement(new Integer(b.size-1));
+
+ for(int i=0; i<3; i++) if (writebacks[i] != -1) b.set(writebacks[i], JS.N(b.size-writebacks[i]));
+ b.add(parserLine, POP); // pop the element thats on the stack from the compare
+ }
+
+ if(!catchAll)
+ b.add(parserLine, THROW);
+
+ for(int i=0;i<catchEnds.size();i++) {
+ int n = ((Integer)catchEnds.elementAt(i)).intValue();
+ b.set(n, JS.N(b.size-n));
+ }
+
+ // pop the try and catch markers
+ b.add(parserLine,POP);
+ b.add(parserLine,POP);
+ }
+
+ // jump here if no exception was thrown
+ b.set(successJMPInsn, JS.N(b.size - successJMPInsn));
+
+ int finallyJMPDistance = -1;
+ if (peekToken() == FINALLY) {
+ b.add(parserLine, LITERAL, null); // null FinallyData
+ finallyJMPDistance = b.size - tryInsn;
+ consume(FINALLY);
+ parseStatement(b, null);
+ b.add(parserLine,FINALLY_DONE);
+ }
+
+ // setup the TRY arguments
+ b.set(tryInsn, new int[] { catchJMPDistance, finallyJMPDistance });
+
+ break;
+ }
+
+ case FOR: {
+ consume(LP);
+
+ tok = getToken();
+ boolean hadVar = false; // if it's a for..in, we ignore the VAR
+ if (tok == VAR) { hadVar = true; tok = getToken(); }
+ String varName = string;
+ boolean forIn = peekToken() == IN; // determine if this is a for..in loop or not
+ pushBackToken(tok, varName);
+
+ if (forIn) {
+ consume(NAME);
+ consume(IN);
+ startExpr(b,-1);
+ consume(RP);
+
+ b.add(parserLine, PUSHKEYS);
+ b.add(parserLine, DUP);
+ b.add(parserLine, LITERAL, "length");
+ b.add(parserLine, GET);
+ // Stack is now: n, keys, obj, ...
+
+ int size = b.size;
+ b.add(parserLine, LOOP);
+ b.add(parserLine, POP);
+ // Stack is now: LoopMarker, n, keys, obj, ...
+ // NOTE: This will break if the interpreter ever becomes more strict
+ // and prevents bytecode from messing with the Markers
+ b.add(parserLine, SWAP, JS.N(3));
+ // Stack is now: Tn, keys, obj, LoopMarker, ...
+
+ b.add(parserLine, LITERAL, JS.N(1));
+ b.add(parserLine, SUB);
+ b.add(parserLine, DUP);
+ // Stack is now: index, keys, obj, LoopMarker
+ b.add(parserLine, LITERAL, JS.ZERO);
+ b.add(parserLine, LT);
+ // Stack is now index<0, index, keys, obj, LoopMarker, ...
+
+ b.add(parserLine, JF, JS.N(5)); // if we're >= 0 jump 5 down (to NEWSCOPE)
+ // Move the LoopMarker back into place - this is sort of ugly
+ b.add(parserLine, SWAP, JS.N(3));
+ b.add(parserLine, SWAP, JS.N(3));
+ b.add(parserLine, SWAP, JS.N(3));
+ // Stack is now: LoopMarker, -1, keys, obj, ...
+ b.add(parserLine, BREAK);
+
+ b.add(parserLine, NEWSCOPE);
+ if(hadVar) {
+ b.add(parserLine, DECLARE, varName);
+ b.add(parserLine, POP);
+ }
+
+ // Stack is now: index, keys, obj, LoopMarker, ...
+ b.add(parserLine, GET_PRESERVE); // key, index, keys, obj, LoopMarker, ...
+ b.add(parserLine, TOPSCOPE); // scope, key, index, keys, obj, LoopMarker, ...
+ b.add(parserLine, SWAP); // key, scope, index, keys, obj, LoopMarker, ...
+ b.add(parserLine, LITERAL, varName); // varName, key, scope, index, keys, obj, LoopMaker, ...
+ b.add(parserLine, SWAP); // key, varName, scope, index, keys, obj, LoopMarker, ...
+ b.add(parserLine, PUT); // key, scope, index, keys, obj, LoopMarker, ...
+ b.add(parserLine, POP); // scope, index, keys, obj, LoopMarker
+ b.add(parserLine, POP); // index, keys, obj, LoopMarker, ...
+ // Move the LoopMarker back into place - this is sort of ugly
+ b.add(parserLine, SWAP, JS.N(3));
+ b.add(parserLine, SWAP, JS.N(3));
+ b.add(parserLine, SWAP, JS.N(3));
+
+ parseStatement(b, null);
+
+ b.add(parserLine, OLDSCOPE);
+ b.add(parserLine, CONTINUE);
+ // jump here on break
+ b.set(size, JS.N(b.size - size));
+
+ b.add(parserLine, POP); // N
+ b.add(parserLine, POP); // KEYS
+ b.add(parserLine, POP); // OBJ
+
+ } else {
+ if (hadVar) pushBackToken(VAR, null); // yeah, this actually matters
+ b.add(parserLine, NEWSCOPE); // grab a fresh scope
+
+ parseStatement(b, null); // initializer
+ JSFunction e2 = // we need to put the incrementor before the test
+ new JSFunction(sourceName, parserLine, null); // so we save the test here
+ if (peekToken() != SEMI)
+ startExpr(e2, -1);
+ else
+ e2.add(parserLine, JSFunction.LITERAL, Boolean.TRUE); // handle the for(foo;;foo) case
+ consume(SEMI);
+ if (label != null) b.add(parserLine, LABEL, label);
+ b.add(parserLine, LOOP);
+ int size2 = b.size;
+
+ b.add(parserLine, JT, JS.ZERO); // if we're on the first iteration, jump over the incrementor
+ int size = b.size;
+ if (peekToken() != RP) { // do the increment thing
+ startExpr(b, -1);
+ b.add(parserLine, POP);
+ }
+ b.set(size - 1, JS.N(b.size - size + 1));
+ consume(RP);
+
+ b.paste(e2); // ok, *now* test if we're done yet
+ b.add(parserLine, JT, JS.N(2)); // break out if we don't meet the test
+ b.add(parserLine, BREAK);
+ parseStatement(b, null);
+ b.add(parserLine, CONTINUE); // if we fall out the bottom, CONTINUE
+ b.set(size2 - 1, JS.N(b.size - size2 + 1)); // end of the loop
+
+ b.add(parserLine, OLDSCOPE); // get our scope back
+ }
+ break;
+ }
+
+ case NAME: { // either a label or an identifier; this is the one place we're not LL(1)
+ String possiblyTheLabel = string;
+ if (peekToken() == COLON) { // label
+ consume(COLON);
+ parseStatement(b, possiblyTheLabel);
+ break;
+ } else { // expression
+ pushBackToken(NAME, possiblyTheLabel);
+ startExpr(b, -1);
+ b.add(parserLine, POP);
+ if ((mostRecentlyReadToken != RC || peekToken() == SEMI) && peekToken() != -1 && mostRecentlyReadToken != SEMI) consume(SEMI);
+ break;
+ }
+ }
+
+ case SEMI: return; // yep, the null statement is valid
+
+ case LC: { // blocks are statements too
+ pushBackToken();
+ b.add(parserLine, NEWSCOPE);
+ parseBlock(b, label);
+ b.add(parserLine, OLDSCOPE);
+ break;
+ }
+
+ default: { // hope that it's an expression
+ pushBackToken();
+ startExpr(b, -1);
+ b.add(parserLine, POP);
+ if ((mostRecentlyReadToken != RC || peekToken() == SEMI) && peekToken() != -1 && mostRecentlyReadToken != SEMI) consume(SEMI);
+ break;
+ }
+ }
+ }
+
+
+ // ParserException //////////////////////////////////////////////////////////////////////
+ private IOException pe(String s) { return new IOException(sourceName + ":" + line + " " + s); }
+
+}
+
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.js;
+
+import java.io.*;
+import java.util.zip.*;
+import org.ibex.util.*;
+import org.ibex.plat.*;
+import org.ibex.net.*;
+
+/**
+ * Essentiall an InputStream "factory". You can repeatedly ask a
+ * Stream for an InputStream, and each InputStream you get back will
+ * be totally independent of the others (ie separate stream position
+ * and state) although they draw from the same data source.
+ */
+public abstract class Stream extends JS.Cloneable {
+
+ // Public Interface //////////////////////////////////////////////////////////////////////////////
+
+ public static InputStream getInputStream(Object js) throws IOException { return ((Stream)((JS)js).unclone()).getInputStream();}
+ public static class NotCacheableException extends Exception { }
+
+ // streams are "sealed" by default to prevent accidental object leakage
+ public void put(Object key, Object val) { }
+ private Cache getCache = new Cache(100);
+ protected Object _get(Object key) { return null; }
+ public final Object get(Object key) {
+ Object ret = getCache.get(key);
+ if (ret == null) getCache.put(key, ret = _get(key));
+ return ret;
+ }
+
+ // Private Interface //////////////////////////////////////////////////////////////////////////////
+
+ public abstract InputStream getInputStream() throws IOException;
+ protected String getCacheKey() throws NotCacheableException { throw new NotCacheableException(); }
+
+ /** HTTP or HTTPS resource */
+ public static class HTTP extends Stream {
+ private String url;
+ public String toString() { return "Stream.HTTP:" + url; }
+ public HTTP(String url) { while (url.endsWith("/")) url = url.substring(0, url.length() - 1); this.url = url; }
+ public Object _get(Object key) { return new HTTP(url + "/" + (String)key); }
+ public String getCacheKey(Vec path) throws NotCacheableException { return url; }
+ public InputStream getInputStream() throws IOException { return new org.ibex.net.HTTP(url).GET(); }
+ }
+
+ /** byte arrays */
+ public static class ByteArray extends Stream {
+ private byte[] bytes;
+ private String cacheKey;
+ public ByteArray(byte[] bytes, String cacheKey) { this.bytes = bytes; this.cacheKey = cacheKey; }
+ public String getCacheKey() throws NotCacheableException {
+ if (cacheKey == null) throw new NotCacheableException(); return cacheKey; }
+ public InputStream getInputStream() throws IOException { return new ByteArrayInputStream(bytes); }
+ }
+
+ /** a file */
+ public static class File extends Stream {
+ private String path;
+ public File(String path) { this.path = path; }
+ public String toString() { return "file:" + path; }
+ public String getCacheKey() throws NotCacheableException { throw new NotCacheableException(); /* already on disk */ }
+ public InputStream getInputStream() throws IOException { return new FileInputStream(path); }
+ public Object _get(Object key) { return new File(path + java.io.File.separatorChar + (String)key); }
+ }
+
+ /** "unwrap" a Zip archive */
+ public static class Zip extends Stream {
+ private Stream parent;
+ private String path;
+ public Zip(Stream parent) { this(parent, null); }
+ public Zip(Stream parent, String path) {
+ while(path != null && path.startsWith("/")) path = path.substring(1);
+ this.parent = parent;
+ this.path = path;
+ }
+ public String getCacheKey() throws NotCacheableException { return parent.getCacheKey() + "!zip:"; }
+ public Object _get(Object key) { return new Zip(parent, path==null?(String)key:path+'/'+(String)key); }
+ public InputStream getInputStream() throws IOException {
+ InputStream pis = parent.getInputStream();
+ ZipInputStream zis = new ZipInputStream(pis);
+ ZipEntry ze = zis.getNextEntry();
+ while(ze != null && !ze.getName().equals(path)) ze = zis.getNextEntry();
+ if (ze == null) throw new IOException("requested file (" + path + ") not found in archive");
+ return new KnownLength.KnownLengthInputStream(zis, (int)ze.getSize());
+ }
+ }
+
+ /** "unwrap" a Cab archive */
+ public static class Cab extends Stream {
+ private Stream parent;
+ private String path;
+ public Cab(Stream parent) { this(parent, null); }
+ public Cab(Stream parent, String path) { this.parent = parent; this.path = path; }
+ public String getCacheKey() throws NotCacheableException { return parent.getCacheKey() + "!cab:"; }
+ public Object _get(Object key) { return new Cab(parent, path==null?(String)key:path+'/'+(String)key); }
+ public InputStream getInputStream() throws IOException { return new MSPack(parent.getInputStream()).getInputStream(path); }
+ }
+
+ /** the Builtin resource */
+ public static class Builtin extends Stream {
+ public String getCacheKey() throws NotCacheableException { throw new NotCacheableException(); }
+ public InputStream getInputStream() throws IOException { return Platform.getBuiltinInputStream(); }
+ }
+
+ /** shadow resource which replaces the graft */
+ public static class ProgressWatcher extends Stream {
+ final Stream watchee;
+ JS callback;
+ public ProgressWatcher(Stream watchee, JS callback) { this.watchee = watchee; this.callback = callback; }
+ public String getCacheKey() throws NotCacheableException { return watchee.getCacheKey(); }
+ public InputStream getInputStream() throws IOException {
+ final InputStream is = watchee.getInputStream();
+ return new FilterInputStream(is) {
+ int bytesDownloaded = 0;
+ public int read() throws IOException {
+ int ret = super.read();
+ if (ret != -1) bytesDownloaded++;
+ return ret;
+ }
+ public int read(byte[] b, int off, int len) throws IOException {
+ int ret = super.read(b, off, len);
+ if (ret != 1) bytesDownloaded += ret;
+ Scheduler.add(new Task() { public void perform() throws IOException, JSExn {
+ callback.call(N(bytesDownloaded),
+ N(is instanceof KnownLength ? ((KnownLength)is).getLength() : 0), null, null, 2);
+ } });
+ return ret;
+ }
+ };
+ }
+ }
+
+ /** subclass from this if you want a CachedInputStream for each path */
+ public static class CachedStream extends Stream {
+ private Stream parent;
+ private boolean disk = false;
+ private String key;
+ public String getCacheKey() throws NotCacheableException { return key; }
+ CachedInputStream cis = null;
+ public CachedStream(Stream p, String s, boolean d) throws NotCacheableException {
+ this.parent = p; this.disk = d; this.key = p.getCacheKey();
+ }
+ public InputStream getInputStream() throws IOException {
+ if (cis != null) return cis.getInputStream();
+ if (!disk) {
+ cis = new CachedInputStream(parent.getInputStream());
+ } else {
+ java.io.File f = org.ibex.core.LocalStorage.Cache.getCacheFileForKey(key);
+ if (f.exists()) return new FileInputStream(f);
+ cis = new CachedInputStream(parent.getInputStream(), f);
+ }
+ return cis.getInputStream();
+ }
+ }
+}
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.js;
+
+/** this class contains a <tt>public static final int</tt> for each valid token */
+interface Tokens {
+
+ // Token Constants //////////////////////////////////////////////////////////
+
+ // arithmetic operations; also valid as bytecodes
+ public static final int BITOR = 0; // |
+ public static final int ASSIGN_BITOR = 1; // |=
+ public static final int BITXOR = 2; // ^
+ public static final int ASSIGN_BITXOR = 3; // ^=
+ public static final int BITAND = 4; // &
+ public static final int ASSIGN_BITAND = 5; // &=
+ public static final int LSH = 6; // <<
+ public static final int ASSIGN_LSH = 7; // <<=
+ public static final int RSH = 8; // >>
+ public static final int ASSIGN_RSH = 9; // >>=
+ public static final int URSH = 10; // >>>
+ public static final int ASSIGN_URSH = 11; // >>>=
+ public static final int ADD = 12; // +
+ public static final int ASSIGN_ADD = 13; // +=
+ public static final int SUB = 14; // -
+ public static final int ASSIGN_SUB = 15; // -=
+ public static final int MUL = 16; // *
+ public static final int ASSIGN_MUL = 17; // *=
+ public static final int DIV = 18; // /
+ public static final int ASSIGN_DIV = 19; // /=
+ public static final int MOD = 20; // %
+ public static final int ASSIGN_MOD = 21; // %=
+ public static final int BITNOT = 22; // ~
+ public static final int ASSIGN_BITNOT = 23; // ~=
+
+ // logical operations; also valid as bytecodes
+ public static final int OR = 24; // ||
+ public static final int AND = 25; // &&
+ public static final int BANG = 26; // !
+
+ // equality operations; also valid as bytecodes
+ public static final int EQ = 27; // ==
+ public static final int NE = 28; // !=
+ public static final int LT = 29; // <
+ public static final int LE = 30; // <=
+ public static final int GT = 31; // >
+ public static final int GE = 32; // >=
+ public static final int SHEQ = 33; // ===
+ public static final int SHNE = 34; // !==
+
+ // other permissible bytecode tokens
+ public static final int RETURN = 35; // return
+ public static final int TYPEOF = 36; // typeof
+ public static final int BREAK = 37; // break keyword
+ public static final int CONTINUE = 38; // continue keyword
+ public static final int TRY = 39; // try
+ public static final int THROW = 40; // throw
+ public static final int ASSERT = 41; // assert keyword
+
+ public static final int NAME = 42; // *** identifiers ***
+ public static final int NUMBER = 43; // *** numeric literals ***
+ public static final int STRING = 44; // *** string literals ***
+ public static final int NULL = 45; // null
+ public static final int THIS = 46; // this
+ public static final int FALSE = 47; // false
+ public static final int TRUE = 48; // true
+ public static final int IN = 49; // in
+
+ public static final int SEMI = 50; // ;
+ public static final int LB = 51; // [
+ public static final int RB = 52; // ]
+ public static final int LC = 53; // {
+ public static final int RC = 54; // }
+ public static final int LP = 55; // (
+ public static final int RP = 56; // )
+ public static final int COMMA = 57; // ,
+ public static final int ASSIGN = 58; // =
+ public static final int HOOK = 59; // ?
+ public static final int COLON = 60; // :
+ public static final int INC = 61; // ++
+ public static final int DEC = 62; // --
+ public static final int DOT = 63; // .
+ public static final int FUNCTION = 64; // function
+ public static final int IF = 65; // if keyword
+ public static final int ELSE = 66; // else keyword
+ public static final int SWITCH = 67; // switch keyword
+ public static final int CASE = 68; // case keyword
+ public static final int DEFAULT = 69; // default keyword
+ public static final int WHILE = 70; // while keyword
+ public static final int DO = 71; // do keyword
+ public static final int FOR = 72; // for keyword
+ public static final int VAR = 73; // var keyword
+ public static final int WITH = 74; // with keyword
+ public static final int CATCH = 75; // catch keyword
+ public static final int FINALLY = 76; // finally keyword
+ public static final int RESERVED = 77; // reserved keyword
+ public static final int GRAMMAR = 78; // the grammar-definition operator (::=)
+ public static final int ADD_TRAP = 79; // the add-trap operator (++=)
+ public static final int DEL_TRAP = 80; // the del-trap operator (--=)
+
+ public static final int MAX_TOKEN = DEL_TRAP;
+
+ public final static String[] codeToString = new String[] {
+ "BITOR", "ASSIGN_BITOR", "BITXOR", "ASSIGN_BITXOR", "BITAND",
+ "ASSIGN_BITAND", "LSH", "ASSIGN_LSH", "RSH", "ASSIGN_RSH",
+ "URSH", "ASSIGN_URSH", "ADD", "ASSIGN_ADD", "SUB",
+ "ASSIGN_SUB", "MUL", "ASSIGN_MUL", "DIV", "ASSIGN_DIV", "MOD",
+ "ASSIGN_MOD", "BITNOT", "ASSIGN_BITNOT", "OR", "AND", "BANG",
+ "EQ", "NE", "LT", "LE", "GT", "GE", "SHEQ", "SHNE", "RETURN",
+ "TYPEOF", "BREAK", "CONTINUE", "TRY", "THROW", "ASSERT", "NAME",
+ "NUMBER", "STRING", "NULL", "THIS", "FALSE", "TRUE", "IN",
+ "SEMI", "LB", "RB", "LC", "RC", "LP", "RP", "COMMA", "ASSIGN",
+ "HOOK", "COLON", "INC", "DEC", "DOT", "FUNCTION", "IF",
+ "ELSE", "SWITCH", "CASE", "DEFAULT", "WHILE", "DO", "FOR",
+ "VAR", "WITH", "CATCH", "FINALLY", "RESERVED", "GRAMMAR",
+ "ADD_TRAP", "DEL_TRAP"
+ };
+
+}
+
+
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.js;
+
+/**
+ * This class encapsulates a single trap placed on a given node. The
+ * traps for a given property name on a given box are maintained as a
+ * linked list stack, with the most recently placed trap at the head
+ * of the list.
+ */
+class Trap {
+
+ JS trapee = null; ///< the box on which this trap was placed
+ Object name = null; ///< the property that the trap was placed on
+
+ JSFunction f = null; ///< the function for this trap
+ Trap next = null; ///< the next trap down the trap stack
+
+ Trap(JS b, String n, JSFunction f, Trap nx) {
+ trapee = b; name = n; this.f = f; this.next = nx;
+ }
+
+ static final JSFunction putInvoker = new JSFunction("putInvoker", 0, null);
+ static final JSFunction getInvoker = new JSFunction("getInvoker", 0, null);
+
+ static {
+ putInvoker.add(1, ByteCodes.PUT, null);
+ putInvoker.add(2, Tokens.RETURN, null);
+ getInvoker.add(1, ByteCodes.GET, null);
+ getInvoker.add(2, Tokens.RETURN, null);
+ }
+
+ void invoke(Object value) throws JSExn {
+ Interpreter i = new Interpreter(putInvoker, false, null);
+ i.stack.push(trapee);
+ i.stack.push(name);
+ i.stack.push(value);
+ i.resume();
+ }
+
+ Object invoke() throws JSExn {
+ Interpreter i = new Interpreter(getInvoker, false, null);
+ i.stack.push(trapee);
+ i.stack.push(name);
+ return i.resume();
+ }
+
+ // FIXME: review; is necessary?
+ static class TrapScope extends JSScope {
+ Trap t;
+ Object val = null;
+ boolean cascadeHappened = false;
+ public TrapScope(JSScope parent, Trap t, Object val) { super(parent); this.t = t; this.val = val; }
+ public Object get(Object key) throws JSExn {
+ if (key.equals("trapee")) return t.trapee;
+ if (key.equals("callee")) return t.f;
+ if (key.equals("trapname")) return t.name;
+ return super.get(key);
+ }
+ }
+}
+
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.net;
+
+import java.net.*;
+import java.io.*;
+import java.util.*;
+import org.ibex.js.*;
+import org.ibex.util.*;
+import org.ibex.plat.*;
+import org.ibex.core.*;
+import org.ibex.crypto.*;
+
+/**
+ * This object encapsulates a *single* HTTP connection. Multiple requests may be pipelined over a connection (thread-safe),
+ * although any IOException encountered in a request will invalidate all later requests.
+ */
+public class HTTP {
+
+
+ // Public Methods ////////////////////////////////////////////////////////////////////////////////////////
+
+ public HTTP(String url) { this(url, false); }
+ public HTTP(String url, boolean skipResolveCheck) { originalUrl = url; this.skipResolveCheck = skipResolveCheck; }
+
+ /** Performs an HTTP GET request */
+ public InputStream GET() throws IOException { return makeRequest(null, null); }
+
+ /** Performs an HTTP POST request; content is additional headers, blank line, and body */
+ public InputStream POST(String contentType, String content) throws IOException { return makeRequest(contentType, content); }
+
+ public static class HTTPException extends IOException { public HTTPException(String s) { super(s); } }
+
+ public static HTTP stdio = new HTTP("stdio:");
+
+
+ // Statics ///////////////////////////////////////////////////////////////////////////////////////////////
+
+ static Hash resolvedHosts = new Hash(); ///< cache for resolveAndCheckIfFirewalled()
+ private static Hash authCache = new Hash(); ///< cache of userInfo strings, keyed on originalUrl
+
+
+ // Instance Data ///////////////////////////////////////////////////////////////////////////////////////////////
+
+ final String originalUrl; ///< the URL as passed to the original constructor; this is never changed
+ String url = null; ///< the URL to connect to; this is munged when the url is parsed */
+ String host = null; ///< the host to connect to
+ int port = -1; ///< the port to connect on
+ boolean ssl = false; ///< true if SSL (HTTPS) should be used
+ String path = null; ///< the path (URI) to retrieve on the server
+ Socket sock = null; ///< the socket
+ InputStream in = null; ///< the socket's inputstream
+ String userInfo = null; ///< the username and password portions of the URL
+ boolean firstRequest = true; ///< true iff this is the first request to be made on this socket
+ boolean skipResolveCheck = false; ///< allowed to skip the resolve check when downloading PAC script
+ boolean proxied = false; ///< true iff we're using a proxy
+
+ /** this is null if the current request is the first request on
+ * this HTTP connection; otherwise it is a Semaphore which will be
+ * released once the request ahead of us has recieved its response
+ */
+ Semaphore okToRecieve = null;
+
+ /**
+ * This method isn't synchronized; however, only one thread can be in the inner synchronized block at a time, and the rest of
+ * the method is protected by in-order one-at-a-time semaphore lock-steps
+ */
+ private InputStream makeRequest(String contentType, String content) throws IOException {
+
+ // Step 1: send the request and establish a semaphore to stop any requests that pipeline after us
+ Semaphore blockOn = null;
+ Semaphore releaseMe = null;
+ synchronized(this) {
+ try {
+ connect();
+ sendRequest(contentType, content);
+ } catch (IOException e) {
+ reset();
+ throw e;
+ }
+ blockOn = okToRecieve;
+ releaseMe = okToRecieve = new Semaphore();
+ }
+
+ // Step 2: wait for requests ahead of us to complete, then read the reply off the stream
+ boolean doRelease = true;
+ try {
+ if (blockOn != null) blockOn.block();
+
+ // previous call wrecked the socket connection, but we already sent our request, so we can't just retry --
+ // this could cause the server to receive the request twice, which could be bad (think of the case where the
+ // server call causes Amazon.com to ship you an item with one-click purchasing).
+ if (in == null)
+ throw new HTTPException("a previous pipelined call messed up the socket");
+
+ Hashtable h = in == null ? null : parseHeaders(in);
+ if (h == null) {
+ if (firstRequest) throw new HTTPException("server closed the socket with no response");
+ // sometimes the server chooses to close the stream between requests
+ reset();
+ releaseMe.release();
+ return makeRequest(contentType, content);
+ }
+
+ String reply = h.get("STATUSLINE").toString();
+
+ if (reply.startsWith("407") || reply.startsWith("401")) {
+
+ if (reply.startsWith("407")) doProxyAuth(h, content == null ? "GET" : "POST");
+ else doWebAuth(h, content == null ? "GET" : "POST");
+
+ if (h.get("HTTP").equals("1.0") && h.get("content-length") == null) {
+ if (Log.on) Log.info(this, "proxy returned an HTTP/1.0 reply with no content-length...");
+ reset();
+ } else {
+ int cl = h.get("content-length") == null ? -1 : Integer.parseInt(h.get("content-length").toString());
+ new HTTPInputStream(in, cl, releaseMe).close();
+ }
+ releaseMe.release();
+ return makeRequest(contentType, content);
+
+ } else if (reply.startsWith("2")) {
+ if (h.get("HTTP").equals("1.0") && h.get("content-length") == null)
+ throw new HTTPException("Ibex does not support HTTP/1.0 servers which fail to return the Content-Length header");
+ int cl = h.get("content-length") == null ? -1 : Integer.parseInt(h.get("content-length").toString());
+ InputStream ret = new HTTPInputStream(in, cl, releaseMe);
+ if ("gzip".equals(h.get("content-encoding"))) ret = new java.util.zip.GZIPInputStream(ret);
+ doRelease = false;
+ return ret;
+
+ } else {
+ throw new HTTPException("HTTP Error: " + reply);
+
+ }
+
+ } catch (IOException e) { reset(); throw e;
+ } finally { if (doRelease) releaseMe.release();
+ }
+ }
+
+
+ // Safeguarded DNS Resolver ///////////////////////////////////////////////////////////////////////////
+
+ /**
+ * resolves the hostname and returns it as a string in the form "x.y.z.w"
+ * @throws HTTPException if the host falls within a firewalled netblock
+ */
+ private void resolveAndCheckIfFirewalled(String host) throws HTTPException {
+
+ // cached
+ if (resolvedHosts.get(host) != null) return;
+
+ // if all scripts are trustworthy (local FS), continue
+ if (Main.originAddr == null) return;
+
+ // resolve using DNS
+ try {
+ InetAddress addr = InetAddress.getByName(host);
+ byte[] quadbyte = addr.getAddress();
+ if ((quadbyte[0] == 10 ||
+ (quadbyte[0] == 192 && quadbyte[1] == 168) ||
+ (quadbyte[0] == 172 && (quadbyte[1] & 0xF0) == 16)) && !addr.equals(Main.originAddr))
+ throw new HTTPException("security violation: " + host + " [" + addr.getHostAddress() +
+ "] is in a firewalled netblock");
+ return;
+ } catch (UnknownHostException uhe) { }
+
+ if (Platform.detectProxy() == null)
+ throw new HTTPException("could not resolve hostname \"" + host + "\" and no proxy configured");
+ }
+
+
+ // Methods to attempt socket creation /////////////////////////////////////////////////////////////////
+
+ private Socket getSocket(String host, int port, boolean ssl, boolean negotiate) throws IOException {
+ Socket ret = ssl ? new SSL(host, port, negotiate) : new Socket(java.net.InetAddress.getByName(host), port);
+ ret.setTcpNoDelay(true);
+ return ret;
+ }
+
+ /** Attempts a direct connection */
+ private Socket attemptDirect() {
+ try {
+ Log.info(this, "attempting to create unproxied socket to " +
+ host + ":" + port + (ssl ? " [ssl]" : ""));
+ return getSocket(host, port, ssl, true);
+ } catch (IOException e) {
+ if (Log.on) Log.info(this, "exception in attemptDirect(): " + e);
+ return null;
+ }
+ }
+
+ /** Attempts to use an HTTP proxy, employing the CONNECT method if HTTPS is requested */
+ private Socket attemptHttpProxy(String proxyHost, int proxyPort) {
+ try {
+ if (Log.verbose) Log.info(this, "attempting to create HTTP proxied socket using proxy " + proxyHost + ":" + proxyPort);
+ Socket sock = getSocket(proxyHost, proxyPort, ssl, false);
+
+ if (!ssl) {
+ if (!path.startsWith("http://")) path = "http://" + host + ":" + port + path;
+ return sock;
+ }
+
+ PrintWriter pw = new PrintWriter(new OutputStreamWriter(sock.getOutputStream()));
+ BufferedReader br = new BufferedReader(new InputStreamReader(sock.getInputStream()));
+ pw.print("CONNECT " + host + ":" + port + " HTTP/1.1\r\n\r\n");
+ pw.flush();
+ String s = br.readLine();
+ if (s.charAt(9) != '2') throw new HTTPException("proxy refused CONNECT method: \"" + s + "\"");
+ while (br.readLine().length() > 0) { };
+ ((SSL)sock).negotiate();
+ return sock;
+
+ } catch (IOException e) {
+ if (Log.on) Log.info(this, "exception in attemptHttpProxy(): " + e);
+ return null;
+ }
+ }
+
+ /**
+ * Implements SOCKSv4 with v4a DNS extension
+ * @see http://www.socks.nec.com/protocol/socks4.protocol
+ * @see http://www.socks.nec.com/protocol/socks4a.protocol
+ */
+ private Socket attemptSocksProxy(String proxyHost, int proxyPort) {
+
+ // even if host is already a "x.y.z.w" string, we use this to parse it into bytes
+ InetAddress addr = null;
+ try { addr = InetAddress.getByName(host); } catch (Exception e) { }
+
+ if (Log.verbose) Log.info(this, "attempting to create SOCKSv4" + (addr == null ? "" : "a") +
+ " proxied socket using proxy " + proxyHost + ":" + proxyPort);
+
+ try {
+ Socket sock = getSocket(proxyHost, proxyPort, ssl, false);
+
+ DataOutputStream dos = new DataOutputStream(sock.getOutputStream());
+ dos.writeByte(0x04); // SOCKSv4(a)
+ dos.writeByte(0x01); // CONNECT
+ dos.writeShort(port & 0xffff); // port
+ if (addr == null) dos.writeInt(0x00000001); // bogus IP
+ else dos.write(addr.getAddress()); // actual IP
+ dos.writeByte(0x00); // no userid
+ if (addr == null) {
+ PrintWriter pw = new PrintWriter(new OutputStreamWriter(dos));
+ pw.print(host);
+ pw.flush();
+ dos.writeByte(0x00); // hostname null terminator
+ }
+ dos.flush();
+
+ DataInputStream dis = new DataInputStream(sock.getInputStream());
+ dis.readByte(); // reply version
+ byte success = dis.readByte(); // success/fail
+ dis.skip(6); // ip/port
+
+ if ((int)(success & 0xff) == 90) {
+ if (ssl) ((SSL)sock).negotiate();
+ return sock;
+ }
+ if (Log.on) Log.info(this, "SOCKS server denied access, code " + (success & 0xff));
+ return null;
+
+ } catch (IOException e) {
+ if (Log.on) Log.info(this, "exception in attemptSocksProxy(): " + e);
+ return null;
+ }
+ }
+
+ /** executes the PAC script and dispatches a call to one of the other attempt methods based on the result */
+ private Socket attemptPAC(org.ibex.js.JS pacFunc) {
+ if (Log.verbose) Log.info(this, "evaluating PAC script");
+ String pac = null;
+ try {
+ Object obj = pacFunc.call(url, host, null, null, 2);
+ if (Log.verbose) Log.info(this, " PAC script returned \"" + obj + "\"");
+ pac = obj.toString();
+ } catch (Throwable e) {
+ if (Log.on) Log.info(this, "PAC script threw exception " + e);
+ return null;
+ }
+
+ StringTokenizer st = new StringTokenizer(pac, ";", false);
+ while (st.hasMoreTokens()) {
+ String token = st.nextToken().trim();
+ if (Log.verbose) Log.info(this, " trying \"" + token + "\"...");
+ try {
+ Socket ret = null;
+ if (token.startsWith("DIRECT"))
+ ret = attemptDirect();
+ else if (token.startsWith("PROXY"))
+ ret = attemptHttpProxy(token.substring(token.indexOf(' ') + 1, token.indexOf(':')),
+ Integer.parseInt(token.substring(token.indexOf(':') + 1)));
+ else if (token.startsWith("SOCKS"))
+ ret = attemptSocksProxy(token.substring(token.indexOf(' ') + 1, token.indexOf(':')),
+ Integer.parseInt(token.substring(token.indexOf(':') + 1)));
+ if (ret != null) return ret;
+ } catch (Throwable e) {
+ if (Log.on) Log.info(this, "attempt at \"" + token + "\" failed due to " + e + "; trying next token");
+ }
+ }
+ if (Log.on) Log.info(this, "all PAC results exhausted");
+ return null;
+ }
+
+
+ // Everything Else ////////////////////////////////////////////////////////////////////////////
+
+ private synchronized void connect() throws IOException {
+ if (originalUrl.equals("stdio:")) { in = new BufferedInputStream(System.in); return; }
+ if (sock != null) {
+ if (in == null) in = new BufferedInputStream(sock.getInputStream());
+ return;
+ }
+ // grab the userinfo; gcj doesn't have java.net.URL.getUserInfo()
+ String url = originalUrl;
+ userInfo = url.substring(url.indexOf("://") + 3);
+ userInfo = userInfo.indexOf('/') == -1 ? userInfo : userInfo.substring(0, userInfo.indexOf('/'));
+ if (userInfo.indexOf('@') != -1) {
+ userInfo = userInfo.substring(0, userInfo.indexOf('@'));
+ url = url.substring(0, url.indexOf("://") + 3) + url.substring(url.indexOf('@') + 1);
+ } else {
+ userInfo = null;
+ }
+
+ if (url.startsWith("https:")) {
+ ssl = true;
+ } else if (!url.startsWith("http:")) {
+ throw new IOException("HTTP only supports http/https urls");
+ }
+ if (url.indexOf("://") == -1) throw new IOException("URLs must contain a ://");
+ String temphost = url.substring(url.indexOf("://") + 3);
+ path = temphost.substring(temphost.indexOf('/'));
+ temphost = temphost.substring(0, temphost.indexOf('/'));
+ if (temphost.indexOf(':') != -1) {
+ port = Integer.parseInt(temphost.substring(temphost.indexOf(':')+1));
+ temphost = temphost.substring(0, temphost.indexOf(':'));
+ } else {
+ port = ssl ? 443 : 80;
+ }
+ if (!skipResolveCheck) resolveAndCheckIfFirewalled(temphost);
+ host = temphost;
+ if (Log.verbose) Log.info(this, "creating HTTP object for connection to " + host + ":" + port);
+
+ Proxy pi = Platform.detectProxy();
+ OUTER: do {
+ if (pi != null) {
+ for(int i=0; i<pi.excluded.length; i++) if (host.equals(pi.excluded[i])) break OUTER;
+ if (sock == null && pi.proxyAutoConfigFunction != null) sock = attemptPAC(pi.proxyAutoConfigFunction);
+ if (sock == null && ssl && pi.httpsProxyHost != null) sock = attemptHttpProxy(pi.httpsProxyHost,pi.httpsProxyPort);
+ if (sock == null && pi.httpProxyHost != null) sock = attemptHttpProxy(pi.httpProxyHost, pi.httpProxyPort);
+ if (sock == null && pi.socksProxyHost != null) sock = attemptSocksProxy(pi.socksProxyHost, pi.socksProxyPort);
+ }
+ } while (false);
+ proxied = sock != null;
+ if (sock == null) sock = attemptDirect();
+ if (sock == null) throw new HTTPException("unable to contact host " + host);
+ if (in == null) in = new BufferedInputStream(sock.getInputStream());
+ }
+
+ private void sendRequest(String contentType, String content) throws IOException {
+ PrintWriter pw = new PrintWriter(new OutputStreamWriter(originalUrl.equals("stdio:") ?
+ System.out : sock.getOutputStream()));
+ if (content != null) {
+ pw.print("POST " + path + " HTTP/1.0\r\n"); // FIXME chunked encoding
+ int contentLength = content.substring(0, 2).equals("\r\n") ?
+ content.length() - 2 :
+ (content.length() - content.indexOf("\r\n\r\n") - 4);
+ pw.print("Content-Length: " + contentLength + "\r\n");
+ if (contentType != null) pw.print("Content-Type: " + contentType + "\r\n");
+ } else {
+ pw.print("GET " + path + " HTTP/1.1\r\n");
+ }
+
+ pw.print("User-Agent: Ibex\r\n");
+ pw.print("Accept-encoding: gzip\r\n");
+ pw.print("Host: " + (host + (port == 80 ? "" : (":" + port))) + "\r\n");
+ if (proxied) pw.print("X-RequestOrigin: " + Main.originHost + "\r\n");
+
+ if (Proxy.Authorization.authorization != null) pw.print("Proxy-Authorization: "+Proxy.Authorization.authorization2+"\r\n");
+ if (authCache.get(originalUrl) != null) pw.print("Authorization: " + authCache.get(originalUrl) + "\r\n");
+
+ pw.print(content == null ? "\r\n" : content);
+ pw.print("\r\n");
+ pw.flush();
+ }
+
+ private void doWebAuth(Hashtable h0, String method) throws IOException {
+ if (userInfo == null) throw new HTTPException("web server demanded username/password, but none were supplied");
+ Hashtable h = parseAuthenticationChallenge(h0.get("www-authenticate").toString());
+
+ if (h.get("AUTHTYPE").equals("Basic")) {
+ if (authCache.get(originalUrl) != null) throw new HTTPException("username/password rejected");
+ authCache.put(originalUrl, "Basic " + new String(Base64.encode(userInfo.getBytes("UTF8"))));
+
+ } else if (h.get("AUTHTYPE").equals("Digest")) {
+ if (authCache.get(originalUrl) != null && !"true".equals(h.get("stale")))
+ throw new HTTPException("username/password rejected");
+ String path2 = path;
+ if (path2.startsWith("http://") || path2.startsWith("https://")) {
+ path2 = path2.substring(path2.indexOf("://") + 3);
+ path2 = path2.substring(path2.indexOf('/'));
+ }
+ String A1 = userInfo.substring(0, userInfo.indexOf(':')) + ":" + h.get("realm") + ":" +
+ userInfo.substring(userInfo.indexOf(':') + 1);
+ String A2 = method + ":" + path2;
+ authCache.put(originalUrl,
+ "Digest " +
+ "username=\"" + userInfo.substring(0, userInfo.indexOf(':')) + "\", " +
+ "realm=\"" + h.get("realm") + "\", " +
+ "nonce=\"" + h.get("nonce") + "\", " +
+ "uri=\"" + path2 + "\", " +
+ (h.get("opaque") == null ? "" : ("opaque=\"" + h.get("opaque") + "\", ")) +
+ "response=\"" + H(H(A1) + ":" + h.get("nonce") + ":" + H(A2)) + "\", " +
+ "algorithm=MD5"
+ );
+
+ } else {
+ throw new HTTPException("unknown authentication type: " + h.get("AUTHTYPE"));
+ }
+ }
+
+ private void doProxyAuth(Hashtable h0, String method) throws IOException {
+ if (Log.on) Log.info(this, "Proxy AuthChallenge: " + h0.get("proxy-authenticate"));
+ Hashtable h = parseAuthenticationChallenge(h0.get("proxy-authenticate").toString());
+ String style = h.get("AUTHTYPE").toString();
+ String realm = (String)h.get("realm");
+
+ if (style.equals("NTLM") && Proxy.Authorization.authorization2 == null) {
+ Log.info(this, "Proxy identified itself as NTLM, sending Type 1 packet");
+ Proxy.Authorization.authorization2 = "NTLM " + Base64.encode(Proxy.NTLM.type1);
+ return;
+ }
+
+ if (!realm.equals("Digest") || Proxy.Authorization.authorization2 == null || !"true".equals(h.get("stale")))
+ Proxy.Authorization.getPassword(realm, style, sock.getInetAddress().getHostAddress(),
+ Proxy.Authorization.authorization);
+
+ if (style.equals("Basic")) {
+ Proxy.Authorization.authorization2 =
+ "Basic " + new String(Base64.encode(Proxy.Authorization.authorization.getBytes("UTF8")));
+
+ } else if (style.equals("Digest")) {
+ String A1 = Proxy.Authorization.authorization.substring(0, userInfo.indexOf(':')) + ":" + h.get("realm") + ":" +
+ Proxy.Authorization.authorization.substring(Proxy.Authorization.authorization.indexOf(':') + 1);
+ String A2 = method + ":" + path;
+ Proxy.Authorization.authorization2 =
+ "Digest " +
+ "username=\"" + Proxy.Authorization.authorization.substring(0, Proxy.Authorization.authorization.indexOf(':')) +
+ "\", " +
+ "realm=\"" + h.get("realm") + "\", " +
+ "nonce=\"" + h.get("nonce") + "\", " +
+ "uri=\"" + path + "\", " +
+ (h.get("opaque") == null ? "" : ("opaque=\"" + h.get("opaque") + "\", ")) +
+ "response=\"" + H(H(A1) + ":" + h.get("nonce") + ":" + H(A2)) + "\", " +
+ "algorithm=MD5";
+
+ } else if (style.equals("NTLM")) {
+ Log.info(this, "Proxy identified itself as NTLM, got Type 2 packet");
+ byte[] type2 = Base64.decode(((String)h0.get("proxy-authenticate")).substring(5).trim());
+ for(int i=0; i<type2.length; i += 4) {
+ String log = "";
+ if (i<type2.length) log += Integer.toString(type2[i] & 0xff, 16) + " ";
+ if (i+1<type2.length) log += Integer.toString(type2[i+1] & 0xff, 16) + " ";
+ if (i+2<type2.length) log += Integer.toString(type2[i+2] & 0xff, 16) + " ";
+ if (i+3<type2.length) log += Integer.toString(type2[i+3] & 0xff, 16) + " ";
+ Log.info(this, log);
+ }
+ // FEATURE: need to keep the connection open between type1 and type3
+ // FEATURE: finish this
+ //byte[] type3 = Proxy.NTLM.getResponse(
+ //Proxy.Authorization.authorization2 = "NTLM " + Base64.encode(type3));
+ }
+ }
+
+
+ // HTTPInputStream ///////////////////////////////////////////////////////////////////////////////////
+
+ /** An input stream that represents a subset of a longer input stream. Supports HTTP chunking as well */
+ public class HTTPInputStream extends FilterInputStream implements KnownLength {
+
+ private int length = 0; ///< if chunking, numbytes left in this subset; else the remainder of the chunk
+ private Semaphore releaseMe = null; ///< this semaphore will be released when the stream is closed
+ boolean chunkedDone = false; ///< indicates that we have encountered the zero-length terminator chunk
+ boolean firstChunk = true; ///< if we're on the first chunk, we don't pre-read a CRLF
+ private int contentLength = 0; ///< the length of the entire content body; -1 if chunked
+
+ HTTPInputStream(InputStream in, int length, Semaphore releaseMe) throws IOException {
+ super(in);
+ this.releaseMe = releaseMe;
+ this.contentLength = length;
+ this.length = length == -1 ? 0 : length;
+ }
+
+ public int getLength() { return contentLength; }
+ public boolean markSupported() { return false; }
+ public int read(byte[] b) throws IOException { return read(b, 0, b.length); }
+ public long skip(long n) throws IOException { return read(null, -1, (int)n); }
+ public int available() throws IOException {
+ if (contentLength == -1) return java.lang.Math.min(super.available(), length);
+ return super.available();
+ }
+
+ public int read() throws IOException {
+ byte[] b = new byte[1];
+ int ret = read(b, 0, 1);
+ return ret == -1 ? -1 : b[0] & 0xff;
+ }
+
+ private void readChunk() throws IOException {
+ if (chunkedDone) return;
+ if (!firstChunk) super.skip(2); // CRLF
+ firstChunk = false;
+ String chunkLen = "";
+ while(true) {
+ int i = super.read();
+ if (i == -1) throw new HTTPException("encountered end of stream while reading chunk length");
+
+ // FEATURE: handle chunking extensions
+ if (i == '\r') {
+ super.read(); // LF
+ break;
+ } else {
+ chunkLen += (char)i;
+ }
+ }
+ length = Integer.parseInt(chunkLen.trim(), 16);
+ if (length == 0) chunkedDone = true;
+ }
+
+ public int read(byte[] b, int off, int len) throws IOException {
+ boolean good = false;
+ try {
+ if (length == 0 && contentLength == -1) {
+ readChunk();
+ if (chunkedDone) { good = true; return -1; }
+ } else {
+ if (length == 0) { good = true; return -1; }
+ }
+ if (len > length) len = length;
+ int ret = b == null ? (int)super.skip(len) : super.read(b, off, len);
+ if (ret >= 0) {
+ length -= ret;
+ good = true;
+ }
+ return ret;
+ } finally {
+ if (!good) reset();
+ }
+ }
+
+ public void close() throws IOException {
+ if (contentLength == -1) {
+ while(!chunkedDone) {
+ if (length != 0) skip(length);
+ readChunk();
+ }
+ skip(2);
+ } else {
+ if (length != 0) skip(length);
+ }
+ if (releaseMe != null) releaseMe.release();
+ }
+ }
+
+ void reset() {
+ firstRequest = true;
+ in = null;
+ sock = null;
+ }
+
+
+ // Misc Helpers ///////////////////////////////////////////////////////////////////////////////////
+
+ /** reads a set of HTTP headers off of the input stream, returning null if the stream is already at its end */
+ private Hashtable parseHeaders(InputStream in) throws IOException {
+ Hashtable ret = new Hashtable();
+
+ // we can't use a BufferedReader directly on the input stream, since it will buffer past the end of the headers
+ byte[] buf = new byte[4096];
+ int buflen = 0;
+ while(true) {
+ int read = in.read();
+ if (read == -1 && buflen == 0) return null;
+ if (read == -1) throw new HTTPException("stream closed while reading headers");
+ buf[buflen++] = (byte)read;
+ if (buflen >= 4 && buf[buflen - 4] == '\r' && buf[buflen - 3] == '\n' &&
+ buf[buflen - 2] == '\r' && buf[buflen - 1] == '\n')
+ break;
+ if (buflen >=2 && buf[buflen - 1] == '\n' && buf[buflen - 2] == '\n')
+ break; // nice for people using stdio
+ if (buflen == buf.length) {
+ byte[] newbuf = new byte[buf.length * 2];
+ System.arraycopy(buf, 0, newbuf, 0, buflen);
+ buf = newbuf;
+ }
+ }
+
+ BufferedReader br = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(buf, 0, buflen)));
+ String s = br.readLine();
+ if (!s.startsWith("HTTP/")) throw new HTTPException("Expected reply to start with \"HTTP/\", got: " + s);
+ ret.put("STATUSLINE", s.substring(s.indexOf(' ') + 1));
+ ret.put("HTTP", s.substring(5, s.indexOf(' ')));
+
+ while((s = br.readLine()) != null && s.length() > 0) {
+ String front = s.substring(0, s.indexOf(':')).toLowerCase();
+ String back = s.substring(s.indexOf(':') + 1).trim();
+ // ugly hack: we never replace a Digest-auth with a Basic-auth (proxy + www)
+ if (front.endsWith("-authenticate") && ret.get(front) != null && !back.equals("Digest")) continue;
+ ret.put(front, back);
+ }
+ return ret;
+ }
+
+ private Hashtable parseAuthenticationChallenge(String s) {
+ Hashtable ret = new Hashtable();
+
+ s = s.trim();
+ ret.put("AUTHTYPE", s.substring(0, s.indexOf(' ')));
+ s = s.substring(s.indexOf(' ')).trim();
+
+ while (s.length() > 0) {
+ String val = null;
+ String key = s.substring(0, s.indexOf('='));
+ s = s.substring(s.indexOf('=') + 1);
+ if (s.charAt(0) == '\"') {
+ s = s.substring(1);
+ val = s.substring(0, s.indexOf('\"'));
+ s = s.substring(s.indexOf('\"') + 1);
+ } else {
+ val = s.indexOf(',') == -1 ? s : s.substring(0, s.indexOf(','));
+ s = s.indexOf(',') == -1 ? "" : s.substring(s.indexOf(',') + 1);
+ }
+ if (s.length() > 0 && s.charAt(0) == ',') s = s.substring(1);
+ s = s.trim();
+ ret.put(key, val);
+ }
+ return ret;
+ }
+
+ private String H(String s) throws IOException {
+ byte[] b = s.getBytes("UTF8");
+ MD5 md5 = new MD5();
+ md5.update(b, 0, b.length);
+ byte[] out = new byte[md5.getDigestSize()];
+ md5.doFinal(out, 0);
+ String ret = "";
+ for(int i=0; i<out.length; i++) {
+ ret += "0123456789abcdef".charAt((out[i] & 0xf0) >> 4);
+ ret += "0123456789abcdef".charAt(out[i] & 0x0f);
+ }
+ return ret;
+ }
+
+
+ // Proxy ///////////////////////////////////////////////////////////
+
+ /** encapsulates most of the proxy logic; some is shared in HTTP.java */
+ public static class Proxy {
+
+ public String httpProxyHost = null; ///< the HTTP Proxy host to use
+ public int httpProxyPort = -1; ///< the HTTP Proxy port to use
+ public String httpsProxyHost = null; ///< seperate proxy for HTTPS
+ public int httpsProxyPort = -1;
+ public String socksProxyHost = null; ///< the SOCKS Proxy Host to use
+ public int socksProxyPort = -1; ///< the SOCKS Proxy Port to use
+ public String[] excluded = new String[] { }; ///< hosts to be excluded from proxy use; wildcards permitted
+ public JS proxyAutoConfigFunction = null; ///< the PAC script
+
+ public static Proxy detectProxyViaManual() {
+ Proxy ret = new Proxy();
+
+ ret.httpProxyHost = Platform.getEnv("http_proxy");
+ if (ret.httpProxyHost != null) {
+ if (ret.httpProxyHost.startsWith("http://")) ret.httpProxyHost = ret.httpProxyHost.substring(7);
+ if (ret.httpProxyHost.endsWith("/"))
+ ret.httpProxyHost = ret.httpProxyHost.substring(0, ret.httpProxyHost.length() - 1);
+ if (ret.httpProxyHost.indexOf(':') != -1) {
+ ret.httpProxyPort = Integer.parseInt(ret.httpProxyHost.substring(ret.httpProxyHost.indexOf(':') + 1));
+ ret.httpProxyHost = ret.httpProxyHost.substring(0, ret.httpProxyHost.indexOf(':'));
+ } else {
+ ret.httpProxyPort = 80;
+ }
+ }
+
+ ret.httpsProxyHost = Platform.getEnv("https_proxy");
+ if (ret.httpsProxyHost != null) {
+ if (ret.httpsProxyHost.startsWith("https://")) ret.httpsProxyHost = ret.httpsProxyHost.substring(7);
+ if (ret.httpsProxyHost.endsWith("/"))
+ ret.httpsProxyHost = ret.httpsProxyHost.substring(0, ret.httpsProxyHost.length() - 1);
+ if (ret.httpsProxyHost.indexOf(':') != -1) {
+ ret.httpsProxyPort = Integer.parseInt(ret.httpsProxyHost.substring(ret.httpsProxyHost.indexOf(':') + 1));
+ ret.httpsProxyHost = ret.httpsProxyHost.substring(0, ret.httpsProxyHost.indexOf(':'));
+ } else {
+ ret.httpsProxyPort = 80;
+ }
+ }
+
+ ret.socksProxyHost = Platform.getEnv("socks_proxy");
+ if (ret.socksProxyHost != null) {
+ if (ret.socksProxyHost.startsWith("socks://")) ret.socksProxyHost = ret.socksProxyHost.substring(7);
+ if (ret.socksProxyHost.endsWith("/"))
+ ret.socksProxyHost = ret.socksProxyHost.substring(0, ret.socksProxyHost.length() - 1);
+ if (ret.socksProxyHost.indexOf(':') != -1) {
+ ret.socksProxyPort = Integer.parseInt(ret.socksProxyHost.substring(ret.socksProxyHost.indexOf(':') + 1));
+ ret.socksProxyHost = ret.socksProxyHost.substring(0, ret.socksProxyHost.indexOf(':'));
+ } else {
+ ret.socksProxyPort = 80;
+ }
+ }
+
+ String noproxy = Platform.getEnv("no_proxy");
+ if (noproxy != null) {
+ StringTokenizer st = new StringTokenizer(noproxy, ",");
+ ret.excluded = new String[st.countTokens()];
+ for(int i=0; st.hasMoreTokens(); i++) ret.excluded[i] = st.nextToken();
+ }
+
+ if (ret.httpProxyHost == null && ret.socksProxyHost == null) return null;
+ return ret;
+ }
+
+ public static JSScope proxyAutoConfigRootScope = new ProxyAutoConfigRootScope();
+ public static JS getProxyAutoConfigFunction(String url) {
+ try {
+ BufferedReader br = new BufferedReader(new InputStreamReader(new HTTP(url, true).GET()));
+ String s = null;
+ String script = "";
+ while((s = br.readLine()) != null) script += s + "\n";
+ if (Log.on) Log.info(Proxy.class, "successfully retrieved WPAD PAC:");
+ if (Log.on) Log.info(Proxy.class, script);
+
+ // MS CARP hack
+ Vector carpHosts = new Vector();
+ for(int i=0; i<script.length(); i++)
+ if (script.regionMatches(i, "new Node(", 0, 9)) {
+ String host = script.substring(i + 10, script.indexOf('\"', i + 11));
+ if (Log.on) Log.info(Proxy.class, "Detected MS Proxy Server CARP Script, Host=" + host);
+ carpHosts.addElement(host);
+ }
+ if (carpHosts.size() > 0) {
+ script = "function FindProxyForURL(url, host) {\nreturn \"";
+ for(int i=0; i<carpHosts.size(); i++)
+ script += "PROXY " + carpHosts.elementAt(i) + "; ";
+ script += "\";\n}";
+ if (Log.on) Log.info(Proxy.class, "DeCARPed PAC script:");
+ if (Log.on) Log.info(Proxy.class, script);
+ }
+
+ JS scr = JS.fromReader("PAC script at " + url, 0, new StringReader(script));
+ JS.cloneWithNewParentScope(scr, proxyAutoConfigRootScope).call(null, null, null, null, 0);
+ return (JS)proxyAutoConfigRootScope.get("FindProxyForURL");
+ } catch (Exception e) {
+ if (Log.on) {
+ Log.info(Platform.class, "WPAD detection failed due to:");
+ if (e instanceof JSExn) {
+ try {
+ org.ibex.js.JSArray arr = new org.ibex.js.JSArray();
+ arr.addElement(((JSExn)e).getObject());
+ } catch (Exception e2) {
+ Log.info(Platform.class, e);
+ }
+ }
+ else Log.info(Platform.class, e);
+ }
+ return null;
+ }
+ }
+
+
+ // Authorization ///////////////////////////////////////////////////////////////////////////////////
+
+ public static class Authorization {
+
+ static public String authorization = null;
+ static public String authorization2 = null;
+ static public Semaphore waitingForUser = new Semaphore();
+
+ public static synchronized void getPassword(final String realm, final String style,
+ final String proxyIP, String oldAuth) throws IOException {
+
+ // this handles cases where multiple threads hit the proxy auth at the same time -- all but one will block on the
+ // synchronized keyword. If 'authorization' changed while the thread was blocked, it means that the user entered
+ // a password, so we should reattempt authorization.
+
+ if (authorization != oldAuth) return;
+ if (Log.on) Log.info(Authorization.class, "displaying proxy authorization dialog");
+ Scheduler.add(new Task() {
+ public void perform() throws IOException, JSExn {
+ Box b = new Box();
+ Template t = null;
+ // FIXME
+ //Template.buildTemplate("org/ibex/builtin/proxy_authorization.ibex", Stream.getInputStream((JS)Main.builtin.get("org/ibex/builtin/proxy_authorization.ibex")), new Ibex(null));
+ t.apply(b);
+ b.put("realm", realm);
+ b.put("proxyIP", proxyIP);
+ }
+ });
+
+ waitingForUser.block();
+ if (Log.on) Log.info(Authorization.class, "got proxy authorization info; re-attempting connection");
+ }
+ }
+
+
+ // ProxyAutoConfigRootJSScope ////////////////////////////////////////////////////////////////////
+
+ public static class ProxyAutoConfigRootScope extends JSScope.Global {
+
+ public ProxyAutoConfigRootScope() { super(); }
+
+ public Object get(Object name) throws JSExn {
+ //#switch(name)
+ case "isPlainHostName": return METHOD;
+ case "dnsDomainIs": return METHOD;
+ case "localHostOrDomainIs": return METHOD;
+ case "isResolvable": return METHOD;
+ case "isInNet": return METHOD;
+ case "dnsResolve": return METHOD;
+ case "myIpAddress": return METHOD;
+ case "dnsDomainLevels": return METHOD;
+ case "shExpMatch": return METHOD;
+ case "weekdayRange": return METHOD;
+ case "dateRange": return METHOD;
+ case "timeRange": return METHOD;
+ case "ProxyConfig": return ProxyConfig;
+ //#end
+ return super.get(name);
+ }
+
+ private static final JS proxyConfigBindings = new JS();
+ private static final JS ProxyConfig = new JS() {
+ public Object get(Object name) {
+ if (name.equals("bindings")) return proxyConfigBindings;
+ return null;
+ }
+ };
+
+ public Object callMethod(Object method, Object a0, Object a1, Object a2, Object[] rest, int nargs) throws JSExn {
+ //#switch(method)
+ case "isPlainHostName": return (a0.toString().indexOf('.') == -1) ? Boolean.TRUE : Boolean.FALSE;
+ case "dnsDomainIs": return (a0.toString().endsWith(a1.toString())) ? Boolean.TRUE : Boolean.FALSE;
+ case "localHostOrDomainIs":
+ return (a0.equals(a1) || (a0.toString().indexOf('.') == -1 && a1.toString().startsWith(a0.toString()))) ? T:F;
+ case "isResolvable": try {
+ return (InetAddress.getByName(a0.toString()) != null) ? Boolean.TRUE : Boolean.FALSE;
+ } catch (UnknownHostException e) { return F; }
+ case "isInNet":
+ if (nargs != 3) return Boolean.FALSE;
+ try {
+ byte[] host = InetAddress.getByName(a0.toString()).getAddress();
+ byte[] net = InetAddress.getByName(a1.toString()).getAddress();
+ byte[] mask = InetAddress.getByName(a2.toString()).getAddress();
+ return ((host[0] & mask[0]) == net[0] &&
+ (host[1] & mask[1]) == net[1] &&
+ (host[2] & mask[2]) == net[2] &&
+ (host[3] & mask[3]) == net[3]) ?
+ Boolean.TRUE : Boolean.FALSE;
+ } catch (Exception e) {
+ throw new JSExn("exception in isInNet(): " + e);
+ }
+ case "dnsResolve":
+ try {
+ return InetAddress.getByName(a0.toString()).getHostAddress();
+ } catch (UnknownHostException e) {
+ return null;
+ }
+ case "myIpAddress":
+ try {
+ return InetAddress.getLocalHost().getHostAddress();
+ } catch (UnknownHostException e) {
+ if (Log.on) Log.info(this, "strange... host does not know its own address");
+ return null;
+ }
+ case "dnsDomainLevels":
+ String s = a0.toString();
+ int i = 0;
+ while((i = s.indexOf('.', i)) != -1) i++;
+ return new Integer(i);
+ case "shExpMatch":
+ StringTokenizer st = new StringTokenizer(a1.toString(), "*", false);
+ String[] arr = new String[st.countTokens()];
+ String s = a0.toString();
+ for (int i=0; st.hasMoreTokens(); i++) arr[i] = st.nextToken();
+ return match(arr, s, 0) ? Boolean.TRUE : Boolean.FALSE;
+ case "weekdayRange":
+ TimeZone tz = (nargs < 3 || a2 == null || !a2.equals("GMT")) ?
+ TimeZone.getTimeZone("UTC") : TimeZone.getDefault();
+ Calendar c = new GregorianCalendar();
+ c.setTimeZone(tz);
+ c.setTime(new java.util.Date());
+ java.util.Date d = c.getTime();
+ int day = d.getDay();
+ String d1s = a0.toString().toUpperCase();
+ int d1 = 0, d2 = 0;
+ for(int i=0; i<days.length; i++) if (days[i].equals(d1s)) d1 = i;
+
+ if (nargs == 1)
+ return d1 == day ? Boolean.TRUE : Boolean.FALSE;
+
+ String d2s = a1.toString().toUpperCase();
+ for(int i=0; i<days.length; i++) if (days[i].equals(d2s)) d2 = i;
+
+ return ((d1 <= d2 && day >= d1 && day <= d2) || (d1 > d2 && (day >= d1 || day <= d2))) ? T : F;
+
+ case "dateRange": throw new JSExn("Ibex does not support dateRange() in PAC scripts");
+ case "timeRange": throw new JSExn("Ibex does not support timeRange() in PAC scripts");
+ //#end
+ return super.callMethod(method, a0, a1, a2, rest, nargs);
+ }
+ private static boolean match(String[] arr, String s, int index) {
+ if (index >= arr.length) return true;
+ for(int i=0; i<s.length(); i++) {
+ String s2 = s.substring(i);
+ if (s2.startsWith(arr[index]) && match(arr, s2.substring(arr[index].length()), index + 1)) return true;
+ }
+ return false;
+ }
+ public static String[] days = { "SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT" };
+ }
+
+
+ /**
+ * An implementation of Microsoft's proprietary NTLM authentication protocol. This code was derived from Eric
+ * Glass's work, and is copyright as follows:
+ *
+ * Copyright (c) 2003 Eric Glass (eglass1 at comcast.net).
+ *
+ * Permission to use, copy, modify, and distribute this document for any purpose and without any fee is hereby
+ * granted, provided that the above copyright notice and this list of conditions appear in all copies.
+ * The most current version of this document may be obtained from http://davenport.sourceforge.net/ntlm.html .
+ */
+ public static class NTLM {
+
+ public static final byte[] type1 = new byte[] { 0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00 };
+
+ /**
+ * Calculates the NTLM Response for the given challenge, using the
+ * specified password.
+ *
+ * @param password The user's password.
+ * @param challenge The Type 2 challenge from the server.
+ *
+ * @return The NTLM Response.
+ */
+ public static byte[] getNTLMResponse(String password, byte[] challenge)
+ throws UnsupportedEncodingException {
+ byte[] ntlmHash = ntlmHash(password);
+ return lmResponse(ntlmHash, challenge);
+ }
+
+ /**
+ * Calculates the LM Response for the given challenge, using the specified
+ * password.
+ *
+ * @param password The user's password.
+ * @param challenge The Type 2 challenge from the server.
+ *
+ * @return The LM Response.
+ */
+ public static byte[] getLMResponse(String password, byte[] challenge)
+ {
+ byte[] lmHash = lmHash(password);
+ return lmResponse(lmHash, challenge);
+ }
+
+ /**
+ * Calculates the NTLMv2 Response for the given challenge, using the
+ * specified authentication target, username, password, target information
+ * block, and client challenge.
+ *
+ * @param target The authentication target (i.e., domain).
+ * @param user The username.
+ * @param password The user's password.
+ * @param targetInformation The target information block from the Type 2
+ * message.
+ * @param challenge The Type 2 challenge from the server.
+ * @param clientChallenge The random 8-byte client challenge.
+ *
+ * @return The NTLMv2 Response.
+ */
+ public static byte[] getNTLMv2Response(String target, String user,
+ String password, byte[] targetInformation, byte[] challenge,
+ byte[] clientChallenge) throws UnsupportedEncodingException {
+ byte[] ntlmv2Hash = ntlmv2Hash(target, user, password);
+ byte[] blob = createBlob(targetInformation, clientChallenge);
+ return lmv2Response(ntlmv2Hash, blob, challenge);
+ }
+
+ /**
+ * Calculates the LMv2 Response for the given challenge, using the
+ * specified authentication target, username, password, and client
+ * challenge.
+ *
+ * @param target The authentication target (i.e., domain).
+ * @param user The username.
+ * @param password The user's password.
+ * @param challenge The Type 2 challenge from the server.
+ * @param clientChallenge The random 8-byte client challenge.
+ *
+ * @return The LMv2 Response.
+ */
+ public static byte[] getLMv2Response(String target, String user,
+ String password, byte[] challenge, byte[] clientChallenge)
+ throws UnsupportedEncodingException {
+ byte[] ntlmv2Hash = ntlmv2Hash(target, user, password);
+ return lmv2Response(ntlmv2Hash, clientChallenge, challenge);
+ }
+
+ /**
+ * Calculates the NTLM2 Session Response for the given challenge, using the
+ * specified password and client challenge.
+ *
+ * @param password The user's password.
+ * @param challenge The Type 2 challenge from the server.
+ * @param clientChallenge The random 8-byte client challenge.
+ *
+ * @return The NTLM2 Session Response. This is placed in the NTLM
+ * response field of the Type 3 message; the LM response field contains
+ * the client challenge, null-padded to 24 bytes.
+ */
+ public static byte[] getNTLM2SessionResponse(String password,
+ byte[] challenge, byte[] clientChallenge) throws UnsupportedEncodingException {
+ byte[] ntlmHash = ntlmHash(password);
+ MD5 md5 = new MD5();
+ md5.update(challenge, 0, challenge.length);
+ md5.update(clientChallenge, 0, clientChallenge.length);
+ byte[] sessionHash = new byte[8];
+ byte[] md5_out = new byte[md5.getDigestSize()];
+ md5.doFinal(md5_out, 0);
+ System.arraycopy(md5_out, 0, sessionHash, 0, 8);
+ return lmResponse(ntlmHash, sessionHash);
+ }
+
+ /**
+ * Creates the LM Hash of the user's password.
+ *
+ * @param password The password.
+ *
+ * @return The LM Hash of the given password, used in the calculation
+ * of the LM Response.
+ */
+ private static byte[] lmHash(String password) {
+ /*
+ byte[] oemPassword = password.toUpperCase().getBytes("UTF8");
+ int length = java.lang.Math.min(oemPassword.length, 14);
+ byte[] keyBytes = new byte[14];
+ System.arraycopy(oemPassword, 0, keyBytes, 0, length);
+ Key lowKey = createDESKey(keyBytes, 0);
+ Key highKey = createDESKey(keyBytes, 7);
+ byte[] magicConstant = "KGS!@#$%".getBytes("UTF8");
+ Cipher des = Cipher.getInstance("DES/ECB/NoPadding");
+ des.init(Cipher.ENCRYPT_MODE, lowKey);
+ byte[] lowHash = des.doFinal(magicConstant);
+ des.init(Cipher.ENCRYPT_MODE, highKey);
+ byte[] highHash = des.doFinal(magicConstant);
+ byte[] lmHash = new byte[16];
+ System.arraycopy(lowHash, 0, lmHash, 0, 8);
+ System.arraycopy(highHash, 0, lmHash, 8, 8);
+ return lmHash;
+ */
+ return null;
+ }
+
+ /**
+ * Creates the NTLM Hash of the user's password.
+ *
+ * @param password The password.
+ *
+ * @return The NTLM Hash of the given password, used in the calculation
+ * of the NTLM Response and the NTLMv2 and LMv2 Hashes.
+ */
+ private static byte[] ntlmHash(String password) throws UnsupportedEncodingException {
+ // FIXME
+ /*
+ byte[] unicodePassword = password.getBytes("UnicodeLittleUnmarked");
+ MD4 md4 = new MD4();
+ md4.update(unicodePassword, 0, unicodePassword.length);
+ byte[] ret = new byte[md4.getDigestSize()];
+ return ret;
+ */
+ return null;
+ }
+
+ /**
+ * Creates the NTLMv2 Hash of the user's password.
+ *
+ * @param target The authentication target (i.e., domain).
+ * @param user The username.
+ * @param password The password.
+ *
+ * @return The NTLMv2 Hash, used in the calculation of the NTLMv2
+ * and LMv2 Responses.
+ */
+ private static byte[] ntlmv2Hash(String target, String user,
+ String password) throws UnsupportedEncodingException {
+ byte[] ntlmHash = ntlmHash(password);
+ String identity = user.toUpperCase() + target.toUpperCase();
+ return hmacMD5(identity.getBytes("UnicodeLittleUnmarked"), ntlmHash);
+ }
+
+ /**
+ * Creates the LM Response from the given hash and Type 2 challenge.
+ *
+ * @param hash The LM or NTLM Hash.
+ * @param challenge The server challenge from the Type 2 message.
+ *
+ * @return The response (either LM or NTLM, depending on the provided
+ * hash).
+ */
+ private static byte[] lmResponse(byte[] hash, byte[] challenge)
+ {
+ /*
+ byte[] keyBytes = new byte[21];
+ System.arraycopy(hash, 0, keyBytes, 0, 16);
+ Key lowKey = createDESKey(keyBytes, 0);
+ Key middleKey = createDESKey(keyBytes, 7);
+ Key highKey = createDESKey(keyBytes, 14);
+ Cipher des = Cipher.getInstance("DES/ECB/NoPadding");
+ des.init(Cipher.ENCRYPT_MODE, lowKey);
+ byte[] lowResponse = des.doFinal(challenge);
+ des.init(Cipher.ENCRYPT_MODE, middleKey);
+ byte[] middleResponse = des.doFinal(challenge);
+ des.init(Cipher.ENCRYPT_MODE, highKey);
+ byte[] highResponse = des.doFinal(challenge);
+ byte[] lmResponse = new byte[24];
+ System.arraycopy(lowResponse, 0, lmResponse, 0, 8);
+ System.arraycopy(middleResponse, 0, lmResponse, 8, 8);
+ System.arraycopy(highResponse, 0, lmResponse, 16, 8);
+ return lmResponse;
+ */
+ return null;
+ }
+
+ /**
+ * Creates the LMv2 Response from the given hash, client data, and
+ * Type 2 challenge.
+ *
+ * @param hash The NTLMv2 Hash.
+ * @param clientData The client data (blob or client challenge).
+ * @param challenge The server challenge from the Type 2 message.
+ *
+ * @return The response (either NTLMv2 or LMv2, depending on the
+ * client data).
+ */
+ private static byte[] lmv2Response(byte[] hash, byte[] clientData,
+ byte[] challenge) {
+ byte[] data = new byte[challenge.length + clientData.length];
+ System.arraycopy(challenge, 0, data, 0, challenge.length);
+ System.arraycopy(clientData, 0, data, challenge.length,
+ clientData.length);
+ byte[] mac = hmacMD5(data, hash);
+ byte[] lmv2Response = new byte[mac.length + clientData.length];
+ System.arraycopy(mac, 0, lmv2Response, 0, mac.length);
+ System.arraycopy(clientData, 0, lmv2Response, mac.length,
+ clientData.length);
+ return lmv2Response;
+ }
+
+ /**
+ * Creates the NTLMv2 blob from the given target information block and
+ * client challenge.
+ *
+ * @param targetInformation The target information block from the Type 2
+ * message.
+ * @param clientChallenge The random 8-byte client challenge.
+ *
+ * @return The blob, used in the calculation of the NTLMv2 Response.
+ */
+ private static byte[] createBlob(byte[] targetInformation,
+ byte[] clientChallenge) {
+ byte[] blobSignature = new byte[] {
+ (byte) 0x01, (byte) 0x01, (byte) 0x00, (byte) 0x00
+ };
+ byte[] reserved = new byte[] {
+ (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00
+ };
+ byte[] unknown1 = new byte[] {
+ (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00
+ };
+ byte[] unknown2 = new byte[] {
+ (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00
+ };
+ long time = System.currentTimeMillis();
+ time += 11644473600000l; // milliseconds from January 1, 1601 -> epoch.
+ time *= 10000; // tenths of a microsecond.
+ // convert to little-endian byte array.
+ byte[] timestamp = new byte[8];
+ for (int i = 0; i < 8; i++) {
+ timestamp[i] = (byte) time;
+ time >>>= 8;
+ }
+ byte[] blob = new byte[blobSignature.length + reserved.length +
+ timestamp.length + clientChallenge.length +
+ unknown1.length + targetInformation.length +
+ unknown2.length];
+ int offset = 0;
+ System.arraycopy(blobSignature, 0, blob, offset, blobSignature.length);
+ offset += blobSignature.length;
+ System.arraycopy(reserved, 0, blob, offset, reserved.length);
+ offset += reserved.length;
+ System.arraycopy(timestamp, 0, blob, offset, timestamp.length);
+ offset += timestamp.length;
+ System.arraycopy(clientChallenge, 0, blob, offset,
+ clientChallenge.length);
+ offset += clientChallenge.length;
+ System.arraycopy(unknown1, 0, blob, offset, unknown1.length);
+ offset += unknown1.length;
+ System.arraycopy(targetInformation, 0, blob, offset,
+ targetInformation.length);
+ offset += targetInformation.length;
+ System.arraycopy(unknown2, 0, blob, offset, unknown2.length);
+ return blob;
+ }
+
+ /**
+ * Calculates the HMAC-MD5 hash of the given data using the specified
+ * hashing key.
+ *
+ * @param data The data for which the hash will be calculated.
+ * @param key The hashing key.
+ *
+ * @return The HMAC-MD5 hash of the given data.
+ */
+ private static byte[] hmacMD5(byte[] data, byte[] key) {
+ byte[] ipad = new byte[64];
+ byte[] opad = new byte[64];
+ for (int i = 0; i < 64; i++) {
+ ipad[i] = (byte) 0x36;
+ opad[i] = (byte) 0x5c;
+ }
+ for (int i = key.length - 1; i >= 0; i--) {
+ ipad[i] ^= key[i];
+ opad[i] ^= key[i];
+ }
+ byte[] content = new byte[data.length + 64];
+ System.arraycopy(ipad, 0, content, 0, 64);
+ System.arraycopy(data, 0, content, 64, data.length);
+ MD5 md5 = new MD5();
+ md5.update(content, 0, content.length);
+ data = new byte[md5.getDigestSize()];
+ md5.doFinal(data, 0);
+ content = new byte[data.length + 64];
+ System.arraycopy(opad, 0, content, 0, 64);
+ System.arraycopy(data, 0, content, 64, data.length);
+ md5 = new MD5();
+ md5.update(content, 0, content.length);
+ byte[] ret = new byte[md5.getDigestSize()];
+ md5.doFinal(ret, 0);
+ return ret;
+ }
+
+ /**
+ * Creates a DES encryption key from the given key material.
+ *
+ * @param bytes A byte array containing the DES key material.
+ * @param offset The offset in the given byte array at which
+ * the 7-byte key material starts.
+ *
+ * @return A DES encryption key created from the key material
+ * starting at the specified offset in the given byte array.
+ */
+ /*
+ private static Key createDESKey(byte[] bytes, int offset) {
+ byte[] keyBytes = new byte[7];
+ System.arraycopy(bytes, offset, keyBytes, 0, 7);
+ byte[] material = new byte[8];
+ material[0] = keyBytes[0];
+ material[1] = (byte) (keyBytes[0] << 7 | (keyBytes[1] & 0xff) >>> 1);
+ material[2] = (byte) (keyBytes[1] << 6 | (keyBytes[2] & 0xff) >>> 2);
+ material[3] = (byte) (keyBytes[2] << 5 | (keyBytes[3] & 0xff) >>> 3);
+ material[4] = (byte) (keyBytes[3] << 4 | (keyBytes[4] & 0xff) >>> 4);
+ material[5] = (byte) (keyBytes[4] << 3 | (keyBytes[5] & 0xff) >>> 5);
+ material[6] = (byte) (keyBytes[5] << 2 | (keyBytes[6] & 0xff) >>> 6);
+ material[7] = (byte) (keyBytes[6] << 1);
+ oddParity(material);
+ return new SecretKeySpec(material, "DES");
+ }
+ */
+
+ /**
+ * Applies odd parity to the given byte array.
+ *
+ * @param bytes The data whose parity bits are to be adjusted for
+ * odd parity.
+ */
+ private static void oddParity(byte[] bytes) {
+ for (int i = 0; i < bytes.length; i++) {
+ byte b = bytes[i];
+ boolean needsParity = (((b >>> 7) ^ (b >>> 6) ^ (b >>> 5) ^
+ (b >>> 4) ^ (b >>> 3) ^ (b >>> 2) ^
+ (b >>> 1)) & 0x01) == 0;
+ if (needsParity) {
+ bytes[i] |= (byte) 0x01;
+ } else {
+ bytes[i] &= (byte) 0xfe;
+ }
+ }
+ }
+
+ }
+ }
+}
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.net;
+
+import java.io.*;
+import java.util.*;
+import org.ibex.js.*;
+import org.ibex.util.*;
+import org.ibex.crypto.*;
+
+/**
+ * A partial RPC-style SOAP 1.1 client. Implemented from the SOAP 1.1
+ * Spec and Dave Winer's "SOAP for Busy Developers". This class
+ * extends XMLRPC in order to share some networking logic.
+ *
+ * Currently unsupported features/hacks:
+ * <ul><li> Multi-ref data and circular references
+ * <li> 'Document Style'
+ * <li> WSDL support
+ * </ul>
+ */
+public class SOAP extends XMLRPC {
+
+ /** the desired content of the SOAPAction header */
+ String action = null;
+
+ /** the namespace to use */
+ String nameSpace = null;
+
+ /** When you get a property from an SOAP, it just returns another SOAP with the property name tacked onto methodname. */
+ public Object get(Object name) {
+ return new SOAP(url, (method.equals("") ? "" : method + ".") + name.toString(), this, action, nameSpace); }
+
+
+ // Methods to Recieve and parse SOAP Responses ////////////////////////////////////////////////////
+
+ public void startElement(String name, String[] keys, Object[] vals, int line, int col) {
+
+ content.reset();
+ if (name.equals("SOAP-ENV:Envelope")) return;
+ if (name.equals("SOAP-ENV:Body")) return;
+ if (name.equals("SOAP-ENV:Fault")) fault = true;
+
+ // add a generic struct; we'll change this if our type is different
+ objects.addElement(new JS());
+
+ for(int i=0; i<keys.length; i++) {
+ String key = keys[i];
+ String value = vals[i].toString();
+ if (key.endsWith("ype")) {
+ if (value.endsWith("boolean")) {
+ objects.removeElementAt(objects.size() - 1);
+ objects.addElement(Boolean.FALSE);
+ } else if (value.endsWith("int")) {
+ objects.removeElementAt(objects.size() - 1);
+ objects.addElement(new Integer(0));
+ } else if (value.endsWith("double")) {
+ objects.removeElementAt(objects.size() - 1);
+ objects.addElement(new Double(0.0));
+ } else if (value.endsWith("string")) {
+ objects.removeElementAt(objects.size() - 1);
+ objects.addElement("");
+ } else if (value.endsWith("base64")) {
+ objects.removeElementAt(objects.size() - 1);
+ objects.addElement(new byte[] { });
+ } else if (value.endsWith("null")) {
+ objects.removeElementAt(objects.size() - 1);
+ objects.addElement(null);
+ } else if (value.endsWith("arrayType") || value.endsWith("JSArray") || key.endsWith("arrayType")) {
+ objects.removeElementAt(objects.size() - 1);
+ objects.addElement(new JSArray());
+ }
+ }
+ }
+ }
+
+ public void endElement(String name, int line, int col) {
+
+ if (name.equals("SOAP-ENV:Envelope")) return;
+ if (name.equals("SOAP-ENV:Body")) return;
+
+ if (content.size() > 0 && content.toString().trim().length() > 0) {
+
+ // remove ourselves
+ Object me = objects.elementAt(objects.size() - 1);
+
+ if (fault || me instanceof String) {
+ objects.removeElementAt(objects.size() - 1);
+ objects.addElement(new String(content.getBuf(), 0, content.size()).intern());
+ content.reset();
+
+ } else if (me instanceof byte[]) {
+ objects.removeElementAt(objects.size() - 1);
+ objects.addElement(new Stream.ByteArray(Base64.decode(new String(content.getBuf(), 0, content.size())), null));
+ content.reset();
+
+ } else if (me instanceof Integer) {
+ objects.removeElementAt(objects.size() - 1);
+ objects.addElement(new Integer(new String(content.getBuf(), 0, content.size())));
+ content.reset();
+
+ } else if (me instanceof Boolean) {
+ objects.removeElementAt(objects.size() - 1);
+ String s = new String(content.getBuf(), 0, content.size()).trim();
+ if (s.equals("1") || s.equals("true")) objects.addElement(Boolean.TRUE);
+ else objects.addElement(Boolean.FALSE);
+ content.reset();
+
+ } else if (me instanceof Double) {
+ objects.removeElementAt(objects.size() - 1);
+ objects.addElement(new Double(new String(content.getBuf(), 0, content.size())));
+ content.reset();
+
+ } else {
+ // okay, we got PCDATA for what is supposedly a
+ // struct... somebody's not adding their type info...
+ String s = new String(content.getBuf(), 0, content.size()).trim();
+ boolean hasdot = false;
+ for(int i=0; i<s.length(); i++) {
+ if (s.charAt(i) == '.') hasdot = true;
+ if (!Character.isDigit(s.charAt(i))) {
+ objects.removeElementAt(objects.size() - 1);
+ objects.addElement(s);
+ return;
+ }
+ }
+ if (hasdot) {
+ objects.removeElementAt(objects.size() - 1);
+ objects.addElement(new Double(s));
+ } else {
+ objects.removeElementAt(objects.size() - 1);
+ objects.addElement(new Integer(s));
+ }
+ content.reset();
+ }
+
+ }
+
+ // remove ourselves
+ Object me = objects.elementAt(objects.size() - 1);
+
+ // find our parent
+ Object parent = objects.size() > 1 ? objects.elementAt(objects.size() - 2) : null;
+
+ // we want to fold stuff back into the fault object
+ if (objects.size() < 2) return;
+
+ // our parent "should" be an aggregate type -- add ourselves to it.
+ if (parent != null && parent instanceof JSArray) {
+ objects.removeElementAt(objects.size() - 1);
+ ((JSArray)parent).addElement(me);
+
+ } else if (parent != null && parent instanceof JS) {
+ objects.removeElementAt(objects.size() - 1);
+ try {
+ ((JS)parent).put(name, me);
+ } catch (JSExn e) {
+ throw new Error("this should never happen");
+ }
+
+ }
+
+ }
+
+ /** Appends the SOAP representation of <code>o</code> to <code>sb</code> */
+ void appendObject(String name, Object o, StringBuffer sb) throws JSExn {
+ if (o instanceof Number) {
+ if ((double)((Number)o).intValue() == ((Number)o).doubleValue()) {
+ sb.append(" <" + name + " xsi:type=\"xsd:int\">");
+ sb.append(((Number)o).intValue());
+ sb.append("</" + name + ">\r\n");
+ } else {
+ sb.append(" <" + name + " xsi:type=\"xsd:double\">");
+ sb.append(o);
+ sb.append("</" + name + ">\r\n");
+ }
+
+ } else if (o instanceof Boolean) {
+ sb.append(" <" + name + " xsi:type=\"xsd:boolean\">");
+ sb.append(((Boolean)o).booleanValue() ? "true" : "false");
+ sb.append("</" + name + ">\r\n");
+
+ } else if (o instanceof Stream) {
+ try {
+ sb.append(" <" + name + " xsi:type=\"SOAP-ENC:base64\">\r\n");
+ InputStream is = ((Stream)o).getInputStream();
+ byte[] buf = new byte[54];
+ while(true) {
+ int numread = is.read(buf, 0, 54);
+ if (numread == -1) break;
+ byte[] writebuf = buf;
+ if (numread < buf.length) {
+ writebuf = new byte[numread];
+ System.arraycopy(buf, 0, writebuf, 0, numread);
+ }
+ sb.append(" ");
+ sb.append(new String(Base64.encode(writebuf)));
+ sb.append("\r\n");
+ }
+ sb.append(((Boolean)o).booleanValue() ? "1" : "0");
+ sb.append("</" + name + ">\r\n");
+ } catch (IOException e) {
+ if (Log.on) Log.info(this, "caught IOException while attempting to send a ByteStream via SOAP");
+ if (Log.on) Log.info(this, e);
+ throw new JSExn("caught IOException while attempting to send a ByteStream via SOAP");
+ }
+
+ } else if (o instanceof String) {
+ sb.append(" <" + name + " xsi:type=\"xsd:string\">");
+ String s = (String)o;
+ if (s.indexOf('<') == -1 && s.indexOf('&') == -1) {
+ sb.append(s);
+ } else {
+ char[] cbuf = s.toCharArray();
+ while(true) {
+ int oldi = 0, i=0;
+ while(i < cbuf.length && cbuf[i] != '<' && cbuf[i] != '&') i++;
+ sb.append(cbuf, oldi, i);
+ if (i == cbuf.length) break;
+ if (cbuf[i] == '<') sb.append("<");
+ else if (cbuf[i] == '&') sb.append("&");
+ i = oldi = i + 1;
+ }
+ }
+ sb.append("</" + name + ">\r\n");
+
+ } else if (o instanceof JSArray) {
+ JSArray a = (JSArray)o;
+ sb.append(" <" + name + " SOAP-ENC:arrayType=\"xsd:ur-type[" + a.length() + "]\">");
+ for(int i=0; i<a.length(); i++) appendObject("item", a.elementAt(i), sb);
+ sb.append("</" + name + ">\r\n");
+
+ } else if (o instanceof JS) {
+ JS j = (JS)o;
+ sb.append(" <" + name + ">");
+ Enumeration e = j.keys();
+ while(e.hasMoreElements()) {
+ Object key = e.nextElement();
+ appendObject((String)key, j.get(key), sb);
+ }
+ sb.append("</" + name + ">\r\n");
+
+ }
+ }
+
+ protected String buildRequest(JSArray args) throws JSExn, IOException {
+ // build up the request
+ StringBuffer content = new StringBuffer();
+ content.append("SOAPAction: " + action + "\r\n\r\n");
+ content.append("<?xml version=\"1.0\"?>\r\n");
+ content.append("<SOAP-ENV:Envelope SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"\r\n");
+ content.append(" xmlns:SOAP-ENC=\"http://schemas.xmlsoap.org/soap/encoding/\"\r\n");
+ content.append(" xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\"\r\n");
+ content.append(" xmlns:xsd=\"http://www.w3.org/1999/XMLSchema\"\r\n");
+ content.append(" xmlns:xsi=\"http://www.w3.org/1999/XMLSchema-instance\">\r\n");
+ content.append("<SOAP-ENV:Body>\r\n");
+ content.append(" <");
+ content.append(method);
+ content.append(nameSpace != null ? " xmlns=\"" + nameSpace + "\"" : "");
+ content.append(">\r\n");
+ if (args.length() > 0) {
+ Enumeration e = ((JS)args.elementAt(0)).keys();
+ while(e.hasMoreElements()) {
+ Object key = e.nextElement();
+ appendObject((String)key, ((JS)args.elementAt(0)).get(key), content);
+ }
+ }
+ content.append(" </" + method + "></SOAP-ENV:Body></SOAP-ENV:Envelope>\r\n");
+ return content.toString();
+ }
+
+ public SOAP(String url, String methodname, String action, String nameSpace) {
+ super(url, methodname);
+ this.action = action;
+ this.nameSpace = nameSpace;
+ }
+ public SOAP(String url, String methodname, SOAP httpSource, String action, String nameSpace) {
+ super(url, methodname, httpSource);
+ this.action = action;
+ this.nameSpace = nameSpace;
+ }
+
+}
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.net;
+
+import java.io.*;
+import java.util.*;
+import org.ibex.js.*;
+import org.ibex.util.*;
+import org.ibex.crypto.*;
+
+/**
+ * An XML-RPC client implemented as a JavaScript Host Object. See the
+ * Ibex spec for information on its behavior.
+ *
+ * NOTE: this client is EXTREMELY lenient in the responses it will
+ * accept; there are many, many invalid responses that it will
+ * successfully parse and return. Do NOT use this to determine the
+ * validity of your server.
+ *
+ * This client conforms to <a href="http://www.xmlrpc.com/spec">The
+ * XML-RPC Spec</a>, subject to these limitations:
+ * <ol>
+ * <li> XMLRPC cannot invoke methods that require a <base64/> argument
+ * <li> if a return value contains a <base64/>, it will be returned as a string
+ * <li> The decision to pass a number as <i4/> or <double/> is based
+ * entirely on whether or not the argument is fractional. Thus, it
+ * is impossible to pass a non-fractional number to an xmlrpc
+ * method that insists on being called with a <double/> element. We
+ * hope that most xml-rpc servers will be able to automatically
+ * convert.
+ * </ol>
+ */
+public class XMLRPC extends JS {
+
+ public XMLRPC(String url, String method) {
+ this.http = url.startsWith("stdio:") ? HTTP.stdio : new HTTP(url);
+ this.url = url;
+ this.method = method;
+ }
+ public XMLRPC(String url, String method, XMLRPC httpSource) {
+ this.http = httpSource.http; this.url = url; this.method = method; }
+ public Object get(Object name) {
+ return new XMLRPC(url, (method.equals("") ? "" : method + ".") + name.toString(), this); }
+
+
+ /** this holds character content as we read it in -- since there is only one per instance, we don't support mixed content */
+ protected AccessibleCharArrayWriter content = new AccessibleCharArrayWriter(100);
+ protected String url = null; ///< the url to connect to
+ protected String method = null; ///< the method name to invoke on the remove server
+ protected HTTP http = null; ///< the HTTP connection to use
+ private Hash tracker; ///< used to detect multi-ref data
+ protected boolean fault = false; ///< True iff the return value is a fault (and should be thrown as an exception)
+
+
+ /** The object stack. As we process xml elements, pieces of the
+ * return value are pushed onto and popped off of this stack.
+ *
+ * The general protocol is that any time a <value> tag is
+ * encountered, an empty String ("") is pushed onto the stack. If
+ * the <value/> node has content (either an anonymous
+ * string or some other XML node), that content replaces the
+ * empty string.
+ *
+ * If an <array> tag is encountered, a null is pushed onto the
+ * stack. When a </data> is encountered, we search back on the
+ * stack to the last null, replace it with a NativeJSArray, and
+ * insert into it all elements above it on the stack.
+ *
+ * If a <struct> tag is encountered, a JSect is pushed
+ * onto the stack. If a <name> tag is encountered, its CDATA is
+ * pushed onto the stack. When a </member> is encountered, the
+ * name (second element on stack) and value (top of stack) are
+ * popped off the stack and inserted into the struct (third
+ * element on stack).
+ */
+ protected Vec objects = null;
+
+
+ // Recieve ////////////////////////////////////////////////////////////////
+
+ private class Helper extends XML {
+ public Helper() { super(BUFFER_SIZE); }
+
+ public void startElement(XML.Element c) {
+ content.reset();
+ //#switch(c.getLocalName())
+ case "fault": fault = true;
+ case "struct": objects.setElementAt(new JS(), objects.size() - 1);
+ case "array": objects.setElementAt(null, objects.size() - 1);
+ case "value": objects.addElement("");
+ //#end
+ }
+
+ public void endElement(XML.Element c) {
+ //#switch(c.getLocalName())
+ case "int": objects.setElementAt(new Integer(new String(content.getBuf(), 0, content.size())), objects.size() - 1);
+ case "i4": objects.setElementAt(new Integer(new String(content.getBuf(), 0, content.size())), objects.size() - 1);
+ case "boolean": objects.setElementAt(content.getBuf()[0] == '1' ? Boolean.TRUE : Boolean.FALSE, objects.size() - 1);
+ case "string": objects.setElementAt(new String(content.getBuf(), 0, content.size()), objects.size() - 1);
+ case "double": objects.setElementAt(new Double(new String(content.getBuf(), 0, content.size())), objects.size() - 1);
+ case "base64":
+ objects.setElementAt(new Stream.ByteArray(Base64.decode(new String(content.getBuf(), 0, content.size())),
+ null), objects.size() - 1);
+ case "name": objects.addElement(new String(content.getBuf(), 0, content.size()));
+ case "value": if ("".equals(objects.lastElement()))
+ objects.setElementAt(new String(content.getBuf(), 0, content.size()), objects.size() - 1);
+ case "dateTime.iso8601":
+ String s = new String(content.getBuf(), 0, content.size());
+
+ // strip whitespace
+ int i=0;
+ while(Character.isWhitespace(s.charAt(i))) i++;
+ if (i > 0) s = s.substring(i);
+
+ try {
+ JSDate nd = new JSDate();
+ double date = JSDate.date_msecFromDate(Double.valueOf(s.substring(0, 4)).doubleValue(),
+ Double.valueOf(s.substring(4, 6)).doubleValue() - 1,
+ Double.valueOf(s.substring(6, 8)).doubleValue(),
+ Double.valueOf(s.substring(9, 11)).doubleValue(),
+ Double.valueOf(s.substring(12, 14)).doubleValue(),
+ Double.valueOf(s.substring(15, 17)).doubleValue(),
+ (double)0
+ );
+ nd.setTime(JSDate.internalUTC(date));
+ objects.setElementAt(nd, objects.size() - 1);
+
+ } catch (Exception e) {
+ throw new RuntimeException("ibex.net.rpc.xml.recieve.malformedDateTag" +
+ "the server sent a <dateTime.iso8601> tag which was malformed: " + s);
+ }
+ case "member":
+ Object memberValue = objects.elementAt(objects.size() - 1);
+ String memberName = (String)objects.elementAt(objects.size() - 2);
+ JS struct = (JS)objects.elementAt(objects.size() - 3);
+ try {
+ struct.put(memberName, memberValue);
+ } catch (JSExn e) {
+ throw new Error("this should never happen");
+ }
+ objects.setSize(objects.size() - 2);
+ case "data":
+ int i;
+ for(i=objects.size() - 1; objects.elementAt(i) != null; i--);
+ JSArray arr = new JSArray();
+ try {
+ for(int j = i + 1; j<objects.size(); j++) arr.put(new Integer(j - i - 1), objects.elementAt(j));
+ } catch (JSExn e) {
+ throw new Error("this should never happen");
+ }
+ objects.setElementAt(arr, i);
+ objects.setSize(i + 1);
+ //#end
+ content.reset();
+ }
+
+ public void characters(char[] ch, int start, int length) {
+ try { content.write(ch, start, length); }
+ catch (Exception e) {
+ if (Log.on) Log.info(this, "Exception in XMLRPC.content() -- this should never happen");
+ if (Log.on) Log.info(this, e);
+ }
+ }
+
+ public void whitespace(char[] ch, int start, int length) {}
+ }
+
+ // Send ///////////////////////////////////////////////////////////////////////////
+
+ protected String buildRequest(JSArray args) throws JSExn, IOException {
+ StringBuffer content = new StringBuffer();
+ content.append("\r\n");
+ content.append("<?xml version=\"1.0\"?>\n");
+ content.append(" <methodCall>\n");
+ content.append(" <methodName>");
+ content.append(method);
+ content.append("</methodName>\n");
+ content.append(" <params>\n");
+ for(int i=0; i<args.length(); i++) {
+ content.append(" <param>\n");
+ appendObject(args.elementAt(i), content);
+ content.append(" </param>\n");
+ }
+ content.append(" </params>\n");
+ content.append(" </methodCall>");
+ return content.toString();
+ }
+
+ /** Appends the XML-RPC representation of <code>o</code> to <code>sb</code> */
+ void appendObject(Object o, StringBuffer sb) throws JSExn {
+
+ if (o == null) {
+ throw new JSExn("attempted to send a null value via XML-RPC");
+
+ } else if (o instanceof Number) {
+ if ((double)((Number)o).intValue() == ((Number)o).doubleValue()) {
+ sb.append(" <value><i4>");
+ sb.append(((Number)o).intValue());
+ sb.append("</i4></value>\n");
+ } else {
+ sb.append(" <value><double>");
+ sb.append(o);
+ sb.append("</double></value>\n");
+ }
+
+ } else if (o instanceof Boolean) {
+ sb.append(" <value><boolean>");
+ sb.append(((Boolean)o).booleanValue() ? "1" : "0");
+ sb.append("</boolean></value>\n");
+
+ } else if (o instanceof Stream) {
+ try {
+ sb.append(" <value><base64>\n");
+ InputStream is = ((Stream)o).getInputStream();
+ byte[] buf = new byte[54];
+ while(true) {
+ int numread = is.read(buf, 0, 54);
+ if (numread == -1) break;
+ byte[] writebuf = buf;
+ if (numread < buf.length) {
+ writebuf = new byte[numread];
+ System.arraycopy(buf, 0, writebuf, 0, numread);
+ }
+ sb.append(" ");
+ sb.append(new String(Base64.encode(writebuf)));
+ sb.append("\n");
+ }
+ sb.append("\n </base64></value>\n");
+ } catch (IOException e) {
+ if (Log.on) Log.info(this, "caught IOException while attempting to send a ByteStream via XML-RPC");
+ if (Log.on) Log.info(this, e);
+ throw new JSExn("caught IOException while attempting to send a ByteStream via XML-RPC");
+ }
+
+ } else if (o instanceof String) {
+ sb.append(" <value><string>");
+ String s = (String)o;
+ if (s.indexOf('<') == -1 && s.indexOf('&') == -1) {
+ sb.append(s);
+ } else {
+ char[] cbuf = s.toCharArray();
+ int oldi = 0, i=0;
+ while(true) {
+ while(i < cbuf.length && cbuf[i] != '<' && cbuf[i] != '&') i++;
+ sb.append(cbuf, oldi, i - oldi);
+ if (i >= cbuf.length) break;
+ if (cbuf[i] == '<') sb.append("<");
+ else if (cbuf[i] == '&') sb.append("&");
+ i = oldi = i + 1;
+ if (i >= cbuf.length) break;
+ }
+ }
+ sb.append("</string></value>\n");
+
+ } else if (o instanceof JSDate) {
+ sb.append(" <value><dateTime.iso8601>");
+ java.util.Date d = new java.util.Date(((JSDate)o).getRawTime());
+ sb.append(d.getYear() + 1900);
+ if (d.getMonth() + 1 < 10) sb.append('0');
+ sb.append(d.getMonth() + 1);
+ if (d.getDate() < 10) sb.append('0');
+ sb.append(d.getDate());
+ sb.append('T');
+ if (d.getHours() < 10) sb.append('0');
+ sb.append(d.getHours());
+ sb.append(':');
+ if (d.getMinutes() < 10) sb.append('0');
+ sb.append(d.getMinutes());
+ sb.append(':');
+ if (d.getSeconds() < 10) sb.append('0');
+ sb.append(d.getSeconds());
+ sb.append("</dateTime.iso8601></value>\n");
+
+ } else if (o instanceof JSArray) {
+ if (tracker.get(o) != null) throw new JSExn("attempted to send multi-ref data structure via XML-RPC");
+ tracker.put(o, Boolean.TRUE);
+ sb.append(" <value><array><data>\n");
+ JSArray a = (JSArray)o;
+ for(int i=0; i<a.length(); i++) appendObject(a.elementAt(i), sb);
+ sb.append(" </data></array></value>\n");
+
+ } else if (o instanceof JS) {
+ if (tracker.get(o) != null) throw new JSExn("attempted to send multi-ref data structure via XML-RPC");
+ tracker.put(o, Boolean.TRUE);
+ JS j = (JS)o;
+ sb.append(" <value><struct>\n");
+ Enumeration e = j.keys();
+ while(e.hasMoreElements()) {
+ Object key = e.nextElement();
+ sb.append(" <member><name>" + key + "</name>\n");
+ appendObject(j.get(key), sb);
+ sb.append(" </member>\n");
+ }
+ sb.append(" </struct></value>\n");
+
+ } else {
+ throw new JSExn("attempt to send object of type " + o.getClass().getName() + " via XML-RPC");
+
+ }
+ }
+
+
+ // Call Sequence //////////////////////////////////////////////////////////////////////////
+
+ public final Object call(Object a0, Object a1, Object a2, Object[] rest, int nargs) throws JSExn {
+ JSArray args = new JSArray();
+ for(int i=0; i<nargs; i++) args.addElement(i==0?a0:i==1?a1:i==2?a2:rest[i-3]);
+ return call(args);
+ }
+
+ public final Object call(final JSArray args) throws JSExn {
+ try {
+ final JS.UnpauseCallback callback = JS.pause();
+ new java.lang.Thread() { public void run() { call(callback, args); } }.start();
+ return null; // doesn't matter since we paused
+ } catch (NotPauseableException npe) {
+ throw new JSExn("cannot invoke an XML-RPC call in the foreground thread");
+ }
+ }
+
+ final void call(final JS.UnpauseCallback callback, final JSArray args) {
+ try {
+ if (Log.rpc) Log.info(this, "call to " + url + " : " + method);
+ if (tracker == null) tracker = new Hash();
+ if (objects == null) objects = new Vec();
+ String request = buildRequest(args);
+ if (Log.rpc) Log.info(this, "send:\n" + request);
+ InputStream is = http.POST("text/xml", request);
+ BufferedReader br = new BufferedReader(new InputStreamReader(is));
+ try {
+ new Helper().parse(br);
+ final Object result = fault ? new JSExn(objects.elementAt(0)) : objects.size() == 0 ? null : objects.elementAt(0);
+ Scheduler.add(new Task() { public void perform() throws JSExn { callback.unpause(result); }});
+ } finally {
+ tracker.clear();
+ objects.setSize(0);
+ }
+ } catch (final JSExn e) {
+ final Exception e2 = e;
+ Scheduler.add(new Task() { public void perform() throws JSExn { callback.unpause(e2); }});
+ } catch (final IOException e) {
+ final Exception e2 = e;
+ Scheduler.add(new Task() { public void perform() throws JSExn { callback.unpause(new JSExn(e2)); }});
+ } catch (final XML.Exn e) {
+ final Exception e2 = e;
+ Scheduler.add(new Task() { public void perform() throws JSExn { callback.unpause(new JSExn(e2)); }});
+ }
+ }
+}
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.plat;
+
+import org.ibex.util.*;
+import java.io.*;
+import org.ibex.js.*;
+import java.awt.*;
+import java.awt.datatransfer.*;
+import java.awt.image.*;
+import java.awt.event.*;
+import org.ibex.graphics.*;
+import org.ibex.core.*;
+import org.ibex.net.*;
+
+/** Platform subclass for all VM's providing AWT 1.1 functionality */
+public class AWT extends JVM {
+
+ protected String getDescriptiveName() { return "Generic JDK 1.1+ with AWT"; }
+ protected PixelBuffer _createPixelBuffer(int w, int h, Surface owner) { return new AWTPixelBuffer(w, h); }
+ protected Picture _createPicture(JS r) { return new AWTPicture(r); }
+ protected int _getScreenWidth() { return Toolkit.getDefaultToolkit().getScreenSize().width; }
+ protected int _getScreenHeight() { return Toolkit.getDefaultToolkit().getScreenSize().height; }
+ protected Surface _createSurface(Box b, boolean framed) { return new AWTSurface(b, framed); }
+
+ protected void postInit() {
+ if (Log.on) Log.diag(Platform.class, " color depth = " +
+ Toolkit.getDefaultToolkit().getColorModel().getPixelSize() + "bpp");
+ }
+
+ protected void _criticalAbort(String message) {
+ if (Log.on) Log.info(this, message);
+ final Dialog d = new Dialog(new Frame(), "Ibex Cannot Continue");
+ d.setLayout(new BorderLayout());
+ TextArea ta = new TextArea("Ibex cannot continue because:\n\n" + message, 10, 80);
+ ta.setEditable(false);
+ d.add(ta, "Center");
+ Button b = new Button("OK");
+ b.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ d.dispose();
+ }
+ });
+ d.add(b, "South");
+ d.setModal(true);
+ d.pack();
+ d.show();
+ new Semaphore().block();
+ }
+
+ protected String _getClipBoard() {
+ Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard();
+ if (cb == null) return null;
+ Transferable clipdata = cb.getContents(null);
+ try { return (String)clipdata.getTransferData(DataFlavor.stringFlavor); } catch (Exception ex) { return null; }
+ }
+
+ protected void _setClipBoard(String s) {
+ Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
+ if (clipboard == null) return;
+ StringSelection clipString = new StringSelection(s);
+ clipboard.setContents(clipString, clipString);
+ }
+
+ /** some platforms (cough, cough, NetscapeVM) have totally broken modifier masks; they will need to override this */
+ protected static int modifiersToButtonNumber(int modifiers) {
+ if ((modifiers & InputEvent.BUTTON1_MASK) == InputEvent.BUTTON1_MASK) return 1;
+ if ((modifiers & InputEvent.BUTTON2_MASK) == InputEvent.BUTTON2_MASK) {
+ // ugh, MacOSX reports the right mouse button as BUTTON2_MASK...
+ if (System.getProperty("os.name", "").startsWith("Mac OS X")) return 2;
+ return 3;
+ }
+ if ((modifiers & InputEvent.BUTTON3_MASK) == InputEvent.BUTTON3_MASK) {
+ // ugh, MacOSX reports the right mouse button as BUTTON2_MASK...
+ if (System.getProperty("os.name", "").startsWith("Mac OS X")) return 3;
+ return 2;
+ }
+ return 0;
+ }
+
+ static class FileDialogHelper extends FileDialog implements WindowListener, ComponentListener {
+ Semaphore s;
+ public FileDialogHelper(String suggestedFileName, Semaphore s, boolean write) {
+ super(new Frame(), write ? "Save" : "Open", write ? FileDialog.SAVE : FileDialog.LOAD);
+ this.s = s;
+ addWindowListener(this);
+ addComponentListener(this);
+ if (suggestedFileName.indexOf(File.separatorChar) == -1) {
+ setFile(suggestedFileName);
+ } else {
+ setDirectory(suggestedFileName.substring(0, suggestedFileName.lastIndexOf(File.separatorChar)));
+ setFile(suggestedFileName.substring(suggestedFileName.lastIndexOf(File.separatorChar) + 1));
+ }
+ show();
+ }
+ public void windowActivated(WindowEvent e) { }
+ public void windowClosed(WindowEvent e) { s.release(); }
+ public void windowClosing(WindowEvent e) { }
+ public void windowDeactivated(WindowEvent e) { }
+ public void windowDeiconified(WindowEvent e) { }
+ public void windowIconified(WindowEvent e) { }
+ public void windowOpened(WindowEvent e) { }
+ public void componentHidden(ComponentEvent e) { s.release(); }
+ public void componentMoved(ComponentEvent e) { }
+ public void componentResized(ComponentEvent e) { }
+ public void componentShown(ComponentEvent e) { }
+ };
+
+ protected String _fileDialog(String suggestedFileName, boolean write) {
+ final Semaphore s = new Semaphore();
+ FileDialogHelper fd = new FileDialogHelper(suggestedFileName, s, write);
+ s.block();
+ return fd.getDirectory() == null ? null : (fd.getDirectory() + File.separatorChar + fd.getFile());
+ }
+
+
+ // Inner Classes /////////////////////////////////////////////////////////////////////////////////////
+
+ protected org.ibex.graphics.Font.Glyph _createGlyph(org.ibex.graphics.Font f, char c) { return new AWTGlyph(f, c); }
+ protected static class AWTGlyph extends org.ibex.graphics.Font.Glyph {
+ private Image i = null;
+ private static ColorModel cmodel = new DirectColorModel(32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000);
+
+ // this doesn't work on Win32 because the JVM is broken
+ /*
+ static final ColorModel cmodel = new ColorModel(8) {
+ public int getRed(int p) { return 0; }
+ public int getGreen(int p) { return 0; }
+ public int getBlue(int p) { return 0; }
+ public int getAlpha(int p) { return p & 0xFF; }
+ };
+ */
+
+ public AWTGlyph(org.ibex.graphics.Font f, char c) { super(f, c); }
+ Image getImage() {
+ if (i == null && isLoaded) {
+
+ int[] data2 = new int[data.length];
+ for(int i=0; i<data2.length; i++) data2[i] = ((data[i]) & 0xff) << 24;
+
+ MemoryImageSource mis = new MemoryImageSource(width, height, cmodel, data2, 0, width);
+ mis.setAnimated(true);
+ i = Toolkit.getDefaultToolkit().createImage(mis);
+ MediaTracker mediatracker = new MediaTracker(new Canvas());
+ mediatracker.addImage(i, 1);
+ try { mediatracker.waitForAll(); } catch (InterruptedException e) { }
+ mediatracker.removeImage(i);
+ synchronized(AWTPixelBuffer.class) {
+ if (AWTPixelBuffer.component == null) {
+ AWTPixelBuffer.component = new Frame();
+ AWTPixelBuffer.component.setVisible(false);
+ AWTPixelBuffer.component.addNotify();
+ }
+ }
+ data = null;
+ }
+ return i;
+ }
+ }
+
+ protected static class AWTPicture extends Picture {
+ public Image i = null;
+ private static ColorModel cmodel = new DirectColorModel(32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000);
+
+ boolean initialized = false;
+ public AWTPicture(JS r) { super(r); }
+ public void init() {
+ if (initialized) return;
+ initialized = true;
+ MemoryImageSource mis = new MemoryImageSource(width, height, cmodel, data, 0, width);
+ mis.setAnimated(true);
+ i = Toolkit.getDefaultToolkit().createImage(mis);
+ MediaTracker mediatracker = new MediaTracker(new Canvas());
+ mediatracker.addImage(i, 1);
+ try { mediatracker.waitForAll(); } catch (InterruptedException e) { }
+ mediatracker.removeImage(i);
+ synchronized(AWTPixelBuffer.class) {
+ if (AWTPixelBuffer.component == null) {
+ AWTPixelBuffer.component = new Frame();
+ AWTPixelBuffer.component.setVisible(false);
+ AWTPixelBuffer.component.addNotify();
+ }
+ }
+ }
+ }
+
+ protected static class AWTPixelBuffer extends PixelBuffer {
+
+ protected Image i = null;
+ protected Graphics g = null;
+
+ /** JDK1.1 platforms require that a component be associated with each off-screen buffer */
+ static Component component = null;
+
+ protected AWTPixelBuffer() { }
+ public AWTPixelBuffer(int w, int h) {
+ synchronized(AWTPixelBuffer.class) {
+ if (component == null) {
+ component = new Frame();
+ component.setVisible(false);
+ component.addNotify();
+ }
+ }
+ i = component.createImage(w, h);
+ g = i.getGraphics();
+ }
+
+ public int getHeight() { return i == null ? 0 : i.getHeight(null); }
+ public int getWidth() { return i == null ? 0 : i.getWidth(null); }
+
+ public void drawPicture(Picture source, int dx, int dy, int cx1, int cy1, int cx2, int cy2) {
+ ((AWTPicture)source).init();
+ g.setClip(cx1, cy1, cx2 - cx1, cy2 - cy1);
+ g.drawImage(((AWTPicture)source).i, dx, dy, null);
+ g.setClip(0, 0, i.getWidth(null), i.getHeight(null));
+ }
+
+ /** implemented with java.awt 1.1's setXORMode() */
+ public void drawGlyph(org.ibex.graphics.Font.Glyph source, int dx, int dy, int cx1, int cy1, int cx2, int cy2, int rgb) {
+
+ // XOR the target region
+ g.setXORMode(new java.awt.Color((rgb & 0x00ff0000) >> 16, (rgb & 0x0000ff00) >> 8, rgb & 0x000000ff));
+ g.setColor(new java.awt.Color(0x0, 0x0, 0x0));
+ g.fillRect(cx1, cy1, cx2 - cx1, cy2 - cy1);
+
+ // blacken the area we want the glyph to cover
+ g.setPaintMode();
+ g.setClip(cx1, cy1, cx2 - cx1, cy2 - cy1);
+ g.drawImage(((AWTGlyph)source).getImage(), dx, dy, null);
+ g.setClip(0, 0, i.getWidth(null), i.getHeight(null));
+
+ // XOR back, turning black into the chosen rgb color
+ g.setXORMode(new java.awt.Color((rgb & 0x00ff0000) >> 16, (rgb & 0x0000ff00) >> 8, rgb & 0x000000ff));
+ g.setColor(new java.awt.Color(0x0, 0x0, 0x0));
+ g.fillRect(cx1, cy1, cx2 - cx1, cy2 - cy1);
+
+ // restore the graphics context
+ g.setPaintMode();
+ }
+
+ // FIXME: try to use os acceleration
+ public void fillTrapezoid(int x1, int x2, int y1, int x3, int x4, int y2, int argb) {
+ g.setColor(new java.awt.Color((argb & 0x00FF0000) >> 16, (argb & 0x0000FF00) >> 8, (argb & 0x000000FF)));
+ if (x1 == x3 && x2 == x4) {
+ g.fillRect(x1, y1, x4 - x1, y2 - y1);
+ } else for(int y=y1; y<y2; y++) {
+ int _x1 = (int)Math.floor((y - y1) * (x3 - x1) / (y2 - y1) + x1);
+ int _y1 = (int)Math.floor(y);
+ int _x2 = (int)Math.ceil((y - y1) * (x4 - x2) / (y2 - y1) + x2);
+ int _y2 = (int)Math.floor(y) + 1;
+ if (_x1 > _x2) { int _x0 = _x1; _x1 = _x2; _x2 = _x0; }
+ g.fillRect(_x1, _y1, _x2 - _x1, _y2 - _y1);
+ }
+ }
+ }
+
+
+ protected static class AWTSurface extends Surface.DoubleBufferedSurface
+ implements MouseListener, MouseMotionListener, KeyListener, ComponentListener, WindowListener {
+
+ public void blit(PixelBuffer s, int sx, int sy, int dx, int dy, int dx2, int dy2) {
+ insets = (frame == null ? window : frame).getInsets();
+ window.getGraphics().drawImage(((AWTPixelBuffer)s).i,
+ dx + insets.left,
+ dy + insets.top,
+ dx2 + insets.left,
+ dy2 + insets.top,
+ sx, sy, sx + (dx2 - dx), sy + (dy2 - dy), null);
+ }
+
+ /** if (component instanceof Frame) then frame == window else frame == null */
+ Frame frame = null;
+ Window window = null;
+
+ /** our component's insets */
+ protected Insets insets = new Insets(0, 0, 0, 0);
+
+ /** some JDKs let us recycle a single Dimension object when calling getSize() */
+ Dimension singleSize = new Dimension();
+
+ public void toBack() { if (window != null) window.toBack(); }
+ public void toFront() { if (window != null) window.toFront(); }
+ public void setLocation() { window.setLocation(root.x, root.y); }
+ public void setTitleBarText(String s) { if (frame != null) frame.setTitle(s); }
+ public void setIcon(Picture i) { if (frame != null) frame.setIconImage(((AWTPicture)i).i); }
+ public void _setSize(int width, int height) { window.setSize(width + (insets.left + insets.right), height + (insets.top + insets.bottom)); }
+ public void setInvisible(boolean b) { window.setVisible(!b); }
+ protected void _setMinimized(boolean b) { if (Log.on) Log.info(this, "JDK 1.1 platforms cannot minimize or unminimize windows"); }
+ protected void _setMaximized(boolean b) {
+ if (!b) {
+ if (Log.on) Log.info(this, "JDK 1.1 platforms cannot unmaximize windows");
+ return;
+ }
+ window.setLocation(new Point(0, 0));
+ window.setSize(Toolkit.getDefaultToolkit().getScreenSize());
+ }
+
+ class InnerFrame extends Frame {
+ public InnerFrame() throws java.lang.UnsupportedOperationException { }
+ public Dimension getMinimumSize() {
+ return new Dimension(root == null ? 0 : root.minwidth, root == null ? 0 : root.minheight); }
+ public void update(Graphics gr) { paint(gr); }
+ public void paint(Graphics gr) {
+ Rectangle r = gr.getClipBounds();
+
+ // ugly hack for Java1.4 dynamicLayout on Win32 -- this catches expansions during smooth resize
+ int newwidth = Math.max(r.x - insets.left + r.width, root.width);
+ int newheight = Math.max(r.y - insets.top + r.height, root.height);
+ if (newwidth > root.width || newheight > root.height)
+ componentResized(window.getWidth() - insets.left - insets.right,
+ window.getHeight() - insets.top - insets.bottom);
+
+ Dirty(r.x - insets.left, r.y - insets.top, r.width, r.height);
+ }
+ }
+
+ class InnerWindow extends Window {
+ public InnerWindow() throws java.lang.UnsupportedOperationException { super(new Frame()); }
+ public Dimension getMinimumSize() {
+ return new Dimension(root == null ? 0 : root.minwidth, root == null ? 0 : root.minheight); }
+ public void update(Graphics gr) { paint(gr); }
+ public void paint(Graphics gr) {
+ Rectangle r = gr.getClipBounds();
+ Dirty(r.x - insets.left, r.y - insets.top, r.width, r.height);
+ }
+ }
+
+ public void setMinimumSize(int minx, int miny, boolean resizable) { if (frame != null) frame.setResizable(resizable); }
+
+ private int oldfill = 0x0;
+ public void render() {
+ // useful optimizatin;
+ if (oldfill != root.fillcolor) {
+ oldfill = root.fillcolor;
+ window.setBackground((root.fillcolor & 0xFF000000) == 0 ?
+ java.awt.Color.white :
+ new java.awt.Color((root.fillcolor >> 16) & 0xff,
+ (root.fillcolor >> 8) & 0xff,
+ (root.fillcolor) & 0xff));
+ }
+ super.render();
+ }
+
+ AWTSurface(Box root, boolean framed) {
+ super(root);
+ try {
+ if (framed) window = frame = new InnerFrame();
+ else window = new InnerWindow();
+
+ // this is here to catch HeadlessException on jdk1.4
+ } catch (java.lang.UnsupportedOperationException e) {
+ if (Log.on) Log.info(this, "Exception thrown in AWTSurface$InnerFrame() -- this should never happen");
+ if (Log.on) Log.info(this, e);
+ }
+
+ insets = window.getInsets();
+
+ window.addMouseListener(this);
+ window.addKeyListener(this);
+ window.addComponentListener(this);
+ window.addMouseMotionListener(this);
+ window.addWindowListener(this);
+
+ // IMPORTANT: this must be called before render() to ensure
+ // that our peer has been created
+ makeVisible();
+ }
+
+ protected void makeVisible() { window.setVisible(true); }
+
+ public void _dispose() {
+ window.removeMouseListener(this);
+
+ // removed to work around a jdk1.3 bug
+ /* window.removeKeyListener(this); */
+
+ window.removeComponentListener(this);
+ window.removeMouseMotionListener(this);
+ window.removeWindowListener(this);
+ window.dispose();
+ }
+
+ public void syncCursor() {
+ if (cursor.equals("crosshair")) window.setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
+ else if (cursor.equals("east")) window.setCursor(Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR));
+ else if (cursor.equals("move")) window.setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
+ else if (cursor.equals("north")) window.setCursor(Cursor.getPredefinedCursor(Cursor.N_RESIZE_CURSOR));
+ else if (cursor.equals("northeast")) window.setCursor(Cursor.getPredefinedCursor(Cursor.NE_RESIZE_CURSOR));
+ else if (cursor.equals("northwest")) window.setCursor(Cursor.getPredefinedCursor(Cursor.NW_RESIZE_CURSOR));
+ else if (cursor.equals("south")) window.setCursor(Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR));
+ else if (cursor.equals("southeast")) window.setCursor(Cursor.getPredefinedCursor(Cursor.SE_RESIZE_CURSOR));
+ else if (cursor.equals("southwest")) window.setCursor(Cursor.getPredefinedCursor(Cursor.SW_RESIZE_CURSOR));
+ else if (cursor.equals("text")) window.setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR));
+ else if (cursor.equals("west")) window.setCursor(Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR));
+ else if (cursor.equals("wait")) window.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
+ else if (cursor.equals("hand")) window.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
+ else window.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
+ }
+
+ // AWT Message translation ////////////////////////////////////////////////////////////////
+
+ // these functions are all executed in the AWT thread, not the
+ // MessageQueue thread. As a result, they must be *extremely*
+ // careful about invoking methods on instances of Box. Currently,
+ // they should only enqueue messages, use Box.whoIs()
+ // (unsynchronized but thought to be safe), and modify members of
+ // Surface.
+
+ public void componentHidden(ComponentEvent e) { }
+ public void componentShown(ComponentEvent e) { }
+ public void windowOpened(WindowEvent e) { }
+ public void windowClosed(WindowEvent e) { }
+ public void windowClosing(WindowEvent e) { Close(); }
+ public void windowIconified(WindowEvent e) { Minimized(true); }
+ public void windowDeiconified(WindowEvent e) { dirty(0, 0, root.width, root.height); Minimized(false); }
+ public void windowActivated(WindowEvent e) { Focused(true); }
+ public void windowDeactivated(WindowEvent e) { Focused(false); }
+ public void componentMoved(ComponentEvent e) { PosChange(window.getLocation().x + insets.left, window.getLocation().y + insets.top); }
+
+ public void componentResized(ComponentEvent e) {
+ // we have to periodically do this; I don't know why
+ insets = window.getInsets();
+ componentResized(window.getWidth() - insets.left - insets.right, window.getHeight() - insets.top - insets.bottom);
+ }
+
+ public void componentResized(int newwidth, int newheight) { SizeChange(newwidth, newheight); }
+
+ public void keyTyped(KeyEvent k) { }
+ public void keyPressed(KeyEvent k) { KeyPressed(translateKey(k)); }
+ public void keyReleased(KeyEvent k) { KeyReleased(translateKey(k)); }
+ public void mouseExited(MouseEvent m) { mouseMoved(m); }
+ public void mouseEntered(MouseEvent m) { mouseMoved(m); }
+ public void mouseDragged(MouseEvent m) { mouseMoved(m); }
+ public void mouseMoved(MouseEvent m) {
+
+ // ugly hack for Java1.4 dynamicLayout on Win32 -- this catches contractions during smooth resize
+ int newwidth = window.getWidth() - insets.left - insets.right;
+ int newheight = window.getHeight() - insets.top - insets.bottom;
+ if (newwidth != root.width || newheight != root.height) componentResized(newwidth, newheight);
+
+ Move(m.getX() - insets.left, m.getY() - insets.top);
+ }
+ public void mousePressed(MouseEvent m) { Press(modifiersToButtonNumber(m.getModifiers())); }
+ public void mouseReleased(MouseEvent m) { Release(modifiersToButtonNumber(m.getModifiers())); }
+ public void mouseClicked(MouseEvent m) {
+ if (m.getClickCount() == 2) DoubleClick(modifiersToButtonNumber(m.getModifiers()));
+ else Click(modifiersToButtonNumber(m.getModifiers()));
+ }
+
+ String translateKey(KeyEvent k) {
+ switch (k.getKeyCode()) {
+ case KeyEvent.VK_ALT: return "alt";
+ case KeyEvent.VK_BACK_SPACE: return "back_space";
+ case KeyEvent.VK_CONTROL: return "control";
+ case KeyEvent.VK_DELETE: return "delete";
+ case KeyEvent.VK_DOWN: return "down";
+ case KeyEvent.VK_END: return "end";
+ case KeyEvent.VK_ENTER: return "enter";
+ case KeyEvent.VK_ESCAPE: return "escape";
+ case KeyEvent.VK_F1: return "f1";
+ case KeyEvent.VK_F10: return "f10";
+ case KeyEvent.VK_F11: return "f11";
+ case KeyEvent.VK_F12: return "f12";
+ case KeyEvent.VK_F2: return "f2";
+ case KeyEvent.VK_F3: return "f3";
+ case KeyEvent.VK_F4: return "f4";
+ case KeyEvent.VK_F5: return "f5";
+ case KeyEvent.VK_F6: return "f6";
+ case KeyEvent.VK_F7: return "f7";
+ case KeyEvent.VK_F8: return "f8";
+ case KeyEvent.VK_F9: return "f9";
+ case KeyEvent.VK_HOME: return "home";
+ case KeyEvent.VK_INSERT: return "insert";
+ case KeyEvent.VK_LEFT: return "left";
+ case KeyEvent.VK_META: return "alt";
+ case KeyEvent.VK_PAGE_DOWN: return "page_down";
+ case KeyEvent.VK_PAGE_UP: return "page_up";
+ case KeyEvent.VK_PAUSE: return "pause";
+ case KeyEvent.VK_PRINTSCREEN: return "printscreen";
+ case KeyEvent.VK_RIGHT: return "right";
+ case KeyEvent.VK_SHIFT: return "shift";
+ case KeyEvent.VK_TAB: return "tab";
+ case KeyEvent.VK_UP: return "up";
+ default:
+ char c = k.getKeyChar();
+ if (c >= 1 && c <= 26) c = (char)('a' + c - 1);
+ return String.valueOf(c);
+ }
+ }
+ }
+
+ protected void _decodeJPEG(InputStream is, Picture p) {
+ try {
+ Image i = Toolkit.getDefaultToolkit().createImage(InputStreamToByteArray.convert(is));
+ MediaTracker mediatracker = new MediaTracker(new Canvas());
+ mediatracker.addImage(i, 1);
+ try { mediatracker.waitForAll(); } catch (InterruptedException e) { }
+ mediatracker.removeImage(i);
+ final int width = i.getWidth(null);
+ final int height = i.getHeight(null);
+ final int[] data = new int[width * height];
+ PixelGrabber pg = new PixelGrabber(i, 0, 0, width, height, data, 0, width);
+ pg.grabPixels();
+ if ((pg.getStatus() & ImageObserver.ABORT) != 0)
+ Log.info(this, "PixelGrabber reported an error while decoding JPEG image");
+ p.width = width;
+ p.height = height;
+ p.data = data;
+ } catch (Exception e) {
+ Log.info(this, "Exception caught while decoding JPEG image");
+ Log.info(this, e);
+ }
+ }
+}
--- /dev/null
+// Copyright 2003 Adam Megacz, see the COPYING file for licensing [LGPL]
+// Authors: Brian Alliet and Evan Jones
+#ifndef __APPLE_CC__
+#define FSF_GCC
+#define __APPLE_CC__
+#else
+#define APPLE_GCC
+#endif
+
+#define __private_extern__
+#include <mach-o/dyld.h>
+
+#include "POSIX.cc"
+#include "OpenGL.cc"
+
+#include <java/lang/Object.h>
+#include <java/lang/Error.h>
+
+#include <org/ibex/plat/Darwin.h>
+#include <org/ibex/plat/Darwin$CarbonSurface.h>
+#include <org/ibex/plat/Darwin$GLCarbonSurface.h>
+#include <org/ibex/plat/Darwin$GLCarbonPixelBuffer.h>
+#include <org/ibex/plat/Darwin$CarbonMessage.h>
+#include <org/ibex/plat/Darwin$CarbonOpenGL.h>
+#include <org/ibex/plat/Darwin$FileDialogHelper.h>
+#include <org/ibex/plat/GCJ$Retainer.h>
+#include <org/ibex/net/HTTP$Proxy.h>
+#include <org/ibex/util/Semaphore.h>
+
+#include <stdlib.h>
+#include <pthread.h>
+
+#include "DarwinCarbonHeaders.h"
+
+#define Ibex_CARBON_NO_BUNDLE_HACK
+#ifdef Ibex_CARBON_NO_BUNDLE_HACK
+extern "C" {
+ OSErr CPSEnableForegroundOperation(ProcessSerialNumber *psn);
+ OSErr CPSSetFrontProcess(ProcessSerialNumber *psn);
+}
+#endif
+
+static const mach_header* CarbonHandle = NULL;
+static const mach_header* AGLHandle = NULL;
+static const mach_header* SCHandle = NULL;
+#define CARBON_LIBRARY_PATH "/System/Library/Frameworks/Carbon.framework/Versions/A/Carbon"
+#define AGL_LIBRARY_PATH "/System/Library/Frameworks/AGL.framework/Versions/A/AGL"
+#define SC_LIBRARY_PATH "/System/Library/Frameworks/SystemConfiguration.framework/Versions/A/SystemConfiguration"
+
+static void* dlsym(char* symbol) {
+ if (CarbonHandle == NULL) CarbonHandle = NSAddImage(CARBON_LIBRARY_PATH, NSADDIMAGE_OPTION_NONE);
+ if (AGLHandle == NULL) AGLHandle = NSAddImage(AGL_LIBRARY_PATH, NSADDIMAGE_OPTION_NONE);
+ if (SCHandle == NULL) SCHandle = NSAddImage(SC_LIBRARY_PATH, NSADDIMAGE_OPTION_NONE);
+ void* ret = NSAddressOfSymbol(NSLookupSymbolInImage(CarbonHandle, symbol,
+ NSLOOKUPSYMBOLINIMAGE_OPTION_BIND));
+ if (ret == NULL) ret = NSAddressOfSymbol(NSLookupSymbolInImage(AGLHandle, symbol,
+ NSLOOKUPSYMBOLINIMAGE_OPTION_BIND));
+ if (ret == NULL) ret = NSAddressOfSymbol(NSLookupSymbolInImage(SCHandle, symbol,
+ NSLOOKUPSYMBOLINIMAGE_OPTION_BIND));
+ /*printf("linking symbol %s to address %x\n", symbol, ret);
+ fflush(stdout);*/
+ return ret;
+}
+
+#define declare_weak(symbol) typeof(symbol) *symbol##_weak = NULL
+#define WC(func) \
+ (*((func##_weak != NULL) ? func##_weak : func##_weak = (typeof(func##_weak))dlsym("_" #func)))
+
+declare_weak(GetRegionBounds);
+declare_weak(RegisterToolboxObjectClass);
+declare_weak(GetWindowProperty);
+declare_weak(SetWindowProperty);
+declare_weak(CreateCustomWindow);
+declare_weak(InstallWindowContentPaintProc);
+declare_weak(AEGetNthPtr);
+declare_weak(CFArrayGetCount);
+declare_weak(CFArrayGetTypeID);
+declare_weak(CFArrayGetValueAtIndex);
+declare_weak(CFDictionaryGetValue);
+declare_weak(CFGetTypeID);
+declare_weak(CFNumberGetTypeID);
+declare_weak(CFNumberGetValue);
+declare_weak(CFRelease);
+declare_weak(CFStringCompare);
+declare_weak(CFStringCreateWithCString);
+declare_weak(CFStringCreateWithCharacters);
+declare_weak(CFStringGetCharacters);
+declare_weak(CFStringGetLength);
+declare_weak(CFStringGetTypeID);
+declare_weak(CFURLCopyScheme);
+declare_weak(CFURLCreateWithString);
+declare_weak(CGDisplayPixelsHigh);
+declare_weak(CGDisplayPixelsWide);
+declare_weak(CallNextEventHandler);
+declare_weak(CollapseWindow);
+declare_weak(ConstrainWindowToScreen);
+declare_weak(CreateEvent);
+declare_weak(CreateNewWindow);
+declare_weak(DisposeEventHandlerUPP);
+declare_weak(DisposeNavEventUPP);
+declare_weak(DisposeWindow);
+declare_weak(ExitToShell);
+declare_weak(FSRefMakePath);
+declare_weak(FrontWindow);
+declare_weak(Gestalt);
+declare_weak(GetApplicationEventTarget);
+declare_weak(GetCurrentProcess);
+declare_weak(GetCurrentScrap);
+declare_weak(GetEventClass);
+declare_weak(GetEventKind);
+declare_weak(GetEventParameter);
+declare_weak(GetMainEventQueue);
+declare_weak(GetScrapFlavorData);
+declare_weak(GetScrapFlavorSize);
+declare_weak(GetWindowBounds);
+declare_weak(GetWindowEventTarget);
+declare_weak(GetWindowPort);
+declare_weak(HideWindow);
+declare_weak(InstallEventHandler);
+declare_weak(IsWindowCollapsed);
+declare_weak(LSOpenCFURLRef);
+declare_weak(NavCreateGetFileDialog);
+declare_weak(NavCreatePutFileDialog);
+declare_weak(NavDialogDispose);
+declare_weak(NavDialogGetReply);
+declare_weak(NavDialogGetUserAction);
+declare_weak(NavDialogRun);
+declare_weak(NavDisposeReply);
+declare_weak(NavGetDefaultDialogCreationOptions);
+declare_weak(NewEventHandlerUPP);
+declare_weak(NewNavEventUPP);
+declare_weak(PostEventToQueue);
+declare_weak(PutScrapFlavor);
+declare_weak(QuitApplicationEventLoop);
+declare_weak(ReleaseEvent);
+declare_weak(RunApplicationEventLoop);
+declare_weak(SCDynamicStoreCopyProxies);
+declare_weak(SelectWindow);
+declare_weak(SendBehind);
+declare_weak(SetEventParameter);
+declare_weak(SetThemeCursor);
+declare_weak(SetWindowBounds);
+declare_weak(SetWindowResizeLimits);
+declare_weak(SetWindowTitleWithCFString);
+declare_weak(ShowWindow);
+declare_weak(ZoomWindowIdeal);
+declare_weak(__CFStringMakeConstantString);
+declare_weak(aglChoosePixelFormat);
+declare_weak(aglCreateContext);
+declare_weak(aglDestroyContext);
+declare_weak(aglSetCurrentContext);
+declare_weak(aglSetDrawable);
+declare_weak(aglSurfaceTexture);
+declare_weak(aglUpdateContext);
+declare_weak(CPSEnableForegroundOperation);
+declare_weak(CPSSetFrontProcess);
+declare_weak(kCFAllocatorDefault);
+declare_weak(NewWindowPaintUPP);
+
+#define GetWindowEventTarget WC(GetWindowEventTarget)
+#define InstallEventHandler WC(InstallEventHandler)
+#define __CFStringMakeConstantString WC(__CFStringMakeConstantString)
+
+using namespace org::ibex::plat;
+using gnu::gcj::RawData;
+using org::ibex::util::Semaphore;
+using java::lang::Object;
+
+namespace org { namespace ibex { namespace plat {
+
+
+#pragma mark ----- Blit Locks ------
+static pthread_mutex_t blit_mutex;
+static pthread_cond_t blit_cond;
+
+static inline void blit_lock() { if(pthread_mutex_lock(&blit_mutex) != 0) abort(); }
+static inline void blit_unlock() { if(pthread_mutex_unlock(&blit_mutex) != 0) abort(); }
+static inline void blit_wait() { if(pthread_cond_wait(&blit_cond,&blit_mutex) != 0) abort(); }
+static inline void blit_signal() { if(pthread_cond_signal(&blit_cond) != 0) abort(); }
+
+void Darwin$CarbonSurface::blitLock() { blit_lock(); }
+void Darwin$CarbonSurface::blitUnlock() { blit_unlock(); }
+void Darwin$CarbonSurface::blitWait() { blit_wait(); }
+
+
+template <bool CHECK> static inline int CompileTimeCheck() { const int something_is_wrong=1; something_is_wrong++; return 0; }
+template <> static inline int CompileTimeCheck<true>() { return 0; }
+const static int unichar_check = CompileTimeCheck<sizeof(jchar)==sizeof(UniChar)>();
+
+static void funcFailed(const char *func,int r);
+static inline void funcFailed(const char *func) { funcFailed(func,-1); }
+
+static inline void checkStatus(OSStatus r, char *func) { if(r != noErr) funcFailed(func,r); }
+static inline void checkStatus(GLboolean b, char *func) { if(!b) funcFailed(func,-1); }
+static inline void checkStatus(void *p, char *func) { if(!p) funcFailed(func,-1); }
+
+jstring cfStringToJString(CFStringRef s) {
+ CFIndex length = WC(CFStringGetLength)(s);
+ CFRange range = CFRangeMake(0,length);
+ jstring js = JvAllocString(length);
+ UniChar *buf = (UniChar*)JvGetStringChars(js);
+ WC(CFStringGetCharacters)(s,range,buf);
+ return js;
+}
+
+#pragma mark ------ SmartCFString ------
+class SmartCFString {
+ private:
+ CFStringRef p;
+ void release() { if(p) WC(CFRelease)(p); }
+ void checkNull() { if(!p) funcFailed("CFString function"); }
+ public:
+ // Constructors
+ SmartCFString() : p(0) { }
+ SmartCFString(const char *s) : p(0) { *this = s; }
+ SmartCFString(jstring js) : p(0) { *this = js; }
+ SmartCFString(CFStringRef cf) : p(0) { *this = cf; }
+ // Destructor
+ ~SmartCFString() { release(); }
+ // Assignment
+ SmartCFString& operator= (const char *s) {
+ release();
+ if(!s) s = "(null)";
+ p = WC(CFStringCreateWithCString)(WC(kCFAllocatorDefault),s,kCFStringEncodingISOLatin1);
+ checkNull();
+ return *this;
+ }
+ SmartCFString& operator= (jstring js) {
+ if(!js) return *this = "(null)";
+ release();
+ UniChar *buf = (UniChar*) JvGetStringChars(js);
+ CFIndex length = js->length();
+ p = WC(CFStringCreateWithCharacters)(WC(kCFAllocatorDefault),buf,length);
+ checkNull();
+ return *this;
+ }
+ SmartCFString& operator= (CFStringRef cf) {
+ if(cf == NULL) return *this = "(null)";
+ release();
+ p = cf;
+ return *this;
+ }
+ operator CFStringRef() { return p; }
+ operator jstring() { return getJString(); }
+
+ jstring getJString() { return cfStringToJString(p); }
+
+ bool equals(const char *s) {
+ SmartCFString cfs(s);
+ return equals(cfs);
+ }
+
+ bool equals(CFStringRef cfs) {
+ return WC(CFStringCompare)(p,cfs,0) == kCFCompareEqualTo;
+ }
+};
+
+// CHECKME: Is just making up your own four char codes really correct?
+const static UInt32 kEventClassCarbonMessage = 'ibexa';
+const static UInt32 kEventCarbonMessage = 'ibexb';
+const static UInt32 kEventParamCarbonMessage = 'ibexc';
+
+static OSStatus carbonMessageEventHandler(EventHandlerCallRef handler, EventRef e, void *userData);
+static EventHandlerUPP carbonMessageEventHandlerUPP;
+
+static void fileDialogEventHandler(NavEventCallbackMessage callBackSelector, NavCBRecPtr callBackParms, void *userData);
+static NavEventUPP fileDialogEventHandlerUPP;
+
+static OSStatus windowEventHandler(EventHandlerCallRef handler, EventRef e, void *userData);
+static EventHandlerUPP windowEventHandlerUPP;
+
+static OSStatus paintProc(GDHandle device,GrafPtr qdContext,WindowRef window,RgnHandle inClientPaintRgn,RgnHandle outSystemPaintRgn,void *userData);
+static WindowPaintUPP paintProcUPP;
+
+jboolean Darwin::isJaguar() {
+ SInt32 version;
+ OSStatus r = WC(Gestalt)(gestaltSystemVersion, &version);
+ checkStatus(r,"Gestalt");
+ return version >= 0x1020;
+}
+
+void Darwin$CarbonMessage::natInit() {
+ OSStatus r;
+
+ EventTypeSpec eventTypes = { kEventClassCarbonMessage, kEventCarbonMessage };
+ r = InstallEventHandler(WC(GetApplicationEventTarget)(),carbonMessageEventHandlerUPP,1,&eventTypes,NULL,NULL);
+ checkStatus(r,"InstallEventHandler");
+}
+
+void Darwin$CarbonMessage::add(Darwin$CarbonMessage *msg) {
+ EventRef event;
+ OSStatus r;
+
+ GCJ$Retainer::retain(msg);
+
+ r = WC(CreateEvent)(WC(kCFAllocatorDefault),kEventClassCarbonMessage,kEventCarbonMessage,0,kEventAttributeNone,&event);
+ checkStatus(r,"CreateEvent");
+ r = WC(SetEventParameter)(event,kEventParamCarbonMessage,typeVoidPtr,sizeof(msg),(void*)&msg);
+ checkStatus(r,"SetEventParameter");
+ r = WC(PostEventToQueue)(WC(GetMainEventQueue)(),event,kEventPriorityHigh);
+ checkStatus(r,"PostEventToQueue");
+ WC(ReleaseEvent)(event);
+}
+
+
+static OSStatus carbonMessageEventHandler(EventHandlerCallRef handler, EventRef e, void *userData) {
+ UInt32 eKind = WC(GetEventKind)(e);
+ UInt32 eClass = WC(GetEventClass)(e);
+ OSStatus r;
+ Darwin$CarbonMessage *msg;
+ if(eClass != kEventClassCarbonMessage || eKind != kEventCarbonMessage)
+ return eventNotHandledErr;
+ r = WC(GetEventParameter)(e,kEventParamCarbonMessage,typeVoidPtr,NULL,sizeof(msg),NULL,&msg);
+ checkStatus(r,"GetEventParameter");
+ msg->perform();
+ GCJ$Retainer::release(msg);
+ return noErr;
+}
+
+
+#pragma mark ------ Utility Functions ------
+
+static void funcFailed(const char *func,int r){
+ fprintf(stderr,"%s() failed (%d)\n",func,r);
+ exit(EXIT_FAILURE);
+}
+
+#pragma mark ------ CarbonPicture Methods ------
+
+#pragma mark ----- Carbon Surface Methods ----
+
+
+void Darwin$CarbonSurface::natSyncCursor(jint n) {
+ ThemeCursor c;
+ // see Carbon.java for what these numbers mean
+ switch(n) {
+ case 1: c = kThemeWatchCursor;
+ case 2: c = kThemePlusCursor;
+ case 3: c = kThemeIBeamCursor;
+ case 4: c = kThemePointingHandCursor;
+ case 5: c = kThemeOpenHandCursor;
+ case 6: c = kThemeResizeLeftRightCursor;
+ default: c = kThemeArrowCursor;
+ }
+ WC(SetThemeCursor)(c);
+}
+
+void Darwin$CarbonSurface::natSetInvisible(jboolean b) {
+ WindowRef window = (WindowRef) rawWindowRef;
+ fprintf(stderr,"Making window %s\n",b?"invisible":"visible");
+ if(b) WC(HideWindow)(window);
+ else WC(ShowWindow)(window);
+}
+
+void Darwin$CarbonSurface::nat_setMaximized(jboolean b) {
+ WindowRef window = (WindowRef) rawWindowRef;
+ Point ideal = { 10000, 10000 };
+ OSStatus r = WC(ZoomWindowIdeal)(window,(b?inZoomOut:inZoomIn),&ideal);
+ checkStatus(r,"ZoomWindowIdeal");
+}
+
+void Darwin$CarbonSurface::nat_setMinimized(jboolean b) {
+ WindowRef window = (WindowRef) rawWindowRef;
+ if((WC(IsWindowCollapsed)(window) ? 1 : 0) == (b ? 1 : 0)) return;
+ OSStatus r = WC(CollapseWindow)(window,b);
+ checkStatus(r,"CollapseWindow");
+}
+
+void Darwin$CarbonSurface::natSetTitleBarText(jstring js) {
+ SmartCFString s = js;
+ WindowRef window = (WindowRef) rawWindowRef;
+ WC(SetWindowTitleWithCFString)(window,s);
+}
+
+void Darwin$CarbonSurface::natToBack() {
+ WindowRef window = (WindowRef) rawWindowRef;
+ WC(SendBehind)(window,NULL);
+}
+
+void Darwin$CarbonSurface::natToFront() {
+ WindowRef window = (WindowRef) rawWindowRef;
+ fprintf(stderr,"SelectWindow)()\n");
+ WC(SelectWindow)(window);
+}
+
+#pragma mark ---- Window Event Handler ----
+static const EventTypeSpec eventTypeSpecs[] = {
+ // kEventClassCommand
+ // { kEventClassCommand, ??? },
+
+ // kEventClassWindow
+ { kEventClassWindow, kEventWindowUpdate },
+ { kEventClassWindow, kEventWindowBoundsChanged },
+ { kEventClassWindow, kEventWindowBoundsChanging },
+ { kEventClassWindow, kEventWindowActivated },
+ { kEventClassWindow, kEventWindowDeactivated },
+ { kEventClassWindow, kEventWindowZoomed },
+ { kEventClassWindow, kEventWindowCollapsed },
+ { kEventClassWindow, kEventWindowExpanded },
+ { kEventClassWindow, kEventWindowClose },
+ { kEventClassWindow, kEventWindowClosed },
+ { kEventClassWindow, kEventWindowDrawFrame },
+ { kEventClassWindow, kEventWindowDrawPart },
+
+ // kEventClassControl
+ { kEventClassControl, kEventControlApplyBackground },
+
+ // kEventClassKeyboard
+ { kEventClassKeyboard, kEventRawKeyDown },
+ { kEventClassKeyboard, kEventRawKeyRepeat },
+ { kEventClassKeyboard, kEventRawKeyUp },
+ { kEventClassKeyboard, kEventRawKeyModifiersChanged },
+
+ // kEventClassMouse
+ { kEventClassMouse, kEventMouseDown },
+ { kEventClassMouse, kEventMouseUp },
+ { kEventClassMouse, kEventMouseMoved },
+ { kEventClassMouse, kEventMouseDragged },
+ { kEventClassMouse, kEventMouseWheelMoved },
+};
+
+static OSStatus windowEventHandler(EventHandlerCallRef handler, EventRef e, void *userData) {
+ Darwin$CarbonSurface *surface = (Darwin$CarbonSurface*)userData;
+ UInt32 eKind = WC(GetEventKind)(e);
+ UInt32 eClass = WC(GetEventClass)(e);
+ OSStatus r;
+ char* ec = (char*)&eClass;
+ if (surface == NULL) return eventNotHandledErr;
+
+
+ switch(eClass) {
+ case kEventClassCommand:
+ switch(eKind) {
+ // TODO: handle menu items
+ }
+ break;
+ case kEventClassKeyboard:
+ switch(eKind) {
+ case kEventRawKeyDown:
+ case kEventRawKeyRepeat:
+ case kEventRawKeyUp: {
+ UInt32 keyCode;
+ jstring js;
+
+ r = WC(GetEventParameter)(e,kEventParamKeyCode,typeUInt32,NULL,sizeof(keyCode),NULL,&keyCode);
+ checkStatus(r,"GetEventParameter");
+
+ switch(keyCode) {
+ // These values were obtained by experimentation. I can't find any constants for them
+ // in the header files
+ case 126: js = JvNewStringLatin1("up"); break;
+ case 125: js = JvNewStringLatin1("down"); break;
+ case 124: js = JvNewStringLatin1("right"); break;
+ case 123: js = JvNewStringLatin1("left"); break;
+ case 122: js = JvNewStringLatin1("f1"); break;
+ case 120: js = JvNewStringLatin1("f2"); break;
+ case 99: js = JvNewStringLatin1("f3"); break;
+ case 118: js = JvNewStringLatin1("f4"); break;
+ case 96: js = JvNewStringLatin1("f5"); break;
+ case 97: js = JvNewStringLatin1("f6"); break;
+ case 98: js = JvNewStringLatin1("f7"); break;
+ case 100: js = JvNewStringLatin1("f8"); break;
+ case 101: js = JvNewStringLatin1("f9"); break;
+ case 109: js = JvNewStringLatin1("f10"); break;
+ case 103: js = JvNewStringLatin1("f11"); break;
+ case 111: js = JvNewStringLatin1("f12"); break;
+ case 105: js = JvNewStringLatin1("f13"); break;
+ case 114: js = JvNewStringLatin1("insert"); break;
+ case 117: js = JvNewStringLatin1("delete"); break;
+ case 116: js = JvNewStringLatin1("page_up"); break;
+ case 121: js = JvNewStringLatin1("page_down"); break;
+ case 115: js = JvNewStringLatin1("home"); break;
+ case 119: js = JvNewStringLatin1("end"); break;
+ case 71: js = JvNewStringLatin1("num_lock"); break;
+ case 53: js = JvNewStringLatin1("escape"); break;
+ case 51: js = JvNewStringLatin1("back_space"); break;
+ case 36: js = JvNewStringLatin1("enter"); break;
+ case 48: js = JvNewStringLatin1("tab"); break;
+ case 76: js = JvNewStringLatin1("enter"); break; // number pad enter
+ default: {
+ UInt32 size;
+ UInt32 modifiers = surface->modifiers;
+ r = WC(GetEventParameter)(e,kEventParamKeyUnicodes,typeUnicodeText,NULL,0,&size,NULL);
+ checkStatus(r,"GetEventParameter");
+ if(size == 0 || (modifiers & controlKey && size>sizeof(UniChar))) return eventNotHandledErr;
+
+ js = JvAllocString(size/sizeof(UniChar));
+ UniChar *buf = (UniChar*)JvGetStringChars(js);
+ r = WC(GetEventParameter)(e,kEventParamKeyUnicodes,typeUnicodeText,NULL,size,NULL,buf);
+ checkStatus(r,"GetEventParameter");
+
+ if(!buf[0]) return eventNotHandledErr; // shouldn't happen
+ // odd, when the ctrl key is pressed a-"`" become 1-31, this brings them back to the corect values
+ if(modifiers & controlKey && buf[0] < 32) buf[0] += 0x60;
+ break;
+ }
+ }
+
+ if(eKind == kEventRawKeyUp)
+ surface->KeyReleased(js);
+ else
+ surface->KeyPressed(js);
+ return noErr;
+ }
+ case kEventRawKeyModifiersChanged: {
+ const static struct {
+ UInt32 mask;
+ jstring ibexKey;
+ } modifiersTable[] = {
+ { shiftKey, JvNewStringLatin1("shift") },
+ { alphaLock, JvNewStringLatin1("caps_lock") },
+ { controlKey, JvNewStringLatin1("control") },
+ { optionKey, JvNewStringLatin1("alt") },
+ { kEventKeyModifierNumLockMask, JvNewStringLatin1("num_lock") },
+ { 0, 0 }
+ };
+
+ UInt32 oldModifiers = (UInt32) surface->modifiers;
+ UInt32 newModifiers;
+ r = WC(GetEventParameter)(e,kEventParamKeyModifiers,typeUInt32,NULL,sizeof(newModifiers),NULL,&newModifiers);
+ checkStatus(r,"GetEventParameter");
+ surface->modifiers = (jint) newModifiers;
+ UInt32 changedModifiers = oldModifiers ^ newModifiers;
+
+ for(int i=0;modifiersTable[i].mask;i++) {
+ UInt32 mask = modifiersTable[i].mask;
+ if(!(changedModifiers & mask)) continue;
+ if(newModifiers & mask)
+ surface->KeyPressed(modifiersTable[i].ibexKey);
+ else
+ surface->KeyReleased(modifiersTable[i].ibexKey);
+ }
+ return noErr;
+ }
+ }
+ break;
+ case kEventClassMouse:
+ // The default handler gets first dibs on mouse events
+ // (this catches the titlebar, resize box, etc)
+ r = WC(CallNextEventHandler)(handler, e);
+ if(r != eventNotHandledErr && eKind != kEventMouseMoved && eKind != kEventMouseDragged) return r;
+
+ switch(eKind) {
+ case kEventMouseMoved:
+ case kEventMouseDragged: {
+ WindowRef window = (WindowRef) surface->rawWindowRef;
+ Point p;
+ Rect rect;
+
+ r = WC(GetEventParameter)(e,kEventParamMouseLocation,typeQDPoint,NULL,sizeof(p),NULL,&p);
+ checkStatus(r,"GetEventParameter");
+ r = WC(GetWindowBounds)(window,kWindowContentRgn,&rect);
+ checkStatus(r,"GetWindowBounds");
+ surface->Move(p.h-rect.left,p.v-rect.top);
+ return noErr;
+ }
+ case kEventMouseDown:
+ case kEventMouseUp: {
+ EventMouseButton button;
+ UInt32 clickCount;
+ jint ibexButton;
+ r = WC(GetEventParameter)(e,kEventParamMouseButton,typeMouseButton,NULL,sizeof(button),NULL,&button);
+ checkStatus(r,"GetEventParameter");
+ r = WC(GetEventParameter)(e,kEventParamClickCount,typeUInt32,NULL,sizeof(clickCount),NULL,&clickCount);
+ checkStatus(r,"GetEventParameter");
+
+ switch(button) {
+ case kEventMouseButtonPrimary: ibexButton = 1; break;
+ case kEventMouseButtonSecondary: ibexButton = 2; break;
+ case kEventMouseButtonTertiary: ibexButton = 3; break;
+ default: return noErr;
+ }
+ if(eKind == kEventMouseDown) {
+ surface->Press(ibexButton);
+ } else {
+ surface->Release(ibexButton);
+ while(clickCount > 1) {
+ surface->DoubleClick(ibexButton);
+ clickCount-=2;
+ }
+ if(clickCount) surface->Click(ibexButton);
+ }
+ return noErr;
+ }
+ case kEventMouseWheelMoved: {
+ EventMouseWheelAxis axis;
+ SInt32 delta;
+ r = WC(GetEventParameter)(e,kEventParamMouseWheelAxis,typeMouseWheelAxis,NULL,sizeof(axis),NULL,&axis);
+ checkStatus(r,"GetEventParameter");
+ r = WC(GetEventParameter)(e,kEventParamMouseWheelDelta,typeSInt32,NULL,sizeof(delta),NULL,&delta);
+ checkStatus(r,"GetEventParameter");
+ switch(axis) {
+ case kEventMouseWheelAxisX: surface->HScroll((jint)(40 * delta)); break;
+ case kEventMouseWheelAxisY: surface->VScroll((jint)(40 * delta)); break;
+ }
+ return noErr;
+ }
+ }
+ break;
+
+ case kEventClassWindow: {
+ WindowRef window;
+ r = WC(GetEventParameter)(e,kEventParamDirectObject,typeWindowRef,NULL,sizeof(window),NULL,&window);
+ checkStatus(r,"kEventClassWindow/WC(GetEventParameter");
+
+ if((RawData*)window != surface->rawWindowRef) Darwin::abort(JvNewStringLatin1("window != surface->window"));
+
+ switch(eKind) {
+ case kEventWindowBoundsChanging: {
+ UInt32 attr;
+ Rect rect;
+
+ r = WC(GetEventParameter)(e,kEventParamAttributes,typeUInt32,NULL,sizeof(attr),NULL,&attr);
+ checkStatus(r,"kEventWindowBoundsChanged/GetEventParameter");
+
+ r = WC(GetEventParameter)(e,kEventParamCurrentBounds,typeQDRectangle,NULL,sizeof(rect),NULL,&rect);
+ checkStatus(r,"kEventWindowBoundsChanging/GetEventParameter");
+
+ if(attr & kWindowBoundsChangeSizeChanged) {
+ jint w = rect.right-rect.left;
+ jint h = rect.bottom-rect.top;
+
+ blit_lock();
+
+ surface->winWidth = w;
+ surface->winHeight = h;
+ surface->pendingResize = true;
+ surface->needsReshape();
+
+ blit_unlock();
+
+ surface->SizeChange(w,h);
+ if(attr & kWindowBoundsChangeUserResize && surface->maximized)
+ surface->Maximized(false);
+ }
+
+ if(attr & kWindowBoundsChangeOriginChanged) {
+ surface->PosChange(rect.left,rect.top);
+ }
+
+ return noErr;
+ }
+ case kEventWindowBoundsChanged: {
+ UInt32 attr;
+ r = WC(GetEventParameter)(e,kEventParamAttributes,typeUInt32,NULL,sizeof(attr),NULL,&attr);
+ checkStatus(r,"kEventWindowBoundsChanged/GetEventParameter");
+
+ if(attr & kWindowBoundsChangeSizeChanged) {
+ blit_lock();
+
+ surface->pendingResize = false;
+
+ blit_signal();
+ blit_unlock();
+ }
+ return noErr;
+ }
+ case kEventWindowActivated:
+ case kEventWindowDeactivated: {
+ surface->Focused(eKind == kEventWindowActivated);
+ return noErr;
+ }
+ case kEventWindowZoomed: {
+ surface->Maximized(true);
+ return noErr;
+ }
+ case kEventWindowCollapsed: {
+ surface->Minimized(true);
+ return noErr;
+ }
+ case kEventWindowExpanded: {
+ surface->Minimized(false);
+ return noErr;
+ }
+ case kEventWindowClose: {
+ surface->Close();
+ return noErr;
+ }
+ case kEventWindowClosed: {
+ GCJ$Retainer::release(surface);
+ return noErr;
+ }
+ case kEventWindowUpdate: {
+ fprintf(stderr,"kEventWindowUpdate: Should not be here\n");
+ abort();
+ }
+ }
+ }
+ break;
+ }
+ return eventNotHandledErr;
+}
+
+static OSStatus paintProc (
+ GDHandle device,
+ GrafPtr qdContext,
+ WindowRef window,
+ RgnHandle inClientPaintRgn,
+ RgnHandle outSystemPaintRgn,
+ void *userData
+) {
+ Darwin$CarbonSurface *surface = (Darwin$CarbonSurface*) userData;
+ Rect rect;
+ WC(GetRegionBounds)(inClientPaintRgn, &rect);
+ surface->Dirty(rect.left,rect.top,rect.right-rect.left,rect.bottom-rect.top);
+ return noErr;
+}
+
+void Darwin$CarbonSurface::natInit(jboolean framed) {
+ WindowRef window;
+ Rect rect;
+ WindowClass wc = framed ? kDocumentWindowClass : kPlainWindowClass;
+ // FIXME: unframed windows should appear in the window menu
+ // This probably needs a hack similar to whats in Cocoa.mm
+ WindowAttributes attr = kWindowStandardHandlerAttribute|
+ (framed ? kWindowInWindowMenuAttribute|kWindowStandardDocumentAttributes|kWindowLiveResizeAttribute : 0);
+ OSStatus r;
+ rect.top = rect.left = 0;
+ rect.bottom = rect.right = 10;
+ winWidth = winHeight = 10;
+
+ r = WC(CreateNewWindow)(wc, attr, &rect, &window);
+ checkStatus(r,"CreateNewWindow");
+
+ rawWindowRef = (RawData*) window;
+
+ GCJ$Retainer::retain(this); // Need to account for the EventHandlers pointer to us
+
+ r = InstallWindowEventHandler(window,windowEventHandlerUPP,sizeof(eventTypeSpecs)/sizeof(EventTypeSpec),eventTypeSpecs,this,NULL);
+ checkStatus(r,"InstallWindowEventHandler");
+
+ r = WC(InstallWindowContentPaintProc)(window,paintProcUPP,kWindowPaintProcOptionsNone,this);
+ checkStatus(r,"InstallWindowContentPaintProc");
+
+ WC(ShowWindow)(window);
+}
+
+void Darwin$CarbonSurface::natDispose() {
+ WindowRef window = (WindowRef) rawWindowRef;
+ WC(DisposeWindow)(window);
+}
+
+void Darwin$CarbonSurface::natSetIcon(org::ibex::graphics::Picture *_p) {
+}
+
+void Darwin$CarbonSurface::natSetLocation() {
+ WindowRef window = (WindowRef) rawWindowRef;
+ Rect rect;
+ jint x = root->x;
+ jint y = root->y;
+ OSStatus r = WC(GetWindowBounds)(window,kWindowStructureRgn,&rect);
+ checkStatus(r,"GetWindowBounds");
+ rect.bottom = y + (rect.bottom - rect.top);
+ rect.right = x + (rect.right - rect.left);
+ rect.top = y;
+ rect.left = x;
+ r = WC(SetWindowBounds)(window,kWindowStructureRgn,&rect);
+ checkStatus(r,"SetWindowBounds");
+ r = WC(ConstrainWindowToScreen)(window,kWindowStructureRgn,kWindowConstrainMoveRegardlessOfFit,NULL,NULL);
+ checkStatus(r,"ConstrainWindowToScreen");
+}
+
+void Darwin$CarbonSurface::natSetSize(jint w, jint h) {
+ WindowRef window = (WindowRef) rawWindowRef;
+ Rect rect;
+ OSStatus r = WC(GetWindowBounds)(window,kWindowContentRgn,&rect);
+ checkStatus(r,"GetWindowBounds");
+ rect.bottom = rect.top + h;
+ rect.right = rect.left + w;
+ r = WC(SetWindowBounds)(window,kWindowContentRgn,&rect);
+ checkStatus(r,"SetWindowBounds");
+ r = WC(ConstrainWindowToScreen)(window,kWindowStructureRgn,kWindowConstrainMoveRegardlessOfFit,NULL,NULL);
+ checkStatus(r,"ConstrainWindowToScreen");
+}
+
+void Darwin$CarbonSurface::natSetLimits(jint minw, jint minh, jint maxw, jint maxh) {
+ WindowRef window = (WindowRef) rawWindowRef;
+ const int maxMax = 32767;
+ const int minMinW = 80;
+ const int minMinH = 20;
+ HISize min,max;
+ min.width = minw > maxMax ? maxMax : (minw < minMinW ? minMinW : minw);
+ min.height = minh > maxMax ? maxMax : (minh < minMinH ? minMinH : minh);
+ max.width = maxw > maxMax ? maxMax : (maxw < minMinW ? minMinW : maxw);
+ max.height = maxh > maxMax ? maxMax : (maxh < minMinH ? minMinH : maxh);
+ OSStatus r = WC(SetWindowResizeLimits)(window,&min,&max);
+ checkStatus(r,"SetWindowResizeLimits");
+}
+
+
+#pragma mark ------ Carbon Methods ------
+void fileDialogEventHandler(NavEventCallbackMessage callBackSelector, NavCBRecPtr callBackParms, void *userData) {
+ Darwin$FileDialogHelper *helper = (Darwin$FileDialogHelper*) userData;
+ NavDialogRef dialog = callBackParms->context;
+ OSStatus r;
+ switch(callBackSelector) {
+ case kNavCBUserAction: {
+ NavUserAction action = WC(NavDialogGetUserAction)(dialog);
+ if(action == kNavUserActionNone || action == kNavUserActionCancel) {
+ helper->fileName = 0;
+ } else {
+ NavReplyRecord reply;
+ r = WC(NavDialogGetReply)(dialog,&reply);
+ checkStatus(r,"NavDialogGetReply");
+
+ AEKeyword keyword;
+ FSRef ref;
+ char buf[4096];
+ r = WC(AEGetNthPtr)(&reply.selection,1,typeFSRef,&keyword,NULL,&ref,sizeof(ref),NULL);
+ checkStatus(r,"AEGetNthPtr");
+ r = WC(FSRefMakePath)(&ref,(UInt8*)buf,sizeof(buf)-1);
+ checkStatus(r,"FSRefMakePath");
+ helper->fileName = JvNewStringLatin1(buf);
+ if(helper->save) helper->saveName = cfStringToJString(reply.saveFileName);
+ r = WC(NavDisposeReply)(&reply);
+ checkStatus(r,"NavDialogGetReply");
+ }
+ helper->sem->release();
+ break;
+ }
+ case kNavCBTerminate:
+ WC(NavDialogDispose)(dialog);
+ break;
+ }
+}
+
+void Darwin::natFileDialog(Darwin$FileDialogHelper *helper,jstring suggestion_, jboolean write) {
+ NavDialogRef dlg;
+ SmartCFString suggestion = suggestion_;
+ CFStringRef message = CFSTR("By selecting a file in this dialog you are giving this Ibex application permission to access that file.");
+ OSStatus r;
+ WindowRef window = WC(FrontWindow)();
+ NavDialogCreationOptions options;
+
+ WC(NavGetDefaultDialogCreationOptions)(&options);
+ options.optionFlags =
+ (options.optionFlags|kNavAllFilesInPopup|kNavSelectAllReadableItem|kNavDontUseCustomFrame|kNavDontConfirmReplacement)
+ &~(kNavAllowStationery|kNavAllowMultipleFiles);
+ options.clientName = CFSTR("Ibex");
+ if(write)
+ options.saveFileName = suggestion;
+ options.message = message;
+ options.modality = window ? kWindowModalityWindowModal : kWindowModalityAppModal;
+ options.parentWindow = window;
+
+ if(write)
+ r = WC(NavCreatePutFileDialog)(&options,0,0,fileDialogEventHandlerUPP,helper,&dlg);
+ else
+ r = WC(NavCreateGetFileDialog)(&options,NULL,fileDialogEventHandlerUPP,NULL,NULL,helper,&dlg);
+ checkStatus(r,"NavCreate(Get/Put)FileDialog");
+
+ WC(NavDialogRun)(dlg);
+}
+
+jstring Darwin::natGetClipBoard() {
+ ScrapRef scrap;
+ OSStatus r;
+ Size size,size2;
+
+ r = WC(GetCurrentScrap)(&scrap);
+ checkStatus(r,"GetCurrentScrap");
+
+ r = WC(GetScrapFlavorSize)( scrap, kScrapFlavorTypeUnicode, &size);
+ if(r == scrapFlavorNotFoundErr) return JvNewStringLatin1("");
+ checkStatus(r,"GetScrapFlavorSize");
+
+ unsigned int length = size/sizeof(UniChar);
+
+ jstring js = JvAllocString(length);
+ UniChar *buf = (UniChar*) JvGetStringChars(js);
+ size2 = size;
+ r = WC(GetScrapFlavorData)(scrap,kScrapFlavorTypeUnicode,&size2,buf);
+ if(r == scrapFlavorNotFoundErr);
+ checkStatus(r,"GetScrapFlavorData");
+ if(size2 != size) return JvNewStringLatin1("");
+
+ return js;
+}
+
+void Darwin::natSetClipBoard(jstring js) {
+ unsigned int length = js->length();
+ ScrapRef scrap;
+ OSStatus r;
+
+ r = WC(GetCurrentScrap)(&scrap);
+ checkStatus(r,"GetCurrentScrap");
+
+ r = WC(PutScrapFlavor)(scrap,kScrapFlavorTypeUnicode,0,sizeof(UniChar)*length,JvGetStringChars(js));
+ checkStatus(r,"PutScrapFlavor");
+}
+
+org::ibex::net::HTTP$Proxy *Darwin::natDetectProxy() {
+ org::ibex::net::HTTP$Proxy *p=0;
+ CFStringRef string;
+ CFNumberRef number;
+ SmartCFString smartString;
+ CFArrayRef exceptionList;
+ int i;
+
+ CFDictionaryRef proxyInfo = WC(SCDynamicStoreCopyProxies)(NULL);
+ if(proxyInfo == NULL) return 0;
+
+#define doproto(proto,var) \
+ number = (CFNumberRef) WC(CFDictionaryGetValue)(proxyInfo,kSCPropNetProxies ## proto ## Enable); \
+ if(number != NULL && WC(CFGetTypeID)(number) != WC(CFNumberGetTypeID)()) number = NULL; \
+ if(number && WC(CFNumberGetValue)(number,kCFNumberIntType,&i) && i) { \
+ string = (CFStringRef) WC(CFDictionaryGetValue)(proxyInfo, kSCPropNetProxies ## proto ## Proxy);\
+ if(string != NULL && WC(CFGetTypeID)(string) != WC(CFStringGetTypeID)()) string = NULL; \
+ number = (CFNumberRef) WC(CFDictionaryGetValue)(proxyInfo, kSCPropNetProxies ## proto ## Port); \
+ if(number != NULL && WC(CFGetTypeID)(number) != WC(CFNumberGetTypeID)()) number = NULL; \
+ if(string && number && WC(CFNumberGetValue)(number,kCFNumberIntType,&i) && i) { \
+ if(!p) p = new org::ibex::net::HTTP$Proxy(); \
+ p->var ## ProxyHost = cfStringToJString(string); \
+ p->var ## ProxyPort = i; \
+ } \
+ }
+doproto(HTTP,http)
+doproto(HTTPS,https)
+doproto(SOCKS,socks)
+#undef doproto
+
+ exceptionList = (CFArrayRef) WC(CFDictionaryGetValue)(proxyInfo,kSCPropNetProxiesExceptionsList);
+ if(exceptionList != NULL && WC(CFGetTypeID)(exceptionList) != WC(CFArrayGetTypeID)()) exceptionList = NULL;
+ if(p && exceptionList && WC(CFArrayGetCount)(exceptionList)) {
+ CFIndex count = WC(CFArrayGetCount)(exceptionList);
+ p->excluded = (JArray<java::lang::String*>*)
+ JvNewObjectArray(count,&java::lang::String::class$,0);
+ for(i=0;i<count;i++) {
+ string = (CFStringRef) WC(CFArrayGetValueAtIndex)(exceptionList,i);
+ if(string != NULL && WC(CFGetTypeID)(string) != WC(CFStringGetTypeID)()) string = NULL;
+ elements(p->excluded)[i] = string ? cfStringToJString(string) : JvNewStringLatin1("(null)");
+ }
+ }
+ WC(CFRelease)(proxyInfo);
+
+ return p;
+/*
+ exceptionList = [proxyInfo objectForKey: (NSString*) kSCPropNetProxiesExceptionsList];
+ if(p && exceptionList && [exceptionList count]) {
+ NSLog(@"excl: %@",exceptionList);
+ p->excluded = (JArray<java::lang::String*>*)
+ JvNewObjectArray([exceptionList count],&java::lang::String::class$,0);
+ for(i=0;i<[exceptionList count];i++)
+ elements(p->excluded)[i] = [[exceptionList objectAtIndex: i] jstring];
+ }
+ return p;
+ */
+
+/*
+ using org::ibex::Proxy;
+ AutoARP pool;
+ Proxy *p=0;
+ NSString *host;
+ NSNumber *port;
+ NSArray *exceptionList;
+ unsigned int i;
+ NSDictionary *proxyInfo = (NSDictionary*)WC(SCDynamicStoreCopyProxies)(NULL);
+
+ if(proxyInfo == NULL) return 0;
+ if([[proxyInfo objectForKey: (NSString*) kSCPropNetProxiesHTTPEnable] boolValue]) {
+ host = [proxyInfo objectForKey: (NSString*) kSCPropNetProxiesHTTPProxy];
+ port = [proxyInfo objectForKey: (NSString*) kSCPropNetProxiesHTTPPort];
+ if(host && [port intValue]) {
+ if(!p) p = new Proxy();
+ p->httpProxyHost = [host jstring];
+ p->httpProxyPort = [port intValue];
+ }
+ }
+ if([[proxyInfo objectForKey: (NSString*) kSCPropNetProxiesHTTPSEnable] boolValue]) {
+ host = [proxyInfo objectForKey: (NSString*) kSCPropNetProxiesHTTPSProxy];
+ port = [proxyInfo objectForKey: (NSString*) kSCPropNetProxiesHTTPSPort];
+ if(host && [port intValue]) {
+ if(!p) p = new Proxy();
+ p->httpsProxyHost = [host jstring];
+ p->httpsProxyPort = [port intValue];
+ }
+ }
+ if([[proxyInfo objectForKey: (NSString*) kSCPropNetProxiesSOCKSEnable] boolValue]) {
+ host = [proxyInfo objectForKey: (NSString*) kSCPropNetProxiesSOCKSProxy];
+ port = [proxyInfo objectForKey: (NSString*) kSCPropNetProxiesSOCKSPort];
+ if(host && [port intValue]) {
+ if(!p) p = new Proxy();
+ p->socksProxyHost = [host jstring];
+ p->socksProxyPort = [port intValue];
+ }
+ }
+
+ exceptionList = [proxyInfo objectForKey: (NSString*) kSCPropNetProxiesExceptionsList];
+ if(p && exceptionList && [exceptionList count]) {
+ NSLog(@"excl: %@",exceptionList);
+ p->excluded = (JArray<java::lang::String*>*)
+ JvNewObjectArray([exceptionList count],&java::lang::String::class$,0);
+ for(i=0;i<[exceptionList count];i++)
+ elements(p->excluded)[i] = [[exceptionList objectAtIndex: i] jstring];
+ }
+ return p;
+*/
+}
+
+jint Darwin::cgScreenWidth() {
+ return WC(CGDisplayPixelsWide)(((CGDirectDisplayID)0));
+}
+
+jint Darwin::cgScreenHeight() {
+ return WC(CGDisplayPixelsHigh)(((CGDirectDisplayID)0));
+}
+
+void Darwin::_newBrowserWindow(jstring js) {
+ SmartCFString cfs = js;
+ CFURLRef url = WC(CFURLCreateWithString)(WC(kCFAllocatorDefault),cfs,NULL);
+ SmartCFString scheme = WC(CFURLCopyScheme)(url);
+ if(scheme.equals(CFStringRef("http")))
+ WC(LSOpenCFURLRef)(url,NULL);
+ WC(CFRelease)(url);
+}
+
+void Darwin::natInit() {
+ OSStatus r;
+
+ if(pthread_mutex_init(&blit_mutex,NULL) != 0) funcFailed("pthread_mutex_init");
+ if(pthread_cond_init(&blit_cond,NULL) != 0) funcFailed("pthread_cond_init");
+
+ carbonMessageEventHandlerUPP = WC(NewEventHandlerUPP)(carbonMessageEventHandler);
+ windowEventHandlerUPP = WC(NewEventHandlerUPP)(windowEventHandler);
+ fileDialogEventHandlerUPP = WC(NewNavEventUPP)(fileDialogEventHandler);
+ paintProcUPP = WC(NewWindowPaintUPP)(paintProc);
+
+ #ifdef Ibex_CARBON_NO_BUNDLE_HACK
+ {
+ ProcessSerialNumber currentProcess = { 0, kCurrentProcess };
+
+ ::fprintf(stderr,"Doing Ibex_CARBON_NO_BUNDLE_HACK\n");
+ r = WC(GetCurrentProcess)(¤tProcess);
+ checkStatus(r,"GetCurrentProcess");
+ r = WC(CPSEnableForegroundOperation)( ¤tProcess );
+ checkStatus(r,"CPSEnableForegroundOperation");
+ r = WC(CPSSetFrontProcess)(¤tProcess);
+ checkStatus(r,"CPSSetFrontProcess");
+ }
+ #else
+ {
+ IBNibRef nib;
+ r = CreateNibReference(CFSTR("MainMenu"), &nib);
+ checkStatus(r,"CreateNibReference");
+ r = SetMenuBarFromNib(nib, CFSTR("MenuBar"));
+ checkStatus(r,"SetMenuBarFromNib");
+ DisposeNibReference(nib);
+
+ // FEATURE: Install menu event handler
+ }
+ #endif
+}
+
+void Darwin::runApplicationEventLoop() {
+ WC(RunApplicationEventLoop)();
+ WC(ExitToShell)();
+}
+
+#pragma mark ------ OpenGL Functions -----
+
+void Darwin$CarbonOpenGL::activateSharedContext() {
+ AGLContext ctx = (AGLContext) rawSharedContext;
+ WC(aglSetCurrentContext)(ctx);
+}
+
+jboolean Darwin$CarbonOpenGL::initPixelFormat() {
+ GLint attr[] = {
+ AGL_NO_RECOVERY,
+ AGL_RGBA,
+ AGL_DEPTH_SIZE, 32,
+ AGL_RED_SIZE, 8,
+ AGL_GREEN_SIZE, 8,
+ AGL_RED_SIZE, 8,
+ AGL_ALPHA_SIZE, 8,
+ AGL_NONE
+ };
+
+ rawPixelFormat = (RawData*) WC(aglChoosePixelFormat)(NULL,0,attr);
+ return rawPixelFormat != 0;
+}
+
+void Darwin$CarbonOpenGL::initSharedContext() {
+ AGLPixelFormat fmt = (AGLPixelFormat) rawPixelFormat;
+ rawSharedContext = (RawData*) WC(aglCreateContext)(fmt,NULL);
+ checkStatus(rawSharedContext,"aglCreateContext");
+}
+
+void Darwin$GLCarbonPixelBuffer::natInit() {
+ WindowClass wc = kPlainWindowClass;
+ WindowAttributes attr = 0;
+ WindowRef window;
+ Rect rect;
+ OSStatus r;
+ AGLContext ctx,shared;
+ AGLPixelFormat fmt;
+ GLboolean b;
+ GLuint tex;
+ GLuint target;
+
+ rect.top = rect.left = 0;
+ rect.right = width + rect.left;
+ rect.bottom = height + rect.top;
+
+ r = WC(CreateNewWindow)(wc,attr,&rect,&window);
+ checkStatus(r,"CreateNewWindow");
+
+ shared = (AGLContext) gl->rawSharedContext;
+ fmt = (AGLPixelFormat) gl->rawPixelFormat;
+ ctx = WC(aglCreateContext)(fmt,shared);
+ checkStatus(ctx, "aglCreateContext");
+
+ b = WC(aglSetDrawable)(ctx,WC(GetWindowPort)(window));
+ checkStatus(b,"aglSetDrawable");
+
+ WC(aglSetCurrentContext)(ctx);
+ WC(aglUpdateContext)(ctx);
+ drawableInit(width,height);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ WC(aglSetCurrentContext)(shared);
+ target = rectTexture ? GL_TEXTURE_RECTANGLE_EXT : GL_TEXTURE_2D;
+ glEnable(target);
+ glGenTextures(1,&tex);
+ glBindTexture(target,tex);
+ glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ WC(aglSurfaceTexture) (shared, target, GL_RGBA, ctx);
+ checkGLError();
+ glDisable(target);
+
+ //WC(ShowWindow)(window);
+ textureName = (jint) tex;
+ rawWindowRef = (RawData*) window;
+ rawCTX = (RawData*) ctx;
+}
+
+void Darwin$GLCarbonPixelBuffer::activateContext() {
+ AGLContext ctx = (AGLContext) rawCTX;
+ WC(aglSetCurrentContext)(ctx);
+}
+
+void Darwin$GLCarbonPixelBuffer::natCleanup(RawData* rawWindowRef, RawData* rawCTX) {
+ WindowRef window = (WindowRef) rawWindowRef;
+ AGLContext ctx = (AGLContext) rawCTX;
+ WC(aglDestroyContext)(ctx);
+ WC(DisposeWindow)(window);
+}
+
+void Darwin$GLCarbonSurface::clear() {
+ AGLContext ctx = (AGLContext) rawCTX;
+ WC(aglSetCurrentContext)(ctx);
+ glColor4f(1.0f,1.0f,1.0f,1.0f);
+
+ glMatrixMode (GL_MODELVIEW);
+ glPushMatrix ();
+ glLoadIdentity ();
+ glMatrixMode (GL_PROJECTION);
+ glPushMatrix ();
+ glLoadIdentity ();
+ glBegin (GL_QUADS);
+ glVertex3i (-1, -1, -1);
+ glVertex3i (1, -1, -1);
+ glVertex3i (1, 1, -1);
+ glVertex3i (-1, 1, -1);
+ glEnd ();
+ glPopMatrix ();
+ glMatrixMode (GL_MODELVIEW);
+ glPopMatrix ();
+}
+
+void Darwin$GLCarbonSurface::flush() {
+ AGLContext ctx = (AGLContext) rawCTX;
+ WC(aglSetCurrentContext)(ctx);
+ glFlush();
+}
+
+// blit_lock is assumed to be held
+void Darwin$GLCarbonSurface::reshape(jint w, jint h) {
+ AGLContext ctx = (AGLContext) rawCTX;
+ WC(aglSetCurrentContext)(ctx);
+ WC(aglUpdateContext)(ctx);
+
+ glViewport(0,0,w,h);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(0,w,h,0,-1,1);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glTranslatef (0.375f, 0.375f, 0.0f);
+ checkGLError();
+}
+
+// blit_lock is assumed to be held
+void Darwin$GLCarbonSurface::natBlit(Darwin$GLCarbonPixelBuffer *db, jint sx1, jint sy1, jint dx1, jint dy1, jint dx2, jint dy2) {
+ AGLContext ctx = (AGLContext) rawCTX;
+ int sx2 = sx1 + (dx2-dx1);
+ int sy2 = sy1 + (dy2-dy1);
+ jint w, h;
+ db->activateContext();
+ glFlush();
+ checkGLError();
+
+ WC(aglSetCurrentContext)(ctx);
+ checkGLError();
+
+ if(db->rectTexture) {
+ glEnable(GL_TEXTURE_RECTANGLE_EXT);
+ checkGLError();
+ glBindTexture(GL_TEXTURE_RECTANGLE_EXT, db->textureName);
+ checkGLError();
+ glBegin(GL_QUADS);
+ glTexCoord2i (sx1, sy1 );
+ glVertex3i (dx1, dy1, 0);
+ glTexCoord2i (sx2, sy1 );
+ glVertex3i (dx2, dy1, 0);
+ glTexCoord2i (sx2, sy2 );
+ glVertex3i (dx2, dy2, 0);
+ glTexCoord2i (sx1, sy2 );
+ glVertex3i (dx1, dy2, 0);
+ glEnd();
+ checkGLError();
+ glDisable(GL_TEXTURE_RECTANGLE_EXT);
+ checkGLError();
+ } else {
+ float tx1,ty1,tx2,ty2; // normalized texture coords
+ tx1 = (float) sx1 / (float) db->width;
+ ty1 = (float) sy1 / (float) db->height;
+ tx2 = (float) sx2 / (float) db->width;
+ ty2 = (float) sy2 / (float) db->height;
+
+ glColor4f(1.0f,1.0f,1.0f,1.0f);
+ glEnable(GL_TEXTURE_2D);
+ glBindTexture(GL_TEXTURE_2D, db->textureName);
+ checkGLError();
+ glBegin(GL_QUADS);
+ glTexCoord2f (tx1, ty1 );
+ glVertex3i (dx1, dy1, 0);
+ glTexCoord2f (tx2, ty1 );
+ glVertex3i (dx2, dy1, 0);
+ glTexCoord2f (tx2, ty2 );
+ glVertex3i (dx2, dy2, 0);
+ glTexCoord2f (tx1, ty2 );
+ glVertex3i (dx1, dy2, 0);
+ glEnd();
+ glDisable(GL_TEXTURE_2D);
+ checkGLError();
+ }
+}
+
+void Darwin$GLCarbonSurface::natInit() {
+ WindowRef window = (WindowRef) rawWindowRef;
+ AGLContext ctx,shared;
+ AGLPixelFormat fmt;
+ GLboolean b;
+
+ shared = (AGLContext) gl->rawSharedContext;
+ fmt = (AGLPixelFormat) gl->rawPixelFormat;
+ ctx = WC(aglCreateContext)(fmt,shared);
+ checkStatus(ctx, "aglCreateContext");
+
+ b = WC(aglSetDrawable)(ctx,WC(GetWindowPort)(window));
+ checkStatus(b,"aglSetDrawable");
+
+ WC(aglSetCurrentContext)(ctx);
+ glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
+
+ glClearColor (1.0f, 1.0f, 1.0f, 1.0f);
+ glClearDepth( 0.0f );
+
+ needsReshape();
+
+ rawCTX = (RawData*)ctx;
+}
+
+void Darwin$GLCarbonSurface::natDispose() {
+ AGLContext ctx = (AGLContext) rawCTX;
+ WC(aglDestroyContext)(ctx);
+ Darwin$CarbonSurface::natDispose();
+}
+
+} } } // end namepsace org::ibex::plat
+
+
+
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [LGPL]
+// Authors: Brian Alliet and Evan Jones
+
+package org.ibex.plat;
+
+import gnu.gcj.RawData;
+import org.ibex.util.*;
+import org.ibex.js.*;
+import org.ibex.graphics.*;
+import org.ibex.core.*;
+import org.ibex.net.*;
+
+public class Darwin extends POSIX {
+ public static void main(String[] s) throws Exception { org.ibex.core.Main.main(s); }
+ private static final Class openGLClass = OpenGL.class;
+ static Darwin singleton;
+ private CarbonOpenGL openGL;
+ boolean jaguar; // true if we are on OS X >= 10.2
+
+ // General Methods
+ protected String _getAltKeyName() { return "Option"; }
+ protected boolean _needsAutoClick() { return false; }
+ protected boolean _needsAutoDoubleClick() { return false; }
+ protected String getDescriptiveName() { return "GCJ Darwin Binary"; }
+ protected boolean _isCaseSensitive() { return false; /* Well, not always, could be UFS */ }
+
+
+ // Native Methods
+ protected int _getScreenWidth() { return cgScreenWidth(); }
+ protected int _getScreenHeight() { return cgScreenHeight(); }
+ private native static int cgScreenWidth();
+ private native static int cgScreenHeight();
+ protected native void _newBrowserWindow(String url);
+ protected native HTTP.Proxy natDetectProxy();
+ private native void natInit();
+
+ private native String natGetClipBoard();
+ private native void natSetClipBoard(String text);
+ protected void _setClipBoard(final String text) { CarbonMessage.add(new CarbonMessage() { public void perform() { natSetClipBoard(text); } }); }
+ protected String _getClipBoard() {
+ final Semaphore sem = new Semaphore();
+ final String[] result = new String[1]; // Kind of like a pointer
+ CarbonMessage.add(new CarbonMessage() { public void perform() { result[0] = natGetClipBoard(); sem.release(); } });
+ sem.block();
+ return result[0];
+ }
+
+ private static class FileDialogHelper {
+ public FileDialogHelper(boolean save) { this.save = save; }
+ public boolean save;
+ public Semaphore sem = new Semaphore();
+ public String fileName;
+ public String saveName;
+ }
+ private native void natFileDialog(FileDialogHelper helper, String suggestedFileName, boolean write);
+ protected String _fileDialog(final String fn, final boolean w) {
+ final FileDialogHelper helper = new FileDialogHelper(w);
+ CarbonMessage.add(new CarbonMessage() { public void perform() { natFileDialog(helper,fn,w); } });
+ helper.sem.block();
+ if(w)
+ return helper.fileName + "/" + helper.saveName;
+ else
+ return helper.fileName;
+ }
+
+
+ static void abort(String err) {
+ throw new Error(err);
+ }
+
+ public Darwin() {
+ synchronized(Darwin.class) {
+ if(singleton != null) abort("Tried to instansiate Darwin more than once");
+ singleton = this;
+ }
+ }
+
+ protected synchronized HTTP.Proxy _detectProxy() {
+ return natDetectProxy();
+ }
+
+ private static native final boolean isJaguar();
+
+ public void postInit() {
+ jaguar = isJaguar();
+ try {
+ openGL = new CarbonOpenGL();
+ openGL.init();
+ } catch(OpenGL.NotSupportedException e) {
+ Log.info(this,"WARNING: OpenGL support not available: " + e);
+ // FEATURE: fall back to quartz 2d
+ throw new Error("No OpenGL support");
+ }
+ natInit();
+ }
+
+ protected Scheduler _getScheduler() { return new DarwinScheduler(); }
+ protected native void runApplicationEventLoop();
+ private class DarwinScheduler extends org.ibex.util.Scheduler {
+ public void run() {
+ new Thread() { public void run() { defaultRun(); } }.start();
+ runApplicationEventLoop();
+ }
+ }
+
+ private final class CarbonOpenGL extends OpenGL {
+ public RawData rawPixelFormat;
+ public RawData rawSharedContext;
+ public int maxAglSurfaceTexSize;
+ public int maxSurfaceWidth;
+ public int maxSurfaceHeight;
+
+ private native boolean initPixelFormat();
+ private native void initSharedContext();
+
+ public CarbonOpenGL() throws NotSupportedException {
+ if(!jaguar)
+ throw new NotSupportedException("OpenGL requires Mac OS X 10.2 or greater");
+ if(!initPixelFormat())
+ throw new NotSupportedException("Couldn't get an acceptable pixel format");
+ initSharedContext();
+ }
+
+ public void init() throws NotSupportedException {
+ super.init();
+ maxAglSurfaceTexSize = rectangularTextures ? maxRectTexSize : maxTexSize;
+ if(renderer.startsWith("ATI Radeon 7500")) {
+ maxAglSurfaceTexSize = Math.min(rectangularTextures ? 1600 : 1024,maxAglSurfaceTexSize);
+ Log.info(this,"Working around Radeon 7500 bug: maxAglSurfaceTexSize: " + maxAglSurfaceTexSize);
+ }
+ maxSurfaceWidth = maxSurfaceHeight = maxAglSurfaceTexSize;
+ }
+ protected native void activateSharedContext();
+ }
+
+ static abstract class CarbonSurface extends Surface.DoubleBufferedSurface {
+ RawData rawWindowRef;
+ int modifiers;
+ int winWidth;
+ int winHeight;
+
+ boolean pendingResize;
+
+ private native void natSetInvisible(boolean i);
+ public void setInvisible(final boolean i) { CarbonMessage.add(new CarbonMessage() { public void perform() { natSetInvisible(i); } }); }
+ private native void nat_setMaximized(boolean b);
+ public void _setMaximized(final boolean b) { CarbonMessage.add(new CarbonMessage() { public void perform() { nat_setMaximized(b); } }); }
+ private native void nat_setMinimized(boolean b);
+ public void _setMinimized(final boolean b) { CarbonMessage.add(new CarbonMessage() { public void perform() { nat_setMinimized(b); } }); }
+ private native void natSetIcon(Picture p);
+ public void setIcon(final Picture p) { CarbonMessage.add(new CarbonMessage() { public void perform() { natSetIcon(p); } }); }
+ private native void natSetTitleBarText(String s);
+ public void setTitleBarText(final String s) { CarbonMessage.add(new CarbonMessage() { public void perform() { natSetTitleBarText(s); } }); }
+ private native void natSetSize(int w, int h);
+ public void _setSize(final int w, final int h) { CarbonMessage.add(new CarbonMessage() { public void perform() { natSetSize(w,h); } }); }
+ private native void natSetLocation();
+ public void setLocation() { CarbonMessage.add(new CarbonMessage() { public void perform() { natSetLocation(); } }); }
+ private native void natToFront();
+ public void toFront() { CarbonMessage.add(new CarbonMessage() { public void perform() { natToFront(); } }); }
+ private native void natToBack();
+ public void toBack() { CarbonMessage.add(new CarbonMessage() { public void perform() { natToBack(); } }); }
+ private native void natSetLimits(int minWidth, int minHeight, int maxWidth, int maxHeight);
+ public void setLimits(final int mnw, final int mnh, final int mxw, final int mxh) {
+ if(Darwin.singleton.jaguar)
+ CarbonMessage.add(new CarbonMessage() { public void perform() { natSetLimits(mnw,mnh,mxw,mxh); } });
+ }
+ private native void natSyncCursor(int n);
+ public void syncCursor() {
+ int n;
+ if(cursor.equals("default")) n = 0;
+ else if(cursor.equals("wait")) n = 1;
+ else if(cursor.equals("crosshair")) n = 2;
+ else if(cursor.equals("text")) n = 3;
+ else if(cursor.equals("hand")) n = 4;
+ else if(cursor.equals("move")) n = 5;
+ else if(cursor.equals("east") || cursor.equals("west")) n = 6;
+ else n = 0;
+ final int n_ = n;
+ CarbonMessage.add(new CarbonMessage() { public void perform() { natSyncCursor(n_); } });
+ }
+
+ /* Drawing stuff */
+ public abstract void blit(PixelBuffer s, int sx, int sy, int dx, int dy, int dx2, int dy2);
+
+ public final void _dispose() { CarbonMessage.add(new CarbonMessage() { public void perform() { natDispose(); } }); }
+ public native void natDispose();
+
+ public final native void natInit(boolean framed);
+
+ public CarbonSurface(Box root, final boolean framed) {
+ super(root);
+ final Semaphore sem = new Semaphore();
+ CarbonMessage.add(new CarbonMessage() { public void perform() { CarbonSurface.this.natInit(framed); sem.release(); } });
+ sem.block();
+ }
+
+ public void needsReshape() { }
+ protected static native void blitLock();
+ protected static native void blitUnlock();
+ protected static native void blitWait();
+ }
+
+ static class GLCarbonPixelBuffer extends OpenGL.GLPixelBuffer {
+ RawData rawCTX;
+ RawData rawWindowRef;
+ int textureName;
+ boolean rectTexture;
+ CarbonOpenGL gl;
+
+ private native void natInit();
+ private static native void natCleanup(RawData rawWindowRef, RawData rawCTX);
+
+
+ private static final int fixupDimension(CarbonOpenGL gl, int n) {
+ if(!gl.rectangularTextures) n = OpenGL.roundToPowerOf2(n);
+ return Math.min(n,gl.maxAglSurfaceTexSize);
+ }
+ public GLCarbonPixelBuffer(int w, int h, final CarbonOpenGL gl) {
+ super(fixupDimension(gl,w),fixupDimension(gl,h));
+ this.gl = gl;
+ rectTexture = gl.hasRectangularTextures();
+ final Semaphore sem = new Semaphore();
+ CarbonMessage.add(new CarbonMessage() { public void perform() { GLCarbonPixelBuffer.this.natInit(); sem.release(); } });
+ sem.block();
+ }
+ public native void activateContext();
+ protected void finalize() {
+ CarbonMessage.add(new CarbonMessage() { public void perform() { natCleanup(rawWindowRef,rawCTX); } });
+ gl.deleteTexture(textureName);
+ }
+ }
+
+ static class GLCarbonSurface extends CarbonSurface {
+ RawData rawCTX;
+ CarbonOpenGL gl;
+ boolean needsReshape;
+
+ private final native void natInit();
+ private final native void flush();
+ private final native void clear();
+
+ public GLCarbonSurface(Box root, boolean framed, CarbonOpenGL gl) {
+ super(root,framed);
+ this.gl = gl;
+ natInit();
+ }
+
+ public void setLimits(int mnw,int mnh, int mxw, int mxh) {
+ mxw = Math.min(mxw,gl.maxSurfaceWidth);
+ mxh = Math.min(mxh,gl.maxSurfaceHeight);
+ super.setLimits(mnw,mnh,mxw,mxh);
+ }
+
+ public void _setSize(int w, int h) {
+ w = Math.min(w,gl.maxSurfaceWidth);
+ h = Math.min(h,gl.maxSurfaceWidth);
+ super._setSize(w,h);
+ }
+
+ private native void natBlit(GLCarbonPixelBuffer db, int sx, int sy, int dx, int dy, int dx2, int dy2);
+ public void blit(PixelBuffer db, int sx, int sy, int dx, int dy, int dx2, int dy2) {
+ natBlit((GLCarbonPixelBuffer)db,sx,sy,dx,dy,dx2,dy2);
+ }
+
+
+ // The blit_lock ensures the window size does not change through the entire blit operation.
+ public void render() {
+ /*
+ blitLock();
+ while(pendingResize) blitWait();
+ */
+ if(needsReshape) {
+ needsReshape = false;
+
+ reshape(winWidth,winHeight);
+ clear();
+ Dirty(0,0,winWidth,winHeight);
+ }
+ super.render();
+ flush();
+ /*
+ blitUnlock();
+ */
+ }
+
+ private native void reshape(int w, int h);
+ // blit_lock is assumed to be held
+ public void needsReshape() { needsReshape = true; }
+
+ public native void natDispose();
+ }
+
+ /*private class QZCarbonPixelBuffer extends PixelBuffer {
+
+ public QZCarbonPixelBuffer(int width, int height) {
+ }
+ }
+ private class QZCarbonSurface extends CarbonSurface {
+ public QZCarbonSurface(Box root, boolean framed) {
+ super(b,root);
+ }
+ public native void blit(PixelBuffer s, int sx, int sy, int dx, int dy, int dx2, int dy2);
+ }
+
+ private class QZCarbonPicture extends Picture {
+ int width;
+ int height;
+
+ public final int getWidth() { return width; }
+ public final int getHeight() { return height; }
+
+ public QZCarbonPicture(int w, int h) {
+ this.width = w;
+ this.height = h;
+ }
+ }*/
+
+ protected PixelBuffer _createPixelBuffer(int w, int h, Surface owner) {
+ if(openGL != null)
+ return new GLCarbonPixelBuffer(w,h,openGL);
+ else
+ return /*new QZCarbonPixelBuffer(w,h)*/ null;
+ }
+ protected Surface _createSurface(Box b, boolean framed) {
+ if(openGL != null)
+ return new GLCarbonSurface(b,framed, openGL);
+ else
+ return /*new QZCarbonSufrace(b,framed)*/ null;
+ }
+ protected Picture _createPicture(JS r) {
+ if(openGL != null)
+ return openGL._createPicture(r, true);
+ else
+ return /*new QZCarbonPicture(data,w,h);*/ null;
+ }
+ protected org.ibex.graphics.Font.Glyph _createGlyph(org.ibex.graphics.Font f, char c) {
+ if(openGL != null)
+ return openGL._createGlyph(f, c);
+ else
+ return super.createGlyph(f, c);
+ }
+
+ /* A message that is sent through the carbon event queue */
+ private static abstract class CarbonMessage {
+ public abstract void perform();
+
+ static { natInit(); }
+ public static native void natInit();
+ public static native void add(CarbonMessage m);
+ }
+}
--- /dev/null
+// stuff needed from Mac OS headers that ARE NOT in /usr/include
+// this stuff usually comes from /System/Library/Frameworks/*/Headers
+
+#include <math.h>
+
+typedef u_int8_t uint8_t;
+typedef u_int16_t uint16_t;
+typedef u_int32_t uint32_t;
+typedef u_int64_t uint64_t;
+
+
+
+typedef int8_t int_least8_t;
+typedef int16_t int_least16_t;
+typedef int32_t int_least32_t;
+typedef int64_t int_least64_t;
+typedef uint8_t uint_least8_t;
+typedef uint16_t uint_least16_t;
+typedef uint32_t uint_least32_t;
+typedef uint64_t uint_least64_t;
+
+
+
+typedef int8_t int_fast8_t;
+typedef int16_t int_fast16_t;
+typedef int32_t int_fast32_t;
+typedef int64_t int_fast64_t;
+typedef uint8_t uint_fast8_t;
+typedef uint16_t uint_fast16_t;
+typedef uint32_t uint_fast32_t;
+typedef uint64_t uint_fast64_t;
+typedef long long intmax_t;
+typedef unsigned long long uintmax_t;
+
+
+
+extern "C" {
+
+
+typedef unsigned char UInt8;
+typedef signed char SInt8;
+typedef unsigned short UInt16;
+typedef signed short SInt16;
+typedef unsigned long UInt32;
+typedef signed long SInt32;
+
+struct wide {
+ SInt32 hi;
+ UInt32 lo;
+};
+typedef struct wide wide;
+struct UnsignedWide {
+ UInt32 hi;
+ UInt32 lo;
+};
+typedef struct UnsignedWide UnsignedWide;
+ typedef signed long long SInt64;
+ typedef unsigned long long UInt64;
+typedef long Fixed;
+typedef Fixed * FixedPtr;
+typedef long Fract;
+typedef Fract * FractPtr;
+typedef unsigned long UnsignedFixed;
+typedef UnsignedFixed * UnsignedFixedPtr;
+typedef short ShortFixed;
+typedef ShortFixed * ShortFixedPtr;
+typedef float Float32;
+typedef double Float64;
+struct Float80 {
+ SInt16 exp;
+ UInt16 man[4];
+};
+typedef struct Float80 Float80;
+
+struct Float96 {
+ SInt16 exp[2];
+ UInt16 man[4];
+};
+typedef struct Float96 Float96;
+struct Float32Point {
+ Float32 x;
+ Float32 y;
+};
+typedef struct Float32Point Float32Point;
+typedef char * Ptr;
+typedef Ptr * Handle;
+typedef long Size;
+typedef SInt16 OSErr;
+typedef SInt32 OSStatus;
+typedef void * LogicalAddress;
+typedef const void * ConstLogicalAddress;
+typedef void * PhysicalAddress;
+typedef UInt8 * BytePtr;
+typedef UInt32 ByteCount;
+typedef UInt32 ByteOffset;
+typedef SInt32 Duration;
+typedef UnsignedWide AbsoluteTime;
+typedef UInt32 OptionBits;
+typedef UInt32 ItemCount;
+typedef UInt32 PBVersion;
+typedef SInt16 ScriptCode;
+typedef SInt16 LangCode;
+typedef SInt16 RegionCode;
+typedef unsigned long FourCharCode;
+typedef FourCharCode OSType;
+typedef FourCharCode ResType;
+typedef OSType * OSTypePtr;
+typedef ResType * ResTypePtr;
+typedef unsigned char Boolean;
+typedef long ( * ProcPtr)();
+typedef void ( * Register68kProcPtr)();
+
+
+
+
+typedef ProcPtr UniversalProcPtr;
+
+
+typedef ProcPtr * ProcHandle;
+typedef UniversalProcPtr * UniversalProcHandle;
+enum {
+ noErr = 0
+};
+
+enum {
+ kNilOptions = 0
+};
+
+
+enum {
+ kVariableLengthArray = 1
+};
+
+enum {
+ kUnknownType = 0x3F3F3F3F
+};
+typedef UInt32 UnicodeScalarValue;
+typedef UInt32 UTF32Char;
+typedef UInt16 UniChar;
+typedef UInt16 UTF16Char;
+typedef UInt8 UTF8Char;
+typedef UniChar * UniCharPtr;
+typedef UInt32 UniCharCount;
+typedef UniCharCount * UniCharCountPtr;
+typedef unsigned char Str255[256];
+typedef unsigned char Str63[64];
+typedef unsigned char Str32[33];
+typedef unsigned char Str31[32];
+typedef unsigned char Str27[28];
+typedef unsigned char Str15[16];
+typedef unsigned char Str32Field[34];
+typedef Str63 StrFileName;
+typedef unsigned char * StringPtr;
+typedef StringPtr * StringHandle;
+typedef const unsigned char * ConstStringPtr;
+typedef const unsigned char * ConstStr255Param;
+typedef const unsigned char * ConstStr63Param;
+typedef const unsigned char * ConstStr32Param;
+typedef const unsigned char * ConstStr31Param;
+typedef const unsigned char * ConstStr27Param;
+typedef const unsigned char * ConstStr15Param;
+typedef ConstStr63Param ConstStrFileNameParam;
+
+inline unsigned char StrLength(ConstStr255Param string) { return (*string); }
+struct Point {
+ short v;
+ short h;
+};
+typedef struct Point Point;
+typedef Point * PointPtr;
+struct Rect {
+ short top;
+ short left;
+ short bottom;
+ short right;
+};
+typedef struct Rect Rect;
+typedef Rect * RectPtr;
+struct FixedPoint {
+ Fixed x;
+ Fixed y;
+};
+typedef struct FixedPoint FixedPoint;
+struct FixedRect {
+ Fixed left;
+ Fixed top;
+ Fixed right;
+ Fixed bottom;
+};
+typedef struct FixedRect FixedRect;
+
+typedef short CharParameter;
+enum {
+ normal = 0,
+ bold = 1,
+ italic = 2,
+ underline = 4,
+ outline = 8,
+ shadow = 0x10,
+ condense = 0x20,
+ extend = 0x40
+};
+
+typedef unsigned char Style;
+typedef short StyleParameter;
+typedef Style StyleField;
+typedef long TimeValue;
+typedef long TimeScale;
+typedef wide CompTimeValue;
+typedef SInt64 TimeValue64;
+typedef struct TimeBaseRecord* TimeBase;
+struct TimeRecord {
+ CompTimeValue value;
+ TimeScale scale;
+ TimeBase base;
+};
+typedef struct TimeRecord TimeRecord;
+struct NumVersion {
+
+ UInt8 majorRev;
+ UInt8 minorAndBugRev;
+ UInt8 stage;
+ UInt8 nonRelRev;
+};
+typedef struct NumVersion NumVersion;
+enum {
+
+ developStage = 0x20,
+ alphaStage = 0x40,
+ betaStage = 0x60,
+ finalStage = 0x80
+};
+
+union NumVersionVariant {
+
+ NumVersion parts;
+ unsigned long whole;
+};
+typedef union NumVersionVariant NumVersionVariant;
+typedef NumVersionVariant * NumVersionVariantPtr;
+typedef NumVersionVariantPtr * NumVersionVariantHandle;
+struct VersRec {
+
+ NumVersion numericVersion;
+ short countryCode;
+ Str255 shortVersion;
+ Str255 reserved;
+};
+typedef struct VersRec VersRec;
+typedef VersRec * VersRecPtr;
+typedef VersRecPtr * VersRecHndl;
+
+
+
+
+
+typedef UInt8 Byte;
+typedef SInt8 SignedByte;
+typedef wide * WidePtr;
+typedef UnsignedWide * UnsignedWidePtr;
+typedef Float80 extended80;
+typedef Float96 extended96;
+typedef SInt8 VHSelect;
+extern void
+Debugger(void) ;
+extern void
+DebugStr(ConstStr255Param debuggerMsg) ;
+extern void
+SysBreak(void) ;
+extern void
+SysBreakStr(ConstStr255Param debuggerMsg) ;
+extern void
+SysBreakFunc(ConstStr255Param debuggerMsg) ;
+
+
+}
+extern "C" {
+extern double kCFCoreFoundationVersionNumber;
+
+
+
+
+
+
+
+typedef UInt32 CFTypeID;
+typedef UInt32 CFOptionFlags;
+typedef UInt32 CFHashCode;
+typedef SInt32 CFIndex;
+
+
+typedef const void * CFTypeRef;
+
+typedef const struct __CFString * CFStringRef;
+typedef struct __CFString * CFMutableStringRef;
+
+
+
+
+
+
+typedef CFTypeRef CFPropertyListRef;
+
+
+typedef enum {
+ kCFCompareLessThan = -1,
+ kCFCompareEqualTo = 0,
+ kCFCompareGreaterThan = 1
+} CFComparisonResult;
+
+
+typedef CFComparisonResult (*CFComparatorFunction)(const void *val1, const void *val2, void *context);
+
+
+
+enum {
+ kCFNotFound = -1
+};
+
+
+
+typedef struct {
+ CFIndex location;
+ CFIndex length;
+} CFRange;
+
+
+static __inline__ CFRange CFRangeMake(CFIndex loc, CFIndex len) {
+ CFRange range;
+ range.location = loc;
+ range.length = len;
+ return range;
+}
+
+
+
+
+
+extern
+CFRange __CFRangeMake(CFIndex loc, CFIndex len);
+
+
+
+
+
+typedef const struct __CFNull * CFNullRef;
+
+extern
+CFTypeID CFNullGetTypeID(void);
+
+extern
+const CFNullRef kCFNull;
+typedef const struct __CFAllocator * CFAllocatorRef;
+
+
+extern
+const CFAllocatorRef kCFAllocatorDefault;
+
+
+extern
+const CFAllocatorRef kCFAllocatorSystemDefault;
+
+
+
+
+
+
+
+extern
+const CFAllocatorRef kCFAllocatorMalloc;
+
+
+
+
+
+extern
+const CFAllocatorRef kCFAllocatorNull;
+
+
+
+
+
+extern
+const CFAllocatorRef kCFAllocatorUseContext;
+
+typedef const void * (*CFAllocatorRetainCallBack)(const void *info);
+typedef void (*CFAllocatorReleaseCallBack)(const void *info);
+typedef CFStringRef (*CFAllocatorCopyDescriptionCallBack)(const void *info);
+typedef void * (*CFAllocatorAllocateCallBack)(CFIndex allocSize, CFOptionFlags hint, void *info);
+typedef void * (*CFAllocatorReallocateCallBack)(void *ptr, CFIndex newsize, CFOptionFlags hint, void *info);
+typedef void (*CFAllocatorDeallocateCallBack)(void *ptr, void *info);
+typedef CFIndex (*CFAllocatorPreferredSizeCallBack)(CFIndex size, CFOptionFlags hint, void *info);
+typedef struct {
+ CFIndex version;
+ void * info;
+ CFAllocatorRetainCallBack retain;
+ CFAllocatorReleaseCallBack release;
+ CFAllocatorCopyDescriptionCallBack copyDescription;
+ CFAllocatorAllocateCallBack allocate;
+ CFAllocatorReallocateCallBack reallocate;
+ CFAllocatorDeallocateCallBack deallocate;
+ CFAllocatorPreferredSizeCallBack preferredSize;
+} CFAllocatorContext;
+
+extern
+CFTypeID CFAllocatorGetTypeID(void);
+extern
+void CFAllocatorSetDefault(CFAllocatorRef allocator);
+
+extern
+CFAllocatorRef CFAllocatorGetDefault(void);
+
+extern
+CFAllocatorRef CFAllocatorCreate(CFAllocatorRef allocator, CFAllocatorContext *context);
+
+extern
+void *CFAllocatorAllocate(CFAllocatorRef allocator, CFIndex size, CFOptionFlags hint);
+
+extern
+void *CFAllocatorReallocate(CFAllocatorRef allocator, void *ptr, CFIndex newsize, CFOptionFlags hint);
+
+extern
+void CFAllocatorDeallocate(CFAllocatorRef allocator, void *ptr);
+
+extern
+CFIndex CFAllocatorGetPreferredSizeForSize(CFAllocatorRef allocator, CFIndex size, CFOptionFlags hint);
+
+extern
+void CFAllocatorGetContext(CFAllocatorRef allocator, CFAllocatorContext *context);
+
+
+
+
+extern
+CFTypeID CFGetTypeID(CFTypeRef cf);
+
+extern
+CFStringRef CFCopyTypeIDDescription(CFTypeID type_id);
+
+extern
+CFTypeRef CFRetain(CFTypeRef cf);
+
+extern
+void CFRelease(CFTypeRef cf);
+
+extern
+CFIndex CFGetRetainCount(CFTypeRef cf);
+
+extern
+Boolean CFEqual(CFTypeRef cf1, CFTypeRef cf2);
+
+extern
+CFHashCode CFHash(CFTypeRef cf);
+
+extern
+CFStringRef CFCopyDescription(CFTypeRef cf);
+
+extern
+CFAllocatorRef CFGetAllocator(CFTypeRef cf);
+
+
+}
+extern "C" {
+typedef const void * (*CFArrayRetainCallBack)(CFAllocatorRef allocator, const void *value);
+typedef void (*CFArrayReleaseCallBack)(CFAllocatorRef allocator, const void *value);
+typedef CFStringRef (*CFArrayCopyDescriptionCallBack)(const void *value);
+typedef Boolean (*CFArrayEqualCallBack)(const void *value1, const void *value2);
+typedef struct {
+ CFIndex version;
+ CFArrayRetainCallBack retain;
+ CFArrayReleaseCallBack release;
+ CFArrayCopyDescriptionCallBack copyDescription;
+ CFArrayEqualCallBack equal;
+} CFArrayCallBacks;
+
+
+
+
+
+
+extern
+const CFArrayCallBacks kCFTypeArrayCallBacks;
+typedef void (*CFArrayApplierFunction)(const void *value, void *context);
+
+
+
+
+
+typedef const struct __CFArray * CFArrayRef;
+
+
+
+
+
+typedef struct __CFArray * CFMutableArrayRef;
+
+
+
+
+
+extern
+CFTypeID CFArrayGetTypeID(void);
+extern
+CFArrayRef CFArrayCreate(CFAllocatorRef allocator, const void **values, CFIndex numValues, const CFArrayCallBacks *callBacks);
+extern
+CFArrayRef CFArrayCreateCopy(CFAllocatorRef allocator, CFArrayRef theArray);
+extern
+CFMutableArrayRef CFArrayCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFArrayCallBacks *callBacks);
+extern
+CFMutableArrayRef CFArrayCreateMutableCopy(CFAllocatorRef allocator, CFIndex capacity, CFArrayRef theArray);
+extern
+CFIndex CFArrayGetCount(CFArrayRef theArray);
+extern
+CFIndex CFArrayGetCountOfValue(CFArrayRef theArray, CFRange range, const void *value);
+extern
+Boolean CFArrayContainsValue(CFArrayRef theArray, CFRange range, const void *value);
+extern
+const void *CFArrayGetValueAtIndex(CFArrayRef theArray, CFIndex idx);
+extern
+void CFArrayGetValues(CFArrayRef theArray, CFRange range, const void **values);
+extern
+void CFArrayApplyFunction(CFArrayRef theArray, CFRange range, CFArrayApplierFunction applier, void *context);
+extern
+CFIndex CFArrayGetFirstIndexOfValue(CFArrayRef theArray, CFRange range, const void *value);
+extern
+CFIndex CFArrayGetLastIndexOfValue(CFArrayRef theArray, CFRange range, const void *value);
+extern
+CFIndex CFArrayBSearchValues(CFArrayRef theArray, CFRange range, const void *value, CFComparatorFunction comparator, void *context);
+extern
+void CFArrayAppendValue(CFMutableArrayRef theArray, const void *value);
+extern
+void CFArrayInsertValueAtIndex(CFMutableArrayRef theArray, CFIndex idx, const void *value);
+extern
+void CFArraySetValueAtIndex(CFMutableArrayRef theArray, CFIndex idx, const void *value);
+extern
+void CFArrayRemoveValueAtIndex(CFMutableArrayRef theArray, CFIndex idx);
+extern
+void CFArrayRemoveAllValues(CFMutableArrayRef theArray);
+extern
+void CFArrayReplaceValues(CFMutableArrayRef theArray, CFRange range, const void **newValues, CFIndex newCount);
+extern
+void CFArrayExchangeValuesAtIndices(CFMutableArrayRef theArray, CFIndex idx1, CFIndex idx2);
+extern
+void CFArraySortValues(CFMutableArrayRef theArray, CFRange range, CFComparatorFunction comparator, void *context);
+extern
+void CFArrayAppendArray(CFMutableArrayRef theArray, CFArrayRef otherArray, CFRange otherRange);
+
+
+}
+extern "C" {
+
+
+typedef const void * (*CFBagRetainCallBack)(CFAllocatorRef allocator, const void *value);
+typedef void (*CFBagReleaseCallBack)(CFAllocatorRef allocator, const void *value);
+typedef CFStringRef (*CFBagCopyDescriptionCallBack)(const void *value);
+typedef Boolean (*CFBagEqualCallBack)(const void *value1, const void *value2);
+typedef CFHashCode (*CFBagHashCallBack)(const void *value);
+typedef struct {
+ CFIndex version;
+ CFBagRetainCallBack retain;
+ CFBagReleaseCallBack release;
+ CFBagCopyDescriptionCallBack copyDescription;
+ CFBagEqualCallBack equal;
+ CFBagHashCallBack hash;
+} CFBagCallBacks;
+
+extern
+const CFBagCallBacks kCFTypeBagCallBacks;
+extern
+const CFBagCallBacks kCFCopyStringBagCallBacks;
+
+typedef void (*CFBagApplierFunction)(const void *value, void *context);
+
+typedef const struct __CFBag * CFBagRef;
+typedef struct __CFBag * CFMutableBagRef;
+
+extern
+CFTypeID CFBagGetTypeID(void);
+
+extern
+CFBagRef CFBagCreate(CFAllocatorRef allocator, const void **values, CFIndex numValues, const CFBagCallBacks *callBacks);
+
+extern
+CFBagRef CFBagCreateCopy(CFAllocatorRef allocator, CFBagRef theBag);
+
+extern
+CFMutableBagRef CFBagCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFBagCallBacks *callBacks);
+
+extern
+CFMutableBagRef CFBagCreateMutableCopy(CFAllocatorRef allocator, CFIndex capacity, CFBagRef theBag);
+
+extern
+CFIndex CFBagGetCount(CFBagRef theBag);
+
+extern
+CFIndex CFBagGetCountOfValue(CFBagRef theBag, const void *value);
+
+extern
+Boolean CFBagContainsValue(CFBagRef theBag, const void *value);
+
+extern
+const void *CFBagGetValue(CFBagRef theBag, const void *value);
+
+extern
+Boolean CFBagGetValueIfPresent(CFBagRef theBag, const void *candidate, const void **value);
+
+extern
+void CFBagGetValues(CFBagRef theBag, const void **values);
+
+extern
+void CFBagApplyFunction(CFBagRef theBag, CFBagApplierFunction applier, void *context);
+
+extern
+void CFBagAddValue(CFMutableBagRef theBag, const void *value);
+
+extern
+void CFBagReplaceValue(CFMutableBagRef theBag, const void *value);
+
+extern
+void CFBagSetValue(CFMutableBagRef theBag, const void *value);
+
+extern
+void CFBagRemoveValue(CFMutableBagRef theBag, const void *value);
+
+extern
+void CFBagRemoveAllValues(CFMutableBagRef theBag);
+
+
+}
+extern "C" {
+
+
+typedef const struct __CFData * CFDataRef;
+typedef struct __CFData * CFMutableDataRef;
+
+extern
+CFTypeID CFDataGetTypeID(void);
+
+extern
+CFDataRef CFDataCreate(CFAllocatorRef allocator, const UInt8 *bytes, CFIndex length);
+
+extern
+CFDataRef CFDataCreateWithBytesNoCopy(CFAllocatorRef allocator, const UInt8 *bytes, CFIndex length, CFAllocatorRef bytesDeallocator);
+
+
+extern
+CFDataRef CFDataCreateCopy(CFAllocatorRef allocator, CFDataRef theData);
+
+extern
+CFMutableDataRef CFDataCreateMutable(CFAllocatorRef allocator, CFIndex capacity);
+
+extern
+CFMutableDataRef CFDataCreateMutableCopy(CFAllocatorRef allocator, CFIndex capacity, CFDataRef theData);
+
+extern
+CFIndex CFDataGetLength(CFDataRef theData);
+
+extern
+const UInt8 *CFDataGetBytePtr(CFDataRef theData);
+
+extern
+UInt8 *CFDataGetMutableBytePtr(CFMutableDataRef theData);
+
+extern
+void CFDataGetBytes(CFDataRef theData, CFRange range, UInt8 *buffer);
+
+extern
+void CFDataSetLength(CFMutableDataRef theData, CFIndex length);
+
+extern
+void CFDataIncreaseLength(CFMutableDataRef theData, CFIndex extraLength);
+
+extern
+void CFDataAppendBytes(CFMutableDataRef theData, const UInt8 *bytes, CFIndex length);
+
+extern
+void CFDataReplaceBytes(CFMutableDataRef theData, CFRange range, const UInt8 *newBytes, CFIndex newLength);
+
+extern
+void CFDataDeleteBytes(CFMutableDataRef theData, CFRange range);
+
+
+}
+
+
+extern "C" {
+
+
+
+
+
+
+typedef const struct __CFCharacterSet * CFCharacterSetRef;
+
+
+
+
+
+typedef struct __CFCharacterSet * CFMutableCharacterSetRef;
+
+
+
+
+
+typedef enum {
+ kCFCharacterSetControl = 1,
+ kCFCharacterSetWhitespace,
+ kCFCharacterSetWhitespaceAndNewline,
+ kCFCharacterSetDecimalDigit,
+ kCFCharacterSetLetter,
+ kCFCharacterSetLowercaseLetter,
+ kCFCharacterSetUppercaseLetter,
+ kCFCharacterSetNonBase,
+ kCFCharacterSetDecomposable,
+ kCFCharacterSetAlphaNumeric,
+ kCFCharacterSetPunctuation,
+ kCFCharacterSetIllegal
+
+ ,
+ kCFCharacterSetCapitalizedLetter
+
+} CFCharacterSetPredefinedSet;
+
+
+
+
+
+extern
+CFTypeID CFCharacterSetGetTypeID(void);
+extern
+CFCharacterSetRef CFCharacterSetGetPredefined(CFCharacterSetPredefinedSet theSetIdentifier);
+extern
+CFCharacterSetRef CFCharacterSetCreateWithCharactersInRange(CFAllocatorRef alloc, CFRange theRange);
+extern
+CFCharacterSetRef CFCharacterSetCreateWithCharactersInString(CFAllocatorRef alloc, CFStringRef theString);
+extern
+CFCharacterSetRef CFCharacterSetCreateWithBitmapRepresentation(CFAllocatorRef alloc, CFDataRef theData);
+extern CFCharacterSetRef CFCharacterSetCreateInvertedSet(CFAllocatorRef alloc, CFCharacterSetRef theSet);
+extern Boolean CFCharacterSetIsSupersetOfSet(CFCharacterSetRef theSet, CFCharacterSetRef theOtherset);
+extern Boolean CFCharacterSetHasMemberInPlane(CFCharacterSetRef theSet, CFIndex thePlane);
+extern
+CFMutableCharacterSetRef CFCharacterSetCreateMutable(CFAllocatorRef alloc);
+extern
+CFMutableCharacterSetRef CFCharacterSetCreateMutableCopy(CFAllocatorRef alloc, CFCharacterSetRef theSet);
+extern
+Boolean CFCharacterSetIsCharacterMember(CFCharacterSetRef theSet, UniChar theChar);
+extern Boolean CFCharacterSetIsLongCharacterMember(CFCharacterSetRef theSet, UTF32Char theChar);
+extern
+CFDataRef CFCharacterSetCreateBitmapRepresentation(CFAllocatorRef alloc, CFCharacterSetRef theSet);
+extern
+void CFCharacterSetAddCharactersInRange(CFMutableCharacterSetRef theSet, CFRange theRange);
+extern
+void CFCharacterSetRemoveCharactersInRange(CFMutableCharacterSetRef theSet, CFRange theRange);
+extern
+void CFCharacterSetAddCharactersInString(CFMutableCharacterSetRef theSet, CFStringRef theString);
+extern
+void CFCharacterSetRemoveCharactersInString(CFMutableCharacterSetRef theSet, CFStringRef theString);
+extern
+void CFCharacterSetUnion(CFMutableCharacterSetRef theSet, CFCharacterSetRef theOtherSet);
+extern
+void CFCharacterSetIntersect(CFMutableCharacterSetRef theSet, CFCharacterSetRef theOtherSet);
+extern
+void CFCharacterSetInvert(CFMutableCharacterSetRef theSet);
+
+
+}
+
+extern "C" {
+
+
+typedef double CFTimeInterval;
+typedef CFTimeInterval CFAbsoluteTime;
+
+
+
+extern
+CFAbsoluteTime CFAbsoluteTimeGetCurrent(void);
+
+extern
+const CFTimeInterval kCFAbsoluteTimeIntervalSince1970;
+extern
+const CFTimeInterval kCFAbsoluteTimeIntervalSince1904;
+
+typedef const struct __CFDate * CFDateRef;
+
+extern
+CFTypeID CFDateGetTypeID(void);
+
+extern
+CFDateRef CFDateCreate(CFAllocatorRef allocator, CFAbsoluteTime at);
+
+extern
+CFAbsoluteTime CFDateGetAbsoluteTime(CFDateRef theDate);
+
+extern
+CFTimeInterval CFDateGetTimeIntervalSinceDate(CFDateRef theDate, CFDateRef otherDate);
+
+extern
+CFComparisonResult CFDateCompare(CFDateRef theDate, CFDateRef otherDate, void *context);
+
+typedef const struct __CFTimeZone * CFTimeZoneRef;
+
+typedef struct {
+ SInt32 year;
+ SInt8 month;
+ SInt8 day;
+ SInt8 hour;
+ SInt8 minute;
+ double second;
+} CFGregorianDate;
+
+typedef struct {
+ SInt32 years;
+ SInt32 months;
+ SInt32 days;
+ SInt32 hours;
+ SInt32 minutes;
+ double seconds;
+} CFGregorianUnits;
+
+typedef enum {
+ kCFGregorianUnitsYears = (1 << 0),
+ kCFGregorianUnitsMonths = (1 << 1),
+ kCFGregorianUnitsDays = (1 << 2),
+ kCFGregorianUnitsHours = (1 << 3),
+ kCFGregorianUnitsMinutes = (1 << 4),
+ kCFGregorianUnitsSeconds = (1 << 5),
+
+
+
+
+ kCFGregorianAllUnits = 0x00FFFFFF
+} CFGregorianUnitFlags;
+
+extern
+Boolean CFGregorianDateIsValid(CFGregorianDate gdate, CFOptionFlags unitFlags);
+
+extern
+CFAbsoluteTime CFGregorianDateGetAbsoluteTime(CFGregorianDate gdate, CFTimeZoneRef tz);
+
+extern
+CFGregorianDate CFAbsoluteTimeGetGregorianDate(CFAbsoluteTime at, CFTimeZoneRef tz);
+
+extern
+CFAbsoluteTime CFAbsoluteTimeAddGregorianUnits(CFAbsoluteTime at, CFTimeZoneRef tz, CFGregorianUnits units);
+
+extern
+CFGregorianUnits CFAbsoluteTimeGetDifferenceAsGregorianUnits(CFAbsoluteTime at1, CFAbsoluteTime at2, CFTimeZoneRef tz, CFOptionFlags unitFlags);
+
+extern
+SInt32 CFAbsoluteTimeGetDayOfWeek(CFAbsoluteTime at, CFTimeZoneRef tz);
+
+extern
+SInt32 CFAbsoluteTimeGetDayOfYear(CFAbsoluteTime at, CFTimeZoneRef tz);
+
+extern
+SInt32 CFAbsoluteTimeGetWeekOfYear(CFAbsoluteTime at, CFTimeZoneRef tz);
+
+
+}
+extern "C" {
+typedef const void * (*CFDictionaryRetainCallBack)(CFAllocatorRef allocator, const void *value);
+typedef void (*CFDictionaryReleaseCallBack)(CFAllocatorRef allocator, const void *value);
+typedef CFStringRef (*CFDictionaryCopyDescriptionCallBack)(const void *value);
+typedef Boolean (*CFDictionaryEqualCallBack)(const void *value1, const void *value2);
+typedef CFHashCode (*CFDictionaryHashCallBack)(const void *value);
+typedef struct {
+ CFIndex version;
+ CFDictionaryRetainCallBack retain;
+ CFDictionaryReleaseCallBack release;
+ CFDictionaryCopyDescriptionCallBack copyDescription;
+ CFDictionaryEqualCallBack equal;
+ CFDictionaryHashCallBack hash;
+} CFDictionaryKeyCallBacks;
+
+
+
+
+
+
+
+extern
+const CFDictionaryKeyCallBacks kCFTypeDictionaryKeyCallBacks;
+extern
+const CFDictionaryKeyCallBacks kCFCopyStringDictionaryKeyCallBacks;
+typedef struct {
+ CFIndex version;
+ CFDictionaryRetainCallBack retain;
+ CFDictionaryReleaseCallBack release;
+ CFDictionaryCopyDescriptionCallBack copyDescription;
+ CFDictionaryEqualCallBack equal;
+} CFDictionaryValueCallBacks;
+
+
+
+
+
+
+
+extern
+const CFDictionaryValueCallBacks kCFTypeDictionaryValueCallBacks;
+typedef void (*CFDictionaryApplierFunction)(const void *key, const void *value, void *context);
+
+
+
+
+
+typedef const struct __CFDictionary * CFDictionaryRef;
+
+
+
+
+
+typedef struct __CFDictionary * CFMutableDictionaryRef;
+
+
+
+
+
+extern
+CFTypeID CFDictionaryGetTypeID(void);
+extern
+CFDictionaryRef CFDictionaryCreate(CFAllocatorRef allocator, const void **keys, const void **values, CFIndex numValues, const CFDictionaryKeyCallBacks *keyCallBacks, const CFDictionaryValueCallBacks *valueCallBacks);
+extern
+CFDictionaryRef CFDictionaryCreateCopy(CFAllocatorRef allocator, CFDictionaryRef theDict);
+extern
+CFMutableDictionaryRef CFDictionaryCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFDictionaryKeyCallBacks *keyCallBacks, const CFDictionaryValueCallBacks *valueCallBacks);
+extern
+CFMutableDictionaryRef CFDictionaryCreateMutableCopy(CFAllocatorRef allocator, CFIndex capacity, CFDictionaryRef theDict);
+extern
+CFIndex CFDictionaryGetCount(CFDictionaryRef theDict);
+extern
+CFIndex CFDictionaryGetCountOfKey(CFDictionaryRef theDict, const void *key);
+extern
+CFIndex CFDictionaryGetCountOfValue(CFDictionaryRef theDict, const void *value);
+extern
+Boolean CFDictionaryContainsKey(CFDictionaryRef theDict, const void *key);
+extern
+Boolean CFDictionaryContainsValue(CFDictionaryRef theDict, const void *value);
+extern
+const void *CFDictionaryGetValue(CFDictionaryRef theDict, const void *key);
+extern
+Boolean CFDictionaryGetValueIfPresent(CFDictionaryRef theDict, const void *key, const void **value);
+extern
+void CFDictionaryGetKeysAndValues(CFDictionaryRef theDict, const void **keys, const void **values);
+extern
+void CFDictionaryApplyFunction(CFDictionaryRef theDict, CFDictionaryApplierFunction applier, void *context);
+extern
+void CFDictionaryAddValue(CFMutableDictionaryRef theDict, const void *key, const void *value);
+extern
+void CFDictionarySetValue(CFMutableDictionaryRef theDict, const void *key, const void *value);
+extern
+void CFDictionaryReplaceValue(CFMutableDictionaryRef theDict, const void *key, const void *value);
+extern
+void CFDictionaryRemoveValue(CFMutableDictionaryRef theDict, const void *key);
+extern
+void CFDictionaryRemoveAllValues(CFMutableDictionaryRef theDict);
+
+
+}
+extern "C" {
+
+
+typedef const struct __CFBoolean * CFBooleanRef;
+
+extern
+const CFBooleanRef kCFBooleanTrue;
+extern
+const CFBooleanRef kCFBooleanFalse;
+
+extern
+CFTypeID CFBooleanGetTypeID(void);
+
+extern
+Boolean CFBooleanGetValue(CFBooleanRef boolean);
+
+typedef enum {
+
+ kCFNumberSInt8Type = 1,
+ kCFNumberSInt16Type = 2,
+ kCFNumberSInt32Type = 3,
+ kCFNumberSInt64Type = 4,
+ kCFNumberFloat32Type = 5,
+ kCFNumberFloat64Type = 6,
+
+ kCFNumberCharType = 7,
+ kCFNumberShortType = 8,
+ kCFNumberIntType = 9,
+ kCFNumberLongType = 10,
+ kCFNumberLongLongType = 11,
+ kCFNumberFloatType = 12,
+ kCFNumberDoubleType = 13,
+
+ kCFNumberCFIndexType = 14,
+ kCFNumberMaxType = 14
+} CFNumberType;
+
+typedef const struct __CFNumber * CFNumberRef;
+
+extern
+const CFNumberRef kCFNumberPositiveInfinity;
+extern
+const CFNumberRef kCFNumberNegativeInfinity;
+extern
+const CFNumberRef kCFNumberNaN;
+
+extern
+CFTypeID CFNumberGetTypeID(void);
+extern
+CFNumberRef CFNumberCreate(CFAllocatorRef allocator, CFNumberType theType, const void *valuePtr);
+
+
+
+
+
+extern
+CFNumberType CFNumberGetType(CFNumberRef number);
+
+
+
+
+extern
+CFIndex CFNumberGetByteSize(CFNumberRef number);
+
+
+
+
+
+extern
+Boolean CFNumberIsFloatType(CFNumberRef number);
+extern
+Boolean CFNumberGetValue(CFNumberRef number, CFNumberType theType, void *valuePtr);
+extern
+CFComparisonResult CFNumberCompare(CFNumberRef number, CFNumberRef otherNumber, void *context);
+
+
+}
+typedef __builtin_va_list __gnuc_va_list;
+typedef __gnuc_va_list va_list;
+
+
+extern "C" {
+typedef UInt32 CFStringEncoding;
+
+
+
+
+
+typedef enum {
+ kCFStringEncodingMacRoman = 0,
+ kCFStringEncodingWindowsLatin1 = 0x0500,
+ kCFStringEncodingISOLatin1 = 0x0201,
+ kCFStringEncodingNextStepLatin = 0x0B01,
+ kCFStringEncodingASCII = 0x0600,
+ kCFStringEncodingUnicode = 0x0100,
+ kCFStringEncodingUTF8 = 0x08000100,
+ kCFStringEncodingNonLossyASCII = 0x0BFF
+} CFStringBuiltInEncodings;
+
+
+extern
+CFTypeID CFStringGetTypeID(void);
+extern
+CFStringRef CFStringCreateWithPascalString(CFAllocatorRef alloc, ConstStr255Param pStr, CFStringEncoding encoding);
+
+extern
+CFStringRef CFStringCreateWithCString(CFAllocatorRef alloc, const char *cStr, CFStringEncoding encoding);
+
+extern
+CFStringRef CFStringCreateWithCharacters(CFAllocatorRef alloc, const UniChar *chars, CFIndex numChars);
+extern
+CFStringRef CFStringCreateWithPascalStringNoCopy(CFAllocatorRef alloc, ConstStr255Param pStr, CFStringEncoding encoding, CFAllocatorRef contentsDeallocator);
+
+extern
+CFStringRef CFStringCreateWithCStringNoCopy(CFAllocatorRef alloc, const char *cStr, CFStringEncoding encoding, CFAllocatorRef contentsDeallocator);
+
+extern
+CFStringRef CFStringCreateWithCharactersNoCopy(CFAllocatorRef alloc, const UniChar *chars, CFIndex numChars, CFAllocatorRef contentsDeallocator);
+
+
+
+extern
+CFStringRef CFStringCreateWithSubstring(CFAllocatorRef alloc, CFStringRef str, CFRange range);
+
+extern
+CFStringRef CFStringCreateCopy(CFAllocatorRef alloc, CFStringRef theString);
+
+
+
+extern
+CFStringRef CFStringCreateWithFormat(CFAllocatorRef alloc, CFDictionaryRef formatOptions, CFStringRef format, ...);
+
+extern
+CFStringRef CFStringCreateWithFormatAndArguments(CFAllocatorRef alloc, CFDictionaryRef formatOptions, CFStringRef format, va_list arguments);
+
+
+
+extern
+CFMutableStringRef CFStringCreateMutable(CFAllocatorRef alloc, CFIndex maxLength);
+
+extern
+CFMutableStringRef CFStringCreateMutableCopy(CFAllocatorRef alloc, CFIndex maxLength, CFStringRef theString);
+
+
+
+
+
+
+
+extern
+CFMutableStringRef CFStringCreateMutableWithExternalCharactersNoCopy(CFAllocatorRef alloc, UniChar *chars, CFIndex numChars, CFIndex capacity, CFAllocatorRef externalCharactersAllocator);
+
+
+
+
+
+extern
+CFIndex CFStringGetLength(CFStringRef theString);
+
+
+
+
+
+
+extern
+UniChar CFStringGetCharacterAtIndex(CFStringRef theString, CFIndex idx);
+
+extern
+void CFStringGetCharacters(CFStringRef theString, CFRange range, UniChar *buffer);
+extern
+Boolean CFStringGetPascalString(CFStringRef theString, StringPtr buffer, CFIndex bufferSize, CFStringEncoding encoding);
+
+extern
+Boolean CFStringGetCString(CFStringRef theString, char *buffer, CFIndex bufferSize, CFStringEncoding encoding);
+
+
+
+
+
+
+extern
+ConstStringPtr CFStringGetPascalStringPtr(CFStringRef theString, CFStringEncoding encoding);
+
+extern
+const char *CFStringGetCStringPtr(CFStringRef theString, CFStringEncoding encoding);
+
+extern
+const UniChar *CFStringGetCharactersPtr(CFStringRef theString);
+extern
+CFIndex CFStringGetBytes(CFStringRef theString, CFRange range, CFStringEncoding encoding, UInt8 lossByte, Boolean isExternalRepresentation, UInt8 *buffer, CFIndex maxBufLen, CFIndex *usedBufLen);
+
+
+
+
+
+
+
+extern
+CFStringRef CFStringCreateWithBytes(CFAllocatorRef alloc, const UInt8 *bytes, CFIndex numBytes, CFStringEncoding encoding, Boolean isExternalRepresentation);
+
+
+
+
+
+
+
+extern
+CFStringRef CFStringCreateFromExternalRepresentation(CFAllocatorRef alloc, CFDataRef data, CFStringEncoding encoding);
+
+extern
+CFDataRef CFStringCreateExternalRepresentation(CFAllocatorRef alloc, CFStringRef theString, CFStringEncoding encoding, UInt8 lossByte);
+
+
+
+extern
+CFStringEncoding CFStringGetSmallestEncoding(CFStringRef theString);
+
+extern
+CFStringEncoding CFStringGetFastestEncoding(CFStringRef theString);
+
+
+
+extern
+CFStringEncoding CFStringGetSystemEncoding(void);
+
+extern
+CFIndex CFStringGetMaximumSizeForEncoding(CFIndex length, CFStringEncoding encoding);
+
+
+
+
+
+
+typedef enum {
+ kCFCompareCaseInsensitive = 1,
+ kCFCompareBackwards = 4,
+ kCFCompareAnchored = 8,
+ kCFCompareNonliteral = 16,
+ kCFCompareLocalized = 32,
+ kCFCompareNumerically = 64
+} CFStringCompareFlags;
+
+
+
+
+
+
+extern
+CFComparisonResult CFStringCompareWithOptions(CFStringRef theString1, CFStringRef theString2, CFRange rangeToCompare, CFOptionFlags compareOptions);
+
+
+
+
+
+extern
+CFComparisonResult CFStringCompare(CFStringRef theString1, CFStringRef theString2, CFOptionFlags compareOptions);
+
+
+
+
+
+extern
+Boolean CFStringFindWithOptions(CFStringRef theString, CFStringRef stringToFind, CFRange rangeToSearch, CFOptionFlags searchOptions, CFRange *result);
+extern
+CFArrayRef CFStringCreateArrayWithFindResults(CFAllocatorRef alloc, CFStringRef theString, CFStringRef stringToFind, CFRange rangeToSearch, CFOptionFlags compareOptions);
+
+
+
+extern
+CFRange CFStringFind(CFStringRef theString, CFStringRef stringToFind, CFOptionFlags compareOptions);
+
+extern
+Boolean CFStringHasPrefix(CFStringRef theString, CFStringRef prefix);
+
+extern
+Boolean CFStringHasSuffix(CFStringRef theString, CFStringRef suffix);
+extern CFRange CFStringGetRangeOfComposedCharactersAtIndex(CFStringRef theString, CFIndex theIndex);
+extern Boolean CFStringFindCharacterFromSet(CFStringRef theString, CFCharacterSetRef theSet, CFRange rangeToSearch, CFOptionFlags searchOptions, CFRange *result);
+extern
+void CFStringGetLineBounds(CFStringRef theString, CFRange range, CFIndex *lineBeginIndex, CFIndex *lineEndIndex, CFIndex *contentsEndIndex);
+
+
+
+extern
+CFStringRef CFStringCreateByCombiningStrings(CFAllocatorRef alloc, CFArrayRef theArray, CFStringRef separatorString);
+
+extern
+CFArrayRef CFStringCreateArrayBySeparatingStrings(CFAllocatorRef alloc, CFStringRef theString, CFStringRef separatorString);
+
+
+
+extern
+SInt32 CFStringGetIntValue(CFStringRef str);
+
+extern
+double CFStringGetDoubleValue(CFStringRef str);
+extern
+void CFStringAppend(CFMutableStringRef theString, CFStringRef appendedString);
+
+extern
+void CFStringAppendCharacters(CFMutableStringRef theString, const UniChar *chars, CFIndex numChars);
+
+extern
+void CFStringAppendPascalString(CFMutableStringRef theString, ConstStr255Param pStr, CFStringEncoding encoding);
+
+extern
+void CFStringAppendCString(CFMutableStringRef theString, const char *cStr, CFStringEncoding encoding);
+
+extern
+void CFStringAppendFormat(CFMutableStringRef theString, CFDictionaryRef formatOptions, CFStringRef format, ...);
+
+extern
+void CFStringAppendFormatAndArguments(CFMutableStringRef theString, CFDictionaryRef formatOptions, CFStringRef format, va_list arguments);
+
+extern
+void CFStringInsert(CFMutableStringRef str, CFIndex idx, CFStringRef insertedStr);
+
+extern
+void CFStringDelete(CFMutableStringRef theString, CFRange range);
+
+extern
+void CFStringReplace(CFMutableStringRef theString, CFRange range, CFStringRef replacement);
+
+extern
+void CFStringReplaceAll(CFMutableStringRef theString, CFStringRef replacement);
+extern
+CFIndex CFStringFindAndReplace(CFMutableStringRef theString, CFStringRef stringToFind, CFStringRef replacementString, CFRange rangeToSearch, CFOptionFlags compareOptions);
+extern
+void CFStringSetExternalCharactersNoCopy(CFMutableStringRef theString, UniChar *chars, CFIndex length, CFIndex capacity);
+extern
+void CFStringPad(CFMutableStringRef theString, CFStringRef padString, CFIndex length, CFIndex indexIntoPad);
+
+extern
+void CFStringTrim(CFMutableStringRef theString, CFStringRef trimString);
+
+extern
+void CFStringTrimWhitespace(CFMutableStringRef theString);
+
+extern
+void CFStringLowercase(CFMutableStringRef theString, const void *localeTBD);
+
+extern
+void CFStringUppercase(CFMutableStringRef theString, const void *localeTBD);
+
+extern
+void CFStringCapitalize(CFMutableStringRef theString, const void *localeTBD);
+
+
+
+
+
+
+
+typedef enum {
+ kCFStringNormalizationFormD = 0,
+ kCFStringNormalizationFormKD,
+ kCFStringNormalizationFormC,
+ kCFStringNormalizationFormKC
+} CFStringNormalizationForm;
+extern void CFStringNormalize(CFMutableStringRef theString, CFStringNormalizationForm theForm);
+
+
+
+
+extern
+Boolean CFStringIsEncodingAvailable(CFStringEncoding encoding);
+
+
+
+extern
+const CFStringEncoding *CFStringGetListOfAvailableEncodings(void);
+
+
+
+extern
+CFStringRef CFStringGetNameOfEncoding(CFStringEncoding encoding);
+
+
+
+extern
+UInt32 CFStringConvertEncodingToNSStringEncoding(CFStringEncoding encoding);
+
+extern
+CFStringEncoding CFStringConvertNSStringEncodingToEncoding(UInt32 encoding);
+
+
+
+extern
+UInt32 CFStringConvertEncodingToWindowsCodepage(CFStringEncoding encoding);
+
+extern
+CFStringEncoding CFStringConvertWindowsCodepageToEncoding(UInt32 codepage);
+
+
+
+extern
+CFStringEncoding CFStringConvertIANACharSetNameToEncoding(CFStringRef theString);
+
+extern
+CFStringRef CFStringConvertEncodingToIANACharSetName(CFStringEncoding encoding);
+
+
+
+
+
+extern
+CFStringEncoding CFStringGetMostCompatibleMacStringEncoding(CFStringEncoding encoding);
+typedef struct {
+ UniChar buffer[64];
+ CFStringRef theString;
+ const UniChar *directBuffer;
+ CFRange rangeToBuffer;
+ CFIndex bufferedRangeStart;
+ CFIndex bufferedRangeEnd;
+} CFStringInlineBuffer;
+
+
+static __inline__ void CFStringInitInlineBuffer(CFStringRef str, CFStringInlineBuffer *buf, CFRange range) {
+ buf->theString = str;
+ buf->rangeToBuffer = range;
+ buf->directBuffer = CFStringGetCharactersPtr(str);
+ buf->bufferedRangeStart = buf->bufferedRangeEnd = 0;
+}
+
+static __inline__ UniChar CFStringGetCharacterFromInlineBuffer(CFStringInlineBuffer *buf, CFIndex idx) {
+ if (buf->directBuffer) return buf->directBuffer[idx + buf->rangeToBuffer.location];
+ if (idx >= buf->bufferedRangeEnd || idx < buf->bufferedRangeStart) {
+ if (idx < 0 || idx > buf->rangeToBuffer.length) return 0;
+ if ((buf->bufferedRangeStart = idx - 4) < 0) buf->bufferedRangeStart = 0;
+ buf->bufferedRangeEnd = buf->bufferedRangeStart + 64;
+ if (buf->bufferedRangeEnd > buf->rangeToBuffer.length) buf->bufferedRangeEnd = buf->rangeToBuffer.length;
+ CFStringGetCharacters(buf->theString, CFRangeMake(buf->rangeToBuffer.location + buf->bufferedRangeStart, buf->bufferedRangeEnd - buf->bufferedRangeStart), buf->buffer);
+ }
+ return buf->buffer[idx - buf->bufferedRangeStart];
+}
+extern
+void CFShow(CFTypeRef obj);
+
+extern
+void CFShowStr(CFStringRef str);
+
+
+extern
+CFStringRef __CFStringMakeConstantString(const char *cStr);
+
+
+}
+extern "C" {
+
+
+typedef enum {
+ kCFURLPOSIXPathStyle = 0,
+ kCFURLHFSPathStyle,
+ kCFURLWindowsPathStyle
+} CFURLPathStyle;
+
+typedef const struct __CFURL * CFURLRef;
+extern
+CFTypeID CFURLGetTypeID(void);
+
+
+
+extern
+CFURLRef CFURLCreateWithBytes(CFAllocatorRef allocator, const UInt8 *URLBytes, CFIndex length, CFStringEncoding encoding, CFURLRef baseURL);
+
+
+
+
+
+extern
+CFDataRef CFURLCreateData(CFAllocatorRef allocator, CFURLRef url, CFStringEncoding encoding, Boolean escapeWhitespace);
+
+
+extern
+CFURLRef CFURLCreateWithString(CFAllocatorRef allocator, CFStringRef URLString, CFURLRef baseURL);
+
+
+
+
+
+
+
+extern
+CFURLRef CFURLCreateWithFileSystemPath(CFAllocatorRef allocator, CFStringRef filePath, CFURLPathStyle pathStyle, Boolean isDirectory);
+
+extern
+CFURLRef CFURLCreateFromFileSystemRepresentation(CFAllocatorRef allocator, const UInt8 *buffer, CFIndex bufLen, Boolean isDirectory);
+
+extern
+CFURLRef CFURLCreateWithFileSystemPathRelativeToBase(CFAllocatorRef allocator, CFStringRef filePath, CFURLPathStyle pathStyle, Boolean isDirectory, CFURLRef baseURL);
+
+extern
+CFURLRef CFURLCreateFromFileSystemRepresentationRelativeToBase(CFAllocatorRef allocator, const UInt8 *buffer, CFIndex bufLen, Boolean isDirectory, CFURLRef baseURL);
+extern
+Boolean CFURLGetFileSystemRepresentation(CFURLRef url, Boolean resolveAgainstBase, UInt8 *buffer, CFIndex maxBufLen);
+
+
+extern
+CFURLRef CFURLCopyAbsoluteURL(CFURLRef relativeURL);
+
+
+extern
+CFStringRef CFURLGetString(CFURLRef anURL);
+
+
+extern
+CFURLRef CFURLGetBaseURL(CFURLRef anURL);
+extern
+Boolean CFURLCanBeDecomposed(CFURLRef anURL);
+
+
+
+extern
+CFStringRef CFURLCopyScheme(CFURLRef anURL);
+
+
+extern
+CFStringRef CFURLCopyNetLocation(CFURLRef anURL);
+extern
+CFStringRef CFURLCopyPath(CFURLRef anURL);
+
+extern
+CFStringRef CFURLCopyStrictPath(CFURLRef anURL, Boolean *isAbsolute);
+
+extern
+CFStringRef CFURLCopyFileSystemPath(CFURLRef anURL, CFURLPathStyle pathStyle);
+
+
+
+extern
+Boolean CFURLHasDirectoryPath(CFURLRef anURL);
+
+
+
+extern
+CFStringRef CFURLCopyResourceSpecifier(CFURLRef anURL);
+
+extern
+CFStringRef CFURLCopyHostName(CFURLRef anURL);
+
+extern
+SInt32 CFURLGetPortNumber(CFURLRef anURL);
+
+extern
+CFStringRef CFURLCopyUserName(CFURLRef anURL);
+
+extern
+CFStringRef CFURLCopyPassword(CFURLRef anURL);
+
+
+
+
+
+
+extern
+CFStringRef CFURLCopyParameterString(CFURLRef anURL, CFStringRef charactersToLeaveEscaped);
+
+extern
+CFStringRef CFURLCopyQueryString(CFURLRef anURL, CFStringRef charactersToLeaveEscaped);
+
+extern
+CFStringRef CFURLCopyFragment(CFURLRef anURL, CFStringRef charactersToLeaveEscaped);
+
+extern
+CFStringRef CFURLCopyLastPathComponent(CFURLRef url);
+
+extern
+CFStringRef CFURLCopyPathExtension(CFURLRef url);
+
+
+
+
+
+extern
+CFURLRef CFURLCreateCopyAppendingPathComponent(CFAllocatorRef allocator, CFURLRef url, CFStringRef pathComponent, Boolean isDirectory);
+
+extern
+CFURLRef CFURLCreateCopyDeletingLastPathComponent(CFAllocatorRef allocator, CFURLRef url);
+
+extern
+CFURLRef CFURLCreateCopyAppendingPathExtension(CFAllocatorRef allocator, CFURLRef url, CFStringRef extension);
+
+extern
+CFURLRef CFURLCreateCopyDeletingPathExtension(CFAllocatorRef allocator, CFURLRef url);
+extern
+CFStringRef CFURLCreateStringByReplacingPercentEscapes(CFAllocatorRef allocator, CFStringRef originalString, CFStringRef charactersToLeaveEscaped);
+extern
+CFStringRef CFURLCreateStringByAddingPercentEscapes(CFAllocatorRef allocator, CFStringRef originalString, CFStringRef charactersToLeaveUnescaped, CFStringRef legalURLCharactersToBeEscaped, CFStringEncoding encoding);
+
+
+
+struct FSRef;
+
+extern
+CFURLRef CFURLCreateFromFSRef(CFAllocatorRef allocator, const struct FSRef *fsRef);
+
+extern
+Boolean CFURLGetFSRef(CFURLRef url, struct FSRef *fsRef);
+
+
+
+}
+
+extern "C" {
+
+
+
+
+
+
+typedef struct __CFRunLoop * CFRunLoopRef;
+
+
+
+
+
+typedef struct __CFRunLoopSource * CFRunLoopSourceRef;
+
+
+
+
+
+typedef struct __CFRunLoopObserver * CFRunLoopObserverRef;
+
+
+
+
+
+typedef struct __CFRunLoopTimer * CFRunLoopTimerRef;
+
+
+enum {
+ kCFRunLoopRunFinished = 1,
+ kCFRunLoopRunStopped = 2,
+ kCFRunLoopRunTimedOut = 3,
+ kCFRunLoopRunHandledSource = 4
+};
+
+
+typedef enum {
+ kCFRunLoopEntry = (1 << 0),
+ kCFRunLoopBeforeTimers = (1 << 1),
+ kCFRunLoopBeforeSources = (1 << 2),
+ kCFRunLoopBeforeWaiting = (1 << 5),
+ kCFRunLoopAfterWaiting = (1 << 6),
+ kCFRunLoopExit = (1 << 7),
+ kCFRunLoopAllActivities = 0x0FFFFFFFU
+} CFRunLoopActivity;
+
+extern const CFStringRef kCFRunLoopDefaultMode;
+extern const CFStringRef kCFRunLoopCommonModes;
+
+
+
+
+
+extern CFTypeID CFRunLoopGetTypeID(void);
+
+
+
+
+
+
+extern CFRunLoopRef CFRunLoopGetCurrent(void);
+extern CFStringRef CFRunLoopCopyCurrentMode(CFRunLoopRef rl);
+
+
+
+
+
+
+
+extern CFArrayRef CFRunLoopCopyAllModes(CFRunLoopRef rl);
+extern void CFRunLoopAddCommonMode(CFRunLoopRef rl, CFStringRef mode);
+extern CFAbsoluteTime CFRunLoopGetNextTimerFireDate(CFRunLoopRef rl, CFStringRef mode);
+
+
+
+
+
+extern void CFRunLoopRun(void);
+extern SInt32 CFRunLoopRunInMode(CFStringRef mode, CFTimeInterval seconds, Boolean returnAfterSourceHandled);
+extern Boolean CFRunLoopIsWaiting(CFRunLoopRef rl);
+extern void CFRunLoopWakeUp(CFRunLoopRef rl);
+extern void CFRunLoopStop(CFRunLoopRef rl);
+
+extern Boolean CFRunLoopContainsSource(CFRunLoopRef rl, CFRunLoopSourceRef source, CFStringRef mode);
+extern void CFRunLoopAddSource(CFRunLoopRef rl, CFRunLoopSourceRef source, CFStringRef mode);
+extern void CFRunLoopRemoveSource(CFRunLoopRef rl, CFRunLoopSourceRef source, CFStringRef mode);
+
+extern Boolean CFRunLoopContainsObserver(CFRunLoopRef rl, CFRunLoopObserverRef observer, CFStringRef mode);
+extern void CFRunLoopAddObserver(CFRunLoopRef rl, CFRunLoopObserverRef observer, CFStringRef mode);
+extern void CFRunLoopRemoveObserver(CFRunLoopRef rl, CFRunLoopObserverRef observer, CFStringRef mode);
+
+extern Boolean CFRunLoopContainsTimer(CFRunLoopRef rl, CFRunLoopTimerRef timer, CFStringRef mode);
+extern void CFRunLoopAddTimer(CFRunLoopRef rl, CFRunLoopTimerRef timer, CFStringRef mode);
+extern void CFRunLoopRemoveTimer(CFRunLoopRef rl, CFRunLoopTimerRef timer, CFStringRef mode);
+typedef struct {
+ CFIndex version;
+ void * info;
+ const void *(*retain)(const void *info);
+ void (*release)(const void *info);
+ CFStringRef (*copyDescription)(const void *info);
+ Boolean (*equal)(const void *info1, const void *info2);
+ CFHashCode (*hash)(const void *info);
+ void (*schedule)(void *info, CFRunLoopRef rl, CFStringRef mode);
+ void (*cancel)(void *info, CFRunLoopRef rl, CFStringRef mode);
+ void (*perform)(void *info);
+} CFRunLoopSourceContext;
+
+
+typedef struct {
+ CFIndex version;
+ void * info;
+ const void *(*retain)(const void *info);
+ void (*release)(const void *info);
+ CFStringRef (*copyDescription)(const void *info);
+ Boolean (*equal)(const void *info1, const void *info2);
+ CFHashCode (*hash)(const void *info);
+ mach_port_t (*getPort)(void *info);
+ void * (*perform)(void *msg, CFIndex size, CFAllocatorRef allocator, void *info);
+} CFRunLoopSourceContext1;
+
+
+
+
+
+
+extern CFTypeID CFRunLoopSourceGetTypeID(void);
+extern CFRunLoopSourceRef CFRunLoopSourceCreate(CFAllocatorRef allocator, CFIndex order, CFRunLoopSourceContext *context);
+
+
+
+
+
+
+
+extern CFIndex CFRunLoopSourceGetOrder(CFRunLoopSourceRef source);
+extern void CFRunLoopSourceInvalidate(CFRunLoopSourceRef source);
+
+
+
+
+
+
+
+extern Boolean CFRunLoopSourceIsValid(CFRunLoopSourceRef source);
+extern void CFRunLoopSourceGetContext(CFRunLoopSourceRef source, CFRunLoopSourceContext *context);
+extern void CFRunLoopSourceSignal(CFRunLoopSourceRef source);
+
+typedef struct {
+ CFIndex version;
+ void * info;
+ const void *(*retain)(const void *info);
+ void (*release)(const void *info);
+ CFStringRef (*copyDescription)(const void *info);
+} CFRunLoopObserverContext;
+
+typedef void (*CFRunLoopObserverCallBack)(CFRunLoopObserverRef observer, CFRunLoopActivity activity, void *info);
+
+
+
+
+
+extern CFTypeID CFRunLoopObserverGetTypeID(void);
+
+extern CFRunLoopObserverRef CFRunLoopObserverCreate(CFAllocatorRef allocator, CFOptionFlags activities, Boolean repeats, CFIndex order, CFRunLoopObserverCallBack callout, CFRunLoopObserverContext *context);
+
+extern CFOptionFlags CFRunLoopObserverGetActivities(CFRunLoopObserverRef observer);
+extern Boolean CFRunLoopObserverDoesRepeat(CFRunLoopObserverRef observer);
+extern CFIndex CFRunLoopObserverGetOrder(CFRunLoopObserverRef observer);
+extern void CFRunLoopObserverInvalidate(CFRunLoopObserverRef observer);
+extern Boolean CFRunLoopObserverIsValid(CFRunLoopObserverRef observer);
+extern void CFRunLoopObserverGetContext(CFRunLoopObserverRef observer, CFRunLoopObserverContext *context);
+
+typedef struct {
+ CFIndex version;
+ void * info;
+ const void *(*retain)(const void *info);
+ void (*release)(const void *info);
+ CFStringRef (*copyDescription)(const void *info);
+} CFRunLoopTimerContext;
+
+typedef void (*CFRunLoopTimerCallBack)(CFRunLoopTimerRef timer, void *info);
+
+
+
+
+
+extern CFTypeID CFRunLoopTimerGetTypeID(void);
+
+extern CFRunLoopTimerRef CFRunLoopTimerCreate(CFAllocatorRef allocator, CFAbsoluteTime fireDate, CFTimeInterval interval, CFOptionFlags flags, CFIndex order, CFRunLoopTimerCallBack callout, CFRunLoopTimerContext *context);
+extern CFAbsoluteTime CFRunLoopTimerGetNextFireDate(CFRunLoopTimerRef timer);
+extern void CFRunLoopTimerSetNextFireDate(CFRunLoopTimerRef timer, CFAbsoluteTime fireDate);
+extern CFTimeInterval CFRunLoopTimerGetInterval(CFRunLoopTimerRef timer);
+extern Boolean CFRunLoopTimerDoesRepeat(CFRunLoopTimerRef timer);
+extern CFIndex CFRunLoopTimerGetOrder(CFRunLoopTimerRef timer);
+extern void CFRunLoopTimerInvalidate(CFRunLoopTimerRef timer);
+extern Boolean CFRunLoopTimerIsValid(CFRunLoopTimerRef timer);
+extern void CFRunLoopTimerGetContext(CFRunLoopTimerRef timer, CFRunLoopTimerContext *context);
+
+
+}
+extern "C" {
+
+
+
+
+
+
+typedef int CFSocketNativeHandle;
+
+typedef struct __CFSocket * CFSocketRef;
+typedef enum {
+ kCFSocketSuccess = 0,
+ kCFSocketError = -1,
+ kCFSocketTimeout = -2
+} CFSocketError;
+
+typedef struct {
+ SInt32 protocolFamily;
+ SInt32 socketType;
+ SInt32 protocol;
+ CFDataRef address;
+} CFSocketSignature;
+
+typedef enum {
+ kCFSocketNoCallBack = 0,
+ kCFSocketReadCallBack = 1,
+ kCFSocketAcceptCallBack = 2,
+ kCFSocketDataCallBack = 3,
+ kCFSocketConnectCallBack = 4
+
+ ,
+ kCFSocketWriteCallBack = 8
+
+} CFSocketCallBackType;
+
+
+
+enum {
+ kCFSocketAutomaticallyReenableReadCallBack = 1,
+ kCFSocketAutomaticallyReenableAcceptCallBack = 2,
+ kCFSocketAutomaticallyReenableDataCallBack = 3,
+ kCFSocketAutomaticallyReenableWriteCallBack = 8,
+ kCFSocketCloseOnInvalidate = 128
+};
+
+
+typedef void (*CFSocketCallBack)(CFSocketRef s, CFSocketCallBackType type, CFDataRef address, const void *data, void *info);
+
+
+typedef struct {
+ CFIndex version;
+ void * info;
+ const void *(*retain)(const void *info);
+ void (*release)(const void *info);
+ CFStringRef (*copyDescription)(const void *info);
+} CFSocketContext;
+
+extern CFTypeID CFSocketGetTypeID(void);
+
+extern CFSocketRef CFSocketCreate(CFAllocatorRef allocator, SInt32 protocolFamily, SInt32 socketType, SInt32 protocol, CFOptionFlags callBackTypes, CFSocketCallBack callout, const CFSocketContext *context);
+extern CFSocketRef CFSocketCreateWithNative(CFAllocatorRef allocator, CFSocketNativeHandle sock, CFOptionFlags callBackTypes, CFSocketCallBack callout, const CFSocketContext *context);
+extern CFSocketRef CFSocketCreateWithSocketSignature(CFAllocatorRef allocator, const CFSocketSignature *signature, CFOptionFlags callBackTypes, CFSocketCallBack callout, const CFSocketContext *context);
+extern CFSocketRef CFSocketCreateConnectedToSocketSignature(CFAllocatorRef allocator, const CFSocketSignature *signature, CFOptionFlags callBackTypes, CFSocketCallBack callout, const CFSocketContext *context, CFTimeInterval timeout);
+
+
+extern CFSocketError CFSocketSetAddress(CFSocketRef s, CFDataRef address);
+extern CFSocketError CFSocketConnectToAddress(CFSocketRef s, CFDataRef address, CFTimeInterval timeout);
+extern void CFSocketInvalidate(CFSocketRef s);
+
+extern Boolean CFSocketIsValid(CFSocketRef s);
+extern CFDataRef CFSocketCopyAddress(CFSocketRef s);
+extern CFDataRef CFSocketCopyPeerAddress(CFSocketRef s);
+extern void CFSocketGetContext(CFSocketRef s, CFSocketContext *context);
+extern CFSocketNativeHandle CFSocketGetNative(CFSocketRef s);
+
+extern CFRunLoopSourceRef CFSocketCreateRunLoopSource(CFAllocatorRef allocator, CFSocketRef s, CFIndex order);
+
+
+extern CFOptionFlags CFSocketGetSocketFlags(CFSocketRef s);
+extern void CFSocketSetSocketFlags(CFSocketRef s, CFOptionFlags flags);
+extern void CFSocketDisableCallBacks(CFSocketRef s, CFOptionFlags callBackTypes);
+extern void CFSocketEnableCallBacks(CFSocketRef s, CFOptionFlags callBackTypes);
+
+
+
+extern CFSocketError CFSocketSendData(CFSocketRef s, CFDataRef address, CFDataRef data, CFTimeInterval timeout);
+extern CFSocketError CFSocketRegisterValue(const CFSocketSignature *nameServerSignature, CFTimeInterval timeout, CFStringRef name, CFPropertyListRef value);
+extern CFSocketError CFSocketCopyRegisteredValue(const CFSocketSignature *nameServerSignature, CFTimeInterval timeout, CFStringRef name, CFPropertyListRef *value, CFDataRef *nameServerAddress);
+
+extern CFSocketError CFSocketRegisterSocketSignature(const CFSocketSignature *nameServerSignature, CFTimeInterval timeout, CFStringRef name, const CFSocketSignature *signature);
+extern CFSocketError CFSocketCopyRegisteredSocketSignature(const CFSocketSignature *nameServerSignature, CFTimeInterval timeout, CFStringRef name, CFSocketSignature *signature, CFDataRef *nameServerAddress);
+
+extern CFSocketError CFSocketUnregister(const CFSocketSignature *nameServerSignature, CFTimeInterval timeout, CFStringRef name);
+
+extern void CFSocketSetDefaultNameRegistryPortNumber(UInt16 port);
+extern UInt16 CFSocketGetDefaultNameRegistryPortNumber(void);
+
+
+extern const CFStringRef kCFSocketCommandKey;
+extern const CFStringRef kCFSocketNameKey;
+extern const CFStringRef kCFSocketValueKey;
+extern const CFStringRef kCFSocketResultKey;
+extern const CFStringRef kCFSocketErrorKey;
+extern const CFStringRef kCFSocketRegisterCommand;
+extern const CFStringRef kCFSocketRetrieveCommand;
+
+
+}
+
+
+extern "C" {
+
+
+typedef enum {
+ kCFStreamStatusNotOpen = 0,
+ kCFStreamStatusOpening,
+ kCFStreamStatusOpen,
+ kCFStreamStatusReading,
+ kCFStreamStatusWriting,
+ kCFStreamStatusAtEnd,
+ kCFStreamStatusClosed,
+ kCFStreamStatusError
+} CFStreamStatus;
+
+typedef enum {
+ kCFStreamErrorDomainCustom = -1,
+ kCFStreamErrorDomainPOSIX = 1,
+ kCFStreamErrorDomainMacOSStatus
+} CFStreamErrorDomain;
+
+typedef struct {
+ CFStreamErrorDomain domain;
+ SInt32 error;
+} CFStreamError;
+
+typedef enum {
+ kCFStreamEventNone = 0,
+ kCFStreamEventOpenCompleted = 1,
+ kCFStreamEventHasBytesAvailable = 2,
+ kCFStreamEventCanAcceptBytes = 4,
+ kCFStreamEventErrorOccurred = 8,
+ kCFStreamEventEndEncountered = 16
+} CFStreamEventType;
+
+typedef struct {
+ CFIndex version;
+ void *info;
+ void *(*retain)(void *info);
+ void (*release)(void *info);
+ CFStringRef (*copyDescription)(void *info);
+} CFStreamClientContext;
+
+typedef struct __CFReadStream * CFReadStreamRef;
+typedef struct __CFWriteStream * CFWriteStreamRef;
+
+typedef void (*CFReadStreamClientCallBack)(CFReadStreamRef stream, CFStreamEventType type, void *clientCallBackInfo);
+typedef void (*CFWriteStreamClientCallBack)(CFWriteStreamRef stream, CFStreamEventType type, void *clientCallBackInfo);
+
+extern
+CFTypeID CFReadStreamGetTypeID(void);
+extern
+CFTypeID CFWriteStreamGetTypeID(void);
+
+
+
+
+extern
+const CFStringRef kCFStreamPropertyDataWritten;
+
+
+extern
+CFReadStreamRef CFReadStreamCreateWithBytesNoCopy(CFAllocatorRef alloc, const UInt8 *bytes, CFIndex length, CFAllocatorRef bytesDeallocator);
+
+
+extern
+CFWriteStreamRef CFWriteStreamCreateWithBuffer(CFAllocatorRef alloc, UInt8 *buffer, CFIndex bufferCapacity);
+
+
+extern
+CFWriteStreamRef CFWriteStreamCreateWithAllocatedBuffers(CFAllocatorRef alloc, CFAllocatorRef bufferAllocator);
+
+
+extern
+CFReadStreamRef CFReadStreamCreateWithFile(CFAllocatorRef alloc, CFURLRef fileURL);
+extern
+CFWriteStreamRef CFWriteStreamCreateWithFile(CFAllocatorRef alloc, CFURLRef fileURL);
+
+
+
+extern
+const CFStringRef kCFStreamPropertyAppendToFile;
+
+
+
+
+
+extern
+const CFStringRef kCFStreamPropertySocketNativeHandle;
+
+
+extern
+const CFStringRef kCFStreamPropertySocketRemoteHostName;
+
+
+extern
+const CFStringRef kCFStreamPropertySocketRemotePortNumber;
+
+
+extern
+void CFStreamCreatePairWithSocket(CFAllocatorRef alloc, CFSocketNativeHandle sock, CFReadStreamRef *readStream, CFWriteStreamRef *writeStream);
+extern
+void CFStreamCreatePairWithSocketToHost(CFAllocatorRef alloc, CFStringRef host, UInt32 port, CFReadStreamRef *readStream, CFWriteStreamRef *writeStream);
+
+extern
+void CFStreamCreatePairWithPeerSocketSignature(CFAllocatorRef alloc, const CFSocketSignature *signature, CFReadStreamRef *readStream, CFWriteStreamRef *writeStream);
+
+
+
+
+extern
+CFStreamStatus CFReadStreamGetStatus(CFReadStreamRef stream);
+extern
+CFStreamStatus CFWriteStreamGetStatus(CFWriteStreamRef stream);
+
+
+
+
+extern
+CFStreamError CFReadStreamGetError(CFReadStreamRef stream);
+extern
+CFStreamError CFWriteStreamGetError(CFWriteStreamRef stream);
+
+
+
+
+
+
+extern
+Boolean CFReadStreamOpen(CFReadStreamRef stream);
+extern
+Boolean CFWriteStreamOpen(CFWriteStreamRef stream);
+
+
+
+
+extern
+void CFReadStreamClose(CFReadStreamRef stream);
+extern
+void CFWriteStreamClose(CFWriteStreamRef stream);
+
+
+
+extern
+Boolean CFReadStreamHasBytesAvailable(CFReadStreamRef stream);
+extern
+CFIndex CFReadStreamRead(CFReadStreamRef stream, UInt8 *buffer, CFIndex bufferLength);
+extern
+const UInt8 *CFReadStreamGetBuffer(CFReadStreamRef stream, CFIndex maxBytesToRead, CFIndex *numBytesRead);
+
+
+
+extern
+Boolean CFWriteStreamCanAcceptBytes(CFWriteStreamRef stream);
+
+
+
+
+
+
+extern
+CFIndex CFWriteStreamWrite(CFWriteStreamRef stream, const UInt8 *buffer, CFIndex bufferLength);
+extern
+CFTypeRef CFReadStreamCopyProperty(CFReadStreamRef stream, CFStringRef propertyName);
+extern
+CFTypeRef CFWriteStreamCopyProperty(CFWriteStreamRef stream, CFStringRef propertyName);
+
+
+
+
+extern
+Boolean CFReadStreamSetProperty(CFReadStreamRef stream, CFStringRef propertyName, CFTypeRef propertyValue);
+extern
+Boolean CFWriteStreamSetProperty(CFWriteStreamRef stream, CFStringRef propertyName, CFTypeRef propertyValue);
+extern
+Boolean CFReadStreamSetClient(CFReadStreamRef stream, CFOptionFlags streamEvents, CFReadStreamClientCallBack clientCB, CFStreamClientContext *clientContext);
+extern
+Boolean CFWriteStreamSetClient(CFWriteStreamRef stream, CFOptionFlags streamEvents, CFWriteStreamClientCallBack clientCB, CFStreamClientContext *clientContext);
+
+extern
+void CFReadStreamScheduleWithRunLoop(CFReadStreamRef stream, CFRunLoopRef runLoop, CFStringRef runLoopMode);
+extern
+void CFWriteStreamScheduleWithRunLoop(CFWriteStreamRef stream, CFRunLoopRef runLoop, CFStringRef runLoopMode);
+
+extern
+void CFReadStreamUnscheduleFromRunLoop(CFReadStreamRef stream, CFRunLoopRef runLoop, CFStringRef runLoopMode);
+extern
+void CFWriteStreamUnscheduleFromRunLoop(CFWriteStreamRef stream, CFRunLoopRef runLoop, CFStringRef runLoopMode);
+
+
+}
+
+
+extern "C" {
+
+
+typedef enum {
+ kCFPropertyListImmutable = 0,
+ kCFPropertyListMutableContainers,
+ kCFPropertyListMutableContainersAndLeaves
+} CFPropertyListMutabilityOptions;
+extern
+CFPropertyListRef CFPropertyListCreateFromXMLData(CFAllocatorRef allocator, CFDataRef xmlData, CFOptionFlags mutabilityOption, CFStringRef *errorString);
+extern
+CFDataRef CFPropertyListCreateXMLData(CFAllocatorRef allocator, CFPropertyListRef propertyList);
+
+
+
+
+
+
+
+extern
+CFPropertyListRef CFPropertyListCreateDeepCopy(CFAllocatorRef allocator, CFPropertyListRef propertyList, CFOptionFlags mutabilityOption);
+
+
+
+typedef enum {
+ kCFPropertyListOpenStepFormat = 1,
+ kCFPropertyListXMLFormat_v1_0 = 100,
+ kCFPropertyListBinaryFormat_v1_0 = 200
+} CFPropertyListFormat;
+
+extern
+Boolean CFPropertyListIsValid(CFPropertyListRef plist, CFPropertyListFormat format);
+
+
+
+
+
+
+
+extern
+CFIndex CFPropertyListWriteToStream(CFPropertyListRef propertyList, CFWriteStreamRef stream, CFPropertyListFormat format, CFStringRef *errorString);
+extern
+CFPropertyListRef CFPropertyListCreateFromStream(CFAllocatorRef allocator, CFReadStreamRef stream, CFIndex streamLength, CFOptionFlags mutabilityOption, CFPropertyListFormat *format, CFStringRef *errorString);
+}
+extern "C" {
+typedef const void * (*CFSetRetainCallBack)(CFAllocatorRef allocator, const void *value);
+
+
+
+
+
+
+
+typedef void (*CFSetReleaseCallBack)(CFAllocatorRef allocator, const void *value);
+
+
+
+
+
+
+
+typedef CFStringRef (*CFSetCopyDescriptionCallBack)(const void *value);
+typedef Boolean (*CFSetEqualCallBack)(const void *value1, const void *value2);
+
+
+
+
+
+
+
+typedef CFHashCode (*CFSetHashCallBack)(const void *value);
+typedef struct {
+ CFIndex version;
+ CFSetRetainCallBack retain;
+ CFSetReleaseCallBack release;
+ CFSetCopyDescriptionCallBack copyDescription;
+ CFSetEqualCallBack equal;
+ CFSetHashCallBack hash;
+} CFSetCallBacks;
+
+
+
+
+
+
+extern
+const CFSetCallBacks kCFTypeSetCallBacks;
+
+
+
+
+
+
+
+extern
+const CFSetCallBacks kCFCopyStringSetCallBacks;
+typedef void (*CFSetApplierFunction)(const void *value, void *context);
+
+
+
+
+
+typedef const struct __CFSet * CFSetRef;
+
+
+
+
+
+typedef struct __CFSet * CFMutableSetRef;
+
+
+
+
+
+extern
+CFTypeID CFSetGetTypeID(void);
+extern
+CFSetRef CFSetCreate(CFAllocatorRef allocator, const void **values, CFIndex numValues, const CFSetCallBacks *callBacks);
+extern
+CFSetRef CFSetCreateCopy(CFAllocatorRef allocator, CFSetRef theSet);
+extern
+CFMutableSetRef CFSetCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFSetCallBacks *callBacks);
+extern
+CFMutableSetRef CFSetCreateMutableCopy(CFAllocatorRef allocator, CFIndex capacity, CFSetRef theSet);
+extern
+CFIndex CFSetGetCount(CFSetRef theSet);
+extern
+CFIndex CFSetGetCountOfValue(CFSetRef theSet, const void *value);
+extern
+Boolean CFSetContainsValue(CFSetRef theSet, const void *value);
+extern
+const void *CFSetGetValue(CFSetRef theSet, const void *value);
+extern
+Boolean CFSetGetValueIfPresent(CFSetRef theSet, const void *candidate, const void **value);
+extern
+void CFSetGetValues(CFSetRef theSet, const void **values);
+extern
+void CFSetApplyFunction(CFSetRef theSet, CFSetApplierFunction applier, void *context);
+extern
+void CFSetAddValue(CFMutableSetRef theSet, const void *value);
+extern
+void CFSetReplaceValue(CFMutableSetRef theSet, const void *value);
+extern
+void CFSetSetValue(CFMutableSetRef theSet, const void *value);
+extern
+void CFSetRemoveValue(CFMutableSetRef theSet, const void *value);
+extern
+void CFSetRemoveAllValues(CFMutableSetRef theSet);
+
+
+}
+
+extern "C" {
+
+
+extern
+CFTypeID CFTimeZoneGetTypeID(void);
+
+extern
+CFTimeZoneRef CFTimeZoneCopySystem(void);
+
+extern
+void CFTimeZoneResetSystem(void);
+
+extern
+CFTimeZoneRef CFTimeZoneCopyDefault(void);
+
+extern
+void CFTimeZoneSetDefault(CFTimeZoneRef tz);
+
+extern
+CFArrayRef CFTimeZoneCopyKnownNames(void);
+
+extern
+CFDictionaryRef CFTimeZoneCopyAbbreviationDictionary(void);
+
+extern
+void CFTimeZoneSetAbbreviationDictionary(CFDictionaryRef dict);
+
+extern
+CFTimeZoneRef CFTimeZoneCreate(CFAllocatorRef allocator, CFStringRef name, CFDataRef data);
+
+extern
+CFTimeZoneRef CFTimeZoneCreateWithTimeIntervalFromGMT(CFAllocatorRef allocator, CFTimeInterval ti);
+
+extern
+CFTimeZoneRef CFTimeZoneCreateWithName(CFAllocatorRef allocator, CFStringRef name, Boolean tryAbbrev);
+
+extern
+CFStringRef CFTimeZoneGetName(CFTimeZoneRef tz);
+
+extern
+CFDataRef CFTimeZoneGetData(CFTimeZoneRef tz);
+
+extern
+CFTimeInterval CFTimeZoneGetSecondsFromGMT(CFTimeZoneRef tz, CFAbsoluteTime at);
+
+extern
+CFStringRef CFTimeZoneCopyAbbreviation(CFTimeZoneRef tz, CFAbsoluteTime at);
+
+extern
+Boolean CFTimeZoneIsDaylightSavingTime(CFTimeZoneRef tz, CFAbsoluteTime at);
+
+
+}
+extern "C" {
+typedef const void * (*CFTreeRetainCallBack)(const void *info);
+
+
+
+
+
+
+
+typedef void (*CFTreeReleaseCallBack)(const void *info);
+typedef CFStringRef (*CFTreeCopyDescriptionCallBack)(const void *info);
+typedef struct {
+ CFIndex version;
+ void * info;
+ CFTreeRetainCallBack retain;
+ CFTreeReleaseCallBack release;
+ CFTreeCopyDescriptionCallBack copyDescription;
+} CFTreeContext;
+typedef void (*CFTreeApplierFunction)(const void *value, void *context);
+
+
+
+
+
+typedef struct __CFTree * CFTreeRef;
+
+
+
+
+
+extern
+CFTypeID CFTreeGetTypeID(void);
+extern
+CFTreeRef CFTreeCreate(CFAllocatorRef allocator, const CFTreeContext *context);
+extern
+CFTreeRef CFTreeGetParent(CFTreeRef tree);
+extern
+CFTreeRef CFTreeGetNextSibling(CFTreeRef tree);
+extern
+CFTreeRef CFTreeGetFirstChild(CFTreeRef tree);
+extern
+void CFTreeGetContext(CFTreeRef tree, CFTreeContext *context);
+extern
+CFIndex CFTreeGetChildCount(CFTreeRef tree);
+extern
+CFTreeRef CFTreeGetChildAtIndex(CFTreeRef tree, CFIndex idx);
+extern
+void CFTreeGetChildren(CFTreeRef tree, CFTreeRef *children);
+extern
+void CFTreeApplyFunctionToChildren(CFTreeRef tree, CFTreeApplierFunction applier, void *context);
+extern
+CFTreeRef CFTreeFindRoot(CFTreeRef tree);
+extern
+void CFTreeSetContext(CFTreeRef tree, const CFTreeContext *context);
+extern
+void CFTreePrependChild(CFTreeRef tree, CFTreeRef newChild);
+extern
+void CFTreeAppendChild(CFTreeRef tree, CFTreeRef newChild);
+extern
+void CFTreeInsertSibling(CFTreeRef tree, CFTreeRef newSibling);
+
+
+
+
+
+
+
+extern
+void CFTreeRemove(CFTreeRef tree);
+
+
+
+
+
+
+
+extern
+void CFTreeRemoveAllChildren(CFTreeRef tree);
+extern
+void CFTreeSortChildren(CFTreeRef tree, CFComparatorFunction comparator, void *context);
+
+
+}
+
+extern "C" {
+
+
+enum {
+ kCFXMLNodeCurrentVersion = 1
+};
+
+typedef const struct __CFXMLNode * CFXMLNodeRef;
+typedef CFTreeRef CFXMLTreeRef;
+typedef enum {
+ kCFXMLNodeTypeDocument = 1,
+ kCFXMLNodeTypeElement = 2,
+ kCFXMLNodeTypeAttribute = 3,
+ kCFXMLNodeTypeProcessingInstruction = 4,
+ kCFXMLNodeTypeComment = 5,
+ kCFXMLNodeTypeText = 6,
+ kCFXMLNodeTypeCDATASection = 7,
+ kCFXMLNodeTypeDocumentFragment = 8,
+ kCFXMLNodeTypeEntity = 9,
+ kCFXMLNodeTypeEntityReference = 10,
+ kCFXMLNodeTypeDocumentType = 11,
+ kCFXMLNodeTypeWhitespace = 12,
+ kCFXMLNodeTypeNotation = 13,
+ kCFXMLNodeTypeElementTypeDeclaration = 14,
+ kCFXMLNodeTypeAttributeListDeclaration = 15
+} CFXMLNodeTypeCode;
+
+typedef struct {
+ CFDictionaryRef attributes;
+ CFArrayRef attributeOrder;
+ Boolean isEmpty;
+ char _reserved[3];
+} CFXMLElementInfo;
+
+typedef struct {
+ CFStringRef dataString;
+} CFXMLProcessingInstructionInfo;
+
+typedef struct {
+ CFURLRef sourceURL;
+ CFStringEncoding encoding;
+} CFXMLDocumentInfo;
+
+typedef struct {
+ CFURLRef systemID;
+ CFStringRef publicID;
+} CFXMLExternalID;
+
+typedef struct {
+ CFXMLExternalID externalID;
+} CFXMLDocumentTypeInfo;
+
+typedef struct {
+ CFXMLExternalID externalID;
+} CFXMLNotationInfo;
+
+typedef struct {
+
+ CFStringRef contentDescription;
+} CFXMLElementTypeDeclarationInfo;
+
+typedef struct {
+
+ CFStringRef attributeName;
+ CFStringRef typeString;
+ CFStringRef defaultString;
+} CFXMLAttributeDeclarationInfo;
+
+typedef struct {
+ CFIndex numberOfAttributes;
+ CFXMLAttributeDeclarationInfo *attributes;
+} CFXMLAttributeListDeclarationInfo;
+
+typedef enum {
+ kCFXMLEntityTypeParameter,
+ kCFXMLEntityTypeParsedInternal,
+ kCFXMLEntityTypeParsedExternal,
+ kCFXMLEntityTypeUnparsed,
+ kCFXMLEntityTypeCharacter
+} CFXMLEntityTypeCode;
+
+typedef struct {
+ CFXMLEntityTypeCode entityType;
+ CFStringRef replacementText;
+ CFXMLExternalID entityID;
+ CFStringRef notationName;
+} CFXMLEntityInfo;
+
+typedef struct {
+ CFXMLEntityTypeCode entityType;
+} CFXMLEntityReferenceInfo;
+extern
+CFTypeID CFXMLNodeGetTypeID(void);
+
+
+extern
+CFXMLNodeRef CFXMLNodeCreate(CFAllocatorRef alloc, CFXMLNodeTypeCode xmlType, CFStringRef dataString, const void *additionalInfoPtr, CFIndex version);
+
+
+extern
+CFXMLNodeRef CFXMLNodeCreateCopy(CFAllocatorRef alloc, CFXMLNodeRef origNode);
+
+extern
+CFXMLNodeTypeCode CFXMLNodeGetTypeCode(CFXMLNodeRef node);
+
+extern
+CFStringRef CFXMLNodeGetString(CFXMLNodeRef node);
+
+extern
+const void *CFXMLNodeGetInfoPtr(CFXMLNodeRef node);
+
+extern
+CFIndex CFXMLNodeGetVersion(CFXMLNodeRef node);
+
+
+
+
+extern
+CFXMLTreeRef CFXMLTreeCreateWithNode(CFAllocatorRef allocator, CFXMLNodeRef node);
+
+
+extern
+CFXMLNodeRef CFXMLTreeGetNode(CFXMLTreeRef xmlTree);
+
+
+}
+extern "C" {
+
+
+typedef struct __CFXMLParser * CFXMLParserRef;
+typedef enum {
+ kCFXMLParserValidateDocument = (1 << 0),
+ kCFXMLParserSkipMetaData = (1 << 1),
+ kCFXMLParserReplacePhysicalEntities = (1 << 2),
+ kCFXMLParserSkipWhitespace = (1 << 3),
+ kCFXMLParserResolveExternalEntities = (1 << 4),
+ kCFXMLParserAddImpliedAttributes = (1 << 5),
+ kCFXMLParserAllOptions = 0x00FFFFFF,
+ kCFXMLParserNoOptions = 0
+} CFXMLParserOptions;
+
+
+typedef enum {
+ kCFXMLStatusParseNotBegun = -2,
+ kCFXMLStatusParseInProgress = -1,
+ kCFXMLStatusParseSuccessful = 0,
+ kCFXMLErrorUnexpectedEOF = 1,
+ kCFXMLErrorUnknownEncoding,
+ kCFXMLErrorEncodingConversionFailure,
+ kCFXMLErrorMalformedProcessingInstruction,
+ kCFXMLErrorMalformedDTD,
+ kCFXMLErrorMalformedName,
+ kCFXMLErrorMalformedCDSect,
+ kCFXMLErrorMalformedCloseTag,
+ kCFXMLErrorMalformedStartTag,
+ kCFXMLErrorMalformedDocument,
+ kCFXMLErrorElementlessDocument,
+ kCFXMLErrorMalformedComment,
+ kCFXMLErrorMalformedCharacterReference,
+ kCFXMLErrorMalformedParsedCharacterData,
+ kCFXMLErrorNoData
+} CFXMLParserStatusCode;
+typedef void * (*CFXMLParserCreateXMLStructureCallBack)(CFXMLParserRef parser, CFXMLNodeRef nodeDesc, void *info);
+typedef void (*CFXMLParserAddChildCallBack)(CFXMLParserRef parser, void *parent, void *child, void *info);
+typedef void (*CFXMLParserEndXMLStructureCallBack)(CFXMLParserRef parser, void *xmlType, void *info);
+typedef CFDataRef (*CFXMLParserResolveExternalEntityCallBack)(CFXMLParserRef parser, CFXMLExternalID *extID, void *info);
+typedef Boolean (*CFXMLParserHandleErrorCallBack)(CFXMLParserRef parser, CFXMLParserStatusCode error, void *info);
+typedef struct {
+ CFIndex version;
+ CFXMLParserCreateXMLStructureCallBack createXMLStructure;
+ CFXMLParserAddChildCallBack addChild;
+ CFXMLParserEndXMLStructureCallBack endXMLStructure;
+ CFXMLParserResolveExternalEntityCallBack resolveExternalEntity;
+ CFXMLParserHandleErrorCallBack handleError;
+} CFXMLParserCallBacks;
+
+typedef const void * (*CFXMLParserRetainCallBack)(const void *info);
+typedef void (*CFXMLParserReleaseCallBack)(const void *info);
+typedef CFStringRef (*CFXMLParserCopyDescriptionCallBack)(const void *info);
+typedef struct {
+ CFIndex version;
+ void * info;
+ CFXMLParserRetainCallBack retain;
+ CFXMLParserReleaseCallBack release;
+ CFXMLParserCopyDescriptionCallBack copyDescription;
+} CFXMLParserContext;
+
+extern
+CFTypeID CFXMLParserGetTypeID(void);
+extern
+CFXMLParserRef CFXMLParserCreate(CFAllocatorRef allocator, CFDataRef xmlData, CFURLRef dataSource, CFOptionFlags parseOptions, CFIndex versionOfNodes, CFXMLParserCallBacks *callBacks, CFXMLParserContext *context);
+
+
+
+
+extern
+CFXMLParserRef CFXMLParserCreateWithDataFromURL(CFAllocatorRef allocator, CFURLRef dataSource, CFOptionFlags parseOptions, CFIndex versionOfNodes, CFXMLParserCallBacks *callBacks, CFXMLParserContext *context);
+
+
+extern
+void CFXMLParserGetContext(CFXMLParserRef parser, CFXMLParserContext *context);
+
+extern
+void CFXMLParserGetCallBacks(CFXMLParserRef parser, CFXMLParserCallBacks *callBacks);
+
+extern
+CFURLRef CFXMLParserGetSourceURL(CFXMLParserRef parser);
+
+
+extern
+CFIndex CFXMLParserGetLocation(CFXMLParserRef parser);
+
+
+extern
+CFIndex CFXMLParserGetLineNumber(CFXMLParserRef parser);
+
+
+extern
+void *CFXMLParserGetDocument(CFXMLParserRef parser);
+
+
+
+
+extern
+CFXMLParserStatusCode CFXMLParserGetStatusCode(CFXMLParserRef parser);
+
+extern
+CFStringRef CFXMLParserCopyErrorDescription(CFXMLParserRef parser);
+
+
+
+
+extern
+void CFXMLParserAbort(CFXMLParserRef parser, CFXMLParserStatusCode errorCode, CFStringRef errorDescription);
+
+
+
+
+
+
+extern
+Boolean CFXMLParserParse(CFXMLParserRef parser);
+
+
+
+
+
+
+
+extern
+CFXMLTreeRef CFXMLTreeCreateFromData(CFAllocatorRef allocator, CFDataRef xmlData, CFURLRef dataSource, CFOptionFlags parseOptions, CFIndex versionOfNodes);
+
+
+
+extern
+CFXMLTreeRef CFXMLTreeCreateWithDataFromURL(CFAllocatorRef allocator, CFURLRef dataSource, CFOptionFlags parseOptions, CFIndex versionOfNodes);
+
+
+
+
+
+
+
+extern
+CFDataRef CFXMLTreeCreateXMLData(CFAllocatorRef allocator, CFXMLTreeRef xmlTree);
+
+
+}
+
+extern "C" {
+
+
+typedef struct {
+ CFIndex version;
+ void * info;
+ const void *(*retain)(const void *info);
+ void (*release)(const void *info);
+ CFStringRef (*copyDescription)(const void *info);
+} CFBinaryHeapCompareContext;
+typedef struct {
+ CFIndex version;
+ const void *(*retain)(CFAllocatorRef allocator, const void *ptr);
+ void (*release)(CFAllocatorRef allocator, const void *ptr);
+ CFStringRef (*copyDescription)(const void *ptr);
+ CFComparisonResult (*compare)(const void *ptr1, const void *ptr2, void *context);
+} CFBinaryHeapCallBacks;
+
+
+
+
+
+
+
+extern const CFBinaryHeapCallBacks kCFStringBinaryHeapCallBacks;
+typedef void (*CFBinaryHeapApplierFunction)(const void *val, void *context);
+
+
+
+
+
+typedef struct __CFBinaryHeap * CFBinaryHeapRef;
+
+
+
+
+
+extern CFTypeID CFBinaryHeapGetTypeID(void);
+extern CFBinaryHeapRef CFBinaryHeapCreate(CFAllocatorRef allocator, CFIndex capacity, const CFBinaryHeapCallBacks *callBacks, const CFBinaryHeapCompareContext *compareContext);
+extern CFBinaryHeapRef CFBinaryHeapCreateCopy(CFAllocatorRef allocator, CFIndex capacity, CFBinaryHeapRef heap);
+extern CFIndex CFBinaryHeapGetCount(CFBinaryHeapRef heap);
+extern CFIndex CFBinaryHeapGetCountOfValue(CFBinaryHeapRef heap, const void *value);
+extern Boolean CFBinaryHeapContainsValue(CFBinaryHeapRef heap, const void *value);
+extern const void * CFBinaryHeapGetMinimum(CFBinaryHeapRef heap);
+extern Boolean CFBinaryHeapGetMinimumIfPresent(CFBinaryHeapRef heap, const void **value);
+extern void CFBinaryHeapGetValues(CFBinaryHeapRef heap, const void **values);
+extern void CFBinaryHeapApplyFunction(CFBinaryHeapRef heap, CFBinaryHeapApplierFunction applier, void *context);
+extern void CFBinaryHeapAddValue(CFBinaryHeapRef heap, const void *value);
+
+
+
+
+
+
+
+extern void CFBinaryHeapRemoveMinimumValue(CFBinaryHeapRef heap);
+extern void CFBinaryHeapRemoveAllValues(CFBinaryHeapRef heap);
+
+
+}
+extern "C" {
+
+
+typedef UInt32 CFBit;
+
+typedef const struct __CFBitVector * CFBitVectorRef;
+typedef struct __CFBitVector * CFMutableBitVectorRef;
+
+extern CFTypeID CFBitVectorGetTypeID(void);
+
+extern CFBitVectorRef CFBitVectorCreate(CFAllocatorRef allocator, const UInt8 *bytes, CFIndex numBits);
+extern CFBitVectorRef CFBitVectorCreateCopy(CFAllocatorRef allocator, CFBitVectorRef bv);
+extern CFMutableBitVectorRef CFBitVectorCreateMutable(CFAllocatorRef allocator, CFIndex capacity);
+extern CFMutableBitVectorRef CFBitVectorCreateMutableCopy(CFAllocatorRef allocator, CFIndex capacity, CFBitVectorRef bv);
+
+extern CFIndex CFBitVectorGetCount(CFBitVectorRef bv);
+extern CFIndex CFBitVectorGetCountOfBit(CFBitVectorRef bv, CFRange range, CFBit value);
+extern Boolean CFBitVectorContainsBit(CFBitVectorRef bv, CFRange range, CFBit value);
+extern CFBit CFBitVectorGetBitAtIndex(CFBitVectorRef bv, CFIndex idx);
+extern void CFBitVectorGetBits(CFBitVectorRef bv, CFRange range, UInt8 *bytes);
+extern CFIndex CFBitVectorGetFirstIndexOfBit(CFBitVectorRef bv, CFRange range, CFBit value);
+extern CFIndex CFBitVectorGetLastIndexOfBit(CFBitVectorRef bv, CFRange range, CFBit value);
+
+extern void CFBitVectorSetCount(CFMutableBitVectorRef bv, CFIndex count);
+extern void CFBitVectorFlipBitAtIndex(CFMutableBitVectorRef bv, CFIndex idx);
+extern void CFBitVectorFlipBits(CFMutableBitVectorRef bv, CFRange range);
+extern void CFBitVectorSetBitAtIndex(CFMutableBitVectorRef bv, CFIndex idx, CFBit value);
+extern void CFBitVectorSetBits(CFMutableBitVectorRef bv, CFRange range, CFBit value);
+extern void CFBitVectorSetAllBits(CFMutableBitVectorRef bv, CFBit value);
+
+
+}
+extern "C" {
+
+
+typedef struct __CFBundle *CFBundleRef;
+typedef struct __CFBundle *CFPlugInRef;
+
+
+extern
+const CFStringRef kCFBundleInfoDictionaryVersionKey;
+
+extern
+const CFStringRef kCFBundleExecutableKey;
+
+extern
+const CFStringRef kCFBundleIdentifierKey;
+
+extern
+const CFStringRef kCFBundleVersionKey;
+
+
+extern
+const CFStringRef kCFBundleDevelopmentRegionKey;
+
+extern
+const CFStringRef kCFBundleNameKey;
+
+
+extern
+const CFStringRef kCFBundleLocalizationsKey;
+
+
+
+
+
+extern
+CFBundleRef CFBundleGetMainBundle(void);
+
+extern
+CFBundleRef CFBundleGetBundleWithIdentifier(CFStringRef bundleID);
+
+
+
+
+
+extern
+CFArrayRef CFBundleGetAllBundles(void);
+
+
+
+
+extern
+UInt32 CFBundleGetTypeID(void);
+
+extern
+CFBundleRef CFBundleCreate(CFAllocatorRef allocator, CFURLRef bundleURL);
+
+
+extern
+CFArrayRef CFBundleCreateBundlesFromDirectory(CFAllocatorRef allocator, CFURLRef directoryURL, CFStringRef bundleType);
+
+
+
+
+
+extern
+CFURLRef CFBundleCopyBundleURL(CFBundleRef bundle);
+
+extern
+CFTypeRef CFBundleGetValueForInfoDictionaryKey(CFBundleRef bundle, CFStringRef key);
+
+
+extern
+CFDictionaryRef CFBundleGetInfoDictionary(CFBundleRef bundle);
+
+
+
+extern
+CFDictionaryRef CFBundleGetLocalInfoDictionary(CFBundleRef bundle);
+
+
+extern
+void CFBundleGetPackageInfo(CFBundleRef bundle, UInt32 *packageType, UInt32 *packageCreator);
+
+extern
+CFStringRef CFBundleGetIdentifier(CFBundleRef bundle);
+
+extern
+UInt32 CFBundleGetVersionNumber(CFBundleRef bundle);
+
+extern
+CFStringRef CFBundleGetDevelopmentRegion(CFBundleRef bundle);
+
+extern
+CFURLRef CFBundleCopySupportFilesDirectoryURL(CFBundleRef bundle);
+
+extern
+CFURLRef CFBundleCopyResourcesDirectoryURL(CFBundleRef bundle);
+
+extern
+CFURLRef CFBundleCopyPrivateFrameworksURL(CFBundleRef bundle);
+
+extern
+CFURLRef CFBundleCopySharedFrameworksURL(CFBundleRef bundle);
+
+extern
+CFURLRef CFBundleCopySharedSupportURL(CFBundleRef bundle);
+
+extern
+CFURLRef CFBundleCopyBuiltInPlugInsURL(CFBundleRef bundle);
+
+
+
+
+extern
+CFDictionaryRef CFBundleCopyInfoDictionaryInDirectory(CFURLRef bundleURL);
+
+extern
+Boolean CFBundleGetPackageInfoInDirectory(CFURLRef url, UInt32 *packageType, UInt32 *packageCreator);
+
+
+
+extern
+CFURLRef CFBundleCopyResourceURL(CFBundleRef bundle, CFStringRef resourceName, CFStringRef resourceType, CFStringRef subDirName);
+
+extern
+CFArrayRef CFBundleCopyResourceURLsOfType(CFBundleRef bundle, CFStringRef resourceType, CFStringRef subDirName);
+
+extern
+CFStringRef CFBundleCopyLocalizedString(CFBundleRef bundle, CFStringRef key, CFStringRef value, CFStringRef tableName);
+extern
+CFURLRef CFBundleCopyResourceURLInDirectory(CFURLRef bundleURL, CFStringRef resourceName, CFStringRef resourceType, CFStringRef subDirName);
+
+extern
+CFArrayRef CFBundleCopyResourceURLsOfTypeInDirectory(CFURLRef bundleURL, CFStringRef resourceType, CFStringRef subDirName);
+
+
+
+
+
+
+extern
+CFArrayRef CFBundleCopyBundleLocalizations(CFBundleRef bundle);
+
+
+extern
+CFArrayRef CFBundleCopyPreferredLocalizationsFromArray(CFArrayRef locArray);
+
+
+
+
+
+
+
+extern
+CFArrayRef CFBundleCopyLocalizationsForPreferences(CFArrayRef locArray, CFArrayRef prefArray);
+extern
+CFURLRef CFBundleCopyResourceURLForLocalization(CFBundleRef bundle, CFStringRef resourceName, CFStringRef resourceType, CFStringRef subDirName, CFStringRef localizationName);
+
+extern
+CFArrayRef CFBundleCopyResourceURLsOfTypeForLocalization(CFBundleRef bundle, CFStringRef resourceType, CFStringRef subDirName, CFStringRef localizationName);
+
+
+
+
+
+extern
+CFDictionaryRef CFBundleCopyInfoDictionaryForURL(CFURLRef url);
+
+
+
+
+
+extern
+CFArrayRef CFBundleCopyLocalizationsForURL(CFURLRef url);
+extern
+CFURLRef CFBundleCopyExecutableURL(CFBundleRef bundle);
+
+extern
+Boolean CFBundleIsExecutableLoaded(CFBundleRef bundle);
+
+extern
+Boolean CFBundleLoadExecutable(CFBundleRef bundle);
+
+extern
+void CFBundleUnloadExecutable(CFBundleRef bundle);
+
+extern
+void *CFBundleGetFunctionPointerForName(CFBundleRef bundle, CFStringRef functionName);
+
+extern
+void CFBundleGetFunctionPointersForNames(CFBundleRef bundle, CFArrayRef functionNames, void *ftbl[]);
+
+extern
+void *CFBundleGetDataPointerForName(CFBundleRef bundle, CFStringRef symbolName);
+
+extern
+void CFBundleGetDataPointersForNames(CFBundleRef bundle, CFArrayRef symbolNames, void *stbl[]);
+
+extern
+CFURLRef CFBundleCopyAuxiliaryExecutableURL(CFBundleRef bundle, CFStringRef executableName);
+extern
+CFPlugInRef CFBundleGetPlugIn(CFBundleRef bundle);
+
+
+
+extern
+short CFBundleOpenBundleResourceMap(CFBundleRef bundle);
+
+
+
+
+
+
+extern
+SInt32 CFBundleOpenBundleResourceFiles(CFBundleRef bundle, short *refNum, short *localizedRefNum);
+
+
+
+extern
+void CFBundleCloseBundleResourceMap(CFBundleRef bundle, short refNum);
+
+
+}
+extern "C" {
+
+
+typedef enum __CFByteOrder {
+ CFByteOrderUnknown,
+ CFByteOrderLittleEndian,
+ CFByteOrderBigEndian
+} CFByteOrder;
+
+static __inline__ CFByteOrder CFByteOrderGetCurrent(void) {
+ uint32_t x = (CFByteOrderBigEndian << 24) | CFByteOrderLittleEndian;
+ return (CFByteOrder)*((UInt8 *)&x);
+}
+
+static __inline__ uint16_t CFSwapInt16(uint16_t arg) {
+
+
+
+
+
+ uint16_t result;
+ __asm__ volatile("lhbrx %0, 0, %1" : "=r" (result) : "r" (&arg) : "r0");
+ return result;
+}
+
+static __inline__ uint32_t CFSwapInt32(uint32_t arg) {
+
+
+
+
+
+ uint32_t result;
+ __asm__ volatile("lwbrx %0, 0, %1" : "=r" (result) : "r" (&arg) : "r0");
+ return result;
+}
+
+static __inline__ uint64_t CFSwapInt64(uint64_t arg) {
+ union CFSwap {
+ uint64_t sv;
+ UInt8 uc[8];
+ } result, *argp = (union CFSwap *)&arg;
+ result.uc[0] = argp->uc[7];
+ result.uc[1] = argp->uc[6];
+ result.uc[2] = argp->uc[5];
+ result.uc[3] = argp->uc[4];
+ result.uc[4] = argp->uc[3];
+ result.uc[5] = argp->uc[2];
+ result.uc[6] = argp->uc[1];
+ result.uc[7] = argp->uc[0];
+ return result.sv;
+
+}
+
+static __inline__ uint16_t CFSwapInt16BigToHost(uint16_t arg) {
+
+ return arg;
+
+
+
+}
+
+static __inline__ uint32_t CFSwapInt32BigToHost(uint32_t arg) {
+
+ return arg;
+
+
+
+}
+
+static __inline__ uint64_t CFSwapInt64BigToHost(uint64_t arg) {
+
+ return arg;
+
+
+
+}
+
+static __inline__ uint16_t CFSwapInt16HostToBig(uint16_t arg) {
+
+ return arg;
+
+
+
+}
+
+static __inline__ uint32_t CFSwapInt32HostToBig(uint32_t arg) {
+
+ return arg;
+
+
+
+}
+
+static __inline__ uint64_t CFSwapInt64HostToBig(uint64_t arg) {
+
+ return arg;
+
+
+
+}
+
+static __inline__ uint16_t CFSwapInt16LittleToHost(uint16_t arg) {
+
+
+
+ return CFSwapInt16(arg);
+
+}
+
+static __inline__ uint32_t CFSwapInt32LittleToHost(uint32_t arg) {
+
+
+
+ return CFSwapInt32(arg);
+
+}
+
+static __inline__ uint64_t CFSwapInt64LittleToHost(uint64_t arg) {
+
+
+
+ return CFSwapInt64(arg);
+
+}
+
+static __inline__ uint16_t CFSwapInt16HostToLittle(uint16_t arg) {
+
+
+
+ return CFSwapInt16(arg);
+
+}
+
+static __inline__ uint32_t CFSwapInt32HostToLittle(uint32_t arg) {
+
+
+
+ return CFSwapInt32(arg);
+
+}
+
+static __inline__ uint64_t CFSwapInt64HostToLittle(uint64_t arg) {
+
+
+
+ return CFSwapInt64(arg);
+
+}
+
+typedef struct {uint32_t v;} CFSwappedFloat32;
+typedef struct {uint64_t v;} CFSwappedFloat64;
+
+static __inline__ CFSwappedFloat32 CFConvertFloat32HostToSwapped(Float32 arg) {
+ union CFSwap {
+ Float32 v;
+ CFSwappedFloat32 sv;
+ } result;
+ result.v = arg;
+
+
+
+ return result.sv;
+}
+
+static __inline__ Float32 CFConvertFloat32SwappedToHost(CFSwappedFloat32 arg) {
+ union CFSwap {
+ Float32 v;
+ CFSwappedFloat32 sv;
+ } result;
+ result.sv = arg;
+
+
+
+ return result.v;
+}
+
+static __inline__ CFSwappedFloat64 CFConvertFloat64HostToSwapped(Float64 arg) {
+ union CFSwap {
+ Float64 v;
+ CFSwappedFloat64 sv;
+ } result;
+ result.v = arg;
+
+
+
+ return result.sv;
+}
+
+static __inline__ Float64 CFConvertFloat64SwappedToHost(CFSwappedFloat64 arg) {
+ union CFSwap {
+ Float64 v;
+ CFSwappedFloat64 sv;
+ } result;
+ result.sv = arg;
+
+
+
+ return result.v;
+}
+
+static __inline__ CFSwappedFloat32 CFConvertFloatHostToSwapped(float arg) {
+ union CFSwap {
+ float v;
+ CFSwappedFloat32 sv;
+ } result;
+ result.v = arg;
+
+
+
+ return result.sv;
+}
+
+static __inline__ float CFConvertFloatSwappedToHost(CFSwappedFloat32 arg) {
+ union CFSwap {
+ float v;
+ CFSwappedFloat32 sv;
+ } result;
+ result.sv = arg;
+
+
+
+ return result.v;
+}
+
+static __inline__ CFSwappedFloat64 CFConvertDoubleHostToSwapped(double arg) {
+ union CFSwap {
+ double v;
+ CFSwappedFloat64 sv;
+ } result;
+ result.v = arg;
+
+
+
+ return result.sv;
+}
+
+static __inline__ double CFConvertDoubleSwappedToHost(CFSwappedFloat64 arg) {
+ union CFSwap {
+ double v;
+ CFSwappedFloat64 sv;
+ } result;
+ result.sv = arg;
+
+
+
+ return result.v;
+}
+
+
+}
+extern "C" {
+
+
+typedef const struct __CFUUID * CFUUIDRef;
+
+typedef struct {
+ UInt8 byte0;
+ UInt8 byte1;
+ UInt8 byte2;
+ UInt8 byte3;
+ UInt8 byte4;
+ UInt8 byte5;
+ UInt8 byte6;
+ UInt8 byte7;
+ UInt8 byte8;
+ UInt8 byte9;
+ UInt8 byte10;
+ UInt8 byte11;
+ UInt8 byte12;
+ UInt8 byte13;
+ UInt8 byte14;
+ UInt8 byte15;
+} CFUUIDBytes;
+
+
+
+
+
+
+extern
+CFTypeID CFUUIDGetTypeID(void);
+
+extern
+CFUUIDRef CFUUIDCreate(CFAllocatorRef alloc);
+
+
+extern
+CFUUIDRef CFUUIDCreateWithBytes(CFAllocatorRef alloc, UInt8 byte0, UInt8 byte1, UInt8 byte2, UInt8 byte3, UInt8 byte4, UInt8 byte5, UInt8 byte6, UInt8 byte7, UInt8 byte8, UInt8 byte9, UInt8 byte10, UInt8 byte11, UInt8 byte12, UInt8 byte13, UInt8 byte14, UInt8 byte15);
+
+
+extern
+CFUUIDRef CFUUIDCreateFromString(CFAllocatorRef alloc, CFStringRef uuidStr);
+
+
+extern
+CFStringRef CFUUIDCreateString(CFAllocatorRef alloc, CFUUIDRef uuid);
+
+
+extern
+CFUUIDRef CFUUIDGetConstantUUIDWithBytes(CFAllocatorRef alloc, UInt8 byte0, UInt8 byte1, UInt8 byte2, UInt8 byte3, UInt8 byte4, UInt8 byte5, UInt8 byte6, UInt8 byte7, UInt8 byte8, UInt8 byte9, UInt8 byte10, UInt8 byte11, UInt8 byte12, UInt8 byte13, UInt8 byte14, UInt8 byte15);
+
+
+extern
+CFUUIDBytes CFUUIDGetUUIDBytes(CFUUIDRef uuid);
+
+extern
+CFUUIDRef CFUUIDCreateFromUUIDBytes(CFAllocatorRef alloc, CFUUIDBytes bytes);
+
+
+}
+
+
+extern "C" {
+
+
+
+
+extern
+const CFStringRef kCFPlugInDynamicRegistrationKey;
+extern
+const CFStringRef kCFPlugInDynamicRegisterFunctionKey;
+extern
+const CFStringRef kCFPlugInUnloadFunctionKey;
+extern
+const CFStringRef kCFPlugInFactoriesKey;
+extern
+const CFStringRef kCFPlugInTypesKey;
+
+
+
+
+typedef void (*CFPlugInDynamicRegisterFunction)(CFPlugInRef plugIn);
+typedef void (*CFPlugInUnloadFunction)(CFPlugInRef plugIn);
+typedef void *(*CFPlugInFactoryFunction)(CFAllocatorRef allocator, CFUUIDRef typeUUID);
+
+
+
+extern
+UInt32 CFPlugInGetTypeID(void);
+
+extern
+CFPlugInRef CFPlugInCreate(CFAllocatorRef allocator, CFURLRef plugInURL);
+
+
+extern
+CFBundleRef CFPlugInGetBundle(CFPlugInRef plugIn);
+
+
+
+
+
+
+
+extern
+void CFPlugInSetLoadOnDemand(CFPlugInRef plugIn, Boolean flag);
+
+extern
+Boolean CFPlugInIsLoadOnDemand(CFPlugInRef plugIn);
+
+
+
+
+
+extern
+CFArrayRef CFPlugInFindFactoriesForPlugInType(CFUUIDRef typeUUID);
+
+
+extern
+CFArrayRef CFPlugInFindFactoriesForPlugInTypeInPlugIn(CFUUIDRef typeUUID, CFPlugInRef plugIn);
+
+
+extern
+void *CFPlugInInstanceCreate(CFAllocatorRef allocator, CFUUIDRef factoryUUID, CFUUIDRef typeUUID);
+
+
+
+
+
+
+extern
+Boolean CFPlugInRegisterFactoryFunction(CFUUIDRef factoryUUID, CFPlugInFactoryFunction func);
+
+extern
+Boolean CFPlugInRegisterFactoryFunctionByName(CFUUIDRef factoryUUID, CFPlugInRef plugIn, CFStringRef functionName);
+
+extern
+Boolean CFPlugInUnregisterFactory(CFUUIDRef factoryUUID);
+
+extern
+Boolean CFPlugInRegisterPlugInType(CFUUIDRef factoryUUID, CFUUIDRef typeUUID);
+
+extern
+Boolean CFPlugInUnregisterPlugInType(CFUUIDRef factoryUUID, CFUUIDRef typeUUID);
+
+
+
+
+
+extern
+void CFPlugInAddInstanceForFactory(CFUUIDRef factoryID);
+
+extern
+void CFPlugInRemoveInstanceForFactory(CFUUIDRef factoryID);
+
+
+
+
+typedef struct __CFPlugInInstance *CFPlugInInstanceRef;
+
+typedef Boolean (*CFPlugInInstanceGetInterfaceFunction)(CFPlugInInstanceRef instance, CFStringRef interfaceName, void **ftbl);
+typedef void (*CFPlugInInstanceDeallocateInstanceDataFunction)(void *instanceData);
+
+extern
+Boolean CFPlugInInstanceGetInterfaceFunctionTable(CFPlugInInstanceRef instance, CFStringRef interfaceName, void **ftbl);
+extern
+CFStringRef CFPlugInInstanceGetFactoryName(CFPlugInInstanceRef instance);
+extern
+void *CFPlugInInstanceGetInstanceData(CFPlugInInstanceRef instance);
+extern
+UInt32 CFPlugInInstanceGetTypeID(void);
+extern
+CFPlugInInstanceRef CFPlugInInstanceCreateWithInstanceDataSize(CFAllocatorRef allocator, CFIndex instanceDataSize, CFPlugInInstanceDeallocateInstanceDataFunction deallocateInstanceFunction, CFStringRef factoryName, CFPlugInInstanceGetInterfaceFunction getInterfaceFunction);
+
+
+}
+extern "C" {
+extern
+Boolean CFURLCreateDataAndPropertiesFromResource(CFAllocatorRef alloc, CFURLRef url, CFDataRef *resourceData, CFDictionaryRef *properties, CFArrayRef desiredProperties, SInt32 *errorCode);
+extern
+Boolean CFURLWriteDataAndPropertiesToResource(CFURLRef url, CFDataRef dataToWrite, CFDictionaryRef propertiesToWrite, SInt32 *errorCode);
+
+
+
+extern
+Boolean CFURLDestroyResource(CFURLRef url, SInt32 *errorCode);
+
+
+
+extern
+CFTypeRef CFURLCreatePropertyFromResource(CFAllocatorRef alloc, CFURLRef url, CFStringRef property, SInt32 *errorCode);
+
+
+typedef enum {
+ kCFURLUnknownError = -10,
+ kCFURLUnknownSchemeError = -11,
+ kCFURLResourceNotFoundError = -12,
+ kCFURLResourceAccessViolationError = -13,
+ kCFURLRemoteHostUnavailableError = -14,
+ kCFURLImproperArgumentsError = -15,
+ kCFURLUnknownPropertyKeyError = -16,
+ kCFURLPropertyKeyUnavailableError = -17,
+ kCFURLTimeoutError = -18
+} CFURLError;
+
+
+
+extern
+const CFStringRef kCFURLFileExists;
+extern
+const CFStringRef kCFURLFileDirectoryContents;
+extern
+const CFStringRef kCFURLFileLength;
+extern
+const CFStringRef kCFURLFileLastModificationTime;
+extern
+const CFStringRef kCFURLFilePOSIXMode;
+extern
+const CFStringRef kCFURLFileOwnerID;
+extern
+const CFStringRef kCFURLHTTPStatusCode;
+extern
+const CFStringRef kCFURLHTTPStatusLine;
+}
+
+
+
+extern "C" {
+
+
+typedef struct __CFMachPort * CFMachPortRef;
+
+typedef struct {
+ CFIndex version;
+ void * info;
+ const void *(*retain)(const void *info);
+ void (*release)(const void *info);
+ CFStringRef (*copyDescription)(const void *info);
+} CFMachPortContext;
+
+typedef void (*CFMachPortCallBack)(CFMachPortRef port, void *msg, CFIndex size, void *info);
+typedef void (*CFMachPortInvalidationCallBack)(CFMachPortRef port, void *info);
+
+extern CFTypeID CFMachPortGetTypeID(void);
+
+extern CFMachPortRef CFMachPortCreate(CFAllocatorRef allocator, CFMachPortCallBack callout, CFMachPortContext *context, Boolean *shouldFreeInfo);
+extern CFMachPortRef CFMachPortCreateWithPort(CFAllocatorRef allocator, mach_port_t portNum, CFMachPortCallBack callout, CFMachPortContext *context, Boolean *shouldFreeInfo);
+
+extern mach_port_t CFMachPortGetPort(CFMachPortRef port);
+extern void CFMachPortGetContext(CFMachPortRef port, CFMachPortContext *context);
+extern void CFMachPortInvalidate(CFMachPortRef port);
+extern Boolean CFMachPortIsValid(CFMachPortRef port);
+extern CFMachPortInvalidationCallBack CFMachPortGetInvalidationCallBack(CFMachPortRef port);
+extern void CFMachPortSetInvalidationCallBack(CFMachPortRef port, CFMachPortInvalidationCallBack callout);
+
+extern CFRunLoopSourceRef CFMachPortCreateRunLoopSource(CFAllocatorRef allocator, CFMachPortRef port, CFIndex order);
+
+
+}
+extern "C" {
+
+
+typedef struct __CFMessagePort * CFMessagePortRef;
+
+enum {
+ kCFMessagePortSuccess = 0,
+ kCFMessagePortSendTimeout = -1,
+ kCFMessagePortReceiveTimeout = -2,
+ kCFMessagePortIsInvalid = -3,
+ kCFMessagePortTransportError = -4
+};
+
+typedef struct {
+ CFIndex version;
+ void * info;
+ const void *(*retain)(const void *info);
+ void (*release)(const void *info);
+ CFStringRef (*copyDescription)(const void *info);
+} CFMessagePortContext;
+
+typedef CFDataRef (*CFMessagePortCallBack)(CFMessagePortRef local, SInt32 msgid, CFDataRef data, void *info);
+
+typedef void (*CFMessagePortInvalidationCallBack)(CFMessagePortRef ms, void *info);
+
+extern CFTypeID CFMessagePortGetTypeID(void);
+
+extern CFMessagePortRef CFMessagePortCreateLocal(CFAllocatorRef allocator, CFStringRef name, CFMessagePortCallBack callout, CFMessagePortContext *context, Boolean *shouldFreeInfo);
+extern CFMessagePortRef CFMessagePortCreateRemote(CFAllocatorRef allocator, CFStringRef name);
+
+extern Boolean CFMessagePortIsRemote(CFMessagePortRef ms);
+extern CFStringRef CFMessagePortGetName(CFMessagePortRef ms);
+extern Boolean CFMessagePortSetName(CFMessagePortRef ms, CFStringRef newName);
+extern void CFMessagePortGetContext(CFMessagePortRef ms, CFMessagePortContext *context);
+extern void CFMessagePortInvalidate(CFMessagePortRef ms);
+extern Boolean CFMessagePortIsValid(CFMessagePortRef ms);
+extern CFMessagePortInvalidationCallBack CFMessagePortGetInvalidationCallBack(CFMessagePortRef ms);
+extern void CFMessagePortSetInvalidationCallBack(CFMessagePortRef ms, CFMessagePortInvalidationCallBack callout);
+
+
+extern SInt32 CFMessagePortSendRequest(CFMessagePortRef remote, SInt32 msgid, CFDataRef data, CFTimeInterval sendTimeout, CFTimeInterval rcvTimeout, CFStringRef replyMode, CFDataRef *returnData);
+
+extern CFRunLoopSourceRef CFMessagePortCreateRunLoopSource(CFAllocatorRef allocator, CFMessagePortRef local, CFIndex order);
+
+
+}
+
+
+
+
+
+
+extern "C" {
+
+
+typedef struct __CFNotificationCenter * CFNotificationCenterRef;
+
+typedef void (*CFNotificationCallback)(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo);
+
+typedef enum {
+ CFNotificationSuspensionBehaviorDrop = 1,
+
+ CFNotificationSuspensionBehaviorCoalesce = 2,
+
+ CFNotificationSuspensionBehaviorHold = 3,
+
+ CFNotificationSuspensionBehaviorDeliverImmediately = 4
+
+} CFNotificationSuspensionBehavior;
+
+extern CFTypeID CFNotificationCenterGetTypeID(void);
+
+
+extern CFNotificationCenterRef CFNotificationCenterGetDistributedCenter(void);
+
+
+extern void CFNotificationCenterAddObserver(CFNotificationCenterRef center, const void *observer, CFNotificationCallback callBack, CFStringRef name, const void *object, CFNotificationSuspensionBehavior suspensionBehavior);
+
+extern void CFNotificationCenterRemoveObserver(CFNotificationCenterRef center, const void *observer, CFStringRef name, const void *object);
+extern void CFNotificationCenterRemoveEveryObserver(CFNotificationCenterRef center, const void *observer);
+
+
+extern void CFNotificationCenterPostNotification(CFNotificationCenterRef center, CFStringRef name, const void *object, CFDictionaryRef userInfo, Boolean deliverImmediately);
+
+
+}
+extern "C" {
+
+
+extern
+const CFStringRef kCFPreferencesAnyApplication;
+extern
+const CFStringRef kCFPreferencesCurrentApplication;
+extern
+const CFStringRef kCFPreferencesAnyHost;
+extern
+const CFStringRef kCFPreferencesCurrentHost;
+extern
+const CFStringRef kCFPreferencesAnyUser;
+extern
+const CFStringRef kCFPreferencesCurrentUser;
+extern
+CFPropertyListRef CFPreferencesCopyAppValue(CFStringRef key, CFStringRef applicationID);
+
+
+
+
+extern
+Boolean CFPreferencesGetAppBooleanValue(CFStringRef key, CFStringRef applicationID, Boolean *keyExistsAndHasValidFormat);
+
+
+
+
+extern
+CFIndex CFPreferencesGetAppIntegerValue(CFStringRef key, CFStringRef applicationID, Boolean *keyExistsAndHasValidFormat);
+
+
+
+
+extern
+void CFPreferencesSetAppValue(CFStringRef key, CFPropertyListRef value, CFStringRef applicationID);
+
+
+
+
+
+extern
+void CFPreferencesAddSuitePreferencesToApp(CFStringRef applicationID, CFStringRef suiteID);
+
+extern
+void CFPreferencesRemoveSuitePreferencesFromApp(CFStringRef applicationID, CFStringRef suiteID);
+
+
+
+extern
+Boolean CFPreferencesAppSynchronize(CFStringRef applicationID);
+
+
+
+
+
+extern
+CFPropertyListRef CFPreferencesCopyValue(CFStringRef key, CFStringRef applicationID, CFStringRef userName, CFStringRef hostName);
+
+
+
+
+
+extern
+CFDictionaryRef CFPreferencesCopyMultiple(CFArrayRef keysToFetch, CFStringRef applicationID, CFStringRef userName, CFStringRef hostName);
+
+
+
+extern
+void CFPreferencesSetValue(CFStringRef key, CFPropertyListRef value, CFStringRef applicationID, CFStringRef userName, CFStringRef hostName);
+
+
+
+extern
+void CFPreferencesSetMultiple(CFDictionaryRef keysToSet, CFArrayRef keysToRemove, CFStringRef applicationID, CFStringRef userName, CFStringRef hostName);
+
+extern
+Boolean CFPreferencesSynchronize(CFStringRef applicationID, CFStringRef userName, CFStringRef hostName);
+
+
+
+
+
+extern
+CFArrayRef CFPreferencesCopyApplicationList(CFStringRef userName, CFStringRef hostName);
+
+
+
+
+extern
+CFArrayRef CFPreferencesCopyKeyList(CFStringRef applicationID, CFStringRef userName, CFStringRef hostName);
+
+
+
+
+
+
+
+extern
+Boolean CFPreferencesAppValueIsForced(CFStringRef key, CFStringRef applicationID);
+
+
+
+
+}
+
+extern "C" {
+
+
+typedef enum {
+
+ kCFStringEncodingMacJapanese = 1,
+ kCFStringEncodingMacChineseTrad = 2,
+ kCFStringEncodingMacKorean = 3,
+ kCFStringEncodingMacArabic = 4,
+ kCFStringEncodingMacHebrew = 5,
+ kCFStringEncodingMacGreek = 6,
+ kCFStringEncodingMacCyrillic = 7,
+ kCFStringEncodingMacDevanagari = 9,
+ kCFStringEncodingMacGurmukhi = 10,
+ kCFStringEncodingMacGujarati = 11,
+ kCFStringEncodingMacOriya = 12,
+ kCFStringEncodingMacBengali = 13,
+ kCFStringEncodingMacTamil = 14,
+ kCFStringEncodingMacTelugu = 15,
+ kCFStringEncodingMacKannada = 16,
+ kCFStringEncodingMacMalayalam = 17,
+ kCFStringEncodingMacSinhalese = 18,
+ kCFStringEncodingMacBurmese = 19,
+ kCFStringEncodingMacKhmer = 20,
+ kCFStringEncodingMacThai = 21,
+ kCFStringEncodingMacLaotian = 22,
+ kCFStringEncodingMacGeorgian = 23,
+ kCFStringEncodingMacArmenian = 24,
+ kCFStringEncodingMacChineseSimp = 25,
+ kCFStringEncodingMacTibetan = 26,
+ kCFStringEncodingMacMongolian = 27,
+ kCFStringEncodingMacEthiopic = 28,
+ kCFStringEncodingMacCentralEurRoman = 29,
+ kCFStringEncodingMacVietnamese = 30,
+ kCFStringEncodingMacExtArabic = 31,
+
+ kCFStringEncodingMacSymbol = 33,
+ kCFStringEncodingMacDingbats = 34,
+ kCFStringEncodingMacTurkish = 35,
+ kCFStringEncodingMacCroatian = 36,
+ kCFStringEncodingMacIcelandic = 37,
+ kCFStringEncodingMacRomanian = 38,
+ kCFStringEncodingMacCeltic = 39,
+ kCFStringEncodingMacGaelic = 40,
+
+ kCFStringEncodingMacFarsi = 0x8C,
+
+ kCFStringEncodingMacUkrainian = 0x98,
+
+ kCFStringEncodingMacInuit = 0xEC,
+ kCFStringEncodingMacVT100 = 0xFC,
+
+ kCFStringEncodingMacHFS = 0xFF,
+
+
+
+
+
+
+ kCFStringEncodingISOLatin2 = 0x0202,
+ kCFStringEncodingISOLatin3 = 0x0203,
+ kCFStringEncodingISOLatin4 = 0x0204,
+ kCFStringEncodingISOLatinCyrillic = 0x0205,
+ kCFStringEncodingISOLatinArabic = 0x0206,
+ kCFStringEncodingISOLatinGreek = 0x0207,
+ kCFStringEncodingISOLatinHebrew = 0x0208,
+ kCFStringEncodingISOLatin5 = 0x0209,
+ kCFStringEncodingISOLatin6 = 0x020A,
+ kCFStringEncodingISOLatinThai = 0x020B,
+ kCFStringEncodingISOLatin7 = 0x020D,
+ kCFStringEncodingISOLatin8 = 0x020E,
+ kCFStringEncodingISOLatin9 = 0x020F,
+
+
+ kCFStringEncodingDOSLatinUS = 0x0400,
+ kCFStringEncodingDOSGreek = 0x0405,
+ kCFStringEncodingDOSBalticRim = 0x0406,
+ kCFStringEncodingDOSLatin1 = 0x0410,
+ kCFStringEncodingDOSGreek1 = 0x0411,
+ kCFStringEncodingDOSLatin2 = 0x0412,
+ kCFStringEncodingDOSCyrillic = 0x0413,
+ kCFStringEncodingDOSTurkish = 0x0414,
+ kCFStringEncodingDOSPortuguese = 0x0415,
+ kCFStringEncodingDOSIcelandic = 0x0416,
+ kCFStringEncodingDOSHebrew = 0x0417,
+ kCFStringEncodingDOSCanadianFrench = 0x0418,
+ kCFStringEncodingDOSArabic = 0x0419,
+ kCFStringEncodingDOSNordic = 0x041A,
+ kCFStringEncodingDOSRussian = 0x041B,
+ kCFStringEncodingDOSGreek2 = 0x041C,
+ kCFStringEncodingDOSThai = 0x041D,
+ kCFStringEncodingDOSJapanese = 0x0420,
+ kCFStringEncodingDOSChineseSimplif = 0x0421,
+ kCFStringEncodingDOSKorean = 0x0422,
+ kCFStringEncodingDOSChineseTrad = 0x0423,
+
+ kCFStringEncodingWindowsLatin2 = 0x0501,
+ kCFStringEncodingWindowsCyrillic = 0x0502,
+ kCFStringEncodingWindowsGreek = 0x0503,
+ kCFStringEncodingWindowsLatin5 = 0x0504,
+ kCFStringEncodingWindowsHebrew = 0x0505,
+ kCFStringEncodingWindowsArabic = 0x0506,
+ kCFStringEncodingWindowsBalticRim = 0x0507,
+ kCFStringEncodingWindowsKoreanJohab = 0x0510,
+ kCFStringEncodingWindowsVietnamese = 0x0508,
+
+
+
+ kCFStringEncodingJIS_X0201_76 = 0x0620,
+ kCFStringEncodingJIS_X0208_83 = 0x0621,
+ kCFStringEncodingJIS_X0208_90 = 0x0622,
+ kCFStringEncodingJIS_X0212_90 = 0x0623,
+ kCFStringEncodingJIS_C6226_78 = 0x0624,
+ kCFStringEncodingShiftJIS_X0213_00 = 0x0628,
+ kCFStringEncodingGB_2312_80 = 0x0630,
+ kCFStringEncodingGBK_95 = 0x0631,
+ kCFStringEncodingGB_18030_2000 = 0x0632,
+ kCFStringEncodingKSC_5601_87 = 0x0640,
+ kCFStringEncodingKSC_5601_92_Johab = 0x0641,
+ kCFStringEncodingCNS_11643_92_P1 = 0x0651,
+ kCFStringEncodingCNS_11643_92_P2 = 0x0652,
+ kCFStringEncodingCNS_11643_92_P3 = 0x0653,
+
+
+ kCFStringEncodingISO_2022_JP = 0x0820,
+ kCFStringEncodingISO_2022_JP_2 = 0x0821,
+ kCFStringEncodingISO_2022_JP_1 = 0x0822,
+ kCFStringEncodingISO_2022_JP_3 = 0x0823,
+ kCFStringEncodingISO_2022_CN = 0x0830,
+ kCFStringEncodingISO_2022_CN_EXT = 0x0831,
+ kCFStringEncodingISO_2022_KR = 0x0840,
+
+
+ kCFStringEncodingEUC_JP = 0x0920,
+ kCFStringEncodingEUC_CN = 0x0930,
+ kCFStringEncodingEUC_TW = 0x0931,
+ kCFStringEncodingEUC_KR = 0x0940,
+
+
+ kCFStringEncodingShiftJIS = 0x0A01,
+ kCFStringEncodingKOI8_R = 0x0A02,
+ kCFStringEncodingBig5 = 0x0A03,
+ kCFStringEncodingMacRomanLatin1 = 0x0A04,
+ kCFStringEncodingHZ_GB_2312 = 0x0A05,
+ kCFStringEncodingBig5_HKSCS_1999 = 0x0A06,
+
+
+
+
+
+ kCFStringEncodingEBCDIC_US = 0x0C01,
+ kCFStringEncodingEBCDIC_CP037 = 0x0C02
+} CFStringEncodings;
+
+
+}
+extern "C" {
+
+
+typedef struct __CFUserNotification * CFUserNotificationRef;
+typedef void (*CFUserNotificationCallBack)(CFUserNotificationRef userNotification, CFOptionFlags responseFlags);
+
+extern
+CFTypeID CFUserNotificationGetTypeID(void);
+
+extern
+CFUserNotificationRef CFUserNotificationCreate(CFAllocatorRef allocator, CFTimeInterval timeout, CFOptionFlags flags, SInt32 *error, CFDictionaryRef dictionary);
+
+extern
+SInt32 CFUserNotificationReceiveResponse(CFUserNotificationRef userNotification, CFTimeInterval timeout, CFOptionFlags *responseFlags);
+
+extern
+CFStringRef CFUserNotificationGetResponseValue(CFUserNotificationRef userNotification, CFStringRef key, CFIndex idx);
+
+extern
+CFDictionaryRef CFUserNotificationGetResponseDictionary(CFUserNotificationRef userNotification);
+
+extern
+SInt32 CFUserNotificationUpdate(CFUserNotificationRef userNotification, CFTimeInterval timeout, CFOptionFlags flags, CFDictionaryRef dictionary);
+
+extern
+SInt32 CFUserNotificationCancel(CFUserNotificationRef userNotification);
+
+extern
+CFRunLoopSourceRef CFUserNotificationCreateRunLoopSource(CFAllocatorRef allocator, CFUserNotificationRef userNotification, CFUserNotificationCallBack callout, CFIndex order);
+
+
+
+
+extern
+SInt32 CFUserNotificationDisplayNotice(CFTimeInterval timeout, CFOptionFlags flags, CFURLRef iconURL, CFURLRef soundURL, CFURLRef localizationURL, CFStringRef alertHeader, CFStringRef alertMessage, CFStringRef defaultButtonTitle);
+
+extern
+SInt32 CFUserNotificationDisplayAlert(CFTimeInterval timeout, CFOptionFlags flags, CFURLRef iconURL, CFURLRef soundURL, CFURLRef localizationURL, CFStringRef alertHeader, CFStringRef alertMessage, CFStringRef defaultButtonTitle, CFStringRef alternateButtonTitle, CFStringRef otherButtonTitle, CFOptionFlags *responseFlags);
+
+
+
+
+enum {
+ kCFUserNotificationStopAlertLevel = 0,
+ kCFUserNotificationNoteAlertLevel = 1,
+ kCFUserNotificationCautionAlertLevel = 2,
+ kCFUserNotificationPlainAlertLevel = 3
+};
+
+enum {
+ kCFUserNotificationDefaultResponse = 0,
+ kCFUserNotificationAlternateResponse = 1,
+ kCFUserNotificationOtherResponse = 2,
+ kCFUserNotificationCancelResponse = 3
+};
+
+enum {
+ kCFUserNotificationNoDefaultButtonFlag = (1 << 5),
+ kCFUserNotificationUseRadioButtonsFlag = (1 << 6)
+};
+
+static __inline__ CFOptionFlags CFUserNotificationCheckBoxChecked(CFIndex i) {return (1 << (8 + i));}
+static __inline__ CFOptionFlags CFUserNotificationSecureTextField(CFIndex i) {return (1 << (16 + i));}
+static __inline__ CFOptionFlags CFUserNotificationPopUpSelection(CFIndex n) {return (n << 24);}
+
+
+
+
+extern
+const CFStringRef kCFUserNotificationIconURLKey;
+
+extern
+const CFStringRef kCFUserNotificationSoundURLKey;
+
+extern
+const CFStringRef kCFUserNotificationLocalizationURLKey;
+
+extern
+const CFStringRef kCFUserNotificationAlertHeaderKey;
+
+extern
+const CFStringRef kCFUserNotificationAlertMessageKey;
+
+extern
+const CFStringRef kCFUserNotificationDefaultButtonTitleKey;
+
+extern
+const CFStringRef kCFUserNotificationAlternateButtonTitleKey;
+
+extern
+const CFStringRef kCFUserNotificationOtherButtonTitleKey;
+
+extern
+const CFStringRef kCFUserNotificationProgressIndicatorValueKey;
+
+extern
+const CFStringRef kCFUserNotificationPopUpTitlesKey;
+
+extern
+const CFStringRef kCFUserNotificationTextFieldTitlesKey;
+
+extern
+const CFStringRef kCFUserNotificationCheckBoxTitlesKey;
+
+extern
+const CFStringRef kCFUserNotificationTextFieldValuesKey;
+
+
+}
+
+
+enum {
+ kClippingCreator = 'drag',
+ kClippingPictureType = 'clpp',
+ kClippingTextType = 'clpt',
+ kClippingSoundType = 'clps',
+ kClippingUnknownType = 'clpu'
+};
+
+
+
+enum {
+ kInternetLocationCreator = 'drag',
+ kInternetLocationHTTP = 'ilht',
+ kInternetLocationFTP = 'ilft',
+ kInternetLocationFile = 'ilfi',
+ kInternetLocationMail = 'ilma',
+ kInternetLocationNNTP = 'ilnw',
+ kInternetLocationAFP = 'ilaf',
+ kInternetLocationAppleTalk = 'ilat',
+ kInternetLocationNSL = 'ilns',
+ kInternetLocationGeneric = 'ilge'
+};
+
+
+
+enum {
+ kCustomIconResource = -16455
+};
+
+
+
+
+
+
+enum {
+ kCustomBadgeResourceType = 'badg',
+ kCustomBadgeResourceID = kCustomIconResource,
+ kCustomBadgeResourceVersion = 0
+};
+
+struct CustomBadgeResource {
+ SInt16 version;
+ SInt16 customBadgeResourceID;
+
+ OSType customBadgeType;
+ OSType customBadgeCreator;
+ OSType windowBadgeType;
+ OSType windowBadgeCreator;
+
+ OSType overrideType;
+ OSType overrideCreator;
+};
+typedef struct CustomBadgeResource CustomBadgeResource;
+typedef CustomBadgeResource * CustomBadgeResourcePtr;
+typedef CustomBadgeResourcePtr * CustomBadgeResourceHandle;
+enum {
+ kRoutingResourceType = 'rout',
+ kRoutingResourceID = 0
+};
+
+struct RoutingResourceEntry {
+ OSType creator;
+ OSType fileType;
+ OSType targetFolder;
+ OSType destinationFolder;
+ OSType reservedField;
+};
+typedef struct RoutingResourceEntry RoutingResourceEntry;
+typedef RoutingResourceEntry * RoutingResourcePtr;
+typedef RoutingResourcePtr * RoutingResourceHandle;
+
+
+enum {
+ kContainerFolderAliasType = 'fdrp',
+ kContainerTrashAliasType = 'trsh',
+ kContainerHardDiskAliasType = 'hdsk',
+ kContainerFloppyAliasType = 'flpy',
+ kContainerServerAliasType = 'srvr',
+ kApplicationAliasType = 'adrp',
+ kContainerAliasType = 'drop',
+ kDesktopPrinterAliasType = 'dtpa',
+ kContainerCDROMAliasType = 'cddr',
+ kApplicationCPAliasType = 'acdp',
+ kApplicationDAAliasType = 'addp',
+ kPackageAliasType = 'fpka',
+ kAppPackageAliasType = 'fapa'
+};
+
+
+enum {
+ kSystemFolderAliasType = 'fasy',
+ kAppleMenuFolderAliasType = 'faam',
+ kStartupFolderAliasType = 'fast',
+ kPrintMonitorDocsFolderAliasType = 'fapn',
+ kPreferencesFolderAliasType = 'fapf',
+ kControlPanelFolderAliasType = 'fact',
+ kExtensionFolderAliasType = 'faex'
+};
+
+
+enum {
+ kExportedFolderAliasType = 'faet',
+ kDropFolderAliasType = 'fadr',
+ kSharedFolderAliasType = 'fash',
+ kMountedFolderAliasType = 'famn'
+};
+
+
+
+
+
+enum {
+ kIsOnDesk = 0x0001,
+ kColor = 0x000E,
+
+ kIsShared = 0x0040,
+
+
+
+ kHasNoINITs = 0x0080,
+
+ kHasBeenInited = 0x0100,
+
+
+
+
+
+ kHasCustomIcon = 0x0400,
+ kIsStationery = 0x0800,
+ kNameLocked = 0x1000,
+ kHasBundle = 0x2000,
+ kIsInvisible = 0x4000,
+ kIsAlias = 0x8000
+};
+
+
+enum {
+ fOnDesk = kIsOnDesk,
+ fHasBundle = kHasBundle,
+ fInvisible = kIsInvisible
+};
+
+
+enum {
+ fTrash = -3,
+ fDesktop = -2,
+ fDisk = 0
+};
+enum {
+ kExtendedFlagsAreInvalid = 0x8000,
+ kExtendedFlagHasCustomBadge = 0x0100,
+ kExtendedFlagHasRoutingInfo = 0x0004
+};
+enum {
+ kFirstMagicBusyFiletype = 'bzy ',
+ kLastMagicBusyFiletype = 'bzy?'
+};
+
+
+
+
+
+
+enum {
+ kMagicBusyCreationDate = 0x4F3AFDB0
+};
+struct FileInfo {
+ OSType fileType;
+ OSType fileCreator;
+ UInt16 finderFlags;
+ Point location;
+
+ UInt16 reservedField;
+};
+typedef struct FileInfo FileInfo;
+struct FolderInfo {
+ Rect windowBounds;
+ UInt16 finderFlags;
+ Point location;
+
+ UInt16 reservedField;
+};
+typedef struct FolderInfo FolderInfo;
+struct ExtendedFileInfo {
+ SInt16 reserved1[4];
+ UInt16 extendedFinderFlags;
+ SInt16 reserved2;
+ SInt32 putAwayFolderID;
+};
+typedef struct ExtendedFileInfo ExtendedFileInfo;
+struct ExtendedFolderInfo {
+ Point scrollPosition;
+ SInt32 reserved1;
+ UInt16 extendedFinderFlags;
+ SInt16 reserved2;
+ SInt32 putAwayFolderID;
+};
+typedef struct ExtendedFolderInfo ExtendedFolderInfo;
+struct FInfo {
+ OSType fdType;
+ OSType fdCreator;
+ UInt16 fdFlags;
+ Point fdLocation;
+
+ SInt16 fdFldr;
+};
+typedef struct FInfo FInfo;
+
+
+
+
+
+
+
+struct FXInfo {
+ SInt16 fdIconID;
+ SInt16 fdReserved[3];
+ SInt8 fdScript;
+ SInt8 fdXFlags;
+ SInt16 fdComment;
+ SInt32 fdPutAway;
+};
+typedef struct FXInfo FXInfo;
+
+
+
+
+
+
+struct DInfo {
+ Rect frRect;
+ UInt16 frFlags;
+ Point frLocation;
+
+ SInt16 frView;
+};
+typedef struct DInfo DInfo;
+
+
+
+
+
+
+
+struct DXInfo {
+ Point frScroll;
+ SInt32 frOpenChain;
+ SInt8 frScript;
+ SInt8 frXFlags;
+ SInt16 frComment;
+ SInt32 frPutAway;
+};
+typedef struct DXInfo DXInfo;
+
+
+
+
+
+extern "C" {
+extern Fixed
+FixRatio(
+ short numer,
+ short denom) ;
+extern Fixed
+FixMul(
+ Fixed a,
+ Fixed b) ;
+extern short
+FixRound(Fixed x) ;
+extern Fract
+Fix2Frac(Fixed x) ;
+extern long
+Fix2Long(Fixed x) ;
+extern Fixed
+Long2Fix(long x) ;
+extern Fixed
+Frac2Fix(Fract x) ;
+extern Fract
+FracMul(
+ Fract x,
+ Fract y) ;
+extern Fixed
+FixDiv(
+ Fixed x,
+ Fixed y) ;
+extern Fract
+FracDiv(
+ Fract x,
+ Fract y) ;
+extern Fract
+FracSqrt(Fract x) ;
+extern Fract
+FracSin(Fixed x) ;
+extern Fract
+FracCos(Fixed x) ;
+extern Fixed
+FixATan2(
+ long x,
+ long y) ;
+extern double
+Frac2X(Fract x) ;
+extern double
+Fix2X(Fixed x) ;
+extern Fixed
+X2Fix(double x) ;
+extern Fract
+X2Frac(double x) ;
+extern short
+WideCompare(
+ const wide * target,
+ const wide * source) ;
+extern wide *
+WideAdd(
+ wide * target,
+ const wide * source) ;
+extern wide *
+WideSubtract(
+ wide * target,
+ const wide * source) ;
+extern wide *
+WideNegate(wide * target) ;
+extern wide *
+WideShift(
+ wide * target,
+ long shift) ;
+extern unsigned long
+WideSquareRoot(const wide * source) ;
+extern wide *
+WideMultiply(
+ long multiplicand,
+ long multiplier,
+ wide * target) ;
+extern long
+WideDivide(
+ const wide * dividend,
+ long divisor,
+ long * remainder) ;
+extern wide *
+WideWideDivide(
+ wide * dividend,
+ long divisor,
+ long * remainder) ;
+extern wide *
+WideBitShift(
+ wide * src,
+ long shift) ;
+
+
+
+
+
+
+
+}
+
+
+
+
+enum {
+
+ itlcShowIcon = 7,
+ itlcDualCaret = 6,
+
+ itlcSysDirection = 15
+};
+
+enum {
+
+ itlcDisableKeyScriptSync = 3
+};
+
+enum {
+
+ itlcDisableKeyScriptSyncMask = 1 << itlcDisableKeyScriptSync
+};
+
+
+enum {
+ tokLeftQuote = 1,
+ tokRightQuote = 2,
+ tokLeadPlacer = 3,
+ tokLeader = 4,
+ tokNonLeader = 5,
+ tokZeroLead = 6,
+ tokPercent = 7,
+ tokPlusSign = 8,
+ tokMinusSign = 9,
+ tokThousands = 10,
+ tokReserved = 11,
+ tokSeparator = 12,
+ tokEscape = 13,
+ tokDecPoint = 14,
+ tokEPlus = 15,
+ tokEMinus = 16,
+ tokMaxSymbols = 31,
+ curNumberPartsVersion = 1
+};
+
+enum {
+ currSymLead = 16,
+ currNegSym = 32,
+ currTrailingZ = 64,
+ currLeadingZ = 128
+};
+
+enum {
+ mdy = 0,
+ dmy = 1,
+ ymd = 2,
+ myd = 3,
+ dym = 4,
+ ydm = 5
+};
+
+typedef SInt8 DateOrders;
+enum {
+ timeCycle24 = 0,
+ timeCycleZero = 1,
+ timeCycle12 = 255,
+ zeroCycle = 1,
+ longDay = 0,
+ longWeek = 1,
+ longMonth = 2,
+ longYear = 3,
+ supDay = 1,
+ supWeek = 2,
+ supMonth = 4,
+ supYear = 8,
+ dayLdingZ = 32,
+ mntLdingZ = 64,
+ century = 128,
+ secLeadingZ = 32,
+ minLeadingZ = 64,
+ hrLeadingZ = 128
+};
+
+
+struct OffPair {
+ short offFirst;
+ short offSecond;
+};
+typedef struct OffPair OffPair;
+typedef OffPair OffsetTable[3];
+struct Intl0Rec {
+ char decimalPt;
+ char thousSep;
+ char listSep;
+ char currSym1;
+ char currSym2;
+ char currSym3;
+ UInt8 currFmt;
+ UInt8 dateOrder;
+ UInt8 shrtDateFmt;
+ char dateSep;
+ UInt8 timeCycle;
+ UInt8 timeFmt;
+ char mornStr[4];
+ char eveStr[4];
+ char timeSep;
+ char time1Suff;
+ char time2Suff;
+ char time3Suff;
+ char time4Suff;
+ char time5Suff;
+ char time6Suff;
+ char time7Suff;
+ char time8Suff;
+ UInt8 metricSys;
+ short intl0Vers;
+};
+typedef struct Intl0Rec Intl0Rec;
+typedef Intl0Rec * Intl0Ptr;
+typedef Intl0Ptr * Intl0Hndl;
+struct Intl1Rec {
+ Str15 days[7];
+ Str15 months[12];
+ UInt8 suppressDay;
+ UInt8 lngDateFmt;
+ UInt8 dayLeading0;
+ UInt8 abbrLen;
+ char st0[4];
+ char st1[4];
+ char st2[4];
+ char st3[4];
+ char st4[4];
+ short intl1Vers;
+ short localRtn[1];
+};
+typedef struct Intl1Rec Intl1Rec;
+typedef Intl1Rec * Intl1Ptr;
+typedef Intl1Ptr * Intl1Hndl;
+
+struct Itl1ExtRec {
+ Intl1Rec base;
+ short version;
+ short format;
+ short calendarCode;
+ long extraDaysTableOffset;
+ long extraDaysTableLength;
+ long extraMonthsTableOffset;
+ long extraMonthsTableLength;
+ long abbrevDaysTableOffset;
+ long abbrevDaysTableLength;
+ long abbrevMonthsTableOffset;
+ long abbrevMonthsTableLength;
+ long extraSepsTableOffset;
+ long extraSepsTableLength;
+ short tables[1];
+};
+typedef struct Itl1ExtRec Itl1ExtRec;
+struct UntokenTable {
+ short len;
+ short lastToken;
+ short index[256];
+};
+typedef struct UntokenTable UntokenTable;
+typedef UntokenTable * UntokenTablePtr;
+typedef UntokenTablePtr * UntokenTableHandle;
+union WideChar {
+ char a[2];
+ short b;
+};
+typedef union WideChar WideChar;
+struct WideCharArr {
+ short size;
+ WideChar data[10];
+};
+typedef struct WideCharArr WideCharArr;
+struct NumberParts {
+ short version;
+ WideChar data[31];
+ WideCharArr pePlus;
+ WideCharArr peMinus;
+ WideCharArr peMinusPlus;
+ WideCharArr altNumTable;
+ char reserved[20];
+};
+typedef struct NumberParts NumberParts;
+typedef NumberParts * NumberPartsPtr;
+
+struct Itl4Rec {
+ short flags;
+ long resourceType;
+ short resourceNum;
+ short version;
+ long resHeader1;
+ long resHeader2;
+ short numTables;
+ long mapOffset;
+ long strOffset;
+ long fetchOffset;
+ long unTokenOffset;
+ long defPartsOffset;
+ long resOffset6;
+ long resOffset7;
+ long resOffset8;
+};
+typedef struct Itl4Rec Itl4Rec;
+typedef Itl4Rec * Itl4Ptr;
+typedef Itl4Ptr * Itl4Handle;
+
+struct NItl4Rec {
+ short flags;
+ long resourceType;
+ short resourceNum;
+ short version;
+ short format;
+ short resHeader;
+ long resHeader2;
+ short numTables;
+ long mapOffset;
+ long strOffset;
+ long fetchOffset;
+ long unTokenOffset;
+ long defPartsOffset;
+ long whtSpListOffset;
+ long resOffset7;
+ long resOffset8;
+ short resLength1;
+ short resLength2;
+ short resLength3;
+ short unTokenLength;
+ short defPartsLength;
+ short whtSpListLength;
+ short resLength7;
+ short resLength8;
+};
+typedef struct NItl4Rec NItl4Rec;
+typedef NItl4Rec * NItl4Ptr;
+typedef NItl4Ptr * NItl4Handle;
+
+struct TableDirectoryRecord {
+ OSType tableSignature;
+ unsigned long reserved;
+ unsigned long tableStartOffset;
+ unsigned long tableSize;
+};
+typedef struct TableDirectoryRecord TableDirectoryRecord;
+struct Itl5Record {
+ Fixed versionNumber;
+ unsigned short numberOfTables;
+ unsigned short reserved[3];
+ TableDirectoryRecord tableDirectory[1];
+};
+typedef struct Itl5Record Itl5Record;
+struct RuleBasedTrslRecord {
+ short sourceType;
+ short targetType;
+ short formatNumber;
+ short propertyFlag;
+ short numberOfRules;
+};
+typedef struct RuleBasedTrslRecord RuleBasedTrslRecord;
+
+struct ItlcRecord {
+ short itlcSystem;
+ short itlcReserved;
+ SInt8 itlcFontForce;
+ SInt8 itlcIntlForce;
+ SInt8 itlcOldKybd;
+ SInt8 itlcFlags;
+ short itlcIconOffset;
+ SInt8 itlcIconSide;
+ SInt8 itlcIconRsvd;
+ short itlcRegionCode;
+ short itlcSysFlags;
+ SInt8 itlcReserved4[32];
+};
+typedef struct ItlcRecord ItlcRecord;
+struct ItlbRecord {
+ short itlbNumber;
+ short itlbDate;
+ short itlbSort;
+ short itlbFlags;
+ short itlbToken;
+ short itlbEncoding;
+ short itlbLang;
+ SInt8 itlbNumRep;
+ SInt8 itlbDateRep;
+ short itlbKeys;
+ short itlbIcon;
+};
+typedef struct ItlbRecord ItlbRecord;
+
+struct ItlbExtRecord {
+ ItlbRecord base;
+ long itlbLocalSize;
+ short itlbMonoFond;
+ short itlbMonoSize;
+ short itlbPrefFond;
+ short itlbPrefSize;
+ short itlbSmallFond;
+ short itlbSmallSize;
+ short itlbSysFond;
+ short itlbSysSize;
+ short itlbAppFond;
+ short itlbAppSize;
+ short itlbHelpFond;
+ short itlbHelpSize;
+ Style itlbValidStyles;
+ Style itlbAliasStyle;
+};
+typedef struct ItlbExtRecord ItlbExtRecord;
+
+
+
+extern "C" {
+
+
+
+
+enum {
+ smSystemScript = -1,
+ smCurrentScript = -2,
+ smAllScripts = -3
+};
+enum {
+ smRoman = 0,
+ smJapanese = 1,
+ smTradChinese = 2,
+ smKorean = 3,
+ smArabic = 4,
+ smHebrew = 5,
+ smGreek = 6,
+ smCyrillic = 7,
+ smRSymbol = 8,
+ smDevanagari = 9,
+ smGurmukhi = 10,
+ smGujarati = 11,
+ smOriya = 12,
+ smBengali = 13,
+ smTamil = 14,
+ smTelugu = 15,
+ smKannada = 16,
+ smMalayalam = 17,
+ smSinhalese = 18,
+ smBurmese = 19,
+ smKhmer = 20,
+ smThai = 21,
+ smLao = 22,
+ smGeorgian = 23,
+ smArmenian = 24,
+ smSimpChinese = 25,
+ smTibetan = 26,
+ smMongolian = 27,
+ smEthiopic = 28,
+ smGeez = 28,
+ smCentralEuroRoman = 29,
+ smVietnamese = 30,
+ smExtArabic = 31,
+ smUninterp = 32
+};
+
+
+enum {
+ smUnicodeScript = 0x7E
+};
+
+
+enum {
+ smChinese = 2,
+ smRussian = 7,
+
+ smLaotian = 22,
+ smAmharic = 28,
+ smSlavic = 29,
+ smEastEurRoman = 29,
+ smSindhi = 31,
+ smKlingon = 32
+};
+
+
+
+
+
+
+enum {
+ langEnglish = 0,
+ langFrench = 1,
+ langGerman = 2,
+ langItalian = 3,
+ langDutch = 4,
+ langSwedish = 5,
+ langSpanish = 6,
+ langDanish = 7,
+ langPortuguese = 8,
+ langNorwegian = 9,
+ langHebrew = 10,
+ langJapanese = 11,
+ langArabic = 12,
+ langFinnish = 13,
+ langGreek = 14,
+ langIcelandic = 15,
+ langMaltese = 16,
+ langTurkish = 17,
+ langCroatian = 18,
+ langTradChinese = 19,
+ langUrdu = 20,
+ langHindi = 21,
+ langThai = 22,
+ langKorean = 23
+};
+
+enum {
+ langLithuanian = 24,
+ langPolish = 25,
+ langHungarian = 26,
+ langEstonian = 27,
+ langLatvian = 28,
+ langSami = 29,
+ langFaroese = 30,
+ langFarsi = 31,
+ langPersian = 31,
+ langRussian = 32,
+ langSimpChinese = 33,
+ langFlemish = 34,
+ langIrishGaelic = 35,
+ langAlbanian = 36,
+ langRomanian = 37,
+ langCzech = 38,
+ langSlovak = 39,
+ langSlovenian = 40,
+ langYiddish = 41,
+ langSerbian = 42,
+ langMacedonian = 43,
+ langBulgarian = 44,
+ langUkrainian = 45,
+ langByelorussian = 46,
+ langBelorussian = 46
+};
+
+enum {
+ langUzbek = 47,
+ langKazakh = 48,
+ langAzerbaijani = 49,
+ langAzerbaijanAr = 50,
+ langArmenian = 51,
+ langGeorgian = 52,
+ langMoldavian = 53,
+ langKirghiz = 54,
+ langTajiki = 55,
+ langTurkmen = 56,
+ langMongolian = 57,
+ langMongolianCyr = 58,
+ langPashto = 59,
+ langKurdish = 60,
+ langKashmiri = 61,
+ langSindhi = 62,
+ langTibetan = 63,
+ langNepali = 64,
+ langSanskrit = 65,
+ langMarathi = 66,
+ langBengali = 67,
+ langAssamese = 68,
+ langGujarati = 69,
+ langPunjabi = 70
+};
+
+enum {
+ langOriya = 71,
+ langMalayalam = 72,
+ langKannada = 73,
+ langTamil = 74,
+ langTelugu = 75,
+ langSinhalese = 76,
+ langBurmese = 77,
+ langKhmer = 78,
+ langLao = 79,
+ langVietnamese = 80,
+ langIndonesian = 81,
+ langTagalog = 82,
+ langMalayRoman = 83,
+ langMalayArabic = 84,
+ langAmharic = 85,
+ langTigrinya = 86,
+ langOromo = 87,
+ langSomali = 88,
+ langSwahili = 89,
+ langKinyarwanda = 90,
+ langRuanda = 90,
+ langRundi = 91,
+ langNyanja = 92,
+ langChewa = 92,
+ langMalagasy = 93,
+ langEsperanto = 94
+};
+
+enum {
+ langWelsh = 128,
+ langBasque = 129,
+ langCatalan = 130,
+ langLatin = 131,
+ langQuechua = 132,
+ langGuarani = 133,
+ langAymara = 134,
+ langTatar = 135,
+ langUighur = 136,
+ langDzongkha = 137,
+ langJavaneseRom = 138,
+ langSundaneseRom = 139,
+ langGalician = 140,
+ langAfrikaans = 141
+};
+
+enum {
+ langBreton = 142,
+ langInuktitut = 143,
+ langScottishGaelic = 144,
+ langManxGaelic = 145,
+ langIrishGaelicScript = 146,
+ langTongan = 147,
+ langGreekPoly = 148,
+ langGreenlandic = 149,
+ langAzerbaijanRoman = 150
+};
+
+enum {
+ langUnspecified = 32767
+};
+
+
+
+
+
+enum {
+ langPortugese = 8,
+ langMalta = 16,
+ langYugoslavian = 18,
+ langChinese = 19,
+ langLettish = 28,
+ langLapponian = 29,
+ langLappish = 29,
+ langSaamisk = 29,
+ langFaeroese = 30,
+ langIrish = 35,
+ langGalla = 87,
+ langAfricaans = 141
+};
+enum {
+
+ verUS = 0,
+ verFrance = 1,
+ verBritain = 2,
+ verGermany = 3,
+ verItaly = 4,
+ verNetherlands = 5,
+ verFlemish = 6,
+ verSweden = 7,
+ verSpain = 8,
+ verDenmark = 9,
+ verPortugal = 10,
+ verFrCanada = 11,
+ verNorway = 12,
+ verIsrael = 13,
+ verJapan = 14,
+ verAustralia = 15,
+ verArabic = 16,
+ verFinland = 17,
+ verFrSwiss = 18,
+ verGrSwiss = 19,
+ verGreece = 20,
+ verIceland = 21,
+ verMalta = 22,
+ verCyprus = 23,
+ verTurkey = 24,
+ verYugoCroatian = 25
+};
+
+enum {
+ verNetherlandsComma = 26,
+ verBelgiumLuxPoint = 27,
+ verCanadaComma = 28,
+ verCanadaPoint = 29,
+ vervariantPortugal = 30,
+ vervariantNorway = 31,
+ vervariantDenmark = 32
+};
+
+enum {
+ verIndiaHindi = 33,
+ verPakistanUrdu = 34,
+ verTurkishModified = 35,
+ verItalianSwiss = 36,
+ verInternational = 37,
+
+ verRomania = 39,
+ verGreecePoly = 40,
+ verLithuania = 41,
+ verPoland = 42,
+ verHungary = 43,
+ verEstonia = 44,
+ verLatvia = 45,
+ verSami = 46,
+ verFaroeIsl = 47,
+ verIran = 48,
+ verRussia = 49,
+ verIreland = 50,
+ verKorea = 51,
+ verChina = 52,
+ verTaiwan = 53,
+ verThailand = 54,
+ verScriptGeneric = 55,
+ verCzech = 56,
+ verSlovak = 57,
+ verFarEastGeneric = 58,
+ verMagyar = 59,
+ verBengali = 60,
+ verByeloRussian = 61
+};
+
+enum {
+ verUkraine = 62,
+
+ verGreeceAlt = 64,
+ verSerbian = 65,
+ verSlovenian = 66,
+ verMacedonian = 67,
+ verCroatia = 68,
+
+ verGermanReformed = 70,
+ verBrazil = 71,
+ verBulgaria = 72,
+ verCatalonia = 73,
+ verMultilingual = 74,
+ verScottishGaelic = 75,
+ verManxGaelic = 76,
+ verBreton = 77,
+ verNunavut = 78,
+ verWelsh = 79,
+
+ verIrishGaelicScript = 81,
+ verEngCanada = 82,
+ verBhutan = 83,
+ verArmenian = 84,
+ verGeorgian = 85,
+ verSpLatinAmerica = 86,
+
+ verTonga = 88,
+
+
+ verFrenchUniversal = 91,
+ verAustria = 92,
+
+ verGujarati = 94,
+ verPunjabi = 95,
+ verIndiaUrdu = 96,
+ verVietnam = 97
+};
+
+enum {
+ verFrBelgium = 98,
+ verUzbek = 99,
+ verSingapore = 100,
+ verNynorsk = 101,
+ verAfrikaans = 102,
+ verEsperanto = 103,
+ verMarathi = 104,
+ verTibetan = 105,
+ verNepal = 106,
+ verGreenland = 107,
+ verIrelandEnglish = 108
+};
+enum {
+ verFrBelgiumLux = 6,
+ verBelgiumLux = 6,
+ verArabia = 16,
+ verYugoslavia = 25,
+ verIndia = 33,
+ verPakistan = 34,
+ verRumania = 39,
+ verGreekAncient = 40,
+ verLapland = 46,
+ verFaeroeIsl = 47,
+ verGenericFE = 58,
+ verBelarus = 61,
+ verUkrania = 62,
+ verAlternateGr = 64,
+ verSerbia = 65,
+ verSlovenia = 66,
+ verMacedonia = 67,
+ verBrittany = 77,
+ verWales = 79,
+ verArmenia = 84,
+ verGeorgia = 85,
+ verAustriaGerman = 92,
+ verTibet = 105
+};
+
+enum {
+ minCountry = verUS,
+ maxCountry = verGreenland
+};
+
+enum {
+
+ calGregorian = 0,
+ calArabicCivil = 1,
+ calArabicLunar = 2,
+ calJapanese = 3,
+ calJewish = 4,
+ calCoptic = 5,
+ calPersian = 6
+};
+
+enum {
+
+ intWestern = 0,
+ intArabic = 1,
+ intRoman = 2,
+ intJapanese = 3,
+ intEuropean = 4,
+ intOutputMask = 0x8000
+};
+
+enum {
+
+ smSingleByte = 0,
+ smFirstByte = -1,
+ smLastByte = 1,
+ smMiddleByte = 2
+};
+
+enum {
+
+ smcTypeMask = 0x000F,
+ smcReserved = 0x00F0,
+ smcClassMask = 0x0F00,
+ smcOrientationMask = 0x1000,
+ smcRightMask = 0x2000,
+ smcUpperMask = 0x4000,
+ smcDoubleMask = 0x8000
+};
+
+enum {
+
+ smCharPunct = 0x0000,
+ smCharAscii = 0x0001,
+ smCharEuro = 0x0007,
+ smCharExtAscii = 0x0007,
+
+ smCharKatakana = 0x0002,
+ smCharHiragana = 0x0003,
+ smCharIdeographic = 0x0004,
+ smCharTwoByteGreek = 0x0005,
+ smCharTwoByteRussian = 0x0006,
+ smCharBidirect = 0x0008,
+ smCharContextualLR = 0x0009,
+ smCharNonContextualLR = 0x000A,
+ smCharHangul = 0x000C,
+ smCharJamo = 0x000D,
+ smCharBopomofo = 0x000E,
+ smCharGanaKana = 0x000F,
+
+ smCharFISKana = 0x0002,
+ smCharFISGana = 0x0003,
+ smCharFISIdeo = 0x0004
+};
+
+enum {
+ smCharFISGreek = 0x0005,
+ smCharFISRussian = 0x0006,
+
+ smPunctNormal = 0x0000,
+ smPunctNumber = 0x0100,
+ smPunctSymbol = 0x0200,
+ smPunctBlank = 0x0300,
+ smPunctRepeat = 0x0400,
+ smPunctGraphic = 0x0500,
+
+ smKanaSmall = 0x0100,
+ smKanaHardOK = 0x0200,
+ smKanaSoftOK = 0x0300,
+
+ smIdeographicLevel1 = 0x0000,
+ smIdeographicLevel2 = 0x0100,
+ smIdeographicUser = 0x0200,
+
+ smFISClassLvl1 = 0x0000,
+ smFISClassLvl2 = 0x0100,
+ smFISClassUser = 0x0200,
+
+ smJamoJaeum = 0x0000,
+ smJamoBogJaeum = 0x0100,
+ smJamoMoeum = 0x0200,
+ smJamoBogMoeum = 0x0300
+};
+
+enum {
+
+ smCharHorizontal = 0x0000,
+ smCharVertical = 0x1000,
+
+ smCharLeft = 0x0000,
+ smCharRight = 0x2000,
+ smCharLower = 0x0000,
+ smCharUpper = 0x4000,
+ smChar1byte = 0x0000,
+ smChar2byte = 0x8000
+};
+
+enum {
+
+ smTransAscii = 0,
+ smTransNative = 1,
+ smTransCase = 0xFE,
+ smTransSystem = 0xFF,
+
+ smTransAscii1 = 2,
+ smTransAscii2 = 3,
+ smTransKana1 = 4,
+ smTransKana2 = 5
+};
+
+enum {
+ smTransGana2 = 7,
+ smTransHangul2 = 8,
+ smTransJamo2 = 9,
+ smTransBopomofo2 = 10,
+
+ smTransLower = 0x4000,
+ smTransUpper = 0x8000,
+
+ smTransRuleBaseFormat = 1,
+ smTransHangulFormat = 2,
+
+ smTransPreDoubleByting = 1,
+ smTransPreLowerCasing = 2
+};
+
+enum {
+
+ smMaskAll = (long)0xFFFFFFFF,
+
+ smMaskAscii = 0x00000001,
+ smMaskNative = 0x00000002,
+
+ smMaskAscii1 = 0x00000004,
+ smMaskAscii2 = 0x00000008,
+ smMaskKana1 = 0x00000010,
+ smMaskKana2 = 0x00000020,
+ smMaskGana2 = 0x00000080,
+ smMaskHangul2 = 0x00000100,
+ smMaskJamo2 = 0x00000200,
+ smMaskBopomofo2 = 0x00000400
+};
+
+enum {
+
+ smNotInstalled = 0,
+ smBadVerb = -1,
+ smBadScript = -2
+};
+
+enum {
+
+ smRedrawChar = 0,
+ smRedrawWord = 1,
+ smRedrawLine = -1
+};
+
+enum {
+
+ smVersion = 0,
+ smMunged = 2,
+ smEnabled = 4,
+ smBidirect = 6,
+ smFontForce = 8,
+ smIntlForce = 10,
+ smForced = 12,
+ smDefault = 14,
+ smPrint = 16,
+ smSysScript = 18,
+ smLastScript = 20,
+ smKeyScript = 22,
+ smSysRef = 24,
+ smKeyCache = 26,
+ smKeySwap = 28,
+ smGenFlags = 30,
+ smOverride = 32,
+ smCharPortion = 34,
+
+ smDoubleByte = 36,
+ smKCHRCache = 38,
+ smRegionCode = 40,
+ smKeyDisableState = 42
+};
+
+enum {
+
+
+
+ smScriptVersion = 0,
+ smScriptMunged = 2,
+ smScriptEnabled = 4,
+ smScriptRight = 6,
+ smScriptJust = 8,
+ smScriptRedraw = 10,
+ smScriptSysFond = 12,
+ smScriptAppFond = 14,
+ smScriptBundle = 16,
+ smScriptNumber = 16,
+ smScriptDate = 18,
+ smScriptSort = 20,
+ smScriptFlags = 22,
+ smScriptToken = 24,
+ smScriptEncoding = 26,
+ smScriptLang = 28
+};
+
+enum {
+ smScriptNumDate = 30,
+ smScriptKeys = 32,
+ smScriptIcon = 34,
+ smScriptPrint = 36,
+ smScriptTrap = 38,
+ smScriptCreator = 40,
+ smScriptFile = 42,
+ smScriptName = 44,
+
+
+ smScriptMonoFondSize = 78,
+ smScriptPrefFondSize = 80,
+ smScriptSmallFondSize = 82,
+ smScriptSysFondSize = 84,
+ smScriptAppFondSize = 86,
+ smScriptHelpFondSize = 88,
+ smScriptValidStyles = 90,
+ smScriptAliasStyle = 92
+};
+
+
+
+enum {
+
+ smLayoutCache = -309,
+ smOldVerbSupport = -311,
+ smSetKashidas = -291,
+ smSetKashProp = -287,
+ smScriptSysBase = -281,
+ smScriptAppBase = -283,
+ smScriptFntBase = -285,
+ smScriptLigatures = -263,
+ smScriptNumbers = -267
+};
+
+enum {
+
+ iuSystemScript = -1,
+ iuCurrentScript = -2
+};
+
+enum {
+
+ smKeyNextScript = -1,
+ smKeySysScript = -2,
+ smKeySwapScript = -3,
+
+ smKeyNextKybd = -4,
+ smKeySwapKybd = -5,
+ smKeyDisableKybds = -6,
+ smKeyEnableKybds = -7,
+ smKeyToggleInline = -8,
+ smKeyToggleDirection = -9,
+ smKeyNextInputMethod = -10,
+ smKeySwapInputMethod = -11,
+ smKeyDisableKybdSwitch = -12,
+ smKeySetDirLeftRight = -15,
+ smKeySetDirRightLeft = -16,
+ smKeyRoman = -17
+};
+
+
+enum {
+
+ smfDisableKeyScriptSync = 27
+};
+
+enum {
+
+ smfDisableKeyScriptSyncMask = 1L << smfDisableKeyScriptSync
+};
+
+enum {
+
+ smKeyForceKeyScriptBit = 7,
+ smKeyForceKeyScriptMask = 1 << smKeyForceKeyScriptBit
+};
+
+enum {
+
+
+ smsfIntellCP = 0,
+ smsfSingByte = 1,
+ smsfNatCase = 2,
+ smsfContext = 3,
+ smsfNoForceFont = 4,
+ smsfB0Digits = 5,
+ smsfAutoInit = 6,
+ smsfUnivExt = 7,
+ smsfSynchUnstyledTE = 8,
+ smsfForms = 13,
+ smsfLigatures = 14,
+ smsfReverse = 15,
+
+
+ smfShowIcon = 31,
+ smfDualCaret = 30,
+ smfNameTagEnab = 29,
+ smfUseAssocFontInfo = 28
+};
+
+enum {
+
+
+
+ romanSysFond = 0x3FFF,
+ romanAppFond = 3,
+ romanFlags = 0x0007,
+
+ smFondStart = 0x4000,
+ smFondEnd = 0xC000,
+
+ smUprHalfCharSet = 0x80
+};
+
+enum {
+
+ diaeresisUprY = 0xD9,
+ fraction = 0xDA,
+ intlCurrency = 0xDB,
+ leftSingGuillemet = 0xDC,
+ rightSingGuillemet = 0xDD,
+ fiLigature = 0xDE,
+ flLigature = 0xDF,
+ dblDagger = 0xE0,
+ centeredDot = 0xE1,
+ baseSingQuote = 0xE2,
+ baseDblQuote = 0xE3,
+ perThousand = 0xE4,
+ circumflexUprA = 0xE5,
+ circumflexUprE = 0xE6,
+ acuteUprA = 0xE7,
+ diaeresisUprE = 0xE8,
+ graveUprE = 0xE9,
+ acuteUprI = 0xEA,
+ circumflexUprI = 0xEB,
+ diaeresisUprI = 0xEC,
+ graveUprI = 0xED,
+ acuteUprO = 0xEE,
+ circumflexUprO = 0xEF,
+ appleLogo = 0xF0,
+ graveUprO = 0xF1,
+ acuteUprU = 0xF2,
+ circumflexUprU = 0xF3,
+ graveUprU = 0xF4,
+ dotlessLwrI = 0xF5,
+ circumflex = 0xF6,
+ tilde = 0xF7,
+ macron = 0xF8,
+ breveMark = 0xF9,
+ overDot = 0xFA,
+ ringMark = 0xFB,
+ cedilla = 0xFC,
+ doubleAcute = 0xFD,
+ ogonek = 0xFE,
+ hachek = 0xFF
+};
+
+enum {
+
+ tokenIntl = 4,
+ tokenEmpty = -1
+};
+
+enum {
+ tokenUnknown = 0,
+ tokenWhite = 1,
+ tokenLeftLit = 2,
+ tokenRightLit = 3,
+ tokenAlpha = 4,
+ tokenNumeric = 5,
+ tokenNewLine = 6,
+ tokenLeftComment = 7,
+ tokenRightComment = 8,
+ tokenLiteral = 9,
+ tokenEscape = 10,
+ tokenAltNum = 11,
+ tokenRealNum = 12,
+ tokenAltReal = 13,
+ tokenReserve1 = 14,
+ tokenReserve2 = 15,
+ tokenLeftParen = 16,
+ tokenRightParen = 17,
+ tokenLeftBracket = 18,
+ tokenRightBracket = 19
+};
+
+enum {
+ tokenLeftCurly = 20,
+ tokenRightCurly = 21,
+ tokenLeftEnclose = 22,
+ tokenRightEnclose = 23,
+ tokenPlus = 24,
+ tokenMinus = 25,
+ tokenAsterisk = 26,
+ tokenDivide = 27,
+ tokenPlusMinus = 28,
+ tokenSlash = 29,
+ tokenBackSlash = 30,
+ tokenLess = 31,
+ tokenGreat = 32,
+ tokenEqual = 33,
+ tokenLessEqual2 = 34,
+ tokenLessEqual1 = 35,
+ tokenGreatEqual2 = 36,
+ tokenGreatEqual1 = 37,
+ token2Equal = 38,
+ tokenColonEqual = 39
+};
+
+enum {
+ tokenNotEqual = 40,
+ tokenLessGreat = 41,
+ tokenExclamEqual = 42,
+ tokenExclam = 43,
+ tokenTilde = 44,
+ tokenComma = 45,
+ tokenPeriod = 46,
+ tokenLeft2Quote = 47,
+ tokenRight2Quote = 48,
+ tokenLeft1Quote = 49,
+ tokenRight1Quote = 50,
+ token2Quote = 51,
+ token1Quote = 52,
+ tokenSemicolon = 53,
+ tokenPercent = 54,
+ tokenCaret = 55,
+ tokenUnderline = 56,
+ tokenAmpersand = 57,
+ tokenAtSign = 58,
+ tokenBar = 59
+};
+
+enum {
+ tokenQuestion = 60,
+ tokenPi = 61,
+ tokenRoot = 62,
+ tokenSigma = 63,
+ tokenIntegral = 64,
+ tokenMicro = 65,
+ tokenCapPi = 66,
+ tokenInfinity = 67,
+ tokenColon = 68,
+ tokenHash = 69,
+ tokenDollar = 70,
+ tokenNoBreakSpace = 71,
+ tokenFraction = 72,
+ tokenIntlCurrency = 73,
+ tokenLeftSingGuillemet = 74,
+ tokenRightSingGuillemet = 75,
+ tokenPerThousand = 76,
+ tokenEllipsis = 77,
+ tokenCenterDot = 78,
+ tokenNil = 127
+};
+
+enum {
+ delimPad = -2,
+ tokenTilda = 44,
+ tokenCarat = 55
+};
+
+enum {
+
+ smWordSelectTable = 0,
+ smWordWrapTable = 1,
+ smNumberPartsTable = 2,
+ smUnTokenTable = 3,
+ smWhiteSpaceList = 4,
+ iuWordSelectTable = 0,
+ iuWordWrapTable = 1,
+ iuNumberPartsTable = 2,
+ iuUnTokenTable = 3,
+ iuWhiteSpaceList = 4
+};
+
+
+enum {
+ tokenOK = 0,
+ tokenOverflow = 1,
+ stringOverflow = 2,
+ badDelim = 3,
+ badEnding = 4,
+ crash = 5
+};
+
+typedef SInt8 TokenResults;
+typedef char CharByteTable[256];
+
+typedef short ScriptTokenType;
+typedef ScriptTokenType DelimType[2];
+typedef ScriptTokenType CommentType[4];
+struct TokenRec {
+ ScriptTokenType theToken;
+ Ptr position;
+ long length;
+ StringPtr stringPosition;
+};
+typedef struct TokenRec TokenRec;
+typedef TokenRec * TokenRecPtr;
+struct TokenBlock {
+ Ptr source;
+ long sourceLength;
+ Ptr tokenList;
+ long tokenLength;
+ long tokenCount;
+ Ptr stringList;
+ long stringLength;
+ long stringCount;
+ Boolean doString;
+ Boolean doAppend;
+ Boolean doAlphanumeric;
+ Boolean doNest;
+ ScriptTokenType leftDelims[2];
+ ScriptTokenType rightDelims[2];
+ ScriptTokenType leftComment[4];
+ ScriptTokenType rightComment[4];
+ ScriptTokenType escapeCode;
+ ScriptTokenType decimalCode;
+ Handle itlResource;
+ long reserved[8];
+};
+typedef struct TokenBlock TokenBlock;
+typedef TokenBlock * TokenBlockPtr;
+extern short
+GetSysDirection(void) ;
+extern void
+SetSysDirection(short value) ;
+extern short
+FontScript(void) ;
+extern short
+IntlScript(void) ;
+extern short
+FontToScript(short fontNumber) ;
+extern long
+GetScriptManagerVariable(short selector) ;
+extern OSErr
+SetScriptManagerVariable(
+ short selector,
+ long param) ;
+extern long
+GetScriptVariable(
+ short script,
+ short selector) ;
+extern OSErr
+SetScriptVariable(
+ short script,
+ short selector,
+ long param) ;
+extern short
+CharacterByteType(
+ Ptr textBuf,
+ short textOffset,
+ ScriptCode script) ;
+extern short
+CharacterType(
+ Ptr textBuf,
+ short textOffset,
+ ScriptCode script) ;
+extern OSErr
+TransliterateText(
+ Handle srcHandle,
+ Handle dstHandle,
+ short target,
+ long srcMask,
+ ScriptCode script) ;
+extern Boolean
+FillParseTable(
+ CharByteTable table,
+ ScriptCode script) ;
+extern Handle
+GetIntlResource(short theID) ;
+extern void
+ClearIntlResourceCache(void) ;
+extern void
+GetIntlResourceTable(
+ ScriptCode script,
+ short tableCode,
+ Handle * itlHandle,
+ long * offset,
+ long * length) ;
+extern TokenResults
+IntlTokenize(TokenBlockPtr tokenParam) ;
+
+
+}
+
+
+
+extern "C" {
+
+
+enum {
+ paramErr = -50,
+ noHardwareErr = -200,
+ notEnoughHardwareErr = -201,
+ userCanceledErr = -128,
+ qErr = -1,
+ vTypErr = -2,
+ corErr = -3,
+ unimpErr = -4,
+ SlpTypeErr = -5,
+ seNoDB = -8,
+ controlErr = -17,
+ statusErr = -18,
+ readErr = -19,
+ writErr = -20,
+ badUnitErr = -21,
+ unitEmptyErr = -22,
+ openErr = -23,
+ closErr = -24,
+ dRemovErr = -25,
+ dInstErr = -26
+};
+
+enum {
+ abortErr = -27,
+ iIOAbortErr = -27,
+ notOpenErr = -28,
+ unitTblFullErr = -29,
+ dceExtErr = -30,
+ slotNumErr = -360,
+ gcrOnMFMErr = -400,
+ dirFulErr = -33,
+ dskFulErr = -34,
+ nsvErr = -35,
+ ioErr = -36,
+ bdNamErr = -37,
+ fnOpnErr = -38,
+ eofErr = -39,
+ posErr = -40,
+ mFulErr = -41,
+ tmfoErr = -42,
+ fnfErr = -43,
+ wPrErr = -44,
+ fLckdErr = -45
+};
+
+enum {
+ vLckdErr = -46,
+ fBsyErr = -47,
+ dupFNErr = -48,
+ opWrErr = -49,
+ rfNumErr = -51,
+ gfpErr = -52,
+ volOffLinErr = -53,
+ permErr = -54,
+ volOnLinErr = -55,
+ nsDrvErr = -56,
+ noMacDskErr = -57,
+ extFSErr = -58,
+ fsRnErr = -59,
+ badMDBErr = -60,
+ wrPermErr = -61,
+ dirNFErr = -120,
+ tmwdoErr = -121,
+ badMovErr = -122,
+ wrgVolTypErr = -123,
+ volGoneErr = -124
+};
+
+enum {
+ fidNotFound = -1300,
+ fidExists = -1301,
+ notAFileErr = -1302,
+ diffVolErr = -1303,
+ catChangedErr = -1304,
+ desktopDamagedErr = -1305,
+ sameFileErr = -1306,
+ badFidErr = -1307,
+ notARemountErr = -1308,
+ fileBoundsErr = -1309,
+ fsDataTooBigErr = -1310,
+ volVMBusyErr = -1311,
+ badFCBErr = -1327,
+ errFSUnknownCall = -1400,
+ errFSBadFSRef = -1401,
+ errFSBadForkName = -1402,
+ errFSBadBuffer = -1403,
+ errFSBadForkRef = -1404,
+ errFSBadInfoBitmap = -1405,
+ errFSMissingCatInfo = -1406,
+ errFSNotAFolder = -1407,
+ errFSForkNotFound = -1409,
+ errFSNameTooLong = -1410,
+ errFSMissingName = -1411,
+ errFSBadPosMode = -1412,
+ errFSBadAllocFlags = -1413,
+ errFSNoMoreItems = -1417,
+ errFSBadItemCount = -1418,
+ errFSBadSearchParams = -1419,
+ errFSRefsDifferent = -1420,
+ errFSForkExists = -1421,
+ errFSBadIteratorFlags = -1422,
+ errFSIteratorNotFound = -1423,
+ errFSIteratorNotSupported = -1424,
+ errFSQuotaExceeded = -1425,
+ envNotPresent = -5500,
+ envBadVers = -5501,
+ envVersTooBig = -5502,
+ fontDecError = -64,
+ fontNotDeclared = -65,
+ fontSubErr = -66,
+ fontNotOutlineErr = -32615,
+ firstDskErr = -84,
+ lastDskErr = -64,
+ noDriveErr = -64,
+ offLinErr = -65,
+ noNybErr = -66
+};
+
+enum {
+ noAdrMkErr = -67,
+ dataVerErr = -68,
+ badCksmErr = -69,
+ badBtSlpErr = -70,
+ noDtaMkErr = -71,
+ badDCksum = -72,
+ badDBtSlp = -73,
+ wrUnderrun = -74,
+ cantStepErr = -75,
+ tk0BadErr = -76,
+ initIWMErr = -77,
+ twoSideErr = -78,
+ spdAdjErr = -79,
+ seekErr = -80,
+ sectNFErr = -81,
+ fmt1Err = -82,
+ fmt2Err = -83,
+ verErr = -84,
+ clkRdErr = -85,
+ clkWrErr = -86,
+ prWrErr = -87,
+ prInitErr = -88,
+ rcvrErr = -89,
+ breakRecd = -90
+};
+
+enum {
+
+ noScrapErr = -100,
+ noTypeErr = -102
+};
+
+enum {
+
+ eLenErr = -92,
+ eMultiErr = -91
+};
+
+enum {
+ ddpSktErr = -91,
+ ddpLenErr = -92,
+ noBridgeErr = -93,
+ lapProtErr = -94,
+ excessCollsns = -95,
+ portNotPwr = -96,
+ portInUse = -97,
+ portNotCf = -98
+};
+
+enum {
+
+ memROZWarn = -99,
+ memROZError = -99,
+ memROZErr = -99,
+ memFullErr = -108,
+ nilHandleErr = -109,
+ memWZErr = -111,
+ memPurErr = -112,
+ memAdrErr = -110,
+ memAZErr = -113,
+ memPCErr = -114,
+ memBCErr = -115,
+ memSCErr = -116,
+ memLockedErr = -117
+};
+
+enum {
+
+ iMemFullErr = -108,
+ iIOAbort = -27
+};
+
+
+enum {
+ resourceInMemory = -188,
+ writingPastEnd = -189,
+ inputOutOfBounds = -190,
+ resNotFound = -192,
+ resFNotFound = -193,
+ addResFailed = -194,
+ addRefFailed = -195,
+ rmvResFailed = -196,
+ rmvRefFailed = -197,
+ resAttrErr = -198,
+ mapReadErr = -199,
+ CantDecompress = -186,
+ badExtResource = -185,
+ noMemForPictPlaybackErr = -145,
+ rgnOverflowErr = -147,
+ rgnTooBigError = -147,
+ pixMapTooDeepErr = -148,
+ insufficientStackErr = -149,
+ nsStackErr = -149
+};
+
+enum {
+ evtNotEnb = 1
+};
+
+
+enum {
+ cMatchErr = -150,
+ cTempMemErr = -151,
+ cNoMemErr = -152,
+ cRangeErr = -153,
+ cProtectErr = -154,
+ cDevErr = -155,
+ cResErr = -156,
+ cDepthErr = -157,
+ rgnTooBigErr = -500,
+ updPixMemErr = -125,
+ pictInfoVersionErr = -11000,
+ pictInfoIDErr = -11001,
+ pictInfoVerbErr = -11002,
+ cantLoadPickMethodErr = -11003,
+ colorsRequestedErr = -11004,
+ pictureDataErr = -11005
+};
+
+
+enum {
+
+ cmProfileError = -170,
+ cmMethodError = -171,
+ cmMethodNotFound = -175,
+ cmProfileNotFound = -176,
+ cmProfilesIdentical = -177,
+ cmCantConcatenateError = -178,
+ cmCantXYZ = -179,
+ cmCantDeleteProfile = -180,
+ cmUnsupportedDataType = -181,
+ cmNoCurrentProfile = -182
+};
+
+
+enum {
+
+ noHardware = noHardwareErr,
+ notEnoughHardware = notEnoughHardwareErr,
+ queueFull = -203,
+ resProblem = -204,
+ badChannel = -205,
+ badFormat = -206,
+ notEnoughBufferSpace = -207,
+ badFileFormat = -208,
+ channelBusy = -209,
+ buffersTooSmall = -210,
+ channelNotBusy = -211,
+ noMoreRealTime = -212,
+ siVBRCompressionNotSupported = -213,
+ siNoSoundInHardware = -220,
+ siBadSoundInDevice = -221,
+ siNoBufferSpecified = -222,
+ siInvalidCompression = -223,
+ siHardDriveTooSlow = -224,
+ siInvalidSampleRate = -225,
+ siInvalidSampleSize = -226,
+ siDeviceBusyErr = -227,
+ siBadDeviceName = -228,
+ siBadRefNum = -229,
+ siInputDeviceErr = -230,
+ siUnknownInfoType = -231,
+ siUnknownQuality = -232
+};
+
+
+enum {
+ noSynthFound = -240,
+ synthOpenFailed = -241,
+ synthNotReady = -242,
+ bufTooSmall = -243,
+ voiceNotFound = -244,
+ incompatibleVoice = -245,
+ badDictFormat = -246,
+ badInputText = -247
+};
+
+
+enum {
+ midiNoClientErr = -250,
+ midiNoPortErr = -251,
+ midiTooManyPortsErr = -252,
+ midiTooManyConsErr = -253,
+ midiVConnectErr = -254,
+ midiVConnectMade = -255,
+ midiVConnectRmvd = -256,
+ midiNoConErr = -257,
+ midiWriteErr = -258,
+ midiNameLenErr = -259,
+ midiDupIDErr = -260,
+ midiInvalidCmdErr = -261
+};
+
+
+enum {
+ nmTypErr = -299
+};
+
+
+enum {
+ siInitSDTblErr = 1,
+ siInitVBLQsErr = 2,
+ siInitSPTblErr = 3,
+ sdmJTInitErr = 10,
+ sdmInitErr = 11,
+ sdmSRTInitErr = 12,
+ sdmPRAMInitErr = 13,
+ sdmPriInitErr = 14
+};
+
+enum {
+ smSDMInitErr = -290,
+ smSRTInitErr = -291,
+ smPRAMInitErr = -292,
+ smPriInitErr = -293,
+ smEmptySlot = -300,
+ smCRCFail = -301,
+ smFormatErr = -302,
+ smRevisionErr = -303,
+ smNoDir = -304,
+ smDisabledSlot = -305,
+ smNosInfoArray = -306
+};
+
+
+enum {
+ smResrvErr = -307,
+ smUnExBusErr = -308,
+ smBLFieldBad = -309,
+ smFHBlockRdErr = -310,
+ smFHBlkDispErr = -311,
+ smDisposePErr = -312,
+ smNoBoardSRsrc = -313,
+ smGetPRErr = -314,
+ smNoBoardId = -315,
+ smInitStatVErr = -316,
+ smInitTblVErr = -317,
+ smNoJmpTbl = -318,
+ smReservedSlot = -318,
+ smBadBoardId = -319,
+ smBusErrTO = -320,
+
+ svTempDisable = -32768L,
+ svDisabled = -32640,
+ smBadRefId = -330,
+ smBadsList = -331,
+ smReservedErr = -332,
+ smCodeRevErr = -333
+};
+
+enum {
+ smCPUErr = -334,
+ smsPointerNil = -335,
+ smNilsBlockErr = -336,
+ smSlotOOBErr = -337,
+ smSelOOBErr = -338,
+ smNewPErr = -339,
+ smBlkMoveErr = -340,
+ smCkStatusErr = -341,
+ smGetDrvrNamErr = -342,
+ smDisDrvrNamErr = -343,
+ smNoMoresRsrcs = -344,
+ smsGetDrvrErr = -345,
+ smBadsPtrErr = -346,
+ smByteLanesErr = -347,
+ smOffsetErr = -348,
+ smNoGoodOpens = -349,
+ smSRTOvrFlErr = -350,
+ smRecNotFnd = -351
+};
+
+
+enum {
+
+ notBTree = -410,
+ btNoSpace = -413,
+ btDupRecErr = -414,
+ btRecNotFnd = -415,
+ btKeyLenErr = -416,
+ btKeyAttrErr = -417,
+ unknownInsertModeErr = -20000,
+ recordDataTooBigErr = -20001,
+ invalidIndexErr = -20002
+};
+
+
+
+
+
+enum {
+ fsmFFSNotFoundErr = -431,
+ fsmBusyFFSErr = -432,
+ fsmBadFFSNameErr = -433,
+ fsmBadFSDLenErr = -434,
+ fsmDuplicateFSIDErr = -435,
+ fsmBadFSDVersionErr = -436,
+ fsmNoAlternateStackErr = -437,
+ fsmUnknownFSMMessageErr = -438
+};
+
+
+enum {
+
+ editionMgrInitErr = -450,
+ badSectionErr = -451,
+ notRegisteredSectionErr = -452,
+ badEditionFileErr = -453,
+ badSubPartErr = -454,
+ multiplePublisherWrn = -460,
+ containerNotFoundWrn = -461,
+ containerAlreadyOpenWrn = -462,
+ notThePublisherWrn = -463
+};
+
+enum {
+ teScrapSizeErr = -501,
+ hwParamErr = -502,
+ driverHardwareGoneErr = -503
+};
+
+enum {
+
+ procNotFound = -600,
+ memFragErr = -601,
+ appModeErr = -602,
+ protocolErr = -603,
+ hardwareConfigErr = -604,
+ appMemFullErr = -605,
+ appIsDaemon = -606,
+ bufferIsSmall = -607,
+ noOutstandingHLE = -608,
+ connectionInvalid = -609,
+ noUserInteractionAllowed = -610
+};
+
+enum {
+
+ wrongApplicationPlatform = -875,
+ appVersionTooOld = -876,
+ notAppropriateForClassic = -877
+};
+
+
+enum {
+ threadTooManyReqsErr = -617,
+ threadNotFoundErr = -618,
+ threadProtocolErr = -619
+};
+
+enum {
+ threadBadAppContextErr = -616
+};
+
+
+enum {
+ notEnoughMemoryErr = -620,
+ notHeldErr = -621,
+ cannotMakeContiguousErr = -622,
+ notLockedErr = -623,
+ interruptsMaskedErr = -624,
+ cannotDeferErr = -625,
+ noMMUErr = -626
+};
+
+
+enum {
+ vmMorePhysicalThanVirtualErr = -628,
+ vmKernelMMUInitErr = -629,
+ vmOffErr = -630,
+ vmMemLckdErr = -631,
+ vmBadDriver = -632,
+ vmNoVectorErr = -633
+};
+
+
+enum {
+ vmInvalidBackingFileIDErr = -640,
+ vmMappingPrivilegesErr = -641,
+ vmBusyBackingFileErr = -642,
+ vmNoMoreBackingFilesErr = -643,
+ vmInvalidFileViewIDErr = -644,
+ vmFileViewAccessErr = -645,
+ vmNoMoreFileViewsErr = -646,
+ vmAddressNotInFileViewErr = -647,
+ vmInvalidOwningProcessErr = -648
+};
+
+
+enum {
+ rcDBNull = -800,
+ rcDBValue = -801,
+ rcDBError = -802,
+ rcDBBadType = -803,
+ rcDBBreak = -804,
+ rcDBExec = -805,
+ rcDBBadSessID = -806,
+ rcDBBadSessNum = -807,
+ rcDBBadDDEV = -808,
+ rcDBAsyncNotSupp = -809,
+ rcDBBadAsyncPB = -810,
+ rcDBNoHandler = -811,
+ rcDBWrongVersion = -812,
+ rcDBPackNotInited = -813
+};
+
+
+
+enum {
+ hmHelpDisabled = -850,
+ hmBalloonAborted = -853,
+ hmSameAsLastBalloon = -854,
+ hmHelpManagerNotInited = -855,
+ hmSkippedBalloon = -857,
+ hmWrongVersion = -858,
+ hmUnknownHelpType = -859,
+ hmOperationUnsupported = -861,
+ hmNoBalloonUp = -862,
+ hmCloseViewActive = -863
+};
+
+
+
+enum {
+
+ notInitErr = -900,
+ nameTypeErr = -902,
+ noPortErr = -903,
+
+
+ noGlobalsErr = -904,
+ localOnlyErr = -905,
+ destPortErr = -906,
+ sessTableErr = -907,
+ noSessionErr = -908,
+ badReqErr = -909,
+ portNameExistsErr = -910,
+ noUserNameErr = -911,
+ userRejectErr = -912,
+ noMachineNameErr = -913,
+ noToolboxNameErr = -914,
+ noResponseErr = -915,
+ portClosedErr = -916,
+ sessClosedErr = -917,
+ badPortNameErr = -919,
+ noDefaultUserErr = -922,
+ notLoggedInErr = -923,
+ noUserRefErr = -924,
+ networkErr = -925,
+ noInformErr = -926,
+ authFailErr = -927,
+ noUserRecErr = -928,
+ badServiceMethodErr = -930,
+ badLocNameErr = -931,
+ guestNotAllowedErr = -932
+};
+
+
+enum {
+ kFMIterationCompleted = -980L,
+ kFMInvalidFontFamilyErr = -981L,
+ kFMInvalidFontErr = -982L,
+ kFMIterationScopeModifiedErr = -983L,
+ kFMFontTableAccessErr = -984L,
+ kFMFontContainerAccessErr = -985L
+};
+
+enum {
+ noMaskFoundErr = -1000
+};
+
+enum {
+ nbpBuffOvr = -1024,
+ nbpNoConfirm = -1025,
+ nbpConfDiff = -1026,
+ nbpDuplicate = -1027,
+ nbpNotFound = -1028,
+ nbpNISErr = -1029
+};
+
+enum {
+ aspBadVersNum = -1066,
+ aspBufTooSmall = -1067,
+ aspNoMoreSess = -1068,
+ aspNoServers = -1069,
+ aspParamErr = -1070,
+ aspServerBusy = -1071,
+ aspSessClosed = -1072,
+ aspSizeErr = -1073,
+ aspTooMany = -1074,
+ aspNoAck = -1075
+};
+
+enum {
+ reqFailed = -1096,
+ tooManyReqs = -1097,
+ tooManySkts = -1098,
+ badATPSkt = -1099,
+ badBuffNum = -1100,
+ noRelErr = -1101,
+ cbNotFound = -1102,
+ noSendResp = -1103,
+ noDataArea = -1104,
+ reqAborted = -1105
+};
+
+
+enum {
+
+ errRefNum = -1280,
+ errAborted = -1279,
+ errState = -1278,
+ errOpening = -1277,
+ errAttention = -1276,
+ errFwdReset = -1275,
+ errDSPQueueSize = -1274,
+ errOpenDenied = -1273
+};
+
+
+
+
+
+
+enum {
+ errAECoercionFail = -1700,
+ errAEDescNotFound = -1701,
+ errAECorruptData = -1702,
+ errAEWrongDataType = -1703,
+ errAENotAEDesc = -1704,
+ errAEBadListItem = -1705,
+ errAENewerVersion = -1706,
+ errAENotAppleEvent = -1707,
+ errAEEventNotHandled = -1708,
+ errAEReplyNotValid = -1709,
+ errAEUnknownSendMode = -1710,
+ errAEWaitCanceled = -1711,
+ errAETimeout = -1712,
+ errAENoUserInteraction = -1713,
+ errAENotASpecialFunction = -1714,
+ errAEParamMissed = -1715,
+ errAEUnknownAddressType = -1716,
+ errAEHandlerNotFound = -1717,
+ errAEReplyNotArrived = -1718,
+ errAEIllegalIndex = -1719,
+ errAEImpossibleRange = -1720,
+ errAEWrongNumberArgs = -1721,
+ errAEAccessorNotFound = -1723,
+ errAENoSuchLogical = -1725,
+ errAEBadTestKey = -1726,
+ errAENotAnObjSpec = -1727,
+ errAENoSuchObject = -1728,
+ errAENegativeCount = -1729,
+ errAEEmptyListContainer = -1730,
+ errAEUnknownObjectType = -1731,
+ errAERecordingIsAlreadyOn = -1732,
+ errAEReceiveTerminate = -1733,
+ errAEReceiveEscapeCurrent = -1734,
+ errAEEventFiltered = -1735,
+ errAEDuplicateHandler = -1736,
+ errAEStreamBadNesting = -1737,
+ errAEStreamAlreadyConverted = -1738,
+ errAEDescIsNull = -1739,
+ errAEBuildSyntaxError = -1740,
+ errAEBufferTooSmall = -1741
+};
+
+enum {
+ errOSASystemError = -1750,
+ errOSAInvalidID = -1751,
+ errOSABadStorageType = -1752,
+ errOSAScriptError = -1753,
+ errOSABadSelector = -1754,
+ errOSASourceNotAvailable = -1756,
+ errOSANoSuchDialect = -1757,
+ errOSADataFormatObsolete = -1758,
+ errOSADataFormatTooNew = -1759,
+ errOSACorruptData = errAECorruptData,
+ errOSARecordingIsAlreadyOn = errAERecordingIsAlreadyOn,
+ errOSAComponentMismatch = -1761,
+ errOSACantOpenComponent = -1762
+};
+
+
+
+
+enum {
+ errOffsetInvalid = -1800,
+ errOffsetIsOutsideOfView = -1801,
+ errTopOfDocument = -1810,
+ errTopOfBody = -1811,
+ errEndOfDocument = -1812,
+ errEndOfBody = -1813
+};
+
+
+enum {
+
+ badDragRefErr = -1850,
+ badDragItemErr = -1851,
+ badDragFlavorErr = -1852,
+ duplicateFlavorErr = -1853,
+ cantGetFlavorErr = -1854,
+ duplicateHandlerErr = -1855,
+ handlerNotFoundErr = -1856,
+ dragNotAcceptedErr = -1857,
+ unsupportedForPlatformErr = -1858,
+ noSuitableDisplaysErr = -1859,
+ badImageRgnErr = -1860,
+ badImageErr = -1861,
+ nonDragOriginatorErr = -1862
+};
+
+
+
+enum {
+ couldNotResolveDataRef = -2000,
+ badImageDescription = -2001,
+ badPublicMovieAtom = -2002,
+ cantFindHandler = -2003,
+ cantOpenHandler = -2004,
+ badComponentType = -2005,
+ noMediaHandler = -2006,
+ noDataHandler = -2007,
+ invalidMedia = -2008,
+ invalidTrack = -2009,
+ invalidMovie = -2010,
+ invalidSampleTable = -2011,
+ invalidDataRef = -2012,
+ invalidHandler = -2013,
+ invalidDuration = -2014,
+ invalidTime = -2015,
+ cantPutPublicMovieAtom = -2016,
+ badEditList = -2017,
+ mediaTypesDontMatch = -2018,
+ progressProcAborted = -2019,
+ movieToolboxUninitialized = -2020,
+ noRecordOfApp = movieToolboxUninitialized,
+ wfFileNotFound = -2021,
+ cantCreateSingleForkFile = -2022,
+ invalidEditState = -2023,
+ nonMatchingEditState = -2024,
+ staleEditState = -2025,
+ userDataItemNotFound = -2026,
+ maxSizeToGrowTooSmall = -2027,
+ badTrackIndex = -2028,
+ trackIDNotFound = -2029,
+ trackNotInMovie = -2030,
+ timeNotInTrack = -2031,
+ timeNotInMedia = -2032,
+ badEditIndex = -2033,
+ internalQuickTimeError = -2034,
+ cantEnableTrack = -2035,
+ invalidRect = -2036,
+ invalidSampleNum = -2037,
+ invalidChunkNum = -2038,
+ invalidSampleDescIndex = -2039,
+ invalidChunkCache = -2040,
+ invalidSampleDescription = -2041,
+ dataNotOpenForRead = -2042,
+ dataNotOpenForWrite = -2043,
+ dataAlreadyOpenForWrite = -2044,
+ dataAlreadyClosed = -2045,
+ endOfDataReached = -2046,
+ dataNoDataRef = -2047,
+ noMovieFound = -2048,
+ invalidDataRefContainer = -2049,
+ badDataRefIndex = -2050,
+ noDefaultDataRef = -2051,
+ couldNotUseAnExistingSample = -2052,
+ featureUnsupported = -2053,
+ noVideoTrackInMovieErr = -2054,
+ noSoundTrackInMovieErr = -2055,
+ soundSupportNotAvailableErr = -2056,
+ unsupportedAuxiliaryImportData = -2057,
+ auxiliaryExportDataUnavailable = -2058,
+ samplesAlreadyInMediaErr = -2059,
+ noSourceTreeFoundErr = -2060,
+ sourceNotFoundErr = -2061,
+ movieTextNotFoundErr = -2062,
+ missingRequiredParameterErr = -2063,
+ invalidSpriteWorldPropertyErr = -2064,
+ invalidSpritePropertyErr = -2065,
+ gWorldsNotSameDepthAndSizeErr = -2066,
+ invalidSpriteIndexErr = -2067,
+ invalidImageIndexErr = -2068,
+ invalidSpriteIDErr = -2069
+};
+
+enum {
+ internalComponentErr = -2070,
+ notImplementedMusicOSErr = -2071,
+ cantSendToSynthesizerOSErr = -2072,
+ cantReceiveFromSynthesizerOSErr = -2073,
+ illegalVoiceAllocationOSErr = -2074,
+ illegalPartOSErr = -2075,
+ illegalChannelOSErr = -2076,
+ illegalKnobOSErr = -2077,
+ illegalKnobValueOSErr = -2078,
+ illegalInstrumentOSErr = -2079,
+ illegalControllerOSErr = -2080,
+ midiManagerAbsentOSErr = -2081,
+ synthesizerNotRespondingOSErr = -2082,
+ synthesizerOSErr = -2083,
+ illegalNoteChannelOSErr = -2084,
+ noteChannelNotAllocatedOSErr = -2085,
+ tunePlayerFullOSErr = -2086,
+ tuneParseOSErr = -2087,
+ noExportProcAvailableErr = -2089,
+ videoOutputInUseErr = -2090
+};
+
+enum {
+ componentDllLoadErr = -2091,
+ componentDllEntryNotFoundErr = -2092,
+ qtmlDllLoadErr = -2093,
+ qtmlDllEntryNotFoundErr = -2094,
+ qtmlUninitialized = -2095,
+ unsupportedOSErr = -2096,
+ unsupportedProcessorErr = -2097
+};
+
+enum {
+ cannotFindAtomErr = -2101,
+ notLeafAtomErr = -2102,
+ atomsNotOfSameTypeErr = -2103,
+ atomIndexInvalidErr = -2104,
+ duplicateAtomTypeAndIDErr = -2105,
+ invalidAtomErr = -2106,
+ invalidAtomContainerErr = -2107,
+ invalidAtomTypeErr = -2108,
+ cannotBeLeafAtomErr = -2109,
+ pathTooLongErr = -2110,
+ emptyPathErr = -2111,
+ noPathMappingErr = -2112,
+ pathNotVerifiedErr = -2113,
+ unknownFormatErr = -2114,
+ wackBadFileErr = -2115,
+ wackForkNotFoundErr = -2116,
+ wackBadMetaDataErr = -2117,
+ qfcbNotFoundErr = -2118,
+ qfcbNotCreatedErr = -2119,
+ AAPNotCreatedErr = -2120,
+ AAPNotFoundErr = -2121,
+ ASDBadHeaderErr = -2122,
+ ASDBadForkErr = -2123,
+ ASDEntryNotFoundErr = -2124,
+ fileOffsetTooBigErr = -2125,
+ notAllowedToSaveMovieErr = -2126,
+ qtNetworkAlreadyAllocatedErr = -2127,
+ urlDataHHTTPProtocolErr = -2129,
+ urlDataHHTTPNoNetDriverErr = -2130,
+ urlDataHHTTPURLErr = -2131,
+ urlDataHHTTPRedirectErr = -2132,
+ urlDataHFTPProtocolErr = -2133,
+ urlDataHFTPShutdownErr = -2134,
+ urlDataHFTPBadUserErr = -2135,
+ urlDataHFTPBadPasswordErr = -2136,
+ urlDataHFTPServerErr = -2137,
+ urlDataHFTPDataConnectionErr = -2138,
+ urlDataHFTPNoDirectoryErr = -2139,
+ urlDataHFTPQuotaErr = -2140,
+ urlDataHFTPPermissionsErr = -2141,
+ urlDataHFTPFilenameErr = -2142,
+ urlDataHFTPNoNetDriverErr = -2143,
+ urlDataHFTPBadNameListErr = -2144,
+ urlDataHFTPNeedPasswordErr = -2145,
+ urlDataHFTPNoPasswordErr = -2146,
+ urlDataHFTPServerDisconnectedErr = -2147,
+ urlDataHFTPURLErr = -2148,
+ notEnoughDataErr = -2149,
+ qtActionNotHandledErr = -2157,
+ qtXMLParseErr = -2158,
+ qtXMLApplicationErr = -2159
+};
+
+
+enum {
+ digiUnimpErr = -2201,
+ qtParamErr = -2202,
+ matrixErr = -2203,
+ notExactMatrixErr = -2204,
+ noMoreKeyColorsErr = -2205,
+ notExactSizeErr = -2206,
+ badDepthErr = -2207,
+ noDMAErr = -2208,
+ badCallOrderErr = -2209
+};
+
+
+
+enum {
+ kernelIncompleteErr = -2401,
+ kernelCanceledErr = -2402,
+ kernelOptionsErr = -2403,
+ kernelPrivilegeErr = -2404,
+ kernelUnsupportedErr = -2405,
+ kernelObjectExistsErr = -2406,
+ kernelWritePermissionErr = -2407,
+ kernelReadPermissionErr = -2408,
+ kernelExecutePermissionErr = -2409,
+ kernelDeletePermissionErr = -2410,
+ kernelExecutionLevelErr = -2411,
+ kernelAttributeErr = -2412,
+ kernelAsyncSendLimitErr = -2413,
+ kernelAsyncReceiveLimitErr = -2414,
+ kernelTimeoutErr = -2415,
+ kernelInUseErr = -2416,
+ kernelTerminatedErr = -2417,
+ kernelExceptionErr = -2418,
+ kernelIDErr = -2419,
+ kernelAlreadyFreeErr = -2421,
+ kernelReturnValueErr = -2422,
+ kernelUnrecoverableErr = -2499
+};
+
+
+
+enum {
+
+ tsmComponentNoErr = 0,
+ tsmUnsupScriptLanguageErr = -2500,
+ tsmInputMethodNotFoundErr = -2501,
+ tsmNotAnAppErr = -2502,
+ tsmAlreadyRegisteredErr = -2503,
+ tsmNeverRegisteredErr = -2504,
+ tsmInvalidDocIDErr = -2505,
+ tsmTSMDocBusyErr = -2506,
+ tsmDocNotActiveErr = -2507,
+ tsmNoOpenTSErr = -2508,
+ tsmCantOpenComponentErr = -2509,
+ tsmTextServiceNotFoundErr = -2510,
+ tsmDocumentOpenErr = -2511,
+ tsmUseInputWindowErr = -2512,
+ tsmTSHasNoMenuErr = -2513,
+ tsmTSNotOpenErr = -2514,
+ tsmComponentAlreadyOpenErr = -2515,
+ tsmInputMethodIsOldErr = -2516,
+ tsmScriptHasNoIMErr = -2517,
+ tsmUnsupportedTypeErr = -2518,
+ tsmUnknownErr = -2519,
+ tsmInvalidContext = -2520,
+ tsmNoHandler = -2521,
+ tsmNoMoreTokens = -2522,
+ tsmNoStem = -2523,
+ tsmDefaultIsNotInputMethodErr = -2524,
+ tsmDocPropertyNotFoundErr = -2528,
+ tsmDocPropertyBufferTooSmallErr = -2529,
+ tsmCantChangeForcedClassStateErr = -2530
+};
+
+
+enum {
+
+ mmInternalError = -2526
+};
+
+
+enum {
+ nrLockedErr = -2536,
+ nrNotEnoughMemoryErr = -2537,
+ nrInvalidNodeErr = -2538,
+ nrNotFoundErr = -2539,
+ nrNotCreatedErr = -2540,
+ nrNameErr = -2541,
+ nrNotSlotDeviceErr = -2542,
+ nrDataTruncatedErr = -2543,
+ nrPowerErr = -2544,
+ nrPowerSwitchAbortErr = -2545,
+ nrTypeMismatchErr = -2546,
+ nrNotModifiedErr = -2547,
+ nrOverrunErr = -2548,
+ nrResultCodeBase = -2549,
+ nrPathNotFound = -2550,
+ nrPathBufferTooSmall = -2551,
+ nrInvalidEntryIterationOp = -2552,
+ nrPropertyAlreadyExists = -2553,
+ nrIterationDone = -2554,
+ nrExitedIteratorScope = -2555,
+ nrTransactionAborted = -2556,
+ nrCallNotSupported = -2557
+};
+
+
+enum {
+ invalidIconRefErr = -2580,
+ noSuchIconErr = -2581,
+ noIconDataAvailableErr = -2582
+};
+enum {
+ errOSACantCoerce = errAECoercionFail,
+ errOSACantAccess = errAENoSuchObject,
+ errOSACantAssign = -10006,
+ errOSAGeneralError = -2700,
+ errOSADivideByZero = -2701,
+ errOSANumericOverflow = -2702,
+ errOSACantLaunch = -2703,
+ errOSAAppNotHighLevelEventAware = -2704,
+ errOSACorruptTerminology = -2705,
+ errOSAStackOverflow = -2706,
+ errOSAInternalTableOverflow = -2707,
+ errOSADataBlockTooLarge = -2708,
+ errOSACantGetTerminology = -2709,
+ errOSACantCreate = -2710
+};
+enum {
+ errOSATypeError = errAEWrongDataType,
+ OSAMessageNotUnderstood = errAEEventNotHandled,
+ OSAUndefinedHandler = errAEHandlerNotFound,
+ OSAIllegalAccess = errAEAccessorNotFound,
+ OSAIllegalIndex = errAEIllegalIndex,
+ OSAIllegalRange = errAEImpossibleRange,
+ OSAIllegalAssign = -10003,
+ OSASyntaxError = -2740,
+ OSASyntaxTypeError = -2741,
+ OSATokenTooLong = -2742,
+ OSAMissingParameter = errAEDescNotFound,
+ OSAParameterMismatch = errAEWrongNumberArgs,
+ OSADuplicateParameter = -2750,
+ OSADuplicateProperty = -2751,
+ OSADuplicateHandler = -2752,
+ OSAUndefinedVariable = -2753,
+ OSAInconsistentDeclarations = -2754,
+ OSAControlFlowError = -2755
+};
+enum {
+ errASCantConsiderAndIgnore = -2720,
+ errASCantCompareMoreThan32k = -2721,
+ errASTerminologyNestingTooDeep = -2760,
+ errASIllegalFormalParameter = -2761,
+ errASParameterNotForEvent = -2762,
+ errASNoResultReturned = -2763,
+ errASInconsistentNames = -2780
+};
+
+
+
+enum {
+ cfragFirstErrCode = -2800,
+ cfragContextIDErr = -2800,
+ cfragConnectionIDErr = -2801,
+ cfragNoSymbolErr = -2802,
+ cfragNoSectionErr = -2803,
+ cfragNoLibraryErr = -2804,
+ cfragDupRegistrationErr = -2805,
+ cfragFragmentFormatErr = -2806,
+ cfragUnresolvedErr = -2807,
+ cfragNoPositionErr = -2808,
+ cfragNoPrivateMemErr = -2809,
+ cfragNoClientMemErr = -2810,
+ cfragNoIDsErr = -2811,
+ cfragInitOrderErr = -2812,
+ cfragImportTooOldErr = -2813,
+ cfragImportTooNewErr = -2814,
+ cfragInitLoopErr = -2815,
+ cfragInitAtBootErr = -2816,
+ cfragLibConnErr = -2817,
+ cfragCFMStartupErr = -2818,
+ cfragCFMInternalErr = -2819,
+ cfragFragmentCorruptErr = -2820,
+ cfragInitFunctionErr = -2821,
+ cfragNoApplicationErr = -2822,
+ cfragArchitectureErr = -2823,
+ cfragFragmentUsageErr = -2824,
+ cfragFileSizeErr = -2825,
+ cfragNotClosureErr = -2826,
+ cfragNoRegistrationErr = -2827,
+ cfragContainerIDErr = -2828,
+ cfragClosureIDErr = -2829,
+ cfragAbortClosureErr = -2830,
+ cfragOutputLengthErr = -2831,
+ cfragLastErrCode = -2899
+};
+
+enum {
+
+ cfragFirstReservedCode = -2897,
+ cfragReservedCode_3 = -2897,
+ cfragReservedCode_2 = -2898,
+ cfragReservedCode_1 = -2899
+};
+enum {
+ invalidComponentID = -3000,
+ validInstancesExist = -3001,
+ componentNotCaptured = -3002,
+ componentDontRegister = -3003,
+ unresolvedComponentDLLErr = -3004,
+ retryComponentRegistrationErr = -3005
+};
+
+
+enum {
+ invalidTranslationPathErr = -3025,
+ couldNotParseSourceFileErr = -3026,
+ noTranslationPathErr = -3030,
+ badTranslationSpecErr = -3031,
+ noPrefAppErr = -3032
+};
+
+enum {
+ buf2SmallErr = -3101,
+ noMPPErr = -3102,
+ ckSumErr = -3103,
+ extractErr = -3104,
+ readQErr = -3105,
+ atpLenErr = -3106,
+ atpBadRsp = -3107,
+ recNotFnd = -3108,
+ sktClosedErr = -3109
+};
+
+
+
+enum {
+ kOTNoError = 0,
+ kOTOutOfMemoryErr = -3211,
+ kOTNotFoundErr = -3201,
+ kOTDuplicateFoundErr = -3216,
+ kOTBadAddressErr = -3150,
+ kOTBadOptionErr = -3151,
+ kOTAccessErr = -3152,
+ kOTBadReferenceErr = -3153,
+ kOTNoAddressErr = -3154,
+ kOTOutStateErr = -3155,
+ kOTBadSequenceErr = -3156,
+ kOTSysErrorErr = -3157,
+ kOTLookErr = -3158,
+ kOTBadDataErr = -3159,
+ kOTBufferOverflowErr = -3160,
+ kOTFlowErr = -3161,
+ kOTNoDataErr = -3162,
+ kOTNoDisconnectErr = -3163,
+ kOTNoUDErrErr = -3164,
+ kOTBadFlagErr = -3165,
+ kOTNoReleaseErr = -3166,
+ kOTNotSupportedErr = -3167,
+ kOTStateChangeErr = -3168,
+ kOTNoStructureTypeErr = -3169,
+ kOTBadNameErr = -3170,
+ kOTBadQLenErr = -3171,
+ kOTAddressBusyErr = -3172,
+ kOTIndOutErr = -3173,
+ kOTProviderMismatchErr = -3174,
+ kOTResQLenErr = -3175,
+ kOTResAddressErr = -3176,
+ kOTQFullErr = -3177,
+ kOTProtocolErr = -3178,
+ kOTBadSyncErr = -3179,
+ kOTCanceledErr = -3180,
+ kEPERMErr = -3200,
+ kENOENTErr = -3201,
+ kENORSRCErr = -3202,
+ kEINTRErr = -3203,
+ kEIOErr = -3204,
+ kENXIOErr = -3205,
+ kEBADFErr = -3208,
+ kEAGAINErr = -3210,
+ kENOMEMErr = -3211,
+ kEACCESErr = -3212,
+ kEFAULTErr = -3213,
+ kEBUSYErr = -3215,
+ kEEXISTErr = -3216,
+ kENODEVErr = -3218,
+ kEINVALErr = -3221,
+ kENOTTYErr = -3224,
+ kEPIPEErr = -3231,
+ kERANGEErr = -3233,
+ kEWOULDBLOCKErr = -3234,
+ kEDEADLKErr = -3234,
+ kEALREADYErr = -3236,
+ kENOTSOCKErr = -3237,
+ kEDESTADDRREQErr = -3238,
+ kEMSGSIZEErr = -3239,
+ kEPROTOTYPEErr = -3240,
+ kENOPROTOOPTErr = -3241,
+ kEPROTONOSUPPORTErr = -3242,
+ kESOCKTNOSUPPORTErr = -3243,
+ kEOPNOTSUPPErr = -3244,
+ kEADDRINUSEErr = -3247,
+ kEADDRNOTAVAILErr = -3248,
+ kENETDOWNErr = -3249,
+ kENETUNREACHErr = -3250,
+ kENETRESETErr = -3251,
+ kECONNABORTEDErr = -3252,
+ kECONNRESETErr = -3253,
+ kENOBUFSErr = -3254,
+ kEISCONNErr = -3255,
+ kENOTCONNErr = -3256,
+ kESHUTDOWNErr = -3257,
+ kETOOMANYREFSErr = -3258,
+ kETIMEDOUTErr = -3259,
+ kECONNREFUSEDErr = -3260,
+ kEHOSTDOWNErr = -3263,
+ kEHOSTUNREACHErr = -3264,
+ kEPROTOErr = -3269,
+ kETIMEErr = -3270,
+ kENOSRErr = -3271,
+ kEBADMSGErr = -3272,
+ kECANCELErr = -3273,
+ kENOSTRErr = -3274,
+ kENODATAErr = -3275,
+ kEINPROGRESSErr = -3276,
+ kESRCHErr = -3277,
+ kENOMSGErr = -3278,
+ kOTClientNotInittedErr = -3279,
+ kOTPortHasDiedErr = -3280,
+ kOTPortWasEjectedErr = -3281,
+ kOTBadConfigurationErr = -3282,
+ kOTConfigurationChangedErr = -3283,
+ kOTUserRequestedErr = -3284,
+ kOTPortLostConnection = -3285
+};
+
+
+
+enum {
+ kQDNoPalette = -3950,
+ kQDNoColorHWCursorSupport = -3951,
+ kQDCursorAlreadyRegistered = -3952,
+ kQDCursorNotRegistered = -3953,
+ kQDCorruptPICTDataErr = -3954
+};
+
+
+
+
+enum {
+ firstPickerError = -4000,
+ invalidPickerType = firstPickerError,
+ requiredFlagsDontMatch = -4001,
+ pickerResourceError = -4002,
+ cantLoadPicker = -4003,
+ cantCreatePickerWindow = -4004,
+ cantLoadPackage = -4005,
+ pickerCantLive = -4006,
+ colorSyncNotInstalled = -4007,
+ badProfileError = -4008,
+ noHelpForItem = -4009
+};
+
+
+
+
+enum {
+ kNSL68kContextNotSupported = -4170,
+ kNSLSchedulerError = -4171,
+ kNSLBadURLSyntax = -4172,
+ kNSLNoCarbonLib = -4173,
+ kNSLUILibraryNotAvailable = -4174,
+ kNSLNotImplementedYet = -4175,
+ kNSLErrNullPtrError = -4176,
+ kNSLSomePluginsFailedToLoad = -4177,
+ kNSLNullNeighborhoodPtr = -4178,
+ kNSLNoPluginsForSearch = -4179,
+ kNSLSearchAlreadyInProgress = -4180,
+ kNSLNoPluginsFound = -4181,
+ kNSLPluginLoadFailed = -4182,
+ kNSLBadProtocolTypeErr = -4183,
+ kNSLNullListPtr = -4184,
+ kNSLBadClientInfoPtr = -4185,
+ kNSLCannotContinueLookup = -4186,
+ kNSLBufferTooSmallForData = -4187,
+ kNSLNoContextAvailable = -4188,
+ kNSLRequestBufferAlreadyInList = -4189,
+ kNSLInvalidPluginSpec = -4190,
+ kNSLNoSupportForService = -4191,
+ kNSLBadNetConnection = -4192,
+ kNSLBadDataTypeErr = -4193,
+ kNSLBadServiceTypeErr = -4194,
+ kNSLBadReferenceErr = -4195,
+ kNSLNoElementsInList = -4196,
+ kNSLInsufficientOTVer = -4197,
+ kNSLInsufficientSysVer = -4198,
+ kNSLNotInitialized = -4199,
+ kNSLInitializationFailed = -4200
+};
+
+
+
+
+enum {
+ kDTPHoldJobErr = -4200,
+ kDTPStopQueueErr = -4201,
+ kDTPTryAgainErr = -4202,
+ kDTPAbortJobErr = 128
+};
+
+
+
+enum {
+
+ cmElementTagNotFound = -4200,
+ cmIndexRangeErr = -4201,
+ cmCantDeleteElement = -4202,
+ cmFatalProfileErr = -4203,
+ cmInvalidProfile = -4204,
+ cmInvalidProfileLocation = -4205,
+ cmCantCopyModifiedV1Profile = -4215,
+
+ cmInvalidSearch = -4206,
+ cmSearchError = -4207,
+ cmErrIncompatibleProfile = -4208,
+ cmInvalidColorSpace = -4209,
+ cmInvalidSrcMap = -4210,
+ cmInvalidDstMap = -4211,
+ cmNoGDevicesError = -4212,
+ cmInvalidProfileComment = -4213,
+ cmRangeOverFlow = -4214,
+ cmNamedColorNotFound = -4216,
+ cmCantGamutCheckError = -4217
+};
+
+
+enum {
+ badFolderDescErr = -4270,
+ duplicateFolderDescErr = -4271,
+ noMoreFolderDescErr = -4272,
+ invalidFolderTypeErr = -4273,
+ duplicateRoutingErr = -4274,
+ routingNotFoundErr = -4275,
+ badRoutingSizeErr = -4276
+};
+
+
+
+enum {
+ coreFoundationUnknownErr = -4960
+};
+
+
+enum {
+ internalScrapErr = -4988,
+ duplicateScrapFlavorErr = -4989,
+ badScrapRefErr = -4990,
+ processStateIncorrectErr = -4991,
+ scrapPromiseNotKeptErr = -4992,
+ noScrapPromiseKeeperErr = -4993,
+ nilScrapFlavorDataErr = -4994,
+ scrapFlavorFlagsMismatchErr = -4995,
+ scrapFlavorSizeMismatchErr = -4996,
+ illegalScrapFlavorFlagsErr = -4997,
+ illegalScrapFlavorTypeErr = -4998,
+ illegalScrapFlavorSizeErr = -4999,
+ scrapFlavorNotFoundErr = -102,
+ needClearScrapErr = -100
+};
+
+
+enum {
+
+ afpAccessDenied = -5000,
+ afpAuthContinue = -5001,
+ afpBadUAM = -5002,
+ afpBadVersNum = -5003,
+ afpBitmapErr = -5004,
+ afpCantMove = -5005,
+ afpDenyConflict = -5006,
+ afpDirNotEmpty = -5007,
+ afpDiskFull = -5008,
+ afpEofError = -5009,
+ afpFileBusy = -5010,
+ afpFlatVol = -5011,
+ afpItemNotFound = -5012,
+ afpLockErr = -5013,
+ afpMiscErr = -5014,
+ afpNoMoreLocks = -5015,
+ afpNoServer = -5016,
+ afpObjectExists = -5017,
+ afpObjectNotFound = -5018,
+ afpParmErr = -5019,
+ afpRangeNotLocked = -5020,
+ afpRangeOverlap = -5021,
+ afpSessClosed = -5022,
+ afpUserNotAuth = -5023,
+ afpCallNotSupported = -5024,
+ afpObjectTypeErr = -5025,
+ afpTooManyFilesOpen = -5026,
+ afpServerGoingDown = -5027,
+ afpCantRename = -5028,
+ afpDirNotFound = -5029,
+ afpIconTypeError = -5030,
+ afpVolLocked = -5031,
+ afpObjectLocked = -5032,
+ afpContainsSharedErr = -5033,
+ afpIDNotFound = -5034,
+ afpIDExists = -5035,
+ afpDiffVolErr = -5036,
+ afpCatalogChanged = -5037,
+ afpSameObjectErr = -5038,
+ afpBadIDErr = -5039,
+ afpPwdSameErr = -5040,
+ afpPwdTooShortErr = -5041,
+ afpPwdExpiredErr = -5042,
+ afpInsideSharedErr = -5043,
+
+ afpInsideTrashErr = -5044,
+
+ afpPwdNeedsChangeErr = -5045,
+ afpPwdPolicyErr = -5046,
+ afpAlreadyLoggedInErr = -5047,
+ afpCallNotAllowed = -5048
+};
+
+enum {
+
+ afpBadDirIDType = -5060,
+ afpCantMountMoreSrvre = -5061,
+ afpAlreadyMounted = -5062,
+ afpSameNodeErr = -5063
+};
+
+
+
+
+
+
+enum {
+ numberFormattingNotANumberErr = -5200,
+ numberFormattingOverflowInDestinationErr = -5201,
+ numberFormattingBadNumberFormattingObjectErr = -5202,
+ numberFormattingSpuriousCharErr = -5203,
+ numberFormattingLiteralMissingErr = -5204,
+ numberFormattingDelimiterMissingErr = -5205,
+ numberFormattingEmptyFormatErr = -5206,
+ numberFormattingBadFormatErr = -5207,
+ numberFormattingBadOptionsErr = -5208,
+ numberFormattingBadTokenErr = -5209,
+ numberFormattingUnOrderedCurrencyRangeErr = -5210,
+ numberFormattingBadCurrencyPositionErr = -5211,
+ numberFormattingNotADigitErr = -5212,
+ numberFormattingUnOrdredCurrencyRangeErr = -5210,
+ numberFortmattingNotADigitErr = -5212
+};
+
+
+enum {
+ textParserBadParamErr = -5220,
+ textParserObjectNotFoundErr = -5221,
+ textParserBadTokenValueErr = -5222,
+ textParserBadParserObjectErr = -5223,
+ textParserParamErr = -5224,
+ textParserNoMoreTextErr = -5225,
+ textParserBadTextLanguageErr = -5226,
+ textParserBadTextEncodingErr = -5227,
+ textParserNoSuchTokenFoundErr = -5228,
+ textParserNoMoreTokensErr = -5229
+};
+
+enum {
+ errUnknownAttributeTag = -5240,
+ errMarginWilllNotFit = -5241,
+ errNotInImagingMode = -5242,
+ errAlreadyInImagingMode = -5243,
+ errEngineNotFound = -5244,
+ errIteratorReachedEnd = -5245,
+ errInvalidRange = -5246,
+ errOffsetNotOnElementBounday = -5247,
+ errNoHiliteText = -5248,
+ errEmptyScrap = -5249,
+ errReadOnlyText = -5250,
+ errUnknownElement = -5251,
+ errNonContiuousAttribute = -5252,
+ errCannotUndo = -5253
+};
+
+
+
+enum {
+ hrHTMLRenderingLibNotInstalledErr = -5360,
+ hrMiscellaneousExceptionErr = -5361,
+ hrUnableToResizeHandleErr = -5362,
+ hrURLNotHandledErr = -5363
+};
+
+
+
+enum {
+ errIANoErr = 0,
+ errIAUnknownErr = -5380,
+ errIAAllocationErr = -5381,
+ errIAParamErr = -5382,
+ errIANoMoreItems = -5383,
+ errIABufferTooSmall = -5384,
+ errIACanceled = -5385,
+ errIAInvalidDocument = -5386,
+ errIATextExtractionErr = -5387,
+ errIAEndOfTextRun = -5388
+};
+
+
+
+enum {
+ qtsBadSelectorErr = -5400,
+ qtsBadStateErr = -5401,
+ qtsBadDataErr = -5402,
+ qtsUnsupportedDataTypeErr = -5403,
+ qtsUnsupportedRateErr = -5404,
+ qtsUnsupportedFeatureErr = -5405,
+ qtsTooMuchDataErr = -5406,
+ qtsUnknownValueErr = -5407,
+ qtsTimeoutErr = -5408,
+ qtsConnectionFailedErr = -5420,
+ qtsAddressBusyErr = -5421
+};
+
+
+enum {
+
+ gestaltUnknownErr = -5550,
+ gestaltUndefSelectorErr = -5551,
+ gestaltDupSelectorErr = -5552,
+ gestaltLocationErr = -5553
+};
+
+
+
+enum {
+ menuPropertyInvalidErr = -5603,
+ menuPropertyInvalid = menuPropertyInvalidErr,
+ menuPropertyNotFoundErr = -5604,
+ menuNotFoundErr = -5620,
+ menuUsesSystemDefErr = -5621,
+ menuItemNotFoundErr = -5622,
+ menuInvalidErr = -5623
+};
+
+
+
+enum {
+ errInvalidWindowPtr = -5600,
+ errInvalidWindowRef = -5600,
+ errUnsupportedWindowAttributesForClass = -5601,
+ errWindowDoesNotHaveProxy = -5602,
+ errInvalidWindowProperty = -5603,
+ errWindowPropertyNotFound = -5604,
+ errUnrecognizedWindowClass = -5605,
+ errCorruptWindowDescription = -5606,
+ errUserWantsToDragWindow = -5607,
+ errWindowsAlreadyInitialized = -5608,
+ errFloatingWindowsNotInitialized = -5609,
+ errWindowNotFound = -5610,
+ errWindowDoesNotFitOnscreen = -5611,
+ windowAttributeImmutableErr = -5612,
+ windowAttributesConflictErr = -5613,
+ windowManagerInternalErr = -5614,
+ windowWrongStateErr = -5615,
+ windowGroupInvalidErr = -5616,
+ windowAppModalStateAlreadyExistsErr = -5617,
+ windowNoAppModalStateErr = -5618,
+ errWindowDoesntSupportFocus = -30583,
+ errWindowRegionCodeInvalid = -30593
+};
+
+
+
+enum {
+ dialogNoTimeoutErr = -5640
+};
+
+
+
+enum {
+ kNavWrongDialogStateErr = -5694,
+ kNavWrongDialogClassErr = -5695,
+ kNavInvalidSystemConfigErr = -5696,
+ kNavCustomControlMessageFailedErr = -5697,
+ kNavInvalidCustomControlMessageErr = -5698,
+ kNavMissingKindStringErr = -5699
+};
+
+
+
+enum {
+ collectionItemLockedErr = -5750,
+ collectionItemNotFoundErr = -5751,
+ collectionIndexRangeErr = -5752,
+ collectionVersionErr = -5753
+};
+
+
+
+enum {
+ kQTSSUnknownErr = -6150
+};
+
+
+enum {
+
+ kDMGenErr = -6220,
+
+ kDMMirroringOnAlready = -6221,
+ kDMWrongNumberOfDisplays = -6222,
+ kDMMirroringBlocked = -6223,
+ kDMCantBlock = -6224,
+ kDMMirroringNotOn = -6225,
+
+ kSysSWTooOld = -6226,
+ kDMSWNotInitializedErr = -6227,
+ kDMDriverNotDisplayMgrAwareErr = -6228,
+ kDMDisplayNotFoundErr = -6229,
+ kDMNotFoundErr = -6229,
+ kDMDisplayAlreadyInstalledErr = -6230,
+ kDMMainDisplayCannotMoveErr = -6231,
+ kDMNoDeviceTableclothErr = -6231,
+ kDMFoundErr = -6232
+};
+
+
+
+
+
+enum {
+ laTooSmallBufferErr = -6984,
+ laEnvironmentBusyErr = -6985,
+ laEnvironmentNotFoundErr = -6986,
+ laEnvironmentExistErr = -6987,
+ laInvalidPathErr = -6988,
+ laNoMoreMorphemeErr = -6989,
+ laFailAnalysisErr = -6990,
+ laTextOverFlowErr = -6991,
+ laDictionaryNotOpenedErr = -6992,
+ laDictionaryUnknownErr = -6993,
+ laDictionaryTooManyErr = -6994,
+ laPropertyValueErr = -6995,
+ laPropertyUnknownErr = -6996,
+ laPropertyIsReadOnlyErr = -6997,
+ laPropertyNotFoundErr = -6998,
+ laPropertyErr = -6999,
+ laEngineNotFoundErr = -7000
+};
+
+
+enum {
+ kUSBNoErr = 0,
+ kUSBNoTran = 0,
+ kUSBNoDelay = 0,
+ kUSBPending = 1
+};
+enum {
+ kUSBNotSent2Err = -6901,
+ kUSBNotSent1Err = -6902,
+ kUSBBufUnderRunErr = -6903,
+ kUSBBufOvrRunErr = -6904,
+ kUSBRes2Err = -6905,
+ kUSBRes1Err = -6906,
+ kUSBUnderRunErr = -6907,
+ kUSBOverRunErr = -6908,
+ kUSBWrongPIDErr = -6909,
+ kUSBPIDCheckErr = -6910,
+ kUSBNotRespondingErr = -6911,
+ kUSBEndpointStallErr = -6912,
+ kUSBDataToggleErr = -6913,
+ kUSBBitstufErr = -6914,
+ kUSBCRCErr = -6915,
+ kUSBLinkErr = -6916
+};
+
+
+
+
+
+
+enum {
+ kUSBQueueFull = -6948,
+ kUSBNotHandled = -6987,
+ kUSBUnknownNotification = -6949,
+ kUSBBadDispatchTable = -6950
+};
+
+
+
+
+
+
+
+enum {
+ kUSBInternalReserved10 = -6951,
+ kUSBInternalReserved9 = -6952,
+ kUSBInternalReserved8 = -6953,
+ kUSBInternalReserved7 = -6954,
+ kUSBInternalReserved6 = -6955,
+ kUSBInternalReserved5 = -6956,
+ kUSBInternalReserved4 = -6957,
+ kUSBInternalReserved3 = -6958,
+ kUSBInternalReserved2 = -6959,
+ kUSBInternalReserved1 = -6960
+};
+
+
+enum {
+ kUSBPortDisabled = -6969,
+ kUSBQueueAborted = -6970,
+ kUSBTimedOut = -6971,
+ kUSBDeviceDisconnected = -6972,
+ kUSBDeviceNotSuspended = -6973,
+ kUSBDeviceSuspended = -6974,
+ kUSBInvalidBuffer = -6975,
+ kUSBDevicePowerProblem = -6976,
+ kUSBDeviceBusy = -6977,
+ kUSBUnknownInterfaceErr = -6978,
+ kUSBPipeStalledError = -6979,
+ kUSBPipeIdleError = -6980,
+ kUSBNoBandwidthError = -6981,
+ kUSBAbortedError = -6982,
+ kUSBFlagsError = -6983,
+ kUSBCompletionError = -6984,
+ kUSBPBLengthError = -6985,
+ kUSBPBVersionError = -6986,
+ kUSBNotFound = -6987,
+ kUSBOutOfMemoryErr = -6988,
+ kUSBDeviceErr = -6989,
+ kUSBNoDeviceErr = -6990,
+ kUSBAlreadyOpenErr = -6991,
+ kUSBTooManyTransactionsErr = -6992,
+ kUSBUnknownRequestErr = -6993,
+ kUSBRqErr = -6994,
+ kUSBIncorrectTypeErr = -6995,
+ kUSBTooManyPipesErr = -6996,
+ kUSBUnknownPipeErr = -6997,
+ kUSBUnknownDeviceErr = -6998,
+ kUSBInternalErr = -6999
+};
+
+
+
+
+
+enum {
+ dcmParamErr = -7100,
+ dcmNotDictionaryErr = -7101,
+ dcmBadDictionaryErr = -7102,
+ dcmPermissionErr = -7103,
+ dcmDictionaryNotOpenErr = -7104,
+ dcmDictionaryBusyErr = -7105,
+ dcmBlockFullErr = -7107,
+ dcmNoRecordErr = -7108,
+ dcmDupRecordErr = -7109,
+ dcmNecessaryFieldErr = -7110,
+ dcmBadFieldInfoErr = -7111,
+ dcmBadFieldTypeErr = -7112,
+ dcmNoFieldErr = -7113,
+ dcmBadKeyErr = -7115,
+ dcmTooManyKeyErr = -7116,
+ dcmBadDataSizeErr = -7117,
+ dcmBadFindMethodErr = -7118,
+ dcmBadPropertyErr = -7119,
+ dcmProtectedErr = -7121,
+ dcmNoAccessMethodErr = -7122,
+ dcmBadFeatureErr = -7124,
+ dcmIterationCompleteErr = -7126,
+ dcmBufferOverflowErr = -7127
+};
+
+
+
+enum {
+ kRAInvalidParameter = -7100,
+ kRAInvalidPort = -7101,
+ kRAStartupFailed = -7102,
+ kRAPortSetupFailed = -7103,
+ kRAOutOfMemory = -7104,
+ kRANotSupported = -7105,
+ kRAMissingResources = -7106,
+ kRAIncompatiblePrefs = -7107,
+ kRANotConnected = -7108,
+ kRAConnectionCanceled = -7109,
+ kRAUnknownUser = -7110,
+ kRAInvalidPassword = -7111,
+ kRAInternalError = -7112,
+ kRAInstallationDamaged = -7113,
+ kRAPortBusy = -7114,
+ kRAUnknownPortState = -7115,
+ kRAInvalidPortState = -7116,
+ kRAInvalidSerialProtocol = -7117,
+ kRAUserLoginDisabled = -7118,
+ kRAUserPwdChangeRequired = -7119,
+ kRAUserPwdEntryRequired = -7120,
+ kRAUserInteractionRequired = -7121,
+ kRAInitOpenTransportFailed = -7122,
+ kRARemoteAccessNotReady = -7123,
+ kRATCPIPInactive = -7124,
+ kRATCPIPNotConfigured = -7125,
+ kRANotPrimaryInterface = -7126,
+ kRAConfigurationDBInitErr = -7127,
+ kRAPPPProtocolRejected = -7128,
+ kRAPPPAuthenticationFailed = -7129,
+ kRAPPPNegotiationFailed = -7130,
+ kRAPPPUserDisconnected = -7131,
+ kRAPPPPeerDisconnected = -7132,
+ kRAPeerNotResponding = -7133,
+ kRAATalkInactive = -7134,
+ kRAExtAuthenticationFailed = -7135,
+ kRANCPRejectedbyPeer = -7136,
+ kRADuplicateIPAddr = -7137,
+ kRACallBackFailed = -7138,
+ kRANotEnabled = -7139
+};
+enum {
+ kATSUInvalidTextLayoutErr = -8790,
+
+
+ kATSUInvalidStyleErr = -8791,
+
+
+ kATSUInvalidTextRangeErr = -8792,
+
+
+ kATSUFontsMatched = -8793,
+
+
+ kATSUFontsNotMatched = -8794,
+
+
+ kATSUNoCorrespondingFontErr = -8795,
+
+
+
+
+
+
+ kATSUInvalidFontErr = -8796,
+ kATSUInvalidAttributeValueErr = -8797,
+
+ kATSUInvalidAttributeSizeErr = -8798,
+
+ kATSUInvalidAttributeTagErr = -8799,
+
+ kATSUInvalidCacheErr = -8800,
+
+
+
+
+ kATSUNotSetErr = -8801,
+
+
+
+ kATSUNoStyleRunsAssignedErr = -8802,
+
+ kATSUQuickDrawTextErr = -8803,
+
+ kATSULowLevelErr = -8804,
+
+ kATSUNoFontCmapAvailableErr = -8805,
+
+ kATSUNoFontScalerAvailableErr = -8806,
+
+ kATSUCoordinateOverflowErr = -8807,
+
+ kATSULineBreakInWord = -8808,
+
+
+ kATSUBusyObjectErr = -8809
+};
+enum {
+
+ kTextUnsupportedEncodingErr = -8738,
+ kTextMalformedInputErr = -8739,
+ kTextUndefinedElementErr = -8740,
+ kTECMissingTableErr = -8745,
+ kTECTableChecksumErr = -8746,
+ kTECTableFormatErr = -8747,
+ kTECCorruptConverterErr = -8748,
+ kTECNoConversionPathErr = -8749,
+ kTECBufferBelowMinimumSizeErr = -8750,
+ kTECArrayFullErr = -8751,
+ kTECBadTextRunErr = -8752,
+ kTECPartialCharErr = -8753,
+ kTECUnmappableElementErr = -8754,
+ kTECIncompleteElementErr = -8755,
+ kTECDirectionErr = -8756,
+ kTECGlobalsUnavailableErr = -8770,
+ kTECItemUnavailableErr = -8771,
+
+ kTECUsedFallbacksStatus = -8783,
+ kTECNeedFlushStatus = -8784,
+ kTECOutputBufferFullStatus = -8785,
+
+ unicodeChecksumErr = -8769,
+ unicodeNoTableErr = -8768,
+ unicodeVariantErr = -8767,
+ unicodeFallbacksErr = -8766,
+ unicodePartConvertErr = -8765,
+ unicodeBufErr = -8764,
+ unicodeCharErr = -8763,
+ unicodeElementErr = -8762,
+ unicodeNotFoundErr = -8761,
+ unicodeTableFormatErr = -8760,
+ unicodeDirectionErr = -8759,
+ unicodeContextualErr = -8758,
+ unicodeTextEncodingDataErr = -8757
+};
+
+
+
+enum {
+ kUTCUnderflowErr = -8850,
+ kUTCOverflowErr = -8851,
+ kIllegalClockValueErr = -8852
+};
+
+
+
+
+
+enum {
+ kATSUInvalidFontFallbacksErr = -8900,
+
+ kATSUUnsupportedStreamFormatErr = -8901,
+
+ kATSUBadStreamErr = -8902,
+
+
+ kATSUOutputBufferTooSmallErr = -8903,
+
+ kATSUInvalidCallInsideCallbackErr = -8904,
+
+ kATSULastErr = -8959
+};
+
+
+
+enum {
+ codecErr = -8960,
+ noCodecErr = -8961,
+ codecUnimpErr = -8962,
+ codecSizeErr = -8963,
+ codecScreenBufErr = -8964,
+ codecImageBufErr = -8965,
+ codecSpoolErr = -8966,
+ codecAbortErr = -8967,
+ codecWouldOffscreenErr = -8968,
+ codecBadDataErr = -8969,
+ codecDataVersErr = -8970,
+ codecExtensionNotFoundErr = -8971,
+ scTypeNotFoundErr = codecExtensionNotFoundErr,
+ codecConditionErr = -8972,
+ codecOpenErr = -8973,
+ codecCantWhenErr = -8974,
+ codecCantQueueErr = -8975,
+ codecNothingToBlitErr = -8976,
+ codecNoMemoryPleaseWaitErr = -8977,
+ codecDisabledErr = -8978,
+ codecNeedToFlushChainErr = -8979,
+ lockPortBitsBadSurfaceErr = -8980,
+ lockPortBitsWindowMovedErr = -8981,
+ lockPortBitsWindowResizedErr = -8982,
+ lockPortBitsWindowClippedErr = -8983,
+ lockPortBitsBadPortErr = -8984,
+ lockPortBitsSurfaceLostErr = -8985,
+ codecParameterDialogConfirm = -8986,
+ codecNeedAccessKeyErr = -8987,
+ codecOffscreenFailedErr = -8988,
+ codecDroppedFrameErr = -8989,
+ directXObjectAlreadyExists = -8990,
+ lockPortBitsWrongGDeviceErr = -8991,
+ codecOffscreenFailedPleaseRetryErr = -8992,
+ badCodecCharacterizationErr = -8993,
+ noThumbnailFoundErr = -8994
+};
+
+
+
+enum {
+ kBadAdapterErr = -9050,
+ kBadAttributeErr = -9051,
+ kBadBaseErr = -9052,
+ kBadEDCErr = -9053,
+ kBadIRQErr = -9054,
+ kBadOffsetErr = -9055,
+ kBadPageErr = -9056,
+ kBadSizeErr = -9057,
+ kBadSocketErr = -9058,
+ kBadTypeErr = -9059,
+ kBadVccErr = -9060,
+ kBadVppErr = -9061,
+ kBadWindowErr = -9062,
+ kBadArgLengthErr = -9063,
+ kBadArgsErr = -9064,
+ kBadHandleErr = -9065,
+ kBadCISErr = -9066,
+ kBadSpeedErr = -9067,
+ kReadFailureErr = -9068,
+ kWriteFailureErr = -9069,
+ kGeneralFailureErr = -9070,
+ kNoCardErr = -9071,
+ kUnsupportedFunctionErr = -9072,
+ kUnsupportedModeErr = -9073,
+ kBusyErr = -9074,
+ kWriteProtectedErr = -9075,
+ kConfigurationLockedErr = -9076,
+ kInUseErr = -9077,
+ kNoMoreItemsErr = -9078,
+ kOutOfResourceErr = -9079,
+ kNoCardSevicesSocketsErr = -9080,
+ kInvalidRegEntryErr = -9081,
+ kBadLinkErr = -9082,
+ kBadDeviceErr = -9083,
+ k16BitCardErr = -9084,
+ kCardBusCardErr = -9085,
+ kPassCallToChainErr = -9086,
+ kCantConfigureCardErr = -9087,
+ kPostCardEventErr = -9088,
+ kInvalidDeviceNumber = -9089,
+ kUnsupportedVsErr = -9090,
+ kInvalidCSClientErr = -9091,
+ kBadTupleDataErr = -9092,
+ kBadCustomIFIDErr = -9093,
+ kNoIOWindowRequestedErr = -9094,
+ kNoMoreTimerClientsErr = -9095,
+ kNoMoreInterruptSlotsErr = -9096,
+ kNoClientTableErr = -9097,
+ kUnsupportedCardErr = -9098,
+ kNoCardEnablersFoundErr = -9099,
+ kNoEnablerForCardErr = -9100,
+ kNoCompatibleNameErr = -9101,
+ kClientRequestDenied = -9102,
+
+ kNotReadyErr = -9103,
+ kTooManyIOWindowsErr = -9104,
+ kAlreadySavedStateErr = -9105,
+ kAttemptDupCardEntryErr = -9106,
+ kCardPowerOffErr = -9107,
+ kNotZVCapableErr = -9108,
+ kNoCardBusCISErr = -9109
+};
+
+
+enum {
+ noDeviceForChannel = -9400,
+ grabTimeComplete = -9401,
+ cantDoThatInCurrentMode = -9402,
+ notEnoughMemoryToGrab = -9403,
+ notEnoughDiskSpaceToGrab = -9404,
+ couldntGetRequiredComponent = -9405,
+ badSGChannel = -9406,
+ seqGrabInfoNotAvailable = -9407,
+ deviceCantMeetRequest = -9408,
+ badControllerHeight = -9994,
+ editingNotAllowed = -9995,
+ controllerBoundsNotExact = -9996,
+ cannotSetWidthOfAttachedController = -9997,
+ controllerHasFixedHeight = -9998,
+ cannotMoveAttachedController = -9999
+};
+
+
+enum {
+ errAEBadKeyForm = -10002,
+ errAECantHandleClass = -10010,
+ errAECantSupplyType = -10009,
+ errAECantUndo = -10015,
+ errAEEventFailed = -10000,
+ errAEIndexTooLarge = -10007,
+ errAEInTransaction = -10011,
+ errAELocalOnly = -10016,
+ errAENoSuchTransaction = -10012,
+ errAENotAnElement = -10008,
+ errAENotASingleObject = -10014,
+ errAENotModifiable = -10003,
+ errAENoUserSelection = -10013,
+ errAEPrivilegeError = -10004,
+ errAEReadDenied = -10005,
+ errAETypeError = -10001,
+ errAEWriteDenied = -10006,
+ errAENotAnEnumMember = -10023,
+ errAECantPutThatThere = -10024,
+ errAEPropertiesClash = -10025
+};
+
+
+enum {
+ telGenericError = -1,
+ telNoErr = 0,
+ telNoTools = 8,
+ telBadTermErr = -10001,
+ telBadDNErr = -10002,
+ telBadCAErr = -10003,
+ telBadHandErr = -10004,
+ telBadProcErr = -10005,
+ telCAUnavail = -10006,
+ telNoMemErr = -10007,
+ telNoOpenErr = -10008,
+ telBadHTypeErr = -10010,
+ telHTypeNotSupp = -10011,
+ telBadLevelErr = -10012,
+ telBadVTypeErr = -10013,
+ telVTypeNotSupp = -10014,
+ telBadAPattErr = -10015,
+ telAPattNotSupp = -10016,
+ telBadIndex = -10017,
+ telIndexNotSupp = -10018,
+ telBadStateErr = -10019,
+ telStateNotSupp = -10020,
+ telBadIntExt = -10021,
+ telIntExtNotSupp = -10022,
+ telBadDNDType = -10023,
+ telDNDTypeNotSupp = -10024,
+ telFeatNotSub = -10030,
+ telFeatNotAvail = -10031,
+ telFeatActive = -10032,
+ telFeatNotSupp = -10033,
+ telConfLimitErr = -10040,
+ telConfNoLimit = -10041,
+ telConfErr = -10042,
+ telConfRej = -10043,
+ telTransferErr = -10044,
+ telTransferRej = -10045,
+ telCBErr = -10046,
+ telConfLimitExceeded = -10047,
+ telBadDNType = -10050,
+ telBadPageID = -10051,
+ telBadIntercomID = -10052,
+ telBadFeatureID = -10053,
+ telBadFwdType = -10054,
+ telBadPickupGroupID = -10055,
+ telBadParkID = -10056,
+ telBadSelect = -10057,
+ telBadBearerType = -10058,
+ telBadRate = -10059,
+ telDNTypeNotSupp = -10060,
+ telFwdTypeNotSupp = -10061,
+ telBadDisplayMode = -10062,
+ telDisplayModeNotSupp = -10063,
+ telNoCallbackRef = -10064,
+ telAlreadyOpen = -10070,
+ telStillNeeded = -10071,
+ telTermNotOpen = -10072,
+ telCANotAcceptable = -10080,
+ telCANotRejectable = -10081,
+ telCANotDeflectable = -10082,
+ telPBErr = -10090,
+ telBadFunction = -10091,
+
+ telNoSuchTool = -10102,
+ telUnknownErr = -10103,
+ telNoCommFolder = -10106,
+ telInitFailed = -10107,
+ telBadCodeResource = -10108,
+ telDeviceNotFound = -10109,
+ telBadProcID = -10110,
+ telValidateFailed = -10111,
+ telAutoAnsNotOn = -10112,
+ telDetAlreadyOn = -10113,
+ telBadSWErr = -10114,
+ telBadSampleRate = -10115,
+ telNotEnoughdspBW = -10116
+};
+
+enum {
+ errTaskNotFound = -10780
+};
+
+
+
+
+
+enum {
+
+ pmBusyErr = -13000,
+ pmReplyTOErr = -13001,
+ pmSendStartErr = -13002,
+ pmSendEndErr = -13003,
+ pmRecvStartErr = -13004,
+ pmRecvEndErr = -13005
+};
+
+
+enum {
+ kPowerHandlerExistsForDeviceErr = -13006,
+ kPowerHandlerNotFoundForDeviceErr = -13007,
+ kPowerHandlerNotFoundForProcErr = -13008,
+ kPowerMgtMessageNotHandled = -13009,
+ kPowerMgtRequestDenied = -13010,
+ kCantReportProcessorTemperatureErr = -13013,
+ kProcessorTempRoutineRequiresMPLib2 = -13014,
+ kNoSuchPowerSource = -13020,
+ kBridgeSoftwareRunningCantSleep = -13038
+};
+
+
+
+enum {
+ debuggingExecutionContextErr = -13880,
+ debuggingDuplicateSignatureErr = -13881,
+ debuggingDuplicateOptionErr = -13882,
+ debuggingInvalidSignatureErr = -13883,
+ debuggingInvalidOptionErr = -13884,
+ debuggingInvalidNameErr = -13885,
+ debuggingNoCallbackErr = -13886,
+ debuggingNoMatchErr = -13887
+};
+
+
+
+enum {
+ kHIDVersionIncompatibleErr = -13909,
+ kHIDDeviceNotReady = -13910
+};
+
+
+
+enum {
+ kHIDSuccess = 0,
+ kHIDInvalidRangePageErr = -13923,
+ kHIDReportIDZeroErr = -13924,
+ kHIDReportCountZeroErr = -13925,
+ kHIDReportSizeZeroErr = -13926,
+ kHIDUnmatchedDesignatorRangeErr = -13927,
+ kHIDUnmatchedStringRangeErr = -13928,
+ kHIDInvertedUsageRangeErr = -13929,
+ kHIDUnmatchedUsageRangeErr = -13930,
+ kHIDInvertedPhysicalRangeErr = -13931,
+ kHIDInvertedLogicalRangeErr = -13932,
+ kHIDBadLogicalMaximumErr = -13933,
+ kHIDBadLogicalMinimumErr = -13934,
+ kHIDUsagePageZeroErr = -13935,
+ kHIDEndOfDescriptorErr = -13936,
+ kHIDNotEnoughMemoryErr = -13937,
+ kHIDBadParameterErr = -13938,
+ kHIDNullPointerErr = -13939,
+ kHIDInvalidReportLengthErr = -13940,
+ kHIDInvalidReportTypeErr = -13941,
+ kHIDBadLogPhysValuesErr = -13942,
+ kHIDIncompatibleReportErr = -13943,
+ kHIDInvalidPreparsedDataErr = -13944,
+ kHIDNotValueArrayErr = -13945,
+ kHIDUsageNotFoundErr = -13946,
+ kHIDValueOutOfRangeErr = -13947,
+ kHIDBufferTooSmallErr = -13948,
+ kHIDNullStateErr = -13949,
+ kHIDBaseError = -13950
+};
+
+
+
+enum {
+ kModemOutOfMemory = -14000,
+ kModemPreferencesMissing = -14001,
+ kModemScriptMissing = -14002
+};
+
+
+
+
+enum {
+ kTXNEndIterationErr = -22000,
+ kTXNCannotAddFrameErr = -22001,
+ kTXNInvalidFrameIDErr = -22002,
+ kTXNIllegalToCrossDataBoundariesErr = -22003,
+ kTXNUserCanceledOperationErr = -22004,
+ kTXNBadDefaultFileTypeWarning = -22005,
+ kTXNCannotSetAutoIndentErr = -22006,
+ kTXNRunIndexOutofBoundsErr = -22007,
+ kTXNNoMatchErr = -22008,
+ kTXNAttributeTagInvalidForRunErr = -22009,
+ kTXNSomeOrAllTagsInvalidForRunErr = -22010,
+ kTXNInvalidRunIndex = -22011,
+ kTXNAlreadyInitializedErr = -22012,
+ kTXNCannotTurnTSMOffWhenUsingUnicodeErr = -22013,
+ kTXNCopyNotAllowedInEchoModeErr = -22014,
+ kTXNDataTypeNotAllowedErr = -22015,
+ kTXNATSUIIsNotInstalledErr = -22016,
+ kTXNOutsideOfLineErr = -22017,
+ kTXNOutsideOfFrameErr = -22018
+};
+
+
+
+
+
+enum {
+ printerStatusOpCodeNotSupportedErr = -25280
+};
+
+
+
+enum {
+ errKCNotAvailable = -25291,
+ errKCReadOnly = -25292,
+ errKCAuthFailed = -25293,
+ errKCNoSuchKeychain = -25294,
+ errKCInvalidKeychain = -25295,
+ errKCDuplicateKeychain = -25296,
+ errKCDuplicateCallback = -25297,
+ errKCInvalidCallback = -25298,
+ errKCDuplicateItem = -25299,
+ errKCItemNotFound = -25300,
+ errKCBufferTooSmall = -25301,
+ errKCDataTooLarge = -25302,
+ errKCNoSuchAttr = -25303,
+ errKCInvalidItemRef = -25304,
+ errKCInvalidSearchRef = -25305,
+ errKCNoSuchClass = -25306,
+ errKCNoDefaultKeychain = -25307,
+ errKCInteractionNotAllowed = -25308,
+ errKCReadOnlyAttr = -25309,
+ errKCWrongKCVersion = -25310,
+ errKCKeySizeNotAllowed = -25311,
+ errKCNoStorageModule = -25312,
+ errKCNoCertificateModule = -25313,
+ errKCNoPolicyModule = -25314,
+ errKCInteractionRequired = -25315,
+ errKCDataNotAvailable = -25316,
+ errKCDataNotModifiable = -25317,
+ errKCCreateChainFailed = -25318
+};
+
+
+
+enum {
+ kUCOutputBufferTooSmall = -25340,
+ kUCTextBreakLocatorMissingType = -25341
+};
+
+enum {
+ kUCTSNoKeysAddedToObjectErr = -25342,
+ kUCTSSearchListErr = -25343
+};
+
+
+enum {
+ kMPIterationEndErr = -29275,
+ kMPPrivilegedErr = -29276,
+ kMPProcessCreatedErr = -29288,
+ kMPProcessTerminatedErr = -29289,
+ kMPTaskCreatedErr = -29290,
+ kMPTaskBlockedErr = -29291,
+ kMPTaskStoppedErr = -29292,
+ kMPBlueBlockingErr = -29293,
+ kMPDeletedErr = -29295,
+ kMPTimeoutErr = -29296,
+ kMPTaskAbortedErr = -29297,
+ kMPInsufficientResourcesErr = -29298,
+ kMPInvalidIDErr = -29299
+};
+
+enum {
+ kMPNanokernelNeedsMemoryErr = -29294
+};
+
+
+enum {
+ kCollateAttributesNotFoundErr = -29500,
+ kCollateInvalidOptions = -29501,
+ kCollateMissingUnicodeTableErr = -29502,
+ kCollateUnicodeConvertFailedErr = -29503,
+ kCollatePatternNotFoundErr = -29504,
+ kCollateInvalidChar = -29505,
+ kCollateBufferTooSmall = -29506,
+ kCollateInvalidCollationRef = -29507
+};
+
+
+
+enum {
+ kFNSInvalidReferenceErr = -29580,
+ kFNSBadReferenceVersionErr = -29581,
+ kFNSInvalidProfileErr = -29582,
+ kFNSBadProfileVersionErr = -29583,
+ kFNSDuplicateReferenceErr = -29584,
+ kFNSMismatchErr = -29585,
+ kFNSInsufficientDataErr = -29586,
+ kFNSBadFlattenedSizeErr = -29587,
+ kFNSNameNotFoundErr = -29589
+};
+
+
+
+
+enum {
+ kLocalesBufferTooSmallErr = -30001,
+ kLocalesTableFormatErr = -30002,
+ kLocalesDefaultDisplayStatus = -30029
+};
+
+
+
+enum {
+ kALMInternalErr = -30049,
+ kALMGroupNotFoundErr = -30048,
+ kALMNoSuchModuleErr = -30047,
+ kALMModuleCommunicationErr = -30046,
+ kALMDuplicateModuleErr = -30045,
+ kALMInstallationErr = -30044,
+ kALMDeferSwitchErr = -30043,
+ kALMRebootFlagsLevelErr = -30042
+};
+
+enum {
+ kALMLocationNotFoundErr = kALMGroupNotFoundErr
+};
+
+
+
+enum {
+ kSSpInternalErr = -30340,
+ kSSpVersionErr = -30341,
+ kSSpCantInstallErr = -30342,
+ kSSpParallelUpVectorErr = -30343,
+ kSSpScaleToZeroErr = -30344
+};
+
+
+
+enum {
+ kNSpInitializationFailedErr = -30360,
+ kNSpAlreadyInitializedErr = -30361,
+ kNSpTopologyNotSupportedErr = -30362,
+ kNSpPipeFullErr = -30364,
+ kNSpHostFailedErr = -30365,
+ kNSpProtocolNotAvailableErr = -30366,
+ kNSpInvalidGameRefErr = -30367,
+ kNSpInvalidParameterErr = -30369,
+ kNSpOTNotPresentErr = -30370,
+ kNSpOTVersionTooOldErr = -30371,
+ kNSpMemAllocationErr = -30373,
+ kNSpAlreadyAdvertisingErr = -30374,
+ kNSpNotAdvertisingErr = -30376,
+ kNSpInvalidAddressErr = -30377,
+ kNSpFreeQExhaustedErr = -30378,
+ kNSpRemovePlayerFailedErr = -30379,
+ kNSpAddressInUseErr = -30380,
+ kNSpFeatureNotImplementedErr = -30381,
+ kNSpNameRequiredErr = -30382,
+ kNSpInvalidPlayerIDErr = -30383,
+ kNSpInvalidGroupIDErr = -30384,
+ kNSpNoPlayersErr = -30385,
+ kNSpNoGroupsErr = -30386,
+ kNSpNoHostVolunteersErr = -30387,
+ kNSpCreateGroupFailedErr = -30388,
+ kNSpAddPlayerFailedErr = -30389,
+ kNSpInvalidDefinitionErr = -30390,
+ kNSpInvalidProtocolRefErr = -30391,
+ kNSpInvalidProtocolListErr = -30392,
+ kNSpTimeoutErr = -30393,
+ kNSpGameTerminatedErr = -30394,
+ kNSpConnectFailedErr = -30395,
+ kNSpSendFailedErr = -30396,
+ kNSpMessageTooBigErr = -30397,
+ kNSpCantBlockErr = -30398,
+ kNSpJoinFailedErr = -30399
+};
+
+
+
+enum {
+ kISpInternalErr = -30420,
+ kISpSystemListErr = -30421,
+ kISpBufferToSmallErr = -30422,
+ kISpElementInListErr = -30423,
+ kISpElementNotInListErr = -30424,
+ kISpSystemInactiveErr = -30425,
+ kISpDeviceInactiveErr = -30426,
+ kISpSystemActiveErr = -30427,
+ kISpDeviceActiveErr = -30428,
+ kISpListBusyErr = -30429
+};
+
+
+enum {
+ kDSpNotInitializedErr = -30440L,
+ kDSpSystemSWTooOldErr = -30441L,
+ kDSpInvalidContextErr = -30442L,
+ kDSpInvalidAttributesErr = -30443L,
+ kDSpContextAlreadyReservedErr = -30444L,
+ kDSpContextNotReservedErr = -30445L,
+ kDSpContextNotFoundErr = -30446L,
+ kDSpFrameRateNotReadyErr = -30447L,
+ kDSpConfirmSwitchWarning = -30448L,
+ kDSpInternalErr = -30449L,
+ kDSpStereoContextErr = -30450L
+};
+
+
+
+
+
+
+
+enum {
+ kFBCvTwinExceptionErr = -30500,
+ kFBCnoIndexesFound = -30501,
+ kFBCallocFailed = -30502,
+ kFBCbadParam = -30503,
+ kFBCfileNotIndexed = -30504,
+ kFBCbadIndexFile = -30505,
+ kFBCcompactionFailed = -30506,
+ kFBCvalidationFailed = -30507,
+ kFBCindexingFailed = -30508,
+ kFBCcommitFailed = -30509,
+ kFBCdeletionFailed = -30510,
+ kFBCmoveFailed = -30511,
+ kFBCtokenizationFailed = -30512,
+ kFBCmergingFailed = -30513,
+ kFBCindexCreationFailed = -30514,
+ kFBCaccessorStoreFailed = -30515,
+ kFBCaddDocFailed = -30516,
+ kFBCflushFailed = -30517,
+ kFBCindexNotFound = -30518,
+ kFBCnoSearchSession = -30519,
+ kFBCindexingCanceled = -30520,
+ kFBCaccessCanceled = -30521,
+ kFBCindexFileDestroyed = -30522,
+ kFBCindexNotAvailable = -30523,
+ kFBCsearchFailed = -30524,
+ kFBCsomeFilesNotIndexed = -30525,
+ kFBCillegalSessionChange = -30526,
+
+ kFBCanalysisNotAvailable = -30527,
+ kFBCbadIndexFileVersion = -30528,
+ kFBCsummarizationCanceled = -30529,
+ kFBCindexDiskIOFailed = -30530,
+ kFBCbadSearchSession = -30531,
+ kFBCnoSuchHit = -30532
+};
+
+
+
+enum {
+ notAQTVRMovieErr = -30540,
+ constraintReachedErr = -30541,
+ callNotSupportedByNodeErr = -30542,
+ selectorNotSupportedByNodeErr = -30543,
+ invalidNodeIDErr = -30544,
+ invalidViewStateErr = -30545,
+ timeNotInViewErr = -30546,
+ propertyNotSupportedByNodeErr = -30547,
+ settingNotSupportedByNodeErr = -30548,
+ limitReachedErr = -30549,
+ invalidNodeFormatErr = -30550,
+ invalidHotSpotIDErr = -30551,
+ noMemoryNodeFailedInitialize = -30552,
+ streamingNodeNotReadyErr = -30553,
+ qtvrLibraryLoadErr = -30554,
+ qtvrUninitialized = -30555
+};
+
+
+
+enum {
+ themeInvalidBrushErr = -30560,
+ themeProcessRegisteredErr = -30561,
+ themeProcessNotRegisteredErr = -30562,
+ themeBadTextColorErr = -30563,
+ themeHasNoAccentsErr = -30564,
+ themeBadCursorIndexErr = -30565,
+ themeScriptFontNotFoundErr = -30566,
+ themeMonitorDepthNotSupportedErr = -30567,
+ themeNoAppropriateBrushErr = -30568
+};
+
+
+
+enum {
+ errMessageNotSupported = -30580,
+ errDataNotSupported = -30581,
+ errControlDoesntSupportFocus = -30582,
+ errUnknownControl = -30584,
+ errCouldntSetFocus = -30585,
+ errNoRootControl = -30586,
+ errRootAlreadyExists = -30587,
+ errInvalidPartCode = -30588,
+ errControlsAlreadyExist = -30589,
+ errControlIsNotEmbedder = -30590,
+ errDataSizeMismatch = -30591,
+ errControlHiddenOrDisabled = -30592,
+ errCantEmbedIntoSelf = -30594,
+ errCantEmbedRoot = -30595,
+ errItemNotControl = -30596,
+ controlInvalidDataVersionErr = -30597,
+ controlPropertyInvalid = -5603,
+ controlPropertyNotFoundErr = -5604,
+ controlHandleInvalidErr = -30599
+};
+
+
+
+
+
+enum {
+ kURLInvalidURLReferenceError = -30770,
+ kURLProgressAlreadyDisplayedError = -30771,
+ kURLDestinationExistsError = -30772,
+ kURLInvalidURLError = -30773,
+ kURLUnsupportedSchemeError = -30774,
+ kURLServerBusyError = -30775,
+ kURLAuthenticationError = -30776,
+ kURLPropertyNotYetKnownError = -30777,
+ kURLUnknownPropertyError = -30778,
+ kURLPropertyBufferTooSmallError = -30779,
+ kURLUnsettablePropertyError = -30780,
+ kURLInvalidCallError = -30781,
+ kURLFileEmptyError = -30783,
+ kURLExtensionFailureError = -30785,
+ kURLInvalidConfigurationError = -30786,
+ kURLAccessNotAvailableError = -30787,
+ kURL68kNotSupportedError = -30788
+};
+
+
+
+enum {
+ badComponentInstance = (long)0x80008001,
+ badComponentSelector = (long)0x80008002
+};
+
+
+
+enum {
+ dsBusError = 1,
+ dsAddressErr = 2,
+ dsIllInstErr = 3,
+ dsZeroDivErr = 4,
+ dsChkErr = 5,
+ dsOvflowErr = 6,
+ dsPrivErr = 7,
+ dsTraceErr = 8,
+ dsLineAErr = 9,
+ dsLineFErr = 10,
+ dsMiscErr = 11,
+ dsCoreErr = 12,
+ dsIrqErr = 13,
+ dsIOCoreErr = 14,
+ dsLoadErr = 15,
+ dsFPErr = 16,
+ dsNoPackErr = 17,
+ dsNoPk1 = 18,
+ dsNoPk2 = 19
+};
+
+enum {
+ dsNoPk3 = 20,
+ dsNoPk4 = 21,
+ dsNoPk5 = 22,
+ dsNoPk6 = 23,
+ dsNoPk7 = 24,
+ dsMemFullErr = 25,
+ dsBadLaunch = 26,
+ dsFSErr = 27,
+ dsStknHeap = 28,
+ negZcbFreeErr = 33,
+ dsFinderErr = 41,
+ dsBadSlotInt = 51,
+ dsBadSANEOpcode = 81,
+ dsBadPatchHeader = 83,
+ menuPrgErr = 84,
+ dsMBarNFnd = 85,
+ dsHMenuFindErr = 86,
+ dsWDEFNotFound = 87,
+ dsCDEFNotFound = 88,
+ dsMDEFNotFound = 89
+};
+
+enum {
+ dsNoFPU = 90,
+ dsNoPatch = 98,
+ dsBadPatch = 99,
+ dsParityErr = 101,
+ dsOldSystem = 102,
+ ds32BitMode = 103,
+ dsNeedToWriteBootBlocks = 104,
+ dsNotEnoughRAMToBoot = 105,
+ dsBufPtrTooLow = 106,
+ dsVMDeferredFuncTableFull = 112,
+ dsVMBadBackingStore = 113,
+ dsCantHoldSystemHeap = 114,
+ dsSystemRequiresPowerPC = 116,
+ dsGibblyMovedToDisabledFolder = 117,
+ dsUnBootableSystem = 118,
+ dsMustUseFCBAccessors = 119,
+ dsMacOSROMVersionTooOld = 120,
+ dsLostConnectionToNetworkDisk = 121,
+ dsRAMDiskTooBig = 122,
+ dsWriteToSupervisorStackGuardPage = 128,
+ dsReinsert = 30,
+ shutDownAlert = 42,
+ dsShutDownOrRestart = 20000,
+ dsSwitchOffOrRestart = 20001,
+ dsForcedQuit = 20002,
+ dsRemoveDisk = 20003,
+ dsDirtyDisk = 20004,
+ dsShutDownOrResume = 20109,
+ dsSCSIWarn = 20010,
+ dsMBSysError = 29200,
+ dsMBFlpySysError = 29201,
+ dsMBATASysError = 29202,
+ dsMBATAPISysError = 29203,
+ dsMBExternFlpySysError = 29204,
+ dsPCCardATASysError = 29205
+};
+
+
+
+
+
+
+enum {
+ dsNoExtsMacsBug = -1,
+ dsNoExtsDisassembler = -2,
+ dsMacsBugInstalled = -10,
+ dsDisassemblerInstalled = -11,
+ dsExtensionsDisabled = -13,
+ dsGreeting = 40,
+ dsSysErr = 32767,
+
+ WDEFNFnd = dsWDEFNotFound
+};
+
+enum {
+ CDEFNFnd = dsCDEFNotFound,
+ dsNotThe1 = 31,
+ dsBadStartupDisk = 42,
+ dsSystemFileErr = 43,
+ dsHD20Installed = -12,
+ mBarNFnd = -126,
+ fsDSIntErr = -127,
+ hMenuFindErr = -127,
+ userBreak = -490,
+ strUserBreak = -491,
+ exUserBreak = -492
+};
+
+
+enum {
+
+ dsBadLibrary = 1010,
+ dsMixedModeFailure = 1011
+};
+extern void
+SysError(short errorCode) ;
+
+
+
+
+
+
+}
+extern "C" {
+
+
+
+
+enum {
+ kUTCDefaultOptions = 0
+};
+
+
+struct UTCDateTime {
+ UInt16 highSeconds;
+ UInt32 lowSeconds;
+ UInt16 fraction;
+};
+typedef struct UTCDateTime UTCDateTime;
+typedef UTCDateTime * UTCDateTimePtr;
+typedef UTCDateTimePtr * UTCDateTimeHandle;
+struct LocalDateTime {
+ UInt16 highSeconds;
+ UInt32 lowSeconds;
+ UInt16 fraction;
+};
+typedef struct LocalDateTime LocalDateTime;
+typedef LocalDateTime * LocalDateTimePtr;
+typedef LocalDateTimePtr * LocalDateTimeHandle;
+extern OSStatus
+ConvertLocalTimeToUTC(
+ UInt32 localSeconds,
+ UInt32 * utcSeconds) ;
+extern OSStatus
+ConvertUTCToLocalTime(
+ UInt32 utcSeconds,
+ UInt32 * localSeconds) ;
+extern OSStatus
+ConvertUTCToLocalDateTime(
+ const UTCDateTime * utcDateTime,
+ LocalDateTime * localDateTime) ;
+extern OSStatus
+ConvertLocalToUTCDateTime(
+ const LocalDateTime * localDateTime,
+ UTCDateTime * utcDateTime) ;
+extern OSStatus
+GetUTCDateTime(
+ UTCDateTime * utcDateTime,
+ OptionBits options) ;
+extern OSStatus
+SetUTCDateTime(
+ const UTCDateTime * utcDateTime,
+ OptionBits options) ;
+extern OSStatus
+GetLocalDateTime(
+ LocalDateTime * localDateTime,
+ OptionBits options) ;
+extern OSStatus
+SetLocalDateTime(
+ const LocalDateTime * localDateTime,
+ OptionBits options) ;
+
+
+
+
+
+}
+
+
+
+extern "C" {
+
+
+
+
+
+typedef UInt32 TextEncodingBase;
+enum {
+
+ kTextEncodingMacRoman = 0L,
+ kTextEncodingMacJapanese = 1,
+ kTextEncodingMacChineseTrad = 2,
+ kTextEncodingMacKorean = 3,
+ kTextEncodingMacArabic = 4,
+ kTextEncodingMacHebrew = 5,
+ kTextEncodingMacGreek = 6,
+ kTextEncodingMacCyrillic = 7,
+ kTextEncodingMacDevanagari = 9,
+ kTextEncodingMacGurmukhi = 10,
+ kTextEncodingMacGujarati = 11,
+ kTextEncodingMacOriya = 12,
+ kTextEncodingMacBengali = 13,
+ kTextEncodingMacTamil = 14,
+ kTextEncodingMacTelugu = 15,
+ kTextEncodingMacKannada = 16,
+ kTextEncodingMacMalayalam = 17,
+ kTextEncodingMacSinhalese = 18,
+ kTextEncodingMacBurmese = 19,
+ kTextEncodingMacKhmer = 20,
+ kTextEncodingMacThai = 21,
+ kTextEncodingMacLaotian = 22,
+ kTextEncodingMacGeorgian = 23,
+ kTextEncodingMacArmenian = 24,
+ kTextEncodingMacChineseSimp = 25,
+ kTextEncodingMacTibetan = 26,
+ kTextEncodingMacMongolian = 27,
+ kTextEncodingMacEthiopic = 28,
+ kTextEncodingMacCentralEurRoman = 29,
+ kTextEncodingMacVietnamese = 30,
+ kTextEncodingMacExtArabic = 31,
+ kTextEncodingMacSymbol = 33,
+ kTextEncodingMacDingbats = 34,
+ kTextEncodingMacTurkish = 35,
+ kTextEncodingMacCroatian = 36,
+ kTextEncodingMacIcelandic = 37,
+ kTextEncodingMacRomanian = 38,
+ kTextEncodingMacCeltic = 39,
+ kTextEncodingMacGaelic = 40,
+ kTextEncodingMacKeyboardGlyphs = 41
+};
+
+
+enum {
+ kTextEncodingMacTradChinese = kTextEncodingMacChineseTrad,
+ kTextEncodingMacRSymbol = 8,
+ kTextEncodingMacSimpChinese = kTextEncodingMacChineseSimp,
+ kTextEncodingMacGeez = kTextEncodingMacEthiopic,
+ kTextEncodingMacEastEurRoman = kTextEncodingMacCentralEurRoman,
+ kTextEncodingMacUninterp = 32
+};
+enum {
+ kTextEncodingMacUnicode = 0x7E
+};
+
+
+enum {
+
+ kTextEncodingMacFarsi = 0x8C,
+
+ kTextEncodingMacUkrainian = 0x98,
+
+ kTextEncodingMacInuit = 0xEC,
+ kTextEncodingMacVT100 = 0xFC
+};
+
+
+enum {
+ kTextEncodingMacHFS = 0xFF
+};
+
+
+enum {
+ kTextEncodingUnicodeDefault = 0x0100,
+ kTextEncodingUnicodeV1_1 = 0x0101,
+ kTextEncodingISO10646_1993 = 0x0101,
+ kTextEncodingUnicodeV2_0 = 0x0103,
+ kTextEncodingUnicodeV2_1 = 0x0103,
+ kTextEncodingUnicodeV3_0 = 0x0104,
+ kTextEncodingUnicodeV3_1 = 0x0105,
+ kTextEncodingUnicodeV3_2 = 0x0106
+};
+
+
+enum {
+ kTextEncodingISOLatin1 = 0x0201,
+ kTextEncodingISOLatin2 = 0x0202,
+ kTextEncodingISOLatin3 = 0x0203,
+ kTextEncodingISOLatin4 = 0x0204,
+ kTextEncodingISOLatinCyrillic = 0x0205,
+ kTextEncodingISOLatinArabic = 0x0206,
+ kTextEncodingISOLatinGreek = 0x0207,
+ kTextEncodingISOLatinHebrew = 0x0208,
+ kTextEncodingISOLatin5 = 0x0209,
+ kTextEncodingISOLatin6 = 0x020A,
+ kTextEncodingISOLatin7 = 0x020D,
+ kTextEncodingISOLatin8 = 0x020E,
+ kTextEncodingISOLatin9 = 0x020F
+};
+
+
+enum {
+ kTextEncodingDOSLatinUS = 0x0400,
+ kTextEncodingDOSGreek = 0x0405,
+ kTextEncodingDOSBalticRim = 0x0406,
+ kTextEncodingDOSLatin1 = 0x0410,
+ kTextEncodingDOSGreek1 = 0x0411,
+ kTextEncodingDOSLatin2 = 0x0412,
+ kTextEncodingDOSCyrillic = 0x0413,
+ kTextEncodingDOSTurkish = 0x0414,
+ kTextEncodingDOSPortuguese = 0x0415,
+ kTextEncodingDOSIcelandic = 0x0416,
+ kTextEncodingDOSHebrew = 0x0417,
+ kTextEncodingDOSCanadianFrench = 0x0418,
+ kTextEncodingDOSArabic = 0x0419,
+ kTextEncodingDOSNordic = 0x041A,
+ kTextEncodingDOSRussian = 0x041B,
+ kTextEncodingDOSGreek2 = 0x041C,
+ kTextEncodingDOSThai = 0x041D,
+ kTextEncodingDOSJapanese = 0x0420,
+ kTextEncodingDOSChineseSimplif = 0x0421,
+ kTextEncodingDOSKorean = 0x0422,
+ kTextEncodingDOSChineseTrad = 0x0423,
+ kTextEncodingWindowsLatin1 = 0x0500,
+ kTextEncodingWindowsANSI = 0x0500,
+ kTextEncodingWindowsLatin2 = 0x0501,
+ kTextEncodingWindowsCyrillic = 0x0502,
+ kTextEncodingWindowsGreek = 0x0503,
+ kTextEncodingWindowsLatin5 = 0x0504,
+ kTextEncodingWindowsHebrew = 0x0505,
+ kTextEncodingWindowsArabic = 0x0506,
+ kTextEncodingWindowsBalticRim = 0x0507,
+ kTextEncodingWindowsVietnamese = 0x0508,
+ kTextEncodingWindowsKoreanJohab = 0x0510
+};
+
+
+enum {
+ kTextEncodingUS_ASCII = 0x0600,
+ kTextEncodingJIS_X0201_76 = 0x0620,
+ kTextEncodingJIS_X0208_83 = 0x0621,
+ kTextEncodingJIS_X0208_90 = 0x0622,
+ kTextEncodingJIS_X0212_90 = 0x0623,
+ kTextEncodingJIS_C6226_78 = 0x0624,
+ kTextEncodingShiftJIS_X0213_00 = 0x0628,
+ kTextEncodingGB_2312_80 = 0x0630,
+ kTextEncodingGBK_95 = 0x0631,
+ kTextEncodingGB_18030_2000 = 0x0632,
+ kTextEncodingKSC_5601_87 = 0x0640,
+ kTextEncodingKSC_5601_92_Johab = 0x0641,
+ kTextEncodingCNS_11643_92_P1 = 0x0651,
+ kTextEncodingCNS_11643_92_P2 = 0x0652,
+ kTextEncodingCNS_11643_92_P3 = 0x0653
+};
+
+
+enum {
+ kTextEncodingISO_2022_JP = 0x0820,
+ kTextEncodingISO_2022_JP_2 = 0x0821,
+ kTextEncodingISO_2022_JP_1 = 0x0822,
+ kTextEncodingISO_2022_JP_3 = 0x0823,
+ kTextEncodingISO_2022_CN = 0x0830,
+ kTextEncodingISO_2022_CN_EXT = 0x0831,
+ kTextEncodingISO_2022_KR = 0x0840
+};
+
+
+enum {
+ kTextEncodingEUC_JP = 0x0920,
+ kTextEncodingEUC_CN = 0x0930,
+ kTextEncodingEUC_TW = 0x0931,
+ kTextEncodingEUC_KR = 0x0940
+};
+
+
+enum {
+ kTextEncodingShiftJIS = 0x0A01,
+ kTextEncodingKOI8_R = 0x0A02,
+ kTextEncodingBig5 = 0x0A03,
+ kTextEncodingMacRomanLatin1 = 0x0A04,
+ kTextEncodingHZ_GB_2312 = 0x0A05,
+ kTextEncodingBig5_HKSCS_1999 = 0x0A06
+};
+
+
+enum {
+ kTextEncodingNextStepLatin = 0x0B01,
+ kTextEncodingNextStepJapanese = 0x0B02
+};
+
+
+enum {
+ kTextEncodingEBCDIC_US = 0x0C01,
+ kTextEncodingEBCDIC_CP037 = 0x0C02
+};
+
+
+enum {
+ kTextEncodingMultiRun = 0x0FFF,
+ kTextEncodingUnknown = 0xFFFF
+};
+
+
+
+typedef UInt32 TextEncodingVariant;
+
+enum {
+ kTextEncodingDefaultVariant = 0
+};
+
+
+enum {
+ kMacRomanDefaultVariant = 0,
+ kMacRomanCurrencySignVariant = 1,
+ kMacRomanEuroSignVariant = 2
+};
+
+
+enum {
+ kMacCyrillicDefaultVariant = 0,
+ kMacCyrillicCurrSignStdVariant = 1,
+ kMacCyrillicCurrSignUkrVariant = 2,
+ kMacCyrillicEuroSignVariant = 3
+};
+
+
+enum {
+ kMacIcelandicStdDefaultVariant = 0,
+ kMacIcelandicTTDefaultVariant = 1,
+
+ kMacIcelandicStdCurrSignVariant = 2,
+ kMacIcelandicTTCurrSignVariant = 3,
+
+ kMacIcelandicStdEuroSignVariant = 4,
+ kMacIcelandicTTEuroSignVariant = 5
+};
+
+
+enum {
+ kMacCroatianDefaultVariant = 0,
+ kMacCroatianCurrencySignVariant = 1,
+ kMacCroatianEuroSignVariant = 2
+};
+
+
+
+enum {
+ kMacRomanianDefaultVariant = 0,
+ kMacRomanianCurrencySignVariant = 1,
+ kMacRomanianEuroSignVariant = 2
+};
+
+
+
+enum {
+ kMacJapaneseStandardVariant = 0,
+ kMacJapaneseStdNoVerticalsVariant = 1,
+ kMacJapaneseBasicVariant = 2,
+ kMacJapanesePostScriptScrnVariant = 3,
+ kMacJapanesePostScriptPrintVariant = 4,
+ kMacJapaneseVertAtKuPlusTenVariant = 5
+};
+
+
+enum {
+ kMacArabicStandardVariant = 0,
+ kMacArabicTrueTypeVariant = 1,
+ kMacArabicThuluthVariant = 2,
+ kMacArabicAlBayanVariant = 3
+};
+
+
+enum {
+ kMacFarsiStandardVariant = 0,
+ kMacFarsiTrueTypeVariant = 1
+};
+
+
+enum {
+ kMacHebrewStandardVariant = 0,
+ kMacHebrewFigureSpaceVariant = 1
+};
+
+
+enum {
+ kMacVT100DefaultVariant = 0,
+ kMacVT100CurrencySignVariant = 1,
+ kMacVT100EuroSignVariant = 2
+};
+
+
+enum {
+ kUnicodeNoSubset = 0,
+ kUnicodeCanonicalDecompVariant = 2,
+ kUnicodeCanonicalCompVariant = 3,
+ kUnicodeHFSPlusDecompVariant = 8,
+ kUnicodeHFSPlusCompVariant = 9
+};
+
+
+enum {
+ kBig5_BasicVariant = 0,
+ kBig5_StandardVariant = 1,
+ kBig5_ETenVariant = 2
+};
+
+
+enum {
+ kMacRomanLatin1DefaultVariant = 0,
+ kMacRomanLatin1StandardVariant = 2,
+ kMacRomanLatin1TurkishVariant = 6,
+ kMacRomanLatin1CroatianVariant = 8,
+ kMacRomanLatin1IcelandicVariant = 11,
+ kMacRomanLatin1RomanianVariant = 14
+};
+
+
+enum {
+ kUnicodeNoCompatibilityVariant = 1,
+ kUnicodeNoCorporateVariant = 4
+};
+
+
+enum {
+ kMacRomanStandardVariant = 0,
+ kMacIcelandicStandardVariant = 0,
+ kMacIcelandicTrueTypeVariant = 1,
+ kJapaneseStandardVariant = 0,
+ kJapaneseStdNoVerticalsVariant = 1,
+ kJapaneseBasicVariant = 2,
+ kJapanesePostScriptScrnVariant = 3,
+ kJapanesePostScriptPrintVariant = 4,
+ kJapaneseVertAtKuPlusTenVariant = 5,
+
+ kHebrewStandardVariant = 0,
+ kHebrewFigureSpaceVariant = 1,
+ kUnicodeMaxDecomposedVariant = 2,
+ kUnicodeNoComposedVariant = 3,
+
+
+ kJapaneseNoOneByteKanaOption = 0x20,
+ kJapaneseUseAsciiBackslashOption = 0x40
+};
+
+
+typedef UInt32 TextEncodingFormat;
+enum {
+
+ kTextEncodingDefaultFormat = 0,
+ kUnicode16BitFormat = 0,
+ kUnicodeUTF7Format = 1,
+ kUnicodeUTF8Format = 2,
+ kUnicode32BitFormat = 3
+};
+
+
+typedef UInt32 TextEncoding;
+
+typedef UInt32 TextEncodingNameSelector;
+enum {
+ kTextEncodingFullName = 0,
+ kTextEncodingBaseName = 1,
+ kTextEncodingVariantName = 2,
+ kTextEncodingFormatName = 3
+};
+
+
+struct TextEncodingRun {
+ ByteOffset offset;
+ TextEncoding textEncoding;
+};
+typedef struct TextEncodingRun TextEncodingRun;
+typedef TextEncodingRun * TextEncodingRunPtr;
+typedef const TextEncodingRun * ConstTextEncodingRunPtr;
+struct ScriptCodeRun {
+ ByteOffset offset;
+ ScriptCode script;
+};
+typedef struct ScriptCodeRun ScriptCodeRun;
+typedef ScriptCodeRun * ScriptCodeRunPtr;
+typedef const ScriptCodeRun * ConstScriptCodeRunPtr;
+typedef UInt8 * TextPtr;
+typedef const UInt8 * ConstTextPtr;
+
+typedef UniChar * UniCharArrayPtr;
+typedef const UniChar * ConstUniCharArrayPtr;
+
+
+
+
+typedef UniCharArrayPtr * UniCharArrayHandle;
+
+
+
+
+typedef UInt32 UniCharArrayOffset;
+
+enum {
+ kTextScriptDontCare = -128,
+ kTextLanguageDontCare = -128,
+ kTextRegionDontCare = -128
+};
+
+
+
+struct TECInfo {
+ UInt16 format;
+ UInt16 tecVersion;
+ UInt32 tecTextConverterFeatures;
+ UInt32 tecUnicodeConverterFeatures;
+ UInt32 tecTextCommonFeatures;
+ Str31 tecTextEncodingsFolderName;
+ Str31 tecExtensionFileName;
+ UInt16 tecLowestTEFileVersion;
+ UInt16 tecHighestTEFileVersion;
+};
+typedef struct TECInfo TECInfo;
+typedef TECInfo * TECInfoPtr;
+typedef TECInfoPtr * TECInfoHandle;
+
+enum {
+ kTECInfoCurrentFormat = 2
+};
+enum {
+ kTECKeepInfoFixBit = 0,
+ kTECFallbackTextLengthFixBit = 1,
+ kTECTextRunBitClearFixBit = 2,
+ kTECTextToUnicodeScanFixBit = 3,
+ kTECAddForceASCIIChangesBit = 4,
+ kTECPreferredEncodingFixBit = 5,
+ kTECAddTextRunHeuristicsBit = 6,
+ kTECAddFallbackInterruptBit = 7
+};
+
+enum {
+ kTECKeepInfoFixMask = 1L << kTECKeepInfoFixBit,
+ kTECFallbackTextLengthFixMask = 1L << kTECFallbackTextLengthFixBit,
+ kTECTextRunBitClearFixMask = 1L << kTECTextRunBitClearFixBit,
+ kTECTextToUnicodeScanFixMask = 1L << kTECTextToUnicodeScanFixBit,
+ kTECAddForceASCIIChangesMask = 1L << kTECAddForceASCIIChangesBit,
+ kTECPreferredEncodingFixMask = 1L << kTECPreferredEncodingFixBit,
+ kTECAddTextRunHeuristicsMask = 1L << kTECAddTextRunHeuristicsBit,
+ kTECAddFallbackInterruptMask = 1L << kTECAddFallbackInterruptBit
+};
+
+
+
+
+
+
+
+enum {
+ kUnicodeByteOrderMark = 0xFEFF,
+ kUnicodeObjectReplacement = 0xFFFC,
+ kUnicodeReplacementChar = 0xFFFD,
+ kUnicodeSwappedByteOrderMark = 0xFFFE,
+ kUnicodeNotAChar = 0xFFFF
+};
+
+
+
+
+
+
+typedef SInt32 UCCharPropertyType;
+enum {
+ kUCCharPropTypeGenlCategory = 1,
+ kUCCharPropTypeCombiningClass = 2,
+ kUCCharPropTypeBidiCategory = 3
+};
+
+typedef UInt32 UCCharPropertyValue;
+
+enum {
+
+ kUCGenlCatOtherNotAssigned = 0,
+ kUCGenlCatOtherControl = 1,
+ kUCGenlCatOtherFormat = 2,
+ kUCGenlCatOtherSurrogate = 3,
+ kUCGenlCatOtherPrivateUse = 4,
+ kUCGenlCatMarkNonSpacing = 5,
+ kUCGenlCatMarkSpacingCombining = 6,
+ kUCGenlCatMarkEnclosing = 7,
+ kUCGenlCatNumberDecimalDigit = 8,
+ kUCGenlCatNumberLetter = 9,
+ kUCGenlCatNumberOther = 10,
+ kUCGenlCatSeparatorSpace = 11,
+ kUCGenlCatSeparatorLine = 12,
+ kUCGenlCatSeparatorParagraph = 13,
+ kUCGenlCatLetterUppercase = 14,
+ kUCGenlCatLetterLowercase = 15,
+ kUCGenlCatLetterTitlecase = 16,
+
+ kUCGenlCatLetterModifier = 17,
+ kUCGenlCatLetterOther = 18,
+ kUCGenlCatPunctConnector = 20,
+ kUCGenlCatPunctDash = 21,
+ kUCGenlCatPunctOpen = 22,
+ kUCGenlCatPunctClose = 23,
+ kUCGenlCatPunctInitialQuote = 24,
+ kUCGenlCatPunctFinalQuote = 25,
+ kUCGenlCatPunctOther = 26,
+ kUCGenlCatSymbolMath = 28,
+ kUCGenlCatSymbolCurrency = 29,
+ kUCGenlCatSymbolModifier = 30,
+ kUCGenlCatSymbolOther = 31
+};
+
+
+enum {
+ kUCBidiCatNotApplicable = 0,
+
+ kUCBidiCatLeftRight = 1,
+ kUCBidiCatRightLeft = 2,
+
+ kUCBidiCatEuroNumber = 3,
+ kUCBidiCatEuroNumberSeparator = 4,
+ kUCBidiCatEuroNumberTerminator = 5,
+ kUCBidiCatArabicNumber = 6,
+ kUCBidiCatCommonNumberSeparator = 7,
+
+ kUCBidiCatBlockSeparator = 8,
+ kUCBidiCatSegmentSeparator = 9,
+
+ kUCBidiCatWhitespace = 10,
+ kUCBidiCatOtherNeutral = 11,
+
+ kUCBidiCatRightLeftArabic = 12,
+ kUCBidiCatLeftRightEmbedding = 13,
+ kUCBidiCatRightLeftEmbedding = 14,
+ kUCBidiCatLeftRightOverride = 15,
+ kUCBidiCatRightLeftOverride = 16,
+ kUCBidiCatPopDirectionalFormat = 17,
+ kUCBidiCatNonSpacingMark = 18,
+ kUCBidiCatBoundaryNeutral = 19
+};
+extern TextEncoding
+CreateTextEncoding(
+ TextEncodingBase encodingBase,
+ TextEncodingVariant encodingVariant,
+ TextEncodingFormat encodingFormat) ;
+extern TextEncodingBase
+GetTextEncodingBase(TextEncoding encoding) ;
+extern TextEncodingVariant
+GetTextEncodingVariant(TextEncoding encoding) ;
+extern TextEncodingFormat
+GetTextEncodingFormat(TextEncoding encoding) ;
+extern TextEncoding
+ResolveDefaultTextEncoding(TextEncoding encoding) ;
+extern OSStatus
+GetTextEncodingName(
+ TextEncoding iEncoding,
+ TextEncodingNameSelector iNamePartSelector,
+ RegionCode iPreferredRegion,
+ TextEncoding iPreferredEncoding,
+ ByteCount iOutputBufLen,
+ ByteCount * oNameLength,
+ RegionCode * oActualRegion,
+ TextEncoding * oActualEncoding,
+ TextPtr oEncodingName) ;
+extern OSStatus
+TECGetInfo(TECInfoHandle * tecInfo) ;
+extern OSStatus
+UpgradeScriptInfoToTextEncoding(
+ ScriptCode iTextScriptID,
+ LangCode iTextLanguageID,
+ RegionCode iRegionID,
+ ConstStr255Param iTextFontname,
+ TextEncoding * oEncoding) ;
+extern OSStatus
+RevertTextEncodingToScriptInfo(
+ TextEncoding iEncoding,
+ ScriptCode * oTextScriptID,
+ LangCode * oTextLanguageID,
+ Str255 oTextFontname) ;
+extern OSStatus
+GetTextEncodingFromScriptInfo(
+ ScriptCode iTextScriptID,
+ LangCode iTextLanguageID,
+ RegionCode iTextRegionID,
+ TextEncoding * oEncoding) ;
+extern OSStatus
+GetScriptInfoFromTextEncoding(
+ TextEncoding iEncoding,
+ ScriptCode * oTextScriptID,
+ LangCode * oTextLanguageID) ;
+extern OSStatus
+NearestMacTextEncodings(
+ TextEncoding generalEncoding,
+ TextEncoding * bestMacEncoding,
+ TextEncoding * alternateMacEncoding) ;
+extern OSStatus
+UCGetCharProperty(
+ const UniChar * charPtr,
+ UniCharCount textLength,
+ UCCharPropertyType propType,
+ UCCharPropertyValue * propValue) ;
+enum {
+ kUCHighSurrogateRangeStart = 0xD800UL,
+ kUCHighSurrogateRangeEnd = 0xDBFFUL,
+ kUCLowSurrogateRangeStart = 0xDC00UL,
+ kUCLowSurrogateRangeEnd = 0xDFFFUL
+};
+static __inline__ Boolean UCIsSurrogateHighCharacter( UniChar character ) {
+
+ return ( ( character & 0xFC00UL ) == kUCHighSurrogateRangeStart );
+}
+
+
+
+
+
+
+
+static __inline__ Boolean UCIsSurrogateLowCharacter( UniChar character ) {
+
+ return ( ( character & 0xFC00UL ) == kUCLowSurrogateRangeStart );
+}
+static __inline__ UnicodeScalarValue UCGetUnicodeScalarValueForSurrogatePair( UniChar surrogateHigh, UniChar surrogateLow ) {
+ return ( ( surrogateHigh - kUCHighSurrogateRangeStart ) << 10 ) + ( surrogateLow - kUCLowSurrogateRangeStart ) + 0x0010000UL;
+}
+
+
+
+
+
+}
+
+
+
+
+
+
+enum {
+ kRoutineDescriptorVersion = 7
+};
+
+
+enum {
+ _MixedModeMagic = 0xAAFE
+};
+
+
+enum {
+ kCurrentMixedModeStateRecord = 1
+};
+
+
+typedef unsigned short CallingConventionType;
+enum {
+ kPascalStackBased = 0,
+ kCStackBased = 1,
+ kRegisterBased = 2,
+ kD0DispatchedPascalStackBased = 8,
+ kD1DispatchedPascalStackBased = 12,
+ kD0DispatchedCStackBased = 9,
+ kStackDispatchedPascalStackBased = 14,
+ kThinkCStackBased = 5
+};
+
+
+typedef SInt8 ISAType;
+enum {
+ kM68kISA = 0,
+ kPowerPCISA = 1
+};
+
+enum {
+ kX86ISA = 2
+};
+
+
+typedef SInt8 RTAType;
+enum {
+ kOld68kRTA = 0 << 4,
+ kPowerPCRTA = 0 << 4,
+ kCFM68kRTA = 1 << 4
+};
+
+enum {
+ kX86RTA = 2 << 4
+};
+enum {
+ kRegisterD0 = 0,
+ kRegisterD1 = 1,
+ kRegisterD2 = 2,
+ kRegisterD3 = 3,
+ kRegisterD4 = 8,
+ kRegisterD5 = 9,
+ kRegisterD6 = 10,
+ kRegisterD7 = 11,
+ kRegisterA0 = 4,
+ kRegisterA1 = 5,
+ kRegisterA2 = 6,
+ kRegisterA3 = 7,
+ kRegisterA4 = 12,
+ kRegisterA5 = 13,
+ kRegisterA6 = 14,
+ kCCRegisterCBit = 16,
+ kCCRegisterVBit = 17,
+ kCCRegisterZBit = 18,
+ kCCRegisterNBit = 19,
+ kCCRegisterXBit = 20
+};
+
+typedef unsigned short registerSelectorType;
+
+enum {
+ kNoByteCode = 0,
+ kOneByteCode = 1,
+ kTwoByteCode = 2,
+ kFourByteCode = 3
+};
+
+
+typedef unsigned long ProcInfoType;
+
+typedef unsigned short RoutineFlagsType;
+enum {
+ kProcDescriptorIsAbsolute = 0x00,
+ kProcDescriptorIsRelative = 0x01
+};
+
+enum {
+ kFragmentIsPrepared = 0x00,
+ kFragmentNeedsPreparing = 0x02
+};
+
+enum {
+ kUseCurrentISA = 0x00,
+ kUseNativeISA = 0x04
+};
+
+enum {
+ kPassSelector = 0x00,
+ kDontPassSelector = 0x08
+};
+
+enum {
+ kRoutineIsNotDispatchedDefaultRoutine = 0x00,
+ kRoutineIsDispatchedDefaultRoutine = 0x10
+};
+
+enum {
+ kProcDescriptorIsProcPtr = 0x00,
+ kProcDescriptorIsIndex = 0x20
+};
+
+struct RoutineRecord {
+ ProcInfoType procInfo;
+ SInt8 reserved1;
+ ISAType ISA;
+ RoutineFlagsType routineFlags;
+ ProcPtr procDescriptor;
+ UInt32 reserved2;
+ UInt32 selector;
+};
+typedef struct RoutineRecord RoutineRecord;
+typedef RoutineRecord * RoutineRecordPtr;
+typedef RoutineRecordPtr * RoutineRecordHandle;
+
+
+typedef UInt8 RDFlagsType;
+enum {
+ kSelectorsAreNotIndexable = 0x00,
+ kSelectorsAreIndexable = 0x01
+};
+
+
+struct RoutineDescriptor {
+ UInt16 goMixedModeTrap;
+ SInt8 version;
+ RDFlagsType routineDescriptorFlags;
+ UInt32 reserved1;
+ UInt8 reserved2;
+ UInt8 selectorInfo;
+ UInt16 routineCount;
+ RoutineRecord routineRecords[1];
+};
+typedef struct RoutineDescriptor RoutineDescriptor;
+typedef RoutineDescriptor * RoutineDescriptorPtr;
+typedef RoutineDescriptorPtr * RoutineDescriptorHandle;
+
+struct MixedModeStateRecord {
+ UInt32 state1;
+ UInt32 state2;
+ UInt32 state3;
+ UInt32 state4;
+};
+typedef struct MixedModeStateRecord MixedModeStateRecord;
+enum {
+
+ kCallingConventionWidth = 4,
+ kCallingConventionPhase = 0,
+ kCallingConventionMask = 0x0F,
+ kResultSizeWidth = 2,
+ kResultSizePhase = kCallingConventionWidth,
+ kResultSizeMask = 0x30,
+ kStackParameterWidth = 2,
+ kStackParameterPhase = (kCallingConventionWidth + kResultSizeWidth),
+ kStackParameterMask = (long)0xFFFFFFC0,
+ kRegisterResultLocationWidth = 5,
+ kRegisterResultLocationPhase = (kCallingConventionWidth + kResultSizeWidth),
+ kRegisterParameterWidth = 5,
+ kRegisterParameterPhase = (kCallingConventionWidth + kResultSizeWidth + kRegisterResultLocationWidth),
+ kRegisterParameterMask = 0x7FFFF800,
+ kRegisterParameterSizePhase = 0,
+ kRegisterParameterSizeWidth = 2,
+ kRegisterParameterWhichPhase = kRegisterParameterSizeWidth,
+ kRegisterParameterWhichWidth = 3,
+ kDispatchedSelectorSizeWidth = 2,
+ kDispatchedSelectorSizePhase = (kCallingConventionWidth + kResultSizeWidth),
+ kDispatchedParameterPhase = (kCallingConventionWidth + kResultSizeWidth + kDispatchedSelectorSizeWidth),
+ kSpecialCaseSelectorWidth = 6,
+ kSpecialCaseSelectorPhase = kCallingConventionWidth,
+ kSpecialCaseSelectorMask = 0x03F0
+};
+
+enum {
+ kSpecialCase = 0x000F
+};
+
+enum {
+
+ kSpecialCaseHighHook = 0,
+ kSpecialCaseCaretHook = 0,
+ kSpecialCaseEOLHook = 1,
+ kSpecialCaseWidthHook = 2,
+ kSpecialCaseTextWidthHook = 2,
+ kSpecialCaseNWidthHook = 3,
+ kSpecialCaseDrawHook = 4,
+ kSpecialCaseHitTestHook = 5,
+ kSpecialCaseTEFindWord = 6,
+ kSpecialCaseProtocolHandler = 7,
+ kSpecialCaseSocketListener = 8,
+ kSpecialCaseTERecalc = 9,
+ kSpecialCaseTEDoText = 10,
+ kSpecialCaseGNEFilterProc = 11,
+ kSpecialCaseMBarHook = 12
+};
+extern "C" {
+
+
+
+
+
+
+enum {
+ kCollectionDontWantTag = 0L,
+ kCollectionDontWantId = 0L,
+ kCollectionDontWantSize = 0L,
+ kCollectionDontWantAttributes = 0L,
+ kCollectionDontWantIndex = 0L,
+ kCollectionDontWantData = 0L
+};
+
+
+
+enum {
+ kCollectionNoAttributes = 0x00000000,
+ kCollectionAllAttributes = (long)0xFFFFFFFF,
+ kCollectionUserAttributes = 0x0000FFFF,
+ kCollectionDefaultAttributes = 0x40000000
+};
+
+
+
+
+
+
+
+enum {
+ kCollectionUser0Bit = 0,
+ kCollectionUser1Bit = 1,
+ kCollectionUser2Bit = 2,
+ kCollectionUser3Bit = 3,
+ kCollectionUser4Bit = 4,
+ kCollectionUser5Bit = 5,
+ kCollectionUser6Bit = 6,
+ kCollectionUser7Bit = 7,
+ kCollectionUser8Bit = 8,
+ kCollectionUser9Bit = 9,
+ kCollectionUser10Bit = 10,
+ kCollectionUser11Bit = 11,
+ kCollectionUser12Bit = 12,
+ kCollectionUser13Bit = 13,
+ kCollectionUser14Bit = 14,
+ kCollectionUser15Bit = 15,
+ kCollectionReserved0Bit = 16,
+ kCollectionReserved1Bit = 17,
+ kCollectionReserved2Bit = 18,
+ kCollectionReserved3Bit = 19,
+ kCollectionReserved4Bit = 20,
+ kCollectionReserved5Bit = 21,
+ kCollectionReserved6Bit = 22,
+ kCollectionReserved7Bit = 23,
+ kCollectionReserved8Bit = 24,
+ kCollectionReserved9Bit = 25,
+ kCollectionReserved10Bit = 26,
+ kCollectionReserved11Bit = 27,
+ kCollectionReserved12Bit = 28,
+ kCollectionReserved13Bit = 29,
+ kCollectionPersistenceBit = 30,
+ kCollectionLockBit = 31
+};
+
+
+
+enum {
+ kCollectionUser0Mask = 1L << kCollectionUser0Bit,
+ kCollectionUser1Mask = 1L << kCollectionUser1Bit,
+ kCollectionUser2Mask = 1L << kCollectionUser2Bit,
+ kCollectionUser3Mask = 1L << kCollectionUser3Bit,
+ kCollectionUser4Mask = 1L << kCollectionUser4Bit,
+ kCollectionUser5Mask = 1L << kCollectionUser5Bit,
+ kCollectionUser6Mask = 1L << kCollectionUser6Bit,
+ kCollectionUser7Mask = 1L << kCollectionUser7Bit,
+ kCollectionUser8Mask = 1L << kCollectionUser8Bit,
+ kCollectionUser9Mask = 1L << kCollectionUser9Bit,
+ kCollectionUser10Mask = 1L << kCollectionUser10Bit,
+ kCollectionUser11Mask = 1L << kCollectionUser11Bit,
+ kCollectionUser12Mask = 1L << kCollectionUser12Bit,
+ kCollectionUser13Mask = 1L << kCollectionUser13Bit,
+ kCollectionUser14Mask = 1L << kCollectionUser14Bit,
+ kCollectionUser15Mask = 1L << kCollectionUser15Bit,
+ kCollectionReserved0Mask = 1L << kCollectionReserved0Bit,
+ kCollectionReserved1Mask = 1L << kCollectionReserved1Bit,
+ kCollectionReserved2Mask = 1L << kCollectionReserved2Bit,
+ kCollectionReserved3Mask = 1L << kCollectionReserved3Bit,
+ kCollectionReserved4Mask = 1L << kCollectionReserved4Bit,
+ kCollectionReserved5Mask = 1L << kCollectionReserved5Bit,
+ kCollectionReserved6Mask = 1L << kCollectionReserved6Bit,
+ kCollectionReserved7Mask = 1L << kCollectionReserved7Bit,
+ kCollectionReserved8Mask = 1L << kCollectionReserved8Bit,
+ kCollectionReserved9Mask = 1L << kCollectionReserved9Bit,
+ kCollectionReserved10Mask = 1L << kCollectionReserved10Bit,
+ kCollectionReserved11Mask = 1L << kCollectionReserved11Bit,
+ kCollectionReserved12Mask = 1L << kCollectionReserved12Bit,
+ kCollectionReserved13Mask = 1L << kCollectionReserved13Bit,
+ kCollectionPersistenceMask = 1L << kCollectionPersistenceBit,
+ kCollectionLockMask = 1L << kCollectionLockBit
+};
+
+
+
+
+
+
+typedef struct OpaqueCollection* Collection;
+
+typedef FourCharCode CollectionTag;
+typedef OSErr ( * CollectionFlattenProcPtr)(SInt32 size, void *data, void *refCon);
+typedef OSErr ( * CollectionExceptionProcPtr)(Collection c, OSErr status);
+typedef CollectionFlattenProcPtr CollectionFlattenUPP;
+typedef CollectionExceptionProcPtr CollectionExceptionUPP;
+extern CollectionFlattenUPP
+NewCollectionFlattenUPP(CollectionFlattenProcPtr userRoutine) ;
+extern CollectionExceptionUPP
+NewCollectionExceptionUPP(CollectionExceptionProcPtr userRoutine) ;
+extern void
+DisposeCollectionFlattenUPP(CollectionFlattenUPP userUPP) ;
+extern void
+DisposeCollectionExceptionUPP(CollectionExceptionUPP userUPP) ;
+extern OSErr
+InvokeCollectionFlattenUPP(
+ SInt32 size,
+ void * data,
+ void * refCon,
+ CollectionFlattenUPP userUPP) ;
+extern OSErr
+InvokeCollectionExceptionUPP(
+ Collection c,
+ OSErr status,
+ CollectionExceptionUPP userUPP) ;
+extern Collection
+NewCollection(void) ;
+extern void
+DisposeCollection(Collection c) ;
+extern Collection
+CloneCollection(Collection c) ;
+extern SInt32
+CountCollectionOwners(Collection c) ;
+extern OSStatus
+RetainCollection(Collection c) ;
+extern OSStatus
+ReleaseCollection(Collection c) ;
+extern ItemCount
+GetCollectionRetainCount(Collection c) ;
+extern Collection
+CopyCollection(
+ Collection srcCollection,
+ Collection dstCollection) ;
+extern SInt32
+GetCollectionDefaultAttributes(Collection c) ;
+extern void
+SetCollectionDefaultAttributes(
+ Collection c,
+ SInt32 whichAttributes,
+ SInt32 newAttributes) ;
+extern SInt32
+CountCollectionItems(Collection c) ;
+extern OSErr
+AddCollectionItem(
+ Collection c,
+ CollectionTag tag,
+ SInt32 id,
+ SInt32 itemSize,
+ const void * itemData) ;
+extern OSErr
+GetCollectionItem(
+ Collection c,
+ CollectionTag tag,
+ SInt32 id,
+ SInt32 * itemSize,
+ void * itemData) ;
+extern OSErr
+RemoveCollectionItem(
+ Collection c,
+ CollectionTag tag,
+ SInt32 id) ;
+extern OSErr
+SetCollectionItemInfo(
+ Collection c,
+ CollectionTag tag,
+ SInt32 id,
+ SInt32 whichAttributes,
+ SInt32 newAttributes) ;
+extern OSErr
+GetCollectionItemInfo(
+ Collection c,
+ CollectionTag tag,
+ SInt32 id,
+ SInt32 * index,
+ SInt32 * itemSize,
+ SInt32 * attributes) ;
+extern OSErr
+ReplaceIndexedCollectionItem(
+ Collection c,
+ SInt32 index,
+ SInt32 itemSize,
+ const void * itemData) ;
+extern OSErr
+GetIndexedCollectionItem(
+ Collection c,
+ SInt32 index,
+ SInt32 * itemSize,
+ void * itemData) ;
+extern OSErr
+RemoveIndexedCollectionItem(
+ Collection c,
+ SInt32 index) ;
+extern OSErr
+SetIndexedCollectionItemInfo(
+ Collection c,
+ SInt32 index,
+ SInt32 whichAttributes,
+ SInt32 newAttributes) ;
+extern OSErr
+GetIndexedCollectionItemInfo(
+ Collection c,
+ SInt32 index,
+ CollectionTag * tag,
+ SInt32 * id,
+ SInt32 * itemSize,
+ SInt32 * attributes) ;
+extern Boolean
+CollectionTagExists(
+ Collection c,
+ CollectionTag tag) ;
+extern SInt32
+CountCollectionTags(Collection c) ;
+extern OSErr
+GetIndexedCollectionTag(
+ Collection c,
+ SInt32 tagIndex,
+ CollectionTag * tag) ;
+extern SInt32
+CountTaggedCollectionItems(
+ Collection c,
+ CollectionTag tag) ;
+extern OSErr
+GetTaggedCollectionItem(
+ Collection c,
+ CollectionTag tag,
+ SInt32 whichItem,
+ SInt32 * itemSize,
+ void * itemData) ;
+extern OSErr
+GetTaggedCollectionItemInfo(
+ Collection c,
+ CollectionTag tag,
+ SInt32 whichItem,
+ SInt32 * id,
+ SInt32 * index,
+ SInt32 * itemSize,
+ SInt32 * attributes) ;
+extern void
+PurgeCollection(
+ Collection c,
+ SInt32 whichAttributes,
+ SInt32 matchingAttributes) ;
+extern void
+PurgeCollectionTag(
+ Collection c,
+ CollectionTag tag) ;
+extern void
+EmptyCollection(Collection c) ;
+extern OSErr
+FlattenCollection(
+ Collection c,
+ CollectionFlattenUPP flattenProc,
+ void * refCon) ;
+extern OSErr
+FlattenPartialCollection(
+ Collection c,
+ CollectionFlattenUPP flattenProc,
+ void * refCon,
+ SInt32 whichAttributes,
+ SInt32 matchingAttributes) ;
+extern OSErr
+UnflattenCollection(
+ Collection c,
+ CollectionFlattenUPP flattenProc,
+ void * refCon) ;
+extern CollectionExceptionUPP
+GetCollectionExceptionProc(Collection c) ;
+extern void
+SetCollectionExceptionProc(
+ Collection c,
+ CollectionExceptionUPP exceptionProc) ;
+extern Collection
+GetNewCollection(SInt16 collectionID) ;
+extern OSErr
+AddCollectionItemHdl(
+ Collection aCollection,
+ CollectionTag tag,
+ SInt32 id,
+ Handle itemData) ;
+extern OSErr
+GetCollectionItemHdl(
+ Collection aCollection,
+ CollectionTag tag,
+ SInt32 id,
+ Handle itemData) ;
+extern OSErr
+ReplaceIndexedCollectionItemHdl(
+ Collection aCollection,
+ SInt32 index,
+ Handle itemData) ;
+extern OSErr
+GetIndexedCollectionItemHdl(
+ Collection aCollection,
+ SInt32 index,
+ Handle itemData) ;
+extern OSErr
+FlattenCollectionToHdl(
+ Collection aCollection,
+ Handle flattened) ;
+extern OSErr
+UnflattenCollectionFromHdl(
+ Collection aCollection,
+ Handle flattened) ;
+}
+
+
+
+typedef long BigEndianLong;
+typedef unsigned long BigEndianUnsignedLong;
+typedef short BigEndianShort;
+typedef unsigned short BigEndianUnsignedShort;
+typedef Fixed BigEndianFixed;
+typedef UnsignedFixed BigEndianUnsignedFixed;
+typedef OSType BigEndianOSType;
+
+
+
+
+
+
+extern "C" {
+
+
+
+
+typedef OSErr ( * SelectorFunctionProcPtr)(OSType selector, long *response);
+typedef SelectorFunctionProcPtr SelectorFunctionUPP;
+extern OSErr
+Gestalt(
+ OSType selector,
+ long * response) ;
+extern OSErr
+ReplaceGestalt(
+ OSType selector,
+ SelectorFunctionUPP gestaltFunction,
+ SelectorFunctionUPP * oldGestaltFunction) ;
+extern OSErr
+NewGestalt(
+ OSType selector,
+ SelectorFunctionUPP gestaltFunction) ;
+extern OSErr
+NewGestaltValue(
+ OSType selector,
+ long newValue) ;
+extern OSErr
+ReplaceGestaltValue(
+ OSType selector,
+ long replacementValue) ;
+extern OSErr
+SetGestaltValue(
+ OSType selector,
+ long newValue) ;
+extern OSErr
+DeleteGestaltValue(OSType selector) ;
+extern SelectorFunctionUPP
+NewSelectorFunctionUPP(SelectorFunctionProcPtr userRoutine) ;
+extern void
+DisposeSelectorFunctionUPP(SelectorFunctionUPP userUPP) ;
+extern OSErr
+InvokeSelectorFunctionUPP(
+ OSType selector,
+ long * response,
+ SelectorFunctionUPP userUPP) ;
+
+
+
+enum {
+ gestaltAddressingModeAttr = 'addr',
+ gestalt32BitAddressing = 0,
+ gestalt32BitSysZone = 1,
+ gestalt32BitCapable = 2
+};
+
+enum {
+ gestaltAFPClient = 'afps',
+ gestaltAFPClientVersionMask = 0x0000FFFF,
+
+ gestaltAFPClient3_5 = 0x0001,
+ gestaltAFPClient3_6 = 0x0002,
+ gestaltAFPClient3_6_1 = 0x0003,
+ gestaltAFPClient3_6_2 = 0x0004,
+ gestaltAFPClient3_6_3 = 0x0005,
+ gestaltAFPClient3_7 = 0x0006,
+ gestaltAFPClient3_7_2 = 0x0007,
+ gestaltAFPClient3_8 = 0x0008,
+ gestaltAFPClient3_8_1 = 0x0009,
+ gestaltAFPClient3_8_3 = 0x000A,
+ gestaltAFPClient3_8_4 = 0x000B,
+ gestaltAFPClientAttributeMask = (long)0xFFFF0000,
+
+ gestaltAFPClientCfgRsrc = 16,
+ gestaltAFPClientSupportsIP = 29,
+ gestaltAFPClientVMUI = 30,
+ gestaltAFPClientMultiReq = 31
+};
+
+
+enum {
+ gestaltAliasMgrAttr = 'alis',
+ gestaltAliasMgrPresent = 0,
+ gestaltAliasMgrSupportsRemoteAppletalk = 1,
+ gestaltAliasMgrSupportsAOCEKeychain = 2,
+ gestaltAliasMgrResolveAliasFileWithMountOptions = 3,
+ gestaltAliasMgrFollowsAliasesWhenResolving = 4,
+ gestaltAliasMgrSupportsExtendedCalls = 5,
+ gestaltAliasMgrSupportsFSCalls = 6,
+ gestaltAliasMgrPrefersPath = 7
+};
+
+
+enum {
+ gestaltAppearanceAttr = 'appr',
+ gestaltAppearanceExists = 0,
+ gestaltAppearanceCompatMode = 1
+};
+
+
+
+
+
+
+
+enum {
+ gestaltAppearanceVersion = 'apvr'
+};
+
+enum {
+ gestaltArbitorAttr = 'arb ',
+ gestaltSerialArbitrationExists = 0
+};
+
+enum {
+ gestaltAppleScriptVersion = 'ascv'
+};
+
+enum {
+ gestaltAppleScriptAttr = 'ascr',
+ gestaltAppleScriptPresent = 0,
+ gestaltAppleScriptPowerPCSupport = 1
+};
+
+enum {
+ gestaltATAAttr = 'ata ',
+ gestaltATAPresent = 0
+};
+
+enum {
+ gestaltATalkVersion = 'atkv'
+};
+
+enum {
+ gestaltAppleTalkVersion = 'atlk'
+};
+enum {
+ gestaltAUXVersion = 'a/ux'
+};
+
+enum {
+ gestaltMacOSCompatibilityBoxAttr = 'bbox',
+ gestaltMacOSCompatibilityBoxPresent = 0,
+ gestaltMacOSCompatibilityBoxHasSerial = 1,
+ gestaltMacOSCompatibilityBoxless = 2
+};
+
+enum {
+ gestaltBusClkSpeed = 'bclk'
+};
+
+enum {
+ gestaltCloseViewAttr = 'BSDa',
+ gestaltCloseViewEnabled = 0,
+ gestaltCloseViewDisplayMgrFriendly = 1
+};
+
+enum {
+ gestaltCarbonVersion = 'cbon'
+};
+
+enum {
+ gestaltCFMAttr = 'cfrg',
+ gestaltCFMPresent = 0,
+ gestaltCFMPresentMask = 0x0001,
+ gestaltCFM99Present = 2,
+ gestaltCFM99PresentMask = 0x0004
+};
+
+enum {
+ gestaltCollectionMgrVersion = 'cltn'
+};
+
+enum {
+ gestaltColorMatchingAttr = 'cmta',
+ gestaltHighLevelMatching = 0,
+ gestaltColorMatchingLibLoaded = 1
+};
+
+enum {
+ gestaltColorMatchingVersion = 'cmtc',
+ gestaltColorSync10 = 0x0100,
+ gestaltColorSync11 = 0x0110,
+ gestaltColorSync104 = 0x0104,
+ gestaltColorSync105 = 0x0105,
+ gestaltColorSync20 = 0x0200,
+ gestaltColorSync21 = 0x0210,
+ gestaltColorSync211 = 0x0211,
+ gestaltColorSync212 = 0x0212,
+ gestaltColorSync213 = 0x0213,
+ gestaltColorSync25 = 0x0250,
+ gestaltColorSync26 = 0x0260,
+ gestaltColorSync261 = 0x0261,
+ gestaltColorSync30 = 0x0300
+};
+
+enum {
+ gestaltControlMgrVersion = 'cmvr'
+};
+
+enum {
+ gestaltControlMgrAttr = 'cntl',
+ gestaltControlMgrPresent = (1L << 0),
+
+
+ gestaltControlMgrPresentBit = 0,
+ gestaltControlMsgPresentMask = (1L << gestaltControlMgrPresentBit)
+};
+
+enum {
+ gestaltConnMgrAttr = 'conn',
+ gestaltConnMgrPresent = 0,
+ gestaltConnMgrCMSearchFix = 1,
+ gestaltConnMgrErrorString = 2,
+ gestaltConnMgrMultiAsyncIO = 3
+};
+
+enum {
+ gestaltColorPickerVersion = 'cpkr',
+ gestaltColorPicker = 'cpkr'
+};
+
+enum {
+ gestaltComponentMgr = 'cpnt',
+ gestaltComponentPlatform = 'copl'
+};
+enum {
+ gestaltNativeCPUtype = 'cput',
+ gestaltNativeCPUfamily = 'cpuf',
+ gestaltCPU68000 = 0,
+ gestaltCPU68010 = 1,
+ gestaltCPU68020 = 2,
+ gestaltCPU68030 = 3,
+ gestaltCPU68040 = 4,
+ gestaltCPU601 = 0x0101,
+ gestaltCPU603 = 0x0103,
+ gestaltCPU604 = 0x0104,
+ gestaltCPU603e = 0x0106,
+ gestaltCPU603ev = 0x0107,
+ gestaltCPU750 = 0x0108,
+ gestaltCPU604e = 0x0109,
+ gestaltCPU604ev = 0x010A,
+ gestaltCPUG4 = 0x010C,
+ gestaltCPUG47450 = 0x0110
+};
+
+enum {
+ gestaltCPUApollo = 0x0111,
+ gestaltCPU750FX = 0x0120
+};
+
+enum {
+
+ gestaltCPU486 = 'i486',
+ gestaltCPUPentium = 'i586',
+ gestaltCPUPentiumPro = 'i5pr',
+ gestaltCPUPentiumII = 'i5ii',
+ gestaltCPUX86 = 'ixxx'
+};
+
+enum {
+ gestaltCRMAttr = 'crm ',
+ gestaltCRMPresent = 0,
+ gestaltCRMPersistentFix = 1,
+ gestaltCRMToolRsrcCalls = 2
+};
+
+enum {
+ gestaltControlStripVersion = 'csvr'
+};
+
+enum {
+ gestaltCTBVersion = 'ctbv'
+};
+
+enum {
+ gestaltDBAccessMgrAttr = 'dbac',
+ gestaltDBAccessMgrPresent = 0
+};
+
+enum {
+ gestaltDiskCacheSize = 'dcsz'
+};
+
+enum {
+ gestaltSDPFindVersion = 'dfnd'
+};
+
+enum {
+ gestaltDictionaryMgrAttr = 'dict',
+ gestaltDictionaryMgrPresent = 0
+};
+
+enum {
+ gestaltDITLExtAttr = 'ditl',
+ gestaltDITLExtPresent = 0,
+ gestaltDITLExtSupportsIctb = 1
+};
+
+enum {
+ gestaltDialogMgrAttr = 'dlog',
+ gestaltDialogMgrPresent = (1L << 0),
+
+
+ gestaltDialogMgrPresentBit = 0,
+ gestaltDialogMgrHasAquaAlertBit = 2,
+ gestaltDialogMgrPresentMask = (1L << gestaltDialogMgrPresentBit),
+ gestaltDialogMgrHasAquaAlertMask = (1L << gestaltDialogMgrHasAquaAlertBit),
+ gestaltDialogMsgPresentMask = gestaltDialogMgrPresentMask
+};
+
+enum {
+ gestaltDesktopPicturesAttr = 'dkpx',
+ gestaltDesktopPicturesInstalled = 0,
+ gestaltDesktopPicturesDisplayed = 1
+};
+
+enum {
+ gestaltDisplayMgrVers = 'dplv'
+};
+
+enum {
+ gestaltDisplayMgrAttr = 'dply',
+ gestaltDisplayMgrPresent = 0,
+ gestaltDisplayMgrCanSwitchMirrored = 2,
+ gestaltDisplayMgrSetDepthNotifies = 3,
+ gestaltDisplayMgrCanConfirm = 4,
+ gestaltDisplayMgrColorSyncAware = 5,
+ gestaltDisplayMgrGeneratesProfiles = 6,
+ gestaltDisplayMgrSleepNotifies = 7
+};
+
+enum {
+ gestaltDragMgrAttr = 'drag',
+ gestaltDragMgrPresent = 0,
+ gestaltDragMgrFloatingWind = 1,
+ gestaltPPCDragLibPresent = 2,
+ gestaltDragMgrHasImageSupport = 3,
+ gestaltCanStartDragInFloatWindow = 4,
+ gestaltSetDragImageUpdates = 5
+};
+
+enum {
+ gestaltDrawSprocketVersion = 'dspv'
+};
+
+enum {
+ gestaltDigitalSignatureVersion = 'dsig'
+};
+
+
+
+
+
+enum {
+ gestaltDTPFeatures = 'dtpf',
+ kDTPThirdPartySupported = 0x00000004
+};
+
+
+
+
+
+
+enum {
+ gestaltDTPInfo = 'dtpx'
+};
+
+enum {
+ gestaltEasyAccessAttr = 'easy',
+ gestaltEasyAccessOff = 0,
+ gestaltEasyAccessOn = 1,
+ gestaltEasyAccessSticky = 2,
+ gestaltEasyAccessLocked = 3
+};
+
+enum {
+ gestaltEditionMgrAttr = 'edtn',
+ gestaltEditionMgrPresent = 0,
+ gestaltEditionMgrTranslationAware = 1
+};
+
+enum {
+ gestaltAppleEventsAttr = 'evnt',
+ gestaltAppleEventsPresent = 0,
+ gestaltScriptingSupport = 1,
+ gestaltOSLInSystem = 2,
+ gestaltSupportsApplicationURL = 4
+};
+
+enum {
+ gestaltExtensionTableVersion = 'etbl'
+};
+
+
+enum {
+ gestaltFBCIndexingState = 'fbci',
+ gestaltFBCindexingSafe = 0,
+ gestaltFBCindexingCritical = 1
+};
+
+enum {
+ gestaltFBCVersion = 'fbcv',
+ gestaltFBCCurrentVersion = 0x0011,
+ gestaltOSXFBCCurrentVersion = 0x0100
+};
+
+
+enum {
+ gestaltFileMappingAttr = 'flmp',
+ gestaltFileMappingPresent = 0,
+ gestaltFileMappingMultipleFilesFix = 1
+};
+
+enum {
+ gestaltFloppyAttr = 'flpy',
+ gestaltFloppyIsMFMOnly = 0,
+ gestaltFloppyIsManualEject = 1,
+ gestaltFloppyUsesDiskInPlace = 2
+};
+
+enum {
+ gestaltFinderAttr = 'fndr',
+ gestaltFinderDropEvent = 0,
+ gestaltFinderMagicPlacement = 1,
+ gestaltFinderCallsAEProcess = 2,
+ gestaltOSLCompliantFinder = 3,
+ gestaltFinderSupports4GBVolumes = 4,
+ gestaltFinderHasClippings = 6,
+ gestaltFinderFullDragManagerSupport = 7,
+ gestaltFinderFloppyRootComments = 8,
+ gestaltFinderLargeAndNotSavedFlavorsOK = 9,
+ gestaltFinderUsesExtensibleFolderManager = 10,
+ gestaltFinderUnderstandsRedirectedDesktopFolder = 11
+};
+
+enum {
+ gestaltFindFolderAttr = 'fold',
+ gestaltFindFolderPresent = 0,
+ gestaltFolderDescSupport = 1,
+ gestaltFolderMgrFollowsAliasesWhenResolving = 2,
+ gestaltFolderMgrSupportsExtendedCalls = 3,
+ gestaltFolderMgrSupportsDomains = 4,
+ gestaltFolderMgrSupportsFSCalls = 5
+};
+
+enum {
+ gestaltFindFolderRedirectionAttr = 'fole'
+};
+
+
+enum {
+ gestaltFontMgrAttr = 'font',
+ gestaltOutlineFonts = 0
+};
+
+enum {
+ gestaltFPUType = 'fpu ',
+ gestaltNoFPU = 0,
+ gestalt68881 = 1,
+ gestalt68882 = 2,
+ gestalt68040FPU = 3
+};
+
+enum {
+ gestaltFSAttr = 'fs ',
+ gestaltFullExtFSDispatching = 0,
+ gestaltHasFSSpecCalls = 1,
+ gestaltHasFileSystemManager = 2,
+ gestaltFSMDoesDynamicLoad = 3,
+ gestaltFSSupports4GBVols = 4,
+ gestaltFSSupports2TBVols = 5,
+ gestaltHasExtendedDiskInit = 6,
+ gestaltDTMgrSupportsFSM = 7,
+ gestaltFSNoMFSVols = 8,
+ gestaltFSSupportsHFSPlusVols = 9,
+ gestaltFSIncompatibleDFA82 = 10
+};
+
+enum {
+ gestaltFSSupportsDirectIO = 11
+};
+
+enum {
+ gestaltHasHFSPlusAPIs = 12,
+ gestaltMustUseFCBAccessors = 13,
+ gestaltFSUsesPOSIXPathsForConversion = 14,
+ gestaltFSSupportsExclusiveLocks = 15,
+ gestaltFSSupportsHardLinkDetection = 16
+};
+
+enum {
+ gestaltAdminFeaturesFlagsAttr = 'fred',
+ gestaltFinderUsesSpecialOpenFoldersFile = 0
+};
+
+enum {
+ gestaltFSMVersion = 'fsm '
+};
+
+enum {
+ gestaltFXfrMgrAttr = 'fxfr',
+ gestaltFXfrMgrPresent = 0,
+ gestaltFXfrMgrMultiFile = 1,
+ gestaltFXfrMgrErrorString = 2,
+ gestaltFXfrMgrAsync = 3
+};
+
+enum {
+ gestaltGraphicsAttr = 'gfxa',
+ gestaltGraphicsIsDebugging = 0x00000001,
+ gestaltGraphicsIsLoaded = 0x00000002,
+ gestaltGraphicsIsPowerPC = 0x00000004
+};
+
+enum {
+ gestaltGraphicsVersion = 'grfx',
+ gestaltCurrentGraphicsVersion = 0x00010200
+};
+
+enum {
+ gestaltHardwareAttr = 'hdwr',
+ gestaltHasVIA1 = 0,
+ gestaltHasVIA2 = 1,
+ gestaltHasASC = 3,
+ gestaltHasSCC = 4,
+ gestaltHasSCSI = 7,
+ gestaltHasSoftPowerOff = 19,
+ gestaltHasSCSI961 = 21,
+ gestaltHasSCSI962 = 22,
+ gestaltHasUniversalROM = 24,
+ gestaltHasEnhancedLtalk = 30
+};
+
+enum {
+ gestaltHelpMgrAttr = 'help',
+ gestaltHelpMgrPresent = 0,
+ gestaltHelpMgrExtensions = 1,
+ gestaltAppleGuideIsDebug = 30,
+ gestaltAppleGuidePresent = 31
+};
+
+enum {
+ gestaltHardwareVendorCode = 'hrad',
+ gestaltHardwareVendorApple = 'Appl'
+};
+
+enum {
+ gestaltCompressionMgr = 'icmp'
+};
+
+enum {
+ gestaltIconUtilitiesAttr = 'icon',
+ gestaltIconUtilitiesPresent = 0,
+ gestaltIconUtilitiesHas48PixelIcons = 1,
+ gestaltIconUtilitiesHas32BitIcons = 2,
+ gestaltIconUtilitiesHas8BitDeepMasks = 3,
+ gestaltIconUtilitiesHasIconServices = 4
+};
+
+enum {
+ gestaltInternalDisplay = 'idsp'
+};
+
+
+
+
+
+enum {
+ gestaltKeyboardType = 'kbd ',
+ gestaltMacKbd = 1,
+ gestaltMacAndPad = 2,
+ gestaltMacPlusKbd = 3,
+ gestaltExtADBKbd = 4,
+ gestaltStdADBKbd = 5,
+ gestaltPrtblADBKbd = 6,
+ gestaltPrtblISOKbd = 7,
+ gestaltStdISOADBKbd = 8,
+ gestaltExtISOADBKbd = 9,
+ gestaltADBKbdII = 10,
+ gestaltADBISOKbdII = 11,
+ gestaltPwrBookADBKbd = 12,
+ gestaltPwrBookISOADBKbd = 13,
+ gestaltAppleAdjustKeypad = 14,
+ gestaltAppleAdjustADBKbd = 15,
+ gestaltAppleAdjustISOKbd = 16,
+ gestaltJapanAdjustADBKbd = 17,
+ gestaltPwrBkExtISOKbd = 20,
+ gestaltPwrBkExtJISKbd = 21,
+ gestaltPwrBkExtADBKbd = 24,
+ gestaltPS2Keyboard = 27,
+ gestaltPwrBkSubDomKbd = 28,
+ gestaltPwrBkSubISOKbd = 29,
+ gestaltPwrBkSubJISKbd = 30,
+ gestaltPwrBkEKDomKbd = 195,
+ gestaltPwrBkEKISOKbd = 196,
+ gestaltPwrBkEKJISKbd = 197,
+ gestaltUSBCosmoANSIKbd = 198,
+ gestaltUSBCosmoISOKbd = 199,
+ gestaltUSBCosmoJISKbd = 200,
+ gestaltPwrBk99JISKbd = 201,
+ gestaltUSBAndyANSIKbd = 204,
+ gestaltUSBAndyISOKbd = 205,
+ gestaltUSBAndyJISKbd = 206
+};
+
+
+enum {
+ gestaltPortable2001ANSIKbd = 202,
+ gestaltPortable2001ISOKbd = 203,
+ gestaltPortable2001JISKbd = 207
+};
+
+
+
+
+
+enum {
+ gestaltUDFSupport = 'kudf'
+};
+
+enum {
+ gestaltLowMemorySize = 'lmem'
+};
+
+enum {
+ gestaltLogicalRAMSize = 'lram'
+};
+enum {
+ gestaltMachineType = 'mach',
+ gestaltClassic = 1,
+ gestaltMacXL = 2,
+ gestaltMac512KE = 3,
+ gestaltMacPlus = 4,
+ gestaltMacSE = 5,
+ gestaltMacII = 6,
+ gestaltMacIIx = 7,
+ gestaltMacIIcx = 8,
+ gestaltMacSE030 = 9,
+ gestaltPortable = 10,
+ gestaltMacIIci = 11,
+ gestaltPowerMac8100_120 = 12,
+ gestaltMacIIfx = 13,
+ gestaltMacClassic = 17,
+ gestaltMacIIsi = 18,
+ gestaltMacLC = 19,
+ gestaltMacQuadra900 = 20,
+ gestaltPowerBook170 = 21,
+ gestaltMacQuadra700 = 22,
+ gestaltClassicII = 23,
+ gestaltPowerBook100 = 24,
+ gestaltPowerBook140 = 25,
+ gestaltMacQuadra950 = 26,
+ gestaltMacLCIII = 27,
+ gestaltPerforma450 = gestaltMacLCIII,
+ gestaltPowerBookDuo210 = 29,
+ gestaltMacCentris650 = 30,
+ gestaltPowerBookDuo230 = 32,
+ gestaltPowerBook180 = 33,
+ gestaltPowerBook160 = 34,
+ gestaltMacQuadra800 = 35,
+ gestaltMacQuadra650 = 36,
+ gestaltMacLCII = 37,
+ gestaltPowerBookDuo250 = 38,
+ gestaltAWS9150_80 = 39,
+ gestaltPowerMac8100_110 = 40,
+ gestaltAWS8150_110 = gestaltPowerMac8100_110,
+ gestaltPowerMac5200 = 41,
+ gestaltPowerMac5260 = gestaltPowerMac5200,
+ gestaltPerforma5300 = gestaltPowerMac5200,
+ gestaltPowerMac6200 = 42,
+ gestaltPerforma6300 = gestaltPowerMac6200,
+ gestaltMacIIvi = 44,
+ gestaltMacIIvm = 45,
+ gestaltPerforma600 = gestaltMacIIvm,
+ gestaltPowerMac7100_80 = 47,
+ gestaltMacIIvx = 48,
+ gestaltMacColorClassic = 49,
+ gestaltPerforma250 = gestaltMacColorClassic,
+ gestaltPowerBook165c = 50,
+ gestaltMacCentris610 = 52,
+ gestaltMacQuadra610 = 53,
+ gestaltPowerBook145 = 54,
+ gestaltPowerMac8100_100 = 55,
+ gestaltMacLC520 = 56,
+ gestaltAWS9150_120 = 57,
+ gestaltPowerMac6400 = 58,
+ gestaltPerforma6400 = gestaltPowerMac6400,
+ gestaltPerforma6360 = gestaltPerforma6400,
+ gestaltMacCentris660AV = 60,
+ gestaltMacQuadra660AV = gestaltMacCentris660AV,
+ gestaltPerforma46x = 62,
+ gestaltPowerMac8100_80 = 65,
+ gestaltAWS8150_80 = gestaltPowerMac8100_80,
+ gestaltPowerMac9500 = 67,
+ gestaltPowerMac9600 = gestaltPowerMac9500,
+ gestaltPowerMac7500 = 68,
+ gestaltPowerMac7600 = gestaltPowerMac7500,
+ gestaltPowerMac8500 = 69,
+ gestaltPowerMac8600 = gestaltPowerMac8500,
+ gestaltAWS8550 = gestaltPowerMac7500,
+ gestaltPowerBook180c = 71,
+ gestaltPowerBook520 = 72,
+ gestaltPowerBook520c = gestaltPowerBook520,
+ gestaltPowerBook540 = gestaltPowerBook520,
+ gestaltPowerBook540c = gestaltPowerBook520,
+ gestaltPowerMac5400 = 74,
+ gestaltPowerMac6100_60 = 75,
+ gestaltAWS6150_60 = gestaltPowerMac6100_60,
+ gestaltPowerBookDuo270c = 77,
+ gestaltMacQuadra840AV = 78,
+ gestaltPerforma550 = 80,
+ gestaltPowerBook165 = 84,
+ gestaltPowerBook190 = 85,
+ gestaltMacTV = 88,
+ gestaltMacLC475 = 89,
+ gestaltPerforma47x = gestaltMacLC475,
+ gestaltMacLC575 = 92,
+ gestaltMacQuadra605 = 94,
+ gestaltMacQuadra630 = 98,
+ gestaltMacLC580 = 99,
+ gestaltPerforma580 = gestaltMacLC580,
+ gestaltPowerMac6100_66 = 100,
+ gestaltAWS6150_66 = gestaltPowerMac6100_66,
+ gestaltPowerBookDuo280 = 102,
+ gestaltPowerBookDuo280c = 103,
+ gestaltPowerMacLC475 = 104,
+ gestaltPowerMacPerforma47x = gestaltPowerMacLC475,
+ gestaltPowerMacLC575 = 105,
+ gestaltPowerMacPerforma57x = gestaltPowerMacLC575,
+ gestaltPowerMacQuadra630 = 106,
+ gestaltPowerMacLC630 = gestaltPowerMacQuadra630,
+ gestaltPowerMacPerforma63x = gestaltPowerMacQuadra630,
+ gestaltPowerMac7200 = 108,
+ gestaltPowerMac7300 = 109,
+ gestaltPowerMac7100_66 = 112,
+ gestaltPowerBook150 = 115,
+ gestaltPowerMacQuadra700 = 116,
+ gestaltPowerMacQuadra900 = 117,
+ gestaltPowerMacQuadra950 = 118,
+ gestaltPowerMacCentris610 = 119,
+ gestaltPowerMacCentris650 = 120,
+ gestaltPowerMacQuadra610 = 121,
+ gestaltPowerMacQuadra650 = 122,
+ gestaltPowerMacQuadra800 = 123,
+ gestaltPowerBookDuo2300 = 124,
+ gestaltPowerBook500PPCUpgrade = 126,
+ gestaltPowerBook5300 = 128,
+ gestaltPowerBook1400 = 310,
+ gestaltPowerBook3400 = 306,
+ gestaltPowerBook2400 = 307,
+ gestaltPowerBookG3Series = 312,
+ gestaltPowerBookG3 = 313,
+ gestaltPowerBookG3Series2 = 314,
+ gestaltPowerMacNewWorld = 406,
+ gestaltPowerMacG3 = 510,
+ gestaltPowerMac5500 = 512,
+ gestalt20thAnniversary = gestaltPowerMac5500,
+ gestaltPowerMac6500 = 513,
+ gestaltPowerMac4400_160 = 514,
+ gestaltPowerMac4400 = 515,
+ gestaltMacOSCompatibility = 1206
+};
+
+
+enum {
+ gestaltQuadra605 = gestaltMacQuadra605,
+ gestaltQuadra610 = gestaltMacQuadra610,
+ gestaltQuadra630 = gestaltMacQuadra630,
+ gestaltQuadra650 = gestaltMacQuadra650,
+ gestaltQuadra660AV = gestaltMacQuadra660AV,
+ gestaltQuadra700 = gestaltMacQuadra700,
+ gestaltQuadra800 = gestaltMacQuadra800,
+ gestaltQuadra840AV = gestaltMacQuadra840AV,
+ gestaltQuadra900 = gestaltMacQuadra900,
+ gestaltQuadra950 = gestaltMacQuadra950
+};
+
+enum {
+ kMachineNameStrID = -16395
+};
+
+enum {
+ gestaltSMPMailerVersion = 'malr'
+};
+
+enum {
+ gestaltMediaBay = 'mbeh',
+ gestaltMBLegacy = 0,
+ gestaltMBSingleBay = 1,
+ gestaltMBMultipleBays = 2
+};
+
+enum {
+ gestaltMessageMgrVersion = 'mess'
+};
+
+
+
+enum {
+ gestaltMenuMgrAttr = 'menu',
+ gestaltMenuMgrPresent = (1L << 0),
+
+
+ gestaltMenuMgrPresentBit = 0,
+ gestaltMenuMgrAquaLayoutBit = 1,
+ gestaltMenuMgrMultipleItemsWithCommandIDBit = 2,
+ gestaltMenuMgrRetainsIconRefBit = 3,
+ gestaltMenuMgrSendsMenuBoundsToDefProcBit = 4,
+ gestaltMenuMgrMoreThanFiveMenusDeepBit = 5,
+
+ gestaltMenuMgrPresentMask = (1L << gestaltMenuMgrPresentBit),
+ gestaltMenuMgrAquaLayoutMask = (1L << gestaltMenuMgrAquaLayoutBit),
+ gestaltMenuMgrMultipleItemsWithCommandIDMask = (1L << gestaltMenuMgrMultipleItemsWithCommandIDBit),
+ gestaltMenuMgrRetainsIconRefMask = (1L << gestaltMenuMgrRetainsIconRefBit),
+ gestaltMenuMgrSendsMenuBoundsToDefProcMask = (1L << gestaltMenuMgrSendsMenuBoundsToDefProcBit),
+ gestaltMenuMgrMoreThanFiveMenusDeepMask = (1L << gestaltMenuMgrMoreThanFiveMenusDeepBit)
+};
+
+
+enum {
+ gestaltMultipleUsersState = 'mfdr'
+};
+
+
+enum {
+ gestaltMachineIcon = 'micn'
+};
+
+enum {
+ gestaltMiscAttr = 'misc',
+ gestaltScrollingThrottle = 0,
+ gestaltSquareMenuBar = 2
+};
+enum {
+ gestaltMixedModeVersion = 'mixd'
+};
+
+enum {
+ gestaltMixedModeAttr = 'mixd',
+ gestaltMixedModePowerPC = 0,
+ gestaltPowerPCAware = 0,
+ gestaltMixedModeCFM68K = 1,
+ gestaltMixedModeCFM68KHasTrap = 2,
+ gestaltMixedModeCFM68KHasState = 3
+};
+
+enum {
+ gestaltQuickTimeConferencing = 'mtlk'
+};
+
+enum {
+ gestaltMemoryMapAttr = 'mmap',
+ gestaltMemoryMapSparse = 0
+};
+
+enum {
+ gestaltMMUType = 'mmu ',
+ gestaltNoMMU = 0,
+ gestaltAMU = 1,
+ gestalt68851 = 2,
+ gestalt68030MMU = 3,
+ gestalt68040MMU = 4,
+ gestaltEMMU1 = 5
+};
+
+enum {
+ gestaltUserVisibleMachineName = 'mnam'
+};
+
+enum {
+ gestaltMPCallableAPIsAttr = 'mpsc',
+ gestaltMPFileManager = 0,
+ gestaltMPDeviceManager = 1,
+ gestaltMPTrapCalls = 2
+};
+
+enum {
+ gestaltStdNBPAttr = 'nlup',
+ gestaltStdNBPPresent = 0,
+ gestaltStdNBPSupportsAutoPosition = 1
+};
+
+enum {
+ gestaltNotificationMgrAttr = 'nmgr',
+ gestaltNotificationPresent = 0
+};
+
+enum {
+ gestaltNameRegistryVersion = 'nreg'
+};
+
+enum {
+ gestaltNuBusSlotCount = 'nubs'
+};
+
+enum {
+ gestaltOCEToolboxVersion = 'ocet',
+ gestaltOCETB = 0x0102,
+ gestaltSFServer = 0x0100
+};
+
+enum {
+ gestaltOCEToolboxAttr = 'oceu',
+ gestaltOCETBPresent = 0x01,
+ gestaltOCETBAvailable = 0x02,
+ gestaltOCESFServerAvailable = 0x04,
+ gestaltOCETBNativeGlueAvailable = 0x10
+};
+
+enum {
+ gestaltOpenFirmwareInfo = 'opfw'
+};
+
+enum {
+ gestaltOSAttr = 'os ',
+ gestaltSysZoneGrowable = 0,
+ gestaltLaunchCanReturn = 1,
+ gestaltLaunchFullFileSpec = 2,
+ gestaltLaunchControl = 3,
+ gestaltTempMemSupport = 4,
+ gestaltRealTempMemory = 5,
+ gestaltTempMemTracked = 6,
+ gestaltIPCSupport = 7,
+ gestaltSysDebuggerSupport = 8,
+ gestaltNativeProcessMgrBit = 19,
+ gestaltAltivecRegistersSwappedCorrectlyBit = 20
+};
+
+enum {
+ gestaltOSTable = 'ostt'
+};
+enum {
+ gestaltOpenTptNetworkSetup = 'otcf',
+ gestaltOpenTptNetworkSetupLegacyImport = 0,
+ gestaltOpenTptNetworkSetupLegacyExport = 1,
+ gestaltOpenTptNetworkSetupSupportsMultihoming = 2
+};
+
+enum {
+ gestaltOpenTptNetworkSetupVersion = 'otcv'
+};
+
+
+
+
+
+
+
+enum {
+ gestaltOpenTptRemoteAccess = 'otra',
+ gestaltOpenTptRemoteAccessPresent = 0,
+ gestaltOpenTptRemoteAccessLoaded = 1,
+ gestaltOpenTptRemoteAccessClientOnly = 2,
+ gestaltOpenTptRemoteAccessPServer = 3,
+ gestaltOpenTptRemoteAccessMPServer = 4,
+ gestaltOpenTptPPPPresent = 5,
+ gestaltOpenTptARAPPresent = 6
+};
+
+enum {
+ gestaltOpenTptRemoteAccessVersion = 'otrv'
+};
+
+
+
+
+
+enum {
+ gestaltOpenTptVersions = 'otvr'
+};
+
+enum {
+ gestaltOpenTpt = 'otan',
+ gestaltOpenTptPresentMask = 0x00000001,
+ gestaltOpenTptLoadedMask = 0x00000002,
+ gestaltOpenTptAppleTalkPresentMask = 0x00000004,
+ gestaltOpenTptAppleTalkLoadedMask = 0x00000008,
+ gestaltOpenTptTCPPresentMask = 0x00000010,
+ gestaltOpenTptTCPLoadedMask = 0x00000020,
+ gestaltOpenTptIPXSPXPresentMask = 0x00000040,
+ gestaltOpenTptIPXSPXLoadedMask = 0x00000080,
+ gestaltOpenTptPresentBit = 0,
+ gestaltOpenTptLoadedBit = 1,
+ gestaltOpenTptAppleTalkPresentBit = 2,
+ gestaltOpenTptAppleTalkLoadedBit = 3,
+ gestaltOpenTptTCPPresentBit = 4,
+ gestaltOpenTptTCPLoadedBit = 5,
+ gestaltOpenTptIPXSPXPresentBit = 6,
+ gestaltOpenTptIPXSPXLoadedBit = 7
+};
+
+
+enum {
+ gestaltPCCard = 'pccd',
+ gestaltCardServicesPresent = 0,
+ gestaltPCCardFamilyPresent = 1,
+ gestaltPCCardHasPowerControl = 2,
+ gestaltPCCardSupportsCardBus = 3
+};
+
+enum {
+ gestaltProcClkSpeed = 'pclk'
+};
+
+enum {
+ gestaltPCXAttr = 'pcxg',
+ gestaltPCXHas8and16BitFAT = 0,
+ gestaltPCXHasProDOS = 1,
+ gestaltPCXNewUI = 2,
+ gestaltPCXUseICMapping = 3
+};
+
+enum {
+ gestaltLogicalPageSize = 'pgsz'
+};
+enum {
+ gestaltScreenCaptureMain = 'pic1',
+ gestaltScreenCaptureDir = 'pic2'
+};
+
+enum {
+ gestaltGXPrintingMgrVersion = 'pmgr'
+};
+
+enum {
+ gestaltPopupAttr = 'pop!',
+ gestaltPopupPresent = 0
+};
+
+enum {
+ gestaltPowerMgrAttr = 'powr',
+ gestaltPMgrExists = 0,
+ gestaltPMgrCPUIdle = 1,
+ gestaltPMgrSCC = 2,
+ gestaltPMgrSound = 3,
+ gestaltPMgrDispatchExists = 4,
+ gestaltPMgrSupportsAVPowerStateAtSleepWake = 5
+};
+
+enum {
+ gestaltPowerMgrVers = 'pwrv'
+};
+
+
+
+
+
+
+
+enum {
+ gestaltPPCToolboxAttr = 'ppc ',
+ gestaltPPCToolboxPresent = 0x0000,
+ gestaltPPCSupportsRealTime = 0x1000,
+ gestaltPPCSupportsIncoming = 0x0001,
+ gestaltPPCSupportsOutGoing = 0x0002,
+ gestaltPPCSupportsTCP_IP = 0x0004,
+ gestaltPPCSupportsIncomingAppleTalk = 0x0010,
+ gestaltPPCSupportsIncomingTCP_IP = 0x0020,
+ gestaltPPCSupportsOutgoingAppleTalk = 0x0100,
+ gestaltPPCSupportsOutgoingTCP_IP = 0x0200
+};
+
+enum {
+ gestaltPowerPCProcessorFeatures = 'ppcf',
+ gestaltPowerPCHasGraphicsInstructions = 0,
+ gestaltPowerPCHasSTFIWXInstruction = 1,
+ gestaltPowerPCHasSquareRootInstructions = 2,
+ gestaltPowerPCHasDCBAInstruction = 3,
+ gestaltPowerPCHasVectorInstructions = 4,
+ gestaltPowerPCHasDataStreams = 5
+};
+
+enum {
+ gestaltProcessorType = 'proc',
+ gestalt68000 = 1,
+ gestalt68010 = 2,
+ gestalt68020 = 3,
+ gestalt68030 = 4,
+ gestalt68040 = 5
+};
+
+enum {
+ gestaltSDPPromptVersion = 'prpv'
+};
+
+enum {
+ gestaltParityAttr = 'prty',
+ gestaltHasParityCapability = 0,
+ gestaltParityEnabled = 1
+};
+
+enum {
+ gestaltQD3DVersion = 'q3v '
+};
+
+enum {
+ gestaltQD3DViewer = 'q3vc',
+ gestaltQD3DViewerPresent = 0
+};
+enum {
+ gestaltQuickdrawVersion = 'qd ',
+ gestaltOriginalQD = 0x0000,
+ gestalt8BitQD = 0x0100,
+ gestalt32BitQD = 0x0200,
+ gestalt32BitQD11 = 0x0201,
+ gestalt32BitQD12 = 0x0220,
+ gestalt32BitQD13 = 0x0230,
+ gestaltAllegroQD = 0x0250,
+ gestaltMacOSXQD = 0x0300
+};
+
+enum {
+ gestaltQD3D = 'qd3d',
+ gestaltQD3DPresent = 0
+};
+enum {
+ gestaltGXVersion = 'qdgx'
+};
+
+enum {
+ gestaltQuickdrawFeatures = 'qdrw',
+ gestaltHasColor = 0,
+ gestaltHasDeepGWorlds = 1,
+ gestaltHasDirectPixMaps = 2,
+ gestaltHasGrayishTextOr = 3,
+ gestaltSupportsMirroring = 4,
+ gestaltQDHasLongRowBytes = 5
+};
+
+enum {
+ gestaltQDTextVersion = 'qdtx',
+ gestaltOriginalQDText = 0x0000,
+ gestaltAllegroQDText = 0x0100,
+ gestaltMacOSXQDText = 0x0200
+};
+
+enum {
+ gestaltQDTextFeatures = 'qdtf',
+ gestaltWSIISupport = 0,
+ gestaltSbitFontSupport = 1,
+ gestaltAntiAliasedTextAvailable = 2,
+ gestaltOFA2available = 3,
+ gestaltCreatesAliasFontRsrc = 4,
+ gestaltNativeType1FontSupport = 5,
+ gestaltCanUseCGTextRendering = 6
+};
+
+
+enum {
+ gestaltQuickTimeConferencingInfo = 'qtci'
+};
+
+enum {
+ gestaltQuickTimeVersion = 'qtim',
+ gestaltQuickTime = 'qtim'
+};
+
+enum {
+ gestaltQuickTimeFeatures = 'qtrs',
+ gestaltPPCQuickTimeLibPresent = 0
+};
+
+enum {
+ gestaltQuickTimeStreamingFeatures = 'qtsf'
+};
+
+enum {
+ gestaltQuickTimeStreamingVersion = 'qtst'
+};
+
+enum {
+ gestaltQTVRMgrAttr = 'qtvr',
+ gestaltQTVRMgrPresent = 0,
+ gestaltQTVRObjMoviesPresent = 1,
+ gestaltQTVRCylinderPanosPresent = 2,
+ gestaltQTVRCubicPanosPresent = 3
+};
+
+enum {
+ gestaltQTVRMgrVers = 'qtvv'
+};
+
+enum {
+ gestaltPhysicalRAMSize = 'ram '
+};
+
+enum {
+ gestaltRBVAddr = 'rbv '
+};
+
+enum {
+ gestaltROMSize = 'rom '
+};
+
+enum {
+ gestaltROMVersion = 'romv'
+};
+
+enum {
+ gestaltResourceMgrAttr = 'rsrc',
+ gestaltPartialRsrcs = 0,
+ gestaltHasResourceOverrides = 1
+};
+
+enum {
+ gestaltResourceMgrBugFixesAttrs = 'rmbg',
+ gestaltRMForceSysHeapRolledIn = 0,
+ gestaltRMFakeAppleMenuItemsRolledIn = 1,
+ gestaltSanityCheckResourceFiles = 2,
+ gestaltSupportsFSpResourceFileAlreadyOpenBit = 3,
+ gestaltRMSupportsFSCalls = 4,
+ gestaltRMTypeIndexOrderingReverse = 8
+};
+
+
+enum {
+ gestaltRealtimeMgrAttr = 'rtmr',
+ gestaltRealtimeMgrPresent = 0
+};
+
+
+enum {
+ gestaltSafeOFAttr = 'safe',
+ gestaltVMZerosPagesBit = 0,
+ gestaltInitHeapZerosOutHeapsBit = 1,
+ gestaltNewHandleReturnsZeroedMemoryBit = 2,
+ gestaltNewPtrReturnsZeroedMemoryBit = 3,
+ gestaltFileAllocationZeroedBlocksBit = 4
+};
+
+
+enum {
+ gestaltSCCReadAddr = 'sccr'
+};
+
+enum {
+ gestaltSCCWriteAddr = 'sccw'
+};
+
+enum {
+ gestaltScrapMgrAttr = 'scra',
+ gestaltScrapMgrTranslationAware = 0
+};
+
+enum {
+ gestaltScriptMgrVersion = 'scri'
+};
+
+enum {
+ gestaltScriptCount = 'scr#'
+};
+
+enum {
+ gestaltSCSI = 'scsi',
+ gestaltAsyncSCSI = 0,
+ gestaltAsyncSCSIINROM = 1,
+ gestaltSCSISlotBoot = 2,
+ gestaltSCSIPollSIH = 3
+};
+
+enum {
+ gestaltControlStripAttr = 'sdev',
+ gestaltControlStripExists = 0,
+ gestaltControlStripVersionFixed = 1,
+ gestaltControlStripUserFont = 2,
+ gestaltControlStripUserHotKey = 3
+};
+
+enum {
+ gestaltSDPStandardDirectoryVersion = 'sdvr'
+};
+
+enum {
+ gestaltSerialAttr = 'ser ',
+ gestaltHasGPIaToDCDa = 0,
+ gestaltHasGPIaToRTxCa = 1,
+ gestaltHasGPIbToDCDb = 2,
+ gestaltHidePortA = 3,
+ gestaltHidePortB = 4,
+ gestaltPortADisabled = 5,
+ gestaltPortBDisabled = 6
+};
+
+enum {
+ gestaltShutdownAttributes = 'shut',
+ gestaltShutdownHassdOnBootVolUnmount = 0
+};
+
+enum {
+ gestaltNuBusConnectors = 'sltc'
+};
+
+enum {
+ gestaltSlotAttr = 'slot',
+ gestaltSlotMgrExists = 0,
+ gestaltNuBusPresent = 1,
+ gestaltSESlotPresent = 2,
+ gestaltSE30SlotPresent = 3,
+ gestaltPortableSlotPresent = 4
+};
+
+enum {
+ gestaltFirstSlotNumber = 'slt1'
+};
+
+enum {
+ gestaltSoundAttr = 'snd ',
+ gestaltStereoCapability = 0,
+ gestaltStereoMixing = 1,
+ gestaltSoundIOMgrPresent = 3,
+ gestaltBuiltInSoundInput = 4,
+ gestaltHasSoundInputDevice = 5,
+ gestaltPlayAndRecord = 6,
+ gestalt16BitSoundIO = 7,
+ gestaltStereoInput = 8,
+ gestaltLineLevelInput = 9,
+
+ gestaltSndPlayDoubleBuffer = 10,
+ gestaltMultiChannels = 11,
+ gestalt16BitAudioSupport = 12
+};
+
+enum {
+ gestaltSplitOSAttr = 'spos',
+ gestaltSplitOSBootDriveIsNetworkVolume = 0,
+ gestaltSplitOSAware = 1,
+ gestaltSplitOSEnablerVolumeIsDifferentFromBootVolume = 2,
+ gestaltSplitOSMachineNameSetToNetworkNameTemp = 3,
+ gestaltSplitOSMachineNameStartupDiskIsNonPersistent = 5
+};
+
+enum {
+ gestaltSMPSPSendLetterVersion = 'spsl'
+};
+
+enum {
+ gestaltSpeechRecognitionAttr = 'srta',
+ gestaltDesktopSpeechRecognition = 1,
+ gestaltTelephoneSpeechRecognition = 2
+};
+
+enum {
+ gestaltSpeechRecognitionVersion = 'srtb'
+};
+
+enum {
+ gestaltSoftwareVendorCode = 'srad',
+ gestaltSoftwareVendorApple = 'Appl',
+ gestaltSoftwareVendorLicensee = 'Lcns'
+};
+
+enum {
+ gestaltStandardFileAttr = 'stdf',
+ gestaltStandardFile58 = 0,
+ gestaltStandardFileTranslationAware = 1,
+ gestaltStandardFileHasColorIcons = 2,
+ gestaltStandardFileUseGenericIcons = 3,
+ gestaltStandardFileHasDynamicVolumeAllocation = 4
+};
+
+enum {
+ gestaltSysArchitecture = 'sysa',
+ gestalt68k = 1,
+ gestaltPowerPC = 2
+};
+
+enum {
+ gestaltIntel = 10
+};
+
+enum {
+ gestaltSystemUpdateVersion = 'sysu'
+};
+
+enum {
+ gestaltSystemVersion = 'sysv'
+};
+
+enum {
+ gestaltToolboxTable = 'tbtt'
+};
+
+enum {
+ gestaltTextEditVersion = 'te ',
+ gestaltTE1 = 1,
+ gestaltTE2 = 2,
+ gestaltTE3 = 3,
+ gestaltTE4 = 4,
+ gestaltTE5 = 5
+};
+
+enum {
+ gestaltTE6 = 6
+};
+
+enum {
+ gestaltTEAttr = 'teat',
+ gestaltTEHasGetHiliteRgn = 0,
+ gestaltTESupportsInlineInput = 1,
+ gestaltTESupportsTextObjects = 2,
+ gestaltTEHasWhiteBackground = 3
+};
+
+enum {
+ gestaltTeleMgrAttr = 'tele',
+ gestaltTeleMgrPresent = 0,
+ gestaltTeleMgrPowerPCSupport = 1,
+ gestaltTeleMgrSoundStreams = 2,
+ gestaltTeleMgrAutoAnswer = 3,
+ gestaltTeleMgrIndHandset = 4,
+ gestaltTeleMgrSilenceDetect = 5,
+ gestaltTeleMgrNewTELNewSupport = 6
+};
+
+enum {
+ gestaltTermMgrAttr = 'term',
+ gestaltTermMgrPresent = 0,
+ gestaltTermMgrErrorString = 2
+};
+
+enum {
+ gestaltThreadMgrAttr = 'thds',
+ gestaltThreadMgrPresent = 0,
+ gestaltSpecificMatchSupport = 1,
+ gestaltThreadsLibraryPresent = 2
+};
+
+enum {
+ gestaltTimeMgrVersion = 'tmgr',
+ gestaltStandardTimeMgr = 1,
+ gestaltRevisedTimeMgr = 2,
+ gestaltExtendedTimeMgr = 3,
+ gestaltNativeTimeMgr = 4
+};
+
+enum {
+ gestaltTSMTEVersion = 'tmTV',
+ gestaltTSMTE1 = 0x0100,
+ gestaltTSMTE15 = 0x0150,
+ gestaltTSMTE152 = 0x0152
+};
+
+enum {
+ gestaltTSMTEAttr = 'tmTE',
+ gestaltTSMTEPresent = 0,
+ gestaltTSMTE = 0
+};
+
+enum {
+ gestaltAVLTreeAttr = 'tree',
+ gestaltAVLTreePresentBit = 0,
+ gestaltAVLTreeSupportsHandleBasedTreeBit = 1,
+ gestaltAVLTreeSupportsTreeLockingBit = 2
+};
+
+enum {
+ gestaltALMAttr = 'trip',
+ gestaltALMPresent = 0,
+ gestaltALMHasSFGroup = 1,
+ gestaltALMHasCFMSupport = 2,
+ gestaltALMHasRescanNotifiers = 3
+};
+
+enum {
+ gestaltALMHasSFLocation = gestaltALMHasSFGroup
+};
+
+enum {
+ gestaltTSMgrVersion = 'tsmv',
+ gestaltTSMgr15 = 0x0150,
+ gestaltTSMgr20 = 0x0200
+};
+
+enum {
+ gestaltTSMgrAttr = 'tsma',
+ gestaltTSMDisplayMgrAwareBit = 0,
+ gestaltTSMdoesTSMTEBit = 1
+};
+
+enum {
+ gestaltSpeechAttr = 'ttsc',
+ gestaltSpeechMgrPresent = 0,
+ gestaltSpeechHasPPCGlue = 1
+};
+
+enum {
+ gestaltTVAttr = 'tv ',
+ gestaltHasTVTuner = 0,
+ gestaltHasSoundFader = 1,
+ gestaltHasHWClosedCaptioning = 2,
+ gestaltHasIRRemote = 3,
+ gestaltHasVidDecoderScaler = 4,
+ gestaltHasStereoDecoder = 5,
+ gestaltHasSerialFader = 6,
+ gestaltHasFMTuner = 7,
+ gestaltHasSystemIRFunction = 8,
+ gestaltIRDisabled = 9,
+ gestaltINeedIRPowerOffConfirm = 10,
+ gestaltHasZoomedVideo = 11
+};
+
+
+enum {
+ gestaltATSUVersion = 'uisv',
+ gestaltOriginalATSUVersion = (1 << 16),
+ gestaltATSUUpdate1 = (2 << 16),
+ gestaltATSUUpdate2 = (3 << 16),
+ gestaltATSUUpdate3 = (4 << 16),
+ gestaltATSUUpdate4 = (5 << 16),
+ gestaltATSUUpdate5 = (6 << 16),
+ gestaltATSUUpdate6 = (7 << 16)
+};
+
+enum {
+ gestaltATSUFeatures = 'uisf',
+ gestaltATSUTrackingFeature = 0x00000001,
+ gestaltATSUMemoryFeature = 0x00000001,
+ gestaltATSUFallbacksFeature = 0x00000001,
+ gestaltATSUGlyphBoundsFeature = 0x00000001,
+ gestaltATSULineControlFeature = 0x00000001,
+ gestaltATSULayoutCreateAndCopyFeature = 0x00000001,
+ gestaltATSULayoutCacheClearFeature = 0x00000001,
+ gestaltATSUTextLocatorUsageFeature = 0x00000002,
+ gestaltATSULowLevelOrigFeatures = 0x00000004,
+ gestaltATSUFallbacksObjFeatures = 0x00000008,
+ gestaltATSUIgnoreLeadingFeature = 0x00000008,
+ gestaltATSUByCharacterClusterFeature = 0x00000010,
+ gestaltATSUAscentDescentControlsFeature = 0x00000010,
+ gestaltATSUHighlightInactiveTextFeature = 0x00000010,
+ gestaltATSUPositionToCursorFeature = 0x00000010,
+ gestaltATSUBatchBreakLinesFeature = 0x00000010,
+ gestaltATSUTabSupportFeature = 0x00000010,
+ gestaltATSUDirectAccess = 0x00000010
+};
+
+enum {
+ gestaltUSBAttr = 'usb ',
+ gestaltUSBPresent = 0,
+ gestaltUSBHasIsoch = 1
+};
+
+enum {
+ gestaltUSBVersion = 'usbv'
+};
+
+enum {
+ gestaltVersion = 'vers',
+ gestaltValueImplementedVers = 5
+};
+
+enum {
+ gestaltVIA1Addr = 'via1'
+};
+
+enum {
+ gestaltVIA2Addr = 'via2'
+};
+
+enum {
+ gestaltVMAttr = 'vm ',
+ gestaltVMPresent = 0,
+ gestaltVMHasLockMemoryForOutput = 1,
+ gestaltVMFilemappingOn = 3,
+ gestaltVMHasPagingControl = 4
+};
+
+enum {
+ gestaltVMInfoType = 'vmin',
+
+ gestaltVMInfoSizeStorageType = 0,
+ gestaltVMInfoSizeType = 1,
+ gestaltVMInfoSimpleType = 2,
+ gestaltVMInfoNoneType = 3
+};
+
+enum {
+ gestaltVMBackingStoreFileRefNum = 'vmbs'
+};
+
+
+
+enum {
+ gestaltALMVers = 'walk'
+};
+
+enum {
+ gestaltWindowMgrAttr = 'wind',
+ gestaltWindowMgrPresent = (1L << 0),
+
+
+ gestaltWindowMgrPresentBit = 0,
+ gestaltExtendedWindowAttributes = 1,
+ gestaltExtendedWindowAttributesBit = 1,
+ gestaltHasFloatingWindows = 2,
+ gestaltHasFloatingWindowsBit = 2,
+ gestaltHasWindowBuffering = 3,
+ gestaltHasWindowBufferingBit = 3,
+ gestaltWindowLiveResizeBit = 4,
+ gestaltWindowMinimizeToDockBit = 5,
+ gestaltHasWindowShadowsBit = 6,
+ gestaltSheetsAreWindowModalBit = 7,
+ gestaltFrontWindowMayBeHiddenBit = 8,
+
+ gestaltWindowMgrPresentMask = (1L << gestaltWindowMgrPresentBit),
+ gestaltExtendedWindowAttributesMask = (1L << gestaltExtendedWindowAttributesBit),
+ gestaltHasFloatingWindowsMask = (1L << gestaltHasFloatingWindowsBit),
+ gestaltHasWindowBufferingMask = (1L << gestaltHasWindowBufferingBit),
+ gestaltWindowLiveResizeMask = (1L << gestaltWindowLiveResizeBit),
+ gestaltWindowMinimizeToDockMask = (1L << gestaltWindowMinimizeToDockBit),
+ gestaltHasWindowShadowsMask = (1L << gestaltHasWindowShadowsBit),
+ gestaltSheetsAreWindowModalMask = (1L << gestaltSheetsAreWindowModalBit),
+ gestaltFrontWindowMayBeHiddenMask = (1L << gestaltFrontWindowMayBeHiddenBit)
+};
+
+enum {
+ gestaltHasSingleWindowModeBit = 8,
+ gestaltHasSingleWindowModeMask = (1L << gestaltHasSingleWindowModeBit)
+};
+enum {
+ gestaltTranslationAttr = 'xlat',
+ gestaltTranslationMgrExists = 0,
+ gestaltTranslationMgrHintOrder = 1,
+ gestaltTranslationPPCAvail = 2,
+ gestaltTranslationGetPathAPIAvail = 3
+};
+
+enum {
+ gestaltExtToolboxTable = 'xttt'
+};
+
+enum {
+ gestaltUSBPrinterSharingVersion = 'zak ',
+ gestaltUSBPrinterSharingVersionMask = 0x0000FFFF,
+ gestaltUSBPrinterSharingAttr = 'zak ',
+ gestaltUSBPrinterSharingAttrMask = (long)0xFFFF0000,
+ gestaltUSBPrinterSharingAttrRunning = (long)0x80000000,
+ gestaltUSBPrinterSharingAttrBooted = 0x40000000
+};
+
+
+enum {
+ gestaltWorldScriptIIVersion = 'doub',
+ gestaltWorldScriptIIAttr = 'wsat',
+ gestaltWSIICanPrintWithoutPrGeneralBit = 0
+};
+
+
+
+
+
+
+}
+
+
+
+extern "C" {
+
+
+
+enum {
+ maxSize = 0x7FFFFFF0
+};
+
+enum {
+ defaultPhysicalEntryCount = 8
+};
+
+enum {
+
+ kPageInMemory = 0,
+ kPageOnDisk = 1,
+ kNotPaged = 2
+};
+
+enum {
+
+ k32BitHeap = 1,
+ kNewStyleHeap = 2,
+ kNewDebugHeap = 4
+};
+
+
+
+enum {
+ kHandleIsResourceBit = 5,
+ kHandlePurgeableBit = 6,
+ kHandleLockedBit = 7
+};
+
+
+enum {
+ kHandleIsResourceMask = 0x20,
+ kHandlePurgeableMask = 0x40,
+ kHandleLockedMask = 0x80
+};
+
+
+typedef long ( * GrowZoneProcPtr)(Size cbNeeded);
+typedef void ( * PurgeProcPtr)(Handle blockToPurge);
+typedef void ( * UserFnProcPtr)(void * parameter);
+typedef GrowZoneProcPtr GrowZoneUPP;
+typedef PurgeProcPtr PurgeUPP;
+typedef UserFnProcPtr UserFnUPP;
+struct Zone {
+ Ptr bkLim;
+ Ptr purgePtr;
+ Ptr hFstFree;
+ long zcbFree;
+ GrowZoneUPP gzProc;
+ short moreMast;
+ short flags;
+ short cntRel;
+ short maxRel;
+ short cntNRel;
+ SInt8 heapType;
+ SInt8 unused;
+ short cntEmpty;
+ short cntHandles;
+ long minCBFree;
+ PurgeUPP purgeProc;
+ Ptr sparePtr;
+ Ptr allocPtr;
+ short heapData;
+};
+typedef struct Zone Zone;
+typedef Zone * THz;
+typedef THz * THzPtr;
+struct MemoryBlock {
+ void * address;
+ unsigned long count;
+};
+typedef struct MemoryBlock MemoryBlock;
+struct LogicalToPhysicalTable {
+ MemoryBlock logical;
+ MemoryBlock physical[8];
+};
+typedef struct LogicalToPhysicalTable LogicalToPhysicalTable;
+
+typedef short PageState;
+typedef short StatusRegisterContents;
+enum {
+ kVolumeVirtualMemoryInfoVersion1 = 1
+};
+
+struct VolumeVirtualMemoryInfo {
+ PBVersion version;
+ SInt16 volumeRefNum;
+ Boolean inUse;
+ UInt8 _fill;
+ UInt32 vmOptions;
+
+};
+typedef struct VolumeVirtualMemoryInfo VolumeVirtualMemoryInfo;
+typedef VolumeVirtualMemoryInfo * VolumeVirtualMemoryInfoPtr;
+extern GrowZoneUPP
+NewGrowZoneUPP(GrowZoneProcPtr userRoutine) ;
+extern PurgeUPP
+NewPurgeUPP(PurgeProcPtr userRoutine) ;
+extern UserFnUPP
+NewUserFnUPP(UserFnProcPtr userRoutine) ;
+extern void
+DisposeGrowZoneUPP(GrowZoneUPP userUPP) ;
+extern void
+DisposePurgeUPP(PurgeUPP userUPP) ;
+extern void
+DisposeUserFnUPP(UserFnUPP userUPP) ;
+extern long
+InvokeGrowZoneUPP(
+ Size cbNeeded,
+ GrowZoneUPP userUPP) ;
+extern void
+InvokePurgeUPP(
+ Handle blockToPurge,
+ PurgeUPP userUPP) ;
+extern void
+InvokeUserFnUPP(
+ void * parameter,
+ UserFnUPP userUPP) ;
+extern Handle
+GZSaveHnd(void) ;
+extern Ptr
+TopMem(void) ;
+extern OSErr
+MemError(void) ;
+extern Handle
+NewHandle(Size byteCount) ;
+extern Handle
+NewHandleClear(Size byteCount) ;
+extern Handle
+RecoverHandle(Ptr p) ;
+extern Ptr
+NewPtr(Size byteCount) ;
+extern Ptr
+NewPtrClear(Size byteCount) ;
+extern long
+MaxBlock(void) ;
+extern long
+StackSpace(void) ;
+extern Handle
+NewEmptyHandle(void) ;
+extern void
+HLock(Handle h) ;
+extern void
+HUnlock(Handle h) ;
+extern void
+HPurge(Handle h) ;
+extern void
+HNoPurge(Handle h) ;
+extern void
+HLockHi(Handle h) ;
+extern Handle
+TempNewHandle(
+ Size logicalSize,
+ OSErr * resultCode) ;
+extern Size
+TempMaxMem(Size * grow) ;
+extern long
+TempFreeMem(void) ;
+extern Size
+CompactMem(Size cbNeeded) ;
+extern void
+PurgeMem(Size cbNeeded) ;
+extern long
+FreeMem(void) ;
+extern void
+ReserveMem(Size cbNeeded) ;
+extern Size
+MaxMem(Size * grow) ;
+extern void
+SetGrowZone(GrowZoneUPP growZone) ;
+extern GrowZoneUPP
+GetGrowZone(void) ;
+extern void
+MoveHHi(Handle h) ;
+extern void
+DisposePtr(Ptr p) ;
+extern Size
+GetPtrSize(Ptr p) ;
+extern void
+SetPtrSize(
+ Ptr p,
+ Size newSize) ;
+extern void
+DisposeHandle(Handle h) ;
+extern void
+SetHandleSize(
+ Handle h,
+ Size newSize) ;
+extern Size
+GetHandleSize(Handle h) ;
+extern void
+ReallocateHandle(
+ Handle h,
+ Size byteCount) ;
+extern void
+EmptyHandle(Handle h) ;
+extern void
+HSetRBit(Handle h) ;
+extern void
+HClrRBit(Handle h) ;
+extern SInt8
+HGetState(Handle h) ;
+extern void
+HSetState(
+ Handle h,
+ SInt8 flags) ;
+extern void
+PurgeSpace(
+ long * total,
+ long * contig) ;
+extern long
+PurgeSpaceTotal(void) ;
+extern long
+PurgeSpaceContiguous(void) ;
+extern void
+BlockMove(
+ const void * srcPtr,
+ void * destPtr,
+ Size byteCount) ;
+extern void
+BlockMoveData(
+ const void * srcPtr,
+ void * destPtr,
+ Size byteCount) ;
+extern void
+BlockMoveUncached(
+ const void * srcPtr,
+ void * destPtr,
+ Size byteCount) ;
+extern void
+BlockMoveDataUncached(
+ const void * srcPtr,
+ void * destPtr,
+ Size byteCount) ;
+extern void
+BlockZero(
+ void * destPtr,
+ Size byteCount) ;
+extern void
+BlockZeroUncached(
+ void * destPtr,
+ Size byteCount) ;
+extern void
+MoreMasters(void) ;
+extern void
+MoreMasterPointers(UInt32 inCount) ;
+extern void
+TempHLock(
+ Handle h,
+ OSErr * resultCode) ;
+extern void
+TempHUnlock(
+ Handle h,
+ OSErr * resultCode) ;
+extern void
+TempDisposeHandle(
+ Handle h,
+ OSErr * resultCode) ;
+extern Ptr
+TempTopMem(void) ;
+extern OSErr
+HoldMemory(
+ void * address,
+ unsigned long count) ;
+extern OSErr
+UnholdMemory(
+ void * address,
+ unsigned long count) ;
+extern OSErr
+MakeMemoryResident(
+ void * address,
+ unsigned long count) ;
+extern OSErr
+ReleaseMemoryData(
+ void * address,
+ unsigned long count) ;
+extern OSErr
+MakeMemoryNonResident(
+ void * address,
+ unsigned long count) ;
+extern OSErr
+FlushMemory(
+ void * address,
+ unsigned long count) ;
+extern OSErr
+HandToHand(Handle * theHndl) ;
+extern OSErr
+PtrToXHand(
+ const void * srcPtr,
+ Handle dstHndl,
+ long size) ;
+extern OSErr
+PtrToHand(
+ const void * srcPtr,
+ Handle * dstHndl,
+ long size) ;
+extern OSErr
+HandAndHand(
+ Handle hand1,
+ Handle hand2) ;
+extern OSErr
+PtrAndHand(
+ const void * ptr1,
+ Handle hand2,
+ long size) ;
+extern Boolean
+CheckAllHeaps(void) ;
+extern Boolean
+IsHeapValid(void) ;
+extern Boolean
+IsHandleValid(Handle h) ;
+extern Boolean
+IsPointerValid(Ptr p) ;
+
+
+}
+
+
+
+extern "C" {
+extern SInt64
+S64Max(void);
+extern SInt64
+S64Min(void);
+extern SInt64
+S64Add(
+ SInt64 left,
+ SInt64 right);
+extern SInt64
+S64Subtract(
+ SInt64 left,
+ SInt64 right);
+extern SInt64
+S64Negate(SInt64 value);
+extern SInt64
+S64Multiply(
+ SInt64 left,
+ SInt64 right);
+extern SInt64
+S64Mod(
+ SInt64 dividend,
+ SInt64 divisor);
+extern SInt64
+S64Divide(
+ SInt64 dividend,
+ SInt64 divisor,
+ SInt64 * remainder);
+extern SInt64
+S64Div(
+ SInt64 dividend,
+ SInt64 divisor);
+extern SInt64
+S64Set(SInt32 value);
+extern SInt64
+S64SetU(UInt32 value);
+extern SInt32
+S32Set(SInt64 value);
+extern Boolean
+S64And(
+ SInt64 left,
+ SInt64 right);
+extern Boolean
+S64Or(
+ SInt64 left,
+ SInt64 right);
+extern Boolean
+S64Eor(
+ SInt64 left,
+ SInt64 right);
+extern Boolean
+S64Not(SInt64 value);
+extern SInt32
+S64Compare(
+ SInt64 left,
+ SInt64 right) ;
+extern SInt64
+S64BitwiseAnd(
+ SInt64 left,
+ SInt64 right);
+extern SInt64
+S64BitwiseOr(
+ SInt64 left,
+ SInt64 right);
+extern SInt64
+S64BitwiseEor(
+ SInt64 left,
+ SInt64 right);
+extern SInt64
+S64BitwiseNot(SInt64 value);
+extern SInt64
+S64ShiftRight(
+ SInt64 value,
+ UInt32 shift);
+extern SInt64
+S64ShiftLeft(
+ SInt64 value,
+ UInt32 shift);
+extern UInt64
+U64Max(void);
+extern UInt64
+U64Add(
+ UInt64 left,
+ UInt64 right);
+extern UInt64
+U64Subtract(
+ UInt64 left,
+ UInt64 right);
+extern UInt64
+U64Multiply(
+ UInt64 left,
+ UInt64 right);
+extern UInt64
+U64Mod(
+ UInt64 dividend,
+ UInt64 divisor);
+extern UInt64
+U64Divide(
+ UInt64 dividend,
+ UInt64 divisor,
+ UInt64 * remainder);
+extern UInt64
+U64Div(
+ UInt64 dividend,
+ UInt64 divisor);
+extern UInt64
+U64Set(SInt32 value);
+extern UInt64
+U64SetU(UInt32 value);
+extern UInt32
+U32SetU(UInt64 value);
+extern Boolean
+U64And(
+ UInt64 left,
+ UInt64 right);
+extern Boolean
+U64Or(
+ UInt64 left,
+ UInt64 right);
+extern Boolean
+U64Eor(
+ UInt64 left,
+ UInt64 right);
+extern Boolean
+U64Not(UInt64 value);
+extern SInt32
+U64Compare(
+ UInt64 left,
+ UInt64 right) ;
+extern UInt64
+U64BitwiseAnd(
+ UInt64 left,
+ UInt64 right);
+extern UInt64
+U64BitwiseOr(
+ UInt64 left,
+ UInt64 right);
+extern UInt64
+U64BitwiseEor(
+ UInt64 left,
+ UInt64 right);
+extern UInt64
+U64BitwiseNot(UInt64 value);
+extern UInt64
+U64ShiftRight(
+ UInt64 value,
+ UInt32 shift);
+extern UInt64
+U64ShiftLeft(
+ UInt64 value,
+ UInt32 shift);
+extern SInt64
+UInt64ToSInt64(UInt64 value);
+extern UInt64
+SInt64ToUInt64(SInt64 value);
+}
+extern "C" {
+
+
+typedef SInt16 ToggleResults;
+enum {
+
+ toggleUndefined = 0,
+ toggleOK = 1,
+ toggleBadField = 2,
+ toggleBadDelta = 3,
+ toggleBadChar = 4,
+ toggleUnknown = 5,
+ toggleBadNum = 6,
+ toggleOutOfRange = 7,
+ toggleErr3 = 7,
+ toggleErr4 = 8,
+ toggleErr5 = 9
+};
+
+enum {
+
+ smallDateBit = 31,
+ togChar12HourBit = 30,
+ togCharZCycleBit = 29,
+ togDelta12HourBit = 28,
+ genCdevRangeBit = 27,
+ validDateFields = -1,
+ maxDateField = 10
+};
+
+enum {
+ eraMask = 0x0001,
+ yearMask = 0x0002,
+ monthMask = 0x0004,
+ dayMask = 0x0008,
+ hourMask = 0x0010,
+ minuteMask = 0x0020,
+ secondMask = 0x0040,
+ dayOfWeekMask = 0x0080,
+ dayOfYearMask = 0x0100,
+ weekOfYearMask = 0x0200,
+ pmMask = 0x0400,
+ dateStdMask = 0x007F
+};
+
+typedef SInt8 LongDateField;
+enum {
+ eraField = 0,
+ yearField = 1,
+ monthField = 2,
+ dayField = 3,
+ hourField = 4,
+ minuteField = 5,
+ secondField = 6,
+ dayOfWeekField = 7,
+ dayOfYearField = 8,
+ weekOfYearField = 9,
+ pmField = 10,
+ res1Field = 11,
+ res2Field = 12,
+ res3Field = 13
+};
+
+typedef SInt8 DateForm;
+enum {
+ shortDate = 0,
+ longDate = 1,
+ abbrevDate = 2
+};
+
+enum {
+
+ fatalDateTime = 0x8000,
+ longDateFound = 1,
+ leftOverChars = 2,
+ sepNotIntlSep = 4,
+ fieldOrderNotIntl = 8,
+ extraneousStrings = 16,
+ tooManySeps = 32,
+ sepNotConsistent = 64,
+ tokenErr = 0x8100,
+ cantReadUtilities = 0x8200,
+ dateTimeNotFound = 0x8400,
+ dateTimeInvalid = 0x8800
+};
+
+typedef short StringToDateStatus;
+typedef StringToDateStatus String2DateStatus;
+struct DateCacheRecord {
+ short hidden[256];
+};
+typedef struct DateCacheRecord DateCacheRecord;
+typedef DateCacheRecord * DateCachePtr;
+struct DateTimeRec {
+ short year;
+ short month;
+ short day;
+ short hour;
+ short minute;
+ short second;
+ short dayOfWeek;
+};
+typedef struct DateTimeRec DateTimeRec;
+
+typedef SInt64 LongDateTime;
+
+union LongDateCvt {
+ SInt64 c;
+ struct {
+ UInt32 lHigh;
+ UInt32 lLow;
+ } hl;
+};
+typedef union LongDateCvt LongDateCvt;
+union LongDateRec {
+ struct {
+ short era;
+ short year;
+ short month;
+ short day;
+ short hour;
+ short minute;
+ short second;
+ short dayOfWeek;
+ short dayOfYear;
+ short weekOfYear;
+ short pm;
+ short res1;
+ short res2;
+ short res3;
+ } ld;
+ short list[14];
+ struct {
+ short eraAlt;
+ DateTimeRec oldDate;
+ } od;
+};
+typedef union LongDateRec LongDateRec;
+
+typedef SInt8 DateDelta;
+struct TogglePB {
+ long togFlags;
+ ResType amChars;
+ ResType pmChars;
+ long reserved[4];
+};
+typedef struct TogglePB TogglePB;
+extern OSStatus
+UCConvertUTCDateTimeToCFAbsoluteTime(
+ const UTCDateTime * iUTCDate,
+ CFAbsoluteTime * oCFTime) ;
+extern OSStatus
+UCConvertSecondsToCFAbsoluteTime(
+ UInt32 iSeconds,
+ CFAbsoluteTime * oCFTime) ;
+extern OSStatus
+UCConvertLongDateTimeToCFAbsoluteTime(
+ LongDateTime iLongTime,
+ CFAbsoluteTime * oCFTime) ;
+extern OSStatus
+UCConvertCFAbsoluteTimeToUTCDateTime(
+ CFAbsoluteTime iCFTime,
+ UTCDateTime * oUTCDate) ;
+extern OSStatus
+UCConvertCFAbsoluteTimeToSeconds(
+ CFAbsoluteTime iCFTime,
+ UInt32 * oSeconds) ;
+extern OSStatus
+UCConvertCFAbsoluteTimeToLongDateTime(
+ CFAbsoluteTime iCFTime,
+ LongDateTime * oLongDate) ;
+extern void
+DateString(
+ long dateTime,
+ DateForm longFlag,
+ Str255 result,
+ Handle intlHandle) ;
+extern void
+TimeString(
+ long dateTime,
+ Boolean wantSeconds,
+ Str255 result,
+ Handle intlHandle) ;
+extern void
+LongDateString(
+ const LongDateTime * dateTime,
+ DateForm longFlag,
+ Str255 result,
+ Handle intlHandle) ;
+extern void
+LongTimeString(
+ const LongDateTime * dateTime,
+ Boolean wantSeconds,
+ Str255 result,
+ Handle intlHandle) ;
+extern OSErr
+InitDateCache(DateCachePtr theCache) ;
+extern StringToDateStatus
+StringToDate(
+ Ptr textPtr,
+ long textLen,
+ DateCachePtr theCache,
+ long * lengthUsed,
+ LongDateRec * dateTime) ;
+extern StringToDateStatus
+StringToTime(
+ Ptr textPtr,
+ long textLen,
+ DateCachePtr theCache,
+ long * lengthUsed,
+ LongDateRec * dateTime) ;
+extern void
+LongDateToSeconds(
+ const LongDateRec * lDate,
+ LongDateTime * lSecs) ;
+extern void
+LongSecondsToDate(
+ const LongDateTime * lSecs,
+ LongDateRec * lDate) ;
+extern ToggleResults
+ToggleDate(
+ LongDateTime * lSecs,
+ LongDateField field,
+ DateDelta delta,
+ short ch,
+ const TogglePB * params) ;
+extern short
+ValidDate(
+ const LongDateRec * vDate,
+ long flags,
+ LongDateTime * newSecs) ;
+extern OSErr
+ReadDateTime(unsigned long * time) ;
+extern void
+GetDateTime(unsigned long * secs) ;
+extern OSErr
+SetDateTime(unsigned long time) ;
+extern void
+SetTime(const DateTimeRec * d) ;
+extern void
+GetTime(DateTimeRec * d) ;
+extern void
+DateToSeconds(
+ const DateTimeRec * d,
+ unsigned long * secs) ;
+extern void
+SecondsToDate(
+ unsigned long secs,
+ DateTimeRec * d) ;
+
+
+}
+extern "C" {
+
+
+
+enum {
+ useFree = 0,
+ useATalk = 1,
+ useAsync = 2,
+ useExtClk = 3,
+ useMIDI = 4
+};
+
+enum {
+ false32b = 0,
+ true32b = 1
+};
+
+enum {
+
+ sortsBefore = -1,
+ sortsEqual = 0,
+ sortsAfter = 1
+};
+
+enum {
+ dummyType = 0,
+ vType = 1,
+ ioQType = 2,
+ drvQType = 3,
+ evType = 4,
+ fsQType = 5,
+ sIQType = 6,
+ dtQType = 7,
+ nmType = 8
+};
+
+typedef SignedByte QTypes;
+struct SysParmType {
+ UInt8 valid;
+ UInt8 aTalkA;
+ UInt8 aTalkB;
+ UInt8 config;
+ short portA;
+ short portB;
+ long alarm;
+ short font;
+ short kbdPrint;
+ short volClik;
+ short misc;
+};
+typedef struct SysParmType SysParmType;
+typedef SysParmType * SysPPtr;
+struct QElem {
+ struct QElem * qLink;
+ short qType;
+ short qData[1];
+};
+typedef struct QElem QElem;
+typedef QElem * QElemPtr;
+struct QHdr {
+ volatile short qFlags;
+ volatile QElemPtr qHead;
+ volatile QElemPtr qTail;
+};
+typedef struct QHdr QHdr;
+typedef QHdr * QHdrPtr;
+typedef void ( * DeferredTaskProcPtr)(long dtParam);
+typedef DeferredTaskProcPtr DeferredTaskUPP;
+extern DeferredTaskUPP
+NewDeferredTaskUPP(DeferredTaskProcPtr userRoutine) ;
+extern void
+DisposeDeferredTaskUPP(DeferredTaskUPP userUPP) ;
+extern void
+InvokeDeferredTaskUPP(
+ long dtParam,
+ DeferredTaskUPP userUPP) ;
+
+struct DeferredTask {
+ volatile QElemPtr qLink;
+ short qType;
+ volatile short dtFlags;
+ DeferredTaskUPP dtAddr;
+ long dtParam;
+ long dtReserved;
+};
+typedef struct DeferredTask DeferredTask;
+typedef DeferredTask * DeferredTaskPtr;
+struct MachineLocation {
+ Fract latitude;
+ Fract longitude;
+ union {
+
+ SInt8 dlsDelta;
+
+ long gmtDelta;
+ struct {
+
+
+
+ SInt8 Delta;
+ } dls;
+ } u;
+};
+typedef struct MachineLocation MachineLocation;
+extern Boolean
+IsMetric(void) ;
+extern SysPPtr
+GetSysPPtr(void) ;
+extern OSErr
+DTInstall(DeferredTaskPtr dtTaskPtr) ;
+extern void
+Delay(
+ unsigned long numTicks,
+ unsigned long * finalTicks) ;
+extern OSErr
+WriteParam(void) ;
+extern void
+Enqueue(
+ QElemPtr qElement,
+ QHdrPtr qHeader) ;
+extern OSErr
+Dequeue(
+ QElemPtr qElement,
+ QHdrPtr qHeader) ;
+extern long
+SetCurrentA5(void) ;
+extern long
+SetA5(long newA5) ;
+extern OSErr
+InitUtil(void) ;
+extern void
+MakeDataExecutable(
+ void * baseAddress,
+ unsigned long length) ;
+extern void
+ReadLocation(MachineLocation * loc) ;
+extern void
+WriteLocation(const MachineLocation * loc) ;
+extern UInt32
+TickCount(void) ;
+extern CFStringRef
+CSCopyUserName(Boolean useShortName) ;
+extern CFStringRef
+CSCopyMachineName(void) ;
+enum {
+ curSysEnvVers = 2
+};
+
+struct SysEnvRec {
+ short environsVersion;
+ short machineType;
+ short systemVersion;
+ short processor;
+ Boolean hasFPU;
+ Boolean hasColorQD;
+ short keyBoardType;
+ short atDrvrVersNum;
+ short sysVRefNum;
+};
+typedef struct SysEnvRec SysEnvRec;
+enum {
+
+ envMac = -1,
+ envXL = -2,
+ envMachUnknown = 0,
+ env512KE = 1,
+ envMacPlus = 2,
+ envSE = 3,
+ envMacII = 4,
+ envMacIIx = 5,
+ envMacIIcx = 6,
+ envSE30 = 7,
+ envPortable = 8,
+ envMacIIci = 9,
+ envMacIIfx = 11
+};
+
+enum {
+
+ envCPUUnknown = 0,
+ env68000 = 1,
+ env68010 = 2,
+ env68020 = 3,
+ env68030 = 4,
+ env68040 = 5
+};
+
+enum {
+
+ envUnknownKbd = 0,
+ envMacKbd = 1,
+ envMacAndPad = 2,
+ envMacPlusKbd = 3,
+ envAExtendKbd = 4,
+ envStandADBKbd = 5,
+ envPrtblADBKbd = 6,
+ envPrtblISOKbd = 7,
+ envStdISOADBKbd = 8,
+ envExtISOADBKbd = 9
+};
+
+
+}
+extern "C" {
+
+
+
+
+
+struct HFSUniStr255 {
+ UInt16 length;
+ UniChar unicode[255];
+};
+typedef struct HFSUniStr255 HFSUniStr255;
+typedef const HFSUniStr255 * ConstHFSUniStr255Param;
+enum {
+ fsCurPerm = 0x00,
+ fsRdPerm = 0x01,
+ fsWrPerm = 0x02,
+ fsRdWrPerm = 0x03,
+ fsRdWrShPerm = 0x04,
+ fsRdDenyPerm = 0x10,
+ fsWrDenyPerm = 0x20
+};
+
+enum {
+ fsRtParID = 1,
+ fsRtDirID = 2
+};
+
+enum {
+ fsAtMark = 0,
+ fsFromStart = 1,
+ fsFromLEOF = 2,
+ fsFromMark = 3
+};
+
+enum {
+
+ pleaseCacheBit = 4,
+ pleaseCacheMask = 0x0010,
+ noCacheBit = 5,
+ noCacheMask = 0x0020,
+ rdVerifyBit = 6,
+ rdVerifyMask = 0x0040,
+ rdVerify = 64,
+ forceReadBit = 6,
+ forceReadMask = 0x0040,
+ newLineBit = 7,
+ newLineMask = 0x0080,
+ newLineCharMask = 0xFF00
+};
+
+
+enum {
+
+ fsSBPartialName = 1,
+ fsSBFullName = 2,
+ fsSBFlAttrib = 4,
+ fsSBFlFndrInfo = 8,
+ fsSBFlLgLen = 32,
+ fsSBFlPyLen = 64,
+ fsSBFlRLgLen = 128,
+ fsSBFlRPyLen = 256,
+ fsSBFlCrDat = 512,
+ fsSBFlMdDat = 1024,
+ fsSBFlBkDat = 2048,
+ fsSBFlXFndrInfo = 4096,
+ fsSBFlParID = 8192,
+ fsSBNegate = 16384,
+ fsSBDrUsrWds = 8,
+ fsSBDrNmFls = 16,
+ fsSBDrCrDat = 512,
+ fsSBDrMdDat = 1024,
+ fsSBDrBkDat = 2048,
+ fsSBDrFndrInfo = 4096,
+ fsSBDrParID = 8192
+};
+
+enum {
+
+ fsSBPartialNameBit = 0,
+ fsSBFullNameBit = 1,
+ fsSBFlAttribBit = 2,
+ fsSBFlFndrInfoBit = 3,
+ fsSBFlLgLenBit = 5,
+ fsSBFlPyLenBit = 6,
+ fsSBFlRLgLenBit = 7,
+ fsSBFlRPyLenBit = 8,
+ fsSBFlCrDatBit = 9,
+ fsSBFlMdDatBit = 10,
+ fsSBFlBkDatBit = 11,
+ fsSBFlXFndrInfoBit = 12,
+ fsSBFlParIDBit = 13,
+ fsSBNegateBit = 14,
+ fsSBDrUsrWdsBit = 3,
+ fsSBDrNmFlsBit = 4,
+ fsSBDrCrDatBit = 9,
+ fsSBDrMdDatBit = 10,
+ fsSBDrBkDatBit = 11,
+ fsSBDrFndrInfoBit = 12,
+ fsSBDrParIDBit = 13
+};
+
+enum {
+
+ bLimitFCBs = 31,
+ bLocalWList = 30,
+ bNoMiniFndr = 29,
+ bNoVNEdit = 28,
+ bNoLclSync = 27,
+ bTrshOffLine = 26,
+ bNoSwitchTo = 25,
+ bNoDeskItems = 20,
+ bNoBootBlks = 19,
+ bAccessCntl = 18,
+ bNoSysDir = 17,
+ bHasExtFSVol = 16,
+ bHasOpenDeny = 15,
+ bHasCopyFile = 14,
+ bHasMoveRename = 13,
+ bHasDesktopMgr = 12,
+ bHasShortName = 11,
+ bHasFolderLock = 10,
+ bHasPersonalAccessPrivileges = 9,
+ bHasUserGroupList = 8,
+ bHasCatSearch = 7,
+ bHasFileIDs = 6,
+ bHasBTreeMgr = 5,
+ bHasBlankAccessPrivileges = 4,
+ bSupportsAsyncRequests = 3,
+ bSupportsTrashVolumeCache = 2
+};
+
+enum {
+
+ bHasDirectIO = 1
+};
+
+enum {
+
+ bIsEjectable = 0,
+ bSupportsHFSPlusAPIs = 1,
+ bSupportsFSCatalogSearch = 2,
+ bSupportsFSExchangeObjects = 3,
+ bSupports2TBFiles = 4,
+ bSupportsLongNames = 5,
+ bSupportsMultiScriptNames = 6,
+ bSupportsNamedForks = 7,
+ bSupportsSubtreeIterators = 8,
+ bL2PCanMapFileBlocks = 9
+};
+
+enum {
+
+ bParentModDateChanges = 10,
+ bAncestorModDateChanges = 11
+};
+
+enum {
+
+ bSupportsSymbolicLinks = 13,
+ bIsAutoMounted = 14,
+ bAllowCDiDataHandler = 17,
+ bSupportsExclusiveLocks = 18
+};
+
+enum {
+
+ kLargeIcon = 1,
+ kLarge4BitIcon = 2,
+ kLarge8BitIcon = 3,
+ kSmallIcon = 4,
+ kSmall4BitIcon = 5,
+ kSmall8BitIcon = 6,
+ kicnsIconFamily = 239
+};
+
+enum {
+ kLargeIconSize = 256,
+ kLarge4BitIconSize = 512,
+ kLarge8BitIconSize = 1024,
+ kSmallIconSize = 64,
+ kSmall4BitIconSize = 128,
+ kSmall8BitIconSize = 256
+};
+
+enum {
+
+ kWidePosOffsetBit = 8,
+ kUseWidePositioning = (1 << kWidePosOffsetBit),
+ kMaximumBlocksIn4GB = 0x007FFFFF
+};
+
+enum {
+
+ fsUnixPriv = 1
+};
+
+enum {
+
+ kNoUserAuthentication = 1,
+ kPassword = 2,
+ kEncryptPassword = 3,
+ kTwoWayEncryptPassword = 6
+};
+
+
+
+enum {
+ kOwnerID2Name = 1,
+ kGroupID2Name = 2,
+ kOwnerName2ID = 3,
+ kGroupName2ID = 4,
+ kReturnNextUser = 1,
+ kReturnNextGroup = 2,
+ kReturnNextUG = 3
+};
+
+
+enum {
+ kVCBFlagsIdleFlushBit = 3,
+ kVCBFlagsIdleFlushMask = 0x0008,
+ kVCBFlagsHFSPlusAPIsBit = 4,
+ kVCBFlagsHFSPlusAPIsMask = 0x0010,
+ kVCBFlagsHardwareGoneBit = 5,
+ kVCBFlagsHardwareGoneMask = 0x0020,
+ kVCBFlagsVolumeDirtyBit = 15,
+ kVCBFlagsVolumeDirtyMask = 0x8000
+};
+
+
+enum {
+ kioVAtrbDefaultVolumeBit = 5,
+ kioVAtrbDefaultVolumeMask = 0x0020,
+ kioVAtrbFilesOpenBit = 6,
+ kioVAtrbFilesOpenMask = 0x0040,
+ kioVAtrbHardwareLockedBit = 7,
+ kioVAtrbHardwareLockedMask = 0x0080,
+ kioVAtrbSoftwareLockedBit = 15,
+ kioVAtrbSoftwareLockedMask = 0x8000
+};
+
+
+enum {
+
+ kioFlAttribLockedBit = 0,
+ kioFlAttribLockedMask = 0x01,
+ kioFlAttribResOpenBit = 2,
+ kioFlAttribResOpenMask = 0x04,
+ kioFlAttribDataOpenBit = 3,
+ kioFlAttribDataOpenMask = 0x08,
+ kioFlAttribDirBit = 4,
+ kioFlAttribDirMask = 0x10,
+ ioDirFlg = 4,
+ ioDirMask = 0x10,
+ kioFlAttribCopyProtBit = 6,
+ kioFlAttribCopyProtMask = 0x40,
+ kioFlAttribFileOpenBit = 7,
+ kioFlAttribFileOpenMask = 0x80,
+ kioFlAttribInSharedBit = 2,
+ kioFlAttribInSharedMask = 0x04,
+ kioFlAttribMountedBit = 3,
+ kioFlAttribMountedMask = 0x08,
+ kioFlAttribSharePointBit = 5,
+ kioFlAttribSharePointMask = 0x20
+};
+
+
+enum {
+ kioFCBWriteBit = 8,
+ kioFCBWriteMask = 0x0100,
+ kioFCBResourceBit = 9,
+ kioFCBResourceMask = 0x0200,
+ kioFCBWriteLockedBit = 10,
+ kioFCBWriteLockedMask = 0x0400,
+ kioFCBLargeFileBit = 11,
+ kioFCBLargeFileMask = 0x0800,
+ kioFCBSharedWriteBit = 12,
+ kioFCBSharedWriteMask = 0x1000,
+ kioFCBFileLockedBit = 13,
+ kioFCBFileLockedMask = 0x2000,
+ kioFCBOwnClumpBit = 14,
+ kioFCBOwnClumpMask = 0x4000,
+ kioFCBModifiedBit = 15,
+ kioFCBModifiedMask = 0x8000
+};
+
+
+
+enum {
+ kioACUserNoSeeFolderBit = 0,
+ kioACUserNoSeeFolderMask = 0x01,
+ kioACUserNoSeeFilesBit = 1,
+ kioACUserNoSeeFilesMask = 0x02,
+ kioACUserNoMakeChangesBit = 2,
+ kioACUserNoMakeChangesMask = 0x04,
+ kioACUserNotOwnerBit = 7,
+ kioACUserNotOwnerMask = 0x80
+};
+
+
+enum {
+ kioACAccessOwnerBit = 31,
+ kioACAccessOwnerMask = (long)0x80000000,
+ kioACAccessBlankAccessBit = 28,
+ kioACAccessBlankAccessMask = 0x10000000,
+ kioACAccessUserWriteBit = 26,
+ kioACAccessUserWriteMask = 0x04000000,
+ kioACAccessUserReadBit = 25,
+ kioACAccessUserReadMask = 0x02000000,
+ kioACAccessUserSearchBit = 24,
+ kioACAccessUserSearchMask = 0x01000000,
+ kioACAccessEveryoneWriteBit = 18,
+ kioACAccessEveryoneWriteMask = 0x00040000,
+ kioACAccessEveryoneReadBit = 17,
+ kioACAccessEveryoneReadMask = 0x00020000,
+ kioACAccessEveryoneSearchBit = 16,
+ kioACAccessEveryoneSearchMask = 0x00010000,
+ kioACAccessGroupWriteBit = 10,
+ kioACAccessGroupWriteMask = 0x00000400,
+ kioACAccessGroupReadBit = 9,
+ kioACAccessGroupReadMask = 0x00000200,
+ kioACAccessGroupSearchBit = 8,
+ kioACAccessGroupSearchMask = 0x00000100,
+ kioACAccessOwnerWriteBit = 2,
+ kioACAccessOwnerWriteMask = 0x00000004,
+ kioACAccessOwnerReadBit = 1,
+ kioACAccessOwnerReadMask = 0x00000002,
+ kioACAccessOwnerSearchBit = 0,
+ kioACAccessOwnerSearchMask = 0x00000001,
+ kfullPrivileges = 0x00070007,
+ kownerPrivileges = 0x00000007
+};
+
+
+enum {
+ knoUser = 0,
+ kadministratorUser = 1
+};
+
+enum {
+ knoGroup = 0
+};
+
+
+struct GetVolParmsInfoBuffer {
+ short vMVersion;
+ long vMAttrib;
+ Handle vMLocalHand;
+ long vMServerAdr;
+
+ long vMVolumeGrade;
+ short vMForeignPrivID;
+
+ long vMExtendedAttributes;
+
+ void * vMDeviceID;
+
+ UniCharCount vMMaxNameLength;
+
+};
+typedef struct GetVolParmsInfoBuffer GetVolParmsInfoBuffer;
+typedef union ParamBlockRec ParamBlockRec;
+
+typedef ParamBlockRec * ParmBlkPtr;
+typedef void ( * IOCompletionProcPtr)(ParmBlkPtr paramBlock);
+typedef IOCompletionProcPtr IOCompletionUPP;
+struct IOParam {
+ QElemPtr qLink;
+ short qType;
+ short ioTrap;
+ Ptr ioCmdAddr;
+ IOCompletionUPP ioCompletion;
+ volatile OSErr ioResult;
+ StringPtr ioNamePtr;
+ short ioVRefNum;
+ short ioRefNum;
+ SInt8 ioVersNum;
+ SInt8 ioPermssn;
+ Ptr ioMisc;
+ Ptr ioBuffer;
+ long ioReqCount;
+ long ioActCount;
+ short ioPosMode;
+ long ioPosOffset;
+};
+typedef struct IOParam IOParam;
+typedef IOParam * IOParamPtr;
+struct FileParam {
+ QElemPtr qLink;
+ short qType;
+ short ioTrap;
+ Ptr ioCmdAddr;
+ IOCompletionUPP ioCompletion;
+ volatile OSErr ioResult;
+ StringPtr ioNamePtr;
+ short ioVRefNum;
+ short ioFRefNum;
+ SInt8 ioFVersNum;
+ SInt8 filler1;
+ short ioFDirIndex;
+ SInt8 ioFlAttrib;
+ SInt8 ioFlVersNum;
+ FInfo ioFlFndrInfo;
+ unsigned long ioFlNum;
+ unsigned short ioFlStBlk;
+ long ioFlLgLen;
+ long ioFlPyLen;
+ unsigned short ioFlRStBlk;
+ long ioFlRLgLen;
+ long ioFlRPyLen;
+ unsigned long ioFlCrDat;
+ unsigned long ioFlMdDat;
+};
+typedef struct FileParam FileParam;
+typedef FileParam * FileParamPtr;
+struct VolumeParam {
+ QElemPtr qLink;
+ short qType;
+ short ioTrap;
+ Ptr ioCmdAddr;
+ IOCompletionUPP ioCompletion;
+ volatile OSErr ioResult;
+ StringPtr ioNamePtr;
+ short ioVRefNum;
+ long filler2;
+ short ioVolIndex;
+ unsigned long ioVCrDate;
+ unsigned long ioVLsBkUp;
+ unsigned short ioVAtrb;
+ unsigned short ioVNmFls;
+ unsigned short ioVDirSt;
+ short ioVBlLn;
+ unsigned short ioVNmAlBlks;
+ unsigned long ioVAlBlkSiz;
+ unsigned long ioVClpSiz;
+ unsigned short ioAlBlSt;
+ unsigned long ioVNxtFNum;
+ unsigned short ioVFrBlk;
+};
+typedef struct VolumeParam VolumeParam;
+typedef VolumeParam * VolumeParamPtr;
+struct CntrlParam {
+ QElemPtr qLink;
+ short qType;
+ short ioTrap;
+ Ptr ioCmdAddr;
+ IOCompletionUPP ioCompletion;
+ volatile OSErr ioResult;
+ StringPtr ioNamePtr;
+ short ioVRefNum;
+ short ioCRefNum;
+ short csCode;
+ short csParam[11];
+};
+typedef struct CntrlParam CntrlParam;
+typedef CntrlParam * CntrlParamPtr;
+struct SlotDevParam {
+ QElemPtr qLink;
+ short qType;
+ short ioTrap;
+ Ptr ioCmdAddr;
+ IOCompletionUPP ioCompletion;
+ volatile OSErr ioResult;
+ StringPtr ioNamePtr;
+ short ioVRefNum;
+ short ioSRefNum;
+ SInt8 ioSVersNum;
+ SInt8 ioSPermssn;
+ Ptr ioSMix;
+ short ioSFlags;
+ SInt8 ioSlot;
+ SInt8 ioID;
+};
+typedef struct SlotDevParam SlotDevParam;
+typedef SlotDevParam * SlotDevParamPtr;
+struct MultiDevParam {
+ QElemPtr qLink;
+ short qType;
+ short ioTrap;
+ Ptr ioCmdAddr;
+ IOCompletionUPP ioCompletion;
+ volatile OSErr ioResult;
+ StringPtr ioNamePtr;
+ short ioVRefNum;
+ short ioMRefNum;
+ SInt8 ioMVersNum;
+ SInt8 ioMPermssn;
+ Ptr ioMMix;
+ short ioMFlags;
+ Ptr ioSEBlkPtr;
+};
+typedef struct MultiDevParam MultiDevParam;
+typedef MultiDevParam * MultiDevParamPtr;
+union ParamBlockRec {
+ IOParam ioParam;
+ FileParam fileParam;
+ VolumeParam volumeParam;
+ CntrlParam cntrlParam;
+ SlotDevParam slotDevParam;
+ MultiDevParam multiDevParam;
+};
+
+struct HFileInfo {
+ QElemPtr qLink;
+ short qType;
+ short ioTrap;
+ Ptr ioCmdAddr;
+ IOCompletionUPP ioCompletion;
+ volatile OSErr ioResult;
+ StringPtr ioNamePtr;
+ short ioVRefNum;
+ short ioFRefNum;
+ SInt8 ioFVersNum;
+ SInt8 filler1;
+ short ioFDirIndex;
+ SInt8 ioFlAttrib;
+ SInt8 ioACUser;
+ FInfo ioFlFndrInfo;
+ long ioDirID;
+ unsigned short ioFlStBlk;
+ long ioFlLgLen;
+ long ioFlPyLen;
+ unsigned short ioFlRStBlk;
+ long ioFlRLgLen;
+ long ioFlRPyLen;
+ unsigned long ioFlCrDat;
+ unsigned long ioFlMdDat;
+ unsigned long ioFlBkDat;
+ FXInfo ioFlXFndrInfo;
+ long ioFlParID;
+ long ioFlClpSiz;
+};
+typedef struct HFileInfo HFileInfo;
+struct DirInfo {
+ QElemPtr qLink;
+ short qType;
+ short ioTrap;
+ Ptr ioCmdAddr;
+ IOCompletionUPP ioCompletion;
+ volatile OSErr ioResult;
+ StringPtr ioNamePtr;
+ short ioVRefNum;
+ short ioFRefNum;
+ SInt8 ioFVersNum;
+ SInt8 filler1;
+ short ioFDirIndex;
+ SInt8 ioFlAttrib;
+ SInt8 ioACUser;
+ DInfo ioDrUsrWds;
+ long ioDrDirID;
+ unsigned short ioDrNmFls;
+ short filler3[9];
+ unsigned long ioDrCrDat;
+ unsigned long ioDrMdDat;
+ unsigned long ioDrBkDat;
+ DXInfo ioDrFndrInfo;
+ long ioDrParID;
+};
+typedef struct DirInfo DirInfo;
+union CInfoPBRec {
+ HFileInfo hFileInfo;
+ DirInfo dirInfo;
+};
+typedef union CInfoPBRec CInfoPBRec;
+typedef CInfoPBRec * CInfoPBPtr;
+struct XCInfoPBRec {
+ QElemPtr qLink;
+ short qType;
+ short ioTrap;
+ Ptr ioCmdAddr;
+ ProcPtr ioCompletion;
+ volatile OSErr ioResult;
+ StringPtr ioNamePtr;
+ short ioVRefNum;
+ long filler1;
+ StringPtr ioShortNamePtr;
+ short filler2;
+ short ioPDType;
+ long ioPDAuxType;
+ long filler3[2];
+ long ioDirID;
+};
+typedef struct XCInfoPBRec XCInfoPBRec;
+typedef XCInfoPBRec * XCInfoPBPtr;
+
+struct CatPositionRec {
+ long initialize;
+ short priv[6];
+};
+typedef struct CatPositionRec CatPositionRec;
+struct FSSpec {
+ short vRefNum;
+ long parID;
+ StrFileName name;
+};
+typedef struct FSSpec FSSpec;
+typedef FSSpec * FSSpecPtr;
+typedef FSSpecPtr * FSSpecHandle;
+
+typedef FSSpecPtr FSSpecArrayPtr;
+
+
+
+
+typedef const FSSpec * ConstFSSpecPtr;
+
+
+
+
+
+typedef OSType VolumeType;
+enum {
+
+ AppleShareMediaType = 'afpm'
+};
+
+
+
+
+struct VolMountInfoHeader {
+ short length;
+ VolumeType media;
+};
+typedef struct VolMountInfoHeader VolMountInfoHeader;
+typedef VolMountInfoHeader * VolMountInfoPtr;
+
+
+
+
+struct VolumeMountInfoHeader {
+ short length;
+ VolumeType media;
+ short flags;
+};
+typedef struct VolumeMountInfoHeader VolumeMountInfoHeader;
+typedef VolumeMountInfoHeader * VolumeMountInfoHeaderPtr;
+
+enum {
+ volMountNoLoginMsgFlagBit = 0,
+ volMountNoLoginMsgFlagMask = 0x0001,
+ volMountExtendedFlagsBit = 7,
+ volMountExtendedFlagsMask = 0x0080,
+ volMountInteractBit = 15,
+ volMountInteractMask = 0x8000,
+ volMountChangedBit = 14,
+ volMountChangedMask = 0x4000,
+ volMountFSReservedMask = 0x00FF,
+ volMountSysReservedMask = 0xFF00
+};
+
+
+
+struct AFPVolMountInfo {
+ short length;
+ VolumeType media;
+ short flags;
+ SInt8 nbpInterval;
+ SInt8 nbpCount;
+ short uamType;
+ short zoneNameOffset;
+ short serverNameOffset;
+ short volNameOffset;
+ short userNameOffset;
+ short userPasswordOffset;
+ short volPasswordOffset;
+ char AFPData[144];
+};
+typedef struct AFPVolMountInfo AFPVolMountInfo;
+typedef AFPVolMountInfo * AFPVolMountInfoPtr;
+
+
+
+struct AFPXVolMountInfo {
+ short length;
+ VolumeType media;
+ short flags;
+ SInt8 nbpInterval;
+ SInt8 nbpCount;
+ short uamType;
+ short zoneNameOffset;
+ short serverNameOffset;
+ short volNameOffset;
+ short userNameOffset;
+ short userPasswordOffset;
+ short volPasswordOffset;
+ short extendedFlags;
+ short uamNameOffset;
+ short alternateAddressOffset;
+ char AFPData[176];
+};
+typedef struct AFPXVolMountInfo AFPXVolMountInfo;
+typedef AFPXVolMountInfo * AFPXVolMountInfoPtr;
+enum {
+ kAFPExtendedFlagsAlternateAddressMask = 1
+};
+
+
+enum {
+
+ kAFPTagTypeIP = 0x01,
+ kAFPTagTypeIPPort = 0x02,
+ kAFPTagTypeDDP = 0x03,
+ kAFPTagTypeDNS = 0x04
+};
+
+
+enum {
+
+ kAFPTagLengthIP = 0x06,
+ kAFPTagLengthIPPort = 0x08,
+ kAFPTagLengthDDP = 0x06
+};
+
+struct AFPTagData {
+ UInt8 fLength;
+ UInt8 fType;
+ UInt8 fData[1];
+};
+typedef struct AFPTagData AFPTagData;
+struct AFPAlternateAddress {
+
+ UInt8 fVersion;
+ UInt8 fAddressCount;
+ UInt8 fAddressList[1];
+};
+typedef struct AFPAlternateAddress AFPAlternateAddress;
+struct DTPBRec {
+ QElemPtr qLink;
+ short qType;
+ short ioTrap;
+ Ptr ioCmdAddr;
+ IOCompletionUPP ioCompletion;
+ volatile OSErr ioResult;
+ StringPtr ioNamePtr;
+ short ioVRefNum;
+ short ioDTRefNum;
+ short ioIndex;
+ long ioTagInfo;
+ Ptr ioDTBuffer;
+ long ioDTReqCount;
+ long ioDTActCount;
+ SInt8 ioFiller1;
+ UInt8 ioIconType;
+ short ioFiller2;
+ long ioDirID;
+ OSType ioFileCreator;
+ OSType ioFileType;
+ long ioFiller3;
+ long ioDTLgLen;
+ long ioDTPyLen;
+ short ioFiller4[14];
+ long ioAPPLParID;
+};
+typedef struct DTPBRec DTPBRec;
+typedef DTPBRec * DTPBPtr;
+
+struct HIOParam {
+ QElemPtr qLink;
+ short qType;
+ short ioTrap;
+ Ptr ioCmdAddr;
+ IOCompletionUPP ioCompletion;
+ volatile OSErr ioResult;
+ StringPtr ioNamePtr;
+ short ioVRefNum;
+ short ioRefNum;
+ SInt8 ioVersNum;
+ SInt8 ioPermssn;
+ Ptr ioMisc;
+ Ptr ioBuffer;
+ long ioReqCount;
+ long ioActCount;
+ short ioPosMode;
+ long ioPosOffset;
+};
+typedef struct HIOParam HIOParam;
+typedef HIOParam * HIOParamPtr;
+struct HFileParam {
+ QElemPtr qLink;
+ short qType;
+ short ioTrap;
+ Ptr ioCmdAddr;
+ IOCompletionUPP ioCompletion;
+ volatile OSErr ioResult;
+ StringPtr ioNamePtr;
+ short ioVRefNum;
+ short ioFRefNum;
+ SInt8 ioFVersNum;
+ SInt8 filler1;
+ short ioFDirIndex;
+ SInt8 ioFlAttrib;
+ SInt8 ioFlVersNum;
+ FInfo ioFlFndrInfo;
+ long ioDirID;
+ unsigned short ioFlStBlk;
+ long ioFlLgLen;
+ long ioFlPyLen;
+ unsigned short ioFlRStBlk;
+ long ioFlRLgLen;
+ long ioFlRPyLen;
+ unsigned long ioFlCrDat;
+ unsigned long ioFlMdDat;
+};
+typedef struct HFileParam HFileParam;
+typedef HFileParam * HFileParamPtr;
+struct HVolumeParam {
+ QElemPtr qLink;
+ short qType;
+ short ioTrap;
+ Ptr ioCmdAddr;
+ IOCompletionUPP ioCompletion;
+ volatile OSErr ioResult;
+ StringPtr ioNamePtr;
+ short ioVRefNum;
+ long filler2;
+ short ioVolIndex;
+ unsigned long ioVCrDate;
+ unsigned long ioVLsMod;
+ short ioVAtrb;
+ unsigned short ioVNmFls;
+ unsigned short ioVBitMap;
+ unsigned short ioAllocPtr;
+ unsigned short ioVNmAlBlks;
+ unsigned long ioVAlBlkSiz;
+ unsigned long ioVClpSiz;
+ unsigned short ioAlBlSt;
+ unsigned long ioVNxtCNID;
+ unsigned short ioVFrBlk;
+ unsigned short ioVSigWord;
+ short ioVDrvInfo;
+ short ioVDRefNum;
+ short ioVFSID;
+ unsigned long ioVBkUp;
+ short ioVSeqNum;
+ unsigned long ioVWrCnt;
+ unsigned long ioVFilCnt;
+ unsigned long ioVDirCnt;
+ long ioVFndrInfo[8];
+};
+typedef struct HVolumeParam HVolumeParam;
+typedef HVolumeParam * HVolumeParamPtr;
+struct XIOParam {
+ QElemPtr qLink;
+ short qType;
+ short ioTrap;
+ Ptr ioCmdAddr;
+ IOCompletionUPP ioCompletion;
+ volatile OSErr ioResult;
+ StringPtr ioNamePtr;
+ short ioVRefNum;
+ short ioRefNum;
+ SInt8 ioVersNum;
+ SInt8 ioPermssn;
+ Ptr ioMisc;
+ Ptr ioBuffer;
+ long ioReqCount;
+ long ioActCount;
+ short ioPosMode;
+ wide ioWPosOffset;
+};
+typedef struct XIOParam XIOParam;
+typedef XIOParam * XIOParamPtr;
+struct XVolumeParam {
+ QElemPtr qLink;
+ short qType;
+ short ioTrap;
+ Ptr ioCmdAddr;
+ IOCompletionUPP ioCompletion;
+ volatile OSErr ioResult;
+ StringPtr ioNamePtr;
+ short ioVRefNum;
+ unsigned long ioXVersion;
+ short ioVolIndex;
+ unsigned long ioVCrDate;
+ unsigned long ioVLsMod;
+ short ioVAtrb;
+ unsigned short ioVNmFls;
+ unsigned short ioVBitMap;
+ unsigned short ioAllocPtr;
+ unsigned short ioVNmAlBlks;
+ unsigned long ioVAlBlkSiz;
+ unsigned long ioVClpSiz;
+ unsigned short ioAlBlSt;
+ unsigned long ioVNxtCNID;
+ unsigned short ioVFrBlk;
+ unsigned short ioVSigWord;
+ short ioVDrvInfo;
+ short ioVDRefNum;
+ short ioVFSID;
+ unsigned long ioVBkUp;
+ short ioVSeqNum;
+ unsigned long ioVWrCnt;
+ unsigned long ioVFilCnt;
+ unsigned long ioVDirCnt;
+ long ioVFndrInfo[8];
+ UInt64 ioVTotalBytes;
+ UInt64 ioVFreeBytes;
+};
+typedef struct XVolumeParam XVolumeParam;
+typedef XVolumeParam * XVolumeParamPtr;
+struct AccessParam {
+ QElemPtr qLink;
+ short qType;
+ short ioTrap;
+ Ptr ioCmdAddr;
+ IOCompletionUPP ioCompletion;
+ volatile OSErr ioResult;
+ StringPtr ioNamePtr;
+ short ioVRefNum;
+ short filler3;
+ short ioDenyModes;
+ short filler4;
+ SInt8 filler5;
+ SInt8 ioACUser;
+ long filler6;
+ long ioACOwnerID;
+ long ioACGroupID;
+ long ioACAccess;
+ long ioDirID;
+};
+typedef struct AccessParam AccessParam;
+typedef AccessParam * AccessParamPtr;
+struct ObjParam {
+ QElemPtr qLink;
+ short qType;
+ short ioTrap;
+ Ptr ioCmdAddr;
+ IOCompletionUPP ioCompletion;
+ volatile OSErr ioResult;
+ StringPtr ioNamePtr;
+ short ioVRefNum;
+ short filler7;
+ short ioObjType;
+ StringPtr ioObjNamePtr;
+ long ioObjID;
+};
+typedef struct ObjParam ObjParam;
+typedef ObjParam * ObjParamPtr;
+struct CopyParam {
+ QElemPtr qLink;
+ short qType;
+ short ioTrap;
+ Ptr ioCmdAddr;
+ IOCompletionUPP ioCompletion;
+ volatile OSErr ioResult;
+ StringPtr ioNamePtr;
+ short ioVRefNum;
+ short ioDstVRefNum;
+ short filler8;
+ StringPtr ioNewName;
+ StringPtr ioCopyName;
+ long ioNewDirID;
+ long filler14;
+ long filler15;
+ long ioDirID;
+};
+typedef struct CopyParam CopyParam;
+typedef CopyParam * CopyParamPtr;
+struct WDParam {
+ QElemPtr qLink;
+ short qType;
+ short ioTrap;
+ Ptr ioCmdAddr;
+ IOCompletionUPP ioCompletion;
+ volatile OSErr ioResult;
+ StringPtr ioNamePtr;
+ short ioVRefNum;
+ short ioWDCreated;
+ short ioWDIndex;
+ long ioWDProcID;
+ short ioWDVRefNum;
+ short filler10;
+ long filler11;
+ long filler12;
+ long filler13;
+ long ioWDDirID;
+};
+typedef struct WDParam WDParam;
+typedef WDParam * WDParamPtr;
+struct FIDParam {
+ QElemPtr qLink;
+ short qType;
+ short ioTrap;
+ Ptr ioCmdAddr;
+ IOCompletionUPP ioCompletion;
+ volatile OSErr ioResult;
+ StringPtr ioNamePtr;
+ short ioVRefNum;
+ long filler14;
+ StringPtr ioDestNamePtr;
+ long filler15;
+ long ioDestDirID;
+ long filler16;
+ long filler17;
+ long ioSrcDirID;
+ short filler18;
+ long ioFileID;
+};
+typedef struct FIDParam FIDParam;
+typedef FIDParam * FIDParamPtr;
+struct ForeignPrivParam {
+ QElemPtr qLink;
+ short qType;
+ short ioTrap;
+ Ptr ioCmdAddr;
+ IOCompletionUPP ioCompletion;
+ volatile OSErr ioResult;
+ StringPtr ioNamePtr;
+ short ioVRefNum;
+ long ioFiller21;
+ long ioFiller22;
+ Ptr ioForeignPrivBuffer;
+ long ioForeignPrivActCount;
+ long ioForeignPrivReqCount;
+ long ioFiller23;
+ long ioForeignPrivDirID;
+ long ioForeignPrivInfo1;
+ long ioForeignPrivInfo2;
+ long ioForeignPrivInfo3;
+ long ioForeignPrivInfo4;
+};
+typedef struct ForeignPrivParam ForeignPrivParam;
+typedef ForeignPrivParam * ForeignPrivParamPtr;
+struct CSParam {
+ QElemPtr qLink;
+ short qType;
+ short ioTrap;
+ Ptr ioCmdAddr;
+ IOCompletionUPP ioCompletion;
+ volatile OSErr ioResult;
+ StringPtr ioNamePtr;
+ short ioVRefNum;
+ FSSpecPtr ioMatchPtr;
+ long ioReqMatchCount;
+ long ioActMatchCount;
+ long ioSearchBits;
+ CInfoPBPtr ioSearchInfo1;
+ CInfoPBPtr ioSearchInfo2;
+ long ioSearchTime;
+ CatPositionRec ioCatPosition;
+ Ptr ioOptBuffer;
+ long ioOptBufSize;
+};
+typedef struct CSParam CSParam;
+typedef CSParam * CSParamPtr;
+union HParamBlockRec {
+ HIOParam ioParam;
+ HFileParam fileParam;
+ HVolumeParam volumeParam;
+ AccessParam accessParam;
+ ObjParam objParam;
+ CopyParam copyParam;
+ WDParam wdParam;
+ FIDParam fidParam;
+ CSParam csParam;
+ ForeignPrivParam foreignPrivParam;
+};
+typedef union HParamBlockRec HParamBlockRec;
+
+
+typedef HParamBlockRec * HParmBlkPtr;
+
+struct CMovePBRec {
+ QElemPtr qLink;
+ short qType;
+ short ioTrap;
+ Ptr ioCmdAddr;
+ IOCompletionUPP ioCompletion;
+ volatile OSErr ioResult;
+ StringPtr ioNamePtr;
+ short ioVRefNum;
+ long filler1;
+ StringPtr ioNewName;
+ long filler2;
+ long ioNewDirID;
+ long filler3[2];
+ long ioDirID;
+};
+typedef struct CMovePBRec CMovePBRec;
+typedef CMovePBRec * CMovePBPtr;
+struct WDPBRec {
+ QElemPtr qLink;
+ short qType;
+ short ioTrap;
+ Ptr ioCmdAddr;
+ IOCompletionUPP ioCompletion;
+ volatile OSErr ioResult;
+ StringPtr ioNamePtr;
+ short ioVRefNum;
+ short filler1;
+ short ioWDIndex;
+ long ioWDProcID;
+ short ioWDVRefNum;
+ short filler2[7];
+ long ioWDDirID;
+};
+typedef struct WDPBRec WDPBRec;
+typedef WDPBRec * WDPBPtr;
+struct FCBPBRec {
+ QElemPtr qLink;
+ short qType;
+ short ioTrap;
+ Ptr ioCmdAddr;
+ IOCompletionUPP ioCompletion;
+ volatile OSErr ioResult;
+ StringPtr ioNamePtr;
+ short ioVRefNum;
+ short ioRefNum;
+ short filler;
+ short ioFCBIndx;
+ short filler1;
+ long ioFCBFlNm;
+ short ioFCBFlags;
+ unsigned short ioFCBStBlk;
+ long ioFCBEOF;
+ long ioFCBPLen;
+ long ioFCBCrPs;
+ short ioFCBVRefNum;
+ long ioFCBClpSiz;
+ long ioFCBParID;
+};
+typedef struct FCBPBRec FCBPBRec;
+typedef FCBPBRec * FCBPBPtr;
+struct VCB {
+ QElemPtr qLink;
+ short qType;
+ short vcbFlags;
+ unsigned short vcbSigWord;
+ unsigned long vcbCrDate;
+ unsigned long vcbLsMod;
+ short vcbAtrb;
+ unsigned short vcbNmFls;
+ short vcbVBMSt;
+ short vcbAllocPtr;
+ unsigned short vcbNmAlBlks;
+ long vcbAlBlkSiz;
+ long vcbClpSiz;
+ short vcbAlBlSt;
+ long vcbNxtCNID;
+ unsigned short vcbFreeBks;
+ Str27 vcbVN;
+ short vcbDrvNum;
+ short vcbDRefNum;
+ short vcbFSID;
+ short vcbVRefNum;
+ Ptr vcbMAdr;
+ Ptr vcbBufAdr;
+ short vcbMLen;
+ short vcbDirIndex;
+ short vcbDirBlk;
+ unsigned long vcbVolBkUp;
+ unsigned short vcbVSeqNum;
+ long vcbWrCnt;
+ long vcbXTClpSiz;
+ long vcbCTClpSiz;
+ unsigned short vcbNmRtDirs;
+ long vcbFilCnt;
+ long vcbDirCnt;
+ long vcbFndrInfo[8];
+ unsigned short vcbVCSize;
+ unsigned short vcbVBMCSiz;
+ unsigned short vcbCtlCSiz;
+ unsigned short vcbXTAlBlks;
+ unsigned short vcbCTAlBlks;
+ short vcbXTRef;
+ short vcbCTRef;
+ Ptr vcbCtlBuf;
+ long vcbDirIDM;
+ short vcbOffsM;
+};
+typedef struct VCB VCB;
+typedef VCB * VCBPtr;
+struct DrvQEl {
+ QElemPtr qLink;
+ short qType;
+ short dQDrive;
+ short dQRefNum;
+ short dQFSID;
+ unsigned short dQDrvSz;
+ unsigned short dQDrvSz2;
+};
+typedef struct DrvQEl DrvQEl;
+typedef DrvQEl * DrvQElPtr;
+extern IOCompletionUPP
+NewIOCompletionUPP(IOCompletionProcPtr userRoutine) ;
+extern void
+DisposeIOCompletionUPP(IOCompletionUPP userUPP) ;
+extern void
+InvokeIOCompletionUPP(
+ ParmBlkPtr paramBlock,
+ IOCompletionUPP userUPP) ;
+extern OSErr PBXGetVolInfoSync(XVolumeParamPtr paramBlock) ;
+extern OSErr PBXGetVolInfoAsync(XVolumeParamPtr paramBlock) ;
+extern OSErr PBFlushVolSync(ParmBlkPtr paramBlock) ;
+extern OSErr PBFlushVolAsync(ParmBlkPtr paramBlock) ;
+extern OSErr PBAllocateSync(ParmBlkPtr paramBlock) ;
+extern OSErr PBAllocateAsync(ParmBlkPtr paramBlock) ;
+extern OSErr PBGetEOFSync(ParmBlkPtr paramBlock) ;
+extern OSErr PBGetEOFAsync(ParmBlkPtr paramBlock) ;
+extern OSErr PBSetEOFSync(ParmBlkPtr paramBlock) ;
+extern OSErr PBSetEOFAsync(ParmBlkPtr paramBlock) ;
+extern OSErr PBGetFPosSync(ParmBlkPtr paramBlock) ;
+extern OSErr PBGetFPosAsync(ParmBlkPtr paramBlock) ;
+extern OSErr PBSetFPosSync(ParmBlkPtr paramBlock) ;
+extern OSErr PBSetFPosAsync(ParmBlkPtr paramBlock) ;
+extern OSErr PBFlushFileSync(ParmBlkPtr paramBlock) ;
+extern OSErr PBFlushFileAsync(ParmBlkPtr paramBlock) ;
+extern OSErr PBUnmountVol(ParmBlkPtr paramBlock) ;
+extern OSErr PBCatSearchSync(CSParamPtr paramBlock) ;
+extern OSErr PBCatSearchAsync(CSParamPtr paramBlock) ;
+extern OSErr
+UnmountVol(
+ ConstStr63Param volName,
+ short vRefNum) ;
+extern OSErr
+FlushVol(
+ ConstStr63Param volName,
+ short vRefNum) ;
+extern OSErr
+HSetVol(
+ ConstStr63Param volName,
+ short vRefNum,
+ long dirID) ;
+extern OSErr
+FSClose(short refNum) ;
+extern OSErr
+FSRead(
+ short refNum,
+ long * count,
+ void * buffPtr) ;
+extern OSErr
+FSWrite(
+ short refNum,
+ long * count,
+ const void * buffPtr) ;
+extern OSErr
+Allocate(
+ short refNum,
+ long * count) ;
+extern OSErr
+GetEOF(
+ short refNum,
+ long * logEOF) ;
+extern OSErr
+SetEOF(
+ short refNum,
+ long logEOF) ;
+extern OSErr
+GetFPos(
+ short refNum,
+ long * filePos) ;
+extern OSErr
+SetFPos(
+ short refNum,
+ short posMode,
+ long posOff) ;
+extern OSErr
+GetVRefNum(
+ short fileRefNum,
+ short * vRefNum) ;
+extern OSErr PBHSetVolSync(WDPBPtr paramBlock) ;
+extern OSErr PBHSetVolAsync(WDPBPtr paramBlock) ;
+extern OSErr PBHGetVolSync(WDPBPtr paramBlock) ;
+extern OSErr PBHGetVolAsync(WDPBPtr paramBlock) ;
+extern OSErr PBCatMoveSync(CMovePBPtr paramBlock) ;
+extern OSErr PBCatMoveAsync(CMovePBPtr paramBlock) ;
+extern OSErr PBDirCreateSync(HParmBlkPtr paramBlock) ;
+extern OSErr PBDirCreateAsync(HParmBlkPtr paramBlock) ;
+extern OSErr PBGetFCBInfoSync(FCBPBPtr paramBlock) ;
+extern OSErr PBGetFCBInfoAsync(FCBPBPtr paramBlock) ;
+extern OSErr PBGetCatInfoSync(CInfoPBPtr paramBlock) ;
+extern OSErr PBGetCatInfoAsync(CInfoPBPtr paramBlock) ;
+extern OSErr PBSetCatInfoSync(CInfoPBPtr paramBlock) ;
+extern OSErr PBSetCatInfoAsync(CInfoPBPtr paramBlock) ;
+extern OSErr PBAllocContigSync(ParmBlkPtr paramBlock) ;
+extern OSErr PBAllocContigAsync(ParmBlkPtr paramBlock) ;
+extern OSErr PBLockRangeSync(ParmBlkPtr paramBlock) ;
+extern OSErr PBLockRangeAsync(ParmBlkPtr paramBlock) ;
+extern OSErr PBUnlockRangeSync(ParmBlkPtr paramBlock) ;
+extern OSErr PBUnlockRangeAsync(ParmBlkPtr paramBlock) ;
+extern OSErr PBSetVInfoSync(HParmBlkPtr paramBlock) ;
+extern OSErr PBSetVInfoAsync(HParmBlkPtr paramBlock) ;
+extern OSErr PBHGetVInfoSync(HParmBlkPtr paramBlock) ;
+extern OSErr PBHGetVInfoAsync(HParmBlkPtr paramBlock) ;
+extern OSErr PBHOpenSync(HParmBlkPtr paramBlock) ;
+extern OSErr PBHOpenAsync(HParmBlkPtr paramBlock) ;
+extern OSErr PBHOpenRFSync(HParmBlkPtr paramBlock) ;
+extern OSErr PBHOpenRFAsync(HParmBlkPtr paramBlock) ;
+extern OSErr PBHOpenDFSync(HParmBlkPtr paramBlock) ;
+extern OSErr PBHOpenDFAsync(HParmBlkPtr paramBlock) ;
+extern OSErr PBHCreateSync(HParmBlkPtr paramBlock) ;
+extern OSErr PBHCreateAsync(HParmBlkPtr paramBlock) ;
+extern OSErr PBHDeleteSync(HParmBlkPtr paramBlock) ;
+extern OSErr PBHDeleteAsync(HParmBlkPtr paramBlock) ;
+extern OSErr PBHRenameSync(HParmBlkPtr paramBlock) ;
+extern OSErr PBHRenameAsync(HParmBlkPtr paramBlock) ;
+extern OSErr PBHRstFLockSync(HParmBlkPtr paramBlock) ;
+extern OSErr PBHRstFLockAsync(HParmBlkPtr paramBlock) ;
+extern OSErr PBHSetFLockSync(HParmBlkPtr paramBlock) ;
+extern OSErr PBHSetFLockAsync(HParmBlkPtr paramBlock) ;
+extern OSErr PBHGetFInfoSync(HParmBlkPtr paramBlock) ;
+extern OSErr PBHGetFInfoAsync(HParmBlkPtr paramBlock) ;
+extern OSErr PBHSetFInfoSync(HParmBlkPtr paramBlock) ;
+extern OSErr PBHSetFInfoAsync(HParmBlkPtr paramBlock) ;
+extern OSErr PBMakeFSSpecSync(HParmBlkPtr paramBlock) ;
+extern OSErr PBMakeFSSpecAsync(HParmBlkPtr paramBlock) ;
+extern OSErr
+HGetVol(
+ StringPtr volName,
+ short * vRefNum,
+ long * dirID) ;
+extern OSErr
+HOpen(
+ short vRefNum,
+ long dirID,
+ ConstStr255Param fileName,
+ SInt8 permission,
+ short * refNum) ;
+extern OSErr
+HOpenDF(
+ short vRefNum,
+ long dirID,
+ ConstStr255Param fileName,
+ SInt8 permission,
+ short * refNum) ;
+extern OSErr
+HOpenRF(
+ short vRefNum,
+ long dirID,
+ ConstStr255Param fileName,
+ SInt8 permission,
+ short * refNum) ;
+extern OSErr
+AllocContig(
+ short refNum,
+ long * count) ;
+extern OSErr
+HCreate(
+ short vRefNum,
+ long dirID,
+ ConstStr255Param fileName,
+ OSType creator,
+ OSType fileType) ;
+extern OSErr
+DirCreate(
+ short vRefNum,
+ long parentDirID,
+ ConstStr255Param directoryName,
+ long * createdDirID) ;
+extern OSErr
+HDelete(
+ short vRefNum,
+ long dirID,
+ ConstStr255Param fileName) ;
+extern OSErr
+HGetFInfo(
+ short vRefNum,
+ long dirID,
+ ConstStr255Param fileName,
+ FInfo * fndrInfo) ;
+extern OSErr
+HSetFInfo(
+ short vRefNum,
+ long dirID,
+ ConstStr255Param fileName,
+ const FInfo * fndrInfo) ;
+extern OSErr
+HSetFLock(
+ short vRefNum,
+ long dirID,
+ ConstStr255Param fileName) ;
+extern OSErr
+HRstFLock(
+ short vRefNum,
+ long dirID,
+ ConstStr255Param fileName) ;
+extern OSErr
+HRename(
+ short vRefNum,
+ long dirID,
+ ConstStr255Param oldName,
+ ConstStr255Param newName) ;
+extern OSErr
+CatMove(
+ short vRefNum,
+ long dirID,
+ ConstStr255Param oldName,
+ long newDirID,
+ ConstStr255Param newName) ;
+extern OSErr PBHGetVolParmsSync(HParmBlkPtr paramBlock) ;
+extern OSErr PBHGetVolParmsAsync(HParmBlkPtr paramBlock) ;
+extern OSErr PBHGetLogInInfoSync(HParmBlkPtr paramBlock) ;
+extern OSErr PBHGetLogInInfoAsync(HParmBlkPtr paramBlock) ;
+extern OSErr PBHGetDirAccessSync(HParmBlkPtr paramBlock) ;
+extern OSErr PBHGetDirAccessAsync(HParmBlkPtr paramBlock) ;
+extern OSErr PBHSetDirAccessSync(HParmBlkPtr paramBlock) ;
+extern OSErr PBHSetDirAccessAsync(HParmBlkPtr paramBlock) ;
+extern OSErr PBHMapIDSync(HParmBlkPtr paramBlock) ;
+extern OSErr PBHMapIDAsync(HParmBlkPtr paramBlock) ;
+extern OSErr PBHMapNameSync(HParmBlkPtr paramBlock) ;
+extern OSErr PBHMapNameAsync(HParmBlkPtr paramBlock) ;
+extern OSErr PBHCopyFileSync(HParmBlkPtr paramBlock) ;
+extern OSErr PBHCopyFileAsync(HParmBlkPtr paramBlock) ;
+extern OSErr PBHMoveRenameSync(HParmBlkPtr paramBlock) ;
+extern OSErr PBHMoveRenameAsync(HParmBlkPtr paramBlock) ;
+extern OSErr PBHOpenDenySync(HParmBlkPtr paramBlock) ;
+extern OSErr PBHOpenDenyAsync(HParmBlkPtr paramBlock) ;
+extern OSErr PBHOpenRFDenySync(HParmBlkPtr paramBlock) ;
+extern OSErr PBHOpenRFDenyAsync(HParmBlkPtr paramBlock) ;
+extern OSErr PBGetXCatInfoSync(XCInfoPBPtr paramBlock) ;
+extern OSErr PBGetXCatInfoAsync(XCInfoPBPtr paramBlock) ;
+extern OSErr PBExchangeFilesSync(HParmBlkPtr paramBlock) ;
+extern OSErr PBExchangeFilesAsync(HParmBlkPtr paramBlock) ;
+extern OSErr PBCreateFileIDRefSync(HParmBlkPtr paramBlock) ;
+extern OSErr PBCreateFileIDRefAsync(HParmBlkPtr paramBlock) ;
+extern OSErr PBResolveFileIDRefSync(HParmBlkPtr paramBlock) ;
+extern OSErr PBResolveFileIDRefAsync(HParmBlkPtr paramBlock) ;
+extern OSErr PBDeleteFileIDRefSync(HParmBlkPtr paramBlock) ;
+extern OSErr PBDeleteFileIDRefAsync(HParmBlkPtr paramBlock) ;
+extern OSErr PBGetForeignPrivsSync(HParmBlkPtr paramBlock) ;
+extern OSErr PBGetForeignPrivsAsync(HParmBlkPtr paramBlock) ;
+extern OSErr PBSetForeignPrivsSync(HParmBlkPtr paramBlock) ;
+extern OSErr PBSetForeignPrivsAsync(HParmBlkPtr paramBlock) ;
+extern OSErr PBDTGetPath(DTPBPtr paramBlock) ;
+extern OSErr PBDTCloseDown(DTPBPtr paramBlock) ;
+extern OSErr PBDTAddIconSync(DTPBPtr paramBlock) ;
+extern OSErr PBDTAddIconAsync(DTPBPtr paramBlock) ;
+extern OSErr PBDTGetIconSync(DTPBPtr paramBlock) ;
+extern OSErr PBDTGetIconAsync(DTPBPtr paramBlock) ;
+extern OSErr PBDTGetIconInfoSync(DTPBPtr paramBlock) ;
+extern OSErr PBDTGetIconInfoAsync(DTPBPtr paramBlock) ;
+extern OSErr PBDTAddAPPLSync(DTPBPtr paramBlock) ;
+extern OSErr PBDTAddAPPLAsync(DTPBPtr paramBlock) ;
+extern OSErr PBDTRemoveAPPLSync(DTPBPtr paramBlock) ;
+extern OSErr PBDTRemoveAPPLAsync(DTPBPtr paramBlock) ;
+extern OSErr PBDTGetAPPLSync(DTPBPtr paramBlock) ;
+extern OSErr PBDTGetAPPLAsync(DTPBPtr paramBlock) ;
+extern OSErr PBDTSetCommentSync(DTPBPtr paramBlock) ;
+extern OSErr PBDTSetCommentAsync(DTPBPtr paramBlock) ;
+extern OSErr PBDTRemoveCommentSync(DTPBPtr paramBlock) ;
+extern OSErr PBDTRemoveCommentAsync(DTPBPtr paramBlock) ;
+extern OSErr PBDTGetCommentSync(DTPBPtr paramBlock) ;
+extern OSErr PBDTGetCommentAsync(DTPBPtr paramBlock) ;
+extern OSErr PBDTFlushSync(DTPBPtr paramBlock) ;
+extern OSErr PBDTFlushAsync(DTPBPtr paramBlock) ;
+extern OSErr PBDTResetSync(DTPBPtr paramBlock) ;
+extern OSErr PBDTResetAsync(DTPBPtr paramBlock) ;
+extern OSErr PBDTGetInfoSync(DTPBPtr paramBlock) ;
+extern OSErr PBDTGetInfoAsync(DTPBPtr paramBlock) ;
+extern OSErr PBDTOpenInform(DTPBPtr paramBlock) ;
+extern OSErr PBDTDeleteSync(DTPBPtr paramBlock) ;
+extern OSErr PBDTDeleteAsync(DTPBPtr paramBlock) ;
+extern OSErr PBGetVolMountInfoSize(ParmBlkPtr paramBlock) ;
+extern OSErr PBGetVolMountInfo(ParmBlkPtr paramBlock) ;
+extern OSErr PBVolumeMount(ParmBlkPtr paramBlock) ;
+extern OSErr
+FSMakeFSSpec(
+ short vRefNum,
+ long dirID,
+ ConstStr255Param fileName,
+ FSSpec * spec) ;
+extern OSErr
+FSpOpenDF(
+ const FSSpec * spec,
+ SInt8 permission,
+ short * refNum) ;
+extern OSErr
+FSpOpenRF(
+ const FSSpec * spec,
+ SInt8 permission,
+ short * refNum) ;
+extern OSErr
+FSpCreate(
+ const FSSpec * spec,
+ OSType creator,
+ OSType fileType,
+ ScriptCode scriptTag) ;
+extern OSErr
+FSpDirCreate(
+ const FSSpec * spec,
+ ScriptCode scriptTag,
+ long * createdDirID) ;
+extern OSErr
+FSpDelete(const FSSpec * spec) ;
+extern OSErr
+FSpGetFInfo(
+ const FSSpec * spec,
+ FInfo * fndrInfo) ;
+extern OSErr
+FSpSetFInfo(
+ const FSSpec * spec,
+ const FInfo * fndrInfo) ;
+extern OSErr
+FSpSetFLock(const FSSpec * spec) ;
+extern OSErr
+FSpRstFLock(const FSSpec * spec) ;
+extern OSErr
+FSpRename(
+ const FSSpec * spec,
+ ConstStr255Param newName) ;
+extern OSErr
+FSpCatMove(
+ const FSSpec * source,
+ const FSSpec * dest) ;
+extern OSErr
+FSpExchangeFiles(
+ const FSSpec * source,
+ const FSSpec * dest) ;
+extern OSErr PBShareSync(HParmBlkPtr paramBlock) ;
+extern OSErr PBShareAsync(HParmBlkPtr paramBlock) ;
+extern OSErr PBUnshareSync(HParmBlkPtr paramBlock) ;
+extern OSErr PBUnshareAsync(HParmBlkPtr paramBlock) ;
+extern OSErr PBGetUGEntrySync(HParmBlkPtr paramBlock) ;
+extern OSErr PBGetUGEntryAsync(HParmBlkPtr paramBlock) ;
+typedef SInt16 FSVolumeRefNum;
+enum {
+ kFSInvalidVolumeRefNum = 0
+};
+
+struct FSRef {
+ UInt8 hidden[80];
+};
+typedef struct FSRef FSRef;
+typedef FSRef * FSRefPtr;
+struct FSPermissionInfo {
+ UInt32 userID;
+ UInt32 groupID;
+ UInt8 reserved1;
+ UInt8 userAccess;
+ UInt16 mode;
+ UInt32 reserved2;
+};
+typedef struct FSPermissionInfo FSPermissionInfo;
+
+
+typedef UInt32 FSCatalogInfoBitmap;
+enum {
+ kFSCatInfoNone = 0x00000000,
+ kFSCatInfoTextEncoding = 0x00000001,
+ kFSCatInfoNodeFlags = 0x00000002,
+ kFSCatInfoVolume = 0x00000004,
+ kFSCatInfoParentDirID = 0x00000008,
+ kFSCatInfoNodeID = 0x00000010,
+ kFSCatInfoCreateDate = 0x00000020,
+ kFSCatInfoContentMod = 0x00000040,
+ kFSCatInfoAttrMod = 0x00000080,
+ kFSCatInfoAccessDate = 0x00000100,
+ kFSCatInfoBackupDate = 0x00000200,
+ kFSCatInfoPermissions = 0x00000400,
+ kFSCatInfoFinderInfo = 0x00000800,
+ kFSCatInfoFinderXInfo = 0x00001000,
+ kFSCatInfoValence = 0x00002000,
+ kFSCatInfoDataSizes = 0x00004000,
+ kFSCatInfoRsrcSizes = 0x00008000,
+ kFSCatInfoSharingFlags = 0x00010000,
+ kFSCatInfoUserPrivs = 0x00020000,
+ kFSCatInfoUserAccess = 0x00080000,
+ kFSCatInfoAllDates = 0x000003E0,
+ kFSCatInfoGettableInfo = 0x0003FFFF,
+ kFSCatInfoSettableInfo = 0x00001FE3,
+ kFSCatInfoReserved = (long)0xFFFC0000
+};
+
+
+enum {
+ kFSNodeLockedBit = 0,
+ kFSNodeLockedMask = 0x0001,
+ kFSNodeResOpenBit = 2,
+ kFSNodeResOpenMask = 0x0004,
+ kFSNodeDataOpenBit = 3,
+ kFSNodeDataOpenMask = 0x0008,
+ kFSNodeIsDirectoryBit = 4,
+ kFSNodeIsDirectoryMask = 0x0010,
+ kFSNodeCopyProtectBit = 6,
+ kFSNodeCopyProtectMask = 0x0040,
+ kFSNodeForkOpenBit = 7,
+ kFSNodeForkOpenMask = 0x0080,
+ kFSNodeHardLinkBit = 8,
+ kFSNodeHardLinkMask = 0x00000100
+};
+
+
+enum {
+ kFSNodeInSharedBit = 2,
+ kFSNodeInSharedMask = 0x0004,
+ kFSNodeIsMountedBit = 3,
+ kFSNodeIsMountedMask = 0x0008,
+ kFSNodeIsSharePointBit = 5,
+ kFSNodeIsSharePointMask = 0x0020
+};
+
+
+struct FSCatalogInfo {
+ UInt16 nodeFlags;
+ FSVolumeRefNum volume;
+ UInt32 parentDirID;
+ UInt32 nodeID;
+ UInt8 sharingFlags;
+ UInt8 userPrivileges;
+ UInt8 reserved1;
+ UInt8 reserved2;
+ UTCDateTime createDate;
+ UTCDateTime contentModDate;
+ UTCDateTime attributeModDate;
+ UTCDateTime accessDate;
+ UTCDateTime backupDate;
+
+ UInt32 permissions[4];
+
+ UInt8 finderInfo[16];
+ UInt8 extFinderInfo[16];
+
+ UInt64 dataLogicalSize;
+ UInt64 dataPhysicalSize;
+ UInt64 rsrcLogicalSize;
+ UInt64 rsrcPhysicalSize;
+
+ UInt32 valence;
+ TextEncoding textEncodingHint;
+};
+typedef struct FSCatalogInfo FSCatalogInfo;
+typedef FSCatalogInfo * FSCatalogInfoPtr;
+struct FSRefParam {
+ QElemPtr qLink;
+ short qType;
+ short ioTrap;
+ Ptr ioCmdAddr;
+ IOCompletionUPP ioCompletion;
+ volatile OSErr ioResult;
+ ConstStringPtr ioNamePtr;
+ short ioVRefNum;
+
+ SInt16 reserved1;
+ UInt8 reserved2;
+ UInt8 reserved3;
+
+ const FSRef * ref;
+ FSCatalogInfoBitmap whichInfo;
+ FSCatalogInfo * catInfo;
+ UniCharCount nameLength;
+ const UniChar * name;
+ long ioDirID;
+ FSSpec * spec;
+ FSRef * parentRef;
+ FSRef * newRef;
+ TextEncoding textEncodingHint;
+ HFSUniStr255 * outName;
+};
+typedef struct FSRefParam FSRefParam;
+typedef FSRefParam * FSRefParamPtr;
+typedef struct OpaqueFSIterator* FSIterator;
+enum {
+ kFSIterateFlat = 0,
+ kFSIterateSubtree = 1,
+ kFSIterateDelete = 2,
+ kFSIterateReserved = (long)0xFFFFFFFC
+};
+
+typedef OptionBits FSIteratorFlags;
+enum {
+
+ fsSBNodeID = 0x00008000,
+ fsSBAttributeModDate = 0x00010000,
+ fsSBAccessDate = 0x00020000,
+ fsSBPermissions = 0x00040000,
+ fsSBNodeIDBit = 15,
+ fsSBAttributeModDateBit = 16,
+ fsSBAccessDateBit = 17,
+ fsSBPermissionsBit = 18
+};
+
+struct FSSearchParams {
+ Duration searchTime;
+ OptionBits searchBits;
+ UniCharCount searchNameLength;
+ const UniChar * searchName;
+ FSCatalogInfo * searchInfo1;
+ FSCatalogInfo * searchInfo2;
+};
+typedef struct FSSearchParams FSSearchParams;
+typedef FSSearchParams * FSSearchParamsPtr;
+struct FSCatalogBulkParam {
+ QElemPtr qLink;
+ short qType;
+ short ioTrap;
+ Ptr ioCmdAddr;
+ IOCompletionUPP ioCompletion;
+ volatile OSErr ioResult;
+ Boolean containerChanged;
+ UInt8 reserved;
+
+ FSIteratorFlags iteratorFlags;
+ FSIterator iterator;
+ const FSRef * container;
+ ItemCount maximumItems;
+ ItemCount actualItems;
+ FSCatalogInfoBitmap whichInfo;
+ FSCatalogInfo * catalogInfo;
+ FSRef * refs;
+ FSSpec * specs;
+ HFSUniStr255 * names;
+ const FSSearchParams * searchParams;
+};
+typedef struct FSCatalogBulkParam FSCatalogBulkParam;
+typedef FSCatalogBulkParam * FSCatalogBulkParamPtr;
+typedef UInt16 FSAllocationFlags;
+enum {
+ kFSAllocDefaultFlags = 0x0000,
+ kFSAllocAllOrNothingMask = 0x0001,
+ kFSAllocContiguousMask = 0x0002,
+ kFSAllocNoRoundUpMask = 0x0004,
+ kFSAllocReservedMask = 0xFFF8
+};
+
+struct FSForkIOParam {
+ QElemPtr qLink;
+ short qType;
+ short ioTrap;
+ Ptr ioCmdAddr;
+ IOCompletionUPP ioCompletion;
+ volatile OSErr ioResult;
+ void * reserved1;
+ SInt16 reserved2;
+ SInt16 forkRefNum;
+ UInt8 reserved3;
+ SInt8 permissions;
+ const FSRef * ref;
+
+
+ Ptr buffer;
+ UInt32 requestCount;
+ UInt32 actualCount;
+ UInt16 positionMode;
+ SInt64 positionOffset;
+
+ FSAllocationFlags allocationFlags;
+ UInt64 allocationAmount;
+
+ UniCharCount forkNameLength;
+ const UniChar * forkName;
+
+ CatPositionRec forkIterator;
+ HFSUniStr255 * outForkName;
+};
+typedef struct FSForkIOParam FSForkIOParam;
+typedef FSForkIOParam * FSForkIOParamPtr;
+struct FSForkInfo {
+ SInt8 flags;
+ SInt8 permissions;
+ FSVolumeRefNum volume;
+ UInt32 reserved2;
+ UInt32 nodeID;
+ UInt32 forkID;
+ UInt64 currentPosition;
+ UInt64 logicalEOF;
+ UInt64 physicalEOF;
+ UInt64 process;
+};
+typedef struct FSForkInfo FSForkInfo;
+typedef FSForkInfo * FSForkInfoPtr;
+struct FSForkCBInfoParam {
+ QElemPtr qLink;
+ short qType;
+ short ioTrap;
+ Ptr ioCmdAddr;
+ IOCompletionUPP ioCompletion;
+ volatile OSErr ioResult;
+ SInt16 desiredRefNum;
+ SInt16 volumeRefNum;
+ SInt16 iterator;
+ SInt16 actualRefNum;
+
+ FSRef * ref;
+ FSForkInfo * forkInfo;
+ HFSUniStr255 * forkName;
+};
+typedef struct FSForkCBInfoParam FSForkCBInfoParam;
+typedef FSForkCBInfoParam * FSForkCBInfoParamPtr;
+typedef UInt32 FSVolumeInfoBitmap;
+enum {
+ kFSVolInfoNone = 0x0000,
+ kFSVolInfoCreateDate = 0x0001,
+ kFSVolInfoModDate = 0x0002,
+ kFSVolInfoBackupDate = 0x0004,
+ kFSVolInfoCheckedDate = 0x0008,
+ kFSVolInfoFileCount = 0x0010,
+ kFSVolInfoDirCount = 0x0020,
+ kFSVolInfoSizes = 0x0040,
+ kFSVolInfoBlocks = 0x0080,
+ kFSVolInfoNextAlloc = 0x0100,
+ kFSVolInfoRsrcClump = 0x0200,
+ kFSVolInfoDataClump = 0x0400,
+ kFSVolInfoNextID = 0x0800,
+ kFSVolInfoFinderInfo = 0x1000,
+ kFSVolInfoFlags = 0x2000,
+ kFSVolInfoFSInfo = 0x4000,
+ kFSVolInfoDriveInfo = 0x8000,
+ kFSVolInfoGettableInfo = 0xFFFF,
+ kFSVolInfoSettableInfo = 0x3004
+};
+
+
+enum {
+ kFSVolFlagDefaultVolumeBit = 5,
+ kFSVolFlagDefaultVolumeMask = 0x0020,
+ kFSVolFlagFilesOpenBit = 6,
+ kFSVolFlagFilesOpenMask = 0x0040,
+ kFSVolFlagHardwareLockedBit = 7,
+ kFSVolFlagHardwareLockedMask = 0x0080,
+ kFSVolFlagSoftwareLockedBit = 15,
+ kFSVolFlagSoftwareLockedMask = 0x8000
+};
+
+
+struct FSVolumeInfo {
+
+ UTCDateTime createDate;
+ UTCDateTime modifyDate;
+ UTCDateTime backupDate;
+ UTCDateTime checkedDate;
+
+
+ UInt32 fileCount;
+ UInt32 folderCount;
+
+
+ UInt64 totalBytes;
+ UInt64 freeBytes;
+
+
+ UInt32 blockSize;
+ UInt32 totalBlocks;
+ UInt32 freeBlocks;
+ UInt32 nextAllocation;
+ UInt32 rsrcClumpSize;
+ UInt32 dataClumpSize;
+ UInt32 nextCatalogID;
+ UInt8 finderInfo[32];
+
+
+ UInt16 flags;
+ UInt16 filesystemID;
+ UInt16 signature;
+ UInt16 driveNumber;
+ short driverRefNum;
+};
+typedef struct FSVolumeInfo FSVolumeInfo;
+typedef FSVolumeInfo * FSVolumeInfoPtr;
+struct FSVolumeInfoParam {
+ QElemPtr qLink;
+ short qType;
+ short ioTrap;
+ Ptr ioCmdAddr;
+ IOCompletionUPP ioCompletion;
+ volatile OSErr ioResult;
+ StringPtr ioNamePtr;
+ FSVolumeRefNum ioVRefNum;
+
+ UInt32 volumeIndex;
+ FSVolumeInfoBitmap whichInfo;
+ FSVolumeInfo * volumeInfo;
+ HFSUniStr255 * volumeName;
+ FSRef * ref;
+};
+typedef struct FSVolumeInfoParam FSVolumeInfoParam;
+typedef FSVolumeInfoParam * FSVolumeInfoParamPtr;
+extern OSErr
+FSpMakeFSRef(
+ const FSSpec * source,
+ FSRef * newRef) ;
+extern OSErr
+PBMakeFSRefSync(FSRefParam * paramBlock) ;
+extern void
+PBMakeFSRefAsync(FSRefParam * paramBlock) ;
+extern OSErr
+FSMakeFSRefUnicode(
+ const FSRef * parentRef,
+ UniCharCount nameLength,
+ const UniChar * name,
+ TextEncoding textEncodingHint,
+ FSRef * newRef) ;
+extern OSErr
+PBMakeFSRefUnicodeSync(FSRefParam * paramBlock) ;
+extern void
+PBMakeFSRefUnicodeAsync(FSRefParam * paramBlock) ;
+extern OSErr
+FSCompareFSRefs(
+ const FSRef * ref1,
+ const FSRef * ref2) ;
+extern OSErr
+PBCompareFSRefsSync(FSRefParam * paramBlock) ;
+extern void
+PBCompareFSRefsAsync(FSRefParam * paramBlock) ;
+extern OSErr
+FSCreateFileUnicode(
+ const FSRef * parentRef,
+ UniCharCount nameLength,
+ const UniChar * name,
+ FSCatalogInfoBitmap whichInfo,
+ const FSCatalogInfo * catalogInfo,
+ FSRef * newRef,
+ FSSpec * newSpec) ;
+extern OSErr
+PBCreateFileUnicodeSync(FSRefParam * paramBlock) ;
+extern void
+PBCreateFileUnicodeAsync(FSRefParam * paramBlock) ;
+extern OSErr
+FSCreateDirectoryUnicode(
+ const FSRef * parentRef,
+ UniCharCount nameLength,
+ const UniChar * name,
+ FSCatalogInfoBitmap whichInfo,
+ const FSCatalogInfo * catalogInfo,
+ FSRef * newRef,
+ FSSpec * newSpec,
+ UInt32 * newDirID) ;
+extern OSErr
+PBCreateDirectoryUnicodeSync(FSRefParam * paramBlock) ;
+extern void
+PBCreateDirectoryUnicodeAsync(FSRefParam * paramBlock) ;
+extern OSErr
+FSDeleteObject(const FSRef * ref) ;
+extern OSErr
+PBDeleteObjectSync(FSRefParam * paramBlock) ;
+extern void
+PBDeleteObjectAsync(FSRefParam * paramBlock) ;
+extern OSErr
+FSMoveObject(
+ const FSRef * ref,
+ const FSRef * destDirectory,
+ FSRef * newRef) ;
+extern OSErr
+PBMoveObjectSync(FSRefParam * paramBlock) ;
+extern void
+PBMoveObjectAsync(FSRefParam * paramBlock) ;
+extern OSErr
+FSExchangeObjects(
+ const FSRef * ref,
+ const FSRef * destRef) ;
+extern OSErr
+PBExchangeObjectsSync(FSRefParam * paramBlock) ;
+extern void
+PBExchangeObjectsAsync(FSRefParam * paramBlock) ;
+extern OSErr
+FSRenameUnicode(
+ const FSRef * ref,
+ UniCharCount nameLength,
+ const UniChar * name,
+ TextEncoding textEncodingHint,
+ FSRef * newRef) ;
+extern OSErr
+PBRenameUnicodeSync(FSRefParam * paramBlock) ;
+extern void
+PBRenameUnicodeAsync(FSRefParam * paramBlock) ;
+extern OSErr
+FSGetCatalogInfo(
+ const FSRef * ref,
+ FSCatalogInfoBitmap whichInfo,
+ FSCatalogInfo * catalogInfo,
+ HFSUniStr255 * outName,
+ FSSpec * fsSpec,
+ FSRef * parentRef) ;
+extern OSErr
+PBGetCatalogInfoSync(FSRefParam * paramBlock) ;
+extern void
+PBGetCatalogInfoAsync(FSRefParam * paramBlock) ;
+extern OSErr
+FSSetCatalogInfo(
+ const FSRef * ref,
+ FSCatalogInfoBitmap whichInfo,
+ const FSCatalogInfo * catalogInfo) ;
+extern OSErr
+PBSetCatalogInfoSync(FSRefParam * paramBlock) ;
+extern void
+PBSetCatalogInfoAsync(FSRefParam * paramBlock) ;
+extern OSErr
+FSOpenIterator(
+ const FSRef * container,
+ FSIteratorFlags iteratorFlags,
+ FSIterator * iterator) ;
+extern OSErr
+PBOpenIteratorSync(FSCatalogBulkParam * paramBlock) ;
+extern void
+PBOpenIteratorAsync(FSCatalogBulkParam * paramBlock) ;
+extern OSErr
+FSCloseIterator(FSIterator iterator) ;
+extern OSErr
+PBCloseIteratorSync(FSCatalogBulkParam * paramBlock) ;
+extern void
+PBCloseIteratorAsync(FSCatalogBulkParam * paramBlock) ;
+extern OSErr
+FSGetCatalogInfoBulk(
+ FSIterator iterator,
+ ItemCount maximumObjects,
+ ItemCount * actualObjects,
+ Boolean * containerChanged,
+ FSCatalogInfoBitmap whichInfo,
+ FSCatalogInfo * catalogInfos,
+ FSRef * refs,
+ FSSpec * specs,
+ HFSUniStr255 * names) ;
+extern OSErr
+PBGetCatalogInfoBulkSync(FSCatalogBulkParam * paramBlock) ;
+extern void
+PBGetCatalogInfoBulkAsync(FSCatalogBulkParam * paramBlock) ;
+extern OSErr
+FSCatalogSearch(
+ FSIterator iterator,
+ const FSSearchParams * searchCriteria,
+ ItemCount maximumObjects,
+ ItemCount * actualObjects,
+ Boolean * containerChanged,
+ FSCatalogInfoBitmap whichInfo,
+ FSCatalogInfo * catalogInfos,
+ FSRef * refs,
+ FSSpec * specs,
+ HFSUniStr255 * names) ;
+extern OSErr
+PBCatalogSearchSync(FSCatalogBulkParam * paramBlock) ;
+extern void
+PBCatalogSearchAsync(FSCatalogBulkParam * paramBlock) ;
+extern OSErr
+FSCreateFork(
+ const FSRef * ref,
+ UniCharCount forkNameLength,
+ const UniChar * forkName) ;
+extern OSErr
+PBCreateForkSync(FSForkIOParam * paramBlock) ;
+extern void
+PBCreateForkAsync(FSForkIOParam * paramBlock) ;
+extern OSErr
+FSDeleteFork(
+ const FSRef * ref,
+ UniCharCount forkNameLength,
+ const UniChar * forkName) ;
+extern OSErr
+PBDeleteForkSync(FSForkIOParam * paramBlock) ;
+extern void
+PBDeleteForkAsync(FSForkIOParam * paramBlock) ;
+extern OSErr
+FSIterateForks(
+ const FSRef * ref,
+ CatPositionRec * forkIterator,
+ HFSUniStr255 * forkName,
+ SInt64 * forkSize,
+ UInt64 * forkPhysicalSize) ;
+extern OSErr
+PBIterateForksSync(FSForkIOParam * paramBlock) ;
+extern void
+PBIterateForksAsync(FSForkIOParam * paramBlock) ;
+extern OSErr
+FSOpenFork(
+ const FSRef * ref,
+ UniCharCount forkNameLength,
+ const UniChar * forkName,
+ SInt8 permissions,
+ SInt16 * forkRefNum) ;
+extern OSErr
+PBOpenForkSync(FSForkIOParam * paramBlock) ;
+extern void
+PBOpenForkAsync(FSForkIOParam * paramBlock) ;
+extern OSErr
+FSReadFork(
+ SInt16 forkRefNum,
+ UInt16 positionMode,
+ SInt64 positionOffset,
+ ByteCount requestCount,
+ void * buffer,
+ ByteCount * actualCount) ;
+extern OSErr
+PBReadForkSync(FSForkIOParam * paramBlock) ;
+extern void
+PBReadForkAsync(FSForkIOParam * paramBlock) ;
+extern OSErr
+FSWriteFork(
+ SInt16 forkRefNum,
+ UInt16 positionMode,
+ SInt64 positionOffset,
+ ByteCount requestCount,
+ const void * buffer,
+ ByteCount * actualCount) ;
+extern OSErr
+PBWriteForkSync(FSForkIOParam * paramBlock) ;
+extern void
+PBWriteForkAsync(FSForkIOParam * paramBlock) ;
+extern OSErr
+FSGetForkPosition(
+ SInt16 forkRefNum,
+ SInt64 * position) ;
+extern OSErr
+PBGetForkPositionSync(FSForkIOParam * paramBlock) ;
+extern void
+PBGetForkPositionAsync(FSForkIOParam * paramBlock) ;
+extern OSErr
+FSSetForkPosition(
+ SInt16 forkRefNum,
+ UInt16 positionMode,
+ SInt64 positionOffset) ;
+extern OSErr
+PBSetForkPositionSync(FSForkIOParam * paramBlock) ;
+extern void
+PBSetForkPositionAsync(FSForkIOParam * paramBlock) ;
+extern OSErr
+FSGetForkSize(
+ SInt16 forkRefNum,
+ SInt64 * forkSize) ;
+extern OSErr
+PBGetForkSizeSync(FSForkIOParam * paramBlock) ;
+extern void
+PBGetForkSizeAsync(FSForkIOParam * paramBlock) ;
+extern OSErr
+FSSetForkSize(
+ SInt16 forkRefNum,
+ UInt16 positionMode,
+ SInt64 positionOffset) ;
+extern OSErr
+PBSetForkSizeSync(FSForkIOParam * paramBlock) ;
+extern void
+PBSetForkSizeAsync(FSForkIOParam * paramBlock) ;
+extern OSErr
+FSAllocateFork(
+ SInt16 forkRefNum,
+ FSAllocationFlags flags,
+ UInt16 positionMode,
+ SInt64 positionOffset,
+ UInt64 requestCount,
+ UInt64 * actualCount) ;
+extern OSErr
+PBAllocateForkSync(FSForkIOParam * paramBlock) ;
+extern void
+PBAllocateForkAsync(FSForkIOParam * paramBlock) ;
+extern OSErr
+FSFlushFork(SInt16 forkRefNum) ;
+extern OSErr
+PBFlushForkSync(FSForkIOParam * paramBlock) ;
+extern void
+PBFlushForkAsync(FSForkIOParam * paramBlock) ;
+extern OSErr
+FSCloseFork(SInt16 forkRefNum) ;
+extern OSErr
+PBCloseForkSync(FSForkIOParam * paramBlock) ;
+extern void
+PBCloseForkAsync(FSForkIOParam * paramBlock) ;
+extern OSErr
+FSGetForkCBInfo(
+ SInt16 desiredRefNum,
+ FSVolumeRefNum volume,
+ SInt16 * iterator,
+ SInt16 * actualRefNum,
+ FSForkInfo * forkInfo,
+ FSRef * ref,
+ HFSUniStr255 * outForkName) ;
+extern OSErr
+PBGetForkCBInfoSync(FSForkCBInfoParam * paramBlock) ;
+extern void
+PBGetForkCBInfoAsync(FSForkCBInfoParam * paramBlock) ;
+extern OSErr
+FSGetVolumeInfo(
+ FSVolumeRefNum volume,
+ ItemCount volumeIndex,
+ FSVolumeRefNum * actualVolume,
+ FSVolumeInfoBitmap whichInfo,
+ FSVolumeInfo * info,
+ HFSUniStr255 * volumeName,
+ FSRef * rootDirectory) ;
+extern OSErr
+PBGetVolumeInfoSync(FSVolumeInfoParam * paramBlock) ;
+extern void
+PBGetVolumeInfoAsync(FSVolumeInfoParam * paramBlock) ;
+extern OSErr
+FSSetVolumeInfo(
+ FSVolumeRefNum volume,
+ FSVolumeInfoBitmap whichInfo,
+ const FSVolumeInfo * info) ;
+extern OSErr
+PBSetVolumeInfoSync(FSVolumeInfoParam * paramBlock) ;
+extern void
+PBSetVolumeInfoAsync(FSVolumeInfoParam * paramBlock) ;
+extern OSErr
+FSGetDataForkName(HFSUniStr255 * dataForkName) ;
+extern OSErr
+FSGetResourceForkName(HFSUniStr255 * resourceForkName) ;
+extern OSStatus
+FSRefMakePath(
+ const FSRef * ref,
+ UInt8 * path,
+ UInt32 maxPathSize) ;
+extern OSStatus
+FSPathMakeRef(
+ const UInt8 * path,
+ FSRef * ref,
+ Boolean * isDirectory) ;
+typedef UInt32 FNMessage;
+enum {
+ kFNDirectoryModifiedMessage = 1
+};
+extern OSStatus
+FNNotify(
+ const FSRef * ref,
+ FNMessage message,
+ OptionBits flags) ;
+extern OSStatus
+FNNotifyByPath(
+ const UInt8 * path,
+ FNMessage message,
+ OptionBits flags) ;
+extern OSStatus
+FNNotifyAll(
+ FNMessage message,
+ OptionBits flags) ;
+typedef struct OpaqueFNSubscriptionRef* FNSubscriptionRef;
+
+
+
+
+
+enum {
+
+
+
+
+
+
+
+ kFNNoImplicitAllSubscription = (1 << 0)
+};
+typedef void ( * FNSubscriptionProcPtr)(FNMessage message, OptionBits flags, void *refcon, FNSubscriptionRef subscription);
+typedef FNSubscriptionProcPtr FNSubscriptionUPP;
+extern FNSubscriptionUPP
+NewFNSubscriptionUPP(FNSubscriptionProcPtr userRoutine) ;
+extern void
+DisposeFNSubscriptionUPP(FNSubscriptionUPP userUPP) ;
+extern void
+InvokeFNSubscriptionUPP(
+ FNMessage message,
+ OptionBits flags,
+ void * refcon,
+ FNSubscriptionRef subscription,
+ FNSubscriptionUPP userUPP) ;
+extern OSStatus
+FNSubscribe(
+ const FSRef * directoryRef,
+ FNSubscriptionUPP callback,
+ void * refcon,
+ OptionBits flags,
+ FNSubscriptionRef * subscription) ;
+extern OSStatus
+FNSubscribeByPath(
+ const UInt8 * directoryPath,
+ FNSubscriptionUPP callback,
+ void * refcon,
+ OptionBits flags,
+ FNSubscriptionRef * subscription) ;
+extern OSStatus
+FNUnsubscribe(FNSubscriptionRef subscription) ;
+extern OSStatus
+FNGetDirectoryForSubscription(
+ FNSubscriptionRef subscription,
+ FSRef * ref) ;
+
+
+
+enum {
+ kAsyncMountInProgress = 1,
+ kAsyncMountComplete = 2,
+ kAsyncUnmountInProgress = 3,
+ kAsyncUnmountComplete = 4,
+ kAsyncEjectInProgress = 5,
+ kAsyncEjectComplete = 6
+};
+
+typedef UInt32 FSMountStatus;
+typedef UInt32 FSEjectStatus;
+typedef UInt32 FSUnmountStatus;
+typedef struct OpaqueFSVolumeOperation* FSVolumeOperation;
+typedef void ( * FSVolumeMountProcPtr)(FSVolumeOperation volumeOp, void *clientData, OSStatus err, FSVolumeRefNum mountedVolumeRefNum);
+typedef void ( * FSVolumeUnmountProcPtr)(FSVolumeOperation volumeOp, void *clientData, OSStatus err, FSVolumeRefNum volumeRefNum, pid_t dissenter);
+typedef void ( * FSVolumeEjectProcPtr)(FSVolumeOperation volumeOp, void *clientData, OSStatus err, FSVolumeRefNum volumeRefNum, pid_t dissenter);
+typedef FSVolumeMountProcPtr FSVolumeMountUPP;
+typedef FSVolumeUnmountProcPtr FSVolumeUnmountUPP;
+typedef FSVolumeEjectProcPtr FSVolumeEjectUPP;
+extern FSVolumeMountUPP
+NewFSVolumeMountUPP(FSVolumeMountProcPtr userRoutine) ;
+extern FSVolumeUnmountUPP
+NewFSVolumeUnmountUPP(FSVolumeUnmountProcPtr userRoutine) ;
+extern FSVolumeEjectUPP
+NewFSVolumeEjectUPP(FSVolumeEjectProcPtr userRoutine) ;
+extern void
+DisposeFSVolumeMountUPP(FSVolumeMountUPP userUPP) ;
+extern void
+DisposeFSVolumeUnmountUPP(FSVolumeUnmountUPP userUPP) ;
+extern void
+DisposeFSVolumeEjectUPP(FSVolumeEjectUPP userUPP) ;
+extern void
+InvokeFSVolumeMountUPP(
+ FSVolumeOperation volumeOp,
+ void * clientData,
+ OSStatus err,
+ FSVolumeRefNum mountedVolumeRefNum,
+ FSVolumeMountUPP userUPP) ;
+extern void
+InvokeFSVolumeUnmountUPP(
+ FSVolumeOperation volumeOp,
+ void * clientData,
+ OSStatus err,
+ FSVolumeRefNum volumeRefNum,
+ pid_t dissenter,
+ FSVolumeUnmountUPP userUPP) ;
+extern void
+InvokeFSVolumeEjectUPP(
+ FSVolumeOperation volumeOp,
+ void * clientData,
+ OSStatus err,
+ FSVolumeRefNum volumeRefNum,
+ pid_t dissenter,
+ FSVolumeEjectUPP userUPP) ;
+extern OSStatus
+FSCreateVolumeOperation(FSVolumeOperation * volumeOp) ;
+extern OSStatus
+FSDisposeVolumeOperation(FSVolumeOperation volumeOp) ;
+extern OSStatus
+FSMountLocalVolumeSync(
+ CFStringRef diskID,
+ CFURLRef mountDir,
+ FSVolumeRefNum * mountedVolumeRefNum,
+ OptionBits flags) ;
+extern OSStatus
+FSMountLocalVolumeAsync(
+ CFStringRef diskID,
+ CFURLRef mountDir,
+ FSVolumeOperation volumeOp,
+ void * clientData,
+ OptionBits flags,
+ FSVolumeMountUPP callback,
+ CFRunLoopRef runloop,
+ CFStringRef runloopMode) ;
+extern OSStatus
+FSMountServerVolumeSync(
+ CFURLRef url,
+ CFURLRef mountDir,
+ CFStringRef user,
+ CFStringRef password,
+ FSVolumeRefNum * mountedVolumeRefNum,
+ OptionBits flags) ;
+extern OSStatus
+FSMountServerVolumeAsync(
+ CFURLRef url,
+ CFURLRef mountDir,
+ CFStringRef user,
+ CFStringRef password,
+ FSVolumeOperation volumeOp,
+ void * clientData,
+ OptionBits flags,
+ FSVolumeMountUPP callback,
+ CFRunLoopRef runloop,
+ CFStringRef runloopMode) ;
+extern OSStatus
+FSGetAsyncMountStatus(
+ FSVolumeOperation volumeOp,
+ FSMountStatus * status,
+ OSStatus * volumeOpStatus,
+ FSVolumeRefNum * mountedVolumeRefNum,
+ void ** clientData) ;
+extern OSStatus
+FSUnmountVolumeSync(
+ FSVolumeRefNum vRefNum,
+ OptionBits flags,
+ pid_t * dissenter) ;
+extern OSStatus
+FSUnmountVolumeAsync(
+ FSVolumeRefNum vRefNum,
+ OptionBits flags,
+ FSVolumeOperation volumeOp,
+ void * clientData,
+ FSVolumeUnmountUPP callback,
+ CFRunLoopRef runloop,
+ CFStringRef runloopMode) ;
+extern OSStatus
+FSGetAsyncUnmountStatus(
+ FSVolumeOperation volumeOp,
+ FSUnmountStatus * status,
+ OSStatus * volumeOpStatus,
+ FSVolumeRefNum * volumeRefNum,
+ pid_t * dissenter,
+ void ** clientData) ;
+extern OSStatus
+FSCancelVolumeOperation(FSVolumeOperation volumeOp) ;
+extern OSStatus
+FSEjectVolumeSync(
+ FSVolumeRefNum vRefNum,
+ OptionBits flags,
+ pid_t * dissenter) ;
+extern OSStatus
+FSEjectVolumeAsync(
+ FSVolumeRefNum vRefNum,
+ OptionBits flags,
+ FSVolumeOperation volumeOp,
+ void * clientData,
+ FSVolumeEjectUPP callback,
+ CFRunLoopRef runloop,
+ CFStringRef runloopMode) ;
+extern OSStatus
+FSGetAsyncEjectStatus(
+ FSVolumeOperation volumeOp,
+ FSEjectStatus * status,
+ OSStatus * volumeOpStatus,
+ FSVolumeRefNum * volumeRefNum,
+ pid_t * dissenter,
+ void ** clientData) ;
+extern OSStatus
+FSCopyDiskIDForVolume(
+ FSVolumeRefNum vRefNum,
+ CFStringRef * diskID) ;
+
+
+
+
+
+
+}
+extern "C" {
+
+
+
+enum {
+ kAppleManufacturer = 'appl',
+ kComponentResourceType = 'thng',
+ kComponentAliasResourceType = 'thga'
+};
+
+enum {
+ kAnyComponentType = 0,
+ kAnyComponentSubType = 0,
+ kAnyComponentManufacturer = 0,
+ kAnyComponentFlagsMask = 0
+};
+
+enum {
+ cmpIsMissing = 1L << 29,
+ cmpWantsRegisterMessage = 1L << 31
+};
+
+enum {
+ kComponentOpenSelect = -1,
+ kComponentCloseSelect = -2,
+ kComponentCanDoSelect = -3,
+ kComponentVersionSelect = -4,
+ kComponentRegisterSelect = -5,
+ kComponentTargetSelect = -6,
+ kComponentUnregisterSelect = -7,
+ kComponentGetMPWorkFunctionSelect = -8,
+ kComponentExecuteWiredActionSelect = -9,
+ kComponentGetPublicResourceSelect = -10
+};
+
+
+enum {
+ componentDoAutoVersion = (1 << 0),
+ componentWantsUnregister = (1 << 1),
+ componentAutoVersionIncludeFlags = (1 << 2),
+ componentHasMultiplePlatforms = (1 << 3),
+ componentLoadResident = (1 << 4)
+};
+
+
+
+
+enum {
+ defaultComponentIdentical = 0,
+ defaultComponentAnyFlags = 1,
+ defaultComponentAnyManufacturer = 2,
+ defaultComponentAnySubType = 4,
+ defaultComponentAnyFlagsAnyManufacturer = (defaultComponentAnyFlags + defaultComponentAnyManufacturer),
+ defaultComponentAnyFlagsAnyManufacturerAnySubType = (defaultComponentAnyFlags + defaultComponentAnyManufacturer + defaultComponentAnySubType)
+};
+
+
+enum {
+ registerComponentGlobal = 1,
+ registerComponentNoDuplicates = 2,
+ registerComponentAfterExisting = 4,
+ registerComponentAliasesOnly = 8
+};
+
+
+struct ComponentDescription {
+ OSType componentType;
+ OSType componentSubType;
+ OSType componentManufacturer;
+ unsigned long componentFlags;
+ unsigned long componentFlagsMask;
+};
+typedef struct ComponentDescription ComponentDescription;
+
+struct ResourceSpec {
+ OSType resType;
+ short resID;
+};
+typedef struct ResourceSpec ResourceSpec;
+struct ComponentResource {
+ ComponentDescription cd;
+ ResourceSpec component;
+ ResourceSpec componentName;
+ ResourceSpec componentInfo;
+ ResourceSpec componentIcon;
+};
+typedef struct ComponentResource ComponentResource;
+typedef ComponentResource * ComponentResourcePtr;
+typedef ComponentResourcePtr * ComponentResourceHandle;
+struct ComponentPlatformInfo {
+ long componentFlags;
+ ResourceSpec component;
+ short platformType;
+};
+typedef struct ComponentPlatformInfo ComponentPlatformInfo;
+struct ComponentResourceExtension {
+ long componentVersion;
+ long componentRegisterFlags;
+ short componentIconFamily;
+};
+typedef struct ComponentResourceExtension ComponentResourceExtension;
+struct ComponentPlatformInfoArray {
+ long count;
+ ComponentPlatformInfo platformArray[1];
+};
+typedef struct ComponentPlatformInfoArray ComponentPlatformInfoArray;
+struct ExtComponentResource {
+ ComponentDescription cd;
+ ResourceSpec component;
+ ResourceSpec componentName;
+ ResourceSpec componentInfo;
+ ResourceSpec componentIcon;
+ long componentVersion;
+ long componentRegisterFlags;
+ short componentIconFamily;
+ long count;
+ ComponentPlatformInfo platformArray[1];
+};
+typedef struct ExtComponentResource ExtComponentResource;
+typedef ExtComponentResource * ExtComponentResourcePtr;
+typedef ExtComponentResourcePtr * ExtComponentResourceHandle;
+struct ComponentAliasResource {
+ ComponentResource cr;
+ ComponentDescription aliasCD;
+};
+typedef struct ComponentAliasResource ComponentAliasResource;
+
+struct ComponentParameters {
+ UInt8 flags;
+ UInt8 paramSize;
+ short what;
+ long params[1];
+};
+typedef struct ComponentParameters ComponentParameters;
+struct ComponentRecord {
+ long data[1];
+};
+typedef struct ComponentRecord ComponentRecord;
+typedef ComponentRecord * Component;
+struct ComponentInstanceRecord {
+ long data[1];
+};
+typedef struct ComponentInstanceRecord ComponentInstanceRecord;
+typedef ComponentInstanceRecord * ComponentInstance;
+struct RegisteredComponentRecord {
+ long data[1];
+};
+typedef struct RegisteredComponentRecord RegisteredComponentRecord;
+typedef RegisteredComponentRecord * RegisteredComponentRecordPtr;
+struct RegisteredComponentInstanceRecord {
+ long data[1];
+};
+typedef struct RegisteredComponentInstanceRecord RegisteredComponentInstanceRecord;
+typedef RegisteredComponentInstanceRecord * RegisteredComponentInstanceRecordPtr;
+typedef long ComponentResult;
+enum {
+ platform68k = 1,
+ platformPowerPC = 2,
+ platformInterpreted = 3,
+ platformWin32 = 4,
+ platformPowerPCNativeEntryPoint = 5
+};
+
+enum {
+ platformIRIXmips = 1000,
+ platformSunOSsparc = 1100,
+ platformSunOSintel = 1101,
+ platformLinuxppc = 1200,
+ platformLinuxintel = 1201,
+ platformAIXppc = 1300,
+ platformNeXTIntel = 1400,
+ platformNeXTppc = 1401,
+ platformNeXTsparc = 1402,
+ platformNeXT68k = 1403,
+ platformMacOSx86 = 1500
+};
+
+enum {
+ mpWorkFlagDoWork = (1 << 0),
+ mpWorkFlagDoCompletion = (1 << 1),
+ mpWorkFlagCopyWorkBlock = (1 << 2),
+ mpWorkFlagDontBlock = (1 << 3),
+ mpWorkFlagGetProcessorCount = (1 << 4),
+ mpWorkFlagGetIsRunning = (1 << 6)
+};
+
+enum {
+ cmpAliasNoFlags = 0,
+ cmpAliasOnlyThisFile = 1
+};
+
+struct ComponentMPWorkFunctionHeaderRecord {
+ UInt32 headerSize;
+ UInt32 recordSize;
+ UInt32 workFlags;
+ UInt16 processorCount;
+ UInt8 unused;
+ UInt8 isRunning;
+};
+typedef struct ComponentMPWorkFunctionHeaderRecord ComponentMPWorkFunctionHeaderRecord;
+typedef ComponentMPWorkFunctionHeaderRecord * ComponentMPWorkFunctionHeaderRecordPtr;
+typedef ComponentResult ( * ComponentMPWorkFunctionProcPtr)(void *globalRefCon, ComponentMPWorkFunctionHeaderRecordPtr header);
+typedef ComponentResult ( * ComponentRoutineProcPtr)(ComponentParameters *cp, Handle componentStorage);
+typedef OSErr ( * GetMissingComponentResourceProcPtr)(Component c, OSType resType, short resID, void *refCon, Handle *resource);
+typedef ComponentMPWorkFunctionProcPtr ComponentMPWorkFunctionUPP;
+typedef ComponentRoutineProcPtr ComponentRoutineUPP;
+typedef GetMissingComponentResourceProcPtr GetMissingComponentResourceUPP;
+
+
+
+
+
+typedef UniversalProcPtr ComponentFunctionUPP;
+extern ComponentFunctionUPP
+NewComponentFunctionUPP(
+ ProcPtr userRoutine,
+ ProcInfoType procInfo) ;
+extern void
+DisposeComponentFunctionUPP(ComponentFunctionUPP userUPP) ;
+extern Component
+RegisterComponent(
+ ComponentDescription * cd,
+ ComponentRoutineUPP componentEntryPoint,
+ short global,
+ Handle componentName,
+ Handle componentInfo,
+ Handle componentIcon) ;
+extern Component
+RegisterComponentResource(
+ ComponentResourceHandle cr,
+ short global) ;
+extern OSErr
+UnregisterComponent(Component aComponent) ;
+extern Component
+FindNextComponent(
+ Component aComponent,
+ ComponentDescription * looking) ;
+extern long
+CountComponents(ComponentDescription * looking) ;
+extern OSErr
+GetComponentInfo(
+ Component aComponent,
+ ComponentDescription * cd,
+ Handle componentName,
+ Handle componentInfo,
+ Handle componentIcon) ;
+extern long
+GetComponentListModSeed(void) ;
+extern long
+GetComponentTypeModSeed(OSType componentType) ;
+extern OSErr
+OpenAComponent(
+ Component aComponent,
+ ComponentInstance * ci) ;
+extern ComponentInstance
+OpenComponent(Component aComponent) ;
+extern OSErr
+CloseComponent(ComponentInstance aComponentInstance) ;
+extern OSErr
+GetComponentInstanceError(ComponentInstance aComponentInstance) ;
+extern Component
+ResolveComponentAlias(Component aComponent) ;
+extern OSErr
+GetComponentPublicResource(
+ Component aComponent,
+ OSType resourceType,
+ short resourceID,
+ Handle * theResource) ;
+extern OSErr
+GetComponentPublicResourceList(
+ OSType resourceType,
+ short resourceID,
+ long flags,
+ ComponentDescription * cd,
+ GetMissingComponentResourceUPP missingProc,
+ void * refCon,
+ void * atomContainerPtr) ;
+extern OSErr
+GetComponentPublicIndString(
+ Component aComponent,
+ Str255 theString,
+ short strListID,
+ short index) ;
+extern void
+SetComponentInstanceError(
+ ComponentInstance aComponentInstance,
+ OSErr theError) ;
+extern long
+GetComponentRefcon(Component aComponent) ;
+extern void
+SetComponentRefcon(
+ Component aComponent,
+ long theRefcon) ;
+extern short
+OpenComponentResFile(Component aComponent) ;
+extern OSErr
+OpenAComponentResFile(
+ Component aComponent,
+ short * resRef) ;
+extern OSErr
+CloseComponentResFile(short refnum) ;
+extern OSErr
+GetComponentResource(
+ Component aComponent,
+ OSType resType,
+ short resID,
+ Handle * theResource) ;
+extern OSErr
+GetComponentIndString(
+ Component aComponent,
+ Str255 theString,
+ short strListID,
+ short index) ;
+extern Handle
+GetComponentInstanceStorage(ComponentInstance aComponentInstance) ;
+extern void
+SetComponentInstanceStorage(
+ ComponentInstance aComponentInstance,
+ Handle theStorage) ;
+extern long
+CountComponentInstances(Component aComponent) ;
+extern long
+CallComponentFunction(
+ ComponentParameters * params,
+ ComponentFunctionUPP func) ;
+extern long
+CallComponentFunctionWithStorage(
+ Handle storage,
+ ComponentParameters * params,
+ ComponentFunctionUPP func) ;
+extern long
+CallComponentFunctionWithStorageProcInfo(
+ Handle storage,
+ ComponentParameters * params,
+ ProcPtr func,
+ ProcInfoType funcProcInfo) ;
+extern long
+DelegateComponentCall(
+ ComponentParameters * originalParams,
+ ComponentInstance ci) ;
+extern OSErr
+SetDefaultComponent(
+ Component aComponent,
+ short flags) ;
+extern ComponentInstance
+OpenDefaultComponent(
+ OSType componentType,
+ OSType componentSubType) ;
+extern OSErr
+OpenADefaultComponent(
+ OSType componentType,
+ OSType componentSubType,
+ ComponentInstance * ci) ;
+extern Component
+CaptureComponent(
+ Component capturedComponent,
+ Component capturingComponent) ;
+extern OSErr
+UncaptureComponent(Component aComponent) ;
+extern long
+RegisterComponentResourceFile(
+ short resRefNum,
+ short global) ;
+extern OSErr
+GetComponentIconSuite(
+ Component aComponent,
+ Handle * iconSuite) ;
+extern OSErr
+RegisterComponentFile(
+ const FSSpec * spec,
+ short global) ;
+extern OSErr
+RegisterComponentFileEntries(
+ const FSSpec * spec,
+ short global,
+ const ComponentDescription * toRegister,
+ UInt32 registerCount) ;
+extern OSErr
+RegisterComponentFileRef(
+ const FSRef * ref,
+ short global) ;
+extern OSErr
+RegisterComponentFileRefEntries(
+ const FSRef * ref,
+ short global,
+ const ComponentDescription * toRegister,
+ UInt32 registerCount) ;
+extern long
+ComponentFunctionImplemented(
+ ComponentInstance ci,
+ short ftnNumber) ;
+extern long
+GetComponentVersion(ComponentInstance ci) ;
+extern long
+ComponentSetTarget(
+ ComponentInstance ci,
+ ComponentInstance target) ;
+extern ComponentResult
+CallComponentOpen(
+ ComponentInstance ci,
+ ComponentInstance self) ;
+extern ComponentResult
+CallComponentClose(
+ ComponentInstance ci,
+ ComponentInstance self) ;
+extern ComponentResult
+CallComponentCanDo(
+ ComponentInstance ci,
+ short ftnNumber) ;
+extern ComponentResult
+CallComponentVersion(ComponentInstance ci) ;
+extern ComponentResult
+CallComponentRegister(ComponentInstance ci) ;
+extern ComponentResult
+CallComponentTarget(
+ ComponentInstance ci,
+ ComponentInstance target) ;
+extern ComponentResult
+CallComponentUnregister(ComponentInstance ci) ;
+extern ComponentResult
+CallComponentGetMPWorkFunction(
+ ComponentInstance ci,
+ ComponentMPWorkFunctionUPP * workFunction,
+ void ** refCon) ;
+extern ComponentResult
+CallComponentGetPublicResource(
+ ComponentInstance ci,
+ OSType resourceType,
+ short resourceID,
+ Handle * resource) ;
+extern ComponentResult
+CallComponentDispatch(ComponentParameters * cp) ;
+extern ComponentMPWorkFunctionUPP
+NewComponentMPWorkFunctionUPP(ComponentMPWorkFunctionProcPtr userRoutine) ;
+extern ComponentRoutineUPP
+NewComponentRoutineUPP(ComponentRoutineProcPtr userRoutine) ;
+extern GetMissingComponentResourceUPP
+NewGetMissingComponentResourceUPP(GetMissingComponentResourceProcPtr userRoutine) ;
+extern void
+DisposeComponentMPWorkFunctionUPP(ComponentMPWorkFunctionUPP userUPP) ;
+extern void
+DisposeComponentRoutineUPP(ComponentRoutineUPP userUPP) ;
+extern void
+DisposeGetMissingComponentResourceUPP(GetMissingComponentResourceUPP userUPP) ;
+extern ComponentResult
+InvokeComponentMPWorkFunctionUPP(
+ void * globalRefCon,
+ ComponentMPWorkFunctionHeaderRecordPtr header,
+ ComponentMPWorkFunctionUPP userUPP) ;
+extern ComponentResult
+InvokeComponentRoutineUPP(
+ ComponentParameters * cp,
+ Handle componentStorage,
+ ComponentRoutineUPP userUPP) ;
+extern OSErr
+InvokeGetMissingComponentResourceUPP(
+ Component c,
+ OSType resType,
+ short resID,
+ void * refCon,
+ Handle * resource,
+ GetMissingComponentResourceUPP userUPP) ;
+
+
+
+
+enum {
+ uppComponentFunctionImplementedProcInfo = 0x000002F0,
+ uppGetComponentVersionProcInfo = 0x000000F0,
+ uppComponentSetTargetProcInfo = 0x000003F0,
+ uppCallComponentOpenProcInfo = 0x000003F0,
+ uppCallComponentCloseProcInfo = 0x000003F0,
+ uppCallComponentCanDoProcInfo = 0x000002F0,
+ uppCallComponentVersionProcInfo = 0x000000F0,
+ uppCallComponentRegisterProcInfo = 0x000000F0,
+ uppCallComponentTargetProcInfo = 0x000003F0,
+ uppCallComponentUnregisterProcInfo = 0x000000F0,
+ uppCallComponentGetMPWorkFunctionProcInfo = 0x00000FF0,
+ uppCallComponentGetPublicResourceProcInfo = 0x00003BF0
+};
+
+
+
+
+
+
+
+
+
+}
+extern "C" {
+
+
+
+enum {
+ resSysHeap = 64,
+ resPurgeable = 32,
+ resLocked = 16,
+ resProtected = 8,
+ resPreload = 4,
+ resChanged = 2,
+ mapReadOnly = 128,
+ mapCompact = 64,
+ mapChanged = 32
+};
+
+enum {
+ resSysRefBit = 7,
+ resSysHeapBit = 6,
+ resPurgeableBit = 5,
+ resLockedBit = 4,
+ resProtectedBit = 3,
+ resPreloadBit = 2,
+ resChangedBit = 1,
+ mapReadOnlyBit = 7,
+ mapCompactBit = 6,
+ mapChangedBit = 5
+};
+
+enum {
+ kResFileNotOpened = -1,
+ kSystemResFile = 0
+};
+
+
+typedef void ( * ResErrProcPtr)(OSErr thErr);
+typedef ResErrProcPtr ResErrUPP;
+extern ResErrUPP
+NewResErrUPP(ResErrProcPtr userRoutine) ;
+extern void
+DisposeResErrUPP(ResErrUPP userUPP) ;
+extern void
+InvokeResErrUPP(
+ OSErr thErr,
+ ResErrUPP userUPP) ;
+
+
+typedef OSErr ( * ResourceEndianFilterPtr)(Handle theResource, Boolean currentlyNativeEndian);
+extern void
+CloseResFile(short refNum) ;
+extern OSErr
+ResError(void) ;
+extern short
+CurResFile(void) ;
+extern short
+HomeResFile(Handle theResource) ;
+extern void
+UseResFile(short refNum) ;
+extern short
+CountTypes(void) ;
+extern short
+Count1Types(void) ;
+extern void
+GetIndType(
+ ResType * theType,
+ short index) ;
+extern void
+Get1IndType(
+ ResType * theType,
+ short index) ;
+extern void
+SetResLoad(Boolean load) ;
+extern short
+CountResources(ResType theType) ;
+extern short
+Count1Resources(ResType theType) ;
+extern Handle
+GetIndResource(
+ ResType theType,
+ short index) ;
+extern Handle
+Get1IndResource(
+ ResType theType,
+ short index) ;
+extern Handle
+GetResource(
+ ResType theType,
+ short theID) ;
+extern Handle
+Get1Resource(
+ ResType theType,
+ short theID) ;
+extern Handle
+GetNamedResource(
+ ResType theType,
+ ConstStr255Param name) ;
+extern Handle
+Get1NamedResource(
+ ResType theType,
+ ConstStr255Param name) ;
+extern void
+LoadResource(Handle theResource) ;
+extern void
+ReleaseResource(Handle theResource) ;
+extern void
+DetachResource(Handle theResource) ;
+extern short
+UniqueID(ResType theType) ;
+extern short
+Unique1ID(ResType theType) ;
+extern short
+GetResAttrs(Handle theResource) ;
+extern void
+GetResInfo(
+ Handle theResource,
+ short * theID,
+ ResType * theType,
+ Str255 name) ;
+extern void
+SetResInfo(
+ Handle theResource,
+ short theID,
+ ConstStr255Param name) ;
+extern void
+AddResource(
+ Handle theData,
+ ResType theType,
+ short theID,
+ ConstStr255Param name) ;
+extern long
+GetResourceSizeOnDisk(Handle theResource) ;
+extern long
+GetMaxResourceSize(Handle theResource) ;
+extern void
+SetResAttrs(
+ Handle theResource,
+ short attrs) ;
+extern void
+ChangedResource(Handle theResource) ;
+extern void
+RemoveResource(Handle theResource) ;
+extern void
+UpdateResFile(short refNum) ;
+extern void
+WriteResource(Handle theResource) ;
+extern void
+SetResPurge(Boolean install) ;
+extern short
+GetResFileAttrs(short refNum) ;
+extern void
+SetResFileAttrs(
+ short refNum,
+ short attrs) ;
+extern short
+OpenRFPerm(
+ ConstStr255Param fileName,
+ short vRefNum,
+ SInt8 permission) ;
+extern short
+HOpenResFile(
+ short vRefNum,
+ long dirID,
+ ConstStr255Param fileName,
+ SInt8 permission) ;
+extern void
+HCreateResFile(
+ short vRefNum,
+ long dirID,
+ ConstStr255Param fileName) ;
+extern short
+FSpOpenResFile(
+ const FSSpec * spec,
+ SignedByte permission) ;
+extern void
+FSpCreateResFile(
+ const FSSpec * spec,
+ OSType creator,
+ OSType fileType,
+ ScriptCode scriptTag) ;
+extern void
+ReadPartialResource(
+ Handle theResource,
+ long offset,
+ void * buffer,
+ long count) ;
+extern void
+WritePartialResource(
+ Handle theResource,
+ long offset,
+ const void * buffer,
+ long count) ;
+extern void
+SetResourceSize(
+ Handle theResource,
+ long newSize) ;
+extern Handle
+GetNextFOND(Handle fondHandle) ;
+typedef SInt16 RsrcChainLocation;
+enum {
+ kRsrcChainBelowSystemMap = 0,
+ kRsrcChainBelowApplicationMap = 1,
+ kRsrcChainAboveApplicationMap = 2,
+ kRsrcChainAboveAllMaps = 4
+};
+extern OSErr
+InsertResourceFile(
+ SInt16 refNum,
+ RsrcChainLocation where) ;
+extern OSErr
+DetachResourceFile(SInt16 refNum) ;
+extern Boolean
+FSpResourceFileAlreadyOpen(
+ const FSSpec * resourceFile,
+ Boolean * inChain,
+ SInt16 * refNum) ;
+extern OSErr
+FSpOpenOrphanResFile(
+ const FSSpec * spec,
+ SignedByte permission,
+ SInt16 * refNum) ;
+extern OSErr
+GetTopResourceFile(SInt16 * refNum) ;
+extern OSErr
+GetNextResourceFile(
+ SInt16 curRefNum,
+ SInt16 * nextRefNum) ;
+extern short
+FSOpenResFile(
+ const FSRef * ref,
+ SInt8 permission) ;
+extern void
+FSCreateResFile(
+ const FSRef * parentRef,
+ UniCharCount nameLength,
+ const UniChar * name,
+ FSCatalogInfoBitmap whichInfo,
+ const FSCatalogInfo * catalogInfo,
+ FSRef * newRef,
+ FSSpec * newSpec) ;
+extern Boolean
+FSResourceFileAlreadyOpen(
+ const FSRef * resourceFileRef,
+ Boolean * inChain,
+ SInt16 * refNum) ;
+extern OSErr
+FSCreateResourceFile(
+ const FSRef * parentRef,
+ UniCharCount nameLength,
+ const UniChar * name,
+ FSCatalogInfoBitmap whichInfo,
+ const FSCatalogInfo * catalogInfo,
+ UniCharCount forkNameLength,
+ const UniChar * forkName,
+ FSRef * newRef,
+ FSSpec * newSpec) ;
+extern OSErr
+FSCreateResourceFork(
+ const FSRef * ref,
+ UniCharCount forkNameLength,
+ const UniChar * forkName,
+ UInt32 flags) ;
+extern OSErr
+FSOpenResourceFile(
+ const FSRef * ref,
+ UniCharCount forkNameLength,
+ const UniChar * forkName,
+ SInt8 permissions,
+ SInt16 * refNum) ;
+
+
+
+
+
+typedef short ResFileRefNum;
+typedef short ResID;
+typedef short ResAttributes;
+typedef short ResFileAttributes;
+}
+
+
+
+extern "C" {
+
+
+enum {
+ MPLibrary_MajorVersion = 2,
+ MPLibrary_MinorVersion = 3,
+ MPLibrary_Release = 1,
+ MPLibrary_DevelopmentRevision = 1
+};
+
+
+
+typedef struct OpaqueMPProcessID* MPProcessID;
+typedef struct OpaqueMPTaskID* MPTaskID;
+typedef struct OpaqueMPQueueID* MPQueueID;
+typedef struct OpaqueMPSemaphoreID* MPSemaphoreID;
+typedef struct OpaqueMPCriticalRegionID* MPCriticalRegionID;
+typedef struct OpaqueMPTimerID* MPTimerID;
+typedef struct OpaqueMPEventID* MPEventID;
+typedef struct OpaqueMPAddressSpaceID* MPAddressSpaceID;
+typedef struct OpaqueMPNotificationID* MPNotificationID;
+typedef struct OpaqueMPCoherenceID* MPCoherenceID;
+typedef struct OpaqueMPCpuID* MPCpuID;
+typedef struct OpaqueMPAreaID* MPAreaID;
+typedef struct OpaqueMPConsoleID* MPConsoleID;
+typedef struct OpaqueMPOpaqueID* MPOpaqueID;
+enum {
+
+ kOpaqueAnyID = 0,
+ kOpaqueProcessID = 1,
+ kOpaqueTaskID = 2,
+ kOpaqueTimerID = 3,
+ kOpaqueQueueID = 4,
+ kOpaqueSemaphoreID = 5,
+ kOpaqueCriticalRegionID = 6,
+ kOpaqueCpuID = 7,
+ kOpaqueAddressSpaceID = 8,
+ kOpaqueEventID = 9,
+ kOpaqueCoherenceID = 10,
+ kOpaqueAreaID = 11,
+ kOpaqueNotificationID = 12,
+ kOpaqueConsoleID = 13
+};
+
+typedef UInt32 MPOpaqueIDClass;
+
+enum {
+ kMPNoID = 0
+};
+
+
+typedef OptionBits MPTaskOptions;
+typedef UInt32 TaskStorageIndex;
+typedef UInt32 TaskStorageValue;
+typedef ItemCount MPSemaphoreCount;
+typedef UInt32 MPTaskWeight;
+typedef UInt32 MPEventFlags;
+typedef UInt32 MPExceptionKind;
+typedef UInt32 MPTaskStateKind;
+typedef UInt32 MPPageSizeClass;
+
+enum {
+ kDurationImmediate = 0L,
+ kDurationForever = 0x7FFFFFFF,
+ kDurationMillisecond = 1,
+ kDurationMicrosecond = -1
+};
+extern ItemCount
+MPProcessors(void) ;
+extern ItemCount
+MPProcessorsScheduled(void) ;
+enum {
+
+ kMPCreateTaskSuspendedMask = 1L << 0,
+ kMPCreateTaskTakesAllExceptionsMask = 1L << 1,
+ kMPCreateTaskNotDebuggableMask = 1L << 2,
+ kMPCreateTaskValidOptionsMask = kMPCreateTaskSuspendedMask | kMPCreateTaskTakesAllExceptionsMask | kMPCreateTaskNotDebuggableMask
+};
+
+
+
+
+
+
+
+typedef OSStatus ( * TaskProc)(void * parameter);
+extern OSStatus
+MPCreateTask(
+ TaskProc entryPoint,
+ void * parameter,
+ ByteCount stackSize,
+ MPQueueID notifyQueue,
+ void * terminationParameter1,
+ void * terminationParameter2,
+ MPTaskOptions options,
+ MPTaskID * task) ;
+extern OSStatus
+MPTerminateTask(
+ MPTaskID task,
+ OSStatus terminationStatus) ;
+extern OSStatus
+MPSetTaskWeight(
+ MPTaskID task,
+ MPTaskWeight weight) ;
+extern Boolean
+MPTaskIsPreemptive(MPTaskID taskID) ;
+extern void
+MPExit(OSStatus status) ;
+extern void
+MPYield(void) ;
+extern MPTaskID
+MPCurrentTaskID(void) ;
+extern OSStatus
+MPSetTaskType(
+ MPTaskID task,
+ OSType taskType) ;
+extern OSStatus
+MPAllocateTaskStorageIndex(TaskStorageIndex * index) ;
+extern OSStatus
+MPDeallocateTaskStorageIndex(TaskStorageIndex index) ;
+extern OSStatus
+MPSetTaskStorageValue(
+ TaskStorageIndex index,
+ TaskStorageValue value) ;
+extern TaskStorageValue
+MPGetTaskStorageValue(TaskStorageIndex index) ;
+extern OSStatus
+MPCreateQueue(MPQueueID * queue) ;
+extern OSStatus
+MPDeleteQueue(MPQueueID queue) ;
+extern OSStatus
+MPNotifyQueue(
+ MPQueueID queue,
+ void * param1,
+ void * param2,
+ void * param3) ;
+extern OSStatus
+MPWaitOnQueue(
+ MPQueueID queue,
+ void ** param1,
+ void ** param2,
+ void ** param3,
+ Duration timeout) ;
+extern OSStatus
+MPSetQueueReserve(
+ MPQueueID queue,
+ ItemCount count) ;
+extern OSStatus
+MPCreateSemaphore(
+ MPSemaphoreCount maximumValue,
+ MPSemaphoreCount initialValue,
+ MPSemaphoreID * semaphore) ;
+extern OSStatus
+MPDeleteSemaphore(MPSemaphoreID semaphore) ;
+extern OSStatus
+MPSignalSemaphore(MPSemaphoreID semaphore) ;
+extern OSStatus
+MPWaitOnSemaphore(
+ MPSemaphoreID semaphore,
+ Duration timeout) ;
+extern OSStatus
+MPCreateCriticalRegion(MPCriticalRegionID * criticalRegion) ;
+extern OSStatus
+MPDeleteCriticalRegion(MPCriticalRegionID criticalRegion) ;
+extern OSStatus
+MPEnterCriticalRegion(
+ MPCriticalRegionID criticalRegion,
+ Duration timeout) ;
+extern OSStatus
+MPExitCriticalRegion(MPCriticalRegionID criticalRegion) ;
+extern OSStatus
+MPCreateEvent(MPEventID * event) ;
+extern OSStatus
+MPDeleteEvent(MPEventID event) ;
+extern OSStatus
+MPSetEvent(
+ MPEventID event,
+ MPEventFlags flags) ;
+extern OSStatus
+MPWaitForEvent(
+ MPEventID event,
+ MPEventFlags * flags,
+ Duration timeout) ;
+extern OSStatus
+MPCreateNotification(MPNotificationID * notificationID) ;
+extern OSStatus
+MPDeleteNotification(MPNotificationID notificationID) ;
+extern OSStatus
+MPModifyNotification(
+ MPNotificationID notificationID,
+ MPOpaqueID anID,
+ void * notifyParam1,
+ void * notifyParam2,
+ void * notifyParam3) ;
+extern OSStatus
+MPModifyNotificationParameters(
+ MPNotificationID notificationID,
+ MPOpaqueIDClass kind,
+ void * notifyParam1,
+ void * notifyParam2,
+ void * notifyParam3) ;
+extern OSStatus
+MPCauseNotification(MPNotificationID notificationID) ;
+enum {
+
+ kMPPreserveTimerIDMask = 1L << 0,
+ kMPTimeIsDeltaMask = 1L << 1,
+ kMPTimeIsDurationMask = 1L << 2
+};
+extern OSStatus
+MPDelayUntil(AbsoluteTime * expirationTime) ;
+extern OSStatus
+MPCreateTimer(MPTimerID * timerID) ;
+extern OSStatus
+MPDeleteTimer(MPTimerID timerID) ;
+extern OSStatus
+MPSetTimerNotify(
+ MPTimerID timerID,
+ MPOpaqueID anID,
+ void * notifyParam1,
+ void * notifyParam2,
+ void * notifyParam3) ;
+extern OSStatus
+MPArmTimer(
+ MPTimerID timerID,
+ AbsoluteTime * expirationTime,
+ OptionBits options) ;
+extern OSStatus
+MPCancelTimer(
+ MPTimerID timerID,
+ AbsoluteTime * timeRemaining) ;
+enum {
+
+ kMPMaxAllocSize = 1024L * 1024 * 1024
+};
+
+enum {
+
+ kMPAllocateDefaultAligned = 0,
+ kMPAllocate8ByteAligned = 3,
+ kMPAllocate16ByteAligned = 4,
+ kMPAllocate32ByteAligned = 5,
+ kMPAllocate1024ByteAligned = 10,
+ kMPAllocate4096ByteAligned = 12,
+ kMPAllocateMaxAlignment = 16,
+ kMPAllocateAltiVecAligned = kMPAllocate16ByteAligned,
+ kMPAllocateVMXAligned = kMPAllocateAltiVecAligned,
+ kMPAllocateVMPageAligned = 254,
+ kMPAllocateInterlockAligned = 255
+};
+
+
+
+enum {
+
+ kMPAllocateClearMask = 0x0001,
+ kMPAllocateGloballyMask = 0x0002,
+ kMPAllocateResidentMask = 0x0004,
+ kMPAllocateNoGrowthMask = 0x0010,
+ kMPAllocateNoCreateMask = 0x0020
+};
+extern LogicalAddress
+MPAllocateAligned(
+ ByteCount size,
+ UInt8 alignment,
+ OptionBits options) ;
+extern LogicalAddress
+MPAllocate(ByteCount size) ;
+extern void
+MPFree(LogicalAddress object) ;
+extern ByteCount
+MPGetAllocatedBlockSize(LogicalAddress object) ;
+extern void
+MPBlockCopy(
+ LogicalAddress source,
+ LogicalAddress destination,
+ ByteCount size) ;
+extern void
+MPBlockClear(
+ LogicalAddress address,
+ ByteCount size) ;
+extern void
+MPDataToCode(
+ LogicalAddress address,
+ ByteCount size) ;
+enum {
+
+ kMPTaskStateRegisters = 0,
+ kMPTaskStateFPU = 1,
+ kMPTaskStateVectors = 2,
+ kMPTaskStateMachine = 3,
+ kMPTaskState32BitMemoryException = 4,
+ kMPTaskStateTaskInfo = 5
+};
+
+
+
+enum {
+
+ kMPTaskPropagate = 0,
+ kMPTaskResumeStep = 1,
+ kMPTaskResumeBranch = 2,
+ kMPTaskResumeMask = 0x0000,
+ kMPTaskPropagateMask = 1 << kMPTaskPropagate,
+ kMPTaskResumeStepMask = 1 << kMPTaskResumeStep,
+ kMPTaskResumeBranchMask = 1 << kMPTaskResumeBranch
+};
+
+
+
+enum {
+
+ kMPTaskBlocked = 0,
+ kMPTaskReady = 1,
+ kMPTaskRunning = 2
+};
+
+enum {
+
+ kMPTaskInfoVersion = 3
+};
+
+
+struct MPTaskInfoVersion2 {
+ PBVersion version;
+
+ OSType name;
+
+ OSType queueName;
+ UInt16 runState;
+ UInt16 lastCPU;
+ UInt32 weight;
+
+ MPProcessID processID;
+
+ AbsoluteTime cpuTime;
+ AbsoluteTime schedTime;
+ AbsoluteTime creationTime;
+
+ ItemCount codePageFaults;
+ ItemCount dataPageFaults;
+ ItemCount preemptions;
+
+ MPCpuID cpuID;
+};
+typedef struct MPTaskInfoVersion2 MPTaskInfoVersion2;
+struct MPTaskInfo {
+ PBVersion version;
+
+ OSType name;
+
+ OSType queueName;
+ UInt16 runState;
+ UInt16 lastCPU;
+ UInt32 weight;
+
+ MPProcessID processID;
+
+ AbsoluteTime cpuTime;
+ AbsoluteTime schedTime;
+ AbsoluteTime creationTime;
+
+ ItemCount codePageFaults;
+ ItemCount dataPageFaults;
+ ItemCount preemptions;
+
+ MPCpuID cpuID;
+ MPOpaqueID blockedObject;
+ MPAddressSpaceID spaceID;
+
+ LogicalAddress stackBase;
+ LogicalAddress stackLimit;
+ LogicalAddress stackCurr;
+};
+typedef struct MPTaskInfo MPTaskInfo;
+extern OSStatus
+MPSetExceptionHandler(
+ MPTaskID task,
+ MPQueueID exceptionQ) ;
+extern OSStatus
+MPDisposeTaskException(
+ MPTaskID task,
+ OptionBits action) ;
+extern OSStatus
+MPExtractTaskState(
+ MPTaskID task,
+ MPTaskStateKind kind,
+ void * info) ;
+extern OSStatus
+MPSetTaskState(
+ MPTaskID task,
+ MPTaskStateKind kind,
+ void * info) ;
+extern OSStatus
+MPThrowException(
+ MPTaskID task,
+ MPExceptionKind kind) ;
+
+
+
+
+
+
+typedef UInt32 MPDebuggerLevel;
+enum {
+ kMPLowLevelDebugger = 0x00000000,
+ kMPMidLevelDebugger = 0x10000000,
+ kMPHighLevelDebugger = 0x20000000
+};
+extern OSStatus
+MPRegisterDebugger(
+ MPQueueID queue,
+ MPDebuggerLevel level) ;
+extern OSStatus
+MPUnregisterDebugger(MPQueueID queue) ;
+typedef void * ( * MPRemoteProcedure)(void * parameter);
+
+typedef UInt8 MPRemoteContext;
+enum {
+ kMPAnyRemoteContext = 0,
+ kMPOwningProcessRemoteContext = 1,
+ kMPInterruptRemoteContext = 2,
+ kMPAsyncInterruptRemoteContext = 3
+};
+extern void *
+MPRemoteCall(
+ MPRemoteProcedure remoteProc,
+ void * parameter,
+ MPRemoteContext context) ;
+extern Boolean
+_MPIsFullyInitialized(void) ;
+
+
+typedef Boolean ( * MPIsFullyInitializedProc)(void);
+extern void
+_MPLibraryVersion(
+ const char ** versionCString,
+ UInt32 * major,
+ UInt32 * minor,
+ UInt32 * release,
+ UInt32 * revision) ;
+extern Boolean
+_MPLibraryIsCompatible(
+ const char * versionCString,
+ UInt32 major,
+ UInt32 minor,
+ UInt32 release,
+ UInt32 revision) ;
+
+
+}
+extern "C" {
+
+
+enum {
+ kCFragResourceType = 'cfrg',
+ kCFragResourceID = 0,
+ kCFragLibraryFileType = 'shlb',
+ kCFragAllFileTypes = (long)0xFFFFFFFF
+};
+
+
+typedef OSType CFragArchitecture;
+enum {
+
+ kPowerPCCFragArch = 'pwpc',
+ kMotorola68KCFragArch = 'm68k',
+ kAnyCFragArch = 0x3F3F3F3F
+};
+
+
+
+enum {
+ kCompiledCFragArch = kPowerPCCFragArch
+};
+typedef UInt32 CFragVersionNumber;
+enum {
+ kNullCFragVersion = 0,
+ kWildcardCFragVersion = (long)0xFFFFFFFF
+};
+
+
+typedef UInt8 CFragUsage;
+enum {
+
+ kImportLibraryCFrag = 0,
+ kApplicationCFrag = 1,
+ kDropInAdditionCFrag = 2,
+ kStubLibraryCFrag = 3,
+ kWeakStubLibraryCFrag = 4
+};
+
+
+enum {
+ kIsCompleteCFrag = 0,
+ kFirstCFragUpdate = 1
+};
+
+
+enum {
+ kCFragGoesToEOF = 0
+};
+
+
+
+
+typedef UInt8 CFragLocatorKind;
+enum {
+
+ kMemoryCFragLocator = 0,
+ kDataForkCFragLocator = 1,
+ kResourceCFragLocator = 2,
+ kNamedFragmentCFragLocator = 4,
+ kCFBundleCFragLocator = 5,
+ kCFBundlePreCFragLocator = 6
+};
+union CFragUsage1Union {
+ UInt32 appStackSize;
+};
+typedef union CFragUsage1Union CFragUsage1Union;
+union CFragUsage2Union {
+ SInt16 appSubdirID;
+ UInt16 libFlags;
+};
+typedef union CFragUsage2Union CFragUsage2Union;
+enum {
+
+ kCFragLibUsageMapPrivatelyMask = 0x0001
+};
+
+union CFragWhere1Union {
+ UInt32 spaceID;
+};
+typedef union CFragWhere1Union CFragWhere1Union;
+union CFragWhere2Union {
+ UInt16 reserved;
+};
+typedef union CFragWhere2Union CFragWhere2Union;
+enum {
+ kDefaultCFragNameLen = 16
+};
+
+
+struct CFragResourceMember {
+ CFragArchitecture architecture;
+ UInt16 reservedA;
+ UInt8 reservedB;
+ UInt8 updateLevel;
+ CFragVersionNumber currentVersion;
+ CFragVersionNumber oldDefVersion;
+ CFragUsage1Union uUsage1;
+ CFragUsage2Union uUsage2;
+ CFragUsage usage;
+ CFragLocatorKind where;
+ UInt32 offset;
+ UInt32 length;
+ CFragWhere1Union uWhere1;
+ CFragWhere2Union uWhere2;
+ UInt16 extensionCount;
+ UInt16 memberSize;
+ unsigned char name[16];
+};
+typedef struct CFragResourceMember CFragResourceMember;
+typedef CFragResourceMember * CFragResourceMemberPtr;
+struct CFragResourceExtensionHeader {
+ UInt16 extensionKind;
+ UInt16 extensionSize;
+};
+typedef struct CFragResourceExtensionHeader CFragResourceExtensionHeader;
+typedef CFragResourceExtensionHeader * CFragResourceExtensionHeaderPtr;
+struct CFragResourceSearchExtension {
+ CFragResourceExtensionHeader header;
+ OSType libKind;
+ unsigned char qualifiers[1];
+};
+typedef struct CFragResourceSearchExtension CFragResourceSearchExtension;
+typedef CFragResourceSearchExtension * CFragResourceSearchExtensionPtr;
+enum {
+ kCFragResourceSearchExtensionKind = 0x30EE
+};
+
+
+struct CFragResource {
+ UInt32 reservedA;
+ UInt32 reservedB;
+ UInt16 reservedC;
+ UInt16 version;
+ UInt32 reservedD;
+ UInt32 reservedE;
+ UInt32 reservedF;
+ UInt32 reservedG;
+ UInt16 reservedH;
+ UInt16 memberCount;
+ CFragResourceMember firstMember;
+};
+typedef struct CFragResource CFragResource;
+typedef CFragResource * CFragResourcePtr;
+typedef CFragResourcePtr * CFragResourceHandle;
+enum {
+ kCurrCFragResourceVersion = 1
+};
+typedef MPProcessID CFragContextID;
+typedef struct OpaqueCFragConnectionID* CFragConnectionID;
+typedef struct OpaqueCFragClosureID* CFragClosureID;
+typedef struct OpaqueCFragContainerID* CFragContainerID;
+typedef OptionBits CFragLoadOptions;
+enum {
+
+ kReferenceCFrag = 0x0001,
+ kFindCFrag = 0x0002,
+ kPrivateCFragCopy = 0x0005
+};
+
+
+enum {
+ kUnresolvedCFragSymbolAddress = 0
+};
+
+
+typedef UInt8 CFragSymbolClass;
+enum {
+
+ kCodeCFragSymbol = 0,
+ kDataCFragSymbol = 1,
+ kTVectorCFragSymbol = 2,
+ kTOCCFragSymbol = 3,
+ kGlueCFragSymbol = 4
+};
+extern OSErr
+GetSharedLibrary(
+ ConstStr63Param libName,
+ CFragArchitecture archType,
+ CFragLoadOptions options,
+ CFragConnectionID * connID,
+ Ptr * mainAddr,
+ Str255 errMessage) ;
+extern OSErr
+GetDiskFragment(
+ const FSSpec * fileSpec,
+ UInt32 offset,
+ UInt32 length,
+ ConstStr63Param fragName,
+ CFragLoadOptions options,
+ CFragConnectionID * connID,
+ Ptr * mainAddr,
+ Str255 errMessage) ;
+extern OSErr
+GetMemFragment(
+ void * memAddr,
+ UInt32 length,
+ ConstStr63Param fragName,
+ CFragLoadOptions options,
+ CFragConnectionID * connID,
+ Ptr * mainAddr,
+ Str255 errMessage) ;
+extern OSErr
+CloseConnection(CFragConnectionID * connID) ;
+extern OSErr
+FindSymbol(
+ CFragConnectionID connID,
+ ConstStr255Param symName,
+ Ptr * symAddr,
+ CFragSymbolClass * symClass) ;
+extern OSErr
+CountSymbols(
+ CFragConnectionID connID,
+ long * symCount) ;
+extern OSErr
+GetIndSymbol(
+ CFragConnectionID connID,
+ long symIndex,
+ Str255 symName,
+ Ptr * symAddr,
+ CFragSymbolClass * symClass) ;
+struct CFragSystem7MemoryLocator {
+ LogicalAddress address;
+ UInt32 length;
+ Boolean inPlace;
+ UInt8 reservedA;
+ UInt16 reservedB;
+};
+typedef struct CFragSystem7MemoryLocator CFragSystem7MemoryLocator;
+struct CFragSystem7DiskFlatLocator {
+ FSSpec * fileSpec;
+ UInt32 offset;
+ UInt32 length;
+};
+typedef struct CFragSystem7DiskFlatLocator CFragSystem7DiskFlatLocator;
+
+struct CFragSystem7SegmentedLocator {
+ FSSpec * fileSpec;
+ OSType rsrcType;
+ SInt16 rsrcID;
+ UInt16 reservedA;
+};
+typedef struct CFragSystem7SegmentedLocator CFragSystem7SegmentedLocator;
+
+
+
+
+struct CFragCFBundleLocator {
+ CFBundleRef fragmentBundle;
+ UInt32 offset;
+ UInt32 length;
+};
+typedef struct CFragCFBundleLocator CFragCFBundleLocator;
+struct CFragSystem7Locator {
+ SInt32 where;
+ union {
+ CFragSystem7DiskFlatLocator onDisk;
+ CFragSystem7MemoryLocator inMem;
+ CFragSystem7SegmentedLocator inSegs;
+ CFragCFBundleLocator inBundle;
+ } u;
+};
+typedef struct CFragSystem7Locator CFragSystem7Locator;
+typedef CFragSystem7Locator * CFragSystem7LocatorPtr;
+struct CFragSystem7InitBlock {
+ CFragContextID contextID;
+ CFragClosureID closureID;
+ CFragConnectionID connectionID;
+ CFragSystem7Locator fragLocator;
+ StringPtr libName;
+ UInt32 reservedA;
+};
+typedef struct CFragSystem7InitBlock CFragSystem7InitBlock;
+typedef CFragSystem7InitBlock * CFragSystem7InitBlockPtr;
+typedef CFragSystem7InitBlock CFragInitBlock;
+typedef CFragSystem7InitBlockPtr CFragInitBlockPtr;
+
+typedef OSErr ( * CFragInitFunction)(const CFragInitBlock * initBlock);
+typedef void ( * CFragTermProcedure)(void);
+extern OSErr
+ConvertBundlePreLocator(CFragSystem7LocatorPtr initBlockLocator) ;
+enum {
+ kLoadCFrag = kReferenceCFrag
+};
+
+
+}
+
+
+
+extern "C" {
+
+
+
+typedef UInt32 FSAliasInfoBitmap;
+enum {
+ kFSAliasInfoNone = 0x00000000,
+ kFSAliasInfoVolumeCreateDate = 0x00000001,
+ kFSAliasInfoTargetCreateDate = 0x00000002,
+ kFSAliasInfoFinderInfo = 0x00000004,
+ kFSAliasInfoIsDirectory = 0x00000008,
+ kFSAliasInfoIDs = 0x00000010,
+ kFSAliasInfoFSInfo = 0x00000020,
+ kFSAliasInfoVolumeFlags = 0x00000040
+};
+
+enum {
+ rAliasType = 'alis'
+};
+
+enum {
+
+ kARMMountVol = 0x00000001,
+ kARMNoUI = 0x00000002,
+ kARMMultVols = 0x00000008,
+ kARMSearch = 0x00000100,
+ kARMSearchMore = 0x00000200,
+ kARMSearchRelFirst = 0x00000400,
+ kARMTryFileIDFirst = 0x00000800
+};
+
+enum {
+
+ asiZoneName = -3,
+ asiServerName = -2,
+ asiVolumeName = -1,
+ asiAliasName = 0,
+ asiParentName = 1
+};
+
+
+enum {
+ kResolveAliasFileNoUI = 0x00000001,
+ kResolveAliasTryFileIDFirst = 0x00000002
+};
+
+
+struct AliasRecord {
+ OSType userType;
+ unsigned short aliasSize;
+};
+typedef struct AliasRecord AliasRecord;
+typedef AliasRecord * AliasPtr;
+typedef AliasPtr * AliasHandle;
+
+struct FSAliasInfo {
+ UTCDateTime volumeCreateDate;
+ UTCDateTime targetCreateDate;
+ OSType fileType;
+ OSType fileCreator;
+ UInt32 parentDirID;
+ UInt32 nodeID;
+ UInt16 filesystemID;
+ UInt16 signature;
+ Boolean volumeIsBootVolume;
+ Boolean volumeIsAutomounted;
+ Boolean volumeIsEjectable;
+ Boolean volumeHasPersistentFileIDs;
+ Boolean isDirectory;
+};
+typedef struct FSAliasInfo FSAliasInfo;
+typedef FSAliasInfo * FSAliasInfoPtr;
+
+typedef short AliasInfoType;
+extern OSErr
+NewAlias(
+ const FSSpec * fromFile,
+ const FSSpec * target,
+ AliasHandle * alias) ;
+extern OSErr
+NewAliasMinimal(
+ const FSSpec * target,
+ AliasHandle * alias) ;
+extern OSErr
+NewAliasMinimalFromFullPath(
+ short fullPathLength,
+ const void * fullPath,
+ ConstStr32Param zoneName,
+ ConstStr31Param serverName,
+ AliasHandle * alias) ;
+extern OSErr
+ResolveAlias(
+ const FSSpec * fromFile,
+ AliasHandle alias,
+ FSSpec * target,
+ Boolean * wasChanged) ;
+extern OSErr
+GetAliasInfo(
+ AliasHandle alias,
+ AliasInfoType index,
+ Str63 theString) ;
+extern OSErr
+IsAliasFile(
+ const FSSpec * fileFSSpec,
+ Boolean * aliasFileFlag,
+ Boolean * folderFlag) ;
+extern OSErr
+ResolveAliasWithMountFlags(
+ const FSSpec * fromFile,
+ AliasHandle alias,
+ FSSpec * target,
+ Boolean * wasChanged,
+ unsigned long mountFlags) ;
+extern OSErr
+ResolveAliasFile(
+ FSSpec * theSpec,
+ Boolean resolveAliasChains,
+ Boolean * targetIsFolder,
+ Boolean * wasAliased) ;
+extern OSErr
+ResolveAliasFileWithMountFlags(
+ FSSpec * theSpec,
+ Boolean resolveAliasChains,
+ Boolean * targetIsFolder,
+ Boolean * wasAliased,
+ unsigned long mountFlags) ;
+extern OSErr
+FollowFinderAlias(
+ const FSSpec * fromFile,
+ AliasHandle alias,
+ Boolean logon,
+ FSSpec * target,
+ Boolean * wasChanged) ;
+extern OSErr
+UpdateAlias(
+ const FSSpec * fromFile,
+ const FSSpec * target,
+ AliasHandle alias,
+ Boolean * wasChanged) ;
+
+
+
+typedef Boolean ( * AliasFilterProcPtr)(CInfoPBPtr cpbPtr, Boolean *quitFlag, Ptr myDataPtr);
+typedef AliasFilterProcPtr AliasFilterUPP;
+extern AliasFilterUPP
+NewAliasFilterUPP(AliasFilterProcPtr userRoutine) ;
+extern void
+DisposeAliasFilterUPP(AliasFilterUPP userUPP) ;
+extern Boolean
+InvokeAliasFilterUPP(
+ CInfoPBPtr cpbPtr,
+ Boolean * quitFlag,
+ Ptr myDataPtr,
+ AliasFilterUPP userUPP) ;
+extern OSErr
+MatchAlias(
+ const FSSpec * fromFile,
+ unsigned long rulesMask,
+ AliasHandle alias,
+ short * aliasCount,
+ FSSpecArrayPtr aliasList,
+ Boolean * needsUpdate,
+ AliasFilterUPP aliasFilter,
+ void * yourDataPtr) ;
+extern OSErr
+ResolveAliasFileWithMountFlagsNoUI(
+ FSSpec * theSpec,
+ Boolean resolveAliasChains,
+ Boolean * targetIsFolder,
+ Boolean * wasAliased,
+ unsigned long mountFlags) ;
+extern OSErr
+MatchAliasNoUI(
+ const FSSpec * fromFile,
+ unsigned long rulesMask,
+ AliasHandle alias,
+ short * aliasCount,
+ FSSpecArrayPtr aliasList,
+ Boolean * needsUpdate,
+ AliasFilterUPP aliasFilter,
+ void * yourDataPtr) ;
+extern OSErr
+FSNewAlias(
+ const FSRef * fromFile,
+ const FSRef * target,
+ AliasHandle * inAlias) ;
+extern OSErr
+FSNewAliasMinimal(
+ const FSRef * target,
+ AliasHandle * inAlias) ;
+extern OSErr
+FSIsAliasFile(
+ const FSRef * fileRef,
+ Boolean * aliasFileFlag,
+ Boolean * folderFlag) ;
+extern OSErr
+FSResolveAliasWithMountFlags(
+ const FSRef * fromFile,
+ AliasHandle inAlias,
+ FSRef * target,
+ Boolean * wasChanged,
+ unsigned long mountFlags) ;
+extern OSErr
+FSResolveAlias(
+ const FSRef * fromFile,
+ AliasHandle alias,
+ FSRef * target,
+ Boolean * wasChanged) ;
+extern OSErr
+FSResolveAliasFileWithMountFlags(
+ FSRef * theRef,
+ Boolean resolveAliasChains,
+ Boolean * targetIsFolder,
+ Boolean * wasAliased,
+ unsigned long mountFlags) ;
+extern OSErr
+FSResolveAliasFile(
+ FSRef * theRef,
+ Boolean resolveAliasChains,
+ Boolean * targetIsFolder,
+ Boolean * wasAliased) ;
+extern OSErr
+FSFollowFinderAlias(
+ FSRef * fromFile,
+ AliasHandle alias,
+ Boolean logon,
+ FSRef * target,
+ Boolean * wasChanged) ;
+extern OSErr
+FSUpdateAlias(
+ const FSRef * fromFile,
+ const FSRef * target,
+ AliasHandle alias,
+ Boolean * wasChanged) ;
+extern OSErr
+FSNewAliasUnicode(
+ const FSRef * fromFile,
+ const FSRef * targetParentRef,
+ UniCharCount targetNameLength,
+ const UniChar * targetName,
+ AliasHandle * inAlias,
+ Boolean * isDirectory) ;
+extern OSErr
+FSNewAliasMinimalUnicode(
+ const FSRef * targetParentRef,
+ UniCharCount targetNameLength,
+ const UniChar * targetName,
+ AliasHandle * inAlias,
+ Boolean * isDirectory) ;
+extern OSErr
+FSMatchAlias(
+ const FSRef * fromFile,
+ unsigned long rulesMask,
+ AliasHandle inAlias,
+ short * aliasCount,
+ FSRef * aliasList,
+ Boolean * needsUpdate,
+ AliasFilterUPP aliasFilter,
+ void * yourDataPtr) ;
+extern OSErr
+FSMatchAliasNoUI(
+ const FSRef * fromFile,
+ unsigned long rulesMask,
+ AliasHandle inAlias,
+ short * aliasCount,
+ FSRef * aliasList,
+ Boolean * needsUpdate,
+ AliasFilterUPP aliasFilter,
+ void * yourDataPtr) ;
+extern OSStatus
+FSCopyAliasInfo(
+ AliasHandle inAlias,
+ HFSUniStr255 * targetName,
+ HFSUniStr255 * volumeName,
+ CFStringRef * pathString,
+ FSAliasInfoBitmap * whichInfo,
+ FSAliasInfo * info) ;
+
+
+
+
+
+
+}
+
+
+
+extern "C" {
+
+
+typedef struct OpaqueLocaleRef* LocaleRef;
+typedef UInt32 LocalePartMask;
+enum {
+
+ kLocaleLanguageMask = 1L << 0,
+ kLocaleLanguageVariantMask = 1L << 1,
+ kLocaleScriptMask = 1L << 2,
+ kLocaleScriptVariantMask = 1L << 3,
+ kLocaleRegionMask = 1L << 4,
+ kLocaleRegionVariantMask = 1L << 5,
+ kLocaleAllPartsMask = 0x0000003F
+};
+
+typedef FourCharCode LocaleOperationClass;
+
+typedef FourCharCode LocaleOperationVariant;
+struct LocaleAndVariant {
+ LocaleRef locale;
+ LocaleOperationVariant opVariant;
+};
+typedef struct LocaleAndVariant LocaleAndVariant;
+
+typedef UInt32 LocaleNameMask;
+enum {
+
+ kLocaleNameMask = 1L << 0,
+ kLocaleOperationVariantNameMask = 1L << 1,
+ kLocaleAndVariantNameMask = 0x00000003
+};
+extern OSStatus
+LocaleRefFromLangOrRegionCode(
+ LangCode lang,
+ RegionCode region,
+ LocaleRef * locale) ;
+extern OSStatus
+LocaleRefFromLocaleString(
+ const char localeString[],
+ LocaleRef * locale) ;
+extern OSStatus
+LocaleRefGetPartString(
+ LocaleRef locale,
+ LocalePartMask partMask,
+ ByteCount maxStringLen,
+ char partString[]) ;
+extern OSStatus
+LocaleStringToLangAndRegionCodes(
+ const char localeString[],
+ LangCode * lang,
+ RegionCode * region) ;
+extern OSStatus
+LocaleOperationCountLocales(
+ LocaleOperationClass opClass,
+ ItemCount * localeCount) ;
+extern OSStatus
+LocaleOperationGetLocales(
+ LocaleOperationClass opClass,
+ ItemCount maxLocaleCount,
+ ItemCount * actualLocaleCount,
+ LocaleAndVariant localeVariantList[]) ;
+extern OSStatus
+LocaleGetName(
+ LocaleRef locale,
+ LocaleOperationVariant opVariant,
+ LocaleNameMask nameMask,
+ LocaleRef displayLocale,
+ UniCharCount maxNameLen,
+ UniCharCount * actualNameLen,
+ UniChar displayName[]) ;
+extern OSStatus
+LocaleCountNames(
+ LocaleRef locale,
+ LocaleOperationVariant opVariant,
+ LocaleNameMask nameMask,
+ ItemCount * nameCount) ;
+extern OSStatus
+LocaleGetIndName(
+ LocaleRef locale,
+ LocaleOperationVariant opVariant,
+ LocaleNameMask nameMask,
+ ItemCount nameIndex,
+ UniCharCount maxNameLen,
+ UniCharCount * actualNameLen,
+ UniChar displayName[],
+ LocaleRef * displayLocale) ;
+extern OSStatus
+LocaleGetRegionLanguageName(
+ RegionCode region,
+ Str255 languageName) ;
+extern OSStatus
+LocaleOperationGetName(
+ LocaleOperationClass opClass,
+ LocaleRef displayLocale,
+ UniCharCount maxNameLen,
+ UniCharCount * actualNameLen,
+ UniChar displayName[]) ;
+extern OSStatus
+LocaleOperationCountNames(
+ LocaleOperationClass opClass,
+ ItemCount * nameCount) ;
+extern OSStatus
+LocaleOperationGetIndName(
+ LocaleOperationClass opClass,
+ ItemCount nameIndex,
+ UniCharCount maxNameLen,
+ UniCharCount * actualNameLen,
+ UniChar displayName[],
+ LocaleRef * displayLocale) ;
+
+
+
+
+
+}
+
+
+
+extern "C" {
+enum {
+ kBlessedBusErrorBait = 0x68F168F1
+};
+extern void
+DebugAssert(
+ OSType componentSignature,
+ UInt32 options,
+ const char * assertionString,
+ const char * exceptionLabelString,
+ const char * errorString,
+ const char * fileName,
+ long lineNumber,
+ void * value) ;
+
+
+
+
+
+enum {
+ k68kInterruptLevelMask = 0x00000007,
+ kInVBLTaskMask = 0x00000010,
+ kInDeferredTaskMask = 0x00000020,
+ kInSecondaryIntHandlerMask = 0x00000040,
+ kInNestedInterruptMask = 0x00000080
+};
+extern UInt32
+TaskLevel(void) ;
+
+
+
+
+
+enum {
+ kComponentDebugOption = 0
+};
+
+enum {
+ kGetDebugOption = 1,
+ kSetDebugOption = 2
+};
+typedef void ( * DebugComponentCallbackProcPtr)(SInt32 optionSelectorNum, UInt32 command, Boolean *optionSetting);
+typedef DebugComponentCallbackProcPtr DebugComponentCallbackUPP;
+extern OSStatus
+NewDebugComponent(
+ OSType componentSignature,
+ ConstStr255Param componentName,
+ DebugComponentCallbackUPP componentCallback) ;
+extern OSStatus
+NewDebugOption(
+ OSType componentSignature,
+ SInt32 optionSelectorNum,
+ ConstStr255Param optionName) ;
+extern OSStatus
+DisposeDebugComponent(OSType componentSignature) ;
+extern OSStatus
+GetDebugComponentInfo(
+ UInt32 index,
+ OSType * componentSignature,
+ Str255 componentName) ;
+extern OSStatus
+GetDebugOptionInfo(
+ UInt32 index,
+ OSType componentSignature,
+ SInt32 * optionSelectorNum,
+ Str255 optionName,
+ Boolean * optionSetting) ;
+extern OSStatus
+SetDebugOptionValue(
+ OSType componentSignature,
+ SInt32 optionSelectorNum,
+ Boolean newOptionSetting) ;
+typedef void ( * DebugAssertOutputHandlerProcPtr)(OSType componentSignature, UInt32 options, const char *assertionString, const char *exceptionLabelString, const char *errorString, const char *fileName, long lineNumber, void *value, ConstStr255Param outputMsg);
+typedef DebugAssertOutputHandlerProcPtr DebugAssertOutputHandlerUPP;
+extern void
+InstallDebugAssertOutputHandler(DebugAssertOutputHandlerUPP handler) ;
+extern DebugComponentCallbackUPP
+NewDebugComponentCallbackUPP(DebugComponentCallbackProcPtr userRoutine) ;
+extern DebugAssertOutputHandlerUPP
+NewDebugAssertOutputHandlerUPP(DebugAssertOutputHandlerProcPtr userRoutine) ;
+extern void
+DisposeDebugComponentCallbackUPP(DebugComponentCallbackUPP userUPP) ;
+extern void
+DisposeDebugAssertOutputHandlerUPP(DebugAssertOutputHandlerUPP userUPP) ;
+extern void
+InvokeDebugComponentCallbackUPP(
+ SInt32 optionSelectorNum,
+ UInt32 command,
+ Boolean * optionSetting,
+ DebugComponentCallbackUPP userUPP) ;
+extern void
+InvokeDebugAssertOutputHandlerUPP(
+ OSType componentSignature,
+ UInt32 options,
+ const char * assertionString,
+ const char * exceptionLabelString,
+ const char * errorString,
+ const char * fileName,
+ long lineNumber,
+ void * value,
+ ConstStr255Param outputMsg,
+ DebugAssertOutputHandlerUPP userUPP) ;
+
+
+
+}
+
+
+
+extern "C" {
+extern short
+PLstrcmp(
+ ConstStr255Param str1,
+ ConstStr255Param str2) ;
+extern short
+PLstrncmp(
+ ConstStr255Param str1,
+ ConstStr255Param str2,
+ short num) ;
+extern StringPtr
+PLstrcpy(
+ StringPtr str1,
+ ConstStr255Param str2) ;
+extern StringPtr
+PLstrncpy(
+ StringPtr str1,
+ ConstStr255Param str2,
+ short num) ;
+extern StringPtr
+PLstrcat(
+ StringPtr str1,
+ ConstStr255Param str2) ;
+extern StringPtr
+PLstrncat(
+ StringPtr str1,
+ ConstStr255Param str2,
+ short num) ;
+extern Ptr
+PLstrchr(
+ ConstStr255Param str1,
+ short ch1) ;
+extern Ptr
+PLstrrchr(
+ ConstStr255Param str1,
+ short ch1) ;
+extern Ptr
+PLstrpbrk(
+ ConstStr255Param str1,
+ ConstStr255Param str2) ;
+extern short
+PLstrspn(
+ ConstStr255Param str1,
+ ConstStr255Param str2) ;
+extern Ptr
+PLstrstr(
+ ConstStr255Param str1,
+ ConstStr255Param str2) ;
+extern short
+PLstrlen(ConstStr255Param str) ;
+extern short
+PLpos(
+ ConstStr255Param str1,
+ ConstStr255Param str2) ;
+
+
+
+
+
+}
+
+
+
+extern "C" {
+extern Boolean
+CompareAndSwap(
+ UInt32 oldVvalue,
+ UInt32 newValue,
+ UInt32 * OldValueAdr) ;
+extern Boolean
+TestAndClear(
+ UInt32 bit,
+ UInt8 * startAddress) ;
+extern Boolean
+TestAndSet(
+ UInt32 bit,
+ UInt8 * startAddress) ;
+extern SInt8
+IncrementAtomic8(SInt8 * value) ;
+extern SInt8
+DecrementAtomic8(SInt8 * value) ;
+extern SInt8
+AddAtomic8(
+ SInt32 amount,
+ SInt8 * value) ;
+extern UInt8
+BitAndAtomic8(
+ UInt32 mask,
+ UInt8 * value) ;
+extern UInt8
+BitOrAtomic8(
+ UInt32 mask,
+ UInt8 * value) ;
+extern UInt8
+BitXorAtomic8(
+ UInt32 mask,
+ UInt8 * value) ;
+extern SInt16
+IncrementAtomic16(SInt16 * value) ;
+extern SInt16
+DecrementAtomic16(SInt16 * value) ;
+extern SInt16
+AddAtomic16(
+ SInt32 amount,
+ SInt16 * value) ;
+extern UInt16
+BitAndAtomic16(
+ UInt32 mask,
+ UInt16 * value) ;
+extern UInt16
+BitOrAtomic16(
+ UInt32 mask,
+ UInt16 * value) ;
+extern UInt16
+BitXorAtomic16(
+ UInt32 mask,
+ UInt16 * value) ;
+extern SInt32
+IncrementAtomic(SInt32 * value) ;
+extern SInt32
+DecrementAtomic(SInt32 * value) ;
+extern SInt32
+AddAtomic(
+ SInt32 amount,
+ SInt32 * value) ;
+extern UInt32
+BitAndAtomic(
+ UInt32 mask,
+ UInt32 * value) ;
+extern UInt32
+BitOrAtomic(
+ UInt32 mask,
+ UInt32 * value) ;
+extern UInt32
+BitXorAtomic(
+ UInt32 mask,
+ UInt32 * value) ;
+
+
+
+
+
+}
+
+
+
+
+
+
+
+
+
+
+typedef void * RegPropertyValue;
+
+typedef UInt32 RegPropertyValueSize;
+
+
+
+
+
+typedef struct OpaqueDeviceNodePtr* DeviceNodePtr;
+struct RegEntryID {
+ unsigned short es_ver;
+ unsigned short es_gen;
+ DeviceNodePtr es_devid;
+ unsigned long es_spare1;
+ unsigned long es_spare2;
+};
+typedef struct RegEntryID RegEntryID;
+typedef RegEntryID * RegEntryIDPtr;
+
+
+
+
+typedef RegEntryID RegEntryRef;
+enum {
+ kRegCStrMaxEntryNameLength = 47
+};
+
+
+typedef char RegCStrEntryName;
+typedef char * RegCStrEntryNamePtr;
+
+typedef char RegCStrEntryNameBuf[48];
+typedef char RegCStrPathName;
+typedef UInt32 RegPathNameSize;
+enum {
+ kRegPathNameSeparator = ':',
+ kRegEntryNameTerminator = 0x00,
+ kRegPathNameTerminator = 0x00
+};
+
+
+
+
+
+
+enum {
+ kRegMaximumPropertyNameLength = 31,
+ kRegPropertyNameTerminator = 0x00
+};
+
+typedef char RegPropertyNameBuf[32];
+typedef char RegPropertyName;
+typedef char * RegPropertyNamePtr;
+enum {
+ kRegMaxPropertyNameLength = kRegMaximumPropertyNameLength
+};
+
+
+
+
+
+
+
+typedef UInt32 RegIterationOp;
+typedef RegIterationOp RegEntryIterationOp;
+enum {
+
+ kRegIterRoot = 0x00000002,
+ kRegIterParents = 0x00000003,
+
+ kRegIterChildren = 0x00000004,
+ kRegIterSubTrees = 0x00000005,
+ kRegIterDescendants = 0x00000005,
+
+ kRegIterSibling = 0x00000006,
+
+ kRegIterContinue = 0x00000001
+};
+typedef UInt32 RegModifiers;
+typedef RegModifiers RegEntryModifiers;
+typedef RegModifiers RegPropertyModifiers;
+enum {
+ kRegNoModifiers = 0x00000000,
+ kRegUniversalModifierMask = 0x0000FFFF,
+ kRegNameSpaceModifierMask = 0x00FF0000,
+ kRegModifierMask = (long)0xFF000000
+};
+
+
+enum {
+ kRegPropertyValueIsSavedToNVRAM = 0x00000020,
+ kRegPropertyValueIsSavedToDisk = 0x00000040
+};
+
+
+enum {
+ LatestNR_PEFVersion = 0x01030000
+};
+
+
+
+
+
+
+
+enum {
+ kSelectRegistryEntryIDInit = 0,
+ kSelectRegistryEntryIDCompare = 1,
+ kSelectRegistryEntryIDCopy = 2,
+ kSelectRegistryEntryIDDispose = 3,
+ kSelectRegistryCStrEntryCreate = 4,
+ kSelectRegistryEntryDelete = 5,
+ kSelectRegistryEntryCopy = 6,
+ kSelectRegistryEntryIterateCreate = 7,
+ kSelectRegistryEntryIterateDispose = 8,
+ kSelectRegistryEntryIterateSet = 9,
+ kSelectRegistryEntryIterate = 10,
+ kSelectRegistryEntrySearch = 11,
+ kSelectRegistryCStrEntryLookup = 12,
+ kSelectRegistryEntryToPathSize = 13,
+ kSelectRegistryCStrEntryToPath = 14,
+ kSelectRegistryCStrEntryToName = 15,
+ kSelectRegistryPropertyCreate = 16,
+ kSelectRegistryPropertyDelete = 17,
+ kSelectRegistryPropertyRename = 18,
+ kSelectRegistryPropertyIterateCreate = 19,
+ kSelectRegistryPropertyIterateDispose = 20,
+ kSelectRegistryPropertyIterate = 21,
+ kSelectRegistryPropertyGetSize = 22,
+ kSelectRegistryPropertyGet = 23,
+ kSelectRegistryPropertySet = 24,
+ kSelectRegistryEntryGetMod = 25,
+ kSelectRegistryEntrySetMod = 26,
+ kSelectRegistryPropertyGetMod = 27,
+ kSelectRegistryPropertySetMod = 28,
+ kSelectRegistryEntryMod = 29,
+ kSelectRegistryEntryPropertyMod = 30,
+ kSelectRegistryHighestSelector = kSelectRegistryEntryPropertyMod
+};
+typedef struct OpaqueRegEntryIter* RegEntryIter;
+typedef struct OpaqueRegPropertyIter* RegPropertyIter;
+extern "C" {
+
+
+
+
+enum {
+ chooserInitMsg = 11,
+ newSelMsg = 12,
+ fillListMsg = 13,
+ getSelMsg = 14,
+ selectMsg = 15,
+ deselectMsg = 16,
+ terminateMsg = 17,
+ buttonMsg = 19
+};
+
+
+
+enum {
+ chooserID = 1
+};
+
+
+
+enum {
+ initMsg = 1,
+ okMsg = 2,
+ cancelMsg = 3,
+ hitMsg = 4,
+ nulMsg = 5,
+ updateMsg = 6,
+ activateMsg = 7,
+ deactivateMsg = 8,
+ keyEvtMsg = 9,
+ superMsg = 10,
+ normalMsg = 11,
+ startupMsg = 12
+};
+
+
+
+enum {
+ goodbye = -1,
+ killCode = 1,
+ accEvent = 64,
+ accRun = 65,
+ accCursor = 66,
+ accMenu = 67,
+ accUndo = 68,
+ accCut = 70,
+ accCopy = 71,
+ accPaste = 72,
+ accClear = 73
+};
+
+
+
+
+
+enum {
+ ioInProgress = 1,
+ aRdCmd = 2,
+ aWrCmd = 3,
+ asyncTrpBit = 10,
+ noQueueBit = 9
+};
+
+
+enum {
+ dReadEnable = 0,
+ dWritEnable = 1,
+ dCtlEnable = 2,
+ dStatEnable = 3,
+ dNeedGoodBye = 4,
+ dNeedTime = 5,
+ dNeedLock = 6
+};
+
+enum {
+ dNeedLockMask = 0x4000,
+ dNeedTimeMask = 0x2000,
+ dNeedGoodByeMask = 0x1000,
+ dStatEnableMask = 0x0800,
+ dCtlEnableMask = 0x0400,
+ dWritEnableMask = 0x0200,
+ dReadEnableMask = 0x0100
+};
+
+
+
+enum {
+ dVMImmuneBit = 0,
+ dOpened = 5,
+ dRAMBased = 6,
+ drvrActive = 7
+};
+
+enum {
+ dVMImmuneMask = 0x0001,
+ dOpenedMask = 0x0020,
+ dRAMBasedMask = 0x0040,
+ drvrActiveMask = 0x0080
+};
+
+struct DRVRHeader {
+ short drvrFlags;
+ short drvrDelay;
+ short drvrEMask;
+ short drvrMenu;
+ short drvrOpen;
+ short drvrPrime;
+ short drvrCtl;
+ short drvrStatus;
+ short drvrClose;
+ unsigned char drvrName[1];
+};
+typedef struct DRVRHeader DRVRHeader;
+typedef DRVRHeader * DRVRHeaderPtr;
+typedef DRVRHeaderPtr * DRVRHeaderHandle;
+
+typedef UInt16 UnitNumber;
+typedef UInt32 DriverOpenCount;
+typedef SInt16 DriverRefNum;
+typedef SInt16 DriverFlags;
+typedef UInt32 IOCommandCode;
+enum {
+ kOpenCommand = 0,
+ kCloseCommand = 1,
+ kReadCommand = 2,
+ kWriteCommand = 3,
+ kControlCommand = 4,
+ kStatusCommand = 5,
+ kKillIOCommand = 6,
+ kInitializeCommand = 7,
+ kFinalizeCommand = 8,
+ kReplaceCommand = 9,
+ kSupersededCommand = 10,
+ kSuspendCommand = 11,
+ kResumeCommand = 12
+};
+
+enum {
+
+ kPowerManagementCommand = 13
+};
+
+typedef MPAddressSpaceID AddressSpaceID;
+typedef struct OpaqueIOCommandID* IOCommandID;
+extern OSErr
+PBCloseSync(ParmBlkPtr paramBlock) ;
+extern OSErr
+PBCloseAsync(ParmBlkPtr paramBlock) ;
+extern OSErr
+PBReadSync(ParmBlkPtr paramBlock) ;
+extern OSErr
+PBReadAsync(ParmBlkPtr paramBlock) ;
+extern OSErr
+PBWriteSync(ParmBlkPtr paramBlock) ;
+extern OSErr
+PBWriteAsync(ParmBlkPtr paramBlock) ;
+extern OSErr
+PBWaitIOComplete(
+ ParmBlkPtr paramBlock,
+ Duration timeout) ;
+typedef OSStatus ( * ShimEntryPoint)(Ptr paramBlock, Ptr refcon);
+
+
+}
+
+
+
+extern "C" {
+
+
+
+
+typedef struct OpaqueAreaID* AreaID;
+
+struct MachineInformationPowerPC {
+ UnsignedWide CTR;
+ UnsignedWide LR;
+ UnsignedWide PC;
+ unsigned long CR;
+ unsigned long XER;
+ unsigned long MSR;
+ unsigned long MQ;
+ unsigned long ExceptKind;
+ unsigned long DSISR;
+ UnsignedWide DAR;
+ UnsignedWide Reserved;
+};
+typedef struct MachineInformationPowerPC MachineInformationPowerPC;
+struct RegisterInformationPowerPC {
+ UnsignedWide R0;
+ UnsignedWide R1;
+ UnsignedWide R2;
+ UnsignedWide R3;
+ UnsignedWide R4;
+ UnsignedWide R5;
+ UnsignedWide R6;
+ UnsignedWide R7;
+ UnsignedWide R8;
+ UnsignedWide R9;
+ UnsignedWide R10;
+ UnsignedWide R11;
+ UnsignedWide R12;
+ UnsignedWide R13;
+ UnsignedWide R14;
+ UnsignedWide R15;
+ UnsignedWide R16;
+ UnsignedWide R17;
+ UnsignedWide R18;
+ UnsignedWide R19;
+ UnsignedWide R20;
+ UnsignedWide R21;
+ UnsignedWide R22;
+ UnsignedWide R23;
+ UnsignedWide R24;
+ UnsignedWide R25;
+ UnsignedWide R26;
+ UnsignedWide R27;
+ UnsignedWide R28;
+ UnsignedWide R29;
+ UnsignedWide R30;
+ UnsignedWide R31;
+};
+typedef struct RegisterInformationPowerPC RegisterInformationPowerPC;
+struct FPUInformationPowerPC {
+ UnsignedWide Registers[32];
+ unsigned long FPSCR;
+ unsigned long Reserved;
+};
+typedef struct FPUInformationPowerPC FPUInformationPowerPC;
+union Vector128 {
+
+
+
+ unsigned long l[4];
+ unsigned short s[8];
+ unsigned char c[16];
+};
+typedef union Vector128 Vector128;
+struct VectorInformationPowerPC {
+ Vector128 Registers[32];
+ Vector128 VSCR;
+ UInt32 VRsave;
+};
+typedef struct VectorInformationPowerPC VectorInformationPowerPC;
+
+enum {
+ kWriteReference = 0,
+ kReadReference = 1,
+ kFetchReference = 2,
+ writeReference = kWriteReference,
+ readReference = kReadReference,
+ fetchReference = kFetchReference
+};
+
+
+typedef unsigned long MemoryReferenceKind;
+struct MemoryExceptionInformation {
+ AreaID theArea;
+ LogicalAddress theAddress;
+ OSStatus theError;
+ MemoryReferenceKind theReference;
+};
+typedef struct MemoryExceptionInformation MemoryExceptionInformation;
+enum {
+ kUnknownException = 0,
+ kIllegalInstructionException = 1,
+ kTrapException = 2,
+ kAccessException = 3,
+ kUnmappedMemoryException = 4,
+ kExcludedMemoryException = 5,
+ kReadOnlyMemoryException = 6,
+ kUnresolvablePageFaultException = 7,
+ kPrivilegeViolationException = 8,
+ kTraceException = 9,
+ kInstructionBreakpointException = 10,
+ kDataBreakpointException = 11,
+ kIntegerException = 12,
+ kFloatingPointException = 13,
+ kStackOverflowException = 14,
+ kTaskTerminationException = 15,
+ kTaskCreationException = 16,
+ kDataAlignmentException = 17
+};
+typedef unsigned long ExceptionKind;
+union ExceptionInfo {
+ MemoryExceptionInformation * memoryInfo;
+};
+typedef union ExceptionInfo ExceptionInfo;
+struct ExceptionInformationPowerPC {
+ ExceptionKind theKind;
+ MachineInformationPowerPC * machineState;
+ RegisterInformationPowerPC * registerImage;
+ FPUInformationPowerPC * FPUImage;
+ ExceptionInfo info;
+ VectorInformationPowerPC * vectorImage;
+};
+typedef struct ExceptionInformationPowerPC ExceptionInformationPowerPC;
+
+typedef ExceptionInformationPowerPC ExceptionInformation;
+typedef MachineInformationPowerPC MachineInformation;
+typedef RegisterInformationPowerPC RegisterInformation;
+typedef FPUInformationPowerPC FPUInformation;
+typedef VectorInformationPowerPC VectorInformation;
+typedef OSStatus ( * ExceptionHandlerProcPtr)(ExceptionInformation * theException);
+typedef ExceptionHandlerProcPtr ExceptionHandlerUPP;
+extern ExceptionHandlerUPP
+NewExceptionHandlerUPP(ExceptionHandlerProcPtr userRoutine) ;
+extern void
+DisposeExceptionHandlerUPP(ExceptionHandlerUPP userUPP) ;
+extern OSStatus
+InvokeExceptionHandlerUPP(
+ ExceptionInformation * theException,
+ ExceptionHandlerUPP userUPP) ;
+typedef ExceptionHandlerUPP ExceptionHandlerTPP;
+typedef ExceptionHandlerTPP ExceptionHandler;
+extern ExceptionHandlerTPP InstallExceptionHandler(ExceptionHandlerTPP theHandler) ;
+
+
+
+
+
+
+}
+extern "C" {
+
+
+
+
+
+
+
+
+
+typedef struct OpaqueIOPreparationID* IOPreparationID;
+typedef struct OpaqueSoftwareInterruptID* SoftwareInterruptID;
+typedef struct OpaqueTaskID* TaskID;
+typedef struct OpaqueTimerID* TimerID;
+
+typedef UInt32 ExecutionLevel;
+enum {
+ kTaskLevel = 0,
+ kSoftwareInterruptLevel = 1,
+ kAcceptFunctionLevel = 2,
+ kKernelLevel = 3,
+ kSIHAcceptFunctionLevel = 4,
+ kSecondaryInterruptLevel = 5,
+ kHardwareInterruptLevel = 6,
+ kMPTaskLevel = 7
+};
+
+typedef void ( * SoftwareInterruptHandler)(void *p1, void *p2);
+typedef OSStatus ( * SecondaryInterruptHandler2)(void *p1, void *p2);
+
+
+struct LogicalAddressRange {
+ LogicalAddress address;
+ ByteCount count;
+};
+typedef struct LogicalAddressRange LogicalAddressRange;
+typedef LogicalAddressRange * LogicalAddressRangePtr;
+struct PhysicalAddressRange {
+ PhysicalAddress address;
+ ByteCount count;
+};
+typedef struct PhysicalAddressRange PhysicalAddressRange;
+typedef PhysicalAddressRange * PhysicalAddressRangePtr;
+
+typedef OptionBits IOPreparationOptions;
+enum {
+ kIOMultipleRanges = 0x00000001,
+ kIOLogicalRanges = 0x00000002,
+ kIOMinimalLogicalMapping = 0x00000004,
+ kIOShareMappingTables = 0x00000008,
+ kIOIsInput = 0x00000010,
+ kIOIsOutput = 0x00000020,
+ kIOCoherentDataPath = 0x00000040,
+ kIOTransferIsLogical = 0x00000080,
+ kIOClientIsUserMode = 0x00000080
+};
+
+typedef OptionBits IOPreparationState;
+enum {
+ kIOStateDone = 0x00000001
+};
+
+enum {
+ kInvalidPageAddress = (-1)
+};
+
+struct AddressRange {
+ void * base;
+ ByteCount length;
+};
+typedef struct AddressRange AddressRange;
+
+
+typedef LogicalAddress * LogicalMappingTablePtr;
+typedef PhysicalAddress * PhysicalMappingTablePtr;
+typedef AddressRange * AddressRangeTablePtr;
+struct MultipleAddressRange {
+ ItemCount entryCount;
+ AddressRangeTablePtr rangeTable;
+};
+typedef struct MultipleAddressRange MultipleAddressRange;
+
+
+
+
+struct IOPreparationTable {
+ IOPreparationOptions options;
+ IOPreparationState state;
+ IOPreparationID preparationID;
+ AddressSpaceID addressSpace;
+ ByteCount granularity;
+ ByteCount firstPrepared;
+ ByteCount lengthPrepared;
+ ItemCount mappingEntryCount;
+ LogicalMappingTablePtr logicalMapping;
+ PhysicalMappingTablePtr physicalMapping;
+ union {
+ AddressRange range;
+ MultipleAddressRange multipleRanges;
+ } rangeInfo;
+};
+typedef struct IOPreparationTable IOPreparationTable;
+
+typedef OptionBits IOCheckpointOptions;
+enum {
+ kNextIOIsInput = 0x00000001,
+ kNextIOIsOutput = 0x00000002,
+ kMoreIOTransfers = 0x00000004
+};
+
+
+
+typedef UInt32 ProcessorCacheMode;
+enum {
+ kProcessorCacheModeDefault = 0,
+ kProcessorCacheModeInhibited = 1,
+ kProcessorCacheModeWriteThrough = 2,
+ kProcessorCacheModeCopyBack = 3
+};
+
+
+
+
+
+
+enum {
+ kPageInformationVersion = 1
+};
+
+typedef UInt32 PageStateInformation;
+enum {
+ kPageIsProtected = 0x00000001,
+ kPageIsProtectedPrivileged = 0x00000002,
+ kPageIsModified = 0x00000004,
+ kPageIsReferenced = 0x00000008,
+ kPageIsLockedResident = 0x00000010,
+ kPageIsInMemory = 0x00000020,
+ kPageIsShared = 0x00000040,
+ kPageIsWriteThroughCached = 0x00000080,
+ kPageIsCopyBackCached = 0x00000100,
+ kPageIsHeldResident = 0x00000200,
+ kPageIsLocked = kPageIsLockedResident,
+ kPageIsResident = kPageIsInMemory
+};
+
+struct PageInformation {
+ AreaID area;
+ ItemCount count;
+ PageStateInformation information[1];
+};
+typedef struct PageInformation PageInformation;
+typedef PageInformation * PageInformationPtr;
+typedef LogicalAddress * DeviceLogicalAddressPtr;
+enum {
+ durationMicrosecond = -1L,
+ durationMillisecond = 1L,
+ durationSecond = 1000L,
+ durationMinute = 60000L,
+ durationHour = 3600000L,
+ durationDay = 86400000L,
+ durationNoWait = 0L,
+ durationForever = 0x7FFFFFFF
+};
+
+enum {
+ k8BitAccess = 0,
+ k16BitAccess = 1,
+ k32BitAccess = 2
+};
+
+typedef UnsignedWide Nanoseconds;
+extern AbsoluteTime
+UpTime(void) ;
+extern Nanoseconds
+AbsoluteToNanoseconds(AbsoluteTime absoluteTime) ;
+extern Duration
+AbsoluteToDuration(AbsoluteTime absoluteTime) ;
+extern AbsoluteTime
+NanosecondsToAbsolute(Nanoseconds nanoseconds) ;
+extern AbsoluteTime
+DurationToAbsolute(Duration duration) ;
+extern AbsoluteTime
+AddAbsoluteToAbsolute(
+ AbsoluteTime absoluteTime1,
+ AbsoluteTime absoluteTime2) ;
+extern AbsoluteTime
+SubAbsoluteFromAbsolute(
+ AbsoluteTime leftAbsoluteTime,
+ AbsoluteTime rightAbsoluteTime) ;
+extern AbsoluteTime
+AddNanosecondsToAbsolute(
+ Nanoseconds nanoseconds,
+ AbsoluteTime absoluteTime) ;
+extern AbsoluteTime
+AddDurationToAbsolute(
+ Duration duration,
+ AbsoluteTime absoluteTime) ;
+extern AbsoluteTime
+SubNanosecondsFromAbsolute(
+ Nanoseconds nanoseconds,
+ AbsoluteTime absoluteTime) ;
+extern AbsoluteTime
+SubDurationFromAbsolute(
+ Duration duration,
+ AbsoluteTime absoluteTime) ;
+extern Nanoseconds
+AbsoluteDeltaToNanoseconds(
+ AbsoluteTime leftAbsoluteTime,
+ AbsoluteTime rightAbsoluteTime) ;
+extern Duration
+AbsoluteDeltaToDuration(
+ AbsoluteTime leftAbsoluteTime,
+ AbsoluteTime rightAbsoluteTime) ;
+extern Nanoseconds
+DurationToNanoseconds(Duration theDuration) ;
+extern Duration
+NanosecondsToDuration(Nanoseconds theNanoseconds) ;
+typedef struct OpaqueInterruptSetID* InterruptSetID;
+typedef long InterruptMemberNumber;
+struct InterruptSetMember {
+ InterruptSetID setID;
+ InterruptMemberNumber member;
+};
+typedef struct InterruptSetMember InterruptSetMember;
+enum {
+ kISTChipInterruptSource = 0,
+ kISTOutputDMAInterruptSource = 1,
+ kISTInputDMAInterruptSource = 2,
+ kISTPropertyMemberCount = 3
+};
+
+typedef InterruptSetMember ISTProperty[3];
+
+
+typedef long InterruptReturnValue;
+enum {
+ kFirstMemberNumber = 1,
+ kIsrIsComplete = 0,
+ kIsrIsNotComplete = -1,
+ kMemberNumberParent = -2
+};
+
+typedef Boolean InterruptSourceState;
+enum {
+ kSourceWasEnabled = true,
+ kSourceWasDisabled = false
+};
+
+
+typedef InterruptMemberNumber ( * InterruptHandler)(InterruptSetMember ISTmember, void *refCon, UInt32 theIntCount);
+typedef void ( * InterruptEnabler)(InterruptSetMember ISTmember, void *refCon);
+typedef InterruptSourceState ( * InterruptDisabler)(InterruptSetMember ISTmember, void *refCon);
+enum {
+ kReturnToParentWhenComplete = 0x00000001,
+ kReturnToParentWhenNotComplete = 0x00000002
+};
+
+typedef OptionBits InterruptSetOptions;
+
+
+}
+
+
+
+
+
+
+
+extern "C" {
+
+
+struct NumFormatString {
+ UInt8 fLength;
+ UInt8 fVersion;
+ char data[254];
+};
+typedef struct NumFormatString NumFormatString;
+typedef NumFormatString NumFormatStringRec;
+typedef short FormatStatus;
+enum {
+ fVNumber = 0
+};
+
+typedef SInt8 FormatClass;
+enum {
+ fPositive = 0,
+ fNegative = 1,
+ fZero = 2
+};
+
+typedef SInt8 FormatResultType;
+enum {
+ fFormatOK = 0,
+ fBestGuess = 1,
+ fOutOfSynch = 2,
+ fSpuriousChars = 3,
+ fMissingDelimiter = 4,
+ fExtraDecimal = 5,
+ fMissingLiteral = 6,
+ fExtraExp = 7,
+ fFormatOverflow = 8,
+ fFormStrIsNAN = 9,
+ fBadPartsTable = 10,
+ fExtraPercent = 11,
+ fExtraSeparator = 12,
+ fEmptyFormatString = 13
+};
+
+struct FVector {
+ short start;
+ short length;
+};
+typedef struct FVector FVector;
+
+typedef FVector TripleInt[3];
+extern void
+StringToNum(
+ ConstStr255Param theString,
+ long * theNum) ;
+extern void
+NumToString(
+ long theNum,
+ Str255 theString) ;
+extern FormatStatus
+ExtendedToString(
+ const extended80 * x,
+ const NumFormatString * myCanonical,
+ const NumberParts * partsTable,
+ Str255 outString) ;
+extern FormatStatus
+StringToExtended(
+ ConstStr255Param source,
+ const NumFormatString * myCanonical,
+ const NumberParts * partsTable,
+ extended80 * x) ;
+extern FormatStatus
+StringToFormatRec(
+ ConstStr255Param inString,
+ const NumberParts * partsTable,
+ NumFormatString * outString) ;
+extern FormatStatus
+FormatRecToString(
+ const NumFormatString * myCanonical,
+ const NumberParts * partsTable,
+ Str255 outString,
+ TripleInt positions) ;
+
+
+}
+
+
+
+
+
+
+
+extern "C" {
+enum {
+
+ systemCurLang = -2,
+ systemDefLang = -3,
+ currentCurLang = -4,
+ currentDefLang = -5,
+ scriptCurLang = -6,
+ scriptDefLang = -7
+};
+
+
+enum {
+ iuSystemCurLang = systemCurLang,
+ iuSystemDefLang = systemDefLang,
+ iuCurrentCurLang = currentCurLang,
+ iuCurrentDefLang = currentDefLang,
+ iuScriptCurLang = scriptCurLang,
+ iuScriptDefLang = scriptDefLang
+};
+extern short
+ReplaceText(
+ Handle baseText,
+ Handle substitutionText,
+ Str15 key) ;
+extern short
+ScriptOrder(
+ ScriptCode script1,
+ ScriptCode script2) ;
+extern short
+CompareString(
+ ConstStr255Param aStr,
+ ConstStr255Param bStr,
+ Handle itl2Handle) ;
+extern short
+IdenticalString(
+ ConstStr255Param aStr,
+ ConstStr255Param bStr,
+ Handle itl2Handle) ;
+extern short
+StringOrder(
+ ConstStr255Param aStr,
+ ConstStr255Param bStr,
+ ScriptCode aScript,
+ ScriptCode bScript,
+ LangCode aLang,
+ LangCode bLang) ;
+extern short
+CompareText(
+ const void * aPtr,
+ const void * bPtr,
+ short aLen,
+ short bLen,
+ Handle itl2Handle) ;
+extern short
+IdenticalText(
+ const void * aPtr,
+ const void * bPtr,
+ short aLen,
+ short bLen,
+ Handle itl2Handle) ;
+extern short
+TextOrder(
+ const void * aPtr,
+ const void * bPtr,
+ short aLen,
+ short bLen,
+ ScriptCode aScript,
+ ScriptCode bScript,
+ LangCode aLang,
+ LangCode bLang) ;
+extern short
+LanguageOrder(
+ LangCode language1,
+ LangCode language2) ;
+extern short
+RelString(
+ ConstStr255Param str1,
+ ConstStr255Param str2,
+ Boolean caseSensitive,
+ Boolean diacSensitive) ;
+extern Boolean
+EqualString(
+ ConstStr255Param str1,
+ ConstStr255Param str2,
+ Boolean caseSensitive,
+ Boolean diacSensitive) ;
+extern short
+relstring(
+ const char * str1,
+ const char * str2,
+ Boolean caseSensitive,
+ Boolean diacSensitive) ;
+}
+
+
+
+extern "C" {
+
+
+struct ScriptRunStatus {
+ SInt8 script;
+ SInt8 runVariant;
+};
+typedef struct ScriptRunStatus ScriptRunStatus;
+struct BreakTable {
+ char charTypes[256];
+ short tripleLength;
+ short triples[1];
+};
+typedef struct BreakTable BreakTable;
+typedef BreakTable * BreakTablePtr;
+struct NBreakTable {
+ SInt8 flags1;
+ SInt8 flags2;
+ short version;
+ short classTableOff;
+ short auxCTableOff;
+ short backwdTableOff;
+ short forwdTableOff;
+ short doBackup;
+ short length;
+ char charTypes[256];
+ short tables[1];
+};
+typedef struct NBreakTable NBreakTable;
+typedef NBreakTable * NBreakTablePtr;
+extern long
+Munger(
+ Handle h,
+ long offset,
+ const void * ptr1,
+ long len1,
+ const void * ptr2,
+ long len2) ;
+extern StringHandle
+NewString(ConstStr255Param theString) ;
+extern void
+SetString(
+ StringHandle theString,
+ ConstStr255Param strNew) ;
+extern StringHandle
+GetString(short stringID) ;
+extern void
+GetIndString(
+ Str255 theString,
+ short strListID,
+ short index) ;
+extern void
+FindWordBreaks(
+ Ptr textPtr,
+ short textLength,
+ short offset,
+ Boolean leadingEdge,
+ BreakTablePtr breaks,
+ OffsetTable offsets,
+ ScriptCode script) ;
+extern void
+LowercaseText(
+ Ptr textPtr,
+ short len,
+ ScriptCode script) ;
+extern void
+UppercaseText(
+ Ptr textPtr,
+ short len,
+ ScriptCode script) ;
+extern void
+StripDiacritics(
+ Ptr textPtr,
+ short len,
+ ScriptCode script) ;
+extern void
+UppercaseStripDiacritics(
+ Ptr textPtr,
+ short len,
+ ScriptCode script) ;
+extern ScriptRunStatus
+FindScriptRun(
+ Ptr textPtr,
+ long textLen,
+ long * lenUsed) ;
+extern void
+UpperString(
+ Str255 theString,
+ Boolean diacSensitive) ;
+extern void
+upperstring(
+ char * theString,
+ Boolean diacSensitive) ;
+extern void
+c2pstrcpy(
+ Str255 dst,
+ const char * src) ;
+extern void
+p2cstrcpy(
+ char * dst,
+ ConstStr255Param src) ;
+extern void
+CopyPascalStringToC(
+ ConstStr255Param src,
+ char * dst) ;
+extern void
+CopyCStringToPascal(
+ const char * src,
+ Str255 dst) ;
+
+
+}
+
+
+
+extern "C" {
+
+
+extern Boolean
+BitTst(
+ const void * bytePtr,
+ long bitNum) ;
+extern void
+BitSet(
+ void * bytePtr,
+ long bitNum) ;
+extern void
+BitClr(
+ void * bytePtr,
+ long bitNum) ;
+extern long
+BitAnd(
+ long value1,
+ long value2) ;
+extern long
+BitOr(
+ long value1,
+ long value2) ;
+extern long
+BitXor(
+ long value1,
+ long value2) ;
+extern long
+BitNot(long value) ;
+extern long
+BitShift(
+ long value,
+ short count) ;
+
+
+
+
+
+
+
+
+}
+
+
+
+
+
+
+
+extern "C" {
+
+
+typedef UInt16 UCKeyOutput;
+typedef UInt16 UCKeyCharSeq;
+enum {
+ kUCKeyOutputStateIndexMask = 0x4000,
+ kUCKeyOutputSequenceIndexMask = 0x8000,
+ kUCKeyOutputTestForIndexMask = 0xC000,
+ kUCKeyOutputGetIndexMask = 0x3FFF
+};
+struct UCKeyStateRecord {
+ UCKeyCharSeq stateZeroCharData;
+ UInt16 stateZeroNextState;
+ UInt16 stateEntryCount;
+ UInt16 stateEntryFormat;
+
+
+ UInt32 stateEntryData[1];
+};
+typedef struct UCKeyStateRecord UCKeyStateRecord;
+
+
+
+
+enum {
+ kUCKeyStateEntryTerminalFormat = 0x0001,
+ kUCKeyStateEntryRangeFormat = 0x0002
+};
+
+
+
+
+
+
+struct UCKeyStateEntryTerminal {
+ UInt16 curState;
+ UCKeyCharSeq charData;
+};
+typedef struct UCKeyStateEntryTerminal UCKeyStateEntryTerminal;
+
+
+
+
+
+
+
+struct UCKeyStateEntryRange {
+ UInt16 curStateStart;
+ UInt8 curStateRange;
+ UInt8 deltaMultiplier;
+ UCKeyCharSeq charData;
+ UInt16 nextState;
+};
+typedef struct UCKeyStateEntryRange UCKeyStateEntryRange;
+struct UCKeyboardTypeHeader {
+ UInt32 keyboardTypeFirst;
+ UInt32 keyboardTypeLast;
+ ByteOffset keyModifiersToTableNumOffset;
+ ByteOffset keyToCharTableIndexOffset;
+ ByteOffset keyStateRecordsIndexOffset;
+ ByteOffset keyStateTerminatorsOffset;
+ ByteOffset keySequenceDataIndexOffset;
+};
+typedef struct UCKeyboardTypeHeader UCKeyboardTypeHeader;
+struct UCKeyboardLayout {
+
+ UInt16 keyLayoutHeaderFormat;
+ UInt16 keyLayoutDataVersion;
+ ByteOffset keyLayoutFeatureInfoOffset;
+ ItemCount keyboardTypeCount;
+ UCKeyboardTypeHeader keyboardTypeList[1];
+};
+typedef struct UCKeyboardLayout UCKeyboardLayout;
+
+struct UCKeyLayoutFeatureInfo {
+ UInt16 keyLayoutFeatureInfoFormat;
+ UInt16 reserved;
+ UniCharCount maxOutputStringLength;
+};
+typedef struct UCKeyLayoutFeatureInfo UCKeyLayoutFeatureInfo;
+
+struct UCKeyModifiersToTableNum {
+ UInt16 keyModifiersToTableNumFormat;
+ UInt16 defaultTableNum;
+ ItemCount modifiersCount;
+ UInt8 tableNum[1];
+
+
+};
+typedef struct UCKeyModifiersToTableNum UCKeyModifiersToTableNum;
+
+struct UCKeyToCharTableIndex {
+ UInt16 keyToCharTableIndexFormat;
+ UInt16 keyToCharTableSize;
+ ItemCount keyToCharTableCount;
+ ByteOffset keyToCharTableOffsets[1];
+
+
+
+
+
+
+};
+typedef struct UCKeyToCharTableIndex UCKeyToCharTableIndex;
+
+struct UCKeyStateRecordsIndex {
+ UInt16 keyStateRecordsIndexFormat;
+ UInt16 keyStateRecordCount;
+ ByteOffset keyStateRecordOffsets[1];
+
+
+
+
+};
+typedef struct UCKeyStateRecordsIndex UCKeyStateRecordsIndex;
+
+struct UCKeyStateTerminators {
+ UInt16 keyStateTerminatorsFormat;
+ UInt16 keyStateTerminatorCount;
+ UCKeyCharSeq keyStateTerminators[1];
+
+
+
+};
+typedef struct UCKeyStateTerminators UCKeyStateTerminators;
+
+struct UCKeySequenceDataIndex {
+ UInt16 keySequenceDataIndexFormat;
+ UInt16 charSequenceCount;
+ UInt16 charSequenceOffsets[1];
+
+
+
+
+
+};
+typedef struct UCKeySequenceDataIndex UCKeySequenceDataIndex;
+
+
+
+enum {
+ kUCKeyLayoutHeaderFormat = 0x1002,
+ kUCKeyLayoutFeatureInfoFormat = 0x2001,
+ kUCKeyModifiersToTableNumFormat = 0x3001,
+ kUCKeyToCharTableIndexFormat = 0x4001,
+ kUCKeyStateRecordsIndexFormat = 0x5001,
+ kUCKeyStateTerminatorsFormat = 0x6001,
+ kUCKeySequenceDataIndexFormat = 0x7001
+};
+enum {
+ kUCKeyActionDown = 0,
+ kUCKeyActionUp = 1,
+ kUCKeyActionAutoKey = 2,
+ kUCKeyActionDisplay = 3
+};
+
+
+
+
+
+
+
+enum {
+ kUCKeyTranslateNoDeadKeysBit = 0
+};
+
+enum {
+ kUCKeyTranslateNoDeadKeysMask = 1L << kUCKeyTranslateNoDeadKeysBit
+};
+
+
+
+
+
+
+
+enum {
+ kUnicodeCollationClass = 'ucol'
+};
+
+typedef struct OpaqueCollatorRef* CollatorRef;
+typedef UInt32 UCCollateOptions;
+enum {
+
+ kUCCollateComposeInsensitiveMask = 1L << 1,
+ kUCCollateWidthInsensitiveMask = 1L << 2,
+ kUCCollateCaseInsensitiveMask = 1L << 3,
+ kUCCollateDiacritInsensitiveMask = 1L << 4,
+ kUCCollatePunctuationSignificantMask = 1L << 15,
+ kUCCollateDigitsOverrideMask = 1L << 16,
+ kUCCollateDigitsAsNumberMask = 1L << 17
+};
+
+enum {
+ kUCCollateStandardOptions = kUCCollateComposeInsensitiveMask | kUCCollateWidthInsensitiveMask
+};
+
+
+
+
+
+enum {
+ kUCCollateTypeHFSExtended = 1
+};
+
+
+enum {
+ kUCCollateTypeSourceMask = 0x000000FF,
+ kUCCollateTypeShiftBits = 24
+};
+
+enum {
+ kUCCollateTypeMask = kUCCollateTypeSourceMask << kUCCollateTypeShiftBits
+};
+
+
+typedef UInt32 UCCollationValue;
+
+
+
+
+
+
+enum {
+ kUnicodeTextBreakClass = 'ubrk'
+};
+
+typedef struct OpaqueTextBreakLocatorRef* TextBreakLocatorRef;
+typedef UInt32 UCTextBreakType;
+enum {
+ kUCTextBreakCharMask = 1L << 0,
+ kUCTextBreakClusterMask = 1L << 2,
+ kUCTextBreakWordMask = 1L << 4,
+ kUCTextBreakLineMask = 1L << 6
+};
+
+typedef UInt32 UCTextBreakOptions;
+enum {
+ kUCTextBreakLeadingEdgeMask = 1L << 0,
+ kUCTextBreakGoBackwardsMask = 1L << 1,
+ kUCTextBreakIterateMask = 1L << 2
+};
+extern OSStatus
+UCKeyTranslate(
+ const UCKeyboardLayout * keyLayoutPtr,
+ UInt16 virtualKeyCode,
+ UInt16 keyAction,
+ UInt32 modifierKeyState,
+ UInt32 keyboardType,
+ OptionBits keyTranslateOptions,
+ UInt32 * deadKeyState,
+ UniCharCount maxStringLength,
+ UniCharCount * actualStringLength,
+ UniChar unicodeString[]) ;
+extern OSStatus
+UCCreateCollator(
+ LocaleRef locale,
+ LocaleOperationVariant opVariant,
+ UCCollateOptions options,
+ CollatorRef * collatorRef) ;
+extern OSStatus
+UCGetCollationKey(
+ CollatorRef collatorRef,
+ const UniChar * textPtr,
+ UniCharCount textLength,
+ ItemCount maxKeySize,
+ ItemCount * actualKeySize,
+ UCCollationValue collationKey[]) ;
+extern OSStatus
+UCCompareCollationKeys(
+ const UCCollationValue * key1Ptr,
+ ItemCount key1Length,
+ const UCCollationValue * key2Ptr,
+ ItemCount key2Length,
+ Boolean * equivalent,
+ SInt32 * order) ;
+extern OSStatus
+UCCompareText(
+ CollatorRef collatorRef,
+ const UniChar * text1Ptr,
+ UniCharCount text1Length,
+ const UniChar * text2Ptr,
+ UniCharCount text2Length,
+ Boolean * equivalent,
+ SInt32 * order) ;
+extern OSStatus
+UCDisposeCollator(CollatorRef * collatorRef) ;
+extern OSStatus
+UCCompareTextDefault(
+ UCCollateOptions options,
+ const UniChar * text1Ptr,
+ UniCharCount text1Length,
+ const UniChar * text2Ptr,
+ UniCharCount text2Length,
+ Boolean * equivalent,
+ SInt32 * order) ;
+extern OSStatus
+UCCompareTextNoLocale(
+ UCCollateOptions options,
+ const UniChar * text1Ptr,
+ UniCharCount text1Length,
+ const UniChar * text2Ptr,
+ UniCharCount text2Length,
+ Boolean * equivalent,
+ SInt32 * order) ;
+extern OSStatus
+UCCreateTextBreakLocator(
+ LocaleRef locale,
+ LocaleOperationVariant opVariant,
+ UCTextBreakType breakTypes,
+ TextBreakLocatorRef * breakRef) ;
+extern OSStatus
+UCFindTextBreak(
+ TextBreakLocatorRef breakRef,
+ UCTextBreakType breakType,
+ UCTextBreakOptions options,
+ const UniChar * textPtr,
+ UniCharCount textLength,
+ UniCharArrayOffset startOffset,
+ UniCharArrayOffset * breakOffset) ;
+extern OSStatus
+UCDisposeTextBreakLocator(TextBreakLocatorRef * breakRef) ;
+
+
+
+
+
+}
+
+
+
+extern double acos (double);
+extern double asin (double);
+extern double atan (double);
+extern double atan2 (double, double);
+extern double ceil (double);
+extern double cos (double);
+extern double cosh (double);
+extern double exp (double);
+extern double fabs (double);
+extern double floor (double);
+extern double fmod (double, double);
+extern double frexp (double, int *);
+extern double ldexp (double, int);
+extern double log10 (double);
+extern double log (double);
+extern double modf (double, double *);
+extern double pow (double, double);
+extern double sin (double);
+extern double sinh (double);
+extern double sqrt (double);
+extern double tan (double);
+extern double tanh (double);
+extern "C" {
+
+
+extern const double_t pi;
+extern double_t compound(double_t rate, double_t periods) ;
+extern double_t annuity(double_t rate, double_t periods) ;
+extern double_t randomx(double_t * x) ;
+typedef short relop;
+enum {
+ GREATERTHAN = 0,
+ LESSTHAN = 1,
+ EQUALTO = 2,
+ UNORDERED = 3
+};
+extern relop relation(double_t x, double_t y) ;
+struct decimal {
+ char sgn;
+ char unused;
+ short exp;
+ struct {
+ unsigned char length;
+ unsigned char text[36];
+ unsigned char unused;
+ } sig;
+};
+typedef struct decimal decimal;
+
+struct decform {
+ char style;
+ char unused;
+ short digits;
+};
+typedef struct decform decform;
+extern void num2dec(const decform *f, double_t x, decimal *d) ;
+extern double_t dec2num(const decimal * d) ;
+extern void dec2str(const decform *f, const decimal *d, char *s) ;
+extern void str2dec(const char *s, short *ix, decimal *d, short *vp) ;
+extern float dec2f(const decimal * d) ;
+extern short dec2s(const decimal * d) ;
+extern long dec2l(const decimal * d) ;
+extern long double cosl(long double x);
+
+
+ inline long double cosl(long double x) { return (long double) cos((double)(x)); }
+extern long double sinl(long double x);
+
+
+ inline long double sinl(long double x) { return (long double) sin((double)(x)); }
+extern long double tanl(long double x);
+
+
+ inline long double tanl(long double x) { return (long double) tan((double)(x)); }
+extern long double acosl(long double x);
+
+
+ inline long double acosl(long double x) { return (long double) acos((double)(x)); }
+extern long double asinl(long double x);
+
+
+ inline long double asinl(long double x) { return (long double) asin((double)(x)); }
+extern long double atanl(long double x);
+
+
+ inline long double atanl(long double x) { return (long double) atan((double)(x)); }
+extern long double atan2l(long double y, long double x);
+
+
+ inline long double atan2l(long double y, long double x) { return (long double) atan2((double)(y), (double)(x)); }
+extern long double coshl(long double x);
+
+
+ inline long double coshl(long double x) { return (long double) cosh((double)(x)); }
+extern long double sinhl(long double x);
+
+
+ inline long double sinhl(long double x) { return (long double) sinh((double)(x)); }
+extern long double tanhl(long double x);
+
+
+ inline long double tanhl(long double x) { return (long double) tanh((double)(x)); }
+extern long double acoshl(long double x);
+
+
+ inline long double acoshl(long double x) { return (long double) acosh((double)(x)); }
+extern long double asinhl(long double x);
+
+
+ inline long double asinhl(long double x) { return (long double) asinh((double)(x)); }
+extern long double atanhl(long double x);
+
+
+ inline long double atanhl(long double x) { return (long double) atanh((double)(x)); }
+extern long double expl(long double x);
+
+
+ inline long double expl(long double x) { return (long double) exp((double)(x)); }
+extern long double expm1l(long double x);
+
+
+ inline long double expm1l(long double x) { return (long double) expm1((double)(x)); }
+extern long double exp2l(long double x);
+
+
+ inline long double exp2l(long double x) { return (long double) exp2((double)(x)); }
+extern long double frexpl(long double x, int *exponent);
+
+
+ inline long double frexpl(long double x, int *exponent) { return (long double) frexp((double)(x), (exponent)); }
+extern long double ldexpl(long double x, int n);
+
+
+ inline long double ldexpl(long double x, int n) { return (long double) ldexp((double)(x), (n)); }
+extern long double logl(long double x);
+
+
+ inline long double logl(long double x) { return (long double) log((double)(x)); }
+extern long double log1pl(long double x);
+
+
+ inline long double log1pl(long double x) { return (long double) log1p((double)(x)); }
+extern long double log10l(long double x);
+
+
+ inline long double log10l(long double x) { return (long double) log10((double)(x)); }
+extern long double log2l(long double x);
+
+
+ inline long double log2l(long double x) { return (long double) log2((double)(x)); }
+extern long double logbl(long double x);
+
+
+ inline long double logbl(long double x) { return (long double) logb((double)(x)); }
+extern long double scalbl(long double x, long n);
+
+
+ inline long double scalbl(long double x, long n) { return (long double) scalb((double)(x), (n)); }
+extern long double fabsl(long double x);
+
+
+ inline long double fabsl(long double x) { return (long double) fabs((double)(x)); }
+extern long double hypotl(long double x, long double y);
+
+
+ inline long double hypotl(long double x, long double y) { return (long double) hypot((double)(x), (double)(y)); }
+extern long double powl(long double x, long double y);
+
+
+ inline long double powl(long double x, long double y) { return (long double) pow((double)(x), (double)(y)); }
+extern long double sqrtl(long double x);
+
+
+ inline long double sqrtl(long double x) { return (long double) sqrt((double)(x)); }
+extern long double erfl(long double x);
+
+
+ inline long double erfl(long double x) { return (long double) erf((double)(x)); }
+extern long double erfcl(long double x);
+
+
+ inline long double erfcl(long double x) { return (long double) erfc((double)(x)); }
+extern long double gammal(long double x);
+
+
+ inline long double gammal(long double x) { return (long double) gamma((double)(x)); }
+extern long double lgammal(long double x);
+
+
+ inline long double lgammal(long double x) { return (long double) lgamma((double)(x)); }
+extern long double ceill(long double x);
+
+
+ inline long double ceill(long double x) { return (long double) ceil((double)(x)); }
+extern long double floorl(long double x);
+
+
+ inline long double floorl(long double x) { return (long double) floor((double)(x)); }
+extern long double rintl(long double x);
+
+
+ inline long double rintl(long double x) { return (long double) rint((double)(x)); }
+extern long double nearbyintl(long double x);
+
+
+ inline long double nearbyintl(long double x) { return (long double) nearbyint((double)(x)); }
+extern long rinttoll(long double x);
+
+
+ inline long rinttoll(long double x) { return rinttol((double)(x)); }
+extern long double roundl(long double x);
+
+
+ inline long double roundl(long double x) { return (long double) round((double)(x)); }
+extern long roundtoll(long double x);
+
+
+ inline long roundtoll(long double x) { return roundtol((double)(x)); }
+extern long double truncl(long double x);
+
+
+ inline long double truncl(long double x) { return (long double) trunc((double)(x)); }
+extern long double remainderl(long double x, long double y);
+
+
+ inline long double remainderl(long double x, long double y) { return (long double) remainder((double)(x), (double)(y)); }
+extern long double remquol(long double x, long double y, int *quo);
+
+
+ inline long double remquol(long double x, long double y, int *quo) { return (long double) remquo((double)(x), (double)(y), (quo)); }
+extern long double copysignl(long double x, long double y);
+
+
+ inline long double copysignl(long double x, long double y) { return (long double) copysign((double)(x), (double)(y)); }
+extern long double fdiml(long double x, long double y);
+
+
+ inline long double fdiml(long double x, long double y) { return (long double) fdim((double)(x), (double)(y)); }
+extern long double fmaxl(long double x, long double y);
+
+
+ inline long double fmaxl(long double x, long double y) { return (long double) fmax((double)(x), (double)(y)); }
+extern long double fminl(long double x, long double y);
+
+
+ inline long double fminl(long double x, long double y) { return (long double) fmin((double)(x), (double)(y)); }
+extern relop relationl(long double x, long double y);
+
+
+ inline relop relationl(long double x, long double y) { return relation((double)(x), (double)(y)); }
+extern void num2decl(const decform *f, long double x, decimal *d);
+
+
+ inline void num2decl(const decform *f, long double x, decimal *d) { num2dec((f), (double)(x), (d)); }
+extern long double dec2numl(const decimal * d);
+
+
+ inline long double dec2numl(const decimal *d) { return (long double) dec2num(d); }
+extern double x80tod(const extended80 * x80) ;
+extern void dtox80(const double *x, extended80 *x80) ;
+extern void x80told(const extended80 *x80, long double *x);
+
+
+ inline void x80told(const extended80 *x80, long double *x) { *(x) = (long double) x80tod(x80); }
+extern void ldtox80(const long double *x, extended80 *x80);
+
+
+ inline void ldtox80(const long double *x, extended80 *x80) { double d = (double) *(x); dtox80(&d, (x80)); }
+
+
+}
+
+
+extern "C" {
+typedef long fenv_t;
+typedef long fexcept_t;
+
+
+enum {
+ FE_INEXACT = 0x02000000,
+ FE_DIVBYZERO = 0x04000000,
+ FE_UNDERFLOW = 0x08000000,
+ FE_OVERFLOW = 0x10000000,
+ FE_INVALID = 0x20000000,
+ FE_ALL_EXCEPT = 0x3E000000
+};
+
+
+
+enum {
+ FE_TONEAREST = 0x00000000,
+ FE_TOWARDZERO = 0x00000001,
+ FE_UPWARD = 0x00000002,
+ FE_DOWNWARD = 0x00000003
+};
+
+
+extern const fenv_t _FE_DFL_ENV;
+extern void feclearexcept(int excepts);
+extern void fegetexceptflag(fexcept_t *flagp, int excepts);
+
+
+
+
+
+
+
+extern void feraiseexcept(int excepts);
+extern void fesetexceptflag(const fexcept_t *flagp, int excepts);
+extern int fetestexcept(int excepts);
+extern int fegetround(void);
+extern int fesetround(int round);
+
+
+
+
+
+
+
+extern void fegetenv(fenv_t * envp);
+extern int feholdexcept(fenv_t * envp);
+extern void fesetenv(const fenv_t * envp);
+extern void feupdateenv(const fenv_t * envp);
+
+
+
+}
+
+extern "C" {
+
+
+
+typedef OSType TECPluginSignature;
+typedef UInt32 TECPluginVersion;
+
+enum {
+ kTECSignature = 'encv',
+ kTECUnicodePluginSignature = 'puni',
+ kTECJapanesePluginSignature = 'pjpn',
+ kTECChinesePluginSignature = 'pzho',
+ kTECKoreanPluginSignature = 'pkor'
+};
+
+
+
+typedef struct OpaqueTECObjectRef* TECObjectRef;
+typedef struct OpaqueTECSnifferObjectRef* TECSnifferObjectRef;
+typedef OSType TECPluginSig;
+struct TECConversionInfo {
+ TextEncoding sourceEncoding;
+ TextEncoding destinationEncoding;
+ UInt16 reserved1;
+ UInt16 reserved2;
+};
+typedef struct TECConversionInfo TECConversionInfo;
+extern OSStatus
+TECCountAvailableTextEncodings(ItemCount * numberEncodings) ;
+extern OSStatus
+TECGetAvailableTextEncodings(
+ TextEncoding availableEncodings[],
+ ItemCount maxAvailableEncodings,
+ ItemCount * actualAvailableEncodings) ;
+extern OSStatus
+TECCountDirectTextEncodingConversions(ItemCount * numberOfEncodings) ;
+extern OSStatus
+TECGetDirectTextEncodingConversions(
+ TECConversionInfo availableConversions[],
+ ItemCount maxAvailableConversions,
+ ItemCount * actualAvailableConversions) ;
+extern OSStatus
+TECCountDestinationTextEncodings(
+ TextEncoding inputEncoding,
+ ItemCount * numberOfEncodings) ;
+extern OSStatus
+TECGetDestinationTextEncodings(
+ TextEncoding inputEncoding,
+ TextEncoding destinationEncodings[],
+ ItemCount maxDestinationEncodings,
+ ItemCount * actualDestinationEncodings) ;
+extern OSStatus
+TECGetTextEncodingInternetName(
+ TextEncoding textEncoding,
+ Str255 encodingName) ;
+extern OSStatus
+TECGetTextEncodingFromInternetName(
+ TextEncoding * textEncoding,
+ ConstStr255Param encodingName) ;
+extern OSStatus
+TECCreateConverter(
+ TECObjectRef * newEncodingConverter,
+ TextEncoding inputEncoding,
+ TextEncoding outputEncoding) ;
+extern OSStatus
+TECCreateConverterFromPath(
+ TECObjectRef * newEncodingConverter,
+ const TextEncoding inPath[],
+ ItemCount inEncodings) ;
+extern OSStatus
+TECDisposeConverter(TECObjectRef newEncodingConverter) ;
+extern OSStatus
+TECClearConverterContextInfo(TECObjectRef encodingConverter) ;
+extern OSStatus
+TECConvertText(
+ TECObjectRef encodingConverter,
+ ConstTextPtr inputBuffer,
+ ByteCount inputBufferLength,
+ ByteCount * actualInputLength,
+ TextPtr outputBuffer,
+ ByteCount outputBufferLength,
+ ByteCount * actualOutputLength) ;
+extern OSStatus
+TECFlushText(
+ TECObjectRef encodingConverter,
+ TextPtr outputBuffer,
+ ByteCount outputBufferLength,
+ ByteCount * actualOutputLength) ;
+extern OSStatus
+TECCountSubTextEncodings(
+ TextEncoding inputEncoding,
+ ItemCount * numberOfEncodings) ;
+extern OSStatus
+TECGetSubTextEncodings(
+ TextEncoding inputEncoding,
+ TextEncoding subEncodings[],
+ ItemCount maxSubEncodings,
+ ItemCount * actualSubEncodings) ;
+extern OSStatus
+TECGetEncodingList(
+ TECObjectRef encodingConverter,
+ ItemCount * numEncodings,
+ Handle * encodingList) ;
+extern OSStatus
+TECCreateOneToManyConverter(
+ TECObjectRef * newEncodingConverter,
+ TextEncoding inputEncoding,
+ ItemCount numOutputEncodings,
+ const TextEncoding outputEncodings[]) ;
+extern OSStatus
+TECConvertTextToMultipleEncodings(
+ TECObjectRef encodingConverter,
+ ConstTextPtr inputBuffer,
+ ByteCount inputBufferLength,
+ ByteCount * actualInputLength,
+ TextPtr outputBuffer,
+ ByteCount outputBufferLength,
+ ByteCount * actualOutputLength,
+ TextEncodingRun outEncodingsBuffer[],
+ ItemCount maxOutEncodingRuns,
+ ItemCount * actualOutEncodingRuns) ;
+extern OSStatus
+TECFlushMultipleEncodings(
+ TECObjectRef encodingConverter,
+ TextPtr outputBuffer,
+ ByteCount outputBufferLength,
+ ByteCount * actualOutputLength,
+ TextEncodingRun outEncodingsBuffer[],
+ ItemCount maxOutEncodingRuns,
+ ItemCount * actualOutEncodingRuns) ;
+extern OSStatus
+TECCountWebTextEncodings(
+ RegionCode locale,
+ ItemCount * numberEncodings) ;
+extern OSStatus
+TECGetWebTextEncodings(
+ RegionCode locale,
+ TextEncoding availableEncodings[],
+ ItemCount maxAvailableEncodings,
+ ItemCount * actualAvailableEncodings) ;
+extern OSStatus
+TECCountMailTextEncodings(
+ RegionCode locale,
+ ItemCount * numberEncodings) ;
+extern OSStatus
+TECGetMailTextEncodings(
+ RegionCode locale,
+ TextEncoding availableEncodings[],
+ ItemCount maxAvailableEncodings,
+ ItemCount * actualAvailableEncodings) ;
+extern OSStatus
+TECCountAvailableSniffers(ItemCount * numberOfEncodings) ;
+extern OSStatus
+TECGetAvailableSniffers(
+ TextEncoding availableSniffers[],
+ ItemCount maxAvailableSniffers,
+ ItemCount * actualAvailableSniffers) ;
+extern OSStatus
+TECCreateSniffer(
+ TECSnifferObjectRef * encodingSniffer,
+ TextEncoding testEncodings[],
+ ItemCount numTextEncodings) ;
+extern OSStatus
+TECSniffTextEncoding(
+ TECSnifferObjectRef encodingSniffer,
+ TextPtr inputBuffer,
+ ByteCount inputBufferLength,
+ TextEncoding testEncodings[],
+ ItemCount numTextEncodings,
+ ItemCount numErrsArray[],
+ ItemCount maxErrs,
+ ItemCount numFeaturesArray[],
+ ItemCount maxFeatures) ;
+extern OSStatus
+TECDisposeSniffer(TECSnifferObjectRef encodingSniffer) ;
+extern OSStatus
+TECClearSnifferContextInfo(TECSnifferObjectRef encodingSniffer) ;
+
+
+}
+
+
+
+extern "C" {
+
+
+
+
+typedef struct OpaqueTextToUnicodeInfo* TextToUnicodeInfo;
+typedef struct OpaqueUnicodeToTextInfo* UnicodeToTextInfo;
+typedef struct OpaqueUnicodeToTextRunInfo* UnicodeToTextRunInfo;
+typedef const TextToUnicodeInfo ConstTextToUnicodeInfo;
+typedef const UnicodeToTextInfo ConstUnicodeToTextInfo;
+
+typedef SInt32 UnicodeMapVersion;
+enum {
+ kUnicodeUseLatestMapping = -1,
+ kUnicodeUseHFSPlusMapping = 4
+};
+
+
+struct UnicodeMapping {
+ TextEncoding unicodeEncoding;
+ TextEncoding otherEncoding;
+ UnicodeMapVersion mappingVersion;
+};
+typedef struct UnicodeMapping UnicodeMapping;
+typedef UnicodeMapping * UnicodeMappingPtr;
+typedef const UnicodeMapping * ConstUnicodeMappingPtr;
+
+enum {
+ kUnicodeUseFallbacksBit = 0,
+ kUnicodeKeepInfoBit = 1,
+ kUnicodeDirectionalityBits = 2,
+ kUnicodeVerticalFormBit = 4,
+ kUnicodeLooseMappingsBit = 5,
+ kUnicodeStringUnterminatedBit = 6,
+ kUnicodeTextRunBit = 7,
+ kUnicodeKeepSameEncodingBit = 8,
+ kUnicodeForceASCIIRangeBit = 9,
+ kUnicodeNoHalfwidthCharsBit = 10,
+ kUnicodeTextRunHeuristicsBit = 11,
+ kUnicodeMapLineFeedToReturnBit = 12
+};
+
+enum {
+ kUnicodeUseFallbacksMask = 1L << kUnicodeUseFallbacksBit,
+ kUnicodeKeepInfoMask = 1L << kUnicodeKeepInfoBit,
+ kUnicodeDirectionalityMask = 3L << kUnicodeDirectionalityBits,
+ kUnicodeVerticalFormMask = 1L << kUnicodeVerticalFormBit,
+ kUnicodeLooseMappingsMask = 1L << kUnicodeLooseMappingsBit,
+ kUnicodeStringUnterminatedMask = 1L << kUnicodeStringUnterminatedBit,
+ kUnicodeTextRunMask = 1L << kUnicodeTextRunBit,
+ kUnicodeKeepSameEncodingMask = 1L << kUnicodeKeepSameEncodingBit,
+ kUnicodeForceASCIIRangeMask = 1L << kUnicodeForceASCIIRangeBit,
+ kUnicodeNoHalfwidthCharsMask = 1L << kUnicodeNoHalfwidthCharsBit,
+ kUnicodeTextRunHeuristicsMask = 1L << kUnicodeTextRunHeuristicsBit,
+ kUnicodeMapLineFeedToReturnMask = 1L << kUnicodeMapLineFeedToReturnBit
+};
+
+
+enum {
+ kUnicodeDefaultDirection = 0,
+ kUnicodeLeftToRight = 1,
+ kUnicodeRightToLeft = 2
+};
+
+
+enum {
+ kUnicodeDefaultDirectionMask = kUnicodeDefaultDirection << kUnicodeDirectionalityBits,
+ kUnicodeLeftToRightMask = kUnicodeLeftToRight << kUnicodeDirectionalityBits,
+ kUnicodeRightToLeftMask = kUnicodeRightToLeft << kUnicodeDirectionalityBits
+};
+enum {
+ kUnicodeMatchUnicodeBaseBit = 0,
+ kUnicodeMatchUnicodeVariantBit = 1,
+ kUnicodeMatchUnicodeFormatBit = 2,
+ kUnicodeMatchOtherBaseBit = 3,
+ kUnicodeMatchOtherVariantBit = 4,
+ kUnicodeMatchOtherFormatBit = 5
+};
+
+enum {
+ kUnicodeMatchUnicodeBaseMask = 1L << kUnicodeMatchUnicodeBaseBit,
+ kUnicodeMatchUnicodeVariantMask = 1L << kUnicodeMatchUnicodeVariantBit,
+ kUnicodeMatchUnicodeFormatMask = 1L << kUnicodeMatchUnicodeFormatBit,
+ kUnicodeMatchOtherBaseMask = 1L << kUnicodeMatchOtherBaseBit,
+ kUnicodeMatchOtherVariantMask = 1L << kUnicodeMatchOtherVariantBit,
+ kUnicodeMatchOtherFormatMask = 1L << kUnicodeMatchOtherFormatBit
+};
+
+
+enum {
+ kUnicodeFallbackSequencingBits = 0
+};
+
+enum {
+ kUnicodeFallbackSequencingMask = 3L << kUnicodeFallbackSequencingBits,
+ kUnicodeFallbackInterruptSafeMask = 1L << 2
+};
+
+
+enum {
+ kUnicodeFallbackDefaultOnly = 0L,
+ kUnicodeFallbackCustomOnly = 1L,
+ kUnicodeFallbackDefaultFirst = 2L,
+ kUnicodeFallbackCustomFirst = 3L
+};
+
+
+
+typedef OSStatus ( * UnicodeToTextFallbackProcPtr)(UniChar *iSrcUniStr, ByteCount iSrcUniStrLen, ByteCount *oSrcConvLen, TextPtr oDestStr, ByteCount iDestStrLen, ByteCount *oDestConvLen, LogicalAddress iInfoPtr, ConstUnicodeMappingPtr iUnicodeMappingPtr);
+typedef UnicodeToTextFallbackProcPtr UnicodeToTextFallbackUPP;
+extern UnicodeToTextFallbackUPP
+NewUnicodeToTextFallbackUPP(UnicodeToTextFallbackProcPtr userRoutine) ;
+extern void
+DisposeUnicodeToTextFallbackUPP(UnicodeToTextFallbackUPP userUPP) ;
+extern OSStatus
+InvokeUnicodeToTextFallbackUPP(
+ UniChar * iSrcUniStr,
+ ByteCount iSrcUniStrLen,
+ ByteCount * oSrcConvLen,
+ TextPtr oDestStr,
+ ByteCount iDestStrLen,
+ ByteCount * oDestConvLen,
+ LogicalAddress iInfoPtr,
+ ConstUnicodeMappingPtr iUnicodeMappingPtr,
+ UnicodeToTextFallbackUPP userUPP) ;
+extern OSStatus
+CreateTextToUnicodeInfo(
+ ConstUnicodeMappingPtr iUnicodeMapping,
+ TextToUnicodeInfo * oTextToUnicodeInfo) ;
+extern OSStatus
+CreateTextToUnicodeInfoByEncoding(
+ TextEncoding iEncoding,
+ TextToUnicodeInfo * oTextToUnicodeInfo) ;
+extern OSStatus
+CreateUnicodeToTextInfo(
+ ConstUnicodeMappingPtr iUnicodeMapping,
+ UnicodeToTextInfo * oUnicodeToTextInfo) ;
+extern OSStatus
+CreateUnicodeToTextInfoByEncoding(
+ TextEncoding iEncoding,
+ UnicodeToTextInfo * oUnicodeToTextInfo) ;
+extern OSStatus
+CreateUnicodeToTextRunInfo(
+ ItemCount iNumberOfMappings,
+ const UnicodeMapping iUnicodeMappings[],
+ UnicodeToTextRunInfo * oUnicodeToTextInfo) ;
+extern OSStatus
+CreateUnicodeToTextRunInfoByEncoding(
+ ItemCount iNumberOfEncodings,
+ const TextEncoding iEncodings[],
+ UnicodeToTextRunInfo * oUnicodeToTextInfo) ;
+extern OSStatus
+CreateUnicodeToTextRunInfoByScriptCode(
+ ItemCount iNumberOfScriptCodes,
+ const ScriptCode iScripts[],
+ UnicodeToTextRunInfo * oUnicodeToTextInfo) ;
+extern OSStatus
+ChangeTextToUnicodeInfo(
+ TextToUnicodeInfo ioTextToUnicodeInfo,
+ ConstUnicodeMappingPtr iUnicodeMapping) ;
+extern OSStatus
+ChangeUnicodeToTextInfo(
+ UnicodeToTextInfo ioUnicodeToTextInfo,
+ ConstUnicodeMappingPtr iUnicodeMapping) ;
+extern OSStatus
+DisposeTextToUnicodeInfo(TextToUnicodeInfo * ioTextToUnicodeInfo) ;
+extern OSStatus
+DisposeUnicodeToTextInfo(UnicodeToTextInfo * ioUnicodeToTextInfo) ;
+extern OSStatus
+DisposeUnicodeToTextRunInfo(UnicodeToTextRunInfo * ioUnicodeToTextRunInfo) ;
+extern OSStatus
+ConvertFromTextToUnicode(
+ TextToUnicodeInfo iTextToUnicodeInfo,
+ ByteCount iSourceLen,
+ ConstLogicalAddress iSourceStr,
+ OptionBits iControlFlags,
+ ItemCount iOffsetCount,
+ ByteOffset iOffsetArray[],
+ ItemCount * oOffsetCount,
+ ByteOffset oOffsetArray[],
+ ByteCount iOutputBufLen,
+ ByteCount * oSourceRead,
+ ByteCount * oUnicodeLen,
+ UniChar oUnicodeStr[]) ;
+extern OSStatus
+ConvertFromUnicodeToText(
+ UnicodeToTextInfo iUnicodeToTextInfo,
+ ByteCount iUnicodeLen,
+ const UniChar iUnicodeStr[],
+ OptionBits iControlFlags,
+ ItemCount iOffsetCount,
+ ByteOffset iOffsetArray[],
+ ItemCount * oOffsetCount,
+ ByteOffset oOffsetArray[],
+ ByteCount iOutputBufLen,
+ ByteCount * oInputRead,
+ ByteCount * oOutputLen,
+ LogicalAddress oOutputStr) ;
+extern OSStatus
+ConvertFromUnicodeToTextRun(
+ UnicodeToTextRunInfo iUnicodeToTextInfo,
+ ByteCount iUnicodeLen,
+ const UniChar iUnicodeStr[],
+ OptionBits iControlFlags,
+ ItemCount iOffsetCount,
+ ByteOffset iOffsetArray[],
+ ItemCount * oOffsetCount,
+ ByteOffset oOffsetArray[],
+ ByteCount iOutputBufLen,
+ ByteCount * oInputRead,
+ ByteCount * oOutputLen,
+ LogicalAddress oOutputStr,
+ ItemCount iEncodingRunBufLen,
+ ItemCount * oEncodingRunOutLen,
+ TextEncodingRun oEncodingRuns[]) ;
+extern OSStatus
+ConvertFromUnicodeToScriptCodeRun(
+ UnicodeToTextRunInfo iUnicodeToTextInfo,
+ ByteCount iUnicodeLen,
+ const UniChar iUnicodeStr[],
+ OptionBits iControlFlags,
+ ItemCount iOffsetCount,
+ ByteOffset iOffsetArray[],
+ ItemCount * oOffsetCount,
+ ByteOffset oOffsetArray[],
+ ByteCount iOutputBufLen,
+ ByteCount * oInputRead,
+ ByteCount * oOutputLen,
+ LogicalAddress oOutputStr,
+ ItemCount iScriptRunBufLen,
+ ItemCount * oScriptRunOutLen,
+ ScriptCodeRun oScriptCodeRuns[]) ;
+extern OSStatus
+TruncateForTextToUnicode(
+ ConstTextToUnicodeInfo iTextToUnicodeInfo,
+ ByteCount iSourceLen,
+ ConstLogicalAddress iSourceStr,
+ ByteCount iMaxLen,
+ ByteCount * oTruncatedLen) ;
+extern OSStatus
+TruncateForUnicodeToText(
+ ConstUnicodeToTextInfo iUnicodeToTextInfo,
+ ByteCount iSourceLen,
+ const UniChar iSourceStr[],
+ OptionBits iControlFlags,
+ ByteCount iMaxLen,
+ ByteCount * oTruncatedLen) ;
+extern OSStatus
+ConvertFromPStringToUnicode(
+ TextToUnicodeInfo iTextToUnicodeInfo,
+ ConstStr255Param iPascalStr,
+ ByteCount iOutputBufLen,
+ ByteCount * oUnicodeLen,
+ UniChar oUnicodeStr[]) ;
+extern OSStatus
+ConvertFromUnicodeToPString(
+ UnicodeToTextInfo iUnicodeToTextInfo,
+ ByteCount iUnicodeLen,
+ const UniChar iUnicodeStr[],
+ Str255 oPascalStr) ;
+extern OSStatus
+CountUnicodeMappings(
+ OptionBits iFilter,
+ ConstUnicodeMappingPtr iFindMapping,
+ ItemCount * oActualCount) ;
+extern OSStatus
+QueryUnicodeMappings(
+ OptionBits iFilter,
+ ConstUnicodeMappingPtr iFindMapping,
+ ItemCount iMaxCount,
+ ItemCount * oActualCount,
+ UnicodeMapping oReturnedMappings[]) ;
+extern OSStatus
+SetFallbackUnicodeToText(
+ UnicodeToTextInfo iUnicodeToTextInfo,
+ UnicodeToTextFallbackUPP iFallback,
+ OptionBits iControlFlags,
+ LogicalAddress iInfoPtr) ;
+extern OSStatus
+SetFallbackUnicodeToTextRun(
+ UnicodeToTextRunInfo iUnicodeToTextRunInfo,
+ UnicodeToTextFallbackUPP iFallback,
+ OptionBits iControlFlags,
+ LogicalAddress iInfoPtr) ;
+extern OSStatus
+ResetTextToUnicodeInfo(TextToUnicodeInfo ioTextToUnicodeInfo) ;
+extern OSStatus
+ResetUnicodeToTextInfo(UnicodeToTextInfo ioUnicodeToTextInfo) ;
+extern OSStatus
+ResetUnicodeToTextRunInfo(UnicodeToTextRunInfo ioUnicodeToTextRunInfo) ;
+
+
+
+
+
+
+}
+
+
+
+extern "C" {
+
+
+
+
+typedef UInt16 ThreadState;
+enum {
+ kReadyThreadState = 0,
+ kStoppedThreadState = 1,
+ kRunningThreadState = 2
+};
+
+
+
+
+typedef void * ThreadTaskRef;
+
+typedef UInt32 ThreadStyle;
+enum {
+ kCooperativeThread = 1L << 0,
+ kPreemptiveThread = 1L << 1
+};
+
+
+typedef UInt32 ThreadID;
+enum {
+ kNoThreadID = 0,
+ kCurrentThreadID = 1,
+ kApplicationThreadID = 2
+};
+
+
+typedef UInt32 ThreadOptions;
+enum {
+ kNewSuspend = (1 << 0),
+ kUsePremadeThread = (1 << 1),
+ kCreateIfNeeded = (1 << 2),
+ kFPUNotNeeded = (1 << 3),
+ kExactMatchThread = (1 << 4)
+};
+
+
+struct SchedulerInfoRec {
+ UInt32 InfoRecSize;
+ ThreadID CurrentThreadID;
+ ThreadID SuggestedThreadID;
+ ThreadID InterruptedCoopThreadID;
+};
+typedef struct SchedulerInfoRec SchedulerInfoRec;
+typedef SchedulerInfoRec * SchedulerInfoRecPtr;
+
+
+
+
+
+
+typedef void * voidPtr;
+
+typedef voidPtr ( * ThreadEntryProcPtr)(void * threadParam);
+
+typedef ThreadID ( * ThreadSchedulerProcPtr)(SchedulerInfoRecPtr schedulerInfo);
+
+typedef void ( * ThreadSwitchProcPtr)(ThreadID threadBeingSwitched, void *switchProcParam);
+
+typedef void ( * ThreadTerminationProcPtr)(ThreadID threadTerminated, void *terminationProcParam);
+
+typedef void ( * DebuggerNewThreadProcPtr)(ThreadID threadCreated);
+
+typedef void ( * DebuggerDisposeThreadProcPtr)(ThreadID threadDeleted);
+
+typedef ThreadID ( * DebuggerThreadSchedulerProcPtr)(SchedulerInfoRecPtr schedulerInfo);
+typedef ThreadEntryProcPtr ThreadEntryUPP;
+typedef ThreadSchedulerProcPtr ThreadSchedulerUPP;
+typedef ThreadSwitchProcPtr ThreadSwitchUPP;
+typedef ThreadTerminationProcPtr ThreadTerminationUPP;
+typedef DebuggerNewThreadProcPtr DebuggerNewThreadUPP;
+typedef DebuggerDisposeThreadProcPtr DebuggerDisposeThreadUPP;
+typedef DebuggerThreadSchedulerProcPtr DebuggerThreadSchedulerUPP;
+extern ThreadEntryUPP
+NewThreadEntryUPP(ThreadEntryProcPtr userRoutine) ;
+extern ThreadSchedulerUPP
+NewThreadSchedulerUPP(ThreadSchedulerProcPtr userRoutine) ;
+extern ThreadSwitchUPP
+NewThreadSwitchUPP(ThreadSwitchProcPtr userRoutine) ;
+extern ThreadTerminationUPP
+NewThreadTerminationUPP(ThreadTerminationProcPtr userRoutine) ;
+extern DebuggerNewThreadUPP
+NewDebuggerNewThreadUPP(DebuggerNewThreadProcPtr userRoutine) ;
+extern DebuggerDisposeThreadUPP
+NewDebuggerDisposeThreadUPP(DebuggerDisposeThreadProcPtr userRoutine) ;
+extern DebuggerThreadSchedulerUPP
+NewDebuggerThreadSchedulerUPP(DebuggerThreadSchedulerProcPtr userRoutine) ;
+extern void
+DisposeThreadEntryUPP(ThreadEntryUPP userUPP) ;
+extern void
+DisposeThreadSchedulerUPP(ThreadSchedulerUPP userUPP) ;
+extern void
+DisposeThreadSwitchUPP(ThreadSwitchUPP userUPP) ;
+extern void
+DisposeThreadTerminationUPP(ThreadTerminationUPP userUPP) ;
+extern void
+DisposeDebuggerNewThreadUPP(DebuggerNewThreadUPP userUPP) ;
+extern void
+DisposeDebuggerDisposeThreadUPP(DebuggerDisposeThreadUPP userUPP) ;
+extern void
+DisposeDebuggerThreadSchedulerUPP(DebuggerThreadSchedulerUPP userUPP) ;
+extern voidPtr
+InvokeThreadEntryUPP(
+ void * threadParam,
+ ThreadEntryUPP userUPP) ;
+extern ThreadID
+InvokeThreadSchedulerUPP(
+ SchedulerInfoRecPtr schedulerInfo,
+ ThreadSchedulerUPP userUPP) ;
+extern void
+InvokeThreadSwitchUPP(
+ ThreadID threadBeingSwitched,
+ void * switchProcParam,
+ ThreadSwitchUPP userUPP) ;
+extern void
+InvokeThreadTerminationUPP(
+ ThreadID threadTerminated,
+ void * terminationProcParam,
+ ThreadTerminationUPP userUPP) ;
+extern void
+InvokeDebuggerNewThreadUPP(
+ ThreadID threadCreated,
+ DebuggerNewThreadUPP userUPP) ;
+extern void
+InvokeDebuggerDisposeThreadUPP(
+ ThreadID threadDeleted,
+ DebuggerDisposeThreadUPP userUPP) ;
+extern ThreadID
+InvokeDebuggerThreadSchedulerUPP(
+ SchedulerInfoRecPtr schedulerInfo,
+ DebuggerThreadSchedulerUPP userUPP) ;
+typedef ThreadEntryUPP ThreadEntryTPP;
+typedef ThreadSchedulerUPP ThreadSchedulerTPP;
+typedef ThreadSwitchUPP ThreadSwitchTPP;
+typedef ThreadTerminationUPP ThreadTerminationTPP;
+typedef DebuggerNewThreadUPP DebuggerNewThreadTPP;
+typedef DebuggerDisposeThreadUPP DebuggerDisposeThreadTPP;
+typedef DebuggerThreadSchedulerUPP DebuggerThreadSchedulerTPP;
+extern OSErr
+NewThread(
+ ThreadStyle threadStyle,
+ ThreadEntryTPP threadEntry,
+ void * threadParam,
+ Size stackSize,
+ ThreadOptions options,
+ void ** threadResult,
+ ThreadID * threadMade) ;
+extern OSErr
+SetThreadScheduler(ThreadSchedulerTPP threadScheduler) ;
+extern OSErr
+SetThreadSwitcher(
+ ThreadID thread,
+ ThreadSwitchTPP threadSwitcher,
+ void * switchProcParam,
+ Boolean inOrOut) ;
+extern OSErr
+SetThreadTerminator(
+ ThreadID thread,
+ ThreadTerminationTPP threadTerminator,
+ void * terminationProcParam) ;
+extern OSErr
+SetDebuggerNotificationProcs(
+ DebuggerNewThreadTPP notifyNewThread,
+ DebuggerDisposeThreadTPP notifyDisposeThread,
+ DebuggerThreadSchedulerTPP notifyThreadScheduler) ;
+extern OSErr
+CreateThreadPool(
+ ThreadStyle threadStyle,
+ SInt16 numToCreate,
+ Size stackSize) ;
+extern OSErr
+GetFreeThreadCount(
+ ThreadStyle threadStyle,
+ SInt16 * freeCount) ;
+extern OSErr
+GetSpecificFreeThreadCount(
+ ThreadStyle threadStyle,
+ Size stackSize,
+ SInt16 * freeCount) ;
+extern OSErr
+GetDefaultThreadStackSize(
+ ThreadStyle threadStyle,
+ Size * stackSize) ;
+extern OSErr
+ThreadCurrentStackSpace(
+ ThreadID thread,
+ UInt32 * freeStack) ;
+extern OSErr
+DisposeThread(
+ ThreadID threadToDump,
+ void * threadResult,
+ Boolean recycleThread) ;
+extern OSErr
+YieldToThread(ThreadID suggestedThread) ;
+extern OSErr
+YieldToAnyThread(void) ;
+extern OSErr
+GetCurrentThread(ThreadID * currentThreadID) ;
+extern OSErr
+GetThreadState(
+ ThreadID threadToGet,
+ ThreadState * threadState) ;
+extern OSErr
+SetThreadState(
+ ThreadID threadToSet,
+ ThreadState newState,
+ ThreadID suggestedThread) ;
+extern OSErr
+SetThreadStateEndCritical(
+ ThreadID threadToSet,
+ ThreadState newState,
+ ThreadID suggestedThread) ;
+extern OSErr
+ThreadBeginCritical(void) ;
+extern OSErr
+ThreadEndCritical(void) ;
+extern OSErr
+GetThreadCurrentTaskRef(ThreadTaskRef * threadTRef) ;
+extern OSErr
+GetThreadStateGivenTaskRef(
+ ThreadTaskRef threadTRef,
+ ThreadID threadToGet,
+ ThreadState * threadState) ;
+extern OSErr
+SetThreadReadyGivenTaskRef(
+ ThreadTaskRef threadTRef,
+ ThreadID threadToSet) ;
+
+
+
+
+
+}
+
+
+
+extern "C" {
+
+
+
+enum {
+ kOnSystemDisk = -32768L,
+ kOnAppropriateDisk = -32767,
+
+
+ kSystemDomain = -32766,
+ kLocalDomain = -32765,
+ kNetworkDomain = -32764,
+ kUserDomain = -32763,
+ kClassicDomain = -32762
+};
+
+
+
+
+
+enum {
+ kLastDomainConstant = kUserDomain
+};
+
+enum {
+ kCreateFolder = true,
+ kDontCreateFolder = false
+};
+
+enum {
+ kSystemFolderType = 'macs',
+ kDesktopFolderType = 'desk',
+ kSystemDesktopFolderType = 'sdsk',
+ kTrashFolderType = 'trsh',
+ kSystemTrashFolderType = 'strs',
+ kWhereToEmptyTrashFolderType = 'empt',
+ kPrintMonitorDocsFolderType = 'prnt',
+ kStartupFolderType = 'strt',
+ kShutdownFolderType = 'shdf',
+ kAppleMenuFolderType = 'amnu',
+ kControlPanelFolderType = 'ctrl',
+ kSystemControlPanelFolderType = 'sctl',
+ kExtensionFolderType = 'extn',
+ kFontsFolderType = 'font',
+ kPreferencesFolderType = 'pref',
+ kSystemPreferencesFolderType = 'sprf',
+ kTemporaryFolderType = 'temp'
+};
+extern OSErr
+FindFolder(
+ short vRefNum,
+ OSType folderType,
+ Boolean createFolder,
+ short * foundVRefNum,
+ long * foundDirID) ;
+extern OSErr
+FindFolderExtended(
+ short vol,
+ OSType foldType,
+ Boolean createFolder,
+ UInt32 flags,
+ void * data,
+ short * vRefNum,
+ long * dirID) ;
+extern OSErr
+ReleaseFolder(
+ short vRefNum,
+ OSType folderType) ;
+extern OSErr
+FSFindFolder(
+ short vRefNum,
+ OSType folderType,
+ Boolean createFolder,
+ FSRef * foundRef) ;
+extern OSErr
+FSFindFolderExtended(
+ short vol,
+ OSType foldType,
+ Boolean createFolder,
+ UInt32 flags,
+ void * data,
+ FSRef * foundRef) ;
+enum {
+ kExtensionDisabledFolderType = 'extD',
+ kControlPanelDisabledFolderType = 'ctrD',
+ kSystemExtensionDisabledFolderType = 'macD',
+ kStartupItemsDisabledFolderType = 'strD',
+ kShutdownItemsDisabledFolderType = 'shdD',
+ kApplicationsFolderType = 'apps',
+ kDocumentsFolderType = 'docs'
+};
+
+enum {
+
+ kVolumeRootFolderType = 'root',
+ kChewableItemsFolderType = 'flnt',
+ kApplicationSupportFolderType = 'asup',
+ kTextEncodingsFolderType = 'Ätex',
+ kStationeryFolderType = 'odst',
+ kOpenDocFolderType = 'odod',
+ kOpenDocShellPlugInsFolderType = 'odsp',
+ kEditorsFolderType = 'oded',
+ kOpenDocEditorsFolderType = 'Äodf',
+ kOpenDocLibrariesFolderType = 'odlb',
+ kGenEditorsFolderType = 'Äedi',
+ kHelpFolderType = 'Ählp',
+ kInternetPlugInFolderType = 'Änet',
+ kModemScriptsFolderType = 'Ämod',
+ kPrinterDescriptionFolderType = 'ppdf',
+ kPrinterDriverFolderType = 'Äprd',
+ kScriptingAdditionsFolderType = 'Äscr',
+ kSharedLibrariesFolderType = 'Älib',
+ kVoicesFolderType = 'fvoc',
+ kControlStripModulesFolderType = 'sdev',
+ kAssistantsFolderType = 'astÄ',
+ kUtilitiesFolderType = 'utiÄ',
+ kAppleExtrasFolderType = 'aexÄ',
+ kContextualMenuItemsFolderType = 'cmnu',
+ kMacOSReadMesFolderType = 'morÄ',
+ kALMModulesFolderType = 'walk',
+ kALMPreferencesFolderType = 'trip',
+ kALMLocationsFolderType = 'fall',
+ kColorSyncProfilesFolderType = 'prof',
+ kThemesFolderType = 'thme',
+ kFavoritesFolderType = 'favs',
+ kInternetFolderType = 'intÄ',
+ kAppearanceFolderType = 'appr',
+ kSoundSetsFolderType = 'snds',
+ kDesktopPicturesFolderType = 'dtpÄ',
+ kInternetSearchSitesFolderType = 'issf',
+ kFindSupportFolderType = 'fnds',
+ kFindByContentFolderType = 'fbcf',
+ kInstallerLogsFolderType = 'ilgf',
+ kScriptsFolderType = 'scrÄ',
+ kFolderActionsFolderType = 'fasf',
+ kLauncherItemsFolderType = 'laun',
+ kRecentApplicationsFolderType = 'rapp',
+ kRecentDocumentsFolderType = 'rdoc',
+ kRecentServersFolderType = 'rsvr',
+ kSpeakableItemsFolderType = 'spki',
+ kKeychainFolderType = 'kchn',
+ kQuickTimeExtensionsFolderType = 'qtex',
+ kDisplayExtensionsFolderType = 'dspl',
+ kMultiprocessingFolderType = 'mpxf',
+ kPrintingPlugInsFolderType = 'pplg'
+};
+
+
+
+
+enum {
+ kDomainTopLevelFolderType = 'dtop',
+ kDomainLibraryFolderType = 'dlib',
+ kColorSyncFolderType = 'sync',
+ kColorSyncCMMFolderType = 'ccmm',
+ kColorSyncScriptingFolderType = 'cscr',
+ kPrintersFolderType = 'impr',
+ kSpeechFolderType = 'spch',
+ kCarbonLibraryFolderType = 'carb',
+ kDocumentationFolderType = 'info',
+ kDeveloperDocsFolderType = 'ddoc',
+ kDeveloperHelpFolderType = 'devh',
+ kISSDownloadsFolderType = 'issd',
+ kUserSpecificTmpFolderType = 'utmp',
+ kCachedDataFolderType = 'cach',
+ kFrameworksFolderType = 'fram',
+ kPrivateFrameworksFolderType = 'pfrm',
+ kClassicDesktopFolderType = 'sdsk',
+
+
+ kDeveloperFolderType = 'devf',
+ kSystemSoundsFolderType = 'ssnd',
+ kComponentsFolderType = 'cmpd',
+ kQuickTimeComponentsFolderType = 'wcmp',
+ kCoreServicesFolderType = 'csrv',
+ kPictureDocumentsFolderType = 'pdoc',
+ kMovieDocumentsFolderType = 'mdoc',
+ kMusicDocumentsFolderType = 'µdoc',
+ kInternetSitesFolderType = 'site',
+ kPublicFolderType = 'pubb',
+ kAudioSupportFolderType = 'adio',
+ kAudioSoundsFolderType = 'asnd',
+ kAudioSoundBanksFolderType = 'bank',
+ kAudioAlertSoundsFolderType = 'alrt',
+ kAudioPlugInsFolderType = 'aplg',
+ kAudioComponentsFolderType = 'acmp',
+ kKernelExtensionsFolderType = 'kext',
+ kDirectoryServicesFolderType = 'dsrv',
+ kDirectoryServicesPlugInsFolderType = 'dplg',
+ kInstallerReceiptsFolderType = 'rcpt',
+ kFileSystemSupportFolderType = 'fsys',
+ kAppleShareSupportFolderType = 'shar',
+ kAppleShareAuthenticationFolderType = 'auth',
+ kMIDIDriversFolderType = 'midi',
+ kKeyboardLayoutsFolderType = 'klay',
+ kIndexFilesFolderType = 'indx',
+ kFindByContentIndexesFolderType = 'fbcx',
+ kManagedItemsFolderType = 'mang',
+ kBootTimeStartupItemsFolderType = 'empz'
+};
+
+enum {
+ kLocalesFolderType = 'Äloc',
+ kFindByContentPluginsFolderType = 'fbcp'
+};
+
+enum {
+ kUsersFolderType = 'usrs',
+ kCurrentUserFolderType = 'cusr',
+ kCurrentUserRemoteFolderLocation = 'rusf',
+ kCurrentUserRemoteFolderType = 'rusr',
+ kSharedUserDataFolderType = 'sdat',
+ kVolumeSettingsFolderType = 'vsfd'
+};
+
+enum {
+ kAppleshareAutomountServerAliasesFolderType = 'srvÄ',
+ kPreMacOS91ApplicationsFolderType = '\8cpps',
+ kPreMacOS91InstallerLogsFolderType = '\94lgf',
+ kPreMacOS91AssistantsFolderType = '\8cstÄ',
+ kPreMacOS91UtilitiesFolderType = '\9ftiÄ',
+ kPreMacOS91AppleExtrasFolderType = '\8cexÄ',
+ kPreMacOS91MacOSReadMesFolderType = 'µorÄ',
+ kPreMacOS91InternetFolderType = '\94ntÄ',
+ kPreMacOS91AutomountedServersFolderType = '§rvÄ',
+ kPreMacOS91StationeryFolderType = '¿dst'
+};
+
+
+enum {
+ kCreateFolderAtBoot = 0x00000002,
+ kCreateFolderAtBootBit = 1,
+ kFolderCreatedInvisible = 0x00000004,
+ kFolderCreatedInvisibleBit = 2,
+ kFolderCreatedNameLocked = 0x00000008,
+ kFolderCreatedNameLockedBit = 3,
+ kFolderCreatedAdminPrivs = 0x00000010,
+ kFolderCreatedAdminPrivsBit = 4
+};
+
+enum {
+ kFolderInUserFolder = 0x00000020,
+ kFolderInUserFolderBit = 5,
+ kFolderTrackedByAlias = 0x00000040,
+ kFolderTrackedByAliasBit = 6,
+ kFolderInRemoteUserFolderIfAvailable = 0x00000080,
+ kFolderInRemoteUserFolderIfAvailableBit = 7,
+ kFolderNeverMatchedInIdentifyFolder = 0x00000100,
+ kFolderNeverMatchedInIdentifyFolderBit = 8,
+ kFolderMustStayOnSameVolume = 0x00000200,
+ kFolderMustStayOnSameVolumeBit = 9,
+ kFolderManagerFolderInMacOS9FolderIfMacOSXIsInstalledMask = 0x00000400,
+ kFolderManagerFolderInMacOS9FolderIfMacOSXIsInstalledBit = 10,
+ kFolderInLocalOrRemoteUserFolder = kFolderInUserFolder | kFolderInRemoteUserFolderIfAvailable
+};
+
+typedef UInt32 FolderDescFlags;
+
+enum {
+ kRelativeFolder = 'relf',
+ kSpecialFolder = 'spcf'
+};
+
+typedef OSType FolderClass;
+
+enum {
+ kBlessedFolder = 'blsf',
+ kRootFolder = 'rotf'
+};
+
+enum {
+ kCurrentUserFolderLocation = 'cusf'
+};
+
+typedef OSType FolderType;
+typedef OSType FolderLocation;
+
+struct FolderDesc {
+ Size descSize;
+ FolderType foldType;
+ FolderDescFlags flags;
+ FolderClass foldClass;
+ FolderType foldLocation;
+ OSType badgeSignature;
+ OSType badgeType;
+ UInt32 reserved;
+ StrFileName name;
+};
+typedef struct FolderDesc FolderDesc;
+typedef FolderDesc * FolderDescPtr;
+
+typedef UInt32 RoutingFlags;
+struct FolderRouting {
+ Size descSize;
+ OSType fileType;
+ FolderType routeFromFolder;
+ FolderType routeToFolder;
+ RoutingFlags flags;
+};
+typedef struct FolderRouting FolderRouting;
+typedef FolderRouting * FolderRoutingPtr;
+
+
+enum {
+
+
+
+ kFindFolderRedirectionFlagUseDistinctUserFoldersBit = 0,
+
+
+ kFindFolderRedirectionFlagUseGivenVRefAndDirIDAsUserFolderBit = 1,
+
+
+ kFindFolderRedirectionFlagsUseGivenVRefNumAndDirIDAsRemoteUserFolderBit = 2
+};
+
+struct FindFolderUserRedirectionGlobals {
+ UInt32 version;
+ UInt32 flags;
+
+ Str31 userName;
+ short userNameScript;
+
+ short currentUserFolderVRefNum;
+ long currentUserFolderDirID;
+
+ short remoteUserFolderVRefNum;
+ long remoteUserFolderDirID;
+};
+typedef struct FindFolderUserRedirectionGlobals FindFolderUserRedirectionGlobals;
+typedef FindFolderUserRedirectionGlobals * FindFolderUserRedirectionGlobalsPtr;
+enum {
+ kFolderManagerUserRedirectionGlobalsCurrentVersion = 1
+};
+
+
+
+
+
+enum {
+ kFindFolderExtendedFlagsDoNotFollowAliasesBit = 0,
+ kFindFolderExtendedFlagsDoNotUseUserFolderBit = 1,
+ kFindFolderExtendedFlagsUseOtherUserRecord = 0x01000000
+};
+
+typedef OSStatus ( * FolderManagerNotificationProcPtr)(OSType message, void *arg, void *userRefCon);
+typedef FolderManagerNotificationProcPtr FolderManagerNotificationUPP;
+extern FolderManagerNotificationUPP
+NewFolderManagerNotificationUPP(FolderManagerNotificationProcPtr userRoutine) ;
+extern void
+DisposeFolderManagerNotificationUPP(FolderManagerNotificationUPP userUPP) ;
+extern OSStatus
+InvokeFolderManagerNotificationUPP(
+ OSType message,
+ void * arg,
+ void * userRefCon,
+ FolderManagerNotificationUPP userUPP) ;
+
+enum {
+ kFolderManagerNotificationMessageUserLogIn = 'log+',
+ kFolderManagerNotificationMessagePreUserLogIn = 'logj',
+ kFolderManagerNotificationMessageUserLogOut = 'log-',
+ kFolderManagerNotificationMessagePostUserLogOut = 'logp',
+ kFolderManagerNotificationDiscardCachedData = 'dche',
+ kFolderManagerNotificationMessageLoginStartup = 'stup'
+};
+
+
+
+enum {
+ kDoNotRemoveWhenCurrentApplicationQuitsBit = 0,
+ kDoNotRemoveWheCurrentApplicationQuitsBit = kDoNotRemoveWhenCurrentApplicationQuitsBit
+};
+
+
+enum {
+ kStopIfAnyNotificationProcReturnsErrorBit = 31
+};
+extern OSErr
+AddFolderDescriptor(
+ FolderType foldType,
+ FolderDescFlags flags,
+ FolderClass foldClass,
+ FolderLocation foldLocation,
+ OSType badgeSignature,
+ OSType badgeType,
+ ConstStrFileNameParam name,
+ Boolean replaceFlag) ;
+extern OSErr
+GetFolderDescriptor(
+ FolderType foldType,
+ Size descSize,
+ FolderDesc * foldDesc) ;
+extern OSErr
+GetFolderTypes(
+ UInt32 requestedTypeCount,
+ UInt32 * totalTypeCount,
+ FolderType * theTypes) ;
+extern OSErr
+RemoveFolderDescriptor(FolderType foldType) ;
+extern OSErr
+GetFolderName(
+ short vRefNum,
+ OSType foldType,
+ short * foundVRefNum,
+ StrFileName name) ;
+extern OSErr
+AddFolderRouting(
+ OSType fileType,
+ FolderType routeFromFolder,
+ FolderType routeToFolder,
+ RoutingFlags flags,
+ Boolean replaceFlag) ;
+extern OSErr
+RemoveFolderRouting(
+ OSType fileType,
+ FolderType routeFromFolder) ;
+extern OSErr
+FindFolderRouting(
+ OSType fileType,
+ FolderType routeFromFolder,
+ FolderType * routeToFolder,
+ RoutingFlags * flags) ;
+extern OSErr
+GetFolderRoutings(
+ UInt32 requestedRoutingCount,
+ UInt32 * totalRoutingCount,
+ Size routingSize,
+ FolderRouting * theRoutings) ;
+extern OSErr
+InvalidateFolderDescriptorCache(
+ short vRefNum,
+ long dirID) ;
+extern OSErr
+IdentifyFolder(
+ short vRefNum,
+ long dirID,
+ FolderType * foldType) ;
+extern OSErr
+FolderManagerRegisterNotificationProc(
+ FolderManagerNotificationUPP notificationProc,
+ void * refCon,
+ UInt32 options) ;
+extern OSErr
+FolderManagerUnregisterNotificationProc(
+ FolderManagerNotificationUPP notificationProc,
+ void * refCon) ;
+extern OSStatus
+FolderManagerRegisterCallNotificationProcs(
+ OSType message,
+ void * arg,
+ UInt32 options) ;
+struct MultiUserGestalt {
+
+ short giVersion;
+ short giReserved0;
+ short giReserved1;
+ short giReserved2;
+ short giReserved3;
+ FSSpec giReserved4;
+
+
+ short giDocsVRefNum;
+ long giDocsDirID;
+ short giForceSaves;
+ short giForceOpens;
+ Str31 giSetupName;
+ Str31 giUserName;
+ Str31 giFrontAppName;
+ short giReserved5;
+ short giIsOn;
+
+
+
+
+
+ short giUserLoggedInType;
+ char giUserEncryptPwd[16];
+ short giUserEnvironment;
+ long giReserved6;
+ long giReserved7;
+ Boolean giDisableScrnShots;
+
+
+ Boolean giSupportsAsyncFSCalls;
+ short giPrefsVRefNum;
+ long giPrefsDirID;
+ unsigned long giUserLogInTime;
+ Boolean giUsingPrintQuotas;
+ Boolean giUsingDiskQuotas;
+
+
+ Boolean giInSystemAccess;
+ Boolean giUserFolderEnabled;
+ short giReserved8;
+ long giReserved9;
+ Boolean giInLoginScreen;
+
+
+
+
+};
+typedef struct MultiUserGestalt MultiUserGestalt;
+typedef MultiUserGestalt * MultiUserGestaltPtr;
+typedef MultiUserGestaltPtr * MultiUserGestaltHandle;
+
+
+
+
+
+}
+
+
+
+extern "C" {
+
+
+
+enum {
+
+ kTMTaskActive = (1L << 15)
+};
+
+typedef struct TMTask TMTask;
+typedef TMTask * TMTaskPtr;
+typedef void ( * TimerProcPtr)(TMTaskPtr tmTaskPtr);
+typedef TimerProcPtr TimerUPP;
+struct TMTask {
+ QElemPtr qLink;
+ short qType;
+ TimerUPP tmAddr;
+ long tmCount;
+ long tmWakeUp;
+ long tmReserved;
+};
+extern void
+InsTime(QElemPtr tmTaskPtr) ;
+extern void
+InsXTime(QElemPtr tmTaskPtr) ;
+extern void
+PrimeTime(
+ QElemPtr tmTaskPtr,
+ long count) ;
+extern void
+RmvTime(QElemPtr tmTaskPtr) ;
+extern OSErr
+InstallTimeTask(QElemPtr tmTaskPtr) ;
+extern OSErr
+InstallXTimeTask(QElemPtr tmTaskPtr) ;
+extern OSErr
+PrimeTimeTask(
+ QElemPtr tmTaskPtr,
+ long count) ;
+extern OSErr
+RemoveTimeTask(QElemPtr tmTaskPtr) ;
+extern void
+Microseconds(UnsignedWide * microTickCount) ;
+extern TimerUPP
+NewTimerUPP(TimerProcPtr userRoutine) ;
+extern void
+DisposeTimerUPP(TimerUPP userUPP) ;
+extern void
+InvokeTimerUPP(
+ TMTaskPtr tmTaskPtr,
+ TimerUPP userUPP) ;
+
+
+
+
+
+
+}
+
+
+
+enum {
+
+ kMPQueueInfoVersion = 1L | (kOpaqueQueueID << 16),
+ kMPSemaphoreInfoVersion = 1L | (kOpaqueSemaphoreID << 16),
+ kMPEventInfoVersion = 1L | (kOpaqueEventID << 16),
+ kMPCriticalRegionInfoVersion = 1L | (kOpaqueCriticalRegionID << 16),
+ kMPNotificationInfoVersion = 1L | (kOpaqueNotificationID << 16),
+ kMPAddressSpaceInfoVersion = 1L | (kOpaqueAddressSpaceID << 16)
+};
+
+
+struct MPQueueInfo {
+ PBVersion version;
+
+ MPProcessID processID;
+ OSType queueName;
+
+ ItemCount nWaiting;
+ MPTaskID waitingTaskID;
+
+ ItemCount nMessages;
+ ItemCount nReserved;
+
+ void * p1;
+ void * p2;
+ void * p3;
+};
+typedef struct MPQueueInfo MPQueueInfo;
+struct MPSemaphoreInfo {
+ PBVersion version;
+
+ MPProcessID processID;
+ OSType semaphoreName;
+
+ ItemCount nWaiting;
+ MPTaskID waitingTaskID;
+
+ ItemCount maximum;
+ ItemCount count;
+};
+typedef struct MPSemaphoreInfo MPSemaphoreInfo;
+struct MPEventInfo {
+ PBVersion version;
+
+ MPProcessID processID;
+ OSType eventName;
+
+ ItemCount nWaiting;
+ MPTaskID waitingTaskID;
+
+ MPEventFlags events;
+};
+typedef struct MPEventInfo MPEventInfo;
+struct MPCriticalRegionInfo {
+ PBVersion version;
+
+ MPProcessID processID;
+ OSType regionName;
+
+ ItemCount nWaiting;
+ MPTaskID waitingTaskID;
+
+ MPTaskID owningTask;
+ ItemCount count;
+};
+typedef struct MPCriticalRegionInfo MPCriticalRegionInfo;
+struct MPNotificationInfo {
+ PBVersion version;
+
+ MPProcessID processID;
+ OSType notificationName;
+
+ MPQueueID queueID;
+ void * p1;
+ void * p2;
+ void * p3;
+
+ MPEventID eventID;
+ MPEventFlags events;
+
+ MPSemaphoreID semaphoreID;
+};
+typedef struct MPNotificationInfo MPNotificationInfo;
+struct MPAddressSpaceInfo {
+ PBVersion version;
+
+ MPProcessID processID;
+ MPCoherenceID groupID;
+ ItemCount nTasks;
+ UInt32 vsid[16];
+};
+typedef struct MPAddressSpaceInfo MPAddressSpaceInfo;
+extern "C" {
+
+
+extern Ptr LMGetMemTop(void) ;
+extern void LMSetMemTop(Ptr value) ;
+extern Ptr LMGetBufPtr(void) ;
+extern void LMSetBufPtr(Ptr value) ;
+extern Ptr LMGetHeapEnd(void) ;
+extern void LMSetHeapEnd(Ptr value) ;
+extern UInt8 LMGetCPUFlag(void) ;
+extern void LMSetCPUFlag(UInt8 value) ;
+extern SInt32 LMGetRndSeed(void) ;
+extern void LMSetRndSeed(SInt32 value) ;
+extern UInt8 LMGetSEvtEnb(void) ;
+extern void LMSetSEvtEnb(UInt8 value) ;
+extern SInt16 LMGetBootDrive(void) ;
+extern void LMSetBootDrive(SInt16 value) ;
+extern SInt16 LMGetMemErr(void) ;
+extern void LMSetMemErr(SInt16 value) ;
+extern UInt8 LMGetSdVolume(void) ;
+extern void LMSetSdVolume(UInt8 value) ;
+extern Ptr LMGetSoundPtr(void) ;
+extern void LMSetSoundPtr(Ptr value) ;
+extern Ptr LMGetSoundBase(void) ;
+extern void LMSetSoundBase(Ptr value) ;
+extern UInt8 LMGetSoundLevel(void) ;
+extern void LMSetSoundLevel(UInt8 value) ;
+extern SInt16 LMGetCurPitch(void) ;
+extern void LMSetCurPitch(SInt16 value) ;
+extern THz LMGetSysZone(void) ;
+extern void LMSetSysZone(THz value) ;
+extern THz LMGetApplZone(void) ;
+extern void LMSetApplZone(THz value) ;
+extern UInt8 LMGetScrDmpEnb(void) ;
+extern void LMSetScrDmpEnb(UInt8 value) ;
+extern SInt32 LMGetBufTgFNum(void) ;
+extern void LMSetBufTgFNum(SInt32 value) ;
+extern SInt16 LMGetBufTgFFlg(void) ;
+extern void LMSetBufTgFFlg(SInt16 value) ;
+extern SInt16 LMGetBufTgFBkNum(void) ;
+extern void LMSetBufTgFBkNum(SInt16 value) ;
+extern SInt32 LMGetBufTgDate(void) ;
+extern void LMSetBufTgDate(SInt32 value) ;
+extern SInt32 LMGetMinStack(void) ;
+extern void LMSetMinStack(SInt32 value) ;
+extern SInt32 LMGetDefltStack(void) ;
+extern void LMSetDefltStack(SInt32 value) ;
+extern Handle LMGetGZRootHnd(void) ;
+extern void LMSetGZRootHnd(Handle value) ;
+extern Handle LMGetGZMoveHnd(void) ;
+extern void LMSetGZMoveHnd(Handle value) ;
+extern UniversalProcPtr LMGetToExtFS(void) ;
+extern void LMSetToExtFS(UniversalProcPtr value) ;
+extern UniversalProcPtr LMGetJStash(void) ;
+extern void LMSetJStash(UniversalProcPtr value) ;
+extern SInt16 LMGetCurApRefNum(void) ;
+extern void LMSetCurApRefNum(SInt16 value) ;
+extern Ptr LMGetCurStackBase(void) ;
+extern void LMSetCurStackBase(Ptr value) ;
+extern SInt16 LMGetCurPageOption(void) ;
+extern void LMSetCurPageOption(SInt16 value) ;
+extern SInt16 LMGetPrintErr(void) ;
+extern void LMSetPrintErr(SInt16 value) ;
+extern SInt16 LMGetApFontID(void) ;
+extern void LMSetApFontID(SInt16 value) ;
+extern SInt32 LMGetOneOne(void) ;
+extern void LMSetOneOne(SInt32 value) ;
+extern SInt32 LMGetMinusOne(void) ;
+extern void LMSetMinusOne(SInt32 value) ;
+extern SInt16 LMGetSysMap(void) ;
+extern void LMSetSysMap(SInt16 value) ;
+extern UInt8 LMGetResLoad(void) ;
+extern void LMSetResLoad(UInt8 value) ;
+extern SInt16 LMGetResErr(void) ;
+extern void LMSetResErr(SInt16 value) ;
+extern UInt8 LMGetTmpResLoad(void) ;
+extern void LMSetTmpResLoad(UInt8 value) ;
+extern Ptr LMGetIntlSpec(void) ;
+extern void LMSetIntlSpec(Ptr value) ;
+extern SInt16 LMGetSysFontFam(void) ;
+extern void LMSetSysFontFam(SInt16 value) ;
+extern SInt16 LMGetSysFontSize(void) ;
+extern void LMSetSysFontSize(SInt16 value) ;
+extern StringPtr LMGetCurApName(void) ;
+extern void LMSetCurApName(ConstStr31Param curApNameValue) ;
+extern StringPtr LMGetSysResName(void) ;
+extern void LMSetSysResName(ConstStr15Param sysResNameValue) ;
+extern StringPtr LMGetFinderName(void) ;
+extern void LMSetFinderName(ConstStr15Param finderNameValue) ;
+extern Ptr LMGetToolScratch(void) ;
+extern void LMSetToolScratch(const void * toolScratchValue) ;
+extern UniversalProcPtr LMGetLvl2DT(short vectorNumber) ;
+extern void LMSetLvl2DT(UniversalProcPtr Lvl2DTValue, short vectorNumber) ;
+extern Ptr LMGetHighHeapMark(void) ;
+extern void LMSetHighHeapMark(Ptr value) ;
+extern Ptr LMGetStackLowPoint(void) ;
+extern void LMSetStackLowPoint(Ptr value) ;
+extern Ptr LMGetDiskFormatingHFSDefaults(void) ;
+extern void LMSetDiskFormatingHFSDefaults(Ptr value) ;
+
+
+}
+
+
+
+extern "C" {
+
+
+typedef UInt16 AVLVisitStage;
+enum {
+ kAVLPreOrder = 0,
+ kAVLInOrder = 1,
+ kAVLPostOrder = 2
+};
+
+
+typedef UInt16 AVLOrder;
+enum {
+ kLeftToRight = 0,
+ kRightToLeft = 1
+};
+
+
+typedef UInt16 AVLNodeType;
+enum {
+ kAVLIsTree = 0,
+ kAVLIsLeftBranch = 1,
+ kAVLIsRightBranch = 2,
+ kAVLIsLeaf = 3,
+ kAVLNullNode = 4
+};
+
+enum {
+ errItemAlreadyInTree = -960,
+ errNotValidTree = -961,
+ errItemNotFoundInTree = -962,
+ errCanNotInsertWhileWalkProcInProgress = -963,
+ errTreeIsLocked = -964
+};
+
+
+struct AVLTreeStruct {
+ OSType signature;
+ unsigned long privateStuff[8];
+};
+typedef struct AVLTreeStruct AVLTreeStruct;
+typedef AVLTreeStruct * AVLTreePtr;
+
+
+
+
+
+
+
+typedef SInt32 ( * AVLCompareItemsProcPtr)(AVLTreePtr tree, const void *i1, const void *i2, AVLNodeType nd_typ);
+
+
+
+
+
+
+typedef UInt32 ( * AVLItemSizeProcPtr)(AVLTreePtr tree, const void *itemPtr);
+
+
+
+
+
+
+typedef void ( * AVLDisposeItemProcPtr)(AVLTreePtr tree, const void *dataP);
+typedef OSErr ( * AVLWalkProcPtr)(AVLTreePtr tree, const void *dataP, AVLVisitStage visitStage, AVLNodeType node, UInt32 level, SInt32 balance, void *refCon);
+typedef AVLCompareItemsProcPtr AVLCompareItemsUPP;
+typedef AVLItemSizeProcPtr AVLItemSizeUPP;
+typedef AVLDisposeItemProcPtr AVLDisposeItemUPP;
+typedef AVLWalkProcPtr AVLWalkUPP;
+extern AVLCompareItemsUPP
+NewAVLCompareItemsUPP(AVLCompareItemsProcPtr userRoutine) ;
+extern AVLItemSizeUPP
+NewAVLItemSizeUPP(AVLItemSizeProcPtr userRoutine) ;
+extern AVLDisposeItemUPP
+NewAVLDisposeItemUPP(AVLDisposeItemProcPtr userRoutine) ;
+extern AVLWalkUPP
+NewAVLWalkUPP(AVLWalkProcPtr userRoutine) ;
+extern void
+DisposeAVLCompareItemsUPP(AVLCompareItemsUPP userUPP) ;
+extern void
+DisposeAVLItemSizeUPP(AVLItemSizeUPP userUPP) ;
+extern void
+DisposeAVLDisposeItemUPP(AVLDisposeItemUPP userUPP) ;
+extern void
+DisposeAVLWalkUPP(AVLWalkUPP userUPP) ;
+extern SInt32
+InvokeAVLCompareItemsUPP(
+ AVLTreePtr tree,
+ const void * i1,
+ const void * i2,
+ AVLNodeType nd_typ,
+ AVLCompareItemsUPP userUPP) ;
+extern UInt32
+InvokeAVLItemSizeUPP(
+ AVLTreePtr tree,
+ const void * itemPtr,
+ AVLItemSizeUPP userUPP) ;
+extern void
+InvokeAVLDisposeItemUPP(
+ AVLTreePtr tree,
+ const void * dataP,
+ AVLDisposeItemUPP userUPP) ;
+extern OSErr
+InvokeAVLWalkUPP(
+ AVLTreePtr tree,
+ const void * dataP,
+ AVLVisitStage visitStage,
+ AVLNodeType node,
+ UInt32 level,
+ SInt32 balance,
+ void * refCon,
+ AVLWalkUPP userUPP) ;
+extern OSErr
+AVLInit(
+ UInt32 flags,
+ AVLCompareItemsUPP compareItemsProc,
+ AVLItemSizeUPP sizeItemProc,
+ AVLDisposeItemUPP disposeItemProc,
+ void * refCon,
+ AVLTreePtr * tree) ;
+extern OSErr
+AVLDispose(
+ AVLTreePtr * tree,
+ AVLOrder order) ;
+extern OSErr
+AVLWalk(
+ AVLTreePtr tree,
+ AVLWalkUPP walkProc,
+ AVLOrder order,
+ void * walkRefCon) ;
+extern OSErr
+AVLCount(
+ AVLTreePtr tree,
+ UInt32 * count) ;
+extern OSErr
+AVLGetIndItem(
+ AVLTreePtr tree,
+ UInt32 index,
+ void * dataPtr,
+ UInt32 * itemSize) ;
+extern OSErr
+AVLInsert(
+ AVLTreePtr tree,
+ const void * data) ;
+extern OSErr
+AVLRemove(
+ AVLTreePtr tree,
+ const void * key,
+ void * dataPtr,
+ UInt32 * itemSize) ;
+extern OSErr
+AVLFind(
+ AVLTreePtr tree,
+ const void * key,
+ void * dataPtr,
+ UInt32 * itemSize) ;
+extern OSErr
+AVLGetRefcon(
+ AVLTreePtr tree,
+ void ** refCon) ;
+
+
+
+
+
+}
+
+
+
+struct PEFContainerHeader {
+ OSType tag1;
+ OSType tag2;
+ OSType architecture;
+ UInt32 formatVersion;
+ UInt32 dateTimeStamp;
+ UInt32 oldDefVersion;
+ UInt32 oldImpVersion;
+ UInt32 currentVersion;
+ UInt16 sectionCount;
+ UInt16 instSectionCount;
+ UInt32 reservedA;
+};
+typedef struct PEFContainerHeader PEFContainerHeader;
+enum {
+ kPEFTag1 = 'Joy!',
+ kPEFTag2 = 'peff',
+ kPEFVersion = 0x00000001
+};
+
+
+enum {
+ kPEFFirstSectionHeaderOffset = sizeof(PEFContainerHeader)
+};
+struct PEFSectionHeader {
+ SInt32 nameOffset;
+ UInt32 defaultAddress;
+ UInt32 totalLength;
+ UInt32 unpackedLength;
+ UInt32 containerLength;
+ UInt32 containerOffset;
+ UInt8 sectionKind;
+ UInt8 shareKind;
+ UInt8 alignment;
+ UInt8 reservedA;
+};
+typedef struct PEFSectionHeader PEFSectionHeader;
+enum {
+
+
+ kPEFCodeSection = 0,
+ kPEFUnpackedDataSection = 1,
+ kPEFPackedDataSection = 2,
+ kPEFConstantSection = 3,
+ kPEFExecDataSection = 6,
+
+ kPEFLoaderSection = 4,
+ kPEFDebugSection = 5,
+ kPEFExceptionSection = 7,
+ kPEFTracebackSection = 8
+};
+
+
+enum {
+
+ kPEFProcessShare = 1,
+ kPEFGlobalShare = 4,
+ kPEFProtectedShare = 5
+};
+enum {
+
+ kPEFPkDataZero = 0,
+ kPEFPkDataBlock = 1,
+ kPEFPkDataRepeat = 2,
+ kPEFPkDataRepeatBlock = 3,
+ kPEFPkDataRepeatZero = 4
+};
+
+
+enum {
+ kPEFPkDataOpcodeShift = 5,
+ kPEFPkDataCount5Mask = 0x1F,
+ kPEFPkDataMaxCount5 = 31,
+ kPEFPkDataVCountShift = 7,
+ kPEFPkDataVCountMask = 0x7F,
+ kPEFPkDataVCountEndMask = 0x80
+};
+struct PEFLoaderInfoHeader {
+ SInt32 mainSection;
+ UInt32 mainOffset;
+ SInt32 initSection;
+ UInt32 initOffset;
+ SInt32 termSection;
+ UInt32 termOffset;
+ UInt32 importedLibraryCount;
+ UInt32 totalImportedSymbolCount;
+ UInt32 relocSectionCount;
+ UInt32 relocInstrOffset;
+ UInt32 loaderStringsOffset;
+ UInt32 exportHashOffset;
+ UInt32 exportHashTablePower;
+ UInt32 exportedSymbolCount;
+};
+typedef struct PEFLoaderInfoHeader PEFLoaderInfoHeader;
+
+
+
+
+
+
+
+struct PEFImportedLibrary {
+ UInt32 nameOffset;
+ UInt32 oldImpVersion;
+ UInt32 currentVersion;
+ UInt32 importedSymbolCount;
+ UInt32 firstImportedSymbol;
+ UInt8 options;
+ UInt8 reservedA;
+ UInt16 reservedB;
+};
+typedef struct PEFImportedLibrary PEFImportedLibrary;
+enum {
+
+ kPEFWeakImportLibMask = 0x40,
+ kPEFInitLibBeforeMask = 0x80
+};
+struct PEFImportedSymbol {
+ UInt32 classAndName;
+};
+typedef struct PEFImportedSymbol PEFImportedSymbol;
+enum {
+ kPEFImpSymClassShift = 24,
+ kPEFImpSymNameOffsetMask = 0x00FFFFFF,
+ kPEFImpSymMaxNameOffset = 0x00FFFFFF
+};
+
+
+
+
+
+
+
+enum {
+
+ kPEFCodeSymbol = 0x00,
+ kPEFDataSymbol = 0x01,
+ kPEFTVectorSymbol = 0x02,
+ kPEFTOCSymbol = 0x03,
+ kPEFGlueSymbol = 0x04,
+ kPEFUndefinedSymbol = 0x0F,
+ kPEFWeakImportSymMask = 0x80
+};
+struct PEFExportedSymbolHashSlot {
+ UInt32 countAndStart;
+};
+typedef struct PEFExportedSymbolHashSlot PEFExportedSymbolHashSlot;
+enum {
+ kPEFHashSlotSymCountShift = 18,
+ kPEFHashSlotFirstKeyMask = 0x0003FFFF,
+ kPEFHashSlotMaxSymbolCount = 0x00003FFF,
+ kPEFHashSlotMaxKeyIndex = 0x0003FFFF
+};
+struct PEFSplitHashWord {
+ UInt16 nameLength;
+ UInt16 hashValue;
+};
+typedef struct PEFSplitHashWord PEFSplitHashWord;
+struct PEFExportedSymbolKey {
+ union {
+ UInt32 fullHashWord;
+ PEFSplitHashWord splitHashWord;
+ } u;
+};
+typedef struct PEFExportedSymbolKey PEFExportedSymbolKey;
+enum {
+ kPEFHashLengthShift = 16,
+ kPEFHashValueMask = 0x0000FFFF,
+ kPEFHashMaxLength = 0x0000FFFF
+};
+struct PEFExportedSymbol {
+ UInt32 classAndName;
+ UInt32 symbolValue;
+ SInt16 sectionIndex;
+};
+typedef struct PEFExportedSymbol PEFExportedSymbol;
+enum {
+ kPEFExpSymClassShift = 24,
+ kPEFExpSymNameOffsetMask = 0x00FFFFFF,
+ kPEFExpSymMaxNameOffset = 0x00FFFFFF
+};
+
+
+
+
+
+
+
+enum {
+
+ kPEFAbsoluteExport = -2,
+ kPEFReexportedImport = -3
+};
+typedef UInt16 PEFRelocChunk;
+struct PEFLoaderRelocationHeader {
+ UInt16 sectionIndex;
+ UInt16 reservedA;
+ UInt32 relocCount;
+ UInt32 firstRelocOffset;
+};
+typedef struct PEFLoaderRelocationHeader PEFLoaderRelocationHeader;
+enum {
+ kPEFRelocBasicOpcodeRange = 128
+};
+enum {
+ kPEFRelocBySectDWithSkip = 0x00,
+ kPEFRelocBySectC = 0x20,
+ kPEFRelocBySectD = 0x21,
+ kPEFRelocTVector12 = 0x22,
+ kPEFRelocTVector8 = 0x23,
+ kPEFRelocVTable8 = 0x24,
+ kPEFRelocImportRun = 0x25,
+ kPEFRelocSmByImport = 0x30,
+ kPEFRelocSmSetSectC = 0x31,
+ kPEFRelocSmSetSectD = 0x32,
+ kPEFRelocSmBySection = 0x33,
+ kPEFRelocIncrPosition = 0x40,
+ kPEFRelocSmRepeat = 0x48,
+ kPEFRelocSetPosition = 0x50,
+ kPEFRelocLgByImport = 0x52,
+ kPEFRelocLgRepeat = 0x58,
+ kPEFRelocLgSetOrBySection = 0x5A,
+ kPEFRelocUndefinedOpcode = 0xFF
+};
+enum {
+ kPEFRelocLgBySectionSubopcode = 0x00,
+ kPEFRelocLgSetSectCSubopcode = 0x01,
+ kPEFRelocLgSetSectDSubopcode = 0x02
+};
+enum {
+ kPEFRelocWithSkipMaxSkipCount = 255,
+ kPEFRelocWithSkipMaxRelocCount = 63
+};
+enum {
+ kPEFRelocRunMaxRunLength = 512
+};
+enum {
+ kPEFRelocSmIndexMaxIndex = 511
+};
+enum {
+ kPEFRelocIncrPositionMaxOffset = 4096
+};
+enum {
+ kPEFRelocSmRepeatMaxChunkCount = 16,
+ kPEFRelocSmRepeatMaxRepeatCount = 256
+};
+enum {
+ kPEFRelocSetPosMaxOffset = 0x03FFFFFF
+};
+enum {
+ kPEFRelocLgByImportMaxIndex = 0x03FFFFFF
+};
+enum {
+ kPEFRelocLgRepeatMaxChunkCount = 16,
+ kPEFRelocLgRepeatMaxRepeatCount = 0x003FFFFF
+};
+enum {
+ kPEFRelocLgSetOrBySectionMaxIndex = 0x003FFFFF
+};
+struct XLibContainerHeader {
+
+
+
+ OSType tag1;
+ OSType tag2;
+ UInt32 currentFormat;
+ UInt32 containerStringsOffset;
+ UInt32 exportHashOffset;
+ UInt32 exportKeyOffset;
+ UInt32 exportSymbolOffset;
+ UInt32 exportNamesOffset;
+ UInt32 exportHashTablePower;
+ UInt32 exportedSymbolCount;
+
+
+
+ UInt32 fragNameOffset;
+ UInt32 fragNameLength;
+ UInt32 dylibPathOffset;
+ UInt32 dylibPathLength;
+ OSType cpuFamily;
+ OSType cpuModel;
+ UInt32 dateTimeStamp;
+ UInt32 currentVersion;
+ UInt32 oldDefVersion;
+ UInt32 oldImpVersion;
+
+};
+typedef struct XLibContainerHeader XLibContainerHeader;
+enum {
+ kXLibTag1 = 'ðMac',
+ kVLibTag2 = 'VLib',
+ kBLibTag2 = 'BLib',
+ kXLibVersion = 0x00000001
+};
+
+
+
+typedef PEFExportedSymbolHashSlot XLibExportedSymbolHashSlot;
+typedef PEFExportedSymbolKey XLibExportedSymbolKey;
+struct XLibExportedSymbol {
+ UInt32 classAndName;
+ UInt32 bpOffset;
+};
+typedef struct XLibExportedSymbol XLibExportedSymbol;
+
+
+
+
+
+enum {
+ kHFSSigWord = 0x4244,
+ kHFSPlusSigWord = 0x482B,
+ kHFSPlusVersion = 0x0004,
+ kHFSPlusMountVersion = '8.10'
+};
+
+
+
+typedef UInt32 HFSCatalogNodeID;
+enum {
+ kHFSMaxVolumeNameChars = 27,
+ kHFSMaxFileNameChars = 31,
+ kHFSPlusMaxFileNameChars = 255
+};
+
+
+
+
+struct HFSExtentKey {
+ UInt8 keyLength;
+ UInt8 forkType;
+ HFSCatalogNodeID fileID;
+ UInt16 startBlock;
+};
+typedef struct HFSExtentKey HFSExtentKey;
+
+struct HFSPlusExtentKey {
+ UInt16 keyLength;
+ UInt8 forkType;
+ UInt8 pad;
+ HFSCatalogNodeID fileID;
+ UInt32 startBlock;
+};
+typedef struct HFSPlusExtentKey HFSPlusExtentKey;
+
+enum {
+ kHFSExtentDensity = 3,
+ kHFSPlusExtentDensity = 8
+};
+
+
+struct HFSExtentDescriptor {
+ UInt16 startBlock;
+ UInt16 blockCount;
+};
+typedef struct HFSExtentDescriptor HFSExtentDescriptor;
+
+struct HFSPlusExtentDescriptor {
+ UInt32 startBlock;
+ UInt32 blockCount;
+};
+typedef struct HFSPlusExtentDescriptor HFSPlusExtentDescriptor;
+
+
+typedef HFSExtentDescriptor HFSExtentRecord[3];
+
+typedef HFSPlusExtentDescriptor HFSPlusExtentRecord[8];
+
+
+struct HFSPlusForkData {
+ UInt64 logicalSize;
+ UInt32 clumpSize;
+ UInt32 totalBlocks;
+ HFSPlusExtentRecord extents;
+};
+typedef struct HFSPlusForkData HFSPlusForkData;
+
+struct HFSPlusPermissions {
+ UInt32 ownerID;
+ UInt32 groupID;
+ UInt32 permissions;
+ UInt32 specialDevice;
+};
+typedef struct HFSPlusPermissions HFSPlusPermissions;
+
+enum {
+ kHFSRootParentID = 1,
+ kHFSRootFolderID = 2,
+ kHFSExtentsFileID = 3,
+ kHFSCatalogFileID = 4,
+ kHFSBadBlockFileID = 5,
+ kHFSAllocationFileID = 6,
+ kHFSStartupFileID = 7,
+ kHFSAttributesFileID = 8,
+ kHFSBogusExtentFileID = 15,
+ kHFSFirstUserCatalogNodeID = 16
+};
+
+
+
+struct HFSCatalogKey {
+ UInt8 keyLength;
+ UInt8 reserved;
+ HFSCatalogNodeID parentID;
+ Str31 nodeName;
+};
+typedef struct HFSCatalogKey HFSCatalogKey;
+
+struct HFSPlusCatalogKey {
+ UInt16 keyLength;
+ HFSCatalogNodeID parentID;
+ HFSUniStr255 nodeName;
+};
+typedef struct HFSPlusCatalogKey HFSPlusCatalogKey;
+
+
+enum {
+
+ kHFSFolderRecord = 0x0100,
+ kHFSFileRecord = 0x0200,
+ kHFSFolderThreadRecord = 0x0300,
+ kHFSFileThreadRecord = 0x0400,
+
+ kHFSPlusFolderRecord = 1,
+ kHFSPlusFileRecord = 2,
+ kHFSPlusFolderThreadRecord = 3,
+ kHFSPlusFileThreadRecord = 4
+};
+
+
+
+enum {
+ kHFSFileLockedBit = 0x0000,
+ kHFSFileLockedMask = 0x0001,
+ kHFSThreadExistsBit = 0x0001,
+ kHFSThreadExistsMask = 0x0002
+};
+
+
+
+struct HFSCatalogFolder {
+ SInt16 recordType;
+ UInt16 flags;
+ UInt16 valence;
+ HFSCatalogNodeID folderID;
+ UInt32 createDate;
+ UInt32 modifyDate;
+ UInt32 backupDate;
+ DInfo userInfo;
+ DXInfo finderInfo;
+ UInt32 reserved[4];
+};
+typedef struct HFSCatalogFolder HFSCatalogFolder;
+
+struct HFSPlusCatalogFolder {
+ SInt16 recordType;
+ UInt16 flags;
+ UInt32 valence;
+ HFSCatalogNodeID folderID;
+ UInt32 createDate;
+ UInt32 contentModDate;
+ UInt32 attributeModDate;
+ UInt32 accessDate;
+ UInt32 backupDate;
+ HFSPlusPermissions permissions;
+ DInfo userInfo;
+ DXInfo finderInfo;
+ UInt32 textEncoding;
+ UInt32 reserved;
+};
+typedef struct HFSPlusCatalogFolder HFSPlusCatalogFolder;
+
+struct HFSCatalogFile {
+ SInt16 recordType;
+ UInt8 flags;
+ SInt8 fileType;
+ FInfo userInfo;
+ HFSCatalogNodeID fileID;
+ UInt16 dataStartBlock;
+ SInt32 dataLogicalSize;
+ SInt32 dataPhysicalSize;
+ UInt16 rsrcStartBlock;
+ SInt32 rsrcLogicalSize;
+ SInt32 rsrcPhysicalSize;
+ UInt32 createDate;
+ UInt32 modifyDate;
+ UInt32 backupDate;
+ FXInfo finderInfo;
+ UInt16 clumpSize;
+ HFSExtentRecord dataExtents;
+ HFSExtentRecord rsrcExtents;
+ UInt32 reserved;
+};
+typedef struct HFSCatalogFile HFSCatalogFile;
+
+struct HFSPlusCatalogFile {
+ SInt16 recordType;
+ UInt16 flags;
+ UInt32 reserved1;
+ HFSCatalogNodeID fileID;
+ UInt32 createDate;
+ UInt32 contentModDate;
+ UInt32 attributeModDate;
+ UInt32 accessDate;
+ UInt32 backupDate;
+ HFSPlusPermissions permissions;
+ FInfo userInfo;
+ FXInfo finderInfo;
+ UInt32 textEncoding;
+ UInt32 reserved2;
+
+
+ HFSPlusForkData dataFork;
+ HFSPlusForkData resourceFork;
+};
+typedef struct HFSPlusCatalogFile HFSPlusCatalogFile;
+
+struct HFSCatalogThread {
+ SInt16 recordType;
+ SInt32 reserved[2];
+ HFSCatalogNodeID parentID;
+ Str31 nodeName;
+};
+typedef struct HFSCatalogThread HFSCatalogThread;
+
+struct HFSPlusCatalogThread {
+ SInt16 recordType;
+ SInt16 reserved;
+ HFSCatalogNodeID parentID;
+ HFSUniStr255 nodeName;
+};
+typedef struct HFSPlusCatalogThread HFSPlusCatalogThread;
+
+
+
+
+
+enum {
+ kHFSPlusAttrInlineData = 0x10,
+ kHFSPlusAttrForkData = 0x20,
+ kHFSPlusAttrExtents = 0x30
+};
+struct HFSPlusAttrInlineData {
+ UInt32 recordType;
+ UInt32 reserved;
+ UInt32 logicalSize;
+ UInt8 userData[2];
+};
+typedef struct HFSPlusAttrInlineData HFSPlusAttrInlineData;
+
+
+
+
+
+
+struct HFSPlusAttrForkData {
+ UInt32 recordType;
+ UInt32 reserved;
+ HFSPlusForkData theFork;
+};
+typedef struct HFSPlusAttrForkData HFSPlusAttrForkData;
+
+
+
+
+
+struct HFSPlusAttrExtents {
+ UInt32 recordType;
+ UInt32 reserved;
+ HFSPlusExtentRecord extents;
+};
+typedef struct HFSPlusAttrExtents HFSPlusAttrExtents;
+
+union HFSPlusAttrRecord {
+ UInt32 recordType;
+ HFSPlusAttrInlineData inlineData;
+ HFSPlusAttrForkData forkData;
+ HFSPlusAttrExtents overflowExtents;
+};
+typedef union HFSPlusAttrRecord HFSPlusAttrRecord;
+
+enum {
+ kHFSPlusExtentKeyMaximumLength = sizeof(HFSPlusExtentKey) - sizeof(UInt16),
+ kHFSExtentKeyMaximumLength = sizeof(HFSExtentKey) - sizeof(UInt8),
+ kHFSPlusCatalogKeyMaximumLength = sizeof(HFSPlusCatalogKey) - sizeof(UInt16),
+ kHFSPlusCatalogKeyMinimumLength = kHFSPlusCatalogKeyMaximumLength - sizeof(HFSUniStr255) + sizeof(UInt16),
+ kHFSCatalogKeyMaximumLength = sizeof(HFSCatalogKey) - sizeof(UInt8),
+ kHFSCatalogKeyMinimumLength = kHFSCatalogKeyMaximumLength - sizeof(Str31) + sizeof(UInt8),
+ kHFSPlusCatalogMinNodeSize = 4096,
+ kHFSPlusExtentMinNodeSize = 512,
+ kHFSPlusAttrMinNodeSize = 4096
+};
+
+
+
+enum {
+
+ kHFSVolumeHardwareLockBit = 7,
+ kHFSVolumeUnmountedBit = 8,
+ kHFSVolumeSparedBlocksBit = 9,
+ kHFSVolumeNoCacheRequiredBit = 10,
+ kHFSBootVolumeInconsistentBit = 11,
+
+ kHFSVolumeSoftwareLockBit = 15,
+ kHFSVolumeHardwareLockMask = 1 << kHFSVolumeHardwareLockBit,
+ kHFSVolumeUnmountedMask = 1 << kHFSVolumeUnmountedBit,
+ kHFSVolumeSparedBlocksMask = 1 << kHFSVolumeSparedBlocksBit,
+ kHFSVolumeNoCacheRequiredMask = 1 << kHFSVolumeNoCacheRequiredBit,
+ kHFSBootVolumeInconsistentMask = 1 << kHFSBootVolumeInconsistentBit,
+ kHFSVolumeSoftwareLockMask = 1 << kHFSVolumeSoftwareLockBit,
+ kHFSMDBAttributesMask = 0x8380
+};
+
+enum {
+ kHFSCatalogNodeIDsReusedBit = 12,
+ kHFSCatalogNodeIDsReusedMask = 1 << kHFSCatalogNodeIDsReusedBit
+};
+
+
+
+struct HFSMasterDirectoryBlock {
+
+
+
+ UInt16 drSigWord;
+ UInt32 drCrDate;
+ UInt32 drLsMod;
+ UInt16 drAtrb;
+ UInt16 drNmFls;
+ UInt16 drVBMSt;
+ UInt16 drAllocPtr;
+ UInt16 drNmAlBlks;
+ UInt32 drAlBlkSiz;
+ UInt32 drClpSiz;
+ UInt16 drAlBlSt;
+ UInt32 drNxtCNID;
+ UInt16 drFreeBks;
+ Str27 drVN;
+
+
+
+ UInt32 drVolBkUp;
+ UInt16 drVSeqNum;
+ UInt32 drWrCnt;
+ UInt32 drXTClpSiz;
+ UInt32 drCTClpSiz;
+ UInt16 drNmRtDirs;
+ UInt32 drFilCnt;
+ UInt32 drDirCnt;
+ SInt32 drFndrInfo[8];
+ UInt16 drEmbedSigWord;
+ HFSExtentDescriptor drEmbedExtent;
+ UInt32 drXTFlSize;
+ HFSExtentRecord drXTExtRec;
+ UInt32 drCTFlSize;
+ HFSExtentRecord drCTExtRec;
+};
+typedef struct HFSMasterDirectoryBlock HFSMasterDirectoryBlock;
+
+
+struct HFSPlusVolumeHeader {
+ UInt16 signature;
+ UInt16 version;
+ UInt32 attributes;
+ UInt32 lastMountedVersion;
+ UInt32 reserved;
+
+ UInt32 createDate;
+ UInt32 modifyDate;
+ UInt32 backupDate;
+ UInt32 checkedDate;
+
+ UInt32 fileCount;
+ UInt32 folderCount;
+
+ UInt32 blockSize;
+ UInt32 totalBlocks;
+ UInt32 freeBlocks;
+
+ UInt32 nextAllocation;
+ UInt32 rsrcClumpSize;
+ UInt32 dataClumpSize;
+ HFSCatalogNodeID nextCatalogID;
+
+ UInt32 writeCount;
+ UInt64 encodingsBitmap;
+
+ UInt8 finderInfo[32];
+
+ HFSPlusForkData allocationFile;
+ HFSPlusForkData extentsFile;
+ HFSPlusForkData catalogFile;
+ HFSPlusForkData attributesFile;
+ HFSPlusForkData startupFile;
+};
+typedef struct HFSPlusVolumeHeader HFSPlusVolumeHeader;
+
+
+struct BTNodeDescriptor {
+ UInt32 fLink;
+ UInt32 bLink;
+ SInt8 kind;
+ UInt8 height;
+ UInt16 numRecords;
+ UInt16 reserved;
+};
+typedef struct BTNodeDescriptor BTNodeDescriptor;
+
+enum {
+ kBTLeafNode = -1,
+ kBTIndexNode = 0,
+ kBTHeaderNode = 1,
+ kBTMapNode = 2
+};
+
+
+struct BTHeaderRec {
+ UInt16 treeDepth;
+ UInt32 rootNode;
+ UInt32 leafRecords;
+ UInt32 firstLeafNode;
+ UInt32 lastLeafNode;
+ UInt16 nodeSize;
+ UInt16 maxKeyLength;
+ UInt32 totalNodes;
+ UInt32 freeNodes;
+ UInt16 reserved1;
+ UInt32 clumpSize;
+ UInt8 btreeType;
+ UInt8 reserved2;
+ UInt32 attributes;
+ UInt32 reserved3[16];
+};
+typedef struct BTHeaderRec BTHeaderRec;
+
+enum {
+ kBTBadCloseMask = 0x00000001,
+ kBTBigKeysMask = 0x00000002,
+ kBTVariableIndexKeysMask = 0x00000004
+};
+
+
+
+
+
+
+enum {
+ AIFFID = 'AIFF',
+ AIFCID = 'AIFC',
+ FormatVersionID = 'FVER',
+ CommonID = 'COMM',
+ FORMID = 'FORM',
+ SoundDataID = 'SSND',
+ MarkerID = 'MARK',
+ InstrumentID = 'INST',
+ MIDIDataID = 'MIDI',
+ AudioRecordingID = 'AESD',
+ ApplicationSpecificID = 'APPL',
+ CommentID = 'COMT',
+ NameID = 'NAME',
+ AuthorID = 'AUTH',
+ CopyrightID = '(c) ',
+ AnnotationID = 'ANNO'
+};
+
+enum {
+ NoLooping = 0,
+ ForwardLooping = 1,
+ ForwardBackwardLooping = 2
+};
+
+enum {
+
+ AIFCVersion1 = (long)0xA2805140
+};
+
+
+
+
+
+
+
+enum {
+
+ NoneType = 'NONE',
+ ACE2Type = 'ACE2',
+ ACE8Type = 'ACE8',
+ MACE3Type = 'MAC3',
+ MACE6Type = 'MAC6'
+};
+
+typedef unsigned long ID;
+typedef short MarkerIdType;
+struct ChunkHeader {
+ ID ckID;
+ long ckSize;
+};
+typedef struct ChunkHeader ChunkHeader;
+struct ContainerChunk {
+ ID ckID;
+ long ckSize;
+ ID formType;
+};
+typedef struct ContainerChunk ContainerChunk;
+struct FormatVersionChunk {
+ ID ckID;
+ long ckSize;
+ unsigned long timestamp;
+};
+typedef struct FormatVersionChunk FormatVersionChunk;
+typedef FormatVersionChunk * FormatVersionChunkPtr;
+struct CommonChunk {
+ ID ckID;
+ long ckSize;
+ short numChannels;
+ unsigned long numSampleFrames;
+ short sampleSize;
+ extended80 sampleRate;
+};
+typedef struct CommonChunk CommonChunk;
+typedef CommonChunk * CommonChunkPtr;
+struct ExtCommonChunk {
+ ID ckID;
+ long ckSize;
+ short numChannels;
+ unsigned long numSampleFrames;
+ short sampleSize;
+ extended80 sampleRate;
+ ID compressionType;
+ char compressionName[1];
+};
+typedef struct ExtCommonChunk ExtCommonChunk;
+typedef ExtCommonChunk * ExtCommonChunkPtr;
+struct SoundDataChunk {
+ ID ckID;
+ long ckSize;
+ unsigned long offset;
+ unsigned long blockSize;
+};
+typedef struct SoundDataChunk SoundDataChunk;
+typedef SoundDataChunk * SoundDataChunkPtr;
+struct Marker {
+ MarkerIdType id;
+ unsigned long position;
+ Str255 markerName;
+};
+typedef struct Marker Marker;
+struct MarkerChunk {
+ ID ckID;
+ long ckSize;
+ unsigned short numMarkers;
+ Marker Markers[1];
+};
+typedef struct MarkerChunk MarkerChunk;
+typedef MarkerChunk * MarkerChunkPtr;
+struct AIFFLoop {
+ short playMode;
+ MarkerIdType beginLoop;
+ MarkerIdType endLoop;
+};
+typedef struct AIFFLoop AIFFLoop;
+struct InstrumentChunk {
+ ID ckID;
+ long ckSize;
+ UInt8 baseFrequency;
+ UInt8 detune;
+ UInt8 lowFrequency;
+ UInt8 highFrequency;
+ UInt8 lowVelocity;
+ UInt8 highVelocity;
+ short gain;
+ AIFFLoop sustainLoop;
+ AIFFLoop releaseLoop;
+};
+typedef struct InstrumentChunk InstrumentChunk;
+typedef InstrumentChunk * InstrumentChunkPtr;
+struct MIDIDataChunk {
+ ID ckID;
+ long ckSize;
+ UInt8 MIDIdata[1];
+};
+typedef struct MIDIDataChunk MIDIDataChunk;
+typedef MIDIDataChunk * MIDIDataChunkPtr;
+struct AudioRecordingChunk {
+ ID ckID;
+ long ckSize;
+ UInt8 AESChannelStatus[24];
+};
+typedef struct AudioRecordingChunk AudioRecordingChunk;
+typedef AudioRecordingChunk * AudioRecordingChunkPtr;
+struct ApplicationSpecificChunk {
+ ID ckID;
+ long ckSize;
+ OSType applicationSignature;
+ UInt8 data[1];
+};
+typedef struct ApplicationSpecificChunk ApplicationSpecificChunk;
+typedef ApplicationSpecificChunk * ApplicationSpecificChunkPtr;
+struct Comment {
+ unsigned long timeStamp;
+ MarkerIdType marker;
+ unsigned short count;
+ char text[1];
+};
+typedef struct Comment Comment;
+struct CommentsChunk {
+ ID ckID;
+ long ckSize;
+ unsigned short numComments;
+ Comment comments[1];
+};
+typedef struct CommentsChunk CommentsChunk;
+typedef CommentsChunk * CommentsChunkPtr;
+struct TextChunk {
+ ID ckID;
+ long ckSize;
+ char text[1];
+};
+typedef struct TextChunk TextChunk;
+typedef TextChunk * TextChunkPtr;
+
+
+
+
+struct TECBufferContextRec {
+ TextPtr textInputBuffer;
+ TextPtr textInputBufferEnd;
+ TextPtr textOutputBuffer;
+ TextPtr textOutputBufferEnd;
+
+ TextEncodingRunPtr encodingInputBuffer;
+ TextEncodingRunPtr encodingInputBufferEnd;
+ TextEncodingRunPtr encodingOutputBuffer;
+ TextEncodingRunPtr encodingOutputBufferEnd;
+};
+typedef struct TECBufferContextRec TECBufferContextRec;
+struct TECPluginStateRec {
+
+ UInt8 state1;
+ UInt8 state2;
+ UInt8 state3;
+ UInt8 state4;
+
+ UInt32 longState1;
+ UInt32 longState2;
+ UInt32 longState3;
+ UInt32 longState4;
+};
+typedef struct TECPluginStateRec TECPluginStateRec;
+struct TECConverterContextRec {
+
+
+ Ptr pluginRec;
+ TextEncoding sourceEncoding;
+ TextEncoding destEncoding;
+ UInt32 reserved1;
+ UInt32 reserved2;
+ TECBufferContextRec bufferContext;
+
+ UInt32 contextRefCon;
+ ProcPtr conversionProc;
+ ProcPtr flushProc;
+ ProcPtr clearContextInfoProc;
+ UInt32 options1;
+ UInt32 options2;
+ TECPluginStateRec pluginState;
+};
+typedef struct TECConverterContextRec TECConverterContextRec;
+struct TECSnifferContextRec {
+
+ Ptr pluginRec;
+ TextEncoding encoding;
+ ItemCount maxErrors;
+ ItemCount maxFeatures;
+ TextPtr textInputBuffer;
+ TextPtr textInputBufferEnd;
+ ItemCount numFeatures;
+ ItemCount numErrors;
+
+ UInt32 contextRefCon;
+ ProcPtr sniffProc;
+ ProcPtr clearContextInfoProc;
+ TECPluginStateRec pluginState;
+};
+typedef struct TECSnifferContextRec TECSnifferContextRec;
+
+
+
+
+
+
+typedef OSStatus ( * TECPluginNewEncodingConverterPtr)(TECObjectRef *newEncodingConverter, TECConverterContextRec *plugContext, TextEncoding inputEncoding, TextEncoding outputEncoding);
+typedef OSStatus ( * TECPluginClearContextInfoPtr)(TECObjectRef encodingConverter, TECConverterContextRec *plugContext);
+typedef OSStatus ( * TECPluginConvertTextEncodingPtr)(TECObjectRef encodingConverter, TECConverterContextRec *plugContext);
+typedef OSStatus ( * TECPluginFlushConversionPtr)(TECObjectRef encodingConverter, TECConverterContextRec *plugContext);
+typedef OSStatus ( * TECPluginDisposeEncodingConverterPtr)(TECObjectRef newEncodingConverter, TECConverterContextRec *plugContext);
+typedef OSStatus ( * TECPluginNewEncodingSnifferPtr)(TECSnifferObjectRef *encodingSniffer, TECSnifferContextRec *snifContext, TextEncoding inputEncoding);
+typedef OSStatus ( * TECPluginClearSnifferContextInfoPtr)(TECSnifferObjectRef encodingSniffer, TECSnifferContextRec *snifContext);
+typedef OSStatus ( * TECPluginSniffTextEncodingPtr)(TECSnifferObjectRef encodingSniffer, TECSnifferContextRec *snifContext);
+typedef OSStatus ( * TECPluginDisposeEncodingSnifferPtr)(TECSnifferObjectRef encodingSniffer, TECSnifferContextRec *snifContext);
+typedef OSStatus ( * TECPluginGetCountAvailableTextEncodingsPtr)(TextEncoding *availableEncodings, ItemCount maxAvailableEncodings, ItemCount *actualAvailableEncodings);
+typedef OSStatus ( * TECPluginGetCountAvailableTextEncodingPairsPtr)(TECConversionInfo *availableEncodings, ItemCount maxAvailableEncodings, ItemCount *actualAvailableEncodings);
+typedef OSStatus ( * TECPluginGetCountDestinationTextEncodingsPtr)(TextEncoding inputEncoding, TextEncoding *destinationEncodings, ItemCount maxDestinationEncodings, ItemCount *actualDestinationEncodings);
+typedef OSStatus ( * TECPluginGetCountSubTextEncodingsPtr)(TextEncoding inputEncoding, TextEncoding subEncodings[], ItemCount maxSubEncodings, ItemCount *actualSubEncodings);
+typedef OSStatus ( * TECPluginGetCountAvailableSniffersPtr)(TextEncoding *availableEncodings, ItemCount maxAvailableEncodings, ItemCount *actualAvailableEncodings);
+typedef OSStatus ( * TECPluginGetTextEncodingInternetNamePtr)(TextEncoding textEncoding, Str255 encodingName);
+typedef OSStatus ( * TECPluginGetTextEncodingFromInternetNamePtr)(TextEncoding *textEncoding, ConstStr255Param encodingName);
+typedef OSStatus ( * TECPluginGetCountWebEncodingsPtr)(TextEncoding *availableEncodings, ItemCount maxAvailableEncodings, ItemCount *actualAvailableEncodings);
+typedef OSStatus ( * TECPluginGetCountMailEncodingsPtr)(TextEncoding *availableEncodings, ItemCount maxAvailableEncodings, ItemCount *actualAvailableEncodings);
+
+
+
+
+
+
+enum {
+ kTECPluginDispatchTableVersion1 = 0x00010000,
+ kTECPluginDispatchTableVersion1_1 = 0x00010001,
+ kTECPluginDispatchTableVersion1_2 = 0x00010002,
+ kTECPluginDispatchTableCurrentVersion = kTECPluginDispatchTableVersion1_2
+};
+
+struct TECPluginDispatchTable {
+
+ TECPluginVersion version;
+ TECPluginVersion compatibleVersion;
+ TECPluginSignature PluginID;
+
+ TECPluginNewEncodingConverterPtr PluginNewEncodingConverter;
+ TECPluginClearContextInfoPtr PluginClearContextInfo;
+ TECPluginConvertTextEncodingPtr PluginConvertTextEncoding;
+ TECPluginFlushConversionPtr PluginFlushConversion;
+ TECPluginDisposeEncodingConverterPtr PluginDisposeEncodingConverter;
+
+ TECPluginNewEncodingSnifferPtr PluginNewEncodingSniffer;
+ TECPluginClearSnifferContextInfoPtr PluginClearSnifferContextInfo;
+ TECPluginSniffTextEncodingPtr PluginSniffTextEncoding;
+ TECPluginDisposeEncodingSnifferPtr PluginDisposeEncodingSniffer;
+
+ TECPluginGetCountAvailableTextEncodingsPtr PluginGetCountAvailableTextEncodings;
+ TECPluginGetCountAvailableTextEncodingPairsPtr PluginGetCountAvailableTextEncodingPairs;
+ TECPluginGetCountDestinationTextEncodingsPtr PluginGetCountDestinationTextEncodings;
+ TECPluginGetCountSubTextEncodingsPtr PluginGetCountSubTextEncodings;
+ TECPluginGetCountAvailableSniffersPtr PluginGetCountAvailableSniffers;
+ TECPluginGetCountWebEncodingsPtr PluginGetCountWebTextEncodings;
+ TECPluginGetCountMailEncodingsPtr PluginGetCountMailTextEncodings;
+
+ TECPluginGetTextEncodingInternetNamePtr PluginGetTextEncodingInternetName;
+ TECPluginGetTextEncodingFromInternetNamePtr PluginGetTextEncodingFromInternetName;
+
+};
+typedef struct TECPluginDispatchTable TECPluginDispatchTable;
+typedef TECPluginDispatchTable * ( * TECPluginGetPluginDispatchTablePtr)(void);
+
+
+
+
+
+
+
+
+
+
+
+enum {
+ sbSIGWord = 0x4552,
+ sbMac = 1
+};
+
+
+enum {
+ pMapSIG = 0x504D,
+ pdSigWord = 0x5453,
+ oldPMSigWord = pdSigWord,
+ newPMSigWord = pMapSIG
+};
+
+
+
+struct Block0 {
+ UInt16 sbSig;
+ UInt16 sbBlkSize;
+ UInt32 sbBlkCount;
+ UInt16 sbDevType;
+ UInt16 sbDevId;
+ UInt32 sbData;
+ UInt16 sbDrvrCount;
+ UInt32 ddBlock;
+ UInt16 ddSize;
+ UInt16 ddType;
+ UInt16 ddPad[243];
+};
+typedef struct Block0 Block0;
+
+struct DDMap {
+ UInt32 ddBlock;
+ UInt16 ddSize;
+ UInt16 ddType;
+};
+typedef struct DDMap DDMap;
+
+enum {
+ kDriverTypeMacSCSI = 0x0001,
+ kDriverTypeMacATA = 0x0701,
+ kDriverTypeMacSCSIChained = 0xFFFF,
+ kDriverTypeMacATAChained = 0xF8FF
+};
+
+
+struct Partition {
+ UInt16 pmSig;
+ UInt16 pmSigPad;
+ UInt32 pmMapBlkCnt;
+ UInt32 pmPyPartStart;
+ UInt32 pmPartBlkCnt;
+ UInt8 pmPartName[32];
+ UInt8 pmParType[32];
+ UInt32 pmLgDataStart;
+ UInt32 pmDataCnt;
+ UInt32 pmPartStatus;
+ UInt32 pmLgBootStart;
+ UInt32 pmBootSize;
+ UInt32 pmBootAddr;
+ UInt32 pmBootAddr2;
+ UInt32 pmBootEntry;
+ UInt32 pmBootEntry2;
+ UInt32 pmBootCksum;
+ UInt8 pmProcessor[16];
+ UInt16 pmPad[188];
+};
+typedef struct Partition Partition;
+
+
+enum {
+ kPartitionAUXIsValid = 0x00000001,
+ kPartitionAUXIsAllocated = 0x00000002,
+ kPartitionAUXIsInUse = 0x00000004,
+ kPartitionAUXIsBootValid = 0x00000008,
+ kPartitionAUXIsReadable = 0x00000010,
+ kPartitionAUXIsWriteable = 0x00000020,
+ kPartitionAUXIsBootCodePositionIndependent = 0x00000040,
+ kPartitionIsWriteable = 0x00000020,
+ kPartitionIsMountedAtStartup = 0x40000000,
+ kPartitionIsStartup = (long)0x80000000,
+ kPartitionIsChainCompatible = 0x00000100,
+ kPartitionIsRealDeviceDriver = 0x00000200,
+ kPartitionCanChainToNext = 0x00000400
+};
+
+
+
+
+
+enum {
+ kPatchDriverSignature = 'ptDR',
+ kSCSIDriverSignature = 0x00010600,
+ kATADriverSignature = 'wiki',
+ kSCSICDDriverSignature = 'CDvr',
+ kATAPIDriverSignature = 'ATPI',
+ kDriveSetupHFSSignature = 'DSU1'
+};
+
+
+
+
+
+
+
+extern "C" {
+
+
+
+enum {
+
+ modemOnBit = 0,
+ ringWakeUpBit = 2,
+ modemInstalledBit = 3,
+ ringDetectBit = 4,
+ modemOnHookBit = 5
+};
+
+enum {
+
+ modemOnMask = 0x01,
+ ringWakeUpMask = 0x04,
+ modemInstalledMask = 0x08,
+ ringDetectMask = 0x10,
+ modemOnHookMask = 0x20
+};
+
+enum {
+
+ chargerConnBit = 0,
+ hiChargeBit = 1,
+ chargeOverFlowBit = 2,
+ batteryDeadBit = 3,
+ batteryLowBit = 4,
+ connChangedBit = 5
+};
+
+enum {
+
+ chargerConnMask = 0x01,
+ hiChargeMask = 0x02,
+ chargeOverFlowMask = 0x04,
+ batteryDeadMask = 0x08,
+ batteryLowMask = 0x10,
+ connChangedMask = 0x20
+};
+
+enum {
+
+ MediaBaySndEnBit = 0,
+ PCISndEnBit = 1,
+ ZVSndEnBit = 2,
+ PCCardSndEnBit = 3
+};
+
+enum {
+
+ MediaBaySndEnMask = 0x01,
+ PCISndEnMask = 0x02,
+ ZVSndEnMask = 0x04,
+ PCCardSndEnMask = 0x08
+};
+
+enum {
+
+ kSleepRequest = 1,
+ kSleepDemand = 2,
+ kSleepWakeUp = 3,
+ kSleepRevoke = 4,
+ kSleepUnlock = 4,
+ kSleepDeny = 5,
+ kSleepNow = 6,
+ kDozeDemand = 7,
+ kDozeWakeUp = 8,
+ kDozeRequest = 9,
+ kEnterStandby = 10,
+ kEnterRun = 11,
+ kSuspendRequest = 12,
+ kSuspendDemand = 13,
+ kSuspendRevoke = 14,
+ kSuspendWakeUp = 15,
+ kGetPowerLevel = 16,
+ kSetPowerLevel = 17,
+ kDeviceInitiatedWake = 18,
+ kWakeToDoze = 19,
+ kDozeToFullWakeUp = 20,
+ kGetPowerInfo = 21,
+ kGetWakeOnNetInfo = 22,
+ kSuspendWakeToDoze = 23,
+ kEnterIdle = 24,
+ kStillIdle = 25,
+ kExitIdle = 26
+};
+
+enum {
+
+ sleepRequest = kSleepRequest,
+ sleepDemand = kSleepDemand,
+ sleepWakeUp = kSleepWakeUp,
+ sleepRevoke = kSleepRevoke,
+ sleepUnlock = kSleepUnlock,
+ sleepDeny = kSleepDeny,
+ sleepNow = kSleepNow,
+ dozeDemand = kDozeDemand,
+ dozeWakeUp = kDozeWakeUp,
+ dozeRequest = kDozeRequest,
+ enterStandby = kEnterStandby,
+ enterRun = kEnterRun,
+ suspendRequestMsg = kSuspendRequest,
+ suspendDemandMsg = kSuspendDemand,
+ suspendRevokeMsg = kSuspendRevoke,
+ suspendWakeUpMsg = kSuspendWakeUp,
+ getPowerLevel = kGetPowerLevel,
+ setPowerLevel = kSetPowerLevel
+};
+
+
+typedef UInt32 PowerLevel;
+
+enum {
+ kPMDevicePowerLevel_On = 0,
+ kPMDevicePowerLevel_D1 = 1,
+ kPMDevicePowerLevel_D2 = 2,
+ kPMDevicePowerLevel_Off = 3
+};
+
+
+typedef OSStatus ( * PowerHandlerProcPtr)(UInt32 message, void *param, UInt32 refCon, RegEntryID *regEntryID);
+typedef PowerHandlerProcPtr PowerHandlerUPP;
+enum {
+ kUseDefaultMinimumWakeTime = 0,
+ kPowerSummaryVersion = 1,
+ kDevicePowerInfoVersion = 1
+};
+
+enum {
+
+ kPCIPowerOffAllowed = (1L << 0)
+};
+
+enum {
+
+ kDevicePCIPowerOffAllowed = (1L << 0),
+ kDeviceSupportsPMIS = (1L << 1),
+ kDeviceCanAssertPMEDuringSleep = (1L << 2),
+ kDeviceUsesCommonLogicPower = (1L << 3),
+ kDeviceDriverPresent = (1L << 4),
+ kDeviceDriverSupportsPowerMgt = (1L << 5)
+};
+
+struct DevicePowerInfo {
+ UInt32 version;
+ RegEntryID regID;
+ OptionBits flags;
+ UInt32 minimumWakeTime;
+ UInt32 sleepPowerNeeded;
+};
+typedef struct DevicePowerInfo DevicePowerInfo;
+struct PowerSummary {
+ UInt32 version;
+ OptionBits flags;
+ UInt32 sleepPowerAvailable;
+ UInt32 sleepPowerNeeded;
+ UInt32 minimumWakeTime;
+ ItemCount deviceCount;
+ DevicePowerInfo devices[1];
+};
+typedef struct PowerSummary PowerSummary;
+enum {
+
+ noCalls = 1,
+ noRequest = 2,
+ slpQType = 16,
+ sleepQType = 16
+};
+
+
+enum {
+
+ kAEMacPowerMgtEvt = 'pmgt',
+ kAEMacToWake = 'wake',
+ kAEMacLowPowerSaveData = 'pmsd',
+ kAEMacEmergencySleep = 'emsl',
+ kAEMacEmergencyShutdown = 'emsd'
+};
+
+
+
+
+
+
+
+enum {
+ kDeviceDidNotWakeMachine = 0,
+ kDeviceRequestsFullWake = 1,
+ kDeviceRequestsWakeToDoze = 2
+};
+
+
+enum {
+ hasWakeupTimer = 0,
+ hasSharedModemPort = 1,
+ hasProcessorCycling = 2,
+ mustProcessorCycle = 3,
+ hasReducedSpeed = 4,
+ dynamicSpeedChange = 5,
+ hasSCSIDiskMode = 6,
+ canGetBatteryTime = 7,
+ canWakeupOnRing = 8,
+ hasDimmingSupport = 9,
+ hasStartupTimer = 10,
+ hasChargeNotification = 11,
+ hasDimSuspendSupport = 12,
+ hasWakeOnNetActivity = 13,
+ hasWakeOnLid = 14,
+ canPowerOffPCIBus = 15,
+ hasDeepSleep = 16,
+ hasSleep = 17,
+ supportsServerModeAPIs = 18,
+ supportsUPSIntegration = 19,
+ hasAggressiveIdling = 20,
+ supportsIdleQueue = 21
+};
+
+
+enum {
+ hasInternalModem = 0,
+ intModemRingDetect = 1,
+ intModemOffHook = 2,
+ intModemRingWakeEnb = 3,
+ extModemSelected = 4,
+ modemSetBit = 15
+};
+
+
+
+enum {
+ batteryInstalled = 7,
+ batteryCharging = 6,
+ chargerConnected = 5,
+ upsConnected = 4,
+ upsIsPowerSource = 3
+};
+
+enum {
+ HDPwrQType = 0x4844,
+ PMgrStateQType = 0x504D
+};
+
+
+enum {
+ pmSleepTimeoutChanged = 0,
+ pmSleepEnableChanged = 1,
+ pmHardDiskTimeoutChanged = 2,
+ pmHardDiskSpindownChanged = 3,
+ pmDimmingTimeoutChanged = 4,
+ pmDimmingEnableChanged = 5,
+ pmDiskModeAddressChanged = 6,
+ pmProcessorCyclingChanged = 7,
+ pmProcessorSpeedChanged = 8,
+ pmWakeupTimerChanged = 9,
+ pmStartupTimerChanged = 10,
+ pmHardDiskPowerRemovedbyUser = 11,
+ pmChargeStatusChanged = 12,
+ pmPowerLevelChanged = 13,
+ pmWakeOnNetActivityChanged = 14
+};
+
+enum {
+ pmSleepTimeoutChangedMask = (1 << pmSleepTimeoutChanged),
+ pmSleepEnableChangedMask = (1 << pmSleepEnableChanged),
+ pmHardDiskTimeoutChangedMask = (1 << pmHardDiskTimeoutChanged),
+ pmHardDiskSpindownChangedMask = (1 << pmHardDiskSpindownChanged),
+ pmDimmingTimeoutChangedMask = (1 << pmDimmingTimeoutChanged),
+ pmDimmingEnableChangedMask = (1 << pmDimmingEnableChanged),
+ pmDiskModeAddressChangedMask = (1 << pmDiskModeAddressChanged),
+ pmProcessorCyclingChangedMask = (1 << pmProcessorCyclingChanged),
+ pmProcessorSpeedChangedMask = (1 << pmProcessorSpeedChanged),
+ pmWakeupTimerChangedMask = (1 << pmWakeupTimerChanged),
+ pmStartupTimerChangedMask = (1 << pmStartupTimerChanged),
+ pmHardDiskPowerRemovedbyUserMask = (1 << pmHardDiskPowerRemovedbyUser),
+ pmChargeStatusChangedMask = (1 << pmChargeStatusChanged),
+ pmPowerLevelChangedMask = (1 << pmPowerLevelChanged),
+ pmWakeOnNetActivityChangedMask = (1 << pmWakeOnNetActivityChanged)
+};
+enum {
+ OverallAct = 0,
+ UsrActivity = 1,
+ NetActivity = 2,
+ HDActivity = 3,
+ IdleActivity = 4
+};
+
+
+enum {
+ kMediaModeOn = 0,
+ kMediaModeStandBy = 1,
+ kMediaModeSuspend = 2,
+ kMediaModeOff = 3
+};
+
+enum {
+ kMediaPowerCSCode = 70
+};
+
+
+
+enum {
+ kHDQueuePostBit = 0,
+ kHDQueuePostMask = (1 << kHDQueuePostBit)
+};
+
+struct ActivityInfo {
+ short ActivityType;
+ unsigned long ActivityTime;
+};
+typedef struct ActivityInfo ActivityInfo;
+
+struct BatteryInfo {
+ UInt8 flags;
+ UInt8 warningLevel;
+ UInt8 reserved;
+ UInt8 batteryLevel;
+};
+typedef struct BatteryInfo BatteryInfo;
+
+typedef SInt8 ModemByte;
+typedef SInt8 BatteryByte;
+typedef SInt8 SoundMixerByte;
+typedef long PMResultCode;
+typedef struct SleepQRec SleepQRec;
+typedef SleepQRec * SleepQRecPtr;
+typedef struct HDQueueElement HDQueueElement;
+typedef struct PMgrQueueElement PMgrQueueElement;
+typedef long ( * SleepQProcPtr)(long message, SleepQRecPtr qRecPtr);
+typedef void ( * HDSpindownProcPtr)(HDQueueElement * theElement);
+typedef void ( * PMgrStateChangeProcPtr)(PMgrQueueElement *theElement, long stateBits);
+typedef SleepQProcPtr SleepQUPP;
+typedef HDSpindownProcPtr HDSpindownUPP;
+typedef PMgrStateChangeProcPtr PMgrStateChangeUPP;
+struct SleepQRec {
+ SleepQRecPtr sleepQLink;
+ short sleepQType;
+ SleepQUPP sleepQProc;
+ short sleepQFlags;
+};
+
+struct HDQueueElement {
+ struct HDQueueElement * hdQLink;
+ short hdQType;
+ short hdFlags;
+ HDSpindownUPP hdProc;
+ long hdUser;
+};
+
+struct PMgrQueueElement {
+ struct PMgrQueueElement * pmQLink;
+ short pmQType;
+ short pmFlags;
+ long pmNotifyBits;
+ PMgrStateChangeUPP pmProc;
+ long pmUser;
+};
+
+
+struct BatteryTimeRec {
+ unsigned long expectedBatteryTime;
+ unsigned long minimumBatteryTime;
+ unsigned long maximumBatteryTime;
+ unsigned long timeUntilCharged;
+};
+typedef struct BatteryTimeRec BatteryTimeRec;
+
+struct WakeupTime {
+ unsigned long wakeTime;
+ Boolean wakeEnabled;
+ SInt8 filler;
+};
+typedef struct WakeupTime WakeupTime;
+
+struct StartupTime {
+ unsigned long startTime;
+ Boolean startEnabled;
+ SInt8 filler;
+};
+typedef struct StartupTime StartupTime;
+
+enum {
+ kVersionOnePowerSource = 1,
+ kVersionTwoPowerSource = 2,
+ kCurrentPowerSourceVersion = kVersionTwoPowerSource
+};
+
+
+
+enum {
+ bSourceIsBattery = 0,
+ bSourceIsAC = 1,
+ bSourceCanBeCharged = 2,
+ bSourceIsUPS = 3,
+ bSourceProvidesWarnLevels = 4,
+ kSourceIsBatteryMask = (1 << bSourceIsBattery),
+ kSourceIsACMask = (1 << bSourceIsAC),
+ kSourceCanBeChargedMask = (1 << bSourceCanBeCharged),
+ kSourceIsUPSMask = (1 << bSourceIsUPS),
+ kSourceProvidesWarnLevelsMask = (1 << bSourceProvidesWarnLevels)
+};
+
+
+
+enum {
+ bSourceIsAvailable = 0,
+ bSourceIsCharging = 1,
+ bChargerIsAttached = 2,
+ kSourceIsAvailableMask = (1 << bSourceIsAvailable),
+ kSourceIsChargingMask = (1 << bSourceIsCharging),
+ kChargerIsAttachedMask = (1 << bChargerIsAttached)
+};
+
+
+
+enum {
+ kCapacityIsActual = 0,
+ kCapacityIsPercentOfMax = 1
+};
+
+
+enum {
+ kConfigSupportsWakeOnNetBit = 0,
+ kWakeOnNetAdminAccessesBit = 1,
+ kWakeOnAllNetAccessesBit = 2,
+ kUnmountServersBeforeSleepingBit = 3,
+ kConfigSupportsWakeOnNetMask = (1 << kConfigSupportsWakeOnNetBit),
+ kWakeOnNetAdminAccessesMask = (1 << kWakeOnNetAdminAccessesBit),
+ kWakeOnAllNetAccessesMask = (1 << kWakeOnAllNetAccessesBit),
+ kUnmountServersBeforeSleepingMask = (1 << kUnmountServersBeforeSleepingBit)
+};
+
+
+enum {
+ kCurrentCapacityIsActualValue = 0,
+ kCurrentCapacityIsPercentOfMax = 1
+};
+
+
+typedef SInt16 PowerSourceID;
+struct PowerSourceParamBlock {
+ PowerSourceID sourceID;
+ UInt16 sourceCapacityUsage;
+ UInt32 sourceVersion;
+ OptionBits sourceAttr;
+ OptionBits sourceState;
+ UInt32 currentCapacity;
+
+ UInt32 maxCapacity;
+ UInt32 timeRemaining;
+
+ UInt32 timeToFullCharge;
+
+ UInt32 voltage;
+ SInt32 current;
+
+
+ UInt32 lowWarnLevel;
+ UInt32 deadWarnLevel;
+ UInt32 reserved[16];
+};
+typedef struct PowerSourceParamBlock PowerSourceParamBlock;
+typedef PowerSourceParamBlock * PowerSourceParamBlockPtr;
+extern OSErr
+DisableWUTime(void) ;
+extern OSErr
+SetWUTime(long wuTime) ;
+extern OSErr
+GetWUTime(
+ long * wuTime,
+ Byte * wuFlag) ;
+extern OSErr
+BatteryStatus(
+ Byte * status,
+ Byte * power) ;
+extern OSErr
+ModemStatus(Byte * status) ;
+extern long
+IdleUpdate(void) ;
+extern long
+GetCPUSpeed(void) ;
+extern void
+EnableIdle(void) ;
+extern void
+DisableIdle(void) ;
+extern void
+SleepQInstall(SleepQRecPtr qRecPtr) ;
+extern void
+SleepQRemove(SleepQRecPtr qRecPtr) ;
+extern void
+AOn(void) ;
+extern void
+AOnIgnoreModem(void) ;
+extern void
+BOn(void) ;
+extern void
+AOff(void) ;
+extern void
+BOff(void) ;
+extern short
+PMSelectorCount(void) ;
+extern UInt32
+PMFeatures(void) ;
+extern UInt8
+GetSleepTimeout(void) ;
+extern void
+SetSleepTimeout(UInt8 timeout) ;
+extern UInt8
+GetHardDiskTimeout(void) ;
+extern void
+SetHardDiskTimeout(UInt8 timeout) ;
+extern Boolean
+HardDiskPowered(void) ;
+extern void
+SpinDownHardDisk(void) ;
+extern Boolean
+IsSpindownDisabled(void) ;
+extern void
+SetSpindownDisable(Boolean setDisable) ;
+extern OSErr
+HardDiskQInstall(HDQueueElement * theElement) ;
+extern OSErr
+HardDiskQRemove(HDQueueElement * theElement) ;
+extern void
+GetScaledBatteryInfo(
+ short whichBattery,
+ BatteryInfo * theInfo) ;
+extern void
+AutoSleepControl(Boolean enableSleep) ;
+extern UInt32
+GetIntModemInfo(void) ;
+extern void
+SetIntModemState(short theState) ;
+extern short
+MaximumProcessorSpeed(void) ;
+extern short
+MinimumProcessorSpeed(void) ;
+extern short
+CurrentProcessorSpeed(void) ;
+extern Boolean
+FullProcessorSpeed(void) ;
+extern Boolean
+SetProcessorSpeed(Boolean fullSpeed) ;
+extern short
+GetSCSIDiskModeAddress(void) ;
+extern void
+SetSCSIDiskModeAddress(short scsiAddress) ;
+extern void
+GetWakeupTimer(WakeupTime * theTime) ;
+extern void
+SetWakeupTimer(WakeupTime * theTime) ;
+extern Boolean
+IsProcessorCyclingEnabled(void) ;
+extern void
+EnableProcessorCycling(Boolean enable) ;
+extern short
+BatteryCount(void) ;
+extern Fixed
+GetBatteryVoltage(short whichBattery) ;
+extern void
+GetBatteryTimes(
+ short whichBattery,
+ BatteryTimeRec * theTimes) ;
+extern UInt8
+GetDimmingTimeout(void) ;
+extern void
+SetDimmingTimeout(UInt8 timeout) ;
+extern void
+DimmingControl(Boolean enableSleep) ;
+extern Boolean
+IsDimmingControlDisabled(void) ;
+extern Boolean
+IsAutoSlpControlDisabled(void) ;
+extern OSErr
+PMgrStateQInstall(PMgrQueueElement * theElement) ;
+extern OSErr
+PMgrStateQRemove(PMgrQueueElement * theElement) ;
+extern OSErr
+UpdateSystemActivity(UInt8 activity) ;
+extern OSErr
+DelaySystemIdle(void) ;
+extern OSErr
+GetStartupTimer(StartupTime * theTime) ;
+extern OSErr
+SetStartupTimer(StartupTime * theTime) ;
+extern OSErr
+GetLastActivity(ActivityInfo * theActivity) ;
+extern OSErr
+GetSoundMixerState(SoundMixerByte * theSoundMixerByte) ;
+extern OSErr
+SetSoundMixerState(SoundMixerByte * theSoundMixerByte) ;
+extern Boolean
+GetDimSuspendState(void) ;
+extern void
+SetDimSuspendState(Boolean dimSuspendState) ;
+extern SleepQUPP
+NewSleepQUPP(SleepQProcPtr userRoutine) ;
+extern HDSpindownUPP
+NewHDSpindownUPP(HDSpindownProcPtr userRoutine) ;
+extern PMgrStateChangeUPP
+NewPMgrStateChangeUPP(PMgrStateChangeProcPtr userRoutine) ;
+extern void
+DisposeSleepQUPP(SleepQUPP userUPP) ;
+extern void
+DisposeHDSpindownUPP(HDSpindownUPP userUPP) ;
+extern void
+DisposePMgrStateChangeUPP(PMgrStateChangeUPP userUPP) ;
+extern long
+InvokeSleepQUPP(
+ long message,
+ SleepQRecPtr qRecPtr,
+ SleepQUPP userUPP) ;
+extern void
+InvokeHDSpindownUPP(
+ HDQueueElement * theElement,
+ HDSpindownUPP userUPP) ;
+extern void
+InvokePMgrStateChangeUPP(
+ PMgrQueueElement * theElement,
+ long stateBits,
+ PMgrStateChangeUPP userUPP) ;
+
+
+
+
+
+}
+
+
+
+extern "C" {
+
+
+
+
+enum {
+ scInc = 1,
+ scNoInc = 2,
+ scAdd = 3,
+ scMove = 4,
+ scLoop = 5,
+ scNop = 6,
+ scStop = 7,
+ scComp = 8
+};
+
+
+struct SCSIInstr {
+ unsigned short scOpcode;
+ long scParam1;
+ long scParam2;
+};
+typedef struct SCSIInstr SCSIInstr;
+enum {
+ scsiVERSION = 43
+};
+
+
+
+
+
+typedef void ( * SCSICallbackProcPtr)(void * scsiPB);
+typedef SCSICallbackProcPtr SCSICallbackUPP;
+extern SCSICallbackUPP
+NewSCSICallbackUPP(SCSICallbackProcPtr userRoutine) ;
+extern void
+DisposeSCSICallbackUPP(SCSICallbackUPP userUPP) ;
+extern void
+InvokeSCSICallbackUPP(
+ void * scsiPB,
+ SCSICallbackUPP userUPP) ;
+
+
+
+
+
+
+enum {
+ SCSINop = 0x00,
+ SCSIExecIO = 0x01,
+ SCSIBusInquiry = 0x03,
+ SCSIReleaseQ = 0x04,
+ SCSIAbortCommand = 0x10,
+ SCSIResetBus = 0x11,
+ SCSIResetDevice = 0x12,
+ SCSITerminateIO = 0x13
+};
+
+enum {
+ vendorUnique = 0xC0
+};
+
+
+
+enum {
+ handshakeDataLength = 8,
+ maxCDBLength = 16,
+ vendorIDLength = 16
+};
+
+
+struct DeviceIdent {
+ UInt8 diReserved;
+ UInt8 bus;
+ UInt8 targetID;
+ UInt8 LUN;
+};
+typedef struct DeviceIdent DeviceIdent;
+
+
+
+
+
+
+enum {
+ kBusTypeSCSI = 0,
+ kBusTypeATA = 1,
+ kBusTypePCMCIA = 2,
+ kBusTypeMediaBay = 3
+};
+
+
+
+
+struct DeviceIdentATA {
+ UInt8 diReserved;
+ UInt8 busNum;
+ UInt8 devNum;
+ UInt8 diReserved2;
+};
+typedef struct DeviceIdentATA DeviceIdentATA;
+
+
+
+union CDB {
+ BytePtr cdbPtr;
+ UInt8 cdbBytes[16];
+};
+typedef union CDB CDB;
+typedef CDB * CDBPtr;
+
+struct SGRecord {
+ Ptr SGAddr;
+ UInt32 SGCount;
+};
+typedef struct SGRecord SGRecord;
+struct SCSIHdr {
+ struct SCSIHdr * qLink;
+ short scsiReserved1;
+ UInt16 scsiPBLength;
+ UInt8 scsiFunctionCode;
+ UInt8 scsiReserved2;
+ volatile OSErr scsiResult;
+ DeviceIdent scsiDevice;
+ SCSICallbackUPP scsiCompletion;
+ UInt32 scsiFlags;
+ BytePtr scsiDriverStorage;
+ Ptr scsiXPTprivate;
+ long scsiReserved3;
+};
+typedef struct SCSIHdr SCSIHdr;
+struct SCSI_PB {
+ SCSIHdr * qLink;
+ short scsiReserved1;
+ UInt16 scsiPBLength;
+ UInt8 scsiFunctionCode;
+ UInt8 scsiReserved2;
+ volatile OSErr scsiResult;
+ DeviceIdent scsiDevice;
+ SCSICallbackUPP scsiCompletion;
+ UInt32 scsiFlags;
+ BytePtr scsiDriverStorage;
+ Ptr scsiXPTprivate;
+ long scsiReserved3;
+};
+typedef struct SCSI_PB SCSI_PB;
+struct SCSI_IO {
+ SCSIHdr * qLink;
+ short scsiReserved1;
+ UInt16 scsiPBLength;
+ UInt8 scsiFunctionCode;
+ UInt8 scsiReserved2;
+ volatile OSErr scsiResult;
+ DeviceIdent scsiDevice;
+ SCSICallbackUPP scsiCompletion;
+ UInt32 scsiFlags;
+ BytePtr scsiDriverStorage;
+ Ptr scsiXPTprivate;
+ long scsiReserved3;
+
+ UInt16 scsiResultFlags;
+ UInt16 scsiReserved3pt5;
+ BytePtr scsiDataPtr;
+ UInt32 scsiDataLength;
+ BytePtr scsiSensePtr;
+ UInt8 scsiSenseLength;
+ UInt8 scsiCDBLength;
+ UInt16 scsiSGListCount;
+ UInt32 scsiReserved4;
+ UInt8 scsiSCSIstatus;
+ SInt8 scsiSenseResidual;
+ UInt16 scsiReserved5;
+ long scsiDataResidual;
+ CDB scsiCDB;
+ long scsiTimeout;
+ BytePtr scsiReserved5pt5;
+ UInt16 scsiReserved5pt6;
+ UInt16 scsiIOFlags;
+ UInt8 scsiTagAction;
+ UInt8 scsiReserved6;
+ UInt16 scsiReserved7;
+ UInt16 scsiSelectTimeout;
+ UInt8 scsiDataType;
+ UInt8 scsiTransferType;
+ UInt32 scsiReserved8;
+ UInt32 scsiReserved9;
+ UInt16 scsiHandshake[8];
+ UInt32 scsiReserved10;
+ UInt32 scsiReserved11;
+ struct SCSI_IO * scsiCommandLink;
+
+ UInt8 scsiSIMpublics[8];
+ UInt8 scsiAppleReserved6[8];
+
+
+
+ UInt16 scsiCurrentPhase;
+ short scsiSelector;
+ OSErr scsiOldCallResult;
+ UInt8 scsiSCSImessage;
+ UInt8 XPTprivateFlags;
+ UInt8 XPTextras[12];
+};
+typedef struct SCSI_IO SCSI_IO;
+typedef SCSI_IO SCSIExecIOPB;
+
+struct SCSIBusInquiryPB {
+ SCSIHdr * qLink;
+ short scsiReserved1;
+ UInt16 scsiPBLength;
+ UInt8 scsiFunctionCode;
+ UInt8 scsiReserved2;
+ volatile OSErr scsiResult;
+ DeviceIdent scsiDevice;
+ SCSICallbackUPP scsiCompletion;
+ UInt32 scsiFlags;
+ BytePtr scsiDriverStorage;
+ Ptr scsiXPTprivate;
+ long scsiReserved3;
+
+ UInt16 scsiEngineCount;
+ UInt16 scsiMaxTransferType;
+
+ UInt32 scsiDataTypes;
+
+ UInt16 scsiIOpbSize;
+ UInt16 scsiMaxIOpbSize;
+
+ UInt32 scsiFeatureFlags;
+
+ UInt8 scsiVersionNumber;
+ UInt8 scsiHBAInquiry;
+ UInt8 scsiTargetModeFlags;
+ UInt8 scsiScanFlags;
+
+ UInt32 scsiSIMPrivatesPtr;
+ UInt32 scsiSIMPrivatesSize;
+ UInt32 scsiAsyncFlags;
+
+ UInt8 scsiHiBusID;
+ UInt8 scsiInitiatorID;
+ UInt16 scsiBIReserved0;
+
+ UInt32 scsiBIReserved1;
+ UInt32 scsiFlagsSupported;
+
+ UInt16 scsiIOFlagsSupported;
+ UInt16 scsiWeirdStuff;
+ UInt16 scsiMaxTarget;
+ UInt16 scsiMaxLUN;
+
+ char scsiSIMVendor[16];
+ char scsiHBAVendor[16];
+ char scsiControllerFamily[16];
+ char scsiControllerType[16];
+
+ char scsiXPTversion[4];
+ char scsiSIMversion[4];
+ char scsiHBAversion[4];
+
+ UInt8 scsiHBAslotType;
+ UInt8 scsiHBAslotNumber;
+ UInt16 scsiSIMsRsrcID;
+
+ UInt16 scsiBIReserved3;
+ UInt16 scsiAdditionalLength;
+};
+typedef struct SCSIBusInquiryPB SCSIBusInquiryPB;
+
+struct SCSIAbortCommandPB {
+ SCSIHdr * qLink;
+ short scsiReserved1;
+ UInt16 scsiPBLength;
+ UInt8 scsiFunctionCode;
+ UInt8 scsiReserved2;
+ volatile OSErr scsiResult;
+ DeviceIdent scsiDevice;
+ SCSICallbackUPP scsiCompletion;
+ UInt32 scsiFlags;
+ BytePtr scsiDriverStorage;
+ Ptr scsiXPTprivate;
+ long scsiReserved3;
+ SCSI_IO * scsiIOptr;
+};
+typedef struct SCSIAbortCommandPB SCSIAbortCommandPB;
+
+struct SCSITerminateIOPB {
+ SCSIHdr * qLink;
+ short scsiReserved1;
+ UInt16 scsiPBLength;
+ UInt8 scsiFunctionCode;
+ UInt8 scsiReserved2;
+ volatile OSErr scsiResult;
+ DeviceIdent scsiDevice;
+ SCSICallbackUPP scsiCompletion;
+ UInt32 scsiFlags;
+ BytePtr scsiDriverStorage;
+ Ptr scsiXPTprivate;
+ long scsiReserved3;
+ SCSI_IO * scsiIOptr;
+};
+typedef struct SCSITerminateIOPB SCSITerminateIOPB;
+
+struct SCSIResetBusPB {
+ SCSIHdr * qLink;
+ short scsiReserved1;
+ UInt16 scsiPBLength;
+ UInt8 scsiFunctionCode;
+ UInt8 scsiReserved2;
+ volatile OSErr scsiResult;
+ DeviceIdent scsiDevice;
+ SCSICallbackUPP scsiCompletion;
+ UInt32 scsiFlags;
+ BytePtr scsiDriverStorage;
+ Ptr scsiXPTprivate;
+ long scsiReserved3;
+};
+typedef struct SCSIResetBusPB SCSIResetBusPB;
+
+struct SCSIResetDevicePB {
+ SCSIHdr * qLink;
+ short scsiReserved1;
+ UInt16 scsiPBLength;
+ UInt8 scsiFunctionCode;
+ UInt8 scsiReserved2;
+ volatile OSErr scsiResult;
+ DeviceIdent scsiDevice;
+ SCSICallbackUPP scsiCompletion;
+ UInt32 scsiFlags;
+ BytePtr scsiDriverStorage;
+ Ptr scsiXPTprivate;
+ long scsiReserved3;
+};
+typedef struct SCSIResetDevicePB SCSIResetDevicePB;
+
+struct SCSIReleaseQPB {
+ SCSIHdr * qLink;
+ short scsiReserved1;
+ UInt16 scsiPBLength;
+ UInt8 scsiFunctionCode;
+ UInt8 scsiReserved2;
+ volatile OSErr scsiResult;
+ DeviceIdent scsiDevice;
+ SCSICallbackUPP scsiCompletion;
+ UInt32 scsiFlags;
+ BytePtr scsiDriverStorage;
+ Ptr scsiXPTprivate;
+ long scsiReserved3;
+};
+typedef struct SCSIReleaseQPB SCSIReleaseQPB;
+
+struct SCSIGetVirtualIDInfoPB {
+ SCSIHdr * qLink;
+ short scsiReserved1;
+ UInt16 scsiPBLength;
+ UInt8 scsiFunctionCode;
+ UInt8 scsiReserved2;
+ volatile OSErr scsiResult;
+ DeviceIdent scsiDevice;
+ SCSICallbackUPP scsiCompletion;
+ UInt32 scsiFlags;
+ Ptr scsiDriverStorage;
+ Ptr scsiXPTprivate;
+ long scsiReserved3;
+ UInt16 scsiOldCallID;
+ Boolean scsiExists;
+ SInt8 filler;
+};
+typedef struct SCSIGetVirtualIDInfoPB SCSIGetVirtualIDInfoPB;
+
+struct SCSIDriverPB {
+ SCSIHdr * qLink;
+ short scsiReserved1;
+ UInt16 scsiPBLength;
+ UInt8 scsiFunctionCode;
+ UInt8 scsiReserved2;
+ volatile OSErr scsiResult;
+ DeviceIdent scsiDevice;
+ SCSICallbackUPP scsiCompletion;
+ UInt32 scsiFlags;
+ Ptr scsiDriverStorage;
+ Ptr scsiXPTprivate;
+ long scsiReserved3;
+ short scsiDriver;
+ UInt16 scsiDriverFlags;
+ DeviceIdent scsiNextDevice;
+};
+typedef struct SCSIDriverPB SCSIDriverPB;
+
+struct SCSILoadDriverPB {
+ SCSIHdr * qLink;
+ short scsiReserved1;
+ UInt16 scsiPBLength;
+ UInt8 scsiFunctionCode;
+ UInt8 scsiReserved2;
+ volatile OSErr scsiResult;
+ DeviceIdent scsiDevice;
+ SCSICallbackUPP scsiCompletion;
+ UInt32 scsiFlags;
+ Ptr scsiDriverStorage;
+ Ptr scsiXPTprivate;
+ long scsiReserved3;
+ short scsiLoadedRefNum;
+ Boolean scsiDiskLoadFailed;
+ SInt8 filler;
+};
+typedef struct SCSILoadDriverPB SCSILoadDriverPB;
+
+
+enum {
+ scsiTransferBlind = 0,
+ scsiTransferPolled = 1
+};
+
+enum {
+ scsiErrorBase = -7936
+};
+
+enum {
+ scsiRequestInProgress = 1,
+
+ scsiRequestAborted = scsiErrorBase + 2,
+ scsiUnableToAbort = scsiErrorBase + 3,
+ scsiNonZeroStatus = scsiErrorBase + 4,
+ scsiUnused05 = scsiErrorBase + 5,
+ scsiUnused06 = scsiErrorBase + 6,
+ scsiUnused07 = scsiErrorBase + 7,
+ scsiUnused08 = scsiErrorBase + 8,
+ scsiUnableToTerminate = scsiErrorBase + 9,
+ scsiSelectTimeout = scsiErrorBase + 10,
+ scsiCommandTimeout = scsiErrorBase + 11,
+ scsiIdentifyMessageRejected = scsiErrorBase + 12,
+ scsiMessageRejectReceived = scsiErrorBase + 13,
+ scsiSCSIBusReset = scsiErrorBase + 14,
+ scsiParityError = scsiErrorBase + 15,
+ scsiAutosenseFailed = scsiErrorBase + 16,
+ scsiUnused11 = scsiErrorBase + 17,
+ scsiDataRunError = scsiErrorBase + 18,
+ scsiUnexpectedBusFree = scsiErrorBase + 19,
+ scsiSequenceFailed = scsiErrorBase + 20,
+ scsiWrongDirection = scsiErrorBase + 21,
+ scsiUnused16 = scsiErrorBase + 22,
+ scsiBDRsent = scsiErrorBase + 23,
+ scsiTerminated = scsiErrorBase + 24,
+ scsiNoNexus = scsiErrorBase + 25,
+ scsiCDBReceived = scsiErrorBase + 26,
+
+ scsiTooManyBuses = scsiErrorBase + 48,
+ scsiBusy = scsiErrorBase + 49,
+ scsiProvideFail = scsiErrorBase + 50,
+ scsiDeviceNotThere = scsiErrorBase + 51,
+ scsiNoHBA = scsiErrorBase + 52,
+ scsiDeviceConflict = scsiErrorBase + 53,
+ scsiNoSuchXref = scsiErrorBase + 54,
+ scsiQLinkInvalid = scsiErrorBase + 55,
+
+
+ scsiPBLengthError = scsiErrorBase + 64,
+ scsiFunctionNotAvailable = scsiErrorBase + 65,
+ scsiRequestInvalid = scsiErrorBase + 66,
+ scsiBusInvalid = scsiErrorBase + 67,
+ scsiTIDInvalid = scsiErrorBase + 68,
+ scsiLUNInvalid = scsiErrorBase + 69,
+ scsiIDInvalid = scsiErrorBase + 70,
+ scsiDataTypeInvalid = scsiErrorBase + 71,
+ scsiTransferTypeInvalid = scsiErrorBase + 72,
+ scsiCDBLengthInvalid = scsiErrorBase + 73
+};
+
+
+enum {
+ scsiUnused74 = scsiErrorBase + 74,
+ scsiUnused75 = scsiErrorBase + 75,
+ scsiBadDataLength = scsiErrorBase + 76,
+ scsiPartialPrepared = scsiErrorBase + 77,
+ scsiInvalidMsgType = scsiErrorBase + 78,
+ scsiUnused79 = scsiErrorBase + 79,
+ scsiBadConnID = scsiErrorBase + 80,
+ scsiUnused81 = scsiErrorBase + 81,
+ scsiIOInProgress = scsiErrorBase + 82,
+ scsiTargetReserved = scsiErrorBase + 83,
+ scsiUnused84 = scsiErrorBase + 84,
+ scsiUnused85 = scsiErrorBase + 85,
+ scsiBadConnType = scsiErrorBase + 86,
+ scsiCannotLoadPlugin = scsiErrorBase + 87
+};
+enum {
+ scsiFamilyInternalError = scsiErrorBase + 87,
+ scsiPluginInternalError = scsiErrorBase + 88,
+ scsiVendorSpecificErrorBase = scsiErrorBase + 128,
+ scsiVendorSpecificErrorCount = 16
+};
+
+
+enum {
+ scsiExecutionErrors = scsiErrorBase,
+ scsiNotExecutedErrors = scsiTooManyBuses,
+ scsiParameterErrors = scsiPBLengthError
+};
+
+
+enum {
+ scsiSIMQFrozen = 0x0001,
+ scsiAutosenseValid = 0x0002,
+ scsiBusNotFree = 0x0004
+};
+
+
+enum {
+ kbSCSIDisableAutosense = 29,
+ kbSCSIFlagReservedA = 28,
+ kbSCSIFlagReserved0 = 27,
+ kbSCSICDBLinked = 26,
+ kbSCSIQEnable = 25,
+ kbSCSICDBIsPointer = 24,
+ kbSCSIFlagReserved1 = 23,
+ kbSCSIInitiateSyncData = 22,
+ kbSCSIDisableSyncData = 21,
+ kbSCSISIMQHead = 20,
+ kbSCSISIMQFreeze = 19,
+ kbSCSISIMQNoFreeze = 18,
+ kbSCSIDoDisconnect = 17,
+ kbSCSIDontDisconnect = 16,
+ kbSCSIDataReadyForDMA = 15,
+ kbSCSIFlagReserved3 = 14,
+ kbSCSIDataPhysical = 13,
+ kbSCSISensePhysical = 12,
+ kbSCSIFlagReserved5 = 11,
+ kbSCSIFlagReserved6 = 10,
+ kbSCSIFlagReserved7 = 9,
+ kbSCSIFlagReserved8 = 8,
+ kbSCSIDataBufferValid = 7,
+ kbSCSIStatusBufferValid = 6,
+ kbSCSIMessageBufferValid = 5,
+ kbSCSIFlagReserved9 = 4
+};
+
+
+enum {
+ scsiDirectionMask = (long)0xC0000000,
+ scsiDirectionNone = (long)0xC0000000,
+ scsiDirectionReserved = 0x00000000,
+ scsiDirectionOut = (long)0x80000000,
+ scsiDirectionIn = 0x40000000,
+ scsiDisableAutosense = 0x20000000,
+ scsiFlagReservedA = 0x10000000,
+ scsiFlagReserved0 = 0x08000000,
+ scsiCDBLinked = 0x04000000,
+ scsiQEnable = 0x02000000,
+ scsiCDBIsPointer = 0x01000000,
+ scsiFlagReserved1 = 0x00800000,
+ scsiInitiateSyncData = 0x00400000,
+ scsiDisableSyncData = 0x00200000,
+ scsiSIMQHead = 0x00100000,
+ scsiSIMQFreeze = 0x00080000,
+ scsiSIMQNoFreeze = 0x00040000,
+ scsiDoDisconnect = 0x00020000,
+ scsiDontDisconnect = 0x00010000,
+ scsiDataReadyForDMA = 0x00008000,
+ scsiFlagReserved3 = 0x00004000,
+ scsiDataPhysical = 0x00002000,
+ scsiSensePhysical = 0x00001000,
+ scsiFlagReserved5 = 0x00000800,
+ scsiFlagReserved6 = 0x00000400,
+ scsiFlagReserved7 = 0x00000200,
+ scsiFlagReserved8 = 0x00000100
+};
+
+
+enum {
+ scsiNoParityCheck = 0x0002,
+ scsiDisableSelectWAtn = 0x0004,
+ scsiSavePtrOnDisconnect = 0x0008,
+ scsiNoBucketIn = 0x0010,
+ scsiNoBucketOut = 0x0020,
+ scsiDisableWide = 0x0040,
+ scsiInitiateWide = 0x0080,
+ scsiRenegotiateSense = 0x0100,
+ scsiDisableDiscipline = 0x0200,
+ scsiIOFlagReserved0080 = 0x0080,
+ scsiIOFlagReserved8000 = 0x8000
+};
+
+
+
+enum {
+ scsiBusMDP = 0x80,
+ scsiBusWide32 = 0x40,
+ scsiBusWide16 = 0x20,
+ scsiBusSDTR = 0x10,
+ scsiBusLinkedCDB = 0x08,
+ scsiBusTagQ = 0x02,
+ scsiBusSoftReset = 0x01
+};
+
+
+enum {
+ scsiDataBuffer = 0,
+ scsiDataTIB = 1,
+ scsiDataSG = 2,
+ scsiDataIOTable = 3
+};
+
+
+
+enum {
+ scsiBusDataTIB = (1 << scsiDataTIB),
+ scsiBusDataBuffer = (1 << scsiDataBuffer),
+ scsiBusDataSG = (1 << scsiDataSG),
+ scsiBusDataIOTable = (1 << scsiDataIOTable),
+ scsiBusDataReserved = (long)0x80000000
+};
+
+
+enum {
+ scsiBusScansDevices = 0x80,
+ scsiBusScansOnInit = 0x40,
+ scsiBusLoadsROMDrivers = 0x20
+};
+
+
+enum {
+ scsiBusLVD = 0x00000400,
+ scsiBusUltra3SCSI = 0x00000200,
+ scsiBusUltra2SCSI = 0x00000100,
+ scsiBusInternalExternalMask = 0x000000C0,
+ scsiBusInternalExternalUnknown = 0x00000000,
+ scsiBusInternalExternal = 0x000000C0,
+ scsiBusInternal = 0x00000080,
+ scsiBusExternal = 0x00000040,
+ scsiBusCacheCoherentDMA = 0x00000020,
+ scsiBusOldCallCapable = 0x00000010,
+ scsiBusUltraSCSI = 0x00000008,
+ scsiBusDifferential = 0x00000004,
+ scsiBusFastSCSI = 0x00000002,
+ scsiBusDMAavailable = 0x00000001
+};
+
+
+enum {
+ scsiOddDisconnectUnsafeRead1 = 0x0001,
+ scsiOddDisconnectUnsafeWrite1 = 0x0002,
+ scsiBusErrorsUnsafe = 0x0004,
+ scsiRequiresHandshake = 0x0008,
+ scsiTargetDrivenSDTRSafe = 0x0010,
+ scsiOddCountForPhysicalUnsafe = 0x0020,
+ scsiAbortCmdFixed = 0x0040,
+ scsiMeshACKTimingFixed = 0x0080
+};
+
+
+enum {
+ scsiMotherboardBus = 0x00,
+ scsiNuBus = 0x01,
+ scsiPDSBus = 0x03,
+ scsiPCIBus = 0x04,
+ scsiPCMCIABus = 0x05,
+ scsiFireWireBridgeBus = 0x06,
+ scsiUSBBus = 0x07
+};
+
+
+enum {
+ scsiDeviceSensitive = 0x0001,
+ scsiDeviceNoOldCallAccess = 0x0002
+};
+
+
+
+
+
+
+enum {
+ scsiStatGood = 0x00,
+ scsiStatCheckCondition = 0x02,
+ scsiStatConditionMet = 0x04,
+ scsiStatBusy = 0x08,
+ scsiStatIntermediate = 0x10,
+ scsiStatIntermedMet = 0x14,
+ scsiStatResvConflict = 0x18,
+ scsiStatTerminated = 0x22,
+ scsiStatQFull = 0x28
+};
+
+
+enum {
+ kCmdCompleteMsg = 0,
+ kExtendedMsg = 1,
+ kSaveDataPointerMsg = 2,
+ kRestorePointersMsg = 3,
+ kDisconnectMsg = 4,
+ kInitiatorDetectedErrorMsg = 5,
+ kAbortMsg = 6,
+ kMsgRejectMsg = 7,
+ kNoOperationMsg = 8,
+ kMsgParityErrorMsg = 9,
+ kLinkedCmdCompleteMsg = 10,
+ kLinkedCmdCompleteWithFlagMsg = 11,
+ kBusDeviceResetMsg = 12,
+ kAbortTagMsg = 13,
+ kClearQueueMsg = 14,
+ kInitiateRecoveryMsg = 15,
+ kReleaseRecoveryMsg = 16,
+ kTerminateIOProcessMsg = 17,
+ kSimpleQueueTag = 0x20,
+ kHeadOfQueueTagMsg = 0x21,
+ kOrderedQueueTagMsg = 0x22,
+ kIgnoreWideResidueMsg = 0x23
+};
+extern OSErr
+SCSIAction(SCSI_PB * parameterBlock) ;
+
+
+}
+
+
+
+extern "C" {
+
+
+
+
+
+enum {
+ kSystemSoundNoError = 0,
+ kSystemSoundUnspecifiedError = -1500
+};
+
+
+
+
+typedef UInt32 SystemSoundActionID;
+extern void
+AlertSoundPlay(void) ;
+extern void
+SystemSoundPlay(SystemSoundActionID inAction) ;
+extern OSStatus
+SystemSoundGetActionID(
+ const FSRef * userFile,
+ SystemSoundActionID * outAction) ;
+extern OSStatus
+SystemSoundRemoveActionID(SystemSoundActionID inAction) ;
+
+
+
+
+}
+
+
+
+
+
+
+enum {
+ kThumbnail32BitData = 'it32',
+ kThumbnail8BitMask = 't8mk'
+};
+
+enum {
+ kHuge1BitMask = 'ich#',
+ kHuge4BitData = 'ich4',
+ kHuge8BitData = 'ich8',
+ kHuge32BitData = 'ih32',
+ kHuge8BitMask = 'h8mk'
+};
+
+
+
+enum {
+ kLarge1BitMask = 'ICN#',
+ kLarge4BitData = 'icl4',
+ kLarge8BitData = 'icl8',
+ kLarge32BitData = 'il32',
+ kLarge8BitMask = 'l8mk',
+ kSmall1BitMask = 'ics#',
+ kSmall4BitData = 'ics4',
+ kSmall8BitData = 'ics8',
+ kSmall32BitData = 'is32',
+ kSmall8BitMask = 's8mk',
+ kMini1BitMask = 'icm#',
+ kMini4BitData = 'icm4',
+ kMini8BitData = 'icm8'
+};
+
+
+enum {
+ large1BitMask = kLarge1BitMask,
+ large4BitData = kLarge4BitData,
+ large8BitData = kLarge8BitData,
+ small1BitMask = kSmall1BitMask,
+ small4BitData = kSmall4BitData,
+ small8BitData = kSmall8BitData,
+ mini1BitMask = kMini1BitMask,
+ mini4BitData = kMini4BitData,
+ mini8BitData = kMini8BitData
+};
+enum {
+ kIconFamilyType = 'icns'
+};
+
+
+struct IconFamilyElement {
+ OSType elementType;
+ Size elementSize;
+ unsigned char elementData[1];
+};
+typedef struct IconFamilyElement IconFamilyElement;
+struct IconFamilyResource {
+ OSType resourceType;
+ Size resourceSize;
+ IconFamilyElement elements[1];
+
+};
+typedef struct IconFamilyResource IconFamilyResource;
+typedef IconFamilyResource * IconFamilyPtr;
+typedef IconFamilyPtr * IconFamilyHandle;
+
+
+
+enum {
+ kTileIconVariant = 'tile',
+ kRolloverIconVariant = 'over',
+ kDropIconVariant = 'drop',
+ kOpenIconVariant = 'open',
+ kOpenDropIconVariant = 'odrp'
+};
+
+
+
+
+
+extern "C" {
+
+
+typedef UInt8 OTUInt8Param;
+typedef UInt16 OTUInt16Param;
+typedef SInt16 OTSInt16Param;
+typedef SInt8 OTSInt8Param;
+typedef Boolean OTBooleanParam;
+typedef UInt8 uchar_p;
+typedef UInt16 ushort_p;
+typedef SInt16 short_p;
+typedef SInt8 char_p;
+typedef Boolean boolean_p;
+
+
+
+
+
+
+
+ typedef unsigned int OTByteCount;
+ typedef unsigned int OTItemCount;
+ typedef int OTInt32;
+ typedef unsigned int OTUInt32;
+
+
+typedef long int_t;
+typedef unsigned long uint_t;
+enum {
+ kOTCFMClass = 'otan'
+};
+
+
+
+
+typedef UInt32 OTTimeout;
+
+typedef SInt32 OTSequence;
+
+typedef SInt32 OTNameID;
+
+
+
+
+typedef SInt32 OTReason;
+
+typedef UInt32 OTQLen;
+
+typedef UInt8 * OTClientName;
+
+typedef SInt32 OTCommand;
+
+typedef void* OTClient;
+typedef UInt32 OTOpenFlags;
+enum {
+ kO_ASYNC = 0x01,
+ kO_NDELAY = 0x04,
+ kO_NONBLOCK = 0x04
+};
+typedef UInt16 OTUnixErr;
+typedef UInt16 OTXTIErr;
+enum {
+ TSUCCESS = 0,
+ TBADADDR = 1,
+ TBADOPT = 2,
+ TACCES = 3,
+ TBADF = 4,
+ TNOADDR = 5,
+ TOUTSTATE = 6,
+ TBADSEQ = 7,
+ TSYSERR = 8,
+ TLOOK = 9,
+ TBADDATA = 10,
+ TBUFOVFLW = 11,
+ TFLOW = 12,
+ TNODATA = 13,
+ TNODIS = 14,
+ TNOUDERR = 15,
+ TBADFLAG = 16,
+ TNOREL = 17,
+ TNOTSUPPORT = 18,
+ TSTATECHNG = 19,
+ TNOSTRUCTYPE = 20,
+ TBADNAME = 21,
+ TBADQLEN = 22,
+ TADDRBUSY = 23,
+ TINDOUT = 24,
+ TPROVMISMATCH = 25,
+ TRESQLEN = 26,
+ TRESADDR = 27,
+ TQFULL = 28,
+ TPROTO = 29,
+ TBADSYNC = 30,
+ TCANCELED = 31,
+ TLASTXTIERROR = 31
+};
+typedef SInt32 OTResult;
+enum {
+ kOTGenericName = 0
+};
+
+typedef UInt16 OTAddressType;
+struct OTAddress {
+ OTAddressType fAddressType;
+ UInt8 fAddress[1];
+};
+typedef struct OTAddress OTAddress;
+enum {
+ T_BIND = 1,
+ T_OPTMGMT = 2,
+ T_CALL = 3,
+ T_DIS = 4,
+ T_UNITDATA = 5,
+ T_UDERROR = 6,
+ T_INFO = 7,
+ T_REPLYDATA = 8,
+ T_REQUESTDATA = 9,
+ T_UNITREQUEST = 10,
+ T_UNITREPLY = 11
+};
+
+
+typedef UInt32 OTStructType;
+
+
+
+
+enum {
+ T_ADDR = 0x01,
+ T_OPT = 0x02,
+ T_UDATA = 0x04,
+ T_ALL = 0xFFFF
+};
+
+typedef UInt32 OTFieldsType;
+
+
+
+
+
+
+
+typedef UInt32 OTFlags;
+
+
+
+
+enum {
+ T_MORE = 0x0001,
+ T_EXPEDITED = 0x0002,
+ T_ACKNOWLEDGED = 0x0004,
+ T_PARTIALDATA = 0x0008,
+ T_NORECEIPT = 0x0010,
+ T_TIMEDOUT = 0x0020
+};
+
+
+
+enum {
+ T_NEGOTIATE = 0x0004,
+ T_CHECK = 0x0008,
+ T_DEFAULT = 0x0010,
+ T_CURRENT = 0x0080
+};
+
+
+
+
+
+
+enum {
+ T_SUCCESS = 0x0020,
+ T_FAILURE = 0x0040,
+ T_PARTSUCCESS = 0x0100,
+ T_READONLY = 0x0200,
+ T_NOTSUPPORT = 0x0400
+};
+typedef UInt32 OTBand;
+ typedef class TProvider* ProviderRef;
+ typedef class TEndpoint* EndpointRef;
+ typedef class TMapper* MapperRef;
+typedef UInt32 OTEventCode;
+enum {
+ T_LISTEN = 0x0001,
+ T_CONNECT = 0x0002,
+ T_DATA = 0x0004,
+ T_EXDATA = 0x0008,
+ T_DISCONNECT = 0x0010,
+ T_ERROR = 0x0020,
+ T_UDERR = 0x0040,
+ T_ORDREL = 0x0080,
+ T_GODATA = 0x0100,
+ T_GOEXDATA = 0x0200,
+ T_REQUEST = 0x0400,
+ T_REPLY = 0x0800,
+ T_PASSCON = 0x1000,
+ T_RESET = 0x2000,
+ kPRIVATEEVENT = 0x10000000,
+ kCOMPLETEEVENT = 0x20000000,
+ T_BINDCOMPLETE = 0x20000001,
+ T_UNBINDCOMPLETE = 0x20000002,
+ T_ACCEPTCOMPLETE = 0x20000003,
+ T_REPLYCOMPLETE = 0x20000004,
+ T_DISCONNECTCOMPLETE = 0x20000005,
+ T_OPTMGMTCOMPLETE = 0x20000006,
+ T_OPENCOMPLETE = 0x20000007,
+ T_GETPROTADDRCOMPLETE = 0x20000008,
+ T_RESOLVEADDRCOMPLETE = 0x20000009,
+ T_GETINFOCOMPLETE = 0x2000000A,
+ T_SYNCCOMPLETE = 0x2000000B,
+ T_MEMORYRELEASED = 0x2000000C,
+ T_REGNAMECOMPLETE = 0x2000000D,
+ T_DELNAMECOMPLETE = 0x2000000E,
+ T_LKUPNAMECOMPLETE = 0x2000000F,
+ T_LKUPNAMERESULT = 0x20000010,
+ kOTSyncIdleEvent = 0x20000011,
+ kSTREAMEVENT = 0x21000000,
+ kOTReservedEvent1 = 0x21000001,
+ kGetmsgEvent = 0x21000002,
+ kStreamReadEvent = 0x21000003,
+ kStreamWriteEvent = 0x21000004,
+ kStreamIoctlEvent = 0x21000005,
+ kOTReservedEvent2 = 0x21000006,
+ kStreamOpenEvent = 0x21000007,
+ kPollEvent = 0x21000008,
+ kOTReservedEvent3 = 0x21000009,
+ kOTReservedEvent4 = 0x2100000A,
+ kOTReservedEvent5 = 0x2100000B,
+ kOTReservedEvent6 = 0x2100000C,
+ kOTReservedEvent7 = 0x2100000D,
+ kOTReservedEvent8 = 0x2100000E,
+ kSIGNALEVENT = 0x22000000,
+ kPROTOCOLEVENT = 0x23000000,
+ kOTProviderIsDisconnected = 0x23000001,
+ kOTProviderIsReconnected = 0x23000002,
+ kOTProviderWillClose = 0x24000001,
+ kOTProviderIsClosed = 0x24000002,
+ kOTPortDisabled = 0x25000001,
+ kOTPortEnabled = 0x25000002,
+ kOTPortOffline = 0x25000003,
+ kOTPortOnline = 0x25000004,
+ kOTClosePortRequest = 0x25000005,
+ kOTYieldPortRequest = 0x25000005,
+ kOTNewPortRegistered = 0x25000006,
+ kOTPortNetworkChange = 0x25000007,
+ kOTConfigurationChanged = 0x26000001,
+ kOTSystemSleep = 0x26000002,
+ kOTSystemShutdown = 0x26000003,
+ kOTSystemAwaken = 0x26000004,
+ kOTSystemIdle = 0x26000005,
+ kOTSystemSleepPrep = 0x26000006,
+ kOTSystemShutdownPrep = 0x26000007,
+ kOTSystemAwakenPrep = 0x26000008,
+ kOTStackIsLoading = 0x27000001,
+ kOTStackWasLoaded = 0x27000002,
+ kOTStackIsUnloading = 0x27000003
+};
+enum {
+ kOTDisablePortEvent = 0x21000001,
+ kStreamCloseEvent = 0x21000006,
+ kBackgroundStreamEvent = 0x21000009,
+ kIoctlRecvFdEvent = 0x2100000A,
+ kOTTryShutdownEvent = 0x2100000B,
+ kOTScheduleTerminationEvent = 0x2100000C,
+ kOTEnablePortEvent = 0x2100000D,
+ kOTNewPortRegisteredEvent = 0x2100000E,
+ kOTPortOfflineEvent = 0x2100000F,
+ kOTPortOnlineEvent = 0x21000010,
+ kOTPortNetworkChangeEvent = 0x21000011
+};
+enum {
+ kSIGHUP = 1,
+ kSIGURG = 16,
+ kSIGPOLL = 30
+};
+typedef void ( * OTNotifyProcPtr)(void *contextPtr, OTEventCode code, OTResult result, void *cookie);
+typedef OTNotifyProcPtr OTNotifyUPP;
+extern OTNotifyUPP
+NewOTNotifyUPP(OTNotifyProcPtr userRoutine) ;
+extern void
+DisposeOTNotifyUPP(OTNotifyUPP userUPP) ;
+extern void
+InvokeOTNotifyUPP(
+ void * contextPtr,
+ OTEventCode code,
+ OTResult result,
+ void * cookie,
+ OTNotifyUPP userUPP) ;
+
+
+
+enum {
+ XTI_GENERIC = 0xFFFF
+};
+
+typedef UInt32 OTXTILevel;
+
+typedef UInt32 OTXTIName;
+
+enum {
+ XTI_DEBUG = 0x0001,
+ XTI_LINGER = 0x0080,
+ XTI_RCVBUF = 0x1002,
+ XTI_RCVLOWAT = 0x1004,
+ XTI_SNDBUF = 0x1001,
+ XTI_SNDLOWAT = 0x1003,
+ XTI_PROTOTYPE = 0x1005,
+ OPT_CHECKSUM = 0x0600,
+ OPT_RETRYCNT = 0x0601,
+ OPT_INTERVAL = 0x0602,
+ OPT_ENABLEEOM = 0x0603,
+ OPT_SELFSEND = 0x0604,
+ OPT_SERVERSTATUS = 0x0605,
+ OPT_ALERTENABLE = 0x0606,
+ OPT_KEEPALIVE = 0x0008
+};
+enum {
+ MIOC_STREAMIO = 'A',
+ MIOC_TMOD = 'a',
+ MIOC_STRLOG = 'b',
+ MIOC_ND = 'c',
+ MIOC_ECHO = 'd',
+ MIOC_TLI = 'e',
+ MIOC_RESERVEDf = 'f',
+ MIOC_SAD = 'g',
+ MIOC_ARP = 'h',
+ MIOC_HAVOC = 'H',
+ MIOC_RESERVEDi = 'i',
+ MIOC_SIOC = 'j',
+ MIOC_TCP = 'k',
+ MIOC_DLPI = 'l',
+ MIOC_SOCKETS = 'm',
+ MIOC_IPX = 'o',
+ MIOC_OT = 'O',
+ MIOC_ATALK = 'T',
+ MIOC_SRL = 'U',
+ MIOC_RESERVEDp = 'p',
+ MIOC_RESERVEDr = 'r',
+ MIOC_RESERVEDs = 's',
+ MIOC_CFIG = 'z'
+};
+
+
+
+enum {
+ I_OTGetMiscellaneousEvents = ((MIOC_OT << 8) | 1),
+ I_OTSetFramingType = ((MIOC_OT << 8) | 2),
+ kOTGetFramingValue = (unsigned long)0xFFFFFFFF,
+ I_OTSetRawMode = ((MIOC_OT << 8) | 3),
+ kOTSetRecvMode = 0x01,
+ kOTSendErrorPacket = 0x02,
+ I_OTConnect = ((MIOC_OT << 8) | 4),
+ I_OTDisconnect = ((MIOC_OT << 8) | 5),
+ I_OTScript = ((MIOC_OT << 8) | 6)
+};
+
+
+
+struct OTScriptInfo {
+ UInt32 fScriptType;
+ void * fTheScript;
+ UInt32 fScriptLength;
+};
+typedef struct OTScriptInfo OTScriptInfo;
+
+
+
+
+
+typedef UInt32 OTXTIStates;
+enum {
+ T_UNINIT = 0,
+ T_UNBND = 1,
+ T_IDLE = 2,
+ T_OUTCON = 3,
+ T_INCON = 4,
+ T_DATAXFER = 5,
+ T_OUTREL = 6,
+ T_INREL = 7
+};
+
+
+
+
+
+
+enum {
+ T_YES = 1,
+ T_NO = 0,
+ T_UNUSED = (unsigned long)(-1),
+ kT_NULL = 0,
+ T_ABSREQ = 0x8000
+};
+
+enum {
+ kT_UNSPEC = (unsigned long)0xFFFFFFFD,
+ T_ALLOPT = 0
+};
+typedef class OTConfiguration* OTConfigurationRef;
+struct TOptionHeader {
+ ByteCount len;
+
+
+ OTXTILevel level;
+ OTXTIName name;
+ UInt32 status;
+};
+typedef struct TOptionHeader TOptionHeader;
+
+
+
+
+
+struct TOption {
+ ByteCount len;
+
+
+ OTXTILevel level;
+ OTXTIName name;
+ UInt32 status;
+ UInt32 value[1];
+};
+typedef struct TOption TOption;
+
+enum {
+ kOTOptionHeaderSize = sizeof(TOptionHeader),
+ kOTBooleanOptionDataSize = sizeof(UInt32),
+ kOTBooleanOptionSize = kOTOptionHeaderSize + kOTBooleanOptionDataSize,
+ kOTOneByteOptionSize = kOTOptionHeaderSize + 1,
+ kOTTwoByteOptionSize = kOTOptionHeaderSize + 2,
+ kOTFourByteOptionSize = kOTOptionHeaderSize + sizeof(UInt32)
+};
+struct t_kpalive {
+ SInt32 kp_onoff;
+ SInt32 kp_timeout;
+};
+typedef struct t_kpalive t_kpalive;
+
+struct t_linger {
+ SInt32 l_onoff;
+ SInt32 l_linger;
+};
+typedef struct t_linger t_linger;
+
+
+
+
+
+
+
+typedef UInt32 OTServiceType;
+enum {
+ T_COTS = 1,
+ T_COTS_ORD = 2,
+ T_CLTS = 3,
+ T_TRANS = 5,
+ T_TRANS_ORD = 6,
+ T_TRANS_CLTS = 7
+};
+
+
+
+enum {
+ T_SENDZERO = 0x0001,
+ T_XPG4_1 = 0x0002,
+ T_CAN_SUPPORT_MDATA = 0x10000000,
+ T_CAN_RESOLVE_ADDR = 0x40000000,
+ T_CAN_SUPPLY_MIB = 0x20000000
+};
+
+
+
+
+
+
+enum {
+ T_INFINITE = -1,
+ T_INVALID = -2
+};
+
+
+typedef SInt32 OTDataSize;
+
+struct TEndpointInfo {
+ OTDataSize addr;
+ OTDataSize options;
+ OTDataSize tsdu;
+ OTDataSize etsdu;
+ OTDataSize connect;
+ OTDataSize discon;
+ OTServiceType servtype;
+ UInt32 flags;
+};
+typedef struct TEndpointInfo TEndpointInfo;
+typedef UInt32 OTPortRef;
+typedef OTPortRef * OTPortRefPtr;
+enum {
+ kOTInvalidPortRef = 0
+};
+
+
+
+typedef UInt8 OTBusType;
+enum {
+ kOTUnknownBusPort = 0,
+ kOTMotherboardBus = 1,
+ kOTNuBus = 2,
+ kOTPCIBus = 3,
+ kOTGeoPort = 4,
+ kOTPCCardBus = 5,
+ kOTFireWireBus = 6,
+ kOTLastBusIndex = 15
+};
+
+
+
+
+
+
+typedef UInt16 OTDeviceType;
+enum {
+ kOTNoDeviceType = 0,
+ kOTADEVDevice = 1,
+ kOTMDEVDevice = 2,
+ kOTLocalTalkDevice = 3,
+ kOTIRTalkDevice = 4,
+ kOTTokenRingDevice = 5,
+ kOTISDNDevice = 6,
+ kOTATMDevice = 7,
+ kOTSMDSDevice = 8,
+ kOTSerialDevice = 9,
+ kOTEthernetDevice = 10,
+ kOTSLIPDevice = 11,
+ kOTPPPDevice = 12,
+ kOTModemDevice = 13,
+ kOTFastEthernetDevice = 14,
+ kOTFDDIDevice = 15,
+ kOTIrDADevice = 16,
+ kOTATMSNAPDevice = 17,
+ kOTFibreChannelDevice = 18,
+ kOTFireWireDevice = 19,
+ kOTPseudoDevice = 1023,
+ kOTLastDeviceIndex = 1022
+};
+
+
+
+enum {
+ kOTLastSlotNumber = 255,
+ kOTLastOtherNumber = 255
+};
+
+typedef UInt16 OTSlotNumber;
+extern OTPortRef
+OTCreatePortRef(
+ OTBusType busType,
+ OTDeviceType devType,
+ OTSlotNumber slot,
+ UInt16 other) ;
+extern OTDeviceType
+OTGetDeviceTypeFromPortRef(OTPortRef ref) ;
+extern UInt16
+OTGetBusTypeFromPortRef(OTPortRef ref) ;
+extern OTSlotNumber
+OTGetSlotFromPortRef(
+ OTPortRef ref,
+ UInt16 * other) ;
+extern OTPortRef
+OTSetDeviceTypeInPortRef(
+ OTPortRef ref,
+ OTDeviceType devType) ;
+extern OTPortRef
+OTSetBusTypeInPortRef(
+ OTPortRef ref,
+ OTBusType busType) ;
+enum {
+ kMaxModuleNameLength = 31,
+ kMaxModuleNameSize = kMaxModuleNameLength + 1,
+ kMaxProviderNameLength = kMaxModuleNameLength + 4,
+ kMaxProviderNameSize = kMaxProviderNameLength + 1,
+ kMaxSlotIDLength = 7,
+ kMaxSlotIDSize = kMaxSlotIDLength + 1,
+ kMaxResourceInfoLength = 31,
+ kMaxResourceInfoSize = 32,
+ kMaxPortNameLength = kMaxModuleNameLength + 4,
+ kMaxPortNameSize = kMaxPortNameLength + 1
+};
+
+
+
+
+
+
+enum {
+ kOTPortIsActive = 0x00000001,
+ kOTPortIsDisabled = 0x00000002,
+ kOTPortIsUnavailable = 0x00000004,
+ kOTPortIsOffline = 0x00000008
+};
+
+
+
+enum {
+ kOTPortIsDLPI = 0x00000001,
+ kOTPortIsTPI = 0x00000002,
+ kOTPortCanYield = 0x00000004,
+ kOTPortCanArbitrate = 0x00000008,
+ kOTPortIsTransitory = 0x00000010,
+ kOTPortAutoConnects = 0x00000020,
+ kOTPortIsSystemRegistered = 0x00004000,
+ kOTPortIsPrivate = 0x00008000,
+ kOTPortIsAlias = (unsigned long)0x80000000
+};
+struct OTPortRecord {
+ OTPortRef fRef;
+ UInt32 fPortFlags;
+ UInt32 fInfoFlags;
+ UInt32 fCapabilities;
+ ItemCount fNumChildPorts;
+ OTPortRef * fChildPorts;
+ char fPortName[36];
+ char fModuleName[32];
+ char fSlotID[8];
+ char fResourceInfo[32];
+ char fReserved[164];
+};
+typedef struct OTPortRecord OTPortRecord;
+extern Boolean
+OTGetIndexedPort(
+ OTPortRecord * portRecord,
+ OTItemCount index) ;
+extern Boolean
+OTFindPort(
+ OTPortRecord * portRecord,
+ const char * portName) ;
+extern Boolean
+OTFindPortByRef(
+ OTPortRecord * portRecord,
+ OTPortRef ref) ;
+struct TNetbuf {
+ ByteCount maxlen;
+ ByteCount len;
+ UInt8 * buf;
+};
+typedef struct TNetbuf TNetbuf;
+struct strbuf {
+ SInt32 maxlen;
+ SInt32 len;
+ char * buf;
+};
+typedef struct strbuf strbuf;
+
+
+
+
+
+
+
+struct OTData {
+ void * fNext;
+ void * fData;
+ ByteCount fLen;
+};
+typedef struct OTData OTData;
+enum {
+ kNetbufDataIsOTData = (unsigned long)0xFFFFFFFE
+};
+struct OTBuffer {
+ void * fLink;
+ void * fLink2;
+ struct OTBuffer * fNext;
+ UInt8 * fData;
+ ByteCount fLen;
+ void * fSave;
+ UInt8 fBand;
+ UInt8 fType;
+ UInt8 fPad1;
+ UInt8 fFlags;
+};
+typedef struct OTBuffer OTBuffer;
+enum {
+ kOTNetbufDataIsOTBufferStar = (unsigned long)0xFFFFFFFD
+};
+
+
+
+
+
+
+struct OTBufferInfo {
+ OTBuffer * fBuffer;
+ ByteCount fOffset;
+ UInt8 fPad;
+};
+typedef struct OTBufferInfo OTBufferInfo;
+enum {
+ kOTNetbufIsRawMode = (unsigned long)0xFFFFFFFF
+};
+struct TBind {
+ TNetbuf addr;
+ OTQLen qlen;
+};
+typedef struct TBind TBind;
+
+
+
+
+struct TDiscon {
+ TNetbuf udata;
+ OTReason reason;
+ OTSequence sequence;
+};
+typedef struct TDiscon TDiscon;
+
+
+
+
+struct TCall {
+ TNetbuf addr;
+ TNetbuf opt;
+ TNetbuf udata;
+ OTSequence sequence;
+};
+typedef struct TCall TCall;
+
+struct TUnitData {
+ TNetbuf addr;
+ TNetbuf opt;
+ TNetbuf udata;
+};
+typedef struct TUnitData TUnitData;
+
+
+
+
+struct TUDErr {
+ TNetbuf addr;
+ TNetbuf opt;
+ SInt32 error;
+};
+typedef struct TUDErr TUDErr;
+
+struct TOptMgmt {
+ TNetbuf opt;
+ OTFlags flags;
+};
+typedef struct TOptMgmt TOptMgmt;
+struct TRequest {
+ TNetbuf data;
+ TNetbuf opt;
+ OTSequence sequence;
+};
+typedef struct TRequest TRequest;
+
+struct TReply {
+ TNetbuf data;
+ TNetbuf opt;
+ OTSequence sequence;
+};
+typedef struct TReply TReply;
+
+
+
+
+struct TUnitRequest {
+ TNetbuf addr;
+ TNetbuf opt;
+ TNetbuf udata;
+ OTSequence sequence;
+};
+typedef struct TUnitRequest TUnitRequest;
+
+struct TUnitReply {
+ TNetbuf opt;
+ TNetbuf udata;
+ OTSequence sequence;
+};
+typedef struct TUnitReply TUnitReply;
+
+
+
+
+
+
+
+struct TRegisterRequest {
+ TNetbuf name;
+ TNetbuf addr;
+ OTFlags flags;
+};
+typedef struct TRegisterRequest TRegisterRequest;
+
+
+
+
+struct TRegisterReply {
+ TNetbuf addr;
+ OTNameID nameid;
+};
+typedef struct TRegisterReply TRegisterReply;
+
+struct TLookupRequest {
+ TNetbuf name;
+ TNetbuf addr;
+ UInt32 maxcnt;
+ OTTimeout timeout;
+ OTFlags flags;
+};
+typedef struct TLookupRequest TLookupRequest;
+
+
+
+
+struct TLookupReply {
+ TNetbuf names;
+ UInt32 rspcount;
+};
+typedef struct TLookupReply TLookupReply;
+
+
+
+
+struct TLookupBuffer {
+ UInt16 fAddressLength;
+ UInt16 fNameLength;
+ UInt8 fAddressBuffer[1];
+};
+typedef struct TLookupBuffer TLookupBuffer;
+typedef struct OpaqueOTClientContextPtr* OTClientContextPtr;
+typedef UInt32 OTInitializationFlags;
+enum {
+ kInitOTForApplicationMask = 1,
+ kInitOTForExtensionMask = 2
+};
+extern OSStatus
+InitOpenTransportInContext(
+ OTInitializationFlags flags,
+ OTClientContextPtr * outClientContext) ;
+extern void
+CloseOpenTransportInContext(OTClientContextPtr clientContext) ;
+extern OSStatus
+OTRegisterAsClientInContext(
+ OTClientName name,
+ OTNotifyUPP proc,
+ OTClientContextPtr clientContext) ;
+extern OSStatus
+OTUnregisterAsClientInContext(OTClientContextPtr clientContext) ;
+typedef void ( * OTProcessProcPtr)(void * arg);
+typedef OTProcessProcPtr OTProcessUPP;
+extern OTProcessUPP
+NewOTProcessUPP(OTProcessProcPtr userRoutine) ;
+extern void
+DisposeOTProcessUPP(OTProcessUPP userUPP) ;
+extern void
+InvokeOTProcessUPP(
+ void * arg,
+ OTProcessUPP userUPP) ;
+extern long
+OTCreateDeferredTaskInContext(
+ OTProcessUPP upp,
+ void * arg,
+ OTClientContextPtr clientContext) ;
+typedef long OTDeferredTaskRef;
+extern Boolean
+OTScheduleDeferredTask(OTDeferredTaskRef dtCookie) ;
+extern OSStatus
+OTDestroyDeferredTask(OTDeferredTaskRef dtCookie) ;
+typedef long OTSystemTaskRef;
+extern Boolean
+OTCanMakeSyncCall(void) ;
+extern OSStatus
+OTCloseProvider(ProviderRef ref) ;
+extern SInt32
+OTIoctl(
+ ProviderRef ref,
+ UInt32 cmd,
+ void * data) ;
+extern OSStatus
+OTSetAsynchronous(ProviderRef ref) ;
+extern OSStatus
+OTSetSynchronous(ProviderRef ref) ;
+extern Boolean
+OTIsSynchronous(ProviderRef ref) ;
+extern OSStatus
+OTSetBlocking(ProviderRef ref) ;
+extern OSStatus
+OTSetNonBlocking(ProviderRef ref) ;
+extern Boolean
+OTIsBlocking(ProviderRef ref) ;
+extern OSStatus
+OTInstallNotifier(
+ ProviderRef ref,
+ OTNotifyUPP proc,
+ void * contextPtr) ;
+extern OSStatus
+OTUseSyncIdleEvents(
+ ProviderRef ref,
+ Boolean useEvents) ;
+extern void
+OTRemoveNotifier(ProviderRef ref) ;
+extern void
+OTLeaveNotifier(ProviderRef ref) ;
+extern Boolean
+OTEnterNotifier(ProviderRef ref) ;
+extern OSStatus
+OTAckSends(ProviderRef ref) ;
+extern OSStatus
+OTDontAckSends(ProviderRef ref) ;
+extern Boolean
+OTIsAckingSends(ProviderRef ref) ;
+extern OSStatus
+OTCancelSynchronousCalls(
+ ProviderRef ref,
+ OSStatus err) ;
+extern EndpointRef
+OTOpenEndpointInContext(
+ OTConfigurationRef config,
+ OTOpenFlags oflag,
+ TEndpointInfo * info,
+ OSStatus * err,
+ OTClientContextPtr clientContext) ;
+extern OSStatus
+OTAsyncOpenEndpointInContext(
+ OTConfigurationRef config,
+ OTOpenFlags oflag,
+ TEndpointInfo * info,
+ OTNotifyUPP upp,
+ void * contextPtr,
+ OTClientContextPtr clientContext) ;
+extern OSStatus
+OTGetEndpointInfo(
+ EndpointRef ref,
+ TEndpointInfo * info) ;
+extern OTResult
+OTGetEndpointState(EndpointRef ref) ;
+extern OTResult
+OTLook(EndpointRef ref) ;
+extern OTResult
+OTCountDataBytes(
+ EndpointRef ref,
+ OTByteCount * countPtr) ;
+extern OSStatus
+OTGetProtAddress(
+ EndpointRef ref,
+ TBind * boundAddr,
+ TBind * peerAddr) ;
+extern OSStatus
+OTResolveAddress(
+ EndpointRef ref,
+ TBind * reqAddr,
+ TBind * retAddr,
+ OTTimeout timeOut) ;
+extern void *
+OTAllocInContext(
+ EndpointRef ref,
+ OTStructType structType,
+ UInt32 fields,
+ OSStatus * err,
+ OTClientContextPtr clientContext) ;
+extern OTResult
+OTFree(
+ void * ptr,
+ OTStructType structType) ;
+extern OSStatus
+OTOptionManagement(
+ EndpointRef ref,
+ TOptMgmt * req,
+ TOptMgmt * ret) ;
+extern OSStatus
+OTNextOption(
+ UInt8 * buffer,
+ UInt32 buflen,
+ TOption ** prevOptPtr) ;
+extern TOption *
+OTFindOption(
+ UInt8 * buffer,
+ UInt32 buflen,
+ OTXTILevel level,
+ OTXTIName name) ;
+extern OSStatus
+OTBind(
+ EndpointRef ref,
+ TBind * reqAddr,
+ TBind * retAddr) ;
+extern OSStatus
+OTUnbind(EndpointRef ref) ;
+extern OSStatus
+OTConnect(
+ EndpointRef ref,
+ TCall * sndCall,
+ TCall * rcvCall) ;
+extern OSStatus
+OTRcvConnect(
+ EndpointRef ref,
+ TCall * call) ;
+extern OSStatus
+OTListen(
+ EndpointRef ref,
+ TCall * call) ;
+extern OSStatus
+OTAccept(
+ EndpointRef listener,
+ EndpointRef worker,
+ TCall * call) ;
+extern OSStatus
+OTSndDisconnect(
+ EndpointRef ref,
+ TCall * call) ;
+extern OSStatus
+OTSndOrderlyDisconnect(EndpointRef ref) ;
+extern OSStatus
+OTRcvDisconnect(
+ EndpointRef ref,
+ TDiscon * discon) ;
+extern OSStatus
+OTRcvOrderlyDisconnect(EndpointRef ref) ;
+extern OTResult
+OTRcv(
+ EndpointRef ref,
+ void * buf,
+ OTByteCount nbytes,
+ OTFlags * flags) ;
+extern OTResult
+OTSnd(
+ EndpointRef ref,
+ void * buf,
+ OTByteCount nbytes,
+ OTFlags flags) ;
+extern OSStatus
+OTSndUData(
+ EndpointRef ref,
+ TUnitData * udata) ;
+extern OSStatus
+OTRcvUData(
+ EndpointRef ref,
+ TUnitData * udata,
+ OTFlags * flags) ;
+extern OSStatus
+OTRcvUDErr(
+ EndpointRef ref,
+ TUDErr * uderr) ;
+extern OSStatus
+OTAsyncOpenMapperInContext(
+ OTConfigurationRef config,
+ OTOpenFlags oflag,
+ OTNotifyUPP upp,
+ void * contextPtr,
+ OTClientContextPtr clientContext) ;
+extern MapperRef
+OTOpenMapperInContext(
+ OTConfigurationRef config,
+ OTOpenFlags oflag,
+ OSStatus * err,
+ OTClientContextPtr clientContext) ;
+extern OSStatus
+OTRegisterName(
+ MapperRef ref,
+ TRegisterRequest * req,
+ TRegisterReply * reply) ;
+extern OSStatus
+OTDeleteName(
+ MapperRef ref,
+ TNetbuf * name) ;
+extern OSStatus
+OTDeleteNameByID(
+ MapperRef ref,
+ OTNameID nameID) ;
+extern OSStatus
+OTLookupName(
+ MapperRef ref,
+ TLookupRequest * req,
+ TLookupReply * reply) ;
+extern OTConfigurationRef
+OTCreateConfiguration(const char * path) ;
+extern OTConfigurationRef
+OTCloneConfiguration(OTConfigurationRef cfig) ;
+extern void
+OTDestroyConfiguration(OTConfigurationRef cfig) ;
+extern void *
+OTAllocMemInContext(
+ OTByteCount size,
+ OTClientContextPtr clientContext) ;
+extern void
+OTFreeMem(void * mem) ;
+extern void
+OTDelay(UInt32 seconds) ;
+extern void
+OTIdle(void) ;
+extern void
+OTMemcpy(
+ void * dest,
+ const void * src,
+ OTByteCount nBytes) ;
+extern Boolean
+OTMemcmp(
+ const void * mem1,
+ const void * mem2,
+ OTByteCount nBytes) ;
+extern void
+OTMemmove(
+ void * dest,
+ const void * src,
+ OTByteCount nBytes) ;
+extern void
+OTMemzero(
+ void * dest,
+ OTByteCount nBytes) ;
+extern void
+OTMemset(
+ void * dest,
+ OTUInt8Param toSet,
+ OTByteCount nBytes) ;
+extern OTByteCount
+OTStrLength(const char * str) ;
+extern void
+OTStrCopy(
+ char * dest,
+ const char * src) ;
+extern void
+OTStrCat(
+ char * dest,
+ const char * src) ;
+extern Boolean
+OTStrEqual(
+ const char * src1,
+ const char * src2) ;
+typedef UnsignedWide OTTimeStamp;
+extern void
+OTGetTimeStamp(OTTimeStamp * currentTime) ;
+extern OTTimeStamp *
+OTSubtractTimeStamps(
+ OTTimeStamp * result,
+ OTTimeStamp * startTime,
+ OTTimeStamp * endEnd) ;
+extern UInt32
+OTTimeStampInMilliseconds(OTTimeStamp * delta) ;
+extern UInt32
+OTTimeStampInMicroseconds(OTTimeStamp * delta) ;
+extern UInt32
+OTElapsedMilliseconds(OTTimeStamp * startTime) ;
+extern UInt32
+OTElapsedMicroseconds(OTTimeStamp * startTime) ;
+extern UInt32
+OTGetClockTimeInSecs(void) ;
+struct OTLink {
+ struct OTLink * fNext;
+
+
+
+
+
+ void Init() { fNext = __null; }
+
+
+
+};
+typedef struct OTLink OTLink;
+struct OTLIFO {
+ OTLink * fHead;
+
+
+
+
+
+ void Init();
+ void Enqueue(OTLink* link);
+ OTLink* Dequeue();
+ OTLink* StealList();
+ Boolean IsEmpty();
+
+
+
+};
+typedef struct OTLIFO OTLIFO;
+extern void
+OTLIFOEnqueue(
+ OTLIFO * list,
+ OTLink * link) ;
+extern OTLink *
+OTLIFODequeue(OTLIFO * list) ;
+extern OTLink *
+OTLIFOStealList(OTLIFO * list) ;
+extern OTLink *
+OTReverseList(OTLink * list) ;
+
+
+
+
+
+
+
+ inline void OTLIFO::Init() { fHead = __null; }
+ inline void OTLIFO::Enqueue(OTLink* link) { OTLIFOEnqueue(this, link); }
+ inline OTLink* OTLIFO::Dequeue() { return OTLIFODequeue(this); }
+ inline OTLink* OTLIFO::StealList() { return OTLIFOStealList(this); }
+ inline Boolean OTLIFO::IsEmpty() { return fHead == __null; }
+typedef Boolean ( * OTListSearchProcPtr)(const void *ref, OTLink *linkToCheck);
+typedef OTListSearchProcPtr OTListSearchUPP;
+extern OTListSearchUPP
+NewOTListSearchUPP(OTListSearchProcPtr userRoutine) ;
+extern void
+DisposeOTListSearchUPP(OTListSearchUPP userUPP) ;
+extern Boolean
+InvokeOTListSearchUPP(
+ const void * ref,
+ OTLink * linkToCheck,
+ OTListSearchUPP userUPP) ;
+
+struct OTList {
+ OTLink * fHead;
+
+
+
+
+ void Init();
+ Boolean IsEmpty();
+ void AddFirst(OTLink* link);
+ void AddLast(OTLink* link);
+ OTLink* GetFirst();
+ OTLink* GetLast();
+ OTLink* RemoveFirst();
+ OTLink* RemoveLast();
+ Boolean IsInList(OTLink* link);
+ OTLink* FindLink(OTListSearchUPP proc, const void* ref);
+ Boolean RemoveLink(OTLink* link);
+ OTLink* FindAndRemoveLink(OTListSearchUPP proc, const void* ref);
+ OTLink* GetIndexedLink(OTItemCount index);
+
+
+
+};
+typedef struct OTList OTList;
+extern void
+OTAddFirst(
+ OTList * list,
+ OTLink * link) ;
+extern void
+OTAddLast(
+ OTList * list,
+ OTLink * link) ;
+extern OTLink *
+OTRemoveFirst(OTList * list) ;
+extern OTLink *
+OTRemoveLast(OTList * list) ;
+extern OTLink *
+OTGetFirst(OTList * list) ;
+extern OTLink *
+OTGetLast(OTList * list) ;
+extern Boolean
+OTIsInList(
+ OTList * list,
+ OTLink * link) ;
+extern OTLink *
+OTFindLink(
+ OTList * list,
+ OTListSearchUPP proc,
+ const void * ref) ;
+extern Boolean
+OTRemoveLink(
+ OTList * list,
+ OTLink * link) ;
+extern OTLink *
+OTFindAndRemoveLink(
+ OTList * list,
+ OTListSearchUPP proc,
+ const void * ref) ;
+extern OTLink *
+OTGetIndexedLink(
+ OTList * list,
+ OTItemCount index) ;
+extern void
+OTEnqueue(
+ void ** listHead,
+ void * object,
+ OTByteCount linkOffset) ;
+extern void *
+OTDequeue(
+ void ** listHead,
+ OTByteCount linkOffset) ;
+
+
+
+
+
+
+ inline void OTList::Init() { fHead = __null; }
+ inline Boolean OTList::IsEmpty() { return fHead == __null; }
+ inline void OTList::AddFirst(OTLink* link) { OTAddFirst(this, link); }
+ inline void OTList::AddLast(OTLink* link) { OTAddLast(this, link); }
+ inline OTLink* OTList::GetFirst() { return OTGetFirst(this); }
+ inline OTLink* OTList::GetLast() { return OTGetLast(this); }
+ inline OTLink* OTList::RemoveFirst() { return OTRemoveFirst(this); }
+ inline OTLink* OTList::RemoveLast() { return OTRemoveLast(this); }
+ inline Boolean OTList::IsInList(OTLink* link) { return OTIsInList(this, link); }
+ inline OTLink* OTList::FindLink(OTListSearchUPP proc, const void* ref)
+ { return OTFindLink(this, proc, ref); }
+ inline Boolean OTList::RemoveLink(OTLink* link) { return OTRemoveLink(this, link); }
+ inline OTLink* OTList::FindAndRemoveLink(OTListSearchUPP proc, const void* ref)
+ { return OTFindAndRemoveLink(this, proc, ref); }
+ inline OTLink* OTList::GetIndexedLink(OTItemCount index)
+ { return OTGetIndexedLink(this, index); }
+extern Boolean
+OTAtomicSetBit(
+ UInt8 * bytePtr,
+ OTByteCount bitNumber) ;
+extern Boolean
+OTAtomicClearBit(
+ UInt8 * bytePtr,
+ OTByteCount bitNumber) ;
+extern Boolean
+OTAtomicTestBit(
+ UInt8 * bytePtr,
+ OTByteCount bitNumber) ;
+extern Boolean
+OTCompareAndSwapPtr(
+ void * oldValue,
+ void * newValue,
+ void ** dest) ;
+extern Boolean
+OTCompareAndSwap32(
+ UInt32 oldValue,
+ UInt32 newValue,
+ UInt32 * dest) ;
+extern Boolean
+OTCompareAndSwap16(
+ UInt32 oldValue,
+ UInt32 newValue,
+ UInt16 * dest) ;
+extern Boolean
+OTCompareAndSwap8(
+ UInt32 oldValue,
+ UInt32 newValue,
+ UInt8 * dest) ;
+extern SInt32
+OTAtomicAdd32(
+ SInt32 toAdd,
+ SInt32 * dest) ;
+extern SInt16
+OTAtomicAdd16(
+ SInt32 toAdd,
+ SInt16 * dest) ;
+extern SInt8
+OTAtomicAdd8(
+ SInt32 toAdd,
+ SInt8 * dest) ;
+
+
+
+
+
+
+typedef UInt8 OTLock;
+}
+class TProvider
+{
+ private:
+ void* operator new(size_t);
+ void operator delete(void*) {}
+
+
+
+
+
+ public:
+ OSStatus Close() { return OTCloseProvider(this); }
+
+ OSStatus SetNonBlocking() { return OTSetNonBlocking(this); }
+ OSStatus SetBlocking() { return OTSetBlocking(this); }
+ Boolean IsBlocking() { return OTIsBlocking(this); }
+ Boolean IsNonBlocking() { return !OTIsBlocking(this); }
+ OSStatus SetSynchronous() { return OTSetSynchronous(this); }
+ OSStatus SetAsynchronous() { return OTSetAsynchronous(this); }
+ Boolean IsSynchronous() { return OTIsSynchronous(this); }
+ Boolean IsAsynchronous() { return !OTIsSynchronous(this); }
+
+ OSStatus AckSends() { return OTAckSends(this); }
+ OSStatus DontAckSends() { return OTDontAckSends(this); }
+ Boolean IsAckingSends() { return OTIsAckingSends(this); }
+
+ void CancelSynchronousCalls(OSStatus err)
+ { (void)OTCancelSynchronousCalls(this, err); }
+
+ OSStatus InstallNotifier(OTNotifyUPP proc, void* ptr)
+ { return OTInstallNotifier(this, proc, ptr); }
+
+ OSStatus UseSyncIdleEvents()
+ { return OTUseSyncIdleEvents(this, true); }
+
+ OSStatus DontUseSyncIdleEvents()
+ { return OTUseSyncIdleEvents(this, false); }
+
+ void RemoveNotifier()
+ { OTRemoveNotifier(this); }
+
+ Boolean EnterNotifier()
+ { return OTEnterNotifier(this); }
+
+ void LeaveNotifier()
+ { OTLeaveNotifier(this); }
+ SInt32 Ioctl(UInt32 cmd, void* data)
+ { return OTIoctl(this, cmd, data); }
+ SInt32 Ioctl(UInt32 cmd, long data)
+ { return OTIoctl(this, cmd, (void*)data); }
+ public:
+ void* fData;
+};
+class TEndpoint : public TProvider
+{
+ public:
+
+
+
+ OSStatus GetEndpointInfo(TEndpointInfo* info)
+ { return OTGetEndpointInfo(this, info); }
+
+ OSStatus GetProtAddress(TBind* boundAddr, TBind* peerAddr)
+ { return OTGetProtAddress(this, boundAddr, peerAddr); }
+
+ OSStatus ResolveAddress(TBind* reqAddr, TBind* retAddr, OTTimeout timeout)
+ { return OTResolveAddress(this, reqAddr, retAddr, timeout); }
+
+ OTResult GetEndpointState()
+ { return OTGetEndpointState(this); }
+
+ OTResult Look()
+ { return OTLook(this); }
+ void* AllocInContext(OTStructType structType, UInt32 fields, OSStatus* err = __null, OTClientContextPtr clientContext = __null)
+ { return OTAllocInContext(this, structType, fields, err, clientContext); }
+
+ void* Alloc(OTStructType structType, UInt32 fields, OSStatus* err = __null)
+ {
+
+ return OTAllocInContext(this, structType, fields, err, __null);
+
+
+
+ };
+
+ OTResult Free(void* ptr, OTStructType structType)
+ { return OTFree(ptr, structType); }
+
+
+
+ OSStatus OptionManagement(TOptMgmt* req, TOptMgmt* ret)
+ { return OTOptionManagement(this, req, ret); }
+
+
+
+ OSStatus Bind(TBind* reqAddr, TBind* retAddr)
+ { return OTBind(this, reqAddr, retAddr); }
+
+ OSStatus Unbind()
+ { return OTUnbind(this); }
+
+
+
+ OSStatus Connect(TCall* sndCall, TCall* rcvCall)
+ { return OTConnect(this, sndCall, rcvCall); }
+
+ OSStatus RcvConnect(TCall* call)
+ { return OTRcvConnect(this, call); }
+
+ OSStatus Listen(TCall* call)
+ { return OTListen(this, call); }
+
+ OSStatus Accept(EndpointRef resRef, TCall* call)
+ { return OTAccept(this, resRef, call); }
+
+ OSStatus SndDisconnect(TCall* call)
+ { return OTSndDisconnect(this, call); }
+
+ OSStatus SndOrderlyDisconnect()
+ { return OTSndOrderlyDisconnect(this); }
+
+ OSStatus RcvDisconnect(TDiscon* discon)
+ { return OTRcvDisconnect(this, discon); }
+
+ OSStatus RcvOrderlyDisconnect()
+ { return OTRcvOrderlyDisconnect(this); }
+
+
+
+ OTResult Snd(void* buf, OTByteCount nbytes, OTFlags flags)
+ { return OTSnd(this, buf, nbytes, flags); }
+
+ OTResult Rcv(void* buf, OTByteCount nbytes, OTFlags* flagP)
+ { return OTRcv(this, buf, nbytes, flagP); }
+
+
+
+ OSStatus SndUData(TUnitData* udata)
+ { return OTSndUData(this, udata); }
+
+ OSStatus RcvUData(TUnitData* udata, OTFlags* flagP)
+ { return OTRcvUData(this, udata, flagP); }
+
+ OSStatus RcvUDErr(TUDErr* uderr)
+ { return OTRcvUDErr(this, uderr); }
+ OTResult CountDataBytes(OTByteCount* countPtr)
+ { return OTCountDataBytes(this, countPtr); }
+};
+
+
+
+
+
+
+
+class TMapper : public TProvider
+{
+ public:
+ OSStatus RegisterName(TRegisterRequest* req, TRegisterReply* reply)
+ { return OTRegisterName(this, req, reply); }
+
+ OSStatus DeleteName(TNetbuf* name)
+ { return OTDeleteName(this, name); }
+
+ OSStatus DeleteName(OTNameID theID)
+ { return OTDeleteNameByID(this, theID); }
+
+ OSStatus LookupName(TLookupRequest* req, TLookupReply* reply)
+ { return OTLookupName(this, req, reply); }
+};
+
+
+
+extern "C" {
+
+
+}
+extern "C" {
+
+
+typedef UInt16 InetPort;
+typedef UInt32 InetHost;
+
+
+enum {
+ AF_DNS = 42
+};
+
+
+
+
+
+
+
+enum {
+ kOTAnyInetAddress = 0
+};
+ typedef class TInternetServices* InetSvcRef;
+enum {
+ INET_IP = 0x00,
+ INET_TCP = 0x06,
+ INET_UDP = 0x11
+};
+
+
+
+enum {
+ TCP_NODELAY = 0x01,
+ TCP_MAXSEG = 0x02,
+ TCP_NOTIFY_THRESHOLD = 0x10,
+ TCP_ABORT_THRESHOLD = 0x11,
+ TCP_CONN_NOTIFY_THRESHOLD = 0x12,
+ TCP_CONN_ABORT_THRESHOLD = 0x13,
+ TCP_OOBINLINE = 0x14,
+ TCP_URGENT_PTR_TYPE = 0x15,
+ TCP_KEEPALIVE = 0x0008
+};
+enum {
+ T_GARBAGE = 2
+};
+
+
+
+enum {
+ UDP_CHECKSUM = 0x0600,
+ UDP_RX_ICMP = 0x02
+};
+enum {
+ kIP_OPTIONS = 0x01,
+ kIP_TOS = 0x02,
+ kIP_TTL = 0x03,
+ kIP_REUSEADDR = 0x04,
+ kIP_DONTROUTE = 0x10,
+ kIP_BROADCAST = 0x20,
+ kIP_REUSEPORT = 0x0200,
+ kIP_HDRINCL = 0x1002,
+ kIP_RCVOPTS = 0x1005,
+ kIP_RCVDSTADDR = 0x1007,
+ kIP_MULTICAST_IF = 0x1010,
+ kIP_MULTICAST_TTL = 0x1011,
+ kIP_MULTICAST_LOOP = 0x1012,
+ kIP_ADD_MEMBERSHIP = 0x1013,
+ kIP_DROP_MEMBERSHIP = 0x1014,
+ kIP_BROADCAST_IFNAME = 0x1015,
+ kIP_RCVIFADDR = 0x1016
+};
+
+
+
+
+
+
+
+enum {
+ DVMRP_INIT = 100,
+ DVMRP_DONE = 101,
+ DVMRP_ADD_VIF = 102,
+ DVMRP_DEL_VIF = 103,
+ DVMRP_ADD_LGRP = 104,
+ DVMRP_DEL_LGRP = 105,
+ DVMRP_ADD_MRT = 106,
+ DVMRP_DEL_MRT = 107
+};
+
+
+
+
+enum {
+ T_ROUTINE = 0,
+ T_PRIORITY = 1,
+ T_IMMEDIATE = 2,
+ T_FLASH = 3,
+ T_OVERRIDEFLASH = 4,
+ T_CRITIC_ECP = 5,
+ T_INETCONTROL = 6,
+ T_NETCONTROL = 7
+};
+
+
+
+enum {
+ T_NOTOS = 0x00,
+ T_LDELAY = (1 << 4),
+ T_HITHRPT = (1 << 3),
+ T_HIREL = (1 << 2)
+};
+
+
+
+
+struct TIPAddMulticast {
+ InetHost multicastGroupAddress;
+ InetHost interfaceAddress;
+};
+typedef struct TIPAddMulticast TIPAddMulticast;
+
+enum {
+ T_DNRSTRINGTOADDRCOMPLETE = kPRIVATEEVENT + 1,
+ T_DNRADDRTONAMECOMPLETE = kPRIVATEEVENT + 2,
+ T_DNRSYSINFOCOMPLETE = kPRIVATEEVENT + 3,
+ T_DNRMAILEXCHANGECOMPLETE = kPRIVATEEVENT + 4,
+ T_DNRQUERYCOMPLETE = kPRIVATEEVENT + 5
+};
+
+
+
+struct InetAddress {
+ OTAddressType fAddressType;
+ InetPort fPort;
+ InetHost fHost;
+ UInt8 fUnused[8];
+};
+typedef struct InetAddress InetAddress;
+
+enum {
+ kMaxHostAddrs = 10,
+ kMaxSysStringLen = 32,
+ kMaxHostNameLen = 255
+};
+
+
+typedef char InetDomainName[256];
+struct InetHostInfo {
+ InetDomainName name;
+ InetHost addrs[10];
+};
+typedef struct InetHostInfo InetHostInfo;
+struct InetSysInfo {
+ char cpuType[32];
+ char osType[32];
+};
+typedef struct InetSysInfo InetSysInfo;
+struct InetMailExchange {
+ UInt16 preference;
+ InetDomainName exchange;
+};
+typedef struct InetMailExchange InetMailExchange;
+struct DNSQueryInfo {
+ UInt16 qType;
+ UInt16 qClass;
+ UInt32 ttl;
+ InetDomainName name;
+ UInt16 responseType;
+ UInt16 resourceLen;
+ char resourceData[4];
+};
+typedef struct DNSQueryInfo DNSQueryInfo;
+struct DNSAddress {
+ OTAddressType fAddressType;
+ InetDomainName fName;
+};
+typedef struct DNSAddress DNSAddress;
+
+enum {
+ kDefaultInetInterface = -1
+};
+
+enum {
+ kInetInterfaceInfoVersion = 3
+};
+
+struct InetInterfaceInfo {
+ InetHost fAddress;
+ InetHost fNetmask;
+ InetHost fBroadcastAddr;
+ InetHost fDefaultGatewayAddr;
+ InetHost fDNSAddr;
+ UInt16 fVersion;
+ UInt16 fHWAddrLen;
+ UInt8 * fHWAddr;
+ UInt32 fIfMTU;
+ UInt8 * fReservedPtrs[2];
+ InetDomainName fDomainName;
+ UInt32 fIPSecondaryCount;
+ UInt8 fReserved[252];
+};
+typedef struct InetInterfaceInfo InetInterfaceInfo;
+
+enum {
+ kAllDHCPOptions = -1,
+ kDHCPLongOption = 126,
+ kDHCPLongOptionReq = 127
+};
+
+struct InetDHCPOption {
+ UInt8 fOptionTag;
+ UInt8 fOptionLen;
+ UInt8 fOptionValue;
+};
+typedef struct InetDHCPOption InetDHCPOption;
+extern void
+OTInitInetAddress(
+ InetAddress * addr,
+ InetPort port,
+ InetHost host) ;
+extern OTByteCount
+OTInitDNSAddress(
+ DNSAddress * addr,
+ char * str) ;
+extern OSStatus
+OTInetStringToHost(
+ const char * str,
+ InetHost * host) ;
+extern void
+OTInetHostToString(
+ InetHost host,
+ char * str) ;
+extern OSStatus
+OTInetGetInterfaceInfo(
+ InetInterfaceInfo * info,
+ SInt32 val) ;
+extern OSStatus
+OTInetGetSecondaryAddresses(
+ InetHost * addr,
+ UInt32 * count,
+ SInt32 val) ;
+extern InetSvcRef
+OTOpenInternetServicesInContext(
+ OTConfigurationRef cfig,
+ OTOpenFlags oflag,
+ OSStatus * err,
+ OTClientContextPtr clientContext) ;
+extern OSStatus
+OTAsyncOpenInternetServicesInContext(
+ OTConfigurationRef cfig,
+ OTOpenFlags oflag,
+ OTNotifyUPP upp,
+ void * contextPtr,
+ OTClientContextPtr clientContext) ;
+extern OSStatus
+OTInetStringToAddress(
+ InetSvcRef ref,
+ char * name,
+ InetHostInfo * hinfo) ;
+extern OSStatus
+OTInetAddressToName(
+ InetSvcRef ref,
+ InetHost addr,
+ InetDomainName name) ;
+extern OSStatus
+OTInetSysInfo(
+ InetSvcRef ref,
+ char * name,
+ InetSysInfo * sysinfo) ;
+extern OSStatus
+OTInetMailExchange(
+ InetSvcRef ref,
+ char * name,
+ UInt16 * num,
+ InetMailExchange * mx) ;
+extern OSStatus
+OTInetQuery(
+ InetSvcRef ref,
+ char * name,
+ UInt16 qClass,
+ UInt16 qType,
+ char * buf,
+ OTByteCount buflen,
+ void ** argv,
+ OTByteCount argvlen,
+ OTFlags flags) ;
+
+
+
+}
+
+class TInternetServices : public TProvider
+{
+ public:
+ OSStatus StringToAddress(char* name, InetHostInfo* hinfo)
+ { return OTInetStringToAddress(this, name, hinfo); }
+
+ OSStatus AddressToName(InetHost addr, InetDomainName name)
+ { return OTInetAddressToName(this, addr, name); }
+
+ OSStatus SysInfo(char* name, InetSysInfo* sysinfo )
+ { return OTInetSysInfo(this, name, sysinfo); }
+
+ OSStatus MailExchange(char* name, UInt16* num, InetMailExchange* mx)
+ { return OTInetMailExchange(this, name, num, mx); }
+
+ OSStatus Query(char* name, UInt16 qClass, UInt16 qType,
+ char* buf, OTByteCount buflen,
+ void** argv, OTByteCount argvlen,
+ OTFlags flags)
+ { return OTInetQuery(this, name, qClass, qType, buf, buflen, argv, argvlen, flags); }
+};
+
+extern "C" {
+enum {
+ ATK_DDP = 'DDP ',
+ ATK_AARP = 'AARP',
+ ATK_ATP = 'ATP ',
+ ATK_ADSP = 'ADSP',
+ ATK_ASP = 'ASP ',
+ ATK_PAP = 'PAP ',
+ ATK_NBP = 'NBP ',
+ ATK_ZIP = 'ZIP '
+};
+enum {
+ DDP_OPT_HOPCOUNT = 0x2100
+};
+
+enum {
+ DDP_OPT_CHECKSUM = 0x0600,
+ DDP_OPT_SRCADDR = 0x2101,
+ ATP_OPT_REPLYCNT = 0x2110,
+ ATP_OPT_DATALEN = 0x2111,
+ ATP_OPT_RELTIMER = 0x2112,
+ ATP_OPT_TRANID = 0x2113,
+ PAP_OPT_OPENRETRY = 0x2120
+};
+enum {
+ kAppleTalkEvent = kPROTOCOLEVENT | 0x00010000,
+ T_GETMYZONECOMPLETE = kAppleTalkEvent + 1,
+ T_GETLOCALZONESCOMPLETE = kAppleTalkEvent + 2,
+ T_GETZONELISTCOMPLETE = kAppleTalkEvent + 3,
+ T_GETATALKINFOCOMPLETE = kAppleTalkEvent + 4,
+ T_ATALKROUTERDOWNEVENT = kAppleTalkEvent + 51,
+ T_ATALKROUTERUPEVENT = kAppleTalkEvent + 52,
+ T_ATALKZONENAMECHANGEDEVENT = kAppleTalkEvent + 53,
+ T_ATALKCONNECTIVITYCHANGEDEVENT = kAppleTalkEvent + 54,
+ T_ATALKINTERNETAVAILABLEEVENT = kAppleTalkEvent + 55,
+ T_ATALKCABLERANGECHANGEDEVENT = kAppleTalkEvent + 56
+};
+
+enum {
+ T_ATALKBADROUTEREVENT = kAppleTalkEvent + 70,
+ T_ALLNODESTAKENEVENT = kAppleTalkEvent + 71,
+ T_FIXEDNODETAKENEVENT = kAppleTalkEvent + 72,
+ T_MPPCOMPATCFIGEVENT = kAppleTalkEvent + 73,
+ T_FIXEDNODEBADEVENT = kAppleTalkEvent + 74
+};
+
+enum {
+ kAllATalkRoutersDown = 0,
+ kLocalATalkRoutersDown = -1L,
+ kARARouterDisconnected = -2L
+};
+
+enum {
+ kARARouterOnline = -1L,
+ kATalkRouterOnline = 0,
+ kLocalATalkRouterOnline = -2L
+};
+
+
+
+
+enum {
+ ATALK_IOC_FULLSELFSEND = ((MIOC_ATALK << 8) | 47),
+ ADSP_IOC_FORWARDRESET = ((MIOC_ATALK << 8) | 60)
+};
+
+
+
+
+
+enum {
+ kECHO_TSDU = 585
+};
+
+
+
+enum {
+ kNBPMaxNameLength = 32,
+ kNBPMaxTypeLength = 32,
+ kNBPMaxZoneLength = 32,
+ kNBPSlushLength = 9,
+ kNBPMaxEntityLength = (kNBPMaxNameLength + kNBPMaxTypeLength + kNBPMaxZoneLength + 3),
+ kNBPEntityBufferSize = (kNBPMaxNameLength + kNBPMaxTypeLength + kNBPMaxZoneLength + kNBPSlushLength),
+ kNBPWildCard = 0x3D,
+ kNBPImbeddedWildCard = 0xC5,
+ kNBPDefaultZone = 0x2A
+};
+
+
+
+enum {
+ kZIPMaxZoneLength = kNBPMaxZoneLength
+};
+
+enum {
+ kDDPAddressLength = 8,
+ kNBPAddressLength = kNBPEntityBufferSize,
+ kAppleTalkAddressLength = kDDPAddressLength + kNBPEntityBufferSize
+};
+ typedef class TAppleTalkServices* ATSvcRef;
+extern OSStatus
+OTAsyncOpenAppleTalkServicesInContext(
+ OTConfigurationRef cfig,
+ OTOpenFlags flags,
+ OTNotifyUPP proc,
+ void * contextPtr,
+ OTClientContextPtr clientContext) ;
+extern ATSvcRef
+OTOpenAppleTalkServicesInContext(
+ OTConfigurationRef cfig,
+ OTOpenFlags flags,
+ OSStatus * err,
+ OTClientContextPtr clientContext) ;
+extern OSStatus
+OTATalkGetMyZone(
+ ATSvcRef ref,
+ TNetbuf * zone) ;
+extern OSStatus
+OTATalkGetLocalZones(
+ ATSvcRef ref,
+ TNetbuf * zones) ;
+extern OSStatus
+OTATalkGetZoneList(
+ ATSvcRef ref,
+ TNetbuf * zones) ;
+extern OSStatus
+OTATalkGetInfo(
+ ATSvcRef ref,
+ TNetbuf * info) ;
+
+
+
+}
+
+class TAppleTalkServices : public TProvider
+{
+ public:
+ OSStatus GetMyZone(TNetbuf* zone) { return OTATalkGetMyZone(this, zone); }
+ OSStatus GetLocalZones(TNetbuf* zones) { return OTATalkGetLocalZones(this, zones); }
+ OSStatus GetZoneList(TNetbuf* zones) { return OTATalkGetZoneList(this, zones); }
+ OSStatus GetInfo(TNetbuf* info) { return OTATalkGetInfo(this, info); }
+};
+
+extern "C" {
+enum {
+ AF_ATALK_FAMILY = 0x0100,
+ AF_ATALK_DDP = 0x0100,
+ AF_ATALK_DDPNBP = AF_ATALK_FAMILY + 1,
+ AF_ATALK_NBP = AF_ATALK_FAMILY + 2,
+ AF_ATALK_MNODE = AF_ATALK_FAMILY + 3
+};
+
+struct NBPEntity {
+ UInt8 fEntity[99];
+};
+typedef struct NBPEntity NBPEntity;
+struct DDPAddress {
+ OTAddressType fAddressType;
+ UInt16 fNetwork;
+ UInt8 fNodeID;
+ UInt8 fSocket;
+ UInt8 fDDPType;
+ UInt8 fPad;
+
+
+
+
+ void Init(const DDPAddress&);
+ void Init(UInt16 net, UInt8 node, UInt8 socket);
+ void Init(UInt16 net, UInt8 node, UInt8 socket, UInt8 type);
+
+ void SetSocket(UInt8);
+ void SetType(UInt8);
+ void SetNode(UInt8);
+ void SetNetwork(UInt16);
+
+ OTByteCount GetAddressLength() const;
+ OTAddressType GetAddressType() const;
+ UInt8 GetSocket() const;
+ UInt8 GetType() const;
+ UInt8 GetNode() const;
+ UInt16 GetNetwork() const;
+
+ Boolean operator==(const DDPAddress&) const;
+ Boolean operator!=(const DDPAddress&) const;
+ void operator=(const DDPAddress&);
+
+
+
+};
+typedef struct DDPAddress DDPAddress;
+struct NBPAddress {
+ OTAddressType fAddressType;
+ UInt8 fNBPNameBuffer[105];
+
+
+
+
+ OTByteCount Init();
+ OTByteCount Init(const NBPEntity&);
+ OTByteCount Init(const char*);
+ OTByteCount Init(const char*, OTByteCount len);
+ Boolean ExtractEntity(NBPEntity&, OTByteCount len);
+
+ OTAddressType GetAddressType() const;
+
+
+
+};
+typedef struct NBPAddress NBPAddress;
+struct DDPNBPAddress {
+ OTAddressType fAddressType;
+ UInt16 fNetwork;
+ UInt8 fNodeID;
+ UInt8 fSocket;
+ UInt8 fDDPType;
+ UInt8 fPad;
+ UInt8 fNBPNameBuffer[105];
+
+
+
+
+ void Init(const DDPAddress&);
+ void Init(UInt16 net, UInt8 node, UInt8 socket);
+ void Init(UInt16 net, UInt8 node, UInt8 socket, UInt8 type);
+
+ void SetSocket(UInt8);
+ void SetType(UInt8);
+ void SetNode(UInt8);
+ void SetNetwork(UInt16);
+
+ OTAddressType GetAddressType() const;
+ UInt8 GetSocket() const;
+ UInt8 GetType() const;
+ UInt8 GetNode() const;
+ UInt16 GetNetwork() const;
+
+ Boolean ExtractEntity(NBPEntity&, OTByteCount len);
+ OTByteCount SetNBPEntity(const NBPEntity&);
+ OTByteCount SetNBPEntity(const char*);
+ OTByteCount SetNBPEntity(const char*, OTByteCount len);
+
+ Boolean operator==(const DDPAddress&) const;
+
+
+
+};
+typedef struct DDPNBPAddress DDPNBPAddress;
+extern void
+OTInitDDPAddress(
+ DDPAddress * addr,
+ UInt16 net,
+ UInt8 node,
+ UInt8 socket,
+ UInt8 ddpType) ;
+extern OTByteCount
+OTInitNBPAddress(
+ NBPAddress * addr,
+ const char * name) ;
+extern OTByteCount
+OTInitDDPNBPAddress(
+ DDPNBPAddress * addr,
+ const char * name,
+ UInt16 net,
+ UInt8 node,
+ UInt8 socket,
+ UInt8 ddpType) ;
+extern Boolean
+OTCompareDDPAddresses(
+ const DDPAddress * addr1,
+ const DDPAddress * addr2) ;
+extern void
+OTInitNBPEntity(NBPEntity * entity) ;
+extern OTByteCount
+OTGetNBPEntityLengthAsAddress(const NBPEntity * entity) ;
+extern OTByteCount
+OTSetAddressFromNBPEntity(
+ UInt8 * nameBuf,
+ const NBPEntity * entity) ;
+extern OTByteCount
+OTSetAddressFromNBPString(
+ UInt8 * addrBuf,
+ const char * name,
+ SInt32 len) ;
+extern Boolean
+OTSetNBPEntityFromAddress(
+ NBPEntity * entity,
+ const UInt8 * addrBuf,
+ OTByteCount len) ;
+extern Boolean
+OTSetNBPName(
+ NBPEntity * entity,
+ const char * name) ;
+extern Boolean
+OTSetNBPType(
+ NBPEntity * entity,
+ const char * typeVal) ;
+extern Boolean
+OTSetNBPZone(
+ NBPEntity * entity,
+ const char * zone) ;
+extern void
+OTExtractNBPName(
+ const NBPEntity * entity,
+ char * name) ;
+extern void
+OTExtractNBPType(
+ const NBPEntity * entity,
+ char * typeVal) ;
+extern void
+OTExtractNBPZone(
+ const NBPEntity * entity,
+ char * zone) ;
+
+
+
+
+
+
+inline void DDPAddress::operator=(const DDPAddress& addr)
+{
+ *(UInt32*)&fAddressType = *(UInt32*)&addr.fAddressType;
+ *(UInt32*)&fNodeID = *(UInt32*)&addr.fNodeID;
+}
+
+inline Boolean DDPAddress::operator==(const DDPAddress& addr) const
+{
+ return OTCompareDDPAddresses(&addr, this);
+}
+
+inline Boolean DDPAddress::operator!=(const DDPAddress& addr) const
+{
+ return !OTCompareDDPAddresses(&addr, this);
+}
+
+inline void DDPAddress::SetSocket(UInt8 socket)
+{
+ fSocket = socket;
+}
+
+inline void DDPAddress::SetNode(UInt8 node)
+{
+ fNodeID = node;
+}
+
+inline void DDPAddress::SetType(UInt8 type)
+{
+ fDDPType = type;
+}
+
+inline void DDPAddress::SetNetwork(UInt16 net)
+{
+ fNetwork = net;
+}
+
+inline OTByteCount DDPAddress::GetAddressLength() const
+{
+ return kDDPAddressLength;
+}
+
+inline OTAddressType DDPAddress::GetAddressType() const
+{
+ return fAddressType;
+}
+
+inline UInt8 DDPAddress::GetSocket() const
+{
+ return fSocket;
+}
+
+inline UInt8 DDPAddress::GetNode() const
+{
+ return fNodeID;
+}
+
+inline UInt8 DDPAddress::GetType() const
+{
+ return fDDPType;
+}
+
+inline UInt16 DDPAddress::GetNetwork() const
+{
+ return fNetwork;
+}
+
+inline void DDPAddress::Init(UInt16 net, UInt8 node,
+ UInt8 socket)
+{
+ fAddressType = AF_ATALK_DDP;
+ SetNetwork(net);
+ SetNode(node);
+ SetSocket(socket);
+ SetType(0);
+}
+
+inline void DDPAddress::Init(UInt16 net, UInt8 node,
+ UInt8 socket, UInt8 type)
+{
+ fAddressType = AF_ATALK_DDP;
+ SetNetwork(net);
+ SetNode(node);
+ SetSocket(socket);
+ SetType(type);
+}
+
+inline void DDPAddress::Init(const DDPAddress& addr)
+{
+ *(UInt32*)&fAddressType = *(UInt32*)&addr.fAddressType;
+ *(UInt32*)&fNodeID = *(UInt32*)&addr.fNodeID;
+}
+
+
+
+inline OTByteCount NBPAddress::Init()
+{
+ fAddressType = AF_ATALK_NBP;
+ return sizeof(OTAddressType);
+}
+
+inline OTByteCount NBPAddress::Init(const NBPEntity& addr)
+{
+ fAddressType = AF_ATALK_NBP;
+ return sizeof(OTAddressType) + OTSetAddressFromNBPEntity(fNBPNameBuffer, &addr);
+}
+
+inline OTByteCount NBPAddress::Init(const char* name)
+{
+ fAddressType = AF_ATALK_NBP;
+ return sizeof(OTAddressType) + OTSetAddressFromNBPString(fNBPNameBuffer, name, -1);
+}
+
+inline OTByteCount NBPAddress::Init(const char* name, OTByteCount len)
+{
+ fAddressType = AF_ATALK_NBP;
+ return sizeof(OTAddressType) + OTSetAddressFromNBPString(fNBPNameBuffer, name, (SInt32)len);
+}
+
+inline Boolean NBPAddress::ExtractEntity(NBPEntity& entity, OTByteCount len)
+{
+ return OTSetNBPEntityFromAddress(&entity, fNBPNameBuffer, len);
+}
+
+inline OTAddressType NBPAddress::GetAddressType() const
+{
+ return fAddressType;
+}
+
+
+
+inline Boolean DDPNBPAddress::operator==(const DDPAddress& addr) const
+{
+ return OTCompareDDPAddresses((const DDPAddress*)this, &addr);
+}
+
+inline void DDPNBPAddress::SetSocket(UInt8 socket)
+{
+ fSocket = socket;
+}
+
+inline void DDPNBPAddress::SetNode(UInt8 node)
+{
+ fNodeID = node;
+}
+
+inline void DDPNBPAddress::SetType(UInt8 type)
+{
+ fDDPType = type;
+}
+
+inline void DDPNBPAddress::SetNetwork(UInt16 net)
+{
+ fNetwork = net;
+}
+
+inline OTAddressType DDPNBPAddress::GetAddressType() const
+{
+ return fAddressType;
+}
+
+inline UInt8 DDPNBPAddress::GetSocket() const
+{
+ return fSocket;
+}
+
+inline UInt8 DDPNBPAddress::GetNode() const
+{
+ return fNodeID;
+}
+
+inline UInt8 DDPNBPAddress::GetType() const
+{
+ return fDDPType;
+}
+
+inline UInt16 DDPNBPAddress::GetNetwork() const
+{
+ return fNetwork;
+}
+
+inline void DDPNBPAddress::Init(UInt16 net, UInt8 node,
+ UInt8 socket)
+{
+ fAddressType = AF_ATALK_DDPNBP;
+ SetNetwork(net);
+ SetNode(node);
+ SetSocket(socket);
+ SetType(0);
+}
+
+inline void DDPNBPAddress::Init(UInt16 net, UInt8 node,
+ UInt8 socket, UInt8 type)
+{
+ fAddressType = AF_ATALK_DDPNBP;
+ SetNetwork(net);
+ SetNode(node);
+ SetSocket(socket);
+ SetType(type);
+}
+
+inline void DDPNBPAddress::Init(const DDPAddress& addr)
+{
+ fAddressType = AF_ATALK_DDPNBP;
+ SetNetwork(addr.GetNetwork());
+ SetNode(addr.GetNode());
+ SetSocket(addr.GetSocket());
+ SetType(addr.GetType());
+ fNBPNameBuffer[0] = 0;
+}
+
+inline OTByteCount DDPNBPAddress::SetNBPEntity(const NBPEntity& entity)
+{
+ return OTSetAddressFromNBPEntity(fNBPNameBuffer, &entity) + kDDPAddressLength;
+}
+
+inline OTByteCount DDPNBPAddress::SetNBPEntity(const char* name)
+{
+ return OTSetAddressFromNBPString(fNBPNameBuffer, name, -1) + kDDPAddressLength;
+}
+
+inline OTByteCount DDPNBPAddress::SetNBPEntity(const char* name, OTByteCount len)
+{
+ return OTSetAddressFromNBPString(fNBPNameBuffer, name, (SInt32)len) + kDDPAddressLength;
+}
+
+inline Boolean DDPNBPAddress::ExtractEntity(NBPEntity& entity, OTByteCount len)
+{
+ return OTSetNBPEntityFromAddress(&entity, fNBPNameBuffer, len);
+}
+
+
+
+
+struct AppleTalkInfo {
+ DDPAddress fOurAddress;
+ DDPAddress fRouterAddress;
+ UInt16 fCableRange[2];
+ UInt16 fFlags;
+};
+typedef struct AppleTalkInfo AppleTalkInfo;
+
+enum {
+ kATalkInfoIsExtended = 0x0001,
+ kATalkInfoHasRouter = 0x0002,
+ kATalkInfoOneZone = 0x0004
+};
+
+
+
+
+
+
+
+enum {
+ kOTFramingEthernet = 0x01,
+ kOTFramingEthernetIPX = 0x02,
+ kOTFraming8023 = 0x04,
+ kOTFraming8022 = 0x08
+};
+enum {
+ kOTRawRcvOn = 0,
+ kOTRawRcvOff = 1,
+ kOTRawRcvOnWithTimeStamp = 2
+};
+
+enum {
+ DL_PROMISC_OFF = 0
+};
+
+
+
+
+
+enum {
+ kT8022ModuleID = 7100,
+ kEnetModuleID = 7101,
+ kTokenRingModuleID = 7102,
+ kFDDIModuleID = 7103
+};
+enum {
+ AF_8022 = 8200
+};
+
+
+
+enum {
+ LNK_ENET = 'ENET',
+ LNK_TOKN = 'TOKN',
+ LNK_FDDI = 'FDDI',
+ LNK_TPI = 'LTPI'
+};
+
+
+
+enum {
+ OPT_ADDMCAST = 0x1000,
+ OPT_DELMCAST = 0x1001,
+ OPT_RCVPACKETTYPE = 0x1002,
+ OPT_RCVDESTADDR = 0x1003,
+ OPT_SETRAWMODE = 0x1004,
+ OPT_SETPROMISCUOUS = 0x1005
+};
+
+typedef UInt32 OTPacketType;
+enum {
+ kETypeStandard = 0,
+ kETypeMulticast = 1,
+ kETypeBroadcast = 2,
+ kETRawPacketBit = (unsigned long)0x80000000,
+ kETTimeStampBit = 0x40000000
+};
+
+
+
+enum {
+ kMulticastLength = 6,
+ k48BitAddrLength = 6,
+ k8022DLSAPLength = 2,
+ k8022SNAPLength = 5,
+ kEnetAddressLength = k48BitAddrLength + k8022DLSAPLength,
+
+ kSNAPSAP = 0x00AA,
+ kIPXSAP = 0x00FF,
+ kMax8022SAP = 0x00FE,
+ k8022GlobalSAP = 0x00FF,
+ kMinDIXSAP = 1501,
+ kMaxDIXSAP = 0xFFFF
+};
+
+
+
+struct T8022Address {
+ OTAddressType fAddrFamily;
+ UInt8 fHWAddr[6];
+ UInt16 fSAP;
+ UInt8 fSNAP[5];
+};
+typedef struct T8022Address T8022Address;
+enum {
+ k8022BasicAddressLength = sizeof(OTAddressType) + k48BitAddrLength + sizeof(UInt16),
+ k8022SNAPAddressLength = sizeof(OTAddressType) + k48BitAddrLength + sizeof(UInt16) + k8022SNAPLength
+};
+enum {
+ kEnetPacketHeaderLength = (2 * k48BitAddrLength) + k8022DLSAPLength,
+ kEnetTSDU = 1514,
+ kTokenRingTSDU = 4458,
+ kFDDITSDU = 4458,
+ k8022SAPLength = 1,
+ k8022BasicHeaderLength = 3,
+
+ k8022SNAPHeaderLength = k8022SNAPLength + k8022BasicHeaderLength
+};
+
+
+
+
+typedef UInt32 EAddrType;
+enum {
+ keaStandardAddress = 0,
+ keaMulticast = 1,
+ keaBroadcast = 2,
+ keaBadAddress = 3,
+ keaRawPacketBit = (unsigned long)0x80000000,
+ keaTimeStampBit = 0x40000000
+};
+
+
+
+struct EnetPacketHeader {
+ UInt8 fDestAddr[6];
+ UInt8 fSourceAddr[6];
+ UInt16 fProto;
+};
+typedef struct EnetPacketHeader EnetPacketHeader;
+struct T8022Header {
+ UInt8 fDSAP;
+ UInt8 fSSAP;
+ UInt8 fCtrl;
+};
+typedef struct T8022Header T8022Header;
+struct T8022SNAPHeader {
+ UInt8 fDSAP;
+ UInt8 fSSAP;
+ UInt8 fCtrl;
+ UInt8 fSNAP[5];
+};
+typedef struct T8022SNAPHeader T8022SNAPHeader;
+struct T8022FullPacketHeader {
+ EnetPacketHeader fEnetPart;
+ T8022SNAPHeader f8022Part;
+};
+typedef struct T8022FullPacketHeader T8022FullPacketHeader;
+
+enum {
+ kT8022HeaderLength = 3,
+ kT8022SNAPHeaderLength = 3 + k8022SNAPLength,
+ kT8022FullPacketHeaderLength = kEnetPacketHeaderLength + kT8022SNAPHeaderLength
+};
+
+
+
+
+
+
+
+enum {
+ COM_SERIAL = 'SERL'
+};
+enum {
+ kSerialABModuleID = 7200
+};
+
+enum {
+ kOTSerialFramingAsync = 0x01,
+ kOTSerialFramingHDLC = 0x02,
+ kOTSerialFramingSDLC = 0x04,
+ kOTSerialFramingAsyncPackets = 0x08,
+ kOTSerialFramingPPP = 0x10
+};
+
+
+
+enum {
+ I_SetSerialDTR = ((MIOC_SRL << 8) | 0),
+ kOTSerialSetDTROff = 0,
+ kOTSerialSetDTROn = 1,
+ I_SetSerialBreak = ((MIOC_SRL << 8) | 1),
+
+
+ kOTSerialSetBreakOn = (unsigned long)0xFFFFFFFF,
+ kOTSerialSetBreakOff = 0,
+ I_SetSerialXOffState = ((MIOC_SRL << 8) | 2),
+ kOTSerialForceXOffTrue = 1,
+ kOTSerialForceXOffFalse = 0,
+ I_SetSerialXOn = ((MIOC_SRL << 8) | 3),
+ kOTSerialSendXOnAlways = 1,
+ kOTSerialSendXOnIfXOffTrue = 0,
+ I_SetSerialXOff = ((MIOC_SRL << 8) | 4),
+ kOTSerialSendXOffAlways = 1,
+ kOTSerialSendXOffIfXOnTrue = 0
+};
+enum {
+ SERIAL_OPT_BAUDRATE = 0x0100,
+ SERIAL_OPT_DATABITS = 0x0101,
+ SERIAL_OPT_STOPBITS = 0x0102,
+ SERIAL_OPT_PARITY = 0x0103,
+ SERIAL_OPT_STATUS = 0x0104,
+
+
+ SERIAL_OPT_HANDSHAKE = 0x0105,
+
+
+
+
+
+ SERIAL_OPT_RCVTIMEOUT = 0x0106,
+
+
+
+
+
+
+ SERIAL_OPT_ERRORCHARACTER = 0x0107,
+ SERIAL_OPT_EXTCLOCK = 0x0108,
+
+
+
+ SERIAL_OPT_BURSTMODE = 0x0109,
+
+
+ SERIAL_OPT_DUMMY = 0x010A
+};
+
+typedef UInt32 ParityOptionValues;
+enum {
+ kOTSerialNoParity = 0,
+ kOTSerialOddParity = 1,
+ kOTSerialEvenParity = 2
+};
+
+enum {
+ kOTSerialSwOverRunErr = 0x01,
+ kOTSerialBreakOn = 0x08,
+ kOTSerialParityErr = 0x10,
+ kOTSerialOverrunErr = 0x20,
+ kOTSerialFramingErr = 0x40,
+ kOTSerialXOffSent = 0x00010000,
+ kOTSerialDTRNegated = 0x00020000,
+ kOTSerialCTLHold = 0x00040000,
+ kOTSerialXOffHold = 0x00080000,
+ kOTSerialOutputBreakOn = 0x01000000
+};
+
+enum {
+ kOTSerialXOnOffInputHandshake = 1,
+ kOTSerialXOnOffOutputHandshake = 2,
+ kOTSerialCTSInputHandshake = 4,
+ kOTSerialDTROutputHandshake = 8
+};
+
+
+
+
+ inline UInt32 OTSerialHandshakeData(UInt16 type, UInt8 onChar, UInt8 offChar)
+ {
+ return (((UInt32)type) << 16) | (((UInt32)onChar) << 8) | offChar;
+ }
+inline UInt32 OTSerialSetErrorCharacter(UInt8 rep)
+{
+ return (UInt32)rep & 0x000000ff;
+}
+
+inline UInt32 OTSerialSetErrorCharacterWithAlternate(UInt8 rep, UInt8 alternate)
+{
+ return (((rep & 0xff) | ((alternate & 0xff) << 8)) | 0x80000000L);
+}
+enum {
+ kOTSerialDefaultBaudRate = 19200,
+ kOTSerialDefaultDataBits = 8,
+ kOTSerialDefaultStopBits = 10,
+ kOTSerialDefaultParity = kOTSerialNoParity,
+ kOTSerialDefaultHandshake = 0,
+ kOTSerialDefaultOnChar = ('Q' & 0xFFFFFFBF),
+ kOTSerialDefaultOffChar = ('S' & 0xFFFFFFBF),
+ kOTSerialDefaultSndBufSize = 1024,
+ kOTSerialDefaultRcvBufSize = 1024,
+ kOTSerialDefaultSndLoWat = 96,
+ kOTSerialDefaultRcvLoWat = 1,
+ kOTSerialDefaultRcvTimeout = 10
+};
+
+
+
+
+
+
+
+enum {
+ COM_ISDN = 'ISDN'
+};
+
+
+
+
+enum {
+ kISDNModuleID = 7300
+};
+
+
+
+
+enum {
+ kOTISDNFramingTransparentSupported = 0x0010,
+ kOTISDNFramingHDLCSupported = 0x0020,
+ kOTISDNFramingV110Supported = 0x0040,
+ kOTISDNFramingV14ESupported = 0x0080
+};
+
+
+
+
+
+enum {
+ kOTISDNUnallocatedNumber = 1,
+ kOTISDNNoRouteToSpecifiedTransitNetwork = 2,
+ kOTISDNNoRouteToDestination = 3,
+ kOTISDNChannelUnacceptable = 6,
+ kOTISDNNormal = 16,
+ kOTISDNUserBusy = 17,
+ kOTISDNNoUserResponding = 18,
+ kOTISDNNoAnswerFromUser = 19,
+ kOTISDNCallRejected = 21,
+ kOTISDNNumberChanged = 22,
+ kOTISDNNonSelectedUserClearing = 26,
+ kOTISDNDestinationOutOfOrder = 27,
+ kOTISDNInvalidNumberFormat = 28,
+ kOTISDNFacilityRejected = 29,
+ kOTISDNNormalUnspecified = 31,
+ kOTISDNNoCircuitChannelAvailable = 34,
+ kOTISDNNetworkOutOfOrder = 41,
+ kOTISDNSwitchingEquipmentCongestion = 42,
+ kOTISDNAccessInformationDiscarded = 43,
+ kOTISDNRequestedCircuitChannelNotAvailable = 44,
+ kOTISDNResourceUnavailableUnspecified = 45,
+ kOTISDNQualityOfServiceUnvailable = 49,
+ kOTISDNRequestedFacilityNotSubscribed = 50,
+ kOTISDNBearerCapabilityNotAuthorized = 57,
+ kOTISDNBearerCapabilityNotPresentlyAvailable = 58,
+ kOTISDNCallRestricted = 59,
+ kOTISDNServiceOrOptionNotAvilableUnspecified = 63,
+ kOTISDNBearerCapabilityNotImplemented = 65,
+ kOTISDNRequestedFacilityNotImplemented = 69,
+ kOTISDNOnlyRestrictedDigitalBearer = 70,
+ kOTISDNServiceOrOptionNotImplementedUnspecified = 79,
+ kOTISDNCallIdentityNotUsed = 83,
+ kOTISDNCallIdentityInUse = 84,
+ kOTISDNNoCallSuspended = 85,
+ kOTISDNCallIdentityCleared = 86,
+ kOTISDNIncompatibleDestination = 88,
+ kOTISDNInvalidTransitNetworkSelection = 91,
+ kOTISDNInvalidMessageUnspecified = 95,
+ kOTISDNMandatoryInformationElementIsMissing = 96,
+ kOTISDNMessageTypeNonExistentOrNotImplemented = 97,
+ kOTISDNInterworkingUnspecified = 127
+};
+enum {
+ kAF_ISDN = 0x2000
+};
+
+
+enum {
+ kOTISDNMaxPhoneSize = 32,
+ kOTISDNMaxSubSize = 4
+};
+
+struct OTISDNAddress {
+ OTAddressType fAddressType;
+ UInt16 fPhoneLength;
+ char fPhoneNumber[37];
+};
+typedef struct OTISDNAddress OTISDNAddress;
+
+
+
+enum {
+ MIOC_ISDN = 'U'
+};
+
+enum {
+ I_OTISDNAlerting = ((MIOC_ISDN << 8) | 100),
+ I_OTISDNSuspend = ((MIOC_ISDN << 8) | 101),
+
+ I_OTISDNSuspendAcknowledge = ((MIOC_ISDN << 8) | 102),
+ I_OTISDNSuspendReject = ((MIOC_ISDN << 8) | 103),
+ I_OTISDNResume = ((MIOC_ISDN << 8) | 104),
+
+ I_OTISDNResumeAcknowledge = ((MIOC_ISDN << 8) | 105),
+ I_OTISDNResumeReject = ((MIOC_ISDN << 8) | 106),
+ I_OTISDNFaciltity = ((MIOC_ISDN << 8) | 107)
+};
+
+
+
+enum {
+ kOTISDNMaxUserDataSize = 32
+};
+
+
+
+enum {
+ ISDN_OPT_COMMTYPE = 0x0200,
+ ISDN_OPT_FRAMINGTYPE = 0x0201,
+ ISDN_OPT_56KADAPTATION = 0x0202
+};
+
+
+
+enum {
+ kOTISDNTelephoneALaw = 1,
+ kOTISDNTelephoneMuLaw = 26,
+ kOTISDNDigital64k = 13,
+ kOTISDNDigital56k = 37,
+ kOTISDNVideo64k = 41,
+ kOTISDNVideo56k = 42
+};
+
+
+
+enum {
+ kOTISDNFramingTransparent = 0x0010,
+ kOTISDNFramingHDLC = 0x0020,
+ kOTISDNFramingV110 = 0x0040,
+ kOTISDNFramingV14E = 0x0080
+};
+
+
+
+enum {
+ kOTISDNNot56KAdaptation = false,
+ kOTISDN56KAdaptation = true
+};
+
+
+
+enum {
+ kOTISDNDefaultCommType = kOTISDNDigital64k,
+ kOTISDNDefaultFramingType = kOTISDNFramingHDLC,
+ kOTISDNDefault56KAdaptation = kOTISDNNot56KAdaptation
+};
+enum {
+ COM_PPP = 'PPPC'
+};
+
+
+
+enum {
+ kPPPMaxIDLength = 255,
+ kPPPMaxPasswordLength = 255,
+ kPPPMaxDTEAddressLength = 127,
+ kPPPMaxCallInfoLength = 255
+};
+
+
+
+
+enum {
+ kPPPStateInitial = 1,
+ kPPPStateClosed = 2,
+ kPPPStateClosing = 3,
+ kPPPStateOpening = 4,
+ kPPPStateOpened = 5
+};
+
+enum {
+ kPPPConnectionStatusIdle = 1,
+ kPPPConnectionStatusConnecting = 2,
+ kPPPConnectionStatusConnected = 3,
+ kPPPConnectionStatusDisconnecting = 4
+};
+
+enum {
+ kPPPMinMRU = 0,
+ kPPPMaxMRU = 4500
+};
+
+enum {
+ kIPCPTCPHdrCompressionDisabled = 0,
+ kIPCPTCPHdrCompressionEnabled = 1
+};
+
+enum {
+ kPPPCompressionDisabled = 0x00000000,
+ kPPPProtoCompression = 0x00000001,
+ kPPPAddrCompression = 0x00000002
+};
+
+enum {
+ kPPPNoOutAuthentication = 0,
+ kPPPCHAPOrPAPOutAuthentication = 1
+};
+
+enum {
+ kCCReminderTimerDisabled = 0,
+ kCCIPIdleTimerDisabled = 0
+};
+
+enum {
+ kPPPScriptTypeModem = 1,
+ kPPPScriptTypeConnect = 2,
+ kPPPMaxScriptSize = 32000
+};
+
+enum {
+ kE164Address = 1,
+ kPhoneAddress = 1,
+ kCompoundPhoneAddress = 2,
+ kX121Address = 3
+};
+
+enum {
+ kPPPConnectionStatusDialogsFlag = 0x00000001,
+ kPPPConnectionRemindersFlag = 0x00000002,
+ kPPPConnectionFlashingIconFlag = 0x00000004,
+ kPPPOutPasswordDialogsFlag = 0x00000008,
+ kPPPAllAlertsDisabledFlag = 0x00000000,
+ kPPPAllAlertsEnabledFlag = 0x0000000F
+};
+
+enum {
+ kPPPAsyncMapCharsNone = 0x00000000,
+ kPPPAsyncMapCharsXOnXOff = 0x000A0000,
+ kPPPAsyncMapCharsAll = (unsigned long)0xFFFFFFFF
+};
+
+
+
+
+enum {
+ IPCP_OPT_GETREMOTEPROTOADDR = 0x00007000,
+ IPCP_OPT_GETLOCALPROTOADDR = 0x00007001,
+ IPCP_OPT_TCPHDRCOMPRESSION = 0x00007002,
+ LCP_OPT_PPPCOMPRESSION = 0x00007003,
+ LCP_OPT_MRU = 0x00007004,
+ LCP_OPT_RCACCMAP = 0x00007005,
+ LCP_OPT_TXACCMAP = 0x00007006,
+ SEC_OPT_OUTAUTHENTICATION = 0x00007007,
+ SEC_OPT_ID = 0x00007008,
+ SEC_OPT_PASSWORD = 0x00007009,
+ CC_OPT_REMINDERTIMER = 0x00007010,
+ CC_OPT_IPIDLETIMER = 0x00007011,
+ CC_OPT_DTEADDRESSTYPE = 0x00007012,
+ CC_OPT_DTEADDRESS = 0x00007013,
+ CC_OPT_CALLINFO = 0x00007014,
+ CC_OPT_GETMISCINFO = 0x00007015,
+ PPP_OPT_GETCURRENTSTATE = 0x00007016,
+ LCP_OPT_ECHO = 0x00007017,
+ CC_OPT_SERIALPORTNAME = 0x00007200
+};
+
+
+
+enum {
+ kPPPEvent = kPROTOCOLEVENT | 0x000F0000,
+ kPPPConnectCompleteEvent = kPPPEvent + 1,
+ kPPPSetScriptCompleteEvent = kPPPEvent + 2,
+ kPPPDisconnectCompleteEvent = kPPPEvent + 3,
+ kPPPDisconnectEvent = kPPPEvent + 4,
+ kPPPIPCPUpEvent = kPPPEvent + 5,
+ kPPPIPCPDownEvent = kPPPEvent + 6,
+ kPPPLCPUpEvent = kPPPEvent + 7,
+ kPPPLCPDownEvent = kPPPEvent + 8,
+ kPPPLowerLayerUpEvent = kPPPEvent + 9,
+ kPPPLowerLayerDownEvent = kPPPEvent + 10,
+ kPPPAuthenticationStartedEvent = kPPPEvent + 11,
+ kPPPAuthenticationFinishedEvent = kPPPEvent + 12,
+ kPPPDCEInitStartedEvent = kPPPEvent + 13,
+ kPPPDCEInitFinishedEvent = kPPPEvent + 14,
+ kPPPDCECallStartedEvent = kPPPEvent + 15,
+ kPPPDCECallFinishedEvent = kPPPEvent + 16
+};
+struct PPPMRULimits {
+ UInt32 mruSize;
+ UInt32 upperMRULimit;
+ UInt32 lowerMRULimit;
+};
+typedef struct PPPMRULimits PPPMRULimits;
+
+
+
+
+struct CCMiscInfo {
+ UInt32 connectionStatus;
+ UInt32 connectionTimeElapsed;
+ UInt32 connectionTimeRemaining;
+ UInt32 bytesTransmitted;
+ UInt32 bytesReceived;
+ UInt32 reserved;
+};
+typedef struct CCMiscInfo CCMiscInfo;
+
+
+
+
+
+
+struct LCPEcho {
+ UInt32 retryCount;
+ UInt32 retryPeriod;
+};
+typedef struct LCPEcho LCPEcho;
+
+
+
+
+enum {
+ kRAProductClientOnly = 2,
+ kRAProductOnePortServer = 3,
+ kRAProductManyPortServer = 4
+};
+
+
+
+
+
+
+
+
+
+}
+extern "C" {
+
+
+enum {
+ I_NREAD = ((MIOC_STREAMIO << 8) | 1),
+ I_PUSH = ((MIOC_STREAMIO << 8) | 2),
+ I_POP = ((MIOC_STREAMIO << 8) | 3),
+ I_LOOK = ((MIOC_STREAMIO << 8) | 4),
+ I_FLUSH = ((MIOC_STREAMIO << 8) | 5),
+ I_SRDOPT = ((MIOC_STREAMIO << 8) | 6),
+ I_GRDOPT = ((MIOC_STREAMIO << 8) | 7),
+ I_STR = ((MIOC_STREAMIO << 8) | 8),
+ I_SETSIG = ((MIOC_STREAMIO << 8) | 9),
+ I_GETSIG = ((MIOC_STREAMIO << 8) | 10),
+ I_FIND = ((MIOC_STREAMIO << 8) | 11),
+ I_LINK = ((MIOC_STREAMIO << 8) | 12),
+ I_UNLINK = ((MIOC_STREAMIO << 8) | 13),
+ I_PEEK = ((MIOC_STREAMIO << 8) | 15),
+ I_FDINSERT = ((MIOC_STREAMIO << 8) | 16),
+ I_SENDFD = ((MIOC_STREAMIO << 8) | 17),
+ I_RECVFD = ((MIOC_STREAMIO << 8) | 18),
+ I_FLUSHBAND = ((MIOC_STREAMIO << 8) | 19),
+ I_SWROPT = ((MIOC_STREAMIO << 8) | 20),
+ I_GWROPT = ((MIOC_STREAMIO << 8) | 21),
+ I_LIST = ((MIOC_STREAMIO << 8) | 22),
+ I_ATMARK = ((MIOC_STREAMIO << 8) | 23),
+ I_CKBAND = ((MIOC_STREAMIO << 8) | 24),
+ I_GETBAND = ((MIOC_STREAMIO << 8) | 25),
+ I_CANPUT = ((MIOC_STREAMIO << 8) | 26),
+ I_SETCLTIME = ((MIOC_STREAMIO << 8) | 27),
+ I_GETCLTIME = ((MIOC_STREAMIO << 8) | 28),
+ I_PLINK = ((MIOC_STREAMIO << 8) | 29),
+ I_PUNLINK = ((MIOC_STREAMIO << 8) | 30),
+ I_GETMSG = ((MIOC_STREAMIO << 8) | 40),
+ I_PUTMSG = ((MIOC_STREAMIO << 8) | 41),
+ I_POLL = ((MIOC_STREAMIO << 8) | 42),
+ I_SETDELAY = ((MIOC_STREAMIO << 8) | 43),
+ I_GETDELAY = ((MIOC_STREAMIO << 8) | 44),
+ I_RUN_QUEUES = ((MIOC_STREAMIO << 8) | 45),
+ I_GETPMSG = ((MIOC_STREAMIO << 8) | 46),
+ I_PUTPMSG = ((MIOC_STREAMIO << 8) | 47),
+ I_AUTOPUSH = ((MIOC_STREAMIO << 8) | 48),
+ I_PIPE = ((MIOC_STREAMIO << 8) | 49),
+ I_HEAP_REPORT = ((MIOC_STREAMIO << 8) | 50),
+ I_FIFO = ((MIOC_STREAMIO << 8) | 51)
+};
+enum {
+ RS_HIPRI = 0x01
+};
+
+
+enum {
+ MSG_HIPRI = 0x01,
+ MSG_BAND = 0x02,
+ MSG_ANY = 0x04
+};
+
+
+enum {
+ MORECTL = 0x01,
+ MOREDATA = 0x02
+};
+
+
+enum {
+ FMNAMESZ = 31
+};
+
+
+
+enum {
+ INFTIM = (unsigned long)0xFFFFFFFF
+};
+
+
+enum {
+ FLUSHR = 0x01,
+ FLUSHW = 0x02,
+ FLUSHRW = (FLUSHW | FLUSHR)
+};
+
+enum {
+ FLUSHBAND = 0x40
+};
+struct bandinfo {
+ unsigned char bi_pri;
+ char pad1;
+ SInt32 bi_flag;
+};
+typedef struct bandinfo bandinfo;
+
+enum {
+ ANYMARK = 0x01,
+ LASTMARK = 0x02
+};
+
+
+enum {
+ S_INPUT = 0x01,
+ S_HIPRI = 0x02,
+ S_OUTPUT = 0x04,
+ S_MSG = 0x08,
+ S_RDNORM = 0x10,
+ S_RDBAND = 0x20,
+ S_WRNORM = 0x40,
+ S_WRBAND = 0x80,
+ S_ERROR = 0x0100,
+ S_HANGUP = 0x0200,
+ S_BANDURG = 0x0400
+};
+
+
+enum {
+ RNORM = 0x01,
+ RMSGD = 0x02,
+ RMSGN = 0x04,
+ RFILL = 0x08
+};
+
+
+enum {
+ RPROTNORM = 0x10,
+ RPROTDIS = 0x20,
+ RPROTDAT = 0x40
+};
+
+
+enum {
+ SNDZERO = 0x01
+};
+
+enum {
+ MUXID_ALL = -1
+};
+
+
+
+
+
+
+
+struct strfdinsert {
+ strbuf ctlbuf;
+ strbuf databuf;
+ long flags;
+ long fildes;
+ SInt32 offset;
+};
+typedef struct strfdinsert strfdinsert;
+
+struct str_mlist {
+ char l_name[32];
+};
+typedef struct str_mlist str_mlist;
+struct str_list {
+ SInt32 sl_nmods;
+ str_mlist * sl_modlist;
+};
+typedef struct str_list str_list;
+
+struct strpeek {
+ strbuf ctlbuf;
+ strbuf databuf;
+ long flags;
+};
+typedef struct strpeek strpeek;
+
+struct strpmsg {
+ strbuf ctlbuf;
+ strbuf databuf;
+ SInt32 band;
+ long flags;
+};
+typedef struct strpmsg strpmsg;
+
+struct strrecvfd {
+ long fd;
+ unsigned short uid;
+ unsigned short gid;
+ char fill[8];
+};
+typedef struct strrecvfd strrecvfd;
+
+struct strioctl {
+ SInt32 ic_cmd;
+ SInt32 ic_timout;
+ SInt32 ic_len;
+ char * ic_dp;
+};
+typedef struct strioctl strioctl;
+
+
+struct log_ctl {
+ short mid;
+ short sid;
+ char level;
+ char pad1;
+ short flags;
+ long ltime;
+ long ttime;
+ SInt32 seq_no;
+};
+typedef struct log_ctl log_ctl;
+enum {
+ SL_FATAL = 0x01,
+ SL_NOTIFY = 0x02,
+ SL_ERROR = 0x04,
+ SL_TRACE = 0x08,
+ SL_CONSOLE = 0x00,
+ SL_WARN = 0x20,
+ SL_NOTE = 0x40
+};
+
+struct trace_ids {
+ short ti_mid;
+ short ti_sid;
+ char ti_level;
+};
+typedef struct trace_ids trace_ids;
+enum {
+ I_TRCLOG = ((MIOC_STRLOG << 8) | 1),
+ I_ERRLOG = ((MIOC_STRLOG << 8) | 2)
+};
+
+enum {
+ LOGMSGSZ = 128
+};
+struct OTPortCloseStruct {
+ OTPortRef fPortRef;
+ ProviderRef fTheProvider;
+ OSStatus fDenyReason;
+};
+typedef struct OTPortCloseStruct OTPortCloseStruct;
+
+struct OTClientList {
+ ItemCount fNumClients;
+ UInt8 fBuffer[4];
+};
+typedef struct OTClientList OTClientList;
+typedef long OTTimerTask;
+extern long
+OTCreateTimerTaskInContext(
+ OTProcessUPP upp,
+ void * arg,
+ OTClientContextPtr clientContext) ;
+extern Boolean
+OTCancelTimerTask(OTTimerTask timerTask) ;
+extern void
+OTDestroyTimerTask(OTTimerTask timerTask) ;
+extern Boolean
+OTScheduleTimerTask(
+ OTTimerTask timerTask,
+ OTTimeout milliSeconds) ;
+extern OTByteCount
+OTBufferDataSize(OTBuffer * buffer) ;
+extern Boolean
+OTReadBuffer(
+ OTBufferInfo * buffer,
+ void * dest,
+ OTByteCount * len) ;
+extern void
+OTReleaseBuffer(OTBuffer * buffer) ;
+extern OTResult
+OTSetFirstClearBit(
+ UInt8 * bitMap,
+ OTByteCount startBit,
+ OTByteCount numBits) ;
+extern Boolean
+OTClearBit(
+ UInt8 * bitMap,
+ OTByteCount bitNo) ;
+extern Boolean
+OTSetBit(
+ UInt8 * bitMap,
+ OTByteCount bitNo) ;
+extern Boolean
+OTTestBit(
+ UInt8 * bitMap,
+ OTByteCount bitNo) ;
+typedef UInt32 ( * OTHashProcPtr)(OTLink * linkToHash);
+typedef Boolean ( * OTHashSearchProcPtr)(const void *ref, OTLink *linkToCheck);
+struct OTHashList {
+ OTHashProcPtr fHashProc;
+ ByteCount fHashTableSize;
+ OTLink ** fHashBuckets;
+
+
+
+
+
+
+ void Add(OTLink* toAdd);
+
+ Boolean RemoveLink(OTLink* toRemove);
+
+ OTLink* Remove(OTHashSearchProcPtr proc, const void* refPtr, UInt32 hashValue);
+
+ Boolean IsInList(OTLink* toFind);
+
+ OTLink* FindLink(OTHashSearchProcPtr proc, const void* refPtr, UInt32 hash);
+
+
+
+};
+typedef struct OTHashList OTHashList;
+typedef Boolean ( * OTGateProcPtr)(OTLink * thisLink);
+struct OTGate {
+ OTLIFO fLIFO;
+ OTList fList;
+ OTGateProcPtr fProc;
+ SInt32 fNumQueued;
+ SInt32 fInside;
+};
+typedef struct OTGate OTGate;
+
+
+}
+extern "C" {
+
+
+
+
+enum {
+ kNSLMinSystemVersion = 0x0900,
+ kNSLMinOTVersion = 0x0130
+};
+
+enum {
+ kNSLDefaultListSize = 256
+};
+
+enum {
+ kNSLURLDelimiter = ','
+};
+
+
+
+
+enum {
+ kNSLNoContext = 0
+};
+
+struct NSLError {
+ OSStatus theErr;
+ UInt32 theContext;
+};
+typedef struct NSLError NSLError;
+typedef NSLError * NSLErrorPtr;
+enum {
+
+
+
+
+ kNSLDuplicateSearchInProgress = 100,
+ kNSLUserCanceled = userCanceledErr,
+
+ kNSLInvalidEnumeratorRef = 0
+};
+
+typedef UInt16 NSLSearchState;
+enum {
+
+ kNSLSearchStateBufferFull = 1,
+ kNSLSearchStateOnGoing = 2,
+ kNSLSearchStateComplete = 3,
+ kNSLSearchStateStalled = 4,
+ kNSLWaitingForContinue = 5
+};
+
+typedef UInt32 NSLEventCode;
+enum {
+
+ kNSLServicesLookupDataEvent = 6,
+ kNSLNeighborhoodLookupDataEvent = 7,
+ kNSLNewDataEvent = 8,
+ kNSLContinueLookupEvent = 9
+};
+
+
+typedef UInt32 NSLClientRef;
+typedef UInt32 NSLRequestRef;
+typedef UInt32 NSLOneBasedIndex;
+typedef char * NSLPath;
+typedef char * NSLServiceType;
+typedef Handle NSLServicesList;
+typedef unsigned char * NSLNeighborhood;
+
+
+
+
+
+
+struct NSLClientAsyncInfo {
+ void * clientContextPtr;
+ void * mgrContextPtr;
+ char * resultBuffer;
+ long bufferLen;
+ long maxBufferSize;
+ UInt32 startTime;
+ UInt32 intStartTime;
+ UInt32 maxSearchTime;
+ UInt32 alertInterval;
+ UInt32 totalItems;
+ UInt32 alertThreshold;
+ NSLSearchState searchState;
+ NSLError searchResult;
+ NSLEventCode searchDataType;
+
+};
+typedef struct NSLClientAsyncInfo NSLClientAsyncInfo;
+typedef NSLClientAsyncInfo * NSLClientAsyncInfoPtr;
+
+
+struct NSLPluginAsyncInfo {
+ void * mgrContextPtr;
+ void * pluginContextPtr;
+ void * pluginPtr;
+ char * resultBuffer;
+ long bufferLen;
+ long maxBufferSize;
+ UInt32 maxSearchTime;
+ UInt32 reserved1;
+ UInt32 reserved2;
+ UInt32 reserved3;
+ NSLClientRef clientRef;
+ NSLRequestRef requestRef;
+ NSLSearchState searchState;
+ OSStatus searchResult;
+};
+typedef struct NSLPluginAsyncInfo NSLPluginAsyncInfo;
+typedef NSLPluginAsyncInfo * NSLPluginAsyncInfoPtr;
+
+
+typedef void ( * NSLMgrNotifyProcPtr)(NSLPluginAsyncInfo * thePluginAsyncInfo);
+
+
+typedef void ( * NSLClientNotifyProcPtr)(NSLClientAsyncInfo * theClientAsyncInfo);
+typedef NSLMgrNotifyProcPtr NSLMgrNotifyUPP;
+typedef NSLClientNotifyProcPtr NSLClientNotifyUPP;
+extern NSLMgrNotifyUPP
+NewNSLMgrNotifyUPP(NSLMgrNotifyProcPtr userRoutine) ;
+extern NSLClientNotifyUPP
+NewNSLClientNotifyUPP(NSLClientNotifyProcPtr userRoutine) ;
+extern void
+DisposeNSLMgrNotifyUPP(NSLMgrNotifyUPP userUPP) ;
+extern void
+DisposeNSLClientNotifyUPP(NSLClientNotifyUPP userUPP) ;
+extern void
+InvokeNSLMgrNotifyUPP(
+ NSLPluginAsyncInfo * thePluginAsyncInfo,
+ NSLMgrNotifyUPP userUPP) ;
+extern void
+InvokeNSLClientNotifyUPP(
+ NSLClientAsyncInfo * theClientAsyncInfo,
+ NSLClientNotifyUPP userUPP) ;
+
+
+
+
+
+
+struct NSLTypedData {
+ unsigned long dataType;
+ unsigned long lengthOfData;
+
+
+};
+typedef struct NSLTypedData NSLTypedData;
+typedef NSLTypedData * NSLTypedDataPtr;
+
+
+
+
+
+
+
+struct NSLServicesListHeader {
+ unsigned long numServices;
+ unsigned long logicalLen;
+
+
+};
+typedef struct NSLServicesListHeader NSLServicesListHeader;
+typedef NSLServicesListHeader * NSLServicesListHeaderPtr;
+struct NSLPluginData {
+ long reserved1;
+ long reserved2;
+ long reserved3;
+ Boolean supportsRegistration;
+ Boolean isPurgeable;
+ UInt16 totalLen;
+ UInt16 dataTypeOffset;
+ UInt16 serviceListOffset;
+ UInt16 protocolListOffset;
+ UInt16 commentStringOffset;
+
+
+};
+typedef struct NSLPluginData NSLPluginData;
+typedef NSLPluginData * NSLPluginDataPtr;
+extern UInt32
+NSLLibraryVersion(void) ;
+
+
+
+
+
+ inline Boolean NSLLibraryPresent() { return NSLLibraryVersion != (void*)kUnresolvedCFragSymbolAddress; }
+extern NSLError
+NSLStandardRegisterURL(
+ NSLPath urlToRegister,
+ NSLNeighborhood neighborhoodToRegisterIn) ;
+extern NSLError
+NSLStandardDeregisterURL(
+ NSLPath urlToDeregister,
+ NSLNeighborhood neighborhoodToDeregisterIn) ;
+extern OSStatus
+NSLHexEncodeText(
+ const char * rawText,
+ UInt16 rawTextLen,
+ char * newTextBuffer,
+ UInt16 * newTextBufferLen,
+ Boolean * textChanged) ;
+extern OSStatus
+NSLHexDecodeText(
+ const char * encodedText,
+ UInt16 encodedTextLen,
+ char * decodedTextBuffer,
+ UInt16 * decodedTextBufferLen,
+ Boolean * textChanged) ;
+extern NSLServicesList
+NSLMakeNewServicesList(const char * initialServiceList) ;
+extern NSLError
+NSLAddServiceToServicesList(
+ NSLServicesList serviceList,
+ NSLServiceType serviceType) ;
+extern void
+NSLDisposeServicesList(NSLServicesList theList) ;
+extern NSLNeighborhood
+NSLMakeNewNeighborhood(
+ const char * name,
+ const char * protocolList) ;
+extern NSLNeighborhood
+NSLCopyNeighborhood(NSLNeighborhood neighborhood) ;
+extern NSLNeighborhood
+NSLFreeNeighborhood(NSLNeighborhood neighborhood) ;
+extern void
+NSLGetNameFromNeighborhood(
+ NSLNeighborhood neighborhood,
+ char ** name,
+ long * length) ;
+extern OSStatus
+NSLMakeServicesRequestPB(
+ NSLServicesList serviceList,
+ NSLTypedDataPtr * newDataPtr) ;
+extern NSLTypedDataPtr
+NSLFreeTypedDataPtr(NSLTypedDataPtr nslTypeData) ;
+extern Boolean
+NSLGetNextUrl(
+ NSLClientAsyncInfoPtr infoPtr,
+ char ** urlPtr,
+ long * urlLength) ;
+extern Boolean
+NSLGetNextNeighborhood(
+ NSLClientAsyncInfoPtr infoPtr,
+ NSLNeighborhood * neighborhood,
+ long * neighborhoodLength) ;
+extern OSStatus
+NSLErrorToString(
+ NSLError theErr,
+ char * errorString,
+ char * solutionString) ;
+extern OSStatus
+NSLOpenNavigationAPI(NSLClientRef * newRef) ;
+extern void
+NSLCloseNavigationAPI(NSLClientRef theClient) ;
+extern NSLError
+NSLPrepareRequest(
+ NSLClientNotifyUPP notifier,
+ void * contextPtr,
+ NSLClientRef theClient,
+ NSLRequestRef * ref,
+ char * bufPtr,
+ unsigned long bufLen,
+ NSLClientAsyncInfoPtr * infoPtr) ;
+extern NSLError
+NSLStartNeighborhoodLookup(
+ NSLRequestRef ref,
+ NSLNeighborhood neighborhood,
+ NSLClientAsyncInfo * asyncInfo) ;
+extern NSLError
+NSLStartServicesLookup(
+ NSLRequestRef ref,
+ NSLNeighborhood neighborhood,
+ NSLTypedDataPtr requestData,
+ NSLClientAsyncInfo * asyncInfo) ;
+extern NSLError
+NSLContinueLookup(NSLClientAsyncInfo * asyncInfo) ;
+extern NSLError
+NSLCancelRequest(NSLRequestRef ref) ;
+extern NSLError
+NSLDeleteRequest(NSLRequestRef ref) ;
+extern OSStatus
+NSLParseServicesRequestPB(
+ NSLTypedDataPtr newDataPtr,
+ char ** serviceListPtr,
+ UInt16 * serviceListLen) ;
+extern OSStatus
+NSLParseServiceRegistrationPB(
+ NSLTypedDataPtr newDataPtr,
+ NSLNeighborhood * neighborhoodPtr,
+ UInt16 * neighborhoodLen,
+ char ** urlPtr,
+ UInt16 * urlLen) ;
+extern OSStatus
+NSLGetErrorStringsFromResource(
+ OSStatus theErr,
+ const FSSpec * fileSpecPtr,
+ SInt16 errorResID,
+ char * errorString,
+ char * solutionString) ;
+extern Boolean
+NSLServiceIsInServiceList(
+ NSLServicesList serviceList,
+ NSLServiceType svcToFind) ;
+extern OSStatus
+NSLGetServiceFromURL(
+ char * theURL,
+ char ** svcString,
+ UInt16 * svcLen) ;
+extern long
+NSLGetNeighborhoodLength(NSLNeighborhood neighborhood) ;
+extern OSErr
+NSLNewThread(
+ ThreadStyle threadStyle,
+ ThreadEntryProcPtr threadEntry,
+ void * threadParam,
+ Size stackSize,
+ ThreadOptions options,
+ void ** threadResult,
+ ThreadID * threadMade) ;
+extern OSErr
+NSLDisposeThread(
+ ThreadID threadToDump,
+ void * threadResult,
+ Boolean recycleThread) ;
+
+
+}
+extern "C" {
+
+
+
+
+
+
+typedef struct OpaqueSecKeychainRef* SecKeychainRef;
+typedef struct OpaqueSecKeychainItemRef* SecKeychainItemRef;
+typedef struct OpaqueSecKeychainSearchRef* SecKeychainSearchRef;
+typedef OSType SecKeychainAttrType;
+typedef UInt32 SecKeychainStatus;
+struct SecKeychainAttribute {
+ SecKeychainAttrType tag;
+ UInt32 length;
+ void * data;
+};
+typedef struct SecKeychainAttribute SecKeychainAttribute;
+typedef SecKeychainAttribute * SecKeychainAttributePtr;
+struct SecKeychainAttributeList {
+ UInt32 count;
+ SecKeychainAttribute * attr;
+};
+typedef struct SecKeychainAttributeList SecKeychainAttributeList;
+
+
+typedef SecKeychainRef KCRef;
+typedef SecKeychainItemRef KCItemRef;
+typedef SecKeychainSearchRef KCSearchRef;
+typedef SecKeychainAttribute KCAttribute;
+typedef SecKeychainAttributeList KCAttributeList;
+typedef SecKeychainAttrType KCAttrType;
+typedef SecKeychainStatus KCStatus;
+typedef UInt16 KCEvent;
+enum {
+ kIdleKCEvent = 0,
+ kLockKCEvent = 1,
+ kUnlockKCEvent = 2,
+ kAddKCEvent = 3,
+ kDeleteKCEvent = 4,
+ kUpdateKCEvent = 5,
+ kPasswordChangedKCEvent = 6,
+ kSystemKCEvent = 8,
+ kDefaultChangedKCEvent = 9,
+ kDataAccessKCEvent = 10,
+ kKeychainListChangedKCEvent = 11
+};
+
+typedef UInt16 KCEventMask;
+enum {
+ kIdleKCEventMask = 1 << kIdleKCEvent,
+ kLockKCEventMask = 1 << kLockKCEvent,
+ kUnlockKCEventMask = 1 << kUnlockKCEvent,
+ kAddKCEventMask = 1 << kAddKCEvent,
+ kDeleteKCEventMask = 1 << kDeleteKCEvent,
+ kUpdateKCEventMask = 1 << kUpdateKCEvent,
+ kPasswordChangedKCEventMask = 1 << kPasswordChangedKCEvent,
+ kSystemEventKCEventMask = 1 << kSystemKCEvent,
+ kDefaultChangedKCEventMask = 1 << kDefaultChangedKCEvent,
+ kDataAccessKCEventMask = 1 << kDataAccessKCEvent,
+ kEveryKCEventMask = 0xFFFF
+};
+
+typedef UInt8 AFPServerSignature[16];
+typedef UInt8 KCPublicKeyHash[20];
+struct KCCallbackInfo {
+ UInt32 version;
+ KCItemRef item;
+ long processID[2];
+ long event[4];
+ KCRef keychain;
+};
+typedef struct KCCallbackInfo KCCallbackInfo;
+enum {
+ kUnlockStateKCStatus = 1,
+ kRdPermKCStatus = 2,
+ kWrPermKCStatus = 4
+};
+
+
+enum {
+ kCertificateKCItemClass = 'cert',
+ kAppleSharePasswordKCItemClass = 'ashp',
+ kInternetPasswordKCItemClass = 'inet',
+ kGenericPasswordKCItemClass = 'genp'
+};
+
+
+typedef FourCharCode KCItemClass;
+enum {
+
+ kClassKCItemAttr = 'clas',
+ kCreationDateKCItemAttr = 'cdat',
+ kModDateKCItemAttr = 'mdat',
+ kDescriptionKCItemAttr = 'desc',
+ kCommentKCItemAttr = 'icmt',
+ kCreatorKCItemAttr = 'crtr',
+ kTypeKCItemAttr = 'type',
+ kScriptCodeKCItemAttr = 'scrp',
+ kLabelKCItemAttr = 'labl',
+ kInvisibleKCItemAttr = 'invi',
+ kNegativeKCItemAttr = 'nega',
+ kCustomIconKCItemAttr = 'cusi',
+ kAccountKCItemAttr = 'acct',
+
+ kServiceKCItemAttr = 'svce',
+ kGenericKCItemAttr = 'gena',
+
+ kSecurityDomainKCItemAttr = 'sdmn',
+ kServerKCItemAttr = 'srvr',
+ kAuthTypeKCItemAttr = 'atyp',
+ kPortKCItemAttr = 'port',
+ kPathKCItemAttr = 'path',
+
+ kVolumeKCItemAttr = 'vlme',
+ kAddressKCItemAttr = 'addr',
+ kSignatureKCItemAttr = 'ssig',
+
+ kProtocolKCItemAttr = 'ptcl',
+
+ kSubjectKCItemAttr = 'subj',
+ kCommonNameKCItemAttr = 'cn ',
+ kIssuerKCItemAttr = 'issu',
+ kSerialNumberKCItemAttr = 'snbr',
+ kEMailKCItemAttr = 'mail',
+ kPublicKeyHashKCItemAttr = 'hpky',
+ kIssuerURLKCItemAttr = 'iurl',
+
+ kEncryptKCItemAttr = 'encr',
+ kDecryptKCItemAttr = 'decr',
+ kSignKCItemAttr = 'sign',
+ kVerifyKCItemAttr = 'veri',
+ kWrapKCItemAttr = 'wrap',
+ kUnwrapKCItemAttr = 'unwr',
+ kStartDateKCItemAttr = 'sdat',
+ kEndDateKCItemAttr = 'edat'
+};
+
+typedef FourCharCode KCItemAttr;
+enum {
+ kKCAuthTypeNTLM = 'ntlm',
+ kKCAuthTypeMSN = 'msna',
+ kKCAuthTypeDPA = 'dpaa',
+ kKCAuthTypeRPA = 'rpaa',
+ kKCAuthTypeHTTPDigest = 'httd',
+ kKCAuthTypeDefault = 'dflt'
+};
+
+typedef FourCharCode KCAuthType;
+enum {
+ kKCProtocolTypeFTP = 'ftp ',
+ kKCProtocolTypeFTPAccount = 'ftpa',
+ kKCProtocolTypeHTTP = 'http',
+ kKCProtocolTypeIRC = 'irc ',
+ kKCProtocolTypeNNTP = 'nntp',
+ kKCProtocolTypePOP3 = 'pop3',
+ kKCProtocolTypeSMTP = 'smtp',
+ kKCProtocolTypeSOCKS = 'sox ',
+ kKCProtocolTypeIMAP = 'imap',
+ kKCProtocolTypeLDAP = 'ldap',
+ kKCProtocolTypeAppleTalk = 'atlk',
+ kKCProtocolTypeAFP = 'afp ',
+ kKCProtocolTypeTelnet = 'teln'
+};
+
+typedef FourCharCode KCProtocolType;
+typedef UInt32 KCCertAddOptions;
+enum {
+ kSecOptionReserved = 0x000000FF,
+ kCertUsageShift = 8,
+ kCertUsageSigningAdd = 1 << (kCertUsageShift + 0),
+ kCertUsageSigningAskAndAdd = 1 << (kCertUsageShift + 1),
+ kCertUsageVerifyAdd = 1 << (kCertUsageShift + 2),
+ kCertUsageVerifyAskAndAdd = 1 << (kCertUsageShift + 3),
+ kCertUsageEncryptAdd = 1 << (kCertUsageShift + 4),
+ kCertUsageEncryptAskAndAdd = 1 << (kCertUsageShift + 5),
+ kCertUsageDecryptAdd = 1 << (kCertUsageShift + 6),
+ kCertUsageDecryptAskAndAdd = 1 << (kCertUsageShift + 7),
+ kCertUsageKeyExchAdd = 1 << (kCertUsageShift + 8),
+ kCertUsageKeyExchAskAndAdd = 1 << (kCertUsageShift + 9),
+ kCertUsageRootAdd = 1 << (kCertUsageShift + 10),
+ kCertUsageRootAskAndAdd = 1 << (kCertUsageShift + 11),
+ kCertUsageSSLAdd = 1 << (kCertUsageShift + 12),
+ kCertUsageSSLAskAndAdd = 1 << (kCertUsageShift + 13),
+ kCertUsageAllAdd = 0x7FFFFF00
+};
+
+typedef UInt16 KCVerifyStopOn;
+enum {
+ kPolicyKCStopOn = 0,
+ kNoneKCStopOn = 1,
+ kFirstPassKCStopOn = 2,
+ kFirstFailKCStopOn = 3
+};
+
+typedef UInt32 KCCertSearchOptions;
+enum {
+ kCertSearchShift = 0,
+ kCertSearchSigningIgnored = 0,
+ kCertSearchSigningAllowed = 1 << (kCertSearchShift + 0),
+ kCertSearchSigningDisallowed = 1 << (kCertSearchShift + 1),
+ kCertSearchSigningMask = ((kCertSearchSigningAllowed) | (kCertSearchSigningDisallowed)),
+ kCertSearchVerifyIgnored = 0,
+ kCertSearchVerifyAllowed = 1 << (kCertSearchShift + 2),
+ kCertSearchVerifyDisallowed = 1 << (kCertSearchShift + 3),
+ kCertSearchVerifyMask = ((kCertSearchVerifyAllowed) | (kCertSearchVerifyDisallowed)),
+ kCertSearchEncryptIgnored = 0,
+ kCertSearchEncryptAllowed = 1 << (kCertSearchShift + 4),
+ kCertSearchEncryptDisallowed = 1 << (kCertSearchShift + 5),
+ kCertSearchEncryptMask = ((kCertSearchEncryptAllowed) | (kCertSearchEncryptDisallowed)),
+ kCertSearchDecryptIgnored = 0,
+ kCertSearchDecryptAllowed = 1 << (kCertSearchShift + 6),
+ kCertSearchDecryptDisallowed = 1 << (kCertSearchShift + 7),
+ kCertSearchDecryptMask = ((kCertSearchDecryptAllowed) | (kCertSearchDecryptDisallowed)),
+ kCertSearchWrapIgnored = 0,
+ kCertSearchWrapAllowed = 1 << (kCertSearchShift + 8),
+ kCertSearchWrapDisallowed = 1 << (kCertSearchShift + 9),
+ kCertSearchWrapMask = ((kCertSearchWrapAllowed) | (kCertSearchWrapDisallowed)),
+ kCertSearchUnwrapIgnored = 0,
+ kCertSearchUnwrapAllowed = 1 << (kCertSearchShift + 10),
+ kCertSearchUnwrapDisallowed = 1 << (kCertSearchShift + 11),
+ kCertSearchUnwrapMask = ((kCertSearchUnwrapAllowed) | (kCertSearchUnwrapDisallowed)),
+ kCertSearchPrivKeyRequired = 1 << (kCertSearchShift + 12),
+ kCertSearchAny = 0
+};
+
+
+enum {
+ kAnyPort = 0
+};
+
+enum {
+ kAnyProtocol = 0,
+ kAnyAuthType = 0
+};
+extern OSStatus
+KCGetKeychainManagerVersion(UInt32 * returnVers);
+ inline Boolean KeychainManagerAvailable() { return true; }
+extern OSStatus
+KCSetInteractionAllowed(Boolean state) ;
+extern Boolean
+KCIsInteractionAllowed(void) ;
+extern OSStatus
+KCMakeKCRefFromFSSpec(
+ FSSpec * keychainFSSpec,
+ KCRef * keychain) ;
+extern OSStatus
+KCMakeKCRefFromAlias(
+ AliasHandle keychainAlias,
+ KCRef * keychain) ;
+extern OSStatus
+KCMakeAliasFromKCRef(
+ KCRef keychain,
+ AliasHandle * keychainAlias) ;
+extern OSStatus
+KCReleaseKeychain(KCRef * keychain) ;
+extern OSStatus
+KCGetDefaultKeychain(KCRef * keychain) ;
+extern OSStatus
+KCSetDefaultKeychain(KCRef keychain) ;
+extern OSStatus
+KCGetStatus(
+ KCRef keychain,
+ UInt32 * keychainStatus) ;
+extern OSStatus
+KCGetKeychain(
+ KCItemRef item,
+ KCRef * keychain) ;
+extern OSStatus
+KCGetKeychainName(
+ KCRef keychain,
+ StringPtr keychainName) ;
+extern UInt16
+KCCountKeychains(void) ;
+extern OSStatus
+KCGetIndKeychain(
+ UInt16 index,
+ KCRef * keychain) ;
+
+
+typedef OSStatus ( * KCCallbackProcPtr)(KCEvent keychainEvent, KCCallbackInfo *info, void *userContext);
+typedef KCCallbackProcPtr KCCallbackUPP;
+extern KCCallbackUPP
+NewKCCallbackUPP(KCCallbackProcPtr userRoutine) ;
+extern void
+DisposeKCCallbackUPP(KCCallbackUPP userUPP) ;
+extern OSStatus
+InvokeKCCallbackUPP(
+ KCEvent keychainEvent,
+ KCCallbackInfo * info,
+ void * userContext,
+ KCCallbackUPP userUPP) ;
+extern OSStatus
+KCFindAppleSharePassword(
+ AFPServerSignature * serverSignature,
+ StringPtr serverAddress,
+ StringPtr serverName,
+ StringPtr volumeName,
+ StringPtr accountName,
+ UInt32 maxLength,
+ void * passwordData,
+ UInt32 * actualLength,
+ KCItemRef * item) ;
+extern OSStatus
+KCFindInternetPassword(
+ StringPtr serverName,
+ StringPtr securityDomain,
+ StringPtr accountName,
+ UInt16 port,
+ OSType protocol,
+ OSType authType,
+ UInt32 maxLength,
+ void * passwordData,
+ UInt32 * actualLength,
+ KCItemRef * item) ;
+extern OSStatus
+KCFindInternetPasswordWithPath(
+ StringPtr serverName,
+ StringPtr securityDomain,
+ StringPtr accountName,
+ StringPtr path,
+ UInt16 port,
+ OSType protocol,
+ OSType authType,
+ UInt32 maxLength,
+ void * passwordData,
+ UInt32 * actualLength,
+ KCItemRef * item) ;
+extern OSStatus
+KCFindGenericPassword(
+ StringPtr serviceName,
+ StringPtr accountName,
+ UInt32 maxLength,
+ void * passwordData,
+ UInt32 * actualLength,
+ KCItemRef * item) ;
+extern OSStatus
+KCAddCallback(
+ KCCallbackUPP callbackProc,
+ KCEventMask eventMask,
+ void * userContext) ;
+extern OSStatus
+KCRemoveCallback(KCCallbackUPP callbackProc) ;
+extern OSStatus
+KCNewItem(
+ KCItemClass itemClass,
+ OSType itemCreator,
+ UInt32 length,
+ const void * data,
+ KCItemRef * item) ;
+extern OSStatus
+KCSetAttribute(
+ KCItemRef item,
+ KCAttribute * attr) ;
+extern OSStatus
+KCGetAttribute(
+ KCItemRef item,
+ KCAttribute * attr,
+ UInt32 * actualLength) ;
+extern OSStatus
+KCSetData(
+ KCItemRef item,
+ UInt32 length,
+ const void * data) ;
+extern OSStatus
+KCUpdateItem(KCItemRef item) ;
+extern OSStatus
+KCReleaseItem(KCItemRef * item) ;
+extern OSStatus
+KCCopyItem(
+ KCItemRef item,
+ KCRef destKeychain,
+ KCItemRef * copy) ;
+extern OSStatus
+KCFindFirstItem(
+ KCRef keychain,
+ const KCAttributeList * attrList,
+ KCSearchRef * search,
+ KCItemRef * item) ;
+extern OSStatus
+KCFindNextItem(
+ KCSearchRef search,
+ KCItemRef * item) ;
+extern OSStatus
+KCReleaseSearch(KCSearchRef * search) ;
+extern OSStatus
+KCDeleteItem(KCItemRef item) ;
+extern OSStatus
+KCGetData(
+ KCItemRef item,
+ UInt32 maxLength,
+ void * data,
+ UInt32 * actualLength) ;
+extern OSStatus
+KCLock(KCRef keychain) ;
+extern OSStatus
+kcgetkeychainname(
+ KCRef keychain,
+ char * keychainName) ;
+extern OSStatus
+kcfindapplesharepassword(
+ AFPServerSignature * serverSignature,
+ const char * serverAddress,
+ const char * serverName,
+ const char * volumeName,
+ const char * accountName,
+ UInt32 maxLength,
+ void * passwordData,
+ UInt32 * actualLength,
+ KCItemRef * item) ;
+extern OSStatus
+kcfindinternetpassword(
+ const char * serverName,
+ const char * securityDomain,
+ const char * accountName,
+ UInt16 port,
+ OSType protocol,
+ OSType authType,
+ UInt32 maxLength,
+ void * passwordData,
+ UInt32 * actualLength,
+ KCItemRef * item) ;
+extern OSStatus
+kcfindinternetpasswordwithpath(
+ const char * serverName,
+ const char * securityDomain,
+ const char * accountName,
+ const char * path,
+ UInt16 port,
+ OSType protocol,
+ OSType authType,
+ UInt32 maxLength,
+ void * passwordData,
+ UInt32 * actualLength,
+ KCItemRef * item) ;
+extern OSStatus
+kcfindgenericpassword(
+ const char * serviceName,
+ const char * accountName,
+ UInt32 maxLength,
+ void * passwordData,
+ UInt32 * actualLength,
+ KCItemRef * item) ;
+
+
+
+
+
+}
+
+
+
+
+
+extern double acos (double);
+extern double asin (double);
+extern double atan (double);
+extern double atan2 (double, double);
+extern double ceil (double);
+extern double cos (double);
+extern double cosh (double);
+extern double exp (double);
+extern double fabs (double);
+extern double floor (double);
+extern double fmod (double, double);
+extern double frexp (double, int *);
+extern double ldexp (double, int);
+extern double log10 (double);
+extern double log (double);
+extern double modf (double, double *);
+extern double pow (double, double);
+extern double sin (double);
+extern double sinh (double);
+extern double sqrt (double);
+extern double tan (double);
+extern double tanh (double);
+
+
+
+
+
+
+
+
+
+
+extern double acos (double);
+extern double asin (double);
+extern double atan (double);
+extern double atan2 (double, double);
+extern double ceil (double);
+extern double cos (double);
+extern double cosh (double);
+extern double exp (double);
+extern double fabs (double);
+extern double floor (double);
+extern double fmod (double, double);
+extern double frexp (double, int *);
+extern double ldexp (double, int);
+extern double log10 (double);
+extern double log (double);
+extern double modf (double, double *);
+extern double pow (double, double);
+extern double sin (double);
+extern double sinh (double);
+extern double sqrt (double);
+extern double tan (double);
+extern double tanh (double);
+
+
+
+extern "C" {
+
+
+
+
+
+extern const int kCFStreamErrorDomainSSL;
+extern const CFStringRef kCFStreamPropertySocketSecurityLevel;
+extern const CFStringRef kCFStreamSocketSecurityLevelNone;
+extern const CFStringRef kCFStreamSocketSecurityLevelSSLv2;
+extern const CFStringRef kCFStreamSocketSecurityLevelSSLv3;
+extern const CFStringRef kCFStreamSocketSecurityLevelTLSv1;
+extern const CFStringRef kCFStreamSocketSecurityLevelNegotiatedSSL;
+
+
+
+
+
+extern const int kCFStreamErrorDomainSOCKS;
+
+
+static __inline__
+SInt32 CFSocketStreamSOCKSGetErrorSubdomain(CFStreamError* error) {
+ return ((error->domain >> 16) & 0x0000FFFF);
+}
+
+static __inline__
+SInt32 CFSocketStreamSOCKSGetError(CFStreamError* error) {
+ return (error->domain & 0x0000FFFF);
+}
+
+
+enum {
+ kCFStreamErrorSOCKSSubDomainNone = 0,
+ kCFStreamErrorSOCKSSubDomainVersionCode,
+ kCFStreamErrorSOCKS4SubDomainResponse,
+ kCFStreamErrorSOCKS5SubDomainUserPass,
+ kCFStreamErrorSOCKS5SubDomainMethod,
+ kCFStreamErrorSOCKS5SubDomainResponse
+};
+
+enum {
+
+ kCFStreamErrorSOCKS5BadResponseAddr = 1,
+ kCFStreamErrorSOCKS5BadState,
+ kCFStreamErrorSOCKSUnknownClientVersion,
+
+
+ kCFStreamErrorSOCKS4RequestFailed = 91,
+ kCFStreamErrorSOCKS4IdentdFailed = 92,
+ kCFStreamErrorSOCKS4IdConflict = 93,
+
+
+ kSOCKS5NoAcceptableMethod = 0xFF
+};
+extern const CFStringRef kCFStreamPropertySOCKSProxy;
+extern const CFStringRef kCFStreamPropertySOCKSProxyHost;
+extern const CFStringRef kCFStreamPropertySOCKSProxyPort;
+extern const CFStringRef kCFStreamPropertySOCKSVersion;
+extern const CFStringRef kCFStreamSocketSOCKSVersion4;
+extern const CFStringRef kCFStreamSocketSOCKSVersion5;
+extern const CFStringRef kCFStreamPropertySOCKSUser;
+extern const CFStringRef kCFStreamPropertySOCKSPassword;
+extern const CFStringRef kCFStreamPropertyShouldCloseNativeSocket;
+typedef enum {
+ kCFStreamSocketSecurityNone = 0,
+ kCFStreamSocketSecuritySSLv2,
+ kCFStreamSocketSecuritySSLv3,
+ kCFStreamSocketSecuritySSLv23,
+ kCFStreamSocketSecurityTLSv1
+} CFStreamSocketSecurityProtocol;
+extern
+Boolean CFSocketStreamPairSetSecurityProtocol(CFReadStreamRef socketReadStream, CFWriteStreamRef socketWriteStream, CFStreamSocketSecurityProtocol securityProtocol);
+
+
+
+}
+extern "C" {
+
+
+extern const CFStringRef kCFHTTPVersion1_0;
+extern const CFStringRef kCFHTTPVersion1_1;
+extern const CFStringRef kCFHTTPAuthenticationSchemeBasic;
+extern const CFStringRef kCFHTTPAuthenticationSchemeDigest;
+
+typedef struct __CFHTTPMessage * CFHTTPMessageRef;
+
+extern
+CFTypeID CFHTTPMessageGetTypeID(void);
+
+extern
+CFHTTPMessageRef CFHTTPMessageCreateRequest(CFAllocatorRef allocator, CFStringRef requestMethod, CFURLRef url, CFStringRef httpVersion);
+
+
+extern
+CFHTTPMessageRef CFHTTPMessageCreateResponse(CFAllocatorRef allocator, int statusCode, CFStringRef statusDescription, CFStringRef httpVersion);
+
+
+extern
+CFHTTPMessageRef CFHTTPMessageCreateEmpty(CFAllocatorRef allocator, Boolean isRequest);
+
+extern
+CFHTTPMessageRef CFHTTPMessageCreateCopy(CFAllocatorRef allocator, CFHTTPMessageRef message);
+
+
+extern
+Boolean CFHTTPMessageIsRequest(CFHTTPMessageRef message);
+
+extern
+CFStringRef CFHTTPMessageCopyVersion(CFHTTPMessageRef message);
+
+extern
+CFDataRef CFHTTPMessageCopyBody(CFHTTPMessageRef message);
+
+extern
+void CFHTTPMessageSetBody(CFHTTPMessageRef message, CFDataRef bodyData);
+
+extern
+CFStringRef CFHTTPMessageCopyHeaderFieldValue(CFHTTPMessageRef message, CFStringRef headerField);
+
+extern
+CFDictionaryRef CFHTTPMessageCopyAllHeaderFields(CFHTTPMessageRef message);
+
+extern
+void CFHTTPMessageSetHeaderFieldValue(CFHTTPMessageRef message, CFStringRef headerField, CFStringRef value);
+
+
+extern
+Boolean CFHTTPMessageAppendBytes(CFHTTPMessageRef message, const UInt8 *newBytes, CFIndex numBytes);
+
+
+extern
+Boolean CFHTTPMessageIsHeaderComplete(CFHTTPMessageRef message);
+
+extern
+CFDataRef CFHTTPMessageCopySerializedMessage(CFHTTPMessageRef request);
+
+
+extern
+CFURLRef CFHTTPMessageCopyRequestURL(CFHTTPMessageRef request);
+
+extern
+CFStringRef CFHTTPMessageCopyRequestMethod(CFHTTPMessageRef request);
+
+
+
+
+
+
+extern
+Boolean CFHTTPMessageAddAuthentication(CFHTTPMessageRef request, CFHTTPMessageRef authenticationFailureResponse, CFStringRef username, CFStringRef password, CFStringRef authenticationScheme, Boolean forProxy);
+
+
+
+extern
+UInt32 CFHTTPMessageGetResponseStatusCode(CFHTTPMessageRef response);
+
+extern
+CFStringRef CFHTTPMessageCopyResponseStatusLine(CFHTTPMessageRef response);
+
+
+}
+extern "C" {
+
+
+extern
+const SInt32 kCFStreamErrorDomainHTTP;
+
+typedef enum {
+ kCFStreamErrorHTTPParseFailure = -1,
+ kCFStreamErrorHTTPRedirectionLoop = -2,
+ kCFStreamErrorHTTPBadURL = -3
+} CFStreamErrorHTTP;
+
+
+
+
+extern
+const CFStringRef kCFStreamPropertyHTTPResponseHeader;
+
+
+extern
+const CFStringRef kCFStreamPropertyHTTPFinalURL;
+
+
+
+
+
+
+
+extern const CFStringRef kCFStreamPropertyHTTPProxy;
+
+extern const CFStringRef kCFStreamPropertyHTTPProxyHost;
+extern const CFStringRef kCFStreamPropertyHTTPProxyPort;
+extern const CFStringRef kCFStreamPropertyHTTPSProxyHost;
+extern const CFStringRef kCFStreamPropertyHTTPSProxyPort;
+
+
+
+extern
+const CFStringRef kCFStreamPropertyHTTPShouldAutoredirect;
+
+
+extern
+const CFStringRef kCFStreamPropertyHTTPAttemptPersistentConnection;
+
+
+
+
+extern
+CFReadStreamRef CFReadStreamCreateForHTTPRequest(CFAllocatorRef alloc, CFHTTPMessageRef request);
+
+
+extern
+CFReadStreamRef CFReadStreamCreateForStreamedHTTPRequest(CFAllocatorRef alloc, CFHTTPMessageRef requestHeaders, CFReadStreamRef requestBody);
+
+extern
+void CFHTTPReadStreamSetRedirectsAutomatically(CFReadStreamRef httpStream, Boolean shouldAutoRedirect);
+
+extern
+void CFHTTPReadStreamSetProxy(CFReadStreamRef httpStream, CFStringRef proxyHost, CFIndex proxyPort);
+
+
+}
+extern "C" {
+extern
+const SInt32 kCFStreamErrorDomainNetServices;
+
+extern
+const SInt32 kCFStreamErrorDomainMach;
+
+
+typedef enum {
+ kCFNetServicesErrorUnknown = -72000,
+ kCFNetServicesErrorCollision = -72001,
+ kCFNetServicesErrorNotFound = -72002,
+ kCFNetServicesErrorInProgress = -72003,
+ kCFNetServicesErrorBadArgument = -72004,
+ kCFNetServicesErrorCancel = -72005,
+ kCFNetServicesErrorInvalid = -72006
+} CFNetServicesError;
+
+
+
+enum {
+ kCFNetServiceFlagMoreComing = 1,
+ kCFNetServiceFlagIsDomain = 2,
+ kCFNetServiceFlagIsRegistrationDomain = 4,
+ kCFNetServiceFlagRemove = 8
+};
+
+
+typedef struct {
+ CFIndex version;
+ void *info;
+ void *(*retain)(void *info);
+ void (*release)(void *info);
+ CFStringRef (*copyDescription)(void *info);
+} CFNetServiceClientContext;
+
+
+typedef struct __CFNetService* CFNetServiceRef;
+typedef void (*CFNetServiceClientCallBack)(CFNetServiceRef theService, CFStreamError* error, void* info);
+
+typedef struct __CFNetServiceBrowser* CFNetServiceBrowserRef;
+typedef void (*CFNetServiceBrowserClientCallBack)(CFNetServiceBrowserRef browser, CFOptionFlags flags, CFTypeRef domainOrService, CFStreamError* error, void* info);
+
+
+extern
+CFTypeID CFNetServiceGetTypeID(void);
+
+extern
+CFTypeID CFNetServiceBrowserGetTypeID(void);
+extern
+CFNetServiceRef CFNetServiceCreate(CFAllocatorRef alloc,
+ CFStringRef domain,
+ CFStringRef type,
+ CFStringRef name,
+ UInt32 port);
+extern
+CFStringRef CFNetServiceGetDomain(CFNetServiceRef theService);
+extern
+CFStringRef CFNetServiceGetType(CFNetServiceRef theService);
+extern
+CFStringRef CFNetServiceGetName(CFNetServiceRef theService);
+extern
+CFArrayRef CFNetServiceGetAddressing(CFNetServiceRef theService);
+extern
+CFStringRef CFNetServiceGetProtocolSpecificInformation(CFNetServiceRef theService);
+extern
+void CFNetServiceSetProtocolSpecificInformation(CFNetServiceRef theService, CFStringRef theInfo);
+extern
+Boolean CFNetServiceRegister(CFNetServiceRef theService, CFStreamError* error);
+extern
+Boolean CFNetServiceResolve(CFNetServiceRef theService, CFStreamError* error);
+extern
+void CFNetServiceCancel(CFNetServiceRef theService);
+extern
+Boolean CFNetServiceSetClient(CFNetServiceRef theService,
+ CFNetServiceClientCallBack clientCB,
+ CFNetServiceClientContext* clientContext);
+extern
+void CFNetServiceScheduleWithRunLoop(CFNetServiceRef theService,
+ CFRunLoopRef runLoop,
+ CFStringRef runLoopMode);
+extern
+void CFNetServiceUnscheduleFromRunLoop(CFNetServiceRef theService,
+ CFRunLoopRef runLoop,
+ CFStringRef runLoopMode);
+extern
+CFNetServiceBrowserRef CFNetServiceBrowserCreate(CFAllocatorRef alloc,
+ CFNetServiceBrowserClientCallBack clientCB,
+ CFNetServiceClientContext* clientContext);
+extern
+void CFNetServiceBrowserInvalidate(CFNetServiceBrowserRef browser);
+extern
+Boolean CFNetServiceBrowserSearchForDomains(CFNetServiceBrowserRef browser,
+ Boolean registrationDomains,
+ CFStreamError* error);
+extern
+Boolean CFNetServiceBrowserSearchForServices(CFNetServiceBrowserRef browser,
+ CFStringRef domain,
+ CFStringRef type,
+ CFStreamError* error);
+extern
+void CFNetServiceBrowserStopSearch(CFNetServiceBrowserRef browser, CFStreamError* error);
+extern
+void CFNetServiceBrowserScheduleWithRunLoop(CFNetServiceBrowserRef browser,
+ CFRunLoopRef runLoop,
+ CFStringRef runLoopMode);
+extern
+void CFNetServiceBrowserUnscheduleFromRunLoop(CFNetServiceBrowserRef browser,
+ CFRunLoopRef runLoop,
+ CFStringRef runLoopMode);
+
+
+
+
+}
+
+
+
+
+
+
+
+
+
+extern double acos (double);
+extern double asin (double);
+extern double atan (double);
+extern double atan2 (double, double);
+extern double ceil (double);
+extern double cos (double);
+extern double cosh (double);
+extern double exp (double);
+extern double fabs (double);
+extern double floor (double);
+extern double fmod (double, double);
+extern double frexp (double, int *);
+extern double ldexp (double, int);
+extern double log10 (double);
+extern double log (double);
+extern double modf (double, double *);
+extern double pow (double, double);
+extern double sin (double);
+extern double sinh (double);
+extern double sqrt (double);
+extern double tan (double);
+extern double tanh (double);
+
+
+
+
+
+
+extern "C" {
+
+
+
+
+
+
+
+enum {
+ errWSInternalError = -65793L,
+ errWSTransportError = -65794L,
+ errWSParseError = -65795L,
+ errWSTimeoutError = -65796L
+};
+enum WSTypeID {
+
+
+
+
+ eWSUnknownType = 0,
+
+
+
+
+ eWSNullType = 1,
+
+
+
+
+ eWSBooleanType = 2,
+
+
+
+
+ eWSIntegerType = 3,
+
+
+
+
+ eWSDoubleType = 4,
+
+
+
+
+ eWSStringType = 5,
+
+
+
+
+ eWSDateType = 6,
+
+
+
+
+ eWSDataType = 7,
+
+
+
+
+ eWSArrayType = 8,
+
+
+
+
+ eWSDictionaryType = 9
+};
+typedef enum WSTypeID WSTypeID;
+extern WSTypeID
+WSGetWSTypeIDFromCFType(CFTypeRef ref) ;
+extern CFTypeID
+WSGetCFTypeIDFromWSTypeID(WSTypeID typeID) ;
+
+
+typedef void * ( * WSClientContextRetainCallBackProcPtr)(void * info);
+typedef void ( * WSClientContextReleaseCallBackProcPtr)(void * info);
+typedef CFStringRef ( * WSClientContextCopyDescriptionCallBackProcPtr)(void * info);
+struct WSClientContext {
+
+
+
+
+ CFIndex version;
+
+
+
+
+ void * info;
+
+
+
+
+ WSClientContextRetainCallBackProcPtr retain;
+
+
+
+
+ WSClientContextReleaseCallBackProcPtr release;
+
+
+
+
+ WSClientContextCopyDescriptionCallBackProcPtr copyDescription;
+};
+typedef struct WSClientContext WSClientContext;
+extern CFStringRef kWSXMLRPCProtocol;
+extern CFStringRef kWSSOAP1999Protocol;
+extern CFStringRef kWSSOAP2001Protocol;
+extern CFStringRef kWSMethodInvocationResult;
+
+
+
+extern CFStringRef kWSFaultString;
+extern CFStringRef kWSFaultCode;
+extern CFStringRef kWSFaultExtra;
+extern CFStringRef kWSNetworkStreamFaultString;
+extern CFStringRef kWSStreamErrorMessage;
+extern CFStringRef kWSStreamErrorDomain;
+extern CFStringRef kWSStreamErrorError;
+extern CFStringRef kWSHTTPMessage;
+extern CFStringRef kWSHTTPResponseMessage;
+
+
+
+
+
+extern CFStringRef kWSHTTPVersion;
+extern CFStringRef kWSHTTPExtraHeaders;
+extern CFStringRef kWSHTTPProxy;
+extern CFStringRef kWSHTTPFollowsRedirects;
+extern CFStringRef kWSDebugOutgoingHeaders;
+extern CFStringRef kWSDebugOutgoingBody;
+extern CFStringRef kWSDebugIncomingHeaders;
+extern CFStringRef kWSDebugIncomingBody;
+
+
+
+
+
+extern CFStringRef kWSSOAPMethodNamespaceURI;
+extern CFStringRef kWSSOAPBodyEncodingStyle;
+extern CFStringRef kWSSOAPStyleDoc;
+extern CFStringRef kWSSOAPStyleRPC;
+
+
+
+
+
+
+
+extern CFStringRef kWSSOAPMessageHeaders;
+
+
+
+
+
+extern CFStringRef kWSRecordParameterOrder;
+extern CFStringRef kWSRecordNamespaceURI;
+extern CFStringRef kWSRecordType;
+
+
+
+
+
+extern CFStringRef kWSMethodInvocationResultParameterName;
+
+
+
+
+
+
+extern CFStringRef kWSMethodInvocationTimeoutValue;
+typedef struct OpaqueWSMethodInvocationRef* WSMethodInvocationRef;
+extern CFTypeID
+WSMethodInvocationGetTypeID(void) ;
+extern WSMethodInvocationRef
+WSMethodInvocationCreate(
+ CFURLRef url,
+ CFStringRef methodName,
+ CFStringRef protocol) ;
+extern WSMethodInvocationRef
+WSMethodInvocationCreateFromSerialization(CFDataRef contract) ;
+extern CFDataRef
+WSMethodInvocationCopySerialization(WSMethodInvocationRef invocation) ;
+extern void
+WSMethodInvocationSetParameters(
+ WSMethodInvocationRef invocation,
+ CFDictionaryRef parameters,
+ CFArrayRef parameterOrder) ;
+extern CFDictionaryRef
+WSMethodInvocationCopyParameters(
+ WSMethodInvocationRef invocation,
+ CFArrayRef * parameterOrder) ;
+extern void
+WSMethodInvocationSetProperty(
+ WSMethodInvocationRef invocation,
+ CFStringRef propertyName,
+ CFTypeRef propertyValue) ;
+extern CFTypeRef
+WSMethodInvocationCopyProperty(
+ WSMethodInvocationRef invocation,
+ CFStringRef propertyName) ;
+extern CFDictionaryRef
+WSMethodInvocationInvoke(WSMethodInvocationRef invocation) ;
+typedef void ( * WSMethodInvocationCallBackProcPtr)(WSMethodInvocationRef invocation, void *info, CFDictionaryRef outRef);
+extern void
+WSMethodInvocationSetCallBack(
+ WSMethodInvocationRef invocation,
+ WSMethodInvocationCallBackProcPtr clientCB,
+ WSClientContext * context) ;
+extern void
+WSMethodInvocationScheduleWithRunLoop(
+ WSMethodInvocationRef invocation,
+ CFRunLoopRef runLoop,
+ CFStringRef runLoopMode) ;
+extern void
+WSMethodInvocationUnscheduleFromRunLoop(
+ WSMethodInvocationRef invocation,
+ CFRunLoopRef runLoop,
+ CFStringRef runLoopMode) ;
+extern Boolean
+WSMethodResultIsFault(CFDictionaryRef methodResult) ;
+typedef CFStringRef ( * WSMethodInvocationSerializationProcPtr)(WSMethodInvocationRef invocation, CFTypeRef obj, void *info);
+extern void
+WSMethodInvocationAddSerializationOverride(
+ WSMethodInvocationRef invocation,
+ CFTypeID objType,
+ WSMethodInvocationSerializationProcPtr serializationProc,
+ WSClientContext * context) ;
+typedef CFTypeRef ( * WSMethodInvocationDeserializationProcPtr)(WSMethodInvocationRef invocation, CFXMLTreeRef msgRoot, CFXMLTreeRef deserializeRoot, void *info);
+extern void
+WSMethodInvocationAddDeserializationOverride(
+ WSMethodInvocationRef invocation,
+ CFStringRef typeNamespace,
+ CFStringRef typeName,
+ WSMethodInvocationDeserializationProcPtr deserializationProc,
+ WSClientContext * context) ;
+
+
+
+
+
+
+
+
+
+}
+
+
+
+enum {
+ kAllTypographicFeaturesType = 0,
+ kLigaturesType = 1,
+ kCursiveConnectionType = 2,
+ kLetterCaseType = 3,
+ kVerticalSubstitutionType = 4,
+ kLinguisticRearrangementType = 5,
+ kNumberSpacingType = 6,
+ kSmartSwashType = 8,
+ kDiacriticsType = 9,
+ kVerticalPositionType = 10,
+ kFractionsType = 11,
+ kOverlappingCharactersType = 13,
+ kTypographicExtrasType = 14,
+ kMathematicalExtrasType = 15,
+ kOrnamentSetsType = 16,
+ kCharacterAlternativesType = 17,
+ kDesignComplexityType = 18,
+ kStyleOptionsType = 19,
+ kCharacterShapeType = 20,
+ kNumberCaseType = 21,
+ kTextSpacingType = 22,
+ kTransliterationType = 23,
+ kAnnotationType = 24,
+ kKanaSpacingType = 25,
+ kIdeographicSpacingType = 26,
+ kUnicodeDecompositionType = 27,
+ kRubyKanaType = 28,
+ kCJKSymbolAlternativesType = 29,
+ kIdeographicAlternativesType = 30,
+ kCJKVerticalRomanPlacementType = 31,
+ kItalicCJKRomanType = 32,
+ kCJKRomanSpacingType = 103,
+ kLastFeatureType = -1
+};
+
+
+
+
+
+
+enum {
+ kAllTypeFeaturesOnSelector = 0,
+ kAllTypeFeaturesOffSelector = 1
+};
+
+
+
+
+
+
+
+enum {
+ kRequiredLigaturesOnSelector = 0,
+ kRequiredLigaturesOffSelector = 1,
+ kCommonLigaturesOnSelector = 2,
+ kCommonLigaturesOffSelector = 3,
+ kRareLigaturesOnSelector = 4,
+ kRareLigaturesOffSelector = 5,
+ kLogosOnSelector = 6,
+ kLogosOffSelector = 7,
+ kRebusPicturesOnSelector = 8,
+ kRebusPicturesOffSelector = 9,
+ kDiphthongLigaturesOnSelector = 10,
+ kDiphthongLigaturesOffSelector = 11,
+ kSquaredLigaturesOnSelector = 12,
+ kSquaredLigaturesOffSelector = 13,
+ kAbbrevSquaredLigaturesOnSelector = 14,
+ kAbbrevSquaredLigaturesOffSelector = 15,
+ kSymbolLigaturesOnSelector = 16,
+ kSymbolLigaturesOffSelector = 17
+};
+
+
+
+
+
+
+enum {
+ kUnconnectedSelector = 0,
+ kPartiallyConnectedSelector = 1,
+ kCursiveSelector = 2
+};
+
+
+
+
+
+
+enum {
+ kUpperAndLowerCaseSelector = 0,
+ kAllCapsSelector = 1,
+ kAllLowerCaseSelector = 2,
+ kSmallCapsSelector = 3,
+ kInitialCapsSelector = 4,
+ kInitialCapsAndSmallCapsSelector = 5
+};
+
+
+
+
+
+
+enum {
+ kSubstituteVerticalFormsOnSelector = 0,
+ kSubstituteVerticalFormsOffSelector = 1
+};
+
+
+
+
+
+
+enum {
+ kLinguisticRearrangementOnSelector = 0,
+ kLinguisticRearrangementOffSelector = 1
+};
+
+
+
+
+
+
+enum {
+ kMonospacedNumbersSelector = 0,
+ kProportionalNumbersSelector = 1,
+ kThirdWidthNumbersSelector = 2,
+ kQuarterWidthNumbersSelector = 3
+};
+
+
+
+
+
+
+enum {
+ kWordInitialSwashesOnSelector = 0,
+ kWordInitialSwashesOffSelector = 1,
+ kWordFinalSwashesOnSelector = 2,
+ kWordFinalSwashesOffSelector = 3,
+ kLineInitialSwashesOnSelector = 4,
+ kLineInitialSwashesOffSelector = 5,
+ kLineFinalSwashesOnSelector = 6,
+ kLineFinalSwashesOffSelector = 7,
+ kNonFinalSwashesOnSelector = 8,
+ kNonFinalSwashesOffSelector = 9
+};
+
+
+
+
+
+
+enum {
+ kShowDiacriticsSelector = 0,
+ kHideDiacriticsSelector = 1,
+ kDecomposeDiacriticsSelector = 2
+};
+
+
+
+
+
+
+enum {
+ kNormalPositionSelector = 0,
+ kSuperiorsSelector = 1,
+ kInferiorsSelector = 2,
+ kOrdinalsSelector = 3
+};
+
+
+
+
+
+
+enum {
+ kNoFractionsSelector = 0,
+ kVerticalFractionsSelector = 1,
+ kDiagonalFractionsSelector = 2
+};
+
+
+
+
+
+
+enum {
+ kPreventOverlapOnSelector = 0,
+ kPreventOverlapOffSelector = 1
+};
+
+
+
+
+
+
+enum {
+ kHyphensToEmDashOnSelector = 0,
+ kHyphensToEmDashOffSelector = 1,
+ kHyphenToEnDashOnSelector = 2,
+ kHyphenToEnDashOffSelector = 3,
+ kSlashedZeroOnSelector = 4,
+ kSlashedZeroOffSelector = 5,
+ kFormInterrobangOnSelector = 6,
+ kFormInterrobangOffSelector = 7,
+ kSmartQuotesOnSelector = 8,
+ kSmartQuotesOffSelector = 9,
+ kPeriodsToEllipsisOnSelector = 10,
+ kPeriodsToEllipsisOffSelector = 11
+};
+
+
+
+
+
+
+enum {
+ kHyphenToMinusOnSelector = 0,
+ kHyphenToMinusOffSelector = 1,
+ kAsteriskToMultiplyOnSelector = 2,
+ kAsteriskToMultiplyOffSelector = 3,
+ kSlashToDivideOnSelector = 4,
+ kSlashToDivideOffSelector = 5,
+ kInequalityLigaturesOnSelector = 6,
+ kInequalityLigaturesOffSelector = 7,
+ kExponentsOnSelector = 8,
+ kExponentsOffSelector = 9
+};
+
+
+
+
+
+
+enum {
+ kNoOrnamentsSelector = 0,
+ kDingbatsSelector = 1,
+ kPiCharactersSelector = 2,
+ kFleuronsSelector = 3,
+ kDecorativeBordersSelector = 4,
+ kInternationalSymbolsSelector = 5,
+ kMathSymbolsSelector = 6
+};
+
+
+
+
+
+
+enum {
+ kNoAlternatesSelector = 0
+};
+
+
+
+
+
+
+enum {
+ kDesignLevel1Selector = 0,
+ kDesignLevel2Selector = 1,
+ kDesignLevel3Selector = 2,
+ kDesignLevel4Selector = 3,
+ kDesignLevel5Selector = 4
+};
+
+
+
+
+
+
+enum {
+ kNoStyleOptionsSelector = 0,
+ kDisplayTextSelector = 1,
+ kEngravedTextSelector = 2,
+ kIlluminatedCapsSelector = 3,
+ kTitlingCapsSelector = 4,
+ kTallCapsSelector = 5
+};
+
+
+
+
+
+
+enum {
+ kTraditionalCharactersSelector = 0,
+ kSimplifiedCharactersSelector = 1,
+ kJIS1978CharactersSelector = 2,
+ kJIS1983CharactersSelector = 3,
+ kJIS1990CharactersSelector = 4,
+ kTraditionalAltOneSelector = 5,
+ kTraditionalAltTwoSelector = 6,
+ kTraditionalAltThreeSelector = 7,
+ kTraditionalAltFourSelector = 8,
+ kTraditionalAltFiveSelector = 9,
+ kExpertCharactersSelector = 10
+};
+
+
+
+
+
+
+enum {
+ kLowerCaseNumbersSelector = 0,
+ kUpperCaseNumbersSelector = 1
+};
+
+
+
+
+
+
+enum {
+ kProportionalTextSelector = 0,
+ kMonospacedTextSelector = 1,
+ kHalfWidthTextSelector = 2
+};
+
+
+
+
+
+
+enum {
+ kNoTransliterationSelector = 0,
+ kHanjaToHangulSelector = 1,
+ kHiraganaToKatakanaSelector = 2,
+ kKatakanaToHiraganaSelector = 3,
+ kKanaToRomanizationSelector = 4,
+ kRomanizationToHiraganaSelector = 5,
+ kRomanizationToKatakanaSelector = 6,
+ kHanjaToHangulAltOneSelector = 7,
+ kHanjaToHangulAltTwoSelector = 8,
+ kHanjaToHangulAltThreeSelector = 9
+};
+
+
+
+
+
+
+enum {
+ kNoAnnotationSelector = 0,
+ kBoxAnnotationSelector = 1,
+ kRoundedBoxAnnotationSelector = 2,
+ kCircleAnnotationSelector = 3,
+ kInvertedCircleAnnotationSelector = 4,
+ kParenthesisAnnotationSelector = 5,
+ kPeriodAnnotationSelector = 6,
+ kRomanNumeralAnnotationSelector = 7,
+ kDiamondAnnotationSelector = 8,
+ kInvertedBoxAnnotationSelector = 9,
+ kInvertedRoundedBoxAnnotationSelector = 10
+};
+
+
+
+
+
+
+enum {
+ kFullWidthKanaSelector = 0,
+ kProportionalKanaSelector = 1
+};
+
+
+
+
+
+
+enum {
+ kFullWidthIdeographsSelector = 0,
+ kProportionalIdeographsSelector = 1,
+ kHalfWidthIdeographsSelector = 2
+};
+
+
+
+
+
+
+enum {
+ kCanonicalCompositionOnSelector = 0,
+ kCanonicalCompositionOffSelector = 1,
+ kCompatibilityCompositionOnSelector = 2,
+ kCompatibilityCompositionOffSelector = 3,
+ kTranscodingCompositionOnSelector = 4,
+ kTranscodingCompositionOffSelector = 5
+};
+
+
+
+
+
+
+enum {
+ kNoRubyKanaSelector = 0,
+ kRubyKanaSelector = 1
+};
+
+
+
+
+
+
+enum {
+ kNoCJKSymbolAlternativesSelector = 0,
+ kCJKSymbolAltOneSelector = 1,
+ kCJKSymbolAltTwoSelector = 2,
+ kCJKSymbolAltThreeSelector = 3,
+ kCJKSymbolAltFourSelector = 4,
+ kCJKSymbolAltFiveSelector = 5
+};
+
+
+
+
+
+
+enum {
+ kNoIdeographicAlternativesSelector = 0,
+ kIdeographicAltOneSelector = 1,
+ kIdeographicAltTwoSelector = 2,
+ kIdeographicAltThreeSelector = 3,
+ kIdeographicAltFourSelector = 4,
+ kIdeographicAltFiveSelector = 5
+};
+
+
+
+
+
+
+enum {
+ kCJKVerticalRomanCenteredSelector = 0,
+ kCJKVerticalRomanHBaselineSelector = 1
+};
+
+
+
+
+
+
+enum {
+ kNoCJKItalicRomanSelector = 0,
+ kCJKItalicRomanSelector = 1
+};
+
+
+
+
+
+
+enum {
+ kHalfWidthCJKRomanSelector = 0,
+ kProportionalCJKRomanSelector = 1,
+ kDefaultCJKRomanSelector = 2,
+ kFullWidthCJKRomanSelector = 3
+};
+
+
+
+
+
+enum {
+ kSFNTLookupSimpleArray = 0,
+ kSFNTLookupSegmentSingle = 2,
+ kSFNTLookupSegmentArray = 4,
+ kSFNTLookupSingleTable = 6,
+ kSFNTLookupTrimmedArray = 8
+};
+
+typedef UInt16 SFNTLookupTableFormat;
+typedef UInt16 SFNTLookupValue;
+typedef UInt16 SFNTLookupOffset;
+typedef UInt32 SFNTLookupKind;
+
+
+
+
+
+
+struct SFNTLookupBinarySearchHeader {
+ UInt16 unitSize;
+ UInt16 nUnits;
+ UInt16 searchRange;
+ UInt16 entrySelector;
+ UInt16 rangeShift;
+};
+typedef struct SFNTLookupBinarySearchHeader SFNTLookupBinarySearchHeader;
+
+struct SFNTLookupArrayHeader {
+ SFNTLookupValue lookupValues[1];
+};
+typedef struct SFNTLookupArrayHeader SFNTLookupArrayHeader;
+
+struct SFNTLookupTrimmedArrayHeader {
+ UInt16 firstGlyph;
+ UInt16 count;
+ SFNTLookupValue valueArray[1];
+};
+typedef struct SFNTLookupTrimmedArrayHeader SFNTLookupTrimmedArrayHeader;
+
+
+
+
+
+
+struct SFNTLookupSegment {
+ UInt16 lastGlyph;
+ UInt16 firstGlyph;
+ UInt16 value[1];
+};
+typedef struct SFNTLookupSegment SFNTLookupSegment;
+struct SFNTLookupSegmentHeader {
+ SFNTLookupBinarySearchHeader binSearch;
+ SFNTLookupSegment segments[1];
+};
+typedef struct SFNTLookupSegmentHeader SFNTLookupSegmentHeader;
+
+struct SFNTLookupSingle {
+ UInt16 glyph;
+ UInt16 value[1];
+};
+typedef struct SFNTLookupSingle SFNTLookupSingle;
+struct SFNTLookupSingleHeader {
+ SFNTLookupBinarySearchHeader binSearch;
+ SFNTLookupSingle entries[1];
+};
+typedef struct SFNTLookupSingleHeader SFNTLookupSingleHeader;
+
+union SFNTLookupFormatSpecificHeader {
+ SFNTLookupArrayHeader theArray;
+ SFNTLookupSegmentHeader segment;
+ SFNTLookupSingleHeader single;
+ SFNTLookupTrimmedArrayHeader trimmedArray;
+};
+typedef union SFNTLookupFormatSpecificHeader SFNTLookupFormatSpecificHeader;
+
+struct SFNTLookupTable {
+ SFNTLookupTableFormat format;
+ SFNTLookupFormatSpecificHeader fsHeader;
+};
+typedef struct SFNTLookupTable SFNTLookupTable;
+typedef SFNTLookupTable * SFNTLookupTablePtr;
+typedef SFNTLookupTablePtr * SFNTLookupTableHandle;
+
+
+enum {
+ kSTClassEndOfText = 0,
+ kSTClassOutOfBounds = 1,
+ kSTClassDeletedGlyph = 2,
+ kSTClassEndOfLine = 3,
+ kSTSetMark = 0x8000,
+ kSTNoAdvance = 0x4000,
+ kSTMarkEnd = 0x2000,
+ kSTLigActionMask = 0x3FFF,
+ kSTRearrVerbMask = 0x000F
+};
+
+typedef UInt8 STClass;
+typedef UInt8 STEntryIndex;
+struct STHeader {
+ UInt8 filler;
+ STClass nClasses;
+ UInt16 classTableOffset;
+ UInt16 stateArrayOffset;
+ UInt16 entryTableOffset;
+};
+typedef struct STHeader STHeader;
+struct STClassTable {
+ UInt16 firstGlyph;
+ UInt16 nGlyphs;
+ STClass classes[1];
+};
+typedef struct STClassTable STClassTable;
+struct STEntryZero {
+ UInt16 newState;
+ UInt16 flags;
+};
+typedef struct STEntryZero STEntryZero;
+struct STEntryOne {
+ UInt16 newState;
+ UInt16 flags;
+ UInt16 offset1;
+};
+typedef struct STEntryOne STEntryOne;
+struct STEntryTwo {
+ UInt16 newState;
+ UInt16 flags;
+ UInt16 offset1;
+ UInt16 offset2;
+};
+typedef struct STEntryTwo STEntryTwo;
+
+
+enum {
+ kSTXHasLigAction = 0x2000
+};
+
+
+typedef UInt16 STXClass;
+typedef UInt16 STXStateIndex;
+typedef UInt16 STXEntryIndex;
+struct STXHeader {
+ UInt32 nClasses;
+ UInt32 classTableOffset;
+ UInt32 stateArrayOffset;
+ UInt32 entryTableOffset;
+};
+typedef struct STXHeader STXHeader;
+
+typedef SFNTLookupTable STXClassTable;
+struct STXEntryZero {
+ STXStateIndex newState;
+ UInt16 flags;
+};
+typedef struct STXEntryZero STXEntryZero;
+struct STXEntryOne {
+ STXStateIndex newState;
+ UInt16 flags;
+ UInt16 index1;
+};
+typedef struct STXEntryOne STXEntryOne;
+struct STXEntryTwo {
+ STXStateIndex newState;
+ UInt16 flags;
+ UInt16 index1;
+ UInt16 index2;
+};
+typedef struct STXEntryTwo STXEntryTwo;
+
+
+
+enum {
+ kLCARTag = 0x6C636172,
+ kLCARCurrentVersion = 0x00010000,
+ kLCARLinearFormat = 0,
+ kLCARCtlPointFormat = 1
+};
+
+
+struct LcarCaretClassEntry {
+ UInt16 count;
+ UInt16 partials[1];
+};
+typedef struct LcarCaretClassEntry LcarCaretClassEntry;
+struct LcarCaretTable {
+ Fixed version;
+ UInt16 format;
+ SFNTLookupTable lookup;
+};
+typedef struct LcarCaretTable LcarCaretTable;
+typedef LcarCaretTable * LcarCaretTablePtr;
+
+
+
+enum {
+ kJUSTTag = 0x6A757374,
+ kJUSTCurrentVersion = 0x00010000,
+ kJUSTStandardFormat = 0,
+ kJUSTnoGlyphcode = 0xFFFF,
+ kJUSTpcDecompositionAction = 0,
+ kJUSTpcUnconditionalAddAction = 1,
+ kJUSTpcConditionalAddAction = 2,
+ kJUSTpcGlyphStretchAction = 3,
+ kJUSTpcDuctilityAction = 4,
+ kJUSTpcGlyphRepeatAddAction = 5
+};
+
+
+enum {
+ kJUSTKashidaPriority = 0,
+ kJUSTSpacePriority = 1,
+ kJUSTLetterPriority = 2,
+ kJUSTNullPriority = 3,
+ kJUSTPriorityCount = 4
+};
+
+
+enum {
+ kJUSTOverridePriority = 0x8000,
+ kJUSTOverrideLimits = 0x4000,
+ kJUSTOverrideUnlimited = 0x2000,
+ kJUSTUnlimited = 0x1000,
+ kJUSTPriorityMask = 0x0003
+};
+
+
+typedef UInt16 JustPCActionType;
+typedef UInt16 JustificationFlags;
+
+struct JustPCDecompositionAction {
+ Fixed lowerLimit;
+ Fixed upperLimit;
+ UInt16 order;
+ UInt16 count;
+ UInt16 glyphs[1];
+};
+typedef struct JustPCDecompositionAction JustPCDecompositionAction;
+
+
+typedef UInt16 JustPCUnconditionalAddAction;
+
+
+
+
+
+struct JustPCConditionalAddAction {
+ Fixed substThreshhold;
+ UInt16 addGlyph;
+ UInt16 substGlyph;
+};
+typedef struct JustPCConditionalAddAction JustPCConditionalAddAction;
+
+struct JustPCDuctilityAction {
+ UInt32 ductilityAxis;
+ Fixed minimumLimit;
+ Fixed noStretchValue;
+ Fixed maximumLimit;
+};
+typedef struct JustPCDuctilityAction JustPCDuctilityAction;
+
+
+
+
+
+struct JustPCGlyphRepeatAddAction {
+ UInt16 flags;
+ UInt16 glyph;
+};
+typedef struct JustPCGlyphRepeatAddAction JustPCGlyphRepeatAddAction;
+
+struct JustPCActionSubrecord {
+ UInt16 theClass;
+ JustPCActionType theType;
+ UInt32 length;
+ UInt32 data;
+};
+typedef struct JustPCActionSubrecord JustPCActionSubrecord;
+
+struct JustPCAction {
+ UInt32 actionCount;
+ JustPCActionSubrecord actions[1];
+};
+typedef struct JustPCAction JustPCAction;
+
+
+
+
+struct JustWidthDeltaEntry {
+ UInt32 justClass;
+ Fixed beforeGrowLimit;
+ Fixed beforeShrinkLimit;
+ Fixed afterGrowLimit;
+ Fixed afterShrinkLimit;
+ JustificationFlags growFlags;
+ JustificationFlags shrinkFlags;
+};
+typedef struct JustWidthDeltaEntry JustWidthDeltaEntry;
+struct JustWidthDeltaGroup {
+ UInt32 count;
+ JustWidthDeltaEntry entries[1];
+};
+typedef struct JustWidthDeltaGroup JustWidthDeltaGroup;
+
+struct JustPostcompTable {
+ SFNTLookupTable lookupTable;
+
+};
+typedef struct JustPostcompTable JustPostcompTable;
+struct JustDirectionTable {
+ UInt16 justClass;
+ UInt16 widthDeltaClusters;
+ UInt16 postcomp;
+ SFNTLookupTable lookup;
+};
+typedef struct JustDirectionTable JustDirectionTable;
+struct JustTable {
+ Fixed version;
+ UInt16 format;
+ UInt16 horizHeaderOffset;
+ UInt16 vertHeaderOffset;
+};
+typedef struct JustTable JustTable;
+
+
+
+enum {
+ kOPBDTag = 0x6F706264,
+ kOPBDCurrentVersion = 0x00010000,
+ kOPBDDistanceFormat = 0,
+ kOPBDControlPointFormat = 1
+};
+
+
+
+typedef UInt16 OpbdTableFormat;
+
+
+
+
+
+struct OpbdSideValues {
+ SInt16 leftSideShift;
+ SInt16 topSideShift;
+ SInt16 rightSideShift;
+ SInt16 bottomSideShift;
+};
+typedef struct OpbdSideValues OpbdSideValues;
+struct OpbdTable {
+ Fixed version;
+ OpbdTableFormat format;
+ SFNTLookupTable lookupTable;
+};
+typedef struct OpbdTable OpbdTable;
+
+
+
+enum {
+ kMORTTag = 0x6D6F7274,
+ kMORTCurrentVersion = 0x00010000,
+
+ kMORTCoverVertical = 0x8000,
+ kMORTCoverDescending = 0x4000,
+ kMORTCoverIgnoreVertical = 0x2000,
+ kMORTCoverTypeMask = 0x000F,
+ kMORTRearrangementType = 0,
+ kMORTContextualType = 1,
+ kMORTLigatureType = 2,
+ kMORTSwashType = 4,
+ kMORTInsertionType = 5,
+ kMORTLigLastAction = (long)0x80000000,
+ kMORTLigStoreLigature = 0x40000000,
+ kMORTLigFormOffsetMask = 0x3FFFFFFF,
+ kMORTLigFormOffsetShift = 2,
+ kMORTraNoAction = 0,
+ kMORTraxA = 1,
+ kMORTraDx = 2,
+ kMORTraDxA = 3,
+ kMORTraxAB = 4,
+ kMORTraxBA = 5,
+ kMORTraCDx = 6,
+ kMORTraDCx = 7,
+ kMORTraCDxA = 8,
+ kMORTraDCxA = 9,
+ kMORTraDxAB = 10,
+ kMORTraDxBA = 11,
+ kMORTraCDxAB = 12,
+ kMORTraCDxBA = 13,
+ kMORTraDCxAB = 14,
+ kMORTraDCxBA = 15,
+
+ kMORTDoInsertionsBefore = 0x80,
+ kMORTIsSplitVowelPiece = 0x40,
+ kMORTInsertionsCountMask = 0x3F,
+ kMORTCurrInsertKashidaLike = 0x2000,
+ kMORTMarkInsertKashidaLike = 0x1000,
+ kMORTCurrInsertBefore = 0x0800,
+ kMORTMarkInsertBefore = 0x0400,
+ kMORTMarkJustTableCountMask = 0x3F80,
+ kMORTMarkJustTableCountShift = 7,
+ kMORTCurrJustTableCountMask = 0x007F,
+ kMORTCurrJustTableCountShift = 0,
+ kMORTCurrInsertCountMask = 0x03E0,
+ kMORTCurrInsertCountShift = 5,
+ kMORTMarkInsertCountMask = 0x001F,
+ kMORTMarkInsertCountShift = 0
+};
+
+
+
+typedef UInt32 MortSubtableMaskFlags;
+typedef UInt32 MortLigatureActionEntry;
+struct MortRearrangementSubtable {
+ STHeader header;
+};
+typedef struct MortRearrangementSubtable MortRearrangementSubtable;
+struct MortContextualSubtable {
+ STHeader header;
+ UInt16 substitutionTableOffset;
+};
+typedef struct MortContextualSubtable MortContextualSubtable;
+struct MortLigatureSubtable {
+ STHeader header;
+ UInt16 ligatureActionTableOffset;
+ UInt16 componentTableOffset;
+ UInt16 ligatureTableOffset;
+};
+typedef struct MortLigatureSubtable MortLigatureSubtable;
+struct MortSwashSubtable {
+ SFNTLookupTable lookup;
+};
+typedef struct MortSwashSubtable MortSwashSubtable;
+struct MortInsertionSubtable {
+ STHeader header;
+};
+typedef struct MortInsertionSubtable MortInsertionSubtable;
+union MortSpecificSubtable {
+ MortRearrangementSubtable rearrangement;
+ MortContextualSubtable contextual;
+ MortLigatureSubtable ligature;
+ MortSwashSubtable swash;
+ MortInsertionSubtable insertion;
+};
+typedef union MortSpecificSubtable MortSpecificSubtable;
+struct MortSubtable {
+ UInt16 length;
+ UInt16 coverage;
+ MortSubtableMaskFlags flags;
+ MortSpecificSubtable u;
+};
+typedef struct MortSubtable MortSubtable;
+struct MortFeatureEntry {
+ UInt16 featureType;
+ UInt16 featureSelector;
+ MortSubtableMaskFlags enableFlags;
+ MortSubtableMaskFlags disableFlags;
+};
+typedef struct MortFeatureEntry MortFeatureEntry;
+struct MortChain {
+ MortSubtableMaskFlags defaultFlags;
+ UInt32 length;
+ UInt16 nFeatures;
+ UInt16 nSubtables;
+ MortFeatureEntry featureEntries[1];
+
+};
+typedef struct MortChain MortChain;
+struct MortTable {
+ Fixed version;
+ UInt32 nChains;
+ MortChain chains[1];
+};
+typedef struct MortTable MortTable;
+
+
+
+enum {
+ kMORXTag = 0x6D6F7278,
+ kMORXCurrentVersion = 0x00020000,
+
+ kMORXCoverVertical = (long)0x80000000,
+ kMORXCoverDescending = 0x40000000,
+ kMORXCoverIgnoreVertical = 0x20000000,
+ kMORXCoverTypeMask = 0x000000FF
+};
+
+
+struct MorxRearrangementSubtable {
+ STXHeader header;
+};
+typedef struct MorxRearrangementSubtable MorxRearrangementSubtable;
+struct MorxContextualSubtable {
+ STXHeader header;
+ UInt32 substitutionTableOffset;
+};
+typedef struct MorxContextualSubtable MorxContextualSubtable;
+struct MorxLigatureSubtable {
+ STXHeader header;
+ UInt32 ligatureActionTableOffset;
+ UInt32 componentTableOffset;
+ UInt32 ligatureTableOffset;
+};
+typedef struct MorxLigatureSubtable MorxLigatureSubtable;
+struct MorxInsertionSubtable {
+ STXHeader header;
+ UInt32 insertionGlyphTableOffset;
+};
+typedef struct MorxInsertionSubtable MorxInsertionSubtable;
+union MorxSpecificSubtable {
+ MorxRearrangementSubtable rearrangement;
+ MorxContextualSubtable contextual;
+ MorxLigatureSubtable ligature;
+ MortSwashSubtable swash;
+ MorxInsertionSubtable insertion;
+};
+typedef union MorxSpecificSubtable MorxSpecificSubtable;
+struct MorxSubtable {
+ UInt32 length;
+ UInt32 coverage;
+ MortSubtableMaskFlags flags;
+ MorxSpecificSubtable u;
+};
+typedef struct MorxSubtable MorxSubtable;
+struct MorxChain {
+ MortSubtableMaskFlags defaultFlags;
+ UInt32 length;
+ UInt32 nFeatures;
+ UInt32 nSubtables;
+ MortFeatureEntry featureEntries[1];
+
+};
+typedef struct MorxChain MorxChain;
+struct MorxTable {
+ Fixed version;
+ UInt32 nChains;
+ MorxChain chains[1];
+};
+typedef struct MorxTable MorxTable;
+
+
+
+enum {
+ kPROPTag = 0x70726F70,
+ kPROPCurrentVersion = 0x00030000,
+ kPROPPairOffsetShift = 8,
+ kPROPPairOffsetSign = 7,
+ kPROPIsFloaterMask = 0x8000,
+ kPROPCanHangLTMask = 0x4000,
+ kPROPCanHangRBMask = 0x2000,
+ kPROPUseRLPairMask = 0x1000,
+ kPROPPairOffsetMask = 0x0F00,
+ kPROPRightConnectMask = 0x0080,
+ kPROPZeroReserved = 0x0060,
+ kPROPDirectionMask = 0x001F
+};
+
+
+enum {
+ kPROPLDirectionClass = 0,
+ kPROPRDirectionClass = 1,
+ kPROPALDirectionClass = 2,
+ kPROPENDirectionClass = 3,
+ kPROPESDirectionClass = 4,
+ kPROPETDirectionClass = 5,
+ kPROPANDirectionClass = 6,
+ kPROPCSDirectionClass = 7,
+ kPROPPSDirectionClass = 8,
+ kPROPSDirectionClass = 9,
+ kPROPWSDirectionClass = 10,
+ kPROPONDirectionClass = 11,
+ kPROPSENDirectionClass = 12,
+ kPROPLREDirectionClass = 13,
+ kPROPLRODirectionClass = 14,
+ kPROPRLEDirectionClass = 15,
+ kPROPRLODirectionClass = 16,
+ kPROPPDFDirectionClass = 17,
+ kPROPNSMDirectionClass = 18,
+ kPROPBNDirectionClass = 19,
+ kPROPNumDirectionClasses = 20
+};
+
+
+
+typedef UInt16 PropCharProperties;
+struct PropTable {
+ Fixed version;
+ UInt16 format;
+ PropCharProperties defaultProps;
+ SFNTLookupTable lookup;
+};
+typedef struct PropTable PropTable;
+struct PropLookupSegment {
+ UInt16 lastGlyph;
+ UInt16 firstGlyph;
+ UInt16 value;
+};
+typedef struct PropLookupSegment PropLookupSegment;
+struct PropLookupSingle {
+ UInt16 glyph;
+ PropCharProperties props;
+};
+typedef struct PropLookupSingle PropLookupSingle;
+
+
+
+enum {
+ kTRAKTag = 0x7472616B,
+ kTRAKCurrentVersion = 0x00010000,
+ kTRAKUniformFormat = 0
+};
+
+
+
+typedef SInt16 TrakValue;
+struct TrakTableEntry {
+ Fixed track;
+ UInt16 nameTableIndex;
+ UInt16 sizesOffset;
+};
+typedef struct TrakTableEntry TrakTableEntry;
+struct TrakTableData {
+ UInt16 nTracks;
+ UInt16 nSizes;
+ UInt32 sizeTableOffset;
+ TrakTableEntry trakTable[1];
+};
+typedef struct TrakTableData TrakTableData;
+struct TrakTable {
+ Fixed version;
+ UInt16 format;
+ UInt16 horizOffset;
+ UInt16 vertOffset;
+};
+typedef struct TrakTable TrakTable;
+
+
+
+enum {
+ kKERNTag = 0x6B65726E,
+ kKERNCurrentVersion = 0x00010000,
+ kKERNVertical = 0x8000,
+ kKERNResetCrossStream = 0x8000,
+ kKERNCrossStream = 0x4000,
+ kKERNVariation = 0x2000,
+ kKERNUnusedBits = 0x1F00,
+ kKERNFormatMask = 0x00FF
+};
+
+enum {
+ kKERNOrderedList = 0,
+ kKERNStateTable = 1,
+ kKERNSimpleArray = 2,
+ kKERNIndexArray = 3
+};
+
+
+enum {
+ kKERNLineStart = 0x00000001,
+ kKERNLineEndKerning = 0x00000002,
+ kKERNNoCrossKerning = 0x00000004,
+ kKERNNotesRequested = 0x00000008,
+ kKERNNoStakeNote = 1,
+ kKERNCrossStreamResetNote = 2,
+ kKERNNotApplied = 0x00000001
+};
+
+
+
+typedef UInt8 KernTableFormat;
+typedef UInt16 KernSubtableInfo;
+typedef SInt16 KernKerningValue;
+typedef UInt16 KernArrayOffset;
+
+struct KernVersion0Header {
+ UInt16 version;
+ UInt16 nTables;
+ UInt16 firstSubtable[1];
+};
+typedef struct KernVersion0Header KernVersion0Header;
+
+struct KernTableHeader {
+ Fixed version;
+ SInt32 nTables;
+ UInt16 firstSubtable[1];
+};
+typedef struct KernTableHeader KernTableHeader;
+typedef KernTableHeader * KernTableHeaderPtr;
+typedef KernTableHeaderPtr * KernTableHeaderHandle;
+struct KernKerningPair {
+ UInt16 left;
+ UInt16 right;
+};
+typedef struct KernKerningPair KernKerningPair;
+
+struct KernOrderedListEntry {
+ KernKerningPair pair;
+ KernKerningValue value;
+};
+typedef struct KernOrderedListEntry KernOrderedListEntry;
+typedef KernOrderedListEntry * KernOrderedListEntryPtr;
+
+struct KernOrderedListHeader {
+ UInt16 nPairs;
+ UInt16 searchRange;
+ UInt16 entrySelector;
+ UInt16 rangeShift;
+ UInt16 table[1];
+};
+typedef struct KernOrderedListHeader KernOrderedListHeader;
+
+struct KernStateHeader {
+ STHeader header;
+ UInt16 valueTable;
+ UInt8 firstTable[1];
+};
+typedef struct KernStateHeader KernStateHeader;
+struct KernStateEntry {
+ UInt16 newState;
+ UInt16 flags;
+};
+typedef struct KernStateEntry KernStateEntry;
+
+
+
+
+
+
+struct KernOffsetTable {
+ UInt16 firstGlyph;
+ UInt16 nGlyphs;
+ KernArrayOffset offsetTable[1];
+};
+typedef struct KernOffsetTable KernOffsetTable;
+typedef KernOffsetTable * KernOffsetTablePtr;
+struct KernSimpleArrayHeader {
+ UInt16 rowWidth;
+ UInt16 leftOffsetTable;
+ UInt16 rightOffsetTable;
+ KernArrayOffset theArray;
+ UInt16 firstTable[1];
+};
+typedef struct KernSimpleArrayHeader KernSimpleArrayHeader;
+
+struct KernIndexArrayHeader {
+ UInt16 glyphCount;
+ UInt8 kernValueCount;
+ UInt8 leftClassCount;
+ UInt8 rightClassCount;
+ UInt8 flags;
+ SInt16 kernValue[1];
+ UInt8 leftClass[1];
+ UInt8 rightClass[1];
+ UInt8 kernIndex[1];
+};
+typedef struct KernIndexArrayHeader KernIndexArrayHeader;
+
+union KernFormatSpecificHeader {
+ KernOrderedListHeader orderedList;
+ KernStateHeader stateTable;
+ KernSimpleArrayHeader simpleArray;
+ KernIndexArrayHeader indexArray;
+};
+typedef union KernFormatSpecificHeader KernFormatSpecificHeader;
+
+struct KernVersion0SubtableHeader {
+ UInt16 version;
+ UInt16 length;
+ KernSubtableInfo stInfo;
+ KernFormatSpecificHeader fsHeader;
+};
+typedef struct KernVersion0SubtableHeader KernVersion0SubtableHeader;
+
+struct KernSubtableHeader {
+ SInt32 length;
+ KernSubtableInfo stInfo;
+ SInt16 tupleIndex;
+ KernFormatSpecificHeader fsHeader;
+};
+typedef struct KernSubtableHeader KernSubtableHeader;
+typedef KernSubtableHeader * KernSubtableHeaderPtr;
+
+
+
+enum {
+ kBSLNTag = 0x62736C6E,
+ kBSLNCurrentVersion = 0x00010000,
+ kBSLNDistanceFormatNoMap = 0,
+ kBSLNDistanceFormatWithMap = 1,
+ kBSLNControlPointFormatNoMap = 2,
+ kBSLNControlPointFormatWithMap = 3
+};
+
+
+enum {
+ kBSLNRomanBaseline = 0,
+ kBSLNIdeographicCenterBaseline = 1,
+ kBSLNIdeographicLowBaseline = 2,
+ kBSLNHangingBaseline = 3,
+ kBSLNMathBaseline = 4,
+ kBSLNLastBaseline = 31,
+ kBSLNNumBaselineClasses = kBSLNLastBaseline + 1,
+ kBSLNNoBaselineOverride = 255
+};
+
+
+typedef UInt32 BslnBaselineClass;
+
+typedef Fixed BslnBaselineRecord[32];
+
+
+
+
+struct BslnFormat0Part {
+ SInt16 deltas[32];
+};
+typedef struct BslnFormat0Part BslnFormat0Part;
+
+struct BslnFormat1Part {
+ SInt16 deltas[32];
+ SFNTLookupTable mappingData;
+};
+typedef struct BslnFormat1Part BslnFormat1Part;
+
+
+
+
+
+
+struct BslnFormat2Part {
+ UInt16 stdGlyph;
+ SInt16 ctlPoints[32];
+};
+typedef struct BslnFormat2Part BslnFormat2Part;
+
+
+
+
+
+struct BslnFormat3Part {
+ UInt16 stdGlyph;
+ SInt16 ctlPoints[32];
+ SFNTLookupTable mappingData;
+};
+typedef struct BslnFormat3Part BslnFormat3Part;
+
+union BslnFormatUnion {
+ BslnFormat0Part fmt0Part;
+ BslnFormat1Part fmt1Part;
+ BslnFormat2Part fmt2Part;
+ BslnFormat3Part fmt3Part;
+};
+typedef union BslnFormatUnion BslnFormatUnion;
+
+
+typedef UInt16 BslnTableFormat;
+
+struct BslnTable {
+ Fixed version;
+ BslnTableFormat format;
+ UInt16 defaultBaseline;
+ BslnFormatUnion parts;
+};
+typedef struct BslnTable BslnTable;
+typedef BslnTable * BslnTablePtr;
+
+
+
+
+
+extern "C" {
+
+
+
+typedef UInt32 FMGeneration;
+
+
+
+
+
+
+
+typedef SInt16 FMFontFamily;
+typedef SInt16 FMFontStyle;
+typedef SInt16 FMFontSize;
+
+
+
+
+
+
+
+typedef UInt32 FMFont;
+struct FMFontFamilyInstance {
+ FMFontFamily fontFamily;
+ FMFontStyle fontStyle;
+};
+typedef struct FMFontFamilyInstance FMFontFamilyInstance;
+struct FMFontFamilyIterator {
+ UInt32 reserved[16];
+};
+typedef struct FMFontFamilyIterator FMFontFamilyIterator;
+struct FMFontIterator {
+ UInt32 reserved[16];
+};
+typedef struct FMFontIterator FMFontIterator;
+struct FMFontFamilyInstanceIterator {
+ UInt32 reserved[16];
+};
+typedef struct FMFontFamilyInstanceIterator FMFontFamilyInstanceIterator;
+enum {
+ kInvalidGeneration = 0L,
+ kInvalidFontFamily = -1,
+ kInvalidFont = 0L
+};
+
+enum {
+ kFMCurrentFilterFormat = 0L
+};
+
+typedef UInt32 FMFilterSelector;
+enum {
+ kFMFontTechnologyFilterSelector = 1L,
+ kFMFontContainerFilterSelector = 2L,
+ kFMGenerationFilterSelector = 3L,
+ kFMFontFamilyCallbackFilterSelector = 4L,
+ kFMFontCallbackFilterSelector = 5L,
+ kFMFontDirectoryFilterSelector = 6L
+};
+
+enum {
+ kFMTrueTypeFontTechnology = 'true',
+ kFMPostScriptFontTechnology = 'typ1'
+};
+
+typedef OSStatus ( * FMFontFamilyCallbackFilterProcPtr)(FMFontFamily iFontFamily, void *iRefCon);
+typedef OSStatus ( * FMFontCallbackFilterProcPtr)(FMFont iFont, void *iRefCon);
+typedef FMFontFamilyCallbackFilterProcPtr FMFontFamilyCallbackFilterUPP;
+typedef FMFontCallbackFilterProcPtr FMFontCallbackFilterUPP;
+extern FMFontFamilyCallbackFilterUPP
+NewFMFontFamilyCallbackFilterUPP(FMFontFamilyCallbackFilterProcPtr userRoutine) ;
+extern FMFontCallbackFilterUPP
+NewFMFontCallbackFilterUPP(FMFontCallbackFilterProcPtr userRoutine) ;
+extern void
+DisposeFMFontFamilyCallbackFilterUPP(FMFontFamilyCallbackFilterUPP userUPP) ;
+extern void
+DisposeFMFontCallbackFilterUPP(FMFontCallbackFilterUPP userUPP) ;
+extern OSStatus
+InvokeFMFontFamilyCallbackFilterUPP(
+ FMFontFamily iFontFamily,
+ void * iRefCon,
+ FMFontFamilyCallbackFilterUPP userUPP) ;
+extern OSStatus
+InvokeFMFontCallbackFilterUPP(
+ FMFont iFont,
+ void * iRefCon,
+ FMFontCallbackFilterUPP userUPP) ;
+
+struct FMFontDirectoryFilter {
+ SInt16 fontFolderDomain;
+ UInt32 reserved[2];
+};
+typedef struct FMFontDirectoryFilter FMFontDirectoryFilter;
+struct FMFilter {
+ UInt32 format;
+ FMFilterSelector selector;
+ union {
+ FourCharCode fontTechnologyFilter;
+ FSSpec fontContainerFilter;
+ FMGeneration generationFilter;
+ FMFontFamilyCallbackFilterUPP fontFamilyCallbackFilter;
+ FMFontCallbackFilterUPP fontCallbackFilter;
+ FMFontDirectoryFilter fontDirectoryFilter;
+ } filter;
+};
+typedef struct FMFilter FMFilter;
+
+typedef OptionBits ATSOptionFlags;
+typedef UInt32 ATSGeneration;
+typedef UInt32 ATSFontContainerRef;
+typedef UInt32 ATSFontFamilyRef;
+typedef UInt32 ATSFontRef;
+typedef UInt16 ATSGlyphRef;
+typedef Float32 ATSFontSize;
+enum {
+ kATSGenerationUnspecified = 0L,
+ kATSFontContainerRefUnspecified = 0L,
+ kATSFontFamilyRefUnspecified = 0L,
+ kATSFontRefUnspecified = 0L
+};
+
+struct ATSFontMetrics {
+ UInt32 version;
+ Float32 ascent;
+
+ Float32 descent;
+
+ Float32 leading;
+ Float32 avgAdvanceWidth;
+ Float32 maxAdvanceWidth;
+ Float32 minLeftSideBearing;
+ Float32 minRightSideBearing;
+ Float32 stemWidth;
+ Float32 stemHeight;
+ Float32 capHeight;
+ Float32 xHeight;
+ Float32 italicAngle;
+ Float32 underlinePosition;
+ Float32 underlineThickness;
+};
+typedef struct ATSFontMetrics ATSFontMetrics;
+enum {
+ kATSItalicQDSkew = (1 << 16) / 4,
+ kATSBoldQDStretch = (1 << 16) * 3 / 2,
+ kATSRadiansFactor = 1144
+};
+
+
+typedef UInt16 ATSCurveType;
+enum {
+ kATSCubicCurveType = 0x0001,
+ kATSQuadCurveType = 0x0002,
+ kATSOtherCurveType = 0x0003
+};
+
+
+
+
+
+
+enum {
+ kATSDeletedGlyphcode = 0xFFFF
+};
+
+struct ATSUCurvePath {
+ UInt32 vectors;
+ UInt32 controlBits[1];
+ Float32Point vector[1];
+};
+typedef struct ATSUCurvePath ATSUCurvePath;
+struct ATSUCurvePaths {
+ UInt32 contours;
+ ATSUCurvePath contour[1];
+};
+typedef struct ATSUCurvePaths ATSUCurvePaths;
+
+struct ATSGlyphIdealMetrics {
+ Float32Point advance;
+ Float32Point sideBearing;
+ Float32Point otherSideBearing;
+};
+typedef struct ATSGlyphIdealMetrics ATSGlyphIdealMetrics;
+
+struct ATSGlyphScreenMetrics {
+ Float32Point deviceAdvance;
+ Float32Point topLeft;
+ UInt32 height;
+ UInt32 width;
+ Float32Point sideBearing;
+ Float32Point otherSideBearing;
+};
+typedef struct ATSGlyphScreenMetrics ATSGlyphScreenMetrics;
+
+
+typedef ATSGlyphRef GlyphID;
+
+
+
+}
+extern "C" {
+
+
+
+
+
+
+
+
+
+enum {
+ kATSUseGlyphAdvance = 0x7FFFFFFF,
+ kATSUseLineHeight = 0x7FFFFFFF,
+ kATSNoTracking = (long)0x80000000
+};
+enum {
+
+
+
+
+
+
+ kATSUseCaretOrigins = 0,
+
+
+
+
+
+
+ kATSUseDeviceOrigins = 1,
+ kATSUseFractionalOrigins = 2,
+ kATSUseOriginFlags = 3
+};
+typedef UInt32 ATSULayoutOperationSelector;
+enum {
+
+
+
+
+ kATSULayoutOperationNone = 0x00000000,
+
+
+
+
+ kATSULayoutOperationJustification = 0x00000001,
+
+
+
+
+ kATSULayoutOperationMorph = 0x00000002,
+
+
+
+
+ kATSULayoutOperationKerningAdjustment = 0x00000004,
+
+
+
+
+ kATSULayoutOperationBaselineAdjustment = 0x00000008,
+
+
+
+
+ kATSULayoutOperationTrackingAdjustment = 0x00000010,
+
+
+
+
+
+ kATSULayoutOperationPostLayoutAdjustment = 0x00000020,
+ kATSULayoutOperationAppleReserved = (unsigned long)0xFFFFFFC0
+};
+typedef UInt32 ATSULayoutOperationCallbackStatus;
+enum {
+
+
+
+
+
+
+ kATSULayoutOperationCallbackStatusHandled = 0x00000000,
+
+
+
+
+
+
+ kATSULayoutOperationCallbackStatusContinue = 0x00000001
+};
+typedef UInt32 ATSLineLayoutOptions;
+enum {
+
+
+
+
+ kATSLineNoLayoutOptions = 0x00000000,
+
+
+
+
+ kATSLineIsDisplayOnly = 0x00000001,
+
+
+
+
+ kATSLineHasNoHangers = 0x00000002,
+
+
+
+
+ kATSLineHasNoOpticalAlignment = 0x00000004,
+
+
+
+
+ kATSLineKeepSpacesOutOfMargin = 0x00000008,
+
+
+
+
+ kATSLineNoSpecialJustification = 0x00000010,
+
+
+
+
+
+ kATSLineLastNoJustification = 0x00000020,
+
+
+
+
+
+ kATSLineFractDisable = 0x00000040,
+
+
+
+
+
+ kATSLineImposeNoAngleForEnds = 0x00000080,
+
+
+
+
+
+ kATSLineFillOutToWidth = 0x00000100,
+
+
+
+
+
+ kATSLineTabAdjustEnabled = 0x00000200,
+
+
+
+
+
+ kATSLineIgnoreFontLeading = 0x00000400,
+
+
+
+
+
+ kATSLineApplyAntiAliasing = 0x00000800,
+
+
+
+
+
+
+ kATSLineNoAntiAliasing = 0x00001000,
+
+
+
+
+
+
+ kATSLineDisableNegativeJustification = 0x00002000,
+
+
+
+
+
+
+
+ kATSLineDisableAutoAdjustDisplayPos = 0x00004000,
+
+
+
+
+
+ kATSLineUseQDRendering = 0x00008000,
+
+
+
+
+ kATSLineDisableAllJustification = 0x00010000,
+
+
+
+
+ kATSLineDisableAllGlyphMorphing = 0x00020000,
+
+
+
+
+ kATSLineDisableAllKerningAdjustments = 0x00040000,
+
+
+
+
+ kATSLineDisableAllBaselineAdjustments = 0x00080000,
+
+
+
+
+ kATSLineDisableAllTrackingAdjustments = 0x00100000,
+
+
+
+
+ kATSLineDisableAllLayoutOperations = kATSLineDisableAllJustification | kATSLineDisableAllGlyphMorphing | kATSLineDisableAllKerningAdjustments | kATSLineDisableAllBaselineAdjustments | kATSLineDisableAllTrackingAdjustments,
+
+
+
+
+
+ kATSLineUseDeviceMetrics = 0x01000000,
+
+
+
+
+
+ kATSLineAppleReserved = (unsigned long)0xFEE00000
+};
+typedef UInt32 ATSStyleRenderingOptions;
+enum {
+
+
+
+
+ kATSStyleNoOptions = 0x00000000,
+
+
+
+
+
+ kATSStyleNoHinting = 0x00000001,
+
+
+
+
+
+ kATSStyleApplyAntiAliasing = 0x00000002,
+
+
+
+
+
+
+ kATSStyleNoAntiAliasing = 0x00000004,
+
+
+
+
+
+ kATSStyleAppleReserved = (unsigned long)0xFFFFFFF8,
+
+
+
+
+
+
+ kATSStyleApplyHints = kATSStyleNoOptions
+};
+typedef UInt32 ATSGlyphInfoFlags;
+enum {
+
+
+
+
+
+ kATSGlyphInfoAppleReserved = 0x1FFBFFE8,
+
+
+
+
+ kATSGlyphInfoIsAttachment = (unsigned long)0x80000000,
+
+
+
+
+ kATSGlyphInfoIsLTHanger = 0x40000000,
+
+
+
+
+ kATSGlyphInfoIsRBHanger = 0x20000000,
+
+
+
+
+
+ kATSGlyphInfoTerminatorGlyph = 0x00080000,
+
+
+
+
+ kATSGlyphInfoIsWhiteSpace = 0x00040000,
+
+
+
+
+ kATSGlyphInfoHasImposedWidth = 0x00000010,
+
+
+
+
+
+
+
+ kATSGlyphInfoByteSizeMask = 0x00000007
+};
+struct ATSLayoutRecord {
+
+
+
+
+ ATSGlyphRef glyphID;
+
+
+
+
+ ATSGlyphInfoFlags flags;
+
+
+
+
+ ByteCount originalOffset;
+
+
+
+
+ Fixed realPos;
+};
+typedef struct ATSLayoutRecord ATSLayoutRecord;
+struct ATSTrapezoid {
+ FixedPoint upperLeft;
+ FixedPoint upperRight;
+ FixedPoint lowerRight;
+ FixedPoint lowerLeft;
+};
+typedef struct ATSTrapezoid ATSTrapezoid;
+struct ATSJustWidthDeltaEntryOverride {
+
+
+
+
+ Fixed beforeGrowLimit;
+
+
+
+
+ Fixed beforeShrinkLimit;
+
+
+
+
+ Fixed afterGrowLimit;
+
+
+
+
+ Fixed afterShrinkLimit;
+
+
+
+
+ JustificationFlags growFlags;
+
+
+
+
+ JustificationFlags shrinkFlags;
+};
+typedef struct ATSJustWidthDeltaEntryOverride ATSJustWidthDeltaEntryOverride;
+
+typedef ATSJustWidthDeltaEntryOverride ATSJustPriorityWidthDeltaOverrides[4];
+typedef struct ATSGlyphVector* ATSULineRef;
+typedef OSStatus ( * ATSUDirectLayoutOperationOverrideProcPtr)(ATSULayoutOperationSelector iCurrentOperation, ATSULineRef iLineRef, UInt32 iRefCon, void *iOperationCallbackParameterPtr, ATSULayoutOperationCallbackStatus *oCallbackStatus);
+typedef ATSUDirectLayoutOperationOverrideProcPtr ATSUDirectLayoutOperationOverrideUPP;
+extern ATSUDirectLayoutOperationOverrideUPP
+NewATSUDirectLayoutOperationOverrideUPP(ATSUDirectLayoutOperationOverrideProcPtr userRoutine) ;
+extern void
+DisposeATSUDirectLayoutOperationOverrideUPP(ATSUDirectLayoutOperationOverrideUPP userUPP) ;
+extern OSStatus
+InvokeATSUDirectLayoutOperationOverrideUPP(
+ ATSULayoutOperationSelector iCurrentOperation,
+ ATSULineRef iLineRef,
+ UInt32 iRefCon,
+ void * iOperationCallbackParameterPtr,
+ ATSULayoutOperationCallbackStatus * oCallbackStatus,
+ ATSUDirectLayoutOperationOverrideUPP userUPP) ;
+struct ATSULayoutOperationOverrideSpecifier {
+
+
+
+
+
+
+ ATSULayoutOperationSelector operationSelector;
+ ATSUDirectLayoutOperationOverrideUPP overrideUPP;
+
+};
+typedef struct ATSULayoutOperationOverrideSpecifier ATSULayoutOperationOverrideSpecifier;
+
+
+
+}
+
+
+
+
+
+extern double acos (double);
+extern double asin (double);
+extern double atan (double);
+extern double atan2 (double, double);
+extern double ceil (double);
+extern double cos (double);
+extern double cosh (double);
+extern double exp (double);
+extern double fabs (double);
+extern double floor (double);
+extern double fmod (double, double);
+extern double frexp (double, int *);
+extern double ldexp (double, int);
+extern double log10 (double);
+extern double log (double);
+extern double modf (double, double *);
+extern double pow (double, double);
+extern double sin (double);
+extern double sinh (double);
+extern double sqrt (double);
+extern double tan (double);
+extern double tanh (double);
+
+
+
+
+
+
+
+
+
+
+struct sfntDirectoryEntry {
+ FourCharCode tableTag;
+ UInt32 checkSum;
+ UInt32 offset;
+ UInt32 length;
+};
+typedef struct sfntDirectoryEntry sfntDirectoryEntry;
+
+struct sfntDirectory {
+ FourCharCode format;
+ UInt16 numOffsets;
+ UInt16 searchRange;
+ UInt16 entrySelector;
+ UInt16 rangeShift;
+ sfntDirectoryEntry table[1];
+};
+typedef struct sfntDirectory sfntDirectory;
+enum {
+ sizeof_sfntDirectory = 12
+};
+
+
+enum {
+ cmapFontTableTag = 'cmap'
+};
+
+enum {
+ kFontUnicodePlatform = 0,
+ kFontMacintoshPlatform = 1,
+ kFontReservedPlatform = 2,
+ kFontMicrosoftPlatform = 3,
+ kFontCustomPlatform = 4
+};
+
+enum {
+ kFontUnicodeDefaultSemantics = 0,
+ kFontUnicodeV1_1Semantics = 1,
+ kFontISO10646_1993Semantics = 2
+};
+
+enum {
+ kFontRomanScript = 0,
+ kFontJapaneseScript = 1,
+ kFontTraditionalChineseScript = 2,
+ kFontChineseScript = kFontTraditionalChineseScript,
+ kFontKoreanScript = 3,
+ kFontArabicScript = 4,
+ kFontHebrewScript = 5,
+ kFontGreekScript = 6,
+ kFontCyrillicScript = 7,
+ kFontRussian = kFontCyrillicScript,
+ kFontRSymbolScript = 8,
+ kFontDevanagariScript = 9,
+ kFontGurmukhiScript = 10,
+ kFontGujaratiScript = 11,
+ kFontOriyaScript = 12,
+ kFontBengaliScript = 13,
+ kFontTamilScript = 14,
+ kFontTeluguScript = 15,
+ kFontKannadaScript = 16,
+ kFontMalayalamScript = 17,
+ kFontSinhaleseScript = 18,
+ kFontBurmeseScript = 19,
+ kFontKhmerScript = 20,
+ kFontThaiScript = 21,
+ kFontLaotianScript = 22,
+ kFontGeorgianScript = 23,
+ kFontArmenianScript = 24,
+ kFontSimpleChineseScript = 25,
+ kFontTibetanScript = 26,
+ kFontMongolianScript = 27,
+ kFontGeezScript = 28,
+ kFontEthiopicScript = kFontGeezScript,
+ kFontAmharicScript = kFontGeezScript,
+ kFontSlavicScript = 29,
+ kFontEastEuropeanRomanScript = kFontSlavicScript,
+ kFontVietnameseScript = 30,
+ kFontExtendedArabicScript = 31,
+ kFontSindhiScript = kFontExtendedArabicScript,
+ kFontUninterpretedScript = 32
+};
+
+enum {
+ kFontMicrosoftSymbolScript = 0,
+ kFontMicrosoftStandardScript = 1,
+ kFontMicrosoftUCS4Script = 10
+};
+
+
+enum {
+ kFontCustom8BitScript = 0,
+ kFontCustom816BitScript = 1,
+ kFontCustom16BitScript = 2
+};
+
+
+enum {
+ kFontEnglishLanguage = 0,
+ kFontFrenchLanguage = 1,
+ kFontGermanLanguage = 2,
+ kFontItalianLanguage = 3,
+ kFontDutchLanguage = 4,
+ kFontSwedishLanguage = 5,
+ kFontSpanishLanguage = 6,
+ kFontDanishLanguage = 7,
+ kFontPortugueseLanguage = 8,
+ kFontNorwegianLanguage = 9,
+ kFontHebrewLanguage = 10,
+ kFontJapaneseLanguage = 11,
+ kFontArabicLanguage = 12,
+ kFontFinnishLanguage = 13,
+ kFontGreekLanguage = 14,
+ kFontIcelandicLanguage = 15,
+ kFontMalteseLanguage = 16,
+ kFontTurkishLanguage = 17,
+ kFontCroatianLanguage = 18,
+ kFontTradChineseLanguage = 19,
+ kFontUrduLanguage = 20,
+ kFontHindiLanguage = 21,
+ kFontThaiLanguage = 22,
+ kFontKoreanLanguage = 23,
+ kFontLithuanianLanguage = 24,
+ kFontPolishLanguage = 25,
+ kFontHungarianLanguage = 26,
+ kFontEstonianLanguage = 27,
+ kFontLettishLanguage = 28,
+ kFontLatvianLanguage = kFontLettishLanguage,
+ kFontSaamiskLanguage = 29,
+ kFontLappishLanguage = kFontSaamiskLanguage,
+ kFontFaeroeseLanguage = 30,
+ kFontFarsiLanguage = 31,
+ kFontPersianLanguage = kFontFarsiLanguage,
+ kFontRussianLanguage = 32,
+ kFontSimpChineseLanguage = 33,
+ kFontFlemishLanguage = 34,
+ kFontIrishLanguage = 35,
+ kFontAlbanianLanguage = 36,
+ kFontRomanianLanguage = 37,
+ kFontCzechLanguage = 38,
+ kFontSlovakLanguage = 39,
+ kFontSlovenianLanguage = 40,
+ kFontYiddishLanguage = 41,
+ kFontSerbianLanguage = 42,
+ kFontMacedonianLanguage = 43,
+ kFontBulgarianLanguage = 44,
+ kFontUkrainianLanguage = 45,
+ kFontByelorussianLanguage = 46,
+ kFontUzbekLanguage = 47,
+ kFontKazakhLanguage = 48,
+ kFontAzerbaijaniLanguage = 49,
+ kFontAzerbaijanArLanguage = 50,
+ kFontArmenianLanguage = 51,
+ kFontGeorgianLanguage = 52,
+ kFontMoldavianLanguage = 53,
+ kFontKirghizLanguage = 54,
+ kFontTajikiLanguage = 55,
+ kFontTurkmenLanguage = 56,
+ kFontMongolianLanguage = 57,
+ kFontMongolianCyrLanguage = 58,
+ kFontPashtoLanguage = 59,
+ kFontKurdishLanguage = 60,
+ kFontKashmiriLanguage = 61,
+ kFontSindhiLanguage = 62,
+ kFontTibetanLanguage = 63,
+ kFontNepaliLanguage = 64,
+ kFontSanskritLanguage = 65,
+ kFontMarathiLanguage = 66,
+ kFontBengaliLanguage = 67,
+ kFontAssameseLanguage = 68,
+ kFontGujaratiLanguage = 69,
+ kFontPunjabiLanguage = 70,
+ kFontOriyaLanguage = 71,
+ kFontMalayalamLanguage = 72,
+ kFontKannadaLanguage = 73,
+ kFontTamilLanguage = 74,
+ kFontTeluguLanguage = 75,
+ kFontSinhaleseLanguage = 76,
+ kFontBurmeseLanguage = 77,
+ kFontKhmerLanguage = 78,
+ kFontLaoLanguage = 79,
+ kFontVietnameseLanguage = 80,
+ kFontIndonesianLanguage = 81,
+ kFontTagalogLanguage = 82,
+ kFontMalayRomanLanguage = 83,
+ kFontMalayArabicLanguage = 84,
+ kFontAmharicLanguage = 85,
+ kFontTigrinyaLanguage = 86,
+ kFontGallaLanguage = 87,
+ kFontOromoLanguage = kFontGallaLanguage,
+ kFontSomaliLanguage = 88,
+ kFontSwahiliLanguage = 89,
+ kFontRuandaLanguage = 90,
+ kFontRundiLanguage = 91,
+ kFontChewaLanguage = 92,
+ kFontMalagasyLanguage = 93,
+ kFontEsperantoLanguage = 94,
+ kFontWelshLanguage = 128,
+ kFontBasqueLanguage = 129,
+ kFontCatalanLanguage = 130,
+ kFontLatinLanguage = 131,
+ kFontQuechuaLanguage = 132,
+ kFontGuaraniLanguage = 133,
+ kFontAymaraLanguage = 134,
+ kFontTatarLanguage = 135,
+ kFontUighurLanguage = 136,
+ kFontDzongkhaLanguage = 137,
+ kFontJavaneseRomLanguage = 138,
+ kFontSundaneseRomLanguage = 139
+};
+
+
+enum {
+ kFontNoPlatformCode = (unsigned long)(-1),
+ kFontNoScriptCode = (unsigned long)(-1),
+ kFontNoLanguageCode = (unsigned long)(-1)
+};
+
+struct sfntCMapSubHeader {
+ UInt16 format;
+ UInt16 length;
+ UInt16 languageID;
+};
+typedef struct sfntCMapSubHeader sfntCMapSubHeader;
+enum {
+ sizeof_sfntCMapSubHeader = 6
+};
+
+struct sfntCMapExtendedSubHeader {
+ UInt16 format;
+ UInt16 reserved;
+ UInt32 length;
+ UInt32 language;
+};
+typedef struct sfntCMapExtendedSubHeader sfntCMapExtendedSubHeader;
+enum {
+ sizeof_sfntCMapExtendedSubHeader = 12
+};
+
+struct sfntCMapEncoding {
+ UInt16 platformID;
+ UInt16 scriptID;
+ UInt32 offset;
+};
+typedef struct sfntCMapEncoding sfntCMapEncoding;
+enum {
+ sizeof_sfntCMapEncoding = 8
+};
+
+struct sfntCMapHeader {
+ UInt16 version;
+ UInt16 numTables;
+ sfntCMapEncoding encoding[1];
+};
+typedef struct sfntCMapHeader sfntCMapHeader;
+enum {
+ sizeof_sfntCMapHeader = 4
+};
+
+
+enum {
+ nameFontTableTag = 'name'
+};
+
+enum {
+ kFontCopyrightName = 0,
+ kFontFamilyName = 1,
+ kFontStyleName = 2,
+ kFontUniqueName = 3,
+ kFontFullName = 4,
+ kFontVersionName = 5,
+ kFontPostscriptName = 6,
+ kFontTrademarkName = 7,
+ kFontManufacturerName = 8,
+ kFontDesignerName = 9,
+ kFontDescriptionName = 10,
+ kFontVendorURLName = 11,
+ kFontDesignerURLName = 12,
+ kFontLicenseDescriptionName = 13,
+ kFontLicenseInfoURLName = 14,
+ kFontLastReservedName = 255
+};
+
+
+enum {
+ kFontNoNameCode = (unsigned long)(-1)
+};
+
+struct sfntNameRecord {
+ UInt16 platformID;
+ UInt16 scriptID;
+ UInt16 languageID;
+ UInt16 nameID;
+ UInt16 length;
+ UInt16 offset;
+};
+typedef struct sfntNameRecord sfntNameRecord;
+enum {
+ sizeof_sfntNameRecord = 12
+};
+
+struct sfntNameHeader {
+ UInt16 format;
+ UInt16 count;
+ UInt16 stringOffset;
+ sfntNameRecord rec[1];
+};
+typedef struct sfntNameHeader sfntNameHeader;
+enum {
+ sizeof_sfntNameHeader = 6
+};
+
+
+enum {
+ variationFontTableTag = 'fvar'
+};
+
+
+struct sfntVariationAxis {
+ FourCharCode axisTag;
+ Fixed minValue;
+ Fixed defaultValue;
+ Fixed maxValue;
+ SInt16 flags;
+ SInt16 nameID;
+};
+typedef struct sfntVariationAxis sfntVariationAxis;
+enum {
+ sizeof_sfntVariationAxis = 20
+};
+
+
+struct sfntInstance {
+ SInt16 nameID;
+ SInt16 flags;
+ Fixed coord[1];
+
+};
+typedef struct sfntInstance sfntInstance;
+enum {
+ sizeof_sfntInstance = 4
+};
+
+struct sfntVariationHeader {
+ Fixed version;
+ UInt16 offsetToData;
+ UInt16 countSizePairs;
+ UInt16 axisCount;
+ UInt16 axisSize;
+ UInt16 instanceCount;
+ UInt16 instanceSize;
+
+ sfntVariationAxis axis[1];
+ sfntInstance instance[1];
+};
+typedef struct sfntVariationHeader sfntVariationHeader;
+enum {
+ sizeof_sfntVariationHeader = 16
+};
+
+
+enum {
+ descriptorFontTableTag = 'fdsc'
+};
+
+struct sfntFontDescriptor {
+ FourCharCode name;
+ Fixed value;
+};
+typedef struct sfntFontDescriptor sfntFontDescriptor;
+struct sfntDescriptorHeader {
+ Fixed version;
+ SInt32 descriptorCount;
+ sfntFontDescriptor descriptor[1];
+};
+typedef struct sfntDescriptorHeader sfntDescriptorHeader;
+enum {
+ sizeof_sfntDescriptorHeader = 8
+};
+
+
+enum {
+ featureFontTableTag = 'feat'
+};
+
+struct sfntFeatureName {
+ UInt16 featureType;
+ UInt16 settingCount;
+ SInt32 offsetToSettings;
+ UInt16 featureFlags;
+ UInt16 nameID;
+};
+typedef struct sfntFeatureName sfntFeatureName;
+struct sfntFontFeatureSetting {
+ UInt16 setting;
+ UInt16 nameID;
+};
+typedef struct sfntFontFeatureSetting sfntFontFeatureSetting;
+struct sfntFontRunFeature {
+ UInt16 featureType;
+ UInt16 setting;
+};
+typedef struct sfntFontRunFeature sfntFontRunFeature;
+struct sfntFeatureHeader {
+ SInt32 version;
+ UInt16 featureNameCount;
+ UInt16 featureSetCount;
+ SInt32 reserved;
+ sfntFeatureName names[1];
+ sfntFontFeatureSetting settings[1];
+ sfntFontRunFeature runs[1];
+};
+typedef struct sfntFeatureHeader sfntFeatureHeader;
+
+enum {
+ os2FontTableTag = 'OS/2'
+};
+
+
+enum {
+ nonGlyphID = 65535L
+};
+
+
+
+
+
+enum {
+ kFontNoPlatform = -1,
+ kFontNoScript = -1,
+ kFontNoLanguage = -1,
+ kFontNoName = -1
+};
+
+
+
+
+
+typedef UInt32 FontNameCode;
+
+typedef UInt32 FontPlatformCode;
+typedef UInt32 FontScriptCode;
+typedef UInt32 FontLanguageCode;
+
+
+
+
+struct FontVariation {
+ FourCharCode name;
+ Fixed value;
+};
+typedef struct FontVariation FontVariation;
+
+extern "C" {
+
+
+
+
+
+
+
+enum {
+ kATSOptionFlagsDefault = kNilOptions,
+ kATSOptionFlagsComposeFontPostScriptName = 1 << 0,
+ kATSOptionFlagsUseDataForkAsResourceFork = 1 << 8,
+ kATSOptionFlagsUseResourceFork = 2 << 8,
+ kATSOptionFlagsUseDataFork = 3 << 8
+};
+
+enum {
+ kATSIterationCompleted = -980L,
+ kATSInvalidFontFamilyAccess = -981L,
+ kATSInvalidFontAccess = -982L,
+ kATSIterationScopeModified = -983L,
+ kATSInvalidFontTableAccess = -984L,
+ kATSInvalidFontContainerAccess = -985L
+};
+
+
+typedef UInt32 ATSFontContext;
+enum {
+ kATSFontContextUnspecified = 0,
+ kATSFontContextGlobal = 1,
+ kATSFontContextLocal = 2
+};
+
+enum {
+ kATSOptionFlagsDoNotNotify = 0x00000001 << 8,
+ kATSOptionFlagsIterationScopeMask = 0x00000007 << 12,
+ kATSOptionFlagsDefaultScope = 0x00000000 << 12,
+ kATSOptionFlagsUnRestrictedScope = 0x00000001 << 12,
+ kATSOptionFlagsRestrictedScope = 0x00000002 << 12,
+ kATSOptionFlagsProcessSubdirectories = 0x00000001 << 6
+};
+
+
+enum {
+ kATSOptionFlagsIterateByPrecedenceMask = 0x00000001 << 5
+};
+
+typedef UInt32 ATSFontFormat;
+enum {
+ kATSFontFormatUnspecified = 0
+};
+
+typedef OSStatus ( * ATSFontFamilyApplierFunction)(ATSFontFamilyRef iFamily, void *iRefCon);
+typedef OSStatus ( * ATSFontApplierFunction)(ATSFontRef iFont, void *iRefCon);
+typedef struct ATSFontFamilyIterator_* ATSFontFamilyIterator;
+typedef struct ATSFontIterator_* ATSFontIterator;
+enum {
+ kATSFontFilterCurrentVersion = 0
+};
+
+enum ATSFontFilterSelector {
+ kATSFontFilterSelectorUnspecified = 0,
+ kATSFontFilterSelectorGeneration = 3,
+ kATSFontFilterSelectorFontFamily = 7,
+ kATSFontFilterSelectorFontFamilyApplierFunction = 8,
+ kATSFontFilterSelectorFontApplierFunction = 9
+};
+typedef enum ATSFontFilterSelector ATSFontFilterSelector;
+
+struct ATSFontFilter {
+ UInt32 version;
+ ATSFontFilterSelector filterSelector;
+ union {
+ ATSGeneration generationFilter;
+ ATSFontFamilyRef fontFamilyFilter;
+ ATSFontFamilyApplierFunction fontFamilyApplierFunctionFilter;
+ ATSFontApplierFunction fontApplierFunctionFilter;
+ } filter;
+};
+typedef struct ATSFontFilter ATSFontFilter;
+
+typedef struct ATSFontNotificationRef_* ATSFontNotificationRef;
+typedef struct ATSFontNotificationInfoRef_* ATSFontNotificationInfoRef;
+enum ATSFontNotifyOption {
+
+
+
+
+ kATSFontNotifyOptionDefault = 0,
+ kATSFontNotifyOptionReceiveWhileSuspended = 1L << 0
+};
+typedef enum ATSFontNotifyOption ATSFontNotifyOption;
+enum ATSFontNotifyAction {
+ kATSFontNotifyActionFontsChanged = 1,
+ kATSFontNotifyActionDirectoriesChanged = 2
+};
+typedef enum ATSFontNotifyAction ATSFontNotifyAction;
+typedef void ( * ATSNotificationCallback)(ATSFontNotificationInfoRef info, void *refCon);
+extern ATSGeneration
+ATSGetGeneration(void) ;
+extern OSStatus
+ATSFontActivateFromFileSpecification(
+ const FSSpec * iFile,
+ ATSFontContext iContext,
+ ATSFontFormat iFormat,
+ void * iReserved,
+ ATSOptionFlags iOptions,
+ ATSFontContainerRef * oContainer) ;
+extern OSStatus
+ATSFontActivateFromMemory(
+ LogicalAddress iData,
+ ByteCount iLength,
+ ATSFontContext iContext,
+ ATSFontFormat iFormat,
+ void * iReserved,
+ ATSOptionFlags iOptions,
+ ATSFontContainerRef * oContainer) ;
+extern OSStatus
+ATSFontDeactivate(
+ ATSFontContainerRef iContainer,
+ void * iRefCon,
+ ATSOptionFlags iOptions) ;
+extern OSStatus
+ATSFontFamilyApplyFunction(
+ ATSFontFamilyApplierFunction iFunction,
+ void * iRefCon) ;
+extern OSStatus
+ATSFontFamilyIteratorCreate(
+ ATSFontContext iContext,
+ const ATSFontFilter * iFilter,
+ void * iRefCon,
+ ATSOptionFlags iOptions,
+ ATSFontFamilyIterator * ioIterator) ;
+extern OSStatus
+ATSFontFamilyIteratorRelease(ATSFontFamilyIterator * ioIterator) ;
+extern OSStatus
+ATSFontFamilyIteratorReset(
+ ATSFontContext iContext,
+ const ATSFontFilter * iFilter,
+ void * iRefCon,
+ ATSOptionFlags iOptions,
+ ATSFontFamilyIterator * ioIterator) ;
+extern OSStatus
+ATSFontFamilyIteratorNext(
+ ATSFontFamilyIterator iIterator,
+ ATSFontFamilyRef * oFamily) ;
+extern ATSFontFamilyRef
+ATSFontFamilyFindFromName(
+ CFStringRef iName,
+ ATSOptionFlags iOptions) ;
+extern ATSGeneration
+ATSFontFamilyGetGeneration(ATSFontFamilyRef iFamily) ;
+extern OSStatus
+ATSFontFamilyGetName(
+ ATSFontFamilyRef iFamily,
+ ATSOptionFlags iOptions,
+ CFStringRef * oName) ;
+extern TextEncoding
+ATSFontFamilyGetEncoding(ATSFontFamilyRef iFamily) ;
+extern OSStatus
+ATSFontApplyFunction(
+ ATSFontApplierFunction iFunction,
+ void * iRefCon) ;
+extern OSStatus
+ATSFontIteratorCreate(
+ ATSFontContext iContext,
+ const ATSFontFilter * iFilter,
+ void * iRefCon,
+ ATSOptionFlags iOptions,
+ ATSFontIterator * ioIterator) ;
+extern OSStatus
+ATSFontIteratorRelease(ATSFontIterator * ioIterator) ;
+extern OSStatus
+ATSFontIteratorReset(
+ ATSFontContext iContext,
+ const ATSFontFilter * iFilter,
+ void * iRefCon,
+ ATSOptionFlags iOptions,
+ ATSFontIterator * ioIterator) ;
+extern OSStatus
+ATSFontIteratorNext(
+ ATSFontIterator iIterator,
+ ATSFontRef * oFont) ;
+extern ATSFontRef
+ATSFontFindFromName(
+ CFStringRef iName,
+ ATSOptionFlags iOptions) ;
+extern ATSFontRef
+ATSFontFindFromPostScriptName(
+ CFStringRef iName,
+ ATSOptionFlags iOptions) ;
+extern OSStatus
+ATSFontFindFromContainer(
+ ATSFontContainerRef iContainer,
+ ATSOptionFlags iOptions,
+ ItemCount iCount,
+ ATSFontRef ioArray[],
+ ItemCount * oCount) ;
+extern ATSGeneration
+ATSFontGetGeneration(ATSFontRef iFont) ;
+extern OSStatus
+ATSFontGetName(
+ ATSFontRef iFont,
+ ATSOptionFlags iOptions,
+ CFStringRef * oName) ;
+extern OSStatus
+ATSFontGetPostScriptName(
+ ATSFontRef iFont,
+ ATSOptionFlags iOptions,
+ CFStringRef * oName) ;
+extern OSStatus
+ATSFontGetTableDirectory(
+ ATSFontRef iFont,
+ ByteCount iBufferSize,
+ void * ioBuffer,
+ ByteCount * oSize) ;
+extern OSStatus
+ATSFontGetTable(
+ ATSFontRef iFont,
+ FourCharCode iTag,
+ ByteOffset iOffset,
+ ByteCount iBufferSize,
+ void * ioBuffer,
+ ByteCount * oSize) ;
+extern OSStatus
+ATSFontGetHorizontalMetrics(
+ ATSFontRef iFont,
+ ATSOptionFlags iOptions,
+ ATSFontMetrics * oMetrics) ;
+extern OSStatus
+ATSFontGetVerticalMetrics(
+ ATSFontRef iFont,
+ ATSOptionFlags iOptions,
+ ATSFontMetrics * oMetrics) ;
+extern ATSFontFamilyRef
+ATSFontFamilyFindFromQuickDrawName(ConstStr255Param iName) ;
+extern OSStatus
+ATSFontFamilyGetQuickDrawName(
+ ATSFontFamilyRef iFamily,
+ Str255 oName) ;
+extern OSStatus
+ATSFontGetFileSpecification(
+ ATSFontRef iFont,
+ FSSpec * oFile) ;
+extern OSStatus
+ATSFontGetFontFamilyResource(
+ ATSFontRef iFont,
+ ByteCount iBufferSize,
+ void * ioBuffer,
+ ByteCount * oSize) ;
+extern OSStatus
+ATSFontNotify(
+ ATSFontNotifyAction action,
+ void * info) ;
+extern OSStatus
+ATSFontNotificationSubscribe(
+ ATSNotificationCallback callback,
+ ATSFontNotifyOption options,
+ void * iRefcon,
+ ATSFontNotificationRef * oNotificationRef) ;
+extern OSStatus
+ATSFontNotificationUnsubscribe(ATSFontNotificationRef notificationRef) ;
+struct ATSFontQuerySourceContext {
+
+
+
+
+
+ UInt32 version;
+
+
+
+
+
+ void * refCon;
+
+
+
+
+ CFAllocatorRetainCallBack retain;
+
+
+
+
+ CFAllocatorReleaseCallBack release;
+};
+typedef struct ATSFontQuerySourceContext ATSFontQuerySourceContext;
+
+
+
+
+
+
+
+enum ATSFontQueryMessageID {
+
+
+
+
+
+
+
+ kATSQueryActivateFontMessage = 'atsa'
+};
+typedef enum ATSFontQueryMessageID ATSFontQueryMessageID;
+typedef CFPropertyListRef ( * ATSFontQueryCallback)(ATSFontQueryMessageID msgid, CFPropertyListRef data, void *refCon);
+extern CFRunLoopSourceRef
+ATSCreateFontQueryRunLoopSource(
+ CFIndex queryOrder,
+ CFIndex sourceOrder,
+ ATSFontQueryCallback callout,
+ const ATSFontQuerySourceContext * context) ;
+
+
+}
+
+
+
+
+
+
+
+
+
+enum {
+ cexec68K = 0x00000001,
+ truetypeStreamType = 0x00000001,
+ type1StreamType = 0x00000002,
+ type3StreamType = 0x00000004,
+ type42StreamType = 0x00000008,
+ type42GXStreamType = 0x00000010,
+ portableStreamType = 0x00000020,
+ flattenedStreamType = 0x00000040,
+ cidType2StreamType = 0x00000080,
+ cidType0StreamType = 0x00000100,
+ type1CFFStreamType = 0x00000200,
+ evenOddModifierStreamType = 0x00008000,
+ eexecBinaryModifierStreamType = 0x00010000,
+ unicodeMappingModifierStreamType = 0x00020000,
+ scalerSpecifcModifierMask = 0x0000F000,
+ streamTypeModifierMask = (long)0xFFFFF000
+};
+
+
+typedef unsigned long scalerStreamTypeFlag;
+enum {
+ downloadStreamAction = 0,
+ asciiDownloadStreamAction = 1,
+ fontSizeQueryStreamAction = 2,
+ encodingOnlyStreamAction = 3,
+ prerequisiteQueryStreamAction = 4,
+ prerequisiteItemStreamAction = 5,
+ variationQueryStreamAction = 6,
+ variationPSOperatorStreamAction = 7
+};
+
+typedef long scalerStreamAction;
+enum {
+ selectAllVariations = -1
+};
+
+struct scalerPrerequisiteItem {
+ long enumeration;
+ long size;
+ unsigned char name[1];
+};
+typedef struct scalerPrerequisiteItem scalerPrerequisiteItem;
+struct scalerStream {
+ const void * streamRefCon;
+ const char * targetVersion;
+ scalerStreamTypeFlag types;
+ scalerStreamAction action;
+ unsigned long memorySize;
+ long variationCount;
+ const void * variations;
+ union {
+
+ struct {
+ const unsigned short * encoding;
+ long * glyphBits;
+ char * name;
+ } font;
+
+
+ struct {
+ long size;
+ void * list;
+ } prerequisiteQuery;
+
+ long prerequisiteItem;
+
+ long variationQueryResult;
+ } info;
+};
+typedef struct scalerStream scalerStream;
+struct scalerStreamData {
+ long hexFlag;
+ long byteCount;
+ const void * data;
+};
+typedef struct scalerStreamData scalerStreamData;
+
+
+
+
+extern "C" {
+}
+
+typedef struct CGAffineTransform CGAffineTransform;
+
+
+extern "C" {
+
+
+
+struct CGPoint {
+ float x;
+ float y;
+};
+typedef struct CGPoint CGPoint;
+
+
+
+struct CGSize {
+ float width;
+ float height;
+};
+typedef struct CGSize CGSize;
+
+
+
+struct CGRect {
+ CGPoint origin;
+ CGSize size;
+};
+typedef struct CGRect CGRect;
+
+
+
+enum CGRectEdge {
+ CGRectMinXEdge, CGRectMinYEdge, CGRectMaxXEdge, CGRectMaxYEdge
+};
+typedef enum CGRectEdge CGRectEdge;
+
+
+
+extern const CGPoint CGPointZero;
+
+
+
+extern const CGSize CGSizeZero;
+
+
+
+extern const CGRect CGRectZero;
+
+
+
+
+
+extern const CGRect CGRectNull;
+
+
+
+static inline CGPoint CGPointMake(float x, float y);
+
+
+
+static inline CGSize CGSizeMake(float width, float height);
+
+
+
+static inline CGRect CGRectMake(float x, float y, float width, float height);
+
+
+
+extern float CGRectGetMinX(CGRect rect);
+
+
+
+extern float CGRectGetMidX(CGRect rect);
+
+
+
+extern float CGRectGetMaxX(CGRect rect);
+
+
+
+extern float CGRectGetMinY(CGRect rect);
+
+
+
+extern float CGRectGetMidY(CGRect rect);
+
+
+
+extern float CGRectGetMaxY(CGRect rect);
+
+
+
+extern float CGRectGetWidth(CGRect rect);
+
+
+
+extern float CGRectGetHeight(CGRect rect);
+
+
+
+extern int CGPointEqualToPoint(CGPoint point1, CGPoint point2);
+
+
+
+extern int CGSizeEqualToSize(CGSize size1, CGSize size2);
+
+
+
+extern int CGRectEqualToRect(CGRect rect1, CGRect rect2);
+
+
+
+
+extern CGRect CGRectStandardize(CGRect rect);
+
+
+
+
+extern int CGRectIsEmpty(CGRect rect);
+
+
+
+
+extern int CGRectIsNull(CGRect rect);
+
+
+
+
+extern CGRect CGRectInset(CGRect rect, float dx, float dy);
+
+
+
+
+extern CGRect CGRectIntegral(CGRect rect);
+
+
+
+extern CGRect CGRectUnion(CGRect r1, CGRect r2);
+
+
+
+
+extern CGRect CGRectIntersection(CGRect r1, CGRect r2);
+
+
+
+extern CGRect CGRectOffset(CGRect rect, float dx, float dy);
+
+
+
+
+
+
+
+extern void CGRectDivide(CGRect rect, CGRect *slice, CGRect *remainder, float amount, CGRectEdge edge);
+
+
+
+extern int CGRectContainsPoint(CGRect rect, CGPoint point);
+
+
+
+
+
+extern int CGRectContainsRect(CGRect rect1, CGRect rect2);
+
+
+
+
+
+extern int CGRectIntersectsRect(CGRect rect1, CGRect rect2);
+
+
+
+static inline CGPoint CGPointMake(float x, float y)
+{
+ CGPoint p; p.x = x; p.y = y; return p;
+}
+
+static inline CGSize CGSizeMake(float width, float height)
+{
+ CGSize size; size.width = width; size.height = height; return size;
+}
+
+static inline CGRect CGRectMake(float x, float y, float width, float height)
+{
+ CGRect rect;
+ rect.origin.x = x; rect.origin.y = y;
+ rect.size.width = width; rect.size.height = height;
+ return rect;
+}
+
+}
+
+extern "C" {
+
+struct CGAffineTransform {
+ float a, b, c, d;
+ float tx, ty;
+};
+
+
+
+extern const CGAffineTransform CGAffineTransformIdentity;
+
+
+
+extern CGAffineTransform CGAffineTransformMake(float a, float b, float c, float d, float tx, float ty);
+
+
+
+
+extern CGAffineTransform CGAffineTransformMakeTranslation(float tx, float ty);
+
+
+
+
+extern CGAffineTransform CGAffineTransformMakeScale(float sx, float sy);
+
+
+
+
+extern CGAffineTransform CGAffineTransformMakeRotation(float angle);
+
+
+
+
+extern CGAffineTransform CGAffineTransformTranslate(CGAffineTransform t, float tx, float ty);
+
+
+
+
+extern CGAffineTransform CGAffineTransformScale(CGAffineTransform t, float sx, float sy);
+
+
+
+
+extern CGAffineTransform CGAffineTransformRotate(CGAffineTransform t, float angle);
+
+
+
+
+extern CGAffineTransform CGAffineTransformInvert(CGAffineTransform t);
+
+
+
+
+extern CGAffineTransform CGAffineTransformConcat(CGAffineTransform t1, CGAffineTransform t2);
+
+
+
+
+
+extern CGPoint CGPointApplyAffineTransform(CGPoint point, CGAffineTransform t);
+
+
+
+
+
+extern CGSize CGSizeApplyAffineTransform(CGSize size, CGAffineTransform t);
+
+
+
+static inline CGAffineTransform
+__CGAffineTransformMake(float a, float b, float c, float d, float tx, float ty)
+{
+ CGAffineTransform t;
+
+ t.a = a; t.b = b; t.c = c; t.d = d; t.tx = tx; t.ty = ty;
+ return t;
+}
+
+
+
+static inline CGPoint
+__CGPointApplyAffineTransform(CGPoint point, CGAffineTransform t)
+{
+ CGPoint p;
+
+ p.x = t.a * point.x + t.c * point.y + t.tx;
+ p.y = t.b * point.x + t.d * point.y + t.ty;
+ return p;
+}
+
+
+
+static inline CGSize
+__CGSizeApplyAffineTransform(CGSize size, CGAffineTransform t)
+{
+ CGSize s;
+
+ s.width = t.a * size.width + t.c * size.height;
+ s.height = t.b * size.width + t.d * size.height;
+ return s;
+}
+
+
+
+}
+typedef struct CGContext *CGContextRef;
+
+
+
+typedef struct CGColorSpace *CGColorSpaceRef;
+
+
+typedef struct CGDataProvider *CGDataProviderRef;
+
+
+
+
+extern "C" {
+struct CGDataProviderCallbacks {
+ size_t (*getBytes)(void *info, void *buffer, size_t count);
+ void (*skipBytes)(void *info, size_t count);
+ void (*rewind)(void *info);
+ void (*releaseProvider)(void *info);
+};
+typedef struct CGDataProviderCallbacks CGDataProviderCallbacks;
+struct CGDataProviderDirectAccessCallbacks {
+ const void *(*getBytePointer)(void *info);
+ void (*releaseBytePointer)(void *info, const void *pointer);
+ size_t (*getBytes)(void *info, void *buffer, size_t offset, size_t count);
+ void (*releaseProvider)(void *info);
+};
+typedef struct CGDataProviderDirectAccessCallbacks CGDataProviderDirectAccessCallbacks;
+
+
+
+extern CFTypeID CGDataProviderGetTypeID(void);
+
+
+
+
+extern CGDataProviderRef CGDataProviderCreate(void *info, const CGDataProviderCallbacks *callbacks);
+
+
+
+
+extern CGDataProviderRef CGDataProviderCreateDirectAccess(void *info, size_t size, const CGDataProviderDirectAccessCallbacks *callbacks);
+
+
+
+
+
+extern CGDataProviderRef CGDataProviderCreateWithData(void *info, const void *data, size_t size, void (*releaseData)(void *info, const void *data, size_t size));
+
+
+
+extern CGDataProviderRef CGDataProviderCreateWithURL(CFURLRef url);
+
+
+
+extern CGDataProviderRef CGDataProviderRetain(CGDataProviderRef provider);
+
+
+
+extern void CGDataProviderRelease(CGDataProviderRef provider);
+
+
+
+
+
+extern CGDataProviderRef CGDataProviderCreateWithFilename(const char *filename);
+
+}
+
+enum CGColorRenderingIntent {
+ kCGRenderingIntentDefault,
+ kCGRenderingIntentAbsoluteColorimetric,
+ kCGRenderingIntentRelativeColorimetric,
+ kCGRenderingIntentPerceptual,
+ kCGRenderingIntentSaturation
+};
+typedef enum CGColorRenderingIntent CGColorRenderingIntent;
+
+
+
+
+
+extern "C" {
+
+
+
+extern CFTypeID CGColorSpaceGetTypeID(void);
+
+
+
+
+
+extern CGColorSpaceRef CGColorSpaceCreateDeviceGray(void);
+
+
+
+extern CGColorSpaceRef CGColorSpaceCreateDeviceRGB(void);
+
+
+
+extern CGColorSpaceRef CGColorSpaceCreateDeviceCMYK(void);
+extern CGColorSpaceRef CGColorSpaceCreateCalibratedGray(const float whitePoint[3], const float blackPoint[3], float gamma);
+extern CGColorSpaceRef CGColorSpaceCreateCalibratedRGB(const float whitePoint[3], const float blackPoint[3], const float gamma[3], const float matrix[9]);
+extern CGColorSpaceRef CGColorSpaceCreateLab(const float whitePoint[3], const float blackPoint[3], const float range[4]);
+extern CGColorSpaceRef CGColorSpaceCreateICCBased(size_t nComponents, const float *range, CGDataProviderRef profile, CGColorSpaceRef alternate);
+extern CGColorSpaceRef CGColorSpaceCreateIndexed(CGColorSpaceRef baseSpace, size_t lastIndex, const unsigned char *colorTable);
+
+
+
+
+
+
+extern CGColorSpaceRef CGColorSpaceCreatePattern(CGColorSpaceRef baseSpace);
+
+
+
+
+
+extern CGColorSpaceRef CGColorSpaceCreateWithPlatformColorSpace(void *platformColorSpaceReference);
+
+
+
+extern CGColorSpaceRef CGColorSpaceCreateWithName(CFStringRef name);
+
+
+
+
+
+extern size_t CGColorSpaceGetNumberOfComponents(const CGColorSpaceRef cs);
+
+
+
+
+
+extern CGColorSpaceRef CGColorSpaceRetain(CGColorSpaceRef cs);
+
+
+
+extern void CGColorSpaceRelease(CGColorSpaceRef cs);
+
+}
+typedef struct CGFont *CGFontRef;
+typedef unsigned short CGFontIndex;
+typedef CGFontIndex CGGlyph;
+
+
+
+
+
+enum {
+ kCGFontIndexMax = ((1 << 16) - 2),
+ kCGFontIndexInvalid = ((1 << 16) - 1),
+ kCGGlyphMax = kCGFontIndexMax
+};
+
+extern "C" {
+
+
+
+extern CFTypeID CGFontGetTypeID(void);
+
+
+
+
+
+extern CGFontRef CGFontCreateWithPlatformFont(void *platformFontReference);
+
+
+
+extern CGFontRef CGFontRetain(CGFontRef font);
+
+
+
+extern void CGFontRelease(CGFontRef font);
+
+}
+
+
+
+enum {
+ CGGlyphMin = 0,
+ CGGlyphMax = kCGGlyphMax
+};
+typedef struct CGImage *CGImageRef;
+
+
+
+
+
+
+extern "C" {
+
+enum CGImageAlphaInfo {
+ kCGImageAlphaNone,
+ kCGImageAlphaPremultipliedLast,
+ kCGImageAlphaPremultipliedFirst,
+ kCGImageAlphaLast,
+ kCGImageAlphaFirst,
+ kCGImageAlphaNoneSkipLast,
+ kCGImageAlphaNoneSkipFirst
+};
+typedef enum CGImageAlphaInfo CGImageAlphaInfo;
+
+
+
+extern CFTypeID CGImageGetTypeID(void);
+
+
+
+extern CGImageRef CGImageCreate(size_t width, size_t height, size_t bitsPerComponent, size_t bitsPerPixel, size_t bytesPerRow, CGColorSpaceRef colorspace, CGImageAlphaInfo alphaInfo, CGDataProviderRef provider, const float decode[], bool shouldInterpolate, CGColorRenderingIntent intent);
+
+
+
+extern CGImageRef CGImageMaskCreate(size_t width, size_t height, size_t bitsPerComponent, size_t bitsPerPixel, size_t bytesPerRow, CGDataProviderRef provider, const float decode[], bool shouldInterpolate);
+
+
+
+extern CGImageRef CGImageCreateWithJPEGDataProvider(CGDataProviderRef source, const float decode[], bool shouldInterpolate, CGColorRenderingIntent intent);
+
+
+
+extern CGImageRef CGImageCreateWithPNGDataProvider(CGDataProviderRef source, const float decode[], bool shouldInterpolate, CGColorRenderingIntent intent);
+
+
+
+extern CGImageRef CGImageRetain(CGImageRef image);
+
+
+
+extern void CGImageRelease(CGImageRef image);
+
+
+
+extern bool CGImageIsMask(CGImageRef image);
+
+
+
+extern size_t CGImageGetWidth(CGImageRef image);
+
+
+
+extern size_t CGImageGetHeight(CGImageRef image);
+
+
+
+extern size_t CGImageGetBitsPerComponent(CGImageRef image);
+
+
+
+extern size_t CGImageGetBitsPerPixel(CGImageRef image);
+
+
+
+extern size_t CGImageGetBytesPerRow(CGImageRef image);
+
+
+
+
+extern CGColorSpaceRef CGImageGetColorSpace(CGImageRef image);
+
+
+
+extern CGImageAlphaInfo CGImageGetAlphaInfo(CGImageRef image);
+
+
+
+extern CGDataProviderRef CGImageGetDataProvider(CGImageRef image);
+
+
+
+extern const float *CGImageGetDecode(CGImageRef image);
+
+
+
+extern bool CGImageGetShouldInterpolate(CGImageRef image);
+
+
+
+extern CGColorRenderingIntent CGImageGetRenderingIntent(CGImageRef image);
+
+}
+typedef struct CGPath *CGMutablePathRef;
+typedef const struct CGPath *CGPathRef;
+
+
+
+
+
+extern "C" {
+
+
+
+extern CFTypeID CGPathGetTypeID(void);
+
+
+
+extern CGMutablePathRef CGPathCreateMutable(void);
+
+
+
+extern CGPathRef CGPathCreateCopy(CGPathRef path);
+
+
+
+extern CGMutablePathRef CGPathCreateMutableCopy(CGPathRef path);
+
+
+
+extern CGPathRef CGPathRetain(CGPathRef path);
+
+
+
+extern void CGPathRelease(CGPathRef path);
+
+
+
+extern bool CGPathEqualToPath(CGPathRef path1, CGPathRef path2);
+
+
+
+
+
+
+extern void CGPathMoveToPoint(CGMutablePathRef path, const CGAffineTransform *m, float x, float y);
+
+
+
+
+
+extern void CGPathAddLineToPoint(CGMutablePathRef path, const CGAffineTransform *m, float x, float y);
+
+
+
+
+
+extern void CGPathAddQuadCurveToPoint(CGMutablePathRef path, const CGAffineTransform *m, float cpx, float cpy, float x, float y);
+
+
+
+
+
+
+extern void CGPathAddCurveToPoint(CGMutablePathRef path, const CGAffineTransform *m, float cp1x, float cp1y, float cp2x, float cp2y, float x, float y);
+
+
+
+
+extern void CGPathCloseSubpath(CGMutablePathRef path);
+
+
+
+
+
+
+extern void CGPathAddRect(CGMutablePathRef path, const CGAffineTransform *m, CGRect rect);
+
+
+
+
+
+extern void CGPathAddRects(CGMutablePathRef path, const CGAffineTransform *m, const CGRect rects[], size_t count);
+
+
+
+
+
+extern void CGPathAddLines(CGMutablePathRef path, const CGAffineTransform *m, const CGPoint points[], size_t count);
+extern void CGPathAddArc(CGMutablePathRef path, const CGAffineTransform *m, float x, float y, float radius, float startAngle, float endAngle, bool clockwise);
+extern void CGPathAddArcToPoint(CGMutablePathRef path, const CGAffineTransform *m, float x1, float y1, float x2, float y2, float radius);
+
+
+
+
+extern void CGPathAddPath(CGMutablePathRef path1, const CGAffineTransform *m, CGPathRef path2);
+
+
+
+
+
+extern bool CGPathIsEmpty(CGPathRef path);
+
+
+
+extern bool CGPathIsRect(CGPathRef path, CGRect *rect);
+
+
+
+
+extern CGPoint CGPathGetCurrentPoint(CGPathRef path);
+
+
+
+
+
+
+extern CGRect CGPathGetBoundingBox(CGPathRef path);
+
+enum CGPathElementType {
+ kCGPathElementMoveToPoint,
+ kCGPathElementAddLineToPoint,
+ kCGPathElementAddQuadCurveToPoint,
+ kCGPathElementAddCurveToPoint,
+ kCGPathElementCloseSubpath
+};
+typedef enum CGPathElementType CGPathElementType;
+
+struct CGPathElement {
+ CGPathElementType type;
+ CGPoint *points;
+};
+typedef struct CGPathElement CGPathElement;
+
+typedef void (*CGPathApplierFunction)(void *info, const CGPathElement *element);
+
+extern void CGPathApply(CGPathRef path, void *info, CGPathApplierFunction function);
+
+}
+typedef struct CGPattern *CGPatternRef;
+
+
+enum CGPatternTiling {
+ kCGPatternTilingNoDistortion,
+ kCGPatternTilingConstantSpacingMinimalDistortion,
+ kCGPatternTilingConstantSpacing
+};
+typedef enum CGPatternTiling CGPatternTiling;
+
+extern "C" {
+typedef void (*CGPatternDrawPatternCallback)(void *info, CGContextRef c);
+typedef void (*CGPatternReleaseInfoCallback)(void *info);
+
+struct CGPatternCallbacks {
+ unsigned int version;
+ CGPatternDrawPatternCallback drawPattern;
+ CGPatternReleaseInfoCallback releaseInfo;
+};
+typedef struct CGPatternCallbacks CGPatternCallbacks;
+
+
+
+extern CFTypeID CGPatternGetTypeID(void);
+
+
+
+extern CGPatternRef CGPatternCreate(void *info, CGRect bounds, CGAffineTransform matrix, float xStep, float yStep, CGPatternTiling tiling, bool isColored, const CGPatternCallbacks *callbacks);
+
+
+
+extern CGPatternRef CGPatternRetain(CGPatternRef pattern);
+
+
+
+extern void CGPatternRelease(CGPatternRef pattern);
+
+}
+typedef struct CGPDFDocument *CGPDFDocumentRef;
+
+
+
+
+
+
+extern "C" {
+
+
+
+extern CFTypeID CGPDFDocumentGetTypeID(void);
+
+
+
+
+extern CGPDFDocumentRef CGPDFDocumentCreateWithProvider(CGDataProviderRef provider);
+
+
+
+extern CGPDFDocumentRef CGPDFDocumentCreateWithURL(CFURLRef url);
+
+
+
+extern CGPDFDocumentRef CGPDFDocumentRetain(CGPDFDocumentRef document);
+
+
+
+extern void CGPDFDocumentRelease(CGPDFDocumentRef document);
+
+
+
+
+
+
+extern bool CGPDFDocumentIsEncrypted(CGPDFDocumentRef document);
+
+
+
+
+
+extern bool CGPDFDocumentUnlockWithPassword(CGPDFDocumentRef document, const char *password);
+
+
+
+
+
+extern bool CGPDFDocumentIsUnlocked(CGPDFDocumentRef document);
+
+
+
+
+
+
+extern bool CGPDFDocumentAllowsPrinting(CGPDFDocumentRef document);
+
+
+
+
+
+
+extern bool CGPDFDocumentAllowsCopying(CGPDFDocumentRef document);
+
+
+
+extern size_t CGPDFDocumentGetNumberOfPages(CGPDFDocumentRef document);
+
+
+
+extern CGRect CGPDFDocumentGetMediaBox(CGPDFDocumentRef document, int page);
+
+
+
+extern CGRect CGPDFDocumentGetCropBox(CGPDFDocumentRef document, int page);
+
+
+
+extern CGRect CGPDFDocumentGetBleedBox(CGPDFDocumentRef document, int page);
+
+
+
+extern CGRect CGPDFDocumentGetTrimBox(CGPDFDocumentRef document, int page);
+
+
+
+extern CGRect CGPDFDocumentGetArtBox(CGPDFDocumentRef document, int page);
+
+
+
+
+extern int CGPDFDocumentGetRotationAngle(CGPDFDocumentRef document, int page);
+
+}
+typedef struct CGFunction *CGFunctionRef;
+typedef void (*CGFunctionEvaluateCallback)(void *info, const float *in, float *out);
+typedef void (*CGFunctionReleaseInfoCallback)(void *info);
+struct CGFunctionCallbacks {
+ unsigned int version;
+ CGFunctionEvaluateCallback evaluate;
+ CGFunctionReleaseInfoCallback releaseInfo;
+};
+typedef struct CGFunctionCallbacks CGFunctionCallbacks;
+
+extern "C" {
+
+
+
+
+
+extern CFTypeID CGFunctionGetTypeID(void);
+extern CGFunctionRef CGFunctionCreate(void *info, size_t domainDimension, const float *domain, size_t rangeDimension, const float *range, const CGFunctionCallbacks *callbacks);
+
+
+
+
+
+
+extern CGFunctionRef CGFunctionRetain(CGFunctionRef function);
+
+
+
+
+
+
+extern void CGFunctionRelease(CGFunctionRef function);
+
+}
+
+
+
+typedef struct CGShading *CGShadingRef;
+
+extern "C" {
+
+
+
+
+
+extern CFTypeID CGShadingGetTypeID(void);
+extern CGShadingRef CGShadingCreateAxial(CGColorSpaceRef colorspace, CGPoint start, CGPoint end, CGFunctionRef function, bool extendStart, bool extendEnd);
+extern CGShadingRef CGShadingCreateRadial(CGColorSpaceRef colorspace, CGPoint start, float startRadius, CGPoint end, float endRadius, CGFunctionRef function, bool extendStart, bool extendEnd);
+
+
+
+
+
+
+extern CGShadingRef CGShadingRetain(CGShadingRef shading);
+
+
+
+
+
+
+extern void CGShadingRelease(CGShadingRef shading);
+
+}
+
+
+extern "C" {
+
+
+
+enum CGLineJoin {
+ kCGLineJoinMiter,
+ kCGLineJoinRound,
+ kCGLineJoinBevel
+};
+typedef enum CGLineJoin CGLineJoin;
+
+
+
+enum CGLineCap {
+ kCGLineCapButt,
+ kCGLineCapRound,
+ kCGLineCapSquare
+};
+typedef enum CGLineCap CGLineCap;
+
+
+
+enum CGPathDrawingMode {
+ kCGPathFill,
+ kCGPathEOFill,
+ kCGPathStroke,
+ kCGPathFillStroke,
+ kCGPathEOFillStroke
+};
+typedef enum CGPathDrawingMode CGPathDrawingMode;
+
+
+
+enum CGTextDrawingMode {
+ kCGTextFill,
+ kCGTextStroke,
+ kCGTextFillStroke,
+ kCGTextInvisible,
+ kCGTextFillClip,
+ kCGTextStrokeClip,
+ kCGTextFillStrokeClip,
+ kCGTextClip
+};
+typedef enum CGTextDrawingMode CGTextDrawingMode;
+
+
+
+enum CGTextEncoding {
+ kCGEncodingFontSpecific,
+ kCGEncodingMacRoman
+};
+typedef enum CGTextEncoding CGTextEncoding;
+
+enum CGInterpolationQuality {
+ kCGInterpolationDefault,
+ kCGInterpolationNone,
+ kCGInterpolationLow,
+ kCGInterpolationHigh
+};
+typedef enum CGInterpolationQuality CGInterpolationQuality;
+
+
+
+extern CFTypeID CGContextGetTypeID(void);
+
+
+
+
+
+
+
+extern void CGContextSaveGState(CGContextRef c);
+
+
+
+
+
+extern void CGContextRestoreGState(CGContextRef c);
+
+
+
+
+
+
+extern void CGContextScaleCTM(CGContextRef c, float sx, float sy);
+
+
+
+
+extern void CGContextTranslateCTM(CGContextRef c, float tx, float ty);
+
+
+
+
+extern void CGContextRotateCTM(CGContextRef c, float angle);
+
+
+
+
+extern void CGContextConcatCTM(CGContextRef c, CGAffineTransform transform);
+
+
+
+extern CGAffineTransform CGContextGetCTM(CGContextRef c);
+
+
+
+
+
+extern void CGContextSetLineWidth(CGContextRef c, float width);
+
+
+
+extern void CGContextSetLineCap(CGContextRef c, CGLineCap cap);
+
+
+
+extern void CGContextSetLineJoin(CGContextRef c, CGLineJoin join);
+
+
+
+extern void CGContextSetMiterLimit(CGContextRef c, float limit);
+
+
+
+extern void CGContextSetLineDash(CGContextRef c, float phase, const float lengths[], size_t count);
+
+
+
+
+extern void CGContextSetFlatness(CGContextRef c, float flatness);
+
+
+
+extern void CGContextSetAlpha(CGContextRef c, float alpha);
+extern void CGContextBeginPath(CGContextRef c);
+
+
+
+extern void CGContextMoveToPoint(CGContextRef c, float x, float y);
+
+
+
+extern void CGContextAddLineToPoint(CGContextRef c, float x, float y);
+
+
+
+
+extern void CGContextAddCurveToPoint(CGContextRef c, float cp1x, float cp1y, float cp2x, float cp2y, float x, float y);
+
+
+
+
+extern void CGContextAddQuadCurveToPoint(CGContextRef c, float cpx, float cpy, float x, float y);
+
+
+
+extern void CGContextClosePath(CGContextRef c);
+
+
+
+
+
+extern void CGContextAddRect(CGContextRef c, CGRect rect);
+
+
+
+extern void CGContextAddRects(CGContextRef c, const CGRect rects[], size_t count);
+
+
+
+extern void CGContextAddLines(CGContextRef c, const CGPoint points[], size_t count);
+extern void CGContextAddArc(CGContextRef c, float x, float y, float radius, float startAngle, float endAngle, int clockwise);
+
+
+
+
+
+
+extern void CGContextAddArcToPoint(CGContextRef c, float x1, float y1, float x2, float y2, float radius);
+
+
+
+
+extern void CGContextAddPath(CGContextRef context, CGPathRef path);
+
+
+
+
+
+extern int CGContextIsPathEmpty(CGContextRef c);
+
+
+
+
+extern CGPoint CGContextGetPathCurrentPoint(CGContextRef c);
+
+
+
+
+
+extern CGRect CGContextGetPathBoundingBox(CGContextRef c);
+
+
+
+
+
+extern void CGContextDrawPath(CGContextRef c, CGPathDrawingMode mode);
+
+
+
+
+
+
+extern void CGContextFillPath(CGContextRef c);
+
+
+
+
+extern void CGContextEOFillPath(CGContextRef c);
+
+
+
+extern void CGContextStrokePath(CGContextRef c);
+
+
+
+extern void CGContextFillRect(CGContextRef c, CGRect rect);
+
+
+
+
+extern void CGContextFillRects(CGContextRef c, const CGRect rects[], size_t count);
+
+
+
+extern void CGContextStrokeRect(CGContextRef c, CGRect rect);
+
+
+
+
+extern void CGContextStrokeRectWithWidth(CGContextRef c, CGRect rect, float width);
+
+
+
+
+extern void CGContextClearRect(CGContextRef c, CGRect rect);
+
+
+
+
+
+
+
+extern void CGContextClip(CGContextRef c);
+
+
+
+
+
+extern void CGContextEOClip(CGContextRef c);
+
+
+
+
+
+
+extern void CGContextClipToRect(CGContextRef c, CGRect rect);
+
+
+
+
+
+extern void CGContextClipToRects(CGContextRef c, const CGRect rects[], size_t count);
+
+
+
+
+
+
+
+extern void CGContextSetFillColorSpace(CGContextRef c, CGColorSpaceRef colorspace);
+
+
+
+
+
+extern void CGContextSetStrokeColorSpace(CGContextRef c, CGColorSpaceRef colorspace);
+extern void CGContextSetFillColor(CGContextRef c, const float components[]);
+
+
+
+
+
+
+
+extern void CGContextSetStrokeColor(CGContextRef c, const float components[]);
+extern void CGContextSetFillPattern(CGContextRef c, CGPatternRef pattern, const float components[]);
+extern void CGContextSetStrokePattern(CGContextRef c, CGPatternRef pattern, const float components[]);
+
+
+
+extern void CGContextSetPatternPhase(CGContextRef c, CGSize phase);
+
+
+
+
+
+
+extern void CGContextSetGrayFillColor(CGContextRef c, float gray, float alpha);
+
+
+
+
+extern void CGContextSetGrayStrokeColor(CGContextRef c, float gray, float alpha);
+
+
+
+
+
+extern void CGContextSetRGBFillColor(CGContextRef c, float red, float green, float blue, float alpha);
+
+
+
+
+
+extern void CGContextSetRGBStrokeColor(CGContextRef c, float red, float green, float blue, float alpha);
+
+
+
+
+
+extern void CGContextSetCMYKFillColor(CGContextRef c, float cyan, float magenta, float yellow, float black, float alpha);
+
+
+
+
+
+extern void CGContextSetCMYKStrokeColor(CGContextRef c, float cyan, float magenta, float yellow, float black, float alpha);
+
+
+
+
+
+extern void CGContextSetRenderingIntent(CGContextRef c, CGColorRenderingIntent intent);
+
+
+
+
+
+
+extern void CGContextDrawImage(CGContextRef c, CGRect rect, CGImageRef image);
+
+
+
+
+
+
+
+extern CGInterpolationQuality CGContextGetInterpolationQuality(CGContextRef c);
+
+
+
+extern void CGContextSetInterpolationQuality(CGContextRef c, CGInterpolationQuality quality);
+
+
+
+
+
+extern void CGContextDrawShading(CGContextRef c, CGShadingRef shading);
+
+
+
+
+
+
+
+extern void CGContextSetCharacterSpacing(CGContextRef c, float spacing);
+
+
+
+
+extern void CGContextSetTextPosition(CGContextRef c, float x, float y);
+
+
+
+
+extern CGPoint CGContextGetTextPosition(CGContextRef c);
+
+
+
+extern void CGContextSetTextMatrix(CGContextRef c, CGAffineTransform t);
+
+
+
+extern CGAffineTransform CGContextGetTextMatrix(CGContextRef c);
+
+
+
+extern void CGContextSetTextDrawingMode(CGContextRef c, CGTextDrawingMode mode);
+
+
+
+extern void CGContextSetFont(CGContextRef c, CGFontRef font);
+
+
+
+extern void CGContextSetFontSize(CGContextRef c, float size);
+
+
+
+
+
+extern void CGContextSelectFont(CGContextRef c, const char *name, float size, CGTextEncoding textEncoding);
+
+
+
+
+
+
+extern void CGContextShowText(CGContextRef c, const char *string, size_t length);
+
+
+
+
+extern void CGContextShowGlyphs(CGContextRef c, const CGGlyph g[], size_t count);
+extern void CGContextShowTextAtPoint(CGContextRef c, float x, float y, const char *string, size_t length);
+
+
+
+
+
+extern void CGContextShowGlyphsAtPoint(CGContextRef c, float x, float y, const CGGlyph glyphs[], size_t count);
+
+
+
+
+
+
+
+extern void CGContextDrawPDFDocument(CGContextRef c, CGRect rect, CGPDFDocumentRef document, int page);
+
+
+
+
+
+extern void CGContextBeginPage(CGContextRef c, const CGRect *mediaBox);
+
+
+
+extern void CGContextEndPage(CGContextRef c);
+
+
+
+
+
+extern CGContextRef CGContextRetain(CGContextRef c);
+
+
+
+extern void CGContextRelease(CGContextRef c);
+
+
+
+extern void CGContextFlush(CGContextRef c);
+
+
+
+extern void CGContextSynchronize(CGContextRef c);
+
+
+
+
+
+
+extern void CGContextSetShouldAntialias(CGContextRef c, bool shouldAntialias);
+
+
+
+
+
+
+extern void CGContextSetShouldSmoothFonts(CGContextRef c, bool shouldSmoothFonts);
+
+}
+
+extern "C" {
+extern CGContextRef CGBitmapContextCreate(void *data, size_t width, size_t height, size_t bitsPerComponent, size_t bytesPerRow, CGColorSpaceRef colorspace, CGImageAlphaInfo alphaInfo);
+
+
+
+
+extern void *CGBitmapContextGetData(CGContextRef c);
+
+
+
+
+extern size_t CGBitmapContextGetWidth(CGContextRef c);
+
+
+
+
+extern size_t CGBitmapContextGetHeight(CGContextRef c);
+
+
+
+
+extern size_t CGBitmapContextGetBitsPerComponent(CGContextRef c);
+
+
+
+
+extern size_t CGBitmapContextGetBitsPerPixel(CGContextRef c);
+
+
+
+
+extern size_t CGBitmapContextGetBytesPerRow(CGContextRef c);
+
+
+
+
+extern CGColorSpaceRef CGBitmapContextGetColorSpace(CGContextRef c);
+
+
+
+
+extern CGImageAlphaInfo CGBitmapContextGetAlphaInfo(CGContextRef c);
+
+}
+
+
+typedef struct CGDataConsumer *CGDataConsumerRef;
+
+
+
+
+extern "C" {
+
+
+
+
+
+
+
+struct CGDataConsumerCallbacks {
+ size_t (*putBytes)(void *info, const void *buffer, size_t count);
+ void (*releaseConsumer)(void *info);
+};
+typedef struct CGDataConsumerCallbacks CGDataConsumerCallbacks;
+
+
+
+extern CFTypeID CGDataConsumerGetTypeID(void);
+
+
+
+
+extern CGDataConsumerRef CGDataConsumerCreate(void *info, const CGDataConsumerCallbacks *callbacks);
+
+
+
+extern CGDataConsumerRef CGDataConsumerCreateWithURL(CFURLRef url);
+
+
+
+extern CGDataConsumerRef CGDataConsumerRetain(CGDataConsumerRef consumer);
+
+
+
+extern void CGDataConsumerRelease(CGDataConsumerRef consumer);
+
+}
+
+extern "C" {
+
+
+enum _CGError {
+ kCGErrorSuccess = 0,
+ kCGErrorFirst = 1000,
+ kCGErrorFailure = kCGErrorFirst,
+ kCGErrorIllegalArgument = 1001,
+ kCGErrorInvalidConnection = 1002,
+ kCGErrorInvalidContext = 1003,
+ kCGErrorCannotComplete = 1004,
+ kCGErrorNameTooLong = 1005,
+ kCGErrorNotImplemented = 1006,
+ kCGErrorRangeCheck = 1007,
+ kCGErrorTypeCheck = 1008,
+ kCGErrorNoCurrentPoint = 1009,
+ kCGErrorInvalidOperation = 1010,
+ kCGErrorNoneAvailable = 1011,
+
+
+ kCGErrorApplicationRequiresNewerSystem = 1015,
+
+
+
+ kCGErrorApplicationNotPermittedToExecute = 1016,
+
+
+ kCGErrorLast = kCGErrorApplicationRequiresNewerSystem
+};
+typedef int32_t CGError;
+
+}
+
+
+extern double acos (double);
+extern double asin (double);
+extern double atan (double);
+extern double atan2 (double, double);
+extern double ceil (double);
+extern double cos (double);
+extern double cosh (double);
+extern double exp (double);
+extern double fabs (double);
+extern double floor (double);
+extern double fmod (double, double);
+extern double frexp (double, int *);
+extern double ldexp (double, int);
+extern double log10 (double);
+extern double log (double);
+extern double modf (double, double *);
+extern double pow (double, double);
+extern double sin (double);
+extern double sinh (double);
+extern double sqrt (double);
+extern double tan (double);
+extern double tanh (double);
+
+
+extern "C" {
+
+typedef struct _CGDirectDisplayID * CGDirectDisplayID;
+typedef struct _CGDirectPaletteRef * CGDirectPaletteRef;
+typedef uint32_t CGDisplayCount;
+typedef uint32_t CGTableCount;
+typedef int32_t CGDisplayCoord;
+typedef uint8_t CGByteValue;
+typedef uint32_t CGOpenGLDisplayMask;
+typedef uint32_t CGBeamPosition;
+typedef int32_t CGMouseDelta;
+typedef double CGRefreshRate;
+
+typedef CGError CGDisplayErr;
+CGDirectDisplayID CGMainDisplayID(void);
+CGDisplayErr CGGetDisplaysWithPoint(CGPoint point,
+ CGDisplayCount maxDisplays,
+ CGDirectDisplayID * dspys,
+ CGDisplayCount * dspyCnt);
+
+CGDisplayErr CGGetDisplaysWithRect(CGRect rect,
+ CGDisplayCount maxDisplays,
+ CGDirectDisplayID * dspys,
+ CGDisplayCount * dspyCnt);
+
+CGDisplayErr CGGetDisplaysWithOpenGLDisplayMask(CGOpenGLDisplayMask mask,
+ CGDisplayCount maxDisplays,
+ CGDirectDisplayID * dspys,
+ CGDisplayCount * dspyCnt);
+CGDisplayErr CGGetActiveDisplayList(CGDisplayCount maxDisplays,
+ CGDirectDisplayID * activeDspys,
+ CGDisplayCount * dspyCnt);
+CGDisplayErr CGGetOnlineDisplayList(CGDisplayCount maxDisplays,
+ CGDirectDisplayID * onlineDspys,
+ CGDisplayCount * dspyCnt);
+
+
+CGOpenGLDisplayMask CGDisplayIDToOpenGLDisplayMask(CGDirectDisplayID display);
+
+
+
+
+
+
+
+CGDirectDisplayID CGOpenGLDisplayMaskToDisplayID(CGOpenGLDisplayMask mask);
+
+
+CGRect CGDisplayBounds(CGDirectDisplayID display);
+
+size_t CGDisplayPixelsWide(CGDirectDisplayID display);
+size_t CGDisplayPixelsHigh(CGDirectDisplayID display);
+CFArrayRef CGDisplayAvailableModes(CGDirectDisplayID display);
+CFDictionaryRef CGDisplayBestModeForParameters(CGDirectDisplayID display, size_t bitsPerPixel, size_t width, size_t height, boolean_t * exactMatch);
+
+CFDictionaryRef CGDisplayBestModeForParametersAndRefreshRate(CGDirectDisplayID display, size_t bitsPerPixel, size_t width, size_t height, CGRefreshRate refresh, boolean_t * exactMatch);
+
+CFDictionaryRef CGDisplayBestModeForParametersAndRefreshRateWithProperty(CGDirectDisplayID display, size_t bitsPerPixel, size_t width, size_t height, CGRefreshRate refresh, CFStringRef property, boolean_t * exactMatch);
+
+
+
+
+
+CFDictionaryRef CGDisplayCurrentMode(CGDirectDisplayID display);
+CGDisplayErr CGDisplaySwitchToMode(CGDirectDisplayID display, CFDictionaryRef mode);
+
+
+size_t CGDisplayBitsPerPixel(CGDirectDisplayID display);
+size_t CGDisplayBitsPerSample(CGDirectDisplayID display);
+size_t CGDisplaySamplesPerPixel(CGDirectDisplayID display);
+size_t CGDisplayBytesPerRow(CGDirectDisplayID display);
+typedef float CGGammaValue;
+
+CGDisplayErr CGSetDisplayTransferByFormula(CGDirectDisplayID display,
+ CGGammaValue redMin,
+ CGGammaValue redMax,
+ CGGammaValue redGamma,
+ CGGammaValue greenMin,
+ CGGammaValue greenMax,
+ CGGammaValue greenGamma,
+ CGGammaValue blueMin,
+ CGGammaValue blueMax,
+ CGGammaValue blueGamma);
+
+CGDisplayErr CGGetDisplayTransferByFormula(CGDirectDisplayID display,
+ CGGammaValue *redMin,
+ CGGammaValue *redMax,
+ CGGammaValue *redGamma,
+ CGGammaValue *greenMin,
+ CGGammaValue *greenMax,
+ CGGammaValue *greenGamma,
+ CGGammaValue *blueMin,
+ CGGammaValue *blueMax,
+ CGGammaValue *blueGamma);
+CGDisplayErr CGSetDisplayTransferByTable(CGDirectDisplayID display,
+ CGTableCount tableSize,
+ const CGGammaValue *redTable,
+ const CGGammaValue *greenTable,
+ const CGGammaValue *blueTable);
+
+
+
+
+
+
+CGDisplayErr CGGetDisplayTransferByTable(CGDirectDisplayID display,
+ CGTableCount capacity,
+ CGGammaValue *redTable,
+ CGGammaValue *greenTable,
+ CGGammaValue *blueTable,
+ CGTableCount *sampleCount);
+
+
+CGDisplayErr CGSetDisplayTransferByByteTable(CGDirectDisplayID display,
+ CGTableCount tableSize,
+ const CGByteValue *redTable,
+ const CGByteValue *greenTable,
+ const CGByteValue *blueTable);
+
+
+void CGDisplayRestoreColorSyncSettings(void);
+
+
+
+boolean_t CGDisplayIsCaptured(CGDirectDisplayID display);
+CGDisplayErr CGDisplayCapture(CGDirectDisplayID display);
+CGDisplayErr CGDisplayRelease(CGDirectDisplayID display);
+
+
+
+
+
+
+CGDisplayErr CGCaptureAllDisplays(void);
+
+
+
+
+
+CGDisplayErr CGReleaseAllDisplays(void);
+
+
+
+
+
+void * CGShieldingWindowID(CGDirectDisplayID display);
+
+
+
+
+
+
+int32_t CGShieldingWindowLevel(void);
+
+
+
+
+
+
+void * CGDisplayBaseAddress(CGDirectDisplayID display);
+
+
+
+
+
+
+
+void * CGDisplayAddressForPosition(CGDirectDisplayID display, CGDisplayCoord x, CGDisplayCoord y);
+
+
+
+CGDisplayErr CGDisplayHideCursor(CGDirectDisplayID display);
+CGDisplayErr CGDisplayShowCursor(CGDirectDisplayID display);
+
+
+
+
+
+
+
+CGDisplayErr CGDisplayMoveCursorToPoint(CGDirectDisplayID display, CGPoint point);
+
+
+
+
+
+void CGGetLastMouseDelta( CGMouseDelta * deltaX, CGMouseDelta * deltaY );
+boolean_t CGDisplayCanSetPalette(CGDirectDisplayID display);
+CGDisplayErr CGDisplaySetPalette(CGDirectDisplayID display, const CGDirectPaletteRef palette);
+CGDisplayErr CGDisplayWaitForBeamPositionOutsideLines( CGDirectDisplayID display,
+ CGBeamPosition upperScanLine,
+ CGBeamPosition lowerScanLine );
+
+
+
+
+
+
+CGBeamPosition CGDisplayBeamPosition( CGDirectDisplayID display );
+
+}
+extern "C" {
+
+typedef float CGPaletteBlendFraction;
+
+
+
+
+
+
+
+struct _CGDeviceColor
+{
+ float red;
+ float green;
+ float blue;
+};
+typedef struct _CGDeviceColor CGDeviceColor;
+
+struct _CGDeviceByteColor
+{
+ CGByteValue red;
+ CGByteValue green;
+ CGByteValue blue;
+};
+typedef struct _CGDeviceByteColor CGDeviceByteColor;
+
+
+
+
+
+CGDirectPaletteRef CGPaletteCreateDefaultColorPalette(void);
+
+
+
+
+
+
+CGDirectPaletteRef CGPaletteCreateWithDisplay(CGDirectDisplayID display);
+
+
+
+
+
+CGDirectPaletteRef CGPaletteCreateWithCapacity( CGTableCount capacity );
+
+
+
+
+
+CGDirectPaletteRef CGPaletteCreateWithSamples(CGDeviceColor * sampleTable, CGTableCount sampleCount);
+
+
+
+
+
+
+CGDirectPaletteRef CGPaletteCreateWithByteSamples(CGDeviceByteColor * sampleTable, CGTableCount sampleCount);
+
+
+
+
+void CGPaletteRelease( CGDirectPaletteRef palette );
+
+
+
+
+CGDeviceColor CGPaletteGetColorAtIndex(CGDirectPaletteRef palette, CGTableCount index);
+
+
+
+
+
+
+CGTableCount CGPaletteGetIndexForColor(CGDirectPaletteRef palette, CGDeviceColor color);
+
+
+
+
+CGTableCount CGPaletteGetNumberOfSamples(CGDirectPaletteRef palette);
+
+
+
+
+
+void CGPaletteSetColorAtIndex(CGDirectPaletteRef palette, CGDeviceColor color, CGTableCount index);
+
+
+
+
+CGDirectPaletteRef CGPaletteCreateCopy(CGDirectPaletteRef palette);
+
+
+
+
+Boolean CGPaletteIsEqualToPalette(CGDirectPaletteRef palette1, CGDirectPaletteRef palette2);
+
+
+
+
+
+CGDirectPaletteRef CGPaletteCreateFromPaletteBlendedWithColor(
+ CGDirectPaletteRef palette,
+ CGPaletteBlendFraction fraction,
+ CGDeviceColor color);
+
+}
+extern "C" {
+typedef struct _CGDisplayConfigRef * CGDisplayConfigRef;
+
+
+CGError CGBeginDisplayConfiguration(CGDisplayConfigRef *pConfigRef);
+CGError CGConfigureDisplayOrigin(CGDisplayConfigRef configRef,
+ CGDirectDisplayID display,
+ CGDisplayCoord x,
+ CGDisplayCoord y);
+CGError CGConfigureDisplayMode(CGDisplayConfigRef configRef,
+ CGDirectDisplayID display,
+ CFDictionaryRef mode);
+CGError CGConfigureDisplayMirrorOfDisplay(CGDisplayConfigRef configRef,
+ CGDirectDisplayID display,
+ CGDirectDisplayID masterDisplay);
+
+
+CGError CGCancelDisplayConfiguration(CGDisplayConfigRef configRef);
+enum {
+ kCGConfigureForAppOnly = 0,
+ kCGConfigureForSession = 1,
+ kCGConfigurePermanently = 2
+};
+typedef u_int32_t CGConfigureOption;
+
+CGError CGCompleteDisplayConfiguration( CGDisplayConfigRef configRef, CGConfigureOption option );
+
+
+void CGRestorePermanentDisplayConfiguration(void);
+boolean_t CGDisplayIsActive(CGDirectDisplayID display);
+
+
+boolean_t CGDisplayIsAsleep(CGDirectDisplayID display);
+
+
+
+
+
+ boolean_t CGDisplayIsOnline(CGDirectDisplayID display);
+
+
+boolean_t CGDisplayIsMain(CGDirectDisplayID display);
+
+
+boolean_t CGDisplayIsBuiltin(CGDirectDisplayID display);
+
+
+boolean_t CGDisplayIsInMirrorSet(CGDirectDisplayID display);
+
+
+boolean_t CGDisplayIsAlwaysInMirrorSet(CGDirectDisplayID display);
+
+
+boolean_t CGDisplayIsInHWMirrorSet(CGDirectDisplayID display);
+
+
+CGDirectDisplayID CGDisplayMirrorsDisplay(CGDirectDisplayID display);
+
+
+boolean_t CGDisplayUsesOpenGLAcceleration(CGDirectDisplayID display);
+
+
+
+
+
+
+CGDirectDisplayID CGDisplayPrimaryDisplay(CGDirectDisplayID display);
+
+
+
+
+
+uint32_t CGDisplayUnitNumber(CGDirectDisplayID display);
+uint32_t CGDisplayVendorNumber(CGDirectDisplayID display);
+uint32_t CGDisplayModelNumber(CGDirectDisplayID display);
+uint32_t CGDisplaySerialNumber(CGDirectDisplayID display);
+
+
+
+
+}
+extern "C" {
+
+typedef uint32_t CGDisplayFadeReservationToken;
+
+
+typedef float CGDisplayBlendFraction;
+typedef float CGDisplayFadeInterval;
+CGError CGConfigureDisplayFadeEffect(CGDisplayConfigRef configRef,
+ CGDisplayFadeInterval fadeOutSeconds,
+ CGDisplayFadeInterval fadeInSeconds,
+ float fadeRed,
+ float fadeGreen,
+ float fadeBlue);
+
+
+
+
+
+
+
+typedef float CGDisplayReservationInterval;
+CGError CGAcquireDisplayFadeReservation(CGDisplayReservationInterval seconds,
+ CGDisplayFadeReservationToken * pNewToken);
+CGError CGReleaseDisplayFadeReservation(CGDisplayFadeReservationToken myToken);
+CGError CGDisplayFade(CGDisplayFadeReservationToken myToken,
+ CGDisplayFadeInterval seconds,
+ CGDisplayBlendFraction startBlend,
+ CGDisplayBlendFraction endBlend,
+ float redBlend, float greenBlend, float blueBlend,
+ boolean_t synchronous );
+
+
+
+
+boolean_t CGDisplayFadeOperationInProgress(void);
+
+
+
+}
+
+
+
+
+
+
+
+extern "C" {
+
+
+
+
+
+
+
+extern CGContextRef CGPDFContextCreate(CGDataConsumerRef consumer, const CGRect *mediaBox, CFDictionaryRef auxiliaryInfo);
+
+
+
+extern CGContextRef CGPDFContextCreateWithURL(CFURLRef url, const CGRect *mediaBox, CFDictionaryRef auxiliaryInfo);
+}
+
+extern "C" {
+
+typedef CGError CGEventErr;
+typedef u_int32_t CGRectCount;
+typedef void (*CGScreenRefreshCallback)(CGRectCount count, const CGRect * rectArray, void * userParameter);
+
+
+
+
+
+
+
+extern void CGRegisterScreenRefreshCallback( CGScreenRefreshCallback function, void * userParameter );
+
+
+
+
+
+extern void CGUnregisterScreenRefreshCallback( CGScreenRefreshCallback function, void * userParameter );
+extern CGEventErr CGWaitForScreenRefreshRects( CGRect ** pRectArray, CGRectCount * pCount );
+
+
+
+
+extern void CGReleaseScreenRefreshRects( CGRect * rectArray );
+typedef u_int32_t CGButtonCount;
+extern CGEventErr CGPostMouseEvent( CGPoint mouseCursorPosition,
+ boolean_t updateMouseCursorPosition,
+ CGButtonCount buttonCount,
+ boolean_t mouseButtonDown, ... );
+typedef u_int32_t CGWheelCount;
+extern CGEventErr CGPostScrollWheelEvent( CGWheelCount wheelCount,
+ int32_t wheel1, ... );
+typedef u_int16_t CGCharCode;
+typedef u_int16_t CGKeyCode;
+
+extern CGEventErr CGPostKeyboardEvent( CGCharCode keyChar,
+ CGKeyCode virtualKey,
+ boolean_t keyDown );
+
+
+
+
+
+extern CGEventErr CGWarpMouseCursorPosition( CGPoint newCursorPosition );
+extern CGEventErr CGInhibitLocalEvents( boolean_t doInhibit);
+
+
+
+
+
+extern CGEventErr CGSetLocalEventsSuppressionInterval(CFTimeInterval seconds);
+extern CGEventErr CGEnableEventStateCombining(boolean_t doCombineState);
+enum
+{
+ kCGEventFilterMaskPermitLocalMouseEvents = 0x00000001,
+ kCGEventFilterMaskPermitLocalKeyboardEvents = 0x00000002,
+ kCGEventFilterMaskPermitSystemDefinedEvents = 0x00000004
+};
+typedef uint32_t CGEventFilterMask;
+
+enum
+{
+ kCGEventSupressionStateSupressionInterval = 0,
+ kCGEventSupressionStateRemoteMouseDrag,
+ kCGNumberOfEventSupressionStates
+};
+typedef uint32_t CGEventSupressionState;
+
+
+
+
+
+extern CGEventErr CGSetLocalEventsFilterDuringSupressionState(CGEventFilterMask filter,
+CGEventSupressionState state);
+extern CGEventErr CGAssociateMouseAndMouseCursorPosition(boolean_t connected);
+extern CFMachPortRef CGWindowServerCFMachPort(void);
+
+
+}
+
+extern "C" {
+typedef int32_t CGWindowLevel;
+typedef int32_t CGWindowLevelKey;
+
+enum _CGCommonWindowLevelKey {
+ kCGBaseWindowLevelKey = 0,
+ kCGMinimumWindowLevelKey,
+ kCGDesktopWindowLevelKey,
+ kCGBackstopMenuLevelKey,
+ kCGNormalWindowLevelKey,
+ kCGFloatingWindowLevelKey,
+ kCGTornOffMenuWindowLevelKey,
+ kCGDockWindowLevelKey,
+ kCGMainMenuWindowLevelKey,
+ kCGStatusWindowLevelKey,
+ kCGModalPanelWindowLevelKey,
+ kCGPopUpMenuWindowLevelKey,
+ kCGDraggingWindowLevelKey,
+ kCGScreenSaverWindowLevelKey,
+ kCGMaximumWindowLevelKey,
+ kCGOverlayWindowLevelKey,
+ kCGHelpWindowLevelKey,
+ kCGUtilityWindowLevelKey,
+ kCGDesktopIconWindowLevelKey,
+ kCGCursorWindowLevelKey,
+ kCGNumberOfWindowLevelKeys
+};
+
+CGWindowLevel CGWindowLevelForKey( CGWindowLevelKey key );
+}
+
+
+
+extern "C" {
+
+
+typedef long CMError;
+
+typedef struct OpaqueCMProfileRef* CMProfileRef;
+
+typedef struct OpaqueCMProfileSearchRef* CMProfileSearchRef;
+
+typedef struct OpaqueCMMatchRef* CMMatchRef;
+
+typedef struct OpaqueCMWorldRef* CMWorldRef;
+
+
+
+typedef UInt32 CMDisplayIDType;
+
+
+typedef OSErr ( * CMFlattenProcPtr)(long command, long *size, void *data, void *refCon);
+
+typedef Boolean ( * CMBitmapCallBackProcPtr)(long progress, void *refCon);
+
+typedef Boolean ( * CMConcatCallBackProcPtr)(long progress, void *refCon);
+
+typedef Boolean ( * CMProfileFilterProcPtr)(CMProfileRef prof, void *refCon);
+
+typedef OSErr ( * CMProfileAccessProcPtr)(long command, long offset, long *size, void *data, void *refCon);
+typedef CMFlattenProcPtr CMFlattenUPP;
+typedef CMBitmapCallBackProcPtr CMBitmapCallBackUPP;
+typedef CMConcatCallBackProcPtr CMConcatCallBackUPP;
+typedef CMProfileFilterProcPtr CMProfileFilterUPP;
+typedef CMProfileAccessProcPtr CMProfileAccessUPP;
+extern CMFlattenUPP
+NewCMFlattenUPP(CMFlattenProcPtr userRoutine) ;
+extern CMBitmapCallBackUPP
+NewCMBitmapCallBackUPP(CMBitmapCallBackProcPtr userRoutine) ;
+extern CMConcatCallBackUPP
+NewCMConcatCallBackUPP(CMConcatCallBackProcPtr userRoutine) ;
+extern CMProfileFilterUPP
+NewCMProfileFilterUPP(CMProfileFilterProcPtr userRoutine) ;
+extern CMProfileAccessUPP
+NewCMProfileAccessUPP(CMProfileAccessProcPtr userRoutine) ;
+extern void
+DisposeCMFlattenUPP(CMFlattenUPP userUPP) ;
+extern void
+DisposeCMBitmapCallBackUPP(CMBitmapCallBackUPP userUPP) ;
+extern void
+DisposeCMConcatCallBackUPP(CMConcatCallBackUPP userUPP) ;
+extern void
+DisposeCMProfileFilterUPP(CMProfileFilterUPP userUPP) ;
+extern void
+DisposeCMProfileAccessUPP(CMProfileAccessUPP userUPP) ;
+extern OSErr
+InvokeCMFlattenUPP(
+ long command,
+ long * size,
+ void * data,
+ void * refCon,
+ CMFlattenUPP userUPP) ;
+extern Boolean
+InvokeCMBitmapCallBackUPP(
+ long progress,
+ void * refCon,
+ CMBitmapCallBackUPP userUPP) ;
+extern Boolean
+InvokeCMConcatCallBackUPP(
+ long progress,
+ void * refCon,
+ CMConcatCallBackUPP userUPP) ;
+extern Boolean
+InvokeCMProfileFilterUPP(
+ CMProfileRef prof,
+ void * refCon,
+ CMProfileFilterUPP userUPP) ;
+extern OSErr
+InvokeCMProfileAccessUPP(
+ long command,
+ long offset,
+ long * size,
+ void * data,
+ void * refCon,
+ CMProfileAccessUPP userUPP) ;
+
+
+
+}
+
+
+
+
+
+enum {
+ cmICCProfileVersion4 = 0x04000000,
+ cmICCProfileVersion2 = 0x02000000,
+ cmICCProfileVersion21 = 0x02100000,
+ cmCS2ProfileVersion = cmICCProfileVersion2,
+ cmCS1ProfileVersion = 0x00000100
+};
+
+
+enum {
+ cmProfileMajorVersionMask = (long)0xFF000000,
+ cmCurrentProfileMajorVersion = 0x02000000
+};
+
+
+enum {
+ cmMagicNumber = 'acsp'
+};
+
+
+
+
+
+
+enum {
+ cmICCReservedFlagsMask = 0x0000FFFF,
+ cmEmbeddedMask = 0x00000001,
+ cmEmbeddedUseMask = 0x00000002,
+ cmCMSReservedFlagsMask = (long)0xFFFF0000,
+ cmQualityMask = 0x00030000,
+ cmInterpolationMask = 0x00040000,
+ cmGamutCheckingMask = 0x00080000
+};
+
+
+enum {
+ cmEmbeddedProfile = 0,
+ cmEmbeddedUse = 1
+};
+
+
+enum {
+ cmNormalMode = 0,
+ cmDraftMode = 1,
+ cmBestMode = 2
+};
+
+
+
+
+
+
+enum {
+ cmReflectiveTransparentMask = 0x00000001,
+ cmGlossyMatteMask = 0x00000002
+};
+
+
+enum {
+ cmReflective = 0,
+ cmGlossy = 1
+};
+
+
+
+enum {
+ cmPerceptual = 0,
+ cmRelativeColorimetric = 1,
+ cmSaturation = 2,
+ cmAbsoluteColorimetric = 3
+};
+
+
+
+
+enum {
+ cmAsciiData = 0,
+ cmBinaryData = 1
+};
+
+
+enum {
+ cmPrtrDefaultScreens = 0,
+ cmLinesPer = 1
+};
+
+
+enum {
+ cmNumHeaderElements = 10
+};
+
+
+enum {
+ cmAToB0Tag = 'A2B0',
+ cmAToB1Tag = 'A2B1',
+ cmAToB2Tag = 'A2B2',
+ cmBlueColorantTag = 'bXYZ',
+ cmBlueTRCTag = 'bTRC',
+ cmBToA0Tag = 'B2A0',
+ cmBToA1Tag = 'B2A1',
+ cmBToA2Tag = 'B2A2',
+ cmCalibrationDateTimeTag = 'calt',
+ cmChromaticAdaptationTag = 'chad',
+ cmCharTargetTag = 'targ',
+ cmCopyrightTag = 'cprt',
+ cmDeviceMfgDescTag = 'dmnd',
+ cmDeviceModelDescTag = 'dmdd',
+ cmGamutTag = 'gamt',
+ cmGrayTRCTag = 'kTRC',
+ cmGreenColorantTag = 'gXYZ',
+ cmGreenTRCTag = 'gTRC',
+ cmLuminanceTag = 'lumi',
+ cmMeasurementTag = 'meas',
+ cmMediaBlackPointTag = 'bkpt',
+ cmMediaWhitePointTag = 'wtpt',
+ cmNamedColorTag = 'ncol',
+ cmNamedColor2Tag = 'ncl2',
+ cmPreview0Tag = 'pre0',
+ cmPreview1Tag = 'pre1',
+ cmPreview2Tag = 'pre2',
+ cmProfileDescriptionTag = 'desc',
+ cmProfileSequenceDescTag = 'pseq',
+ cmPS2CRD0Tag = 'psd0',
+ cmPS2CRD1Tag = 'psd1',
+ cmPS2CRD2Tag = 'psd2',
+ cmPS2CRD3Tag = 'psd3',
+ cmPS2CSATag = 'ps2s',
+ cmPS2RenderingIntentTag = 'ps2i',
+ cmRedColorantTag = 'rXYZ',
+ cmRedTRCTag = 'rTRC',
+ cmScreeningDescTag = 'scrd',
+ cmScreeningTag = 'scrn',
+ cmTechnologyTag = 'tech',
+ cmUcrBgTag = 'bfd ',
+ cmViewingConditionsDescTag = 'vued',
+ cmViewingConditionsTag = 'view'
+};
+
+
+enum {
+ cmPS2CRDVMSizeTag = 'psvm',
+ cmVideoCardGammaTag = 'vcgt',
+ cmMakeAndModelTag = 'mmod',
+ cmProfileDescriptionMLTag = 'dscm',
+ cmNativeDisplayInfoTag = 'ndin'
+};
+
+
+enum {
+ cmSigCrdInfoType = 'crdi',
+ cmSigCurveType = 'curv',
+ cmSigDataType = 'data',
+ cmSigDateTimeType = 'dtim',
+ cmSigLut16Type = 'mft2',
+ cmSigLut8Type = 'mft1',
+ cmSigMeasurementType = 'meas',
+ cmSigMultiFunctA2BType = 'mAB ',
+ cmSigMultiFunctB2AType = 'mBA ',
+ cmSigNamedColorType = 'ncol',
+ cmSigNamedColor2Type = 'ncl2',
+ cmSigParametricCurveType = 'para',
+ cmSigProfileDescriptionType = 'desc',
+ cmSigProfileSequenceDescType = 'pseq',
+ cmSigScreeningType = 'scrn',
+ cmSigS15Fixed16Type = 'sf32',
+ cmSigSignatureType = 'sig ',
+ cmSigTextType = 'text',
+ cmSigU16Fixed16Type = 'uf32',
+ cmSigU1Fixed15Type = 'uf16',
+ cmSigUInt8Type = 'ui08',
+ cmSigUInt16Type = 'ui16',
+ cmSigUInt32Type = 'ui32',
+ cmSigUInt64Type = 'ui64',
+ cmSigUcrBgType = 'bfd ',
+ cmSigUnicodeTextType = 'utxt',
+ cmSigViewingConditionsType = 'view',
+ cmSigXYZType = 'XYZ '
+};
+
+
+enum {
+ cmSigPS2CRDVMSizeType = 'psvm',
+ cmSigVideoCardGammaType = 'vcgt',
+ cmSigMakeAndModelType = 'mmod',
+ cmSigNativeDisplayInfoType = 'ndin',
+ cmSigMultiLocalizedUniCodeType = 'mluc'
+};
+
+
+
+enum {
+ cmTechnologyDigitalCamera = 'dcam',
+ cmTechnologyFilmScanner = 'fscn',
+ cmTechnologyReflectiveScanner = 'rscn',
+ cmTechnologyInkJetPrinter = 'ijet',
+ cmTechnologyThermalWaxPrinter = 'twax',
+ cmTechnologyElectrophotographicPrinter = 'epho',
+ cmTechnologyElectrostaticPrinter = 'esta',
+ cmTechnologyDyeSublimationPrinter = 'dsub',
+ cmTechnologyPhotographicPaperPrinter = 'rpho',
+ cmTechnologyFilmWriter = 'fprn',
+ cmTechnologyVideoMonitor = 'vidm',
+ cmTechnologyVideoCamera = 'vidc',
+ cmTechnologyProjectionTelevision = 'pjtv',
+ cmTechnologyCRTDisplay = 'CRT ',
+ cmTechnologyPMDisplay = 'PMD ',
+ cmTechnologyAMDisplay = 'AMD ',
+ cmTechnologyPhotoCD = 'KPCD',
+ cmTechnologyPhotoImageSetter = 'imgs',
+ cmTechnologyGravure = 'grav',
+ cmTechnologyOffsetLithography = 'offs',
+ cmTechnologySilkscreen = 'silk',
+ cmTechnologyFlexography = 'flex'
+};
+
+
+
+
+enum {
+ cmFlare0 = 0x00000000,
+ cmFlare100 = 0x00000001
+};
+
+
+enum {
+ cmGeometryUnknown = 0x00000000,
+ cmGeometry045or450 = 0x00000001,
+ cmGeometry0dord0 = 0x00000002
+};
+
+
+enum {
+ cmStdobsUnknown = 0x00000000,
+ cmStdobs1931TwoDegrees = 0x00000001,
+ cmStdobs1964TenDegrees = 0x00000002
+};
+
+
+enum {
+ cmIlluminantUnknown = 0x00000000,
+ cmIlluminantD50 = 0x00000001,
+ cmIlluminantD65 = 0x00000002,
+ cmIlluminantD93 = 0x00000003,
+ cmIlluminantF2 = 0x00000004,
+ cmIlluminantD55 = 0x00000005,
+ cmIlluminantA = 0x00000006,
+ cmIlluminantEquiPower = 0x00000007,
+ cmIlluminantF8 = 0x00000008
+};
+
+
+enum {
+ cmSpotFunctionUnknown = 0,
+ cmSpotFunctionDefault = 1,
+ cmSpotFunctionRound = 2,
+ cmSpotFunctionDiamond = 3,
+ cmSpotFunctionEllipse = 4,
+ cmSpotFunctionLine = 5,
+ cmSpotFunctionSquare = 6,
+ cmSpotFunctionCross = 7
+};
+
+
+enum {
+ cmXYZData = 'XYZ ',
+ cmLabData = 'Lab ',
+ cmLuvData = 'Luv ',
+ cmYCbCrData = 'YCbr',
+ cmYxyData = 'Yxy ',
+ cmRGBData = 'RGB ',
+ cmSRGBData = 'sRGB',
+ cmGrayData = 'GRAY',
+ cmHSVData = 'HSV ',
+ cmHLSData = 'HLS ',
+ cmCMYKData = 'CMYK',
+ cmCMYData = 'CMY ',
+ cmMCH5Data = 'MCH5',
+ cmMCH6Data = 'MCH6',
+ cmMCH7Data = 'MCH7',
+ cmMCH8Data = 'MCH8',
+ cm3CLRData = '3CLR',
+ cm4CLRData = '4CLR',
+ cm5CLRData = '5CLR',
+ cm6CLRData = '6CLR',
+ cm7CLRData = '7CLR',
+ cm8CLRData = '8CLR',
+ cm9CLRData = '9CLR',
+ cm10CLRData = 'ACLR',
+ cm11CLRData = 'BCLR',
+ cm12CLRData = 'CCLR',
+ cm13CLRData = 'DCLR',
+ cm14CLRData = 'ECLR',
+ cm15CLRData = 'FCLR',
+ cmNamedData = 'NAME'
+};
+
+
+enum {
+ cmInputClass = 'scnr',
+ cmDisplayClass = 'mntr',
+ cmOutputClass = 'prtr',
+ cmLinkClass = 'link',
+ cmAbstractClass = 'abst',
+ cmColorSpaceClass = 'spac',
+ cmNamedColorClass = 'nmcl'
+};
+
+
+enum {
+ cmMacintosh = 'APPL',
+ cmMicrosoft = 'MSFT',
+ cmSolaris = 'SUNW',
+ cmSiliconGraphics = 'SGI ',
+ cmTaligent = 'TGNT'
+};
+
+
+enum {
+ cmParametricType0 = 0,
+ cmParametricType1 = 1,
+ cmParametricType2 = 2,
+ cmParametricType3 = 3,
+ cmParametricType4 = 4
+};
+
+
+
+enum {
+ cmCS1ChromTag = 'chrm',
+ cmCS1TRCTag = 'trc ',
+ cmCS1NameTag = 'name',
+ cmCS1CustTag = 'cust'
+};
+
+
+struct CMDateTime {
+ UInt16 year;
+ UInt16 month;
+ UInt16 dayOfTheMonth;
+ UInt16 hours;
+ UInt16 minutes;
+ UInt16 seconds;
+};
+typedef struct CMDateTime CMDateTime;
+struct CMFixedXYColor {
+ Fixed x;
+ Fixed y;
+};
+typedef struct CMFixedXYColor CMFixedXYColor;
+struct CMFixedXYZColor {
+ Fixed X;
+ Fixed Y;
+ Fixed Z;
+};
+typedef struct CMFixedXYZColor CMFixedXYZColor;
+
+typedef UInt16 CMXYZComponent;
+struct CMXYZColor {
+ CMXYZComponent X;
+ CMXYZComponent Y;
+ CMXYZComponent Z;
+};
+typedef struct CMXYZColor CMXYZColor;
+
+
+
+typedef unsigned char CMProfileMD5[16];
+typedef CMProfileMD5 * CMProfileMD5Ptr;
+
+
+
+
+
+
+
+ inline Boolean CMProfileMD5AreEqual(CMProfileMD5 a, CMProfileMD5 b)
+ {
+ return ((long*)a)[0]==((long*)b)[0] && ((long*)a)[1]==((long*)b)[1] &&
+ ((long*)a)[2]==((long*)b)[2] && ((long*)a)[3]==((long*)b)[3];
+ }
+
+
+
+
+
+
+struct CM2Header {
+ UInt32 size;
+ OSType CMMType;
+ UInt32 profileVersion;
+ OSType profileClass;
+ OSType dataColorSpace;
+ OSType profileConnectionSpace;
+ CMDateTime dateTime;
+ OSType CS2profileSignature;
+ OSType platform;
+ UInt32 flags;
+ OSType deviceManufacturer;
+ UInt32 deviceModel;
+ UInt32 deviceAttributes[2];
+ UInt32 renderingIntent;
+ CMFixedXYZColor white;
+ OSType creator;
+ char reserved[44];
+};
+typedef struct CM2Header CM2Header;
+struct CM4Header {
+ UInt32 size;
+ OSType CMMType;
+ UInt32 profileVersion;
+ OSType profileClass;
+ OSType dataColorSpace;
+ OSType profileConnectionSpace;
+ CMDateTime dateTime;
+ OSType CS2profileSignature;
+ OSType platform;
+ UInt32 flags;
+ OSType deviceManufacturer;
+ UInt32 deviceModel;
+ UInt32 deviceAttributes[2];
+ UInt32 renderingIntent;
+ CMFixedXYZColor white;
+ OSType creator;
+ CMProfileMD5 digest;
+ char reserved[28];
+};
+typedef struct CM4Header CM4Header;
+struct CMTagRecord {
+ OSType tag;
+ UInt32 elementOffset;
+ UInt32 elementSize;
+};
+typedef struct CMTagRecord CMTagRecord;
+struct CMTagElemTable {
+ UInt32 count;
+ CMTagRecord tagList[1];
+};
+typedef struct CMTagElemTable CMTagElemTable;
+struct CM2Profile {
+ CM2Header header;
+ CMTagElemTable tagTable;
+ char elemData[1];
+};
+typedef struct CM2Profile CM2Profile;
+typedef CM2Profile * CM2ProfilePtr;
+typedef CM2ProfilePtr * CM2ProfileHandle;
+
+struct CMAdaptationMatrixType {
+ OSType typeDescriptor;
+ unsigned long reserved;
+ Fixed adaptationMatrix[9];
+};
+typedef struct CMAdaptationMatrixType CMAdaptationMatrixType;
+struct CMCurveType {
+ OSType typeDescriptor;
+ UInt32 reserved;
+ UInt32 countValue;
+ UInt16 data[1];
+};
+typedef struct CMCurveType CMCurveType;
+struct CMDataType {
+ OSType typeDescriptor;
+ UInt32 reserved;
+ UInt32 dataFlag;
+ char data[1];
+};
+typedef struct CMDataType CMDataType;
+struct CMDateTimeType {
+ OSType typeDescriptor;
+ UInt32 reserved;
+ CMDateTime dateTime;
+};
+typedef struct CMDateTimeType CMDateTimeType;
+struct CMLut16Type {
+ OSType typeDescriptor;
+ UInt32 reserved;
+ UInt8 inputChannels;
+ UInt8 outputChannels;
+ UInt8 gridPoints;
+ UInt8 reserved2;
+ Fixed matrix[3][3];
+ UInt16 inputTableEntries;
+ UInt16 outputTableEntries;
+ UInt16 inputTable[1];
+};
+typedef struct CMLut16Type CMLut16Type;
+struct CMLut8Type {
+ OSType typeDescriptor;
+ UInt32 reserved;
+ UInt8 inputChannels;
+ UInt8 outputChannels;
+ UInt8 gridPoints;
+ UInt8 reserved2;
+ Fixed matrix[3][3];
+ UInt8 inputTable[1];
+};
+typedef struct CMLut8Type CMLut8Type;
+struct CMMultiFunctLutType {
+ OSType typeDescriptor;
+ UInt32 reserved;
+ UInt8 inputChannels;
+ UInt8 outputChannels;
+ UInt16 reserved2;
+ UInt32 offsetBcurves;
+ UInt32 offsetMatrix;
+ UInt32 offsetMcurves;
+ UInt32 offsetCLUT;
+ UInt32 offsetAcurves;
+ UInt8 data[1];
+};
+typedef struct CMMultiFunctLutType CMMultiFunctLutType;
+typedef CMMultiFunctLutType CMMultiFunctLutA2BType;
+typedef CMMultiFunctLutType CMMultiFunctLutB2AType;
+struct CMMultiFunctCLUTType {
+ UInt8 gridPoints[16];
+ UInt8 entrySize;
+ UInt8 reserved[3];
+ UInt8 data[1];
+};
+typedef struct CMMultiFunctCLUTType CMMultiFunctCLUTType;
+struct CMMeasurementType {
+ OSType typeDescriptor;
+ UInt32 reserved;
+ UInt32 standardObserver;
+ CMFixedXYZColor backingXYZ;
+ UInt32 geometry;
+ UInt32 flare;
+ UInt32 illuminant;
+};
+typedef struct CMMeasurementType CMMeasurementType;
+struct CMNamedColorType {
+ OSType typeDescriptor;
+ UInt32 reserved;
+ UInt32 vendorFlag;
+ UInt32 count;
+ UInt8 prefixName[1];
+};
+typedef struct CMNamedColorType CMNamedColorType;
+struct CMNamedColor2EntryType {
+ UInt8 rootName[32];
+ UInt16 PCSColorCoords[3];
+ UInt16 DeviceColorCoords[1];
+};
+typedef struct CMNamedColor2EntryType CMNamedColor2EntryType;
+struct CMNamedColor2Type {
+ OSType typeDescriptor;
+ UInt32 reserved;
+ UInt32 vendorFlag;
+ UInt32 count;
+ UInt32 deviceChannelCount;
+ UInt8 prefixName[32];
+ UInt8 suffixName[32];
+ char data[1];
+};
+typedef struct CMNamedColor2Type CMNamedColor2Type;
+struct CMNativeDisplayInfo {
+ UInt32 dataSize;
+ CMFixedXYColor redPhosphor;
+ CMFixedXYColor greenPhosphor;
+ CMFixedXYColor bluePhosphor;
+ CMFixedXYColor whitePoint;
+ Fixed redGammaValue;
+ Fixed greenGammaValue;
+ Fixed blueGammaValue;
+
+
+
+ UInt16 gammaChannels;
+ UInt16 gammaEntryCount;
+ UInt16 gammaEntrySize;
+ char gammaData[1];
+};
+typedef struct CMNativeDisplayInfo CMNativeDisplayInfo;
+struct CMNativeDisplayInfoType {
+ OSType typeDescriptor;
+ unsigned long reserved;
+ CMNativeDisplayInfo nativeDisplayInfo;
+};
+typedef struct CMNativeDisplayInfoType CMNativeDisplayInfoType;
+struct CMParametricCurveType {
+ OSType typeDescriptor;
+ UInt32 reserved;
+ UInt16 functionType;
+ UInt16 reserved2;
+ Fixed value[1];
+};
+typedef struct CMParametricCurveType CMParametricCurveType;
+struct CMTextDescriptionType {
+ OSType typeDescriptor;
+ UInt32 reserved;
+ UInt32 ASCIICount;
+ UInt8 ASCIIName[2];
+};
+typedef struct CMTextDescriptionType CMTextDescriptionType;
+struct CMTextType {
+ OSType typeDescriptor;
+ UInt32 reserved;
+ UInt8 text[1];
+};
+typedef struct CMTextType CMTextType;
+struct CMUnicodeTextType {
+ OSType typeDescriptor;
+ UInt32 reserved;
+ UniChar text[1];
+};
+typedef struct CMUnicodeTextType CMUnicodeTextType;
+struct CMScreeningChannelRec {
+ Fixed frequency;
+ Fixed angle;
+ UInt32 spotFunction;
+};
+typedef struct CMScreeningChannelRec CMScreeningChannelRec;
+struct CMScreeningType {
+ OSType typeDescriptor;
+ UInt32 reserved;
+ UInt32 screeningFlag;
+ UInt32 channelCount;
+ CMScreeningChannelRec channelInfo[1];
+};
+typedef struct CMScreeningType CMScreeningType;
+struct CMSignatureType {
+ OSType typeDescriptor;
+ UInt32 reserved;
+ OSType signature;
+};
+typedef struct CMSignatureType CMSignatureType;
+struct CMS15Fixed16ArrayType {
+ OSType typeDescriptor;
+ UInt32 reserved;
+ Fixed value[1];
+};
+typedef struct CMS15Fixed16ArrayType CMS15Fixed16ArrayType;
+struct CMU16Fixed16ArrayType {
+ OSType typeDescriptor;
+ UInt32 reserved;
+ UInt32 value[1];
+};
+typedef struct CMU16Fixed16ArrayType CMU16Fixed16ArrayType;
+struct CMUInt8ArrayType {
+ OSType typeDescriptor;
+ UInt32 reserved;
+ UInt8 value[1];
+};
+typedef struct CMUInt8ArrayType CMUInt8ArrayType;
+struct CMUInt16ArrayType {
+ OSType typeDescriptor;
+ UInt32 reserved;
+ UInt16 value[1];
+};
+typedef struct CMUInt16ArrayType CMUInt16ArrayType;
+struct CMUInt32ArrayType {
+ OSType typeDescriptor;
+ UInt32 reserved;
+ UInt32 value[1];
+};
+typedef struct CMUInt32ArrayType CMUInt32ArrayType;
+struct CMUInt64ArrayType {
+ OSType typeDescriptor;
+ UInt32 reserved;
+ UInt32 value[1];
+};
+typedef struct CMUInt64ArrayType CMUInt64ArrayType;
+struct CMViewingConditionsType {
+ OSType typeDescriptor;
+ UInt32 reserved;
+ CMFixedXYZColor illuminant;
+ CMFixedXYZColor surround;
+ UInt32 stdIlluminant;
+};
+typedef struct CMViewingConditionsType CMViewingConditionsType;
+struct CMXYZType {
+ OSType typeDescriptor;
+ UInt32 reserved;
+ CMFixedXYZColor XYZ[1];
+};
+typedef struct CMXYZType CMXYZType;
+struct CMProfileSequenceDescType {
+ OSType typeDescriptor;
+ UInt32 reserved;
+ UInt32 count;
+ char data[1];
+};
+typedef struct CMProfileSequenceDescType CMProfileSequenceDescType;
+struct CMUcrBgType {
+ OSType typeDescriptor;
+ UInt32 reserved;
+ UInt32 ucrCount;
+ UInt16 ucrValues[1];
+};
+typedef struct CMUcrBgType CMUcrBgType;
+
+struct CMIntentCRDVMSize {
+ long renderingIntent;
+ UInt32 VMSize;
+};
+typedef struct CMIntentCRDVMSize CMIntentCRDVMSize;
+struct CMPS2CRDVMSizeType {
+ OSType typeDescriptor;
+ UInt32 reserved;
+ UInt32 count;
+ CMIntentCRDVMSize intentCRD[1];
+};
+typedef struct CMPS2CRDVMSizeType CMPS2CRDVMSizeType;
+enum {
+ cmVideoCardGammaTableType = 0,
+ cmVideoCardGammaFormulaType = 1
+};
+
+struct CMVideoCardGammaTable {
+ UInt16 channels;
+ UInt16 entryCount;
+ UInt16 entrySize;
+ char data[1];
+};
+typedef struct CMVideoCardGammaTable CMVideoCardGammaTable;
+struct CMVideoCardGammaFormula {
+ Fixed redGamma;
+ Fixed redMin;
+ Fixed redMax;
+ Fixed greenGamma;
+ Fixed greenMin;
+ Fixed greenMax;
+ Fixed blueGamma;
+ Fixed blueMin;
+ Fixed blueMax;
+};
+typedef struct CMVideoCardGammaFormula CMVideoCardGammaFormula;
+struct CMVideoCardGamma {
+ UInt32 tagType;
+ union {
+ CMVideoCardGammaTable table;
+ CMVideoCardGammaFormula formula;
+ } u;
+};
+typedef struct CMVideoCardGamma CMVideoCardGamma;
+struct CMVideoCardGammaType {
+ OSType typeDescriptor;
+ UInt32 reserved;
+ CMVideoCardGamma gamma;
+};
+typedef struct CMVideoCardGammaType CMVideoCardGammaType;
+struct CMMakeAndModel {
+ OSType manufacturer;
+ UInt32 model;
+ UInt32 serialNumber;
+ UInt32 manufactureDate;
+ UInt32 reserved1;
+ UInt32 reserved2;
+ UInt32 reserved3;
+ UInt32 reserved4;
+};
+typedef struct CMMakeAndModel CMMakeAndModel;
+struct CMMakeAndModelType {
+ OSType typeDescriptor;
+ UInt32 reserved;
+ CMMakeAndModel makeAndModel;
+};
+typedef struct CMMakeAndModelType CMMakeAndModelType;
+struct CMMultiLocalizedUniCodeEntryRec {
+ char languageCode[2];
+ char regionCode[2];
+ UInt32 textLength;
+ UInt32 textOffset;
+};
+typedef struct CMMultiLocalizedUniCodeEntryRec CMMultiLocalizedUniCodeEntryRec;
+struct CMMultiLocalizedUniCodeType {
+ OSType typeDescriptor;
+ UInt32 reserved;
+ UInt32 entryCount;
+ UInt32 entrySize;
+
+
+
+
+};
+typedef struct CMMultiLocalizedUniCodeType CMMultiLocalizedUniCodeType;
+
+
+
+enum {
+ cmGrayResponse = 0,
+ cmRedResponse = 1,
+ cmGreenResponse = 2,
+ cmBlueResponse = 3,
+ cmCyanResponse = 4,
+ cmMagentaResponse = 5,
+ cmYellowResponse = 6,
+ cmUcrResponse = 7,
+ cmBgResponse = 8,
+ cmOnePlusLastResponse = 9
+};
+
+
+
+enum {
+ cmMonitorDevice = 'mntr',
+ cmScannerDevice = 'scnr',
+ cmPrinterDevice = 'prtr'
+};
+
+
+struct CMIString {
+ ScriptCode theScript;
+ Str63 theString;
+};
+typedef struct CMIString CMIString;
+
+enum {
+ cmPerceptualMatch = 0x0000,
+ cmColorimetricMatch = 0x0001,
+ cmSaturationMatch = 0x0002
+};
+
+
+enum {
+ cmNativeMatchingPreferred = 0x00000001,
+ cmTurnOffCache = 0x00000002
+};
+
+
+typedef long CMMatchOption;
+typedef long CMMatchFlag;
+struct CMHeader {
+ UInt32 size;
+ OSType CMMType;
+ UInt32 applProfileVersion;
+ OSType dataType;
+ OSType deviceType;
+ OSType deviceManufacturer;
+ UInt32 deviceModel;
+ UInt32 deviceAttributes[2];
+ UInt32 profileNameOffset;
+ UInt32 customDataOffset;
+ CMMatchFlag flags;
+ CMMatchOption options;
+ CMXYZColor white;
+ CMXYZColor black;
+};
+typedef struct CMHeader CMHeader;
+struct CMProfileChromaticities {
+ CMXYZColor red;
+ CMXYZColor green;
+ CMXYZColor blue;
+ CMXYZColor cyan;
+ CMXYZColor magenta;
+ CMXYZColor yellow;
+};
+typedef struct CMProfileChromaticities CMProfileChromaticities;
+struct CMProfileResponse {
+ UInt16 counts[9];
+ UInt16 data[1];
+};
+typedef struct CMProfileResponse CMProfileResponse;
+struct CMProfile {
+ CMHeader header;
+ CMProfileChromaticities profile;
+ CMProfileResponse response;
+ CMIString profileName;
+ char customData[1];
+};
+typedef struct CMProfile CMProfile;
+typedef CMProfile * CMProfilePtr;
+typedef CMProfilePtr * CMProfileHandle;
+extern "C" {
+
+
+
+enum {
+ kDefaultCMMSignature = 'appl'
+};
+
+
+enum {
+ cmTrap = 0xABEE
+};
+
+
+
+enum {
+ cmBeginProfile = 220,
+ cmEndProfile = 221,
+ cmEnableMatching = 222,
+ cmDisableMatching = 223,
+ cmComment = 224
+};
+
+
+enum {
+ cmBeginProfileSel = 0,
+ cmContinueProfileSel = 1,
+ cmEndProfileSel = 2,
+ cmProfileIdentifierSel = 3
+};
+
+
+
+enum {
+ cmMatchCMMType = 0x00000001,
+ cmMatchApplProfileVersion = 0x00000002,
+ cmMatchDataType = 0x00000004,
+ cmMatchDeviceType = 0x00000008,
+ cmMatchDeviceManufacturer = 0x00000010,
+ cmMatchDeviceModel = 0x00000020,
+ cmMatchDeviceAttributes = 0x00000040,
+ cmMatchFlags = 0x00000080,
+ cmMatchOptions = 0x00000100,
+ cmMatchWhite = 0x00000200,
+ cmMatchBlack = 0x00000400
+};
+
+
+enum {
+ cmMatchAnyProfile = 0x00000000,
+ cmMatchProfileCMMType = 0x00000001,
+ cmMatchProfileClass = 0x00000002,
+ cmMatchDataColorSpace = 0x00000004,
+ cmMatchProfileConnectionSpace = 0x00000008,
+ cmMatchManufacturer = 0x00000010,
+ cmMatchModel = 0x00000020,
+ cmMatchAttributes = 0x00000040,
+ cmMatchProfileFlags = 0x00000080
+};
+
+
+
+enum {
+ cmPS7bit = 1,
+ cmPS8bit = 2
+};
+
+
+enum {
+ cmEmbedWholeProfile = 0x00000000,
+ cmEmbedProfileIdentifier = 0x00000001
+};
+
+
+enum {
+ cmOpenReadSpool = 1,
+ cmOpenWriteSpool = 2,
+ cmReadSpool = 3,
+ cmWriteSpool = 4,
+ cmCloseSpool = 5
+};
+
+
+enum {
+ cmOpenReadAccess = 1,
+ cmOpenWriteAccess = 2,
+ cmReadAccess = 3,
+ cmWriteAccess = 4,
+ cmCloseAccess = 5,
+ cmCreateNewAccess = 6,
+ cmAbortWriteAccess = 7,
+ cmBeginAccess = 8,
+ cmEndAccess = 9
+};
+
+
+
+enum {
+ cmInputUse = 'inpt',
+ cmOutputUse = 'outp',
+ cmDisplayUse = 'dply',
+ cmProofUse = 'pruf'
+};
+
+
+
+union CMAppleProfileHeader {
+ CMHeader cm1;
+ CM2Header cm2;
+ CM4Header cm4;
+};
+typedef union CMAppleProfileHeader CMAppleProfileHeader;
+
+struct CMConcatProfileSet {
+ UInt16 keyIndex;
+ UInt16 count;
+ CMProfileRef profileSet[1];
+};
+typedef struct CMConcatProfileSet CMConcatProfileSet;
+
+struct NCMConcatProfileSpec {
+ UInt32 renderingIntent;
+ UInt32 transformTag;
+ CMProfileRef profile;
+};
+typedef struct NCMConcatProfileSpec NCMConcatProfileSpec;
+struct NCMConcatProfileSet {
+ OSType cmm;
+ UInt32 flags;
+ UInt32 flagsMask;
+ UInt32 profileCount;
+ NCMConcatProfileSpec profileSpecs[1];
+};
+typedef struct NCMConcatProfileSet NCMConcatProfileSet;
+enum {
+ kNoTransform = 0,
+ kUseAtoB = 1,
+ kUseBtoA = 2,
+ kUseBtoB = 3,
+
+ kDeviceToPCS = kUseAtoB,
+ kPCSToDevice = kUseBtoA,
+ kPCSToPCS = kUseBtoB,
+ kUseProfileIntent = (long)0xFFFFFFFF
+};
+
+
+
+struct CMRGBColor {
+ UInt16 red;
+ UInt16 green;
+ UInt16 blue;
+};
+typedef struct CMRGBColor CMRGBColor;
+struct CMCMYKColor {
+ UInt16 cyan;
+ UInt16 magenta;
+ UInt16 yellow;
+ UInt16 black;
+};
+typedef struct CMCMYKColor CMCMYKColor;
+struct CMCMYColor {
+ UInt16 cyan;
+ UInt16 magenta;
+ UInt16 yellow;
+};
+typedef struct CMCMYColor CMCMYColor;
+struct CMHLSColor {
+ UInt16 hue;
+ UInt16 lightness;
+ UInt16 saturation;
+};
+typedef struct CMHLSColor CMHLSColor;
+struct CMHSVColor {
+ UInt16 hue;
+ UInt16 saturation;
+ UInt16 value;
+};
+typedef struct CMHSVColor CMHSVColor;
+struct CMLabColor {
+ UInt16 L;
+ UInt16 a;
+ UInt16 b;
+};
+typedef struct CMLabColor CMLabColor;
+struct CMLuvColor {
+ UInt16 L;
+ UInt16 u;
+ UInt16 v;
+};
+typedef struct CMLuvColor CMLuvColor;
+struct CMYxyColor {
+ UInt16 capY;
+ UInt16 x;
+ UInt16 y;
+};
+typedef struct CMYxyColor CMYxyColor;
+struct CMGrayColor {
+ UInt16 gray;
+};
+typedef struct CMGrayColor CMGrayColor;
+struct CMMultichannel5Color {
+ UInt8 components[5];
+};
+typedef struct CMMultichannel5Color CMMultichannel5Color;
+struct CMMultichannel6Color {
+ UInt8 components[6];
+};
+typedef struct CMMultichannel6Color CMMultichannel6Color;
+struct CMMultichannel7Color {
+ UInt8 components[7];
+};
+typedef struct CMMultichannel7Color CMMultichannel7Color;
+struct CMMultichannel8Color {
+ UInt8 components[8];
+};
+typedef struct CMMultichannel8Color CMMultichannel8Color;
+struct CMNamedColor {
+ UInt32 namedColorIndex;
+};
+typedef struct CMNamedColor CMNamedColor;
+union CMColor {
+ CMRGBColor rgb;
+ CMHSVColor hsv;
+ CMHLSColor hls;
+ CMXYZColor XYZ;
+ CMLabColor Lab;
+ CMLuvColor Luv;
+ CMYxyColor Yxy;
+ CMCMYKColor cmyk;
+ CMCMYColor cmy;
+ CMGrayColor gray;
+ CMMultichannel5Color mc5;
+ CMMultichannel6Color mc6;
+ CMMultichannel7Color mc7;
+ CMMultichannel8Color mc8;
+ CMNamedColor namedColor;
+};
+typedef union CMColor CMColor;
+
+struct CMProfileSearchRecord {
+ CMHeader header;
+ UInt32 fieldMask;
+ UInt32 reserved[2];
+};
+typedef struct CMProfileSearchRecord CMProfileSearchRecord;
+typedef CMProfileSearchRecord * CMProfileSearchRecordPtr;
+typedef CMProfileSearchRecordPtr * CMProfileSearchRecordHandle;
+
+struct CMSearchRecord {
+ OSType CMMType;
+ OSType profileClass;
+ OSType dataColorSpace;
+ OSType profileConnectionSpace;
+ UInt32 deviceManufacturer;
+ UInt32 deviceModel;
+ UInt32 deviceAttributes[2];
+ UInt32 profileFlags;
+ UInt32 searchMask;
+ CMProfileFilterUPP filter;
+};
+typedef struct CMSearchRecord CMSearchRecord;
+
+struct CMMInfo {
+ UInt32 dataSize;
+ OSType CMMType;
+ OSType CMMMfr;
+ UInt32 CMMVersion;
+ unsigned char ASCIIName[32];
+ unsigned char ASCIIDesc[256];
+ UniCharCount UniCodeNameCount;
+ UniChar UniCodeName[32];
+ UniCharCount UniCodeDescCount;
+ UniChar UniCodeDesc[256];
+};
+typedef struct CMMInfo CMMInfo;
+
+struct CMMInfoRecord {
+ OSType CMMType;
+ long CMMVersion;
+};
+typedef struct CMMInfoRecord CMMInfoRecord;
+struct CMCWInfoRecord {
+ UInt32 cmmCount;
+ CMMInfoRecord cmmInfo[2];
+};
+typedef struct CMCWInfoRecord CMCWInfoRecord;
+
+struct CMProfileIdentifier {
+ CM2Header profileHeader;
+ CMDateTime calibrationDate;
+ UInt32 ASCIIProfileDescriptionLen;
+ char ASCIIProfileDescription[1];
+};
+typedef struct CMProfileIdentifier CMProfileIdentifier;
+typedef CMProfileIdentifier * CMProfileIdentifierPtr;
+
+enum {
+ cmColorSpaceSpaceMask = 0x0000003F,
+ cmColorSpacePremulAlphaMask = 0x00000040,
+ cmColorSpaceAlphaMask = 0x00000080,
+ cmColorSpaceSpaceAndAlphaMask = 0x000000FF,
+ cmColorSpacePackingMask = 0x0000FF00,
+ cmColorSpaceEncodingMask = 0x000F0000,
+ cmColorSpaceReservedMask = (long)0xFFF00000
+};
+
+
+enum {
+ cmNoColorPacking = 0x0000,
+ cmWord5ColorPacking = 0x0500,
+ cmWord565ColorPacking = 0x0600,
+ cmLong8ColorPacking = 0x0800,
+ cmLong10ColorPacking = 0x0A00,
+ cmAlphaFirstPacking = 0x1000,
+ cmOneBitDirectPacking = 0x0B00,
+ cmAlphaLastPacking = 0x0000,
+ cm8_8ColorPacking = 0x2800,
+ cm16_8ColorPacking = 0x2000,
+ cm24_8ColorPacking = 0x2100,
+ cm32_8ColorPacking = cmLong8ColorPacking,
+ cm40_8ColorPacking = 0x2200,
+ cm48_8ColorPacking = 0x2300,
+ cm56_8ColorPacking = 0x2400,
+ cm64_8ColorPacking = 0x2500,
+ cm32_16ColorPacking = 0x2600,
+ cm48_16ColorPacking = 0x2900,
+ cm64_16ColorPacking = 0x2A00,
+ cm32_32ColorPacking = 0x2700,
+ cmLittleEndianPacking = 0x4000,
+ cmReverseChannelPacking = 0x8000
+};
+
+
+enum {
+ cmSRGB16ChannelEncoding = 0x00010000
+};
+
+
+enum {
+ cmNoSpace = 0x0000,
+ cmRGBSpace = 0x0001,
+ cmCMYKSpace = 0x0002,
+ cmHSVSpace = 0x0003,
+ cmHLSSpace = 0x0004,
+ cmYXYSpace = 0x0005,
+ cmXYZSpace = 0x0006,
+ cmLUVSpace = 0x0007,
+ cmLABSpace = 0x0008,
+ cmReservedSpace1 = 0x0009,
+ cmGraySpace = 0x000A,
+ cmReservedSpace2 = 0x000B,
+ cmGamutResultSpace = 0x000C,
+ cmNamedIndexedSpace = 0x0010,
+ cmMCFiveSpace = 0x0011,
+ cmMCSixSpace = 0x0012,
+ cmMCSevenSpace = 0x0013,
+ cmMCEightSpace = 0x0014,
+ cmAlphaPmulSpace = 0x0040,
+ cmAlphaSpace = 0x0080,
+ cmRGBASpace = cmRGBSpace + cmAlphaSpace,
+ cmGrayASpace = cmGraySpace + cmAlphaSpace,
+ cmRGBAPmulSpace = cmRGBASpace + cmAlphaPmulSpace,
+ cmGrayAPmulSpace = cmGrayASpace + cmAlphaPmulSpace
+};
+
+
+
+
+enum {
+ cmGray8Space = cmGraySpace + cm8_8ColorPacking,
+ cmGray16Space = cmGraySpace,
+ cmGray16LSpace = cmGraySpace + cmLittleEndianPacking,
+ cmGrayA16Space = cmGrayASpace + cm16_8ColorPacking,
+ cmGrayA32Space = cmGrayASpace,
+ cmGrayA32LSpace = cmGrayASpace + cmLittleEndianPacking,
+ cmGrayA16PmulSpace = cmGrayAPmulSpace + cm16_8ColorPacking,
+ cmGrayA32PmulSpace = cmGrayAPmulSpace,
+ cmGrayA32LPmulSpace = cmGrayAPmulSpace + cmLittleEndianPacking,
+ cmRGB16Space = cmRGBSpace + cmWord5ColorPacking,
+ cmRGB16LSpace = cmRGBSpace + cmWord5ColorPacking + cmLittleEndianPacking,
+ cmRGB565Space = cmRGBSpace + cmWord565ColorPacking,
+ cmRGB565LSpace = cmRGBSpace + cmWord565ColorPacking + cmLittleEndianPacking,
+ cmRGB24Space = cmRGBSpace + cm24_8ColorPacking,
+ cmRGB32Space = cmRGBSpace + cm32_8ColorPacking,
+ cmRGB48Space = cmRGBSpace + cm48_16ColorPacking,
+ cmRGB48LSpace = cmRGBSpace + cm48_16ColorPacking + cmLittleEndianPacking,
+ cmARGB32Space = cmRGBASpace + cm32_8ColorPacking + cmAlphaFirstPacking,
+ cmARGB64Space = cmRGBASpace + cm64_16ColorPacking + cmAlphaFirstPacking,
+ cmARGB64LSpace = cmRGBASpace + cm64_16ColorPacking + cmAlphaFirstPacking + cmLittleEndianPacking,
+ cmRGBA32Space = cmRGBASpace + cm32_8ColorPacking + cmAlphaLastPacking,
+ cmRGBA64Space = cmRGBASpace + cm64_16ColorPacking + cmAlphaLastPacking,
+ cmRGBA64LSpace = cmRGBASpace + cm64_16ColorPacking + cmAlphaLastPacking + cmLittleEndianPacking,
+ cmARGB32PmulSpace = cmRGBAPmulSpace + cm32_8ColorPacking + cmAlphaFirstPacking,
+ cmARGB64PmulSpace = cmRGBAPmulSpace + cm64_16ColorPacking + cmAlphaFirstPacking,
+ cmARGB64LPmulSpace = cmRGBAPmulSpace + cm64_16ColorPacking + cmAlphaFirstPacking + cmLittleEndianPacking,
+ cmRGBA32PmulSpace = cmRGBAPmulSpace + cm32_8ColorPacking + cmAlphaLastPacking,
+ cmRGBA64PmulSpace = cmRGBAPmulSpace + cm64_16ColorPacking + cmAlphaLastPacking,
+ cmRGBA64LPmulSpace = cmRGBAPmulSpace + cm64_16ColorPacking + cmAlphaLastPacking + cmLittleEndianPacking,
+ cmCMYK32Space = cmCMYKSpace + cm32_8ColorPacking,
+ cmCMYK64Space = cmCMYKSpace + cm64_16ColorPacking,
+ cmCMYK64LSpace = cmCMYKSpace + cm64_16ColorPacking + cmLittleEndianPacking,
+ cmHSV32Space = cmHSVSpace + cmLong10ColorPacking,
+ cmHLS32Space = cmHLSSpace + cmLong10ColorPacking,
+ cmYXY32Space = cmYXYSpace + cmLong10ColorPacking,
+ cmXYZ24Space = cmXYZSpace + cm24_8ColorPacking,
+ cmXYZ32Space = cmXYZSpace + cmLong10ColorPacking,
+ cmXYZ48Space = cmXYZSpace + cm48_16ColorPacking,
+ cmXYZ48LSpace = cmXYZSpace + cm48_16ColorPacking + cmLittleEndianPacking,
+ cmLUV32Space = cmLUVSpace + cmLong10ColorPacking,
+ cmLAB24Space = cmLABSpace + cm24_8ColorPacking,
+ cmLAB32Space = cmLABSpace + cmLong10ColorPacking,
+ cmLAB48Space = cmLABSpace + cm48_16ColorPacking,
+ cmLAB48LSpace = cmLABSpace + cm48_16ColorPacking + cmLittleEndianPacking,
+ cmGamutResult1Space = cmOneBitDirectPacking + cmGamutResultSpace,
+ cmNamedIndexed32Space = cm32_32ColorPacking + cmNamedIndexedSpace,
+ cmNamedIndexed32LSpace = cm32_32ColorPacking + cmNamedIndexedSpace + cmLittleEndianPacking,
+ cmMCFive8Space = cm40_8ColorPacking + cmMCFiveSpace,
+ cmMCSix8Space = cm48_8ColorPacking + cmMCSixSpace,
+ cmMCSeven8Space = cm56_8ColorPacking + cmMCSevenSpace,
+ cmMCEight8Space = cm64_8ColorPacking + cmMCEightSpace
+};
+
+
+typedef UInt32 CMBitmapColorSpace;
+struct CMBitmap {
+ char * image;
+ long width;
+ long height;
+ long rowBytes;
+ long pixelSize;
+ CMBitmapColorSpace space;
+ long user1;
+ long user2;
+};
+typedef struct CMBitmap CMBitmap;
+
+
+typedef UInt32 CMChromaticAdaptation;
+enum {
+ cmUseDefaultChromaticAdaptation = 0,
+ cmLinearChromaticAdaptation = 1,
+ cmVonKriesChromaticAdaptation = 2,
+ cmBradfordChromaticAdaptation = 3
+};
+
+
+
+enum {
+ CS_MAX_PATH = 256
+};
+
+enum {
+ cmNoProfileBase = 0,
+ cmFileBasedProfile = 1,
+ cmHandleBasedProfile = 2,
+ cmPtrBasedProfile = 3,
+ cmProcedureBasedProfile = 4,
+ cmPathBasedProfile = 5,
+ cmBufferBasedProfile = 6
+};
+
+struct CMFileLocation {
+ FSSpec spec;
+};
+typedef struct CMFileLocation CMFileLocation;
+struct CMHandleLocation {
+ Handle h;
+};
+typedef struct CMHandleLocation CMHandleLocation;
+struct CMPtrLocation {
+ Ptr p;
+};
+typedef struct CMPtrLocation CMPtrLocation;
+struct CMProcedureLocation {
+ CMProfileAccessUPP proc;
+ void * refCon;
+};
+typedef struct CMProcedureLocation CMProcedureLocation;
+struct CMPathLocation {
+ char path[256];
+};
+typedef struct CMPathLocation CMPathLocation;
+struct CMBufferLocation {
+ void * buffer;
+ UInt32 size;
+};
+typedef struct CMBufferLocation CMBufferLocation;
+union CMProfLoc {
+ CMFileLocation fileLoc;
+ CMHandleLocation handleLoc;
+ CMPtrLocation ptrLoc;
+ CMProcedureLocation procLoc;
+ CMPathLocation pathLoc;
+ CMBufferLocation bufferLoc;
+};
+typedef union CMProfLoc CMProfLoc;
+struct CMProfileLocation {
+ short locType;
+ CMProfLoc u;
+};
+typedef struct CMProfileLocation CMProfileLocation;
+enum {
+ cmOriginalProfileLocationSize = 72,
+ cmCurrentProfileLocationSize = 2 + CS_MAX_PATH
+};
+
+
+enum {
+ cmProfileIterateDataVersion1 = 0x00010000,
+ cmProfileIterateDataVersion2 = 0x00020000,
+ cmProfileIterateDataVersion3 = 0x00030000
+};
+
+struct CMProfileIterateData {
+ UInt32 dataVersion;
+ CM2Header header;
+ ScriptCode code;
+ Str255 name;
+ CMProfileLocation location;
+ UniCharCount uniCodeNameCount;
+ UniChar * uniCodeName;
+ unsigned char * asciiName;
+ CMMakeAndModel * makeAndModel;
+ CMProfileMD5 * digest;
+};
+typedef struct CMProfileIterateData CMProfileIterateData;
+
+typedef OSErr ( * CMProfileIterateProcPtr)(CMProfileIterateData *iterateData, void *refCon);
+typedef OSErr ( * CMMIterateProcPtr)(CMMInfo *iterateData, void *refCon);
+typedef CMProfileIterateProcPtr CMProfileIterateUPP;
+typedef CMMIterateProcPtr CMMIterateUPP;
+extern CMProfileIterateUPP
+NewCMProfileIterateUPP(CMProfileIterateProcPtr userRoutine) ;
+extern CMMIterateUPP
+NewCMMIterateUPP(CMMIterateProcPtr userRoutine) ;
+extern void
+DisposeCMProfileIterateUPP(CMProfileIterateUPP userUPP) ;
+extern void
+DisposeCMMIterateUPP(CMMIterateUPP userUPP) ;
+extern OSErr
+InvokeCMProfileIterateUPP(
+ CMProfileIterateData * iterateData,
+ void * refCon,
+ CMProfileIterateUPP userUPP) ;
+extern OSErr
+InvokeCMMIterateUPP(
+ CMMInfo * iterateData,
+ void * refCon,
+ CMMIterateUPP userUPP) ;
+extern CMError
+CMNewProfile(
+ CMProfileRef * prof,
+ const CMProfileLocation * theProfile) ;
+extern CMError
+CMOpenProfile(
+ CMProfileRef * prof,
+ const CMProfileLocation * theProfile) ;
+extern CMError
+CMCloseProfile(CMProfileRef prof) ;
+extern CMError
+CMUpdateProfile(CMProfileRef prof) ;
+extern CMError
+CMCopyProfile(
+ CMProfileRef * targetProf,
+ const CMProfileLocation * targetLocation,
+ CMProfileRef srcProf) ;
+extern CMError
+CMValidateProfile(
+ CMProfileRef prof,
+ Boolean * valid,
+ Boolean * preferredCMMnotfound) ;
+extern CMError
+CMGetProfileLocation(
+ CMProfileRef prof,
+ CMProfileLocation * theProfile) ;
+extern CMError
+NCMGetProfileLocation(
+ CMProfileRef prof,
+ CMProfileLocation * theProfile,
+ UInt32 * locationSize) ;
+extern CMError
+CMFlattenProfile(
+ CMProfileRef prof,
+ UInt32 flags,
+ CMFlattenUPP proc,
+ void * refCon,
+ Boolean * preferredCMMnotfound) ;
+extern CMError
+CMGetProfileHeader(
+ CMProfileRef prof,
+ CMAppleProfileHeader * header) ;
+extern CMError
+CMSetProfileHeader(
+ CMProfileRef prof,
+ const CMAppleProfileHeader * header) ;
+extern CMError
+CMProfileElementExists(
+ CMProfileRef prof,
+ OSType tag,
+ Boolean * found) ;
+extern CMError
+CMCountProfileElements(
+ CMProfileRef prof,
+ UInt32 * elementCount) ;
+extern CMError
+CMGetProfileElement(
+ CMProfileRef prof,
+ OSType tag,
+ UInt32 * elementSize,
+ void * elementData) ;
+extern CMError
+CMSetProfileElement(
+ CMProfileRef prof,
+ OSType tag,
+ UInt32 elementSize,
+ const void * elementData) ;
+extern CMError
+CMSetProfileElementSize(
+ CMProfileRef prof,
+ OSType tag,
+ UInt32 elementSize) ;
+extern CMError
+CMSetProfileElementReference(
+ CMProfileRef prof,
+ OSType elementTag,
+ OSType referenceTag) ;
+extern CMError
+CMGetPartialProfileElement(
+ CMProfileRef prof,
+ OSType tag,
+ UInt32 offset,
+ UInt32 * byteCount,
+ void * elementData) ;
+extern CMError
+CMSetPartialProfileElement(
+ CMProfileRef prof,
+ OSType tag,
+ UInt32 offset,
+ UInt32 byteCount,
+ const void * elementData) ;
+extern CMError
+CMGetIndProfileElementInfo(
+ CMProfileRef prof,
+ UInt32 index,
+ OSType * tag,
+ UInt32 * elementSize,
+ Boolean * refs) ;
+extern CMError
+CMGetIndProfileElement(
+ CMProfileRef prof,
+ UInt32 index,
+ UInt32 * elementSize,
+ void * elementData) ;
+extern CMError
+CMRemoveProfileElement(
+ CMProfileRef prof,
+ OSType tag) ;
+extern CMError
+CMGetScriptProfileDescription(
+ CMProfileRef prof,
+ Str255 name,
+ ScriptCode * code) ;
+extern CMError
+CMGetProfileDescriptions(
+ CMProfileRef prof,
+ char * aName,
+ UInt32 * aCount,
+ Str255 mName,
+ ScriptCode * mCode,
+ UniChar * uName,
+ UniCharCount * uCount) ;
+extern CMError
+CMSetProfileDescriptions(
+ CMProfileRef prof,
+ const char * aName,
+ UInt32 aCount,
+ ConstStr255Param mName,
+ ScriptCode mCode,
+ const UniChar * uName,
+ UniCharCount uCount) ;
+extern CMError
+CMCopyProfileLocalizedStringDictionary(
+ CMProfileRef prof,
+ OSType tag,
+ CFDictionaryRef * theDict) ;
+extern CMError
+CMSetProfileLocalizedStringDictionary(
+ CMProfileRef prof,
+ OSType tag,
+ CFDictionaryRef theDict) ;
+extern CMError
+CMCopyProfileLocalizedString(
+ CMProfileRef prof,
+ OSType tag,
+ CFStringRef reqLocale,
+ CFStringRef * locale,
+ CFStringRef * str) ;
+extern CMError
+CMCloneProfileRef(CMProfileRef prof) ;
+extern CMError
+CMGetProfileRefCount(
+ CMProfileRef prof,
+ long * count) ;
+extern CMError
+CMProfileModified(
+ CMProfileRef prof,
+ Boolean * modified) ;
+extern CMError
+CMGetProfileMD5(
+ CMProfileRef prof,
+ CMProfileMD5 digest) ;
+extern CMError
+CMGetNamedColorInfo(
+ CMProfileRef prof,
+ UInt32 * deviceChannels,
+ OSType * deviceColorSpace,
+ OSType * PCSColorSpace,
+ UInt32 * count,
+ StringPtr prefix,
+ StringPtr suffix) ;
+extern CMError
+CMGetNamedColorValue(
+ CMProfileRef prof,
+ StringPtr name,
+ CMColor * deviceColor,
+ CMColor * PCSColor) ;
+extern CMError
+CMGetIndNamedColorValue(
+ CMProfileRef prof,
+ UInt32 index,
+ CMColor * deviceColor,
+ CMColor * PCSColor) ;
+extern CMError
+CMGetNamedColorIndex(
+ CMProfileRef prof,
+ StringPtr name,
+ UInt32 * index) ;
+extern CMError
+CMGetNamedColorName(
+ CMProfileRef prof,
+ UInt32 index,
+ StringPtr name) ;
+extern CMError
+NCWNewColorWorld(
+ CMWorldRef * cw,
+ CMProfileRef src,
+ CMProfileRef dst) ;
+extern CMError
+CWConcatColorWorld(
+ CMWorldRef * cw,
+ CMConcatProfileSet * profileSet) ;
+extern CMError
+CWNewLinkProfile(
+ CMProfileRef * prof,
+ const CMProfileLocation * targetLocation,
+ CMConcatProfileSet * profileSet) ;
+extern CMError
+NCWConcatColorWorld(
+ CMWorldRef * cw,
+ NCMConcatProfileSet * profileSet,
+ CMConcatCallBackUPP proc,
+ void * refCon) ;
+extern CMError
+NCWNewLinkProfile(
+ CMProfileRef * prof,
+ const CMProfileLocation * targetLocation,
+ NCMConcatProfileSet * profileSet,
+ CMConcatCallBackUPP proc,
+ void * refCon) ;
+extern void
+CWDisposeColorWorld(CMWorldRef cw) ;
+extern CMError
+CWMatchColors(
+ CMWorldRef cw,
+ CMColor * myColors,
+ UInt32 count) ;
+extern CMError
+CWCheckColors(
+ CMWorldRef cw,
+ CMColor * myColors,
+ UInt32 count,
+ UInt32 * result) ;
+extern CMError
+CWMatchBitmap(
+ CMWorldRef cw,
+ CMBitmap * bitmap,
+ CMBitmapCallBackUPP progressProc,
+ void * refCon,
+ CMBitmap * matchedBitmap) ;
+extern CMError
+CWCheckBitmap(
+ CMWorldRef cw,
+ const CMBitmap * bitmap,
+ CMBitmapCallBackUPP progressProc,
+ void * refCon,
+ CMBitmap * resultBitmap) ;
+extern CMError
+CMCreateProfileIdentifier(
+ CMProfileRef prof,
+ CMProfileIdentifierPtr ident,
+ UInt32 * size) ;
+extern CMError
+CMGetSystemProfile(CMProfileRef * prof) ;
+extern CMError
+CMSetSystemProfile(const FSSpec * profileFileSpec) ;
+extern CMError
+NCMSetSystemProfile(const CMProfileLocation * profLoc) ;
+extern CMError
+CMGetDefaultProfileBySpace(
+ OSType dataColorSpace,
+ CMProfileRef * prof) ;
+extern CMError
+CMSetDefaultProfileBySpace(
+ OSType dataColorSpace,
+ CMProfileRef prof) ;
+extern CMError
+CMGetProfileByAVID(
+ CMDisplayIDType theID,
+ CMProfileRef * prof) ;
+extern CMError
+CMSetProfileByAVID(
+ CMDisplayIDType theID,
+ CMProfileRef prof) ;
+extern CMError
+CMGetGammaByAVID(
+ CMDisplayIDType theID,
+ CMVideoCardGamma * gamma,
+ UInt32 * size) ;
+extern CMError
+CMSetGammaByAVID(
+ CMDisplayIDType theID,
+ CMVideoCardGamma * gamma) ;
+extern CMError
+CMGetDefaultProfileByUse(
+ OSType use,
+ CMProfileRef * prof) ;
+extern CMError
+CMSetDefaultProfileByUse(
+ OSType use,
+ CMProfileRef prof) ;
+extern CMError
+CMNewProfileSearch(
+ CMSearchRecord * searchSpec,
+ void * refCon,
+ UInt32 * count,
+ CMProfileSearchRef * searchResult) ;
+extern CMError
+CMUpdateProfileSearch(
+ CMProfileSearchRef search,
+ void * refCon,
+ UInt32 * count) ;
+extern void
+CMDisposeProfileSearch(CMProfileSearchRef search) ;
+extern CMError
+CMSearchGetIndProfile(
+ CMProfileSearchRef search,
+ UInt32 index,
+ CMProfileRef * prof) ;
+extern CMError
+CMSearchGetIndProfileFileSpec(
+ CMProfileSearchRef search,
+ UInt32 index,
+ FSSpec * profileFile) ;
+extern CMError
+CMProfileIdentifierFolderSearch(
+ CMProfileIdentifierPtr ident,
+ UInt32 * matchedCount,
+ CMProfileSearchRef * searchResult) ;
+extern CMError
+CMProfileIdentifierListSearch(
+ CMProfileIdentifierPtr ident,
+ CMProfileRef * profileList,
+ UInt32 listSize,
+ UInt32 * matchedCount,
+ CMProfileRef * matchedList) ;
+extern CMError
+CMIterateColorSyncFolder(
+ CMProfileIterateUPP proc,
+ UInt32 * seed,
+ UInt32 * count,
+ void * refCon) ;
+extern CMError
+NCMUnflattenProfile(
+ CMProfileLocation * targetLocation,
+ CMFlattenUPP proc,
+ void * refCon,
+ Boolean * preferredCMMnotfound) ;
+extern CMError
+CMGetColorSyncFolderSpec(
+ short vRefNum,
+ Boolean createFolder,
+ short * foundVRefNum,
+ long * foundDirID) ;
+extern CMError
+CMGetCWInfo(
+ CMWorldRef cw,
+ CMCWInfoRecord * info) ;
+extern CMError
+CMGetPreferredCMM(
+ OSType * cmmType,
+ Boolean * preferredCMMnotfound) ;
+extern CMError
+CMIterateCMMInfo(
+ CMMIterateUPP proc,
+ UInt32 * count,
+ void * refCon) ;
+extern CMError
+CMGetColorSyncVersion(UInt32 * version) ;
+extern CMError
+CMLaunchControlPanel(UInt32 flags) ;
+extern CMError
+CMConvertXYZToLab(
+ const CMColor * src,
+ const CMXYZColor * white,
+ CMColor * dst,
+ UInt32 count) ;
+extern CMError
+CMConvertLabToXYZ(
+ const CMColor * src,
+ const CMXYZColor * white,
+ CMColor * dst,
+ UInt32 count) ;
+extern CMError
+CMConvertXYZToLuv(
+ const CMColor * src,
+ const CMXYZColor * white,
+ CMColor * dst,
+ UInt32 count) ;
+extern CMError
+CMConvertLuvToXYZ(
+ const CMColor * src,
+ const CMXYZColor * white,
+ CMColor * dst,
+ UInt32 count) ;
+extern CMError
+CMConvertXYZToYxy(
+ const CMColor * src,
+ CMColor * dst,
+ UInt32 count) ;
+extern CMError
+CMConvertYxyToXYZ(
+ const CMColor * src,
+ CMColor * dst,
+ UInt32 count) ;
+extern CMError
+CMConvertRGBToHLS(
+ const CMColor * src,
+ CMColor * dst,
+ UInt32 count) ;
+extern CMError
+CMConvertHLSToRGB(
+ const CMColor * src,
+ CMColor * dst,
+ UInt32 count) ;
+extern CMError
+CMConvertRGBToHSV(
+ const CMColor * src,
+ CMColor * dst,
+ UInt32 count) ;
+extern CMError
+CMConvertHSVToRGB(
+ const CMColor * src,
+ CMColor * dst,
+ UInt32 count) ;
+extern CMError
+CMConvertRGBToGray(
+ const CMColor * src,
+ CMColor * dst,
+ UInt32 count) ;
+extern CMError
+CMConvertXYZToFixedXYZ(
+ const CMXYZColor * src,
+ CMFixedXYZColor * dst,
+ UInt32 count) ;
+extern CMError
+CMConvertFixedXYZToXYZ(
+ const CMFixedXYZColor * src,
+ CMXYZColor * dst,
+ UInt32 count) ;
+extern CMError
+CMConvertXYZToXYZ(
+ const CMColor * src,
+ const CMXYZColor * srcIlluminant,
+ CMColor * dst,
+ const CMXYZColor * dstIlluminant,
+ CMChromaticAdaptation method,
+ UInt32 count) ;
+extern CMError
+CMGetPS2ColorSpace(
+ CMProfileRef srcProf,
+ UInt32 flags,
+ CMFlattenUPP proc,
+ void * refCon,
+ Boolean * preferredCMMnotfound) ;
+extern CMError
+CMGetPS2ColorRenderingIntent(
+ CMProfileRef srcProf,
+ UInt32 flags,
+ CMFlattenUPP proc,
+ void * refCon,
+ Boolean * preferredCMMnotfound) ;
+extern CMError
+CMGetPS2ColorRendering(
+ CMProfileRef srcProf,
+ CMProfileRef dstProf,
+ UInt32 flags,
+ CMFlattenUPP proc,
+ void * refCon,
+ Boolean * preferredCMMnotfound) ;
+extern CMError
+CMGetPS2ColorRenderingVMSize(
+ CMProfileRef srcProf,
+ CMProfileRef dstProf,
+ UInt32 * vmSize,
+ Boolean * preferredCMMnotfound) ;
+
+
+}
+
+
+
+
+
+
+
+extern "C" {
+
+
+
+
+
+
+
+enum {
+ cmDeviceInfoVersion1 = 0x00010000,
+ cmDeviceProfileInfoVersion1 = 0x00010000,
+ cmDeviceProfileInfoVersion2 = 0x00020000
+};
+
+enum {
+ cmCurrentDeviceInfoVersion = cmDeviceInfoVersion1,
+ cmCurrentProfileInfoVersion = cmDeviceProfileInfoVersion1
+};
+
+
+
+
+
+enum {
+ cmDefaultDeviceID = 0,
+ cmDefaultProfileID = 0
+};
+
+
+
+
+
+enum {
+ cmDeviceStateDefault = 0x00000000,
+ cmDeviceStateOffline = 0x00000001,
+ cmDeviceStateBusy = 0x00000002,
+ cmDeviceStateForceNotify = (long)0x80000000,
+ cmDeviceStateDeviceRsvdBits = 0x00FF0000,
+ cmDeviceStateAppleRsvdBits = (long)0xFF00FFFF
+};
+enum {
+ cmIterateFactoryDeviceProfiles = 0x00000001,
+ cmIterateCustomDeviceProfiles = 0x00000002,
+ cmIterateCurrentDeviceProfiles = 0x00000003,
+ cmIterateAllDeviceProfiles = 0x00000004,
+ cmIterateDeviceProfilesMask = 0x0000000F
+};
+
+
+
+
+enum {
+ cmDeviceDBNotFoundErr = -4227,
+ cmDeviceAlreadyRegistered = -4228,
+ cmDeviceNotRegistered = -4229,
+ cmDeviceProfilesNotFound = -4230,
+ cmInternalCFErr = -4231
+};
+typedef UInt32 CMDeviceState;
+
+
+
+typedef UInt32 CMDeviceID;
+
+
+
+typedef UInt32 CMDeviceProfileID;
+
+
+
+enum {
+ cmScannerDeviceClass = 'scnr',
+ cmCameraDeviceClass = 'cmra',
+ cmDisplayDeviceClass = 'mntr',
+ cmPrinterDeviceClass = 'prtr',
+ cmProofDeviceClass = 'pruf'
+};
+
+typedef OSType CMDeviceClass;
+
+
+
+
+struct CMDeviceScope {
+ CFStringRef deviceUser;
+ CFStringRef deviceHost;
+};
+typedef struct CMDeviceScope CMDeviceScope;
+typedef CMDeviceScope CMDeviceProfileScope;
+
+
+
+
+struct CMDeviceInfo {
+ UInt32 dataVersion;
+ CMDeviceClass deviceClass;
+ CMDeviceID deviceID;
+ CMDeviceScope deviceScope;
+ CMDeviceState deviceState;
+ CMDeviceProfileID defaultProfileID;
+ CFDictionaryRef * deviceName;
+
+ UInt32 profileCount;
+ UInt32 reserved;
+};
+typedef struct CMDeviceInfo CMDeviceInfo;
+typedef CMDeviceInfo * CMDeviceInfoPtr;
+
+
+
+
+struct CMDeviceProfileInfo {
+ UInt32 dataVersion;
+ CMDeviceProfileID profileID;
+ CMProfileLocation profileLoc;
+ CFDictionaryRef profileName;
+ UInt32 reserved;
+};
+typedef struct CMDeviceProfileInfo CMDeviceProfileInfo;
+struct NCMDeviceProfileInfo {
+ UInt32 dataVersion;
+ CMDeviceProfileID profileID;
+ CMProfileLocation profileLoc;
+ CFDictionaryRef profileName;
+ CMDeviceProfileScope profileScope;
+ UInt32 reserved;
+};
+typedef struct NCMDeviceProfileInfo NCMDeviceProfileInfo;
+
+
+
+
+struct CMDeviceProfileArray {
+ UInt32 profileCount;
+ CMDeviceProfileInfo profiles[1];
+};
+typedef struct CMDeviceProfileArray CMDeviceProfileArray;
+typedef CMDeviceProfileArray * CMDeviceProfileArrayPtr;
+
+
+
+typedef OSErr ( * CMIterateDeviceInfoProcPtr)(const CMDeviceInfo *deviceInfo, void *refCon);
+typedef OSErr ( * CMIterateDeviceProfileProcPtr)(const CMDeviceInfo *deviceInfo, const NCMDeviceProfileInfo *profileInfo, void *refCon);
+extern CMError
+CMRegisterColorDevice(
+ CMDeviceClass deviceClass,
+ CMDeviceID deviceID,
+ CFDictionaryRef deviceName,
+ const CMDeviceScope * deviceScope) ;
+extern CMError
+CMUnregisterColorDevice(
+ CMDeviceClass deviceClass,
+ CMDeviceID deviceID) ;
+extern CMError
+CMSetDefaultDevice(
+ CMDeviceClass deviceClass,
+ CMDeviceID deviceID) ;
+extern CMError
+CMGetDefaultDevice(
+ CMDeviceClass deviceClass,
+ CMDeviceID * deviceID) ;
+extern CMError
+CMSetDeviceFactoryProfiles(
+ CMDeviceClass deviceClass,
+ CMDeviceID deviceID,
+ CMDeviceProfileID defaultProfID,
+ const CMDeviceProfileArray * deviceProfiles) ;
+extern CMError
+CMGetDeviceFactoryProfiles(
+ CMDeviceClass deviceClass,
+ CMDeviceID deviceID,
+ CMDeviceProfileID * defaultProfID,
+ UInt32 * arraySize,
+ CMDeviceProfileArray * deviceProfiles) ;
+extern CMError
+CMSetDeviceProfiles(
+ CMDeviceClass deviceClass,
+ CMDeviceID deviceID,
+ const CMDeviceProfileScope * profileScope,
+ const CMDeviceProfileArray * deviceProfiles) ;
+extern CMError
+CMGetDeviceProfiles(
+ CMDeviceClass deviceClass,
+ CMDeviceID deviceID,
+ UInt32 * arraySize,
+ CMDeviceProfileArray * deviceProfiles) ;
+extern CMError
+CMSetDeviceDefaultProfileID(
+ CMDeviceClass deviceClass,
+ CMDeviceID deviceID,
+ CMDeviceProfileID defaultProfID) ;
+extern CMError
+CMGetDeviceDefaultProfileID(
+ CMDeviceClass deviceClass,
+ CMDeviceID deviceID,
+ CMDeviceProfileID * defaultProfID) ;
+extern CMError
+CMGetDeviceProfile(
+ CMDeviceClass deviceClass,
+ CMDeviceID deviceID,
+ CMDeviceProfileID profileID,
+ CMProfileLocation * deviceProfLoc) ;
+extern CMError
+CMSetDeviceProfile(
+ CMDeviceClass deviceClass,
+ CMDeviceID deviceID,
+ const CMDeviceProfileScope * profileScope,
+ CMDeviceProfileID profileID,
+ const CMProfileLocation * deviceProfLoc) ;
+extern CMError
+CMSetDeviceState(
+ CMDeviceClass deviceClass,
+ CMDeviceID deviceID,
+ CMDeviceState deviceState) ;
+extern CMError
+CMGetDeviceState(
+ CMDeviceClass deviceClass,
+ CMDeviceID deviceID,
+ CMDeviceState * deviceState) ;
+extern CMError
+CMGetDeviceInfo(
+ CMDeviceClass deviceClass,
+ CMDeviceID deviceID,
+ CMDeviceInfo * deviceInfo) ;
+extern CMError
+CMIterateColorDevices(
+ CMIterateDeviceInfoProcPtr proc,
+ UInt32 * seed,
+ UInt32 * count,
+ void * refCon) ;
+extern CMError
+CMIterateDeviceProfiles(
+ CMIterateDeviceProfileProcPtr proc,
+ UInt32 * seed,
+ UInt32 * count,
+ UInt32 flags,
+ void * refCon) ;
+
+
+
+
+
+}
+
+
+
+enum {
+ CMMInterfaceVersion = 1
+};
+
+
+
+enum {
+
+ kCMMOpen = -1,
+ kCMMClose = -2,
+ kCMMGetInfo = -4,
+ kNCMMInit = 6,
+ kCMMMatchColors = 1,
+ kCMMCheckColors = 2,
+
+
+ kCMMValidateProfile = 8,
+ kCMMMatchBitmap = 9,
+ kCMMCheckBitmap = 10,
+ kCMMConcatenateProfiles = 5,
+ kCMMConcatInit = 7,
+ kCMMNewLinkProfile = 16,
+ kNCMMConcatInit = 18,
+ kNCMMNewLinkProfile = 19,
+ kCMMGetPS2ColorSpace = 11,
+ kCMMGetPS2ColorRenderingIntent = 12,
+ kCMMGetPS2ColorRendering = 13,
+ kCMMGetPS2ColorRenderingVMSize = 17,
+
+
+ kCMMFlattenProfile = 14,
+ kCMMUnflattenProfile = 15,
+
+
+ kCMMInit = 0,
+ kCMMGetNamedColorInfo = 70,
+ kCMMGetNamedColorValue = 71,
+ kCMMGetIndNamedColorValue = 72,
+ kCMMGetNamedColorIndex = 73,
+ kCMMGetNamedColorName = 74,
+
+
+ kCMMMatchPixMap = 3,
+ kCMMCheckPixMap = 4
+};
+
+
+
+extern "C" {
+
+
+enum {
+
+ cmspInvalidImageFile = -4220,
+ cmspInvalidImageSpace = -4221,
+ cmspInvalidProfileEmbed = -4222,
+ cmspInvalidProfileSource = -4223,
+ cmspInvalidProfileDest = -4224,
+ cmspInvalidProfileProof = -4225,
+ cmspInvalidProfileLink = -4226
+};
+
+
+
+
+
+
+enum {
+ cmspFavorEmbeddedMask = 0x00000001
+};
+
+
+
+typedef CMError ( * ValidateImageProcPtr)(const FSSpec * spec);
+typedef CMError ( * GetImageSpaceProcPtr)(const FSSpec *spec, OSType *space);
+typedef CMError ( * ValidateSpaceProcPtr)(const FSSpec *spec, OSType *space);
+typedef CMError ( * EmbedImageProcPtr)(const FSSpec *specFrom, const FSSpec *specInto, CMProfileRef embedProf, UInt32 embedFlags);
+typedef CMError ( * UnembedImageProcPtr)(const FSSpec *specFrom, const FSSpec *specInto);
+typedef CMError ( * MatchImageProcPtr)(const FSSpec *specFrom, const FSSpec *specInto, UInt32 qual, UInt32 srcIntent, CMProfileRef srcProf, CMProfileRef dstProf, CMProfileRef prfProf, UInt32 matchFlags);
+typedef CMError ( * CountImageProfilesProcPtr)(const FSSpec *spec, UInt32 *count);
+typedef CMError ( * GetIndImageProfileProcPtr)(const FSSpec *spec, UInt32 index, CMProfileRef *prof);
+typedef CMError ( * SetIndImageProfileProcPtr)(const FSSpec *specFrom, const FSSpec *specInto, UInt32 index, CMProfileRef prof, UInt32 embedFlags);
+
+typedef CMError ( * CMValidImageProcPtr)(const FSSpec * spec);
+typedef CMError ( * CMGetImageSpaceProcPtr)(const FSSpec *spec, OSType *space);
+typedef CMError ( * CMEmbedImageProcPtr)(const FSSpec *specFrom, const FSSpec *specInto, Boolean repl, CMProfileRef embProf);
+typedef CMError ( * CMUnembedImageProcPtr)(const FSSpec *specFrom, const FSSpec *specInto, Boolean repl);
+typedef CMError ( * CMMatchImageProcPtr)(const FSSpec *specFrom, const FSSpec *specInto, Boolean repl, UInt32 qual, CMProfileRef srcProf, UInt32 srcIntent, CMProfileRef dstProf);
+typedef CMError ( * CMProofImageProcPtr)(const FSSpec *specFrom, const FSSpec *specInto, Boolean repl, UInt32 qual, CMProfileRef srcProf, UInt32 srcIntent, CMProfileRef dstProf, CMProfileRef prfProf);
+typedef CMError ( * CMLinkImageProcPtr)(const FSSpec *specFrom, const FSSpec *specInto, Boolean repl, UInt32 qual, CMProfileRef lnkProf, UInt32 lnkIntent);
+typedef CMError ( * CMCountImageProfilesProcPtr)(const FSSpec *spec, UInt32 *count);
+typedef CMError ( * CMGetIndImageProfileProcPtr)(const FSSpec *spec, UInt32 index, CMProfileRef *prof);
+typedef CMError ( * CMSetIndImageProfileProcPtr)(const FSSpec *specFrom, const FSSpec *specInto, Boolean repl, UInt32 index, CMProfileRef prof);
+extern CMError
+CMValidImage(const FSSpec * spec);
+extern CMError
+CMGetImageSpace(
+ const FSSpec * spec,
+ OSType * space);
+extern CMError
+CMEmbedImage(
+ const FSSpec * specFrom,
+ const FSSpec * specInto,
+ Boolean repl,
+ CMProfileRef embProf);
+extern CMError
+CMUnembedImage(
+ const FSSpec * specFrom,
+ const FSSpec * specInto,
+ Boolean repl);
+extern CMError
+CMMatchImage(
+ const FSSpec * specFrom,
+ const FSSpec * specInto,
+ Boolean repl,
+ UInt32 qual,
+ CMProfileRef srcProf,
+ UInt32 srcIntent,
+ CMProfileRef dstProf);
+extern CMError
+CMProofImage(
+ const FSSpec * specFrom,
+ const FSSpec * specInto,
+ Boolean repl,
+ UInt32 qual,
+ CMProfileRef srcProf,
+ UInt32 srcIntent,
+ CMProfileRef dstProf,
+ CMProfileRef prfProf);
+extern CMError
+CMLinkImage(
+ const FSSpec * specFrom,
+ const FSSpec * specInto,
+ Boolean repl,
+ UInt32 qual,
+ CMProfileRef lnkProf,
+ UInt32 lnkIntent);
+extern CMError
+CMCountImageProfiles(
+ const FSSpec * spec,
+ UInt32 * count);
+extern CMError
+CMGetIndImageProfile(
+ const FSSpec * spec,
+ UInt32 index,
+ CMProfileRef * prof);
+extern CMError
+CMSetIndImageProfile(
+ const FSSpec * specFrom,
+ const FSSpec * specInto,
+ Boolean repl,
+ UInt32 index,
+ CMProfileRef prof);
+
+
+
+
+}
+
+
+
+
+
+
+
+extern "C" {
+
+
+
+
+enum {
+ typeBoolean = 'bool',
+ typeChar = 'TEXT'
+};
+
+
+enum {
+ typeSInt16 = 'shor',
+ typeSInt32 = 'long',
+ typeUInt32 = 'magn',
+ typeSInt64 = 'comp',
+ typeIEEE32BitFloatingPoint = 'sing',
+ typeIEEE64BitFloatingPoint = 'doub',
+ type128BitFloatingPoint = 'ldbl',
+ typeDecimalStruct = 'decm'
+};
+
+
+enum {
+ typeSMInt = typeSInt16,
+ typeShortInteger = typeSInt16,
+ typeInteger = typeSInt32,
+ typeLongInteger = typeSInt32,
+ typeMagnitude = typeUInt32,
+ typeComp = typeSInt64,
+ typeSMFloat = typeIEEE32BitFloatingPoint,
+ typeShortFloat = typeIEEE32BitFloatingPoint,
+ typeFloat = typeIEEE64BitFloatingPoint,
+ typeLongFloat = typeIEEE64BitFloatingPoint,
+ typeExtended = 'exte'
+};
+
+
+enum {
+ typeAEList = 'list',
+ typeAERecord = 'reco',
+ typeAppleEvent = 'aevt',
+ typeEventRecord = 'evrc',
+ typeTrue = 'true',
+ typeFalse = 'fals',
+ typeAlias = 'alis',
+ typeEnumerated = 'enum',
+ typeType = 'type',
+ typeAppParameters = 'appa',
+ typeProperty = 'prop',
+ typeFSS = 'fss ',
+ typeFSRef = 'fsrf',
+ typeFileURL = 'furl',
+ typeKeyword = 'keyw',
+ typeSectionH = 'sect',
+ typeWildCard = '****',
+ typeApplSignature = 'sign',
+ typeQDRectangle = 'qdrt',
+ typeFixed = 'fixd',
+ typeProcessSerialNumber = 'psn ',
+ typeApplicationURL = 'aprl',
+ typeNull = 'null'
+};
+
+
+enum {
+ typeKernelProcessID = 'kpid',
+ typeMachPort = 'port'
+};
+
+
+enum {
+ keyTransactionIDAttr = 'tran',
+ keyReturnIDAttr = 'rtid',
+ keyEventClassAttr = 'evcl',
+ keyEventIDAttr = 'evid',
+ keyAddressAttr = 'addr',
+ keyOptionalKeywordAttr = 'optk',
+ keyTimeoutAttr = 'timo',
+ keyInteractLevelAttr = 'inte',
+ keyEventSourceAttr = 'esrc',
+ keyMissedKeywordAttr = 'miss',
+ keyOriginalAddressAttr = 'from',
+ keyAcceptTimeoutAttr = 'actm'
+};
+
+
+enum {
+ kAEDebugPOSTHeader = (1 << 0),
+ kAEDebugReplyHeader = (1 << 1),
+ kAEDebugXMLRequest = (1 << 2),
+ kAEDebugXMLResponse = (1 << 3),
+ kAEDebugXMLDebugAll = (long)0xFFFFFFFF
+};
+
+
+
+
+
+enum {
+ kSOAP1999Schema = 'ss99',
+ kSOAP2001Schema = 'ss01'
+};
+
+enum {
+
+ keyUserNameAttr = 'unam',
+ keyUserPasswordAttr = 'pass',
+ keyDisableAuthenticationAttr = 'auth',
+
+
+ keyXMLDebuggingAttr = 'xdbg',
+
+ kAERPCClass = 'rpc ',
+ kAEXMLRPCScheme = 'RPC2',
+ kAESOAPScheme = 'SOAP',
+ kAESharedScriptHandler = 'wscp',
+
+ keyRPCMethodName = 'meth',
+ keyRPCMethodParam = 'parm',
+ keyRPCMethodParamOrder = '/ord',
+
+ keyAEPOSTHeaderData = 'phed',
+ keyAEReplyHeaderData = 'rhed',
+ keyAEXMLRequestData = 'xreq',
+ keyAEXMLReplyData = 'xrep',
+
+ keyAdditionalHTTPHeaders = 'ahed',
+ keySOAPAction = 'sact',
+ keySOAPMethodNameSpace = 'mspc',
+ keySOAPMethodNameSpaceURI = 'mspu',
+ keySOAPSchemaVersion = 'ssch'
+};
+enum {
+ keySOAPStructureMetaData = '/smd',
+ keySOAPSMDNamespace = 'ssns',
+ keySOAPSMDNamespaceURI = 'ssnu',
+ keySOAPSMDType = 'sstp'
+};
+
+
+
+
+
+
+enum {
+
+ kAEUseHTTPProxyAttr = 'xupr',
+
+ kAEHTTPProxyPortAttr = 'xhtp',
+ kAEHTTPProxyHostAttr = 'xhth'
+};
+
+
+
+
+
+
+enum {
+ kAESocks4Protocol = 4,
+ kAESocks5Protocol = 5
+};
+
+enum {
+ kAEUseSocksAttr = 'xscs',
+
+ kAESocksProxyAttr = 'xsok',
+
+ kAESocksHostAttr = 'xshs',
+ kAESocksPortAttr = 'xshp',
+ kAESocksUserAttr = 'xshu',
+
+ kAESocksPasswordAttr = 'xshw'
+};
+
+
+
+enum {
+ kAEDescListFactorNone = 0,
+ kAEDescListFactorType = 4,
+ kAEDescListFactorTypeAndSize = 8
+};
+
+
+enum {
+
+ kAutoGenerateReturnID = -1,
+
+ kAnyTransactionID = 0
+};
+
+
+typedef ResType DescType;
+typedef FourCharCode AEKeyword;
+
+typedef struct OpaqueAEDataStorageType* AEDataStorageType;
+
+
+
+
+typedef AEDataStorageType * AEDataStorage;
+struct AEDesc {
+ DescType descriptorType;
+ AEDataStorage dataHandle;
+};
+typedef struct AEDesc AEDesc;
+typedef AEDesc * AEDescPtr;
+struct AEKeyDesc {
+ AEKeyword descKey;
+ AEDesc descContent;
+};
+typedef struct AEKeyDesc AEKeyDesc;
+
+
+typedef AEDesc AEDescList;
+
+typedef AEDescList AERecord;
+
+typedef AEDesc AEAddressDesc;
+
+typedef AERecord AppleEvent;
+typedef AppleEvent * AppleEventPtr;
+typedef SInt16 AEReturnID;
+typedef SInt32 AETransactionID;
+typedef FourCharCode AEEventClass;
+typedef FourCharCode AEEventID;
+typedef SInt8 AEArrayType;
+enum {
+ kAEDataArray = 0,
+ kAEPackedArray = 1,
+ kAEDescArray = 3,
+ kAEKeyDescArray = 4
+};
+
+
+enum {
+ kAEHandleArray = 2
+};
+
+union AEArrayData {
+ short kAEDataArray[1];
+ char kAEPackedArray[1];
+ Handle kAEHandleArray[1];
+ AEDesc kAEDescArray[1];
+ AEKeyDesc kAEKeyDescArray[1];
+};
+typedef union AEArrayData AEArrayData;
+typedef AEArrayData * AEArrayDataPointer;
+
+
+
+
+typedef SInt16 AESendPriority;
+enum {
+ kAENormalPriority = 0x00000000,
+ kAEHighPriority = 0x00000001
+};
+
+
+typedef SInt32 AESendMode;
+enum {
+ kAENoReply = 0x00000001,
+ kAEQueueReply = 0x00000002,
+ kAEWaitReply = 0x00000003,
+ kAEDontReconnect = 0x00000080,
+ kAEWantReceipt = 0x00000200,
+ kAENeverInteract = 0x00000010,
+ kAECanInteract = 0x00000020,
+ kAEAlwaysInteract = 0x00000030,
+ kAECanSwitchLayer = 0x00000040,
+ kAEDontRecord = 0x00001000,
+ kAEDontExecute = 0x00002000,
+ kAEProcessNonReplyEvents = 0x00008000
+};
+
+
+
+enum {
+ kAEDefaultTimeout = -1,
+ kNoTimeOut = -2
+};
+
+
+
+
+
+typedef OSErr ( * AECoerceDescProcPtr)(const AEDesc *fromDesc, DescType toType, long handlerRefcon, AEDesc *toDesc);
+typedef OSErr ( * AECoercePtrProcPtr)(DescType typeCode, const void *dataPtr, Size dataSize, DescType toType, long handlerRefcon, AEDesc *result);
+typedef AECoerceDescProcPtr AECoerceDescUPP;
+typedef AECoercePtrProcPtr AECoercePtrUPP;
+extern AECoerceDescUPP
+NewAECoerceDescUPP(AECoerceDescProcPtr userRoutine) ;
+extern AECoercePtrUPP
+NewAECoercePtrUPP(AECoercePtrProcPtr userRoutine) ;
+extern void
+DisposeAECoerceDescUPP(AECoerceDescUPP userUPP) ;
+extern void
+DisposeAECoercePtrUPP(AECoercePtrUPP userUPP) ;
+extern OSErr
+InvokeAECoerceDescUPP(
+ const AEDesc * fromDesc,
+ DescType toType,
+ long handlerRefcon,
+ AEDesc * toDesc,
+ AECoerceDescUPP userUPP) ;
+extern OSErr
+InvokeAECoercePtrUPP(
+ DescType typeCode,
+ const void * dataPtr,
+ Size dataSize,
+ DescType toType,
+ long handlerRefcon,
+ AEDesc * result,
+ AECoercePtrUPP userUPP) ;
+
+
+
+
+
+typedef AECoerceDescUPP AECoercionHandlerUPP;
+extern OSErr
+AEInstallCoercionHandler(
+ DescType fromType,
+ DescType toType,
+ AECoercionHandlerUPP handler,
+ long handlerRefcon,
+ Boolean fromTypeIsDesc,
+ Boolean isSysHandler) ;
+extern OSErr
+AERemoveCoercionHandler(
+ DescType fromType,
+ DescType toType,
+ AECoercionHandlerUPP handler,
+ Boolean isSysHandler) ;
+extern OSErr
+AEGetCoercionHandler(
+ DescType fromType,
+ DescType toType,
+ AECoercionHandlerUPP * handler,
+ long * handlerRefcon,
+ Boolean * fromTypeIsDesc,
+ Boolean isSysHandler) ;
+extern OSErr
+AECoercePtr(
+ DescType typeCode,
+ const void * dataPtr,
+ Size dataSize,
+ DescType toType,
+ AEDesc * result) ;
+extern OSErr
+AECoerceDesc(
+ const AEDesc * theAEDesc,
+ DescType toType,
+ AEDesc * result) ;
+extern void
+AEInitializeDesc(AEDesc * desc) ;
+
+
+
+
+ inline void AEInitializeDescInline(AEDesc* d) { d->descriptorType = typeNull; d->dataHandle = __null; };
+extern OSErr
+AECreateDesc(
+ DescType typeCode,
+ const void * dataPtr,
+ Size dataSize,
+ AEDesc * result) ;
+extern OSErr
+AEDisposeDesc(AEDesc * theAEDesc) ;
+extern OSErr
+AEDuplicateDesc(
+ const AEDesc * theAEDesc,
+ AEDesc * result) ;
+typedef void ( * AEDisposeExternalProcPtr)(const void *dataPtr, Size dataLength, long refcon);
+typedef AEDisposeExternalProcPtr AEDisposeExternalUPP;
+extern OSStatus
+AECreateDescFromExternalPtr(
+ OSType descriptorType,
+ const void * dataPtr,
+ Size dataLength,
+ AEDisposeExternalUPP disposeCallback,
+ long disposeRefcon,
+ AEDesc * theDesc) ;
+extern OSErr
+AECreateList(
+ const void * factoringPtr,
+ Size factoredSize,
+ Boolean isRecord,
+ AEDescList * resultList) ;
+extern OSErr
+AECountItems(
+ const AEDescList * theAEDescList,
+ long * theCount) ;
+extern OSErr
+AEPutPtr(
+ AEDescList * theAEDescList,
+ long index,
+ DescType typeCode,
+ const void * dataPtr,
+ Size dataSize) ;
+extern OSErr
+AEPutDesc(
+ AEDescList * theAEDescList,
+ long index,
+ const AEDesc * theAEDesc) ;
+extern OSErr
+AEGetNthPtr(
+ const AEDescList * theAEDescList,
+ long index,
+ DescType desiredType,
+ AEKeyword * theAEKeyword,
+ DescType * typeCode,
+ void * dataPtr,
+ Size maximumSize,
+ Size * actualSize) ;
+extern OSErr
+AEGetNthDesc(
+ const AEDescList * theAEDescList,
+ long index,
+ DescType desiredType,
+ AEKeyword * theAEKeyword,
+ AEDesc * result) ;
+extern OSErr
+AESizeOfNthItem(
+ const AEDescList * theAEDescList,
+ long index,
+ DescType * typeCode,
+ Size * dataSize) ;
+extern OSErr
+AEGetArray(
+ const AEDescList * theAEDescList,
+ AEArrayType arrayType,
+ AEArrayDataPointer arrayPtr,
+ Size maximumSize,
+ DescType * itemType,
+ Size * itemSize,
+ long * itemCount) ;
+extern OSErr
+AEPutArray(
+ AEDescList * theAEDescList,
+ AEArrayType arrayType,
+ const AEArrayData * arrayPtr,
+ DescType itemType,
+ Size itemSize,
+ long itemCount) ;
+extern OSErr
+AEDeleteItem(
+ AEDescList * theAEDescList,
+ long index) ;
+extern Boolean
+AECheckIsRecord(const AEDesc * theDesc) ;
+extern OSErr
+AECreateAppleEvent(
+ AEEventClass theAEEventClass,
+ AEEventID theAEEventID,
+ const AEAddressDesc * target,
+ AEReturnID returnID,
+ AETransactionID transactionID,
+ AppleEvent * result) ;
+extern OSErr
+AEPutParamPtr(
+ AppleEvent * theAppleEvent,
+ AEKeyword theAEKeyword,
+ DescType typeCode,
+ const void * dataPtr,
+ Size dataSize) ;
+extern OSErr
+AEPutParamDesc(
+ AppleEvent * theAppleEvent,
+ AEKeyword theAEKeyword,
+ const AEDesc * theAEDesc) ;
+extern OSErr
+AEGetParamPtr(
+ const AppleEvent * theAppleEvent,
+ AEKeyword theAEKeyword,
+ DescType desiredType,
+ DescType * typeCode,
+ void * dataPtr,
+ Size maximumSize,
+ Size * actualSize) ;
+extern OSErr
+AEGetParamDesc(
+ const AppleEvent * theAppleEvent,
+ AEKeyword theAEKeyword,
+ DescType desiredType,
+ AEDesc * result) ;
+extern OSErr
+AESizeOfParam(
+ const AppleEvent * theAppleEvent,
+ AEKeyword theAEKeyword,
+ DescType * typeCode,
+ Size * dataSize) ;
+extern OSErr
+AEDeleteParam(
+ AppleEvent * theAppleEvent,
+ AEKeyword theAEKeyword) ;
+extern OSErr
+AEGetAttributePtr(
+ const AppleEvent * theAppleEvent,
+ AEKeyword theAEKeyword,
+ DescType desiredType,
+ DescType * typeCode,
+ void * dataPtr,
+ Size maximumSize,
+ Size * actualSize) ;
+extern OSErr
+AEGetAttributeDesc(
+ const AppleEvent * theAppleEvent,
+ AEKeyword theAEKeyword,
+ DescType desiredType,
+ AEDesc * result) ;
+extern OSErr
+AESizeOfAttribute(
+ const AppleEvent * theAppleEvent,
+ AEKeyword theAEKeyword,
+ DescType * typeCode,
+ Size * dataSize) ;
+extern OSErr
+AEPutAttributePtr(
+ AppleEvent * theAppleEvent,
+ AEKeyword theAEKeyword,
+ DescType typeCode,
+ const void * dataPtr,
+ Size dataSize) ;
+extern OSErr
+AEPutAttributeDesc(
+ AppleEvent * theAppleEvent,
+ AEKeyword theAEKeyword,
+ const AEDesc * theAEDesc) ;
+extern Size
+AESizeOfFlattenedDesc(const AEDesc * theAEDesc) ;
+extern OSStatus
+AEFlattenDesc(
+ const AEDesc * theAEDesc,
+ Ptr buffer,
+ Size bufferSize,
+ Size * actualSize) ;
+extern OSStatus
+AEUnflattenDesc(
+ Ptr buffer,
+ AEDesc * result) ;
+extern OSErr
+AEGetDescData(
+ const AEDesc * theAEDesc,
+ void * dataPtr,
+ Size maximumSize) ;
+extern Size
+AEGetDescDataSize(const AEDesc * theAEDesc) ;
+extern OSErr
+AEReplaceDescData(
+ DescType typeCode,
+ const void * dataPtr,
+ Size dataSize,
+ AEDesc * theAEDesc) ;
+extern OSStatus
+AEGetDescDataRange(
+ const AEDesc * dataDesc,
+ void * buffer,
+ Size offset,
+ Size length) ;
+
+
+
+
+
+typedef OSErr ( * AEEventHandlerProcPtr)(const AppleEvent *theAppleEvent, AppleEvent *reply, long handlerRefcon);
+typedef AEEventHandlerProcPtr AEEventHandlerUPP;
+extern AEDisposeExternalUPP
+NewAEDisposeExternalUPP(AEDisposeExternalProcPtr userRoutine) ;
+extern AEEventHandlerUPP
+NewAEEventHandlerUPP(AEEventHandlerProcPtr userRoutine) ;
+extern void
+DisposeAEDisposeExternalUPP(AEDisposeExternalUPP userUPP) ;
+extern void
+DisposeAEEventHandlerUPP(AEEventHandlerUPP userUPP) ;
+extern void
+InvokeAEDisposeExternalUPP(
+ const void * dataPtr,
+ Size dataLength,
+ long refcon,
+ AEDisposeExternalUPP userUPP) ;
+extern OSErr
+InvokeAEEventHandlerUPP(
+ const AppleEvent * theAppleEvent,
+ AppleEvent * reply,
+ long handlerRefcon,
+ AEEventHandlerUPP userUPP) ;
+
+
+
+
+
+}
+
+
+
+extern "C" {
+
+
+enum {
+
+ keyDirectObject = '----',
+ keyErrorNumber = 'errn',
+ keyErrorString = 'errs',
+ keyProcessSerialNumber = 'psn ',
+ keyPreDispatch = 'phac',
+ keySelectProc = 'selh',
+
+ keyAERecorderCount = 'recr',
+
+ keyAEVersion = 'vers'
+};
+
+
+enum {
+ kCoreEventClass = 'aevt'
+};
+
+
+enum {
+ kAEOpenApplication = 'oapp',
+ kAEOpenDocuments = 'odoc',
+ kAEPrintDocuments = 'pdoc',
+ kAEQuitApplication = 'quit',
+ kAEAnswer = 'ansr',
+ kAEApplicationDied = 'obit',
+ kAEShowPreferences = 'pref'
+};
+
+
+enum {
+ kAEStartRecording = 'reca',
+ kAEStopRecording = 'recc',
+ kAENotifyStartRecording = 'rec1',
+ kAENotifyStopRecording = 'rec0',
+ kAENotifyRecording = 'recr'
+};
+typedef SInt8 AEEventSource;
+enum {
+ kAEUnknownSource = 0,
+ kAEDirectCall = 1,
+ kAESameProcess = 2,
+ kAELocalProcess = 3,
+ kAERemoteProcess = 4
+};
+extern OSErr
+AEInstallEventHandler(
+ AEEventClass theAEEventClass,
+ AEEventID theAEEventID,
+ AEEventHandlerUPP handler,
+ long handlerRefcon,
+ Boolean isSysHandler) ;
+extern OSErr
+AERemoveEventHandler(
+ AEEventClass theAEEventClass,
+ AEEventID theAEEventID,
+ AEEventHandlerUPP handler,
+ Boolean isSysHandler) ;
+extern OSErr
+AEGetEventHandler(
+ AEEventClass theAEEventClass,
+ AEEventID theAEEventID,
+ AEEventHandlerUPP * handler,
+ long * handlerRefcon,
+ Boolean isSysHandler) ;
+extern OSErr
+AEInstallSpecialHandler(
+ AEKeyword functionClass,
+ AEEventHandlerUPP handler,
+ Boolean isSysHandler) ;
+extern OSErr
+AERemoveSpecialHandler(
+ AEKeyword functionClass,
+ AEEventHandlerUPP handler,
+ Boolean isSysHandler) ;
+extern OSErr
+AEGetSpecialHandler(
+ AEKeyword functionClass,
+ AEEventHandlerUPP * handler,
+ Boolean isSysHandler) ;
+extern OSErr
+AEManagerInfo(
+ AEKeyword keyWord,
+ long * result) ;
+}
+
+
+
+extern "C" {
+extern OSErr
+CreateOffsetDescriptor(
+ long theOffset,
+ AEDesc * theDescriptor) ;
+extern OSErr
+CreateCompDescriptor(
+ DescType comparisonOperator,
+ AEDesc * operand1,
+ AEDesc * operand2,
+ Boolean disposeInputs,
+ AEDesc * theDescriptor) ;
+extern OSErr
+CreateLogicalDescriptor(
+ AEDescList * theLogicalTerms,
+ DescType theLogicOperator,
+ Boolean disposeInputs,
+ AEDesc * theDescriptor) ;
+extern OSErr
+CreateObjSpecifier(
+ DescType desiredClass,
+ AEDesc * theContainer,
+ DescType keyForm,
+ AEDesc * keyData,
+ Boolean disposeInputs,
+ AEDesc * objSpecifier) ;
+extern OSErr
+CreateRangeDescriptor(
+ AEDesc * rangeStart,
+ AEDesc * rangeStop,
+ Boolean disposeInputs,
+ AEDesc * theDescriptor) ;
+
+
+
+
+}
+
+
+
+extern "C" {
+
+
+
+enum {
+
+ kAEAND = 'AND ',
+ kAEOR = 'OR ',
+ kAENOT = 'NOT ',
+
+ kAEFirst = 'firs',
+ kAELast = 'last',
+ kAEMiddle = 'midd',
+ kAEAny = 'any ',
+ kAEAll = 'all ',
+
+ kAENext = 'next',
+ kAEPrevious = 'prev',
+
+ keyAECompOperator = 'relo',
+ keyAELogicalTerms = 'term',
+ keyAELogicalOperator = 'logc',
+ keyAEObject1 = 'obj1',
+ keyAEObject2 = 'obj2',
+
+ keyAEDesiredClass = 'want',
+ keyAEContainer = 'from',
+ keyAEKeyForm = 'form',
+ keyAEKeyData = 'seld'
+};
+
+enum {
+
+ keyAERangeStart = 'star',
+ keyAERangeStop = 'stop',
+
+ keyDisposeTokenProc = 'xtok',
+ keyAECompareProc = 'cmpr',
+ keyAECountProc = 'cont',
+ keyAEMarkTokenProc = 'mkid',
+ keyAEMarkProc = 'mark',
+ keyAEAdjustMarksProc = 'adjm',
+ keyAEGetErrDescProc = 'indc'
+};
+
+
+enum {
+
+ formAbsolutePosition = 'indx',
+ formRelativePosition = 'rele',
+ formTest = 'test',
+ formRange = 'rang',
+ formPropertyID = 'prop',
+ formName = 'name',
+
+ typeObjectSpecifier = 'obj ',
+ typeObjectBeingExamined = 'exmn',
+ typeCurrentContainer = 'ccnt',
+ typeToken = 'toke',
+ typeRelativeDescriptor = 'rel ',
+ typeAbsoluteOrdinal = 'abso',
+ typeIndexDescriptor = 'inde',
+ typeRangeDescriptor = 'rang',
+ typeLogicalDescriptor = 'logi',
+ typeCompDescriptor = 'cmpd',
+ typeOSLTokenList = 'ostl'
+};
+
+
+enum {
+ kAEIDoMinimum = 0x0000,
+ kAEIDoWhose = 0x0001,
+ kAEIDoMarking = 0x0004,
+ kAEPassSubDescs = 0x0008,
+ kAEResolveNestedLists = 0x0010,
+ kAEHandleSimpleRanges = 0x0020,
+ kAEUseRelativeIterators = 0x0040
+};
+
+
+enum {
+ typeWhoseDescriptor = 'whos',
+ formWhose = 'whos',
+ typeWhoseRange = 'wrng',
+ keyAEWhoseRangeStart = 'wstr',
+ keyAEWhoseRangeStop = 'wstp',
+ keyAEIndex = 'kidx',
+ keyAETest = 'ktst'
+};
+
+
+
+
+
+
+
+struct ccntTokenRecord {
+ DescType tokenClass;
+ AEDesc token;
+};
+typedef struct ccntTokenRecord ccntTokenRecord;
+typedef ccntTokenRecord * ccntTokenRecPtr;
+typedef ccntTokenRecPtr * ccntTokenRecHandle;
+
+
+
+
+
+
+typedef OSErr ( * OSLAccessorProcPtr)(DescType desiredClass, const AEDesc *container, DescType containerClass, DescType form, const AEDesc *selectionData, AEDesc *value, long accessorRefcon);
+typedef OSErr ( * OSLCompareProcPtr)(DescType oper, const AEDesc *obj1, const AEDesc *obj2, Boolean *result);
+typedef OSErr ( * OSLCountProcPtr)(DescType desiredType, DescType containerClass, const AEDesc *container, long *result);
+typedef OSErr ( * OSLDisposeTokenProcPtr)(AEDesc * unneededToken);
+typedef OSErr ( * OSLGetMarkTokenProcPtr)(const AEDesc *dContainerToken, DescType containerClass, AEDesc *result);
+typedef OSErr ( * OSLGetErrDescProcPtr)(AEDesc ** appDescPtr);
+typedef OSErr ( * OSLMarkProcPtr)(const AEDesc *dToken, const AEDesc *markToken, long index);
+typedef OSErr ( * OSLAdjustMarksProcPtr)(long newStart, long newStop, const AEDesc *markToken);
+typedef OSLAccessorProcPtr OSLAccessorUPP;
+typedef OSLCompareProcPtr OSLCompareUPP;
+typedef OSLCountProcPtr OSLCountUPP;
+typedef OSLDisposeTokenProcPtr OSLDisposeTokenUPP;
+typedef OSLGetMarkTokenProcPtr OSLGetMarkTokenUPP;
+typedef OSLGetErrDescProcPtr OSLGetErrDescUPP;
+typedef OSLMarkProcPtr OSLMarkUPP;
+typedef OSLAdjustMarksProcPtr OSLAdjustMarksUPP;
+extern OSLAccessorUPP
+NewOSLAccessorUPP(OSLAccessorProcPtr userRoutine) ;
+extern OSLCompareUPP
+NewOSLCompareUPP(OSLCompareProcPtr userRoutine) ;
+extern OSLCountUPP
+NewOSLCountUPP(OSLCountProcPtr userRoutine) ;
+extern OSLDisposeTokenUPP
+NewOSLDisposeTokenUPP(OSLDisposeTokenProcPtr userRoutine) ;
+extern OSLGetMarkTokenUPP
+NewOSLGetMarkTokenUPP(OSLGetMarkTokenProcPtr userRoutine) ;
+extern OSLGetErrDescUPP
+NewOSLGetErrDescUPP(OSLGetErrDescProcPtr userRoutine) ;
+extern OSLMarkUPP
+NewOSLMarkUPP(OSLMarkProcPtr userRoutine) ;
+extern OSLAdjustMarksUPP
+NewOSLAdjustMarksUPP(OSLAdjustMarksProcPtr userRoutine) ;
+extern void
+DisposeOSLAccessorUPP(OSLAccessorUPP userUPP) ;
+extern void
+DisposeOSLCompareUPP(OSLCompareUPP userUPP) ;
+extern void
+DisposeOSLCountUPP(OSLCountUPP userUPP) ;
+extern void
+DisposeOSLDisposeTokenUPP(OSLDisposeTokenUPP userUPP) ;
+extern void
+DisposeOSLGetMarkTokenUPP(OSLGetMarkTokenUPP userUPP) ;
+extern void
+DisposeOSLGetErrDescUPP(OSLGetErrDescUPP userUPP) ;
+extern void
+DisposeOSLMarkUPP(OSLMarkUPP userUPP) ;
+extern void
+DisposeOSLAdjustMarksUPP(OSLAdjustMarksUPP userUPP) ;
+extern OSErr
+InvokeOSLAccessorUPP(
+ DescType desiredClass,
+ const AEDesc * container,
+ DescType containerClass,
+ DescType form,
+ const AEDesc * selectionData,
+ AEDesc * value,
+ long accessorRefcon,
+ OSLAccessorUPP userUPP) ;
+extern OSErr
+InvokeOSLCompareUPP(
+ DescType oper,
+ const AEDesc * obj1,
+ const AEDesc * obj2,
+ Boolean * result,
+ OSLCompareUPP userUPP) ;
+extern OSErr
+InvokeOSLCountUPP(
+ DescType desiredType,
+ DescType containerClass,
+ const AEDesc * container,
+ long * result,
+ OSLCountUPP userUPP) ;
+extern OSErr
+InvokeOSLDisposeTokenUPP(
+ AEDesc * unneededToken,
+ OSLDisposeTokenUPP userUPP) ;
+extern OSErr
+InvokeOSLGetMarkTokenUPP(
+ const AEDesc * dContainerToken,
+ DescType containerClass,
+ AEDesc * result,
+ OSLGetMarkTokenUPP userUPP) ;
+extern OSErr
+InvokeOSLGetErrDescUPP(
+ AEDesc ** appDescPtr,
+ OSLGetErrDescUPP userUPP) ;
+extern OSErr
+InvokeOSLMarkUPP(
+ const AEDesc * dToken,
+ const AEDesc * markToken,
+ long index,
+ OSLMarkUPP userUPP) ;
+extern OSErr
+InvokeOSLAdjustMarksUPP(
+ long newStart,
+ long newStop,
+ const AEDesc * markToken,
+ OSLAdjustMarksUPP userUPP) ;
+extern OSErr
+AEObjectInit(void) ;
+extern OSErr
+AESetObjectCallbacks(
+ OSLCompareUPP myCompareProc,
+ OSLCountUPP myCountProc,
+ OSLDisposeTokenUPP myDisposeTokenProc,
+ OSLGetMarkTokenUPP myGetMarkTokenProc,
+ OSLMarkUPP myMarkProc,
+ OSLAdjustMarksUPP myAdjustMarksProc,
+ OSLGetErrDescUPP myGetErrDescProcPtr) ;
+extern OSErr
+AEResolve(
+ const AEDesc * objectSpecifier,
+ short callbackFlags,
+ AEDesc * theToken) ;
+extern OSErr
+AEInstallObjectAccessor(
+ DescType desiredClass,
+ DescType containerType,
+ OSLAccessorUPP theAccessor,
+ long accessorRefcon,
+ Boolean isSysHandler) ;
+extern OSErr
+AERemoveObjectAccessor(
+ DescType desiredClass,
+ DescType containerType,
+ OSLAccessorUPP theAccessor,
+ Boolean isSysHandler) ;
+extern OSErr
+AEGetObjectAccessor(
+ DescType desiredClass,
+ DescType containerType,
+ OSLAccessorUPP * accessor,
+ long * accessorRefcon,
+ Boolean isSysHandler) ;
+extern OSErr
+AEDisposeToken(AEDesc * theToken) ;
+extern OSErr
+AECallObjectAccessor(
+ DescType desiredClass,
+ const AEDesc * containerToken,
+ DescType containerClass,
+ DescType keyForm,
+ const AEDesc * keyData,
+ AEDesc * token) ;
+
+
+
+
+
+
+}
+
+
+
+
+enum {
+ cAEList = 'list',
+ cApplication = 'capp',
+ cArc = 'carc',
+ cBoolean = 'bool',
+ cCell = 'ccel',
+ cChar = 'cha ',
+ cColorTable = 'clrt',
+ cColumn = 'ccol',
+ cDocument = 'docu',
+ cDrawingArea = 'cdrw',
+ cEnumeration = 'enum',
+ cFile = 'file',
+ cFixed = 'fixd',
+ cFixedPoint = 'fpnt',
+ cFixedRectangle = 'frct',
+ cGraphicLine = 'glin',
+ cGraphicObject = 'cgob',
+ cGraphicShape = 'cgsh',
+ cGraphicText = 'cgtx',
+ cGroupedGraphic = 'cpic'
+};
+
+enum {
+ cInsertionLoc = 'insl',
+ cInsertionPoint = 'cins',
+ cIntlText = 'itxt',
+ cIntlWritingCode = 'intl',
+ cItem = 'citm',
+ cLine = 'clin',
+ cLongDateTime = 'ldt ',
+ cLongFixed = 'lfxd',
+ cLongFixedPoint = 'lfpt',
+ cLongFixedRectangle = 'lfrc',
+ cLongInteger = 'long',
+ cLongPoint = 'lpnt',
+ cLongRectangle = 'lrct',
+ cMachineLoc = 'mLoc',
+ cMenu = 'cmnu',
+ cMenuItem = 'cmen',
+ cObject = 'cobj',
+ cObjectSpecifier = 'obj ',
+ cOpenableObject = 'coob',
+ cOval = 'covl'
+};
+
+enum {
+ cParagraph = 'cpar',
+ cPICT = 'PICT',
+ cPixel = 'cpxl',
+ cPixelMap = 'cpix',
+ cPolygon = 'cpgn',
+ cProperty = 'prop',
+ cQDPoint = 'QDpt',
+ cQDRectangle = 'qdrt',
+ cRectangle = 'crec',
+ cRGBColor = 'cRGB',
+ cRotation = 'trot',
+ cRoundedRectangle = 'crrc',
+ cRow = 'crow',
+ cSelection = 'csel',
+ cShortInteger = 'shor',
+ cTable = 'ctbl',
+ cText = 'ctxt',
+ cTextFlow = 'cflo',
+ cTextStyles = 'tsty',
+ cType = 'type'
+};
+
+enum {
+ cVersion = 'vers',
+ cWindow = 'cwin',
+ cWord = 'cwor',
+ enumArrows = 'arro',
+ enumJustification = 'just',
+ enumKeyForm = 'kfrm',
+ enumPosition = 'posi',
+ enumProtection = 'prtn',
+ enumQuality = 'qual',
+ enumSaveOptions = 'savo',
+ enumStyle = 'styl',
+ enumTransferMode = 'tran',
+ formUniqueID = 'ID ',
+ kAEAbout = 'abou',
+ kAEAfter = 'afte',
+ kAEAliasSelection = 'sali',
+ kAEAllCaps = 'alcp',
+ kAEArrowAtEnd = 'aren',
+ kAEArrowAtStart = 'arst',
+ kAEArrowBothEnds = 'arbo'
+};
+
+enum {
+ kAEAsk = 'ask ',
+ kAEBefore = 'befo',
+ kAEBeginning = 'bgng',
+ kAEBeginsWith = 'bgwt',
+ kAEBeginTransaction = 'begi',
+ kAEBold = 'bold',
+ kAECaseSensEquals = 'cseq',
+ kAECentered = 'cent',
+ kAEChangeView = 'view',
+ kAEClone = 'clon',
+ kAEClose = 'clos',
+ kAECondensed = 'cond',
+ kAEContains = 'cont',
+ kAECopy = 'copy',
+ kAECoreSuite = 'core',
+ kAECountElements = 'cnte',
+ kAECreateElement = 'crel',
+ kAECreatePublisher = 'cpub',
+ kAECut = 'cut ',
+ kAEDelete = 'delo'
+};
+
+enum {
+ kAEDoObjectsExist = 'doex',
+ kAEDoScript = 'dosc',
+ kAEDrag = 'drag',
+ kAEDuplicateSelection = 'sdup',
+ kAEEditGraphic = 'edit',
+ kAEEmptyTrash = 'empt',
+ kAEEnd = 'end ',
+ kAEEndsWith = 'ends',
+ kAEEndTransaction = 'endt',
+ kAEEquals = '= ',
+ kAEExpanded = 'pexp',
+ kAEFast = 'fast',
+ kAEFinderEvents = 'FNDR',
+ kAEFormulaProtect = 'fpro',
+ kAEFullyJustified = 'full',
+ kAEGetClassInfo = 'qobj',
+ kAEGetData = 'getd',
+ kAEGetDataSize = 'dsiz',
+ kAEGetEventInfo = 'gtei',
+ kAEGetInfoSelection = 'sinf'
+};
+
+enum {
+ kAEGetPrivilegeSelection = 'sprv',
+ kAEGetSuiteInfo = 'gtsi',
+ kAEGreaterThan = '> ',
+ kAEGreaterThanEquals = '>= ',
+ kAEGrow = 'grow',
+ kAEHidden = 'hidn',
+ kAEHiQuality = 'hiqu',
+ kAEImageGraphic = 'imgr',
+ kAEIsUniform = 'isun',
+ kAEItalic = 'ital',
+ kAELeftJustified = 'left',
+ kAELessThan = '< ',
+ kAELessThanEquals = '<= ',
+ kAELowercase = 'lowc',
+ kAEMakeObjectsVisible = 'mvis',
+ kAEMiscStandards = 'misc',
+ kAEModifiable = 'modf',
+ kAEMove = 'move',
+ kAENo = 'no ',
+ kAENoArrow = 'arno'
+};
+
+enum {
+ kAENonmodifiable = 'nmod',
+ kAEOpen = 'odoc',
+ kAEOpenSelection = 'sope',
+ kAEOutline = 'outl',
+ kAEPageSetup = 'pgsu',
+ kAEPaste = 'past',
+ kAEPlain = 'plan',
+ kAEPrint = 'pdoc',
+ kAEPrintSelection = 'spri',
+ kAEPrintWindow = 'pwin',
+ kAEPutAwaySelection = 'sput',
+ kAEQDAddOver = 'addo',
+ kAEQDAddPin = 'addp',
+ kAEQDAdMax = 'admx',
+ kAEQDAdMin = 'admn',
+ kAEQDBic = 'bic ',
+ kAEQDBlend = 'blnd',
+ kAEQDCopy = 'cpy ',
+ kAEQDNotBic = 'nbic',
+ kAEQDNotCopy = 'ncpy'
+};
+
+enum {
+ kAEQDNotOr = 'ntor',
+ kAEQDNotXor = 'nxor',
+ kAEQDOr = 'or ',
+ kAEQDSubOver = 'subo',
+ kAEQDSubPin = 'subp',
+ kAEQDSupplementalSuite = 'qdsp',
+ kAEQDXor = 'xor ',
+ kAEQuickdrawSuite = 'qdrw',
+ kAEQuitAll = 'quia',
+ kAERedo = 'redo',
+ kAERegular = 'regl',
+ kAEReopenApplication = 'rapp',
+ kAEReplace = 'rplc',
+ kAERequiredSuite = 'reqd',
+ kAERestart = 'rest',
+ kAERevealSelection = 'srev',
+ kAERevert = 'rvrt',
+ kAERightJustified = 'rght',
+ kAESave = 'save',
+ kAESelect = 'slct',
+ kAESetData = 'setd'
+};
+
+enum {
+ kAESetPosition = 'posn',
+ kAEShadow = 'shad',
+ kAEShowClipboard = 'shcl',
+ kAEShutDown = 'shut',
+ kAESleep = 'slep',
+ kAESmallCaps = 'smcp',
+ kAESpecialClassProperties = 'c@#!',
+ kAEStrikethrough = 'strk',
+ kAESubscript = 'sbsc',
+ kAESuperscript = 'spsc',
+ kAETableSuite = 'tbls',
+ kAETextSuite = 'TEXT',
+ kAETransactionTerminated = 'ttrm',
+ kAEUnderline = 'undl',
+ kAEUndo = 'undo',
+ kAEWholeWordEquals = 'wweq',
+ kAEYes = 'yes ',
+ kAEZoom = 'zoom'
+};
+
+
+enum {
+ kAELogOut = 'logo',
+ kAEReallyLogOut = 'rlgo',
+ kAEShowRestartDialog = 'rrst',
+ kAEShowShutdownDialog = 'rsdn'
+};
+
+
+enum {
+ kAEMouseClass = 'mous',
+ kAEDown = 'down',
+ kAEUp = 'up ',
+ kAEMoved = 'move',
+ kAEStoppedMoving = 'stop',
+ kAEWindowClass = 'wind',
+ kAEUpdate = 'updt',
+ kAEActivate = 'actv',
+ kAEDeactivate = 'dact',
+ kAECommandClass = 'cmnd',
+ kAEKeyClass = 'keyc',
+ kAERawKey = 'rkey',
+ kAEVirtualKey = 'keyc',
+ kAENavigationKey = 'nave',
+ kAEAutoDown = 'auto',
+ kAEApplicationClass = 'appl',
+ kAESuspend = 'susp',
+ kAEResume = 'rsme',
+ kAEDiskEvent = 'disk',
+ kAENullEvent = 'null',
+ kAEWakeUpEvent = 'wake',
+ kAEScrapEvent = 'scrp',
+ kAEHighLevel = 'high'
+};
+
+enum {
+ keyAEAngle = 'kang',
+ keyAEArcAngle = 'parc'
+};
+
+enum {
+ keyAEBaseAddr = 'badd',
+ keyAEBestType = 'pbst',
+ keyAEBgndColor = 'kbcl',
+ keyAEBgndPattern = 'kbpt',
+ keyAEBounds = 'pbnd',
+ keyAECellList = 'kclt',
+ keyAEClassID = 'clID',
+ keyAEColor = 'colr',
+ keyAEColorTable = 'cltb',
+ keyAECurveHeight = 'kchd',
+ keyAECurveWidth = 'kcwd',
+ keyAEDashStyle = 'pdst',
+ keyAEData = 'data',
+ keyAEDefaultType = 'deft',
+ keyAEDefinitionRect = 'pdrt',
+ keyAEDescType = 'dstp',
+ keyAEDestination = 'dest',
+ keyAEDoAntiAlias = 'anta',
+ keyAEDoDithered = 'gdit',
+ keyAEDoRotate = 'kdrt'
+};
+
+enum {
+ keyAEDoScale = 'ksca',
+ keyAEDoTranslate = 'ktra',
+ keyAEEditionFileLoc = 'eloc',
+ keyAEElements = 'elms',
+ keyAEEndPoint = 'pend',
+ keyAEEventClass = 'evcl',
+ keyAEEventID = 'evti',
+ keyAEFile = 'kfil',
+ keyAEFileType = 'fltp',
+ keyAEFillColor = 'flcl',
+ keyAEFillPattern = 'flpt',
+ keyAEFlipHorizontal = 'kfho',
+ keyAEFlipVertical = 'kfvt',
+ keyAEFont = 'font',
+ keyAEFormula = 'pfor',
+ keyAEGraphicObjects = 'gobs',
+ keyAEID = 'ID ',
+ keyAEImageQuality = 'gqua',
+ keyAEInsertHere = 'insh',
+ keyAEKeyForms = 'keyf'
+};
+
+enum {
+ keyAEKeyword = 'kywd',
+ keyAELevel = 'levl',
+ keyAELineArrow = 'arro',
+ keyAEName = 'pnam',
+ keyAENewElementLoc = 'pnel',
+ keyAEObject = 'kobj',
+ keyAEObjectClass = 'kocl',
+ keyAEOffStyles = 'ofst',
+ keyAEOnStyles = 'onst',
+ keyAEParameters = 'prms',
+ keyAEParamFlags = 'pmfg',
+ keyAEPenColor = 'ppcl',
+ keyAEPenPattern = 'pppa',
+ keyAEPenWidth = 'ppwd',
+ keyAEPixelDepth = 'pdpt',
+ keyAEPixMapMinus = 'kpmm',
+ keyAEPMTable = 'kpmt',
+ keyAEPointList = 'ptlt',
+ keyAEPointSize = 'ptsz',
+ keyAEPosition = 'kpos'
+};
+
+enum {
+ keyAEPropData = 'prdt',
+ keyAEProperties = 'qpro',
+ keyAEProperty = 'kprp',
+ keyAEPropFlags = 'prfg',
+ keyAEPropID = 'prop',
+ keyAEProtection = 'ppro',
+ keyAERenderAs = 'kren',
+ keyAERequestedType = 'rtyp',
+ keyAEResult = '----',
+ keyAEResultInfo = 'rsin',
+ keyAERotation = 'prot',
+ keyAERotPoint = 'krtp',
+ keyAERowList = 'krls',
+ keyAESaveOptions = 'savo',
+ keyAEScale = 'pscl',
+ keyAEScriptTag = 'psct',
+ keyAEShowWhere = 'show',
+ keyAEStartAngle = 'pang',
+ keyAEStartPoint = 'pstp',
+ keyAEStyles = 'ksty'
+};
+
+enum {
+ keyAESuiteID = 'suit',
+ keyAEText = 'ktxt',
+ keyAETextColor = 'ptxc',
+ keyAETextFont = 'ptxf',
+ keyAETextPointSize = 'ptps',
+ keyAETextStyles = 'txst',
+ keyAETextLineHeight = 'ktlh',
+ keyAETextLineAscent = 'ktas',
+ keyAETheText = 'thtx',
+ keyAETransferMode = 'pptm',
+ keyAETranslation = 'ptrs',
+ keyAETryAsStructGraf = 'toog',
+ keyAEUniformStyles = 'ustl',
+ keyAEUpdateOn = 'pupd',
+ keyAEUserTerm = 'utrm',
+ keyAEWindow = 'wndw',
+ keyAEWritingCode = 'wrcd'
+};
+
+enum {
+ keyMiscellaneous = 'fmsc',
+ keySelection = 'fsel',
+ keyWindow = 'kwnd',
+
+ keyWhen = 'when',
+ keyWhere = 'wher',
+ keyModifiers = 'mods',
+ keyKey = 'key ',
+ keyKeyCode = 'code',
+ keyKeyboard = 'keyb',
+ keyDriveNumber = 'drv#',
+ keyErrorCode = 'err#',
+ keyHighLevelClass = 'hcls',
+ keyHighLevelID = 'hid '
+};
+
+enum {
+ pArcAngle = 'parc',
+ pBackgroundColor = 'pbcl',
+ pBackgroundPattern = 'pbpt',
+ pBestType = 'pbst',
+ pBounds = 'pbnd',
+ pClass = 'pcls',
+ pClipboard = 'pcli',
+ pColor = 'colr',
+ pColorTable = 'cltb',
+ pContents = 'pcnt',
+ pCornerCurveHeight = 'pchd',
+ pCornerCurveWidth = 'pcwd',
+ pDashStyle = 'pdst',
+ pDefaultType = 'deft',
+ pDefinitionRect = 'pdrt',
+ pEnabled = 'enbl',
+ pEndPoint = 'pend',
+ pFillColor = 'flcl',
+ pFillPattern = 'flpt',
+ pFont = 'font'
+};
+
+enum {
+ pFormula = 'pfor',
+ pGraphicObjects = 'gobs',
+ pHasCloseBox = 'hclb',
+ pHasTitleBar = 'ptit',
+ pID = 'ID ',
+ pIndex = 'pidx',
+ pInsertionLoc = 'pins',
+ pIsFloating = 'isfl',
+ pIsFrontProcess = 'pisf',
+ pIsModal = 'pmod',
+ pIsModified = 'imod',
+ pIsResizable = 'prsz',
+ pIsStationeryPad = 'pspd',
+ pIsZoomable = 'iszm',
+ pIsZoomed = 'pzum',
+ pItemNumber = 'itmn',
+ pJustification = 'pjst',
+ pLineArrow = 'arro',
+ pMenuID = 'mnid',
+ pName = 'pnam'
+};
+
+enum {
+ pNewElementLoc = 'pnel',
+ pPenColor = 'ppcl',
+ pPenPattern = 'pppa',
+ pPenWidth = 'ppwd',
+ pPixelDepth = 'pdpt',
+ pPointList = 'ptlt',
+ pPointSize = 'ptsz',
+ pProtection = 'ppro',
+ pRotation = 'prot',
+ pScale = 'pscl',
+ pScript = 'scpt',
+ pScriptTag = 'psct',
+ pSelected = 'selc',
+ pSelection = 'sele',
+ pStartAngle = 'pang',
+ pStartPoint = 'pstp',
+ pTextColor = 'ptxc',
+ pTextFont = 'ptxf',
+ pTextItemDelimiters = 'txdl',
+ pTextPointSize = 'ptps'
+};
+
+enum {
+ pTextStyles = 'txst',
+ pTransferMode = 'pptm',
+ pTranslation = 'ptrs',
+ pUniformStyles = 'ustl',
+ pUpdateOn = 'pupd',
+ pUserSelection = 'pusl',
+ pVersion = 'vers',
+ pVisible = 'pvis'
+};
+
+enum {
+ typeAEText = 'tTXT',
+ typeArc = 'carc',
+ typeBest = 'best',
+ typeCell = 'ccel',
+ typeClassInfo = 'gcli',
+ typeColorTable = 'clrt',
+ typeColumn = 'ccol',
+ typeDashStyle = 'tdas',
+ typeData = 'tdta',
+ typeDrawingArea = 'cdrw',
+ typeElemInfo = 'elin',
+ typeEnumeration = 'enum',
+ typeEPS = 'EPS ',
+ typeEventInfo = 'evin'
+};
+
+enum {
+ typeFinderWindow = 'fwin',
+ typeFixedPoint = 'fpnt',
+ typeFixedRectangle = 'frct',
+ typeGraphicLine = 'glin',
+ typeGraphicText = 'cgtx',
+ typeGroupedGraphic = 'cpic',
+ typeInsertionLoc = 'insl',
+ typeIntlText = 'itxt',
+ typeIntlWritingCode = 'intl',
+ typeLongDateTime = 'ldt ',
+ typeISO8601DateTime = 'isot',
+ typeLongFixed = 'lfxd',
+ typeLongFixedPoint = 'lfpt',
+ typeLongFixedRectangle = 'lfrc',
+ typeLongPoint = 'lpnt',
+ typeLongRectangle = 'lrct',
+ typeMachineLoc = 'mLoc',
+ typeOval = 'covl',
+ typeParamInfo = 'pmin',
+ typePict = 'PICT'
+};
+
+enum {
+ typePixelMap = 'cpix',
+ typePixMapMinus = 'tpmm',
+ typePolygon = 'cpgn',
+ typePropInfo = 'pinf',
+ typePtr = 'ptr ',
+ typeQDPoint = 'QDpt',
+ typeQDRegion = 'Qrgn',
+ typeRectangle = 'crec',
+ typeRGB16 = 'tr16',
+ typeRGB96 = 'tr96',
+ typeRGBColor = 'cRGB',
+ typeRotation = 'trot',
+ typeRoundedRectangle = 'crrc',
+ typeRow = 'crow',
+ typeScrapStyles = 'styl',
+ typeScript = 'scpt',
+ typeStyledText = 'STXT',
+ typeSuiteInfo = 'suin',
+ typeTable = 'ctbl',
+ typeTextStyles = 'tsty'
+};
+
+enum {
+ typeTIFF = 'TIFF',
+ typeVersion = 'vers'
+};
+
+enum {
+ kAEMenuClass = 'menu',
+ kAEMenuSelect = 'mhit',
+ kAEMouseDown = 'mdwn',
+ kAEMouseDownInBack = 'mdbk',
+ kAEKeyDown = 'kdwn',
+ kAEResized = 'rsiz',
+ kAEPromise = 'prom'
+};
+
+enum {
+ keyMenuID = 'mid ',
+ keyMenuItem = 'mitm',
+ keyCloseAllWindows = 'caw ',
+ keyOriginalBounds = 'obnd',
+ keyNewBounds = 'nbnd',
+ keyLocalWhere = 'lwhr'
+};
+
+enum {
+ typeHIMenu = 'mobj',
+ typeHIWindow = 'wobj'
+};
+
+enum {
+ kBySmallIcon = 0,
+ kByIconView = 1,
+ kByNameView = 2,
+ kByDateView = 3,
+ kBySizeView = 4,
+ kByKindView = 5,
+ kByCommentView = 6,
+ kByLabelView = 7,
+ kByVersionView = 8
+};
+
+enum {
+ kAEInfo = 11,
+ kAEMain = 0,
+ kAESharing = 13
+};
+
+enum {
+ kAEZoomIn = 7,
+ kAEZoomOut = 8
+};
+
+enum {
+ kTextServiceClass = 'tsvc',
+ kUpdateActiveInputArea = 'updt',
+ kShowHideInputWindow = 'shiw',
+ kPos2Offset = 'p2st',
+ kOffset2Pos = 'st2p',
+ kUnicodeNotFromInputMethod = 'unim',
+ kGetSelectedText = 'gtxt',
+ keyAETSMDocumentRefcon = 'refc',
+ keyAEServerInstance = 'srvi',
+ keyAETheData = 'kdat',
+ keyAEFixLength = 'fixl',
+ keyAEUpdateRange = 'udng',
+ keyAECurrentPoint = 'cpos',
+ keyAEBufferSize = 'buff',
+ keyAEMoveView = 'mvvw',
+ keyAENextBody = 'nxbd',
+ keyAETSMScriptTag = 'sclg',
+ keyAETSMTextFont = 'ktxf',
+ keyAETSMTextFMFont = 'ktxm',
+ keyAETSMTextPointSize = 'ktps',
+ keyAETSMEventRecord = 'tevt',
+ keyAETSMEventRef = 'tevr',
+ keyAETextServiceEncoding = 'tsen',
+ keyAETextServiceMacEncoding = 'tmen',
+ keyAETSMGlyphInfoArray = 'tgia',
+ typeTextRange = 'txrn',
+ typeComponentInstance = 'cmpi',
+ typeOffsetArray = 'ofay',
+ typeTextRangeArray = 'tray',
+ typeLowLevelEventRecord = 'evtr',
+ typeGlyphInfoArray = 'glia',
+ typeEventRef = 'evrf',
+ typeText = typeChar
+};
+
+
+
+enum {
+ kTSMOutsideOfBody = 1,
+ kTSMInsideOfBody = 2,
+ kTSMInsideOfActiveInputArea = 3
+};
+
+enum {
+ kNextBody = 1,
+ kPreviousBody = 2
+};
+
+struct TextRange {
+ long fStart;
+ long fEnd;
+ short fHiliteStyle;
+};
+typedef struct TextRange TextRange;
+typedef TextRange * TextRangePtr;
+typedef TextRangePtr * TextRangeHandle;
+struct TextRangeArray {
+ short fNumOfRanges;
+ TextRange fRange[1];
+};
+typedef struct TextRangeArray TextRangeArray;
+typedef TextRangeArray * TextRangeArrayPtr;
+typedef TextRangeArrayPtr * TextRangeArrayHandle;
+struct OffsetArray {
+ short fNumOfOffsets;
+ long fOffset[1];
+};
+typedef struct OffsetArray OffsetArray;
+typedef OffsetArray * OffsetArrayPtr;
+typedef OffsetArrayPtr * OffsetArrayHandle;
+struct WritingCode {
+ ScriptCode theScriptCode;
+ LangCode theLangCode;
+};
+typedef struct WritingCode WritingCode;
+struct IntlText {
+ ScriptCode theScriptCode;
+ LangCode theLangCode;
+ char theText[1];
+};
+typedef struct IntlText IntlText;
+
+
+enum {
+ kCaretPosition = 1,
+ kRawText = 2,
+ kSelectedRawText = 3,
+ kConvertedText = 4,
+ kSelectedConvertedText = 5,
+ kBlockFillText = 6,
+ kOutlineText = 7,
+ kSelectedText = 8
+};
+
+enum {
+ keyAEHiliteRange = 'hrng',
+ keyAEPinRange = 'pnrg',
+ keyAEClauseOffsets = 'clau',
+ keyAEOffset = 'ofst',
+ keyAEPoint = 'gpos',
+ keyAELeftSide = 'klef',
+ keyAERegionClass = 'rgnc',
+ keyAEDragging = 'bool'
+};
+enum {
+
+ typeUnicodeText = 'utxt',
+ typeStyledUnicodeText = 'sutx',
+ typeUTF8Text = 'utf8',
+ typeEncodedString = 'encs',
+ typeCString = 'cstr',
+ typePString = 'pstr'
+};
+
+enum {
+
+ typeMeters = 'metr',
+ typeInches = 'inch',
+ typeFeet = 'feet',
+ typeYards = 'yard',
+ typeMiles = 'mile',
+ typeKilometers = 'kmtr',
+ typeCentimeters = 'cmtr',
+ typeSquareMeters = 'sqrm',
+ typeSquareFeet = 'sqft',
+ typeSquareYards = 'sqyd',
+ typeSquareMiles = 'sqmi',
+ typeSquareKilometers = 'sqkm',
+ typeLiters = 'litr',
+ typeQuarts = 'qrts',
+ typeGallons = 'galn',
+ typeCubicMeters = 'cmet',
+ typeCubicFeet = 'cfet',
+ typeCubicInches = 'cuin',
+ typeCubicCentimeter = 'ccmt',
+ typeCubicYards = 'cyrd',
+ typeKilograms = 'kgrm',
+ typeGrams = 'gram',
+ typeOunces = 'ozs ',
+ typePounds = 'lbs ',
+ typeDegreesC = 'degc',
+ typeDegreesF = 'degf',
+ typeDegreesK = 'degk'
+};
+
+enum {
+
+ kFAServerApp = 'ssrv',
+ kDoFolderActionEvent = 'fola',
+ kFolderActionCode = 'actn',
+ kFolderOpenedEvent = 'fopn',
+ kFolderClosedEvent = 'fclo',
+ kFolderWindowMovedEvent = 'fsiz',
+ kFolderItemsAddedEvent = 'fget',
+ kFolderItemsRemovedEvent = 'flos',
+ kItemList = 'flst',
+ kNewSizeParameter = 'fnsz',
+ kFASuiteCode = 'faco',
+ kFAAttachCommand = 'atfa',
+ kFARemoveCommand = 'rmfa',
+ kFAEditCommand = 'edfa',
+ kFAFileParam = 'faal',
+ kFAIndexParam = 'indx'
+};
+
+
+enum {
+
+ kAEInternetSuite = 'gurl',
+ kAEISWebStarSuite = 'WWW½'
+};
+
+enum {
+
+ kAEISGetURL = 'gurl',
+ KAEISHandleCGI = 'sdoc'
+};
+
+enum {
+
+ cURL = 'url ',
+ cInternetAddress = 'IPAD',
+ cHTML = 'html',
+ cFTPItem = 'ftp '
+};
+
+enum {
+
+ kAEISHTTPSearchArgs = 'kfor',
+ kAEISPostArgs = 'post',
+ kAEISMethod = 'meth',
+ kAEISClientAddress = 'addr',
+ kAEISUserName = 'user',
+ kAEISPassword = 'pass',
+ kAEISFromUser = 'frmu',
+ kAEISServerName = 'svnm',
+ kAEISServerPort = 'svpt',
+ kAEISScriptName = 'scnm',
+ kAEISContentType = 'ctyp',
+ kAEISReferrer = 'refr',
+ kAEISUserAgent = 'Agnt',
+ kAEISAction = 'Kact',
+ kAEISActionPath = 'Kapt',
+ kAEISClientIP = 'Kcip',
+ kAEISFullRequest = 'Kfrq'
+};
+
+enum {
+
+ pScheme = 'pusc',
+ pHost = 'HOST',
+ pPath = 'FTPc',
+ pUserName = 'RAun',
+ pUserPassword = 'RApw',
+ pDNSForm = 'pDNS',
+ pURL = 'pURL',
+ pTextEncoding = 'ptxe',
+ pFTPKind = 'kind'
+};
+
+enum {
+
+ eScheme = 'esch',
+ eurlHTTP = 'http',
+ eurlHTTPS = 'htps',
+ eurlFTP = 'ftp ',
+ eurlMail = 'mail',
+ eurlFile = 'file',
+ eurlGopher = 'gphr',
+ eurlTelnet = 'tlnt',
+ eurlNews = 'news',
+ eurlSNews = 'snws',
+ eurlNNTP = 'nntp',
+ eurlMessage = 'mess',
+ eurlMailbox = 'mbox',
+ eurlMulti = 'mult',
+ eurlLaunch = 'laun',
+ eurlAFP = 'afp ',
+ eurlAT = 'at ',
+ eurlEPPC = 'eppc',
+ eurlRTSP = 'rtsp',
+ eurlIMAP = 'imap',
+ eurlNFS = 'unfs',
+ eurlPOP = 'upop',
+ eurlLDAP = 'uldp',
+ eurlUnknown = 'url?'
+};
+
+enum {
+
+ kConnSuite = 'macc',
+ cDevSpec = 'cdev',
+ cAddressSpec = 'cadr',
+ cADBAddress = 'cadb',
+ cAppleTalkAddress = 'cat ',
+ cBusAddress = 'cbus',
+ cEthernetAddress = 'cen ',
+ cFireWireAddress = 'cfw ',
+ cIPAddress = 'cip ',
+ cLocalTalkAddress = 'clt ',
+ cSCSIAddress = 'cscs',
+ cTokenRingAddress = 'ctok',
+ cUSBAddress = 'cusb',
+
+ pDeviceType = 'pdvt',
+ pDeviceAddress = 'pdva',
+ pConduit = 'pcon',
+ pProtocol = 'pprt',
+ pATMachine = 'patm',
+ pATZone = 'patz',
+ pATType = 'patt',
+ pDottedDecimal = 'pipd',
+ pDNS = 'pdns',
+ pPort = 'ppor',
+ pNetwork = 'pnet',
+ pNode = 'pnod',
+ pSocket = 'psoc',
+ pSCSIBus = 'pscb',
+ pSCSILUN = 'pslu',
+
+ eDeviceType = 'edvt',
+ eAddressSpec = 'eads',
+ eConduit = 'econ',
+ eProtocol = 'epro',
+ eADB = 'eadb',
+ eAnalogAudio = 'epau',
+ eAppleTalk = 'epat',
+ eAudioLineIn = 'ecai',
+ eAudioLineOut = 'ecal',
+ eAudioOut = 'ecao',
+ eBus = 'ebus',
+ eCDROM = 'ecd ',
+ eCommSlot = 'eccm',
+ eDigitalAudio = 'epda',
+ eDisplay = 'edds',
+ eDVD = 'edvd',
+ eEthernet = 'ecen',
+ eFireWire = 'ecfw',
+ eFloppy = 'efd ',
+ eHD = 'ehd ',
+ eInfrared = 'ecir',
+ eIP = 'epip',
+ eIrDA = 'epir',
+ eIRTalk = 'epit',
+ eKeyboard = 'ekbd',
+ eLCD = 'edlc',
+ eLocalTalk = 'eclt',
+ eMacIP = 'epmi',
+ eMacVideo = 'epmv',
+ eMicrophone = 'ecmi',
+ eModemPort = 'ecmp',
+ eModemPrinterPort = 'empp',
+ eModem = 'edmm',
+ eMonitorOut = 'ecmn',
+ eMouse = 'emou',
+ eNuBusCard = 'ednb',
+ eNuBus = 'enub',
+ ePCcard = 'ecpc',
+ ePCIbus = 'ecpi',
+ ePCIcard = 'edpi',
+ ePDSslot = 'ecpd',
+ ePDScard = 'epds',
+ ePointingDevice = 'edpd',
+ ePostScript = 'epps',
+ ePPP = 'eppp',
+ ePrinterPort = 'ecpp',
+ ePrinter = 'edpr',
+ eSvideo = 'epsv',
+ eSCSI = 'ecsc',
+ eSerial = 'epsr',
+ eSpeakers = 'edsp',
+ eStorageDevice = 'edst',
+ eSVGA = 'epsg',
+ eTokenRing = 'etok',
+ eTrackball = 'etrk',
+ eTrackpad = 'edtp',
+ eUSB = 'ecus',
+ eVideoIn = 'ecvi',
+ eVideoMonitor = 'edvm',
+ eVideoOut = 'ecvo'
+};
+
+enum {
+
+ cKeystroke = 'kprs',
+ pKeystrokeKey = 'kMsg',
+ pModifiers = 'kMod',
+ pKeyKind = 'kknd',
+ eModifiers = 'eMds',
+ eOptionDown = 'Kopt',
+ eCommandDown = 'Kcmd',
+ eControlDown = 'Kctl',
+ eShiftDown = 'Ksft',
+ eCapsLockDown = 'Kclk',
+ eKeyKind = 'ekst',
+
+ eEscapeKey = 0x6B733500,
+ eDeleteKey = 0x6B733300,
+ eTabKey = 0x6B733000,
+ eReturnKey = 0x6B732400,
+ eClearKey = 0x6B734700,
+ eEnterKey = 0x6B734C00,
+ eUpArrowKey = 0x6B737E00,
+ eDownArrowKey = 0x6B737D00,
+ eLeftArrowKey = 0x6B737B00,
+ eRightArrowKey = 0x6B737C00,
+ eHelpKey = 0x6B737200,
+ eHomeKey = 0x6B737300,
+ ePageUpKey = 0x6B737400,
+ ePageDownKey = 0x6B737900,
+ eForwardDelKey = 0x6B737500,
+ eEndKey = 0x6B737700,
+ eF1Key = 0x6B737A00,
+ eF2Key = 0x6B737800,
+ eF3Key = 0x6B736300,
+ eF4Key = 0x6B737600,
+ eF5Key = 0x6B736000,
+ eF6Key = 0x6B736100,
+ eF7Key = 0x6B736200,
+ eF8Key = 0x6B736400,
+ eF9Key = 0x6B736500,
+ eF10Key = 0x6B736D00,
+ eF11Key = 0x6B736700,
+ eF12Key = 0x6B736F00,
+ eF13Key = 0x6B736900,
+ eF14Key = 0x6B736B00,
+ eF15Key = 0x6B737100
+};
+
+
+
+
+
+
+enum {
+ kAEUserTerminology = 'aeut',
+ kAETerminologyExtension = 'aete',
+ kAEScriptingSizeResource = 'scsz',
+ kAEOSAXSizeResource = 'osiz'
+};
+
+enum {
+ kAEUTHasReturningParam = 31,
+ kAEUTOptional = 15,
+ kAEUTlistOfItems = 14,
+ kAEUTEnumerated = 13,
+ kAEUTReadWrite = 12,
+ kAEUTChangesState = 12,
+ kAEUTTightBindingFunction = 12,
+
+ kAEUTEnumsAreTypes = 11,
+ kAEUTEnumListIsExclusive = 10,
+ kAEUTReplyIsReference = 9,
+ kAEUTDirectParamIsReference = 9,
+ kAEUTParamIsReference = 9,
+ kAEUTPropertyIsReference = 9,
+ kAEUTNotDirectParamIsTarget = 8,
+ kAEUTParamIsTarget = 8,
+ kAEUTApostrophe = 3,
+ kAEUTFeminine = 2,
+ kAEUTMasculine = 1,
+ kAEUTPlural = 0
+};
+
+struct TScriptingSizeResource {
+ short scriptingSizeFlags;
+ unsigned long minStackSize;
+ unsigned long preferredStackSize;
+ unsigned long maxStackSize;
+ unsigned long minHeapSize;
+ unsigned long preferredHeapSize;
+ unsigned long maxHeapSize;
+};
+typedef struct TScriptingSizeResource TScriptingSizeResource;
+enum {
+ kLaunchToGetTerminology = (1 << 15),
+ kDontFindAppBySignature = (1 << 14),
+ kAlwaysSendSubject = (1 << 13)
+};
+
+
+enum {
+ kReadExtensionTermsMask = (1 << 15)
+};
+
+enum {
+
+
+ kOSIZDontOpenResourceFile = 15,
+ kOSIZdontAcceptRemoteEvents = 14,
+ kOSIZOpenWithReadPermission = 13,
+ kOSIZCodeInSharedLibraries = 11
+};
+
+
+
+
+
+extern "C" {
+
+
+typedef UInt32 AEBuildErrorCode;
+enum {
+ aeBuildSyntaxNoErr = 0,
+ aeBuildSyntaxBadToken = 1,
+ aeBuildSyntaxBadEOF = 2,
+ aeBuildSyntaxNoEOF = 3,
+ aeBuildSyntaxBadNegative = 4,
+ aeBuildSyntaxMissingQuote = 5,
+ aeBuildSyntaxBadHex = 6,
+ aeBuildSyntaxOddHex = 7,
+ aeBuildSyntaxNoCloseHex = 8,
+ aeBuildSyntaxUncoercedHex = 9,
+ aeBuildSyntaxNoCloseString = 10,
+ aeBuildSyntaxBadDesc = 11,
+ aeBuildSyntaxBadData = 12,
+ aeBuildSyntaxNoCloseParen = 13,
+ aeBuildSyntaxNoCloseBracket = 14,
+ aeBuildSyntaxNoCloseBrace = 15,
+ aeBuildSyntaxNoKey = 16,
+ aeBuildSyntaxNoColon = 17,
+ aeBuildSyntaxCoercedList = 18,
+ aeBuildSyntaxUncoercedDoubleAt = 19
+};
+
+
+
+struct AEBuildError {
+ AEBuildErrorCode fError;
+ UInt32 fErrorPos;
+};
+typedef struct AEBuildError AEBuildError;
+extern OSStatus
+AEBuildDesc(
+ AEDesc * dst,
+ AEBuildError * error,
+ const char * src,
+ ...) ;
+extern OSStatus
+vAEBuildDesc(
+ AEDesc * dst,
+ AEBuildError * error,
+ const char * src,
+ va_list args) ;
+extern OSStatus
+AEBuildParameters(
+ AppleEvent * event,
+ AEBuildError * error,
+ const char * format,
+ ...) ;
+extern OSStatus
+vAEBuildParameters(
+ AppleEvent * event,
+ AEBuildError * error,
+ const char * format,
+ va_list args) ;
+extern OSStatus
+AEBuildAppleEvent(
+ AEEventClass theClass,
+ AEEventID theID,
+ DescType addressType,
+ const void * addressData,
+ long addressLength,
+ short returnID,
+ long transactionID,
+ AppleEvent * result,
+ AEBuildError * error,
+ const char * paramsFmt,
+ ...) ;
+extern OSStatus
+vAEBuildAppleEvent(
+ AEEventClass theClass,
+ AEEventID theID,
+ DescType addressType,
+ const void * addressData,
+ long addressLength,
+ short returnID,
+ long transactionID,
+ AppleEvent * resultEvt,
+ AEBuildError * error,
+ const char * paramsFmt,
+ va_list args) ;
+extern OSStatus
+AEPrintDescToHandle(
+ const AEDesc * desc,
+ Handle * result) ;
+typedef struct OpaqueAEStreamRef* AEStreamRef;
+extern AEStreamRef
+AEStreamOpen(void) ;
+extern OSStatus
+AEStreamClose(
+ AEStreamRef ref,
+ AEDesc * desc) ;
+extern OSStatus
+AEStreamOpenDesc(
+ AEStreamRef ref,
+ DescType newType) ;
+extern OSStatus
+AEStreamWriteData(
+ AEStreamRef ref,
+ const void * data,
+ Size length) ;
+extern OSStatus
+AEStreamCloseDesc(AEStreamRef ref) ;
+extern OSStatus
+AEStreamWriteDesc(
+ AEStreamRef ref,
+ DescType newType,
+ const void * data,
+ Size length) ;
+extern OSStatus
+AEStreamWriteAEDesc(
+ AEStreamRef ref,
+ const AEDesc * desc) ;
+extern OSStatus
+AEStreamOpenList(AEStreamRef ref) ;
+extern OSStatus
+AEStreamCloseList(AEStreamRef ref) ;
+extern OSStatus
+AEStreamOpenRecord(
+ AEStreamRef ref,
+ DescType newType) ;
+extern OSStatus
+AEStreamSetRecordType(
+ AEStreamRef ref,
+ DescType newType) ;
+extern OSStatus
+AEStreamCloseRecord(AEStreamRef ref) ;
+extern OSStatus
+AEStreamWriteKeyDesc(
+ AEStreamRef ref,
+ AEKeyword key,
+ DescType newType,
+ const void * data,
+ Size length) ;
+extern OSStatus
+AEStreamOpenKeyDesc(
+ AEStreamRef ref,
+ AEKeyword key,
+ DescType newType) ;
+extern OSStatus
+AEStreamWriteKey(
+ AEStreamRef ref,
+ AEKeyword key) ;
+extern AEStreamRef
+AEStreamCreateEvent(
+ AEEventClass clazz,
+ AEEventID id,
+ DescType targetType,
+ const void * targetData,
+ long targetLength,
+ short returnID,
+ long transactionID) ;
+extern AEStreamRef
+AEStreamOpenEvent(AppleEvent * event) ;
+extern OSStatus
+AEStreamOptionalParam(
+ AEStreamRef ref,
+ AEKeyword key) ;
+
+
+
+
+
+}
+
+
+
+extern "C" {
+enum {
+ keyReplyPortAttr = 'repp'
+};
+
+
+enum {
+ typeReplyPortAttr = keyReplyPortAttr
+};
+
+
+
+
+
+}
+
+
+
+
+extern "C" {
+
+
+extern OSStatus
+StandardGlyphs(
+ void * dataStream,
+ ByteCount size) ;
+
+
+
+enum {
+
+ leftCaret = 0,
+ rightCaret = -1,
+ kHilite = 1
+};
+
+enum {
+ smLeftCaret = 0,
+ smRightCaret = -1,
+ smHilite = 1
+};
+
+enum {
+
+ onlyStyleRun = 0,
+ leftStyleRun = 1,
+ rightStyleRun = 2,
+ middleStyleRun = 3,
+ smOnlyStyleRun = 0,
+ smLeftStyleRun = 1,
+ smRightStyleRun = 2,
+ smMiddleStyleRun = 3
+};
+
+
+typedef short JustStyleCode;
+
+typedef short TruncCode;
+enum {
+
+ truncEnd = 0,
+ truncMiddle = 0x4000,
+ smTruncEnd = 0,
+ smTruncMiddle = 0x4000
+};
+
+enum {
+
+ notTruncated = 0,
+ truncated = 1,
+ truncErr = -1,
+ smNotTruncated = 0,
+ smTruncated = 1,
+ smTruncErr = -1
+};
+
+typedef SInt8 StyledLineBreakCode;
+enum {
+ smBreakWord = 0,
+ smBreakChar = 1,
+ smBreakOverflow = 2
+};
+
+
+enum {
+
+ tfAntiAlias = 1 << 0,
+ tfUnicode = 1 << 1
+};
+
+
+struct FontInfo {
+ short ascent;
+ short descent;
+ short widMax;
+ short leading;
+};
+typedef struct FontInfo FontInfo;
+
+typedef short FormatOrder[1];
+typedef FormatOrder * FormatOrderPtr;
+
+
+
+typedef Boolean ( * StyleRunDirectionProcPtr)(short styleRunIndex, void *dirParam);
+typedef StyleRunDirectionProcPtr StyleRunDirectionUPP;
+extern StyleRunDirectionUPP
+NewStyleRunDirectionUPP(StyleRunDirectionProcPtr userRoutine) ;
+extern void
+DisposeStyleRunDirectionUPP(StyleRunDirectionUPP userUPP) ;
+extern Boolean
+InvokeStyleRunDirectionUPP(
+ short styleRunIndex,
+ void * dirParam,
+ StyleRunDirectionUPP userUPP) ;
+extern short
+PixelToChar(
+ Ptr textBuf,
+ long textLength,
+ Fixed slop,
+ Fixed pixelWidth,
+ Boolean * leadingEdge,
+ Fixed * widthRemaining,
+ JustStyleCode styleRunPosition,
+ Point numer,
+ Point denom) ;
+extern short
+CharToPixel(
+ Ptr textBuf,
+ long textLength,
+ Fixed slop,
+ long offset,
+ short direction,
+ JustStyleCode styleRunPosition,
+ Point numer,
+ Point denom) ;
+extern void
+DrawJustified(
+ Ptr textPtr,
+ long textLength,
+ Fixed slop,
+ JustStyleCode styleRunPosition,
+ Point numer,
+ Point denom) ;
+extern void
+MeasureJustified(
+ Ptr textPtr,
+ long textLength,
+ Fixed slop,
+ Ptr charLocs,
+ JustStyleCode styleRunPosition,
+ Point numer,
+ Point denom) ;
+extern Fixed
+PortionLine(
+ Ptr textPtr,
+ long textLen,
+ JustStyleCode styleRunPosition,
+ Point numer,
+ Point denom) ;
+extern void
+HiliteText(
+ Ptr textPtr,
+ short textLength,
+ short firstOffset,
+ short secondOffset,
+ OffsetTable offsets) ;
+extern long
+VisibleLength(
+ Ptr textPtr,
+ long textLength) ;
+extern void
+GetFormatOrder(
+ FormatOrderPtr ordering,
+ short firstFormat,
+ short lastFormat,
+ Boolean lineRight,
+ StyleRunDirectionUPP rlDirProc,
+ Ptr dirParam) ;
+extern void
+TextFont(short font) ;
+extern void
+TextFace(StyleParameter face) ;
+extern void
+TextMode(short mode) ;
+extern void
+TextSize(short size) ;
+extern void
+SpaceExtra(Fixed extra) ;
+extern void
+DrawChar(CharParameter ch) ;
+extern void
+DrawString(ConstStr255Param s) ;
+extern void
+DrawText(
+ const void * textBuf,
+ short firstByte,
+ short byteCount) ;
+extern short
+CharWidth(CharParameter ch) ;
+extern short
+StringWidth(ConstStr255Param s) ;
+extern short
+TextWidth(
+ const void * textBuf,
+ short firstByte,
+ short byteCount) ;
+extern void
+MeasureText(
+ short count,
+ const void * textAddr,
+ void * charLocs) ;
+extern void
+GetFontInfo(FontInfo * info) ;
+extern void
+CharExtra(Fixed extra) ;
+extern void
+StdText(
+ short count,
+ const void * textAddr,
+ Point numer,
+ Point denom) ;
+extern short
+StdTxMeas(
+ short byteCount,
+ const void * textAddr,
+ Point * numer,
+ Point * denom,
+ FontInfo * info) ;
+extern StyledLineBreakCode
+StyledLineBreak(
+ Ptr textPtr,
+ long textLen,
+ long textStart,
+ long textEnd,
+ long flags,
+ Fixed * textWidth,
+ long * textOffset) ;
+extern short
+TruncString(
+ short width,
+ Str255 theString,
+ TruncCode truncWhere) ;
+extern short
+TruncText(
+ short width,
+ Ptr textPtr,
+ short * length,
+ TruncCode truncWhere) ;
+extern void
+stdtext(
+ short count,
+ const void * textAddr,
+ const Point * numer,
+ const Point * denom) ;
+extern UInt32
+SwapQDTextFlags(UInt32 newFlags) ;
+
+
+}
+extern "C" {
+
+
+
+enum {
+ invalColReq = -1
+};
+
+enum {
+
+ srcCopy = 0,
+ srcOr = 1,
+ srcXor = 2,
+ srcBic = 3,
+ notSrcCopy = 4,
+ notSrcOr = 5,
+ notSrcXor = 6,
+ notSrcBic = 7,
+ patCopy = 8,
+ patOr = 9,
+ patXor = 10,
+ patBic = 11,
+ notPatCopy = 12,
+ notPatOr = 13,
+ notPatXor = 14,
+ notPatBic = 15,
+ grayishTextOr = 49,
+ hilitetransfermode = 50,
+ hilite = 50,
+ blend = 32,
+ addPin = 33,
+ addOver = 34,
+ subPin = 35,
+ addMax = 37,
+ adMax = 37,
+ subOver = 38,
+ adMin = 39,
+ ditherCopy = 64,
+ transparent = 36
+};
+
+enum {
+ italicBit = 1,
+ ulineBit = 2,
+ outlineBit = 3,
+ shadowBit = 4,
+ condenseBit = 5,
+ extendBit = 6
+};
+
+enum {
+
+ normalBit = 0,
+ inverseBit = 1,
+ redBit = 4,
+ greenBit = 3,
+ blueBit = 2,
+ cyanBit = 8,
+ magentaBit = 7,
+ yellowBit = 6,
+ blackBit = 5
+};
+
+enum {
+ blackColor = 33,
+ whiteColor = 30,
+ redColor = 205,
+ greenColor = 341,
+ blueColor = 409,
+ cyanColor = 273,
+ magentaColor = 137,
+ yellowColor = 69
+};
+
+enum {
+ picLParen = 0,
+ picRParen = 1,
+ clutType = 0,
+ fixedType = 1,
+ directType = 2,
+ gdDevType = 0
+};
+
+enum {
+ interlacedDevice = 2,
+ hwMirroredDevice = 4,
+ roundedDevice = 5,
+ hasAuxMenuBar = 6,
+ burstDevice = 7,
+ ext32Device = 8,
+ ramInit = 10,
+ mainScreen = 11,
+ allInit = 12,
+ screenDevice = 13,
+ noDriver = 14,
+ screenActive = 15,
+ hiliteBit = 7,
+ pHiliteBit = 0,
+ defQDColors = 127,
+
+ RGBDirect = 16,
+
+ baseAddr32 = 4
+};
+
+
+enum {
+ sysPatListID = 0,
+ iBeamCursor = 1,
+ crossCursor = 2,
+ plusCursor = 3,
+ watchCursor = 4
+};
+
+enum {
+ kQDGrafVerbFrame = 0,
+ kQDGrafVerbPaint = 1,
+ kQDGrafVerbErase = 2,
+ kQDGrafVerbInvert = 3,
+ kQDGrafVerbFill = 4
+};
+typedef SInt8 GrafVerb;
+enum {
+ chunky = 0,
+ chunkyPlanar = 1,
+ planar = 2
+};
+
+typedef SInt8 PixelType;
+typedef short Bits16[16];
+struct Pattern {
+ UInt8 pat[8];
+};
+typedef struct Pattern Pattern;
+
+
+
+
+
+typedef const Pattern * ConstPatternParam;
+typedef Pattern * PatPtr;
+typedef PatPtr * PatHandle;
+typedef SignedByte QDByte;
+typedef QDByte * QDPtr;
+typedef QDPtr * QDHandle;
+typedef short QDErr;
+enum {
+ singleDevicesBit = 0,
+ dontMatchSeedsBit = 1,
+ allDevicesBit = 2
+};
+
+enum {
+ singleDevices = 1 << singleDevicesBit,
+ dontMatchSeeds = 1 << dontMatchSeedsBit,
+ allDevices = 1 << allDevicesBit
+};
+
+typedef unsigned long DeviceLoopFlags;
+
+
+
+typedef SInt32 PrinterStatusOpcode;
+enum {
+ kPrinterFontStatus = 0,
+ kPrinterScalingStatus = 1
+};
+
+struct PrinterFontStatus {
+ SInt32 oResult;
+ SInt16 iFondID;
+ Style iStyle;
+};
+typedef struct PrinterFontStatus PrinterFontStatus;
+struct PrinterScalingStatus {
+ Point oScalingFactors;
+};
+typedef struct PrinterScalingStatus PrinterScalingStatus;
+struct BitMap {
+ Ptr baseAddr;
+ short rowBytes;
+ Rect bounds;
+};
+typedef struct BitMap BitMap;
+typedef BitMap * BitMapPtr;
+typedef BitMapPtr * BitMapHandle;
+struct Cursor {
+ Bits16 data;
+ Bits16 mask;
+ Point hotSpot;
+};
+typedef struct Cursor Cursor;
+typedef Cursor * CursPtr;
+typedef CursPtr * CursHandle;
+struct PenState {
+ Point pnLoc;
+ Point pnSize;
+ short pnMode;
+ Pattern pnPat;
+};
+typedef struct PenState PenState;
+typedef struct OpaqueRgnHandle* RgnHandle;
+
+
+struct Picture {
+ short picSize;
+ Rect picFrame;
+};
+typedef struct Picture Picture;
+typedef Picture * PicPtr;
+typedef PicPtr * PicHandle;
+struct MacPolygon {
+ short polySize;
+ Rect polyBBox;
+ Point polyPoints[1];
+};
+typedef struct MacPolygon MacPolygon;
+
+
+
+
+typedef MacPolygon Polygon;
+typedef MacPolygon * PolyPtr;
+typedef PolyPtr * PolyHandle;
+typedef void ( * QDTextProcPtr)(short byteCount, const void *textBuf, Point numer, Point denom);
+typedef void ( * QDLineProcPtr)(Point newPt);
+typedef void ( * QDRectProcPtr)(GrafVerb verb, const Rect *r);
+typedef void ( * QDRRectProcPtr)(GrafVerb verb, const Rect *r, short ovalWidth, short ovalHeight);
+typedef void ( * QDOvalProcPtr)(GrafVerb verb, const Rect *r);
+typedef void ( * QDArcProcPtr)(GrafVerb verb, const Rect *r, short startAngle, short arcAngle);
+typedef void ( * QDPolyProcPtr)(GrafVerb verb, PolyHandle poly);
+typedef void ( * QDRgnProcPtr)(GrafVerb verb, RgnHandle rgn);
+typedef void ( * QDBitsProcPtr)(const BitMap *srcBits, const Rect *srcRect, const Rect *dstRect, short mode, RgnHandle maskRgn);
+typedef void ( * QDCommentProcPtr)(short kind, short dataSize, Handle dataHandle);
+typedef short ( * QDTxMeasProcPtr)(short byteCount, const void *textAddr, Point *numer, Point *denom, FontInfo *info);
+typedef void ( * QDGetPicProcPtr)(void *dataPtr, short byteCount);
+typedef void ( * QDPutPicProcPtr)(const void *dataPtr, short byteCount);
+typedef void ( * QDOpcodeProcPtr)(const Rect *fromRect, const Rect *toRect, UInt16 opcode, SInt16 version);
+typedef OSStatus ( * QDStdGlyphsProcPtr)(void *dataStream, ByteCount size);
+typedef void ( * QDJShieldCursorProcPtr)(short left, short top, short right, short bottom);
+typedef QDTextProcPtr QDTextUPP;
+typedef QDLineProcPtr QDLineUPP;
+typedef QDRectProcPtr QDRectUPP;
+typedef QDRRectProcPtr QDRRectUPP;
+typedef QDOvalProcPtr QDOvalUPP;
+typedef QDArcProcPtr QDArcUPP;
+typedef QDPolyProcPtr QDPolyUPP;
+typedef QDRgnProcPtr QDRgnUPP;
+typedef QDBitsProcPtr QDBitsUPP;
+typedef QDCommentProcPtr QDCommentUPP;
+typedef QDTxMeasProcPtr QDTxMeasUPP;
+typedef QDGetPicProcPtr QDGetPicUPP;
+typedef QDPutPicProcPtr QDPutPicUPP;
+typedef QDOpcodeProcPtr QDOpcodeUPP;
+typedef QDStdGlyphsProcPtr QDStdGlyphsUPP;
+typedef QDJShieldCursorProcPtr QDJShieldCursorUPP;
+struct QDProcs {
+ QDTextUPP textProc;
+ QDLineUPP lineProc;
+ QDRectUPP rectProc;
+ QDRRectUPP rRectProc;
+ QDOvalUPP ovalProc;
+ QDArcUPP arcProc;
+ QDPolyUPP polyProc;
+ QDRgnUPP rgnProc;
+ QDBitsUPP bitsProc;
+ QDCommentUPP commentProc;
+ QDTxMeasUPP txMeasProc;
+ QDGetPicUPP getPicProc;
+ QDPutPicUPP putPicProc;
+};
+typedef struct QDProcs QDProcs;
+typedef QDProcs * QDProcsPtr;
+extern QDTextUPP
+NewQDTextUPP(QDTextProcPtr userRoutine) ;
+extern QDLineUPP
+NewQDLineUPP(QDLineProcPtr userRoutine) ;
+extern QDRectUPP
+NewQDRectUPP(QDRectProcPtr userRoutine) ;
+extern QDRRectUPP
+NewQDRRectUPP(QDRRectProcPtr userRoutine) ;
+extern QDOvalUPP
+NewQDOvalUPP(QDOvalProcPtr userRoutine) ;
+extern QDArcUPP
+NewQDArcUPP(QDArcProcPtr userRoutine) ;
+extern QDPolyUPP
+NewQDPolyUPP(QDPolyProcPtr userRoutine) ;
+extern QDRgnUPP
+NewQDRgnUPP(QDRgnProcPtr userRoutine) ;
+extern QDBitsUPP
+NewQDBitsUPP(QDBitsProcPtr userRoutine) ;
+extern QDCommentUPP
+NewQDCommentUPP(QDCommentProcPtr userRoutine) ;
+extern QDTxMeasUPP
+NewQDTxMeasUPP(QDTxMeasProcPtr userRoutine) ;
+extern QDGetPicUPP
+NewQDGetPicUPP(QDGetPicProcPtr userRoutine) ;
+extern QDPutPicUPP
+NewQDPutPicUPP(QDPutPicProcPtr userRoutine) ;
+extern QDOpcodeUPP
+NewQDOpcodeUPP(QDOpcodeProcPtr userRoutine) ;
+extern QDStdGlyphsUPP
+NewQDStdGlyphsUPP(QDStdGlyphsProcPtr userRoutine) ;
+extern QDJShieldCursorUPP
+NewQDJShieldCursorUPP(QDJShieldCursorProcPtr userRoutine) ;
+extern void
+DisposeQDTextUPP(QDTextUPP userUPP) ;
+extern void
+DisposeQDLineUPP(QDLineUPP userUPP) ;
+extern void
+DisposeQDRectUPP(QDRectUPP userUPP) ;
+extern void
+DisposeQDRRectUPP(QDRRectUPP userUPP) ;
+extern void
+DisposeQDOvalUPP(QDOvalUPP userUPP) ;
+extern void
+DisposeQDArcUPP(QDArcUPP userUPP) ;
+extern void
+DisposeQDPolyUPP(QDPolyUPP userUPP) ;
+extern void
+DisposeQDRgnUPP(QDRgnUPP userUPP) ;
+extern void
+DisposeQDBitsUPP(QDBitsUPP userUPP) ;
+extern void
+DisposeQDCommentUPP(QDCommentUPP userUPP) ;
+extern void
+DisposeQDTxMeasUPP(QDTxMeasUPP userUPP) ;
+extern void
+DisposeQDGetPicUPP(QDGetPicUPP userUPP) ;
+extern void
+DisposeQDPutPicUPP(QDPutPicUPP userUPP) ;
+extern void
+DisposeQDOpcodeUPP(QDOpcodeUPP userUPP) ;
+extern void
+DisposeQDStdGlyphsUPP(QDStdGlyphsUPP userUPP) ;
+extern void
+DisposeQDJShieldCursorUPP(QDJShieldCursorUPP userUPP) ;
+extern void
+InvokeQDTextUPP(
+ short byteCount,
+ const void * textBuf,
+ Point numer,
+ Point denom,
+ QDTextUPP userUPP) ;
+extern void
+InvokeQDLineUPP(
+ Point newPt,
+ QDLineUPP userUPP) ;
+extern void
+InvokeQDRectUPP(
+ GrafVerb verb,
+ const Rect * r,
+ QDRectUPP userUPP) ;
+extern void
+InvokeQDRRectUPP(
+ GrafVerb verb,
+ const Rect * r,
+ short ovalWidth,
+ short ovalHeight,
+ QDRRectUPP userUPP) ;
+extern void
+InvokeQDOvalUPP(
+ GrafVerb verb,
+ const Rect * r,
+ QDOvalUPP userUPP) ;
+extern void
+InvokeQDArcUPP(
+ GrafVerb verb,
+ const Rect * r,
+ short startAngle,
+ short arcAngle,
+ QDArcUPP userUPP) ;
+extern void
+InvokeQDPolyUPP(
+ GrafVerb verb,
+ PolyHandle poly,
+ QDPolyUPP userUPP) ;
+extern void
+InvokeQDRgnUPP(
+ GrafVerb verb,
+ RgnHandle rgn,
+ QDRgnUPP userUPP) ;
+extern void
+InvokeQDBitsUPP(
+ const BitMap * srcBits,
+ const Rect * srcRect,
+ const Rect * dstRect,
+ short mode,
+ RgnHandle maskRgn,
+ QDBitsUPP userUPP) ;
+extern void
+InvokeQDCommentUPP(
+ short kind,
+ short dataSize,
+ Handle dataHandle,
+ QDCommentUPP userUPP) ;
+extern short
+InvokeQDTxMeasUPP(
+ short byteCount,
+ const void * textAddr,
+ Point * numer,
+ Point * denom,
+ FontInfo * info,
+ QDTxMeasUPP userUPP) ;
+extern void
+InvokeQDGetPicUPP(
+ void * dataPtr,
+ short byteCount,
+ QDGetPicUPP userUPP) ;
+extern void
+InvokeQDPutPicUPP(
+ const void * dataPtr,
+ short byteCount,
+ QDPutPicUPP userUPP) ;
+extern void
+InvokeQDOpcodeUPP(
+ const Rect * fromRect,
+ const Rect * toRect,
+ UInt16 opcode,
+ SInt16 version,
+ QDOpcodeUPP userUPP) ;
+extern OSStatus
+InvokeQDStdGlyphsUPP(
+ void * dataStream,
+ ByteCount size,
+ QDStdGlyphsUPP userUPP) ;
+extern void
+InvokeQDJShieldCursorUPP(
+ short left,
+ short top,
+ short right,
+ short bottom,
+ QDJShieldCursorUPP userUPP) ;
+typedef struct OpaqueWindowPtr* WindowPtr;
+typedef struct OpaqueDialogPtr* DialogPtr;
+typedef struct OpaqueGrafPtr* GrafPtr;
+
+
+typedef WindowPtr WindowRef;
+
+typedef UInt16 DragConstraint;
+enum {
+ kNoConstraint = 0,
+ kVerticalConstraint = 1,
+ kHorizontalConstraint = 2
+};
+
+
+typedef void ( * DragGrayRgnProcPtr)(void);
+
+
+
+
+
+struct RGBColor {
+ unsigned short red;
+ unsigned short green;
+ unsigned short blue;
+};
+typedef struct RGBColor RGBColor;
+typedef RGBColor * RGBColorPtr;
+typedef RGBColorPtr * RGBColorHdl;
+typedef Boolean ( * ColorSearchProcPtr)(RGBColor *rgb, long *position);
+typedef Boolean ( * ColorComplementProcPtr)(RGBColor * rgb);
+typedef DragGrayRgnProcPtr DragGrayRgnUPP;
+typedef ColorSearchProcPtr ColorSearchUPP;
+typedef ColorComplementProcPtr ColorComplementUPP;
+extern DragGrayRgnUPP
+NewDragGrayRgnUPP(DragGrayRgnProcPtr userRoutine) ;
+extern ColorSearchUPP
+NewColorSearchUPP(ColorSearchProcPtr userRoutine) ;
+extern ColorComplementUPP
+NewColorComplementUPP(ColorComplementProcPtr userRoutine) ;
+extern void
+DisposeDragGrayRgnUPP(DragGrayRgnUPP userUPP) ;
+extern void
+DisposeColorSearchUPP(ColorSearchUPP userUPP) ;
+extern void
+DisposeColorComplementUPP(ColorComplementUPP userUPP) ;
+extern void
+InvokeDragGrayRgnUPP(DragGrayRgnUPP userUPP) ;
+extern Boolean
+InvokeColorSearchUPP(
+ RGBColor * rgb,
+ long * position,
+ ColorSearchUPP userUPP) ;
+extern Boolean
+InvokeColorComplementUPP(
+ RGBColor * rgb,
+ ColorComplementUPP userUPP) ;
+
+struct ColorSpec {
+ short value;
+ RGBColor rgb;
+};
+typedef struct ColorSpec ColorSpec;
+typedef ColorSpec * ColorSpecPtr;
+typedef ColorSpec CSpecArray[1];
+struct ColorTable {
+ long ctSeed;
+ short ctFlags;
+ short ctSize;
+ CSpecArray ctTable;
+};
+typedef struct ColorTable ColorTable;
+typedef ColorTable * CTabPtr;
+typedef CTabPtr * CTabHandle;
+struct xColorSpec {
+ short value;
+ RGBColor rgb;
+ short xalpha;
+};
+typedef struct xColorSpec xColorSpec;
+typedef xColorSpec * xColorSpecPtr;
+typedef xColorSpec xCSpecArray[1];
+struct MatchRec {
+ unsigned short red;
+ unsigned short green;
+ unsigned short blue;
+ long matchData;
+};
+typedef struct MatchRec MatchRec;
+enum {
+ k1MonochromePixelFormat = 0x00000001,
+ k2IndexedPixelFormat = 0x00000002,
+ k4IndexedPixelFormat = 0x00000004,
+ k8IndexedPixelFormat = 0x00000008,
+ k16BE555PixelFormat = 0x00000010,
+ k24RGBPixelFormat = 0x00000018,
+ k32ARGBPixelFormat = 0x00000020,
+ k1IndexedGrayPixelFormat = 0x00000021,
+ k2IndexedGrayPixelFormat = 0x00000022,
+ k4IndexedGrayPixelFormat = 0x00000024,
+ k8IndexedGrayPixelFormat = 0x00000028
+};
+
+
+
+enum {
+ k16LE555PixelFormat = 'L555',
+ k16LE5551PixelFormat = '5551',
+ k16BE565PixelFormat = 'B565',
+ k16LE565PixelFormat = 'L565',
+ k24BGRPixelFormat = '24BG',
+ k32BGRAPixelFormat = 'BGRA',
+ k32ABGRPixelFormat = 'ABGR',
+ k32RGBAPixelFormat = 'RGBA',
+ kYUVSPixelFormat = 'yuvs',
+ kYUVUPixelFormat = 'yuvu',
+ kYVU9PixelFormat = 'YVU9',
+ kYUV411PixelFormat = 'Y411',
+ kYVYU422PixelFormat = 'YVYU',
+ kUYVY422PixelFormat = 'UYVY',
+ kYUV211PixelFormat = 'Y211',
+ k2vuyPixelFormat = '2vuy'
+};
+
+
+struct PixMap {
+ Ptr baseAddr;
+ short rowBytes;
+ Rect bounds;
+ short pmVersion;
+ short packType;
+ long packSize;
+ Fixed hRes;
+ Fixed vRes;
+ short pixelType;
+ short pixelSize;
+ short cmpCount;
+ short cmpSize;
+
+
+
+
+
+ OSType pixelFormat;
+ CTabHandle pmTable;
+ void* pmExt;
+
+};
+typedef struct PixMap PixMap;
+typedef PixMap * PixMapPtr;
+typedef PixMapPtr * PixMapHandle;
+struct PixPat {
+ short patType;
+ PixMapHandle patMap;
+ Handle patData;
+ Handle patXData;
+ short patXValid;
+ Handle patXMap;
+ Pattern pat1Data;
+};
+typedef struct PixPat PixPat;
+typedef PixPat * PixPatPtr;
+typedef PixPatPtr * PixPatHandle;
+struct CCrsr {
+ short crsrType;
+ PixMapHandle crsrMap;
+ Handle crsrData;
+ Handle crsrXData;
+ short crsrXValid;
+ Handle crsrXHandle;
+ Bits16 crsr1Data;
+ Bits16 crsrMask;
+ Point crsrHotSpot;
+ long crsrXTable;
+ long crsrID;
+};
+typedef struct CCrsr CCrsr;
+typedef CCrsr * CCrsrPtr;
+typedef CCrsrPtr * CCrsrHandle;
+struct GammaTbl {
+ short gVersion;
+ short gType;
+ short gFormulaSize;
+ short gChanCnt;
+ short gDataCnt;
+ short gDataWidth;
+ short gFormulaData[1];
+};
+typedef struct GammaTbl GammaTbl;
+typedef GammaTbl * GammaTblPtr;
+typedef GammaTblPtr * GammaTblHandle;
+struct ITab {
+ long iTabSeed;
+ short iTabRes;
+ Byte iTTable[1];
+};
+typedef struct ITab ITab;
+typedef ITab * ITabPtr;
+typedef ITabPtr * ITabHandle;
+struct SProcRec {
+ Handle nxtSrch;
+ ColorSearchUPP srchProc;
+};
+typedef struct SProcRec SProcRec;
+typedef SProcRec * SProcPtr;
+typedef SProcPtr * SProcHndl;
+struct CProcRec {
+ Handle nxtComp;
+ ColorComplementUPP compProc;
+};
+typedef struct CProcRec CProcRec;
+typedef CProcRec * CProcPtr;
+typedef CProcPtr * CProcHndl;
+typedef struct GDevice GDevice;
+typedef GDevice * GDPtr;
+typedef GDPtr * GDHandle;
+struct GDevice {
+ short gdRefNum;
+ short gdID;
+ short gdType;
+ ITabHandle gdITable;
+ short gdResPref;
+ SProcHndl gdSearchProc;
+ CProcHndl gdCompProc;
+ short gdFlags;
+ PixMapHandle gdPMap;
+ long gdRefCon;
+ GDHandle gdNextGD;
+ Rect gdRect;
+ long gdMode;
+ short gdCCBytes;
+ short gdCCDepth;
+ Handle gdCCXData;
+ Handle gdCCXMask;
+
+
+
+ Handle gdExt;
+
+};
+
+struct GrafVars {
+ RGBColor rgbOpColor;
+ RGBColor rgbHiliteColor;
+ Handle pmFgColor;
+ short pmFgIndex;
+ Handle pmBkColor;
+ short pmBkIndex;
+ short pmFlags;
+};
+typedef struct GrafVars GrafVars;
+typedef GrafVars * GVarPtr;
+typedef GVarPtr * GVarHandle;
+
+
+
+
+
+typedef GrafPtr CGrafPtr;
+
+
+typedef OSStatus ( * QDPrinterStatusProcPtr)(PrinterStatusOpcode opcode, CGrafPtr currentPort, void *printerStatus);
+typedef QDPrinterStatusProcPtr QDPrinterStatusUPP;
+
+struct CQDProcs {
+ QDTextUPP textProc;
+ QDLineUPP lineProc;
+ QDRectUPP rectProc;
+ QDRRectUPP rRectProc;
+ QDOvalUPP ovalProc;
+ QDArcUPP arcProc;
+ QDPolyUPP polyProc;
+ QDRgnUPP rgnProc;
+ QDBitsUPP bitsProc;
+ QDCommentUPP commentProc;
+ QDTxMeasUPP txMeasProc;
+ QDGetPicUPP getPicProc;
+ QDPutPicUPP putPicProc;
+ QDOpcodeUPP opcodeProc;
+ UniversalProcPtr newProc1;
+ QDStdGlyphsUPP glyphsProc;
+ QDPrinterStatusUPP printerStatusProc;
+ UniversalProcPtr newProc4;
+ UniversalProcPtr newProc5;
+ UniversalProcPtr newProc6;
+};
+typedef struct CQDProcs CQDProcs;
+typedef CQDProcs * CQDProcsPtr;
+typedef WindowPtr CWindowPtr;
+
+
+
+
+struct ReqListRec {
+ short reqLSize;
+ short reqLData[1];
+};
+typedef struct ReqListRec ReqListRec;
+struct OpenCPicParams {
+ Rect srcRect;
+ Fixed hRes;
+ Fixed vRes;
+ short version;
+ short reserved1;
+ long reserved2;
+};
+typedef struct OpenCPicParams OpenCPicParams;
+enum {
+ kCursorImageMajorVersion = 0x0001,
+ kCursorImageMinorVersion = 0x0000
+};
+
+struct CursorImageRec {
+ UInt16 majorVersion;
+ UInt16 minorVersion;
+ PixMapHandle cursorPixMap;
+ BitMapHandle cursorBitMask;
+};
+typedef struct CursorImageRec CursorImageRec;
+typedef CursorImageRec * CursorImagePtr;
+typedef void ( * DeviceLoopDrawingProcPtr)(short depth, short deviceFlags, GDHandle targetDevice, long userData);
+typedef DeviceLoopDrawingProcPtr DeviceLoopDrawingUPP;
+extern DeviceLoopDrawingUPP
+NewDeviceLoopDrawingUPP(DeviceLoopDrawingProcPtr userRoutine) ;
+extern void
+DisposeDeviceLoopDrawingUPP(DeviceLoopDrawingUPP userUPP) ;
+extern void
+InvokeDeviceLoopDrawingUPP(
+ short depth,
+ short deviceFlags,
+ GDHandle targetDevice,
+ long userData,
+ DeviceLoopDrawingUPP userUPP) ;
+extern OSErr
+LockPortBits(GrafPtr port) ;
+extern OSErr
+UnlockPortBits(GrafPtr port) ;
+
+
+
+
+enum {
+ kQDParseRegionFromTop = (1 << 0),
+ kQDParseRegionFromBottom = (1 << 1),
+ kQDParseRegionFromLeft = (1 << 2),
+ kQDParseRegionFromRight = (1 << 3),
+ kQDParseRegionFromTopLeft = kQDParseRegionFromTop | kQDParseRegionFromLeft,
+ kQDParseRegionFromBottomRight = kQDParseRegionFromBottom | kQDParseRegionFromRight
+};
+
+typedef SInt32 QDRegionParseDirection;
+enum {
+ kQDRegionToRectsMsgInit = 1,
+ kQDRegionToRectsMsgParse = 2,
+ kQDRegionToRectsMsgTerminate = 3
+};
+
+typedef OSStatus ( * RegionToRectsProcPtr)(UInt16 message, RgnHandle rgn, const Rect *rect, void *refCon);
+typedef RegionToRectsProcPtr RegionToRectsUPP;
+extern RegionToRectsUPP
+NewRegionToRectsUPP(RegionToRectsProcPtr userRoutine) ;
+extern void
+DisposeRegionToRectsUPP(RegionToRectsUPP userUPP) ;
+extern OSStatus
+InvokeRegionToRectsUPP(
+ UInt16 message,
+ RgnHandle rgn,
+ const Rect * rect,
+ void * refCon,
+ RegionToRectsUPP userUPP) ;
+extern OSStatus
+QDRegionToRects(
+ RgnHandle rgn,
+ QDRegionParseDirection dir,
+ RegionToRectsUPP proc,
+ void * userData) ;
+extern void
+SetPort(GrafPtr port) ;
+extern void
+GetPort(GrafPtr * port) ;
+extern Boolean
+QDSwapPort(
+ CGrafPtr inNewPort,
+ CGrafPtr * outOldPort) ;
+extern void
+GrafDevice(short device) ;
+extern void
+SetPortBits(const BitMap * bm) ;
+extern void
+PortSize(
+ short width,
+ short height) ;
+extern void
+MovePortTo(
+ short leftGlobal,
+ short topGlobal) ;
+extern void
+SetOrigin(
+ short h,
+ short v) ;
+extern void
+SetClip(RgnHandle rgn) ;
+extern void
+GetClip(RgnHandle rgn) ;
+extern void
+ClipRect(const Rect * r) ;
+extern void
+BackPat(const Pattern * pat) ;
+extern void
+InitCursor(void) ;
+extern void
+SetCursor(const Cursor * crsr) ;
+extern void
+HideCursor(void) ;
+extern void
+ShowCursor(void) ;
+extern void
+ObscureCursor(void) ;
+extern void
+HidePen(void) ;
+extern void
+ShowPen(void) ;
+extern void
+GetPen(Point * pt) ;
+extern void
+GetPenState(PenState * pnState) ;
+extern void
+SetPenState(const PenState * pnState) ;
+extern void
+PenSize(
+ short width,
+ short height) ;
+extern void
+PenMode(short mode) ;
+extern void
+PenPat(const Pattern * pat) ;
+extern void
+PenNormal(void) ;
+extern void
+MoveTo(
+ short h,
+ short v) ;
+extern void
+Move(
+ short dh,
+ short dv) ;
+extern void
+LineTo(
+ short h,
+ short v) ;
+extern void
+Line(
+ short dh,
+ short dv) ;
+extern void
+ForeColor(long color) ;
+extern void
+BackColor(long color) ;
+extern void
+ColorBit(short whichBit) ;
+extern void
+SetRect(
+ Rect * r,
+ short left,
+ short top,
+ short right,
+ short bottom) ;
+extern void
+OffsetRect(
+ Rect * r,
+ short dh,
+ short dv) ;
+extern void
+InsetRect(
+ Rect * r,
+ short dh,
+ short dv) ;
+extern Boolean
+SectRect(
+ const Rect * src1,
+ const Rect * src2,
+ Rect * dstRect) ;
+extern void
+UnionRect(
+ const Rect * src1,
+ const Rect * src2,
+ Rect * dstRect) ;
+extern Boolean
+EqualRect(
+ const Rect * rect1,
+ const Rect * rect2) ;
+extern Boolean
+EmptyRect(const Rect * r) ;
+extern void
+FrameRect(const Rect * r) ;
+extern void
+PaintRect(const Rect * r) ;
+extern void
+EraseRect(const Rect * r) ;
+extern void
+InvertRect(const Rect * r) ;
+extern void
+FillRect(
+ const Rect * r,
+ const Pattern * pat) ;
+extern void
+FrameOval(const Rect * r) ;
+extern void
+PaintOval(const Rect * r) ;
+extern void
+EraseOval(const Rect * r) ;
+extern void
+InvertOval(const Rect * r) ;
+extern void
+FillOval(
+ const Rect * r,
+ const Pattern * pat) ;
+extern void
+FrameRoundRect(
+ const Rect * r,
+ short ovalWidth,
+ short ovalHeight) ;
+extern void
+PaintRoundRect(
+ const Rect * r,
+ short ovalWidth,
+ short ovalHeight) ;
+extern void
+EraseRoundRect(
+ const Rect * r,
+ short ovalWidth,
+ short ovalHeight) ;
+extern void
+InvertRoundRect(
+ const Rect * r,
+ short ovalWidth,
+ short ovalHeight) ;
+extern void
+FillRoundRect(
+ const Rect * r,
+ short ovalWidth,
+ short ovalHeight,
+ const Pattern * pat) ;
+extern void
+FrameArc(
+ const Rect * r,
+ short startAngle,
+ short arcAngle) ;
+extern void
+PaintArc(
+ const Rect * r,
+ short startAngle,
+ short arcAngle) ;
+extern void
+EraseArc(
+ const Rect * r,
+ short startAngle,
+ short arcAngle) ;
+extern void
+InvertArc(
+ const Rect * r,
+ short startAngle,
+ short arcAngle) ;
+extern void
+FillArc(
+ const Rect * r,
+ short startAngle,
+ short arcAngle,
+ const Pattern * pat) ;
+extern RgnHandle
+NewRgn(void) ;
+extern void
+OpenRgn(void) ;
+extern void
+CloseRgn(RgnHandle dstRgn) ;
+extern OSErr
+BitMapToRegion(
+ RgnHandle region,
+ const BitMap * bMap) ;
+extern void
+HandleToRgn(
+ Handle oldRegion,
+ RgnHandle region) ;
+extern void
+RgnToHandle(
+ RgnHandle region,
+ Handle flattenedRgnDataHdl) ;
+extern void
+DisposeRgn(RgnHandle rgn) ;
+extern void
+CopyRgn(
+ RgnHandle srcRgn,
+ RgnHandle dstRgn) ;
+extern void
+SetEmptyRgn(RgnHandle rgn) ;
+extern void
+SetRectRgn(
+ RgnHandle rgn,
+ short left,
+ short top,
+ short right,
+ short bottom) ;
+extern void
+RectRgn(
+ RgnHandle rgn,
+ const Rect * r) ;
+extern void
+OffsetRgn(
+ RgnHandle rgn,
+ short dh,
+ short dv) ;
+extern void
+InsetRgn(
+ RgnHandle rgn,
+ short dh,
+ short dv) ;
+extern void
+SectRgn(
+ RgnHandle srcRgnA,
+ RgnHandle srcRgnB,
+ RgnHandle dstRgn) ;
+extern void
+UnionRgn(
+ RgnHandle srcRgnA,
+ RgnHandle srcRgnB,
+ RgnHandle dstRgn) ;
+extern void
+DiffRgn(
+ RgnHandle srcRgnA,
+ RgnHandle srcRgnB,
+ RgnHandle dstRgn) ;
+extern void
+XorRgn(
+ RgnHandle srcRgnA,
+ RgnHandle srcRgnB,
+ RgnHandle dstRgn) ;
+extern Boolean
+RectInRgn(
+ const Rect * r,
+ RgnHandle rgn) ;
+extern Boolean
+EqualRgn(
+ RgnHandle rgnA,
+ RgnHandle rgnB) ;
+extern Boolean
+EmptyRgn(RgnHandle rgn) ;
+extern void
+FrameRgn(RgnHandle rgn) ;
+extern void
+PaintRgn(RgnHandle rgn) ;
+extern void
+EraseRgn(RgnHandle rgn) ;
+extern void
+InvertRgn(RgnHandle rgn) ;
+extern void
+FillRgn(
+ RgnHandle rgn,
+ const Pattern * pat) ;
+extern void
+ScrollRect(
+ const Rect * r,
+ short dh,
+ short dv,
+ RgnHandle updateRgn) ;
+extern void
+CopyBits(
+ const BitMap * srcBits,
+ const BitMap * dstBits,
+ const Rect * srcRect,
+ const Rect * dstRect,
+ short mode,
+ RgnHandle maskRgn) ;
+extern void
+SeedFill(
+ const void * srcPtr,
+ void * dstPtr,
+ short srcRow,
+ short dstRow,
+ short height,
+ short words,
+ short seedH,
+ short seedV) ;
+extern void
+CalcMask(
+ const void * srcPtr,
+ void * dstPtr,
+ short srcRow,
+ short dstRow,
+ short height,
+ short words) ;
+extern void
+CopyMask(
+ const BitMap * srcBits,
+ const BitMap * maskBits,
+ const BitMap * dstBits,
+ const Rect * srcRect,
+ const Rect * maskRect,
+ const Rect * dstRect) ;
+extern PicHandle
+OpenPicture(const Rect * picFrame) ;
+extern void
+PicComment(
+ short kind,
+ short dataSize,
+ Handle dataHandle) ;
+extern void
+ClosePicture(void) ;
+extern void
+DrawPicture(
+ PicHandle myPicture,
+ const Rect * dstRect) ;
+extern void
+KillPicture(PicHandle myPicture) ;
+extern PolyHandle
+OpenPoly(void) ;
+extern void
+ClosePoly(void) ;
+extern void
+KillPoly(PolyHandle poly) ;
+extern void
+OffsetPoly(
+ PolyHandle poly,
+ short dh,
+ short dv) ;
+extern void
+FramePoly(PolyHandle poly) ;
+extern void
+PaintPoly(PolyHandle poly) ;
+extern void
+ErasePoly(PolyHandle poly) ;
+extern void
+InvertPoly(PolyHandle poly) ;
+extern void
+FillPoly(
+ PolyHandle poly,
+ const Pattern * pat) ;
+extern void
+SetPt(
+ Point * pt,
+ short h,
+ short v) ;
+extern void
+LocalToGlobal(Point * pt) ;
+extern void
+GlobalToLocal(Point * pt) ;
+extern short
+Random(void) ;
+extern void
+StuffHex(
+ void * thingPtr,
+ ConstStr255Param s) ;
+extern Boolean
+GetPixel(
+ short h,
+ short v) ;
+extern void
+ScalePt(
+ Point * pt,
+ const Rect * srcRect,
+ const Rect * dstRect) ;
+extern void
+MapPt(
+ Point * pt,
+ const Rect * srcRect,
+ const Rect * dstRect) ;
+extern void
+MapRect(
+ Rect * r,
+ const Rect * srcRect,
+ const Rect * dstRect) ;
+extern void
+MapRgn(
+ RgnHandle rgn,
+ const Rect * srcRect,
+ const Rect * dstRect) ;
+extern void
+MapPoly(
+ PolyHandle poly,
+ const Rect * srcRect,
+ const Rect * dstRect) ;
+extern void
+SetStdProcs(QDProcs * procs) ;
+extern void
+StdRect(
+ GrafVerb verb,
+ const Rect * r) ;
+extern void
+StdRRect(
+ GrafVerb verb,
+ const Rect * r,
+ short ovalWidth,
+ short ovalHeight) ;
+extern void
+StdOval(
+ GrafVerb verb,
+ const Rect * r) ;
+extern void
+StdArc(
+ GrafVerb verb,
+ const Rect * r,
+ short startAngle,
+ short arcAngle) ;
+extern void
+StdPoly(
+ GrafVerb verb,
+ PolyHandle poly) ;
+extern void
+StdRgn(
+ GrafVerb verb,
+ RgnHandle rgn) ;
+extern void
+StdBits(
+ const BitMap * srcBits,
+ const Rect * srcRect,
+ const Rect * dstRect,
+ short mode,
+ RgnHandle maskRgn) ;
+extern void
+StdComment(
+ short kind,
+ short dataSize,
+ Handle dataHandle) ;
+extern void
+StdGetPic(
+ void * dataPtr,
+ short byteCount) ;
+extern void
+StdPutPic(
+ const void * dataPtr,
+ short byteCount) ;
+extern void
+StdOpcode(
+ const Rect * fromRect,
+ const Rect * toRect,
+ UInt16 opcode,
+ SInt16 version) ;
+extern void
+AddPt(
+ Point src,
+ Point * dst) ;
+extern Boolean
+EqualPt(
+ Point pt1,
+ Point pt2) ;
+extern Boolean
+PtInRect(
+ Point pt,
+ const Rect * r) ;
+extern void
+Pt2Rect(
+ Point pt1,
+ Point pt2,
+ Rect * dstRect) ;
+extern void
+PtToAngle(
+ const Rect * r,
+ Point pt,
+ short * angle) ;
+extern void
+SubPt(
+ Point src,
+ Point * dst) ;
+extern Boolean
+PtInRgn(
+ Point pt,
+ RgnHandle rgn) ;
+extern void
+StdLine(Point newPt) ;
+extern PixMapHandle
+NewPixMap(void) ;
+extern void
+DisposePixMap(PixMapHandle pm) ;
+extern void
+CopyPixMap(
+ PixMapHandle srcPM,
+ PixMapHandle dstPM) ;
+extern PixPatHandle
+NewPixPat(void) ;
+extern void
+DisposePixPat(PixPatHandle pp) ;
+extern void
+CopyPixPat(
+ PixPatHandle srcPP,
+ PixPatHandle dstPP) ;
+extern void
+PenPixPat(PixPatHandle pp) ;
+extern void
+BackPixPat(PixPatHandle pp) ;
+extern PixPatHandle
+GetPixPat(short patID) ;
+extern void
+MakeRGBPat(
+ PixPatHandle pp,
+ const RGBColor * myColor) ;
+extern void
+FillCRect(
+ const Rect * r,
+ PixPatHandle pp) ;
+extern void
+FillCOval(
+ const Rect * r,
+ PixPatHandle pp) ;
+extern void
+FillCRoundRect(
+ const Rect * r,
+ short ovalWidth,
+ short ovalHeight,
+ PixPatHandle pp) ;
+extern void
+FillCArc(
+ const Rect * r,
+ short startAngle,
+ short arcAngle,
+ PixPatHandle pp) ;
+extern void
+FillCRgn(
+ RgnHandle rgn,
+ PixPatHandle pp) ;
+extern void
+FillCPoly(
+ PolyHandle poly,
+ PixPatHandle pp) ;
+extern void
+RGBForeColor(const RGBColor * color) ;
+extern void
+RGBBackColor(const RGBColor * color) ;
+extern void
+SetCPixel(
+ short h,
+ short v,
+ const RGBColor * cPix) ;
+extern void
+SetPortPix(PixMapHandle pm) ;
+extern void
+GetCPixel(
+ short h,
+ short v,
+ RGBColor * cPix) ;
+extern void
+GetForeColor(RGBColor * color) ;
+extern void
+GetBackColor(RGBColor * color) ;
+extern void
+SeedCFill(
+ const BitMap * srcBits,
+ const BitMap * dstBits,
+ const Rect * srcRect,
+ const Rect * dstRect,
+ short seedH,
+ short seedV,
+ ColorSearchUPP matchProc,
+ long matchData) ;
+extern void
+CalcCMask(
+ const BitMap * srcBits,
+ const BitMap * dstBits,
+ const Rect * srcRect,
+ const Rect * dstRect,
+ const RGBColor * seedRGB,
+ ColorSearchUPP matchProc,
+ long matchData) ;
+extern PicHandle
+OpenCPicture(const OpenCPicParams * newHeader) ;
+extern void
+OpColor(const RGBColor * color) ;
+extern void
+HiliteColor(const RGBColor * color) ;
+extern void
+DisposeCTable(CTabHandle cTable) ;
+extern CTabHandle
+GetCTable(short ctID) ;
+extern CCrsrHandle
+GetCCursor(short crsrID) ;
+extern void
+SetCCursor(CCrsrHandle cCrsr) ;
+extern void
+AllocCursor(void) ;
+extern void
+DisposeCCursor(CCrsrHandle cCrsr) ;
+extern void
+SetStdCProcs(CQDProcs * procs) ;
+extern GDHandle
+GetMaxDevice(const Rect * globalRect) ;
+extern long
+GetCTSeed(void) ;
+extern GDHandle
+GetDeviceList(void) ;
+extern GDHandle
+GetMainDevice(void) ;
+extern GDHandle
+GetNextDevice(GDHandle curDevice) ;
+extern Boolean
+TestDeviceAttribute(
+ GDHandle gdh,
+ short attribute) ;
+extern void
+SetDeviceAttribute(
+ GDHandle gdh,
+ short attribute,
+ Boolean value) ;
+extern void
+InitGDevice(
+ short qdRefNum,
+ long mode,
+ GDHandle gdh) ;
+extern GDHandle
+NewGDevice(
+ short refNum,
+ long mode) ;
+extern void
+DisposeGDevice(GDHandle gdh) ;
+extern void
+SetGDevice(GDHandle gd) ;
+extern GDHandle
+GetGDevice(void) ;
+extern long
+Color2Index(const RGBColor * myColor) ;
+extern void
+Index2Color(
+ long index,
+ RGBColor * aColor) ;
+extern void
+InvertColor(RGBColor * myColor) ;
+extern Boolean
+RealColor(const RGBColor * color) ;
+extern void
+GetSubTable(
+ CTabHandle myColors,
+ short iTabRes,
+ CTabHandle targetTbl) ;
+extern void
+MakeITable(
+ CTabHandle cTabH,
+ ITabHandle iTabH,
+ short res) ;
+extern void
+AddSearch(ColorSearchUPP searchProc) ;
+extern void
+AddComp(ColorComplementUPP compProc) ;
+extern void
+DelSearch(ColorSearchUPP searchProc) ;
+extern void
+DelComp(ColorComplementUPP compProc) ;
+extern void
+SetClientID(short id) ;
+extern void
+ProtectEntry(
+ short index,
+ Boolean protect) ;
+extern void
+ReserveEntry(
+ short index,
+ Boolean reserve) ;
+extern void
+SetEntries(
+ short start,
+ short count,
+ CSpecArray aTable) ;
+extern void
+SaveEntries(
+ CTabHandle srcTable,
+ CTabHandle resultTable,
+ ReqListRec * selection) ;
+extern void
+RestoreEntries(
+ CTabHandle srcTable,
+ CTabHandle dstTable,
+ ReqListRec * selection) ;
+extern short
+QDError(void) ;
+extern void
+CopyDeepMask(
+ const BitMap * srcBits,
+ const BitMap * maskBits,
+ const BitMap * dstBits,
+ const Rect * srcRect,
+ const Rect * maskRect,
+ const Rect * dstRect,
+ short mode,
+ RgnHandle maskRgn) ;
+extern void
+DeviceLoop(
+ RgnHandle drawingRgn,
+ DeviceLoopDrawingUPP drawingProc,
+ long userData,
+ DeviceLoopFlags flags) ;
+extern Ptr
+GetMaskTable(void) ;
+extern PatHandle
+GetPattern(short patternID) ;
+extern CursHandle
+GetCursor(short cursorID) ;
+extern PicHandle
+GetPicture(short pictureID) ;
+extern long
+DeltaPoint(
+ Point ptA,
+ Point ptB) ;
+extern void
+ShieldCursor(
+ const Rect * shieldRect,
+ Point offsetPt) ;
+extern void
+ScreenRes(
+ short * scrnHRes,
+ short * scrnVRes) ;
+extern void
+GetIndPattern(
+ Pattern * thePat,
+ short patternListID,
+ short index) ;
+extern long
+deltapoint(
+ Point * ptA,
+ Point * ptB) ;
+extern void
+PackBits(
+ Ptr * srcPtr,
+ Ptr * dstPtr,
+ short srcBytes) ;
+extern void
+UnpackBits(
+ Ptr * srcPtr,
+ Ptr * dstPtr,
+ short dstBytes) ;
+extern Fixed
+SlopeFromAngle(short angle) ;
+extern short
+AngleFromSlope(Fixed slope) ;
+
+
+
+enum {
+ colorXorXFer = 52,
+ noiseXFer = 53,
+ customXFer = 54
+};
+
+
+enum {
+ kXFer1PixelAtATime = 0x00000001,
+ kXFerConvertPixelToRGB32 = 0x00000002
+};
+
+struct CustomXFerRec {
+ UInt32 version;
+ void * srcPixels;
+ void * destPixels;
+ void * resultPixels;
+ UInt32 refCon;
+ UInt32 pixelSize;
+ UInt32 pixelCount;
+ Point firstPixelHV;
+ Rect destBounds;
+};
+typedef struct CustomXFerRec CustomXFerRec;
+typedef CustomXFerRec * CustomXFerRecPtr;
+typedef void ( * CustomXFerProcPtr)(CustomXFerRecPtr info);
+extern OSErr
+GetPortCustomXFerProc(
+ CGrafPtr port,
+ CustomXFerProcPtr * proc,
+ UInt32 * flags,
+ UInt32 * refCon) ;
+extern OSErr
+SetPortCustomXFerProc(
+ CGrafPtr port,
+ CustomXFerProcPtr proc,
+ UInt32 flags,
+ UInt32 refCon) ;
+
+
+
+enum {
+ kCursorComponentsVersion = 0x00010001
+};
+
+enum {
+ kCursorComponentType = 'curs'
+};
+
+
+enum {
+ cursorDoesAnimate = 1L << 0,
+ cursorDoesHardware = 1L << 1,
+ cursorDoesUnreadableScreenBits = 1L << 2
+};
+
+
+enum {
+ kRenderCursorInHardware = 1L << 0,
+ kRenderCursorInSoftware = 1L << 1
+};
+
+
+struct CursorInfo {
+ long version;
+ long capabilities;
+ long animateDuration;
+ Rect bounds;
+ Point hotspot;
+ long reserved;
+
+};
+typedef struct CursorInfo CursorInfo;
+
+enum {
+ kCursorComponentInit = 0x0001,
+ kCursorComponentGetInfo = 0x0002,
+ kCursorComponentSetOutputMode = 0x0003,
+ kCursorComponentSetData = 0x0004,
+ kCursorComponentReconfigure = 0x0005,
+ kCursorComponentDraw = 0x0006,
+ kCursorComponentErase = 0x0007,
+ kCursorComponentMove = 0x0008,
+ kCursorComponentAnimate = 0x0009,
+ kCursorComponentLastReserved = 0x0050
+};
+extern OSErr
+OpenCursorComponent(
+ Component c,
+ ComponentInstance * ci) ;
+extern OSErr
+CloseCursorComponent(ComponentInstance ci) ;
+extern OSErr
+SetCursorComponent(ComponentInstance ci) ;
+extern OSErr
+CursorComponentChanged(ComponentInstance ci) ;
+extern OSErr
+CursorComponentSetData(
+ ComponentInstance ci,
+ long data) ;
+extern CMError
+CWMatchPixMap(
+ CMWorldRef cw,
+ PixMap * myPixMap,
+ CMBitmapCallBackUPP progressProc,
+ void * refCon) ;
+extern CMError
+CWCheckPixMap(
+ CMWorldRef cw,
+ PixMap * myPixMap,
+ CMBitmapCallBackUPP progressProc,
+ void * refCon,
+ BitMap * resultBitMap) ;
+extern CMError
+NCMBeginMatching(
+ CMProfileRef src,
+ CMProfileRef dst,
+ CMMatchRef * myRef) ;
+extern void
+CMEndMatching(CMMatchRef myRef) ;
+extern void
+NCMDrawMatchedPicture(
+ PicHandle myPicture,
+ CMProfileRef dst,
+ Rect * myRect) ;
+extern void
+CMEnableMatchingComment(Boolean enableIt) ;
+extern CMError
+NCMUseProfileComment(
+ CMProfileRef prof,
+ UInt32 flags) ;
+extern Boolean
+IsValidPort(CGrafPtr port) ;
+extern PixMapHandle
+GetPortPixMap(CGrafPtr port) ;
+extern const BitMap *
+GetPortBitMapForCopyBits(CGrafPtr port) ;
+extern Rect *
+GetPortBounds(
+ CGrafPtr port,
+ Rect * rect) ;
+extern RGBColor *
+GetPortForeColor(
+ CGrafPtr port,
+ RGBColor * foreColor) ;
+extern RGBColor *
+GetPortBackColor(
+ CGrafPtr port,
+ RGBColor * backColor) ;
+extern RGBColor *
+GetPortOpColor(
+ CGrafPtr port,
+ RGBColor * opColor) ;
+extern RGBColor *
+GetPortHiliteColor(
+ CGrafPtr port,
+ RGBColor * hiliteColor) ;
+extern CQDProcsPtr
+GetPortGrafProcs(CGrafPtr port) ;
+extern short
+GetPortTextFont(CGrafPtr port) ;
+extern Style
+GetPortTextFace(CGrafPtr port) ;
+extern short
+GetPortTextMode(CGrafPtr port) ;
+extern short
+GetPortTextSize(CGrafPtr port) ;
+extern short
+GetPortChExtra(CGrafPtr port) ;
+extern short
+GetPortFracHPenLocation(CGrafPtr port) ;
+extern Fixed
+GetPortSpExtra(CGrafPtr port) ;
+extern short
+GetPortPenVisibility(CGrafPtr port) ;
+extern RgnHandle
+GetPortVisibleRegion(
+ CGrafPtr port,
+ RgnHandle visRgn) ;
+extern RgnHandle
+GetPortClipRegion(
+ CGrafPtr port,
+ RgnHandle clipRgn) ;
+extern PixPatHandle
+GetPortBackPixPat(
+ CGrafPtr port,
+ PixPatHandle backPattern) ;
+extern PixPatHandle
+GetPortPenPixPat(
+ CGrafPtr port,
+ PixPatHandle penPattern) ;
+extern PixPatHandle
+GetPortFillPixPat(
+ CGrafPtr port,
+ PixPatHandle fillPattern) ;
+extern Point *
+GetPortPenSize(
+ CGrafPtr port,
+ Point * penSize) ;
+extern SInt32
+GetPortPenMode(CGrafPtr port) ;
+extern Point *
+GetPortPenLocation(
+ CGrafPtr port,
+ Point * penLocation) ;
+extern Boolean
+IsPortRegionBeingDefined(CGrafPtr port) ;
+extern Boolean
+IsPortPictureBeingDefined(CGrafPtr port) ;
+extern Boolean
+IsPortPolyBeingDefined(CGrafPtr port) ;
+extern Boolean
+IsPortOffscreen(CGrafPtr port) ;
+extern Boolean
+IsPortColor(CGrafPtr port) ;
+extern Boolean
+IsPortVisibleRegionEmpty(CGrafPtr port) ;
+extern Boolean
+IsPortClipRegionEmpty(CGrafPtr port) ;
+extern void
+SectRegionWithPortClipRegion(
+ CGrafPtr port,
+ RgnHandle ioRegion) ;
+extern void
+SectRegionWithPortVisibleRegion(
+ CGrafPtr port,
+ RgnHandle ioRegion) ;
+extern Handle
+SwapPortPicSaveHandle(
+ CGrafPtr port,
+ Handle inPicSaveHdl) ;
+extern Handle
+SwapPortPolySaveHandle(
+ CGrafPtr port,
+ Handle inPolySaveHdl) ;
+extern Handle
+SwapPortRegionSaveHandle(
+ CGrafPtr port,
+ Handle inRegionSaveHdl) ;
+extern void
+SetPortBounds(
+ CGrafPtr port,
+ const Rect * rect) ;
+extern void
+SetPortOpColor(
+ CGrafPtr port,
+ const RGBColor * opColor) ;
+extern void
+SetPortGrafProcs(
+ CGrafPtr port,
+ CQDProcsPtr procs) ;
+extern void
+SetPortTextFont(
+ CGrafPtr port,
+ short txFont) ;
+extern void
+SetPortTextSize(
+ CGrafPtr port,
+ short txSize) ;
+extern void
+SetPortTextFace(
+ CGrafPtr port,
+ StyleParameter face) ;
+extern void
+SetPortTextMode(
+ CGrafPtr port,
+ short mode) ;
+extern void
+SetPortVisibleRegion(
+ CGrafPtr port,
+ RgnHandle visRgn) ;
+extern void
+SetPortClipRegion(
+ CGrafPtr port,
+ RgnHandle clipRgn) ;
+extern void
+SetPortPenPixPat(
+ CGrafPtr port,
+ PixPatHandle penPattern) ;
+extern void
+SetPortFillPixPat(
+ CGrafPtr port,
+ PixPatHandle penPattern) ;
+extern void
+SetPortBackPixPat(
+ CGrafPtr port,
+ PixPatHandle backPattern) ;
+extern void
+SetPortPenSize(
+ CGrafPtr port,
+ Point penSize) ;
+extern void
+SetPortPenMode(
+ CGrafPtr port,
+ SInt32 penMode) ;
+extern void
+SetPortFracHPenLocation(
+ CGrafPtr port,
+ short pnLocHFrac) ;
+extern Rect *
+GetPixBounds(
+ PixMapHandle pixMap,
+ Rect * bounds) ;
+extern short
+GetPixDepth(PixMapHandle pixMap) ;
+extern long
+GetQDGlobalsRandomSeed(void) ;
+extern BitMap *
+GetQDGlobalsScreenBits(BitMap * screenBits) ;
+extern Cursor *
+GetQDGlobalsArrow(Cursor * arrow) ;
+extern Pattern *
+GetQDGlobalsDarkGray(Pattern * dkGray) ;
+extern Pattern *
+GetQDGlobalsLightGray(Pattern * ltGray) ;
+extern Pattern *
+GetQDGlobalsGray(Pattern * gray) ;
+extern Pattern *
+GetQDGlobalsBlack(Pattern * black) ;
+extern Pattern *
+GetQDGlobalsWhite(Pattern * white) ;
+extern CGrafPtr
+GetQDGlobalsThePort(void) ;
+extern void
+SetQDGlobalsRandomSeed(long randomSeed) ;
+extern void
+SetQDGlobalsArrow(const Cursor * arrow) ;
+extern Rect *
+GetRegionBounds(
+ RgnHandle region,
+ Rect * bounds) ;
+extern Boolean
+IsRegionRectangular(RgnHandle region) ;
+extern CGrafPtr
+CreateNewPort(void) ;
+extern void
+DisposePort(CGrafPtr port) ;
+extern void
+SetQDError(OSErr err) ;
+extern Point *
+QDLocalToGlobalPoint(
+ CGrafPtr port,
+ Point * point) ;
+extern Point *
+QDGlobalToLocalPoint(
+ CGrafPtr port,
+ Point * point) ;
+extern Rect *
+QDLocalToGlobalRect(
+ CGrafPtr port,
+ Rect * bounds) ;
+extern Rect *
+QDGlobalToLocalRect(
+ CGrafPtr port,
+ Rect * bounds) ;
+extern RgnHandle
+QDLocalToGlobalRegion(
+ CGrafPtr port,
+ RgnHandle region) ;
+extern RgnHandle
+QDGlobalToLocalRegion(
+ CGrafPtr port,
+ RgnHandle region) ;
+extern Boolean
+QDIsPortBuffered(CGrafPtr port) ;
+extern Boolean
+QDIsPortBufferDirty(CGrafPtr port) ;
+extern void
+QDFlushPortBuffer(
+ CGrafPtr port,
+ RgnHandle region) ;
+extern OSStatus
+QDGetDirtyRegion(
+ CGrafPtr port,
+ RgnHandle rgn) ;
+extern OSStatus
+QDSetDirtyRegion(
+ CGrafPtr port,
+ RgnHandle rgn) ;
+extern OSStatus
+QDAddRectToDirtyRegion(
+ CGrafPtr inPort,
+ const Rect * inBounds) ;
+extern OSStatus
+QDAddRegionToDirtyRegion(
+ CGrafPtr inPort,
+ RgnHandle inRegion) ;
+extern OSStatus
+CreateCGContextForPort(
+ CGrafPtr inPort,
+ CGContextRef * outContext) ;
+extern OSStatus
+ClipCGContextToRegion(
+ CGContextRef gc,
+ const Rect * portRect,
+ RgnHandle region) ;
+extern OSStatus
+SyncCGContextOriginWithPort(
+ CGContextRef inContext,
+ CGrafPtr port) ;
+extern OSStatus
+QDBeginCGContext(
+ CGrafPtr inPort,
+ CGContextRef * outContext) ;
+extern OSStatus
+QDEndCGContext(
+ CGrafPtr inPort,
+ CGContextRef * inoutContext) ;
+typedef struct OpaqueQDRegionBitsRef* QDRegionBitsRef;
+extern QDRegionBitsRef
+QDSaveRegionBits(RgnHandle region) ;
+extern OSStatus
+QDRestoreRegionBits(
+ RgnHandle region,
+ QDRegionBitsRef regionBits) ;
+extern OSStatus
+QDDisposeRegionBits(QDRegionBitsRef regionBits) ;
+extern CGrafPtr
+CreateNewPortForCGDisplayID(UInt32 inCGDisplayID) ;
+extern void
+QDDisplayWaitCursor(Boolean forceWaitCursor) ;
+extern void
+QDSetPatternOrigin(Point origin) ;
+extern void
+QDGetPatternOrigin(Point * origin) ;
+extern Boolean
+QDIsNamedPixMapCursorRegistered(const char name[128]) ;
+extern OSStatus
+QDRegisterNamedPixMapCursor(
+ PixMapHandle crsrData,
+ PixMapHandle crsrMask,
+ Point hotSpot,
+ const char name[128]) ;
+extern OSStatus
+QDUnregisterNamedPixMapCursur(const char name[128]) ;
+extern OSStatus
+QDSetNamedPixMapCursor(const char name[128]) ;
+extern OSStatus
+QDSetCursorScale(float scale) ;
+
+
+
+
+enum {
+ kQDUseDefaultTextRendering = 0,
+
+ kQDUseTrueTypeScalerGlyphs = (1 << 0),
+ kQDUseCGTextRendering = (1 << 1),
+ kQDUseCGTextMetrics = (1 << 2),
+ kQDSupportedFlags = kQDUseTrueTypeScalerGlyphs | kQDUseCGTextRendering | kQDUseCGTextMetrics,
+ kQDDontChangeFlags = (long)0xFFFFFFFF
+};
+extern UInt32
+QDSwapTextFlags(UInt32 newFlags) ;
+extern UInt32
+QDSwapPortTextFlags(
+ CGrafPtr port,
+ UInt32 newFlags) ;
+extern SInt16
+LMGetScrVRes(void) ;
+extern void
+LMSetScrVRes(SInt16 value) ;
+extern SInt16
+LMGetScrHRes(void) ;
+extern void
+LMSetScrHRes(SInt16 value) ;
+extern GDHandle
+LMGetMainDevice(void) ;
+extern void
+LMSetMainDevice(GDHandle value) ;
+extern GDHandle
+LMGetDeviceList(void) ;
+extern void
+LMSetDeviceList(GDHandle value) ;
+extern Handle
+LMGetQDColors(void) ;
+extern void
+LMSetQDColors(Handle value) ;
+extern Handle
+LMGetWidthListHand(void) ;
+extern void
+LMSetWidthListHand(Handle value) ;
+extern UInt8
+LMGetHiliteMode(void) ;
+extern void
+LMSetHiliteMode(UInt8 value) ;
+extern Ptr
+LMGetWidthPtr(void) ;
+extern void
+LMSetWidthPtr(Ptr value) ;
+extern Handle
+LMGetWidthTabHandle(void) ;
+extern void
+LMSetWidthTabHandle(Handle value) ;
+extern SInt32
+LMGetLastSPExtra(void) ;
+extern void
+LMSetLastSPExtra(SInt32 value) ;
+extern Handle
+LMGetLastFOND(void) ;
+extern void
+LMSetLastFOND(Handle value) ;
+extern UInt8
+LMGetFractEnable(void) ;
+extern void
+LMSetFractEnable(UInt8 value) ;
+extern GDHandle
+LMGetTheGDevice(void) ;
+extern void
+LMSetTheGDevice(GDHandle value) ;
+extern void
+LMGetHiliteRGB(RGBColor * hiliteRGBValue) ;
+extern void
+LMSetHiliteRGB(const RGBColor * hiliteRGBValue) ;
+extern Boolean
+LMGetCursorNew(void) ;
+extern void
+LMSetCursorNew(Boolean value) ;
+
+
+}
+
+
+
+extern "C" {
+
+
+enum {
+ pixPurgeBit = 0,
+ noNewDeviceBit = 1,
+ useTempMemBit = 2,
+ keepLocalBit = 3,
+ useDistantHdwrMemBit = 4,
+ useLocalHdwrMemBit = 5,
+ pixelsPurgeableBit = 6,
+ pixelsLockedBit = 7,
+ mapPixBit = 16,
+ newDepthBit = 17,
+ alignPixBit = 18,
+ newRowBytesBit = 19,
+ reallocPixBit = 20,
+ clipPixBit = 28,
+ stretchPixBit = 29,
+ ditherPixBit = 30,
+ gwFlagErrBit = 31
+};
+
+enum {
+ pixPurge = 1L << pixPurgeBit,
+ noNewDevice = 1L << noNewDeviceBit,
+ useTempMem = 1L << useTempMemBit,
+ keepLocal = 1L << keepLocalBit,
+ useDistantHdwrMem = 1L << useDistantHdwrMemBit,
+ useLocalHdwrMem = 1L << useLocalHdwrMemBit,
+ pixelsPurgeable = 1L << pixelsPurgeableBit,
+ pixelsLocked = 1L << pixelsLockedBit,
+ kAllocDirectDrawSurface = 1L << 14,
+ mapPix = 1L << mapPixBit,
+ newDepth = 1L << newDepthBit,
+ alignPix = 1L << alignPixBit,
+ newRowBytes = 1L << newRowBytesBit,
+ reallocPix = 1L << reallocPixBit,
+ clipPix = 1L << clipPixBit,
+ stretchPix = 1L << stretchPixBit,
+ ditherPix = 1L << ditherPixBit,
+ gwFlagErr = 1L << gwFlagErrBit
+};
+
+typedef unsigned long GWorldFlags;
+
+typedef CGrafPtr GWorldPtr;
+extern QDErr
+NewGWorld(
+ GWorldPtr * offscreenGWorld,
+ short PixelDepth,
+ const Rect * boundsRect,
+ CTabHandle cTable,
+ GDHandle aGDevice,
+ GWorldFlags flags) ;
+
+
+
+enum {
+ deviceIsIndirect = (1L << 0),
+ deviceNeedsLock = (1L << 1),
+ deviceIsStatic = (1L << 2),
+ deviceIsExternalBuffer = (1L << 3),
+ deviceIsDDSurface = (1L << 4),
+ deviceIsDCISurface = (1L << 5),
+ deviceIsGDISurface = (1L << 6),
+ deviceIsAScreen = (1L << 7),
+ deviceIsOverlaySurface = (1L << 8)
+};
+extern QDErr
+NewGWorldFromPtr(
+ GWorldPtr * offscreenGWorld,
+ unsigned long PixelFormat,
+ const Rect * boundsRect,
+ CTabHandle cTable,
+ GDHandle aGDevice,
+ GWorldFlags flags,
+ Ptr newBuffer,
+ long rowBytes) ;
+extern Boolean
+LockPixels(PixMapHandle pm) ;
+extern void
+UnlockPixels(PixMapHandle pm) ;
+extern GWorldFlags
+UpdateGWorld(
+ GWorldPtr * offscreenGWorld,
+ short pixelDepth,
+ const Rect * boundsRect,
+ CTabHandle cTable,
+ GDHandle aGDevice,
+ GWorldFlags flags) ;
+extern void
+DisposeGWorld(GWorldPtr offscreenGWorld) ;
+extern void
+GetGWorld(
+ CGrafPtr * port,
+ GDHandle * gdh) ;
+extern void
+SetGWorld(
+ CGrafPtr port,
+ GDHandle gdh) ;
+extern void
+CTabChanged(CTabHandle ctab) ;
+extern void
+PixPatChanged(PixPatHandle ppat) ;
+extern void
+PortChanged(GrafPtr port) ;
+extern void
+GDeviceChanged(GDHandle gdh) ;
+extern void
+AllowPurgePixels(PixMapHandle pm) ;
+extern void
+NoPurgePixels(PixMapHandle pm) ;
+extern GWorldFlags
+GetPixelsState(PixMapHandle pm) ;
+extern void
+SetPixelsState(
+ PixMapHandle pm,
+ GWorldFlags state) ;
+extern Ptr
+GetPixBaseAddr(PixMapHandle pm) ;
+extern long
+GetPixRowBytes(PixMapHandle pm) ;
+extern QDErr
+NewScreenBuffer(
+ const Rect * globalRect,
+ Boolean purgeable,
+ GDHandle * gdh,
+ PixMapHandle * offscreenPixMap) ;
+extern void
+DisposeScreenBuffer(PixMapHandle offscreenPixMap) ;
+extern GDHandle
+GetGWorldDevice(GWorldPtr offscreenGWorld) ;
+extern Boolean
+QDDone(GrafPtr port) ;
+extern long
+OffscreenVersion(void) ;
+extern QDErr
+NewTempScreenBuffer(
+ const Rect * globalRect,
+ Boolean purgeable,
+ GDHandle * gdh,
+ PixMapHandle * offscreenPixMap) ;
+extern Boolean
+PixMap32Bit(PixMapHandle pmHandle) ;
+extern PixMapHandle
+GetGWorldPixMap(GWorldPtr offscreenGWorld) ;
+
+
+
+
+}
+
+
+
+extern "C" {
+
+
+typedef struct QDPict* QDPictRef;
+extern QDPictRef
+QDPictCreateWithProvider(CGDataProviderRef provider) ;
+extern QDPictRef
+QDPictCreateWithURL(CFURLRef url) ;
+extern QDPictRef
+QDPictRetain(QDPictRef pictRef) ;
+extern void
+QDPictRelease(QDPictRef pictRef) ;
+extern CGRect
+QDPictGetBounds(QDPictRef pictRef) ;
+extern void
+QDPictGetResolution(
+ QDPictRef pictRef,
+ float * xRes,
+ float * yRes) ;
+extern OSStatus
+QDPictDrawToCGContext(
+ CGContextRef ctx,
+ CGRect rect,
+ QDPictRef pictRef) ;
+
+
+
+
+}
+
+
+
+
+
+
+
+extern "C" {
+
+
+
+enum {
+ systemFont = 0,
+ applFont = 1
+};
+
+enum {
+ kFMDefaultOptions = kNilOptions
+};
+
+
+enum {
+ kFMDefaultActivationContext = kFMDefaultOptions,
+ kFMGlobalActivationContext = 0x00000001,
+ kFMLocalActivationContext = kFMDefaultActivationContext
+};
+
+
+enum {
+ kFMDefaultIterationScope = kFMDefaultOptions,
+ kFMGlobalIterationScope = 0x00000001,
+ kFMLocalIterationScope = kFMDefaultIterationScope
+};
+
+
+
+enum {
+ kPlatformDefaultGuiFontID = applFont
+};
+
+enum {
+ commandMark = 17,
+ checkMark = 18,
+ diamondMark = 19,
+ appleMark = 20
+};
+
+enum {
+ propFont = 36864L,
+ prpFntH = 36865L,
+ prpFntW = 36866L,
+ prpFntHW = 36867L,
+ fixedFont = 45056L,
+ fxdFntH = 45057L,
+ fxdFntW = 45058L,
+ fxdFntHW = 45059L,
+ fontWid = 44208L
+};
+
+struct FMInput {
+ short family;
+ short size;
+ Style face;
+ Boolean needBits;
+ short device;
+ Point numer;
+ Point denom;
+};
+typedef struct FMInput FMInput;
+struct FMOutput {
+ short errNum;
+ Handle fontHandle;
+ UInt8 boldPixels;
+ UInt8 italicPixels;
+ UInt8 ulOffset;
+ UInt8 ulShadow;
+ UInt8 ulThick;
+ UInt8 shadowPixels;
+ SInt8 extra;
+ UInt8 ascent;
+ UInt8 descent;
+ UInt8 widMax;
+ SInt8 leading;
+ SInt8 curStyle;
+ Point numer;
+ Point denom;
+};
+typedef struct FMOutput FMOutput;
+typedef FMOutput * FMOutputPtr;
+typedef FMOutputPtr FMOutPtr;
+struct FMetricRec {
+ Fixed ascent;
+ Fixed descent;
+ Fixed leading;
+ Fixed widMax;
+ Handle wTabHandle;
+};
+typedef struct FMetricRec FMetricRec;
+typedef FMetricRec * FMetricRecPtr;
+typedef FMetricRecPtr * FMetricRecHandle;
+extern void
+GetFontName(
+ short familyID,
+ Str255 name) ;
+extern void
+GetFNum(
+ ConstStr255Param name,
+ short * familyID) ;
+extern Boolean
+RealFont(
+ short fontNum,
+ short size) ;
+extern FMOutPtr
+FMSwapFont(const FMInput * inRec) ;
+extern void
+SetFScaleDisable(Boolean fscaleDisable) ;
+extern void
+FontMetrics(FMetricRecPtr theMetrics) ;
+extern void
+SetFractEnable(Boolean fractEnable) ;
+extern short
+GetDefFontSize(void) ;
+extern Boolean
+IsOutline(
+ Point numer,
+ Point denom) ;
+extern void
+SetOutlinePreferred(Boolean outlinePreferred) ;
+extern Boolean
+GetOutlinePreferred(void) ;
+extern OSErr
+OutlineMetrics(
+ short byteCount,
+ const void * textPtr,
+ Point numer,
+ Point denom,
+ short * yMax,
+ short * yMin,
+ FixedPtr awArray,
+ FixedPtr lsbArray,
+ RectPtr boundsArray) ;
+extern void
+SetPreserveGlyph(Boolean preserveGlyph) ;
+extern Boolean
+GetPreserveGlyph(void) ;
+extern short
+GetSysFont(void) ;
+extern short
+GetAppFont(void) ;
+extern OSStatus
+SetAntiAliasedTextEnabled(
+ Boolean iEnable,
+ SInt16 iMinFontSize) ;
+extern Boolean
+IsAntiAliasedTextEnabled(SInt16 * oMinFontSize) ;
+extern void
+QDTextBounds(
+ short byteCount,
+ const void * textAddr,
+ Rect * bounds) ;
+extern OSErr
+FetchFontInfo(
+ SInt16 fontID,
+ SInt16 fontSize,
+ SInt16 fontStyle,
+ FontInfo * info) ;
+extern OSStatus
+FMCreateFontFamilyIterator(
+ const FMFilter * iFilter,
+ void * iRefCon,
+ OptionBits iOptions,
+ FMFontFamilyIterator * ioIterator) ;
+extern OSStatus
+FMDisposeFontFamilyIterator(FMFontFamilyIterator * ioIterator) ;
+extern OSStatus
+FMResetFontFamilyIterator(
+ const FMFilter * iFilter,
+ void * iRefCon,
+ OptionBits iOptions,
+ FMFontFamilyIterator * ioIterator) ;
+extern OSStatus
+FMGetNextFontFamily(
+ FMFontFamilyIterator * ioIterator,
+ FMFontFamily * oFontFamily) ;
+extern OSStatus
+FMCreateFontIterator(
+ const FMFilter * iFilter,
+ void * iRefCon,
+ OptionBits iOptions,
+ FMFontIterator * ioIterator) ;
+extern OSStatus
+FMDisposeFontIterator(FMFontIterator * ioIterator) ;
+extern OSStatus
+FMResetFontIterator(
+ const FMFilter * iFilter,
+ void * iRefCon,
+ OptionBits iOptions,
+ FMFontIterator * ioIterator) ;
+extern OSStatus
+FMGetNextFont(
+ FMFontIterator * ioIterator,
+ FMFont * oFont) ;
+extern OSStatus
+FMCreateFontFamilyInstanceIterator(
+ FMFontFamily iFontFamily,
+ FMFontFamilyInstanceIterator * ioIterator) ;
+extern OSStatus
+FMDisposeFontFamilyInstanceIterator(FMFontFamilyInstanceIterator * ioIterator) ;
+extern OSStatus
+FMResetFontFamilyInstanceIterator(
+ FMFontFamily iFontFamily,
+ FMFontFamilyInstanceIterator * ioIterator) ;
+extern OSStatus
+FMGetNextFontFamilyInstance(
+ FMFontFamilyInstanceIterator * ioIterator,
+ FMFont * oFont,
+ FMFontStyle * oStyle,
+ FMFontSize * oSize) ;
+extern FMFontFamily
+FMGetFontFamilyFromName(ConstStr255Param iName) ;
+extern OSStatus
+FMGetFontFamilyName(
+ FMFontFamily iFontFamily,
+ Str255 oName) ;
+extern OSStatus
+FMGetFontFamilyTextEncoding(
+ FMFontFamily iFontFamily,
+ TextEncoding * oTextEncoding) ;
+extern OSStatus
+FMGetFontFamilyGeneration(
+ FMFontFamily iFontFamily,
+ FMGeneration * oGeneration) ;
+extern OSStatus
+FMGetFontFormat(
+ FMFont iFont,
+ FourCharCode * oFormat) ;
+extern OSStatus
+FMGetFontTableDirectory(
+ FMFont iFont,
+ ByteCount iLength,
+ void * iBuffer,
+ ByteCount * oActualLength) ;
+extern OSStatus
+FMGetFontTable(
+ FMFont iFont,
+ FourCharCode iTag,
+ ByteOffset iOffset,
+ ByteCount iLength,
+ void * iBuffer,
+ ByteCount * oActualLength) ;
+extern OSStatus
+FMGetFontGeneration(
+ FMFont iFont,
+ FMGeneration * oGeneration) ;
+extern OSStatus
+FMGetFontContainer(
+ FMFont iFont,
+ FSSpec * oFontContainer) ;
+extern OSStatus
+FMGetFontFromFontFamilyInstance(
+ FMFontFamily iFontFamily,
+ FMFontStyle iStyle,
+ FMFont * oFont,
+ FMFontStyle * oIntrinsicStyle) ;
+extern OSStatus
+FMGetFontFamilyInstanceFromFont(
+ FMFont iFont,
+ FMFontFamily * oFontFamily,
+ FMFontStyle * oStyle) ;
+extern ATSFontRef
+FMGetATSFontRefFromFont(FMFont iFont) ;
+extern ATSFontFamilyRef
+FMGetATSFontFamilyRefFromFontFamily(FMFontFamily iFamily) ;
+extern FMFont
+FMGetFontFromATSFontRef(ATSFontRef iFont) ;
+extern FMFontFamily
+FMGetFontFamilyFromATSFontFamilyRef(ATSFontFamilyRef iFamily) ;
+extern OSStatus
+FMActivateFonts(
+ const FSSpec * iFontContainer,
+ const FMFilter * iFilter,
+ void * iRefCon,
+ OptionBits iOptions) ;
+extern OSStatus
+FMDeactivateFonts(
+ const FSSpec * iFontContainer,
+ const FMFilter * iFilter,
+ void * iRefCon,
+ OptionBits iOptions) ;
+extern FMGeneration
+FMGetGeneration(void) ;
+extern OSStatus
+FMGetFontContainerFromFontFamilyInstance(
+ FMFontFamily iFontFamily,
+ FMFontStyle iStyle,
+ FMFontSize iFontSize,
+ FSSpec * oFontContainer) ;
+extern OSStatus
+FMGetFontFamilyResource(
+ FMFontFamily iFontFamily,
+ FMFontStyle iFontStyle,
+ FMFontSize iFontSize,
+ ByteCount iBufferSize,
+ void * ioBuffer,
+ ByteCount * oSize) ;
+
+
+
+typedef FMFontFamily FontFamilyID;
+typedef FMFontSize FontPointSize;
+
+
+
+
+
+
+enum {
+ kFMUseGlobalScopeOption = 0x00000001
+};
+
+enum {
+ kFontIDNewYork = 2,
+ kFontIDGeneva = 3,
+ kFontIDMonaco = 4,
+ kFontIDVenice = 5,
+ kFontIDLondon = 6,
+ kFontIDAthens = 7,
+ kFontIDSanFrancisco = 8,
+ kFontIDToronto = 9,
+ kFontIDCairo = 11,
+ kFontIDLosAngeles = 12,
+ kFontIDTimes = 20,
+ kFontIDHelvetica = 21,
+ kFontIDCourier = 22,
+ kFontIDSymbol = 23,
+ kFontIDMobile = 24
+};
+struct WidEntry {
+ short widStyle;
+};
+typedef struct WidEntry WidEntry;
+struct WidTable {
+ short numWidths;
+};
+typedef struct WidTable WidTable;
+struct AsscEntry {
+ short fontSize;
+ short fontStyle;
+ short fontID;
+};
+typedef struct AsscEntry AsscEntry;
+struct FontAssoc {
+ short numAssoc;
+};
+typedef struct FontAssoc FontAssoc;
+struct StyleTable {
+ short fontClass;
+ long offset;
+ long reserved;
+ char indexes[48];
+};
+typedef struct StyleTable StyleTable;
+struct NameTable {
+ short stringCount;
+ Str255 baseFontName;
+};
+typedef struct NameTable NameTable;
+struct KernPair {
+ char kernFirst;
+ char kernSecond;
+ short kernWidth;
+};
+typedef struct KernPair KernPair;
+struct KernEntry {
+ short kernStyle;
+ short kernLength;
+};
+typedef struct KernEntry KernEntry;
+struct KernTable {
+ short numKerns;
+};
+typedef struct KernTable KernTable;
+struct WidthTable {
+ Fixed tabData[256];
+ Handle tabFont;
+ long sExtra;
+ long style;
+ short fID;
+ short fSize;
+ short face;
+ short device;
+ Point inNumer;
+ Point inDenom;
+ short aFID;
+ Handle fHand;
+ Boolean usedFam;
+ UInt8 aFace;
+ short vOutput;
+ short hOutput;
+ short vFactor;
+ short hFactor;
+ short aSize;
+ short tabSize;
+};
+typedef struct WidthTable WidthTable;
+typedef WidthTable * WidthTablePtr;
+typedef WidthTablePtr * WidthTableHdl;
+struct FamRec {
+ short ffFlags;
+ short ffFamID;
+ short ffFirstChar;
+ short ffLastChar;
+ short ffAscent;
+ short ffDescent;
+ short ffLeading;
+ short ffWidMax;
+ long ffWTabOff;
+ long ffKernOff;
+ long ffStylOff;
+ short ffProperty[9];
+ short ffIntl[2];
+ short ffVersion;
+};
+typedef struct FamRec FamRec;
+struct FontRec {
+ short fontType;
+ short firstChar;
+ short lastChar;
+ short widMax;
+ short kernMax;
+ short nDescent;
+ short fRectWidth;
+ short fRectHeight;
+ unsigned short owTLoc;
+ short ascent;
+ short descent;
+ short leading;
+ short rowWords;
+};
+typedef struct FontRec FontRec;
+typedef FontRec * FontRecPtr;
+typedef FontRecPtr * FontRecHdl;
+
+
+}
+
+
+
+extern "C" {
+
+
+
+enum {
+ pmCourteous = 0,
+ pmDithered = 0x0001,
+ pmTolerant = 0x0002,
+ pmAnimated = 0x0004,
+ pmExplicit = 0x0008,
+ pmWhite = 0x0010,
+ pmBlack = 0x0020,
+ pmInhibitG2 = 0x0100,
+ pmInhibitC2 = 0x0200,
+ pmInhibitG4 = 0x0400,
+ pmInhibitC4 = 0x0800,
+ pmInhibitG8 = 0x1000,
+ pmInhibitC8 = 0x2000,
+ pmNoUpdates = 0x8000,
+ pmBkUpdates = 0xA000,
+ pmFgUpdates = 0xC000,
+ pmAllUpdates = 0xE000
+};
+
+struct ColorInfo {
+ RGBColor ciRGB;
+ short ciUsage;
+ short ciTolerance;
+ short ciDataFields[3];
+};
+typedef struct ColorInfo ColorInfo;
+typedef ColorInfo * ColorInfoPtr;
+typedef ColorInfoPtr * ColorInfoHandle;
+struct Palette {
+ short pmEntries;
+ short pmDataFields[7];
+ ColorInfo pmInfo[1];
+};
+typedef struct Palette Palette;
+typedef Palette * PalettePtr;
+typedef PalettePtr * PaletteHandle;
+extern void
+InitPalettes(void) ;
+extern PaletteHandle
+NewPalette(
+ short entries,
+ CTabHandle srcColors,
+ short srcUsage,
+ short srcTolerance) ;
+extern PaletteHandle
+GetNewPalette(short PaletteID) ;
+extern void
+DisposePalette(PaletteHandle srcPalette) ;
+extern void
+ActivatePalette(WindowRef srcWindow) ;
+extern void
+SetPalette(
+ WindowRef dstWindow,
+ PaletteHandle srcPalette,
+ Boolean cUpdates) ;
+extern void
+NSetPalette(
+ WindowRef dstWindow,
+ PaletteHandle srcPalette,
+ short nCUpdates) ;
+extern PaletteHandle
+GetPalette(WindowRef srcWindow) ;
+extern void
+CopyPalette(
+ PaletteHandle srcPalette,
+ PaletteHandle dstPalette,
+ short srcEntry,
+ short dstEntry,
+ short dstLength) ;
+extern void
+PmForeColor(short dstEntry) ;
+extern void
+PmBackColor(short dstEntry) ;
+extern void
+AnimateEntry(
+ WindowRef dstWindow,
+ short dstEntry,
+ const RGBColor * srcRGB) ;
+extern void
+AnimatePalette(
+ WindowRef dstWindow,
+ CTabHandle srcCTab,
+ short srcIndex,
+ short dstEntry,
+ short dstLength) ;
+extern void
+GetEntryColor(
+ PaletteHandle srcPalette,
+ short srcEntry,
+ RGBColor * dstRGB) ;
+extern void
+SetEntryColor(
+ PaletteHandle dstPalette,
+ short dstEntry,
+ const RGBColor * srcRGB) ;
+extern void
+GetEntryUsage(
+ PaletteHandle srcPalette,
+ short srcEntry,
+ short * dstUsage,
+ short * dstTolerance) ;
+extern void
+SetEntryUsage(
+ PaletteHandle dstPalette,
+ short dstEntry,
+ short srcUsage,
+ short srcTolerance) ;
+extern void
+CTab2Palette(
+ CTabHandle srcCTab,
+ PaletteHandle dstPalette,
+ short srcUsage,
+ short srcTolerance) ;
+extern void
+Palette2CTab(
+ PaletteHandle srcPalette,
+ CTabHandle dstCTab) ;
+extern long
+Entry2Index(short entry) ;
+extern void
+RestoreDeviceClut(GDHandle gd) ;
+extern void
+ResizePalette(
+ PaletteHandle p,
+ short size) ;
+extern void
+SaveFore(ColorSpec * c) ;
+extern void
+SaveBack(ColorSpec * c) ;
+extern void
+RestoreFore(const ColorSpec * c) ;
+extern void
+RestoreBack(const ColorSpec * c) ;
+extern OSErr
+SetDepth(
+ GDHandle gd,
+ short depth,
+ short whichFlags,
+ short flags) ;
+extern short
+HasDepth(
+ GDHandle gd,
+ short depth,
+ short whichFlags,
+ short flags) ;
+extern short
+PMgrVersion(void) ;
+extern void
+SetPaletteUpdates(
+ PaletteHandle p,
+ short updates) ;
+extern short
+GetPaletteUpdates(PaletteHandle p) ;
+extern Boolean
+GetGray(
+ GDHandle device,
+ const RGBColor * backGround,
+ RGBColor * foreGround) ;
+
+
+
+
+
+
+
+}
+
+
+
+extern "C" {
+
+
+
+
+enum {
+ returnColorTable = 0x0001,
+ returnPalette = 0x0002,
+ recordComments = 0x0004,
+ recordFontInfo = 0x0008,
+ suppressBlackAndWhite = 0x0010
+};
+
+enum {
+
+ systemMethod = 0,
+ popularMethod = 1,
+ medianMethod = 2
+};
+
+enum {
+
+ ColorBankIsCustom = -1,
+ ColorBankIsExactAnd555 = 0,
+ ColorBankIs555 = 1
+};
+
+typedef long PictInfoID;
+struct CommentSpec {
+ short count;
+ short ID;
+};
+typedef struct CommentSpec CommentSpec;
+typedef CommentSpec * CommentSpecPtr;
+typedef CommentSpecPtr * CommentSpecHandle;
+struct FontSpec {
+ short pictFontID;
+ short sysFontID;
+ long size[4];
+ short style;
+ long nameOffset;
+};
+typedef struct FontSpec FontSpec;
+typedef FontSpec * FontSpecPtr;
+typedef FontSpecPtr * FontSpecHandle;
+struct PictInfo {
+ short version;
+ long uniqueColors;
+ PaletteHandle thePalette;
+ CTabHandle theColorTable;
+ Fixed hRes;
+ Fixed vRes;
+ short depth;
+ Rect sourceRect;
+ long textCount;
+ long lineCount;
+ long rectCount;
+ long rRectCount;
+ long ovalCount;
+ long arcCount;
+ long polyCount;
+ long regionCount;
+ long bitMapCount;
+ long pixMapCount;
+ long commentCount;
+ long uniqueComments;
+ CommentSpecHandle commentHandle;
+ long uniqueFonts;
+ FontSpecHandle fontHandle;
+ Handle fontNamesHandle;
+ long reserved1;
+ long reserved2;
+};
+typedef struct PictInfo PictInfo;
+typedef PictInfo * PictInfoPtr;
+typedef PictInfoPtr * PictInfoHandle;
+typedef OSErr ( * InitPickMethodProcPtr)(SInt16 colorsRequested, UInt32 *dataRef, SInt16 *colorBankType);
+typedef OSErr ( * RecordColorsProcPtr)(UInt32 dataRef, RGBColor *colorsArray, SInt32 colorCount, SInt32 *uniqueColors);
+typedef OSErr ( * CalcColorTableProcPtr)(UInt32 dataRef, SInt16 colorsRequested, void *colorBankPtr, CSpecArray resultPtr);
+typedef OSErr ( * DisposeColorPickMethodProcPtr)(UInt32 dataRef);
+typedef InitPickMethodProcPtr InitPickMethodUPP;
+typedef RecordColorsProcPtr RecordColorsUPP;
+typedef CalcColorTableProcPtr CalcColorTableUPP;
+typedef DisposeColorPickMethodProcPtr DisposeColorPickMethodUPP;
+extern InitPickMethodUPP
+NewInitPickMethodUPP(InitPickMethodProcPtr userRoutine) ;
+extern RecordColorsUPP
+NewRecordColorsUPP(RecordColorsProcPtr userRoutine) ;
+extern CalcColorTableUPP
+NewCalcColorTableUPP(CalcColorTableProcPtr userRoutine) ;
+extern DisposeColorPickMethodUPP
+NewDisposeColorPickMethodUPP(DisposeColorPickMethodProcPtr userRoutine) ;
+extern void
+DisposeInitPickMethodUPP(InitPickMethodUPP userUPP) ;
+extern void
+DisposeRecordColorsUPP(RecordColorsUPP userUPP) ;
+extern void
+DisposeCalcColorTableUPP(CalcColorTableUPP userUPP) ;
+extern void
+DisposeDisposeColorPickMethodUPP(DisposeColorPickMethodUPP userUPP) ;
+extern OSErr
+InvokeInitPickMethodUPP(
+ SInt16 colorsRequested,
+ UInt32 * dataRef,
+ SInt16 * colorBankType,
+ InitPickMethodUPP userUPP) ;
+extern OSErr
+InvokeRecordColorsUPP(
+ UInt32 dataRef,
+ RGBColor * colorsArray,
+ SInt32 colorCount,
+ SInt32 * uniqueColors,
+ RecordColorsUPP userUPP) ;
+extern OSErr
+InvokeCalcColorTableUPP(
+ UInt32 dataRef,
+ SInt16 colorsRequested,
+ void * colorBankPtr,
+ CSpecArray resultPtr,
+ CalcColorTableUPP userUPP) ;
+extern OSErr
+InvokeDisposeColorPickMethodUPP(
+ UInt32 dataRef,
+ DisposeColorPickMethodUPP userUPP) ;
+extern OSErr
+GetPictInfo(
+ PicHandle thePictHandle,
+ PictInfo * thePictInfo,
+ short verb,
+ short colorsRequested,
+ short colorPickMethod,
+ short version) ;
+extern OSErr
+GetPixMapInfo(
+ PixMapHandle thePixMapHandle,
+ PictInfo * thePictInfo,
+ short verb,
+ short colorsRequested,
+ short colorPickMethod,
+ short version) ;
+extern OSErr
+NewPictInfo(
+ PictInfoID * thePictInfoID,
+ short verb,
+ short colorsRequested,
+ short colorPickMethod,
+ short version) ;
+extern OSErr
+RecordPictInfo(
+ PictInfoID thePictInfoID,
+ PicHandle thePictHandle) ;
+extern OSErr
+RecordPixMapInfo(
+ PictInfoID thePictInfoID,
+ PixMapHandle thePixMapHandle) ;
+extern OSErr
+RetrievePictInfo(
+ PictInfoID thePictInfoID,
+ PictInfo * thePictInfo,
+ short colorsRequested) ;
+extern OSErr
+DisposePictInfo(PictInfoID thePictInfoID) ;
+
+
+}
+
+
+
+extern "C" {
+
+
+typedef Fixed ATSUTextMeasurement;
+
+
+
+
+
+
+
+typedef FMFont ATSUFontID;
+
+
+
+
+typedef UInt16 ATSUFontFeatureType;
+typedef UInt16 ATSUFontFeatureSelector;
+
+
+
+
+typedef FourCharCode ATSUFontVariationAxis;
+typedef Fixed ATSUFontVariationValue;
+
+
+
+
+
+typedef struct OpaqueATSUTextLayout* ATSUTextLayout;
+
+
+
+
+
+typedef struct OpaqueATSUStyle* ATSUStyle;
+
+
+
+
+
+typedef struct OpaqueATSUFontFallbacks* ATSUFontFallbacks;
+typedef UInt32 ATSUAttributeTag;
+enum {
+
+ kATSULineWidthTag = 1L,
+
+ kATSULineRotationTag = 2L,
+
+ kATSULineDirectionTag = 3L,
+
+ kATSULineJustificationFactorTag = 4L,
+
+ kATSULineFlushFactorTag = 5L,
+
+ kATSULineBaselineValuesTag = 6L,
+
+ kATSULineLayoutOptionsTag = 7L,
+
+ kATSULineAscentTag = 8L,
+
+ kATSULineDescentTag = 9L,
+
+ kATSULineLangRegionTag = 10L,
+
+ kATSULineTextLocatorTag = 11L,
+
+ kATSULineTruncationTag = 12L,
+
+ kATSULineFontFallbacksTag = 13L,
+
+ kATSULayoutOperationOverrideTag = 15L,
+
+ kATSUMaxLineTag = 16L,
+
+ kATSULineLanguageTag = 10L,
+
+ kATSUCGContextTag = 32767L,
+
+
+
+ kATSUQDBoldfaceTag = 256L,
+
+ kATSUQDItalicTag = 257L,
+
+ kATSUQDUnderlineTag = 258L,
+
+ kATSUQDCondensedTag = 259L,
+
+ kATSUQDExtendedTag = 260L,
+
+
+ kATSUFontTag = 261L,
+
+ kATSUSizeTag = 262L,
+
+ kATSUColorTag = 263L,
+
+
+ kATSULangRegionTag = 264L,
+
+ kATSUVerticalCharacterTag = 265L,
+
+ kATSUImposeWidthTag = 266L,
+
+ kATSUBeforeWithStreamShiftTag = 267L,
+
+ kATSUAfterWithStreamShiftTag = 268L,
+
+ kATSUCrossStreamShiftTag = 269L,
+
+ kATSUTrackingTag = 270L,
+
+ kATSUHangingInhibitFactorTag = 271L,
+
+ kATSUKerningInhibitFactorTag = 272L,
+
+ kATSUDecompositionFactorTag = 273L,
+
+ kATSUBaselineClassTag = 274L,
+
+ kATSUPriorityJustOverrideTag = 275L,
+
+ kATSUNoLigatureSplitTag = 276L,
+
+ kATSUNoCaretAngleTag = 277L,
+
+ kATSUSuppressCrossKerningTag = 278L,
+
+ kATSUNoOpticalAlignmentTag = 279L,
+
+ kATSUForceHangingTag = 280L,
+
+ kATSUNoSpecialJustificationTag = 281L,
+
+ kATSUStyleTextLocatorTag = 282L,
+
+ kATSUStyleRenderingOptionsTag = 283L,
+
+ kATSUAscentTag = 284L,
+
+ kATSUDescentTag = 285L,
+
+ kATSULeadingTag = 286L,
+
+ kATSUGlyphSelectorTag = 287L,
+
+ kATSURGBAlphaColorTag = 288L,
+
+ kATSUFontMatrixTag = 289L,
+
+ kATSUMaxStyleTag = 290L,
+
+ kATSULanguageTag = 264L,
+
+ kATSUMaxATSUITagValue = 65535L
+};
+
+
+
+
+
+
+typedef void * ATSUAttributeValuePtr;
+typedef const void * ConstATSUAttributeValuePtr;
+struct ATSUAttributeInfo {
+ ATSUAttributeTag fTag;
+ ByteCount fValueSize;
+};
+typedef struct ATSUAttributeInfo ATSUAttributeInfo;
+struct ATSUCaret {
+ Fixed fX;
+ Fixed fY;
+ Fixed fDeltaX;
+ Fixed fDeltaY;
+};
+typedef struct ATSUCaret ATSUCaret;
+
+
+
+
+
+
+typedef UInt16 ATSUCursorMovementType;
+enum {
+ kATSUByCharacter = 0,
+ kATSUByTypographicCluster = 1,
+ kATSUByWord = 2,
+ kATSUByCharacterCluster = 3,
+ kATSUByCluster = 1
+};
+
+
+
+
+
+typedef UInt32 ATSULineTruncation;
+enum {
+ kATSUTruncateNone = 0,
+ kATSUTruncateStart = 1,
+ kATSUTruncateEnd = 2,
+ kATSUTruncateMiddle = 3,
+ kATSUTruncateSpecificationMask = 0x00000007,
+
+ kATSUTruncFeatNoSquishing = 0x00000008
+};
+
+
+
+
+
+
+typedef UInt16 ATSUVerticalCharacterType;
+enum {
+ kATSUStronglyHorizontal = 0,
+ kATSUStronglyVertical = 1
+};
+
+
+
+
+
+
+
+typedef UInt16 ATSUStyleComparison;
+enum {
+ kATSUStyleUnequal = 0,
+ kATSUStyleContains = 1,
+ kATSUStyleEquals = 2,
+ kATSUStyleContainedBy = 3
+};
+typedef UInt16 ATSUFontFallbackMethod;
+enum {
+ kATSUDefaultFontFallbacks = 0,
+ kATSULastResortOnlyFallback = 1,
+ kATSUSequentialFallbacksPreferred = 2,
+ kATSUSequentialFallbacksExclusive = 3
+};
+typedef UInt16 ATSUTabType;
+enum {
+ kATSULeftTab = 0,
+ kATSUCenterTab = 1,
+ kATSURightTab = 2,
+ kATSUNumberTabTypes = 3
+};
+
+
+
+
+
+
+struct ATSUTab {
+ ATSUTextMeasurement tabPosition;
+ ATSUTabType tabType;
+};
+typedef struct ATSUTab ATSUTab;
+
+
+
+
+
+
+typedef UInt16 GlyphCollection;
+enum {
+ kGlyphCollectionGID = 0,
+ kGlyphCollectionAdobeCNS1 = 1,
+ kGlyphCollectionAdobeGB1 = 2,
+ kGlyphCollectionAdobeJapan1 = 3,
+ kGlyphCollectionAdobeJapan2 = 4,
+ kGlyphCollectionAdobeKorea1 = 5,
+ kGlyphCollectionUnspecified = 0xFF
+};
+
+
+
+
+
+
+struct ATSUGlyphSelector {
+ GlyphCollection collection;
+ GlyphID glyphID;
+};
+typedef struct ATSUGlyphSelector ATSUGlyphSelector;
+struct ATSUGlyphInfo {
+ GlyphID glyphID;
+ UInt16 reserved;
+ UInt32 layoutFlags;
+ UniCharArrayOffset charIndex;
+ ATSUStyle style;
+ Float32 deltaY;
+ Float32 idealX;
+ SInt16 screenX;
+ SInt16 caretX;
+};
+typedef struct ATSUGlyphInfo ATSUGlyphInfo;
+struct ATSUGlyphInfoArray {
+ ATSUTextLayout layout;
+ ItemCount numGlyphs;
+ ATSUGlyphInfo glyphs[1];
+};
+typedef struct ATSUGlyphInfoArray ATSUGlyphInfoArray;
+
+
+
+typedef UInt32 ATSUHighlightMethod;
+enum {
+ kInvertHighlighting = 0,
+ kRedrawHighlighting = 1
+};
+
+typedef UInt32 ATSUBackgroundDataType;
+enum {
+ kATSUBackgroundColor = 0,
+ kATSUBackgroundCallback = 1
+};
+
+struct ATSURGBAlphaColor {
+ float red;
+ float green;
+ float blue;
+ float alpha;
+};
+typedef struct ATSURGBAlphaColor ATSURGBAlphaColor;
+typedef ATSURGBAlphaColor ATSUBackgroundColor;
+typedef Boolean ( * RedrawBackgroundProcPtr)(ATSUTextLayout iLayout, UniCharArrayOffset iTextOffset, UniCharCount iTextLength, ATSTrapezoid iUnhighlightArea[], ItemCount iTrapezoidCount);
+typedef RedrawBackgroundProcPtr RedrawBackgroundUPP;
+extern RedrawBackgroundUPP
+NewRedrawBackgroundUPP(RedrawBackgroundProcPtr userRoutine) ;
+extern void
+DisposeRedrawBackgroundUPP(RedrawBackgroundUPP userUPP) ;
+extern Boolean
+InvokeRedrawBackgroundUPP(
+ ATSUTextLayout iLayout,
+ UniCharArrayOffset iTextOffset,
+ UniCharCount iTextLength,
+ ATSTrapezoid iUnhighlightArea[],
+ ItemCount iTrapezoidCount,
+ RedrawBackgroundUPP userUPP) ;
+
+union ATSUBackgroundData {
+ ATSUBackgroundColor backgroundColor;
+ RedrawBackgroundUPP backgroundUPP;
+};
+typedef union ATSUBackgroundData ATSUBackgroundData;
+struct ATSUUnhighlightData {
+ ATSUBackgroundDataType dataType;
+ ATSUBackgroundData unhighlightData;
+};
+typedef struct ATSUUnhighlightData ATSUUnhighlightData;
+
+
+
+
+enum {
+ kATSULeftToRightBaseDirection = 0,
+ kATSURightToLeftBaseDirection = 1
+};
+enum {
+ kATSUInvalidFontID = 0
+};
+
+
+enum {
+ kATSUUseLineControlWidth = 0x7FFFFFFF
+};
+
+
+enum {
+ kATSUNoSelector = 0x0000FFFF
+};
+
+
+enum {
+ kATSUUseGrafPortPenLoc = (unsigned long)0xFFFFFFFF,
+ kATSUClearAll = (unsigned long)0xFFFFFFFF
+};
+
+
+enum {
+ kATSUFromTextBeginning = (unsigned long)0xFFFFFFFF,
+ kATSUToTextEnd = (unsigned long)0xFFFFFFFF
+};
+extern OSStatus
+ATSUCopyToHandle(
+ ATSUStyle iStyle,
+ Handle oStyleHandle) ;
+extern OSStatus
+ATSUPasteFromHandle(
+ ATSUStyle iStyle,
+ Handle iStyleHandle) ;
+extern OSStatus
+ATSUCreateFontFallbacks(ATSUFontFallbacks * oFontFallback) ;
+extern OSStatus
+ATSUDisposeFontFallbacks(ATSUFontFallbacks iFontFallbacks) ;
+extern OSStatus
+ATSUSetObjFontFallbacks(
+ ATSUFontFallbacks iFontFallbacks,
+ ItemCount iFontFallbacksCount,
+ const ATSUFontID iFonts[],
+ ATSUFontFallbackMethod iFontFallbackMethod) ;
+extern OSStatus
+ATSUGetObjFontFallbacks(
+ ATSUFontFallbacks iFontFallbacks,
+ ItemCount iMaxFontFallbacksCount,
+ ATSUFontID oFonts[],
+ ATSUFontFallbackMethod * oFontFallbackMethod,
+ ItemCount * oActualFallbacksCount) ;
+extern OSStatus
+ATSUCreateStyle(ATSUStyle * oStyle) ;
+extern OSStatus
+ATSUCreateAndCopyStyle(
+ ATSUStyle iStyle,
+ ATSUStyle * oStyle) ;
+extern OSStatus
+ATSUDisposeStyle(ATSUStyle iStyle) ;
+extern OSStatus
+ATSUSetStyleRefCon(
+ ATSUStyle iStyle,
+ UInt32 iRefCon) ;
+extern OSStatus
+ATSUGetStyleRefCon(
+ ATSUStyle iStyle,
+ UInt32 * oRefCon) ;
+extern OSStatus
+ATSUCompareStyles(
+ ATSUStyle iFirstStyle,
+ ATSUStyle iSecondStyle,
+ ATSUStyleComparison * oComparison) ;
+extern OSStatus
+ATSUCopyAttributes(
+ ATSUStyle iSourceStyle,
+ ATSUStyle iDestinationStyle) ;
+extern OSStatus
+ATSUOverwriteAttributes(
+ ATSUStyle iSourceStyle,
+ ATSUStyle iDestinationStyle) ;
+extern OSStatus
+ATSUUnderwriteAttributes(
+ ATSUStyle iSourceStyle,
+ ATSUStyle iDestinationStyle) ;
+extern OSStatus
+ATSUClearStyle(ATSUStyle iStyle) ;
+extern OSStatus
+ATSUStyleIsEmpty(
+ ATSUStyle iStyle,
+ Boolean * oIsClear) ;
+extern OSStatus
+ATSUCalculateBaselineDeltas(
+ ATSUStyle iStyle,
+ BslnBaselineClass iBaselineClass,
+ BslnBaselineRecord oBaselineDeltas) ;
+extern OSStatus
+ATSUSetAttributes(
+ ATSUStyle iStyle,
+ ItemCount iAttributeCount,
+ const ATSUAttributeTag iTag[],
+ const ByteCount iValueSize[],
+ const ATSUAttributeValuePtr iValue[]) ;
+extern OSStatus
+ATSUGetAttribute(
+ ATSUStyle iStyle,
+ ATSUAttributeTag iTag,
+ ByteCount iExpectedValueSize,
+ ATSUAttributeValuePtr oValue,
+ ByteCount * oActualValueSize) ;
+extern OSStatus
+ATSUGetAllAttributes(
+ ATSUStyle iStyle,
+ ATSUAttributeInfo oAttributeInfoArray[],
+ ItemCount iTagValuePairArraySize,
+ ItemCount * oTagValuePairCount) ;
+extern OSStatus
+ATSUClearAttributes(
+ ATSUStyle iStyle,
+ ItemCount iTagCount,
+ const ATSUAttributeTag iTag[]) ;
+extern OSStatus
+ATSUSetFontFeatures(
+ ATSUStyle iStyle,
+ ItemCount iFeatureCount,
+ const ATSUFontFeatureType iType[],
+ const ATSUFontFeatureSelector iSelector[]) ;
+extern OSStatus
+ATSUGetFontFeature(
+ ATSUStyle iStyle,
+ ItemCount iFeatureIndex,
+ ATSUFontFeatureType * oFeatureType,
+ ATSUFontFeatureSelector * oFeatureSelector) ;
+extern OSStatus
+ATSUGetAllFontFeatures(
+ ATSUStyle iStyle,
+ ItemCount iMaximumFeatureCount,
+ ATSUFontFeatureType oFeatureType[],
+ ATSUFontFeatureSelector oFeatureSelector[],
+ ItemCount * oActualFeatureCount) ;
+extern OSStatus
+ATSUClearFontFeatures(
+ ATSUStyle iStyle,
+ ItemCount iFeatureCount,
+ const ATSUFontFeatureType iType[],
+ const ATSUFontFeatureSelector iSelector[]) ;
+extern OSStatus
+ATSUSetVariations(
+ ATSUStyle iStyle,
+ ItemCount iVariationCount,
+ const ATSUFontVariationAxis iAxes[],
+ const ATSUFontVariationValue iValue[]) ;
+extern OSStatus
+ATSUGetFontVariationValue(
+ ATSUStyle iStyle,
+ ATSUFontVariationAxis iFontVariationAxis,
+ ATSUFontVariationValue * oFontVariationValue) ;
+extern OSStatus
+ATSUGetAllFontVariations(
+ ATSUStyle iStyle,
+ ItemCount iVariationCount,
+ ATSUFontVariationAxis oVariationAxes[],
+ ATSUFontVariationValue oFontVariationValues[],
+ ItemCount * oActualVariationCount) ;
+extern OSStatus
+ATSUClearFontVariations(
+ ATSUStyle iStyle,
+ ItemCount iAxisCount,
+ const ATSUFontVariationAxis iAxis[]) ;
+extern OSStatus
+ATSUCreateTextLayout(ATSUTextLayout * oTextLayout) ;
+extern OSStatus
+ATSUCreateAndCopyTextLayout(
+ ATSUTextLayout iTextLayout,
+ ATSUTextLayout * oTextLayout) ;
+extern OSStatus
+ATSUCreateTextLayoutWithTextPtr(
+ ConstUniCharArrayPtr iText,
+ UniCharArrayOffset iTextOffset,
+ UniCharCount iTextLength,
+ UniCharCount iTextTotalLength,
+ ItemCount iNumberOfRuns,
+ const UniCharCount iRunLengths[],
+ ATSUStyle iStyles[],
+ ATSUTextLayout * oTextLayout) ;
+extern OSStatus
+ATSUCreateTextLayoutWithTextHandle(
+ UniCharArrayHandle iText,
+ UniCharArrayOffset iTextOffset,
+ UniCharCount iTextLength,
+ UniCharCount iTextTotalLength,
+ ItemCount iNumberOfRuns,
+ const UniCharCount iRunLengths[],
+ ATSUStyle iStyles[],
+ ATSUTextLayout * oTextLayout) ;
+extern OSStatus
+ATSUClearLayoutCache(
+ ATSUTextLayout iTextLayout,
+ UniCharArrayOffset iLineStart) ;
+extern OSStatus
+ATSUDisposeTextLayout(ATSUTextLayout iTextLayout) ;
+extern OSStatus
+ATSUSetTextLayoutRefCon(
+ ATSUTextLayout iTextLayout,
+ UInt32 iRefCon) ;
+extern OSStatus
+ATSUGetTextLayoutRefCon(
+ ATSUTextLayout iTextLayout,
+ UInt32 * oRefCon) ;
+extern OSStatus
+ATSUGetGlyphBounds(
+ ATSUTextLayout iTextLayout,
+ ATSUTextMeasurement iTextBasePointX,
+ ATSUTextMeasurement iTextBasePointY,
+ UniCharArrayOffset iBoundsCharStart,
+ UniCharCount iBoundsCharLength,
+ UInt16 iTypeOfBounds,
+ ItemCount iMaxNumberOfBounds,
+ ATSTrapezoid oGlyphBounds[],
+ ItemCount * oActualNumberOfBounds) ;
+extern OSStatus
+ATSUIdle(ATSUTextLayout iTextLayout) ;
+extern OSStatus
+ATSUSetTextPointerLocation(
+ ATSUTextLayout iTextLayout,
+ ConstUniCharArrayPtr iText,
+ UniCharArrayOffset iTextOffset,
+ UniCharCount iTextLength,
+ UniCharCount iTextTotalLength) ;
+extern OSStatus
+ATSUSetTextHandleLocation(
+ ATSUTextLayout iTextLayout,
+ UniCharArrayHandle iText,
+ UniCharArrayOffset iTextOffset,
+ UniCharCount iTextLength,
+ UniCharCount iTextTotalLength) ;
+extern OSStatus
+ATSUGetTextLocation(
+ ATSUTextLayout iTextLayout,
+ void ** oText,
+ Boolean * oTextIsStoredInHandle,
+ UniCharArrayOffset * oOffset,
+ UniCharCount * oTextLength,
+ UniCharCount * oTextTotalLength) ;
+extern OSStatus
+ATSUTextDeleted(
+ ATSUTextLayout iTextLayout,
+ UniCharArrayOffset iDeletedRangeStart,
+ UniCharCount iDeletedRangeLength) ;
+extern OSStatus
+ATSUTextInserted(
+ ATSUTextLayout iTextLayout,
+ UniCharArrayOffset iInsertionLocation,
+ UniCharCount iInsertionLength) ;
+extern OSStatus
+ATSUTextMoved(
+ ATSUTextLayout iTextLayout,
+ ConstUniCharArrayPtr iNewLocation) ;
+extern OSStatus
+ATSUCopyLayoutControls(
+ ATSUTextLayout iSourceTextLayout,
+ ATSUTextLayout iDestTextLayout) ;
+extern OSStatus
+ATSUSetLayoutControls(
+ ATSUTextLayout iTextLayout,
+ ItemCount iAttributeCount,
+ const ATSUAttributeTag iTag[],
+ const ByteCount iValueSize[],
+ const ATSUAttributeValuePtr iValue[]) ;
+extern OSStatus
+ATSUGetLayoutControl(
+ ATSUTextLayout iTextLayout,
+ ATSUAttributeTag iTag,
+ ByteCount iExpectedValueSize,
+ ATSUAttributeValuePtr oValue,
+ ByteCount * oActualValueSize) ;
+extern OSStatus
+ATSUGetAllLayoutControls(
+ ATSUTextLayout iTextLayout,
+ ATSUAttributeInfo oAttributeInfoArray[],
+ ItemCount iTagValuePairArraySize,
+ ItemCount * oTagValuePairCount) ;
+extern OSStatus
+ATSUClearLayoutControls(
+ ATSUTextLayout iTextLayout,
+ ItemCount iTagCount,
+ const ATSUAttributeTag iTag[]) ;
+extern OSStatus
+ATSUCopyLineControls(
+ ATSUTextLayout iSourceTextLayout,
+ UniCharArrayOffset iSourceLineStart,
+ ATSUTextLayout iDestTextLayout,
+ UniCharArrayOffset iDestLineStart) ;
+extern OSStatus
+ATSUSetLineControls(
+ ATSUTextLayout iTextLayout,
+ UniCharArrayOffset iLineStart,
+ ItemCount iAttributeCount,
+ const ATSUAttributeTag iTag[],
+ const ByteCount iValueSize[],
+ const ATSUAttributeValuePtr iValue[]) ;
+extern OSStatus
+ATSUGetLineControl(
+ ATSUTextLayout iTextLayout,
+ UniCharArrayOffset iLineStart,
+ ATSUAttributeTag iTag,
+ ByteCount iExpectedValueSize,
+ ATSUAttributeValuePtr oValue,
+ ByteCount * oActualValueSize) ;
+extern OSStatus
+ATSUGetAllLineControls(
+ ATSUTextLayout iTextLayout,
+ UniCharArrayOffset iLineStart,
+ ATSUAttributeInfo oAttributeInfoArray[],
+ ItemCount iTagValuePairArraySize,
+ ItemCount * oTagValuePairCount) ;
+extern OSStatus
+ATSUClearLineControls(
+ ATSUTextLayout iTextLayout,
+ UniCharArrayOffset iLineStart,
+ ItemCount iTagCount,
+ const ATSUAttributeTag iTag[]) ;
+extern OSStatus
+ATSUSetRunStyle(
+ ATSUTextLayout iTextLayout,
+ ATSUStyle iStyle,
+ UniCharArrayOffset iRunStart,
+ UniCharCount iRunLength) ;
+extern OSStatus
+ATSUGetRunStyle(
+ ATSUTextLayout iTextLayout,
+ UniCharArrayOffset iOffset,
+ ATSUStyle * oStyle,
+ UniCharArrayOffset * oRunStart,
+ UniCharCount * oRunLength) ;
+extern OSStatus
+ATSUGetContinuousAttributes(
+ ATSUTextLayout iTextLayout,
+ UniCharArrayOffset iOffset,
+ UniCharCount iLength,
+ ATSUStyle oStyle) ;
+extern OSStatus
+ATSUDrawText(
+ ATSUTextLayout iTextLayout,
+ UniCharArrayOffset iLineOffset,
+ UniCharCount iLineLength,
+ ATSUTextMeasurement iLocationX,
+ ATSUTextMeasurement iLocationY) ;
+extern OSStatus
+ATSUMeasureText(
+ ATSUTextLayout iTextLayout,
+ UniCharArrayOffset iLineStart,
+ UniCharCount iLineLength,
+ ATSUTextMeasurement * oTextBefore,
+ ATSUTextMeasurement * oTextAfter,
+ ATSUTextMeasurement * oAscent,
+ ATSUTextMeasurement * oDescent) ;
+extern OSStatus
+ATSUGetUnjustifiedBounds(
+ ATSUTextLayout iTextLayout,
+ UniCharArrayOffset iLineStart,
+ UniCharCount iLineLength,
+ ATSUTextMeasurement * oTextBefore,
+ ATSUTextMeasurement * oTextAfter,
+ ATSUTextMeasurement * oAscent,
+ ATSUTextMeasurement * oDescent) ;
+extern OSStatus
+ATSUMeasureTextImage(
+ ATSUTextLayout iTextLayout,
+ UniCharArrayOffset iLineOffset,
+ UniCharCount iLineLength,
+ ATSUTextMeasurement iLocationX,
+ ATSUTextMeasurement iLocationY,
+ Rect * oTextImageRect) ;
+extern OSStatus
+ATSUHighlightText(
+ ATSUTextLayout iTextLayout,
+ ATSUTextMeasurement iTextBasePointX,
+ ATSUTextMeasurement iTextBasePointY,
+ UniCharArrayOffset iHighlightStart,
+ UniCharCount iHighlightLength) ;
+extern OSStatus
+ATSUUnhighlightText(
+ ATSUTextLayout iTextLayout,
+ ATSUTextMeasurement iTextBasePointX,
+ ATSUTextMeasurement iTextBasePointY,
+ UniCharArrayOffset iHighlightStart,
+ UniCharCount iHighlightLength) ;
+extern OSStatus
+ATSUGetTextHighlight(
+ ATSUTextLayout iTextLayout,
+ ATSUTextMeasurement iTextBasePointX,
+ ATSUTextMeasurement iTextBasePointY,
+ UniCharArrayOffset iHighlightStart,
+ UniCharCount iHighlightLength,
+ RgnHandle oHighlightRegion) ;
+extern OSStatus
+ATSUHighlightInactiveText(
+ ATSUTextLayout iTextLayout,
+ ATSUTextMeasurement iTextBasePointX,
+ ATSUTextMeasurement iTextBasePointY,
+ UniCharArrayOffset iHighlightStart,
+ UniCharCount iHighlightLength) ;
+extern OSStatus
+ATSUPositionToOffset(
+ ATSUTextLayout iTextLayout,
+ ATSUTextMeasurement iLocationX,
+ ATSUTextMeasurement iLocationY,
+ UniCharArrayOffset * ioPrimaryOffset,
+ Boolean * oIsLeading,
+ UniCharArrayOffset * oSecondaryOffset) ;
+extern OSStatus
+ATSUOffsetToPosition(
+ ATSUTextLayout iTextLayout,
+ UniCharArrayOffset iOffset,
+ Boolean iIsLeading,
+ ATSUCaret * oMainCaret,
+ ATSUCaret * oSecondCaret,
+ Boolean * oCaretIsSplit) ;
+extern OSStatus
+ATSUPositionToCursorOffset(
+ ATSUTextLayout iTextLayout,
+ ATSUTextMeasurement iLocationX,
+ ATSUTextMeasurement iLocationY,
+ ATSUCursorMovementType iMovementType,
+ UniCharArrayOffset * ioPrimaryOffset,
+ Boolean * oIsLeading,
+ UniCharArrayOffset * oSecondaryOffset) ;
+extern OSStatus
+ATSUOffsetToCursorPosition(
+ ATSUTextLayout iTextLayout,
+ UniCharArrayOffset iOffset,
+ Boolean iIsLeading,
+ ATSUCursorMovementType iMovementType,
+ ATSUCaret * oMainCaret,
+ ATSUCaret * oSecondCaret,
+ Boolean * oCaretIsSplit) ;
+extern OSStatus
+ATSUNextCursorPosition(
+ ATSUTextLayout iTextLayout,
+ UniCharArrayOffset iOldOffset,
+ ATSUCursorMovementType iMovementType,
+ UniCharArrayOffset * oNewOffset) ;
+extern OSStatus
+ATSUPreviousCursorPosition(
+ ATSUTextLayout iTextLayout,
+ UniCharArrayOffset iOldOffset,
+ ATSUCursorMovementType iMovementType,
+ UniCharArrayOffset * oNewOffset) ;
+extern OSStatus
+ATSURightwardCursorPosition(
+ ATSUTextLayout iTextLayout,
+ UniCharArrayOffset iOldOffset,
+ ATSUCursorMovementType iMovementType,
+ UniCharArrayOffset * oNewOffset) ;
+extern OSStatus
+ATSULeftwardCursorPosition(
+ ATSUTextLayout iTextLayout,
+ UniCharArrayOffset iOldOffset,
+ ATSUCursorMovementType iMovementType,
+ UniCharArrayOffset * oNewOffset) ;
+extern OSStatus
+ATSUBatchBreakLines(
+ ATSUTextLayout iTextLayout,
+ UniCharArrayOffset iRangeStart,
+ UniCharCount iRangeLength,
+ ATSUTextMeasurement iLineWidth,
+ ItemCount * oBreakCount) ;
+extern OSStatus
+ATSUBreakLine(
+ ATSUTextLayout iTextLayout,
+ UniCharArrayOffset iLineStart,
+ ATSUTextMeasurement iLineWidth,
+ Boolean iUseAsSoftLineBreak,
+ UniCharArrayOffset * oLineBreak) ;
+extern OSStatus
+ATSUSetSoftLineBreak(
+ ATSUTextLayout iTextLayout,
+ UniCharArrayOffset iLineBreak) ;
+extern OSStatus
+ATSUGetSoftLineBreaks(
+ ATSUTextLayout iTextLayout,
+ UniCharArrayOffset iRangeStart,
+ UniCharCount iRangeLength,
+ ItemCount iMaximumBreaks,
+ UniCharArrayOffset oBreaks[],
+ ItemCount * oBreakCount) ;
+extern OSStatus
+ATSUClearSoftLineBreaks(
+ ATSUTextLayout iTextLayout,
+ UniCharArrayOffset iRangeStart,
+ UniCharCount iRangeLength) ;
+extern OSStatus
+ATSUSetTabArray(
+ ATSUTextLayout iTextLayout,
+ const ATSUTab iTabs[],
+ ItemCount iTabCount) ;
+extern OSStatus
+ATSUGetTabArray(
+ ATSUTextLayout iTextLayout,
+ ItemCount iMaxTabCount,
+ ATSUTab oTabs[],
+ ItemCount * oTabCount) ;
+extern OSStatus
+ATSUSetFontFallbacks(
+ ItemCount iFontFallbacksCount,
+ const ATSUFontID iFontIDs[],
+ ATSUFontFallbackMethod iFontFallbackMethod) ;
+extern OSStatus
+ATSUGetFontFallbacks(
+ ItemCount iMaxFontFallbacksCount,
+ ATSUFontID oFontIDs[],
+ ATSUFontFallbackMethod * oFontFallbackMethod,
+ ItemCount * oActualFallbacksCount) ;
+extern OSStatus
+ATSUMatchFontsToText(
+ ATSUTextLayout iTextLayout,
+ UniCharArrayOffset iTextStart,
+ UniCharCount iTextLength,
+ ATSUFontID * oFontID,
+ UniCharArrayOffset * oChangedOffset,
+ UniCharCount * oChangedLength) ;
+extern OSStatus
+ATSUSetTransientFontMatching(
+ ATSUTextLayout iTextLayout,
+ Boolean iTransientFontMatching) ;
+extern OSStatus
+ATSUGetTransientFontMatching(
+ ATSUTextLayout iTextLayout,
+ Boolean * oTransientFontMatching) ;
+extern OSStatus
+ATSUFontCount(ItemCount * oFontCount) ;
+extern OSStatus
+ATSUGetFontIDs(
+ ATSUFontID oFontIDs[],
+ ItemCount iArraySize,
+ ItemCount * oFontCount) ;
+extern OSStatus
+ATSUFONDtoFontID(
+ short iFONDNumber,
+ Style iFONDStyle,
+ ATSUFontID * oFontID) ;
+extern OSStatus
+ATSUFontIDtoFOND(
+ ATSUFontID iFontID,
+ short * oFONDNumber,
+ Style * oFONDStyle) ;
+extern OSStatus
+ATSUCountFontNames(
+ ATSUFontID iFontID,
+ ItemCount * oFontNameCount) ;
+extern OSStatus
+ATSUGetIndFontName(
+ ATSUFontID iFontID,
+ ItemCount iFontNameIndex,
+ ByteCount iMaximumNameLength,
+ Ptr oName,
+ ByteCount * oActualNameLength,
+ FontNameCode * oFontNameCode,
+ FontPlatformCode * oFontNamePlatform,
+ FontScriptCode * oFontNameScript,
+ FontLanguageCode * oFontNameLanguage) ;
+extern OSStatus
+ATSUFindFontName(
+ ATSUFontID iFontID,
+ FontNameCode iFontNameCode,
+ FontPlatformCode iFontNamePlatform,
+ FontScriptCode iFontNameScript,
+ FontLanguageCode iFontNameLanguage,
+ ByteCount iMaximumNameLength,
+ Ptr oName,
+ ByteCount * oActualNameLength,
+ ItemCount * oFontNameIndex) ;
+extern OSStatus
+ATSUFindFontFromName(
+ Ptr iName,
+ ByteCount iNameLength,
+ FontNameCode iFontNameCode,
+ FontPlatformCode iFontNamePlatform,
+ FontScriptCode iFontNameScript,
+ FontLanguageCode iFontNameLanguage,
+ ATSUFontID * oFontID) ;
+extern OSStatus
+ATSUCountFontFeatureTypes(
+ ATSUFontID iFontID,
+ ItemCount * oTypeCount) ;
+extern OSStatus
+ATSUCountFontFeatureSelectors(
+ ATSUFontID iFontID,
+ ATSUFontFeatureType iType,
+ ItemCount * oSelectorCount) ;
+extern OSStatus
+ATSUGetFontFeatureTypes(
+ ATSUFontID iFontID,
+ ItemCount iMaximumTypes,
+ ATSUFontFeatureType oTypes[],
+ ItemCount * oActualTypeCount) ;
+extern OSStatus
+ATSUGetFontFeatureSelectors(
+ ATSUFontID iFontID,
+ ATSUFontFeatureType iType,
+ ItemCount iMaximumSelectors,
+ ATSUFontFeatureSelector oSelectors[],
+ Boolean oSelectorIsOnByDefault[],
+ ItemCount * oActualSelectorCount,
+ Boolean * oIsMutuallyExclusive) ;
+extern OSStatus
+ATSUGetFontFeatureNameCode(
+ ATSUFontID iFontID,
+ ATSUFontFeatureType iType,
+ ATSUFontFeatureSelector iSelector,
+ FontNameCode * oNameCode) ;
+extern OSStatus
+ATSUCountFontTracking(
+ ATSUFontID iFontID,
+ ATSUVerticalCharacterType iCharacterOrientation,
+ ItemCount * oTrackingCount) ;
+extern OSStatus
+ATSUGetIndFontTracking(
+ ATSUFontID iFontID,
+ ATSUVerticalCharacterType iCharacterOrientation,
+ ItemCount iTrackIndex,
+ Fixed * oFontTrackingValue,
+ FontNameCode * oNameCode) ;
+extern OSStatus
+ATSUCountFontVariations(
+ ATSUFontID iFontID,
+ ItemCount * oVariationCount) ;
+extern OSStatus
+ATSUGetIndFontVariation(
+ ATSUFontID iFontID,
+ ItemCount iVariationIndex,
+ ATSUFontVariationAxis * oATSUFontVariationAxis,
+ ATSUFontVariationValue * oMinimumValue,
+ ATSUFontVariationValue * oMaximumValue,
+ ATSUFontVariationValue * oDefaultValue) ;
+extern OSStatus
+ATSUGetFontVariationNameCode(
+ ATSUFontID iFontID,
+ ATSUFontVariationAxis iAxis,
+ FontNameCode * oNameCode) ;
+extern OSStatus
+ATSUCountFontInstances(
+ ATSUFontID iFontID,
+ ItemCount * oInstances) ;
+extern OSStatus
+ATSUGetFontInstance(
+ ATSUFontID iFontID,
+ ItemCount iFontInstanceIndex,
+ ItemCount iMaximumVariations,
+ ATSUFontVariationAxis oAxes[],
+ ATSUFontVariationValue oValues[],
+ ItemCount * oActualVariationCount) ;
+extern OSStatus
+ATSUGetFontInstanceNameCode(
+ ATSUFontID iFontID,
+ ItemCount iInstanceIndex,
+ FontNameCode * oNameCode) ;
+extern OSStatus
+ATSUGetGlyphInfo(
+ ATSUTextLayout iTextLayout,
+ UniCharArrayOffset iLineStart,
+ UniCharCount iLineLength,
+ ByteCount * ioBufferSize,
+ ATSUGlyphInfoArray * oGlyphInfoPtr) ;
+extern OSStatus
+ATSUDrawGlyphInfo(
+ ATSUGlyphInfoArray * iGlyphInfoArray,
+ Float32Point iLocation) ;
+extern OSStatus
+ATSUGlyphGetIdealMetrics(
+ ATSUStyle iATSUStyle,
+ ItemCount iNumOfGlyphs,
+ GlyphID iGlyphIDs[],
+ ByteOffset iInputOffset,
+ ATSGlyphIdealMetrics oIdealMetrics[]) ;
+extern OSStatus
+ATSUGetNativeCurveType(
+ ATSUStyle iATSUStyle,
+ ATSCurveType * oCurveType) ;
+extern OSStatus
+ATSUGlyphGetScreenMetrics(
+ ATSUStyle iATSUStyle,
+ ItemCount iNumOfGlyphs,
+ GlyphID iGlyphIDs[],
+ ByteOffset iInputOffset,
+ Boolean iForcingAntiAlias,
+ Boolean iAntiAliasSwitch,
+ ATSGlyphScreenMetrics oScreenMetrics[]) ;
+
+
+
+
+
+typedef OSStatus ( * ATSQuadraticLineProcPtr)(const Float32Point *pt1, const Float32Point *pt2, void *callBackDataPtr);
+typedef OSStatus ( * ATSQuadraticCurveProcPtr)(const Float32Point *pt1, const Float32Point *controlPt, const Float32Point *pt2, void *callBackDataPtr);
+typedef OSStatus ( * ATSQuadraticNewPathProcPtr)(void * callBackDataPtr);
+typedef OSStatus ( * ATSQuadraticClosePathProcPtr)(void * callBackDataPtr);
+typedef ATSQuadraticLineProcPtr ATSQuadraticLineUPP;
+typedef ATSQuadraticCurveProcPtr ATSQuadraticCurveUPP;
+typedef ATSQuadraticNewPathProcPtr ATSQuadraticNewPathUPP;
+typedef ATSQuadraticClosePathProcPtr ATSQuadraticClosePathUPP;
+extern ATSQuadraticLineUPP
+NewATSQuadraticLineUPP(ATSQuadraticLineProcPtr userRoutine) ;
+extern ATSQuadraticCurveUPP
+NewATSQuadraticCurveUPP(ATSQuadraticCurveProcPtr userRoutine) ;
+extern ATSQuadraticNewPathUPP
+NewATSQuadraticNewPathUPP(ATSQuadraticNewPathProcPtr userRoutine) ;
+extern ATSQuadraticClosePathUPP
+NewATSQuadraticClosePathUPP(ATSQuadraticClosePathProcPtr userRoutine) ;
+extern void
+DisposeATSQuadraticLineUPP(ATSQuadraticLineUPP userUPP) ;
+extern void
+DisposeATSQuadraticCurveUPP(ATSQuadraticCurveUPP userUPP) ;
+extern void
+DisposeATSQuadraticNewPathUPP(ATSQuadraticNewPathUPP userUPP) ;
+extern void
+DisposeATSQuadraticClosePathUPP(ATSQuadraticClosePathUPP userUPP) ;
+extern OSStatus
+InvokeATSQuadraticLineUPP(
+ const Float32Point * pt1,
+ const Float32Point * pt2,
+ void * callBackDataPtr,
+ ATSQuadraticLineUPP userUPP) ;
+extern OSStatus
+InvokeATSQuadraticCurveUPP(
+ const Float32Point * pt1,
+ const Float32Point * controlPt,
+ const Float32Point * pt2,
+ void * callBackDataPtr,
+ ATSQuadraticCurveUPP userUPP) ;
+extern OSStatus
+InvokeATSQuadraticNewPathUPP(
+ void * callBackDataPtr,
+ ATSQuadraticNewPathUPP userUPP) ;
+extern OSStatus
+InvokeATSQuadraticClosePathUPP(
+ void * callBackDataPtr,
+ ATSQuadraticClosePathUPP userUPP) ;
+extern OSStatus
+ATSUGlyphGetQuadraticPaths(
+ ATSUStyle iATSUStyle,
+ GlyphID iGlyphID,
+ ATSQuadraticNewPathUPP iNewPathProc,
+ ATSQuadraticLineUPP iLineProc,
+ ATSQuadraticCurveUPP iCurveProc,
+ ATSQuadraticClosePathUPP iClosePathProc,
+ void * iCallbackDataPtr,
+ OSStatus * oCallbackResult) ;
+
+
+
+typedef OSStatus ( * ATSCubicMoveToProcPtr)(const Float32Point *pt, void *callBackDataPtr);
+typedef OSStatus ( * ATSCubicLineToProcPtr)(const Float32Point *pt, void *callBackDataPtr);
+typedef OSStatus ( * ATSCubicCurveToProcPtr)(const Float32Point *pt1, const Float32Point *pt2, const Float32Point *pt3, void *callBackDataPtr);
+typedef OSStatus ( * ATSCubicClosePathProcPtr)(void * callBackDataPtr);
+typedef ATSCubicMoveToProcPtr ATSCubicMoveToUPP;
+typedef ATSCubicLineToProcPtr ATSCubicLineToUPP;
+typedef ATSCubicCurveToProcPtr ATSCubicCurveToUPP;
+typedef ATSCubicClosePathProcPtr ATSCubicClosePathUPP;
+extern ATSCubicMoveToUPP
+NewATSCubicMoveToUPP(ATSCubicMoveToProcPtr userRoutine) ;
+extern ATSCubicLineToUPP
+NewATSCubicLineToUPP(ATSCubicLineToProcPtr userRoutine) ;
+extern ATSCubicCurveToUPP
+NewATSCubicCurveToUPP(ATSCubicCurveToProcPtr userRoutine) ;
+extern ATSCubicClosePathUPP
+NewATSCubicClosePathUPP(ATSCubicClosePathProcPtr userRoutine) ;
+extern void
+DisposeATSCubicMoveToUPP(ATSCubicMoveToUPP userUPP) ;
+extern void
+DisposeATSCubicLineToUPP(ATSCubicLineToUPP userUPP) ;
+extern void
+DisposeATSCubicCurveToUPP(ATSCubicCurveToUPP userUPP) ;
+extern void
+DisposeATSCubicClosePathUPP(ATSCubicClosePathUPP userUPP) ;
+extern OSStatus
+InvokeATSCubicMoveToUPP(
+ const Float32Point * pt,
+ void * callBackDataPtr,
+ ATSCubicMoveToUPP userUPP) ;
+extern OSStatus
+InvokeATSCubicLineToUPP(
+ const Float32Point * pt,
+ void * callBackDataPtr,
+ ATSCubicLineToUPP userUPP) ;
+extern OSStatus
+InvokeATSCubicCurveToUPP(
+ const Float32Point * pt1,
+ const Float32Point * pt2,
+ const Float32Point * pt3,
+ void * callBackDataPtr,
+ ATSCubicCurveToUPP userUPP) ;
+extern OSStatus
+InvokeATSCubicClosePathUPP(
+ void * callBackDataPtr,
+ ATSCubicClosePathUPP userUPP) ;
+extern OSStatus
+ATSUGlyphGetCubicPaths(
+ ATSUStyle iATSUStyle,
+ GlyphID iGlyphID,
+ ATSCubicMoveToUPP iMoveToProc,
+ ATSCubicLineToUPP iLineToProc,
+ ATSCubicCurveToUPP iCurveToProc,
+ ATSCubicClosePathUPP iClosePathProc,
+ void * iCallbackDataPtr,
+ OSStatus * oCallbackResult) ;
+extern OSStatus
+ATSUGlyphGetCurvePaths(
+ ATSUStyle iATSUStyle,
+ GlyphID iGlyphID,
+ ByteCount * ioBufferSize,
+ ATSUCurvePaths * oPaths) ;
+extern OSStatus
+ATSUSetHighlightingMethod(
+ ATSUTextLayout iTextLayout,
+ ATSUHighlightMethod iMethod,
+ const ATSUUnhighlightData * iUnhighlightData) ;
+
+
+
+
+
+
+}
+
+
+
+
+enum {
+ mBaseOffset = 1,
+ mRowBytes = 2,
+ mBounds = 3,
+ mVersion = 4,
+ mHRes = 5,
+ mVRes = 6,
+ mPixelType = 7,
+ mPixelSize = 8,
+ mCmpCount = 9,
+ mCmpSize = 10,
+ mPlaneBytes = 11,
+ mVertRefRate = 14,
+ mVidParams = 1,
+ mTable = 2,
+ mPageCnt = 3,
+ mDevType = 4,
+ oneBitMode = 128,
+ twoBitMode = 129,
+ fourBitMode = 130,
+ eightBitMode = 131
+};
+
+enum {
+ sixteenBitMode = 132,
+ thirtyTwoBitMode = 133,
+ firstVidMode = 128,
+ secondVidMode = 129,
+ thirdVidMode = 130,
+ fourthVidMode = 131,
+ fifthVidMode = 132,
+ sixthVidMode = 133,
+ spGammaDir = 64,
+ spVidNamesDir = 65
+};
+
+
+
+
+enum {
+ kDeclROMtables = 'decl',
+ kDetailedTimingFormat = 'arba'
+};
+
+
+enum {
+ kDDCBlockSize = 128
+};
+
+
+enum {
+ kDDCBlockTypeEDID = 0
+};
+
+
+enum {
+ kDDCForceReadBit = 0,
+ kDDCForceReadMask = (1 << kDDCForceReadBit)
+};
+enum {
+ timingInvalid = 0,
+ timingInvalid_SM_T24 = 8,
+ timingApple_FixedRateLCD = 42,
+ timingApple_512x384_60hz = 130,
+ timingApple_560x384_60hz = 135,
+ timingApple_640x480_67hz = 140,
+ timingApple_640x400_67hz = 145,
+ timingVESA_640x480_60hz = 150,
+ timingVESA_640x480_72hz = 152,
+ timingVESA_640x480_75hz = 154,
+ timingVESA_640x480_85hz = 158,
+ timingGTF_640x480_120hz = 159,
+ timingApple_640x870_75hz = 160,
+ timingApple_640x818_75hz = 165,
+ timingApple_832x624_75hz = 170,
+ timingVESA_800x600_56hz = 180,
+ timingVESA_800x600_60hz = 182,
+ timingVESA_800x600_72hz = 184,
+ timingVESA_800x600_75hz = 186,
+ timingVESA_800x600_85hz = 188,
+ timingVESA_1024x768_60hz = 190,
+ timingVESA_1024x768_70hz = 200,
+ timingVESA_1024x768_75hz = 204,
+ timingVESA_1024x768_85hz = 208,
+ timingApple_1024x768_75hz = 210,
+ timingApple_1152x870_75hz = 220,
+ timingAppleNTSC_ST = 230,
+ timingAppleNTSC_FF = 232,
+ timingAppleNTSC_STconv = 234,
+ timingAppleNTSC_FFconv = 236,
+ timingApplePAL_ST = 238,
+ timingApplePAL_FF = 240,
+ timingApplePAL_STconv = 242,
+ timingApplePAL_FFconv = 244,
+ timingVESA_1280x960_75hz = 250,
+ timingVESA_1280x960_60hz = 252,
+ timingVESA_1280x960_85hz = 254,
+ timingVESA_1280x1024_60hz = 260,
+ timingVESA_1280x1024_75hz = 262,
+ timingVESA_1280x1024_85hz = 268,
+ timingVESA_1600x1200_60hz = 280,
+ timingVESA_1600x1200_65hz = 282,
+ timingVESA_1600x1200_70hz = 284,
+ timingVESA_1600x1200_75hz = 286,
+ timingVESA_1600x1200_80hz = 288,
+ timingVESA_1600x1200_85hz = 289,
+ timingVESA_1792x1344_60hz = 296,
+ timingVESA_1792x1344_75hz = 298,
+ timingVESA_1856x1392_60hz = 300,
+ timingVESA_1856x1392_75hz = 302,
+ timingVESA_1920x1440_60hz = 304,
+ timingVESA_1920x1440_75hz = 306,
+ timingSMPTE240M_60hz = 400,
+ timingFilmRate_48hz = 410,
+ timingSony_1600x1024_76hz = 500,
+ timingSony_1920x1080_60hz = 510,
+ timingSony_1920x1080_72hz = 520,
+ timingSony_1920x1200_76hz = 540,
+ timingApple_0x0_0hz_Offline = 550
+};
+
+
+
+enum {
+ timingApple12 = timingApple_512x384_60hz,
+ timingApple12x = timingApple_560x384_60hz,
+ timingApple13 = timingApple_640x480_67hz,
+ timingApple13x = timingApple_640x400_67hz,
+ timingAppleVGA = timingVESA_640x480_60hz,
+ timingApple15 = timingApple_640x870_75hz,
+ timingApple15x = timingApple_640x818_75hz,
+ timingApple16 = timingApple_832x624_75hz,
+ timingAppleSVGA = timingVESA_800x600_56hz,
+ timingApple1Ka = timingVESA_1024x768_60hz,
+ timingApple1Kb = timingVESA_1024x768_70hz,
+ timingApple19 = timingApple_1024x768_75hz,
+ timingApple21 = timingApple_1152x870_75hz,
+ timingSony_1900x1200_74hz = 530,
+ timingSony_1900x1200_76hz = timingSony_1920x1200_76hz
+};
+
+
+enum {
+ kAllModesValid = 0,
+ kAllModesSafe = 1,
+ kReportsTagging = 2,
+ kHasDirectConnection = 3,
+ kIsMonoDev = 4,
+ kUncertainConnection = 5,
+ kTaggingInfoNonStandard = 6,
+ kReportsDDCConnection = 7,
+ kHasDDCConnection = 8,
+ kConnectionInactive = 9,
+ kDependentConnection = 10,
+ kBuiltInConnection = 11,
+ kOverrideConnection = 12,
+ kFastCheckForDDC = 13,
+ kReportsHotPlugging = 14
+};
+
+
+
+enum {
+ kUnknownConnect = 1,
+ kPanelConnect = 2,
+ kPanelTFTConnect = 2,
+ kFixedModeCRTConnect = 3,
+ kMultiModeCRT1Connect = 4,
+ kMultiModeCRT2Connect = 5,
+ kMultiModeCRT3Connect = 6,
+ kMultiModeCRT4Connect = 7,
+ kModelessConnect = 8,
+ kFullPageConnect = 9,
+ kVGAConnect = 10,
+ kNTSCConnect = 11,
+ kPALConnect = 12,
+ kHRConnect = 13,
+ kPanelFSTNConnect = 14,
+ kMonoTwoPageConnect = 15,
+ kColorTwoPageConnect = 16,
+ kColor16Connect = 17,
+ kColor19Connect = 18,
+ kGenericCRT = 19,
+ kGenericLCD = 20,
+ kDDCConnect = 21,
+ kNoConnect = 22
+};
+
+
+enum {
+ kModeValid = 0,
+ kModeSafe = 1,
+ kModeDefault = 2,
+ kModeShowNow = 3,
+ kModeNotResize = 4,
+ kModeRequiresPan = 5,
+ kModeInterlaced = 6,
+ kModeShowNever = 7,
+ kModeSimulscan = 8,
+ kModeNotPreset = 9,
+ kModeBuiltIn = 10,
+ kModeStretched = 11
+};
+
+
+enum {
+ kDepthDependent = 0
+};
+
+
+enum {
+ kResolutionHasMultipleDepthSizes = 0
+};
+
+
+enum {
+
+ kAVPowerOff = 0,
+ kAVPowerStandby = 1,
+ kAVPowerSuspend = 2,
+ kAVPowerOn = 3,
+ kHardwareSleep = 128,
+ kHardwareWake = 129,
+ kHardwareWakeFromSuspend = 130,
+ kHardwareWakeToDoze = 131,
+ kHardwareWakeToDozeFromSuspend = 132
+};
+
+enum {
+
+ kPowerStateNeedsRefresh = 0,
+ kPowerStateSleepAwareBit = 1,
+ kPowerStateSleepForbiddenBit = 2,
+ kPowerStateSleepCanPowerOffBit = 3,
+ kPowerStateSleepNoDPMSBit = 4,
+ kPowerStateSleepWaketoDozeBit = 5,
+ kPowerStateNeedsRefreshMask = (1L << kPowerStateNeedsRefresh),
+ kPowerStateSleepAwareMask = (1L << kPowerStateSleepAwareBit),
+ kPowerStateSleepForbiddenMask = (1L << kPowerStateSleepForbiddenBit),
+ kPowerStateSleepCanPowerOffMask = (1L << kPowerStateSleepCanPowerOffBit),
+ kPowerStateSleepNoDPMSMask = (1L << kPowerStateSleepNoDPMSBit),
+ kPowerStateSleepWaketoDozeMask = (1L << kPowerStateSleepWaketoDozeBit)
+};
+
+
+enum {
+
+ cscReset = 0,
+ cscKillIO = 1,
+ cscSetMode = 2,
+ cscSetEntries = 3,
+ cscSetGamma = 4,
+ cscGrayPage = 5,
+ cscGrayScreen = 5,
+ cscSetGray = 6,
+ cscSetInterrupt = 7,
+ cscDirectSetEntries = 8,
+ cscSetDefaultMode = 9,
+ cscSwitchMode = 10,
+ cscSetSync = 11,
+ cscSavePreferredConfiguration = 16,
+ cscSetHardwareCursor = 22,
+ cscDrawHardwareCursor = 23,
+ cscSetConvolution = 24,
+ cscSetPowerState = 25,
+ cscPrivateControlCall = 26,
+ cscSetMultiConnect = 28,
+ cscSetClutBehavior = 29,
+ cscSetDetailedTiming = 31,
+ cscDoCommunication = 33,
+ cscProbeConnection = 34,
+ cscUnusedCall = 127
+};
+
+enum {
+
+ cscGetMode = 2,
+ cscGetEntries = 3,
+ cscGetPageCnt = 4,
+ cscGetPages = 4,
+ cscGetPageBase = 5,
+ cscGetBaseAddr = 5,
+ cscGetGray = 6,
+ cscGetInterrupt = 7,
+ cscGetGamma = 8,
+ cscGetDefaultMode = 9,
+ cscGetCurMode = 10,
+ cscGetSync = 11,
+ cscGetConnection = 12,
+ cscGetModeTiming = 13,
+ cscGetModeBaseAddress = 14,
+ cscGetScanProc = 15,
+ cscGetPreferredConfiguration = 16,
+ cscGetNextResolution = 17,
+ cscGetVideoParameters = 18,
+ cscGetGammaInfoList = 20,
+ cscRetrieveGammaTable = 21,
+ cscSupportsHardwareCursor = 22,
+ cscGetHardwareCursorDrawState = 23,
+ cscGetConvolution = 24,
+ cscGetPowerState = 25,
+ cscPrivateStatusCall = 26,
+ cscGetDDCBlock = 27,
+ cscGetMultiConnect = 28,
+ cscGetClutBehavior = 29,
+ cscGetTimingRanges = 30,
+ cscGetDetailedTiming = 31,
+ cscGetCommunicationInfo = 32
+};
+
+
+enum {
+ kDisableHorizontalSyncBit = 0,
+ kDisableVerticalSyncBit = 1,
+ kDisableCompositeSyncBit = 2,
+ kEnableSyncOnBlue = 3,
+ kEnableSyncOnGreen = 4,
+ kEnableSyncOnRed = 5,
+ kNoSeparateSyncControlBit = 6,
+ kTriStateSyncBit = 7,
+ kHorizontalSyncMask = 0x01,
+ kVerticalSyncMask = 0x02,
+ kCompositeSyncMask = 0x04,
+ kDPMSSyncMask = 0x07,
+ kTriStateSyncMask = 0x80,
+ kSyncOnBlueMask = 0x08,
+ kSyncOnGreenMask = 0x10,
+ kSyncOnRedMask = 0x20,
+ kSyncOnMask = 0x38
+};
+
+enum {
+
+ kDPMSSyncOn = 0,
+ kDPMSSyncStandby = 1,
+ kDPMSSyncSuspend = 2,
+ kDPMSSyncOff = 7
+};
+
+
+enum {
+ kConvolved = 0,
+ kLiveVideoPassThru = 1,
+ kConvolvedMask = 0x01,
+ kLiveVideoPassThruMask = 0x02
+};
+
+
+struct VPBlock {
+ long vpBaseOffset;
+ short vpRowBytes;
+ Rect vpBounds;
+ short vpVersion;
+ short vpPackType;
+ long vpPackSize;
+ long vpHRes;
+ long vpVRes;
+ short vpPixelType;
+ short vpPixelSize;
+ short vpCmpCount;
+ short vpCmpSize;
+ long vpPlaneBytes;
+};
+typedef struct VPBlock VPBlock;
+typedef VPBlock * VPBlockPtr;
+struct VDEntryRecord {
+ Ptr csTable;
+};
+typedef struct VDEntryRecord VDEntryRecord;
+typedef VDEntryRecord * VDEntRecPtr;
+
+struct VDGrayRecord {
+ Boolean csMode;
+ SInt8 filler;
+};
+typedef struct VDGrayRecord VDGrayRecord;
+typedef VDGrayRecord * VDGrayPtr;
+
+struct VDFlagRecord {
+ SInt8 csMode;
+ SInt8 filler;
+};
+typedef struct VDFlagRecord VDFlagRecord;
+typedef VDFlagRecord * VDFlagRecPtr;
+
+struct VDSetEntryRecord {
+ ColorSpec * csTable;
+ short csStart;
+ short csCount;
+};
+typedef struct VDSetEntryRecord VDSetEntryRecord;
+typedef VDSetEntryRecord * VDSetEntryPtr;
+
+struct VDGammaRecord {
+ Ptr csGTable;
+};
+typedef struct VDGammaRecord VDGammaRecord;
+typedef VDGammaRecord * VDGamRecPtr;
+struct VDBaseAddressInfoRec {
+ long csDevData;
+ long csDevBase;
+ short csModeReserved;
+ long csModeBase;
+};
+typedef struct VDBaseAddressInfoRec VDBaseAddressInfoRec;
+typedef VDBaseAddressInfoRec * VDBaseAddressInfoPtr;
+struct VDSwitchInfoRec {
+ unsigned short csMode;
+ unsigned long csData;
+ unsigned short csPage;
+ Ptr csBaseAddr;
+ unsigned long csReserved;
+};
+typedef struct VDSwitchInfoRec VDSwitchInfoRec;
+typedef VDSwitchInfoRec * VDSwitchInfoPtr;
+struct VDTimingInfoRec {
+ unsigned long csTimingMode;
+ unsigned long csTimingReserved;
+ unsigned long csTimingFormat;
+ unsigned long csTimingData;
+ unsigned long csTimingFlags;
+};
+typedef struct VDTimingInfoRec VDTimingInfoRec;
+typedef VDTimingInfoRec * VDTimingInfoPtr;
+struct VDDisplayConnectInfoRec {
+ unsigned short csDisplayType;
+ unsigned char csConnectTaggedType;
+ unsigned char csConnectTaggedData;
+ unsigned long csConnectFlags;
+ unsigned long csDisplayComponent;
+ unsigned long csConnectReserved;
+};
+typedef struct VDDisplayConnectInfoRec VDDisplayConnectInfoRec;
+typedef VDDisplayConnectInfoRec * VDDisplayConnectInfoPtr;
+struct VDMultiConnectInfoRec {
+ unsigned long csDisplayCountOrNumber;
+ VDDisplayConnectInfoRec csConnectInfo;
+};
+typedef struct VDMultiConnectInfoRec VDMultiConnectInfoRec;
+typedef VDMultiConnectInfoRec * VDMultiConnectInfoPtr;
+typedef unsigned char RawSenseCode;
+enum {
+ kRSCZero = 0,
+ kRSCOne = 1,
+ kRSCTwo = 2,
+ kRSCThree = 3,
+ kRSCFour = 4,
+ kRSCFive = 5,
+ kRSCSix = 6,
+ kRSCSeven = 7
+};
+typedef unsigned char ExtendedSenseCode;
+enum {
+ kESCZero21Inch = 0x00,
+ kESCOnePortraitMono = 0x14,
+ kESCTwo12Inch = 0x21,
+ kESCThree21InchRadius = 0x31,
+ kESCThree21InchMonoRadius = 0x34,
+ kESCThree21InchMono = 0x35,
+ kESCFourNTSC = 0x0A,
+ kESCFivePortrait = 0x1E,
+ kESCSixMSB1 = 0x03,
+ kESCSixMSB2 = 0x0B,
+ kESCSixMSB3 = 0x23,
+ kESCSixStandard = 0x2B,
+ kESCSevenPAL = 0x00,
+ kESCSevenNTSC = 0x14,
+ kESCSevenVGA = 0x17,
+ kESCSeven16Inch = 0x2D,
+ kESCSevenPALAlternate = 0x30,
+ kESCSeven19Inch = 0x3A,
+ kESCSevenDDC = 0x3E,
+ kESCSevenNoDisplay = 0x3F
+};
+typedef unsigned short DepthMode;
+enum {
+ kDepthMode1 = 128,
+ kDepthMode2 = 129,
+ kDepthMode3 = 130,
+ kDepthMode4 = 131,
+ kDepthMode5 = 132,
+ kDepthMode6 = 133
+};
+
+enum {
+ kFirstDepthMode = 128,
+ kSecondDepthMode = 129,
+ kThirdDepthMode = 130,
+ kFourthDepthMode = 131,
+ kFifthDepthMode = 132,
+ kSixthDepthMode = 133
+};
+
+
+struct VDPageInfo {
+ short csMode;
+ long csData;
+ short csPage;
+ Ptr csBaseAddr;
+};
+typedef struct VDPageInfo VDPageInfo;
+typedef VDPageInfo * VDPgInfoPtr;
+struct VDSizeInfo {
+ short csHSize;
+ short csHPos;
+ short csVSize;
+ short csVPos;
+};
+typedef struct VDSizeInfo VDSizeInfo;
+typedef VDSizeInfo * VDSzInfoPtr;
+struct VDSettings {
+ short csParamCnt;
+ short csBrightMax;
+ short csBrightDef;
+ short csBrightVal;
+ short csCntrstMax;
+ short csCntrstDef;
+ short csCntrstVal;
+ short csTintMax;
+ short csTintDef;
+ short csTintVal;
+ short csHueMax;
+ short csHueDef;
+ short csHueVal;
+ short csHorizDef;
+ short csHorizVal;
+ short csHorizMax;
+ short csVertDef;
+ short csVertVal;
+ short csVertMax;
+};
+typedef struct VDSettings VDSettings;
+typedef VDSettings * VDSettingsPtr;
+struct VDDefMode {
+ UInt8 csID;
+ SInt8 filler;
+};
+typedef struct VDDefMode VDDefMode;
+typedef VDDefMode * VDDefModePtr;
+struct VDSyncInfoRec {
+ UInt8 csMode;
+ UInt8 csFlags;
+};
+typedef struct VDSyncInfoRec VDSyncInfoRec;
+typedef VDSyncInfoRec * VDSyncInfoPtr;
+typedef UInt32 AVIDType;
+typedef AVIDType DisplayIDType;
+typedef UInt32 DisplayModeID;
+typedef UInt32 VideoDeviceType;
+typedef UInt32 GammaTableID;
+
+
+
+
+
+enum {
+ kDisplayModeIDCurrent = 0x00,
+ kDisplayModeIDInvalid = (long)0xFFFFFFFF,
+ kDisplayModeIDFindFirstResolution = (long)0xFFFFFFFE,
+ kDisplayModeIDNoMoreResolutions = (long)0xFFFFFFFD,
+ kDisplayModeIDFindFirstProgrammable = (long)0xFFFFFFFC,
+ kDisplayModeIDBootProgrammable = (long)0xFFFFFFFB,
+ kDisplayModeIDReservedBase = (long)0x80000000
+};
+
+
+enum {
+ kGammaTableIDFindFirst = (long)0xFFFFFFFE,
+ kGammaTableIDNoMoreTables = (long)0xFFFFFFFD,
+ kGammaTableIDSpecific = 0x00
+};
+
+
+enum {
+ kGetConnectionCount = (long)0xFFFFFFFF,
+ kActivateConnection = (0 << kConnectionInactive),
+ kDeactivateConnection = (1 << kConnectionInactive)
+};
+
+
+enum {
+ kVideoDefaultBus = 0
+};
+
+
+
+enum {
+ kVideoBusTypeInvalid = 0,
+ kVideoBusTypeI2C = 1
+};
+
+
+
+enum {
+ kVideoNoTransactionType = 0,
+ kVideoSimpleI2CType = 1,
+ kVideoDDCciReplyType = 2
+};
+
+
+enum {
+ kVideoReplyMicroSecDelayMask = (1 << 0)
+};
+
+
+
+struct VDResolutionInfoRec {
+ DisplayModeID csPreviousDisplayModeID;
+ DisplayModeID csDisplayModeID;
+ unsigned long csHorizontalPixels;
+ unsigned long csVerticalLines;
+ Fixed csRefreshRate;
+ DepthMode csMaxDepthMode;
+ unsigned long csResolutionFlags;
+ unsigned long csReserved;
+};
+typedef struct VDResolutionInfoRec VDResolutionInfoRec;
+typedef VDResolutionInfoRec * VDResolutionInfoPtr;
+struct VDVideoParametersInfoRec {
+ DisplayModeID csDisplayModeID;
+ DepthMode csDepthMode;
+ VPBlockPtr csVPBlockPtr;
+ unsigned long csPageCount;
+ VideoDeviceType csDeviceType;
+ UInt32 csDepthFlags;
+};
+typedef struct VDVideoParametersInfoRec VDVideoParametersInfoRec;
+typedef VDVideoParametersInfoRec * VDVideoParametersInfoPtr;
+struct VDGammaInfoRec {
+ GammaTableID csLastGammaID;
+ GammaTableID csNextGammaID;
+ Ptr csGammaPtr;
+ unsigned long csReserved;
+};
+typedef struct VDGammaInfoRec VDGammaInfoRec;
+typedef VDGammaInfoRec * VDGammaInfoPtr;
+struct VDGetGammaListRec {
+ GammaTableID csPreviousGammaTableID;
+ GammaTableID csGammaTableID;
+ unsigned long csGammaTableSize;
+ char * csGammaTableName;
+};
+typedef struct VDGetGammaListRec VDGetGammaListRec;
+typedef VDGetGammaListRec * VDGetGammaListPtr;
+struct VDRetrieveGammaRec {
+ GammaTableID csGammaTableID;
+ GammaTbl * csGammaTablePtr;
+};
+typedef struct VDRetrieveGammaRec VDRetrieveGammaRec;
+typedef VDRetrieveGammaRec * VDRetrieveGammaPtr;
+struct VDSetHardwareCursorRec {
+ void * csCursorRef;
+ UInt32 csReserved1;
+ UInt32 csReserved2;
+};
+typedef struct VDSetHardwareCursorRec VDSetHardwareCursorRec;
+typedef VDSetHardwareCursorRec * VDSetHardwareCursorPtr;
+struct VDDrawHardwareCursorRec {
+ SInt32 csCursorX;
+ SInt32 csCursorY;
+ UInt32 csCursorVisible;
+ UInt32 csReserved1;
+ UInt32 csReserved2;
+};
+typedef struct VDDrawHardwareCursorRec VDDrawHardwareCursorRec;
+typedef VDDrawHardwareCursorRec * VDDrawHardwareCursorPtr;
+struct VDSupportsHardwareCursorRec {
+ UInt32 csSupportsHardwareCursor;
+
+ UInt32 csReserved1;
+ UInt32 csReserved2;
+};
+typedef struct VDSupportsHardwareCursorRec VDSupportsHardwareCursorRec;
+typedef VDSupportsHardwareCursorRec * VDSupportsHardwareCursorPtr;
+struct VDHardwareCursorDrawStateRec {
+ SInt32 csCursorX;
+ SInt32 csCursorY;
+ UInt32 csCursorVisible;
+ UInt32 csCursorSet;
+ UInt32 csReserved1;
+ UInt32 csReserved2;
+};
+typedef struct VDHardwareCursorDrawStateRec VDHardwareCursorDrawStateRec;
+typedef VDHardwareCursorDrawStateRec * VDHardwareCursorDrawStatePtr;
+struct VDConvolutionInfoRec {
+ DisplayModeID csDisplayModeID;
+ DepthMode csDepthMode;
+ unsigned long csPage;
+ UInt32 csFlags;
+ UInt32 csReserved;
+};
+typedef struct VDConvolutionInfoRec VDConvolutionInfoRec;
+typedef VDConvolutionInfoRec * VDConvolutionInfoPtr;
+struct VDPowerStateRec {
+ unsigned long powerState;
+ unsigned long powerFlags;
+
+ unsigned long powerReserved1;
+ unsigned long powerReserved2;
+};
+typedef struct VDPowerStateRec VDPowerStateRec;
+typedef VDPowerStateRec * VDPowerStatePtr;
+struct VDPrivateSelectorDataRec {
+ LogicalAddress privateParameters;
+ ByteCount privateParametersSize;
+ LogicalAddress privateResults;
+ ByteCount privateResultsSize;
+};
+typedef struct VDPrivateSelectorDataRec VDPrivateSelectorDataRec;
+
+struct VDPrivateSelectorRec {
+ UInt32 reserved;
+ VDPrivateSelectorDataRec data[1];
+};
+typedef struct VDPrivateSelectorRec VDPrivateSelectorRec;
+struct VDDDCBlockRec {
+ UInt32 ddcBlockNumber;
+ ResType ddcBlockType;
+ UInt32 ddcFlags;
+ UInt32 ddcReserved;
+ Byte ddcBlockData[128];
+};
+typedef struct VDDDCBlockRec VDDDCBlockRec;
+typedef VDDDCBlockRec * VDDDCBlockPtr;
+
+enum {
+
+ kSyncInterlaceMask = (1 << 7),
+ kSyncAnalogCompositeMask = 0,
+ kSyncAnalogCompositeSerrateMask = (1 << 2),
+ kSyncAnalogCompositeRGBSyncMask = (1 << 1),
+ kSyncAnalogBipolarMask = (1 << 3),
+ kSyncAnalogBipolarSerrateMask = (1 << 2),
+ kSyncAnalogBipolarSRGBSyncMask = (1 << 1),
+ kSyncDigitalCompositeMask = (1 << 4),
+ kSyncDigitalCompositeSerrateMask = (1 << 2),
+ kSyncDigitalCompositeMatchHSyncMask = (1 << 2),
+ kSyncDigitalSeperateMask = (1 << 4) + (1 << 3),
+ kSyncDigitalVSyncPositiveMask = (1 << 2),
+ kSyncDigitalHSyncPositiveMask = (1 << 1)
+};
+
+
+
+struct VDDisplayTimingRangeRec {
+ UInt32 csRangeSize;
+ UInt32 csRangeType;
+ UInt32 csRangeVersion;
+ UInt32 csRangeReserved;
+
+ UInt32 csRangeBlockIndex;
+ UInt32 csRangeGroup;
+ UInt32 csRangeBlockCount;
+ UInt32 csRangeFlags;
+
+ UInt64 csMinPixelClock;
+ UInt64 csMaxPixelClock;
+
+ UInt32 csMaxPixelError;
+ UInt32 csTimingRangeSyncFlags;
+ UInt32 csTimingRangeSignalLevels;
+ UInt32 csReserved0;
+
+ UInt32 csMinFrameRate;
+ UInt32 csMaxFrameRate;
+ UInt32 csMinLineRate;
+ UInt32 csMaxLineRate;
+
+
+ UInt32 csMaxHorizontalTotal;
+ UInt32 csMaxVerticalTotal;
+ UInt32 csMaxTotalReserved1;
+ UInt32 csMaxTotalReserved2;
+ UInt8 csCharSizeHorizontalActive;
+ UInt8 csCharSizeHorizontalBlanking;
+ UInt8 csCharSizeHorizontalSyncOffset;
+ UInt8 csCharSizeHorizontalSyncPulse;
+
+ UInt8 csCharSizeVerticalActive;
+ UInt8 csCharSizeVerticalBlanking;
+ UInt8 csCharSizeVerticalSyncOffset;
+ UInt8 csCharSizeVerticalSyncPulse;
+
+ UInt8 csCharSizeHorizontalBorderLeft;
+ UInt8 csCharSizeHorizontalBorderRight;
+ UInt8 csCharSizeVerticalBorderTop;
+ UInt8 csCharSizeVerticalBorderBottom;
+
+ UInt8 csCharSizeHorizontalTotal;
+ UInt8 csCharSizeVerticalTotal;
+ UInt16 csCharSizeReserved1;
+
+
+ UInt32 csMinHorizontalActiveClocks;
+ UInt32 csMaxHorizontalActiveClocks;
+ UInt32 csMinHorizontalBlankingClocks;
+ UInt32 csMaxHorizontalBlankingClocks;
+
+ UInt32 csMinHorizontalSyncOffsetClocks;
+ UInt32 csMaxHorizontalSyncOffsetClocks;
+ UInt32 csMinHorizontalPulseWidthClocks;
+ UInt32 csMaxHorizontalPulseWidthClocks;
+
+ UInt32 csMinVerticalActiveClocks;
+ UInt32 csMaxVerticalActiveClocks;
+ UInt32 csMinVerticalBlankingClocks;
+ UInt32 csMaxVerticalBlankingClocks;
+
+ UInt32 csMinVerticalSyncOffsetClocks;
+ UInt32 csMaxVerticalSyncOffsetClocks;
+ UInt32 csMinVerticalPulseWidthClocks;
+ UInt32 csMaxVerticalPulseWidthClocks;
+
+
+ UInt32 csMinHorizontalBorderLeft;
+ UInt32 csMaxHorizontalBorderLeft;
+ UInt32 csMinHorizontalBorderRight;
+ UInt32 csMaxHorizontalBorderRight;
+
+ UInt32 csMinVerticalBorderTop;
+ UInt32 csMaxVerticalBorderTop;
+ UInt32 csMinVerticalBorderBottom;
+ UInt32 csMaxVerticalBorderBottom;
+
+ UInt32 csReserved1;
+ UInt32 csReserved2;
+ UInt32 csReserved3;
+ UInt32 csReserved4;
+
+ UInt32 csReserved5;
+ UInt32 csReserved6;
+ UInt32 csReserved7;
+ UInt32 csReserved8;
+};
+typedef struct VDDisplayTimingRangeRec VDDisplayTimingRangeRec;
+typedef VDDisplayTimingRangeRec * VDDisplayTimingRangePtr;
+
+enum {
+
+ kDMSModeReady = 0,
+ kDMSModeNotReady = 1,
+ kDMSModeFree = 2
+};
+
+
+
+enum {
+ kTimingChangeRestrictedErr = -10930,
+ kVideoI2CReplyPendingErr = -10931,
+ kVideoI2CTransactionErr = -10932,
+ kVideoI2CBusyErr = -10933,
+ kVideoI2CTransactionTypeErr = -10934,
+ kVideoBufferSizeErr = -10935
+};
+
+
+enum {
+
+ kRangeSupportsSignal_0700_0300_Bit = 0,
+ kRangeSupportsSignal_0714_0286_Bit = 1,
+ kRangeSupportsSignal_1000_0400_Bit = 2,
+ kRangeSupportsSignal_0700_0000_Bit = 3,
+ kRangeSupportsSignal_0700_0300_Mask = (1 << kRangeSupportsSignal_0700_0300_Bit),
+ kRangeSupportsSignal_0714_0286_Mask = (1 << kRangeSupportsSignal_0714_0286_Bit),
+ kRangeSupportsSignal_1000_0400_Mask = (1 << kRangeSupportsSignal_1000_0400_Bit),
+ kRangeSupportsSignal_0700_0000_Mask = (1 << kRangeSupportsSignal_0700_0000_Bit)
+};
+
+
+enum {
+
+ kDigitalSignalBit = 0,
+ kAnalogSetupExpectedBit = 1,
+ kDigitalSignalMask = (1 << kDigitalSignalBit),
+ kAnalogSetupExpectedMask = (1 << kAnalogSetupExpectedBit)
+};
+
+
+enum {
+
+ kAnalogSignalLevel_0700_0300 = 0,
+ kAnalogSignalLevel_0714_0286 = 1,
+ kAnalogSignalLevel_1000_0400 = 2,
+ kAnalogSignalLevel_0700_0000 = 3
+};
+
+
+enum {
+
+ kRangeSupportsSeperateSyncsBit = 0,
+ kRangeSupportsSyncOnGreenBit = 1,
+ kRangeSupportsCompositeSyncBit = 2,
+ kRangeSupportsVSyncSerrationBit = 3,
+ kRangeSupportsSeperateSyncsMask = (1 << kRangeSupportsSeperateSyncsBit),
+ kRangeSupportsSyncOnGreenMask = (1 << kRangeSupportsSyncOnGreenBit),
+ kRangeSupportsCompositeSyncMask = (1 << kRangeSupportsCompositeSyncBit),
+ kRangeSupportsVSyncSerrationMask = (1 << kRangeSupportsVSyncSerrationBit)
+};
+
+
+
+enum {
+
+ kSyncPositivePolarityBit = 0,
+ kSyncPositivePolarityMask = (1 << kSyncPositivePolarityBit)
+};
+
+
+
+
+
+struct VDDetailedTimingRec {
+ UInt32 csTimingSize;
+ UInt32 csTimingType;
+ UInt32 csTimingVersion;
+ UInt32 csTimingReserved;
+
+ DisplayModeID csDisplayModeID;
+ UInt32 csDisplayModeSeed;
+ UInt32 csDisplayModeState;
+ UInt32 csDisplayModeAlias;
+
+ UInt32 csSignalConfig;
+ UInt32 csSignalLevels;
+
+ UInt64 csPixelClock;
+
+ UInt64 csMinPixelClock;
+ UInt64 csMaxPixelClock;
+
+
+ UInt32 csHorizontalActive;
+ UInt32 csHorizontalBlanking;
+ UInt32 csHorizontalSyncOffset;
+ UInt32 csHorizontalSyncPulseWidth;
+
+ UInt32 csVerticalActive;
+ UInt32 csVerticalBlanking;
+ UInt32 csVerticalSyncOffset;
+ UInt32 csVerticalSyncPulseWidth;
+
+ UInt32 csHorizontalBorderLeft;
+ UInt32 csHorizontalBorderRight;
+ UInt32 csVerticalBorderTop;
+ UInt32 csVerticalBorderBottom;
+
+ UInt32 csHorizontalSyncConfig;
+ UInt32 csHorizontalSyncLevel;
+ UInt32 csVerticalSyncConfig;
+ UInt32 csVerticalSyncLevel;
+
+ UInt32 csReserved1;
+ UInt32 csReserved2;
+ UInt32 csReserved3;
+ UInt32 csReserved4;
+
+ UInt32 csReserved5;
+ UInt32 csReserved6;
+ UInt32 csReserved7;
+ UInt32 csReserved8;
+};
+typedef struct VDDetailedTimingRec VDDetailedTimingRec;
+typedef VDDetailedTimingRec * VDDetailedTimingPtr;
+typedef UInt32 VDClutBehavior;
+typedef VDClutBehavior * VDClutBehaviorPtr;
+enum {
+ kSetClutAtSetEntries = 0,
+ kSetClutAtVBL = 1
+};
+
+
+struct VDCommunicationRec {
+ SInt32 csBusID;
+ UInt32 csCommFlags;
+ UInt32 csMinReplyDelay;
+ UInt32 csReserved2;
+
+ UInt32 csSendAddress;
+ UInt32 csSendType;
+ LogicalAddress csSendBuffer;
+ ByteCount csSendSize;
+
+ UInt32 csReplyAddress;
+ UInt32 csReplyType;
+ LogicalAddress csReplyBuffer;
+ ByteCount csReplySize;
+
+ UInt32 csReserved3;
+ UInt32 csReserved4;
+ UInt32 csReserved5;
+ UInt32 csReserved6;
+};
+typedef struct VDCommunicationRec VDCommunicationRec;
+typedef VDCommunicationRec * VDCommunicationPtr;
+struct VDCommunicationInfoRec {
+ SInt32 csBusID;
+ UInt32 csBusType;
+ SInt32 csMinBus;
+ SInt32 csMaxBus;
+
+ UInt32 csSupportedTypes;
+ UInt32 csSupportedCommFlags;
+ UInt32 csReserved2;
+ UInt32 csReserved3;
+
+ UInt32 csReserved4;
+ UInt32 csReserved5;
+ UInt32 csReserved6;
+ UInt32 csReserved7;
+};
+typedef struct VDCommunicationInfoRec VDCommunicationInfoRec;
+typedef VDCommunicationInfoRec * VDCommunicationInfoPtr;
+
+
+
+
+extern "C" {
+
+
+
+typedef void * DMProcessInfoPtr;
+typedef void * DMModalFilterUPP;
+enum {
+
+ kAESystemConfigNotice = 'cnfg',
+ kAEDisplayNotice = 'dspl',
+ kAEDisplaySummary = 'dsum',
+ keyDMConfigVersion = 'dmcv',
+ keyDMConfigFlags = 'dmcf',
+ keyDMConfigReserved = 'dmcr',
+ keyDisplayID = 'dmid',
+ keyDisplayComponent = 'dmdc',
+ keyDisplayDevice = 'dmdd',
+ keyDisplayFlags = 'dmdf',
+ keyDisplayMode = 'dmdm',
+ keyDisplayModeReserved = 'dmmr',
+ keyDisplayReserved = 'dmdr',
+ keyDisplayMirroredId = 'dmmi',
+ keyDeviceFlags = 'dddf',
+ keyDeviceDepthMode = 'dddm',
+ keyDeviceRect = 'dddr',
+ keyPixMapRect = 'dpdr',
+ keyPixMapHResolution = 'dphr',
+ keyPixMapVResolution = 'dpvr',
+ keyPixMapPixelType = 'dppt',
+ keyPixMapPixelSize = 'dpps',
+ keyPixMapCmpCount = 'dpcc',
+ keyPixMapCmpSize = 'dpcs',
+ keyPixMapAlignment = 'dppa',
+ keyPixMapResReserved = 'dprr',
+ keyPixMapReserved = 'dppr',
+ keyPixMapColorTableSeed = 'dpct',
+ keySummaryMenubar = 'dsmb',
+ keySummaryChanges = 'dsch',
+ keyDisplayOldConfig = 'dold',
+ keyDisplayNewConfig = 'dnew'
+};
+
+enum {
+ dmOnlyActiveDisplays = true,
+ dmAllDisplays = false
+};
+
+
+enum {
+
+ kDependentNotifyClassShowCursor = 'shcr',
+ kDependentNotifyClassDriverOverride = 'ndrv',
+ kDependentNotifyClassDisplayMgrOverride = 'dmgr',
+ kDependentNotifyClassProfileChanged = 'prof'
+};
+
+
+enum {
+
+ kNoSwitchConfirmBit = 0,
+ kDepthNotAvailableBit = 1,
+ kShowModeBit = 3,
+ kModeNotResizeBit = 4,
+ kNeverShowModeBit = 5
+};
+
+
+
+
+enum {
+ kBeginEndConfigureBit = 0,
+ kMovedDisplayBit = 1,
+ kSetMainDisplayBit = 2,
+ kSetDisplayModeBit = 3,
+ kAddDisplayBit = 4,
+ kRemoveDisplayBit = 5,
+ kNewDisplayBit = 6,
+ kDisposeDisplayBit = 7,
+ kEnabledDisplayBit = 8,
+ kDisabledDisplayBit = 9,
+ kMirrorDisplayBit = 10,
+ kUnMirrorDisplayBit = 11
+};
+
+
+enum {
+
+ kDMNotifyRequestConnectionProbe = 0,
+ kDMNotifyInstalled = 1,
+ kDMNotifyEvent = 2,
+ kDMNotifyRemoved = 3,
+ kDMNotifyPrep = 4,
+ kDMNotifyExtendEvent = 5,
+ kDMNotifyDependents = 6,
+ kDMNotifySuspendConfigure = 7,
+ kDMNotifyResumeConfigure = 8,
+ kDMNotifyRequestDisplayProbe = 9,
+ kDMNotifyDisplayWillSleep = 10,
+ kDMNotifyDisplayDidWake = 11,
+
+ kExtendedNotificationProc = (1L << 16)
+};
+
+
+
+enum {
+ kFullNotify = 0,
+ kFullDependencyNotify = 1
+};
+
+
+enum {
+ kDummyDeviceID = 0x00FF,
+ kInvalidDisplayID = 0x0000,
+ kFirstDisplayID = 0x0100
+};
+
+enum {
+
+ kAllowDuplicatesBit = 0
+};
+
+enum {
+
+ kSuppressNumberBit = 0,
+ kSuppressNumberMask = 1,
+ kForceNumberBit = 1,
+ kForceNumberMask = 2,
+ kSuppressNameBit = 2,
+ kSuppressNameMask = 4
+};
+
+
+enum {
+ kDMSupressNumbersMask = (1 << 0),
+ kDMForceNumbersMask = (1 << 1),
+ kDMSupressNameMask = (1 << 2)
+};
+
+
+
+
+enum {
+ kNoFidelity = 0,
+ kMinimumFidelity = 1,
+ kDefaultFidelity = 500,
+ kDefaultManufacturerFidelity = 1000
+};
+
+enum {
+ kAnyPanelType = 0,
+ kAnyEngineType = 0,
+ kAnyDeviceType = 0,
+ kAnyPortType = 0
+};
+
+
+enum {
+
+ kPLIncludeOfflineDevicesBit = 0
+};
+
+
+
+enum {
+ kForceConfirmBit = 0,
+ kForceConfirmMask = (1 << kForceConfirmBit)
+};
+
+
+
+enum {
+ kDisplayModeListNotPreferredBit = 0,
+ kDisplayModeListNotPreferredMask = (1 << kDisplayModeListNotPreferredBit)
+};
+
+
+
+enum {
+ kComponentListNotPreferredBit = 0,
+ kComponentListNotPreferredMask = (1 << kComponentListNotPreferredBit)
+};
+
+enum {
+ kDisplayTimingInfoVersionZero = 1,
+ kDisplayTimingInfoReservedCountVersionZero = 16,
+ kDisplayModeEntryVersionZero = 0,
+ kDisplayModeEntryVersionOne = 1
+};
+
+
+enum {
+ kMakeAndModelReservedCount = 4
+};
+
+
+
+enum {
+ kDisplayGestaltDisplayCommunicationAttr = 'comm',
+ kDisplayGestaltForbidI2CMask = (1 << 0),
+ kDisplayGestaltUseI2CPowerMask = (1 << 1),
+ kDisplayGestaltCalibratorAttr = 'cali',
+ kDisplayGestaltBrightnessAffectsGammaMask = (1 << 0),
+ kDisplayGestaltViewAngleAffectsGammaMask = (1 << 1)
+};
+
+
+typedef UInt32 DMFidelityType;
+
+
+
+
+
+
+typedef void * DMListType;
+typedef unsigned long DMListIndexType;
+typedef VDPowerStateRec AVPowerStateRec;
+typedef VDPowerStateRec * AVPowerStatePtr;
+struct DMDisplayTimingInfoRec {
+ UInt32 timingInfoVersion;
+ UInt32 timingInfoAttributes;
+ SInt32 timingInfoRelativeQuality;
+ SInt32 timingInfoRelativeDefault;
+
+ UInt32 timingInfoReserved[16];
+};
+typedef struct DMDisplayTimingInfoRec DMDisplayTimingInfoRec;
+typedef DMDisplayTimingInfoRec * DMDisplayTimingInfoPtr;
+
+struct DMComponentListEntryRec {
+ DisplayIDType itemID;
+ Component itemComponent;
+ ComponentDescription itemDescription;
+
+ ResType itemClass;
+ DMFidelityType itemFidelity;
+ ResType itemSubClass;
+ Point itemSort;
+
+ unsigned long itemFlags;
+ ResType itemReserved;
+ unsigned long itemFuture1;
+ unsigned long itemFuture2;
+ unsigned long itemFuture3;
+ unsigned long itemFuture4;
+};
+typedef struct DMComponentListEntryRec DMComponentListEntryRec;
+typedef DMComponentListEntryRec * DMComponentListEntryPtr;
+
+struct AVLocationRec {
+ unsigned long locationConstant;
+};
+typedef struct AVLocationRec AVLocationRec;
+typedef AVLocationRec * AVLocationPtr;
+struct DMDepthInfoRec {
+ VDSwitchInfoPtr depthSwitchInfo;
+ VPBlockPtr depthVPBlock;
+ UInt32 depthFlags;
+ UInt32 depthReserved1;
+ UInt32 depthReserved2;
+};
+typedef struct DMDepthInfoRec DMDepthInfoRec;
+typedef DMDepthInfoRec * DMDepthInfoPtr;
+struct DMDepthInfoBlockRec {
+ unsigned long depthBlockCount;
+ DMDepthInfoPtr depthVPBlock;
+ unsigned long depthBlockFlags;
+ unsigned long depthBlockReserved1;
+ unsigned long depthBlockReserved2;
+};
+typedef struct DMDepthInfoBlockRec DMDepthInfoBlockRec;
+typedef DMDepthInfoBlockRec * DMDepthInfoBlockPtr;
+struct DMDisplayModeListEntryRec {
+ UInt32 displayModeFlags;
+ VDSwitchInfoPtr displayModeSwitchInfo;
+ VDResolutionInfoPtr displayModeResolutionInfo;
+ VDTimingInfoPtr displayModeTimingInfo;
+ DMDepthInfoBlockPtr displayModeDepthBlockInfo;
+ UInt32 displayModeVersion;
+ StringPtr displayModeName;
+ DMDisplayTimingInfoPtr displayModeDisplayInfo;
+};
+typedef struct DMDisplayModeListEntryRec DMDisplayModeListEntryRec;
+typedef DMDisplayModeListEntryRec * DMDisplayModeListEntryPtr;
+
+struct DependentNotifyRec {
+ ResType notifyType;
+ ResType notifyClass;
+ DisplayIDType notifyPortID;
+ ComponentInstance notifyComponent;
+
+ unsigned long notifyVersion;
+ unsigned long notifyFlags;
+ unsigned long notifyReserved;
+ unsigned long notifyFuture;
+};
+typedef struct DependentNotifyRec DependentNotifyRec;
+typedef DependentNotifyRec * DependentNotifyPtr;
+
+struct DMMakeAndModelRec {
+ ResType manufacturer;
+ UInt32 model;
+ UInt32 serialNumber;
+ UInt32 manufactureDate;
+
+ UInt32 makeReserved[4];
+};
+typedef struct DMMakeAndModelRec DMMakeAndModelRec;
+typedef DMMakeAndModelRec * DMMakeAndModelPtr;
+
+enum {
+ kIncludeOnlineActiveDisplaysMask = (1 << 0),
+ kIncludeOnlineDisabledDisplaysMask = (1 << 1),
+ kIncludeOfflineDisplaysMask = (1 << 2),
+ kIncludeOfflineDummyDisplaysMask = (1 << 3),
+ kIncludeHardwareMirroredDisplaysMask = (1 << 4)
+};
+
+
+enum {
+
+ kDMModeListIncludeAllModesMask = (1 << 0),
+ kDMModeListIncludeOfflineModesMask = (1 << 1),
+ kDMModeListExcludeDriverModesMask = (1 << 2),
+ kDMModeListExcludeDisplayModesMask = (1 << 3),
+ kDMModeListExcludeCustomModesMask = (1 << 4),
+ kDMModeListPreferStretchedModesMask = (1 << 5),
+ kDMModeListPreferSafeModesMask = (1 << 6)
+};
+
+
+
+struct DisplayListEntryRec {
+ GDHandle displayListEntryGDevice;
+ DisplayIDType displayListEntryDisplayID;
+ UInt32 displayListEntryIncludeFlags;
+ UInt32 displayListEntryReserved1;
+
+ UInt32 displayListEntryReserved2;
+ UInt32 displayListEntryReserved3;
+ UInt32 displayListEntryReserved4;
+ UInt32 displayListEntryReserved5;
+};
+typedef struct DisplayListEntryRec DisplayListEntryRec;
+typedef DisplayListEntryRec * DisplayListEntryPtr;
+struct DMProfileListEntryRec {
+ CMProfileRef profileRef;
+ Ptr profileReserved1;
+ Ptr profileReserved2;
+ Ptr profileReserved3;
+};
+typedef struct DMProfileListEntryRec DMProfileListEntryRec;
+typedef DMProfileListEntryRec * DMProfileListEntryPtr;
+typedef void ( * DMNotificationProcPtr)(AppleEvent * theEvent);
+typedef void ( * DMExtendedNotificationProcPtr)(void *userData, short theMessage, void *notifyData);
+typedef void ( * DMComponentListIteratorProcPtr)(void *userData, DMListIndexType itemIndex, DMComponentListEntryPtr componentInfo);
+typedef void ( * DMDisplayModeListIteratorProcPtr)(void *userData, DMListIndexType itemIndex, DMDisplayModeListEntryPtr displaymodeInfo);
+typedef void ( * DMProfileListIteratorProcPtr)(void *userData, DMListIndexType itemIndex, DMProfileListEntryPtr profileInfo);
+typedef void ( * DMDisplayListIteratorProcPtr)(void *userData, DMListIndexType itemIndex, DisplayListEntryPtr displaymodeInfo);
+typedef DMNotificationProcPtr DMNotificationUPP;
+typedef DMExtendedNotificationProcPtr DMExtendedNotificationUPP;
+typedef DMComponentListIteratorProcPtr DMComponentListIteratorUPP;
+typedef DMDisplayModeListIteratorProcPtr DMDisplayModeListIteratorUPP;
+typedef DMProfileListIteratorProcPtr DMProfileListIteratorUPP;
+typedef DMDisplayListIteratorProcPtr DMDisplayListIteratorUPP;
+extern DMNotificationUPP
+NewDMNotificationUPP(DMNotificationProcPtr userRoutine) ;
+extern DMExtendedNotificationUPP
+NewDMExtendedNotificationUPP(DMExtendedNotificationProcPtr userRoutine) ;
+extern DMComponentListIteratorUPP
+NewDMComponentListIteratorUPP(DMComponentListIteratorProcPtr userRoutine) ;
+extern DMDisplayModeListIteratorUPP
+NewDMDisplayModeListIteratorUPP(DMDisplayModeListIteratorProcPtr userRoutine) ;
+extern DMProfileListIteratorUPP
+NewDMProfileListIteratorUPP(DMProfileListIteratorProcPtr userRoutine) ;
+extern DMDisplayListIteratorUPP
+NewDMDisplayListIteratorUPP(DMDisplayListIteratorProcPtr userRoutine) ;
+extern void
+DisposeDMNotificationUPP(DMNotificationUPP userUPP) ;
+extern void
+DisposeDMExtendedNotificationUPP(DMExtendedNotificationUPP userUPP) ;
+extern void
+DisposeDMComponentListIteratorUPP(DMComponentListIteratorUPP userUPP) ;
+extern void
+DisposeDMDisplayModeListIteratorUPP(DMDisplayModeListIteratorUPP userUPP) ;
+extern void
+DisposeDMProfileListIteratorUPP(DMProfileListIteratorUPP userUPP) ;
+extern void
+DisposeDMDisplayListIteratorUPP(DMDisplayListIteratorUPP userUPP) ;
+extern void
+InvokeDMNotificationUPP(
+ AppleEvent * theEvent,
+ DMNotificationUPP userUPP) ;
+extern void
+InvokeDMExtendedNotificationUPP(
+ void * userData,
+ short theMessage,
+ void * notifyData,
+ DMExtendedNotificationUPP userUPP) ;
+extern void
+InvokeDMComponentListIteratorUPP(
+ void * userData,
+ DMListIndexType itemIndex,
+ DMComponentListEntryPtr componentInfo,
+ DMComponentListIteratorUPP userUPP) ;
+extern void
+InvokeDMDisplayModeListIteratorUPP(
+ void * userData,
+ DMListIndexType itemIndex,
+ DMDisplayModeListEntryPtr displaymodeInfo,
+ DMDisplayModeListIteratorUPP userUPP) ;
+extern void
+InvokeDMProfileListIteratorUPP(
+ void * userData,
+ DMListIndexType itemIndex,
+ DMProfileListEntryPtr profileInfo,
+ DMProfileListIteratorUPP userUPP) ;
+extern void
+InvokeDMDisplayListIteratorUPP(
+ void * userData,
+ DMListIndexType itemIndex,
+ DisplayListEntryPtr displaymodeInfo,
+ DMDisplayListIteratorUPP userUPP) ;
+extern GDHandle
+DMGetFirstScreenDevice(Boolean activeOnly) ;
+extern GDHandle
+DMGetNextScreenDevice(
+ GDHandle theDevice,
+ Boolean activeOnly) ;
+extern void
+DMDrawDesktopRect(Rect * globalRect) ;
+extern void
+DMDrawDesktopRegion(RgnHandle globalRgn) ;
+extern OSErr
+DMBeginConfigureDisplays(Handle * displayState) ;
+extern OSErr
+DMEndConfigureDisplays(Handle displayState) ;
+extern OSErr
+DMAddDisplay(
+ GDHandle newDevice,
+ short driver,
+ unsigned long mode,
+ unsigned long reserved,
+ unsigned long displayID,
+ Component displayComponent,
+ Handle displayState) ;
+extern OSErr
+DMMoveDisplay(
+ GDHandle moveDevice,
+ short x,
+ short y,
+ Handle displayState) ;
+extern OSErr
+DMDisableDisplay(
+ GDHandle disableDevice,
+ Handle displayState) ;
+extern OSErr
+DMEnableDisplay(
+ GDHandle enableDevice,
+ Handle displayState) ;
+extern OSErr
+DMRemoveDisplay(
+ GDHandle removeDevice,
+ Handle displayState) ;
+extern OSErr
+DMSetMainDisplay(
+ GDHandle newMainDevice,
+ Handle displayState) ;
+extern OSErr
+DMSetDisplayMode(
+ GDHandle theDevice,
+ unsigned long mode,
+ unsigned long * depthMode,
+ unsigned long reserved,
+ Handle displayState) ;
+extern OSErr
+DMCheckDisplayMode(
+ GDHandle theDevice,
+ unsigned long mode,
+ unsigned long depthMode,
+ unsigned long * switchFlags,
+ unsigned long reserved,
+ Boolean * modeOk) ;
+extern OSErr
+DMGetDeskRegion(RgnHandle * desktopRegion) ;
+extern OSErr
+DMRegisterNotifyProc(
+ DMNotificationUPP notificationProc,
+ DMProcessInfoPtr whichPSN) ;
+extern OSErr
+DMRemoveNotifyProc(
+ DMNotificationUPP notificationProc,
+ DMProcessInfoPtr whichPSN) ;
+extern OSErr
+DMQDIsMirroringCapable(Boolean * qdIsMirroringCapable) ;
+extern OSErr
+DMCanMirrorNow(Boolean * canMirrorNow) ;
+extern OSErr
+DMIsMirroringOn(Boolean * isMirroringOn) ;
+extern OSErr
+DMMirrorDevices(
+ GDHandle gD1,
+ GDHandle gD2,
+ Handle displayState) ;
+extern OSErr
+DMUnmirrorDevice(
+ GDHandle gDevice,
+ Handle displayState) ;
+extern OSErr
+DMGetNextMirroredDevice(
+ GDHandle gDevice,
+ GDHandle * mirroredDevice) ;
+extern OSErr
+DMBlockMirroring(void) ;
+extern OSErr
+DMUnblockMirroring(void) ;
+extern OSErr
+DMGetDisplayIDByGDevice(
+ GDHandle displayDevice,
+ DisplayIDType * displayID,
+ Boolean failToMain) ;
+extern OSErr
+DMGetGDeviceByDisplayID(
+ DisplayIDType displayID,
+ GDHandle * displayDevice,
+ Boolean failToMain) ;
+extern OSErr
+DMSetDisplayComponent(
+ GDHandle theDevice,
+ Component displayComponent) ;
+extern OSErr
+DMGetDisplayComponent(
+ GDHandle theDevice,
+ Component * displayComponent) ;
+extern OSErr
+DMNewDisplay(
+ GDHandle * newDevice,
+ short driverRefNum,
+ unsigned long mode,
+ unsigned long reserved,
+ DisplayIDType displayID,
+ Component displayComponent,
+ Handle displayState) ;
+extern OSErr
+DMDisposeDisplay(
+ GDHandle disposeDevice,
+ Handle displayState) ;
+extern OSErr
+DMResolveDisplayComponents(void) ;
+extern OSErr
+DMRegisterExtendedNotifyProc(
+ DMExtendedNotificationUPP notifyProc,
+ void * notifyUserData,
+ unsigned short nofifyOnFlags,
+ DMProcessInfoPtr whichPSN) ;
+extern OSErr
+DMRemoveExtendedNotifyProc(
+ DMExtendedNotificationUPP notifyProc,
+ void * notifyUserData,
+ DMProcessInfoPtr whichPSN,
+ unsigned short removeFlags) ;
+extern OSErr
+DMNewAVPanelList(
+ DisplayIDType displayID,
+ ResType panelType,
+ DMFidelityType minimumFidelity,
+ unsigned long panelListFlags,
+ unsigned long reserved,
+ DMListIndexType * thePanelCount,
+ DMListType * thePanelList) ;
+extern OSErr
+DMNewAVEngineList(
+ DisplayIDType displayID,
+ ResType engineType,
+ DMFidelityType minimumFidelity,
+ unsigned long engineListFlags,
+ unsigned long reserved,
+ DMListIndexType * engineCount,
+ DMListType * engineList) ;
+extern OSErr
+DMNewAVDeviceList(
+ ResType deviceType,
+ unsigned long deviceListFlags,
+ unsigned long reserved,
+ DMListIndexType * deviceCount,
+ DMListType * deviceList) ;
+extern OSErr
+DMNewAVPortListByPortType(
+ ResType subType,
+ unsigned long portListFlags,
+ unsigned long reserved,
+ DMListIndexType * devicePortCount,
+ DMListType * theDevicePortList) ;
+extern OSErr
+DMGetIndexedComponentFromList(
+ DMListType panelList,
+ DMListIndexType itemIndex,
+ unsigned long reserved,
+ DMComponentListIteratorUPP listIterator,
+ void * userData) ;
+extern OSErr
+DMDisposeList(DMListType panelList) ;
+extern OSErr
+DMGetNameByAVID(
+ AVIDType theID,
+ unsigned long nameFlags,
+ Str255 name) ;
+extern OSErr
+DMNewAVIDByPortComponent(
+ Component thePortComponent,
+ ResType portKind,
+ unsigned long reserved,
+ AVIDType * newID) ;
+extern OSErr
+DMGetPortComponentByAVID(
+ DisplayIDType thePortID,
+ Component * thePortComponent,
+ ComponentDescription * theDesciption,
+ ResType * thePortKind) ;
+extern OSErr
+DMSendDependentNotification(
+ ResType notifyType,
+ ResType notifyClass,
+ AVIDType displayID,
+ ComponentInstance notifyComponent) ;
+extern OSErr
+DMDisposeAVComponent(Component theAVComponent) ;
+extern OSErr
+DMSaveScreenPrefs(
+ unsigned long reserved1,
+ unsigned long saveFlags,
+ unsigned long reserved2) ;
+extern OSErr
+DMNewAVIDByDeviceComponent(
+ Component theDeviceComponent,
+ ResType portKind,
+ unsigned long reserved,
+ DisplayIDType * newID) ;
+extern OSErr
+DMNewAVPortListByDeviceAVID(
+ AVIDType theID,
+ DMFidelityType minimumFidelity,
+ unsigned long portListFlags,
+ unsigned long reserved,
+ DMListIndexType * devicePortCount,
+ DMListType * theDevicePortList) ;
+extern OSErr
+DMGetDeviceComponentByAVID(
+ AVIDType theDeviceID,
+ Component * theDeviceComponent,
+ ComponentDescription * theDesciption,
+ ResType * theDeviceKind) ;
+extern OSErr
+DMNewDisplayModeList(
+ DisplayIDType displayID,
+ unsigned long modeListFlags,
+ unsigned long reserved,
+ DMListIndexType * thePanelCount,
+ DMListType * thePanelList) ;
+extern OSErr
+DMGetIndexedDisplayModeFromList(
+ DMListType panelList,
+ DMListIndexType itemIndex,
+ unsigned long reserved,
+ DMDisplayModeListIteratorUPP listIterator,
+ void * userData) ;
+extern OSErr
+DMGetGraphicInfoByAVID(
+ AVIDType theID,
+ PicHandle * theAVPcit,
+ Handle * theAVIconSuite,
+ AVLocationRec * theAVLocation) ;
+extern OSErr
+DMGetAVPowerState(
+ AVIDType theID,
+ AVPowerStatePtr getPowerState,
+ unsigned long reserved1) ;
+extern OSErr
+DMSetAVPowerState(
+ AVIDType theID,
+ AVPowerStatePtr setPowerState,
+ unsigned long powerFlags,
+ Handle displayState) ;
+extern OSErr
+DMGetDeviceAVIDByPortAVID(
+ AVIDType portAVID,
+ AVIDType * deviceAVID) ;
+extern OSErr
+DMGetEnableByAVID(
+ AVIDType theAVID,
+ Boolean * isAVIDEnabledNow,
+ Boolean * canChangeEnableNow) ;
+extern OSErr
+DMSetEnableByAVID(
+ AVIDType theAVID,
+ Boolean doEnable,
+ Handle displayState) ;
+extern OSErr
+DMGetDisplayMode(
+ GDHandle theDevice,
+ VDSwitchInfoPtr switchInfo) ;
+extern OSErr
+DMConfirmConfiguration(
+ DMModalFilterUPP filterProc,
+ UInt32 confirmFlags,
+ UInt32 reserved,
+ Handle displayState) ;
+
+
+
+
+
+}
+
+
+
+extern "C" {
+
+
+
+
+
+typedef UInt32 FNSMatchOptions;
+enum {
+ kFNSMatchNames = 0x00000001,
+ kFNSMatchTechnology = 0x00000002,
+ kFNSMatchGlyphs = 0x00000004,
+ kFNSMatchEncodings = 0x00000008,
+ kFNSMatchQDMetrics = 0x00000010,
+ kFNSMatchATSUMetrics = 0x00000020,
+ kFNSMatchKerning = 0x00000040,
+ kFNSMatchWSLayout = 0x00000080,
+ kFNSMatchAATLayout = 0x00000100,
+ kFNSMatchPrintEncoding = 0x00000200,
+ kFNSMissingDataNoMatch = (unsigned long)0x80000000,
+ kFNSMatchAll = (unsigned long)0xFFFFFFFF,
+ kFNSMatchDefaults = 0
+};
+extern FNSMatchOptions
+FNSMatchDefaultsGet(void) ;
+
+
+
+
+typedef UInt32 FNSObjectVersion;
+enum {
+ kFNSVersionDontCare = 0,
+ kFNSCurSysInfoVersion = 1
+};
+
+
+typedef UInt32 FNSFeatureFlags;
+
+
+
+
+struct FNSSysInfo {
+ FNSObjectVersion iSysInfoVersion;
+ FNSFeatureFlags oFeatures;
+ FNSObjectVersion oCurRefVersion;
+ FNSObjectVersion oMinRefVersion;
+ FNSObjectVersion oCurProfileVersion;
+ FNSObjectVersion oMinProfileVersion;
+ UInt16 oFontSyncVersion;
+};
+typedef struct FNSSysInfo FNSSysInfo;
+extern void
+FNSSysInfoGet(FNSSysInfo * ioInfo) ;
+
+
+
+
+typedef struct OpaqueFNSFontReference* FNSFontReference;
+extern OSStatus
+FNSReferenceGetVersion(
+ FNSFontReference iReference,
+ FNSObjectVersion * oVersion) ;
+extern OSStatus
+FNSReferenceDispose(FNSFontReference iReference) ;
+extern OSStatus
+FNSReferenceMatch(
+ FNSFontReference iReference1,
+ FNSFontReference iReference2,
+ FNSMatchOptions iOptions,
+ FNSMatchOptions * oFailedMatchOptions) ;
+extern OSStatus
+FNSReferenceFlattenedSize(
+ FNSFontReference iReference,
+ ByteCount * oFlattenedSize) ;
+extern OSStatus
+FNSReferenceFlatten(
+ FNSFontReference iReference,
+ void * oFlatReference,
+ ByteCount * oFlattenedSize) ;
+extern OSStatus
+FNSReferenceUnflatten(
+ const void * iFlatReference,
+ ByteCount iFlattenedSize,
+ FNSFontReference * oReference) ;
+
+
+
+
+enum {
+ kFNSCreatorDefault = 0,
+ kFNSProfileFileType = 'fnsp'
+};
+
+typedef struct OpaqueFNSFontProfile* FNSFontProfile;
+extern OSStatus
+FNSProfileCreate(
+ const FSSpec * iFile,
+ FourCharCode iCreator,
+ ItemCount iEstNumRefs,
+ FNSObjectVersion iDesiredVersion,
+ FNSFontProfile * oProfile) ;
+extern OSStatus
+FNSProfileOpen(
+ const FSSpec * iFile,
+ Boolean iOpenForWrite,
+ FNSFontProfile * oProfile) ;
+extern OSStatus
+FNSProfileCreateWithFSRef(
+ const FSRef * iParentDirectory,
+ UniCharCount iNameLength,
+ const UniChar * iName,
+ FourCharCode iCreator,
+ ItemCount iEstNumRefs,
+ FNSObjectVersion iDesiredVersion,
+ FNSFontProfile * oProfile) ;
+extern OSStatus
+FNSProfileOpenWithFSRef(
+ const FSRef * iFile,
+ Boolean iOpenForWrite,
+ FNSFontProfile * oProfile) ;
+extern OSStatus
+FNSProfileGetVersion(
+ FNSFontProfile iProfile,
+ FNSObjectVersion * oVersion) ;
+extern OSStatus
+FNSProfileCompact(FNSFontProfile iProfile) ;
+extern OSStatus
+FNSProfileClose(FNSFontProfile iProfile) ;
+extern OSStatus
+FNSProfileAddReference(
+ FNSFontProfile iProfile,
+ FNSFontReference iReference) ;
+extern OSStatus
+FNSProfileRemoveReference(
+ FNSFontProfile iProfile,
+ FNSFontReference iReference) ;
+extern OSStatus
+FNSProfileRemoveIndReference(
+ FNSFontProfile iProfile,
+ UInt32 iIndex) ;
+extern OSStatus
+FNSProfileClear(FNSFontProfile iProfile) ;
+extern OSStatus
+FNSProfileCountReferences(
+ FNSFontProfile iProfile,
+ ItemCount * oCount) ;
+extern OSStatus
+FNSProfileGetIndReference(
+ FNSFontProfile iProfile,
+ UInt32 iWhichReference,
+ FNSFontReference * oReference) ;
+extern OSStatus
+FNSProfileMatchReference(
+ FNSFontProfile iProfile,
+ FNSFontReference iReference,
+ FNSMatchOptions iMatchOptions,
+ ItemCount iOutputSize,
+ UInt32 oIndices[],
+ ItemCount * oNumMatches) ;
+extern OSStatus
+FNSReferenceCreate(
+ FMFont iFont,
+ FNSObjectVersion iDesiredVersion,
+ FNSFontReference * oReference) ;
+extern OSStatus
+FNSReferenceMatchFonts(
+ FNSFontReference iReference,
+ FNSMatchOptions iMatchOptions,
+ ItemCount iOutputSize,
+ FMFont oFonts[],
+ ItemCount * oNumMatches) ;
+extern OSStatus
+FNSReferenceCreateFromFamily(
+ FMFontFamily iFamily,
+ FMFontStyle iStyle,
+ FNSObjectVersion iDesiredVersion,
+ FNSFontReference * oReference,
+ FMFontStyle * oActualStyle) ;
+extern OSStatus
+FNSReferenceMatchFamilies(
+ FNSFontReference iReference,
+ FNSMatchOptions iMatchOptions,
+ ItemCount iOutputSize,
+ FMFontFamilyInstance oFonts[],
+ ItemCount * oNumMatches) ;
+extern OSStatus
+FNSReferenceGetFamilyInfo(
+ FNSFontReference iReference,
+ Str255 oFamilyName,
+ ScriptCode * oFamilyNameScript,
+ FMFontStyle * oActualStyle) ;
+extern OSStatus
+FNSReferenceCountNames(
+ FNSFontReference iReference,
+ ItemCount * oNameCount) ;
+extern OSStatus
+FNSReferenceGetIndName(
+ FNSFontReference iReference,
+ ItemCount iFontNameIndex,
+ ByteCount iMaximumNameLength,
+ Ptr oName,
+ ByteCount * oActualNameLength,
+ FontNameCode * oFontNameCode,
+ FontPlatformCode * oFontNamePlatform,
+ FontScriptCode * oFontNameScript,
+ FontLanguageCode * oFontNameLanguage) ;
+extern OSStatus
+FNSReferenceFindName(
+ FNSFontReference iReference,
+ FontNameCode iFontNameCode,
+ FontPlatformCode iFontNamePlatform,
+ FontScriptCode iFontNameScript,
+ FontLanguageCode iFontNameLanguage,
+ ByteCount iMaximumNameLength,
+ Ptr oName,
+ ByteCount * oActualNameLength,
+ ItemCount * oFontNameIndex) ;
+extern Boolean
+FNSEnabled(void) ;
+
+
+
+
+
+}
+
+
+
+extern "C" {
+
+
+typedef UInt32 ATSUFlattenedDataStreamFormat;
+enum {
+ kATSUDataStreamUnicodeStyledText = 'ustl'
+};
+
+
+
+
+
+
+
+typedef UInt32 ATSUFlattenStyleRunOptions;
+enum {
+ kATSUFlattenOptionNoOptionsMask = 0x00000000
+};
+
+
+
+
+
+
+typedef UInt32 ATSUUnFlattenStyleRunOptions;
+enum {
+ kATSUUnFlattenOptionNoOptionsMask = 0x00000000
+};
+struct ATSUStyleRunInfo {
+ UniCharCount runLength;
+ ItemCount styleObjectIndex;
+};
+typedef struct ATSUStyleRunInfo ATSUStyleRunInfo;
+enum {
+ kATSFlatDataUstlVersion0 = 0,
+ kATSFlatDataUstlVersion1 = 1,
+ kATSFlatDataUstlVersion2 = 2,
+ kATSFlatDataUstlCurrentVersion = kATSFlatDataUstlVersion2
+};
+struct ATSFlatDataMainHeaderBlock {
+
+
+
+
+ UInt32 version;
+
+
+
+ ByteCount sizeOfDataBlock;
+
+
+
+ ByteCount offsetToTextLayouts;
+
+
+
+ ByteCount offsetToStyleRuns;
+
+
+
+ ByteCount offsetToStyleList;
+};
+typedef struct ATSFlatDataMainHeaderBlock ATSFlatDataMainHeaderBlock;
+struct ATSFlatDataTextLayoutDataHeader {
+
+
+
+ ByteCount sizeOfLayoutData;
+
+
+ ByteCount textLayoutLength;
+
+
+
+
+ ByteCount offsetToLayoutControls;
+
+
+
+
+ ByteCount offsetToLineInfo;
+
+
+
+
+
+
+
+};
+typedef struct ATSFlatDataTextLayoutDataHeader ATSFlatDataTextLayoutDataHeader;
+
+
+
+
+
+struct ATSFlatDataLayoutControlsDataHeader {
+
+
+
+ ItemCount numberOfLayoutControls;
+ ATSUAttributeInfo controlArray[1];
+};
+typedef struct ATSFlatDataLayoutControlsDataHeader ATSFlatDataLayoutControlsDataHeader;
+struct ATSFlatDataLineInfoData {
+
+
+ UniCharCount lineLength;
+
+
+
+ ItemCount numberOfLineControls;
+
+
+
+
+};
+typedef struct ATSFlatDataLineInfoData ATSFlatDataLineInfoData;
+
+
+
+
+
+struct ATSFlatDataLineInfoHeader {
+
+
+
+
+
+ ItemCount numberOfLines;
+
+
+
+
+ ATSFlatDataLineInfoData lineInfoArray[1];
+};
+typedef struct ATSFlatDataLineInfoHeader ATSFlatDataLineInfoHeader;
+struct ATSFlatDataStyleRunDataHeader {
+
+
+ ItemCount numberOfStyleRuns;
+
+
+
+
+ ATSUStyleRunInfo styleRunArray[1];
+};
+typedef struct ATSFlatDataStyleRunDataHeader ATSFlatDataStyleRunDataHeader;
+struct ATSFlatDataStyleListStyleDataHeader {
+
+
+
+
+ ByteCount sizeOfStyleInfo;
+
+
+
+
+ ItemCount numberOfSetAttributes;
+
+
+
+ ItemCount numberOfSetFeatures;
+
+
+
+ ItemCount numberOfSetVariations;
+};
+typedef struct ATSFlatDataStyleListStyleDataHeader ATSFlatDataStyleListStyleDataHeader;
+
+
+
+
+
+struct ATSFlatDataStyleListHeader {
+
+
+ ItemCount numberOfStyles;
+
+
+
+
+
+
+ ATSFlatDataStyleListStyleDataHeader styleDataArray[1];
+
+};
+typedef struct ATSFlatDataStyleListHeader ATSFlatDataStyleListHeader;
+
+
+
+
+
+struct ATSFlatDataStyleListFeatureData {
+
+
+ ATSUFontFeatureType theFeatureType;
+
+
+ ATSUFontFeatureSelector theFeatureSelector;
+};
+typedef struct ATSFlatDataStyleListFeatureData ATSFlatDataStyleListFeatureData;
+
+
+
+
+
+
+struct ATSFlatDataStyleListVariationData {
+
+
+ ATSUFontVariationAxis theVariationAxis;
+
+
+ ATSUFontVariationValue theVariationValue;
+};
+typedef struct ATSFlatDataStyleListVariationData ATSFlatDataStyleListVariationData;
+typedef UInt32 ATSFlatDataFontSpeciferType;
+enum {
+
+
+ kATSFlattenedFontSpecifierRawNameData = 'namd'
+};
+
+
+
+
+
+
+struct ATSFlatDataFontNameDataHeader {
+
+
+ ATSFlatDataFontSpeciferType nameSpecifierType;
+
+
+
+
+
+ ByteCount nameSpecifierSize;
+
+
+
+
+
+
+
+};
+typedef struct ATSFlatDataFontNameDataHeader ATSFlatDataFontNameDataHeader;
+
+
+
+
+
+
+
+struct ATSFlatDataFontSpecRawNameData {
+
+
+ FontNameCode fontNameType;
+
+
+
+
+
+ FontPlatformCode fontNamePlatform;
+
+
+
+
+
+ FontScriptCode fontNameScript;
+
+
+
+
+ FontLanguageCode fontNameLanguage;
+
+
+
+ ByteCount fontNameLength;
+
+
+
+
+};
+typedef struct ATSFlatDataFontSpecRawNameData ATSFlatDataFontSpecRawNameData;
+struct ATSFlatDataFontSpecRawNameDataHeader {
+
+
+
+ ItemCount numberOfFlattenedNames;
+
+
+
+
+
+ ATSFlatDataFontSpecRawNameData nameDataArray[1];
+
+};
+typedef struct ATSFlatDataFontSpecRawNameDataHeader ATSFlatDataFontSpecRawNameDataHeader;
+extern OSStatus
+ATSUFlattenStyleRunsToStream(
+ ATSUFlattenedDataStreamFormat iStreamFormat,
+ ATSUFlattenStyleRunOptions iFlattenOptions,
+ ItemCount iNumberOfRunInfo,
+ const ATSUStyleRunInfo iRunInfoArray[],
+ ItemCount iNumberOfStyleObjects,
+ const ATSUStyle iStyleArray[],
+ ByteCount iStreamBufferSize,
+ void * oStreamBuffer,
+ ByteCount * oActualStreamBufferSize) ;
+extern OSStatus
+ATSUUnflattenStyleRunsFromStream(
+ ATSUFlattenedDataStreamFormat iStreamFormat,
+ ATSUUnFlattenStyleRunOptions iUnflattenOptions,
+ ByteCount iStreamBufferSize,
+ const void * iStreamBuffer,
+ ItemCount iNumberOfRunInfo,
+ ItemCount iNumberOfStyleObjects,
+ ATSUStyleRunInfo oRunInfoArray[],
+ ATSUStyle oStyleArray[],
+ ItemCount * oActualNumberOfRunInfo,
+ ItemCount * oActualNumberOfStyleObjects) ;
+
+
+
+
+
+}
+
+
+
+extern "C" {
+typedef UInt32 ATSUDirectDataSelector;
+enum {
+ kATSUDirectDataAdvanceDeltaFixedArray = 0L,
+ kATSUDirectDataBaselineDeltaFixedArray = 1L,
+ kATSUDirectDataDeviceDeltaSInt16Array = 2L,
+ kATSUDirectDataStyleIndexUInt16Array = 3L,
+ kATSUDirectDataStyleSettingATSUStyleSettingRefArray = 4L,
+ kATSUDirectDataLayoutRecordATSLayoutRecordVersion1 = 100L,
+ kATSUDirectDataLayoutRecordATSLayoutRecordCurrent = kATSUDirectDataLayoutRecordATSLayoutRecordVersion1
+};
+typedef struct ATSStyleSetting* ATSUStyleSettingRef;
+extern OSStatus
+ATSUDirectGetLayoutDataArrayPtrFromLineRef(
+ ATSULineRef iLineRef,
+ ATSUDirectDataSelector iDataSelector,
+ Boolean iCreate,
+ void * oLayoutDataArrayPtr[],
+ ItemCount * oLayoutDataCount) ;
+extern OSStatus
+ATSUDirectGetLayoutDataArrayPtrFromTextLayout(
+ ATSUTextLayout iTextLayout,
+ UniCharArrayOffset iLineOffset,
+ ATSUDirectDataSelector iDataSelector,
+ void * oLayoutDataArrayPtr[],
+ ItemCount * oLayoutDataCount) ;
+extern OSStatus
+ATSUDirectReleaseLayoutDataArrayPtr(
+ ATSULineRef iLineRef,
+ ATSUDirectDataSelector iDataSelector,
+ void * iLayoutDataArrayPtr[]) ;
+extern OSStatus
+ATSUDirectAddStyleSettingRef(
+ ATSULineRef iLineRef,
+ ATSUStyleSettingRef iStyleSettingRef,
+ UInt16 * oStyleIndex) ;
+
+
+
+
+
+}
+
+
+
+
+
+
+
+extern "C" {
+
+
+
+
+
+enum {
+ kGenericDocumentIconResource = -4000,
+ kGenericStationeryIconResource = -3985,
+ kGenericEditionFileIconResource = -3989,
+ kGenericApplicationIconResource = -3996,
+ kGenericDeskAccessoryIconResource = -3991,
+ kGenericFolderIconResource = -3999,
+ kPrivateFolderIconResource = -3994,
+ kFloppyIconResource = -3998,
+ kTrashIconResource = -3993,
+ kGenericRAMDiskIconResource = -3988,
+ kGenericCDROMIconResource = -3987
+};
+
+
+
+enum {
+ kDesktopIconResource = -3992,
+ kOpenFolderIconResource = -3997,
+ kGenericHardDiskIconResource = -3995,
+ kGenericFileServerIconResource = -3972,
+ kGenericSuitcaseIconResource = -3970,
+ kGenericMoverObjectIconResource = -3969
+};
+
+
+
+enum {
+ kGenericPreferencesIconResource = -3971,
+ kGenericQueryDocumentIconResource = -16506,
+ kGenericExtensionIconResource = -16415,
+ kSystemFolderIconResource = -3983,
+ kHelpIconResource = -20271,
+ kAppleMenuFolderIconResource = -3982
+};
+
+
+enum {
+ genericDocumentIconResource = kGenericDocumentIconResource,
+ genericStationeryIconResource = kGenericStationeryIconResource,
+ genericEditionFileIconResource = kGenericEditionFileIconResource,
+ genericApplicationIconResource = kGenericApplicationIconResource,
+ genericDeskAccessoryIconResource = kGenericDeskAccessoryIconResource,
+ genericFolderIconResource = kGenericFolderIconResource,
+ privateFolderIconResource = kPrivateFolderIconResource,
+ floppyIconResource = kFloppyIconResource,
+ trashIconResource = kTrashIconResource,
+ genericRAMDiskIconResource = kGenericRAMDiskIconResource,
+ genericCDROMIconResource = kGenericCDROMIconResource,
+ desktopIconResource = kDesktopIconResource,
+ openFolderIconResource = kOpenFolderIconResource,
+ genericHardDiskIconResource = kGenericHardDiskIconResource,
+ genericFileServerIconResource = kGenericFileServerIconResource,
+ genericSuitcaseIconResource = kGenericSuitcaseIconResource,
+ genericMoverObjectIconResource = kGenericMoverObjectIconResource,
+ genericPreferencesIconResource = kGenericPreferencesIconResource,
+ genericQueryDocumentIconResource = kGenericQueryDocumentIconResource,
+ genericExtensionIconResource = kGenericExtensionIconResource,
+ systemFolderIconResource = kSystemFolderIconResource,
+ appleMenuFolderIconResource = kAppleMenuFolderIconResource
+};
+
+
+enum {
+ kStartupFolderIconResource = -3981,
+ kOwnedFolderIconResource = -3980,
+ kDropFolderIconResource = -3979,
+ kSharedFolderIconResource = -3978,
+ kMountedFolderIconResource = -3977,
+ kControlPanelFolderIconResource = -3976,
+ kPrintMonitorFolderIconResource = -3975,
+ kPreferencesFolderIconResource = -3974,
+ kExtensionsFolderIconResource = -3973,
+ kFontsFolderIconResource = -3968,
+ kFullTrashIconResource = -3984
+};
+
+
+enum {
+ startupFolderIconResource = kStartupFolderIconResource,
+ ownedFolderIconResource = kOwnedFolderIconResource,
+ dropFolderIconResource = kDropFolderIconResource,
+ sharedFolderIconResource = kSharedFolderIconResource,
+ mountedFolderIconResource = kMountedFolderIconResource,
+ controlPanelFolderIconResource = kControlPanelFolderIconResource,
+ printMonitorFolderIconResource = kPrintMonitorFolderIconResource,
+ preferencesFolderIconResource = kPreferencesFolderIconResource,
+ extensionsFolderIconResource = kExtensionsFolderIconResource,
+ fontsFolderIconResource = kFontsFolderIconResource,
+ fullTrashIconResource = kFullTrashIconResource
+};
+
+
+enum {
+ kAlignNone = 0x00,
+ kAlignVerticalCenter = 0x01,
+ kAlignTop = 0x02,
+ kAlignBottom = 0x03,
+ kAlignHorizontalCenter = 0x04,
+ kAlignAbsoluteCenter = kAlignVerticalCenter | kAlignHorizontalCenter,
+ kAlignCenterTop = kAlignTop | kAlignHorizontalCenter,
+ kAlignCenterBottom = kAlignBottom | kAlignHorizontalCenter,
+ kAlignLeft = 0x08,
+ kAlignCenterLeft = kAlignVerticalCenter | kAlignLeft,
+ kAlignTopLeft = kAlignTop | kAlignLeft,
+ kAlignBottomLeft = kAlignBottom | kAlignLeft,
+ kAlignRight = 0x0C,
+ kAlignCenterRight = kAlignVerticalCenter | kAlignRight,
+ kAlignTopRight = kAlignTop | kAlignRight,
+ kAlignBottomRight = kAlignBottom | kAlignRight
+};
+
+
+enum {
+ atNone = kAlignNone,
+ atVerticalCenter = kAlignVerticalCenter,
+ atTop = kAlignTop,
+ atBottom = kAlignBottom,
+ atHorizontalCenter = kAlignHorizontalCenter,
+ atAbsoluteCenter = kAlignAbsoluteCenter,
+ atCenterTop = kAlignCenterTop,
+ atCenterBottom = kAlignCenterBottom,
+ atLeft = kAlignLeft,
+ atCenterLeft = kAlignCenterLeft,
+ atTopLeft = kAlignTopLeft,
+ atBottomLeft = kAlignBottomLeft,
+ atRight = kAlignRight,
+ atCenterRight = kAlignCenterRight,
+ atTopRight = kAlignTopRight,
+ atBottomRight = kAlignBottomRight
+};
+
+typedef SInt16 IconAlignmentType;
+
+enum {
+ kTransformNone = 0x00,
+ kTransformDisabled = 0x01,
+ kTransformOffline = 0x02,
+ kTransformOpen = 0x03,
+ kTransformLabel1 = 0x0100,
+ kTransformLabel2 = 0x0200,
+ kTransformLabel3 = 0x0300,
+ kTransformLabel4 = 0x0400,
+ kTransformLabel5 = 0x0500,
+ kTransformLabel6 = 0x0600,
+ kTransformLabel7 = 0x0700,
+ kTransformSelected = 0x4000,
+ kTransformSelectedDisabled = kTransformSelected | kTransformDisabled,
+ kTransformSelectedOffline = kTransformSelected | kTransformOffline,
+ kTransformSelectedOpen = kTransformSelected | kTransformOpen
+};
+
+
+enum {
+ ttNone = kTransformNone,
+ ttDisabled = kTransformDisabled,
+ ttOffline = kTransformOffline,
+ ttOpen = kTransformOpen,
+ ttLabel1 = kTransformLabel1,
+ ttLabel2 = kTransformLabel2,
+ ttLabel3 = kTransformLabel3,
+ ttLabel4 = kTransformLabel4,
+ ttLabel5 = kTransformLabel5,
+ ttLabel6 = kTransformLabel6,
+ ttLabel7 = kTransformLabel7,
+ ttSelected = kTransformSelected,
+ ttSelectedDisabled = kTransformSelectedDisabled,
+ ttSelectedOffline = kTransformSelectedOffline,
+ ttSelectedOpen = kTransformSelectedOpen
+};
+
+typedef SInt16 IconTransformType;
+
+enum {
+ kSelectorLarge1Bit = 0x00000001,
+ kSelectorLarge4Bit = 0x00000002,
+ kSelectorLarge8Bit = 0x00000004,
+ kSelectorLarge32Bit = 0x00000008,
+ kSelectorLarge8BitMask = 0x00000010,
+ kSelectorSmall1Bit = 0x00000100,
+ kSelectorSmall4Bit = 0x00000200,
+ kSelectorSmall8Bit = 0x00000400,
+ kSelectorSmall32Bit = 0x00000800,
+ kSelectorSmall8BitMask = 0x00001000,
+ kSelectorMini1Bit = 0x00010000,
+ kSelectorMini4Bit = 0x00020000,
+ kSelectorMini8Bit = 0x00040000,
+ kSelectorHuge1Bit = 0x01000000,
+ kSelectorHuge4Bit = 0x02000000,
+ kSelectorHuge8Bit = 0x04000000,
+ kSelectorHuge32Bit = 0x08000000,
+ kSelectorHuge8BitMask = 0x10000000,
+ kSelectorAllLargeData = 0x000000FF,
+ kSelectorAllSmallData = 0x0000FF00,
+ kSelectorAllMiniData = 0x00FF0000,
+ kSelectorAllHugeData = (long)0xFF000000,
+ kSelectorAll1BitData = kSelectorLarge1Bit | kSelectorSmall1Bit | kSelectorMini1Bit | kSelectorHuge1Bit,
+ kSelectorAll4BitData = kSelectorLarge4Bit | kSelectorSmall4Bit | kSelectorMini4Bit | kSelectorHuge4Bit,
+ kSelectorAll8BitData = kSelectorLarge8Bit | kSelectorSmall8Bit | kSelectorMini8Bit | kSelectorHuge8Bit,
+ kSelectorAll32BitData = kSelectorLarge32Bit | kSelectorSmall32Bit | kSelectorHuge32Bit,
+ kSelectorAllAvailableData = (long)0xFFFFFFFF
+};
+
+
+
+enum {
+ svLarge1Bit = kSelectorLarge1Bit,
+ svLarge4Bit = kSelectorLarge4Bit,
+ svLarge8Bit = kSelectorLarge8Bit,
+ svSmall1Bit = kSelectorSmall1Bit,
+ svSmall4Bit = kSelectorSmall4Bit,
+ svSmall8Bit = kSelectorSmall8Bit,
+ svMini1Bit = kSelectorMini1Bit,
+ svMini4Bit = kSelectorMini4Bit,
+ svMini8Bit = kSelectorMini8Bit,
+ svAllLargeData = kSelectorAllLargeData,
+ svAllSmallData = kSelectorAllSmallData,
+ svAllMiniData = kSelectorAllMiniData,
+ svAll1BitData = kSelectorAll1BitData,
+ svAll4BitData = kSelectorAll4BitData,
+ svAll8BitData = kSelectorAll8BitData,
+ svAllAvailableData = kSelectorAllAvailableData
+};
+
+typedef UInt32 IconSelectorValue;
+typedef OSErr ( * IconActionProcPtr)(ResType theType, Handle *theIcon, void *yourDataPtr);
+typedef Handle ( * IconGetterProcPtr)(ResType theType, void *yourDataPtr);
+typedef IconActionProcPtr IconActionUPP;
+typedef IconGetterProcPtr IconGetterUPP;
+extern IconActionUPP
+NewIconActionUPP(IconActionProcPtr userRoutine) ;
+extern IconGetterUPP
+NewIconGetterUPP(IconGetterProcPtr userRoutine) ;
+extern void
+DisposeIconActionUPP(IconActionUPP userUPP) ;
+extern void
+DisposeIconGetterUPP(IconGetterUPP userUPP) ;
+extern OSErr
+InvokeIconActionUPP(
+ ResType theType,
+ Handle * theIcon,
+ void * yourDataPtr,
+ IconActionUPP userUPP) ;
+extern Handle
+InvokeIconGetterUPP(
+ ResType theType,
+ void * yourDataPtr,
+ IconGetterUPP userUPP) ;
+
+typedef IconGetterProcPtr IconGetter;
+typedef IconActionProcPtr IconAction;
+
+struct CIcon {
+ PixMap iconPMap;
+ BitMap iconMask;
+ BitMap iconBMap;
+ Handle iconData;
+ SInt16 iconMaskData[1];
+};
+typedef struct CIcon CIcon;
+typedef CIcon * CIconPtr;
+typedef CIconPtr * CIconHandle;
+extern CIconHandle
+GetCIcon(SInt16 iconID) ;
+extern void
+PlotCIcon(
+ const Rect * theRect,
+ CIconHandle theIcon) ;
+extern void
+DisposeCIcon(CIconHandle theIcon) ;
+extern Handle
+GetIcon(SInt16 iconID) ;
+extern void
+PlotIcon(
+ const Rect * theRect,
+ Handle theIcon) ;
+typedef Handle IconSuiteRef;
+typedef Handle IconCacheRef;
+
+typedef struct OpaqueIconRef* IconRef;
+extern OSErr
+PlotIconID(
+ const Rect * theRect,
+ IconAlignmentType align,
+ IconTransformType transform,
+ SInt16 theResID) ;
+extern OSErr
+NewIconSuite(IconSuiteRef * theIconSuite) ;
+extern OSErr
+AddIconToSuite(
+ Handle theIconData,
+ IconSuiteRef theSuite,
+ ResType theType) ;
+extern OSErr
+GetIconFromSuite(
+ Handle * theIconData,
+ IconSuiteRef theSuite,
+ ResType theType) ;
+extern OSErr
+ForEachIconDo(
+ IconSuiteRef theSuite,
+ IconSelectorValue selector,
+ IconActionUPP action,
+ void * yourDataPtr) ;
+extern OSErr
+GetIconSuite(
+ IconSuiteRef * theIconSuite,
+ SInt16 theResID,
+ IconSelectorValue selector) ;
+extern OSErr
+DisposeIconSuite(
+ IconSuiteRef theIconSuite,
+ Boolean disposeData) ;
+extern OSErr
+PlotIconSuite(
+ const Rect * theRect,
+ IconAlignmentType align,
+ IconTransformType transform,
+ IconSuiteRef theIconSuite) ;
+extern OSErr
+MakeIconCache(
+ IconCacheRef * theCache,
+ IconGetterUPP makeIcon,
+ void * yourDataPtr) ;
+extern OSErr
+LoadIconCache(
+ const Rect * theRect,
+ IconAlignmentType align,
+ IconTransformType transform,
+ IconCacheRef theIconCache) ;
+extern OSErr
+PlotIconMethod(
+ const Rect * theRect,
+ IconAlignmentType align,
+ IconTransformType transform,
+ IconGetterUPP theMethod,
+ void * yourDataPtr) ;
+extern OSErr
+GetLabel(
+ SInt16 labelNumber,
+ RGBColor * labelColor,
+ Str255 labelString) ;
+extern Boolean
+PtInIconID(
+ Point testPt,
+ const Rect * iconRect,
+ IconAlignmentType align,
+ SInt16 iconID) ;
+extern Boolean
+PtInIconSuite(
+ Point testPt,
+ const Rect * iconRect,
+ IconAlignmentType align,
+ IconSuiteRef theIconSuite) ;
+extern Boolean
+PtInIconMethod(
+ Point testPt,
+ const Rect * iconRect,
+ IconAlignmentType align,
+ IconGetterUPP theMethod,
+ void * yourDataPtr) ;
+extern Boolean
+RectInIconID(
+ const Rect * testRect,
+ const Rect * iconRect,
+ IconAlignmentType align,
+ SInt16 iconID) ;
+extern Boolean
+RectInIconSuite(
+ const Rect * testRect,
+ const Rect * iconRect,
+ IconAlignmentType align,
+ IconSuiteRef theIconSuite) ;
+extern Boolean
+RectInIconMethod(
+ const Rect * testRect,
+ const Rect * iconRect,
+ IconAlignmentType align,
+ IconGetterUPP theMethod,
+ void * yourDataPtr) ;
+extern OSErr
+IconIDToRgn(
+ RgnHandle theRgn,
+ const Rect * iconRect,
+ IconAlignmentType align,
+ SInt16 iconID) ;
+extern OSErr
+IconSuiteToRgn(
+ RgnHandle theRgn,
+ const Rect * iconRect,
+ IconAlignmentType align,
+ IconSuiteRef theIconSuite) ;
+extern OSErr
+IconMethodToRgn(
+ RgnHandle theRgn,
+ const Rect * iconRect,
+ IconAlignmentType align,
+ IconGetterUPP theMethod,
+ void * yourDataPtr) ;
+extern OSErr
+SetSuiteLabel(
+ IconSuiteRef theSuite,
+ SInt16 theLabel) ;
+extern SInt16
+GetSuiteLabel(IconSuiteRef theSuite) ;
+extern OSErr
+GetIconCacheData(
+ IconCacheRef theCache,
+ void ** theData) ;
+extern OSErr
+SetIconCacheData(
+ IconCacheRef theCache,
+ void * theData) ;
+extern OSErr
+GetIconCacheProc(
+ IconCacheRef theCache,
+ IconGetterUPP * theProc) ;
+extern OSErr
+SetIconCacheProc(
+ IconCacheRef theCache,
+ IconGetterUPP theProc) ;
+extern OSErr
+PlotIconHandle(
+ const Rect * theRect,
+ IconAlignmentType align,
+ IconTransformType transform,
+ Handle theIcon) ;
+extern OSErr
+PlotSICNHandle(
+ const Rect * theRect,
+ IconAlignmentType align,
+ IconTransformType transform,
+ Handle theSICN) ;
+extern OSErr
+PlotCIconHandle(
+ const Rect * theRect,
+ IconAlignmentType align,
+ IconTransformType transform,
+ CIconHandle theCIcon) ;
+enum {
+ kSystemIconsCreator = 'macs'
+};
+enum {
+ kClipboardIcon = 'CLIP',
+ kClippingUnknownTypeIcon = 'clpu',
+ kClippingPictureTypeIcon = 'clpp',
+ kClippingTextTypeIcon = 'clpt',
+ kClippingSoundTypeIcon = 'clps',
+ kDesktopIcon = 'desk',
+ kFinderIcon = 'FNDR',
+ kFontSuitcaseIcon = 'FFIL',
+ kFullTrashIcon = 'ftrh',
+ kGenericApplicationIcon = 'APPL',
+ kGenericCDROMIcon = 'cddr',
+ kGenericControlPanelIcon = 'APPC',
+ kGenericControlStripModuleIcon = 'sdev',
+ kGenericComponentIcon = 'thng',
+ kGenericDeskAccessoryIcon = 'APPD',
+ kGenericDocumentIcon = 'docu',
+ kGenericEditionFileIcon = 'edtf',
+ kGenericExtensionIcon = 'INIT',
+ kGenericFileServerIcon = 'srvr',
+ kGenericFontIcon = 'ffil',
+ kGenericFontScalerIcon = 'sclr',
+ kGenericFloppyIcon = 'flpy',
+ kGenericHardDiskIcon = 'hdsk',
+ kGenericIDiskIcon = 'idsk',
+ kGenericRemovableMediaIcon = 'rmov',
+ kGenericMoverObjectIcon = 'movr',
+ kGenericPCCardIcon = 'pcmc',
+ kGenericPreferencesIcon = 'pref',
+ kGenericQueryDocumentIcon = 'qery',
+ kGenericRAMDiskIcon = 'ramd',
+ kGenericSharedLibaryIcon = 'shlb',
+ kGenericStationeryIcon = 'sdoc',
+ kGenericSuitcaseIcon = 'suit',
+ kGenericURLIcon = 'gurl',
+ kGenericWORMIcon = 'worm',
+ kInternationalResourcesIcon = 'ifil',
+ kKeyboardLayoutIcon = 'kfil',
+ kSoundFileIcon = 'sfil',
+ kSystemSuitcaseIcon = 'zsys',
+ kTrashIcon = 'trsh',
+ kTrueTypeFontIcon = 'tfil',
+ kTrueTypeFlatFontIcon = 'sfnt',
+ kTrueTypeMultiFlatFontIcon = 'ttcf',
+ kUserIDiskIcon = 'udsk',
+ kUnknownFSObjectIcon = 'unfs',
+ kInternationResourcesIcon = kInternationalResourcesIcon
+};
+
+
+enum {
+ kInternetLocationHTTPIcon = 'ilht',
+ kInternetLocationFTPIcon = 'ilft',
+ kInternetLocationAppleShareIcon = 'ilaf',
+ kInternetLocationAppleTalkZoneIcon = 'ilat',
+ kInternetLocationFileIcon = 'ilfi',
+ kInternetLocationMailIcon = 'ilma',
+ kInternetLocationNewsIcon = 'ilnw',
+ kInternetLocationNSLNeighborhoodIcon = 'ilns',
+ kInternetLocationGenericIcon = 'ilge'
+};
+
+
+enum {
+ kGenericFolderIcon = 'fldr',
+ kDropFolderIcon = 'dbox',
+ kMountedFolderIcon = 'mntd',
+ kOpenFolderIcon = 'ofld',
+ kOwnedFolderIcon = 'ownd',
+ kPrivateFolderIcon = 'prvf',
+ kSharedFolderIcon = 'shfl'
+};
+
+
+enum {
+ kSharingPrivsNotApplicableIcon = 'shna',
+ kSharingPrivsReadOnlyIcon = 'shro',
+ kSharingPrivsReadWriteIcon = 'shrw',
+ kSharingPrivsUnknownIcon = 'shuk',
+ kSharingPrivsWritableIcon = 'writ'
+};
+
+
+
+enum {
+ kUserFolderIcon = 'ufld',
+ kWorkgroupFolderIcon = 'wfld',
+ kGuestUserIcon = 'gusr',
+ kUserIcon = 'user',
+ kOwnerIcon = 'susr',
+ kGroupIcon = 'grup'
+};
+
+
+enum {
+ kAppearanceFolderIcon = 'appr',
+ kAppleExtrasFolderIcon = 'aexÄ',
+ kAppleMenuFolderIcon = 'amnu',
+ kApplicationsFolderIcon = 'apps',
+ kApplicationSupportFolderIcon = 'asup',
+ kAssistantsFolderIcon = 'astÄ',
+ kColorSyncFolderIcon = 'prof',
+ kContextualMenuItemsFolderIcon = 'cmnu',
+ kControlPanelDisabledFolderIcon = 'ctrD',
+ kControlPanelFolderIcon = 'ctrl',
+ kControlStripModulesFolderIcon = 'sdvÄ',
+ kDocumentsFolderIcon = 'docs',
+ kExtensionsDisabledFolderIcon = 'extD',
+ kExtensionsFolderIcon = 'extn',
+ kFavoritesFolderIcon = 'favs',
+ kFontsFolderIcon = 'font',
+ kHelpFolderIcon = 'Ählp',
+ kInternetFolderIcon = 'intÄ',
+ kInternetPlugInFolderIcon = 'Änet',
+ kInternetSearchSitesFolderIcon = 'issf',
+ kLocalesFolderIcon = 'Äloc',
+ kMacOSReadMeFolderIcon = 'morÄ',
+ kPublicFolderIcon = 'pubf',
+ kPreferencesFolderIcon = 'prfÄ',
+ kPrinterDescriptionFolderIcon = 'ppdf',
+ kPrinterDriverFolderIcon = 'Äprd',
+ kPrintMonitorFolderIcon = 'prnt',
+ kRecentApplicationsFolderIcon = 'rapp',
+ kRecentDocumentsFolderIcon = 'rdoc',
+ kRecentServersFolderIcon = 'rsrv',
+ kScriptingAdditionsFolderIcon = 'Äscr',
+ kSharedLibrariesFolderIcon = 'Älib',
+ kScriptsFolderIcon = 'scrÄ',
+ kShutdownItemsDisabledFolderIcon = 'shdD',
+ kShutdownItemsFolderIcon = 'shdf',
+ kSpeakableItemsFolder = 'spki',
+ kStartupItemsDisabledFolderIcon = 'strD',
+ kStartupItemsFolderIcon = 'strt',
+ kSystemExtensionDisabledFolderIcon = 'macD',
+ kSystemFolderIcon = 'macs',
+ kTextEncodingsFolderIcon = 'Ätex',
+ kUsersFolderIcon = 'usrÄ',
+ kUtilitiesFolderIcon = 'utiÄ',
+ kVoicesFolderIcon = 'fvoc'
+};
+
+
+enum {
+ kAppleScriptBadgeIcon = 'scrp',
+ kLockedBadgeIcon = 'lbdg',
+ kMountedBadgeIcon = 'mbdg',
+ kSharedBadgeIcon = 'sbdg',
+ kAliasBadgeIcon = 'abdg',
+ kAlertCautionBadgeIcon = 'cbdg'
+};
+
+
+enum {
+ kAlertNoteIcon = 'note',
+ kAlertCautionIcon = 'caut',
+ kAlertStopIcon = 'stop'
+};
+
+
+enum {
+ kAppleTalkIcon = 'atlk',
+ kAppleTalkZoneIcon = 'atzn',
+ kAFPServerIcon = 'afps',
+ kFTPServerIcon = 'ftps',
+ kHTTPServerIcon = 'htps',
+ kGenericNetworkIcon = 'gnet',
+ kIPFileServerIcon = 'isrv'
+};
+
+
+enum {
+ kToolbarCustomizeIcon = 'tcus',
+ kToolbarDeleteIcon = 'tdel',
+ kToolbarFavoritesIcon = 'tfav',
+ kToolbarHomeIcon = 'thom'
+};
+
+
+enum {
+ kAppleLogoIcon = 'capl',
+ kAppleMenuIcon = 'sapl',
+ kBackwardArrowIcon = 'baro',
+ kFavoriteItemsIcon = 'favr',
+ kForwardArrowIcon = 'faro',
+ kGridIcon = 'grid',
+ kHelpIcon = 'help',
+ kKeepArrangedIcon = 'arng',
+ kLockedIcon = 'lock',
+ kNoFilesIcon = 'nfil',
+ kNoFolderIcon = 'nfld',
+ kNoWriteIcon = 'nwrt',
+ kProtectedApplicationFolderIcon = 'papp',
+ kProtectedSystemFolderIcon = 'psys',
+ kRecentItemsIcon = 'rcnt',
+ kShortcutIcon = 'shrt',
+ kSortAscendingIcon = 'asnd',
+ kSortDescendingIcon = 'dsnd',
+ kUnlockedIcon = 'ulck',
+ kConnectToIcon = 'cnct',
+ kGenericWindowIcon = 'gwin',
+ kQuestionMarkIcon = 'ques',
+ kDeleteAliasIcon = 'dali',
+ kEjectMediaIcon = 'ejec',
+ kBurningIcon = 'burn',
+ kRightContainerArrowIcon = 'rcar'
+};
+
+
+
+
+typedef UInt32 IconServicesUsageFlags;
+enum {
+ kIconServicesNormalUsageFlag = 0
+};
+
+
+
+
+
+
+
+enum {
+ kIconServicesCatalogInfoMask = (kFSCatInfoNodeID | kFSCatInfoParentDirID | kFSCatInfoVolume | kFSCatInfoNodeFlags | kFSCatInfoFinderInfo | kFSCatInfoFinderXInfo | kFSCatInfoUserAccess)
+};
+typedef UInt32 PlotIconRefFlags;
+enum {
+
+
+
+
+ kPlotIconRefNormalFlags = 0L,
+
+
+
+
+ kPlotIconRefNoImage = (1 << 1),
+
+
+
+
+ kPlotIconRefNoMask = (1 << 2)
+};
+extern OSErr
+IconRefToIconFamily(
+ IconRef theIconRef,
+ IconSelectorValue whichIcons,
+ IconFamilyHandle * iconFamily) ;
+extern OSErr
+IconFamilyToIconSuite(
+ IconFamilyHandle iconFamily,
+ IconSelectorValue whichIcons,
+ IconSuiteRef * iconSuite) ;
+extern OSErr
+IconSuiteToIconFamily(
+ IconSuiteRef iconSuite,
+ IconSelectorValue whichIcons,
+ IconFamilyHandle * iconFamily) ;
+extern OSErr
+SetIconFamilyData(
+ IconFamilyHandle iconFamily,
+ OSType iconType,
+ Handle h) ;
+extern OSErr
+GetIconFamilyData(
+ IconFamilyHandle iconFamily,
+ OSType iconType,
+ Handle h) ;
+extern OSErr
+GetIconRefOwners(
+ IconRef theIconRef,
+ UInt16 * owners) ;
+extern OSErr
+AcquireIconRef(IconRef theIconRef) ;
+extern OSErr
+ReleaseIconRef(IconRef theIconRef) ;
+extern OSErr
+GetIconRefFromFile(
+ const FSSpec * theFile,
+ IconRef * theIconRef,
+ SInt16 * theLabel) ;
+extern OSErr
+GetIconRef(
+ SInt16 vRefNum,
+ OSType creator,
+ OSType iconType,
+ IconRef * theIconRef) ;
+extern OSErr
+GetIconRefFromFolder(
+ SInt16 vRefNum,
+ SInt32 parentFolderID,
+ SInt32 folderID,
+ SInt8 attributes,
+ SInt8 accessPrivileges,
+ IconRef * theIconRef) ;
+extern OSStatus
+GetIconRefFromFileInfo(
+ const FSRef * inRef,
+ UniCharCount inFileNameLength,
+ const UniChar * inFileName,
+ FSCatalogInfoBitmap inWhichInfo,
+ const FSCatalogInfo * inCatalogInfo,
+ IconServicesUsageFlags inUsageFlags,
+ IconRef * outIconRef,
+ SInt16 * outLabel) ;
+extern OSErr
+RegisterIconRefFromIconFamily(
+ OSType creator,
+ OSType iconType,
+ IconFamilyHandle iconFamily,
+ IconRef * theIconRef) ;
+extern OSErr
+RegisterIconRefFromResource(
+ OSType creator,
+ OSType iconType,
+ const FSSpec * resourceFile,
+ SInt16 resourceID,
+ IconRef * theIconRef) ;
+extern OSStatus
+RegisterIconRefFromFSRef(
+ OSType creator,
+ OSType iconType,
+ const FSRef * iconFile,
+ IconRef * theIconRef) ;
+extern OSErr
+UnregisterIconRef(
+ OSType creator,
+ OSType iconType) ;
+extern OSErr
+UpdateIconRef(IconRef theIconRef) ;
+extern OSErr
+OverrideIconRefFromResource(
+ IconRef theIconRef,
+ const FSSpec * resourceFile,
+ SInt16 resourceID) ;
+extern OSErr
+OverrideIconRef(
+ IconRef oldIconRef,
+ IconRef newIconRef) ;
+extern OSErr
+RemoveIconRefOverride(IconRef theIconRef) ;
+extern OSErr
+CompositeIconRef(
+ IconRef backgroundIconRef,
+ IconRef foregroundIconRef,
+ IconRef * compositeIconRef) ;
+extern OSErr
+IsIconRefComposite(
+ IconRef compositeIconRef,
+ IconRef * backgroundIconRef,
+ IconRef * foregroundIconRef) ;
+extern Boolean
+IsValidIconRef(IconRef theIconRef) ;
+extern OSErr
+PlotIconRef(
+ const Rect * theRect,
+ IconAlignmentType align,
+ IconTransformType transform,
+ IconServicesUsageFlags theIconServicesUsageFlags,
+ IconRef theIconRef) ;
+extern OSStatus
+PlotIconRefInContext(
+ CGContextRef inContext,
+ const CGRect * inRect,
+ IconAlignmentType inAlign,
+ IconTransformType inTransform,
+ const RGBColor * inLabelColor,
+ PlotIconRefFlags inFlags,
+ IconRef inIconRef) ;
+extern Boolean
+PtInIconRef(
+ const Point * testPt,
+ const Rect * iconRect,
+ IconAlignmentType align,
+ IconServicesUsageFlags theIconServicesUsageFlags,
+ IconRef theIconRef) ;
+extern Boolean
+RectInIconRef(
+ const Rect * testRect,
+ const Rect * iconRect,
+ IconAlignmentType align,
+ IconServicesUsageFlags iconServicesUsageFlags,
+ IconRef theIconRef) ;
+extern OSErr
+IconRefToRgn(
+ RgnHandle theRgn,
+ const Rect * iconRect,
+ IconAlignmentType align,
+ IconServicesUsageFlags iconServicesUsageFlags,
+ IconRef theIconRef) ;
+extern OSErr
+GetIconSizesFromIconRef(
+ IconSelectorValue iconSelectorInput,
+ IconSelectorValue * iconSelectorOutputPtr,
+ IconServicesUsageFlags iconServicesUsageFlags,
+ IconRef theIconRef) ;
+extern OSErr
+FlushIconRefs(
+ OSType creator,
+ OSType iconType) ;
+extern OSErr
+FlushIconRefsByVolume(SInt16 vRefNum) ;
+extern OSErr
+SetCustomIconsEnabled(
+ SInt16 vRefNum,
+ Boolean enableCustomIcons) ;
+extern OSErr
+GetCustomIconsEnabled(
+ SInt16 vRefNum,
+ Boolean * customIconsEnabled) ;
+extern Boolean
+IsIconRefMaskEmpty(IconRef iconRef) ;
+extern IconRef
+GetIconRefVariant(
+ IconRef inIconRef,
+ OSType inVariant,
+ IconTransformType * outTransform) ;
+extern OSErr
+RegisterIconRefFromIconFile(
+ OSType creator,
+ OSType iconType,
+ const FSSpec * iconFile,
+ IconRef * theIconRef) ;
+extern OSErr
+ReadIconFile(
+ const FSSpec * iconFile,
+ IconFamilyHandle * iconFamily) ;
+extern OSStatus
+ReadIconFromFSRef(
+ const FSRef * ref,
+ IconFamilyHandle * iconFamily) ;
+extern OSErr
+WriteIconFile(
+ IconFamilyHandle iconFamily,
+ const FSSpec * iconFile) ;
+
+
+
+
+
+
+}
+
+
+
+extern "C" {
+
+
+
+
+
+
+
+enum {
+ icPrefNotFoundErr = -666,
+ icPermErr = -667,
+ icPrefDataErr = -668,
+ icInternalErr = -669,
+ icTruncatedErr = -670,
+ icNoMoreWritersErr = -671,
+ icNothingToOverrideErr = -672,
+ icNoURLErr = -673,
+ icConfigNotFoundErr = -674,
+ icConfigInappropriateErr = -675,
+ icProfileNotFoundErr = -676,
+ icTooManyProfilesErr = -677
+};
+
+
+
+
+
+enum {
+ kICComponentInterfaceVersion0 = 0x00000000,
+ kICComponentInterfaceVersion1 = 0x00010000,
+ kICComponentInterfaceVersion2 = 0x00020000,
+ kICComponentInterfaceVersion3 = 0x00030000,
+ kICComponentInterfaceVersion4 = 0x00040000,
+ kICComponentInterfaceVersion = kICComponentInterfaceVersion4
+};
+
+
+
+
+
+typedef struct OpaqueICInstance* ICInstance;
+
+
+
+
+struct ICDirSpec {
+ short vRefNum;
+ long dirID;
+};
+typedef struct ICDirSpec ICDirSpec;
+typedef ICDirSpec ICDirSpecArray[4];
+typedef ICDirSpecArray * ICDirSpecArrayPtr;
+
+
+
+
+typedef UInt32 ICAttr;
+
+enum {
+ kICAttrLockedBit = 0,
+ kICAttrVolatileBit = 1
+};
+
+enum {
+ kICAttrNoChange = (unsigned long)0xFFFFFFFF,
+ kICAttrLockedMask = 0x00000001,
+ kICAttrVolatileMask = 0x00000002
+};
+
+
+
+
+
+typedef UInt8 ICPerm;
+
+enum {
+ icNoPerm = 0,
+ icReadOnlyPerm = 1,
+ icReadWritePerm = 2
+};
+typedef long ICProfileID;
+typedef ICProfileID * ICProfileIDPtr;
+
+enum {
+ kICNilProfileID = 0
+};
+
+
+
+
+
+enum {
+ kICNoUserInteractionBit = 0
+};
+
+enum {
+ kICNoUserInteractionMask = 0x00000001
+};
+
+enum {
+ kICFileType = 'ICAp',
+ kICCreator = 'ICAp'
+};
+
+
+
+
+
+enum {
+ kInternetEventClass = 'GURL',
+ kAEGetURL = 'GURL',
+ kAEFetchURL = 'FURL',
+ keyAEAttaching = 'Atch'
+};
+
+
+
+enum {
+ kICEditPreferenceEventClass = 'ICAp',
+ kICEditPreferenceEvent = 'ICAp',
+ keyICEditPreferenceDestination = 'dest'
+};
+
+
+
+
+
+enum {
+ kICComponentVersion = 0,
+ kICNumVersion = 1
+};
+
+
+
+
+struct ICFontRecord {
+ short size;
+ Style face;
+ char pad;
+ Str255 font;
+};
+typedef struct ICFontRecord ICFontRecord;
+typedef ICFontRecord * ICFontRecordPtr;
+typedef ICFontRecordPtr * ICFontRecordHandle;
+
+
+
+
+struct ICCharTable {
+ unsigned char netToMac[256];
+ unsigned char macToNet[256];
+};
+typedef struct ICCharTable ICCharTable;
+typedef ICCharTable * ICCharTablePtr;
+typedef ICCharTablePtr * ICCharTableHandle;
+
+
+
+
+struct ICAppSpec {
+ OSType fCreator;
+ Str63 name;
+};
+typedef struct ICAppSpec ICAppSpec;
+typedef ICAppSpec * ICAppSpecPtr;
+typedef ICAppSpecPtr * ICAppSpecHandle;
+struct ICAppSpecList {
+ short numberOfItems;
+ ICAppSpec appSpecs[1];
+};
+typedef struct ICAppSpecList ICAppSpecList;
+typedef ICAppSpecList * ICAppSpecListPtr;
+typedef ICAppSpecListPtr * ICAppSpecListHandle;
+
+
+
+
+
+
+struct ICFileSpec {
+ Str31 volName;
+ long volCreationDate;
+ FSSpec fss;
+ AliasRecord alias;
+
+
+};
+typedef struct ICFileSpec ICFileSpec;
+typedef ICFileSpec * ICFileSpecPtr;
+typedef ICFileSpecPtr * ICFileSpecHandle;
+enum {
+ kICFileSpecHeaderSize = sizeof(ICFileSpec) - sizeof(AliasRecord)
+};
+
+
+
+
+typedef long ICMapEntryFlags;
+typedef short ICFixedLength;
+
+
+struct ICMapEntry {
+ short totalLength;
+ ICFixedLength fixedLength;
+ short version;
+ OSType fileType;
+ OSType fileCreator;
+ OSType postCreator;
+ ICMapEntryFlags flags;
+
+ Str255 extension;
+ Str255 creatorAppName;
+ Str255 postAppName;
+ Str255 MIMEType;
+ Str255 entryName;
+};
+typedef struct ICMapEntry ICMapEntry;
+typedef ICMapEntry * ICMapEntryPtr;
+typedef ICMapEntryPtr * ICMapEntryHandle;
+enum {
+ kICMapFixedLength = 22
+};
+
+enum {
+ kICMapBinaryBit = 0,
+ kICMapResourceForkBit = 1,
+ kICMapDataForkBit = 2,
+ kICMapPostBit = 3,
+ kICMapNotIncomingBit = 4,
+ kICMapNotOutgoingBit = 5
+};
+
+enum {
+ kICMapBinaryMask = 0x00000001,
+ kICMapResourceForkMask = 0x00000002,
+ kICMapDataForkMask = 0x00000004,
+ kICMapPostMask = 0x00000008,
+ kICMapNotIncomingMask = 0x00000010,
+ kICMapNotOutgoingMask = 0x00000020
+};
+
+
+
+
+typedef short ICServiceEntryFlags;
+struct ICServiceEntry {
+ Str255 name;
+ short port;
+ ICServiceEntryFlags flags;
+};
+typedef struct ICServiceEntry ICServiceEntry;
+typedef ICServiceEntry * ICServiceEntryPtr;
+typedef ICServiceEntryPtr * ICServiceEntryHandle;
+
+enum {
+ kICServicesTCPBit = 0,
+ kICServicesUDPBit = 1
+};
+
+enum {
+ kICServicesTCPMask = 0x00000001,
+ kICServicesUDPMask = 0x00000002
+};
+
+struct ICServices {
+ short count;
+ ICServiceEntry services[1];
+};
+typedef struct ICServices ICServices;
+typedef ICServices * ICServicesPtr;
+typedef ICServicesPtr * ICServicesHandle;
+extern OSStatus
+ICStart(
+ ICInstance * inst,
+ OSType signature) ;
+extern OSStatus
+ICStop(ICInstance inst) ;
+extern OSStatus
+ICGetVersion(
+ ICInstance inst,
+ long whichVersion,
+ UInt32 * version) ;
+extern OSStatus
+ICGetConfigName(
+ ICInstance inst,
+ Boolean longname,
+ Str255 name) ;
+extern OSStatus
+ICGetSeed(
+ ICInstance inst,
+ long * seed) ;
+extern OSStatus
+ICGetPerm(
+ ICInstance inst,
+ ICPerm * perm) ;
+extern OSStatus
+ICBegin(
+ ICInstance inst,
+ ICPerm perm) ;
+extern OSStatus
+ICGetPref(
+ ICInstance inst,
+ ConstStr255Param key,
+ ICAttr * attr,
+ void * buf,
+ long * size) ;
+extern OSStatus
+ICSetPref(
+ ICInstance inst,
+ ConstStr255Param key,
+ ICAttr attr,
+ const void * buf,
+ long size) ;
+extern OSStatus
+ICFindPrefHandle(
+ ICInstance inst,
+ ConstStr255Param key,
+ ICAttr * attr,
+ Handle prefh) ;
+extern OSStatus
+ICGetPrefHandle(
+ ICInstance inst,
+ ConstStr255Param key,
+ ICAttr * attr,
+ Handle * prefh) ;
+extern OSStatus
+ICSetPrefHandle(
+ ICInstance inst,
+ ConstStr255Param key,
+ ICAttr attr,
+ Handle prefh) ;
+extern OSStatus
+ICCountPref(
+ ICInstance inst,
+ long * count) ;
+extern OSStatus
+ICGetIndPref(
+ ICInstance inst,
+ long index,
+ Str255 key) ;
+extern OSStatus
+ICDeletePref(
+ ICInstance inst,
+ ConstStr255Param key) ;
+extern OSStatus
+ICEnd(ICInstance inst) ;
+extern OSStatus
+ICGetDefaultPref(
+ ICInstance inst,
+ ConstStr255Param key,
+ Handle prefH) ;
+extern OSStatus
+ICEditPreferences(
+ ICInstance inst,
+ ConstStr255Param key) ;
+extern OSStatus
+ICLaunchURL(
+ ICInstance inst,
+ ConstStr255Param hint,
+ const void * data,
+ long len,
+ long * selStart,
+ long * selEnd) ;
+extern OSStatus
+ICParseURL(
+ ICInstance inst,
+ ConstStr255Param hint,
+ const void * data,
+ long len,
+ long * selStart,
+ long * selEnd,
+ Handle url) ;
+extern OSStatus
+ICCreateGURLEvent(
+ ICInstance inst,
+ OSType helperCreator,
+ Handle urlH,
+ AppleEvent * theEvent) ;
+extern OSStatus
+ICSendGURLEvent(
+ ICInstance inst,
+ AppleEvent * theEvent) ;
+extern OSStatus
+ICMapFilename(
+ ICInstance inst,
+ ConstStr255Param filename,
+ ICMapEntry * entry) ;
+extern OSStatus
+ICMapTypeCreator(
+ ICInstance inst,
+ OSType fType,
+ OSType fCreator,
+ ConstStr255Param filename,
+ ICMapEntry * entry) ;
+extern OSStatus
+ICMapEntriesFilename(
+ ICInstance inst,
+ Handle entries,
+ ConstStr255Param filename,
+ ICMapEntry * entry) ;
+extern OSStatus
+ICMapEntriesTypeCreator(
+ ICInstance inst,
+ Handle entries,
+ OSType fType,
+ OSType fCreator,
+ ConstStr255Param filename,
+ ICMapEntry * entry) ;
+extern OSStatus
+ICCountMapEntries(
+ ICInstance inst,
+ Handle entries,
+ long * count) ;
+extern OSStatus
+ICGetIndMapEntry(
+ ICInstance inst,
+ Handle entries,
+ long index,
+ long * pos,
+ ICMapEntry * entry) ;
+extern OSStatus
+ICGetMapEntry(
+ ICInstance inst,
+ Handle entries,
+ long pos,
+ ICMapEntry * entry) ;
+extern OSStatus
+ICSetMapEntry(
+ ICInstance inst,
+ Handle entries,
+ long pos,
+ const ICMapEntry * entry) ;
+extern OSStatus
+ICDeleteMapEntry(
+ ICInstance inst,
+ Handle entries,
+ long pos) ;
+extern OSStatus
+ICAddMapEntry(
+ ICInstance inst,
+ Handle entries,
+ const ICMapEntry * entry) ;
+extern OSStatus
+ICGetCurrentProfile(
+ ICInstance inst,
+ ICProfileID * currentID) ;
+extern OSStatus
+ICSetCurrentProfile(
+ ICInstance inst,
+ ICProfileID newID) ;
+extern OSStatus
+ICCountProfiles(
+ ICInstance inst,
+ long * count) ;
+extern OSStatus
+ICGetIndProfile(
+ ICInstance inst,
+ long index,
+ ICProfileID * thisID) ;
+extern OSStatus
+ICGetProfileName(
+ ICInstance inst,
+ ICProfileID thisID,
+ Str255 name) ;
+extern OSStatus
+ICSetProfileName(
+ ICInstance inst,
+ ICProfileID thisID,
+ ConstStr255Param name) ;
+extern OSStatus
+ICAddProfile(
+ ICInstance inst,
+ ICProfileID prototypeID,
+ ICProfileID * newID) ;
+extern OSStatus
+ICDeleteProfile(
+ ICInstance inst,
+ ICProfileID thisID) ;
+
+
+}
+
+
+
+extern "C" {
+
+
+
+
+struct ProcessSerialNumber {
+ unsigned long highLongOfPSN;
+ unsigned long lowLongOfPSN;
+};
+typedef struct ProcessSerialNumber ProcessSerialNumber;
+typedef ProcessSerialNumber * ProcessSerialNumberPtr;
+enum {
+
+ kNoProcess = 0,
+ kSystemProcess = 1,
+ kCurrentProcess = 2
+};
+
+
+
+typedef unsigned short LaunchFlags;
+enum {
+ launchContinue = 0x4000,
+ launchNoFileFlags = 0x0800,
+ launchUseMinimum = 0x0400,
+ launchDontSwitch = 0x0200,
+ launchAllow24Bit = 0x0100,
+ launchInhibitDaemon = 0x0080
+};
+
+
+
+struct AppParameters {
+ struct {
+ UInt16 what;
+ UInt32 message;
+ UInt32 when;
+ Point where;
+ UInt16 modifiers;
+ } theMsgEvent;
+ unsigned long eventRefCon;
+ unsigned long messageLength;
+};
+typedef struct AppParameters AppParameters;
+typedef AppParameters * AppParametersPtr;
+
+struct LaunchParamBlockRec {
+ unsigned long reserved1;
+ unsigned short reserved2;
+ unsigned short launchBlockID;
+ unsigned long launchEPBLength;
+ unsigned short launchFileFlags;
+ LaunchFlags launchControlFlags;
+ FSSpecPtr launchAppSpec;
+ ProcessSerialNumber launchProcessSN;
+ unsigned long launchPreferredSize;
+ unsigned long launchMinimumSize;
+ unsigned long launchAvailableSize;
+ AppParametersPtr launchAppParameters;
+};
+typedef struct LaunchParamBlockRec LaunchParamBlockRec;
+typedef LaunchParamBlockRec * LaunchPBPtr;
+
+
+enum {
+ extendedBlock = 0x4C43,
+ extendedBlockLen = sizeof(LaunchParamBlockRec) - 12
+};
+
+enum {
+
+ modeReserved = 0x01000000,
+ modeControlPanel = 0x00080000,
+ modeLaunchDontSwitch = 0x00040000,
+ modeDeskAccessory = 0x00020000,
+ modeMultiLaunch = 0x00010000,
+ modeNeedSuspendResume = 0x00004000,
+ modeCanBackground = 0x00001000,
+ modeDoesActivateOnFGSwitch = 0x00000800,
+ modeOnlyBackground = 0x00000400,
+ modeGetFrontClicks = 0x00000200,
+ modeGetAppDiedMsg = 0x00000100,
+ mode32BitCompatible = 0x00000080,
+ modeHighLevelEventAware = 0x00000040,
+ modeLocalAndRemoteHLEvents = 0x00000020,
+ modeStationeryAware = 0x00000010,
+ modeUseTextEditServices = 0x00000008,
+ modeDisplayManagerAware = 0x00000004
+};
+struct ProcessInfoRec {
+ unsigned long processInfoLength;
+ StringPtr processName;
+ ProcessSerialNumber processNumber;
+ unsigned long processType;
+ OSType processSignature;
+ unsigned long processMode;
+ Ptr processLocation;
+ unsigned long processSize;
+ unsigned long processFreeMem;
+ ProcessSerialNumber processLauncher;
+ unsigned long processLaunchDate;
+ unsigned long processActiveTime;
+ FSSpecPtr processAppSpec;
+};
+typedef struct ProcessInfoRec ProcessInfoRec;
+typedef ProcessInfoRec * ProcessInfoRecPtr;
+struct ProcessInfoExtendedRec {
+ unsigned long processInfoLength;
+ StringPtr processName;
+ ProcessSerialNumber processNumber;
+ unsigned long processType;
+ OSType processSignature;
+ unsigned long processMode;
+ Ptr processLocation;
+ unsigned long processSize;
+ unsigned long processFreeMem;
+ ProcessSerialNumber processLauncher;
+ unsigned long processLaunchDate;
+ unsigned long processActiveTime;
+ FSSpecPtr processAppSpec;
+ unsigned long processTempMemTotal;
+ unsigned long processPurgeableTempMemTotal;
+};
+typedef struct ProcessInfoExtendedRec ProcessInfoExtendedRec;
+typedef ProcessInfoExtendedRec * ProcessInfoExtendedRecPtr;
+
+struct SizeResourceRec {
+ unsigned short flags;
+ unsigned long preferredHeapSize;
+ unsigned long minimumHeapSize;
+};
+typedef struct SizeResourceRec SizeResourceRec;
+typedef SizeResourceRec * SizeResourceRecPtr;
+typedef SizeResourceRecPtr * SizeResourceRecHandle;
+
+
+
+
+
+enum {
+
+
+
+
+
+ kProcessDictionaryIncludeAllInformationMask = (long)0xFFFFFFFF
+};
+enum {
+ kQuitBeforeNormalTimeMask = 1,
+ kQuitAtNormalTimeMask = 2,
+ kQuitBeforeFBAsQuitMask = 4,
+ kQuitBeforeShellQuitsMask = 8,
+ kQuitBeforeTerminatorAppQuitsMask = 16,
+ kQuitNeverMask = 32,
+ kQuitOptionsMask = 0x7F,
+ kQuitNotQuitDuringInstallMask = 0x0100,
+ kQuitNotQuitDuringLogoutMask = 0x0200
+};
+extern OSErr
+LaunchApplication(LaunchPBPtr LaunchParams) ;
+extern OSErr
+GetCurrentProcess(ProcessSerialNumber * PSN) ;
+extern OSErr
+GetFrontProcess(ProcessSerialNumber * PSN) ;
+extern OSErr
+GetNextProcess(ProcessSerialNumber * PSN) ;
+extern OSErr
+GetProcessInformation(
+ const ProcessSerialNumber * PSN,
+ ProcessInfoRec * info) ;
+extern CFDictionaryRef
+ProcessInformationCopyDictionary(
+ const ProcessSerialNumber * PSN,
+ UInt32 infoToReturn) ;
+extern OSErr
+SetFrontProcess(const ProcessSerialNumber * PSN) ;
+
+
+
+
+
+
+
+enum {
+
+
+
+
+
+
+ kSetFrontProcessFrontWindowOnly = (1 << 0)
+};
+extern OSStatus
+SetFrontProcessWithOptions(
+ const ProcessSerialNumber * inProcess,
+ OptionBits inOptions) ;
+extern OSErr
+WakeUpProcess(const ProcessSerialNumber * PSN) ;
+extern OSErr
+SameProcess(
+ const ProcessSerialNumber * PSN1,
+ const ProcessSerialNumber * PSN2,
+ Boolean * result) ;
+extern void
+ExitToShell(void) ;
+extern OSStatus
+GetProcessBundleLocation(
+ const ProcessSerialNumber * psn,
+ FSRef * location) ;
+extern OSStatus
+CopyProcessName(
+ const ProcessSerialNumber * psn,
+ CFStringRef * name) ;
+extern OSStatus
+GetProcessPID(
+ const ProcessSerialNumber * psn,
+ pid_t * pid) ;
+extern OSStatus
+GetProcessForPID(
+ pid_t pid,
+ ProcessSerialNumber * psn) ;
+extern Boolean
+IsProcessVisible(const ProcessSerialNumber * psn) ;
+extern OSErr
+ShowHideProcess(
+ const ProcessSerialNumber * psn,
+ Boolean visible) ;
+
+
+
+
+enum {
+ initDev = 0,
+ hitDev = 1,
+ closeDev = 2,
+ nulDev = 3,
+ updateDev = 4,
+ activDev = 5,
+ deactivDev = 6,
+ keyEvtDev = 7,
+ macDev = 8,
+ undoDev = 9,
+ cutDev = 10,
+ copyDev = 11,
+ pasteDev = 12,
+ clearDev = 13,
+ cursorDev = 14
+};
+
+
+enum {
+ cdevGenErr = -1,
+ cdevMemErr = 0,
+ cdevResErr = 1,
+ cdevUnset = 3
+};
+
+
+
+
+
+
+
+}
+
+
+
+extern "C" {
+
+
+
+
+extern double acos (double);
+extern double asin (double);
+extern double atan (double);
+extern double atan2 (double, double);
+extern double ceil (double);
+extern double cos (double);
+extern double cosh (double);
+extern double exp (double);
+extern double fabs (double);
+extern double floor (double);
+extern double fmod (double, double);
+extern double frexp (double, int *);
+extern double ldexp (double, int);
+extern double log10 (double);
+extern double log (double);
+extern double modf (double, double *);
+extern double pow (double, double);
+extern double sin (double);
+extern double sinh (double);
+extern double sqrt (double);
+extern double tan (double);
+extern double tanh (double);
+
+
+
+enum {
+ kAXErrorSuccess = 0,
+ kAXErrorFailure = -25200,
+ kAXErrorIllegalArgument = -25201,
+ kAXErrorInvalidUIElement = -25202,
+ kAXErrorInvalidUIElementObserver = -25203,
+ kAXErrorCannotComplete = -25204,
+ kAXErrorAttributeUnsupported = -25205,
+ kAXErrorActionUnsupported = -25206,
+ kAXErrorNotificationUnsupported = -25207,
+ kAXErrorNotImplemented = -25208,
+ kAXErrorNotificationAlreadyRegistered = -25209,
+ kAXErrorNotificationNotRegistered = -25210,
+ kAXErrorAPIDisabled = -25211,
+ kAXErrorNoValue = -25212
+};
+typedef SInt32 AXError;
+
+
+
+}
+
+
+extern double acos (double);
+extern double asin (double);
+extern double atan (double);
+extern double atan2 (double, double);
+extern double ceil (double);
+extern double cos (double);
+extern double cosh (double);
+extern double exp (double);
+extern double fabs (double);
+extern double floor (double);
+extern double fmod (double, double);
+extern double frexp (double, int *);
+extern double ldexp (double, int);
+extern double log10 (double);
+extern double log (double);
+extern double modf (double, double *);
+extern double pow (double, double);
+extern double sin (double);
+extern double sinh (double);
+extern double sqrt (double);
+extern double tan (double);
+extern double tanh (double);
+
+
+extern "C" {
+
+
+
+
+extern double acos (double);
+extern double asin (double);
+extern double atan (double);
+extern double atan2 (double, double);
+extern double ceil (double);
+extern double cos (double);
+extern double cosh (double);
+extern double exp (double);
+extern double fabs (double);
+extern double floor (double);
+extern double fmod (double, double);
+extern double frexp (double, int *);
+extern double ldexp (double, int);
+extern double log10 (double);
+extern double log (double);
+extern double modf (double, double *);
+extern double pow (double, double);
+extern double sin (double);
+extern double sinh (double);
+extern double sqrt (double);
+extern double tan (double);
+extern double tanh (double);
+
+
+
+extern Boolean AXAPIEnabled ();
+
+typedef struct __AXUIElement *AXUIElementRef;
+
+extern CFTypeID AXUIElementGetTypeID (void);
+
+extern AXError AXUIElementCopyAttributeNames (AXUIElementRef element, CFArrayRef *names);
+extern AXError AXUIElementCopyAttributeValue (AXUIElementRef element, CFStringRef attribute, CFTypeRef *value);
+extern AXError AXUIElementGetAttributeValueCount (AXUIElementRef element, CFStringRef attribute, CFIndex *count);
+extern AXError AXUIElementCopyAttributeValues (AXUIElementRef element, CFStringRef attribute, CFIndex index, CFIndex maxValues, CFArrayRef *values);
+extern AXError AXUIElementIsAttributeSettable (AXUIElementRef element, CFStringRef attribute, Boolean *settable);
+extern AXError AXUIElementSetAttributeValue (AXUIElementRef element, CFStringRef attribute, CFTypeRef value);
+
+extern AXError AXUIElementCopyActionNames (AXUIElementRef element, CFArrayRef *names);
+extern AXError AXUIElementCopyActionDescription (AXUIElementRef element, CFStringRef action, CFStringRef *description);
+extern AXError AXUIElementPerformAction (AXUIElementRef element, CFStringRef action);
+
+extern AXError AXUIElementCopyElementAtPosition (AXUIElementRef application, float x,float y, AXUIElementRef *element);
+
+extern AXUIElementRef AXUIElementCreateApplication (pid_t pid);
+extern AXUIElementRef AXUIElementCreateSystemWide (void);
+
+extern AXError AXUIElementGetPid (AXUIElementRef element, pid_t *pid);
+
+
+
+extern AXError AXUIElementPostKeyboardEvent (AXUIElementRef application, CGCharCode keyChar, CGKeyCode virtualKey, Boolean keyDown);
+
+
+
+typedef struct __AXObserver *AXObserverRef;
+
+typedef void (*AXObserverCallback)(AXObserverRef observer, AXUIElementRef element, CFStringRef notification, void *refcon);
+
+CFTypeID AXObserverGetTypeID (void);
+
+extern AXError AXObserverCreate (pid_t application, AXObserverCallback callback, AXObserverRef *outObserver);
+
+extern AXError AXObserverAddNotification (AXObserverRef observer, AXUIElementRef element, CFStringRef notification, void *refcon);
+extern AXError AXObserverRemoveNotification (AXObserverRef observer, AXUIElementRef element, CFStringRef notification);
+
+extern CFRunLoopSourceRef AXObserverGetRunLoopSource (AXObserverRef observer);
+
+
+}
+extern "C" {
+
+
+
+
+extern double acos (double);
+extern double asin (double);
+extern double atan (double);
+extern double atan2 (double, double);
+extern double ceil (double);
+extern double cos (double);
+extern double cosh (double);
+extern double exp (double);
+extern double fabs (double);
+extern double floor (double);
+extern double fmod (double, double);
+extern double frexp (double, int *);
+extern double ldexp (double, int);
+extern double log10 (double);
+extern double log (double);
+extern double modf (double, double *);
+extern double pow (double, double);
+extern double sin (double);
+extern double sinh (double);
+extern double sqrt (double);
+extern double tan (double);
+extern double tanh (double);
+
+
+
+typedef enum {
+
+ kAXValueCGPointType = 1,
+ kAXValueCGSizeType = 2,
+ kAXValueCGRectType = 3,
+
+
+ kAXValueCFRangeType = 4,
+
+
+ kAXValueIllegalType = 0
+
+} AXValueType;
+
+
+extern CFTypeRef AXValueCreate (AXValueType theType, const void *valuePtr);
+extern AXValueType AXValueGetType(CFTypeRef value);
+
+extern Boolean AXValueGetValue(CFTypeRef value, AXValueType theType, void *valuePtr);
+
+
+
+}
+extern "C" {
+
+
+enum {
+
+ kFBCenglishHighWord = (long)0x80000000,
+ kFBCdutchHighWord = 0x40000000,
+ kFBCgermanHighWord = 0x20000000,
+ kFBCswedishHighWord = 0x10000000,
+ kFBCdanishHighWord = 0x08000000,
+ kFBCspanishHighWord = 0x04000000,
+ kFBCportugueseHighWord = 0x02000000,
+ kFBCitalianHighWord = 0x01000000,
+ kFBCfrenchHighWord = 0x00800000,
+ kFBCromanHighWord = 0x00400000,
+
+ kFBCicelandicHighWord = 0x00200000,
+ kFBChebrewHighWord = 0x00100000,
+ kFBCarabicHighWord = 0x00080000,
+ kFBCcenteuroHighWord = 0x00040000,
+ kFBCcroatianHighWord = 0x00020000,
+ kFBCturkishHighWord = 0x00010000,
+ kFBCromanianHighWord = 0x00008000,
+ kFBCgreekHighWord = 0x00004000,
+ kFBCcyrillicHighWord = 0x00002000,
+ kFBCdevanagariHighWord = 0x00001000,
+ kFBCgujuratiHighWord = 0x00000800,
+ kFBCgurmukhiHighWord = 0x00000400,
+ kFBCjapaneseHighWord = 0x00000200,
+ kFBCkoreanHighWord = 0x00000100,
+ kFBCdefaultLanguagesHighWord = (long)0xFF800000
+};
+
+
+enum {
+ kFBCnotAllFoldersSearchable = -30533
+};
+enum {
+
+ kFBCphIndexing = 0,
+ kFBCphFlushing = 1,
+ kFBCphMerging = 2,
+ kFBCphMakingIndexAccessor = 3,
+ kFBCphCompacting = 4,
+ kFBCphIndexWaiting = 5,
+ kFBCphSearching = 6,
+ kFBCphMakingAccessAccessor = 7,
+ kFBCphAccessWaiting = 8,
+ kFBCphSummarizing = 9,
+ kFBCphIdle = 10,
+ kFBCphCanceling = 11
+};
+
+enum {
+ kFBCsummarizationFailed = -30533
+};
+typedef struct OpaqueFBCSearchSession* FBCSearchSession;
+
+typedef struct OpaqueFBCSummaryRef* FBCSummaryRef;
+
+typedef char * FBCWordItem;
+
+typedef FBCWordItem * FBCWordList;
+typedef Boolean ( * FBCCallbackProcPtr)(UInt16 phase, float percentDone, void *data);
+typedef FBCCallbackProcPtr FBCCallbackUPP;
+extern FBCCallbackUPP
+NewFBCCallbackUPP(FBCCallbackProcPtr userRoutine) ;
+extern void
+DisposeFBCCallbackUPP(FBCCallbackUPP userUPP) ;
+extern Boolean
+InvokeFBCCallbackUPP(
+ UInt16 phase,
+ float percentDone,
+ void * data,
+ FBCCallbackUPP userUPP) ;
+extern void
+FBCSetSessionCallback(
+ FBCSearchSession searchSession,
+ FBCCallbackUPP fn,
+ void * data) ;
+extern void
+FBCSetCallback(
+ FBCCallbackUPP fn,
+ void * data) ;
+typedef Boolean ( * FBCHitTestProcPtr)(const FSRef *theFile, void *data);
+typedef FBCHitTestProcPtr FBCHitTestUPP;
+extern FBCHitTestUPP
+NewFBCHitTestUPP(FBCHitTestProcPtr userRoutine) ;
+extern void
+DisposeFBCHitTestUPP(FBCHitTestUPP userUPP) ;
+extern Boolean
+InvokeFBCHitTestUPP(
+ const FSRef * theFile,
+ void * data,
+ FBCHitTestUPP userUPP) ;
+extern void
+FBCSetSessionHitTest(
+ FBCSearchSession theSession,
+ FBCHitTestUPP fn,
+ void * data) ;
+extern void
+FBCSetHeapReservation(UInt32 bytes) ;
+extern Boolean
+FBCVolumeIsIndexed(SInt16 theVRefNum) ;
+extern Boolean
+FBCVolumeIsRemote(SInt16 theVRefNum) ;
+extern OSErr
+FBCVolumeIndexTimeStamp(
+ SInt16 theVRefNum,
+ UInt32 * timeStamp) ;
+extern OSErr
+FBCVolumeIndexPhysicalSize(
+ SInt16 theVRefNum,
+ UInt32 * size) ;
+extern OSErr
+FBCCreateSearchSession(FBCSearchSession * searchSession) ;
+extern OSErr
+FBCCloneSearchSession(
+ FBCSearchSession original,
+ FBCSearchSession * clone) ;
+extern OSErr
+FBCAddAllVolumesToSession(
+ FBCSearchSession theSession,
+ Boolean includeRemote) ;
+extern OSErr
+FBCSetSessionVolumes(
+ FBCSearchSession theSession,
+ const SInt16 vRefNums[],
+ UInt16 numVolumes) ;
+extern OSErr
+FBCAddVolumeToSession(
+ FBCSearchSession theSession,
+ SInt16 vRefNum) ;
+extern OSErr
+FBCRemoveVolumeFromSession(
+ FBCSearchSession theSession,
+ SInt16 vRefNum) ;
+extern OSErr
+FBCGetSessionVolumeCount(
+ FBCSearchSession theSession,
+ UInt16 * count) ;
+extern OSErr
+FBCGetSessionVolumes(
+ FBCSearchSession theSession,
+ SInt16 vRefNums[],
+ UInt16 * numVolumes) ;
+extern OSErr
+FBCDoQuerySearch(
+ FBCSearchSession theSession,
+ char * queryText,
+ const FSSpec targetDirs[],
+ UInt32 numTargets,
+ UInt32 maxHits,
+ UInt32 maxHitWords) ;
+extern OSErr
+FBCDoCFStringSearch(
+ FBCSearchSession theSession,
+ CFStringRef queryString,
+ const FSSpec targetDirs[],
+ UInt32 numTargets,
+ UInt32 maxHits,
+ UInt32 maxHitWords) ;
+extern OSErr
+FBCDoExampleSearch(
+ FBCSearchSession theSession,
+ const UInt32 * exampleHitNums,
+ UInt32 numExamples,
+ const FSSpec targetDirs[],
+ UInt32 numTargets,
+ UInt32 maxHits,
+ UInt32 maxHitWords) ;
+extern OSErr
+FBCBlindExampleSearch(
+ const FSSpec examples[],
+ UInt32 numExamples,
+ const FSSpec targetDirs[],
+ UInt32 numTargets,
+ UInt32 maxHits,
+ UInt32 maxHitWords,
+ Boolean allIndexes,
+ Boolean includeRemote,
+ FBCSearchSession * theSession) ;
+extern OSErr
+FBCBlindExampleSearchWithCallback(
+ const FSSpec examples[],
+ UInt32 numExamples,
+ const FSSpec targetDirs[],
+ UInt32 numTargets,
+ UInt32 maxHits,
+ UInt32 maxHitWords,
+ Boolean allIndexes,
+ Boolean includeRemote,
+ FBCSearchSession * theSession,
+ FBCCallbackUPP callback,
+ void * callbackData,
+ FBCHitTestUPP userHitTest,
+ void * userHitTestData) ;
+extern OSErr
+FBCGetHitCount(
+ FBCSearchSession theSession,
+ UInt32 * count) ;
+extern OSErr
+FBCGetHitDocument(
+ FBCSearchSession theSession,
+ UInt32 hitNumber,
+ FSSpec * theDocument) ;
+extern OSErr
+FBCGetHitDocumentRef(
+ FBCSearchSession theSession,
+ UInt32 hitNumber,
+ FSRef * theDocument) ;
+extern OSErr
+FBCGetHitScore(
+ FBCSearchSession theSession,
+ UInt32 hitNumber,
+ float * score) ;
+extern OSErr
+FBCSummarize(
+ const void * inBuf,
+ UInt32 inLength,
+ void * outBuf,
+ UInt32 * outLength,
+ UInt32 * numSentences) ;
+extern OSStatus
+FBCSummarizeCFString(
+ CFStringRef inString,
+ CFStringRef * outString,
+ UInt32 * numSentences) ;
+extern OSStatus
+FBCGetSummaryOfCFString(
+ CFStringRef inString,
+ FBCSummaryRef * summary) ;
+extern OSStatus
+FBCGetSummarySentenceCount(
+ FBCSummaryRef summary,
+ UInt32 * numSentences) ;
+extern OSStatus
+FBCGetSummarySentences(
+ FBCSummaryRef summary,
+ CFStringRef * outString,
+ UInt32 * numSentences,
+ Boolean paragraphs) ;
+extern OSStatus
+FBCDisposeSummary(FBCSummaryRef summary) ;
+extern OSErr
+FBCReleaseSessionHits(FBCSearchSession theSession) ;
+extern OSErr
+FBCDestroySearchSession(FBCSearchSession theSession) ;
+extern OSErr
+FBCIndexItems(
+ FSSpecArrayPtr theItems,
+ UInt32 itemCount) ;
+extern OSErr
+FBCIndexItemsInLanguages(
+ FSSpecArrayPtr theItems,
+ UInt32 itemCount,
+ UInt32 languageHighBits,
+ UInt32 languageLowBits) ;
+extern OSErr
+FBCFindIndexFileFolderForFolder(
+ const FSRef * inFolder,
+ FSRef * outFolder) ;
+extern OSErr
+FBCDeleteIndexFileForFolder(const FSRef * folder) ;
+extern OSErr
+FBCGetMatchedWords(
+ FBCSearchSession theSession,
+ UInt32 hitNumber,
+ UInt32 * wordCount,
+ FBCWordList * list) ;
+extern OSErr
+FBCGetTopicWords(
+ FBCSearchSession theSession,
+ UInt32 hitNumber,
+ UInt32 * wordCount,
+ FBCWordList * list) ;
+extern OSErr
+FBCDestroyWordList(
+ FBCWordList theList,
+ UInt32 wordCount) ;
+
+
+
+enum {
+
+ englishHighWord = kFBCenglishHighWord,
+ dutchHighWord = kFBCdutchHighWord,
+ germanHighWord = kFBCgermanHighWord,
+ swedishHighWord = kFBCswedishHighWord,
+ danishHighWord = kFBCdanishHighWord,
+ spanishHighWord = kFBCspanishHighWord,
+ portugueseHighWord = kFBCportugueseHighWord,
+ italianHighWord = kFBCitalianHighWord,
+ frenchHighWord = kFBCfrenchHighWord,
+ romanHighWord = kFBCromanHighWord,
+
+ icelandicHighWord = kFBCicelandicHighWord,
+ hebrewHighWord = kFBChebrewHighWord,
+ arabicHighWord = kFBCarabicHighWord,
+ centeuroHighWord = kFBCcenteuroHighWord,
+ croatianHighWord = kFBCcroatianHighWord,
+ turkishHighWord = kFBCturkishHighWord,
+ romanianHighWord = kFBCromanianHighWord,
+ greekHighWord = kFBCgreekHighWord,
+ cyrillicHighWord = kFBCcyrillicHighWord,
+ devanagariHighWord = kFBCdevanagariHighWord,
+ gujuratiHighWord = kFBCgujuratiHighWord,
+ gurmukhiHighWord = kFBCgurmukhiHighWord,
+ japaneseHighWord = kFBCjapaneseHighWord,
+ koreanHighWord = kFBCkoreanHighWord,
+ kDefaultLanguagesHighWord = kFBCdefaultLanguagesHighWord
+};
+
+
+
+
+}
+
+
+
+
+
+typedef const void * PMObject;
+typedef struct OpaquePMDialog* PMDialog;
+typedef struct OpaquePMPrintSettings* PMPrintSettings;
+typedef struct OpaquePMPageFormat* PMPageFormat;
+typedef struct OpaquePMPrintContext* PMPrintContext;
+typedef struct OpaquePMPrintSession* PMPrintSession;
+typedef struct OpaquePMPrinter* PMPrinter;
+typedef struct OpaquePMServer* PMServer;
+enum {
+ kPMCancel = 0x0080
+};
+typedef UInt16 PMDestinationType;
+enum {
+ kPMDestinationInvalid = 0,
+ kPMDestinationPrinter = 1,
+ kPMDestinationFile = 2,
+ kPMDestinationFax = 3,
+ kPMDestinationPreview = 4
+};
+
+
+typedef UInt32 PMTag;
+enum {
+
+ kPMCurrentValue = 'curr',
+ kPMDefaultValue = 'dflt',
+ kPMMinimumValue = 'minv',
+ kPMMaximumValue = 'maxv',
+
+ kPMSourceProfile = 'srcp',
+
+ kPMMinRange = 'mnrg',
+ kPMMaxRange = 'mxrg',
+ kPMMinSquareResolution = 'mins',
+ kPMMaxSquareResolution = 'maxs',
+ kPMDefaultResolution = 'dftr'
+};
+
+
+typedef UInt16 PMOrientation;
+enum {
+ kPMPortrait = 1,
+ kPMLandscape = 2,
+ kPMReversePortrait = 3,
+ kPMReverseLandscape = 4
+};
+
+
+typedef UInt16 PMPrinterState;
+enum {
+ kPMPrinterIdle = 3,
+ kPMPrinterProcessing = 4,
+ kPMPrinterStopped = 5
+};
+
+enum {
+ kSizeOfTPrint = 120
+};
+
+typedef UInt16 PMColorMode;
+enum {
+ kPMBlackAndWhite = 1,
+ kPMGray = 2,
+ kPMColor = 3,
+ kPMColorModeDuotone = 4,
+ kPMColorModeSpecialColor = 5
+};
+
+
+
+typedef UInt32 PMColorSyncIntent;
+enum {
+ kPMColorIntentUndefined = 0x0000,
+ kPMColorIntentAutomatic = 0x0001,
+ kPMColorIntentPhoto = 0x0002,
+ kPMColorIntentBusiness = 0x0004,
+ kPMColorIntentRelColor = 0x0008,
+ kPMColorIntentAbsColor = 0x0010,
+ kPMColorIntentUnused = 0xFFE0
+};
+
+
+typedef UInt32 PMQualityMode;
+enum {
+ kPMQualityLowest = 0x0000,
+ kPMQualityInkSaver = 0x0001,
+ kPMQualityDraft = 0x0004,
+ kPMQualityNormal = 0x0008,
+ kPMQualityPhoto = 0x000B,
+ kPMQualityBest = 0x000D,
+ kPMQualityHighest = 0x000F
+};
+
+
+
+typedef UInt32 PMPaperType;
+enum {
+ kPMPaperTypeUnknown = 0x0000,
+ kPMPaperTypePlain = 0x0001,
+ kPMPaperTypeCoated = 0x0002,
+ kPMPaperTypePremium = 0x0003,
+ kPMPaperTypeGlossy = 0x0004,
+ kPMPaperTypeTransparency = 0x0005,
+ kPMPaperTypeTShirt = 0x0006
+};
+
+
+typedef UInt16 PMScalingAlignment;
+enum {
+ kPMScalingPinTopLeft = 1,
+ kPMScalingPinTopRight = 2,
+ kPMScalingPinBottomLeft = 3,
+ kPMScalingPinBottomRight = 4,
+ kPMScalingCenterOnPaper = 5,
+ kPMScalingCenterOnImgArea = 6
+};
+
+
+typedef UInt16 PMDuplexBinding;
+enum {
+ kPMDuplexBindingLeftRight = 1,
+ kPMDuplexBindingTopDown = 2
+};
+
+
+typedef UInt16 PMLayoutDirection;
+enum {
+
+ kPMLayoutLeftRightTopBottom = 1,
+ kPMLayoutLeftRightBottomTop = 2,
+ kPMLayoutRightLeftTopBottom = 3,
+ kPMLayoutRightLeftBottomTop = 4,
+ kPMLayoutTopBottomLeftRight = 5,
+ kPMLayoutTopBottomRightLeft = 6,
+ kPMLayoutBottomTopLeftRight = 7,
+ kPMLayoutBottomTopRightLeft = 8
+};
+
+
+typedef UInt16 PMBorderType;
+enum {
+ kPMBorderSingleHairline = 1,
+ kPMBorderDoubleHairline = 2,
+ kPMBorderSingleThickline = 3,
+ kPMBorderDoubleThickline = 4
+};
+
+
+enum {
+ kPSPageInjectAllPages = -1,
+ kPSInjectionMaxDictSize = 5
+};
+
+
+typedef UInt16 PSInjectionPlacement;
+enum {
+ kPSInjectionBeforeSubsection = 1,
+ kPSInjectionAfterSubsection = 2,
+ kPSInjectionReplaceSubsection = 3
+};
+
+
+typedef SInt32 PSInjectionSection;
+enum {
+
+ kInjectionSectJob = 1,
+ kInjectionSectCoverPage = 2
+};
+
+
+typedef SInt32 PSInjectionSubsection;
+enum {
+ kInjectionSubPSAdobe = 1,
+ kInjectionSubPSAdobeEPS = 2,
+ kInjectionSubBoundingBox = 3,
+ kInjectionSubEndComments = 4,
+ kInjectionSubOrientation = 5,
+ kInjectionSubPages = 6,
+ kInjectionSubPageOrder = 7,
+ kInjectionSubBeginProlog = 8,
+ kInjectionSubEndProlog = 9,
+ kInjectionSubBeginSetup = 10,
+ kInjectionSubEndSetup = 11,
+ kInjectionSubBeginDefaults = 12,
+ kInjectionSubEndDefaults = 13,
+ kInjectionSubDocFonts = 14,
+ kInjectionSubDocNeededFonts = 15,
+ kInjectionSubDocSuppliedFonts = 16,
+ kInjectionSubDocNeededRes = 17,
+ kInjectionSubDocSuppliedRes = 18,
+ kInjectionSubDocCustomColors = 19,
+ kInjectionSubDocProcessColors = 20,
+ kInjectionSubPlateColor = 21,
+ kInjectionSubPageTrailer = 22,
+ kInjectionSubTrailer = 23,
+ kInjectionSubEOF = 24,
+ kInjectionSubBeginFont = 25,
+ kInjectionSubEndFont = 26,
+ kInjectionSubBeginResource = 27,
+ kInjectionSubEndResource = 28,
+ kInjectionSubPage = 29,
+ kInjectionSubBeginPageSetup = 30,
+ kInjectionSubEndPageSetup = 31
+};
+enum {
+ kPMNoError = noErr,
+ kPMGeneralError = -30870,
+ kPMOutOfScope = -30871,
+ kPMInvalidParameter = paramErr,
+ kPMNoDefaultPrinter = -30872,
+ kPMNotImplemented = -30873,
+ kPMNoSuchEntry = -30874,
+ kPMInvalidPrintSettings = -30875,
+ kPMInvalidPageFormat = -30876,
+ kPMValueOutOfRange = -30877,
+ kPMLockIgnored = -30878
+};
+
+enum {
+ kPMInvalidPrintSession = -30879,
+ kPMInvalidPrinter = -30880,
+ kPMObjectInUse = -30881
+};
+
+
+enum {
+ kPMPrintAllPages = -1
+};
+
+enum {
+ kPMUnlocked = false,
+ kPMLocked = true
+};
+
+struct PMRect {
+ double top;
+ double left;
+ double bottom;
+ double right;
+};
+typedef struct PMRect PMRect;
+struct PMResolution {
+ double hRes;
+ double vRes;
+};
+typedef struct PMResolution PMResolution;
+struct PMLanguageInfo {
+ Str32 level;
+ Str32 version;
+ Str32 release;
+};
+typedef struct PMLanguageInfo PMLanguageInfo;
+
+extern "C" {
+
+
+
+
+
+
+
+typedef void ( * PMIdleProcPtr)(void);
+typedef PMIdleProcPtr PMIdleUPP;
+extern PMIdleUPP
+NewPMIdleUPP(PMIdleProcPtr userRoutine) ;
+extern void
+DisposePMIdleUPP(PMIdleUPP userUPP) ;
+extern void
+InvokePMIdleUPP(PMIdleUPP userUPP) ;
+extern OSStatus
+PMRetain(PMObject object) ;
+extern OSStatus
+PMRelease(PMObject object) ;
+extern OSStatus
+PMCreateSession(PMPrintSession * printSession) ;
+extern OSStatus
+PMCreatePageFormat(PMPageFormat * pageFormat) ;
+extern OSStatus
+PMSessionDefaultPageFormat(
+ PMPrintSession printSession,
+ PMPageFormat pageFormat) ;
+extern OSStatus
+PMSessionValidatePageFormat(
+ PMPrintSession printSession,
+ PMPageFormat pageFormat,
+ Boolean * result) ;
+extern OSStatus
+PMCreatePrintSettings(PMPrintSettings * printSettings) ;
+extern OSStatus
+PMSessionDefaultPrintSettings(
+ PMPrintSession printSession,
+ PMPrintSettings printSettings) ;
+extern OSStatus
+PMSessionValidatePrintSettings(
+ PMPrintSession printSession,
+ PMPrintSettings printSettings,
+ Boolean * result) ;
+extern OSStatus
+PMSessionGeneral(
+ PMPrintSession printSession,
+ Ptr pData) ;
+extern OSStatus
+PMSessionConvertOldPrintRecord(
+ PMPrintSession printSession,
+ Handle printRecordHandle,
+ PMPrintSettings * printSettings,
+ PMPageFormat * pageFormat) ;
+extern OSStatus
+PMSessionMakeOldPrintRecord(
+ PMPrintSession printSession,
+ PMPrintSettings printSettings,
+ PMPageFormat pageFormat,
+ Handle * printRecordHandle) ;
+extern OSStatus
+PMPrinterGetDescriptionURL(
+ PMPrinter printer,
+ CFStringRef descriptionType,
+ CFURLRef * fileURL) ;
+extern OSStatus
+PMSessionGetCurrentPrinter(
+ PMPrintSession printSession,
+ PMPrinter * currentPrinter) ;
+extern OSStatus
+PMPrinterGetLanguageInfo(
+ PMPrinter printer,
+ PMLanguageInfo * info) ;
+extern OSStatus
+PMPrinterGetDriverCreator(
+ PMPrinter printer,
+ OSType * creator) ;
+extern OSStatus
+PMPrinterGetDriverReleaseInfo(
+ PMPrinter printer,
+ VersRec * release) ;
+extern OSStatus
+PMPrinterGetPrinterResolutionCount(
+ PMPrinter printer,
+ UInt32 * count) ;
+extern OSStatus
+PMPrinterGetPrinterResolution(
+ PMPrinter printer,
+ PMTag tag,
+ PMResolution * res) ;
+extern OSStatus
+PMPrinterGetIndexedPrinterResolution(
+ PMPrinter printer,
+ UInt32 index,
+ PMResolution * res) ;
+extern Boolean
+PMPrinterIsPostScriptCapable(PMPrinter printer) ;
+extern OSStatus
+PMPrinterGetMakeAndModelName(
+ PMPrinter printer,
+ CFStringRef * makeAndModel) ;
+extern OSStatus
+PMSessionEnableColorSync(PMPrintSession printSession) ;
+extern OSStatus
+PMSessionDisableColorSync(PMPrintSession printSession) ;
+extern OSStatus
+PMSessionPostScriptBegin(PMPrintSession printSession) ;
+extern OSStatus
+PMSessionPostScriptEnd(PMPrintSession printSession) ;
+extern OSStatus
+PMSessionPostScriptHandle(
+ PMPrintSession printSession,
+ Handle psHandle) ;
+extern OSStatus
+PMSessionPostScriptData(
+ PMPrintSession printSession,
+ Ptr psPtr,
+ Size len) ;
+extern OSStatus
+PMSessionPostScriptFile(
+ PMPrintSession printSession,
+ FSSpec * psFile) ;
+extern OSStatus
+PMSessionSetPSInjectionData(
+ PMPrintSession printSession,
+ PMPrintSettings printSettings,
+ CFArrayRef injectionDictArray) ;
+extern OSStatus
+PMSessionError(PMPrintSession printSession) ;
+extern OSStatus
+PMSessionSetError(
+ PMPrintSession printSession,
+ OSStatus printError) ;
+extern OSStatus
+PMSessionGetDocumentFormatGeneration(
+ PMPrintSession printSession,
+ CFArrayRef * docFormats) ;
+extern OSStatus
+PMSessionSetDocumentFormatGeneration(
+ PMPrintSession printSession,
+ CFStringRef docFormat,
+ CFArrayRef graphicsContextTypes,
+ CFTypeRef options) ;
+extern OSStatus
+PMSessionGetDocumentFormatSupported(
+ PMPrintSession printSession,
+ CFArrayRef * docFormats,
+ UInt32 limit) ;
+extern OSStatus
+PMSessionIsDocumentFormatSupported(
+ PMPrintSession printSession,
+ CFStringRef docFormat,
+ Boolean * supported) ;
+extern OSStatus
+PMSessionGetGraphicsContext(
+ PMPrintSession printSession,
+ CFStringRef graphicsContextType,
+ void ** graphicsContext) ;
+extern OSStatus
+PMSessionSetIdleProc(
+ PMPrintSession printSession,
+ PMIdleUPP idleProc) ;
+extern OSStatus
+PMSessionSetDataInSession(
+ PMPrintSession printSession,
+ CFStringRef key,
+ CFTypeRef data) ;
+extern OSStatus
+PMSessionGetDataFromSession(
+ PMPrintSession printSession,
+ CFStringRef key,
+ CFTypeRef * data) ;
+extern OSStatus
+PMSessionCreatePrinterList(
+ PMPrintSession printSession,
+ CFArrayRef * printerList,
+ CFIndex * currentIndex,
+ PMPrinter * currentPrinter) ;
+extern OSStatus
+PMSessionSetCurrentPrinter(
+ PMPrintSession session,
+ CFStringRef printerName) ;
+extern OSStatus
+PMSessionSetDestination(
+ PMPrintSession printSession,
+ PMPrintSettings printSettings,
+ PMDestinationType destType,
+ CFStringRef destFormat,
+ CFURLRef destLocation) ;
+extern OSStatus
+PMSessionGetDestinationType(
+ PMPrintSession printSession,
+ PMPrintSettings printSettings,
+ PMDestinationType * destTypeP) ;
+extern OSStatus
+PMSessionCopyDestinationFormat(
+ PMPrintSession printSession,
+ PMPrintSettings printSettings,
+ CFStringRef * destFormatP) ;
+extern OSStatus
+PMSessionCopyDestinationLocation(
+ PMPrintSession printSession,
+ PMPrintSettings printSettings,
+ CFURLRef * destLocationP) ;
+extern OSStatus
+PMSessionCopyOutputFormatList(
+ PMPrintSession printSession,
+ PMDestinationType destType,
+ CFArrayRef * documentFormatP) ;
+extern OSStatus
+PMSessionCreatePageFormatList(
+ PMPrintSession printSession,
+ PMPrinter printer,
+ CFArrayRef * pageFormatList) ;
+extern OSStatus
+PMSessionBeginDocumentNoDialog(
+ PMPrintSession printSession,
+ PMPrintSettings printSettings,
+ PMPageFormat pageFormat) ;
+extern OSStatus
+PMSessionEndDocumentNoDialog(PMPrintSession printSession) ;
+extern OSStatus
+PMSessionBeginPageNoDialog(
+ PMPrintSession printSession,
+ PMPageFormat pageFormat,
+ const PMRect * pageFrame) ;
+extern OSStatus
+PMSessionEndPageNoDialog(PMPrintSession printSession) ;
+extern OSStatus
+PMCopyPageFormat(
+ PMPageFormat formatSrc,
+ PMPageFormat formatDest) ;
+extern OSStatus
+PMFlattenPageFormat(
+ PMPageFormat pageFormat,
+ Handle * flatFormat) ;
+extern OSStatus
+PMUnflattenPageFormat(
+ Handle flatFormat,
+ PMPageFormat * pageFormat) ;
+extern OSStatus
+PMGetPageFormatExtendedData(
+ PMPageFormat pageFormat,
+ OSType dataID,
+ UInt32 * size,
+ void * extendedData) ;
+extern OSStatus
+PMSetPageFormatExtendedData(
+ PMPageFormat pageFormat,
+ OSType dataID,
+ UInt32 size,
+ void * extendedData) ;
+extern OSStatus
+PMGetScale(
+ PMPageFormat pageFormat,
+ double * scale) ;
+extern OSStatus
+PMSetScale(
+ PMPageFormat pageFormat,
+ double scale) ;
+extern OSStatus
+PMGetResolution(
+ PMPageFormat pageFormat,
+ PMResolution * res) ;
+extern OSStatus
+PMSetResolution(
+ PMPageFormat pageFormat,
+ const PMResolution * res) ;
+extern OSStatus
+PMGetPhysicalPaperSize(
+ PMPageFormat pageFormat,
+ PMRect * paperSize) ;
+extern OSStatus
+PMSetPhysicalPaperSize(
+ PMPageFormat pageFormat,
+ const PMRect * paperSize) ;
+extern OSStatus
+PMGetPhysicalPageSize(
+ PMPageFormat pageFormat,
+ PMRect * pageSize) ;
+extern OSStatus
+PMGetAdjustedPaperRect(
+ PMPageFormat pageFormat,
+ PMRect * paperRect) ;
+extern OSStatus
+PMGetAdjustedPageRect(
+ PMPageFormat pageFormat,
+ PMRect * pageRect) ;
+extern OSStatus
+PMGetUnadjustedPaperRect(
+ PMPageFormat pageFormat,
+ PMRect * paperRect) ;
+extern OSStatus
+PMSetUnadjustedPaperRect(
+ PMPageFormat pageFormat,
+ const PMRect * paperRect) ;
+extern OSStatus
+PMGetUnadjustedPageRect(
+ PMPageFormat pageFormat,
+ PMRect * pageRect) ;
+extern OSStatus
+PMSetAdjustedPageRect(
+ PMPageFormat pageFormat,
+ const PMRect * pageRect) ;
+extern OSStatus
+PMGetOrientation(
+ PMPageFormat pageFormat,
+ PMOrientation * orientation) ;
+extern OSStatus
+PMSetOrientation(
+ PMPageFormat pageFormat,
+ PMOrientation orientation,
+ Boolean lock) ;
+extern OSStatus
+PMCopyPrintSettings(
+ PMPrintSettings settingSrc,
+ PMPrintSettings settingDest) ;
+extern OSStatus
+PMFlattenPrintSettings(
+ PMPrintSettings printSettings,
+ Handle * flatSettings) ;
+extern OSStatus
+PMUnflattenPrintSettings(
+ Handle flatSettings,
+ PMPrintSettings * printSettings) ;
+extern OSStatus
+PMGetPrintSettingsExtendedData(
+ PMPrintSettings printSettings,
+ OSType dataID,
+ UInt32 * size,
+ void * extendedData) ;
+extern OSStatus
+PMSetPrintSettingsExtendedData(
+ PMPrintSettings printSettings,
+ OSType dataID,
+ UInt32 size,
+ void * extendedData) ;
+extern OSStatus
+PMGetDestination(
+ PMPrintSettings printSettings,
+ PMDestinationType * destType,
+ CFURLRef * fileURL) ;
+extern OSStatus
+PMGetJobName(
+ PMPrintSettings printSettings,
+ StringPtr name) ;
+extern OSStatus
+PMSetJobName(
+ PMPrintSettings printSettings,
+ StringPtr name) ;
+extern OSStatus
+PMGetCopies(
+ PMPrintSettings printSettings,
+ UInt32 * copies) ;
+extern OSStatus
+PMSetCopies(
+ PMPrintSettings printSettings,
+ UInt32 copies,
+ Boolean lock) ;
+extern OSStatus
+PMGetFirstPage(
+ PMPrintSettings printSettings,
+ UInt32 * first) ;
+extern OSStatus
+PMSetFirstPage(
+ PMPrintSettings printSettings,
+ UInt32 first,
+ Boolean lock) ;
+extern OSStatus
+PMGetLastPage(
+ PMPrintSettings printSettings,
+ UInt32 * last) ;
+extern OSStatus
+PMSetLastPage(
+ PMPrintSettings printSettings,
+ UInt32 last,
+ Boolean lock) ;
+extern OSStatus
+PMGetPageRange(
+ PMPrintSettings printSettings,
+ UInt32 * minPage,
+ UInt32 * maxPage) ;
+extern OSStatus
+PMSetPageRange(
+ PMPrintSettings printSettings,
+ UInt32 minPage,
+ UInt32 maxPage) ;
+extern OSStatus
+PMSetProfile(
+ PMPrintSettings printSettings,
+ PMTag tag,
+ const CMProfileLocation * profile) ;
+extern OSStatus
+PMGetColorMode(
+ PMPrintSettings printSettings,
+ PMColorMode * colorMode) ;
+extern OSStatus
+PMSetColorMode(
+ PMPrintSettings printSettings,
+ PMColorMode colorMode) ;
+extern OSStatus
+PMGetJobNameCFString(
+ PMPrintSettings printSettings,
+ CFStringRef * name) ;
+extern OSStatus
+PMSetJobNameCFString(
+ PMPrintSettings printSettings,
+ CFStringRef name) ;
+extern OSStatus
+PMSetCollate(
+ PMPrintSettings printSettings,
+ Boolean collate) ;
+extern OSStatus
+PMGetCollate(
+ PMPrintSettings printSettings,
+ Boolean * collate) ;
+extern OSStatus
+PMServerCreatePrinterList(
+ PMServer server,
+ CFArrayRef * printerList) ;
+extern CFStringRef
+PMPrinterGetName(PMPrinter printer) ;
+extern CFStringRef
+PMPrinterGetID(PMPrinter printer) ;
+extern Boolean
+PMPrinterIsDefault(PMPrinter printer) ;
+extern CFStringRef
+PMPrinterGetLocation(PMPrinter printer) ;
+extern OSStatus
+PMPrinterGetState(
+ PMPrinter printer,
+ PMPrinterState * state) ;
+extern OSStatus
+PMPrinterGetDeviceURI(
+ PMPrinter printer,
+ CFURLRef * deviceURI) ;
+extern Boolean
+PMPrinterIsFavorite(PMPrinter printer) ;
+extern CGImageRef
+PMCGImageCreateWithEPSDataProvider(
+ CGDataProviderRef epsDataProvider,
+ CGImageRef epsPreview) ;
+
+
+
+
+}
+
+
+
+extern "C" {
+
+
+enum {
+ kDictionaryFileType = 'dict',
+ kDCMDictionaryHeaderSignature = 'dict',
+ kDCMDictionaryHeaderVersion = 2
+};
+
+enum {
+ kDCMAnyFieldTag = typeWildCard,
+ kDCMAnyFieldType = typeWildCard
+};
+
+
+
+
+enum {
+ keyDCMFieldTag = 'ftag',
+ keyDCMFieldType = 'ftyp',
+ keyDCMMaxRecordSize = 'mrsz',
+ keyDCMFieldAttributes = 'fatr',
+ keyDCMFieldDefaultData = 'fdef',
+ keyDCMFieldName = 'fnam',
+ keyDCMFieldFindMethods = 'ffnd'
+};
+
+
+
+
+enum {
+ typeDCMFieldAttributes = 'fatr',
+ typeDCMFindMethod = 'fmth'
+};
+
+
+
+
+
+enum {
+ kDCMIndexedFieldMask = 0x00000001,
+ kDCMRequiredFieldMask = 0x00000002,
+ kDCMIdentifyFieldMask = 0x00000004,
+ kDCMFixedSizeFieldMask = 0x00000008,
+ kDCMHiddenFieldMask = (long)0x80000000
+};
+
+typedef OptionBits DCMFieldAttributes;
+
+
+
+enum {
+ pDCMAccessMethod = 'amtd',
+ pDCMPermission = 'perm',
+ pDCMListing = 'list',
+ pDCMMaintenance = 'mtnc',
+ pDCMLocale = 'locl',
+ pDCMClass = pClass,
+ pDCMCopyright = 'info'
+};
+
+
+
+
+enum {
+ kDCMReadOnlyDictionary = 0,
+ kDCMReadWriteDictionary = 1
+};
+
+
+
+
+enum {
+ kDCMAllowListing = 0,
+ kDCMProhibitListing = 1
+};
+
+
+
+
+enum {
+ kDCMUserDictionaryClass = 0,
+ kDCMSpecificDictionaryClass = 1,
+ kDCMBasicDictionaryClass = 2
+};
+
+
+
+
+enum {
+ kDCMFindMethodExactMatch = kAEEquals,
+ kDCMFindMethodBeginningMatch = kAEBeginsWith,
+ kDCMFindMethodContainsMatch = kAEContains,
+ kDCMFindMethodEndingMatch = kAEEndsWith,
+ kDCMFindMethodForwardTrie = 'ftri',
+ kDCMFindMethodBackwardTrie = 'btri'
+};
+
+typedef OSType DCMFindMethod;
+
+
+
+enum {
+ kDCMCanUseFileDictionaryMask = 0x00000001,
+ kDCMCanUseMemoryDictionaryMask = 0x00000002,
+ kDCMCanStreamDictionaryMask = 0x00000004,
+ kDCMCanHaveMultipleIndexMask = 0x00000008,
+ kDCMCanModifyDictionaryMask = 0x00000010,
+ kDCMCanCreateDictionaryMask = 0x00000020,
+ kDCMCanAddDictionaryFieldMask = 0x00000040,
+ kDCMCanUseTransactionMask = 0x00000080
+};
+
+typedef OptionBits DCMAccessMethodFeature;
+typedef UInt32 DCMUniqueID;
+typedef struct OpaqueDCMObjectID* DCMObjectID;
+typedef DCMObjectID DCMAccessMethodID;
+typedef DCMObjectID DCMDictionaryID;
+
+typedef struct OpaqueDCMObjectRef* DCMObjectRef;
+typedef DCMObjectRef DCMDictionaryRef;
+typedef DCMObjectRef DCMDictionaryStreamRef;
+
+typedef struct OpaqueDCMObjectIterator* DCMObjectIterator;
+typedef DCMObjectIterator DCMAccessMethodIterator;
+typedef DCMObjectIterator DCMDictionaryIterator;
+typedef struct OpaqueDCMFoundRecordIterator* DCMFoundRecordIterator;
+
+
+
+typedef DescType DCMFieldTag;
+typedef DescType DCMFieldType;
+
+
+
+struct DCMDictionaryHeader {
+ FourCharCode headerSignature;
+ UInt32 headerVersion;
+ ByteCount headerSize;
+ Str63 accessMethod;
+};
+typedef struct DCMDictionaryHeader DCMDictionaryHeader;
+
+
+
+typedef Boolean ( * DCMProgressFilterProcPtr)(Boolean determinateProcess, UInt16 percentageComplete, UInt32 callbackUD);
+typedef DCMProgressFilterProcPtr DCMProgressFilterUPP;
+extern UInt32
+DCMLibraryVersion(void) ;
+extern OSStatus
+DCMNewDictionary(
+ DCMAccessMethodID accessMethodID,
+ const FSSpec * newDictionaryFile,
+ ScriptCode scriptTag,
+ const AEDesc * listOfFieldInfoRecords,
+ Boolean invisible,
+ ItemCount recordCapacity,
+ DCMDictionaryID * newDictionary) ;
+extern OSStatus
+DCMDeriveNewDictionary(
+ DCMDictionaryID srcDictionary,
+ const FSSpec * newDictionaryFile,
+ ScriptCode scriptTag,
+ Boolean invisible,
+ ItemCount recordCapacity,
+ DCMDictionaryID * newDictionary) ;
+extern OSStatus
+DCMDeleteDictionary(DCMDictionaryID dictionaryID) ;
+extern OSStatus
+DCMRegisterDictionaryFile(
+ const FSSpec * dictionaryFile,
+ DCMDictionaryID * dictionaryID) ;
+extern OSStatus
+DCMUnregisterDictionary(DCMDictionaryID dictionaryID) ;
+extern OSStatus
+DCMOpenDictionary(
+ DCMDictionaryID dictionaryID,
+ ByteCount protectKeySize,
+ ConstLogicalAddress protectKey,
+ DCMDictionaryRef * dictionaryRef) ;
+extern OSStatus
+DCMCloseDictionary(DCMDictionaryRef dictionaryRef) ;
+extern OSStatus
+DCMGetDictionaryWriteAccess(
+ DCMDictionaryRef dictionaryRef,
+ Duration timeOutDuration) ;
+extern OSStatus
+DCMReleaseDictionaryWriteAccess(
+ DCMDictionaryRef dictionaryRef,
+ Boolean commitTransaction) ;
+extern OSStatus
+DCMFindRecords(
+ DCMDictionaryRef dictionaryRef,
+ DCMFieldTag keyFieldTag,
+ ByteCount keySize,
+ ConstLogicalAddress keyData,
+ DCMFindMethod findMethod,
+ ItemCount preFetchedDataNum,
+ DCMFieldTag preFetchedData[],
+ ItemCount skipCount,
+ ItemCount maxRecordCount,
+ DCMFoundRecordIterator * recordIterator) ;
+extern ItemCount
+DCMCountRecordIterator(DCMFoundRecordIterator recordIterator) ;
+extern OSStatus
+DCMIterateFoundRecord(
+ DCMFoundRecordIterator recordIterator,
+ ByteCount maxKeySize,
+ ByteCount * actualKeySize,
+ LogicalAddress keyData,
+ DCMUniqueID * uniqueID,
+ AEDesc * dataList) ;
+extern OSStatus
+DCMDisposeRecordIterator(DCMFoundRecordIterator recordIterator) ;
+extern OSStatus
+DCMCountRecord(
+ DCMDictionaryID dictionaryID,
+ ItemCount * count) ;
+extern OSStatus
+DCMGetRecordSequenceNumber(
+ DCMDictionaryRef dictionaryRef,
+ DCMFieldTag keyFieldTag,
+ ByteCount keySize,
+ ConstLogicalAddress keyData,
+ DCMUniqueID uniqueID,
+ ItemCount * sequenceNum) ;
+extern OSStatus
+DCMGetNthRecord(
+ DCMDictionaryRef dictionaryRef,
+ DCMFieldTag keyFieldTag,
+ ItemCount serialNum,
+ ByteCount maxKeySize,
+ ByteCount * keySize,
+ LogicalAddress keyData,
+ DCMUniqueID * uniqueID) ;
+extern OSStatus
+DCMGetNextRecord(
+ DCMDictionaryRef dictionaryRef,
+ DCMFieldTag keyFieldTag,
+ ByteCount keySize,
+ ConstLogicalAddress keyData,
+ DCMUniqueID uniqueID,
+ ByteCount maxKeySize,
+ ByteCount * nextKeySize,
+ LogicalAddress nextKeyData,
+ DCMUniqueID * nextUniqueID) ;
+extern OSStatus
+DCMGetPrevRecord(
+ DCMDictionaryRef dictionaryRef,
+ DCMFieldTag keyFieldTag,
+ ByteCount keySize,
+ ConstLogicalAddress keyData,
+ DCMUniqueID uniqueID,
+ ByteCount maxKeySize,
+ ByteCount * prevKeySize,
+ LogicalAddress prevKeyData,
+ DCMUniqueID * prevUniqueID) ;
+extern OSStatus
+DCMGetFieldData(
+ DCMDictionaryRef dictionaryRef,
+ DCMFieldTag keyFieldTag,
+ ByteCount keySize,
+ ConstLogicalAddress keyData,
+ DCMUniqueID uniqueID,
+ ItemCount numOfData,
+ const DCMFieldTag dataTag[],
+ AEDesc * dataList) ;
+extern OSStatus
+DCMSetFieldData(
+ DCMDictionaryRef dictionaryRef,
+ DCMFieldTag keyFieldTag,
+ ByteCount keySize,
+ ConstLogicalAddress keyData,
+ DCMUniqueID uniqueID,
+ const AEDesc * dataList) ;
+extern OSStatus
+DCMAddRecord(
+ DCMDictionaryRef dictionaryRef,
+ DCMFieldTag keyFieldTag,
+ ByteCount keySize,
+ ConstLogicalAddress keyData,
+ Boolean checkOnly,
+ const AEDesc * dataList,
+ DCMUniqueID * newUniqueID) ;
+extern OSStatus
+DCMDeleteRecord(
+ DCMDictionaryRef dictionaryRef,
+ DCMFieldTag keyFieldTag,
+ ByteCount keySize,
+ ConstLogicalAddress keyData,
+ DCMUniqueID uniqueID) ;
+extern OSStatus
+DCMReorganizeDictionary(
+ DCMDictionaryID dictionaryID,
+ ItemCount extraCapacity,
+ DCMProgressFilterUPP progressProc,
+ UInt32 userData) ;
+extern OSStatus
+DCMCompactDictionary(
+ DCMDictionaryID dictionaryID,
+ DCMProgressFilterUPP progressProc,
+ UInt32 userData) ;
+extern OSStatus
+DCMGetFileFromDictionaryID(
+ DCMDictionaryID dictionaryID,
+ FSSpec * fileRef) ;
+extern OSStatus
+DCMGetDictionaryIDFromFile(
+ const FSSpec * fileRef,
+ DCMDictionaryID * dictionaryID) ;
+extern DCMDictionaryID
+DCMGetDictionaryIDFromRef(DCMDictionaryRef dictionaryRef) ;
+extern OSStatus
+DCMGetDictionaryFieldInfo(
+ DCMDictionaryID dictionaryID,
+ DCMFieldTag fieldTag,
+ AEDesc * fieldInfoRecord) ;
+extern OSStatus
+DCMGetDictionaryProperty(
+ DCMDictionaryID dictionaryID,
+ DCMFieldTag propertyTag,
+ ByteCount maxPropertySize,
+ ByteCount * actualSize,
+ LogicalAddress propertyValue) ;
+extern OSStatus
+DCMSetDictionaryProperty(
+ DCMDictionaryID dictionaryID,
+ DCMFieldTag propertyTag,
+ ByteCount propertySize,
+ ConstLogicalAddress propertyValue) ;
+extern OSStatus
+DCMGetDictionaryPropertyList(
+ DCMDictionaryID dictionaryID,
+ ItemCount maxPropertyNum,
+ ItemCount * numProperties,
+ DCMFieldTag propertyTag[]) ;
+extern OSStatus
+DCMCreateDictionaryIterator(DCMDictionaryIterator * dictionaryIterator) ;
+extern OSStatus
+DCMCreateAccessMethodIterator(DCMAccessMethodIterator * accessMethodIterator) ;
+extern ItemCount
+DCMCountObjectIterator(DCMObjectIterator iterator) ;
+extern OSStatus
+DCMIterateObject(
+ DCMObjectIterator iterator,
+ DCMObjectID * objectID) ;
+extern OSStatus
+DCMResetObjectIterator(DCMObjectIterator iterator) ;
+extern OSStatus
+DCMDisposeObjectIterator(DCMObjectIterator iterator) ;
+extern OSStatus
+DCMGetAccessMethodIDFromName(
+ ConstStr63Param accessMethodName,
+ DCMAccessMethodID * accessMethodID) ;
+extern OSStatus
+DCMCreateFieldInfoRecord(
+ DescType fieldTag,
+ DescType fieldType,
+ ByteCount maxRecordSize,
+ DCMFieldAttributes fieldAttributes,
+ AEDesc * fieldDefaultData,
+ ItemCount numberOfFindMethods,
+ DCMFindMethod findMethods[],
+ AEDesc * fieldInfoRecord) ;
+extern OSStatus
+DCMGetFieldTagAndType(
+ const AEDesc * fieldInfoRecord,
+ DCMFieldTag * fieldTag,
+ DCMFieldType * fieldType) ;
+extern OSStatus
+DCMGetFieldMaxRecordSize(
+ const AEDesc * fieldInfoRecord,
+ ByteCount * maxRecordSize) ;
+extern OSStatus
+DCMGetFieldAttributes(
+ const AEDesc * fieldInfoRecord,
+ DCMFieldAttributes * attributes) ;
+extern OSStatus
+DCMGetFieldDefaultData(
+ const AEDesc * fieldInfoRecord,
+ DescType desiredType,
+ AEDesc * fieldDefaultData) ;
+extern OSStatus
+DCMGetFieldFindMethods(
+ const AEDesc * fieldInfoRecord,
+ ItemCount findMethodsArrayMaxSize,
+ DCMFindMethod findMethods[],
+ ItemCount * actualNumberOfFindMethods) ;
+ inline Boolean DCMDictionaryManagerAvailable() { return true; }
+enum {
+ kMaxYomiLengthInAppleJapaneseDictionary = 40,
+ kMaxKanjiLengthInAppleJapaneseDictionary = 64
+};
+
+
+
+
+enum {
+ kDCMJapaneseYomiTag = 'yomi',
+ kDCMJapaneseHyokiTag = 'hyok',
+ kDCMJapaneseHinshiTag = 'hins',
+ kDCMJapaneseWeightTag = 'hind',
+ kDCMJapanesePhoneticTag = 'hton',
+ kDCMJapaneseAccentTag = 'acnt',
+ kDCMJapaneseOnKunReadingTag = 'OnKn',
+ kDCMJapaneseFukugouInfoTag = 'fuku'
+};
+
+enum {
+ kDCMJapaneseYomiType = typeUnicodeText,
+ kDCMJapaneseHyokiType = typeUnicodeText,
+ kDCMJapaneseHinshiType = 'hins',
+ kDCMJapaneseWeightType = typeShortInteger,
+ kDCMJapanesePhoneticType = typeUnicodeText,
+ kDCMJapaneseAccentType = 'byte',
+ kDCMJapaneseOnKunReadingType = typeUnicodeText,
+ kDCMJapaneseFukugouInfoType = 'fuku'
+};
+
+enum {
+
+ kInsert = 0,
+ kReplace = 1,
+ kInsertOrReplace = 2
+};
+
+
+
+typedef short DictionaryDataInsertMode;
+enum {
+
+ kIsCaseSensitive = 0x10,
+ kIsNotDiacriticalSensitive = 0x20
+};
+
+enum {
+
+ kNoun = -1,
+ kVerb = -2,
+ kAdjective = -3,
+ kAdverb = -4
+};
+
+
+typedef SInt8 DictionaryEntryAttribute;
+
+struct DictionaryInformation {
+ FSSpec dictionaryFSSpec;
+ SInt32 numberOfRecords;
+ SInt32 currentGarbageSize;
+ ScriptCode script;
+ SInt16 maximumKeyLength;
+ SInt8 keyAttributes;
+};
+typedef struct DictionaryInformation DictionaryInformation;
+struct DictionaryAttributeTable {
+ UInt8 datSize;
+ DictionaryEntryAttribute datTable[1];
+};
+typedef struct DictionaryAttributeTable DictionaryAttributeTable;
+typedef DictionaryAttributeTable * DictionaryAttributeTablePtr;
+
+
+}
+extern "C" {
+
+
+
+typedef struct OpaqueLAEnvironmentRef* LAEnvironmentRef;
+typedef struct OpaqueLAContextRef* LAContextRef;
+typedef AEKeyword LAPropertyKey;
+typedef DescType LAPropertyType;
+
+
+
+struct LAMorphemeRec {
+ ByteCount sourceTextLength;
+ LogicalAddress sourceTextPtr;
+ ByteCount morphemeTextLength;
+ LogicalAddress morphemeTextPtr;
+ UInt32 partOfSpeech;
+};
+typedef struct LAMorphemeRec LAMorphemeRec;
+struct LAMorphemesArray {
+ ItemCount morphemesCount;
+ ByteCount processedTextLength;
+ ByteCount morphemesTextLength;
+ LAMorphemeRec morphemes[1];
+};
+typedef struct LAMorphemesArray LAMorphemesArray;
+typedef LAMorphemesArray * LAMorphemesArrayPtr;
+enum {
+ kLAMorphemesArrayVersion = 0
+};
+
+
+
+
+typedef AERecord LAMorphemeBundle;
+typedef AERecord LAMorphemePath;
+typedef AERecord LAMorpheme;
+typedef AERecord LAHomograph;
+enum {
+ keyAELAMorphemeBundle = 'lmfb',
+ keyAELAMorphemePath = 'lmfp',
+ keyAELAMorpheme = 'lmfn',
+ keyAELAHomograph = 'lmfh'
+};
+
+enum {
+ typeLAMorphemeBundle = typeAERecord,
+ typeLAMorphemePath = typeAERecord,
+ typeLAMorpheme = typeAEList,
+ typeLAHomograph = typeAEList
+};
+
+
+
+
+enum {
+ keyAEMorphemePartOfSpeechCode = 'lamc',
+ keyAEMorphemeTextRange = 'lamt'
+};
+
+enum {
+ typeAEMorphemePartOfSpeechCode = 'lamc',
+ typeAEMorphemeTextRange = 'lamt'
+};
+
+typedef UInt32 MorphemePartOfSpeech;
+struct MorphemeTextRange {
+ UInt32 sourceOffset;
+ UInt32 length;
+};
+typedef struct MorphemeTextRange MorphemeTextRange;
+
+
+
+enum {
+ kLAEndOfSourceTextMask = 0x00000001
+};
+
+
+
+
+enum {
+ kLADefaultEdge = 0,
+ kLAFreeEdge = 1,
+ kLAIncompleteEdge = 2
+};
+
+
+
+
+enum {
+ kLAAllMorphemes = 0
+};
+extern UInt32
+LALibraryVersion(void) ;
+extern OSStatus
+LATextToMorphemes(
+ LAContextRef context,
+ TextEncoding preferedEncoding,
+ ByteCount textLength,
+ ConstLogicalAddress sourceText,
+ ByteCount bufferSize,
+ OptionBits convertFlags,
+ UInt32 structureVersion,
+ ByteCount * acceptedLength,
+ LAMorphemesArrayPtr resultBuffer) ;
+extern OSStatus
+LAOpenAnalysisContext(
+ LAEnvironmentRef environ,
+ LAContextRef * context) ;
+extern OSStatus
+LACloseAnalysisContext(LAContextRef context) ;
+extern OSStatus
+LAGetEnvironmentList(
+ UInt32 maxCount,
+ UInt32 * actualCount,
+ LAEnvironmentRef environmentList[]) ;
+extern OSStatus
+LAGetEnvironmentName(
+ LAEnvironmentRef environment,
+ Str63 environmentName) ;
+extern OSStatus
+LAGetEnvironmentRef(
+ ConstStr63Param targetEnvironmentName,
+ LAEnvironmentRef * environment) ;
+extern OSStatus
+LACreateCustomEnvironment(
+ LAEnvironmentRef baseEnvironment,
+ ConstStr63Param newEnvironmentName,
+ Boolean persistent,
+ LAEnvironmentRef * newEnvironment) ;
+extern OSStatus
+LADeleteCustomEnvironment(LAEnvironmentRef environment) ;
+extern OSStatus
+LAOpenDictionary(
+ LAEnvironmentRef environ,
+ const FSSpec * dictionary) ;
+extern OSStatus
+LACloseDictionary(
+ LAEnvironmentRef environ,
+ const FSSpec * dictionary) ;
+extern OSStatus
+LAListAvailableDictionaries(
+ LAEnvironmentRef environ,
+ ItemCount maxCount,
+ ItemCount * actualCount,
+ FSSpec dictionaryList[],
+ Boolean opened[]) ;
+extern OSStatus
+LAAddNewWord(
+ LAEnvironmentRef environ,
+ const FSSpec * dictionary,
+ const AEDesc * dataList) ;
+extern OSStatus
+LAMorphemeAnalysis(
+ LAContextRef context,
+ ConstUniCharArrayPtr text,
+ UniCharCount textLength,
+ LAMorphemePath * leadingPath,
+ LAMorphemePath * trailingPath,
+ ItemCount pathCount,
+ LAMorphemeBundle * result) ;
+extern OSStatus
+LAContinuousMorphemeAnalysis(
+ LAContextRef context,
+ ConstUniCharArrayPtr text,
+ UniCharCount textLength,
+ Boolean incrementalText,
+ LAMorphemePath * leadingPath,
+ LAMorphemePath * trailingPath,
+ Boolean * modified) ;
+extern OSStatus
+LAGetMorphemes(
+ LAContextRef context,
+ LAMorphemePath * result) ;
+extern OSStatus
+LAShiftMorphemes(
+ LAContextRef context,
+ ItemCount morphemeCount,
+ LAMorphemePath * path,
+ UniCharCount * shiftedLength) ;
+extern OSStatus
+LAResetAnalysis(LAContextRef context) ;
+ inline Boolean LALanguageAnalysisAvailable() { return true; }
+enum {
+ kAppleJapaneseDictionarySignature = 'jlan'
+};
+
+
+
+
+enum {
+ kMaxInputLengthOfAppleJapaneseEngine = 200
+};
+
+
+
+
+
+typedef MorphemePartOfSpeech JapanesePartOfSpeech;
+typedef UInt16 HomographWeight;
+typedef UInt8 HomographAccent;
+
+
+
+enum {
+ keyAEHomographDicInfo = 'lahd',
+ keyAEHomographWeight = 'lahw',
+ keyAEHomographAccent = 'laha'
+};
+
+enum {
+ typeAEHomographDicInfo = 'lahd',
+ typeAEHomographWeight = typeShortInteger,
+ typeAEHomographAccent = 'laha'
+};
+
+
+
+
+struct HomographDicInfoRec {
+ DCMDictionaryID dictionaryID;
+ DCMUniqueID uniqueID;
+};
+typedef struct HomographDicInfoRec HomographDicInfoRec;
+enum {
+ kLASpeechRoughClassMask = 0x0000F000,
+ kLASpeechMediumClassMask = 0x0000FF00,
+ kLASpeechStrictClassMask = 0x0000FFF0,
+ kLASpeechKatsuyouMask = 0x0000000F
+};
+
+
+
+
+
+enum {
+ kLASpeechMeishi = 0x00000000,
+ kLASpeechFutsuuMeishi = 0x00000000,
+ kLASpeechJinmei = 0x00000100,
+ kLASpeechJinmeiSei = 0x00000110,
+ kLASpeechJinmeiMei = 0x00000120,
+ kLASpeechChimei = 0x00000200,
+ kLASpeechSetsubiChimei = 0x00000210,
+ kLASpeechSoshikimei = 0x00000300,
+ kLASpeechKoyuuMeishi = 0x00000400,
+ kLASpeechSahenMeishi = 0x00000500,
+ kLASpeechKeidouMeishi = 0x00000600,
+ kLASpeechRentaishi = 0x00001000,
+ kLASpeechFukushi = 0x00002000,
+ kLASpeechSetsuzokushi = 0x00003000,
+ kLASpeechKandoushi = 0x00004000,
+ kLASpeechDoushi = 0x00005000,
+ kLASpeechGodanDoushi = 0x00005000,
+ kLASpeechKagyouGodan = 0x00005000,
+ kLASpeechSagyouGodan = 0x00005010,
+ kLASpeechTagyouGodan = 0x00005020,
+ kLASpeechNagyouGodan = 0x00005030,
+ kLASpeechMagyouGodan = 0x00005040,
+ kLASpeechRagyouGodan = 0x00005050,
+ kLASpeechWagyouGodan = 0x00005060,
+ kLASpeechGagyouGodan = 0x00005070,
+ kLASpeechBagyouGodan = 0x00005080,
+ kLASpeechIchidanDoushi = 0x00005100,
+ kLASpeechKahenDoushi = 0x00005200,
+ kLASpeechSahenDoushi = 0x00005300,
+ kLASpeechZahenDoushi = 0x00005400,
+ kLASpeechKeiyoushi = 0x00006000,
+ kLASpeechKeiyoudoushi = 0x00007000,
+ kLASpeechSettougo = 0x00008000,
+ kLASpeechSuujiSettougo = 0x00008100,
+ kLASpeechSetsubigo = 0x00009000,
+ kLASpeechJinmeiSetsubigo = 0x00009100,
+ kLASpeechChimeiSetsubigo = 0x00009200,
+ kLASpeechSoshikimeiSetsubigo = 0x00009300,
+ kLASpeechSuujiSetsubigo = 0x00009400,
+ kLASpeechMuhinshi = 0x0000A000,
+ kLASpeechTankanji = 0x0000A000,
+ kLASpeechKigou = 0x0000A100,
+ kLASpeechKuten = 0x0000A110,
+ kLASpeechTouten = 0x0000A120,
+ kLASpeechSuushi = 0x0000A200,
+ kLASpeechDokuritsugo = 0x0000A300,
+ kLASpeechSeiku = 0x0000A400,
+ kLASpeechJodoushi = 0x0000B000,
+ kLASpeechJoshi = 0x0000C000
+};
+
+
+
+
+
+enum {
+ kLASpeechKatsuyouGokan = 0x00000001,
+ kLASpeechKatsuyouMizen = 0x00000002,
+ kLASpeechKatsuyouRenyou = 0x00000003,
+ kLASpeechKatsuyouSyuushi = 0x00000004,
+ kLASpeechKatsuyouRentai = 0x00000005,
+ kLASpeechKatsuyouKatei = 0x00000006,
+ kLASpeechKatsuyouMeirei = 0x00000007
+};
+
+
+
+
+
+}
+
+
+
+extern "C" {
+
+
+
+enum {
+ kTextToSpeechSynthType = 'ttsc',
+ kTextToSpeechVoiceType = 'ttvd',
+ kTextToSpeechVoiceFileType = 'ttvf',
+ kTextToSpeechVoiceBundleType = 'ttvb'
+};
+
+enum {
+ kNoEndingProsody = 1,
+ kNoSpeechInterrupt = 2,
+ kPreflightThenPause = 4
+};
+
+enum {
+ kImmediate = 0,
+ kEndOfWord = 1,
+ kEndOfSentence = 2
+};
+
+
+
+
+
+enum {
+ soStatus = 'stat',
+ soErrors = 'erro',
+ soInputMode = 'inpt',
+ soCharacterMode = 'char',
+ soNumberMode = 'nmbr',
+ soRate = 'rate',
+ soPitchBase = 'pbas',
+ soPitchMod = 'pmod',
+ soVolume = 'volm',
+ soSynthType = 'vers',
+ soRecentSync = 'sync',
+ soPhonemeSymbols = 'phsy',
+ soCurrentVoice = 'cvox',
+ soCommandDelimiter = 'dlim',
+ soReset = 'rset',
+ soCurrentA5 = 'myA5',
+ soRefCon = 'refc',
+ soTextDoneCallBack = 'tdcb',
+ soSpeechDoneCallBack = 'sdcb',
+ soSyncCallBack = 'sycb',
+ soErrorCallBack = 'ercb',
+ soPhonemeCallBack = 'phcb',
+ soWordCallBack = 'wdcb',
+ soSynthExtension = 'xtnd',
+ soSoundOutput = 'sndo'
+};
+
+
+
+
+
+enum {
+ modeText = 'TEXT',
+ modePhonemes = 'PHON',
+ modeNormal = 'NORM',
+ modeLiteral = 'LTRL'
+};
+
+
+enum {
+ soVoiceDescription = 'info',
+ soVoiceFile = 'fref'
+};
+
+
+
+
+
+
+struct SpeechChannelRecord {
+ long data[1];
+};
+typedef struct SpeechChannelRecord SpeechChannelRecord;
+typedef SpeechChannelRecord * SpeechChannel;
+
+struct VoiceSpec {
+ OSType creator;
+ OSType id;
+};
+typedef struct VoiceSpec VoiceSpec;
+typedef VoiceSpec * VoiceSpecPtr;
+
+enum {
+ kNeuter = 0,
+ kMale = 1,
+ kFemale = 2
+};
+
+
+
+
+struct VoiceDescription {
+ long length;
+ VoiceSpec voice;
+ long version;
+ Str63 name;
+ Str255 comment;
+ short gender;
+ short age;
+ short script;
+ short language;
+ short region;
+ long reserved[4];
+};
+typedef struct VoiceDescription VoiceDescription;
+
+
+struct VoiceFileInfo {
+ FSSpec fileSpec;
+ short resID;
+};
+typedef struct VoiceFileInfo VoiceFileInfo;
+struct SpeechStatusInfo {
+ Boolean outputBusy;
+ Boolean outputPaused;
+ long inputBytesLeft;
+ short phonemeCode;
+};
+typedef struct SpeechStatusInfo SpeechStatusInfo;
+
+
+struct SpeechErrorInfo {
+ short count;
+ OSErr oldest;
+ long oldPos;
+ OSErr newest;
+ long newPos;
+};
+typedef struct SpeechErrorInfo SpeechErrorInfo;
+
+
+struct SpeechVersionInfo {
+ OSType synthType;
+ OSType synthSubType;
+ OSType synthManufacturer;
+ long synthFlags;
+ NumVersion synthVersion;
+};
+typedef struct SpeechVersionInfo SpeechVersionInfo;
+
+
+struct PhonemeInfo {
+ short opcode;
+ Str15 phStr;
+ Str31 exampleStr;
+ short hiliteStart;
+ short hiliteEnd;
+};
+typedef struct PhonemeInfo PhonemeInfo;
+
+struct PhonemeDescriptor {
+ short phonemeCount;
+ PhonemeInfo thePhonemes[1];
+};
+typedef struct PhonemeDescriptor PhonemeDescriptor;
+struct SpeechXtndData {
+ OSType synthCreator;
+ Byte synthData[2];
+};
+typedef struct SpeechXtndData SpeechXtndData;
+
+struct DelimiterInfo {
+ Byte startDelimiter[2];
+ Byte endDelimiter[2];
+};
+typedef struct DelimiterInfo DelimiterInfo;
+
+typedef void ( * SpeechTextDoneProcPtr)(SpeechChannel chan, long refCon, const void **nextBuf, unsigned long *byteLen, long *controlFlags);
+typedef void ( * SpeechDoneProcPtr)(SpeechChannel chan, long refCon);
+typedef void ( * SpeechSyncProcPtr)(SpeechChannel chan, long refCon, OSType syncMessage);
+typedef void ( * SpeechErrorProcPtr)(SpeechChannel chan, long refCon, OSErr theError, long bytePos);
+typedef void ( * SpeechPhonemeProcPtr)(SpeechChannel chan, long refCon, short phonemeOpcode);
+typedef void ( * SpeechWordProcPtr)(SpeechChannel chan, long refCon, unsigned long wordPos, unsigned short wordLen);
+typedef SpeechTextDoneProcPtr SpeechTextDoneUPP;
+typedef SpeechDoneProcPtr SpeechDoneUPP;
+typedef SpeechSyncProcPtr SpeechSyncUPP;
+typedef SpeechErrorProcPtr SpeechErrorUPP;
+typedef SpeechPhonemeProcPtr SpeechPhonemeUPP;
+typedef SpeechWordProcPtr SpeechWordUPP;
+extern SpeechTextDoneUPP
+NewSpeechTextDoneUPP(SpeechTextDoneProcPtr userRoutine) ;
+extern SpeechDoneUPP
+NewSpeechDoneUPP(SpeechDoneProcPtr userRoutine) ;
+extern SpeechSyncUPP
+NewSpeechSyncUPP(SpeechSyncProcPtr userRoutine) ;
+extern SpeechErrorUPP
+NewSpeechErrorUPP(SpeechErrorProcPtr userRoutine) ;
+extern SpeechPhonemeUPP
+NewSpeechPhonemeUPP(SpeechPhonemeProcPtr userRoutine) ;
+extern SpeechWordUPP
+NewSpeechWordUPP(SpeechWordProcPtr userRoutine) ;
+extern void
+DisposeSpeechTextDoneUPP(SpeechTextDoneUPP userUPP) ;
+extern void
+DisposeSpeechDoneUPP(SpeechDoneUPP userUPP) ;
+extern void
+DisposeSpeechSyncUPP(SpeechSyncUPP userUPP) ;
+extern void
+DisposeSpeechErrorUPP(SpeechErrorUPP userUPP) ;
+extern void
+DisposeSpeechPhonemeUPP(SpeechPhonemeUPP userUPP) ;
+extern void
+DisposeSpeechWordUPP(SpeechWordUPP userUPP) ;
+extern void
+InvokeSpeechTextDoneUPP(
+ SpeechChannel chan,
+ long refCon,
+ const void ** nextBuf,
+ unsigned long * byteLen,
+ long * controlFlags,
+ SpeechTextDoneUPP userUPP) ;
+extern void
+InvokeSpeechDoneUPP(
+ SpeechChannel chan,
+ long refCon,
+ SpeechDoneUPP userUPP) ;
+extern void
+InvokeSpeechSyncUPP(
+ SpeechChannel chan,
+ long refCon,
+ OSType syncMessage,
+ SpeechSyncUPP userUPP) ;
+extern void
+InvokeSpeechErrorUPP(
+ SpeechChannel chan,
+ long refCon,
+ OSErr theError,
+ long bytePos,
+ SpeechErrorUPP userUPP) ;
+extern void
+InvokeSpeechPhonemeUPP(
+ SpeechChannel chan,
+ long refCon,
+ short phonemeOpcode,
+ SpeechPhonemeUPP userUPP) ;
+extern void
+InvokeSpeechWordUPP(
+ SpeechChannel chan,
+ long refCon,
+ unsigned long wordPos,
+ unsigned short wordLen,
+ SpeechWordUPP userUPP) ;
+extern NumVersion
+SpeechManagerVersion(void) ;
+extern OSErr
+MakeVoiceSpec(
+ OSType creator,
+ OSType id,
+ VoiceSpec * voice) ;
+extern OSErr
+CountVoices(short * numVoices) ;
+extern OSErr
+GetIndVoice(
+ short index,
+ VoiceSpec * voice) ;
+extern OSErr
+GetVoiceDescription(
+ const VoiceSpec * voice,
+ VoiceDescription * info,
+ long infoLength) ;
+extern OSErr
+GetVoiceInfo(
+ const VoiceSpec * voice,
+ OSType selector,
+ void * voiceInfo) ;
+extern OSErr
+NewSpeechChannel(
+ VoiceSpec * voice,
+ SpeechChannel * chan) ;
+extern OSErr
+DisposeSpeechChannel(SpeechChannel chan) ;
+extern OSErr
+SpeakString(ConstStr255Param textToBeSpoken) ;
+extern OSErr
+SpeakText(
+ SpeechChannel chan,
+ const void * textBuf,
+ unsigned long textBytes) ;
+extern OSErr
+SpeakBuffer(
+ SpeechChannel chan,
+ const void * textBuf,
+ unsigned long textBytes,
+ long controlFlags) ;
+extern OSErr
+StopSpeech(SpeechChannel chan) ;
+extern OSErr
+StopSpeechAt(
+ SpeechChannel chan,
+ long whereToStop) ;
+extern OSErr
+PauseSpeechAt(
+ SpeechChannel chan,
+ long whereToPause) ;
+extern OSErr
+ContinueSpeech(SpeechChannel chan) ;
+extern short
+SpeechBusy(void) ;
+extern short
+SpeechBusySystemWide(void) ;
+extern OSErr
+SetSpeechRate(
+ SpeechChannel chan,
+ Fixed rate) ;
+extern OSErr
+GetSpeechRate(
+ SpeechChannel chan,
+ Fixed * rate) ;
+extern OSErr
+SetSpeechPitch(
+ SpeechChannel chan,
+ Fixed pitch) ;
+extern OSErr
+GetSpeechPitch(
+ SpeechChannel chan,
+ Fixed * pitch) ;
+extern OSErr
+SetSpeechInfo(
+ SpeechChannel chan,
+ OSType selector,
+ const void * speechInfo) ;
+extern OSErr
+GetSpeechInfo(
+ SpeechChannel chan,
+ OSType selector,
+ void * speechInfo) ;
+extern OSErr
+TextToPhonemes(
+ SpeechChannel chan,
+ const void * textBuf,
+ unsigned long textBytes,
+ Handle phonemeBuf,
+ long * phonemeBytes) ;
+extern OSErr
+UseDictionary(
+ SpeechChannel chan,
+ Handle dictionary) ;
+
+
+
+
+
+
+
+}
+
+
+
+extern "C" {
+
+
+
+
+
+
+
+
+
+enum {
+ kLSUnknownErr = -10810,
+ kLSNotAnApplicationErr = -10811,
+ kLSNotInitializedErr = -10812,
+ kLSDataUnavailableErr = -10813,
+ kLSApplicationNotFoundErr = -10814,
+ kLSUnknownTypeErr = -10815,
+ kLSDataTooOldErr = -10816,
+ kLSDataErr = -10817,
+ kLSLaunchInProgressErr = -10818,
+ kLSNotRegisteredErr = -10819,
+ kLSAppDoesNotClaimTypeErr = -10820,
+ kLSAppDoesNotSupportSchemeWarning = -10821,
+ kLSServerCommunicationErr = -10822,
+ kLSCannotSetInfoErr = -10823
+};
+
+typedef OptionBits LSInitializeFlags;
+enum {
+ kLSInitializeDefaults = 0x00000001
+};
+
+enum {
+ kLSMinCatInfoBitmap = (kFSCatInfoNodeFlags | kFSCatInfoParentDirID | kFSCatInfoFinderInfo | kFSCatInfoFinderXInfo)
+};
+
+enum {
+ kLSInvalidExtensionIndex = (unsigned long)0xFFFFFFFF
+};
+
+typedef OptionBits LSRequestedInfo;
+enum {
+ kLSRequestExtension = 0x00000001,
+ kLSRequestTypeCreator = 0x00000002,
+ kLSRequestBasicFlagsOnly = 0x00000004,
+ kLSRequestAppTypeFlags = 0x00000008,
+ kLSRequestAllFlags = 0x00000010,
+ kLSRequestIconAndKind = 0x00000020,
+ kLSRequestExtensionFlagsOnly = 0x00000040,
+ kLSRequestAllInfo = (unsigned long)0xFFFFFFFF
+};
+
+typedef OptionBits LSItemInfoFlags;
+enum {
+ kLSItemInfoIsPlainFile = 0x00000001,
+ kLSItemInfoIsPackage = 0x00000002,
+ kLSItemInfoIsApplication = 0x00000004,
+ kLSItemInfoIsContainer = 0x00000008,
+ kLSItemInfoIsAliasFile = 0x00000010,
+ kLSItemInfoIsSymlink = 0x00000020,
+ kLSItemInfoIsInvisible = 0x00000040,
+ kLSItemInfoIsNativeApp = 0x00000080,
+ kLSItemInfoIsClassicApp = 0x00000100,
+ kLSItemInfoAppPrefersNative = 0x00000200,
+ kLSItemInfoAppPrefersClassic = 0x00000400,
+ kLSItemInfoAppIsScriptable = 0x00000800,
+ kLSItemInfoIsVolume = 0x00001000,
+ kLSItemInfoExtensionIsHidden = 0x00100000
+};
+
+typedef OptionBits LSRolesMask;
+enum {
+ kLSRolesNone = 0x00000001,
+ kLSRolesViewer = 0x00000002,
+ kLSRolesEditor = 0x00000004,
+ kLSRolesAll = (unsigned long)0xFFFFFFFF
+};
+
+typedef UInt32 LSKindID;
+enum {
+ kLSUnknownKindID = 0
+};
+
+enum {
+ kLSUnknownType = 0,
+ kLSUnknownCreator = 0
+};
+
+struct LSItemInfoRecord {
+ LSItemInfoFlags flags;
+ OSType filetype;
+ OSType creator;
+ CFStringRef extension;
+ CFStringRef iconFileName;
+ LSKindID kindID;
+};
+typedef struct LSItemInfoRecord LSItemInfoRecord;
+
+typedef OptionBits LSAcceptanceFlags;
+enum {
+ kLSAcceptDefault = 0x00000001,
+ kLSAcceptAllowLoginUI = 0x00000002
+};
+
+typedef OptionBits LSLaunchFlags;
+enum {
+ kLSLaunchDefaults = 0x00000001,
+ kLSLaunchAndPrint = 0x00000002,
+ kLSLaunchReserved2 = 0x00000004,
+ kLSLaunchReserved3 = 0x00000008,
+ kLSLaunchReserved4 = 0x00000010,
+ kLSLaunchReserved5 = 0x00000020,
+ kLSLaunchReserved6 = 0x00000040,
+ kLSLaunchInhibitBGOnly = 0x00000080,
+ kLSLaunchDontAddToRecents = 0x00000100,
+ kLSLaunchDontSwitch = 0x00000200,
+ kLSLaunchNoParams = 0x00000800,
+ kLSLaunchAsync = 0x00010000,
+ kLSLaunchStartClassic = 0x00020000,
+ kLSLaunchInClassic = 0x00040000,
+ kLSLaunchNewInstance = 0x00080000,
+ kLSLaunchAndHide = 0x00100000,
+ kLSLaunchAndHideOthers = 0x00200000
+};
+
+struct LSLaunchFSRefSpec {
+ const FSRef * appRef;
+ UInt32 numDocs;
+ const FSRef * itemRefs;
+ const AEDesc * passThruParams;
+ LSLaunchFlags launchFlags;
+ void * asyncRefCon;
+};
+typedef struct LSLaunchFSRefSpec LSLaunchFSRefSpec;
+struct LSLaunchURLSpec {
+ CFURLRef appURL;
+ CFArrayRef itemURLs;
+ const AEDesc * passThruParams;
+ LSLaunchFlags launchFlags;
+ void * asyncRefCon;
+};
+typedef struct LSLaunchURLSpec LSLaunchURLSpec;
+extern OSStatus
+LSInit(LSInitializeFlags inFlags) ;
+extern OSStatus
+LSTerm(void) ;
+extern OSStatus
+LSCopyItemInfoForRef(
+ const FSRef * inItemRef,
+ LSRequestedInfo inWhichInfo,
+ LSItemInfoRecord * outItemInfo) ;
+extern OSStatus
+LSCopyItemInfoForURL(
+ CFURLRef inURL,
+ LSRequestedInfo inWhichInfo,
+ LSItemInfoRecord * outItemInfo) ;
+extern OSStatus
+LSGetExtensionInfo(
+ UniCharCount inNameLen,
+ const UniChar inNameBuffer[],
+ UniCharCount * outExtStartIndex) ;
+extern OSStatus
+LSCopyDisplayNameForRef(
+ const FSRef * inRef,
+ CFStringRef * outDisplayName) ;
+extern OSStatus
+LSCopyDisplayNameForURL(
+ CFURLRef inURL,
+ CFStringRef * outDisplayName) ;
+extern OSStatus
+LSSetExtensionHiddenForRef(
+ const FSRef * inRef,
+ Boolean inHide) ;
+extern OSStatus
+LSSetExtensionHiddenForURL(
+ CFURLRef inURL,
+ Boolean inHide) ;
+extern OSStatus
+LSCopyKindStringForRef(
+ const FSRef * inFSRef,
+ CFStringRef * outKindString) ;
+extern OSStatus
+LSCopyKindStringForURL(
+ CFURLRef inURL,
+ CFStringRef * outKindString) ;
+extern OSStatus
+LSCopyKindStringForTypeInfo(
+ OSType inType,
+ OSType inCreator,
+ CFStringRef inExtension,
+ CFStringRef * outKindString) ;
+extern OSStatus
+LSCopyKindStringForMIMEType(
+ CFStringRef inMIMEType,
+ CFStringRef * outKindString) ;
+extern OSStatus
+LSGetApplicationForItem(
+ const FSRef * inItemRef,
+ LSRolesMask inRoleMask,
+ FSRef * outAppRef,
+ CFURLRef * outAppURL) ;
+extern OSStatus
+LSGetApplicationForInfo(
+ OSType inType,
+ OSType inCreator,
+ CFStringRef inExtension,
+ LSRolesMask inRoleMask,
+ FSRef * outAppRef,
+ CFURLRef * outAppURL) ;
+extern OSStatus
+LSCopyApplicationForMIMEType(
+ CFStringRef inMIMEType,
+ LSRolesMask inRoleMask,
+ CFURLRef * outAppURL) ;
+extern OSStatus
+LSGetApplicationForURL(
+ CFURLRef inURL,
+ LSRolesMask inRoleMask,
+ FSRef * outAppRef,
+ CFURLRef * outAppURL) ;
+extern OSStatus
+LSFindApplicationForInfo(
+ OSType inCreator,
+ CFStringRef inBundleID,
+ CFStringRef inName,
+ FSRef * outAppRef,
+ CFURLRef * outAppURL) ;
+extern OSStatus
+LSCanRefAcceptItem(
+ const FSRef * inItemFSRef,
+ const FSRef * inTargetRef,
+ LSRolesMask inRoleMask,
+ LSAcceptanceFlags inFlags,
+ Boolean * outAcceptsItem) ;
+extern OSStatus
+LSCanURLAcceptURL(
+ CFURLRef inItemURL,
+ CFURLRef inTargetURL,
+ LSRolesMask inRoleMask,
+ LSAcceptanceFlags inFlags,
+ Boolean * outAcceptsItem) ;
+extern OSStatus
+LSOpenFSRef(
+ const FSRef * inRef,
+ FSRef * outLaunchedRef) ;
+extern OSStatus
+LSOpenCFURLRef(
+ CFURLRef inURL,
+ CFURLRef * outLaunchedURL) ;
+extern OSStatus
+LSOpenFromRefSpec(
+ const LSLaunchFSRefSpec * inLaunchSpec,
+ FSRef * outLaunchedRef) ;
+extern OSStatus
+LSOpenFromURLSpec(
+ const LSLaunchURLSpec * inLaunchSpec,
+ CFURLRef * outLaunchedURL) ;
+
+
+
+
+
+
+}
+
+
+
+
+
+
+extern double acos (double);
+extern double asin (double);
+extern double atan (double);
+extern double atan2 (double, double);
+extern double ceil (double);
+extern double cos (double);
+extern double cosh (double);
+extern double exp (double);
+extern double fabs (double);
+extern double floor (double);
+extern double fmod (double, double);
+extern double frexp (double, int *);
+extern double ldexp (double, int);
+extern double log10 (double);
+extern double log (double);
+extern double modf (double, double *);
+extern double pow (double, double);
+extern double sin (double);
+extern double sinh (double);
+extern double sqrt (double);
+extern double tan (double);
+extern double tanh (double);
+
+
+
+
+
+extern "C" {
+
+
+
+
+
+
+typedef struct OpaqueEventRef* EventRef;
+enum {
+
+
+
+
+
+ eventAlreadyPostedErr = -9860,
+
+
+
+
+
+ eventTargetBusyErr = -9861,
+
+
+
+
+ eventClassInvalidErr = -9862,
+
+
+
+
+ eventClassIncorrectErr = -9864,
+
+
+
+
+
+
+ eventHandlerAlreadyInstalledErr = -9866,
+
+
+
+
+ eventInternalErr = -9868,
+
+
+
+
+ eventKindIncorrectErr = -9869,
+
+
+
+
+ eventParameterNotFoundErr = -9870,
+ eventNotHandledErr = -9874,
+
+
+
+
+
+ eventLoopTimedOutErr = -9875,
+
+
+
+
+
+ eventLoopQuitErr = -9876,
+
+
+
+
+
+ eventNotInQueueErr = -9877,
+ eventHotKeyExistsErr = -9878,
+ eventHotKeyInvalidErr = -9879
+};
+typedef SInt16 EventPriority;
+enum {
+
+
+
+
+
+ kEventPriorityLow = 0,
+
+
+
+
+ kEventPriorityStandard = 1,
+
+
+
+
+ kEventPriorityHigh = 2
+};
+
+enum {
+ kEventLeaveInQueue = false,
+ kEventRemoveFromQueue = true
+};
+
+
+
+
+
+
+typedef double EventTime;
+typedef EventTime EventTimeout;
+typedef EventTime EventTimerInterval;
+ inline EventTime TicksToEventTime( UInt32 t ) { return ( (t) / 60.0 ); }
+ inline UInt32 EventTimeToTicks( EventTime t ) { return (UInt32)( ((t) * 60) + 0.5 ); }
+struct EventTypeSpec {
+ UInt32 eventClass;
+ UInt32 eventKind;
+};
+typedef struct EventTypeSpec EventTypeSpec;
+
+
+
+typedef OSType EventParamName;
+typedef OSType EventParamType;
+typedef struct OpaqueEventLoopRef* EventLoopRef;
+extern EventLoopRef
+GetCurrentEventLoop(void) ;
+extern EventLoopRef
+GetMainEventLoop(void) ;
+extern OSStatus
+RunCurrentEventLoop(EventTimeout inTimeout) ;
+extern OSStatus
+QuitEventLoop(EventLoopRef inEventLoop) ;
+extern CFTypeRef
+GetCFRunLoopFromEventLoop(EventLoopRef inEventLoop) ;
+extern OSStatus
+ReceiveNextEvent(
+ UInt32 inNumTypes,
+ const EventTypeSpec * inList,
+ EventTimeout inTimeout,
+ Boolean inPullEvent,
+ EventRef * outEvent) ;
+
+
+
+
+
+typedef UInt32 EventAttributes;
+enum {
+ kEventAttributeNone = 0,
+ kEventAttributeUserEvent = (1 << 0)
+};
+extern OSStatus
+CreateEvent(
+ CFAllocatorRef inAllocator,
+ UInt32 inClassID,
+ UInt32 kind,
+ EventTime when,
+ EventAttributes flags,
+ EventRef * outEvent) ;
+extern EventRef
+CopyEvent(EventRef inOther) ;
+extern EventRef
+RetainEvent(EventRef inEvent) ;
+extern UInt32
+GetEventRetainCount(EventRef inEvent) ;
+extern void
+ReleaseEvent(EventRef inEvent) ;
+extern OSStatus
+SetEventParameter(
+ EventRef inEvent,
+ EventParamName inName,
+ EventParamType inType,
+ UInt32 inSize,
+ const void * inDataPtr) ;
+extern OSStatus
+GetEventParameter(
+ EventRef inEvent,
+ EventParamName inName,
+ EventParamType inDesiredType,
+ EventParamType * outActualType,
+ UInt32 inBufferSize,
+ UInt32 * outActualSize,
+ void * outData) ;
+extern UInt32
+GetEventClass(EventRef inEvent) ;
+extern UInt32
+GetEventKind(EventRef inEvent) ;
+extern EventTime
+GetEventTime(EventRef inEvent) ;
+extern OSStatus
+SetEventTime(
+ EventRef inEvent,
+ EventTime inTime) ;
+
+
+
+
+
+
+typedef struct OpaqueEventQueueRef* EventQueueRef;
+extern EventQueueRef
+GetCurrentEventQueue(void) ;
+extern EventQueueRef
+GetMainEventQueue(void) ;
+typedef Boolean ( * EventComparatorProcPtr)(EventRef inEvent, void *inCompareData);
+typedef EventComparatorProcPtr EventComparatorUPP;
+extern EventComparatorUPP
+NewEventComparatorUPP(EventComparatorProcPtr userRoutine) ;
+extern void
+DisposeEventComparatorUPP(EventComparatorUPP userUPP) ;
+extern Boolean
+InvokeEventComparatorUPP(
+ EventRef inEvent,
+ void * inCompareData,
+ EventComparatorUPP userUPP) ;
+extern OSStatus
+PostEventToQueue(
+ EventQueueRef inQueue,
+ EventRef inEvent,
+ EventPriority inPriority) ;
+extern OSStatus
+FlushEventsMatchingListFromQueue(
+ EventQueueRef inQueue,
+ UInt32 inNumTypes,
+ const EventTypeSpec * inList) ;
+extern OSStatus
+FlushSpecificEventsFromQueue(
+ EventQueueRef inQueue,
+ EventComparatorUPP inComparator,
+ void * inCompareData) ;
+extern OSStatus
+FlushEventQueue(EventQueueRef inQueue) ;
+extern EventRef
+FindSpecificEventInQueue(
+ EventQueueRef inQueue,
+ EventComparatorUPP inComparator,
+ void * inCompareData) ;
+extern UInt32
+GetNumEventsInQueue(EventQueueRef inQueue) ;
+extern OSStatus
+RemoveEventFromQueue(
+ EventQueueRef inQueue,
+ EventRef inEvent) ;
+extern Boolean
+IsEventInQueue(
+ EventQueueRef inQueue,
+ EventRef inEvent) ;
+extern EventRef
+GetCurrentEvent(void) ;
+extern UInt32
+GetCurrentEventButtonState(void) ;
+extern UInt32
+GetCurrentEventKeyModifiers(void) ;
+extern UInt32
+GetCurrentButtonState(void) ;
+extern EventTime
+GetCurrentEventTime(void) ;
+typedef struct __EventLoopTimer* EventLoopTimerRef;
+typedef void ( * EventLoopTimerProcPtr)(EventLoopTimerRef inTimer, void *inUserData);
+
+
+
+
+
+enum {
+
+
+
+
+
+
+ kEventLoopIdleTimerStarted = 1,
+
+
+
+
+
+
+
+ kEventLoopIdleTimerIdling = 2,
+
+
+
+
+
+ kEventLoopIdleTimerStopped = 3
+};
+
+typedef UInt16 EventLoopIdleTimerMessage;
+typedef void ( * EventLoopIdleTimerProcPtr)(EventLoopTimerRef inTimer, EventLoopIdleTimerMessage inState, void *inUserData);
+typedef EventLoopTimerProcPtr EventLoopTimerUPP;
+typedef EventLoopIdleTimerProcPtr EventLoopIdleTimerUPP;
+extern EventLoopTimerUPP
+NewEventLoopTimerUPP(EventLoopTimerProcPtr userRoutine) ;
+extern EventLoopIdleTimerUPP
+NewEventLoopIdleTimerUPP(EventLoopIdleTimerProcPtr userRoutine) ;
+extern void
+DisposeEventLoopTimerUPP(EventLoopTimerUPP userUPP) ;
+extern void
+DisposeEventLoopIdleTimerUPP(EventLoopIdleTimerUPP userUPP) ;
+extern void
+InvokeEventLoopTimerUPP(
+ EventLoopTimerRef inTimer,
+ void * inUserData,
+ EventLoopTimerUPP userUPP) ;
+extern void
+InvokeEventLoopIdleTimerUPP(
+ EventLoopTimerRef inTimer,
+ EventLoopIdleTimerMessage inState,
+ void * inUserData,
+ EventLoopIdleTimerUPP userUPP) ;
+extern OSStatus
+InstallEventLoopTimer(
+ EventLoopRef inEventLoop,
+ EventTimerInterval inFireDelay,
+ EventTimerInterval inInterval,
+ EventLoopTimerUPP inTimerProc,
+ void * inTimerData,
+ EventLoopTimerRef * outTimer) ;
+extern OSStatus
+InstallEventLoopIdleTimer(
+ EventLoopRef inEventLoop,
+ EventTimerInterval inDelay,
+ EventTimerInterval inInterval,
+ EventLoopIdleTimerUPP inTimerProc,
+ void * inTimerData,
+ EventLoopTimerRef * outTimer) ;
+extern OSStatus
+InstallIdleTimer(
+ EventLoopRef inEventLoop,
+ EventTimerInterval inDelay,
+ EventTimerInterval inInterval,
+ EventLoopTimerUPP inTimerProc,
+ void * inTimerData,
+ EventLoopTimerRef * outTimer) ;
+extern OSStatus
+RemoveEventLoopTimer(EventLoopTimerRef inTimer) ;
+extern OSStatus
+SetEventLoopTimerNextFireTime(
+ EventLoopTimerRef inTimer,
+ EventTimerInterval inNextFire) ;
+typedef struct OpaqueEventHandlerRef* EventHandlerRef;
+typedef struct OpaqueEventHandlerCallRef* EventHandlerCallRef;
+typedef OSStatus ( * EventHandlerProcPtr)(EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void *inUserData);
+typedef EventHandlerProcPtr EventHandlerUPP;
+extern EventHandlerUPP
+NewEventHandlerUPP(EventHandlerProcPtr userRoutine) ;
+extern void
+DisposeEventHandlerUPP(EventHandlerUPP userUPP) ;
+extern OSStatus
+InvokeEventHandlerUPP(
+ EventHandlerCallRef inHandlerCallRef,
+ EventRef inEvent,
+ void * inUserData,
+ EventHandlerUPP userUPP) ;
+
+typedef struct OpaqueEventTargetRef* EventTargetRef;
+extern OSStatus
+InstallEventHandler(
+ EventTargetRef inTarget,
+ EventHandlerUPP inHandler,
+ UInt32 inNumTypes,
+ const EventTypeSpec * inList,
+ void * inUserData,
+ EventHandlerRef * outRef) ;
+extern OSStatus
+InstallStandardEventHandler(EventTargetRef inTarget) ;
+extern OSStatus
+RemoveEventHandler(EventHandlerRef inHandlerRef) ;
+extern OSStatus
+AddEventTypesToHandler(
+ EventHandlerRef inHandlerRef,
+ UInt32 inNumTypes,
+ const EventTypeSpec * inList) ;
+extern OSStatus
+RemoveEventTypesFromHandler(
+ EventHandlerRef inHandlerRef,
+ UInt32 inNumTypes,
+ const EventTypeSpec * inList) ;
+extern OSStatus
+CallNextEventHandler(
+ EventHandlerCallRef inCallRef,
+ EventRef inEvent) ;
+enum {
+
+
+
+
+
+
+
+ kEventTargetDontPropagate = (1 << 0),
+ kEventTargetSendToAllHandlers = (1 << 1)
+};
+extern OSStatus
+SendEventToEventTarget(
+ EventRef inEvent,
+ EventTargetRef inTarget) ;
+extern OSStatus
+SendEventToEventTargetWithOptions(
+ EventRef inEvent,
+ EventTargetRef inTarget,
+ OptionBits inOptions) ;
+
+
+
+
+
+
+}
+extern "C" {
+typedef struct OpaqueHIObjectClassRef* HIObjectClassRef;
+typedef struct OpaqueHIObjectRef* HIObjectRef;
+
+
+
+
+
+enum {
+
+
+
+
+ hiObjectClassExistsErr = -22080,
+
+
+
+
+
+ hiObjectClassHasInstancesErr = -22081,
+ hiObjectClassHasSubclassesErr = -22082,
+
+
+
+
+
+
+ hiObjectClassIsAbstractErr = -22083
+};
+enum {
+
+
+
+
+ kEventClassHIObject = 'hiob',
+ kEventHIObjectConstruct = 1,
+ kEventHIObjectInitialize = 2,
+
+
+
+
+
+
+
+ kEventHIObjectDestruct = 3,
+
+
+
+
+
+
+ kEventHIObjectIsEqual = 4,
+
+
+
+
+
+
+ kEventHIObjectPrintDebugInfo = 5
+};
+
+enum {
+ kEventParamHIObjectInstance = 'hioi',
+ typeHIObjectRef = 'hiob'
+};
+extern OSStatus
+HIObjectRegisterSubclass(
+ CFStringRef inClassID,
+ CFStringRef inBaseClassID,
+ OptionBits inOptions,
+ EventHandlerUPP inConstructProc,
+ UInt32 inNumEvents,
+ const EventTypeSpec * inEventList,
+ void * inConstructData,
+ HIObjectClassRef * outClassRef) ;
+extern OSStatus
+HIObjectUnregisterClass(HIObjectClassRef inClassRef) ;
+extern OSStatus
+HIObjectCreate(
+ CFStringRef inClassID,
+ EventRef inConstructData,
+ HIObjectRef * outObject) ;
+extern EventTargetRef
+HIObjectGetEventTarget(HIObjectRef inObject) ;
+extern void
+HIObjectPrintDebugInfo(HIObjectRef inObject) ;
+extern CFStringRef
+HIObjectCopyClassID(HIObjectRef inObject) ;
+extern Boolean
+HIObjectIsOfClass(
+ HIObjectRef inObject,
+ CFStringRef inObjectClassID) ;
+extern void *
+HIObjectDynamicCast(
+ HIObjectRef inObject,
+ CFStringRef inClassID) ;
+extern OSStatus
+HIObjectCreateFromBundle(
+ CFBundleRef inBundle,
+ HIObjectRef * outObject) ;
+extern Boolean
+HIObjectIsAccessibilityIgnored(HIObjectRef inObject) ;
+extern OSStatus
+HIObjectSetAccessibilityIgnored(
+ HIObjectRef inObject,
+ Boolean inIgnored) ;
+extern HIObjectRef
+_HIObjectRetain(HIObjectRef inObject) ;
+extern void
+_HIObjectRelease(HIObjectRef inObject) ;
+extern UInt32
+_HIObjectGetRetainCount(HIObjectRef inObject) ;
+extern Boolean
+_HIObjectIsEqual(
+ HIObjectRef inObject,
+ HIObjectRef inOtherObject) ;
+extern const CFArrayCallBacks kHIObjectCFArrayCallbacks;
+extern const CFDictionaryKeyCallBacks kHIObjectCFDictKeyCallbacks;
+extern const CFDictionaryValueCallBacks kHIObjectCFDictValueCallbacks;
+
+
+
+
+}
+
+
+
+extern "C" {
+
+
+
+typedef UInt16 EventKind;
+typedef UInt16 EventMask;
+enum {
+ nullEvent = 0,
+ mouseDown = 1,
+ mouseUp = 2,
+ keyDown = 3,
+ keyUp = 4,
+ autoKey = 5,
+ updateEvt = 6,
+ diskEvt = 7,
+ activateEvt = 8,
+ osEvt = 15,
+ kHighLevelEvent = 23
+};
+
+enum {
+ mDownMask = 1 << mouseDown,
+ mUpMask = 1 << mouseUp,
+ keyDownMask = 1 << keyDown,
+ keyUpMask = 1 << keyUp,
+ autoKeyMask = 1 << autoKey,
+ updateMask = 1 << updateEvt,
+ diskMask = 1 << diskEvt,
+ activMask = 1 << activateEvt,
+ highLevelEventMask = 0x0400,
+ osMask = 1 << osEvt,
+ everyEvent = 0xFFFF
+};
+
+enum {
+ charCodeMask = 0x000000FF,
+ keyCodeMask = 0x0000FF00,
+ adbAddrMask = 0x00FF0000,
+ osEvtMessageMask = (unsigned long)0xFF000000
+};
+
+enum {
+
+ mouseMovedMessage = 0x00FA,
+ suspendResumeMessage = 0x0001
+};
+
+enum {
+ resumeFlag = 1
+};
+typedef UInt16 EventModifiers;
+enum {
+
+ activeFlagBit = 0,
+ btnStateBit = 7,
+ cmdKeyBit = 8,
+ shiftKeyBit = 9,
+ alphaLockBit = 10,
+ optionKeyBit = 11,
+ controlKeyBit = 12,
+ rightShiftKeyBit = 13,
+ rightOptionKeyBit = 14,
+ rightControlKeyBit = 15
+};
+
+enum {
+ activeFlag = 1 << activeFlagBit,
+ btnState = 1 << btnStateBit,
+ cmdKey = 1 << cmdKeyBit,
+ shiftKey = 1 << shiftKeyBit,
+ alphaLock = 1 << alphaLockBit,
+ optionKey = 1 << optionKeyBit,
+ controlKey = 1 << controlKeyBit,
+ rightShiftKey = 1 << rightShiftKeyBit,
+ rightOptionKey = 1 << rightOptionKeyBit,
+ rightControlKey = 1 << rightControlKeyBit
+};
+
+
+enum {
+ kNullCharCode = 0,
+ kHomeCharCode = 1,
+ kEnterCharCode = 3,
+ kEndCharCode = 4,
+ kHelpCharCode = 5,
+ kBellCharCode = 7,
+ kBackspaceCharCode = 8,
+ kTabCharCode = 9,
+ kLineFeedCharCode = 10,
+ kVerticalTabCharCode = 11,
+ kPageUpCharCode = 11,
+ kFormFeedCharCode = 12,
+ kPageDownCharCode = 12,
+ kReturnCharCode = 13,
+ kFunctionKeyCharCode = 16,
+ kCommandCharCode = 17,
+ kCheckCharCode = 18,
+ kDiamondCharCode = 19,
+ kAppleLogoCharCode = 20,
+ kEscapeCharCode = 27,
+ kClearCharCode = 27,
+ kLeftArrowCharCode = 28,
+ kRightArrowCharCode = 29,
+ kUpArrowCharCode = 30,
+ kDownArrowCharCode = 31,
+ kSpaceCharCode = 32,
+ kDeleteCharCode = 127,
+ kBulletCharCode = 165,
+ kNonBreakingSpaceCharCode = 202
+};
+
+
+enum {
+ kShiftUnicode = 0x21E7,
+ kControlUnicode = 0x2303,
+ kOptionUnicode = 0x2325,
+ kCommandUnicode = 0x2318,
+ kPencilUnicode = 0x270E,
+ kCheckUnicode = 0x2713,
+ kDiamondUnicode = 0x25C6,
+ kBulletUnicode = 0x2022,
+ kAppleLogoUnicode = 0xF8FF
+};
+
+struct EventRecord {
+ EventKind what;
+ UInt32 message;
+ UInt32 when;
+ Point where;
+ EventModifiers modifiers;
+};
+typedef struct EventRecord EventRecord;
+typedef void ( * FKEYProcPtr)(void);
+typedef FKEYProcPtr FKEYUPP;
+extern void
+GetMouse(Point * mouseLoc) ;
+extern Boolean
+Button(void) ;
+extern Boolean
+StillDown(void) ;
+extern Boolean
+WaitMouseUp(void) ;
+extern UInt32
+KeyTranslate(
+ const void * transData,
+ UInt16 keycode,
+ UInt32 * state) ;
+extern UInt32
+GetCaretTime(void) ;
+typedef BigEndianLong KeyMap[4];
+
+
+typedef UInt8 KeyMapByteArray[16];
+extern void
+GetKeys(KeyMap theKeys) ;
+
+
+
+enum {
+ networkEvt = 10,
+ driverEvt = 11,
+ app1Evt = 12,
+ app2Evt = 13,
+ app3Evt = 14,
+ app4Evt = 15,
+ networkMask = 0x0400,
+ driverMask = 0x0800,
+ app1Mask = 0x1000,
+ app2Mask = 0x2000,
+ app3Mask = 0x4000,
+ app4Mask = 0x8000
+};
+
+struct EvQEl {
+ QElemPtr qLink;
+ SInt16 qType;
+ EventKind evtQWhat;
+ UInt32 evtQMessage;
+ UInt32 evtQWhen;
+ Point evtQWhere;
+ EventModifiers evtQModifiers;
+};
+typedef struct EvQEl EvQEl;
+typedef EvQEl * EvQElPtr;
+typedef void ( * GetNextEventFilterProcPtr)(EventRecord *theEvent, Boolean *result);
+typedef GetNextEventFilterProcPtr GetNextEventFilterUPP;
+typedef GetNextEventFilterUPP GNEFilterUPP;
+extern UInt32
+GetDblTime(void) ;
+extern void
+SetEventMask(EventMask value) ;
+extern Boolean
+GetNextEvent(
+ EventMask eventMask,
+ EventRecord * theEvent) ;
+extern Boolean
+WaitNextEvent(
+ EventMask eventMask,
+ EventRecord * theEvent,
+ UInt32 sleep,
+ RgnHandle mouseRgn) ;
+extern Boolean
+EventAvail(
+ EventMask eventMask,
+ EventRecord * theEvent) ;
+extern OSErr
+PostEvent(
+ EventKind eventNum,
+ UInt32 eventMsg) ;
+extern void
+FlushEvents(
+ EventMask whichMask,
+ EventMask stopMask) ;
+extern void
+GetGlobalMouse(Point * globalMouse) ;
+extern UInt32
+GetCurrentKeyModifiers(void) ;
+extern Boolean
+CheckEventQueueForUserCancel(void) ;
+extern void
+KeyScript(short code) ;
+extern Boolean
+IsCmdChar(
+ const EventRecord * event,
+ short test) ;
+extern SInt16
+LMGetKeyThresh(void) ;
+extern void
+LMSetKeyThresh(SInt16 value) ;
+extern SInt16
+LMGetKeyRepThresh(void) ;
+extern void
+LMSetKeyRepThresh(SInt16 value) ;
+extern UInt8
+LMGetKbdLast(void) ;
+extern void
+LMSetKbdLast(UInt8 value) ;
+extern UInt8
+LMGetKbdType(void) ;
+extern void
+LMSetKbdType(UInt8 value) ;
+
+
+
+
+
+}
+extern "C" {
+
+
+enum {
+ noMark = 0
+};
+enum {
+
+ kMenuDrawMsg = 0,
+ kMenuSizeMsg = 2,
+ kMenuPopUpMsg = 3,
+ kMenuCalcItemMsg = 5,
+ kMenuThemeSavvyMsg = 7,
+ mDrawMsg = 0,
+ mSizeMsg = 2,
+ mPopUpMsg = 3,
+ mCalcItemMsg = 5
+};
+enum {
+ kThemeSavvyMenuResponse = 0x7473
+};
+
+
+enum {
+ kMenuInitMsg = 8,
+ kMenuDisposeMsg = 9,
+ kMenuFindItemMsg = 10,
+ kMenuHiliteItemMsg = 11,
+ kMenuDrawItemsMsg = 12
+};
+
+enum {
+ textMenuProc = 0,
+ hMenuCmd = 27,
+ hierMenu = -1,
+ kInsertHierarchicalMenu = -1,
+ mctAllItems = -98,
+ mctLastIDIndic = -99
+};
+
+
+enum {
+ kMenuStdMenuProc = 63,
+ kMenuStdMenuBarProc = 63
+};
+
+
+enum {
+ kMenuNoModifiers = 0,
+ kMenuShiftModifier = (1 << 0),
+ kMenuOptionModifier = (1 << 1),
+ kMenuControlModifier = (1 << 2),
+ kMenuNoCommandModifier = (1 << 3)
+};
+
+
+enum {
+ kMenuNoIcon = 0,
+ kMenuIconType = 1,
+ kMenuShrinkIconType = 2,
+ kMenuSmallIconType = 3,
+ kMenuColorIconType = 4,
+ kMenuIconSuiteType = 5,
+ kMenuIconRefType = 6,
+ kMenuCGImageRefType = 7,
+ kMenuSystemIconSelectorType = 8,
+ kMenuIconResourceType = 9
+};
+
+
+enum {
+ kMenuNullGlyph = 0x00,
+ kMenuTabRightGlyph = 0x02,
+ kMenuTabLeftGlyph = 0x03,
+ kMenuEnterGlyph = 0x04,
+ kMenuShiftGlyph = 0x05,
+ kMenuControlGlyph = 0x06,
+ kMenuOptionGlyph = 0x07,
+ kMenuSpaceGlyph = 0x09,
+ kMenuDeleteRightGlyph = 0x0A,
+ kMenuReturnGlyph = 0x0B,
+ kMenuReturnR2LGlyph = 0x0C,
+ kMenuNonmarkingReturnGlyph = 0x0D,
+ kMenuPencilGlyph = 0x0F,
+ kMenuDownwardArrowDashedGlyph = 0x10,
+ kMenuCommandGlyph = 0x11,
+ kMenuCheckmarkGlyph = 0x12,
+ kMenuDiamondGlyph = 0x13,
+ kMenuAppleLogoFilledGlyph = 0x14,
+ kMenuParagraphKoreanGlyph = 0x15,
+ kMenuDeleteLeftGlyph = 0x17,
+ kMenuLeftArrowDashedGlyph = 0x18,
+ kMenuUpArrowDashedGlyph = 0x19,
+ kMenuRightArrowDashedGlyph = 0x1A,
+ kMenuEscapeGlyph = 0x1B,
+ kMenuClearGlyph = 0x1C,
+ kMenuLeftDoubleQuotesJapaneseGlyph = 0x1D,
+ kMenuRightDoubleQuotesJapaneseGlyph = 0x1E,
+ kMenuTrademarkJapaneseGlyph = 0x1F,
+ kMenuBlankGlyph = 0x61,
+ kMenuPageUpGlyph = 0x62,
+ kMenuCapsLockGlyph = 0x63,
+ kMenuLeftArrowGlyph = 0x64,
+ kMenuRightArrowGlyph = 0x65,
+ kMenuNorthwestArrowGlyph = 0x66,
+ kMenuHelpGlyph = 0x67,
+ kMenuUpArrowGlyph = 0x68,
+ kMenuSoutheastArrowGlyph = 0x69,
+ kMenuDownArrowGlyph = 0x6A,
+ kMenuPageDownGlyph = 0x6B,
+ kMenuAppleLogoOutlineGlyph = 0x6C,
+ kMenuContextualMenuGlyph = 0x6D,
+ kMenuPowerGlyph = 0x6E,
+ kMenuF1Glyph = 0x6F,
+ kMenuF2Glyph = 0x70,
+ kMenuF3Glyph = 0x71,
+ kMenuF4Glyph = 0x72,
+ kMenuF5Glyph = 0x73,
+ kMenuF6Glyph = 0x74,
+ kMenuF7Glyph = 0x75,
+ kMenuF8Glyph = 0x76,
+ kMenuF9Glyph = 0x77,
+ kMenuF10Glyph = 0x78,
+ kMenuF11Glyph = 0x79,
+ kMenuF12Glyph = 0x7A,
+ kMenuF13Glyph = 0x87,
+ kMenuF14Glyph = 0x88,
+ kMenuF15Glyph = 0x89,
+ kMenuControlISOGlyph = 0x8A,
+ kMenuEjectGlyph = 0x8C
+};
+typedef UInt32 MenuAttributes;
+enum {
+
+
+
+
+
+ kMenuAttrExcludesMarkColumn = (1 << 0),
+
+
+
+
+
+ kMenuAttrAutoDisable = (1 << 2),
+
+
+
+
+
+
+
+ kMenuAttrUsePencilGlyph = (1 << 3),
+ kMenuAttrHidden = (1 << 4)
+};
+typedef UInt32 MenuItemAttributes;
+enum {
+
+
+
+
+ kMenuItemAttrDisabled = (1 << 0),
+
+
+
+
+ kMenuItemAttrIconDisabled = (1 << 1),
+
+
+
+
+ kMenuItemAttrSubmenuParentChoosable = (1 << 2),
+
+
+
+
+ kMenuItemAttrDynamic = (1 << 3),
+
+
+
+
+
+ kMenuItemAttrNotPreviousAlternate = (1 << 4),
+
+
+
+
+
+
+ kMenuItemAttrHidden = (1 << 5),
+
+
+
+
+ kMenuItemAttrSeparator = (1 << 6),
+
+
+
+
+
+ kMenuItemAttrSectionHeader = (1 << 7),
+
+
+
+
+
+ kMenuItemAttrIgnoreMeta = (1 << 8),
+
+
+
+
+
+ kMenuItemAttrAutoRepeat = (1 << 9),
+
+
+
+
+
+
+ kMenuItemAttrUseVirtualKey = (1 << 10),
+
+
+
+
+
+
+
+ kMenuItemAttrCustomDraw = (1 << 11),
+ kMenuItemAttrIncludeInCmdKeyMatching = (1 << 12)
+};
+typedef UInt32 MenuTrackingMode;
+enum {
+
+
+
+
+ kMenuTrackingModeMouse = 1,
+
+
+
+
+ kMenuTrackingModeKeyboard = 2
+};
+typedef UInt32 MenuEventOptions;
+enum {
+
+
+
+
+ kMenuEventIncludeDisabledItems = 0x0001,
+
+
+
+
+ kMenuEventQueryOnly = 0x0002,
+
+
+
+
+ kMenuEventDontCheckSubmenus = 0x0004
+};
+
+
+
+
+typedef SInt16 MenuID;
+typedef UInt16 MenuItemIndex;
+typedef UInt32 MenuCommand;
+typedef struct OpaqueMenuRef* MenuRef;
+
+typedef MenuRef MenuHandle;
+typedef Handle MenuBarHandle;
+struct MenuBarHeader {
+
+
+
+
+
+ UInt16 lastMenu;
+
+
+
+
+
+ SInt16 lastRight;
+
+
+
+
+
+ SInt16 mbResID;
+};
+typedef struct MenuBarHeader MenuBarHeader;
+struct HMenuBarHeader {
+
+
+
+
+
+ UInt16 lastHMenu;
+
+
+
+
+
+ PixMapHandle menuTitleBits;
+};
+typedef struct HMenuBarHeader HMenuBarHeader;
+struct MenuBarMenu {
+
+
+
+
+ MenuRef menu;
+
+
+
+
+
+ SInt16 menuLeft;
+};
+typedef struct MenuBarMenu MenuBarMenu;
+struct HMenuBarMenu {
+
+
+
+
+ MenuRef menu;
+
+
+
+
+ SInt16 reserved;
+};
+typedef struct HMenuBarMenu HMenuBarMenu;
+struct MCEntry {
+ MenuID mctID;
+ short mctItem;
+ RGBColor mctRGB1;
+ RGBColor mctRGB2;
+ RGBColor mctRGB3;
+ RGBColor mctRGB4;
+ short mctReserved;
+};
+typedef struct MCEntry MCEntry;
+typedef MCEntry * MCEntryPtr;
+typedef MCEntry MCTable[1];
+typedef MCEntry * MCTablePtr;
+typedef MCTablePtr * MCTableHandle;
+struct MenuCRsrc {
+ short numEntries;
+ MCTable mcEntryRecs;
+};
+typedef struct MenuCRsrc MenuCRsrc;
+typedef MenuCRsrc * MenuCRsrcPtr;
+typedef MenuCRsrcPtr * MenuCRsrcHandle;
+struct MenuTrackingData {
+ MenuRef menu;
+ MenuItemIndex itemSelected;
+ MenuItemIndex itemUnderMouse;
+ Rect itemRect;
+ SInt32 virtualMenuTop;
+ SInt32 virtualMenuBottom;
+};
+typedef struct MenuTrackingData MenuTrackingData;
+typedef MenuTrackingData * MenuTrackingDataPtr;
+struct MDEFHiliteItemData {
+
+
+
+
+
+ MenuItemIndex previousItem;
+
+
+
+
+
+ MenuItemIndex newItem;
+
+
+
+
+
+ void * context;
+};
+typedef struct MDEFHiliteItemData MDEFHiliteItemData;
+typedef MDEFHiliteItemData * MDEFHiliteItemDataPtr;
+typedef MDEFHiliteItemData HiliteMenuItemData;
+typedef MDEFHiliteItemDataPtr HiliteMenuItemDataPtr;
+struct MDEFDrawData {
+
+
+
+
+
+
+ MenuTrackingData trackingData;
+
+
+
+
+
+ void * context;
+};
+typedef struct MDEFDrawData MDEFDrawData;
+typedef MDEFDrawData * MDEFDrawDataPtr;
+struct MDEFFindItemData {
+
+
+
+
+
+
+ MenuTrackingData trackingData;
+
+
+
+
+
+
+ void * context;
+};
+typedef struct MDEFFindItemData MDEFFindItemData;
+typedef MDEFFindItemData * MDEFFindItemDataPtr;
+struct MDEFDrawItemsData {
+
+
+
+
+ MenuItemIndex firstItem;
+
+
+
+
+ MenuItemIndex lastItem;
+
+
+
+
+
+
+ MenuTrackingData * trackingData;
+
+
+
+
+
+ void * context;
+};
+typedef struct MDEFDrawItemsData MDEFDrawItemsData;
+typedef MDEFDrawItemsData * MDEFDrawItemsDataPtr;
+enum {
+ kMenuItemDataText = (1 << 0),
+
+
+
+
+
+ kMenuItemDataMark = (1 << 1),
+
+
+
+
+
+ kMenuItemDataCmdKey = (1 << 2),
+
+
+
+
+
+ kMenuItemDataCmdKeyGlyph = (1 << 3),
+
+
+
+
+
+ kMenuItemDataCmdKeyModifiers = (1 << 4),
+
+
+
+
+
+ kMenuItemDataStyle = (1 << 5),
+
+
+
+
+
+
+ kMenuItemDataEnabled = (1 << 6),
+
+
+
+
+
+ kMenuItemDataIconEnabled = (1 << 7),
+
+
+
+
+
+ kMenuItemDataIconID = (1 << 8),
+ kMenuItemDataIconHandle = (1 << 9),
+
+
+
+
+
+ kMenuItemDataCommandID = (1 << 10),
+
+
+
+
+
+ kMenuItemDataTextEncoding = (1 << 11),
+ kMenuItemDataSubmenuID = (1 << 12),
+ kMenuItemDataSubmenuHandle = (1 << 13),
+ kMenuItemDataFontID = (1 << 14),
+ kMenuItemDataRefcon = (1 << 15),
+ kMenuItemDataAttributes = (1 << 16),
+ kMenuItemDataCFString = (1 << 17),
+ kMenuItemDataProperties = (1 << 18),
+
+
+
+
+
+ kMenuItemDataIndent = (1 << 19),
+
+
+
+
+
+
+
+ kMenuItemDataCmdVirtualKey = (1 << 20),
+ kMenuItemDataAllDataVersionOne = 0x000FFFFF,
+ kMenuItemDataAllDataVersionTwo = kMenuItemDataAllDataVersionOne | kMenuItemDataCmdVirtualKey
+};
+
+enum {
+ kMenuItemDataAllData = kMenuItemDataAllDataVersionTwo
+};
+
+typedef UInt64 MenuItemDataFlags;
+struct MenuItemDataRec {
+ MenuItemDataFlags whichData;
+ StringPtr text;
+ UniChar mark;
+ UniChar cmdKey;
+ UInt32 cmdKeyGlyph;
+ UInt32 cmdKeyModifiers;
+ Style style;
+ Boolean enabled;
+ Boolean iconEnabled;
+ UInt8 filler1;
+ SInt32 iconID;
+ UInt32 iconType;
+ Handle iconHandle;
+ MenuCommand cmdID;
+ TextEncoding encoding;
+ MenuID submenuID;
+ MenuRef submenuHandle;
+ SInt32 fontID;
+ UInt32 refcon;
+ OptionBits attr;
+ CFStringRef cfText;
+ Collection properties;
+ UInt32 indent;
+ UInt16 cmdVirtualKey;
+};
+typedef struct MenuItemDataRec MenuItemDataRec;
+typedef MenuItemDataRec * MenuItemDataPtr;
+typedef UInt32 MenuItemID;
+
+
+
+
+
+
+typedef void ( * MenuDefProcPtr)(short message, MenuRef theMenu, Rect *menuRect, Point hitPt, short *whichItem);
+typedef MenuDefProcPtr MenuDefUPP;
+extern MenuDefUPP
+NewMenuDefUPP(MenuDefProcPtr userRoutine) ;
+extern void
+DisposeMenuDefUPP(MenuDefUPP userUPP) ;
+extern void
+InvokeMenuDefUPP(
+ short message,
+ MenuRef theMenu,
+ Rect * menuRect,
+ Point hitPt,
+ short * whichItem,
+ MenuDefUPP userUPP) ;
+
+typedef long ( * MenuBarDefProcPtr)(short selector, short message, short parameter1, long parameter2);
+typedef void ( * MenuHookProcPtr)(void);
+typedef short ( * MBarHookProcPtr)(Rect * menuRect);
+typedef MenuBarDefProcPtr MenuBarDefUPP;
+typedef MenuHookProcPtr MenuHookUPP;
+typedef MBarHookProcPtr MBarHookUPP;
+enum {
+ kMenuDefProcPtr = 0
+};
+
+typedef UInt32 MenuDefType;
+enum {
+ kMenuDefObjectClass = 1
+};
+
+typedef struct OpaqueMenuLayoutRef* MenuLayoutRef;
+struct MenuDefSpec {
+ MenuDefType defType;
+ union {
+ MenuDefUPP defProc;
+ } u;
+};
+typedef struct MenuDefSpec MenuDefSpec;
+typedef MenuDefSpec * MenuDefSpecPtr;
+extern MenuRef
+NewMenu(
+ MenuID menuID,
+ ConstStr255Param menuTitle) ;
+extern MenuRef
+GetMenu(short resourceID) ;
+extern void
+DisposeMenu(MenuRef theMenu) ;
+extern void
+CalcMenuSize(MenuRef theMenu) ;
+extern UInt16
+CountMenuItems(MenuRef theMenu) ;
+extern OSStatus
+GetMenuFont(
+ MenuRef menu,
+ SInt16 * outFontID,
+ UInt16 * outFontSize) ;
+extern OSStatus
+SetMenuFont(
+ MenuRef menu,
+ SInt16 inFontID,
+ UInt16 inFontSize) ;
+extern Boolean
+GetMenuExcludesMarkColumn(MenuRef menu) ;
+extern OSStatus
+SetMenuExcludesMarkColumn(
+ MenuRef menu,
+ Boolean excludesMark) ;
+extern OSStatus
+RegisterMenuDefinition(
+ SInt16 inResID,
+ MenuDefSpecPtr inDefSpec) ;
+extern OSStatus
+CreateNewMenu(
+ MenuID inMenuID,
+ MenuAttributes inMenuAttributes,
+ MenuRef * outMenuRef) ;
+extern OSStatus
+CreateCustomMenu(
+ const MenuDefSpec * inDefSpec,
+ MenuID inMenuID,
+ MenuAttributes inMenuAttributes,
+ MenuRef * outMenuRef) ;
+extern Boolean
+IsValidMenu(MenuRef inMenu) ;
+extern ItemCount
+GetMenuRetainCount(MenuRef inMenu) ;
+extern OSStatus
+RetainMenu(MenuRef inMenu) ;
+extern OSStatus
+ReleaseMenu(MenuRef inMenu) ;
+extern OSStatus
+DuplicateMenu(
+ MenuRef inSourceMenu,
+ MenuRef * outMenu) ;
+extern OSStatus
+CopyMenuTitleAsCFString(
+ MenuRef inMenu,
+ CFStringRef * outString) ;
+extern OSStatus
+SetMenuTitleWithCFString(
+ MenuRef inMenu,
+ CFStringRef inString) ;
+extern OSStatus
+SetMenuTitleIcon(
+ MenuRef inMenu,
+ UInt32 inType,
+ void * inIcon) ;
+extern OSStatus
+GetMenuTitleIcon(
+ MenuRef inMenu,
+ UInt32 * outType,
+ void ** outIcon) ;
+extern OSStatus
+InvalidateMenuSize(MenuRef inMenu) ;
+extern Boolean
+IsMenuSizeInvalid(MenuRef inMenu) ;
+extern OSStatus
+EraseMenuBackground(
+ MenuRef inMenu,
+ const Rect * inEraseRect,
+ CGContextRef inContext) ;
+extern OSStatus
+ScrollMenuImage(
+ MenuRef inMenu,
+ const Rect * inScrollRect,
+ int inHScroll,
+ int inVScroll,
+ CGContextRef inContext) ;
+extern void
+AppendMenu(
+ MenuRef menu,
+ ConstStr255Param data) ;
+extern void
+InsertResMenu(
+ MenuRef theMenu,
+ ResType theType,
+ short afterItem) ;
+extern void
+AppendResMenu(
+ MenuRef theMenu,
+ ResType theType) ;
+extern void
+InsertMenuItem(
+ MenuRef theMenu,
+ ConstStr255Param itemString,
+ short afterItem) ;
+extern void
+DeleteMenuItem(
+ MenuRef theMenu,
+ short item) ;
+extern void
+InsertFontResMenu(
+ MenuRef theMenu,
+ short afterItem,
+ short scriptFilter) ;
+extern void
+InsertIntlResMenu(
+ MenuRef theMenu,
+ ResType theType,
+ short afterItem,
+ short scriptFilter) ;
+extern OSStatus
+AppendMenuItemText(
+ MenuRef menu,
+ ConstStr255Param inString) ;
+extern OSStatus
+InsertMenuItemText(
+ MenuRef menu,
+ ConstStr255Param inString,
+ MenuItemIndex afterItem) ;
+extern OSStatus
+CopyMenuItems(
+ MenuRef inSourceMenu,
+ MenuItemIndex inFirstItem,
+ ItemCount inNumItems,
+ MenuRef inDestMenu,
+ MenuItemIndex inInsertAfter) ;
+extern OSStatus
+DeleteMenuItems(
+ MenuRef inMenu,
+ MenuItemIndex inFirstItem,
+ ItemCount inNumItems) ;
+extern OSStatus
+AppendMenuItemTextWithCFString(
+ MenuRef inMenu,
+ CFStringRef inString,
+ MenuItemAttributes inAttributes,
+ MenuCommand inCommandID,
+ MenuItemIndex * outNewItem) ;
+extern OSStatus
+InsertMenuItemTextWithCFString(
+ MenuRef inMenu,
+ CFStringRef inString,
+ MenuItemIndex inAfterItem,
+ MenuItemAttributes inAttributes,
+ MenuCommand inCommandID) ;
+extern long
+MenuKey(CharParameter ch) ;
+extern long
+MenuSelect(Point startPt) ;
+extern long
+PopUpMenuSelect(
+ MenuRef menu,
+ short top,
+ short left,
+ short popUpItem) ;
+extern long
+MenuChoice(void) ;
+extern UInt32
+MenuEvent(const EventRecord * inEvent) ;
+extern Boolean
+IsMenuKeyEvent(
+ MenuRef inStartMenu,
+ EventRef inEvent,
+ MenuEventOptions inOptions,
+ MenuRef * outMenu,
+ MenuItemIndex * outMenuItem) ;
+extern OSStatus
+InvalidateMenuEnabling(MenuRef inMenu) ;
+extern short
+GetMBarHeight(void) ;
+extern void
+DrawMenuBar(void) ;
+extern void
+InvalMenuBar(void) ;
+extern Boolean
+IsMenuBarInvalid(MenuRef rootMenu) ;
+extern void
+HiliteMenu(MenuID menuID) ;
+extern MenuBarHandle
+GetNewMBar(short menuBarID) ;
+extern MenuBarHandle
+GetMenuBar(void) ;
+extern void
+SetMenuBar(MenuBarHandle mbar) ;
+extern OSStatus
+DuplicateMenuBar(
+ MenuBarHandle inMbar,
+ MenuBarHandle * outMbar) ;
+extern OSStatus
+DisposeMenuBar(MenuBarHandle inMbar) ;
+extern MenuRef
+GetMenuHandle(MenuID menuID) ;
+extern void
+InsertMenu(
+ MenuRef theMenu,
+ MenuID beforeID) ;
+extern void
+DeleteMenu(MenuID menuID) ;
+extern void
+ClearMenuBar(void) ;
+extern void
+SetMenuFlashCount(short count) ;
+extern void
+FlashMenuBar(MenuID menuID) ;
+extern Boolean
+IsMenuBarVisible(void) ;
+extern void
+ShowMenuBar(void) ;
+extern void
+HideMenuBar(void) ;
+extern MenuRef
+AcquireRootMenu(void) ;
+extern OSStatus
+SetRootMenu(MenuRef inMenu) ;
+extern void
+CheckMenuItem(
+ MenuRef theMenu,
+ short item,
+ Boolean checked) ;
+extern void
+SetMenuItemText(
+ MenuRef theMenu,
+ short item,
+ ConstStr255Param itemString) ;
+extern void
+GetMenuItemText(
+ MenuRef theMenu,
+ short item,
+ Str255 itemString) ;
+extern void
+SetItemMark(
+ MenuRef theMenu,
+ short item,
+ CharParameter markChar) ;
+extern void
+GetItemMark(
+ MenuRef theMenu,
+ short item,
+ CharParameter * markChar) ;
+extern void
+SetItemCmd(
+ MenuRef theMenu,
+ short item,
+ CharParameter cmdChar) ;
+extern void
+GetItemCmd(
+ MenuRef theMenu,
+ short item,
+ CharParameter * cmdChar) ;
+extern void
+SetItemIcon(
+ MenuRef theMenu,
+ short item,
+ short iconIndex) ;
+extern void
+GetItemIcon(
+ MenuRef theMenu,
+ short item,
+ short * iconIndex) ;
+extern void
+SetItemStyle(
+ MenuRef theMenu,
+ short item,
+ StyleParameter chStyle) ;
+extern void
+GetItemStyle(
+ MenuRef theMenu,
+ short item,
+ Style * chStyle) ;
+extern OSErr
+SetMenuItemCommandID(
+ MenuRef inMenu,
+ SInt16 inItem,
+ MenuCommand inCommandID) ;
+extern OSErr
+GetMenuItemCommandID(
+ MenuRef inMenu,
+ SInt16 inItem,
+ MenuCommand * outCommandID) ;
+extern OSErr
+SetMenuItemModifiers(
+ MenuRef inMenu,
+ SInt16 inItem,
+ UInt8 inModifiers) ;
+extern OSErr
+GetMenuItemModifiers(
+ MenuRef inMenu,
+ SInt16 inItem,
+ UInt8 * outModifiers) ;
+extern OSErr
+SetMenuItemIconHandle(
+ MenuRef inMenu,
+ SInt16 inItem,
+ UInt8 inIconType,
+ Handle inIconHandle) ;
+extern OSErr
+GetMenuItemIconHandle(
+ MenuRef inMenu,
+ SInt16 inItem,
+ UInt8 * outIconType,
+ Handle * outIconHandle) ;
+extern OSErr
+SetMenuItemTextEncoding(
+ MenuRef inMenu,
+ SInt16 inItem,
+ TextEncoding inScriptID) ;
+extern OSErr
+GetMenuItemTextEncoding(
+ MenuRef inMenu,
+ SInt16 inItem,
+ TextEncoding * outScriptID) ;
+extern OSErr
+SetMenuItemHierarchicalID(
+ MenuRef inMenu,
+ SInt16 inItem,
+ MenuID inHierID) ;
+extern OSErr
+GetMenuItemHierarchicalID(
+ MenuRef inMenu,
+ SInt16 inItem,
+ MenuID * outHierID) ;
+extern OSErr
+SetMenuItemFontID(
+ MenuRef inMenu,
+ SInt16 inItem,
+ SInt16 inFontID) ;
+extern OSErr
+GetMenuItemFontID(
+ MenuRef inMenu,
+ SInt16 inItem,
+ SInt16 * outFontID) ;
+extern OSErr
+SetMenuItemRefCon(
+ MenuRef inMenu,
+ SInt16 inItem,
+ UInt32 inRefCon) ;
+extern OSErr
+GetMenuItemRefCon(
+ MenuRef inMenu,
+ SInt16 inItem,
+ UInt32 * outRefCon) ;
+extern OSErr
+SetMenuItemKeyGlyph(
+ MenuRef inMenu,
+ SInt16 inItem,
+ SInt16 inGlyph) ;
+extern OSErr
+GetMenuItemKeyGlyph(
+ MenuRef inMenu,
+ SInt16 inItem,
+ SInt16 * outGlyph) ;
+extern void
+EnableMenuItem(
+ MenuRef theMenu,
+ MenuItemIndex item) ;
+extern void
+DisableMenuItem(
+ MenuRef theMenu,
+ MenuItemIndex item) ;
+extern Boolean
+IsMenuItemEnabled(
+ MenuRef menu,
+ MenuItemIndex item) ;
+extern void
+EnableMenuItemIcon(
+ MenuRef theMenu,
+ MenuItemIndex item) ;
+extern void
+DisableMenuItemIcon(
+ MenuRef theMenu,
+ MenuItemIndex item) ;
+extern Boolean
+IsMenuItemIconEnabled(
+ MenuRef menu,
+ MenuItemIndex item) ;
+extern OSStatus
+SetMenuItemHierarchicalMenu(
+ MenuRef inMenu,
+ MenuItemIndex inItem,
+ MenuRef inHierMenu) ;
+extern OSStatus
+GetMenuItemHierarchicalMenu(
+ MenuRef inMenu,
+ MenuItemIndex inItem,
+ MenuRef * outHierMenu) ;
+extern OSStatus
+CopyMenuItemTextAsCFString(
+ MenuRef inMenu,
+ MenuItemIndex inItem,
+ CFStringRef * outString) ;
+extern OSStatus
+SetMenuItemTextWithCFString(
+ MenuRef inMenu,
+ MenuItemIndex inItem,
+ CFStringRef inString) ;
+extern OSStatus
+GetMenuItemIndent(
+ MenuRef inMenu,
+ MenuItemIndex inItem,
+ UInt32 * outIndent) ;
+extern OSStatus
+SetMenuItemIndent(
+ MenuRef inMenu,
+ MenuItemIndex inItem,
+ UInt32 inIndent) ;
+extern OSStatus
+GetMenuItemCommandKey(
+ MenuRef inMenu,
+ MenuItemIndex inItem,
+ Boolean inGetVirtualKey,
+ UInt16 * outKey) ;
+extern OSStatus
+SetMenuItemCommandKey(
+ MenuRef inMenu,
+ MenuItemIndex inItem,
+ Boolean inSetVirtualKey,
+ UInt16 inKey) ;
+extern void
+DeleteMCEntries(
+ MenuID menuID,
+ short menuItem) ;
+extern MCTableHandle
+GetMCInfo(void) ;
+extern void
+SetMCInfo(MCTableHandle menuCTbl) ;
+extern void
+DisposeMCInfo(MCTableHandle menuCTbl) ;
+extern MCEntryPtr
+GetMCEntry(
+ MenuID menuID,
+ short menuItem) ;
+extern void
+SetMCEntries(
+ short numEntries,
+ MCTablePtr menuCEntries) ;
+enum {
+ kMenuPropertyPersistent = 0x00000001
+};
+extern OSStatus
+GetMenuItemProperty(
+ MenuRef menu,
+ MenuItemIndex item,
+ OSType propertyCreator,
+ OSType propertyTag,
+ UInt32 bufferSize,
+ UInt32 * actualSize,
+ void * propertyBuffer) ;
+extern OSStatus
+GetMenuItemPropertySize(
+ MenuRef menu,
+ MenuItemIndex item,
+ OSType propertyCreator,
+ OSType propertyTag,
+ UInt32 * size) ;
+extern OSStatus
+SetMenuItemProperty(
+ MenuRef menu,
+ MenuItemIndex item,
+ OSType propertyCreator,
+ OSType propertyTag,
+ UInt32 propertySize,
+ const void * propertyData) ;
+extern OSStatus
+RemoveMenuItemProperty(
+ MenuRef menu,
+ MenuItemIndex item,
+ OSType propertyCreator,
+ OSType propertyTag) ;
+extern OSStatus
+GetMenuItemPropertyAttributes(
+ MenuRef menu,
+ MenuItemIndex item,
+ OSType propertyCreator,
+ OSType propertyTag,
+ UInt32 * attributes) ;
+extern OSStatus
+ChangeMenuItemPropertyAttributes(
+ MenuRef menu,
+ MenuItemIndex item,
+ OSType propertyCreator,
+ OSType propertyTag,
+ UInt32 attributesToSet,
+ UInt32 attributesToClear) ;
+extern OSStatus
+GetMenuAttributes(
+ MenuRef menu,
+ MenuAttributes * outAttributes) ;
+extern OSStatus
+ChangeMenuAttributes(
+ MenuRef menu,
+ MenuAttributes setTheseAttributes,
+ MenuAttributes clearTheseAttributes) ;
+extern OSStatus
+GetMenuItemAttributes(
+ MenuRef menu,
+ MenuItemIndex item,
+ MenuItemAttributes * outAttributes) ;
+extern OSStatus
+ChangeMenuItemAttributes(
+ MenuRef menu,
+ MenuItemIndex item,
+ MenuItemAttributes setTheseAttributes,
+ MenuItemAttributes clearTheseAttributes) ;
+extern void
+DisableAllMenuItems(MenuRef theMenu) ;
+extern void
+EnableAllMenuItems(MenuRef theMenu) ;
+extern Boolean
+MenuHasEnabledItems(MenuRef theMenu) ;
+extern OSStatus
+GetMenuTrackingData(
+ MenuRef theMenu,
+ MenuTrackingData * outData) ;
+extern OSStatus
+GetMenuType(
+ MenuRef theMenu,
+ UInt16 * outType) ;
+extern ItemCount
+CountMenuItemsWithCommandID(
+ MenuRef inMenu,
+ MenuCommand inCommandID) ;
+extern OSStatus
+GetIndMenuItemWithCommandID(
+ MenuRef inMenu,
+ MenuCommand inCommandID,
+ UInt32 inItemIndex,
+ MenuRef * outMenu,
+ MenuItemIndex * outIndex) ;
+extern void
+EnableMenuCommand(
+ MenuRef inMenu,
+ MenuCommand inCommandID) ;
+extern void
+DisableMenuCommand(
+ MenuRef inMenu,
+ MenuCommand inCommandID) ;
+extern Boolean
+IsMenuCommandEnabled(
+ MenuRef inMenu,
+ MenuCommand inCommandID) ;
+extern OSStatus
+SetMenuCommandMark(
+ MenuRef inMenu,
+ MenuCommand inCommandID,
+ UniChar inMark) ;
+extern OSStatus
+GetMenuCommandMark(
+ MenuRef inMenu,
+ MenuCommand inCommandID,
+ UniChar * outMark) ;
+extern OSStatus
+GetMenuCommandProperty(
+ MenuRef inMenu,
+ MenuCommand inCommandID,
+ OSType inPropertyCreator,
+ OSType inPropertyTag,
+ ByteCount inBufferSize,
+ ByteCount * outActualSize,
+ void * inPropertyBuffer) ;
+extern OSStatus
+GetMenuCommandPropertySize(
+ MenuRef inMenu,
+ MenuCommand inCommandID,
+ OSType inPropertyCreator,
+ OSType inPropertyTag,
+ ByteCount * outSize) ;
+extern OSStatus
+SetMenuCommandProperty(
+ MenuRef inMenu,
+ MenuCommand inCommandID,
+ OSType inPropertyCreator,
+ OSType inPropertyTag,
+ ByteCount inPropertySize,
+ const void * inPropertyData) ;
+extern OSStatus
+RemoveMenuCommandProperty(
+ MenuRef inMenu,
+ MenuCommand inCommandID,
+ OSType inPropertyCreator,
+ OSType inPropertyTag) ;
+extern OSStatus
+CopyMenuItemData(
+ MenuRef inMenu,
+ MenuItemID inItem,
+ Boolean inIsCommandID,
+ MenuItemDataPtr ioData) ;
+extern OSStatus
+SetMenuItemData(
+ MenuRef inMenu,
+ MenuItemID inItem,
+ Boolean inIsCommandID,
+ const MenuItemDataRec * inData) ;
+extern Boolean
+IsMenuItemInvalid(
+ MenuRef inMenu,
+ MenuItemIndex inItem) ;
+extern OSStatus
+InvalidateMenuItems(
+ MenuRef inMenu,
+ MenuItemIndex inFirstItem,
+ ItemCount inNumItems) ;
+extern OSStatus
+UpdateInvalidMenuItems(MenuRef inMenu) ;
+enum {
+ kHierarchicalFontMenuOption = 0x00000001
+};
+extern OSStatus
+CreateStandardFontMenu(
+ MenuRef menu,
+ MenuItemIndex afterItem,
+ MenuID firstHierMenuID,
+ OptionBits options,
+ ItemCount * outHierMenuCount) ;
+extern OSStatus
+UpdateStandardFontMenu(
+ MenuRef menu,
+ ItemCount * outHierMenuCount) ;
+extern OSStatus
+GetFontFamilyFromMenuSelection(
+ MenuRef menu,
+ MenuItemIndex item,
+ FMFontFamily * outFontFamily,
+ FMFontStyle * outStyle) ;
+enum {
+ gestaltContextualMenuAttr = 'cmnu',
+ gestaltContextualMenuUnusedBit = 0,
+ gestaltContextualMenuTrapAvailable = 1,
+ gestaltContextualMenuHasAttributeAndModifierKeys = 2,
+ gestaltContextualMenuHasUnicodeSupport = 3
+};
+
+
+
+
+
+
+enum {
+
+
+
+
+
+
+ kCMHelpItemNoHelp = 0,
+
+
+
+
+
+
+ kCMHelpItemAppleGuide = 1,
+ kCMHelpItemOtherHelp = 2,
+ kCMHelpItemRemoveHelp = 3
+};
+
+
+
+
+
+
+enum {
+
+
+
+
+
+ kCMNothingSelected = 0,
+
+
+
+
+
+
+
+ kCMMenuItemSelected = 1,
+
+
+
+
+
+
+
+ kCMShowHelpSelected = 3
+};
+enum {
+ keyContextualMenuName = 'pnam',
+
+
+
+
+
+ keyContextualMenuCommandID = 'cmcd',
+
+
+
+
+
+
+ keyContextualMenuSubmenu = 'cmsb',
+
+
+
+
+
+
+ keyContextualMenuAttributes = 'cmat',
+ keyContextualMenuModifiers = 'cmmd'
+};
+extern OSStatus
+InitContextualMenus(void) ;
+extern Boolean
+IsShowContextualMenuClick(const EventRecord * inEvent) ;
+extern Boolean
+IsShowContextualMenuEvent(EventRef inEvent) ;
+extern OSStatus
+ContextualMenuSelect(
+ MenuRef inMenu,
+ Point inGlobalLocation,
+ Boolean inReserved,
+ UInt32 inHelpType,
+ ConstStr255Param inHelpItemString,
+ const AEDesc * inSelection,
+ UInt32 * outUserSelectionType,
+ SInt16 * outMenuID,
+ MenuItemIndex * outMenuItem) ;
+extern Boolean
+ProcessIsContextualMenuClient(ProcessSerialNumber * inPSN) ;
+struct ContextualMenuInterfaceStruct
+{
+ void *_reserved; SInt32 (*QueryInterface)(void *thisPointer, CFUUIDBytes iid, void ** ppv); UInt32 (*AddRef)(void *thisPointer); UInt32 (*Release)(void *thisPointer);
+ OSStatus ( *ExamineContext )(
+ void* thisInstance,
+ const AEDesc* inContext,
+ AEDescList* outCommandPairs );
+ OSStatus ( *HandleSelection )(
+ void* thisInstance,
+ AEDesc* inContext,
+ SInt32 inCommandID );
+ void ( *PostMenuCleanup )(
+ void* thisInstance );
+};
+typedef struct ContextualMenuInterfaceStruct ContextualMenuInterfaceStruct;
+
+
+
+
+
+
+
+extern OSStatus
+CMPluginExamineContext(
+ void * thisInstance,
+ const AEDesc * inContext,
+ AEDescList * outCommandPairs);
+extern OSStatus
+CMPluginHandleSelection(
+ void * thisInstance,
+ AEDesc * inContext,
+ SInt32 inCommandID);
+extern void
+CMPluginPostMenuCleanup(void * thisInstance);
+extern SInt16
+LMGetTheMenu(void) ;
+extern MenuID
+GetMenuID(MenuRef menu) ;
+extern SInt16
+GetMenuWidth(MenuRef menu) ;
+extern SInt16
+GetMenuHeight(MenuRef menu) ;
+extern StringPtr
+GetMenuTitle(
+ MenuRef menu,
+ Str255 title) ;
+extern OSStatus
+GetMenuDefinition(
+ MenuRef menu,
+ MenuDefSpecPtr outDefSpec) ;
+extern void
+SetMenuID(
+ MenuRef menu,
+ MenuID menuID) ;
+extern void
+SetMenuWidth(
+ MenuRef menu,
+ SInt16 width) ;
+extern void
+SetMenuHeight(
+ MenuRef menu,
+ SInt16 height) ;
+extern OSStatus
+SetMenuTitle(
+ MenuRef menu,
+ ConstStr255Param title) ;
+extern OSStatus
+SetMenuDefinition(
+ MenuRef menu,
+ const MenuDefSpec * defSpec) ;
+
+
+}
+extern "C" {
+
+
+typedef HIObjectRef HIToolbarRef;
+typedef HIObjectRef HIToolbarItemRef;
+enum {
+
+
+
+
+
+
+ kHIToolbarDisplayModeDefault = 0,
+
+
+
+
+
+ kHIToolbarDisplayModeIconAndLabel = 1,
+
+
+
+
+ kHIToolbarDisplayModeIconOnly = 2,
+
+
+
+
+ kHIToolbarDisplayModeLabelOnly = 3
+};
+
+typedef UInt32 HIToolbarDisplayMode;
+
+
+
+
+
+enum {
+
+
+
+
+
+ kHIToolbarDisplaySizeDefault = 0,
+
+
+
+
+ kHIToolbarDisplaySizeNormal = 1,
+
+
+
+
+ kHIToolbarDisplaySizeSmall = 2
+};
+
+typedef UInt32 HIToolbarDisplaySize;
+
+
+
+
+
+enum {
+
+
+
+
+ kHIToolbarNoAttributes = 0,
+ kHIToolbarAutoSavesConfig = (1 << 0),
+
+
+
+
+
+
+ kHIToolbarIsConfigurable = (1 << 1),
+ kHIToolbarValidAttrs = kHIToolbarAutoSavesConfig | kHIToolbarIsConfigurable
+};
+
+
+
+
+
+
+
+enum {
+
+
+
+
+
+
+
+ kHICommandCustomizeToolbar = 'tcfg',
+
+
+
+
+
+
+ kHICommandShowToolbar = 'tbsh',
+
+
+
+
+
+
+ kHICommandHideToolbar = 'tbhd'
+};
+enum {
+
+
+
+
+
+
+ kEventToolbarGetDefaultIdentifiers = 1,
+
+
+
+
+
+
+
+ kEventToolbarGetAllowedIdentifiers = 2,
+
+
+
+
+
+ kEventToolbarCreateItemWithIdentifier = 3,
+
+
+
+
+
+
+
+ kEventToolbarCreateItemFromDrag = 4
+};
+
+
+
+
+
+
+enum {
+
+
+
+
+
+
+ kEventToolbarItemImageChanged = 1,
+
+
+
+
+
+
+ kEventToolbarItemLabelChanged = 2,
+
+
+
+
+
+
+ kEventToolbarItemHelpTextChanged = 3,
+
+
+
+
+
+
+ kEventToolbarItemCommandIDChanged = 4,
+ kEventToolbarItemGetPersistentData = 5,
+
+
+
+
+
+
+
+ kEventToolbarItemCreateCustomView = 6,
+
+
+
+
+
+
+ kEventToolbarItemEnabledStateChanged = 7,
+
+
+
+
+
+
+
+ kEventToolbarItemPerformAction = 8
+};
+
+
+
+
+
+
+enum {
+ kHIToolbarItemNoAttributes = 0,
+ kHIToolbarItemAllowDuplicates = (1 << 0),
+ kHIToolbarItemCantBeRemoved = (1 << 1),
+ kHIToolbarItemAnchoredLeft = (1 << 2),
+ kHIToolbarItemIsSeparator = (1 << 3),
+
+
+
+
+
+
+ kHIToolbarItemSendCmdToUserFocus = (1 << 4),
+ kHIToolbarItemValidAttrs = kHIToolbarItemAllowDuplicates | kHIToolbarItemIsSeparator | kHIToolbarItemCantBeRemoved | kHIToolbarItemAnchoredLeft | kHIToolbarItemSendCmdToUserFocus,
+ kHIToolbarItemMutableAttrs = kHIToolbarItemCantBeRemoved | kHIToolbarItemAnchoredLeft
+};
+extern OSStatus
+HIToolbarCreate(
+ CFStringRef inIdentifier,
+ OptionBits inAttributes,
+ HIToolbarRef * outToolbar) ;
+extern OSStatus
+HIToolbarGetAttributes(
+ HIToolbarRef inToolbar,
+ OptionBits * outAttributes) ;
+extern OSStatus
+HIToolbarChangeAttributes(
+ HIToolbarRef inToolbar,
+ OptionBits inAttrsToSet,
+ OptionBits inAttrsToClear) ;
+extern OSStatus
+HIToolbarGetDisplayMode(
+ HIToolbarRef inToolbar,
+ HIToolbarDisplayMode * outDisplayMode) ;
+extern OSStatus
+HIToolbarSetDisplayMode(
+ HIToolbarRef inToolbar,
+ HIToolbarDisplayMode inDisplayMode) ;
+extern OSStatus
+HIToolbarGetDisplaySize(
+ HIToolbarRef inToolbar,
+ HIToolbarDisplaySize * outSize) ;
+extern OSStatus
+HIToolbarSetDisplaySize(
+ HIToolbarRef inToolbar,
+ HIToolbarDisplaySize inSize) ;
+extern OSStatus
+HIToolbarCopyIdentifier(
+ HIToolbarRef inToolbar,
+ CFStringRef * outIdentifier) ;
+extern OSStatus
+HIToolbarCopyItems(
+ HIToolbarRef inToolbar,
+ CFArrayRef * outItems) ;
+extern OSStatus
+HIToolbarCreateItemWithIdentifier(
+ HIToolbarRef inToolbar,
+ CFStringRef inIdentifier,
+ CFTypeRef inConfigData,
+ HIToolbarItemRef * outItem) ;
+extern OSStatus
+HIToolbarInsertItemAtIndex(
+ HIToolbarRef inToolbar,
+ HIToolbarItemRef inItem,
+ CFIndex inIndex) ;
+extern OSStatus
+HIToolbarAppendItem(
+ HIToolbarRef inToolbar,
+ HIToolbarItemRef inItem) ;
+extern OSStatus
+HIToolbarRemoveItemAtIndex(
+ HIToolbarRef inToolbar,
+ CFIndex inIndex) ;
+extern OSStatus
+HIToolbarSetDelegate(
+ HIToolbarRef inToolbar,
+ HIObjectRef inDelegate) ;
+extern HIObjectRef
+HIToolbarGetDelegate(HIToolbarRef inToolbar) ;
+extern OSStatus
+HIToolbarItemCreate(
+ CFStringRef inIdentifier,
+ OptionBits inOptions,
+ HIToolbarItemRef * outItem) ;
+extern OSStatus
+HIToolbarItemCopyIdentifier(
+ HIToolbarItemRef inItem,
+ CFStringRef * outIdentifier) ;
+extern OSStatus
+HIToolbarItemGetAttributes(
+ HIToolbarItemRef inItem,
+ OptionBits * outAttributes) ;
+extern OSStatus
+HIToolbarItemChangeAttributes(
+ HIToolbarItemRef inItem,
+ OptionBits inAttrsToSet,
+ OptionBits inAttrsToClear) ;
+extern OSStatus
+HIToolbarItemSetLabel(
+ HIToolbarItemRef inItem,
+ CFStringRef inLabel) ;
+extern OSStatus
+HIToolbarItemCopyLabel(
+ HIToolbarItemRef inItem,
+ CFStringRef * outLabel) ;
+extern OSStatus
+HIToolbarItemSetHelpText(
+ HIToolbarItemRef inItem,
+ CFStringRef inShortText,
+ CFStringRef inLongText) ;
+extern OSStatus
+HIToolbarItemCopyHelpText(
+ HIToolbarItemRef inItem,
+ CFStringRef * outShortText,
+ CFStringRef * outLongText) ;
+extern OSStatus
+HIToolbarItemSetCommandID(
+ HIToolbarItemRef inItem,
+ MenuCommand inCommandID) ;
+extern OSStatus
+HIToolbarItemGetCommandID(
+ HIToolbarItemRef inItem,
+ MenuCommand * outCommandID) ;
+extern OSStatus
+HIToolbarItemSetIconRef(
+ HIToolbarItemRef inItem,
+ IconRef inIcon) ;
+extern OSStatus
+HIToolbarItemSetImage(
+ HIToolbarItemRef inItem,
+ CGImageRef inImage) ;
+extern OSStatus
+HIToolbarItemCopyImage(
+ HIToolbarItemRef inItem,
+ CGImageRef * outImage) ;
+extern OSStatus
+HIToolbarItemSetMenu(
+ HIToolbarItemRef inItem,
+ MenuRef inMenu) ;
+extern OSStatus
+HIToolbarItemCopyMenu(
+ HIToolbarItemRef inItem,
+ MenuRef * outMenu) ;
+extern HIToolbarRef
+HIToolbarItemGetToolbar(HIToolbarItemRef inItem) ;
+extern Boolean
+HIToolbarItemIsEnabled(HIToolbarItemRef inItem) ;
+extern OSStatus
+HIToolbarItemSetEnabled(
+ HIToolbarItemRef inItem,
+ Boolean inEnabled) ;
+
+
+
+
+}
+
+
+
+extern "C" {
+
+
+
+typedef struct TERec TERec;
+typedef TERec * TEPtr;
+typedef TEPtr * TEHandle;
+typedef void ( * HighHookProcPtr)(const Rect *r, TEPtr pTE);
+typedef Boolean ( * EOLHookProcPtr)(char theChar, TEPtr pTE, TEHandle hTE);
+typedef void ( * CaretHookProcPtr)(const Rect *r, TEPtr pTE);
+typedef unsigned short ( * WidthHookProcPtr)(unsigned short textLen, unsigned short textOffset, void *textBufferPtr, TEPtr pTE, TEHandle hTE);
+typedef unsigned short ( * TextWidthHookProcPtr)(unsigned short textLen, unsigned short textOffset, void *textBufferPtr, TEPtr pTE, TEHandle hTE);
+typedef unsigned short ( * NWidthHookProcPtr)(unsigned short styleRunLen, unsigned short styleRunOffset, short slop, short direction, void *textBufferPtr, short *lineStart, TEPtr pTE, TEHandle hTE);
+typedef void ( * DrawHookProcPtr)(unsigned short textOffset, unsigned short drawLen, void *textBufferPtr, TEPtr pTE, TEHandle hTE);
+typedef Boolean ( * HitTestHookProcPtr)(unsigned short styleRunLen, unsigned short styleRunOffset, unsigned short slop, void *textBufferPtr, TEPtr pTE, TEHandle hTE, unsigned short *pixelWidth, unsigned short *charOffset, Boolean *pixelInChar);
+typedef void ( * TEFindWordProcPtr)(unsigned short currentPos, short caller, TEPtr pTE, TEHandle hTE, unsigned short *wordStart, unsigned short *wordEnd);
+typedef void ( * TERecalcProcPtr)(TEPtr pTE, unsigned short changeLength, unsigned short *lineStart, unsigned short *firstChar, unsigned short *lastChar);
+typedef void ( * TEDoTextProcPtr)(TEPtr pTE, unsigned short firstChar, unsigned short lastChar, short selector, GrafPtr *currentGrafPort, short *charPosition);
+typedef Boolean ( * TEClickLoopProcPtr)(TEPtr pTE);
+typedef Boolean ( * WordBreakProcPtr)(Ptr text, short charPos);
+typedef HighHookProcPtr HighHookUPP;
+typedef EOLHookProcPtr EOLHookUPP;
+typedef CaretHookProcPtr CaretHookUPP;
+typedef WidthHookProcPtr WidthHookUPP;
+typedef TextWidthHookProcPtr TextWidthHookUPP;
+typedef NWidthHookProcPtr NWidthHookUPP;
+typedef DrawHookProcPtr DrawHookUPP;
+typedef HitTestHookProcPtr HitTestHookUPP;
+typedef TEFindWordProcPtr TEFindWordUPP;
+typedef TERecalcProcPtr TERecalcUPP;
+typedef TEDoTextProcPtr TEDoTextUPP;
+typedef TEClickLoopProcPtr TEClickLoopUPP;
+typedef WordBreakProcPtr WordBreakUPP;
+struct TERec {
+ Rect destRect;
+ Rect viewRect;
+ Rect selRect;
+ short lineHeight;
+ short fontAscent;
+ Point selPoint;
+ short selStart;
+ short selEnd;
+ short active;
+ WordBreakUPP wordBreak;
+ TEClickLoopUPP clickLoop;
+ long clickTime;
+ short clickLoc;
+ long caretTime;
+ short caretState;
+ short just;
+ short teLength;
+ Handle hText;
+ long hDispatchRec;
+ short clikStuff;
+ short crOnly;
+ short txFont;
+ StyleField txFace;
+ short txMode;
+ short txSize;
+ GrafPtr inPort;
+ HighHookUPP highHook;
+ CaretHookUPP caretHook;
+ short nLines;
+ short lineStarts[16001];
+};
+
+enum {
+
+ teJustLeft = 0,
+ teJustCenter = 1,
+ teJustRight = -1,
+ teForceLeft = -2,
+ teFlushDefault = 0,
+ teCenter = 1,
+ teFlushRight = -1,
+ teFlushLeft = -2
+};
+
+enum {
+
+ fontBit = 0,
+ faceBit = 1,
+ sizeBit = 2,
+ clrBit = 3,
+ addSizeBit = 4,
+ toggleBit = 5
+};
+
+enum {
+
+ doFont = 1,
+ doFace = 2,
+ doSize = 4,
+ doColor = 8,
+ doAll = 15,
+ addSize = 16,
+ doToggle = 32
+};
+
+enum {
+
+ EOLHook = 0,
+ DRAWHook = 4,
+ WIDTHHook = 8,
+ HITTESTHook = 12,
+ nWIDTHHook = 24,
+ TextWidthHook = 28
+};
+
+enum {
+
+ intEOLHook = 0,
+ intDrawHook = 1,
+ intWidthHook = 2,
+ intHitTestHook = 3,
+ intNWidthHook = 6,
+ intTextWidthHook = 7,
+ intInlineInputTSMTEPreUpdateHook = 8,
+ intInlineInputTSMTEPostUpdateHook = 9
+};
+
+enum {
+
+ teFAutoScroll = 0,
+ teFTextBuffering = 1,
+ teFOutlineHilite = 2,
+ teFInlineInput = 3,
+ teFUseWhiteBackground = 4,
+ teFUseInlineInput = 5,
+ teFInlineInputAutoScroll = 6
+};
+
+enum {
+
+
+
+
+
+
+ teFIdleWithEventLoopTimer = 7
+};
+
+enum {
+
+ teBitClear = 0,
+ teBitSet = 1,
+ teBitTest = -1
+};
+
+enum {
+
+ teWordSelect = 4,
+ teWordDrag = 8,
+ teFromFind = 12,
+ teFromRecal = 16
+};
+
+enum {
+
+ teFind = 0,
+ teHighlight = 1,
+ teDraw = -1,
+ teCaret = -2
+};
+
+
+typedef char Chars[32001];
+typedef char * CharsPtr;
+typedef CharsPtr * CharsHandle;
+struct StyleRun {
+ short startChar;
+ short styleIndex;
+};
+typedef struct StyleRun StyleRun;
+struct STElement {
+ short stCount;
+ short stHeight;
+ short stAscent;
+ short stFont;
+ StyleField stFace;
+ short stSize;
+ RGBColor stColor;
+};
+typedef struct STElement STElement;
+typedef STElement TEStyleTable[1777];
+typedef STElement * STPtr;
+typedef STPtr * STHandle;
+struct LHElement {
+ short lhHeight;
+ short lhAscent;
+};
+typedef struct LHElement LHElement;
+typedef LHElement LHTable[8001];
+typedef LHElement * LHPtr;
+typedef LHPtr * LHHandle;
+struct ScrpSTElement {
+ long scrpStartChar;
+ short scrpHeight;
+ short scrpAscent;
+ short scrpFont;
+ StyleField scrpFace;
+ short scrpSize;
+ RGBColor scrpColor;
+};
+typedef struct ScrpSTElement ScrpSTElement;
+
+typedef ScrpSTElement ScrpSTTable[1601];
+struct StScrpRec {
+ short scrpNStyles;
+ ScrpSTTable scrpStyleTab;
+};
+typedef struct StScrpRec StScrpRec;
+typedef StScrpRec * StScrpPtr;
+typedef StScrpPtr * StScrpHandle;
+struct NullStRec {
+ long teReserved;
+ StScrpHandle nullScrap;
+};
+typedef struct NullStRec NullStRec;
+typedef NullStRec * NullStPtr;
+typedef NullStPtr * NullStHandle;
+struct TEStyleRec {
+ short nRuns;
+ short nStyles;
+ STHandle styleTab;
+ LHHandle lhTab;
+ long teRefCon;
+ NullStHandle nullStyle;
+ StyleRun runs[8001];
+};
+typedef struct TEStyleRec TEStyleRec;
+typedef TEStyleRec * TEStylePtr;
+typedef TEStylePtr * TEStyleHandle;
+struct TextStyle {
+ short tsFont;
+ StyleField tsFace;
+ short tsSize;
+ RGBColor tsColor;
+};
+typedef struct TextStyle TextStyle;
+typedef TextStyle * TextStylePtr;
+typedef TextStylePtr * TextStyleHandle;
+typedef short TEIntHook;
+extern HighHookUPP
+NewHighHookUPP(HighHookProcPtr userRoutine) ;
+extern EOLHookUPP
+NewEOLHookUPP(EOLHookProcPtr userRoutine) ;
+extern CaretHookUPP
+NewCaretHookUPP(CaretHookProcPtr userRoutine) ;
+extern WidthHookUPP
+NewWidthHookUPP(WidthHookProcPtr userRoutine) ;
+extern TextWidthHookUPP
+NewTextWidthHookUPP(TextWidthHookProcPtr userRoutine) ;
+extern NWidthHookUPP
+NewNWidthHookUPP(NWidthHookProcPtr userRoutine) ;
+extern DrawHookUPP
+NewDrawHookUPP(DrawHookProcPtr userRoutine) ;
+extern HitTestHookUPP
+NewHitTestHookUPP(HitTestHookProcPtr userRoutine) ;
+extern TEFindWordUPP
+NewTEFindWordUPP(TEFindWordProcPtr userRoutine) ;
+extern TERecalcUPP
+NewTERecalcUPP(TERecalcProcPtr userRoutine) ;
+extern TEDoTextUPP
+NewTEDoTextUPP(TEDoTextProcPtr userRoutine) ;
+extern TEClickLoopUPP
+NewTEClickLoopUPP(TEClickLoopProcPtr userRoutine) ;
+extern void
+DisposeHighHookUPP(HighHookUPP userUPP) ;
+extern void
+DisposeEOLHookUPP(EOLHookUPP userUPP) ;
+extern void
+DisposeCaretHookUPP(CaretHookUPP userUPP) ;
+extern void
+DisposeWidthHookUPP(WidthHookUPP userUPP) ;
+extern void
+DisposeTextWidthHookUPP(TextWidthHookUPP userUPP) ;
+extern void
+DisposeNWidthHookUPP(NWidthHookUPP userUPP) ;
+extern void
+DisposeDrawHookUPP(DrawHookUPP userUPP) ;
+extern void
+DisposeHitTestHookUPP(HitTestHookUPP userUPP) ;
+extern void
+DisposeTEFindWordUPP(TEFindWordUPP userUPP) ;
+extern void
+DisposeTERecalcUPP(TERecalcUPP userUPP) ;
+extern void
+DisposeTEDoTextUPP(TEDoTextUPP userUPP) ;
+extern void
+DisposeTEClickLoopUPP(TEClickLoopUPP userUPP) ;
+extern void
+InvokeHighHookUPP(
+ const Rect * r,
+ TEPtr pTE,
+ HighHookUPP userUPP) ;
+extern Boolean
+InvokeEOLHookUPP(
+ char theChar,
+ TEPtr pTE,
+ TEHandle hTE,
+ EOLHookUPP userUPP) ;
+extern void
+InvokeCaretHookUPP(
+ const Rect * r,
+ TEPtr pTE,
+ CaretHookUPP userUPP) ;
+extern unsigned short
+InvokeWidthHookUPP(
+ unsigned short textLen,
+ unsigned short textOffset,
+ void * textBufferPtr,
+ TEPtr pTE,
+ TEHandle hTE,
+ WidthHookUPP userUPP) ;
+extern unsigned short
+InvokeTextWidthHookUPP(
+ unsigned short textLen,
+ unsigned short textOffset,
+ void * textBufferPtr,
+ TEPtr pTE,
+ TEHandle hTE,
+ TextWidthHookUPP userUPP) ;
+extern unsigned short
+InvokeNWidthHookUPP(
+ unsigned short styleRunLen,
+ unsigned short styleRunOffset,
+ short slop,
+ short direction,
+ void * textBufferPtr,
+ short * lineStart,
+ TEPtr pTE,
+ TEHandle hTE,
+ NWidthHookUPP userUPP) ;
+extern void
+InvokeDrawHookUPP(
+ unsigned short textOffset,
+ unsigned short drawLen,
+ void * textBufferPtr,
+ TEPtr pTE,
+ TEHandle hTE,
+ DrawHookUPP userUPP) ;
+extern Boolean
+InvokeHitTestHookUPP(
+ unsigned short styleRunLen,
+ unsigned short styleRunOffset,
+ unsigned short slop,
+ void * textBufferPtr,
+ TEPtr pTE,
+ TEHandle hTE,
+ unsigned short * pixelWidth,
+ unsigned short * charOffset,
+ Boolean * pixelInChar,
+ HitTestHookUPP userUPP) ;
+extern void
+InvokeTEFindWordUPP(
+ unsigned short currentPos,
+ short caller,
+ TEPtr pTE,
+ TEHandle hTE,
+ unsigned short * wordStart,
+ unsigned short * wordEnd,
+ TEFindWordUPP userUPP) ;
+extern void
+InvokeTERecalcUPP(
+ TEPtr pTE,
+ unsigned short changeLength,
+ unsigned short * lineStart,
+ unsigned short * firstChar,
+ unsigned short * lastChar,
+ TERecalcUPP userUPP) ;
+extern void
+InvokeTEDoTextUPP(
+ TEPtr pTE,
+ unsigned short firstChar,
+ unsigned short lastChar,
+ short selector,
+ GrafPtr * currentGrafPort,
+ short * charPosition,
+ TEDoTextUPP userUPP) ;
+extern Boolean
+InvokeTEClickLoopUPP(
+ TEPtr pTE,
+ TEClickLoopUPP userUPP) ;
+enum {
+
+ teFUseTextServices = 4
+};
+extern Handle
+TEScrapHandle(void) ;
+extern long
+TEGetScrapLength(void) ;
+extern TEHandle
+TENew(
+ const Rect * destRect,
+ const Rect * viewRect) ;
+extern void
+TEDispose(TEHandle hTE) ;
+extern void
+TESetText(
+ const void * text,
+ long length,
+ TEHandle hTE) ;
+extern CharsHandle
+TEGetText(TEHandle hTE) ;
+extern void
+TEIdle(TEHandle hTE) ;
+extern void
+TESetSelect(
+ long selStart,
+ long selEnd,
+ TEHandle hTE) ;
+extern void
+TEActivate(TEHandle hTE) ;
+extern void
+TEDeactivate(TEHandle hTE) ;
+extern void
+TEKey(
+ CharParameter key,
+ TEHandle hTE) ;
+extern void
+TECut(TEHandle hTE) ;
+extern void
+TECopy(TEHandle hTE) ;
+extern void
+TEPaste(TEHandle hTE) ;
+extern void
+TEDelete(TEHandle hTE) ;
+extern void
+TEInsert(
+ const void * text,
+ long length,
+ TEHandle hTE) ;
+extern void
+TESetAlignment(
+ short just,
+ TEHandle hTE) ;
+extern void
+TEUpdate(
+ const Rect * rUpdate,
+ TEHandle hTE) ;
+extern void
+TETextBox(
+ const void * text,
+ long length,
+ const Rect * box,
+ short just) ;
+extern void
+TEScroll(
+ short dh,
+ short dv,
+ TEHandle hTE) ;
+extern void
+TESelView(TEHandle hTE) ;
+extern void
+TEPinScroll(
+ short dh,
+ short dv,
+ TEHandle hTE) ;
+extern void
+TEAutoView(
+ Boolean fAuto,
+ TEHandle hTE) ;
+extern void
+TECalText(TEHandle hTE) ;
+extern short
+TEGetOffset(
+ Point pt,
+ TEHandle hTE) ;
+extern Point
+TEGetPoint(
+ short offset,
+ TEHandle hTE) ;
+extern void
+TEClick(
+ Point pt,
+ Boolean fExtend,
+ TEHandle h) ;
+extern TEHandle
+TEStyleNew(
+ const Rect * destRect,
+ const Rect * viewRect) ;
+extern void
+TESetStyleHandle(
+ TEStyleHandle theHandle,
+ TEHandle hTE) ;
+extern TEStyleHandle
+TEGetStyleHandle(TEHandle hTE) ;
+extern void
+TEGetStyle(
+ short offset,
+ TextStyle * theStyle,
+ short * lineHeight,
+ short * fontAscent,
+ TEHandle hTE) ;
+extern void
+TEStylePaste(TEHandle hTE) ;
+extern void
+TESetStyle(
+ short mode,
+ const TextStyle * newStyle,
+ Boolean fRedraw,
+ TEHandle hTE) ;
+extern void
+TEReplaceStyle(
+ short mode,
+ const TextStyle * oldStyle,
+ const TextStyle * newStyle,
+ Boolean fRedraw,
+ TEHandle hTE) ;
+extern StScrpHandle
+TEGetStyleScrapHandle(TEHandle hTE) ;
+extern void
+TEStyleInsert(
+ const void * text,
+ long length,
+ StScrpHandle hST,
+ TEHandle hTE) ;
+extern long
+TEGetHeight(
+ long endLine,
+ long startLine,
+ TEHandle hTE) ;
+extern Boolean
+TEContinuousStyle(
+ short * mode,
+ TextStyle * aStyle,
+ TEHandle hTE) ;
+extern void
+TEUseStyleScrap(
+ long rangeStart,
+ long rangeEnd,
+ StScrpHandle newStyles,
+ Boolean fRedraw,
+ TEHandle hTE) ;
+extern void
+TECustomHook(
+ TEIntHook which,
+ UniversalProcPtr * addr,
+ TEHandle hTE) ;
+extern long
+TENumStyles(
+ long rangeStart,
+ long rangeEnd,
+ TEHandle hTE) ;
+extern short
+TEFeatureFlag(
+ short feature,
+ short action,
+ TEHandle hTE) ;
+extern OSErr
+TEGetHiliteRgn(
+ RgnHandle region,
+ TEHandle hTE) ;
+extern void
+TESetScrapLength(long length) ;
+extern OSErr
+TEFromScrap(void) ;
+extern OSErr
+TEToScrap(void) ;
+extern void
+TESetClickLoop(
+ TEClickLoopUPP clikProc,
+ TEHandle hTE) ;
+extern TEDoTextUPP
+TEGetDoTextHook(void) ;
+extern void
+TESetDoTextHook(TEDoTextUPP value) ;
+extern TERecalcUPP
+TEGetRecalcHook(void) ;
+extern void
+TESetRecalcHook(TERecalcUPP value) ;
+extern TEFindWordUPP
+TEGetFindWordHook(void) ;
+extern void
+TESetFindWordHook(TEFindWordUPP value) ;
+extern Handle
+TEGetScrapHandle(void) ;
+extern void
+TESetScrapHandle(Handle value) ;
+extern UInt8
+LMGetWordRedraw(void) ;
+extern void
+LMSetWordRedraw(UInt8 value) ;
+
+
+}
+
+
+
+extern "C" {
+
+
+typedef CGPoint HIPoint;
+typedef CGSize HISize;
+typedef CGRect HIRect;
+
+
+
+
+
+
+typedef struct OpaqueDragRef* DragRef;
+typedef UInt32 DragItemRef;
+typedef OSType FlavorType;
+
+
+
+
+
+
+typedef UInt32 DragAttributes;
+enum {
+ kDragHasLeftSenderWindow = (1L << 0),
+ kDragInsideSenderApplication = (1L << 1),
+ kDragInsideSenderWindow = (1L << 2)
+};
+
+
+
+
+
+
+
+typedef UInt32 DragBehaviors;
+enum {
+ kDragBehaviorNone = 0,
+ kDragBehaviorZoomBackAnimation = (1L << 0)
+};
+
+
+
+
+
+
+
+typedef UInt32 DragImageFlags;
+enum {
+ kDragRegionAndImage = (1L << 4)
+};
+enum {
+ kDragStandardTranslucency = 0L,
+ kDragDarkTranslucency = 1L,
+ kDragDarkerTranslucency = 2L,
+ kDragOpaqueTranslucency = 3L
+};
+typedef SInt16 DragRegionMessage;
+enum {
+ kDragRegionBegin = 1,
+ kDragRegionDraw = 2,
+ kDragRegionHide = 3,
+ kDragRegionIdle = 4,
+ kDragRegionEnd = 5
+};
+typedef SInt16 ZoomAcceleration;
+enum {
+ kZoomNoAcceleration = 0,
+ kZoomAccelerate = 1,
+ kZoomDecelerate = 2
+};
+typedef UInt32 FlavorFlags;
+enum {
+ flavorSenderOnly = (1 << 0),
+ flavorSenderTranslated = (1 << 1),
+ flavorNotSaved = (1 << 2),
+ flavorSystemTranslated = (1 << 8),
+ flavorDataPromised = (1 << 9)
+};
+enum {
+ kDragFlavorTypeHFS = 'hfs ',
+ kDragFlavorTypePromiseHFS = 'phfs',
+ flavorTypeHFS = kDragFlavorTypeHFS,
+ flavorTypePromiseHFS = kDragFlavorTypePromiseHFS
+};
+
+enum {
+ kDragPromisedFlavorFindFile = 'rWm1',
+ kDragPromisedFlavor = 'fssP'
+};
+
+enum {
+ kDragPseudoCreatorVolumeOrDirectory = 'MACS',
+ kDragPseudoFileTypeVolume = 'disk',
+ kDragPseudoFileTypeDirectory = 'fold'
+};
+enum {
+ flavorTypeDirectory = 'diry'
+};
+enum {
+ kFlavorTypeClippingName = 'clnm',
+ kFlavorTypeClippingFilename = 'clfn',
+ kFlavorTypeUnicodeClippingName = 'ucln',
+ kFlavorTypeUnicodeClippingFilename = 'uclf',
+ kFlavorTypeDragToTrashOnly = 'fdtt',
+ kFlavorTypeFinderNoTrackingBehavior = 'fntb'
+};
+typedef SInt16 DragTrackingMessage;
+enum {
+ kDragTrackingEnterHandler = 1,
+ kDragTrackingEnterWindow = 2,
+ kDragTrackingInWindow = 3,
+ kDragTrackingLeaveWindow = 4,
+ kDragTrackingLeaveHandler = 5
+};
+enum {
+
+
+
+
+
+
+
+ kDragStandardDropLocationTrash = 'trsh',
+
+
+
+
+ kDragStandardDropLocationUnknown = 'unkn'
+};
+
+typedef OSType StandardDropLocation;
+enum {
+
+
+
+
+
+
+ kDragActionNothing = 0L,
+
+
+
+
+ kDragActionCopy = 1L,
+
+
+
+
+ kDragActionAlias = (1L << 1),
+
+
+
+
+
+ kDragActionGeneric = (1L << 2),
+
+
+
+
+
+ kDragActionPrivate = (1L << 3),
+
+
+
+
+ kDragActionMove = (1L << 4),
+
+
+
+
+ kDragActionDelete = (1L << 5),
+
+
+
+
+ kDragActionAll = (long)0xFFFFFFFF
+};
+
+typedef UInt32 DragActions;
+
+
+
+
+
+
+struct HFSFlavor {
+ OSType fileType;
+ OSType fileCreator;
+ UInt16 fdFlags;
+ FSSpec fileSpec;
+};
+typedef struct HFSFlavor HFSFlavor;
+struct PromiseHFSFlavor {
+ OSType fileType;
+ OSType fileCreator;
+ UInt16 fdFlags;
+ FlavorType promisedFlavor;
+};
+typedef struct PromiseHFSFlavor PromiseHFSFlavor;
+
+
+
+
+
+
+typedef OSErr ( * DragTrackingHandlerProcPtr)(DragTrackingMessage message, WindowRef theWindow, void *handlerRefCon, DragRef theDrag);
+typedef OSErr ( * DragReceiveHandlerProcPtr)(WindowRef theWindow, void *handlerRefCon, DragRef theDrag);
+typedef DragTrackingHandlerProcPtr DragTrackingHandlerUPP;
+typedef DragReceiveHandlerProcPtr DragReceiveHandlerUPP;
+extern DragTrackingHandlerUPP
+NewDragTrackingHandlerUPP(DragTrackingHandlerProcPtr userRoutine) ;
+extern DragReceiveHandlerUPP
+NewDragReceiveHandlerUPP(DragReceiveHandlerProcPtr userRoutine) ;
+extern void
+DisposeDragTrackingHandlerUPP(DragTrackingHandlerUPP userUPP) ;
+extern void
+DisposeDragReceiveHandlerUPP(DragReceiveHandlerUPP userUPP) ;
+extern OSErr
+InvokeDragTrackingHandlerUPP(
+ DragTrackingMessage message,
+ WindowRef theWindow,
+ void * handlerRefCon,
+ DragRef theDrag,
+ DragTrackingHandlerUPP userUPP) ;
+extern OSErr
+InvokeDragReceiveHandlerUPP(
+ WindowRef theWindow,
+ void * handlerRefCon,
+ DragRef theDrag,
+ DragReceiveHandlerUPP userUPP) ;
+
+
+
+
+
+
+
+typedef OSErr ( * DragSendDataProcPtr)(FlavorType theType, void *dragSendRefCon, DragItemRef theItemRef, DragRef theDrag);
+typedef OSErr ( * DragInputProcPtr)(Point *mouse, SInt16 *modifiers, void *dragInputRefCon, DragRef theDrag);
+typedef OSErr ( * DragDrawingProcPtr)(DragRegionMessage message, RgnHandle showRegion, Point showOrigin, RgnHandle hideRegion, Point hideOrigin, void *dragDrawingRefCon, DragRef theDrag);
+typedef DragSendDataProcPtr DragSendDataUPP;
+typedef DragInputProcPtr DragInputUPP;
+typedef DragDrawingProcPtr DragDrawingUPP;
+extern DragSendDataUPP
+NewDragSendDataUPP(DragSendDataProcPtr userRoutine) ;
+extern DragInputUPP
+NewDragInputUPP(DragInputProcPtr userRoutine) ;
+extern DragDrawingUPP
+NewDragDrawingUPP(DragDrawingProcPtr userRoutine) ;
+extern void
+DisposeDragSendDataUPP(DragSendDataUPP userUPP) ;
+extern void
+DisposeDragInputUPP(DragInputUPP userUPP) ;
+extern void
+DisposeDragDrawingUPP(DragDrawingUPP userUPP) ;
+extern OSErr
+InvokeDragSendDataUPP(
+ FlavorType theType,
+ void * dragSendRefCon,
+ DragItemRef theItemRef,
+ DragRef theDrag,
+ DragSendDataUPP userUPP) ;
+extern OSErr
+InvokeDragInputUPP(
+ Point * mouse,
+ SInt16 * modifiers,
+ void * dragInputRefCon,
+ DragRef theDrag,
+ DragInputUPP userUPP) ;
+extern OSErr
+InvokeDragDrawingUPP(
+ DragRegionMessage message,
+ RgnHandle showRegion,
+ Point showOrigin,
+ RgnHandle hideRegion,
+ Point hideOrigin,
+ void * dragDrawingRefCon,
+ DragRef theDrag,
+ DragDrawingUPP userUPP) ;
+extern OSErr
+InstallTrackingHandler(
+ DragTrackingHandlerUPP trackingHandler,
+ WindowRef theWindow,
+ void * handlerRefCon) ;
+extern OSErr
+InstallReceiveHandler(
+ DragReceiveHandlerUPP receiveHandler,
+ WindowRef theWindow,
+ void * handlerRefCon) ;
+extern OSErr
+RemoveTrackingHandler(
+ DragTrackingHandlerUPP trackingHandler,
+ WindowRef theWindow) ;
+extern OSErr
+RemoveReceiveHandler(
+ DragReceiveHandlerUPP receiveHandler,
+ WindowRef theWindow) ;
+extern OSErr
+NewDrag(DragRef * theDrag) ;
+extern OSErr
+DisposeDrag(DragRef theDrag) ;
+extern OSErr
+AddDragItemFlavor(
+ DragRef theDrag,
+ DragItemRef theItemRef,
+ FlavorType theType,
+ const void * dataPtr,
+ Size dataSize,
+ FlavorFlags theFlags) ;
+extern OSErr
+SetDragItemFlavorData(
+ DragRef theDrag,
+ DragItemRef theItemRef,
+ FlavorType theType,
+ const void * dataPtr,
+ Size dataSize,
+ UInt32 dataOffset) ;
+extern OSErr
+SetDragSendProc(
+ DragRef theDrag,
+ DragSendDataUPP sendProc,
+ void * dragSendRefCon) ;
+extern OSErr
+SetDragInputProc(
+ DragRef theDrag,
+ DragInputUPP inputProc,
+ void * dragInputRefCon) ;
+extern OSErr
+SetDragDrawingProc(
+ DragRef theDrag,
+ DragDrawingUPP drawingProc,
+ void * dragDrawingRefCon) ;
+extern OSErr
+SetDragImage(
+ DragRef theDrag,
+ PixMapHandle imagePixMap,
+ RgnHandle imageRgn,
+ Point imageOffsetPt,
+ DragImageFlags theImageFlags) ;
+extern OSStatus
+SetDragImageWithCGImage(
+ DragRef inDrag,
+ CGImageRef inCGImage,
+ const HIPoint * inImageOffsetPt,
+ DragImageFlags inImageFlags) ;
+extern OSErr
+ChangeDragBehaviors(
+ DragRef theDrag,
+ DragBehaviors inBehaviorsToSet,
+ DragBehaviors inBehaviorsToClear) ;
+extern OSErr
+TrackDrag(
+ DragRef theDrag,
+ const EventRecord * theEvent,
+ RgnHandle theRegion) ;
+extern OSErr
+CountDragItems(
+ DragRef theDrag,
+ UInt16 * numItems) ;
+extern OSErr
+GetDragItemReferenceNumber(
+ DragRef theDrag,
+ UInt16 index,
+ DragItemRef * theItemRef) ;
+extern OSErr
+CountDragItemFlavors(
+ DragRef theDrag,
+ DragItemRef theItemRef,
+ UInt16 * numFlavors) ;
+extern OSErr
+GetFlavorType(
+ DragRef theDrag,
+ DragItemRef theItemRef,
+ UInt16 index,
+ FlavorType * theType) ;
+extern OSErr
+GetFlavorFlags(
+ DragRef theDrag,
+ DragItemRef theItemRef,
+ FlavorType theType,
+ FlavorFlags * theFlags) ;
+extern OSErr
+GetFlavorDataSize(
+ DragRef theDrag,
+ DragItemRef theItemRef,
+ FlavorType theType,
+ Size * dataSize) ;
+extern OSErr
+GetFlavorData(
+ DragRef theDrag,
+ DragItemRef theItemRef,
+ FlavorType theType,
+ void * dataPtr,
+ Size * dataSize,
+ UInt32 dataOffset) ;
+extern OSErr
+GetDragItemBounds(
+ DragRef theDrag,
+ DragItemRef theItemRef,
+ Rect * itemBounds) ;
+extern OSErr
+SetDragItemBounds(
+ DragRef theDrag,
+ DragItemRef theItemRef,
+ const Rect * itemBounds) ;
+extern OSErr
+GetDropLocation(
+ DragRef theDrag,
+ AEDesc * dropLocation) ;
+extern OSErr
+SetDropLocation(
+ DragRef theDrag,
+ const AEDesc * dropLocation) ;
+extern OSStatus
+GetStandardDropLocation(
+ DragRef theDrag,
+ StandardDropLocation * outDropLocation) ;
+extern OSStatus
+SetStandardDropLocation(
+ DragRef theDrag,
+ StandardDropLocation dropLocation) ;
+extern OSErr
+GetDragAttributes(
+ DragRef theDrag,
+ DragAttributes * flags) ;
+extern OSErr
+GetDragMouse(
+ DragRef theDrag,
+ Point * mouse,
+ Point * globalPinnedMouse) ;
+extern OSErr
+SetDragMouse(
+ DragRef theDrag,
+ Point globalPinnedMouse) ;
+extern OSErr
+GetDragOrigin(
+ DragRef theDrag,
+ Point * globalInitialMouse) ;
+extern OSErr
+GetDragModifiers(
+ DragRef theDrag,
+ SInt16 * modifiers,
+ SInt16 * mouseDownModifiers,
+ SInt16 * mouseUpModifiers) ;
+extern OSStatus
+GetDragAllowableActions(
+ DragRef theDrag,
+ DragActions * outActions) ;
+extern OSStatus
+SetDragAllowableActions(
+ DragRef theDrag,
+ DragActions inActions,
+ Boolean isLocal) ;
+extern OSStatus
+GetDragDropAction(
+ DragRef theDrag,
+ DragActions * outAction) ;
+extern OSStatus
+SetDragDropAction(
+ DragRef theDrag,
+ DragActions inAction) ;
+extern OSErr
+ShowDragHilite(
+ DragRef theDrag,
+ RgnHandle hiliteFrame,
+ Boolean inside) ;
+extern OSErr
+HideDragHilite(DragRef theDrag) ;
+extern OSErr
+DragPreScroll(
+ DragRef theDrag,
+ SInt16 dH,
+ SInt16 dV) ;
+extern OSErr
+DragPostScroll(DragRef theDrag) ;
+extern OSErr
+UpdateDragHilite(
+ DragRef theDrag,
+ RgnHandle updateRgn) ;
+extern OSErr
+GetDragHiliteColor(
+ WindowRef window,
+ RGBColor * color) ;
+extern Boolean
+WaitMouseMoved(Point initialGlobalMouse) ;
+extern OSErr
+ZoomRects(
+ const Rect * fromRect,
+ const Rect * toRect,
+ SInt16 zoomSteps,
+ ZoomAcceleration acceleration) ;
+extern OSErr
+ZoomRegion(
+ RgnHandle region,
+ Point zoomDistance,
+ SInt16 zoomSteps,
+ ZoomAcceleration acceleration) ;
+typedef DragRef DragReference;
+typedef DragItemRef ItemReference;
+
+
+}
+extern "C" {
+
+
+
+
+
+
+enum {
+ kControlDefProcType = 'CDEF',
+ kControlTemplateResourceType = 'CNTL',
+ kControlColorTableResourceType = 'cctb',
+ kControlDefProcResourceType = 'CDEF'
+};
+
+
+
+
+struct ControlTemplate {
+ Rect controlRect;
+ SInt16 controlValue;
+ Boolean controlVisible;
+ UInt8 fill;
+ SInt16 controlMaximum;
+ SInt16 controlMinimum;
+ SInt16 controlDefProcID;
+ SInt32 controlReference;
+ Str255 controlTitle;
+};
+typedef struct ControlTemplate ControlTemplate;
+typedef ControlTemplate * ControlTemplatePtr;
+typedef ControlTemplatePtr * ControlTemplateHandle;
+typedef struct OpaqueControlRef* ControlRef;
+
+
+
+typedef ControlRef ControlHandle;
+typedef SInt16 ControlPartCode;
+
+
+
+typedef void ( * ControlActionProcPtr)(ControlRef theControl, ControlPartCode partCode);
+typedef ControlActionProcPtr ControlActionUPP;
+extern ControlActionUPP
+NewControlActionUPP(ControlActionProcPtr userRoutine) ;
+extern void
+DisposeControlActionUPP(ControlActionUPP userUPP) ;
+extern void
+InvokeControlActionUPP(
+ ControlRef theControl,
+ ControlPartCode partCode,
+ ControlActionUPP userUPP) ;
+
+
+
+
+enum {
+ cFrameColor = 0,
+ cBodyColor = 1,
+ cTextColor = 2,
+ cThumbColor = 3,
+ kNumberCtlCTabEntries = 4
+};
+
+struct CtlCTab {
+ SInt32 ccSeed;
+ SInt16 ccRider;
+ SInt16 ctSize;
+ ColorSpec ctTable[4];
+};
+typedef struct CtlCTab CtlCTab;
+typedef CtlCTab * CCTabPtr;
+typedef CCTabPtr * CCTabHandle;
+typedef SInt16 ControlVariant;
+enum {
+ kControlNoVariant = 0,
+ kControlUsesOwningWindowsFontVariant = 1 << 3
+};
+
+
+
+
+
+
+enum {
+ kControlNoPart = 0,
+ kControlIndicatorPart = 129,
+ kControlDisabledPart = 254,
+ kControlInactivePart = 255
+};
+
+
+
+
+enum {
+ kControlEntireControl = 0
+};
+enum {
+ kControlStructureMetaPart = -1,
+ kControlContentMetaPart = -2
+};
+
+
+enum {
+ kControlFocusNoPart = 0,
+ kControlFocusNextPart = -1,
+ kControlFocusPrevPart = -2
+};
+
+typedef SInt16 ControlFocusPart;
+enum {
+ kControlCollectionTagBounds = 'boun',
+ kControlCollectionTagValue = 'valu',
+ kControlCollectionTagMinimum = 'min ',
+ kControlCollectionTagMaximum = 'max ',
+ kControlCollectionTagViewSize = 'view',
+ kControlCollectionTagVisibility = 'visi',
+ kControlCollectionTagRefCon = 'refc',
+ kControlCollectionTagTitle = 'titl',
+ kControlCollectionTagUnicodeTitle = 'uttl',
+ kControlCollectionTagIDSignature = 'idsi',
+ kControlCollectionTagIDID = 'idid',
+ kControlCollectionTagCommand = 'cmd ',
+ kControlCollectionTagVarCode = 'varc'
+};
+
+
+enum {
+ kControlCollectionTagSubControls = 'subc'
+};
+
+
+
+
+enum {
+ kControlContentTextOnly = 0,
+ kControlNoContent = 0,
+ kControlContentIconSuiteRes = 1,
+ kControlContentCIconRes = 2,
+ kControlContentPictRes = 3,
+ kControlContentICONRes = 4,
+ kControlContentIconSuiteHandle = 129,
+ kControlContentCIconHandle = 130,
+ kControlContentPictHandle = 131,
+ kControlContentIconRef = 132,
+ kControlContentICON = 133
+};
+
+typedef SInt16 ControlContentType;
+struct ControlButtonContentInfo {
+ ControlContentType contentType;
+ union {
+ SInt16 resID;
+ CIconHandle cIconHandle;
+ Handle iconSuite;
+ IconRef iconRef;
+ PicHandle picture;
+ Handle ICONHandle;
+ } u;
+};
+typedef struct ControlButtonContentInfo ControlButtonContentInfo;
+typedef ControlButtonContentInfo * ControlButtonContentInfoPtr;
+typedef ControlButtonContentInfo ControlImageContentInfo;
+typedef ControlButtonContentInfo * ControlImageContentInfoPtr;
+
+
+
+enum {
+ kControlKeyScriptBehaviorAllowAnyScript = 'any ',
+ kControlKeyScriptBehaviorPrefersRoman = 'prmn',
+ kControlKeyScriptBehaviorRequiresRoman = 'rrmn'
+};
+
+typedef UInt32 ControlKeyScriptBehavior;
+enum {
+ kControlFontBigSystemFont = -1,
+ kControlFontSmallSystemFont = -2,
+ kControlFontSmallBoldSystemFont = -3,
+ kControlFontViewSystemFont = -4
+};
+
+
+
+
+enum {
+ kControlUseFontMask = 0x0001,
+ kControlUseFaceMask = 0x0002,
+ kControlUseSizeMask = 0x0004,
+ kControlUseForeColorMask = 0x0008,
+ kControlUseBackColorMask = 0x0010,
+ kControlUseModeMask = 0x0020,
+ kControlUseJustMask = 0x0040,
+ kControlUseAllMask = 0x00FF,
+ kControlAddFontSizeMask = 0x0100
+};
+
+
+
+
+enum {
+ kControlAddToMetaFontMask = 0x0200
+};
+
+
+
+
+
+enum {
+ kControlUseThemeFontIDMask = 0x0080
+};
+
+struct ControlFontStyleRec {
+ SInt16 flags;
+ SInt16 font;
+ SInt16 size;
+ SInt16 style;
+ SInt16 mode;
+ SInt16 just;
+ RGBColor foreColor;
+ RGBColor backColor;
+};
+typedef struct ControlFontStyleRec ControlFontStyleRec;
+typedef ControlFontStyleRec * ControlFontStylePtr;
+enum {
+ kDoNotActivateAndIgnoreClick = 0,
+ kDoNotActivateAndHandleClick = 1,
+ kActivateAndIgnoreClick = 2,
+ kActivateAndHandleClick = 3
+};
+
+typedef UInt32 ClickActivationResult;
+enum {
+ kControlFontStyleTag = 'font',
+ kControlKeyFilterTag = 'fltr',
+
+
+
+
+
+ kControlKindTag = 'kind',
+
+
+
+
+
+
+
+ kControlSizeTag = 'size'
+};
+
+
+
+
+enum {
+
+ kControlSupportsGhosting = 1 << 0,
+ kControlSupportsEmbedding = 1 << 1,
+ kControlSupportsFocus = 1 << 2,
+ kControlWantsIdle = 1 << 3,
+ kControlWantsActivate = 1 << 4,
+ kControlHandlesTracking = 1 << 5,
+ kControlSupportsDataAccess = 1 << 6,
+ kControlHasSpecialBackground = 1 << 7,
+ kControlGetsFocusOnClick = 1 << 8,
+ kControlSupportsCalcBestRect = 1 << 9,
+ kControlSupportsLiveFeedback = 1 << 10,
+ kControlHasRadioBehavior = 1 << 11,
+ kControlSupportsDragAndDrop = 1 << 12,
+ kControlAutoToggles = 1 << 14,
+ kControlSupportsGetRegion = 1 << 17,
+ kControlSupportsFlattening = 1 << 19,
+ kControlSupportsSetCursor = 1 << 20,
+ kControlSupportsContextualMenus = 1 << 21,
+ kControlSupportsClickActivation = 1 << 22,
+ kControlIdlesWithTimer = 1 << 23
+};
+
+
+
+
+enum {
+ drawCntl = 0,
+ testCntl = 1,
+ calcCRgns = 2,
+ initCntl = 3,
+ dispCntl = 4,
+ posCntl = 5,
+ thumbCntl = 6,
+ dragCntl = 7,
+ autoTrack = 8,
+ calcCntlRgn = 10,
+ calcThumbRgn = 11,
+ drawThumbOutline = 12,
+ kControlMsgDrawGhost = 13,
+ kControlMsgCalcBestRect = 14,
+ kControlMsgHandleTracking = 15,
+ kControlMsgFocus = 16,
+ kControlMsgKeyDown = 17,
+ kControlMsgIdle = 18,
+ kControlMsgGetFeatures = 19,
+ kControlMsgSetData = 20,
+ kControlMsgGetData = 21,
+ kControlMsgActivate = 22,
+ kControlMsgSetUpBackground = 23,
+ kControlMsgCalcValueFromPos = 26,
+ kControlMsgTestNewMsgSupport = 27,
+ kControlMsgSubValueChanged = 25,
+ kControlMsgSubControlAdded = 28,
+ kControlMsgSubControlRemoved = 29,
+ kControlMsgApplyTextColor = 30,
+ kControlMsgGetRegion = 31,
+ kControlMsgFlatten = 32,
+ kControlMsgSetCursor = 33,
+ kControlMsgDragEnter = 38,
+ kControlMsgDragLeave = 39,
+ kControlMsgDragWithin = 40,
+ kControlMsgDragReceive = 41,
+ kControlMsgDisplayDebugInfo = 46,
+ kControlMsgContextualMenuClick = 47,
+ kControlMsgGetClickActivation = 48
+};
+
+typedef SInt16 ControlDefProcMessage;
+enum {
+
+
+
+
+
+ kControlSizeNormal = 0,
+
+
+
+
+
+
+ kControlSizeSmall = 1,
+
+
+
+
+
+
+ kControlSizeLarge = 2,
+
+
+
+
+
+
+ kControlSizeAuto = 0xFFFF
+};
+
+typedef UInt16 ControlSize;
+
+
+
+enum {
+ kDrawControlEntireControl = 0,
+ kDrawControlIndicatorOnly = 129
+};
+
+
+
+
+enum {
+ kDragControlEntireControl = 0,
+ kDragControlIndicator = 1
+};
+
+
+
+
+struct IndicatorDragConstraint {
+ Rect limitRect;
+ Rect slopRect;
+ DragConstraint axis;
+};
+typedef struct IndicatorDragConstraint IndicatorDragConstraint;
+typedef IndicatorDragConstraint * IndicatorDragConstraintPtr;
+
+
+
+enum {
+ kControlSupportsNewMessages = ' ok '
+};
+
+
+
+
+
+struct ControlTrackingRec {
+ Point startPt;
+ EventModifiers modifiers;
+ ControlActionUPP action;
+};
+typedef struct ControlTrackingRec ControlTrackingRec;
+typedef ControlTrackingRec * ControlTrackingPtr;
+
+
+
+struct ControlKeyDownRec {
+ EventModifiers modifiers;
+ SInt16 keyCode;
+ SInt16 charCode;
+};
+typedef struct ControlKeyDownRec ControlKeyDownRec;
+typedef ControlKeyDownRec * ControlKeyDownPtr;
+
+
+
+
+struct ControlDataAccessRec {
+ ResType tag;
+ ResType part;
+ Size size;
+ Ptr dataPtr;
+};
+typedef struct ControlDataAccessRec ControlDataAccessRec;
+typedef ControlDataAccessRec * ControlDataAccessPtr;
+
+
+
+struct ControlCalcSizeRec {
+ SInt16 height;
+ SInt16 width;
+ SInt16 baseLine;
+};
+typedef struct ControlCalcSizeRec ControlCalcSizeRec;
+typedef ControlCalcSizeRec * ControlCalcSizePtr;
+
+
+
+
+struct ControlBackgroundRec {
+ SInt16 depth;
+ Boolean colorDevice;
+};
+typedef struct ControlBackgroundRec ControlBackgroundRec;
+typedef ControlBackgroundRec * ControlBackgroundPtr;
+
+
+
+
+struct ControlApplyTextColorRec {
+ SInt16 depth;
+ Boolean colorDevice;
+ Boolean active;
+};
+typedef struct ControlApplyTextColorRec ControlApplyTextColorRec;
+typedef ControlApplyTextColorRec * ControlApplyTextColorPtr;
+
+
+
+
+struct ControlGetRegionRec {
+ RgnHandle region;
+ ControlPartCode part;
+};
+typedef struct ControlGetRegionRec ControlGetRegionRec;
+typedef ControlGetRegionRec * ControlGetRegionPtr;
+
+
+
+
+struct ControlSetCursorRec {
+ Point localPoint;
+ EventModifiers modifiers;
+ Boolean cursorWasSet;
+};
+typedef struct ControlSetCursorRec ControlSetCursorRec;
+typedef ControlSetCursorRec * ControlSetCursorPtr;
+
+
+
+
+
+struct ControlContextualMenuClickRec {
+ Point localPoint;
+ Boolean menuDisplayed;
+};
+typedef struct ControlContextualMenuClickRec ControlContextualMenuClickRec;
+typedef ControlContextualMenuClickRec * ControlContextualMenuClickPtr;
+
+
+
+
+
+struct ControlClickActivationRec {
+ Point localPoint;
+ EventModifiers modifiers;
+ ClickActivationResult result;
+};
+typedef struct ControlClickActivationRec ControlClickActivationRec;
+typedef ControlClickActivationRec * ControlClickActivationPtr;
+
+
+
+typedef SInt32 ( * ControlDefProcPtr)(SInt16 varCode, ControlRef theControl, ControlDefProcMessage message, SInt32 param);
+typedef ControlDefProcPtr ControlDefUPP;
+extern ControlDefUPP
+NewControlDefUPP(ControlDefProcPtr userRoutine) ;
+extern void
+DisposeControlDefUPP(ControlDefUPP userUPP) ;
+extern SInt32
+InvokeControlDefUPP(
+ SInt16 varCode,
+ ControlRef theControl,
+ ControlDefProcMessage message,
+ SInt32 param,
+ ControlDefUPP userUPP) ;
+enum {
+ kControlKeyFilterBlockKey = 0,
+ kControlKeyFilterPassKey = 1
+};
+
+typedef SInt16 ControlKeyFilterResult;
+typedef ControlKeyFilterResult ( * ControlKeyFilterProcPtr)(ControlRef theControl, SInt16 *keyCode, SInt16 *charCode, EventModifiers *modifiers);
+typedef ControlKeyFilterProcPtr ControlKeyFilterUPP;
+extern ControlKeyFilterUPP
+NewControlKeyFilterUPP(ControlKeyFilterProcPtr userRoutine) ;
+extern void
+DisposeControlKeyFilterUPP(ControlKeyFilterUPP userUPP) ;
+extern ControlKeyFilterResult
+InvokeControlKeyFilterUPP(
+ ControlRef theControl,
+ SInt16 * keyCode,
+ SInt16 * charCode,
+ EventModifiers * modifiers,
+ ControlKeyFilterUPP userUPP) ;
+
+
+
+
+
+
+
+enum {
+ noConstraint = kNoConstraint,
+ hAxisOnly = 1,
+ vAxisOnly = 2
+};
+
+
+
+
+
+enum {
+ kControlDefProcPtr = 0,
+ kControlDefObjectClass = 1
+};
+
+typedef UInt32 ControlDefType;
+struct ControlDefSpec {
+ ControlDefType defType;
+ union {
+ ControlDefUPP defProc;
+ void * classRef;
+ } u;
+};
+typedef struct ControlDefSpec ControlDefSpec;
+extern OSStatus
+CreateCustomControl(
+ WindowRef owningWindow,
+ const Rect * contBounds,
+ const ControlDefSpec * def,
+ Collection initData,
+ ControlRef * outControl) ;
+extern ControlRef
+NewControl(
+ WindowRef owningWindow,
+ const Rect * boundsRect,
+ ConstStr255Param controlTitle,
+ Boolean initiallyVisible,
+ SInt16 initialValue,
+ SInt16 minimumValue,
+ SInt16 maximumValue,
+ SInt16 procID,
+ SInt32 controlReference) ;
+extern ControlRef
+GetNewControl(
+ SInt16 resourceID,
+ WindowRef owningWindow) ;
+extern void
+DisposeControl(ControlRef theControl) ;
+extern void
+KillControls(WindowRef theWindow) ;
+typedef OSStatus ( * ControlCNTLToCollectionProcPtr)(const Rect *bounds, SInt16 value, Boolean visible, SInt16 max, SInt16 min, SInt16 procID, SInt32 refCon, ConstStr255Param title, Collection collection);
+typedef ControlCNTLToCollectionProcPtr ControlCNTLToCollectionUPP;
+extern ControlCNTLToCollectionUPP
+NewControlCNTLToCollectionUPP(ControlCNTLToCollectionProcPtr userRoutine) ;
+extern void
+DisposeControlCNTLToCollectionUPP(ControlCNTLToCollectionUPP userUPP) ;
+extern OSStatus
+InvokeControlCNTLToCollectionUPP(
+ const Rect * bounds,
+ SInt16 value,
+ Boolean visible,
+ SInt16 max,
+ SInt16 min,
+ SInt16 procID,
+ SInt32 refCon,
+ ConstStr255Param title,
+ Collection collection,
+ ControlCNTLToCollectionUPP userUPP) ;
+extern OSStatus
+RegisterControlDefinition(
+ SInt16 inCDEFResID,
+ const ControlDefSpec * inControlDef,
+ ControlCNTLToCollectionUPP inConversionProc) ;
+extern void
+HiliteControl(
+ ControlRef theControl,
+ ControlPartCode hiliteState) ;
+extern void
+ShowControl(ControlRef theControl) ;
+extern void
+HideControl(ControlRef theControl) ;
+extern Boolean
+IsControlActive(ControlRef inControl) ;
+extern Boolean
+IsControlVisible(ControlRef inControl) ;
+extern OSErr
+ActivateControl(ControlRef inControl) ;
+extern OSErr
+DeactivateControl(ControlRef inControl) ;
+extern OSErr
+SetControlVisibility(
+ ControlRef inControl,
+ Boolean inIsVisible,
+ Boolean inDoDraw) ;
+extern Boolean
+IsControlEnabled(ControlRef inControl) ;
+extern OSStatus
+EnableControl(ControlRef inControl) ;
+extern OSStatus
+DisableControl(ControlRef inControl) ;
+extern void
+DrawControls(WindowRef theWindow) ;
+extern void
+Draw1Control(ControlRef theControl) ;
+extern void
+UpdateControls(
+ WindowRef inWindow,
+ RgnHandle inUpdateRegion) ;
+extern OSErr
+GetBestControlRect(
+ ControlRef inControl,
+ Rect * outRect,
+ SInt16 * outBaseLineOffset) ;
+extern OSErr
+SetControlFontStyle(
+ ControlRef inControl,
+ const ControlFontStyleRec * inStyle) ;
+extern void
+DrawControlInCurrentPort(ControlRef inControl) ;
+extern OSErr
+SetUpControlBackground(
+ ControlRef inControl,
+ SInt16 inDepth,
+ Boolean inIsColorDevice) ;
+extern OSErr
+SetUpControlTextColor(
+ ControlRef inControl,
+ SInt16 inDepth,
+ Boolean inIsColorDevice) ;
+typedef OSStatus ( * ControlColorProcPtr)(ControlRef inControl, SInt16 inMessage, SInt16 inDrawDepth, Boolean inDrawInColor);
+typedef ControlColorProcPtr ControlColorUPP;
+extern ControlColorUPP
+NewControlColorUPP(ControlColorProcPtr userRoutine) ;
+extern void
+DisposeControlColorUPP(ControlColorUPP userUPP) ;
+extern OSStatus
+InvokeControlColorUPP(
+ ControlRef inControl,
+ SInt16 inMessage,
+ SInt16 inDrawDepth,
+ Boolean inDrawInColor,
+ ControlColorUPP userUPP) ;
+extern OSStatus
+SetControlColorProc(
+ ControlRef inControl,
+ ControlColorUPP inProc) ;
+extern ControlPartCode
+TrackControl(
+ ControlRef theControl,
+ Point startPoint,
+ ControlActionUPP actionProc) ;
+extern void
+DragControl(
+ ControlRef theControl,
+ Point startPoint,
+ const Rect * limitRect,
+ const Rect * slopRect,
+ DragConstraint axis) ;
+extern ControlPartCode
+TestControl(
+ ControlRef theControl,
+ Point testPoint) ;
+extern ControlPartCode
+FindControl(
+ Point testPoint,
+ WindowRef theWindow,
+ ControlRef * theControl) ;
+extern ControlRef
+FindControlUnderMouse(
+ Point inWhere,
+ WindowRef inWindow,
+ ControlPartCode * outPart) ;
+extern ControlPartCode
+HandleControlClick(
+ ControlRef inControl,
+ Point inWhere,
+ EventModifiers inModifiers,
+ ControlActionUPP inAction) ;
+extern OSStatus
+HandleControlContextualMenuClick(
+ ControlRef inControl,
+ Point inWhere,
+ Boolean * menuDisplayed) ;
+extern OSStatus
+GetControlClickActivation(
+ ControlRef inControl,
+ Point inWhere,
+ EventModifiers inModifiers,
+ ClickActivationResult * outResult) ;
+extern ControlPartCode
+HandleControlKey(
+ ControlRef inControl,
+ SInt16 inKeyCode,
+ SInt16 inCharCode,
+ EventModifiers inModifiers) ;
+extern void
+IdleControls(WindowRef inWindow) ;
+extern OSStatus
+HandleControlSetCursor(
+ ControlRef control,
+ Point localPoint,
+ EventModifiers modifiers,
+ Boolean * cursorWasSet) ;
+extern void
+MoveControl(
+ ControlRef theControl,
+ SInt16 h,
+ SInt16 v) ;
+extern void
+SizeControl(
+ ControlRef theControl,
+ SInt16 w,
+ SInt16 h) ;
+extern void
+SetControlTitle(
+ ControlRef theControl,
+ ConstStr255Param title) ;
+extern void
+GetControlTitle(
+ ControlRef theControl,
+ Str255 title) ;
+extern OSStatus
+SetControlTitleWithCFString(
+ ControlRef inControl,
+ CFStringRef inString) ;
+extern OSStatus
+CopyControlTitleAsCFString(
+ ControlRef inControl,
+ CFStringRef * outString) ;
+extern SInt16
+GetControlValue(ControlRef theControl) ;
+extern void
+SetControlValue(
+ ControlRef theControl,
+ SInt16 newValue) ;
+extern SInt16
+GetControlMinimum(ControlRef theControl) ;
+extern void
+SetControlMinimum(
+ ControlRef theControl,
+ SInt16 newMinimum) ;
+extern SInt16
+GetControlMaximum(ControlRef theControl) ;
+extern void
+SetControlMaximum(
+ ControlRef theControl,
+ SInt16 newMaximum) ;
+extern SInt32
+GetControlViewSize(ControlRef theControl) ;
+extern void
+SetControlViewSize(
+ ControlRef theControl,
+ SInt32 newViewSize) ;
+extern SInt32
+GetControl32BitValue(ControlRef theControl) ;
+extern void
+SetControl32BitValue(
+ ControlRef theControl,
+ SInt32 newValue) ;
+extern SInt32
+GetControl32BitMaximum(ControlRef theControl) ;
+extern void
+SetControl32BitMaximum(
+ ControlRef theControl,
+ SInt32 newMaximum) ;
+extern SInt32
+GetControl32BitMinimum(ControlRef theControl) ;
+extern void
+SetControl32BitMinimum(
+ ControlRef theControl,
+ SInt32 newMinimum) ;
+extern Boolean
+IsValidControlHandle(ControlRef theControl) ;
+
+
+
+
+
+
+struct ControlID {
+ OSType signature;
+ SInt32 id;
+};
+typedef struct ControlID ControlID;
+extern OSStatus
+SetControlID(
+ ControlRef inControl,
+ const ControlID * inID) ;
+extern OSStatus
+GetControlID(
+ ControlRef inControl,
+ ControlID * outID) ;
+extern OSStatus
+GetControlByID(
+ WindowRef inWindow,
+ const ControlID * inID,
+ ControlRef * outControl) ;
+extern OSStatus
+SetControlCommandID(
+ ControlRef inControl,
+ UInt32 inCommandID) ;
+extern OSStatus
+GetControlCommandID(
+ ControlRef inControl,
+ UInt32 * outCommandID) ;
+
+
+
+
+
+
+struct ControlKind {
+ OSType signature;
+ OSType kind;
+};
+typedef struct ControlKind ControlKind;
+
+
+
+
+
+enum {
+
+
+
+
+ kControlKindSignatureApple = 'appl'
+};
+extern OSStatus
+GetControlKind(
+ ControlRef inControl,
+ ControlKind * outControlKind) ;
+
+
+
+
+
+enum {
+ kControlPropertyPersistent = 0x00000001
+};
+extern OSStatus
+GetControlProperty(
+ ControlRef control,
+ OSType propertyCreator,
+ OSType propertyTag,
+ UInt32 bufferSize,
+ UInt32 * actualSize,
+ void * propertyBuffer) ;
+extern OSStatus
+GetControlPropertySize(
+ ControlRef control,
+ OSType propertyCreator,
+ OSType propertyTag,
+ UInt32 * size) ;
+extern OSStatus
+SetControlProperty(
+ ControlRef control,
+ OSType propertyCreator,
+ OSType propertyTag,
+ UInt32 propertySize,
+ const void * propertyData) ;
+extern OSStatus
+RemoveControlProperty(
+ ControlRef control,
+ OSType propertyCreator,
+ OSType propertyTag) ;
+extern OSStatus
+GetControlPropertyAttributes(
+ ControlRef control,
+ OSType propertyCreator,
+ OSType propertyTag,
+ UInt32 * attributes) ;
+extern OSStatus
+ChangeControlPropertyAttributes(
+ ControlRef control,
+ OSType propertyCreator,
+ OSType propertyTag,
+ UInt32 attributesToSet,
+ UInt32 attributesToClear) ;
+extern OSStatus
+GetControlRegion(
+ ControlRef inControl,
+ ControlPartCode inPart,
+ RgnHandle outRegion) ;
+extern ControlVariant
+GetControlVariant(ControlRef theControl) ;
+extern void
+SetControlAction(
+ ControlRef theControl,
+ ControlActionUPP actionProc) ;
+extern ControlActionUPP
+GetControlAction(ControlRef theControl) ;
+extern void
+SetControlReference(
+ ControlRef theControl,
+ SInt32 data) ;
+extern SInt32
+GetControlReference(ControlRef theControl) ;
+extern SInt32
+SendControlMessage(
+ ControlRef inControl,
+ SInt16 inMessage,
+ void * inParam) ;
+extern OSErr
+DumpControlHierarchy(
+ WindowRef inWindow,
+ const FSSpec * inDumpFile) ;
+extern OSErr
+CreateRootControl(
+ WindowRef inWindow,
+ ControlRef * outControl) ;
+extern OSErr
+GetRootControl(
+ WindowRef inWindow,
+ ControlRef * outControl) ;
+extern OSErr
+EmbedControl(
+ ControlRef inControl,
+ ControlRef inContainer) ;
+extern OSErr
+AutoEmbedControl(
+ ControlRef inControl,
+ WindowRef inWindow) ;
+extern OSErr
+GetSuperControl(
+ ControlRef inControl,
+ ControlRef * outParent) ;
+extern OSErr
+CountSubControls(
+ ControlRef inControl,
+ UInt16 * outNumChildren) ;
+extern OSErr
+GetIndexedSubControl(
+ ControlRef inControl,
+ UInt16 inIndex,
+ ControlRef * outSubControl) ;
+extern OSErr
+SetControlSupervisor(
+ ControlRef inControl,
+ ControlRef inBoss) ;
+extern OSErr
+GetKeyboardFocus(
+ WindowRef inWindow,
+ ControlRef * outControl) ;
+extern OSErr
+SetKeyboardFocus(
+ WindowRef inWindow,
+ ControlRef inControl,
+ ControlFocusPart inPart) ;
+extern OSErr
+AdvanceKeyboardFocus(WindowRef inWindow) ;
+extern OSErr
+ReverseKeyboardFocus(WindowRef inWindow) ;
+extern OSErr
+ClearKeyboardFocus(WindowRef inWindow) ;
+extern OSErr
+GetControlFeatures(
+ ControlRef inControl,
+ UInt32 * outFeatures) ;
+extern OSErr
+SetControlData(
+ ControlRef inControl,
+ ControlPartCode inPart,
+ ResType inTagName,
+ Size inSize,
+ const void * inData) ;
+extern OSErr
+GetControlData(
+ ControlRef inControl,
+ ControlPartCode inPart,
+ ResType inTagName,
+ Size inBufferSize,
+ void * inBuffer,
+ Size * outActualSize) ;
+extern OSErr
+GetControlDataSize(
+ ControlRef inControl,
+ ControlPartCode inPart,
+ ResType inTagName,
+ Size * outMaxSize) ;
+enum {
+
+
+
+
+
+ kDragTrackingEnterControl = 2,
+
+
+
+
+
+ kDragTrackingInControl = 3,
+
+
+
+
+
+ kDragTrackingLeaveControl = 4
+};
+extern OSStatus
+HandleControlDragTracking(
+ ControlRef inControl,
+ DragTrackingMessage inMessage,
+ DragReference inDrag,
+ Boolean * outLikesDrag) ;
+extern OSStatus
+HandleControlDragReceive(
+ ControlRef inControl,
+ DragReference inDrag) ;
+extern OSStatus
+SetControlDragTrackingEnabled(
+ ControlRef inControl,
+ Boolean inTracks) ;
+extern OSStatus
+IsControlDragTrackingEnabled(
+ ControlRef inControl,
+ Boolean * outTracks) ;
+extern OSStatus
+SetAutomaticControlDragTrackingEnabledForWindow(
+ WindowRef inWindow,
+ Boolean inTracks) ;
+extern OSStatus
+IsAutomaticControlDragTrackingEnabledForWindow(
+ WindowRef inWindow,
+ Boolean * outTracks) ;
+extern Rect *
+GetControlBounds(
+ ControlRef control,
+ Rect * bounds) ;
+extern Boolean
+IsControlHilited(ControlRef control) ;
+extern UInt16
+GetControlHilite(ControlRef control) ;
+extern WindowRef
+GetControlOwner(ControlRef control) ;
+extern Handle
+GetControlDataHandle(ControlRef control) ;
+extern MenuRef
+GetControlPopupMenuHandle(ControlRef control) ;
+extern short
+GetControlPopupMenuID(ControlRef control) ;
+extern void
+SetControlDataHandle(
+ ControlRef control,
+ Handle dataHandle) ;
+extern void
+SetControlBounds(
+ ControlRef control,
+ const Rect * bounds) ;
+extern void
+SetControlPopupMenuHandle(
+ ControlRef control,
+ MenuRef popupMenu) ;
+extern void
+SetControlPopupMenuID(
+ ControlRef control,
+ short menuID) ;
+
+
+
+
+
+
+}
+
+
+
+extern "C" {
+
+
+typedef OSType PropertyCreator;
+typedef OSType PropertyTag;
+typedef UInt32 WindowClass;
+enum {
+ kAlertWindowClass = 1,
+ kMovableAlertWindowClass = 2,
+ kModalWindowClass = 3,
+ kMovableModalWindowClass = 4,
+ kFloatingWindowClass = 5,
+ kDocumentWindowClass = 6,
+ kUtilityWindowClass = 8,
+ kHelpWindowClass = 10,
+ kSheetWindowClass = 11,
+ kToolbarWindowClass = 12,
+ kPlainWindowClass = 13,
+ kOverlayWindowClass = 14,
+ kSheetAlertWindowClass = 15,
+ kAltPlainWindowClass = 16,
+ kDrawerWindowClass = 20,
+ kAllWindowClasses = (unsigned long)0xFFFFFFFF
+};
+
+
+
+
+
+
+typedef UInt32 WindowAttributes;
+
+
+
+
+
+enum {
+
+
+
+
+ kWindowNoAttributes = 0L,
+
+
+
+
+
+
+ kWindowCloseBoxAttribute = (1L << 0),
+
+
+
+
+
+
+ kWindowHorizontalZoomAttribute = (1L << 1),
+
+
+
+
+
+
+ kWindowVerticalZoomAttribute = (1L << 2),
+
+
+
+
+
+
+ kWindowFullZoomAttribute = (kWindowVerticalZoomAttribute | kWindowHorizontalZoomAttribute),
+
+
+
+
+
+
+
+ kWindowCollapseBoxAttribute = (1L << 3),
+
+
+
+
+
+
+ kWindowResizableAttribute = (1L << 4),
+
+
+
+
+
+
+ kWindowSideTitlebarAttribute = (1L << 5),
+
+
+
+
+
+ kWindowToolbarButtonAttribute = (1L << 6),
+ kWindowMetalAttribute = (1L << 8),
+
+
+
+
+ kWindowNoUpdatesAttribute = (1L << 16),
+
+
+
+
+ kWindowNoActivatesAttribute = (1L << 17),
+
+
+
+
+
+
+
+ kWindowOpaqueForEventsAttribute = (1L << 18),
+ kWindowCompositingAttribute = (1L << 19),
+
+
+
+
+
+
+ kWindowNoShadowAttribute = (1L << 21),
+
+
+
+
+
+
+
+ kWindowHideOnSuspendAttribute = (1L << 24),
+
+
+
+
+
+ kWindowStandardHandlerAttribute = (1L << 25),
+
+
+
+
+
+
+
+ kWindowHideOnFullScreenAttribute = (1L << 26),
+
+
+
+
+
+
+ kWindowInWindowMenuAttribute = (1L << 27),
+
+
+
+
+
+ kWindowLiveResizeAttribute = (1L << 28),
+
+
+
+
+
+
+
+ kWindowIgnoreClicksAttribute = (1L << 29),
+
+
+
+
+
+
+
+ kWindowNoConstrainAttribute = (unsigned long)((1L << 31)),
+
+
+
+
+
+ kWindowStandardDocumentAttributes = (kWindowCloseBoxAttribute | kWindowFullZoomAttribute | kWindowCollapseBoxAttribute | kWindowResizableAttribute),
+
+
+
+
+
+ kWindowStandardFloatingAttributes = (kWindowCloseBoxAttribute | kWindowCollapseBoxAttribute)
+};
+
+
+
+
+
+enum {
+ kWindowDefProcType = 'WDEF'
+};
+
+
+
+
+enum {
+ kStandardWindowDefinition = 0,
+ kRoundWindowDefinition = 1,
+ kFloatingWindowDefinition = 124
+};
+
+
+
+
+enum {
+
+ kDocumentWindowVariantCode = 0,
+ kModalDialogVariantCode = 1,
+ kPlainDialogVariantCode = 2,
+ kShadowDialogVariantCode = 3,
+ kMovableModalDialogVariantCode = 5,
+ kAlertVariantCode = 7,
+ kMovableAlertVariantCode = 9,
+ kSideFloaterVariantCode = 8
+};
+
+
+
+
+
+enum {
+
+ documentProc = 0,
+ dBoxProc = 1,
+ plainDBox = 2,
+ altDBoxProc = 3,
+ noGrowDocProc = 4,
+ movableDBoxProc = 5,
+ zoomDocProc = 8,
+ zoomNoGrow = 12,
+ floatProc = 1985,
+ floatGrowProc = 1987,
+ floatZoomProc = 1989,
+ floatZoomGrowProc = 1991,
+ floatSideProc = 1993,
+ floatSideGrowProc = 1995,
+ floatSideZoomProc = 1997,
+ floatSideZoomGrowProc = 1999
+};
+enum {
+
+ kWindowDocumentDefProcResID = 64,
+ kWindowDialogDefProcResID = 65,
+ kWindowUtilityDefProcResID = 66,
+ kWindowUtilitySideTitleDefProcResID = 67,
+ kWindowSheetDefProcResID = 68,
+ kWindowSimpleDefProcResID = 69,
+ kWindowSheetAlertDefProcResID = 70
+};
+
+enum {
+
+ kWindowDocumentProc = 1024,
+ kWindowGrowDocumentProc = 1025,
+ kWindowVertZoomDocumentProc = 1026,
+ kWindowVertZoomGrowDocumentProc = 1027,
+ kWindowHorizZoomDocumentProc = 1028,
+ kWindowHorizZoomGrowDocumentProc = 1029,
+ kWindowFullZoomDocumentProc = 1030,
+ kWindowFullZoomGrowDocumentProc = 1031
+};
+
+
+enum {
+
+ kWindowPlainDialogProc = 1040,
+ kWindowShadowDialogProc = 1041,
+ kWindowModalDialogProc = 1042,
+ kWindowMovableModalDialogProc = 1043,
+ kWindowAlertProc = 1044,
+ kWindowMovableAlertProc = 1045
+};
+
+
+enum {
+
+ kWindowMovableModalGrowProc = 1046
+};
+
+
+enum {
+
+ kWindowFloatProc = 1057,
+ kWindowFloatGrowProc = 1059,
+ kWindowFloatVertZoomProc = 1061,
+ kWindowFloatVertZoomGrowProc = 1063,
+ kWindowFloatHorizZoomProc = 1065,
+ kWindowFloatHorizZoomGrowProc = 1067,
+ kWindowFloatFullZoomProc = 1069,
+ kWindowFloatFullZoomGrowProc = 1071
+};
+
+
+enum {
+
+ kWindowFloatSideProc = 1073,
+ kWindowFloatSideGrowProc = 1075,
+ kWindowFloatSideVertZoomProc = 1077,
+ kWindowFloatSideVertZoomGrowProc = 1079,
+ kWindowFloatSideHorizZoomProc = 1081,
+ kWindowFloatSideHorizZoomGrowProc = 1083,
+ kWindowFloatSideFullZoomProc = 1085,
+ kWindowFloatSideFullZoomGrowProc = 1087
+};
+
+
+enum {
+
+ kWindowSheetProc = 1088,
+ kWindowSheetAlertProc = 1120
+};
+
+
+
+
+
+
+
+enum {
+
+
+
+
+
+
+ kWindowSimpleProc = 1104,
+
+
+
+
+ kWindowSimpleFrameProc = 1105
+};
+enum {
+ kWindowNoPosition = 0x0000,
+ kWindowDefaultPosition = 0x0000,
+ kWindowCenterMainScreen = 0x280A,
+ kWindowAlertPositionMainScreen = 0x300A,
+ kWindowStaggerMainScreen = 0x380A,
+ kWindowCenterParentWindow = 0xA80A,
+ kWindowAlertPositionParentWindow = 0xB00A,
+ kWindowStaggerParentWindow = 0xB80A,
+ kWindowCenterParentWindowScreen = 0x680A,
+ kWindowAlertPositionParentWindowScreen = 0x700A,
+ kWindowStaggerParentWindowScreen = 0x780A
+};
+typedef UInt32 WindowPositionMethod;
+enum {
+
+
+
+
+ kWindowCenterOnMainScreen = 1,
+
+
+
+
+ kWindowCenterOnParentWindow = 2,
+
+
+
+
+
+ kWindowCenterOnParentWindowScreen = 3,
+
+
+
+
+ kWindowCascadeOnMainScreen = 4,
+
+
+
+
+ kWindowCascadeOnParentWindow = 5,
+
+
+
+
+
+ kWindowCascadeOnParentWindowScreen = 6,
+
+
+
+
+
+
+
+ kWindowCascadeStartAtParentWindowScreen = 10,
+
+
+
+
+ kWindowAlertPositionOnMainScreen = 7,
+
+
+
+
+ kWindowAlertPositionOnParentWindow = 8,
+
+
+
+
+
+ kWindowAlertPositionOnParentWindowScreen = 9
+};
+
+
+
+
+
+typedef UInt16 WindowRegionCode;
+enum {
+
+ kWindowTitleBarRgn = 0,
+ kWindowTitleTextRgn = 1,
+ kWindowCloseBoxRgn = 2,
+ kWindowZoomBoxRgn = 3,
+ kWindowDragRgn = 5,
+ kWindowGrowRgn = 6,
+ kWindowCollapseBoxRgn = 7,
+ kWindowTitleProxyIconRgn = 8,
+ kWindowStructureRgn = 32,
+ kWindowContentRgn = 33,
+ kWindowUpdateRgn = 34,
+ kWindowOpaqueRgn = 35,
+ kWindowGlobalPortRgn = 40
+};
+
+
+struct GetWindowRegionRec {
+ RgnHandle winRgn;
+ WindowRegionCode regionCode;
+};
+typedef struct GetWindowRegionRec GetWindowRegionRec;
+typedef GetWindowRegionRec * GetWindowRegionPtr;
+typedef GetWindowRegionRec * GetWindowRegionRecPtr;
+struct SetupWindowProxyDragImageRec {
+ GWorldPtr imageGWorld;
+ RgnHandle imageRgn;
+ RgnHandle outlineRgn;
+};
+typedef struct SetupWindowProxyDragImageRec SetupWindowProxyDragImageRec;
+
+struct MeasureWindowTitleRec {
+
+ SInt16 fullTitleWidth;
+ SInt16 titleTextWidth;
+
+
+ Boolean isUnicodeTitle;
+ Boolean unused;
+};
+typedef struct MeasureWindowTitleRec MeasureWindowTitleRec;
+typedef MeasureWindowTitleRec * MeasureWindowTitleRecPtr;
+
+
+
+
+
+
+
+struct GetGrowImageRegionRec {
+ Rect growRect;
+ RgnHandle growImageRegion;
+};
+typedef struct GetGrowImageRegionRec GetGrowImageRegionRec;
+
+
+
+enum {
+ dialogKind = 2,
+ userKind = 8,
+ kDialogWindowKind = 2,
+ kApplicationWindowKind = 8
+};
+
+
+
+
+
+typedef SInt16 WindowPartCode;
+enum {
+ inDesk = 0,
+ inNoWindow = 0,
+ inMenuBar = 1,
+ inSysWindow = 2,
+ inContent = 3,
+ inDrag = 4,
+ inGrow = 5,
+ inGoAway = 6,
+ inZoomIn = 7,
+ inZoomOut = 8,
+ inCollapseBox = 11,
+ inProxyIcon = 12,
+ inToolbarButton = 13,
+ inStructure = 15
+};
+
+
+
+
+typedef SInt16 WindowDefPartCode;
+enum {
+ wNoHit = 0,
+ wInContent = 1,
+ wInDrag = 2,
+ wInGrow = 3,
+ wInGoAway = 4,
+ wInZoomIn = 5,
+ wInZoomOut = 6,
+ wInCollapseBox = 9,
+ wInProxyIcon = 10,
+ wInToolbarButton = 11,
+ wInStructure = 13
+};
+
+
+
+
+
+enum {
+ kWindowMsgDraw = 0,
+ kWindowMsgHitTest = 1,
+ kWindowMsgCalculateShape = 2,
+ kWindowMsgInitialize = 3,
+ kWindowMsgCleanUp = 4,
+ kWindowMsgDrawGrowOutline = 5,
+ kWindowMsgDrawGrowBox = 6
+};
+
+
+enum {
+ kWindowMsgGetFeatures = 7,
+ kWindowMsgGetRegion = 8
+};
+
+
+enum {
+ kWindowMsgDragHilite = 9,
+ kWindowMsgModified = 10,
+ kWindowMsgDrawInCurrentPort = 11,
+ kWindowMsgSetupProxyDragImage = 12,
+ kWindowMsgStateChanged = 13,
+ kWindowMsgMeasureTitle = 14
+};
+
+
+enum {
+ kWindowMsgGetGrowImageRegion = 19
+};
+
+
+enum {
+ wDraw = 0,
+ wHit = 1,
+ wCalcRgns = 2,
+ wNew = 3,
+ wDispose = 4,
+ wGrow = 5,
+ wDrawGIcon = 6
+};
+
+
+
+
+enum {
+ kWindowStateTitleChanged = (1 << 0)
+};
+
+
+
+
+
+enum {
+ kWindowCanGrow = (1 << 0),
+ kWindowCanZoom = (1 << 1),
+ kWindowCanCollapse = (1 << 2),
+ kWindowIsModal = (1 << 3),
+ kWindowCanGetWindowRegion = (1 << 4),
+ kWindowIsAlert = (1 << 5),
+ kWindowHasTitleBar = (1 << 6)
+};
+
+
+enum {
+ kWindowSupportsDragHilite = (1 << 7),
+ kWindowSupportsModifiedBit = (1 << 8),
+ kWindowCanDrawInCurrentPort = (1 << 9),
+ kWindowCanSetupProxyDragImage = (1 << 10),
+ kWindowCanMeasureTitle = (1 << 11),
+ kWindowWantsDisposeAtProcessDeath = (1 << 12),
+ kWindowSupportsGetGrowImageRegion = (1 << 13),
+ kWindowDefSupportsColorGrafPort = 0x40000002
+};
+
+
+enum {
+ kWindowIsOpaque = (1 << 14)
+};
+
+
+
+
+
+enum {
+ kWindowSupportsSetGrowImageRegion = (1 << 13)
+};
+
+
+
+
+enum {
+ deskPatID = 16
+};
+
+
+
+
+
+
+enum {
+ wContentColor = 0,
+ wFrameColor = 1,
+ wTextColor = 2,
+ wHiliteColor = 3,
+ wTitleBarColor = 4
+};
+
+
+
+
+
+
+enum {
+ kMouseUpOutOfSlop = (long)0x80008000
+};
+
+
+
+
+
+struct WinCTab {
+ long wCSeed;
+ short wCReserved;
+ short ctSize;
+ ColorSpec ctTable[5];
+};
+typedef struct WinCTab WinCTab;
+typedef WinCTab * WCTabPtr;
+typedef WCTabPtr * WCTabHandle;
+enum {
+ kWindowDefinitionVersionOne = 1,
+ kWindowDefinitionVersionTwo = 2
+};
+
+
+enum {
+ kWindowIsCollapsedState = (1 << 0L)
+};
+
+struct BasicWindowDescription {
+ UInt32 descriptionSize;
+
+ Rect windowContentRect;
+ Rect windowZoomRect;
+ UInt32 windowRefCon;
+ UInt32 windowStateFlags;
+ WindowPositionMethod windowPositionMethod;
+
+ UInt32 windowDefinitionVersion;
+ union {
+ struct {
+ SInt16 windowDefProc;
+ Boolean windowHasCloseBox;
+ } versionOne;
+
+ struct {
+ WindowClass windowClass;
+ WindowAttributes windowAttributes;
+ } versionTwo;
+
+ } windowDefinition;
+};
+typedef struct BasicWindowDescription BasicWindowDescription;
+
+enum {
+ kStoredWindowSystemTag = 'appl',
+ kStoredBasicWindowDescriptionID = 'sbas',
+ kStoredWindowPascalTitleID = 's255'
+};
+
+enum {
+ kStoredWindowUnicodeTitleID = 'ustr',
+ kStoredWindowTitleCFStringID = 'cfst'
+};
+struct WStateData {
+ Rect userState;
+ Rect stdState;
+};
+typedef struct WStateData WStateData;
+typedef WStateData * WStateDataPtr;
+typedef WStateDataPtr * WStateDataHandle;
+
+
+
+typedef long ( * WindowDefProcPtr)(short varCode, WindowRef window, short message, long param);
+typedef void ( * DeskHookProcPtr)(Boolean mouseClick, EventRecord *theEvent);
+typedef OSStatus ( * WindowPaintProcPtr)(GDHandle device, GrafPtr qdContext, WindowRef window, RgnHandle inClientPaintRgn, RgnHandle outSystemPaintRgn, void *refCon);
+typedef WindowDefProcPtr WindowDefUPP;
+typedef DeskHookProcPtr DeskHookUPP;
+typedef WindowPaintProcPtr WindowPaintUPP;
+extern WindowDefUPP
+NewWindowDefUPP(WindowDefProcPtr userRoutine) ;
+extern WindowPaintUPP
+NewWindowPaintUPP(WindowPaintProcPtr userRoutine) ;
+extern void
+DisposeWindowDefUPP(WindowDefUPP userUPP) ;
+extern void
+DisposeWindowPaintUPP(WindowPaintUPP userUPP) ;
+extern long
+InvokeWindowDefUPP(
+ short varCode,
+ WindowRef window,
+ short message,
+ long param,
+ WindowDefUPP userUPP) ;
+extern OSStatus
+InvokeWindowPaintUPP(
+ GDHandle device,
+ GrafPtr qdContext,
+ WindowRef window,
+ RgnHandle inClientPaintRgn,
+ RgnHandle outSystemPaintRgn,
+ void * refCon,
+ WindowPaintUPP userUPP) ;
+
+
+
+
+enum {
+ kWindowDefProcPtr = 0,
+ kWindowDefObjectClass = 1,
+ kWindowDefProcID = 2,
+ kWindowDefHIView = 3
+};
+
+typedef UInt32 WindowDefType;
+struct WindowDefSpec {
+ WindowDefType defType;
+ union {
+ WindowDefUPP defProc;
+ void * classRef;
+ short procID;
+ void * rootView;
+ } u;
+};
+typedef struct WindowDefSpec WindowDefSpec;
+typedef WindowDefSpec * WindowDefSpecPtr;
+extern WindowRef
+GetNewCWindow(
+ short windowID,
+ void * wStorage,
+ WindowRef behind) ;
+extern WindowRef
+NewWindow(
+ void * wStorage,
+ const Rect * boundsRect,
+ ConstStr255Param title,
+ Boolean visible,
+ short theProc,
+ WindowRef behind,
+ Boolean goAwayFlag,
+ long refCon) ;
+extern WindowRef
+GetNewWindow(
+ short windowID,
+ void * wStorage,
+ WindowRef behind) ;
+extern WindowRef
+NewCWindow(
+ void * wStorage,
+ const Rect * boundsRect,
+ ConstStr255Param title,
+ Boolean visible,
+ short procID,
+ WindowRef behind,
+ Boolean goAwayFlag,
+ long refCon) ;
+extern void
+DisposeWindow(WindowRef window) ;
+extern OSStatus
+CreateNewWindow(
+ WindowClass windowClass,
+ WindowAttributes attributes,
+ const Rect * contentBounds,
+ WindowRef * outWindow) ;
+extern OSStatus
+CreateWindowFromResource(
+ SInt16 resID,
+ WindowRef * outWindow) ;
+extern OSStatus
+StoreWindowIntoCollection(
+ WindowRef window,
+ Collection collection) ;
+extern OSStatus
+CreateWindowFromCollection(
+ Collection collection,
+ WindowRef * outWindow) ;
+extern OSStatus
+GetWindowOwnerCount(
+ WindowRef window,
+ UInt32 * outCount) ;
+extern OSStatus
+CloneWindow(WindowRef window) ;
+extern ItemCount
+GetWindowRetainCount(WindowRef inWindow) ;
+extern OSStatus
+RetainWindow(WindowRef inWindow) ;
+extern OSStatus
+ReleaseWindow(WindowRef inWindow) ;
+extern OSStatus
+CreateCustomWindow(
+ const WindowDefSpec * def,
+ WindowClass windowClass,
+ WindowAttributes attributes,
+ const Rect * contentBounds,
+ WindowRef * outWindow) ;
+extern OSStatus
+ReshapeCustomWindow(WindowRef window) ;
+extern OSStatus
+RegisterWindowDefinition(
+ SInt16 inResID,
+ const WindowDefSpec * inDefSpec) ;
+extern OSStatus
+GetWindowWidgetHilite(
+ WindowRef inWindow,
+ WindowDefPartCode * outHilite) ;
+extern Boolean
+IsValidWindowClass(WindowClass inClass) ;
+extern WindowAttributes
+GetAvailableWindowAttributes(WindowClass inClass) ;
+extern OSStatus
+GetWindowClass(
+ WindowRef window,
+ WindowClass * outClass) ;
+extern OSStatus
+GetWindowAttributes(
+ WindowRef window,
+ WindowAttributes * outAttributes) ;
+extern OSStatus
+ChangeWindowAttributes(
+ WindowRef window,
+ WindowAttributes setTheseAttributes,
+ WindowAttributes clearTheseAttributes) ;
+extern OSStatus
+SetWindowClass(
+ WindowRef inWindow,
+ WindowClass inWindowClass) ;
+typedef UInt32 WindowModality;
+enum {
+
+
+
+
+
+ kWindowModalityNone = 0,
+
+
+
+
+
+
+ kWindowModalitySystemModal = 1,
+
+
+
+
+
+ kWindowModalityAppModal = 2,
+
+
+
+
+ kWindowModalityWindowModal = 3
+};
+extern OSStatus
+SetWindowModality(
+ WindowRef inWindow,
+ WindowModality inModalKind,
+ WindowRef inUnavailableWindow) ;
+extern OSStatus
+GetWindowModality(
+ WindowRef inWindow,
+ WindowModality * outModalKind,
+ WindowRef * outUnavailableWindow) ;
+extern OSStatus
+ShowFloatingWindows(void) ;
+extern OSStatus
+HideFloatingWindows(void) ;
+extern Boolean
+AreFloatingWindowsVisible(void) ;
+typedef struct OpaqueWindowGroupRef* WindowGroupRef;
+typedef UInt32 WindowGroupAttributes;
+enum {
+
+
+
+
+
+
+
+ kWindowGroupAttrSelectAsLayer = 1 << 0,
+
+
+
+
+
+
+ kWindowGroupAttrMoveTogether = 1 << 1,
+ kWindowGroupAttrLayerTogether = 1 << 2,
+
+
+
+
+
+
+
+ kWindowGroupAttrSharedActivation = 1 << 3,
+ kWindowGroupAttrHideOnCollapse = 1 << 4
+};
+typedef UInt32 WindowActivationScope;
+enum {
+ kWindowActivationScopeNone = 0,
+
+
+
+
+
+
+
+ kWindowActivationScopeIndependent = 1,
+
+
+
+
+
+
+
+ kWindowActivationScopeAll = 2
+};
+
+
+
+
+
+
+
+enum {
+
+
+
+
+
+ kNextWindowGroup = true,
+
+
+
+
+
+ kPreviousWindowGroup = false
+};
+typedef UInt32 WindowGroupContentOptions;
+enum {
+
+
+
+
+
+
+ kWindowGroupContentsReturnWindows = 1 << 0,
+
+
+
+
+
+
+
+ kWindowGroupContentsRecurse = 1 << 1,
+
+
+
+
+
+
+ kWindowGroupContentsVisible = 1 << 2
+};
+extern OSStatus
+CreateWindowGroup(
+ WindowGroupAttributes inAttributes,
+ WindowGroupRef * outGroup) ;
+extern OSStatus
+RetainWindowGroup(WindowGroupRef inGroup) ;
+extern OSStatus
+ReleaseWindowGroup(WindowGroupRef inGroup) ;
+extern ItemCount
+GetWindowGroupRetainCount(WindowGroupRef inGroup) ;
+extern WindowGroupRef
+GetWindowGroupOfClass(WindowClass windowClass) ;
+extern OSStatus
+SetWindowGroupName(
+ WindowGroupRef inGroup,
+ CFStringRef inName) ;
+extern OSStatus
+CopyWindowGroupName(
+ WindowGroupRef inGroup,
+ CFStringRef * outName) ;
+extern OSStatus
+GetWindowGroupAttributes(
+ WindowGroupRef inGroup,
+ WindowGroupAttributes * outAttributes) ;
+extern OSStatus
+ChangeWindowGroupAttributes(
+ WindowGroupRef inGroup,
+ WindowGroupAttributes setTheseAttributes,
+ WindowGroupAttributes clearTheseAttributes) ;
+extern OSStatus
+SetWindowGroupLevel(
+ WindowGroupRef inGroup,
+ SInt32 inLevel) ;
+extern OSStatus
+GetWindowGroupLevel(
+ WindowGroupRef inGroup,
+ SInt32 * outLevel) ;
+extern OSStatus
+SendWindowGroupBehind(
+ WindowGroupRef inGroup,
+ WindowGroupRef behindGroup) ;
+extern WindowGroupRef
+GetWindowGroup(WindowRef inWindow) ;
+extern OSStatus
+SetWindowGroup(
+ WindowRef inWindow,
+ WindowGroupRef inNewGroup) ;
+extern Boolean
+IsWindowContainedInGroup(
+ WindowRef inWindow,
+ WindowGroupRef inGroup) ;
+extern WindowGroupRef
+GetWindowGroupParent(WindowGroupRef inGroup) ;
+extern OSStatus
+SetWindowGroupParent(
+ WindowGroupRef inGroup,
+ WindowGroupRef inNewGroup) ;
+extern WindowGroupRef
+GetWindowGroupSibling(
+ WindowGroupRef inGroup,
+ Boolean inNextGroup) ;
+extern WindowRef
+GetWindowGroupOwner(WindowGroupRef inGroup) ;
+extern OSStatus
+SetWindowGroupOwner(
+ WindowGroupRef inGroup,
+ WindowRef inWindow) ;
+extern ItemCount
+CountWindowGroupContents(
+ WindowGroupRef inGroup,
+ WindowGroupContentOptions inOptions) ;
+extern OSStatus
+GetWindowGroupContents(
+ WindowGroupRef inGroup,
+ WindowGroupContentOptions inOptions,
+ ItemCount inAllowedItems,
+ ItemCount * outNumItems,
+ void ** outItems) ;
+extern OSStatus
+GetIndexedWindow(
+ WindowGroupRef inGroup,
+ UInt32 inIndex,
+ WindowGroupContentOptions inOptions,
+ WindowRef * outWindow) ;
+extern OSStatus
+GetWindowIndex(
+ WindowRef inWindow,
+ WindowGroupRef inStartGroup,
+ WindowGroupContentOptions inOptions,
+ UInt32 * outIndex) ;
+extern WindowRef
+ActiveNonFloatingWindow(void) ;
+extern Boolean
+IsWindowActive(WindowRef inWindow) ;
+extern OSStatus
+ActivateWindow(
+ WindowRef inWindow,
+ Boolean inActivate) ;
+extern OSStatus
+GetWindowActivationScope(
+ WindowRef inWindow,
+ WindowActivationScope * outScope) ;
+extern OSStatus
+SetWindowActivationScope(
+ WindowRef inWindow,
+ WindowActivationScope inScope) ;
+extern void
+DebugPrintWindowGroup(WindowGroupRef inGroup) ;
+extern void
+DebugPrintAllWindowGroups(void) ;
+extern OSStatus
+SetWindowContentColor(
+ WindowRef window,
+ const RGBColor * color) ;
+extern OSStatus
+GetWindowContentColor(
+ WindowRef window,
+ RGBColor * color) ;
+extern OSStatus
+GetWindowContentPattern(
+ WindowRef window,
+ PixPatHandle outPixPat) ;
+extern OSStatus
+SetWindowContentPattern(
+ WindowRef window,
+ PixPatHandle pixPat) ;
+
+
+
+typedef OptionBits WindowPaintProcOptions;
+enum {
+ kWindowPaintProcOptionsNone = 0
+};
+extern OSStatus
+InstallWindowContentPaintProc(
+ WindowRef window,
+ WindowPaintUPP paintProc,
+ WindowPaintProcOptions options,
+ void * refCon) ;
+
+
+
+
+
+typedef UInt32 ScrollWindowOptions;
+enum {
+ kScrollWindowNoOptions = 0,
+ kScrollWindowInvalidate = (1L << 0),
+ kScrollWindowEraseToPortBackground = (1L << 1)
+};
+extern OSStatus
+ScrollWindowRect(
+ WindowRef inWindow,
+ const Rect * inScrollRect,
+ SInt16 inHPixels,
+ SInt16 inVPixels,
+ ScrollWindowOptions inOptions,
+ RgnHandle outExposedRgn) ;
+extern OSStatus
+ScrollWindowRegion(
+ WindowRef inWindow,
+ RgnHandle inScrollRgn,
+ SInt16 inHPixels,
+ SInt16 inVPixels,
+ ScrollWindowOptions inOptions,
+ RgnHandle outExposedRgn) ;
+extern void
+ClipAbove(WindowRef window) ;
+extern void
+PaintOne(
+ WindowRef window,
+ RgnHandle clobberedRgn) ;
+extern void
+PaintBehind(
+ WindowRef startWindow,
+ RgnHandle clobberedRgn) ;
+extern void
+CalcVis(WindowRef window) ;
+extern void
+CalcVisBehind(
+ WindowRef startWindow,
+ RgnHandle clobberedRgn) ;
+extern Boolean
+CheckUpdate(EventRecord * theEvent) ;
+extern WindowPartCode
+FindWindow(
+ Point thePoint,
+ WindowRef * window) ;
+extern WindowRef
+FrontWindow(void) ;
+extern void
+BringToFront(WindowRef window) ;
+extern void
+SendBehind(
+ WindowRef window,
+ WindowRef behindWindow) ;
+extern void
+SelectWindow(WindowRef window) ;
+extern WindowRef
+FrontNonFloatingWindow(void) ;
+extern WindowRef
+GetNextWindowOfClass(
+ WindowRef inWindow,
+ WindowClass inWindowClass,
+ Boolean mustBeVisible) ;
+extern WindowRef
+GetFrontWindowOfClass(
+ WindowClass inWindowClass,
+ Boolean mustBeVisible) ;
+extern OSStatus
+FindWindowOfClass(
+ const Point * where,
+ WindowClass inWindowClass,
+ WindowRef * outWindow,
+ WindowPartCode * outWindowPart) ;
+
+
+
+
+
+
+
+enum {
+
+
+
+
+
+ kWindowMenuIncludeRotate = 1 << 0
+};
+extern OSStatus
+CreateStandardWindowMenu(
+ OptionBits inOptions,
+ MenuRef * outMenu) ;
+extern OSStatus
+SetWindowAlternateTitle(
+ WindowRef inWindow,
+ CFStringRef inTitle) ;
+extern OSStatus
+CopyWindowAlternateTitle(
+ WindowRef inWindow,
+ CFStringRef * outTitle) ;
+extern Boolean
+IsValidWindowPtr(WindowRef possibleWindow) ;
+extern void
+HiliteWindow(
+ WindowRef window,
+ Boolean fHilite) ;
+extern void
+SetWRefCon(
+ WindowRef window,
+ long data) ;
+extern long
+GetWRefCon(WindowRef window) ;
+extern void
+SetWindowPic(
+ WindowRef window,
+ PicHandle pic) ;
+extern PicHandle
+GetWindowPic(WindowRef window) ;
+extern short
+GetWVariant(WindowRef window) ;
+extern OSStatus
+GetWindowFeatures(
+ WindowRef window,
+ UInt32 * outFeatures) ;
+extern OSStatus
+GetWindowRegion(
+ WindowRef window,
+ WindowRegionCode inRegionCode,
+ RgnHandle ioWinRgn) ;
+extern OSStatus
+GetWindowStructureWidths(
+ WindowRef inWindow,
+ Rect * outRect) ;
+extern void
+BeginUpdate(WindowRef window) ;
+extern void
+EndUpdate(WindowRef window) ;
+extern OSStatus
+InvalWindowRgn(
+ WindowRef window,
+ RgnHandle region) ;
+extern OSStatus
+InvalWindowRect(
+ WindowRef window,
+ const Rect * bounds) ;
+extern OSStatus
+ValidWindowRgn(
+ WindowRef window,
+ RgnHandle region) ;
+extern OSStatus
+ValidWindowRect(
+ WindowRef window,
+ const Rect * bounds) ;
+extern void
+DrawGrowIcon(WindowRef window) ;
+extern void
+SetWTitle(
+ WindowRef window,
+ ConstStr255Param title) ;
+extern void
+GetWTitle(
+ WindowRef window,
+ Str255 title) ;
+extern OSStatus
+SetWindowTitleWithCFString(
+ WindowRef inWindow,
+ CFStringRef inString) ;
+extern OSStatus
+CopyWindowTitleAsCFString(
+ WindowRef inWindow,
+ CFStringRef * outString) ;
+extern OSStatus
+SetWindowProxyFSSpec(
+ WindowRef window,
+ const FSSpec * inFile) ;
+extern OSStatus
+GetWindowProxyFSSpec(
+ WindowRef window,
+ FSSpec * outFile) ;
+extern OSStatus
+SetWindowProxyAlias(
+ WindowRef inWindow,
+ AliasHandle inAlias) ;
+extern OSStatus
+GetWindowProxyAlias(
+ WindowRef window,
+ AliasHandle * alias) ;
+extern OSStatus
+SetWindowProxyCreatorAndType(
+ WindowRef window,
+ OSType fileCreator,
+ OSType fileType,
+ SInt16 vRefNum) ;
+extern OSStatus
+GetWindowProxyIcon(
+ WindowRef window,
+ IconRef * outIcon) ;
+extern OSStatus
+SetWindowProxyIcon(
+ WindowRef window,
+ IconRef icon) ;
+extern OSStatus
+RemoveWindowProxy(WindowRef window) ;
+extern OSStatus
+BeginWindowProxyDrag(
+ WindowRef window,
+ DragReference * outNewDrag,
+ RgnHandle outDragOutlineRgn) ;
+extern OSStatus
+EndWindowProxyDrag(
+ WindowRef window,
+ DragReference theDrag) ;
+extern OSStatus
+TrackWindowProxyFromExistingDrag(
+ WindowRef window,
+ Point startPt,
+ DragReference drag,
+ RgnHandle inDragOutlineRgn) ;
+extern OSStatus
+TrackWindowProxyDrag(
+ WindowRef window,
+ Point startPt) ;
+extern Boolean
+IsWindowModified(WindowRef window) ;
+extern OSStatus
+SetWindowModified(
+ WindowRef window,
+ Boolean modified) ;
+extern Boolean
+IsWindowPathSelectClick(
+ WindowRef window,
+ const EventRecord * event) ;
+extern OSStatus
+WindowPathSelect(
+ WindowRef window,
+ MenuRef menu,
+ SInt32 * outMenuResult) ;
+extern Boolean
+IsWindowPathSelectEvent(
+ WindowRef window,
+ EventRef inEvent) ;
+extern OSStatus
+HiliteWindowFrameForDrag(
+ WindowRef window,
+ Boolean hilited) ;
+typedef UInt32 WindowTransitionEffect;
+enum {
+
+
+
+
+
+ kWindowZoomTransitionEffect = 1,
+
+
+
+
+
+
+ kWindowSheetTransitionEffect = 2,
+
+
+
+
+
+
+ kWindowSlideTransitionEffect = 3
+};
+typedef UInt32 WindowTransitionAction;
+enum {
+
+
+
+
+
+
+
+ kWindowShowTransitionAction = 1,
+
+
+
+
+
+
+
+ kWindowHideTransitionAction = 2,
+
+
+
+
+
+
+
+ kWindowMoveTransitionAction = 3,
+
+
+
+
+
+
+
+ kWindowResizeTransitionAction = 4
+};
+extern OSStatus
+TransitionWindow(
+ WindowRef inWindow,
+ WindowTransitionEffect inEffect,
+ WindowTransitionAction inAction,
+ const Rect * inRect) ;
+extern OSStatus
+TransitionWindowAndParent(
+ WindowRef inWindow,
+ WindowRef inParentWindow,
+ WindowTransitionEffect inEffect,
+ WindowTransitionAction inAction,
+ const Rect * inRect) ;
+extern void
+MoveWindow(
+ WindowRef window,
+ short hGlobal,
+ short vGlobal,
+ Boolean front) ;
+extern void
+SizeWindow(
+ WindowRef window,
+ short w,
+ short h,
+ Boolean fUpdate) ;
+extern long
+GrowWindow(
+ WindowRef window,
+ Point startPt,
+ const Rect * bBox) ;
+extern void
+DragWindow(
+ WindowRef window,
+ Point startPt,
+ const Rect * boundsRect) ;
+extern void
+ZoomWindow(
+ WindowRef window,
+ WindowPartCode partCode,
+ Boolean front) ;
+extern Boolean
+IsWindowCollapsable(WindowRef window) ;
+extern Boolean
+IsWindowCollapsed(WindowRef window) ;
+extern OSStatus
+CollapseWindow(
+ WindowRef window,
+ Boolean collapse) ;
+extern OSStatus
+CollapseAllWindows(Boolean collapse) ;
+extern OSStatus
+CreateQDContextForCollapsedWindowDockTile(
+ WindowRef inWindow,
+ CGrafPtr * outContext) ;
+extern OSStatus
+ReleaseQDContextForCollapsedWindowDockTile(
+ WindowRef inWindow,
+ CGrafPtr inContext) ;
+extern OSStatus
+UpdateCollapsedWindowDockTile(WindowRef inWindow) ;
+extern OSStatus
+SetWindowDockTileMenu(
+ WindowRef inWindow,
+ MenuRef inMenu) ;
+extern MenuRef
+GetWindowDockTileMenu(WindowRef inWindow) ;
+extern OSStatus
+GetWindowBounds(
+ WindowRef window,
+ WindowRegionCode regionCode,
+ Rect * globalBounds) ;
+extern OSStatus
+SetWindowResizeLimits(
+ WindowRef inWindow,
+ const HISize * inMinLimits,
+ const HISize * inMaxLimits) ;
+extern OSStatus
+GetWindowResizeLimits(
+ WindowRef inWindow,
+ HISize * outMinLimits,
+ HISize * outMaxLimits) ;
+extern Boolean
+ResizeWindow(
+ WindowRef inWindow,
+ Point inStartPoint,
+ const Rect * inSizeConstraints,
+ Rect * outNewContentRect) ;
+extern OSStatus
+SetWindowBounds(
+ WindowRef window,
+ WindowRegionCode regionCode,
+ const Rect * globalBounds) ;
+extern OSStatus
+RepositionWindow(
+ WindowRef window,
+ WindowRef parentWindow,
+ WindowPositionMethod method) ;
+extern OSStatus
+MoveWindowStructure(
+ WindowRef window,
+ short hGlobal,
+ short vGlobal) ;
+extern Boolean
+IsWindowInStandardState(
+ WindowRef inWindow,
+ const Point * inIdealSize,
+ Rect * outIdealStandardState) ;
+extern OSStatus
+ZoomWindowIdeal(
+ WindowRef inWindow,
+ WindowPartCode inPartCode,
+ Point * ioIdealSize) ;
+extern OSStatus
+GetWindowIdealUserState(
+ WindowRef inWindow,
+ Rect * outUserState) ;
+extern OSStatus
+SetWindowIdealUserState(
+ WindowRef inWindow,
+ const Rect * inUserState) ;
+extern OSStatus
+GetWindowGreatestAreaDevice(
+ WindowRef inWindow,
+ WindowRegionCode inRegion,
+ GDHandle * outGreatestDevice,
+ Rect * outGreatestDeviceRect) ;
+
+
+
+
+
+
+
+typedef UInt32 WindowConstrainOptions;
+enum {
+
+
+
+
+ kWindowConstrainMayResize = (1L << 0),
+
+
+
+
+ kWindowConstrainMoveRegardlessOfFit = (1L << 1),
+
+
+
+
+
+ kWindowConstrainAllowPartial = (1L << 2),
+
+
+
+
+
+ kWindowConstrainCalcOnly = (1L << 3),
+
+
+
+
+
+ kWindowConstrainUseTransitionWindow = (1L << 4),
+
+
+
+
+
+
+
+ kWindowConstrainStandardOptions = kWindowConstrainMoveRegardlessOfFit
+};
+extern OSStatus
+ConstrainWindowToScreen(
+ WindowRef inWindowRef,
+ WindowRegionCode inRegionCode,
+ WindowConstrainOptions inOptions,
+ const Rect * inScreenRect,
+ Rect * outStructure) ;
+extern OSStatus
+GetAvailableWindowPositioningBounds(
+ GDHandle inDevice,
+ Rect * outAvailableRect) ;
+extern OSStatus
+GetAvailableWindowPositioningRegion(
+ GDHandle inDevice,
+ RgnHandle ioRgn) ;
+extern void
+HideWindow(WindowRef window) ;
+extern void
+ShowWindow(WindowRef window) ;
+extern void
+ShowHide(
+ WindowRef window,
+ Boolean showFlag) ;
+extern Boolean
+IsWindowVisible(WindowRef window) ;
+typedef UInt32 WindowLatentVisibility;
+enum {
+
+
+
+
+ kWindowLatentVisibleFloater = 1 << 0,
+
+
+
+
+ kWindowLatentVisibleSuspend = 1 << 1,
+
+
+
+
+ kWindowLatentVisibleFullScreen = 1 << 2,
+
+
+
+
+ kWindowLatentVisibleAppHidden = 1 << 3,
+
+
+
+
+ kWindowLatentVisibleCollapsedOwner = 1 << 4,
+
+
+
+
+
+ kWindowLatentVisibleCollapsedGroup = 1 << 5
+};
+extern Boolean
+IsWindowLatentVisible(
+ WindowRef inWindow,
+ WindowLatentVisibility * outLatentVisible) ;
+extern OSStatus
+ShowSheetWindow(
+ WindowRef inSheet,
+ WindowRef inParentWindow) ;
+extern OSStatus
+HideSheetWindow(WindowRef inSheet) ;
+extern OSStatus
+GetSheetWindowParent(
+ WindowRef inSheet,
+ WindowRef * outParentWindow) ;
+enum {
+
+
+
+
+
+
+
+ kWindowEdgeDefault = 0,
+
+
+
+
+ kWindowEdgeTop = 1 << 0,
+
+
+
+
+ kWindowEdgeLeft = 1 << 1,
+
+
+
+
+ kWindowEdgeBottom = 1 << 2,
+
+
+
+
+ kWindowEdgeRight = 1 << 3
+};
+
+
+
+
+
+
+enum {
+
+
+
+
+ kWindowDrawerOpening = 1,
+
+
+
+
+ kWindowDrawerOpen = 2,
+
+
+
+
+ kWindowDrawerClosing = 3,
+
+
+
+
+ kWindowDrawerClosed = 4
+};
+
+typedef UInt32 WindowDrawerState;
+extern OptionBits
+GetDrawerPreferredEdge(WindowRef inDrawerWindow) ;
+extern OSStatus
+SetDrawerPreferredEdge(
+ WindowRef inDrawerWindow,
+ OptionBits inEdge) ;
+extern OptionBits
+GetDrawerCurrentEdge(WindowRef inDrawerWindow) ;
+extern WindowDrawerState
+GetDrawerState(WindowRef inDrawerWindow) ;
+extern WindowRef
+GetDrawerParent(WindowRef inDrawerWindow) ;
+extern OSStatus
+SetDrawerParent(
+ WindowRef inDrawerWindow,
+ WindowRef inParent) ;
+extern OSStatus
+SetDrawerOffsets(
+ WindowRef inDrawerWindow,
+ float inLeadingOffset,
+ float inTrailingOffset) ;
+extern OSStatus
+GetDrawerOffsets(
+ WindowRef inDrawerWindow,
+ float * outLeadingOffset,
+ float * outTrailingOffset) ;
+extern OSStatus
+ToggleDrawer(WindowRef inDrawerWindow) ;
+extern OSStatus
+OpenDrawer(
+ WindowRef inDrawerWindow,
+ OptionBits inEdge,
+ Boolean inAsync) ;
+extern OSStatus
+CloseDrawer(
+ WindowRef inDrawerWindow,
+ Boolean inAsync) ;
+extern OSStatus
+DisableScreenUpdates(void) ;
+extern OSStatus
+EnableScreenUpdates(void) ;
+extern OSStatus
+SetWindowToolbar(
+ WindowRef inWindow,
+ HIToolbarRef inToolbar) ;
+extern OSStatus
+GetWindowToolbar(
+ WindowRef inWindow,
+ HIToolbarRef * outToolbar) ;
+extern OSStatus
+ShowHideWindowToolbar(
+ WindowRef inWindow,
+ Boolean inShow,
+ Boolean inAnimate) ;
+extern Boolean
+IsWindowToolbarVisible(WindowRef inWindow) ;
+extern OSStatus
+SetWindowAlpha(
+ WindowRef inWindow,
+ float inAlpha) ;
+extern OSStatus
+GetWindowAlpha(
+ WindowRef inWindow,
+ float * outAlpha) ;
+extern OSStatus
+GetWindowProperty(
+ WindowRef window,
+ PropertyCreator propertyCreator,
+ PropertyTag propertyTag,
+ UInt32 bufferSize,
+ UInt32 * actualSize,
+ void * propertyBuffer) ;
+extern OSStatus
+GetWindowPropertySize(
+ WindowRef window,
+ PropertyCreator creator,
+ PropertyTag tag,
+ UInt32 * size) ;
+extern OSStatus
+SetWindowProperty(
+ WindowRef window,
+ PropertyCreator propertyCreator,
+ PropertyTag propertyTag,
+ UInt32 propertySize,
+ const void * propertyBuffer) ;
+extern OSStatus
+RemoveWindowProperty(
+ WindowRef window,
+ PropertyCreator propertyCreator,
+ PropertyTag propertyTag) ;
+
+
+
+
+
+enum {
+ kWindowPropertyPersistent = 0x00000001
+};
+extern OSStatus
+GetWindowPropertyAttributes(
+ WindowRef window,
+ OSType propertyCreator,
+ OSType propertyTag,
+ UInt32 * attributes) ;
+extern OSStatus
+ChangeWindowPropertyAttributes(
+ WindowRef window,
+ OSType propertyCreator,
+ OSType propertyTag,
+ UInt32 attributesToSet,
+ UInt32 attributesToClear) ;
+extern long
+PinRect(
+ const Rect * theRect,
+ Point thePt) ;
+extern RgnHandle
+GetGrayRgn(void) ;
+extern Boolean
+TrackBox(
+ WindowRef window,
+ Point thePt,
+ WindowPartCode partCode) ;
+extern Boolean
+TrackGoAway(
+ WindowRef window,
+ Point thePt) ;
+extern long
+DragGrayRgn(
+ RgnHandle theRgn,
+ Point startPt,
+ const Rect * limitRect,
+ const Rect * slopRect,
+ short axis,
+ DragGrayRgnUPP actionProc) ;
+extern long
+DragTheRgn(
+ RgnHandle theRgn,
+ Point startPt,
+ const Rect * limitRect,
+ const Rect * slopRect,
+ short axis,
+ DragGrayRgnUPP actionProc) ;
+extern WindowRef
+GetWindowList(void) ;
+extern CGrafPtr
+GetWindowPort(WindowRef window) ;
+extern CGrafPtr
+GetWindowStructurePort(WindowRef inWindow) ;
+extern short
+GetWindowKind(WindowRef window) ;
+extern Boolean
+IsWindowHilited(WindowRef window) ;
+extern Boolean
+IsWindowUpdatePending(WindowRef window) ;
+extern WindowRef
+GetNextWindow(WindowRef window) ;
+extern WindowRef
+GetPreviousWindow(WindowRef inWindow) ;
+extern Rect *
+GetWindowStandardState(
+ WindowRef window,
+ Rect * rect) ;
+extern Rect *
+GetWindowUserState(
+ WindowRef window,
+ Rect * rect) ;
+extern void
+SetWindowKind(
+ WindowRef window,
+ short kind) ;
+extern void
+SetWindowStandardState(
+ WindowRef window,
+ const Rect * rect) ;
+extern void
+SetWindowUserState(
+ WindowRef window,
+ const Rect * rect) ;
+extern void
+SetPortWindowPort(WindowRef window) ;
+extern Rect *
+GetWindowPortBounds(
+ WindowRef window,
+ Rect * bounds) ;
+extern WindowRef
+GetWindowFromPort(CGrafPtr port) ;
+enum {
+ kWindowGroupAttrSelectable = kWindowGroupAttrSelectAsLayer,
+ kWindowGroupAttrPositionFixed = kWindowGroupAttrMoveTogether,
+ kWindowGroupAttrZOrderFixed = kWindowGroupAttrLayerTogether
+};
+
+
+}
+extern "C" {
+
+
+enum {
+ kTrackMouseLocationOptionDontConsumeMouseUp = (1 << 0)
+};
+
+typedef UInt16 MouseTrackingResult;
+enum {
+ kMouseTrackingMouseDown = 1,
+ kMouseTrackingMouseUp = 2,
+ kMouseTrackingMouseExited = 3,
+ kMouseTrackingMouseEntered = 4,
+ kMouseTrackingMouseDragged = 5,
+ kMouseTrackingKeyModifiersChanged = 6,
+ kMouseTrackingUserCancelled = 7,
+ kMouseTrackingTimedOut = 8,
+ kMouseTrackingMouseMoved = 9
+};
+extern Boolean
+IsUserCancelEventRef(EventRef event) ;
+extern OSStatus
+TrackMouseLocation(
+ GrafPtr inPort,
+ Point * outPt,
+ MouseTrackingResult * outResult) ;
+extern OSStatus
+TrackMouseLocationWithOptions(
+ GrafPtr inPort,
+ OptionBits inOptions,
+ EventTimeout inTimeout,
+ Point * outPt,
+ UInt32 * outModifiers,
+ MouseTrackingResult * outResult) ;
+extern OSStatus
+TrackMouseRegion(
+ GrafPtr inPort,
+ RgnHandle inRegion,
+ Boolean * ioWasInRgn,
+ MouseTrackingResult * outResult) ;
+extern Boolean
+ConvertEventRefToEventRecord(
+ EventRef inEvent,
+ EventRecord * outEvent) ;
+extern Boolean
+IsEventInMask(
+ EventRef inEvent,
+ EventMask inMask) ;
+extern EventTime
+GetLastUserEventTime(void) ;
+extern Boolean
+IsMouseCoalescingEnabled(void) ;
+extern OSStatus
+SetMouseCoalescingEnabled(
+ Boolean inNewState,
+ Boolean * outOldState) ;
+enum {
+
+
+
+
+ kEventClassMouse = 'mous',
+
+
+
+
+ kEventClassKeyboard = 'keyb',
+
+
+
+
+ kEventClassTextInput = 'text',
+
+
+
+
+ kEventClassApplication = 'appl',
+
+
+
+
+ kEventClassAppleEvent = 'eppc',
+
+
+
+
+ kEventClassMenu = 'menu',
+
+
+
+
+ kEventClassWindow = 'wind',
+
+
+
+
+ kEventClassControl = 'cntl',
+
+
+
+
+ kEventClassCommand = 'cmds',
+
+
+
+
+ kEventClassTablet = 'tblt',
+
+
+
+
+ kEventClassVolume = 'vol ',
+
+
+
+
+ kEventClassAppearance = 'appm',
+
+
+
+
+ kEventClassService = 'serv',
+
+
+
+
+ kEventClassToolbar = 'tbar',
+
+
+
+
+ kEventClassToolbarItem = 'tbit',
+
+
+
+
+ kEventClassAccessibility = 'acce'
+};
+enum {
+
+
+
+
+ kEventMouseDown = 1,
+
+
+
+
+ kEventMouseUp = 2,
+
+
+
+
+ kEventMouseMoved = 5,
+
+
+
+
+ kEventMouseDragged = 6,
+
+
+
+
+ kEventMouseEntered = 8,
+
+
+
+
+ kEventMouseExited = 9,
+
+
+
+
+ kEventMouseWheelMoved = 10
+};
+typedef UInt16 EventMouseButton;
+enum {
+
+
+
+
+
+ kEventMouseButtonPrimary = 1,
+
+
+
+
+ kEventMouseButtonSecondary = 2,
+
+
+
+
+ kEventMouseButtonTertiary = 3
+};
+
+
+
+
+
+
+
+typedef UInt16 EventMouseWheelAxis;
+enum {
+
+
+
+
+ kEventMouseWheelAxisX = 0,
+
+
+
+
+ kEventMouseWheelAxisY = 1
+};
+enum {
+
+
+
+
+
+ kEventTextInputUpdateActiveInputArea = 1,
+ kEventTextInputUnicodeForKeyEvent = 2,
+
+
+
+
+
+
+
+ kEventTextInputOffsetToPos = 3,
+ kEventTextInputPosToOffset = 4,
+
+
+
+
+
+
+ kEventTextInputShowHideBottomWindow = 5,
+
+
+
+
+
+ kEventTextInputGetSelectedText = 6,
+ kEventTextInputUnicodeText = 7
+};
+enum {
+
+
+
+
+ kEventRawKeyDown = 1,
+
+
+
+
+ kEventRawKeyRepeat = 2,
+
+
+
+
+ kEventRawKeyUp = 3,
+
+
+
+
+ kEventRawKeyModifiersChanged = 4,
+
+
+
+
+ kEventHotKeyPressed = 5,
+
+
+
+
+ kEventHotKeyReleased = 6
+};
+enum {
+
+
+
+
+ kEventKeyModifierNumLockBit = 16,
+
+
+
+
+ kEventKeyModifierFnBit = 17
+};
+
+enum {
+ kEventKeyModifierNumLockMask = 1L << kEventKeyModifierNumLockBit,
+ kEventKeyModifierFnMask = 1L << kEventKeyModifierFnBit
+};
+enum {
+
+
+
+
+
+
+ kEventAppActivated = 1,
+
+
+
+
+ kEventAppDeactivated = 2,
+ kEventAppQuit = 3,
+
+
+
+
+
+
+ kEventAppLaunchNotification = 4,
+
+
+
+
+
+ kEventAppLaunched = 5,
+
+
+
+
+
+ kEventAppTerminated = 6,
+
+
+
+
+
+ kEventAppFrontSwitched = 7,
+
+
+
+
+
+
+
+ kEventAppFocusMenuBar = 8,
+ kEventAppFocusNextDocumentWindow = 9,
+ kEventAppFocusNextFloatingWindow = 10,
+ kEventAppFocusToolbar = 11,
+ kEventAppGetDockTileMenu = 20,
+
+
+
+
+ kEventAppHidden = 107,
+
+
+
+
+
+ kEventAppShown = 108,
+
+
+
+
+
+ kEventAppSystemUIModeChanged = 109
+};
+enum {
+
+
+
+
+
+ kEventAppleEvent = 1
+};
+enum {
+
+
+
+
+
+
+
+ kEventWindowUpdate = 1,
+
+
+
+
+
+
+ kEventWindowDrawContent = 2
+};
+enum {
+
+
+
+
+
+
+ kEventWindowActivated = 5,
+
+
+
+
+
+
+ kEventWindowDeactivated = 6,
+ kEventWindowGetClickActivation = 7
+};
+enum {
+
+
+
+
+ kEventWindowShowing = 22,
+
+
+
+
+ kEventWindowHiding = 23,
+
+
+
+
+ kEventWindowShown = 24,
+
+
+
+
+ kEventWindowHidden = 25,
+
+
+
+
+
+ kEventWindowCollapsing = 86,
+
+
+
+
+ kEventWindowCollapsed = 67,
+
+
+
+
+
+ kEventWindowExpanding = 87,
+
+
+
+
+ kEventWindowExpanded = 70,
+ kEventWindowZoomed = 76,
+ kEventWindowBoundsChanging = 26,
+
+
+
+
+
+
+
+
+ kEventWindowBoundsChanged = 27,
+
+
+
+
+ kEventWindowResizeStarted = 28,
+
+
+
+
+ kEventWindowResizeCompleted = 29,
+
+
+
+
+ kEventWindowDragStarted = 30,
+
+
+
+
+ kEventWindowDragCompleted = 31,
+
+
+
+
+ kEventWindowClosed = 73
+};
+enum {
+
+
+
+
+
+ kWindowBoundsChangeUserDrag = (1 << 0),
+
+
+
+
+ kWindowBoundsChangeUserResize = (1 << 1),
+
+
+
+
+ kWindowBoundsChangeSizeChanged = (1 << 2),
+
+
+
+
+ kWindowBoundsChangeOriginChanged = (1 << 3),
+ kWindowBoundsChangeZoom = (1 << 4)
+};
+enum {
+
+
+
+
+
+ kEventWindowClickDragRgn = 32,
+
+
+
+
+
+ kEventWindowClickResizeRgn = 33,
+
+
+
+
+
+
+
+ kEventWindowClickCollapseRgn = 34,
+
+
+
+
+
+ kEventWindowClickCloseRgn = 35,
+
+
+
+
+
+ kEventWindowClickZoomRgn = 36,
+
+
+
+
+
+
+
+ kEventWindowClickContentRgn = 37,
+
+
+
+
+
+
+ kEventWindowClickProxyIconRgn = 38,
+
+
+
+
+
+
+ kEventWindowClickToolbarButtonRgn = 41,
+
+
+
+
+
+ kEventWindowClickStructureRgn = 42
+};
+enum {
+ kEventWindowCursorChange = 40
+};
+enum {
+ kEventWindowCollapse = 66,
+ kEventWindowCollapseAll = 68,
+ kEventWindowExpand = 69,
+ kEventWindowExpandAll = 71,
+
+
+
+
+
+
+
+ kEventWindowClose = 72,
+ kEventWindowCloseAll = 74,
+ kEventWindowZoom = 75,
+ kEventWindowZoomAll = 77,
+
+
+
+
+
+
+ kEventWindowContextualMenuSelect = 78,
+
+
+
+
+
+
+ kEventWindowPathSelect = 79,
+
+
+
+
+
+ kEventWindowGetIdealSize = 80,
+ kEventWindowGetMinimumSize = 81,
+ kEventWindowGetMaximumSize = 82,
+ kEventWindowConstrain = 83,
+
+
+
+
+
+
+
+ kEventWindowHandleContentClick = 85,
+ kEventWindowGetDockTileMenu = 90,
+
+
+
+
+
+ kEventWindowProxyBeginDrag = 128,
+
+
+
+
+
+ kEventWindowProxyEndDrag = 129,
+ kEventWindowToolbarSwitchMode = 150
+};
+enum {
+
+
+
+
+
+
+
+ kEventWindowFocusAcquired = 200,
+
+
+
+
+
+
+ kEventWindowFocusRelinquish = 201,
+
+
+
+
+
+
+
+ kEventWindowFocusContent = 202,
+
+
+
+
+
+
+
+ kEventWindowFocusToolbar = 203
+};
+enum {
+
+
+
+
+
+
+ kEventWindowDrawerOpening = 220,
+
+
+
+
+
+ kEventWindowDrawerOpened = 221,
+
+
+
+
+
+
+ kEventWindowDrawerClosing = 222,
+
+
+
+
+
+ kEventWindowDrawerClosed = 223
+};
+enum {
+
+
+
+
+
+
+
+ kEventWindowDrawFrame = 1000,
+
+
+
+
+
+
+ kEventWindowDrawPart = 1001,
+
+
+
+
+
+
+
+ kEventWindowGetRegion = 1002,
+
+
+
+
+
+
+
+ kEventWindowHitTest = 1003,
+ kEventWindowInit = 1004,
+ kEventWindowDispose = 1005,
+
+
+
+
+
+
+ kEventWindowDragHilite = 1006,
+
+
+
+
+
+
+ kEventWindowModified = 1007,
+
+
+
+
+
+
+ kEventWindowSetupProxyDragImage = 1008,
+
+
+
+
+
+ kEventWindowStateChanged = 1009,
+
+
+
+
+
+ kEventWindowMeasureTitle = 1010,
+ kEventWindowDrawGrowBox = 1011,
+ kEventWindowGetGrowImageRegion = 1012,
+ kEventWindowPaint = 1013
+};
+enum {
+ kEventMenuBeginTracking = 1,
+
+
+
+
+ kEventMenuEndTracking = 2,
+
+
+
+
+
+
+
+ kEventMenuChangeTrackingMode = 3,
+ kEventMenuOpening = 4,
+
+
+
+
+ kEventMenuClosed = 5,
+
+
+
+
+
+ kEventMenuTargetItem = 6,
+ kEventMenuMatchKey = 7,
+ kEventMenuEnableItems = 8,
+ kEventMenuPopulate = 9,
+ kEventMenuMeasureItemWidth = 100,
+ kEventMenuMeasureItemHeight = 101,
+ kEventMenuDrawItem = 102,
+ kEventMenuDrawItemContent = 103,
+
+
+
+
+ kEventMenuDispose = 1001
+};
+
+
+
+
+
+
+
+enum {
+
+
+
+
+
+
+
+ kMenuContextMenuBar = 1 << 0,
+
+
+
+
+
+ kMenuContextPullDown = 1 << 8,
+
+
+
+
+
+ kMenuContextPopUp = 1 << 9,
+
+
+
+
+
+ kMenuContextSubmenu = 1 << 10,
+
+
+
+
+
+ kMenuContextMenuBarTracking = 1 << 16,
+
+
+
+
+
+ kMenuContextPopUpTracking = 1 << 17,
+
+
+
+
+
+ kMenuContextKeyMatching = 1 << 18,
+ kMenuContextMenuEnabling = 1 << 19,
+
+
+
+
+
+
+
+ kMenuContextCommandIDSearch = 1 << 20
+};
+enum {
+ kEventProcessCommand = 1,
+ kEventCommandProcess = 1,
+ kEventCommandUpdateStatus = 2
+};
+enum {
+
+
+
+
+ kHICommandOK = 'ok ',
+
+
+
+
+ kHICommandCancel = 'not!',
+
+
+
+
+ kHICommandQuit = 'quit',
+
+
+
+
+ kHICommandUndo = 'undo',
+
+
+
+
+ kHICommandRedo = 'redo',
+
+
+
+
+ kHICommandCut = 'cut ',
+
+
+
+
+ kHICommandCopy = 'copy',
+
+
+
+
+ kHICommandPaste = 'past',
+
+
+
+
+ kHICommandClear = 'clea',
+
+
+
+
+ kHICommandSelectAll = 'sall',
+
+
+
+
+
+
+ kHICommandHide = 'hide',
+
+
+
+
+
+
+ kHICommandHideOthers = 'hido',
+
+
+
+
+
+
+ kHICommandShowAll = 'shal',
+
+
+
+
+ kHICommandPreferences = 'pref',
+ kHICommandZoomWindow = 'zoom',
+
+
+
+
+
+
+ kHICommandMinimizeWindow = 'mini',
+
+
+
+
+
+
+
+ kHICommandMinimizeAll = 'mina',
+
+
+
+
+
+
+ kHICommandMaximizeWindow = 'maxi',
+
+
+
+
+
+
+
+ kHICommandMaximizeAll = 'maxa',
+
+
+
+
+
+
+ kHICommandArrangeInFront = 'frnt',
+
+
+
+
+
+
+
+ kHICommandBringAllToFront = 'bfrt',
+ kHICommandWindowListSeparator = 'wldv',
+ kHICommandWindowListTerminator = 'wlst',
+
+
+
+
+
+
+ kHICommandSelectWindow = 'swin',
+ kHICommandRotateWindowsForward = 'rotw',
+ kHICommandRotateWindowsBackward = 'rotb',
+ kHICommandRotateFloatingWindowsForward = 'rtfw',
+ kHICommandRotateFloatingWindowsBackward = 'rtfb',
+
+
+
+
+ kHICommandAbout = 'abou',
+
+
+
+
+ kHICommandNew = 'new ',
+
+
+
+
+ kHICommandOpen = 'open',
+
+
+
+
+ kHICommandClose = 'clos',
+
+
+
+
+ kHICommandSave = 'save',
+
+
+
+
+ kHICommandSaveAs = 'svas',
+
+
+
+
+
+ kHICommandRevert = 'rvrt',
+
+
+
+
+ kHICommandPrint = 'prnt',
+
+
+
+
+
+ kHICommandPageSetup = 'page',
+
+
+
+
+
+
+
+ kHICommandAppHelp = 'ahlp'
+};
+enum {
+
+
+
+
+
+ kHICommandFromMenu = (1L << 0),
+
+
+
+
+
+ kHICommandFromControl = (1L << 1),
+
+
+
+
+
+ kHICommandFromWindow = (1L << 2)
+};
+
+struct HICommand {
+ UInt32 attributes;
+ UInt32 commandID;
+ struct {
+ MenuRef menuRef;
+ MenuItemIndex menuItemIndex;
+ } menu;
+};
+typedef struct HICommand HICommand;
+struct HICommandExtended {
+ UInt32 attributes;
+ UInt32 commandID;
+ union {
+ ControlRef control;
+ WindowRef window;
+ struct {
+ MenuRef menuRef;
+ MenuItemIndex menuItemIndex;
+ } menu;
+ } source;
+};
+typedef struct HICommandExtended HICommandExtended;
+enum {
+
+
+
+
+ kEventControlInitialize = 1000,
+
+
+
+
+ kEventControlDispose = 1001,
+ kEventControlGetOptimalBounds = 1003,
+ kEventControlDefInitialize = kEventControlInitialize,
+ kEventControlDefDispose = kEventControlDispose,
+
+
+
+
+
+ kEventControlHit = 1,
+ kEventControlSimulateHit = 2,
+
+
+
+
+
+
+
+ kEventControlHitTest = 3,
+
+
+
+
+
+
+ kEventControlDraw = 4,
+
+
+
+
+
+
+
+ kEventControlApplyBackground = 5,
+ kEventControlApplyTextColor = 6,
+ kEventControlSetFocusPart = 7,
+
+
+
+
+
+
+ kEventControlGetFocusPart = 8,
+
+
+
+
+
+ kEventControlActivate = 9,
+
+
+
+
+
+ kEventControlDeactivate = 10,
+
+
+
+
+
+ kEventControlSetCursor = 11,
+
+
+
+
+
+
+ kEventControlContextualMenuClick = 12,
+
+
+
+
+
+
+
+ kEventControlClick = 13,
+ kEventControlGetNextFocusCandidate = 14,
+
+
+
+
+
+
+ kEventControlGetAutoToggleValue = 15,
+ kEventControlInterceptSubviewClick = 16,
+ kEventControlGetClickActivation = 17,
+ kEventControlDragEnter = 18,
+
+
+
+
+
+
+
+ kEventControlDragWithin = 19,
+
+
+
+
+
+ kEventControlDragLeave = 20,
+
+
+
+
+ kEventControlDragReceive = 21,
+
+
+
+
+
+
+
+ kEventControlTrack = 51,
+ kEventControlGetScrollToHereStartPoint = 52,
+
+
+
+
+
+
+ kEventControlGetIndicatorDragConstraint = 53,
+
+
+
+
+
+
+
+ kEventControlIndicatorMoved = 54,
+
+
+
+
+
+ kEventControlGhostingFinished = 55,
+
+
+
+
+
+
+
+ kEventControlGetActionProcPart = 56,
+
+
+
+
+
+
+
+ kEventControlGetPartRegion = 101,
+
+
+
+
+
+
+
+ kEventControlGetPartBounds = 102,
+
+
+
+
+
+ kEventControlSetData = 103,
+
+
+
+
+
+ kEventControlGetData = 104,
+ kEventControlGetSizeConstraints = 105,
+
+
+
+
+
+
+ kEventControlValueFieldChanged = 151,
+
+
+
+
+
+ kEventControlAddedSubControl = 152,
+
+
+
+
+
+ kEventControlRemovingSubControl = 153,
+
+
+
+
+
+ kEventControlBoundsChanged = 154,
+
+
+
+
+
+ kEventControlTitleChanged = 158,
+
+
+
+
+
+
+ kEventControlOwningWindowChanged = 159,
+
+
+
+
+
+
+
+ kEventControlHiliteChanged = 160,
+
+
+
+
+
+
+
+ kEventControlEnabledStateChanged = 161,
+
+
+
+
+
+ kEventControlArbitraryMessage = 201
+};
+enum {
+
+
+
+
+ kControlBoundsChangeSizeChanged = (1 << 2),
+
+
+
+
+ kControlBoundsChangePositionChanged = (1 << 3)
+};
+enum {
+
+
+
+
+
+ kEventTabletPoint = 1,
+
+
+
+
+
+ kEventTabletProximity = 2,
+ kEventTabletPointer = 1
+};
+
+struct TabletPointRec {
+ SInt32 absX;
+ SInt32 absY;
+ SInt32 absZ;
+ UInt16 buttons;
+ UInt16 pressure;
+ SInt16 tiltX;
+ SInt16 tiltY;
+ UInt16 rotation;
+ SInt16 tangentialPressure;
+ UInt16 deviceID;
+ SInt16 vendor1;
+ SInt16 vendor2;
+ SInt16 vendor3;
+};
+typedef struct TabletPointRec TabletPointRec;
+typedef TabletPointRec TabletPointerRec;
+struct TabletProximityRec {
+ UInt16 vendorID;
+ UInt16 tabletID;
+ UInt16 pointerID;
+ UInt16 deviceID;
+ UInt16 systemTabletID;
+ UInt16 vendorPointerType;
+ UInt32 pointerSerialNumber;
+ UInt64 uniqueID;
+ UInt32 capabilityMask;
+ UInt8 pointerType;
+ UInt8 enterProximity;
+};
+typedef struct TabletProximityRec TabletProximityRec;
+enum {
+
+
+
+
+
+ kEventVolumeMounted = 1,
+
+
+
+
+
+ kEventVolumeUnmounted = 2
+};
+enum {
+ typeFSVolumeRefNum = 'voln'
+};
+enum {
+
+
+
+
+
+ kEventAppearanceScrollBarVariantChanged = 1
+};
+enum {
+
+
+
+
+
+
+ kEventServiceCopy = 1,
+
+
+
+
+
+
+ kEventServicePaste = 2,
+ kEventServiceGetTypes = 3,
+ kEventServicePerform = 4
+};
+extern CFStringRef
+CreateTypeStringWithOSType(OSType inType) ;
+enum {
+ kEventAccessibleGetChildAtPoint = 1,
+ kEventAccessibleGetFocusedChild = 2,
+
+
+
+
+
+
+ kEventAccessibleGetAllAttributeNames = 21,
+
+
+
+
+
+
+
+ kEventAccessibleGetNamedAttribute = 22,
+ kEventAccessibleSetNamedAttribute = 23,
+ kEventAccessibleIsNamedAttributeSettable = 24,
+
+
+
+
+
+
+ kEventAccessibleGetAllActionNames = 41,
+
+
+
+
+
+
+ kEventAccessiblePerformNamedAction = 42,
+ kEventAccessibleGetNamedActionDescription = 44
+};
+extern AXUIElementRef
+AXUIElementCreateWithHIObjectAndIdentifier(
+ HIObjectRef inHIObject,
+ UInt64 inIdentifier) ;
+extern HIObjectRef
+AXUIElementGetHIObject(AXUIElementRef inUIElement) ;
+extern void
+AXUIElementGetIdentifier(
+ AXUIElementRef inUIElement,
+ UInt64 * outIdentifier) ;
+extern void
+AXNotificationHIObjectNotify(
+ CFStringRef inNotification,
+ HIObjectRef inHIObject,
+ UInt64 inIdentifier) ;
+
+
+
+
+
+enum {
+ kEventParamDirectObject = '----'
+};
+
+
+
+
+enum {
+ kEventParamPostTarget = 'ptrg',
+
+
+
+
+ typeEventTargetRef = 'etrg'
+};
+
+
+
+enum {
+ kEventParamWindowRef = 'wind',
+ kEventParamGrafPort = 'graf',
+ kEventParamDragRef = 'drag',
+ kEventParamMenuRef = 'menu',
+ kEventParamEventRef = 'evnt',
+ kEventParamControlRef = 'ctrl',
+ kEventParamRgnHandle = 'rgnh',
+ kEventParamEnabled = 'enab',
+ kEventParamDimensions = 'dims',
+ kEventParamAvailableBounds = 'avlb',
+ kEventParamAEEventID = keyAEEventID,
+ kEventParamAEEventClass = keyAEEventClass,
+ kEventParamCGContextRef = 'cntx',
+ kEventParamDeviceDepth = 'devd',
+ kEventParamDeviceColor = 'devc',
+ kEventParamMutableArray = 'marr',
+ kEventParamResult = 'ansr',
+ kEventParamMinimumSize = 'mnsz',
+ kEventParamMaximumSize = 'mxsz',
+ typeWindowRef = 'wind',
+ typeGrafPtr = 'graf',
+ typeGWorldPtr = 'gwld',
+ typeDragRef = 'drag',
+ typeMenuRef = 'menu',
+ typeControlRef = 'ctrl',
+ typeCollection = 'cltn',
+ typeQDRgnHandle = 'rgnh',
+ typeOSStatus = 'osst',
+ typeCFStringRef = 'cfst',
+ typeCFMutableStringRef = 'cfms',
+ typeCFIndex = 'cfix',
+ typeCFTypeRef = 'cfty',
+ typeCGContextRef = 'cntx',
+ typeHIPoint = 'hipt',
+ typeHISize = 'hisz',
+ typeHIRect = 'hirc',
+ typeVoidPtr = 'void'
+};
+
+
+
+enum {
+ kEventParamMouseLocation = 'mloc',
+ kEventParamWindowMouseLocation = 'wmou',
+ kEventParamMouseButton = 'mbtn',
+ kEventParamClickCount = 'ccnt',
+ kEventParamMouseWheelAxis = 'mwax',
+ kEventParamMouseWheelDelta = 'mwdl',
+ kEventParamMouseDelta = 'mdta',
+ kEventParamMouseChord = 'chor',
+ kEventParamTabletEventType = 'tblt',
+ kEventParamMouseTrackingRef = 'mtrf',
+ typeMouseButton = 'mbtn',
+ typeMouseWheelAxis = 'mwax',
+ typeMouseTrackingRef = 'mtrf'
+};
+
+
+
+enum {
+ kEventParamKeyCode = 'kcod',
+ kEventParamKeyMacCharCodes = 'kchr',
+ kEventParamKeyModifiers = 'kmod',
+ kEventParamKeyUnicodes = 'kuni',
+ kEventParamKeyboardType = 'kbdt',
+ typeEventHotKeyID = 'hkid'
+};
+
+
+
+enum {
+ kEventParamTextInputSendRefCon = 'tsrc',
+ kEventParamTextInputSendComponentInstance = 'tsci',
+ kEventParamTextInputSendSLRec = 'tssl',
+ kEventParamTextInputReplySLRec = 'trsl',
+ kEventParamTextInputSendText = 'tstx',
+ kEventParamTextInputReplyText = 'trtx',
+ kEventParamTextInputSendUpdateRng = 'tsup',
+ kEventParamTextInputSendHiliteRng = 'tshi',
+ kEventParamTextInputSendClauseRng = 'tscl',
+ kEventParamTextInputSendPinRng = 'tspn',
+ kEventParamTextInputSendFixLen = 'tsfx',
+ kEventParamTextInputSendLeadingEdge = 'tsle',
+ kEventParamTextInputReplyLeadingEdge = 'trle',
+ kEventParamTextInputSendTextOffset = 'tsto',
+ kEventParamTextInputReplyTextOffset = 'trto',
+ kEventParamTextInputReplyRegionClass = 'trrg',
+ kEventParamTextInputSendCurrentPoint = 'tscp',
+ kEventParamTextInputSendDraggingMode = 'tsdm',
+ kEventParamTextInputReplyPoint = 'trpt',
+ kEventParamTextInputReplyFont = 'trft',
+ kEventParamTextInputReplyFMFont = 'trfm',
+ kEventParamTextInputReplyPointSize = 'trpz',
+ kEventParamTextInputReplyLineHeight = 'trlh',
+ kEventParamTextInputReplyLineAscent = 'trla',
+ kEventParamTextInputReplyTextAngle = 'trta',
+ kEventParamTextInputSendShowHide = 'tssh',
+ kEventParamTextInputReplyShowHide = 'trsh',
+ kEventParamTextInputSendKeyboardEvent = 'tske',
+ kEventParamTextInputSendTextServiceEncoding = 'tsse',
+ kEventParamTextInputSendTextServiceMacEncoding = 'tssm',
+ kEventParamTextInputGlyphInfoArray = 'glph'
+};
+
+
+
+enum {
+ kEventParamHICommand = 'hcmd',
+ typeHICommand = 'hcmd'
+};
+
+
+
+enum {
+ kEventParamWindowFeatures = 'wftr',
+ kEventParamWindowDefPart = 'wdpc',
+ kEventParamCurrentBounds = 'crct',
+ kEventParamOriginalBounds = 'orct',
+ kEventParamPreviousBounds = 'prct',
+ kEventParamClickActivation = 'clac',
+ kEventParamWindowRegionCode = 'wshp',
+ kEventParamWindowDragHiliteFlag = 'wdhf',
+ kEventParamWindowModifiedFlag = 'wmff',
+ kEventParamWindowProxyGWorldPtr = 'wpgw',
+ kEventParamWindowProxyImageRgn = 'wpir',
+ kEventParamWindowProxyOutlineRgn = 'wpor',
+ kEventParamWindowStateChangedFlags = 'wscf',
+ kEventParamWindowTitleFullWidth = 'wtfw',
+ kEventParamWindowTitleTextWidth = 'wttw',
+ kEventParamWindowGrowRect = 'grct',
+ kEventParamAttributes = 'attr',
+ kEventParamPreviousDockRect = 'pdrc',
+ kEventParamCurrentDockRect = 'cdrc',
+ typeWindowRegionCode = 'wshp',
+ typeWindowDefPartCode = 'wdpt',
+ typeClickActivationResult = 'clac'
+};
+
+
+
+enum {
+ kEventParamControlPart = 'cprt',
+ kEventParamInitCollection = 'icol',
+ kEventParamControlMessage = 'cmsg',
+ kEventParamControlParam = 'cprm',
+ kEventParamControlResult = 'crsl',
+ kEventParamControlRegion = 'crgn',
+ kEventParamControlAction = 'caup',
+ kEventParamControlIndicatorDragConstraint = 'cidc',
+ kEventParamControlIndicatorRegion = 'cirn',
+ kEventParamControlIsGhosting = 'cgst',
+ kEventParamControlIndicatorOffset = 'ciof',
+ kEventParamControlClickActivationResult = 'ccar',
+ kEventParamControlSubControl = 'csub',
+ kEventParamControlOptimalBounds = 'cobn',
+ kEventParamControlOptimalBaselineOffset = 'cobo',
+ kEventParamControlDataTag = 'cdtg',
+ kEventParamControlDataBuffer = 'cdbf',
+ kEventParamControlDataBufferSize = 'cdbs',
+ kEventParamControlDrawDepth = 'cddp',
+ kEventParamControlDrawInColor = 'cdic',
+ kEventParamControlFeatures = 'cftr',
+ kEventParamControlPartBounds = 'cpbd',
+ kEventParamControlOriginalOwningWindow = 'coow',
+ kEventParamControlCurrentOwningWindow = 'ccow',
+ kEventParamControlFocusEverything = 'cfev',
+ kEventParamNextControl = 'cnxc',
+ kEventParamStartControl = 'cstc',
+ kEventParamControlSubview = 'csvw',
+ kEventParamControlPreviousPart = 'copc',
+ kEventParamControlCurrentPart = 'cnpc',
+ kEventParamControlInvalRgn = 'civr',
+ kEventParamControlValue = 'cval',
+ typeControlActionUPP = 'caup',
+ typeIndicatorDragConstraint = 'cidc',
+ typeControlPartCode = 'cprt'
+};
+
+
+
+enum {
+ kEventParamCurrentMenuTrackingMode = 'cmtm',
+ kEventParamNewMenuTrackingMode = 'nmtm',
+ kEventParamMenuFirstOpen = '1sto',
+ kEventParamMenuItemIndex = 'item',
+ kEventParamMenuCommand = 'mcmd',
+ kEventParamEnableMenuForKeyEvent = 'fork',
+ kEventParamMenuEventOptions = 'meop',
+ kEventParamMenuContext = 'mctx',
+ kEventParamMenuItemBounds = 'mitb',
+ kEventParamMenuMarkBounds = 'mmkb',
+ kEventParamMenuIconBounds = 'micb',
+ kEventParamMenuTextBounds = 'mtxb',
+ kEventParamMenuTextBaseline = 'mtbl',
+ kEventParamMenuCommandKeyBounds = 'mcmb',
+ kEventParamMenuVirtualTop = 'mvrt',
+ kEventParamMenuVirtualBottom = 'mvrb',
+ kEventParamMenuDrawState = 'mdrs',
+ kEventParamMenuItemType = 'mitp',
+ kEventParamMenuItemWidth = 'mitw',
+ kEventParamMenuItemHeight = 'mith',
+ typeMenuItemIndex = 'midx',
+ typeMenuCommand = 'mcmd',
+ typeMenuTrackingMode = 'mtmd',
+ typeMenuEventOptions = 'meop',
+ typeThemeMenuState = 'tmns',
+ typeThemeMenuItemType = 'tmit'
+};
+
+
+
+enum {
+ kEventParamProcessID = 'psn ',
+ kEventParamLaunchRefCon = 'lref',
+ kEventParamLaunchErr = 'err ',
+ kEventParamSystemUIMode = 'uimd'
+};
+
+
+
+enum {
+ kEventParamTabletPointRec = 'tbrc',
+ kEventParamTabletProximityRec = 'tbpx',
+ typeTabletPointRec = 'tbrc',
+ typeTabletProximityRec = 'tbpx',
+ kEventParamTabletPointerRec = 'tbrc',
+ typeTabletPointerRec = 'tbrc'
+};
+
+
+
+enum {
+ kEventParamNewScrollBarVariant = 'nsbv'
+};
+
+
+
+enum {
+ kEventParamScrapRef = 'scrp',
+ kEventParamServiceCopyTypes = 'svsd',
+ kEventParamServicePasteTypes = 'svpt',
+ kEventParamServiceMessageName = 'svmg',
+ kEventParamServiceUserData = 'svud',
+ typeScrapRef = 'scrp',
+ typeCFMutableArrayRef = 'cfma'
+};
+
+
+
+enum {
+ kEventParamToolbar = 'tbar',
+ kEventParamToolbarItem = 'tbit',
+ kEventParamToolbarItemIdentifier = 'tbii',
+ kEventParamToolbarItemConfigData = 'tbid',
+ typeHIToolbarRef = 'tbar',
+ typeHIToolbarItemRef = 'tbit'
+};
+
+
+
+enum {
+ kEventParamAccessibleObject = 'aobj',
+ kEventParamAccessibleChild = 'achl',
+ kEventParamAccessibleAttributeName = 'atnm',
+ kEventParamAccessibleAttributeNames = 'atns',
+ kEventParamAccessibleAttributeValue = 'atvl',
+ kEventParamAccessibleAttributeSettable = 'atst',
+ kEventParamAccessibleActionName = 'acnm',
+ kEventParamAccessibleActionNames = 'acns',
+ kEventParamAccessibleActionDescription = 'acds'
+};
+extern EventTargetRef
+GetWindowEventTarget(WindowRef inWindow) ;
+extern EventTargetRef
+GetControlEventTarget(ControlRef inControl) ;
+extern EventTargetRef
+GetMenuEventTarget(MenuRef inMenu) ;
+extern EventTargetRef
+GetApplicationEventTarget(void) ;
+extern EventTargetRef
+GetUserFocusEventTarget(void) ;
+extern EventTargetRef
+GetEventDispatcherTarget(void) ;
+typedef struct OpaqueToolboxObjectClassRef* ToolboxObjectClassRef;
+extern OSStatus
+RegisterToolboxObjectClass(
+ CFStringRef inClassID,
+ ToolboxObjectClassRef inBaseClass,
+ UInt32 inNumEvents,
+ const EventTypeSpec * inEventList,
+ EventHandlerUPP inEventHandler,
+ void * inEventHandlerData,
+ ToolboxObjectClassRef * outClassRef) ;
+extern OSStatus
+UnregisterToolboxObjectClass(ToolboxObjectClassRef inClassRef) ;
+extern OSStatus
+ProcessHICommand(const HICommand * inCommand) ;
+extern void
+RunApplicationEventLoop(void) ;
+extern void
+QuitApplicationEventLoop(void) ;
+extern OSStatus
+RunAppModalLoopForWindow(WindowRef inWindow) ;
+extern OSStatus
+QuitAppModalLoopForWindow(WindowRef inWindow) ;
+extern OSStatus
+BeginAppModalStateForWindow(WindowRef inWindow) ;
+extern OSStatus
+EndAppModalStateForWindow(WindowRef inWindow) ;
+extern OSStatus
+SetUserFocusWindow(WindowRef inWindow) ;
+extern WindowRef
+GetUserFocusWindow(void) ;
+extern OSStatus
+SetWindowDefaultButton(
+ WindowRef inWindow,
+ ControlRef inControl) ;
+extern OSStatus
+SetWindowCancelButton(
+ WindowRef inWindow,
+ ControlRef inControl) ;
+extern OSStatus
+GetWindowDefaultButton(
+ WindowRef inWindow,
+ ControlRef * outControl) ;
+extern OSStatus
+GetWindowCancelButton(
+ WindowRef inWindow,
+ ControlRef * outControl) ;
+
+
+
+
+
+
+struct EventHotKeyID {
+ OSType signature;
+ UInt32 id;
+};
+typedef struct EventHotKeyID EventHotKeyID;
+typedef struct OpaqueEventHotKeyRef* EventHotKeyRef;
+extern OSStatus
+RegisterEventHotKey(
+ UInt32 inHotKeyCode,
+ UInt32 inHotKeyModifiers,
+ EventHotKeyID inHotKeyID,
+ EventTargetRef inTarget,
+ OptionBits inOptions,
+ EventHotKeyRef * outRef) ;
+extern OSStatus
+UnregisterEventHotKey(EventHotKeyRef inHotKey) ;
+typedef struct OpaqueMouseTrackingRef* MouseTrackingRef;
+typedef UInt32 MouseTrackingOptions;
+enum {
+
+
+
+
+
+ kMouseTrackingOptionsLocalClip = 0,
+
+
+
+
+
+ kMouseTrackingOptionsGlobalClip = 1,
+
+
+
+
+
+ kMouseTrackingOptionsStandard = kMouseTrackingOptionsLocalClip
+};
+
+struct MouseTrackingRegionID {
+ OSType signature;
+ SInt32 id;
+};
+typedef struct MouseTrackingRegionID MouseTrackingRegionID;
+extern OSStatus
+CreateMouseTrackingRegion(
+ WindowRef inWindow,
+ RgnHandle inRegion,
+ RgnHandle inClip,
+ MouseTrackingOptions inOptions,
+ MouseTrackingRegionID inID,
+ void * inRefCon,
+ EventTargetRef inTargetToNotify,
+ MouseTrackingRef * outTrackingRef) ;
+extern OSStatus
+RetainMouseTrackingRegion(MouseTrackingRef inMouseRef) ;
+extern OSStatus
+ReleaseMouseTrackingRegion(MouseTrackingRef inMouseRef) ;
+extern OSStatus
+ChangeMouseTrackingRegion(
+ MouseTrackingRef inMouseRef,
+ RgnHandle inRegion,
+ RgnHandle inClip) ;
+extern OSStatus
+ClipMouseTrackingRegion(
+ MouseTrackingRef inMouseRef,
+ RgnHandle inRegion) ;
+extern OSStatus
+GetMouseTrackingRegionID(
+ MouseTrackingRef inMouseRef,
+ MouseTrackingRegionID * outID) ;
+extern OSStatus
+GetMouseTrackingRegionRefCon(
+ MouseTrackingRef inMouseRef,
+ void ** outRefCon) ;
+extern OSStatus
+MoveMouseTrackingRegion(
+ MouseTrackingRef inMouseRef,
+ SInt16 deltaH,
+ SInt16 deltaV,
+ RgnHandle inClip) ;
+extern OSStatus
+SetMouseTrackingRegionEnabled(
+ MouseTrackingRef inMouseRef,
+ Boolean inEnabled) ;
+extern OSStatus
+ClipWindowMouseTrackingRegions(
+ WindowRef inWindow,
+ OSType inSignature,
+ RgnHandle inClip) ;
+extern OSStatus
+MoveWindowMouseTrackingRegions(
+ WindowRef inWindow,
+ OSType inSignature,
+ SInt16 deltaH,
+ SInt16 deltaV,
+ RgnHandle inClip) ;
+extern OSStatus
+SetWindowMouseTrackingRegionsEnabled(
+ WindowRef inWindow,
+ OSType inSignature,
+ Boolean inEnabled) ;
+extern OSStatus
+ReleaseWindowMouseTrackingRegions(
+ WindowRef inWindow,
+ OSType inSignature) ;
+
+
+
+
+
+
+enum {
+ kEventWindowDefDrawFrame = kEventWindowDrawFrame,
+ kEventWindowDefDrawPart = kEventWindowDrawPart,
+ kEventWindowDefGetRegion = kEventWindowGetRegion,
+ kEventWindowDefHitTest = kEventWindowHitTest,
+ kEventWindowDefInit = kEventWindowInit,
+ kEventWindowDefDispose = kEventWindowDispose,
+ kEventWindowDefDragHilite = kEventWindowDragHilite,
+ kEventWindowDefModified = kEventWindowModified,
+ kEventWindowDefSetupProxyDragImage = kEventWindowSetupProxyDragImage,
+ kEventWindowDefStateChanged = kEventWindowStateChanged,
+ kEventWindowDefMeasureTitle = kEventWindowMeasureTitle,
+ kEventWindowDefDrawGrowBox = kEventWindowDrawGrowBox,
+ kEventWindowDefGetGrowImageRegion = kEventWindowGetGrowImageRegion
+};
+
+
+enum {
+ kEventClassEPPC = kEventClassAppleEvent,
+ kEventHighLevelEvent = kEventAppleEvent
+};
+
+enum {
+ kEventUpdateActiveInputArea = kEventTextInputUpdateActiveInputArea,
+ kEventUnicodeForKeyEvent = kEventTextInputUnicodeForKeyEvent,
+ kEventOffsetToPos = kEventTextInputOffsetToPos,
+ kEventPosToOffset = kEventTextInputPosToOffset,
+ kEventShowHideBottomWindow = kEventTextInputShowHideBottomWindow,
+ kEventGetSelectedText = kEventTextInputGetSelectedText
+};
+
+
+
+
+
+typedef UInt32 EventClassID;
+typedef UInt32 EventClass;
+typedef UInt32 EventType;
+
+
+
+enum {
+ kMouseTrackingMousePressed = kMouseTrackingMouseDown,
+ kMouseTrackingMouseReleased = kMouseTrackingMouseUp
+};
+
+enum {
+ kEventControlGetSubviewForMouseEvent = kEventControlInterceptSubviewClick
+};
+
+
+
+
+}
+extern "C" {
+
+
+
+typedef ControlRef HIViewRef;
+typedef ControlID HIViewID;
+typedef ControlPartCode HIViewPartCode;
+extern const HIViewID kHIViewWindowContentID;
+extern const HIViewID kHIViewWindowGrowBoxID;
+
+
+
+
+
+
+enum {
+
+
+
+
+ kHIViewZOrderAbove = 1,
+
+
+
+
+ kHIViewZOrderBelow = 2
+};
+
+typedef UInt32 HIViewZOrderOp;
+enum {
+
+
+
+
+
+
+
+ kHIViewSendCommandToUserFocus = (1 << 0)
+};
+extern HIViewRef
+HIViewGetRoot(WindowRef inWindow) ;
+extern OSStatus
+HIViewAddSubview(
+ HIViewRef inParent,
+ HIViewRef inNewChild) ;
+extern OSStatus
+HIViewRemoveFromSuperview(HIViewRef inView) ;
+extern HIViewRef
+HIViewGetSuperview(HIViewRef inView) ;
+extern HIViewRef
+HIViewGetFirstSubview(HIViewRef inView) ;
+extern HIViewRef
+HIViewGetLastSubview(HIViewRef inView) ;
+extern HIViewRef
+HIViewGetNextView(HIViewRef inView) ;
+extern HIViewRef
+HIViewGetPreviousView(HIViewRef inView) ;
+extern OSStatus
+HIViewSetZOrder(
+ HIViewRef inView,
+ HIViewZOrderOp inOp,
+ HIViewRef inOther) ;
+extern OSStatus
+HIViewSetVisible(
+ HIViewRef inView,
+ Boolean inVisible) ;
+extern Boolean
+HIViewIsVisible(HIViewRef inView) ;
+extern OSStatus
+HIViewGetBounds(
+ HIViewRef inView,
+ HIRect * outRect) ;
+extern OSStatus
+HIViewGetFrame(
+ HIViewRef inView,
+ HIRect * outRect) ;
+extern OSStatus
+HIViewSetFrame(
+ HIViewRef inView,
+ const HIRect * inRect) ;
+extern OSStatus
+HIViewMoveBy(
+ HIViewRef inView,
+ float inDX,
+ float inDY) ;
+extern OSStatus
+HIViewPlaceInSuperviewAt(
+ HIViewRef inView,
+ float inX,
+ float inY) ;
+extern OSStatus
+HIViewReshapeStructure(HIViewRef inView) ;
+extern OSStatus
+HIViewGetViewForMouseEvent(
+ HIViewRef inView,
+ EventRef inEvent,
+ HIViewRef * outView) ;
+extern OSStatus
+HIViewClick(
+ HIViewRef inView,
+ EventRef inEvent) ;
+extern OSStatus
+HIViewSimulateClick(
+ HIViewRef inView,
+ HIViewPartCode inPartToClick,
+ UInt32 inModifiers,
+ ControlPartCode * outPartClicked) ;
+extern OSStatus
+HIViewGetPartHit(
+ HIViewRef inView,
+ const HIPoint * inPoint,
+ HIViewPartCode * outPart) ;
+extern OSStatus
+HIViewGetSubviewHit(
+ HIViewRef inView,
+ const HIPoint * inPoint,
+ Boolean inDeep,
+ HIViewRef * outView) ;
+extern Boolean
+HIViewGetNeedsDisplay(HIViewRef inView) ;
+extern OSStatus
+HIViewSetNeedsDisplay(
+ HIViewRef inView,
+ Boolean inNeedsDisplay) ;
+extern OSStatus
+HIViewSetNeedsDisplayInRegion(
+ HIViewRef inView,
+ RgnHandle inRgn,
+ Boolean inNeedsDisplay) ;
+extern OSStatus
+HIViewFlashDirtyArea(WindowRef inWindow) ;
+extern OSStatus
+HIViewGetSizeConstraints(
+ HIViewRef inView,
+ HISize * outMinSize,
+ HISize * outMaxSize) ;
+extern OSStatus
+HIViewConvertPoint(
+ HIPoint * ioPoint,
+ HIViewRef inSourceView,
+ HIViewRef inDestView) ;
+extern OSStatus
+HIViewConvertRect(
+ HIRect * ioRect,
+ HIViewRef inSourceView,
+ HIViewRef inDestView) ;
+extern OSStatus
+HIViewConvertRegion(
+ RgnHandle ioRgn,
+ HIViewRef inSourceView,
+ HIViewRef inDestView) ;
+extern OSStatus
+HIViewSetDrawingEnabled(
+ HIViewRef inView,
+ Boolean inEnabled) ;
+extern Boolean
+HIViewIsDrawingEnabled(HIViewRef inView) ;
+extern OSStatus
+HIViewScrollRect(
+ HIViewRef inView,
+ const HIRect * inRect,
+ float inDX,
+ float inDY) ;
+extern OSStatus
+HIViewSetBoundsOrigin(
+ HIViewRef inView,
+ float inX,
+ float inY) ;
+extern OSStatus
+HIViewAdvanceFocus(
+ HIViewRef inRootForFocus,
+ EventModifiers inModifiers) ;
+extern OSStatus
+HIViewGetFocusPart(
+ HIViewRef inView,
+ HIViewPartCode * outFocusPart) ;
+extern Boolean
+HIViewSubtreeContainsFocus(HIViewRef inSubtreeStart) ;
+extern OSStatus
+HIViewSetNextFocus(
+ HIViewRef inView,
+ HIViewRef inNextFocus) ;
+extern OSStatus
+HIViewSetFirstSubViewFocus(
+ HIViewRef inParent,
+ HIViewRef inSubView) ;
+extern OSStatus
+HIViewFindByID(
+ HIViewRef inStartView,
+ HIViewID inID,
+ HIViewRef * outControl) ;
+extern OSStatus
+HIViewGetAttributes(
+ HIViewRef inView,
+ OptionBits * outAttrs) ;
+extern OSStatus
+HIViewChangeAttributes(
+ HIViewRef inView,
+ OptionBits inAttrsToSet,
+ OptionBits inAttrsToClear) ;
+extern OSStatus
+HIViewCreateOffscreenImage(
+ HIViewRef inView,
+ OptionBits inOptions,
+ HIRect * outFrame,
+ CGImageRef * outImage) ;
+extern OSStatus
+HIViewDrawCGImage(
+ CGContextRef inContext,
+ const HIRect * inBounds,
+ CGImageRef inImage) ;
+extern OSStatus
+HIGrowBoxViewSetTransparent(
+ HIViewRef inGrowBoxView,
+ Boolean inTransparent) ;
+extern Boolean
+HIGrowBoxViewIsTransparent(HIViewRef inGrowBoxView) ;
+
+
+
+
+
+
+enum {
+ kEventClassScrollable = 'scrl'
+};
+
+enum {
+ kEventScrollableGetInfo = 1,
+ kEventScrollableInfoChanged = 2,
+ kEventScrollableScrollTo = 10
+};
+
+enum {
+ kEventParamImageSize = 'imsz',
+ kEventParamViewSize = 'vwsz',
+ kEventParamLineSize = 'lnsz',
+ kEventParamOrigin = 'orgn'
+};
+
+
+
+
+
+
+enum {
+
+
+
+
+ kHIScrollViewOptionsVertScroll = (1 << 0),
+
+
+
+
+ kHIScrollViewOptionsHorizScroll = (1 << 1),
+
+
+
+
+
+
+ kHIScrollViewOptionsAllowGrow = (1 << 2),
+ kHIScrollViewValidOptions = (kHIScrollViewOptionsVertScroll | kHIScrollViewOptionsHorizScroll | kHIScrollViewOptionsAllowGrow)
+};
+extern OSStatus
+HIScrollViewCreate(
+ OptionBits inOptions,
+ HIViewRef * outView) ;
+extern OSStatus
+HIScrollViewSetScrollBarAutoHide(
+ HIViewRef inView,
+ Boolean inAutoHide) ;
+extern Boolean
+HIScrollViewGetScrollBarAutoHide(HIViewRef inView) ;
+extern OSStatus
+HIImageViewCreate(
+ CGImageRef inImage,
+ ControlRef * outControl) ;
+
+
+enum {
+ kHIImageViewImageTag = 'imag'
+};
+extern OSStatus
+HIImageViewSetOpaque(
+ HIViewRef inView,
+ Boolean inOpaque) ;
+extern Boolean
+HIImageViewIsOpaque(HIViewRef inView) ;
+extern OSStatus
+HIImageViewSetAlpha(
+ HIViewRef inView,
+ float inAlpha) ;
+extern float
+HIImageViewGetAlpha(HIViewRef inView) ;
+extern OSStatus
+HIImageViewSetScaleToFit(
+ HIViewRef inView,
+ Boolean inScaleToFit) ;
+extern Boolean
+HIImageViewGetScaleToFit(HIViewRef inView) ;
+extern OSStatus
+HIImageViewSetImage(
+ HIViewRef inView,
+ CGImageRef inImage) ;
+extern CGImageRef
+HIImageViewCopyImage(HIViewRef inView) ;
+enum {
+
+
+
+
+ kHIComboBoxNoAttributes = 0L,
+
+
+
+
+
+
+ kHIComboBoxAutoCompletionAttribute = (1L << 0),
+
+
+
+
+
+ kHIComboBoxAutoDisclosureAttribute = (1L << 1),
+
+
+
+
+
+ kHIComboBoxAutoSortAttribute = (1L << 2),
+
+
+
+
+
+ kHIComboBoxAutoSizeListAttribute = (1L << 3),
+
+
+
+
+ kHIComboBoxStandardAttributes = (kHIComboBoxAutoCompletionAttribute | kHIComboBoxAutoDisclosureAttribute | kHIComboBoxAutoSizeListAttribute)
+};
+
+
+enum {
+ kControlKindHIComboBox = 'cbbx'
+};
+
+
+enum {
+ kHIComboBoxEditTextPart = 5,
+ kHIComboBoxDisclosurePart = 28
+};
+
+
+
+
+
+
+enum {
+
+
+
+
+
+
+
+ kHIComboBoxListTag = 'cbls',
+
+
+
+
+
+ kHIComboBoxListPixelWidthTag = 'cblw',
+
+
+
+
+
+ kHIComboBoxListPixelHeightTag = 'cblh',
+
+
+
+
+
+ kHIComboBoxNumVisibleItemsTag = 'cbni'
+};
+extern OSStatus
+HIComboBoxCreate(
+ const HIRect * boundsRect,
+ CFStringRef text,
+ const ControlFontStyleRec * style,
+ CFArrayRef list,
+ OptionBits inAttributes,
+ HIViewRef * outComboBox) ;
+extern ItemCount
+HIComboBoxGetItemCount(HIViewRef inComboBox) ;
+extern OSStatus
+HIComboBoxInsertTextItemAtIndex(
+ HIViewRef inComboBox,
+ CFIndex inIndex,
+ CFStringRef inText) ;
+extern OSStatus
+HIComboBoxAppendTextItem(
+ HIViewRef inComboBox,
+ CFStringRef inText,
+ CFIndex * outIndex) ;
+extern OSStatus
+HIComboBoxCopyTextItemAtIndex(
+ HIViewRef inComboBox,
+ CFIndex inIndex,
+ CFStringRef * outString) ;
+extern OSStatus
+HIComboBoxRemoveItemAtIndex(
+ HIViewRef inComboBox,
+ CFIndex inIndex) ;
+extern OSStatus
+HIComboBoxChangeAttributes(
+ HIViewRef inComboBox,
+ OptionBits inAttributesToSet,
+ OptionBits inAttributesToClear) ;
+extern OSStatus
+HIComboBoxGetAttributes(
+ HIViewRef inComboBox,
+ OptionBits * outAttributes) ;
+
+
+
+
+
+}
+
+
+
+extern "C" {
+extern OSStatus
+GetTextAndEncodingFromCFString(
+ CFStringRef inString,
+ BytePtr outText,
+ ByteCount inTextMaxLength,
+ ByteCount * outTextLength,
+ TextEncoding * outEncoding) ;
+
+
+
+
+}
+
+
+
+extern "C" {
+typedef const struct __HIShape* HIShapeRef;
+typedef struct __HIShape* HIMutableShapeRef;
+extern CFTypeID
+HIShapeGetTypeID(void) ;
+extern HIShapeRef
+HIShapeCreateWithQDRgn(RgnHandle inRgn) ;
+extern HIShapeRef
+HIShapeCreateWithRect(const HIRect * inRect) ;
+extern HIShapeRef
+HIShapeCreateCopy(HIShapeRef inShape) ;
+extern HIShapeRef
+HIShapeCreateIntersection(
+ HIShapeRef inShape1,
+ HIShapeRef inShape2) ;
+extern HIShapeRef
+HIShapeCreateDifference(
+ HIShapeRef inShape1,
+ HIShapeRef inShape2) ;
+extern HIShapeRef
+HIShapeCreateUnion(
+ HIShapeRef inShape1,
+ HIShapeRef inShape2) ;
+extern Boolean
+HIShapeIsEmpty(HIShapeRef inShape) ;
+extern Boolean
+HIShapeIsRectangular(HIShapeRef inShape) ;
+extern Boolean
+HIShapeContainsPoint(
+ HIShapeRef inShape,
+ const HIPoint * inPoint) ;
+extern HIRect *
+HIShapeGetBounds(
+ HIShapeRef inShape,
+ HIRect * outRect) ;
+extern OSStatus
+HIShapeGetAsQDRgn(
+ HIShapeRef inShape,
+ RgnHandle outRgn) ;
+extern OSStatus
+HIShapeReplacePathInCGContext(
+ HIShapeRef inShape,
+ CGContextRef inContext) ;
+extern OSStatus
+HIShapeSetQDClip(
+ HIShapeRef inShape,
+ CGrafPtr inPort) ;
+extern HIMutableShapeRef
+HIShapeCreateMutable(void) ;
+extern HIMutableShapeRef
+HIShapeCreateMutableCopy(HIShapeRef inOrig) ;
+extern OSStatus
+HIShapeSetEmpty(HIMutableShapeRef inShape) ;
+extern OSStatus
+HIShapeIntersect(
+ HIShapeRef inShape1,
+ HIShapeRef inShape2,
+ HIMutableShapeRef outResult) ;
+extern OSStatus
+HIShapeDifference(
+ HIShapeRef inShape1,
+ HIShapeRef inShape2,
+ HIMutableShapeRef outResult) ;
+extern OSStatus
+HIShapeUnion(
+ HIShapeRef inShape1,
+ HIShapeRef inShape2,
+ HIMutableShapeRef outResult) ;
+extern OSStatus
+HIShapeOffset(
+ HIMutableShapeRef inShape,
+ float inDX,
+ float inDY) ;
+
+
+
+
+
+}
+
+
+
+extern "C" {
+
+
+
+
+
+
+
+
+
+typedef SInt16 BalloonVariant;
+enum {
+ kTopLeftTipPointsLeftVariant = 0,
+ kTopLeftTipPointsUpVariant = 1,
+ kTopRightTipPointsUpVariant = 2,
+ kTopRightTipPointsRightVariant = 3,
+ kBottomRightTipPointsRightVariant = 4,
+ kBottomRightTipPointsDownVariant = 5,
+ kBottomLeftTipPointsDownVariant = 6,
+ kBottomLeftTipPointsLeftVariant = 7,
+ kBalloonVariantCount = 8
+};
+
+
+enum {
+ hmBalloonHelpVersion = 0x0002
+};
+
+enum {
+ kHMHelpMenuID = -16490,
+ kHMAboutHelpItem = 1,
+ kHMShowBalloonsItem = 3
+};
+
+enum {
+ kHMHelpID = -5696,
+ kBalloonWDEFID = 126
+};
+
+enum {
+
+ helpItem = 1
+};
+
+enum {
+
+ hmDefaultOptions = 0,
+ hmUseSubIDBit = 0,
+ hmAbsoluteCoordsBit = 1,
+ hmSaveBitsNoWindowBit = 2,
+ hmSaveBitsWindowBit = 3,
+ hmMatchInTitleBit = 4,
+ hmUseSubIDMask = (1 << hmUseSubIDBit),
+ hmAbsoluteCoordsMask = (1 << hmAbsoluteCoordsBit),
+ hmSaveBitsNoWindowMask = (1 << hmSaveBitsNoWindowBit),
+ hmSaveBitsWindowMask = (1 << hmSaveBitsWindowBit),
+ hmMatchInTitleMask = (1 << hmMatchInTitleBit)
+};
+enum {
+
+ kHMStringItem = 1,
+ kHMPictItem = 2,
+ kHMStringResItem = 3,
+ kHMTEResItem = 6,
+ kHMSTRResItem = 7,
+ kHMSkipItem = 256,
+ kHMCompareItem = 512,
+ kHMNamedResourceItem = 1024,
+ kHMTrackCntlItem = 2048
+};
+
+enum {
+
+ khmmString = 1,
+ khmmPict = 2,
+ khmmStringRes = 3,
+ khmmTEHandle = 4,
+ khmmPictHandle = 5,
+ khmmTERes = 6,
+ khmmSTRRes = 7,
+ kHMEnabledItem = 0
+};
+
+enum {
+
+ kHMTETextResType = 'TEXT',
+ kHMTEStyleResType = 'styl'
+};
+
+enum {
+ kHMDisabledItem = 1,
+ kHMCheckedItem = 2,
+ kHMOtherItem = 3,
+
+ kHMRegularWindow = 0,
+ kHMSaveBitsNoWindow = 1,
+ kHMSaveBitsWindow = 2
+};
+
+enum {
+
+ kHMMenuResType = 'hmnu',
+ kHMDialogResType = 'hdlg',
+ kHMWindListResType = 'hwin',
+ kHMRectListResType = 'hrct',
+ kHMOverrideResType = 'hovr',
+ kHMFinderApplResType = 'hfdr'
+};
+
+struct HMStringResType {
+ short hmmResID;
+ short hmmIndex;
+};
+typedef struct HMStringResType HMStringResType;
+struct HMMessageRecord {
+ SInt16 hmmHelpType;
+ union {
+ Str255 hmmString;
+ SInt16 hmmPict;
+ TEHandle hmmTEHandle;
+ HMStringResType hmmStringRes;
+ SInt16 hmmPictRes;
+ PicHandle hmmPictHandle;
+ SInt16 hmmTERes;
+ SInt16 hmmSTRRes;
+ } u;
+};
+typedef struct HMMessageRecord HMMessageRecord;
+typedef HMMessageRecord * HMMessageRecPtr;
+typedef OSErr ( * TipFunctionProcPtr)(Point tip, RgnHandle structure, Rect *r, BalloonVariant *balloonVariant);
+typedef TipFunctionProcPtr TipFunctionUPP;
+
+
+}
+
+
+
+
+
+
+
+extern "C" {
+
+
+
+typedef struct NMRec NMRec;
+typedef NMRec * NMRecPtr;
+typedef void ( * NMProcPtr)(NMRecPtr nmReqPtr);
+typedef NMProcPtr NMUPP;
+struct NMRec {
+ QElemPtr qLink;
+ short qType;
+ short nmFlags;
+ long nmPrivate;
+ short nmReserved;
+ short nmMark;
+ Handle nmIcon;
+ Handle nmSound;
+ StringPtr nmStr;
+ NMUPP nmResp;
+ long nmRefCon;
+};
+extern NMUPP
+NewNMUPP(NMProcPtr userRoutine) ;
+extern void
+DisposeNMUPP(NMUPP userUPP) ;
+extern void
+InvokeNMUPP(
+ NMRecPtr nmReqPtr,
+ NMUPP userUPP) ;
+extern OSErr
+NMInstall(NMRecPtr nmReqPtr) ;
+extern OSErr
+NMRemove(NMRecPtr nmReqPtr) ;
+
+
+
+
+
+
+}
+extern "C" {
+
+
+
+enum {
+ kAppearanceEventClass = 'appr',
+ kAEAppearanceChanged = 'thme',
+ kAESystemFontChanged = 'sysf',
+ kAESmallSystemFontChanged = 'ssfn',
+ kAEViewsFontChanged = 'vfnt'
+};
+
+
+
+
+enum {
+ kThemeDataFileType = 'thme',
+ kThemePlatinumFileType = 'pltn',
+ kThemeCustomThemesFileType = 'scen',
+ kThemeSoundTrackFileType = 'tsnd'
+};
+enum {
+ kThemeBrushDialogBackgroundActive = 1,
+ kThemeBrushDialogBackgroundInactive = 2,
+ kThemeBrushAlertBackgroundActive = 3,
+ kThemeBrushAlertBackgroundInactive = 4,
+ kThemeBrushModelessDialogBackgroundActive = 5,
+ kThemeBrushModelessDialogBackgroundInactive = 6,
+ kThemeBrushUtilityWindowBackgroundActive = 7,
+ kThemeBrushUtilityWindowBackgroundInactive = 8,
+ kThemeBrushListViewSortColumnBackground = 9,
+ kThemeBrushListViewBackground = 10,
+ kThemeBrushIconLabelBackground = 11,
+ kThemeBrushListViewSeparator = 12,
+ kThemeBrushChasingArrows = 13,
+ kThemeBrushDragHilite = 14,
+ kThemeBrushDocumentWindowBackground = 15,
+ kThemeBrushFinderWindowBackground = 16
+};
+
+
+enum {
+ kThemeBrushScrollBarDelimiterActive = 17,
+ kThemeBrushScrollBarDelimiterInactive = 18,
+ kThemeBrushFocusHighlight = 19,
+ kThemeBrushPopupArrowActive = 20,
+ kThemeBrushPopupArrowPressed = 21,
+ kThemeBrushPopupArrowInactive = 22,
+ kThemeBrushAppleGuideCoachmark = 23,
+ kThemeBrushIconLabelBackgroundSelected = 24,
+ kThemeBrushStaticAreaFill = 25,
+ kThemeBrushActiveAreaFill = 26,
+ kThemeBrushButtonFrameActive = 27,
+ kThemeBrushButtonFrameInactive = 28,
+ kThemeBrushButtonFaceActive = 29,
+ kThemeBrushButtonFaceInactive = 30,
+ kThemeBrushButtonFacePressed = 31,
+ kThemeBrushButtonActiveDarkShadow = 32,
+ kThemeBrushButtonActiveDarkHighlight = 33,
+ kThemeBrushButtonActiveLightShadow = 34,
+ kThemeBrushButtonActiveLightHighlight = 35,
+ kThemeBrushButtonInactiveDarkShadow = 36,
+ kThemeBrushButtonInactiveDarkHighlight = 37,
+ kThemeBrushButtonInactiveLightShadow = 38,
+ kThemeBrushButtonInactiveLightHighlight = 39,
+ kThemeBrushButtonPressedDarkShadow = 40,
+ kThemeBrushButtonPressedDarkHighlight = 41,
+ kThemeBrushButtonPressedLightShadow = 42,
+ kThemeBrushButtonPressedLightHighlight = 43,
+ kThemeBrushBevelActiveLight = 44,
+ kThemeBrushBevelActiveDark = 45,
+ kThemeBrushBevelInactiveLight = 46,
+ kThemeBrushBevelInactiveDark = 47
+};
+
+
+enum {
+ kThemeBrushNotificationWindowBackground = 48
+};
+
+
+enum {
+ kThemeBrushMovableModalBackground = 49,
+ kThemeBrushSheetBackgroundOpaque = 50,
+ kThemeBrushDrawerBackground = 51,
+ kThemeBrushToolbarBackground = 52,
+ kThemeBrushSheetBackgroundTransparent = 53,
+ kThemeBrushMenuBackground = 54,
+ kThemeBrushMenuBackgroundSelected = 55
+};
+
+
+enum {
+ kThemeBrushSheetBackground = kThemeBrushSheetBackgroundOpaque
+};
+
+
+
+
+enum {
+ kThemeBrushBlack = -1,
+ kThemeBrushWhite = -2,
+ kThemeBrushPrimaryHighlightColor = -3,
+ kThemeBrushSecondaryHighlightColor = -4
+};
+
+typedef SInt16 ThemeBrush;
+enum {
+ kThemeTextColorDialogActive = 1,
+ kThemeTextColorDialogInactive = 2,
+ kThemeTextColorAlertActive = 3,
+ kThemeTextColorAlertInactive = 4,
+ kThemeTextColorModelessDialogActive = 5,
+ kThemeTextColorModelessDialogInactive = 6,
+ kThemeTextColorWindowHeaderActive = 7,
+ kThemeTextColorWindowHeaderInactive = 8,
+ kThemeTextColorPlacardActive = 9,
+ kThemeTextColorPlacardInactive = 10,
+ kThemeTextColorPlacardPressed = 11,
+ kThemeTextColorPushButtonActive = 12,
+ kThemeTextColorPushButtonInactive = 13,
+ kThemeTextColorPushButtonPressed = 14,
+ kThemeTextColorBevelButtonActive = 15,
+ kThemeTextColorBevelButtonInactive = 16,
+ kThemeTextColorBevelButtonPressed = 17,
+ kThemeTextColorPopupButtonActive = 18,
+ kThemeTextColorPopupButtonInactive = 19,
+ kThemeTextColorPopupButtonPressed = 20,
+ kThemeTextColorIconLabel = 21,
+ kThemeTextColorListView = 22
+};
+
+
+enum {
+ kThemeTextColorDocumentWindowTitleActive = 23,
+ kThemeTextColorDocumentWindowTitleInactive = 24,
+ kThemeTextColorMovableModalWindowTitleActive = 25,
+ kThemeTextColorMovableModalWindowTitleInactive = 26,
+ kThemeTextColorUtilityWindowTitleActive = 27,
+ kThemeTextColorUtilityWindowTitleInactive = 28,
+ kThemeTextColorPopupWindowTitleActive = 29,
+ kThemeTextColorPopupWindowTitleInactive = 30,
+ kThemeTextColorRootMenuActive = 31,
+ kThemeTextColorRootMenuSelected = 32,
+ kThemeTextColorRootMenuDisabled = 33,
+ kThemeTextColorMenuItemActive = 34,
+ kThemeTextColorMenuItemSelected = 35,
+ kThemeTextColorMenuItemDisabled = 36,
+ kThemeTextColorPopupLabelActive = 37,
+ kThemeTextColorPopupLabelInactive = 38
+};
+
+
+
+enum {
+ kThemeTextColorTabFrontActive = 39,
+ kThemeTextColorTabNonFrontActive = 40,
+ kThemeTextColorTabNonFrontPressed = 41,
+ kThemeTextColorTabFrontInactive = 42,
+ kThemeTextColorTabNonFrontInactive = 43,
+ kThemeTextColorIconLabelSelected = 44,
+ kThemeTextColorBevelButtonStickyActive = 45,
+ kThemeTextColorBevelButtonStickyInactive = 46
+};
+
+
+enum {
+ kThemeTextColorNotification = 47
+};
+
+
+
+enum {
+ kThemeTextColorSystemDetail = 48
+};
+
+
+
+enum {
+ kThemeTextColorBlack = -1,
+ kThemeTextColorWhite = -2
+};
+
+typedef SInt16 ThemeTextColor;
+
+enum {
+ kThemeStateInactive = 0,
+ kThemeStateActive = 1,
+ kThemeStatePressed = 2,
+ kThemeStateRollover = 6,
+ kThemeStateUnavailable = 7,
+ kThemeStateUnavailableInactive = 8
+};
+
+
+enum {
+ kThemeStateDisabled = 0
+};
+
+enum {
+ kThemeStatePressedUp = 2,
+ kThemeStatePressedDown = 3
+};
+
+typedef UInt32 ThemeDrawState;
+
+
+
+enum {
+ kThemeArrowCursor = 0,
+ kThemeCopyArrowCursor = 1,
+ kThemeAliasArrowCursor = 2,
+ kThemeContextualMenuArrowCursor = 3,
+ kThemeIBeamCursor = 4,
+ kThemeCrossCursor = 5,
+ kThemePlusCursor = 6,
+ kThemeWatchCursor = 7,
+ kThemeClosedHandCursor = 8,
+ kThemeOpenHandCursor = 9,
+ kThemePointingHandCursor = 10,
+ kThemeCountingUpHandCursor = 11,
+ kThemeCountingDownHandCursor = 12,
+ kThemeCountingUpAndDownHandCursor = 13,
+ kThemeSpinningCursor = 14,
+ kThemeResizeLeftCursor = 15,
+ kThemeResizeRightCursor = 16,
+ kThemeResizeLeftRightCursor = 17,
+ kThemeNotAllowedCursor = 18
+};
+
+typedef UInt32 ThemeCursor;
+
+
+
+enum {
+ kThemeMenuBarNormal = 0,
+ kThemeMenuBarSelected = 1
+};
+
+typedef UInt16 ThemeMenuBarState;
+
+enum {
+ kThemeMenuSquareMenuBar = (1 << 0)
+};
+
+
+
+
+enum {
+ kThemeMenuActive = 0,
+ kThemeMenuSelected = 1,
+ kThemeMenuDisabled = 3
+};
+
+typedef UInt16 ThemeMenuState;
+
+
+
+
+enum {
+ kThemeMenuTypePullDown = 0,
+ kThemeMenuTypePopUp = 1,
+ kThemeMenuTypeHierarchical = 2,
+ kThemeMenuTypeInactive = 0x0100
+};
+
+typedef UInt16 ThemeMenuType;
+enum {
+ kThemeMenuItemPlain = 0,
+ kThemeMenuItemHierarchical = 1,
+ kThemeMenuItemScrollUpArrow = 2,
+ kThemeMenuItemScrollDownArrow = 3,
+ kThemeMenuItemAtTop = 0x0100,
+ kThemeMenuItemAtBottom = 0x0200,
+ kThemeMenuItemHierBackground = 0x0400,
+ kThemeMenuItemPopUpBackground = 0x0800,
+ kThemeMenuItemHasIcon = 0x8000,
+ kThemeMenuItemNoBackground = 0x4000
+};
+
+typedef UInt16 ThemeMenuItemType;
+
+
+
+enum {
+ kThemeBackgroundTabPane = 1,
+ kThemeBackgroundPlacard = 2,
+ kThemeBackgroundWindowHeader = 3,
+ kThemeBackgroundListViewWindowHeader = 4,
+ kThemeBackgroundSecondaryGroupBox = 5
+};
+
+typedef UInt32 ThemeBackgroundKind;
+enum {
+ kThemeNameTag = 'name',
+ kThemeVariantNameTag = 'varn',
+ kThemeVariantBaseTintTag = 'tint',
+ kThemeHighlightColorTag = 'hcol',
+ kThemeScrollBarArrowStyleTag = 'sbar',
+ kThemeScrollBarThumbStyleTag = 'sbth',
+ kThemeSoundsEnabledTag = 'snds',
+ kThemeDblClickCollapseTag = 'coll'
+};
+
+enum {
+ kThemeAppearanceFileNameTag = 'thme',
+ kThemeSystemFontTag = 'lgsf',
+ kThemeSmallSystemFontTag = 'smsf',
+ kThemeViewsFontTag = 'vfnt',
+ kThemeViewsFontSizeTag = 'vfsz',
+ kThemeDesktopPatternNameTag = 'patn',
+ kThemeDesktopPatternTag = 'patt',
+ kThemeDesktopPictureNameTag = 'dpnm',
+ kThemeDesktopPictureAliasTag = 'dpal',
+ kThemeDesktopPictureAlignmentTag = 'dpan',
+ kThemeHighlightColorNameTag = 'hcnm',
+ kThemeExamplePictureIDTag = 'epic',
+ kThemeSoundTrackNameTag = 'sndt',
+ kThemeSoundMaskTag = 'smsk',
+ kThemeUserDefinedTag = 'user',
+ kThemeSmoothFontEnabledTag = 'smoo',
+ kThemeSmoothFontMinSizeTag = 'smos'
+};
+
+
+enum {
+ kTiledOnScreen = 1,
+ kCenterOnScreen = 2,
+ kFitToScreen = 3,
+ kFillScreen = 4,
+ kUseBestGuess = 5
+};
+
+
+
+
+enum {
+ kThemeCheckBoxClassicX = 0,
+ kThemeCheckBoxCheckMark = 1
+};
+
+typedef UInt16 ThemeCheckBoxStyle;
+enum {
+ kThemeScrollBarArrowsSingle = 0,
+ kThemeScrollBarArrowsLowerRight = 1
+};
+
+typedef UInt16 ThemeScrollBarArrowStyle;
+enum {
+ kThemeScrollBarThumbNormal = 0,
+ kThemeScrollBarThumbProportional = 1
+};
+
+typedef UInt16 ThemeScrollBarThumbStyle;
+enum {
+ kThemeSystemFont = 0,
+
+
+
+
+
+
+ kThemeSmallSystemFont = 1,
+
+
+
+
+
+
+ kThemeSmallEmphasizedSystemFont = 2,
+
+
+
+
+
+ kThemeViewsFont = 3,
+
+
+
+
+
+
+
+ kThemeEmphasizedSystemFont = 4,
+
+
+
+
+
+
+
+ kThemeApplicationFont = 5,
+
+
+
+
+
+
+
+ kThemeLabelFont = 6,
+
+
+
+
+
+ kThemeMenuTitleFont = 100,
+
+
+
+
+
+ kThemeMenuItemFont = 101,
+
+
+
+
+
+ kThemeMenuItemMarkFont = 102,
+
+
+
+
+
+ kThemeMenuItemCmdKeyFont = 103,
+
+
+
+
+
+ kThemeWindowTitleFont = 104,
+
+
+
+
+
+ kThemePushButtonFont = 105,
+
+
+
+
+
+ kThemeUtilityWindowTitleFont = 106,
+
+
+
+
+
+ kThemeAlertHeaderFont = 107,
+ kThemeSystemFontDetail = 7,
+ kThemeSystemFontDetailEmphasized = 8,
+ kThemeCurrentPortFont = 200,
+
+
+
+
+
+ kThemeToolbarFont = 108
+};
+
+
+enum {
+ kPublicThemeFontCount = 17
+};
+
+typedef UInt16 ThemeFontID;
+
+
+
+enum {
+ kThemeTabNonFront = 0,
+ kThemeTabNonFrontPressed = 1,
+ kThemeTabNonFrontInactive = 2,
+ kThemeTabFront = 3,
+ kThemeTabFrontInactive = 4,
+ kThemeTabNonFrontUnavailable = 5,
+ kThemeTabFrontUnavailable = 6
+};
+
+typedef UInt16 ThemeTabStyle;
+enum {
+ kThemeTabNorth = 0,
+ kThemeTabSouth = 1,
+ kThemeTabEast = 2,
+ kThemeTabWest = 3
+};
+
+typedef UInt16 ThemeTabDirection;
+
+
+
+
+
+
+enum {
+ kThemeSmallTabHeight = 16,
+ kThemeLargeTabHeight = 21,
+ kThemeTabPaneOverlap = 3,
+ kThemeSmallTabHeightMax = 19,
+ kThemeLargeTabHeightMax = 24
+};
+
+
+
+
+enum {
+ kThemeMediumScrollBar = 0,
+ kThemeSmallScrollBar = 1,
+ kThemeMediumSlider = 2,
+ kThemeMediumProgressBar = 3,
+ kThemeMediumIndeterminateBar = 4,
+ kThemeRelevanceBar = 5,
+ kThemeSmallSlider = 6,
+ kThemeLargeProgressBar = 7,
+ kThemeLargeIndeterminateBar = 8
+};
+
+typedef UInt16 ThemeTrackKind;
+
+
+
+enum {
+
+ kThemeTrackActive = 0,
+ kThemeTrackDisabled = 1,
+ kThemeTrackNothingToScroll = 2,
+ kThemeTrackInactive = 3
+};
+
+typedef UInt8 ThemeTrackEnableState;
+
+
+
+enum {
+
+ kThemeLeftOutsideArrowPressed = 0x01,
+ kThemeLeftInsideArrowPressed = 0x02,
+ kThemeLeftTrackPressed = 0x04,
+ kThemeThumbPressed = 0x08,
+ kThemeRightTrackPressed = 0x10,
+ kThemeRightInsideArrowPressed = 0x20,
+ kThemeRightOutsideArrowPressed = 0x40,
+ kThemeTopOutsideArrowPressed = kThemeLeftOutsideArrowPressed,
+ kThemeTopInsideArrowPressed = kThemeLeftInsideArrowPressed,
+ kThemeTopTrackPressed = kThemeLeftTrackPressed,
+ kThemeBottomTrackPressed = kThemeRightTrackPressed,
+ kThemeBottomInsideArrowPressed = kThemeRightInsideArrowPressed,
+ kThemeBottomOutsideArrowPressed = kThemeRightOutsideArrowPressed
+};
+
+typedef UInt8 ThemeTrackPressState;
+
+
+
+enum {
+
+ kThemeThumbPlain = 0,
+ kThemeThumbUpward = 1,
+ kThemeThumbDownward = 2
+};
+
+typedef UInt8 ThemeThumbDirection;
+enum {
+
+
+
+
+ kThemeTrackHorizontal = (1 << 0),
+
+
+
+
+ kThemeTrackRightToLeft = (1 << 1),
+
+
+
+
+ kThemeTrackShowThumb = (1 << 2),
+
+
+
+
+ kThemeTrackThumbRgnIsNotGhost = (1 << 3),
+
+
+
+
+
+ kThemeTrackNoScrollBarArrows = (1 << 4),
+
+
+
+
+
+ kThemeTrackHasFocus = (1 << 5)
+};
+
+typedef UInt16 ThemeTrackAttributes;
+
+
+
+struct ScrollBarTrackInfo {
+ SInt32 viewsize;
+ ThemeTrackPressState pressState;
+};
+typedef struct ScrollBarTrackInfo ScrollBarTrackInfo;
+struct SliderTrackInfo {
+ ThemeThumbDirection thumbDir;
+ ThemeTrackPressState pressState;
+};
+typedef struct SliderTrackInfo SliderTrackInfo;
+struct ProgressTrackInfo {
+ UInt8 phase;
+};
+typedef struct ProgressTrackInfo ProgressTrackInfo;
+struct ThemeTrackDrawInfo {
+ ThemeTrackKind kind;
+ Rect bounds;
+ SInt32 min;
+ SInt32 max;
+ SInt32 value;
+ UInt32 reserved;
+
+ ThemeTrackAttributes attributes;
+ ThemeTrackEnableState enableState;
+ UInt8 filler1;
+
+ union {
+ ScrollBarTrackInfo scrollbar;
+ SliderTrackInfo slider;
+ ProgressTrackInfo progress;
+ } trackInfo;
+};
+typedef struct ThemeTrackDrawInfo ThemeTrackDrawInfo;
+
+
+
+enum {
+ kThemeWindowHasGrow = (1 << 0),
+ kThemeWindowHasHorizontalZoom = (1 << 3),
+ kThemeWindowHasVerticalZoom = (1 << 4),
+ kThemeWindowHasFullZoom = kThemeWindowHasHorizontalZoom + kThemeWindowHasVerticalZoom,
+ kThemeWindowHasCloseBox = (1 << 5),
+ kThemeWindowHasCollapseBox = (1 << 6),
+ kThemeWindowHasTitleText = (1 << 7),
+ kThemeWindowIsCollapsed = (1 << 8),
+ kThemeWindowHasDirty = (1 << 9)
+};
+
+
+typedef UInt32 ThemeWindowAttributes;
+
+
+
+enum {
+ kThemeDocumentWindow = 0,
+ kThemeDialogWindow = 1,
+ kThemeMovableDialogWindow = 2,
+ kThemeAlertWindow = 3,
+ kThemeMovableAlertWindow = 4,
+ kThemePlainDialogWindow = 5,
+ kThemeShadowDialogWindow = 6,
+ kThemePopupWindow = 7,
+ kThemeUtilityWindow = 8,
+ kThemeUtilitySideWindow = 9,
+ kThemeSheetWindow = 10,
+ kThemeDrawerWindow = 11
+};
+
+typedef UInt16 ThemeWindowType;
+
+
+
+enum {
+ kThemeWidgetCloseBox = 0,
+ kThemeWidgetZoomBox = 1,
+ kThemeWidgetCollapseBox = 2,
+ kThemeWidgetDirtyCloseBox = 6
+};
+
+enum {
+
+ kThemeWidgetABox = 3,
+ kThemeWidgetBBox = 4,
+ kThemeWidgetBOffBox = 5
+};
+
+typedef UInt16 ThemeTitleBarWidget;
+
+
+
+enum {
+ kThemeArrowLeft = 0,
+ kThemeArrowDown = 1,
+ kThemeArrowRight = 2,
+ kThemeArrowUp = 3
+};
+
+typedef UInt16 ThemeArrowOrientation;
+
+
+
+enum {
+ kThemeArrow3pt = 0,
+ kThemeArrow5pt = 1,
+ kThemeArrow7pt = 2,
+ kThemeArrow9pt = 3
+};
+
+typedef UInt16 ThemePopupArrowSize;
+
+
+
+enum {
+ kThemeGrowLeft = (1 << 0),
+ kThemeGrowRight = (1 << 1),
+ kThemeGrowUp = (1 << 2),
+ kThemeGrowDown = (1 << 3)
+};
+
+typedef UInt16 ThemeGrowDirection;
+
+
+
+enum {
+ kThemePushButton = 0,
+ kThemeCheckBox = 1,
+ kThemeRadioButton = 2,
+ kThemeBevelButton = 3,
+ kThemeArrowButton = 4,
+ kThemePopupButton = 5,
+ kThemeDisclosureButton = 6,
+ kThemeIncDecButton = 7,
+ kThemeSmallBevelButton = 8,
+ kThemeMediumBevelButton = 3,
+ kThemeLargeBevelButton = 9,
+ kThemeListHeaderButton = 10,
+ kThemeRoundButton = 11,
+ kThemeLargeRoundButton = 12,
+ kThemeSmallCheckBox = 13,
+ kThemeSmallRadioButton = 14,
+ kThemeRoundedBevelButton = 15,
+ kThemeNormalCheckBox = kThemeCheckBox,
+ kThemeNormalRadioButton = kThemeRadioButton
+};
+
+typedef UInt16 ThemeButtonKind;
+
+
+
+enum {
+ kThemeButtonOff = 0,
+ kThemeButtonOn = 1,
+ kThemeButtonMixed = 2,
+ kThemeDisclosureRight = 0,
+ kThemeDisclosureDown = 1,
+ kThemeDisclosureLeft = 2
+};
+
+typedef UInt16 ThemeButtonValue;
+
+
+
+enum {
+ kThemeAdornmentNone = 0,
+ kThemeAdornmentDefault = (1 << 0),
+ kThemeAdornmentFocus = (1 << 2),
+ kThemeAdornmentRightToLeft = (1 << 4),
+ kThemeAdornmentDrawIndicatorOnly = (1 << 5),
+ kThemeAdornmentHeaderButtonLeftNeighborSelected = (1 << 6),
+ kThemeAdornmentHeaderButtonRightNeighborSelected = (1 << 7),
+ kThemeAdornmentHeaderButtonSortUp = (1 << 8),
+ kThemeAdornmentHeaderMenuButton = (1 << 9),
+ kThemeAdornmentHeaderButtonNoShadow = (1 << 10),
+ kThemeAdornmentHeaderButtonShadowOnly = (1 << 11),
+ kThemeAdornmentNoShadow = kThemeAdornmentHeaderButtonNoShadow,
+ kThemeAdornmentShadowOnly = kThemeAdornmentHeaderButtonShadowOnly,
+ kThemeAdornmentArrowLeftArrow = (1 << 6),
+ kThemeAdornmentArrowDownArrow = (1 << 7),
+ kThemeAdornmentArrowDoubleArrow = (1 << 8),
+ kThemeAdornmentArrowUpArrow = (1 << 9)
+};
+
+typedef UInt16 ThemeButtonAdornment;
+
+
+
+struct ThemeButtonDrawInfo {
+ ThemeDrawState state;
+ ThemeButtonValue value;
+ ThemeButtonAdornment adornment;
+};
+typedef struct ThemeButtonDrawInfo ThemeButtonDrawInfo;
+typedef ThemeButtonDrawInfo * ThemeButtonDrawInfoPtr;
+enum {
+ kThemeNoSounds = 0,
+ kThemeWindowSoundsMask = (1 << 0),
+ kThemeMenuSoundsMask = (1 << 1),
+ kThemeControlSoundsMask = (1 << 2),
+ kThemeFinderSoundsMask = (1 << 3)
+};
+enum {
+ kThemeDragSoundNone = 0,
+ kThemeDragSoundMoveWindow = 'wmov',
+ kThemeDragSoundGrowWindow = 'wgro',
+ kThemeDragSoundMoveUtilWindow = 'umov',
+ kThemeDragSoundGrowUtilWindow = 'ugro',
+ kThemeDragSoundMoveDialog = 'dmov',
+ kThemeDragSoundMoveAlert = 'amov',
+ kThemeDragSoundMoveIcon = 'imov',
+ kThemeDragSoundSliderThumb = 'slth',
+ kThemeDragSoundSliderGhost = 'slgh',
+ kThemeDragSoundScrollBarThumb = 'sbth',
+ kThemeDragSoundScrollBarGhost = 'sbgh',
+ kThemeDragSoundScrollBarArrowDecreasing = 'sbad',
+ kThemeDragSoundScrollBarArrowIncreasing = 'sbai',
+ kThemeDragSoundDragging = 'drag'
+};
+
+typedef OSType ThemeDragSoundKind;
+enum {
+ kThemeSoundNone = 0,
+ kThemeSoundMenuOpen = 'mnuo',
+ kThemeSoundMenuClose = 'mnuc',
+ kThemeSoundMenuItemHilite = 'mnui',
+ kThemeSoundMenuItemRelease = 'mnus',
+ kThemeSoundWindowClosePress = 'wclp',
+ kThemeSoundWindowCloseEnter = 'wcle',
+ kThemeSoundWindowCloseExit = 'wclx',
+ kThemeSoundWindowCloseRelease = 'wclr',
+ kThemeSoundWindowZoomPress = 'wzmp',
+ kThemeSoundWindowZoomEnter = 'wzme',
+ kThemeSoundWindowZoomExit = 'wzmx',
+ kThemeSoundWindowZoomRelease = 'wzmr',
+ kThemeSoundWindowCollapsePress = 'wcop',
+ kThemeSoundWindowCollapseEnter = 'wcoe',
+ kThemeSoundWindowCollapseExit = 'wcox',
+ kThemeSoundWindowCollapseRelease = 'wcor',
+ kThemeSoundWindowDragBoundary = 'wdbd',
+ kThemeSoundUtilWinClosePress = 'uclp',
+ kThemeSoundUtilWinCloseEnter = 'ucle',
+ kThemeSoundUtilWinCloseExit = 'uclx',
+ kThemeSoundUtilWinCloseRelease = 'uclr',
+ kThemeSoundUtilWinZoomPress = 'uzmp',
+ kThemeSoundUtilWinZoomEnter = 'uzme',
+ kThemeSoundUtilWinZoomExit = 'uzmx',
+ kThemeSoundUtilWinZoomRelease = 'uzmr',
+ kThemeSoundUtilWinCollapsePress = 'ucop',
+ kThemeSoundUtilWinCollapseEnter = 'ucoe',
+ kThemeSoundUtilWinCollapseExit = 'ucox',
+ kThemeSoundUtilWinCollapseRelease = 'ucor',
+ kThemeSoundUtilWinDragBoundary = 'udbd',
+ kThemeSoundWindowOpen = 'wopn',
+ kThemeSoundWindowClose = 'wcls',
+ kThemeSoundWindowZoomIn = 'wzmi',
+ kThemeSoundWindowZoomOut = 'wzmo',
+ kThemeSoundWindowCollapseUp = 'wcol',
+ kThemeSoundWindowCollapseDown = 'wexp',
+ kThemeSoundWindowActivate = 'wact',
+ kThemeSoundUtilWindowOpen = 'uopn',
+ kThemeSoundUtilWindowClose = 'ucls',
+ kThemeSoundUtilWindowZoomIn = 'uzmi',
+ kThemeSoundUtilWindowZoomOut = 'uzmo',
+ kThemeSoundUtilWindowCollapseUp = 'ucol',
+ kThemeSoundUtilWindowCollapseDown = 'uexp',
+ kThemeSoundUtilWindowActivate = 'uact',
+ kThemeSoundDialogOpen = 'dopn',
+ kThemeSoundDialogClose = 'dlgc',
+ kThemeSoundAlertOpen = 'aopn',
+ kThemeSoundAlertClose = 'altc',
+ kThemeSoundPopupWindowOpen = 'pwop',
+ kThemeSoundPopupWindowClose = 'pwcl',
+ kThemeSoundButtonPress = 'btnp',
+ kThemeSoundButtonEnter = 'btne',
+ kThemeSoundButtonExit = 'btnx',
+ kThemeSoundButtonRelease = 'btnr',
+ kThemeSoundDefaultButtonPress = 'dbtp',
+ kThemeSoundDefaultButtonEnter = 'dbte',
+ kThemeSoundDefaultButtonExit = 'dbtx',
+ kThemeSoundDefaultButtonRelease = 'dbtr',
+ kThemeSoundCancelButtonPress = 'cbtp',
+ kThemeSoundCancelButtonEnter = 'cbte',
+ kThemeSoundCancelButtonExit = 'cbtx',
+ kThemeSoundCancelButtonRelease = 'cbtr',
+ kThemeSoundCheckboxPress = 'chkp',
+ kThemeSoundCheckboxEnter = 'chke',
+ kThemeSoundCheckboxExit = 'chkx',
+ kThemeSoundCheckboxRelease = 'chkr',
+ kThemeSoundRadioPress = 'radp',
+ kThemeSoundRadioEnter = 'rade',
+ kThemeSoundRadioExit = 'radx',
+ kThemeSoundRadioRelease = 'radr',
+ kThemeSoundScrollArrowPress = 'sbap',
+ kThemeSoundScrollArrowEnter = 'sbae',
+ kThemeSoundScrollArrowExit = 'sbax',
+ kThemeSoundScrollArrowRelease = 'sbar',
+ kThemeSoundScrollEndOfTrack = 'sbte',
+ kThemeSoundScrollTrackPress = 'sbtp',
+ kThemeSoundSliderEndOfTrack = 'slte',
+ kThemeSoundSliderTrackPress = 'sltp',
+ kThemeSoundBalloonOpen = 'blno',
+ kThemeSoundBalloonClose = 'blnc',
+ kThemeSoundBevelPress = 'bevp',
+ kThemeSoundBevelEnter = 'beve',
+ kThemeSoundBevelExit = 'bevx',
+ kThemeSoundBevelRelease = 'bevr',
+ kThemeSoundLittleArrowUpPress = 'laup',
+ kThemeSoundLittleArrowDnPress = 'ladp',
+ kThemeSoundLittleArrowEnter = 'lare',
+ kThemeSoundLittleArrowExit = 'larx',
+ kThemeSoundLittleArrowUpRelease = 'laur',
+ kThemeSoundLittleArrowDnRelease = 'ladr',
+ kThemeSoundPopupPress = 'popp',
+ kThemeSoundPopupEnter = 'pope',
+ kThemeSoundPopupExit = 'popx',
+ kThemeSoundPopupRelease = 'popr',
+ kThemeSoundDisclosurePress = 'dscp',
+ kThemeSoundDisclosureEnter = 'dsce',
+ kThemeSoundDisclosureExit = 'dscx',
+ kThemeSoundDisclosureRelease = 'dscr',
+ kThemeSoundTabPressed = 'tabp',
+ kThemeSoundTabEnter = 'tabe',
+ kThemeSoundTabExit = 'tabx',
+ kThemeSoundTabRelease = 'tabr',
+ kThemeSoundDragTargetHilite = 'dthi',
+ kThemeSoundDragTargetUnhilite = 'dtuh',
+ kThemeSoundDragTargetDrop = 'dtdr',
+ kThemeSoundEmptyTrash = 'ftrs',
+ kThemeSoundSelectItem = 'fsel',
+ kThemeSoundNewItem = 'fnew',
+ kThemeSoundReceiveDrop = 'fdrp',
+ kThemeSoundCopyDone = 'fcpd',
+ kThemeSoundResolveAlias = 'fral',
+ kThemeSoundLaunchApp = 'flap',
+ kThemeSoundDiskInsert = 'dski',
+ kThemeSoundDiskEject = 'dske',
+ kThemeSoundFinderDragOnIcon = 'fdon',
+ kThemeSoundFinderDragOffIcon = 'fdof'
+};
+
+typedef OSType ThemeSoundKind;
+enum {
+ kThemePopupTabNormalPosition = 0,
+ kThemePopupTabCenterOnWindow = 1,
+ kThemePopupTabCenterOnOffset = 2
+};
+
+struct ThemeWindowMetrics {
+ UInt16 metricSize;
+ SInt16 titleHeight;
+ SInt16 titleWidth;
+ SInt16 popupTabOffset;
+ SInt16 popupTabWidth;
+ UInt16 popupTabPosition;
+};
+typedef struct ThemeWindowMetrics ThemeWindowMetrics;
+typedef ThemeWindowMetrics * ThemeWindowMetricsPtr;
+enum {
+
+
+
+
+ kThemeMetricScrollBarWidth = 0,
+
+
+
+
+ kThemeMetricSmallScrollBarWidth = 1,
+
+
+
+
+ kThemeMetricCheckBoxHeight = 2,
+
+
+
+
+ kThemeMetricRadioButtonHeight = 3,
+ kThemeMetricEditTextWhitespace = 4,
+
+
+
+
+
+
+
+ kThemeMetricEditTextFrameOutset = 5,
+
+
+
+
+
+ kThemeMetricListBoxFrameOutset = 6,
+
+
+
+
+
+
+ kThemeMetricFocusRectOutset = 7,
+
+
+
+
+ kThemeMetricImageWellThickness = 8,
+
+
+
+
+
+
+
+ kThemeMetricScrollBarOverlap = 9,
+
+
+
+
+ kThemeMetricLargeTabHeight = 10,
+
+
+
+
+
+ kThemeMetricLargeTabCapsWidth = 11,
+
+
+
+
+
+
+
+ kThemeMetricTabFrameOverlap = 12,
+ kThemeMetricTabIndentOrStyle = 13,
+
+
+
+
+
+ kThemeMetricTabOverlap = 14,
+
+
+
+
+
+ kThemeMetricSmallTabHeight = 15,
+
+
+
+
+
+ kThemeMetricSmallTabCapsWidth = 16,
+
+
+
+
+ kThemeMetricPushButtonHeight = 19,
+
+
+
+
+ kThemeMetricListHeaderHeight = 20,
+
+
+
+
+
+ kThemeMetricDisclosureTriangleHeight = 25,
+
+
+
+
+ kThemeMetricDisclosureTriangleWidth = 26,
+
+
+
+
+ kThemeMetricLittleArrowsHeight = 27,
+
+
+
+
+ kThemeMetricLittleArrowsWidth = 28,
+
+
+
+
+ kThemeMetricPopupButtonHeight = 30,
+
+
+
+
+ kThemeMetricSmallPopupButtonHeight = 31,
+
+
+
+
+ kThemeMetricLargeProgressBarThickness = 32,
+
+
+
+
+ kThemeMetricPullDownHeight = 33,
+
+
+
+
+ kThemeMetricSmallPullDownHeight = 34,
+
+
+
+
+ kThemeMetricResizeControlHeight = 38,
+
+
+
+
+ kThemeMetricSmallResizeControlHeight = 39,
+
+
+
+
+ kThemeMetricHSliderHeight = 41,
+
+
+
+
+ kThemeMetricHSliderTickHeight = 42,
+
+
+
+
+ kThemeMetricVSliderWidth = 45,
+
+
+
+
+ kThemeMetricVSliderTickWidth = 46,
+
+
+
+
+
+ kThemeMetricTitleBarControlsHeight = 49,
+
+
+
+
+ kThemeMetricCheckBoxWidth = 50,
+
+
+
+
+ kThemeMetricRadioButtonWidth = 52,
+
+
+
+
+ kThemeMetricNormalProgressBarThickness = 58,
+
+
+
+
+ kThemeMetricProgressBarShadowOutset = 59,
+
+
+
+
+
+ kThemeMetricSmallProgressBarShadowOutset = 60,
+
+
+
+
+
+ kThemeMetricPrimaryGroupBoxContentInset = 61,
+
+
+
+
+
+ kThemeMetricSecondaryGroupBoxContentInset = 62,
+
+
+
+
+ kThemeMetricMenuMarkColumnWidth = 63,
+
+
+
+
+
+ kThemeMetricMenuExcludedMarkColumnWidth = 64,
+
+
+
+
+
+ kThemeMetricMenuMarkIndent = 65,
+
+
+
+
+ kThemeMetricMenuTextLeadingEdgeMargin = 66,
+
+
+
+
+ kThemeMetricMenuTextTrailingEdgeMargin = 67,
+
+
+
+
+ kThemeMetricMenuIndentWidth = 68,
+
+
+
+
+
+ kThemeMetricMenuIconTrailingEdgeMargin = 69
+};
+
+
+
+
+
+
+enum {
+
+
+
+
+ kThemeMetricDisclosureButtonHeight = 17,
+
+
+
+
+ kThemeMetricRoundButtonSize = 18,
+
+
+
+
+ kThemeMetricSmallCheckBoxHeight = 21,
+
+
+
+
+ kThemeMetricDisclosureButtonWidth = 22,
+
+
+
+
+ kThemeMetricSmallDisclosureButtonHeight = 23,
+
+
+
+
+ kThemeMetricSmallDisclosureButtonWidth = 24,
+
+
+
+
+ kThemeMetricPaneSplitterHeight = 29,
+
+
+
+
+ kThemeMetricSmallPushButtonHeight = 35,
+
+
+
+
+ kThemeMetricSmallRadioButtonHeight = 36,
+
+
+
+
+ kThemeMetricRelevanceIndicatorHeight = 37,
+
+
+
+
+ kThemeMetricLargeRoundButtonSize = 40,
+
+
+
+
+ kThemeMetricSmallHSliderHeight = 43,
+
+
+
+
+
+ kThemeMetricSmallHSliderTickHeight = 44,
+
+
+
+
+ kThemeMetricSmallVSliderWidth = 47,
+
+
+
+
+ kThemeMetricSmallVSliderTickWidth = 48,
+
+
+
+
+ kThemeMetricSmallCheckBoxWidth = 51,
+
+
+
+
+ kThemeMetricSmallRadioButtonWidth = 53,
+
+
+
+
+
+ kThemeMetricSmallHSliderMinThumbWidth = 54,
+
+
+
+
+ kThemeMetricSmallVSliderMinThumbHeight = 55,
+
+
+
+
+
+ kThemeMetricSmallHSliderTickOffset = 56,
+
+
+
+
+
+ kThemeMetricSmallVSliderTickOffset = 57
+};
+
+typedef UInt32 ThemeMetric;
+
+
+
+typedef struct OpaqueThemeDrawingState* ThemeDrawingState;
+
+
+
+typedef void ( * ThemeTabTitleDrawProcPtr)(const Rect *bounds, ThemeTabStyle style, ThemeTabDirection direction, SInt16 depth, Boolean isColorDev, UInt32 userData);
+typedef void ( * ThemeEraseProcPtr)(const Rect *bounds, UInt32 eraseData, SInt16 depth, Boolean isColorDev);
+typedef void ( * ThemeButtonDrawProcPtr)(const Rect *bounds, ThemeButtonKind kind, const ThemeButtonDrawInfo *info, UInt32 userData, SInt16 depth, Boolean isColorDev);
+typedef void ( * WindowTitleDrawingProcPtr)(const Rect *bounds, SInt16 depth, Boolean colorDevice, UInt32 userData);
+typedef Boolean ( * ThemeIteratorProcPtr)(ConstStr255Param inFileName, SInt16 resID, Collection inThemeSettings, void *inUserData);
+typedef ThemeTabTitleDrawProcPtr ThemeTabTitleDrawUPP;
+typedef ThemeEraseProcPtr ThemeEraseUPP;
+typedef ThemeButtonDrawProcPtr ThemeButtonDrawUPP;
+typedef WindowTitleDrawingProcPtr WindowTitleDrawingUPP;
+typedef ThemeIteratorProcPtr ThemeIteratorUPP;
+extern ThemeTabTitleDrawUPP
+NewThemeTabTitleDrawUPP(ThemeTabTitleDrawProcPtr userRoutine) ;
+extern ThemeEraseUPP
+NewThemeEraseUPP(ThemeEraseProcPtr userRoutine) ;
+extern ThemeButtonDrawUPP
+NewThemeButtonDrawUPP(ThemeButtonDrawProcPtr userRoutine) ;
+extern WindowTitleDrawingUPP
+NewWindowTitleDrawingUPP(WindowTitleDrawingProcPtr userRoutine) ;
+extern ThemeIteratorUPP
+NewThemeIteratorUPP(ThemeIteratorProcPtr userRoutine) ;
+extern void
+DisposeThemeTabTitleDrawUPP(ThemeTabTitleDrawUPP userUPP) ;
+extern void
+DisposeThemeEraseUPP(ThemeEraseUPP userUPP) ;
+extern void
+DisposeThemeButtonDrawUPP(ThemeButtonDrawUPP userUPP) ;
+extern void
+DisposeWindowTitleDrawingUPP(WindowTitleDrawingUPP userUPP) ;
+extern void
+DisposeThemeIteratorUPP(ThemeIteratorUPP userUPP) ;
+extern void
+InvokeThemeTabTitleDrawUPP(
+ const Rect * bounds,
+ ThemeTabStyle style,
+ ThemeTabDirection direction,
+ SInt16 depth,
+ Boolean isColorDev,
+ UInt32 userData,
+ ThemeTabTitleDrawUPP userUPP) ;
+extern void
+InvokeThemeEraseUPP(
+ const Rect * bounds,
+ UInt32 eraseData,
+ SInt16 depth,
+ Boolean isColorDev,
+ ThemeEraseUPP userUPP) ;
+extern void
+InvokeThemeButtonDrawUPP(
+ const Rect * bounds,
+ ThemeButtonKind kind,
+ const ThemeButtonDrawInfo * info,
+ UInt32 userData,
+ SInt16 depth,
+ Boolean isColorDev,
+ ThemeButtonDrawUPP userUPP) ;
+extern void
+InvokeWindowTitleDrawingUPP(
+ const Rect * bounds,
+ SInt16 depth,
+ Boolean colorDevice,
+ UInt32 userData,
+ WindowTitleDrawingUPP userUPP) ;
+extern Boolean
+InvokeThemeIteratorUPP(
+ ConstStr255Param inFileName,
+ SInt16 resID,
+ Collection inThemeSettings,
+ void * inUserData,
+ ThemeIteratorUPP userUPP) ;
+
+
+
+
+typedef void ( * MenuTitleDrawingProcPtr)(const Rect *inBounds, SInt16 inDepth, Boolean inIsColorDevice, SInt32 inUserData);
+typedef void ( * MenuItemDrawingProcPtr)(const Rect *inBounds, SInt16 inDepth, Boolean inIsColorDevice, SInt32 inUserData);
+typedef MenuTitleDrawingProcPtr MenuTitleDrawingUPP;
+typedef MenuItemDrawingProcPtr MenuItemDrawingUPP;
+extern MenuTitleDrawingUPP
+NewMenuTitleDrawingUPP(MenuTitleDrawingProcPtr userRoutine) ;
+extern MenuItemDrawingUPP
+NewMenuItemDrawingUPP(MenuItemDrawingProcPtr userRoutine) ;
+extern void
+DisposeMenuTitleDrawingUPP(MenuTitleDrawingUPP userUPP) ;
+extern void
+DisposeMenuItemDrawingUPP(MenuItemDrawingUPP userUPP) ;
+extern void
+InvokeMenuTitleDrawingUPP(
+ const Rect * inBounds,
+ SInt16 inDepth,
+ Boolean inIsColorDevice,
+ SInt32 inUserData,
+ MenuTitleDrawingUPP userUPP) ;
+extern void
+InvokeMenuItemDrawingUPP(
+ const Rect * inBounds,
+ SInt16 inDepth,
+ Boolean inIsColorDevice,
+ SInt32 inUserData,
+ MenuItemDrawingUPP userUPP) ;
+extern OSStatus
+RegisterAppearanceClient(void) ;
+extern OSStatus
+UnregisterAppearanceClient(void) ;
+extern Boolean
+IsAppearanceClient(const ProcessSerialNumber * process) ;
+extern OSStatus
+SetThemePen(
+ ThemeBrush inBrush,
+ SInt16 inDepth,
+ Boolean inIsColorDevice) ;
+extern OSStatus
+SetThemeBackground(
+ ThemeBrush inBrush,
+ SInt16 inDepth,
+ Boolean inIsColorDevice) ;
+extern OSStatus
+SetThemeTextColor(
+ ThemeTextColor inColor,
+ SInt16 inDepth,
+ Boolean inIsColorDevice) ;
+extern OSStatus
+SetThemeWindowBackground(
+ WindowRef inWindow,
+ ThemeBrush inBrush,
+ Boolean inUpdate) ;
+extern OSStatus
+DrawThemeWindowHeader(
+ const Rect * inRect,
+ ThemeDrawState inState) ;
+extern OSStatus
+DrawThemeWindowListViewHeader(
+ const Rect * inRect,
+ ThemeDrawState inState) ;
+extern OSStatus
+DrawThemePlacard(
+ const Rect * inRect,
+ ThemeDrawState inState) ;
+extern OSStatus
+DrawThemeEditTextFrame(
+ const Rect * inRect,
+ ThemeDrawState inState) ;
+extern OSStatus
+DrawThemeListBoxFrame(
+ const Rect * inRect,
+ ThemeDrawState inState) ;
+extern OSStatus
+DrawThemeFocusRect(
+ const Rect * inRect,
+ Boolean inHasFocus) ;
+extern OSStatus
+DrawThemePrimaryGroup(
+ const Rect * inRect,
+ ThemeDrawState inState) ;
+extern OSStatus
+DrawThemeSecondaryGroup(
+ const Rect * inRect,
+ ThemeDrawState inState) ;
+extern OSStatus
+DrawThemeSeparator(
+ const Rect * inRect,
+ ThemeDrawState inState) ;
+extern OSStatus
+DrawThemeModelessDialogFrame(
+ const Rect * inRect,
+ ThemeDrawState inState) ;
+extern OSStatus
+DrawThemeGenericWell(
+ const Rect * inRect,
+ ThemeDrawState inState,
+ Boolean inFillCenter) ;
+extern OSStatus
+DrawThemeFocusRegion(
+ RgnHandle inRegion,
+ Boolean inHasFocus) ;
+extern Boolean
+IsThemeInColor(
+ SInt16 inDepth,
+ Boolean inIsColorDevice) ;
+extern OSStatus
+GetThemeAccentColors(CTabHandle * outColors) ;
+extern OSStatus
+DrawThemeMenuBarBackground(
+ const Rect * inBounds,
+ ThemeMenuBarState inState,
+ UInt32 inAttributes) ;
+extern OSStatus
+DrawThemeMenuTitle(
+ const Rect * inMenuBarRect,
+ const Rect * inTitleRect,
+ ThemeMenuState inState,
+ UInt32 inAttributes,
+ MenuTitleDrawingUPP inTitleProc,
+ UInt32 inTitleData) ;
+extern OSStatus
+GetThemeMenuBarHeight(SInt16 * outHeight) ;
+extern OSStatus
+DrawThemeMenuBackground(
+ const Rect * inMenuRect,
+ ThemeMenuType inMenuType) ;
+extern OSStatus
+GetThemeMenuBackgroundRegion(
+ const Rect * inMenuRect,
+ ThemeMenuType menuType,
+ RgnHandle region) ;
+extern OSStatus
+DrawThemeMenuItem(
+ const Rect * inMenuRect,
+ const Rect * inItemRect,
+ SInt16 inVirtualMenuTop,
+ SInt16 inVirtualMenuBottom,
+ ThemeMenuState inState,
+ ThemeMenuItemType inItemType,
+ MenuItemDrawingUPP inDrawProc,
+ UInt32 inUserData) ;
+extern OSStatus
+DrawThemeMenuSeparator(const Rect * inItemRect) ;
+extern OSStatus
+GetThemeMenuSeparatorHeight(SInt16 * outHeight) ;
+extern OSStatus
+GetThemeMenuItemExtra(
+ ThemeMenuItemType inItemType,
+ SInt16 * outHeight,
+ SInt16 * outWidth) ;
+extern OSStatus
+GetThemeMenuTitleExtra(
+ SInt16 * outWidth,
+ Boolean inIsSquished) ;
+extern OSStatus
+GetTheme(Collection ioCollection) ;
+extern OSStatus
+SetTheme(Collection ioCollection) ;
+extern OSStatus
+IterateThemes(
+ ThemeIteratorUPP inProc,
+ void * inUserData) ;
+extern OSStatus
+DrawThemeTabPane(
+ const Rect * inRect,
+ ThemeDrawState inState) ;
+extern OSStatus
+DrawThemeTab(
+ const Rect * inRect,
+ ThemeTabStyle inStyle,
+ ThemeTabDirection inDirection,
+ ThemeTabTitleDrawUPP labelProc,
+ UInt32 userData) ;
+extern OSStatus
+GetThemeTabRegion(
+ const Rect * inRect,
+ ThemeTabStyle inStyle,
+ ThemeTabDirection inDirection,
+ RgnHandle ioRgn) ;
+extern OSStatus
+SetThemeCursor(ThemeCursor inCursor) ;
+extern OSStatus
+SetAnimatedThemeCursor(
+ ThemeCursor inCursor,
+ UInt32 inAnimationStep) ;
+extern OSStatus
+GetThemeScrollBarThumbStyle(ThemeScrollBarThumbStyle * outStyle) ;
+extern OSStatus
+GetThemeScrollBarArrowStyle(ThemeScrollBarArrowStyle * outStyle) ;
+extern OSStatus
+GetThemeCheckBoxStyle(ThemeCheckBoxStyle * outStyle) ;
+extern OSStatus
+UseThemeFont(
+ ThemeFontID inFontID,
+ ScriptCode inScript) ;
+extern OSStatus
+GetThemeFont(
+ ThemeFontID inFontID,
+ ScriptCode inScript,
+ Str255 outFontName,
+ SInt16 * outFontSize,
+ Style * outStyle) ;
+extern OSStatus
+DrawThemeTextBox(
+ CFStringRef inString,
+ ThemeFontID inFontID,
+ ThemeDrawState inState,
+ Boolean inWrapToWidth,
+ const Rect * inBoundingBox,
+ SInt16 inJust,
+ void * inContext) ;
+extern OSStatus
+TruncateThemeText(
+ CFMutableStringRef inString,
+ ThemeFontID inFontID,
+ ThemeDrawState inState,
+ SInt16 inPixelWidthLimit,
+ TruncCode inTruncWhere,
+ Boolean * outTruncated) ;
+extern OSStatus
+GetThemeTextDimensions(
+ CFStringRef inString,
+ ThemeFontID inFontID,
+ ThemeDrawState inState,
+ Boolean inWrapToWidth,
+ Point * ioBounds,
+ SInt16 * outBaseline) ;
+extern OSStatus
+GetThemeTextShadowOutset(
+ ThemeFontID inFontID,
+ ThemeDrawState inState,
+ Rect * outOutset) ;
+extern OSStatus
+DrawThemeTrack(
+ const ThemeTrackDrawInfo * drawInfo,
+ RgnHandle rgnGhost,
+ ThemeEraseUPP eraseProc,
+ UInt32 eraseData) ;
+extern Boolean
+HitTestThemeTrack(
+ const ThemeTrackDrawInfo * drawInfo,
+ Point mousePoint,
+ ControlPartCode * partHit) ;
+extern OSStatus
+GetThemeTrackBounds(
+ const ThemeTrackDrawInfo * drawInfo,
+ Rect * bounds) ;
+extern OSStatus
+GetThemeTrackThumbRgn(
+ const ThemeTrackDrawInfo * drawInfo,
+ RgnHandle thumbRgn) ;
+extern OSStatus
+GetThemeTrackDragRect(
+ const ThemeTrackDrawInfo * drawInfo,
+ Rect * dragRect) ;
+extern OSStatus
+DrawThemeTrackTickMarks(
+ const ThemeTrackDrawInfo * drawInfo,
+ ItemCount numTicks,
+ ThemeEraseUPP eraseProc,
+ UInt32 eraseData) ;
+extern OSStatus
+GetThemeTrackThumbPositionFromOffset(
+ const ThemeTrackDrawInfo * drawInfo,
+ Point thumbOffset,
+ SInt32 * relativePosition) ;
+extern OSStatus
+GetThemeTrackThumbPositionFromRegion(
+ const ThemeTrackDrawInfo * drawInfo,
+ RgnHandle thumbRgn,
+ SInt32 * relativePosition) ;
+extern OSStatus
+GetThemeTrackLiveValue(
+ const ThemeTrackDrawInfo * drawInfo,
+ SInt32 relativePosition,
+ SInt32 * value) ;
+extern OSStatus
+DrawThemeScrollBarArrows(
+ const Rect * bounds,
+ ThemeTrackEnableState enableState,
+ ThemeTrackPressState pressState,
+ Boolean isHoriz,
+ Rect * trackBounds) ;
+extern OSStatus
+GetThemeScrollBarTrackRect(
+ const Rect * bounds,
+ ThemeTrackEnableState enableState,
+ ThemeTrackPressState pressState,
+ Boolean isHoriz,
+ Rect * trackBounds) ;
+extern Boolean
+HitTestThemeScrollBarArrows(
+ const Rect * scrollBarBounds,
+ ThemeTrackEnableState enableState,
+ ThemeTrackPressState pressState,
+ Boolean isHoriz,
+ Point ptHit,
+ Rect * trackBounds,
+ ControlPartCode * partcode) ;
+extern OSStatus
+GetThemeWindowRegion(
+ ThemeWindowType flavor,
+ const Rect * contRect,
+ ThemeDrawState state,
+ const ThemeWindowMetrics * metrics,
+ ThemeWindowAttributes attributes,
+ WindowRegionCode winRegion,
+ RgnHandle rgn) ;
+extern OSStatus
+DrawThemeWindowFrame(
+ ThemeWindowType flavor,
+ const Rect * contRect,
+ ThemeDrawState state,
+ const ThemeWindowMetrics * metrics,
+ ThemeWindowAttributes attributes,
+ WindowTitleDrawingUPP titleProc,
+ UInt32 titleData) ;
+extern OSStatus
+DrawThemeTitleBarWidget(
+ ThemeWindowType flavor,
+ const Rect * contRect,
+ ThemeDrawState state,
+ const ThemeWindowMetrics * metrics,
+ ThemeWindowAttributes attributes,
+ ThemeTitleBarWidget widget) ;
+extern Boolean
+GetThemeWindowRegionHit(
+ ThemeWindowType flavor,
+ const Rect * inContRect,
+ ThemeDrawState state,
+ const ThemeWindowMetrics * metrics,
+ ThemeWindowAttributes inAttributes,
+ Point inPoint,
+ WindowRegionCode * outRegionHit) ;
+extern OSStatus
+DrawThemeScrollBarDelimiters(
+ ThemeWindowType flavor,
+ const Rect * inContRect,
+ ThemeDrawState state,
+ ThemeWindowAttributes attributes) ;
+extern OSStatus
+DrawThemeButton(
+ const Rect * inBounds,
+ ThemeButtonKind inKind,
+ const ThemeButtonDrawInfo * inNewInfo,
+ const ThemeButtonDrawInfo * inPrevInfo,
+ ThemeEraseUPP inEraseProc,
+ ThemeButtonDrawUPP inLabelProc,
+ UInt32 inUserData) ;
+extern OSStatus
+GetThemeButtonRegion(
+ const Rect * inBounds,
+ ThemeButtonKind inKind,
+ const ThemeButtonDrawInfo * inNewInfo,
+ RgnHandle outRegion) ;
+extern OSStatus
+GetThemeButtonContentBounds(
+ const Rect * inBounds,
+ ThemeButtonKind inKind,
+ const ThemeButtonDrawInfo * inDrawInfo,
+ Rect * outBounds) ;
+extern OSStatus
+GetThemeButtonBackgroundBounds(
+ const Rect * inBounds,
+ ThemeButtonKind inKind,
+ const ThemeButtonDrawInfo * inDrawInfo,
+ Rect * outBounds) ;
+extern OSStatus
+PlayThemeSound(ThemeSoundKind kind) ;
+extern OSStatus
+BeginThemeDragSound(ThemeDragSoundKind kind) ;
+extern OSStatus
+EndThemeDragSound(void) ;
+extern OSStatus
+DrawThemeTickMark(
+ const Rect * bounds,
+ ThemeDrawState state) ;
+extern OSStatus
+DrawThemeChasingArrows(
+ const Rect * bounds,
+ UInt32 index,
+ ThemeDrawState state,
+ ThemeEraseUPP eraseProc,
+ UInt32 eraseData) ;
+extern OSStatus
+DrawThemePopupArrow(
+ const Rect * bounds,
+ ThemeArrowOrientation orientation,
+ ThemePopupArrowSize size,
+ ThemeDrawState state,
+ ThemeEraseUPP eraseProc,
+ UInt32 eraseData) ;
+extern OSStatus
+DrawThemeStandaloneGrowBox(
+ Point origin,
+ ThemeGrowDirection growDirection,
+ Boolean isSmall,
+ ThemeDrawState state) ;
+extern OSStatus
+DrawThemeStandaloneNoGrowBox(
+ Point origin,
+ ThemeGrowDirection growDirection,
+ Boolean isSmall,
+ ThemeDrawState state) ;
+extern OSStatus
+GetThemeStandaloneGrowBoxBounds(
+ Point origin,
+ ThemeGrowDirection growDirection,
+ Boolean isSmall,
+ Rect * bounds) ;
+extern OSStatus
+NormalizeThemeDrawingState(void) ;
+extern OSStatus
+GetThemeDrawingState(ThemeDrawingState * outState) ;
+extern OSStatus
+SetThemeDrawingState(
+ ThemeDrawingState inState,
+ Boolean inDisposeNow) ;
+extern OSStatus
+DisposeThemeDrawingState(ThemeDrawingState inState) ;
+extern OSStatus
+ApplyThemeBackground(
+ ThemeBackgroundKind inKind,
+ const Rect * bounds,
+ ThemeDrawState inState,
+ SInt16 inDepth,
+ Boolean inColorDev) ;
+extern OSStatus
+SetThemeTextColorForWindow(
+ WindowRef inWindow,
+ Boolean inActive,
+ SInt16 inDepth,
+ Boolean inColorDev) ;
+extern Boolean
+IsValidAppearanceFileType(OSType fileType) ;
+extern OSStatus
+GetThemeBrushAsColor(
+ ThemeBrush inBrush,
+ SInt16 inDepth,
+ Boolean inColorDev,
+ RGBColor * outColor) ;
+extern OSStatus
+GetThemeTextColor(
+ ThemeTextColor inColor,
+ SInt16 inDepth,
+ Boolean inColorDev,
+ RGBColor * outColor) ;
+extern OSStatus
+GetThemeMetric(
+ ThemeMetric inMetric,
+ SInt32 * outMetric) ;
+extern OSStatus
+CopyThemeIdentifier(CFStringRef * outIdentifier) ;
+
+
+
+
+
+
+enum {
+ appearanceBadBrushIndexErr = themeInvalidBrushErr,
+ appearanceProcessRegisteredErr = themeProcessRegisteredErr,
+ appearanceProcessNotRegisteredErr = themeProcessNotRegisteredErr,
+ appearanceBadTextColorIndexErr = themeBadTextColorErr,
+ appearanceThemeHasNoAccents = themeHasNoAccentsErr,
+ appearanceBadCursorIndexErr = themeBadCursorIndexErr
+};
+
+enum {
+ kThemeActiveDialogBackgroundBrush = kThemeBrushDialogBackgroundActive,
+ kThemeInactiveDialogBackgroundBrush = kThemeBrushDialogBackgroundInactive,
+ kThemeActiveAlertBackgroundBrush = kThemeBrushAlertBackgroundActive,
+ kThemeInactiveAlertBackgroundBrush = kThemeBrushAlertBackgroundInactive,
+ kThemeActiveModelessDialogBackgroundBrush = kThemeBrushModelessDialogBackgroundActive,
+ kThemeInactiveModelessDialogBackgroundBrush = kThemeBrushModelessDialogBackgroundInactive,
+ kThemeActiveUtilityWindowBackgroundBrush = kThemeBrushUtilityWindowBackgroundActive,
+ kThemeInactiveUtilityWindowBackgroundBrush = kThemeBrushUtilityWindowBackgroundInactive,
+ kThemeListViewSortColumnBackgroundBrush = kThemeBrushListViewSortColumnBackground,
+ kThemeListViewBackgroundBrush = kThemeBrushListViewBackground,
+ kThemeIconLabelBackgroundBrush = kThemeBrushIconLabelBackground,
+ kThemeListViewSeparatorBrush = kThemeBrushListViewSeparator,
+ kThemeChasingArrowsBrush = kThemeBrushChasingArrows,
+ kThemeDragHiliteBrush = kThemeBrushDragHilite,
+ kThemeDocumentWindowBackgroundBrush = kThemeBrushDocumentWindowBackground,
+ kThemeFinderWindowBackgroundBrush = kThemeBrushFinderWindowBackground
+};
+
+enum {
+ kThemeActiveScrollBarDelimiterBrush = kThemeBrushScrollBarDelimiterActive,
+ kThemeInactiveScrollBarDelimiterBrush = kThemeBrushScrollBarDelimiterInactive,
+ kThemeFocusHighlightBrush = kThemeBrushFocusHighlight,
+ kThemeActivePopupArrowBrush = kThemeBrushPopupArrowActive,
+ kThemePressedPopupArrowBrush = kThemeBrushPopupArrowPressed,
+ kThemeInactivePopupArrowBrush = kThemeBrushPopupArrowInactive,
+ kThemeAppleGuideCoachmarkBrush = kThemeBrushAppleGuideCoachmark
+};
+
+enum {
+ kThemeActiveDialogTextColor = kThemeTextColorDialogActive,
+ kThemeInactiveDialogTextColor = kThemeTextColorDialogInactive,
+ kThemeActiveAlertTextColor = kThemeTextColorAlertActive,
+ kThemeInactiveAlertTextColor = kThemeTextColorAlertInactive,
+ kThemeActiveModelessDialogTextColor = kThemeTextColorModelessDialogActive,
+ kThemeInactiveModelessDialogTextColor = kThemeTextColorModelessDialogInactive,
+ kThemeActiveWindowHeaderTextColor = kThemeTextColorWindowHeaderActive,
+ kThemeInactiveWindowHeaderTextColor = kThemeTextColorWindowHeaderInactive,
+ kThemeActivePlacardTextColor = kThemeTextColorPlacardActive,
+ kThemeInactivePlacardTextColor = kThemeTextColorPlacardInactive,
+ kThemePressedPlacardTextColor = kThemeTextColorPlacardPressed,
+ kThemeActivePushButtonTextColor = kThemeTextColorPushButtonActive,
+ kThemeInactivePushButtonTextColor = kThemeTextColorPushButtonInactive,
+ kThemePressedPushButtonTextColor = kThemeTextColorPushButtonPressed,
+ kThemeActiveBevelButtonTextColor = kThemeTextColorBevelButtonActive,
+ kThemeInactiveBevelButtonTextColor = kThemeTextColorBevelButtonInactive,
+ kThemePressedBevelButtonTextColor = kThemeTextColorBevelButtonPressed,
+ kThemeActivePopupButtonTextColor = kThemeTextColorPopupButtonActive,
+ kThemeInactivePopupButtonTextColor = kThemeTextColorPopupButtonInactive,
+ kThemePressedPopupButtonTextColor = kThemeTextColorPopupButtonPressed,
+ kThemeIconLabelTextColor = kThemeTextColorIconLabel,
+ kThemeListViewTextColor = kThemeTextColorListView
+};
+
+enum {
+ kThemeActiveDocumentWindowTitleTextColor = kThemeTextColorDocumentWindowTitleActive,
+ kThemeInactiveDocumentWindowTitleTextColor = kThemeTextColorDocumentWindowTitleInactive,
+ kThemeActiveMovableModalWindowTitleTextColor = kThemeTextColorMovableModalWindowTitleActive,
+ kThemeInactiveMovableModalWindowTitleTextColor = kThemeTextColorMovableModalWindowTitleInactive,
+ kThemeActiveUtilityWindowTitleTextColor = kThemeTextColorUtilityWindowTitleActive,
+ kThemeInactiveUtilityWindowTitleTextColor = kThemeTextColorUtilityWindowTitleInactive,
+ kThemeActivePopupWindowTitleColor = kThemeTextColorPopupWindowTitleActive,
+ kThemeInactivePopupWindowTitleColor = kThemeTextColorPopupWindowTitleInactive,
+ kThemeActiveRootMenuTextColor = kThemeTextColorRootMenuActive,
+ kThemeSelectedRootMenuTextColor = kThemeTextColorRootMenuSelected,
+ kThemeDisabledRootMenuTextColor = kThemeTextColorRootMenuDisabled,
+ kThemeActiveMenuItemTextColor = kThemeTextColorMenuItemActive,
+ kThemeSelectedMenuItemTextColor = kThemeTextColorMenuItemSelected,
+ kThemeDisabledMenuItemTextColor = kThemeTextColorMenuItemDisabled,
+ kThemeActivePopupLabelTextColor = kThemeTextColorPopupLabelActive,
+ kThemeInactivePopupLabelTextColor = kThemeTextColorPopupLabelInactive
+};
+
+enum {
+ kAEThemeSwitch = kAEAppearanceChanged
+};
+
+enum {
+ kThemeNoAdornment = kThemeAdornmentNone,
+ kThemeDefaultAdornment = kThemeAdornmentDefault,
+ kThemeFocusAdornment = kThemeAdornmentFocus,
+ kThemeRightToLeftAdornment = kThemeAdornmentRightToLeft,
+ kThemeDrawIndicatorOnly = kThemeAdornmentDrawIndicatorOnly
+};
+
+enum {
+ kThemeBrushPassiveAreaFill = kThemeBrushStaticAreaFill
+};
+
+enum {
+ kThemeMetricCheckBoxGlyphHeight = kThemeMetricCheckBoxHeight,
+ kThemeMetricRadioButtonGlyphHeight = kThemeMetricRadioButtonHeight,
+ kThemeMetricDisclosureButtonSize = kThemeMetricDisclosureButtonHeight,
+ kThemeMetricBestListHeaderHeight = kThemeMetricListHeaderHeight,
+ kThemeMetricSmallProgressBarThickness = kThemeMetricNormalProgressBarThickness,
+ kThemeMetricProgressBarThickness = kThemeMetricLargeProgressBarThickness
+};
+
+enum {
+ kThemeScrollBar = kThemeMediumScrollBar,
+ kThemeSlider = kThemeMediumSlider,
+ kThemeProgressBar = kThemeMediumProgressBar,
+ kThemeIndeterminateBar = kThemeMediumIndeterminateBar
+};
+
+
+
+
+}
+extern "C" {
+
+
+
+enum {
+
+ kControlDialogItem = 4,
+ kButtonDialogItem = kControlDialogItem | 0,
+ kCheckBoxDialogItem = kControlDialogItem | 1,
+ kRadioButtonDialogItem = kControlDialogItem | 2,
+ kResourceControlDialogItem = kControlDialogItem | 3,
+ kStaticTextDialogItem = 8,
+ kEditTextDialogItem = 16,
+ kIconDialogItem = 32,
+ kPictureDialogItem = 64,
+ kUserDialogItem = 0,
+ kHelpDialogItem = 1,
+ kItemDisableBit = 128
+};
+
+enum {
+
+ ctrlItem = 4,
+ btnCtrl = 0,
+ chkCtrl = 1,
+ radCtrl = 2,
+ resCtrl = 3,
+ statText = 8,
+ editText = 16,
+ iconItem = 32,
+ picItem = 64,
+ userItem = 0,
+ itemDisable = 128
+};
+
+enum {
+
+ kStdOkItemIndex = 1,
+ kStdCancelItemIndex = 2,
+ ok = kStdOkItemIndex,
+ cancel = kStdCancelItemIndex
+};
+
+enum {
+
+ kStopIcon = 0,
+ kNoteIcon = 1,
+ kCautionIcon = 2,
+ stopIcon = kStopIcon,
+ noteIcon = kNoteIcon,
+ cautionIcon = kCautionIcon
+};
+typedef SInt16 DITLMethod;
+enum {
+ overlayDITL = 0,
+ appendDITLRight = 1,
+ appendDITLBottom = 2
+};
+
+typedef SInt16 StageList;
+
+typedef DialogPtr DialogRef;
+struct DialogTemplate {
+ Rect boundsRect;
+ SInt16 procID;
+ Boolean visible;
+ Boolean filler1;
+ Boolean goAwayFlag;
+ Boolean filler2;
+ SInt32 refCon;
+ SInt16 itemsID;
+ Str255 title;
+};
+typedef struct DialogTemplate DialogTemplate;
+typedef DialogTemplate * DialogTPtr;
+typedef DialogTPtr * DialogTHndl;
+struct AlertTemplate {
+ Rect boundsRect;
+ SInt16 itemsID;
+ StageList stages;
+};
+typedef struct AlertTemplate AlertTemplate;
+typedef AlertTemplate * AlertTPtr;
+typedef AlertTPtr * AlertTHndl;
+
+typedef SInt16 DialogItemIndexZeroBased;
+typedef SInt16 DialogItemIndex;
+typedef SInt16 DialogItemType;
+
+typedef void ( * SoundProcPtr)(SInt16 soundNumber);
+typedef Boolean ( * ModalFilterProcPtr)(DialogRef theDialog, EventRecord *theEvent, DialogItemIndex *itemHit);
+
+typedef Boolean ( * ModalFilterYDProcPtr)(DialogRef theDialog, EventRecord *theEvent, short *itemHit, void *yourDataPtr);
+typedef void ( * UserItemProcPtr)(DialogRef theDialog, DialogItemIndex itemNo);
+typedef SoundProcPtr SoundUPP;
+typedef ModalFilterProcPtr ModalFilterUPP;
+typedef ModalFilterYDProcPtr ModalFilterYDUPP;
+typedef UserItemProcPtr UserItemUPP;
+extern ModalFilterUPP
+NewModalFilterUPP(ModalFilterProcPtr userRoutine) ;
+extern ModalFilterYDUPP
+NewModalFilterYDUPP(ModalFilterYDProcPtr userRoutine) ;
+extern UserItemUPP
+NewUserItemUPP(UserItemProcPtr userRoutine) ;
+extern void
+DisposeModalFilterUPP(ModalFilterUPP userUPP) ;
+extern void
+DisposeModalFilterYDUPP(ModalFilterYDUPP userUPP) ;
+extern void
+DisposeUserItemUPP(UserItemUPP userUPP) ;
+extern Boolean
+InvokeModalFilterUPP(
+ DialogRef theDialog,
+ EventRecord * theEvent,
+ DialogItemIndex * itemHit,
+ ModalFilterUPP userUPP) ;
+extern Boolean
+InvokeModalFilterYDUPP(
+ DialogRef theDialog,
+ EventRecord * theEvent,
+ short * itemHit,
+ void * yourDataPtr,
+ ModalFilterYDUPP userUPP) ;
+extern void
+InvokeUserItemUPP(
+ DialogRef theDialog,
+ DialogItemIndex itemNo,
+ UserItemUPP userUPP) ;
+
+
+
+
+
+
+
+enum {
+
+ kAlertStopAlert = 0,
+ kAlertNoteAlert = 1,
+ kAlertCautionAlert = 2,
+ kAlertPlainAlert = 3
+};
+
+typedef SInt16 AlertType;
+enum {
+ kAlertDefaultOKText = -1,
+ kAlertDefaultCancelText = -1,
+ kAlertDefaultOtherText = -1
+};
+
+
+enum {
+ kAlertStdAlertOKButton = 1,
+ kAlertStdAlertCancelButton = 2,
+ kAlertStdAlertOtherButton = 3,
+ kAlertStdAlertHelpButton = 4
+};
+
+enum {
+
+ kDialogFlagsUseThemeBackground = (1 << 0),
+ kDialogFlagsUseControlHierarchy = (1 << 1),
+ kDialogFlagsHandleMovableModal = (1 << 2),
+ kDialogFlagsUseThemeControls = (1 << 3)
+};
+
+enum {
+
+ kAlertFlagsUseThemeBackground = (1 << 0),
+ kAlertFlagsUseControlHierarchy = (1 << 1),
+ kAlertFlagsAlertIsMovable = (1 << 2),
+ kAlertFlagsUseThemeControls = (1 << 3)
+};
+
+
+enum {
+ kDialogFontNoFontStyle = 0,
+ kDialogFontUseFontMask = 0x0001,
+ kDialogFontUseFaceMask = 0x0002,
+ kDialogFontUseSizeMask = 0x0004,
+ kDialogFontUseForeColorMask = 0x0008,
+ kDialogFontUseBackColorMask = 0x0010,
+ kDialogFontUseModeMask = 0x0020,
+ kDialogFontUseJustMask = 0x0040,
+ kDialogFontUseAllMask = 0x00FF,
+ kDialogFontAddFontSizeMask = 0x0100,
+ kDialogFontUseFontNameMask = 0x0200,
+ kDialogFontAddToMetaFontMask = 0x0400
+};
+
+
+
+enum {
+ kDialogFontUseThemeFontIDMask = 0x0080
+};
+
+struct AlertStdAlertParamRec {
+ Boolean movable;
+ Boolean helpButton;
+ ModalFilterUPP filterProc;
+ ConstStringPtr defaultText;
+ ConstStringPtr cancelText;
+ ConstStringPtr otherText;
+ SInt16 defaultButton;
+ SInt16 cancelButton;
+ UInt16 position;
+
+};
+typedef struct AlertStdAlertParamRec AlertStdAlertParamRec;
+typedef AlertStdAlertParamRec * AlertStdAlertParamPtr;
+enum {
+ kHICommandOther = 'othr'
+};
+
+enum {
+ kStdCFStringAlertVersionOne = 1
+};
+
+
+
+
+
+
+
+enum {
+
+
+
+
+
+
+ kStdAlertDoNotDisposeSheet = 1 << 0,
+
+
+
+
+
+
+ kStdAlertDoNotAnimateOnDefault = 1 << 1,
+
+
+
+
+
+
+ kStdAlertDoNotAnimateOnCancel = 1 << 2,
+
+
+
+
+
+
+ kStdAlertDoNotAnimateOnOther = 1 << 3
+};
+
+struct AlertStdCFStringAlertParamRec {
+ UInt32 version;
+ Boolean movable;
+ Boolean helpButton;
+ CFStringRef defaultText;
+ CFStringRef cancelText;
+ CFStringRef otherText;
+ SInt16 defaultButton;
+ SInt16 cancelButton;
+ UInt16 position;
+
+ OptionBits flags;
+};
+typedef struct AlertStdCFStringAlertParamRec AlertStdCFStringAlertParamRec;
+typedef AlertStdCFStringAlertParamRec * AlertStdCFStringAlertParamPtr;
+extern DialogRef
+NewDialog(
+ void * dStorage,
+ const Rect * boundsRect,
+ ConstStr255Param title,
+ Boolean visible,
+ SInt16 procID,
+ WindowRef behind,
+ Boolean goAwayFlag,
+ SInt32 refCon,
+ Handle items) ;
+extern DialogRef
+GetNewDialog(
+ SInt16 dialogID,
+ void * dStorage,
+ WindowRef behind) ;
+extern DialogRef
+NewColorDialog(
+ void * dStorage,
+ const Rect * boundsRect,
+ ConstStr255Param title,
+ Boolean visible,
+ SInt16 procID,
+ WindowRef behind,
+ Boolean goAwayFlag,
+ SInt32 refCon,
+ Handle items) ;
+extern void
+DisposeDialog(DialogRef theDialog) ;
+extern void
+ModalDialog(
+ ModalFilterUPP modalFilter,
+ DialogItemIndex * itemHit) ;
+extern Boolean
+IsDialogEvent(const EventRecord * theEvent) ;
+extern Boolean
+DialogSelect(
+ const EventRecord * theEvent,
+ DialogRef * theDialog,
+ DialogItemIndex * itemHit) ;
+extern void
+DrawDialog(DialogRef theDialog) ;
+extern void
+UpdateDialog(
+ DialogRef theDialog,
+ RgnHandle updateRgn) ;
+extern void
+HideDialogItem(
+ DialogRef theDialog,
+ DialogItemIndex itemNo) ;
+extern void
+ShowDialogItem(
+ DialogRef theDialog,
+ DialogItemIndex itemNo) ;
+extern DialogItemIndexZeroBased
+FindDialogItem(
+ DialogRef theDialog,
+ Point thePt) ;
+extern void
+DialogCut(DialogRef theDialog) ;
+extern void
+DialogPaste(DialogRef theDialog) ;
+extern void
+DialogCopy(DialogRef theDialog) ;
+extern void
+DialogDelete(DialogRef theDialog) ;
+extern DialogItemIndex
+Alert(
+ SInt16 alertID,
+ ModalFilterUPP modalFilter) ;
+extern DialogItemIndex
+StopAlert(
+ SInt16 alertID,
+ ModalFilterUPP modalFilter) ;
+extern DialogItemIndex
+NoteAlert(
+ SInt16 alertID,
+ ModalFilterUPP modalFilter) ;
+extern DialogItemIndex
+CautionAlert(
+ SInt16 alertID,
+ ModalFilterUPP modalFilter) ;
+extern void
+GetDialogItem(
+ DialogRef theDialog,
+ DialogItemIndex itemNo,
+ DialogItemType * itemType,
+ Handle * item,
+ Rect * box) ;
+extern void
+SetDialogItem(
+ DialogRef theDialog,
+ DialogItemIndex itemNo,
+ DialogItemType itemType,
+ Handle item,
+ const Rect * box) ;
+extern void
+ParamText(
+ ConstStr255Param param0,
+ ConstStr255Param param1,
+ ConstStr255Param param2,
+ ConstStr255Param param3) ;
+extern void
+SelectDialogItemText(
+ DialogRef theDialog,
+ DialogItemIndex itemNo,
+ SInt16 strtSel,
+ SInt16 endSel) ;
+extern void
+GetDialogItemText(
+ Handle item,
+ Str255 text) ;
+extern void
+SetDialogItemText(
+ Handle item,
+ ConstStr255Param text) ;
+extern SInt16
+GetAlertStage(void) ;
+extern void
+SetDialogFont(SInt16 fontNum) ;
+extern void
+ResetAlertStage(void) ;
+extern void
+GetParamText(
+ StringPtr param0,
+ StringPtr param1,
+ StringPtr param2,
+ StringPtr param3) ;
+extern void
+AppendDITL(
+ DialogRef theDialog,
+ Handle theHandle,
+ DITLMethod method) ;
+extern DialogItemIndex
+CountDITL(DialogRef theDialog) ;
+extern void
+ShortenDITL(
+ DialogRef theDialog,
+ DialogItemIndex numberItems) ;
+extern OSStatus
+InsertDialogItem(
+ DialogRef theDialog,
+ DialogItemIndex afterItem,
+ DialogItemType itemType,
+ Handle itemHandle,
+ const Rect * box) ;
+extern OSStatus
+RemoveDialogItems(
+ DialogRef theDialog,
+ DialogItemIndex itemNo,
+ DialogItemIndex amountToRemove,
+ Boolean disposeItemData) ;
+extern Boolean
+StdFilterProc(
+ DialogRef theDialog,
+ EventRecord * event,
+ DialogItemIndex * itemHit) ;
+extern OSErr
+GetStdFilterProc(ModalFilterUPP * theProc) ;
+extern OSErr
+SetDialogDefaultItem(
+ DialogRef theDialog,
+ DialogItemIndex newItem) ;
+extern OSErr
+SetDialogCancelItem(
+ DialogRef theDialog,
+ DialogItemIndex newItem) ;
+extern OSErr
+SetDialogTracksCursor(
+ DialogRef theDialog,
+ Boolean tracks) ;
+extern DialogRef
+NewFeaturesDialog(
+ void * inStorage,
+ const Rect * inBoundsRect,
+ ConstStr255Param inTitle,
+ Boolean inIsVisible,
+ SInt16 inProcID,
+ WindowRef inBehind,
+ Boolean inGoAwayFlag,
+ SInt32 inRefCon,
+ Handle inItemListHandle,
+ UInt32 inFlags) ;
+extern OSErr
+AutoSizeDialog(DialogRef inDialog) ;
+extern OSErr
+StandardAlert(
+ AlertType inAlertType,
+ ConstStr255Param inError,
+ ConstStr255Param inExplanation,
+ const AlertStdAlertParamRec * inAlertParam,
+ SInt16 * outItemHit) ;
+extern OSStatus
+GetStandardAlertDefaultParams(
+ AlertStdCFStringAlertParamPtr param,
+ UInt32 version) ;
+extern OSStatus
+CreateStandardAlert(
+ AlertType alertType,
+ CFStringRef error,
+ CFStringRef explanation,
+ const AlertStdCFStringAlertParamRec * param,
+ DialogRef * outAlert) ;
+extern OSStatus
+RunStandardAlert(
+ DialogRef inAlert,
+ ModalFilterUPP filterProc,
+ DialogItemIndex * outItemHit) ;
+extern OSStatus
+CreateStandardSheet(
+ AlertType alertType,
+ CFStringRef error,
+ CFStringRef explanation,
+ const AlertStdCFStringAlertParamRec * param,
+ EventTargetRef notifyTarget,
+ DialogRef * outSheet) ;
+extern OSStatus
+CloseStandardSheet(
+ DialogRef inSheet,
+ UInt32 inResultCommand) ;
+extern OSErr
+GetDialogItemAsControl(
+ DialogRef inDialog,
+ SInt16 inItemNo,
+ ControlRef * outControl) ;
+extern OSErr
+MoveDialogItem(
+ DialogRef inDialog,
+ SInt16 inItemNo,
+ SInt16 inHoriz,
+ SInt16 inVert) ;
+extern OSErr
+SizeDialogItem(
+ DialogRef inDialog,
+ SInt16 inItemNo,
+ SInt16 inWidth,
+ SInt16 inHeight) ;
+extern OSErr
+AppendDialogItemList(
+ DialogRef dialog,
+ SInt16 ditlID,
+ DITLMethod method) ;
+extern OSStatus
+SetDialogTimeout(
+ DialogRef inDialog,
+ SInt16 inButtonToPress,
+ UInt32 inSecondsToWait) ;
+extern OSStatus
+GetDialogTimeout(
+ DialogRef inDialog,
+ SInt16 * outButtonToPress,
+ UInt32 * outSecondsToWait,
+ UInt32 * outSecondsRemaining) ;
+extern OSStatus
+SetModalDialogEventMask(
+ DialogRef inDialog,
+ EventMask inMask) ;
+extern OSStatus
+GetModalDialogEventMask(
+ DialogRef inDialog,
+ EventMask * outMask) ;
+extern WindowRef
+GetDialogWindow(DialogRef dialog) ;
+extern TEHandle
+GetDialogTextEditHandle(DialogRef dialog) ;
+extern SInt16
+GetDialogDefaultItem(DialogRef dialog) ;
+extern SInt16
+GetDialogCancelItem(DialogRef dialog) ;
+extern SInt16
+GetDialogKeyboardFocusItem(DialogRef dialog) ;
+extern void
+SetPortDialogPort(DialogRef dialog) ;
+extern CGrafPtr
+GetDialogPort(DialogRef dialog) ;
+extern DialogRef
+GetDialogFromWindow(WindowRef window) ;
+
+
+}
+
+
+
+extern "C" {
+
+
+
+typedef Point Cell;
+typedef Rect ListBounds;
+typedef char DataArray[32001];
+typedef char * DataPtr;
+typedef DataPtr * DataHandle;
+typedef short ( * ListSearchProcPtr)(Ptr aPtr, Ptr bPtr, short aLen, short bLen);
+typedef Boolean ( * ListClickLoopProcPtr)(void);
+typedef ListSearchProcPtr ListSearchUPP;
+typedef ListClickLoopProcPtr ListClickLoopUPP;
+struct ListRec {
+ Rect rView;
+ GrafPtr port;
+ Point indent;
+ Point cellSize;
+ ListBounds visible;
+ ControlRef vScroll;
+ ControlRef hScroll;
+ SInt8 selFlags;
+ Boolean lActive;
+ SInt8 lReserved;
+ SInt8 listFlags;
+ long clikTime;
+ Point clikLoc;
+ Point mouseLoc;
+ ListClickLoopUPP lClickLoop;
+ Cell lastClick;
+ long refCon;
+ Handle listDefProc;
+ Handle userHandle;
+ ListBounds dataBounds;
+ DataHandle cells;
+ short maxIndex;
+ short cellArray[1];
+};
+typedef struct ListRec ListRec;
+typedef ListRec * ListPtr;
+typedef ListPtr * ListHandle;
+
+typedef ListHandle ListRef;
+
+
+enum {
+
+ lDrawingModeOffBit = 3,
+ lDoVAutoscrollBit = 1,
+ lDoHAutoscrollBit = 0
+};
+
+enum {
+
+ lDrawingModeOff = 8,
+ lDoVAutoscroll = 2,
+ lDoHAutoscroll = 1
+};
+
+
+enum {
+
+ lOnlyOneBit = 7,
+ lExtendDragBit = 6,
+ lNoDisjointBit = 5,
+ lNoExtendBit = 4,
+ lNoRectBit = 3,
+ lUseSenseBit = 2,
+ lNoNilHiliteBit = 1
+};
+
+
+enum {
+
+ lOnlyOne = -128,
+ lExtendDrag = 64,
+ lNoDisjoint = 32,
+ lNoExtend = 16,
+ lNoRect = 8,
+ lUseSense = 4,
+ lNoNilHilite = 2
+};
+
+
+enum {
+
+ lInitMsg = 0,
+ lDrawMsg = 1,
+ lHiliteMsg = 2,
+ lCloseMsg = 3
+};
+
+
+
+
+
+struct StandardIconListCellDataRec {
+ Handle iconHandle;
+ short font;
+ short face;
+ short size;
+ Str255 name;
+};
+typedef struct StandardIconListCellDataRec StandardIconListCellDataRec;
+typedef StandardIconListCellDataRec * StandardIconListCellDataPtr;
+
+
+typedef void ( * ListDefProcPtr)(short lMessage, Boolean lSelect, Rect *lRect, Cell lCell, short lDataOffset, short lDataLen, ListHandle lHandle);
+typedef ListDefProcPtr ListDefUPP;
+extern ListSearchUPP
+NewListSearchUPP(ListSearchProcPtr userRoutine) ;
+extern ListClickLoopUPP
+NewListClickLoopUPP(ListClickLoopProcPtr userRoutine) ;
+extern ListDefUPP
+NewListDefUPP(ListDefProcPtr userRoutine) ;
+extern void
+DisposeListSearchUPP(ListSearchUPP userUPP) ;
+extern void
+DisposeListClickLoopUPP(ListClickLoopUPP userUPP) ;
+extern void
+DisposeListDefUPP(ListDefUPP userUPP) ;
+extern short
+InvokeListSearchUPP(
+ Ptr aPtr,
+ Ptr bPtr,
+ short aLen,
+ short bLen,
+ ListSearchUPP userUPP) ;
+extern Boolean
+InvokeListClickLoopUPP(ListClickLoopUPP userUPP) ;
+extern void
+InvokeListDefUPP(
+ short lMessage,
+ Boolean lSelect,
+ Rect * lRect,
+ Cell lCell,
+ short lDataOffset,
+ short lDataLen,
+ ListHandle lHandle,
+ ListDefUPP userUPP) ;
+
+enum {
+ kListDefProcPtr = 0,
+ kListDefUserProcType = kListDefProcPtr,
+ kListDefStandardTextType = 1,
+ kListDefStandardIconType = 2
+};
+
+typedef UInt32 ListDefType;
+struct ListDefSpec {
+ ListDefType defType;
+ union {
+ ListDefUPP userProc;
+ } u;
+};
+typedef struct ListDefSpec ListDefSpec;
+typedef ListDefSpec * ListDefSpecPtr;
+extern OSStatus
+CreateCustomList(
+ const Rect * rView,
+ const ListBounds * dataBounds,
+ Point cellSize,
+ const ListDefSpec * theSpec,
+ WindowRef theWindow,
+ Boolean drawIt,
+ Boolean hasGrow,
+ Boolean scrollHoriz,
+ Boolean scrollVert,
+ ListHandle * outList) ;
+extern ListHandle
+LNew(
+ const Rect * rView,
+ const ListBounds * dataBounds,
+ Point cSize,
+ short theProc,
+ WindowRef theWindow,
+ Boolean drawIt,
+ Boolean hasGrow,
+ Boolean scrollHoriz,
+ Boolean scrollVert) ;
+extern void
+LDispose(ListHandle lHandle) ;
+extern short
+LAddColumn(
+ short count,
+ short colNum,
+ ListHandle lHandle) ;
+extern short
+LAddRow(
+ short count,
+ short rowNum,
+ ListHandle lHandle) ;
+extern void
+LDelColumn(
+ short count,
+ short colNum,
+ ListHandle lHandle) ;
+extern void
+LDelRow(
+ short count,
+ short rowNum,
+ ListHandle lHandle) ;
+extern Boolean
+LGetSelect(
+ Boolean next,
+ Cell * theCell,
+ ListHandle lHandle) ;
+extern Cell
+LLastClick(ListHandle lHandle) ;
+extern Boolean
+LNextCell(
+ Boolean hNext,
+ Boolean vNext,
+ Cell * theCell,
+ ListHandle lHandle) ;
+extern Boolean
+LSearch(
+ const void * dataPtr,
+ short dataLen,
+ ListSearchUPP searchProc,
+ Cell * theCell,
+ ListHandle lHandle) ;
+extern void
+LSize(
+ short listWidth,
+ short listHeight,
+ ListHandle lHandle) ;
+extern void
+LSetDrawingMode(
+ Boolean drawIt,
+ ListHandle lHandle) ;
+extern void
+LScroll(
+ short dCols,
+ short dRows,
+ ListHandle lHandle) ;
+extern void
+LAutoScroll(ListHandle lHandle) ;
+extern void
+LUpdate(
+ RgnHandle theRgn,
+ ListHandle lHandle) ;
+extern void
+LActivate(
+ Boolean act,
+ ListHandle lHandle) ;
+extern void
+LCellSize(
+ Point cSize,
+ ListHandle lHandle) ;
+extern Boolean
+LClick(
+ Point pt,
+ EventModifiers modifiers,
+ ListHandle lHandle) ;
+extern void
+LAddToCell(
+ const void * dataPtr,
+ short dataLen,
+ Cell theCell,
+ ListHandle lHandle) ;
+extern void
+LClrCell(
+ Cell theCell,
+ ListHandle lHandle) ;
+extern void
+LGetCell(
+ void * dataPtr,
+ short * dataLen,
+ Cell theCell,
+ ListHandle lHandle) ;
+extern void
+LRect(
+ Rect * cellRect,
+ Cell theCell,
+ ListHandle lHandle) ;
+extern void
+LSetCell(
+ const void * dataPtr,
+ short dataLen,
+ Cell theCell,
+ ListHandle lHandle) ;
+extern void
+LSetSelect(
+ Boolean setIt,
+ Cell theCell,
+ ListHandle lHandle) ;
+extern void
+LDraw(
+ Cell theCell,
+ ListHandle lHandle) ;
+extern void
+LGetCellDataLocation(
+ short * offset,
+ short * len,
+ Cell theCell,
+ ListHandle lHandle) ;
+extern OSStatus
+RegisterListDefinition(
+ SInt16 inResID,
+ ListDefSpecPtr inDefSpec) ;
+extern Rect *
+GetListViewBounds(
+ ListHandle list,
+ Rect * view) ;
+extern CGrafPtr
+GetListPort(ListHandle list) ;
+extern Point *
+GetListCellIndent(
+ ListHandle list,
+ Point * indent) ;
+extern Point *
+GetListCellSize(
+ ListHandle list,
+ Point * size) ;
+extern ListBounds *
+GetListVisibleCells(
+ ListHandle list,
+ ListBounds * visible) ;
+extern ControlRef
+GetListVerticalScrollBar(ListHandle list) ;
+extern ControlRef
+GetListHorizontalScrollBar(ListHandle list) ;
+extern Boolean
+GetListActive(ListHandle list) ;
+extern SInt32
+GetListClickTime(ListHandle list) ;
+extern Point *
+GetListClickLocation(
+ ListHandle list,
+ Point * click) ;
+extern Point *
+GetListMouseLocation(
+ ListHandle list,
+ Point * mouse) ;
+extern ListClickLoopUPP
+GetListClickLoop(ListHandle list) ;
+extern SInt32
+GetListRefCon(ListHandle list) ;
+extern Handle
+GetListDefinition(ListHandle list) ;
+extern Handle
+GetListUserHandle(ListHandle list) ;
+extern ListBounds *
+GetListDataBounds(
+ ListHandle list,
+ ListBounds * bounds) ;
+extern DataHandle
+GetListDataHandle(ListHandle list) ;
+extern OptionBits
+GetListFlags(ListHandle list) ;
+extern OptionBits
+GetListSelectionFlags(ListHandle list) ;
+extern void
+SetListViewBounds(
+ ListHandle list,
+ const Rect * view) ;
+extern void
+SetListPort(
+ ListHandle list,
+ CGrafPtr port) ;
+extern void
+SetListCellIndent(
+ ListHandle list,
+ Point * indent) ;
+extern void
+SetListClickTime(
+ ListHandle list,
+ SInt32 time) ;
+extern void
+SetListClickLoop(
+ ListHandle list,
+ ListClickLoopUPP clickLoop) ;
+extern void
+SetListLastClick(
+ ListHandle list,
+ Cell * lastClick) ;
+extern void
+SetListRefCon(
+ ListHandle list,
+ SInt32 refCon) ;
+extern void
+SetListUserHandle(
+ ListHandle list,
+ Handle userHandle) ;
+extern void
+SetListFlags(
+ ListHandle list,
+ OptionBits listFlags) ;
+extern void
+SetListSelectionFlags(
+ ListHandle list,
+ OptionBits selectionFlags) ;
+
+
+}
+extern "C" {
+
+
+
+
+
+typedef Boolean ( * AEIdleProcPtr)(EventRecord *theEvent, long *sleepTime, RgnHandle *mouseRgn);
+typedef Boolean ( * AEFilterProcPtr)(EventRecord *theEvent, long returnID, long transactionID, const AEAddressDesc *sender);
+typedef AEIdleProcPtr AEIdleUPP;
+typedef AEFilterProcPtr AEFilterUPP;
+extern OSErr
+AESend(
+ const AppleEvent * theAppleEvent,
+ AppleEvent * reply,
+ AESendMode sendMode,
+ AESendPriority sendPriority,
+ long timeOutInTicks,
+ AEIdleUPP idleProc,
+ AEFilterUPP filterProc) ;
+extern OSErr
+AEProcessAppleEvent(const EventRecord * theEventRecord) ;
+extern OSErr
+AEResetTimer(const AppleEvent * reply) ;
+typedef SInt8 AEInteractAllowed;
+enum {
+ kAEInteractWithSelf = 0,
+ kAEInteractWithLocal = 1,
+ kAEInteractWithAll = 2
+};
+extern OSErr
+AEGetInteractionAllowed(AEInteractAllowed * level) ;
+extern OSErr
+AESetInteractionAllowed(AEInteractAllowed level) ;
+extern OSErr
+AEInteractWithUser(
+ long timeOutInTicks,
+ NMRecPtr nmReqPtr,
+ AEIdleUPP idleProc) ;
+extern OSErr
+AESuspendTheCurrentEvent(const AppleEvent * theAppleEvent) ;
+enum {
+ kAEDoNotIgnoreHandler = 0x00000000,
+ kAEIgnoreAppPhacHandler = 0x00000001,
+ kAEIgnoreAppEventHandler = 0x00000002,
+ kAEIgnoreSysPhacHandler = 0x00000004,
+ kAEIgnoreSysEventHandler = 0x00000008,
+ kAEIngoreBuiltInEventHandler = 0x00000010,
+ kAEDontDisposeOnResume = (long)0x80000000
+};
+
+
+enum {
+ kAENoDispatch = 0,
+ kAEUseStandardDispatch = (long)0xFFFFFFFF
+};
+extern OSErr
+AEResumeTheCurrentEvent(
+ const AppleEvent * theAppleEvent,
+ const AppleEvent * reply,
+ AEEventHandlerUPP dispatcher,
+ long handlerRefcon) ;
+extern OSErr
+AEGetTheCurrentEvent(AppleEvent * theAppleEvent) ;
+extern OSErr
+AESetTheCurrentEvent(const AppleEvent * theAppleEvent) ;
+extern AEIdleUPP
+NewAEIdleUPP(AEIdleProcPtr userRoutine) ;
+extern AEFilterUPP
+NewAEFilterUPP(AEFilterProcPtr userRoutine) ;
+extern void
+DisposeAEIdleUPP(AEIdleUPP userUPP) ;
+extern void
+DisposeAEFilterUPP(AEFilterUPP userUPP) ;
+extern Boolean
+InvokeAEIdleUPP(
+ EventRecord * theEvent,
+ long * sleepTime,
+ RgnHandle * mouseRgn,
+ AEIdleUPP userUPP) ;
+extern Boolean
+InvokeAEFilterUPP(
+ EventRecord * theEvent,
+ long returnID,
+ long transactionID,
+ const AEAddressDesc * sender,
+ AEFilterUPP userUPP) ;
+
+
+
+
+
+
+}
+extern "C" {
+
+
+
+enum {
+ kTextService = 'tsvc',
+ kTSMVersion = 0x0150
+};
+
+
+
+
+
+
+enum {
+ kKeyboardInputMethodClass = 'inpm',
+ kInkInputMethodClass = 'ink ',
+ kCharacterPaletteInputMethodClass = 'cplt'
+};
+
+typedef OSType TextServiceClass;
+enum {
+ kTSClassHonorUserSetting = 1,
+ kTSClassForceSetting = 2,
+ kTSClassForceToHonorUserSetting = 3
+};
+
+typedef UInt32 TSClassEnablingForceLevel;
+enum {
+ kUnicodeDocument = 'udoc',
+ kUnicodeTextService = 'utsv'
+};
+
+
+enum {
+ kTSMDocumentPropertySupportGlyphInfo = 'dpgi'
+};
+
+
+
+enum {
+ kUnknownLanguage = 0xFFFF,
+ kUnknownScript = 0xFFFF,
+ kNeutralScript = 0xFFFF
+};
+
+
+enum {
+ kTextServiceVersion2 = 'tsv2'
+};
+
+
+
+enum {
+ kInteractiveServicesTag = 'tmin',
+ kLocaleIDTag = 'loce',
+ kTextInputObjectTag = 'tiot',
+ kLocaleObjectRefTag = 'lobj',
+ kLocaleRefTag = 'lref',
+ kKeyboardInputMethodContextTag = 'kinp',
+ kKeyboardLocaleObjectRefTag = 'kilo',
+ kHandwritingInputMethodContextTag = 'hinp',
+ kHandwritingLocaleObjectRefTag = 'hilo',
+ kSpeechInputMethodContextTag = 'sinp',
+ kSpeechLocaleObjectRefTag = 'silo',
+ kPasswordModeTag = 'pwdm',
+ kRefconTag = 'refc',
+ kUseFloatingWindowTag = 'uswm',
+ kReadOnlyDocumentTag = 'isro',
+ kSupportsMultiInlineHolesTag = 'minl',
+ kProtocolVersionTag = 'nprt',
+ kTSMContextCollectionTag = 'tsmx'
+};
+
+
+
+enum {
+ kIMRomanInputMode = 'romn',
+ kIMPasswordInputMode = 'pasw',
+ kIMXingInputMode = 'xing',
+ kIMHuaInputMode = 'huam',
+ kIMPinyinInputMode = 'piny',
+ kIMQuweiInputMode = 'quwe',
+ kIMCangjieInputMode = 'cgji',
+ kIMJianyiInputMode = 'jnyi',
+ kIMZhuyinInputMode = 'zhuy',
+ kIMB5CodeInputMode = 'b5cd',
+ kIMKatakanaInputMode = 'kata',
+ kIMHiraganaInputMode = 'hira'
+};
+
+
+
+enum {
+ kIM2ByteInputMode = '2byt',
+ kIM1ByteInputMode = '1byt',
+ kIMDirectInputMode = 'dinp'
+};
+enum {
+ kNeedsInputWindow = 1,
+ kHandlesUpdateRegion = 2,
+ kHandlesGetRegion = 3,
+ kHandlesPos2Offset = 4,
+ kHandlesOffset2Pos = 5,
+ kInPasswordMode = 6,
+ kHandleMultipleHoles = 7,
+ kDocumentIsReadOnly = 8
+};
+
+enum {
+
+ bTakeActiveEvent = 15,
+ bHandleAERecording = 16,
+ bScriptMask = 0x00007F00,
+ bLanguageMask = 0x000000FF,
+ bScriptLanguageMask = bScriptMask + bLanguageMask
+};
+
+enum {
+
+ kIMJaTypingMethodProperty = 'jtyp',
+ kIMJaTypingMethodRoman = 'roma',
+ kIMJaTypingMethodKana = 'kana'
+};
+
+enum {
+
+ kCMGetScriptLangSupport = 0x0001,
+ kCMInitiateTextService = 0x0002,
+ kCMTerminateTextService = 0x0003,
+ kCMActivateTextService = 0x0004,
+ kCMDeactivateTextService = 0x0005,
+ kCMTextServiceEvent = 0x0006,
+ kCMGetTextServiceMenu = 0x0007,
+ kCMTextServiceMenuSelect = 0x0008,
+ kCMFixTextService = 0x0009,
+ kCMSetTextServiceCursor = 0x000A,
+ kCMHidePaletteWindows = 0x000B,
+ kCMGetTextServiceProperty = 0x000C,
+ kCMSetTextServiceProperty = 0x000D
+};
+
+enum {
+
+ kCMUCTextServiceEvent = 0x000E
+};
+
+
+
+
+
+
+
+typedef struct OpaqueTSMContext* TSMContext;
+typedef struct OpaqueTSMDocumentID* TSMDocumentID;
+typedef OSType InterfaceTypeList[1];
+
+
+struct TextServiceInfo {
+ Component fComponent;
+ Str255 fItemName;
+};
+typedef struct TextServiceInfo TextServiceInfo;
+typedef TextServiceInfo * TextServiceInfoPtr;
+struct TextServiceList {
+ short fTextServiceCount;
+ TextServiceInfo fServices[1];
+};
+typedef struct TextServiceList TextServiceList;
+typedef TextServiceList * TextServiceListPtr;
+typedef TextServiceListPtr * TextServiceListHandle;
+struct ScriptLanguageRecord {
+ ScriptCode fScript;
+ LangCode fLanguage;
+};
+typedef struct ScriptLanguageRecord ScriptLanguageRecord;
+struct ScriptLanguageSupport {
+ short fScriptLanguageCount;
+ ScriptLanguageRecord fScriptLanguageArray[1];
+};
+typedef struct ScriptLanguageSupport ScriptLanguageSupport;
+typedef ScriptLanguageSupport * ScriptLanguageSupportPtr;
+typedef ScriptLanguageSupportPtr * ScriptLanguageSupportHandle;
+struct TSMGlyphInfo {
+ CFRange range;
+ ATSFontRef fontRef;
+ UInt16 collection;
+ UInt16 glyphID;
+};
+typedef struct TSMGlyphInfo TSMGlyphInfo;
+struct TSMGlyphInfoArray {
+ ItemCount numGlyphInfo;
+ TSMGlyphInfo glyphInfo[1];
+};
+typedef struct TSMGlyphInfoArray TSMGlyphInfoArray;
+extern OSErr
+NewTSMDocument(
+ short numOfInterface,
+ InterfaceTypeList supportedInterfaceTypes,
+ TSMDocumentID * idocID,
+ long refcon) ;
+extern OSErr
+DeleteTSMDocument(TSMDocumentID idocID) ;
+extern OSErr
+ActivateTSMDocument(TSMDocumentID idocID) ;
+extern OSErr
+DeactivateTSMDocument(TSMDocumentID idocID) ;
+extern OSErr
+FixTSMDocument(TSMDocumentID idocID) ;
+extern OSErr
+GetServiceList(
+ short numOfInterface,
+ OSType * supportedInterfaceTypes,
+ TextServiceListHandle * serviceInfo,
+ long * seedValue) ;
+extern OSErr
+OpenTextService(
+ TSMDocumentID idocID,
+ Component aComponent,
+ ComponentInstance * aComponentInstance) ;
+extern OSErr
+CloseTextService(
+ TSMDocumentID idocID,
+ ComponentInstance aComponentInstance) ;
+extern OSErr
+SendAEFromTSMComponent(
+ const AppleEvent * theAppleEvent,
+ AppleEvent * reply,
+ AESendMode sendMode,
+ AESendPriority sendPriority,
+ long timeOutInTicks,
+ AEIdleUPP idleProc,
+ AEFilterUPP filterProc) ;
+extern OSStatus
+SendTextInputEvent(EventRef inEvent) ;
+extern OSErr
+SetDefaultInputMethod(
+ Component ts,
+ ScriptLanguageRecord * slRecordPtr) ;
+extern OSErr
+GetDefaultInputMethod(
+ Component * ts,
+ ScriptLanguageRecord * slRecordPtr) ;
+extern OSErr
+SetTextServiceLanguage(ScriptLanguageRecord * slRecordPtr) ;
+extern OSErr
+GetTextServiceLanguage(ScriptLanguageRecord * slRecordPtr) ;
+extern OSErr
+UseInputWindow(
+ TSMDocumentID idocID,
+ Boolean useWindow) ;
+extern OSStatus
+TSMSetInlineInputRegion(
+ TSMDocumentID inTSMDocument,
+ WindowRef inWindow,
+ RgnHandle inRegion) ;
+extern ComponentResult
+GetScriptLanguageSupport(
+ ComponentInstance ts,
+ ScriptLanguageSupportHandle * scriptHdl) ;
+extern ComponentResult
+InitiateTextService(ComponentInstance ts) ;
+extern ComponentResult
+TerminateTextService(ComponentInstance ts) ;
+extern ComponentResult
+ActivateTextService(ComponentInstance ts) ;
+extern ComponentResult
+DeactivateTextService(ComponentInstance ts) ;
+extern ComponentResult
+GetTextServiceMenu(
+ ComponentInstance ts,
+ MenuRef * serviceMenu) ;
+extern ComponentResult
+TextServiceEventRef(
+ ComponentInstance ts,
+ EventRef event) ;
+extern ComponentResult
+FixTextService(ComponentInstance ts) ;
+extern ComponentResult
+HidePaletteWindows(ComponentInstance ts) ;
+extern ComponentResult
+GetTextServiceProperty(
+ ComponentInstance ts,
+ OSType propertySelector,
+ SInt32 * result) ;
+extern ComponentResult
+SetTextServiceProperty(
+ ComponentInstance ts,
+ OSType propertySelector,
+ SInt32 value) ;
+extern TSMDocumentID
+TSMGetActiveDocument(void) ;
+extern OSStatus
+GetDefaultInputMethodOfClass(
+ Component * aComp,
+ ScriptLanguageRecord * slRecPtr,
+ TextServiceClass tsClass) ;
+extern OSStatus
+SetDefaultInputMethodOfClass(
+ Component aComp,
+ ScriptLanguageRecord * slRecPtr,
+ TextServiceClass tsClass) ;
+extern OSStatus
+DeselectTextService(Component aComp) ;
+extern OSStatus
+SelectTextService(Component aComp) ;
+extern OSStatus
+TSMSetDocumentProperty(
+ TSMDocumentID docID,
+ OSType propertyTag,
+ UInt32 propertySize,
+ void * propertyData) ;
+extern OSStatus
+TSMGetDocumentProperty(
+ TSMDocumentID docID,
+ OSType propertyTag,
+ UInt32 bufferSize,
+ UInt32 * actualSize,
+ void * propertyBuffer) ;
+extern OSStatus
+TSMRemoveDocumentProperty(
+ TSMDocumentID docID,
+ OSType propertyTag) ;
+
+
+}
+
+
+
+extern "C" {
+
+
+typedef FourCharCode ScrapFlavorType;
+
+
+
+
+
+
+enum {
+ kScrapFlavorTypePicture = 'PICT',
+ kScrapFlavorTypeText = 'TEXT',
+ kScrapFlavorTypeTextStyle = 'styl',
+ kScrapFlavorTypeMovie = 'moov',
+ kScrapFlavorTypeSound = 'snd ',
+ kScrapFlavorTypeUnicode = 'utxt',
+ kScrapFlavorTypeUnicodeStyle = 'ustl'
+};
+extern OSStatus
+LoadScrap(void) ;
+extern OSStatus
+UnloadScrap(void) ;
+enum {
+ kScrapFlavorSizeUnknown = -1
+};
+
+
+
+
+
+
+
+enum {
+ kScrapReservedFlavorType = 'srft'
+};
+enum {
+ kScrapFlavorMaskNone = 0x00000000,
+ kScrapFlavorMaskSenderOnly = 0x00000001,
+ kScrapFlavorMaskTranslated = 0x00000002
+};
+
+typedef UInt32 ScrapFlavorFlags;
+
+
+
+
+struct ScrapFlavorInfo {
+ ScrapFlavorType flavorType;
+ ScrapFlavorFlags flavorFlags;
+};
+typedef struct ScrapFlavorInfo ScrapFlavorInfo;
+typedef struct OpaqueScrapRef* ScrapRef;
+enum {
+ kScrapGetNamedScrap = 0,
+ kScrapClearNamedScrap = (1L << 0)
+};
+extern OSStatus
+GetScrapByName(
+ CFStringRef name,
+ OptionBits options,
+ ScrapRef * scrap) ;
+extern OSStatus
+GetCurrentScrap(ScrapRef * scrap) ;
+extern OSStatus
+GetScrapFlavorFlags(
+ ScrapRef scrap,
+ ScrapFlavorType flavorType,
+ ScrapFlavorFlags * flavorFlags) ;
+extern OSStatus
+GetScrapFlavorSize(
+ ScrapRef scrap,
+ ScrapFlavorType flavorType,
+ Size * byteCount) ;
+extern OSStatus
+GetScrapFlavorData(
+ ScrapRef scrap,
+ ScrapFlavorType flavorType,
+ Size * byteCount,
+ void * destination) ;
+extern OSStatus
+ClearCurrentScrap(void) ;
+extern OSStatus
+ClearScrap(ScrapRef * inOutScrap) ;
+extern OSStatus
+PutScrapFlavor(
+ ScrapRef scrap,
+ ScrapFlavorType flavorType,
+ ScrapFlavorFlags flavorFlags,
+ Size flavorSize,
+ const void * flavorData) ;
+typedef OSStatus ( * ScrapPromiseKeeperProcPtr)(ScrapRef scrap, ScrapFlavorType flavorType, void *userData);
+typedef ScrapPromiseKeeperProcPtr ScrapPromiseKeeperUPP;
+extern ScrapPromiseKeeperUPP
+NewScrapPromiseKeeperUPP(ScrapPromiseKeeperProcPtr userRoutine) ;
+extern void
+DisposeScrapPromiseKeeperUPP(ScrapPromiseKeeperUPP userUPP) ;
+extern OSStatus
+InvokeScrapPromiseKeeperUPP(
+ ScrapRef scrap,
+ ScrapFlavorType flavorType,
+ void * userData,
+ ScrapPromiseKeeperUPP userUPP) ;
+extern OSStatus
+SetScrapPromiseKeeper(
+ ScrapRef scrap,
+ ScrapPromiseKeeperUPP upp,
+ const void * userData) ;
+extern OSStatus
+GetScrapFlavorCount(
+ ScrapRef scrap,
+ UInt32 * infoCount) ;
+extern OSStatus
+GetScrapFlavorInfoList(
+ ScrapRef scrap,
+ UInt32 * infoCount,
+ ScrapFlavorInfo info[]) ;
+extern OSStatus
+CallInScrapPromises(void) ;
+
+
+
+
+
+}
+
+
+
+extern "C" {
+
+
+
+
+
+typedef struct OpaqueTXNObject* TXNObject;
+typedef struct OpaqueTXNFontMenuObject* TXNFontMenuObject;
+typedef UInt32 TXNFrameID;
+typedef UInt32 TXNVersionValue;
+enum {
+ kTXNWillDefaultToATSUIBit = 0,
+ kTXNWillDefaultToCarbonEventBit = 1
+};
+
+
+typedef OptionBits TXNFeatureBits;
+enum {
+ kTXNWillDefaultToATSUIMask = 1L << kTXNWillDefaultToATSUIBit,
+ kTXNWillDefaultToCarbonEventMask = 1L << kTXNWillDefaultToCarbonEventBit
+};
+
+enum {
+ kTXNWantMoviesBit = 0,
+ kTXNWantSoundBit = 1,
+ kTXNWantGraphicsBit = 2,
+ kTXNAlwaysUseQuickDrawTextBit = 3,
+ kTXNUseTemporaryMemoryBit = 4
+};
+
+
+typedef OptionBits TXNInitOptions;
+enum {
+ kTXNWantMoviesMask = 1L << kTXNWantMoviesBit,
+ kTXNWantSoundMask = 1L << kTXNWantSoundBit,
+ kTXNWantGraphicsMask = 1L << kTXNWantGraphicsBit,
+ kTXNAlwaysUseQuickDrawTextMask = 1L << kTXNAlwaysUseQuickDrawTextBit,
+ kTXNUseTemporaryMemoryMask = 1L << kTXNUseTemporaryMemoryBit
+};
+
+enum {
+ kTXNDrawGrowIconBit = 0,
+ kTXNShowWindowBit = 1,
+ kTXNWantHScrollBarBit = 2,
+ kTXNWantVScrollBarBit = 3,
+ kTXNNoTSMEverBit = 4,
+ kTXNReadOnlyBit = 5,
+ kTXNNoKeyboardSyncBit = 6,
+ kTXNNoSelectionBit = 7,
+ kTXNSaveStylesAsSTYLResourceBit = 8,
+ kOutputTextInUnicodeEncodingBit = 9,
+ kTXNDoNotInstallDragProcsBit = 10,
+ kTXNAlwaysWrapAtViewEdgeBit = 11,
+ kTXNDontDrawCaretWhenInactiveBit = 12,
+ kTXNDontDrawSelectionWhenInactiveBit = 13,
+ kTXNSingleLineOnlyBit = 14,
+ kTXNDisableDragAndDropBit = 15,
+ kTXNUseQDforImagingBit = 16,
+ kTXNMonostyledTextBit = 17
+};
+typedef OptionBits TXNFrameOptions;
+enum {
+
+
+
+
+ kTXNDrawGrowIconMask = 1L << kTXNDrawGrowIconBit,
+
+
+
+
+
+
+
+ kTXNShowWindowMask = 1L << kTXNShowWindowBit,
+
+
+
+
+ kTXNWantHScrollBarMask = 1L << kTXNWantHScrollBarBit,
+
+
+
+
+ kTXNWantVScrollBarMask = 1L << kTXNWantVScrollBarBit,
+
+
+
+
+
+ kTXNNoTSMEverMask = 1L << kTXNNoTSMEverBit,
+
+
+
+
+ kTXNReadOnlyMask = 1L << kTXNReadOnlyBit,
+
+
+
+
+ kTXNNoKeyboardSyncMask = 1L << kTXNNoKeyboardSyncBit,
+
+
+
+
+
+ kTXNNoSelectionMask = 1L << kTXNNoSelectionBit,
+ kTXNSaveStylesAsSTYLResourceMask = 1L << kTXNSaveStylesAsSTYLResourceBit,
+
+
+
+
+ kOutputTextInUnicodeEncodingMask = 1L << kOutputTextInUnicodeEncodingBit,
+
+
+
+
+
+
+ kTXNDoNotInstallDragProcsMask = 1L << kTXNDoNotInstallDragProcsBit,
+
+
+
+
+ kTXNAlwaysWrapAtViewEdgeMask = 1L << kTXNAlwaysWrapAtViewEdgeBit,
+
+
+
+
+
+ kTXNDontDrawCaretWhenInactiveMask = 1L << kTXNDontDrawCaretWhenInactiveBit,
+
+
+
+
+
+ kTXNDontDrawSelectionWhenInactiveMask = 1L << kTXNDontDrawSelectionWhenInactiveBit,
+
+
+
+
+
+
+
+ kTXNSingleLineOnlyMask = 1L << kTXNSingleLineOnlyBit,
+
+
+
+
+
+ kTXNDisableDragAndDropMask = 1L << kTXNDisableDragAndDropBit,
+
+
+
+
+
+ kTXNUseQDforImagingMask = 1L << kTXNUseQDforImagingBit,
+
+
+
+
+
+ kTXNMonostyledTextMask = 1L << kTXNMonostyledTextBit
+};
+
+enum {
+ kTXNSetFlushnessBit = 0,
+ kTXNSetJustificationBit = 1,
+ kTXNUseFontFallBackBit = 2,
+ kTXNRotateTextBit = 3,
+ kTXNUseVerticalTextBit = 4,
+ kTXNDontUpdateBoxRectBit = 5,
+ kTXNDontDrawTextBit = 6,
+ kTXNUseCGContextRefBit = 7,
+ kTXNImageWithQDBit = 8,
+ kTXNDontWrapTextBit = 9
+};
+typedef OptionBits TXNTextBoxOptions;
+enum {
+
+
+
+
+
+ kTXNSetFlushnessMask = 1L << kTXNSetFlushnessBit,
+
+
+
+
+
+
+
+ kTXNSetJustificationMask = 1L << kTXNSetJustificationBit,
+
+
+
+
+
+ kTXNUseFontFallBackMask = 1L << kTXNUseFontFallBackBit,
+
+
+
+
+
+
+
+ kTXNRotateTextMask = 1L << kTXNRotateTextBit,
+
+
+
+
+
+ kTXNUseVerticalTextMask = 1L << kTXNUseVerticalTextBit,
+ kTXNDontUpdateBoxRectMask = 1L << kTXNDontUpdateBoxRectBit,
+
+
+
+
+
+ kTXNDontDrawTextMask = 1L << kTXNDontDrawTextBit,
+
+
+
+
+
+ kTXNUseCGContextRefMask = 1L << kTXNUseCGContextRefBit,
+
+
+
+
+
+ kTXNImageWithQDMask = 1L << kTXNImageWithQDBit,
+
+
+
+
+ kTXNDontWrapTextMask = 1L << kTXNDontWrapTextBit
+};
+
+struct TXNTextBoxOptionsData {
+ TXNTextBoxOptions optionTags;
+ Fract flushness;
+ Fract justification;
+ Fixed rotation;
+ void * options;
+};
+typedef struct TXNTextBoxOptionsData TXNTextBoxOptionsData;
+enum {
+ kTXNFontContinuousBit = 0,
+ kTXNSizeContinuousBit = 1,
+ kTXNStyleContinuousBit = 2,
+ kTXNColorContinuousBit = 3
+};
+
+typedef OptionBits TXNContinuousFlags;
+enum {
+ kTXNFontContinuousMask = 1L << kTXNFontContinuousBit,
+ kTXNSizeContinuousMask = 1L << kTXNSizeContinuousBit,
+ kTXNStyleContinuousMask = 1L << kTXNStyleContinuousBit,
+ kTXNColorContinuousMask = 1L << kTXNColorContinuousBit
+};
+
+enum {
+ kTXNIgnoreCaseBit = 0,
+ kTXNEntireWordBit = 1,
+ kTXNUseEncodingWordRulesBit = 31
+};
+
+typedef OptionBits TXNMatchOptions;
+enum {
+ kTXNIgnoreCaseMask = 1L << kTXNIgnoreCaseBit,
+ kTXNEntireWordMask = 1L << kTXNEntireWordBit,
+ kTXNUseEncodingWordRulesMask = (unsigned long)(1L << kTXNUseEncodingWordRulesBit)
+};
+
+
+typedef OSType TXNFileType;
+enum {
+ kTXNTextensionFile = 'txtn',
+ kTXNTextFile = 'TEXT',
+ kTXNPictureFile = 'PICT',
+ kTXNMovieFile = 'MooV',
+ kTXNSoundFile = 'sfil',
+ kTXNAIFFFile = 'AIFF',
+ kTXNUnicodeTextFile = 'utxt'
+};
+
+
+typedef UInt32 TXNFrameType;
+enum {
+ kTXNTextEditStyleFrameType = 1,
+ kTXNPageFrameType = 2,
+ kTXNMultipleFrameType = 3
+};
+
+
+typedef OSType TXNDataType;
+enum {
+ kTXNTextData = 'TEXT',
+ kTXNPictureData = 'PICT',
+ kTXNMovieData = 'moov',
+ kTXNSoundData = 'snd ',
+ kTXNUnicodeTextData = 'utxt'
+};
+
+
+typedef FourCharCode TXNControlTag;
+enum {
+ kTXNLineDirectionTag = 'lndr',
+ kTXNJustificationTag = 'just',
+ kTXNIOPrivilegesTag = 'iopv',
+ kTXNSelectionStateTag = 'slst',
+ kTXNInlineStateTag = 'inst',
+ kTXNWordWrapStateTag = 'wwrs',
+ kTXNKeyboardSyncStateTag = 'kbsy',
+ kTXNAutoIndentStateTag = 'auin',
+ kTXNTabSettingsTag = 'tabs',
+ kTXNRefConTag = 'rfcn',
+ kTXNMarginsTag = 'marg',
+ kTXNFlattenMoviesTag = 'flat',
+ kTXNDoFontSubstitution = 'fSub',
+ kTXNNoUserIOTag = 'nuio',
+ kTXNUseCarbonEvents = 'cbcb',
+ kTXNDrawCaretWhenInactiveTag = 'dcrt',
+ kTXNDrawSelectionWhenInactiveTag = 'dsln',
+ kTXNDisableDragAndDropTag = 'drag',
+ kTXNSingleLevelUndoTag = 'undo',
+ kTXNVisibilityTag = 'visb'
+};
+
+typedef UInt32 TXNActionKey;
+enum {
+ kTXNTypingAction = 0,
+ kTXNCutAction = 1,
+ kTXNPasteAction = 2,
+ kTXNClearAction = 3,
+ kTXNChangeFontAction = 4,
+ kTXNChangeFontColorAction = 5,
+ kTXNChangeFontSizeAction = 6,
+ kTXNChangeStyleAction = 7,
+ kTXNAlignLeftAction = 8,
+ kTXNAlignCenterAction = 9,
+ kTXNAlignRightAction = 10,
+ kTXNDropAction = 11,
+ kTXNMoveAction = 12,
+ kTXNFontFeatureAction = 13,
+ kTXNFontVariationAction = 14,
+ kTXNUndoLastAction = 1024
+};
+
+enum {
+ kTXNClearThisControl = (long)0xFFFFFFFF,
+ kTXNClearTheseFontFeatures = (long)0x80000000
+};
+
+
+
+
+
+enum {
+ kTXNReadWrite = false,
+ kTXNReadOnly = true
+};
+
+
+enum {
+ kTXNSelectionOn = true,
+ kTXNSelectionOff = false
+};
+
+
+enum {
+ kTXNUseInline = false,
+ kTXNUseBottomline = true
+};
+
+
+
+enum {
+ kTXNAutoWrap = false,
+ kTXNNoAutoWrap = true
+};
+
+
+enum {
+ kTXNSyncKeyboard = false,
+ kTXNNoSyncKeyboard = true
+};
+
+
+enum {
+ kTXNAutoIndentOff = false,
+ kTXNAutoIndentOn = true
+};
+
+
+enum {
+ kTXNDontDrawCaretWhenInactive = false,
+ kTXNDrawCaretWhenInactive = true
+};
+
+
+enum {
+ kTXNDontDrawSelectionWhenInactive = false,
+ kTXNDrawSelectionWhenInactive = true
+};
+
+
+enum {
+ kTXNEnableDragAndDrop = false,
+ kTXNDisableDragAndDrop = true
+};
+
+typedef SInt8 TXNTabType;
+enum {
+ kTXNRightTab = -1,
+ kTXNLeftTab = 0,
+ kTXNCenterTab = 1
+};
+
+struct TXNTab {
+ SInt16 value;
+ TXNTabType tabType;
+ UInt8 filler;
+};
+typedef struct TXNTab TXNTab;
+enum {
+ kTXNLeftToRight = 0,
+ kTXNRightToLeft = 1
+};
+
+enum {
+ kTXNFlushDefault = 0,
+ kTXNFlushLeft = 1,
+ kTXNFlushRight = 2,
+ kTXNCenter = 4,
+ kTXNFullJust = 8,
+ kTXNForceFullJust = 16
+};
+
+
+
+
+
+struct TXNMargins {
+ SInt16 topMargin;
+ SInt16 leftMargin;
+ SInt16 bottomMargin;
+ SInt16 rightMargin;
+};
+typedef struct TXNMargins TXNMargins;
+union TXNControlData {
+ UInt32 uValue;
+ SInt32 sValue;
+ TXNTab tabValue;
+ TXNMargins * marginsPtr;
+};
+typedef union TXNControlData TXNControlData;
+typedef Boolean TXNScrollBarState;
+enum {
+ kScrollBarsAlwaysActive = true,
+ kScrollBarsSyncWithFocus = false
+};
+
+
+
+
+
+enum {
+ kTXNDontCareTypeSize = (long)0xFFFFFFFF,
+ kTXNDontCareTypeStyle = 0xFF,
+ kTXNIncrementTypeSize = 0x00000001,
+ kTXNDecrementTypeSize = (long)0x80000000,
+ kTXNUseScriptDefaultValue = -1,
+ kTXNNoFontVariations = 0x7FFF
+};
+
+typedef UInt32 TXNOffset;
+enum {
+ kTXNUseCurrentSelection = (unsigned long)0xFFFFFFFF,
+ kTXNStartOffset = 0,
+ kTXNEndOffset = 0x7FFFFFFF
+};
+
+
+enum {
+ kTXNSingleStylePerTextDocumentResType = 'MPSR',
+ kTXNMultipleStylesPerTextDocumentResType = 'styl'
+};
+
+
+typedef void * TXNObjectRefcon;
+
+enum {
+ kTXNShowStart = false,
+ kTXNShowEnd = true
+};
+
+typedef OSStatus TXNErrors;
+
+
+enum {
+ kTXNDefaultFontSize = 0x000C0000
+};
+
+enum {
+ kTXNDefaultFontStyle = normal
+};
+
+
+typedef UInt32 TXNHyperLinkState;
+enum {
+ kTXNLinkNotPressed = 0,
+ kTXNLinkWasPressed = 1,
+ kTXNLinkTracking = 3
+};
+
+typedef FourCharCode TXNTypeRunAttributes;
+enum {
+ kTXNQDFontNameAttribute = 'fntn',
+ kTXNQDFontFamilyIDAttribute = 'font',
+ kTXNQDFontSizeAttribute = 'size',
+ kTXNQDFontStyleAttribute = 'face',
+ kTXNQDFontColorAttribute = 'klor',
+ kTXNTextEncodingAttribute = 'encd',
+ kTXNATSUIFontFeaturesAttribute = 'atfe',
+ kTXNATSUIFontVariationsAttribute = 'atva',
+ kTXNURLAttribute = 'urla'
+};
+
+
+
+
+
+
+typedef ByteCount TXNTypeRunAttributeSizes;
+enum {
+ kTXNQDFontNameAttributeSize = sizeof(Str255),
+ kTXNQDFontFamilyIDAttributeSize = sizeof(SInt16),
+ kTXNQDFontSizeAttributeSize = sizeof(SInt16),
+ kTXNQDFontStyleAttributeSize = sizeof(Style),
+ kTXNQDFontColorAttributeSize = sizeof(RGBColor),
+ kTXNTextEncodingAttributeSize = sizeof(TextEncoding),
+ kTXNFontSizeAttributeSize = sizeof(Fixed)
+};
+
+typedef UInt32 TXNPermanentTextEncodingType;
+enum {
+ kTXNSystemDefaultEncoding = 0,
+ kTXNMacOSEncoding = 1,
+ kTXNUnicodeEncoding = 2
+};
+
+
+
+typedef FourCharCode TXTNTag;
+struct TXNATSUIFeatures {
+ ItemCount featureCount;
+ ATSUFontFeatureType * featureTypes;
+ ATSUFontFeatureSelector * featureSelectors;
+};
+typedef struct TXNATSUIFeatures TXNATSUIFeatures;
+struct TXNATSUIVariations {
+ ItemCount variationCount;
+ ATSUFontVariationAxis * variationAxis;
+ ATSUFontVariationValue * variationValues;
+};
+typedef struct TXNATSUIVariations TXNATSUIVariations;
+union TXNAttributeData {
+ void * dataPtr;
+ UInt32 dataValue;
+ TXNATSUIFeatures * atsuFeatures;
+ TXNATSUIVariations * atsuVariations;
+ CFURLRef urlReference;
+};
+typedef union TXNAttributeData TXNAttributeData;
+struct TXNTypeAttributes {
+ TXTNTag tag;
+ ByteCount size;
+ TXNAttributeData data;
+};
+typedef struct TXNTypeAttributes TXNTypeAttributes;
+struct TXNMacOSPreferredFontDescription {
+ UInt32 fontID;
+ Fixed pointSize;
+ TextEncoding encoding;
+ Style fontStyle;
+};
+typedef struct TXNMacOSPreferredFontDescription TXNMacOSPreferredFontDescription;
+struct TXNMatchTextRecord {
+ const void * iTextPtr;
+ SInt32 iTextToMatchLength;
+ TextEncoding iTextEncoding;
+};
+typedef struct TXNMatchTextRecord TXNMatchTextRecord;
+
+typedef UInt32 TXNBackgroundType;
+enum {
+ kTXNBackgroundTypeRGB = 1
+};
+
+
+
+
+
+union TXNBackgroundData {
+ RGBColor color;
+};
+typedef union TXNBackgroundData TXNBackgroundData;
+struct TXNBackground {
+ TXNBackgroundType bgType;
+ TXNBackgroundData bg;
+};
+typedef struct TXNBackground TXNBackground;
+struct TXNLongRect {
+ SInt32 top;
+ SInt32 left;
+ SInt32 bottom;
+ SInt32 right;
+};
+typedef struct TXNLongRect TXNLongRect;
+
+
+
+
+enum {
+ kTXNTextInputCountBit = 0,
+ kTXNRunCountBit = 1
+};
+
+typedef OptionBits TXNCountOptions;
+enum {
+ kTXNTextInputCountMask = 1L << kTXNTextInputCountBit,
+ kTXNRunCountMask = 1L << kTXNRunCountBit,
+ kTXNAllCountMask = kTXNTextInputCountMask | kTXNRunCountMask
+};
+
+
+typedef UInt32 TXNScrollUnit;
+enum {
+ kTXNScrollUnitsInPixels = 0,
+ kTXNScrollUnitsInLines = 1,
+ kTXNScrollUnitsInViewRects = 2
+};
+
+typedef UInt32 TXNScrollBarOrientation;
+enum {
+ kTXNHorizontal = 0,
+ kTXNVertical = 1
+};
+
+typedef OSStatus ( * TXNFindProcPtr)(const TXNMatchTextRecord *matchData, TXNDataType iDataType, TXNMatchOptions iMatchOptions, const void *iSearchTextPtr, TextEncoding encoding, TXNOffset absStartOffset, ByteCount searchTextLength, TXNOffset *oStartMatch, TXNOffset *oEndMatch, Boolean *ofound, UInt32 refCon);
+typedef CFStringRef ( * TXNActionKeyMapperProcPtr)(TXNActionKey actionKey, UInt32 commandID);
+
+typedef void ( * TXNScrollInfoProcPtr)(SInt32 iValue, SInt32 iMaximumValue, TXNScrollBarOrientation iScrollBarOrientation, SInt32 iRefCon);
+typedef TXNFindProcPtr TXNFindUPP;
+typedef TXNActionKeyMapperProcPtr TXNActionKeyMapperUPP;
+typedef TXNScrollInfoProcPtr TXNScrollInfoUPP;
+extern TXNFindUPP
+NewTXNFindUPP(TXNFindProcPtr userRoutine) ;
+extern TXNActionKeyMapperUPP
+NewTXNActionKeyMapperUPP(TXNActionKeyMapperProcPtr userRoutine) ;
+extern TXNScrollInfoUPP
+NewTXNScrollInfoUPP(TXNScrollInfoProcPtr userRoutine) ;
+extern void
+DisposeTXNFindUPP(TXNFindUPP userUPP) ;
+extern void
+DisposeTXNActionKeyMapperUPP(TXNActionKeyMapperUPP userUPP) ;
+extern void
+DisposeTXNScrollInfoUPP(TXNScrollInfoUPP userUPP) ;
+extern OSStatus
+InvokeTXNFindUPP(
+ const TXNMatchTextRecord * matchData,
+ TXNDataType iDataType,
+ TXNMatchOptions iMatchOptions,
+ const void * iSearchTextPtr,
+ TextEncoding encoding,
+ TXNOffset absStartOffset,
+ ByteCount searchTextLength,
+ TXNOffset * oStartMatch,
+ TXNOffset * oEndMatch,
+ Boolean * ofound,
+ UInt32 refCon,
+ TXNFindUPP userUPP) ;
+extern CFStringRef
+InvokeTXNActionKeyMapperUPP(
+ TXNActionKey actionKey,
+ UInt32 commandID,
+ TXNActionKeyMapperUPP userUPP) ;
+extern void
+InvokeTXNScrollInfoUPP(
+ SInt32 iValue,
+ SInt32 iMaximumValue,
+ TXNScrollBarOrientation iScrollBarOrientation,
+ SInt32 iRefCon,
+ TXNScrollInfoUPP userUPP) ;
+enum {
+ kTXNNoAppleEventHandlersBit = 0,
+ kTXNRestartAppleEventHandlersBit = 1
+};
+
+enum {
+ kTXNNoAppleEventHandlersMask = 1 << kTXNNoAppleEventHandlersBit,
+ kTXNRestartAppleEventHandlersMask = 1 << kTXNRestartAppleEventHandlersBit
+};
+struct TXNCarbonEventInfo {
+ Boolean useCarbonEvents;
+ UInt8 filler;
+ UInt16 flags;
+ CFDictionaryRef fDictionary;
+};
+typedef struct TXNCarbonEventInfo TXNCarbonEventInfo;
+extern OSStatus
+TXNNewObject(
+ const FSSpec * iFileSpec,
+ WindowRef iWindow,
+ const Rect * iFrame,
+ TXNFrameOptions iFrameOptions,
+ TXNFrameType iFrameType,
+ TXNFileType iFileType,
+ TXNPermanentTextEncodingType iPermanentEncoding,
+ TXNObject * oTXNObject,
+ TXNFrameID * oTXNFrameID,
+ TXNObjectRefcon iRefCon) ;
+extern void
+TXNDeleteObject(TXNObject iTXNObject) ;
+extern void
+TXNResizeFrame(
+ TXNObject iTXNObject,
+ UInt32 iWidth,
+ UInt32 iHeight,
+ TXNFrameID iTXNFrameID) ;
+extern void
+TXNSetFrameBounds(
+ TXNObject iTXNObject,
+ SInt32 iTop,
+ SInt32 iLeft,
+ SInt32 iBottom,
+ SInt32 iRight,
+ TXNFrameID iTXNFrameID) ;
+extern OSStatus
+TXNInitTextension(
+ const TXNMacOSPreferredFontDescription iDefaultFonts[],
+ ItemCount iCountDefaultFonts,
+ TXNInitOptions iUsageFlags) ;
+extern void
+TXNTerminateTextension(void) ;
+extern void
+TXNKeyDown(
+ TXNObject iTXNObject,
+ const EventRecord * iEvent) ;
+extern void
+TXNAdjustCursor(
+ TXNObject iTXNObject,
+ RgnHandle ioCursorRgn) ;
+extern void
+TXNClick(
+ TXNObject iTXNObject,
+ const EventRecord * iEvent) ;
+extern void
+TXNSelectAll(TXNObject iTXNObject) ;
+extern void
+TXNFocus(
+ TXNObject iTXNObject,
+ Boolean iBecomingFocused) ;
+extern void
+TXNUpdate(TXNObject iTXNObject) ;
+extern void
+TXNDraw(
+ TXNObject iTXNObject,
+ GWorldPtr iDrawPort) ;
+extern void
+TXNForceUpdate(TXNObject iTXNObject) ;
+extern UInt32
+TXNGetSleepTicks(TXNObject iTXNObject) ;
+extern void
+TXNIdle(TXNObject iTXNObject) ;
+extern void
+TXNGrowWindow(
+ TXNObject iTXNObject,
+ const EventRecord * iEvent) ;
+extern void
+TXNZoomWindow(
+ TXNObject iTXNObject,
+ SInt16 iPart) ;
+extern Boolean
+TXNCanUndo(
+ TXNObject iTXNObject,
+ TXNActionKey * oTXNActionKey) ;
+extern void
+TXNUndo(TXNObject iTXNObject) ;
+extern Boolean
+TXNCanRedo(
+ TXNObject iTXNObject,
+ TXNActionKey * oTXNActionKey) ;
+extern void
+TXNRedo(TXNObject iTXNObject) ;
+extern OSStatus
+TXNCut(TXNObject iTXNObject) ;
+extern OSStatus
+TXNCopy(TXNObject iTXNObject) ;
+extern OSStatus
+TXNPaste(TXNObject iTXNObject) ;
+extern OSStatus
+TXNClear(TXNObject iTXNObject) ;
+extern void
+TXNGetSelection(
+ TXNObject iTXNObject,
+ TXNOffset * oStartOffset,
+ TXNOffset * oEndOffset) ;
+extern void
+TXNShowSelection(
+ TXNObject iTXNObject,
+ Boolean iShowEnd) ;
+extern Boolean
+TXNIsSelectionEmpty(TXNObject iTXNObject) ;
+extern OSStatus
+TXNSetSelection(
+ TXNObject iTXNObject,
+ TXNOffset iStartOffset,
+ TXNOffset iEndOffset) ;
+extern OSStatus
+TXNGetContinuousTypeAttributes(
+ TXNObject iTxnObject,
+ TXNContinuousFlags * oContinuousFlags,
+ ItemCount iCount,
+ TXNTypeAttributes ioTypeAttributes[]) ;
+extern OSStatus
+TXNSetTypeAttributes(
+ TXNObject iTXNObject,
+ ItemCount iAttrCount,
+ const TXNTypeAttributes iAttributes[],
+ TXNOffset iStartOffset,
+ TXNOffset iEndOffset) ;
+extern OSStatus
+TXNSetTXNObjectControls(
+ TXNObject iTXNObject,
+ Boolean iClearAll,
+ ItemCount iControlCount,
+ const TXNControlTag iControlTags[],
+ const TXNControlData iControlData[]) ;
+extern OSStatus
+TXNGetTXNObjectControls(
+ TXNObject iTXNObject,
+ ItemCount iControlCount,
+ const TXNControlTag iControlTags[],
+ TXNControlData oControlData[]) ;
+extern OSStatus
+TXNCountRunsInRange(
+ TXNObject iTXNObject,
+ TXNOffset iStartOffset,
+ TXNOffset iEndOffset,
+ ItemCount * oRunCount) ;
+extern OSStatus
+TXNGetIndexedRunInfoFromRange(
+ TXNObject iTXNObject,
+ ItemCount iIndex,
+ TXNOffset iStartOffset,
+ TXNOffset iEndOffset,
+ TXNOffset * oRunStartOffset,
+ TXNOffset * oRunEndOffset,
+ TXNDataType * oRunDataType,
+ ItemCount iTypeAttributeCount,
+ TXNTypeAttributes * ioTypeAttributes) ;
+extern ByteCount
+TXNDataSize(TXNObject iTXNObject) ;
+extern OSStatus
+TXNGetData(
+ TXNObject iTXNObject,
+ TXNOffset iStartOffset,
+ TXNOffset iEndOffset,
+ Handle * oDataHandle) ;
+extern OSStatus
+TXNGetDataEncoded(
+ TXNObject iTXNObject,
+ TXNOffset iStartOffset,
+ TXNOffset iEndOffset,
+ Handle * oDataHandle,
+ TXNDataType iEncoding) ;
+extern OSStatus
+TXNSetDataFromFile(
+ TXNObject iTXNObject,
+ SInt16 iFileRefNum,
+ OSType iFileType,
+ ByteCount iFileLength,
+ TXNOffset iStartOffset,
+ TXNOffset iEndOffset) ;
+extern OSStatus
+TXNSetData(
+ TXNObject iTXNObject,
+ TXNDataType iDataType,
+ const void * iDataPtr,
+ ByteCount iDataSize,
+ TXNOffset iStartOffset,
+ TXNOffset iEndOffset) ;
+extern ItemCount
+TXNGetChangeCount(TXNObject iTXNObject) ;
+extern OSStatus
+TXNSave(
+ TXNObject iTXNObject,
+ TXNFileType iType,
+ OSType iResType,
+ TXNPermanentTextEncodingType iPermanentEncoding,
+ const FSSpec * iFileSpecification,
+ SInt16 iDataReference,
+ SInt16 iResourceReference) ;
+extern OSStatus
+TXNRevert(TXNObject iTXNObject) ;
+extern OSStatus
+TXNPageSetup(TXNObject iTXNObject) ;
+extern OSStatus
+TXNPrint(TXNObject iTXNObject) ;
+extern Boolean
+TXNIsScrapPastable(void) ;
+extern OSStatus
+TXNConvertToPublicScrap(void) ;
+extern OSStatus
+TXNConvertFromPublicScrap(void) ;
+extern void
+TXNGetViewRect(
+ TXNObject iTXNObject,
+ Rect * oViewRect) ;
+extern void
+TXNSetViewRect(
+ TXNObject iTXNObject,
+ const Rect * iViewRect) ;
+extern OSStatus
+TXNFind(
+ TXNObject iTXNObject,
+ const TXNMatchTextRecord * iMatchTextDataPtr,
+ TXNDataType iDataType,
+ TXNMatchOptions iMatchOptions,
+ TXNOffset iStartSearchOffset,
+ TXNOffset iEndSearchOffset,
+ TXNFindUPP iFindProc,
+ SInt32 iRefCon,
+ TXNOffset * oStartMatchOffset,
+ TXNOffset * oEndMatchOffset) ;
+extern OSStatus
+TXNSetFontDefaults(
+ TXNObject iTXNObject,
+ ItemCount iCount,
+ const TXNMacOSPreferredFontDescription iFontDefaults[]) ;
+extern OSStatus
+TXNGetFontDefaults(
+ TXNObject iTXNObject,
+ ItemCount * ioCount,
+ TXNMacOSPreferredFontDescription ioFontDefaults[]) ;
+extern OSStatus
+TXNAttachObjectToWindow(
+ TXNObject iTXNObject,
+ GWorldPtr iWindow,
+ Boolean iIsActualWindow) ;
+extern Boolean
+TXNIsObjectAttachedToWindow(TXNObject iTXNObject) ;
+extern OSErr
+TXNDragTracker(
+ TXNObject iTXNObject,
+ TXNFrameID iTXNFrameID,
+ DragTrackingMessage iMessage,
+ WindowRef iWindow,
+ DragReference iDragReference,
+ Boolean iDifferentObjectSameWindow) ;
+extern OSErr
+TXNDragReceiver(
+ TXNObject iTXNObject,
+ TXNFrameID iTXNFrameID,
+ WindowRef iWindow,
+ DragReference iDragReference,
+ Boolean iDifferentObjectSameWindow) ;
+extern OSStatus
+TXNActivate(
+ TXNObject iTXNObject,
+ TXNFrameID iTXNFrameID,
+ TXNScrollBarState iActiveState) ;
+extern OSStatus
+TXNSetBackground(
+ TXNObject iTXNObject,
+ const TXNBackground * iBackgroundInfo) ;
+extern OSStatus
+TXNEchoMode(
+ TXNObject iTXNObject,
+ UniChar iEchoCharacter,
+ TextEncoding iEncoding,
+ Boolean iOn) ;
+extern OSStatus
+TXNNewFontMenuObject(
+ MenuRef iFontMenuHandle,
+ SInt16 iMenuID,
+ SInt16 iStartHierMenuID,
+ TXNFontMenuObject * oTXNFontMenuObject) ;
+extern OSStatus
+TXNGetFontMenuHandle(
+ TXNFontMenuObject iTXNFontMenuObject,
+ MenuRef * oFontMenuHandle) ;
+extern OSStatus
+TXNDisposeFontMenuObject(TXNFontMenuObject iTXNFontMenuObject) ;
+extern OSStatus
+TXNDoFontMenuSelection(
+ TXNObject iTXNObject,
+ TXNFontMenuObject iTXNFontMenuObject,
+ SInt16 iMenuID,
+ SInt16 iMenuItem) ;
+extern OSStatus
+TXNPrepareFontMenu(
+ TXNObject iTXNObject,
+ TXNFontMenuObject iTXNFontMenuObject) ;
+extern TXNVersionValue
+TXNVersionInformation(TXNFeatureBits * oFeatureFlags) ;
+extern OSStatus
+TXNPointToOffset(
+ TXNObject iTXNObject,
+ Point iPoint,
+ TXNOffset * oOffset) ;
+extern OSStatus
+TXNOffsetToPoint(
+ TXNObject iTXNObject,
+ TXNOffset iOffset,
+ Point * oPoint) ;
+extern OSStatus
+TXNDrawUnicodeTextBox(
+ const UniChar iText[],
+ UniCharCount iLen,
+ Rect * ioBox,
+ ATSUStyle iStyle,
+ const TXNTextBoxOptionsData * iOptions) ;
+extern OSStatus
+TXNDrawCFStringTextBox(
+ CFStringRef iText,
+ Rect * ioBox,
+ ATSUStyle iStyle,
+ const TXNTextBoxOptionsData * iOptions) ;
+extern OSStatus
+TXNGetLineCount(
+ TXNObject iTXNObject,
+ ItemCount * oLineTotal) ;
+extern OSStatus
+TXNGetLineMetrics(
+ TXNObject iTXNObject,
+ UInt32 iLineNumber,
+ Fixed * oLineWidth,
+ Fixed * oLineHeight) ;
+extern OSStatus
+TXNGetActionChangeCount(
+ TXNObject iTXNObject,
+ TXNCountOptions iOptions,
+ ItemCount * oCount) ;
+extern OSStatus
+TXNClearActionChangeCount(
+ TXNObject iTXNObject,
+ TXNCountOptions iOptions) ;
+extern OSStatus
+TXNIsObjectAttachedToSpecificWindow(
+ TXNObject iTXNObject,
+ WindowRef iWindow,
+ Boolean * oAttached) ;
+extern void
+TXNSetRectBounds(
+ TXNObject iTXNObject,
+ const Rect * iViewRect,
+ const TXNLongRect * iDestinationRect,
+ Boolean iUpdate) ;
+extern OSStatus
+TXNGetRectBounds(
+ TXNObject iTXNObject,
+ Rect * oViewRect,
+ TXNLongRect * oDestinationRect,
+ TXNLongRect * oTextRect) ;
+extern void
+TXNRecalcTextLayout(TXNObject iTXNObject) ;
+extern OSStatus
+TXNScroll(
+ TXNObject iTXNObject,
+ TXNScrollUnit iVerticalScrollUnit,
+ TXNScrollUnit iHorizontalScrollUnit,
+ SInt32 * ioVerticalDelta,
+ SInt32 * ioHorizontalDelta) ;
+extern void
+TXNRegisterScrollInfoProc(
+ TXNObject iTXNObject,
+ TXNScrollInfoUPP iTXNScrollInfoUPP,
+ SInt32 iRefCon) ;
+extern OSStatus
+TXNClearUndo(TXNObject iTXNObject) ;
+
+
+
+
+
+}
+
+
+
+extern "C" {
+
+
+
+
+
+
+enum {
+ kMacHelpVersion = 0x0003
+};
+
+typedef SInt16 HMContentRequest;
+enum {
+ kHMSupplyContent = 0,
+ kHMDisposeContent = 1
+};
+
+typedef UInt32 HMContentType;
+enum {
+ kHMNoContent = 'none',
+ kHMCFStringContent = 'cfst',
+ kHMCFStringLocalizedContent = 'cfsl',
+ kHMPascalStrContent = 'pstr',
+ kHMStringResContent = 'str#',
+ kHMTEHandleContent = 'txth',
+ kHMTextResContent = 'text',
+ kHMStrResContent = 'str '
+};
+typedef SInt16 HMTagDisplaySide;
+enum {
+
+
+
+
+ kHMDefaultSide = 0,
+
+
+
+
+ kHMOutsideTopScriptAligned = 1,
+
+
+
+
+ kHMOutsideLeftCenterAligned = 2,
+ kHMOutsideBottomScriptAligned = 3,
+
+
+
+
+ kHMOutsideRightCenterAligned = 4,
+
+
+
+
+ kHMOutsideTopLeftAligned = 5,
+
+
+
+
+ kHMOutsideTopRightAligned = 6,
+
+
+
+
+ kHMOutsideLeftTopAligned = 7,
+
+
+
+
+ kHMOutsideLeftBottomAligned = 8,
+
+
+
+
+ kHMOutsideBottomLeftAligned = 9,
+
+
+
+
+ kHMOutsideBottomRightAligned = 10,
+ kHMOutsideRightTopAligned = 11,
+ kHMOutsideRightBottomAligned = 12,
+
+
+
+
+ kHMOutsideTopCenterAligned = 13,
+
+
+
+
+ kHMOutsideBottomCenterAligned = 14,
+
+
+
+
+ kHMInsideRightCenterAligned = 15,
+
+
+
+
+ kHMInsideLeftCenterAligned = 16,
+
+
+
+
+ kHMInsideBottomCenterAligned = 17,
+
+
+
+
+ kHMInsideTopCenterAligned = 18,
+
+
+
+
+ kHMInsideTopLeftCorner = 19,
+
+
+
+
+ kHMInsideTopRightCorner = 20,
+
+
+
+
+ kHMInsideBottomLeftCorner = 21,
+
+
+
+
+ kHMInsideBottomRightCorner = 22,
+
+
+
+
+ kHMAbsoluteCenterAligned = 23
+};
+
+
+enum {
+ kHMTopSide = kHMOutsideTopScriptAligned,
+ kHMLeftSide = kHMOutsideLeftCenterAligned,
+ kHMBottomSide = kHMOutsideBottomScriptAligned,
+ kHMRightSide = kHMOutsideRightCenterAligned,
+ kHMTopLeftCorner = kHMOutsideTopLeftAligned,
+ kHMTopRightCorner = kHMOutsideTopRightAligned,
+ kHMLeftTopCorner = kHMOutsideLeftTopAligned,
+ kHMLeftBottomCorner = kHMOutsideLeftBottomAligned,
+ kHMBottomLeftCorner = kHMOutsideBottomLeftAligned,
+ kHMBottomRightCorner = kHMOutsideBottomRightAligned,
+ kHMRightTopCorner = kHMOutsideRightTopAligned,
+ kHMRightBottomCorner = kHMOutsideRightBottomAligned
+};
+
+typedef SInt16 HMContentProvidedType;
+enum {
+ kHMContentProvided = 0,
+ kHMContentNotProvided = 1,
+ kHMContentNotProvidedDontPropagate = 2
+};
+
+enum {
+ kHMMinimumContentIndex = 0,
+ kHMMaximumContentIndex = 1
+};
+
+enum {
+ errHMIllegalContentForMinimumState = -10980,
+ errHMIllegalContentForMaximumState = -10981
+};
+
+
+enum {
+ kHMIllegalContentForMinimumState = errHMIllegalContentForMinimumState
+};
+
+enum {
+ kHelpTagEventHandlerTag = 'hevt'
+};
+
+struct HMHelpContent {
+ HMContentType contentType;
+ union {
+ CFStringRef tagCFString;
+ Str255 tagString;
+ HMStringResType tagStringRes;
+ TEHandle tagTEHandle;
+ SInt16 tagTextRes;
+ SInt16 tagStrRes;
+ } u;
+};
+typedef struct HMHelpContent HMHelpContent;
+struct HMHelpContentRec {
+ SInt32 version;
+ Rect absHotRect;
+ HMTagDisplaySide tagSide;
+ HMHelpContent content[2];
+};
+typedef struct HMHelpContentRec HMHelpContentRec;
+typedef HMHelpContentRec * HMHelpContentPtr;
+
+
+
+typedef OSStatus ( * HMControlContentProcPtr)(ControlRef inControl, Point inGlobalMouse, HMContentRequest inRequest, HMContentProvidedType *outContentProvided, HMHelpContentPtr ioHelpContent);
+typedef OSStatus ( * HMWindowContentProcPtr)(WindowRef inWindow, Point inGlobalMouse, HMContentRequest inRequest, HMContentProvidedType *outContentProvided, HMHelpContentPtr ioHelpContent);
+typedef OSStatus ( * HMMenuTitleContentProcPtr)(MenuRef inMenu, HMContentRequest inRequest, HMContentProvidedType *outContentProvided, HMHelpContentPtr ioHelpContent);
+typedef OSStatus ( * HMMenuItemContentProcPtr)(const MenuTrackingData *inTrackingData, HMContentRequest inRequest, HMContentProvidedType *outContentProvided, HMHelpContentPtr ioHelpContent);
+typedef HMControlContentProcPtr HMControlContentUPP;
+typedef HMWindowContentProcPtr HMWindowContentUPP;
+typedef HMMenuTitleContentProcPtr HMMenuTitleContentUPP;
+typedef HMMenuItemContentProcPtr HMMenuItemContentUPP;
+extern HMControlContentUPP
+NewHMControlContentUPP(HMControlContentProcPtr userRoutine) ;
+extern HMWindowContentUPP
+NewHMWindowContentUPP(HMWindowContentProcPtr userRoutine) ;
+extern HMMenuTitleContentUPP
+NewHMMenuTitleContentUPP(HMMenuTitleContentProcPtr userRoutine) ;
+extern HMMenuItemContentUPP
+NewHMMenuItemContentUPP(HMMenuItemContentProcPtr userRoutine) ;
+extern void
+DisposeHMControlContentUPP(HMControlContentUPP userUPP) ;
+extern void
+DisposeHMWindowContentUPP(HMWindowContentUPP userUPP) ;
+extern void
+DisposeHMMenuTitleContentUPP(HMMenuTitleContentUPP userUPP) ;
+extern void
+DisposeHMMenuItemContentUPP(HMMenuItemContentUPP userUPP) ;
+extern OSStatus
+InvokeHMControlContentUPP(
+ ControlRef inControl,
+ Point inGlobalMouse,
+ HMContentRequest inRequest,
+ HMContentProvidedType * outContentProvided,
+ HMHelpContentPtr ioHelpContent,
+ HMControlContentUPP userUPP) ;
+extern OSStatus
+InvokeHMWindowContentUPP(
+ WindowRef inWindow,
+ Point inGlobalMouse,
+ HMContentRequest inRequest,
+ HMContentProvidedType * outContentProvided,
+ HMHelpContentPtr ioHelpContent,
+ HMWindowContentUPP userUPP) ;
+extern OSStatus
+InvokeHMMenuTitleContentUPP(
+ MenuRef inMenu,
+ HMContentRequest inRequest,
+ HMContentProvidedType * outContentProvided,
+ HMHelpContentPtr ioHelpContent,
+ HMMenuTitleContentUPP userUPP) ;
+extern OSStatus
+InvokeHMMenuItemContentUPP(
+ const MenuTrackingData * inTrackingData,
+ HMContentRequest inRequest,
+ HMContentProvidedType * outContentProvided,
+ HMHelpContentPtr ioHelpContent,
+ HMMenuItemContentUPP userUPP) ;
+extern OSStatus
+HMGetHelpMenu(
+ MenuRef * outHelpMenu,
+ MenuItemIndex * outFirstCustomItemIndex) ;
+extern OSStatus
+HMSetControlHelpContent(
+ ControlRef inControl,
+ const HMHelpContentRec * inContent) ;
+extern OSStatus
+HMGetControlHelpContent(
+ ControlRef inControl,
+ HMHelpContentRec * outContent) ;
+extern OSStatus
+HMSetWindowHelpContent(
+ WindowRef inWindow,
+ const HMHelpContentRec * inContent) ;
+extern OSStatus
+HMGetWindowHelpContent(
+ WindowRef inWindow,
+ HMHelpContentRec * outContent) ;
+extern OSStatus
+HMSetMenuItemHelpContent(
+ MenuRef inMenu,
+ MenuItemIndex inItem,
+ const HMHelpContentRec * inContent) ;
+extern OSStatus
+HMGetMenuItemHelpContent(
+ MenuRef inMenu,
+ MenuItemIndex inItem,
+ HMHelpContentRec * outContent) ;
+extern OSStatus
+HMInstallControlContentCallback(
+ ControlRef inControl,
+ HMControlContentUPP inContentUPP) ;
+extern OSStatus
+HMInstallWindowContentCallback(
+ WindowRef inWindow,
+ HMWindowContentUPP inContentUPP) ;
+extern OSStatus
+HMInstallMenuTitleContentCallback(
+ MenuRef inMenu,
+ HMMenuTitleContentUPP inContentUPP) ;
+extern OSStatus
+HMInstallMenuItemContentCallback(
+ MenuRef inMenu,
+ HMMenuItemContentUPP inContentUPP) ;
+extern OSStatus
+HMGetControlContentCallback(
+ ControlRef inControl,
+ HMControlContentUPP * outContentUPP) ;
+extern OSStatus
+HMGetWindowContentCallback(
+ WindowRef inWindow,
+ HMWindowContentUPP * outContentUPP) ;
+extern OSStatus
+HMGetMenuTitleContentCallback(
+ MenuRef inMenu,
+ HMMenuTitleContentUPP * outContentUPP) ;
+extern OSStatus
+HMGetMenuItemContentCallback(
+ MenuRef inMenu,
+ HMMenuItemContentUPP * outContentUPP) ;
+extern Boolean
+HMAreHelpTagsDisplayed(void) ;
+extern OSStatus
+HMSetHelpTagsDisplayed(Boolean inDisplayTags) ;
+extern OSStatus
+HMSetTagDelay(Duration inDelay) ;
+extern OSStatus
+HMGetTagDelay(Duration * outDelay) ;
+extern OSStatus
+HMSetMenuHelpFromBalloonRsrc(
+ MenuRef inMenu,
+ SInt16 inHmnuRsrcID) ;
+extern OSStatus
+HMSetDialogHelpFromBalloonRsrc(
+ DialogRef inDialog,
+ SInt16 inHdlgRsrcID,
+ SInt16 inItemStart) ;
+extern OSStatus
+HMDisplayTag(const HMHelpContentRec * inContent) ;
+extern OSStatus
+HMHideTag(void) ;
+
+
+
+
+
+}
+
+
+
+extern "C" {
+
+
+enum {
+ kControlTabListResType = 'tab#',
+ kControlListDescResType = 'ldes'
+};
+
+
+
+
+enum {
+ kControlCheckBoxUncheckedValue = 0,
+ kControlCheckBoxCheckedValue = 1,
+ kControlCheckBoxMixedValue = 2
+};
+
+
+
+
+enum {
+ kControlRadioButtonUncheckedValue = 0,
+ kControlRadioButtonCheckedValue = 1,
+ kControlRadioButtonMixedValue = 2
+};
+
+
+
+
+
+enum {
+ popupFixedWidth = 1 << 0,
+ popupVariableWidth = 1 << 1,
+ popupUseAddResMenu = 1 << 2,
+ popupUseWFont = 1 << 3
+};
+
+
+enum {
+ popupTitleBold = 1 << 8,
+ popupTitleItalic = 1 << 9,
+ popupTitleUnderline = 1 << 10,
+ popupTitleOutline = 1 << 11,
+ popupTitleShadow = 1 << 12,
+ popupTitleCondense = 1 << 13,
+ popupTitleExtend = 1 << 14,
+ popupTitleNoStyle = 1 << 15
+};
+
+
+enum {
+ popupTitleLeftJust = 0x00000000,
+ popupTitleCenterJust = 0x00000001,
+ popupTitleRightJust = 0x000000FF
+};
+enum {
+ pushButProc = 0,
+ checkBoxProc = 1,
+ radioButProc = 2,
+ scrollBarProc = 16,
+ popupMenuProc = 1008
+};
+
+
+
+
+enum {
+ kControlLabelPart = 1,
+ kControlMenuPart = 2,
+ kControlTrianglePart = 4,
+ kControlEditTextPart = 5,
+ kControlPicturePart = 6,
+ kControlIconPart = 7,
+ kControlClockPart = 8,
+ kControlListBoxPart = 24,
+ kControlListBoxDoubleClickPart = 25,
+ kControlImageWellPart = 26,
+ kControlRadioGroupPart = 27,
+ kControlButtonPart = 10,
+ kControlCheckBoxPart = 11,
+ kControlRadioButtonPart = 11,
+ kControlUpButtonPart = 20,
+ kControlDownButtonPart = 21,
+ kControlPageUpPart = 22,
+ kControlPageDownPart = 23,
+ kControlClockHourDayPart = 9,
+ kControlClockMinuteMonthPart = 10,
+ kControlClockSecondYearPart = 11,
+ kControlClockAMPMPart = 12,
+ kControlDataBrowserPart = 24,
+ kControlDataBrowserDraggedPart = 25
+};
+enum {
+ kControlBevelButtonSmallBevelProc = 32,
+ kControlBevelButtonNormalBevelProc = 33,
+ kControlBevelButtonLargeBevelProc = 34
+};
+
+
+enum {
+ kControlBevelButtonSmallBevelVariant = 0,
+ kControlBevelButtonNormalBevelVariant = (1 << 0),
+ kControlBevelButtonLargeBevelVariant = (1 << 1),
+ kControlBevelButtonMenuOnRightVariant = (1 << 2)
+};
+
+
+typedef UInt16 ControlBevelThickness;
+enum {
+ kControlBevelButtonSmallBevel = 0,
+ kControlBevelButtonNormalBevel = 1,
+ kControlBevelButtonLargeBevel = 2
+};
+
+
+
+enum {
+ kControlBehaviorPushbutton = 0,
+ kControlBehaviorToggles = 0x0100,
+ kControlBehaviorSticky = 0x0200,
+ kControlBehaviorSingleValueMenu = 0,
+ kControlBehaviorMultiValueMenu = 0x4000,
+ kControlBehaviorOffsetContents = 0x8000
+};
+
+
+enum {
+ kControlBehaviorCommandMenu = 0x2000
+};
+
+typedef UInt16 ControlBevelButtonBehavior;
+typedef UInt16 ControlBevelButtonMenuBehavior;
+
+typedef UInt16 ControlBevelButtonMenuPlacement;
+enum {
+ kControlBevelButtonMenuOnBottom = 0,
+ kControlBevelButtonMenuOnRight = (1 << 2)
+};
+
+
+enum {
+ kControlKindBevelButton = 'bevl'
+};
+extern OSStatus
+CreateBevelButtonControl(
+ WindowRef window,
+ const Rect * boundsRect,
+ CFStringRef title,
+ ControlBevelThickness thickness,
+ ControlBevelButtonBehavior behavior,
+ ControlButtonContentInfoPtr info,
+ SInt16 menuID,
+ ControlBevelButtonMenuBehavior menuBehavior,
+ ControlBevelButtonMenuPlacement menuPlacement,
+ ControlRef * outControl) ;
+
+
+
+
+
+typedef SInt16 ControlButtonGraphicAlignment;
+enum {
+ kControlBevelButtonAlignSysDirection = -1,
+ kControlBevelButtonAlignCenter = 0,
+ kControlBevelButtonAlignLeft = 1,
+ kControlBevelButtonAlignRight = 2,
+ kControlBevelButtonAlignTop = 3,
+ kControlBevelButtonAlignBottom = 4,
+ kControlBevelButtonAlignTopLeft = 5,
+ kControlBevelButtonAlignBottomLeft = 6,
+ kControlBevelButtonAlignTopRight = 7,
+ kControlBevelButtonAlignBottomRight = 8
+};
+
+
+typedef SInt16 ControlButtonTextAlignment;
+enum {
+ kControlBevelButtonAlignTextSysDirection = teFlushDefault,
+ kControlBevelButtonAlignTextCenter = teCenter,
+ kControlBevelButtonAlignTextFlushRight = teFlushRight,
+ kControlBevelButtonAlignTextFlushLeft = teFlushLeft
+};
+
+
+typedef SInt16 ControlButtonTextPlacement;
+enum {
+ kControlBevelButtonPlaceSysDirection = -1,
+ kControlBevelButtonPlaceNormally = 0,
+ kControlBevelButtonPlaceToRightOfGraphic = 1,
+ kControlBevelButtonPlaceToLeftOfGraphic = 2,
+ kControlBevelButtonPlaceBelowGraphic = 3,
+ kControlBevelButtonPlaceAboveGraphic = 4
+};
+
+
+
+enum {
+ kControlBevelButtonContentTag = 'cont',
+ kControlBevelButtonTransformTag = 'tran',
+ kControlBevelButtonTextAlignTag = 'tali',
+ kControlBevelButtonTextOffsetTag = 'toff',
+ kControlBevelButtonGraphicAlignTag = 'gali',
+ kControlBevelButtonGraphicOffsetTag = 'goff',
+ kControlBevelButtonTextPlaceTag = 'tplc',
+ kControlBevelButtonMenuValueTag = 'mval',
+ kControlBevelButtonMenuHandleTag = 'mhnd',
+ kControlBevelButtonMenuRefTag = 'mhnd',
+ kControlBevelButtonCenterPopupGlyphTag = 'pglc'
+};
+
+
+enum {
+ kControlBevelButtonLastMenuTag = 'lmnu',
+ kControlBevelButtonMenuDelayTag = 'mdly'
+};
+
+
+enum {
+
+
+
+
+
+ kControlBevelButtonScaleIconTag = 'scal'
+};
+
+
+enum {
+ kControlBevelButtonOwnedMenuRefTag = 'omrf',
+ kControlBevelButtonKindTag = 'bebk'
+};
+extern OSErr
+GetBevelButtonMenuValue(
+ ControlRef inButton,
+ SInt16 * outValue) ;
+extern OSErr
+SetBevelButtonMenuValue(
+ ControlRef inButton,
+ SInt16 inValue) ;
+extern OSErr
+GetBevelButtonMenuHandle(
+ ControlRef inButton,
+ MenuHandle * outHandle) ;
+extern OSErr
+GetBevelButtonContentInfo(
+ ControlRef inButton,
+ ControlButtonContentInfoPtr outContent) ;
+extern OSErr
+SetBevelButtonContentInfo(
+ ControlRef inButton,
+ ControlButtonContentInfoPtr inContent) ;
+extern OSErr
+SetBevelButtonTransform(
+ ControlRef inButton,
+ IconTransformType transform) ;
+extern OSErr
+SetBevelButtonGraphicAlignment(
+ ControlRef inButton,
+ ControlButtonGraphicAlignment inAlign,
+ SInt16 inHOffset,
+ SInt16 inVOffset) ;
+extern OSErr
+SetBevelButtonTextAlignment(
+ ControlRef inButton,
+ ControlButtonTextAlignment inAlign,
+ SInt16 inHOffset) ;
+extern OSErr
+SetBevelButtonTextPlacement(
+ ControlRef inButton,
+ ControlButtonTextPlacement inWhere) ;
+enum {
+ kControlSliderProc = 48,
+ kControlSliderLiveFeedback = (1 << 0),
+ kControlSliderHasTickMarks = (1 << 1),
+ kControlSliderReverseDirection = (1 << 2),
+ kControlSliderNonDirectional = (1 << 3)
+};
+
+
+typedef UInt16 ControlSliderOrientation;
+enum {
+ kControlSliderPointsDownOrRight = 0,
+ kControlSliderPointsUpOrLeft = 1,
+ kControlSliderDoesNotPoint = 2
+};
+
+
+enum {
+ kControlKindSlider = 'sldr'
+};
+extern OSStatus
+CreateSliderControl(
+ WindowRef window,
+ const Rect * boundsRect,
+ SInt32 value,
+ SInt32 minimum,
+ SInt32 maximum,
+ ControlSliderOrientation orientation,
+ UInt16 numTickMarks,
+ Boolean liveTracking,
+ ControlActionUPP liveTrackingProc,
+ ControlRef * outControl) ;
+enum {
+ kControlTriangleProc = 64,
+ kControlTriangleLeftFacingProc = 65,
+ kControlTriangleAutoToggleProc = 66,
+ kControlTriangleLeftFacingAutoToggleProc = 67
+};
+
+typedef UInt16 ControlDisclosureTriangleOrientation;
+enum {
+ kControlDisclosureTrianglePointDefault = 0,
+ kControlDisclosureTrianglePointRight = 1,
+ kControlDisclosureTrianglePointLeft = 2
+};
+
+
+enum {
+ kControlKindDisclosureTriangle = 'dist'
+};
+extern OSStatus
+CreateDisclosureTriangleControl(
+ WindowRef inWindow,
+ const Rect * inBoundsRect,
+ ControlDisclosureTriangleOrientation inOrientation,
+ CFStringRef inTitle,
+ SInt32 inInitialValue,
+ Boolean inDrawTitle,
+ Boolean inAutoToggles,
+ ControlRef * outControl) ;
+
+
+
+
+enum {
+ kControlTriangleLastValueTag = 'last'
+};
+extern OSErr
+SetDisclosureTriangleLastValue(
+ ControlRef inTabControl,
+ SInt16 inValue) ;
+enum {
+ kControlProgressBarProc = 80,
+ kControlRelevanceBarProc = 81
+};
+
+
+enum {
+ kControlKindProgressBar = 'prgb',
+ kControlKindRelevanceBar = 'relb'
+};
+extern OSStatus
+CreateProgressBarControl(
+ WindowRef window,
+ const Rect * boundsRect,
+ SInt32 value,
+ SInt32 minimum,
+ SInt32 maximum,
+ Boolean indeterminate,
+ ControlRef * outControl) ;
+extern OSStatus
+CreateRelevanceBarControl(
+ WindowRef window,
+ const Rect * boundsRect,
+ SInt32 value,
+ SInt32 minimum,
+ SInt32 maximum,
+ ControlRef * outControl) ;
+
+
+
+enum {
+ kControlProgressBarIndeterminateTag = 'inde',
+ kControlProgressBarAnimatingTag = 'anim'
+};
+
+
+
+
+
+
+
+enum {
+ kControlLittleArrowsProc = 96
+};
+
+
+enum {
+ kControlKindLittleArrows = 'larr'
+};
+extern OSStatus
+CreateLittleArrowsControl(
+ WindowRef window,
+ const Rect * boundsRect,
+ SInt32 value,
+ SInt32 minimum,
+ SInt32 maximum,
+ SInt32 increment,
+ ControlRef * outControl) ;
+enum {
+ kControlChasingArrowsProc = 112
+};
+
+
+enum {
+ kControlKindChasingArrows = 'carr'
+};
+extern OSStatus
+CreateChasingArrowsControl(
+ WindowRef window,
+ const Rect * boundsRect,
+ ControlRef * outControl) ;
+
+
+
+enum {
+ kControlChasingArrowsAnimatingTag = 'anim'
+};
+enum {
+ kControlTabLargeProc = 128,
+ kControlTabSmallProc = 129,
+ kControlTabLargeNorthProc = 128,
+ kControlTabSmallNorthProc = 129,
+ kControlTabLargeSouthProc = 130,
+ kControlTabSmallSouthProc = 131,
+ kControlTabLargeEastProc = 132,
+ kControlTabSmallEastProc = 133,
+ kControlTabLargeWestProc = 134,
+ kControlTabSmallWestProc = 135
+};
+
+
+typedef UInt16 ControlTabDirection;
+enum {
+ kControlTabDirectionNorth = 0,
+ kControlTabDirectionSouth = 1,
+ kControlTabDirectionEast = 2,
+ kControlTabDirectionWest = 3
+};
+
+
+typedef UInt16 ControlTabSize;
+enum {
+ kControlTabSizeLarge = kControlSizeNormal,
+ kControlTabSizeSmall = kControlSizeSmall
+};
+
+
+
+
+
+struct ControlTabEntry {
+ ControlButtonContentInfo * icon;
+ CFStringRef name;
+ Boolean enabled;
+};
+typedef struct ControlTabEntry ControlTabEntry;
+
+enum {
+ kControlKindTabs = 'tabs'
+};
+extern OSStatus
+CreateTabsControl(
+ WindowRef window,
+ const Rect * boundsRect,
+ ControlTabSize size,
+ ControlTabDirection direction,
+ UInt16 numTabs,
+ const ControlTabEntry * tabArray,
+ ControlRef * outControl) ;
+
+
+
+
+enum {
+ kControlTabContentRectTag = 'rect',
+ kControlTabEnabledFlagTag = 'enab',
+ kControlTabFontStyleTag = kControlFontStyleTag
+};
+
+
+enum {
+ kControlTabInfoTag = 'tabi'
+};
+
+
+enum {
+ kControlTabImageContentTag = 'cont'
+};
+
+enum {
+ kControlTabInfoVersionZero = 0,
+ kControlTabInfoVersionOne = 1
+};
+
+struct ControlTabInfoRec {
+ SInt16 version;
+ SInt16 iconSuiteID;
+ Str255 name;
+};
+typedef struct ControlTabInfoRec ControlTabInfoRec;
+struct ControlTabInfoRecV1 {
+ SInt16 version;
+ SInt16 iconSuiteID;
+ CFStringRef name;
+
+};
+typedef struct ControlTabInfoRecV1 ControlTabInfoRecV1;
+extern OSErr
+GetTabContentRect(
+ ControlRef inTabControl,
+ Rect * outContentRect) ;
+extern OSErr
+SetTabEnabled(
+ ControlRef inTabControl,
+ SInt16 inTabToHilite,
+ Boolean inEnabled) ;
+enum {
+ kControlSeparatorLineProc = 144
+};
+
+
+enum {
+ kControlKindSeparator = 'sepa'
+};
+extern OSStatus
+CreateSeparatorControl(
+ WindowRef window,
+ const Rect * boundsRect,
+ ControlRef * outControl) ;
+enum {
+ kControlGroupBoxTextTitleProc = 160,
+ kControlGroupBoxCheckBoxProc = 161,
+ kControlGroupBoxPopupButtonProc = 162,
+ kControlGroupBoxSecondaryTextTitleProc = 164,
+ kControlGroupBoxSecondaryCheckBoxProc = 165,
+ kControlGroupBoxSecondaryPopupButtonProc = 166
+};
+
+
+enum {
+ kControlKindGroupBox = 'grpb',
+ kControlKindCheckGroupBox = 'cgrp',
+ kControlKindPopupGroupBox = 'pgrp'
+};
+extern OSStatus
+CreateGroupBoxControl(
+ WindowRef window,
+ const Rect * boundsRect,
+ CFStringRef title,
+ Boolean primary,
+ ControlRef * outControl) ;
+extern OSStatus
+CreateCheckGroupBoxControl(
+ WindowRef window,
+ const Rect * boundsRect,
+ CFStringRef title,
+ SInt32 initialValue,
+ Boolean primary,
+ Boolean autoToggle,
+ ControlRef * outControl) ;
+extern OSStatus
+CreatePopupGroupBoxControl(
+ WindowRef window,
+ const Rect * boundsRect,
+ CFStringRef title,
+ Boolean primary,
+ SInt16 menuID,
+ Boolean variableWidth,
+ SInt16 titleWidth,
+ SInt16 titleJustification,
+ Style titleStyle,
+ ControlRef * outControl) ;
+
+
+
+
+enum {
+ kControlGroupBoxMenuHandleTag = 'mhan',
+ kControlGroupBoxMenuRefTag = 'mhan',
+ kControlGroupBoxFontStyleTag = kControlFontStyleTag
+};
+
+
+enum {
+ kControlGroupBoxTitleRectTag = 'trec'
+};
+enum {
+ kControlImageWellProc = 176
+};
+
+
+enum {
+ kControlKindImageWell = 'well'
+};
+extern OSStatus
+CreateImageWellControl(
+ WindowRef window,
+ const Rect * boundsRect,
+ const ControlButtonContentInfo * info,
+ ControlRef * outControl) ;
+
+
+
+enum {
+ kControlImageWellContentTag = 'cont',
+ kControlImageWellTransformTag = 'tran',
+ kControlImageWellIsDragDestinationTag = 'drag'
+};
+extern OSErr
+GetImageWellContentInfo(
+ ControlRef inButton,
+ ControlButtonContentInfoPtr outContent) ;
+extern OSErr
+SetImageWellContentInfo(
+ ControlRef inButton,
+ ControlButtonContentInfoPtr inContent) ;
+extern OSErr
+SetImageWellTransform(
+ ControlRef inButton,
+ IconTransformType inTransform) ;
+enum {
+ kControlPopupArrowEastProc = 192,
+ kControlPopupArrowWestProc = 193,
+ kControlPopupArrowNorthProc = 194,
+ kControlPopupArrowSouthProc = 195,
+ kControlPopupArrowSmallEastProc = 196,
+ kControlPopupArrowSmallWestProc = 197,
+ kControlPopupArrowSmallNorthProc = 198,
+ kControlPopupArrowSmallSouthProc = 199
+};
+
+
+enum {
+ kControlPopupArrowOrientationEast = 0,
+ kControlPopupArrowOrientationWest = 1,
+ kControlPopupArrowOrientationNorth = 2,
+ kControlPopupArrowOrientationSouth = 3
+};
+
+
+typedef UInt16 ControlPopupArrowOrientation;
+
+enum {
+ kControlPopupArrowSizeNormal = 0,
+ kControlPopupArrowSizeSmall = 1
+};
+
+typedef UInt16 ControlPopupArrowSize;
+
+enum {
+ kControlKindPopupArrow = 'parr'
+};
+extern OSStatus
+CreatePopupArrowControl(
+ WindowRef window,
+ const Rect * boundsRect,
+ ControlPopupArrowOrientation orientation,
+ ControlPopupArrowSize size,
+ ControlRef * outControl) ;
+
+
+
+
+
+
+enum {
+ kControlPlacardProc = 224
+};
+
+
+enum {
+ kControlKindPlacard = 'plac'
+};
+extern OSStatus
+CreatePlacardControl(
+ WindowRef window,
+ const Rect * boundsRect,
+ ControlRef * outControl) ;
+enum {
+ kControlClockTimeProc = 240,
+ kControlClockTimeSecondsProc = 241,
+ kControlClockDateProc = 242,
+ kControlClockMonthYearProc = 243
+};
+
+
+typedef UInt16 ControlClockType;
+enum {
+ kControlClockTypeHourMinute = 0,
+ kControlClockTypeHourMinuteSecond = 1,
+ kControlClockTypeMonthDayYear = 2,
+ kControlClockTypeMonthYear = 3
+};
+
+
+
+
+typedef UInt32 ControlClockFlags;
+enum {
+ kControlClockFlagStandard = 0,
+ kControlClockNoFlags = 0,
+ kControlClockFlagDisplayOnly = 1,
+ kControlClockIsDisplayOnly = 1,
+ kControlClockFlagLive = 2,
+ kControlClockIsLive = 2
+};
+
+
+enum {
+ kControlKindClock = 'clck'
+};
+extern OSStatus
+CreateClockControl(
+ WindowRef window,
+ const Rect * boundsRect,
+ ControlClockType clockType,
+ ControlClockFlags clockFlags,
+ ControlRef * outControl) ;
+
+
+
+enum {
+ kControlClockLongDateTag = 'date',
+ kControlClockFontStyleTag = kControlFontStyleTag,
+ kControlClockAnimatingTag = 'anim'
+};
+enum {
+ kControlUserPaneProc = 256
+};
+
+
+enum {
+ kControlKindUserPane = 'upan'
+};
+extern OSStatus
+CreateUserPaneControl(
+ WindowRef window,
+ const Rect * boundsRect,
+ UInt32 features,
+ ControlRef * outControl) ;
+
+
+
+
+enum {
+ kControlUserItemDrawProcTag = 'uidp',
+ kControlUserPaneDrawProcTag = 'draw',
+ kControlUserPaneHitTestProcTag = 'hitt',
+ kControlUserPaneTrackingProcTag = 'trak',
+ kControlUserPaneIdleProcTag = 'idle',
+ kControlUserPaneKeyDownProcTag = 'keyd',
+ kControlUserPaneActivateProcTag = 'acti',
+ kControlUserPaneFocusProcTag = 'foci',
+ kControlUserPaneBackgroundProcTag = 'back'
+};
+
+typedef void ( * ControlUserPaneDrawProcPtr)(ControlRef control, SInt16 part);
+typedef ControlPartCode ( * ControlUserPaneHitTestProcPtr)(ControlRef control, Point where);
+typedef ControlPartCode ( * ControlUserPaneTrackingProcPtr)(ControlRef control, Point startPt, ControlActionUPP actionProc);
+typedef void ( * ControlUserPaneIdleProcPtr)(ControlRef control);
+typedef ControlPartCode ( * ControlUserPaneKeyDownProcPtr)(ControlRef control, SInt16 keyCode, SInt16 charCode, SInt16 modifiers);
+typedef void ( * ControlUserPaneActivateProcPtr)(ControlRef control, Boolean activating);
+typedef ControlPartCode ( * ControlUserPaneFocusProcPtr)(ControlRef control, ControlFocusPart action);
+typedef void ( * ControlUserPaneBackgroundProcPtr)(ControlRef control, ControlBackgroundPtr info);
+typedef ControlUserPaneDrawProcPtr ControlUserPaneDrawUPP;
+typedef ControlUserPaneHitTestProcPtr ControlUserPaneHitTestUPP;
+typedef ControlUserPaneTrackingProcPtr ControlUserPaneTrackingUPP;
+typedef ControlUserPaneIdleProcPtr ControlUserPaneIdleUPP;
+typedef ControlUserPaneKeyDownProcPtr ControlUserPaneKeyDownUPP;
+typedef ControlUserPaneActivateProcPtr ControlUserPaneActivateUPP;
+typedef ControlUserPaneFocusProcPtr ControlUserPaneFocusUPP;
+typedef ControlUserPaneBackgroundProcPtr ControlUserPaneBackgroundUPP;
+extern ControlUserPaneDrawUPP
+NewControlUserPaneDrawUPP(ControlUserPaneDrawProcPtr userRoutine) ;
+extern ControlUserPaneHitTestUPP
+NewControlUserPaneHitTestUPP(ControlUserPaneHitTestProcPtr userRoutine) ;
+extern ControlUserPaneTrackingUPP
+NewControlUserPaneTrackingUPP(ControlUserPaneTrackingProcPtr userRoutine) ;
+extern ControlUserPaneIdleUPP
+NewControlUserPaneIdleUPP(ControlUserPaneIdleProcPtr userRoutine) ;
+extern ControlUserPaneKeyDownUPP
+NewControlUserPaneKeyDownUPP(ControlUserPaneKeyDownProcPtr userRoutine) ;
+extern ControlUserPaneActivateUPP
+NewControlUserPaneActivateUPP(ControlUserPaneActivateProcPtr userRoutine) ;
+extern ControlUserPaneFocusUPP
+NewControlUserPaneFocusUPP(ControlUserPaneFocusProcPtr userRoutine) ;
+extern ControlUserPaneBackgroundUPP
+NewControlUserPaneBackgroundUPP(ControlUserPaneBackgroundProcPtr userRoutine) ;
+extern void
+DisposeControlUserPaneDrawUPP(ControlUserPaneDrawUPP userUPP) ;
+extern void
+DisposeControlUserPaneHitTestUPP(ControlUserPaneHitTestUPP userUPP) ;
+extern void
+DisposeControlUserPaneTrackingUPP(ControlUserPaneTrackingUPP userUPP) ;
+extern void
+DisposeControlUserPaneIdleUPP(ControlUserPaneIdleUPP userUPP) ;
+extern void
+DisposeControlUserPaneKeyDownUPP(ControlUserPaneKeyDownUPP userUPP) ;
+extern void
+DisposeControlUserPaneActivateUPP(ControlUserPaneActivateUPP userUPP) ;
+extern void
+DisposeControlUserPaneFocusUPP(ControlUserPaneFocusUPP userUPP) ;
+extern void
+DisposeControlUserPaneBackgroundUPP(ControlUserPaneBackgroundUPP userUPP) ;
+extern void
+InvokeControlUserPaneDrawUPP(
+ ControlRef control,
+ SInt16 part,
+ ControlUserPaneDrawUPP userUPP) ;
+extern ControlPartCode
+InvokeControlUserPaneHitTestUPP(
+ ControlRef control,
+ Point where,
+ ControlUserPaneHitTestUPP userUPP) ;
+extern ControlPartCode
+InvokeControlUserPaneTrackingUPP(
+ ControlRef control,
+ Point startPt,
+ ControlActionUPP actionProc,
+ ControlUserPaneTrackingUPP userUPP) ;
+extern void
+InvokeControlUserPaneIdleUPP(
+ ControlRef control,
+ ControlUserPaneIdleUPP userUPP) ;
+extern ControlPartCode
+InvokeControlUserPaneKeyDownUPP(
+ ControlRef control,
+ SInt16 keyCode,
+ SInt16 charCode,
+ SInt16 modifiers,
+ ControlUserPaneKeyDownUPP userUPP) ;
+extern void
+InvokeControlUserPaneActivateUPP(
+ ControlRef control,
+ Boolean activating,
+ ControlUserPaneActivateUPP userUPP) ;
+extern ControlPartCode
+InvokeControlUserPaneFocusUPP(
+ ControlRef control,
+ ControlFocusPart action,
+ ControlUserPaneFocusUPP userUPP) ;
+extern void
+InvokeControlUserPaneBackgroundUPP(
+ ControlRef control,
+ ControlBackgroundPtr info,
+ ControlUserPaneBackgroundUPP userUPP) ;
+
+
+
+
+
+
+
+enum {
+ kControlEditTextProc = 272,
+ kControlEditTextPasswordProc = 274
+};
+
+
+enum {
+ kControlEditTextInlineInputProc = 276
+};
+
+
+enum {
+ kControlKindEditText = 'etxt'
+};
+extern OSStatus
+CreateEditTextControl(
+ WindowRef window,
+ const Rect * boundsRect,
+ CFStringRef text,
+ Boolean isPassword,
+ Boolean useInlineInput,
+ const ControlFontStyleRec * style,
+ ControlRef * outControl) ;
+
+
+
+
+enum {
+ kControlEditTextStyleTag = kControlFontStyleTag,
+ kControlEditTextTextTag = 'text',
+ kControlEditTextTEHandleTag = 'than',
+ kControlEditTextKeyFilterTag = kControlKeyFilterTag,
+ kControlEditTextSelectionTag = 'sele',
+ kControlEditTextPasswordTag = 'pass'
+};
+
+
+enum {
+ kControlEditTextKeyScriptBehaviorTag = 'kscr',
+
+ kControlEditTextLockedTag = 'lock',
+ kControlEditTextFixedTextTag = 'ftxt',
+ kControlEditTextValidationProcTag = 'vali',
+ kControlEditTextInlinePreUpdateProcTag = 'prup',
+ kControlEditTextInlinePostUpdateProcTag = 'poup'
+};
+
+
+
+
+
+
+enum {
+
+
+
+
+
+
+ kControlEditTextCFStringTag = 'cfst',
+
+
+
+
+
+
+ kControlEditTextPasswordCFStringTag = 'pwcf'
+};
+
+
+
+
+
+struct ControlEditTextSelectionRec {
+ SInt16 selStart;
+ SInt16 selEnd;
+};
+typedef struct ControlEditTextSelectionRec ControlEditTextSelectionRec;
+typedef ControlEditTextSelectionRec * ControlEditTextSelectionPtr;
+typedef void ( * ControlEditTextValidationProcPtr)(ControlRef control);
+typedef ControlEditTextValidationProcPtr ControlEditTextValidationUPP;
+extern ControlEditTextValidationUPP
+NewControlEditTextValidationUPP(ControlEditTextValidationProcPtr userRoutine) ;
+extern void
+DisposeControlEditTextValidationUPP(ControlEditTextValidationUPP userUPP) ;
+extern void
+InvokeControlEditTextValidationUPP(
+ ControlRef control,
+ ControlEditTextValidationUPP userUPP) ;
+
+
+
+
+
+enum {
+ kControlStaticTextProc = 288
+};
+
+
+enum {
+ kControlKindStaticText = 'stxt'
+};
+extern OSStatus
+CreateStaticTextControl(
+ WindowRef window,
+ const Rect * boundsRect,
+ CFStringRef text,
+ const ControlFontStyleRec * style,
+ ControlRef * outControl) ;
+
+
+
+
+enum {
+ kControlStaticTextStyleTag = kControlFontStyleTag,
+ kControlStaticTextTextTag = 'text',
+ kControlStaticTextTextHeightTag = 'thei'
+};
+
+
+enum {
+ kControlStaticTextTruncTag = 'trun'
+};
+
+
+enum {
+ kControlStaticTextCFStringTag = 'cfst'
+};
+enum {
+ kControlPictureProc = 304,
+ kControlPictureNoTrackProc = 305
+};
+
+
+enum {
+ kControlKindPicture = 'pict'
+};
+extern OSStatus
+CreatePictureControl(
+ WindowRef window,
+ const Rect * boundsRect,
+ const ControlButtonContentInfo * content,
+ Boolean dontTrack,
+ ControlRef * outControl) ;
+
+
+
+enum {
+ kControlPictureHandleTag = 'pich'
+};
+enum {
+ kControlIconProc = 320,
+ kControlIconNoTrackProc = 321,
+ kControlIconSuiteProc = 322,
+ kControlIconSuiteNoTrackProc = 323
+};
+
+enum {
+
+
+
+ kControlIconRefProc = 324,
+ kControlIconRefNoTrackProc = 325
+};
+
+
+enum {
+ kControlKindIcon = 'icon'
+};
+extern OSStatus
+CreateIconControl(
+ WindowRef inWindow,
+ const Rect * inBoundsRect,
+ const ControlButtonContentInfo * inIconContent,
+ Boolean inDontTrack,
+ ControlRef * outControl) ;
+
+
+
+enum {
+ kControlIconTransformTag = 'trfm',
+ kControlIconAlignmentTag = 'algn'
+};
+
+
+enum {
+ kControlIconResourceIDTag = 'ires',
+ kControlIconContentTag = 'cont'
+};
+
+
+
+
+
+enum {
+ kControlWindowHeaderProc = 336,
+ kControlWindowListViewHeaderProc = 337
+};
+
+
+enum {
+ kControlKindWindowHeader = 'whed'
+};
+extern OSStatus
+CreateWindowHeaderControl(
+ WindowRef window,
+ const Rect * boundsRect,
+ Boolean isListHeader,
+ ControlRef * outControl) ;
+enum {
+ kControlListBoxProc = 352,
+ kControlListBoxAutoSizeProc = 353
+};
+
+
+enum {
+ kControlKindListBox = 'lbox'
+};
+extern OSStatus
+CreateListBoxControl(
+ WindowRef window,
+ const Rect * boundsRect,
+ Boolean autoSize,
+ SInt16 numRows,
+ SInt16 numColumns,
+ Boolean horizScroll,
+ Boolean vertScroll,
+ SInt16 cellHeight,
+ SInt16 cellWidth,
+ Boolean hasGrowSpace,
+ const ListDefSpec * listDef,
+ ControlRef * outControl) ;
+
+
+
+enum {
+ kControlListBoxListHandleTag = 'lhan',
+ kControlListBoxKeyFilterTag = kControlKeyFilterTag,
+ kControlListBoxFontStyleTag = kControlFontStyleTag
+};
+
+
+enum {
+ kControlListBoxDoubleClickTag = 'dblc',
+ kControlListBoxLDEFTag = 'ldef'
+};
+enum {
+ kControlPushButtonProc = 368,
+ kControlCheckBoxProc = 369,
+ kControlRadioButtonProc = 370,
+ kControlPushButLeftIconProc = 374,
+ kControlPushButRightIconProc = 375
+};
+
+
+enum {
+ kControlCheckBoxAutoToggleProc = 371,
+ kControlRadioButtonAutoToggleProc = 372
+};
+
+
+typedef UInt16 ControlPushButtonIconAlignment;
+enum {
+ kControlPushButtonIconOnLeft = 6,
+ kControlPushButtonIconOnRight = 7
+};
+
+
+enum {
+ kControlKindPushButton = 'push',
+ kControlKindPushIconButton = 'picn',
+ kControlKindRadioButton = 'rdio',
+ kControlKindCheckBox = 'cbox'
+};
+extern OSStatus
+CreatePushButtonControl(
+ WindowRef window,
+ const Rect * boundsRect,
+ CFStringRef title,
+ ControlRef * outControl) ;
+extern OSStatus
+CreatePushButtonWithIconControl(
+ WindowRef window,
+ const Rect * boundsRect,
+ CFStringRef title,
+ ControlButtonContentInfo * icon,
+ ControlPushButtonIconAlignment iconAlignment,
+ ControlRef * outControl) ;
+extern OSStatus
+CreateRadioButtonControl(
+ WindowRef window,
+ const Rect * boundsRect,
+ CFStringRef title,
+ SInt32 initialValue,
+ Boolean autoToggle,
+ ControlRef * outControl) ;
+extern OSStatus
+CreateCheckBoxControl(
+ WindowRef window,
+ const Rect * boundsRect,
+ CFStringRef title,
+ SInt32 initialValue,
+ Boolean autoToggle,
+ ControlRef * outControl) ;
+
+
+
+
+
+enum {
+ kControlPushButtonDefaultTag = 'dflt',
+ kControlPushButtonCancelTag = 'cncl'
+};
+
+
+
+
+
+
+
+enum {
+ kControlScrollBarProc = 384,
+ kControlScrollBarLiveProc = 386
+};
+
+
+enum {
+ kControlKindScrollBar = 'sbar'
+};
+extern OSStatus
+CreateScrollBarControl(
+ WindowRef window,
+ const Rect * boundsRect,
+ SInt32 value,
+ SInt32 minimum,
+ SInt32 maximum,
+ SInt32 viewSize,
+ Boolean liveTracking,
+ ControlActionUPP liveTrackingProc,
+ ControlRef * outControl) ;
+
+
+
+enum {
+ kControlScrollBarShowsArrowsTag = 'arro'
+};
+enum {
+ kControlPopupButtonProc = 400,
+ kControlPopupFixedWidthVariant = 1 << 0,
+ kControlPopupVariableWidthVariant = 1 << 1,
+ kControlPopupUseAddResMenuVariant = 1 << 2,
+ kControlPopupUseWFontVariant = kControlUsesOwningWindowsFontVariant
+};
+
+
+enum {
+ kControlKindPopupButton = 'popb'
+};
+extern OSStatus
+CreatePopupButtonControl(
+ WindowRef window,
+ const Rect * boundsRect,
+ CFStringRef title,
+ SInt16 menuID,
+ Boolean variableWidth,
+ SInt16 titleWidth,
+ SInt16 titleJustification,
+ Style titleStyle,
+ ControlRef * outControl) ;
+
+
+
+
+
+enum {
+ kControlPopupButtonMenuHandleTag = 'mhan',
+ kControlPopupButtonMenuRefTag = 'mhan',
+ kControlPopupButtonMenuIDTag = 'mnid'
+};
+
+
+enum {
+ kControlPopupButtonExtraHeightTag = 'exht',
+ kControlPopupButtonOwnedMenuRefTag = 'omrf'
+};
+
+
+enum {
+ kControlPopupButtonCheckCurrentTag = 'chck'
+};
+enum {
+ kControlRadioGroupProc = 416
+};
+
+
+enum {
+ kControlKindRadioGroup = 'rgrp'
+};
+extern OSStatus
+CreateRadioGroupControl(
+ WindowRef window,
+ const Rect * boundsRect,
+ ControlRef * outControl) ;
+enum {
+ kControlScrollTextBoxProc = 432,
+ kControlScrollTextBoxAutoScrollProc = 433
+};
+
+
+enum {
+ kControlKindScrollingTextBox = 'stbx'
+};
+extern OSStatus
+CreateScrollingTextBoxControl(
+ WindowRef window,
+ const Rect * boundsRect,
+ SInt16 contentResID,
+ Boolean autoScroll,
+ UInt32 delayBeforeAutoScroll,
+ UInt32 delayBetweenAutoScroll,
+ UInt16 autoScrollAmount,
+ ControlRef * outControl) ;
+
+
+
+enum {
+ kControlScrollTextBoxDelayBeforeAutoScrollTag = 'stdl',
+ kControlScrollTextBoxDelayBetweenAutoScrollTag = 'scdl',
+ kControlScrollTextBoxAutoScrollAmountTag = 'samt',
+ kControlScrollTextBoxContentsTag = 'tres',
+ kControlScrollTextBoxAnimatingTag = 'anim'
+};
+extern OSStatus
+CreateDisclosureButtonControl(
+ WindowRef inWindow,
+ const Rect * inBoundsRect,
+ SInt32 inValue,
+ Boolean inAutoToggles,
+ ControlRef * outControl) ;
+
+
+
+
+enum {
+ kControlKindDisclosureButton = 'disb'
+};
+
+
+
+
+
+
+enum {
+
+
+
+
+ kControlDisclosureButtonClosed = 0,
+
+
+
+
+ kControlDisclosureButtonDisclosed = 1
+};
+typedef SInt16 ControlRoundButtonSize;
+enum {
+
+
+
+
+ kControlRoundButtonNormalSize = kControlSizeNormal,
+
+
+
+
+ kControlRoundButtonLargeSize = kControlSizeLarge
+};
+
+
+enum {
+ kControlRoundButtonContentTag = 'cont',
+ kControlRoundButtonSizeTag = kControlSizeTag
+};
+
+
+enum {
+ kControlKindRoundButton = 'rndb'
+};
+extern OSStatus
+CreateRoundButtonControl(
+ WindowRef inWindow,
+ const Rect * inBoundsRect,
+ ControlRoundButtonSize inSize,
+ ControlButtonContentInfo * inContent,
+ ControlRef * outControl) ;
+enum {
+ kControlKindDataBrowser = 'datb'
+};
+
+
+enum {
+ errDataBrowserNotConfigured = -4970,
+ errDataBrowserItemNotFound = -4971,
+ errDataBrowserItemNotAdded = -4975,
+ errDataBrowserPropertyNotFound = -4972,
+ errDataBrowserInvalidPropertyPart = -4973,
+ errDataBrowserInvalidPropertyData = -4974,
+ errDataBrowserPropertyNotSupported = -4979
+};
+
+enum {
+
+ kControlDataBrowserIncludesFrameAndFocusTag = 'brdr',
+ kControlDataBrowserKeyFilterTag = kControlEditTextKeyFilterTag,
+ kControlDataBrowserEditTextKeyFilterTag = kControlDataBrowserKeyFilterTag,
+ kControlDataBrowserEditTextValidationProcTag = kControlEditTextValidationProcTag
+};
+
+
+typedef OSType DataBrowserViewStyle;
+enum {
+ kDataBrowserNoView = 0x3F3F3F3F,
+ kDataBrowserListView = 'lstv',
+ kDataBrowserColumnView = 'clmv'
+};
+
+
+typedef UInt32 DataBrowserSelectionFlags;
+enum {
+ kDataBrowserDragSelect = 1 << 0,
+ kDataBrowserSelectOnlyOne = 1 << 1,
+ kDataBrowserResetSelection = 1 << 2,
+ kDataBrowserCmdTogglesSelection = 1 << 3,
+ kDataBrowserNoDisjointSelection = 1 << 4,
+ kDataBrowserAlwaysExtendSelection = 1 << 5,
+ kDataBrowserNeverEmptySelectionSet = 1 << 6
+};
+
+
+typedef UInt16 DataBrowserSortOrder;
+enum {
+ kDataBrowserOrderUndefined = 0,
+ kDataBrowserOrderIncreasing = 1,
+ kDataBrowserOrderDecreasing = 2
+};
+
+
+typedef UInt32 DataBrowserItemID;
+enum {
+ kDataBrowserNoItem = 0L
+};
+
+typedef UInt32 DataBrowserItemState;
+enum {
+ kDataBrowserItemNoState = 0,
+ kDataBrowserItemAnyState = (unsigned long)(-1),
+ kDataBrowserItemIsSelected = 1 << 0,
+ kDataBrowserContainerIsOpen = 1 << 1,
+ kDataBrowserItemIsDragTarget = 1 << 2
+};
+
+
+typedef UInt8 DataBrowserRevealOptions;
+enum {
+ kDataBrowserRevealOnly = 0,
+ kDataBrowserRevealAndCenterInView = 1 << 0,
+ kDataBrowserRevealWithoutSelecting = 1 << 1
+};
+
+
+typedef UInt32 DataBrowserSetOption;
+enum {
+ kDataBrowserItemsAdd = 0,
+ kDataBrowserItemsAssign = 1,
+ kDataBrowserItemsToggle = 2,
+ kDataBrowserItemsRemove = 3
+};
+
+
+typedef UInt32 DataBrowserSelectionAnchorDirection;
+enum {
+ kDataBrowserSelectionAnchorUp = 0,
+ kDataBrowserSelectionAnchorDown = 1,
+ kDataBrowserSelectionAnchorLeft = 2,
+ kDataBrowserSelectionAnchorRight = 3
+};
+
+
+typedef UInt32 DataBrowserEditCommand;
+enum {
+ kDataBrowserEditMsgUndo = kHICommandUndo,
+ kDataBrowserEditMsgRedo = kHICommandRedo,
+ kDataBrowserEditMsgCut = kHICommandCut,
+ kDataBrowserEditMsgCopy = kHICommandCopy,
+ kDataBrowserEditMsgPaste = kHICommandPaste,
+ kDataBrowserEditMsgClear = kHICommandClear,
+ kDataBrowserEditMsgSelectAll = kHICommandSelectAll
+};
+
+
+typedef UInt32 DataBrowserItemNotification;
+enum {
+ kDataBrowserItemAdded = 1,
+ kDataBrowserItemRemoved = 2,
+ kDataBrowserEditStarted = 3,
+ kDataBrowserEditStopped = 4,
+ kDataBrowserItemSelected = 5,
+ kDataBrowserItemDeselected = 6,
+ kDataBrowserItemDoubleClicked = 7,
+ kDataBrowserContainerOpened = 8,
+ kDataBrowserContainerClosing = 9,
+ kDataBrowserContainerClosed = 10,
+ kDataBrowserContainerSorting = 11,
+ kDataBrowserContainerSorted = 12,
+ kDataBrowserUserToggledContainer = 16,
+ kDataBrowserTargetChanged = 15,
+ kDataBrowserUserStateChanged = 13,
+ kDataBrowserSelectionSetChanged = 14
+};
+
+
+
+typedef UInt32 DataBrowserPropertyID;
+enum {
+
+ kDataBrowserItemNoProperty = 0L,
+ kDataBrowserItemIsActiveProperty = 1L,
+ kDataBrowserItemIsSelectableProperty = 2L,
+ kDataBrowserItemIsEditableProperty = 3L,
+ kDataBrowserItemIsContainerProperty = 4L,
+ kDataBrowserContainerIsOpenableProperty = 5L,
+ kDataBrowserContainerIsClosableProperty = 6L,
+ kDataBrowserContainerIsSortableProperty = 7L,
+ kDataBrowserItemSelfIdentityProperty = 8L,
+ kDataBrowserContainerAliasIDProperty = 9L,
+ kDataBrowserColumnViewPreviewProperty = 10L,
+ kDataBrowserItemParentContainerProperty = 11L
+};
+
+
+
+
+typedef OSType DataBrowserPropertyType;
+enum {
+
+ kDataBrowserCustomType = 0x3F3F3F3F,
+ kDataBrowserIconType = 'icnr',
+ kDataBrowserTextType = 'text',
+ kDataBrowserDateTimeType = 'date',
+ kDataBrowserSliderType = 'sldr',
+ kDataBrowserCheckboxType = 'chbx',
+ kDataBrowserProgressBarType = 'prog',
+ kDataBrowserRelevanceRankType = 'rank',
+ kDataBrowserPopupMenuType = 'menu',
+ kDataBrowserIconAndTextType = 'ticn'
+};
+
+
+
+
+typedef OSType DataBrowserPropertyPart;
+enum {
+ kDataBrowserPropertyEnclosingPart = 0L,
+ kDataBrowserPropertyContentPart = '----',
+ kDataBrowserPropertyDisclosurePart = 'disc',
+ kDataBrowserPropertyTextPart = kDataBrowserTextType,
+ kDataBrowserPropertyIconPart = kDataBrowserIconType,
+ kDataBrowserPropertySliderPart = kDataBrowserSliderType,
+ kDataBrowserPropertyCheckboxPart = kDataBrowserCheckboxType,
+ kDataBrowserPropertyProgressBarPart = kDataBrowserProgressBarType,
+ kDataBrowserPropertyRelevanceRankPart = kDataBrowserRelevanceRankType
+};
+
+
+typedef unsigned long DataBrowserPropertyFlags;
+
+enum {
+ kDataBrowserUniversalPropertyFlagsMask = 0xFF,
+ kDataBrowserPropertyIsMutable = 1 << 0,
+ kDataBrowserDefaultPropertyFlags = 0 << 0,
+ kDataBrowserUniversalPropertyFlags = kDataBrowserUniversalPropertyFlagsMask,
+ kDataBrowserPropertyIsEditable = kDataBrowserPropertyIsMutable
+};
+
+
+enum {
+ kDataBrowserPropertyFlagsOffset = 8,
+ kDataBrowserPropertyFlagsMask = 0xFF << kDataBrowserPropertyFlagsOffset,
+ kDataBrowserCheckboxTriState = 1 << kDataBrowserPropertyFlagsOffset,
+ kDataBrowserDateTimeRelative = 1 << (kDataBrowserPropertyFlagsOffset),
+ kDataBrowserDateTimeDateOnly = 1 << (kDataBrowserPropertyFlagsOffset + 1),
+ kDataBrowserDateTimeTimeOnly = 1 << (kDataBrowserPropertyFlagsOffset + 2),
+ kDataBrowserDateTimeSecondsToo = 1 << (kDataBrowserPropertyFlagsOffset + 3),
+ kDataBrowserSliderPlainThumb = kThemeThumbPlain << kDataBrowserPropertyFlagsOffset,
+ kDataBrowserSliderUpwardThumb = kThemeThumbUpward << kDataBrowserPropertyFlagsOffset,
+ kDataBrowserSliderDownwardThumb = kThemeThumbDownward << kDataBrowserPropertyFlagsOffset,
+ kDataBrowserDoNotTruncateText = 3 << kDataBrowserPropertyFlagsOffset,
+ kDataBrowserTruncateTextAtEnd = 2 << kDataBrowserPropertyFlagsOffset,
+ kDataBrowserTruncateTextMiddle = 0 << kDataBrowserPropertyFlagsOffset,
+ kDataBrowserTruncateTextAtStart = 1 << kDataBrowserPropertyFlagsOffset,
+ kDataBrowserPropertyModificationFlags = kDataBrowserPropertyFlagsMask,
+ kDataBrowserRelativeDateTime = kDataBrowserDateTimeRelative
+};
+
+
+
+
+
+enum {
+ kDataBrowserViewSpecificFlagsOffset = 16,
+ kDataBrowserViewSpecificFlagsMask = 0xFF << kDataBrowserViewSpecificFlagsOffset,
+ kDataBrowserViewSpecificPropertyFlags = kDataBrowserViewSpecificFlagsMask
+};
+
+
+enum {
+ kDataBrowserClientPropertyFlagsOffset = 24,
+ kDataBrowserClientPropertyFlagsMask = (unsigned long)(0xFF << kDataBrowserClientPropertyFlagsOffset)
+};
+
+
+struct DataBrowserPropertyDesc {
+ DataBrowserPropertyID propertyID;
+ DataBrowserPropertyType propertyType;
+ DataBrowserPropertyFlags propertyFlags;
+};
+typedef struct DataBrowserPropertyDesc DataBrowserPropertyDesc;
+
+typedef void ( * DataBrowserItemProcPtr)(DataBrowserItemID item, DataBrowserItemState state, void *clientData);
+typedef DataBrowserItemProcPtr DataBrowserItemUPP;
+extern DataBrowserItemUPP
+NewDataBrowserItemUPP(DataBrowserItemProcPtr userRoutine) ;
+extern void
+DisposeDataBrowserItemUPP(DataBrowserItemUPP userUPP) ;
+extern void
+InvokeDataBrowserItemUPP(
+ DataBrowserItemID item,
+ DataBrowserItemState state,
+ void * clientData,
+ DataBrowserItemUPP userUPP) ;
+extern OSStatus
+CreateDataBrowserControl(
+ WindowRef window,
+ const Rect * boundsRect,
+ DataBrowserViewStyle style,
+ ControlRef * outControl) ;
+extern OSStatus
+GetDataBrowserViewStyle(
+ ControlRef browser,
+ DataBrowserViewStyle * style) ;
+extern OSStatus
+SetDataBrowserViewStyle(
+ ControlRef browser,
+ DataBrowserViewStyle style) ;
+extern OSStatus
+AddDataBrowserItems(
+ ControlRef browser,
+ DataBrowserItemID container,
+ UInt32 numItems,
+ const DataBrowserItemID * items,
+ DataBrowserPropertyID preSortProperty) ;
+extern OSStatus
+RemoveDataBrowserItems(
+ ControlRef browser,
+ DataBrowserItemID container,
+ UInt32 numItems,
+ const DataBrowserItemID * items,
+ DataBrowserPropertyID preSortProperty) ;
+extern OSStatus
+UpdateDataBrowserItems(
+ ControlRef browser,
+ DataBrowserItemID container,
+ UInt32 numItems,
+ const DataBrowserItemID * items,
+ DataBrowserPropertyID preSortProperty,
+ DataBrowserPropertyID propertyID) ;
+extern Boolean
+EnableDataBrowserEditCommand(
+ ControlRef browser,
+ DataBrowserEditCommand command) ;
+extern OSStatus
+ExecuteDataBrowserEditCommand(
+ ControlRef browser,
+ DataBrowserEditCommand command) ;
+extern OSStatus
+GetDataBrowserSelectionAnchor(
+ ControlRef browser,
+ DataBrowserItemID * first,
+ DataBrowserItemID * last) ;
+extern OSStatus
+MoveDataBrowserSelectionAnchor(
+ ControlRef browser,
+ DataBrowserSelectionAnchorDirection direction,
+ Boolean extendSelection) ;
+extern OSStatus
+OpenDataBrowserContainer(
+ ControlRef browser,
+ DataBrowserItemID container) ;
+extern OSStatus
+CloseDataBrowserContainer(
+ ControlRef browser,
+ DataBrowserItemID container) ;
+extern OSStatus
+SortDataBrowserContainer(
+ ControlRef browser,
+ DataBrowserItemID container,
+ Boolean sortChildren) ;
+extern OSStatus
+GetDataBrowserItems(
+ ControlRef browser,
+ DataBrowserItemID container,
+ Boolean recurse,
+ DataBrowserItemState state,
+ Handle items) ;
+extern OSStatus
+GetDataBrowserItemCount(
+ ControlRef browser,
+ DataBrowserItemID container,
+ Boolean recurse,
+ DataBrowserItemState state,
+ UInt32 * numItems) ;
+extern OSStatus
+ForEachDataBrowserItem(
+ ControlRef browser,
+ DataBrowserItemID container,
+ Boolean recurse,
+ DataBrowserItemState state,
+ DataBrowserItemUPP callback,
+ void * clientData) ;
+extern Boolean
+IsDataBrowserItemSelected(
+ ControlRef browser,
+ DataBrowserItemID item) ;
+extern OSStatus
+GetDataBrowserItemState(
+ ControlRef browser,
+ DataBrowserItemID item,
+ DataBrowserItemState * state) ;
+extern OSStatus
+RevealDataBrowserItem(
+ ControlRef browser,
+ DataBrowserItemID item,
+ DataBrowserPropertyID propertyID,
+ DataBrowserRevealOptions options) ;
+extern OSStatus
+SetDataBrowserSelectedItems(
+ ControlRef browser,
+ UInt32 numItems,
+ const DataBrowserItemID * items,
+ DataBrowserSetOption operation) ;
+extern OSStatus
+SetDataBrowserUserState(
+ ControlRef browser,
+ CFDataRef stateInfo) ;
+extern OSStatus
+GetDataBrowserUserState(
+ ControlRef browser,
+ CFDataRef * stateInfo) ;
+extern OSStatus
+SetDataBrowserActiveItems(
+ ControlRef browser,
+ Boolean active) ;
+extern OSStatus
+GetDataBrowserActiveItems(
+ ControlRef browser,
+ Boolean * active) ;
+extern OSStatus
+SetDataBrowserScrollBarInset(
+ ControlRef browser,
+ Rect * insetRect) ;
+extern OSStatus
+GetDataBrowserScrollBarInset(
+ ControlRef browser,
+ Rect * insetRect) ;
+extern OSStatus
+SetDataBrowserTarget(
+ ControlRef browser,
+ DataBrowserItemID target) ;
+extern OSStatus
+GetDataBrowserTarget(
+ ControlRef browser,
+ DataBrowserItemID * target) ;
+extern OSStatus
+SetDataBrowserSortOrder(
+ ControlRef browser,
+ DataBrowserSortOrder order) ;
+extern OSStatus
+GetDataBrowserSortOrder(
+ ControlRef browser,
+ DataBrowserSortOrder * order) ;
+extern OSStatus
+SetDataBrowserScrollPosition(
+ ControlRef browser,
+ UInt32 top,
+ UInt32 left) ;
+extern OSStatus
+GetDataBrowserScrollPosition(
+ ControlRef browser,
+ UInt32 * top,
+ UInt32 * left) ;
+extern OSStatus
+SetDataBrowserHasScrollBars(
+ ControlRef browser,
+ Boolean horiz,
+ Boolean vert) ;
+extern OSStatus
+GetDataBrowserHasScrollBars(
+ ControlRef browser,
+ Boolean * horiz,
+ Boolean * vert) ;
+extern OSStatus
+SetDataBrowserSortProperty(
+ ControlRef browser,
+ DataBrowserPropertyID property) ;
+extern OSStatus
+GetDataBrowserSortProperty(
+ ControlRef browser,
+ DataBrowserPropertyID * property) ;
+extern OSStatus
+SetDataBrowserSelectionFlags(
+ ControlRef browser,
+ DataBrowserSelectionFlags selectionFlags) ;
+extern OSStatus
+GetDataBrowserSelectionFlags(
+ ControlRef browser,
+ DataBrowserSelectionFlags * selectionFlags) ;
+extern OSStatus
+SetDataBrowserPropertyFlags(
+ ControlRef browser,
+ DataBrowserPropertyID property,
+ DataBrowserPropertyFlags flags) ;
+extern OSStatus
+GetDataBrowserPropertyFlags(
+ ControlRef browser,
+ DataBrowserPropertyID property,
+ DataBrowserPropertyFlags * flags) ;
+extern OSStatus
+SetDataBrowserEditText(
+ ControlRef browser,
+ CFStringRef text) ;
+extern OSStatus
+CopyDataBrowserEditText(
+ ControlRef browser,
+ CFStringRef * text) ;
+extern OSStatus
+GetDataBrowserEditText(
+ ControlRef browser,
+ CFMutableStringRef text) ;
+extern OSStatus
+SetDataBrowserEditItem(
+ ControlRef browser,
+ DataBrowserItemID item,
+ DataBrowserPropertyID property) ;
+extern OSStatus
+GetDataBrowserEditItem(
+ ControlRef browser,
+ DataBrowserItemID * item,
+ DataBrowserPropertyID * property) ;
+extern OSStatus
+GetDataBrowserItemPartBounds(
+ ControlRef browser,
+ DataBrowserItemID item,
+ DataBrowserPropertyID property,
+ DataBrowserPropertyPart part,
+ Rect * bounds) ;
+
+
+
+
+
+typedef void * DataBrowserItemDataRef;
+extern OSStatus
+SetDataBrowserItemDataIcon(
+ DataBrowserItemDataRef itemData,
+ IconRef theData) ;
+extern OSStatus
+GetDataBrowserItemDataIcon(
+ DataBrowserItemDataRef itemData,
+ IconRef * theData) ;
+extern OSStatus
+SetDataBrowserItemDataText(
+ DataBrowserItemDataRef itemData,
+ CFStringRef theData) ;
+extern OSStatus
+GetDataBrowserItemDataText(
+ DataBrowserItemDataRef itemData,
+ CFStringRef * theData) ;
+extern OSStatus
+SetDataBrowserItemDataValue(
+ DataBrowserItemDataRef itemData,
+ SInt32 theData) ;
+extern OSStatus
+GetDataBrowserItemDataValue(
+ DataBrowserItemDataRef itemData,
+ SInt32 * theData) ;
+extern OSStatus
+SetDataBrowserItemDataMinimum(
+ DataBrowserItemDataRef itemData,
+ SInt32 theData) ;
+extern OSStatus
+GetDataBrowserItemDataMinimum(
+ DataBrowserItemDataRef itemData,
+ SInt32 * theData) ;
+extern OSStatus
+SetDataBrowserItemDataMaximum(
+ DataBrowserItemDataRef itemData,
+ SInt32 theData) ;
+extern OSStatus
+GetDataBrowserItemDataMaximum(
+ DataBrowserItemDataRef itemData,
+ SInt32 * theData) ;
+extern OSStatus
+SetDataBrowserItemDataBooleanValue(
+ DataBrowserItemDataRef itemData,
+ Boolean theData) ;
+extern OSStatus
+GetDataBrowserItemDataBooleanValue(
+ DataBrowserItemDataRef itemData,
+ Boolean * theData) ;
+extern OSStatus
+SetDataBrowserItemDataMenuRef(
+ DataBrowserItemDataRef itemData,
+ MenuRef theData) ;
+extern OSStatus
+GetDataBrowserItemDataMenuRef(
+ DataBrowserItemDataRef itemData,
+ MenuRef * theData) ;
+extern OSStatus
+SetDataBrowserItemDataRGBColor(
+ DataBrowserItemDataRef itemData,
+ const RGBColor * theData) ;
+extern OSStatus
+GetDataBrowserItemDataRGBColor(
+ DataBrowserItemDataRef itemData,
+ RGBColor * theData) ;
+extern OSStatus
+SetDataBrowserItemDataDrawState(
+ DataBrowserItemDataRef itemData,
+ ThemeDrawState theData) ;
+extern OSStatus
+GetDataBrowserItemDataDrawState(
+ DataBrowserItemDataRef itemData,
+ ThemeDrawState * theData) ;
+extern OSStatus
+SetDataBrowserItemDataButtonValue(
+ DataBrowserItemDataRef itemData,
+ ThemeButtonValue theData) ;
+extern OSStatus
+GetDataBrowserItemDataButtonValue(
+ DataBrowserItemDataRef itemData,
+ ThemeButtonValue * theData) ;
+extern OSStatus
+SetDataBrowserItemDataIconTransform(
+ DataBrowserItemDataRef itemData,
+ IconTransformType theData) ;
+extern OSStatus
+GetDataBrowserItemDataIconTransform(
+ DataBrowserItemDataRef itemData,
+ IconTransformType * theData) ;
+extern OSStatus
+SetDataBrowserItemDataDateTime(
+ DataBrowserItemDataRef itemData,
+ long theData) ;
+extern OSStatus
+GetDataBrowserItemDataDateTime(
+ DataBrowserItemDataRef itemData,
+ long * theData) ;
+extern OSStatus
+SetDataBrowserItemDataLongDateTime(
+ DataBrowserItemDataRef itemData,
+ const LongDateTime * theData) ;
+extern OSStatus
+GetDataBrowserItemDataLongDateTime(
+ DataBrowserItemDataRef itemData,
+ LongDateTime * theData) ;
+extern OSStatus
+SetDataBrowserItemDataItemID(
+ DataBrowserItemDataRef itemData,
+ DataBrowserItemID theData) ;
+extern OSStatus
+GetDataBrowserItemDataItemID(
+ DataBrowserItemDataRef itemData,
+ DataBrowserItemID * theData) ;
+extern OSStatus
+GetDataBrowserItemDataProperty(
+ DataBrowserItemDataRef itemData,
+ DataBrowserPropertyID * theData) ;
+
+
+
+
+
+
+typedef OSStatus ( * DataBrowserItemDataProcPtr)(ControlRef browser, DataBrowserItemID item, DataBrowserPropertyID property, DataBrowserItemDataRef itemData, Boolean setValue);
+typedef DataBrowserItemDataProcPtr DataBrowserItemDataUPP;
+
+
+typedef Boolean ( * DataBrowserItemCompareProcPtr)(ControlRef browser, DataBrowserItemID itemOne, DataBrowserItemID itemTwo, DataBrowserPropertyID sortProperty);
+typedef DataBrowserItemCompareProcPtr DataBrowserItemCompareUPP;
+typedef void ( * DataBrowserItemNotificationWithItemProcPtr)(ControlRef browser, DataBrowserItemID item, DataBrowserItemNotification message, DataBrowserItemDataRef itemData);
+typedef void ( * DataBrowserItemNotificationProcPtr)(ControlRef browser, DataBrowserItemID item, DataBrowserItemNotification message);
+typedef DataBrowserItemNotificationWithItemProcPtr DataBrowserItemNotificationWithItemUPP;
+typedef DataBrowserItemNotificationProcPtr DataBrowserItemNotificationUPP;
+
+
+
+typedef Boolean ( * DataBrowserAddDragItemProcPtr)(ControlRef browser, DragReference theDrag, DataBrowserItemID item, ItemReference *itemRef);
+typedef Boolean ( * DataBrowserAcceptDragProcPtr)(ControlRef browser, DragReference theDrag, DataBrowserItemID item);
+typedef Boolean ( * DataBrowserReceiveDragProcPtr)(ControlRef browser, DragReference theDrag, DataBrowserItemID item);
+typedef void ( * DataBrowserPostProcessDragProcPtr)(ControlRef browser, DragReference theDrag, OSStatus trackDragResult);
+typedef DataBrowserAddDragItemProcPtr DataBrowserAddDragItemUPP;
+typedef DataBrowserAcceptDragProcPtr DataBrowserAcceptDragUPP;
+typedef DataBrowserReceiveDragProcPtr DataBrowserReceiveDragUPP;
+typedef DataBrowserPostProcessDragProcPtr DataBrowserPostProcessDragUPP;
+
+
+typedef void ( * DataBrowserGetContextualMenuProcPtr)(ControlRef browser, MenuRef *menu, UInt32 *helpType, CFStringRef *helpItemString, AEDesc *selection);
+typedef void ( * DataBrowserSelectContextualMenuProcPtr)(ControlRef browser, MenuRef menu, UInt32 selectionType, SInt16 menuID, MenuItemIndex menuItem);
+typedef DataBrowserGetContextualMenuProcPtr DataBrowserGetContextualMenuUPP;
+typedef DataBrowserSelectContextualMenuProcPtr DataBrowserSelectContextualMenuUPP;
+
+
+typedef void ( * DataBrowserItemHelpContentProcPtr)(ControlRef browser, DataBrowserItemID item, DataBrowserPropertyID property, HMContentRequest inRequest, HMContentProvidedType *outContentProvided, HMHelpContentPtr ioHelpContent);
+typedef DataBrowserItemHelpContentProcPtr DataBrowserItemHelpContentUPP;
+extern DataBrowserItemDataUPP
+NewDataBrowserItemDataUPP(DataBrowserItemDataProcPtr userRoutine) ;
+extern DataBrowserItemCompareUPP
+NewDataBrowserItemCompareUPP(DataBrowserItemCompareProcPtr userRoutine) ;
+extern DataBrowserItemNotificationWithItemUPP
+NewDataBrowserItemNotificationWithItemUPP(DataBrowserItemNotificationWithItemProcPtr userRoutine) ;
+extern DataBrowserItemNotificationUPP
+NewDataBrowserItemNotificationUPP(DataBrowserItemNotificationProcPtr userRoutine) ;
+extern DataBrowserAddDragItemUPP
+NewDataBrowserAddDragItemUPP(DataBrowserAddDragItemProcPtr userRoutine) ;
+extern DataBrowserAcceptDragUPP
+NewDataBrowserAcceptDragUPP(DataBrowserAcceptDragProcPtr userRoutine) ;
+extern DataBrowserReceiveDragUPP
+NewDataBrowserReceiveDragUPP(DataBrowserReceiveDragProcPtr userRoutine) ;
+extern DataBrowserPostProcessDragUPP
+NewDataBrowserPostProcessDragUPP(DataBrowserPostProcessDragProcPtr userRoutine) ;
+extern DataBrowserGetContextualMenuUPP
+NewDataBrowserGetContextualMenuUPP(DataBrowserGetContextualMenuProcPtr userRoutine) ;
+extern DataBrowserSelectContextualMenuUPP
+NewDataBrowserSelectContextualMenuUPP(DataBrowserSelectContextualMenuProcPtr userRoutine) ;
+extern DataBrowserItemHelpContentUPP
+NewDataBrowserItemHelpContentUPP(DataBrowserItemHelpContentProcPtr userRoutine) ;
+extern void
+DisposeDataBrowserItemDataUPP(DataBrowserItemDataUPP userUPP) ;
+extern void
+DisposeDataBrowserItemCompareUPP(DataBrowserItemCompareUPP userUPP) ;
+extern void
+DisposeDataBrowserItemNotificationWithItemUPP(DataBrowserItemNotificationWithItemUPP userUPP) ;
+extern void
+DisposeDataBrowserItemNotificationUPP(DataBrowserItemNotificationUPP userUPP) ;
+extern void
+DisposeDataBrowserAddDragItemUPP(DataBrowserAddDragItemUPP userUPP) ;
+extern void
+DisposeDataBrowserAcceptDragUPP(DataBrowserAcceptDragUPP userUPP) ;
+extern void
+DisposeDataBrowserReceiveDragUPP(DataBrowserReceiveDragUPP userUPP) ;
+extern void
+DisposeDataBrowserPostProcessDragUPP(DataBrowserPostProcessDragUPP userUPP) ;
+extern void
+DisposeDataBrowserGetContextualMenuUPP(DataBrowserGetContextualMenuUPP userUPP) ;
+extern void
+DisposeDataBrowserSelectContextualMenuUPP(DataBrowserSelectContextualMenuUPP userUPP) ;
+extern void
+DisposeDataBrowserItemHelpContentUPP(DataBrowserItemHelpContentUPP userUPP) ;
+extern OSStatus
+InvokeDataBrowserItemDataUPP(
+ ControlRef browser,
+ DataBrowserItemID item,
+ DataBrowserPropertyID property,
+ DataBrowserItemDataRef itemData,
+ Boolean setValue,
+ DataBrowserItemDataUPP userUPP) ;
+extern Boolean
+InvokeDataBrowserItemCompareUPP(
+ ControlRef browser,
+ DataBrowserItemID itemOne,
+ DataBrowserItemID itemTwo,
+ DataBrowserPropertyID sortProperty,
+ DataBrowserItemCompareUPP userUPP) ;
+extern void
+InvokeDataBrowserItemNotificationWithItemUPP(
+ ControlRef browser,
+ DataBrowserItemID item,
+ DataBrowserItemNotification message,
+ DataBrowserItemDataRef itemData,
+ DataBrowserItemNotificationWithItemUPP userUPP) ;
+extern void
+InvokeDataBrowserItemNotificationUPP(
+ ControlRef browser,
+ DataBrowserItemID item,
+ DataBrowserItemNotification message,
+ DataBrowserItemNotificationUPP userUPP) ;
+extern Boolean
+InvokeDataBrowserAddDragItemUPP(
+ ControlRef browser,
+ DragReference theDrag,
+ DataBrowserItemID item,
+ ItemReference * itemRef,
+ DataBrowserAddDragItemUPP userUPP) ;
+extern Boolean
+InvokeDataBrowserAcceptDragUPP(
+ ControlRef browser,
+ DragReference theDrag,
+ DataBrowserItemID item,
+ DataBrowserAcceptDragUPP userUPP) ;
+extern Boolean
+InvokeDataBrowserReceiveDragUPP(
+ ControlRef browser,
+ DragReference theDrag,
+ DataBrowserItemID item,
+ DataBrowserReceiveDragUPP userUPP) ;
+extern void
+InvokeDataBrowserPostProcessDragUPP(
+ ControlRef browser,
+ DragReference theDrag,
+ OSStatus trackDragResult,
+ DataBrowserPostProcessDragUPP userUPP) ;
+extern void
+InvokeDataBrowserGetContextualMenuUPP(
+ ControlRef browser,
+ MenuRef * menu,
+ UInt32 * helpType,
+ CFStringRef * helpItemString,
+ AEDesc * selection,
+ DataBrowserGetContextualMenuUPP userUPP) ;
+extern void
+InvokeDataBrowserSelectContextualMenuUPP(
+ ControlRef browser,
+ MenuRef menu,
+ UInt32 selectionType,
+ SInt16 menuID,
+ MenuItemIndex menuItem,
+ DataBrowserSelectContextualMenuUPP userUPP) ;
+extern void
+InvokeDataBrowserItemHelpContentUPP(
+ ControlRef browser,
+ DataBrowserItemID item,
+ DataBrowserPropertyID property,
+ HMContentRequest inRequest,
+ HMContentProvidedType * outContentProvided,
+ HMHelpContentPtr ioHelpContent,
+ DataBrowserItemHelpContentUPP userUPP) ;
+
+
+enum {
+ kDataBrowserLatestCallbacks = 0
+};
+
+struct DataBrowserCallbacks {
+ UInt32 version;
+
+ union {
+ struct {
+ DataBrowserItemDataUPP itemDataCallback;
+ DataBrowserItemCompareUPP itemCompareCallback;
+ DataBrowserItemNotificationUPP itemNotificationCallback;
+
+ DataBrowserAddDragItemUPP addDragItemCallback;
+ DataBrowserAcceptDragUPP acceptDragCallback;
+ DataBrowserReceiveDragUPP receiveDragCallback;
+ DataBrowserPostProcessDragUPP postProcessDragCallback;
+
+ DataBrowserItemHelpContentUPP itemHelpContentCallback;
+ DataBrowserGetContextualMenuUPP getContextualMenuCallback;
+ DataBrowserSelectContextualMenuUPP selectContextualMenuCallback;
+ } v1;
+ } u;
+};
+typedef struct DataBrowserCallbacks DataBrowserCallbacks;
+extern OSStatus
+InitDataBrowserCallbacks(DataBrowserCallbacks * callbacks) ;
+extern OSStatus
+GetDataBrowserCallbacks(
+ ControlRef browser,
+ DataBrowserCallbacks * callbacks) ;
+extern OSStatus
+SetDataBrowserCallbacks(
+ ControlRef browser,
+ const DataBrowserCallbacks * callbacks) ;
+
+
+
+
+
+typedef unsigned long DataBrowserDragFlags;
+typedef SInt16 DataBrowserTrackingResult;
+enum {
+ kDataBrowserContentHit = 1,
+ kDataBrowserNothingHit = 0,
+ kDataBrowserStopTracking = -1
+};
+
+typedef void ( * DataBrowserDrawItemProcPtr)(ControlRef browser, DataBrowserItemID item, DataBrowserPropertyID property, DataBrowserItemState itemState, const Rect *theRect, SInt16 gdDepth, Boolean colorDevice);
+typedef Boolean ( * DataBrowserEditItemProcPtr)(ControlRef browser, DataBrowserItemID item, DataBrowserPropertyID property, CFStringRef theString, Rect *maxEditTextRect, Boolean *shrinkToFit);
+typedef Boolean ( * DataBrowserHitTestProcPtr)(ControlRef browser, DataBrowserItemID itemID, DataBrowserPropertyID property, const Rect *theRect, const Rect *mouseRect);
+typedef DataBrowserTrackingResult ( * DataBrowserTrackingProcPtr)(ControlRef browser, DataBrowserItemID itemID, DataBrowserPropertyID property, const Rect *theRect, Point startPt, EventModifiers modifiers);
+typedef void ( * DataBrowserItemDragRgnProcPtr)(ControlRef browser, DataBrowserItemID itemID, DataBrowserPropertyID property, const Rect *theRect, RgnHandle dragRgn);
+typedef DataBrowserDragFlags ( * DataBrowserItemAcceptDragProcPtr)(ControlRef browser, DataBrowserItemID itemID, DataBrowserPropertyID property, const Rect *theRect, DragReference theDrag);
+typedef Boolean ( * DataBrowserItemReceiveDragProcPtr)(ControlRef browser, DataBrowserItemID itemID, DataBrowserPropertyID property, DataBrowserDragFlags dragFlags, DragReference theDrag);
+typedef DataBrowserDrawItemProcPtr DataBrowserDrawItemUPP;
+typedef DataBrowserEditItemProcPtr DataBrowserEditItemUPP;
+typedef DataBrowserHitTestProcPtr DataBrowserHitTestUPP;
+typedef DataBrowserTrackingProcPtr DataBrowserTrackingUPP;
+typedef DataBrowserItemDragRgnProcPtr DataBrowserItemDragRgnUPP;
+typedef DataBrowserItemAcceptDragProcPtr DataBrowserItemAcceptDragUPP;
+typedef DataBrowserItemReceiveDragProcPtr DataBrowserItemReceiveDragUPP;
+extern DataBrowserDrawItemUPP
+NewDataBrowserDrawItemUPP(DataBrowserDrawItemProcPtr userRoutine) ;
+extern DataBrowserEditItemUPP
+NewDataBrowserEditItemUPP(DataBrowserEditItemProcPtr userRoutine) ;
+extern DataBrowserHitTestUPP
+NewDataBrowserHitTestUPP(DataBrowserHitTestProcPtr userRoutine) ;
+extern DataBrowserTrackingUPP
+NewDataBrowserTrackingUPP(DataBrowserTrackingProcPtr userRoutine) ;
+extern DataBrowserItemDragRgnUPP
+NewDataBrowserItemDragRgnUPP(DataBrowserItemDragRgnProcPtr userRoutine) ;
+extern DataBrowserItemAcceptDragUPP
+NewDataBrowserItemAcceptDragUPP(DataBrowserItemAcceptDragProcPtr userRoutine) ;
+extern DataBrowserItemReceiveDragUPP
+NewDataBrowserItemReceiveDragUPP(DataBrowserItemReceiveDragProcPtr userRoutine) ;
+extern void
+DisposeDataBrowserDrawItemUPP(DataBrowserDrawItemUPP userUPP) ;
+extern void
+DisposeDataBrowserEditItemUPP(DataBrowserEditItemUPP userUPP) ;
+extern void
+DisposeDataBrowserHitTestUPP(DataBrowserHitTestUPP userUPP) ;
+extern void
+DisposeDataBrowserTrackingUPP(DataBrowserTrackingUPP userUPP) ;
+extern void
+DisposeDataBrowserItemDragRgnUPP(DataBrowserItemDragRgnUPP userUPP) ;
+extern void
+DisposeDataBrowserItemAcceptDragUPP(DataBrowserItemAcceptDragUPP userUPP) ;
+extern void
+DisposeDataBrowserItemReceiveDragUPP(DataBrowserItemReceiveDragUPP userUPP) ;
+extern void
+InvokeDataBrowserDrawItemUPP(
+ ControlRef browser,
+ DataBrowserItemID item,
+ DataBrowserPropertyID property,
+ DataBrowserItemState itemState,
+ const Rect * theRect,
+ SInt16 gdDepth,
+ Boolean colorDevice,
+ DataBrowserDrawItemUPP userUPP) ;
+extern Boolean
+InvokeDataBrowserEditItemUPP(
+ ControlRef browser,
+ DataBrowserItemID item,
+ DataBrowserPropertyID property,
+ CFStringRef theString,
+ Rect * maxEditTextRect,
+ Boolean * shrinkToFit,
+ DataBrowserEditItemUPP userUPP) ;
+extern Boolean
+InvokeDataBrowserHitTestUPP(
+ ControlRef browser,
+ DataBrowserItemID itemID,
+ DataBrowserPropertyID property,
+ const Rect * theRect,
+ const Rect * mouseRect,
+ DataBrowserHitTestUPP userUPP) ;
+extern DataBrowserTrackingResult
+InvokeDataBrowserTrackingUPP(
+ ControlRef browser,
+ DataBrowserItemID itemID,
+ DataBrowserPropertyID property,
+ const Rect * theRect,
+ Point startPt,
+ EventModifiers modifiers,
+ DataBrowserTrackingUPP userUPP) ;
+extern void
+InvokeDataBrowserItemDragRgnUPP(
+ ControlRef browser,
+ DataBrowserItemID itemID,
+ DataBrowserPropertyID property,
+ const Rect * theRect,
+ RgnHandle dragRgn,
+ DataBrowserItemDragRgnUPP userUPP) ;
+extern DataBrowserDragFlags
+InvokeDataBrowserItemAcceptDragUPP(
+ ControlRef browser,
+ DataBrowserItemID itemID,
+ DataBrowserPropertyID property,
+ const Rect * theRect,
+ DragReference theDrag,
+ DataBrowserItemAcceptDragUPP userUPP) ;
+extern Boolean
+InvokeDataBrowserItemReceiveDragUPP(
+ ControlRef browser,
+ DataBrowserItemID itemID,
+ DataBrowserPropertyID property,
+ DataBrowserDragFlags dragFlags,
+ DragReference theDrag,
+ DataBrowserItemReceiveDragUPP userUPP) ;
+
+
+enum {
+ kDataBrowserLatestCustomCallbacks = 0
+};
+
+struct DataBrowserCustomCallbacks {
+
+ UInt32 version;
+
+ union {
+ struct {
+ DataBrowserDrawItemUPP drawItemCallback;
+ DataBrowserEditItemUPP editTextCallback;
+ DataBrowserHitTestUPP hitTestCallback;
+ DataBrowserTrackingUPP trackingCallback;
+
+ DataBrowserItemDragRgnUPP dragRegionCallback;
+ DataBrowserItemAcceptDragUPP acceptDragCallback;
+ DataBrowserItemReceiveDragUPP receiveDragCallback;
+ } v1;
+ } u;
+};
+typedef struct DataBrowserCustomCallbacks DataBrowserCustomCallbacks;
+extern OSStatus
+InitDataBrowserCustomCallbacks(DataBrowserCustomCallbacks * callbacks) ;
+extern OSStatus
+GetDataBrowserCustomCallbacks(
+ ControlRef browser,
+ DataBrowserCustomCallbacks * callbacks) ;
+extern OSStatus
+SetDataBrowserCustomCallbacks(
+ ControlRef browser,
+ const DataBrowserCustomCallbacks * callbacks) ;
+
+
+
+
+
+
+typedef UInt32 DataBrowserTableViewHiliteStyle;
+enum {
+ kDataBrowserTableViewMinimalHilite = 0,
+ kDataBrowserTableViewFillHilite = 1
+};
+
+typedef UInt32 DataBrowserTableViewPropertyFlags;
+enum {
+
+ kDataBrowserTableViewSelectionColumn = 1 << kDataBrowserViewSpecificFlagsOffset
+};
+
+
+
+typedef UInt32 DataBrowserTableViewRowIndex;
+typedef UInt32 DataBrowserTableViewColumnIndex;
+typedef DataBrowserPropertyID DataBrowserTableViewColumnID;
+typedef DataBrowserPropertyDesc DataBrowserTableViewColumnDesc;
+
+
+
+enum {
+ kDataBrowserTableViewLastColumn = -1
+};
+extern OSStatus
+RemoveDataBrowserTableViewColumn(
+ ControlRef browser,
+ DataBrowserTableViewColumnID column) ;
+extern OSStatus
+GetDataBrowserTableViewColumnCount(
+ ControlRef browser,
+ UInt32 * numColumns) ;
+extern OSStatus
+SetDataBrowserTableViewHiliteStyle(
+ ControlRef browser,
+ DataBrowserTableViewHiliteStyle hiliteStyle) ;
+extern OSStatus
+GetDataBrowserTableViewHiliteStyle(
+ ControlRef browser,
+ DataBrowserTableViewHiliteStyle * hiliteStyle) ;
+extern OSStatus
+SetDataBrowserTableViewRowHeight(
+ ControlRef browser,
+ UInt16 height) ;
+extern OSStatus
+GetDataBrowserTableViewRowHeight(
+ ControlRef browser,
+ UInt16 * height) ;
+extern OSStatus
+SetDataBrowserTableViewColumnWidth(
+ ControlRef browser,
+ UInt16 width) ;
+extern OSStatus
+GetDataBrowserTableViewColumnWidth(
+ ControlRef browser,
+ UInt16 * width) ;
+extern OSStatus
+SetDataBrowserTableViewItemRowHeight(
+ ControlRef browser,
+ DataBrowserItemID item,
+ UInt16 height) ;
+extern OSStatus
+GetDataBrowserTableViewItemRowHeight(
+ ControlRef browser,
+ DataBrowserItemID item,
+ UInt16 * height) ;
+extern OSStatus
+SetDataBrowserTableViewNamedColumnWidth(
+ ControlRef browser,
+ DataBrowserTableViewColumnID column,
+ UInt16 width) ;
+extern OSStatus
+GetDataBrowserTableViewNamedColumnWidth(
+ ControlRef browser,
+ DataBrowserTableViewColumnID column,
+ UInt16 * width) ;
+extern OSStatus
+SetDataBrowserTableViewGeometry(
+ ControlRef browser,
+ Boolean variableWidthColumns,
+ Boolean variableHeightRows) ;
+extern OSStatus
+GetDataBrowserTableViewGeometry(
+ ControlRef browser,
+ Boolean * variableWidthColumns,
+ Boolean * variableHeightRows) ;
+extern OSStatus
+GetDataBrowserTableViewItemID(
+ ControlRef browser,
+ DataBrowserTableViewRowIndex row,
+ DataBrowserItemID * item) ;
+extern OSStatus
+SetDataBrowserTableViewItemRow(
+ ControlRef browser,
+ DataBrowserItemID item,
+ DataBrowserTableViewRowIndex row) ;
+extern OSStatus
+GetDataBrowserTableViewItemRow(
+ ControlRef browser,
+ DataBrowserItemID item,
+ DataBrowserTableViewRowIndex * row) ;
+extern OSStatus
+SetDataBrowserTableViewColumnPosition(
+ ControlRef browser,
+ DataBrowserTableViewColumnID column,
+ DataBrowserTableViewColumnIndex position) ;
+extern OSStatus
+GetDataBrowserTableViewColumnPosition(
+ ControlRef browser,
+ DataBrowserTableViewColumnID column,
+ DataBrowserTableViewColumnIndex * position) ;
+extern OSStatus
+GetDataBrowserTableViewColumnProperty(
+ ControlRef browser,
+ DataBrowserTableViewColumnIndex column,
+ DataBrowserTableViewColumnID * property) ;
+
+
+
+
+
+
+typedef UInt32 DataBrowserListViewPropertyFlags;
+enum {
+
+ kDataBrowserListViewMovableColumn = 1 << (kDataBrowserViewSpecificFlagsOffset + 1),
+ kDataBrowserListViewSortableColumn = 1 << (kDataBrowserViewSpecificFlagsOffset + 2),
+ kDataBrowserListViewSelectionColumn = kDataBrowserTableViewSelectionColumn,
+ kDataBrowserListViewDefaultColumnFlags = kDataBrowserListViewMovableColumn + kDataBrowserListViewSortableColumn
+};
+
+
+enum {
+ kDataBrowserListViewLatestHeaderDesc = 0
+};
+
+struct DataBrowserListViewHeaderDesc {
+ UInt32 version;
+
+ UInt16 minimumWidth;
+ UInt16 maximumWidth;
+
+ SInt16 titleOffset;
+ CFStringRef titleString;
+ DataBrowserSortOrder initialOrder;
+ ControlFontStyleRec btnFontStyle;
+ ControlButtonContentInfo btnContentInfo;
+};
+typedef struct DataBrowserListViewHeaderDesc DataBrowserListViewHeaderDesc;
+struct DataBrowserListViewColumnDesc {
+ DataBrowserTableViewColumnDesc propertyDesc;
+ DataBrowserListViewHeaderDesc headerBtnDesc;
+};
+typedef struct DataBrowserListViewColumnDesc DataBrowserListViewColumnDesc;
+
+enum {
+ kDataBrowserListViewAppendColumn = kDataBrowserTableViewLastColumn
+};
+extern OSStatus
+AutoSizeDataBrowserListViewColumns(ControlRef browser) ;
+extern OSStatus
+AddDataBrowserListViewColumn(
+ ControlRef browser,
+ DataBrowserListViewColumnDesc * columnDesc,
+ DataBrowserTableViewColumnIndex position) ;
+extern OSStatus
+GetDataBrowserListViewHeaderDesc(
+ ControlRef browser,
+ DataBrowserTableViewColumnID column,
+ DataBrowserListViewHeaderDesc * desc) ;
+extern OSStatus
+SetDataBrowserListViewHeaderDesc(
+ ControlRef browser,
+ DataBrowserTableViewColumnID column,
+ DataBrowserListViewHeaderDesc * desc) ;
+extern OSStatus
+SetDataBrowserListViewHeaderBtnHeight(
+ ControlRef browser,
+ UInt16 height) ;
+extern OSStatus
+GetDataBrowserListViewHeaderBtnHeight(
+ ControlRef browser,
+ UInt16 * height) ;
+extern OSStatus
+SetDataBrowserListViewUsePlainBackground(
+ ControlRef browser,
+ Boolean usePlainBackground) ;
+extern OSStatus
+GetDataBrowserListViewUsePlainBackground(
+ ControlRef browser,
+ Boolean * usePlainBackground) ;
+extern OSStatus
+SetDataBrowserListViewDisclosureColumn(
+ ControlRef browser,
+ DataBrowserTableViewColumnID column,
+ Boolean expandableRows) ;
+extern OSStatus
+GetDataBrowserListViewDisclosureColumn(
+ ControlRef browser,
+ DataBrowserTableViewColumnID * column,
+ Boolean * expandableRows) ;
+extern OSStatus
+GetDataBrowserColumnViewPath(
+ ControlRef browser,
+ Handle path) ;
+extern OSStatus
+GetDataBrowserColumnViewPathLength(
+ ControlRef browser,
+ UInt32 * pathLength) ;
+extern OSStatus
+SetDataBrowserColumnViewPath(
+ ControlRef browser,
+ UInt32 length,
+ const DataBrowserItemID * path) ;
+extern OSStatus
+SetDataBrowserColumnViewDisplayType(
+ ControlRef browser,
+ DataBrowserPropertyType propertyType) ;
+extern OSStatus
+GetDataBrowserColumnViewDisplayType(
+ ControlRef browser,
+ DataBrowserPropertyType * propertyType) ;
+typedef Boolean ( * EditUnicodePostUpdateProcPtr)(UniCharArrayHandle uniText, UniCharCount uniTextLength, UniCharArrayOffset iStartOffset, UniCharArrayOffset iEndOffset, void *refcon);
+typedef EditUnicodePostUpdateProcPtr EditUnicodePostUpdateUPP;
+extern EditUnicodePostUpdateUPP
+NewEditUnicodePostUpdateUPP(EditUnicodePostUpdateProcPtr userRoutine) ;
+extern void
+DisposeEditUnicodePostUpdateUPP(EditUnicodePostUpdateUPP userUPP) ;
+extern Boolean
+InvokeEditUnicodePostUpdateUPP(
+ UniCharArrayHandle uniText,
+ UniCharCount uniTextLength,
+ UniCharArrayOffset iStartOffset,
+ UniCharArrayOffset iEndOffset,
+ void * refcon,
+ EditUnicodePostUpdateUPP userUPP) ;
+
+
+
+enum {
+ kControlEditUnicodeTextPostUpdateProcTag = 'upup'
+};
+
+
+enum {
+ kControlEditUnicodeTextProc = 912,
+ kControlEditUnicodeTextPasswordProc = 914
+};
+
+
+enum {
+ kControlKindEditUnicodeText = 'eutx'
+};
+extern OSStatus
+CreateEditUnicodeTextControl(
+ WindowRef window,
+ const Rect * boundsRect,
+ CFStringRef text,
+ Boolean isPassword,
+ const ControlFontStyleRec * style,
+ ControlRef * outControl) ;
+
+
+
+enum {
+ kControlEditTextSingleLineTag = 'sglc'
+};
+
+
+}
+
+
+
+extern "C" {
+
+
+
+
+enum {
+ kTSMTESignature = 'tmTE',
+ kTSMTEInterfaceType = 'tmTE'
+};
+enum {
+ kTSMTEAutoScroll = 1
+};
+
+
+
+
+typedef void ( * TSMTEPreUpdateProcPtr)(TEHandle textH, long refCon);
+typedef void ( * TSMTEPostUpdateProcPtr)(TEHandle textH, long fixLen, long inputAreaStart, long inputAreaEnd, long pinStart, long pinEnd, long refCon);
+typedef TSMTEPreUpdateProcPtr TSMTEPreUpdateUPP;
+typedef TSMTEPostUpdateProcPtr TSMTEPostUpdateUPP;
+
+
+
+struct TSMTERec {
+ TEHandle textH;
+ TSMTEPreUpdateUPP preUpdateProc;
+ TSMTEPostUpdateUPP postUpdateProc;
+ long updateFlag;
+ long refCon;
+};
+typedef struct TSMTERec TSMTERec;
+typedef TSMTERec * TSMTERecPtr;
+typedef TSMTERecPtr * TSMTERecHandle;
+extern TSMTEPreUpdateUPP
+NewTSMTEPreUpdateUPP(TSMTEPreUpdateProcPtr userRoutine) ;
+extern TSMTEPostUpdateUPP
+NewTSMTEPostUpdateUPP(TSMTEPostUpdateProcPtr userRoutine) ;
+extern void
+DisposeTSMTEPreUpdateUPP(TSMTEPreUpdateUPP userUPP) ;
+extern void
+DisposeTSMTEPostUpdateUPP(TSMTEPostUpdateUPP userUPP) ;
+extern void
+InvokeTSMTEPreUpdateUPP(
+ TEHandle textH,
+ long refCon,
+ TSMTEPreUpdateUPP userUPP) ;
+extern void
+InvokeTSMTEPostUpdateUPP(
+ TEHandle textH,
+ long fixLen,
+ long inputAreaStart,
+ long inputAreaEnd,
+ long pinStart,
+ long pinEnd,
+ long refCon,
+ TSMTEPostUpdateUPP userUPP) ;
+extern Boolean
+IsTSMTEDialog(DialogRef dialog) ;
+extern TSMDocumentID
+GetTSMTEDialogDocumentID(DialogRef dialog) ;
+extern TSMTERecHandle
+GetTSMTEDialogTSMTERecHandle(DialogRef dialog) ;
+extern void
+SetTSMTEDialogDocumentID(
+ DialogRef dialog,
+ TSMDocumentID documentID) ;
+extern void
+SetTSMTEDialogTSMTERecHandle(
+ DialogRef dialog,
+ TSMTERecHandle tsmteRecHandle) ;
+
+
+
+
+
+}
+
+
+
+extern "C" {
+
+
+
+enum {
+ kSupportsFileTranslation = 1,
+ kSupportsScrapTranslation = 2,
+ kTranslatorCanGenerateFilename = 4
+};
+
+
+
+typedef OSType FileType;
+typedef ResType ScrapType;
+
+typedef UInt32 TranslationAttributes;
+enum {
+ taDstDocNeedsResourceFork = 1,
+ taDstIsAppTranslation = 2
+};
+
+
+struct FileTypeSpec {
+ FileType format;
+ long hint;
+ TranslationAttributes flags;
+ OSType catInfoType;
+ OSType catInfoCreator;
+};
+typedef struct FileTypeSpec FileTypeSpec;
+struct FileTranslationList {
+ unsigned long modDate;
+ unsigned long groupCount;
+};
+typedef struct FileTranslationList FileTranslationList;
+typedef FileTranslationList * FileTranslationListPtr;
+typedef FileTranslationListPtr * FileTranslationListHandle;
+
+struct ScrapTypeSpec {
+ ScrapType format;
+ long hint;
+};
+typedef struct ScrapTypeSpec ScrapTypeSpec;
+struct ScrapTranslationList {
+ unsigned long modDate;
+ unsigned long groupCount;
+};
+typedef struct ScrapTranslationList ScrapTranslationList;
+typedef ScrapTranslationList * ScrapTranslationListPtr;
+typedef ScrapTranslationListPtr * ScrapTranslationListHandle;
+
+
+
+
+
+typedef long TranslationRefNum;
+extern OSErr
+SetTranslationAdvertisement(
+ TranslationRefNum refNum,
+ PicHandle advertisement) ;
+extern OSErr
+UpdateTranslationProgress(
+ TranslationRefNum refNum,
+ short percentDone,
+ Boolean * canceled) ;
+
+
+
+
+
+
+
+enum {
+ kTranslateGetFileTranslationList = 0,
+ kTranslateIdentifyFile = 1,
+ kTranslateTranslateFile = 2,
+ kTranslateGetTranslatedFilename = 3,
+ kTranslateGetScrapTranslationList = 10,
+ kTranslateIdentifyScrap = 11,
+ kTranslateTranslateScrap = 12,
+ kTranslateGetScrapTranslationListConsideringData = 13
+};
+
+
+
+
+
+
+
+typedef ComponentResult ( * DoGetFileTranslationListProcPtr)(ComponentInstance self, FileTranslationListHandle translationList);
+typedef ComponentResult ( * DoIdentifyFileProcPtr)(ComponentInstance self, const FSSpec *theDocument, FileType *docType);
+typedef ComponentResult ( * DoTranslateFileProcPtr)(ComponentInstance self, TranslationRefNum refNum, const FSSpec *sourceDocument, FileType srcType, long srcTypeHint, const FSSpec *dstDoc, FileType dstType, long dstTypeHint);
+typedef ComponentResult ( * DoGetTranslatedFilenameProcPtr)(ComponentInstance self, FileType dstType, long dstTypeHint, FSSpec *theDocument);
+typedef ComponentResult ( * DoGetScrapTranslationListProcPtr)(ComponentInstance self, ScrapTranslationListHandle list);
+typedef ComponentResult ( * DoIdentifyScrapProcPtr)(ComponentInstance self, const void *dataPtr, Size dataLength, ScrapType *dataFormat);
+typedef ComponentResult ( * DoTranslateScrapProcPtr)(ComponentInstance self, TranslationRefNum refNum, const void *srcDataPtr, Size srcDataLength, ScrapType srcType, long srcTypeHint, Handle dstData, ScrapType dstType, long dstTypeHint);
+
+
+
+}
+
+
+
+extern "C" {
+
+
+
+
+typedef short DocOpenMethod;
+enum {
+ domCannot = 0,
+ domNative = 1,
+ domTranslateFirst = 2,
+ domWildcard = 3
+};
+
+
+typedef OSType TypesBlock[64];
+typedef OSType * TypesBlockPtr;
+
+enum {
+ kTranslationScrapProgressDialogID = -16555
+};
+
+
+struct FileTranslationSpec {
+ OSType componentSignature;
+ const void * translationSystemInfo;
+ FileTypeSpec src;
+ FileTypeSpec dst;
+};
+typedef struct FileTranslationSpec FileTranslationSpec;
+typedef FileTranslationSpec * FileTranslationSpecArrayPtr;
+typedef FileTranslationSpecArrayPtr * FileTranslationSpecArrayHandle;
+extern OSErr
+GetFileTypesThatAppCanNativelyOpen(
+ short appVRefNumHint,
+ OSType appSignature,
+ FileType * nativeTypes) ;
+extern OSErr
+ExtendFileTypeList(
+ const FileType * originalTypeList,
+ short numberOriginalTypes,
+ FileType * extendedTypeList,
+ short * numberExtendedTypes) ;
+extern OSErr
+CanDocBeOpened(
+ const FSSpec * targetDocument,
+ short appVRefNumHint,
+ OSType appSignature,
+ const FileType * nativeTypes,
+ Boolean onlyNative,
+ DocOpenMethod * howToOpen,
+ FileTranslationSpec * howToTranslate) ;
+extern short
+GetFileTranslationPaths(
+ const FSSpec * srcDocument,
+ FileType dstDocType,
+ unsigned short maxResultCount,
+ FileTranslationSpecArrayPtr resultBuffer) ;
+extern OSErr
+GetPathFromTranslationDialog(
+ const FSSpec * theDocument,
+ const FSSpec * theApplication,
+ TypesBlockPtr typeList,
+ DocOpenMethod * howToOpen,
+ FileTranslationSpec * howToTranslate) ;
+extern OSErr
+TranslateFile(
+ const FSSpec * sourceDocument,
+ const FSSpec * destinationDocument,
+ const FileTranslationSpec * howToTranslate) ;
+extern OSErr
+GetDocumentKindString(
+ short docVRefNum,
+ OSType docType,
+ OSType docCreator,
+ Str63 kindString) ;
+extern OSErr
+GetTranslationExtensionName(
+ const FileTranslationSpec * translationMethod,
+ Str31 extensionName) ;
+typedef OSErr ( * GetScrapDataProcPtr)(ScrapType requestedFormat, Handle dataH, void *srcDataGetterRefCon);
+typedef GetScrapDataProcPtr GetScrapDataUPP;
+extern GetScrapDataUPP
+NewGetScrapDataUPP(GetScrapDataProcPtr userRoutine) ;
+extern void
+DisposeGetScrapDataUPP(GetScrapDataUPP userUPP) ;
+extern OSErr
+InvokeGetScrapDataUPP(
+ ScrapType requestedFormat,
+ Handle dataH,
+ void * srcDataGetterRefCon,
+ GetScrapDataUPP userUPP) ;
+
+typedef GetScrapDataUPP GetScrapData;
+extern OSErr
+TranslateScrap(
+ GetScrapDataUPP sourceDataGetter,
+ void * sourceDataGetterRefCon,
+ ScrapType destinationFormat,
+ Handle destinationData,
+ short progressDialogID) ;
+
+
+
+
+
+
+
+}
+
+
+
+
+
+
+
+extern "C" {
+
+
+
+typedef SInt16 TSCode;
+enum {
+ tsPreviousSelectMode = -1,
+ tsNormalSelectMode = 0,
+ tsNextSelectMode = 1
+};
+
+struct TypeSelectRecord {
+ unsigned long tsrLastKeyTime;
+ ScriptCode tsrScript;
+ Str63 tsrKeyStrokes;
+};
+typedef struct TypeSelectRecord TypeSelectRecord;
+typedef Boolean ( * IndexToStringProcPtr)(short item, ScriptCode *itemsScript, StringPtr *itemsStringPtr, void *yourDataPtr);
+typedef IndexToStringProcPtr IndexToStringUPP;
+extern void
+TypeSelectClear(TypeSelectRecord * tsr) ;
+extern Boolean
+TypeSelectNewKey(
+ const EventRecord * theEvent,
+ TypeSelectRecord * tsr) ;
+extern short
+TypeSelectFindItem(
+ const TypeSelectRecord * tsr,
+ short listSize,
+ TSCode selectMode,
+ IndexToStringUPP getStringProc,
+ void * yourDataPtr) ;
+extern short
+TypeSelectCompare(
+ const TypeSelectRecord * tsr,
+ ScriptCode testStringScript,
+ StringPtr testStringPtr) ;
+extern IndexToStringUPP
+NewIndexToStringUPP(IndexToStringProcPtr userRoutine) ;
+extern void
+DisposeIndexToStringUPP(IndexToStringUPP userUPP) ;
+extern Boolean
+InvokeIndexToStringUPP(
+ short item,
+ ScriptCode * itemsScript,
+ StringPtr * itemsStringPtr,
+ void * yourDataPtr,
+ IndexToStringUPP userUPP) ;
+
+
+
+
+
+
+
+}
+
+
+
+extern "C" {
+enum {
+
+
+
+
+ kUIModeNormal = 0,
+ kUIModeContentSuppressed = 1,
+
+
+
+
+
+
+
+ kUIModeContentHidden = 2,
+ kUIModeAllHidden = 3
+};
+
+typedef UInt32 SystemUIMode;
+
+
+
+
+
+
+enum {
+
+
+
+
+
+
+ kUIOptionAutoShowMenuBar = 1 << 0,
+
+
+
+
+ kUIOptionDisableAppleMenu = 1 << 2,
+ kUIOptionDisableProcessSwitch = 1 << 3,
+
+
+
+
+
+
+
+ kUIOptionDisableForceQuit = 1 << 4,
+
+
+
+
+
+
+
+ kUIOptionDisableSessionTerminate = 1 << 5
+};
+
+typedef OptionBits SystemUIOptions;
+extern OSStatus
+SetSystemUIMode(
+ SystemUIMode inMode,
+ SystemUIOptions inOptions) ;
+extern void
+GetSystemUIMode(
+ SystemUIMode * outMode,
+ SystemUIOptions * outOptions) ;
+extern HIObjectRef
+HIApplicationGetCurrent(void) ;
+extern OSStatus
+SetApplicationDockTileImage(CGImageRef inImage) ;
+extern OSStatus
+OverlayApplicationDockTileImage(CGImageRef inImage) ;
+extern OSStatus
+RestoreApplicationDockTileImage(void) ;
+extern CGContextRef
+BeginCGContextForApplicationDockTile(void) ;
+extern void
+EndCGContextForApplicationDockTile(CGContextRef inContext) ;
+extern CGrafPtr
+BeginQDContextForApplicationDockTile(void) ;
+extern void
+EndQDContextForApplicationDockTile(CGrafPtr inContext) ;
+extern OSStatus
+SetApplicationDockTileMenu(MenuRef inMenu) ;
+extern MenuRef
+GetApplicationDockTileMenu(void) ;
+extern OSStatus
+CreateCGImageFromPixMaps(
+ PixMapHandle inImage,
+ PixMapHandle inMask,
+ CGImageRef * outImage) ;
+extern TextEncoding
+GetApplicationTextEncoding(void) ;
+extern ScriptCode
+GetApplicationScript(void) ;
+
+
+
+
+
+}
+
+
+
+extern "C" {
+
+
+
+
+
+
+enum {
+ _KeyboardDispatch = 0xAA7A
+};
+
+
+enum {
+ gestaltKeyboardsAttr = 'kbds',
+ gestaltKBPS2Keyboards = 1,
+ gestaltKBPS2SetIDToAny = 2,
+ gestaltKBPS2SetTranslationTable = 4
+};
+
+
+
+
+
+
+enum {
+ errKBPS2KeyboardNotAvailable = -30850,
+ errKBIlligalParameters = -30851,
+ errKBFailSettingID = -30852,
+ errKBFailSettingTranslationTable = -30853,
+ errKBFailWritePreference = -30854
+};
+typedef UInt32 PhysicalKeyboardLayoutType;
+enum {
+
+
+
+
+ kKeyboardJIS = 'JIS ',
+
+
+
+
+ kKeyboardANSI = 'ANSI',
+
+
+
+
+ kKeyboardISO = 'ISO ',
+
+
+
+
+ kKeyboardUnknown = kUnknownType
+};
+extern OSType
+KBGetLayoutType(SInt16 iKeyboardType) ;
+typedef struct OpaqueKeyboardLayoutRef* KeyboardLayoutRef;
+typedef UInt32 KeyboardLayoutPropertyTag;
+enum {
+
+
+
+
+
+ kKLKCHRData = 0,
+
+
+
+
+
+ kKLuchrData = 1,
+
+
+
+
+ kKLIdentifier = 2,
+
+
+
+
+ kKLIcon = 3,
+
+
+
+
+ kKLLocalizedName = 4,
+
+
+
+
+ kKLName = 5,
+
+
+
+
+ kKLGroupIdentifier = 6,
+
+
+
+
+ kKLKind = 7
+};
+typedef SInt32 KeyboardLayoutKind;
+enum {
+
+
+
+
+ kKLKCHRuchrKind = 0,
+
+
+
+
+ kKLKCHRKind = 1,
+
+
+
+
+ kKLuchrKind = 2
+};
+typedef SInt32 KeyboardLayoutIdentifier;
+enum {
+ kKLUSKeyboard = 0
+};
+extern OSStatus
+KLGetKeyboardLayoutCount(CFIndex * oCount) ;
+extern OSStatus
+KLGetKeyboardLayoutAtIndex(
+ CFIndex iIndex,
+ KeyboardLayoutRef * oKeyboardLayout) ;
+extern OSStatus
+KLGetIndexedKeyboardLayout(
+ CFIndex iIndex,
+ KeyboardLayoutRef * oKeyboardLayout) ;
+extern OSStatus
+KLGetKeyboardLayoutProperty(
+ KeyboardLayoutRef iKeyboardLayout,
+ KeyboardLayoutPropertyTag iPropertyTag,
+ const void ** oValue) ;
+extern OSStatus
+KLGetKeyboardLayoutWithIdentifier(
+ SInt32 iIdentifier,
+ KeyboardLayoutRef * oKeyboardLayout) ;
+extern OSStatus
+KLGetKeyboardLayoutWithName(
+ CFStringRef iName,
+ KeyboardLayoutRef * oKeyboardLayout) ;
+extern OSStatus
+KLGetCurrentKeyboardLayout(KeyboardLayoutRef * oKeyboardLayout) ;
+extern OSStatus
+KLSetCurrentKeyboardLayout(KeyboardLayoutRef iKeyboardLayout) ;
+
+
+
+
+}
+
+
+
+extern "C" {
+
+
+enum {
+ kIBCarbonRuntimeCantFindNibFile = -10960,
+ kIBCarbonRuntimeObjectNotOfRequestedType = -10961,
+ kIBCarbonRuntimeCantFindObject = -10962
+};
+
+
+typedef struct OpaqueIBNibRef* IBNibRef;
+extern OSStatus
+CreateNibReference(
+ CFStringRef inNibName,
+ IBNibRef * outNibRef) ;
+extern OSStatus
+CreateNibReferenceWithCFBundle(
+ CFBundleRef inBundle,
+ CFStringRef inNibName,
+ IBNibRef * outNibRef) ;
+extern void
+DisposeNibReference(IBNibRef inNibRef) ;
+extern OSStatus
+CreateWindowFromNib(
+ IBNibRef inNibRef,
+ CFStringRef inName,
+ WindowRef * outWindow) ;
+extern OSStatus
+CreateMenuFromNib(
+ IBNibRef inNibRef,
+ CFStringRef inName,
+ MenuRef * outMenuRef) ;
+extern OSStatus
+CreateMenuBarFromNib(
+ IBNibRef inNibRef,
+ CFStringRef inName,
+ Handle * outMenuBar) ;
+extern OSStatus
+SetMenuBarFromNib(
+ IBNibRef inNibRef,
+ CFStringRef inName) ;
+
+
+
+
+}
+
+
+
+extern "C" {
+
+
+enum {
+ soundListRsrc = 'snd ',
+ kSoundCodecInfoResourceType = 'snfo'
+};
+
+enum {
+ kSimpleBeepID = 1
+};
+
+enum {
+ rate48khz = (long)0xBB800000,
+ rate44khz = (long)0xAC440000,
+ rate32khz = 0x7D000000,
+ rate22050hz = 0x56220000,
+ rate22khz = 0x56EE8BA3,
+ rate16khz = 0x3E800000,
+ rate11khz = 0x2B7745D1,
+ rate11025hz = 0x2B110000,
+ rate8khz = 0x1F400000
+};
+
+
+enum {
+ sampledSynth = 5
+};
+enum {
+ kMiddleC = 60
+};
+
+enum {
+ kNoVolume = 0,
+ kFullVolume = 0x0100
+};
+
+enum {
+ stdQLength = 128
+};
+
+enum {
+ dataOffsetFlag = 0x8000
+};
+
+enum {
+ kUseOptionalOutputDevice = -1
+};
+
+enum {
+ notCompressed = 0,
+ fixedCompression = -1,
+ variableCompression = -2
+};
+
+enum {
+ twoToOne = 1,
+ eightToThree = 2,
+ threeToOne = 3,
+ sixToOne = 4,
+ sixToOnePacketSize = 8,
+ threeToOnePacketSize = 16
+};
+
+enum {
+ stateBlockSize = 64,
+ leftOverBlockSize = 32
+};
+
+enum {
+ firstSoundFormat = 0x0001,
+ secondSoundFormat = 0x0002
+};
+enum {
+ sysBeepDisable = 0x0000,
+ sysBeepEnable = (1 << 0),
+ sysBeepSynchronous = (1 << 1)
+};
+
+enum {
+ unitTypeNoSelection = 0xFFFF,
+ unitTypeSeconds = 0x0000
+};
+
+enum {
+ stdSH = 0x00,
+ extSH = 0xFF,
+ cmpSH = 0xFE
+};
+
+
+enum {
+ nullCmd = 0,
+ quietCmd = 3,
+ flushCmd = 4,
+ reInitCmd = 5,
+ waitCmd = 10,
+ pauseCmd = 11,
+ resumeCmd = 12,
+ callBackCmd = 13,
+ syncCmd = 14,
+ availableCmd = 24,
+ versionCmd = 25,
+ volumeCmd = 46,
+ getVolumeCmd = 47,
+ clockComponentCmd = 50,
+ getClockComponentCmd = 51,
+ scheduledSoundCmd = 52,
+ linkSoundComponentsCmd = 53,
+ soundCmd = 80,
+ bufferCmd = 81,
+ rateMultiplierCmd = 86,
+ getRateMultiplierCmd = 87
+};
+enum {
+ initChanLeft = 0x0002,
+ initChanRight = 0x0003,
+ initNoInterp = 0x0004,
+ initNoDrop = 0x0008,
+ initMono = 0x0080,
+ initStereo = 0x00C0,
+ initMACE3 = 0x0300,
+ initMACE6 = 0x0400,
+ initPanMask = 0x0003,
+ initSRateMask = 0x0030,
+ initStereoMask = 0x00C0,
+ initCompMask = 0xFF00
+};
+
+
+enum {
+ siActiveChannels = 'chac',
+ siActiveLevels = 'lmac',
+ siAGCOnOff = 'agc ',
+ siAsync = 'asyn',
+ siAVDisplayBehavior = 'avdb',
+ siChannelAvailable = 'chav',
+ siCompressionAvailable = 'cmav',
+ siCompressionFactor = 'cmfa',
+ siCompressionHeader = 'cmhd',
+ siCompressionNames = 'cnam',
+ siCompressionParams = 'evaw',
+ siCompressionSampleRate = 'cprt',
+ siCompressionChannels = 'cpct',
+ siCompressionOutputSampleRate = 'cort',
+ siCompressionInputRateList = 'crtl',
+ siCompressionType = 'comp',
+ siCompressionConfiguration = 'ccfg',
+ siContinuous = 'cont',
+ siDecompressionParams = 'wave',
+ siDecompressionConfiguration = 'dcfg',
+ siDeviceBufferInfo = 'dbin',
+ siDeviceConnected = 'dcon',
+ siDeviceIcon = 'icon',
+ siDeviceName = 'name',
+ siEQSpectrumBands = 'eqsb',
+ siEQSpectrumLevels = 'eqlv',
+ siEQSpectrumOnOff = 'eqlo',
+ siEQSpectrumResolution = 'eqrs',
+ siEQToneControlGain = 'eqtg',
+ siEQToneControlOnOff = 'eqtc',
+ siHardwareBalance = 'hbal',
+ siHardwareBalanceSteps = 'hbls',
+ siHardwareBass = 'hbas',
+ siHardwareBassSteps = 'hbst',
+ siHardwareBusy = 'hwbs',
+ siHardwareFormat = 'hwfm',
+ siHardwareMute = 'hmut',
+ siHardwareMuteNoPrefs = 'hmnp',
+ siHardwareTreble = 'htrb',
+ siHardwareTrebleSteps = 'hwts',
+ siHardwareVolume = 'hvol',
+ siHardwareVolumeSteps = 'hstp',
+ siHeadphoneMute = 'pmut',
+ siHeadphoneVolume = 'pvol',
+ siHeadphoneVolumeSteps = 'hdst',
+ siInputAvailable = 'inav',
+ siInputGain = 'gain',
+ siInputSource = 'sour',
+ siInputSourceNames = 'snam',
+ siLevelMeterOnOff = 'lmet',
+ siModemGain = 'mgai',
+ siMonitorAvailable = 'mnav',
+ siMonitorSource = 'mons',
+ siNumberChannels = 'chan',
+ siOptionsDialog = 'optd',
+ siOSTypeInputSource = 'inpt',
+ siOSTypeInputAvailable = 'inav',
+ siOutputDeviceName = 'onam',
+ siPlayThruOnOff = 'plth',
+ siPostMixerSoundComponent = 'psmx',
+ siPreMixerSoundComponent = 'prmx',
+ siQuality = 'qual',
+ siRateMultiplier = 'rmul',
+ siRecordingQuality = 'qual',
+ siSampleRate = 'srat',
+ siSampleRateAvailable = 'srav',
+ siSampleSize = 'ssiz',
+ siSampleSizeAvailable = 'ssav',
+ siSetupCDAudio = 'sucd',
+ siSetupModemAudio = 'sumd',
+ siSlopeAndIntercept = 'flap',
+ siSoundClock = 'sclk',
+ siUseThisSoundClock = 'sclc',
+ siSpeakerMute = 'smut',
+ siSpeakerVolume = 'svol',
+ siSSpCPULoadLimit = '3dll',
+ siSSpLocalization = '3dif',
+ siSSpSpeakerSetup = '3dst',
+ siStereoInputGain = 'sgai',
+ siSubwooferMute = 'bmut',
+ siTerminalType = 'ttyp',
+ siTwosComplementOnOff = 'twos',
+ siVendorProduct = 'vpro',
+ siVolume = 'volu',
+ siVoxRecordInfo = 'voxr',
+ siVoxStopInfo = 'voxs',
+ siWideStereo = 'wide',
+ siSupportedExtendedFlags = 'exfl',
+ siRateConverterRollOffSlope = 'rcdb',
+ siOutputLatency = 'olte',
+ siHALAudioDeviceID = 'hlid',
+ siHALAudioDeviceUniqueID = 'huid',
+ siClientAcceptsVBR = 'cvbr',
+ siSourceIsExhausted = 'srcx',
+ siMediaContextID = 'uuid',
+ siCompressionMaxPacketSize = 'cmxp'
+};
+
+enum {
+ siCloseDriver = 'clos',
+ siInitializeDriver = 'init',
+ siPauseRecording = 'paus',
+ siUserInterruptProc = 'user'
+};
+
+
+enum {
+ kInvalidSource = (long)0xFFFFFFFF,
+ kNoSource = 'none',
+ kCDSource = 'cd ',
+ kExtMicSource = 'emic',
+ kSoundInSource = 'sinj',
+ kRCAInSource = 'irca',
+ kTVFMTunerSource = 'tvfm',
+ kDAVInSource = 'idav',
+ kIntMicSource = 'imic',
+ kMediaBaySource = 'mbay',
+ kModemSource = 'modm',
+ kPCCardSource = 'pcm ',
+ kZoomVideoSource = 'zvpc',
+ kDVDSource = 'dvda',
+ kMicrophoneArray = 'mica'
+};
+
+
+enum {
+ kNoSoundComponentType = '****',
+ kSoundComponentType = 'sift',
+ kSoundComponentPPCType = 'nift',
+ kRate8SubType = 'ratb',
+ kRate16SubType = 'ratw',
+ kConverterSubType = 'conv',
+ kSndSourceSubType = 'sour',
+ kMixerType = 'mixr',
+ kMixer8SubType = 'mixb',
+ kMixer16SubType = 'mixw',
+ kSoundInputDeviceType = 'sinp',
+ kWaveInSubType = 'wavi',
+ kWaveInSnifferSubType = 'wisn',
+ kSoundOutputDeviceType = 'sdev',
+ kClassicSubType = 'clas',
+ kASCSubType = 'asc ',
+ kDSPSubType = 'dsp ',
+ kAwacsSubType = 'awac',
+ kGCAwacsSubType = 'awgc',
+ kSingerSubType = 'sing',
+ kSinger2SubType = 'sng2',
+ kWhitSubType = 'whit',
+ kSoundBlasterSubType = 'sbls',
+ kWaveOutSubType = 'wavo',
+ kWaveOutSnifferSubType = 'wosn',
+ kDirectSoundSubType = 'dsnd',
+ kDirectSoundSnifferSubType = 'dssn',
+ kUNIXsdevSubType = 'un1x',
+ kUSBSubType = 'usb ',
+ kBlueBoxSubType = 'bsnd',
+ kHALCustomComponentSubType = 'halx',
+ kSoundCompressor = 'scom',
+ kSoundDecompressor = 'sdec',
+ kAudioComponentType = 'adio',
+ kAwacsPhoneSubType = 'hphn',
+ kAudioVisionSpeakerSubType = 'telc',
+ kAudioVisionHeadphoneSubType = 'telh',
+ kPhilipsFaderSubType = 'tvav',
+ kSGSToneSubType = 'sgs0',
+ kSoundEffectsType = 'snfx',
+ kEqualizerSubType = 'eqal',
+ kSSpLocalizationSubType = 'snd3'
+};
+
+
+enum {
+ kSoundNotCompressed = 'NONE',
+ k8BitOffsetBinaryFormat = 'raw ',
+ k16BitBigEndianFormat = 'twos',
+ k16BitLittleEndianFormat = 'sowt',
+ kFloat32Format = 'fl32',
+ kFloat64Format = 'fl64',
+ k24BitFormat = 'in24',
+ k32BitFormat = 'in32',
+ k32BitLittleEndianFormat = '23ni',
+ kMACE3Compression = 'MAC3',
+ kMACE6Compression = 'MAC6',
+ kCDXA4Compression = 'cdx4',
+ kCDXA2Compression = 'cdx2',
+ kIMACompression = 'ima4',
+ kULawCompression = 'ulaw',
+ kALawCompression = 'alaw',
+ kMicrosoftADPCMFormat = 0x6D730002,
+ kDVIIntelIMAFormat = 0x6D730011,
+ kDVAudioFormat = 'dvca',
+ kQDesignCompression = 'QDMC',
+ kQDesign2Compression = 'QDM2',
+ kQUALCOMMCompression = 'Qclp',
+ kOffsetBinary = k8BitOffsetBinaryFormat,
+ kTwosComplement = k16BitBigEndianFormat,
+ kLittleEndianFormat = k16BitLittleEndianFormat,
+ kMPEGLayer3Format = 0x6D730055,
+ kFullMPEGLay3Format = '.mp3'
+};
+enum {
+ k16BitNativeEndianFormat = k16BitBigEndianFormat,
+ k16BitNonNativeEndianFormat = k16BitLittleEndianFormat
+};
+
+
+
+
+enum {
+ k8BitRawIn = (1 << 0),
+ k8BitTwosIn = (1 << 1),
+ k16BitIn = (1 << 2),
+ kStereoIn = (1 << 3),
+ k8BitRawOut = (1 << 8),
+ k8BitTwosOut = (1 << 9),
+ k16BitOut = (1 << 10),
+ kStereoOut = (1 << 11),
+ kReverse = (1L << 16),
+ kRateConvert = (1L << 17),
+ kCreateSoundSource = (1L << 18),
+ kVMAwareness = (1L << 21),
+ kHighQuality = (1L << 22),
+ kNonRealTime = (1L << 23)
+};
+
+
+enum {
+ kSoundCodecInfoFixedCompression = (1L << 0),
+ kSoundCodecInfoVariableCompression = (1L << 1),
+ kSoundCodecInfoHasRestrictedInputRates = (1L << 2),
+ kSoundCodecInfoCanChangeOutputRate = (1L << 3),
+ kSoundCodecInfoRequiresExternalFraming = (1L << 4)
+};
+
+
+enum {
+ kSourcePaused = (1 << 0),
+ kPassThrough = (1L << 16),
+ kNoSoundComponentChain = (1L << 17)
+};
+
+
+enum {
+ kNoMixing = (1 << 0),
+ kNoSampleRateConversion = (1 << 1),
+ kNoSampleSizeConversion = (1 << 2),
+ kNoSampleFormatConversion = (1 << 3),
+ kNoChannelConversion = (1 << 4),
+ kNoDecompression = (1 << 5),
+ kNoVolumeConversion = (1 << 6),
+ kNoRealtimeProcessing = (1 << 7),
+ kScheduledSource = (1 << 8),
+ kNonInterleavedBuffer = (1 << 9),
+ kNonPagingMixer = (1 << 10),
+ kSoundConverterMixer = (1 << 11),
+ kPagingMixer = (1 << 12),
+ kVMAwareMixer = (1 << 13),
+ kExtendedSoundData = (1 << 14)
+};
+
+
+enum {
+ kBestQuality = (1 << 0)
+};
+
+
+enum {
+ kInputMask = 0x000000FF,
+ kOutputMask = 0x0000FF00,
+ kOutputShift = 8,
+ kActionMask = 0x00FF0000,
+ kSoundComponentBits = 0x00FFFFFF
+};
+
+
+enum {
+ kAudioFormatAtomType = 'frma',
+ kAudioEndianAtomType = 'enda',
+ kAudioVBRAtomType = 'vbra',
+ kAudioTerminatorAtomType = 0
+};
+
+
+enum {
+ kAVDisplayHeadphoneRemove = 0,
+ kAVDisplayHeadphoneInsert = 1,
+ kAVDisplayPlainTalkRemove = 2,
+ kAVDisplayPlainTalkInsert = 3
+};
+
+
+enum {
+
+ audioAllChannels = 0,
+ audioLeftChannel = 1,
+ audioRightChannel = 2,
+
+ audioUnmuted = 0,
+ audioMuted = 1,
+
+ audioDoesMono = (1L << 0),
+ audioDoesStereo = (1L << 1),
+ audioDoesIndependentChannels = (1L << 2)
+};
+
+
+enum {
+ siCDQuality = 'cd ',
+ siBestQuality = 'best',
+ siBetterQuality = 'betr',
+ siGoodQuality = 'good',
+ siNoneQuality = 'none'
+};
+
+enum {
+ siDeviceIsConnected = 1,
+ siDeviceNotConnected = 0,
+ siDontKnowIfConnected = -1,
+ siReadPermission = 0,
+ siWritePermission = 1
+};
+
+
+enum {
+ kSoundConverterDidntFillBuffer = (1 << 0),
+ kSoundConverterHasLeftOverData = (1 << 1)
+};
+
+
+enum {
+ kExtendedSoundSampleCountNotValid = 1L << 0,
+ kExtendedSoundBufferSizeValid = 1L << 1,
+ kExtendedSoundFrameSizesValid = 1L << 2,
+ kExtendedSoundCommonFrameSizeValid = 1L << 3,
+ kExtendedSoundExtensionsValid = 1L << 4,
+ kExtendedSoundBufferFlagsValid = 1L << 5
+};
+
+
+enum {
+ kExtendedSoundBufferIsDiscontinuous = 1L << 0,
+ kExtendedSoundBufferIsFirstBuffer = 1L << 1
+};
+
+
+
+
+
+
+
+struct SndCommand {
+ unsigned short cmd;
+ short param1;
+ long param2;
+};
+typedef struct SndCommand SndCommand;
+typedef struct SndChannel SndChannel;
+
+typedef SndChannel * SndChannelPtr;
+typedef void ( * SndCallBackProcPtr)(SndChannelPtr chan, SndCommand *cmd);
+typedef SndCallBackProcPtr SndCallBackUPP;
+struct SndChannel {
+ SndChannelPtr nextChan;
+ Ptr firstMod;
+ SndCallBackUPP callBack;
+ long userInfo;
+ long wait;
+ SndCommand cmdInProgress;
+ short flags;
+ short qLength;
+ short qHead;
+ short qTail;
+ SndCommand queue[128];
+};
+extern SndCallBackUPP
+NewSndCallBackUPP(SndCallBackProcPtr userRoutine) ;
+extern void
+DisposeSndCallBackUPP(SndCallBackUPP userUPP) ;
+extern void
+InvokeSndCallBackUPP(
+ SndChannelPtr chan,
+ SndCommand * cmd,
+ SndCallBackUPP userUPP) ;
+
+
+struct StateBlock {
+ short stateVar[64];
+};
+typedef struct StateBlock StateBlock;
+typedef StateBlock * StateBlockPtr;
+struct LeftOverBlock {
+ unsigned long count;
+ SInt8 sampleArea[32];
+};
+typedef struct LeftOverBlock LeftOverBlock;
+typedef LeftOverBlock * LeftOverBlockPtr;
+struct ModRef {
+ unsigned short modNumber;
+ long modInit;
+};
+typedef struct ModRef ModRef;
+struct SndListResource {
+ short format;
+ short numModifiers;
+ ModRef modifierPart[1];
+ short numCommands;
+ SndCommand commandPart[1];
+ UInt8 dataPart[1];
+};
+typedef struct SndListResource SndListResource;
+typedef SndListResource * SndListPtr;
+typedef SndListPtr * SndListHandle;
+typedef SndListHandle SndListHndl;
+
+struct Snd2ListResource {
+ short format;
+ short refCount;
+ short numCommands;
+ SndCommand commandPart[1];
+ UInt8 dataPart[1];
+};
+typedef struct Snd2ListResource Snd2ListResource;
+typedef Snd2ListResource * Snd2ListPtr;
+typedef Snd2ListPtr * Snd2ListHandle;
+typedef Snd2ListHandle Snd2ListHndl;
+struct SoundHeader {
+ Ptr samplePtr;
+ unsigned long length;
+ UnsignedFixed sampleRate;
+ unsigned long loopStart;
+ unsigned long loopEnd;
+ UInt8 encode;
+ UInt8 baseFrequency;
+ UInt8 sampleArea[1];
+};
+typedef struct SoundHeader SoundHeader;
+typedef SoundHeader * SoundHeaderPtr;
+struct CmpSoundHeader {
+ Ptr samplePtr;
+ unsigned long numChannels;
+ UnsignedFixed sampleRate;
+ unsigned long loopStart;
+ unsigned long loopEnd;
+ UInt8 encode;
+ UInt8 baseFrequency;
+ unsigned long numFrames;
+ extended80 AIFFSampleRate;
+ Ptr markerChunk;
+ OSType format;
+ unsigned long futureUse2;
+ StateBlockPtr stateVars;
+ LeftOverBlockPtr leftOverSamples;
+ short compressionID;
+ unsigned short packetSize;
+ unsigned short snthID;
+ unsigned short sampleSize;
+ UInt8 sampleArea[1];
+};
+typedef struct CmpSoundHeader CmpSoundHeader;
+typedef CmpSoundHeader * CmpSoundHeaderPtr;
+struct ExtSoundHeader {
+ Ptr samplePtr;
+ unsigned long numChannels;
+ UnsignedFixed sampleRate;
+ unsigned long loopStart;
+ unsigned long loopEnd;
+ UInt8 encode;
+ UInt8 baseFrequency;
+ unsigned long numFrames;
+ extended80 AIFFSampleRate;
+ Ptr markerChunk;
+ Ptr instrumentChunks;
+ Ptr AESRecording;
+ unsigned short sampleSize;
+ unsigned short futureUse1;
+ unsigned long futureUse2;
+ unsigned long futureUse3;
+ unsigned long futureUse4;
+ UInt8 sampleArea[1];
+};
+typedef struct ExtSoundHeader ExtSoundHeader;
+typedef ExtSoundHeader * ExtSoundHeaderPtr;
+union SoundHeaderUnion {
+ SoundHeader stdHeader;
+ CmpSoundHeader cmpHeader;
+ ExtSoundHeader extHeader;
+};
+typedef union SoundHeaderUnion SoundHeaderUnion;
+struct ConversionBlock {
+ short destination;
+ short unused;
+ CmpSoundHeaderPtr inputPtr;
+ CmpSoundHeaderPtr outputPtr;
+};
+typedef struct ConversionBlock ConversionBlock;
+typedef ConversionBlock * ConversionBlockPtr;
+
+enum {
+ kScheduledSoundDoScheduled = 1 << 0,
+ kScheduledSoundDoCallBack = 1 << 1,
+ kScheduledSoundExtendedHdr = 1 << 2
+};
+
+struct ScheduledSoundHeader {
+ SoundHeaderUnion u;
+ long flags;
+ short reserved;
+ short callBackParam1;
+ long callBackParam2;
+ TimeRecord startTime;
+};
+typedef struct ScheduledSoundHeader ScheduledSoundHeader;
+typedef ScheduledSoundHeader * ScheduledSoundHeaderPtr;
+struct ExtendedScheduledSoundHeader {
+ SoundHeaderUnion u;
+ long flags;
+ short reserved;
+ short callBackParam1;
+ long callBackParam2;
+ TimeRecord startTime;
+ long recordSize;
+ long extendedFlags;
+ long bufferSize;
+ long frameCount;
+ long * frameSizesArray;
+ long commonFrameSize;
+ void * extensionsPtr;
+ long extensionsSize;
+ unsigned long bufferFlags;
+ unsigned long bufferFlagsMask;
+};
+typedef struct ExtendedScheduledSoundHeader ExtendedScheduledSoundHeader;
+typedef ExtendedScheduledSoundHeader * ExtendedScheduledSoundHeaderPtr;
+struct SMStatus {
+ short smMaxCPULoad;
+ short smNumChannels;
+ short smCurCPULoad;
+};
+typedef struct SMStatus SMStatus;
+typedef SMStatus * SMStatusPtr;
+struct SCStatus {
+ UnsignedFixed scStartTime;
+ UnsignedFixed scEndTime;
+ UnsignedFixed scCurrentTime;
+ Boolean scChannelBusy;
+ Boolean scChannelDisposed;
+ Boolean scChannelPaused;
+ Boolean scUnused;
+ unsigned long scChannelAttributes;
+ long scCPULoad;
+};
+typedef struct SCStatus SCStatus;
+typedef SCStatus * SCStatusPtr;
+struct AudioSelection {
+ long unitType;
+ UnsignedFixed selStart;
+ UnsignedFixed selEnd;
+};
+typedef struct AudioSelection AudioSelection;
+typedef AudioSelection * AudioSelectionPtr;
+struct SoundInfoList {
+ short count;
+ Handle infoHandle;
+};
+typedef struct SoundInfoList SoundInfoList;
+typedef SoundInfoList * SoundInfoListPtr;
+struct SoundComponentData {
+ long flags;
+ OSType format;
+ short numChannels;
+ short sampleSize;
+ UnsignedFixed sampleRate;
+ long sampleCount;
+ Byte * buffer;
+ long reserved;
+};
+typedef struct SoundComponentData SoundComponentData;
+typedef SoundComponentData * SoundComponentDataPtr;
+struct ExtendedSoundComponentData {
+ SoundComponentData desc;
+ long recordSize;
+ long extendedFlags;
+ long bufferSize;
+ long frameCount;
+ long * frameSizesArray;
+ long commonFrameSize;
+ void * extensionsPtr;
+ long extensionsSize;
+ unsigned long bufferFlags;
+ unsigned long bufferFlagsMask;
+};
+typedef struct ExtendedSoundComponentData ExtendedSoundComponentData;
+typedef ExtendedSoundComponentData * ExtendedSoundComponentDataPtr;
+typedef struct SoundParamBlock SoundParamBlock;
+typedef SoundParamBlock * SoundParamBlockPtr;
+typedef Boolean ( * SoundParamProcPtr)(SoundParamBlockPtr * pb);
+typedef SoundParamProcPtr SoundParamUPP;
+struct SoundParamBlock {
+ long recordSize;
+ SoundComponentData desc;
+ UnsignedFixed rateMultiplier;
+ short leftVolume;
+ short rightVolume;
+ long quality;
+ ComponentInstance filter;
+ SoundParamUPP moreRtn;
+ SoundParamUPP completionRtn;
+ long refCon;
+ short result;
+};
+
+struct ExtendedSoundParamBlock {
+ SoundParamBlock pb;
+ short reserved;
+ long extendedFlags;
+ long bufferSize;
+ long frameCount;
+ long * frameSizesArray;
+ long commonFrameSize;
+ void * extensionsPtr;
+ long extensionsSize;
+ unsigned long bufferFlags;
+ unsigned long bufferFlagsMask;
+};
+typedef struct ExtendedSoundParamBlock ExtendedSoundParamBlock;
+typedef ExtendedSoundParamBlock * ExtendedSoundParamBlockPtr;
+struct CompressionInfo {
+ long recordSize;
+ OSType format;
+ short compressionID;
+ unsigned short samplesPerPacket;
+ unsigned short bytesPerPacket;
+ unsigned short bytesPerFrame;
+ unsigned short bytesPerSample;
+ unsigned short futureUse1;
+};
+typedef struct CompressionInfo CompressionInfo;
+typedef CompressionInfo * CompressionInfoPtr;
+typedef CompressionInfoPtr * CompressionInfoHandle;
+
+struct SoundSlopeAndInterceptRecord {
+ Float64 slope;
+ Float64 intercept;
+ Float64 minClip;
+ Float64 maxClip;
+};
+typedef struct SoundSlopeAndInterceptRecord SoundSlopeAndInterceptRecord;
+typedef SoundSlopeAndInterceptRecord * SoundSlopeAndInterceptPtr;
+
+typedef struct OpaqueSoundConverter* SoundConverter;
+
+typedef Boolean ( * SoundConverterFillBufferDataProcPtr)(SoundComponentDataPtr *data, void *refCon);
+typedef SoundConverterFillBufferDataProcPtr SoundConverterFillBufferDataUPP;
+
+typedef struct OpaqueSoundSource* SoundSource;
+typedef SoundSource * SoundSourcePtr;
+
+
+struct SoundComponentLink {
+ ComponentDescription description;
+ SoundSource mixerID;
+ SoundSource * linkID;
+};
+typedef struct SoundComponentLink SoundComponentLink;
+typedef SoundComponentLink * SoundComponentLinkPtr;
+struct AudioInfo {
+ long capabilitiesFlags;
+ long reserved;
+ unsigned short numVolumeSteps;
+};
+typedef struct AudioInfo AudioInfo;
+typedef AudioInfo * AudioInfoPtr;
+struct AudioFormatAtom {
+ long size;
+ OSType atomType;
+ OSType format;
+};
+typedef struct AudioFormatAtom AudioFormatAtom;
+typedef AudioFormatAtom * AudioFormatAtomPtr;
+struct AudioEndianAtom {
+ long size;
+ OSType atomType;
+ short littleEndian;
+};
+typedef struct AudioEndianAtom AudioEndianAtom;
+typedef AudioEndianAtom * AudioEndianAtomPtr;
+struct AudioTerminatorAtom {
+ long size;
+ OSType atomType;
+};
+typedef struct AudioTerminatorAtom AudioTerminatorAtom;
+typedef AudioTerminatorAtom * AudioTerminatorAtomPtr;
+struct LevelMeterInfo {
+ short numChannels;
+ UInt8 leftMeter;
+ UInt8 rightMeter;
+};
+typedef struct LevelMeterInfo LevelMeterInfo;
+typedef LevelMeterInfo * LevelMeterInfoPtr;
+struct EQSpectrumBandsRecord {
+ short count;
+ UnsignedFixedPtr frequency;
+};
+typedef struct EQSpectrumBandsRecord EQSpectrumBandsRecord;
+typedef EQSpectrumBandsRecord * EQSpectrumBandsRecordPtr;
+
+
+
+typedef struct SPB SPB;
+typedef SPB * SPBPtr;
+
+
+
+typedef void ( * SIInterruptProcPtr)(SPBPtr inParamPtr, Ptr dataBuffer, short peakAmplitude, long sampleSize);
+typedef void ( * SICompletionProcPtr)(SPBPtr inParamPtr);
+typedef SIInterruptProcPtr SIInterruptUPP;
+typedef SICompletionProcPtr SICompletionUPP;
+
+
+
+struct SPB {
+ long inRefNum;
+ unsigned long count;
+ unsigned long milliseconds;
+ unsigned long bufferLength;
+ Ptr bufferPtr;
+ SICompletionUPP completionRoutine;
+ SIInterruptUPP interruptRoutine;
+ long userLong;
+ OSErr error;
+ long unused1;
+};
+extern SoundParamUPP
+NewSoundParamUPP(SoundParamProcPtr userRoutine) ;
+extern SoundConverterFillBufferDataUPP
+NewSoundConverterFillBufferDataUPP(SoundConverterFillBufferDataProcPtr userRoutine) ;
+extern SIInterruptUPP
+NewSIInterruptUPP(SIInterruptProcPtr userRoutine) ;
+extern SICompletionUPP
+NewSICompletionUPP(SICompletionProcPtr userRoutine) ;
+extern void
+DisposeSoundParamUPP(SoundParamUPP userUPP) ;
+extern void
+DisposeSoundConverterFillBufferDataUPP(SoundConverterFillBufferDataUPP userUPP) ;
+extern void
+DisposeSIInterruptUPP(SIInterruptUPP userUPP) ;
+extern void
+DisposeSICompletionUPP(SICompletionUPP userUPP) ;
+extern Boolean
+InvokeSoundParamUPP(
+ SoundParamBlockPtr * pb,
+ SoundParamUPP userUPP) ;
+extern Boolean
+InvokeSoundConverterFillBufferDataUPP(
+ SoundComponentDataPtr * data,
+ void * refCon,
+ SoundConverterFillBufferDataUPP userUPP) ;
+extern void
+InvokeSIInterruptUPP(
+ SPBPtr inParamPtr,
+ Ptr dataBuffer,
+ short peakAmplitude,
+ long sampleSize,
+ SIInterruptUPP userUPP) ;
+extern void
+InvokeSICompletionUPP(
+ SPBPtr inParamPtr,
+ SICompletionUPP userUPP) ;
+
+typedef void ( * FilePlayCompletionProcPtr)(SndChannelPtr chan);
+typedef FilePlayCompletionProcPtr FilePlayCompletionUPP;
+extern void
+SysBeep(short duration) ;
+extern OSErr
+SndDoCommand(
+ SndChannelPtr chan,
+ const SndCommand * cmd,
+ Boolean noWait) ;
+extern OSErr
+SndDoImmediate(
+ SndChannelPtr chan,
+ const SndCommand * cmd) ;
+extern OSErr
+SndNewChannel(
+ SndChannelPtr * chan,
+ short synth,
+ long init,
+ SndCallBackUPP userRoutine) ;
+extern OSErr
+SndDisposeChannel(
+ SndChannelPtr chan,
+ Boolean quietNow) ;
+extern OSErr
+SndPlay(
+ SndChannelPtr chan,
+ SndListHandle sndHandle,
+ Boolean async) ;
+extern NumVersion
+SndSoundManagerVersion(void) ;
+extern OSErr
+SndChannelStatus(
+ SndChannelPtr chan,
+ short theLength,
+ SCStatusPtr theStatus) ;
+extern OSErr
+SndManagerStatus(
+ short theLength,
+ SMStatusPtr theStatus) ;
+extern void
+SndGetSysBeepState(short * sysBeepState) ;
+extern OSErr
+SndSetSysBeepState(short sysBeepState) ;
+extern OSErr
+GetSysBeepVolume(long * level) ;
+extern OSErr
+SetSysBeepVolume(long level) ;
+extern OSErr
+GetDefaultOutputVolume(long * level) ;
+extern OSErr
+SetDefaultOutputVolume(long level) ;
+extern OSErr
+GetSoundHeaderOffset(
+ SndListHandle sndHandle,
+ long * offset) ;
+extern UnsignedFixed
+UnsignedFixedMulDiv(
+ UnsignedFixed value,
+ UnsignedFixed multiplier,
+ UnsignedFixed divisor);
+extern OSErr
+GetCompressionInfo(
+ short compressionID,
+ OSType format,
+ short numChannels,
+ short sampleSize,
+ CompressionInfoPtr cp) ;
+extern OSErr
+SetSoundPreference(
+ OSType theType,
+ Str255 name,
+ Handle settings) ;
+extern OSErr
+GetSoundPreference(
+ OSType theType,
+ Str255 name,
+ Handle settings) ;
+extern OSErr
+OpenMixerSoundComponent(
+ SoundComponentDataPtr outputDescription,
+ long outputFlags,
+ ComponentInstance * mixerComponent) ;
+extern OSErr
+CloseMixerSoundComponent(ComponentInstance ci) ;
+extern OSErr
+SndGetInfo(
+ SndChannelPtr chan,
+ OSType selector,
+ void * infoPtr) ;
+extern OSErr
+SndSetInfo(
+ SndChannelPtr chan,
+ OSType selector,
+ const void * infoPtr) ;
+extern OSErr
+GetSoundOutputInfo(
+ Component outputDevice,
+ OSType selector,
+ void * infoPtr) ;
+extern OSErr
+SetSoundOutputInfo(
+ Component outputDevice,
+ OSType selector,
+ const void * infoPtr) ;
+extern OSErr
+GetCompressionName(
+ OSType compressionType,
+ Str255 compressionName) ;
+extern OSErr
+SoundConverterOpen(
+ const SoundComponentData * inputFormat,
+ const SoundComponentData * outputFormat,
+ SoundConverter * sc) ;
+extern OSErr
+SoundConverterClose(SoundConverter sc) ;
+extern OSErr
+SoundConverterGetBufferSizes(
+ SoundConverter sc,
+ unsigned long inputBytesTarget,
+ unsigned long * inputFrames,
+ unsigned long * inputBytes,
+ unsigned long * outputBytes) ;
+extern OSErr
+SoundConverterBeginConversion(SoundConverter sc) ;
+extern OSErr
+SoundConverterConvertBuffer(
+ SoundConverter sc,
+ const void * inputPtr,
+ unsigned long inputFrames,
+ void * outputPtr,
+ unsigned long * outputFrames,
+ unsigned long * outputBytes) ;
+extern OSErr
+SoundConverterEndConversion(
+ SoundConverter sc,
+ void * outputPtr,
+ unsigned long * outputFrames,
+ unsigned long * outputBytes) ;
+extern OSErr
+SoundConverterGetInfo(
+ SoundConverter sc,
+ OSType selector,
+ void * infoPtr) ;
+extern OSErr
+SoundConverterSetInfo(
+ SoundConverter sc,
+ OSType selector,
+ void * infoPtr) ;
+extern OSErr
+SoundConverterFillBuffer(
+ SoundConverter sc,
+ SoundConverterFillBufferDataUPP fillBufferDataUPP,
+ void * fillBufferDataRefCon,
+ void * outputBuffer,
+ unsigned long outputBufferByteSize,
+ unsigned long * bytesWritten,
+ unsigned long * framesWritten,
+ unsigned long * outputFlags) ;
+extern OSErr
+SoundManagerGetInfo(
+ OSType selector,
+ void * infoPtr) ;
+extern OSErr
+SoundManagerSetInfo(
+ OSType selector,
+ const void * infoPtr) ;
+extern ComponentResult
+SoundComponentInitOutputDevice(
+ ComponentInstance ti,
+ long actions) ;
+extern ComponentResult
+SoundComponentSetSource(
+ ComponentInstance ti,
+ SoundSource sourceID,
+ ComponentInstance source) ;
+extern ComponentResult
+SoundComponentGetSource(
+ ComponentInstance ti,
+ SoundSource sourceID,
+ ComponentInstance * source) ;
+extern ComponentResult
+SoundComponentGetSourceData(
+ ComponentInstance ti,
+ SoundComponentDataPtr * sourceData) ;
+extern ComponentResult
+SoundComponentSetOutput(
+ ComponentInstance ti,
+ SoundComponentDataPtr requested,
+ SoundComponentDataPtr * actual) ;
+extern ComponentResult
+SoundComponentAddSource(
+ ComponentInstance ti,
+ SoundSource * sourceID) ;
+extern ComponentResult
+SoundComponentRemoveSource(
+ ComponentInstance ti,
+ SoundSource sourceID) ;
+extern ComponentResult
+SoundComponentGetInfo(
+ ComponentInstance ti,
+ SoundSource sourceID,
+ OSType selector,
+ void * infoPtr) ;
+extern ComponentResult
+SoundComponentSetInfo(
+ ComponentInstance ti,
+ SoundSource sourceID,
+ OSType selector,
+ void * infoPtr) ;
+extern ComponentResult
+SoundComponentStartSource(
+ ComponentInstance ti,
+ short count,
+ SoundSource * sources) ;
+extern ComponentResult
+SoundComponentStopSource(
+ ComponentInstance ti,
+ short count,
+ SoundSource * sources) ;
+extern ComponentResult
+SoundComponentPauseSource(
+ ComponentInstance ti,
+ short count,
+ SoundSource * sources) ;
+extern ComponentResult
+SoundComponentPlaySourceBuffer(
+ ComponentInstance ti,
+ SoundSource sourceID,
+ SoundParamBlockPtr pb,
+ long actions) ;
+
+
+
+
+enum {
+ kSoundComponentInitOutputDeviceSelect = 0x0001,
+ kSoundComponentSetSourceSelect = 0x0002,
+ kSoundComponentGetSourceSelect = 0x0003,
+ kSoundComponentGetSourceDataSelect = 0x0004,
+ kSoundComponentSetOutputSelect = 0x0005,
+ kSoundComponentAddSourceSelect = 0x0101,
+ kSoundComponentRemoveSourceSelect = 0x0102,
+ kSoundComponentGetInfoSelect = 0x0103,
+ kSoundComponentSetInfoSelect = 0x0104,
+ kSoundComponentStartSourceSelect = 0x0105,
+ kSoundComponentStopSourceSelect = 0x0106,
+ kSoundComponentPauseSourceSelect = 0x0107,
+ kSoundComponentPlaySourceBufferSelect = 0x0108
+};
+enum {
+ kDelegatedSoundComponentSelectors = 0x0100
+};
+extern NumVersion
+SPBVersion(void) ;
+extern OSErr
+SndRecord(
+ ModalFilterUPP filterProc,
+ Point corner,
+ OSType quality,
+ SndListHandle * sndHandle) ;
+extern OSErr
+SPBSignInDevice(
+ short deviceRefNum,
+ ConstStr255Param deviceName) ;
+extern OSErr
+SPBSignOutDevice(short deviceRefNum) ;
+extern OSErr
+SPBGetIndexedDevice(
+ short count,
+ Str255 deviceName,
+ Handle * deviceIconHandle) ;
+extern OSErr
+SPBOpenDevice(
+ ConstStr255Param deviceName,
+ short permission,
+ long * inRefNum) ;
+extern OSErr
+SPBCloseDevice(long inRefNum) ;
+extern OSErr
+SPBRecord(
+ SPBPtr inParamPtr,
+ Boolean asynchFlag) ;
+extern OSErr
+SPBPauseRecording(long inRefNum) ;
+extern OSErr
+SPBResumeRecording(long inRefNum) ;
+extern OSErr
+SPBStopRecording(long inRefNum) ;
+extern OSErr
+SPBGetRecordingStatus(
+ long inRefNum,
+ short * recordingStatus,
+ short * meterLevel,
+ unsigned long * totalSamplesToRecord,
+ unsigned long * numberOfSamplesRecorded,
+ unsigned long * totalMsecsToRecord,
+ unsigned long * numberOfMsecsRecorded) ;
+extern OSErr
+SPBGetDeviceInfo(
+ long inRefNum,
+ OSType infoType,
+ void * infoData) ;
+extern OSErr
+SPBSetDeviceInfo(
+ long inRefNum,
+ OSType infoType,
+ void * infoData) ;
+extern OSErr
+SPBMillisecondsToBytes(
+ long inRefNum,
+ long * milliseconds) ;
+extern OSErr
+SPBBytesToMilliseconds(
+ long inRefNum,
+ long * byteCount) ;
+extern OSErr
+SetupSndHeader(
+ SndListHandle sndHandle,
+ short numChannels,
+ UnsignedFixed sampleRate,
+ short sampleSize,
+ OSType compressionType,
+ short baseNote,
+ unsigned long numBytes,
+ short * headerLen) ;
+extern OSErr
+SetupAIFFHeader(
+ short fRefNum,
+ short numChannels,
+ UnsignedFixed sampleRate,
+ short sampleSize,
+ OSType compressionType,
+ unsigned long numBytes,
+ unsigned long numFrames) ;
+extern OSErr
+ParseAIFFHeader(
+ short fRefNum,
+ SoundComponentData * sndInfo,
+ unsigned long * numFrames,
+ unsigned long * dataOffset) ;
+extern OSErr
+ParseSndHeader(
+ SndListHandle sndHandle,
+ SoundComponentData * sndInfo,
+ unsigned long * numFrames,
+ unsigned long * dataOffset) ;
+typedef struct SndInputCmpParam SndInputCmpParam;
+typedef SndInputCmpParam * SndInputCmpParamPtr;
+typedef void ( * SICCompletionProcPtr)(SndInputCmpParamPtr SICParmPtr);
+struct SndInputCmpParam {
+ SICCompletionProcPtr ioCompletion;
+ SIInterruptProcPtr ioInterrupt;
+ OSErr ioResult;
+ short pad;
+ unsigned long ioReqCount;
+ unsigned long ioActCount;
+ Ptr ioBuffer;
+ Ptr ioMisc;
+};
+extern ComponentResult
+SndInputReadAsync(
+ ComponentInstance self,
+ SndInputCmpParamPtr SICParmPtr) ;
+extern ComponentResult
+SndInputReadSync(
+ ComponentInstance self,
+ SndInputCmpParamPtr SICParmPtr) ;
+extern ComponentResult
+SndInputPauseRecording(ComponentInstance self) ;
+extern ComponentResult
+SndInputResumeRecording(ComponentInstance self) ;
+extern ComponentResult
+SndInputStopRecording(ComponentInstance self) ;
+extern ComponentResult
+SndInputGetStatus(
+ ComponentInstance self,
+ short * recordingStatus,
+ unsigned long * totalSamplesToRecord,
+ unsigned long * numberOfSamplesRecorded) ;
+extern ComponentResult
+SndInputGetDeviceInfo(
+ ComponentInstance self,
+ OSType infoType,
+ void * infoData) ;
+extern ComponentResult
+SndInputSetDeviceInfo(
+ ComponentInstance self,
+ OSType infoType,
+ void * infoData) ;
+extern ComponentResult
+SndInputInitHardware(ComponentInstance self) ;
+
+
+
+
+enum {
+ kSndInputReadAsyncSelect = 0x0001,
+ kSndInputReadSyncSelect = 0x0002,
+ kSndInputPauseRecordingSelect = 0x0003,
+ kSndInputResumeRecordingSelect = 0x0004,
+ kSndInputStopRecordingSelect = 0x0005,
+ kSndInputGetStatusSelect = 0x0006,
+ kSndInputGetDeviceInfoSelect = 0x0007,
+ kSndInputSetDeviceInfoSelect = 0x0008,
+ kSndInputInitHardwareSelect = 0x0009
+};
+
+
+
+
+
+
+}
+
+
+
+extern "C" {
+
+
+enum {
+ kOSAComponentType = 'osa '
+};
+
+
+enum {
+ kOSAGenericScriptingComponentSubtype = 'scpt'
+};
+
+
+
+enum {
+ kOSAFileType = 'osas'
+};
+
+
+
+
+
+
+enum {
+ kOSASuite = 'ascr'
+};
+
+
+enum {
+ kOSARecordedText = 'recd'
+};
+
+
+
+enum {
+ kOSAScriptIsModified = 'modi'
+};
+
+
+
+enum {
+ kOSAScriptIsTypeCompiledScript = 'cscr'
+};
+
+
+
+enum {
+ kOSAScriptIsTypeScriptValue = 'valu'
+};
+
+
+
+enum {
+ kOSAScriptIsTypeScriptContext = 'cntx'
+};
+
+
+
+enum {
+ kOSAScriptBestType = 'best'
+};
+
+
+
+
+
+
+
+enum {
+ kOSACanGetSource = 'gsrc'
+};
+
+
+enum {
+ typeOSADialectInfo = 'difo',
+ keyOSADialectName = 'dnam',
+ keyOSADialectCode = 'dcod',
+ keyOSADialectLangCode = 'dlcd',
+ keyOSADialectScriptCode = 'dscd'
+};
+
+typedef ComponentResult OSAError;
+
+typedef unsigned long OSAID;
+
+
+
+
+enum {
+ kOSANullScript = 0L
+};
+
+
+enum {
+ kOSANullMode = 0,
+ kOSAModeNull = 0
+};
+
+
+
+
+
+typedef OSErr ( * OSACreateAppleEventProcPtr)(AEEventClass theAEEventClass, AEEventID theAEEventID, const AEAddressDesc *target, short returnID, long transactionID, AppleEvent *result, long refCon);
+typedef OSErr ( * OSASendProcPtr)(const AppleEvent *theAppleEvent, AppleEvent *reply, AESendMode sendMode, AESendPriority sendPriority, long timeOutInTicks, AEIdleUPP idleProc, AEFilterUPP filterProc, long refCon);
+typedef OSACreateAppleEventProcPtr OSACreateAppleEventUPP;
+typedef OSASendProcPtr OSASendUPP;
+extern OSACreateAppleEventUPP
+NewOSACreateAppleEventUPP(OSACreateAppleEventProcPtr userRoutine) ;
+extern OSASendUPP
+NewOSASendUPP(OSASendProcPtr userRoutine) ;
+extern void
+DisposeOSACreateAppleEventUPP(OSACreateAppleEventUPP userUPP) ;
+extern void
+DisposeOSASendUPP(OSASendUPP userUPP) ;
+extern OSErr
+InvokeOSACreateAppleEventUPP(
+ AEEventClass theAEEventClass,
+ AEEventID theAEEventID,
+ const AEAddressDesc * target,
+ short returnID,
+ long transactionID,
+ AppleEvent * result,
+ long refCon,
+ OSACreateAppleEventUPP userUPP) ;
+extern OSErr
+InvokeOSASendUPP(
+ const AppleEvent * theAppleEvent,
+ AppleEvent * reply,
+ AESendMode sendMode,
+ AESendPriority sendPriority,
+ long timeOutInTicks,
+ AEIdleUPP idleProc,
+ AEFilterUPP filterProc,
+ long refCon,
+ OSASendUPP userUPP) ;
+enum {
+ kOSASupportsCompiling = 0x0002,
+ kOSASupportsGetSource = 0x0004,
+ kOSASupportsAECoercion = 0x0008,
+ kOSASupportsAESending = 0x0010,
+ kOSASupportsRecording = 0x0020,
+ kOSASupportsConvenience = 0x0040,
+ kOSASupportsDialects = 0x0080,
+ kOSASupportsEventHandling = 0x0100
+};
+
+
+enum {
+ kOSASelectLoad = 0x0001,
+ kOSASelectStore = 0x0002,
+ kOSASelectExecute = 0x0003,
+ kOSASelectDisplay = 0x0004,
+ kOSASelectScriptError = 0x0005,
+ kOSASelectDispose = 0x0006,
+ kOSASelectSetScriptInfo = 0x0007,
+ kOSASelectGetScriptInfo = 0x0008,
+ kOSASelectSetActiveProc = 0x0009,
+ kOSASelectGetActiveProc = 0x000A
+};
+
+
+enum {
+ kOSASelectScriptingComponentName = 0x0102,
+ kOSASelectCompile = 0x0103,
+ kOSASelectCopyID = 0x0104
+};
+
+enum {
+ kOSASelectCopyScript = 0x0105
+};
+
+
+enum {
+ kOSASelectGetSource = 0x0201
+};
+
+
+enum {
+ kOSASelectCoerceFromDesc = 0x0301,
+ kOSASelectCoerceToDesc = 0x0302
+};
+
+
+enum {
+ kOSASelectSetSendProc = 0x0401,
+ kOSASelectGetSendProc = 0x0402,
+ kOSASelectSetCreateProc = 0x0403,
+ kOSASelectGetCreateProc = 0x0404,
+ kOSASelectSetDefaultTarget = 0x0405
+};
+
+
+enum {
+ kOSASelectStartRecording = 0x0501,
+ kOSASelectStopRecording = 0x0502
+};
+
+
+enum {
+ kOSASelectLoadExecute = 0x0601,
+ kOSASelectCompileExecute = 0x0602,
+ kOSASelectDoScript = 0x0603
+};
+
+
+enum {
+ kOSASelectSetCurrentDialect = 0x0701,
+ kOSASelectGetCurrentDialect = 0x0702,
+ kOSASelectAvailableDialects = 0x0703,
+ kOSASelectGetDialectInfo = 0x0704,
+ kOSASelectAvailableDialectCodeList = 0x0705
+};
+
+
+enum {
+ kOSASelectSetResumeDispatchProc = 0x0801,
+ kOSASelectGetResumeDispatchProc = 0x0802,
+ kOSASelectExecuteEvent = 0x0803,
+ kOSASelectDoEvent = 0x0804,
+ kOSASelectMakeContext = 0x0805
+};
+
+
+enum {
+ kOSADebuggerCreateSession = 0x0901,
+ kOSADebuggerGetSessionState = 0x0902,
+ kOSADebuggerSessionStep = 0x0903,
+ kOSADebuggerDisposeSession = 0x0904,
+ kOSADebuggerGetStatementRanges = 0x0905,
+ kOSADebuggerGetBreakpoint = 0x0910,
+ kOSADebuggerSetBreakpoint = 0x0911,
+ kOSADebuggerGetDefaultBreakpoint = 0x0912,
+ kOSADebuggerGetCurrentCallFrame = 0x0906,
+ kOSADebuggerGetCallFrameState = 0x0907,
+ kOSADebuggerGetVariable = 0x0908,
+ kOSADebuggerSetVariable = 0x0909,
+ kOSADebuggerGetPreviousCallFrame = 0x090A,
+ kOSADebuggerDisposeCallFrame = 0x090B
+};
+
+
+enum {
+ kOSASelectComponentSpecificStart = 0x1001
+};
+enum {
+ kOSAModePreventGetSource = 0x00000001
+};
+enum {
+ kOSAModeNeverInteract = kAENeverInteract,
+ kOSAModeCanInteract = kAECanInteract,
+ kOSAModeAlwaysInteract = kAEAlwaysInteract,
+ kOSAModeDontReconnect = kAEDontReconnect
+};
+enum {
+ kOSAModeCantSwitchLayer = 0x00000040
+};
+enum {
+ kOSAModeDoRecord = 0x00001000
+};
+enum {
+ kOSAModeCompileIntoContext = 0x00000002
+};
+enum {
+ kOSAModeAugmentContext = 0x00000004
+};
+
+
+
+
+
+
+
+enum {
+ kOSAModeDisplayForHumans = 0x00000008
+};
+
+
+
+
+
+
+
+enum {
+ kOSAModeDontStoreParent = 0x00010000
+};
+enum {
+ kOSAModeDispatchToDirectObject = 0x00020000
+};
+
+
+
+
+
+enum {
+ kOSAModeDontGetDataForArguments = 0x00040000
+};
+
+
+
+
+
+
+enum {
+ kOSAModeFullyQualifyDescriptors = 0x00080000
+};
+enum {
+ kOSAScriptResourceType = kOSAGenericScriptingComponentSubtype
+};
+
+
+
+
+
+enum {
+ typeOSAGenericStorage = kOSAScriptResourceType
+};
+extern OSAError
+OSALoad(
+ ComponentInstance scriptingComponent,
+ const AEDesc * scriptData,
+ long modeFlags,
+ OSAID * resultingScriptID) ;
+extern OSAError
+OSAStore(
+ ComponentInstance scriptingComponent,
+ OSAID scriptID,
+ DescType desiredType,
+ long modeFlags,
+ AEDesc * resultingScriptData) ;
+extern OSAError
+OSAExecute(
+ ComponentInstance scriptingComponent,
+ OSAID compiledScriptID,
+ OSAID contextID,
+ long modeFlags,
+ OSAID * resultingScriptValueID) ;
+extern OSAError
+OSADisplay(
+ ComponentInstance scriptingComponent,
+ OSAID scriptValueID,
+ DescType desiredType,
+ long modeFlags,
+ AEDesc * resultingText) ;
+extern OSAError
+OSAScriptError(
+ ComponentInstance scriptingComponent,
+ OSType selector,
+ DescType desiredType,
+ AEDesc * resultingErrorDescription) ;
+enum {
+ kOSAErrorNumber = keyErrorNumber
+};
+enum {
+ kOSAErrorMessage = keyErrorString
+};
+enum {
+ kOSAErrorBriefMessage = 'errb'
+};
+enum {
+ kOSAErrorApp = 'erap'
+};
+enum {
+ kOSAErrorPartialResult = 'ptlr'
+};
+enum {
+ kOSAErrorOffendingObject = 'erob'
+};
+
+
+
+
+
+
+enum {
+ kOSAErrorExpectedType = 'errt'
+};
+enum {
+ kOSAErrorRange = 'erng'
+};
+
+
+
+
+
+
+enum {
+ typeOSAErrorRange = 'erng'
+};
+
+
+
+enum {
+ keyOSASourceStart = 'srcs'
+};
+
+
+
+enum {
+ keyOSASourceEnd = 'srce'
+};
+extern OSAError
+OSADispose(
+ ComponentInstance scriptingComponent,
+ OSAID scriptID) ;
+extern OSAError
+OSASetScriptInfo(
+ ComponentInstance scriptingComponent,
+ OSAID scriptID,
+ OSType selector,
+ long value) ;
+extern OSAError
+OSAGetScriptInfo(
+ ComponentInstance scriptingComponent,
+ OSAID scriptID,
+ OSType selector,
+ long * result) ;
+typedef OSErr ( * OSAActiveProcPtr)(long refCon);
+typedef OSAActiveProcPtr OSAActiveUPP;
+extern OSAActiveUPP
+NewOSAActiveUPP(OSAActiveProcPtr userRoutine) ;
+extern void
+DisposeOSAActiveUPP(OSAActiveUPP userUPP) ;
+extern OSErr
+InvokeOSAActiveUPP(
+ long refCon,
+ OSAActiveUPP userUPP) ;
+extern OSAError
+OSASetActiveProc(
+ ComponentInstance scriptingComponent,
+ OSAActiveUPP activeProc,
+ long refCon) ;
+extern OSAError
+OSAGetActiveProc(
+ ComponentInstance scriptingComponent,
+ OSAActiveUPP * activeProc,
+ long * refCon) ;
+extern OSAError
+OSAScriptingComponentName(
+ ComponentInstance scriptingComponent,
+ AEDesc * resultingScriptingComponentName) ;
+extern OSAError
+OSACompile(
+ ComponentInstance scriptingComponent,
+ const AEDesc * sourceData,
+ long modeFlags,
+ OSAID * previousAndResultingScriptID) ;
+extern OSAError
+OSACopyID(
+ ComponentInstance scriptingComponent,
+ OSAID fromID,
+ OSAID * toID) ;
+extern OSAError
+OSAGetSource(
+ ComponentInstance scriptingComponent,
+ OSAID scriptID,
+ DescType desiredType,
+ AEDesc * resultingSourceData) ;
+extern OSAError
+OSACoerceFromDesc(
+ ComponentInstance scriptingComponent,
+ const AEDesc * scriptData,
+ long modeFlags,
+ OSAID * resultingScriptID) ;
+extern OSAError
+OSACoerceToDesc(
+ ComponentInstance scriptingComponent,
+ OSAID scriptID,
+ DescType desiredType,
+ long modeFlags,
+ AEDesc * result) ;
+extern OSAError
+OSASetSendProc(
+ ComponentInstance scriptingComponent,
+ OSASendUPP sendProc,
+ long refCon) ;
+extern OSAError
+OSAGetSendProc(
+ ComponentInstance scriptingComponent,
+ OSASendUPP * sendProc,
+ long * refCon) ;
+extern OSAError
+OSASetCreateProc(
+ ComponentInstance scriptingComponent,
+ OSACreateAppleEventUPP createProc,
+ long refCon) ;
+extern OSAError
+OSAGetCreateProc(
+ ComponentInstance scriptingComponent,
+ OSACreateAppleEventUPP * createProc,
+ long * refCon) ;
+extern OSAError
+OSASetDefaultTarget(
+ ComponentInstance scriptingComponent,
+ const AEAddressDesc * target) ;
+extern OSAError
+OSAStartRecording(
+ ComponentInstance scriptingComponent,
+ OSAID * compiledScriptToModifyID) ;
+extern OSAError
+OSAStopRecording(
+ ComponentInstance scriptingComponent,
+ OSAID compiledScriptID) ;
+extern OSAError
+OSALoadExecute(
+ ComponentInstance scriptingComponent,
+ const AEDesc * scriptData,
+ OSAID contextID,
+ long modeFlags,
+ OSAID * resultingScriptValueID) ;
+extern OSAError
+OSACompileExecute(
+ ComponentInstance scriptingComponent,
+ const AEDesc * sourceData,
+ OSAID contextID,
+ long modeFlags,
+ OSAID * resultingScriptValueID) ;
+extern OSAError
+OSADoScript(
+ ComponentInstance scriptingComponent,
+ const AEDesc * sourceData,
+ OSAID contextID,
+ DescType desiredType,
+ long modeFlags,
+ AEDesc * resultingText) ;
+extern OSAError
+OSASetCurrentDialect(
+ ComponentInstance scriptingComponent,
+ short dialectCode) ;
+extern OSAError
+OSAGetCurrentDialect(
+ ComponentInstance scriptingComponent,
+ short * resultingDialectCode) ;
+extern OSAError
+OSAAvailableDialects(
+ ComponentInstance scriptingComponent,
+ AEDesc * resultingDialectInfoList) ;
+extern OSAError
+OSAGetDialectInfo(
+ ComponentInstance scriptingComponent,
+ short dialectCode,
+ OSType selector,
+ AEDesc * resultingDialectInfo) ;
+extern OSAError
+OSAAvailableDialectCodeList(
+ ComponentInstance scriptingComponent,
+ AEDesc * resultingDialectCodeList) ;
+extern OSAError
+OSASetResumeDispatchProc(
+ ComponentInstance scriptingComponent,
+ AEEventHandlerUPP resumeDispatchProc,
+ long refCon) ;
+enum {
+ kOSAUseStandardDispatch = kAEUseStandardDispatch
+};
+enum {
+ kOSANoDispatch = kAENoDispatch
+};
+enum {
+ kOSADontUsePhac = 0x0001
+};
+extern OSAError
+OSAGetResumeDispatchProc(
+ ComponentInstance scriptingComponent,
+ AEEventHandlerUPP * resumeDispatchProc,
+ long * refCon) ;
+extern OSAError
+OSAExecuteEvent(
+ ComponentInstance scriptingComponent,
+ const AppleEvent * theAppleEvent,
+ OSAID contextID,
+ long modeFlags,
+ OSAID * resultingScriptValueID) ;
+extern OSAError
+OSADoEvent(
+ ComponentInstance scriptingComponent,
+ const AppleEvent * theAppleEvent,
+ OSAID contextID,
+ long modeFlags,
+ AppleEvent * reply) ;
+extern OSAError
+OSAMakeContext(
+ ComponentInstance scriptingComponent,
+ const AEDesc * contextName,
+ OSAID parentContext,
+ OSAID * resultingContextID) ;
+typedef OSAID OSADebugSessionRef;
+typedef OSAID OSADebugCallFrameRef;
+
+
+
+typedef UInt32 OSAProgramState;
+enum {
+ eNotStarted = 0,
+ eRunnable = 1,
+ eRunning = 2,
+ eStopped = 3,
+ eTerminated = 4
+};
+
+typedef UInt32 OSADebugStepKind;
+enum {
+ eStepOver = 0,
+ eStepIn = 1,
+ eStepOut = 2,
+ eRun = 3
+};
+
+
+
+
+enum {
+ keyProgramState = 'dsps'
+};
+
+
+
+
+struct StatementRange {
+ unsigned long startPos;
+ unsigned long endPos;
+};
+typedef struct StatementRange StatementRange;
+enum {
+ typeStatementRange = 'srng'
+};
+
+enum {
+ keyProcedureName = 'dfnm',
+ keyStatementRange = 'dfsr',
+ keyLocalsNames = 'dfln',
+ keyGlobalsNames = 'dfgn',
+ keyParamsNames = 'dfpn'
+};
+extern OSAError
+OSADebuggerCreateSession(
+ ComponentInstance scriptingComponent,
+ OSAID inScript,
+ OSAID inContext,
+ OSADebugSessionRef * outSession) ;
+extern OSAError
+OSADebuggerGetSessionState(
+ ComponentInstance scriptingComponent,
+ OSADebugSessionRef inSession,
+ AERecord * outState) ;
+extern OSAError
+OSADebuggerSessionStep(
+ ComponentInstance scriptingComponent,
+ OSADebugSessionRef inSession,
+ OSADebugStepKind inKind) ;
+extern OSAError
+OSADebuggerDisposeSession(
+ ComponentInstance scriptingComponent,
+ OSADebugSessionRef inSession) ;
+extern OSAError
+OSADebuggerGetStatementRanges(
+ ComponentInstance scriptingComponent,
+ OSADebugSessionRef inSession,
+ AEDescList * outStatementRangeArray) ;
+extern OSAError
+OSADebuggerGetBreakpoint(
+ ComponentInstance scriptingComponent,
+ OSADebugSessionRef inSession,
+ UInt32 inSrcOffset,
+ OSAID * outBreakpoint) ;
+extern OSAError
+OSADebuggerSetBreakpoint(
+ ComponentInstance scriptingComponent,
+ OSADebugSessionRef inSession,
+ UInt32 inSrcOffset,
+ OSAID inBreakpoint) ;
+extern OSAError
+OSADebuggerGetDefaultBreakpoint(
+ ComponentInstance scriptingComponent,
+ OSADebugSessionRef inSession,
+ OSAID * outBreakpoint) ;
+extern OSAError
+OSADebuggerGetCurrentCallFrame(
+ ComponentInstance scriptingComponent,
+ OSADebugSessionRef inSession,
+ OSADebugCallFrameRef * outCallFrame) ;
+extern OSAError
+OSADebuggerGetCallFrameState(
+ ComponentInstance scriptingComponent,
+ OSADebugCallFrameRef inCallFrame,
+ AERecord * outState) ;
+extern OSAError
+OSADebuggerGetVariable(
+ ComponentInstance scriptingComponent,
+ OSADebugCallFrameRef inCallFrame,
+ const AEDesc * inVariableName,
+ OSAID * outVariable) ;
+extern OSAError
+OSADebuggerSetVariable(
+ ComponentInstance scriptingComponent,
+ OSADebugCallFrameRef inCallFrame,
+ const AEDesc * inVariableName,
+ OSAID inVariable) ;
+extern OSAError
+OSADebuggerGetPreviousCallFrame(
+ ComponentInstance scriptingComponent,
+ OSADebugCallFrameRef inCurrentFrame,
+ OSADebugCallFrameRef * outPrevFrame) ;
+extern OSAError
+OSADebuggerDisposeCallFrame(
+ ComponentInstance scriptingComponent,
+ OSADebugCallFrameRef inCallFrame) ;
+
+
+
+
+
+}
+
+
+
+extern "C" {
+extern OSErr
+OSAGetStorageType(
+ AEDataStorage scriptData,
+ DescType * dscType) ;
+extern OSErr
+OSAAddStorageType(
+ AEDataStorage scriptData,
+ DescType dscType) ;
+extern OSErr
+OSARemoveStorageType(AEDataStorage scriptData) ;
+
+
+
+
+}
+
+
+
+extern "C" {
+enum {
+
+ kGenericComponentVersion = 0x0100
+};
+
+enum {
+ kGSSSelectGetDefaultScriptingComponent = 0x1001,
+ kGSSSelectSetDefaultScriptingComponent = 0x1002,
+ kGSSSelectGetScriptingComponent = 0x1003,
+ kGSSSelectGetScriptingComponentFromStored = 0x1004,
+ kGSSSelectGenericToRealID = 0x1005,
+ kGSSSelectRealToGenericID = 0x1006,
+ kGSSSelectOutOfRange = 0x1007
+};
+
+typedef OSType ScriptingComponentSelector;
+typedef OSAID GenericID;
+extern OSAError
+OSAGetDefaultScriptingComponent(
+ ComponentInstance genericScriptingComponent,
+ ScriptingComponentSelector * scriptingSubType) ;
+extern OSAError
+OSASetDefaultScriptingComponent(
+ ComponentInstance genericScriptingComponent,
+ ScriptingComponentSelector scriptingSubType) ;
+extern OSAError
+OSAGetScriptingComponent(
+ ComponentInstance genericScriptingComponent,
+ ScriptingComponentSelector scriptingSubType,
+ ComponentInstance * scriptingInstance) ;
+extern OSAError
+OSAGetScriptingComponentFromStored(
+ ComponentInstance genericScriptingComponent,
+ const AEDesc * scriptData,
+ ScriptingComponentSelector * scriptingSubType) ;
+extern OSAError
+OSAGenericToRealID(
+ ComponentInstance genericScriptingComponent,
+ OSAID * theScriptID,
+ ComponentInstance * theExactComponent) ;
+extern OSAError
+OSARealToGenericID(
+ ComponentInstance genericScriptingComponent,
+ OSAID * theScriptID,
+ ComponentInstance theExactComponent) ;
+
+
+
+
+
+
+}
+
+
+
+extern "C" {
+enum {
+ typeAppleScript = 'ascr',
+ kAppleScriptSubtype = typeAppleScript,
+ typeASStorage = typeAppleScript
+};
+
+
+
+
+
+enum {
+ kASSelectInit = 0x1001,
+ kASSelectSetSourceStyles = 0x1002,
+ kASSelectGetSourceStyles = 0x1003,
+ kASSelectGetSourceStyleNames = 0x1004
+};
+
+
+
+
+
+enum {
+ kASHasOpenHandler = 'hsod'
+};
+extern OSAError
+ASInit(
+ ComponentInstance scriptingComponent,
+ long modeFlags,
+ long minStackSize,
+ long preferredStackSize,
+ long maxStackSize,
+ long minHeapSize,
+ long preferredHeapSize,
+ long maxHeapSize) ;
+enum {
+ kASDefaultMinStackSize = 4 * 1024,
+ kASDefaultPreferredStackSize = 16 * 1024,
+ kASDefaultMaxStackSize = 16 * 1024,
+ kASDefaultMinHeapSize = 4 * 1024,
+ kASDefaultPreferredHeapSize = 16 * 1024,
+ kASDefaultMaxHeapSize = 32L * 1024 * 1024
+};
+extern OSAError
+ASSetSourceStyles(
+ ComponentInstance scriptingComponent,
+ STHandle sourceStyles) ;
+extern OSAError
+ASGetSourceStyles(
+ ComponentInstance scriptingComponent,
+ STHandle * resultingSourceStyles) ;
+extern OSAError
+ASGetSourceStyleNames(
+ ComponentInstance scriptingComponent,
+ long modeFlags,
+ AEDescList * resultingSourceStyleNamesList) ;
+enum {
+ kASSourceStyleUncompiledText = 0,
+ kASSourceStyleNormalText = 1,
+ kASSourceStyleLanguageKeyword = 2,
+ kASSourceStyleApplicationKeyword = 3,
+ kASSourceStyleComment = 4,
+ kASSourceStyleLiteral = 5,
+ kASSourceStyleUserSymbol = 6,
+ kASSourceStyleObjectSpecifier = 7,
+ kASNumberOfSourceStyles = 8
+};
+
+
+
+
+}
+
+
+
+extern "C" {
+enum {
+ kOSAModeDontDefine = 0x0001
+};
+
+
+
+
+enum {
+ kASSelectSetPropertyObsolete = 0x1101,
+ kASSelectGetPropertyObsolete = 0x1102,
+ kASSelectSetHandlerObsolete = 0x1103,
+ kASSelectGetHandlerObsolete = 0x1104,
+ kASSelectGetAppTerminologyObsolete = 0x1105,
+ kASSelectSetProperty = 0x1106,
+ kASSelectGetProperty = 0x1107,
+ kASSelectSetHandler = 0x1108,
+ kASSelectGetHandler = 0x1109,
+ kASSelectGetAppTerminology = 0x110A,
+ kASSelectGetSysTerminology = 0x110B,
+ kASSelectGetPropertyNames = 0x110C,
+ kASSelectGetHandlerNames = 0x110D
+};
+extern OSAError
+OSASetProperty(
+ ComponentInstance scriptingComponent,
+ long modeFlags,
+ OSAID contextID,
+ const AEDesc * variableName,
+ OSAID scriptValueID) ;
+extern OSAError
+OSAGetProperty(
+ ComponentInstance scriptingComponent,
+ long modeFlags,
+ OSAID contextID,
+ const AEDesc * variableName,
+ OSAID * resultingScriptValueID) ;
+extern OSAError
+OSAGetPropertyNames(
+ ComponentInstance scriptingComponent,
+ long modeFlags,
+ OSAID contextID,
+ AEDescList * resultingPropertyNames) ;
+extern OSAError
+OSASetHandler(
+ ComponentInstance scriptingComponent,
+ long modeFlags,
+ OSAID contextID,
+ const AEDesc * handlerName,
+ OSAID compiledScriptID) ;
+extern OSAError
+OSAGetHandler(
+ ComponentInstance scriptingComponent,
+ long modeFlags,
+ OSAID contextID,
+ const AEDesc * handlerName,
+ OSAID * resultingCompiledScriptID) ;
+extern OSAError
+OSAGetHandlerNames(
+ ComponentInstance scriptingComponent,
+ long modeFlags,
+ OSAID contextID,
+ AEDescList * resultingHandlerNames) ;
+extern OSAError
+OSAGetAppTerminology(
+ ComponentInstance scriptingComponent,
+ long modeFlags,
+ FSSpec * fileSpec,
+ short terminologyID,
+ Boolean * didLaunch,
+ AEDesc * terminologyList) ;
+extern OSAError
+OSAGetSysTerminology(
+ ComponentInstance scriptingComponent,
+ long modeFlags,
+ short terminologyID,
+ AEDesc * terminologyList) ;
+extern OSAError
+ASSetProperty(
+ ComponentInstance scriptingComponent,
+ OSAID contextID,
+ const AEDesc * variableName,
+ OSAID scriptValueID) ;
+extern OSAError
+ASGetProperty(
+ ComponentInstance scriptingComponent,
+ OSAID contextID,
+ const AEDesc * variableName,
+ OSAID * resultingScriptValueID) ;
+extern OSAError
+ASSetHandler(
+ ComponentInstance scriptingComponent,
+ OSAID contextID,
+ const AEDesc * handlerName,
+ OSAID compiledScriptID) ;
+extern OSAError
+ASGetHandler(
+ ComponentInstance scriptingComponent,
+ OSAID contextID,
+ const AEDesc * handlerName,
+ OSAID * resultingCompiledScriptID) ;
+extern OSAError
+ASGetAppTerminology(
+ ComponentInstance scriptingComponent,
+ FSSpec * fileSpec,
+ short terminologID,
+ Boolean * didLaunch,
+ AEDesc * terminologyList) ;
+}
+
+
+
+enum {
+ keyAETarget = 'targ',
+ keySubjectAttr = 'subj',
+ keyASReturning = 'Krtn',
+ kASAppleScriptSuite = 'ascr',
+ kASScriptEditorSuite = 'ToyS',
+ kASTypeNamesSuite = 'tpnm',
+ typeAETE = 'aete',
+ typeAEUT = 'aeut',
+ kGetAETE = 'gdte',
+ kGetAEUT = 'gdut',
+ kUpdateAEUT = 'udut',
+ kUpdateAETE = 'udte',
+ kCleanUpAEUT = 'cdut',
+ kASComment = 'cmnt',
+ kASLaunchEvent = 'noop',
+ keyScszResource = 'scsz',
+ typeScszResource = 'scsz',
+ kASSubroutineEvent = 'psbr',
+ keyASSubroutineName = 'snam',
+ kASPrepositionalSubroutine = 'psbr',
+ keyASPositionalArgs = 'parg'
+};
+
+enum {
+
+ keyAppHandledCoercion = 'idas'
+};
+
+enum {
+
+ kASStartLogEvent = 'log1',
+ kASStopLogEvent = 'log0',
+ kASCommentEvent = 'cmnt'
+};
+
+
+
+enum {
+
+ kASAdd = '+ ',
+ kASSubtract = '- ',
+ kASMultiply = '* ',
+ kASDivide = '/ ',
+ kASQuotient = 'div ',
+ kASRemainder = 'mod ',
+ kASPower = '^ ',
+ kASEqual = kAEEquals,
+ kASNotEqual = ' ',
+ kASGreaterThan = kAEGreaterThan,
+ kASGreaterThanOrEqual = kAEGreaterThanEquals,
+ kASLessThan = kAELessThan,
+ kASLessThanOrEqual = kAELessThanEquals,
+ kASComesBefore = 'cbfr',
+ kASComesAfter = 'cafr',
+ kASConcatenate = 'ccat',
+ kASStartsWith = kAEBeginsWith,
+ kASEndsWith = kAEEndsWith,
+ kASContains = kAEContains
+};
+
+enum {
+ kASAnd = kAEAND,
+ kASOr = kAEOR,
+ kASNot = kAENOT,
+ kASNegate = 'neg ',
+ keyASArg = 'arg '
+};
+
+enum {
+
+ kASErrorEventCode = 'err ',
+ kOSAErrorArgs = 'erra',
+ keyAEErrorObject = 'erob',
+ pLength = 'leng',
+ pReverse = 'rvse',
+ pRest = 'rest',
+ pInherits = 'c@#^',
+ pProperties = 'pALL',
+ keyASUserRecordFields = 'usrf',
+ typeUserRecordFields = typeAEList
+};
+
+
+enum {
+ keyASPrepositionAt = 'at ',
+ keyASPrepositionIn = 'in ',
+ keyASPrepositionFrom = 'from',
+ keyASPrepositionFor = 'for ',
+ keyASPrepositionTo = 'to ',
+ keyASPrepositionThru = 'thru',
+ keyASPrepositionThrough = 'thgh',
+ keyASPrepositionBy = 'by ',
+ keyASPrepositionOn = 'on ',
+ keyASPrepositionInto = 'into',
+ keyASPrepositionOnto = 'onto',
+ keyASPrepositionBetween = 'btwn',
+ keyASPrepositionAgainst = 'agst',
+ keyASPrepositionOutOf = 'outo',
+ keyASPrepositionInsteadOf = 'isto',
+ keyASPrepositionAsideFrom = 'asdf',
+ keyASPrepositionAround = 'arnd',
+ keyASPrepositionBeside = 'bsid',
+ keyASPrepositionBeneath = 'bnth',
+ keyASPrepositionUnder = 'undr'
+};
+
+enum {
+ keyASPrepositionOver = 'over',
+ keyASPrepositionAbove = 'abve',
+ keyASPrepositionBelow = 'belw',
+ keyASPrepositionApartFrom = 'aprt',
+ keyASPrepositionGiven = 'givn',
+ keyASPrepositionWith = 'with',
+ keyASPrepositionWithout = 'wout',
+ keyASPrepositionAbout = 'abou',
+ keyASPrepositionSince = 'snce',
+ keyASPrepositionUntil = 'till'
+};
+
+enum {
+
+ kDialectBundleResType = 'Dbdl',
+ cConstant = typeEnumerated,
+ cClassIdentifier = pClass,
+ cObjectBeingExamined = typeObjectBeingExamined,
+ cList = typeAEList,
+ cSmallReal = typeSMFloat,
+ cReal = typeFloat,
+ cRecord = typeAERecord,
+ cReference = cObjectSpecifier,
+ cUndefined = 'undf',
+ cMissingValue = 'msng',
+ cSymbol = 'symb',
+ cLinkedList = 'llst',
+ cVector = 'vect',
+ cEventIdentifier = 'evnt',
+ cKeyIdentifier = 'kyid',
+ cUserIdentifier = 'uid ',
+ cPreposition = 'prep',
+ cKeyForm = enumKeyForm,
+ cScript = 'scpt',
+ cHandler = 'hand',
+ cProcedure = 'proc'
+};
+
+enum {
+ cHandleBreakpoint = 'brak'
+};
+
+enum {
+ cClosure = 'clsr',
+ cRawData = 'rdat',
+ cStringClass = typeChar,
+ cNumber = 'nmbr',
+ cListElement = 'celm',
+ cListOrRecord = 'lr ',
+ cListOrString = 'ls ',
+ cListRecordOrString = 'lrs ',
+ cNumberOrString = 'ns ',
+ cNumberOrDateTime = 'nd ',
+ cNumberDateTimeOrString = 'nds ',
+ cAliasOrString = 'sf ',
+ cSeconds = 'scnd',
+ typeSound = 'snd ',
+ enumBooleanValues = 'boov',
+ kAETrue = typeTrue,
+ kAEFalse = typeFalse,
+ enumMiscValues = 'misc',
+ kASCurrentApplication = 'cura',
+ formUserPropertyID = 'usrp'
+};
+
+enum {
+ cString = cStringClass
+};
+
+enum {
+
+ pASIt = 'it ',
+ pASMe = 'me ',
+ pASResult = 'rslt',
+ pASSpace = 'spac',
+ pASReturn = 'ret ',
+ pASTab = 'tab ',
+ pASPi = 'pi ',
+ pASParent = 'pare',
+ kASInitializeEventCode = 'init',
+ pASPrintLength = 'prln',
+ pASPrintDepth = 'prdp',
+ pASTopLevelScript = 'ascr'
+};
+
+enum {
+
+ kAECase = 'case',
+ kAEDiacritic = 'diac',
+ kAEWhiteSpace = 'whit',
+ kAEHyphens = 'hyph',
+ kAEExpansion = 'expa',
+ kAEPunctuation = 'punc',
+ kAEZenkakuHankaku = 'zkhk',
+ kAESmallKana = 'skna',
+ kAEKataHiragana = 'hika',
+ kASConsiderReplies = 'rmte',
+ enumConsiderations = 'cons'
+};
+
+
+enum {
+ kAECaseConsiderMask = 0x00000001,
+ kAEDiacriticConsiderMask = 0x00000002,
+ kAEWhiteSpaceConsiderMask = 0x00000004,
+ kAEHyphensConsiderMask = 0x00000008,
+ kAEExpansionConsiderMask = 0x00000010,
+ kAEPunctuationConsiderMask = 0x00000020,
+ kASConsiderRepliesConsiderMask = 0x00000040,
+ kAECaseIgnoreMask = 0x00010000,
+ kAEDiacriticIgnoreMask = 0x00020000,
+ kAEWhiteSpaceIgnoreMask = 0x00040000,
+ kAEHyphensIgnoreMask = 0x00080000,
+ kAEExpansionIgnoreMask = 0x00100000,
+ kAEPunctuationIgnoreMask = 0x00200000,
+ kASConsiderRepliesIgnoreMask = 0x00400000,
+ enumConsidsAndIgnores = 'csig'
+};
+
+enum {
+ cCoercion = 'coec',
+ cCoerceUpperCase = 'txup',
+ cCoerceLowerCase = 'txlo',
+ cCoerceRemoveDiacriticals = 'txdc',
+ cCoerceRemovePunctuation = 'txpc',
+ cCoerceRemoveHyphens = 'txhy',
+ cCoerceOneByteToTwoByte = 'txex',
+ cCoerceRemoveWhiteSpace = 'txws',
+ cCoerceSmallKana = 'txsk',
+ cCoerceZenkakuhankaku = 'txze',
+ cCoerceKataHiragana = 'txkh',
+ cZone = 'zone',
+ cMachine = 'mach',
+ cAddress = 'addr',
+ cRunningAddress = 'radd',
+ cStorage = 'stor'
+};
+
+enum {
+
+ pASWeekday = 'wkdy',
+ pASMonth = 'mnth',
+ pASDay = 'day ',
+ pASYear = 'year',
+ pASTime = 'time',
+ pASDateString = 'dstr',
+ pASTimeString = 'tstr',
+ cMonth = pASMonth,
+ cJanuary = 'jan ',
+ cFebruary = 'feb ',
+ cMarch = 'mar ',
+ cApril = 'apr ',
+ cMay = 'may ',
+ cJune = 'jun ',
+ cJuly = 'jul ',
+ cAugust = 'aug ',
+ cSeptember = 'sep ',
+ cOctober = 'oct ',
+ cNovember = 'nov ',
+ cDecember = 'dec '
+};
+
+enum {
+
+ cWeekday = pASWeekday,
+ cSunday = 'sun ',
+ cMonday = 'mon ',
+ cTuesday = 'tue ',
+ cWednesday = 'wed ',
+ cThursday = 'thu ',
+ cFriday = 'fri ',
+ cSaturday = 'sat ',
+ pASQuote = 'quot',
+ pASSeconds = 'secs',
+ pASMinutes = 'min ',
+ pASHours = 'hour',
+ pASDays = 'days',
+ pASWeeks = 'week',
+ cWritingCodeInfo = 'citl',
+ pScriptCode = 'pscd',
+ pLangCode = 'plcd',
+ kASMagicTellEvent = 'tell',
+ kASMagicEndTellEvent = 'tend'
+};
+
+
+
+enum {
+ kAEFinderSuite = 'fndr'
+};
+
+
+
+
+
+
+enum {
+ kAECleanUp = 'fclu',
+ kAEEject = 'ejct',
+ kAEEmpty = 'empt',
+ kAEErase = 'fera',
+ kAEGestalt = 'gstl',
+ kAEPutAway = 'ptwy',
+ kAERebuildDesktopDB = 'rddb',
+ kAESync = 'fupd',
+ kAEInterceptOpen = 'fopn'
+};
+
+
+enum {
+ kAEDatabaseSuite = 'DATA',
+ kAESort = 'SORT'
+};
+enum {
+ cInternalFinderObject = 'obj '
+};
+
+
+
+
+
+enum {
+
+
+
+ cAliasFile = 'alia',
+ cApplicationFile = 'appf',
+ cControlPanelFile = 'ccdv',
+ cDeskAccessoryFile = 'dafi',
+ cDocumentFile = 'docf',
+ cFontFile = 'fntf',
+ cSoundFile = 'sndf',
+ cClippingFile = 'clpf',
+ cContainer = 'ctnr',
+ cDesktop = 'cdsk',
+ cSharableContainer = 'sctr',
+ cDisk = 'cdis',
+ cFolder = 'cfol',
+ cSuitcase = 'stcs',
+ cAccessorySuitcase = 'dsut',
+ cFontSuitcase = 'fsut',
+ cTrash = 'ctrs',
+ cDesktopPrinter = 'dskp',
+ cPackage = 'pack',
+ cContentSpace = 'dwnd',
+ cContainerWindow = 'cwnd',
+ cInfoWindow = 'iwnd',
+ cSharingWindow = 'swnd',
+ cStatusWindow = 'qwnd',
+ cClippingWindow = 'lwnd',
+ cPreferencesWindow = 'pwnd',
+ cDTPWindow = 'dtpw',
+ cProcess = 'prcs',
+ cAccessoryProcess = 'pcda',
+ cApplicationProcess = 'pcap',
+ cGroup = 'sgrp',
+ cUser = 'cuse',
+ cSharingPrivileges = 'priv',
+ cPreferences = 'cprf',
+ cLabel = 'clbl',
+ cSound = 'snd ',
+ cAliasList = 'alst',
+ cSpecialFolders = 'spfl',
+ cOnlineDisk = 'cods',
+ cOnlineLocalDisk = 'clds',
+ cOnlineRemoteDisk = 'crds',
+ cEntireContents = 'ects',
+ cIconFamily = 'ifam'
+};
+enum {
+
+ pComment = 'comt',
+ pContainer = cContainer,
+ pContentSpace = cContentSpace,
+ pCreationDateOld = 'crtd',
+ pCreationDate = 'ascd',
+ pDescription = 'dscr',
+ pDisk = cDisk,
+ pFolderOld = cFolder,
+ pFolder = 'asdr',
+ pIconBitmap = 'iimg',
+ pInfoWindow = cInfoWindow,
+ pKind = 'kind',
+ pLabelIndex = 'labi',
+ pModificationDateOld = 'modd',
+ pModificationDate = 'asmo',
+
+ pPhysicalSize = 'phys',
+ pPosition = 'posn',
+ pIsSelected = 'issl',
+ pSize = pPointSize,
+ pWindow = cWindow,
+ pPreferencesWindow = cPreferencesWindow
+};
+
+
+
+enum {
+ pFileCreator = 'fcrt',
+ pFileType = 'asty',
+ pFileTypeOld = 'fitp',
+ pIsLocked = 'aslk',
+ pIsLockedOld = 'islk',
+
+
+ pProductVersion = 'ver2'
+};
+
+
+
+enum {
+ pOriginalItem = 'orig'
+};
+
+
+enum {
+ pMinAppPartition = 'mprt',
+ pAppPartition = 'appt',
+ pSuggestedAppPartition = 'sprt',
+ pIsScriptable = 'isab'
+};
+
+
+enum {
+ pInternetLocation = 'iloc'
+};
+
+
+enum {
+ pSound = 'snd '
+};
+enum {
+ pShowFolderSize = 'sfsz',
+ pShowComment = 'scom',
+ pShowDate = 'sdat',
+ pShowCreationDate = 'scda',
+ pShowKind = 'sknd',
+ pShowLabel = 'slbl',
+ pShowSize = 'ssiz',
+ pShowVersion = 'svrs',
+ pSortDirection = 'sord',
+ pShowDiskInfo = 'sdin',
+ pListViewIconSize = 'lvis',
+ pGridIcons = 'fgrd',
+ pStaggerIcons = 'fstg',
+ pViewFont = 'vfnt',
+ pViewFontSize = 'vfsz'
+};
+
+
+enum {
+ pCompletelyExpanded = 'pexc',
+ pContainerWindow = cContainerWindow,
+ pEntireContents = cEntireContents,
+ pExpandable = 'pexa',
+ pExpanded = 'pexp',
+ pPreviousView = 'svew',
+ pView = 'pvew',
+ pIconSize = pListViewIconSize,
+ pKeepArranged = 'arrg',
+ pKeepArrangedBy = 'arby'
+};
+
+
+enum {
+ pStartupDisk = 'sdsk',
+ pTrash = 'trsh'
+};
+
+
+enum {
+ pOwner = 'sown',
+ pOwnerPrivileges = 'ownr',
+ pGroup = cGroup,
+ pGroupPrivileges = 'gppr',
+ pGuestPrivileges = 'gstp',
+ pArePrivilegesInherited = 'iprv',
+ pExported = 'sexp',
+ pMounted = 'smou',
+ pSharingProtection = 'spro',
+ pSharing = 'shar',
+ pSharingWindow = cSharingWindow
+};
+
+
+enum {
+ pCapacity = 'capa',
+ pEjectable = 'isej',
+ pFreeSpace = 'frsp',
+ pLocal = 'isrv',
+ pIsStartup = 'istd'
+};
+
+
+enum {
+ pWarnOnEmpty = 'warn'
+};
+
+
+enum {
+ pIsZoomedFull = 'zumf',
+ pIsPopup = 'drwr',
+ pIsPulledOpen = 'pull',
+ pIsCollapsed = 'wshd'
+};
+
+
+enum {
+ pObject = cObject
+};
+
+
+enum {
+ pSharableContainer = cSharableContainer
+};
+
+
+enum {
+ pInfoPanel = 'panl'
+};
+
+
+
+enum {
+ pFileShareOn = 'fshr',
+ pFileShareStartingUp = 'fsup',
+ pProgramLinkingOn = 'iac '
+};
+
+
+enum {
+
+
+ pShowModificationDate = pShowDate,
+ pUseRelativeDate = 'urdt',
+ pDelayBeforeSpringing = 'dela',
+ pSpringOpenFolders = 'sprg',
+ pUseShortMenus = 'usme',
+ pUseWideGrid = 'uswg',
+ pLabel1 = 'lbl1',
+ pLabel2 = 'lbl2',
+ pLabel3 = 'lbl3',
+ pLabel4 = 'lbl4',
+ pLabel5 = 'lbl5',
+ pLabel6 = 'lbl6',
+ pLabel7 = 'lbl7',
+ pDefaultIconViewIconSize = 'iisz',
+ pDefaultButtonViewIconSize = 'bisz',
+ pDefaultListViewIconSize = 'lisz',
+ pIconViewArrangement = 'iarr',
+ pButtonViewArrangement = 'barr'
+};
+
+
+
+
+
+enum {
+ pNoArrangement = 'narr',
+ pSnapToGridArrangement = 'grda',
+ pByNameArrangement = 'nama',
+ pByModificationDateArrangement = 'mdta',
+ pByCreationDateArrangement = 'cdta',
+ pBySizeArrangement = 'siza',
+ pByKindArrangement = 'kina',
+ pByLabelArrangement = 'laba'
+};
+
+
+
+
+enum {
+
+ pFile = cFile,
+
+
+
+ pPartitionSpaceUsed = 'pusd',
+
+ pLocalAndRemoteEvents = 'revt',
+ pHasScriptingTerminology = 'hscr'
+};
+
+
+enum {
+ pDeskAccessoryFile = cDeskAccessoryFile
+};
+
+
+enum {
+ pApplicationFile = cApplicationFile
+};
+enum {
+
+
+
+
+
+
+ pCanConnect = 'ccon',
+ pCanChangePassword = 'ccpw',
+ pCanDoProgramLinking = 'ciac',
+ pIsOwner = 'isow',
+ pARADialIn = 'arad',
+ pShouldCallBack = 'calb',
+ pCallBackNumber = 'cbnm'
+};
+
+
+
+
+
+enum {
+ pAboutMacintosh = 'abbx',
+ pAppleMenuItemsFolder = 'amnu',
+
+ pControlPanelsFolder = 'ctrl',
+ pDesktop = 'desk',
+ pExtensionsFolder = 'extn',
+
+ pFinderPreferences = 'pfrp',
+ pFontsFolder = 'font',
+ pFontsFolderPreAllegro = 'ffnt',
+
+
+ pLargestFreeBlock = 'mfre',
+ pPreferencesFolder = 'pref',
+
+
+
+ pShortCuts = 'scut',
+ pShutdownFolder = 'shdf',
+ pStartupItemsFolder = 'strt',
+ pSystemFolder = 'macs',
+ pTemporaryFolder = 'temp',
+
+ pViewPreferences = 'pvwp',
+ pStartingUp = 'awak'
+};
+
+
+enum {
+ pSeeFiles = 'prvr',
+ pSeeFolders = 'prvs',
+ pMakeChanges = 'prvw'
+};
+enum {
+ pSmallIcon = 'smic',
+ pSmallButton = 'smbu',
+ pLargeButton = 'lgbu',
+ pGrid = 'grid'
+};
+
+
+
+
+
+
+
+enum {
+ enumViewBy = 'vwby',
+ enumGestalt = 'gsen',
+ enumConflicts = 'cflc',
+ enumExistingItems = 'exsi',
+ enumOlderItems = 'oldr'
+};
+
+enum {
+ enumDate = 'enda',
+ enumAnyDate = 'anyd',
+ enumToday = 'tday',
+ enumYesterday = 'yday',
+ enumThisWeek = 'twek',
+ enumLastWeek = 'lwek',
+ enumThisMonth = 'tmon',
+ enumLastMonth = 'lmon',
+ enumThisYear = 'tyer',
+ enumLastYear = 'lyer',
+ enumBeforeDate = 'bfdt',
+ enumAfterDate = 'afdt',
+ enumBetweenDate = 'btdt',
+ enumOnDate = 'ondt'
+};
+
+enum {
+ enumAllDocuments = 'alld',
+ enumFolders = 'fold',
+ enumAliases = 'alia',
+ enumStationery = 'stat'
+};
+
+enum {
+ enumWhere = 'wher',
+ enumAllLocalDisks = 'aldk',
+ enumAllRemoteDisks = 'ardk',
+ enumAllDisks = 'alld',
+ enumAllOpenFolders = 'aofo'
+};
+
+
+enum {
+ enumIconSize = 'isiz',
+ enumSmallIconSize = pSmallIcon,
+ enumMiniIconSize = 'miic',
+ enumLargeIconSize = 'lgic'
+};
+
+enum {
+ enumSortDirection = 'sodr',
+ enumSortDirectionNormal = 'snrm',
+ enumSortDirectionReverse = 'srvs'
+};
+
+enum {
+ enumArrangement = 'earr'
+};
+
+
+enum {
+ enumInfoWindowPanel = 'ipnl',
+ enumGeneralPanel = 'gpnl',
+ enumSharingPanel = 'spnl',
+ enumStatusNConfigPanel = 'scnl',
+ enumFontsPanel = 'fpnl',
+ enumMemoryPanel = 'mpnl'
+};
+
+
+
+enum {
+ enumPrefsWindowPanel = 'pple',
+ enumPrefsGeneralPanel = 'pgnp',
+ enumPrefsLabelPanel = 'plbp',
+ enumPrefsIconViewPanel = 'pivp',
+ enumPrefsButtonViewPanel = 'pbvp',
+ enumPrefsListViewPanel = 'plvp'
+};
+
+
+
+
+
+
+
+enum {
+ typeIconFamily = cIconFamily,
+ typeIconAndMask = 'ICN#',
+ type8BitMask = 'l8mk',
+ type32BitIcon = 'il32',
+ type8BitIcon = 'icl8',
+ type4BitIcon = 'icl4',
+ typeSmallIconAndMask = 'ics#',
+ typeSmall8BitMask = 's8mk',
+ typeSmall32BitIcon = 'is32',
+ typeSmall8BitIcon = 'ics8',
+ typeSmall4BitIcon = 'ics4',
+ typeRelativeTime = 'rtim',
+ typeConceptualTime = 'timc'
+};
+
+
+
+
+
+
+
+enum {
+ keyIconAndMask = 'ICN#',
+ key32BitIcon = 'il32',
+ key8BitIcon = 'icl8',
+ key4BitIcon = 'icl4',
+ key8BitMask = 'l8mk',
+ keySmallIconAndMask = 'ics#',
+ keySmall8BitIcon = 'ics8',
+ keySmall4BitIcon = 'ics4',
+ keySmall32BitIcon = 'is32',
+ keySmall8BitMask = 's8mk',
+ keyMini1BitMask = 'icm#',
+ keyMini4BitIcon = 'icm4',
+ keyMini8BitIcon = 'icm8',
+ keyAEUsing = 'usin',
+ keyAEReplacing = 'alrp',
+ keyAENoAutoRouting = 'rout',
+ keyLocalPositionList = 'mvpl',
+ keyGlobalPositionList = 'mvpg',
+ keyRedirectedDocumentList = 'fpdl'
+};
+
+
+
+
+
+
+
+enum {
+ keyASPrepositionHas = 'has ',
+ keyAll = 'kyal',
+ keyOldFinderItems = 'fsel'
+};
+
+
+
+
+
+
+
+enum {
+ formAlias = typeAlias,
+ formCreator = pFileCreator
+};
+enum {
+ errFinderIsBusy = -15260,
+ errFinderWindowNotOpen = -15261,
+ errFinderCannotPutAway = -15262,
+ errFinderWindowMustBeIconView = -15263,
+ errFinderWindowMustBeListView = -15264,
+ errFinderCantMoveToDestination = -15265,
+ errFinderCantMoveSource = -15266,
+ errFinderCantOverwrite = -15267,
+ errFinderIncestuousMove = -15268,
+ errFinderCantMoveToAncestor = -15269,
+ errFinderCantUseTrashedItems = -15270,
+ errFinderItemAlreadyInDest = -15271,
+ errFinderUnknownUser = -15272,
+ errFinderSharePointsCantInherit = -15273,
+ errFinderWindowWrongType = -15274,
+ errFinderPropertyNowWindowBased = -15275,
+ errFinderAppFolderProtected = -15276,
+ errFinderSysFolderProtected = -15277,
+ errFinderBoundsWrong = -15278,
+ errAEValueOutOfRange = -15279,
+ errFinderPropertyDoesNotApply = -15280,
+ errFinderFileSharingMustBeOn = -15281,
+ errFinderMustBeActive = -15282,
+ errFinderVolumeNotFound = -15283,
+ errFinderLockedItemsInTrash = -15284,
+ errFinderOnlyLockedItemsInTrash = -15285,
+ errFinderProgramLinkingMustBeOn = -15286,
+ errFinderWindowMustBeButtonView = -15287,
+ errFinderBadPackageContents = -15288,
+ errFinderUnsupportedInsidePackages = -15289,
+ errFinderCorruptOpenFolderList = -15290,
+ errFinderNoInvisibleFiles = -15291,
+ errFinderCantDeleteImmediately = -15292,
+ errFinderLastReserved = -15379
+};
+
+
+
+enum {
+ kDigiHubEventClass = 'dhub'
+};
+
+
+
+enum {
+ kDigiHubMusicCD = 'aucd',
+ kDigiHubPictureCD = 'picd',
+ kDigiHubVideoDVD = 'vdvd',
+ kDigiHubBlankCD = 'bcd ',
+ kDigiHubBlankDVD = 'bdvd'
+};
+
+
+
+extern "C" {
+
+
+
+typedef void ( * PMItemProcPtr)(DialogRef theDialog, short item);
+typedef void ( * PMPrintDialogInitProcPtr)(PMPrintSettings printSettings, PMDialog *theDialog);
+typedef void ( * PMPageSetupDialogInitProcPtr)(PMPageFormat pageFormat, PMDialog *theDialog);
+typedef void ( * PMSheetDoneProcPtr)(PMPrintSession printSession, WindowRef documentWindow, Boolean accepted);
+typedef PMItemProcPtr PMItemUPP;
+typedef PMPrintDialogInitProcPtr PMPrintDialogInitUPP;
+typedef PMPageSetupDialogInitProcPtr PMPageSetupDialogInitUPP;
+typedef PMSheetDoneProcPtr PMSheetDoneUPP;
+extern PMItemUPP
+NewPMItemUPP(PMItemProcPtr userRoutine) ;
+extern PMPrintDialogInitUPP
+NewPMPrintDialogInitUPP(PMPrintDialogInitProcPtr userRoutine) ;
+extern PMPageSetupDialogInitUPP
+NewPMPageSetupDialogInitUPP(PMPageSetupDialogInitProcPtr userRoutine) ;
+extern PMSheetDoneUPP
+NewPMSheetDoneUPP(PMSheetDoneProcPtr userRoutine) ;
+extern void
+DisposePMItemUPP(PMItemUPP userUPP) ;
+extern void
+DisposePMPrintDialogInitUPP(PMPrintDialogInitUPP userUPP) ;
+extern void
+DisposePMPageSetupDialogInitUPP(PMPageSetupDialogInitUPP userUPP) ;
+extern void
+DisposePMSheetDoneUPP(PMSheetDoneUPP userUPP) ;
+extern void
+InvokePMItemUPP(
+ DialogRef theDialog,
+ short item,
+ PMItemUPP userUPP) ;
+extern void
+InvokePMPrintDialogInitUPP(
+ PMPrintSettings printSettings,
+ PMDialog * theDialog,
+ PMPrintDialogInitUPP userUPP) ;
+extern void
+InvokePMPageSetupDialogInitUPP(
+ PMPageFormat pageFormat,
+ PMDialog * theDialog,
+ PMPageSetupDialogInitUPP userUPP) ;
+extern void
+InvokePMSheetDoneUPP(
+ PMPrintSession printSession,
+ WindowRef documentWindow,
+ Boolean accepted,
+ PMSheetDoneUPP userUPP) ;
+extern OSStatus
+PMSessionBeginDocument(
+ PMPrintSession printSession,
+ PMPrintSettings printSettings,
+ PMPageFormat pageFormat) ;
+extern OSStatus
+PMSessionEndDocument(PMPrintSession printSession) ;
+extern OSStatus
+PMSessionBeginPage(
+ PMPrintSession printSession,
+ PMPageFormat pageFormat,
+ const PMRect * pageFrame) ;
+extern OSStatus
+PMSessionEndPage(PMPrintSession printSession) ;
+extern OSStatus
+PMSessionPageSetupDialog(
+ PMPrintSession printSession,
+ PMPageFormat pageFormat,
+ Boolean * accepted) ;
+extern OSStatus
+PMSessionPrintDialog(
+ PMPrintSession printSession,
+ PMPrintSettings printSettings,
+ PMPageFormat constPageFormat,
+ Boolean * accepted) ;
+extern OSStatus
+PMSessionPageSetupDialogInit(
+ PMPrintSession printSession,
+ PMPageFormat pageFormat,
+ PMDialog * newDialog) ;
+extern OSStatus
+PMSessionPrintDialogInit(
+ PMPrintSession printSession,
+ PMPrintSettings printSettings,
+ PMPageFormat constPageFormat,
+ PMDialog * newDialog) ;
+extern OSStatus
+PMSessionPrintDialogMain(
+ PMPrintSession printSession,
+ PMPrintSettings printSettings,
+ PMPageFormat constPageFormat,
+ Boolean * accepted,
+ PMPrintDialogInitUPP myInitProc) ;
+extern OSStatus
+PMSessionPageSetupDialogMain(
+ PMPrintSession printSession,
+ PMPageFormat pageFormat,
+ Boolean * accepted,
+ PMPageSetupDialogInitUPP myInitProc) ;
+extern OSStatus
+PMSessionUseSheets(
+ PMPrintSession printSession,
+ WindowRef documentWindow,
+ PMSheetDoneUPP sheetDoneProc) ;
+extern OSStatus
+PMGetDialogPtr(
+ PMDialog pmDialog,
+ DialogRef * theDialog) ;
+extern OSStatus
+PMGetModalFilterProc(
+ PMDialog pmDialog,
+ ModalFilterUPP * filterProc) ;
+extern OSStatus
+PMSetModalFilterProc(
+ PMDialog pmDialog,
+ ModalFilterUPP filterProc) ;
+extern OSStatus
+PMGetItemProc(
+ PMDialog pmDialog,
+ PMItemUPP * itemProc) ;
+extern OSStatus
+PMSetItemProc(
+ PMDialog pmDialog,
+ PMItemUPP itemProc) ;
+extern OSStatus
+PMGetDialogAccepted(
+ PMDialog pmDialog,
+ Boolean * process) ;
+extern OSStatus
+PMSetDialogAccepted(
+ PMDialog pmDialog,
+ Boolean process) ;
+extern OSStatus
+PMGetDialogDone(
+ PMDialog pmDialog,
+ Boolean * done) ;
+extern OSStatus
+PMSetDialogDone(
+ PMDialog pmDialog,
+ Boolean done) ;
+extern OSStatus
+PMSessionEnablePrinterPresets(
+ PMPrintSession session,
+ CFStringRef graphicsType) ;
+extern OSStatus
+PMSessionDisablePrinterPresets(PMPrintSession session) ;
+
+
+
+
+}
+
+
+
+extern "C" {
+
+
+
+typedef UInt32 NavAskSaveChangesAction;
+enum {
+
+ kNavSaveChangesClosingDocument = 1,
+ kNavSaveChangesQuittingApplication = 2,
+ kNavSaveChangesOther = 0
+};
+
+
+typedef UInt32 NavAskSaveChangesResult;
+enum {
+
+ kNavAskSaveChangesSave = 1,
+ kNavAskSaveChangesCancel = 2,
+ kNavAskSaveChangesDontSave = 3
+};
+
+
+typedef UInt32 NavAskDiscardChangesResult;
+enum {
+
+ kNavAskDiscardChanges = 1,
+ kNavAskDiscardChangesCancel = 2
+};
+
+
+typedef SInt16 NavFilterModes;
+enum {
+
+ kNavFilteringBrowserList = 0,
+ kNavFilteringFavorites = 1,
+ kNavFilteringRecents = 2,
+ kNavFilteringShortCutVolumes = 3,
+ kNavFilteringLocationPopup = 4
+};
+
+
+enum {
+ kNavFileOrFolderVersion = 1
+};
+
+struct NavFileOrFolderInfo {
+ UInt16 version;
+ Boolean isFolder;
+ Boolean visible;
+ UInt32 creationDate;
+ UInt32 modificationDate;
+ union {
+ struct {
+ Boolean locked;
+ Boolean resourceOpen;
+ Boolean dataOpen;
+ Boolean reserved1;
+ UInt32 dataSize;
+ UInt32 resourceSize;
+ FInfo finderInfo;
+ FXInfo finderXInfo;
+ } fileInfo;
+ struct {
+ Boolean shareable;
+ Boolean sharePoint;
+ Boolean mounted;
+ Boolean readable;
+ Boolean writeable;
+ Boolean reserved2;
+ UInt32 numberOfFiles;
+ DInfo finderDInfo;
+ DXInfo finderDXInfo;
+ OSType folderType;
+ OSType folderCreator;
+ char reserved3[206];
+ } folderInfo;
+
+ } fileAndFolder;
+};
+typedef struct NavFileOrFolderInfo NavFileOrFolderInfo;
+union NavEventDataInfo {
+ EventRecord * event;
+ void * param;
+};
+typedef union NavEventDataInfo NavEventDataInfo;
+struct NavEventData {
+ NavEventDataInfo eventDataParms;
+ SInt16 itemHit;
+};
+typedef struct NavEventData NavEventData;
+typedef struct __NavDialog* NavDialogRef;
+typedef UInt32 NavUserAction;
+enum {
+
+
+
+
+
+ kNavUserActionNone = 0,
+
+
+
+
+ kNavUserActionCancel = 1,
+
+
+
+
+ kNavUserActionOpen = 2,
+
+
+
+
+ kNavUserActionSaveAs = 3,
+
+
+
+
+
+ kNavUserActionChoose = 4,
+
+
+
+
+ kNavUserActionNewFolder = 5,
+
+
+
+
+ kNavUserActionSaveChanges = 6,
+
+
+
+
+ kNavUserActionDontSaveChanges = 7,
+
+
+
+
+
+ kNavUserActionDiscardChanges = 8,
+
+
+
+
+
+ kNavUserActionReviewDocuments = 9,
+
+
+
+
+
+ kNavUserActionDiscardDocuments = 10
+};
+
+
+
+enum {
+ kNavCBRecVersion = 1
+};
+struct NavCBRec {
+
+
+
+
+ UInt16 version;
+
+
+
+
+ NavDialogRef context;
+
+
+
+
+ WindowRef window;
+
+
+
+
+ Rect customRect;
+
+
+
+
+ Rect previewRect;
+
+
+
+
+ NavEventData eventData;
+
+
+
+
+
+ NavUserAction userAction;
+
+
+
+
+ char reserved[218];
+};
+typedef struct NavCBRec NavCBRec;
+typedef NavCBRec * NavCBRecPtr;
+
+
+
+
+
+
+
+typedef SInt32 NavEventCallbackMessage;
+enum {
+
+
+
+
+
+ kNavCBEvent = 0,
+
+
+
+
+
+
+
+ kNavCBCustomize = 1,
+
+
+
+
+
+
+ kNavCBStart = 2,
+
+
+
+
+ kNavCBTerminate = 3,
+
+
+
+
+
+
+ kNavCBAdjustRect = 4,
+
+
+
+
+
+
+
+ kNavCBNewLocation = 5,
+
+
+
+
+ kNavCBShowDesktop = 6,
+
+
+
+
+
+
+ kNavCBSelectEntry = 7,
+ kNavCBPopupMenuSelect = 8,
+
+
+
+
+ kNavCBAccept = 9,
+
+
+
+
+ kNavCBCancel = 10,
+
+
+
+
+
+
+ kNavCBAdjustPreview = 11,
+
+
+
+
+
+
+
+ kNavCBUserAction = 12,
+
+
+
+
+
+
+ kNavCBOpenSelection = (long)0x80000000
+};
+
+
+typedef void * NavCallBackUserData;
+
+typedef void ( * NavEventProcPtr)(NavEventCallbackMessage callBackSelector, NavCBRecPtr callBackParms, void *callBackUD);
+
+typedef Boolean ( * NavPreviewProcPtr)(NavCBRecPtr callBackParms, void *callBackUD);
+
+typedef Boolean ( * NavObjectFilterProcPtr)(AEDesc *theItem, void *info, void *callBackUD, NavFilterModes filterMode);
+typedef NavEventProcPtr NavEventUPP;
+typedef NavPreviewProcPtr NavPreviewUPP;
+typedef NavObjectFilterProcPtr NavObjectFilterUPP;
+extern NavEventUPP
+NewNavEventUPP(NavEventProcPtr userRoutine) ;
+extern NavPreviewUPP
+NewNavPreviewUPP(NavPreviewProcPtr userRoutine) ;
+extern NavObjectFilterUPP
+NewNavObjectFilterUPP(NavObjectFilterProcPtr userRoutine) ;
+extern void
+DisposeNavEventUPP(NavEventUPP userUPP) ;
+extern void
+DisposeNavPreviewUPP(NavPreviewUPP userUPP) ;
+extern void
+DisposeNavObjectFilterUPP(NavObjectFilterUPP userUPP) ;
+extern void
+InvokeNavEventUPP(
+ NavEventCallbackMessage callBackSelector,
+ NavCBRecPtr callBackParms,
+ void * callBackUD,
+ NavEventUPP userUPP) ;
+extern Boolean
+InvokeNavPreviewUPP(
+ NavCBRecPtr callBackParms,
+ void * callBackUD,
+ NavPreviewUPP userUPP) ;
+extern Boolean
+InvokeNavObjectFilterUPP(
+ AEDesc * theItem,
+ void * info,
+ void * callBackUD,
+ NavFilterModes filterMode,
+ NavObjectFilterUPP userUPP) ;
+
+typedef SInt32 NavCustomControlMessage;
+enum {
+ kNavCtlShowDesktop = 0,
+ kNavCtlSortBy = 1,
+ kNavCtlSortOrder = 2,
+ kNavCtlScrollHome = 3,
+ kNavCtlScrollEnd = 4,
+ kNavCtlPageUp = 5,
+ kNavCtlPageDown = 6,
+ kNavCtlGetLocation = 7,
+ kNavCtlSetLocation = 8,
+ kNavCtlGetSelection = 9,
+ kNavCtlSetSelection = 10,
+ kNavCtlShowSelection = 11,
+ kNavCtlOpenSelection = 12,
+ kNavCtlEjectVolume = 13,
+ kNavCtlNewFolder = 14,
+ kNavCtlCancel = 15,
+ kNavCtlAccept = 16,
+ kNavCtlIsPreviewShowing = 17,
+ kNavCtlAddControl = 18,
+ kNavCtlAddControlList = 19,
+ kNavCtlGetFirstControlID = 20,
+ kNavCtlSelectCustomType = 21,
+ kNavCtlSelectAllType = 22,
+ kNavCtlGetEditFileName = 23,
+ kNavCtlSetEditFileName = 24,
+ kNavCtlSelectEditFileName = 25,
+ kNavCtlBrowserSelectAll = 26,
+ kNavCtlGotoParent = 27,
+ kNavCtlSetActionState = 28,
+ kNavCtlBrowserRedraw = 29,
+ kNavCtlTerminate = 30
+};
+
+typedef UInt32 NavActionState;
+enum {
+ kNavNormalState = 0x00000000,
+ kNavDontOpenState = 0x00000001,
+ kNavDontSaveState = 0x00000002,
+ kNavDontChooseState = 0x00000004,
+ kNavDontNewFolderState = 0x00000010
+};
+
+typedef UInt16 NavPopupMenuItem;
+enum {
+ kNavAllKnownFiles = 0,
+ kNavAllReadableFiles = 1,
+ kNavAllFiles = 2
+};
+
+typedef UInt16 NavSortKeyField;
+enum {
+ kNavSortNameField = 0,
+ kNavSortDateField = 1
+};
+
+
+typedef UInt16 NavSortOrder;
+enum {
+ kNavSortAscending = 0,
+ kNavSortDescending = 1
+};
+
+
+typedef UInt32 NavDialogOptionFlags;
+enum {
+ kNavDefaultNavDlogOptions = 0x000000E4,
+ kNavNoTypePopup = 0x00000001,
+ kNavDontAutoTranslate = 0x00000002,
+ kNavDontAddTranslateItems = 0x00000004,
+ kNavAllFilesInPopup = 0x00000010,
+ kNavAllowStationery = 0x00000020,
+ kNavAllowPreviews = 0x00000040,
+ kNavAllowMultipleFiles = 0x00000080,
+ kNavAllowInvisibleFiles = 0x00000100,
+ kNavDontResolveAliases = 0x00000200,
+ kNavSelectDefaultLocation = 0x00000400,
+ kNavSelectAllReadableItem = 0x00000800,
+ kNavSupportPackages = 0x00001000,
+ kNavAllowOpenPackages = 0x00002000,
+ kNavDontAddRecents = 0x00004000,
+ kNavDontUseCustomFrame = 0x00008000,
+ kNavDontConfirmReplacement = 0x00010000,
+ kNavPreserveSaveFileExtension = 0x00020000
+};
+
+
+typedef UInt32 NavTranslationOptions;
+enum {
+ kNavTranslateInPlace = 0,
+ kNavTranslateCopy = 1
+};
+
+
+enum {
+ kNavMenuItemSpecVersion = 0
+};
+
+struct NavMenuItemSpec {
+ UInt16 version;
+ OSType menuCreator;
+ OSType menuType;
+ Str255 menuItemName;
+ char reserved[245];
+};
+typedef struct NavMenuItemSpec NavMenuItemSpec;
+typedef NavMenuItemSpec * NavMenuItemSpecArrayPtr;
+typedef NavMenuItemSpecArrayPtr * NavMenuItemSpecArrayHandle;
+typedef NavMenuItemSpecArrayPtr NavMenuItemSpecPtr;
+typedef NavMenuItemSpecArrayHandle NavMenuItemSpecHandle;
+enum {
+ kNavGenericSignature = '****'
+};
+
+struct NavTypeList {
+ OSType componentSignature;
+ short reserved;
+ short osTypeCount;
+ OSType osType[1];
+};
+typedef struct NavTypeList NavTypeList;
+typedef NavTypeList * NavTypeListPtr;
+typedef NavTypeListPtr * NavTypeListHandle;
+enum {
+ kNavDialogOptionsVersion = 0
+};
+
+struct NavDialogOptions {
+ UInt16 version;
+ NavDialogOptionFlags dialogOptionFlags;
+ Point location;
+ Str255 clientName;
+ Str255 windowTitle;
+ Str255 actionButtonLabel;
+ Str255 cancelButtonLabel;
+ Str255 savedFileName;
+ Str255 message;
+ UInt32 preferenceKey;
+ NavMenuItemSpecArrayHandle popupExtension;
+ char reserved[494];
+};
+typedef struct NavDialogOptions NavDialogOptions;
+enum {
+ kNavReplyRecordVersion = 2
+};
+struct NavReplyRecord {
+
+
+
+
+
+
+ UInt16 version;
+
+
+
+
+ Boolean validRecord;
+
+
+
+
+
+
+
+ Boolean replacing;
+
+
+
+
+
+ Boolean isStationery;
+
+
+
+
+
+ Boolean translationNeeded;
+ AEDescList selection;
+
+
+
+
+
+ ScriptCode keyScript;
+
+
+
+
+
+
+
+ FileTranslationSpecArrayHandle fileTranslation;
+
+
+
+
+ UInt32 reserved1;
+
+
+
+
+
+
+
+ CFStringRef saveFileName;
+ Boolean saveFileExtensionHidden;
+
+
+
+
+ UInt8 reserved2;
+
+
+
+
+ char reserved[225];
+};
+typedef struct NavReplyRecord NavReplyRecord;
+extern OSErr
+NavLoad(void);
+extern OSErr
+NavUnload(void);
+extern UInt32
+NavLibraryVersion(void) ;
+extern OSErr
+NavGetDefaultDialogOptions(NavDialogOptions * dialogOptions) ;
+extern OSErr
+NavGetFile(
+ AEDesc * defaultLocation,
+ NavReplyRecord * reply,
+ NavDialogOptions * dialogOptions,
+ NavEventUPP eventProc,
+ NavPreviewUPP previewProc,
+ NavObjectFilterUPP filterProc,
+ NavTypeListHandle typeList,
+ void * callBackUD) ;
+extern OSErr
+NavPutFile(
+ AEDesc * defaultLocation,
+ NavReplyRecord * reply,
+ NavDialogOptions * dialogOptions,
+ NavEventUPP eventProc,
+ OSType fileType,
+ OSType fileCreator,
+ void * callBackUD) ;
+extern OSErr
+NavAskSaveChanges(
+ NavDialogOptions * dialogOptions,
+ NavAskSaveChangesAction action,
+ NavAskSaveChangesResult * reply,
+ NavEventUPP eventProc,
+ void * callBackUD) ;
+extern OSErr
+NavCustomAskSaveChanges(
+ NavDialogOptions * dialogOptions,
+ NavAskSaveChangesResult * reply,
+ NavEventUPP eventProc,
+ void * callBackUD) ;
+extern OSErr
+NavAskDiscardChanges(
+ NavDialogOptions * dialogOptions,
+ NavAskDiscardChangesResult * reply,
+ NavEventUPP eventProc,
+ void * callBackUD) ;
+extern OSErr
+NavChooseFile(
+ AEDesc * defaultLocation,
+ NavReplyRecord * reply,
+ NavDialogOptions * dialogOptions,
+ NavEventUPP eventProc,
+ NavPreviewUPP previewProc,
+ NavObjectFilterUPP filterProc,
+ NavTypeListHandle typeList,
+ void * callBackUD) ;
+extern OSErr
+NavChooseFolder(
+ AEDesc * defaultLocation,
+ NavReplyRecord * reply,
+ NavDialogOptions * dialogOptions,
+ NavEventUPP eventProc,
+ NavObjectFilterUPP filterProc,
+ void * callBackUD) ;
+extern OSErr
+NavChooseVolume(
+ AEDesc * defaultSelection,
+ NavReplyRecord * reply,
+ NavDialogOptions * dialogOptions,
+ NavEventUPP eventProc,
+ NavObjectFilterUPP filterProc,
+ void * callBackUD) ;
+extern OSErr
+NavChooseObject(
+ AEDesc * defaultLocation,
+ NavReplyRecord * reply,
+ NavDialogOptions * dialogOptions,
+ NavEventUPP eventProc,
+ NavObjectFilterUPP filterProc,
+ void * callBackUD) ;
+extern OSErr
+NavNewFolder(
+ AEDesc * defaultLocation,
+ NavReplyRecord * reply,
+ NavDialogOptions * dialogOptions,
+ NavEventUPP eventProc,
+ void * callBackUD) ;
+extern OSErr
+NavTranslateFile(
+ NavReplyRecord * reply,
+ NavTranslationOptions howToTranslate) ;
+extern OSErr
+NavCompleteSave(
+ NavReplyRecord * reply,
+ NavTranslationOptions howToTranslate) ;
+extern OSErr
+NavCustomControl(
+ NavDialogRef dialog,
+ NavCustomControlMessage selector,
+ void * parms) ;
+extern OSErr
+NavCreatePreview(
+ AEDesc * theObject,
+ OSType previewDataType,
+ const void * previewData,
+ Size previewDataSize) ;
+extern OSErr
+NavDisposeReply(NavReplyRecord * reply) ;
+extern Boolean
+NavServicesCanRun(void);
+ inline Boolean NavServicesAvailable() { return true; }
+enum {
+ kNavDialogCreationOptionsVersion = 0
+};
+struct NavDialogCreationOptions {
+
+
+
+
+
+ UInt16 version;
+
+
+
+
+
+ NavDialogOptionFlags optionFlags;
+
+
+
+
+
+
+ Point location;
+ CFStringRef clientName;
+
+
+
+
+
+ CFStringRef windowTitle;
+
+
+
+
+
+ CFStringRef actionButtonLabel;
+
+
+
+
+
+ CFStringRef cancelButtonLabel;
+
+
+
+
+
+ CFStringRef saveFileName;
+
+
+
+
+
+
+ CFStringRef message;
+ UInt32 preferenceKey;
+
+
+
+
+
+
+ CFArrayRef popupExtension;
+
+
+
+
+
+
+
+ WindowModality modality;
+
+
+
+
+
+ WindowRef parentWindow;
+
+
+
+
+ char reserved[16];
+};
+typedef struct NavDialogCreationOptions NavDialogCreationOptions;
+extern OSStatus
+NavGetDefaultDialogCreationOptions(NavDialogCreationOptions * outOptions) ;
+extern OSStatus
+NavCreateGetFileDialog(
+ const NavDialogCreationOptions * inOptions,
+ NavTypeListHandle inTypeList,
+ NavEventUPP inEventProc,
+ NavPreviewUPP inPreviewProc,
+ NavObjectFilterUPP inFilterProc,
+ void * inClientData,
+ NavDialogRef * outDialog) ;
+extern OSStatus
+NavCreatePutFileDialog(
+ const NavDialogCreationOptions * inOptions,
+ OSType inFileType,
+ OSType inFileCreator,
+ NavEventUPP inEventProc,
+ void * inClientData,
+ NavDialogRef * outDialog) ;
+extern OSStatus
+NavCreateAskReviewDocumentsDialog(
+ const NavDialogCreationOptions * inOptions,
+ UInt32 inDocumentCount,
+ NavEventUPP inEventProc,
+ void * inClientData,
+ NavDialogRef * outDialog) ;
+extern OSStatus
+NavCreateAskSaveChangesDialog(
+ const NavDialogCreationOptions * inOptions,
+ NavAskSaveChangesAction inAction,
+ NavEventUPP inEventProc,
+ void * inClientData,
+ NavDialogRef * outDialog) ;
+extern OSStatus
+NavCreateAskDiscardChangesDialog(
+ const NavDialogCreationOptions * inOptions,
+ NavEventUPP inEventProc,
+ void * inClientData,
+ NavDialogRef * outDialog) ;
+extern OSStatus
+NavCreateChooseFileDialog(
+ const NavDialogCreationOptions * inOptions,
+ NavTypeListHandle inTypeList,
+ NavEventUPP inEventProc,
+ NavPreviewUPP inPreviewProc,
+ NavObjectFilterUPP inFilterProc,
+ void * inClientData,
+ NavDialogRef * outDialog) ;
+extern OSStatus
+NavCreateChooseFolderDialog(
+ const NavDialogCreationOptions * inOptions,
+ NavEventUPP inEventProc,
+ NavObjectFilterUPP inFilterProc,
+ void * inClientData,
+ NavDialogRef * outDialog) ;
+extern OSStatus
+NavCreateChooseVolumeDialog(
+ const NavDialogCreationOptions * inOptions,
+ NavEventUPP inEventProc,
+ NavObjectFilterUPP inFilterProc,
+ void * inClientData,
+ NavDialogRef * outDialog) ;
+extern OSStatus
+NavCreateChooseObjectDialog(
+ const NavDialogCreationOptions * inOptions,
+ NavEventUPP inEventProc,
+ NavPreviewUPP inPreviewProc,
+ NavObjectFilterUPP inFilterProc,
+ void * inClientData,
+ NavDialogRef * outDialog) ;
+extern OSStatus
+NavCreateNewFolderDialog(
+ const NavDialogCreationOptions * inOptions,
+ NavEventUPP inEventProc,
+ void * inClientData,
+ NavDialogRef * outDialog) ;
+extern OSStatus
+NavDialogRun(NavDialogRef inDialog) ;
+extern void
+NavDialogDispose(NavDialogRef inDialog) ;
+extern WindowRef
+NavDialogGetWindow(NavDialogRef inDialog) ;
+extern NavUserAction
+NavDialogGetUserAction(NavDialogRef inDialog) ;
+extern OSStatus
+NavDialogGetReply(
+ NavDialogRef inDialog,
+ NavReplyRecord * outReply) ;
+extern CFStringRef
+NavDialogGetSaveFileName(NavDialogRef inPutFileDialog) ;
+extern OSStatus
+NavDialogSetSaveFileName(
+ NavDialogRef inPutFileDialog,
+ CFStringRef inFileName) ;
+extern Boolean
+NavDialogGetSaveFileExtensionHidden(NavDialogRef inPutFileDialog) ;
+extern OSStatus
+NavDialogSetSaveFileExtensionHidden(
+ NavDialogRef inPutFileDialog,
+ Boolean inHidden) ;
+
+
+
+
+
+
+}
+
+
+
+extern "C" {
+
+
+
+enum {
+
+ kMaximumSmallFract = 0x0000FFFF
+};
+
+enum {
+ kDefaultColorPickerWidth = 383,
+ kDefaultColorPickerHeight = 238
+};
+
+typedef SInt16 DialogPlacementSpec;
+enum {
+ kAtSpecifiedOrigin = 0,
+ kDeepestColorScreen = 1,
+ kCenterOnMainScreen = 2
+};
+
+
+
+enum {
+ kColorPickerDialogIsMoveable = 1,
+ kColorPickerDialogIsModal = 2,
+ kColorPickerCanModifyPalette = 4,
+ kColorPickerCanAnimatePalette = 8,
+ kColorPickerAppIsColorSyncAware = 16,
+ kColorPickerInSystemDialog = 32,
+ kColorPickerInApplicationDialog = 64,
+ kColorPickerInPickerDialog = 128,
+ kColorPickerDetachedFromChoices = 256,
+ kColorPickerCallColorProcLive = 512
+};
+typedef unsigned short SmallFract;
+
+
+
+
+struct HSVColor {
+ SmallFract hue;
+ SmallFract saturation;
+ SmallFract value;
+};
+typedef struct HSVColor HSVColor;
+struct HSLColor {
+ SmallFract hue;
+ SmallFract saturation;
+ SmallFract lightness;
+};
+typedef struct HSLColor HSLColor;
+struct CMYColor {
+ SmallFract cyan;
+ SmallFract magenta;
+ SmallFract yellow;
+};
+typedef struct CMYColor CMYColor;
+struct PMColor {
+ CMProfileHandle profile;
+ CMColor color;
+};
+typedef struct PMColor PMColor;
+typedef PMColor * PMColorPtr;
+struct NPMColor {
+ CMProfileRef profile;
+ CMColor color;
+};
+typedef struct NPMColor NPMColor;
+typedef NPMColor * NPMColorPtr;
+typedef struct OpaquePicker* Picker;
+typedef Picker picker;
+struct PickerMenuItemInfo {
+ short editMenuID;
+ short cutItem;
+ short copyItem;
+ short pasteItem;
+ short clearItem;
+ short undoItem;
+};
+typedef struct PickerMenuItemInfo PickerMenuItemInfo;
+
+
+
+
+typedef void ( * ColorChangedProcPtr)(long userData, PMColor *newColor);
+typedef void ( * NColorChangedProcPtr)(long userData, NPMColor *newColor);
+typedef Boolean ( * UserEventProcPtr)(EventRecord * event);
+typedef ColorChangedProcPtr ColorChangedUPP;
+typedef NColorChangedProcPtr NColorChangedUPP;
+typedef UserEventProcPtr UserEventUPP;
+struct ColorPickerInfo {
+ PMColor theColor;
+ CMProfileHandle dstProfile;
+ UInt32 flags;
+ DialogPlacementSpec placeWhere;
+ Point dialogOrigin;
+ OSType pickerType;
+ UserEventUPP eventProc;
+ ColorChangedUPP colorProc;
+ UInt32 colorProcData;
+ Str255 prompt;
+ PickerMenuItemInfo mInfo;
+ Boolean newColorChosen;
+ SInt8 filler;
+};
+typedef struct ColorPickerInfo ColorPickerInfo;
+struct NColorPickerInfo {
+ NPMColor theColor;
+ CMProfileRef dstProfile;
+ UInt32 flags;
+ DialogPlacementSpec placeWhere;
+ Point dialogOrigin;
+ OSType pickerType;
+ UserEventUPP eventProc;
+ NColorChangedUPP colorProc;
+ UInt32 colorProcData;
+ Str255 prompt;
+ PickerMenuItemInfo mInfo;
+ Boolean newColorChosen;
+ UInt8 reserved;
+};
+typedef struct NColorPickerInfo NColorPickerInfo;
+extern SmallFract
+Fix2SmallFract(Fixed f);
+extern Fixed
+SmallFract2Fix(SmallFract s);
+extern void
+CMY2RGB(
+ const CMYColor * cColor,
+ RGBColor * rColor);
+extern void
+RGB2CMY(
+ const RGBColor * rColor,
+ CMYColor * cColor);
+extern void
+HSL2RGB(
+ const HSLColor * hColor,
+ RGBColor * rColor);
+extern void
+RGB2HSL(
+ const RGBColor * rColor,
+ HSLColor * hColor);
+extern void
+HSV2RGB(
+ const HSVColor * hColor,
+ RGBColor * rColor);
+extern void
+RGB2HSV(
+ const RGBColor * rColor,
+ HSVColor * hColor);
+extern Boolean
+GetColor(
+ Point where,
+ ConstStr255Param prompt,
+ const RGBColor * inColor,
+ RGBColor * outColor);
+extern OSErr
+PickColor(ColorPickerInfo * theColorInfo);
+extern OSErr
+NPickColor(NColorPickerInfo * theColorInfo);
+extern ColorChangedUPP
+NewColorChangedUPP(ColorChangedProcPtr userRoutine);
+extern NColorChangedUPP
+NewNColorChangedUPP(NColorChangedProcPtr userRoutine);
+extern UserEventUPP
+NewUserEventUPP(UserEventProcPtr userRoutine);
+extern void
+DisposeColorChangedUPP(ColorChangedUPP userUPP);
+extern void
+DisposeNColorChangedUPP(NColorChangedUPP userUPP);
+extern void
+DisposeUserEventUPP(UserEventUPP userUPP);
+extern void
+InvokeColorChangedUPP(
+ long userData,
+ PMColor * newColor,
+ ColorChangedUPP userUPP);
+extern void
+InvokeNColorChangedUPP(
+ long userData,
+ NPMColor * newColor,
+ NColorChangedUPP userUPP);
+extern Boolean
+InvokeUserEventUPP(
+ EventRecord * event,
+ UserEventUPP userUPP);
+
+
+
+
+
+}
+
+
+
+extern "C" {
+
+
+
+typedef void ( * CalibrateEventProcPtr)(EventRecord * event);
+typedef CalibrateEventProcPtr CalibrateEventUPP;
+
+
+
+enum {
+ kCalibratorNamePrefix = 'cali'
+};
+
+struct CalibratorInfo {
+ UInt32 dataSize;
+ CMDisplayIDType displayID;
+ UInt32 profileLocationSize;
+ CMProfileLocation * profileLocationPtr;
+ CalibrateEventUPP eventProc;
+ Boolean isGood;
+};
+typedef struct CalibratorInfo CalibratorInfo;
+typedef Boolean ( * CanCalibrateProcPtr)(CMDisplayIDType displayID, Str255 errMessage);
+typedef OSErr ( * CalibrateProcPtr)(CalibratorInfo * theInfo);
+typedef CanCalibrateProcPtr CanCalibrateUPP;
+typedef CalibrateProcPtr CalibrateUPP;
+extern CalibrateEventUPP
+NewCalibrateEventUPP(CalibrateEventProcPtr userRoutine) ;
+extern CanCalibrateUPP
+NewCanCalibrateUPP(CanCalibrateProcPtr userRoutine);
+extern CalibrateUPP
+NewCalibrateUPP(CalibrateProcPtr userRoutine);
+extern void
+DisposeCalibrateEventUPP(CalibrateEventUPP userUPP) ;
+extern void
+DisposeCanCalibrateUPP(CanCalibrateUPP userUPP);
+extern void
+DisposeCalibrateUPP(CalibrateUPP userUPP);
+extern void
+InvokeCalibrateEventUPP(
+ EventRecord * event,
+ CalibrateEventUPP userUPP) ;
+extern Boolean
+InvokeCanCalibrateUPP(
+ CMDisplayIDType displayID,
+ Str255 errMessage,
+ CanCalibrateUPP userUPP);
+extern OSErr
+InvokeCalibrateUPP(
+ CalibratorInfo * theInfo,
+ CalibrateUPP userUPP);
+extern OSErr
+CMCalibrateDisplay(CalibratorInfo * theInfo) ;
+
+
+
+
+
+
+}
+
+
+
+extern "C" {
+
+
+
+typedef UInt32 NSLDialogOptionFlags;
+enum {
+ kNSLDefaultNSLDlogOptions = 0x00000000,
+ kNSLNoURLTEField = 0x00000001,
+ kNSLAddServiceTypes = 0x00000002,
+ kNSLClientHandlesRecents = 0x00000004
+};
+
+
+struct NSLDialogOptions {
+ UInt16 version;
+ NSLDialogOptionFlags dialogOptionFlags;
+ Str255 windowTitle;
+ Str255 actionButtonLabel;
+ Str255 cancelButtonLabel;
+ Str255 message;
+};
+typedef struct NSLDialogOptions NSLDialogOptions;
+typedef Boolean ( * NSLURLFilterProcPtr)(char *url, Str255 displayString);
+
+typedef void ( * NSLEventProcPtr)(EventRecord *newEvent, void *userContext);
+typedef NSLURLFilterProcPtr NSLURLFilterUPP;
+typedef NSLEventProcPtr NSLEventUPP;
+extern NSLURLFilterUPP
+NewNSLURLFilterUPP(NSLURLFilterProcPtr userRoutine);
+extern NSLEventUPP
+NewNSLEventUPP(NSLEventProcPtr userRoutine);
+extern void
+DisposeNSLURLFilterUPP(NSLURLFilterUPP userUPP);
+extern void
+DisposeNSLEventUPP(NSLEventUPP userUPP);
+extern Boolean
+InvokeNSLURLFilterUPP(
+ char * url,
+ Str255 displayString,
+ NSLURLFilterUPP userUPP);
+extern void
+InvokeNSLEventUPP(
+ EventRecord * newEvent,
+ void * userContext,
+ NSLEventUPP userUPP);
+extern OSStatus
+NSLStandardGetURL(
+ NSLDialogOptions * dialogOptions,
+ NSLEventUPP eventProc,
+ void * eventProcContextPtr,
+ NSLURLFilterUPP filterProc,
+ char * serviceTypeList,
+ char ** userSelectedURL);
+extern OSStatus
+NSLGetDefaultDialogOptions(NSLDialogOptions * dialogOptions);
+extern char *
+NSLFreeURL(char * url);
+extern OSErr
+NSLSaveURLAliasToFolder(
+ OSType folderSelectorType,
+ const char * url,
+ const char * userFriendlyName);
+
+
+
+
+
+
+
+}
+
+
+
+
+
+
+
+extern "C" {
+
+
+enum {
+
+
+
+
+ kEventClassFont = 'font'
+};
+
+
+
+
+
+
+enum {
+
+
+
+
+
+
+
+ kHICommandShowHideFontPanel = 'shfp'
+};
+enum {
+
+
+
+
+
+ kEventFontPanelClosed = 1,
+ kEventFontSelection = 2
+};
+enum {
+ typeATSUFontID = typeUInt32,
+ typeATSUSize = typeFixed,
+ typeFMFontFamily = typeSInt16,
+ typeFMFontStyle = typeSInt16,
+ typeFMFontSize = typeSInt16,
+ typeFontColor = typeRGBColor,
+ kEventParamATSUFontID = 'auid',
+ kEventParamATSUFontSize = 'ausz',
+ kEventParamFMFontFamily = 'fmfm',
+ kEventParamFMFontStyle = 'fmst',
+ kEventParamFMFontSize = 'fmsz',
+ kEventParamFontColor = 'fclr'
+};
+enum {
+ fontPanelShowErr = -8880,
+ fontPanelSelectionStyleErr = -8881,
+ fontPanelFontSelectionQDStyleVersionErr = -8882
+};
+
+
+
+
+
+
+enum {
+ kFontSelectionATSUIType = 'astl',
+ kFontSelectionQDType = 'qstl'
+};
+
+
+
+
+
+enum {
+ kFontSelectionQDStyleVersionZero = 0
+};
+struct FontSelectionQDStyle {
+ UInt32 version;
+ FMFontFamilyInstance instance;
+ FMFontSize size;
+ Boolean hasColor;
+ UInt8 reserved;
+ RGBColor color;
+};
+typedef struct FontSelectionQDStyle FontSelectionQDStyle;
+typedef FontSelectionQDStyle * FontSelectionQDStylePtr;
+extern Boolean
+FPIsFontPanelVisible(void) ;
+extern OSStatus
+FPShowHideFontPanel(void) ;
+extern OSStatus
+SetFontInfoForSelection(
+ OSType iStyleType,
+ UInt32 iNumStyles,
+ void * iStyles,
+ HIObjectRef iFPEventTarget) ;
+
+
+
+
+
+}
+
+
+
+extern "C" {
+
+
+typedef struct OpaqueHRReference* HRReference;
+extern OSStatus
+HRGetHTMLRenderingLibVersion(NumVersion * returnVers) ;
+ inline Boolean HRHTMLRenderingLibAvailable() { return true; }
+
+
+
+
+
+enum {
+ kHRRendererHTML32Type = 'ht32'
+};
+extern OSStatus
+HRNewReference(
+ HRReference * hrRef,
+ OSType rendererType,
+ GrafPtr grafPtr) ;
+extern OSStatus
+HRNewReferenceInWindow(
+ HRReference * hrRef,
+ OSType rendererType,
+ WindowRef inWindowRef) ;
+extern OSStatus
+HRDisposeReference(HRReference hrRef) ;
+extern SInt32
+HRFreeMemory(Size inBytesNeeded) ;
+extern void
+HRScreenConfigurationChanged(void) ;
+extern Boolean
+HRIsHREvent(const EventRecord * eventRecord) ;
+extern OSStatus
+HRSetGrafPtr(
+ HRReference hrRef,
+ GrafPtr grafPtr) ;
+extern OSStatus
+HRSetWindowRef(
+ HRReference hrRef,
+ WindowRef windowRef) ;
+extern OSStatus
+HRSetEmbeddingControl(
+ HRReference hrRef,
+ ControlRef controlRef) ;
+extern OSStatus
+HRActivate(HRReference hrRef) ;
+extern OSStatus
+HRDeactivate(HRReference hrRef) ;
+extern OSStatus
+HRDraw(
+ HRReference hrRef,
+ RgnHandle updateRgnH) ;
+extern OSStatus
+HRDrawInPort(
+ HRReference hrRef,
+ RgnHandle updateRgnH,
+ CGrafPtr grafPtr) ;
+extern OSStatus
+HRSetRenderingRect(
+ HRReference hrRef,
+ const Rect * renderingRect) ;
+extern OSStatus
+HRGetRenderedImageSize(
+ HRReference hrRef,
+ Point * renderingSize) ;
+extern OSStatus
+HRGetRenderedImageSize32(
+ HRReference hrRef,
+ UInt32 * height,
+ UInt32 * width) ;
+extern OSStatus
+HRScrollToLocation(
+ HRReference hrRef,
+ Point * location) ;
+extern OSStatus
+HRScrollToImageLocation32(
+ HRReference hrRef,
+ SInt32 h,
+ SInt32 v) ;
+extern OSStatus
+HRForceQuickdraw(
+ HRReference hrRef,
+ Boolean forceQuickdraw) ;
+
+
+typedef SInt16 HRScrollbarState;
+enum {
+ eHRScrollbarOn = 0,
+ eHRScrollbarOff = 1,
+ eHRScrollbarAuto = 2
+};
+extern OSStatus
+HRSetScrollbarState(
+ HRReference hrRef,
+ HRScrollbarState hScrollbarState,
+ HRScrollbarState vScrollbarState) ;
+extern OSStatus
+HRSetDrawBorder(
+ HRReference hrRef,
+ Boolean drawBorder) ;
+extern OSStatus
+HRSetGrowboxCutout(
+ HRReference hrRef,
+ Boolean allowCutout) ;
+extern OSStatus
+HRGoToFile(
+ HRReference hrRef,
+ const FSSpec * fsspec,
+ Boolean addToHistory,
+ Boolean forceRefresh) ;
+extern OSStatus
+HRGoToURL(
+ HRReference hrRef,
+ const char * url,
+ Boolean addToHistory,
+ Boolean forceRefresh) ;
+extern OSStatus
+HRGoToAnchor(
+ HRReference hrRef,
+ const char * anchorName) ;
+extern OSStatus
+HRGoToPtr(
+ HRReference hrRef,
+ char * buffer,
+ UInt32 bufferSize,
+ Boolean addToHistory,
+ Boolean forceRefresh) ;
+extern OSStatus
+HRGoToFSRef(
+ HRReference hrRef,
+ const FSRef * fref,
+ Boolean addToHistory,
+ Boolean forceRefresh) ;
+extern OSStatus
+HRGoToCFURL(
+ HRReference hrRef,
+ CFURLRef url,
+ Boolean addToHistory,
+ Boolean forceRefresh) ;
+extern OSStatus
+HRGoToAnchorCFString(
+ HRReference hrRef,
+ CFStringRef anchorName) ;
+extern OSStatus
+HRGoToData(
+ HRReference hrRef,
+ CFDataRef data,
+ Boolean addToHistory,
+ Boolean forceRefresh) ;
+extern OSStatus
+HRGetRootURL(
+ HRReference hrRef,
+ Handle rootURLH) ;
+extern OSStatus
+HRGetBaseURL(
+ HRReference hrRef,
+ Handle baseURLH) ;
+extern OSStatus
+HRGetHTMLURL(
+ HRReference hrRef,
+ Handle HTMLURLH) ;
+extern OSStatus
+HRGetTitle(
+ HRReference hrRef,
+ StringPtr title) ;
+extern OSStatus
+HRGetHTMLFile(
+ HRReference hrRef,
+ FSSpec * fsspec) ;
+extern OSStatus
+HRGetRootURLAsCFString(
+ HRReference hrRef,
+ CFStringRef * rootString) ;
+extern OSStatus
+HRGetBaseURLAsCFString(
+ HRReference hrRef,
+ CFStringRef * baseString) ;
+extern OSStatus
+HRGetHTMLURLAsCFURL(
+ HRReference hrRef,
+ CFURLRef * theURL) ;
+extern OSStatus
+HRGetTitleAsCFString(
+ HRReference hrRef,
+ CFStringRef * title) ;
+extern OSStatus
+HRGetHTMLFileAsFSRef(
+ HRReference hrRef,
+ FSRef * fref) ;
+extern OSStatus
+HRUtilCreateFullURL(
+ const char * rootURL,
+ const char * linkURL,
+ Handle fullURLH) ;
+extern OSStatus
+HRUtilGetFSSpecFromURL(
+ const char * rootURL,
+ const char * linkURL,
+ FSSpec * destSpec) ;
+extern OSStatus
+HRUtilGetURLFromFSSpec(
+ const FSSpec * fsspec,
+ Handle urlHandle) ;
+extern OSStatus
+HRUtilCreateFullCFURL(
+ CFStringRef rootString,
+ CFStringRef linkString,
+ CFURLRef * url) ;
+extern OSStatus
+HRUtilGetFSRefFromURL(
+ CFStringRef rootString,
+ CFStringRef linkString,
+ FSRef * destRef) ;
+extern OSStatus
+HRUtilGetURLFromFSRef(
+ const FSRef * fileRef,
+ CFURLRef * url) ;
+typedef Boolean ( * HRWasURLVisitedProcPtr)(const char *url, void *refCon);
+typedef HRWasURLVisitedProcPtr HRWasURLVisitedUPP;
+extern void
+HRRegisterWasURLVisitedUPP(
+ HRWasURLVisitedUPP inWasURLVisitedUPP,
+ HRReference hrRef,
+ void * inRefCon) ;
+extern void
+HRUnregisterWasURLVisitedUPP(HRReference hrRef) ;
+typedef Boolean ( * HRWasCFURLVisitedProcPtr)(CFURLRef url, void *refCon);
+typedef HRWasCFURLVisitedProcPtr HRWasCFURLVisitedUPP;
+extern void
+HRRegisterWasCFURLVisitedUPP(
+ HRWasCFURLVisitedUPP inWasCFURLVisitedUPP,
+ HRReference hrRef,
+ void * inRefCon) ;
+extern void
+HRUnregisterWasCFURLVisitedUPP(HRReference hrRef) ;
+typedef OSStatus ( * HRNewURLProcPtr)(const char *url, const char *targetFrame, Boolean addToHistory, void *refCon);
+typedef HRNewURLProcPtr HRNewURLUPP;
+extern void
+HRRegisterNewURLUPP(
+ HRNewURLUPP inNewURLUPP,
+ HRReference hrRef,
+ void * inRefCon) ;
+extern void
+HRUnregisterNewURLUPP(HRReference hrRef) ;
+typedef OSStatus ( * HRNewCFURLProcPtr)(CFURLRef url, CFStringRef targetString, Boolean addToHistory, void *refCon);
+typedef HRNewCFURLProcPtr HRNewCFURLUPP;
+extern void
+HRRegisterNewCFURLUPP(
+ HRNewCFURLUPP inURLUPP,
+ HRReference hrRef,
+ void * inRefCon) ;
+extern void
+HRUnregisterNewCFURLUPP(HRReference hrRef) ;
+typedef UInt16 URLSourceType;
+enum {
+ kHRLookingForHTMLSource = 1,
+ kHRLookingForImage = 2,
+ kHRLookingForEmbedded = 3,
+ kHRLookingForImageMap = 4,
+ kHRLookingForFrame = 5
+};
+
+typedef OSStatus ( * HRURLToFSSpecProcPtr)(const char *rootURL, const char *linkURL, FSSpec *fsspec, URLSourceType urlSourceType, void *refCon);
+typedef HRURLToFSSpecProcPtr HRURLToFSSpecUPP;
+extern void
+HRRegisterURLToFSSpecUPP(
+ HRURLToFSSpecUPP inURLToFSSpecUPP,
+ HRReference hrRef,
+ void * inRefCon) ;
+extern void
+HRUnregisterURLToFSSpecUPP(HRReference hrRef) ;
+typedef OSStatus ( * HRURLToFSRefProcPtr)(CFStringRef rootString, CFStringRef linkString, FSRef *fref, URLSourceType urlSourceType, void *refCon);
+typedef HRURLToFSRefProcPtr HRURLToFSRefUPP;
+extern void
+HRRegisterURLToFSRefUPP(
+ HRURLToFSRefUPP inURLToFSRefUPP,
+ HRReference hrRef,
+ void * inRefCon) ;
+extern void
+HRUnregisterURLToFSRefUPP(HRReference hrRef) ;
+extern HRWasURLVisitedUPP
+NewHRWasURLVisitedUPP(HRWasURLVisitedProcPtr userRoutine) ;
+extern HRWasCFURLVisitedUPP
+NewHRWasCFURLVisitedUPP(HRWasCFURLVisitedProcPtr userRoutine) ;
+extern HRNewURLUPP
+NewHRNewURLUPP(HRNewURLProcPtr userRoutine) ;
+extern HRNewCFURLUPP
+NewHRNewCFURLUPP(HRNewCFURLProcPtr userRoutine) ;
+extern HRURLToFSSpecUPP
+NewHRURLToFSSpecUPP(HRURLToFSSpecProcPtr userRoutine) ;
+extern HRURLToFSRefUPP
+NewHRURLToFSRefUPP(HRURLToFSRefProcPtr userRoutine) ;
+extern void
+DisposeHRWasURLVisitedUPP(HRWasURLVisitedUPP userUPP) ;
+extern void
+DisposeHRWasCFURLVisitedUPP(HRWasCFURLVisitedUPP userUPP) ;
+extern void
+DisposeHRNewURLUPP(HRNewURLUPP userUPP) ;
+extern void
+DisposeHRNewCFURLUPP(HRNewCFURLUPP userUPP) ;
+extern void
+DisposeHRURLToFSSpecUPP(HRURLToFSSpecUPP userUPP) ;
+extern void
+DisposeHRURLToFSRefUPP(HRURLToFSRefUPP userUPP) ;
+extern Boolean
+InvokeHRWasURLVisitedUPP(
+ const char * url,
+ void * refCon,
+ HRWasURLVisitedUPP userUPP) ;
+extern Boolean
+InvokeHRWasCFURLVisitedUPP(
+ CFURLRef url,
+ void * refCon,
+ HRWasCFURLVisitedUPP userUPP) ;
+extern OSStatus
+InvokeHRNewURLUPP(
+ const char * url,
+ const char * targetFrame,
+ Boolean addToHistory,
+ void * refCon,
+ HRNewURLUPP userUPP) ;
+extern OSStatus
+InvokeHRNewCFURLUPP(
+ CFURLRef url,
+ CFStringRef targetString,
+ Boolean addToHistory,
+ void * refCon,
+ HRNewCFURLUPP userUPP) ;
+extern OSStatus
+InvokeHRURLToFSSpecUPP(
+ const char * rootURL,
+ const char * linkURL,
+ FSSpec * fsspec,
+ URLSourceType urlSourceType,
+ void * refCon,
+ HRURLToFSSpecUPP userUPP) ;
+extern OSStatus
+InvokeHRURLToFSRefUPP(
+ CFStringRef rootString,
+ CFStringRef linkString,
+ FSRef * fref,
+ URLSourceType urlSourceType,
+ void * refCon,
+ HRURLToFSRefUPP userUPP) ;
+
+
+
+}
+
+
+
+extern "C" {
+
+
+
+
+enum {
+ kSRNotAvailable = -5100,
+ kSRInternalError = -5101,
+ kSRComponentNotFound = -5102,
+ kSROutOfMemory = -5103,
+ kSRNotASpeechObject = -5104,
+ kSRBadParameter = -5105,
+ kSRParamOutOfRange = -5106,
+ kSRBadSelector = -5107,
+ kSRBufferTooSmall = -5108,
+ kSRNotARecSystem = -5109,
+ kSRFeedbackNotAvail = -5110,
+ kSRCantSetProperty = -5111,
+ kSRCantGetProperty = -5112,
+ kSRCantSetDuringRecognition = -5113,
+ kSRAlreadyListening = -5114,
+ kSRNotListeningState = -5115,
+ kSRModelMismatch = -5116,
+ kSRNoClientLanguageModel = -5117,
+ kSRNoPendingUtterances = -5118,
+ kSRRecognitionCanceled = -5119,
+ kSRRecognitionDone = -5120,
+ kSROtherRecAlreadyModal = -5121,
+ kSRHasNoSubItems = -5122,
+ kSRSubItemNotFound = -5123,
+ kSRLanguageModelTooBig = -5124,
+ kSRAlreadyReleased = -5125,
+ kSRAlreadyFinished = -5126,
+ kSRWordNotFound = -5127,
+ kSRNotFinishedWithRejection = -5128,
+ kSRExpansionTooDeep = -5129,
+ kSRTooManyElements = -5130,
+ kSRCantAdd = -5131,
+ kSRSndInSourceDisconnected = -5132,
+ kSRCantReadLanguageObject = -5133,
+
+ kSRNotImplementedYet = -5199
+};
+
+
+
+typedef struct OpaqueSRSpeechObject* SRSpeechObject;
+typedef SRSpeechObject SRRecognitionSystem;
+typedef SRSpeechObject SRRecognizer;
+typedef SRSpeechObject SRSpeechSource;
+typedef SRSpeechSource SRRecognitionResult;
+typedef SRSpeechObject SRLanguageObject;
+typedef SRLanguageObject SRLanguageModel;
+typedef SRLanguageObject SRPath;
+typedef SRLanguageObject SRPhrase;
+typedef SRLanguageObject SRWord;
+
+typedef unsigned short SRSpeedSetting;
+
+typedef unsigned short SRRejectionLevel;
+
+
+
+struct SRCallBackStruct {
+ long what;
+ long message;
+ SRRecognizer instance;
+ OSErr status;
+ short flags;
+ long refCon;
+};
+typedef struct SRCallBackStruct SRCallBackStruct;
+
+typedef void ( * SRCallBackProcPtr)(SRCallBackStruct * param);
+typedef SRCallBackProcPtr SRCallBackUPP;
+extern SRCallBackUPP
+NewSRCallBackUPP(SRCallBackProcPtr userRoutine) ;
+extern void
+DisposeSRCallBackUPP(SRCallBackUPP userUPP) ;
+extern void
+InvokeSRCallBackUPP(
+ SRCallBackStruct * param,
+ SRCallBackUPP userUPP) ;
+
+struct SRCallBackParam {
+ SRCallBackUPP callBack;
+ long refCon;
+};
+typedef struct SRCallBackParam SRCallBackParam;
+
+enum {
+ kSRDefaultRecognitionSystemID = 0
+};
+
+
+enum {
+ kSRFeedbackAndListeningModes = 'fbwn',
+ kSRRejectedWord = 'rejq',
+ kSRCleanupOnClientExit = 'clup'
+};
+
+enum {
+ kSRNoFeedbackNoListenModes = 0,
+ kSRHasFeedbackHasListenModes = 1,
+ kSRNoFeedbackHasListenModes = 2
+};
+
+
+enum {
+ kSRDefaultSpeechSource = 0,
+ kSRLiveDesktopSpeechSource = 'dklv',
+ kSRCanned22kHzSpeechSource = 'ca22'
+};
+
+
+
+enum {
+ kSRNotifyRecognitionBeginning = 1L << 0,
+ kSRNotifyRecognitionDone = 1L << 1
+};
+
+
+
+enum {
+ kAESpeechSuite = 'sprc'
+};
+
+
+enum {
+ kAESpeechDone = 'srsd',
+ kAESpeechDetected = 'srbd'
+};
+
+
+enum {
+ keySRRecognizer = 'krec',
+ keySRSpeechResult = 'kspr',
+ keySRSpeechStatus = 'ksst'
+};
+
+
+enum {
+ typeSRRecognizer = 'trec',
+ typeSRSpeechResult = 'tspr'
+};
+
+
+
+enum {
+ kSRNotificationParam = 'noti',
+ kSRCallBackParam = 'call',
+ kSRSearchStatusParam = 'stat',
+ kSRAutoFinishingParam = 'afin',
+ kSRForegroundOnly = 'fgon',
+ kSRBlockBackground = 'blbg',
+ kSRBlockModally = 'blmd',
+ kSRWantsResultTextDrawn = 'txfb',
+ kSRWantsAutoFBGestures = 'dfbr',
+ kSRSoundInVolume = 'volu',
+ kSRReadAudioFSSpec = 'aurd',
+ kSRCancelOnSoundOut = 'caso',
+ kSRSpeedVsAccuracyParam = 'sped'
+};
+
+
+
+enum {
+ kSRUseToggleListen = 0,
+ kSRUsePushToTalk = 1
+};
+
+enum {
+ kSRListenKeyMode = 'lkmd',
+ kSRListenKeyCombo = 'lkey',
+ kSRListenKeyName = 'lnam',
+ kSRKeyWord = 'kwrd',
+ kSRKeyExpected = 'kexp'
+};
+
+
+enum {
+ kSRIdleRecognizer = 1L << 0,
+ kSRSearchInProgress = 1L << 1,
+ kSRSearchWaitForAllClients = 1L << 2,
+ kSRMustCancelSearch = 1L << 3,
+ kSRPendingSearch = 1L << 4
+};
+
+
+enum {
+ kSRTEXTFormat = 'TEXT',
+ kSRPhraseFormat = 'lmph',
+ kSRPathFormat = 'lmpt',
+ kSRLanguageModelFormat = 'lmfm'
+};
+
+
+enum {
+ kSRSpelling = 'spel',
+ kSRLMObjType = 'lmtp',
+ kSRRefCon = 'refc',
+ kSROptional = 'optl',
+ kSREnabled = 'enbl',
+ kSRRepeatable = 'rptb',
+ kSRRejectable = 'rjbl',
+
+ kSRRejectionLevel = 'rjct'
+};
+
+
+enum {
+ kSRLanguageModelType = 'lmob',
+ kSRPathType = 'path',
+ kSRPhraseType = 'phra',
+ kSRWordType = 'word'
+};
+
+
+enum {
+ kSRDefaultRejectionLevel = 50
+};
+extern OSErr
+SROpenRecognitionSystem(
+ SRRecognitionSystem * system,
+ OSType systemID) ;
+extern OSErr
+SRCloseRecognitionSystem(SRRecognitionSystem system) ;
+extern OSErr
+SRSetProperty(
+ SRSpeechObject srObject,
+ OSType selector,
+ const void * property,
+ Size propertyLen) ;
+extern OSErr
+SRGetProperty(
+ SRSpeechObject srObject,
+ OSType selector,
+ void * property,
+ Size * propertyLen) ;
+extern OSErr
+SRReleaseObject(SRSpeechObject srObject) ;
+extern OSErr
+SRGetReference(
+ SRSpeechObject srObject,
+ SRSpeechObject * newObjectRef) ;
+extern OSErr
+SRNewRecognizer(
+ SRRecognitionSystem system,
+ SRRecognizer * recognizer,
+ OSType sourceID) ;
+extern OSErr
+SRStartListening(SRRecognizer recognizer) ;
+extern OSErr
+SRStopListening(SRRecognizer recognizer) ;
+extern OSErr
+SRSetLanguageModel(
+ SRRecognizer recognizer,
+ SRLanguageModel languageModel) ;
+extern OSErr
+SRGetLanguageModel(
+ SRRecognizer recognizer,
+ SRLanguageModel * languageModel) ;
+extern OSErr
+SRContinueRecognition(SRRecognizer recognizer) ;
+extern OSErr
+SRCancelRecognition(SRRecognizer recognizer) ;
+extern OSErr
+SRIdle(void) ;
+extern OSErr
+SRNewLanguageModel(
+ SRRecognitionSystem system,
+ SRLanguageModel * model,
+ const void * name,
+ Size nameLength) ;
+extern OSErr
+SRNewPath(
+ SRRecognitionSystem system,
+ SRPath * path) ;
+extern OSErr
+SRNewPhrase(
+ SRRecognitionSystem system,
+ SRPhrase * phrase,
+ const void * text,
+ Size textLength) ;
+extern OSErr
+SRNewWord(
+ SRRecognitionSystem system,
+ SRWord * word,
+ const void * text,
+ Size textLength) ;
+extern OSErr
+SRPutLanguageObjectIntoHandle(
+ SRLanguageObject languageObject,
+ Handle lobjHandle) ;
+extern OSErr
+SRPutLanguageObjectIntoDataFile(
+ SRLanguageObject languageObject,
+ short fRefNum) ;
+extern OSErr
+SRNewLanguageObjectFromHandle(
+ SRRecognitionSystem system,
+ SRLanguageObject * languageObject,
+ Handle lObjHandle) ;
+extern OSErr
+SRNewLanguageObjectFromDataFile(
+ SRRecognitionSystem system,
+ SRLanguageObject * languageObject,
+ short fRefNum) ;
+extern OSErr
+SREmptyLanguageObject(SRLanguageObject languageObject) ;
+extern OSErr
+SRChangeLanguageObject(
+ SRLanguageObject languageObject,
+ const void * text,
+ Size textLength) ;
+extern OSErr
+SRAddLanguageObject(
+ SRLanguageObject base,
+ SRLanguageObject addon) ;
+extern OSErr
+SRAddText(
+ SRLanguageObject base,
+ const void * text,
+ Size textLength,
+ long refCon) ;
+extern OSErr
+SRRemoveLanguageObject(
+ SRLanguageObject base,
+ SRLanguageObject toRemove) ;
+extern OSErr
+SRCountItems(
+ SRSpeechObject container,
+ long * count) ;
+extern OSErr
+SRGetIndexedItem(
+ SRSpeechObject container,
+ SRSpeechObject * item,
+ long index) ;
+extern OSErr
+SRSetIndexedItem(
+ SRSpeechObject container,
+ SRSpeechObject item,
+ long index) ;
+extern OSErr
+SRRemoveIndexedItem(
+ SRSpeechObject container,
+ long index) ;
+extern OSErr
+SRDrawText(
+ SRRecognizer recognizer,
+ const void * dispText,
+ Size dispLength) ;
+extern OSErr
+SRDrawRecognizedText(
+ SRRecognizer recognizer,
+ const void * dispText,
+ Size dispLength) ;
+extern OSErr
+SRSpeakText(
+ SRRecognizer recognizer,
+ const void * speakText,
+ Size speakLength) ;
+extern OSErr
+SRSpeakAndDrawText(
+ SRRecognizer recognizer,
+ const void * text,
+ Size textLength) ;
+extern OSErr
+SRStopSpeech(SRRecognizer recognizer) ;
+extern Boolean
+SRSpeechBusy(SRRecognizer recognizer) ;
+extern OSErr
+SRProcessBegin(
+ SRRecognizer recognizer,
+ Boolean failed) ;
+extern OSErr
+SRProcessEnd(
+ SRRecognizer recognizer,
+ Boolean failed) ;
+
+
+
+
+
+
+
+}
+
+
+
+extern "C" {
+extern OSStatus
+KCAddAppleSharePassword(
+ AFPServerSignature * serverSignature,
+ StringPtr serverAddress,
+ StringPtr serverName,
+ StringPtr volumeName,
+ StringPtr accountName,
+ UInt32 passwordLength,
+ const void * passwordData,
+ KCItemRef * item) ;
+extern OSStatus
+KCAddInternetPassword(
+ StringPtr serverName,
+ StringPtr securityDomain,
+ StringPtr accountName,
+ UInt16 port,
+ OSType protocol,
+ OSType authType,
+ UInt32 passwordLength,
+ const void * passwordData,
+ KCItemRef * item) ;
+extern OSStatus
+KCAddInternetPasswordWithPath(
+ StringPtr serverName,
+ StringPtr securityDomain,
+ StringPtr accountName,
+ StringPtr path,
+ UInt16 port,
+ OSType protocol,
+ OSType authType,
+ UInt32 passwordLength,
+ const void * passwordData,
+ KCItemRef * item) ;
+extern OSStatus
+KCAddGenericPassword(
+ StringPtr serviceName,
+ StringPtr accountName,
+ UInt32 passwordLength,
+ const void * passwordData,
+ KCItemRef * item) ;
+extern OSStatus
+KCAddItem(KCItemRef item) ;
+extern OSStatus
+KCUnlock(
+ KCRef keychain,
+ StringPtr password) ;
+extern OSStatus
+KCCreateKeychain(
+ StringPtr password,
+ KCRef * keychain) ;
+extern OSStatus
+KCChangeSettings(KCRef keychain) ;
+extern OSStatus
+kcunlock(
+ KCRef keychain,
+ const char * password) ;
+extern OSStatus
+kccreatekeychain(
+ const char * password,
+ KCRef * keychain) ;
+extern OSStatus
+kcaddapplesharepassword(
+ AFPServerSignature * serverSignature,
+ const char * serverAddress,
+ const char * serverName,
+ const char * volumeName,
+ const char * accountName,
+ UInt32 passwordLength,
+ const void * passwordData,
+ KCItemRef * item) ;
+extern OSStatus
+kcaddinternetpassword(
+ const char * serverName,
+ const char * securityDomain,
+ const char * accountName,
+ UInt16 port,
+ OSType protocol,
+ OSType authType,
+ UInt32 passwordLength,
+ const void * passwordData,
+ KCItemRef * item) ;
+extern OSStatus
+kcaddinternetpasswordwithpath(
+ const char * serverName,
+ const char * securityDomain,
+ const char * accountName,
+ const char * path,
+ UInt16 port,
+ OSType protocol,
+ OSType authType,
+ UInt32 passwordLength,
+ const void * passwordData,
+ KCItemRef * item) ;
+extern OSStatus
+kcaddgenericpassword(
+ const char * serviceName,
+ const char * accountName,
+ UInt32 passwordLength,
+ const void * passwordData,
+ KCItemRef * item) ;
+}
+
+
+
+extern "C" {
+
+
+
+
+typedef struct OpaqueURLReference* URLReference;
+typedef UInt32 URLOpenFlags;
+enum {
+ kURLReplaceExistingFlag = 1 << 0,
+ kURLBinHexFileFlag = 1 << 1,
+ kURLExpandFileFlag = 1 << 2,
+ kURLDisplayProgressFlag = 1 << 3,
+ kURLDisplayAuthFlag = 1 << 4,
+ kURLUploadFlag = 1 << 5,
+ kURLIsDirectoryHintFlag = 1 << 6,
+ kURLDoNotTryAnonymousFlag = 1 << 7,
+ kURLDirectoryListingFlag = 1 << 8,
+ kURLExpandAndVerifyFlag = 1 << 9,
+ kURLNoAutoRedirectFlag = 1 << 10,
+ kURLDebinhexOnlyFlag = 1 << 11,
+ kURLDoNotDeleteOnErrorFlag = 1 << 12,
+
+
+ kURLResumeDownloadFlag = 1 << 13,
+
+
+ kURLReservedFlag = (unsigned long)(1 << 31)
+};
+
+typedef UInt32 URLState;
+enum {
+ kURLNullState = 0,
+ kURLInitiatingState = 1,
+ kURLLookingUpHostState = 2,
+ kURLConnectingState = 3,
+ kURLResourceFoundState = 4,
+ kURLDownloadingState = 5,
+ kURLDataAvailableState = 0x10 + kURLDownloadingState,
+ kURLTransactionCompleteState = 6,
+ kURLErrorOccurredState = 7,
+ kURLAbortingState = 8,
+ kURLCompletedState = 9,
+ kURLUploadingState = 10
+};
+
+typedef UInt32 URLEvent;
+enum {
+ kURLInitiatedEvent = kURLInitiatingState,
+ kURLResourceFoundEvent = kURLResourceFoundState,
+ kURLDownloadingEvent = kURLDownloadingState,
+ kURLAbortInitiatedEvent = kURLAbortingState,
+ kURLCompletedEvent = kURLCompletedState,
+ kURLErrorOccurredEvent = kURLErrorOccurredState,
+ kURLDataAvailableEvent = kURLDataAvailableState,
+ kURLTransactionCompleteEvent = kURLTransactionCompleteState,
+ kURLUploadingEvent = kURLUploadingState,
+ kURLSystemEvent = 29,
+ kURLPercentEvent = 30,
+ kURLPeriodicEvent = 31,
+ kURLPropertyChangedEvent = 32
+};
+
+typedef unsigned long URLEventMask;
+enum {
+ kURLInitiatedEventMask = 1 << (kURLInitiatedEvent - 1),
+ kURLResourceFoundEventMask = 1 << (kURLResourceFoundEvent - 1),
+ kURLDownloadingMask = 1 << (kURLDownloadingEvent - 1),
+ kURLUploadingMask = 1 << (kURLUploadingEvent - 1),
+ kURLAbortInitiatedMask = 1 << (kURLAbortInitiatedEvent - 1),
+ kURLCompletedEventMask = 1 << (kURLCompletedEvent - 1),
+ kURLErrorOccurredEventMask = 1 << (kURLErrorOccurredEvent - 1),
+ kURLDataAvailableEventMask = 1 << (kURLDataAvailableEvent - 1),
+ kURLTransactionCompleteEventMask = 1 << (kURLTransactionCompleteEvent - 1),
+ kURLSystemEventMask = 1 << (kURLSystemEvent - 1),
+ kURLPercentEventMask = 1 << (kURLPercentEvent - 1),
+ kURLPeriodicEventMask = 1 << (kURLPeriodicEvent - 1),
+ kURLPropertyChangedEventMask = 1 << (kURLPropertyChangedEvent - 1),
+ kURLAllBufferEventsMask = kURLDataAvailableEventMask + kURLTransactionCompleteEventMask,
+ kURLAllNonBufferEventsMask = kURLInitiatedEventMask + kURLDownloadingMask + kURLUploadingMask + kURLAbortInitiatedMask + kURLCompletedEventMask + kURLErrorOccurredEventMask + kURLPercentEventMask + kURLPeriodicEventMask + kURLPropertyChangedEventMask,
+ kURLAllEventsMask = (long)0xFFFFFFFF
+};
+
+
+struct URLCallbackInfo {
+ UInt32 version;
+ URLReference urlRef;
+ const char * property;
+ UInt32 currentSize;
+ EventRecord * systemEvent;
+};
+typedef struct URLCallbackInfo URLCallbackInfo;
+
+
+enum {
+ kUserNameAndPasswordFlag = 0x00000001
+};
+extern OSStatus
+URLGetURLAccessVersion(UInt32 * returnVers) ;
+ inline Boolean URLAccessAvailable() { return true; }
+
+
+
+
+
+typedef OSStatus ( * URLNotifyProcPtr)(void *userContext, URLEvent event, URLCallbackInfo *callbackInfo);
+typedef OSStatus ( * URLSystemEventProcPtr)(void *userContext, EventRecord *event);
+typedef URLNotifyProcPtr URLNotifyUPP;
+typedef URLSystemEventProcPtr URLSystemEventUPP;
+extern URLNotifyUPP
+NewURLNotifyUPP(URLNotifyProcPtr userRoutine) ;
+extern URLSystemEventUPP
+NewURLSystemEventUPP(URLSystemEventProcPtr userRoutine) ;
+extern void
+DisposeURLNotifyUPP(URLNotifyUPP userUPP) ;
+extern void
+DisposeURLSystemEventUPP(URLSystemEventUPP userUPP) ;
+extern OSStatus
+InvokeURLNotifyUPP(
+ void * userContext,
+ URLEvent event,
+ URLCallbackInfo * callbackInfo,
+ URLNotifyUPP userUPP) ;
+extern OSStatus
+InvokeURLSystemEventUPP(
+ void * userContext,
+ EventRecord * event,
+ URLSystemEventUPP userUPP) ;
+extern OSStatus
+URLSimpleDownload(
+ const char * url,
+ FSSpec * destination,
+ Handle destinationHandle,
+ URLOpenFlags openFlags,
+ URLSystemEventUPP eventProc,
+ void * userContext) ;
+extern OSStatus
+URLDownload(
+ URLReference urlRef,
+ FSSpec * destination,
+ Handle destinationHandle,
+ URLOpenFlags openFlags,
+ URLSystemEventUPP eventProc,
+ void * userContext) ;
+extern OSStatus
+URLSimpleUpload(
+ const char * url,
+ const FSSpec * source,
+ URLOpenFlags openFlags,
+ URLSystemEventUPP eventProc,
+ void * userContext) ;
+extern OSStatus
+URLUpload(
+ URLReference urlRef,
+ const FSSpec * source,
+ URLOpenFlags openFlags,
+ URLSystemEventUPP eventProc,
+ void * userContext) ;
+extern OSStatus
+URLNewReference(
+ const char * url,
+ URLReference * urlRef) ;
+extern OSStatus
+URLDisposeReference(URLReference urlRef) ;
+extern OSStatus
+URLOpen(
+ URLReference urlRef,
+ FSSpec * fileSpec,
+ URLOpenFlags openFlags,
+ URLNotifyUPP notifyProc,
+ URLEventMask eventRegister,
+ void * userContext) ;
+extern OSStatus
+URLAbort(URLReference urlRef) ;
+extern OSStatus
+URLGetDataAvailable(
+ URLReference urlRef,
+ Size * dataSize) ;
+extern OSStatus
+URLGetBuffer(
+ URLReference urlRef,
+ void ** buffer,
+ Size * bufferSize) ;
+extern OSStatus
+URLReleaseBuffer(
+ URLReference urlRef,
+ void * buffer) ;
+extern OSStatus
+URLGetProperty(
+ URLReference urlRef,
+ const char * property,
+ void * propertyBuffer,
+ Size bufferSize) ;
+extern OSStatus
+URLGetPropertySize(
+ URLReference urlRef,
+ const char * property,
+ Size * propertySize) ;
+extern OSStatus
+URLSetProperty(
+ URLReference urlRef,
+ const char * property,
+ void * propertyBuffer,
+ Size bufferSize) ;
+extern OSStatus
+URLGetCurrentState(
+ URLReference urlRef,
+ URLState * state) ;
+extern OSStatus
+URLGetError(
+ URLReference urlRef,
+ OSStatus * urlError) ;
+extern OSStatus
+URLIdle(void) ;
+extern OSStatus
+URLGetFileInfo(
+ StringPtr fName,
+ OSType * fType,
+ OSType * fCreator) ;
+
+
+
+
+
+}
+
+
+
+extern "C" {
+
+
+
+enum {
+ kAHInternalErr = -10790,
+ kAHInternetConfigPrefErr = -10791
+};
+
+
+typedef SInt16 AHTOCType;
+enum {
+ kAHTOCTypeUser = 0,
+ kAHTOCTypeDeveloper = 1
+};
+extern OSStatus
+AHSearch(
+ CFStringRef bookname,
+ CFStringRef query) ;
+extern OSStatus
+AHGotoMainTOC(AHTOCType toctype) ;
+extern OSStatus
+AHGotoPage(
+ CFStringRef bookname,
+ CFStringRef path,
+ CFStringRef anchor) ;
+extern OSStatus
+AHLookupAnchor(
+ CFStringRef bookname,
+ CFStringRef anchor) ;
+extern OSStatus
+AHRegisterHelpBook(const FSRef * appBundleRef) ;
+
+
+
+
+}
+
+
+
+extern "C" {
+
+
+
+typedef struct OpaqueICAObject* ICAObject;
+typedef struct OpaqueICAProperty* ICAProperty;
+typedef struct OpaqueICAConnectionID* ICAConnectionID;
+typedef struct OpaqueICAEventDataCookie* ICAEventDataCookie;
+typedef struct OpaqueICAScannerSessionID* ICAScannerSessionID;
+
+
+
+
+enum {
+ kICACommunicationErr = -9900,
+ kICADeviceNotFoundErr = -9901,
+ kICADeviceNotOpenErr = -9902,
+ kICAFileCorruptedErr = -9903,
+ kICAIOPendingErr = -9904,
+ kICAInvalidObjectErr = -9905,
+ kICAInvalidPropertyErr = -9906,
+ kICAIndexOutOfRangeErr = -9907,
+ kICAPropertyTypeNotFoundErr = -9908
+};
+
+
+enum {
+ kICADevice = 'icdv',
+ kICADeviceCamera = 'cmra',
+ kICADeviceScanner = 'scan',
+ kICADeviceMFP = 'mfp ',
+ kICAList = 'objl',
+ kICADirectory = 'dire',
+ kICAFile = 'file',
+ kICAFileImage = 'imag',
+ kICAFileMovie = 'moov',
+ kICAFileAudio = 'audo',
+ kICAFileFirmware = 'firm',
+ kICAFileOther = 'othe'
+};
+
+
+enum {
+ kICAProperty = 'prop',
+
+
+
+ kICAPropertyImageWidth = '0100',
+ kICAPropertyImageHeight = '0101',
+ kICAPropertyImageBitDepth = '0102',
+ kICAPropertyImageDPI = '011A',
+ kICAPropertyImageExposureTime = '829A',
+ kICAPropertyImageFNumber = '829D',
+ kICAPropertyImageDateOriginal = '9003',
+ kICAPropertyImageDateDigitized = '9004',
+ kICAPropertyImageShutterSpeed = '9201',
+ kICAPropertyImageAperture = '9202',
+ kICAPropertyImageFlash = '9209',
+ kICAPropertyColorSpace = 'A001',
+ kICAPropertyImageFilename = 'ifil',
+ kICAPropertyImageSize = 'isiz',
+ kICAPropertyImageData = 'idat',
+ kICAPropertyImageThumbnail = 'thum',
+ kICAPropertyColorSyncProfile = 'prof'
+};
+
+
+enum {
+ kICAMessageConnect = 'open',
+ kICAMessageDisconnect = 'clos',
+ kICAMessageReset = 'rese',
+ kICAMessageCheckDevice = 'chkd'
+};
+
+
+
+enum {
+ kICATypeUInt16 = 'ui16',
+ kICATypeUInt32 = 'ui32',
+ kICATypeUInt64 = 'ui64',
+ kICATypeSInt16 = 'si16',
+ kICATypeSInt32 = 'si32',
+ kICATypeSInt64 = 'si64',
+ kICATypeFixed = 'sing',
+ kICATypeBoolean = 'bool',
+ kICATypeString = 'TEXT',
+ kICATypeData = 'data',
+ kICATypeThumbnail = 'thum'
+};
+
+
+
+enum {
+ kICAFlagReadWriteAccess = 1L << 0,
+ kICAFlagReadAccess = 1L << 1
+};
+
+
+
+
+enum {
+ kICAEventCancelTransaction = 'ecnt',
+ kICAEventObjectAdded = 'eoba',
+ kICAEventObjectRemoved = 'eobr',
+ kICAEventStoreAdded = 'esta',
+ kICAEventStoreRemoved = 'estr',
+ kICAEventDeviceAdded = 'edea',
+ kICAEventDeviceRemoved = 'eder',
+ kICAEventDevicePropChanged = 'edpc',
+ kICAEventObjectInfoChanged = 'eoic',
+ kICAEventDeviceInfoChanged = 'edic',
+ kICAEventRequestObjectTransfer = 'erot',
+ kICAEventStoreFull = 'estf',
+ kICAEventDeviceReset = 'edvr',
+ kICAEventStorageInfoChanged = 'esic',
+ kICAEventCaptureComplete = 'ecpc',
+ kICAEventUnreportedStatus = 'eurs'
+};
+
+
+
+enum {
+ kICAStartAtBeginning = 0,
+ kICAEntireLength = -1
+};
+
+
+enum {
+ kDeleteAfterDownload = 0x00000001,
+ kCreateCustomIcon = 0x00000002,
+ kAddMetaDataToFinderComment = 0x00000004,
+ kAdjustCreationDate = 0x00000008,
+ kSetFileTypeAndCreator = 0x00000010,
+ kEmbedColorSyncProfile = 0x00000020,
+ kRotateImage = 0x00000040
+};
+
+
+enum {
+ kExtendedNotificationPB = 'extd',
+ kMessageGetEventData = 'mged',
+ kEventClassPTPStandard = 'PTPs',
+ kEventClassPTPVendor = 'PTPv'
+};
+
+
+
+
+struct ICAObjectInfo {
+ OSType objectType;
+ OSType objectSubtype;
+};
+typedef struct ICAObjectInfo ICAObjectInfo;
+
+
+struct ICAPropertyInfo {
+ OSType propertyType;
+ OSType dataType;
+ UInt32 dataSize;
+ UInt32 dataFlags;
+};
+typedef struct ICAPropertyInfo ICAPropertyInfo;
+
+
+struct ICAMessage {
+ OSType messageType;
+ UInt32 startByte;
+ void * dataPtr;
+ UInt32 dataSize;
+ OSType dataType;
+};
+typedef struct ICAMessage ICAMessage;
+
+
+struct ICAThumbnail {
+ UInt32 width;
+ UInt32 height;
+ UInt32 dataSize;
+ UInt8 data[1];
+};
+typedef struct ICAThumbnail ICAThumbnail;
+enum {
+ kICAPBVersion = 0x00010000
+};
+typedef struct ICAHeader ICAHeader;
+typedef void ( * ICACompletion)(ICAHeader * pb);
+
+
+
+
+
+struct ICAHeader {
+ OSErr err;
+ UInt32 refcon;
+};
+
+
+
+
+
+
+struct ICAGetChildCountPB {
+ ICAHeader header;
+ ICAObject object;
+ UInt32 count;
+};
+typedef struct ICAGetChildCountPB ICAGetChildCountPB;
+
+
+struct ICAGetNthChildPB {
+ ICAHeader header;
+ ICAObject parentObject;
+ UInt32 index;
+ ICAObject childObject;
+ ICAObjectInfo childInfo;
+};
+typedef struct ICAGetNthChildPB ICAGetNthChildPB;
+
+
+struct ICAGetObjectInfoPB {
+ ICAHeader header;
+ ICAObject object;
+ ICAObjectInfo objectInfo;
+};
+typedef struct ICAGetObjectInfoPB ICAGetObjectInfoPB;
+
+
+struct ICAGetParentOfObjectPB {
+ ICAHeader header;
+ ICAObject object;
+ ICAObject parentObject;
+ ICAObjectInfo parentInfo;
+};
+typedef struct ICAGetParentOfObjectPB ICAGetParentOfObjectPB;
+
+
+struct ICAGetRootOfObjectPB {
+ ICAHeader header;
+ ICAObject object;
+ ICAObject rootObject;
+ ICAObjectInfo rootInfo;
+};
+typedef struct ICAGetRootOfObjectPB ICAGetRootOfObjectPB;
+
+
+struct ICAGetObjectRefConPB {
+ ICAHeader header;
+ ICAObject object;
+ UInt32 objectRefCon;
+};
+typedef struct ICAGetObjectRefConPB ICAGetObjectRefConPB;
+
+
+struct ICASetObjectRefConPB {
+ ICAHeader header;
+ ICAObject object;
+ UInt32 objectRefCon;
+};
+typedef struct ICASetObjectRefConPB ICASetObjectRefConPB;
+
+
+
+
+
+struct ICAGetPropertyCountPB {
+ ICAHeader header;
+ ICAObject object;
+ UInt32 count;
+};
+typedef struct ICAGetPropertyCountPB ICAGetPropertyCountPB;
+
+
+struct ICAGetNthPropertyPB {
+ ICAHeader header;
+ ICAObject object;
+ UInt32 index;
+ ICAProperty property;
+ ICAPropertyInfo propertyInfo;
+};
+typedef struct ICAGetNthPropertyPB ICAGetNthPropertyPB;
+
+
+struct ICAGetPropertyByTypePB {
+ ICAHeader header;
+ ICAObject object;
+ OSType propertyType;
+ ICAProperty property;
+ ICAPropertyInfo propertyInfo;
+};
+typedef struct ICAGetPropertyByTypePB ICAGetPropertyByTypePB;
+
+
+struct ICAGetPropertyInfoPB {
+ ICAHeader header;
+ ICAProperty property;
+ ICAPropertyInfo propertyInfo;
+};
+typedef struct ICAGetPropertyInfoPB ICAGetPropertyInfoPB;
+
+
+struct ICAGetPropertyDataPB {
+ ICAHeader header;
+ ICAProperty property;
+ UInt32 startByte;
+ UInt32 requestedSize;
+ void * dataPtr;
+ UInt32 actualSize;
+ OSType dataType;
+};
+typedef struct ICAGetPropertyDataPB ICAGetPropertyDataPB;
+
+
+struct ICASetPropertyDataPB {
+ ICAHeader header;
+ ICAProperty property;
+ UInt32 startByte;
+ void * dataPtr;
+ UInt32 dataSize;
+ OSType dataType;
+};
+typedef struct ICASetPropertyDataPB ICASetPropertyDataPB;
+
+
+struct ICAGetParentOfPropertyPB {
+ ICAHeader header;
+ ICAProperty property;
+ ICAObject parentObject;
+ ICAObjectInfo parentInfo;
+};
+typedef struct ICAGetParentOfPropertyPB ICAGetParentOfPropertyPB;
+
+
+struct ICAGetRootOfPropertyPB {
+ ICAHeader header;
+ ICAProperty property;
+ ICAObject rootObject;
+ ICAObjectInfo rootInfo;
+};
+typedef struct ICAGetRootOfPropertyPB ICAGetRootOfPropertyPB;
+
+
+struct ICAGetPropertyRefConPB {
+ ICAHeader header;
+ ICAProperty property;
+ UInt32 propertyRefCon;
+};
+typedef struct ICAGetPropertyRefConPB ICAGetPropertyRefConPB;
+
+
+struct ICASetPropertyRefConPB {
+ ICAHeader header;
+ ICAProperty property;
+ UInt32 propertyRefCon;
+};
+typedef struct ICASetPropertyRefConPB ICASetPropertyRefConPB;
+
+
+
+
+
+struct ICAGetDeviceListPB {
+ ICAHeader header;
+ ICAObject object;
+};
+typedef struct ICAGetDeviceListPB ICAGetDeviceListPB;
+
+
+struct ICAObjectSendMessagePB {
+ ICAHeader header;
+ ICAObject object;
+ ICAMessage message;
+ UInt32 result;
+};
+typedef struct ICAObjectSendMessagePB ICAObjectSendMessagePB;
+
+
+struct ICARegisterEventNotificationPB {
+ ICAHeader header;
+ ICAObject object;
+ OSType notifyType;
+ ICACompletion notifyProc;
+};
+typedef struct ICARegisterEventNotificationPB ICARegisterEventNotificationPB;
+
+
+struct ICAExtendedRegisterEventNotificationPB {
+ ICAHeader header;
+ ICAObject object;
+ OSType extd;
+ ICACompletion notifyProc;
+
+ UInt32 rawEventType;
+ OSType eventType;
+ OSType eventClass;
+ UInt32 eventDataSize;
+ ICAEventDataCookie eventDataCookie;
+ ICAObject deviceObject;
+};
+typedef struct ICAExtendedRegisterEventNotificationPB ICAExtendedRegisterEventNotificationPB;
+
+
+struct ICADownloadFilePB {
+ ICAHeader header;
+ ICAObject object;
+ FSRef * dirFSRef;
+ UInt32 flags;
+ OSType fileType;
+ OSType fileCreator;
+ Fixed rotationAngle;
+ FSRef * fileFSRef;
+};
+typedef struct ICADownloadFilePB ICADownloadFilePB;
+
+
+struct ICACopyObjectPropertyDictionaryPB {
+ ICAHeader header;
+ ICAObject object;
+ CFDictionaryRef * theDict;
+};
+typedef struct ICACopyObjectPropertyDictionaryPB ICACopyObjectPropertyDictionaryPB;
+extern OSErr
+ICAGetChildCount(
+ ICAGetChildCountPB * pb,
+ ICACompletion completion) ;
+extern OSErr
+ICAGetNthChild(
+ ICAGetNthChildPB * pb,
+ ICACompletion completion) ;
+extern OSErr
+ICAGetObjectInfo(
+ ICAGetObjectInfoPB * pb,
+ ICACompletion completion) ;
+extern OSErr
+ICAGetParentOfObject(
+ ICAGetParentOfObjectPB * pb,
+ ICACompletion completion) ;
+extern OSErr
+ICAGetRootOfObject(
+ ICAGetRootOfObjectPB * pb,
+ ICACompletion completion) ;
+extern OSErr
+ICAGetObjectRefCon(
+ ICAGetObjectRefConPB * pb,
+ ICACompletion completion) ;
+extern OSErr
+ICASetObjectRefCon(
+ ICASetObjectRefConPB * pb,
+ ICACompletion completion) ;
+extern OSErr
+ICAGetPropertyCount(
+ ICAGetPropertyCountPB * pb,
+ ICACompletion completion) ;
+extern OSErr
+ICAGetNthProperty(
+ ICAGetNthPropertyPB * pb,
+ ICACompletion completion) ;
+extern OSErr
+ICAGetPropertyByType(
+ ICAGetPropertyByTypePB * pb,
+ ICACompletion completion) ;
+extern OSErr
+ICAGetPropertyInfo(
+ ICAGetPropertyInfoPB * pb,
+ ICACompletion completion) ;
+extern OSErr
+ICAGetPropertyData(
+ ICAGetPropertyDataPB * pb,
+ ICACompletion completion) ;
+extern OSErr
+ICASetPropertyData(
+ ICASetPropertyDataPB * pb,
+ ICACompletion completion) ;
+extern OSErr
+ICAGetParentOfProperty(
+ ICAGetParentOfPropertyPB * pb,
+ ICACompletion completion) ;
+extern OSErr
+ICAGetRootOfProperty(
+ ICAGetRootOfPropertyPB * pb,
+ ICACompletion completion) ;
+extern OSErr
+ICAGetPropertyRefCon(
+ ICAGetPropertyRefConPB * pb,
+ ICACompletion completion) ;
+extern OSErr
+ICASetPropertyRefCon(
+ ICASetPropertyRefConPB * pb,
+ ICACompletion completion) ;
+extern OSErr
+ICAGetDeviceList(
+ ICAGetDeviceListPB * pb,
+ ICACompletion completion) ;
+extern OSErr
+ICAObjectSendMessage(
+ ICAObjectSendMessagePB * pb,
+ ICACompletion completion) ;
+extern OSErr
+ICARegisterEventNotification(
+ ICARegisterEventNotificationPB * pb,
+ ICACompletion completion) ;
+extern OSErr
+ICADownloadFile(
+ ICADownloadFilePB * pb,
+ ICACompletion completion) ;
+extern OSErr
+ICACopyObjectPropertyDictionary(
+ ICACopyObjectPropertyDictionaryPB * pb,
+ ICACompletion completion) ;
+
+
+
+
+
+
+struct ICAScannerOpenSessionPB {
+ ICAHeader header;
+ ICAObject object;
+ ICAScannerSessionID sessionID;
+};
+typedef struct ICAScannerOpenSessionPB ICAScannerOpenSessionPB;
+
+
+struct ICAScannerCloseSessionPB {
+ ICAHeader header;
+ ICAScannerSessionID sessionID;
+};
+typedef struct ICAScannerCloseSessionPB ICAScannerCloseSessionPB;
+
+
+struct ICAScannerInitializePB {
+ ICAHeader header;
+ ICAScannerSessionID sessionID;
+};
+typedef struct ICAScannerInitializePB ICAScannerInitializePB;
+
+
+struct ICAScannerGetParametersPB {
+ ICAHeader header;
+ ICAScannerSessionID sessionID;
+ CFMutableDictionaryRef theDict;
+};
+typedef struct ICAScannerGetParametersPB ICAScannerGetParametersPB;
+
+
+struct ICAScannerSetParametersPB {
+ ICAHeader header;
+ ICAScannerSessionID sessionID;
+ CFMutableDictionaryRef theDict;
+};
+typedef struct ICAScannerSetParametersPB ICAScannerSetParametersPB;
+
+
+struct ICAScannerStatusPB {
+ ICAHeader header;
+ ICAScannerSessionID sessionID;
+ UInt32 status;
+};
+typedef struct ICAScannerStatusPB ICAScannerStatusPB;
+
+
+struct ICAScannerStartPB {
+ ICAHeader header;
+ ICAScannerSessionID sessionID;
+};
+typedef struct ICAScannerStartPB ICAScannerStartPB;
+extern OSErr
+ICAScannerOpenSession(
+ ICAScannerOpenSessionPB * pb,
+ ICACompletion completion) ;
+extern OSErr
+ICAScannerCloseSession(
+ ICAScannerCloseSessionPB * pb,
+ ICACompletion completion) ;
+extern OSErr
+ICAScannerInitialize(
+ ICAScannerInitializePB * pb,
+ ICACompletion completion) ;
+extern OSErr
+ICAScannerGetParameters(
+ ICAScannerGetParametersPB * pb,
+ ICACompletion completion) ;
+extern OSErr
+ICAScannerSetParameters(
+ ICAScannerSetParametersPB * pb,
+ ICACompletion completion) ;
+extern OSErr
+ICAScannerStatus(
+ ICAScannerStatusPB * pb,
+ ICACompletion completion) ;
+extern OSErr
+ICAScannerStart(
+ ICAScannerStartPB * pb,
+ ICACompletion completion) ;
+
+
+
+
+
+}
+
+
+
+extern "C" {
+
+
+typedef struct ICDHeader ICDHeader;
+typedef void ( * ICDCompletion)(ICDHeader * pb);
+
+
+
+struct ICDHeader {
+ OSErr err;
+ UInt32 refcon;
+};
+
+
+
+
+struct ICD_NewObjectPB {
+ ICDHeader header;
+
+ ICAObject parentObject;
+ ICAObjectInfo objectInfo;
+
+ ICAObject object;
+};
+typedef struct ICD_NewObjectPB ICD_NewObjectPB;
+struct ICD_DisposeObjectPB {
+ ICDHeader header;
+
+ ICAObject object;
+};
+typedef struct ICD_DisposeObjectPB ICD_DisposeObjectPB;
+
+
+
+struct ICD_NewPropertyPB {
+ ICDHeader header;
+
+ ICAObject object;
+ ICAPropertyInfo propertyInfo;
+
+ ICAProperty property;
+};
+typedef struct ICD_NewPropertyPB ICD_NewPropertyPB;
+struct ICD_DisposePropertyPB {
+ ICDHeader header;
+
+ ICAProperty property;
+};
+typedef struct ICD_DisposePropertyPB ICD_DisposePropertyPB;
+extern OSErr
+ICDNewObject(
+ ICD_NewObjectPB * pb,
+ ICDCompletion completion) ;
+extern OSErr
+ICDDisposeObject(
+ ICD_DisposeObjectPB * pb,
+ ICDCompletion completion) ;
+extern OSErr
+ICDNewProperty(
+ ICD_NewPropertyPB * pb,
+ ICDCompletion completion) ;
+extern OSErr
+ICDDisposeProperty(
+ ICD_DisposePropertyPB * pb,
+ ICDCompletion completion) ;
+
+
+
+
+
+
+
+
+
+}
+
+
+
+enum {
+
+
+
+ kICAPropertyCameraBatteryLevel = '5001',
+ kICAPropertyCameraFunctionalMode = '5002',
+ kICAPropertyCameraImageSize = '5003',
+ kICAPropertyCameraCompressionSetting = '5004',
+ kICAPropertyCameraWhiteBalance = '5005',
+ kICAPropertyCameraRGBGain = '5006',
+ kICAPropertyCameraFNumber = '5007',
+ kICAPropertyCameraFocalLength = '5008',
+ kICAPropertyCameraFocusDistance = '5009',
+ kICAPropertyCameraFocusMode = '500A',
+ kICAPropertyCameraExposureMeteringMode = '500B',
+ kICAPropertyCameraFlashMode = '500C',
+ kICAPropertyCameraExposureTime = '500D',
+ kICAPropertyCameraExposureProgramMode = '500E',
+ kICAPropertyCameraExposureIndex = '500F',
+ kICAPropertyCameraExposureBiasCompensation = '5010',
+ kICAPropertyCameraDateTime = '5011',
+ kICAPropertyCameraCaptureDelay = '5012',
+ kICAPropertyCameraStillCaptureMode = '5013',
+ kICAPropertyCameraContrast = '5014',
+ kICAPropertyCameraSharpness = '5015',
+ kICAPropertyCameraDigitalZoom = '5016',
+ kICAPropertyCameraEffectMode = '5017',
+ kICAPropertyCameraBurstNumber = '5018',
+ kICAPropertyCameraBurstInterval = '5019',
+ kICAPropertyCameraTimelapseNumber = '501A',
+ kICAPropertyCameraTimelapseInterval = '501B',
+ kICAPropertyCameraFocusMeteringMode = '501C'
+};
+
+enum {
+
+ kICAPropertyCameraStorageType = 'stor',
+ kICAPropertyCameraFilesystemType = 'fsys',
+ kICAPropertyCameraAccessCapability = 'acap',
+ kICAPropertyCameraMaxCapacity = 'maxc',
+ kICAPropertyCameraFreeSpaceInBytes = 'fres',
+ kICAPropertyCameraFreeSpaceInImages = 'frei',
+ kICAPropertyCameraStorageDescription = 'stod',
+ kICAPropertyCameraVolumeLabel = 'voll'
+};
+
+enum {
+
+ kICAPropertyCameraIcon = 'icon',
+ kICAPropertyCameraSupportedMessages = 'msgs'
+};
+
+enum {
+
+ kICAStorageFixedROM = 0x0001,
+ kICAStorageRemovableROM = 0x0002,
+ kICAStorageFixedRAM = 0x0003,
+ kICAStorageRemovableRAM = 0x0004
+};
+
+enum {
+
+ kICAFileystemGenericFlat = 0x0001,
+ kICAFileystemGenericHierarchical = 0x0002,
+ kICAFileystemDCF = 0x0003
+};
+
+enum {
+
+ kICAAccessReadWrite = 0x0000,
+ kICAAccessReadOnly = 0x0001,
+ kICAAccessReadOnlyWithObjectDeletion = 0x0002
+};
+
+enum {
+
+ kICAMessageCameraCaptureNewImage = 'ccni',
+ kICAMessageCameraDeleteOne = 'del1',
+ kICAMessageCameraDeleteAll = 'dela',
+ kICAMessageCameraSyncClock = 'sclk',
+ kICAMessageCameraUploadData = 'load'
+};
+
+
+extern double acos (double);
+extern double asin (double);
+extern double atan (double);
+extern double atan2 (double, double);
+extern double ceil (double);
+extern double cos (double);
+extern double cosh (double);
+extern double exp (double);
+extern double fabs (double);
+extern double floor (double);
+extern double fmod (double, double);
+extern double frexp (double, int *);
+extern double ldexp (double, int);
+extern double log10 (double);
+extern double log (double);
+extern double modf (double, double *);
+extern double pow (double, double);
+extern double sin (double);
+extern double sinh (double);
+extern double sqrt (double);
+extern double tan (double);
+extern double tanh (double);
+
+
+
+
+
+extern double acos (double);
+extern double asin (double);
+extern double atan (double);
+extern double atan2 (double, double);
+extern double ceil (double);
+extern double cos (double);
+extern double cosh (double);
+extern double exp (double);
+extern double fabs (double);
+extern double floor (double);
+extern double fmod (double, double);
+extern double frexp (double, int *);
+extern double ldexp (double, int);
+extern double log10 (double);
+extern double log (double);
+extern double modf (double, double *);
+extern double pow (double, double);
+extern double sin (double);
+extern double sinh (double);
+extern double sqrt (double);
+extern double tan (double);
+extern double tanh (double);
+
+
+enum {
+
+
+
+ kSCStatusOK = 0,
+ kSCStatusFailed = 1001,
+ kSCStatusInvalidArgument = 1002,
+ kSCStatusAccessError = 1003,
+
+
+
+ kSCStatusNoKey = 1004,
+ kSCStatusKeyExists = 1005,
+ kSCStatusLocked = 1006,
+ kSCStatusNeedLock = 1007,
+
+
+
+ kSCStatusNoStoreSession = 2001,
+ kSCStatusNoStoreServer = 2002,
+ kSCStatusNotifierActive = 2003,
+
+
+
+ kSCStatusNoPrefsSession = 3001,
+ kSCStatusPrefsBusy = 3002,
+ kSCStatusNoConfigFile = 3003,
+ kSCStatusNoLink = 3004,
+ kSCStatusStale = 3005,
+ kSCStatusMaxLink = 3006,
+
+
+
+ kSCStatusReachabilityUnknown = 4001,
+};
+
+
+
+extern "C" {
+void closelog (void);
+void openlog (const char *, int, int);
+int setlogmask (int);
+void syslog (int, const char *, ...);
+void vsyslog (int, const char *, __builtin_va_list);
+}
+
+
+
+extern double acos (double);
+extern double asin (double);
+extern double atan (double);
+extern double atan2 (double, double);
+extern double ceil (double);
+extern double cos (double);
+extern double cosh (double);
+extern double exp (double);
+extern double fabs (double);
+extern double floor (double);
+extern double fmod (double, double);
+extern double frexp (double, int *);
+extern double ldexp (double, int);
+extern double log10 (double);
+extern double log (double);
+extern double modf (double, double *);
+extern double pow (double, double);
+extern double sin (double);
+extern double sinh (double);
+extern double sqrt (double);
+extern double tan (double);
+extern double tanh (double);
+
+
+typedef const struct __SCDynamicStore * SCDynamicStoreRef;
+
+
+
+
+typedef struct {
+ CFIndex version;
+ void * info;
+ const void *(*retain)(const void *info);
+ void (*release)(const void *info);
+ CFStringRef (*copyDescription)(const void *info);
+} SCDynamicStoreContext;
+typedef void (*SCDynamicStoreCallBack) (
+ SCDynamicStoreRef store,
+ CFArrayRef changedKeys,
+ void *info
+ );
+
+
+extern "C" {
+
+
+
+
+
+CFTypeID
+SCDynamicStoreGetTypeID (void);
+SCDynamicStoreRef
+SCDynamicStoreCreate (
+ CFAllocatorRef allocator,
+ CFStringRef name,
+ SCDynamicStoreCallBack callout,
+ SCDynamicStoreContext *context
+ );
+CFRunLoopSourceRef
+SCDynamicStoreCreateRunLoopSource (
+ CFAllocatorRef allocator,
+ SCDynamicStoreRef store,
+ CFIndex order
+ );
+CFArrayRef
+SCDynamicStoreCopyKeyList (
+ SCDynamicStoreRef store,
+ CFStringRef pattern
+ );
+Boolean
+SCDynamicStoreAddValue (
+ SCDynamicStoreRef store,
+ CFStringRef key,
+ CFPropertyListRef value
+ );
+Boolean
+SCDynamicStoreAddTemporaryValue (
+ SCDynamicStoreRef store,
+ CFStringRef key,
+ CFPropertyListRef value
+ );
+CFPropertyListRef
+SCDynamicStoreCopyValue (
+ SCDynamicStoreRef store,
+ CFStringRef key
+ );
+CFDictionaryRef
+SCDynamicStoreCopyMultiple (
+ SCDynamicStoreRef store,
+ CFArrayRef keys,
+ CFArrayRef patterns
+ );
+Boolean
+SCDynamicStoreSetValue (
+ SCDynamicStoreRef store,
+ CFStringRef key,
+ CFPropertyListRef value
+ );
+Boolean
+SCDynamicStoreSetMultiple (
+ SCDynamicStoreRef store,
+ CFDictionaryRef keysToSet,
+ CFArrayRef keysToRemove,
+ CFArrayRef keysToNotify
+ );
+Boolean
+SCDynamicStoreRemoveValue (
+ SCDynamicStoreRef store,
+ CFStringRef key
+ );
+Boolean
+SCDynamicStoreNotifyValue (
+ SCDynamicStoreRef store,
+ CFStringRef key
+ );
+Boolean
+SCDynamicStoreSetNotificationKeys (
+ SCDynamicStoreRef store,
+ CFArrayRef keys,
+ CFArrayRef patterns
+ );
+CFArrayRef
+SCDynamicStoreCopyNotifiedKeys (
+ SCDynamicStoreRef store
+ );
+
+}
+
+
+extern double acos (double);
+extern double asin (double);
+extern double atan (double);
+extern double atan2 (double, double);
+extern double ceil (double);
+extern double cos (double);
+extern double cosh (double);
+extern double exp (double);
+extern double fabs (double);
+extern double floor (double);
+extern double fmod (double, double);
+extern double frexp (double, int *);
+extern double ldexp (double, int);
+extern double log10 (double);
+extern double log (double);
+extern double modf (double, double *);
+extern double pow (double, double);
+extern double sin (double);
+extern double sinh (double);
+extern double sqrt (double);
+extern double tan (double);
+extern double tanh (double);
+
+
+
+
+
+
+
+
+
+extern "C" {
+CFStringRef
+SCDynamicStoreKeyCreate (
+ CFAllocatorRef allocator,
+ CFStringRef fmt,
+ ...
+ );
+
+
+
+
+CFStringRef
+SCDynamicStoreKeyCreateNetworkGlobalEntity (
+ CFAllocatorRef allocator,
+ CFStringRef domain,
+ CFStringRef entity
+ );
+
+
+
+
+CFStringRef
+SCDynamicStoreKeyCreateNetworkInterface (
+ CFAllocatorRef allocator,
+ CFStringRef domain
+ );
+
+
+
+
+CFStringRef
+SCDynamicStoreKeyCreateNetworkInterfaceEntity (
+ CFAllocatorRef allocator,
+ CFStringRef domain,
+ CFStringRef ifname,
+ CFStringRef entity
+ );
+
+
+
+
+CFStringRef
+SCDynamicStoreKeyCreateNetworkServiceEntity (
+ CFAllocatorRef allocator,
+ CFStringRef domain,
+ CFStringRef serviceID,
+ CFStringRef entity
+ );
+CFStringRef
+SCDynamicStoreKeyCreateComputerName (
+ CFAllocatorRef allocator
+ );
+CFStringRef
+SCDynamicStoreKeyCreateConsoleUser (
+ CFAllocatorRef allocator
+ );
+CFStringRef
+SCDynamicStoreKeyCreateHostNames (
+ CFAllocatorRef allocator
+ );
+CFStringRef
+SCDynamicStoreKeyCreateLocation (
+ CFAllocatorRef allocator
+ );
+CFStringRef
+SCDynamicStoreKeyCreateProxies (
+ CFAllocatorRef allocator
+ );
+
+}
+
+
+extern double acos (double);
+extern double asin (double);
+extern double atan (double);
+extern double atan2 (double, double);
+extern double ceil (double);
+extern double cos (double);
+extern double cosh (double);
+extern double exp (double);
+extern double fabs (double);
+extern double floor (double);
+extern double fmod (double, double);
+extern double frexp (double, int *);
+extern double ldexp (double, int);
+extern double log10 (double);
+extern double log (double);
+extern double modf (double, double *);
+extern double pow (double, double);
+extern double sin (double);
+extern double sinh (double);
+extern double sqrt (double);
+extern double tan (double);
+extern double tanh (double);
+
+
+extern "C" {
+CFStringRef
+SCDynamicStoreCopyComputerName (
+ SCDynamicStoreRef store,
+ CFStringEncoding *nameEncoding
+ );
+CFStringRef
+SCDynamicStoreCopyConsoleUser (
+ SCDynamicStoreRef session,
+ uid_t *uid,
+ gid_t *gid
+ );
+CFStringRef
+SCDynamicStoreCopyLocalHostName (
+ SCDynamicStoreRef store
+ );
+CFStringRef
+SCDynamicStoreCopyLocation (
+ SCDynamicStoreRef store
+ );
+CFDictionaryRef
+SCDynamicStoreCopyProxies (
+ SCDynamicStoreRef store
+ );
+
+}
+
+
+
+
+extern double acos (double);
+extern double asin (double);
+extern double atan (double);
+extern double atan2 (double, double);
+extern double ceil (double);
+extern double cos (double);
+extern double cosh (double);
+extern double exp (double);
+extern double fabs (double);
+extern double floor (double);
+extern double fmod (double, double);
+extern double frexp (double, int *);
+extern double ldexp (double, int);
+extern double log10 (double);
+extern double log (double);
+extern double modf (double, double *);
+extern double pow (double, double);
+extern double sin (double);
+extern double sinh (double);
+extern double sqrt (double);
+extern double tan (double);
+extern double tanh (double);
+
+
+typedef const struct __SCPreferences * SCPreferencesRef;
+
+
+extern "C" {
+
+
+
+
+
+CFTypeID
+SCPreferencesGetTypeID (void);
+SCPreferencesRef
+SCPreferencesCreate (
+ CFAllocatorRef allocator,
+ CFStringRef name,
+ CFStringRef prefsID
+ );
+Boolean
+SCPreferencesLock (
+ SCPreferencesRef session,
+ Boolean wait
+ );
+Boolean
+SCPreferencesCommitChanges (
+ SCPreferencesRef session
+ );
+Boolean
+SCPreferencesApplyChanges (
+ SCPreferencesRef session
+ );
+Boolean
+SCPreferencesUnlock (
+ SCPreferencesRef session
+ );
+CFDataRef
+SCPreferencesGetSignature (
+ SCPreferencesRef session
+ );
+CFArrayRef
+SCPreferencesCopyKeyList (
+ SCPreferencesRef session
+ );
+CFPropertyListRef
+SCPreferencesGetValue (
+ SCPreferencesRef session,
+ CFStringRef key
+ );
+Boolean
+SCPreferencesAddValue (
+ SCPreferencesRef session,
+ CFStringRef key,
+ CFPropertyListRef value
+ );
+Boolean
+SCPreferencesSetValue (
+ SCPreferencesRef session,
+ CFStringRef key,
+ CFPropertyListRef value
+ );
+Boolean
+SCPreferencesRemoveValue (
+ SCPreferencesRef session,
+ CFStringRef key
+ );
+
+}
+
+
+extern double acos (double);
+extern double asin (double);
+extern double atan (double);
+extern double atan2 (double, double);
+extern double ceil (double);
+extern double cos (double);
+extern double cosh (double);
+extern double exp (double);
+extern double fabs (double);
+extern double floor (double);
+extern double fmod (double, double);
+extern double frexp (double, int *);
+extern double ldexp (double, int);
+extern double log10 (double);
+extern double log (double);
+extern double modf (double, double *);
+extern double pow (double, double);
+extern double sin (double);
+extern double sinh (double);
+extern double sqrt (double);
+extern double tan (double);
+extern double tanh (double);
+
+
+extern "C" {
+CFStringRef
+SCPreferencesPathCreateUniqueChild (
+ SCPreferencesRef session,
+ CFStringRef prefix
+ );
+CFDictionaryRef
+SCPreferencesPathGetValue (
+ SCPreferencesRef session,
+ CFStringRef path
+ );
+CFStringRef
+SCPreferencesPathGetLink (
+ SCPreferencesRef session,
+ CFStringRef path
+ );
+Boolean
+SCPreferencesPathSetValue (
+ SCPreferencesRef session,
+ CFStringRef path,
+ CFDictionaryRef value
+ );
+Boolean
+SCPreferencesPathSetLink (
+ SCPreferencesRef session,
+ CFStringRef path,
+ CFStringRef link
+ );
+Boolean
+SCPreferencesPathRemoveValue (
+ SCPreferencesRef session,
+ CFStringRef path
+ );
+
+}
+
+
+
+
+typedef u_char sa_family_t;
+struct linger {
+ int l_onoff;
+ int l_linger;
+};
+struct sockaddr {
+ u_char sa_len;
+ u_char sa_family;
+ char sa_data[14];
+};
+
+
+
+
+
+
+struct sockproto {
+ u_short sp_family;
+ u_short sp_protocol;
+};
+struct sockaddr_storage {
+ u_char ss_len;
+ sa_family_t ss_family;
+ char __ss_pad1[((sizeof(int64_t)) - sizeof(u_char) - sizeof(sa_family_t))];
+ int64_t __ss_align;
+ char __ss_pad2[(128 - sizeof(u_char) - sizeof(sa_family_t) - ((sizeof(int64_t)) - sizeof(u_char) - sizeof(sa_family_t)) - (sizeof(int64_t)))];
+};
+struct msghdr {
+ caddr_t msg_name;
+ u_int msg_namelen;
+ struct iovec *msg_iov;
+ u_int msg_iovlen;
+ caddr_t msg_control;
+ u_int msg_controllen;
+ int msg_flags;
+};
+struct cmsghdr {
+ u_int cmsg_len;
+ int cmsg_level;
+ int cmsg_type;
+
+};
+struct osockaddr {
+ u_short sa_family;
+ char sa_data[14];
+};
+
+
+
+
+struct omsghdr {
+ caddr_t msg_name;
+ int msg_namelen;
+ struct iovec *msg_iov;
+ int msg_iovlen;
+ caddr_t msg_accrights;
+ int msg_accrightslen;
+};
+extern "C" {
+int accept (int, struct sockaddr *, int *);
+int bind (int, const struct sockaddr *, int);
+int connect (int, const struct sockaddr *, int);
+int getpeername (int, struct sockaddr *, int *);
+int getsockname (int, struct sockaddr *, int *);
+int getsockopt (int, int, int, void *, int *);
+int listen (int, int);
+ssize_t recv (int, void *, size_t, int);
+ssize_t recvfrom (int, void *, size_t, int, struct sockaddr *, int *);
+ssize_t recvmsg (int, struct msghdr *, int);
+ssize_t send (int, const void *, size_t, int);
+ssize_t sendto (int, const void *, size_t, int, const struct sockaddr *, int);
+
+ssize_t sendmsg (int, const struct msghdr *, int);
+
+
+
+int setsockopt (int, int, int, const void *, int);
+int shutdown (int, int);
+int socket (int, int, int);
+int socketpair (int, int, int, int *);
+
+void pfctlinput (int, struct sockaddr *);
+}
+
+
+extern double acos (double);
+extern double asin (double);
+extern double atan (double);
+extern double atan2 (double, double);
+extern double ceil (double);
+extern double cos (double);
+extern double cosh (double);
+extern double exp (double);
+extern double fabs (double);
+extern double floor (double);
+extern double fmod (double, double);
+extern double frexp (double, int *);
+extern double ldexp (double, int);
+extern double log10 (double);
+extern double log (double);
+extern double modf (double, double *);
+extern double pow (double, double);
+extern double sin (double);
+extern double sinh (double);
+extern double sqrt (double);
+extern double tan (double);
+extern double tanh (double);
+
+
+typedef enum {
+ kSCNetworkFlagsTransientConnection = 1<<0,
+ kSCNetworkFlagsReachable = 1<<1,
+ kSCNetworkFlagsConnectionRequired = 1<<2,
+ kSCNetworkFlagsConnectionAutomatic = 1<<3,
+ kSCNetworkFlagsInterventionRequired = 1<<4,
+} SCNetworkConnectionFlags;
+
+
+extern "C" {
+Boolean
+SCNetworkCheckReachabilityByAddress (
+ const struct sockaddr *address,
+ const int addrlen,
+ SCNetworkConnectionFlags *flags
+ );
+Boolean
+SCNetworkCheckReachabilityByName (
+ const char *nodename,
+ SCNetworkConnectionFlags *flags
+ );
+
+}
+
+extern "C" {
+
+
+
+
+
+
+int SCError ();
+const char * SCErrorString (int status);
+
+}
+
+
+
+extern "C" {
+typedef GDHandle AGLDevice;
+
+
+
+
+typedef CGrafPtr AGLDrawable;
+
+
+
+
+typedef struct __AGLRendererInfoRec *AGLRendererInfo;
+typedef struct __AGLPixelFormatRec *AGLPixelFormat;
+typedef struct __AGLContextRec *AGLContext;
+extern AGLPixelFormat aglChoosePixelFormat(const AGLDevice *gdevs, GLint ndev, const GLint *attribs);
+extern void aglDestroyPixelFormat(AGLPixelFormat pix);
+extern AGLPixelFormat aglNextPixelFormat(AGLPixelFormat pix);
+extern GLboolean aglDescribePixelFormat(AGLPixelFormat pix, GLint attrib, GLint *value);
+extern AGLDevice *aglDevicesOfPixelFormat(AGLPixelFormat pix, GLint *ndevs);
+
+
+
+
+extern AGLRendererInfo aglQueryRendererInfo(const AGLDevice *gdevs, GLint ndev);
+extern void aglDestroyRendererInfo(AGLRendererInfo rend);
+extern AGLRendererInfo aglNextRendererInfo(AGLRendererInfo rend);
+extern GLboolean aglDescribeRenderer(AGLRendererInfo rend, GLint prop, GLint *value);
+
+
+
+
+extern AGLContext aglCreateContext(AGLPixelFormat pix, AGLContext share);
+extern GLboolean aglDestroyContext(AGLContext ctx);
+extern GLboolean aglCopyContext(AGLContext src, AGLContext dst, GLuint mask);
+extern GLboolean aglUpdateContext(AGLContext ctx);
+
+
+
+
+extern GLboolean aglSetCurrentContext(AGLContext ctx);
+extern AGLContext aglGetCurrentContext(void);
+
+
+
+
+extern GLboolean aglSetDrawable(AGLContext ctx, AGLDrawable draw);
+extern GLboolean aglSetOffScreen(AGLContext ctx, GLsizei width, GLsizei height, GLsizei rowbytes, GLvoid *baseaddr);
+extern GLboolean aglSetFullScreen(AGLContext ctx, GLsizei width, GLsizei height, GLsizei freq, GLint device);
+extern AGLDrawable aglGetDrawable(AGLContext ctx);
+
+
+
+
+extern GLboolean aglSetVirtualScreen(AGLContext ctx, GLint screen);
+extern GLint aglGetVirtualScreen(AGLContext ctx);
+
+
+
+
+extern void aglGetVersion(GLint *major, GLint *minor);
+
+
+
+
+extern GLboolean aglConfigure(GLenum pname, GLuint param);
+
+
+
+
+extern void aglSwapBuffers(AGLContext ctx);
+
+
+
+
+extern GLboolean aglEnable(AGLContext ctx, GLenum pname);
+extern GLboolean aglDisable(AGLContext ctx, GLenum pname);
+extern GLboolean aglIsEnabled(AGLContext ctx, GLenum pname);
+extern GLboolean aglSetInteger(AGLContext ctx, GLenum pname, const GLint *params);
+extern GLboolean aglGetInteger(AGLContext ctx, GLenum pname, GLint *params);
+
+
+
+
+extern GLboolean aglUseFont(AGLContext ctx, GLint fontID, Style face, GLint size, GLint first, GLint count, GLint base);
+
+
+
+
+extern GLenum aglGetError(void);
+extern const GLubyte *aglErrorString(GLenum code);
+
+
+
+
+extern void aglResetLibrary(void);
+
+
+
+
+extern void aglSurfaceTexture (AGLContext context, GLenum target, GLenum internalformat, AGLContext surfacecontext);
+
+
+}
+
+
+
+// we have to include any #defines from Apple's headers that we need here
+#define InstallWindowEventHandler( t, h, n, l, u, r ) \
+ InstallEventHandler( GetWindowEventTarget( t ), (h), (n), (l), (u), (r) )
+#define InstallControlEventHandler( t, h, n, l, u, r ) \
+ InstallEventHandler( GetControlEventTarget( t ), (h), (n), (l), (u), (r) )
+#define InstallMenuEventHandler( t, h, n, l, u, r ) \
+ InstallEventHandler( GetMenuEventTarget( t ), (h), (n), (l), (u), (r) )
+
+#define AGL_VERSION_2_0 1
+#define AGL_NONE 0
+#define AGL_ALL_RENDERERS 1 /* choose from all available renderers */
+#define AGL_BUFFER_SIZE 2 /* depth of the index buffer */
+#define AGL_LEVEL 3 /* level in plane stacking */
+#define AGL_RGBA 4 /* choose an RGBA format */
+#define AGL_DOUBLEBUFFER 5 /* double buffering supported */
+#define AGL_STEREO 6 /* stereo buffering supported */
+#define AGL_AUX_BUFFERS 7 /* number of aux buffers */
+#define AGL_RED_SIZE 8 /* number of red component bits */
+#define AGL_GREEN_SIZE 9 /* number of green component bits */
+#define AGL_BLUE_SIZE 10 /* number of blue component bits */
+#define AGL_ALPHA_SIZE 11 /* number of alpha component bits */
+#define AGL_DEPTH_SIZE 12 /* number of depth bits */
+#define AGL_STENCIL_SIZE 13 /* number of stencil bits */
+#define AGL_ACCUM_RED_SIZE 14 /* number of red accum bits */
+#define AGL_ACCUM_GREEN_SIZE 15 /* number of green accum bits */
+#define AGL_ACCUM_BLUE_SIZE 16 /* number of blue accum bits */
+#define AGL_ACCUM_ALPHA_SIZE 17 /* number of alpha accum bits */
+#define AGL_PIXEL_SIZE 50 /* frame buffer bits per pixel */
+#define AGL_MINIMUM_POLICY 51 /* never choose smaller buffers than requested */
+#define AGL_MAXIMUM_POLICY 52 /* choose largest buffers of type requested */
+#define AGL_OFFSCREEN 53 /* choose an off-screen capable renderer */
+#define AGL_FULLSCREEN 54 /* choose a full-screen capable renderer */
+#define AGL_SAMPLE_BUFFERS_ARB 55 /* number of multi sample buffers */
+#define AGL_SAMPLES_ARB 56 /* number of samples per multi sample buffer */
+#define AGL_AUX_DEPTH_STENCIL 57 /* independent depth and/or stencil buffers for the aux buffer */
+#define AGL_RENDERER_ID 70 /* request renderer by ID */
+#define AGL_SINGLE_RENDERER 71 /* choose a single renderer for all screens */
+#define AGL_NO_RECOVERY 72 /* disable all failure recovery systems */
+#define AGL_ACCELERATED 73 /* choose a hardware accelerated renderer */
+#define AGL_CLOSEST_POLICY 74 /* choose the closest color buffer to request */
+#define AGL_ROBUST 75 /* renderer does not need failure recovery */
+#define AGL_BACKING_STORE 76 /* back buffer contents are valid after swap */
+#define AGL_MP_SAFE 78 /* renderer is multi-processor safe */
+#define AGL_WINDOW 80 /* can be used to render to an onscreen window */
+#define AGL_MULTISCREEN 81 /* single window can span multiple screens */
+#define AGL_VIRTUAL_SCREEN 82 /* virtual screen number */
+#define AGL_COMPLIANT 83 /* renderer is opengl compliant */
+/* #define AGL_OFFSCREEN 53 */
+/* #define AGL_FULLSCREEN 54 */
+/* #define AGL_RENDERER_ID 70 */
+/* #define AGL_ACCELERATED 73 */
+/* #define AGL_ROBUST 75 */
+/* #define AGL_BACKING_STORE 76 */
+/* #define AGL_MP_SAFE 78 */
+/* #define AGL_WINDOW 80 */
+/* #define AGL_MULTISCREEN 81 */
+/* #define AGL_COMPLIANT 83 */
+#define AGL_BUFFER_MODES 100
+#define AGL_MIN_LEVEL 101
+#define AGL_MAX_LEVEL 102
+#define AGL_COLOR_MODES 103
+#define AGL_ACCUM_MODES 104
+#define AGL_DEPTH_MODES 105
+#define AGL_STENCIL_MODES 106
+#define AGL_MAX_AUX_BUFFERS 107
+#define AGL_VIDEO_MEMORY 120
+#define AGL_TEXTURE_MEMORY 121
+#define AGL_SWAP_RECT 200 /* Enable or set the swap rectangle */
+#define AGL_BUFFER_RECT 202 /* Enable or set the buffer rectangle */
+#define AGL_SWAP_LIMIT 203 /* Enable or disable the swap async limit */
+#define AGL_COLORMAP_TRACKING 210 /* Enable or disable colormap tracking */
+#define AGL_COLORMAP_ENTRY 212 /* Set a colormap entry to {index, r, g, b} */
+#define AGL_RASTERIZATION 220 /* Enable or disable all rasterization */
+#define AGL_SWAP_INTERVAL 222 /* 0 -> Don't sync, n -> Sync every n retrace */
+#define AGL_STATE_VALIDATION 230 /* Validate state for multi-screen functionality */
+#define AGL_BUFFER_NAME 231 /* Set the buffer name. Allows for multi ctx to share a buffer */
+#define AGL_ORDER_CONTEXT_TO_FRONT 232 /* Order the current context in front of all the other contexts. */
+#define AGL_CONTEXT_SURFACE_ID 233 /* aglGetInteger only - returns the ID of the drawable surface for the context */
+#define AGL_CONTEXT_DISPLAY_ID 234 /* aglGetInteger only - returns the display ID(s) of all displays touched by the context, up to a maximum of 32 displays */
+#define AGL_SURFACE_ORDER 235 /* Position of OpenGL surface relative to window: 1 -> Above window, -1 -> Below Window */
+#define AGL_SURFACE_OPACITY 236 /* Opacity of OpenGL surface: 1 -> Surface is opaque (default), 0 -> non-opaque */
+#define AGL_CLIP_REGION 254 /* Enable or set the drawable clipping region */
+#define AGL_FS_CAPTURE_SINGLE 255 /* Enable the capture of only a single display for aglFullScreen, normally disabled */
+#define AGL_FORMAT_CACHE_SIZE 501 /* Set the size of the pixel format cache */
+#define AGL_CLEAR_FORMAT_CACHE 502 /* Reset the pixel format cache */
+#define AGL_RETAIN_RENDERERS 503 /* Whether to retain loaded renderers in memory */
+#define AGL_MONOSCOPIC_BIT 0x00000001
+#define AGL_STEREOSCOPIC_BIT 0x00000002
+#define AGL_SINGLEBUFFER_BIT 0x00000004
+#define AGL_DOUBLEBUFFER_BIT 0x00000008
+#define AGL_0_BIT 0x00000001
+#define AGL_1_BIT 0x00000002
+#define AGL_2_BIT 0x00000004
+#define AGL_3_BIT 0x00000008
+#define AGL_4_BIT 0x00000010
+#define AGL_5_BIT 0x00000020
+#define AGL_6_BIT 0x00000040
+#define AGL_8_BIT 0x00000080
+#define AGL_10_BIT 0x00000100
+#define AGL_12_BIT 0x00000200
+#define AGL_16_BIT 0x00000400
+#define AGL_24_BIT 0x00000800
+#define AGL_32_BIT 0x00001000
+#define AGL_48_BIT 0x00002000
+#define AGL_64_BIT 0x00004000
+#define AGL_96_BIT 0x00008000
+#define AGL_128_BIT 0x00010000
+#define AGL_RGB8_BIT 0x00000001 /* 8 rgb bit/pixel, RGB=7:0, inverse colormap */
+#define AGL_RGB8_A8_BIT 0x00000002 /* 8-8 argb bit/pixel, A=7:0, RGB=7:0, inverse colormap */
+#define AGL_BGR233_BIT 0x00000004 /* 8 rgb bit/pixel, B=7:6, G=5:3, R=2:0 */
+#define AGL_BGR233_A8_BIT 0x00000008 /* 8-8 argb bit/pixel, A=7:0, B=7:6, G=5:3, R=2:0 */
+#define AGL_RGB332_BIT 0x00000010 /* 8 rgb bit/pixel, R=7:5, G=4:2, B=1:0 */
+#define AGL_RGB332_A8_BIT 0x00000020 /* 8-8 argb bit/pixel, A=7:0, R=7:5, G=4:2, B=1:0 */
+#define AGL_RGB444_BIT 0x00000040 /* 16 rgb bit/pixel, R=11:8, G=7:4, B=3:0 */
+#define AGL_ARGB4444_BIT 0x00000080 /* 16 argb bit/pixel, A=15:12, R=11:8, G=7:4, B=3:0 */
+#define AGL_RGB444_A8_BIT 0x00000100 /* 8-16 argb bit/pixel, A=7:0, R=11:8, G=7:4, B=3:0 */
+#define AGL_RGB555_BIT 0x00000200 /* 16 rgb bit/pixel, R=14:10, G=9:5, B=4:0 */
+#define AGL_ARGB1555_BIT 0x00000400 /* 16 argb bit/pixel, A=15, R=14:10, G=9:5, B=4:0 */
+#define AGL_RGB555_A8_BIT 0x00000800 /* 8-16 argb bit/pixel, A=7:0, R=14:10, G=9:5, B=4:0 */
+#define AGL_RGB565_BIT 0x00001000 /* 16 rgb bit/pixel, R=15:11, G=10:5, B=4:0 */
+#define AGL_RGB565_A8_BIT 0x00002000 /* 8-16 argb bit/pixel, A=7:0, R=15:11, G=10:5, B=4:0 */
+#define AGL_RGB888_BIT 0x00004000 /* 32 rgb bit/pixel, R=23:16, G=15:8, B=7:0 */
+#define AGL_ARGB8888_BIT 0x00008000 /* 32 argb bit/pixel, A=31:24, R=23:16, G=15:8, B=7:0 */
+#define AGL_RGB888_A8_BIT 0x00010000 /* 8-32 argb bit/pixel, A=7:0, R=23:16, G=15:8, B=7:0 */
+#define AGL_RGB101010_BIT 0x00020000 /* 32 rgb bit/pixel, R=29:20, G=19:10, B=9:0 */
+#define AGL_ARGB2101010_BIT 0x00040000 /* 32 argb bit/pixel, A=31:30 R=29:20, G=19:10, B=9:0 */
+#define AGL_RGB101010_A8_BIT 0x00080000 /* 8-32 argb bit/pixel, A=7:0 R=29:20, G=19:10, B=9:0 */
+#define AGL_RGB121212_BIT 0x00100000 /* 48 rgb bit/pixel, R=35:24, G=23:12, B=11:0 */
+#define AGL_ARGB12121212_BIT 0x00200000 /* 48 argb bit/pixel, A=47:36, R=35:24, G=23:12, B=11:0 */
+#define AGL_RGB161616_BIT 0x00400000 /* 64 rgb bit/pixel, R=47:32, G=31:16, B=15:0 */
+#define AGL_ARGB16161616_BIT 0x00800000 /* 64 argb bit/pixel, A=63:48, R=47:32, G=31:16, B=15:0 */
+#define AGL_INDEX8_BIT 0x20000000 /* 8 bit color look up table */
+#define AGL_INDEX16_BIT 0x40000000 /* 16 bit color look up table */
+#define AGL_NO_ERROR 0 /* no error */
+#define AGL_BAD_ATTRIBUTE 10000 /* invalid pixel format attribute */
+#define AGL_BAD_PROPERTY 10001 /* invalid renderer property */
+#define AGL_BAD_PIXELFMT 10002 /* invalid pixel format */
+#define AGL_BAD_RENDINFO 10003 /* invalid renderer info */
+#define AGL_BAD_CONTEXT 10004 /* invalid context */
+#define AGL_BAD_DRAWABLE 10005 /* invalid drawable */
+#define AGL_BAD_GDEV 10006 /* invalid graphics device */
+#define AGL_BAD_STATE 10007 /* invalid context state */
+#define AGL_BAD_VALUE 10008 /* invalid numerical value */
+#define AGL_BAD_MATCH 10009 /* invalid share context */
+#define AGL_BAD_ENUM 10010 /* invalid enumerant */
+#define AGL_BAD_OFFSCREEN 10011 /* invalid offscreen drawable */
+#define AGL_BAD_FULLSCREEN 10012 /* invalid offscreen drawable */
+#define AGL_BAD_WINDOW 10013 /* invalid window */
+#define AGL_BAD_POINTER 10014 /* invalid pointer */
+#define AGL_BAD_MODULE 10015 /* invalid code module */
+#define AGL_BAD_ALLOC 10016 /* memory allocation failure */
+
+
+#define kSCPropNetOverridePrimary SCSTR("OverridePrimary") /* CFNumber (0 or 1) */
+#define kSCPropNetServiceOrder SCSTR("ServiceOrder") /* CFArray[CFString] */
+#define kSCPropNetPPPOverridePrimary SCSTR("PPPOverridePrimary") /* CFNumber (0 or 1) */
+#define kSCPropNetInterfaces SCSTR("Interfaces") /* CFArray[CFString] */
+#define kSCPropNetLocalHostName SCSTR("LocalHostName") /* CFString */
+#define kSCPropNetAirPortAllowNetCreation SCSTR("AllowNetCreation") /* CFNumber (0 or 1) */
+#define kSCPropNetAirPortAuthPassword SCSTR("AuthPassword") /* CFData */
+#define kSCPropNetAirPortAuthPasswordEncryption SCSTR("AuthPasswordEncryption") /* CFString */
+#define kSCPropNetAirPortJoinMode SCSTR("JoinMode") /* CFString */
+#define kSCPropNetAirPortPowerEnabled SCSTR("PowerEnabled") /* CFNumber (0 or 1) */
+#define kSCPropNetAirPortPreferredNetwork SCSTR("PreferredNetwork") /* CFString */
+#define kSCPropNetAirPortSavePasswords SCSTR("SavePasswords") /* CFNumber (0 or 1) */
+/* kSCPropNetAirPortJoinMode values */
+#define kSCPropNetAppleTalkComputerName SCSTR("ComputerName") /* CFString */
+#define kSCPropNetAppleTalkComputerNameEncoding SCSTR("ComputerNameEncoding") /* CFNumber */
+#define kSCPropNetAppleTalkConfigMethod SCSTR("ConfigMethod") /* CFString */
+#define kSCPropNetAppleTalkDefaultZone SCSTR("DefaultZone") /* CFString */
+#define kSCPropNetAppleTalkNetworkID SCSTR("NetworkID") /* CFNumber */
+#define kSCPropNetAppleTalkNetworkRange SCSTR("NetworkRange") /* CFArray[CFNumber] */
+#define kSCPropNetAppleTalkNodeID SCSTR("NodeID") /* CFNumber */
+#define kSCPropNetAppleTalkSeedNetworkRange SCSTR("SeedNetworkRange") /* CFArray[CFNumber] */
+#define kSCPropNetAppleTalkSeedZones SCSTR("SeedZones") /* CFArray[CFString] */
+/* kSCPropNetAppleTalkConfigMethod values */
+#define kSCPropNetDNSDomainName SCSTR("DomainName") /* CFString */
+#define kSCPropNetDNSSearchDomains SCSTR("SearchDomains") /* CFArray[CFString] */
+#define kSCPropNetDNSServerAddresses SCSTR("ServerAddresses") /* CFArray[CFString] */
+#define kSCPropNetDNSSortList SCSTR("SortList") /* CFArray[CFString] */
+#define kSCPropNetInterfaceDeviceName SCSTR("DeviceName") /* CFString */
+#define kSCPropNetInterfaceHardware SCSTR("Hardware") /* CFString */
+#define kSCPropNetInterfaceType SCSTR("Type") /* CFString */
+#define kSCPropNetInterfaceSubType SCSTR("SubType") /* CFString */
+#define kSCPropNetInterfaceSupportsModemOnHold SCSTR("SupportsModemOnHold") /* CFNumber (0 or 1) */
+/* kSCPropNetInterfaceType values */
+/* kSCPropNetServiceSubType values (for PPP) */
+#define kSCPropNetIPv4Addresses SCSTR("Addresses") /* CFArray[CFString] */
+#define kSCPropNetIPv4ConfigMethod SCSTR("ConfigMethod") /* CFString */
+#define kSCPropNetIPv4DHCPClientID SCSTR("DHCPClientID") /* CFString */
+#define kSCPropNetIPv4Router SCSTR("Router") /* CFString */
+#define kSCPropNetIPv4SubnetMasks SCSTR("SubnetMasks") /* CFArray[CFString] */
+#define kSCPropNetIPv4DestAddresses SCSTR("DestAddresses") /* CFArray[CFString] */
+#define kSCPropNetIPv4BroadcastAddresses SCSTR("BroadcastAddresses") /* CFArray[CFString] */
+/* kSCPropNetIPv4ConfigMethod values */
+#define kSCPropNetIPv6Addresses SCSTR("Addresses") /* CFArray[CFString] */
+#define kSCPropNetIPv6ConfigMethod SCSTR("ConfigMethod") /* CFString */
+#define kSCPropNetLinkActive SCSTR("Active") /* CFBoolean */
+#define kSCPropNetLinkDetaching SCSTR("Detaching") /* CFBoolean */
+#define kSCPropNetModemConnectionScript SCSTR("ConnectionScript") /* CFString */
+#define kSCPropNetModemConnectSpeed SCSTR("ConnectSpeed") /* CFNumber */
+#define kSCPropNetModemDataCompression SCSTR("DataCompression") /* CFNumber (0 or 1) */
+#define kSCPropNetModemDialMode SCSTR("DialMode") /* CFString */
+#define kSCPropNetModemErrorCorrection SCSTR("ErrorCorrection") /* CFNumber (0 or 1) */
+#define kSCPropNetModemHoldCallWaitingAudibleAlert SCSTR("HoldCallWaitingAudibleAlert") /* CFNumber (0 or 1) */
+#define kSCPropNetModemHoldDisconnectOnAnswer SCSTR("HoldDisconnectOnAnswer") /* CFNumber (0 or 1) */
+#define kSCPropNetModemHoldEnabled SCSTR("HoldEnabled") /* CFNumber (0 or 1) */
+#define kSCPropNetModemHoldReminder SCSTR("HoldReminder") /* CFNumber (0 or 1) */
+#define kSCPropNetModemHoldReminderTime SCSTR("HoldReminderTime") /* CFNumber */
+#define kSCPropNetModemNote SCSTR("Note") /* CFString */
+#define kSCPropNetModemPulseDial SCSTR("PulseDial") /* CFNumber (0 or 1) */
+#define kSCPropNetModemSpeaker SCSTR("Speaker") /* CFNumber (0 or 1) */
+#define kSCPropNetModemSpeed SCSTR("Speed") /* CFNumber */
+/* kSCPropNetModemDialMode values */
+#define kSCPropNetNetInfoBindingMethods SCSTR("BindingMethods") /* CFString */
+#define kSCPropNetNetInfoServerAddresses SCSTR("ServerAddresses") /* CFArray[CFString] */
+#define kSCPropNetNetInfoServerTags SCSTR("ServerTags") /* CFArray[CFString] */
+#define kSCPropNetNetInfoBroadcastServerTag SCSTR("BroadcastServerTag") /* CFString */
+/* kSCPropNetNetInfoBindingMethods values */
+/* kSCPropNetNetInfoBroadcastServerTag default value */
+#define kSCPropNetPPPConnectTime SCSTR("ConnectTime") /* CFNumber */
+#define kSCPropNetPPPDeviceLastCause SCSTR("DeviceLastCause") /* CFNumber */
+#define kSCPropNetPPPDialOnDemand SCSTR("DialOnDemand") /* CFNumber (0 or 1) */
+#define kSCPropNetPPPDisconnectOnIdle SCSTR("DisconnectOnIdle") /* CFNumber (0 or 1) */
+#define kSCPropNetPPPDisconnectOnIdleTimer SCSTR("DisconnectOnIdleTimer") /* CFNumber */
+#define kSCPropNetPPPDisconnectOnLogout SCSTR("DisconnectOnLogout") /* CFNumber (0 or 1) */
+#define kSCPropNetPPPDisconnectOnSleep SCSTR("DisconnectOnSleep") /* CFNumber (0 or 1) */
+#define kSCPropNetPPPIdleReminderTimer SCSTR("IdleReminderTimer") /* CFNumber */
+#define kSCPropNetPPPIdleReminder SCSTR("IdleReminder") /* CFNumber (0 or 1) */
+#define kSCPropNetPPPLastCause SCSTR("LastCause") /* CFNumber */
+#define kSCPropNetPPPLogfile SCSTR("Logfile") /* CFString */
+#define kSCPropNetPPPPlugins SCSTR("Plugins") /* CFArray[CFString] */
+#define kSCPropNetPPPSessionTimer SCSTR("SessionTimer") /* CFNumber */
+#define kSCPropNetPPPStatus SCSTR("Status") /* CFString */
+#define kSCPropNetPPPUseSessionTimer SCSTR("UseSessionTimer") /* CFNumber (0 or 1) */
+#define kSCPropNetPPPVerboseLogging SCSTR("VerboseLogging") /* CFNumber (0 or 1) */
+#define kSCPropNetPPPAuthName SCSTR("AuthName") /* CFString */
+#define kSCPropNetPPPAuthPassword SCSTR("AuthPassword") /* CFString */
+#define kSCPropNetPPPAuthPasswordEncryption SCSTR("AuthPasswordEncryption") /* CFString */
+#define kSCPropNetPPPAuthProtocol SCSTR("AuthProtocol") /* CFArray[CFString] */
+/* kSCPropNetPPPAuthProtocol values */
+#define kSCPropNetPPPCommAlternateRemoteAddress SCSTR("CommAlternateRemoteAddress") /* CFString */
+#define kSCPropNetPPPCommConnectDelay SCSTR("CommConnectDelay") /* CFNumber */
+#define kSCPropNetPPPCommDisplayTerminalWindow SCSTR("CommDisplayTerminalWindow") /* CFNumber (0 or 1) */
+#define kSCPropNetPPPCommRedialCount SCSTR("CommRedialCount") /* CFNumber */
+#define kSCPropNetPPPCommRedialEnabled SCSTR("CommRedialEnabled") /* CFNumber (0 or 1) */
+#define kSCPropNetPPPCommRedialInterval SCSTR("CommRedialInterval") /* CFNumber */
+#define kSCPropNetPPPCommRemoteAddress SCSTR("CommRemoteAddress") /* CFString */
+#define kSCPropNetPPPCommTerminalScript SCSTR("CommTerminalScript") /* CFString */
+#define kSCPropNetPPPCommUseTerminalScript SCSTR("CommUseTerminalScript") /* CFNumber (0 or 1) */
+#define kSCPropNetPPPCCPEnabled SCSTR("CCPEnabled") /* CFNumber (0 or 1) */
+#define kSCPropNetPPPIPCPCompressionVJ SCSTR("IPCPCompressionVJ") /* CFNumber (0 or 1) */
+#define kSCPropNetPPPLCPEchoEnabled SCSTR("LCPEchoEnabled") /* CFNumber (0 or 1) */
+#define kSCPropNetPPPLCPEchoFailure SCSTR("LCPEchoFailure") /* CFNumber */
+#define kSCPropNetPPPLCPEchoInterval SCSTR("LCPEchoInterval") /* CFNumber */
+#define kSCPropNetPPPLCPCompressionACField SCSTR("LCPCompressionACField") /* CFNumber (0 or 1) */
+#define kSCPropNetPPPLCPCompressionPField SCSTR("LCPCompressionPField") /* CFNumber (0 or 1) */
+#define kSCPropNetPPPLCPMRU SCSTR("LCPMRU") /* CFNumber */
+#define kSCPropNetPPPLCPMTU SCSTR("LCPMTU") /* CFNumber */
+#define kSCPropNetPPPLCPReceiveACCM SCSTR("LCPReceiveACCM") /* CFNumber */
+#define kSCPropNetPPPLCPTransmitACCM SCSTR("LCPTransmitACCM") /* CFNumber */
+#define kSCPropNetProxiesExceptionsList SCSTR("ExceptionsList") /* CFArray[CFString] */
+#define kSCPropNetProxiesFTPEnable SCSTR("FTPEnable") /* CFNumber (0 or 1) */
+#define kSCPropNetProxiesFTPPassive SCSTR("FTPPassive") /* CFNumber (0 or 1) */
+#define kSCPropNetProxiesFTPPort SCSTR("FTPPort") /* CFNumber */
+#define kSCPropNetProxiesFTPProxy SCSTR("FTPProxy") /* CFString */
+#define kSCPropNetProxiesGopherEnable SCSTR("GopherEnable") /* CFNumber (0 or 1) */
+#define kSCPropNetProxiesGopherPort SCSTR("GopherPort") /* CFNumber */
+#define kSCPropNetProxiesGopherProxy SCSTR("GopherProxy") /* CFString */
+#define kSCPropNetProxiesHTTPEnable SCSTR("HTTPEnable") /* CFNumber (0 or 1) */
+#define kSCPropNetProxiesHTTPPort SCSTR("HTTPPort") /* CFNumber */
+#define kSCPropNetProxiesHTTPProxy SCSTR("HTTPProxy") /* CFString */
+#define kSCPropNetProxiesHTTPSEnable SCSTR("HTTPSEnable") /* CFNumber (0 or 1) */
+#define kSCPropNetProxiesHTTPSPort SCSTR("HTTPSPort") /* CFNumber */
+#define kSCPropNetProxiesHTTPSProxy SCSTR("HTTPSProxy") /* CFString */
+#define kSCPropNetProxiesRTSPEnable SCSTR("RTSPEnable") /* CFNumber (0 or 1) */
+#define kSCPropNetProxiesRTSPPort SCSTR("RTSPPort") /* CFNumber */
+#define kSCPropNetProxiesRTSPProxy SCSTR("RTSPProxy") /* CFString */
+#define kSCPropNetProxiesSOCKSEnable SCSTR("SOCKSEnable") /* CFNumber (0 or 1) */
+#define kSCPropNetProxiesSOCKSPort SCSTR("SOCKSPort") /* CFNumber */
+#define kSCPropNetProxiesSOCKSProxy SCSTR("SOCKSProxy") /* CFString */
+
+#define CFSTR(cStr) __CFStringMakeConstantString("" cStr "")
+#define SCSTR(s) CFSTR(s)
+
+CFDictionaryRef
+SCDynamicStoreCopyProxies (
+ SCDynamicStoreRef store
+ );
+
+
--- /dev/null
+// Copyright 2002 Adam Megacz, see the COPYING file for licensing [LGPL]
+
+// Inclusions /////////////////////////////////////////////////////////
+
+#include <gcj/cni.h>
+#include <gcj/array.h>
+#include <org/ibex/plat/Platform.h>
+#include <org/ibex/graphics/Picture.h>
+#include <org/ibex/plat/GCJ.h>
+#include <java/io/InputStream.h>
+#include <java/io/ByteArrayInputStream.h>
+#include <java/lang/RuntimeException.h>
+#include <org/ibex/plat/GCJ.h>
+#include <org/ibex/util/Log.h>
+extern "C" {
+
+// hack for broken Solaris headers
+#define _WCHAR_T
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <setjmp.h>
+#include "jpeglib.h"
+}
+
+#ifdef TRUE
+#undef TRUE
+#endif
+#define TRUE 1
+using org::ibex::util::Log;
+
+// builtin.xwar /////////////////////////////////////////////////////////
+
+extern unsigned char builtin_bytes[];
+extern int builtin_length;
+
+java::io::InputStream* org::ibex::plat::GCJ::_getBuiltinInputStream() {
+ jbyteArray ret = JvNewByteArray(builtin_length);
+ memcpy(elements(ret), builtin_bytes, builtin_length);
+ return new java::io::ByteArrayInputStream(ret);
+}
+
+
+
+// JPEG ////////////////////////////////////////////////////////////////
+
+typedef struct {
+ struct jpeg_source_mgr pub;
+ java::io::InputStream *is;
+ jbyteArray buf;
+} my_source_mgr_t;
+
+typedef struct {
+ struct jpeg_error_mgr pub;
+ jmp_buf setjmp_buffer;
+} my_error_mgr_t;
+
+static void error_exit (j_common_ptr cinfo) {
+ my_error_mgr_t *myerr = (my_error_mgr_t*) cinfo->err;
+ longjmp(myerr->setjmp_buffer,1);
+}
+
+static void term_source (j_decompress_ptr cinfo) { }
+static void init_source (j_decompress_ptr cinfo) { }
+
+boolean fill_input_buffer (j_decompress_ptr cinfo) {
+ my_source_mgr_t* src = (my_source_mgr_t*) cinfo->src;
+ JOCTET *p = (JOCTET*)elements(src->buf);
+ jint n;
+ try {
+ n = src->is->read(src->buf, 0, src->buf->length);
+ } catch(java::lang::Throwable *e) {
+ n = -1;
+ }
+
+ src->pub.next_input_byte = p;
+
+ if (n <= 0) {
+ // the JPEG library specifically suggests padding the end with EOF markers
+ p[0] = 0xff;
+ p[1] = JPEG_EOI;
+ src->pub.bytes_in_buffer = 2;
+ } else {
+ src->pub.bytes_in_buffer = n;
+ }
+ return 1;
+}
+
+void skip_input_data (j_decompress_ptr cinfo, long num_bytes) {
+ my_source_mgr_t* src = (my_source_mgr_t*) cinfo->src;
+
+ if (num_bytes <= 0) return;
+
+ while (num_bytes > src->pub.bytes_in_buffer) {
+ num_bytes -= src->pub.bytes_in_buffer;
+ fill_input_buffer(cinfo);
+ }
+ src->pub.next_input_byte += num_bytes;
+ src->pub.bytes_in_buffer -= num_bytes;
+}
+
+void org::ibex::plat::GCJ::_decodeJPEG(java::io::InputStream* is, org::ibex::graphics::Picture* p) {
+ struct jpeg_decompress_struct cinfo;
+ my_error_mgr_t jerr;
+ my_source_mgr_t src;
+
+ src.is = is;
+ src.buf = JvNewByteArray(16384);
+
+ src.pub.init_source = init_source;
+ src.pub.fill_input_buffer = fill_input_buffer;
+ src.pub.skip_input_data = skip_input_data;
+ src.pub.resync_to_restart = jpeg_resync_to_restart;
+ src.pub.term_source = term_source;
+ src.pub.next_input_byte = NULL;
+ src.pub.bytes_in_buffer = 0;
+
+ if (setjmp(jerr.setjmp_buffer)) {
+ // FEATURE - we should handle errors better than this
+ char msgbuf[JMSG_LENGTH_MAX];
+ (jerr.pub.format_message)((j_common_ptr)&cinfo, msgbuf);
+ Log::info(&GCJ::class$,JvNewStringLatin1(msgbuf));
+ jpeg_destroy_decompress(&cinfo);
+ return;
+ }
+
+ jpeg_create_decompress(&cinfo);
+
+ cinfo.src = &src.pub;
+ cinfo.err = jpeg_std_error(&jerr.pub);
+ jerr.pub.error_exit = error_exit;
+
+ jpeg_read_header(&cinfo,TRUE);
+ jpeg_start_decompress(&cinfo);
+
+ p->width = cinfo.output_width;
+ p->height = cinfo.output_height;
+ p->data = JvNewIntArray(p->width * p->height);
+
+ while (cinfo.output_scanline < cinfo.output_height) {
+ JSAMPLE *dest = (JSAMPLE*) (elements(p->data) + cinfo.output_scanline * p->width);
+ jpeg_read_scanlines(&cinfo,&dest,1);
+ }
+ jpeg_finish_decompress(&cinfo);
+ jpeg_destroy_decompress(&cinfo);
+
+ for(int i=0;i<p->data->length;i++)
+ elements(p->data)[i] |= 0xff000000; // alpha channel
+}
+
+// C++ new/delete operators (JvMalloc never fails)
+void* operator new(size_t size) { return JvMalloc(size); }
+void* operator new[](size_t size) { return JvMalloc(size);}
+void operator delete(void *p) { JvFree(p); }
+void operator delete[](void *p) { JvFree(p); }
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.plat;
+
+import org.ibex.util.*;
+import java.io.*;
+import java.security.*;
+import java.security.cert.*;
+import org.ibex.graphics.*;
+import org.ibex.core.*;
+import org.ibex.net.*;
+
+/** common superclass for all platforms that use GCJ to compile a native binary */
+public abstract class GCJ extends Platform {
+
+ protected native InputStream _getBuiltinInputStream();
+
+ protected native void _decodeJPEG(InputStream is, Picture p);
+
+ // FEATURE: This could be optimized (a lot) by using a custom hashtable
+ public final static class Retainer {
+ private static Hash table = new Hash();
+ private final static class Key {
+ private Object o;
+ public Key(Object o) { this.o = o; }
+ public int hashCode() { return o == null ? 0 : o.hashCode(); }
+ public boolean equals(Object o2) { return (o2 instanceof Key) && ((Key)o2).o == o; }
+ }
+ private final static class Entry {
+ private int refCount;
+ public Entry() { inc(); }
+ public void inc() { refCount++; }
+ public boolean dec() { return --refCount == 0; }
+ }
+ public static synchronized void retain(Object o) {
+ Key k = new Key(o);
+ Entry r = (Entry) table.get(k);
+ if(r == null) table.put(k,new Entry());
+ else r.inc();
+ }
+ public static synchronized void release(Object o) {
+ Key k = new Key(o);
+ Entry e = (Entry) table.get(k);
+ if(e == null) throw new Error("Retainer::Release on unknown object");
+ if(e.dec()) { table.remove(k); }
+ }
+ }
+}
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.plat;
+
+import org.ibex.graphics.*;
+import org.ibex.core.*;
+import org.ibex.net.*;
+
+/** common superclass for all platforms that run in a "real" JVM */
+public abstract class JVM extends Platform {
+
+}
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.plat;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.awt.image.*;
+import java.net.*;
+import java.util.*;
+import org.ibex.util.*;
+import java.lang.reflect.*;
+import org.ibex.graphics.*;
+import org.ibex.core.*;
+import org.ibex.net.*;
+
+/** Platform class for most reasonable Java1.2+ Java2s */
+public class Java2 extends AWT {
+
+ private boolean isJava14 = false;
+
+ public Java2() {
+ // disable the focus manager so we can intercept the tab key
+ String versionString = System.getProperty("java.version", "");
+ int secondDecimal = versionString.substring(versionString.indexOf('.') + 1).indexOf('.');
+ if (secondDecimal != -1) versionString = versionString.substring(0, versionString.indexOf('.') + 1 + secondDecimal);
+ double version = Double.parseDouble(versionString);
+ if (version >= 1.4) {
+ isJava14 = true;
+ try {
+ Toolkit t = java.awt.Toolkit.getDefaultToolkit();
+ Method m = java.awt.Toolkit.class.getMethod("setDynamicLayout", new Class[] { Boolean.TYPE });
+ m.invoke(t, new Object[] { Boolean.TRUE });
+ } catch (Exception e) {
+ Log.info(this, "Exception while trying to enable AWT Dynamic Layout");
+ Log.info(this, e);
+ }
+ }
+ javax.swing.FocusManager.setCurrentManager(new javax.swing.FocusManager() {
+ public void processKeyEvent(Component focusedComponent, KeyEvent anEvent) { }
+ public void focusPreviousComponent(Component aComponent) { }
+ public void focusNextComponent(Component aComponent) { }
+ });
+ }
+
+ /** this is done with reflection in case a new version of the plugin comes out that doesn't let us pull the sun.plugin.* trick */
+ protected synchronized org.ibex.net.HTTP.Proxy _detectProxy() {
+ return (org.ibex.net.HTTP.Proxy)java.security.AccessController.doPrivileged(new java.security.PrivilegedAction() {
+ public Object run() {
+ try {
+ org.ibex.net.HTTP.Proxy pi = new org.ibex.net.HTTP.Proxy();
+
+ Class PluginProxyHandler = Class.forName("sun.plugin.protocol.PluginProxyHandler");
+ Method getDefaultProxyHandler = PluginProxyHandler.getMethod("getDefaultProxyHandler", new Class[] { });
+ Object proxyHandler = getDefaultProxyHandler.invoke(null, new Object[] { });
+
+ Class ProxyHandler = Class.forName("sun.plugin.protocol.ProxyHandler");
+ Method getProxyInfo = ProxyHandler.getMethod("getProxyInfo", new Class[] { URL.class });
+ Object proxyInfo = getProxyInfo.invoke(proxyHandler, new Object[] { new URL("http://www.ibex.org") });
+
+ Class ProxyInfo = Class.forName("sun.plugin.protocol.ProxyInfo");
+
+ if (((Boolean)ProxyInfo.getMethod("isSocksUsed", new Class[] { }).invoke(proxyInfo, new Object[] { })).booleanValue()) {
+ pi.socksProxyHost =
+ (String)ProxyInfo.getMethod("getSocksProxy", new Class[] { }).invoke(proxyInfo, new Object[] { });
+ pi.socksProxyPort =
+ ((Integer)ProxyInfo.getMethod("getSocksPort", new Class[] { }).invoke(proxyInfo, new Object[] { })).intValue();
+ }
+
+ if (((Boolean)ProxyInfo.getMethod("isProxyUsed", new Class[] { }).invoke(proxyInfo, new Object[] { })).booleanValue()) {
+ pi.httpProxyHost =
+ (String)ProxyInfo.getMethod("getProxy", new Class[] { }).invoke(proxyInfo, new Object[] { });
+ pi.httpProxyPort =
+ ((Integer)ProxyInfo.getMethod("getPort", new Class[] { }).invoke(proxyInfo, new Object[] { })).intValue();
+ }
+
+ if (pi.httpProxyHost != null || pi.socksProxyHost != null) return pi;
+ else return null;
+
+ } catch (Throwable e) {
+ if (Log.on) Log.info(this, "No proxy information found in Java Plugin classes");
+ return null;
+ }
+ }});
+ }
+
+ protected PixelBuffer _createPixelBuffer(int w, int h, Surface owner) { return new Java2PixelBuffer(w, h); }
+ protected Surface _createSurface(final Box root, final boolean framed) {
+ return (Surface)java.security.AccessController.doPrivileged(new java.security.PrivilegedAction() {
+ public Object run() {
+ if (isJava14) {
+ try {
+ // weaken the binding here to avoid link errors on 1.3.x
+ Class java14SurfaceClass = Class.forName(Java2.class.getName() + "$Java14Surface");
+ Constructor ctor = java14SurfaceClass.getConstructor(new Class[] { Box.class, Boolean.TYPE });
+ return (Surface)ctor.newInstance(new Object[] { root, Boolean.valueOf(framed) });
+ } catch (Exception e) {
+ Log.info(this, e);
+ throw new LinkageError("error: " + e);
+ }
+ } else {
+ return new Java2Surface(root, framed);
+ }
+ }
+ });
+ }
+
+ // Inner Classes //////////////////////////////////////////////////////////////////
+
+ private static Cursor invisibleCursor =
+ Toolkit.getDefaultToolkit().createCustomCursor(new BufferedImage(2, 2, BufferedImage.TYPE_INT_ARGB),
+ new Point(1, 1), "invisible");
+
+ protected static class Java2Surface extends AWTSurface {
+
+ public Java2Surface(Box root, boolean framed) { super(root, framed); }
+
+ protected void _setMinimized(boolean b) {
+ if (frame == null) Log.info(this, "JDK 1.2 can only minimize frames, not windows");
+ else if (b) frame.setState(java.awt.Frame.ICONIFIED);
+ else frame.setState(java.awt.Frame.NORMAL);
+ }
+
+ public void syncCursor() {
+ if (cursor.equals("invisible")) window.setCursor(invisibleCursor);
+ else super.syncCursor();
+ }
+ }
+
+ protected static class Java14Surface extends Java2Surface implements WindowStateListener, MouseWheelListener {
+ public Java14Surface(Box root, boolean framed) {
+ super(root, true);
+ // JDK1.4 doesn't like java.lang.Window's...
+ if (!framed) ((Frame)window).setUndecorated(true);
+ window.addWindowStateListener(this);
+ window.addMouseWheelListener(this);
+ window.setVisible(true);
+ }
+
+ protected void makeVisible() { }
+
+ protected void _setMaximized(boolean m) {
+ if (frame == null) {
+ if (Log.on) Log.info(this, "JDK 1.4 can only maximize frames, not windows");
+ return;
+ }
+ frame.setExtendedState(m ? Frame.MAXIMIZED_BOTH : (minimized ? Frame.ICONIFIED : Frame.NORMAL));
+ }
+ protected void _setMinimized(boolean m) {
+ if (frame == null) {
+ if (Log.on) Log.info(this, "JDK 1.4 can only minimize frames, not windows");
+ return;
+ }
+ frame.setExtendedState(m ? Frame.ICONIFIED : (maximized ? Frame.MAXIMIZED_BOTH : Frame.NORMAL));
+ }
+ public void windowStateChanged(WindowEvent e) {
+ if (e.getOldState() != e.getNewState()) {
+ if ((e.getNewState() & Frame.MAXIMIZED_BOTH) != 0) Maximized(true);
+ else if (((e.getOldState() & Frame.MAXIMIZED_BOTH) != 0) && (e.getNewState() & Frame.MAXIMIZED_BOTH) == 0)
+ Maximized(false);
+ }
+ }
+
+ public void mouseWheelMoved(MouseWheelEvent m) {
+ if (m.getScrollType() == MouseWheelEvent.WHEEL_UNIT_SCROLL)
+ VScroll(m.getUnitsToScroll());
+ }
+ }
+
+ protected static class Java2PixelBuffer extends AWTPixelBuffer {
+ private static ColorModel cm = Toolkit.getDefaultToolkit().getColorModel();
+ private static Hashtable emptyHashtable = new Hashtable();
+ private static short[] sbank = null;
+ private static int[] ibank = null;
+ private static byte[] bbank = null;
+ private static int bank_start = 0;
+ private WritableRaster raster = null;
+ private SampleModel sm = null;
+ private DataBuffer buf = null;
+
+ // this doens't seem to work on Windows
+ public void drawGlyph(org.ibex.graphics.Font.Glyph source, int dx, int dy, int cx1, int cy1, int cx2, int cy2, int rgb) {
+ Image i2 = ((AWTGlyph)source).getImage();
+ Graphics2D g2 = (Graphics2D)i.getGraphics();
+ g2.setComposite(AlphaComposite.DstOut);
+ g2.setClip(cx1, cy1, cx2 - cx1, cy2 - cy1);
+ g2.drawImage(i2, dx, dy, null);
+ g2.setComposite(AlphaComposite.DstOver);
+ g2.setColor(new java.awt.Color((rgb & 0x00FF0000) >> 16, (rgb & 0x0000FF00) >> 8, (rgb & 0x000000FF)));
+ g2.fillRect(dx, dy, cx2 - dx, cy2 - dy);
+ g2.drawImage(i2, 0, 0, null);
+ g2.setClip(0, 0, i.getWidth(null), i.getHeight(null));
+ }
+
+ public Java2PixelBuffer(int w, int h) {
+ sm = cm.createCompatibleSampleModel(w, h);
+ int numSamples = w * h * sm.getNumDataElements();
+ if (sm.getDataType() == DataBuffer.TYPE_USHORT) {
+ if (sbank == null || numSamples > 512 * 512 / 3) {
+ buf = new DataBufferUShort(numSamples);
+ } else {
+ if (numSamples > sbank.length - bank_start) {
+ bank_start = 0;
+ sbank = new short[512 * 512];
+ }
+ buf = new DataBufferUShort(sbank, numSamples, bank_start);
+ bank_start += numSamples;
+ }
+ } else if (sm.getDataType() == DataBuffer.TYPE_BYTE) {
+ if (bbank == null || numSamples > 512 * 512 / 3) {
+ buf = new DataBufferByte(numSamples);
+ } else {
+ if (numSamples > bbank.length - bank_start) {
+ bank_start = 0;
+ bbank = new byte[512 * 512];
+ }
+ buf = new DataBufferByte(bbank, numSamples, bank_start);
+ bank_start += numSamples;
+ }
+ } else if (sm.getDataType() == DataBuffer.TYPE_INT) {
+ if (ibank == null || numSamples > 512 * 512 / 3) {
+ buf = new DataBufferInt(numSamples);
+ } else {
+ if (numSamples > ibank.length - bank_start) {
+ bank_start = 0;
+ ibank = new int[512 * 512];
+ }
+ buf = new DataBufferInt(ibank, numSamples, bank_start);
+ bank_start += numSamples;
+ }
+ }
+ raster = Raster.createWritableRaster(sm, buf, null);
+ i = new BufferedImage(cm, raster, false, emptyHashtable);
+ g = i.getGraphics();
+ }
+ }
+
+ protected String getDescriptiveName() { return isJava14 ? "Java 1.4+ JVM" : "Java 1.2+ JVM"; }
+
+}
--- /dev/null
+// IMPORTANT: inclusion order: always include gcjh'ed headers first, then superclass cc's, then system headers
+#undef file
+#include <stdint.h>
+#include <java/lang/Class.h>
+#include <org/ibex/js/JS.h>
+#include <org/ibex/util/Log.h>
+#include <org/ibex/plat/Linux.h>
+#include "X11.cc"
+#include <stdint.h>
+
+// we love libgcj!
+extern const char **_Jv_argv;
+extern int _Jv_argc;
+
+void org::ibex::plat::Linux::fixEnvironment() {
+ // this wreaks havoc on gdb
+ // see http://lists.debian.org/debian-glibc/2003/debian-glibc-200311/msg00647.html
+ const char* ld_assume_kernel = getenv("LD_ASSUME_KERNEL");
+ if (ld_assume_kernel == NULL || strcmp("2.4.1", ld_assume_kernel)) {
+ int result;
+ printf("respawning self (%s) with LD_ASSUME_KERNEL=2.4.1\n", _Jv_argv[0]);
+ setenv("LD_ASSUME_KERNEL", "2.4.1", 1);
+ result = execvp(_Jv_argv[0], (char* const*)((void*)_Jv_argv));
+ printf("execvp() failed with error code %d\n", result);
+ exit(-1);
+ }
+}
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.plat;
+
+import org.ibex.graphics.*;
+import org.ibex.core.*;
+import org.ibex.net.*;
+
+/** Linux with an X11 display */
+public class Linux extends X11 {
+
+ public static void main(String[] args) throws Exception { org.ibex.Main.main(args); }
+ private native void fixEnvironment();
+
+ public Linux() {
+ fixEnvironment();
+ }
+
+}
--- /dev/null
+// Copyright 2003 Adam Megacz, see the COPYING file for licensing [LGPL]
+// Author: Brian Alliet
+
+// IMPROVMENT: use alpha testing? might be faster
+
+#include <org/ibex/plat/OpenGL.h>
+#include <org/ibex/plat/OpenGL$GLPixelBuffer.h>
+#include <org/ibex/plat/OpenGL$GLPicture.h>
+#include <org/ibex/plat/OpenGL$RectGLPicture.h>
+#include <org/ibex/plat/OpenGL$SquareGLPicture.h>
+#include <org/ibex/plat/OpenGL$MosaicGLPicture.h>
+
+#include <java/lang/Error.h>
+
+#ifdef __APPLE__
+#include <OpenGL/gl.h>
+#include <OpenGL/glu.h>
+#include <OpenGL/glext.h>
+#else
+#warning I am not sure if these are correct
+#include <gl/gl.h>
+#include <gl/glu.h>
+#include <gl/glext.h>
+#endif
+
+#include <stdio.h>
+
+#define min(a,b) ((a)<(b)?(a):(b))
+#define max(a,b) ((a)>(b)?(a):(b))
+
+namespace org { namespace ibex { namespace plat {
+
+#define checkGLError() checkGLError2(__FILE__,__LINE__)
+static void checkGLError2(const char *file,int line) {
+ GLenum err = glGetError();
+ if(err == GL_NO_ERROR) return;
+
+ fprintf(stderr,"%s:%d: GL Error: %s",file,line,(char *) gluErrorString(err));
+ exit(EXIT_FAILURE);
+}
+
+void OpenGL::natInit() {
+ GLint i;
+ const GLubyte *s;
+ activateSharedContext();
+ s = glGetString(GL_EXTENSIONS);
+ rectangularTextures = (jboolean) gluCheckExtension((GLubyte*)"GL_EXT_texture_rectangle",s);
+ glGetIntegerv(GL_MAX_TEXTURE_SIZE,&i);
+ maxTexSize = (jint) i;
+ if(rectangularTextures) {
+ glGetIntegerv(GL_MAX_RECTANGLE_TEXTURE_SIZE_EXT,&i);
+ maxRectTexSize = (jint) i;
+ }
+ s = glGetString(GL_VENDOR);
+ vendor = JvNewStringLatin1(s==0 ? "" : (char*)s);
+ s = glGetString(GL_RENDERER);
+ renderer = JvNewStringLatin1(s==0 ? "" : (char*)s);
+ s = glGetString(GL_VERSION);
+ version = JvNewStringLatin1(s==0 ? "" : (char*)s);
+}
+
+void OpenGL$GLPixelBuffer::drawableInit(jint width, jint height) {
+ glClearColor (0.3f, 0.7f, 1.0f, 1.0f);
+ glClearDepth( 0.0f );
+ glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
+ glShadeModel(GL_SMOOTH);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ glViewport(0,0,width,height);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(0,width,height,0,-1,1);
+ // CHECKME: This causes textures to be blurry, but something like this
+ // (but not this) might be required to draw straight lines
+ //glMatrixMode(GL_MODELVIEW);
+ //glLoadIdentity();
+ //glTranslatef(0.375, 0.375, 0.0);
+
+ checkGLError();
+}
+
+void OpenGL$GLPixelBuffer::setColor(jint argb) {
+ float alpha = ((argb >> 24) & 0xff) / 255.0;
+ float red = ((argb >> 16) & 0xff) / 255.0;
+ float green = ((argb >> 8) & 0xff) / 255.0;
+ float blue = ((argb >> 0) & 0xff) / 255.0;
+ glColor4f(red,green,blue,alpha);
+}
+
+void OpenGL$GLPixelBuffer::fillTrapezoid(jint x1, jint x2, jint y1, jint x3, jint x4, jint y2, jint color) {
+ activateContext();
+ setColor(color);
+ glBegin(GL_QUADS); {
+ glVertex3f(x1,y1,0.0f );
+ glVertex3f(x3,y2,0.0f );
+ glVertex3f(x4,y2,0.0f );
+ glVertex3f(x2,y1,0.0f );
+ } glEnd();
+}
+
+void OpenGL$GLPixelBuffer::setClip(jint x1, jint y1, jint x2, jint y2) {
+ //fprintf(stderr,"setClip: %d %d %d %d\n",x1,y1,x2,y2);
+ if(x1==0 && y1==0 && x2==width && y2==height) {
+ if(glScissorEnabled) {
+ activateContext();
+ glDisable(GL_SCISSOR_TEST);
+ glScissorEnabled = false;
+ }
+ return;
+ }
+ activateContext();
+ if(!glScissorEnabled) {
+ glEnable(GL_SCISSOR_TEST);
+ glScissorEnabled = true;
+ }
+ if((x1 >= x2) || (y1 >= y2))
+ glScissor(0,0,0,0);
+ else
+ glScissor(x1,height-y2,x2-x1,y2-y1);
+ checkGLError();
+}
+
+void OpenGL$GLPixelBuffer::resetClip() {
+ activateContext();
+ if(glScissorEnabled) {
+ glDisable(GL_SCISSOR_TEST);
+ glScissorEnabled = false;
+ }
+}
+
+// FEATURE: Eliminate duplicate code in RectGLPicture and SquareGLPicture
+void OpenGL$RectGLPicture::natInit(Object *data_, jboolean alphaOnly) {
+ unsigned char *buf;
+ int i,j;
+ int size = width*height;
+ GLuint tex;
+
+ if(alphaOnly) {
+ jbyte *data = elements((JArray<jbyte> *)data_);
+ buf = (unsigned char *) data;
+ } else {
+ jint *data = elements((JArray<jint> *)data_);
+ buf = new unsigned char[size*4];
+ for(i=0,j=0;i<size;i++,j+=4) {
+ jint pixel = data[i];
+ buf[j+0] = (pixel >> 16) & 0xff;
+ buf[j+1] = (pixel >> 8) & 0xff;
+ buf[j+2] = (pixel >> 0) & 0xff;
+ buf[j+3] = (pixel >> 24) & 0xff;
+ }
+ }
+
+ gl->activateSharedContext();
+ glEnable(GL_TEXTURE_RECTANGLE_EXT);
+ glGenTextures(1,&tex);
+ glBindTexture(GL_TEXTURE_RECTANGLE_EXT,tex);
+ glPixelStorei(GL_PACK_ALIGNMENT,1);
+ glTexImage2D(
+ GL_TEXTURE_RECTANGLE_EXT,0,
+ alphaOnly ? GL_ALPHA : GL_RGBA,width,height,0,
+ alphaOnly ? GL_ALPHA : GL_RGBA,GL_UNSIGNED_BYTE,buf);
+ if(!alphaOnly)
+ delete buf;
+
+ if(gl->glVersion >= 1.2) {
+ glTexParameteri(GL_TEXTURE_RECTANGLE_EXT,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_RECTANGLE_EXT,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
+ glTexParameterf(GL_TEXTURE_RECTANGLE_EXT,GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameterf(GL_TEXTURE_RECTANGLE_EXT,GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ } else {
+ glTexParameteri(GL_TEXTURE_RECTANGLE_EXT,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_RECTANGLE_EXT,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
+ }
+
+ glDisable(GL_TEXTURE_RECTANGLE_EXT);
+ checkGLError();
+
+ textureName = (jint)tex;
+}
+
+void OpenGL$RectGLPicture::draw(jint dx, jint dy, jint cx1, jint cy1, jint cx2, jint cy2) {
+ cx1 = max(dx, cx1);
+ cy1 = max(dy, cy1);
+ cx2 = min(cx2, dx + width);
+ cy2 = min(cy2, dy + height);
+ if (cy2 <= cy1 || cx2 <= cx1) return;
+ glEnable(GL_TEXTURE_RECTANGLE_EXT);
+ glBindTexture(GL_TEXTURE_RECTANGLE_EXT, textureName);
+ glBegin(GL_QUADS); {
+ glTexCoord2i (cx1 - dx, cy1 - dy );
+ glVertex3i (cx1, cy1, 0);
+ glTexCoord2i (cx2 - dx, cy1 - dy );
+ glVertex3i (cx2, cy1, 0);
+ glTexCoord2i (cx2 - dx, cy2 - dy );
+ glVertex3i (cx2, cy2, 0);
+ glTexCoord2i (cx1 - dx, cy2 - dy );
+ glVertex3i (cx1, cy2, 0);
+ } glEnd();
+ glDisable(GL_TEXTURE_RECTANGLE_EXT);
+ checkGLError();
+}
+
+void OpenGL::natDeleteTexture(jint tex_) {
+ activateSharedContext();
+ GLuint tex = (GLuint) tex_;
+ glDeleteTextures(1,&tex);
+}
+
+void OpenGL$SquareGLPicture::natInit(Object *data_, jboolean alphaOnly) {
+ unsigned char *buf;
+ int row,col,p;
+ GLuint tex;
+
+ if(alphaOnly) {
+ jbyte *data = elements((JArray<jbyte>*) data_);
+ if(texWidth == width && texHeight == height) {
+ buf = (unsigned char*) data;
+ } else {
+ buf = new unsigned char[texWidth*texHeight];
+ p=0;
+ for(row=0;row<height;row++) {
+ for(col=0;col<width;col++)
+ buf[p++] = data[row*width+col];
+ for(;col<texWidth;col++)
+ buf[p++] = 0;
+ }
+ for(;row<texHeight;row++)
+ for(col=0;col<texWidth;col++)
+ buf[p++] = 0;
+ }
+ } else {
+ jint *data = elements((JArray<jint>*) data_);
+ buf = new unsigned char[texWidth*texHeight*4];
+ p=0;
+ for(row=0;row<height;row++) {
+ for(col=0;col<width;col++) {
+ jint pixel = data[row*width+col];
+ buf[p+0] = (pixel >> 16) & 0xff;
+ buf[p+1] = (pixel >> 8) & 0xff;
+ buf[p+2] = (pixel >> 0) & 0xff;
+ buf[p+3] = (pixel >> 24) & 0xff;
+ p+=4;
+ }
+ for(;col < texWidth;col++,p+=4)
+ buf[p+0] = buf[p+1] = buf[p+2] = buf[p+3] = 0;
+ }
+ for(;row < texHeight;row++)
+ for(col=0;col<texWidth;col++,p+=4)
+ buf[p+0] = buf[p+1] = buf[p+2] = buf[p+3] = 0;
+ }
+
+ gl->activateSharedContext();
+ glEnable(GL_TEXTURE_2D);
+ glGenTextures(1,&tex);
+ glBindTexture(GL_TEXTURE_2D,tex);
+ glPixelStorei(GL_PACK_ALIGNMENT,1);
+ glTexImage2D(GL_TEXTURE_2D,0,alphaOnly ? GL_ALPHA : GL_RGBA,texWidth,texHeight,0,alphaOnly ? GL_ALPHA : GL_RGBA,GL_UNSIGNED_BYTE,buf);
+ checkGLError();
+ if(!alphaOnly || width != texWidth || height != texHeight) delete buf;
+
+ if(gl->glVersion >= 1.2) {
+ glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
+ glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ } else {
+ glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
+ }
+
+ glDisable(GL_TEXTURE_2D);
+ checkGLError();
+
+ textureName = (jint)tex;
+}
+
+void OpenGL$SquareGLPicture::draw(jint dx, jint dy, jint cx1, jint cy1, jint cx2, jint cy2) {
+ cx1 = max(dx, cx1);
+ cy1 = max(dy, cy1);
+ cx2 = min(cx2, dx + width);
+ cy2 = min(cy2, dy + height);
+ if (cy2 <= cy1 || cx2 <= cx1) return;
+ float tx1 = (float) (cx1 - dx) / (float) texWidth;
+ float ty1 = (float) (cy1 - dy) / (float) texHeight;
+ float tx2 = (float) (cx2 - dx) / (float) texWidth;
+ float ty2 = (float) (cy2 - dy) / (float) texHeight;
+ glEnable(GL_TEXTURE_2D);
+ glBindTexture(GL_TEXTURE_2D, textureName);
+ checkGLError();
+ glBegin(GL_QUADS); {
+ glTexCoord2f (tx1, ty1 );
+ glVertex3i (cx1, cy1, 0);
+ glTexCoord2f (tx2, ty1 );
+ glVertex3i (cx2, cy1, 0);
+ glTexCoord2f (tx2, ty2 );
+ glVertex3i (cx2, cy2, 0);
+ glTexCoord2f (tx1, ty2 );
+ glVertex3i (cx1, cy2, 0);
+ } glEnd();
+ glDisable(GL_TEXTURE_2D);
+ checkGLError();
+}
+
+} } } // end org::ibex::plat
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [LGPL]
+// Author: Brian Alliet
+
+package org.ibex.plat;
+import org.ibex.js.*;
+import org.ibex.util.*;
+import org.ibex.graphics.*;
+import org.ibex.core.*;
+import org.ibex.net.*;
+
+abstract class OpenGL {
+ static final boolean pretendToBeACrappyVideoCard = false;
+ boolean rectangularTextures;
+ boolean hasRectangularTextures() { return rectangularTextures; }
+ int maxTexSize;
+ int maxRectTexSize;
+ float glVersion;
+ String version;
+ String renderer;
+ String vendor;
+
+ private native void natInit();
+
+ private static float parseVersion(String s) {
+ int end = s.indexOf(' ');
+ if(end < 0) end = s.length();
+ try {
+ return Float.parseFloat(s.substring(0,end));
+ } catch(NumberFormatException e) {
+ return 1.1f; // just a guess
+ }
+ }
+
+ // This MUST be called after OpenGL is instansiated (and activateSharedContext is functioning)
+ public void init() throws NotSupportedException {
+ natInit();
+ glVersion = parseVersion(version);
+ if(glVersion < 1.1) throw new NotSupportedException("OpenGL 1.1 or greater is required. (you have: " + version +" - " + glVersion + ")");
+ if(pretendToBeACrappyVideoCard) {
+ maxTexSize = 512;
+ maxRectTexSize = 0;
+ rectangularTextures = false;
+ }
+ Log.diag(this,"Renderer: " + renderer);
+ Log.diag(this,"Version: " + version);
+ Log.diag(this,"Vendor: " + vendor);
+ Log.diag(this,"Rectangular textures: " + (rectangularTextures ? "supported" : "unsupported"));
+ Log.diag(this,"Max texture size: " + maxTexSize);
+ Log.diag(this,"Max rectangular texture size: " + maxRectTexSize);
+ }
+
+ protected abstract void activateSharedContext();
+
+ public static class NotSupportedException extends Exception {
+ public NotSupportedException(String s) { super(s); }
+ }
+
+ public static abstract class GLPixelBuffer extends PixelBuffer {
+ protected int width;
+ protected int height;
+ public int getWidth() { return width; }
+ public int getHeight() { return height; }
+
+ private boolean glScissorEnabled = false;
+
+ public GLPixelBuffer(int width, int height) {
+ this.width = width;
+ this.height = height;
+ }
+
+ // This should activate the drawing context and prepare the double buffer for drawing
+ protected abstract void activateContext();
+
+ protected static native void drawableInit(int w, int h);
+
+ private static native void setColor(int color);
+
+ public native void setClip(int x, int y, int x2, int y2);
+ public native void resetClip();
+ public native void fillTrapezoid(int x1, int x2, int y1, int x3, int x4, int y2, int color);
+
+ public void drawString(String font, String text, int x, int y, int color) {
+ //System.out.println("drawString(): " + text);
+ }
+
+ public void drawGlyph(org.ibex.graphics.Font.Glyph source, int dx, int dy, int cx1, int cy1, int cx2, int cy2, int rgb) {
+ drawPicture_(((org.ibex.plat.Platform.DefaultGlyph)source).getPicture(), dx, dy, cx1, cy1, cx2, cy2, rgb);
+ }
+ public void drawPicture(Picture source, int dx, int dy, int cx1, int cy1, int cx2, int cy2) {
+ drawPicture_(source, dx, dy, cx1, cy1, cx2, cy2, 0xffffffff);
+ }
+
+ private void drawPicture_(Picture source, int dx, int dy, int cx1, int cy1, int cx2, int cy2, int color) {
+ activateContext();
+ setColor(color);
+ GLPicture p = getInnerPicture(source, gl);
+ p.draw(dx,dy,cx1,cy1,cx2,cy2);
+ }
+ }
+
+ // FIXME ugly
+ public static OpenGL gl = null;
+ public OpenGL() { gl = this; }
+
+ public final static int roundToPowerOf2(int n) {
+ if(((n-1)&n)==0) return n;
+ for(int x=2;x!=0;x<<=1) if(n < x) return x;
+ return 0;
+ }
+
+ private static GLPicture getInnerPicture(Picture p, OpenGL gl) {
+ OpenGLPicture oglp = (OpenGLPicture)p;
+ if (!oglp.isLoaded || oglp.realPicture != null) return oglp.realPicture;
+ if (gl.rectangularTextures && p.width <= gl.maxRectTexSize && p.height <= gl.maxRectTexSize)
+ oglp.realPicture = new RectGLPicture(p.data,p.width,p.height,oglp.alphaOnly,gl);
+ else if (p.width <= gl.maxTexSize && p.height <= gl.maxTexSize)
+ oglp.realPicture = new SquareGLPicture(p.data,p.width,p.height,oglp.alphaOnly,gl);
+ else
+ oglp.realPicture = new MosaicGLPicture(p.data,p.width,p.height,oglp.alphaOnly,gl);
+ p.data = null;
+ return oglp.realPicture;
+ }
+
+ public Picture _createPicture(JS r, boolean alphaOnly) { return new OpenGLPicture(r, false); }
+
+ public static class OpenGLPicture extends Picture {
+ public OpenGLPicture(JS r, boolean a) { super(r); alphaOnly = a; }
+ boolean alphaOnly;
+ GLPicture realPicture = null;
+ }
+
+ public Font.Glyph _createGlyph(org.ibex.graphics.Font f, char c) { return new org.ibex.plat.Platform.DefaultGlyph(f, c); }
+
+ private native void natDeleteTexture(int tex);
+ public void deleteTexture(final int tex) {
+ // CHECKME: Is this safe to do from finalize()?
+ // natDeleteTexture MUST be run from the message queue thread
+ Scheduler.add(new Task() { public void perform() { natDeleteTexture(tex); }});
+ }
+
+ private static abstract class GLPicture {
+ protected int width;
+ protected int height;
+
+ public final int getWidth() { return width; }
+ public final int getHeight() { return height; }
+
+ public GLPicture(int w, int h) {
+ this.width = w;
+ this.height = h;
+ }
+
+ public abstract void draw(int dx, int dy, int cx1, int cy1, int cx2, int cy2);
+ protected abstract void finalize();
+ }
+
+ private static class RectGLPicture extends GLPicture {
+ private OpenGL gl;
+ public int textureName;
+
+ public native void natInit(Object data, boolean alphaOnly);
+
+ public RectGLPicture(Object data,int w, int h, boolean alphaOnly, OpenGL gl) {
+ super(w,h);
+ this.gl = gl;
+ natInit(data,alphaOnly);
+ }
+
+ public native void draw(int dx, int dy, int cx1, int cy1, int cx2, int cy2);
+ protected void finalize() { gl.deleteTexture(textureName); }
+ }
+
+ private static class SquareGLPicture extends GLPicture {
+ private int texHeight;
+ private int texWidth;
+ private OpenGL gl;
+ public int textureName;
+
+ public native void natInit(Object data, boolean alphaOnly);
+
+ public SquareGLPicture(Object data,int w, int h, boolean alphaOnly, OpenGL gl) {
+ super(w,h);
+ this.gl = gl;
+ if(w > 0x7fffffff || h > 0x7fffffff) throw new Error("insane texture size: " + w + "x" + h);
+ texHeight = roundToPowerOf2(h);
+ texWidth = roundToPowerOf2(w);
+ natInit(data,alphaOnly);
+ }
+
+ public native void draw(int dx, int dy, int cx1, int cy1, int cx2, int cy2);
+ protected void finalize() { gl.deleteTexture(textureName); }
+ }
+
+ private static class MosaicGLPicture extends GLPicture {
+ int psize;
+ GLPicture[][] pics;
+
+ private static float wastedSpace(int w,int h,int size) {
+ int w2 = size * ((w+size-1)/size);
+ int h2 = size * ((h+size-1)/size);
+ return 1.0f-(float)(w*h)/(float)(w2*h2);
+ }
+
+ private static Object subData(Object data, int x, int y, int w, int h, int rowSize) {
+ if(data instanceof byte[]) return subData((byte[])data,x,y,w,h,rowSize);
+ if(data instanceof int[]) return subData((int[])data,x,y,w,h,rowSize);
+ throw new Error("not reached");
+ }
+
+ private static int[] subData(int[] data, int x, int y, int w, int h, int rowSize) {
+ int[] sub = new int[w*h];
+ int row = y;
+ for(int i=0;i<h;i++,row++)
+ for(int j=0;j<w;j++)
+ sub[i*w+j] = data[row*rowSize+j+x];
+ return sub;
+ }
+
+ private static byte[] subData(byte[] data, int x, int y, int w, int h, int rowSize) {
+ byte[] sub = new byte[w*h];
+ int row = y;
+ for(int i=0;i<h;i++,row++)
+ for(int j=0;j<w;j++)
+ sub[i*w+j] = data[row*rowSize+j+x];
+ return sub;
+ }
+
+ public MosaicGLPicture(Object data,int w, int h, boolean alphaOnly, OpenGL gl) {
+ super(w,h);
+ psize = gl.maxTexSize;
+ while(wastedSpace(w,h,psize) > 0.40) psize/=2;
+ Log.info(this,"Using psize: " + psize + " for " + w + "x" + h + " image (wasted space: " + wastedSpace(w,h,psize));
+
+ int rows = (h+psize-1)/psize;
+ int cols = (w+psize-1)/psize;
+ int tmp,tmp2;
+
+ pics = new GLPicture[rows][cols];
+ for(int i=0;i<rows-1;i++)
+ for(int j=0;j<cols-1;j++)
+ pics[i][j] = new SquareGLPicture(subData(data,j*psize,i*psize,psize,psize,w),psize,psize,alphaOnly,gl);
+ tmp = (rows-1)*psize;
+ for(int i=0;i<cols-1;i++)
+ pics[rows-1][i] = new SquareGLPicture(subData(data,i*psize,tmp,psize,h-tmp,w),psize,h-tmp,alphaOnly,gl);
+ tmp2 = (cols-1)*psize;
+ for(int i=0;i<rows-1;i++)
+ pics[i][cols-1] = new SquareGLPicture(subData(data,tmp2,i*psize,w-tmp2,psize,w),w-tmp2,psize,alphaOnly,gl);
+ pics[rows-1][cols-1] = new SquareGLPicture(subData(data,tmp2,tmp,w-tmp2,h-tmp,w),w-tmp2,h-tmp,alphaOnly,gl);
+ }
+ protected void finalize() { }
+
+ private static final int max(int a, int b) { return a > b ? a : b; }
+ private static final int min(int a, int b) { return a < b ? a : b; }
+
+ public void draw(int dx, int dy, int cx1, int cy1, int cx2, int cy2) {
+ // *{x,y}{1,2} key: d=dest s=src, p=bounds of this picture, i=intersection of s and p, pd = dest of this pic
+ for(int i=0;i<pics.length;i++) {
+ for(int j=0;j<pics[i].length;j++) {
+ int px1 = j*psize + dx;
+ int py1 = i*psize + dy;
+ pics[i][j].draw(px1, py1, cx1, cy1, cx2, cy2);
+ }
+ }
+ }
+ }
+}
--- /dev/null
+// Copyright 2002 Adam Megacz, see the COPYING file for licensing [LGPL]
+// see below for copyright information on the second portion of this file
+
+#include <java/lang/String.h>
+#include <org/ibex/graphics/Surface.h>
+#include <org/ibex/graphics/Picture.h>
+#include <org/ibex/js/JS.h>
+#include <org/ibex/core/Box.h>
+#include <org/ibex/util/Semaphore.h>
+#include <org/ibex/plat/Platform.h>
+#include <java/lang/Long.h>
+#include <java/util/Hashtable.h>
+#include <org/ibex/util/Log.h>
+#include <org/ibex/plat/POSIX.h>
+#include <java/lang/System.h>
+#include <java/io/PrintStream.h>
+
+#include "GCJ.cc"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <sys/types.h>
+#include <signal.h>
+
+jstring org::ibex::plat::POSIX::_getEnv(jstring key) {
+ int len = JvGetStringUTFLength(key);
+ char buf[len + 1];
+ JvGetStringUTFRegion(key, 0, len, buf);
+ buf[len] = '\0';
+ char* envstr = getenv(buf);
+ return envstr == NULL ? NULL : JvNewStringLatin1(envstr);
+}
+
+void org::ibex::plat::POSIX::spawnChildProcess(JArray<jstring>* cmd) {
+ jstring* cmdstrings = elements(cmd);
+ char* cmd2[cmd->length + 1];
+ cmd2[cmd->length] = NULL;
+ for(int i=0; i<cmd->length; i++) {
+ cmd2[i] = (char*)malloc(JvGetStringUTFLength(cmdstrings[i]));
+ JvGetStringUTFRegion(cmdstrings[i], 0, JvGetStringUTFLength(cmdstrings[i]), cmd2[i]);
+ }
+
+ if (!fork()) {
+ signal(SIGHUP, SIG_IGN);
+ signal(SIGQUIT, SIG_IGN);
+ signal(SIGINT, SIG_IGN);
+ signal(SIGTERM, SIG_IGN);
+
+ // ignore SIGPIPE in case we were launched from a browser and the browser closed
+ signal(SIGPIPE, SIG_IGN);
+
+ execvp(cmd2[0], cmd2);
+ }
+}
+
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [LGPL]
+package org.ibex.plat;
+
+import java.util.*;
+import org.ibex.graphics.*;
+import org.ibex.core.*;
+import org.ibex.net.*;
+
+/** Platform implementation for POSIX compliant operating systems */
+public class POSIX extends GCJ {
+
+ // General Methods ///////////////////////////////////////////////////////
+
+ protected String getDescriptiveName() { return "GCJ Linux Binary"; }
+
+ /** returns the value of the environment variable key, or null if no such key exists */
+ protected native String _getEnv(String key);
+
+ /** spawns a process which is immune to SIGHUP */
+ private static native void spawnChildProcess(String[] command);
+
+ protected void _newBrowserWindow(String url) {
+ String browserString = getEnv("BROWSER");
+ if (browserString == null) {
+ browserString = "netscape " + url;
+ } else if (browserString.indexOf("%s") != -1) {
+ browserString =
+ browserString.substring(0, browserString.indexOf("%s")) +
+ url + browserString.substring(browserString.indexOf("%s") + 2);
+ } else {
+ browserString += " " + url;
+ }
+
+ StringTokenizer st = new StringTokenizer(browserString, " ");
+ String[] cmd = new String[st.countTokens()];
+ for(int i=0; st.hasMoreTokens(); i++) cmd[i] = st.nextToken();
+
+ spawnChildProcess(cmd);
+ }
+
+}
+
+
+
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.plat;
+import java.io.*;
+import org.ibex.graphics.*;
+import org.ibex.core.*;
+import org.ibex.net.*;
+
+/** Platform class for PalmOS devices */
+public class PalmOS extends Platform {
+
+ public static int PilotMain(int cmd, int cmdBPB, int launchFlags) {
+ //Main.main(new String[] { });
+ return 0;
+ }
+
+ protected void _decodeJPEG(InputStream is, Picture p) {
+ throw new Error("unimplemented");
+ }
+
+}
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.plat;
+
+import java.lang.reflect.*;
+import java.net.*;
+import java.io.*;
+import org.ibex.js.*;
+import org.ibex.util.*;
+import org.ibex.graphics.*;
+import org.ibex.core.*;
+import org.ibex.graphics.*;
+import org.ibex.core.*;
+import org.ibex.net.*;
+
+/**
+ * Abstracts away the small irregularities in JVM implementations.
+ *
+ * The default Platform class supports a vanilla JDK 1.1
+ * JVM. Subclasses are provided for other VMs. Methods whose names
+ * start with an underscore are meant to be overridden by
+ * subclasses. If you create a subclass of Platform, you should put
+ * it in the org.ibex.plat package, and add code to this file's static
+ * block to detect the new platform.
+ */
+public abstract class Platform {
+
+ public Platform() { platform = this; }
+
+ // Static Data /////////////////////////////////////////////////////////////////////////////////////
+
+ public static boolean clipboardReadEnabled = false; ///< true iff inside a C-v/A-v/Press3 trap handler
+ public static Platform platform = null; ///< The appropriate Platform object for this JVM
+ public static boolean alreadyDetectedProxy = false; ///< true if proxy autodetection has already been run
+ public static org.ibex.net.HTTP.Proxy cachedProxyInfo = null; ///< the result of proxy autodetection
+ public static String build = "unknown"; ///< the current build
+
+ // VM Detection Logic /////////////////////////////////////////////////////////////////////
+
+ // If you create a new subclass of Platform, you should add logic
+ // here to detect it. Do not reference your class directly -- use
+ // reflection.
+
+ public static void forceLoad() {
+ System.err.print("Detecting JVM...");
+ try {
+ String vendor = System.getProperty("java.vendor", "");
+ String version = System.getProperty("java.version", "");
+ String os_name = System.getProperty("os.name", "");
+ String os_version = System.getProperty("os.version", "");
+ String platform_class = null;
+
+ if (vendor.startsWith("Free Software Foundation")) {
+ if (os_name.startsWith("Window")) platform_class = "Win32";
+ else if (os_name.startsWith("Linux")) platform_class = "Linux";
+ else if (os_name.startsWith("SunOS")) platform_class = "Solaris";
+ else if (os_name.startsWith("Solaris")) platform_class = "Solaris";
+ else if (os_name.startsWith("Darwin")) platform_class = "Darwin";
+ else platform_class = "X11";
+ }
+ else if (!version.startsWith("1.0") && !version.startsWith("1.1")) platform_class = "Java2";
+
+ if (platform_class == null) {
+ Log.error(Platform.class, "Unable to detect JVM");
+ criticalAbort("Unable to detect JVM");
+ }
+
+ System.err.println(" " + os_name + " ==> org.ibex.plat." + platform_class);
+ try {
+ if (platform_class != null) Class.forName("org.ibex.plat." + platform_class).newInstance();
+ } catch (InstantiationException e) {
+ throw e.getCause();
+ }
+
+ String term = Platform.getEnv("TERM");
+ Log.color = term != null && term.length() != 0 && !term.equals("cygwin");
+
+ try {
+ build = (String)Class.forName("org.ibex.Build").getField("build").get(null);
+ Log.diag(Platform.class, "Ibex build: " + build);
+ } catch (ClassNotFoundException cnfe) {
+ Log.warn(Platform.class, "Ibex build: unknown");
+ } catch (Exception e) {
+ Log.info(Platform.class, "exception while detecting build:");
+ Log.info(Platform.class, e);
+ }
+
+ Log.diag(Platform.class, "Ibex VM detection: vendor = " + vendor);
+ Log.diag(Platform.class, " version = " + version);
+ Log.diag(Platform.class, " os = " + os_name + " [version " + os_version + "]");
+ Log.diag(Platform.class, " platform = " + platform.getDescriptiveName());
+ Log.diag(Platform.class, " class = " + platform.getClass().getName());
+ platform.postInit();
+
+ } catch (Throwable e) {
+ Log.error(Platform.class, "Exception while trying to detect JVM");
+ Log.error(Platform.class, e);
+ criticalAbort("Unable to detect JVM");
+ }
+
+ }
+
+
+ // Methods to be Overridden ///////////////////////////////////////////////////////////////////
+
+ protected Surface _createSurface(Box b, boolean framed) { return null; }
+ protected Picture _createPicture(JS r) { return null; }
+ protected PixelBuffer _createPixelBuffer(int w, int h, Surface owner) { return null; }
+ protected Font.Glyph _createGlyph(org.ibex.graphics.Font f, char c) { return new DefaultGlyph(f, c); }
+
+ public static PixelBuffer createPixelBuffer(int w, int h, Surface s) { return platform._createPixelBuffer(w, h, s); }
+ public static Picture createPicture(JS r) { return platform._createPicture(r); }
+ public static Font.Glyph createGlyph(org.ibex.graphics.Font f, char c) { return platform._createGlyph(f, c); }
+ public static Surface createSurface(Box b, boolean framed, boolean refreshable) {
+ Surface ret = platform._createSurface(b, framed);
+ ret.setInvisible(false);
+ if (refreshable) {
+ Surface.allSurfaces.addElement(ret);
+ ret.dirty(0, 0, b.width, b.height);
+ ret.Refresh();
+ }
+ try {
+ if (b.get("titlebar") != null) ret.setTitleBarText((String)b.get("titlebar"));
+ } catch (JSExn e) {
+ Log.warn(Platform.class, e);
+ }
+ return ret;
+ }
+
+ /** a string describing the VM */
+ protected String getDescriptiveName() { return "Generic Java 1.1 VM"; }
+
+ /** invoked after initialization messages have been printed; useful for additional platform detection log messages */
+ protected void postInit() { }
+
+ /** the human-readable name of the key mapped to Ibex's 'alt' key */
+ public static String altKeyName() { return platform._altKeyName(); }
+ protected String _altKeyName() { return "alt"; }
+
+ /** returns the contents of the clipboard */
+ public static Object getClipBoard() { return clipboardReadEnabled ? platform._getClipBoard() : null; }
+ protected String _getClipBoard() { return null; }
+
+ /** sets the contents of the clipboard */
+ public static void setClipBoard(String s) { platform._setClipBoard(s); }
+ protected void _setClipBoard(String s) { }
+
+ /** returns the width of the screen, in pixels */
+ public static int getScreenWidth() { return platform._getScreenWidth(); }
+ protected int _getScreenWidth() { return 640; }
+
+ /** returns the height of the screen, in pixels */
+ public static int getScreenHeight() { return platform._getScreenHeight(); }
+ protected int _getScreenHeight() { return 480; }
+
+ /** used to notify the user of very serious failures; usually used when logging is not working or unavailable */
+ protected void _criticalAbort(String message) { System.exit(-1); }
+ public static void criticalAbort(String message) {
+ Log.info(Platform.class, "Critical Abort:");
+ Log.info(Platform.class, message);
+ platform._criticalAbort(message);
+ }
+
+ /** if true, org.ibex.Surface will generate a Click automatically after a press and a release */
+ public static boolean needsAutoClick() { return platform._needsAutoClick(); }
+ protected boolean _needsAutoClick() { return false; }
+
+ /** if true, org.ibex.Surface will generate a DoubleClick automatically after recieving two clicks in a short period of time */
+ public static boolean needsAutoDoubleClick() { return platform._needsAutoDoubleClick(); }
+ protected boolean _needsAutoDoubleClick() { return false; }
+
+ /** returns true iff the platform has a case-sensitive filesystem */
+ public static boolean isCaseSensitive() { return platform._isCaseSensitive(); }
+ protected boolean _isCaseSensitive() { return true; }
+
+ /** returns an InputStream to the builtin xwar */
+ public static InputStream getBuiltinInputStream() { return platform._getBuiltinInputStream(); }
+ protected InputStream _getBuiltinInputStream() {return getClass().getClassLoader().getResourceAsStream("org/ibex/builtin.jar");}
+
+ /** returns the value of the environment variable key, or null if no such key exists */
+ public static String getEnv(String key) { return platform._getEnv(key); }
+ protected String _getEnv(String key) {
+ try {
+ String os = System.getProperty("os.name").toLowerCase();
+ Process p;
+ if (os.indexOf("windows 9") != -1 || os.indexOf("windows me") != -1) {
+ // hack -- jdk1.2/1.3 on Win32 pop open an ugly DOS box; 1.4 does not
+ if (platform.getClass().getName().endsWith("Java12")) return null;
+ p = Runtime.getRuntime().exec("command.com /c set");
+ } else if (os.indexOf("windows") > -1) {
+ // hack -- jdk1.2/1.3 on Win32 pop open an ugly DOS box; 1.4 does not
+ if (platform.getClass().getName().endsWith("Java12")) return null;
+ p = Runtime.getRuntime().exec("cmd.exe /c set");
+ } else {
+ p = Runtime.getRuntime().exec("env");
+ }
+ BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
+ String s;
+ while ((s = br.readLine()) != null)
+ if (s.startsWith(key + "="))
+ return s.substring(key.length() + 1);
+ } catch (Exception e) {
+ Log.info(this, "Exception while reading from environment:");
+ Log.info(this, e);
+ }
+ return null;
+ }
+
+ /** convert a JPEG into an Image */
+ public static synchronized void decodeJPEG(InputStream is, Picture p) { platform._decodeJPEG(is, p); }
+ protected abstract void _decodeJPEG(InputStream is, Picture p);
+
+ /** displays a platform-specific "open file" dialog and returns the chosen filename, or null if the user hit cancel */
+ protected String _fileDialog(String suggestedFileName, boolean write) { return null; }
+ public static String fileDialog(String suggestedFileName, boolean write) throws org.ibex.js.JSExn {
+ return platform._fileDialog(suggestedFileName, write);
+ }
+
+ /** default implementation is Eric Albert's BrowserLauncher.java */
+ protected void _newBrowserWindow(String url) {
+ try {
+ Class c = Class.forName("edu.stanford.ejalbert.BrowserLauncher");
+ Method m = c.getMethod("openURL", new Class[] { String.class });
+ m.invoke(null, new String[] { url });
+ } catch (Exception e) {
+ Log.warn(this, "exception trying to open a browser window");
+ Log.warn(this, e);
+ }
+ }
+
+ /** opens a new browser window */
+ public static void newBrowserWindow(String url) {
+ if (!(url.startsWith("https://") || url.startsWith("http://") || url.startsWith("ftp://") || url.startsWith("mailto:"))) {
+ Log.info(Platform.class, "ibex.newBrowserWindow() only supports http and https urls");
+ return;
+ }
+ // check the URL for well-formedness, as a defense against buffer overflow attacks
+ // FIXME check URL without using URL class
+ /*
+ try {
+ String u = url;
+ if (u.startsWith("https")) u = "http" + u.substring(5);
+ new URL(u);
+ } catch (MalformedURLException e) {
+ Log.info(Platform.class, "URL " + url + " is not well-formed");
+ Log.info(Platform.class, e);
+ }
+ */
+ Log.info(Platform.class, "newBrowserWindow, url = " + url);
+ platform._newBrowserWindow(url);
+ }
+
+ /** detects proxy settings */
+ protected synchronized org.ibex.net.HTTP.Proxy _detectProxy() { return null; }
+ public static synchronized org.ibex.net.HTTP.Proxy detectProxy() {
+
+ if (cachedProxyInfo != null) return cachedProxyInfo;
+ if (alreadyDetectedProxy) return null;
+ alreadyDetectedProxy = true;
+
+ Log.info(Platform.class, "attempting environment-variable DNS proxy detection");
+ cachedProxyInfo = org.ibex.net.HTTP.Proxy.detectProxyViaManual();
+ if (cachedProxyInfo != null) return cachedProxyInfo;
+
+ Log.info(Platform.class, "attempting " + platform.getClass().getName() + " proxy detection");
+ cachedProxyInfo = platform._detectProxy();
+ if (cachedProxyInfo != null) return cachedProxyInfo;
+
+ return cachedProxyInfo;
+ }
+
+ /** returns a Scheduler instance; used to implement platform-specific schedulers */
+ protected Scheduler _getScheduler() { return new Scheduler(); }
+ public static Scheduler getScheduler() { return platform._getScheduler(); }
+
+ // FEATURE: be more efficient for many of the subclasses
+ public static class DefaultGlyph extends Font.Glyph {
+ private Picture p = null;
+ public DefaultGlyph(org.ibex.graphics.Font f, char c) { super(f, c); }
+ public Picture getPicture() {
+ if (p == null && isLoaded) {
+ Picture p = createPicture(null);
+ p.data = new int[data.length];
+ for(int i=0; i<data.length; i++) p.data[i] = (data[i] & 0xff) << 24;
+ this.data = null;
+ p.width = this.width;
+ p.height = this.height;
+ p.isLoaded = true;
+ this.p = p;
+ }
+ return p;
+ }
+ }
+}
+
+
--- /dev/null
+#include <sys/int_types.h>
+
+// HACK
+typedef unsigned long long uint64_t;
+
+#include "X11.cc"
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.plat;
+
+/** Solaris with an X11 display */
+public class Solaris extends X11 {
+}
--- /dev/null
+// Copyright 2002 Adam Megacz, see the COPYING file for licensing [LGPL]
+#include "GCJ.cc"
+
+// we have to do this because the jpeg libraries use the symbol 'INT32'
+#define INT32 WIN32_INT32
+
+// this has to precede the others so we don't get collisions on min/max
+#include <org/ibex/js/JS.h>
+#include <org/ibex/Box.h>
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <windows.h>
+#include <mmsystem.h>
+#undef STRICT
+#undef MAX_PRIORITY
+#undef MIN_PRIORITY
+#undef NORM_PRIORITY
+
+#include <gcj/cni.h>
+
+#include <java/lang/Integer.h>
+#include <java/util/Hashtable.h>
+#include <org/ibex/Box.h>
+#include <org/ibex/Surface.h>
+#include <org/ibex/PixelBuffer.h>
+#include <org/ibex/Picture.h>
+#include <org/ibex/Platform.h>
+#include <org/ibex/plat/Win32.h>
+#include <org/ibex/plat/Win32$Win32Surface.h>
+#include <org/ibex/plat/Win32$Win32PixelBuffer.h>
+#include <org/ibex/plat/Win32$Win32Picture.h>
+#include <org/ibex/util/Log.h>
+#include <org/ibex/util/Semaphore.h>
+
+// for debugging
+#include <java/lang/System.h>
+#include <java/io/PrintStream.h>
+
+#define WM_USER_SETCURSOR WM_USER
+#define WM_USER_DISPOSE (WM_USER + 1)
+#define WM_USER_CREATEWINDOW (WM_USER + 2)
+#define WS_NORMAL (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX)
+
+// FEATURE: there are lots of places where HANDLE's get casted to jint's -- this will break on Win64
+// a clean way to do this would be to '#define jraw (gnu::gcj::RawData*)'
+
+// Callbacks ////////////////////////////////////////////////////////////////////
+
+LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) {
+ org::ibex::plat::Win32$Win32Surface* surface =
+ (org::ibex::plat::Win32$Win32Surface*)org::ibex::plat::Win32::hwndToWin32SurfaceMap->get(new java::lang::Integer((jint)hwnd));
+
+ if (surface != NULL) {
+ return (LRESULT)surface->WndProc((jint)hwnd, (jint)iMsg, (jint)wParam, (jint)lParam);
+
+ } else {
+ // this is really lame -- Win32 insists on being able to call your WndProc BEFORE CreateWindow returns...
+ return DefWindowProc(hwnd, iMsg, wParam, lParam);
+ }
+}
+
+
+// Initialization ////////////////////////////////////////////////////////////////////
+
+static int window_class_counter = 0;
+
+jstring org::ibex::plat::Win32::getTempPath() {
+ char buf[1024];
+ DWORD ret = GetTempPath(1024, buf);
+ if (ret == 0) criticalAbort(JvNewStringLatin1("GetTempPath() failed"));
+ return JvNewStringLatin1(buf);
+}
+
+// XOR mask for the hand cursor
+static unsigned char hand_cursor_xor[32 * 4] = {
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x0C, 0x00, 0x00,
+ 0x00, 0x0C, 0x00, 0x00,
+ 0x00, 0x0C, 0x00, 0x00,
+ 0x00, 0x0C, 0x00, 0x00,
+ 0x00, 0x0C, 0x00, 0x00,
+ 0x00, 0x0D, 0x80, 0x00,
+ 0x00, 0x0D, 0xB0, 0x00,
+ 0x00, 0x0D, 0xB4, 0x00,
+ 0x00, 0x0D, 0xB6, 0x00,
+ 0x00, 0xCF, 0xF6, 0x00,
+ 0x00, 0xEF, 0xFE, 0x00,
+ 0x00, 0x6F, 0xFE, 0x00,
+ 0x00, 0x2F, 0xFE, 0x00,
+ 0x00, 0x3F, 0xFE, 0x00,
+ 0x00, 0x1F, 0xFE, 0x00,
+ 0x00, 0x1F, 0xFC, 0x00,
+ 0x00, 0x0F, 0xFC, 0x00,
+ 0x00, 0x0F, 0xFC, 0x00,
+ 0x00, 0x07, 0xF8, 0x00,
+ 0x00, 0x07, 0xF8, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00
+};
+
+// AND mask for the hand cursor
+static unsigned char hand_cursor_and[32 * 4] = {
+ 0xFF, 0xF3, 0xFF, 0xFF,
+ 0xFF, 0xE1, 0xFF, 0xFF,
+ 0xFF, 0xE1, 0xFF, 0xFF,
+ 0xFF, 0xE1, 0xFF, 0xFF,
+ 0xFF, 0xE1, 0xFF, 0xFF,
+ 0xFF, 0xE0, 0x7F, 0xFF,
+ 0xFF, 0xE0, 0x0F, 0xFF,
+ 0xFF, 0xE0, 0x03, 0xFF,
+ 0xFF, 0xE0, 0x01, 0xFF,
+ 0xFF, 0x20, 0x00, 0xFF,
+ 0xFE, 0x00, 0x00, 0xFF,
+ 0xFE, 0x00, 0x00, 0xFF,
+ 0xFF, 0x00, 0x00, 0xFF,
+ 0xFF, 0x80, 0x00, 0xFF,
+ 0xFF, 0x80, 0x00, 0xFF,
+ 0xFF, 0xC0, 0x00, 0xFF,
+ 0xFF, 0xC0, 0x01, 0xFF,
+ 0xFF, 0xE0, 0x01, 0xFF,
+ 0xFF, 0xE0, 0x01, 0xFF,
+ 0xFF, 0xF0, 0x03, 0xFF,
+ 0xFF, 0xF0, 0x03, 0xFF,
+ 0xFF, 0xF0, 0x03, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF
+};
+
+void org::ibex::plat::Win32::natPreInit() {
+ // Win32 throws stderr in the trash unless you designate your binary as a "console binary"
+ if (org::ibex::util::Log::logstream == java::lang::System::err) {
+ AllocConsole();
+ freopen("CONOUT$", "w+t", stderr);
+ }
+}
+
+void org::ibex::plat::Win32::natInit() {
+
+ // grab desktop dc/handle
+ desktop_handle = (jint)GetDesktopWindow();
+ desktop_dc = (jint)GetDC((HWND)desktop_handle);
+
+ // create cursors
+ org::ibex::plat::Win32::wait_cursor = (jint)LoadCursor(NULL, IDC_WAIT);
+ org::ibex::plat::Win32::default_cursor = (jint)LoadCursor(NULL, IDC_ARROW);
+ org::ibex::plat::Win32::crosshair_cursor = (jint)LoadCursor(NULL, IDC_CROSS);
+ org::ibex::plat::Win32::text_cursor = (jint)LoadCursor(NULL, IDC_IBEAM);
+ org::ibex::plat::Win32::move_cursor = (jint)LoadCursor(NULL, IDC_SIZEALL);
+ org::ibex::plat::Win32::sizenesw_cursor = (jint)LoadCursor(NULL, IDC_SIZENESW);
+ org::ibex::plat::Win32::sizens_cursor = (jint)LoadCursor(NULL, IDC_SIZENS);
+ org::ibex::plat::Win32::sizenwse_cursor = (jint)LoadCursor(NULL, IDC_SIZENWSE);
+ org::ibex::plat::Win32::sizewe_cursor = (jint)LoadCursor(NULL, IDC_SIZEWE);
+ org::ibex::plat::Win32::hand_cursor = (jint)CreateCursor(GetModuleHandle(NULL), 14, 1, 32, 32, hand_cursor_and, hand_cursor_xor);
+
+ messagePumpThread = (jint)GetCurrentThreadId();
+ messagePumpStarted->release();
+
+ MSG msg;
+ while(GetMessage(&msg, (HWND)NULL, 0, 0) > 0) {
+
+ if (msg.message == WM_USER_CREATEWINDOW) {
+ org::ibex::plat::Win32$Win32Surface *surface = (org::ibex::plat::Win32$Win32Surface*)msg.lParam;
+
+ // we must create a unique window class name for each
+ // window so that minimization icons can be set independantly
+ char buf[255];
+ sprintf(buf, "Ibex_WINDOW_CLASS_%i", window_class_counter++);
+
+ WNDCLASSEX wc;
+ wc.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
+ wc.lpfnWndProc = WndProc;
+ wc.cbClsExtra = 0;
+ wc.cbSize = sizeof(WNDCLASSEX);
+ wc.cbWndExtra = 0;
+ wc.hInstance = GetModuleHandle(NULL);
+ wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
+ wc.hIconSm = (HICON)LoadImage(GetModuleHandle(NULL),
+ MAKEINTRESOURCE(5),
+ IMAGE_ICON,
+ GetSystemMetrics(SM_CXSMICON),
+ GetSystemMetrics(SM_CYSMICON),
+ LR_DEFAULTCOLOR);
+ wc.hCursor = LoadCursor(NULL, IDC_ARROW);
+ wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
+ wc.lpszMenuName = "menu";
+ wc.lpszClassName = buf;
+ RegisterClassEx(&wc);
+
+ surface->hwnd = (jint)CreateWindow(wc.lpszClassName, TEXT(""),
+ msg.wParam ? WS_NORMAL : WS_POPUP,
+ 200, 200, 100, 100,
+ (HWND__*)NULL, (HMENU__*)NULL,
+ GetModuleHandle(NULL), (LPVOID)NULL);
+
+ SetFocus((HWND)surface->hwnd);
+ surface->hwndCreated->release();
+
+ } else {
+ TranslateMessage(&msg);
+ if (msg.message == WM_LBUTTONDOWN || msg.message == WM_RBUTTONDOWN || msg.message == WM_MBUTTONDOWN) SetFocus(msg.hwnd);
+ DispatchMessage(&msg);
+ }
+
+ }
+ java::lang::System::exit(-1);
+}
+
+
+// Platform Methods ///////////////////////////////////////////////////////////////////
+
+jstring org::ibex::plat::Win32::_getEnv(jstring key) {
+ int len = JvGetStringUTFLength(key);
+ char buf[len + 1];
+ JvGetStringUTFRegion(key, 0, len, buf);
+ buf[len] = '\0';
+ char buf2[1024];
+ DWORD ret = GetEnvironmentVariable(buf, buf2, 1024);
+ if (ret > 0 && ret < 1024) return JvNewStringLatin1(buf2);
+ return NULL;
+}
+
+jstring org::ibex::plat::Win32::_fileDialog(jstring suggestedFileName, jboolean write) {
+
+ char buf[1024];
+ OPENFILENAME ofn;
+ memset(buf, 0, 1024);
+ memset(&ofn, 0, sizeof(OPENFILENAME));
+
+ if (suggestedFileName != NULL)
+ JvGetStringUTFRegion(suggestedFileName, 0, min(1023, JvGetStringUTFLength(suggestedFileName)), buf);
+
+ ofn.lStructSize = sizeof(OPENFILENAME);
+ ofn.nMaxCustFilter = 0;
+ ofn.lpstrFile = buf;
+ ofn.nMaxFile = 1024;
+
+ if (write) ofn.Flags |= OFN_OVERWRITEPROMPT;
+ ofn.Flags |= OFN_HIDEREADONLY;
+
+ int ret = write ? GetSaveFileName(&ofn) : GetOpenFileName(&ofn);
+ return ret == 0 ? NULL : JvNewStringLatin1(buf);
+}
+
+void org::ibex::plat::Win32::__detectProxy(JArray<jstring>* container) {
+
+ HKEY hkey;
+ char buf[1024];
+ DWORD buflen = 1024;
+ DWORD type;
+ LONG result = RegOpenKey(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", &hkey);
+ if (result != ERROR_SUCCESS) return;
+
+ buf[0] = '\0';
+ type = REG_SZ;
+ buflen = 1024;
+ result = RegQueryValueEx(hkey, "AutoConfigURL", NULL, &type, (LPBYTE)buf, &buflen);
+ buf[buflen] = '\0';
+ if (result == ERROR_SUCCESS) elements(container)[2] = JvNewStringLatin1(buf);
+
+ buf[0] = '\0';
+ type = REG_BINARY;
+ RegQueryValueEx(hkey, "ProxyEnable", NULL, &type, (LPBYTE)buf, &buflen);
+ if (buf[0] != 1) return;
+
+ buf[0] = '\0';
+ type = REG_SZ;
+ buflen = 1024;
+ RegQueryValueEx(hkey, "ProxyServer", NULL, &type, (LPBYTE)buf, &buflen);
+ buf[buflen] = '\0';
+ elements(container)[0] = JvNewStringLatin1(buf);
+
+ buf[0] = '\0';
+ buflen = 1024;
+ RegQueryValueEx(hkey, "ProxyOverride", NULL, &type, (LPBYTE)buf, &buflen);
+ buf[buflen] = '\0';
+ elements(container)[1] = JvNewStringLatin1(buf);
+}
+
+jstring org::ibex::plat::Win32::_getClipBoard() {
+ OpenClipboard((HWND)desktop_handle);
+ HGLOBAL hmem = GetClipboardData(CF_TEXT);
+ if (hmem == NULL) return NULL;
+ char* buf = (char*)GlobalLock(hmem);
+ if (buf == NULL) return NULL;
+ jstring ret = JvNewStringLatin1(buf);
+ GlobalUnlock(hmem);
+ CloseClipboard();
+ return ret;
+}
+
+void org::ibex::plat::Win32::_setClipBoard(jstring s) {
+ OpenClipboard((HWND)desktop_handle);
+ HGLOBAL hmem = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, JvGetStringUTFLength(s) + 1);
+ if (hmem == NULL) return;
+ char* buf = (char*)GlobalLock(hmem);
+ if (buf == NULL) return;
+ JvGetStringUTFRegion(s, 0, JvGetStringUTFLength(s), buf);
+ buf[JvGetStringUTFLength(s)] = '\0';
+ GlobalUnlock(hmem);
+ SetClipboardData(CF_TEXT, hmem);
+ CloseClipboard();
+}
+
+void org::ibex::plat::Win32::_criticalAbort(jstring message) {
+ char buf[JvGetStringUTFLength(message) + 1];
+ buf[JvGetStringUTFLength(message)] = '\0';
+ JvGetStringUTFRegion(message, 0, JvGetStringUTFLength(message), buf);
+ MessageBox (NULL, buf, "Ibex Cannot Continue", MB_OK | MB_ICONSTOP | MB_TASKMODAL | MB_SETFOREGROUND);
+ java::lang::System::exit(-1);
+}
+
+jint org::ibex::plat::Win32::_getScreenWidth() {
+ RECT rect;
+ SystemParametersInfo(SPI_GETWORKAREA, 0, &rect, 0);
+ return rect.right - rect.left;
+}
+
+jint org::ibex::plat::Win32::_getScreenHeight() {
+ RECT rect;
+ SystemParametersInfo(SPI_GETWORKAREA, 0, &rect, 0);
+ return rect.bottom - rect.top;
+}
+
+jboolean org::ibex::plat::Win32::_newBrowserWindow_(jstring url) {
+
+ int len = min(2048, JvGetStringUTFLength(url));
+ char buf[len + 1];
+ JvGetStringUTFRegion(url, 0, len, buf);
+ buf[len] = '\0';
+
+ SHELLEXECUTEINFO ei;
+ memset(&ei, 0, sizeof(ei));
+ ei.cbSize = sizeof(ei);
+ ei.lpVerb = "open";
+ ei.lpFile = buf;
+ ei.fMask = SEE_MASK_NOCLOSEPROCESS;
+ ei.nShow = SW_SHOWDEFAULT;
+ return (ShellExecuteEx(&ei) == 0);
+
+}
+
+
+// Win32PixelBuffer /////////////////////////////////////////////////////////////////////////
+
+// This is a scratch area; when blitting a translucent image, we copy the underlying data here first.
+// Since all drawing operations are single-threaded, it's safe to use a global here.
+static HBITMAP scratch = NULL;
+static HDC scratch_dc = NULL;
+static jint* scratch_bits = NULL;
+static jint scratch_w = 0;
+static jint scratch_h = 0;
+
+#define max(a,b) ((a)>(b)?(a):(b))
+#define min(a,b) ((a)<(b)?(a):(b))
+
+void org::ibex::plat::Win32$Win32PixelBuffer::drawPicture(org::ibex::graphics::Picture* source0,
+ jint dx, jint dy,
+ jint cx1, jint cy1, jint cx2, jint cy2,
+ jint rgb, jboolean alphaOnly) {
+ org::ibex::plat::Win32$Win32Picture* source = (org::ibex::plat::Win32$Win32Picture*)source0;
+
+ cx1 = max(dx, cx1);
+ cy1 = max(dy, cy1);
+ cx2 = min(dx + source->getWidth(), cx2);
+ cy2 = min(dy + source->getHeight(), cy2);
+ if (cx1 >= cx2 || cy1 >= cy2) return;
+
+ if (source->hasalpha) {
+
+ if (scratch == NULL || scratch_w < cx2 - cx1 || scratch_h < cy2 - cy1) {
+ if (scratch_dc != NULL) DeleteDC(scratch_dc);
+ if (scratch != NULL) DeleteObject(scratch);
+ scratch_w = max(cx2 - cx1, scratch_w);
+ scratch_h = max(cy2 - cy1, scratch_h);
+
+ BITMAPINFO bitmapinfo;
+ memset(&bitmapinfo, 0, sizeof(BITMAPINFO));
+ bitmapinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bitmapinfo.bmiHeader.biWidth = scratch_w;
+ bitmapinfo.bmiHeader.biHeight = -1 * scratch_h;
+ bitmapinfo.bmiHeader.biPlanes = 1;
+ bitmapinfo.bmiHeader.biBitCount = 32;
+ bitmapinfo.bmiHeader.biCompression = BI_RGB;
+
+ // create section DIB
+ scratch = CreateDIBSection(NULL, &bitmapinfo, DIB_RGB_COLORS, (void**)&scratch_bits, NULL, 0);
+ scratch_dc = CreateCompatibleDC((HDC)org::ibex::plat::Win32::desktop_dc);
+ SelectObject(scratch_dc, scratch);
+ }
+
+ // copy from screen to scratch
+ BitBlt((HDC)scratch_dc, 0, 0, cx2 - cx1, cy2 - cy1, (HDC)hdc, cx1, cy1, SRCCOPY);
+
+ // apply alpha-blending to scratch
+ jint* dat = elements(source->data);
+
+ for(int x = cx1; x < cx2; x++)
+ for(int y = cy1; y < cy2; y++) {
+ jint dst = scratch_bits[(y - dy) * scratch_w + (x - dx)];
+
+ // FEATURE: see if we can leverage GDI to do something more clever here with alphaOnly
+ jint src = alphaOnly ? rgb : dat[(y - dy) * source->getWidth() + x - dx];
+ jint alpha = (dat[(y - dy) * source->getWidth() + x - dx] & 0xFF000000) >> 24;
+ jint r = (((src & 0x00FF0000) >> 16) * alpha + ((dst & 0x00FF0000) >> 16) * (0xFF - alpha)) / 0xFF;
+ jint g = (((src & 0x0000FF00) >> 8) * alpha + ((dst & 0x0000FF00) >> 8) * (0xFF - alpha)) / 0xFF;
+ jint b = (((src & 0x000000FF)) * alpha + ((dst & 0x000000FF)) * (0xFF - alpha)) / 0xFF;
+ scratch_bits[(y - dy) * scratch_w + (x - dx)] = (r << 16) | (g << 8) | b;
+ }
+
+ // copy back from scratch to screen
+ BitBlt((HDC)hdc, cx1, cy1, cx2 - cx1, cy2 - cy1, (HDC)scratch_dc, 0, 0, SRCCOPY);
+
+ } else {
+
+ // FIXME: support alphaOnly case here
+ if (source->hasmask) {
+ BitBlt((HDC)hdc, cx1, cy1, cx2 - cx1, cy2 - cy1, (HDC)source->maskdc, cx1 - dx, cy1 - dy, SRCAND);
+ BitBlt((HDC)hdc, cx1, cy1, cx2 - cx1, cy2 - cy1, (HDC)source->hdc, cx1 - dx, cy1 - dy, SRCPAINT);
+ } else {
+ BitBlt((HDC)hdc, cx1, cy1, cx2 - cx1, cy2 - cy1, (HDC)source->hdc, cx1 - dx, cy1 - dy, SRCCOPY);
+ }
+
+ }
+
+}
+
+void org::ibex::plat::Win32$Win32PixelBuffer::fillRect(jint x, jint y, jint x2, jint y2, jint color) {
+ jint w = x2 - x;
+ jint h = y2 - y;
+
+ // sadly, the ability to change the color of a brush didn't arrive until Win2k...
+ HBRUSH brush = CreateSolidBrush(PALETTERGB((color & 0xFF0000) >> 16, (color & 0xFF00) >> 8, color & 0xFF));
+ if (!brush) return;
+ RECT rect = { x, y, x + w, y + h };
+ FillRect((HDC)hdc, &rect, brush);
+ DeleteObject(brush);
+}
+
+void org::ibex::plat::Win32$Win32Surface::blit(org::ibex::graphics::PixelBuffer* s, jint sx, jint sy, jint dx, jint dy, jint dx2, jint dy2) {
+ // we create the DC lazily to get around some strange race condition in WinXP
+ if (hdc == 0) hdc = (jint)GetDC((HWND)hwnd);
+ BitBlt((HDC)hdc, dx, dy, dx2 - dx, dy2 - dy, (HDC)(((org::ibex::plat::Win32$Win32PixelBuffer*)s)->hdc), sx, sy, SRCCOPY);
+}
+
+void org::ibex::plat::Win32$Win32PixelBuffer::natInit() {
+ hbitmap = (jint)CreateCompatibleBitmap((HDC)org::ibex::plat::Win32::desktop_dc, w, h);
+ hdc = (jint)CreateCompatibleDC((HDC)org::ibex::plat::Win32::desktop_dc);
+ SetBkMode((HDC)hdc, TRANSPARENT);
+ SelectObject((HDC)hdc, (HBITMAP)hbitmap);
+}
+
+void org::ibex::plat::Win32$Win32PixelBuffer::finalize() {
+ DeleteObject((void*)hdc);
+ DeleteObject((void*)hbitmap);
+}
+
+
+
+// Win32Picture /////////////////////////////////////////////////////////////////////////
+
+void org::ibex::plat::Win32$Win32Picture::natInit() {
+
+ BITMAPINFO bitmapinfo;
+ memset(&bitmapinfo, 0, sizeof(BITMAPINFO));
+ bitmapinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bitmapinfo.bmiHeader.biWidth = width;
+ bitmapinfo.bmiHeader.biHeight = -1 * height;
+ bitmapinfo.bmiHeader.biPlanes = 1;
+ bitmapinfo.bmiHeader.biBitCount = 32;
+ bitmapinfo.bmiHeader.biCompression = BI_RGB;
+
+ hbitmap = (jint)CreateCompatibleBitmap((HDC)org::ibex::plat::Win32::desktop_dc, width, height);
+ hdc = (jint)CreateCompatibleDC((HDC)org::ibex::plat::Win32::desktop_dc);
+ SelectObject((HDC)hdc, (HBITMAP)hbitmap);
+ uint32_t* dat = (uint32_t*)elements(data);
+ for(int i=0; i<data->length; i++) if ((dat[i] & 0xFF000000) == 0x00000000) dat[i] = 0x00000000;
+ StretchDIBits((HDC)hdc, 0, 0, width, height, 0, 0, width, height, elements(data), &bitmapinfo, DIB_RGB_COLORS, SRCCOPY);
+
+ jint _copy[min(1024, data->length)];
+ jint* copy = data->length > 1024 ? (jint*)malloc(data->length * 4) : _copy;
+
+ memcpy(copy, elements(data), data->length * 4);
+ for(int i=0; i<data->length; i++)
+ if ((copy[i] & 0xFF000000) == 0x00000000) {
+ hasmask = 1;
+ copy[i] = 0x00FFFFFF;
+ } else if ((copy[i] & 0xFF000000) == 0xFF000000) {
+ copy[i] = 0x00000000;
+ } else {
+ hasalpha = 1;
+ hasmask = 0;
+ if (data->length > 1024) free(copy);
+ return;
+ }
+
+ if (!hasmask) {
+ if (data->length > 1024) free(copy);
+ return;
+ }
+
+ // hmask = (jint)CreateBitmap(w, h, 1, 1, NULL);
+ hmask = (jint)CreateCompatibleBitmap((HDC)org::ibex::plat::Win32::desktop_dc, width, height);
+ maskdc = (jint)CreateCompatibleDC(NULL);
+ SelectObject((HDC)maskdc, (HBITMAP)hmask);
+ StretchDIBits((HDC)maskdc, 0, 0, width, height, 0, 0, width, height, copy, &bitmapinfo, DIB_RGB_COLORS, SRCCOPY);
+ if (data->length > 1024) free(copy);
+}
+
+
+
+// Win32Surface /////////////////////////////////////////////////////////////////////////////
+
+void org::ibex::plat::Win32$Win32Surface::natInit(jboolean framed) {
+
+ // Ask the message-handling thread to create a window for us
+ PostThreadMessage((DWORD)org::ibex::plat::Win32::messagePumpThread, WM_USER + 2, (WPARAM)framed, (LPARAM)this);
+ hwndCreated->block();
+
+ // turn on incremental GC now that we have a user-visible interface
+ // [[this is causing segfaults; enable it later...]]
+ // GC_enable_incremental();
+
+ ShowWindow ((HWND)hwnd, SW_SHOWDEFAULT);
+}
+
+void org::ibex::plat::Win32$Win32Surface::finalize() { /* DeleteObject((void*)hwnd); */ }
+void org::ibex::plat::Win32$Win32Surface::toFront() { BringWindowToTop((HWND)hwnd); }
+void org::ibex::plat::Win32$Win32Surface::toBack() { SetWindowPos((HWND)hwnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); }
+void org::ibex::plat::Win32$Win32Surface::_dispose() { PostMessage((HWND)hwnd, WM_USER_DISPOSE, 0, 0); }
+void org::ibex::plat::Win32$Win32Surface::setInvisible(jboolean h) { ShowWindow((HWND)hwnd, h ? SW_HIDE : SW_SHOWNORMAL); }
+void org::ibex::plat::Win32$Win32Surface::_setMinimized(jboolean m) { ShowWindow((HWND)hwnd, m ? SW_SHOWMINIMIZED : SW_SHOWNORMAL); }
+void org::ibex::plat::Win32$Win32Surface::_setMaximized(jboolean m) { ShowWindow((HWND)hwnd, m ? SW_SHOWMAXIMIZED : SW_SHOWNORMAL); }
+void org::ibex::plat::Win32$Win32Surface::postCursorChange() { PostMessage((HWND)hwnd, WM_USER_SETCURSOR, 0, 0); }
+
+void org::ibex::plat::Win32$Win32Surface::setLocation() {
+ POINT point;
+ RECT rect;
+ point.x = 0;
+ point.y = 0;
+ ClientToScreen((HWND)hwnd, &point);
+ GetWindowRect((HWND)hwnd, &rect);
+ SetWindowPos((HWND)hwnd, NULL, root->x - (point.x - rect.left), root->y - (point.y - rect.top), 0, 0, SWP_NOZORDER | SWP_NOSIZE);
+}
+
+void org::ibex::plat::Win32$Win32Surface::_setSize(jint w, jint h) {
+ RECT client_rect, window_rect;
+ GetClientRect((HWND)hwnd, &client_rect);
+ GetWindowRect((HWND)hwnd, &window_rect);
+ int width = (window_rect.right - window_rect.left) - (client_rect.right - client_rect.left) + w;
+ int height = (window_rect.bottom - window_rect.top) - (client_rect.bottom - client_rect.top) + h;
+ SetWindowPos((HWND)hwnd, NULL, 0, 0, width, height, SWP_NOZORDER | SWP_NOMOVE);
+}
+
+void org::ibex::plat::Win32$Win32Surface::setTitleBarText(java::lang::String* title) {
+ int len = min(1024, JvGetStringUTFLength(title));
+ char buf[len + 1];
+ buf[len] = '\0';
+ JvGetStringUTFRegion(title, 0, len, buf);
+ SetWindowText((HWND)hwnd, buf);
+}
+
+void org::ibex::plat::Win32$Win32Surface::setIcon(org::ibex::graphics::Picture* p0) {
+
+ org::ibex::plat::Win32$Win32Picture* p = (org::ibex::plat::Win32$Win32Picture*)p0;
+ int icon_width = GetSystemMetrics(SM_CXSMICON);
+ int icon_height = GetSystemMetrics(SM_CYSMICON);
+
+ // we create the DC lazily to get around some strange race condition in WinXP
+ if (hdc == 0) hdc = (jint)GetDC((HWND)hwnd);
+
+ // create the bitmap
+ HBITMAP bit = CreateCompatibleBitmap((HDC)hdc, icon_width, icon_height);
+ HDC memdc = CreateCompatibleDC((HDC)hdc);
+ SelectObject(memdc, bit);
+ BitBlt((HDC)memdc, 0, 0, icon_width, icon_height, (HDC)(p->hdc), 0, 0, SRCCOPY);
+
+ // create the mask
+ jint* dat = elements(p->data);
+ HBITMAP bit_mask = CreateBitmap(icon_width, icon_height * 2, 1, 1, NULL);
+ SelectObject(memdc, bit_mask);
+ for(int x=0; x<icon_width; x++)
+ for(int y=0; y<icon_height; y++) {
+ int source = dat[(x * p->getWidth()) / icon_width + ((y * p->getHeight()) / icon_height) * (p->getWidth())];
+ if ((source & 0xFF000000) != 0x00000000) SetPixel(memdc, x, y, PALETTERGB(0, 0, 0));
+ else SetPixel(memdc, x, y, PALETTERGB(255, 255, 255));
+ }
+
+ // instantiate the icon and assign it to the window class
+ ICONINFO ici;
+ ici.fIcon = 1;
+ ici.hbmMask = bit_mask;
+ ici.hbmColor = bit;
+ HICON hicon = CreateIconIndirect(&ici);
+ HICON oldicon = (HICON)SetClassLong((HWND)hwnd, GCL_HICONSM, (LONG)hicon);
+ if (oldicon != NULL) DestroyIcon(oldicon);
+ DeleteObject(memdc);
+}
+
+static jstring keyToString(WPARAM wParam);
+jint org::ibex::plat::Win32$Win32Surface::WndProc(jint _hwnd, jint _iMsg, jint _wParam, jint _lParam) {
+
+ UINT iMsg = (UINT)_iMsg;
+ WPARAM wParam = (WPARAM)_wParam;
+ LPARAM lParam = (LPARAM)_lParam;
+
+ int oldmousex, oldmousey;
+ MINMAXINFO* mmi;
+ int resizable;
+ POINT point;
+ HWND hwnd2;
+ RECT rect, rect2;
+ RECT client_rect, window_rect;
+ jboolean newinside;
+ int16_t mouse_x;
+ int16_t mouse_y;
+ int addwidth, addheight;
+
+ switch(iMsg) {
+ case WM_DEVMODECHANGE: break; // FEATURE: color depth changed
+ case WM_DISPLAYCHANGE: break; // FEATURE: screen size changed
+ case WM_MOUSEWHEEL:
+ VScroll(((jfloat)((wParam & 0xffff0000) >> 16)) / (jfloat)120);
+ break;
+
+ case WM_SYSKEYDOWN: if (GetKeyState(VK_MENU) >> (sizeof(SHORT) * 8 - 1) == 0) return 0;
+ case WM_KEYDOWN:
+ KeyPressed(keyToString(wParam));
+ return 0;
+
+ case WM_SYSKEYUP: if (GetKeyState(VK_MENU) >> (sizeof(SHORT) * 8 - 1) == 0) return 0;
+ case WM_KEYUP:
+ KeyReleased(keyToString(wParam));
+ return 0;
+
+ case WM_SETFOCUS: Focused(true); return 0;
+ case WM_KILLFOCUS: Focused(false); return 0;
+ case WM_LBUTTONDBLCLK: DoubleClick(1); return 0;
+ case WM_RBUTTONDBLCLK: DoubleClick(2); return 0;
+ case WM_MBUTTONDBLCLK: DoubleClick(3); return 0;
+ case WM_LBUTTONDOWN: Press(1); return 0;
+ case WM_RBUTTONDOWN: Press(2); return 0;
+ case WM_MBUTTONDOWN: Press(3); return 0;
+ case WM_CLOSE: Close(); return 0;
+ case WM_ERASEBKGND: return 0;
+
+ case WM_LBUTTONUP:
+ case WM_RBUTTONUP:
+ case WM_MBUTTONUP:
+ Release(iMsg == WM_LBUTTONUP ? 1 : (iMsg == WM_RBUTTONUP ? 2 : 3));
+ if (captured && !inside) {
+ ReleaseCapture();
+ SetCursor((HCURSOR)previous_cursor);
+ }
+ return 0;
+
+ case WM_MOVING:
+ GetClientRect((HWND)hwnd, &rect);
+ PosChange(rect.left, rect.top);
+ return 0;
+
+ case WM_SIZE:
+ if (wParam == SIZE_MINIMIZED) {
+ if (maximized) Maximized(false);
+ Minimized(true);
+ } else if (wParam == SIZE_MAXIMIZED) {
+ if (minimized) Minimized(false);
+ Maximized(true);
+ } else {
+ if (minimized) Minimized(false);
+ if (maximized) Maximized(false);
+ }
+ // deliberately fall through to WM_SIZING
+
+ case WM_SIZING:
+ GetClientRect((HWND)hwnd, &rect);
+ SizeChange(rect.right - rect.left, rect.bottom - rect.top);
+ return 0;
+
+ case WM_MOUSEMOVE:
+ if (mousex == lParam & 0xFFFF && mousey == (lParam & 0xFFFF0000) >> 16) return 0;
+
+ GetClientRect((HWND)hwnd, &rect);
+ point.x = mouse_x = lParam & 0xFFFF;
+ point.y = mouse_y = (lParam & 0xFFFF0000) >> 16;
+ ClientToScreen((HWND)hwnd, &point);
+ hwnd2 = WindowFromPoint(point);
+
+ newinside = hwnd2 == (HWND)hwnd && mouse_x > 0 && mouse_y > 0 && mouse_x < (rect.right - rect.left) && mouse_y < (rect.bottom - rect.top) ? 1 : 0;
+
+ Move(mouse_x, mouse_y);
+
+ if (newinside && !inside) {
+ inside = 1;
+ SetCapture((HWND)hwnd);
+ captured = 1;
+ previous_cursor = (jint)GetCursor();
+ PostMessage((HWND)hwnd, WM_USER_SETCURSOR, 0, 0);
+
+ } else if (!newinside && inside) {
+ inside = 0;
+ if (!button1 && !button2 && !button3) {
+ ReleaseCapture();
+ captured = 0;
+ SetCursor((HCURSOR)previous_cursor);
+ }
+ }
+
+ return 0;
+
+ case WM_USER_SETCURSOR:
+ // I can't find documentation of this anywhere, but in my experience, an event must be received between an invocation
+ // of SetCapture() and SetCursor(). Furthermore, it seems that after calling SetCursor(), the cursor will not change until a
+ // return from WndProc (ie the completion of the processing of some event). Hence, we use WM_USER to indicate that the screen
+ // cursor should be re-set to "current_cursor".
+ SetCursor((HCURSOR)current_cursor);
+ return 0;
+
+ case WM_USER_DISPOSE:
+ // used to signal that we should destroy ourselves
+ DestroyWindow((HWND)hwnd);
+ return 0;
+
+ case WM_GETMINMAXINFO:
+ GetClientRect((HWND)hwnd, &client_rect);
+ GetWindowRect((HWND)hwnd, &window_rect);
+ addwidth = (window_rect.right - window_rect.left) - (client_rect.right - client_rect.left);
+ addheight = (window_rect.bottom - window_rect.top) - (client_rect.bottom - client_rect.top);
+ mmi = (MINMAXINFO*)lParam;
+ mmi->ptMinTrackSize.x = ((uint32_t)root->minwidth) + addwidth;
+ mmi->ptMinTrackSize.y = ((uint32_t)root->minheight) + addheight;
+ resizable = !((root->minwidth == root->maxwidth) && (root->minheight == root->maxheight));
+ mmi->ptMaxTrackSize.x = resizable ? org::ibex::plat::Win32::getScreenWidth() : mmi->ptMinTrackSize.x;
+ mmi->ptMaxTrackSize.y = resizable ? org::ibex::plat::Win32::getScreenHeight() : mmi->ptMinTrackSize.y;
+ return 0;
+
+ case WM_PAINT:
+ PAINTSTRUCT ps;
+ BeginPaint((HWND)org::ibex::plat::Win32$Win32Surface::hwnd, &ps);
+ Dirty(ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.right - ps.rcPaint.left, ps.rcPaint.bottom - ps.rcPaint.top);
+ EndPaint((HWND)org::ibex::plat::Win32$Win32Surface::hwnd, &ps);
+ return 0;
+
+ default: break;
+ }
+
+ return DefWindowProc((HWND)hwnd, iMsg, wParam, lParam);
+}
+
+
+// Key Translator Helper /////////////////////////////////////////////////////////////////////
+
+static char keyarr [256] = { 0 };
+static jstring keyToString(WPARAM wParam) {
+ char arr[8];
+ keyarr[VK_CAPITAL] = GetKeyState(VK_CAPITAL);
+ keyarr[VK_LSHIFT] = GetKeyState(VK_LSHIFT);
+ keyarr[VK_RSHIFT] = GetKeyState(VK_RSHIFT);
+ keyarr[VK_SHIFT] = GetKeyState(VK_SHIFT);
+
+ if (ToAsciiEx(wParam, 0, (BYTE*)keyarr, (WORD*)arr, 0, GetKeyboardLayout(0)) == 1) {
+ switch (arr[0]) {
+ case '\t': return JvNewStringLatin1("tab");
+ case 0x1b: return JvNewStringLatin1("escape");
+ case '\n': return JvNewStringLatin1("enter");
+ case '\r': return JvNewStringLatin1("enter");
+ case 0x08: return JvNewStringLatin1("back_space");
+ default: return JvNewStringLatin1(arr, 1);
+ }
+
+ } else switch (wParam) {
+ case VK_CLEAR: return JvNewStringLatin1("clear");
+ case VK_SHIFT: return JvNewStringLatin1("shift");
+ case VK_CONTROL: return JvNewStringLatin1("control");
+ case VK_CAPITAL: return JvNewStringLatin1("caps_lock");
+ case VK_MENU: return JvNewStringLatin1("alt");
+ case VK_PAUSE: return JvNewStringLatin1("pause");
+ case VK_PRIOR: return JvNewStringLatin1("page_up");
+ case VK_NEXT: return JvNewStringLatin1("page_down");
+ case VK_END: return JvNewStringLatin1("end");
+ case VK_HOME: return JvNewStringLatin1("home");
+ case VK_LEFT: return JvNewStringLatin1("left");
+ case VK_UP: return JvNewStringLatin1("up");
+ case VK_RIGHT: return JvNewStringLatin1("right");
+ case VK_DOWN: return JvNewStringLatin1("down");
+ case VK_INSERT: return JvNewStringLatin1("insert");
+ case VK_DELETE: return JvNewStringLatin1("delete");
+ case VK_NUMPAD0: return JvNewStringLatin1("numpad0");
+ case VK_NUMPAD1: return JvNewStringLatin1("numpad1");
+ case VK_NUMPAD2: return JvNewStringLatin1("numpad2");
+ case VK_NUMPAD3: return JvNewStringLatin1("numpad3");
+ case VK_NUMPAD4: return JvNewStringLatin1("numpad4");
+ case VK_NUMPAD5: return JvNewStringLatin1("numpad5");
+ case VK_NUMPAD6: return JvNewStringLatin1("numpad6");
+ case VK_NUMPAD7: return JvNewStringLatin1("numpad7");
+ case VK_NUMPAD8: return JvNewStringLatin1("numpad8");
+ case VK_NUMPAD9: return JvNewStringLatin1("numpad9");
+ case VK_F1: return JvNewStringLatin1("f1");
+ case VK_F2: return JvNewStringLatin1("f2");
+ case VK_F3: return JvNewStringLatin1("f3");
+ case VK_F4: return JvNewStringLatin1("f4");
+ case VK_F5: return JvNewStringLatin1("f5");
+ case VK_F6: return JvNewStringLatin1("f6");
+ case VK_F7: return JvNewStringLatin1("f7");
+ case VK_F8: return JvNewStringLatin1("f8");
+ case VK_F9: return JvNewStringLatin1("f9");
+ case VK_F10: return JvNewStringLatin1("f10");
+ case VK_F11: return JvNewStringLatin1("f11");
+ case VK_F12: return JvNewStringLatin1("f12");
+ case VK_NUMLOCK: return JvNewStringLatin1("num_lock");
+ case VK_SCROLL: return JvNewStringLatin1("scroll_lock");
+ case VK_LSHIFT: return JvNewStringLatin1("shift");
+ case VK_RSHIFT: return JvNewStringLatin1("shift");
+ case VK_LCONTROL: return JvNewStringLatin1("control");
+ case VK_RCONTROL: return JvNewStringLatin1("control");
+ }
+ return NULL;
+}
--- /dev/null
+;; This file will be copied to bin-Win32/ibex.inf and then packed up
+;; into the .cab file for distribution
+
+[version]
+ signature="$CHICAGO$"
+ AdvancedINF=2.0
+ [Add.Code]
+ ibex.dll=ibex.dll
+ ibex.exe=ibex.exe
+ [ibex.dll]
+ file-win32-x86=thiscab
+ clsid={C60D6D23-3A7D-11d6-82F9-005056CA9250}
+ FileVersion=7,0,0,0
+ RegisterServer=yes
+ [ibex.exe]
+ file-win32-x86=thiscab
+ clsid={FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFE}
+ FileVersion=7,0,0,0
+ RegisterServer=no
+
+
+
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [LGPL]
+package org.ibex.plat;
+
+import org.ibex.util.*;
+import java.util.*;
+import org.ibex.js.*;
+import org.ibex.graphics.*;
+import org.ibex.core.*;
+import org.ibex.net.*;
+
+/** Platform specific code for GCJ-compiled Win32 binaries */
+public class Win32 extends GCJ {
+ // Initialization ////////////////////////////////////////////////////////////////////////////
+
+ // Win32 often asks for a DC/Handle when it doesn't really need one
+ static int desktop_handle = 0;
+ static int desktop_dc = 0;
+
+ // Cursors
+ static int wait_cursor = 0;
+ static int default_cursor = 0;
+ static int crosshair_cursor = 0;
+ static int text_cursor = 0;
+ static int move_cursor = 0;
+ static int sizenesw_cursor = 0;
+ static int sizens_cursor = 0;
+ static int sizenwse_cursor = 0;
+ static int sizewe_cursor = 0;
+ static int hand_cursor = 0;
+
+ /** reverse lookup from hwnd to Win32Surface */
+ public static Hashtable hwndToWin32SurfaceMap = new Hashtable();
+
+ /** lets us know that natInit() is finished */
+ public static Semaphore messagePumpStarted = new Semaphore();
+
+ /** ThreadId of the message pump thread, used to send it messages */
+ public static int messagePumpThread = 0;
+
+ public static native String getTempPath();
+ public static native void natInit();
+ public static native void natPreInit();
+
+ protected native String _fileDialog(String suggestedFileName, boolean write);
+
+ public Win32() { natPreInit(); }
+
+ public void postInit() {
+ new Thread() { public void run() { natInit(); } }.start();
+ messagePumpStarted.block();
+ }
+
+
+ // Implementation of Platform methods /////////////////////////////////////////////////////////
+
+ protected native String _getEnv(String key);
+ protected boolean _needsAutoClick() { return true; }
+ protected String getDescriptiveName() { return "GCJ Win32 Binary"; }
+ protected Surface _createSurface(Box b, boolean framed) { return new Win32Surface(b, framed); }
+ protected PixelBuffer _createPixelBuffer(int w, int h, Surface owner) { return new Win32PixelBuffer(w, h, (Win32Surface)owner); }
+ protected Picture _createPicture(JS r) { return new Win32Picture(r); }
+ protected native int _getScreenWidth();
+ protected native int _getScreenHeight();
+ protected boolean _supressDirtyOnResize() { return false; }
+ protected native void _criticalAbort(String message);
+ protected native String _getClipBoard();
+ protected native void _setClipBoard(String s);
+ protected boolean _isCaseSensitive() { return false; }
+
+ private native void __detectProxy(String[] container);
+
+ protected synchronized HTTP.Proxy _detectProxy() {
+
+ String[] container = new String[] { null, null, null };
+ if (Log.on) Log.info(this, "accessing Win32 registry");
+ __detectProxy(container);
+ if (container[2] == null && container[0] == null) {
+ if (Log.on) Log.info(this, "no proxy settings in the Win32 registry");
+ return null;
+ }
+
+ if (Log.on) Log.info(this, "PAC Script URL: " + container[2]);
+ if (Log.on) Log.info(this, "Proxy Server String: " + container[0]);
+ if (Log.on) Log.info(this, "Proxy Override String: " + container[1]);
+
+ HTTP.Proxy ret = new HTTP.Proxy();
+ if (container[2] != null) {
+ ret.proxyAutoConfigFunction = HTTP.Proxy.getProxyAutoConfigFunction(container[2]);
+ if (ret.proxyAutoConfigFunction != null) return ret;
+ }
+
+ if (container[0] == null) return null;
+ StringTokenizer st = new StringTokenizer(container[0], ";", false);
+ while(st.hasMoreTokens()) try {
+ String s = st.nextToken().trim();
+ String protocol, host;
+ if (s.indexOf(':') == -1) {
+ continue;
+ } else if (s.indexOf("://") != -1) {
+ protocol = s.substring(0, s.indexOf("://"));
+ s = s.substring(s.indexOf("://") + 3);
+ host = s.substring(0, s.indexOf(':'));
+ } else if (s.indexOf('=') == -1) {
+ protocol = "http";
+ host = s.substring(0, s.indexOf(':'));
+ } else {
+ protocol = s.substring(0, s.indexOf('='));
+ host = s.substring(s.indexOf('=') + 1, s.indexOf(':'));
+ }
+ int port = Integer.parseInt(s.substring(s.indexOf(':') + 1));
+ if (protocol.equals("http")) {
+ ret.httpProxyHost = host;
+ ret.httpProxyPort = port;
+ } else if (protocol.equals("https")) {
+ ret.httpsProxyHost = host;
+ ret.httpsProxyPort = port;
+ } else if (protocol.equals("socks")) {
+ ret.socksProxyHost = host;
+ ret.socksProxyPort = port;
+ }
+ } catch (NumberFormatException nfe) { }
+
+ if (container[1] != null) {
+ st = new StringTokenizer(container[1], ";", false);
+ ret.excluded = new String[st.countTokens()];
+ for(int i=0; st.hasMoreTokens(); i++) ret.excluded[i] = st.nextToken();
+ }
+ return ret;
+ }
+
+ protected native boolean _newBrowserWindow_(String url);
+ protected void _newBrowserWindow(String url) {
+ if (!_newBrowserWindow_(url))
+ if (Log.on) Log.info(this, "ShellExecuteEx() failed trying to open url " + url);
+ }
+
+ // Win32Surface ////////////////////////////////////////////////////////////////////////////
+
+ public static class Win32Surface extends Surface.DoubleBufferedSurface {
+
+ /** used to block while waiting for the message pump thread to create a hwnd for us */
+ public Semaphore hwndCreated = new Semaphore();
+
+ /** nothing more than a method version of WndProc, so we can access instance members/methods */
+ public native int WndProc(int hwnd, int imsg, int wparam, int lparam);
+
+ /** true iff the mouse is inside this window; used to determine if we should capture the mouse */
+ boolean inside = false;
+
+ /** true iff we have 'captured' the mouse with SetCapture() */
+ boolean captured = false;
+
+ public int hwnd = -1;
+ public int hdc = 0;
+
+ public int current_cursor = default_cursor;
+
+ /** used to restore the cursor immediately before ReleaseCapture() */
+ public int previous_cursor = 0;
+
+ public native void natInit(boolean framed);
+ public Win32Surface(Box b, final boolean framed) {
+ super(b);
+ natInit(framed);
+ hwndToWin32SurfaceMap.put(new Integer(hwnd), this);
+ }
+
+ public void syncCursor() {
+ if (cursor.equals("default")) current_cursor = default_cursor;
+ else if (cursor.equals("wait")) current_cursor = wait_cursor;
+ else if (cursor.equals("crosshair")) current_cursor = crosshair_cursor;
+ else if (cursor.equals("text")) current_cursor = text_cursor;
+ else if (cursor.equals("move")) current_cursor = move_cursor;
+ else if (cursor.equals("hand")) current_cursor = hand_cursor;
+ else if (cursor.equals("east") || cursor.equals("west")) current_cursor = sizewe_cursor;
+ else if (cursor.equals("north") || cursor.equals("south")) current_cursor = sizens_cursor;
+ else if (cursor.equals("northwest") || cursor.equals("southeast")) current_cursor = sizenwse_cursor;
+ else if (cursor.equals("northeast") || cursor.equals("southwest")) current_cursor = sizenesw_cursor;
+ postCursorChange();
+ }
+
+ public native void finalize();
+ public native void postCursorChange();
+ public native void toBack();
+ public native void toFront();
+ public native void _setMinimized(boolean m);
+ public native void setInvisible(boolean i);
+ public native void _setMaximized(boolean m);
+ public native void _setSize(int w, int h);
+ public native void setLocation();
+ public native void setTitleBarText(String s);
+ public native void setIcon(Picture p);
+ public native void _dispose();
+ public native void blit(PixelBuffer s, int sx, int sy, int dx, int dy, int dx2, int dy2);
+ }
+
+
+ // Win32Picture ////////////////////////////////////////////////////////////////////////////
+
+ public static class Win32Picture extends Picture {
+
+ /** the Win32 bitmap version of this Picture */
+ int hbitmap = -1;
+
+ /** dc of the bitmap */
+ int hdc = -1;
+
+ /** true iff this Picture has translucent regions */
+ boolean hasalpha = false;
+
+ /** true iff this Picture has transparent regions but no translucent regions */
+ boolean hasmask = true;
+
+ /** if hasmask, this mask indicates which regions are transparent */
+ int hmask = -1;
+
+ /** dc of the mask */
+ int maskdc = -1;
+
+ public Win32Picture(JS r) { super(r); }
+ public int getWidth() { return width; };
+ public int getHeight() { return height; };
+ public int[] getData() { return data; }
+ boolean initialized = false;
+ public void init() { if (!initialized && isLoaded) natInit(); initialized = true; }
+ public native void natInit();
+ }
+
+
+ // Win32PixelBuffer //////////////////////////////////////////////////////////////////////////
+
+ public static class Win32PixelBuffer extends PixelBuffer {
+
+ int w = 0;
+ int h = 0;
+
+ int clipx1 = 0;
+ int clipy1 = 0;
+ int clipx2 = 0;
+ int clipy2 = 0;
+
+ int hdc = -1;
+ int hbitmap = -1;
+
+ public int getHeight() { return h; }
+ public int getWidth() { return w; }
+
+ public native void natInit();
+ public Win32PixelBuffer(int w, int h, Win32Surface owner) {
+ this.w = w;
+ this.h = h;
+ clipx2 = w;
+ clipy2 = h;
+ natInit();
+ }
+
+ public native void fillRect(int x, int y, int x2, int y2, int color);
+ public void drawPicture(Picture source, int dx, int dy, int cx1, int cy1, int cx2, int cy2) {
+ ((Win32Picture)source).init();
+ drawPicture(source, dx, dy, cx1, cy1, cx2, cy2, 0, false);
+ }
+ public void drawGlyph(org.ibex.Font.Glyph source, int dx, int dy, int cx1, int cy1, int cx2, int cy2, int rgb) {
+ Win32Picture p = ((Win32Picture)((Platform.DefaultGlyph)source).getPicture());
+ p.init();
+ drawPicture(p, dx, dy, cx1, cy1, cx2, cy2, rgb, true);
+ }
+ public native void drawPicture(Picture source, int dx, int dy, int cx1, int cy1, int cx2, int cy2,
+ int rgb, boolean alphaOnly);
+
+ public native void finalize();
+
+ // FIXME: try to use os acceleration
+ public void fillTrapezoid(int x1, int x2, int y1, int x3, int x4, int y2, int argb) {
+ if (x1 == x3 && x2 == x4) {
+ fillRect(x1, y1, x4, y2, argb);
+ } else for(int y=y1; y<y2; y++) {
+ int _x1 = (int)Math.floor((y - y1) * (x3 - x1) / (y2 - y1) + x1);
+ int _y1 = (int)Math.floor(y);
+ int _x2 = (int)Math.ceil((y - y1) * (x4 - x2) / (y2 - y1) + x2);
+ int _y2 = (int)Math.floor(y) + 1;
+ if (_x1 > _x2) { int _x0 = _x1; _x1 = _x2; _x2 = _x0; }
+ fillRect(_x1, _y1, _x2, _y2, argb);
+ }
+ }
+ }
+
+}
+
--- /dev/null
+// Copyright 2002 Adam Megacz, see the COPYING file for licensing [LGPL]
+// see below for copyright information on the second portion of this file
+
+#include <X11/Xlib.h>
+#include <X11/extensions/XShm.h>
+#include <X11/keysymdef.h>
+#include <X11/keysym.h>
+#include <X11/cursorfont.h>
+#include <X11/Xutil.h>
+#include <X11/Xatom.h>
+#include <X11/Xmu/StdCmap.h>
+
+#include <java/lang/String.h>
+#include <org/ibex/graphics/Surface.h>
+#include <org/ibex/graphics/Picture.h>
+#include <org/ibex/core/Box.h>
+#include <org/ibex/plat/X11.h>
+#include <org/ibex/plat/X11$X11Surface.h>
+#include <org/ibex/plat/X11$X11Picture.h>
+#include <org/ibex/plat/X11$X11PixelBuffer.h>
+#include <org/ibex/util/Semaphore.h>
+#include <org/ibex/plat/Platform.h>
+#include <java/lang/Long.h>
+#include <java/util/Hashtable.h>
+#include <org/ibex/util/Log.h>
+
+#include <java/lang/System.h>
+#include <java/io/PrintStream.h>
+
+#include "POSIX.cc"
+
+// static (per-xserver) data
+static Visual* visual;
+static Colormap s_colormap;
+static XStandardColormap* colormap_info;
+static XShmSegmentInfo shm_info;
+static Window selectionWindow;
+static int shm_supported = 0;
+static int shm_pixmaps_supported;
+static int screen_num;
+static int colorDepth = 0;
+static Display* display;
+static int shm_size = 0;
+
+#define min(a, b) ((a) < (b) ? (a) : (b))
+#define max(a, b) ((a) < (b) ? (b) : (a))
+
+// X11PixelBuffer //////////////////////////////////////////////////////////////////////
+
+// ensures that the shared memory is at least size bytes; if not, allocates 3/2 * size
+static void ensureShmSize(int size) {
+ if (size > shm_size) {
+ if (shm_size > 0) {
+ XShmDetach(display, &shm_info);
+ shmdt(shm_info.shmaddr);
+ shmctl(shm_info.shmid, IPC_RMID, 0);
+ }
+ shm_size = 3 * size / 2;
+ shm_info.shmid = shmget(IPC_PRIVATE, shm_size, IPC_CREAT | 0777 | IPC_EXCL);
+ shm_info.shmaddr = (char*)shmat(shm_info.shmid, 0, 0);
+ shm_info.readOnly = False;
+ XSync(display, False);
+ shmctl(shm_info.shmid, IPC_RMID, 0);
+ XShmAttach(display, &shm_info);
+ XSync(display, False);
+ }
+}
+
+void org::ibex::plat::X11$X11PixelBuffer::fastDrawPicture(org::ibex::graphics::Picture* s,
+ jint dx, jint dy, jint cx1, jint cy1, jint cx2, jint cy2) {
+ org::ibex::plat::X11$X11Picture* source = (org::ibex::plat::X11$X11Picture*)s;
+
+ if (source->doublebuf->stipple != NULL) {
+ XSetClipMask(display, (*((GC*)clipped_gc)), *((Pixmap*)source->doublebuf->stipple));
+ XSetClipOrigin(display, (*((GC*)clipped_gc)), dx, dy);
+ } else {
+ XSetClipMask(display, (*((GC*)clipped_gc)), None);
+ }
+
+ XCopyArea(display,
+ *((Pixmap*)source->doublebuf->pm), (*((Pixmap*)pm)), (*((GC*)clipped_gc)),
+ cx1 - dx, cy1 - dy, cx2 - cx1, cy2 - cy1, cx1, cy1);
+}
+
+void org::ibex::plat::X11$X11PixelBuffer::slowDrawPicture(org::ibex::graphics::Picture* s,
+ jint dx, jint dy, jint cx1, jint cy1, jint cx2, jint cy2,
+ jint rgb, jboolean alphaOnly) {
+
+ org::ibex::plat::X11$X11Picture* source = (org::ibex::plat::X11$X11Picture*)s;
+ XImage* xi;
+
+ // FASTEST: shared pixmap; twiddle bits in video ram directly
+ if (shared_pixmap) {
+ XSync(display, False); // ensure that all pending operations have rendered
+ xi = (XImage*)fake_ximage;
+
+ // MEDIUM: write to a shared ximage, then ask the server to do the blit
+ } else if (shm_supported) {
+ xi = XShmCreateImage(display, visual, colorDepth, ZPixmap, NULL, &shm_info, cx2 - cx1, cy2 - cy1);
+ ensureShmSize(xi->bytes_per_line * xi->height);
+ xi->data = shm_info.shmaddr;
+ XShmGetImage(display, (*((Pixmap*)pm)), xi, cx1, cy1, AllPlanes);
+
+ // SLOWEST: write to an ximage, copy it through the TCP connection, ask the server to do the blit
+ } else {
+ xi = XGetImage(display, (*((Pixmap*)pm)), cx1, cy1, cx2 - cx1, cy2 - cy1, AllPlanes, ZPixmap);
+ }
+
+ int* sourcedata = (int*)elements(source->data);
+ for(int y=cy1; y < cy2; y++) {
+
+ char* current_pixel = (xi->data + y * xi->bytes_per_line) +
+ (shared_pixmap ? cx1 * (xi->bits_per_pixel / 8) : - 1 * cy1 * xi->bytes_per_line);
+
+ for(int x=cx1; x < cx2; x++, current_pixel += xi->bits_per_pixel / 8) {
+ int source_x = x - dx;
+ int source_y = y - dy;
+
+ // FEATURE: be smarter here; can we do something better for the alphaonly case?
+ int sourcepixel = sourcedata[source_x + source_y * source->getWidth()];
+ int alpha = (sourcepixel & 0xFF000000) >> 24;
+ if (alphaOnly) sourcepixel = rgb;
+ int source_red = (sourcepixel & 0x00FF0000) >> 16;
+ int source_green = (sourcepixel & 0x0000FF00) >> 8;
+ int source_blue = (sourcepixel & 0x000000FF);
+ int red = 0, blue = 0, green = 0;
+ int targetpixel;
+ if (alpha == 0x00) continue;
+ if (alpha != 0xFF) {
+ switch (xi->bits_per_pixel) {
+ case 8: targetpixel = (int)(*current_pixel); break;
+ case 15:
+ case 16: targetpixel = (int)(*((uint16_t*)current_pixel)); break;
+
+ // FIXME assumes endianness...
+ case 24: targetpixel =
+ (((int)*current_pixel) << 16) |
+ (((int)*(current_pixel + 1)) << 8) |
+ (((int)*(current_pixel + 2))); break;
+ case 32: targetpixel = *((int*)current_pixel); break;
+ default: org::ibex::plat::Platform::criticalAbort(JvNewStringLatin1("ERROR: bpp not a multiple of 8!"));
+ }
+ targetpixel -= colormap_info->base_pixel;
+
+ // if you're on some wierd display that isn't either RGB or BGR, that's your problem, not mine
+ if (colormap_info->red_mult > colormap_info->green_mult && colormap_info->green_mult > colormap_info->blue_mult) {
+ red = targetpixel / colormap_info->red_mult;
+ green = (targetpixel - red * colormap_info->red_mult) / colormap_info->green_mult;
+ blue = (targetpixel-red * colormap_info->red_mult-green * colormap_info->green_mult)/colormap_info->blue_mult;
+ } else {
+ blue = targetpixel / colormap_info->blue_mult;
+ green = (targetpixel - blue * colormap_info->blue_mult) / colormap_info->green_mult;
+ red = (targetpixel-blue * colormap_info->blue_mult-green * colormap_info->green_mult)/colormap_info->red_mult;
+ }
+ }
+ red = ((source_red * (colormap_info->red_max) * alpha) + (red * 0xFF * (0xFF - alpha))) / (0xFF * 0xFF);
+ green = ((source_green * (colormap_info->green_max) * alpha)+(green * 0xFF * (0xFF - alpha))) / (0xFF * 0xFF);
+ blue = ((source_blue * (colormap_info->blue_max) * alpha) + (blue * 0xFF * (0xFF - alpha))) / (0xFF * 0xFF);
+ uint32_t destpixel =
+ (red * colormap_info->red_mult) +
+ (green * colormap_info->green_mult) +
+ (blue * colormap_info->blue_mult) +
+ colormap_info->base_pixel;
+ switch (xi->bits_per_pixel) {
+ case 8: *current_pixel = (char)(destpixel & 0xFF); break;
+ case 16: *((uint16_t*)current_pixel) = (uint16_t)destpixel; break;
+ case 24: {
+ int offset = (int)current_pixel & 0x3;
+ uint64_t dest = ((uint64_t)destpixel) << (8 * offset);
+ uint64_t mask = ((uint64_t)0xffffff) << (8 * offset);
+ uint64_t* base = (uint64_t*)(current_pixel - offset);
+ *base = (*base & ~mask) | dest;
+ break;
+ }
+ case 32: *((uint32_t*)current_pixel) = destpixel; break;
+ default: org::ibex::plat::Platform::criticalAbort(JvNewStringLatin1("ERROR: bpp not a multiple of 8!"));
+ }
+ }
+ }
+
+ if (shared_pixmap) {
+ // do nothing, we wrote directly to video memory
+
+ } else if (shm_supported) {
+ XShmPutImage(display, (*((Pixmap*)pm)), (*((GC*)gc)), xi, 0, 0, cx1, cy1, cx2 - cx1, cy2 - cy1, False);
+ XDestroyImage(xi);
+
+ } else {
+ XPutImage(display, (*((Pixmap*)pm)), (*((GC*)gc)), xi, 0, 0, cx1, cy1, cx2 - cx1, cy2 - cy1);
+
+ }
+}
+
+void org::ibex::plat::X11$X11PixelBuffer::finalize() {
+ if (shared_pixmap) {
+ XShmSegmentInfo *sinfo = (XShmSegmentInfo*)shm_segment;
+ XShmDetach(display, sinfo);
+ shmdt(sinfo->shmaddr);
+ shmctl(sinfo->shmid, IPC_RMID, 0);
+ XDestroyImage((XImage*)fake_ximage);
+ free(sinfo);
+ }
+ if (stipple) {
+ XFreePixmap(display, *((Pixmap*)stipple));
+ free(stipple);
+ }
+ XFreePixmap(display, *((Pixmap*)pm));
+ XFreeGC(display, *((GC*)gc));
+ XFreeGC(display, *((GC*)clipped_gc));
+}
+
+void org::ibex::plat::X11$X11PixelBuffer::natInit() {
+
+ if (width == 0 || height == 0) return;
+ shared_pixmap &= shm_supported & shm_pixmaps_supported; // refuse to use shared pixmaps if we don't have shm
+ pm = (gnu::gcj::RawData*)malloc(sizeof(Pixmap));
+
+ if (!shared_pixmap)
+ (*((Pixmap*)pm)) = XCreatePixmap(display, RootWindow(display, screen_num), width, height, colorDepth);
+ else {
+ XShmSegmentInfo *sinfo = (XShmSegmentInfo*)malloc(sizeof(XShmSegmentInfo));
+ shm_segment = (gnu::gcj::RawData*)sinfo;
+ ((XImage*)fake_ximage) = XShmCreateImage(display, visual, colorDepth, ZPixmap, NULL, sinfo, width, height);
+ sinfo->shmid = shmget(IPC_PRIVATE, ((XImage*)fake_ximage)->bytes_per_line * height, IPC_CREAT | 0777 | IPC_EXCL);
+ ((XImage*)fake_ximage)->data = sinfo->shmaddr = (char*)shmat(sinfo->shmid, 0, 0);
+ sinfo->readOnly = False;
+ XShmAttach(display, sinfo);
+ XSync(display, False);
+ shmctl(sinfo->shmid, IPC_RMID, 0);
+ (*((Pixmap*)pm)) = XShmCreatePixmap(display, RootWindow(display, screen_num), sinfo->shmaddr, sinfo, width, height, colorDepth);
+ XSync(display, False);
+ }
+
+ gc = (gnu::gcj::RawData*)malloc(sizeof(GC));
+ clipped_gc = (gnu::gcj::RawData*)malloc(sizeof(GC));
+ (*((GC*)gc)) = XCreateGC(display, (*((Pixmap*)pm)), 0, 0);
+ (*((GC*)clipped_gc)) = XCreateGC(display, (*((Pixmap*)pm)), 0, 0);
+
+ XGCValues vm;
+ vm.graphics_exposures = 0;
+ XChangeGC(display, (*((GC*)gc)), GCGraphicsExposures, &vm);
+ XChangeGC(display, (*((GC*)clipped_gc)), GCGraphicsExposures, &vm);
+}
+
+void org::ibex::plat::X11$X11PixelBuffer::createStipple(org::ibex::plat::X11$X11Picture* xpi) {
+
+ stipple = (gnu::gcj::RawData*)malloc(sizeof(Pixmap));
+ (*((Pixmap*)stipple)) = XCreatePixmap(display, RootWindow(display, screen_num), width, height, 1);
+
+ XImage xi;
+ xi.data = (char*)malloc((width + 1) * height);
+ xi.width = width;
+ xi.height = height;
+ xi.xoffset = 0;
+ xi.format = ZPixmap;
+ xi.bitmap_pad = 8;
+ xi.bitmap_unit = 8;
+ xi.byte_order = LSBFirst;
+ xi.depth = 1;
+ xi.bytes_per_line = (width / 8) + 1;
+ xi.bits_per_pixel = 1;
+
+ jint* d = (jint*)elements(xpi->data);
+ memset(xi.data, 0xFF, (width + 1) * height);
+ for(int x=0; x<width; x++)
+ for (int y=0; y<height; y++)
+ xi.data[y * xi.bytes_per_line + (x/8)] &= ~(((d[x + y * width] & 0xFF000000) != 0 ? 0 : 1) << (x % 8));
+
+ GC stipple_gc = XCreateGC(display, (*((Pixmap*)stipple)), 0, 0);
+
+ XGCValues vm;
+ vm.graphics_exposures = 0;
+ XChangeGC(display, stipple_gc, GCGraphicsExposures, &vm);
+
+ XPutImage(display, (*((Pixmap*)stipple)), stipple_gc, &xi, 0, 0, 0, 0, width, height);
+}
+
+void org::ibex::plat::X11$X11Surface::blit(org::ibex::graphics::PixelBuffer* db, jint sx, jint sy, jint dx, jint dy, jint dx2, jint dy2) {
+ org::ibex::plat::X11$X11PixelBuffer *xdb = (org::ibex::plat::X11$X11PixelBuffer*)db;
+ XCopyArea(display, *((Pixmap*)xdb->pm), *((Window*)window), *((GC*)gc), sx, sy, dx2 - dx, dy2 - dy, dx, dy);
+ XFlush(display);
+}
+
+void org::ibex::plat::X11$X11PixelBuffer::fillRect (jint x, jint y, jint x2, jint y2, jint argb) {
+
+ jint w = x2 - x;
+ jint h = y2 - y;
+
+ if (x < clipx) { w -= (clipx - x); x = clipx; }
+ if (y < clipy) { h -= (clipy - y); y = clipy; }
+ if (x + w > clipx + clipw) w = (clipx + clipw - x);
+ if (y + h > clipy + cliph) h = (cliph + clipy - y);
+
+ XSetForeground(display, (*((GC*)gc)),
+ ((((argb & 0x00FF0000) >> 16) * colormap_info->red_max) / 0xFF) * colormap_info->red_mult +
+ ((((argb & 0x0000FF00) >> 8) * colormap_info->green_max) / 0xFF) * colormap_info->green_mult +
+ ((((argb & 0x000000FF)) * colormap_info->blue_max) / 0xFF) * colormap_info->blue_mult +
+ colormap_info->base_pixel
+ );
+
+ XFillRectangle(display, (*((Pixmap*)pm)), (*((GC*)gc)), x, y, w, h);
+}
+
+
+// X11Surface //////////////////////////////////////////////////////////////////////
+
+void org::ibex::plat::X11$X11Surface::setIcon(org::ibex::graphics::Picture* pic) {
+ org::ibex::plat::X11$X11Picture* p = ((org::ibex::plat::X11$X11Picture*)pic);
+ org::ibex::plat::X11$X11PixelBuffer* old_dbuf = p->doublebuf;
+ p->buildPixelBuffer(1);
+ XWMHints xwmh;
+ memset(&xwmh, 0, sizeof(XWMHints));
+ xwmh.flags |= IconPixmapHint | IconMaskHint;
+ xwmh.icon_pixmap = *((Pixmap*)p->doublebuf->pm);
+ xwmh.icon_mask = *((Pixmap*)p->doublebuf->stipple);
+ XSetWMHints(display, (*((Window*)window)), &xwmh);
+ p->doublebuf = old_dbuf;
+}
+
+void org::ibex::plat::X11$X11Surface::setTitleBarText(java::lang::String* s) {
+ int len = min(JvGetStringUTFLength(s), 1024);
+ char buf[len + 1];
+ JvGetStringUTFRegion(s, 0, len, buf);
+ buf[len] = '\0';
+
+ XTextProperty tp;
+ tp.value = (unsigned char*)buf;
+ tp.nitems = len;
+ tp.encoding = XA_STRING;
+ tp.format = 8;
+ XSetTextProperty(display, (*((Window*)window)), &tp, XA_WM_NAME);
+ XSetTextProperty(display, (*((Window*)window)), &tp, XA_WM_ICON_NAME);
+}
+
+void org::ibex::plat::X11$X11Surface::setLimits(jint minw, jint minh, jint maxw, jint maxh) {
+ XSizeHints hints;
+ hints.min_width = minw;
+ hints.min_height = minh;
+ hints.max_width = maxw;
+ hints.max_height = maxh;
+ hints.flags = PMinSize | PMaxSize;
+ XSetWMNormalHints(display, (*((Window*)window)), &hints);
+}
+
+void org::ibex::plat::X11$X11Surface::_setSize (jint width, jint height) {
+ if (width <= 0 || height <= 0) return;
+ XResizeWindow(display, (*((Window*)window)), width, height);
+ XFlush(display);
+}
+
+void org::ibex::plat::X11$X11Surface::setLocation () { XMoveWindow(display, (*((Window*)window)), root->x, root->y); }
+void org::ibex::plat::X11$X11Surface::toFront() { XRaiseWindow(display, (*((Window*)window))); }
+void org::ibex::plat::X11$X11Surface::toBack() { XLowerWindow(display, (*((Window*)window))); }
+
+void org::ibex::plat::X11$X11Surface::_dispose() {
+ // without this we get phantom messages after the window is gone
+ org::ibex::plat::X11::windowToSurfaceMap->remove(new java::lang::Long(*((Window*)window)));
+ XDestroyWindow(display, (*((Window*)window)));
+}
+
+void org::ibex::plat::X11$X11Surface::setInvisible(jboolean i) {
+ if (i) XUnmapWindow(display, (*((Window*)window)));
+ else XMapRaised(display, (*((Window*)window)));
+ XFlush(display);
+}
+
+void org::ibex::plat::X11$X11Surface::_setMinimized(jboolean b) {
+ if (b) XIconifyWindow(display, (*((Window*)window)), screen_num);
+ else XMapRaised(display, (*((Window*)window)));
+ XFlush(display);
+}
+
+void org::ibex::plat::X11$X11Surface::natInit() {
+ XSetWindowAttributes xswa;
+ window = (gnu::gcj::RawData*)malloc(sizeof(Window));
+ xswa.bit_gravity = NorthWestGravity;
+ xswa.colormap = s_colormap;
+ xswa.event_mask = ExposureMask | ButtonPressMask | StructureNotifyMask |
+ KeyPressMask | KeyReleaseMask | ButtonPressMask |
+ ButtonReleaseMask | EnterWindowMask | LeaveWindowMask |
+ PointerMotionMask | ButtonMotionMask | ConfigureNotify | FocusChangeMask;
+ *((Window*)window) = XCreateWindow(display, RootWindow(display, screen_num), 10, 10, 10, 10, 0,
+ colorDepth, InputOutput, CopyFromParent,
+ CWColormap | CWBitGravity | CWEventMask, &xswa);
+
+ if (!framed) {
+ // I don't know why this works....
+ int dat[5] = { 0x2, 0xbffff804, 0x0, 0x817f560, 0x8110694 };
+ XChangeProperty(display, (*((Window*)window)),
+ XInternAtom(display, "_MOTIF_WM_HINTS", False),
+ XInternAtom(display, "_MOTIF_WM_HINTS", False),
+ 32,
+ PropModeReplace,
+ (unsigned char*)dat,
+ 5);
+ }
+
+ XTextProperty tp;
+ tp.value = (unsigned char*)"Ibex";
+ tp.nitems = 4;
+ tp.encoding = XA_STRING;
+ tp.format = 8;
+ XSetTextProperty(display, (*((Window*)window)), &tp, XA_WM_CLASS);
+
+ Atom proto = XInternAtom(display, "WM_DELETE_WINDOW", False);
+ XSetWMProtocols(display, (*((Window*)window)), &proto, 1);
+
+ XSelectInput(display, (*((Window*)window)), StructureNotifyMask);
+ org::ibex::plat::X11::windowToSurfaceMap->put(new java::lang::Long(*((Window*)window)), this);
+
+ XEvent e;
+ XMapRaised(display, (*((Window*)window)));
+ XFlush(display);
+
+ waitForCreation->block();
+ XSelectInput(display, (*((Window*)window)), xswa.event_mask);
+ XFlush(display);
+
+ gc = (gnu::gcj::RawData*)malloc(sizeof(GC));
+ *((GC*)gc) = XCreateGC(display, (*((Window*)window)), 0, 0);
+
+ XGCValues vm;
+ vm.graphics_exposures = 0;
+ XChangeGC(display, *((GC*)gc), GCGraphicsExposures, &vm);
+}
+
+
+void org::ibex::plat::X11$X11Surface::dispatchEvent(gnu::gcj::RawData* ev) {
+
+ XEvent* e = (XEvent*)ev;
+ if (e->type == Expose) {
+ XExposeEvent *expose = (XExposeEvent*)(e);
+ Dirty(expose->x, expose->y, expose->width, expose->height);
+
+ } else if (e->type == MapNotify) { Minimized(0); waitForCreation->release();
+ } else if (e->type == UnmapNotify) { Minimized(1);
+ } else if (e->type == FocusIn) { Focused(1);
+ } else if (e->type == FocusOut) { Focused(0);
+ } else if (e->type == ClientMessage) {
+ if (((XClientMessageEvent*)(e))->data.l[0] == XInternAtom(display, "WM_DELETE_WINDOW", False)) Close();
+
+ } else if (e->type == KeyPress || e->type == KeyRelease) {
+ XKeyEvent *xbe = (XKeyEvent*)(e);
+
+ // drop faked KeyRelease events generated by the X server's autorepeat
+ if (e->type == KeyRelease) {
+ char depressed[32];
+ XQueryKeymap(display, depressed);
+ if ((depressed[(xbe->keycode & 0xff) / 8] & (0x1 << (xbe->keycode % 8))) >> (xbe->keycode % 8)) return;
+ }
+
+ char ss[20];
+ char* s = ss;
+
+ unsigned int savestate = xbe->state;
+ xbe->state = xbe->state & ShiftMask; // ignore everything except shiftmask
+ XLookupString(xbe, s, 20, NULL, NULL);
+ xbe->state = savestate;
+
+ if (s != NULL && s[0] != '\0' && s[1] == '\0' && s[0] >= 0x20 && s[0] <= 0x7E) {
+ int i = s[0];
+
+ } else {
+ KeySym ks = XKeycodeToKeysym(display, xbe->keycode, 0);
+ switch (ks) {
+ case XK_BackSpace: s = "back_space"; break;
+ case XK_Tab: s = "tab"; break;
+ case XK_Linefeed: s = "enter"; break;
+ case XK_Return: s = "enter"; break;
+ case XK_Scroll_Lock: s = "scroll_lock"; break;
+ case XK_Escape: s = "escape"; break;
+ case XK_Insert: s = "insert"; break;
+ case XK_Delete: s = "delete"; break;
+ case XK_Home: s = "home"; break;
+ case XK_Left: s = "left"; break;
+ case XK_Up: s = "up"; break;
+ case XK_Right: s = "right"; break;
+ case XK_Down: s = "down"; break;
+ case XK_Page_Up: s = "page_up"; break;
+ case XK_Page_Down: s = "page_down"; break;
+ case XK_End: s = "end"; break;
+ case XK_Num_Lock: s = "num_lock"; break;
+ case XK_KP_Tab: s = "tab"; break;
+ case XK_KP_Enter: s = "enter"; break;
+ case XK_KP_F1: s = "f1"; break;
+ case XK_KP_F2: s = "f2"; break;
+ case XK_KP_F3: s = "f3"; break;
+ case XK_KP_F4: s = "f4"; break;
+ case XK_KP_Home: s = "home"; break;
+ case XK_KP_Left: s = "left"; break;
+ case XK_KP_Up: s = "up"; break;
+ case XK_KP_Right: s = "right"; break;
+ case XK_KP_Down: s = "down"; break;
+ case XK_KP_Page_Up: s = "page_up"; break;
+ case XK_KP_Page_Down: s = "page_down"; break;
+ case XK_KP_End: s = "end"; break;
+ case XK_KP_Insert: s = "insert"; break;
+ case XK_KP_Delete: s = "delete"; break;
+ case XK_F1: s = "f1"; break;
+ case XK_F2: s = "f2"; break;
+ case XK_F3: s = "f3"; break;
+ case XK_F4: s = "f4"; break;
+ case XK_F5: s = "f5"; break;
+ case XK_F6: s = "f6"; break;
+ case XK_F7: s = "f7"; break;
+ case XK_F8: s = "f8"; break;
+ case XK_F9: s = "f9"; break;
+ case XK_F10: s = "f10"; break;
+ case XK_F11: s = "f11"; break;
+ case XK_F12: s = "f12"; break;
+ case XK_Shift_L: s = "shift"; break;
+ case XK_Shift_R: s = "shift"; break;
+ case XK_Control_L: s = "control"; break;
+ case XK_Control_R: s = "control"; break;
+ case XK_Meta_L: s = "alt"; break;
+ case XK_Meta_R: s = "alt"; break;
+ case XK_Alt_L: s = "alt"; break;
+ case XK_Alt_R: s = "alt"; break;
+ default: return;
+ }
+ }
+
+ jstring s2 = JvNewStringLatin1(s);
+ if (e->type == KeyPress) KeyPressed((xbe->state & LockMask) ? s2->toUpperCase() : s2);
+ if (e->type == KeyRelease) KeyReleased(s2);
+
+ } else if (e->type == ButtonPress) {
+ XButtonEvent* xbe = (XButtonEvent*)(e);
+ switch(xbe->button) {
+ case 4: VScroll((jfloat)-1.0); return;
+ case 5: VScroll((jfloat)1.0); return;
+ case 6: HScroll((jfloat)-1.0); return;
+ case 7: HScroll((jfloat)1.0); return;
+ }
+ if (xbe->button == 2) xbe->button = 3;
+ else if (xbe->button == 3) xbe->button = 2;
+ Press(xbe->button);
+
+ } else if (e->type == ButtonRelease) {
+ XButtonEvent* xbe = (XButtonEvent*)(e);
+ if (xbe->button == 2) xbe->button = 3;
+ else if (xbe->button == 3) xbe->button = 2;
+ Release(xbe->button);
+
+ } else if (e->type == MotionNotify) {
+ XMotionEvent* xme = (XMotionEvent*)(e);
+ Move(xme->x, xme->y);
+
+ } else if (e->type == EnterNotify || e->type == LeaveNotify) {
+ XCrossingEvent* xce = (XCrossingEvent*)(e);
+ Move(xce->x, xce->y);
+
+ } else if (e->type == ConfigureNotify) {
+ Window child;
+ int x_out, y_out;
+ XConfigureEvent* xce = (XConfigureEvent*)(e);
+ XTranslateCoordinates(display, (*((Window*)window)), RootWindow(display, screen_num), 0, 0, &x_out, &y_out, &child);
+ if (xce->width != root->width || xce->height != root->height) SizeChange(xce->width, xce->height);
+ if (x_out != root->x || y_out != root->y) PosChange(x_out, y_out);
+
+ }
+}
+
+static jstring crosshair, east, hand, move, north, northeast, northwest,
+ south, southeast, southwest, text, west, wait_string;
+static Cursor crosshair_cursor, east_cursor, hand_cursor, move_cursor, north_cursor,
+ northeast_cursor, northwest_cursor, south_cursor, southeast_cursor,
+ southwest_cursor, text_cursor, west_cursor, wait_cursor, default_cursor;
+
+void org::ibex::plat::X11$X11Surface::syncCursor() {
+
+ Cursor curs;
+ if (cursor->equals(crosshair)) curs = crosshair_cursor;
+ else if (cursor->equals(east)) curs = east_cursor;
+ else if (cursor->equals(hand)) curs = hand_cursor;
+ else if (cursor->equals(move)) curs = move_cursor;
+ else if (cursor->equals(north)) curs = north_cursor;
+ else if (cursor->equals(northeast)) curs = northeast_cursor;
+ else if (cursor->equals(northwest)) curs = northwest_cursor;
+ else if (cursor->equals(south)) curs = south_cursor;
+ else if (cursor->equals(southeast)) curs = southeast_cursor;
+ else if (cursor->equals(southwest)) curs = southwest_cursor;
+ else if (cursor->equals(text)) curs = text_cursor;
+ else if (cursor->equals(west)) curs = west_cursor;
+ else if (cursor->equals(wait_string)) curs = wait_cursor;
+ else curs = default_cursor;
+
+ XDefineCursor(display, (*((Window*)window)), curs);
+}
+
+
+
+// X11 ///////////////////////////////////////////////////////////////////
+
+jint org::ibex::plat::X11::_getScreenWidth() { return WidthOfScreen(DefaultScreenOfDisplay(display)); }
+jint org::ibex::plat::X11::_getScreenHeight() { return HeightOfScreen(DefaultScreenOfDisplay(display)); }
+
+static void dispatchSelectionEvent(XEvent* e) {
+ if (e->type == SelectionNotify) {
+ XSelectionEvent* xsn = (XSelectionEvent*)(e);
+ if (xsn->property == None) org::ibex::plat::X11::clipboard = JvNewStringLatin1("", 0);
+ else {
+ Atom returntype;
+ int returnformat;
+ unsigned long numitems;
+ unsigned char* ret;
+ unsigned long bytes_after;
+ XGetWindowProperty(display, xsn->requestor, xsn->property, 0, 4096,
+ True, AnyPropertyType, &returntype, &returnformat,
+ &numitems, &bytes_after, &ret);
+ org::ibex::plat::X11::clipboard =
+ (returntype == None ? JvNewStringLatin1("", 0) : JvNewStringLatin1((char*)ret, strlen((char*)ret)));
+ }
+ org::ibex::plat::X11::waiting_for_selection_event->release();
+
+ } else if (e->type == SelectionRequest) {
+ XSelectionRequestEvent* xsr = (XSelectionRequestEvent*)(e);
+ XSelectionEvent xsn;
+ xsn.type = SelectionNotify;
+ xsn.serial = xsr->serial;
+ xsn.send_event = True;
+ xsn.display = display;
+ xsn.requestor = xsr->requestor;
+ xsn.selection = xsr->selection;
+ xsn.target = xsr->target;
+ xsn.property = xsr->property;
+ xsn.time = xsr->time;
+
+ int len = min(1024, JvGetStringUTFLength(org::ibex::plat::X11::clipboard));
+ char buf[len + 1];
+ JvGetStringUTFRegion(org::ibex::plat::X11::clipboard, 0, len, buf);
+ buf[len] = '\0';
+
+ XChangeProperty(display, xsr->requestor, xsr->property, xsr->target, 8, PropModeReplace, (unsigned char*)buf, len + 1);
+ XSendEvent(display, xsr->requestor, True, 0, (XEvent*)(&xsn));
+ }
+}
+
+void org::ibex::plat::X11::eventThread() {
+ XEvent e;
+ while(true) {
+ XNextEvent(display, &e);
+ if (e.type == SelectionNotify || e.type == SelectionRequest) {
+ dispatchSelectionEvent(&e);
+ } else {
+ org::ibex::plat::X11$X11Surface* surface =
+ (org::ibex::plat::X11$X11Surface*)windowToSurfaceMap->get(new java::lang::Long(((XAnyEvent*)&e)->window));
+ if (surface != NULL) surface->dispatchEvent((gnu::gcj::RawData*)&e);
+ }
+ }
+}
+
+jstring org::ibex::plat::X11::_getClipBoard() {
+ XConvertSelection(display, XA_PRIMARY, XA_STRING, XInternAtom(display, "VT_SELECTION", False), selectionWindow, CurrentTime);
+ XFlush(display);
+ org::ibex::plat::X11::waiting_for_selection_event->block();
+ return clipboard;
+}
+
+void org::ibex::plat::X11::_setClipBoard(jstring s) {
+ clipboard = s;
+ int len = JvGetStringUTFLength(clipboard);
+ char buf[len + 1];
+ JvGetStringUTFRegion(clipboard, 0, len, buf);
+ buf[len] = '\0';
+ XSetSelectionOwner(display, XInternAtom(display, "PRIMARY", 0), selectionWindow, CurrentTime);
+}
+
+typedef int (X11ErrorHandler)(Display*, XErrorEvent*);
+int errorHandler(Display* d, XErrorEvent* e) {
+ // this error handler is only installed during the initial
+ // test to see if shm is present
+ shm_supported = 0;
+}
+
+void org::ibex::plat::X11::natInit() {
+
+ if (!XInitThreads())
+ org::ibex::plat::Platform::criticalAbort(JvNewStringLatin1("Your X11 libraries do not support multithreaded programs"));
+
+ char* DISPLAY = getenv("DISPLAY");
+ if (DISPLAY == NULL || strlen(DISPLAY) == 0) DISPLAY = ":0.0";
+ display = XOpenDisplay(DISPLAY);
+
+ if (display == 0)
+ org::ibex::plat::Platform::criticalAbort(JvNewStringLatin1("Unable to connect to X11 display server"));
+
+ screen_num = XDefaultScreen(display);
+ colorDepth = (jint)(DefaultDepth(((Display*)display), 0));
+ shm_info.shmaddr = NULL;
+
+ // FIXME: SHM doesn't work on Darwin
+ //shm_supported = (XShmQueryExtension(display) == True);
+ if (shm_supported) {
+ X11ErrorHandler* oldHandler = XSetErrorHandler(errorHandler);
+ XShmSegmentInfo sinfo;
+ sinfo.shmid = shmget(IPC_PRIVATE, 1, IPC_CREAT | 0777 | IPC_EXCL);
+ sinfo.readOnly = False;
+ // if the server is remote, this will trigger the error handler
+ XShmAttach(display, &sinfo);
+ XSync(display, False);
+ XSetErrorHandler(oldHandler);
+ }
+
+ if (shm_supported)
+ shm_pixmaps_supported = (XShmPixmapFormat(display) == ZPixmap);
+
+ crosshair = JvNewStringLatin1("crosshair");
+ east = JvNewStringLatin1("east");
+ hand = JvNewStringLatin1("hand");
+ move = JvNewStringLatin1("move");
+ north = JvNewStringLatin1("north");
+ northeast = JvNewStringLatin1("northeast");
+ northwest = JvNewStringLatin1("northwest");
+ south = JvNewStringLatin1("south");
+ southeast = JvNewStringLatin1("southeast");
+ southwest = JvNewStringLatin1("southwest");
+ text = JvNewStringLatin1("text");
+ west = JvNewStringLatin1("west");
+ wait_string = JvNewStringLatin1("wait");
+ crosshair_cursor = XCreateFontCursor(display, XC_tcross);
+ east_cursor = XCreateFontCursor(display, XC_right_side);
+ hand_cursor = XCreateFontCursor(display, XC_hand2);
+ move_cursor = XCreateFontCursor(display, XC_fleur);
+ north_cursor = XCreateFontCursor(display, XC_top_side);
+ northeast_cursor = XCreateFontCursor(display, XC_top_right_corner);
+ northwest_cursor = XCreateFontCursor(display, XC_left_side);
+ south_cursor = XCreateFontCursor(display, XC_bottom_side);
+ southeast_cursor = XCreateFontCursor(display, XC_bottom_right_corner);
+ southwest_cursor = XCreateFontCursor(display, XC_bottom_left_corner);
+ text_cursor = XCreateFontCursor(display, XC_xterm);
+ west_cursor = XCreateFontCursor(display, XC_right_side);
+ wait_cursor = XCreateFontCursor(display, XC_watch);
+ default_cursor = XCreateFontCursor(display, XC_left_ptr);
+
+ selectionWindow = XCreateWindow(display, RootWindow(display, screen_num), 0, 0, 1, 1, 0, colorDepth, InputOutput, CopyFromParent, 0, NULL);
+ visual = DefaultVisual(display, screen_num);
+ char buf[255];
+ sprintf(buf, "X11 DISPLAY: %s", XDisplayString(display));
+ org::ibex::util::Log::info(this->getClass(), JvNewStringLatin1(buf));
+ sprintf(buf, "X11 SHM: %s", shm_supported ? "enabled" : "disabled");
+ org::ibex::util::Log::info(this->getClass(), JvNewStringLatin1(buf));
+ sprintf(buf, "X11 Visual: %x %x %x bits: %i visualid: %i depth: %i",
+ visual->red_mask, visual->green_mask, visual->blue_mask, visual->bits_per_rgb, visual->visualid, colorDepth);
+ org::ibex::util::Log::info(this->getClass(), JvNewStringLatin1(buf));
+
+ // FIXME: don't know why (True, False) is the best solution...
+ if(XmuLookupStandardColormap(display, screen_num, visual->visualid, colorDepth, XA_RGB_BEST_MAP, True, False) == 0)
+ org::ibex::plat::Platform::criticalAbort(JvNewStringLatin1("ERROR: XmuLookupStandardColormap failed"));
+ XStandardColormap* best_map_info = NULL;
+ int count;
+ if (XGetRGBColormaps(display, RootWindow(display, screen_num), &best_map_info, &count, XA_RGB_BEST_MAP) == 0)
+ org::ibex::plat::Platform::criticalAbort(JvNewStringLatin1("ERROR: couldn't allocate a standard colormap"));
+ if (!best_map_info->colormap)
+ org::ibex::plat::Platform::criticalAbort(JvNewStringLatin1("ERROR: XmuLookupStandardColomap succeded, but no colormap was found on the root window"));
+ if (best_map_info->red_max == 0)
+ org::ibex::plat::Platform::criticalAbort(JvNewStringLatin1("ERROR: standard colormap exists, but was improperly allocated"));
+ s_colormap = best_map_info->colormap;
+ colormap_info = best_map_info;
+
+ sprintf(buf, " red_max / red_mult: %x %x", colormap_info->red_max, colormap_info->red_mult);
+ org::ibex::util::Log::info(this->getClass(), JvNewStringLatin1(buf));
+ sprintf(buf, " green_max / green_mult: %x %x", colormap_info->green_max, colormap_info->green_mult);
+ org::ibex::util::Log::info(this->getClass(), JvNewStringLatin1(buf));
+ sprintf(buf, " blue_max / blue_mult: %x %x", colormap_info->blue_max, colormap_info->blue_mult);
+ org::ibex::util::Log::info(this->getClass(), JvNewStringLatin1(buf));
+ sprintf(buf, " base_pixel: %x", colormap_info->base_pixel);
+ org::ibex::util::Log::info(this->getClass(), JvNewStringLatin1(buf));
+}
+
+#include "WINGs/WINGs.h"
+jstring org::ibex::plat::X11::_fileDialog(jstring suggestedFileName, jboolean write) {
+ int argc = 1;
+ char* argv[2];
+ argv[0] = "Ibex";
+ argv[1] = NULL;
+ // FIXME see WINGs/Tests/filedialog.c for more info... need an icon
+ WMInitializeApplication("Ibex", &argc, argv);
+ WMScreen *scr = WMCreateSimpleApplicationScreen(display);
+ int len = min(1024, JvGetStringUTFLength(suggestedFileName));
+ char buf[len + 1];
+ JvGetStringUTFRegion(suggestedFileName, 0, len, buf);
+ buf[len] = '\0';
+ if (write) {
+ WMSavePanel *sPanel;
+ sPanel = WMGetSavePanel(scr);
+ if (WMRunModalFilePanelForDirectory(sPanel, NULL, buf, /*title*/ NULL, NULL) != True) return NULL;
+ return JvNewStringLatin1(WMGetFilePanelFileName(sPanel));
+ } else {
+ WMOpenPanel *oPanel;
+ oPanel = WMGetOpenPanel(scr);
+ if (WMRunModalFilePanelForDirectory(oPanel, NULL, buf, /*title*/ NULL, NULL) != True) return NULL;
+ return JvNewStringLatin1(WMGetFilePanelFileName(oPanel));
+ }
+ return NULL;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+// //
+// Everything below this point was taken, cut-and-paste, from the //
+// source for libXmu. It implements the official 'standard colormap //
+// creation algorithm. I made some small changes to //
+// XmuDeleteStandardColormap //
+// //
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+/* $Xorg: LookupCmap.c,v 1.4 2001/02/09 02:03:53 xorgcvs Exp $ */
+
+/*
+
+Copyright 1989, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+/* $XFree86: xc/lib/Xmu/LookupCmap.c,v 1.8 2001/12/14 19:55:47 dawes Exp $ */
+
+/*
+ * Author: Donna Converse, MIT X Consortium
+ */
+
+#include <stdio.h>
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+#include <X11/Xutil.h>
+#include <X11/Xmu/StdCmap.h>
+#include <stdlib.h>
+
+/*
+ * Prototypes
+ */
+static Status lookup(Display*, int, VisualID, Atom, XStandardColormap*, Bool);
+
+/*
+ * To create a standard colormap if one does not currently exist, or
+ * replace the currently existing standard colormap, use
+ * XmuLookupStandardColormap().
+ *
+ * Given a screen, a visual, and a property, XmuLookupStandardColormap()
+ * will determine the best allocation for the property under the specified
+ * visual, and determine the whether to create a new colormap or to use
+ * the default colormap of the screen. It will call XmuStandardColormap()
+ * to create the standard colormap.
+ *
+ * If replace is true, any previous definition of the property will be
+ * replaced. If retain is true, the property and the colormap will be
+ * made permanent for the duration of the server session. However,
+ * pre-existing property definitions which are not replaced cannot be made
+ * permanent by a call to XmuLookupStandardColormap(); a request to retain
+ * resources pertains to newly created resources.
+ *
+ * Returns 0 on failure, non-zero on success. A request to create a
+ * standard colormap upon a visual which cannot support such a map is
+ * considered a failure. An example of this would be requesting any
+ * standard colormap property on a monochrome visual, or, requesting an
+ * RGB_BEST_MAP on a display whose colormap size is 16.
+ */
+
+Status
+XmuLookupStandardColormap(Display *dpy, int screen, VisualID visualid,
+ unsigned int depth, Atom property,
+ Bool replace, Bool retain)
+ /*
+ * dpy - specifies X server connection
+ * screen - specifies screen of display
+ * visualid - specifies the visual type
+ * depth - specifies the visual type
+ * property - a standard colormap property
+ * replace - specifies whether to replace
+ * retain - specifies whether to retain
+ */
+{
+ Display *odpy; /* original display connection */
+ XStandardColormap *colormap;
+ XVisualInfo vinfo_template, *vinfo; /* visual */
+ long vinfo_mask;
+ unsigned long r_max, g_max, b_max; /* allocation */
+ int count;
+ Colormap cmap; /* colormap ID */
+ Status status = 0;
+
+
+ /* Match the requested visual */
+
+ vinfo_template.visualid = visualid;
+ vinfo_template.screen = screen;
+ vinfo_template.depth = depth;
+ vinfo_mask = VisualIDMask | VisualScreenMask | VisualDepthMask;
+ if ((vinfo = XGetVisualInfo(dpy, vinfo_mask, &vinfo_template, &count)) ==
+ NULL)
+ return 0;
+
+ /* Monochrome visuals have no standard maps */
+
+ if (vinfo->colormap_size <= 2) {
+ XFree((char *) vinfo);
+ return 0;
+ }
+
+ /* If the requested property already exists on this screen, and,
+ * if the replace flag has not been set to true, return success.
+ * lookup() will remove a pre-existing map if replace is true.
+ */
+
+ if (lookup(dpy, screen, visualid, property, (XStandardColormap *) NULL,
+ replace) && !replace) {
+ XFree((char *) vinfo);
+ return 1;
+ }
+
+ /* Determine the best allocation for this property under the requested
+ * visualid and depth, and determine whether or not to use the default
+ * colormap of the screen.
+ */
+
+ if (!XmuGetColormapAllocation(vinfo, property, &r_max, &g_max, &b_max)) {
+ XFree((char *) vinfo);
+ return 0;
+ }
+
+ cmap = (property == XA_RGB_DEFAULT_MAP &&
+ visualid == XVisualIDFromVisual(DefaultVisual(dpy, screen)))
+ ? DefaultColormap(dpy, screen) : None;
+
+ /* If retaining resources, open a new connection to the same server */
+
+ if (retain) {
+ odpy = dpy;
+ if ((dpy = XOpenDisplay(XDisplayString(odpy))) == NULL) {
+ XFree((char *) vinfo);
+ return 0;
+ }
+ }
+
+ /* Create the standard colormap */
+
+ colormap = XmuStandardColormap(dpy, screen, visualid, depth, property,
+ cmap, r_max, g_max, b_max);
+
+ /* Set the standard colormap property */
+
+ if (colormap) {
+ XGrabServer(dpy);
+
+ if (lookup(dpy, screen, visualid, property, colormap, replace) &&
+ !replace) {
+ /* Someone has defined the property since we last looked.
+ * Since we will not replace it, release our own resources.
+ * If this is the default map, our allocations will be freed
+ * when this connection closes.
+ */
+ if (colormap->killid == ReleaseByFreeingColormap)
+ XFreeColormap(dpy, colormap->colormap);
+ } else if (retain) {
+ XSetCloseDownMode(dpy, RetainPermanent);
+ }
+ XUngrabServer(dpy);
+ XFree((char *) colormap);
+ status = 1;
+ }
+
+ if (retain)
+ XCloseDisplay(dpy);
+ XFree((char *) vinfo);
+ return status;
+}
+
+/***************************************************************************/
+
+/* Lookup a standard colormap property. If the property is RGB_DEFAULT_MAP,
+ * the visualid is used to determine whether the indicated standard colormap
+ * exists. If the map exists and replace is true, delete the resources used
+ * by the map and remove the property. Return true if the map exists,
+ * or did exist and was deleted; return false if the map was not found.
+ *
+ * Note that this is not the way that a Status return is normally used.
+ *
+ * If new is not NULL, new points to an XStandardColormap structure which
+ * describes a standard colormap of the specified property. It will be made
+ * a standard colormap of the screen if none already exists, or if replace
+ * is true.
+ */
+
+static Status
+lookup(Display *dpy, int screen, VisualID visualid, Atom property,
+ XStandardColormap *cnew, Bool replace)
+ /*
+ * dpy - specifies display connection
+ * screen - specifies screen number
+ * visualid - specifies visualid for std map
+ * property - specifies colormap property name
+ * cnew - specifies a standard colormap
+ * replace - specifies whether to replace
+ */
+{
+ register int i;
+ int count;
+ XStandardColormap *stdcmaps, *s;
+ Window win = RootWindow(dpy, screen);
+
+ /* The property does not already exist */
+
+ if (! XGetRGBColormaps(dpy, win, &stdcmaps, &count, property)) {
+ if (cnew)
+ XSetRGBColormaps(dpy, win, cnew, 1, property);
+ return 0;
+ }
+
+ /* The property exists and is not describing the RGB_DEFAULT_MAP */
+
+ if (property != XA_RGB_DEFAULT_MAP) {
+ if (replace) {
+ XmuDeleteStandardColormap(dpy, screen, property);
+ if (cnew)
+ XSetRGBColormaps(dpy, win, cnew, 1, property);
+ }
+ XFree((char *)stdcmaps);
+ return 1;
+ }
+
+ /* The property exists and is RGB_DEFAULT_MAP */
+
+ for (i=0, s=stdcmaps; (i < count) && (s->visualid != visualid); i++, s++)
+ ;
+
+ /* No RGB_DEFAULT_MAP property matches the given visualid */
+
+ if (i == count) {
+ if (cnew) {
+ XStandardColormap *m, *maps;
+
+ s = (XStandardColormap *) malloc((unsigned) ((count+1) * sizeof
+ (XStandardColormap)));
+
+ for (i = 0, m = s, maps = stdcmaps; i < count; i++, m++, maps++) {
+ m->colormap = maps->colormap;
+ m->red_max = maps->red_max;
+ m->red_mult = maps->red_mult;
+ m->green_max = maps->green_max;
+ m->green_mult = maps->green_mult;
+ m->blue_max = maps->blue_max;
+ m->blue_mult = maps->blue_mult;
+ m->base_pixel = maps->base_pixel;
+ m->visualid = maps->visualid;
+ m->killid = maps->killid;
+ }
+ m->colormap = cnew->colormap;
+ m->red_max = cnew->red_max;
+ m->red_mult = cnew->red_mult;
+ m->green_max = cnew->green_max;
+ m->green_mult = cnew->green_mult;
+ m->blue_max = cnew->blue_max;
+ m->blue_mult = cnew->blue_mult;
+ m->base_pixel = cnew->base_pixel;
+ m->visualid = cnew->visualid;
+ m->killid = cnew->killid;
+
+ XSetRGBColormaps(dpy, win, s, ++count, property);
+ free((char *) s);
+ }
+ XFree((char *) stdcmaps);
+ return 0;
+ }
+
+ /* Found an RGB_DEFAULT_MAP property with a matching visualid */
+
+ if (replace) {
+ /* Free old resources first - we may need them, particularly in
+ * the default colormap of the screen. However, because of this,
+ * it is possible that we will destroy the old resource and fail
+ * to create a new one if XmuStandardColormap() fails.
+ */
+
+ if (count == 1) {
+ XmuDeleteStandardColormap(dpy, screen, property);
+ if (cnew)
+ XSetRGBColormaps(dpy, win, cnew, 1, property);
+ }
+ else {
+ XStandardColormap *map;
+
+ /* s still points to the matching standard colormap */
+
+ if (s->killid == ReleaseByFreeingColormap) {
+ if ((s->colormap != None) &&
+ (s->colormap != DefaultColormap(dpy, screen)))
+ XFreeColormap(dpy, s->colormap);
+ }
+ else if (s->killid != None)
+ XKillClient(dpy, s->killid);
+
+ map = (cnew) ? cnew : stdcmaps + --count;
+
+ s->colormap = map->colormap;
+ s->red_max = map->red_max;
+ s->red_mult = map->red_mult;
+ s->green_max = map->green_max;
+ s->green_mult = map->green_mult;
+ s->blue_max = map->blue_max;
+ s->blue_mult = map->blue_mult;
+ s->visualid = map->visualid;
+ s->killid = map->killid;
+
+ XSetRGBColormaps(dpy, win, stdcmaps, count, property);
+ }
+ }
+ XFree((char *) stdcmaps);
+ return 1;
+}
+
+/* $Xorg: CmapAlloc.c,v 1.4 2001/02/09 02:03:51 xorgcvs Exp $ */
+
+/*
+
+Copyright 1989, 1994, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+/* $XFree86: xc/lib/Xmu/CmapAlloc.c,v 1.7 2001/12/14 19:55:35 dawes Exp $ */
+
+/*
+ * Author: Donna Converse, MIT X Consortium
+ */
+
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+#include <X11/Xutil.h>
+#include <X11/Xmu/StdCmap.h>
+#include <stdio.h>
+
+#define lowbit(x) ((x) & (~(x) + 1))
+
+/*
+ * Prototypes
+ */
+static void best_allocation(XVisualInfo*, unsigned long*, unsigned long*,
+ unsigned long*);
+static int default_allocation(XVisualInfo*, unsigned long*,
+ unsigned long*, unsigned long*);
+static void gray_allocation(int, unsigned long*, unsigned long*,
+ unsigned long*);
+static int icbrt(int);
+static int icbrt_with_bits(int, int);
+static int icbrt_with_guess(int, int);
+
+/* To determine the best allocation of reds, greens, and blues in a
+ * standard colormap, use XmuGetColormapAllocation.
+ * vinfo specifies visual information for a chosen visual
+ * property specifies one of the standard colormap property names
+ * red_max returns maximum red value
+ * green_max returns maximum green value
+ * blue_max returns maximum blue value
+ *
+ * XmuGetColormapAllocation returns 0 on failure, non-zero on success.
+ * It is assumed that the visual is appropriate for the colormap property.
+ */
+
+Status
+XmuGetColormapAllocation(XVisualInfo *vinfo, Atom property,
+ unsigned long *red_max,
+ unsigned long *green_max,
+ unsigned long *blue_max)
+{
+ Status status = 1;
+
+ if (vinfo->colormap_size <= 2)
+ return 0;
+
+ switch (property)
+ {
+ case XA_RGB_DEFAULT_MAP:
+ status = default_allocation(vinfo, red_max, green_max, blue_max);
+ break;
+ case XA_RGB_BEST_MAP:
+ best_allocation(vinfo, red_max, green_max, blue_max);
+ break;
+ case XA_RGB_GRAY_MAP:
+ gray_allocation(vinfo->colormap_size, red_max, green_max, blue_max);
+ break;
+ case XA_RGB_RED_MAP:
+ *red_max = vinfo->colormap_size - 1;
+ *green_max = *blue_max = 0;
+ break;
+ case XA_RGB_GREEN_MAP:
+ *green_max = vinfo->colormap_size - 1;
+ *red_max = *blue_max = 0;
+ break;
+ case XA_RGB_BLUE_MAP:
+ *blue_max = vinfo->colormap_size - 1;
+ *red_max = *green_max = 0;
+ break;
+ default:
+ status = 0;
+ }
+ return status;
+}
+
+/****************************************************************************/
+/* Determine the appropriate color allocations of a gray scale.
+ *
+ * Keith Packard, MIT X Consortium
+ */
+
+static void
+gray_allocation(int n, unsigned long *red_max, unsigned long *green_max,
+ unsigned long *blue_max)
+{
+ *red_max = (n * 30) / 100;
+ *green_max = (n * 59) / 100;
+ *blue_max = (n * 11) / 100;
+ *green_max += ((n - 1) - (*red_max + *green_max + *blue_max));
+}
+
+/****************************************************************************/
+/* Determine an appropriate color allocation for the RGB_DEFAULT_MAP.
+ * If a map has less than a minimum number of definable entries, we do not
+ * produce an allocation for an RGB_DEFAULT_MAP.
+ *
+ * For 16 planes, the default colormap will have 27 each RGB; for 12 planes,
+ * 12 each. For 8 planes, let n = the number of colormap entries, which may
+ * be 256 or 254. Then, maximum red value = floor(cube_root(n - 125)) - 1.
+ * Maximum green and maximum blue values are identical to maximum red.
+ * This leaves at least 125 cells which clients can allocate.
+ *
+ * Return 0 if an allocation has been determined, non-zero otherwise.
+ */
+
+static int
+default_allocation(XVisualInfo *vinfo, unsigned long *red,
+ unsigned long *green, unsigned long *blue)
+{
+ int ngrays; /* number of gray cells */
+
+ switch (vinfo->c_class)
+ {
+ case PseudoColor:
+
+ if (vinfo->colormap_size > 65000)
+ /* intended for displays with 16 planes */
+ *red = *green = *blue = (unsigned long) 27;
+ else if (vinfo->colormap_size > 4000)
+ /* intended for displays with 12 planes */
+ *red = *green = *blue = (unsigned long) 12;
+ else if (vinfo->colormap_size < 250)
+ return 0;
+ else
+ /* intended for displays with 8 planes */
+ *red = *green = *blue = (unsigned long)
+ (icbrt(vinfo->colormap_size - 125) - 1);
+ break;
+
+ case DirectColor:
+
+ if (vinfo->colormap_size < 10)
+ return 0;
+ *red = *green = *blue = vinfo->colormap_size / 2 - 1;
+ break;
+
+ case TrueColor:
+
+ *red = vinfo->red_mask / lowbit(vinfo->red_mask);
+ *green = vinfo->green_mask / lowbit(vinfo->green_mask);
+ *blue = vinfo->blue_mask / lowbit(vinfo->blue_mask);
+ break;
+
+ case GrayScale:
+
+ if (vinfo->colormap_size > 65000)
+ ngrays = 4096;
+ else if (vinfo->colormap_size > 4000)
+ ngrays = 512;
+ else if (vinfo->colormap_size < 250)
+ return 0;
+ else
+ ngrays = 12;
+ gray_allocation(ngrays, red, green, blue);
+ break;
+
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+/****************************************************************************/
+/* Determine an appropriate color allocation for the RGB_BEST_MAP.
+ *
+ * For a DirectColor or TrueColor visual, the allocation is determined
+ * by the red_mask, green_mask, and blue_mask members of the visual info.
+ *
+ * Otherwise, if the colormap size is an integral power of 2, determine
+ * the allocation according to the number of bits given to each color,
+ * with green getting more than red, and red more than blue, if there
+ * are to be inequities in the distribution. If the colormap size is
+ * not an integral power of 2, let n = the number of colormap entries.
+ * Then maximum red value = floor(cube_root(n)) - 1;
+ * maximum blue value = floor(cube_root(n)) - 1;
+ * maximum green value = n / ((# red values) * (# blue values)) - 1;
+ * Which, on a GPX, allows for 252 entries in the best map, out of 254
+ * defineable colormap entries.
+ */
+
+static void
+best_allocation(XVisualInfo *vinfo, unsigned long *red, unsigned long *green,
+ unsigned long *blue)
+{
+
+ if (vinfo->c_class == DirectColor || vinfo->c_class == TrueColor)
+ {
+ *red = vinfo->red_mask;
+ while ((*red & 01) == 0)
+ *red >>= 1;
+ *green = vinfo->green_mask;
+ while ((*green & 01) == 0)
+ *green >>=1;
+ *blue = vinfo->blue_mask;
+ while ((*blue & 01) == 0)
+ *blue >>= 1;
+ }
+ else
+ {
+ register int bits, n;
+
+ /* Determine n such that n is the least integral power of 2 which is
+ * greater than or equal to the number of entries in the colormap.
+ */
+ n = 1;
+ bits = 0;
+ while (vinfo->colormap_size > n)
+ {
+ n = n << 1;
+ bits++;
+ }
+
+ /* If the number of entries in the colormap is a power of 2, determine
+ * the allocation by "dealing" the bits, first to green, then red, then
+ * blue. If not, find the maximum integral red, green, and blue values
+ * which, when multiplied together, do not exceed the number of
+
+ * colormap entries.
+ */
+ if (n == vinfo->colormap_size)
+ {
+ register int r, g, b;
+ b = bits / 3;
+ g = b + ((bits % 3) ? 1 : 0);
+ r = b + (((bits % 3) == 2) ? 1 : 0);
+ *red = 1 << r;
+ *green = 1 << g;
+ *blue = 1 << b;
+ }
+ else
+ {
+ *red = icbrt_with_bits(vinfo->colormap_size, bits);
+ *blue = *red;
+ *green = (vinfo->colormap_size / ((*red) * (*blue)));
+ }
+ (*red)--;
+ (*green)--;
+ (*blue)--;
+ }
+ return;
+}
+
+/*
+ * integer cube roots by Newton's method
+ *
+ * Stephen Gildea, MIT X Consortium, July 1991
+ */
+
+static int
+icbrt(int a)
+{
+ register int bits = 0;
+ register unsigned n = a;
+
+ while (n)
+ {
+ bits++;
+ n >>= 1;
+ }
+ return icbrt_with_bits(a, bits);
+}
+
+
+static int
+icbrt_with_bits(int a, int bits)
+ /* bits - log 2 of a */
+{
+ return icbrt_with_guess(a, a>>2*bits/3);
+}
+
+#ifdef _X_ROOT_STATS
+int icbrt_loopcount;
+#endif
+
+/* Newton's Method: x_n+1 = x_n - ( f(x_n) / f'(x_n) ) */
+
+/* for cube roots, x^3 - a = 0, x_new = x - 1/3 (x - a/x^2) */
+
+/*
+ * Quick and dirty cube roots. Nothing fancy here, just Newton's method.
+ * Only works for positive integers (since that's all we need).
+ * We actually return floor(cbrt(a)) because that's what we need here, too.
+ */
+
+static int
+icbrt_with_guess(int a, int guess)
+{
+ register int delta;
+
+#ifdef _X_ROOT_STATS
+ icbrt_loopcount = 0;
+#endif
+ if (a <= 0)
+ return 0;
+ if (guess < 1)
+ guess = 1;
+
+ do {
+#ifdef _X_ROOT_STATS
+ icbrt_loopcount++;
+#endif
+ delta = (guess - a/(guess*guess))/3;
+#ifdef DEBUG
+ printf("pass %d: guess=%d, delta=%d\n", icbrt_loopcount, guess, delta);
+#endif
+ guess -= delta;
+ } while (delta != 0);
+
+ if (guess*guess*guess > a)
+ guess--;
+
+ return guess;
+}
+
+
+/* $Xorg: StdCmap.c,v 1.4 2001/02/09 02:03:53 xorgcvs Exp $ */
+
+/*
+
+Copyright 1989, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+/* $XFree86: xc/lib/Xmu/StdCmap.c,v 1.6 2001/12/14 19:55:48 dawes Exp $ */
+
+/*
+ * Author: Donna Converse, MIT X Consortium
+ */
+
+#include <stdio.h>
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+#include <X11/Xutil.h>
+#include <X11/Xmu/StdCmap.h>
+
+#define lowbit(x) ((x) & (~(x) + 1))
+
+/*
+ * Prototypes
+ */
+/* argument restrictions */
+static Status valid_args(XVisualInfo*, unsigned long, unsigned long,
+ unsigned long, Atom);
+
+/*
+ * To create any one standard colormap, use XmuStandardColormap().
+ *
+ * Create a standard colormap for the given screen, visualid, and visual
+ * depth, with the given red, green, and blue maximum values, with the
+ * given standard property name. Return a pointer to an XStandardColormap
+ * structure which describes the newly created colormap, upon success.
+ * Upon failure, return NULL.
+ *
+ * XmuStandardColormap() calls XmuCreateColormap() to create the map.
+ *
+ * Resources created by this function are not made permanent; that is the
+ * caller's responsibility.
+ */
+
+XStandardColormap *
+XmuStandardColormap(Display *dpy, int screen, VisualID visualid,
+ unsigned int depth, Atom property, Colormap cmap,
+ unsigned long red_max, unsigned long green_max,
+ unsigned long blue_max)
+ /*
+ * dpy - specifies X server connection
+ * screen - specifies display screen
+ * visualid - identifies the visual type
+ * depth - identifies the visual type
+ * property - a standard colormap property
+ * cmap - specifies colormap ID or None
+ * red_max, green_max, blue_max - allocations
+ */
+{
+ XStandardColormap *stdcmap;
+ Status status;
+ XVisualInfo vinfo_template, *vinfo;
+ long vinfo_mask;
+ int n;
+
+ /* Match the required visual information to an actual visual */
+ vinfo_template.visualid = visualid;
+ vinfo_template.screen = screen;
+ vinfo_template.depth = depth;
+ vinfo_mask = VisualIDMask | VisualScreenMask | VisualDepthMask;
+ if ((vinfo = XGetVisualInfo(dpy, vinfo_mask, &vinfo_template, &n)) == NULL)
+ return 0;
+
+ /* Check the validity of the combination of visual characteristics,
+ * allocation, and colormap property. Create an XStandardColormap
+ * structure.
+ */
+
+ if (! valid_args(vinfo, red_max, green_max, blue_max, property)
+ || ((stdcmap = XAllocStandardColormap()) == NULL)) {
+ XFree((char *) vinfo);
+ return 0;
+ }
+
+ /* Fill in the XStandardColormap structure */
+
+ if (cmap == DefaultColormap(dpy, screen)) {
+ /* Allocating out of the default map, cannot use XFreeColormap() */
+ Window win = XCreateWindow(dpy, RootWindow(dpy, screen), 1, 1, 1, 1,
+ 0, 0, InputOnly, vinfo->visual,
+ (unsigned long) 0,
+ (XSetWindowAttributes *)NULL);
+ stdcmap->killid = (XID) XCreatePixmap(dpy, win, 1, 1, depth);
+ XDestroyWindow(dpy, win);
+ stdcmap->colormap = cmap;
+ } else {
+ stdcmap->killid = ReleaseByFreeingColormap;
+ stdcmap->colormap = XCreateColormap(dpy, RootWindow(dpy, screen),
+ vinfo->visual, AllocNone);
+ }
+ stdcmap->red_max = red_max;
+ stdcmap->green_max = green_max;
+ stdcmap->blue_max = blue_max;
+ if (property == XA_RGB_GRAY_MAP)
+ stdcmap->red_mult = stdcmap->green_mult = stdcmap->blue_mult = 1;
+ else if (vinfo->c_class == TrueColor || vinfo->c_class == DirectColor) {
+ stdcmap->red_mult = lowbit(vinfo->red_mask);
+ stdcmap->green_mult = lowbit(vinfo->green_mask);
+ stdcmap->blue_mult = lowbit(vinfo->blue_mask);
+ } else {
+ stdcmap->red_mult = (red_max > 0)
+ ? (green_max + 1) * (blue_max + 1) : 0;
+ stdcmap->green_mult = (green_max > 0) ? blue_max + 1 : 0;
+ stdcmap->blue_mult = (blue_max > 0) ? 1 : 0;
+ }
+ stdcmap->base_pixel = 0; /* base pixel may change */
+ stdcmap->visualid = vinfo->visualid;
+
+ /* Make the colormap */
+
+ status = XmuCreateColormap(dpy, stdcmap);
+
+ /* Clean up */
+
+ XFree((char *) vinfo);
+ if (!status) {
+
+ /* Free the colormap or the pixmap, if we created one */
+ if (stdcmap->killid == ReleaseByFreeingColormap)
+ XFreeColormap(dpy, stdcmap->colormap);
+ else if (stdcmap->killid != None)
+ XFreePixmap(dpy, stdcmap->killid);
+
+ XFree((char *) stdcmap);
+ return (XStandardColormap *) NULL;
+ }
+ return stdcmap;
+}
+
+/****************************************************************************/
+static Status
+valid_args(XVisualInfo *vinfo, unsigned long red_max, unsigned long green_max,
+ unsigned long blue_max, Atom property)
+ /*
+ * vinfo - specifies visual
+ * red_max, green_max, blue_max - specifies alloc
+ * property - specifies property name
+ */
+{
+ unsigned long ncolors; /* number of colors requested */
+
+ /* Determine that the number of colors requested is <= map size */
+
+ if ((vinfo->c_class == DirectColor) || (vinfo->c_class == TrueColor)) {
+ unsigned long mask;
+
+ mask = vinfo->red_mask;
+ while (!(mask & 1))
+ mask >>= 1;
+ if (red_max > mask)
+ return 0;
+ mask = vinfo->green_mask;
+ while (!(mask & 1))
+ mask >>= 1;
+ if (green_max > mask)
+ return 0;
+ mask = vinfo->blue_mask;
+ while (!(mask & 1))
+ mask >>= 1;
+ if (blue_max > mask)
+ return 0;
+ } else if (property == XA_RGB_GRAY_MAP) {
+ ncolors = red_max + green_max + blue_max + 1;
+ if (ncolors > vinfo->colormap_size)
+ return 0;
+ } else {
+ ncolors = (red_max + 1) * (green_max + 1) * (blue_max + 1);
+ if (ncolors > vinfo->colormap_size)
+ return 0;
+ }
+
+ /* Determine that the allocation and visual make sense for the property */
+
+ switch (property)
+ {
+ case XA_RGB_DEFAULT_MAP:
+ if (red_max == 0 || green_max == 0 || blue_max == 0)
+ return 0;
+ break;
+ case XA_RGB_RED_MAP:
+ if (red_max == 0)
+ return 0;
+ break;
+ case XA_RGB_GREEN_MAP:
+ if (green_max == 0)
+ return 0;
+ break;
+ case XA_RGB_BLUE_MAP:
+ if (blue_max == 0)
+ return 0;
+ break;
+ case XA_RGB_BEST_MAP:
+ if (red_max == 0 || green_max == 0 || blue_max == 0)
+ return 0;
+ break;
+ case XA_RGB_GRAY_MAP:
+ if (red_max == 0 || blue_max == 0 || green_max == 0)
+ return 0;
+ break;
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+
+/* $Xorg: CrCmap.c,v 1.4 2001/02/09 02:03:51 xorgcvs Exp $ */
+
+/*
+
+Copyright 1989, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+/* $XFree86: xc/lib/Xmu/CrCmap.c,v 3.7 2001/12/14 19:55:36 dawes Exp $ */
+
+/*
+ * Author: Donna Converse, MIT X Consortium
+ */
+
+/*
+ * CreateCmap.c - given a standard colormap description, make the map.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xmu/StdCmap.h>
+
+/*
+ * Prototypes
+ */
+/* allocate entire map Read Only */
+static int ROmap(Display*, Colormap, unsigned long[], int, int);
+
+/* allocate a cell, prefer Read Only */
+static Status ROorRWcell(Display*, Colormap, unsigned long[], int,
+ XColor*, unsigned long);
+
+/* allocate a cell Read Write */
+static Status RWcell(Display*, Colormap, XColor*, XColor*, unsigned long*);
+
+/* for quicksort */
+static int compare(_Xconst void*, _Xconst void*);
+
+/* find contiguous sequence of cells */
+static Status contiguous(unsigned long[], int, int, unsigned long, int*, int*);
+
+/* frees resources before quitting */
+static void free_cells(Display*, Colormap, unsigned long[], int, int);
+
+/* create a map in a RO visual type */
+static Status readonly_map(Display*, XVisualInfo*, XStandardColormap*);
+
+/* create a map in a RW visual type */
+static Status readwrite_map(Display*, XVisualInfo*, XStandardColormap*);
+
+#define lowbit(x) ((x) & (~(x) + 1))
+#define TRUEMATCH(mult,max,mask) \
+ (colormap->max * colormap->mult <= vinfo->mask && \
+ lowbit(vinfo->mask) == colormap->mult)
+
+/*
+ * To create any one colormap which is described by an XStandardColormap
+ * structure, use XmuCreateColormap().
+ *
+ * Return 0 on failure, non-zero on success.
+ * Resources created by this function are not made permanent.
+ * No argument error checking is provided. Use at your own risk.
+ *
+ * All colormaps are created with read only allocations, with the exception
+ * of read only allocations of colors in the default map or otherwise
+ * which fail to return the expected pixel value, and these are individually
+ * defined as read/write allocations. This is done so that all the cells
+ * defined in the default map are contiguous, for use in image processing.
+ * This typically happens with White and Black in the default map.
+ *
+ * Colormaps of static visuals are considered to be successfully created if
+ * the map of the static visual matches the definition given in the
+ * standard colormap structure.
+ */
+
+Status
+XmuCreateColormap(Display *dpy, XStandardColormap *colormap)
+ /* dpy - specifies the connection under which the map is created
+ * colormap - specifies the map to be created, and returns, particularly
+ * if the map is created as a subset of the default colormap
+ * of the screen, the base_pixel of the map.
+ */
+{
+ XVisualInfo vinfo_template; /* template visual information */
+ XVisualInfo *vinfo; /* matching visual information */
+ XVisualInfo *vpointer; /* for freeing the entire list */
+ long vinfo_mask; /* specifies the visual mask value */
+ int n; /* number of matching visuals */
+ int status;
+
+ vinfo_template.visualid = colormap->visualid;
+ vinfo_mask = VisualIDMask;
+ if ((vinfo = XGetVisualInfo(dpy, vinfo_mask, &vinfo_template, &n)) == NULL)
+ return 0;
+
+ /* A visual id may be valid on multiple screens. Also, there may
+ * be multiple visuals with identical visual ids at different depths.
+ * If the colormap is the Default Colormap, use the Default Visual.
+ * Otherwise, arbitrarily, use the deepest visual.
+ */
+ vpointer = vinfo;
+ if (n > 1)
+ {
+ register int i;
+ register int screen_number;
+ Bool def_cmap;
+
+ def_cmap = False;
+ for (screen_number = ScreenCount(dpy); --screen_number >= 0; )
+ if (colormap->colormap == DefaultColormap(dpy, screen_number)) {
+ def_cmap = True;
+ break;
+ }
+
+ if (def_cmap) {
+ for (i=0; i < n; i++, vinfo++) {
+ if (vinfo->visual == DefaultVisual(dpy, screen_number))
+ break;
+ }
+ } else {
+ int maxdepth = 0;
+ XVisualInfo *v = NULL;
+
+ for (i=0; i < n; i++, vinfo++)
+ if (vinfo->depth > maxdepth) {
+ maxdepth = vinfo->depth;
+ v = vinfo;
+ }
+ vinfo = v;
+ }
+ }
+
+ if (vinfo->c_class == PseudoColor || vinfo->c_class == DirectColor ||
+ vinfo->c_class == GrayScale)
+ status = readwrite_map(dpy, vinfo, colormap);
+ else if (vinfo->c_class == TrueColor)
+ status = TRUEMATCH(red_mult, red_max, red_mask) &&
+ TRUEMATCH(green_mult, green_max, green_mask) &&
+ TRUEMATCH(blue_mult, blue_max, blue_mask);
+ else
+ status = readonly_map(dpy, vinfo, colormap);
+
+ XFree((char *) vpointer);
+ return status;
+}
+
+/****************************************************************************/
+static Status
+readwrite_map(Display *dpy, XVisualInfo *vinfo, XStandardColormap *colormap)
+{
+ register unsigned long i, n; /* index counters */
+ unsigned long ncolors; /* number of colors to be defined */
+ int npixels; /* number of pixels allocated R/W */
+ int first_index; /* first index of pixels to use */
+ int remainder; /* first index of remainder */
+ XColor color; /* the definition of a color */
+ unsigned long *pixels; /* array of colormap pixels */
+ unsigned long delta;
+
+
+ /* Determine ncolors, the number of colors to be defined.
+ * Insure that 1 < ncolors <= the colormap size.
+ */
+ if (vinfo->c_class == DirectColor) {
+ ncolors = colormap->red_max;
+ if (colormap->green_max > ncolors)
+ ncolors = colormap->green_max;
+ if (colormap->blue_max > ncolors)
+ ncolors = colormap->blue_max;
+ ncolors++;
+ delta = lowbit(vinfo->red_mask) +
+ lowbit(vinfo->green_mask) +
+ lowbit(vinfo->blue_mask);
+ } else {
+ ncolors = colormap->red_max * colormap->red_mult +
+ colormap->green_max * colormap->green_mult +
+ colormap->blue_max * colormap->blue_mult + 1;
+ delta = 1;
+ }
+ if (ncolors <= 1 || (int) ncolors > vinfo->colormap_size) return 0;
+
+ /* Allocate Read/Write as much of the colormap as we can possibly get.
+ * Then insure that the pixels we were allocated are given in
+ * monotonically increasing order, using a quicksort. Next, insure
+ * that our allocation includes a subset of contiguous pixels at least
+ * as long as the number of colors to be defined. Now we know that
+ * these conditions are met:
+ * 1) There are no free cells in the colormap.
+ * 2) We have a contiguous sequence of pixels, monotonically
+ * increasing, of length >= the number of colors requested.
+ *
+ * One cell at a time, we will free, compute the next color value,
+ * then allocate read only. This takes a long time.
+ * This is done to insure that cells are allocated read only in the
+ * contiguous order which we prefer. If the server has a choice of
+ * cells to grant to an allocation request, the server may give us any
+ * cell, so that is why we do these slow gymnastics.
+ */
+
+ if ((pixels = (unsigned long *) calloc((unsigned) vinfo->colormap_size,
+ sizeof(unsigned long))) == NULL)
+ return 0;
+
+ if ((npixels = ROmap(dpy, colormap->colormap, pixels,
+ vinfo->colormap_size, ncolors)) == 0) {
+ free((char *) pixels);
+ return 0;
+ }
+
+ qsort((char *) pixels, npixels, sizeof(unsigned long), compare);
+
+ if (!contiguous(pixels, npixels, ncolors, delta, &first_index, &remainder))
+ {
+ /* can't find enough contiguous cells, give up */
+ XFreeColors(dpy, colormap->colormap, pixels, npixels,
+ (unsigned long) 0);
+ free((char *) pixels);
+ return 0;
+ }
+ colormap->base_pixel = pixels[first_index];
+
+ /* construct a gray map */
+ if (colormap->red_mult == 1 && colormap->green_mult == 1 &&
+ colormap->blue_mult == 1)
+ for (n=colormap->base_pixel, i=0; i < ncolors; i++, n += delta)
+ {
+ color.pixel = n;
+ color.blue = color.green = color.red =
+ (unsigned short) ((i * 65535) / (colormap->red_max +
+ colormap->green_max +
+ colormap->blue_max));
+
+ if (! ROorRWcell(dpy, colormap->colormap, pixels, npixels, &color,
+ first_index + i))
+ return 0;
+ }
+
+ /* construct a red ramp map */
+ else if (colormap->green_max == 0 && colormap->blue_max == 0)
+ for (n=colormap->base_pixel, i=0; i < ncolors; i++, n += delta)
+ {
+ color.pixel = n;
+ color.red = (unsigned short) ((i * 65535) / colormap->red_max);
+ color.green = color.blue = 0;
+
+ if (! ROorRWcell(dpy, colormap->colormap, pixels, npixels, &color,
+ first_index + i))
+ return 0;
+ }
+
+ /* construct a green ramp map */
+ else if (colormap->red_max == 0 && colormap->blue_max == 0)
+ for (n=colormap->base_pixel, i=0; i < ncolors; i++, n += delta)
+ {
+ color.pixel = n;
+ color.green = (unsigned short) ((i * 65535) / colormap->green_max);
+ color.red = color.blue = 0;
+
+ if (! ROorRWcell(dpy, colormap->colormap, pixels, npixels, &color,
+ first_index + i))
+ return 0;
+ }
+
+ /* construct a blue ramp map */
+ else if (colormap->red_max == 0 && colormap->green_max == 0)
+ for (n=colormap->base_pixel, i=0; i < ncolors; i++, n += delta)
+ {
+ color.pixel = n;
+ color.blue = (unsigned short) ((i * 65535) / colormap->blue_max);
+ color.red = color.green = 0;
+
+ if (! ROorRWcell(dpy, colormap->colormap, pixels, npixels, &color,
+ first_index + i))
+ return 0;
+ }
+
+ /* construct a standard red green blue cube map */
+ else
+ {
+#define calc(max,mult) (((n / colormap->mult) % \
+ (colormap->max + 1)) * 65535) / colormap->max
+
+ for (n=0, i=0; i < ncolors; i++, n += delta)
+ {
+ color.pixel = n + colormap->base_pixel;
+ color.red = calc(red_max, red_mult);
+ color.green = calc(green_max, green_mult);
+ color.blue = calc(blue_max, blue_mult);
+ if (! ROorRWcell(dpy, colormap->colormap, pixels, npixels, &color,
+ first_index + i))
+ return 0;
+ }
+#undef calc
+ }
+ /* We have a read-only map defined. Now free unused cells,
+ * first those occuring before the contiguous sequence begins,
+ * then any following the contiguous sequence.
+ */
+
+ if (first_index)
+ XFreeColors(dpy, colormap->colormap, pixels, first_index,
+ (unsigned long) 0);
+ if (remainder)
+ XFreeColors(dpy, colormap->colormap,
+ &(pixels[first_index + ncolors]), remainder,
+ (unsigned long) 0);
+
+ free((char *) pixels);
+ return 1;
+}
+
+
+/****************************************************************************/
+static int
+ROmap(Display *dpy, Colormap cmap, unsigned long pixels[], int m, int n)
+ /*
+ * dpy - the X server connection
+ * cmap - specifies colormap ID
+ * pixels - returns pixel allocations
+ * m - specifies colormap size
+ * n - specifies number of colors
+ */
+{
+ register int p;
+
+ /* first try to allocate the entire colormap */
+ if (XAllocColorCells(dpy, cmap, 1, (unsigned long *) NULL,
+ (unsigned) 0, pixels, (unsigned) m))
+ return m;
+
+ /* Allocate all available cells in the colormap, using a binary
+ * algorithm to discover how many cells we can allocate in the colormap.
+ */
+ m--;
+ while (n <= m) {
+ p = n + ((m - n + 1) / 2);
+ if (XAllocColorCells(dpy, cmap, 1, (unsigned long *) NULL,
+ (unsigned) 0, pixels, (unsigned) p)) {
+ if (p == m)
+ return p;
+ else {
+ XFreeColors(dpy, cmap, pixels, p, (unsigned long) 0);
+ n = p;
+ }
+ }
+ else
+ m = p - 1;
+ }
+ return 0;
+}
+
+
+/****************************************************************************/
+static Status
+contiguous(unsigned long pixels[], int npixels, int ncolors,
+ unsigned long delta, int *first, int *rem)
+ /* pixels - specifies allocated pixels
+ * npixels - specifies count of alloc'd pixels
+ * ncolors - specifies needed sequence length
+ * delta - between pixels
+ * first - returns first index of sequence
+ * rem - returns first index after sequence, or 0, if none follow
+ */
+{
+ register int i = 1; /* walking index into the pixel array */
+ register int count = 1; /* length of sequence discovered so far */
+
+ *first = 0;
+ if (npixels == ncolors) {
+ *rem = 0;
+ return 1;
+ }
+ *rem = npixels - 1;
+ while (count < ncolors && ncolors - count <= *rem)
+ {
+ if (pixels[i-1] + delta == pixels[i])
+ count++;
+ else {
+ count = 1;
+ *first = i;
+ }
+ i++;
+ (*rem)--;
+ }
+ if (count != ncolors)
+ return 0;
+ return 1;
+}
+
+
+/****************************************************************************/
+static Status
+ROorRWcell(Display *dpy, Colormap cmap, unsigned long pixels[],
+ int npixels, XColor *color, unsigned long p)
+{
+ unsigned long pixel;
+ XColor request;
+
+ /* Free the read/write allocation of one cell in the colormap.
+ * Request a read only allocation of one cell in the colormap.
+ * If the read only allocation cannot be granted, give up, because
+ * there must be no free cells in the colormap.
+ * If the read only allocation is granted, but gives us a cell which
+ * is not the one that we just freed, it is probably the case that
+ * we are trying allocate White or Black or some other color which
+ * already has a read-only allocation in the map. So we try to
+ * allocate the previously freed cell with a read/write allocation,
+ * because we want contiguous cells for image processing algorithms.
+ */
+
+ pixel = color->pixel;
+ request.red = color->red;
+ request.green = color->green;
+ request.blue = color->blue;
+
+ XFreeColors(dpy, cmap, &pixel, 1, (unsigned long) 0);
+ if (! XAllocColor(dpy, cmap, color)
+ || (color->pixel != pixel &&
+ (!RWcell(dpy, cmap, color, &request, &pixel))))
+ {
+ free_cells(dpy, cmap, pixels, npixels, (int)p);
+ return 0;
+ }
+ return 1;
+}
+
+
+/****************************************************************************/
+static void
+free_cells(Display *dpy, Colormap cmap, unsigned long pixels[],
+ int npixels, int p)
+ /*
+ * pixels - to be freed
+ * npixels - original number allocated
+ */
+{
+ /* One of the npixels allocated has already been freed.
+ * p is the index of the freed pixel.
+ * First free the pixels preceeding p, and there are p of them;
+ * then free the pixels following p, there are npixels - p - 1 of them.
+ */
+ XFreeColors(dpy, cmap, pixels, p, (unsigned long) 0);
+ XFreeColors(dpy, cmap, &(pixels[p+1]), npixels - p - 1, (unsigned long) 0);
+ free((char *) pixels);
+}
+
+
+/****************************************************************************/
+static Status
+RWcell(Display *dpy, Colormap cmap, XColor *color, XColor *request,
+ unsigned long *pixel)
+{
+ unsigned long n = *pixel;
+
+ XFreeColors(dpy, cmap, &(color->pixel), 1, (unsigned long)0);
+ if (! XAllocColorCells(dpy, cmap, (Bool) 0, (unsigned long *) NULL,
+ (unsigned) 0, pixel, (unsigned) 1))
+ return 0;
+ if (*pixel != n)
+ {
+ XFreeColors(dpy, cmap, pixel, 1, (unsigned long) 0);
+ return 0;
+ }
+ color->pixel = *pixel;
+ color->flags = DoRed | DoGreen | DoBlue;
+ color->red = request->red;
+ color->green = request->green;
+ color->blue = request->blue;
+ XStoreColors(dpy, cmap, color, 1);
+ return 1;
+}
+
+
+/****************************************************************************/
+static int
+compare(_Xconst void *e1, _Xconst void *e2)
+{
+ return ((int)(*(long *)e1 - *(long *)e2));
+}
+
+
+/****************************************************************************/
+static Status
+readonly_map(Display *dpy, XVisualInfo *vinfo, XStandardColormap *colormap)
+{
+ int i, last_pixel;
+ XColor color;
+
+ last_pixel = (colormap->red_max + 1) * (colormap->green_max + 1) *
+ (colormap->blue_max + 1) + colormap->base_pixel - 1;
+
+ for(i=colormap->base_pixel; i <= last_pixel; i++) {
+
+ color.pixel = (unsigned long) i;
+ color.red = (unsigned short)
+ (((i/colormap->red_mult) * 65535) / colormap->red_max);
+
+ if (vinfo->c_class == StaticColor) {
+ color.green = (unsigned short)
+ ((((i/colormap->green_mult) % (colormap->green_max + 1)) *
+ 65535) / colormap->green_max);
+ color.blue = (unsigned short)
+ (((i%colormap->green_mult) * 65535) / colormap->blue_max);
+ }
+ else /* vinfo->c_class == GrayScale, old style allocation XXX */
+ color.green = color.blue = color.red;
+
+ XAllocColor(dpy, colormap->colormap, &color);
+ if (color.pixel != (unsigned long) i)
+ return 0;
+ }
+ return 1;
+}
+
+
+/* $Xorg: DelCmap.c,v 1.4 2001/02/09 02:03:52 xorgcvs Exp $ */
+
+/*
+
+Copyright 1989, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+/* $XFree86: xc/lib/Xmu/DelCmap.c,v 1.7 2001/12/14 19:55:40 dawes Exp $ */
+
+/*
+ * Author: Donna Converse, MIT X Consortium
+ */
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xmu/StdCmap.h>
+
+int ignoreErrorHandler(Display* d, XErrorEvent* e) { }
+
+/* To remove any standard colormap property, use XmuDeleteStandardColormap().
+ * XmuDeleteStandardColormap() will remove the specified property from the
+ * specified screen, releasing any resources used by the colormap(s) of the
+ * property if possible.
+ */
+
+void
+XmuDeleteStandardColormap(Display *dpy, int screen, Atom property)
+ /* dpy; - specifies the X server to connect to
+ * screen - specifies the screen of the display
+ * property - specifies the standard colormap property
+ */
+{
+ XStandardColormap *stdcmaps, *s;
+ int count = 0;
+
+ if (XGetRGBColormaps(dpy, RootWindow(dpy, screen), &stdcmaps, &count,
+ property))
+ {
+ for (s=stdcmaps; count > 0; count--, s++) {
+ if ((s->killid == ReleaseByFreeingColormap) &&
+ (s->colormap != None) &&
+ (s->colormap != DefaultColormap(dpy, screen))) {
+
+ // UGLY HACK written in by Adam Megacz -- sometimes s->colormap isn't valid, so we do some shuffling
+ X11ErrorHandler* oldHandler = XSetErrorHandler(ignoreErrorHandler);
+ XSync(dpy, False);
+ XFreeColormap(dpy, s->colormap);
+ XSync(dpy, False);
+ XSetErrorHandler(oldHandler);
+ XSync(dpy, False);
+
+ } else if (s->killid != None) {
+ XKillClient(dpy, s->killid);
+ }
+ }
+ XDeleteProperty(dpy, RootWindow(dpy, screen), property);
+ XFree((char *) stdcmaps);
+ XSync(dpy, False);
+ }
+}
+
+
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [LGPL]
+package org.ibex.plat;
+
+import gnu.gcj.RawData;
+import java.util.*;
+import org.ibex.js.*;
+import org.ibex.util.*;
+import org.ibex.graphics.*;
+import org.ibex.core.*;
+import org.ibex.net.*;
+
+/** Platform implementation for POSIX compliant operating systems with an X11 Server */
+public class X11 extends POSIX {
+
+ // Static Data ///////////////////////////////////////////////////////////
+
+ /**
+ * When the user reads from the clipboard, the main thread blocks
+ * on this semaphore until we get an X11 SelectionNotify. Crude,
+ * but effective. We know that only one thread will ever block on
+ * this, since only one thread can ever be running JavaScript.
+ */
+ public static Semaphore waiting_for_selection_event = new Semaphore();
+
+ /** our local (in-process) copy of the clipboard */
+ public static String clipboard = null;
+
+ /** map from Window's (casted to jlong, wrapped in java.lang.Long) to X11Surface objects */
+ public static Hashtable windowToSurfaceMap = new Hashtable();
+
+
+ // General Methods ///////////////////////////////////////////////////////
+
+ protected String _getAltKeyName() { return System.getProperty("os.name", "").indexOf("SunOS") != -1 ? "Meta" : "Alt"; }
+
+ protected Picture _createPicture(JS r) { return new X11Picture(r); }
+ protected PixelBuffer _createPixelBuffer(int w, int h, Surface owner) { return new X11PixelBuffer(w, h); }
+ protected Surface _createSurface(Box b, boolean framed) { return new X11Surface(b, framed); }
+ protected boolean _needsAutoClick() { return true; }
+ protected native int _getScreenWidth();
+ protected native int _getScreenHeight();
+ protected native String _getClipBoard();
+ protected native void _setClipBoard(String s);
+ protected boolean _needsAutoDoubleClick() { return true; }
+ protected native String _fileDialog(String suggestedFileName, boolean write);
+ protected native void eventThread();
+ private native void natInit();
+
+ public void postInit() {
+ natInit();
+ (new Thread() { public void run() { eventThread(); } }).start();
+ }
+
+ // X11Surface /////////////////////////////////////////////////////
+
+ /** Implements a Surface as an X11 Window */
+ public static class X11Surface extends Surface.DoubleBufferedSurface {
+
+ gnu.gcj.RawData window;
+ gnu.gcj.RawData gc;
+ boolean framed = false;
+ Semaphore waitForCreation = new Semaphore();
+
+ public native void setInvisible(boolean i);
+ public void _setMaximized(boolean m) { if (Log.on) Log.warn(this, "X11 can't maximize windows"); }
+ public native void setIcon(Picture p);
+ public native void _setMinimized(boolean b);
+ public native void setTitleBarText(String s);
+ public native void _setSize(int w, int h);
+ public native void setLocation();
+ public native void natInit();
+ public native void toFront();
+ public native void toBack();
+ public native void syncCursor();
+ public native void _dispose();
+ public native void setLimits(int minw, int minh, int maxw, int maxh);
+ public native void blit(PixelBuffer s, int sx, int sy, int dx, int dy, int dx2, int dy2);
+ public native void dispatchEvent(gnu.gcj.RawData ev);
+ public void setMinimumSize(int minx, int miny, boolean resizable) {
+ setLimits(minx, miny, resizable ? Short.MAX_VALUE : minx, resizable ? Short.MAX_VALUE : miny);
+ }
+ public X11Surface(Box root, boolean framed) {
+ super(root);
+ this.framed = framed;
+ natInit();
+ }
+
+ }
+
+
+ // Our Subclass of Picture ///////////////////////////////////////////////
+
+ /**
+ * Implements a Picture. No special X11 structure is created
+ * unless the image has no alpha (in which case a
+ * non-shared-pixmap PixelBuffer is created), or all-or-nothing
+ * alpha (in which case a non-shared-pixmap PixelBuffer with a
+ * stipple bitmap is created).
+ */
+ public static class X11Picture extends Picture {
+
+ public X11PixelBuffer doublebuf = null;
+
+ public int getWidth() { return width; }
+ public int getHeight() { return height; }
+
+ boolean initialized = false;
+ public X11Picture(JS r) { super(r); }
+ public void init() {
+ if (initialized) return;
+ initialized = true;
+ boolean needsStipple = false;
+
+ // if we have any non-0x00, non-0xFF alphas, we can't double buffer ourselves
+ for(int i=0; i<width*height; i++)
+ if ((data[i] & 0xFF000000) == 0xFF000000)
+ needsStipple = true;
+ else if ((data[i] & 0xFF000000) != 0x00)
+ return;
+
+ buildPixelBuffer(needsStipple);
+ }
+
+ void buildPixelBuffer(boolean needsStipple) {
+ if (doublebuf != null) return;
+ // no point in using a shared pixmap since we'll only write to this image once
+ X11PixelBuffer b = new X11PixelBuffer(width, height, false);
+ b.drawPicture(this, 0, 0, 0, 0, width, height);
+ if (needsStipple) b.createStipple(this);
+ doublebuf = b;
+ }
+ }
+
+ /**
+ * An X11PixelBuffer is implemented as an X11 pixmap. "Normal"
+ * PixelBuffers will use XShm shared pixmaps if
+ * available. X11PixelBuffers created to accelerate Pictures
+ * with all-or-nothing alpha will not use shared pixmaps, however
+ * (since they are only written to once.
+ */
+ public static class X11PixelBuffer extends PixelBuffer {
+
+ int clipx, clipy, clipw, cliph;
+ int width;
+ int height;
+
+ /** PixelBuffers of X11Pictures can have stipples -- the stipple of the Picture */
+ RawData stipple = null;
+
+ /** Sets the PixelBuffer's internal stipple to the alpha==0x00 regions of xpi */
+ public native void createStipple(X11Picture xpi);
+
+ RawData pm; // Pixmap (if any) representing this Picture
+ boolean shared_pixmap = false; // true if pm is a ShmPixmap
+ RawData fake_ximage = null; // a 'fake' XImage corresponding to the shared pixmap; gives us the address and depth parameters
+ RawData shm_segment = null; // XShmSegmentInfo
+
+ RawData gc; // Graphics Interpreter on pm (never changes, so it's fast)
+ RawData clipped_gc; // Graphics Interpreter on pm, use this one if you need a clip/stipple
+
+ /** PixelBuffer mode */
+ public X11PixelBuffer(int w, int h) { this(w, h, true); }
+ public X11PixelBuffer(int w, int h, boolean shared_pixmap) {
+ width = clipw = w;
+ height = cliph = h;
+ clipx = clipy = 0;
+ this.shared_pixmap = shared_pixmap;
+ natInit();
+ }
+
+ public void drawGlyph(Font.Glyph source, int dx, int dy, int cx1, int cy1, int cx2, int cy2, int rgb) {
+ cx1 = Math.max(dx, cx1);
+ cy1 = Math.max(dy, cy1);
+ cx2 = Math.min(dx + source.width, cx2);
+ cy2 = Math.min(dy + source.height, cy2);
+ if (cx1 >= cx2 || cy1 >= cy2) return;
+ X11Picture pic = (X11Picture)((Platform.DefaultGlyph)source).getPicture();
+ pic.init();
+ slowDrawPicture(pic, dx, dy, cx1, cy1, cx2, cy2, rgb, true);
+ }
+ public void drawPicture(Picture source, int dx, int dy, int cx1, int cy1, int cx2, int cy2) {
+ cx1 = Math.max(dx, cx1);
+ cy1 = Math.max(dy, cy1);
+ cx2 = Math.min(dx + source.width, cx2);
+ cy2 = Math.min(dy + source.height, cy2);
+ if (cx1 >= cx2 || cy1 >= cy2) return;
+ ((X11Picture)source).init();
+ if (((X11Picture)source).doublebuf != null)
+ fastDrawPicture(source, dx, dy, cx1, cy1, cx2, cy2);
+ else
+ slowDrawPicture(source, dx, dy, cx1, cy1, cx2, cy2, 0, false);
+ }
+
+ /** fast path for image drawing (no scaling, all-or-nothing alpha) */
+ public native void fastDrawPicture(Picture source, int dx, int dy, int cx1, int cy1, int cx2, int cy2);
+
+ /** slow path for image drawing */
+ public native void slowDrawPicture(Picture source, int dx, int dy, int cx1, int cy1, int cx2, int cy2, int rgb, boolean alphaOnly);
+
+ public int getWidth() { return width; }
+ public int getHeight() { return height; }
+ public native void natInit();
+ public native void fillRect(int x, int y, int x2, int y2, int color);
+ public native void finalize();
+
+ // FIXME: try to use os acceleration
+ public void fillTrapezoid(int x1, int x2, int y1, int x3, int x4, int y2, int argb) {
+ if (x1 == x3 && x2 == x4) {
+ fillRect(x1, y1, x4, y2, argb);
+ } else for(int y=y1; y<y2; y++) {
+ int _x1 = (int)Math.floor((y - y1) * (x3 - x1) / (y2 - y1) + x1);
+ int _y1 = (int)Math.floor(y);
+ int _x2 = (int)Math.ceil((y - y1) * (x4 - x2) / (y2 - y1) + x2);
+ int _y2 = (int)Math.floor(y) + 1;
+ if (_x1 > _x2) { int _x0 = _x1; _x1 = _x2; _x2 = _x0; }
+ fillRect(_x1, _y1, _x2, _y2, argb);
+ }
+ }
+ }
+
+}
--- /dev/null
+package org.ibex.util;
+
+import java.io.*;
+
+public class AccessibleCharArrayWriter extends CharArrayWriter {
+ public char[] getBuf() { return buf; }
+ public AccessibleCharArrayWriter(int i) { super(i); }
+}
+
--- /dev/null
+// Copyright (C) 2003 Adam Megacz <adam@ibex.org> all rights reserved.
+//
+// You may modify, copy, and redistribute this code under the terms of
+// the GNU Library Public License version 2.1, with the exception of
+// the portion of clause 6a after the semicolon (aka the "obnoxious
+// relink clause")
+
+package org.ibex.util;
+
+// FEATURE: private void intersection() { }
+// FEATURE: private void union() { }
+// FEATURE: private void subset() { }
+// FEATURE: grow if we run out of slots
+
+/** a weight-balanced tree with fake leaves */
+public class BalancedTree {
+
+
+ // Instance Variables ///////////////////////////////////////////////////////////////////
+
+ private int root = 0; ///< the slot of the root element
+
+ private int cached_index = -1;
+ private int cached_slot = -1;
+
+ // Public API //////////////////////////////////////////////////////////////////////////
+
+ /** the number of elements in the tree */
+ public final int treeSize() {
+ synchronized(BalancedTree.class) {
+ return root == 0 ? 0 : size[root];
+ }
+ }
+
+ /** clamps index to [0..treeSize()] and inserts object o *before* the specified index */
+ public final void insertNode(int index, Object o) {
+ synchronized(BalancedTree.class) {
+ if(o == null) throw new Error("can't insert nulls in the balanced tree");
+ cached_slot = cached_index = -1;
+ if (index < 0) index = 0;
+ if (index > treeSize()) index = treeSize();
+ int arg = allocateSlot(o);
+ if (root != 0) {
+ insert(index, arg, root, 0, false, false);
+ } else {
+ root = arg;
+ left[arg] = right[arg] = parent[arg] = 0;
+ size[arg] = 1;
+ }
+ }
+ }
+
+ /** clamps index to [0..treeSize()-1] and replaces the object at that index with object o */
+ public final void replaceNode(int index, Object o) {
+ synchronized(BalancedTree.class) {
+ if(o == null) throw new Error("can't insert nulls in the balanced tree");
+ cached_slot = cached_index = -1;
+ if(root == 0) throw new Error("called replaceNode() on an empty tree");
+ if (index < 0) index = 0;
+ if (index >= treeSize()) index = treeSize() - 1;
+ int arg = allocateSlot(o);
+ insert(index, arg, root, 0, true, false);
+ }
+ }
+
+ /** returns the index of o; runs in O((log n)^2) time unless cache hit */
+ public final int indexNode(Object o) {
+ synchronized(BalancedTree.class) {
+ if(o == null) return -1;
+ if (cached_slot != -1 && objects[cached_slot] == o) return cached_index;
+
+ int slot = getSlot(o);
+ if(slot == -1) return -1;
+
+ int index = 0;
+ while(true) {
+ // everything to the left is before us so add that to the index
+ index += sizeof(left[slot]);
+ // we are before anything on the right
+ while(left[parent[slot]] == slot) slot = parent[slot];
+ // we end of the first node who isn't on the left, go to the node that has as its child
+ slot = parent[slot];
+ // if we just processed the root we're done
+ if(slot == 0) break;
+ // count the node we're currently on towards the index
+ index++;
+ }
+ return index;
+ }
+ }
+
+ /** returns the object at index; runs in O(log n) time unless cache hit */
+ public final Object getNode(int index) {
+ synchronized(BalancedTree.class) {
+ if (index == cached_index) return objects[cached_slot];
+
+ if (cached_index != -1) {
+ int distance = Math.abs(index - cached_index);
+ // if the in-order distance between the cached node and the
+ // target node is less than log(n), it's probably faster to
+ // search directly.
+ if ((distance < 16) && ((2 << distance) < treeSize())) {
+ while(cached_index > index) { cached_slot = prev(cached_slot); cached_index--; }
+ while(cached_index < index) { cached_slot = next(cached_slot); cached_index++; }
+ return objects[cached_slot];
+ }
+ }
+ /*
+ cached_index = index;
+ cached_slot = get(index, root);
+ return objects[cached_slot];
+ */
+ return objects[get(index, root)];
+ }
+ }
+
+ /** deletes the object at index, returning the deleted object */
+ public final Object deleteNode(int index) {
+ synchronized(BalancedTree.class) {
+ cached_slot = cached_index = -1;
+ // FIXME: left[], right[], size[], and parent[] aren't getting cleared properly somewhere in here where a node had two children
+ int del = delete(index, root, 0);
+ left[del] = right[del] = size[del] = parent[del] = 0;
+ Object ret = objects[del];
+ objects[del] = null;
+ return ret;
+ }
+ }
+
+ public final void clear() {
+ synchronized(BalancedTree.class) {
+ if(root == 0) return;
+ int i = leftmost(root);
+ do {
+ int next = next(i);
+ objects[i] = null;
+ left[i] = right[i] = size[i] = parent[i] = 0;
+ i = next;
+ } while(i != 0);
+ root = 0;
+ }
+ }
+
+ protected void finalize() { clear(); }
+
+
+ // Node Data /////////////////////////////////////////////////////////////////////////
+
+ private final static int NUM_SLOTS = 64 * 1024;
+ // FEATURE: GROW - private final static int MAX_SLOT_DISTANCE = 32;
+
+ /**
+ * Every object inserted into *any* tree gets a "slot" in this
+ * array. The slot is determined by hashcode modulo the length of
+ * the array, with quadradic probing to resolve collisions. NOTE
+ * that the "slot" of a node is NOT the same as its index.
+ * Furthermore, if an object is inserted into multiple trees, that
+ * object will have multiple slots.
+ */
+ private static Object[] objects = new Object[NUM_SLOTS];
+
+ /// These two arrays hold the left and right children of each
+ /// slot; in other words, left[x] is the *slot* of the left child
+ /// of the node in slot x.
+ ///
+ /// If x has no left child, then left[x] is -1 multiplied by the
+ /// slot of the node that precedes x; if x is the first node, then
+ /// left[x] is 0. The right[] array works the same way.
+ ///
+ private static int[] left = new int[NUM_SLOTS];
+ private static int[] right = new int[NUM_SLOTS];
+
+ /// The parent of this node (0 if it is the root node)
+ private static int[] parent = new int[NUM_SLOTS];
+
+ ///< the number of descendants of this node *including the node itself*
+ private static int[] size = new int[NUM_SLOTS];
+
+
+ // Slot Management //////////////////////////////////////////////////////////////////////
+
+ /** if alloc == false returns the slot holding object o. if alloc is true returns a new slot for obejct o */
+ private int getSlot(Object o, boolean alloc) {
+ // we XOR with our own hashcode so that we don't get tons of
+ // collisions when a single Object is inserted into multiple
+ // trees
+ int dest = Math.abs(o.hashCode() ^ this.hashCode()) % objects.length;
+ Object search = alloc ? null : o;
+ int odest = dest;
+ boolean plus = true;
+ int tries = 1;
+ if(dest == 0) dest=1;
+ while (objects[dest] != search || !(alloc || root(dest) == root)) {
+ dest = Math.abs((odest + (plus ? 1 : -1) * tries * tries) % objects.length);
+ if (dest == 0) dest=1;
+ if (plus) tries++;
+ plus = !plus;
+ // FEATURE: GROW - if(tries > MAX_SLOT_DISTANCE) return -1;
+ }
+ return dest;
+ }
+
+ /** returns the slots holding object o */
+ private int getSlot(Object o) { return getSlot(o,false); }
+
+ /** allocates a new slot holding object o*/
+ private int allocateSlot(Object o) {
+ int slot = getSlot(o, true);
+ // FEATURE: GROW - if(slot == -1) throw new Error("out of slots");
+ objects[slot] = o;
+ return slot;
+ }
+
+
+
+ // Helpers /////////////////////////////////////////////////////////////////////////
+
+ private final int leftmost(int slot) { return left[slot] <= 0 ? slot : leftmost(left[slot]); }
+ private final int rightmost(int slot) { return right[slot] <= 0 ? slot : rightmost(right[slot]); }
+ private final int next(int slot) { return right[slot] <= 0 ? -1 * right[slot] : leftmost(right[slot]); }
+ private final int prev(int slot) { return left[slot] <= 0 ? -1 * left[slot] : rightmost(left[slot]); }
+ private final int sizeof(int slot) { return slot <= 0 ? 0 : size[slot]; }
+ private final int root(int slot) { return parent[slot] == 0 ? slot : root(parent[slot]); }
+
+
+ // Rotation and Balancing /////////////////////////////////////////////////////////////
+
+ // p p
+ // | |
+ // b d
+ // / \ / \
+ // a d < == > b e
+ // / \ / \
+ // c e a c
+ // FIXME might be doing too much work here
+ private void rotate(boolean toTheLeft, int b, int p) {
+ int[] left = toTheLeft ? BalancedTree.left : BalancedTree.right;
+ int[] right = toTheLeft ? BalancedTree.right : BalancedTree.left;
+ int d = right[b];
+ int c = left[d];
+ if (d <= 0) throw new Error("rotation error");
+ left[d] = b;
+ right[b] = c <= 0 ? -d : c;
+
+ parent[b] = d;
+ parent[d] = p;
+ if(c > 0) parent[c] = b;
+ if (p == 0) root = d;
+ else if (left[p] == b) left[p] = d;
+ else if (right[p] == b) right[p] = d;
+ else throw new Error("rotate called with invalid parent");
+ size[b] = 1 + sizeof(left[b]) + sizeof(right[b]);
+ size[d] = 1 + sizeof(left[d]) + sizeof(right[d]);
+ }
+
+ private void balance(int slot, int p) {
+ if (slot <= 0) return;
+ size[slot] = 1 + sizeof(left[slot]) + sizeof(right[slot]);
+ if (sizeof(left[slot]) - 1 > 2 * sizeof(right[slot])) rotate(false, slot, p);
+ else if (sizeof(left[slot]) * 2 < sizeof(right[slot]) - 1) rotate(true, slot, p);
+ }
+
+
+
+ // Insert /////////////////////////////////////////////////////////////////////////
+
+ private void insert(int index, int arg, int slot, int p, boolean replace, boolean wentLeft) {
+ int diff = slot <= 0 ? 0 : index - sizeof(left[slot]);
+ if (slot > 0 && diff != 0) {
+ if (diff < 0) insert(index, arg, left[slot], slot, replace, true);
+ else insert(index - sizeof(left[slot]) - 1, arg, right[slot], slot, replace, false);
+ balance(slot, p);
+ return;
+ }
+
+ if (size[arg] != 0) throw new Error("double insertion");
+
+ // we are replacing an existing node
+ if (replace) {
+ if (diff != 0) throw new Error("this should never happen"); // since we already clamped the index
+ if (p == 0) root = arg;
+ else if (left[p] == slot) left[p] = arg;
+ else if (right[p] == slot) right[p] = arg;
+ left[arg] = left[slot];
+ right[arg] = right[slot];
+ size[arg] = size[slot];
+ parent[arg] = parent[slot];
+ if(left[slot] > 0) parent[left[slot]] = arg;
+ if(right[slot] > 0) parent[right[slot]] = arg;
+ objects[slot] = null;
+ left[slot] = right[slot] = size[slot] = parent[slot] = 0;
+
+ // we become the child of a former leaf
+ } else if (slot <= 0) {
+ int[] left = wentLeft ? BalancedTree.left : BalancedTree.right;
+ int[] right = wentLeft ? BalancedTree.right : BalancedTree.left;
+ left[arg] = slot;
+ left[p] = arg;
+ right[arg] = -1 * p;
+ parent[arg] = p;
+ balance(arg, p);
+
+ // we take the place of a preexisting node
+ } else {
+ left[arg] = left[slot]; // steal slot's left subtree
+ left[slot] = -1 * arg;
+ right[arg] = slot; // make slot our right subtree
+ parent[arg] = parent[slot];
+ parent[slot] = arg;
+ if (slot == root) {
+ root = arg;
+ balance(slot, arg);
+ balance(arg, 0);
+ } else {
+ if (left[p] == slot) left[p] = arg;
+ else if (right[p] == slot) right[p] = arg;
+ else throw new Error("should never happen");
+ balance(slot, arg);
+ balance(arg, p);
+ }
+ }
+ }
+
+
+ // Retrieval //////////////////////////////////////////////////////////////////////
+
+ private int get(int index, int slot) {
+ int diff = index - sizeof(left[slot]);
+ if (diff > 0) return get(diff - 1, right[slot]);
+ else if (diff < 0) return get(index, left[slot]);
+ else return slot;
+ }
+
+
+ // Deletion //////////////////////////////////////////////////////////////////////
+
+ private int delete(int index, int slot, int p) {
+ int diff = index - sizeof(left[slot]);
+ if (diff < 0) {
+ int ret = delete(index, left[slot], slot);
+ balance(slot, p);
+ return ret;
+
+ } else if (diff > 0) {
+ int ret = delete(diff - 1, right[slot], slot);
+ balance(slot, p);
+ return ret;
+
+ // we found the node to delete
+ } else {
+
+ // fast path: it has no children
+ if (left[slot] <= 0 && right[slot] <= 0) {
+ if (p == 0) root = 0;
+ else {
+ int[] side = left[p] == slot ? left : right;
+ side[p] = side[slot]; // fix parent's pointer
+ }
+
+ // fast path: it has no left child, so we replace it with its right child
+ } else if (left[slot] <= 0) {
+ if (p == 0) root = right[slot];
+ else (left[p] == slot ? left : right)[p] = right[slot]; // fix parent's pointer
+ parent[right[slot]] = p;
+ left[leftmost(right[slot])] = left[slot]; // fix our successor-leaf's fake right ptr
+ balance(right[slot], p);
+
+ // fast path; it has no right child, so we replace it with its left child
+ } else if (right[slot] <= 0) {
+ if (p == 0) root = left[slot];
+ else (left[p] == slot ? left : right)[p] = left[slot]; // fix parent's pointer
+ parent[left[slot]] = p;
+ right[rightmost(left[slot])] = right[slot]; // fix our successor-leaf's fake right ptr
+ balance(left[slot], p);
+
+ // node to be deleted has two children, so we replace it with its left child's rightmost descendant
+ } else {
+ int left_childs_rightmost = delete(sizeof(left[slot]) - 1, left[slot], slot);
+ left[left_childs_rightmost] = left[slot];
+ right[left_childs_rightmost] = right[slot];
+ if(left[slot] > 0) parent[left[slot]] = left_childs_rightmost;
+ if(right[slot] > 0) parent[right[slot]] = left_childs_rightmost;
+ parent[left_childs_rightmost] = parent[slot];
+ if (p == 0) root = left_childs_rightmost;
+ else (left[p] == slot ? left : right)[p] = left_childs_rightmost; // fix parent's pointer
+ balance(left_childs_rightmost, p);
+ }
+
+ return slot;
+ }
+ }
+
+ // Debugging ///////////////////////////////////////////////////////////////////////////
+
+ public void printTree() {
+ if(root == 0) System.err.println("Tree is empty");
+ else printTree(root,0,false);
+ }
+ private void printTree(int node,int indent,boolean l) {
+ for(int i=0;i<indent;i++) System.err.print(" ");
+ if(node < 0) System.err.println((l?"Prev: " : "Next: ") + -node);
+ else if(node == 0) System.err.println(l ? "Start" : "End");
+ else {
+ System.err.print("" + node + ": " + objects[node]);
+ System.err.println(" Parent: " + parent[node]);
+ printTree(left[node],indent+1,true);
+ printTree(right[node],indent+1,false);
+ }
+ }
+}
--- /dev/null
+// Copyright (C) 2003 Adam Megacz <adam@ibex.org> all rights reserved.
+//
+// You may modify, copy, and redistribute this code under the terms of
+// the GNU Library Public License version 2.1, with the exception of
+// the portion of clause 6a after the semicolon (aka the "obnoxious
+// relink clause")
+
+package org.ibex.util;
+
+import java.io.*;
+import java.util.*;
+import java.util.zip.*;
+
+/** Reads a CAB file structure */
+public class CAB {
+
+ /** reads a CAB file, parses it, and returns an InputStream representing the named file */
+ public static InputStream getFileInputStream(InputStream is, String fileName) throws IOException, EOFException {
+ return getFileInputStream(is, 0, fileName);
+ }
+
+ public static InputStream getFileInputStream(InputStream is, int skipHeaders, String fileName) throws IOException, EOFException {
+ DataInputStream dis = new DataInputStream(is);
+ CFHEADER h = new CFHEADER();
+
+ while (skipHeaders > 0) { CFHEADER.seekMSCF(dis); skipHeaders--; }
+
+ try {
+ h.read(dis);
+ } catch (CFHEADER.BogusHeaderException bhe) {
+ throw new EOFException();
+ }
+
+ for(int i=0; i<h.folders.length; i++) {
+ CFFOLDER f = new CFFOLDER(h);
+ try {
+ f.read(dis);
+ } catch (CFFOLDER.UnsupportedCompressionTypeException ucte) {
+ throw ucte;
+ }
+ }
+
+ for(int i=0; i<h.files.length; i++) {
+ CFFILE f = new CFFILE(h);
+ f.read(dis);
+ }
+
+ for(int i=0; i<h.folders.length; i++) {
+ InputStream is2 = new CFFOLDERInputStream(h.folders[i], dis);
+ for(int j=0; j<h.folders[i].files.size(); j++) {
+ CFFILE file = (CFFILE)h.folders[i].files.elementAt(j);
+ if (file.fileName.equals(fileName)) return new LimitStream(is2, file.fileSize);
+ byte[] b = new byte[file.fileSize];
+ }
+ }
+
+ return null;
+ }
+
+ private static class LimitStream extends FilterInputStream {
+ int limit;
+ public LimitStream(InputStream is, int limit) {
+ super(is);
+ this.limit = limit;
+ }
+ public int read() throws IOException {
+ if (limit == 0) return -1;
+ int ret = super.read();
+ if (ret != -1) limit--;
+ return ret;
+ }
+ public int read(byte[] b, int off, int len) throws IOException {
+ if (len > limit) len = limit;
+ if (limit == 0) return -1;
+ int ret = super.read(b, off, len);
+ limit -= ret;
+ return ret;
+ }
+ }
+
+ /** Encapsulates a CFHEADER entry */
+ public static class CFHEADER {
+ byte[] reserved1 = new byte[4]; // reserved
+ int fileSize = 0; // size of this cabinet file in bytes
+ byte[] reserved2 = new byte[4]; // reserved
+ int offsetOfFirstCFFILEEntry; // offset of the first CFFILE entry
+ byte[] reserved3 = new byte[4]; // reserved
+ byte versionMinor = 3; // cabinet file format version, minor
+ byte versionMajor = 1; // cabinet file format version, major
+ boolean prevCAB = false; // true iff there is a cabinet before this one in a sequence
+ boolean nextCAB = false; // true iff there is a cabinet after this one in a sequence
+ boolean hasReserved = false; // true iff the cab has per-{cabinet, folder, block} reserved areas
+ int setID = 0; // must be the same for all cabinets in a set
+ int indexInCabinetSet = 0; // number of this cabinet file in a set
+ byte perCFFOLDERReservedSize = 0; // (optional) size of per-folder reserved area
+ byte perDatablockReservedSize = 0; // (optional) size of per-datablock reserved area
+ byte[] perCabinetReservedArea = null; // per-cabinet reserved area
+ String previousCabinet = null; // name of previous cabinet file in a set
+ String previousDisk = null; // name of previous disk in a set
+ String nextCabinet = null; // name of next cabinet in a set
+ String nextDisk = null; // name of next disk in a set
+
+ CFFOLDER[] folders = new CFFOLDER[0];
+ CFFILE[] files = new CFFILE[0];
+
+ int readCFFOLDERs = 0; // the number of folders read in so far
+ int readCFFILEs = 0; // the number of folders read in so far
+
+ public void print(PrintStream ps) {
+ ps.println("CAB CFFILE CFHEADER v" + ((int)versionMajor) + "." + ((int)versionMinor));
+ ps.println(" total file size = " + fileSize);
+ ps.println(" offset of first file = " + offsetOfFirstCFFILEEntry);
+ ps.println(" total folders = " + folders.length);
+ ps.println(" total files = " + files.length);
+ ps.println(" flags = 0x" +
+ Integer.toString((prevCAB ? 0x1 : 0x0) |
+ (nextCAB ? 0x2 : 0x0) |
+ (hasReserved ? 0x4 : 0x0), 16) + " [ " +
+ (prevCAB ? "prev " : "") +
+ (nextCAB ? "next " : "") +
+ (hasReserved ? "reserve_present " : "") + "]");
+ ps.println(" set id = " + setID);
+ ps.println(" index in set = " + indexInCabinetSet);
+ ps.println(" header reserved area #1 =" +
+ " 0x" + Integer.toString(reserved1[0], 16) +
+ " 0x" + Integer.toString(reserved1[1], 16) +
+ " 0x" + Integer.toString(reserved1[2], 16) +
+ " 0x" + Integer.toString(reserved1[3], 16));
+ ps.println(" header reserved area #2 =" +
+ " 0x" + Integer.toString(reserved2[0], 16) +
+ " 0x" + Integer.toString(reserved2[1], 16) +
+ " 0x" + Integer.toString(reserved2[2], 16) +
+ " 0x" + Integer.toString(reserved2[3], 16));
+ ps.println(" header reserved area #3 =" +
+ " 0x" + Integer.toString(reserved3[0], 16) +
+ " 0x" + Integer.toString(reserved3[1], 16) +
+ " 0x" + Integer.toString(reserved3[2], 16) +
+ " 0x" + Integer.toString(reserved3[3], 16));
+ if (hasReserved) {
+ if (perCabinetReservedArea != null) {
+ ps.print(" per-cabinet reserved area = ");
+ for(int i=0; i<perCabinetReservedArea.length; i++)
+ ps.print(((perCabinetReservedArea[i] & 0xff) < 16 ? "0" : "") +
+ Integer.toString(perCabinetReservedArea[i] & 0xff, 16) + " ");
+ ps.println();
+ }
+ ps.println(" per folder reserved area = " + perCFFOLDERReservedSize + " bytes");
+ ps.println(" per block reserved area = " + perDatablockReservedSize + " bytes");
+ }
+ }
+
+ public String toString() {
+ return
+ "[ CAB CFFILE CFHEADER v" +
+ ((int)versionMajor) + "." + ((int)versionMinor) + ", " +
+ fileSize + " bytes, " +
+ folders.length + " folders, " +
+ files.length + " files] ";
+ }
+
+ /** fills in all fields in the header and positions the stream at the first folder */
+ public void read(DataInputStream dis) throws IOException, BogusHeaderException {
+ seekMSCF(dis);
+ dis.readFully(reserved1);
+
+ byte[] headerHashable = new byte[28];
+ dis.readFully(headerHashable);
+ DataInputStream hhis = new DataInputStream(new ByteArrayInputStream(headerHashable));
+
+ fileSize = readLittleInt(hhis);
+ hhis.readFully(reserved2);
+ offsetOfFirstCFFILEEntry = readLittleInt(hhis);
+ hhis.readFully(reserved3);
+ versionMinor = hhis.readByte();
+ versionMajor = hhis.readByte();
+ folders = new CFFOLDER[readLittleShort(hhis)];
+ files = new CFFILE[readLittleShort(hhis)];
+ int flags = readLittleShort(hhis);
+ prevCAB = (flags & 0x0001) != 0;
+ nextCAB = (flags & 0x0002) != 0;
+ hasReserved = (flags & 0x0004) != 0;
+ setID = readLittleShort(hhis);
+ indexInCabinetSet = readLittleShort(hhis);
+
+ if (offsetOfFirstCFFILEEntry < 0 || fileSize < 0) {
+ throw new BogusHeaderException();
+ }
+
+ if (hasReserved) {
+ perCabinetReservedArea = new byte[readLittleShort(dis)];
+ perCFFOLDERReservedSize = dis.readByte();
+ perDatablockReservedSize = dis.readByte();
+ if (perCabinetReservedArea.length > 0)
+ dis.readFully(perCabinetReservedArea);
+ }
+
+ try {
+ if (prevCAB) {
+ previousCabinet = readZeroTerminatedString(dis);
+ previousDisk = readZeroTerminatedString(dis);
+ }
+ if (nextCAB) {
+ nextCabinet = readZeroTerminatedString(dis);
+ nextDisk = readZeroTerminatedString(dis);
+ }
+ } catch (ArrayIndexOutOfBoundsException e) {
+ throw new BogusHeaderException();
+ }
+ }
+
+ public static void seekMSCF(DataInputStream dis) throws EOFException, IOException
+ {
+ int state;
+ // skip up to and including the 'MSCF' signature
+ state = 0;
+ while (state != 4) {
+ // M
+ while (state == 0 && dis.readByte() != 0x4D) { }
+ state = 1;
+ // S
+ switch (dis.readByte()) {
+ case 0x53 : state = 2; break;
+ case 0x4D : state = 1; continue;
+ default : state = 0; continue;
+ }
+ // C
+ if (dis.readByte() == 0x43) { state = 3; }
+ else { state = 0; continue; }
+ // F
+ if (dis.readByte() == 0x46) { state = 4; }
+ else { state = 0; }
+ }
+ }
+
+ public static class BogusHeaderException extends IOException {}
+ }
+
+ /** Encapsulates a CFFOLDER entry */
+ public static class CFFOLDER {
+ public static final int COMPRESSION_NONE = 0;
+ public static final int COMPRESSION_MSZIP = 1;
+ public static final int COMPRESSION_QUANTUM = 2;
+ public static final int COMPRESSION_LZX = 3;
+
+ int firstBlockOffset = 0; // offset of first data block within this folder
+ int numBlocks = 0; // number of data blocks
+ int compressionType = 0; // compression type for this folder
+ byte[] reservedArea = null; // per-folder reserved area
+ int indexInCFHEADER = 0; // our index in CFHEADER.folders
+ Vector files = new Vector();
+
+ private CFHEADER header = null;
+
+ public CFFOLDER(CFHEADER header) { this.header = header; }
+
+ public String toString() {
+ return "[ CAB CFFOLDER, " + numBlocks + " data blocks, compression type " +
+ compressionName(compressionType) +
+ ", " + reservedArea.length + " bytes of reserved data ]";
+ }
+
+ public void read(DataInputStream dis) throws IOException, UnsupportedCompressionTypeException {
+ firstBlockOffset = readLittleInt(dis);
+ numBlocks = readLittleShort(dis);
+ compressionType = readLittleShort(dis) & 0x000F;
+ if (compressionType != COMPRESSION_MSZIP) {
+ throw new UnsupportedCompressionTypeException(compressionType);
+ }
+ reservedArea = new byte[header.perCFFOLDERReservedSize];
+ if (reservedArea.length > 0) dis.readFully(reservedArea);
+ indexInCFHEADER = header.readCFFOLDERs++;
+ header.folders[indexInCFHEADER] = this;
+ }
+
+ public static String compressionName(int type) {
+ switch (type) {
+ case COMPRESSION_NONE:
+ return "NONE";
+ case COMPRESSION_MSZIP:
+ return "MSZIP";
+ case COMPRESSION_QUANTUM:
+ return "QUANTUM";
+ case COMPRESSION_LZX:
+ return "LZX";
+ default:
+ return "<Unknown type " + type + ">";
+ }
+ }
+
+ public static class UnsupportedCompressionTypeException extends IOException {
+ private int compressionType;
+
+ UnsupportedCompressionTypeException(int type) {
+ compressionType = type;
+ }
+ public String toString() {
+ return "UnsupportedCompressionTypeException: no support for compression type " + compressionName(compressionType);
+ }
+ }
+ }
+
+ /** Encapsulates a CFFILE entry */
+ public static class CFFILE {
+ int fileSize = 0; // size of this file
+ int uncompressedOffsetInCFFOLDER = 0; // offset of this file within the folder, not accounting for compression
+ int folderIndex = 0; // index of the CFFOLDER we belong to
+ Date date = null; // modification date
+ int attrs = 0; // attrs
+ boolean readOnly = false; // read-only flag
+ boolean hidden = false; // hidden flag
+ boolean system = false; // system flag
+ boolean arch = false; // archive flag
+ boolean runAfterExec = false; // true if file should be run during extraction
+ boolean UTFfileName = false; // true if filename is UTF-encoded
+ String fileName = null; // filename
+ int indexInCFHEADER = 0; // our index in CFHEADER.files
+ CFFOLDER folder = null; // the folder we belong to
+ private CFHEADER header = null;
+ File myFile;
+
+ public CFFILE(CFHEADER header) { this.header = header; }
+
+ public CFFILE(File f, String pathName) throws IOException {
+ fileSize = (int)f.length();
+ folderIndex = 0;
+ date = new java.util.Date(f.lastModified());
+ fileName = pathName;
+ myFile = f;
+ }
+
+ public String toString() {
+ return "[ CAB CFFILE: " + fileName + ", " + fileSize + " bytes [ " +
+ (readOnly ? "readonly " : "") +
+ (system ? "system " : "") +
+ (hidden ? "hidden " : "") +
+ (arch ? "arch " : "") +
+ (runAfterExec ? "run_after_exec " : "") +
+ (UTFfileName ? "UTF_filename " : "") +
+ "]";
+ }
+
+ public void read(DataInputStream dis) throws IOException {
+ fileSize = readLittleInt(dis);
+ uncompressedOffsetInCFFOLDER = readLittleInt(dis);
+ folderIndex = readLittleShort(dis);
+ readLittleShort(dis); // date
+ readLittleShort(dis); // time
+ attrs = readLittleShort(dis);
+ readOnly = (attrs & 0x1) != 0;
+ hidden = (attrs & 0x2) != 0;
+ system = (attrs & 0x4) != 0;
+ arch = (attrs & 0x20) != 0;
+ runAfterExec = (attrs & 0x40) != 0;
+ UTFfileName = (attrs & 0x80) != 0;
+ fileName = readZeroTerminatedString(dis);
+
+ indexInCFHEADER = header.readCFFILEs++;
+ header.files[indexInCFHEADER] = this;
+ folder = header.folders[folderIndex];
+ folder.files.addElement(this);
+ }
+ }
+
+
+
+
+ // Compressing Input and Output Streams ///////////////////////////////////////////////
+
+ /** an InputStream that decodes CFDATA blocks belonging to a CFFOLDER */
+ private static class CFFOLDERInputStream extends InputStream {
+ CFFOLDER folder;
+ DataInputStream dis;
+ InputStream iis = null;
+
+ byte[] compressed = new byte[128 * 1024];
+ byte[] uncompressed = new byte[256 * 1024];
+
+ public CFFOLDERInputStream(CFFOLDER f, DataInputStream dis) {
+ this.folder = f;
+ this.dis = dis;
+ }
+
+ InputStream readBlock() throws IOException {
+ int compressedBytes = readLittleShort(dis);
+ int unCompressedBytes = readLittleShort(dis);
+ byte[] reserved = new byte[/*folder.header.perDatablockReservedSize*/0];
+ if (reserved.length > 0) dis.readFully(reserved);
+ if (dis.readByte() != 0x43) throw new CABException("malformed block header");
+ if (dis.readByte() != 0x4B) throw new CABException("malformed block header");
+
+ dis.readFully(compressed, 0, compressedBytes - 2);
+
+ Inflater i = new Inflater(true);
+ i.setInput(compressed, 0, compressedBytes - 2);
+
+ if (unCompressedBytes > uncompressed.length) uncompressed = new byte[unCompressedBytes];
+ try { i.inflate(uncompressed, 0, uncompressed.length);
+ } catch (DataFormatException dfe) {
+ dfe.printStackTrace();
+ throw new CABException(dfe.toString());
+ }
+ return new ByteArrayInputStream(uncompressed, 0, unCompressedBytes);
+ }
+
+ public int available() throws IOException { return iis == null ? 0 : iis.available(); }
+ public void close() throws IOException { iis.close(); }
+ public void mark(int i) { }
+ public boolean markSupported() { return false; }
+ public void reset() { }
+
+ public long skip(long l) throws IOException {
+ if (iis == null) iis = readBlock();
+ int ret = 0;
+ while (l > ret) {
+ long numread = iis.skip(l - ret);
+ if (numread == 0 || numread == -1) iis = readBlock();
+ else ret += numread;
+ }
+ return ret;
+ }
+
+ public int read(byte[] b, int off, int len) throws IOException {
+ if (iis == null) iis = readBlock();
+ int ret = 0;
+ while (len > ret) {
+ int numread = iis.read(b, off + ret, len - ret);
+ if (numread == 0 || numread == -1) iis = readBlock();
+ else ret += numread;
+ }
+ return ret;
+ }
+
+ public int read() throws IOException {
+ if (iis == null) iis = readBlock();
+ int ret = iis.read();
+ if (ret == -1) {
+ iis = readBlock();
+ ret = iis.read();
+ }
+ return ret;
+ }
+ }
+
+
+
+ // Misc Stuff //////////////////////////////////////////////////////////////
+
+ public static String readZeroTerminatedString(DataInputStream dis) throws IOException {
+ int numBytes = 0;
+ byte[] b = new byte[256];
+ while(true) {
+ byte next = dis.readByte();
+ if (next == 0x0) return new String(b, 0, numBytes);
+ b[numBytes++] = next;
+ }
+ }
+
+ public static int readLittleInt(DataInputStream dis) throws IOException {
+ int lowest = (int)(dis.readByte() & 0xff);
+ int low = (int)(dis.readByte() & 0xff);
+ int high = (int)(dis.readByte() & 0xff);
+ int highest = (int)(dis.readByte() & 0xff);
+ return (highest << 24) | (high << 16) | (low << 8) | lowest;
+ }
+
+ public static int readLittleShort(DataInputStream dis) throws IOException {
+ int low = (int)(dis.readByte() & 0xff);
+ int high = (int)(dis.readByte() & 0xff);
+ return (high << 8) | low;
+ }
+
+ public static class CABException extends IOException {
+ public CABException(String s) { super(s); }
+ }
+
+
+ /** scratch space for isToByteArray() */
+ static byte[] workspace = new byte[16 * 1024];
+
+ /** Trivial method to completely read an InputStream */
+ public static synchronized byte[] isToByteArray(InputStream is) throws IOException {
+ int pos = 0;
+ while (true) {
+ int numread = is.read(workspace, pos, workspace.length - pos);
+ if (numread == -1) break;
+ else if (pos + numread < workspace.length) pos += numread;
+ else {
+ pos += numread;
+ byte[] temp = new byte[workspace.length * 2];
+ System.arraycopy(workspace, 0, temp, 0, workspace.length);
+ workspace = temp;
+ }
+ }
+ byte[] ret = new byte[pos];
+ System.arraycopy(workspace, 0, ret, 0, pos);
+ return ret;
+ }
+
+
+}
+
--- /dev/null
+// Copyright (C) 2003 Adam Megacz <adam@ibex.org> all rights reserved.
+//
+// You may modify, copy, and redistribute this code under the terms of
+// the GNU Library Public License version 2.1, with the exception of
+// the portion of clause 6a after the semicolon (aka the "obnoxious
+// relink clause")
+
+/*
+
+Bug report from a user:
+
+I looked at your Cache.java and tried to make good use of it, but I was
+out of luck - it wouldn't run here. Digging deeper into the code, I came
+across something that might be considered a bug. But maybe it's just a
+feature :-)
+
+
+Starting with an empty cache, Cache.put() immediately followed by
+Cache.get() on same keys / same object will set Node lru back to null in
+Node.remove() which is called in get().
+
+Assuming this put()-get() sequence is fixed, it will fill the cache, but
+lru will remain null.
+
+When cache is filled 100%, we have, at the end of the get(), where
+size>maxSize is checked, a state that mru == lru == n (from
+if(lru==null) thus deleteting the newly inserted object. Oops.
+
+
+Hope I made this clear enough. Maybe it's not a problem in xwt due to a
+different usage scheme of the cache.
+
+
+
+*/
+
+package org.ibex.util;
+
+// FIXME needs to be a weak hash
+
+/**
+ * A Hash table with a fixed size; drops extraneous elements. Uses
+ * LRU strategy.
+ */
+public class Cache extends Hash {
+
+ /** head of list is the mru; tail is the lru */
+ Node mru = null;
+ Node lru = null;
+
+ private int maxSize;
+ private Cache() { }
+ public Cache(int maxSize) {
+ super(maxSize * 2, 3);
+ this.maxSize = maxSize;
+ }
+
+ /** A doubly-linked list */
+ private class Node {
+ final Object val;
+ final Object k1;
+ final Object k2;
+ public Node(Object k1, Object k2, Object val) { this.k1 = k1; this.k2 = k2; this.val = val; }
+ Node next = null;
+ Node prev = null;
+ void remove() {
+ if (this == lru) lru = prev;
+ if (this == mru) mru = next;
+ if (next != null) next.prev = prev;
+ if (prev != null) prev.next = next;
+ next = prev = null;
+ }
+ void placeAfter(Node n) {
+ remove();
+ if (n == null) return;
+ next = n.next;
+ if (n.next != null) n.next.prev = this;
+ n.next = this;
+ prev = n;
+ }
+ void placeBefore(Node n) {
+ remove();
+ if (n == null) return;
+ next = n;
+ prev = n.prev;
+ n.prev = this;
+ if (prev != null) prev.next = this;
+ }
+ }
+
+ public void clear() {
+ lru = null;
+ super.clear();
+ }
+
+ public void remove(Object k1, Object k2) {
+ Object o = super.get(k1, k2);
+ if (o != null) ((Node)o).remove();
+ super.remove(k1, k2);
+ }
+
+ public Object get(Object k1, Object k2) {
+ Node n = (Node)super.get(k1, k2);
+ if (n == null) return null;
+ n.remove();
+ n.placeBefore(mru);
+ mru = n;
+ return n.val;
+ }
+
+ public void put(Object k1, Object k2, Object v) {
+ Node n = new Node(k1, k2, v);
+ if (lru == null) {
+ lru = mru = n;
+ } else {
+ n.placeBefore(mru);
+ mru = n;
+ }
+ if (super.get(k1, k2) != null) remove(k1, k2);
+ super.put(k1, k2, n);
+ if (size > maxSize) remove(lru.k1, lru.k2);
+ }
+
+}
+
+
--- /dev/null
+// Copyright (C) 2003 Adam Megacz <adam@ibex.org> all rights reserved.
+//
+// You may modify, copy, and redistribute this code under the terms of
+// the GNU Library Public License version 2.1, with the exception of
+// the portion of clause 6a after the semicolon (aka the "obnoxious
+// relink clause")
+
+package org.ibex.util;
+import java.io.*;
+
+// FEATURE: don't use a byte[] if we have a diskCache file
+/**
+ * Wraps around an InputStream, caching the stream in a byte[] as it
+ * is read and permitting multiple simultaneous readers
+ */
+public class CachedInputStream {
+
+ boolean filling = false; ///< true iff some thread is blocked on us waiting for input
+ boolean eof = false; ///< true iff end of stream has been reached
+ byte[] cache = new byte[1024 * 128];
+ int size = 0;
+ final InputStream is;
+ File diskCache;
+
+ public CachedInputStream(InputStream is) { this(is, null); }
+ public CachedInputStream(InputStream is, File diskCache) {
+ this.is = is;
+ this.diskCache = diskCache;
+ }
+ public InputStream getInputStream() throws IOException {
+ if (diskCache != null && diskCache.exists()) return new FileInputStream(diskCache);
+ return new SubStream();
+ }
+
+ public void grow(int newLength) {
+ if (newLength < cache.length) return;
+ byte[] newCache = new byte[cache.length + 2 * (newLength - cache.length)];
+ System.arraycopy(cache, 0, newCache, 0, size);
+ cache = newCache;
+ }
+
+ synchronized void fillCache(int howMuch) throws IOException {
+ if (filling) { try { wait(); } catch (InterruptedException e) { }; return; }
+ filling = true;
+ grow(size + howMuch);
+ int ret = is.read(cache, size, howMuch);
+ if (ret == -1) {
+ eof = true;
+ // FIXME: probably a race here
+ if (diskCache != null && !diskCache.exists())
+ try {
+ File cacheFile = new File(diskCache + ".incomplete");
+ FileOutputStream cacheFileStream = new FileOutputStream(cacheFile);
+ cacheFileStream.write(cache, 0, size);
+ cacheFileStream.close();
+ cacheFile.renameTo(diskCache);
+ } catch (IOException e) {
+ Log.info(this, "exception thrown while writing disk cache");
+ Log.info(this, e);
+ }
+ }
+ else size += ret;
+ filling = false;
+ notifyAll();
+ }
+
+ private class SubStream extends InputStream implements KnownLength {
+ int pos = 0;
+ public int available() { return Math.max(0, size - pos); }
+ public long skip(long n) throws IOException { pos += (int)n; return n; } // FEATURE: don't skip past EOF
+ public int getLength() { return eof ? size : is instanceof KnownLength ? ((KnownLength)is).getLength() : 0; }
+ public int read() throws IOException { // FEATURE: be smarter here
+ byte[] b = new byte[1];
+ int ret = read(b, 0, 1);
+ return ret == -1 ? -1 : b[0]&0xff;
+ }
+ public int read(byte[] b, int off, int len) throws IOException {
+ synchronized(CachedInputStream.this) {
+ while (pos >= size && !eof) fillCache(pos + len - size);
+ if (eof && pos == size) return -1;
+ int count = Math.min(size - pos, len);
+ System.arraycopy(cache, pos, b, off, count);
+ pos += count;
+ return count;
+ }
+ }
+ }
+}
--- /dev/null
+// Copyright (C) 2003 Adam Megacz <adam@ibex.org> all rights reserved.
+//
+// You may modify, copy, and redistribute this code under the terms of
+// the GNU Library Public License version 2.1, with the exception of
+// the portion of clause 6a after the semicolon (aka the "obnoxious
+// relink clause")
+
+package org.ibex.util;
+
+/** a simple interface for callbacks*/
+public interface Callback {
+
+ public abstract Object call(Object arg);
+
+}
--- /dev/null
+// Copyright (C) 2004 Adam Megacz <adam@ibex.org> all rights reserved.
+//
+// You may modify, copy, and redistribute this code under the terms of
+// the GNU Library Public License version 2.1, with the exception of
+// the portion of clause 6a after the semicolon (aka the "obnoxious
+// relink clause")
+package org.ibex.util;
+import java.util.*;
+
+public class CounterEnumeration implements Enumeration {
+ public final int max;
+ private int cur = 0;
+ public CounterEnumeration(int i) { max = i; }
+ public void reset() { cur = 0; }
+ public boolean hasMoreElements() { return cur < max; }
+ public Object nextElement() { return new Integer(cur++); }
+}
--- /dev/null
+// Copyright (C) 2003 Adam Megacz <adam@ibex.org> all rights reserved.
+//
+// You may modify, copy, and redistribute this code under the terms of
+// the GNU Library Public License version 2.1, with the exception of
+// the portion of clause 6a after the semicolon (aka the "obnoxious
+// relink clause")
+
+package org.ibex.util;
+
+/**
+ * A general-purpose data structure for holding a list of rectangular
+ * regions that need to be repainted, with intelligent coalescing.
+ *
+ * DirtyList will unify two regions A and B if the smallest rectangle
+ * enclosing both A and B occupies no more than epsilon + Area_A +
+ * Area_B. Failing this, if two corners of A fall within B, A will be
+ * shrunk to exclude the union of A and B.
+ */
+public class DirtyList {
+
+ /** The dirty regions (each one is an int[4]). */
+ private int[][] dirties = new int[10][];
+
+ /** The number of dirty regions */
+ private int numdirties = 0;
+
+ /** See class comment */
+ private static final int epsilon = 50 * 50;
+
+ public int num() { return numdirties; }
+
+ /** grows the array */
+ private void grow() {
+ int[][] newdirties = new int[dirties.length * 2][];
+ System.arraycopy(dirties, 0, newdirties, 0, numdirties);
+ dirties = newdirties;
+ }
+
+ /** Add a new rectangle to the dirty list; returns false if the
+ * region fell completely within an existing rectangle or set of
+ * rectangles (ie did not expand the dirty area)
+ */
+ public synchronized boolean dirty(int x, int y, int w, int h) {
+ if (numdirties == dirties.length) grow();
+
+ // we attempt the "lossless" combinations first
+ for(int i=0; i<numdirties; i++) {
+ int[] cur = dirties[i];
+
+ // new region falls completely within existing region
+ if (x >= cur[0] && y >= cur[1] && x + w <= cur[0] + cur[2] && y + h <= cur[1] + cur[3]) {
+ return false;
+
+ // existing region falls completely within new region
+ } else if (x <= cur[0] && y <= cur[1] && x + w >= cur[0] + cur[2] && y + h >= cur[1] + cur[3]) {
+ dirties[i][2] = 0;
+ dirties[i][3] = 0;
+
+ // left end of new region falls within existing region
+ } else if (x >= cur[0] && x < cur[0] + cur[2] && y >= cur[1] && y + h <= cur[1] + cur[3]) {
+ w = x + w - (cur[0] + cur[2]);
+ x = cur[0] + cur[2];
+ i = -1; continue;
+
+ // right end of new region falls within existing region
+ } else if (x + w > cur[0] && x + w <= cur[0] + cur[2] && y >= cur[1] && y + h <= cur[1] + cur[3]) {
+ w = cur[0] - x;
+ i = -1; continue;
+
+ // top end of new region falls within existing region
+ } else if (x >= cur[0] && x + w <= cur[0] + cur[2] && y >= cur[1] && y < cur[1] + cur[3]) {
+ h = y + h - (cur[1] + cur[3]);
+ y = cur[1] + cur[3];
+ i = -1; continue;
+
+ // bottom end of new region falls within existing region
+ } else if (x >= cur[0] && x + w <= cur[0] + cur[2] && y + h > cur[1] && y + h <= cur[1] + cur[3]) {
+ h = cur[1] - y;
+ i = -1; continue;
+
+ // left end of existing region falls within new region
+ } else if (dirties[i][0] >= x && dirties[i][0] < x + w && dirties[i][1] >= y && dirties[i][1] + dirties[i][3] <= y + h) {
+ dirties[i][2] = dirties[i][2] - (x + w - dirties[i][0]);
+ dirties[i][0] = x + w;
+ i = -1; continue;
+
+ // right end of existing region falls within new region
+ } else if (dirties[i][0] + dirties[i][2] > x && dirties[i][0] + dirties[i][2] <= x + w &&
+ dirties[i][1] >= y && dirties[i][1] + dirties[i][3] <= y + h) {
+ dirties[i][2] = x - dirties[i][0];
+ i = -1; continue;
+
+ // top end of existing region falls within new region
+ } else if (dirties[i][0] >= x && dirties[i][0] + dirties[i][2] <= x + w && dirties[i][1] >= y && dirties[i][1] < y + h) {
+ dirties[i][3] = dirties[i][3] - (y + h - dirties[i][1]);
+ dirties[i][1] = y + h;
+ i = -1; continue;
+
+ // bottom end of existing region falls within new region
+ } else if (dirties[i][0] >= x && dirties[i][0] + dirties[i][2] <= x + w &&
+ dirties[i][1] + dirties[i][3] > y && dirties[i][1] + dirties[i][3] <= y + h) {
+ dirties[i][3] = y - dirties[i][1];
+ i = -1; continue;
+ }
+
+ }
+
+ // then we attempt the "lossy" combinations
+ for(int i=0; i<numdirties; i++) {
+ int[] cur = dirties[i];
+ if (w > 0 && h > 0 && cur[2] > 0 && cur[3] > 0 &&
+ ((max(x + w, cur[0] + cur[2]) - min(x, cur[0])) *
+ (max(y + h, cur[1] + cur[3]) - min(y, cur[1])) <
+ w * h + cur[2] * cur[3] + epsilon)) {
+ int a = min(cur[0], x);
+ int b = min(cur[1], y);
+ int c = max(x + w, cur[0] + cur[2]) - min(cur[0], x);
+ int d = max(y + h, cur[1] + cur[3]) - min(cur[1], y);
+ dirties[i][2] = 0;
+ dirties[i][3] = 0;
+ return dirty(a, b, c, d);
+ }
+ }
+
+ dirties[numdirties++] = new int[] { x, y, w, h };
+ return true;
+ }
+
+ /** Returns true if there are no regions that need repainting */
+ public boolean empty() { return (numdirties == 0); }
+
+ /**
+ * Atomically returns the list of dirty rectangles as an array of
+ * four-int arrays and clears the internal dirty-rectangle
+ * list. Note that some of the regions returned may be null, or
+ * may have zero height or zero width, and do not need to be
+ * repainted.
+ */
+ public synchronized int[][] flush() {
+ if (numdirties == 0) return null;
+ int[][] ret = dirties;
+ for(int i=numdirties; i<ret.length; i++) ret[i] = null;
+ dirties = new int[dirties.length][];
+ numdirties = 0;
+ return ret;
+ }
+
+ /** included here so that it can be inlined */
+ private static final int min(int a, int b) {
+ if (a<b) return a;
+ else return b;
+ }
+
+ /** included here so that it can be inlined */
+ private static final int max(int a, int b) {
+ if (a>b) return a;
+ else return b;
+ }
+
+ /** included here so that it can be inlined */
+ private static final int min(int a, int b, int c) {
+ if (a<=b && a<=c) return a;
+ else if (b<=c && b<=a) return b;
+ else return c;
+ }
+
+ /** included here so that it can be inlined */
+ private static final int max(int a, int b, int c) {
+ if (a>=b && a>=c) return a;
+ else if (b>=c && b>=a) return b;
+ else return c;
+ }
+
+ /** included here so that it can be inlined */
+ private static final int bound(int a, int b, int c) {
+ if (a > b) return a;
+ if (c < b) return c;
+ return b;
+ }
+
+}
--- /dev/null
+package org.ibex.util;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ * BrowserLauncher is a class that provides one static method, openURL, which opens the default
+ * web browser for the current user of the system to the given URL. It may support other
+ * protocols depending on the system -- mailto, ftp, etc. -- but that has not been rigorously
+ * tested and is not guaranteed to work.
+ * <p>
+ * Yes, this is platform-specific code, and yes, it may rely on classes on certain platforms
+ * that are not part of the standard JDK. What we're trying to do, though, is to take something
+ * that's frequently desirable but inherently platform-specific -- opening a default browser --
+ * and allow programmers (you, for example) to do so without worrying about dropping into native
+ * code or doing anything else similarly evil.
+ * <p>
+ * Anyway, this code is completely in Java and will run on all JDK 1.1-compliant systems without
+ * modification or a need for additional libraries. All classes that are required on certain
+ * platforms to allow this to run are dynamically loaded at runtime via reflection and, if not
+ * found, will not cause this to do anything other than returning an error when opening the
+ * browser.
+ * <p>
+ * There are certain system requirements for this class, as it's running through Runtime.exec(),
+ * which is Java's way of making a native system call. Currently, this requires that a Macintosh
+ * have a Finder which supports the GURL event, which is true for Mac OS 8.0 and 8.1 systems that
+ * have the Internet Scripting AppleScript dictionary installed in the Scripting Additions folder
+ * in the Extensions folder (which is installed by default as far as I know under Mac OS 8.0 and
+ * 8.1), and for all Mac OS 8.5 and later systems. On Windows, it only runs under Win32 systems
+ * (Windows 95, 98, and NT 4.0, as well as later versions of all). On other systems, this drops
+ * back from the inherently platform-sensitive concept of a default browser and simply attempts
+ * to launch Netscape via a shell command.
+ * <p>
+ * This code is Copyright 1999-2001 by Eric Albert (ejalbert@cs.stanford.edu) and may be
+ * redistributed or modified in any form without restrictions as long as the portion of this
+ * comment from this paragraph through the end of the comment is not removed. The author
+ * requests that he be notified of any application, applet, or other binary that makes use of
+ * this code, but that's more out of curiosity than anything and is not required. This software
+ * includes no warranty. The author is not repsonsible for any loss of data or functionality
+ * or any adverse or unexpected effects of using this software.
+ * <p>
+ * Credits:
+ * <br>Steven Spencer, JavaWorld magazine (<a href="http://www.javaworld.com/javaworld/javatips/jw-javatip66.html">Java Tip 66</a>)
+ * <br>Thanks also to Ron B. Yeh, Eric Shapiro, Ben Engber, Paul Teitlebaum, Andrea Cantatore,
+ * Larry Barowski, Trevor Bedzek, Frank Miedrich, and Ron Rabakukk
+ *
+ * @author Eric Albert (<a href="mailto:ejalbert@cs.stanford.edu">ejalbert@cs.stanford.edu</a>)
+ * @version 1.4b1 (Released June 20, 2001)
+ */
+public class EjAlbertBrowserLauncher {
+
+ /**
+ * The Java virtual machine that we are running on. Actually, in most cases we only care
+ * about the operating system, but some operating systems require us to switch on the VM. */
+ private static int jvm;
+
+ /** The browser for the system */
+ private static Object browser;
+
+ /**
+ * Caches whether any classes, methods, and fields that are not part of the JDK and need to
+ * be dynamically loaded at runtime loaded successfully.
+ * <p>
+ * Note that if this is <code>false</code>, <code>openURL()</code> will always return an
+ * IOException.
+ */
+ private static boolean loadedWithoutErrors;
+
+ /** The com.apple.mrj.MRJFileUtils class */
+ private static Class mrjFileUtilsClass;
+
+ /** The com.apple.mrj.MRJOSType class */
+ private static Class mrjOSTypeClass;
+
+ /** The com.apple.MacOS.AEDesc class */
+ private static Class aeDescClass;
+
+ /** The <init>(int) method of com.apple.MacOS.AETarget */
+ private static Constructor aeTargetConstructor;
+
+ /** The <init>(int, int, int) method of com.apple.MacOS.AppleEvent */
+ private static Constructor appleEventConstructor;
+
+ /** The <init>(String) method of com.apple.MacOS.AEDesc */
+ private static Constructor aeDescConstructor;
+
+ /** The findFolder method of com.apple.mrj.MRJFileUtils */
+ private static Method findFolder;
+
+ /** The getFileCreator method of com.apple.mrj.MRJFileUtils */
+ private static Method getFileCreator;
+
+ /** The getFileType method of com.apple.mrj.MRJFileUtils */
+ private static Method getFileType;
+
+ /** The openURL method of com.apple.mrj.MRJFileUtils */
+ private static Method openURLm;
+
+ /** The makeOSType method of com.apple.MacOS.OSUtils */
+ private static Method makeOSType;
+
+ /** The putParameter method of com.apple.MacOS.AppleEvent */
+ private static Method putParameter;
+
+ /** The sendNoReply method of com.apple.MacOS.AppleEvent */
+ private static Method sendNoReply;
+
+ /** Actually an MRJOSType pointing to the System Folder on a Macintosh */
+ private static Object kSystemFolderType;
+
+ /** The keyDirectObject AppleEvent parameter type */
+ private static Integer keyDirectObject;
+
+ /** The kAutoGenerateReturnID AppleEvent code */
+ private static Integer kAutoGenerateReturnID;
+
+ /** The kAnyTransactionID AppleEvent code */
+ private static Integer kAnyTransactionID;
+
+ /** The linkage object required for JDirect 3 on Mac OS X. */
+ private static Object linkage;
+
+ /** The framework to reference on Mac OS X */
+ private static final String JDirect_MacOSX = "/System/Library/Frameworks/Carbon.framework/Frameworks/HIToolbox.framework/HIToolbox";
+
+ /** JVM constant for MRJ 2.0 */
+ private static final int MRJ_2_0 = 0;
+
+ /** JVM constant for MRJ 2.1 or later */
+ private static final int MRJ_2_1 = 1;
+
+ /** JVM constant for Java on Mac OS X 10.0 (MRJ 3.0) */
+ private static final int MRJ_3_0 = 3;
+
+ /** JVM constant for MRJ 3.1 */
+ private static final int MRJ_3_1 = 4;
+
+ /** JVM constant for any Windows NT JVM */
+ private static final int WINDOWS_NT = 5;
+
+ /** JVM constant for any Windows 9x JVM */
+ private static final int WINDOWS_9x = 6;
+
+ /** JVM constant for any other platform */
+ private static final int OTHER = -1;
+
+ /**
+ * The file type of the Finder on a Macintosh. Hardcoding "Finder" would keep non-U.S. English
+ * systems from working properly.
+ */
+ private static final String FINDER_TYPE = "FNDR";
+
+ /**
+ * The creator code of the Finder on a Macintosh, which is needed to send AppleEvents to the
+ * application.
+ */
+ private static final String FINDER_CREATOR = "MACS";
+
+ /** The name for the AppleEvent type corresponding to a GetURL event. */
+ private static final String GURL_EVENT = "GURL";
+
+ /**
+ * The first parameter that needs to be passed into Runtime.exec() to open the default web
+ * browser on Windows.
+ */
+ private static final String FIRST_WINDOWS_PARAMETER = "/c";
+
+ /** The second parameter for Runtime.exec() on Windows. */
+ private static final String SECOND_WINDOWS_PARAMETER = "start";
+
+ /**
+ * The third parameter for Runtime.exec() on Windows. This is a "title"
+ * parameter that the command line expects. Setting this parameter allows
+ * URLs containing spaces to work.
+ */
+ private static final String THIRD_WINDOWS_PARAMETER = "\"\"";
+
+ /**
+ * The shell parameters for Netscape that opens a given URL in an already-open copy of Netscape
+ * on many command-line systems.
+ */
+ private static final String NETSCAPE_REMOTE_PARAMETER = "-remote";
+ private static final String NETSCAPE_OPEN_PARAMETER_START = "'openURL(";
+ private static final String NETSCAPE_OPEN_PARAMETER_END = ")'";
+
+ /**
+ * The message from any exception thrown throughout the initialization process.
+ */
+ private static String errorMessage;
+
+ /**
+ * An initialization block that determines the operating system and loads the necessary
+ * runtime data.
+ */
+ static {
+ loadedWithoutErrors = true;
+ String osName = System.getProperty("os.name");
+ if (osName.startsWith("Mac OS")) {
+ String mrjVersion = System.getProperty("mrj.version");
+ String majorMRJVersion = mrjVersion.substring(0, 3);
+ try {
+ double version = Double.valueOf(majorMRJVersion).doubleValue();
+ if (version == 2) {
+ jvm = MRJ_2_0;
+ } else if (version >= 2.1 && version < 3) {
+ // Assume that all 2.x versions of MRJ work the same. MRJ 2.1 actually
+ // works via Runtime.exec() and 2.2 supports that but has an openURL() method
+ // as well that we currently ignore.
+ jvm = MRJ_2_1;
+ } else if (version == 3.0) {
+ jvm = MRJ_3_0;
+ } else if (version >= 3.1) {
+ // Assume that all 3.1 and later versions of MRJ work the same.
+ jvm = MRJ_3_1;
+ } else {
+ loadedWithoutErrors = false;
+ errorMessage = "Unsupported MRJ version: " + version;
+ }
+ } catch (NumberFormatException nfe) {
+ loadedWithoutErrors = false;
+ errorMessage = "Invalid MRJ version: " + mrjVersion;
+ }
+ } else if (osName.startsWith("Windows")) {
+ if (osName.indexOf("9") != -1) {
+ jvm = WINDOWS_9x;
+ } else {
+ jvm = WINDOWS_NT;
+ }
+ } else {
+ jvm = OTHER;
+ }
+
+ if (loadedWithoutErrors) { // if we haven't hit any errors yet
+ loadedWithoutErrors = loadClasses();
+ }
+ }
+
+ /**
+ * This class should be never be instantiated; this just ensures so.
+ */
+ private EjAlbertBrowserLauncher() { }
+
+ /**
+ * Called by a static initializer to load any classes, fields, and methods required at runtime
+ * to locate the user's web browser.
+ * @return <code>true</code> if all intialization succeeded
+ * <code>false</code> if any portion of the initialization failed
+ */
+ private static boolean loadClasses() {
+ switch (jvm) {
+ case MRJ_2_0:
+ try {
+ Class aeTargetClass = Class.forName("com.apple.MacOS.AETarget");
+ Class osUtilsClass = Class.forName("com.apple.MacOS.OSUtils");
+ Class appleEventClass = Class.forName("com.apple.MacOS.AppleEvent");
+ Class aeClass = Class.forName("com.apple.MacOS.ae");
+ aeDescClass = Class.forName("com.apple.MacOS.AEDesc");
+
+ aeTargetConstructor = aeTargetClass.getDeclaredConstructor(new Class [] { int.class });
+ appleEventConstructor = appleEventClass.getDeclaredConstructor(new Class[] { int.class, int.class, aeTargetClass, int.class, int.class });
+ aeDescConstructor = aeDescClass.getDeclaredConstructor(new Class[] { String.class });
+
+ makeOSType = osUtilsClass.getDeclaredMethod("makeOSType", new Class [] { String.class });
+ putParameter = appleEventClass.getDeclaredMethod("putParameter", new Class[] { int.class, aeDescClass });
+ sendNoReply = appleEventClass.getDeclaredMethod("sendNoReply", new Class[] { });
+
+ Field keyDirectObjectField = aeClass.getDeclaredField("keyDirectObject");
+ keyDirectObject = (Integer) keyDirectObjectField.get(null);
+ Field autoGenerateReturnIDField = appleEventClass.getDeclaredField("kAutoGenerateReturnID");
+ kAutoGenerateReturnID = (Integer) autoGenerateReturnIDField.get(null);
+ Field anyTransactionIDField = appleEventClass.getDeclaredField("kAnyTransactionID");
+ kAnyTransactionID = (Integer) anyTransactionIDField.get(null);
+ } catch (ClassNotFoundException cnfe) {
+ errorMessage = cnfe.getMessage();
+ return false;
+ } catch (NoSuchMethodException nsme) {
+ errorMessage = nsme.getMessage();
+ return false;
+ } catch (NoSuchFieldException nsfe) {
+ errorMessage = nsfe.getMessage();
+ return false;
+ } catch (IllegalAccessException iae) {
+ errorMessage = iae.getMessage();
+ return false;
+ }
+ break;
+ case MRJ_2_1:
+ try {
+ mrjFileUtilsClass = Class.forName("com.apple.mrj.MRJFileUtils");
+ mrjOSTypeClass = Class.forName("com.apple.mrj.MRJOSType");
+ Field systemFolderField = mrjFileUtilsClass.getDeclaredField("kSystemFolderType");
+ kSystemFolderType = systemFolderField.get(null);
+ findFolder = mrjFileUtilsClass.getDeclaredMethod("findFolder", new Class[] { mrjOSTypeClass });
+ getFileCreator = mrjFileUtilsClass.getDeclaredMethod("getFileCreator", new Class[] { File.class });
+ getFileType = mrjFileUtilsClass.getDeclaredMethod("getFileType", new Class[] { File.class });
+ } catch (ClassNotFoundException cnfe) {
+ errorMessage = cnfe.getMessage();
+ return false;
+ } catch (NoSuchFieldException nsfe) {
+ errorMessage = nsfe.getMessage();
+ return false;
+ } catch (NoSuchMethodException nsme) {
+ errorMessage = nsme.getMessage();
+ return false;
+ } catch (SecurityException se) {
+ errorMessage = se.getMessage();
+ return false;
+ } catch (IllegalAccessException iae) {
+ errorMessage = iae.getMessage();
+ return false;
+ }
+ break;
+ case MRJ_3_0:
+ try {
+ Class linker = Class.forName("com.apple.mrj.jdirect.Linker");
+ Constructor constructor = linker.getConstructor(new Class[]{ Class.class });
+ linkage = constructor.newInstance(new Object[] { EjAlbertBrowserLauncher.class });
+ } catch (ClassNotFoundException cnfe) {
+ errorMessage = cnfe.getMessage();
+ return false;
+ } catch (NoSuchMethodException nsme) {
+ errorMessage = nsme.getMessage();
+ return false;
+ } catch (InvocationTargetException ite) {
+ errorMessage = ite.getMessage();
+ return false;
+ } catch (InstantiationException ie) {
+ errorMessage = ie.getMessage();
+ return false;
+ } catch (IllegalAccessException iae) {
+ errorMessage = iae.getMessage();
+ return false;
+ }
+ break;
+ case MRJ_3_1:
+ try {
+ mrjFileUtilsClass = Class.forName("com.apple.mrj.MRJFileUtils");
+ openURLm = mrjFileUtilsClass.getDeclaredMethod("openURL", new Class[] { String.class });
+ } catch (ClassNotFoundException cnfe) {
+ errorMessage = cnfe.getMessage();
+ return false;
+ } catch (NoSuchMethodException nsme) {
+ errorMessage = nsme.getMessage();
+ return false;
+ }
+ break;
+ default:
+ break;
+ }
+ return true;
+ }
+
+ /**
+ * Attempts to locate the default web browser on the local system. Caches results so it
+ * only locates the browser once for each use of this class per JVM instance.
+ * @return The browser for the system. Note that this may not be what you would consider
+ * to be a standard web browser; instead, it's the application that gets called to
+ * open the default web browser. In some cases, this will be a non-String object
+ * that provides the means of calling the default browser.
+ */
+ private static Object locateBrowser() {
+ if (browser != null) {
+ return browser;
+ }
+ switch (jvm) {
+ case MRJ_2_0:
+ try {
+ Integer finderCreatorCode = (Integer) makeOSType.invoke(null, new Object[] { FINDER_CREATOR });
+ Object aeTarget = aeTargetConstructor.newInstance(new Object[] { finderCreatorCode });
+ Integer gurlType = (Integer) makeOSType.invoke(null, new Object[] { GURL_EVENT });
+ Object appleEvent = appleEventConstructor.newInstance(new Object[] { gurlType, gurlType, aeTarget, kAutoGenerateReturnID, kAnyTransactionID });
+ // Don't set browser = appleEvent because then the next time we call
+ // locateBrowser(), we'll get the same AppleEvent, to which we'll already have
+ // added the relevant parameter. Instead, regenerate the AppleEvent every time.
+ // There's probably a way to do this better; if any has any ideas, please let
+ // me know.
+ return appleEvent;
+ } catch (IllegalAccessException iae) {
+ browser = null;
+ errorMessage = iae.getMessage();
+ return browser;
+ } catch (InstantiationException ie) {
+ browser = null;
+ errorMessage = ie.getMessage();
+ return browser;
+ } catch (InvocationTargetException ite) {
+ browser = null;
+ errorMessage = ite.getMessage();
+ return browser;
+ }
+ case MRJ_2_1:
+ File systemFolder;
+ try {
+ systemFolder = (File) findFolder.invoke(null, new Object[] { kSystemFolderType });
+ } catch (IllegalArgumentException iare) {
+ browser = null;
+ errorMessage = iare.getMessage();
+ return browser;
+ } catch (IllegalAccessException iae) {
+ browser = null;
+ errorMessage = iae.getMessage();
+ return browser;
+ } catch (InvocationTargetException ite) {
+ browser = null;
+ errorMessage = ite.getTargetException().getClass() + ": " + ite.getTargetException().getMessage();
+ return browser;
+ }
+ String[] systemFolderFiles = systemFolder.list();
+ // Avoid a FilenameFilter because that can't be stopped mid-list
+ for(int i = 0; i < systemFolderFiles.length; i++) {
+ try {
+ File file = new File(systemFolder, systemFolderFiles[i]);
+ if (!file.isFile()) {
+ continue;
+ }
+ // We're looking for a file with a creator code of 'MACS' and
+ // a type of 'FNDR'. Only requiring the type results in non-Finder
+ // applications being picked up on certain Mac OS 9 systems,
+ // especially German ones, and sending a GURL event to those
+ // applications results in a logout under Multiple Users.
+ Object fileType = getFileType.invoke(null, new Object[] { file });
+ if (FINDER_TYPE.equals(fileType.toString())) {
+ Object fileCreator = getFileCreator.invoke(null, new Object[] { file });
+ if (FINDER_CREATOR.equals(fileCreator.toString())) {
+ browser = file.toString(); // Actually the Finder, but that's OK
+ return browser;
+ }
+ }
+ } catch (IllegalArgumentException iare) {
+ browser = browser;
+ errorMessage = iare.getMessage();
+ return null;
+ } catch (IllegalAccessException iae) {
+ browser = null;
+ errorMessage = iae.getMessage();
+ return browser;
+ } catch (InvocationTargetException ite) {
+ browser = null;
+ errorMessage = ite.getTargetException().getClass() + ": " + ite.getTargetException().getMessage();
+ return browser;
+ }
+ }
+ browser = null;
+ break;
+ case MRJ_3_0:
+ case MRJ_3_1:
+ browser = ""; // Return something non-null
+ break;
+ case WINDOWS_NT:
+ browser = "cmd.exe";
+ break;
+ case WINDOWS_9x:
+ browser = "command.com";
+ break;
+ case OTHER:
+ default:
+ browser = "netscape";
+ break;
+ }
+ return browser;
+ }
+
+ /**
+ * Attempts to open the default web browser to the given URL.
+ * @param url The URL to open
+ * @throws IOException If the web browser could not be located or does not run
+ */
+ public static void openURL(String url) throws IOException {
+ if (!loadedWithoutErrors) {
+ throw new IOException("Exception in finding browser: " + errorMessage);
+ }
+ Object browser = locateBrowser();
+ if (browser == null) {
+ throw new IOException("Unable to locate browser: " + errorMessage);
+ }
+
+ switch (jvm) {
+ case MRJ_2_0:
+ Object aeDesc = null;
+ try {
+ aeDesc = aeDescConstructor.newInstance(new Object[] { url });
+ putParameter.invoke(browser, new Object[] { keyDirectObject, aeDesc });
+ sendNoReply.invoke(browser, new Object[] { });
+ } catch (InvocationTargetException ite) {
+ throw new IOException("InvocationTargetException while creating AEDesc: " + ite.getMessage());
+ } catch (IllegalAccessException iae) {
+ throw new IOException("IllegalAccessException while building AppleEvent: " + iae.getMessage());
+ } catch (InstantiationException ie) {
+ throw new IOException("InstantiationException while creating AEDesc: " + ie.getMessage());
+ } finally {
+ aeDesc = null; // Encourage it to get disposed if it was created
+ browser = null; // Ditto
+ }
+ break;
+ case MRJ_2_1:
+ Runtime.getRuntime().exec(new String[] { (String) browser, url } );
+ break;
+ case MRJ_3_0:
+ int[] instance = new int[1];
+ int result = ICStart(instance, 0);
+ if (result == 0) {
+ int[] selectionStart = new int[] { 0 };
+ byte[] urlBytes = url.getBytes();
+ int[] selectionEnd = new int[] { urlBytes.length };
+ result = ICLaunchURL(instance[0], new byte[] { 0 }, urlBytes,
+ urlBytes.length, selectionStart,
+ selectionEnd);
+ if (result == 0) {
+ // Ignore the return value; the URL was launched successfully
+ // regardless of what happens here.
+ ICStop(instance);
+ } else {
+ throw new IOException("Unable to launch URL: " + result);
+ }
+ } else {
+ throw new IOException("Unable to create an Internet Config instance: " + result);
+ }
+ break;
+ case MRJ_3_1:
+ try {
+ openURLm.invoke(null, new Object[] { url });
+ } catch (InvocationTargetException ite) {
+ throw new IOException("InvocationTargetException while calling openURL: " + ite.getMessage());
+ } catch (IllegalAccessException iae) {
+ throw new IOException("IllegalAccessException while calling openURL: " + iae.getMessage());
+ }
+ break;
+ case WINDOWS_NT:
+ case WINDOWS_9x:
+ // Add quotes around the URL to allow ampersands and other special
+ // characters to work.
+ Process process = Runtime.getRuntime().exec(new String[] { (String) browser,
+ FIRST_WINDOWS_PARAMETER,
+ SECOND_WINDOWS_PARAMETER,
+ THIRD_WINDOWS_PARAMETER,
+ '"' + url + '"' });
+ // This avoids a memory leak on some versions of Java on Windows.
+ // That's hinted at in <http://developer.java.sun.com/developer/qow/archive/68/>.
+ try {
+ process.waitFor();
+ process.exitValue();
+ } catch (InterruptedException ie) {
+ throw new IOException("InterruptedException while launching browser: " + ie.getMessage());
+ }
+ break;
+ case OTHER:
+ // Assume that we're on Unix and that Netscape is installed
+
+ // First, attempt to open the URL in a currently running session of Netscape
+ process = Runtime.getRuntime().exec(new String[] { (String) browser,
+ NETSCAPE_REMOTE_PARAMETER,
+ NETSCAPE_OPEN_PARAMETER_START +
+ url +
+ NETSCAPE_OPEN_PARAMETER_END });
+ try {
+ int exitCode = process.waitFor();
+ if (exitCode != 0) { // if Netscape was not open
+ Runtime.getRuntime().exec(new String[] { (String) browser, url });
+ }
+ } catch (InterruptedException ie) {
+ throw new IOException("InterruptedException while launching browser: " + ie.getMessage());
+ }
+ break;
+ default:
+ // This should never occur, but if it does, we'll try the simplest thing possible
+ Runtime.getRuntime().exec(new String[] { (String) browser, url });
+ break;
+ }
+ }
+
+ /**
+ * Methods required for Mac OS X. The presence of native methods does not cause
+ * any problems on other platforms.
+ */
+ /*
+ private native static int ICStart(int[] instance, int signature);
+ private native static int ICStop(int[] instance);
+ private native static int ICLaunchURL(int instance, byte[] hint, byte[] data, int len,
+ int[] selectionStart, int[] selectionEnd);
+ */
+ private static int ICStart(int[] instance, int signature) { return 0; }
+ private static int ICStop(int[] instance) { return 0; }
+ private static int ICLaunchURL(int instance, byte[] hint, byte[] data, int len,
+ int[] selectionStart, int[] selectionEnd) { return 0; }
+}
--- /dev/null
+package org.ibex.util;
+
+import org.ibex.js.*;
+
+public abstract class Grammar extends JS {
+
+ public JS action = null;
+
+ // means we call()ed a Grammar that hasn't been bound to a scope yet
+ public Object call(Object a0, Object a1, Object a2, Object[] rest, int nargs) throws JSExn {
+ throw new Error("this should never happen");
+ }
+
+ private static Object NULL = new Object();
+
+ public abstract int match(String s, int start, Hash v, JSScope scope) throws JSExn;
+ public int matchAndWrite(final String s, final int start, Hash v, JSScope scope, String key) throws JSExn {
+ final Hash v2 = new Hash();
+ final int ret = match(s, start, v2, scope);
+ Object result = ret == -1 ? NULL : action == null ?
+ s.substring(start, ret) :
+ JS.cloneWithNewParentScope(action, new JSScope(scope) {
+ public Object get(Object key) throws JSExn {
+ Object val = v2.get(key);
+ if (val == NULL) return null;
+ if (val != null) return val;
+ if (key.equals("whole")) return s.substring(start, ret);
+ return super.get(key);
+ }
+ }).call(null, null, null, null, 0);
+ if (key != null) {
+ Object old = v.get(key);
+ if (old == null || old == NULL) { }
+ else if (old instanceof JSArray) { if (result != NULL) { ((JSArray)old).addElement(result); result = old; } }
+ else if (result != NULL) { JSArray j = new JSArray(); j.addElement(old); j.addElement(result); result = j; }
+ v.put(key, result);
+ }
+ return ret;
+ }
+
+ public static class Alternative extends Grammar {
+ private Grammar r1, r2;
+ public Alternative(Grammar r1, Grammar r2) { this.r1 = r1; this.r2 = r2; }
+ public int match(String s, int start, Hash v, JSScope r) throws JSExn {
+ int s1 = r1.match(s, start, v, r);
+ if (s1 != -1) return s1;
+ int s2 = r2.match(s, start, v, r);
+ if (s2 != -1) return s2;
+ return -1;
+ }
+ }
+
+ public static class Juxtaposition extends Grammar {
+ private Grammar r1, r2;
+ public Juxtaposition(Grammar r1, Grammar r2) { this.r1 = r1; this.r2 = r2; }
+ public int match(String s, int start, Hash v, JSScope r) throws JSExn {
+ int s1 = r1.match(s, start, v, r);
+ if (s1 == -1) return -1;
+ int s2 = r2.match(s, s1, v, r);
+ if (s2 == -1) return -1;
+ return s2;
+ }
+ }
+
+ public static class Repetition extends Grammar {
+ private Grammar r1;
+ private int min, max;
+ public Repetition(Grammar r1, int min, int max) { this.r1 = r1; this.min = min; this.max = max; }
+ public int match(String s, int start, Hash v, JSScope r) throws JSExn {
+ int i;
+ for(i=0; i<max; i++) {
+ start = r1.match(s, start, v, r);
+ if (start == -1) return -1;
+ }
+ if (i < min) return -1;
+ return start;
+ }
+ }
+
+ public static class Literal extends Grammar {
+ String str;
+ public Literal(String str) { this.str = str; }
+ public int match(String s, int start, Hash v, JSScope r) {
+ if (!s.regionMatches(start, str, 0, str.length())) return -1;
+ return start + str.length();
+ }
+ }
+
+ public static class Range extends Grammar {
+ char min, max;
+ public Range(char min, char max) { this.min = min; this.max = max; }
+ public int match(String s, int start, Hash v, JSScope r) throws JSExn {
+ if (!(s.charAt(start) >= min && s.charAt(start) <= max)) return -1;
+ return start + 1;
+ }
+ }
+
+ public static class Reference extends Grammar {
+ String key;
+ public Reference(String key) { this.key = key; }
+ public int match(String s, int start, Hash v, JSScope scope) throws JSExn {
+ return ((Grammar)scope.get(key)).matchAndWrite(s, start, v, scope, key);
+ }
+ }
+}
--- /dev/null
+// Copyright (C) 2003 Adam Megacz <adam@ibex.org> all rights reserved.
+//
+// You may modify, copy, and redistribute this code under the terms of
+// the GNU Library Public License version 2.1, with the exception of
+// the portion of clause 6a after the semicolon (aka the "obnoxious
+// relink clause")
+
+package org.ibex.util;
+
+import java.util.*;
+
+/** Implementation of an unsynchronized hash table, with one or two
+ * keys, using Radke's quadradic residue linear probing instead of
+ * buckets to minimize object count (less allocations, faster GC).
+ * See C. Radke, Communications of the ACM, 1970, 103-105
+ *
+ * Not threadsafe.
+ */
+public class Hash {
+ /** this object is inserted as key in a slot when the
+ * corresponding value is removed -- this ensures that the
+ * probing sequence for any given key remains the same even if
+ * other keys are removed.
+ */
+ private static Object placeholder = new Object();
+
+ /** the number of entries with at least one non-null key */
+ private int usedslots = 0;
+
+ /** the number of entries with non-null values */
+ protected int size = 0;
+
+ /** when num_slots < loadFactor * size, rehash into a bigger table */
+ private final int loadFactor;
+
+ /** primary keys */
+ private Object[] keys1 = null;
+
+ /** secondary keys; null if no secondary key has ever been added */
+ private Object[] keys2 = null;
+
+ /** the values for the table */
+ private Object[] vals = null;
+
+ /** the number of entries with a non-null value */
+ public int size() { return size; }
+
+ /** empties the table */
+ public void clear() {
+ size = 0;
+ usedslots = 0;
+ for(int i=0; i<vals.length; i++) {
+ vals[i] = null;
+ keys1[i] = null;
+ if (keys2 != null) keys2[i] = null;
+ }
+ }
+
+ /** returns all the primary keys in the table */
+ public Enumeration keys() { return new HashEnum(); }
+
+ public Hash() { this(25, 3); }
+ public Hash(int initialcapacity, int loadFactor) {
+ // using a pseudoprime in the form 4x+3 ensures full coverage
+ initialcapacity = initialcapacity / 4;
+ initialcapacity = 4 * initialcapacity + 3;
+ keys1 = new Object[initialcapacity];
+ vals = new Object[initialcapacity];
+ this.loadFactor = loadFactor;
+ }
+
+ public void remove(Object k1) { remove(k1, null); }
+ public void remove(Object k1, Object k2) { put_(k1, k2, null); }
+
+ private void rehash() {
+ Object[] oldkeys1 = keys1;
+ Object[] oldkeys2 = keys2;
+ Object[] oldvals = vals;
+ keys1 = new Object[oldvals.length * 2];
+ keys2 = oldkeys2 == null ? null : new Object[oldvals.length * 2];
+ vals = new Object[oldvals.length * 2];
+ size = 0;
+ usedslots = 0;
+ for(int i=0; i<oldvals.length; i++)
+ if (((oldkeys1[i] != null && oldkeys1[i] != placeholder) || (oldkeys2 != null && oldkeys2[i] != null)) && oldvals[i] != null)
+ put_(oldkeys1[i], oldkeys2 == null ? null : oldkeys2[i], oldvals[i]);
+ }
+
+ public Object get(Object k1) { return get(k1, null); }
+ public Object get(Object k1, Object k2) {
+ if (k2 != null && keys2 == null) return null;
+ int hash = (k1 == null ? 0 : k1.hashCode()) ^ (k2 == null ? 0 : k2.hashCode());
+ int dest = Math.abs(hash) % vals.length;
+ int odest = dest;
+ int tries = 1;
+ boolean plus = true;
+ while (keys1[dest] != null || (keys2 != null && keys2[dest] != null)) {
+ Object hk1 = keys1[dest];
+ Object hk2 = keys2 == null ? null : keys2[dest];
+ if ((k1 == hk1 || (k1 != null && hk1 != null && k1.equals(hk1))) &&
+ (k2 == hk2 || (k2 != null && hk2 != null && k2.equals(hk2)))) {
+ return vals[dest];
+ }
+ dest = Math.abs((odest + (plus ? 1 : -1 ) * tries * tries) % vals.length);
+ if (plus) tries++;
+ plus = !plus;
+ }
+ return null;
+ }
+
+ public void put(Object k1, Object v) { put(k1, null, v); }
+ public void put(Object k1, Object k2, Object v) { put_(k1, k2, v); }
+ private void put_(Object k1, Object k2, Object v) {
+ if (usedslots * loadFactor > vals.length) rehash();
+ int hash = (k1 == null ? 0 : k1.hashCode()) ^ (k2 == null ? 0 : k2.hashCode());
+ int dest = Math.abs(hash) % vals.length;
+ int odest = dest;
+ boolean plus = true;
+ int tries = 1;
+ while (true) {
+ Object hk1 = keys1[dest];
+ Object hk2 = keys2 == null ? null : keys2[dest];
+ if (hk1 == null && hk2 == null) { // empty slot
+ if (v == null) return;
+ size++;
+ usedslots++;
+ break;
+ }
+
+ if ((k1 == hk1 || (k1 != null && hk1 != null && k1.equals(hk1))) && // replacing former entry
+ (k2 == hk2 || (k2 != null && hk2 != null && k2.equals(hk2)))) {
+
+ // we don't actually remove things from the table; rather, we insert a placeholder
+ if (v == null) {
+ k1 = placeholder;
+ k2 = null;
+ size--;
+ }
+ break;
+ }
+
+ dest = Math.abs((odest + (plus ? 1 : -1 ) * tries * tries) % vals.length);
+ if (plus) tries++;
+ plus = !plus;
+ }
+
+ keys1[dest] = k1;
+ if (k2 != null && keys2 == null) keys2 = new Object[keys1.length];
+ if (keys2 != null) keys2[dest] = k2;
+ vals[dest] = v;
+ }
+
+ private class HashEnum implements java.util.Enumeration {
+ private int iterator = 0;
+ private int found = 0;
+
+ public boolean hasMoreElements() {
+ return found < usedslots;
+ }
+
+ public Object nextElement() {
+ if (!hasMoreElements()) throw new java.util.NoSuchElementException();
+
+ Object o = null;
+ while (o == null) o = keys1[iterator++];
+ if (o == null) throw new IllegalStateException("Didn't find an element, when I should have.");
+ found++;
+
+ return o;
+ }
+ }
+}
+
+
--- /dev/null
+// Copyright (C) 2003 Adam Megacz <adam@ibex.org> all rights reserved.
+//
+// You may modify, copy, and redistribute this code under the terms of
+// the GNU Library Public License version 2.1, with the exception of
+// the portion of clause 6a after the semicolon (aka the "obnoxious
+// relink clause")
+
+package org.ibex.util;
+import java.io.*;
+
+public class InputStreamToByteArray {
+
+ /** scratch space for isToByteArray() */
+ private static byte[] workspace = new byte[16 * 1024];
+
+ /** Trivial method to completely read an InputStream */
+ public static synchronized byte[] convert(InputStream is) throws IOException {
+ int pos = 0;
+ while (true) {
+ int numread = is.read(workspace, pos, workspace.length - pos);
+ if (numread == -1) break;
+ else if (pos + numread < workspace.length) pos += numread;
+ else {
+ pos += numread;
+ byte[] temp = new byte[workspace.length * 2];
+ System.arraycopy(workspace, 0, temp, 0, workspace.length);
+ workspace = temp;
+ }
+ }
+ byte[] ret = new byte[pos];
+ System.arraycopy(workspace, 0, ret, 0, pos);
+ return ret;
+ }
+
+}
--- /dev/null
+// Copyright (C) 2003 Adam Megacz <adam@ibex.org> all rights reserved.
+//
+// You may modify, copy, and redistribute this code under the terms of
+// the GNU Library Public License version 2.1, with the exception of
+// the portion of clause 6a after the semicolon (aka the "obnoxious
+// relink clause")
+
+package org.ibex.util;
+import java.io.*;
+
+/** a generic interface for things that "know" their length */
+public interface KnownLength {
+
+ public abstract int getLength();
+
+ public static class KnownLengthInputStream extends FilterInputStream implements KnownLength {
+ int length;
+ public int getLength() { return length; }
+ public KnownLengthInputStream(java.io.InputStream parent, int length) {
+ super(parent);
+ this.length = length;
+ }
+ }
+
+}
--- /dev/null
+package org.ibex.util;
+import java.io.*;
+
+public class LineReader {
+
+ private static int MAXBUF = 1024 * 16;
+ char[] buf = new char[MAXBUF];
+ int buflen = 0;
+ Reader r;
+ Vec pushback = new Vec();
+
+ public LineReader(Reader r) { this.r = r; }
+
+ public void pushback(String s) { pushback.push(s); }
+
+ public String readLine() throws IOException {
+ while(true) {
+ if (pushback.size() > 0) return (String)pushback.pop();
+ for(int i=0; i<buflen; i++) {
+ if (buf[i] == '\n') {
+ String ret;
+ if (buf[i-1] == '\r') ret = new String(buf, 0, i-1);
+ else ret = new String(buf, 0, i);
+ System.arraycopy(buf, i+1, buf, 0, buflen - (i+1));
+ buflen -= i+1;
+ return ret;
+ }
+ }
+ int numread = r.read(buf, buflen, MAXBUF - buflen);
+ if (numread == -1) {
+ if (buflen == 0) return null;
+ String ret = new String(buf, 0, buflen);
+ buflen = 0;
+ return ret;
+ } else {
+ buflen += numread;
+ }
+ }
+ }
+}
--- /dev/null
+// Copyright (C) 2003 Adam Megacz <adam@ibex.org> all rights reserved.
+//
+// You may modify, copy, and redistribute this code under the terms of
+// the GNU Library Public License version 2.1, with the exception of
+// the portion of clause 6a after the semicolon (aka the "obnoxious
+// relink clause")
+
+package org.ibex.util;
+import org.ibex.js.*;
+import java.io.*;
+import java.util.*;
+import java.net.*;
+
+/** easy to use logger */
+public class Log {
+
+ public static boolean on = true;
+ public static boolean rpc = false;
+ public static boolean color = false;
+ public static boolean verbose = false;
+ public static boolean logDates = false;
+ public static Date lastDate = null;
+
+ public static PrintStream logstream = System.err;
+
+ public static void email(String address) { throw new Error("FIXME not supported"); }
+ public static void file(String filename) throws IOException {
+ // FIXME security
+ logstream = new PrintStream(new FileOutputStream(filename));
+ }
+ public static void tcp(String host, int port) throws IOException {
+ // FIXME security
+ logstream = new PrintStream(new Socket(InetAddress.getByName(host), port).getOutputStream());
+ }
+
+ private static Hashtable threadAnnotations = new Hashtable();
+ public static void setThreadAnnotation(String s) { threadAnnotations.put(Thread.currentThread(), s); }
+
+ /** true iff nothing has yet been logged */
+ public static boolean firstMessage = true;
+
+ /** message can be a String or a Throwable */
+ public static synchronized void echo(Object o, Object message) { log(o, message, ECHO); }
+ public static synchronized void diag(Object o, Object message) { log(o, message, DIAGNOSTIC); }
+ public static synchronized void debug(Object o, Object message) { log(o, message, DEBUG); }
+ public static synchronized void info(Object o, Object message) { log(o, message, INFO); }
+ public static synchronized void warn(Object o, Object message) { log(o, message, WARN); }
+ public static synchronized void error(Object o, Object message) { log(o, message, ERROR); }
+
+ // these two logging levels serve ONLY to change the color; semantically they are the same as DEBUG
+ private static final int DIAGNOSTIC = -2;
+ private static final int ECHO = -1;
+
+ // the usual log4j levels, minus FAIL (we just throw an Error in that case)
+ public static final int DEBUG = 0;
+ public static final int INFO = 1;
+ public static final int WARN = 2;
+ public static final int ERROR = 3;
+ public static final int SILENT = Integer.MAX_VALUE;
+ public static int level = INFO;
+
+ private static final int BLUE = 34;
+ private static final int GREEN = 32;
+ private static final int CYAN = 36;
+ private static final int RED = 31;
+ private static final int PURPLE = 35;
+ private static final int BROWN = 33;
+ private static final int GRAY = 37;
+
+ private static String colorize(int color, boolean bright, String s) {
+ if (!Log.color) return s;
+ return
+ "\033[40;" + (bright?"1;":"") + color + "m" +
+ s +
+ "\033[0m";
+ }
+
+ private static String lastClassName = null;
+ private static synchronized void log(Object o, Object message, int level) {
+ if (level < Log.level) return;
+ if (firstMessage && !logDates) {
+ firstMessage = false;
+ logstream.println(colorize(GREEN, false, "==========================================================================="));
+
+ // FIXME later: causes problems with method pruning
+ //diag(Log.class, "Logging enabled at " + new java.util.Date());
+
+ if (color) diag(Log.class, "logging messages in " +
+ colorize(BLUE, true, "c") +
+ colorize(RED, true, "o") +
+ colorize(CYAN, true, "l") +
+ colorize(GREEN, true, "o") +
+ colorize(PURPLE, true, "r"));
+ }
+
+ String classname;
+ if (o instanceof Class) {
+ classname = ((Class)o).getName();
+ if (classname.indexOf('.') != -1) classname = classname.substring(classname.lastIndexOf('.') + 1);
+ }
+ else if (o instanceof String) classname = (String)o;
+ else classname = o.getClass().getName();
+
+ if (classname.equals(lastClassName)) classname = "";
+ else lastClassName = classname;
+
+ if (classname.length() > (logDates ? 14 : 20)) classname = classname.substring(0, (logDates ? 14 : 20));
+ while (classname.length() < (logDates ? 14 : 20)) classname = " " + classname;
+ classname = classname + (classname.trim().length() == 0 ? " " : ": ");
+ classname = colorize(GRAY, true, classname);
+ classname = classname.replace('$', '.');
+
+ if (logDates) {
+ Date d = new Date();
+ if (lastDate == null || d.getYear() != lastDate.getYear() || d.getMonth() != lastDate.getMonth() || d.getDay() != lastDate.getDay()) {
+ String now = new java.text.SimpleDateFormat("EEE dd MMM yyyy").format(d);
+ logstream.println();
+ logstream.println(colorize(GRAY, false, "=== " + now + " =========================================================="));
+ }
+ java.text.DateFormat df = new java.text.SimpleDateFormat("[EEE HH:mm:ss] ");
+ classname = df.format(d) + classname;
+ lastDate = d;
+ }
+
+ String annot = (String)threadAnnotations.get(Thread.currentThread());
+ if (annot != null) classname += annot;
+
+ if (message instanceof Throwable) {
+ if (level < ERROR) level = WARN;
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ((Throwable)message).printStackTrace(new PrintStream(baos));
+ byte[] b = baos.toByteArray();
+ BufferedReader br = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(b)));
+ String s = null;
+ try {
+ String m = "";
+ while((s = br.readLine()) != null) m += s + "\n";
+ if (m.length() > 0) log(o, m.substring(0, m.length() - 1), level);
+ } catch (IOException e) {
+ logstream.println(colorize(RED, true, "Logger: exception thrown by ByteArrayInputStream -- this should not happen"));
+ }
+ lastClassName = "";
+ return;
+ }
+
+ String str = message.toString();
+ if (str.indexOf('\n') != -1) lastClassName = "";
+ while(str.indexOf('\t') != -1)
+ str = str.substring(0, str.indexOf('\t')) + " " + str.substring(str.indexOf('\t') + 1);
+
+ classname = colorize(GRAY, false, classname);
+ int levelcolor = GRAY;
+ boolean bright = true;
+ switch (level) {
+ case DIAGNOSTIC: levelcolor = GREEN; bright = false; break;
+ case ECHO: levelcolor = BLUE; bright = true; break;
+ case DEBUG: levelcolor = BROWN; bright = true; break;
+ case INFO: levelcolor = GRAY; bright = false; break;
+ case WARN: levelcolor = BROWN; bright = false; break;
+ case ERROR: levelcolor = RED; bright = true; break;
+ }
+
+ while(str.indexOf('\n') != -1) {
+ logstream.println(classname + colorize(levelcolor, bright, str.substring(0, str.indexOf('\n'))));
+ classname = logDates ? " " : " ";
+ classname = colorize(GRAY,false,classname);
+ str = str.substring(str.indexOf('\n') + 1);
+ }
+ logstream.println(classname + colorize(levelcolor, bright, str));
+ }
+
+ public static void recursiveLog(String indent, String name, Object o) throws JSExn {
+ if (!name.equals("")) name += " : ";
+
+ if (o == null) {
+ JS.log(indent + name + "<null>");
+
+ } else if (o instanceof JSArray) {
+ JS.log(indent + name + "<array>");
+ JSArray na = (JSArray)o;
+ for(int i=0; i<na.length(); i++)
+ recursiveLog(indent + " ", i + "", na.elementAt(i));
+
+ } else if (o instanceof JS) {
+ JS.log(indent + name + "<object>");
+ JS s = (JS)o;
+ Enumeration e = s.keys();
+ while(e.hasMoreElements()) {
+ Object key = e.nextElement();
+ if (key != null)
+ recursiveLog(indent + " ", key.toString(),
+ (key instanceof Integer) ?
+ s.get(((Integer)key)) : s.get(key.toString()));
+ }
+ } else {
+ JS.log(indent + name + o);
+
+ }
+ }
+
+}
--- /dev/null
+/*
+UserInfo:
+ On start:
+ 0: Addr of CAB/EXE
+ 1: Length of CAB/EXE
+ On Edit:
+ 2: Addr of output_table array
+
+Exit codes:
+ 0: Success
+ 1: Internal Error
+ 2: Invalid CAB
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <sys/fcntl.h>
+
+#include "mspack.h"
+
+#define MAX(a,b) (((a)>(b))?(a):(b))
+#define MIN(a,b) (((a)<(b))?(a):(b))
+#define MAX_MEMBERS 64
+
+char *xstrdup(const char *s) {
+ char *ret = strdup(s);
+ if(ret == NULL) exit(1);
+ return ret;
+}
+
+typedef struct {
+ char *addr;
+ int pos;
+ int size;
+ int length;
+ int writable;
+} mem_buf_t;
+
+static mem_buf_t *cab_mem_buf = NULL;
+
+static void mem_buf_grow(mem_buf_t *buf,size_t newsize) {
+ size_t new_len;
+ char *p;
+ if(buf->length < 0) exit(1);
+ if(newsize <= buf->length) return;
+ new_len = MAX(buf->length ? buf->length*2 : 65536,newsize);
+ p = realloc(buf->addr,new_len);
+ if(p == NULL) exit(1);
+ buf->addr = p;
+ buf->length = new_len;
+}
+
+static struct {
+ char *filename;
+ mem_buf_t buf;
+} write_buf_table[MAX_MEMBERS];
+
+static struct {
+ char *filename;
+ char *data;
+ int length;
+} output_table[MAX_MEMBERS+1];
+
+static struct mspack_file *my_open(struct mspack_system *sys, char *filename, int mode) {
+ mem_buf_t *buf = NULL;
+ int i;
+ if(strcmp(filename,"/dev/cab")==0) {
+ if(mode != MSPACK_SYS_OPEN_READ) return NULL;
+ buf = cab_mem_buf;
+ } else {
+ if(mode != MSPACK_SYS_OPEN_WRITE) return NULL;
+
+ for(i=0;i<MAX_MEMBERS;i++) {
+ if(write_buf_table[i].filename == NULL) {
+ write_buf_table[i].filename = xstrdup(filename);
+ buf = &write_buf_table[i].buf;
+ buf->writable = 1;
+ break;
+ }
+ }
+ }
+
+ return (struct mspack_file *) buf;
+}
+
+static void my_close(struct mspack_file *buf_) {
+ mem_buf_t *buf = (mem_buf_t*) buf_;
+ /* NO OP */
+}
+
+static int my_read(struct mspack_file *buf_, void *out, int count) {
+ mem_buf_t *buf = (mem_buf_t*) buf_;
+ count = MIN(buf->size - buf->pos, count);
+ memcpy(out,buf->addr + buf->pos,count);
+ buf->pos += count;
+ return count;
+}
+
+static int my_write(struct mspack_file *buf_, void *in, int count) {
+ mem_buf_t *buf = (mem_buf_t*) buf_;
+ if(!buf->writable) return -1;
+ if(buf->length < buf->pos + count) mem_buf_grow(buf,buf->pos + count);
+ memcpy(buf->addr+buf->pos,in,count);
+ buf->pos += count;
+ buf->size = MAX(buf->size,buf->pos);
+ return count;
+}
+
+static int my_seek(struct mspack_file *buf_, off_t off, int mode) {
+ mem_buf_t *buf = (mem_buf_t*) buf_;
+ int newpos;
+ switch(mode) {
+ case MSPACK_SYS_SEEK_START: newpos = off; break;
+ case MSPACK_SYS_SEEK_CUR: newpos = buf->pos + off; break;
+ case MSPACK_SYS_SEEK_END: newpos = buf->size - off; break;
+ default: return -1;
+ }
+ if(newpos < 0) return -1;
+ if(newpos > buf->size) {
+ if(!buf->writable) return -1;
+ if(newpos > buf->length)
+ mem_buf_grow(buf,newpos);
+ }
+ buf->pos = newpos;
+ return 0;
+}
+
+static off_t my_tell(struct mspack_file *buf_) {
+ mem_buf_t *buf = (mem_buf_t*) buf_;
+ return buf ? buf->pos : 0;
+}
+
+// FEATURE: Remove this to possibly avoid pulling in stdio from libc
+// (it may be getting pulled in anyway from malloc or something)
+static void my_message(struct mspack_file *file, char *format, ...) {
+ va_list ap;
+ va_start(ap, format);
+ vfprintf(stderr, format, ap);
+ va_end(ap);
+ fputc((int) '\n', stderr);
+ fflush(stderr);
+}
+
+static void *my_alloc(struct mspack_system *sys, size_t size) { return malloc(size); }
+static void my_free(void *p) { free(p); }
+static void my_copy(void *src, void *dest, size_t bytes) { memcpy(dest, src, bytes); }
+
+static struct mspack_system my_system = {
+ &my_open,
+ &my_close,
+ &my_read,
+ &my_write,
+ &my_seek,
+ &my_tell,
+ &my_message,
+ &my_alloc,
+ &my_free,
+ &my_copy,
+ NULL
+};
+
+extern char *user_info[1024];
+
+int mspack_main() {
+ struct mscab_decompressor *decomp;
+ struct mscabd_cabinet *cab;
+ struct mscabd_file *file;
+ mem_buf_t mem_buf;
+ size_t size = (size_t)user_info[1];
+ int i;
+
+ mem_buf.addr = user_info[0];
+ mem_buf.pos = mem_buf.writable = 0;
+ mem_buf.length = -1;
+ mem_buf.size = size;
+
+ cab_mem_buf = &mem_buf;
+
+ decomp = mspack_create_cab_decompressor(&my_system);
+ if(!decomp) exit(1);
+
+ cab = decomp->search(decomp,"/dev/cab");
+ if(!cab) exit(2);
+
+ for(file = cab->files;file;file=file->next)
+ decomp->extract(decomp,file,file->filename);
+
+ decomp->close(decomp,cab);
+ mspack_destroy_cab_decompressor(decomp);
+
+ for(i=0;i<MAX_MEMBERS && write_buf_table[i].filename;i++) {
+ output_table[i].filename = write_buf_table[i].filename;
+ output_table[i].data = write_buf_table[i].buf.addr;
+ output_table[i].length = write_buf_table[i].buf.size;
+ }
+
+ user_info[2] = (char*) output_table;
+
+ return 0;
+}
--- /dev/null
+package org.ibex.util;
+
+import org.ibex.core.Main;
+import org.ibex.util.*;
+import org.xwt.mips.*;
+import java.io.*;
+
+import org.xwt.mips.Runtime;
+
+public class MSPack {
+ private static byte[] image;
+
+ private String[] fileNames;
+ private int[] lengths;
+ private byte[][] data;
+
+ public static class MSPackException extends IOException { public MSPackException(String s) { super(s); } }
+
+ public MSPack(InputStream cabIS) throws IOException {
+ try {
+ Runtime vm = (Runtime)Class.forName("org.ibex.util.MIPSApps").newInstance();
+ byte[] cab = InputStreamToByteArray.convert(cabIS);
+ int cabAddr = vm.sbrk(cab.length);
+ if(cabAddr < 0) throw new MSPackException("sbrk failed");
+
+ vm.copyout(cab,cabAddr,cab.length);
+
+ vm.setUserInfo(0,cabAddr);
+ vm.setUserInfo(1,cab.length);
+
+ int status = vm.run(new String[]{ "mspack"} );
+ if(status != 0) throw new MSPackException("mspack.mips failed (" + status + ")");
+
+ /*static struct {
+ char *filename;
+ char *data;
+ int length;
+ } output_table[MAX_MEMBERS+1]; */
+
+ int filesTable = vm.getUserInfo(2);
+ int count=0;
+ while(vm.memRead(filesTable+count*12) != 0) count++;
+
+ fileNames = new String[count];
+ data = new byte[count][];
+ lengths = new int[count];
+
+ for(int i=0,addr=filesTable;i<count;i++,addr+=12) {
+ int length = vm.memRead(addr+8);
+ data[i] = new byte[length];
+ lengths[i] = length;
+ fileNames[i] = vm.cstring(vm.memRead(addr));
+ System.out.println("" + fileNames[i]);
+ vm.copyin(vm.memRead(addr+4),data[i],length);
+ }
+ } catch(Runtime.ExecutionException e) {
+ e.printStackTrace();
+ throw new MSPackException("mspack.mips crashed");
+ } catch(Exception e) {
+ throw new MSPackException(e.toString());
+ }
+ }
+
+ public String[] getFileNames() { return fileNames; }
+ public int[] getLengths() { return lengths; }
+ public InputStream getInputStream(int index) {
+ return new KnownLength.KnownLengthInputStream(new ByteArrayInputStream(data[index]), data[index].length);
+ }
+ public InputStream getInputStream(String fileName) {
+ for(int i=0;i<fileNames.length;i++) {
+ if(fileName.equalsIgnoreCase(fileNames[i])) return getInputStream(i);
+ }
+ return null;
+ }
+
+ public static void main(String[] args) throws IOException {
+ MSPack pack = new MSPack(new FileInputStream(args[0]));
+ String[] files = pack.getFileNames();
+ for(int i=0;i<files.length;i++)
+ System.out.println(i + ": " + files[i] + ": " + pack.getLengths()[i]);
+ System.out.println("Writing " + files[files.length-1]);
+ InputStream is = pack.getInputStream(files.length-1);
+ OutputStream os = new FileOutputStream(files[files.length-1]);
+ int n;
+ byte[] buf = new byte[4096];
+ while((n = is.read(buf)) != -1) os.write(buf,0,n);
+ os.close();
+ is.close();
+ }
+}
+
--- /dev/null
+package org.ibex.util;
+import java.util.*;
+import java.io.*;
+import java.util.zip.*;
+import org.apache.bcel.*;
+import org.apache.bcel.generic.*;
+import org.apache.bcel.classfile.*;
+import org.apache.bcel.util.*;
+
+public class NanoGoat {
+
+ public static final boolean deleteMethods = false;
+ public static SyntheticRepository repo = null;
+ public static HashSet dest = new HashSet();
+ public static HashSet constructed = new HashSet();
+ public static String outdir = ".";
+ public static Hashtable subclasses = new Hashtable();
+ public static Hashtable uponconstruction = new Hashtable();
+ public static Hashtable mark_if_constructed = new Hashtable();
+ public static int level = 0;
+
+ public NanoGoat() { }
+
+ public void loadAllMethods(String classname) throws Exception {
+ visitJavaClass(repo.loadClass(classname));
+ Method[] meths = getMethods(repo.loadClass(classname));
+ for(int i=0; i<meths.length; i++)
+ visitJavaMethod(repo.loadClass(classname), meths[i]);
+ }
+
+ public void loadAllStaticMethods(String classname) throws Exception {
+ visitJavaClass(repo.loadClass(classname));
+ Method[] meths = getMethods(repo.loadClass(classname));
+ for(int i=0; i<meths.length; i++)
+ if (meths[i].isStatic())
+ visitJavaMethod(repo.loadClass(classname), meths[i]);
+ }
+
+ public void loadMethod(String classAndMethodName) throws Exception {
+ String classname = classAndMethodName.substring(0, classAndMethodName.lastIndexOf('.'));
+ String methodname = classAndMethodName.substring(classAndMethodName.lastIndexOf('.') + 1);
+ if (classname.endsWith("." + methodname)) methodname = "<init>";
+ visitJavaClass(repo.loadClass(classname));
+ Method[] meths = getMethods(repo.loadClass(classname));
+ for(int i=0; i<meths.length; i++)
+ if (meths[i].getName().equals(methodname))
+ visitJavaMethod(repo.loadClass(classname), meths[i]);
+ }
+ public static void main(String[] args) throws Exception {
+ int start = 1;
+ repo = SyntheticRepository.getInstance(new ClassPath(args[0]));
+
+ NanoGoat bcp = new NanoGoat();
+ BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
+ for(String s = br.readLine(); s != null; s = br.readLine()) {
+ s = s.trim();
+ if (s.length() == 0) continue;
+ try {
+ if (s.endsWith("$")) s = s.substring(0, s.length() - 1);
+ if (s.endsWith(".class")) {
+ bcp.visitJavaClass(repo.loadClass(s.substring(0, s.length() - 6)));
+ } else {
+ JavaClass cl = repo.loadClass(s.substring(0, s.lastIndexOf('.')));;
+ bcp.visitJavaClass(cl);
+ bcp.loadMethod(s);
+ Field[] fields = cl.getFields();
+ for(int j=0; j<fields.length; j++) {
+ if (fields[j].getName().equals(s.substring(s.lastIndexOf('.') + 1)))
+ bcp.visitJavaField(fields[j], cl);
+ }
+ }
+ } catch (Exception e) {
+ System.out.println("WARNING: couldn't load class for " + s);
+ e.printStackTrace();
+ }
+ }
+
+ System.out.println("\n\n======================================================================\n");
+
+ // we call start(), but the VM calls run()...
+ bcp.loadMethod("java.lang.Thread.run");
+ bcp.loadAllMethods("java.lang.SecurityContext");
+ bcp.loadAllMethods("java.lang.ThreadDeath");
+ bcp.loadMethod("java.lang.Thread.run"); // we call start(), but the VM calls run()...
+ bcp.loadMethod("java.lang.ref.Reference.enqueue"); // the GC calls this directly
+ bcp.loadAllMethods("gnu.gcj.runtime.StringBuffer"); // the compiler emits calls directly to this class
+ bcp.loadAllMethods("gnu.gcj.convert.Input_UTF8"); // retrieved via reflection
+ bcp.loadAllMethods("gnu.gcj.convert.Output_UTF8"); // retrieved via reflection
+ bcp.loadMethod("gnu.gcj.convert.BytesToUnicode.done"); // called by natString
+ bcp.loadAllStaticMethods("java.lang.reflect.Modifier"); // used all over natClass...
+
+ // the Interpreter.run() method's switchblock is too complex...
+ bcp.loadAllMethods("org.ibex.js.Interpreter$TryMarker");
+ bcp.loadAllMethods("org.ibex.js.Interpreter$CatchMarker");
+ bcp.loadAllMethods("org.ibex.js.Interpreter$LoopMarker");
+ bcp.loadAllMethods("org.ibex.js.Interpreter$FinallyData");
+ bcp.loadAllMethods("org.ibex.js.Interpreter$CallMarker");
+ bcp.loadAllMethods("org.ibex.js.Interpreter");
+ bcp.loadAllMethods("org.ibex.js.Interpreter$1");
+ bcp.loadAllMethods("org.ibex.js.Interpreter$Stub");
+ bcp.loadAllMethods("org.ibex.js.Trap$TrapScope");
+ bcp.loadMethod("org.ibex.js.JSScope.top");
+ bcp.loadAllMethods("org.ibex.Picture$1");
+ bcp.loadAllMethods("org.ibex.Ibex$Blessing");
+ bcp.loadAllMethods("org.ibex.util.SSL$entropySpinner");
+ bcp.loadAllMethods("org.ibex.HTTP$HTTPInputStream");
+ bcp.visitJavaClass(repo.loadClass("org.ibex.util.SSL"));
+
+ bcp.loadAllMethods("java.util.Hashtable$HashIterator");
+ bcp.loadMethod("java.util.SimpleTimeZone.useDaylightTime");
+ bcp.visitJavaClass(repo.loadClass("gnu.gcj.runtime.FinalizerThread"));
+ bcp.visitJavaClass(repo.loadClass("gnu.gcj.runtime.FirstThread"));
+
+ // to ensure we get all the stuff that might be called from CNI
+ bcp.loadAllMethods("org.ibex.plat.Linux");
+ bcp.loadAllMethods("org.ibex.plat.X11");
+ bcp.loadAllMethods("org.ibex.plat.GCJ");
+ bcp.loadAllMethods("org.ibex.plat.POSIX");
+ bcp.loadAllMethods("org.ibex.plat.X11$X11Surface");
+ bcp.loadAllMethods("org.ibex.plat.X11$X11PixelBuffer");
+ bcp.loadAllMethods("org.ibex.plat.X11$X11Picture");
+ bcp.loadAllMethods("org.ibex.Surface");
+ bcp.loadAllMethods("org.ibex.Picture");
+ bcp.loadAllMethods("org.ibex.PixelBuffer");
+
+ // primary entry point
+ bcp.loadMethod("org.ibex.plat.Linux.main");
+ System.out.println();
+
+ System.out.println("Dumping...");
+ ZipFile zf = new ZipFile(args[0]);
+ ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(args[0] + ".tmp"));
+ Enumeration e = zf.entries();
+ while(e.hasMoreElements()) {
+ ZipEntry ze = ((ZipEntry)e.nextElement());
+ String ss = ze.getName();
+ if (!ss.endsWith(".class")) continue;
+ ss = ss.substring(0, ss.length() - 6);
+ ss = ss.replace('/', '.');
+ dump(repo.loadClass(ss), zos);
+ }
+ zos.close();
+ zf.close();
+ new File(args[0] + ".tmp").renameTo(new File(args[0] + ".pruned"));
+ }
+
+ public static void dump(JavaClass clazz, ZipOutputStream zos) throws Exception {
+ if (!dest.contains(clazz)) return;
+
+ ConstantPoolGen newcpg = new ConstantPoolGen(clazz.getConstantPool());
+ ClassGen cg = new ClassGen(clazz);
+ InstructionFactory factory = new InstructionFactory(cg, newcpg);
+ cg.setMajor(46);
+ cg.setMinor(0);
+ cg.setConstantPool(newcpg);
+
+ boolean isconstructed = false;
+ Method[] methods = getMethods(clazz);
+ for(int i=0; i<methods.length; i++)
+ if (dest.contains(methods[i]) && methods[i].getName().equals("<init>"))
+ isconstructed = true;
+
+ // we can only prune static fields (to avoid altering object layout, which is hardcoded into
+ // CNI code), but that's okay since instance fields don't contribute to binary size
+ Field[] fields = clazz.getFields();
+ for(int i=0; i<fields.length; i++) {
+ if ((!dest.contains(fields[i]) && fields[i].isStatic()) ||
+ ((!(constructed.contains(clazz))) && !fields[i].isStatic())) {
+ System.out.println(" pruning field " + clazz.getClassName() + "." + fields[i].getName());
+ // FIXME this confuses gcj in jar-at-a-time mode
+ //cg.removeField(fields[i]);
+ }
+ }
+
+ int numMethods = 0;
+ boolean good = false;
+ for(int i=0; i<methods.length; i++) {
+ if (dest.contains(methods[i]) && (isconstructed || methods[i].isStatic())) {
+ good = true;
+ } else {
+ if (methods[i].getCode() == null) {
+ System.out.println(" empty codeblock: " + clazz.getClassName() + "." + methods[i].getName());
+ } else {
+ System.out.println(" pruning " +(isconstructed?"":"unconstructed")+ " method " +
+ clazz.getClassName() + "." + methods[i].getName());
+ if (deleteMethods) { cg.removeMethod(methods[i]); continue; }
+ MethodGen mg = new MethodGen(methods[i], clazz.getClassName(), newcpg);
+ mg.removeExceptions();
+ InstructionList il = new InstructionList();
+ mg.setInstructionList(il);
+ InstructionHandle ih_0 = il.append(factory.createNew("java.lang.UnsatisfiedLinkError"));
+ il.append(InstructionConstants.DUP);
+ il.append(factory.createInvoke("java.lang.UnsatisfiedLinkError",
+ "<init>", Type.VOID, Type.NO_ARGS, Constants.INVOKESPECIAL));
+ il.append(InstructionConstants.ATHROW);
+ mg.setMaxStack();
+ mg.setMaxLocals();
+ mg.removeExceptions();
+ mg.removeLocalVariables();
+ mg.removeExceptionHandlers();
+ mg.removeLineNumbers();
+ cg.replaceMethod(methods[i], mg.getMethod());
+ il.dispose();
+ }
+ }
+ }
+
+ // FIXME: chain up to superclass' <clinit>... that might remove the need for this hack
+ // FIXME: gcj compiling in jar-at-a-time mode can't be convinced to let classes outside the jar override
+ // the ones inside the jar
+ good = true;
+
+ if (!good && !clazz.isAbstract() && !clazz.isInterface()) {
+ System.out.println("DROPPING " + clazz.getClassName());
+ JavaClass[] ifaces = clazz.getInterfaces();
+ String[] ifacestrings = new String[ifaces.length];
+ for(int i=0; i<ifaces.length; i++) ifacestrings[i] = ifaces[i].getClassName();
+ cg = new ClassGen(clazz.getClassName(),
+ clazz.getSuperClass().getClassName(),
+ clazz.getFileName(),
+ clazz.getAccessFlags(),
+ ifacestrings,
+ newcpg);
+ } else {
+ System.out.println("dumping " + clazz.getClassName());
+ }
+ FilterOutputStream noclose = new FilterOutputStream(zos) { public void close() throws IOException { flush(); } };
+ zos.putNextEntry(new ZipEntry(clazz.getClassName().replace('.', '/')+".class"));
+ cg.getJavaClass().dump(noclose);
+ noclose.flush();
+ }
+
+ public JavaClass sig2class(String sig) throws Exception {
+ if (sig == null) return null;
+ while (sig.length() > 0 && (sig.charAt(0) == 'L' || sig.charAt(0) == '[')) {
+ if (sig.charAt(0) == 'L') sig = sig.substring(1, sig.length() - 1);
+ else if (sig.charAt(0) == '[') sig = sig.substring(1, sig.length());
+ }
+ if (sig.length() <= 1) return null;
+ if (sig.equals("<null object>")) return null;
+ if (sig.startsWith("<return address")) return null;
+ return repo.loadClass(sig);
+ }
+ public void load(String sig) throws Exception {
+ if (sig == null) return;
+ while (sig.length() > 0 && (sig.charAt(0) == 'L' || sig.charAt(0) == '[')) {
+ if (sig.charAt(0) == 'L') sig = sig.substring(1, sig.length() - 1);
+ else if (sig.charAt(0) == '[') sig = sig.substring(1, sig.length());
+ }
+ if (sig.length() <= 1) return;
+ if (sig.equals("<null object>")) return;
+ if (sig.startsWith("<return address")) return;
+ visitJavaClass(repo.loadClass(sig));
+ }
+ public void load(Type t) throws Exception {
+ if (t == null) return;
+ if (t instanceof ArrayType) load(((ArrayType)t).getElementType());
+ if (!(t instanceof ObjectType)) return;
+ load(((ObjectType)t).getClassName());
+ }
+
+ public String getMethodSignature(Method m, ConstantPoolGen cpg) throws Exception { return m.getName() + m.getSignature(); }
+ public String getMethodSignature(InvokeInstruction ii, ConstantPoolGen cpg) throws Exception {
+ String sig = "";
+ Type[] argtypes = ii.getArgumentTypes(cpg);
+ for(int j=0; j<argtypes.length; j++) sig += argtypes[j].getSignature();
+ return ii.getMethodName(cpg) + "(" + sig + ")" + ii.getReturnType(cpg).getSignature();
+ }
+
+ public void visitJavaMethod(JavaClass jc, Method method) throws Exception {
+ visitJavaClass(jc);
+ if (jc.getClassName().indexOf("SharedLib") != -1) return;
+ if (jc.getClassName().indexOf("Datagram") != -1) return;
+ if (jc.getClassName().startsWith("java.io.Object")) return;
+ if (jc.getClassName().startsWith("java.util.jar.")) return;
+ if (jc.getClassName().startsWith("java.net.Inet6")) return;
+
+ // gcj bug; gcj can't compile this method from a .class file input; I have no idea why
+ if (jc.getClassName().equals("java.lang.System") && method.getName().equals("runFinalizersOnExit")) return;
+
+ // we know these can't be constructed
+ if (method.getName().equals("<init>") && jc.getClassName().startsWith("java.lang.reflect.")) return;
+
+ if (dest.contains(method)) return;
+ dest.add(method);
+
+ if (method.getName().equals("<clinit>") && jc.getSuperClass() != null)
+ loadMethod(jc.getSuperClass().getClassName() + ".<clinit>");
+
+ if (method.isStatic() || method.getName().equals("<init>")) loadMethod(jc.getClassName() + ".<clinit>");
+ if (method.getName().equals("<init>")) {
+ // FIXME: generalize to all perinstancemethods
+ constructed.add(jc);
+ HashSet hs = (HashSet)uponconstruction.get(jc);
+ if (hs != null) {
+ Iterator it = hs.iterator();
+ while(it.hasNext()) visitJavaMethod(jc, (Method)it.next());
+ }
+ loadMethod(jc.getClassName() + ".equals");
+ loadMethod(jc.getClassName() + ".hashCode");
+ loadMethod(jc.getClassName() + ".toString");
+ loadMethod(jc.getClassName() + ".finalize");
+ loadMethod(jc.getClassName() + ".clone");
+ }
+
+ ConstantPoolGen cpg = new ConstantPoolGen(method.getConstantPool());
+ if (!method.isStatic() && !constructed.contains(jc)) {
+ HashSet hs = (HashSet)uponconstruction.get(jc);
+ if (hs == null) uponconstruction.put(jc, hs = new HashSet());
+ hs.add(method);
+ markMethodInSubclasses(jc, method, cpg);
+ dest.remove(method);
+ return;
+ }
+
+ level += 2;
+ for(int i=0; i<level; i++) System.out.print(" ");
+ System.out.print(jc.getClassName() + "." + getMethodSignature(method, cpg));
+ markMethodInSubclasses(jc, method, cpg);
+ if (method.getCode() == null) { System.out.println(); level -= 2; return; }
+ byte[] code = method.getCode().getCode();
+ InstructionList il = new InstructionList(code);
+ InstructionHandle[] instructions = il.getInstructionHandles();
+ System.out.println(" [" + instructions.length + " instructions]");
+ for(int i=0; i<instructions.length; i++){
+ Instruction instr = instructions[i].getInstruction();;
+ if (instr instanceof Select) {
+ InstructionHandle[] ih2 = ((Select)instr).getTargets();
+ InstructionHandle[] ih3 = new InstructionHandle[instructions.length + ih2.length];
+ System.arraycopy(instructions, 0, ih3, 0, instructions.length);
+ System.arraycopy(ih2, 0, ih3, instructions.length, ih2.length);
+ instructions = ih3;
+ }
+ if (instr instanceof LoadClass) {
+ ObjectType ot = (ObjectType)((LoadClass)instr).getLoadClassType(cpg);
+ if (ot != null) loadMethod(ot.getClassName() + ".<clinit>");
+ }
+ if (instr instanceof CPInstruction) load(((CPInstruction)instr).getType(cpg));
+ if (instr instanceof TypedInstruction) load(((TypedInstruction)instr).getType(cpg));
+ if (instr instanceof NEW) loadMethod(((NEW)instr).getLoadClassType(cpg).getClassName() + ".<init>");
+ if (instr instanceof org.apache.bcel.generic.FieldOrMethod)
+ load(((org.apache.bcel.generic.FieldOrMethod)instr).getClassType(cpg));
+ if (instr instanceof org.apache.bcel.generic.FieldInstruction) {
+ load(((org.apache.bcel.generic.FieldInstruction)instr).getFieldType(cpg));
+ load(((org.apache.bcel.generic.FieldInstruction)instr).getType(cpg));
+ String fieldName = ((org.apache.bcel.generic.FieldInstruction)instr).getFieldName(cpg);
+ JavaClass jc2 = repo.loadClass(((ObjectType)((org.apache.bcel.generic.FieldInstruction)instr).
+ getLoadClassType(cpg)).getClassName());
+ Field[] fields = jc2.getFields();
+ for(int j=0; j<fields.length; j++) if (fields[j].getName().equals(fieldName)) visitJavaField(fields[j], jc2);
+ }
+ if (instr instanceof InvokeInstruction) {
+ InvokeInstruction ii = (InvokeInstruction)instr;
+ String ii_sig = getMethodSignature(ii, cpg);
+ JavaClass c = sig2class(ii.getLoadClassType(cpg).getSignature());
+
+ load(ii.getType(cpg));
+ Method[] meths = getMethods(c);
+ boolean good = false;
+ for(int i2=0; i2<meths.length; i2++) {
+ if (getMethodSignature(meths[i2], cpg).equals(ii_sig)) {
+ visitJavaMethod(c, meths[i2]);
+ good = true;
+ break;
+ }
+ }
+ if (!good) throw new Exception("couldn't find method " + getMethodSignature(ii, cpg) + " in " + c.getClassName());
+ }
+ }
+ Type[] argtypes = method.getArgumentTypes();
+ for(int i=0; i<argtypes.length; i++) load(argtypes[i]);
+ if (method.getExceptionTable() != null) {
+ String[] exntypes = method.getExceptionTable().getExceptionNames();
+ for(int i=0; i<exntypes.length; i++) load(exntypes[i]);
+ }
+ level -= 2;
+ }
+
+ public void visitJavaField(Field field, JavaClass clazz) throws Exception {
+ if (dest.contains(field)) return;
+ dest.add(field);
+ if (field.isStatic()) loadMethod(clazz.getClassName() + ".<clinit>");
+ }
+
+ public void visitJavaClass(JavaClass clazz) throws Exception {
+ if (dest.contains(clazz)) return;
+ dest.add(clazz);
+
+ ConstantPoolGen cpg = new ConstantPoolGen(clazz.getConstantPool());
+ level += 2;
+ for(int i=0; i<level; i++) System.out.print(" ");
+ System.out.println(clazz.getClassName() + ".class");
+
+ JavaClass superclass = clazz.getSuperClass();
+ for(JavaClass sup = superclass; sup != null; sup = sup.getSuperClass()) {
+ if (subclasses.get(sup) == null) subclasses.put(sup, new HashSet());
+ ((HashSet)subclasses.get(sup)).add(clazz);
+ }
+ JavaClass[] interfaces = clazz.getAllInterfaces();
+ for(int i=0; i<interfaces.length; i++) {
+ if (subclasses.get(interfaces[i]) == null) subclasses.put(interfaces[i], new HashSet());
+ ((HashSet)subclasses.get(interfaces[i])).add(clazz);
+ }
+
+ for(JavaClass sup = superclass; sup != null; sup = sup.getSuperClass()) {
+ visitJavaClass(sup);
+ remarkMethods(sup, clazz, cpg);
+ }
+ for(int i=0; i<interfaces.length; i++) {
+ visitJavaClass(interfaces[i]);
+ remarkMethods(interfaces[i], clazz, cpg);
+ }
+
+ Field[] fields = clazz.getFields();
+ for(int i=0; i<fields.length; i++) {
+ if (!fields[i].isStatic()) visitJavaField(fields[i], clazz);
+ else {
+ Type t = fields[i].getType();
+ if (t instanceof ObjectType) load(t);
+ }
+ }
+ level -= 2;
+ }
+
+ public void markMethodInSubclasses(JavaClass c, Method m, JavaClass subclass, ConstantPoolGen cpg) throws Exception {
+ if (m.isStatic()) return;
+ if (m.getName().equals("<init>")) return;
+ if (m.getName().equals("equals")) return;
+ if (m.getName().equals("hashCode")) return;
+ if (m.getName().equals("clone")) return;
+ if (m.getName().equals("finalize")) return;
+ if (m.getName().equals("toString")) return;
+ String sig = getMethodSignature(m, cpg);
+ Method[] submethods = getMethods(subclass);
+ for(int j=0; j<submethods.length; j++)
+ if (getMethodSignature(submethods[j], cpg).equals(sig))
+ visitJavaMethod(subclass, submethods[j]);
+ }
+ public void markMethodInSubclasses(JavaClass c, Method m, ConstantPoolGen cpg) throws Exception {
+ if (m.isStatic()) return;
+ if (m.getName().equals("<init>")) return;
+ HashSet s = (HashSet)subclasses.get(c);
+ if (s == null) return;
+ Object[] subclasses = s.toArray();
+ for(int i=0; i<subclasses.length; i++) {
+ JavaClass subclass = (JavaClass)subclasses[i];
+ if (subclass == c) continue;
+ markMethodInSubclasses(c, m, subclass, cpg);
+ }
+ }
+
+ public void remarkMethods(JavaClass c, ConstantPoolGen cpg) throws Exception {
+ Method[] meths =getMethods(c);
+ for(int j=0; j<meths.length; j++)
+ if (dest.contains(meths[j]) ||
+ (uponconstruction.get(c) != null && ((HashSet)uponconstruction.get(c)).contains(meths[j])))
+ markMethodInSubclasses(c, meths[j], cpg);
+ }
+
+ public void remarkMethods(JavaClass c, JavaClass target, ConstantPoolGen cpg) throws Exception {
+ Method[] meths = getMethods(c);
+ for(int j=0; j<meths.length; j++)
+ if (dest.contains(meths[j]) ||
+ (uponconstruction.get(c) != null && ((HashSet)uponconstruction.get(c)).contains(meths[j])))
+ markMethodInSubclasses(c, meths[j], target, cpg);
+ }
+
+ public static Hashtable methodsHashtable = new Hashtable();
+ public static Method[] getMethods(JavaClass c) {
+ Method[] ret = (Method[])methodsHashtable.get(c);
+ if (ret == null) methodsHashtable.put(c, ret = c.getMethods());
+ return ret;
+ }
+
+}
--- /dev/null
+// Copyright (C) 2003 Adam Megacz <adam@ibex.org> all rights reserved.
+//
+// You may modify, copy, and redistribute this code under the terms of
+// the GNU Library Public License version 2.1, with the exception of
+// the portion of clause 6a after the semicolon (aka the "obnoxious
+// relink clause")
+
+package org.ibex.util;
+
+/** packs 8-bit bytes into a String of 7-bit chars (to avoid the UTF-8 non-ASCII penalty) */
+public class PackBytesIntoString {
+
+ public static String pack(byte[] b, int off, int len) throws IllegalArgumentException {
+ if (len % 7 != 0) throw new IllegalArgumentException("len must be a multiple of 7");
+ StringBuffer ret = new StringBuffer();
+ for(int i=off; i<off+len; i += 7) {
+ long l = 0;
+ for(int j=6; j>=0; j--) {
+ l <<= 8;
+ l |= (b[i + j] & 0xff);
+ }
+ for(int j=0; j<8; j++) {
+ ret.append((char)(l & 0x7f));
+ l >>= 7;
+ }
+ }
+ return ret.toString();
+ }
+
+ public static byte[] unpack(String s) throws IllegalArgumentException {
+ if (s.length() % 8 != 0) throw new IllegalArgumentException("string length must be a multiple of 8");
+ byte[] ret = new byte[(s.length() / 8) * 7];
+ for(int i=0; i<s.length(); i += 8) {
+ long l = 0;
+ for(int j=7; j>=0; j--) {
+ l <<= 7;
+ l |= (s.charAt(i + j) & 0x7fL);
+ }
+ for(int j=0; j<7; j++) {
+ ret[(i / 8) * 7 + j] = (byte)(l & 0xff);
+ l >>= 8;
+ }
+ }
+ return ret;
+ }
+}
+
--- /dev/null
+// Copyright (C) 2003 Adam Megacz <adam@ibex.org> all rights reserved.
+//
+// You may modify, copy, and redistribute this code under the terms of
+// the GNU Library Public License version 2.1, with the exception of
+// the portion of clause 6a after the semicolon (aka the "obnoxious
+// relink clause")
+
+package org.ibex.util;
+
+import gnu.regexp.*;
+import java.util.*;
+import java.io.*;
+
+/**
+ * A VERY crude, inefficient Java preprocessor
+ *
+ * //#define FOO bar baz -- replace all instances of token FOO with "bar baz"
+ * //#replace foo/bar baz/bop -- DUPLICATE everything between here and //#end,
+ * replacing foo with bar and baz with bop in the *second* copy
+ * //#switch(EXPR) -- switch on strings
+ * case "case1":
+ * //#end
+ *
+ * Replacements are done on a token basis. Tokens are defined as a
+ * sequence of characters which all belong to a single class. The
+ * two character classes are:
+ *
+ * - [a-zA-Z0-9_]
+ * - all other non-whitespace characters
+ */
+public class Preprocessor {
+
+ public static String replaceAll(String source, String regexp, String replaceWith) {
+ try {
+ RE re = new RE(regexp, 0, RESyntax.RE_SYNTAX_PERL5);
+ return (String)re.substituteAll(source, replaceWith);
+ } catch (Exception e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
+ BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
+
+ // process stdin to stdout
+ Preprocessor cc = new Preprocessor(br, bw);
+ Vector err = cc.process();
+ bw.flush();
+
+ // handle errors
+ boolean errors = false;
+ for (int i=0; i < err.size(); i++) { if (err.get(i) instanceof Error) errors = true; System.err.println(err.get(i)); }
+ if (errors) throw new Exception();
+ }
+
+ private Reader r;
+ private Writer w;
+ private LineNumberReader in;
+ private PrintWriter out;
+
+ private Hashtable replace = new Hashtable();
+ private Hashtable repeatreplace = null;
+ private Vector sinceLastRepeat = null;
+ private Vector err = new Vector();
+
+ private int enumSwitch = 0; // number appended to variable used in switch implementation
+
+
+ public Preprocessor(Reader reader, Writer writer) {
+ setReader(reader);
+ setWriter(writer);
+ }
+
+ public void setReader(Reader reader) { r = reader; if (r != null) in = new LineNumberReader(r); }
+ public Reader getReader() { return r; }
+
+ public void setWriter(Writer writer) { w = writer; if (w != null) out = new PrintWriter(w); }
+ public Writer getWriter() { return w; }
+
+
+ /** process data from reader, write to writer, return vector of errors */
+ public Vector process() throws IOException {
+ err.clear();
+
+ String s = null;
+PROCESS:
+ while((s = in.readLine()) != null) {
+ if (sinceLastRepeat != null) sinceLastRepeat.addElement(s);
+ String trimmed = s.trim();
+
+ if (trimmed.startsWith("//#define ")) {
+ if (trimmed.length() == 9 || trimmed.charAt(9) != ' ') {
+ err.add(new Error("#define badly formed, ignored")); continue PROCESS;
+ }
+ int keyStart = indexOfNotWS(trimmed, 9);
+ if (keyStart == -1) {
+ err.add(new Error("#define requires KEY")); continue PROCESS;
+ }
+ int keyEnd = indexOfWS(trimmed, keyStart);
+
+ int macroStart = trimmed.indexOf('(');
+ int macroEnd = trimmed.indexOf(')');
+ if (macroStart > keyEnd) {
+ // no macro is defined, just make sure something dumb like KEYNA)ME hasn't been done
+ if (macroEnd < keyEnd) { err.add(new Error("#define key contains invalid char: ')'")); continue PROCESS; }
+ macroStart = macroEnd = -1;
+ }
+
+ if (macroStart == 0) {
+ err.add(new Error("#define macro requires name")); continue PROCESS;
+ } else if (macroStart > 0) {
+ if (macroStart > macroEnd) { err.add(new Error("#define macro badly formed")); continue PROCESS; }
+ if (macroStart+1 == macroEnd) { err.add(new Error("#define macro requires property name")); continue PROCESS; }
+
+ JSFunctionMacro fm = new JSFunctionMacro();
+ String key = trimmed.substring(keyStart, macroStart);
+ String unbound = trimmed.substring(macroStart +1, macroEnd);
+ int unboundDiv = unbound.indexOf(',');
+ if (unboundDiv == -1) {
+ fm.unbound1 = unbound;
+ } else {
+ fm.unbound1 = unbound.substring(0, unboundDiv);
+ fm.unbound2 = unbound.substring(unboundDiv +1);
+ if (fm.unbound1.length() == 0) { err.add(new Error("#define macro property 1 requires name")); continue PROCESS; }
+ if (fm.unbound2.length() == 0) { err.add(new Error("#define macro property 1 requires name")); continue PROCESS; }
+ }
+ fm.expression = trimmed.substring(keyEnd).trim();
+ replace.put(key, fm);
+ } else {
+ String key = trimmed.substring(keyStart, keyEnd);
+ String val = trimmed.substring(keyEnd).trim();
+ replace.put(key, val);
+ }
+ out.print("\n"); // preserve line numbers
+
+ } else if (trimmed.startsWith("//#repeat ")) {
+ trimmed = trimmed.substring(9);
+ while(trimmed.charAt(trimmed.length() - 1) == '\\') {
+ String s2 = in.readLine().trim();
+ if (s2.startsWith("//")) s2 = s2.substring(2).trim();
+ trimmed = trimmed.substring(0, trimmed.length() - 1) + " " + s2;
+ out.print("\n"); // preserve line numbers
+ }
+ StringTokenizer st = new StringTokenizer(trimmed, " ");
+ repeatreplace = (Hashtable)replace.clone();
+ while (st.hasMoreTokens()) {
+ String tok = st.nextToken().trim();
+ String key = tok.substring(0, tok.indexOf('/'));
+ String val = tok.substring(tok.indexOf('/') + 1);
+ repeatreplace.put(key, val);
+ }
+ sinceLastRepeat = new Vector();
+ out.print("\n"); // preserve line numbers
+
+ } else if (trimmed.startsWith("//#end")) {
+ if (sinceLastRepeat == null) { err.add(new Warning("#end orphaned")); continue PROCESS; }
+ Hashtable save = replace;
+ replace = repeatreplace;
+ out.print("\n");
+ for(int i=0; i<sinceLastRepeat.size() - 1; i++) out.print(processLine((String)sinceLastRepeat.elementAt(i), true));
+ sinceLastRepeat = null;
+ replace = save;
+
+ } else if (trimmed.startsWith("//#switch")) {
+ int expStart = trimmed.indexOf('(') +1;
+ if (expStart < 1) { err.add(new Error("expected ( in #switch")); continue PROCESS; }
+ int expEnd = trimmed.lastIndexOf(')');
+ if (expEnd == -1) { err.add(new Error("expected ) in #switch")); continue PROCESS; }
+ if (expEnd - expStart <= 1) { err.add(new Error("badly formed #switch statement")); continue PROCESS; }
+ String expr = trimmed.substring(expStart, expEnd);
+
+ out.print("final String ccSwitch"+enumSwitch+" = (String)("+expr+"); ");
+ out.print("SUCCESS:do { switch(ccSwitch"+enumSwitch+".length()) {\n");
+
+ Hashtable[] byLength = new Hashtable[255];
+ String key = null;
+ String Default = null;
+ for(trimmed = in.readLine().trim(); !trimmed.startsWith("//#end"); trimmed = in.readLine().trim()) {
+ if (trimmed.startsWith("default:")) {
+ Default = processLine(trimmed.substring(8), false);
+ continue;
+ }
+ if (trimmed.startsWith("case ")) {
+ // find key
+ int strStart = trimmed.indexOf('\"') +1;
+ if (strStart < 1) { err.add(new Error("expected opening of String literal")); continue PROCESS; }
+ int strEnd = trimmed.indexOf('\"', strStart);
+ if (strEnd == -1) { err.add(new Error("expected closing of String literal")); continue PROCESS; }
+ key = trimmed.substring(strStart, strEnd);
+
+ Hashtable thisCase = (Hashtable)byLength[key.length()];
+ if (thisCase == null) byLength[key.length()] = thisCase = new Hashtable();
+ thisCase.put(key, "");
+
+ // find end of case definition
+ int caseEnd = trimmed.indexOf(':', strEnd) +1;
+ if (caseEnd < 1) { err.add(new Error("expected :")); continue PROCESS; }
+ trimmed = trimmed.substring(caseEnd);
+ }
+
+ if (key != null) {
+ Hashtable hash = byLength[key.length()];
+ hash.put(key, (String)hash.get(key) + replaceAll(processLine(trimmed, false), "//[^\"]*$", "").trim() + "\n");
+ } else {
+ out.print(processLine(trimmed, false));
+ }
+ }
+
+ for(int i=0; i<255; i++) {
+ if (byLength[i] == null) continue;
+ out.print("case " + i + ": { switch(ccSwitch"+enumSwitch+".charAt(0)) { ");
+ buildTrie("", byLength[i]);
+ out.print("}; break; } ");
+ }
+ out.print("} /* switch */ ");
+ if (Default != null) out.print(" " + Default);
+ out.print(" } while(false); /* OUTER */\n");
+ enumSwitch++;
+
+ } else {
+ out.print(processLine(s, false));
+ }
+ }
+
+ return err;
+ }
+
+ private void buildTrie(String prefix, Hashtable cases) {
+ Enumeration caseKeys = cases.keys();
+ Vec keys = new Vec();
+ while(caseKeys.hasMoreElements()) keys.addElement(caseKeys.nextElement());
+ keys.sort(new Vec.CompareFunc() { public int compare(Object a, Object b) {
+ return ((String)a).compareTo((String)b);
+ } } );
+
+ for(int i=0; i<keys.size(); i++) {
+ if (!((String)keys.elementAt(i)).startsWith(prefix)) continue;
+ String prefixPlusOne = ((String)keys.elementAt(i)).substring(0, prefix.length() + 1);
+ if (i<keys.size()-1 && prefixPlusOne.equals((((String)keys.elementAt(i + 1)).substring(0, prefix.length() + 1)))) {
+ out.print("case \'" + prefixPlusOne.charAt(prefixPlusOne.length() - 1) + "\': { ");
+ out.print("switch(ccSwitch"+enumSwitch+".charAt(" + (prefix.length()+1) + ")) { ");
+ buildTrie(prefixPlusOne, cases);
+ out.print("} break; } ");
+ while(i<keys.size() && prefixPlusOne.equals(((String)keys.elementAt(i)).substring(0, prefix.length() + 1))) i++;
+ if (i<keys.size()) { i--; continue; }
+ } else {
+ out.print("case \'" + prefixPlusOne.charAt(prefixPlusOne.length() - 1) + "\': ");
+ String code = (String)cases.get(keys.elementAt(i));
+ code = code.substring(0, code.length());
+ String key = (String)keys.elementAt(i);
+ out.print("if (\""+key+"\".equals(ccSwitch"+enumSwitch+")) { if (true) do { " + code + " } while(false); break SUCCESS; } break; ");
+ }
+ }
+ }
+
+ private String processLine(String s, boolean deleteLineEndings) throws IOException {
+ if (deleteLineEndings && s.indexOf("//") != -1) s = s.substring(0, s.indexOf("//"));
+ String ret = "";
+ for(int i=0; i<s.length(); i++) {
+ char c = s.charAt(i);
+ if (!Character.isLetter(c) && !Character.isDigit(c) && c != '_') {
+ ret += c;
+ continue;
+ }
+ int j;
+ for(j = i; j < s.length(); j++) {
+ c = s.charAt(j);
+ if (!Character.isLetter(c) && !Character.isDigit(c) && c != '_') break;
+ }
+ String tok = s.substring(i, j);
+ Object val = replace.get(tok);
+ if (val == null) {
+ ret += tok;
+ i = j - 1;
+ } else if (val instanceof JSFunctionMacro) {
+ if (s.charAt(j) != '(') { ret += tok; i = j - 1; continue; }
+ ret += ((JSFunctionMacro)val).process(s.substring(j+1, s.indexOf(')', j)));
+ i = s.indexOf(')', j);
+ } else {
+ ret += val;
+ i = j - 1;
+ }
+ }
+ if (!deleteLineEndings) ret += "\n";
+ return ret;
+ }
+
+ private static int indexOfWS(String s) { return indexOfWS(s, 0); }
+ private static int indexOfWS(String s, int beginIndex) {
+ if (s == null || beginIndex >= s.length()) return -1;
+ for (; beginIndex < s.length(); beginIndex++) {
+ if (s.charAt(beginIndex) == ' ') return beginIndex;
+ }
+ return s.length();
+ }
+
+ private static int indexOfNotWS(String s) { return indexOfWS(s, 0); }
+ private static int indexOfNotWS(String s, int beginIndex) {
+ if (s == null || beginIndex >= s.length()) return -1;
+ for (; beginIndex < s.length(); beginIndex++) {
+ if (s.charAt(beginIndex) != ' ') return beginIndex;
+ }
+ return -1;
+ }
+
+ public class Warning {
+ protected String msg;
+ protected int line;
+
+ public Warning() { msg = ""; }
+ public Warning(String m) { msg = m; if (in != null) line = in.getLineNumber(); }
+
+ public String toString() { return "WARNING Line "+line+": "+msg; }
+ }
+
+ public class Error extends Warning {
+ public Error() { super(); }
+ public Error(String m) { super(m); }
+ public String toString() { return "ERROR Line "+line+": "+msg; }
+ }
+
+ public static class JSFunctionMacro {
+ public String unbound1 = null;
+ public String unbound2 = null;
+ public String expression = null;
+ public String process(String args) {
+ String bound1 = null;
+ String bound2 = null;
+ if (unbound2 == null) {
+ bound1 = args;
+ return replaceAll(expression, unbound1, bound1);
+ } else {
+ bound1 = args.substring(0, args.indexOf(','));
+ bound2 = args.substring(args.indexOf(',') + 1);
+ return replaceAll(replaceAll(expression, unbound1, bound1), unbound2, bound2);
+ }
+ }
+ }
+}
+
--- /dev/null
+// Copyright (C) 2003 Adam Megacz <adam@ibex.org> all rights reserved.
+//
+// You may modify, copy, and redistribute this code under the terms of
+// the GNU Library Public License version 2.1, with the exception of
+// the portion of clause 6a after the semicolon (aka the "obnoxious
+// relink clause")
+
+package org.ibex.util;
+
+/** A simple synchronized queue, implemented as an array */
+public class Queue {
+
+ public Queue(int initiallength) { vec = new Object[initiallength]; }
+
+ /** The store */
+ private Object[] vec;
+
+ /** The index of the first node in the queue */
+ private int first = 0;
+
+ /** The number of elements in the queue; INVARAINT: size <= vec.length */
+ private int size = 0;
+
+ /** Grow the queue, if needed */
+ private void grow(int newlength) {
+ Object[] newvec = new Object[newlength];
+ if (first + size > vec.length) {
+ System.arraycopy(vec, first, newvec, 0, vec.length - first);
+ System.arraycopy(vec, 0, newvec, vec.length - first, size - (vec.length - first));
+ } else {
+ System.arraycopy(vec, first, newvec, 0, size);
+ }
+ first = 0;
+ vec = newvec;
+ }
+
+ /** The number of elements in the queue */
+ public int size() { return size; }
+
+ /** Empties the queue */
+ public synchronized void flush() {
+ first = 0;
+ size = 0;
+ for(int i=0; i<vec.length; i++) vec[i] = null;
+ }
+
+ /** Add an element to the front of the queue */
+ public synchronized void prepend(Object o) {
+ if (size == vec.length) grow(vec.length * 2);
+ first--;
+ if (first < 0) first += vec.length;
+ vec[first] = o;
+ size++;
+ if (size == 1) notify();
+ }
+
+ /** Add an element to the back of the queue */
+ public synchronized void append(Object o) {
+ if (size == vec.length) grow(vec.length * 2);
+ if (first + size >= vec.length) vec[first + size - vec.length] = o;
+ else vec[first + size] = o;
+ size++;
+ if (size == 1) notify();
+ }
+
+ /** Remove and return and element from the queue, blocking if empty. */
+ public Object remove() { return remove(true); }
+
+ /** Remove and return an element from the queue, blocking if
+ <tt>block</tt> is true and the queue is empty. */
+ public synchronized Object remove(boolean block) {
+
+ while (size == 0 && block) {
+ try { wait(); } catch (InterruptedException e) { }
+ }
+
+ if (!block && size == 0) return null;
+ Object ret = vec[first];
+ first++;
+ size--;
+ if (first >= vec.length) first = 0;
+ return ret;
+ }
+
+ /** Returns the top element in the queue without removing it */
+ public synchronized Object peek() {
+ if (size == 0) return null;
+ return vec[first];
+ }
+
+}
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.util;
+
+import java.io.IOException;
+
+import org.ibex.js.*;
+import org.ibex.util.*;
+import org.ibex.graphics.*;
+import org.ibex.plat.*;
+
+/** Implements cooperative multitasking */
+public class Scheduler {
+
+ // Public API Exposed to org.ibex /////////////////////////////////////////////////
+
+ private static Scheduler singleton;
+ public static void add(Task t) { Log.debug(Scheduler.class, "scheduling " + t); Scheduler.runnable.append(t); }
+ public static void init() { if (singleton == null) (singleton = Platform.getScheduler()).run(); }
+
+ private static Task current = null;
+
+ private static volatile boolean rendering = false;
+ private static volatile boolean again = false;
+
+ /** synchronizd so that we can safely call it from an event-delivery thread, in-context */
+ public static void renderAll() {
+ if (rendering) { again = true; return; }
+ synchronized(Scheduler.class) {
+ try {
+ rendering = true;
+ do {
+ // FEATURE: this could be cleaner
+ again = false;
+ for(int i=0; i<Surface.allSurfaces.size(); i++) {
+ Surface s = ((Surface)Surface.allSurfaces.elementAt(i));
+ do { s.render(); } while(s.abort);
+ }
+ } while(again);
+ } finally {
+ rendering = false;
+ }
+ }
+ }
+
+
+
+ // API which must be supported by subclasses /////////////////////////////////////
+
+ /**
+ * SCHEDULER INVARIANT: all scheduler implementations MUST invoke
+ * Surface.renderAll() after performing a Task if no tasks remain
+ * in the queue. A scheduler may choose to invoke
+ * Surface.renderAll() more often than that if it so chooses.
+ */
+ public void run() { defaultRun(); }
+ public Scheduler() { }
+
+
+ // Default Implementation //////////////////////////////////////////////////////
+
+ protected static Queue runnable = new Queue(50);
+ public void defaultRun() {
+ while(true) {
+ current = (Task)runnable.remove(true);
+ try {
+ // FIXME hideous
+ synchronized(this) {
+ for(int i=0; i<Surface.allSurfaces.size(); i++) {
+ Surface s = (Surface)Surface.allSurfaces.elementAt(i);
+ if (current instanceof JS) {
+ s._mousex = Integer.MAX_VALUE;
+ s._mousey = Integer.MAX_VALUE;
+ } else {
+ s._mousex = s.mousex;
+ s._mousey = s.mousey;
+ }
+ }
+ Log.debug(Scheduler.class, "performing " + current);
+ current.perform();
+ }
+ renderAll();
+ } catch (JSExn e) {
+ Log.info(Scheduler.class, "a JavaScript thread spawned with ibex.thread() threw an exception:");
+ Log.info(Scheduler.class,e);
+ } catch (Exception e) {
+ Log.info(Scheduler.class, "a Task threw an exception which was caught by the scheduler:");
+ Log.info(Scheduler.class, e);
+ } catch (Throwable t) {
+ t.printStackTrace();
+ }
+ // if an Error is thrown it will cause the engine to quit
+ }
+ }
+}
--- /dev/null
+// Copyright (C) 2003 Adam Megacz <adam@ibex.org> all rights reserved.
+//
+// You may modify, copy, and redistribute this code under the terms of
+// the GNU Library Public License version 2.1, with the exception of
+// the portion of clause 6a after the semicolon (aka the "obnoxious
+// relink clause")
+
+package org.ibex.util;
+
+/** Simple implementation of a blocking, counting semaphore. */
+public class Semaphore {
+
+ private int val = 0;
+
+ /** Decrement the counter, blocking if zero. */
+ public synchronized void block() {
+ while(val == 0) {
+ try {
+ wait();
+ } catch (InterruptedException e) {
+ } catch (Throwable e) {
+ if (Log.on) Log.info(this, "Exception in Semaphore.block(); this should never happen");
+ if (Log.on) Log.info(this, e);
+ }
+ }
+ val--;
+ }
+
+ /** Incremenet the counter. */
+ public synchronized void release() {
+ val++;
+ notify();
+ }
+
+}
--- /dev/null
+package org.ibex.util;
+import java.io.* ;
+import java.util.* ;
+
+public class Simplex {
+
+ public final static short FAIL = -1;
+
+ public final static short NULL = 0;
+ public final static short FALSE = 0;
+ public final static short TRUE = 1;
+
+ public final static short DEFNUMINV = 50;
+
+ /* solve status values */
+ public final static short OPTIMAL = 0;
+ public final static short MILP_FAIL = 1;
+ public final static short INFEASIBLE = 2;
+ public final static short UNBOUNDED = 3;
+ public final static short FAILURE = 4;
+ public final static short RUNNING = 5;
+
+ /* lag_solve extra status values */
+ public final static short FEAS_FOUND = 6;
+ public final static short NO_FEAS_FOUND = 7;
+ public final static short BREAK_BB = 8;
+
+ public final static short FIRST_NI = 0;
+ public final static short RAND_NI = 1;
+
+ public final static short LE = 0;
+ public final static short EQ = 1;
+ public final static short GE = 2;
+ public final static short OF = 3;
+
+ public final static short MAX_WARN_COUNT = 20;
+
+ public final static float DEF_INFINITE = (float)1e24; /* limit for dynamic range */
+ public final static float DEF_EPSB = (float)5.01e-7; /* for rounding RHS values to 0 determine
+ infeasibility basis */
+ public final static float DEF_EPSEL = (float)1e-8; /* for rounding other values (vectors) to 0 */
+ public final static float DEF_EPSD = (float)1e-6; /* for rounding reduced costs to zero */
+ public final static float DEF_EPSILON = (float)1e-3; /* to determine if a float value is integer */
+
+ public final static float PREJ = (float)1e-3; /* pivot reject (try others first) */
+
+ public final static int ETA_START_SIZE = 10000; /* start size of array Eta. Realloced if needed */
+
+ static class Ref {
+ float value;
+ public Ref(float v) { value = v; }
+ }
+
+ //public static class Simplex {
+ /* Globals used by solver */
+ short JustInverted;
+ short Status;
+ short Doiter;
+ short DoInvert;
+ short Break_bb;
+
+ public short active; /*TRUE if the globals point to this structure*/
+ public short debug; /* ## Print B&B information */
+ public short trace; /* ## Print information on pivot selection */
+ public int rows; /* Nr of constraint rows in the problem */
+ int rows_alloc; /* The allocated memory for Rows sized data */
+ int columns_alloc;
+ int sum; /* The size of the variables + the slacks */
+ int sum_alloc;
+ int non_zeros; /* The number of elements in the sparce matrix*/
+ int mat_alloc; /* The allocated size for matrix sized
+ structures */
+ MatrixArray mat; /* mat_alloc :The sparse matrix */
+ MatrixArray alternate_mat; /* mat_alloc :The sparse matrix */
+ int[] col_end; /* columns_alloc+1 :Cend[i] is the index of the
+ first element after column i.
+ column[i] is stored in elements
+ col_end[i-1] to col_end[i]-1 */
+ int[] col_no; /* mat_alloc :From Row 1 on, col_no contains the
+ column nr. of the
+ nonzero elements, row by row */
+ short row_end_valid; /* true if row_end & col_no are valid */
+ int[] row_end; /* rows_alloc+1 :row_end[i] is the index of the
+ first element in Colno after row i */
+ float[] orig_rh; /* rows_alloc+1 :The RHS after scaling & sign
+ changing, but before `Bound transformation' */
+ float[] rh; /* rows_alloc+1 :As orig_rh, but after Bound
+ transformation */
+ float[] rhs; /* rows_alloc+1 :The RHS of the curent simplex
+ tableau */
+ float[] orig_upbo; /* sum_alloc+1 :Bound before transformations */
+ float[] orig_lowbo; /* " " */
+ float[] upbo; /* " " :Upper bound after transformation
+ & B&B work*/
+ float[] lowbo; /* " " :Lower bound after transformation
+ & B&B work */
+
+ short basis_valid; /* TRUE is the basis is still valid */
+ int[] bas; /* rows_alloc+1 :The basis column list */
+ short[] basis; /* sum_alloc+1 : basis[i] is TRUE if the column
+ is in the basis */
+ short[] lower; /* " " :TRUE is the variable is at its
+ lower bound (or in the basis), it is FALSE
+ if the variable is at its upper bound */
+
+ short eta_valid; /* TRUE if current Eta structures are valid */
+ int eta_alloc; /* The allocated memory for Eta */
+ int eta_size; /* The number of Eta columns */
+ int num_inv; /* The number of float pivots */
+ int max_num_inv; /* ## The number of float pivots between
+ reinvertions */
+ float[] eta_value; /* eta_alloc :The Structure containing the
+ values of Eta */
+ int[] eta_row_nr; /* " " :The Structure containing the Row
+ indexes of Eta */
+ int[] eta_col_end; /* rows_alloc + MaxNumInv : eta_col_end[i] is
+ the start index of the next Eta column */
+
+ short bb_rule; /* what rule for selecting B&B variables */
+
+ short break_at_int; /* TRUE if stop at first integer better than
+ break_value */
+ float break_value;
+
+ float obj_bound; /* ## Objective function bound for speedup of
+ B&B */
+ int iter; /* The number of iterations in the simplex
+ solver () */
+ int total_iter; /* The total number of iterations (B&B) (ILP)*/
+ int max_level; /* The Deepest B&B level of the last solution */
+ int total_nodes; /* total number of nodes processed in b&b */
+ public float[] solution; /* sum_alloc+1 :The Solution of the last LP,
+ 0 = The Optimal Value,
+ 1..rows The Slacks,
+ rows+1..sum The Variables */
+ public float[] best_solution; /* " " :The Best 'Integer' Solution */
+ float[] duals; /* rows_alloc+1 :The dual variables of the
+ last LP */
+
+ short maximise; /* TRUE if the goal is to maximise the
+ objective function */
+ short floor_first; /* TRUE if B&B does floor bound first */
+ short[] ch_sign; /* rows_alloc+1 :TRUE if the Row in the matrix
+ has changed sign
+ (a`x > b, x>=0) is translated to
+ s + -a`x = -b with x>=0, s>=0) */
+
+ int nr_lagrange; /* Nr. of Langrangian relaxation constraints */
+ float[][]lag_row; /* NumLagrange, columns+1:Pointer to pointer of
+ rows */
+ float[] lag_rhs; /* NumLagrange :Pointer to pointer of Rhs */
+ float[] lambda; /* NumLagrange :Lambda Values */
+ short[] lag_con_type; /* NumLagrange :TRUE if constraint type EQ */
+ float lag_bound; /* the lagrangian lower bound */
+
+ short valid; /* Has this lp pased the 'test' */
+ float infinite; /* ## numercal stuff */
+ float epsilon; /* ## */
+ float epsb; /* ## */
+ float epsd; /* ## */
+ float epsel; /* ## */
+
+ int Rows;
+ int columns;
+ int Sum;
+ int Non_zeros;
+ int Level;
+ MatrixArray Mat;
+ int[] Col_no;
+ int[] Col_end;
+ int[] Row_end;
+ float[] Orig_rh;
+ float[] Rh;
+ float[] Rhs;
+ float[] Orig_upbo;
+ float[] Orig_lowbo;
+ float[] Upbo;
+ float[] Lowbo;
+ int[] Bas;
+ short[] Basis;
+ short[] Lower;
+ int Eta_alloc;
+ int Eta_size;
+ float[] Eta_value;
+ int[] Eta_row_nr;
+ int[] Eta_col_end;
+ int Num_inv;
+ float[] Solution;
+ public float[] Best_solution;
+ float Infinite;
+ float Epsilon;
+ float Epsb;
+ float Epsd;
+ float Epsel;
+
+ float TREJ;
+ float TINV;
+
+ short Maximise;
+ short Floor_first;
+ float Extrad;
+
+ int Warn_count; /* used in CHECK version of rounding macro */
+
+ public Simplex (int nrows, int ncolumns, int matalloc) {
+ int nsum;
+ nsum=nrows+ncolumns;
+ rows=nrows;
+ columns=ncolumns;
+ sum=nsum;
+ rows_alloc=rows;
+ columns_alloc=columns;
+ sum_alloc=sum;
+ mat_alloc=matalloc;
+ eta_alloc=10000;
+ max_num_inv=DEFNUMINV;
+ col_no = new int[mat_alloc];
+ col_end = new int[columns + 1];
+ row_end = new int[rows + 1];
+ orig_rh = new float[rows + 1];
+ rh = new float[rows + 1];
+ rhs = new float[rows + 1];
+ orig_upbo = new float[sum + 1];
+ upbo = new float[sum + 1];
+ orig_lowbo = new float[sum + 1];
+ lowbo = new float[sum + 1];
+ bas = new int[rows+1];
+ basis = new short[sum + 1];
+ lower = new short[sum + 1];
+ eta_value = new float[eta_alloc];
+ eta_row_nr = new int[eta_alloc];
+ eta_col_end = new int[rows_alloc + max_num_inv];
+ solution = new float[sum + 1];
+ best_solution = new float[sum + 1];
+ duals = new float[rows + 1];
+ ch_sign = new short[rows + 1];
+ mat = new MatrixArray(mat_alloc);
+ alternate_mat = new MatrixArray(mat_alloc);
+ }
+
+ public void init(int ncolumns) {
+ int nsum;
+ int nrows = 0;
+ nsum=nrows+ncolumns;
+ active=FALSE;
+ debug=FALSE;
+ trace=FALSE;
+ rows=nrows;
+ columns=ncolumns;
+ sum=nsum;
+ obj_bound=DEF_INFINITE;
+ infinite=DEF_INFINITE;
+ epsilon=DEF_EPSILON;
+ epsb=DEF_EPSB;
+ epsd=DEF_EPSD;
+ epsel=DEF_EPSEL;
+ non_zeros=0;
+
+ for(int i = 0; i < col_end.length; i++) col_end[i] = 0;
+ for(int i = 0; i < rows + 1; i++) row_end[i] = 0;
+ for(int i = 0; i < rows + 1; i++) orig_rh[i] = 0;
+ for(int i = 0; i < rows + 1; i++) rh[i] = 0;
+ for(int i = 0; i < rows + 1; i++) rhs[i] = 0;
+ for(int i = 0; i <= sum; i++) orig_upbo[i]=infinite;
+ for(int i = 0; i < sum + 1; i++) upbo[i] = 0;
+ for(int i = 0; i < sum + 1; i++) orig_lowbo[i] = 0;
+ for(int i = 0; i < sum + 1; i++) lowbo[i] = 0;
+ for(int i = 0; i <= rows; i++) bas[i] = 0;
+ for(int i = 0; i <= sum; i++) basis[i] = 0;
+ for(int i = 0; i <= rows; i++) { bas[i]=i; basis[i]=TRUE; }
+ for(int i = rows + 1; i <= sum; i++) basis[i]=FALSE;
+ for(int i = 0 ; i <= sum; i++) lower[i]=TRUE;
+ for(int i = 0; i <= sum; i++) solution[i] = 0;
+ for(int i = 0; i <= sum; i++) best_solution[i] = 0;
+ for(int i = 0; i <= rows; i++) duals[i] = 0;
+ for(int i = 0; i <= rows; i++) ch_sign[i] = FALSE;
+
+ row_end_valid=FALSE;
+ bb_rule=FIRST_NI;
+ break_at_int=FALSE;
+ break_value=0;
+ iter=0;
+ total_iter=0;
+ basis_valid=TRUE;
+ eta_valid=TRUE;
+ eta_size=0;
+ nr_lagrange=0;
+ maximise = FALSE;
+ floor_first = TRUE;
+ valid = FALSE;
+ }
+
+ public void setObjective(float[] row, boolean maximize) {
+ for(int i=row.length-1; i>0; i--) row[i] = row[i-1];
+ row[0] = (float)0.0;
+ for(int j = 1; j <= columns; j++) {
+ int Row = 0;
+ int column = j;
+ float Value = row[j];
+ int elmnr, lastelm;
+
+ if(Row > rows || Row < 0) throw new Error("row out of range");
+ if(column > columns || column < 1) throw new Error("column out of range");
+
+ if (basis[column] == TRUE && Row > 0) basis_valid = FALSE;
+ eta_valid = FALSE;
+ elmnr = col_end[column-1];
+ while((elmnr < col_end[column]) ? (get_row_nr(mat, elmnr) != Row) : false) elmnr++;
+ if((elmnr != col_end[column]) ? (get_row_nr(mat, elmnr) == Row) : false ) {
+ if (ch_sign[Row] != FALSE) set_value(mat, elmnr, -Value);
+ else set_value(mat, elmnr, Value);
+ } else {
+ /* check if more space is needed for matrix */
+ if (non_zeros + 1 > mat_alloc) throw new Error("not enough mat space; this should not happen");
+ /* Shift the matrix */
+ lastelm=non_zeros;
+ for(int i = lastelm; i > elmnr ; i--) {
+ set_row_nr(mat,i,get_row_nr(mat,i-1));
+ set_value(mat,i,get_value(mat,i-1));
+ }
+ for(int i = column; i <= columns; i++) col_end[i]++;
+ /* Set new element */
+ set_row_nr(mat,elmnr, Row);
+ if (ch_sign[Row] != FALSE) set_value(mat, elmnr, -Value);
+ else set_value(mat, elmnr, Value);
+ row_end_valid=FALSE;
+ non_zeros++;
+ if (active != FALSE) Non_zeros=non_zeros;
+ }
+ }
+ if (maximize) {
+ if (maximise == FALSE) {
+ for(int i = 0; i < non_zeros; i++)
+ if(get_row_nr(mat, i)==0)
+ set_value(mat, i, get_value(mat,i)* (float)-1.0);
+ eta_valid=FALSE;
+ }
+ maximise=TRUE;
+ ch_sign[0]=TRUE;
+ if (active != FALSE) Maximise=TRUE;
+ } else {
+ if (maximise==TRUE) {
+ for(int i = 0; i < non_zeros; i++)
+ if(get_row_nr(mat, i)==0)
+ set_value(mat, i, get_value(mat,i) * (float)-1.0);
+ eta_valid=FALSE;
+ }
+ maximise=FALSE;
+ ch_sign[0]=FALSE;
+ if (active != FALSE) Maximise=FALSE;
+ }
+ }
+
+ public void add_constraint(float[] row, short constr_type, float rh) {
+ for(int i=row.length-1; i>0; i--) row[i] = row[i-1];
+ row[0] = (float)0.0;
+
+ MatrixArray newmat;
+ int elmnr;
+ int stcol;
+
+ newmat = alternate_mat;
+ for(int i = 0; i < non_zeros; i++) { set_row_nr(newmat,i, 0); set_value(newmat, i, 0); }
+ for(int i = 1; i <= columns; i++) if (row[i]!=0) non_zeros++;
+ if (non_zeros > mat_alloc) throw new Error("not enough mat space; this should not happen");
+ rows++;
+ sum++;
+ if(rows > rows_alloc) throw new Error("not enough rows; this should never happen");
+ if(constr_type==GE) ch_sign[rows] = TRUE;
+ else ch_sign[rows] = FALSE;
+
+ elmnr = 0;
+ stcol = 0;
+ for(int i = 1; i <= columns; i++) {
+ for(int j = stcol; j < col_end[i]; j++) {
+ set_row_nr(newmat,elmnr, get_row_nr(mat, j));
+ set_value(newmat, elmnr, get_value(mat,j));
+ elmnr++;
+ }
+ if(((i>=1 && i< columns && row[i]!=0)?TRUE:FALSE) != FALSE) {
+ if(ch_sign[rows] != FALSE) set_value(newmat, elmnr, -row[i]);
+ else set_value(newmat, elmnr, row[i]);
+ set_row_nr(newmat,elmnr, rows);
+ elmnr++;
+ }
+ stcol=col_end[i];
+ col_end[i]=elmnr;
+ }
+
+ alternate_mat = mat;
+ mat = newmat;
+
+ for(int i = sum ; i > rows; i--) {
+ orig_upbo[i]=orig_upbo[i-1];
+ orig_lowbo[i]=orig_lowbo[i-1];
+ basis[i]=basis[i-1];
+ lower[i]=lower[i-1];
+ }
+
+ for(int i = 1 ; i <= rows; i++) if(bas[i] >= rows) bas[i]++;
+
+ if(constr_type==LE || constr_type==GE) orig_upbo[rows]=infinite;
+ else if(constr_type==EQ) orig_upbo[rows]=0;
+ else throw new Error("Wrong constraint type\n");
+ orig_lowbo[rows]=0;
+
+ if(constr_type==GE && rh != 0) orig_rh[rows]=-rh;
+ else orig_rh[rows]=rh;
+
+ row_end_valid=FALSE;
+
+ bas[rows]=rows;
+ basis[rows]=TRUE;
+ lower[rows]=TRUE;
+
+ if (active != FALSE) set_globals();
+ eta_valid=FALSE;
+ }
+
+ public void bound_sum(int column1, int column2, float bound, short type, float[] scratch) {
+ for(int i=0; i<scratch.length; i++) scratch[i] = (float)0.0;
+ scratch[column1] = (float)1.0;
+ scratch[column2] = (float)1.0;
+ add_constraint(scratch, type, bound);
+ for(int i=0; i<scratch.length; i++) scratch[i] = (float)0.0;
+ }
+
+ public void bound_difference(int column1, int column2, float bound, short type, float[] scratch) {
+ for(int i=0; i<scratch.length; i++) scratch[i] = (float)0.0;
+ scratch[column1] = (float)1.0;
+ scratch[column2] = (float)-1.0;
+ add_constraint(scratch, type, bound);
+ for(int i=0; i<scratch.length; i++) scratch[i] = (float)0.0;
+ }
+
+ public void set_upbo(int column, float value) {
+ if(column > columns || column < 1) throw new Error("column out of range");
+ if(value < orig_lowbo[rows + column]) throw new Error("UpperBound must be >= lowerBound");
+ eta_valid = FALSE;
+ orig_upbo[rows+column] = value;
+ }
+
+ public void set_lowbo(int column, float value) {
+ if(column > columns || column < 1) throw new Error("column out of range");
+ if(value > orig_upbo[rows + column]) throw new Error("UpperBound must be >= lowerBound");
+ eta_valid = FALSE;
+ orig_lowbo[rows+column] = value;
+ }
+
+ public void set_rh(int row, float value) {
+ if(row > rows || row < 0) throw new Error("Row out of Range");
+ if(row == 0) throw new Error("Warning: attempt to set RHS of objective function, ignored");
+ if (ch_sign[row] != FALSE) orig_rh[row] = -value;
+ else orig_rh[row] = value;
+ eta_valid = FALSE;
+ }
+
+ public void set_rh_vec(float[] rh) {
+ for(int i=1; i <= rows; i++)
+ if (ch_sign[i] != FALSE) orig_rh[i]=-rh[i];
+ else orig_rh[i]=rh[i];
+ eta_valid=FALSE;
+ }
+
+
+ public void set_constr_type(int row, short con_type) {
+ if (row > rows || row < 1) throw new Error("Row out of Range");
+ switch(con_type) {
+ case EQ:
+ orig_upbo[row]=0;
+ basis_valid=FALSE;
+ if (ch_sign[row] != FALSE) {
+ for(int i = 0; i < non_zeros; i++)
+ if (get_row_nr(mat, i)==row) set_value(mat, i, get_value(mat,i) * (float)-1);
+ eta_valid=FALSE;
+ ch_sign[row]=FALSE;
+ if (orig_rh[row]!=0) orig_rh[row]*=-1;
+ }
+ break;
+ case LE:
+ orig_upbo[row]=infinite;
+ basis_valid=FALSE;
+ if (ch_sign[row] != FALSE) {
+ for(int i = 0; i < non_zeros; i++)
+ if (get_row_nr(mat, i)==row) set_value(mat, i, get_value(mat,i) * (float)-1);
+ eta_valid=FALSE;
+ ch_sign[row]=FALSE;
+ if (orig_rh[row]!=0) orig_rh[row]*=-1;
+ }
+ break;
+ case GE:
+ orig_upbo[row]=infinite;
+ basis_valid=FALSE;
+ if (ch_sign[row] == FALSE) {
+ for(int i = 0; i < non_zeros; i++)
+ if (get_row_nr(mat, i)==row) set_value(mat, i, get_value(mat,i) * (float)-1);
+ eta_valid=FALSE;
+ ch_sign[row]=TRUE;
+ if (orig_rh[row]!=0) orig_rh[row]*=-1;
+ }
+ break;
+ default: throw new Error("Constraint type not (yet) implemented");
+ }
+ }
+
+ void set_globals() {
+ Rows = rows;
+ columns = columns;
+ Sum = Rows + columns;
+ Non_zeros = non_zeros;
+ Mat = mat;
+ Col_no = col_no;
+ Col_end = col_end;
+ Row_end = row_end;
+ Rh = rh;
+ Rhs = rhs;
+ Orig_rh = orig_rh;
+ Orig_upbo = orig_upbo;
+ Orig_lowbo = orig_lowbo;
+ Upbo = upbo;
+ Lowbo = lowbo;
+ Bas = bas;
+ Basis = basis;
+ Lower = lower;
+ Eta_alloc = eta_alloc;
+ Eta_size = eta_size;
+ Num_inv = num_inv;
+ Eta_value = eta_value;
+ Eta_row_nr = eta_row_nr;
+ Eta_col_end = eta_col_end;
+ Solution = solution;
+ Best_solution = best_solution;
+ Infinite = infinite;
+ Epsilon = epsilon;
+ Epsb = epsb;
+ Epsd = epsd;
+ Epsel = epsel;
+ TREJ = TREJ;
+ TINV = TINV;
+ Maximise = maximise;
+ Floor_first = floor_first;
+ active = TRUE;
+ }
+
+ private void ftran(int start, int end, float[] pcol) {
+ int k, r;
+ float theta;
+ for(int i = start; i <= end; i++) {
+ k = Eta_col_end[i] - 1;
+ r = Eta_row_nr[k];
+ theta = pcol[r];
+ if (theta != 0) for(int j = Eta_col_end[i - 1]; j < k; j++)
+ pcol[Eta_row_nr[j]] += theta * Eta_value[j];
+ pcol[r] *= Eta_value[k];
+ }
+ for(int i = 0; i <= Rows; i++) round(pcol[i], Epsel);
+ }
+
+ private void btran(float[] row) {
+ int k;
+ float f;
+ for(int i = Eta_size; i >= 1; i--) {
+ f = 0;
+ k = Eta_col_end[i] - 1;
+ for(int j = Eta_col_end[i - 1]; j <= k; j++) f += row[Eta_row_nr[j]] * Eta_value[j];
+ f = round(f, Epsel);
+ row[Eta_row_nr[k]] = f;
+ }
+ }
+
+ static int[] num = new int[65535];
+ static int[] rownum = new int[65535];
+ static int[] colnum = new int[65535];
+
+ short Isvalid() {
+ int row_nr;
+ if (row_end_valid == FALSE) {
+ for(int i = 0; i <= rows; i++) { num[i] = 0; rownum[i] = 0; }
+ for(int i = 0; i < non_zeros; i++) rownum[get_row_nr(mat, i)]++;
+ row_end[0] = 0;
+ for(int i = 1; i <= rows; i++) row_end[i] = row_end[i - 1] + rownum[i];
+ for(int i = 1; i <= columns; i++)
+ for(int j = col_end[i - 1]; j < col_end[i]; j++) {
+ row_nr = get_row_nr(mat, j);
+ if (row_nr != 0) {
+ num[row_nr]++;
+ col_no[row_end[row_nr - 1] + num[row_nr]] = i;
+ }
+ }
+ row_end_valid = TRUE;
+ }
+ if (valid != FALSE) return(TRUE);
+ for(int i = 0; i <= rows; i++) rownum[i] = 0;
+ for(int i = 0; i <= columns; i++) colnum[i] = 0;
+ for(int i = 1 ; i <= columns; i++)
+ for(int j = col_end[i - 1]; j < col_end[i]; j++) {
+ colnum[i]++;
+ rownum[get_row_nr(mat, j)]++;
+ }
+ for(int i = 1; i <= columns; i++)
+ if (colnum[i] == 0)
+ throw new Error("Warning: Variable " + i + " not used in any constaints\n");
+ valid = TRUE;
+ return(TRUE);
+ }
+
+ private void resize_eta() {
+ Eta_alloc *= 2;
+ throw new Error("eta undersized; this should never happen");
+ /*
+ float[] db_ptr = Eta_value;
+ Eta_value = new float[Eta_alloc];
+ System.arraycopy(db_ptr, 0, Eta_value, 0, db_ptr.length);
+ eta_value = Eta_value;
+
+ int[] int_ptr = Eta_row_nr;
+ Eta_row_nr = new int[Eta_alloc];
+ System.arraycopy(int_ptr, 0, Eta_row_nr, 0, int_ptr.length);
+ eta_row_nr = Eta_row_nr;
+ */
+ }
+
+ private void condensecol(int row_nr, float[] pcol) {
+ int elnr;
+ elnr = Eta_col_end[Eta_size];
+ if (elnr + Rows + 2 > Eta_alloc) resize_eta();
+ for(int i = 0; i <= Rows; i++)
+ if (i != row_nr && pcol[i] != 0) {
+ Eta_row_nr[elnr] = i;
+ Eta_value[elnr] = pcol[i];
+ elnr++;
+ }
+ Eta_row_nr[elnr] = row_nr;
+ Eta_value[elnr] = pcol[row_nr];
+ elnr++;
+ Eta_col_end[Eta_size + 1] = elnr;
+ }
+
+ private void addetacol() {
+ int k;
+ float theta;
+ int j = Eta_col_end[Eta_size];
+ Eta_size++;
+ k = Eta_col_end[Eta_size];
+ theta = 1 / (float) Eta_value[k - 1];
+ Eta_value[k - 1] = theta;
+ for(int i = j; i < k - 1; i++) Eta_value[i] *= -theta;
+ JustInverted = FALSE;
+ }
+
+ private void setpivcol(short lower, int varin, float[] pcol) {
+ int colnr;
+ float f;
+ if (lower != FALSE) f = 1;
+ else f = -1;
+ for(int i = 0; i <= Rows; i++) pcol[i] = 0;
+ if (varin > Rows) {
+ colnr = varin - Rows;
+ for(int i = Col_end[colnr - 1]; i < Col_end[colnr]; i++) pcol[get_row_nr(Mat, i)] = get_value(Mat,i) * f;
+ pcol[0] -= Extrad * f;
+ } else {
+ if (lower != FALSE) pcol[varin] = 1;
+ else pcol[varin] = -1;
+ }
+ ftran(1, Eta_size, pcol);
+ }
+
+ private void minoriteration(int colnr, int row_nr) {
+ int k, wk, varin, varout, elnr;
+ float piv = 0, theta;
+ varin = colnr + Rows;
+ elnr = Eta_col_end[Eta_size];
+ wk = elnr;
+ Eta_size++;
+ if (Extrad != 0) {
+ Eta_row_nr[elnr] = 0;
+ Eta_value[elnr] = -Extrad;
+ elnr++;
+ }
+ for(int j = Col_end[colnr - 1] ; j < Col_end[colnr]; j++) {
+ k = get_row_nr(Mat, j);
+ if (k == 0 && Extrad != 0) Eta_value[Eta_col_end[Eta_size -1]] += get_value(Mat,j);
+ else if (k != row_nr) {
+ Eta_row_nr[elnr] = k;
+ Eta_value[elnr] = get_value(Mat,j);
+ elnr++;
+ } else {
+ piv = get_value(Mat,j);
+ }
+ }
+ Eta_row_nr[elnr] = row_nr;
+ Eta_value[elnr] = 1 / (float) piv;
+ elnr++;
+ theta = Rhs[row_nr] / (float) piv;
+ Rhs[row_nr] = theta;
+ for(int i = wk; i < elnr - 1; i++) Rhs[Eta_row_nr[i]] -= theta * Eta_value[i];
+ varout = Bas[row_nr];
+ Bas[row_nr] = varin;
+ Basis[varout] = FALSE;
+ Basis[varin] = TRUE;
+ for(int i = wk; i < elnr - 1; i++) Eta_value[i] /= - (float) piv;
+ Eta_col_end[Eta_size] = elnr;
+ }
+
+ private void rhsmincol(float theta, int row_nr, int varin) {
+ int varout;
+ float f;
+ if (row_nr > Rows + 1) {
+ System.err.println("Error: rhsmincol called with row_nr: " + row_nr + ", rows: " + Rows + "\n");
+ System.err.println("This indicates numerical instability\n");
+ }
+ int j = Eta_col_end[Eta_size];
+ int k = Eta_col_end[Eta_size + 1];
+ for(int i = j; i < k; i++) {
+ f = Rhs[Eta_row_nr[i]] - theta * Eta_value[i];
+ f = round(f, Epsb);
+ Rhs[Eta_row_nr[i]] = f;
+ }
+ Rhs[row_nr] = theta;
+ varout = Bas[row_nr];
+ Bas[row_nr] = varin;
+ Basis[varout] = FALSE;
+ Basis[varin] = TRUE;
+ }
+
+ private static int[] rownum_ = new int[65535];
+ private static int[] colnum_ = new int[65535];
+ private static int[] col = new int[65535];
+ private static int[] row = new int[65535];
+ private static float[] pcol = new float[65535];
+ private static short[] frow = new short[65535];
+ private static short[] fcol = new short[65535];
+
+ void invert() {
+ int v, wk, numit, varnr, row_nr, colnr, varin;
+ float theta;
+
+ for(int i = 0; i <= Rows; i++) rownum_[i] = 0;
+ for(int i = 0; i <= Rows; i++) col[i] = 0;
+ for(int i = 0; i <= Rows; i++) row[i] = 0;
+ for(int i = 0; i <= Rows; i++) pcol[i] = 0;
+ for(int i = 0; i <= Rows; i++) frow[i] = TRUE;
+ for(int i = 0; i < columns; i++) fcol[i] = FALSE;
+ for(int i = 0; i <= columns; i++) colnum_[i] = 0;
+
+ for(int i = 0; i <= Rows; i++)
+ if (Bas[i] > Rows) fcol[Bas[i] - Rows - 1] = TRUE;
+ else frow[Bas[i]] = FALSE;
+
+ for(int i = 1; i <= Rows; i++)
+ if (frow[i] != FALSE)
+ for(int j = Row_end[i - 1] + 1; j <= Row_end[i]; j++) {
+ wk = Col_no[j];
+ if (fcol[wk - 1] != FALSE) {
+ colnum_[wk]++;
+ rownum_[i - 1]++;
+ }
+ }
+
+ for(int i = 1; i <= Rows; i++) Bas[i] = i;
+ for(int i = 1; i <= Rows; i++) Basis[i] = TRUE;
+ for(int i = 1; i <= columns; i++) Basis[i + Rows] = FALSE;
+ for(int i = 0; i <= Rows; i++) Rhs[i] = Rh[i];
+ for(int i = 1; i <= columns; i++) {
+ varnr = Rows + i;
+ if (Lower[varnr] == FALSE) {
+ theta = Upbo[varnr];
+ for(int j = Col_end[i - 1]; j < Col_end[i]; j++)
+ Rhs[get_row_nr(Mat, j)] -= theta * get_value(Mat,j);
+ }
+ }
+ for(int i = 1; i <= Rows; i++) if (Lower[i] == FALSE) Rhs[i] -= Upbo[i];
+ Eta_size = 0;
+ v = 0;
+ row_nr = 0;
+ Num_inv = 0;
+ numit = 0;
+ while(v < Rows) {
+ int j;
+ row_nr++;
+ if (row_nr > Rows) row_nr = 1;
+ v++;
+ if (rownum_[row_nr - 1] == 1)
+ if (frow[row_nr] != FALSE) {
+ v = 0;
+ j = Row_end[row_nr - 1] + 1;
+ while(fcol[Col_no[j] - 1] == FALSE) j++;
+ colnr = Col_no[j];
+ fcol[colnr - 1] = FALSE;
+ colnum_[colnr] = 0;
+ for(j = Col_end[colnr - 1]; j < Col_end[colnr]; j++)
+ if (frow[get_row_nr(Mat, j)] != FALSE)
+ rownum_[get_row_nr(Mat, j) - 1]--;
+ frow[row_nr] = FALSE;
+ minoriteration(colnr, row_nr);
+ }
+ }
+ v = 0;
+ colnr = 0;
+ while(v < columns) {
+ int j;
+ colnr++;
+ if (colnr > columns) colnr = 1;
+ v++;
+ if (colnum_[colnr] == 1)
+ if (fcol[colnr - 1] != FALSE) {
+ v = 0;
+ j = Col_end[colnr - 1] + 1;
+ while(frow[get_row_nr(Mat, j - 1)] == FALSE) j++;
+ row_nr = get_row_nr(Mat, j - 1);
+ frow[row_nr] = FALSE;
+ rownum_[row_nr - 1] = 0;
+ for(j = Row_end[row_nr - 1] + 1; j <= Row_end[row_nr]; j++)
+ if (fcol[Col_no[j] - 1] != FALSE)
+ colnum_[Col_no[j]]--;
+ fcol[colnr - 1] = FALSE;
+ numit++;
+ col[numit - 1] = colnr;
+ row[numit - 1] = row_nr;
+ }
+ }
+ for(int j = 1; j <= columns; j++)
+ if (fcol[j - 1] != FALSE) {
+ fcol[j - 1] = FALSE;
+ setpivcol(Lower[Rows + j], j + Rows, pcol);
+ row_nr = 1;
+ while((frow[row_nr] == FALSE || pcol[row_nr] == FALSE) && row_nr <= Rows)
+ row_nr++; /* this sometimes sets row_nr to Rows + 1 and makes
+ rhsmincol crash. Solved in 2.0? MB */
+ if (row_nr == Rows + 1) throw new Error("Inverting failed");
+ frow[row_nr] = FALSE;
+ condensecol(row_nr, pcol);
+ theta = Rhs[row_nr] / (float) pcol[row_nr];
+ rhsmincol(theta, row_nr, Rows + j);
+ addetacol();
+ }
+ for(int i = numit - 1; i >= 0; i--) {
+ colnr = col[i];
+ row_nr = row[i];
+ varin = colnr + Rows;
+ for(int j = 0; j <= Rows; j++) pcol[j] = 0;
+ for(int j = Col_end[colnr - 1]; j < Col_end[colnr]; j++) pcol[get_row_nr(Mat, j)] = get_value(Mat,j);
+ pcol[0] -= Extrad;
+ condensecol(row_nr, pcol);
+ theta = Rhs[row_nr] / (float) pcol[row_nr];
+ rhsmincol(theta, row_nr, varin);
+ addetacol();
+ }
+ for(int i = 1; i <= Rows; i++) Rhs[i] = round(Rhs[i], Epsb);
+ JustInverted = TRUE;
+ DoInvert = FALSE;
+ }
+
+ private short colprim(Ref colnr, short minit, float[] drow) {
+ int varnr;
+ float f, dpiv;
+ dpiv = -Epsd;
+ colnr.value = 0;
+ if (minit == FALSE) {
+ for(int i = 1; i <= Sum; i++) drow[i] = 0;
+ drow[0] = 1;
+ btran(drow);
+ for(int i = 1; i <= columns; i++) {
+ varnr = Rows + i;
+ if (Basis[varnr] == FALSE)
+ if (Upbo[varnr] > 0) {
+ f = 0;
+ for(int j = Col_end[i - 1]; j < Col_end[i]; j++) f += drow[get_row_nr(Mat, j)] * get_value(Mat,j);
+ drow[varnr] = f;
+ }
+ }
+ for(int i = 1; i <= Sum; i++) drow[i] = round(drow[i], Epsd);
+ }
+ for(int i = 1; i <= Sum; i++)
+ if (Basis[i] == FALSE)
+ if (Upbo[i] > 0) {
+ if (Lower[i] != FALSE) f = drow[i];
+ else f = -drow[i];
+ if (f < dpiv) {
+ dpiv = f;
+ colnr.value = i;
+ }
+ }
+ if (colnr.value == 0) {
+ Doiter = FALSE;
+ DoInvert = FALSE;
+ Status = OPTIMAL;
+ }
+ return(colnr.value > 0 ? (short)1 : (short)0);
+ }
+
+ private short rowprim(int colnr, Ref row_nr, Ref theta, float[] pcol) {
+ float f = 0, quot;
+ row_nr.value = 0;
+ theta.value = Infinite;
+ for(int i = 1; i <= Rows; i++) {
+ f = pcol[i];
+ if (Math.abs(f) < TREJ) f = 0;
+ if (f != 0) {
+ quot = 2 * Infinite;
+ if (f > 0) quot = Rhs[i] / (float) f;
+ else if (Upbo[Bas[i]] < Infinite) quot = (Rhs[i] - Upbo[Bas[i]]) / (float) f;
+ round(quot, Epsel);
+ if (quot < theta.value) {
+ theta.value = quot;
+ row_nr.value = i;
+ }
+ }
+ }
+ if (row_nr.value == 0)
+ for(int i = 1; i <= Rows; i++) {
+ f = pcol[i];
+ if (f != 0) {
+ quot = 2 * Infinite;
+ if (f > 0) quot = Rhs[i] / (float) f;
+ else if (Upbo[Bas[i]] < Infinite) quot = (Rhs[i] - Upbo[Bas[i]]) / (float) f;
+ quot = round(quot, Epsel);
+ if (quot < theta.value) {
+ theta.value = quot;
+ row_nr.value = i;
+ }
+ }
+ }
+
+ if (theta.value < 0) throw new Error("Warning: Numerical instability, qout = " + theta.value);
+ if (row_nr.value == 0) {
+ if (Upbo[colnr] == Infinite) {
+ Doiter = FALSE;
+ DoInvert = FALSE;
+ Status = UNBOUNDED;
+ } else {
+ int i = 1;
+ while(pcol[i] >= 0 && i <= Rows) i++;
+ if (i > Rows) {
+ Lower[colnr] = FALSE;
+ Rhs[0] += Upbo[colnr]*pcol[0];
+ Doiter = FALSE;
+ DoInvert = FALSE;
+ } else if (pcol[i]<0) {
+ row_nr.value = i;
+ }
+ }
+ }
+ if (row_nr.value > 0) Doiter = TRUE;
+ return((row_nr.value > 0) ? (short)1 : (short)0);
+ }
+
+ private short rowdual(Ref row_nr) {
+ int i;
+ float f, g, minrhs;
+ short artifs;
+ row_nr.value = 0;
+ minrhs = -Epsb;
+ i = 0;
+ artifs = FALSE;
+ while(i < Rows && artifs == FALSE) {
+ i++;
+ f = Upbo[Bas[i]];
+ if (f == 0 && (Rhs[i] != 0)) {
+ artifs = TRUE;
+ row_nr.value = i;
+ } else {
+ if (Rhs[i] < f - Rhs[i]) g = Rhs[i];
+ else g = f - Rhs[i];
+ if (g < minrhs) {
+ minrhs = g;
+ row_nr.value = i;
+ }
+ }
+ }
+ return(row_nr.value > 0 ? (short)1 : (short)0);
+ }
+
+ private short coldual(int row_nr, Ref colnr, short minit, float[] prow, float[] drow) {
+ int r, varnr;
+ float theta, quot, pivot, d, f, g;
+ Doiter = FALSE;
+ if (minit == FALSE) {
+ for(int i = 0; i <= Rows; i++) {
+ prow[i] = 0;
+ drow[i] = 0;
+ }
+ drow[0] = 1;
+ prow[row_nr] = 1;
+ for(int i = Eta_size; i >= 1; i--) {
+ d = 0;
+ f = 0;
+ r = Eta_row_nr[Eta_col_end[i] - 1];
+ for(int j = Eta_col_end[i - 1]; j < Eta_col_end[i]; j++) {
+ /* this is where the program consumes most cpu time */
+ f += prow[Eta_row_nr[j]] * Eta_value[j];
+ d += drow[Eta_row_nr[j]] * Eta_value[j];
+ }
+ f = round(f, Epsel);
+ prow[r] = f;
+ d = round(d, Epsel);
+ drow[r] = d;
+ }
+ for(int i = 1; i <= columns; i++) {
+ varnr = Rows + i;
+ if (Basis[varnr] == FALSE) {
+ d = - Extrad * drow[0];
+ f = 0;
+ for(int j = Col_end[i - 1]; j < Col_end[i]; j++) {
+ d = d + drow[get_row_nr(Mat, j)] * get_value(Mat,j);
+ f = f + prow[get_row_nr(Mat, j)] * get_value(Mat,j);
+ }
+ drow[varnr] = d;
+ prow[varnr] = f;
+ }
+ }
+ for(int i = 0; i <= Sum; i++) {
+ prow[i] = round(prow[i], Epsel);
+ drow[i] = round(drow[i], Epsd);
+ }
+ }
+ if (Rhs[row_nr] > Upbo[Bas[row_nr]]) g = -1;
+ else g = 1;
+ pivot = 0;
+ colnr.value = 0;
+ theta = Infinite;
+ for(int i = 1; i <= Sum; i++) {
+ if (Lower[i] != FALSE) d = prow[i] * g;
+ else d = -prow[i] * g;
+ if ((d < 0) && (Basis[i] == FALSE) && (Upbo[i] > 0)) {
+ if (Lower[i] == FALSE) quot = -drow[i] / (float) d;
+ else quot = drow[i] / (float) d;
+ if (quot < theta) {
+ theta = quot;
+ pivot = d;
+ colnr.value = i;
+ } else if ((quot == theta) && (Math.abs(d) > Math.abs(pivot))) {
+ pivot = d;
+ colnr.value = i;
+ }
+ }
+ }
+ if (colnr.value > 0) Doiter = TRUE;
+ return(colnr.value > 0 ? (short)1 : (short)0);
+ }
+
+ private void iteration(int row_nr, int varin, Ref theta, float up, Ref minit, Ref low, short primal,float[] pcol) {
+ int k, varout;
+ float f;
+ float pivot;
+ iter++;
+ minit.value = theta.value > (up + Epsb) ? 1 : 0;
+ if (minit.value != 0) {
+ theta.value = up;
+ low.value = low.value == 0 ? 1 : 0;
+ }
+ k = Eta_col_end[Eta_size + 1];
+ pivot = Eta_value[k - 1];
+ for(int i = Eta_col_end[Eta_size]; i < k; i++) {
+ f = Rhs[Eta_row_nr[i]] - theta.value * Eta_value[i];
+ f = round(f, Epsb);
+ Rhs[Eta_row_nr[i]] = f;
+ }
+ if (minit.value == 0) {
+ Rhs[row_nr] = theta.value;
+ varout = Bas[row_nr];
+ Bas[row_nr] = varin;
+ Basis[varout] = FALSE;
+ Basis[varin] = TRUE;
+ if (primal != FALSE && pivot < 0) Lower[varout] = FALSE;
+ if (low.value == 0 && up < Infinite) {
+ low.value = TRUE;
+ Rhs[row_nr] = up - Rhs[row_nr];
+ for(int i = Eta_col_end[Eta_size]; i < k; i++) Eta_value[i] = -Eta_value[i];
+ }
+ addetacol();
+ Num_inv++;
+ }
+ }
+
+ static float[] drow = new float[65535];
+ static float[] prow = new float[65535];
+ static float[] Pcol = new float[65535];
+
+ private int solvelp() {
+ int varnr;
+ float f = 0, theta = 0;
+ short primal;
+ short minit;
+ int colnr, row_nr;
+ colnr = 0;
+ row_nr = 0;
+ short flag;
+ Ref ref1, ref2, ref3;
+ ref1 = new Ref(0);
+ ref2 = new Ref(0);
+ ref3 = new Ref(0);
+
+ for(int i = 0; i <= Sum; i++) { drow[i] = 0; prow[i] = 0; }
+ for(int i = 0; i <= Rows; i++) Pcol[i] = 0;
+ iter = 0;
+ minit = FALSE;
+ Status = RUNNING;
+ DoInvert = FALSE;
+ Doiter = FALSE;
+ primal = TRUE;
+ for(int i = 0; i != Rows && primal != FALSE;) {
+ i++;
+ primal = (Rhs[i] >= 0 && Rhs[i] <= Upbo[Bas[i]]) ? (short)1: (short)0;
+ }
+ if (primal == FALSE) {
+ drow[0] = 1;
+ for(int i = 1; i <= Rows; i++) drow[i] = 0;
+ Extrad = 0;
+ for(int i = 1; i <= columns; i++) {
+ varnr = Rows + i;
+ drow[varnr] = 0;
+ for(int j = Col_end[i - 1]; j < Col_end[i]; j++)
+ if (drow[get_row_nr(Mat, j)] != 0)
+ drow[varnr] += drow[get_row_nr(Mat, j)] * get_value(Mat,j);
+ if (drow[varnr] < Extrad) Extrad = drow[varnr];
+ }
+ } else {
+ Extrad = 0;
+ }
+ minit = FALSE;
+ while(Status == RUNNING) {
+ Doiter = FALSE;
+ DoInvert = FALSE;
+ construct_solution(Solution);
+ if (primal != FALSE) {
+ ref1.value = colnr;
+ flag = colprim(ref1, minit, drow);
+ colnr = (int)ref1.value;
+ if (flag != FALSE) {
+ setpivcol(Lower[colnr], colnr, Pcol);
+ ref1.value = row_nr;
+ ref2.value = theta;
+ flag = rowprim(colnr, ref1, ref2, Pcol);
+ row_nr = (int)ref1.value;
+ theta = ref2.value;
+ if (flag != FALSE) condensecol(row_nr, Pcol);
+ }
+ } else {
+ if (minit == FALSE) {
+ ref1.value = row_nr;
+ flag = rowdual(ref1);
+ row_nr = (int)ref1.value;
+ }
+ if (row_nr > 0) {
+ ref1.value = colnr;
+ flag = coldual(row_nr, ref1, minit, prow, drow);
+ colnr = (int)ref1.value;
+ if (flag != FALSE) {
+ setpivcol(Lower[colnr], colnr, Pcol);
+ /* getting div by zero here ... MB */
+ if (Pcol[row_nr] == 0) {
+ throw new Error("An attempt was made to divide by zero (Pcol[" + row_nr + "])");
+ } else {
+ condensecol(row_nr, Pcol);
+ f = Rhs[row_nr] - Upbo[Bas[row_nr]];
+ if (f > 0) {
+ theta = f / (float) Pcol[row_nr];
+ if (theta <= Upbo[colnr])
+ Lower[Bas[row_nr]] = (Lower[Bas[row_nr]] == FALSE)? (short)1:(short)0;
+ } else theta = Rhs[row_nr] / (float) Pcol[row_nr];
+ }
+ } else Status = INFEASIBLE;
+ } else {
+ primal = TRUE;
+ Doiter = FALSE;
+ Extrad = 0;
+ DoInvert = TRUE;
+ }
+ }
+ if (Doiter != FALSE) {
+ ref1.value = theta;
+ ref2.value = minit;
+ ref3.value = Lower[colnr];
+ iteration(row_nr, colnr, ref1, Upbo[colnr], ref2, ref3, primal, Pcol);
+ theta = ref1.value;
+ minit = (short)ref2.value;
+ Lower[colnr] = (short)ref3.value;
+ }
+ if (Num_inv >= max_num_inv) DoInvert = TRUE;
+ if (DoInvert != FALSE) invert();
+ }
+ total_iter += iter;
+ return(Status);
+ }
+
+ private void construct_solution(float[] sol) {
+ float f;
+ int basi;
+ for(int i = 0; i <= Rows; i++) sol[i] = 0;
+ for(int i = Rows + 1; i <= Sum; i++) sol[i] = Lowbo[i];
+ for(int i = 1; i <= Rows; i++) {
+ basi = Bas[i];
+ if (basi > Rows) sol[basi] += Rhs[i];
+ }
+ for(int i = Rows + 1; i <= Sum; i++)
+ if (Basis[i] == FALSE && Lower[i] == FALSE)
+ sol[i] += Upbo[i];
+ for(int j = 1; j <= columns; j++) {
+ f = sol[Rows + j];
+ if (f != 0)
+ for(int i = Col_end[j - 1]; i < Col_end[j]; i++)
+ sol[get_row_nr(Mat, i)] += f * get_value(Mat,i);
+ }
+ for(int i = 0; i <= Rows; i++) {
+ if (Math.abs(sol[i]) < Epsb) sol[i] = 0;
+ else if (ch_sign[i] != FALSE) sol[i] = -sol[i];
+ }
+ }
+
+ private void calculate_duals() {
+ for(int i = 1; i <= Rows; i++) duals[i] = 0;
+ duals[0] = 1;
+ btran(duals);
+ for(int i = 1; i <= Rows; i++) {
+ if (basis[i] != FALSE) duals[i] = 0;
+ else if ( ch_sign[0] == ch_sign[i]) duals[i] = -duals[i];
+ }
+ }
+
+ private static Random rdm = new Random();
+
+ private int milpsolve(float[] upbo, float[] lowbo, short[] sbasis, short[] slower, int[] sbas) {
+ int failure, notint, is_worse;
+ float theta, tmpfloat;
+ notint = 0;
+
+ if (Break_bb != FALSE) return(BREAK_BB);
+ Level++;
+ total_nodes++;
+ if (Level > max_level) max_level = Level;
+ System.arraycopy(upbo, 0, Upbo, 0, Sum + 1);
+ System.arraycopy(lowbo, 0, Lowbo, 0, Sum + 1);
+ System.arraycopy(sbasis, 0, Basis, 0, Sum + 1);
+ System.arraycopy(slower, 0, Lower, 0, Sum + 1);
+ System.arraycopy(sbas, 0, Bas, 0, Rows + 1);
+ System.arraycopy(Orig_rh, 0, Rh, 0, Rows + 1);
+ if (eta_valid == FALSE) {
+ for(int i = 1; i <= columns; i++)
+ if (Lowbo[Rows + i] != 0) {
+ theta = Lowbo[ Rows + i];
+ if (Upbo[Rows + i]<Infinite) Upbo[Rows + i] -= theta;
+ for(int j = Col_end[i - 1]; j < Col_end[i]; j++) Rh[get_row_nr(Mat, j)] -= theta * get_value(Mat,j);
+ }
+ invert();
+ eta_valid = TRUE;
+ }
+ failure = solvelp();
+ if (failure == OPTIMAL) {
+ construct_solution(Solution);
+ /* if this solution is worse than the best sofar, this branch must die */
+ if (Maximise != FALSE) is_worse = (Solution[0] <= Best_solution[0]) ? 1:0;
+ else is_worse = (Solution[0] >= Best_solution[0]) ? 1:0;
+ if (is_worse != FALSE) {
+ Level--;
+ return(MILP_FAIL);
+ }
+ /* check if solution contains enough ints */
+ if (bb_rule == FIRST_NI) {
+ notint = 0;
+ int i = Rows + 1;
+ while(i <= Sum && notint == 0) i++;
+ }
+ if (bb_rule == RAND_NI) {
+ int nr_not_int, select_not_int;
+ nr_not_int = 0;
+ for(int i = Rows + 1; i <= Sum; i++)
+ if (nr_not_int == 0) notint = 0;
+ else {
+ select_not_int=(rdm.nextInt() % nr_not_int) + 1;
+ i = Rows + 1;
+ while(select_not_int > 0) i++;
+ notint = i - 1;
+ }
+ }
+ if (notint != FALSE) throw new Error("integer linear programming not supported");
+ if (Maximise != FALSE) is_worse = (Solution[0] < Best_solution[0]) ? 1:0;
+ else is_worse = (Solution[0] > Best_solution[0]) ? 1:0;
+ if (is_worse == FALSE) {
+ System.arraycopy(Solution, 0, Best_solution, 0, Sum + 1);
+ calculate_duals();
+ if (break_at_int != FALSE) {
+ if (Maximise != FALSE && (Best_solution[0] > break_value)) Break_bb = TRUE;
+ if (Maximise == FALSE && (Best_solution[0] < break_value)) Break_bb = TRUE;
+ }
+ }
+ }
+ Level--;
+ return(failure);
+ }
+
+ public int solve() {
+ int result = FAILURE;
+ if (active == FALSE) set_globals();
+ total_iter = 0;
+ max_level = 1;
+ total_nodes = 0;
+ if (Isvalid() != FALSE) {
+ if (Maximise != FALSE && obj_bound == Infinite) Best_solution[0]=-Infinite;
+ else if (Maximise == FALSE && obj_bound==-Infinite) Best_solution[0] = Infinite;
+ else Best_solution[0] = obj_bound;
+ Level = 0;
+ if (basis_valid == FALSE) {
+ for(int i = 0; i <= rows; i++) {
+ basis[i] = TRUE;
+ bas[i] = i;
+ }
+ for(int i = rows+1; i <= sum; i++) basis[i] = FALSE;
+ for(int i = 0; i <= sum; i++) lower[i] = TRUE;
+ basis_valid = TRUE;
+ }
+ eta_valid = FALSE;
+ Break_bb = FALSE;
+ result = milpsolve(Orig_upbo, Orig_lowbo, Basis, Lower, Bas);
+ eta_size = Eta_size;
+ eta_alloc = Eta_alloc;
+ num_inv = Num_inv;
+ }
+ for(int i = 0; i < maxmat; i++) { set_row_nr(mat,i, 0); set_value(mat, i, 0); }
+ for(int i = 0; i < maxmat; i++) col_no[i] = 0;
+
+ // FIXME: not sure about this
+ for(int i = 0; i < Eta_size; i++) eta_value[i] = 0;
+ for(int i = 0; i < Eta_size; i++) eta_row_nr[i] = 0;
+ for(int i = 0; i < Eta_size; i++) eta_col_end[i] = 0;
+
+ maxmat = 0;
+ return(result);
+ }
+
+ private int maxmat = 0;
+ private final static float round( float val, float eps) { return (Math.abs(val) < eps) ? 0 : val; }
+ int get_row_nr(MatrixArray m, int i) { return m.row_nr[i]; }
+ void set_row_nr(MatrixArray m, int i, int val) { m.row_nr[i] = val; maxmat = Math.max(i, maxmat); }
+ float get_value(MatrixArray m, int i) { return m.value[i]; }
+ void set_value(MatrixArray m, int i, float val) { m.value[i] = val; maxmat = Math.max(i, maxmat); }
+ public static class MatrixArray {
+ public int[] row_nr;
+ public float[] value;
+ public final int length;
+ public MatrixArray(int length) { row_nr = new int[length]; value = new float[length]; this.length = length; }
+ }
+
+}
+
--- /dev/null
+// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL]
+package org.ibex.util;
+import java.io.IOException;
+import org.ibex.js.*;
+
+public interface Task {
+ public abstract void perform() throws IOException, JSExn;
+}
--- /dev/null
+// Copyright (C) 2003 Adam Megacz <adam@ibex.org> all rights reserved.
+//
+// You may modify, copy, and redistribute this code under the terms of
+// the GNU Library Public License version 2.1, with the exception of
+// the portion of clause 6a after the semicolon (aka the "obnoxious
+// relink clause")
+
+package org.ibex.util;
+
+import java.io.*;
+
+/**
+ * An unsynchronized Vector implementation; same semantics as
+ * java.util.Vector. Useful for JDK1.1 platforms that don't have
+ * java.util.ArrayList.
+ *
+ * May contain nulls.
+ *
+ * @see java.util.Vector
+ */
+public final class Vec implements Serializable {
+
+ private Object[] store;
+ private int size = 0;
+
+ public Vec() { this(10); }
+ public Vec(int i) { store = new Object[i]; }
+ public Vec(int i, Object[] store) { size = i; this.store = store; }
+
+ private void grow() { grow(store.length * 2); }
+ private void grow(int newsize) {
+ Object[] newstore = new Object[newsize];
+ System.arraycopy(store, 0, newstore, 0, size);
+ store = newstore;
+ }
+
+ public void removeAllElements() {
+ for(int i=0; i<size; i++) store[i] = null;
+ size = 0;
+ }
+
+ public void toArray(Object[] o) {
+ for(int i=0; i<size; i++)
+ o[i] = store[i];
+ }
+
+ public int indexOf(Object o) {
+ for(int i=0; i<size; i++)
+ if (o == null ? store[i] == null : store[i].equals(o)) return i;
+
+ return -1;
+ }
+
+ public void addElement(Object o) {
+ if (size >= store.length - 1) grow();
+ store[size++] = o;
+ }
+
+ public Object peek() {
+ return lastElement();
+ }
+
+ public Object elementAt(int i) {
+ return store[i];
+ }
+
+ public Object lastElement() {
+ if (size == 0) return null;
+ return store[size - 1];
+ }
+
+ public void push(Object o) { addElement(o); }
+ public Object pop() {
+ Object ret = lastElement();
+ if (size > 0) store[size--] = null;
+ return ret;
+ }
+
+ public int size() { return size; }
+
+ public void setSize(int newSize) {
+ if (newSize < 0) throw new RuntimeException("tried to set size to negative value");
+ if (newSize > store.length) grow(newSize * 2);
+ if (newSize < size)
+ for(int i=newSize; i<size; i++)
+ store[i] = null;
+ size = newSize;
+ }
+
+ public void copyInto(Object[] out) {
+ for(int i=0; i<size; i++)
+ out[i] = store[i];
+ }
+
+ public void fromArray(Object[] in) {
+ setSize(in.length);
+ for(int i=0; i<size; i++)
+ store[i] = in[i];
+ }
+
+ public void removeElementAt(int i) {
+ if (i >= size || i < 0) throw new RuntimeException("tried to remove an element outside the vector's limits");
+ for(int j=i; j<size - 1; j++)
+ store[j] = store[j + 1];
+ setSize(size - 1);
+ }
+
+ public void setElementAt(Object o, int i) {
+ if (i >= size) setSize(i);
+ store[i] = o;
+ }
+
+ public void removeElement(Object o) {
+ int idx = indexOf(o);
+ if (idx != -1) removeElementAt(idx);
+ }
+
+ public void insertElementAt(Object o, int at) {
+ if (size == store.length) grow();
+ for(int i=size; i>at; i--)
+ store[i] = store[i-1];
+ store[at] = o;
+ size++;
+ }
+
+ public interface CompareFunc {
+ public int compare(Object a, Object b);
+ }
+
+ public void sort(CompareFunc c) {
+ sort(this, null, c, 0, size-1);
+ }
+
+ public static void sort(Vec a, Vec b, CompareFunc c) {
+ if (b != null && a.size != b.size) throw new IllegalArgumentException("Vec a and b must be of equal size");
+ sort(a, b, c, 0, a.size-1);
+ }
+
+ private static final void sort(Vec a, Vec b, CompareFunc c, int start, int end) {
+ Object tmpa, tmpb = null;
+ if(start >= end) return;
+ if(end-start <= 6) {
+ for(int i=start+1;i<=end;i++) {
+ tmpa = a.store[i];
+ if (b != null) tmpb = b.store[i];
+ int j;
+ for(j=i-1;j>=start;j--) {
+ if(c.compare(a.store[j],tmpa) <= 0) break;
+ a.store[j+1] = a.store[j];
+ if (b != null) b.store[j+1] = b.store[j];
+ }
+ a.store[j+1] = tmpa;
+ if (b != null) b.store[j+1] = tmpb;
+ }
+ return;
+ }
+
+ Object pivot = a.store[end];
+ int lo = start - 1;
+ int hi = end;
+
+ do {
+ while(c.compare(a.store[++lo],pivot) < 0) { }
+ while((hi > lo) && c.compare(a.store[--hi],pivot) > 0) { }
+ swap(a, lo,hi);
+ if (b != null) swap(b, lo,hi);
+ } while(lo < hi);
+
+ swap(a, lo,end);
+ if (b != null) swap(b, lo,end);
+
+ sort(a, b, c, start, lo-1);
+ sort(a, b, c, lo+1, end);
+ }
+
+ private static final void swap(Vec vec, int a, int b) {
+ if(a != b) {
+ Object tmp = vec.store[a];
+ vec.store[a] = vec.store[b];
+ vec.store[b] = tmp;
+ }
+ }
+
+ public static final void sortInts(int[] a, int start, int end) {
+ int tmpa;
+ if(start >= end) return;
+ if(end-start <= 6) {
+ for(int i=start+1;i<=end;i++) {
+ tmpa = a[i];
+ int j;
+ for(j=i-1;j>=start;j--) {
+ if(a[j] <= tmpa) break;
+ a[j+1] = a[j];
+ }
+ a[j+1] = tmpa;
+ }
+ return;
+ }
+
+ int pivot = a[end];
+ int lo = start - 1;
+ int hi = end;
+
+ do {
+ while(a[++lo] < pivot) { }
+ while((hi > lo) && a[--hi] > pivot) { }
+ swapInts(a, lo, hi);
+ } while(lo < hi);
+ swapInts(a, lo, end);
+ sortInts(a, start, lo-1);
+ sortInts(a, lo+1, end);
+ }
+
+ private static final void swapInts(int[] vec, int a, int b) {
+ if(a != b) {
+ int tmp = vec[a];
+ vec[a] = vec[b];
+ vec[b] = tmp;
+ }
+ }
+}
--- /dev/null
+// Copyright (C) 2003 Adam Megacz <adam@ibex.org> all rights reserved.
+//
+// You may modify, copy, and redistribute this code under the terms of
+// the GNU Library Public License version 2.1, with the exception of
+// the portion of clause 6a after the semicolon (aka the "obnoxious
+// relink clause")
+
+package org.ibex.util;
+
+import java.io.Reader;
+import java.io.IOException;
+import java.io.EOFException;
+
+/**
+ * An Event-Driving, Non-Validating XML Parser with Namespace support.
+ *
+ * A subclass can implement the abstract functions for receiving details
+ * about an xml file as it is parsed. To initate a parse, use the parse()
+ * function.
+ *
+ * <h3>Implementation Notes</h3>
+ * <p>As the parser traverses into an element, it adds it to the linked list
+ * called <tt>elements</tt>. However, <tt>elements</tt> has been pre-filled
+ * with instances of the Element inner class. So in the vast majority of
+ * cases, the pointer current is moved along one, and the values for the
+ * new element are filled into the current object.</p>
+ *
+ * <p>This parser supports all the unicode ranges required by the XML
+ * Specification. However, it is optimised for well-formed ASCII documents.
+ * Documents containing unicode Names and Attributes will take much longer
+ * to process, and invalid documents (badly formed Names or invalid attributes)
+ * will be run through a test on every single unicode character range before
+ * being declared invalid.</p>
+ *
+ * <ul>
+ * <li>Each time the buffer offset <tt>off</tt> is moved, the length
+ * <tt>len</tt> must be decreased.</li>
+ * <li>Each time the buffer length is decreased, it must be checked to make
+ * sure it is >0.</li>
+ * <li><i>error</i> is defined as a Validity Constraint Violation and
+ * is recoverable</li>
+ * <li><i>fatal error</i> is defined as a Well-formedness Constraint
+ * Violation and is not recoverable</li>
+ * </ul>
+ *
+ * @author David Crawshaw
+ * @see <a href="http://w3.org/TR/REC-xml">XML Specification</a>
+ * @see <a href="http://w3.org/TR/REC-xml-names">XML Namespaces</a>
+ */
+public abstract class XML
+{
+ /////////////////////////////////////////////////////////////////////////////////////////////
+ // XML Parser
+ /////////////////////////////////////////////////////////////////////////////////////////////
+
+ public static final int BUFFER_SIZE = 255;
+
+ /** static pool of XML.Element instances shared by all XML Parsers. */
+ private static final Queue elements = new Queue(30);
+
+ private static final char[] single_amp = new char[] { '&' };
+ private static final char[] single_apos = new char[] { '\'' };
+ private static final char[] single_gt = new char[] { '>' };
+ private static final char[] single_lt = new char[] { '<' };
+ private static final char[] single_quot = new char[] { '"' };
+
+ private int line;
+ private int col;
+
+ private Reader in;
+ private char[] buf;
+ private int off;
+ private int base; // base+off == distance into the stream
+ private int len;
+
+ private Element current;
+
+ // used in readEntity() to process a single character without creating a new array
+ private char[] singlechar = new char[1];
+
+
+ public XML() { this(BUFFER_SIZE); }
+
+ public XML(int bSize) {
+ buf = new char[bSize];
+
+ current = (Element)elements.remove(false);
+ if (current == null) current = new Element();
+ }
+
+ /** Returns the line number at the beginning of the last process call. */
+ public int getLine() { return line; }
+
+ /** Returns the column number at the beginning of the last process call. */
+ public int getCol() { return col; }
+
+ /** Returns the global file offset at the beginning of the last process call. */
+ public int getGlobalOffset() { return base + off; }
+
+ /**
+ * Parse given input and call the abstract event functions.
+ *
+ * Careful with threading, as this function is not synchronized.
+ */
+ public final void parse(Reader reader) throws IOException, Exn {
+ in = reader;
+ off = len = 0;
+ line = col = 1;
+
+ clear(); // clean up possible mid-way linked-list element
+
+ try {
+ // process the stream
+ while (true) {
+ if (!buffer(1)) {
+ if (current.qName == null) break;
+ throw new Exn("reached eof without closing <"+current.qName+"> element", Exn.WFC, getLine(), getCol());
+ }
+
+ if (buf[off] == '<') readTag();
+ readChars(current.qName != null);
+ }
+ } finally { clear(); } // clean up elements
+ }
+
+ /** remove any leftover elements from the linked list and queue them */
+ private final void clear() {
+ for (Element last = current; current.parent != null; ) {
+ current = current.parent;
+ last.clear();
+ elements.append(last);
+ }
+ current.clear();
+ }
+
+ /** reads in a tag. expects <tt>buf[off] == '<'</tt> */
+ private final void readTag() throws IOException, Exn {
+ // Start Tag '<' Name (S Attribute)* S? '>'
+ boolean starttag = true;
+
+ // End Tag '</' Name S? '>'
+ boolean endtag = false;
+
+ // if (starttag & endtag) then: EmptyElemTag '<' Name (S Attribute)* S? '/>'
+
+ // Position in the name of the ':' namespace prefix
+ int prefix = -1;
+
+ int namelen = 0;
+
+ col++; off++; len--;
+ if (!buffer(1)) throw new EOFException("Unexpected EOF processing element tag");
+
+ // work out what we can from the beginning of the tag
+ char s = buf[off];
+ if (s == '!') {
+ // definitions here don't necessarily conform to xml spec (as DTDs not yet implemented)
+ col++; off++; len--;
+ if (!buffer(4)) throw new EOFException("Unexpected EOF processing <! element");
+
+ boolean bad = false;
+ switch (buf[off]) {
+ case '-':
+ if (buf[off+1] != '-') { bad = true; break; }
+ col += 2; off += 2; len -= 2;
+
+ // Comment '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
+ readChars(false, "-->", false);
+ col += 3; off += 3; len -= 3;
+ break;
+
+ // we don't care about the following definitions
+
+ case 'A':
+ if (!buffer(7)
+ || buf[off+1] != 'T' || buf[off+2] != 'T' || buf[off+3] != 'L'
+ || buf[off+4] != 'I' || buf[off+5] != 'S' || buf[off+6] != 'T') {
+ bad = true; break;
+ }
+ col += 7; off += 7; len -= 7;
+
+ // ATTLIST '<!ATTLIST' (Char* - '>') '>'
+ readChars(false, ">", true);
+ col++; off++; len--;
+ break;
+ case 'D':
+ if (!buffer(7)
+ || buf[off+1] != 'O' || buf[off+2] != 'C' || buf[off+3] != 'T'
+ || buf[off+4] != 'Y' || buf[off+5] != 'P' || buf[off+6] != 'E') {
+ bad = true; break;
+ }
+ col += 7; off += 7; len -= 7;
+
+ // DTD '<!DOCTYPE' (Char* - '>') '>'
+ readChars(false, ">", true);
+ col++; off++; len--;
+ break;
+ case 'E':
+ if (!buffer(7)) {
+ bad = true;
+ } else if (buf[off+1] == 'L' && buf[off+2] == 'E' && buf[off+3] == 'M'
+ && buf[off+4] == 'E' && buf[off+5] == 'N' && buf[off+6] == 'T') {
+ // ELEMENT '<!ELEMENT' (Char* - '>') '>'
+ readChars(false, ">", true);
+ col++; off++; len--;
+
+ } else if (buf[off+1] == 'N' && buf[off+2] == 'T' && buf[off+3] == 'I'
+ && buf[off+4] == 'T' && buf[off+5] == 'Y') {
+ // ENTITY '<!ENTITY' (Char* - '>') '>'
+ readChars(false, ">", true);
+ col++; off++; len--;
+
+ } else {
+ bad = true;
+ }
+ break;
+
+ case 'N':
+ if (!buffer(8)
+ || buf[off+1] != 'O' || buf[off+2] != 'T' || buf[off+3] != 'A' || buf[off+4] != 'T'
+ || buf[off+5] != 'I' || buf[off+6] != 'O' || buf[off+7] != 'N') {
+ bad = true; break;
+ }
+ col += 8; off += 8; len -= 8;
+ // NOTATION '<!NOTATION' (Char* - '>') '>'
+ readChars(false, ">", true);
+ col++; off++; len--;
+
+ break;
+ default: bad = true;
+ }
+
+ if (bad) throw new Exn("element tag start character is invalid", Exn.MARKUP, getLine(), getCol());
+
+ } else if (s == '?') {
+ // PI (Ignored) '<?' (Char* - (Char* '?>' Char*)) '?>'
+ col++; off++; len--;
+ readChars(false, "?>", true);
+ if (!buffer(2)) throw new EOFException("Unexpected EOF at end of Processing Instruction");
+ col += 2; off += 2; len -= 2;
+
+ } else if (s == '[') {
+ if (!buffer(7)
+ || buf[off+1] != 'C' || buf[off+2] != 'D' || buf[off+3] != 'A'
+ || buf[off+4] != 'T' || buf[off+5] != 'A' || buf[off+6] != '[') {
+ col++; off--; len++;
+ // Conditional '<![' (Char* - (Char* ']]>' Char*)) ']]>'
+ readChars(false, "]]>", false);
+ } else {
+ col += 7; off += 7; len -=7;
+ // CDATA '<![CDATA[' (Char* - (Char* ']]>' Char*)) ']]>'
+ readChars(true, "]]>", false);
+ }
+ col += 3; off += 3; len -= 3;
+ } else {
+ if (s == '/') {
+ // End Tag '</' Name S? '>'
+ starttag = false;
+ endtag = true;
+
+ col++; off++; len--;
+ if (!buffer(1)) throw new EOFException("Unexpected EOF processing end tag");
+ s = buf[off];
+ }
+
+ if (!Name(s)) throw new Exn("invalid starting character in element name", Exn.MARKUP, getLine(), getCol());
+
+ // find the element name (defined in XML Spec: section 2.3)
+ for (namelen = 0; ; namelen++) {
+ if (!buffer(namelen+1)) throw new EOFException("Unexpected EOF in element tag name");
+
+ s = buf[off+namelen];
+
+ if (S(s) || s == '>') {
+ break;
+ } else if (s == '/') {
+ endtag = true;
+ break;
+ } else if (s == ':' && namelen > 0 && prefix < 1) {
+ // we have a definition of the prefix range available
+ prefix = namelen;
+ } else if (!NameChar(s)) {
+ throw new Exn("element name contains invalid character", Exn.MARKUP, getLine(), getCol());
+ }
+ }
+
+ // process name (based on calculated region)
+ if (namelen < 1) throw new Exn("element name is null", Exn.MARKUP, getLine(), getCol());
+
+ // we have marked out the name region, so turn it into a string and move on
+ String qName = new String(buf, off, namelen);
+
+ col += namelen; off += namelen; len -= namelen;
+
+ if (starttag) {
+ // create the in-memory element representation of this beast
+ // if current.qName == null then this is the root element we're dealing with
+ if (current.qName != null) {
+ Element next = (Element)elements.remove(false);
+ if (next == null) next = new Element();
+ //next.clear(); // TODO: remove as elements now checked as they're added to the queue
+ next.parent = current;
+ current = next;
+ }
+
+ current.qName = qName;
+
+ if (prefix > 0) {
+ current.prefix = current.qName.substring(0, prefix);
+ current.localName = current.qName.substring(prefix+1);
+ } else {
+ current.prefix = null;
+ current.localName = current.qName;
+ }
+
+ // process attributes
+ readWhitespace();
+ if (!buffer(1)) throw new EOFException("Unexpected EOF - processing attributes part 1");
+ while (buf[off] != '/' && buf[off] != '>') {
+ readAttribute();
+ if (!buffer(1)) throw new EOFException("Unexpected EOF - processing attributes part 2");
+ readWhitespace();
+ }
+
+ // work out the uri of this element
+ current.uri = current.getUri(current.getPrefix());
+ if (current.getUri().equals("") && current.getPrefix() != null)
+ current.addError(new Exn("undefined prefix '"+current.getPrefix()+"'", Exn.NC, getLine(), getCol()));
+
+ } else {
+ // this is an end-of-element tag
+ if (!qName.equals(current.getQName())) throw new Exn(
+ "end tag </"+qName+"> does not line up with start tag <"+current.getQName()+">", Exn.WFC, getLine(), getCol()
+ );
+ }
+
+ // deal with whitespace
+ readWhitespace();
+
+ // process tag close
+ if (!buffer(1)) throw new EOFException("Unexpected EOF before end of tag");
+ if (buf[off] == '/') {
+ endtag = true;
+ off++; len--; col++;
+ }
+ if (!buffer(1)) throw new EOFException("Unexpected EOF before end of endtag");
+ if (buf[off] == '>') {
+ off++; len--; col++;
+ } else {
+ throw new Exn("missing '>' character from element '"+qName+"'", Exn.MARKUP, getLine(), getCol());
+ }
+
+ // send element signals
+ if (starttag) startElement(current);
+ if (endtag) {
+ endElement(current);
+
+ // we just closed an element, so remove it from the element 'stack'
+ if (current.getParent() == null) {
+ // we just finished the root element
+ current.clear();
+ } else {
+ Element last = current;
+ current = current.parent;
+ last.clear();
+ elements.append(last);
+ }
+ }
+ }
+ }
+
+ /** reads in an attribute of an element. expects Name(buf[off]) */
+ private final void readAttribute() throws IOException, Exn {
+ int ref = 0;
+ int prefix = 0;
+ String n, v, p, u; // attribute name, value, prefix and uri respectively
+ n = v = p = u = null;
+ char s;
+
+ // find the element name (defined in XML Spec: section 2.3)
+ for (ref= 0; ; ref++) {
+ if (!buffer(ref+1)) throw new EOFException("Unexpected EOF in read attribute loop part 1");
+
+ s = buf[off+ref];
+
+ if (s == '=' || S(s)) {
+ break;
+ } else if (s == ':' && ref > 0 && prefix < 1) {
+ // we have a definition of the prefix range available
+ prefix = ref+1;
+ } else if (!NameChar(s)) {
+ throw new Exn("attribute name contains invalid characters", Exn.MARKUP, getLine(), getCol());
+ }
+ }
+
+ // determine prefix and key name
+ if (prefix > 0) {
+ p = new String(buf, off, prefix-1);
+ col += prefix; off += prefix; len -= prefix; ref -= prefix;
+ }
+ n = new String(buf, off, ref);
+ col += ref; off += ref; len -= ref;
+
+ // find name/value divider ('=')
+ readWhitespace();
+ if (!buffer(1)) throw new EOFException("Unexpected EOF before attribute '=' divider");
+ if (buf[off] != '=') throw new Exn("attribute name not followed by '=' sign", Exn.MARKUP, getLine(), getCol());
+
+ col++; off++; len--;
+ readWhitespace();
+
+ if (!buffer(1)) throw new EOFException("Unexpected EOF after attribute '=' divider");
+
+ char wrap;
+ if (buf[off] == '\'' || buf[off] == '"') {
+ wrap = buf[off];
+ } else {
+ throw new Exn("attribute '"+n+"' must have attribute wrapped in ' or \"", Exn.MARKUP, getLine(), getCol());
+ }
+ col++; off++; len--;
+
+ // find the attribute value
+ attval: for (ref = 0; ; ref++) {
+ if (!buffer(ref+1)) throw new EOFException("Unexpected EOF in attribute value");
+
+ if (buf[off+ref] == wrap) {
+ break attval;
+ } else if (buf[off+ref] == '<') {
+ throw new Exn("attribute value for '"+n+"' must not contain '<'", Exn.WFC, getLine(), getCol());
+ }
+ }
+
+ v = new String(buf, off, ref);
+ col += ref; off += ref; len -= ref;
+
+ // remove end wrapper character
+ col++; off++; len--;
+
+ // process attribute
+ if (p != null && p.equals("xmlns")) {
+ current.addUri(n, v);
+ } else if (n.equals("xmlns")) {
+ if (current.getUri().equals("")) {
+ current.addUri("", v);
+ } else {
+ current.addError(new Exn("default namespace definition repeated", Exn.NC, getLine(), getCol()));
+ }
+ } else {
+ // find attribute uri
+ u = current.getUri(p);
+ if (p != null && u.equals("")) current.addError(new Exn("undefined attribute prefix '"+p+"'", Exn.NC, getLine(), getCol()));
+
+ // check to see if attribute is a repeat
+ for (int i=0; current.len > i; i++) if (n.equals(current.getAttrKey(i)) && u.equals(current.getAttrUri(i))) throw new Exn(
+ "attribute name '"+n+"' may not appear more than once in the same element tag", Exn.WFC, getLine(), getCol()
+ );
+
+ current.addAttr(n, v, u);
+ }
+ }
+
+ /** reads an entity and processes out its value. expects buf[off] == '&' */
+ private final void readEntity() throws IOException, Exn {
+ off++; len--;
+ if (!buffer(2)) throw new EOFException("Unexpected EOF reading entity");
+
+ boolean unknown = false;
+ switch (buf[off]) {
+ case '#':
+ off++; len--;
+
+ int radix;
+ if (buf[off] == 'x') { off++; len--; radix = 16; } else { radix = 10; }
+ int c = 0;
+
+ // read in each char, then shift total value to the left and add the extra
+ // style of loop is slightly different from all the others, as this should run a limited number of times
+ findchar: while (true) {
+ if (!buffer(1)) throw new EOFException("Unexpected EOF reading entity");
+ int d = Character.digit(buf[off], radix);
+ if (d == -1) {
+ if (buf[off] != ';') throw new Exn("illegal characters in entity reference", Exn.WFC, getLine(), getCol());
+ off++; len--; col++;
+ break findchar;
+ }
+ c = (c * radix) + d;
+
+ off++; len--;
+ }
+
+ singlechar[0] = Character.forDigit(c, radix);
+ characters(singlechar, 0, 1);
+ break;
+
+ case 'a':
+ if (buffer(4) && buf[off+1] == 'm' && buf[off+2] == 'p' && buf[off+3] == ';') {
+ characters(single_amp, 0, 1); // &
+ off += 4; len -= 4; col++;
+ } else if (buffer(5) && buf[off+1] == 'p' && buf[off+2] == 'o' && buf[off+3] == 's' && buf[off+4] == ';') {
+ characters(single_apos, 0, 1); // '
+ off += 5; len -= 5; col++;
+ } else {
+ unknown = true;
+ }
+ break;
+
+ case 'g':
+ if (buffer(3) && buf[off+1] == 't' && buf[off+2] == ';') {
+ characters(single_gt, 0, 1); // >
+ off += 3; len -= 3; col++;
+ } else {
+ unknown = true;
+ }
+ break;
+
+ case 'l':
+ if (buffer(3) && buf[off+1] == 't' && buf[off+2] == ';') {
+ characters(single_lt, 0, 1); // <
+ off += 3; len -= 3; col++;
+ } else {
+ unknown = true;
+ }
+ break;
+
+ case 'q':
+ if (buffer(5) && buf[off+1] == 'u' && buf[off+2] == 'o' && buf[off+3] == 't' && buf[off+4] == ';') {
+ characters(single_quot, 0, 1); // "
+ off += 5; len -= 5; col++;
+ } else {
+ unknown = true;
+ }
+ break;
+
+ // TODO: check a parser-level Hash of defined entities
+ }
+
+ if (unknown) throw new Exn("unknown entity (<!ENTITY> not supported)", Exn.WFC, getLine(), getCol());
+ }
+
+ /** reads until the passed string is encountered. */
+ private final void readChars(boolean p, String match, boolean entities) throws IOException, Exn {
+ int ref;
+ char[] end = match.toCharArray();
+
+ for (boolean more = true; more;) {
+ if (!buffer(1)) return;
+
+ buf: for (ref = 0; ref < len; ref++) {
+ switch (buf[off+ref]) {
+ case '\r': // windows or macos9 newline
+ // normalise and process
+ buf[off+ref] = '\n'; ref++;
+ if (p) characters(buf, off, ref);
+ off += ref; len -= ref; ref = -1;
+ line++; col = 1;
+
+ // windows double-char newline; skip the next char
+ if (!buffer(1)) return;
+ if (buf[off] == '\n') { off++; len--; }
+ break;
+
+ case '\n': // unix newline
+ ref++;
+ if (p) characters(buf, off, ref);
+ off += ref; len -= ref; ref = -1;
+ line++; col = 1;
+ break;
+
+ case '&': // entity
+ if (entities) {
+ if (p) {
+ if (ref > 0) characters(buf, off, ref);
+ off += ref; len -= ref; ref = -1;
+ readEntity();
+ }
+ break;
+ }
+
+ default:
+ if (!buffer(ref+end.length)) continue buf;
+ for (int i=0; end.length > i; i++) if (end[i] != buf[off+ref+i]) continue buf;
+ more = false;
+ break buf;
+ }
+ }
+
+ if (p && ref > 0) characters(buf, off, ref);
+ off += ref; len -= ref; col += ref;
+ }
+ }
+
+ /**
+ * reads until a <tt><</tt> symbol is encountered
+ * @param p If true call the characters(char[],int,int) funciton for the processed characters
+ */
+ private final void readChars(boolean p) throws IOException, Exn {
+ int ref;
+
+ for (boolean more = true; more;) {
+ if (!buffer(1)) return;
+
+ buf: for (ref = 0; ref < len; ref++) {
+ switch (buf[off+ref]) {
+ case '\r': // windows or macos9 newline
+ // normalise and process
+ buf[off+ref] = '\n'; ref++;
+ if (p) characters(buf, off, ref);
+ off += ref; len -= ref; ref = -1;
+ line++; col = 1;
+
+ // windows double-char newline; skip the next char
+ if (!buffer(1)) return;
+ if (buf[off] == '\n') { off++; len--; }
+ break;
+
+ case '\n': // unix newline
+ ref++;
+ if (p) characters(buf, off, ref);
+ off += ref; len -= ref; ref = -1;
+ line++; col = 1;
+ break;
+
+ case '&': // entity
+ if (p) {
+ if (ref > 0) characters(buf, off, ref);
+ off += ref; len -= ref; ref = -1;
+ readEntity();
+ }
+ break;
+
+ case '<': // end of chars section
+ more = false;
+ break buf;
+ }
+ }
+
+ if (p && ref > 0) characters(buf, off, ref);
+ off += ref; len -= ref; col += ref;
+ }
+ }
+
+ /** reads until a non-whitespace symbol is encountered */
+ private final void readWhitespace() throws IOException, Exn {
+ int ref;
+
+ for (boolean more = true; more;) {
+ if (!buffer(1)) return;
+
+ buf: for (ref = 0; ref < len; ref++) {
+ switch (buf[off+ref]) {
+ case '\r': // windows or macos9 newline
+ // normalise and process
+ buf[off+ref] = '\n';
+ whitespace(buf, off, ++ref);
+ off += ref; len -= ref; ref = -1;
+ line++; col = 1;
+
+ // windows double-char newline; skip the next char
+ if (!buffer(1)) return;
+ if (buf[off] == '\n') { off++; len--; }
+ break;
+
+ case '\n': // unix newline
+ whitespace(buf, off, ++ref);
+ off += ref; len -= ref; ref = -1;
+ line++; col = 1;
+ break;
+
+ case ' ': // space
+ case '\t': // tab
+ break;
+
+ default: // end of whitespace
+ more = false;
+ break buf;
+ }
+ }
+
+ off += ref; len -= ref; col += ref;
+ }
+ }
+
+ /**
+ * attempt to fill the buffer.
+ *
+ * @param min Minimum number of characters to read (even if we have to block to do it).
+ * @return return false if min can't be reached.
+ */
+ private final boolean buffer(int min) throws IOException {
+ if (len > min) return true;
+
+ if (buf.length - (off+len) >= min) {
+ // plenty of space left on the end of the buffer
+ } else if (off >= min) {
+ // moving offset data to start will leave enough free space on the end
+ System.arraycopy(buf, off, buf, 0, len);
+ base += off;
+ off = 0;
+ } else {
+ // buffer size will have to be increased
+ char[] newbuf = new char[buf.length * 2];
+ System.arraycopy(buf, off, newbuf, 0, len);
+ buf = newbuf;
+ base += off;
+ off = 0;
+ }
+
+ while (min > len) {
+ int newlen = in.read(buf, off+len, buf.length-(off+len));
+ if (newlen < 0) return false;
+ len += newlen;
+ }
+
+ return true;
+ }
+
+
+ /////////////////////////////////////////////////////////////////////////////////////////////
+ // Abstract SAX-Like Interface
+ /////////////////////////////////////////////////////////////////////////////////////////////
+
+ /**
+ * Called when the start of an element is processed.
+ *
+ * <p><b>DO NOT</b> store a reference to the Element object, as
+ * they are reused by XML Parser.</p>
+ */
+ public abstract void startElement(Element e) throws Exn;
+
+ /**
+ * Represents up to a line of character data.
+ *
+ * <p>Newlines are all normalised to the Unix \n as per the XML Spec,
+ * and a newline will only appear as the last character in the passed
+ * array segment.</p>
+ *
+ * <p>XML.getLine() and XML.getCol() report the position at the
+ * beginning of this character segment, which can be processed in a
+ * line-by-line fashion due to the above newline restriction.</p>
+ */
+ public abstract void characters(char[] ch, int start, int length) throws Exn, IOException;
+
+ /** Represents up to a line of ignorable whitespace. */
+ public abstract void whitespace(char[] ch, int start, int length) throws Exn, IOException;
+
+ /** Represents the end of an Element. */
+ public abstract void endElement(Element e) throws Exn, IOException;
+
+
+ /////////////////////////////////////////////////////////////////////////////////////////////
+ // Inner Classes for Parser Support
+ /////////////////////////////////////////////////////////////////////////////////////////////
+
+ /**
+ * Represents an element in an XML document. Stores a reference to its
+ * parent, forming a one-way linked list.
+ *
+ * Element objects are reused, so client code making use of them must
+ * drop their references after the specific element process function
+ * has returned.
+ */
+ public static final class Element {
+
+ private static final int DEFAULT_ATTR_SIZE = 10;
+
+ protected Element parent = null;
+
+ protected String uri = null;
+ protected String localName = null;
+ protected String qName = null;
+ protected String prefix = null;
+
+ protected Hash urimap = new Hash(3,3);
+
+ protected String[] keys = new String[DEFAULT_ATTR_SIZE];
+ protected String[] vals = new String[DEFAULT_ATTR_SIZE];
+ protected String[] uris = new String[DEFAULT_ATTR_SIZE];
+ protected int len = 0;
+
+ protected Exn[] errors = new Exn[] {};
+
+ /** Parent of current element. */
+ public Element getParent() { return parent; }
+
+ /** Qualified Name of current element. XML Namespace Spec 14-Jan-1999 [6] */
+ public String getQName() { return qName; }
+
+ /** LocalPart of current element. XML Namespace Spec 14-Jan-1999 [8] */
+ public String getLocalName() { return localName; }
+
+ /** Prefix of current element. Substring of qName. XML Namespace Spec 14-Jan-1999 [7] */
+ public String getPrefix() { return prefix; }
+
+ // HACK
+ public Hash getUriMap() {
+ Hash map = new Hash();
+ for (Element e = this; e != null; e = e.getParent()) {
+ java.util.Enumeration en = e.urimap.keys();
+ while(en.hasMoreElements()) {
+ String key = (String)en.nextElement();
+ String val = getUri(key);
+ map.put(key, val);
+ }
+ }
+ return map;
+ }
+
+ /** URI of current tag. XML Namespace Spec 14-Jan-1999 section 1 */
+ public String getUri() { return getUri(prefix); }
+
+ /** URI of a given prefix. Never returns null, instead gives "". */
+ public String getUri(String p) {
+ String ret = null;
+ for (Element e = this; e != null && ret == null; e = e.getParent()) {
+ ret = (String)e.urimap.get(p == null ? "" : p);
+ }
+ return ret == null ? "" : ret;
+ }
+
+ /** An array of attribute names. */
+ public String getAttrKey(int pos) { return len > pos ? keys[pos] : null; }
+
+ /** An array of attribute values. */
+ public String getAttrVal(int pos) { return len > pos ? vals[pos] : null; }
+
+ /** An array of attribute uris. */
+ public String getAttrUri(int pos) { return len > pos ? uris[pos] : null; }
+
+ /** Current number of attributes in the element. */
+ public int getAttrLen() { return len; }
+
+ /** Poor performance, but easier to use when speed is not a concern */
+ public Hash getAttrHash() {
+ Hash ret = new Hash(getAttrLen() * 2, 3);
+ for(int i=0; i<len; i++)
+ ret.put(getAttrKey(i), getAttrVal(i));
+ return ret;
+ }
+
+ /** Poor performance, but easier to use */
+ public String getAttrVal(String key) {
+ for(int i=0; i<len; i++) if (keys[i].equals(key)) return vals[i];
+ return null;
+ }
+
+ /** An array of non-fatal errors related to this element. */
+ public Exn[] getErrors() { return errors; }
+
+ protected Element() { }
+
+ /** Add (replace if exists in current element) a Namespace prefix/uri map. */
+ public void addUri(String name, String value) {
+ urimap.put(name, value);
+ }
+
+ /** Add an attribute. */
+ protected void addAttr(String key, String val, String uri) {
+ if (len == keys.length) {
+ // increase the size of the attributes arrays
+ String[] newkeys = new String[keys.length*2];
+ String[] newvals = new String[vals.length*2];
+ String[] newuris = new String[uris.length*2];
+ System.arraycopy(keys, 0, newkeys, 0, keys.length);
+ System.arraycopy(vals, 0, newvals, 0, vals.length);
+ System.arraycopy(uris, 0, newuris, 0, uris.length);
+ keys = newkeys; vals = newvals; uris = newuris;
+ }
+
+ keys[len] = key;
+ vals[len] = val;
+ uris[len] = uri;
+ len++;
+ }
+
+ /** Add an error. */
+ protected void addError(Exn e) {
+ // it doesn't really matter about continually expanding the array, as this case is quite rare
+ Exn[] newe = new Exn[errors.length+1];
+ System.arraycopy(errors, 0, newe, 0, errors.length);
+ newe[errors.length] = e;
+ errors = newe;
+ }
+
+ /** Empty out all the data from the Element. */
+ protected void clear() {
+ parent = null;
+ uri = localName = qName = prefix = null;
+ urimap.clear();
+
+ if (keys.length != vals.length || vals.length != uris.length) {
+ keys = new String[DEFAULT_ATTR_SIZE];
+ vals = new String[DEFAULT_ATTR_SIZE];
+ uris = new String[DEFAULT_ATTR_SIZE];
+ } else {
+ for (int i=0; keys.length > i; i++) { keys[i] = null; vals[i] = null; uris[i] = null; };
+ }
+ len = 0;
+
+ errors = new Exn[] {};
+ }
+ }
+
+ /** Parse or Structural Error */
+ public static class Exn extends Exception {
+ /** Violation of Markup restrictions in XML Specification - Fatal Error */
+ public static final int MARKUP = 1;
+
+ /** Well-Formedness Constraint Violation - Fatal Error */
+ public static final int WFC = 2;
+
+ /** Namespace Constraint Violation - Recoverable Error */
+ public static final int NC = 3;
+
+ /** Schema Violation - Fatal Error */
+ public static final int SCHEMA = 4;
+
+ private String error;
+ private int type;
+ private int line;
+ private int col;
+
+ public Exn(String e) { this(e, MARKUP, -1, -1); }
+
+ public Exn(String e, int type, int line, int col) {
+ this.error = e;
+ this.type = type;
+ this.line = line;
+ this.col = col;
+ }
+
+ public int getType() { return this.type; }
+ public int getLine() { return this.line; }
+ public int getCol() { return this.col; }
+ public String getMessage() { return this.error + (line >= 0 && col >= 0 ? " at " + line + ":" + col: ""); }
+ }
+
+
+ /////////////////////////////////////////////////////////////////////////////////////////////
+ // Static Support Functions for the XML Specification
+ /////////////////////////////////////////////////////////////////////////////////////////////
+
+ // attempt to avoid these functions unless you *expect* the input to fall in the given range.
+
+ /** First Character of Name - XML Specification 1.0 [5] */
+ private static final boolean Name(char c) {
+ return BaseCharAscii(c) || c == '_' || c == ':' || Letter(c);
+ }
+
+ /** NameChar - XML Specification 1.0 [4] */
+ private static final boolean NameChar(char c) {
+ return BaseCharAscii(c) || c == '.' || c == '-' || c == '_' || c == ':'
+ || Digit(c) || Letter(c) || Extender(c); // TODO: || CombiningChar(c);
+ }
+
+ /** BaseChar - XMl Specification 1.0 [84] */
+ private static final boolean Letter(char c) {
+ return BaseChar(c) || Ideographic(c);
+ }
+
+ /** Elements of BaseChar that exist in ASCII. */
+ private static final boolean BaseCharAscii(char c) {
+ return (c >= '\u0041' && c <= '\u005A') || (c >= '\u0061' && c <= '\u007A');
+ }
+
+ /** Char - XML Specification 1.0 [2] */
+ private static final boolean Char(char c) {
+ // u000A == r and u000D == n, but the javac compiler can't handle the \ u form
+ return c == '\u0009' || c == '\r' || c == '\n'
+ || (c >= '\u0020' && c <= '\uD7FF')
+ || (c >= '\uE000' && c <= '\uFFFD');
+ }
+
+ /** BaseChar - XML Specification 1.0 [85] */
+ private static final boolean BaseChar(char c) {
+ return BaseCharAscii(c) || (c >= '\u00C0' && c <= '\u00D6')
+ || (c >= '\u00D8' && c <= '\u00F6') || (c >= '\u00F8' && c <= '\u00FF') || (c >= '\u0100' && c <= '\u0131')
+ || (c >= '\u0134' && c <= '\u013E') || (c >= '\u0141' && c <= '\u0148') || (c >= '\u014A' && c <= '\u017E')
+ || (c >= '\u0180' && c <= '\u01C3') || (c >= '\u01CD' && c <= '\u01F0') || (c >= '\u01F4' && c <= '\u01F5')
+ || (c >= '\u01FA' && c <= '\u0217') || (c >= '\u0250' && c <= '\u02A8') || (c >= '\u02BB' && c <= '\u02C1')
+ || (c == '\u0386') || (c >= '\u0388' && c <= '\u038A') || (c == '\u038C')
+ || (c >= '\u038E' && c <= '\u03A1') || (c >= '\u03A3' && c <= '\u03CE') || (c >= '\u03D0' && c <= '\u03D6')
+ || (c == '\u03DA') || (c == '\u03DC') || (c == '\u03DE')
+ || (c == '\u03E0')
+ || (c >= '\u03E2' && c <= '\u03F3') || (c >= '\u0401' && c <= '\u040C') || (c >= '\u040E' && c <= '\u044F')
+ || (c >= '\u0451' && c <= '\u045C') || (c >= '\u045E' && c <= '\u0481') || (c >= '\u0490' && c <= '\u04C4')
+ || (c >= '\u04C7' && c <= '\u04C8') || (c >= '\u04CB' && c <= '\u04CC') || (c >= '\u04D0' && c <= '\u04EB')
+ || (c >= '\u04EE' && c <= '\u04F5') || (c >= '\u04F8' && c <= '\u04F9') || (c >= '\u0531' && c <= '\u0556')
+ || (c == '\u0559')
+ || (c >= '\u0561' && c <= '\u0586') || (c >= '\u05D0' && c <= '\u05EA') || (c >= '\u05F0' && c <= '\u05F2')
+ || (c >= '\u0621' && c <= '\u063A') || (c >= '\u0641' && c <= '\u064A') || (c >= '\u0671' && c <= '\u06B7')
+ || (c >= '\u06BA' && c <= '\u06BE') || (c >= '\u06C0' && c <= '\u06CE') || (c >= '\u06D0' && c <= '\u06D3')
+ || (c == '\u06D5')
+ || (c >= '\u06E5' && c <= '\u06E6') || (c >= '\u0905' && c <= '\u0939')
+ || (c == '\u093D')
+ || (c >= '\u0958' && c <= '\u0961') || (c >= '\u0985' && c <= '\u098C') || (c >= '\u098F' && c <= '\u0990')
+ || (c >= '\u0993' && c <= '\u09A8') || (c >= '\u09AA' && c <= '\u09B0')
+ || (c == '\u09B2')
+ || (c >= '\u09B6' && c <= '\u09B9') || (c >= '\u09DF' && c <= '\u09E1') || (c >= '\u09F0' && c <= '\u09F1')
+ || (c >= '\u0A05' && c <= '\u0A0A') || (c >= '\u0A0F' && c <= '\u0A10') || (c >= '\u0A13' && c <= '\u0A28')
+ || (c >= '\u0A2A' && c <= '\u0A30') || (c >= '\u0A32' && c <= '\u0A33') || (c >= '\u0A35' && c <= '\u0A36')
+ || (c >= '\u0A38' && c <= '\u0A39') || (c >= '\u0A59' && c <= '\u0A5C')
+ || (c == '\u0A5E')
+ || (c >= '\u0A72' && c <= '\u0A74') || (c >= '\u0A85' && c <= '\u0A8B')
+ || (c == '\u0A8D')
+ || (c >= '\u0A8F' && c <= '\u0A91') || (c >= '\u0A93' && c <= '\u0AA8') || (c >= '\u0AAA' && c <= '\u0AB0')
+ || (c >= '\u0AB2' && c <= '\u0AB3') || (c >= '\u0AB5' && c <= '\u0AB9')
+ || (c == '\u0ABD')
+ || (c == '\u0AE0')
+ || (c >= '\u0B05' && c <= '\u0B0C') || (c >= '\u0B0F' && c <= '\u0B10') || (c >= '\u0B13' && c <= '\u0B28')
+ || (c >= '\u0B2A' && c <= '\u0B30') || (c >= '\u0B32' && c <= '\u0B33') || (c >= '\u0B36' && c <= '\u0B39')
+ || (c == '\u0B3D')
+ || (c >= '\u0B5C' && c <= '\u0B5D') || (c >= '\u0B5F' && c <= '\u0B61') || (c >= '\u0B85' && c <= '\u0B8A')
+ || (c >= '\u0B8E' && c <= '\u0B90') || (c >= '\u0B92' && c <= '\u0B95') || (c >= '\u0B99' && c <= '\u0B9A')
+ || (c == '\u0B9C')
+ || (c >= '\u0B9E' && c <= '\u0B9F') || (c >= '\u0BA3' && c <= '\u0BA4') || (c >= '\u0BA8' && c <= '\u0BAA')
+ || (c >= '\u0BAE' && c <= '\u0BB5') || (c >= '\u0BB7' && c <= '\u0BB9') || (c >= '\u0C05' && c <= '\u0C0C')
+ || (c >= '\u0C0E' && c <= '\u0C10') || (c >= '\u0C12' && c <= '\u0C28') || (c >= '\u0C2A' && c <= '\u0C33')
+ || (c >= '\u0C35' && c <= '\u0C39') || (c >= '\u0C60' && c <= '\u0C61') || (c >= '\u0C85' && c <= '\u0C8C')
+ || (c >= '\u0C8E' && c <= '\u0C90') || (c >= '\u0C92' && c <= '\u0CA8') || (c >= '\u0CAA' && c <= '\u0CB3')
+ || (c >= '\u0CB5' && c <= '\u0CB9')
+ || (c == '\u0CDE')
+ || (c >= '\u0CE0' && c <= '\u0CE1') || (c >= '\u0D05' && c <= '\u0D0C') || (c >= '\u0D0E' && c <= '\u0D10')
+ || (c >= '\u0D12' && c <= '\u0D28') || (c >= '\u0D2A' && c <= '\u0D39') || (c >= '\u0D60' && c <= '\u0D61')
+ || (c >= '\u0E01' && c <= '\u0E2E')
+ || (c == '\u0E30')
+ || (c >= '\u0E32' && c <= '\u0E33') || (c >= '\u0E40' && c <= '\u0E45') || (c >= '\u0E81' && c <= '\u0E82')
+ || (c == '\u0E84')
+ || (c >= '\u0E87' && c <= '\u0E88')
+ || (c == '\u0E8A')
+ || (c == '\u0E8D')
+ || (c >= '\u0E94' && c <= '\u0E97') || (c >= '\u0E99' && c <= '\u0E9F') || (c >= '\u0EA1' && c <= '\u0EA3')
+ || (c == '\u0EA5')
+ || (c == '\u0EA7')
+ || (c >= '\u0EAA' && c <= '\u0EAB') || (c >= '\u0EAD' && c <= '\u0EAE')
+ || (c == '\u0EB0')
+ || (c >= '\u0EB2' && c <= '\u0EB3')
+ || (c == '\u0EBD')
+ || (c >= '\u0EC0' && c <= '\u0EC4') || (c >= '\u0F40' && c <= '\u0F47') || (c >= '\u0F49' && c <= '\u0F69')
+ || (c >= '\u10A0' && c <= '\u10C5') || (c >= '\u10D0' && c <= '\u10F6')
+ || (c == '\u1100')
+ || (c >= '\u1102' && c <= '\u1103') || (c >= '\u1105' && c <= '\u1107')
+ || (c == '\u1109')
+ || (c >= '\u110B' && c <= '\u110C') || (c >= '\u110E' && c <= '\u1112')
+ || (c == '\u113C')
+ || (c == '\u113E')
+ || (c == '\u1140')
+ || (c == '\u114C')
+ || (c == '\u114E')
+ || (c == '\u1150')
+ || (c >= '\u1154' && c <= '\u1155')
+ || (c == '\u1159')
+ || (c >= '\u115F' && c <= '\u1161')
+ || (c == '\u1163')
+ || (c == '\u1165')
+ || (c == '\u1167')
+ || (c == '\u1169')
+ || (c >= '\u116D' && c <= '\u116E') || (c >= '\u1172' && c <= '\u1173')
+ || (c == '\u1175')
+ || (c == '\u119E')
+ || (c == '\u11A8')
+ || (c == '\u11AB')
+ || (c >= '\u11AE' && c <= '\u11AF') || (c >= '\u11B7' && c <= '\u11B8')
+ || (c == '\u11BA')
+ || (c >= '\u11BC' && c <= '\u11C2')
+ || (c == '\u11EB')
+ || (c == '\u11F0')
+ || (c == '\u11F9')
+ || (c >= '\u1E00' && c <= '\u1E9B') || (c >= '\u1EA0' && c <= '\u1EF9') || (c >= '\u1F00' && c <= '\u1F15')
+ || (c >= '\u1F18' && c <= '\u1F1D') || (c >= '\u1F20' && c <= '\u1F45') || (c >= '\u1F48' && c <= '\u1F4D')
+ || (c >= '\u1F50' && c <= '\u1F57')
+ || (c == '\u1F59')
+ || (c == '\u1F5B')
+ || (c == '\u1F5D')
+ || (c >= '\u1F5F' && c <= '\u1F7D') || (c >= '\u1F80' && c <= '\u1FB4') || (c >= '\u1FB6' && c <= '\u1FBC')
+ || (c == '\u1FBE')
+ || (c >= '\u1FC2' && c <= '\u1FC4') || (c >= '\u1FC6' && c <= '\u1FCC') || (c >= '\u1FD0' && c <= '\u1FD3')
+ || (c >= '\u1FD6' && c <= '\u1FDB') || (c >= '\u1FE0' && c <= '\u1FEC') || (c >= '\u1FF2' && c <= '\u1FF4')
+ || (c >= '\u1FF6' && c <= '\u1FFC')
+ || (c == '\u2126')
+ || (c >= '\u212A' && c <= '\u212B')
+ || (c == '\u212E')
+ || (c >= '\u2180' && c <= '\u2182') || (c >= '\u3041' && c <= '\u3094') || (c >= '\u30A1' && c <= '\u30FA')
+ || (c >= '\u3105' && c <= '\u312C') || (c >= '\uAC00' && c <= '\uD7A3');
+ }
+
+ /** BaseChar - XMl Specification 1.0 [86] */
+ private static final boolean Ideographic(char c) {
+ return (c >= '\u4E00' && c <= '\u9FA5') || c == '\u3007' || (c >= '\u3021' && c <= '\u3029');
+ }
+
+ /** CombiningChar - XMl Specification 1.0 [87] */
+ /*private static final boolean CombiningChar(char c) {
+ return (c >= '\u0300' && c <= '\u0345')
+ || (c >= '\u0360' && c <= '\u0361') || (c >= '\u0483' && c <= '\u0486') || (c >= '\u0591' && c <= '\u05A1')
+ || (c >= '\u05A3' && c <= '\u05B9') || (c >= '\u05BB' && c <= '\u05BD')
+ || (c == '\u05BF')
+ || (c >= '\u05C1' && c <= '\u05C2')
+ || (c == '\u05C4')
+ || (c >= '\u064B' && c <= '\u0652')
+ || (c == '\u0670')
+ || (c >= '\u06D6' && c <= '\u06DC') || (c >= '\u06DD' && c <= '\u06DF') || (c >= '\u06E0' && c <= '\u06E4')
+ || (c >= '\u06E7' && c <= '\u06E8') || (c >= '\u06EA' && c <= '\u06ED') || (c >= '\u0901' && c <= '\u0903')
+ || (c == '\u093C')
+ || (c >= '\u093E' && c <= '\u094C')
+ || (c == '\u094D')
+ || (c >= '\u0951' && c <= '\u0954') || (c >= '\u0962' && c <= '\u0963') || (c >= '\u0981' && c <= '\u0983')
+ || (c == '\u09BC')
+ || (c == '\u09BE')
+ || (c == '\u09BF')
+ || (c >= '\u09C0' && c <= '\u09C4') || (c >= '\u09C7' && c <= '\u09C8') || (c >= '\u09CB' && c <= '\u09CD')
+ || (c == '\u09D7')
+ || (c >= '\u09E2' && c <= '\u09E3')
+ || (c == '\u0A02')
+ || (c == '\u0A3C')
+ || (c == '\u0A3E')
+ || (c == '\u0A3F')
+ || (c >= '\u0A40' && c <= '\u0A42') || (c >= '\u0A47' && c <= '\u0A48') || (c >= '\u0A4B' && c <= '\u0A4D')
+ || (c >= '\u0A70' && c <= '\u0A71') || (c >= '\u0A81' && c <= '\u0A83')
+ || (c == '\u0ABC')
+ || (c >= '\u0ABE' && c <= '\u0AC5') || (c >= '\u0AC7' && c <= '\u0AC9') || (c >= '\u0ACB' && c <= '\u0ACD')
+ || (c >= '\u0B01' && c <= '\u0B03')
+ || (c == '\u0B3C')
+ || (c >= '\u0B3E' && c <= '\u0B43') || (c >= '\u0B47' && c <= '\u0B48') || (c >= '\u0B4B' && c <= '\u0B4D')
+ || (c >= '\u0B56' && c <= '\u0B57') || (c >= '\u0B82' && c <= '\u0B83') || (c >= '\u0BBE' && c <= '\u0BC2')
+ || (c >= '\u0BC6' && c <= '\u0BC8') || (c >= '\u0BCA' && c <= '\u0BCD')
+ || (c == '\u0BD7')
+ || (c >= '\u0C01' && c <= '\u0C03') || (c >= '\u0C3E' && c <= '\u0C44') || (c >= '\u0C46' && c <= '\u0C48')
+ || (c >= '\u0C4A' && c <= '\u0C4D') || (c >= '\u0C55' && c <= '\u0C56') || (c >= '\u0C82' && c <= '\u0C83')
+ || (c >= '\u0CBE' && c <= '\u0CC4') || (c >= '\u0CC6' && c <= '\u0CC8') || (c >= '\u0CCA' && c <= '\u0CCD')
+ || (c >= '\u0CD5' && c <= '\u0CD6') || (c >= '\u0D02' && c <= '\u0D03') || (c >= '\u0D3E' && c <= '\u0D43')
+ || (c >= '\u0D46' && c <= '\u0D48') || (c >= '\u0D4A' && c <= '\u0D4D')
+ || (c == '\u0D57')
+ || (c == '\u0E31')
+ || (c >= '\u0E34' && c <= '\u0E3A') || (c >= '\u0E47' && c <= '\u0E4E')
+ || (c == '\u0EB1')
+ || (c >= '\u0EB4' && c <= '\u0EB9') || (c >= '\u0EBB' && c <= '\u0EBC') || (c >= '\u0EC8' && c <= '\u0ECD')
+ || (c >= '\u0F18' && c <= '\u0F19')
+ || (c == '\u0F35')
+ || (c == '\u0F37')
+ || (c == '\u0F39')
+ || (c == '\u0F3E')
+ || (c == '\u0F3F')
+ || (c >= '\u0F71' && c <= '\u0F84') || (c >= '\u0F86' && c <= '\u0F8B') || (c >= '\u0F90' && c <= '\u0F95')
+ || (c == '\u0F97')
+ || (c >= '\u0F99' && c <= '\u0FAD') || (c >= '\u0FB1' && c <= '\u0FB7')
+ || (c == '\u0FB9')
+ || (c >= '\u20D0' && c <= '\u20DC')
+ || (c == '\u20E1')
+ || (c >= '\u302A' && c <= '\u302F')
+ || (c == '\u3099')
+ || (c == '\u309A');
+ }*/
+
+ /** Digit - XMl Specification 1.0 [88] */
+ private static final boolean Digit(char c) {
+ return (c >= '\u0030' && c <= '\u0039') || (c >= '\u0660' && c <= '\u0669') || (c >= '\u06F0' && c <= '\u06F9')
+ || (c >= '\u0966' && c <= '\u096F') || (c >= '\u09E6' && c <= '\u09EF') || (c >= '\u0A66' && c <= '\u0A6F')
+ || (c >= '\u0AE6' && c <= '\u0AEF') || (c >= '\u0B66' && c <= '\u0B6F') || (c >= '\u0BE7' && c <= '\u0BEF')
+ || (c >= '\u0C66' && c <= '\u0C6F') || (c >= '\u0CE6' && c <= '\u0CEF') || (c >= '\u0D66' && c <= '\u0D6F')
+ || (c >= '\u0E50' && c <= '\u0E59') || (c >= '\u0ED0' && c <= '\u0ED9') || (c >= '\u0F20' && c <= '\u0F29');
+ }
+
+ /** Extender - XMl Specification 1.0 [89] */
+ private static final boolean Extender(char c) {
+ return c == '\u00B7' || c == '\u02D0' || c == '\u02D1' || c == '\u0387'
+ || c == '\u0640' || c == '\u0E46' || c == '\u0EC6' || c == '\u3005'
+ || (c >= '\u3031' && c <= '\u3035') || (c >= '\u309D' && c <= '\u309E') || (c >= '\u30FC' && c <= '\u30FE');
+ }
+
+ /** Whitespace - XML Specification 1.0 [3] */
+ private static final boolean S(char c) {
+ return c == '\u0020' || c == '\u0009' || c == '\r' || c == '\n';
+ }
+}
--- /dev/null
+#!/bin/sh
+mkdir mach
+mkdir mach/machine
+mkdir mach/ppc
+mkdir mach/i386
+mkdir architecture
+mkdir architecture/i386
+mkdir architecture/ppc
+mkdir sys
+mkdir mach_debug
+mkdir machine
+mkdir ppc
+mkdir servers
+
+# cripple this
+#ln -s ../../../../install/powerpc-apple-darwin/include/ppc/endian.h ppc/endian.h
+touch ppc/endian.h
+
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/host_security.h mach/host_security.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/ledger.h mach/ledger.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/clock_priv.h mach/clock_priv.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/mach_host.h mach/mach_host.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/bootstrap.h mach/bootstrap.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/clock.h mach/clock.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/processor_set.h mach/processor_set.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/task.h mach/task.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/host_priv.h mach/host_priv.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/processor.h mach/processor.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/sync.h mach/sync.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/lock_set.h mach/lock_set.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/mach_interface.h mach/mach_interface.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/thread_act.h mach/thread_act.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/vm_map.h mach/vm_map.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/mach_port.h mach/mach_port.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/mach.h mach/mach.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/vm_task.h mach/vm_task.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/mach_error.h mach/mach_error.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/mach_init.h mach/mach_init.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/mig_errors.h mach/mig_errors.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/port_obj.h mach/port_obj.h
+ln -s ../../../../../install/powerpc-apple-darwin/include/mach/machine/asm.h mach/machine/asm.h
+ln -s ../../../../../install/powerpc-apple-darwin/include/mach/machine/boolean.h mach/machine/boolean.h
+ln -s ../../../../../install/powerpc-apple-darwin/include/mach/machine/exception.h mach/machine/exception.h
+ln -s ../../../../../install/powerpc-apple-darwin/include/mach/machine/processor_info.h mach/machine/processor_info.h
+ln -s ../../../../../install/powerpc-apple-darwin/include/mach/machine/vm_param.h mach/machine/vm_param.h
+ln -s ../../../../../install/powerpc-apple-darwin/include/mach/machine/kern_return.h mach/machine/kern_return.h
+ln -s ../../../../../install/powerpc-apple-darwin/include/mach/machine/ndr_def.h mach/machine/ndr_def.h
+ln -s ../../../../../install/powerpc-apple-darwin/include/mach/machine/rpc.h mach/machine/rpc.h
+ln -s ../../../../../install/powerpc-apple-darwin/include/mach/machine/machine_types.defs mach/machine/machine_types.defs
+ln -s ../../../../../install/powerpc-apple-darwin/include/mach/machine/thread_state.h mach/machine/thread_state.h
+ln -s ../../../../../install/powerpc-apple-darwin/include/mach/machine/thread_status.h mach/machine/thread_status.h
+ln -s ../../../../../install/powerpc-apple-darwin/include/mach/machine/vm_types.h mach/machine/vm_types.h
+ln -s ../../../../../install/powerpc-apple-darwin/include/mach/machine/syscall_sw.h mach/machine/syscall_sw.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/exception_types.h mach/exception_types.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/kmod.h mach/kmod.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/clock_types.h mach/clock_types.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/error.h mach/error.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/boolean.h mach/boolean.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/boot_info.h mach/boot_info.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/memory_object_types.h mach/memory_object_types.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/mig.h mach/mig.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/exception.h mach/exception.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/host_reboot.h mach/host_reboot.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/mach_time.h mach/mach_time.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/host_info.h mach/host_info.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/mach_syscalls.h mach/mach_syscalls.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/kern_return.h mach/kern_return.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/clock_reply.h mach/clock_reply.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/mach_param.h mach/mach_param.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/mach_traps.h mach/mach_traps.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/mach_types.h mach/mach_types.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/machine.h mach/machine.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/processor_info.h mach/processor_info.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/port.h mach/port.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/message.h mach/message.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/notify.h mach/notify.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/policy.h mach/policy.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/rpc.h mach/rpc.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/ndr.h mach/ndr.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/vm_attributes.h mach/vm_attributes.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/semaphore.h mach/semaphore.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/std_types.h mach/std_types.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/shared_memory_server.h mach/shared_memory_server.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/task_info.h mach/task_info.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/thread_status.h mach/thread_status.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/task_special_ports.h mach/task_special_ports.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/sync_policy.h mach/sync_policy.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/syscall_sw.h mach/syscall_sw.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/task_ledger.h mach/task_ledger.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/task_policy.h mach/task_policy.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/thread_policy.h mach/thread_policy.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/mach_types.defs mach/mach_types.defs
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/thread_info.h mach/thread_info.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/thread_special_ports.h mach/thread_special_ports.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/thread_switch.h mach/thread_switch.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/time_value.h mach/time_value.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/clock_types.defs mach/clock_types.defs
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/clock.defs mach/clock.defs
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/vm_behavior.h mach/vm_behavior.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/vm_inherit.h mach/vm_inherit.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/vm_param.h mach/vm_param.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/vm_prot.h mach/vm_prot.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/vm_region.h mach/vm_region.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/vm_statistics.h mach/vm_statistics.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/vm_sync.h mach/vm_sync.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/vm_types.h mach/vm_types.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/clock_priv.defs mach/clock_priv.defs
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/exc.defs mach/exc.defs
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/std_types.defs mach/std_types.defs
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/mach_port.defs mach/mach_port.defs
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/clock_reply.defs mach/clock_reply.defs
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/host_priv.defs mach/host_priv.defs
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/host_security.defs mach/host_security.defs
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/ledger.defs mach/ledger.defs
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/lock_set.defs mach/lock_set.defs
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/mach_host.defs mach/mach_host.defs
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/task.defs mach/task.defs
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/notify.defs mach/notify.defs
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/mach-gcc3.p mach/mach-gcc3.p
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/processor.defs mach/processor.defs
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/processor_set.defs mach/processor_set.defs
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/thread_act.defs mach/thread_act.defs
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/vm_map.defs mach/vm_map.defs
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/upl.defs mach/upl.defs
+ln -s ../../../../install/powerpc-apple-darwin/include/mach/mach.p mach/mach.p
+ln -s ../../../../../install/powerpc-apple-darwin/include/mach/ppc/exception.h mach/ppc/exception.h
+ln -s ../../../../../install/powerpc-apple-darwin/include/mach/ppc/asm.h mach/ppc/asm.h
+ln -s ../../../../../install/powerpc-apple-darwin/include/mach/ppc/boolean.h mach/ppc/boolean.h
+ln -s ../../../../../install/powerpc-apple-darwin/include/mach/ppc/processor_info.h mach/ppc/processor_info.h
+ln -s ../../../../../install/powerpc-apple-darwin/include/mach/ppc/rpc.h mach/ppc/rpc.h
+ln -s ../../../../../install/powerpc-apple-darwin/include/mach/ppc/kern_return.h mach/ppc/kern_return.h
+ln -s ../../../../../install/powerpc-apple-darwin/include/mach/ppc/ndr_def.h mach/ppc/ndr_def.h
+ln -s ../../../../../install/powerpc-apple-darwin/include/mach/ppc/machine_types.defs mach/ppc/machine_types.defs
+ln -s ../../../../../install/powerpc-apple-darwin/include/mach/ppc/thread_state.h mach/ppc/thread_state.h
+ln -s ../../../../../install/powerpc-apple-darwin/include/mach/ppc/thread_status.h mach/ppc/thread_status.h
+ln -s ../../../../../install/powerpc-apple-darwin/include/mach/ppc/vm_param.h mach/ppc/vm_param.h
+ln -s ../../../../../install/powerpc-apple-darwin/include/mach/ppc/vm_types.h mach/ppc/vm_types.h
+ln -s ../../../../../install/powerpc-apple-darwin/include/mach/ppc/syscall_sw.h mach/ppc/syscall_sw.h
+ln -s ../../../../../install/powerpc-apple-darwin/include/mach/i386/mach_i386_server.h mach/i386/mach_i386_server.h
+ln -s ../../../../../install/powerpc-apple-darwin/include/mach/i386/asm.h mach/i386/asm.h
+ln -s ../../../../../install/powerpc-apple-darwin/include/mach/i386/exception.h mach/i386/exception.h
+ln -s ../../../../../install/powerpc-apple-darwin/include/mach/i386/fp_reg.h mach/i386/fp_reg.h
+ln -s ../../../../../install/powerpc-apple-darwin/include/mach/i386/boolean.h mach/i386/boolean.h
+ln -s ../../../../../install/powerpc-apple-darwin/include/mach/i386/processor_info.h mach/i386/processor_info.h
+ln -s ../../../../../install/powerpc-apple-darwin/include/mach/i386/ndr_def.h mach/i386/ndr_def.h
+ln -s ../../../../../install/powerpc-apple-darwin/include/mach/i386/rpc.h mach/i386/rpc.h
+ln -s ../../../../../install/powerpc-apple-darwin/include/mach/i386/mach_i386_types.h mach/i386/mach_i386_types.h
+ln -s ../../../../../install/powerpc-apple-darwin/include/mach/i386/vm_param.h mach/i386/vm_param.h
+ln -s ../../../../../install/powerpc-apple-darwin/include/mach/i386/kern_return.h mach/i386/kern_return.h
+ln -s ../../../../../install/powerpc-apple-darwin/include/mach/i386/thread_status.h mach/i386/thread_status.h
+ln -s ../../../../../install/powerpc-apple-darwin/include/mach/i386/thread_state.h mach/i386/thread_state.h
+ln -s ../../../../../install/powerpc-apple-darwin/include/mach/i386/syscall_sw.h mach/i386/syscall_sw.h
+ln -s ../../../../../install/powerpc-apple-darwin/include/mach/i386/machine_types.defs mach/i386/machine_types.defs
+ln -s ../../../../../install/powerpc-apple-darwin/include/mach/i386/vm_types.h mach/i386/vm_types.h
+ln -s ../../../../../install/powerpc-apple-darwin/include/mach/i386/mach_i386.defs mach/i386/mach_i386.defs
+ln -s ../../../../../install/powerpc-apple-darwin/include/architecture/i386/byte_order.h architecture/i386/byte_order.h
+ln -s ../../../../../install/powerpc-apple-darwin/include/architecture/i386/cpu.h architecture/i386/cpu.h
+ln -s ../../../../../install/powerpc-apple-darwin/include/architecture/i386/alignment.h architecture/i386/alignment.h
+ln -s ../../../../../install/powerpc-apple-darwin/include/architecture/i386/asm_help.h architecture/i386/asm_help.h
+ln -s ../../../../../install/powerpc-apple-darwin/include/architecture/i386/reg_help.h architecture/i386/reg_help.h
+ln -s ../../../../../install/powerpc-apple-darwin/include/architecture/i386/sel.h architecture/i386/sel.h
+ln -s ../../../../../install/powerpc-apple-darwin/include/architecture/i386/desc.h architecture/i386/desc.h
+ln -s ../../../../../install/powerpc-apple-darwin/include/architecture/i386/fpu.h architecture/i386/fpu.h
+ln -s ../../../../../install/powerpc-apple-darwin/include/architecture/i386/frame.h architecture/i386/frame.h
+ln -s ../../../../../install/powerpc-apple-darwin/include/architecture/i386/io.h architecture/i386/io.h
+ln -s ../../../../../install/powerpc-apple-darwin/include/architecture/i386/table.h architecture/i386/table.h
+ln -s ../../../../../install/powerpc-apple-darwin/include/architecture/i386/tss.h architecture/i386/tss.h
+ln -s ../../../../../install/powerpc-apple-darwin/include/architecture/i386/fenv.h architecture/i386/fenv.h
+ln -s ../../../../../install/powerpc-apple-darwin/include/architecture/i386/math.h architecture/i386/math.h
+ln -s ../../../../../install/powerpc-apple-darwin/include/architecture/ppc/basic_regs.h architecture/ppc/basic_regs.h
+ln -s ../../../../../install/powerpc-apple-darwin/include/architecture/ppc/cframe.h architecture/ppc/cframe.h
+ln -s ../../../../../install/powerpc-apple-darwin/include/architecture/ppc/alignment.h architecture/ppc/alignment.h
+ln -s ../../../../../install/powerpc-apple-darwin/include/architecture/ppc/asm_help.h architecture/ppc/asm_help.h
+ln -s ../../../../../install/powerpc-apple-darwin/include/architecture/ppc/byte_order.h architecture/ppc/byte_order.h
+ln -s ../../../../../install/powerpc-apple-darwin/include/architecture/ppc/fp_regs.h architecture/ppc/fp_regs.h
+ln -s ../../../../../install/powerpc-apple-darwin/include/architecture/ppc/macro_help.h architecture/ppc/macro_help.h
+ln -s ../../../../../install/powerpc-apple-darwin/include/architecture/ppc/pseudo_inst.h architecture/ppc/pseudo_inst.h
+ln -s ../../../../../install/powerpc-apple-darwin/include/architecture/ppc/reg_help.h architecture/ppc/reg_help.h
+ln -s ../../../../../install/powerpc-apple-darwin/include/architecture/ppc/workaround.s architecture/ppc/workaround.s
+ln -s ../../../../../install/powerpc-apple-darwin/include/architecture/ppc/fenv.h architecture/ppc/fenv.h
+ln -s ../../../../../install/powerpc-apple-darwin/include/architecture/ppc/math.h architecture/ppc/math.h
+ln -s ../../../../install/powerpc-apple-darwin/include/architecture/zs85C30.h architecture/zs85C30.h
+ln -s ../../../../install/powerpc-apple-darwin/include/architecture/adb_kb_codes.h architecture/adb_kb_codes.h
+ln -s ../../../../install/powerpc-apple-darwin/include/architecture/alignment.h architecture/alignment.h
+ln -s ../../../../install/powerpc-apple-darwin/include/architecture/adb_bus.h architecture/adb_bus.h
+ln -s ../../../../install/powerpc-apple-darwin/include/architecture/adb_kb_map.h architecture/adb_kb_map.h
+ln -s ../../../../install/powerpc-apple-darwin/include/architecture/arch_types.h architecture/arch_types.h
+ln -s ../../../../install/powerpc-apple-darwin/include/architecture/ascii_codes.h architecture/ascii_codes.h
+ln -s ../../../../install/powerpc-apple-darwin/include/architecture/byte_order.h architecture/byte_order.h
+ln -s ../../../../install/powerpc-apple-darwin/include/sys/appleapiopts.h sys/appleapiopts.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach_debug/mach_debug_types.defs mach_debug/mach_debug_types.defs
+ln -s ../../../../install/powerpc-apple-darwin/include/mach_debug/mach_debug_types.h mach_debug/mach_debug_types.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach_debug/mach_debug.h mach_debug/mach_debug.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach_debug/hash_info.h mach_debug/hash_info.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach_debug/ipc_info.h mach_debug/ipc_info.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach_debug/vm_info.h mach_debug/vm_info.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach_debug/zone_info.h mach_debug/zone_info.h
+ln -s ../../../../install/powerpc-apple-darwin/include/mach_debug/page_info.h mach_debug/page_info.h
+ln -s ../../../../install/powerpc-apple-darwin/include/machine machine
+ln -s ../../../../install/powerpc-apple-darwin/include/machine/byte_order.h machine/byte_order.h
+ln -s ../../../../install/powerpc-apple-darwin/include/machine/cons.h machine/cons.h
+ln -s ../../../../install/powerpc-apple-darwin/include/machine/ansi.h machine/ansi.h
+ln -s ../../../../install/powerpc-apple-darwin/include/machine/disklabel.h machine/disklabel.h
+ln -s ../../../../install/powerpc-apple-darwin/include/machine/endian.h machine/endian.h
+ln -s ../../../../install/powerpc-apple-darwin/include/machine/cpu.h machine/cpu.h
+ln -s ../../../../install/powerpc-apple-darwin/include/machine/label_t.h machine/label_t.h
+ln -s ../../../../install/powerpc-apple-darwin/include/machine/param.h machine/param.h
+ln -s ../../../../install/powerpc-apple-darwin/include/machine/exec.h machine/exec.h
+ln -s ../../../../install/powerpc-apple-darwin/include/machine/profile.h machine/profile.h
+ln -s ../../../../install/powerpc-apple-darwin/include/machine/psl.h machine/psl.h
+ln -s ../../../../install/powerpc-apple-darwin/include/machine/proc.h machine/proc.h
+ln -s ../../../../install/powerpc-apple-darwin/include/machine/unix_traps.h machine/unix_traps.h
+ln -s ../../../../install/powerpc-apple-darwin/include/machine/user.h machine/user.h
+ln -s ../../../../install/powerpc-apple-darwin/include/machine/ptrace.h machine/ptrace.h
+ln -s ../../../../install/powerpc-apple-darwin/include/machine/reboot.h machine/reboot.h
+ln -s ../../../../install/powerpc-apple-darwin/include/machine/reg.h machine/reg.h
+ln -s ../../../../install/powerpc-apple-darwin/include/machine/setjmp.h machine/setjmp.h
+ln -s ../../../../install/powerpc-apple-darwin/include/machine/signal.h machine/signal.h
+ln -s ../../../../install/powerpc-apple-darwin/include/machine/spl.h machine/spl.h
+ln -s ../../../../install/powerpc-apple-darwin/include/machine/table.h machine/table.h
+ln -s ../../../../install/powerpc-apple-darwin/include/machine/trap.h machine/trap.h
+ln -s ../../../../install/powerpc-apple-darwin/include/machine/types.h machine/types.h
+ln -s ../../../../install/powerpc-apple-darwin/include/machine/vmparam.h machine/vmparam.h
+ln -s ../../../../install/powerpc-apple-darwin/include/machine/ucontext.h machine/ucontext.h
+ln -s ../../../../install/powerpc-apple-darwin/include/ppc/limits.h ppc/limits.h
+ln -s ../../../../install/powerpc-apple-darwin/include/ppc/ansi.h ppc/ansi.h
+ln -s ../../../../install/powerpc-apple-darwin/include/ppc/disklabel.h ppc/disklabel.h
+
+
+
+ln -s ../../../../install/powerpc-apple-darwin/include/ppc/cpu.h ppc/cpu.h
+ln -s ../../../../install/powerpc-apple-darwin/include/ppc/label_t.h ppc/label_t.h
+ln -s ../../../../install/powerpc-apple-darwin/include/ppc/param.h ppc/param.h
+ln -s ../../../../install/powerpc-apple-darwin/include/ppc/exec.h ppc/exec.h
+ln -s ../../../../install/powerpc-apple-darwin/include/ppc/profile.h ppc/profile.h
+ln -s ../../../../install/powerpc-apple-darwin/include/ppc/psl.h ppc/psl.h
+ln -s ../../../../install/powerpc-apple-darwin/include/ppc/ptrace.h ppc/ptrace.h
+ln -s ../../../../install/powerpc-apple-darwin/include/ppc/reboot.h ppc/reboot.h
+ln -s ../../../../install/powerpc-apple-darwin/include/ppc/reg.h ppc/reg.h
+ln -s ../../../../install/powerpc-apple-darwin/include/ppc/setjmp.h ppc/setjmp.h
+ln -s ../../../../install/powerpc-apple-darwin/include/ppc/signal.h ppc/signal.h
+ln -s ../../../../install/powerpc-apple-darwin/include/ppc/spl.h ppc/spl.h
+ln -s ../../../../install/powerpc-apple-darwin/include/ppc/table.h ppc/table.h
+ln -s ../../../../install/powerpc-apple-darwin/include/ppc/types.h ppc/types.h
+ln -s ../../../../install/powerpc-apple-darwin/include/ppc/user.h ppc/user.h
+ln -s ../../../../install/powerpc-apple-darwin/include/ppc/vmparam.h ppc/vmparam.h
+ln -s ../../../../install/powerpc-apple-darwin/include/ppc/ucontext.h ppc/ucontext.h
+ln -s ../../../install/powerpc-apple-darwin/include/crt_externs.h crt_externs.h
+ln -s ../../../install/powerpc-apple-darwin/include/libc.h libc.h
+ln -s ../../../install/powerpc-apple-darwin/include/standards.h standards.h
+ln -s ../../../../install/powerpc-apple-darwin/include/servers/bootstrap_defs.h servers/bootstrap_defs.h
+ln -s ../../../../install/powerpc-apple-darwin/include/servers/key_defs.h servers/key_defs.h
+ln -s ../../../../install/powerpc-apple-darwin/include/servers/ls_defs.h servers/ls_defs.h
+ln -s ../../../../install/powerpc-apple-darwin/include/servers/netname_defs.h servers/netname_defs.h
+ln -s ../../../../install/powerpc-apple-darwin/include/servers/nm_defs.h servers/nm_defs.h
+ln -s ../../../../install/powerpc-apple-darwin/include/servers/bootstrap.h servers/bootstrap.h
+ln -s ../../../../install/powerpc-apple-darwin/include/servers/netname.h servers/netname.h
--- /dev/null
+diff -rub ./include/architecture/i386/frame.h ./include/architecture/i386/frame.h
+--- ./include/architecture/i386/frame.h Thu May 6 19:24:33 1999
++++ ./include/architecture/i386/frame.h Mon Aug 25 12:56:22 2003
+@@ -63,7 +63,7 @@
+ } pgfault;
+ } err_code_t;
+
+-#import <architecture/i386/sel.h>
++#include <architecture/i386/sel.h>
+
+ /*
+ * The actual hardware exception frame
+diff -rub ./include/architecture/m88k/fp_regs.h ./include/architecture/m88k/fp_regs.h
+--- ./include/architecture/m88k/fp_regs.h Wed Oct 9 18:47:37 2002
++++ ./include/architecture/m88k/fp_regs.h Mon Aug 25 12:56:22 2003
+@@ -37,7 +37,7 @@
+ #ifndef _ARCH_M88K_FP_REGS_H_
+ #define _ARCH_M88K_FP_REGS_H_
+
+-#import <architecture/m88k/reg_help.h>
++#include <architecture/m88k/reg_help.h>
+
+ /*
+ * m88k_xrf_t -- data types that MAY be in extended register file
+diff -rub ./include/architecture/m88k/reg_help.h ./include/architecture/m88k/reg_help.h
+--- ./include/architecture/m88k/reg_help.h Wed Oct 9 18:47:39 2002
++++ ./include/architecture/m88k/reg_help.h Mon Aug 25 12:56:22 2003
+@@ -37,7 +37,7 @@
+ #ifndef _ARCH_M88K_REG_HELP_H_
+ #define _ARCH_M88K_REG_HELP_H_
+
+-#import <architecture/nrw/reg_help.h>
++#include <architecture/nrw/reg_help.h>
+
+ /* Stack pointer must always be a multiple of 16 */
+ #define STACK_INCR 16
+diff -rub ./include/mach/m88k/thread_status.h ./include/mach/m88k/thread_status.h
+--- ./include/mach/m88k/thread_status.h Wed Oct 9 18:48:16 2002
++++ ./include/mach/m88k/thread_status.h Mon Aug 25 12:56:22 2003
+@@ -45,8 +45,8 @@
+ #ifndef _MACH_M88K_THREAD_STATE_
+ #define _MACH_M88K_THREAD_STATE_
+
+-#import <architecture/m88k/fp_regs.h>
+-#import <architecture/m88k/reg_help.h>
++#include <architecture/m88k/fp_regs.h>
++#include <architecture/m88k/reg_help.h>
+
+ /**************************************************************************
+ * Data Typedefs used by thread_getstatus() and thread_setstatus() *
+diff -rub ./include/mach/machine.h ./include/mach/machine.h
+--- ./include/mach/machine.h Mon Feb 10 19:52:25 2003
++++ ./include/mach/machine.h Mon Aug 25 12:56:22 2003
+@@ -81,8 +81,8 @@
+ #ifndef _MACH_MACHINE_H_
+ #define _MACH_MACHINE_H_
+
+-#import <mach/machine/vm_types.h>
+-#import <mach/boolean.h>
++#include <mach/machine/vm_types.h>
++#include <mach/boolean.h>
+
+ /*
+ * For each host, there is a maximum possible number of
+diff -rub ./include/mach-o/hppa/swap.h ./include/mach-o/hppa/swap.h
+--- ./include/mach-o/hppa/swap.h Thu May 6 19:25:11 1999
++++ ./include/mach-o/hppa/swap.h Mon Aug 25 12:56:22 2003
+@@ -21,8 +21,8 @@
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+-#import <architecture/byte_order.h>
+-#import <mach/hppa/thread_status.h>
++#include <architecture/byte_order.h>
++#include <mach/hppa/thread_status.h>
+
+ extern void swap_hppa_integer_thread_state(
+ struct hp_pa_integer_thread_state *regs,
+diff -rub ./include/mach-o/i860/swap.h ./include/mach-o/i860/swap.h
+--- ./include/mach-o/i860/swap.h Thu May 6 19:25:19 1999
++++ ./include/mach-o/i860/swap.h Mon Aug 25 12:56:22 2003
+@@ -21,8 +21,8 @@
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+-#import <architecture/byte_order.h>
+-#import <mach/i860/thread_status.h>
++#include <architecture/byte_order.h>
++#include <mach/i860/thread_status.h>
+
+ extern void swap_i860_thread_state_regs(
+ struct i860_thread_state_regs *cpu,
+diff -rub ./include/mach-o/m68k/swap.h ./include/mach-o/m68k/swap.h
+--- ./include/mach-o/m68k/swap.h Thu May 6 19:25:26 1999
++++ ./include/mach-o/m68k/swap.h Mon Aug 25 12:56:22 2003
+@@ -21,8 +21,8 @@
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+-#import <architecture/byte_order.h>
+-#import <mach/m68k/thread_status.h>
++#include <architecture/byte_order.h>
++#include <mach/m68k/thread_status.h>
+
+ extern void swap_m68k_thread_state_regs(
+ struct m68k_thread_state_regs *cpu,
+diff -rub ./include/mach-o/m88k/swap.h ./include/mach-o/m88k/swap.h
+--- ./include/mach-o/m88k/swap.h Thu May 6 19:25:31 1999
++++ ./include/mach-o/m88k/swap.h Mon Aug 25 12:56:22 2003
+@@ -21,8 +21,8 @@
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+-#import <architecture/byte_order.h>
+-#import <mach/m88k/thread_status.h>
++#include <architecture/byte_order.h>
++#include <mach/m88k/thread_status.h>
+
+ extern void swap_m88k_thread_state_grf_t(
+ m88k_thread_state_grf_t *cpu,
+diff -rub ./include/mach-o/rld.h ./include/mach-o/rld.h
+--- ./include/mach-o/rld.h Tue Oct 2 15:19:03 2001
++++ ./include/mach-o/rld.h Mon Aug 25 12:56:22 2003
+@@ -28,7 +28,7 @@
+ #ifndef _MACHO_RLD_H_
+ #define _MACHO_RLD_H_
+
+-#include <streams/streams.h>
++//~ #include <streams/streams.h>
+ #include <mach-o/loader.h>
+
+ extern long rld_load(
+diff -rub ./include/mach-o/sparc/swap.h ./include/mach-o/sparc/swap.h
+--- ./include/mach-o/sparc/swap.h Thu May 6 19:25:56 1999
++++ ./include/mach-o/sparc/swap.h Mon Aug 25 12:56:22 2003
+@@ -21,8 +21,8 @@
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+-#import <architecture/byte_order.h>
+-#import <mach/sparc/thread_status.h>
++#include <architecture/byte_order.h>
++#include <mach/sparc/thread_status.h>
+
+ void swap_sparc_thread_state_regs(
+ struct sparc_thread_state_regs *cpu,
+diff -rub ./include/standalone/libsa.h ./include/standalone/libsa.h
+--- ./include/standalone/libsa.h Mon Sep 11 15:03:00 2000
++++ ./include/standalone/libsa.h Mon Aug 25 12:56:22 2003
+@@ -23,13 +23,13 @@
+ */
+ /* Exported API for standalone library */
+ #if !(defined(KLD) && defined(__STATIC__))
+-#import <mach/mach.h>
++#include <mach/mach.h>
+ #else /* defined(KLD) && defined(__STATIC__) */
+ #include <mach/kern_return.h>
+ #endif /* !(defined(KLD) && defined(__STATIC__)) */
+-#import <mach-o/loader.h>
+-#import <stdarg.h>
+-#import <stddef.h>
++#include <mach-o/loader.h>
++#include <stdarg.h>
++#include <stddef.h>
+
+ #ifndef bcopy
+ #ifdef __OPENSTEP__
+diff -rub ./include/stuff/allocate.h ./include/stuff/allocate.h
+--- ./include/stuff/allocate.h Thu May 6 19:26:24 1999
++++ ./include/stuff/allocate.h Mon Aug 25 13:08:44 2003
+@@ -21,8 +21,10 @@
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+-#if defined(__MWERKS__) && !defined(__private_extern__)
++#if ( defined(__MWERKS__) && !defined(__private_extern__) )
+ #define __private_extern__ __declspec(private_extern)
++#elif ( defined(__linux__) && !defined(__private_extern__) )
++#define __private_extern__ extern
+ #endif
+
+ /* defined in allocate.c */
+diff -rub ./include/stuff/arch.h ./include/stuff/arch.h
+--- ./include/stuff/arch.h Mon Nov 19 12:09:40 2001
++++ ./include/stuff/arch.h Mon Aug 25 13:10:15 2003
+@@ -24,15 +24,17 @@
+ #ifndef _STUFF_ARCH_H_
+ #define _STUFF_ARCH_H_
+
+-#if defined(__MWERKS__) && !defined(__private_extern__)
++#if ( defined(__MWERKS__) && !defined(__private_extern__) )
+ #define __private_extern__ __declspec(private_extern)
++#elif ( defined(__linux__) && !defined(__private_extern__) )
++#define __private_extern__ extern
+ #endif
+ /*
+ * This file contains the current known set of flags and constants for the
+ * known architectures.
+ */
+-#import <mach/machine.h>
+-#import <stuff/bytesex.h>
++#include <mach/machine.h>
++#include <stuff/bytesex.h>
+
+ /*
+ * The structure describing an architecture flag with the string of the flag
+diff -rub ./include/stuff/best_arch.h ./include/stuff/best_arch.h
+--- ./include/stuff/best_arch.h Thu May 6 19:26:29 1999
++++ ./include/stuff/best_arch.h Mon Aug 25 13:10:13 2003
+@@ -21,8 +21,10 @@
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+-#if defined(__MWERKS__) && !defined(__private_extern__)
++#if ( defined(__MWERKS__) && !defined(__private_extern__) )
+ #define __private_extern__ __declspec(private_extern)
++#elif ( defined(__linux__) && !defined(__private_extern__) )
++#define __private_extern__ extern
+ #endif
+
+ #include <mach/machine.h>
+diff -rub ./include/stuff/breakout.h ./include/stuff/breakout.h
+--- ./include/stuff/breakout.h Mon May 6 14:03:46 2002
++++ ./include/stuff/breakout.h Mon Aug 25 13:10:12 2003
+@@ -21,11 +21,13 @@
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+-#if defined(__MWERKS__) && !defined(__private_extern__)
++#if ( defined(__MWERKS__) && !defined(__private_extern__) )
+ #define __private_extern__ __declspec(private_extern)
++#elif ( defined(__linux__) && !defined(__private_extern__) )
++#define __private_extern__ extern
+ #endif
+
+-#import "stuff/ofile.h"
++#include "stuff/ofile.h"
+
+ /*
+ * The input files are broken out in to their object files and then placed in
+diff -rub ./include/stuff/bytesex.h ./include/stuff/bytesex.h
+--- ./include/stuff/bytesex.h Mon Nov 19 12:09:42 2001
++++ ./include/stuff/bytesex.h Mon Aug 25 13:10:10 2003
+@@ -25,23 +25,25 @@
+ #ifndef _STUFF_BYTESEX_H_
+ #define _STUFF_BYTESEX_H_
+
+-#if defined(__MWERKS__) && !defined(__private_extern__)
++#if ( defined(__MWERKS__) && !defined(__private_extern__) )
+ #define __private_extern__ __declspec(private_extern)
++#elif ( defined(__linux__) && !defined(__private_extern__) )
++#define __private_extern__ extern
+ #endif
+
+-#import <mach-o/fat.h>
+-#import <mach-o/loader.h>
+-#import <mach/m68k/thread_status.h>
+-#import <mach/ppc/thread_status.h>
+-#import <mach/m88k/thread_status.h>
+-#import <mach/i860/thread_status.h>
+-#import <mach/i386/thread_status.h>
+-#import <mach/hppa/thread_status.h>
+-#import <mach/sparc/thread_status.h>
+-#import <mach-o/nlist.h>
+-#import <mach-o/reloc.h>
+-#import <mach-o/ranlib.h>
+-#import "stuff/bool.h"
++#include <mach-o/fat.h>
++#include <mach-o/loader.h>
++#include <mach/m68k/thread_status.h>
++#include <mach/ppc/thread_status.h>
++#include <mach/m88k/thread_status.h>
++#include <mach/i860/thread_status.h>
++#include <mach/i386/thread_status.h>
++#include <mach/hppa/thread_status.h>
++#include <mach/sparc/thread_status.h>
++#include <mach-o/nlist.h>
++#include <mach-o/reloc.h>
++#include <mach-o/ranlib.h>
++#include "stuff/bool.h"
+
+ enum byte_sex {
+ UNKNOWN_BYTE_SEX,
+diff -rub ./include/stuff/errors.h ./include/stuff/errors.h
+--- ./include/stuff/errors.h Thu May 6 19:26:40 1999
++++ ./include/stuff/errors.h Mon Aug 25 13:09:00 2003
+@@ -21,11 +21,13 @@
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+-#if defined(__MWERKS__) && !defined(__private_extern__)
++#if ( defined(__MWERKS__) && !defined(__private_extern__) )
+ #define __private_extern__ __declspec(private_extern)
++#elif ( defined(__linux__) && !defined(__private_extern__) )
++#define __private_extern__ extern
+ #endif
+
+-#import "mach/mach.h"
++#include "mach/mach.h"
+
+ /* user defined (imported) */
+ __private_extern__ char *progname;
+diff -rub ./include/stuff/execute.h ./include/stuff/execute.h
+--- ./include/stuff/execute.h Thu May 6 19:26:42 1999
++++ ./include/stuff/execute.h Mon Aug 25 13:10:04 2003
+@@ -21,8 +21,10 @@
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+-#if defined(__MWERKS__) && !defined(__private_extern__)
++#if ( defined(__MWERKS__) && !defined(__private_extern__) )
+ #define __private_extern__ __declspec(private_extern)
++#elif ( defined(__linux__) && !defined(__private_extern__) )
++#define __private_extern__ extern
+ #endif
+
+ /*
+diff -rub ./include/stuff/hash_string.h ./include/stuff/hash_string.h
+--- ./include/stuff/hash_string.h Thu May 6 19:26:45 1999
++++ ./include/stuff/hash_string.h Mon Aug 25 13:10:32 2003
+@@ -21,8 +21,10 @@
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+-#if defined(__MWERKS__) && !defined(__private_extern__)
++#if ( defined(__MWERKS__) && !defined(__private_extern__) )
+ #define __private_extern__ __declspec(private_extern)
++#elif ( defined(__linux__) && !defined(__private_extern__) )
++#define __private_extern__ extern
+ #endif
+
+ __private_extern__ long hash_string(
+diff -rub ./include/stuff/hppa.h ./include/stuff/hppa.h
+--- ./include/stuff/hppa.h Thu May 6 19:26:47 1999
++++ ./include/stuff/hppa.h Mon Aug 25 13:10:40 2003
+@@ -21,8 +21,10 @@
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+-#if defined(__MWERKS__) && !defined(__private_extern__)
++#if ( defined(__MWERKS__) && !defined(__private_extern__) )
+ #define __private_extern__ __declspec(private_extern)
++#elif ( defined(__linux__) && !defined(__private_extern__) )
++#define __private_extern__ extern
+ #endif
+
+ __private_extern__ void calc_hppa_HILO(
+diff -rub ./include/stuff/ofile.h ./include/stuff/ofile.h
+--- ./include/stuff/ofile.h Mon Feb 10 19:52:33 2003
++++ ./include/stuff/ofile.h Mon Aug 25 13:10:51 2003
+@@ -25,21 +25,23 @@
+ #ifndef _STUFF_OFILE_H_
+ #define _STUFF_OFILE_H_
+
+-#if defined(__MWERKS__) && !defined(__private_extern__)
++#if ( defined(__MWERKS__) && !defined(__private_extern__) )
+ #define __private_extern__ __declspec(private_extern)
++#elif ( defined(__linux__) && !defined(__private_extern__) )
++#define __private_extern__ extern
+ #endif
+
+-#import <ar.h>
++#include <ar.h>
+ #ifndef AR_EFMT1
+ #define AR_EFMT1 "#1/" /* extended format #1 */
+ #endif
+-#import <mach-o/loader.h>
++#include <mach-o/loader.h>
+ #ifdef OFI
+-#import <mach-o/dyld.h>
++#include <mach-o/dyld.h>
+ #endif
+-#import "stuff/bytesex.h"
+-#import "stuff/bool.h"
+-#import "stuff/arch.h"
++#include "stuff/bytesex.h"
++#include "stuff/bool.h"
++#include "stuff/arch.h"
+
+ enum ofile_type {
+ OFILE_UNKNOWN,
+diff -rub ./include/stuff/print.h ./include/stuff/print.h
+--- ./include/stuff/print.h Thu May 6 19:26:55 1999
++++ ./include/stuff/print.h Mon Aug 25 13:10:58 2003
+@@ -21,11 +21,13 @@
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+-#if defined(__MWERKS__) && !defined(__private_extern__)
++#if ( defined(__MWERKS__) && !defined(__private_extern__) )
+ #define __private_extern__ __declspec(private_extern)
++#elif ( defined(__linux__) && !defined(__private_extern__) )
++#define __private_extern__ extern
+ #endif
+
+-#import <stdarg.h>
++#include <stdarg.h>
+
+ __private_extern__ void print(
+ const char *format, ...)
+diff -rub ./include/stuff/reloc.h ./include/stuff/reloc.h
+--- ./include/stuff/reloc.h Thu May 6 19:26:57 1999
++++ ./include/stuff/reloc.h Mon Aug 25 13:11:02 2003
+@@ -21,12 +21,14 @@
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+-#if defined(__MWERKS__) && !defined(__private_extern__)
++#if ( defined(__MWERKS__) && !defined(__private_extern__) )
+ #define __private_extern__ __declspec(private_extern)
++#elif ( defined(__linux__) && !defined(__private_extern__) )
++#define __private_extern__ extern
+ #endif
+
+-#import <mach/machine.h>
+-#import "stuff/bool.h"
++#include <mach/machine.h>
++#include "stuff/bool.h"
+
+ __private_extern__ unsigned long reloc_pair_r_type(
+ cpu_type_t cputype);
+diff -rub ./include/stuff/round.h ./include/stuff/round.h
+--- ./include/stuff/round.h Fri Mar 14 18:18:29 2003
++++ ./include/stuff/round.h Mon Aug 25 13:11:06 2003
+@@ -21,8 +21,10 @@
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+-#if defined(__MWERKS__) && !defined(__private_extern__)
++#if ( defined(__MWERKS__) && !defined(__private_extern__) )
+ #define __private_extern__ __declspec(private_extern)
++#elif ( defined(__linux__) && !defined(__private_extern__) )
++#define __private_extern__ extern
+ #endif
+
+ /*
+diff -rub ./include/stuff/symbol_list.h ./include/stuff/symbol_list.h
+--- ./include/stuff/symbol_list.h Thu Oct 24 17:04:30 2002
++++ ./include/stuff/symbol_list.h Mon Aug 25 13:19:46 2003
+@@ -1,6 +1,12 @@
+ #include <mach-o/nlist.h>
+ #include <stuff/bool.h>
+
++#if ( defined(__MWERKS__) && !defined(__private_extern__) )
++#define __private_extern__ __declspec(private_extern)
++#elif ( defined(__linux__) && !defined(__private_extern__) )
++#define __private_extern__ extern
++#endif
++
+ /*
+ * Data structures to perform selective stripping of symbol table entries.
+ */
+diff -rub ./include/stuff/vm_flush_cache.h ./include/stuff/vm_flush_cache.h
+--- ./include/stuff/vm_flush_cache.h Thu May 6 19:27:05 1999
++++ ./include/stuff/vm_flush_cache.h Mon Aug 25 13:11:15 2003
+@@ -21,11 +21,13 @@
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+-#if defined(__MWERKS__) && !defined(__private_extern__)
++#if ( defined(__MWERKS__) && !defined(__private_extern__) )
+ #define __private_extern__ __declspec(private_extern)
++#elif ( defined(__linux__) && !defined(__private_extern__) )
++#define __private_extern__ extern
+ #endif
+
+-#import <mach/mach.h>
++#include <mach/mach.h>
+ __private_extern__ kern_return_t vm_flush_cache(
+ mach_port_t target_task,
+ vm_address_t address,
+diff -rub ./ld/Makefile ./ld/Makefile
+--- ./ld/Makefile Fri Mar 14 18:18:29 2003
++++ ./ld/Makefile Sat Sep 6 20:17:46 2003
+@@ -9,10 +9,10 @@
+ -DKERNEL -DKERNEL_PRIVATE -DAPPLE -DNeXT -DLIBSA_PRIVATE
+
+
+-MIG = $(NEXT_ROOT)/usr/bin/mig
++MIG = mig
+
+ ifeq "macos" "$(RC_OS)"
+- X_CFLAGS := $(shell if [ "$(RC_RELEASE)" != "Beaker" ] && \
++ X_CFLAGS := $(shell if [ `uname` != "Linux" ] && [ "$(RC_RELEASE)" != "Beaker" ] && \
+ [ "$(RC_RELEASE)" != "Bunsen" ] && \
+ [ "$(RC_RELEASE)" != "Gonzo" ] && \
+ [ "$(RC_RELEASE)" != "Kodiak" ]; then \
+@@ -21,10 +21,19 @@
+ endif
+
+ ifneq "mwccppc" "$(notdir $(CC))"
++ ifeq "Linux" "$(shell uname)"
++ GCC_FLAGS = -Wall $(X_CFLAGS) -D__LITTLE_ENDIAN__ -U__BIG_ENDIAN__ -D__ppc__ -I/usr/include -I../../../macosx-include
++ else
+ GCC_FLAGS = -Wall $(X_CFLAGS)
++ endif
+ endif
+
+-USE_DEPENDENCY_FILE := $(shell if [ "$(notdir $(CC))" != "mwccppc" ]; then \
++# Hack: Add ../misc to the path because it contains seg_hack and ver_string
++ifneq ($(findstring ../misc,$(PATH)),../misc)
++ PATH:=../misc:../../misc:$(PATH)
++endif
++
++USE_DEPENDENCY_FILE := $(shell if [ `uname` != "Linux" ] && [ "$(notdir $(CC))" != "mwccppc" ]; then \
+ echo YES ; else echo NO ; \
+ fi; )
+
+@@ -78,7 +87,7 @@
+ fvmlibs.c layout.c specs.c pass2.c generic_reloc.c rld.c sets.c \
+ 4byte_literals.c 8byte_literals.c literal_pointers.c dylibs.c \
+ indirect_sections.c mod_sections.c i860_reloc.c ppc_reloc.c \
+- m88k_reloc.c hppa_reloc.c sparc_reloc.c coalesced_sections.c
++ m88k_reloc.c hppa_reloc.c sparc_reloc.c coalesced_sections.c fake-mach.c
+ OBJS = $(CFILES:.c=.o)
+ INSTALL_FILES = $(CFILES) $(HFILES) Makefile notes \
+ make.defs make_defs.h librld.ofileList
+@@ -341,8 +350,9 @@
+ makeUser.c ld.c: make.h
+
+ make.h makeUser.c: make.defs
+- $(MIG) $(MIG_FLAGS) $(SRCROOT)/make.defs
+- rm -f makeServer.c
++ #~ $(MIG) $(MIG_FLAGS) $(SRCROOT)/make.defs
++ #~ rm -f makeServer.c
++ cp $(SRCROOT)/makeUser.c .
+
+ ld_vers.o: ld_vers.c
+ ifeq "mwccppc" "$(notdir $(CC))"
+diff -rub ./ld/layout.c ./ld/layout.c
+--- ./ld/layout.c Wed May 28 18:29:27 2003
++++ ./ld/layout.c Mon Aug 25 23:22:05 2003
+@@ -42,18 +42,22 @@
+ #include "stuff/openstep_mach.h"
+ #include <mach-o/fat.h>
+ #include <mach-o/loader.h>
+-#import <mach/m68k/thread_status.h>
+-#import <mach/ppc/thread_status.h>
+-#import <mach/m88k/thread_status.h>
+-#import <mach/i860/thread_status.h>
+-#import <mach/i386/thread_status.h>
+-#import <mach/hppa/thread_status.h>
+-#import <mach/sparc/thread_status.h>
++#include <mach/m68k/thread_status.h>
++#include <mach/ppc/thread_status.h>
++#include <mach/m88k/thread_status.h>
++#include <mach/i860/thread_status.h>
++#include <mach/i386/thread_status.h>
++#include <mach/hppa/thread_status.h>
++#include <mach/sparc/thread_status.h>
+ #include <mach-o/nlist.h>
+ #include <mach-o/reloc.h>
++
++#include <mach/kern_return.h>
++
+ #if defined(RLD) && !defined(SA_RLD) && !(defined(KLD) && defined(__STATIC__))
++typedef void NXStream;
+ #include <mach-o/rld.h>
+-#include <streams/streams.h>
++//~ #include <streams/streams.h>
+ #endif /* defined(RLD) && !defined(SA_RLD) &&
+ !(defined(KLD) && defined(__STATIC__)) */
+ #include "stuff/arch.h"
+@@ -72,6 +76,15 @@
+ #include "sets.h"
+ #include "mach-o/sarld.h"
+ #include "indirect_sections.h"
++
++#if ( defined(__MWERKS__) && !defined(__private_extern__) )
++#define __private_extern__ __declspec(private_extern)
++#elif ( defined(__linux__) && !defined(__private_extern__) )
++#define __private_extern__ extern
++#endif
++
++/** gcc on Linux defines powerpc, if we are compiling on a powerpc. */
++#undef powerpc
+
+ #ifdef RLD
+ __private_extern__ long RLD_DEBUG_OUTPUT_FILENAME_flag;
+diff -rub ./ld/rld.c ./ld/rld.c
+--- ./ld/rld.c Wed May 28 18:29:32 2003
++++ ./ld/rld.c Mon Aug 25 22:11:47 2003
+@@ -56,11 +56,13 @@
+ #include "stuff/openstep_mach.h"
+ #include <mach-o/fat.h>
+ #include <mach-o/nlist.h>
+-#ifdef KLD
++//~ #ifdef KLD
+ #include <mach-o/kld.h>
+-#else /* !defined(KLD) */
++#ifndef KLD
++//~ #else /* !defined(KLD) */
++typedef void NXStream;
+ #include <mach-o/rld.h>
+-#include <streams/streams.h>
++//~ #include <streams/streams.h>
+ #include <objc/zone.h>
+ #endif /* KLD */
+ #include <mach-o/rld_state.h>
+diff -rub ./libstuff/Makefile ./libstuff/Makefile
+--- ./libstuff/Makefile Fri Mar 14 18:18:30 2003
++++ ./libstuff/Makefile Sat Sep 6 20:12:21 2003
+@@ -1,7 +1,7 @@
+ RC_OS = macos
+ OFLAG = -O
+ ifeq "macos" "$(RC_OS)"
+- X_CFLAGS := $(shell if [ "$(RC_RELEASE)" != "Beaker" ] && \
++ X_CFLAGS := $(shell if [ `uname` != "Linux" ] && [ "$(RC_RELEASE)" != "Beaker" ] && \
+ [ "$(RC_RELEASE)" != "Bunsen" ] && \
+ [ "$(RC_RELEASE)" != "Gonzo" ] && \
+ [ "$(RC_RELEASE)" != "Kodiak" ]; then \
+@@ -10,14 +10,18 @@
+ endif
+
+
+-USE_DEPENDENCY_FILE := $(shell if [ "$(notdir $(CC))" != "mwccppc" ]; then \
++USE_DEPENDENCY_FILE := $(shell if [ `uname` != "Linux" ] && [ "$(notdir $(CC))" != "mwccppc" ]; then \
+ echo YES ; else echo NO ; \
+ fi; )
+
+ ifeq "mwccppc" "$(notdir $(CC))"
+ CFLAGS = $(OFLAG) -g -gccinc -I$(SRCROOT)/../include
+ else
++ ifeq "Linux" "$(shell uname)"
++ CFLAGS = $(OFLAG) -g -I$(SRCROOT)/../include -Wall $(X_CFLAGS) -D__LITTLE_ENDIAN__ -U__BIG_ENDIAN__ -D__ppc__ -I/usr/include -I../../../macosx-include
++ else
+ CFLAGS = $(OFLAG) -g -I$(SRCROOT)/../include -Wall $(X_CFLAGS)
++ endif
+ endif
+
+ ifneq "" "$(wildcard /bin/mkdirs)"
+@@ -41,7 +45,7 @@
+ breakout.c writeout.c checkout.c fatal_arch.c ofile_get_word.c \
+ vm_flush_cache.c hash_string.c dylib_roots.c guess_short_name.c \
+ SymLoc.c get_arch_from_host.c crc32.c macosx_deployment_target.c \
+- symbol_list.c
++ symbol_list.c fake-mach.c
+ OBJS = $(CFILES:.c=.o)
+ INSTALL_FILES = $(CFILES) Makefile notes
+
+@@ -91,7 +95,7 @@
+ OFILE_DIR=. \
+ SRCROOT=.. \
+ SYMROOT=.. \
+- COPTS="-dynamic" \
++ COPTS="" \
+ OFLAG="$(OFLAG)" \
+ CFILES="$(CFILES)" \
+ RC_CFLAGS="$(RC_CFLAGS)" \
+@@ -104,7 +108,7 @@
+ OFILE_DIR=$(OBJROOT)/dynamic_obj \
+ SRCROOT=$(SRCROOT) \
+ SYMROOT=$(SYMROOT) \
+- COPTS="-dynamic" \
++ COPTS="" \
+ OFLAG="$(OFLAG)" \
+ CFILES="$(CFILES)" \
+ RC_CFLAGS="$(RC_CFLAGS)" \
+@@ -121,7 +125,7 @@
+ OFILE_DIR=. \
+ SRCROOT=.. \
+ SYMROOT=.. \
+- COPTS="-dynamic -pg" \
++ COPTS="-pg" \
+ OFLAG="$(OFLAG)" \
+ RC_CFLAGS="$(RC_CFLAGS)" \
+ RC_ARCHS="$(RC_ARCHS)"; \
+@@ -133,7 +137,7 @@
+ OFILE_DIR=$(OBJROOT)/profile_obj \
+ SRCROOT=$(SRCROOT) \
+ SYMROOT=$(SYMROOT) \
+- COPTS="-dynamic -pg" \
++ COPTS="-pg" \
+ OFLAG="$(OFLAG)" \
+ RC_CFLAGS="$(RC_CFLAGS)" \
+ RC_ARCHS="$(RC_ARCHS)"; \
+@@ -168,7 +172,8 @@
+ fi
+
+ $(PRODUCT): $(OFILE_DIR) $(SYMROOT) $(OBJS)
+- libtool -static -o $(SYMROOT)/$(PRODUCT) $(OBJS)
++ ar r $(SYMROOT)/$(PRODUCT) $(OBJS)
++ ranlib $(SYMROOT)/$(PRODUCT)
+
+ ifeq "NO" "$(USE_DEPENDENCY_FILE)"
+ .c.o:
+diff -rub ./libstuff/SymLoc.c ./libstuff/SymLoc.c
+--- ./libstuff/SymLoc.c Thu Oct 24 17:04:50 2002
++++ ./libstuff/SymLoc.c Mon Aug 25 13:17:40 2003
+@@ -1,15 +1,15 @@
+-#import <libc.h>
+-#import <ctype.h>
+-#import <sys/types.h>
++#include <libc.h>
++#include <ctype.h>
++#include <sys/types.h>
+ #ifdef __OPENSTEP__
+ #define _POSIX_SOURCE
+ #endif
+-#import <dirent.h>
+-#import <pwd.h>
+-#import "stuff/bool.h"
+-#import "stuff/errors.h"
+-#import "stuff/allocate.h"
+-#import "stuff/SymLoc.h"
++#include <dirent.h>
++#include <pwd.h>
++#include "stuff/bool.h"
++#include "stuff/errors.h"
++#include "stuff/allocate.h"
++#include "stuff/SymLoc.h"
+
+ const char *
+ symLocForDylib(const char *installName, const char *releaseName,
+diff -rub ./libstuff/bytesex.c ./libstuff/bytesex.c
+--- ./libstuff/bytesex.c Mon Nov 19 12:10:07 2001
++++ ./libstuff/bytesex.c Mon Aug 25 13:17:40 2003
+@@ -25,13 +25,13 @@
+ #include <string.h>
+ #include <mach-o/fat.h>
+ #include <mach-o/loader.h>
+-#import <mach/m68k/thread_status.h>
+-#import <mach/ppc/thread_status.h>
+-#import <mach/m88k/thread_status.h>
+-#import <mach/i860/thread_status.h>
+-#import <mach/i386/thread_status.h>
+-#import <mach/hppa/thread_status.h>
+-#import <mach/sparc/thread_status.h>
++#include <mach/m68k/thread_status.h>
++#include <mach/ppc/thread_status.h>
++#include <mach/m88k/thread_status.h>
++#include <mach/i860/thread_status.h>
++#include <mach/i386/thread_status.h>
++#include <mach/hppa/thread_status.h>
++#include <mach/sparc/thread_status.h>
+ #include <mach-o/nlist.h>
+ #include <mach-o/reloc.h>
+ #include <mach-o/ranlib.h>
+diff -rub ./libstuff/crc32.c ./libstuff/crc32.c
+--- ./libstuff/crc32.c Wed Feb 13 17:53:36 2002
++++ ./libstuff/crc32.c Mon Aug 25 13:19:21 2003
+@@ -35,6 +35,12 @@
+ */
+ #include <sys/types.h>
+
++#if ( defined(__MWERKS__) && !defined(__private_extern__) )
++#define __private_extern__ __declspec(private_extern)
++#elif ( defined(__linux__) && !defined(__private_extern__) )
++#define __private_extern__ extern
++#endif
++
+ static const u_int32_t crctab[] = {
+ 0x0,
+ 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
+diff -rub ./libstuff/ofile.c ./libstuff/ofile.c
+--- ./libstuff/ofile.c Wed Apr 16 16:15:01 2003
++++ ./libstuff/ofile.c Tue Sep 2 20:15:34 2003
+@@ -21,6 +21,7 @@
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
++#include "machine/endian.h"
+ #ifdef SHLIB
+ #include "shlib.h"
+ #endif
+@@ -36,12 +37,12 @@
+ #include <sys/file.h>
+ #include <mach-o/fat.h>
+ #include <mach-o/loader.h>
+-#import <mach/m68k/thread_status.h>
+-#import <mach/ppc/thread_status.h>
+-#import <mach/m88k/thread_status.h>
+-#import <mach/i860/thread_status.h>
+-#import <mach/i386/thread_status.h>
+-#import <mach/sparc/thread_status.h>
++#include <mach/m68k/thread_status.h>
++#include <mach/ppc/thread_status.h>
++#include <mach/m88k/thread_status.h>
++#include <mach/i860/thread_status.h>
++#include <mach/i386/thread_status.h>
++#include <mach/sparc/thread_status.h>
+ #include <mach-o/nlist.h>
+ #include <mach-o/reloc.h>
+ #include "stuff/bool.h"
+@@ -677,7 +678,7 @@
+ memset(ofile, '\0', sizeof(struct ofile));
+
+ /* Open the file and map it in */
+- if((fd = open(file_name, O_RDONLY)) == -1){
++ if((fd = open(file_name, O_RDWR)) == -1){
+ #ifdef OFI
+ return(NSObjectFileImageAccess);
+ #else
+@@ -975,7 +976,7 @@
+ }
+ }
+ }
+- /* see if this file is Mach-O file */
++
+ else if(size >= sizeof(struct mach_header) &&
+ (magic == MH_MAGIC || magic == SWAP_LONG(MH_MAGIC))){
+ ofile->file_type = OFILE_Mach_O;
+diff -rub ./libstuff/print.c ./libstuff/print.c
+--- ./libstuff/print.c Thu May 6 19:30:58 1999
++++ ./libstuff/print.c Mon Aug 25 13:17:40 2003
+@@ -21,8 +21,8 @@
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+-#import <stdio.h>
+-#import "stuff/print.h"
++#include <stdio.h>
++#include "stuff/print.h"
+
+ /*
+ * All printing of all messages for ofile functions goes through this function.
+diff -rub ./libstuff/swap_headers.c ./libstuff/swap_headers.c
+--- ./libstuff/swap_headers.c Fri Oct 4 17:54:48 2002
++++ ./libstuff/swap_headers.c Mon Aug 25 13:17:40 2003
+@@ -22,13 +22,13 @@
+ * @APPLE_LICENSE_HEADER_END@
+ */
+ #include <mach-o/loader.h>
+-#import <mach/m68k/thread_status.h>
+-#import <mach/ppc/thread_status.h>
+-#import <mach/m88k/thread_status.h>
+-#import <mach/i860/thread_status.h>
+-#import <mach/i386/thread_status.h>
+-#import <mach/hppa/thread_status.h>
+-#import <mach/sparc/thread_status.h>
++#include <mach/m68k/thread_status.h>
++#include <mach/ppc/thread_status.h>
++#include <mach/m88k/thread_status.h>
++#include <mach/i860/thread_status.h>
++#include <mach/i386/thread_status.h>
++#include <mach/hppa/thread_status.h>
++#include <mach/sparc/thread_status.h>
+ #include "stuff/bool.h"
+ #include "stuff/bytesex.h"
+ #include "stuff/errors.h"
+diff -rub ./misc/Makefile ./misc/Makefile
+--- ./misc/Makefile Fri Mar 14 18:18:30 2003
++++ ./misc/Makefile Sat Sep 6 20:17:36 2003
+@@ -2,11 +2,11 @@
+ OFLAG = -O
+ RC_OS = macos
+ ifeq "macos" "$(RC_OS)"
+- X_CFLAGS := $(shell if [ "$(RC_RELEASE)" != "Beaker" ] && \
++ X_CFLAGS := $(shell if [ `uname` != "Linux" ] && [ "$(RC_RELEASE)" != "Beaker" ] && \
+ [ "$(RC_RELEASE)" != "Bunsen" ] && \
+ [ "$(RC_RELEASE)" != "Gonzo" ] && \
+ [ "$(RC_RELEASE)" != "Kodiak" ]; then \
+- echo -Wno-long-double -no-cpp-precomp; \
++ echo -Wno-long-double -no-cpp-precomp ; \
+ fi; )
+ endif
+
+@@ -14,11 +14,16 @@
+ CFLAGS = $(OFLAG) -g \
+ -I$(SRCROOT) -I$(SRCROOT)/../include -I$(OFILE_DIR)
+ else
++ ifeq "Linux" "$(shell uname)"
++ CFLAGS = $(OFLAG) -g -Wall $(X_CFLAGS) \
++ -I$(SRCROOT) -I$(SRCROOT)/../include -I$(OFILE_DIR) -D__LITTLE_ENDIAN__ -U__BIG_ENDIAN__ -D__ppc__ -I/usr/include -I../../macosx-include
++ else
+ CFLAGS = $(OFLAG) -g -Wall $(X_CFLAGS) \
+ -I$(SRCROOT) -I$(SRCROOT)/../include -I$(OFILE_DIR)
++ endif
+ endif
+
+-USE_DEPENDENCY_FILE := $(shell if [ "$(notdir $(CC))" != "mwccppc" ]; then \
++USE_DEPENDENCY_FILE := $(shell if [ `uname` != "Linux" ] && [ "$(notdir $(CC))" != "mwccppc" ]; then \
+ echo YES ; else echo NO ; \
+ fi; )
+
+@@ -44,10 +49,7 @@
+ LOCLIBDIR = /usr/local/lib
+
+ CFILES1 = libtool.c
+-CFILES2 = main.c lipo.c size.c strings.c nm.c checksyms.c inout.c \
+- indr.c strip.c atom.c segedit.c kern_tool.c cmpdylib.c \
+- dylib_pcsampler.c pagestuff.c redo_prebinding.c seg_addr_table.c \
+- check_dylib.c seg_hack.c check_hints.c install_name_tool.c
++CFILES2 = seg_hack.c strip.c
+ ifeq "nextstep" "$(RC_OS)"
+ CFILES3 = file.c ar.c
+ endif
+@@ -56,11 +58,7 @@
+ notes
+
+
+-PROGS = lipo.NEW size.NEW strings.NEW nm.NEW \
+- libtool.NEW checksyms.NEW indr.NEW strip.NEW nmedit.NEW \
+- segedit.NEW kern_tool.NEW cmpdylib.NEW \
+- dylib_pcsampler.NEW pagestuff.NEW redo_prebinding.NEW \
+- seg_addr_table.NEW check_dylib.NEW seg_hack.NEW install_name_tool.NEW
++PROGS = seg_hack.NEW strip.NEW
+
+ teflon_all macos_all: $(PROGS)
+
+@@ -71,7 +69,7 @@
+ lib_ofiles: $(OFILE_DIR) $(SYMROOT) libredo_prebinding.a
+
+ vers.c:
+- vers_string -c $(VERS_STRING_FLAGS) cctools_misc > $(OFILE_DIR)/$@
++ ./vers_string -c $(VERS_STRING_FLAGS) cctools_misc > $(OFILE_DIR)/$@
+
+ ifeq "NO" "$(USE_DEPENDENCY_FILE)"
+ .c.o:
+@@ -222,6 +220,7 @@
+ $(OFILE_DIR)/seg_hack.o $(OFILE_DIR)/vers.o $(LIBSTUFF)
+ $(CC) $(CFLAGS) $(RC_CFLAGS) -o $(SYMROOT)/seg_hack.NEW \
+ $(OFILE_DIR)/seg_hack.private.o
++ cp $(SYMROOT)/seg_hack.NEW $(SYMROOT)/seg_hack
+
+ install_name_tool.NEW: install_name_tool.o vers.o
+ $(CC) $(CFLAGS) $(RC_CFLAGS) -nostdlib -r \
+@@ -331,7 +330,8 @@
+ $(SYMROOT)/redo_prebinding.NEW \
+ $(SYMROOT)/libredo_prebinding.a \
+ $(SYMROOT)/kern_tool.NEW \
+- $(SYMROOT)/cmpdylib.NEW
++ $(SYMROOT)/cmpdylib.NEW \
++ $(SYMROOT)/seg_hack
+
+ shlib_clean:
+ -rm -f \
+--- ld/makeUser.c Sat Sep 6 21:52:24 2003
++++ ld/makeUser.c Mon Aug 25 22:54:46 2003
+@@ -0,0 +1,305 @@
++/*
++ * IDENTIFICATION:
++ * stub generated Mon Aug 25 15:06:30 2003
++ * with a MiG generated Tue Nov 5 01:17:50 PST 2002 by root@brixen
++ * OPTIONS:
++ */
++#include "make.h"
++
++
++#ifndef mig_internal
++#define mig_internal static
++#endif /* mig_internal */
++
++#ifndef mig_external
++#define mig_external
++#endif /* mig_external */
++
++#ifndef TypeCheck
++#define TypeCheck 0
++#endif /* TypeCheck */
++
++#ifndef LimitCheck
++#define LimitCheck 0
++#endif /* LimitCheck */
++
++#ifndef min
++#define min(a,b) ( ((a) < (b))? (a): (b) )
++#endif /* min */
++
++#ifndef UseStaticTemplates
++#define UseStaticTemplates 0
++#endif /* UseStaticTemplates */
++
++#define _WALIGN_(x) (((x) + 3) & ~3)
++#define _WALIGNSZ_(x) _WALIGN_(sizeof(x))
++#ifndef __MachMsgErrorWithTimeout
++#define __MachMsgErrorWithTimeout(_R_) { \
++ switch (_R_) { \
++ case MACH_SEND_INVALID_REPLY: \
++ case MACH_RCV_INVALID_NAME: \
++ case MACH_RCV_PORT_DIED: \
++ case MACH_RCV_PORT_CHANGED: \
++ case MACH_RCV_TIMED_OUT: \
++ mig_dealloc_reply_port(InP->Head.msgh_reply_port); \
++ break; \
++ default: \
++ mig_put_reply_port(InP->Head.msgh_reply_port); \
++ } \
++}
++#endif /* __MachMsgErrorWithTimeout */
++
++#ifndef __MachMsgErrorWithoutTimeout
++#define __MachMsgErrorWithoutTimeout(_R_) { \
++ switch (_R_) { \
++ case MACH_SEND_INVALID_REPLY: \
++ case MACH_RCV_INVALID_NAME: \
++ case MACH_RCV_PORT_DIED: \
++ case MACH_RCV_PORT_CHANGED: \
++ mig_dealloc_reply_port(InP->Head.msgh_reply_port); \
++ break; \
++ default: \
++ mig_put_reply_port(InP->Head.msgh_reply_port); \
++ } \
++}
++#endif /* __MachMsgErrorWithoutTimeout */
++
++#ifndef __DeclareSendRpc
++#define __DeclareSendRpc(_NUM_, _NAME_)
++#endif /* __DeclareSendRpc */
++
++#ifndef __BeforeSendRpc
++#define __BeforeSendRpc(_NUM_, _NAME_)
++#endif /* __BeforeSendRpc */
++
++#ifndef __AfterSendRpc
++#define __AfterSendRpc(_NUM_, _NAME_)
++#endif /* __AfterSendRpc */
++
++#ifndef __DeclareSendSimple
++#define __DeclareSendSimple(_NUM_, _NAME_)
++#endif /* __DeclareSendSimple */
++
++#ifndef __BeforeSendSimple
++#define __BeforeSendSimple(_NUM_, _NAME_)
++#endif /* __BeforeSendSimple */
++
++#ifndef __AfterSendSimple
++#define __AfterSendSimple(_NUM_, _NAME_)
++#endif /* __AfterSendSimple */
++
++#define msgh_request_port msgh_remote_port
++#define msgh_reply_port msgh_local_port
++
++
++
++/* SimpleRoutine alert_old */
++mig_external kern_return_t make_alert_old
++(
++ mach_port_t makePort,
++ int eventType,
++ make_string_t functionName,
++ mach_msg_type_number_t functionNameCnt,
++ make_string_t fileName,
++ mach_msg_type_number_t fileNameCnt,
++ int line,
++ make_string_t message,
++ mach_msg_type_number_t messageCnt
++)
++{
++ {
++ typedef struct {
++ mach_msg_header_t Head;
++ NDR_record_t NDR;
++ int eventType;
++ mach_msg_type_number_t functionNameCnt;
++ char functionName[1024];
++ mach_msg_type_number_t fileNameCnt;
++ char fileName[1024];
++ int line;
++ mach_msg_type_number_t messageCnt;
++ char message[1024];
++ } Request;
++
++ /*
++ * typedef struct {
++ * mach_msg_header_t Head;
++ * NDR_record_t NDR;
++ * kern_return_t RetCode;
++ * } mig_reply_error_t;
++ */
++
++ union {
++ Request In;
++ } Mess;
++
++ register Request *InP = &Mess.In;
++
++ mach_msg_return_t msg_result;
++ unsigned int msgh_size;
++ unsigned int msgh_size_delta;
++ __DeclareSendSimple(100, "alert_old")
++
++ InP->NDR = NDR_record;
++
++ InP->eventType = eventType;
++
++ if (functionNameCnt > 1024) {
++ { return MIG_ARRAY_TOO_LARGE; }
++ }
++ (void)memcpy((char *) InP->functionName, (const char *) functionName, functionNameCnt);
++
++ InP->functionNameCnt = functionNameCnt;
++
++ msgh_size_delta = _WALIGN_(functionNameCnt);
++ msgh_size = (sizeof(Request) - 3072) + msgh_size_delta;
++ InP = (Request *) ((pointer_t) InP + msgh_size_delta - 1024);
++
++ if (fileNameCnt > 1024) {
++ { return MIG_ARRAY_TOO_LARGE; }
++ }
++ (void)memcpy((char *) InP->fileName, (const char *) fileName, fileNameCnt);
++
++ InP->fileNameCnt = fileNameCnt;
++
++ msgh_size_delta = _WALIGN_(fileNameCnt);
++ msgh_size += msgh_size_delta;
++ InP = (Request *) ((pointer_t) InP + msgh_size_delta - 1024);
++
++ InP->line = line;
++
++ if (messageCnt > 1024) {
++ { return MIG_ARRAY_TOO_LARGE; }
++ }
++ (void)memcpy((char *) InP->message, (const char *) message, messageCnt);
++
++ InP->messageCnt = messageCnt;
++
++ msgh_size += _WALIGN_(messageCnt);
++ InP = &Mess.In;
++ InP->Head.msgh_bits =
++ MACH_MSGH_BITS(19, 0);
++ /* msgh_size passed as argument */
++ InP->Head.msgh_request_port = makePort;
++ InP->Head.msgh_reply_port = MACH_PORT_NULL;
++ InP->Head.msgh_id = 100;
++
++ __BeforeSendSimple(100, "alert_old")
++ msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_MSG_OPTION_NONE, msgh_size, 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
++ __AfterSendSimple(100, "alert_old")
++ return msg_result;
++ }
++}
++
++/* SimpleRoutine alert */
++mig_external kern_return_t make_alert
++(
++ mach_port_t makePort,
++ int eventType,
++ make_string_t functionName,
++ mach_msg_type_number_t functionNameCnt,
++ make_string_t fileName,
++ mach_msg_type_number_t fileNameCnt,
++ make_string_t directory,
++ mach_msg_type_number_t directoryCnt,
++ int line,
++ make_string_t message,
++ mach_msg_type_number_t messageCnt
++)
++{
++ {
++ typedef struct {
++ mach_msg_header_t Head;
++ NDR_record_t NDR;
++ int eventType;
++ mach_msg_type_number_t functionNameCnt;
++ char functionName[1024];
++ mach_msg_type_number_t fileNameCnt;
++ char fileName[1024];
++ mach_msg_type_number_t directoryCnt;
++ char directory[1024];
++ int line;
++ mach_msg_type_number_t messageCnt;
++ char message[1024];
++ } Request;
++
++ /*
++ * typedef struct {
++ * mach_msg_header_t Head;
++ * NDR_record_t NDR;
++ * kern_return_t RetCode;
++ * } mig_reply_error_t;
++ */
++
++ union {
++ Request In;
++ } Mess;
++
++ register Request *InP = &Mess.In;
++
++ mach_msg_return_t msg_result;
++ unsigned int msgh_size;
++ unsigned int msgh_size_delta;
++ __DeclareSendSimple(101, "alert")
++
++ InP->NDR = NDR_record;
++
++ InP->eventType = eventType;
++
++ if (functionNameCnt > 1024) {
++ { return MIG_ARRAY_TOO_LARGE; }
++ }
++ (void)memcpy((char *) InP->functionName, (const char *) functionName, functionNameCnt);
++
++ InP->functionNameCnt = functionNameCnt;
++
++ msgh_size_delta = _WALIGN_(functionNameCnt);
++ msgh_size = (sizeof(Request) - 4096) + msgh_size_delta;
++ InP = (Request *) ((pointer_t) InP + msgh_size_delta - 1024);
++
++ if (fileNameCnt > 1024) {
++ { return MIG_ARRAY_TOO_LARGE; }
++ }
++ (void)memcpy((char *) InP->fileName, (const char *) fileName, fileNameCnt);
++
++ InP->fileNameCnt = fileNameCnt;
++
++ msgh_size_delta = _WALIGN_(fileNameCnt);
++ msgh_size += msgh_size_delta;
++ InP = (Request *) ((pointer_t) InP + msgh_size_delta - 1024);
++
++ if (directoryCnt > 1024) {
++ { return MIG_ARRAY_TOO_LARGE; }
++ }
++ (void)memcpy((char *) InP->directory, (const char *) directory, directoryCnt);
++
++ InP->directoryCnt = directoryCnt;
++
++ msgh_size_delta = _WALIGN_(directoryCnt);
++ msgh_size += msgh_size_delta;
++ InP = (Request *) ((pointer_t) InP + msgh_size_delta - 1024);
++
++ InP->line = line;
++
++ if (messageCnt > 1024) {
++ { return MIG_ARRAY_TOO_LARGE; }
++ }
++ (void)memcpy((char *) InP->message, (const char *) message, messageCnt);
++
++ InP->messageCnt = messageCnt;
++
++ msgh_size += _WALIGN_(messageCnt);
++ InP = &Mess.In;
++ InP->Head.msgh_bits =
++ MACH_MSGH_BITS(19, 0);
++ /* msgh_size passed as argument */
++ InP->Head.msgh_request_port = makePort;
++ InP->Head.msgh_reply_port = MACH_PORT_NULL;
++ InP->Head.msgh_id = 101;
++
++ __BeforeSendSimple(101, "alert")
++ msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_MSG_OPTION_NONE, msgh_size, 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
++ __AfterSendSimple(101, "alert")
++ return msg_result;
++ }
++}
+diff -bur ./Makefile /home/megacz/xwt/upstream/darwin-linker/src/cctools/as/Makefile
+--- as/Makefile Fri Sep 6 18:27:10 2002
++++ as/Makefile Sat Sep 6 23:52:22 2003
+@@ -2,7 +2,7 @@
+ export USE_APPLE_PB_SUPPORT = all
+ OFLAG = -O
+ ifeq "macos" "$(RC_OS)"
+- X_CFLAGS := $(shell if [ "$(RC_RELEASE)" != "Beaker" ] && \
++ X_CFLAGS := $(shell if [ `uname` != "Linux" ] && [ "$(RC_RELEASE)" != "Beaker" ] && \
+ [ "$(RC_RELEASE)" != "Bunsen" ] && \
+ [ "$(RC_RELEASE)" != "Gonzo" ] && \
+ [ "$(RC_RELEASE)" != "Kodiak" ]; then \
+@@ -11,10 +11,14 @@
+ endif
+
+ ifneq "mwccppc" "$(notdir $(CC))"
++ ifeq "Linux" "$(shell uname)"
++ GCC_FLAGS = -Wall $(X_CFLAGS) -D__LITTLE_ENDIAN__ -U__BIG_ENDIAN__ -D__ppc__ -I/usr/include -I../../../macosx-include
++ else
+ GCC_FLAGS = -Wall -Wno-precomp $(X_CFLAGS)
++ endif
+ endif
+
+-USE_DEPENDENCY_FILE := $(shell if [ "$(notdir $(CC))" != "mwccppc" ]; then \
++USE_DEPENDENCY_FILE := $(shell if [ `uname` != "Linux" ] && [ "$(notdir $(CC))" != "mwccppc" ]; then \
+ echo YES ; else echo NO ; \
+ fi; )
+
+diff -bur ./app.h /home/megacz/xwt/upstream/darwin-linker/src/cctools/as/app.h
+--- as/app.h Tue Apr 30 00:37:17 2002
++++ as/app.h Sat Sep 6 23:49:28 2003
+@@ -1,4 +1,4 @@
+-#import <stdio.h>
++#include <stdio.h>
+
+ extern FILE *scrub_file;
+ extern char *scrub_string;
+diff -bur ./as.h /home/megacz/xwt/upstream/darwin-linker/src/cctools/as/as.h
+--- as/as.h Tue Apr 30 00:37:17 2002
++++ as/as.h Sat Sep 6 23:49:28 2003
+@@ -43,10 +43,10 @@
+ */
+ #undef SUSPECT
+
+-/* These #imports are for type definitions etc. */
+-#import <stdio.h>
+-#import <assert.h>
+-#import <mach/machine.h>
++/* These #includes are for type definitions etc. */
++#include <stdio.h>
++#include <assert.h>
++#include <mach/machine.h>
+
+ /* These defines are potentially useful */
+ #undef FALSE
+Only in /home/megacz/xwt/upstream/darwin-linker/src/cctools/as: asparc_dir
+diff -bur ./atof-ieee.h /home/megacz/xwt/upstream/darwin-linker/src/cctools/as/atof-ieee.h
+--- as/atof-ieee.h Tue Apr 30 00:37:17 2002
++++ as/atof-ieee.h Sat Sep 6 23:49:28 2003
+@@ -1,4 +1,4 @@
+-#import "flonum.h"
++#include "flonum.h"
+
+ extern char *atof_ieee(
+ char *str,
+diff -bur ./bignum.h /home/megacz/xwt/upstream/darwin-linker/src/cctools/as/bignum.h
+--- as/bignum.h Tue Apr 30 00:37:17 2002
++++ as/bignum.h Sat Sep 6 23:53:27 2003
+@@ -28,6 +28,8 @@
+ * Bignums are >= 0. *
+ * *
+ \***********************************************************************/
++#ifndef __BIGNUM_H__
++#define __BIGNUM_H__
+
+ #define LITTLENUM_NUMBER_OF_BITS (16)
+ #define LITTLENUM_RADIX (1 << LITTLENUM_NUMBER_OF_BITS)
+@@ -44,3 +46,4 @@
+ /* JF truncated this to get around a problem with GCC */
+ #define LOG_TO_BASE_2_OF_10 (3.3219280948873623478703194294893901758651)
+ /* WARNING: I haven't checked that the trailing digits are correct! */
++#endif
+diff -bur ./expr.h /home/megacz/xwt/upstream/darwin-linker/src/cctools/as/expr.h
+--- as/expr.h Fri Sep 6 18:27:10 2002
++++ as/expr.h Sat Sep 6 23:49:28 2003
+@@ -19,9 +19,9 @@
+ along with GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+-#import "struc-symbol.h"
+-#import "bignum.h"
+-#import "flonum.h"
++#include "struc-symbol.h"
++#include "bignum.h"
++#include "flonum.h"
+
+ /*
+ * This table describes the use of segments as EXPRESSION types.
+diff -bur ./flonum.h /home/megacz/xwt/upstream/darwin-linker/src/cctools/as/flonum.h
+--- as/flonum.h Fri Sep 6 18:27:10 2002
++++ as/flonum.h Sat Sep 6 23:49:28 2003
+@@ -32,7 +32,7 @@
+ * *
+ \***********************************************************************/
+
+-#import "bignum.h"
++#include "bignum.h"
+
+ /***********************************************************************\
+ * *
+diff -bur ./frags.h /home/megacz/xwt/upstream/darwin-linker/src/cctools/as/frags.h
+--- as/frags.h Tue Jan 14 23:35:18 2003
++++ as/frags.h Sat Sep 6 23:49:28 2003
+@@ -19,8 +19,8 @@
+ along with GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+-#import "relax.h"
+-#import "struc-symbol.h"
++#include "relax.h"
++#include "struc-symbol.h"
+
+ /*
+ * A code fragment (frag) is some known number of chars, followed by some
+diff -bur ./md.h /home/megacz/xwt/upstream/darwin-linker/src/cctools/as/md.h
+--- as/md.h Tue Apr 30 00:37:17 2002
++++ as/md.h Sat Sep 6 23:49:29 2003
+@@ -19,13 +19,13 @@
+ in a file named COPYING. Among other things, the copyright
+ notice and this notice must be preserved on all copies. */
+
+-#import <mach/machine.h>
+-#import "stuff/bytesex.h"
+-#import "frags.h"
+-#import "relax.h"
+-#import "struc-symbol.h"
+-#import "fixes.h"
+-#import "read.h"
++#include <mach/machine.h>
++#include "stuff/bytesex.h"
++#include "frags.h"
++#include "relax.h"
++#include "struc-symbol.h"
++#include "fixes.h"
++#include "read.h"
+
+ /* These are the default cputype and cpusubtype for this target MACHINE */
+ extern const cpu_type_t md_cputype;
+diff -bur ./read.h /home/megacz/xwt/upstream/darwin-linker/src/cctools/as/read.h
+--- as/read.h Fri Sep 6 18:27:13 2002
++++ as/read.h Sat Sep 6 23:49:29 2003
+@@ -19,7 +19,7 @@
+ along with GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+-#import "expr.h"
++#include "expr.h"
+
+ #define PERMIT_WHITESPACE /* Define to make whitespace be allowed in */
+ /* many syntactically unnecessary places. */
+diff -bur ./relax.h /home/megacz/xwt/upstream/darwin-linker/src/cctools/as/relax.h
+--- as/relax.h Tue Apr 30 00:37:17 2002
++++ as/relax.h Sat Sep 6 23:53:35 2003
+@@ -1,3 +1,5 @@
++#ifndef __RELAX_H__
++#define __RELAX_H__
+ /* The type used for a target address */
+ typedef unsigned long relax_addressT;
+
+@@ -42,3 +44,4 @@
+ relax_substateT rlx_more; /* Next longer relax-state. */
+ /* 0 means there is no 'next' relax-state. */
+ } relax_typeS;
++#endif
+diff -bur ./sections.h /home/megacz/xwt/upstream/darwin-linker/src/cctools/as/sections.h
+--- as/sections.h Tue Apr 30 00:37:17 2002
++++ as/sections.h Sat Sep 6 23:49:29 2003
+@@ -17,8 +17,8 @@
+ along with GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+-#import <mach-o/loader.h>
+-#import "struc-symbol.h"
++#include <mach-o/loader.h>
++#include "struc-symbol.h"
+
+ /*
+ * For every section the user mentions in the assembley program, we make one
+diff -bur ./struc-symbol.h /home/megacz/xwt/upstream/darwin-linker/src/cctools/as/struc-symbol.h
+--- as/struc-symbol.h Fri Sep 6 18:27:14 2002
++++ as/struc-symbol.h Sat Sep 6 23:49:29 2003
+@@ -20,7 +20,7 @@
+ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+ #ifdef NeXT_MOD
+-#import <mach-o/nlist.h>
++#include <mach-o/nlist.h>
+ #else /* !defined(NeXT_MOD) */
+ #ifndef VMS
+ #include "a.out.h" /* Needed to define struct nlist. Sigh. */
+diff -bur ./symbols.h /home/megacz/xwt/upstream/darwin-linker/src/cctools/as/symbols.h
+--- as/symbols.h Tue Apr 30 00:37:17 2002
++++ as/symbols.h Sat Sep 6 23:49:29 2003
+@@ -17,8 +17,8 @@
+ along with GAS; see the file COPYING. If not, write to
+ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+-#import "struc-symbol.h"
+-#import "hash.h"
++#include "struc-symbol.h"
++#include "hash.h"
+
+ extern struct hash_control *sy_hash;
+ extern struct obstack notes;
+--- as/make.h Sun Sep 7 00:01:26 2003
++++ as/make.h Sat Sep 6 23:55:11 2003
+@@ -0,0 +1,161 @@
++#ifndef _make_user_
++#define _make_user_
++
++/* Module make */
++
++#include <string.h>
++#include <mach/ndr.h>
++#include <mach/boolean.h>
++#include <mach/kern_return.h>
++#include <mach/notify.h>
++#include <mach/mach_types.h>
++#include <mach/message.h>
++#include <mach/mig_errors.h>
++#include <mach/port.h>
++
++#ifdef AUTOTEST
++#ifndef FUNCTION_PTR_T
++#define FUNCTION_PTR_T
++typedef void (*function_ptr_t)(mach_port_t, char *, mach_msg_type_number_t);
++typedef struct {
++ char *name;
++ function_ptr_t function;
++} function_table_entry;
++typedef function_table_entry *function_table_t;
++#endif /* FUNCTION_PTR_T */
++#endif /* AUTOTEST */
++
++#ifndef make_MSG_COUNT
++#define make_MSG_COUNT 2
++#endif /* make_MSG_COUNT */
++
++#include <mach/std_types.h>
++#include <mach/mig.h>
++#include "make_defs.h"
++
++#ifdef __BeforeMigUserHeader
++__BeforeMigUserHeader
++#endif /* __BeforeMigUserHeader */
++
++
++/* SimpleRoutine alert_old */
++#ifdef mig_external
++mig_external
++#else
++extern
++#endif /* mig_external */
++kern_return_t make_alert_old
++(
++ mach_port_t makePort,
++ int eventType,
++ make_string_t functionName,
++ mach_msg_type_number_t functionNameCnt,
++ make_string_t fileName,
++ mach_msg_type_number_t fileNameCnt,
++ int line,
++ make_string_t message,
++ mach_msg_type_number_t messageCnt
++);
++
++/* SimpleRoutine alert */
++#ifdef mig_external
++mig_external
++#else
++extern
++#endif /* mig_external */
++kern_return_t make_alert
++(
++ mach_port_t makePort,
++ int eventType,
++ make_string_t functionName,
++ mach_msg_type_number_t functionNameCnt,
++ make_string_t fileName,
++ mach_msg_type_number_t fileNameCnt,
++ make_string_t directory,
++ mach_msg_type_number_t directoryCnt,
++ int line,
++ make_string_t message,
++ mach_msg_type_number_t messageCnt
++);
++/* typedefs for all requests */
++
++#ifndef __Request__make_subsystem__defined
++#define __Request__make_subsystem__defined
++ typedef struct {
++ mach_msg_header_t Head;
++ NDR_record_t NDR;
++ int eventType;
++ mach_msg_type_number_t functionNameCnt;
++ char functionName[1024];
++ mach_msg_type_number_t fileNameCnt;
++ char fileName[1024];
++ int line;
++ mach_msg_type_number_t messageCnt;
++ char message[1024];
++ } __Request__alert_old_t;
++
++ typedef struct {
++ mach_msg_header_t Head;
++ NDR_record_t NDR;
++ int eventType;
++ mach_msg_type_number_t functionNameCnt;
++ char functionName[1024];
++ mach_msg_type_number_t fileNameCnt;
++ char fileName[1024];
++ mach_msg_type_number_t directoryCnt;
++ char directory[1024];
++ int line;
++ mach_msg_type_number_t messageCnt;
++ char message[1024];
++ } __Request__alert_t;
++
++#endif /* !__Request__make_subsystem__defined */
++
++/* union of all requests */
++
++#ifndef __RequestUnion__make_make_subsystem__defined
++#define __RequestUnion__make_make_subsystem__defined
++union __RequestUnion__make_make_subsystem {
++ __Request__alert_old_t Request_make_alert_old;
++ __Request__alert_t Request_make_alert;
++};
++#endif /* !__RequestUnion__make_make_subsystem__defined */
++/* typedefs for all replies */
++
++#ifndef __Reply__make_subsystem__defined
++#define __Reply__make_subsystem__defined
++ typedef struct {
++ mach_msg_header_t Head;
++ NDR_record_t NDR;
++ kern_return_t RetCode;
++ } __Reply__alert_old_t;
++
++ typedef struct {
++ mach_msg_header_t Head;
++ NDR_record_t NDR;
++ kern_return_t RetCode;
++ } __Reply__alert_t;
++
++#endif /* !__Reply__make_subsystem__defined */
++
++/* union of all replies */
++
++#ifndef __ReplyUnion__make_make_subsystem__defined
++#define __ReplyUnion__make_make_subsystem__defined
++union __ReplyUnion__make_make_subsystem {
++ __Reply__alert_old_t Reply_make_alert_old;
++ __Reply__alert_t Reply_make_alert;
++};
++#endif /* !__RequestUnion__make_make_subsystem__defined */
++
++#ifndef subsystem_to_name_map_make
++#define subsystem_to_name_map_make \
++ { "alert_old", 100 },\
++ { "alert", 101 }
++#endif
++
++#ifdef __AfterMigUserHeader
++__AfterMigUserHeader
++#endif /* __AfterMigUserHeader */
++
++#endif /* _make_user_ */
+--- as/makeUser.c Sun Sep 7 00:01:26 2003
++++ as/makeUser.c Sat Sep 6 23:55:11 2003
+@@ -0,0 +1,305 @@
++/*
++ * IDENTIFICATION:
++ * stub generated Sat Sep 6 23:50:34 2003
++ * with a MiG generated Tue Nov 5 01:17:50 PST 2002 by root@brixen
++ * OPTIONS:
++ */
++#include "make.h"
++
++
++#ifndef mig_internal
++#define mig_internal static
++#endif /* mig_internal */
++
++#ifndef mig_external
++#define mig_external
++#endif /* mig_external */
++
++#ifndef TypeCheck
++#define TypeCheck 0
++#endif /* TypeCheck */
++
++#ifndef LimitCheck
++#define LimitCheck 0
++#endif /* LimitCheck */
++
++#ifndef min
++#define min(a,b) ( ((a) < (b))? (a): (b) )
++#endif /* min */
++
++#ifndef UseStaticTemplates
++#define UseStaticTemplates 0
++#endif /* UseStaticTemplates */
++
++#define _WALIGN_(x) (((x) + 3) & ~3)
++#define _WALIGNSZ_(x) _WALIGN_(sizeof(x))
++#ifndef __MachMsgErrorWithTimeout
++#define __MachMsgErrorWithTimeout(_R_) { \
++ switch (_R_) { \
++ case MACH_SEND_INVALID_REPLY: \
++ case MACH_RCV_INVALID_NAME: \
++ case MACH_RCV_PORT_DIED: \
++ case MACH_RCV_PORT_CHANGED: \
++ case MACH_RCV_TIMED_OUT: \
++ mig_dealloc_reply_port(InP->Head.msgh_reply_port); \
++ break; \
++ default: \
++ mig_put_reply_port(InP->Head.msgh_reply_port); \
++ } \
++}
++#endif /* __MachMsgErrorWithTimeout */
++
++#ifndef __MachMsgErrorWithoutTimeout
++#define __MachMsgErrorWithoutTimeout(_R_) { \
++ switch (_R_) { \
++ case MACH_SEND_INVALID_REPLY: \
++ case MACH_RCV_INVALID_NAME: \
++ case MACH_RCV_PORT_DIED: \
++ case MACH_RCV_PORT_CHANGED: \
++ mig_dealloc_reply_port(InP->Head.msgh_reply_port); \
++ break; \
++ default: \
++ mig_put_reply_port(InP->Head.msgh_reply_port); \
++ } \
++}
++#endif /* __MachMsgErrorWithoutTimeout */
++
++#ifndef __DeclareSendRpc
++#define __DeclareSendRpc(_NUM_, _NAME_)
++#endif /* __DeclareSendRpc */
++
++#ifndef __BeforeSendRpc
++#define __BeforeSendRpc(_NUM_, _NAME_)
++#endif /* __BeforeSendRpc */
++
++#ifndef __AfterSendRpc
++#define __AfterSendRpc(_NUM_, _NAME_)
++#endif /* __AfterSendRpc */
++
++#ifndef __DeclareSendSimple
++#define __DeclareSendSimple(_NUM_, _NAME_)
++#endif /* __DeclareSendSimple */
++
++#ifndef __BeforeSendSimple
++#define __BeforeSendSimple(_NUM_, _NAME_)
++#endif /* __BeforeSendSimple */
++
++#ifndef __AfterSendSimple
++#define __AfterSendSimple(_NUM_, _NAME_)
++#endif /* __AfterSendSimple */
++
++#define msgh_request_port msgh_remote_port
++#define msgh_reply_port msgh_local_port
++
++
++
++/* SimpleRoutine alert_old */
++mig_external kern_return_t make_alert_old
++(
++ mach_port_t makePort,
++ int eventType,
++ make_string_t functionName,
++ mach_msg_type_number_t functionNameCnt,
++ make_string_t fileName,
++ mach_msg_type_number_t fileNameCnt,
++ int line,
++ make_string_t message,
++ mach_msg_type_number_t messageCnt
++)
++{
++ {
++ typedef struct {
++ mach_msg_header_t Head;
++ NDR_record_t NDR;
++ int eventType;
++ mach_msg_type_number_t functionNameCnt;
++ char functionName[1024];
++ mach_msg_type_number_t fileNameCnt;
++ char fileName[1024];
++ int line;
++ mach_msg_type_number_t messageCnt;
++ char message[1024];
++ } Request;
++
++ /*
++ * typedef struct {
++ * mach_msg_header_t Head;
++ * NDR_record_t NDR;
++ * kern_return_t RetCode;
++ * } mig_reply_error_t;
++ */
++
++ union {
++ Request In;
++ } Mess;
++
++ register Request *InP = &Mess.In;
++
++ mach_msg_return_t msg_result;
++ unsigned int msgh_size;
++ unsigned int msgh_size_delta;
++ __DeclareSendSimple(100, "alert_old")
++
++ InP->NDR = NDR_record;
++
++ InP->eventType = eventType;
++
++ if (functionNameCnt > 1024) {
++ { return MIG_ARRAY_TOO_LARGE; }
++ }
++ (void)memcpy((char *) InP->functionName, (const char *) functionName, functionNameCnt);
++
++ InP->functionNameCnt = functionNameCnt;
++
++ msgh_size_delta = _WALIGN_(functionNameCnt);
++ msgh_size = (sizeof(Request) - 3072) + msgh_size_delta;
++ InP = (Request *) ((pointer_t) InP + msgh_size_delta - 1024);
++
++ if (fileNameCnt > 1024) {
++ { return MIG_ARRAY_TOO_LARGE; }
++ }
++ (void)memcpy((char *) InP->fileName, (const char *) fileName, fileNameCnt);
++
++ InP->fileNameCnt = fileNameCnt;
++
++ msgh_size_delta = _WALIGN_(fileNameCnt);
++ msgh_size += msgh_size_delta;
++ InP = (Request *) ((pointer_t) InP + msgh_size_delta - 1024);
++
++ InP->line = line;
++
++ if (messageCnt > 1024) {
++ { return MIG_ARRAY_TOO_LARGE; }
++ }
++ (void)memcpy((char *) InP->message, (const char *) message, messageCnt);
++
++ InP->messageCnt = messageCnt;
++
++ msgh_size += _WALIGN_(messageCnt);
++ InP = &Mess.In;
++ InP->Head.msgh_bits =
++ MACH_MSGH_BITS(19, 0);
++ /* msgh_size passed as argument */
++ InP->Head.msgh_request_port = makePort;
++ InP->Head.msgh_reply_port = MACH_PORT_NULL;
++ InP->Head.msgh_id = 100;
++
++ __BeforeSendSimple(100, "alert_old")
++ msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_MSG_OPTION_NONE, msgh_size, 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
++ __AfterSendSimple(100, "alert_old")
++ return msg_result;
++ }
++}
++
++/* SimpleRoutine alert */
++mig_external kern_return_t make_alert
++(
++ mach_port_t makePort,
++ int eventType,
++ make_string_t functionName,
++ mach_msg_type_number_t functionNameCnt,
++ make_string_t fileName,
++ mach_msg_type_number_t fileNameCnt,
++ make_string_t directory,
++ mach_msg_type_number_t directoryCnt,
++ int line,
++ make_string_t message,
++ mach_msg_type_number_t messageCnt
++)
++{
++ {
++ typedef struct {
++ mach_msg_header_t Head;
++ NDR_record_t NDR;
++ int eventType;
++ mach_msg_type_number_t functionNameCnt;
++ char functionName[1024];
++ mach_msg_type_number_t fileNameCnt;
++ char fileName[1024];
++ mach_msg_type_number_t directoryCnt;
++ char directory[1024];
++ int line;
++ mach_msg_type_number_t messageCnt;
++ char message[1024];
++ } Request;
++
++ /*
++ * typedef struct {
++ * mach_msg_header_t Head;
++ * NDR_record_t NDR;
++ * kern_return_t RetCode;
++ * } mig_reply_error_t;
++ */
++
++ union {
++ Request In;
++ } Mess;
++
++ register Request *InP = &Mess.In;
++
++ mach_msg_return_t msg_result;
++ unsigned int msgh_size;
++ unsigned int msgh_size_delta;
++ __DeclareSendSimple(101, "alert")
++
++ InP->NDR = NDR_record;
++
++ InP->eventType = eventType;
++
++ if (functionNameCnt > 1024) {
++ { return MIG_ARRAY_TOO_LARGE; }
++ }
++ (void)memcpy((char *) InP->functionName, (const char *) functionName, functionNameCnt);
++
++ InP->functionNameCnt = functionNameCnt;
++
++ msgh_size_delta = _WALIGN_(functionNameCnt);
++ msgh_size = (sizeof(Request) - 4096) + msgh_size_delta;
++ InP = (Request *) ((pointer_t) InP + msgh_size_delta - 1024);
++
++ if (fileNameCnt > 1024) {
++ { return MIG_ARRAY_TOO_LARGE; }
++ }
++ (void)memcpy((char *) InP->fileName, (const char *) fileName, fileNameCnt);
++
++ InP->fileNameCnt = fileNameCnt;
++
++ msgh_size_delta = _WALIGN_(fileNameCnt);
++ msgh_size += msgh_size_delta;
++ InP = (Request *) ((pointer_t) InP + msgh_size_delta - 1024);
++
++ if (directoryCnt > 1024) {
++ { return MIG_ARRAY_TOO_LARGE; }
++ }
++ (void)memcpy((char *) InP->directory, (const char *) directory, directoryCnt);
++
++ InP->directoryCnt = directoryCnt;
++
++ msgh_size_delta = _WALIGN_(directoryCnt);
++ msgh_size += msgh_size_delta;
++ InP = (Request *) ((pointer_t) InP + msgh_size_delta - 1024);
++
++ InP->line = line;
++
++ if (messageCnt > 1024) {
++ { return MIG_ARRAY_TOO_LARGE; }
++ }
++ (void)memcpy((char *) InP->message, (const char *) message, messageCnt);
++
++ InP->messageCnt = messageCnt;
++
++ msgh_size += _WALIGN_(messageCnt);
++ InP = &Mess.In;
++ InP->Head.msgh_bits =
++ MACH_MSGH_BITS(19, 0);
++ /* msgh_size passed as argument */
++ InP->Head.msgh_request_port = makePort;
++ InP->Head.msgh_reply_port = MACH_PORT_NULL;
++ InP->Head.msgh_id = 101;
++
++ __BeforeSendSimple(101, "alert")
++ msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_MSG_OPTION_NONE, msgh_size, 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
++ __AfterSendSimple(101, "alert")
++ return msg_result;
++ }
++}
+--- ar/contents.c 30 Apr 2002 07:37:17 -0000 1.1.1.1
++++ ar/contents.c 7 Sep 2003 08:55:11 -0000
+@@ -76,7 +76,6 @@
+ #include <fcntl.h>
+ #include <stdio.h>
+ #include <string.h>
+-#include <tzfile.h>
+ #include <unistd.h>
+
+ #include "archive.h"
+@@ -103,12 +102,14 @@
+ else if (!(file = files(argv)))
+ goto next;
+ if (options & AR_V) {
++/*
+ (void)strmode(chdr.mode, buf);
+ (void)printf("%s %6d/%-6d %8qd ",
+ buf + 1, chdr.uid, chdr.gid, chdr.size);
+ tp = localtime(&chdr.date);
+ (void)strftime(buf, sizeof(buf), "%b %e %H:%M %Y", tp);
+ (void)printf("%s %s\n", buf, file);
++*/
+ } else
+ (void)printf("%s\n", file);
+ if (!all && !*argv)
+--- ar/misc.c 30 Apr 2002 07:37:17 -0000 1.1.1.1
++++ ar/misc.c 7 Sep 2003 08:55:11 -0000
+@@ -68,6 +68,7 @@
+ #endif /* not lint */
+
+ #include <sys/param.h>
++#define EFTYPE 79 /* Inappropriate file type or format */
+
+ #include <dirent.h>
+ #include <err.h>
+--- ar/vers_string Sun Sep 7 01:55:10 2003
++++ ar/vers_string Sun Sep 7 01:53:23 2003
+@@ -0,0 +1,125 @@
++#!/bin/sh
++##
++# Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
++#
++# @APPLE_LICENSE_HEADER_START@
++#
++# "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
++# Reserved. This file contains Original Code and/or Modifications of
++# Original Code as defined in and that are subject to the Apple Public
++# Source License Version 1.0 (the 'License'). You may not use this file
++# except in compliance with the License. Please obtain a copy of the
++# License at http://www.apple.com/publicsource and read it before using
++# this file.
++#
++# The Original Code and all software distributed under the License are
++# distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
++# EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
++# INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
++# FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
++# License for the specific language governing rights and limitations
++# under the License."
++#
++# @APPLE_LICENSE_HEADER_END@
++##
++#
++# vers_string PROGRAM [STAMPED_NAME]
++#
++# Output a string suitable for use as a version identifier
++#
++
++##
++# Usage
++##
++
++program=$(basename $0);
++
++usage ()
++{
++ echo "Usage: ${program} [<options>] <program> [<stamped_name>]";
++ echo " <program>: ???";
++ echo " <stamped_name>: ???";
++ echo "Options: ???";
++}
++
++##
++# Handle command line
++##
++
++ Date=$(date);
++Format=''\''PROGRAM:'\''"${Program}"'\'' PROJECT:'\''"${Version}"'\'' DEVELOPER:'\''"${USER}"'\'' BUILT:'\''"${Date}"'\'''\''';
++
++if ! args=$(getopt cflBn $*); then usage; fi;
++set -- ${args};
++for option; do
++ case "${option}" in
++ -c)
++ Format=''\''#include <sys/cdefs.h>
++#ifndef __IDSTRING
++#define __IDSTRING(name,string) \
++ static const char name[] __attribute__((__unused__)) = string
++#endif
++__IDSTRING(SGS_VERS,"@(#)PROGRAM:'\''"${Program}"'\'' PROJECT:'\''"${Version}"'\'' DEVELOPER:'\''"${USER}"'\'' BUILT:'\''"${Date}"'\''\n");
++__IDSTRING(VERS_NUM,"'\''${Revision}'\''");'\''';
++ shift;
++ ;;
++ -f)
++ Format='"${Program}"'\''-'\''"${Revision}"';
++ shift;
++ ;;
++ -l)
++ Format=''\''#include <sys/cdefs.h>
++#ifndef __IDSTRING
++#define __IDSTRING(name,string) \
++ const char name[] __attribute__((__unused__)) = string
++#endif
++__IDSTRING(SGS_VERS,"@(#)LIBRARY:'\''"${Program}"'\'' PROJECT:'\''"${Version}"'\'' DEVELOPER:'\''"${USER}"'\'' BUILT:'\''"${Date}"'\''\n");'\''';
++ shift;
++ ;;
++ -B)
++ date="NO DATE SET (-B used)";
++ shift;
++ ;;
++ -n)
++ Format='"${Revision}"';
++ shift;
++ ;;
++ --)
++ shift;
++ break;
++ ;;
++ esac;
++done;
++
++Program=$1; if [ $# != 0 ]; then shift; fi;
++Version=$1; if [ $# != 0 ]; then shift; fi;
++
++if [ $# != 0 ]; then usage; fi;
++
++if [ -z "${Program}" ]; then Program="Unknown"; fi;
++
++if [ -n "${Version}" ]; then
++ if ! Revision=$(expr "${Version}" : '.*-\(.*\)'); then
++ echo "${program}: No hyphen in project root ${Version}" >&2
++ exit 1;
++ fi;
++else
++ CurrentDir=$(/bin/pwd);
++ Version=$(basename "${CurrentDir}");
++ while [ "${Version}" != "${CurrentDir}" ]; do
++ if Revision=$(expr "${Version}" : '.*-\(.*\)'); then break; fi;
++ CurrentDir=$(dirname "${CurrentDir}");
++ Version=$(basename "${CurrentDir}");
++ done;
++ if [ "${Version}" = "${CurrentDir}" ]; then
++ CurrentDir=$(/bin/pwd);
++ echo "${program}: No hyphen in project root ${CurrentDir}" >&2
++ echo "${program}: Could not determine version" >&2
++ Version="Unknown";
++ Revision="";
++ fi;
++fi;
++
++if [ -z "${USER}" ]; then USER=$(whoami); fi;
++
++echo "$(eval echo "${Format}")";
+--- ar/Makefile 7 Sep 2002 01:27:09 -0000 1.1.1.2
++++ ar/Makefile 7 Sep 2003 09:03:52 -0000
+@@ -2,12 +2,16 @@
+ ifeq "mwccppc" "$(notdir $(CC))"
+ CFLAGS = -g $(OFLAG) -I$(SRCROOT)/../include
+ else
+- CFLAGS = -g $(OFLAG) -Wall -Wno-precomp -I$(SRCROOT)/../include
++ ifeq "Linux" "$(shell uname)"
++ CFLAGS = -Wall $(X_CFLAGS) -D__LITTLE_ENDIAN__ -U__BIG_ENDIAN__ -D__ppc__ -I/usr/include -I../../macosx-include -I../include
++ else
++ CFLAGS = -g $(OFLAG) -Wall -Wno-precomp -I$(SRCROOT)/../include
++ endif
+ endif
+
+ LIBSTUFF = -L$(SYMROOT)/../libstuff -lstuff
+
+-USE_DEPENDENCY_FILE := $(shell if [ "$(notdir $(CC))" != "mwccppc" ]; then \
++USE_DEPENDENCY_FILE := $(shell if [ `uname` != "Linux" ] && [ "$(notdir $(CC))" != "mwccppc" ]; then \
+ echo YES ; else echo NO ; \
+ fi; )
+
+@@ -43,7 +47,8 @@
+ $(CC) $(CFLAGS) $(RC_CFLAGS) -o $(SYMROOT)/$@ $(OBJS) $(LIBSTUFF)
+
+ vers.c:
+- vers_string -c $(VERS_STRING_FLAGS) $(PRODUCT) > $(OFILE_DIR)/$@
++ chmod +x vers_string
++ ./vers_string -c $(VERS_STRING_FLAGS) $(PRODUCT) > $(OFILE_DIR)/$@
+
+ ifeq "NO" "$(USE_DEPENDENCY_FILE)"
+ .c.o:
+--- ld/fake-mach.c Sun Sep 7 14:13:57 2003
++++ ld/fake-mach.c Sun Sep 7 14:13:50 2003
+@@ -0,0 +1,163 @@
++/** fake-mach.c - A half baked implementation of mach kernel functions using the POSIX UNIX API.
++*
++* This was used to port Apple's Darwin linker (ld) to Linux. This allows Mac OS X applications to
++* be cross complied on Linux. */
++
++#include <stdlib.h>
++#include <assert.h>
++#include <sys/types.h>
++#include <sys/uio.h>
++#include <unistd.h>
++
++#include <errno.h>
++
++#include <sys/mman.h>
++
++// Mach include files for typedefs, return values, etc
++//~ #include <mach/mach.h>
++#include <mach/kern_return.h>
++#include <mach/vm_types.h>
++#include <mach/mach_types.h>
++#include <mach/message.h>
++#include <servers/bootstrap_defs.h>
++
++/** The port for the current task. Ignored in this implementation. */
++mach_port_t mach_task_self_ = 0;
++
++/** The bootstrap port. Ignored in this implementation. */
++mach_port_t bootstrap_port = 0;
++
++#include <mach/ppc/ndr_def.h>
++
++/** Maps the file descriptor into memory. Free the memory using vm_deallocate. Ignores findspace and offset. */
++kern_return_t map_fd( int fd, vm_offset_t offset, vm_offset_t *va, boolean_t findspace, vm_size_t size)
++{
++ void* space = NULL;
++ int bytes = 0;
++
++ assert( fd > 0 );
++ assert( offset == 0 );
++ //~ assert( *va == 0 );
++ assert( findspace == TRUE );
++
++ // Allocate memory
++ space = malloc( size );
++ assert( space != NULL );
++
++ // Read file into space
++ while(bytes < size) bytes += read( fd, ((char*)space) + bytes, size - bytes);
++ assert( bytes == size );
++
++ /*
++ space = mmap( (void*) offset, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0 );
++ // No permission: try to make it read only
++ if ( space == (void*) -1 && errno == EACCES )
++ {
++ space = mmap( (void*) offset, size, PROT_READ, MAP_SHARED, fd, 0 );
++ }
++ assert( space != NULL && space != (void*) -1 );
++ */
++
++ // Copy back the pointer
++ *va = (vm_offset_t) space;
++
++ // Return success
++ return KERN_SUCCESS;
++}
++
++/** Returns a string appropriate to the error argument given. */
++char* mach_error_string( int error_value )
++{
++ char *errorString = "Some fake mach error string.";
++
++ return errorString;
++}
++
++/** Returns the mach port for the current host. We fake it by returning zero. */
++mach_port_t mach_host_self( void )
++{
++ return 0;
++}
++
++/** Returns the mach port for the current task. We fake it by returning zero. */
++//~ mach_port_t mach_task_self( void )
++//~ {
++ //~ return 0;
++//~ }
++
++/**The function vm_allocate allocates a region of virtual memory, placing it in the specified task's address space. Anywhere must be true, as the memory will be allocated anywhere. */
++extern kern_return_t vm_allocate( mach_port_t target_task, vm_address_t *address, vm_size_t size, boolean_t anywhere )
++{
++ assert( anywhere == TRUE );
++
++ // Anonymous memory map
++ *address = (vm_address_t) mmap( NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE|MAP_ANON, 0, 0 );
++ //~ *address = (vm_address_t) malloc( size );
++ assert( address != (vm_address_t) NULL );
++
++ return KERN_SUCCESS;
++}
++
++/**vm_deallocate relinquishes access to a region of a task's address space, causing further access to that memory to fail. This memory must have been allocated with vm_allocate. size is ignored. */
++kern_return_t vm_deallocate( mach_port_t target_task, vm_address_t address, vm_size_t size )
++{
++ int ret = 0;
++
++ assert( address != (vm_address_t) NULL );
++
++ // Free the memory
++ ret = munmap( (void*) address, size );
++ assert( ret == 0 );
++
++ //~ free( (void*) address );
++
++ return KERN_SUCCESS;
++}
++
++/** The function mach_port_allocate_name creates a new right in the specified task, with a specified name for the new right. In this implementation it does nothing. */
++kern_return_t mach_port_allocate_name (mach_port_t task, mach_port_right_t right, mach_port_t name)
++{
++ return KERN_SUCCESS;
++}
++
++/** The function mach_port_deallocate releases a user reference for a right in task's IPC name space. In this implementation it does nothing. */
++kern_return_t mach_port_deallocate (mach_port_t task, mach_port_t name)
++{
++ return KERN_SUCCESS;
++}
++
++/** host_info returns information about the host. It is not implemented in this implementation. */
++kern_return_t host_info( host_t host, host_flavor_t flavor, host_info_t host_info_out, mach_msg_type_number_t *host_info_outCnt )
++{
++ assert( 0 );
++ return KERN_FAILURE;
++}
++
++/** vm_msync unimplemented: It does nothing. */
++kern_return_t vm_msync ( vm_map_t target_task, vm_address_t address, vm_size_t size, vm_sync_t sync_flags )
++{
++ //~ assert( address != (vm_address_t) NULL );
++ //~ int ret = 0;
++ //~ ret = msync( (void*) address, size, int flags);
++ //~ assert( 0 );
++ return KERN_SUCCESS;
++}
++
++/** bootstrap_look_up unimplemented. */
++kern_return_t bootstrap_look_up( mach_port_t bootstrap_port, name_t service_name, mach_port_t *service_port )
++{
++ assert( 0 );
++ return KERN_FAILURE;
++}
++
++/** mach_msg unimplemented. Send and/or receive a message. If the message operation
++ * is interrupted, and the user did not request an indication
++ * of that fact, then restart the appropriate parts of the
++ * operation silently (trap version does not restart).
++ */
++mach_msg_return_t mach_msg( mach_msg_header_t *msg, mach_msg_option_t option, mach_msg_size_t send_size,
++ mach_msg_size_t rcv_size, mach_port_name_t rcv_name, mach_msg_timeout_t timeout, mach_port_name_t notify)
++{
++ //~ assert( 0 );
++ return KERN_SUCCESS;
++}
+--- ar/archive.c 30 Apr 2002 07:37:17 -0000 1.1.1.1
++++ ar/archive.c 8 Sep 2003 01:51:24 -0000
+@@ -69,6 +69,7 @@
+
+ #include <sys/param.h>
+ #include <sys/stat.h>
++#include <stuff/ofile.h>
+
+ #include <ar.h>
+ #include <dirent.h>
+@@ -86,7 +87,7 @@
+ #include "extern.h"
+
+ typedef struct ar_hdr HDR;
+-static char hb[sizeof(HDR) + 1]; /* real header */
++static char hb[61]; /* real header */
+
+ int
+ open_archive(mode)
+@@ -262,30 +263,40 @@
+ */
+ lname = strlen(name);
+ if (options & AR_TR) {
++ char buf[16];
++ int i;
++ for(i=0; i<15; i++) buf[i] = ' ';
++ buf[15] = '\0';
+ if (lname > OLDARMAXNAME) {
+ (void)fflush(stdout);
+ warnx("warning: %s truncated to %.*s",
+ name, OLDARMAXNAME, name);
+ (void)fflush(stderr);
+ }
+- (void)sprintf(hb, HDR3, name, (long int)sb->st_mtimespec.tv_sec,
++ strncpy(buf, name, 15);
++ (void)sprintf(hb, HDR3, buf, (long int)sb->st_mtime,
+ (unsigned int)(u_short)sb->st_uid,
+ (unsigned int)(u_short)sb->st_gid,
+- sb->st_mode, sb->st_size, ARFMAG);
++ sb->st_mode, (long long)sb->st_size, ARFMAG);
+ lname = 0;
+- } else if (lname > sizeof(hdr->ar_name) || strchr(name, ' '))
++ } else if (lname > sizeof(hdr->ar_name) || strchr(name, ' ')) {
+ (void)sprintf(hb, HDR1, AR_EFMT1, (lname + 3) & ~3,
+- (long int)sb->st_mtimespec.tv_sec,
++ (long int)sb->st_mtime,
+ (unsigned int)(u_short)sb->st_uid,
+ (unsigned int)(u_short)sb->st_gid,
+- sb->st_mode, sb->st_size + ((lname + 3) & ~3),
++ sb->st_mode, (long long)(sb->st_size + ((lname + 3) & ~3)),
+ ARFMAG);
+- else {
++} else {
++ char buf[17];
++ int i;
++ for(i=0; i<16; i++) buf[i] = ' ';
++ buf[16] = '\0';
++ strncpy(buf, name, 16);
+ lname = 0;
+- (void)sprintf(hb, HDR2, name, (long int)sb->st_mtimespec.tv_sec,
++ (void)sprintf(hb, HDR2, buf, (long int)sb->st_mtime,
+ (unsigned int)(u_short)sb->st_uid,
+ (unsigned int)(u_short)sb->st_gid,
+- sb->st_mode, sb->st_size, ARFMAG);
++ sb->st_mode, (long long)sb->st_size, ARFMAG);
+ }
+ size = sb->st_size;
+ } else {
+--- misc/libtool.c Wed Apr 23 15:44:51 2003
++++ misc/libtool.c Sun Sep 7 18:58:16 2003
+@@ -2177,14 +2177,15 @@
+
+ strcpy(message_buf, message);
+ strcat(message_buf, arch_name);
+-
++ /*
+ make_alert(ProjectBuilder_port,
+ -1,
+- NULL, 0, /* functionName, not used by ProjectBuilder */
++ NULL, 0,
+ fileName, strlen(fileName)+1 > 1024 ? 1024 : strlen(fileName)+1,
+ NULL, 0,
+ 0,
+ message_buf, strlen(message_buf) + 1);
++*/
+ }
+
+ /*
--- /dev/null
+--- include/freetype/config/ftmodule.h Thu Jul 31 12:59:06 2003
++++ include/freetype/config/ftmodule.h Thu Jul 31 12:59:17 2003
+@@ -1,4 +1,5 @@
+ FT_USE_MODULE(autohint_module_class)
++/*
+ FT_USE_MODULE(cff_driver_class)
+ FT_USE_MODULE(t1cid_driver_class)
+ FT_USE_MODULE(pcf_driver_class)
+@@ -7,13 +8,15 @@
+ FT_USE_MODULE(psnames_module_class)
+ FT_USE_MODULE(pshinter_module_class)
+ FT_USE_MODULE(ft_raster1_renderer_class)
++*/
+ FT_USE_MODULE(sfnt_module_class)
+ FT_USE_MODULE(ft_smooth_renderer_class)
+ FT_USE_MODULE(ft_smooth_lcd_renderer_class)
+ FT_USE_MODULE(ft_smooth_lcdv_renderer_class)
+ FT_USE_MODULE(tt_driver_class)
++/*
+ FT_USE_MODULE(t1_driver_class)
+ FT_USE_MODULE(t42_driver_class)
+ FT_USE_MODULE(pfr_driver_class)
+ FT_USE_MODULE(winfnt_driver_class)
+-
++*/
--- /dev/null
+--- src/base/ftsystem.c.origf Mon Dec 29 05:45:54 2003
++++ src/base/ftsystem.c Mon Dec 29 05:46:08 2003
+@@ -32,7 +32,8 @@
+ #include FT_ERRORS_H
+ #include FT_TYPES_H
+
+-#include <stdio.h>
++#include <fcntl.h>
++#include <unistd.h>
+ #include <stdlib.h>
+
+
+@@ -151,7 +152,7 @@
+
+ /* We use the macro STREAM_FILE for convenience to extract the */
+ /* system-specific stream handle from a given FreeType stream object */
+-#define STREAM_FILE( stream ) ( (FILE*)stream->descriptor.pointer )
++#define STREAM_FD( stream ) ( (int)stream->descriptor.value )
+
+
+ /*************************************************************************/
+@@ -168,7 +169,7 @@
+ FT_CALLBACK_DEF( void )
+ ft_ansi_stream_close( FT_Stream stream )
+ {
+- fclose( STREAM_FILE( stream ) );
++ close(STREAM_FD(stream));
+
+ stream->descriptor.pointer = NULL;
+ stream->size = 0;
+@@ -202,14 +203,14 @@
+ unsigned char* buffer,
+ unsigned long count )
+ {
+- FILE* file;
++ int fd;
+
+
+- file = STREAM_FILE( stream );
++ fd = STREAM_FD( stream );
+
+- fseek( file, offset, SEEK_SET );
++ if(lseek( fd, offset, SEEK_SET ) < 0) return 0;
+
+- return (unsigned long)fread( buffer, 1, count, file );
++ return (unsigned long) read(fd,buffer,count);
+ }
+
+
+@@ -219,14 +220,14 @@
+ FT_Stream_Open( FT_Stream stream,
+ const char* filepathname )
+ {
+- FILE* file;
++ int fd,n;
+
+
+ if ( !stream )
+ return FT_Err_Invalid_Stream_Handle;
+
+- file = fopen( filepathname, "rb" );
+- if ( !file )
++ fd = open( filepathname, O_RDONLY);
++ if (fd < 0)
+ {
+ FT_ERROR(( "FT_Stream_Open:" ));
+ FT_ERROR(( " could not open `%s'\n", filepathname ));
+@@ -234,11 +235,11 @@
+ return FT_Err_Cannot_Open_Resource;
+ }
+
+- fseek( file, 0, SEEK_END );
+- stream->size = ftell( file );
+- fseek( file, 0, SEEK_SET );
++ n = lseek( fd, 0, SEEK_END );
++ stream-> size = n < 0 ? 0 : n;
++ lseek( fd, 0, SEEK_SET );
+
+- stream->descriptor.pointer = file;
++ stream->descriptor.value = fd;
+ stream->pathname.pointer = (char*)filepathname;
+ stream->pos = 0;
+
--- /dev/null
+diff -buNr boehm-gc/ChangeLog boehm-gc/ChangeLog
+--- boehm-gc/ChangeLog Tue May 13 17:08:56 2003
++++ boehm-gc/ChangeLog Sat Sep 13 02:10:15 2003
+@@ -1,69 +1,3 @@
+-2003-05-13 Release Manager
+-
+- * GCC 3.3 Released.
+-
+-2003-05-13 Release Manager
+-
+- * GCC 3.3 Released.
+-
+-2003-05-13 Release Manager
+-
+- * GCC 3.3 Released.
+-
+-2003-05-13 Release Manager
+-
+- * GCC 3.3 Released.
+-
+-2003-04-28 Mohan Embar <gnustuff@thisiscool.com>
+-
+- * configure.in: define GC_DLL under mingw if --enable-shared
+- * configure: rebuilt
+- * win32_threads.c: add #ifdef GC_DLL around DllMain
+-
+-2003-04-09 Tom Tromey <tromey@redhat.com>
+-
+- * include/private/gcconfig.h (LINUX_STACKBOTTOM): Define for
+- POWERPC.
+- (STACK_GRAN, HEURISTIC1): Don't define for POWERPC.
+-
+-2003-03-04 Hans Boehm <Hans.Boehm@hp.com>
+- * include/private/gcconfig.h (GC_data_start): declare when needed.
+- * include/private/gc_priv.h: Include gcconfig.h after ptr_t
+- declaration.
+-
+-2003-03-03 Hans Boehm <Hans.Boehm@hp.com>
+- * mark_rts.c (GC_cond_register_dynamic_libraries): add.
+- (GC_push_roots): explicitly mark free list headers, register
+- dynamic libraries only if !REGISTER_LIBRARIES_EARLY.
+- * alloc.c (GC_stopped_mark): Conditionally call
+- GC_cond_register_dynamic_libraries().
+- (GC_collect_a_little_inner, GC_try_to_collect_inner): Check GC_dont_gc.
+- * dyn_load.c (GC_register_main_static_data): define.
+- (GC_register_dyn_libraries (Linux /proc, Linux ELF versions)):
+- no longer skip main data. Register main data for static executable.
+- * misc.c (GC_REGISTER_MAIN_STATIC_DATA): define.
+- (GC_init_inner): Make main data registration conditional.
+- * include/private/gc_priv.h (GC_register_main_static_data): declare.
+- * include/private/gcconfig.h (REGISTER_LIBRARIES_EARLY): define
+- for LINUX.
+-
+-2003-02-20 Alexandre Oliva <aoliva@redhat.com>
+-
+- * configure.in: Propagate ORIGINAL_LD_FOR_MULTILIBS to
+- config.status.
+- * configure: Rebuilt.
+-
+-2003-02-11 Andreas Tobler <a.tobler@schweiz.ch>
+-
+- * include/private/gcconfig.h: undefine MPROTECT_VDB for MACOSX
+-
+-2003-01-27 Alexandre Oliva <aoliva@redhat.com>
+-
+- * configure.in (toolexecdir, toolexeclibdir): Set and AC_SUBST.
+- Remove USE_LIBDIR conditional.
+- * Makefile.am (toolexecdir, toolexeclibdir): Don't override.
+- * Makefile.in, configure: Rebuilt.
+-
+ 2002-12-31 Tom Tromey <tromey@redhat.com>
+
+ For PR libgcj/8933:
+diff -buNr boehm-gc/Makefile.am boehm-gc/Makefile.am
+--- boehm-gc/Makefile.am Mon Jan 27 17:44:52 2003
++++ boehm-gc/Makefile.am Sat Sep 13 02:10:15 2003
+@@ -16,22 +16,38 @@
+ MULTIDO = true
+ MULTICLEAN = true
+
++## Install a library built with a cross compiler in tooldir, not
++## libdir.
++if USE_LIBDIR
++toolexeclibdir = $(libdir)$(MULTISUBDIR)
++else
++toolexecdir = $(exec_prefix)/$(target_alias)
++toolexeclibdir = $(toolexecdir)/lib$(MULTISUBDIR)
++endif
++
+ noinst_LTLIBRARIES = libgcjgc.la libgcjgc_convenience.la
+
+ GC_SOURCES = allchblk.c alloc.c blacklst.c checksums.c dbg_mlc.c \
+ dyn_load.c finalize.c gc_dlopen.c gcj_mlc.c headers.c irix_threads.c \
+-linux_threads.c malloc.c mallocx.c mark.c mark_rts.c misc.c new_hblk.c \
++malloc.c mallocx.c mark.c mark_rts.c misc.c new_hblk.c \
+ obj_map.c os_dep.c pcr_interface.c ptr_chck.c real_malloc.c reclaim.c \
+ solaris_pthreads.c solaris_threads.c specific.c stubborn.c typd_mlc.c \
+-backgraph.c win32_threads.c
++backgraph.c win32_threads.c \
++pthread_support.c pthread_stop_world.c darwin_stop_world.c
+
+-EXTRA_GC_SOURCES = alpha_mach_dep.s \
+-mips_sgi_mach_dep.S mips_ultrix_mach_dep.s powerpc_macosx_mach_dep.s \
+-rs6000_mach_dep.s sparc_mach_dep.S sparc_netbsd_mach_dep.s \
+-sparc_sunos4_mach_dep.s ia64_save_regs_in_stack.s
++EXTRA_GC_SOURCES = alpha_mach_dep.S \
++ mips_sgi_mach_dep.S mips_ultrix_mach_dep.s powerpc_darwin_mach_dep.s \
++ rs6000_mach_dep.s sparc_mach_dep.S sparc_netbsd_mach_dep.s \
++ sparc_sunos4_mach_dep.s ia64_save_regs_in_stack.s
++
++if POWERPC_DARWIN
++asm_libgc_sources = powerpc_darwin_mach_dep.s
++else
++asm_libgc_sources =
++endif
+
+-libgcjgc_la_SOURCES = $(GC_SOURCES)
+-libgcjgc_convenience_la_SOURCES = $(GC_SOURCES)
++libgcjgc_la_SOURCES = $(GC_SOURCES) $(asm_libgc_sources)
++libgcjgc_convenience_la_SOURCES = $(GC_SOURCES) $(asm_libgc_sources)
+ EXTRA_libgcjgc_la_SOURCES = $(EXTRA_GC_SOURCES)
+ EXTRA_libgcjgc_convenience_la_SOURCES = $(EXTRA_GC_SOURCES)
+
+@@ -77,8 +93,6 @@
+ $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(MY_CFLAGS) $(GC_CFLAGS)
+ LINK = $(LIBTOOL) --mode=link $(CC) $(AM_CFLAGS) $(MY_CFLAGS) $(LDFLAGS) -o $@
+-
+-AM_CFLAGS = @GC_CFLAGS@
+
+ # Work around what appears to be a GNU make bug handling MAKEFLAGS
+ # values defined in terms of make variables, as is the case for CC and
+diff -buNr boehm-gc/Makefile.am~ boehm-gc/Makefile.am~
+--- boehm-gc/Makefile.am~ Wed Dec 31 16:00:00 1969
++++ boehm-gc/Makefile.am~ Sat Sep 13 02:10:15 2003
+@@ -0,0 +1,159 @@
++## Process this file with automake to produce Makefile.in.
++
++## FIXME: `make dist' in this directory will not currently work. Many
++## files that should be in the distribution are not mentioned in this
++## Makefile.am.
++
++AUTOMAKE_OPTIONS = cygnus
++
++SUBDIRS = include
++
++# Multilib support variables.
++MULTISRCTOP =
++MULTIBUILDTOP =
++MULTIDIRS =
++MULTISUBDIR =
++MULTIDO = true
++MULTICLEAN = true
++
++## Install a library built with a cross compiler in tooldir, not
++## libdir.
++if USE_LIBDIR
++toolexeclibdir = $(libdir)$(MULTISUBDIR)
++else
++toolexecdir = $(exec_prefix)/$(target_alias)
++toolexeclibdir = $(toolexecdir)/lib$(MULTISUBDIR)
++endif
++
++noinst_LTLIBRARIES = libgcjgc.la libgcjgc_convenience.la
++
++GC_SOURCES = allchblk.c alloc.c blacklst.c checksums.c dbg_mlc.c \
++dyn_load.c finalize.c gc_dlopen.c gcj_mlc.c headers.c irix_threads.c \
++linux_threads.c malloc.c mallocx.c mark.c mark_rts.c misc.c new_hblk.c \
++obj_map.c os_dep.c pcr_interface.c ptr_chck.c real_malloc.c reclaim.c \
++solaris_pthreads.c solaris_threads.c specific.c stubborn.c typd_mlc.c \
++backgraph.c win32_threads.c
++
++EXTRA_GC_SOURCES = alpha_mach_dep.s \
++mips_sgi_mach_dep.S mips_ultrix_mach_dep.s powerpc_macosx_mach_dep.s \
++rs6000_mach_dep.s sparc_mach_dep.S sparc_netbsd_mach_dep.s \
++sparc_sunos4_mach_dep.s ia64_save_regs_in_stack.s
++
++libgcjgc_la_SOURCES = $(GC_SOURCES)
++libgcjgc_convenience_la_SOURCES = $(GC_SOURCES)
++EXTRA_libgcjgc_la_SOURCES = $(EXTRA_GC_SOURCES)
++EXTRA_libgcjgc_convenience_la_SOURCES = $(EXTRA_GC_SOURCES)
++
++# Include THREADLIBS here to ensure that the correct versions of
++# linuxthread semaphore functions get linked:
++libgcjgc_la_LIBADD = @addobjs@ $(THREADLIBS)
++libgcjgc_la_DEPENDENCIES = @addobjs@
++libgcjgc_la_LDFLAGS = -version-info 1:1:0 -rpath $(toolexeclibdir)
++
++libgcjgc_convenience_la_LIBADD = @addobjs@
++libgcjgc_convenience_la_DEPENDENCIES = @addobjs@
++
++AM_CXXFLAGS = @GC_CFLAGS@
++AM_CFLAGS = @GC_CFLAGS@
++
++check_PROGRAMS = gctest
++# The following hack produces a warning from automake, but we need it in order
++# to build a file from a subdirectory. FIXME.
++test.o: tests/test.c
++ $(COMPILE) -c $(srcdir)/tests/test.c
++# Using $< in the above seems to fail with the HP/UX on Itanium make.
++
++gctest_OBJECTS = test.o
++gctest_LDADD = ./libgcjgc.la $(THREADLIBS) $(EXTRA_TEST_LIBS)
++gctest_LDFLAGS = -shared-libgcc
++TESTS_ENVIRONMENT = LD_LIBRARY_PATH=../../$(MULTIBUILDTOP)gcc
++TESTS = gctest
++
++## FIXME: relies on internal code generated by automake.
++all_objs = @addobjs@ $(libgcjgc_la_OBJECTS)
++$(all_objs) : include/private/gcconfig.h include/private/gc_priv.h \
++include/private/gc_hdrs.h include/gc.h include/gc_gcj.h include/gc_mark.h
++
++## FIXME: we shouldn't have to do this, but automake forces us to.
++.s.lo:
++## We use -Wp,-P to strip #line directives. Irix `as' chokes on
++## these.
++ $(LTCOMPILE) -Wp,-P -x assembler-with-cpp -c $<
++
++## We have our own definition of LTCOMPILE because we want to use our
++## CFLAGS, not those passed in from the top level make.
++LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) \
++ $(AM_CPPFLAGS) $(CPPFLAGS) \
++ $(AM_CFLAGS) $(MY_CFLAGS) $(GC_CFLAGS)
++LINK = $(LIBTOOL) --mode=link $(CC) $(AM_CFLAGS) $(MY_CFLAGS) $(LDFLAGS) -o $@
++
++AM_CFLAGS = @GC_CFLAGS@
++
++# Work around what appears to be a GNU make bug handling MAKEFLAGS
++# values defined in terms of make variables, as is the case for CC and
++# friends when we are called from the top level Makefile.
++AM_MAKEFLAGS = \
++ "AR_FLAGS=$(AR_FLAGS)" \
++ "CC_FOR_BUILD=$(CC_FOR_BUILD)" \
++ "CFLAGS=$(CFLAGS)" \
++ "CXXFLAGS=$(CXXFLAGS)" \
++ "CFLAGS_FOR_BUILD=$(CFLAGS_FOR_BUILD)" \
++ "CFLAGS_FOR_TARGET=$(CFLAGS_FOR_TARGET)" \
++ "INSTALL=$(INSTALL)" \
++ "INSTALL_DATA=$(INSTALL_DATA)" \
++ "INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \
++ "INSTALL_SCRIPT=$(INSTALL_SCRIPT)" \
++ "LDFLAGS=$(LDFLAGS)" \
++ "LIBCFLAGS=$(LIBCFLAGS)" \
++ "LIBCFLAGS_FOR_TARGET=$(LIBCFLAGS_FOR_TARGET)" \
++ "MAKE=$(MAKE)" \
++ "MAKEINFO=$(MAKEINFO) $(MAKEINFOFLAGS)" \
++ "PICFLAG=$(PICFLAG)" \
++ "PICFLAG_FOR_TARGET=$(PICFLAG_FOR_TARGET)" \
++ "SHELL=$(SHELL)" \
++ "EXPECT=$(EXPECT)" \
++ "RUNTEST=$(RUNTEST)" \
++ "RUNTESTFLAGS=$(RUNTESTFLAGS)" \
++ "exec_prefix=$(exec_prefix)" \
++ "infodir=$(infodir)" \
++ "libdir=$(libdir)" \
++ "prefix=$(prefix)" \
++ "tooldir=$(tooldir)" \
++ "AR=$(AR)" \
++ "AS=$(AS)" \
++ "CC=$(CC)" \
++ "CXX=$(CXX)" \
++ "LD=$(LD)" \
++ "LIBCFLAGS=$(LIBCFLAGS)" \
++ "NM=$(NM)" \
++ "PICFLAG=$(PICFLAG)" \
++ "RANLIB=$(RANLIB)" \
++ "DESTDIR=$(DESTDIR)"
++
++CONFIG_STATUS_DEPENDENCIES = $(srcdir)/configure.host
++
++# Multilib support.
++.PHONY: all-multi mostlyclean-multi clean-multi distclean-multi \
++ maintainer-clean-multi
++
++all-am: all-multi
++install-am: install-multi
++mostlyclean-am: mostlyclean-multi
++clean-am: clean-multi
++distclean-am: distclean-multi
++maintainer-clean-am: maintainer-clean-multi
++
++all-multi:
++ : $(MAKE) ; exec $(MULTIDO) $(AM_MAKEFLAGS) DO=all multi-do
++install-multi:
++ $(MULTIDO) $(AM_MAKEFLAGS) DO=install multi-do
++mostlyclean-multi:
++ $(MULTICLEAN) $(AM_MAKEFLAGS) DO=mostlyclean multi-clean
++clean-multi:
++ $(MULTICLEAN) $(AM_MAKEFLAGS) DO=clean multi-clean
++distclean-multi:
++ $(MULTICLEAN) $(AM_MAKEFLAGS) DO=distclean multi-clean
++maintainer-clean-multi:
++ $(MULTICLEAN) $(AM_MAKEFLAGS) DO=maintainer-clean multi-clean
++
++MAKEOVERRIDES=
+diff -buNr boehm-gc/Makefile.in boehm-gc/Makefile.in
+--- boehm-gc/Makefile.in Tue May 13 17:18:14 2003
++++ boehm-gc/Makefile.in Sat Sep 13 02:10:15 2003
+@@ -1,6 +1,8 @@
+-# Makefile.in generated automatically by automake 1.4 from Makefile.am
++# Makefile.in generated by automake 1.6.3 from Makefile.am.
++# @configure_input@
+
+-# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
++# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
++# Free Software Foundation, Inc.
+ # This Makefile.in is free software; the Free Software Foundation
+ # gives unlimited permission to copy and/or distribute it,
+ # with or without modifications, as long as this notice is preserved.
+@@ -10,7 +12,7 @@
+ # even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ # PARTICULAR PURPOSE.
+
+-
++@SET_MAKE@
+ SHELL = @SHELL@
+
+ srcdir = @srcdir@
+@@ -31,13 +33,9 @@
+ mandir = @mandir@
+ includedir = @includedir@
+ oldincludedir = /usr/include
+-
+-DESTDIR =
+-
+ pkgdatadir = $(datadir)/@PACKAGE@
+ pkglibdir = $(libdir)/@PACKAGE@
+ pkgincludedir = $(includedir)/@PACKAGE@
+-
+ top_builddir = .
+
+ ACLOCAL = @ACLOCAL@
+@@ -45,12 +43,16 @@
+ AUTOMAKE = @AUTOMAKE@
+ AUTOHEADER = @AUTOHEADER@
+
++am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+ INSTALL = @INSTALL@
+-INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
++INSTALL_PROGRAM = @INSTALL_PROGRAM@
+ INSTALL_DATA = @INSTALL_DATA@
++install_sh_DATA = $(install_sh) -c -m 644
++install_sh_PROGRAM = $(install_sh) -c
++install_sh_SCRIPT = $(install_sh) -c
+ INSTALL_SCRIPT = @INSTALL_SCRIPT@
++INSTALL_HEADER = $(INSTALL_DATA)
+ transform = @program_transform_name@
+-
+ NORMAL_INSTALL = :
+ PRE_INSTALL = :
+ POST_INSTALL = :
+@@ -63,38 +65,48 @@
+ host_triplet = @host@
+ target_alias = @target_alias@
+ target_triplet = @target@
++
++EXEEXT = @EXEEXT@
++OBJEXT = @OBJEXT@
++PATH_SEPARATOR = @PATH_SEPARATOR@
++AMTAR = @AMTAR@
+ AR = @AR@
+ AS = @AS@
++AWK = @AWK@
+ CC = @CC@
+ CPP = @CPP@
+ CXX = @CXX@
+ CXXCPP = @CXXCPP@
+ CXXINCLUDES = @CXXINCLUDES@
++DEPDIR = @DEPDIR@
+ DLLTOOL = @DLLTOOL@
+-EXEEXT = @EXEEXT@
++ECHO = @ECHO@
++EGREP = @EGREP@
+ EXTRA_TEST_LIBS = @EXTRA_TEST_LIBS@
++F77 = @F77@
+ GCJ = @GCJ@
+ GCJFLAGS = @GCJFLAGS@
+ GC_CFLAGS = @GC_CFLAGS@
+ INCLUDES = @INCLUDES@
++INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+ LIBTOOL = @LIBTOOL@
+ LN_S = @LN_S@
+ MAINT = @MAINT@
+-MAKEINFO = @MAKEINFO@
+ MY_CFLAGS = @MY_CFLAGS@
+ OBJDUMP = @OBJDUMP@
+-OBJEXT = @OBJEXT@
+ PACKAGE = @PACKAGE@
+ RANLIB = @RANLIB@
++RC = @RC@
+ STRIP = @STRIP@
+ THREADLIBS = @THREADLIBS@
+ VERSION = @VERSION@
+ addobjs = @addobjs@
++am__include = @am__include@
++am__quote = @am__quote@
+ gc_basedir = @gc_basedir@
++install_sh = @install_sh@
+ mkinstalldirs = @mkinstalldirs@
+ target_all = @target_all@
+-toolexecdir = @toolexecdir@
+-toolexeclibdir = @toolexeclibdir@
+
+ AUTOMAKE_OPTIONS = cygnus
+
+@@ -108,24 +120,32 @@
+ MULTIDO = true
+ MULTICLEAN = true
+
++@USE_LIBDIR_TRUE@toolexeclibdir = $(libdir)$(MULTISUBDIR)
++@USE_LIBDIR_FALSE@toolexeclibdir = $(toolexecdir)/lib$(MULTISUBDIR)
++@USE_LIBDIR_FALSE@toolexecdir = $(exec_prefix)/$(target_alias)
++
+ noinst_LTLIBRARIES = libgcjgc.la libgcjgc_convenience.la
+
+ GC_SOURCES = allchblk.c alloc.c blacklst.c checksums.c dbg_mlc.c \
+ dyn_load.c finalize.c gc_dlopen.c gcj_mlc.c headers.c irix_threads.c \
+-linux_threads.c malloc.c mallocx.c mark.c mark_rts.c misc.c new_hblk.c \
++malloc.c mallocx.c mark.c mark_rts.c misc.c new_hblk.c \
+ obj_map.c os_dep.c pcr_interface.c ptr_chck.c real_malloc.c reclaim.c \
+ solaris_pthreads.c solaris_threads.c specific.c stubborn.c typd_mlc.c \
+-backgraph.c win32_threads.c
++backgraph.c win32_threads.c \
++pthread_support.c pthread_stop_world.c darwin_stop_world.c
++
+
++EXTRA_GC_SOURCES = alpha_mach_dep.S \
++ mips_sgi_mach_dep.S mips_ultrix_mach_dep.s powerpc_darwin_mach_dep.s \
++ rs6000_mach_dep.s sparc_mach_dep.S sparc_netbsd_mach_dep.s \
++ sparc_sunos4_mach_dep.s ia64_save_regs_in_stack.s
+
+-EXTRA_GC_SOURCES = alpha_mach_dep.s \
+-mips_sgi_mach_dep.S mips_ultrix_mach_dep.s powerpc_macosx_mach_dep.s \
+-rs6000_mach_dep.s sparc_mach_dep.S sparc_netbsd_mach_dep.s \
+-sparc_sunos4_mach_dep.s ia64_save_regs_in_stack.s
+
++@POWERPC_DARWIN_TRUE@asm_libgc_sources = powerpc_darwin_mach_dep.s
++@POWERPC_DARWIN_FALSE@asm_libgc_sources =
+
+-libgcjgc_la_SOURCES = $(GC_SOURCES)
+-libgcjgc_convenience_la_SOURCES = $(GC_SOURCES)
++libgcjgc_la_SOURCES = $(GC_SOURCES) $(asm_libgc_sources)
++libgcjgc_convenience_la_SOURCES = $(GC_SOURCES) $(asm_libgc_sources)
+ EXTRA_libgcjgc_la_SOURCES = $(EXTRA_GC_SOURCES)
+ EXTRA_libgcjgc_convenience_la_SOURCES = $(EXTRA_GC_SOURCES)
+
+@@ -139,12 +159,11 @@
+ libgcjgc_convenience_la_DEPENDENCIES = @addobjs@
+
+ AM_CXXFLAGS = @GC_CFLAGS@
+-
+ AM_CFLAGS = @GC_CFLAGS@
+
+ check_PROGRAMS = gctest
+-# Using $< in the above seems to fail with the HP/UX on Itanium make.
+
++# Using $< in the above seems to fail with the HP/UX on Itanium make.
+ gctest_OBJECTS = test.o
+ gctest_LDADD = ./libgcjgc.la $(THREADLIBS) $(EXTRA_TEST_LIBS)
+ gctest_LDFLAGS = -shared-libgcc
+@@ -204,104 +223,127 @@
+ CONFIG_STATUS_DEPENDENCIES = $(srcdir)/configure.host
+
+ MAKEOVERRIDES =
++subdir = .
+ ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+ CONFIG_CLEAN_FILES =
+ LTLIBRARIES = $(noinst_LTLIBRARIES)
+
++am__objects_1 = allchblk.lo alloc.lo blacklst.lo checksums.lo dbg_mlc.lo \
++ dyn_load.lo finalize.lo gc_dlopen.lo gcj_mlc.lo headers.lo \
++ irix_threads.lo malloc.lo mallocx.lo mark.lo mark_rts.lo \
++ misc.lo new_hblk.lo obj_map.lo os_dep.lo pcr_interface.lo \
++ ptr_chck.lo real_malloc.lo reclaim.lo solaris_pthreads.lo \
++ solaris_threads.lo specific.lo stubborn.lo typd_mlc.lo \
++ backgraph.lo win32_threads.lo pthread_support.lo \
++ pthread_stop_world.lo darwin_stop_world.lo
++@POWERPC_DARWIN_TRUE@am__objects_2 = powerpc_darwin_mach_dep.lo
++@POWERPC_DARWIN_FALSE@am__objects_2 =
++am_libgcjgc_la_OBJECTS = $(am__objects_1) $(am__objects_2)
++libgcjgc_la_OBJECTS = $(am_libgcjgc_la_OBJECTS)
++libgcjgc_convenience_la_LDFLAGS =
++am_libgcjgc_convenience_la_OBJECTS = $(am__objects_1) $(am__objects_2)
++libgcjgc_convenience_la_OBJECTS = $(am_libgcjgc_convenience_la_OBJECTS)
++check_PROGRAMS = gctest$(EXEEXT)
++gctest_DEPENDENCIES = ./libgcjgc.la
+
+-DEFS = @DEFS@ -I. -I$(srcdir)
++DEFS = @DEFS@
++DEFAULT_INCLUDES = -I. -I$(srcdir)
+ CPPFLAGS = @CPPFLAGS@
+ LDFLAGS = @LDFLAGS@
+ LIBS = @LIBS@
+-libgcjgc_la_OBJECTS = allchblk.lo alloc.lo blacklst.lo checksums.lo \
+-dbg_mlc.lo dyn_load.lo finalize.lo gc_dlopen.lo gcj_mlc.lo headers.lo \
+-irix_threads.lo linux_threads.lo malloc.lo mallocx.lo mark.lo \
+-mark_rts.lo misc.lo new_hblk.lo obj_map.lo os_dep.lo pcr_interface.lo \
+-ptr_chck.lo real_malloc.lo reclaim.lo solaris_pthreads.lo \
+-solaris_threads.lo specific.lo stubborn.lo typd_mlc.lo backgraph.lo \
+-win32_threads.lo
+-libgcjgc_convenience_la_LDFLAGS =
+-libgcjgc_convenience_la_OBJECTS = allchblk.lo alloc.lo blacklst.lo \
+-checksums.lo dbg_mlc.lo dyn_load.lo finalize.lo gc_dlopen.lo gcj_mlc.lo \
+-headers.lo irix_threads.lo linux_threads.lo malloc.lo mallocx.lo \
+-mark.lo mark_rts.lo misc.lo new_hblk.lo obj_map.lo os_dep.lo \
+-pcr_interface.lo ptr_chck.lo real_malloc.lo reclaim.lo \
+-solaris_pthreads.lo solaris_threads.lo specific.lo stubborn.lo \
+-typd_mlc.lo backgraph.lo win32_threads.lo
+-check_PROGRAMS = gctest$(EXEEXT)
+-gctest_DEPENDENCIES = ./libgcjgc.la
+-CFLAGS = @CFLAGS@
+-COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
++depcomp =
++am__depfiles_maybe =
++CCASCOMPILE = $(CCAS) $(AM_CCASFLAGS) $(CCASFLAGS)
++LTCCASCOMPILE = $(LIBTOOL) --mode=compile $(CCAS) $(AM_CCASFLAGS) \
++ $(CCASFLAGS)
++CCASFLAGS =
++COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
++ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+ CCLD = $(CC)
+-DIST_COMMON = ChangeLog Makefile.am Makefile.in acinclude.m4 aclocal.m4 \
+-config.guess config.sub configure configure.in install-sh ltconfig \
+-ltmain.sh mkinstalldirs
+-
+-
+-DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+-
+-TAR = gtar
+-GZIP_ENV = --best
++CFLAGS = @CFLAGS@
++DIST_SOURCES = $(libgcjgc_la_SOURCES) $(EXTRA_libgcjgc_la_SOURCES) \
++ $(libgcjgc_convenience_la_SOURCES) \
++ $(EXTRA_libgcjgc_convenience_la_SOURCES)
++
++RECURSIVE_TARGETS = info-recursive dvi-recursive \
++ uninstall-info-recursive all-recursive install-data-recursive \
++ install-exec-recursive installdirs-recursive install-recursive \
++ uninstall-recursive check-recursive installcheck-recursive
+ SOURCES = $(libgcjgc_la_SOURCES) $(EXTRA_libgcjgc_la_SOURCES) $(libgcjgc_convenience_la_SOURCES) $(EXTRA_libgcjgc_convenience_la_SOURCES)
+-OBJECTS = $(libgcjgc_la_OBJECTS) $(libgcjgc_convenience_la_OBJECTS)
+
+-all: all-redirect
++all: all-recursive
++
+ .SUFFIXES:
+ .SUFFIXES: .S .c .lo .o .obj .s
+-$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+- cd $(top_srcdir) && $(AUTOMAKE) --cygnus Makefile
+
+-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+- cd $(top_builddir) \
+- && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
+-
+-$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ configure.in acinclude.m4
+- cd $(srcdir) && $(ACLOCAL)
++am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
++ configure.lineno
++$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
++ cd $(top_srcdir) && \
++ $(AUTOMAKE) --cygnus Makefile
++Makefile: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.in $(top_builddir)/config.status
++ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)
+
+-config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
++$(top_builddir)/config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ $(SHELL) ./config.status --recheck
+-$(srcdir)/configure: @MAINTAINER_MODE_TRUE@$(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
++$(srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
+ cd $(srcdir) && $(AUTOCONF)
+
+-mostlyclean-noinstLTLIBRARIES:
++$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ configure.in acinclude.m4
++ cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
+
+ clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
++ @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
++ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
++ test -z "$dir" && dir=.; \
++ echo "rm -f \"$${dir}/so_locations\""; \
++ rm -f "$${dir}/so_locations"; \
++ done
++libgcjgc.la: $(libgcjgc_la_OBJECTS) $(libgcjgc_la_DEPENDENCIES)
++ $(LINK) $(libgcjgc_la_LDFLAGS) $(libgcjgc_la_OBJECTS) $(libgcjgc_la_LIBADD) $(LIBS)
++libgcjgc_convenience.la: $(libgcjgc_convenience_la_OBJECTS) $(libgcjgc_convenience_la_DEPENDENCIES)
++ $(LINK) $(libgcjgc_convenience_la_LDFLAGS) $(libgcjgc_convenience_la_OBJECTS) $(libgcjgc_convenience_la_LIBADD) $(LIBS)
+
+-distclean-noinstLTLIBRARIES:
+-
+-maintainer-clean-noinstLTLIBRARIES:
+-
+-.c.o:
+- $(COMPILE) -c $<
++clean-checkPROGRAMS:
++ @list='$(check_PROGRAMS)'; for p in $$list; do \
++ f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
++ echo " rm -f $$p $$f"; \
++ rm -f $$p $$f ; \
++ done
++gctest$(EXEEXT): $(gctest_OBJECTS) $(gctest_DEPENDENCIES)
++ @rm -f gctest$(EXEEXT)
++ $(LINK) $(gctest_LDFLAGS) $(gctest_OBJECTS) $(gctest_LDADD) $(LIBS)
+
+-# FIXME: We should only use cygpath when building on Windows,
+-# and only if it is available.
+-.c.obj:
+- $(COMPILE) -c `cygpath -w $<`
++mostlyclean-compile:
++ -rm -f *.$(OBJEXT) core *.core
+
+-.s.o:
+- $(COMPILE) -c $<
++distclean-compile:
++ -rm -f *.tab.c
+
+ .S.o:
+- $(COMPILE) -c $<
++ $(CCASCOMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$<
+
+-mostlyclean-compile:
+- -rm -f *.o core *.core
+- -rm -f *.$(OBJEXT)
++.S.obj:
++ $(CCASCOMPILE) -c `cygpath -w $<`
+
+-clean-compile:
++.S.lo:
++ $(LTCCASCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
+
+-distclean-compile:
+- -rm -f *.tab.c
++.c.o:
++ $(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$<
+
+-maintainer-clean-compile:
++.c.obj:
++ $(COMPILE) -c `cygpath -w $<`
+
+ .c.lo:
+- $(LIBTOOL) --mode=compile $(COMPILE) -c $<
++ $(LTCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
+
+-.S.lo:
+- $(LIBTOOL) --mode=compile $(COMPILE) -c $<
++.s.o:
++ $(CCASCOMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$<
++
++.s.obj:
++ $(CCASCOMPILE) -c `cygpath -w $<`
+
+ mostlyclean-libtool:
+ -rm -f *.lo
+@@ -310,27 +352,8 @@
+ -rm -rf .libs _libs
+
+ distclean-libtool:
+-
+-maintainer-clean-libtool:
+-
+-libgcjgc.la: $(libgcjgc_la_OBJECTS) $(libgcjgc_la_DEPENDENCIES)
+- $(LINK) $(libgcjgc_la_LDFLAGS) $(libgcjgc_la_OBJECTS) $(libgcjgc_la_LIBADD) $(LIBS)
+-
+-libgcjgc_convenience.la: $(libgcjgc_convenience_la_OBJECTS) $(libgcjgc_convenience_la_DEPENDENCIES)
+- $(LINK) $(libgcjgc_convenience_la_LDFLAGS) $(libgcjgc_convenience_la_OBJECTS) $(libgcjgc_convenience_la_LIBADD) $(LIBS)
+-
+-mostlyclean-checkPROGRAMS:
+-
+-clean-checkPROGRAMS:
+- -test -z "$(check_PROGRAMS)" || rm -f $(check_PROGRAMS)
+-
+-distclean-checkPROGRAMS:
+-
+-maintainer-clean-checkPROGRAMS:
+-
+-gctest$(EXEEXT): $(gctest_OBJECTS) $(gctest_DEPENDENCIES)
+- @rm -f gctest$(EXEEXT)
+- $(LINK) $(gctest_LDFLAGS) $(gctest_OBJECTS) $(gctest_LDADD) $(LIBS)
++ -rm -f libtool
++uninstall-info-am:
+
+ # This directory's subdirectories are mostly independent; you can cd
+ # into them and run `make' without going through this Makefile.
+@@ -338,13 +361,8 @@
+ # (1) if the variable is set in `config.status', edit `config.status'
+ # (which will cause the Makefiles to be regenerated when you run `make');
+ # (2) otherwise, pass the desired values on the `make' command line.
+-
+-@SET_MAKE@
+-
+-all-recursive install-data-recursive install-exec-recursive \
+-installdirs-recursive install-recursive uninstall-recursive install-info-recursive \
+-check-recursive installcheck-recursive info-recursive dvi-recursive:
+- @set fnord $(MAKEFLAGS); amf=$$2; \
++$(RECURSIVE_TARGETS):
++ @set fnord $$MAKEFLAGS; amf=$$2; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+@@ -364,13 +382,18 @@
+
+ mostlyclean-recursive clean-recursive distclean-recursive \
+ maintainer-clean-recursive:
+- @set fnord $(MAKEFLAGS); amf=$$2; \
++ @set fnord $$MAKEFLAGS; amf=$$2; \
+ dot_seen=no; \
+- rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \
++ case "$@" in \
++ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
++ *) list='$(SUBDIRS)' ;; \
++ esac; \
++ rev=''; for subdir in $$list; do \
++ if test "$$subdir" = "."; then :; else \
+ rev="$$subdir $$rev"; \
+- test "$$subdir" = "." && dot_seen=yes; \
++ fi; \
+ done; \
+- test "$$dot_seen" = "no" && rev=". $$rev"; \
++ rev="$$rev ."; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+@@ -387,17 +410,22 @@
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+
++ETAGS = etags
++ETAGSFLAGS =
++
+ tags: TAGS
+
+-ID: $(HEADERS) $(SOURCES) $(LISP)
+- list='$(SOURCES) $(HEADERS)'; \
+- unique=`for i in $$list; do echo $$i; done | \
+- awk ' { files[$$0] = 1; } \
++ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
++ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
++ unique=`for i in $$list; do \
++ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
++ done | \
++ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+- here=`pwd` && cd $(srcdir) \
+- && mkid -f$$here/ID $$unique $(LISP)
++ mkid -fID $$unique
+
+-TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
++TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
++ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+@@ -405,193 +433,163 @@
+ test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+- list='$(SOURCES) $(HEADERS)'; \
+- unique=`for i in $$list; do echo $$i; done | \
+- awk ' { files[$$0] = 1; } \
++ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
++ unique=`for i in $$list; do \
++ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
++ done | \
++ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+- test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+- || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
+-
+-mostlyclean-tags:
+-
+-clean-tags:
++ test -z "$(ETAGS_ARGS)$$tags$$unique" \
++ || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
++ $$tags $$unique
++
++GTAGS:
++ here=`$(am__cd) $(top_builddir) && pwd` \
++ && cd $(top_srcdir) \
++ && gtags -i $(GTAGS_ARGS) $$here
+
+ distclean-tags:
+- -rm -f TAGS ID
++ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH
+
+-maintainer-clean-tags:
+-
+-distdir = $(PACKAGE)-$(VERSION)
+-top_distdir = $(distdir)
+-
+-# This target untars the dist file and tries a VPATH configuration. Then
+-# it guarantees that the distribution is self-contained by making another
+-# tarfile.
+-distcheck: dist
+- -rm -rf $(distdir)
+- GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz
+- mkdir $(distdir)/=build
+- mkdir $(distdir)/=inst
+- dc_install_base=`cd $(distdir)/=inst && pwd`; \
+- cd $(distdir)/=build \
+- && ../configure --srcdir=.. --prefix=$$dc_install_base \
+- && $(MAKE) $(AM_MAKEFLAGS) \
+- && $(MAKE) $(AM_MAKEFLAGS) dvi \
+- && $(MAKE) $(AM_MAKEFLAGS) check \
+- && $(MAKE) $(AM_MAKEFLAGS) install \
+- && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+- && $(MAKE) $(AM_MAKEFLAGS) dist
+- -rm -rf $(distdir)
+- @banner="$(distdir).tar.gz is ready for distribution"; \
+- dashes=`echo "$$banner" | sed s/./=/g`; \
+- echo "$$dashes"; \
+- echo "$$banner"; \
+- echo "$$dashes"
+-dist: distdir
+- -chmod -R a+r $(distdir)
+- GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
+- -rm -rf $(distdir)
+-dist-all: distdir
+- -chmod -R a+r $(distdir)
+- GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
+- -rm -rf $(distdir)
+-distdir: $(DISTFILES)
+- -rm -rf $(distdir)
+- mkdir $(distdir)
+- -chmod 777 $(distdir)
+- @for file in $(DISTFILES); do \
+- if test -f $$file; then d=.; else d=$(srcdir); fi; \
+- if test -d $$d/$$file; then \
+- cp -pr $$d/$$file $(distdir)/$$file; \
+- else \
+- test -f $(distdir)/$$file \
+- || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+- || cp -p $$d/$$file $(distdir)/$$file || :; \
+- fi; \
+- done
+- for subdir in $(SUBDIRS); do \
+- if test "$$subdir" = .; then :; else \
+- test -d $(distdir)/$$subdir \
+- || mkdir $(distdir)/$$subdir \
+- || exit 1; \
+- chmod 777 $(distdir)/$$subdir; \
+- (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(distdir) distdir=../$(distdir)/$$subdir distdir) \
+- || exit 1; \
+- fi; \
+- done
+ check-TESTS: $(TESTS)
+- @failed=0; all=0; \
++ @failed=0; all=0; xfail=0; xpass=0; \
+ srcdir=$(srcdir); export srcdir; \
+- for tst in $(TESTS); do \
+- if test -f $$tst; then dir=.; \
+- else dir="$(srcdir)"; fi; \
+- if $(TESTS_ENVIRONMENT) $$dir/$$tst; then \
++ list='$(TESTS)'; \
++ if test -n "$$list"; then \
++ for tst in $$list; do \
++ if test -f ./$$tst; then dir=./; \
++ elif test -f $$tst; then dir=; \
++ else dir="$(srcdir)/"; fi; \
++ if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \
+ all=`expr $$all + 1`; \
++ case " $(XFAIL_TESTS) " in \
++ *" $$tst "*) \
++ xpass=`expr $$xpass + 1`; \
++ failed=`expr $$failed + 1`; \
++ echo "XPASS: $$tst"; \
++ ;; \
++ *) \
+ echo "PASS: $$tst"; \
++ ;; \
++ esac; \
+ elif test $$? -ne 77; then \
+ all=`expr $$all + 1`; \
++ case " $(XFAIL_TESTS) " in \
++ *" $$tst "*) \
++ xfail=`expr $$xfail + 1`; \
++ echo "XFAIL: $$tst"; \
++ ;; \
++ *) \
+ failed=`expr $$failed + 1`; \
+ echo "FAIL: $$tst"; \
++ ;; \
++ esac; \
+ fi; \
+ done; \
+ if test "$$failed" -eq 0; then \
++ if test "$$xfail" -eq 0; then \
+ banner="All $$all tests passed"; \
+ else \
++ banner="All $$all tests behaved as expected ($$xfail expected failures)"; \
++ fi; \
++ else \
++ if test "$$xpass" -eq 0; then \
+ banner="$$failed of $$all tests failed"; \
++ else \
++ banner="$$failed of $$all tests did not behave as expected ($$xpass unexpected passes)"; \
++ fi; \
+ fi; \
+ dashes=`echo "$$banner" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ echo "$$dashes"; \
+- test "$$failed" -eq 0
+-info-am:
+-info: info-recursive
+-dvi-am:
+-dvi: dvi-recursive
++ test "$$failed" -eq 0; \
++ else :; fi
+ check-am: $(check_PROGRAMS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+ check: check-recursive
+-installcheck-am:
+-installcheck: installcheck-recursive
+-install-info-am:
+-install-info: install-info-recursive
+-install-exec-am:
+-install-exec: install-exec-recursive
+-
+-install-data-am:
+-install-data: install-data-recursive
+-
+-install-am: all-am
+- @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+-install: install-recursive
+-uninstall-am:
+-uninstall: uninstall-recursive
+ all-am: Makefile $(LTLIBRARIES)
+-all-redirect: all-recursive
+-install-strip:
+- $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+ installdirs: installdirs-recursive
+ installdirs-am:
+
++install: install-recursive
++install-exec: install-exec-recursive
++install-data: install-data-recursive
++uninstall: uninstall-recursive
+
++installcheck: installcheck-recursive
++install-strip:
++ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
++ INSTALL_STRIP_FLAG=-s \
++ `test -z '$(STRIP)' || \
++ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+ mostlyclean-generic:
+
+ clean-generic:
+
+ distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+- -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+ maintainer-clean-generic:
+-mostlyclean-am: mostlyclean-noinstLTLIBRARIES mostlyclean-compile \
+- mostlyclean-libtool mostlyclean-checkPROGRAMS \
+- mostlyclean-tags mostlyclean-generic
++ @echo "This command is intended for maintainers to use"
++ @echo "it deletes files that may require special tools to rebuild."
++clean: clean-recursive
+
+-mostlyclean: mostlyclean-recursive
++clean-am: clean-checkPROGRAMS clean-generic clean-libtool \
++ clean-noinstLTLIBRARIES mostlyclean-am
+
+-clean-am: clean-noinstLTLIBRARIES clean-compile clean-libtool \
+- clean-checkPROGRAMS clean-tags clean-generic \
+- mostlyclean-am
++distclean: distclean-recursive
++ -rm -f $(am__CONFIG_DISTCLEAN_FILES)
++distclean-am: clean-am distclean-compile distclean-generic \
++ distclean-libtool distclean-tags
+
+-clean: clean-recursive
++dvi: dvi-recursive
+
+-distclean-am: distclean-noinstLTLIBRARIES distclean-compile \
+- distclean-libtool distclean-checkPROGRAMS \
+- distclean-tags distclean-generic clean-am
+- -rm -f libtool
++dvi-am:
+
+-distclean: distclean-recursive
+- -rm -f config.status
++info: info-recursive
+
+-maintainer-clean-am: maintainer-clean-noinstLTLIBRARIES \
+- maintainer-clean-compile maintainer-clean-libtool \
+- maintainer-clean-checkPROGRAMS maintainer-clean-tags \
+- maintainer-clean-generic distclean-am
+- @echo "This command is intended for maintainers to use;"
+- @echo "it deletes files that may require special tools to rebuild."
++info-am:
++
++install-data-am:
++
++install-exec-am:
++
++install-info:
++
++install-man:
++
++installcheck-am:
+
+ maintainer-clean: maintainer-clean-recursive
+- -rm -f config.status
++ -rm -f $(am__CONFIG_DISTCLEAN_FILES)
++ -rm -rf autom4te.cache
++maintainer-clean-am: distclean-am maintainer-clean-generic
+
+-.PHONY: mostlyclean-noinstLTLIBRARIES distclean-noinstLTLIBRARIES \
+-clean-noinstLTLIBRARIES maintainer-clean-noinstLTLIBRARIES \
+-mostlyclean-compile distclean-compile clean-compile \
+-maintainer-clean-compile mostlyclean-libtool distclean-libtool \
+-clean-libtool maintainer-clean-libtool mostlyclean-checkPROGRAMS \
+-distclean-checkPROGRAMS clean-checkPROGRAMS \
+-maintainer-clean-checkPROGRAMS install-data-recursive \
+-uninstall-data-recursive install-exec-recursive \
+-uninstall-exec-recursive installdirs-recursive uninstalldirs-recursive \
+-all-recursive check-recursive installcheck-recursive info-recursive \
+-dvi-recursive mostlyclean-recursive distclean-recursive clean-recursive \
+-maintainer-clean-recursive tags tags-recursive mostlyclean-tags \
+-distclean-tags clean-tags maintainer-clean-tags distdir check-TESTS \
+-info-am info dvi-am dvi check check-am installcheck-am installcheck \
+-install-info-am install-info install-exec-am install-exec \
+-install-data-am install-data install-am install uninstall-am uninstall \
+-all-redirect all-am all installdirs-am installdirs mostlyclean-generic \
+-distclean-generic clean-generic maintainer-clean-generic clean \
+-mostlyclean distclean maintainer-clean
++mostlyclean: mostlyclean-recursive
++
++mostlyclean-am: mostlyclean-compile mostlyclean-generic \
++ mostlyclean-libtool
++
++uninstall-am:
++
++uninstall-info: uninstall-info-recursive
++
++.PHONY: $(RECURSIVE_TARGETS) GTAGS all all-am check check-TESTS check-am \
++ clean clean-checkPROGRAMS clean-generic clean-libtool \
++ clean-noinstLTLIBRARIES clean-recursive distclean \
++ distclean-compile distclean-generic distclean-libtool \
++ distclean-recursive distclean-tags dvi dvi-am dvi-recursive \
++ info info-am info-recursive install install-am install-data \
++ install-data-am install-data-recursive install-exec \
++ install-exec-am install-exec-recursive install-info \
++ install-info-am install-man install-recursive install-strip \
++ installcheck installcheck-am installdirs installdirs-am \
++ installdirs-recursive maintainer-clean maintainer-clean-generic \
++ maintainer-clean-recursive mostlyclean mostlyclean-compile \
++ mostlyclean-generic mostlyclean-libtool mostlyclean-recursive \
++ tags tags-recursive uninstall uninstall-am uninstall-info-am \
++ uninstall-info-recursive uninstall-recursive
+
+ # The following hack produces a warning from automake, but we need it in order
+ # to build a file from a subdirectory. FIXME.
+@@ -626,7 +624,6 @@
+ $(MULTICLEAN) $(AM_MAKEFLAGS) DO=distclean multi-clean
+ maintainer-clean-multi:
+ $(MULTICLEAN) $(AM_MAKEFLAGS) DO=maintainer-clean multi-clean
+-
+ # Tell versions [3.59,3.63) of GNU make to not export all variables.
+ # Otherwise a system limit (for SysV at least) may be exceeded.
+ .NOEXPORT:
+diff -buNr boehm-gc/allchblk.c boehm-gc/allchblk.c
+--- boehm-gc/allchblk.c Mon Apr 8 17:39:15 2002
++++ boehm-gc/allchblk.c Sat Sep 13 02:10:15 2003
+@@ -47,12 +47,16 @@
+ struct hblk * GC_hblkfreelist[N_HBLK_FLS+1] = { 0 };
+
+ #ifndef USE_MUNMAP
++
+ word GC_free_bytes[N_HBLK_FLS+1] = { 0 };
+ /* Number of free bytes on each list. */
+
+ /* Is bytes + the number of free bytes on lists n .. N_HBLK_FLS */
+ /* > GC_max_large_allocd_bytes? */
+- GC_bool GC_enough_large_bytes_left(bytes,n)
++# ifdef __GNUC__
++ __inline__
++# endif
++ static GC_bool GC_enough_large_bytes_left(bytes,n)
+ word bytes;
+ int n;
+ {
+@@ -583,11 +587,11 @@
+ if (!GC_use_entire_heap
+ && size_avail != size_needed
+ && USED_HEAP_SIZE >= GC_requested_heapsize
+- && !GC_incremental && GC_should_collect()) {
++ && !TRUE_INCREMENTAL && GC_should_collect()) {
+ # ifdef USE_MUNMAP
+ continue;
+ # else
+- /* If we enough large blocks left to cover any */
++ /* If we have enough large blocks left to cover any */
+ /* previous request for large blocks, we go ahead */
+ /* and split. Assuming a steady state, that should */
+ /* be safe. It means that we can use the full */
+@@ -595,6 +599,12 @@
+ if (!GC_enough_large_bytes_left(GC_large_allocd_bytes, n)) {
+ continue;
+ }
++ /* If we are deallocating lots of memory from */
++ /* finalizers, fail and collect sooner rather */
++ /* than later. */
++ if (GC_finalizer_mem_freed > (GC_heapsize >> 4)) {
++ continue;
++ }
+ # endif /* !USE_MUNMAP */
+ }
+ /* If the next heap block is obviously better, go on. */
+diff -buNr boehm-gc/alloc.c boehm-gc/alloc.c
+--- boehm-gc/alloc.c Mon Mar 3 22:38:30 2003
++++ boehm-gc/alloc.c Sat Sep 13 02:10:15 2003
+@@ -72,6 +72,13 @@
+ GC_bool GC_need_full_gc = FALSE;
+ /* Need full GC do to heap growth. */
+
++#ifdef THREADS
++ GC_bool GC_world_stopped = FALSE;
++# define IF_THREADS(x) x
++#else
++# define IF_THREADS(x)
++#endif
++
+ word GC_used_heap_size_after_full = 0;
+
+ char * GC_copyright[] =
+@@ -119,7 +126,6 @@
+ unsigned long time_diff;
+
+ if ((count++ & 3) != 0) return(0);
+-#ifndef NO_CLOCK
+ GET_TIME(current_time);
+ time_diff = MS_TIME_DIFF(current_time,GC_start_time);
+ if (time_diff >= GC_time_limit) {
+@@ -132,7 +138,6 @@
+ # endif
+ return(1);
+ }
+-#endif
+ return(0);
+ }
+ #endif /* !SMALL_CONFIG */
+@@ -160,7 +165,7 @@
+ + (GC_large_free_bytes >> 2)
+ /* use a bit more of large empty heap */
+ + total_root_size);
+- if (GC_incremental) {
++ if (TRUE_INCREMENTAL) {
+ return scan_size / (2 * GC_free_space_divisor);
+ } else {
+ return scan_size / GC_free_space_divisor;
+@@ -182,7 +187,8 @@
+ /* managed object should not alter result, assuming the client */
+ /* is playing by the rules. */
+ result = (signed_word)GC_words_allocd
+- - (signed_word)GC_mem_freed - expl_managed;
++ - (signed_word)GC_mem_freed
++ + (signed_word)GC_finalizer_mem_freed - expl_managed;
+ if (result > (signed_word)GC_words_allocd) {
+ result = GC_words_allocd;
+ /* probably client bug or unfortunate scheduling */
+@@ -250,7 +256,6 @@
+
+ if (GC_should_collect()) {
+ if (!GC_incremental) {
+- GC_notify_full_gc();
+ GC_gcollect_inner();
+ n_partial_gcs = 0;
+ return;
+@@ -302,10 +307,14 @@
+ /*
+ * Stop the world garbage collection. Assumes lock held, signals disabled.
+ * If stop_func is not GC_never_stop_func, then abort if stop_func returns TRUE.
++ * Return TRUE if we successfully completed the collection.
+ */
+ GC_bool GC_try_to_collect_inner(stop_func)
+ GC_stop_func stop_func;
+ {
++# ifdef CONDPRINT
++ CLOCK_TYPE start_time, current_time;
++# endif
+ if (GC_dont_gc) return FALSE;
+ if (GC_incremental && GC_collection_in_progress()) {
+ # ifdef CONDPRINT
+@@ -320,8 +329,10 @@
+ GC_collect_a_little_inner(1);
+ }
+ }
++ if (stop_func == GC_never_stop_func) GC_notify_full_gc();
+ # ifdef CONDPRINT
+ if (GC_print_stats) {
++ if (GC_print_stats) GET_TIME(start_time);
+ GC_printf2(
+ "Initiating full world-stop collection %lu after %ld allocd bytes\n",
+ (unsigned long) GC_gc_no+1,
+@@ -360,6 +371,13 @@
+ return(FALSE);
+ }
+ GC_finish_collection();
++# if defined(CONDPRINT)
++ if (GC_print_stats) {
++ GET_TIME(current_time);
++ GC_printf1("Complete collection took %lu msecs\n",
++ MS_TIME_DIFF(current_time,start_time));
++ }
++# endif
+ return(TRUE);
+ }
+
+@@ -430,6 +448,7 @@
+ result = (int)GC_collection_in_progress();
+ UNLOCK();
+ ENABLE_SIGNALS();
++ if (!result && GC_debugging_started) GC_print_all_smashed();
+ return(result);
+ }
+
+@@ -448,16 +467,17 @@
+ CLOCK_TYPE start_time, current_time;
+ # endif
+
+-# if defined(REGISTER_LIBRARIES_EARLY)
+- GC_cond_register_dynamic_libraries();
+-# endif
+- STOP_WORLD();
+ # ifdef PRINTTIMES
+ GET_TIME(start_time);
+ # endif
+ # if defined(CONDPRINT) && !defined(PRINTTIMES)
+ if (GC_print_stats) GET_TIME(start_time);
+ # endif
++# if defined(REGISTER_LIBRARIES_EARLY)
++ GC_cond_register_dynamic_libraries();
++# endif
++ STOP_WORLD();
++ IF_THREADS(GC_world_stopped = TRUE);
+ # ifdef CONDPRINT
+ if (GC_print_stats) {
+ GC_printf1("--> Marking for collection %lu ",
+@@ -488,6 +508,7 @@
+ }
+ # endif
+ GC_deficit = i; /* Give the mutator a chance. */
++ IF_THREADS(GC_world_stopped = FALSE);
+ START_WORLD();
+ return(FALSE);
+ }
+@@ -521,6 +542,8 @@
+ (*GC_check_heap)();
+ }
+
++ IF_THREADS(GC_world_stopped = FALSE);
++ START_WORLD();
+ # ifdef PRINTTIMES
+ GET_TIME(current_time);
+ GC_printf1("World-stopped marking took %lu msecs\n",
+@@ -534,7 +557,6 @@
+ }
+ # endif
+ # endif
+- START_WORLD();
+ return(TRUE);
+ }
+
+@@ -611,6 +633,7 @@
+ GC_print_address_map();
+ }
+ # endif
++ COND_DUMP;
+ if (GC_find_leak) {
+ /* Mark all objects on the free list. All objects should be */
+ /* marked when we're done. */
+@@ -707,6 +730,7 @@
+ GC_words_allocd = 0;
+ GC_words_wasted = 0;
+ GC_mem_freed = 0;
++ GC_finalizer_mem_freed = 0;
+
+ # ifdef USE_MUNMAP
+ GC_unmap_old();
+@@ -730,6 +754,7 @@
+ int result;
+ DCL_LOCK_STATE;
+
++ if (GC_debugging_started) GC_print_all_smashed();
+ GC_INVOKE_FINALIZERS();
+ DISABLE_SIGNALS();
+ LOCK();
+@@ -741,14 +766,17 @@
+ EXIT_GC();
+ UNLOCK();
+ ENABLE_SIGNALS();
+- if(result) GC_INVOKE_FINALIZERS();
++ if(result) {
++ if (GC_debugging_started) GC_print_all_smashed();
++ GC_INVOKE_FINALIZERS();
++ }
+ return(result);
+ }
+
+ void GC_gcollect GC_PROTO(())
+ {
+- GC_notify_full_gc();
+ (void)GC_try_to_collect(GC_never_stop_func);
++ if (GC_have_errors) GC_print_all_errors();
+ }
+
+ word GC_n_heap_sects = 0; /* Number of sections currently in heap. */
+@@ -950,7 +978,6 @@
+ {
+ if (!GC_incremental && !GC_dont_gc &&
+ (GC_dont_expand && GC_words_allocd > 0 || GC_should_collect())) {
+- GC_notify_full_gc();
+ GC_gcollect_inner();
+ } else {
+ word blocks_to_get = GC_heapsize/(HBLKSIZE*GC_free_space_divisor)
+@@ -975,7 +1002,6 @@
+ && !GC_expand_hp_inner(needed_blocks)) {
+ if (GC_fail_count++ < GC_max_retries) {
+ WARN("Out of Memory! Trying to continue ...\n", 0);
+- GC_notify_full_gc();
+ GC_gcollect_inner();
+ } else {
+ # if !defined(AMIGA) || !defined(GC_AMIGA_FASTALLOC)
+@@ -1005,14 +1031,15 @@
+ word sz;
+ int kind;
+ {
+- register ptr_t * flh = &(GC_obj_kinds[kind].ok_freelist[sz]);
++ ptr_t * flh = &(GC_obj_kinds[kind].ok_freelist[sz]);
++ GC_bool tried_minor = FALSE;
+
+ if (sz == 0) return(0);
+
+ while (*flh == 0) {
+ ENTER_GC();
+ /* Do our share of marking work */
+- if(GC_incremental && !GC_dont_gc) GC_collect_a_little_inner(1);
++ if(TRUE_INCREMENTAL) GC_collect_a_little_inner(1);
+ /* Sweep blocks for objects of this size */
+ GC_continue_reclaim(sz, kind);
+ EXIT_GC();
+@@ -1021,13 +1048,21 @@
+ }
+ if (*flh == 0) {
+ ENTER_GC();
++ if (GC_incremental && GC_time_limit == GC_TIME_UNLIMITED
++ && ! tried_minor ) {
++ GC_collect_a_little_inner(1);
++ tried_minor = TRUE;
++ } else {
+ if (!GC_collect_or_expand((word)1,FALSE)) {
+ EXIT_GC();
+ return(0);
+ }
++ }
+ EXIT_GC();
+ }
+ }
++ /* Successful allocation; reset failure count. */
++ GC_fail_count = 0;
+
+ return(*flh);
+ }
+diff -buNr boehm-gc/alpha_mach_dep.s boehm-gc/alpha_mach_dep.s
+--- boehm-gc/alpha_mach_dep.s Fri Aug 17 11:30:45 2001
++++ boehm-gc/alpha_mach_dep.s Sat Sep 13 02:10:15 2003
+@@ -1,3 +1,4 @@
++ # $Id: darwin-gc.patch,v 1.1 2004/01/17 23:07:22 megacz Exp $
+ .arch ev6
+
+ .text
+diff -buNr boehm-gc/autom4te.cache/output.0 boehm-gc/autom4te.cache/output.0
+--- boehm-gc/autom4te.cache/output.0 Wed Dec 31 16:00:00 1969
++++ boehm-gc/autom4te.cache/output.0 Sat Sep 13 02:10:15 2003
+@@ -0,0 +1,5049 @@
++@%:@! /bin/sh
++@%:@ Guess values for system-dependent variables and create Makefiles.
++@%:@ Generated by GNU Autoconf 2.57.
++@%:@
++@%:@ Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002
++@%:@ Free Software Foundation, Inc.
++@%:@ This configure script is free software; the Free Software Foundation
++@%:@ gives unlimited permission to copy, distribute and modify it.
++## --------------------- ##
++## M4sh Initialization. ##
++## --------------------- ##
++
++# Be Bourne compatible
++if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
++ emulate sh
++ NULLCMD=:
++ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
++ # is contrary to our usage. Disable this feature.
++ alias -g '${1+"$@"}'='"$@"'
++elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
++ set -o posix
++fi
++
++# Support unset when possible.
++if (FOO=FOO; unset FOO) >/dev/null 2>&1; then
++ as_unset=unset
++else
++ as_unset=false
++fi
++
++
++# Work around bugs in pre-3.0 UWIN ksh.
++$as_unset ENV MAIL MAILPATH
++PS1='$ '
++PS2='> '
++PS4='+ '
++
++# NLS nuisances.
++for as_var in \
++ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
++ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
++ LC_TELEPHONE LC_TIME
++do
++ if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then
++ eval $as_var=C; export $as_var
++ else
++ $as_unset $as_var
++ fi
++done
++
++# Required to use basename.
++if expr a : '\(a\)' >/dev/null 2>&1; then
++ as_expr=expr
++else
++ as_expr=false
++fi
++
++if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
++ as_basename=basename
++else
++ as_basename=false
++fi
++
++
++# Name of the executable.
++as_me=`$as_basename "$0" ||
++$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
++ X"$0" : 'X\(//\)$' \| \
++ X"$0" : 'X\(/\)$' \| \
++ . : '\(.\)' 2>/dev/null ||
++echo X/"$0" |
++ sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
++ /^X\/\(\/\/\)$/{ s//\1/; q; }
++ /^X\/\(\/\).*/{ s//\1/; q; }
++ s/.*/./; q'`
++
++
++# PATH needs CR, and LINENO needs CR and PATH.
++# Avoid depending upon Character Ranges.
++as_cr_letters='abcdefghijklmnopqrstuvwxyz'
++as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
++as_cr_Letters=$as_cr_letters$as_cr_LETTERS
++as_cr_digits='0123456789'
++as_cr_alnum=$as_cr_Letters$as_cr_digits
++
++# The user is always right.
++if test "${PATH_SEPARATOR+set}" != set; then
++ echo "#! /bin/sh" >conf$$.sh
++ echo "exit 0" >>conf$$.sh
++ chmod +x conf$$.sh
++ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
++ PATH_SEPARATOR=';'
++ else
++ PATH_SEPARATOR=:
++ fi
++ rm -f conf$$.sh
++fi
++
++
++ as_lineno_1=$LINENO
++ as_lineno_2=$LINENO
++ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
++ test "x$as_lineno_1" != "x$as_lineno_2" &&
++ test "x$as_lineno_3" = "x$as_lineno_2" || {
++ # Find who we are. Look in the path if we contain no path at all
++ # relative or not.
++ case $0 in
++ *[\\/]* ) as_myself=$0 ;;
++ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++ IFS=$as_save_IFS
++ test -z "$as_dir" && as_dir=.
++ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
++done
++
++ ;;
++ esac
++ # We did not find ourselves, most probably we were run as `sh COMMAND'
++ # in which case we are not to be found in the path.
++ if test "x$as_myself" = x; then
++ as_myself=$0
++ fi
++ if test ! -f "$as_myself"; then
++ { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2
++ { (exit 1); exit 1; }; }
++ fi
++ case $CONFIG_SHELL in
++ '')
++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
++do
++ IFS=$as_save_IFS
++ test -z "$as_dir" && as_dir=.
++ for as_base in sh bash ksh sh5; do
++ case $as_dir in
++ /*)
++ if ("$as_dir/$as_base" -c '
++ as_lineno_1=$LINENO
++ as_lineno_2=$LINENO
++ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
++ test "x$as_lineno_1" != "x$as_lineno_2" &&
++ test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then
++ $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
++ $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
++ CONFIG_SHELL=$as_dir/$as_base
++ export CONFIG_SHELL
++ exec "$CONFIG_SHELL" "$0" ${1+"$@"}
++ fi;;
++ esac
++ done
++done
++;;
++ esac
++
++ # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
++ # uniformly replaced by the line number. The first 'sed' inserts a
++ # line-number line before each line; the second 'sed' does the real
++ # work. The second script uses 'N' to pair each line-number line
++ # with the numbered line, and appends trailing '-' during
++ # substitution so that $LINENO is not a special case at line end.
++ # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
++ # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-)
++ sed '=' <$as_myself |
++ sed '
++ N
++ s,$,-,
++ : loop
++ s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
++ t loop
++ s,-$,,
++ s,^['$as_cr_digits']*\n,,
++ ' >$as_me.lineno &&
++ chmod +x $as_me.lineno ||
++ { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
++ { (exit 1); exit 1; }; }
++
++ # Don't try to exec as it changes $[0], causing all sort of problems
++ # (the dirname of $[0] is not the place where we might find the
++ # original and so on. Autoconf is especially sensible to this).
++ . ./$as_me.lineno
++ # Exit status is that of the last command.
++ exit
++}
++
++
++case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
++ *c*,-n*) ECHO_N= ECHO_C='
++' ECHO_T=' ' ;;
++ *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;;
++ *) ECHO_N= ECHO_C='\c' ECHO_T= ;;
++esac
++
++if expr a : '\(a\)' >/dev/null 2>&1; then
++ as_expr=expr
++else
++ as_expr=false
++fi
++
++rm -f conf$$ conf$$.exe conf$$.file
++echo >conf$$.file
++if ln -s conf$$.file conf$$ 2>/dev/null; then
++ # We could just check for DJGPP; but this test a) works b) is more generic
++ # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
++ if test -f conf$$.exe; then
++ # Don't use ln at all; we don't have any links
++ as_ln_s='cp -p'
++ else
++ as_ln_s='ln -s'
++ fi
++elif ln conf$$.file conf$$ 2>/dev/null; then
++ as_ln_s=ln
++else
++ as_ln_s='cp -p'
++fi
++rm -f conf$$ conf$$.exe conf$$.file
++
++if mkdir -p . 2>/dev/null; then
++ as_mkdir_p=:
++else
++ as_mkdir_p=false
++fi
++
++as_executable_p="test -f"
++
++# Sed expression to map a string onto a valid CPP name.
++as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g"
++
++# Sed expression to map a string onto a valid variable name.
++as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g"
++
++
++# IFS
++# We need space, tab and new line, in precisely that order.
++as_nl='
++'
++IFS=" $as_nl"
++
++# CDPATH.
++$as_unset CDPATH
++
++
++# Name of the host.
++# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
++# so uname gets run too.
++ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
++
++exec 6>&1
++
++#
++# Initializations.
++#
++ac_default_prefix=/usr/local
++ac_config_libobj_dir=.
++cross_compiling=no
++subdirs=
++MFLAGS=
++MAKEFLAGS=
++SHELL=${CONFIG_SHELL-/bin/sh}
++
++# Maximum number of lines to put in a shell here document.
++# This variable seems obsolete. It should probably be removed, and
++# only ac_max_sed_lines should be used.
++: ${ac_max_here_lines=38}
++
++# Identity of this package.
++PACKAGE_NAME=
++PACKAGE_TARNAME=
++PACKAGE_VERSION=
++PACKAGE_STRING=
++PACKAGE_BUGREPORT=
++
++ac_unique_file="gcj_mlc.c"
++ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS gc_basedir build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os mkinstalldirs INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO SET_MAKE CC CXX AS ac_ct_AS AR ac_ct_AR RANLIB ac_ct_RANLIB MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT GC_CFLAGS LN_S STRIP ac_ct_STRIP LIBTOOL CXXCPP CPPFLAGS THREADLIBS POWERPC_DARWIN_TRUE POWERPC_DARWIN_FALSE EXTRA_TEST_LIBS target_all INCLUDES CXXINCLUDES addobjs MY_CFLAGS USE_LIBDIR_TRUE USE_LIBDIR_FALSE LIB@&t@OBJS LTLIBOBJS'
++ac_subst_files=''
++
++# Initialize some variables set by options.
++ac_init_help=
++ac_init_version=false
++# The variables have the same names as the options, with
++# dashes changed to underlines.
++cache_file=/dev/null
++exec_prefix=NONE
++no_create=
++no_recursion=
++prefix=NONE
++program_prefix=NONE
++program_suffix=NONE
++program_transform_name=s,x,x,
++silent=
++site=
++srcdir=
++verbose=
++x_includes=NONE
++x_libraries=NONE
++
++# Installation directory options.
++# These are left unexpanded so users can "make install exec_prefix=/foo"
++# and all the variables that are supposed to be based on exec_prefix
++# by default will actually change.
++# Use braces instead of parens because sh, perl, etc. also accept them.
++bindir='${exec_prefix}/bin'
++sbindir='${exec_prefix}/sbin'
++libexecdir='${exec_prefix}/libexec'
++datadir='${prefix}/share'
++sysconfdir='${prefix}/etc'
++sharedstatedir='${prefix}/com'
++localstatedir='${prefix}/var'
++libdir='${exec_prefix}/lib'
++includedir='${prefix}/include'
++oldincludedir='/usr/include'
++infodir='${prefix}/info'
++mandir='${prefix}/man'
++
++ac_prev=
++for ac_option
++do
++ # If the previous option needs an argument, assign it.
++ if test -n "$ac_prev"; then
++ eval "$ac_prev=\$ac_option"
++ ac_prev=
++ continue
++ fi
++
++ ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`
++
++ # Accept the important Cygnus configure options, so we can diagnose typos.
++
++ case $ac_option in
++
++ -bindir | --bindir | --bindi | --bind | --bin | --bi)
++ ac_prev=bindir ;;
++ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
++ bindir=$ac_optarg ;;
++
++ -build | --build | --buil | --bui | --bu)
++ ac_prev=build_alias ;;
++ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
++ build_alias=$ac_optarg ;;
++
++ -cache-file | --cache-file | --cache-fil | --cache-fi \
++ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
++ ac_prev=cache_file ;;
++ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
++ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
++ cache_file=$ac_optarg ;;
++
++ --config-cache | -C)
++ cache_file=config.cache ;;
++
++ -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
++ ac_prev=datadir ;;
++ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
++ | --da=*)
++ datadir=$ac_optarg ;;
++
++ -disable-* | --disable-*)
++ ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
++ # Reject names that are not valid shell variable names.
++ expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
++ { echo "$as_me: error: invalid feature name: $ac_feature" >&2
++ { (exit 1); exit 1; }; }
++ ac_feature=`echo $ac_feature | sed 's/-/_/g'`
++ eval "enable_$ac_feature=no" ;;
++
++ -enable-* | --enable-*)
++ ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
++ # Reject names that are not valid shell variable names.
++ expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
++ { echo "$as_me: error: invalid feature name: $ac_feature" >&2
++ { (exit 1); exit 1; }; }
++ ac_feature=`echo $ac_feature | sed 's/-/_/g'`
++ case $ac_option in
++ *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
++ *) ac_optarg=yes ;;
++ esac
++ eval "enable_$ac_feature='$ac_optarg'" ;;
++
++ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
++ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
++ | --exec | --exe | --ex)
++ ac_prev=exec_prefix ;;
++ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
++ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
++ | --exec=* | --exe=* | --ex=*)
++ exec_prefix=$ac_optarg ;;
++
++ -gas | --gas | --ga | --g)
++ # Obsolete; use --with-gas.
++ with_gas=yes ;;
++
++ -help | --help | --hel | --he | -h)
++ ac_init_help=long ;;
++ -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
++ ac_init_help=recursive ;;
++ -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
++ ac_init_help=short ;;
++
++ -host | --host | --hos | --ho)
++ ac_prev=host_alias ;;
++ -host=* | --host=* | --hos=* | --ho=*)
++ host_alias=$ac_optarg ;;
++
++ -includedir | --includedir | --includedi | --included | --include \
++ | --includ | --inclu | --incl | --inc)
++ ac_prev=includedir ;;
++ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
++ | --includ=* | --inclu=* | --incl=* | --inc=*)
++ includedir=$ac_optarg ;;
++
++ -infodir | --infodir | --infodi | --infod | --info | --inf)
++ ac_prev=infodir ;;
++ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
++ infodir=$ac_optarg ;;
++
++ -libdir | --libdir | --libdi | --libd)
++ ac_prev=libdir ;;
++ -libdir=* | --libdir=* | --libdi=* | --libd=*)
++ libdir=$ac_optarg ;;
++
++ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
++ | --libexe | --libex | --libe)
++ ac_prev=libexecdir ;;
++ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
++ | --libexe=* | --libex=* | --libe=*)
++ libexecdir=$ac_optarg ;;
++
++ -localstatedir | --localstatedir | --localstatedi | --localstated \
++ | --localstate | --localstat | --localsta | --localst \
++ | --locals | --local | --loca | --loc | --lo)
++ ac_prev=localstatedir ;;
++ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
++ | --localstate=* | --localstat=* | --localsta=* | --localst=* \
++ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
++ localstatedir=$ac_optarg ;;
++
++ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
++ ac_prev=mandir ;;
++ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
++ mandir=$ac_optarg ;;
++
++ -nfp | --nfp | --nf)
++ # Obsolete; use --without-fp.
++ with_fp=no ;;
++
++ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
++ | --no-cr | --no-c | -n)
++ no_create=yes ;;
++
++ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
++ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
++ no_recursion=yes ;;
++
++ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
++ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
++ | --oldin | --oldi | --old | --ol | --o)
++ ac_prev=oldincludedir ;;
++ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
++ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
++ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
++ oldincludedir=$ac_optarg ;;
++
++ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
++ ac_prev=prefix ;;
++ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
++ prefix=$ac_optarg ;;
++
++ -program-prefix | --program-prefix | --program-prefi | --program-pref \
++ | --program-pre | --program-pr | --program-p)
++ ac_prev=program_prefix ;;
++ -program-prefix=* | --program-prefix=* | --program-prefi=* \
++ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
++ program_prefix=$ac_optarg ;;
++
++ -program-suffix | --program-suffix | --program-suffi | --program-suff \
++ | --program-suf | --program-su | --program-s)
++ ac_prev=program_suffix ;;
++ -program-suffix=* | --program-suffix=* | --program-suffi=* \
++ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
++ program_suffix=$ac_optarg ;;
++
++ -program-transform-name | --program-transform-name \
++ | --program-transform-nam | --program-transform-na \
++ | --program-transform-n | --program-transform- \
++ | --program-transform | --program-transfor \
++ | --program-transfo | --program-transf \
++ | --program-trans | --program-tran \
++ | --progr-tra | --program-tr | --program-t)
++ ac_prev=program_transform_name ;;
++ -program-transform-name=* | --program-transform-name=* \
++ | --program-transform-nam=* | --program-transform-na=* \
++ | --program-transform-n=* | --program-transform-=* \
++ | --program-transform=* | --program-transfor=* \
++ | --program-transfo=* | --program-transf=* \
++ | --program-trans=* | --program-tran=* \
++ | --progr-tra=* | --program-tr=* | --program-t=*)
++ program_transform_name=$ac_optarg ;;
++
++ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
++ | -silent | --silent | --silen | --sile | --sil)
++ silent=yes ;;
++
++ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
++ ac_prev=sbindir ;;
++ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
++ | --sbi=* | --sb=*)
++ sbindir=$ac_optarg ;;
++
++ -sharedstatedir | --sharedstatedir | --sharedstatedi \
++ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
++ | --sharedst | --shareds | --shared | --share | --shar \
++ | --sha | --sh)
++ ac_prev=sharedstatedir ;;
++ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
++ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
++ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
++ | --sha=* | --sh=*)
++ sharedstatedir=$ac_optarg ;;
++
++ -site | --site | --sit)
++ ac_prev=site ;;
++ -site=* | --site=* | --sit=*)
++ site=$ac_optarg ;;
++
++ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
++ ac_prev=srcdir ;;
++ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
++ srcdir=$ac_optarg ;;
++
++ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
++ | --syscon | --sysco | --sysc | --sys | --sy)
++ ac_prev=sysconfdir ;;
++ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
++ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
++ sysconfdir=$ac_optarg ;;
++
++ -target | --target | --targe | --targ | --tar | --ta | --t)
++ ac_prev=target_alias ;;
++ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
++ target_alias=$ac_optarg ;;
++
++ -v | -verbose | --verbose | --verbos | --verbo | --verb)
++ verbose=yes ;;
++
++ -version | --version | --versio | --versi | --vers | -V)
++ ac_init_version=: ;;
++
++ -with-* | --with-*)
++ ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
++ # Reject names that are not valid shell variable names.
++ expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
++ { echo "$as_me: error: invalid package name: $ac_package" >&2
++ { (exit 1); exit 1; }; }
++ ac_package=`echo $ac_package| sed 's/-/_/g'`
++ case $ac_option in
++ *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
++ *) ac_optarg=yes ;;
++ esac
++ eval "with_$ac_package='$ac_optarg'" ;;
++
++ -without-* | --without-*)
++ ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
++ # Reject names that are not valid shell variable names.
++ expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
++ { echo "$as_me: error: invalid package name: $ac_package" >&2
++ { (exit 1); exit 1; }; }
++ ac_package=`echo $ac_package | sed 's/-/_/g'`
++ eval "with_$ac_package=no" ;;
++
++ --x)
++ # Obsolete; use --with-x.
++ with_x=yes ;;
++
++ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
++ | --x-incl | --x-inc | --x-in | --x-i)
++ ac_prev=x_includes ;;
++ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
++ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
++ x_includes=$ac_optarg ;;
++
++ -x-libraries | --x-libraries | --x-librarie | --x-librari \
++ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
++ ac_prev=x_libraries ;;
++ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
++ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
++ x_libraries=$ac_optarg ;;
++
++ -*) { echo "$as_me: error: unrecognized option: $ac_option
++Try \`$0 --help' for more information." >&2
++ { (exit 1); exit 1; }; }
++ ;;
++
++ *=*)
++ ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
++ # Reject names that are not valid shell variable names.
++ expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
++ { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
++ { (exit 1); exit 1; }; }
++ ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`
++ eval "$ac_envvar='$ac_optarg'"
++ export $ac_envvar ;;
++
++ *)
++ # FIXME: should be removed in autoconf 3.0.
++ echo "$as_me: WARNING: you should use --build, --host, --target" >&2
++ expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
++ echo "$as_me: WARNING: invalid host type: $ac_option" >&2
++ : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
++ ;;
++
++ esac
++done
++
++if test -n "$ac_prev"; then
++ ac_option=--`echo $ac_prev | sed 's/_/-/g'`
++ { echo "$as_me: error: missing argument to $ac_option" >&2
++ { (exit 1); exit 1; }; }
++fi
++
++# Be sure to have absolute paths.
++for ac_var in exec_prefix prefix
++do
++ eval ac_val=$`echo $ac_var`
++ case $ac_val in
++ [\\/$]* | ?:[\\/]* | NONE | '' ) ;;
++ *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
++ { (exit 1); exit 1; }; };;
++ esac
++done
++
++# Be sure to have absolute paths.
++for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \
++ localstatedir libdir includedir oldincludedir infodir mandir
++do
++ eval ac_val=$`echo $ac_var`
++ case $ac_val in
++ [\\/$]* | ?:[\\/]* ) ;;
++ *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
++ { (exit 1); exit 1; }; };;
++ esac
++done
++
++# There might be people who depend on the old broken behavior: `$host'
++# used to hold the argument of --host etc.
++# FIXME: To remove some day.
++build=$build_alias
++host=$host_alias
++target=$target_alias
++
++# FIXME: To remove some day.
++if test "x$host_alias" != x; then
++ if test "x$build_alias" = x; then
++ cross_compiling=maybe
++ echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
++ If a cross compiler is detected then cross compile mode will be used." >&2
++ elif test "x$build_alias" != "x$host_alias"; then
++ cross_compiling=yes
++ fi
++fi
++
++ac_tool_prefix=
++test -n "$host_alias" && ac_tool_prefix=$host_alias-
++
++test "$silent" = yes && exec 6>/dev/null
++
++
++# Find the source files, if location was not specified.
++if test -z "$srcdir"; then
++ ac_srcdir_defaulted=yes
++ # Try the directory containing this script, then its parent.
++ ac_confdir=`(dirname "$0") 2>/dev/null ||
++$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
++ X"$0" : 'X\(//\)[^/]' \| \
++ X"$0" : 'X\(//\)$' \| \
++ X"$0" : 'X\(/\)' \| \
++ . : '\(.\)' 2>/dev/null ||
++echo X"$0" |
++ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
++ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
++ /^X\(\/\/\)$/{ s//\1/; q; }
++ /^X\(\/\).*/{ s//\1/; q; }
++ s/.*/./; q'`
++ srcdir=$ac_confdir
++ if test ! -r $srcdir/$ac_unique_file; then
++ srcdir=..
++ fi
++else
++ ac_srcdir_defaulted=no
++fi
++if test ! -r $srcdir/$ac_unique_file; then
++ if test "$ac_srcdir_defaulted" = yes; then
++ { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2
++ { (exit 1); exit 1; }; }
++ else
++ { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
++ { (exit 1); exit 1; }; }
++ fi
++fi
++(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null ||
++ { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2
++ { (exit 1); exit 1; }; }
++srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
++ac_env_build_alias_set=${build_alias+set}
++ac_env_build_alias_value=$build_alias
++ac_cv_env_build_alias_set=${build_alias+set}
++ac_cv_env_build_alias_value=$build_alias
++ac_env_host_alias_set=${host_alias+set}
++ac_env_host_alias_value=$host_alias
++ac_cv_env_host_alias_set=${host_alias+set}
++ac_cv_env_host_alias_value=$host_alias
++ac_env_target_alias_set=${target_alias+set}
++ac_env_target_alias_value=$target_alias
++ac_cv_env_target_alias_set=${target_alias+set}
++ac_cv_env_target_alias_value=$target_alias
++ac_env_CXXCPP_set=${CXXCPP+set}
++ac_env_CXXCPP_value=$CXXCPP
++ac_cv_env_CXXCPP_set=${CXXCPP+set}
++ac_cv_env_CXXCPP_value=$CXXCPP
++ac_env_CPPFLAGS_set=${CPPFLAGS+set}
++ac_env_CPPFLAGS_value=$CPPFLAGS
++ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set}
++ac_cv_env_CPPFLAGS_value=$CPPFLAGS
++
++#
++# Report the --help message.
++#
++if test "$ac_init_help" = "long"; then
++ # Omit some internal or obsolete options to make the list less imposing.
++ # This message is too long to be a string in the A/UX 3.1 sh.
++ cat <<_ACEOF
++\`configure' configures this package to adapt to many kinds of systems.
++
++Usage: $0 [OPTION]... [VAR=VALUE]...
++
++To assign environment variables (e.g., CC, CFLAGS...), specify them as
++VAR=VALUE. See below for descriptions of some of the useful variables.
++
++Defaults for the options are specified in brackets.
++
++Configuration:
++ -h, --help display this help and exit
++ --help=short display options specific to this package
++ --help=recursive display the short help of all the included packages
++ -V, --version display version information and exit
++ -q, --quiet, --silent do not print \`checking...' messages
++ --cache-file=FILE cache test results in FILE [disabled]
++ -C, --config-cache alias for \`--cache-file=config.cache'
++ -n, --no-create do not create output files
++ --srcdir=DIR find the sources in DIR [configure dir or \`..']
++
++_ACEOF
++
++ cat <<_ACEOF
++Installation directories:
++ --prefix=PREFIX install architecture-independent files in PREFIX
++ [$ac_default_prefix]
++ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
++ [PREFIX]
++
++By default, \`make install' will install all the files in
++\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
++an installation prefix other than \`$ac_default_prefix' using \`--prefix',
++for instance \`--prefix=\$HOME'.
++
++For better control, use the options below.
++
++Fine tuning of the installation directories:
++ --bindir=DIR user executables [EPREFIX/bin]
++ --sbindir=DIR system admin executables [EPREFIX/sbin]
++ --libexecdir=DIR program executables [EPREFIX/libexec]
++ --datadir=DIR read-only architecture-independent data [PREFIX/share]
++ --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
++ --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
++ --localstatedir=DIR modifiable single-machine data [PREFIX/var]
++ --libdir=DIR object code libraries [EPREFIX/lib]
++ --includedir=DIR C header files [PREFIX/include]
++ --oldincludedir=DIR C header files for non-gcc [/usr/include]
++ --infodir=DIR info documentation [PREFIX/info]
++ --mandir=DIR man documentation [PREFIX/man]
++_ACEOF
++
++ cat <<\_ACEOF
++
++Program names:
++ --program-prefix=PREFIX prepend PREFIX to installed program names
++ --program-suffix=SUFFIX append SUFFIX to installed program names
++ --program-transform-name=PROGRAM run sed PROGRAM on installed program names
++
++System types:
++ --build=BUILD configure for building on BUILD [guessed]
++ --host=HOST cross-compile to build programs to run on HOST [BUILD]
++ --target=TARGET configure for building compilers for TARGET [HOST]
++_ACEOF
++fi
++
++if test -n "$ac_init_help"; then
++
++ cat <<\_ACEOF
++
++Optional Features:
++ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
++ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
++ --enable-multilib build many library versions (default)
++ --enable-maintainer-mode enable make rules and dependencies not useful
++ (and sometimes confusing) to the casual installer
++ --enable-shared=PKGS build shared libraries default=yes
++ --enable-static=PKGS build static libraries default=yes
++ --enable-fast-install=PKGS optimize for fast installation default=yes
++ --disable-libtool-lock avoid locking (might break parallel builds)
++ --enable-parallel-mark parallelize marking and free list construction
++ --enable-shared=PKGS build shared libraries default=no
++ --enable-full-debug include full support for pointer backtracing etc.
++
++Optional Packages:
++ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
++ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
++ --with-gnu-ld assume the C compiler uses GNU ld default=no
++ --with-pic try to use only PIC/non-PIC objects default=use both
++ --with-target-subdir=SUBDIR
++ configuring with a cross compiler
++ --with-cross-host=HOST configuring with a cross compiler
++ --with-ecos enable runtime eCos target support
++
++Some influential environment variables:
++ CXXCPP C++ preprocessor
++ CPPFLAGS C/C++ preprocessor flags, e.g. -I<include dir> if you have
++ headers in a nonstandard directory <include dir>
++
++Use these variables to override the choices made by `configure' or to help
++it to find libraries and programs with nonstandard names/locations.
++
++_ACEOF
++fi
++
++if test "$ac_init_help" = "recursive"; then
++ # If there are subdirs, report their specific --help.
++ ac_popdir=`pwd`
++ for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
++ test -d $ac_dir || continue
++ ac_builddir=.
++
++if test "$ac_dir" != .; then
++ ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
++ # A "../" for each directory in $ac_dir_suffix.
++ ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
++else
++ ac_dir_suffix= ac_top_builddir=
++fi
++
++case $srcdir in
++ .) # No --srcdir option. We are building in place.
++ ac_srcdir=.
++ if test -z "$ac_top_builddir"; then
++ ac_top_srcdir=.
++ else
++ ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
++ fi ;;
++ [\\/]* | ?:[\\/]* ) # Absolute path.
++ ac_srcdir=$srcdir$ac_dir_suffix;
++ ac_top_srcdir=$srcdir ;;
++ *) # Relative path.
++ ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
++ ac_top_srcdir=$ac_top_builddir$srcdir ;;
++esac
++# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be
++# absolute.
++ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd`
++ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd`
++ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd`
++ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd`
++
++ cd $ac_dir
++ # Check for guested configure; otherwise get Cygnus style configure.
++ if test -f $ac_srcdir/configure.gnu; then
++ echo
++ $SHELL $ac_srcdir/configure.gnu --help=recursive
++ elif test -f $ac_srcdir/configure; then
++ echo
++ $SHELL $ac_srcdir/configure --help=recursive
++ elif test -f $ac_srcdir/configure.ac ||
++ test -f $ac_srcdir/configure.in; then
++ echo
++ $ac_configure --help
++ else
++ echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
++ fi
++ cd $ac_popdir
++ done
++fi
++
++test -n "$ac_init_help" && exit 0
++if $ac_init_version; then
++ cat <<\_ACEOF
++
++Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002
++Free Software Foundation, Inc.
++This configure script is free software; the Free Software Foundation
++gives unlimited permission to copy, distribute and modify it.
++_ACEOF
++ exit 0
++fi
++exec 5>config.log
++cat >&5 <<_ACEOF
++This file contains any messages produced by compilers while
++running configure, to aid debugging if configure makes a mistake.
++
++It was created by $as_me, which was
++generated by GNU Autoconf 2.57. Invocation command line was
++
++ $ $0 $@
++
++_ACEOF
++{
++cat <<_ASUNAME
++@%:@@%:@ --------- @%:@@%:@
++@%:@@%:@ Platform. @%:@@%:@
++@%:@@%:@ --------- @%:@@%:@
++
++hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
++uname -m = `(uname -m) 2>/dev/null || echo unknown`
++uname -r = `(uname -r) 2>/dev/null || echo unknown`
++uname -s = `(uname -s) 2>/dev/null || echo unknown`
++uname -v = `(uname -v) 2>/dev/null || echo unknown`
++
++/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
++/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown`
++
++/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown`
++/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown`
++/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
++hostinfo = `(hostinfo) 2>/dev/null || echo unknown`
++/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown`
++/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown`
++/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown`
++
++_ASUNAME
++
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++ IFS=$as_save_IFS
++ test -z "$as_dir" && as_dir=.
++ echo "PATH: $as_dir"
++done
++
++} >&5
++
++cat >&5 <<_ACEOF
++
++
++@%:@@%:@ ----------- @%:@@%:@
++@%:@@%:@ Core tests. @%:@@%:@
++@%:@@%:@ ----------- @%:@@%:@
++
++_ACEOF
++
++
++# Keep a trace of the command line.
++# Strip out --no-create and --no-recursion so they do not pile up.
++# Strip out --silent because we don't want to record it for future runs.
++# Also quote any args containing shell meta-characters.
++# Make two passes to allow for proper duplicate-argument suppression.
++ac_configure_args=
++ac_configure_args0=
++ac_configure_args1=
++ac_sep=
++ac_must_keep_next=false
++for ac_pass in 1 2
++do
++ for ac_arg
++ do
++ case $ac_arg in
++ -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
++ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
++ | -silent | --silent | --silen | --sile | --sil)
++ continue ;;
++ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
++ ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
++ esac
++ case $ac_pass in
++ 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
++ 2)
++ ac_configure_args1="$ac_configure_args1 '$ac_arg'"
++ if test $ac_must_keep_next = true; then
++ ac_must_keep_next=false # Got value, back to normal.
++ else
++ case $ac_arg in
++ *=* | --config-cache | -C | -disable-* | --disable-* \
++ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
++ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
++ | -with-* | --with-* | -without-* | --without-* | --x)
++ case "$ac_configure_args0 " in
++ "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
++ esac
++ ;;
++ -* ) ac_must_keep_next=true ;;
++ esac
++ fi
++ ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
++ # Get rid of the leading space.
++ ac_sep=" "
++ ;;
++ esac
++ done
++done
++$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
++$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
++
++# When interrupted or exit'd, cleanup temporary files, and complete
++# config.log. We remove comments because anyway the quotes in there
++# would cause problems or look ugly.
++# WARNING: Be sure not to use single quotes in there, as some shells,
++# such as our DU 5.0 friend, will then `close' the trap.
++trap 'exit_status=$?
++ # Save into config.log some information that might help in debugging.
++ {
++ echo
++
++ cat <<\_ASBOX
++@%:@@%:@ ---------------- @%:@@%:@
++@%:@@%:@ Cache variables. @%:@@%:@
++@%:@@%:@ ---------------- @%:@@%:@
++_ASBOX
++ echo
++ # The following way of writing the cache mishandles newlines in values,
++{
++ (set) 2>&1 |
++ case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in
++ *ac_space=\ *)
++ sed -n \
++ "s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
++ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
++ ;;
++ *)
++ sed -n \
++ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
++ ;;
++ esac;
++}
++ echo
++
++ cat <<\_ASBOX
++@%:@@%:@ ----------------- @%:@@%:@
++@%:@@%:@ Output variables. @%:@@%:@
++@%:@@%:@ ----------------- @%:@@%:@
++_ASBOX
++ echo
++ for ac_var in $ac_subst_vars
++ do
++ eval ac_val=$`echo $ac_var`
++ echo "$ac_var='"'"'$ac_val'"'"'"
++ done | sort
++ echo
++
++ if test -n "$ac_subst_files"; then
++ cat <<\_ASBOX
++@%:@@%:@ ------------- @%:@@%:@
++@%:@@%:@ Output files. @%:@@%:@
++@%:@@%:@ ------------- @%:@@%:@
++_ASBOX
++ echo
++ for ac_var in $ac_subst_files
++ do
++ eval ac_val=$`echo $ac_var`
++ echo "$ac_var='"'"'$ac_val'"'"'"
++ done | sort
++ echo
++ fi
++
++ if test -s confdefs.h; then
++ cat <<\_ASBOX
++@%:@@%:@ ----------- @%:@@%:@
++@%:@@%:@ confdefs.h. @%:@@%:@
++@%:@@%:@ ----------- @%:@@%:@
++_ASBOX
++ echo
++ sed "/^$/d" confdefs.h | sort
++ echo
++ fi
++ test "$ac_signal" != 0 &&
++ echo "$as_me: caught signal $ac_signal"
++ echo "$as_me: exit $exit_status"
++ } >&5
++ rm -f core core.* *.core &&
++ rm -rf conftest* confdefs* conf$$* $ac_clean_files &&
++ exit $exit_status
++ ' 0
++for ac_signal in 1 2 13 15; do
++ trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
++done
++ac_signal=0
++
++# confdefs.h avoids OS command line length limits that DEFS can exceed.
++rm -rf conftest* confdefs.h
++# AIX cpp loses on an empty file, so make sure it contains at least a newline.
++echo >confdefs.h
++
++# Predefined preprocessor variables.
++
++cat >>confdefs.h <<_ACEOF
++@%:@define PACKAGE_NAME "$PACKAGE_NAME"
++_ACEOF
++
++
++cat >>confdefs.h <<_ACEOF
++@%:@define PACKAGE_TARNAME "$PACKAGE_TARNAME"
++_ACEOF
++
++
++cat >>confdefs.h <<_ACEOF
++@%:@define PACKAGE_VERSION "$PACKAGE_VERSION"
++_ACEOF
++
++
++cat >>confdefs.h <<_ACEOF
++@%:@define PACKAGE_STRING "$PACKAGE_STRING"
++_ACEOF
++
++
++cat >>confdefs.h <<_ACEOF
++@%:@define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
++_ACEOF
++
++
++# Let the site file select an alternate cache file if it wants to.
++# Prefer explicitly selected file to automatically selected ones.
++if test -z "$CONFIG_SITE"; then
++ if test "x$prefix" != xNONE; then
++ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
++ else
++ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
++ fi
++fi
++for ac_site_file in $CONFIG_SITE; do
++ if test -r "$ac_site_file"; then
++ { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
++echo "$as_me: loading site script $ac_site_file" >&6;}
++ sed 's/^/| /' "$ac_site_file" >&5
++ . "$ac_site_file"
++ fi
++done
++
++if test -r "$cache_file"; then
++ # Some versions of bash will fail to source /dev/null (special
++ # files actually), so we avoid doing that.
++ if test -f "$cache_file"; then
++ { echo "$as_me:$LINENO: loading cache $cache_file" >&5
++echo "$as_me: loading cache $cache_file" >&6;}
++ case $cache_file in
++ [\\/]* | ?:[\\/]* ) . $cache_file;;
++ *) . ./$cache_file;;
++ esac
++ fi
++else
++ { echo "$as_me:$LINENO: creating cache $cache_file" >&5
++echo "$as_me: creating cache $cache_file" >&6;}
++ >$cache_file
++fi
++
++# Check that the precious variables saved in the cache have kept the same
++# value.
++ac_cache_corrupted=false
++for ac_var in `(set) 2>&1 |
++ sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do
++ eval ac_old_set=\$ac_cv_env_${ac_var}_set
++ eval ac_new_set=\$ac_env_${ac_var}_set
++ eval ac_old_val="\$ac_cv_env_${ac_var}_value"
++ eval ac_new_val="\$ac_env_${ac_var}_value"
++ case $ac_old_set,$ac_new_set in
++ set,)
++ { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
++echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
++ ac_cache_corrupted=: ;;
++ ,set)
++ { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
++echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
++ ac_cache_corrupted=: ;;
++ ,);;
++ *)
++ if test "x$ac_old_val" != "x$ac_new_val"; then
++ { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
++echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
++ { echo "$as_me:$LINENO: former value: $ac_old_val" >&5
++echo "$as_me: former value: $ac_old_val" >&2;}
++ { echo "$as_me:$LINENO: current value: $ac_new_val" >&5
++echo "$as_me: current value: $ac_new_val" >&2;}
++ ac_cache_corrupted=:
++ fi;;
++ esac
++ # Pass precious variables to config.status.
++ if test "$ac_new_set" = set; then
++ case $ac_new_val in
++ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
++ ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
++ *) ac_arg=$ac_var=$ac_new_val ;;
++ esac
++ case " $ac_configure_args " in
++ *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
++ *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
++ esac
++ fi
++done
++if $ac_cache_corrupted; then
++ { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
++echo "$as_me: error: changes in the environment can compromise the build" >&2;}
++ { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
++echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
++ { (exit 1); exit 1; }; }
++fi
++
++ac_ext=c
++ac_cpp='$CPP $CPPFLAGS'
++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
++ac_compiler_gnu=$ac_cv_c_compiler_gnu
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++# This works around the fact that libtool configuration may change LD
++# for this particular configuration, but some shells, instead of
++# keeping the changes in LD private, export them just because LD is
++# exported.
++ORIGINAL_LD_FOR_MULTILIBS=$LD
++
++ac_aux_dir=
++for ac_dir in . $srcdir/.; do
++ if test -f $ac_dir/install-sh; then
++ ac_aux_dir=$ac_dir
++ ac_install_sh="$ac_aux_dir/install-sh -c"
++ break
++ elif test -f $ac_dir/install.sh; then
++ ac_aux_dir=$ac_dir
++ ac_install_sh="$ac_aux_dir/install.sh -c"
++ break
++ elif test -f $ac_dir/shtool; then
++ ac_aux_dir=$ac_dir
++ ac_install_sh="$ac_aux_dir/shtool install -c"
++ break
++ fi
++done
++if test -z "$ac_aux_dir"; then
++ { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in . $srcdir/." >&5
++echo "$as_me: error: cannot find install-sh or install.sh in . $srcdir/." >&2;}
++ { (exit 1); exit 1; }; }
++fi
++ac_config_guess="$SHELL $ac_aux_dir/config.guess"
++ac_config_sub="$SHELL $ac_aux_dir/config.sub"
++ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure.
++
++
++# Make sure we can run config.sub.
++$ac_config_sub sun4 >/dev/null 2>&1 ||
++ { { echo "$as_me:$LINENO: error: cannot run $ac_config_sub" >&5
++echo "$as_me: error: cannot run $ac_config_sub" >&2;}
++ { (exit 1); exit 1; }; }
++
++echo "$as_me:$LINENO: checking build system type" >&5
++echo $ECHO_N "checking build system type... $ECHO_C" >&6
++if test "${ac_cv_build+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ ac_cv_build_alias=$build_alias
++test -z "$ac_cv_build_alias" &&
++ ac_cv_build_alias=`$ac_config_guess`
++test -z "$ac_cv_build_alias" &&
++ { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5
++echo "$as_me: error: cannot guess build type; you must specify one" >&2;}
++ { (exit 1); exit 1; }; }
++ac_cv_build=`$ac_config_sub $ac_cv_build_alias` ||
++ { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_build_alias failed" >&5
++echo "$as_me: error: $ac_config_sub $ac_cv_build_alias failed" >&2;}
++ { (exit 1); exit 1; }; }
++
++fi
++echo "$as_me:$LINENO: result: $ac_cv_build" >&5
++echo "${ECHO_T}$ac_cv_build" >&6
++build=$ac_cv_build
++build_cpu=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
++build_vendor=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
++build_os=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
++
++
++echo "$as_me:$LINENO: checking host system type" >&5
++echo $ECHO_N "checking host system type... $ECHO_C" >&6
++if test "${ac_cv_host+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ ac_cv_host_alias=$host_alias
++test -z "$ac_cv_host_alias" &&
++ ac_cv_host_alias=$ac_cv_build_alias
++ac_cv_host=`$ac_config_sub $ac_cv_host_alias` ||
++ { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_host_alias failed" >&5
++echo "$as_me: error: $ac_config_sub $ac_cv_host_alias failed" >&2;}
++ { (exit 1); exit 1; }; }
++
++fi
++echo "$as_me:$LINENO: result: $ac_cv_host" >&5
++echo "${ECHO_T}$ac_cv_host" >&6
++host=$ac_cv_host
++host_cpu=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
++host_vendor=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
++host_os=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
++
++
++# Find a good install program. We prefer a C program (faster),
++# so one script is as good as another. But avoid the broken or
++# incompatible versions:
++# SysV /etc/install, /usr/sbin/install
++# SunOS /usr/etc/install
++# IRIX /sbin/install
++# AIX /bin/install
++# AmigaOS /C/install, which installs bootblocks on floppy discs
++# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
++# AFS /usr/afsws/bin/install, which mishandles nonexistent args
++# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
++# ./install, which can be erroneously created by make from ./install.sh.
++echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
++echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6
++if test -z "$INSTALL"; then
++if test "${ac_cv_path_install+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++ IFS=$as_save_IFS
++ test -z "$as_dir" && as_dir=.
++ # Account for people who put trailing slashes in PATH elements.
++case $as_dir/ in
++ ./ | .// | /cC/* | \
++ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
++ /usr/ucb/* ) ;;
++ *)
++ # OSF1 and SCO ODT 3.0 have their own names for install.
++ # Don't use installbsd from OSF since it installs stuff as root
++ # by default.
++ for ac_prog in ginstall scoinst install; do
++ for ac_exec_ext in '' $ac_executable_extensions; do
++ if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
++ if test $ac_prog = install &&
++ grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
++ # AIX install. It has an incompatible calling convention.
++ :
++ elif test $ac_prog = install &&
++ grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
++ # program-specific install script used by HP pwplus--don't use.
++ :
++ else
++ ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
++ break 3
++ fi
++ fi
++ done
++ done
++ ;;
++esac
++done
++
++
++fi
++ if test "${ac_cv_path_install+set}" = set; then
++ INSTALL=$ac_cv_path_install
++ else
++ # As a last resort, use the slow shell script. We don't cache a
++ # path for INSTALL within a source directory, because that will
++ # break other packages using the cache if that directory is
++ # removed, or if the path is relative.
++ INSTALL=$ac_install_sh
++ fi
++fi
++echo "$as_me:$LINENO: result: $INSTALL" >&5
++echo "${ECHO_T}$INSTALL" >&6
++
++# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
++# It thinks the first close brace ends the variable substitution.
++test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
++
++test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
++
++test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
++
++echo "$as_me:$LINENO: checking whether build environment is sane" >&5
++echo $ECHO_N "checking whether build environment is sane... $ECHO_C" >&6
++# Just in case
++sleep 1
++echo timestamp > conftestfile
++# Do `set' in a subshell so we don't clobber the current shell's
++# arguments. Must try -L first in case configure is actually a
++# symlink; some systems play weird games with the mod time of symlinks
++# (eg FreeBSD returns the mod time of the symlink's containing
++# directory).
++if (
++ set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null`
++ if test "$*" = "X"; then
++ # -L didn't work.
++ set X `ls -t $srcdir/configure conftestfile`
++ fi
++ if test "$*" != "X $srcdir/configure conftestfile" \
++ && test "$*" != "X conftestfile $srcdir/configure"; then
++
++ # If neither matched, then we have a broken ls. This can happen
++ # if, for instance, CONFIG_SHELL is bash and it inherits a
++ # broken ls alias from the environment. This has actually
++ # happened. Such a system could not be considered "sane".
++ { { echo "$as_me:$LINENO: error: ls -t appears to fail. Make sure there is not a broken
++alias in your environment" >&5
++echo "$as_me: error: ls -t appears to fail. Make sure there is not a broken
++alias in your environment" >&2;}
++ { (exit 1); exit 1; }; }
++ fi
++
++ test "$2" = conftestfile
++ )
++then
++ # Ok.
++ :
++else
++ { { echo "$as_me:$LINENO: error: newly created file is older than distributed files!
++Check your system clock" >&5
++echo "$as_me: error: newly created file is older than distributed files!
++Check your system clock" >&2;}
++ { (exit 1); exit 1; }; }
++fi
++rm -f conftest*
++echo "$as_me:$LINENO: result: yes" >&5
++echo "${ECHO_T}yes" >&6
++test "$program_prefix" != NONE &&
++ program_transform_name="s,^,$program_prefix,;$program_transform_name"
++# Use a double $ so make ignores it.
++test "$program_suffix" != NONE &&
++ program_transform_name="s,\$,$program_suffix,;$program_transform_name"
++# Double any \ or $. echo might interpret backslashes.
++# By default was `s,x,x', remove it if useless.
++cat <<\_ACEOF >conftest.sed
++s/[\\$]/&&/g;s/;s,x,x,$//
++_ACEOF
++program_transform_name=`echo $program_transform_name | sed -f conftest.sed`
++rm conftest.sed
++
++echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5
++echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6
++set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,./+-,__p_,'`
++if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ cat >conftest.make <<\_ACEOF
++all:
++ @echo 'ac_maketemp="$(MAKE)"'
++_ACEOF
++# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
++eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=`
++if test -n "$ac_maketemp"; then
++ eval ac_cv_prog_make_${ac_make}_set=yes
++else
++ eval ac_cv_prog_make_${ac_make}_set=no
++fi
++rm -f conftest.make
++fi
++if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
++ echo "$as_me:$LINENO: result: yes" >&5
++echo "${ECHO_T}yes" >&6
++ SET_MAKE=
++else
++ echo "$as_me:$LINENO: result: no" >&5
++echo "${ECHO_T}no" >&6
++ SET_MAKE="MAKE=${MAKE-make}"
++fi
++
++
++# Check whether --enable-multilib or --disable-multilib was given.
++if test "${enable_multilib+set}" = set; then
++ enableval="$enable_multilib"
++ case "${enableval}" in
++ yes) multilib=yes ;;
++ no) multilib=no ;;
++ *) { { echo "$as_me:$LINENO: error: bad value ${enableval} for multilib option" >&5
++echo "$as_me: error: bad value ${enableval} for multilib option" >&2;}
++ { (exit 1); exit 1; }; } ;;
++ esac
++else
++ multilib=yes
++fi;
++
++if test "${srcdir}" = "."; then
++ if test "${with_target_subdir}" != "." -a -n "${with_target_subdir}"; then
++ gc_basedir="${srcdir}/${with_multisrctop}../."
++ else
++ gc_basedir="${srcdir}/${with_multisrctop}."
++ fi
++else
++ gc_basedir="${srcdir}/."
++fi
++
++ac_aux_dir=
++for ac_dir in $gc_basedir/.. $srcdir/$gc_basedir/..; do
++ if test -f $ac_dir/install-sh; then
++ ac_aux_dir=$ac_dir
++ ac_install_sh="$ac_aux_dir/install-sh -c"
++ break
++ elif test -f $ac_dir/install.sh; then
++ ac_aux_dir=$ac_dir
++ ac_install_sh="$ac_aux_dir/install.sh -c"
++ break
++ elif test -f $ac_dir/shtool; then
++ ac_aux_dir=$ac_dir
++ ac_install_sh="$ac_aux_dir/shtool install -c"
++ break
++ fi
++done
++if test -z "$ac_aux_dir"; then
++ { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $gc_basedir/.. $srcdir/$gc_basedir/.." >&5
++echo "$as_me: error: cannot find install-sh or install.sh in $gc_basedir/.. $srcdir/$gc_basedir/.." >&2;}
++ { (exit 1); exit 1; }; }
++fi
++ac_config_guess="$SHELL $ac_aux_dir/config.guess"
++ac_config_sub="$SHELL $ac_aux_dir/config.sub"
++ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure.
++
++if :; then :; else
++ # This overrides the previous occurrence for automake, but not for
++ # autoconf, which is exactly what we want.
++ ac_aux_dir=
++for ac_dir in .. $srcdir/..; do
++ if test -f $ac_dir/install-sh; then
++ ac_aux_dir=$ac_dir
++ ac_install_sh="$ac_aux_dir/install-sh -c"
++ break
++ elif test -f $ac_dir/install.sh; then
++ ac_aux_dir=$ac_dir
++ ac_install_sh="$ac_aux_dir/install.sh -c"
++ break
++ elif test -f $ac_dir/shtool; then
++ ac_aux_dir=$ac_dir
++ ac_install_sh="$ac_aux_dir/shtool install -c"
++ break
++ fi
++done
++if test -z "$ac_aux_dir"; then
++ { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in .. $srcdir/.." >&5
++echo "$as_me: error: cannot find install-sh or install.sh in .. $srcdir/.." >&2;}
++ { (exit 1); exit 1; }; }
++fi
++ac_config_guess="$SHELL $ac_aux_dir/config.guess"
++ac_config_sub="$SHELL $ac_aux_dir/config.sub"
++ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure.
++
++fi
++
++echo "$as_me:$LINENO: checking target system type" >&5
++echo $ECHO_N "checking target system type... $ECHO_C" >&6
++if test "${ac_cv_target+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ ac_cv_target_alias=$target_alias
++test "x$ac_cv_target_alias" = "x" &&
++ ac_cv_target_alias=$ac_cv_host_alias
++ac_cv_target=`$ac_config_sub $ac_cv_target_alias` ||
++ { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_target_alias failed" >&5
++echo "$as_me: error: $ac_config_sub $ac_cv_target_alias failed" >&2;}
++ { (exit 1); exit 1; }; }
++
++fi
++echo "$as_me:$LINENO: result: $ac_cv_target" >&5
++echo "${ECHO_T}$ac_cv_target" >&6
++target=$ac_cv_target
++target_cpu=`echo $ac_cv_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
++target_vendor=`echo $ac_cv_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
++target_os=`echo $ac_cv_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
++
++
++# The aliases save the names the user supplied, while $host etc.
++# will get canonicalized.
++test -n "$target_alias" &&
++ test "$program_prefix$program_suffix$program_transform_name" = \
++ NONENONEs,x,x, &&
++ program_prefix=${target_alias}-
++
++# This works around an automake problem.
++mkinstalldirs="`cd $ac_aux_dir && ${PWDCMD-pwd}`/mkinstalldirs"
++
++
++
++PACKAGE=gc
++
++VERSION=6.0
++
++if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
++ { { echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5
++echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;}
++ { (exit 1); exit 1; }; }
++fi
++
++
++
++missing_dir=`cd $ac_aux_dir && pwd`
++echo "$as_me:$LINENO: checking for working aclocal" >&5
++echo $ECHO_N "checking for working aclocal... $ECHO_C" >&6
++# Run test in a subshell; some versions of sh will print an error if
++# an executable is not found, even if stderr is redirected.
++# Redirect stdin to placate older versions of autoconf. Sigh.
++if (aclocal --version) < /dev/null > /dev/null 2>&1; then
++ ACLOCAL=aclocal
++ echo "$as_me:$LINENO: result: found" >&5
++echo "${ECHO_T}found" >&6
++else
++ ACLOCAL="$missing_dir/missing aclocal"
++ echo "$as_me:$LINENO: result: missing" >&5
++echo "${ECHO_T}missing" >&6
++fi
++
++echo "$as_me:$LINENO: checking for working autoconf" >&5
++echo $ECHO_N "checking for working autoconf... $ECHO_C" >&6
++# Run test in a subshell; some versions of sh will print an error if
++# an executable is not found, even if stderr is redirected.
++# Redirect stdin to placate older versions of autoconf. Sigh.
++if (autoconf --version) < /dev/null > /dev/null 2>&1; then
++ AUTOCONF=autoconf
++ echo "$as_me:$LINENO: result: found" >&5
++echo "${ECHO_T}found" >&6
++else
++ AUTOCONF="$missing_dir/missing autoconf"
++ echo "$as_me:$LINENO: result: missing" >&5
++echo "${ECHO_T}missing" >&6
++fi
++
++echo "$as_me:$LINENO: checking for working automake" >&5
++echo $ECHO_N "checking for working automake... $ECHO_C" >&6
++# Run test in a subshell; some versions of sh will print an error if
++# an executable is not found, even if stderr is redirected.
++# Redirect stdin to placate older versions of autoconf. Sigh.
++if (automake --version) < /dev/null > /dev/null 2>&1; then
++ AUTOMAKE=automake
++ echo "$as_me:$LINENO: result: found" >&5
++echo "${ECHO_T}found" >&6
++else
++ AUTOMAKE="$missing_dir/missing automake"
++ echo "$as_me:$LINENO: result: missing" >&5
++echo "${ECHO_T}missing" >&6
++fi
++
++echo "$as_me:$LINENO: checking for working autoheader" >&5
++echo $ECHO_N "checking for working autoheader... $ECHO_C" >&6
++# Run test in a subshell; some versions of sh will print an error if
++# an executable is not found, even if stderr is redirected.
++# Redirect stdin to placate older versions of autoconf. Sigh.
++if (autoheader --version) < /dev/null > /dev/null 2>&1; then
++ AUTOHEADER=autoheader
++ echo "$as_me:$LINENO: result: found" >&5
++echo "${ECHO_T}found" >&6
++else
++ AUTOHEADER="$missing_dir/missing autoheader"
++ echo "$as_me:$LINENO: result: missing" >&5
++echo "${ECHO_T}missing" >&6
++fi
++
++echo "$as_me:$LINENO: checking for working makeinfo" >&5
++echo $ECHO_N "checking for working makeinfo... $ECHO_C" >&6
++# Run test in a subshell; some versions of sh will print an error if
++# an executable is not found, even if stderr is redirected.
++# Redirect stdin to placate older versions of autoconf. Sigh.
++if (makeinfo --version) < /dev/null > /dev/null 2>&1; then
++ MAKEINFO=makeinfo
++ echo "$as_me:$LINENO: result: found" >&5
++echo "${ECHO_T}found" >&6
++else
++ MAKEINFO="$missing_dir/missing makeinfo"
++ echo "$as_me:$LINENO: result: missing" >&5
++echo "${ECHO_T}missing" >&6
++fi
++
++
++
++# FIXME: We temporarily define our own version of AC_PROG_CC. This is
++# copied from autoconf 2.12, but does not call AC_PROG_CC_WORKS. We
++# are probably using a cross compiler, which will not be able to fully
++# link an executable. This should really be fixed in autoconf
++# itself.
++
++
++
++
++# Extract the first word of "gcc", so it can be a program name with args.
++set dummy gcc; ac_word=$2
++echo "$as_me:$LINENO: checking for $ac_word" >&5
++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
++if test "${ac_cv_prog_CC+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ if test -n "$CC"; then
++ ac_cv_prog_CC="$CC" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++ IFS=$as_save_IFS
++ test -z "$as_dir" && as_dir=.
++ for ac_exec_ext in '' $ac_executable_extensions; do
++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++ ac_cv_prog_CC="gcc"
++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
++ break 2
++ fi
++done
++done
++
++fi
++fi
++CC=$ac_cv_prog_CC
++if test -n "$CC"; then
++ echo "$as_me:$LINENO: result: $CC" >&5
++echo "${ECHO_T}$CC" >&6
++else
++ echo "$as_me:$LINENO: result: no" >&5
++echo "${ECHO_T}no" >&6
++fi
++
++if test -z "$CC"; then
++ # Extract the first word of "cc", so it can be a program name with args.
++set dummy cc; ac_word=$2
++echo "$as_me:$LINENO: checking for $ac_word" >&5
++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
++if test "${ac_cv_prog_CC+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ if test -n "$CC"; then
++ ac_cv_prog_CC="$CC" # Let the user override the test.
++else
++ ac_prog_rejected=no
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++ IFS=$as_save_IFS
++ test -z "$as_dir" && as_dir=.
++ for ac_exec_ext in '' $ac_executable_extensions; do
++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
++ ac_prog_rejected=yes
++ continue
++ fi
++ ac_cv_prog_CC="cc"
++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
++ break 2
++ fi
++done
++done
++
++if test $ac_prog_rejected = yes; then
++ # We found a bogon in the path, so make sure we never use it.
++ set dummy $ac_cv_prog_CC
++ shift
++ if test $@%:@ != 0; then
++ # We chose a different compiler from the bogus one.
++ # However, it has the same basename, so the bogon will be chosen
++ # first if we set CC to just the basename; use the full file name.
++ shift
++ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
++ fi
++fi
++fi
++fi
++CC=$ac_cv_prog_CC
++if test -n "$CC"; then
++ echo "$as_me:$LINENO: result: $CC" >&5
++echo "${ECHO_T}$CC" >&6
++else
++ echo "$as_me:$LINENO: result: no" >&5
++echo "${ECHO_T}no" >&6
++fi
++
++ test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable cc found in \$PATH" >&5
++echo "$as_me: error: no acceptable cc found in \$PATH" >&2;}
++ { (exit 1); exit 1; }; }
++fi
++
++AC_PROG_CC_GNU
++
++if test $ac_cv_c_compiler_gnu = yes; then
++ GCC=yes
++ ac_test_CFLAGS="${CFLAGS+set}"
++ ac_save_CFLAGS="$CFLAGS"
++ CFLAGS=
++ AC_PROG_CC_G
++ if test "$ac_test_CFLAGS" = set; then
++ CFLAGS="$ac_save_CFLAGS"
++ elif test $ac_cv_prog_cc_g = yes; then
++ CFLAGS="-g -O2"
++ else
++ CFLAGS="-O2"
++ fi
++else
++ GCC=
++ test "${CFLAGS+set}" = set || CFLAGS="-g"
++fi
++
++
++# Likewise for AC_PROG_CXX.
++
++
++
++for ac_prog in $CCC c++ g++ gcc CC cxx cc++
++do
++ # Extract the first word of "$ac_prog", so it can be a program name with args.
++set dummy $ac_prog; ac_word=$2
++echo "$as_me:$LINENO: checking for $ac_word" >&5
++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
++if test "${ac_cv_prog_CXX+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ if test -n "$CXX"; then
++ ac_cv_prog_CXX="$CXX" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++ IFS=$as_save_IFS
++ test -z "$as_dir" && as_dir=.
++ for ac_exec_ext in '' $ac_executable_extensions; do
++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++ ac_cv_prog_CXX="$ac_prog"
++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
++ break 2
++ fi
++done
++done
++
++fi
++fi
++CXX=$ac_cv_prog_CXX
++if test -n "$CXX"; then
++ echo "$as_me:$LINENO: result: $CXX" >&5
++echo "${ECHO_T}$CXX" >&6
++else
++ echo "$as_me:$LINENO: result: no" >&5
++echo "${ECHO_T}no" >&6
++fi
++
++ test -n "$CXX" && break
++done
++test -n "$CXX" || CXX="gcc"
++
++test -z "$CXX" && { { echo "$as_me:$LINENO: error: no acceptable c++ found in \$PATH" >&5
++echo "$as_me: error: no acceptable c++ found in \$PATH" >&2;}
++ { (exit 1); exit 1; }; }
++
++AC_PROG_CXX_GNU
++
++if test $ac_cv_cxx_compiler_gnu = yes; then
++ GXX=yes
++ ac_test_CXXFLAGS="${CXXFLAGS+set}"
++ ac_save_CXXFLAGS="$CXXFLAGS"
++ CXXFLAGS=
++ AC_PROG_CXX_G
++ if test "$ac_test_CXXFLAGS" = set; then
++ CXXFLAGS="$ac_save_CXXFLAGS"
++ elif test $ac_cv_prog_cxx_g = yes; then
++ CXXFLAGS="-g -O2"
++ else
++ CXXFLAGS="-O2"
++ fi
++else
++ GXX=
++ test "${CXXFLAGS+set}" = set || CXXFLAGS="-g"
++fi
++
++
++# AC_CHECK_TOOL does AC_REQUIRE (AC_CANONICAL_BUILD). If we don't
++# run it explicitly here, it will be run implicitly before
++# NEWLIB_CONFIGURE, which doesn't work because that means that it will
++# be run before AC_CANONICAL_HOST.
++
++
++if test -n "$ac_tool_prefix"; then
++ # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args.
++set dummy ${ac_tool_prefix}as; ac_word=$2
++echo "$as_me:$LINENO: checking for $ac_word" >&5
++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
++if test "${ac_cv_prog_AS+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ if test -n "$AS"; then
++ ac_cv_prog_AS="$AS" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++ IFS=$as_save_IFS
++ test -z "$as_dir" && as_dir=.
++ for ac_exec_ext in '' $ac_executable_extensions; do
++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++ ac_cv_prog_AS="${ac_tool_prefix}as"
++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
++ break 2
++ fi
++done
++done
++
++fi
++fi
++AS=$ac_cv_prog_AS
++if test -n "$AS"; then
++ echo "$as_me:$LINENO: result: $AS" >&5
++echo "${ECHO_T}$AS" >&6
++else
++ echo "$as_me:$LINENO: result: no" >&5
++echo "${ECHO_T}no" >&6
++fi
++
++fi
++if test -z "$ac_cv_prog_AS"; then
++ ac_ct_AS=$AS
++ # Extract the first word of "as", so it can be a program name with args.
++set dummy as; ac_word=$2
++echo "$as_me:$LINENO: checking for $ac_word" >&5
++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
++if test "${ac_cv_prog_ac_ct_AS+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ if test -n "$ac_ct_AS"; then
++ ac_cv_prog_ac_ct_AS="$ac_ct_AS" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++ IFS=$as_save_IFS
++ test -z "$as_dir" && as_dir=.
++ for ac_exec_ext in '' $ac_executable_extensions; do
++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++ ac_cv_prog_ac_ct_AS="as"
++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
++ break 2
++ fi
++done
++done
++
++fi
++fi
++ac_ct_AS=$ac_cv_prog_ac_ct_AS
++if test -n "$ac_ct_AS"; then
++ echo "$as_me:$LINENO: result: $ac_ct_AS" >&5
++echo "${ECHO_T}$ac_ct_AS" >&6
++else
++ echo "$as_me:$LINENO: result: no" >&5
++echo "${ECHO_T}no" >&6
++fi
++
++ AS=$ac_ct_AS
++else
++ AS="$ac_cv_prog_AS"
++fi
++
++if test -n "$ac_tool_prefix"; then
++ # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
++set dummy ${ac_tool_prefix}ar; ac_word=$2
++echo "$as_me:$LINENO: checking for $ac_word" >&5
++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
++if test "${ac_cv_prog_AR+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ if test -n "$AR"; then
++ ac_cv_prog_AR="$AR" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++ IFS=$as_save_IFS
++ test -z "$as_dir" && as_dir=.
++ for ac_exec_ext in '' $ac_executable_extensions; do
++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++ ac_cv_prog_AR="${ac_tool_prefix}ar"
++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
++ break 2
++ fi
++done
++done
++
++fi
++fi
++AR=$ac_cv_prog_AR
++if test -n "$AR"; then
++ echo "$as_me:$LINENO: result: $AR" >&5
++echo "${ECHO_T}$AR" >&6
++else
++ echo "$as_me:$LINENO: result: no" >&5
++echo "${ECHO_T}no" >&6
++fi
++
++fi
++if test -z "$ac_cv_prog_AR"; then
++ ac_ct_AR=$AR
++ # Extract the first word of "ar", so it can be a program name with args.
++set dummy ar; ac_word=$2
++echo "$as_me:$LINENO: checking for $ac_word" >&5
++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
++if test "${ac_cv_prog_ac_ct_AR+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ if test -n "$ac_ct_AR"; then
++ ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++ IFS=$as_save_IFS
++ test -z "$as_dir" && as_dir=.
++ for ac_exec_ext in '' $ac_executable_extensions; do
++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++ ac_cv_prog_ac_ct_AR="ar"
++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
++ break 2
++ fi
++done
++done
++
++fi
++fi
++ac_ct_AR=$ac_cv_prog_ac_ct_AR
++if test -n "$ac_ct_AR"; then
++ echo "$as_me:$LINENO: result: $ac_ct_AR" >&5
++echo "${ECHO_T}$ac_ct_AR" >&6
++else
++ echo "$as_me:$LINENO: result: no" >&5
++echo "${ECHO_T}no" >&6
++fi
++
++ AR=$ac_ct_AR
++else
++ AR="$ac_cv_prog_AR"
++fi
++
++if test -n "$ac_tool_prefix"; then
++ # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
++set dummy ${ac_tool_prefix}ranlib; ac_word=$2
++echo "$as_me:$LINENO: checking for $ac_word" >&5
++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
++if test "${ac_cv_prog_RANLIB+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ if test -n "$RANLIB"; then
++ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++ IFS=$as_save_IFS
++ test -z "$as_dir" && as_dir=.
++ for ac_exec_ext in '' $ac_executable_extensions; do
++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++ ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
++ break 2
++ fi
++done
++done
++
++fi
++fi
++RANLIB=$ac_cv_prog_RANLIB
++if test -n "$RANLIB"; then
++ echo "$as_me:$LINENO: result: $RANLIB" >&5
++echo "${ECHO_T}$RANLIB" >&6
++else
++ echo "$as_me:$LINENO: result: no" >&5
++echo "${ECHO_T}no" >&6
++fi
++
++fi
++if test -z "$ac_cv_prog_RANLIB"; then
++ ac_ct_RANLIB=$RANLIB
++ # Extract the first word of "ranlib", so it can be a program name with args.
++set dummy ranlib; ac_word=$2
++echo "$as_me:$LINENO: checking for $ac_word" >&5
++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
++if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ if test -n "$ac_ct_RANLIB"; then
++ ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++ IFS=$as_save_IFS
++ test -z "$as_dir" && as_dir=.
++ for ac_exec_ext in '' $ac_executable_extensions; do
++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++ ac_cv_prog_ac_ct_RANLIB="ranlib"
++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
++ break 2
++ fi
++done
++done
++
++ test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":"
++fi
++fi
++ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
++if test -n "$ac_ct_RANLIB"; then
++ echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5
++echo "${ECHO_T}$ac_ct_RANLIB" >&6
++else
++ echo "$as_me:$LINENO: result: no" >&5
++echo "${ECHO_T}no" >&6
++fi
++
++ RANLIB=$ac_ct_RANLIB
++else
++ RANLIB="$ac_cv_prog_RANLIB"
++fi
++
++
++# Find a good install program. We prefer a C program (faster),
++# so one script is as good as another. But avoid the broken or
++# incompatible versions:
++# SysV /etc/install, /usr/sbin/install
++# SunOS /usr/etc/install
++# IRIX /sbin/install
++# AIX /bin/install
++# AmigaOS /C/install, which installs bootblocks on floppy discs
++# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
++# AFS /usr/afsws/bin/install, which mishandles nonexistent args
++# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
++# ./install, which can be erroneously created by make from ./install.sh.
++echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
++echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6
++if test -z "$INSTALL"; then
++if test "${ac_cv_path_install+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++ IFS=$as_save_IFS
++ test -z "$as_dir" && as_dir=.
++ # Account for people who put trailing slashes in PATH elements.
++case $as_dir/ in
++ ./ | .// | /cC/* | \
++ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
++ /usr/ucb/* ) ;;
++ *)
++ # OSF1 and SCO ODT 3.0 have their own names for install.
++ # Don't use installbsd from OSF since it installs stuff as root
++ # by default.
++ for ac_prog in ginstall scoinst install; do
++ for ac_exec_ext in '' $ac_executable_extensions; do
++ if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
++ if test $ac_prog = install &&
++ grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
++ # AIX install. It has an incompatible calling convention.
++ :
++ elif test $ac_prog = install &&
++ grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
++ # program-specific install script used by HP pwplus--don't use.
++ :
++ else
++ ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
++ break 3
++ fi
++ fi
++ done
++ done
++ ;;
++esac
++done
++
++
++fi
++ if test "${ac_cv_path_install+set}" = set; then
++ INSTALL=$ac_cv_path_install
++ else
++ # As a last resort, use the slow shell script. We don't cache a
++ # path for INSTALL within a source directory, because that will
++ # break other packages using the cache if that directory is
++ # removed, or if the path is relative.
++ INSTALL=$ac_install_sh
++ fi
++fi
++echo "$as_me:$LINENO: result: $INSTALL" >&5
++echo "${ECHO_T}$INSTALL" >&6
++
++# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
++# It thinks the first close brace ends the variable substitution.
++test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
++
++test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
++
++test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
++
++
++echo "$as_me:$LINENO: checking whether to enable maintainer-specific portions of Makefiles" >&5
++echo $ECHO_N "checking whether to enable maintainer-specific portions of Makefiles... $ECHO_C" >&6
++ # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given.
++if test "${enable_maintainer_mode+set}" = set; then
++ enableval="$enable_maintainer_mode"
++ USE_MAINTAINER_MODE=$enableval
++else
++ USE_MAINTAINER_MODE=no
++fi;
++ echo "$as_me:$LINENO: result: $USE_MAINTAINER_MODE" >&5
++echo "${ECHO_T}$USE_MAINTAINER_MODE" >&6
++
++
++if test $USE_MAINTAINER_MODE = yes; then
++ MAINTAINER_MODE_TRUE=
++ MAINTAINER_MODE_FALSE='#'
++else
++ MAINTAINER_MODE_TRUE='#'
++ MAINTAINER_MODE_FALSE=
++fi
++ MAINT=$MAINTAINER_MODE_TRUE
++
++
++
++# We need AC_EXEEXT to keep automake happy in cygnus mode. However,
++# at least currently, we never actually build a program, so we never
++# need to use $(EXEEXT). Moreover, the test for EXEEXT normally
++# fails, because we are probably configuring with a cross compiler
++# which can't create executables. So we include AC_EXEEXT to keep
++# automake happy, but we don't execute it, since we don't care about
++# the result.
++if false; then
++ # autoconf 2.50 runs AC_EXEEXT by default, and the macro expands
++ # to nothing, so nothing would remain between `then' and `fi' if it
++ # were not for the `:' below.
++ :
++
++fi
++
++. ${srcdir}/configure.host
++
++case ${gc_basedir} in
++/* | A-Za-z:/\\*) gc_flagbasedir=${gc_basedir} ;;
++*) gc_flagbasedir='$(top_builddir)/'${gc_basedir} ;;
++esac
++
++gc_cflags="${gc_cflags} -I"'$(top_builddir)'"/./targ-include -I${gc_flagbasedir}/libc/include"
++case "${host}" in
++ *-*-cygwin32*)
++ gc_cflags="${gc_cflags} -I${gc_flagbasedir}/../winsup/include"
++ ;;
++esac
++
++
++GC_CFLAGS=${gc_cflags}
++
++
++
++# Check whether --enable-shared or --disable-shared was given.
++if test "${enable_shared+set}" = set; then
++ enableval="$enable_shared"
++ p=${PACKAGE-default}
++case $enableval in
++yes) enable_shared=yes ;;
++no) enable_shared=no ;;
++*)
++ enable_shared=no
++ # Look at the argument we got. We use all the common list separators.
++ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
++ for pkg in $enableval; do
++ if test "X$pkg" = "X$p"; then
++ enable_shared=yes
++ fi
++ done
++ IFS="$ac_save_ifs"
++ ;;
++esac
++else
++ enable_shared=yes
++fi;
++# Check whether --enable-static or --disable-static was given.
++if test "${enable_static+set}" = set; then
++ enableval="$enable_static"
++ p=${PACKAGE-default}
++case $enableval in
++yes) enable_static=yes ;;
++no) enable_static=no ;;
++*)
++ enable_static=no
++ # Look at the argument we got. We use all the common list separators.
++ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
++ for pkg in $enableval; do
++ if test "X$pkg" = "X$p"; then
++ enable_static=yes
++ fi
++ done
++ IFS="$ac_save_ifs"
++ ;;
++esac
++else
++ enable_static=yes
++fi;
++# Check whether --enable-fast-install or --disable-fast-install was given.
++if test "${enable_fast_install+set}" = set; then
++ enableval="$enable_fast_install"
++ p=${PACKAGE-default}
++case $enableval in
++yes) enable_fast_install=yes ;;
++no) enable_fast_install=no ;;
++*)
++ enable_fast_install=no
++ # Look at the argument we got. We use all the common list separators.
++ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
++ for pkg in $enableval; do
++ if test "X$pkg" = "X$p"; then
++ enable_fast_install=yes
++ fi
++ done
++ IFS="$ac_save_ifs"
++ ;;
++esac
++else
++ enable_fast_install=yes
++fi;
++
++# Check whether --with-gnu-ld or --without-gnu-ld was given.
++if test "${with_gnu_ld+set}" = set; then
++ withval="$with_gnu_ld"
++ test "$withval" = no || with_gnu_ld=yes
++else
++ with_gnu_ld=no
++fi;
++ac_prog=ld
++if test "$GCC" = yes; then
++ # Check if gcc -print-prog-name=ld gives a path.
++ echo "$as_me:$LINENO: checking for ld used by GCC" >&5
++echo $ECHO_N "checking for ld used by GCC... $ECHO_C" >&6
++ case $host in
++ *-*-mingw*)
++ # gcc leaves a trailing carriage return which upsets mingw
++ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
++ *)
++ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
++ esac
++ case $ac_prog in
++ # Accept absolute paths.
++ [\\/]* | [A-Za-z]:[\\/]*)
++ re_direlt='/[^/][^/]*/\.\./'
++ # Canonicalize the path of ld
++ ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
++ while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
++ ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
++ done
++ test -z "$LD" && LD="$ac_prog"
++ ;;
++ "")
++ # If it fails, then pretend we aren't using GCC.
++ ac_prog=ld
++ ;;
++ *)
++ # If it is relative, then search for the first ld in PATH.
++ with_gnu_ld=unknown
++ ;;
++ esac
++elif test "$with_gnu_ld" = yes; then
++ echo "$as_me:$LINENO: checking for GNU ld" >&5
++echo $ECHO_N "checking for GNU ld... $ECHO_C" >&6
++else
++ echo "$as_me:$LINENO: checking for non-GNU ld" >&5
++echo $ECHO_N "checking for non-GNU ld... $ECHO_C" >&6
++fi
++if test "${lt_cv_path_LD+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ if test -z "$LD"; then
++ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
++ for ac_dir in $PATH; do
++ test -z "$ac_dir" && ac_dir=.
++ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
++ lt_cv_path_LD="$ac_dir/$ac_prog"
++ # Check to see if the program is GNU ld. I'd rather use --version,
++ # but apparently some GNU ld's only accept -v.
++ # Break only if it was the GNU/non-GNU ld that we prefer.
++ if "$lt_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
++ test "$with_gnu_ld" != no && break
++ else
++ test "$with_gnu_ld" != yes && break
++ fi
++ fi
++ done
++ IFS="$ac_save_ifs"
++else
++ lt_cv_path_LD="$LD" # Let the user override the test with a path.
++fi
++fi
++
++LD="$lt_cv_path_LD"
++if test -n "$LD"; then
++ echo "$as_me:$LINENO: result: $LD" >&5
++echo "${ECHO_T}$LD" >&6
++else
++ echo "$as_me:$LINENO: result: no" >&5
++echo "${ECHO_T}no" >&6
++fi
++test -z "$LD" && { { echo "$as_me:$LINENO: error: no acceptable ld found in \$PATH" >&5
++echo "$as_me: error: no acceptable ld found in \$PATH" >&2;}
++ { (exit 1); exit 1; }; }
++echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5
++echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6
++if test "${lt_cv_prog_gnu_ld+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ # I'd rather use --version here, but apparently some GNU ld's only accept -v.
++if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
++ lt_cv_prog_gnu_ld=yes
++else
++ lt_cv_prog_gnu_ld=no
++fi
++fi
++echo "$as_me:$LINENO: result: $lt_cv_prog_gnu_ld" >&5
++echo "${ECHO_T}$lt_cv_prog_gnu_ld" >&6
++with_gnu_ld=$lt_cv_prog_gnu_ld
++
++
++echo "$as_me:$LINENO: checking for $LD option to reload object files" >&5
++echo $ECHO_N "checking for $LD option to reload object files... $ECHO_C" >&6
++if test "${lt_cv_ld_reload_flag+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ lt_cv_ld_reload_flag='-r'
++fi
++echo "$as_me:$LINENO: result: $lt_cv_ld_reload_flag" >&5
++echo "${ECHO_T}$lt_cv_ld_reload_flag" >&6
++reload_flag=$lt_cv_ld_reload_flag
++test -n "$reload_flag" && reload_flag=" $reload_flag"
++
++echo "$as_me:$LINENO: checking for BSD-compatible nm" >&5
++echo $ECHO_N "checking for BSD-compatible nm... $ECHO_C" >&6
++if test "${lt_cv_path_NM+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ if test -n "$NM"; then
++ # Let the user override the test.
++ lt_cv_path_NM="$NM"
++else
++ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
++ for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do
++ test -z "$ac_dir" && ac_dir=.
++ tmp_nm=$ac_dir/${ac_tool_prefix}nm
++ if test -f $tmp_nm || test -f $tmp_nm$ac_exeext ; then
++ # Check to see if the nm accepts a BSD-compat flag.
++ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
++ # nm: unknown option "B" ignored
++ # Tru64's nm complains that /dev/null is an invalid object file
++ if ($tmp_nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep '(/dev/null|Invalid file or object type)' >/dev/null; then
++ lt_cv_path_NM="$tmp_nm -B"
++ break
++ elif ($tmp_nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
++ lt_cv_path_NM="$tmp_nm -p"
++ break
++ else
++ lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
++ continue # so that we can try to find one that supports BSD flags
++ fi
++ fi
++ done
++ IFS="$ac_save_ifs"
++ test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm
++fi
++fi
++
++NM="$lt_cv_path_NM"
++echo "$as_me:$LINENO: result: $NM" >&5
++echo "${ECHO_T}$NM" >&6
++
++echo "$as_me:$LINENO: checking whether ln -s works" >&5
++echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6
++LN_S=$as_ln_s
++if test "$LN_S" = "ln -s"; then
++ echo "$as_me:$LINENO: result: yes" >&5
++echo "${ECHO_T}yes" >&6
++else
++ echo "$as_me:$LINENO: result: no, using $LN_S" >&5
++echo "${ECHO_T}no, using $LN_S" >&6
++fi
++
++echo "$as_me:$LINENO: checking how to recognise dependant libraries" >&5
++echo $ECHO_N "checking how to recognise dependant libraries... $ECHO_C" >&6
++if test "${lt_cv_deplibs_check_method+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ lt_cv_file_magic_cmd='$MAGIC_CMD'
++lt_cv_file_magic_test_file=
++lt_cv_deplibs_check_method='unknown'
++# Need to set the preceding variable on all platforms that support
++# interlibrary dependencies.
++# 'none' -- dependencies not supported.
++# `unknown' -- same as none, but documents that we really don't know.
++# 'pass_all' -- all dependencies passed with no checks.
++# 'test_compile' -- check by making test program.
++# 'file_magic [regex]' -- check by looking for files in library path
++# which responds to the $file_magic_cmd with a given egrep regex.
++# If you have `file' or equivalent on your system and you're not sure
++# whether `pass_all' will *always* work, you probably want this one.
++
++case $host_os in
++aix*)
++ lt_cv_deplibs_check_method=pass_all
++ ;;
++
++beos*)
++ lt_cv_deplibs_check_method=pass_all
++ ;;
++
++bsdi4*)
++ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'
++ lt_cv_file_magic_cmd='/usr/bin/file -L'
++ lt_cv_file_magic_test_file=/shlib/libc.so
++ ;;
++
++cygwin* | mingw* |pw32*)
++ lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
++ lt_cv_file_magic_cmd='$OBJDUMP -f'
++ ;;
++
++darwin* | rhapsody*)
++ lt_cv_deplibs_check_method='file_magic Mach-O dynamically linked shared library'
++ lt_cv_file_magic_cmd='/usr/bin/file -L'
++ case "$host_os" in
++ rhapsody* | darwin1.012)
++ lt_cv_file_magic_test_file='/System/Library/Frameworks/System.framework/System'
++ ;;
++ *) # Darwin 1.3 on
++ lt_cv_file_magic_test_file='/usr/lib/libSystem.dylib'
++ ;;
++ esac
++ ;;
++
++freebsd* )
++ if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
++ case $host_cpu in
++ i*86 )
++ # Not sure whether the presence of OpenBSD here was a mistake.
++ # Let's accept both of them until this is cleared up.
++ lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD)/i[3-9]86 (compact )?demand paged shared library'
++ lt_cv_file_magic_cmd=/usr/bin/file
++ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
++ ;;
++ esac
++ else
++ lt_cv_deplibs_check_method=pass_all
++ fi
++ ;;
++
++gnu*)
++ lt_cv_deplibs_check_method=pass_all
++ ;;
++
++hpux10.20*|hpux11*)
++ case $host_cpu in
++ hppa*)
++ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library'
++ lt_cv_file_magic_cmd=/usr/bin/file
++ lt_cv_file_magic_test_file=/usr/lib/libc.sl
++ ;;
++ ia64*)
++ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64'
++ lt_cv_file_magic_cmd=/usr/bin/file
++ lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
++ ;;
++ esac
++ ;;
++
++irix5* | irix6*)
++ case $host_os in
++ irix5*)
++ # this will be overridden with pass_all, but let us keep it just in case
++ lt_cv_deplibs_check_method="file_magic ELF 32-bit MSB dynamic lib MIPS - version 1"
++ ;;
++ *)
++ case $LD in
++ *-32|*"-32 ") libmagic=32-bit;;
++ *-n32|*"-n32 ") libmagic=N32;;
++ *-64|*"-64 ") libmagic=64-bit;;
++ *) libmagic=never-match;;
++ esac
++ # this will be overridden with pass_all, but let us keep it just in case
++ lt_cv_deplibs_check_method="file_magic ELF ${libmagic} MSB mips-[1234] dynamic lib MIPS - version 1"
++ ;;
++ esac
++ lt_cv_file_magic_test_file=`echo /lib${libsuff}/libc.so*`
++ lt_cv_deplibs_check_method=pass_all
++ ;;
++
++# This must be Linux ELF.
++linux-gnu*)
++ case $host_cpu in
++ alpha* | hppa* | i*86 | powerpc* | sparc* | ia64* )
++ lt_cv_deplibs_check_method=pass_all ;;
++ *)
++ # glibc up to 2.1.1 does not perform some relocations on ARM
++ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' ;;
++ esac
++ lt_cv_file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so`
++ ;;
++
++netbsd*)
++ if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
++ lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so\.[0-9]+\.[0-9]+$'
++ else
++ lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so$'
++ fi
++ ;;
++
++newsos6)
++ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)'
++ lt_cv_file_magic_cmd=/usr/bin/file
++ lt_cv_file_magic_test_file=/usr/lib/libnls.so
++ ;;
++
++osf3* | osf4* | osf5*)
++ # this will be overridden with pass_all, but let us keep it just in case
++ lt_cv_deplibs_check_method='file_magic COFF format alpha shared library'
++ lt_cv_file_magic_test_file=/shlib/libc.so
++ lt_cv_deplibs_check_method=pass_all
++ ;;
++
++sco3.2v5*)
++ lt_cv_deplibs_check_method=pass_all
++ ;;
++
++solaris*)
++ lt_cv_deplibs_check_method=pass_all
++ lt_cv_file_magic_test_file=/lib/libc.so
++ ;;
++
++sysv5uw[78]* | sysv4*uw2*)
++ lt_cv_deplibs_check_method=pass_all
++ ;;
++
++sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
++ case $host_vendor in
++ ncr)
++ lt_cv_deplibs_check_method=pass_all
++ ;;
++ motorola)
++ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'
++ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
++ ;;
++ esac
++ ;;
++esac
++
++fi
++echo "$as_me:$LINENO: result: $lt_cv_deplibs_check_method" >&5
++echo "${ECHO_T}$lt_cv_deplibs_check_method" >&6
++file_magic_cmd=$lt_cv_file_magic_cmd
++deplibs_check_method=$lt_cv_deplibs_check_method
++
++
++
++
++# Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers!
++
++# Only perform the check for file, if the check method requires it
++case $deplibs_check_method in
++file_magic*)
++ if test "$file_magic_cmd" = '$MAGIC_CMD'; then
++ echo "$as_me:$LINENO: checking for ${ac_tool_prefix}file" >&5
++echo $ECHO_N "checking for ${ac_tool_prefix}file... $ECHO_C" >&6
++if test "${lt_cv_path_MAGIC_CMD+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ case $MAGIC_CMD in
++ /*)
++ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
++ ;;
++ ?:/*)
++ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a dos path.
++ ;;
++ *)
++ ac_save_MAGIC_CMD="$MAGIC_CMD"
++ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
++ ac_dummy="/usr/bin:$PATH"
++ for ac_dir in $ac_dummy; do
++ test -z "$ac_dir" && ac_dir=.
++ if test -f $ac_dir/${ac_tool_prefix}file; then
++ lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file"
++ if test -n "$file_magic_test_file"; then
++ case $deplibs_check_method in
++ "file_magic "*)
++ file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`"
++ MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
++ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
++ egrep "$file_magic_regex" > /dev/null; then
++ :
++ else
++ cat <<EOF 1>&2
++
++*** Warning: the command libtool uses to detect shared libraries,
++*** $file_magic_cmd, produces output that libtool cannot recognize.
++*** The result is that libtool may fail to recognize shared libraries
++*** as such. This will affect the creation of libtool libraries that
++*** depend on shared libraries, but programs linked with such libtool
++*** libraries will work regardless of this problem. Nevertheless, you
++*** may want to report the problem to your system manager and/or to
++*** bug-libtool@gnu.org
++
++EOF
++ fi ;;
++ esac
++ fi
++ break
++ fi
++ done
++ IFS="$ac_save_ifs"
++ MAGIC_CMD="$ac_save_MAGIC_CMD"
++ ;;
++esac
++fi
++
++MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
++if test -n "$MAGIC_CMD"; then
++ echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5
++echo "${ECHO_T}$MAGIC_CMD" >&6
++else
++ echo "$as_me:$LINENO: result: no" >&5
++echo "${ECHO_T}no" >&6
++fi
++
++if test -z "$lt_cv_path_MAGIC_CMD"; then
++ if test -n "$ac_tool_prefix"; then
++ echo "$as_me:$LINENO: checking for file" >&5
++echo $ECHO_N "checking for file... $ECHO_C" >&6
++if test "${lt_cv_path_MAGIC_CMD+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ case $MAGIC_CMD in
++ /*)
++ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
++ ;;
++ ?:/*)
++ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a dos path.
++ ;;
++ *)
++ ac_save_MAGIC_CMD="$MAGIC_CMD"
++ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
++ ac_dummy="/usr/bin:$PATH"
++ for ac_dir in $ac_dummy; do
++ test -z "$ac_dir" && ac_dir=.
++ if test -f $ac_dir/file; then
++ lt_cv_path_MAGIC_CMD="$ac_dir/file"
++ if test -n "$file_magic_test_file"; then
++ case $deplibs_check_method in
++ "file_magic "*)
++ file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`"
++ MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
++ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
++ egrep "$file_magic_regex" > /dev/null; then
++ :
++ else
++ cat <<EOF 1>&2
++
++*** Warning: the command libtool uses to detect shared libraries,
++*** $file_magic_cmd, produces output that libtool cannot recognize.
++*** The result is that libtool may fail to recognize shared libraries
++*** as such. This will affect the creation of libtool libraries that
++*** depend on shared libraries, but programs linked with such libtool
++*** libraries will work regardless of this problem. Nevertheless, you
++*** may want to report the problem to your system manager and/or to
++*** bug-libtool@gnu.org
++
++EOF
++ fi ;;
++ esac
++ fi
++ break
++ fi
++ done
++ IFS="$ac_save_ifs"
++ MAGIC_CMD="$ac_save_MAGIC_CMD"
++ ;;
++esac
++fi
++
++MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
++if test -n "$MAGIC_CMD"; then
++ echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5
++echo "${ECHO_T}$MAGIC_CMD" >&6
++else
++ echo "$as_me:$LINENO: result: no" >&5
++echo "${ECHO_T}no" >&6
++fi
++
++ else
++ MAGIC_CMD=:
++ fi
++fi
++
++ fi
++ ;;
++esac
++
++if test -n "$ac_tool_prefix"; then
++ # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
++set dummy ${ac_tool_prefix}ranlib; ac_word=$2
++echo "$as_me:$LINENO: checking for $ac_word" >&5
++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
++if test "${ac_cv_prog_RANLIB+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ if test -n "$RANLIB"; then
++ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++ IFS=$as_save_IFS
++ test -z "$as_dir" && as_dir=.
++ for ac_exec_ext in '' $ac_executable_extensions; do
++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++ ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
++ break 2
++ fi
++done
++done
++
++fi
++fi
++RANLIB=$ac_cv_prog_RANLIB
++if test -n "$RANLIB"; then
++ echo "$as_me:$LINENO: result: $RANLIB" >&5
++echo "${ECHO_T}$RANLIB" >&6
++else
++ echo "$as_me:$LINENO: result: no" >&5
++echo "${ECHO_T}no" >&6
++fi
++
++fi
++if test -z "$ac_cv_prog_RANLIB"; then
++ ac_ct_RANLIB=$RANLIB
++ # Extract the first word of "ranlib", so it can be a program name with args.
++set dummy ranlib; ac_word=$2
++echo "$as_me:$LINENO: checking for $ac_word" >&5
++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
++if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ if test -n "$ac_ct_RANLIB"; then
++ ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++ IFS=$as_save_IFS
++ test -z "$as_dir" && as_dir=.
++ for ac_exec_ext in '' $ac_executable_extensions; do
++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++ ac_cv_prog_ac_ct_RANLIB="ranlib"
++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
++ break 2
++ fi
++done
++done
++
++ test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":"
++fi
++fi
++ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
++if test -n "$ac_ct_RANLIB"; then
++ echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5
++echo "${ECHO_T}$ac_ct_RANLIB" >&6
++else
++ echo "$as_me:$LINENO: result: no" >&5
++echo "${ECHO_T}no" >&6
++fi
++
++ RANLIB=$ac_ct_RANLIB
++else
++ RANLIB="$ac_cv_prog_RANLIB"
++fi
++
++if test -n "$ac_tool_prefix"; then
++ # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
++set dummy ${ac_tool_prefix}strip; ac_word=$2
++echo "$as_me:$LINENO: checking for $ac_word" >&5
++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
++if test "${ac_cv_prog_STRIP+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ if test -n "$STRIP"; then
++ ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++ IFS=$as_save_IFS
++ test -z "$as_dir" && as_dir=.
++ for ac_exec_ext in '' $ac_executable_extensions; do
++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++ ac_cv_prog_STRIP="${ac_tool_prefix}strip"
++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
++ break 2
++ fi
++done
++done
++
++fi
++fi
++STRIP=$ac_cv_prog_STRIP
++if test -n "$STRIP"; then
++ echo "$as_me:$LINENO: result: $STRIP" >&5
++echo "${ECHO_T}$STRIP" >&6
++else
++ echo "$as_me:$LINENO: result: no" >&5
++echo "${ECHO_T}no" >&6
++fi
++
++fi
++if test -z "$ac_cv_prog_STRIP"; then
++ ac_ct_STRIP=$STRIP
++ # Extract the first word of "strip", so it can be a program name with args.
++set dummy strip; ac_word=$2
++echo "$as_me:$LINENO: checking for $ac_word" >&5
++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
++if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ if test -n "$ac_ct_STRIP"; then
++ ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++ IFS=$as_save_IFS
++ test -z "$as_dir" && as_dir=.
++ for ac_exec_ext in '' $ac_executable_extensions; do
++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++ ac_cv_prog_ac_ct_STRIP="strip"
++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
++ break 2
++ fi
++done
++done
++
++ test -z "$ac_cv_prog_ac_ct_STRIP" && ac_cv_prog_ac_ct_STRIP=":"
++fi
++fi
++ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
++if test -n "$ac_ct_STRIP"; then
++ echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5
++echo "${ECHO_T}$ac_ct_STRIP" >&6
++else
++ echo "$as_me:$LINENO: result: no" >&5
++echo "${ECHO_T}no" >&6
++fi
++
++ STRIP=$ac_ct_STRIP
++else
++ STRIP="$ac_cv_prog_STRIP"
++fi
++
++
++# Check for any special flags to pass to ltconfig.
++libtool_flags="--cache-file=$cache_file"
++test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared"
++test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static"
++test "$enable_fast_install" = no && libtool_flags="$libtool_flags --disable-fast-install"
++test "$GCC" = yes && libtool_flags="$libtool_flags --with-gcc"
++test "$lt_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld"
++
++
++# Check whether --enable-libtool-lock or --disable-libtool-lock was given.
++if test "${enable_libtool_lock+set}" = set; then
++ enableval="$enable_libtool_lock"
++
++fi;
++test "x$enable_libtool_lock" = xno && libtool_flags="$libtool_flags --disable-lock"
++test x"$silent" = xyes && libtool_flags="$libtool_flags --silent"
++
++
++# Check whether --with-pic or --without-pic was given.
++if test "${with_pic+set}" = set; then
++ withval="$with_pic"
++ pic_mode="$withval"
++else
++ pic_mode=default
++fi;
++test x"$pic_mode" = xyes && libtool_flags="$libtool_flags --prefer-pic"
++test x"$pic_mode" = xno && libtool_flags="$libtool_flags --prefer-non-pic"
++
++# Some flags need to be propagated to the compiler or linker for good
++# libtool support.
++case $host in
++*-*-irix6*)
++ # Find out which ABI we are using.
++ echo '#line __oline__ "configure"' > conftest.$ac_ext
++ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
++ (eval $ac_compile) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); }; then
++ case `/usr/bin/file conftest.$ac_objext` in
++ *32-bit*)
++ LD="${LD-ld} -32"
++ ;;
++ *N32*)
++ LD="${LD-ld} -n32"
++ ;;
++ *64-bit*)
++ LD="${LD-ld} -64"
++ ;;
++ esac
++ fi
++ rm -rf conftest*
++ ;;
++
++ia64-*-hpux*)
++ # Find out which ABI we are using.
++ echo 'int i;' > conftest.$ac_ext
++ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
++ (eval $ac_compile) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); }; then
++ case "`/usr/bin/file conftest.o`" in
++ *ELF-32*)
++ HPUX_IA64_MODE="32"
++ ;;
++ *ELF-64*)
++ HPUX_IA64_MODE="64"
++ ;;
++ esac
++ fi
++ rm -rf conftest*
++ ;;
++
++x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*)
++ # Find out which ABI we are using.
++ echo 'int i;' > conftest.$ac_ext
++ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
++ (eval $ac_compile) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); }; then
++ case "`/usr/bin/file conftest.o`" in
++ *32-bit*)
++ case $host in
++ x86_64-*linux*)
++ LD="${LD-ld} -m elf_i386"
++ ;;
++ ppc64-*linux*)
++ LD="${LD-ld} -m elf32ppclinux"
++ ;;
++ s390x-*linux*)
++ LD="${LD-ld} -m elf_s390"
++ ;;
++ sparc64-*linux*)
++ LD="${LD-ld} -m elf32_sparc"
++ ;;
++ esac
++ ;;
++ *64-bit*)
++ case $host in
++ x86_64-*linux*)
++ LD="${LD-ld} -m elf_x86_64"
++ ;;
++ ppc*-*linux*|powerpc*-*linux*)
++ LD="${LD-ld} -m elf64ppc"
++ ;;
++ s390*-*linux*)
++ LD="${LD-ld} -m elf64_s390"
++ ;;
++ sparc*-*linux*)
++ LD="${LD-ld} -m elf64_sparc"
++ ;;
++ esac
++ ;;
++ esac
++ fi
++ rm -rf conftest*
++ ;;
++
++*-*-sco3.2v5*)
++ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
++ SAVE_CFLAGS="$CFLAGS"
++ CFLAGS="$CFLAGS -belf"
++ echo "$as_me:$LINENO: checking whether the C compiler needs -belf" >&5
++echo $ECHO_N "checking whether the C compiler needs -belf... $ECHO_C" >&6
++if test "${lt_cv_cc_needs_belf+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++
++
++ ac_ext=c
++ac_cpp='$CPP $CPPFLAGS'
++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
++ac_compiler_gnu=$ac_cv_c_compiler_gnu
++
++ cat >conftest.$ac_ext <<_ACEOF
++#line $LINENO "configure"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
++
++int
++main ()
++{
++
++ ;
++ return 0;
++}
++_ACEOF
++rm -f conftest.$ac_objext conftest$ac_exeext
++if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
++ (eval $ac_link) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); } &&
++ { ac_try='test -s conftest$ac_exeext'
++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++ (eval $ac_try) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); }; }; then
++ lt_cv_cc_needs_belf=yes
++else
++ echo "$as_me: failed program was:" >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
++lt_cv_cc_needs_belf=no
++fi
++rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
++ ac_ext=c
++ac_cpp='$CPP $CPPFLAGS'
++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
++ac_compiler_gnu=$ac_cv_c_compiler_gnu
++
++fi
++echo "$as_me:$LINENO: result: $lt_cv_cc_needs_belf" >&5
++echo "${ECHO_T}$lt_cv_cc_needs_belf" >&6
++ if test x"$lt_cv_cc_needs_belf" != x"yes"; then
++ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
++ CFLAGS="$SAVE_CFLAGS"
++ fi
++ ;;
++
++
++esac
++
++
++# Save cache, so that ltconfig can load it
++cat >confcache <<\_ACEOF
++# This file is a shell script that caches the results of configure
++# tests run on this system so they can be shared between configure
++# scripts and configure runs, see configure's option --config-cache.
++# It is not useful on other systems. If it contains results you don't
++# want to keep, you may remove or edit it.
++#
++# config.status only pays attention to the cache file if you give it
++# the --recheck option to rerun configure.
++#
++# `ac_cv_env_foo' variables (set or unset) will be overridden when
++# loading this file, other *unset* `ac_cv_foo' will be assigned the
++# following values.
++
++_ACEOF
++
++# The following way of writing the cache mishandles newlines in values,
++# but we know of no workaround that is simple, portable, and efficient.
++# So, don't put newlines in cache variables' values.
++# Ultrix sh set writes to stderr and can't be redirected directly,
++# and sets the high bit in the cache file unless we assign to the vars.
++{
++ (set) 2>&1 |
++ case `(ac_space=' '; set | grep ac_space) 2>&1` in
++ *ac_space=\ *)
++ # `set' does not quote correctly, so add quotes (double-quote
++ # substitution turns \\\\ into \\, and sed turns \\ into \).
++ sed -n \
++ "s/'/'\\\\''/g;
++ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
++ ;;
++ *)
++ # `set' quotes correctly as required by POSIX, so do not add quotes.
++ sed -n \
++ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
++ ;;
++ esac;
++} |
++ sed '
++ t clear
++ : clear
++ s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
++ t end
++ /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
++ : end' >>confcache
++if diff $cache_file confcache >/dev/null 2>&1; then :; else
++ if test -w $cache_file; then
++ test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
++ cat confcache >$cache_file
++ else
++ echo "not updating unwritable cache $cache_file"
++ fi
++fi
++rm -f confcache
++
++# Actually configure libtool. ac_aux_dir is where install-sh is found.
++AR="$AR" LTCC="$CC" CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \
++MAGIC_CMD="$MAGIC_CMD" LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \
++LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" STRIP="$STRIP" \
++AS="$AS" DLLTOOL="$DLLTOOL" OBJDUMP="$OBJDUMP" \
++objext="$OBJEXT" exeext="$EXEEXT" reload_flag="$reload_flag" \
++deplibs_check_method="$deplibs_check_method" file_magic_cmd="$file_magic_cmd" \
++${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \
++$libtool_flags --no-verify --build="$build" $ac_aux_dir/ltmain.sh $host \
++|| { { echo "$as_me:$LINENO: error: libtool configure failed" >&5
++echo "$as_me: error: libtool configure failed" >&2;}
++ { (exit 1); exit 1; }; }
++
++# Reload cache, that may have been modified by ltconfig
++if test -r "$cache_file"; then
++ # Some versions of bash will fail to source /dev/null (special
++ # files actually), so we avoid doing that.
++ if test -f "$cache_file"; then
++ { echo "$as_me:$LINENO: loading cache $cache_file" >&5
++echo "$as_me: loading cache $cache_file" >&6;}
++ case $cache_file in
++ [\\/]* | ?:[\\/]* ) . $cache_file;;
++ *) . ./$cache_file;;
++ esac
++ fi
++else
++ { echo "$as_me:$LINENO: creating cache $cache_file" >&5
++echo "$as_me: creating cache $cache_file" >&6;}
++ >$cache_file
++fi
++
++
++# This can be used to rebuild libtool when needed
++LIBTOOL_DEPS="$ac_aux_dir/ltconfig $ac_aux_dir/ltmain.sh $ac_aux_dir/ltcf-c.sh"
++
++# Always use our own libtool.
++LIBTOOL='$(SHELL) $(top_builddir)/libtool'
++
++# Redirect the config.log output again, so that the ltconfig log is not
++# clobbered by the next message.
++exec 5>>./config.log
++
++ac_ext=cc
++ac_cpp='$CXXCPP $CPPFLAGS'
++ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
++ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
++ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
++echo "$as_me:$LINENO: checking how to run the C++ preprocessor" >&5
++echo $ECHO_N "checking how to run the C++ preprocessor... $ECHO_C" >&6
++if test -z "$CXXCPP"; then
++ if test "${ac_cv_prog_CXXCPP+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ # Double quotes because CXXCPP needs to be expanded
++ for CXXCPP in "$CXX -E" "/lib/cpp"
++ do
++ ac_preproc_ok=false
++for ac_cxx_preproc_warn_flag in '' yes
++do
++ # Use a header file that comes with gcc, so configuring glibc
++ # with a fresh cross-compiler works.
++ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
++ # <limits.h> exists even on freestanding compilers.
++ # On the NeXT, cc -E runs the code through the compiler's parser,
++ # not just through cpp. "Syntax error" is here to catch this case.
++ cat >conftest.$ac_ext <<_ACEOF
++#line $LINENO "configure"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
++@%:@ifdef __STDC__
++@%:@ include <limits.h>
++@%:@else
++@%:@ include <assert.h>
++@%:@endif
++ Syntax error
++_ACEOF
++if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
++ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
++ ac_status=$?
++ grep -v '^ *+' conftest.er1 >conftest.err
++ rm -f conftest.er1
++ cat conftest.err >&5
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); } >/dev/null; then
++ if test -s conftest.err; then
++ ac_cpp_err=$ac_cxx_preproc_warn_flag
++ else
++ ac_cpp_err=
++ fi
++else
++ ac_cpp_err=yes
++fi
++if test -z "$ac_cpp_err"; then
++ :
++else
++ echo "$as_me: failed program was:" >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
++ # Broken: fails on valid input.
++continue
++fi
++rm -f conftest.err conftest.$ac_ext
++
++ # OK, works on sane cases. Now check whether non-existent headers
++ # can be detected and how.
++ cat >conftest.$ac_ext <<_ACEOF
++#line $LINENO "configure"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
++@%:@include <ac_nonexistent.h>
++_ACEOF
++if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
++ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
++ ac_status=$?
++ grep -v '^ *+' conftest.er1 >conftest.err
++ rm -f conftest.er1
++ cat conftest.err >&5
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); } >/dev/null; then
++ if test -s conftest.err; then
++ ac_cpp_err=$ac_cxx_preproc_warn_flag
++ else
++ ac_cpp_err=
++ fi
++else
++ ac_cpp_err=yes
++fi
++if test -z "$ac_cpp_err"; then
++ # Broken: success on invalid input.
++continue
++else
++ echo "$as_me: failed program was:" >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
++ # Passes both tests.
++ac_preproc_ok=:
++break
++fi
++rm -f conftest.err conftest.$ac_ext
++
++done
++# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
++rm -f conftest.err conftest.$ac_ext
++if $ac_preproc_ok; then
++ break
++fi
++
++ done
++ ac_cv_prog_CXXCPP=$CXXCPP
++
++fi
++ CXXCPP=$ac_cv_prog_CXXCPP
++else
++ ac_cv_prog_CXXCPP=$CXXCPP
++fi
++echo "$as_me:$LINENO: result: $CXXCPP" >&5
++echo "${ECHO_T}$CXXCPP" >&6
++ac_preproc_ok=false
++for ac_cxx_preproc_warn_flag in '' yes
++do
++ # Use a header file that comes with gcc, so configuring glibc
++ # with a fresh cross-compiler works.
++ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
++ # <limits.h> exists even on freestanding compilers.
++ # On the NeXT, cc -E runs the code through the compiler's parser,
++ # not just through cpp. "Syntax error" is here to catch this case.
++ cat >conftest.$ac_ext <<_ACEOF
++#line $LINENO "configure"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
++@%:@ifdef __STDC__
++@%:@ include <limits.h>
++@%:@else
++@%:@ include <assert.h>
++@%:@endif
++ Syntax error
++_ACEOF
++if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
++ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
++ ac_status=$?
++ grep -v '^ *+' conftest.er1 >conftest.err
++ rm -f conftest.er1
++ cat conftest.err >&5
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); } >/dev/null; then
++ if test -s conftest.err; then
++ ac_cpp_err=$ac_cxx_preproc_warn_flag
++ else
++ ac_cpp_err=
++ fi
++else
++ ac_cpp_err=yes
++fi
++if test -z "$ac_cpp_err"; then
++ :
++else
++ echo "$as_me: failed program was:" >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
++ # Broken: fails on valid input.
++continue
++fi
++rm -f conftest.err conftest.$ac_ext
++
++ # OK, works on sane cases. Now check whether non-existent headers
++ # can be detected and how.
++ cat >conftest.$ac_ext <<_ACEOF
++#line $LINENO "configure"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
++@%:@include <ac_nonexistent.h>
++_ACEOF
++if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
++ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
++ ac_status=$?
++ grep -v '^ *+' conftest.er1 >conftest.err
++ rm -f conftest.er1
++ cat conftest.err >&5
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); } >/dev/null; then
++ if test -s conftest.err; then
++ ac_cpp_err=$ac_cxx_preproc_warn_flag
++ else
++ ac_cpp_err=
++ fi
++else
++ ac_cpp_err=yes
++fi
++if test -z "$ac_cpp_err"; then
++ # Broken: success on invalid input.
++continue
++else
++ echo "$as_me: failed program was:" >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
++ # Passes both tests.
++ac_preproc_ok=:
++break
++fi
++rm -f conftest.err conftest.$ac_ext
++
++done
++# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
++rm -f conftest.err conftest.$ac_ext
++if $ac_preproc_ok; then
++ :
++else
++ { { echo "$as_me:$LINENO: error: C++ preprocessor \"$CXXCPP\" fails sanity check
++See \`config.log' for more details." >&5
++echo "$as_me: error: C++ preprocessor \"$CXXCPP\" fails sanity check
++See \`config.log' for more details." >&2;}
++ { (exit 1); exit 1; }; }
++fi
++
++ac_ext=c
++ac_cpp='$CPP $CPPFLAGS'
++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
++ac_compiler_gnu=$ac_cv_c_compiler_gnu
++
++
++
++LIBTOOL_DEPS=$LIBTOOL_DEPS" $ac_aux_dir/ltcf-cxx.sh"
++lt_save_CC="$CC"
++lt_save_CFLAGS="$CFLAGS"
++AR="$AR" LTCC="$CC" CC="$CXX" CXX="$CXX" CFLAGS="$CXXFLAGS" CPPFLAGS="$CPPFLAGS" \
++MAGIC_CMD="$MAGIC_CMD" LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \
++LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" STRIP="$STRIP" \
++AS="$AS" DLLTOOL="$DLLTOOL" OBJDUMP="$OBJDUMP" \
++objext="$OBJEXT" exeext="$EXEEXT" reload_flag="$reload_flag" \
++deplibs_check_method="$deplibs_check_method" \
++file_magic_cmd="$file_magic_cmd" \
++${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig -o libtool $libtool_flags \
++--build="$build" --add-tag=CXX $ac_aux_dir/ltcf-cxx.sh $host \
++|| { { echo "$as_me:$LINENO: error: libtool tag configuration failed" >&5
++echo "$as_me: error: libtool tag configuration failed" >&2;}
++ { (exit 1); exit 1; }; }
++CC="$lt_save_CC"
++CFLAGS="$lt_save_CFLAGS"
++
++# Redirect the config.log output again, so that the ltconfig log is not
++# clobbered by the next message.
++exec 5>>./config.log
++
++
++
++
++
++
++
++
++# Check whether --with-target-subdir or --without-target-subdir was given.
++if test "${with_target_subdir+set}" = set; then
++ withval="$with_target_subdir"
++
++fi;
++
++# Check whether --with-cross-host or --without-cross-host was given.
++if test "${with_cross_host+set}" = set; then
++ withval="$with_cross_host"
++
++fi;
++
++echo "$as_me:$LINENO: checking whether to enable maintainer-specific portions of Makefiles" >&5
++echo $ECHO_N "checking whether to enable maintainer-specific portions of Makefiles... $ECHO_C" >&6
++ # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given.
++if test "${enable_maintainer_mode+set}" = set; then
++ enableval="$enable_maintainer_mode"
++ USE_MAINTAINER_MODE=$enableval
++else
++ USE_MAINTAINER_MODE=no
++fi;
++ echo "$as_me:$LINENO: result: $USE_MAINTAINER_MODE" >&5
++echo "${ECHO_T}$USE_MAINTAINER_MODE" >&6
++
++
++if test $USE_MAINTAINER_MODE = yes; then
++ MAINTAINER_MODE_TRUE=
++ MAINTAINER_MODE_FALSE='#'
++else
++ MAINTAINER_MODE_TRUE='#'
++ MAINTAINER_MODE_FALSE=
++fi
++ MAINT=$MAINTAINER_MODE_TRUE
++
++
++# automake wants to see AC_EXEEXT. But we don't need it. And having
++# it is actually a problem, because the compiler we're passed can't
++# necessarily do a full link. So we fool automake here.
++if false; then
++ # autoconf 2.50 runs AC_EXEEXT by default, and the macro expands
++ # to nothing, so nothing would remain between `then' and `fi' if it
++ # were not for the `:' below.
++ :
++
++fi
++
++echo "$as_me:$LINENO: checking for thread model used by GCC" >&5
++echo $ECHO_N "checking for thread model used by GCC... $ECHO_C" >&6
++THREADS=`$CC -v 2>&1 | sed -n 's/^Thread model: //p'`
++if test -z "$THREADS"; then
++ THREADS=no
++fi
++echo "$as_me:$LINENO: result: $THREADS" >&5
++echo "${ECHO_T}$THREADS" >&6
++
++# Check whether --enable-parallel-mark or --disable-parallel-mark was given.
++if test "${enable_parallel_mark+set}" = set; then
++ enableval="$enable_parallel_mark"
++ case "$THREADS" in
++ no | none | single)
++ { { echo "$as_me:$LINENO: error: Parallel mark requires --enable-threads=x spec" >&5
++echo "$as_me: error: Parallel mark requires --enable-threads=x spec" >&2;}
++ { (exit 1); exit 1; }; }
++ ;;
++ esac
++
++fi;
++
++INCLUDES=-I${srcdir}/include
++THREADLIBS=
++case "$THREADS" in
++ no | none | single)
++ THREADS=none
++ ;;
++ posix | pthreads)
++ THREADS=posix
++ THREADLIBS=-lpthread
++ case "$host" in
++ x86-*-linux* | ia64-*-linux* | i586-*-linux* | i686-*-linux* | x86_64-*-linux* )
++ cat >>confdefs.h <<\_ACEOF
++@%:@define GC_LINUX_THREADS 1
++_ACEOF
++
++ cat >>confdefs.h <<\_ACEOF
++@%:@define _REENTRANT 1
++_ACEOF
++
++ if test "${enable_parallel_mark}"; then
++ cat >>confdefs.h <<\_ACEOF
++@%:@define PARALLEL_MARK 1
++_ACEOF
++
++ fi
++ cat >>confdefs.h <<\_ACEOF
++@%:@define THREAD_LOCAL_ALLOC 1
++_ACEOF
++
++ ;;
++ *-*-linux*)
++ cat >>confdefs.h <<\_ACEOF
++@%:@define GC_LINUX_THREADS 1
++_ACEOF
++
++ cat >>confdefs.h <<\_ACEOF
++@%:@define _REENTRANT 1
++_ACEOF
++
++ ;;
++ *-*-hpux*)
++ { echo "$as_me:$LINENO: WARNING: \"Only HP/UX 11 threads are supported.\"" >&5
++echo "$as_me: WARNING: \"Only HP/UX 11 threads are supported.\"" >&2;}
++ cat >>confdefs.h <<\_ACEOF
++@%:@define GC_HPUX_THREADS 1
++_ACEOF
++
++ cat >>confdefs.h <<\_ACEOF
++@%:@define _POSIX_C_SOURCE 199506L
++_ACEOF
++
++ if test "${enable_parallel_mark}" = yes; then
++ cat >>confdefs.h <<\_ACEOF
++@%:@define PARALLEL_MARK 1
++_ACEOF
++
++ fi
++ cat >>confdefs.h <<\_ACEOF
++@%:@define THREAD_LOCAL_ALLOC 1
++_ACEOF
++
++ THREADLIBS="-lpthread -lrt"
++ ;;
++ *-*-freebsd*)
++ { echo "$as_me:$LINENO: WARNING: \"FreeBSD does not yet fully support threads with Boehm GC.\"" >&5
++echo "$as_me: WARNING: \"FreeBSD does not yet fully support threads with Boehm GC.\"" >&2;}
++ cat >>confdefs.h <<\_ACEOF
++@%:@define GC_FREEBSD_THREADS 1
++_ACEOF
++
++ INCLUDES="$INCLUDES -pthread"
++ THREADLIBS=-pthread
++ ;;
++ *-*-solaris*)
++ cat >>confdefs.h <<\_ACEOF
++@%:@define GC_SOLARIS_THREADS 1
++_ACEOF
++
++ cat >>confdefs.h <<\_ACEOF
++@%:@define GC_SOLARIS_PTHREADS 1
++_ACEOF
++
++ ;;
++ *-*-irix*)
++ cat >>confdefs.h <<\_ACEOF
++@%:@define GC_IRIX_THREADS 1
++_ACEOF
++
++ ;;
++ *-*-cygwin*)
++ THREADLIBS=
++ ;;
++ esac
++ ;;
++ *-*-darwin*)
++ cat >>confdefs.h <<\_ACEOF
++@%:@define GC_DARWIN_THREADS 1
++_ACEOF
++
++ cat >>confdefs.h <<\_ACEOF
++@%:@define THREAD_LOCAL_ALLOC 1
++_ACEOF
++
++ if test "${enable_parallel_mark}" = yes; then
++ cat >>confdefs.h <<\_ACEOF
++@%:@define PARALLEL_MARK 1
++_ACEOF
++
++ fi
++ ;;
++ win32)
++ cat >>confdefs.h <<\_ACEOF
++@%:@define GC_WIN32_THREADS 1
++_ACEOF
++
++ cat >>confdefs.h <<\_ACEOF
++@%:@define NO_GETENV 1
++_ACEOF
++
++ ;;
++ decosf1 | irix | mach | os2 | solaris | dce | vxworks)
++ { { echo "$as_me:$LINENO: error: thread package $THREADS not yet supported" >&5
++echo "$as_me: error: thread package $THREADS not yet supported" >&2;}
++ { (exit 1); exit 1; }; }
++ ;;
++ *)
++ { { echo "$as_me:$LINENO: error: $THREADS is an unknown thread package" >&5
++echo "$as_me: error: $THREADS is an unknown thread package" >&2;}
++ { (exit 1); exit 1; }; }
++ ;;
++esac
++
++
++case "$host" in
++ powerpc-*-darwin*)
++ powerpc_darwin=true
++ ;;
++esac
++
++
++if test x$powerpc_darwin = xtrue; then
++ POWERPC_DARWIN_TRUE=
++ POWERPC_DARWIN_FALSE='#'
++else
++ POWERPC_DARWIN_TRUE='#'
++ POWERPC_DARWIN_FALSE=
++fi
++
++# We never want libdl on darwin. It is a fake libdl that just ends up making
++# dyld calls anyway
++case "$host" in
++ *-*-darwin*) ;;
++ *)
++ echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5
++echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6
++if test "${ac_cv_lib_dl_dlopen+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ ac_check_lib_save_LIBS=$LIBS
++LIBS="-ldl $LIBS"
++cat >conftest.$ac_ext <<_ACEOF
++#line $LINENO "configure"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
++
++/* Override any gcc2 internal prototype to avoid an error. */
++#ifdef __cplusplus
++extern "C"
++#endif
++/* We use char because int might match the return type of a gcc2
++ builtin and then its argument prototype would still apply. */
++char dlopen ();
++int
++main ()
++{
++dlopen ();
++ ;
++ return 0;
++}
++_ACEOF
++rm -f conftest.$ac_objext conftest$ac_exeext
++if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
++ (eval $ac_link) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); } &&
++ { ac_try='test -s conftest$ac_exeext'
++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++ (eval $ac_try) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); }; }; then
++ ac_cv_lib_dl_dlopen=yes
++else
++ echo "$as_me: failed program was:" >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
++ac_cv_lib_dl_dlopen=no
++fi
++rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
++LIBS=$ac_check_lib_save_LIBS
++fi
++echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5
++echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6
++if test $ac_cv_lib_dl_dlopen = yes; then
++ EXTRA_TEST_LIBS="$EXTRA_TEST_LIBS -ldl"
++fi
++
++ ;;
++esac
++
++
++
++target_all=libgcjgc.la
++
++
++
++TARGET_ECOS="no"
++
++# Check whether --with-ecos or --without-ecos was given.
++if test "${with_ecos+set}" = set; then
++ withval="$with_ecos"
++ TARGET_ECOS="$with_ecos"
++
++fi;
++
++addobjs=
++CXXINCLUDES=
++case "$TARGET_ECOS" in
++ no)
++ ;;
++ *)
++ cat >>confdefs.h <<\_ACEOF
++@%:@define ECOS 1
++_ACEOF
++
++ CXXINCLUDES="-I${TARGET_ECOS}/include"
++ addobjs="$addobjs ecos.lo"
++ ;;
++esac
++
++
++
++
++
++machdep=
++case "$host" in
++ alpha*-*-openbsd*)
++ machdep="alpha_mach_dep.lo"
++ if test x"${ac_cv_lib_dl_dlopen}" != xyes ; then
++ { echo "$as_me:$LINENO: WARNING: OpenBSD/Alpha without dlopen(). Shared library support is disabled" >&5
++echo "$as_me: WARNING: OpenBSD/Alpha without dlopen(). Shared library support is disabled" >&2;}
++ # Check whether --enable-shared or --disable-shared was given.
++if test "${enable_shared+set}" = set; then
++ enableval="$enable_shared"
++ p=${PACKAGE-default}
++case $enableval in
++yes) enable_shared=yes ;;
++no) enable_shared=no ;;
++*)
++ enable_shared=no
++ # Look at the argument we got. We use all the common list separators.
++ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
++ for pkg in $enableval; do
++ if test "X$pkg" = "X$p"; then
++ enable_shared=yes
++ fi
++ done
++ IFS="$ac_save_ifs"
++ ;;
++esac
++else
++ enable_shared=no
++fi;
++ fi
++ ;;
++ alpha*-*-*)
++ machdep="alpha_mach_dep.lo"
++ ;;
++ i?86-*-solaris2.[89]*)
++ cat >>confdefs.h <<\_ACEOF
++@%:@define SOLARIS25_PROC_VDB_BUG_FIXED 1
++_ACEOF
++
++ ;;
++ mipstx39-*-elf*)
++ machdep="mips_ultrix_mach_dep.lo"
++ cat >>confdefs.h <<\_ACEOF
++@%:@define STACKBASE __stackbase
++_ACEOF
++
++ cat >>confdefs.h <<\_ACEOF
++@%:@define DATASTART_IS_ETEXT 1
++_ACEOF
++
++ ;;
++ mips-dec-ultrix*)
++ machdep="mips_ultrix_mach-dep.lo"
++ ;;
++ mips*-*-linux*)
++ ;;
++ mips-*-*)
++ machdep="mips_sgi_mach_dep.lo"
++ cat >>confdefs.h <<\_ACEOF
++@%:@define NO_EXECUTE_PERMISSION 1
++_ACEOF
++
++ ;;
++ sparc-sun-solaris2.3*)
++ machdep="sparc_mach_dep.lo"
++ cat >>confdefs.h <<\_ACEOF
++@%:@define SUNOS53_SHARED_LIB 1
++_ACEOF
++
++ ;;
++ sparc-sun-solaris2.*)
++ machdep="sparc_mach_dep.lo"
++ ;;
++ ia64-*-*)
++ machdep="mach_dep.lo ia64_save_regs_in_stack.lo"
++ ;;
++esac
++if test x"$machdep" = x; then
++ machdep="mach_dep.lo"
++fi
++addobjs="$addobjs $machdep"
++
++
++case "$host" in
++ sparc-sun-solaris2*)
++ if test "$GCC" = yes; then
++ new_CFLAGS=
++ for i in $CFLAGS; do
++ case "$i" in
++ -O*)
++ ;;
++ *)
++ new_CFLAGS="$new_CFLAGS $i"
++ ;;
++ esac
++ done
++ CFLAGS="$new_CFLAGS"
++ fi
++ ;;
++esac
++
++MY_CFLAGS="$CFLAGS"
++
++
++cat >>confdefs.h <<\_ACEOF
++@%:@define SILENT 1
++_ACEOF
++
++cat >>confdefs.h <<\_ACEOF
++@%:@define NO_SIGNALS 1
++_ACEOF
++
++cat >>confdefs.h <<\_ACEOF
++@%:@define NO_EXECUTE_PERMISSION 1
++_ACEOF
++
++cat >>confdefs.h <<\_ACEOF
++@%:@define ALL_INTERIOR_POINTERS 1
++_ACEOF
++
++
++cat >>confdefs.h <<\_ACEOF
++@%:@define JAVA_FINALIZATION 1
++_ACEOF
++
++cat >>confdefs.h <<\_ACEOF
++@%:@define GC_GCJ_SUPPORT 1
++_ACEOF
++
++cat >>confdefs.h <<\_ACEOF
++@%:@define ATOMIC_UNCOLLECTABLE 1
++_ACEOF
++
++
++if test -n "${with_cross_host}"; then
++ cat >>confdefs.h <<\_ACEOF
++@%:@define NO_SIGSET 1
++_ACEOF
++
++ cat >>confdefs.h <<\_ACEOF
++@%:@define NO_DEBUGGING 1
++_ACEOF
++
++fi
++
++# Check whether --enable-full-debug or --disable-full-debug was given.
++if test "${enable_full_debug+set}" = set; then
++ enableval="$enable_full_debug"
++ if test "$enable_full_debug" = "yes"; then
++ { echo "$as_me:$LINENO: WARNING: \"Must define GC_DEBUG and use debug alloc. in clients.\"" >&5
++echo "$as_me: WARNING: \"Must define GC_DEBUG and use debug alloc. in clients.\"" >&2;}
++ cat >>confdefs.h <<\_ACEOF
++@%:@define KEEP_BACK_PTRS 1
++_ACEOF
++
++ cat >>confdefs.h <<\_ACEOF
++@%:@define DBG_HDRS_ALL 1
++_ACEOF
++
++ case $host in
++ ia64-*-linux* )
++ cat >>confdefs.h <<\_ACEOF
++@%:@define MAKE_BACK_GRAPH 1
++_ACEOF
++
++ ;;
++ x86-*-linux* | i586-*-linux* | i686-*-linux* | x86_64-*-linux* )
++ cat >>confdefs.h <<\_ACEOF
++@%:@define MAKE_BACK_GRAPH 1
++_ACEOF
++
++ { echo "$as_me:$LINENO: WARNING: \"Client must not use -fomit-frame-pointer.\"" >&5
++echo "$as_me: WARNING: \"Client must not use -fomit-frame-pointer.\"" >&2;}
++ cat >>confdefs.h <<\_ACEOF
++@%:@define SAVE_CALL_COUNT 8
++_ACEOF
++
++ ;;
++ esac
++ fi
++fi;
++
++
++
++if test -z "$with_cross_host"; then
++ USE_LIBDIR_TRUE=
++ USE_LIBDIR_FALSE='#'
++else
++ USE_LIBDIR_TRUE='#'
++ USE_LIBDIR_FALSE=
++fi
++
++if test "${multilib}" = "yes"; then
++ multilib_arg="--enable-multilib"
++else
++ multilib_arg=
++fi
++
++ ac_config_files="$ac_config_files Makefile include/Makefile"
++ ac_config_commands="$ac_config_commands default"
++cat >confcache <<\_ACEOF
++# This file is a shell script that caches the results of configure
++# tests run on this system so they can be shared between configure
++# scripts and configure runs, see configure's option --config-cache.
++# It is not useful on other systems. If it contains results you don't
++# want to keep, you may remove or edit it.
++#
++# config.status only pays attention to the cache file if you give it
++# the --recheck option to rerun configure.
++#
++# `ac_cv_env_foo' variables (set or unset) will be overridden when
++# loading this file, other *unset* `ac_cv_foo' will be assigned the
++# following values.
++
++_ACEOF
++
++# The following way of writing the cache mishandles newlines in values,
++# but we know of no workaround that is simple, portable, and efficient.
++# So, don't put newlines in cache variables' values.
++# Ultrix sh set writes to stderr and can't be redirected directly,
++# and sets the high bit in the cache file unless we assign to the vars.
++{
++ (set) 2>&1 |
++ case `(ac_space=' '; set | grep ac_space) 2>&1` in
++ *ac_space=\ *)
++ # `set' does not quote correctly, so add quotes (double-quote
++ # substitution turns \\\\ into \\, and sed turns \\ into \).
++ sed -n \
++ "s/'/'\\\\''/g;
++ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
++ ;;
++ *)
++ # `set' quotes correctly as required by POSIX, so do not add quotes.
++ sed -n \
++ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
++ ;;
++ esac;
++} |
++ sed '
++ t clear
++ : clear
++ s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
++ t end
++ /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
++ : end' >>confcache
++if diff $cache_file confcache >/dev/null 2>&1; then :; else
++ if test -w $cache_file; then
++ test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
++ cat confcache >$cache_file
++ else
++ echo "not updating unwritable cache $cache_file"
++ fi
++fi
++rm -f confcache
++
++test "x$prefix" = xNONE && prefix=$ac_default_prefix
++# Let make expand exec_prefix.
++test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
++
++# VPATH may cause trouble with some makes, so we remove $(srcdir),
++# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
++# trailing colons and then remove the whole line if VPATH becomes empty
++# (actually we leave an empty line to preserve line numbers).
++if test "x$srcdir" = x.; then
++ ac_vpsub='/^[ ]*VPATH[ ]*=/{
++s/:*\$(srcdir):*/:/;
++s/:*\${srcdir}:*/:/;
++s/:*@srcdir@:*/:/;
++s/^\([^=]*=[ ]*\):*/\1/;
++s/:*$//;
++s/^[^=]*=[ ]*$//;
++}'
++fi
++
++# Transform confdefs.h into DEFS.
++# Protect against shell expansion while executing Makefile rules.
++# Protect against Makefile macro expansion.
++#
++# If the first sed substitution is executed (which looks for macros that
++# take arguments), then we branch to the quote section. Otherwise,
++# look for a macro that doesn't take arguments.
++cat >confdef2opt.sed <<\_ACEOF
++t clear
++: clear
++s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\),-D\1=\2,g
++t quote
++s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\),-D\1=\2,g
++t quote
++d
++: quote
++s,[ `~#$^&*(){}\\|;'"<>?],\\&,g
++s,\[,\\&,g
++s,\],\\&,g
++s,\$,$$,g
++p
++_ACEOF
++# We use echo to avoid assuming a particular line-breaking character.
++# The extra dot is to prevent the shell from consuming trailing
++# line-breaks from the sub-command output. A line-break within
++# single-quotes doesn't work because, if this script is created in a
++# platform that uses two characters for line-breaks (e.g., DOS), tr
++# would break.
++ac_LF_and_DOT=`echo; echo .`
++DEFS=`sed -n -f confdef2opt.sed confdefs.h | tr "$ac_LF_and_DOT" ' .'`
++rm -f confdef2opt.sed
++
++
++ac_libobjs=
++ac_ltlibobjs=
++for ac_i in : $LIB@&t@OBJS; do test "x$ac_i" = x: && continue
++ # 1. Remove the extension, and $U if already installed.
++ ac_i=`echo "$ac_i" |
++ sed 's/\$U\././;s/\.o$//;s/\.obj$//'`
++ # 2. Add them.
++ ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext"
++ ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo'
++done
++LIB@&t@OBJS=$ac_libobjs
++
++LTLIBOBJS=$ac_ltlibobjs
++
++
++
++: ${CONFIG_STATUS=./config.status}
++ac_clean_files_save=$ac_clean_files
++ac_clean_files="$ac_clean_files $CONFIG_STATUS"
++{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
++echo "$as_me: creating $CONFIG_STATUS" >&6;}
++cat >$CONFIG_STATUS <<_ACEOF
++#! $SHELL
++# Generated by $as_me.
++# Run this file to recreate the current configuration.
++# Compiler output produced by configure, useful for debugging
++# configure, is in config.log if it exists.
++
++debug=false
++ac_cs_recheck=false
++ac_cs_silent=false
++SHELL=\${CONFIG_SHELL-$SHELL}
++_ACEOF
++
++cat >>$CONFIG_STATUS <<\_ACEOF
++## --------------------- ##
++## M4sh Initialization. ##
++## --------------------- ##
++
++# Be Bourne compatible
++if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
++ emulate sh
++ NULLCMD=:
++ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
++ # is contrary to our usage. Disable this feature.
++ alias -g '${1+"$@"}'='"$@"'
++elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
++ set -o posix
++fi
++
++# Support unset when possible.
++if (FOO=FOO; unset FOO) >/dev/null 2>&1; then
++ as_unset=unset
++else
++ as_unset=false
++fi
++
++
++# Work around bugs in pre-3.0 UWIN ksh.
++$as_unset ENV MAIL MAILPATH
++PS1='$ '
++PS2='> '
++PS4='+ '
++
++# NLS nuisances.
++for as_var in \
++ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
++ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
++ LC_TELEPHONE LC_TIME
++do
++ if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then
++ eval $as_var=C; export $as_var
++ else
++ $as_unset $as_var
++ fi
++done
++
++# Required to use basename.
++if expr a : '\(a\)' >/dev/null 2>&1; then
++ as_expr=expr
++else
++ as_expr=false
++fi
++
++if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
++ as_basename=basename
++else
++ as_basename=false
++fi
++
++
++# Name of the executable.
++as_me=`$as_basename "$0" ||
++$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
++ X"$0" : 'X\(//\)$' \| \
++ X"$0" : 'X\(/\)$' \| \
++ . : '\(.\)' 2>/dev/null ||
++echo X/"$0" |
++ sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
++ /^X\/\(\/\/\)$/{ s//\1/; q; }
++ /^X\/\(\/\).*/{ s//\1/; q; }
++ s/.*/./; q'`
++
++
++# PATH needs CR, and LINENO needs CR and PATH.
++# Avoid depending upon Character Ranges.
++as_cr_letters='abcdefghijklmnopqrstuvwxyz'
++as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
++as_cr_Letters=$as_cr_letters$as_cr_LETTERS
++as_cr_digits='0123456789'
++as_cr_alnum=$as_cr_Letters$as_cr_digits
++
++# The user is always right.
++if test "${PATH_SEPARATOR+set}" != set; then
++ echo "#! /bin/sh" >conf$$.sh
++ echo "exit 0" >>conf$$.sh
++ chmod +x conf$$.sh
++ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
++ PATH_SEPARATOR=';'
++ else
++ PATH_SEPARATOR=:
++ fi
++ rm -f conf$$.sh
++fi
++
++
++ as_lineno_1=$LINENO
++ as_lineno_2=$LINENO
++ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
++ test "x$as_lineno_1" != "x$as_lineno_2" &&
++ test "x$as_lineno_3" = "x$as_lineno_2" || {
++ # Find who we are. Look in the path if we contain no path at all
++ # relative or not.
++ case $0 in
++ *[\\/]* ) as_myself=$0 ;;
++ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++ IFS=$as_save_IFS
++ test -z "$as_dir" && as_dir=.
++ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
++done
++
++ ;;
++ esac
++ # We did not find ourselves, most probably we were run as `sh COMMAND'
++ # in which case we are not to be found in the path.
++ if test "x$as_myself" = x; then
++ as_myself=$0
++ fi
++ if test ! -f "$as_myself"; then
++ { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
++echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
++ { (exit 1); exit 1; }; }
++ fi
++ case $CONFIG_SHELL in
++ '')
++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
++do
++ IFS=$as_save_IFS
++ test -z "$as_dir" && as_dir=.
++ for as_base in sh bash ksh sh5; do
++ case $as_dir in
++ /*)
++ if ("$as_dir/$as_base" -c '
++ as_lineno_1=$LINENO
++ as_lineno_2=$LINENO
++ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
++ test "x$as_lineno_1" != "x$as_lineno_2" &&
++ test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then
++ $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
++ $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
++ CONFIG_SHELL=$as_dir/$as_base
++ export CONFIG_SHELL
++ exec "$CONFIG_SHELL" "$0" ${1+"$@"}
++ fi;;
++ esac
++ done
++done
++;;
++ esac
++
++ # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
++ # uniformly replaced by the line number. The first 'sed' inserts a
++ # line-number line before each line; the second 'sed' does the real
++ # work. The second script uses 'N' to pair each line-number line
++ # with the numbered line, and appends trailing '-' during
++ # substitution so that $LINENO is not a special case at line end.
++ # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
++ # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-)
++ sed '=' <$as_myself |
++ sed '
++ N
++ s,$,-,
++ : loop
++ s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
++ t loop
++ s,-$,,
++ s,^['$as_cr_digits']*\n,,
++ ' >$as_me.lineno &&
++ chmod +x $as_me.lineno ||
++ { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5
++echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;}
++ { (exit 1); exit 1; }; }
++
++ # Don't try to exec as it changes $[0], causing all sort of problems
++ # (the dirname of $[0] is not the place where we might find the
++ # original and so on. Autoconf is especially sensible to this).
++ . ./$as_me.lineno
++ # Exit status is that of the last command.
++ exit
++}
++
++
++case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
++ *c*,-n*) ECHO_N= ECHO_C='
++' ECHO_T=' ' ;;
++ *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;;
++ *) ECHO_N= ECHO_C='\c' ECHO_T= ;;
++esac
++
++if expr a : '\(a\)' >/dev/null 2>&1; then
++ as_expr=expr
++else
++ as_expr=false
++fi
++
++rm -f conf$$ conf$$.exe conf$$.file
++echo >conf$$.file
++if ln -s conf$$.file conf$$ 2>/dev/null; then
++ # We could just check for DJGPP; but this test a) works b) is more generic
++ # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
++ if test -f conf$$.exe; then
++ # Don't use ln at all; we don't have any links
++ as_ln_s='cp -p'
++ else
++ as_ln_s='ln -s'
++ fi
++elif ln conf$$.file conf$$ 2>/dev/null; then
++ as_ln_s=ln
++else
++ as_ln_s='cp -p'
++fi
++rm -f conf$$ conf$$.exe conf$$.file
++
++if mkdir -p . 2>/dev/null; then
++ as_mkdir_p=:
++else
++ as_mkdir_p=false
++fi
++
++as_executable_p="test -f"
++
++# Sed expression to map a string onto a valid CPP name.
++as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g"
++
++# Sed expression to map a string onto a valid variable name.
++as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g"
++
++
++# IFS
++# We need space, tab and new line, in precisely that order.
++as_nl='
++'
++IFS=" $as_nl"
++
++# CDPATH.
++$as_unset CDPATH
++
++exec 6>&1
++
++# Open the log real soon, to keep \$[0] and so on meaningful, and to
++# report actual input values of CONFIG_FILES etc. instead of their
++# values after options handling. Logging --version etc. is OK.
++exec 5>>config.log
++{
++ echo
++ sed 'h;s/./-/g;s/^.../@%:@@%:@ /;s/...$/ @%:@@%:@/;p;x;p;x' <<_ASBOX
++@%:@@%:@ Running $as_me. @%:@@%:@
++_ASBOX
++} >&5
++cat >&5 <<_CSEOF
++
++This file was extended by $as_me, which was
++generated by GNU Autoconf 2.57. Invocation command line was
++
++ CONFIG_FILES = $CONFIG_FILES
++ CONFIG_HEADERS = $CONFIG_HEADERS
++ CONFIG_LINKS = $CONFIG_LINKS
++ CONFIG_COMMANDS = $CONFIG_COMMANDS
++ $ $0 $@
++
++_CSEOF
++echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5
++echo >&5
++_ACEOF
++
++# Files that config.status was made for.
++if test -n "$ac_config_files"; then
++ echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS
++fi
++
++if test -n "$ac_config_headers"; then
++ echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS
++fi
++
++if test -n "$ac_config_links"; then
++ echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS
++fi
++
++if test -n "$ac_config_commands"; then
++ echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS
++fi
++
++cat >>$CONFIG_STATUS <<\_ACEOF
++
++ac_cs_usage="\
++\`$as_me' instantiates files from templates according to the
++current configuration.
++
++Usage: $0 [OPTIONS] [FILE]...
++
++ -h, --help print this help, then exit
++ -V, --version print version number, then exit
++ -q, --quiet do not print progress messages
++ -d, --debug don't remove temporary files
++ --recheck update $as_me by reconfiguring in the same conditions
++ --file=FILE[:TEMPLATE]
++ instantiate the configuration file FILE
++
++Configuration files:
++$config_files
++
++Configuration commands:
++$config_commands
++
++Report bugs to <bug-autoconf@gnu.org>."
++_ACEOF
++
++cat >>$CONFIG_STATUS <<_ACEOF
++ac_cs_version="\\
++config.status
++configured by $0, generated by GNU Autoconf 2.57,
++ with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
++
++Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001
++Free Software Foundation, Inc.
++This config.status script is free software; the Free Software Foundation
++gives unlimited permission to copy, distribute and modify it."
++srcdir=$srcdir
++INSTALL="$INSTALL"
++_ACEOF
++
++cat >>$CONFIG_STATUS <<\_ACEOF
++# If no file are specified by the user, then we need to provide default
++# value. By we need to know if files were specified by the user.
++ac_need_defaults=:
++while test $# != 0
++do
++ case $1 in
++ --*=*)
++ ac_option=`expr "x$1" : 'x\([^=]*\)='`
++ ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
++ ac_shift=:
++ ;;
++ -*)
++ ac_option=$1
++ ac_optarg=$2
++ ac_shift=shift
++ ;;
++ *) # This is not an option, so the user has probably given explicit
++ # arguments.
++ ac_option=$1
++ ac_need_defaults=false;;
++ esac
++
++ case $ac_option in
++ # Handling of the options.
++_ACEOF
++cat >>$CONFIG_STATUS <<\_ACEOF
++ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
++ ac_cs_recheck=: ;;
++ --version | --vers* | -V )
++ echo "$ac_cs_version"; exit 0 ;;
++ --he | --h)
++ # Conflict between --help and --header
++ { { echo "$as_me:$LINENO: error: ambiguous option: $1
++Try \`$0 --help' for more information." >&5
++echo "$as_me: error: ambiguous option: $1
++Try \`$0 --help' for more information." >&2;}
++ { (exit 1); exit 1; }; };;
++ --help | --hel | -h )
++ echo "$ac_cs_usage"; exit 0 ;;
++ --debug | --d* | -d )
++ debug=: ;;
++ --file | --fil | --fi | --f )
++ $ac_shift
++ CONFIG_FILES="$CONFIG_FILES $ac_optarg"
++ ac_need_defaults=false;;
++ --header | --heade | --head | --hea )
++ $ac_shift
++ CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
++ ac_need_defaults=false;;
++ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
++ | -silent | --silent | --silen | --sile | --sil | --si | --s)
++ ac_cs_silent=: ;;
++
++ # This is an error.
++ -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
++Try \`$0 --help' for more information." >&5
++echo "$as_me: error: unrecognized option: $1
++Try \`$0 --help' for more information." >&2;}
++ { (exit 1); exit 1; }; } ;;
++
++ *) ac_config_targets="$ac_config_targets $1" ;;
++
++ esac
++ shift
++done
++
++ac_configure_extra_args=
++
++if $ac_cs_silent; then
++ exec 6>/dev/null
++ ac_configure_extra_args="$ac_configure_extra_args --silent"
++fi
++
++_ACEOF
++cat >>$CONFIG_STATUS <<_ACEOF
++if \$ac_cs_recheck; then
++ echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
++ exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
++fi
++
++_ACEOF
++
++cat >>$CONFIG_STATUS <<_ACEOF
++#
++# INIT-COMMANDS section.
++#
++
++srcdir=${srcdir}
++host=${host}
++target=${target}
++with_multisubdir=${with_multisubdir}
++ac_configure_args="${multilib_arg} ${ac_configure_args}"
++CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
++gc_basedir=${gc_basedir}
++CC="${CC}"
++DEFS="$DEFS"
++
++
++_ACEOF
++
++
++
++cat >>$CONFIG_STATUS <<\_ACEOF
++for ac_config_target in $ac_config_targets
++do
++ case "$ac_config_target" in
++ # Handling of arguments.
++ "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
++ "include/Makefile" ) CONFIG_FILES="$CONFIG_FILES include/Makefile" ;;
++ "default" ) CONFIG_COMMANDS="$CONFIG_COMMANDS default" ;;
++ *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
++echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
++ { (exit 1); exit 1; }; };;
++ esac
++done
++
++# If the user did not use the arguments to specify the items to instantiate,
++# then the envvar interface is used. Set only those that are not.
++# We use the long form for the default assignment because of an extremely
++# bizarre bug on SunOS 4.1.3.
++if $ac_need_defaults; then
++ test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
++ test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
++fi
++
++# Have a temporary directory for convenience. Make it in the build tree
++# simply because there is no reason to put it here, and in addition,
++# creating and moving files from /tmp can sometimes cause problems.
++# Create a temporary directory, and hook for its removal unless debugging.
++$debug ||
++{
++ trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0
++ trap '{ (exit 1); exit 1; }' 1 2 13 15
++}
++
++# Create a (secure) tmp directory for tmp files.
++
++{
++ tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` &&
++ test -n "$tmp" && test -d "$tmp"
++} ||
++{
++ tmp=./confstat$$-$RANDOM
++ (umask 077 && mkdir $tmp)
++} ||
++{
++ echo "$me: cannot create a temporary directory in ." >&2
++ { (exit 1); exit 1; }
++}
++
++_ACEOF
++
++cat >>$CONFIG_STATUS <<_ACEOF
++
++#
++# CONFIG_FILES section.
++#
++
++# No need to generate the scripts if there are no CONFIG_FILES.
++# This happens for instance when ./config.status config.h
++if test -n "\$CONFIG_FILES"; then
++ # Protect against being on the right side of a sed subst in config.status.
++ sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g;
++ s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF
++s,@SHELL@,$SHELL,;t t
++s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t
++s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t
++s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t
++s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t
++s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t
++s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t
++s,@exec_prefix@,$exec_prefix,;t t
++s,@prefix@,$prefix,;t t
++s,@program_transform_name@,$program_transform_name,;t t
++s,@bindir@,$bindir,;t t
++s,@sbindir@,$sbindir,;t t
++s,@libexecdir@,$libexecdir,;t t
++s,@datadir@,$datadir,;t t
++s,@sysconfdir@,$sysconfdir,;t t
++s,@sharedstatedir@,$sharedstatedir,;t t
++s,@localstatedir@,$localstatedir,;t t
++s,@libdir@,$libdir,;t t
++s,@includedir@,$includedir,;t t
++s,@oldincludedir@,$oldincludedir,;t t
++s,@infodir@,$infodir,;t t
++s,@mandir@,$mandir,;t t
++s,@build_alias@,$build_alias,;t t
++s,@host_alias@,$host_alias,;t t
++s,@target_alias@,$target_alias,;t t
++s,@DEFS@,$DEFS,;t t
++s,@ECHO_C@,$ECHO_C,;t t
++s,@ECHO_N@,$ECHO_N,;t t
++s,@ECHO_T@,$ECHO_T,;t t
++s,@LIBS@,$LIBS,;t t
++s,@gc_basedir@,$gc_basedir,;t t
++s,@build@,$build,;t t
++s,@build_cpu@,$build_cpu,;t t
++s,@build_vendor@,$build_vendor,;t t
++s,@build_os@,$build_os,;t t
++s,@host@,$host,;t t
++s,@host_cpu@,$host_cpu,;t t
++s,@host_vendor@,$host_vendor,;t t
++s,@host_os@,$host_os,;t t
++s,@target@,$target,;t t
++s,@target_cpu@,$target_cpu,;t t
++s,@target_vendor@,$target_vendor,;t t
++s,@target_os@,$target_os,;t t
++s,@mkinstalldirs@,$mkinstalldirs,;t t
++s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t
++s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t
++s,@INSTALL_DATA@,$INSTALL_DATA,;t t
++s,@PACKAGE@,$PACKAGE,;t t
++s,@VERSION@,$VERSION,;t t
++s,@ACLOCAL@,$ACLOCAL,;t t
++s,@AUTOCONF@,$AUTOCONF,;t t
++s,@AUTOMAKE@,$AUTOMAKE,;t t
++s,@AUTOHEADER@,$AUTOHEADER,;t t
++s,@MAKEINFO@,$MAKEINFO,;t t
++s,@SET_MAKE@,$SET_MAKE,;t t
++s,@CC@,$CC,;t t
++s,@CXX@,$CXX,;t t
++s,@AS@,$AS,;t t
++s,@ac_ct_AS@,$ac_ct_AS,;t t
++s,@AR@,$AR,;t t
++s,@ac_ct_AR@,$ac_ct_AR,;t t
++s,@RANLIB@,$RANLIB,;t t
++s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t
++s,@MAINTAINER_MODE_TRUE@,$MAINTAINER_MODE_TRUE,;t t
++s,@MAINTAINER_MODE_FALSE@,$MAINTAINER_MODE_FALSE,;t t
++s,@MAINT@,$MAINT,;t t
++s,@GC_CFLAGS@,$GC_CFLAGS,;t t
++s,@LN_S@,$LN_S,;t t
++s,@STRIP@,$STRIP,;t t
++s,@ac_ct_STRIP@,$ac_ct_STRIP,;t t
++s,@LIBTOOL@,$LIBTOOL,;t t
++s,@CXXCPP@,$CXXCPP,;t t
++s,@CPPFLAGS@,$CPPFLAGS,;t t
++s,@THREADLIBS@,$THREADLIBS,;t t
++s,@POWERPC_DARWIN_TRUE@,$POWERPC_DARWIN_TRUE,;t t
++s,@POWERPC_DARWIN_FALSE@,$POWERPC_DARWIN_FALSE,;t t
++s,@EXTRA_TEST_LIBS@,$EXTRA_TEST_LIBS,;t t
++s,@target_all@,$target_all,;t t
++s,@INCLUDES@,$INCLUDES,;t t
++s,@CXXINCLUDES@,$CXXINCLUDES,;t t
++s,@addobjs@,$addobjs,;t t
++s,@MY_CFLAGS@,$MY_CFLAGS,;t t
++s,@USE_LIBDIR_TRUE@,$USE_LIBDIR_TRUE,;t t
++s,@USE_LIBDIR_FALSE@,$USE_LIBDIR_FALSE,;t t
++s,@LIB@&t@OBJS@,$LIB@&t@OBJS,;t t
++s,@LTLIBOBJS@,$LTLIBOBJS,;t t
++CEOF
++
++_ACEOF
++
++ cat >>$CONFIG_STATUS <<\_ACEOF
++ # Split the substitutions into bite-sized pieces for seds with
++ # small command number limits, like on Digital OSF/1 and HP-UX.
++ ac_max_sed_lines=48
++ ac_sed_frag=1 # Number of current file.
++ ac_beg=1 # First line for current file.
++ ac_end=$ac_max_sed_lines # Line after last line for current file.
++ ac_more_lines=:
++ ac_sed_cmds=
++ while $ac_more_lines; do
++ if test $ac_beg -gt 1; then
++ sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
++ else
++ sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
++ fi
++ if test ! -s $tmp/subs.frag; then
++ ac_more_lines=false
++ else
++ # The purpose of the label and of the branching condition is to
++ # speed up the sed processing (if there are no `@' at all, there
++ # is no need to browse any of the substitutions).
++ # These are the two extra sed commands mentioned above.
++ (echo ':t
++ /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed
++ if test -z "$ac_sed_cmds"; then
++ ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
++ else
++ ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
++ fi
++ ac_sed_frag=`expr $ac_sed_frag + 1`
++ ac_beg=$ac_end
++ ac_end=`expr $ac_end + $ac_max_sed_lines`
++ fi
++ done
++ if test -z "$ac_sed_cmds"; then
++ ac_sed_cmds=cat
++ fi
++fi # test -n "$CONFIG_FILES"
++
++_ACEOF
++cat >>$CONFIG_STATUS <<\_ACEOF
++for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
++ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
++ case $ac_file in
++ - | *:- | *:-:* ) # input from stdin
++ cat >$tmp/stdin
++ ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
++ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
++ *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
++ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
++ * ) ac_file_in=$ac_file.in ;;
++ esac
++
++ # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
++ ac_dir=`(dirname "$ac_file") 2>/dev/null ||
++$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
++ X"$ac_file" : 'X\(//\)[^/]' \| \
++ X"$ac_file" : 'X\(//\)$' \| \
++ X"$ac_file" : 'X\(/\)' \| \
++ . : '\(.\)' 2>/dev/null ||
++echo X"$ac_file" |
++ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
++ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
++ /^X\(\/\/\)$/{ s//\1/; q; }
++ /^X\(\/\).*/{ s//\1/; q; }
++ s/.*/./; q'`
++ { if $as_mkdir_p; then
++ mkdir -p "$ac_dir"
++ else
++ as_dir="$ac_dir"
++ as_dirs=
++ while test ! -d "$as_dir"; do
++ as_dirs="$as_dir $as_dirs"
++ as_dir=`(dirname "$as_dir") 2>/dev/null ||
++$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
++ X"$as_dir" : 'X\(//\)[^/]' \| \
++ X"$as_dir" : 'X\(//\)$' \| \
++ X"$as_dir" : 'X\(/\)' \| \
++ . : '\(.\)' 2>/dev/null ||
++echo X"$as_dir" |
++ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
++ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
++ /^X\(\/\/\)$/{ s//\1/; q; }
++ /^X\(\/\).*/{ s//\1/; q; }
++ s/.*/./; q'`
++ done
++ test ! -n "$as_dirs" || mkdir $as_dirs
++ fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
++echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
++ { (exit 1); exit 1; }; }; }
++
++ ac_builddir=.
++
++if test "$ac_dir" != .; then
++ ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
++ # A "../" for each directory in $ac_dir_suffix.
++ ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
++else
++ ac_dir_suffix= ac_top_builddir=
++fi
++
++case $srcdir in
++ .) # No --srcdir option. We are building in place.
++ ac_srcdir=.
++ if test -z "$ac_top_builddir"; then
++ ac_top_srcdir=.
++ else
++ ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
++ fi ;;
++ [\\/]* | ?:[\\/]* ) # Absolute path.
++ ac_srcdir=$srcdir$ac_dir_suffix;
++ ac_top_srcdir=$srcdir ;;
++ *) # Relative path.
++ ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
++ ac_top_srcdir=$ac_top_builddir$srcdir ;;
++esac
++# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be
++# absolute.
++ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd`
++ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd`
++ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd`
++ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd`
++
++
++ case $INSTALL in
++ [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
++ *) ac_INSTALL=$ac_top_builddir$INSTALL ;;
++ esac
++
++ if test x"$ac_file" != x-; then
++ { echo "$as_me:$LINENO: creating $ac_file" >&5
++echo "$as_me: creating $ac_file" >&6;}
++ rm -f "$ac_file"
++ fi
++ # Let's still pretend it is `configure' which instantiates (i.e., don't
++ # use $as_me), people would be surprised to read:
++ # /* config.h. Generated by config.status. */
++ if test x"$ac_file" = x-; then
++ configure_input=
++ else
++ configure_input="$ac_file. "
++ fi
++ configure_input=$configure_input"Generated from `echo $ac_file_in |
++ sed 's,.*/,,'` by configure."
++
++ # First look for the input files in the build tree, otherwise in the
++ # src tree.
++ ac_file_inputs=`IFS=:
++ for f in $ac_file_in; do
++ case $f in
++ -) echo $tmp/stdin ;;
++ [\\/$]*)
++ # Absolute (can't be DOS-style, as IFS=:)
++ test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
++echo "$as_me: error: cannot find input file: $f" >&2;}
++ { (exit 1); exit 1; }; }
++ echo $f;;
++ *) # Relative
++ if test -f "$f"; then
++ # Build tree
++ echo $f
++ elif test -f "$srcdir/$f"; then
++ # Source tree
++ echo $srcdir/$f
++ else
++ # /dev/null tree
++ { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
++echo "$as_me: error: cannot find input file: $f" >&2;}
++ { (exit 1); exit 1; }; }
++ fi;;
++ esac
++ done` || { (exit 1); exit 1; }
++_ACEOF
++cat >>$CONFIG_STATUS <<_ACEOF
++ sed "$ac_vpsub
++$extrasub
++_ACEOF
++cat >>$CONFIG_STATUS <<\_ACEOF
++:t
++/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
++s,@configure_input@,$configure_input,;t t
++s,@srcdir@,$ac_srcdir,;t t
++s,@abs_srcdir@,$ac_abs_srcdir,;t t
++s,@top_srcdir@,$ac_top_srcdir,;t t
++s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t
++s,@builddir@,$ac_builddir,;t t
++s,@abs_builddir@,$ac_abs_builddir,;t t
++s,@top_builddir@,$ac_top_builddir,;t t
++s,@abs_top_builddir@,$ac_abs_top_builddir,;t t
++s,@INSTALL@,$ac_INSTALL,;t t
++" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out
++ rm -f $tmp/stdin
++ if test x"$ac_file" != x-; then
++ mv $tmp/out $ac_file
++ else
++ cat $tmp/out
++ rm -f $tmp/out
++ fi
++
++done
++_ACEOF
++cat >>$CONFIG_STATUS <<\_ACEOF
++
++#
++# CONFIG_COMMANDS section.
++#
++for ac_file in : $CONFIG_COMMANDS; do test "x$ac_file" = x: && continue
++ ac_dest=`echo "$ac_file" | sed 's,:.*,,'`
++ ac_source=`echo "$ac_file" | sed 's,[^:]*:,,'`
++ ac_dir=`(dirname "$ac_dest") 2>/dev/null ||
++$as_expr X"$ac_dest" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
++ X"$ac_dest" : 'X\(//\)[^/]' \| \
++ X"$ac_dest" : 'X\(//\)$' \| \
++ X"$ac_dest" : 'X\(/\)' \| \
++ . : '\(.\)' 2>/dev/null ||
++echo X"$ac_dest" |
++ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
++ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
++ /^X\(\/\/\)$/{ s//\1/; q; }
++ /^X\(\/\).*/{ s//\1/; q; }
++ s/.*/./; q'`
++ ac_builddir=.
++
++if test "$ac_dir" != .; then
++ ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
++ # A "../" for each directory in $ac_dir_suffix.
++ ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
++else
++ ac_dir_suffix= ac_top_builddir=
++fi
++
++case $srcdir in
++ .) # No --srcdir option. We are building in place.
++ ac_srcdir=.
++ if test -z "$ac_top_builddir"; then
++ ac_top_srcdir=.
++ else
++ ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
++ fi ;;
++ [\\/]* | ?:[\\/]* ) # Absolute path.
++ ac_srcdir=$srcdir$ac_dir_suffix;
++ ac_top_srcdir=$srcdir ;;
++ *) # Relative path.
++ ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
++ ac_top_srcdir=$ac_top_builddir$srcdir ;;
++esac
++# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be
++# absolute.
++ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd`
++ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd`
++ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd`
++ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd`
++
++
++ { echo "$as_me:$LINENO: executing $ac_dest commands" >&5
++echo "$as_me: executing $ac_dest commands" >&6;}
++ case $ac_dest in
++ default )
++echo "$DEFS" > boehm-cflags
++
++if test -n "$CONFIG_FILES"; then
++ LD="${ORIGINAL_LD_FOR_MULTILIBS}"
++ ac_file=Makefile . ${gc_basedir}/../config-ml.in
++fi ;;
++ esac
++done
++_ACEOF
++
++cat >>$CONFIG_STATUS <<\_ACEOF
++
++{ (exit 0); exit 0; }
++_ACEOF
++chmod +x $CONFIG_STATUS
++ac_clean_files=$ac_clean_files_save
++
++
++# configure is writing to config.log, and then calls config.status.
++# config.status does its own redirection, appending to config.log.
++# Unfortunately, on DOS this fails, as config.log is still kept open
++# by configure, so config.status won't be able to write to it; its
++# output is simply discarded. So we exec the FD to /dev/null,
++# effectively closing config.log, so it can be properly (re)opened and
++# appended to by config.status. When coming back to configure, we
++# need to make the FD available again.
++if test "$no_create" != yes; then
++ ac_cs_success=:
++ ac_config_status_args=
++ test "$silent" = yes &&
++ ac_config_status_args="$ac_config_status_args --quiet"
++ exec 5>/dev/null
++ $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
++ exec 5>>config.log
++ # Use ||, not &&, to avoid exiting from the if with $? = 1, which
++ # would make configure fail if this is the last instruction.
++ $ac_cs_success || { (exit 1); exit 1; }
++fi
++
+diff -buNr boehm-gc/autom4te.cache/output.1 boehm-gc/autom4te.cache/output.1
+--- boehm-gc/autom4te.cache/output.1 Wed Dec 31 16:00:00 1969
++++ boehm-gc/autom4te.cache/output.1 Sat Sep 13 02:10:15 2003
+@@ -0,0 +1,9496 @@
++@%:@! /bin/sh
++@%:@ Guess values for system-dependent variables and create Makefiles.
++@%:@ Generated by GNU Autoconf 2.54.
++@%:@
++@%:@ Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002
++@%:@ Free Software Foundation, Inc.
++@%:@ This configure script is free software; the Free Software Foundation
++@%:@ gives unlimited permission to copy, distribute and modify it.
++## --------------------- ##
++## M4sh Initialization. ##
++## --------------------- ##
++
++# Be Bourne compatible
++if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
++ emulate sh
++ NULLCMD=:
++ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
++ # is contrary to our usage. Disable this feature.
++ alias -g '${1+"$@"}'='"$@"'
++elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
++ set -o posix
++fi
++
++# Support unset when possible.
++if (FOO=FOO; unset FOO) >/dev/null 2>&1; then
++ as_unset=unset
++else
++ as_unset=false
++fi
++
++
++# Work around bugs in pre-3.0 UWIN ksh.
++$as_unset ENV MAIL MAILPATH
++PS1='$ '
++PS2='> '
++PS4='+ '
++
++# NLS nuisances.
++for as_var in LANG LANGUAGE LC_ALL LC_COLLATE LC_CTYPE LC_NUMERIC LC_MESSAGES LC_TIME
++do
++ if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then
++ eval $as_var=C; export $as_var
++ else
++ $as_unset $as_var
++ fi
++done
++
++# Required to use basename.
++if expr a : '\(a\)' >/dev/null 2>&1; then
++ as_expr=expr
++else
++ as_expr=false
++fi
++
++if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
++ as_basename=basename
++else
++ as_basename=false
++fi
++
++
++# Name of the executable.
++as_me=`$as_basename "$0" ||
++$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
++ X"$0" : 'X\(//\)$' \| \
++ X"$0" : 'X\(/\)$' \| \
++ . : '\(.\)' 2>/dev/null ||
++echo X/"$0" |
++ sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
++ /^X\/\(\/\/\)$/{ s//\1/; q; }
++ /^X\/\(\/\).*/{ s//\1/; q; }
++ s/.*/./; q'`
++
++
++# PATH needs CR, and LINENO needs CR and PATH.
++# Avoid depending upon Character Ranges.
++as_cr_letters='abcdefghijklmnopqrstuvwxyz'
++as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
++as_cr_Letters=$as_cr_letters$as_cr_LETTERS
++as_cr_digits='0123456789'
++as_cr_alnum=$as_cr_Letters$as_cr_digits
++
++# The user is always right.
++if test "${PATH_SEPARATOR+set}" != set; then
++ echo "#! /bin/sh" >conftest.sh
++ echo "exit 0" >>conftest.sh
++ chmod +x conftest.sh
++ if (PATH="/nonexistent;."; conftest.sh) >/dev/null 2>&1; then
++ PATH_SEPARATOR=';'
++ else
++ PATH_SEPARATOR=:
++ fi
++ rm -f conftest.sh
++fi
++
++
++ as_lineno_1=$LINENO
++ as_lineno_2=$LINENO
++ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
++ test "x$as_lineno_1" != "x$as_lineno_2" &&
++ test "x$as_lineno_3" = "x$as_lineno_2" || {
++ # Find who we are. Look in the path if we contain no path at all
++ # relative or not.
++ case $0 in
++ *[\\/]* ) as_myself=$0 ;;
++ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++ IFS=$as_save_IFS
++ test -z "$as_dir" && as_dir=.
++ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
++done
++
++ ;;
++ esac
++ # We did not find ourselves, most probably we were run as `sh COMMAND'
++ # in which case we are not to be found in the path.
++ if test "x$as_myself" = x; then
++ as_myself=$0
++ fi
++ if test ! -f "$as_myself"; then
++ { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2
++ { (exit 1); exit 1; }; }
++ fi
++ case $CONFIG_SHELL in
++ '')
++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
++do
++ IFS=$as_save_IFS
++ test -z "$as_dir" && as_dir=.
++ for as_base in sh bash ksh sh5; do
++ case $as_dir in
++ /*)
++ if ("$as_dir/$as_base" -c '
++ as_lineno_1=$LINENO
++ as_lineno_2=$LINENO
++ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
++ test "x$as_lineno_1" != "x$as_lineno_2" &&
++ test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then
++ $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
++ $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
++ CONFIG_SHELL=$as_dir/$as_base
++ export CONFIG_SHELL
++ exec "$CONFIG_SHELL" "$0" ${1+"$@"}
++ fi;;
++ esac
++ done
++done
++;;
++ esac
++
++ # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
++ # uniformly replaced by the line number. The first 'sed' inserts a
++ # line-number line before each line; the second 'sed' does the real
++ # work. The second script uses 'N' to pair each line-number line
++ # with the numbered line, and appends trailing '-' during
++ # substitution so that $LINENO is not a special case at line end.
++ # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
++ # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-)
++ sed '=' <$as_myself |
++ sed '
++ N
++ s,$,-,
++ : loop
++ s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
++ t loop
++ s,-$,,
++ s,^['$as_cr_digits']*\n,,
++ ' >$as_me.lineno &&
++ chmod +x $as_me.lineno ||
++ { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
++ { (exit 1); exit 1; }; }
++
++ # Don't try to exec as it changes $[0], causing all sort of problems
++ # (the dirname of $[0] is not the place where we might find the
++ # original and so on. Autoconf is especially sensible to this).
++ . ./$as_me.lineno
++ # Exit status is that of the last command.
++ exit
++}
++
++
++case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
++ *c*,-n*) ECHO_N= ECHO_C='
++' ECHO_T=' ' ;;
++ *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;;
++ *) ECHO_N= ECHO_C='\c' ECHO_T= ;;
++esac
++
++if expr a : '\(a\)' >/dev/null 2>&1; then
++ as_expr=expr
++else
++ as_expr=false
++fi
++
++rm -f conf$$ conf$$.exe conf$$.file
++echo >conf$$.file
++if ln -s conf$$.file conf$$ 2>/dev/null; then
++ # We could just check for DJGPP; but this test a) works b) is more generic
++ # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
++ if test -f conf$$.exe; then
++ # Don't use ln at all; we don't have any links
++ as_ln_s='cp -p'
++ else
++ as_ln_s='ln -s'
++ fi
++elif ln conf$$.file conf$$ 2>/dev/null; then
++ as_ln_s=ln
++else
++ as_ln_s='cp -p'
++fi
++rm -f conf$$ conf$$.exe conf$$.file
++
++if mkdir -p . 2>/dev/null; then
++ as_mkdir_p=:
++else
++ as_mkdir_p=false
++fi
++
++as_executable_p="test -f"
++
++# Sed expression to map a string onto a valid CPP name.
++as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g"
++
++# Sed expression to map a string onto a valid variable name.
++as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g"
++
++
++# IFS
++# We need space, tab and new line, in precisely that order.
++as_nl='
++'
++IFS=" $as_nl"
++
++# CDPATH.
++$as_unset CDPATH
++
++
++# Find the correct PATH separator. Usually this is `:', but
++# DJGPP uses `;' like DOS.
++if test "X${PATH_SEPARATOR+set}" != Xset; then
++ UNAME=${UNAME-`uname 2>/dev/null`}
++ case X$UNAME in
++ *-DOS) lt_cv_sys_path_separator=';' ;;
++ *) lt_cv_sys_path_separator=':' ;;
++ esac
++ PATH_SEPARATOR=$lt_cv_sys_path_separator
++fi
++
++
++# Check that we are running under the correct shell.
++SHELL=${CONFIG_SHELL-/bin/sh}
++
++case X$ECHO in
++X*--fallback-echo)
++ # Remove one level of quotation (which was required for Make).
++ ECHO=`echo "$ECHO" | sed 's,\\\\\$\\$0,'$0','`
++ ;;
++esac
++
++echo=${ECHO-echo}
++if test "X$1" = X--no-reexec; then
++ # Discard the --no-reexec flag, and continue.
++ shift
++elif test "X$1" = X--fallback-echo; then
++ # Avoid inline document here, it may be left over
++ :
++elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then
++ # Yippee, $echo works!
++ :
++else
++ # Restart under the correct shell.
++ exec $SHELL "$0" --no-reexec ${1+"$@"}
++fi
++
++if test "X$1" = X--fallback-echo; then
++ # used as fallback echo
++ shift
++ cat <<EOF
++
++EOF
++ exit 0
++fi
++
++# The HP-UX ksh and POSIX shell print the target directory to stdout
++# if CDPATH is set.
++if test "X${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi
++
++if test -z "$ECHO"; then
++if test "X${echo_test_string+set}" != Xset; then
++# find a string as large as possible, as long as the shell can cope with it
++ for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do
++ # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
++ if (echo_test_string="`eval $cmd`") 2>/dev/null &&
++ echo_test_string="`eval $cmd`" &&
++ (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null
++ then
++ break
++ fi
++ done
++fi
++
++if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
++ echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` &&
++ test "X$echo_testing_string" = "X$echo_test_string"; then
++ :
++else
++ # The Solaris, AIX, and Digital Unix default echo programs unquote
++ # backslashes. This makes it impossible to quote backslashes using
++ # echo "$something" | sed 's/\\/\\\\/g'
++ #
++ # So, first we look for a working echo in the user's PATH.
++
++ IFS="${IFS= }"; save_ifs="$IFS"; IFS=$PATH_SEPARATOR
++ for dir in $PATH /usr/ucb; do
++ if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
++ test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
++ echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` &&
++ test "X$echo_testing_string" = "X$echo_test_string"; then
++ echo="$dir/echo"
++ break
++ fi
++ done
++ IFS="$save_ifs"
++
++ if test "X$echo" = Xecho; then
++ # We didn't find a better echo, so look for alternatives.
++ if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' &&
++ echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` &&
++ test "X$echo_testing_string" = "X$echo_test_string"; then
++ # This shell has a builtin print -r that does the trick.
++ echo='print -r'
++ elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) &&
++ test "X$CONFIG_SHELL" != X/bin/ksh; then
++ # If we have ksh, try running configure again with it.
++ ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
++ export ORIGINAL_CONFIG_SHELL
++ CONFIG_SHELL=/bin/ksh
++ export CONFIG_SHELL
++ exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"}
++ else
++ # Try using printf.
++ echo='printf %s\n'
++ if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
++ echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` &&
++ test "X$echo_testing_string" = "X$echo_test_string"; then
++ # Cool, printf works
++ :
++ elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` &&
++ test "X$echo_testing_string" = 'X\t' &&
++ echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
++ test "X$echo_testing_string" = "X$echo_test_string"; then
++ CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL
++ export CONFIG_SHELL
++ SHELL="$CONFIG_SHELL"
++ export SHELL
++ echo="$CONFIG_SHELL $0 --fallback-echo"
++ elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` &&
++ test "X$echo_testing_string" = 'X\t' &&
++ echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
++ test "X$echo_testing_string" = "X$echo_test_string"; then
++ echo="$CONFIG_SHELL $0 --fallback-echo"
++ else
++ # maybe with a smaller string...
++ prev=:
++
++ for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do
++ if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null
++ then
++ break
++ fi
++ prev="$cmd"
++ done
++
++ if test "$prev" != 'sed 50q "$0"'; then
++ echo_test_string=`eval $prev`
++ export echo_test_string
++ exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"}
++ else
++ # Oops. We lost completely, so just stick with echo.
++ echo=echo
++ fi
++ fi
++ fi
++ fi
++fi
++fi
++
++# Copy echo and quote the copy suitably for passing to libtool from
++# the Makefile, instead of quoting the original, which is used later.
++ECHO=$echo
++if test "X$ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then
++ ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo"
++fi
++
++
++
++# Name of the host.
++# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
++# so uname gets run too.
++ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
++
++exec 6>&1
++
++#
++# Initializations.
++#
++ac_default_prefix=/usr/local
++ac_config_libobj_dir=.
++cross_compiling=no
++subdirs=
++MFLAGS=
++MAKEFLAGS=
++SHELL=${CONFIG_SHELL-/bin/sh}
++
++# Maximum number of lines to put in a shell here document.
++# This variable seems obsolete. It should probably be removed, and
++# only ac_max_sed_lines should be used.
++: ${ac_max_here_lines=38}
++
++# Identity of this package.
++PACKAGE_NAME=
++PACKAGE_TARNAME=
++PACKAGE_VERSION=
++PACKAGE_STRING=
++PACKAGE_BUGREPORT=
++
++ac_unique_file="gcj_mlc.c"
++# Factoring default headers for most tests.
++ac_includes_default="\
++#include <stdio.h>
++#if HAVE_SYS_TYPES_H
++# include <sys/types.h>
++#endif
++#if HAVE_SYS_STAT_H
++# include <sys/stat.h>
++#endif
++#if STDC_HEADERS
++# include <stdlib.h>
++# include <stddef.h>
++#else
++# if HAVE_STDLIB_H
++# include <stdlib.h>
++# endif
++#endif
++#if HAVE_STRING_H
++# if !STDC_HEADERS && HAVE_MEMORY_H
++# include <memory.h>
++# endif
++# include <string.h>
++#endif
++#if HAVE_STRINGS_H
++# include <strings.h>
++#endif
++#if HAVE_INTTYPES_H
++# include <inttypes.h>
++#else
++# if HAVE_STDINT_H
++# include <stdint.h>
++# endif
++#endif
++#if HAVE_UNISTD_H
++# include <unistd.h>
++#endif"
++
++ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS gc_basedir build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os mkinstalldirs INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO AMTAR install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM AWK SET_MAKE AS ac_ct_AS AR ac_ct_AR RANLIB ac_ct_RANLIB MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT GC_CFLAGS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE LN_S ECHO CPP EGREP LIBTOOL THREADLIBS POWERPC_DARWIN_TRUE POWERPC_DARWIN_FALSE EXTRA_TEST_LIBS target_all CXX INCLUDES CXXINCLUDES addobjs MY_CFLAGS USE_LIBDIR_TRUE USE_LIBDIR_FALSE LIB@&t@OBJS LTLIBOBJS'
++ac_subst_files=''
++
++# Initialize some variables set by options.
++ac_init_help=
++ac_init_version=false
++# The variables have the same names as the options, with
++# dashes changed to underlines.
++cache_file=/dev/null
++exec_prefix=NONE
++no_create=
++no_recursion=
++prefix=NONE
++program_prefix=NONE
++program_suffix=NONE
++program_transform_name=s,x,x,
++silent=
++site=
++srcdir=
++verbose=
++x_includes=NONE
++x_libraries=NONE
++
++# Installation directory options.
++# These are left unexpanded so users can "make install exec_prefix=/foo"
++# and all the variables that are supposed to be based on exec_prefix
++# by default will actually change.
++# Use braces instead of parens because sh, perl, etc. also accept them.
++bindir='${exec_prefix}/bin'
++sbindir='${exec_prefix}/sbin'
++libexecdir='${exec_prefix}/libexec'
++datadir='${prefix}/share'
++sysconfdir='${prefix}/etc'
++sharedstatedir='${prefix}/com'
++localstatedir='${prefix}/var'
++libdir='${exec_prefix}/lib'
++includedir='${prefix}/include'
++oldincludedir='/usr/include'
++infodir='${prefix}/info'
++mandir='${prefix}/man'
++
++ac_prev=
++for ac_option
++do
++ # If the previous option needs an argument, assign it.
++ if test -n "$ac_prev"; then
++ eval "$ac_prev=\$ac_option"
++ ac_prev=
++ continue
++ fi
++
++ ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`
++
++ # Accept the important Cygnus configure options, so we can diagnose typos.
++
++ case $ac_option in
++
++ -bindir | --bindir | --bindi | --bind | --bin | --bi)
++ ac_prev=bindir ;;
++ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
++ bindir=$ac_optarg ;;
++
++ -build | --build | --buil | --bui | --bu)
++ ac_prev=build_alias ;;
++ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
++ build_alias=$ac_optarg ;;
++
++ -cache-file | --cache-file | --cache-fil | --cache-fi \
++ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
++ ac_prev=cache_file ;;
++ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
++ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
++ cache_file=$ac_optarg ;;
++
++ --config-cache | -C)
++ cache_file=config.cache ;;
++
++ -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
++ ac_prev=datadir ;;
++ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
++ | --da=*)
++ datadir=$ac_optarg ;;
++
++ -disable-* | --disable-*)
++ ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
++ # Reject names that are not valid shell variable names.
++ expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
++ { echo "$as_me: error: invalid feature name: $ac_feature" >&2
++ { (exit 1); exit 1; }; }
++ ac_feature=`echo $ac_feature | sed 's/-/_/g'`
++ eval "enable_$ac_feature=no" ;;
++
++ -enable-* | --enable-*)
++ ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
++ # Reject names that are not valid shell variable names.
++ expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
++ { echo "$as_me: error: invalid feature name: $ac_feature" >&2
++ { (exit 1); exit 1; }; }
++ ac_feature=`echo $ac_feature | sed 's/-/_/g'`
++ case $ac_option in
++ *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
++ *) ac_optarg=yes ;;
++ esac
++ eval "enable_$ac_feature='$ac_optarg'" ;;
++
++ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
++ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
++ | --exec | --exe | --ex)
++ ac_prev=exec_prefix ;;
++ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
++ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
++ | --exec=* | --exe=* | --ex=*)
++ exec_prefix=$ac_optarg ;;
++
++ -gas | --gas | --ga | --g)
++ # Obsolete; use --with-gas.
++ with_gas=yes ;;
++
++ -help | --help | --hel | --he | -h)
++ ac_init_help=long ;;
++ -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
++ ac_init_help=recursive ;;
++ -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
++ ac_init_help=short ;;
++
++ -host | --host | --hos | --ho)
++ ac_prev=host_alias ;;
++ -host=* | --host=* | --hos=* | --ho=*)
++ host_alias=$ac_optarg ;;
++
++ -includedir | --includedir | --includedi | --included | --include \
++ | --includ | --inclu | --incl | --inc)
++ ac_prev=includedir ;;
++ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
++ | --includ=* | --inclu=* | --incl=* | --inc=*)
++ includedir=$ac_optarg ;;
++
++ -infodir | --infodir | --infodi | --infod | --info | --inf)
++ ac_prev=infodir ;;
++ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
++ infodir=$ac_optarg ;;
++
++ -libdir | --libdir | --libdi | --libd)
++ ac_prev=libdir ;;
++ -libdir=* | --libdir=* | --libdi=* | --libd=*)
++ libdir=$ac_optarg ;;
++
++ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
++ | --libexe | --libex | --libe)
++ ac_prev=libexecdir ;;
++ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
++ | --libexe=* | --libex=* | --libe=*)
++ libexecdir=$ac_optarg ;;
++
++ -localstatedir | --localstatedir | --localstatedi | --localstated \
++ | --localstate | --localstat | --localsta | --localst \
++ | --locals | --local | --loca | --loc | --lo)
++ ac_prev=localstatedir ;;
++ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
++ | --localstate=* | --localstat=* | --localsta=* | --localst=* \
++ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
++ localstatedir=$ac_optarg ;;
++
++ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
++ ac_prev=mandir ;;
++ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
++ mandir=$ac_optarg ;;
++
++ -nfp | --nfp | --nf)
++ # Obsolete; use --without-fp.
++ with_fp=no ;;
++
++ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
++ | --no-cr | --no-c | -n)
++ no_create=yes ;;
++
++ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
++ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
++ no_recursion=yes ;;
++
++ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
++ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
++ | --oldin | --oldi | --old | --ol | --o)
++ ac_prev=oldincludedir ;;
++ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
++ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
++ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
++ oldincludedir=$ac_optarg ;;
++
++ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
++ ac_prev=prefix ;;
++ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
++ prefix=$ac_optarg ;;
++
++ -program-prefix | --program-prefix | --program-prefi | --program-pref \
++ | --program-pre | --program-pr | --program-p)
++ ac_prev=program_prefix ;;
++ -program-prefix=* | --program-prefix=* | --program-prefi=* \
++ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
++ program_prefix=$ac_optarg ;;
++
++ -program-suffix | --program-suffix | --program-suffi | --program-suff \
++ | --program-suf | --program-su | --program-s)
++ ac_prev=program_suffix ;;
++ -program-suffix=* | --program-suffix=* | --program-suffi=* \
++ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
++ program_suffix=$ac_optarg ;;
++
++ -program-transform-name | --program-transform-name \
++ | --program-transform-nam | --program-transform-na \
++ | --program-transform-n | --program-transform- \
++ | --program-transform | --program-transfor \
++ | --program-transfo | --program-transf \
++ | --program-trans | --program-tran \
++ | --progr-tra | --program-tr | --program-t)
++ ac_prev=program_transform_name ;;
++ -program-transform-name=* | --program-transform-name=* \
++ | --program-transform-nam=* | --program-transform-na=* \
++ | --program-transform-n=* | --program-transform-=* \
++ | --program-transform=* | --program-transfor=* \
++ | --program-transfo=* | --program-transf=* \
++ | --program-trans=* | --program-tran=* \
++ | --progr-tra=* | --program-tr=* | --program-t=*)
++ program_transform_name=$ac_optarg ;;
++
++ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
++ | -silent | --silent | --silen | --sile | --sil)
++ silent=yes ;;
++
++ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
++ ac_prev=sbindir ;;
++ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
++ | --sbi=* | --sb=*)
++ sbindir=$ac_optarg ;;
++
++ -sharedstatedir | --sharedstatedir | --sharedstatedi \
++ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
++ | --sharedst | --shareds | --shared | --share | --shar \
++ | --sha | --sh)
++ ac_prev=sharedstatedir ;;
++ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
++ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
++ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
++ | --sha=* | --sh=*)
++ sharedstatedir=$ac_optarg ;;
++
++ -site | --site | --sit)
++ ac_prev=site ;;
++ -site=* | --site=* | --sit=*)
++ site=$ac_optarg ;;
++
++ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
++ ac_prev=srcdir ;;
++ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
++ srcdir=$ac_optarg ;;
++
++ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
++ | --syscon | --sysco | --sysc | --sys | --sy)
++ ac_prev=sysconfdir ;;
++ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
++ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
++ sysconfdir=$ac_optarg ;;
++
++ -target | --target | --targe | --targ | --tar | --ta | --t)
++ ac_prev=target_alias ;;
++ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
++ target_alias=$ac_optarg ;;
++
++ -v | -verbose | --verbose | --verbos | --verbo | --verb)
++ verbose=yes ;;
++
++ -version | --version | --versio | --versi | --vers | -V)
++ ac_init_version=: ;;
++
++ -with-* | --with-*)
++ ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
++ # Reject names that are not valid shell variable names.
++ expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
++ { echo "$as_me: error: invalid package name: $ac_package" >&2
++ { (exit 1); exit 1; }; }
++ ac_package=`echo $ac_package| sed 's/-/_/g'`
++ case $ac_option in
++ *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
++ *) ac_optarg=yes ;;
++ esac
++ eval "with_$ac_package='$ac_optarg'" ;;
++
++ -without-* | --without-*)
++ ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
++ # Reject names that are not valid shell variable names.
++ expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
++ { echo "$as_me: error: invalid package name: $ac_package" >&2
++ { (exit 1); exit 1; }; }
++ ac_package=`echo $ac_package | sed 's/-/_/g'`
++ eval "with_$ac_package=no" ;;
++
++ --x)
++ # Obsolete; use --with-x.
++ with_x=yes ;;
++
++ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
++ | --x-incl | --x-inc | --x-in | --x-i)
++ ac_prev=x_includes ;;
++ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
++ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
++ x_includes=$ac_optarg ;;
++
++ -x-libraries | --x-libraries | --x-librarie | --x-librari \
++ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
++ ac_prev=x_libraries ;;
++ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
++ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
++ x_libraries=$ac_optarg ;;
++
++ -*) { echo "$as_me: error: unrecognized option: $ac_option
++Try \`$0 --help' for more information." >&2
++ { (exit 1); exit 1; }; }
++ ;;
++
++ *=*)
++ ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
++ # Reject names that are not valid shell variable names.
++ expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
++ { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
++ { (exit 1); exit 1; }; }
++ ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`
++ eval "$ac_envvar='$ac_optarg'"
++ export $ac_envvar ;;
++
++ *)
++ # FIXME: should be removed in autoconf 3.0.
++ echo "$as_me: WARNING: you should use --build, --host, --target" >&2
++ expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
++ echo "$as_me: WARNING: invalid host type: $ac_option" >&2
++ : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
++ ;;
++
++ esac
++done
++
++if test -n "$ac_prev"; then
++ ac_option=--`echo $ac_prev | sed 's/_/-/g'`
++ { echo "$as_me: error: missing argument to $ac_option" >&2
++ { (exit 1); exit 1; }; }
++fi
++
++# Be sure to have absolute paths.
++for ac_var in exec_prefix prefix
++do
++ eval ac_val=$`echo $ac_var`
++ case $ac_val in
++ [\\/$]* | ?:[\\/]* | NONE | '' ) ;;
++ *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
++ { (exit 1); exit 1; }; };;
++ esac
++done
++
++# Be sure to have absolute paths.
++for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \
++ localstatedir libdir includedir oldincludedir infodir mandir
++do
++ eval ac_val=$`echo $ac_var`
++ case $ac_val in
++ [\\/$]* | ?:[\\/]* ) ;;
++ *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
++ { (exit 1); exit 1; }; };;
++ esac
++done
++
++# There might be people who depend on the old broken behavior: `$host'
++# used to hold the argument of --host etc.
++# FIXME: To remove some day.
++build=$build_alias
++host=$host_alias
++target=$target_alias
++
++# FIXME: To remove some day.
++if test "x$host_alias" != x; then
++ if test "x$build_alias" = x; then
++ cross_compiling=maybe
++ echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
++ If a cross compiler is detected then cross compile mode will be used." >&2
++ elif test "x$build_alias" != "x$host_alias"; then
++ cross_compiling=yes
++ fi
++fi
++
++ac_tool_prefix=
++test -n "$host_alias" && ac_tool_prefix=$host_alias-
++
++test "$silent" = yes && exec 6>/dev/null
++
++
++# Find the source files, if location was not specified.
++if test -z "$srcdir"; then
++ ac_srcdir_defaulted=yes
++ # Try the directory containing this script, then its parent.
++ ac_confdir=`(dirname "$0") 2>/dev/null ||
++$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
++ X"$0" : 'X\(//\)[^/]' \| \
++ X"$0" : 'X\(//\)$' \| \
++ X"$0" : 'X\(/\)' \| \
++ . : '\(.\)' 2>/dev/null ||
++echo X"$0" |
++ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
++ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
++ /^X\(\/\/\)$/{ s//\1/; q; }
++ /^X\(\/\).*/{ s//\1/; q; }
++ s/.*/./; q'`
++ srcdir=$ac_confdir
++ if test ! -r $srcdir/$ac_unique_file; then
++ srcdir=..
++ fi
++else
++ ac_srcdir_defaulted=no
++fi
++if test ! -r $srcdir/$ac_unique_file; then
++ if test "$ac_srcdir_defaulted" = yes; then
++ { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2
++ { (exit 1); exit 1; }; }
++ else
++ { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
++ { (exit 1); exit 1; }; }
++ fi
++fi
++(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null ||
++ { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2
++ { (exit 1); exit 1; }; }
++srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
++ac_env_build_alias_set=${build_alias+set}
++ac_env_build_alias_value=$build_alias
++ac_cv_env_build_alias_set=${build_alias+set}
++ac_cv_env_build_alias_value=$build_alias
++ac_env_host_alias_set=${host_alias+set}
++ac_env_host_alias_value=$host_alias
++ac_cv_env_host_alias_set=${host_alias+set}
++ac_cv_env_host_alias_value=$host_alias
++ac_env_target_alias_set=${target_alias+set}
++ac_env_target_alias_value=$target_alias
++ac_cv_env_target_alias_set=${target_alias+set}
++ac_cv_env_target_alias_value=$target_alias
++ac_env_CC_set=${CC+set}
++ac_env_CC_value=$CC
++ac_cv_env_CC_set=${CC+set}
++ac_cv_env_CC_value=$CC
++ac_env_CFLAGS_set=${CFLAGS+set}
++ac_env_CFLAGS_value=$CFLAGS
++ac_cv_env_CFLAGS_set=${CFLAGS+set}
++ac_cv_env_CFLAGS_value=$CFLAGS
++ac_env_LDFLAGS_set=${LDFLAGS+set}
++ac_env_LDFLAGS_value=$LDFLAGS
++ac_cv_env_LDFLAGS_set=${LDFLAGS+set}
++ac_cv_env_LDFLAGS_value=$LDFLAGS
++ac_env_CPPFLAGS_set=${CPPFLAGS+set}
++ac_env_CPPFLAGS_value=$CPPFLAGS
++ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set}
++ac_cv_env_CPPFLAGS_value=$CPPFLAGS
++ac_env_CPP_set=${CPP+set}
++ac_env_CPP_value=$CPP
++ac_cv_env_CPP_set=${CPP+set}
++ac_cv_env_CPP_value=$CPP
++
++#
++# Report the --help message.
++#
++if test "$ac_init_help" = "long"; then
++ # Omit some internal or obsolete options to make the list less imposing.
++ # This message is too long to be a string in the A/UX 3.1 sh.
++ cat <<_ACEOF
++\`configure' configures this package to adapt to many kinds of systems.
++
++Usage: $0 [OPTION]... [VAR=VALUE]...
++
++To assign environment variables (e.g., CC, CFLAGS...), specify them as
++VAR=VALUE. See below for descriptions of some of the useful variables.
++
++Defaults for the options are specified in brackets.
++
++Configuration:
++ -h, --help display this help and exit
++ --help=short display options specific to this package
++ --help=recursive display the short help of all the included packages
++ -V, --version display version information and exit
++ -q, --quiet, --silent do not print \`checking...' messages
++ --cache-file=FILE cache test results in FILE [disabled]
++ -C, --config-cache alias for \`--cache-file=config.cache'
++ -n, --no-create do not create output files
++ --srcdir=DIR find the sources in DIR [configure dir or \`..']
++
++_ACEOF
++
++ cat <<_ACEOF
++Installation directories:
++ --prefix=PREFIX install architecture-independent files in PREFIX
++ [$ac_default_prefix]
++ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
++ [PREFIX]
++
++By default, \`make install' will install all the files in
++\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
++an installation prefix other than \`$ac_default_prefix' using \`--prefix',
++for instance \`--prefix=\$HOME'.
++
++For better control, use the options below.
++
++Fine tuning of the installation directories:
++ --bindir=DIR user executables [EPREFIX/bin]
++ --sbindir=DIR system admin executables [EPREFIX/sbin]
++ --libexecdir=DIR program executables [EPREFIX/libexec]
++ --datadir=DIR read-only architecture-independent data [PREFIX/share]
++ --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
++ --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
++ --localstatedir=DIR modifiable single-machine data [PREFIX/var]
++ --libdir=DIR object code libraries [EPREFIX/lib]
++ --includedir=DIR C header files [PREFIX/include]
++ --oldincludedir=DIR C header files for non-gcc [/usr/include]
++ --infodir=DIR info documentation [PREFIX/info]
++ --mandir=DIR man documentation [PREFIX/man]
++_ACEOF
++
++ cat <<\_ACEOF
++
++Program names:
++ --program-prefix=PREFIX prepend PREFIX to installed program names
++ --program-suffix=SUFFIX append SUFFIX to installed program names
++ --program-transform-name=PROGRAM run sed PROGRAM on installed program names
++
++System types:
++ --build=BUILD configure for building on BUILD [guessed]
++ --host=HOST cross-compile to build programs to run on HOST [BUILD]
++ --target=TARGET configure for building compilers for TARGET [HOST]
++_ACEOF
++fi
++
++if test -n "$ac_init_help"; then
++
++ cat <<\_ACEOF
++
++Optional Features:
++ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
++ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
++ --enable-multilib build many library versions (default)
++ --enable-maintainer-mode enable make rules and dependencies not useful
++ (and sometimes confusing) to the casual installer
++ --enable-shared=PKGS build shared libraries default=yes
++ --enable-static=PKGS build static libraries default=yes
++ --enable-fast-install=PKGS optimize for fast installation default=yes
++ --disable-dependency-tracking Speeds up one-time builds
++ --enable-dependency-tracking Do not reject slow dependency extractors
++ --disable-libtool-lock avoid locking (might break parallel builds)
++ --enable-parallel-mark parallelize marking and free list construction
++ --enable-shared=PKGS build shared libraries default=no
++ --enable-full-debug include full support for pointer backtracing etc.
++
++Optional Packages:
++ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
++ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
++ --with-gnu-ld assume the C compiler uses GNU ld default=no
++ --with-pic try to use only PIC/non-PIC objects default=use both
++ --with-target-subdir=SUBDIR
++ configuring with a cross compiler
++ --with-cross-host=HOST configuring with a cross compiler
++ --with-ecos enable runtime eCos target support
++
++Some influential environment variables:
++ CC C compiler command
++ CFLAGS C compiler flags
++ LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
++ nonstandard directory <lib dir>
++ CPPFLAGS C/C++ preprocessor flags, e.g. -I<include dir> if you have
++ headers in a nonstandard directory <include dir>
++ CPP C preprocessor
++
++Use these variables to override the choices made by `configure' or to help
++it to find libraries and programs with nonstandard names/locations.
++
++_ACEOF
++fi
++
++if test "$ac_init_help" = "recursive"; then
++ # If there are subdirs, report their specific --help.
++ ac_popdir=`pwd`
++ for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
++ test -d $ac_dir || continue
++ ac_builddir=.
++
++if test "$ac_dir" != .; then
++ ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
++ # A "../" for each directory in $ac_dir_suffix.
++ ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
++else
++ ac_dir_suffix= ac_top_builddir=
++fi
++
++case $srcdir in
++ .) # No --srcdir option. We are building in place.
++ ac_srcdir=.
++ if test -z "$ac_top_builddir"; then
++ ac_top_srcdir=.
++ else
++ ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
++ fi ;;
++ [\\/]* | ?:[\\/]* ) # Absolute path.
++ ac_srcdir=$srcdir$ac_dir_suffix;
++ ac_top_srcdir=$srcdir ;;
++ *) # Relative path.
++ ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
++ ac_top_srcdir=$ac_top_builddir$srcdir ;;
++esac
++# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be
++# absolute.
++ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd`
++ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd`
++ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd`
++ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd`
++
++ cd $ac_dir
++ # Check for guested configure; otherwise get Cygnus style configure.
++ if test -f $ac_srcdir/configure.gnu; then
++ echo
++ $SHELL $ac_srcdir/configure.gnu --help=recursive
++ elif test -f $ac_srcdir/configure; then
++ echo
++ $SHELL $ac_srcdir/configure --help=recursive
++ elif test -f $ac_srcdir/configure.ac ||
++ test -f $ac_srcdir/configure.in; then
++ echo
++ $ac_configure --help
++ else
++ echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
++ fi
++ cd $ac_popdir
++ done
++fi
++
++test -n "$ac_init_help" && exit 0
++if $ac_init_version; then
++ cat <<\_ACEOF
++
++Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002
++Free Software Foundation, Inc.
++This configure script is free software; the Free Software Foundation
++gives unlimited permission to copy, distribute and modify it.
++_ACEOF
++ exit 0
++fi
++exec 5>config.log
++cat >&5 <<_ACEOF
++This file contains any messages produced by compilers while
++running configure, to aid debugging if configure makes a mistake.
++
++It was created by $as_me, which was
++generated by GNU Autoconf 2.54. Invocation command line was
++
++ $ $0 $@
++
++_ACEOF
++{
++cat <<_ASUNAME
++@%:@@%:@ --------- @%:@@%:@
++@%:@@%:@ Platform. @%:@@%:@
++@%:@@%:@ --------- @%:@@%:@
++
++hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
++uname -m = `(uname -m) 2>/dev/null || echo unknown`
++uname -r = `(uname -r) 2>/dev/null || echo unknown`
++uname -s = `(uname -s) 2>/dev/null || echo unknown`
++uname -v = `(uname -v) 2>/dev/null || echo unknown`
++
++/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
++/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown`
++
++/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown`
++/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown`
++/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
++hostinfo = `(hostinfo) 2>/dev/null || echo unknown`
++/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown`
++/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown`
++/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown`
++
++_ASUNAME
++
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++ IFS=$as_save_IFS
++ test -z "$as_dir" && as_dir=.
++ echo "PATH: $as_dir"
++done
++
++} >&5
++
++cat >&5 <<_ACEOF
++
++
++@%:@@%:@ ----------- @%:@@%:@
++@%:@@%:@ Core tests. @%:@@%:@
++@%:@@%:@ ----------- @%:@@%:@
++
++_ACEOF
++
++
++# Keep a trace of the command line.
++# Strip out --no-create and --no-recursion so they do not pile up.
++# Also quote any args containing shell meta-characters.
++ac_configure_args=
++ac_sep=
++for ac_arg
++do
++ case $ac_arg in
++ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
++ | --no-cr | --no-c | -n ) continue ;;
++ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
++ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
++ continue ;;
++ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
++ ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
++ esac
++ ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
++ # Get rid of the leading space.
++ ac_sep=" "
++done
++
++# When interrupted or exit'd, cleanup temporary files, and complete
++# config.log. We remove comments because anyway the quotes in there
++# would cause problems or look ugly.
++# WARNING: Be sure not to use single quotes in there, as some shells,
++# such as our DU 5.0 friend, will then `close' the trap.
++trap 'exit_status=$?
++ # Save into config.log some information that might help in debugging.
++ {
++ echo
++
++ cat <<\_ASBOX
++@%:@@%:@ ---------------- @%:@@%:@
++@%:@@%:@ Cache variables. @%:@@%:@
++@%:@@%:@ ---------------- @%:@@%:@
++_ASBOX
++ echo
++ # The following way of writing the cache mishandles newlines in values,
++{
++ (set) 2>&1 |
++ case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in
++ *ac_space=\ *)
++ sed -n \
++ "s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
++ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
++ ;;
++ *)
++ sed -n \
++ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
++ ;;
++ esac;
++}
++ echo
++
++ cat <<\_ASBOX
++@%:@@%:@ ----------------- @%:@@%:@
++@%:@@%:@ Output variables. @%:@@%:@
++@%:@@%:@ ----------------- @%:@@%:@
++_ASBOX
++ echo
++ for ac_var in $ac_subst_vars
++ do
++ eval ac_val=$`echo $ac_var`
++ echo "$ac_var='"'"'$ac_val'"'"'"
++ done | sort
++ echo
++
++ if test -n "$ac_subst_files"; then
++ cat <<\_ASBOX
++@%:@@%:@ ------------- @%:@@%:@
++@%:@@%:@ Output files. @%:@@%:@
++@%:@@%:@ ------------- @%:@@%:@
++_ASBOX
++ echo
++ for ac_var in $ac_subst_files
++ do
++ eval ac_val=$`echo $ac_var`
++ echo "$ac_var='"'"'$ac_val'"'"'"
++ done | sort
++ echo
++ fi
++
++ if test -s confdefs.h; then
++ cat <<\_ASBOX
++@%:@@%:@ ----------- @%:@@%:@
++@%:@@%:@ confdefs.h. @%:@@%:@
++@%:@@%:@ ----------- @%:@@%:@
++_ASBOX
++ echo
++ sed "/^$/d" confdefs.h | sort
++ echo
++ fi
++ test "$ac_signal" != 0 &&
++ echo "$as_me: caught signal $ac_signal"
++ echo "$as_me: exit $exit_status"
++ } >&5
++ rm -f core core.* *.core &&
++ rm -rf conftest* confdefs* conf$$* $ac_clean_files &&
++ exit $exit_status
++ ' 0
++for ac_signal in 1 2 13 15; do
++ trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
++done
++ac_signal=0
++
++# confdefs.h avoids OS command line length limits that DEFS can exceed.
++rm -rf conftest* confdefs.h
++# AIX cpp loses on an empty file, so make sure it contains at least a newline.
++echo >confdefs.h
++
++# Predefined preprocessor variables.
++
++cat >>confdefs.h <<_ACEOF
++@%:@define PACKAGE_NAME "$PACKAGE_NAME"
++_ACEOF
++
++
++cat >>confdefs.h <<_ACEOF
++@%:@define PACKAGE_TARNAME "$PACKAGE_TARNAME"
++_ACEOF
++
++
++cat >>confdefs.h <<_ACEOF
++@%:@define PACKAGE_VERSION "$PACKAGE_VERSION"
++_ACEOF
++
++
++cat >>confdefs.h <<_ACEOF
++@%:@define PACKAGE_STRING "$PACKAGE_STRING"
++_ACEOF
++
++
++cat >>confdefs.h <<_ACEOF
++@%:@define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
++_ACEOF
++
++
++# Let the site file select an alternate cache file if it wants to.
++# Prefer explicitly selected file to automatically selected ones.
++if test -z "$CONFIG_SITE"; then
++ if test "x$prefix" != xNONE; then
++ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
++ else
++ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
++ fi
++fi
++for ac_site_file in $CONFIG_SITE; do
++ if test -r "$ac_site_file"; then
++ { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
++echo "$as_me: loading site script $ac_site_file" >&6;}
++ sed 's/^/| /' "$ac_site_file" >&5
++ . "$ac_site_file"
++ fi
++done
++
++if test -r "$cache_file"; then
++ # Some versions of bash will fail to source /dev/null (special
++ # files actually), so we avoid doing that.
++ if test -f "$cache_file"; then
++ { echo "$as_me:$LINENO: loading cache $cache_file" >&5
++echo "$as_me: loading cache $cache_file" >&6;}
++ case $cache_file in
++ [\\/]* | ?:[\\/]* ) . $cache_file;;
++ *) . ./$cache_file;;
++ esac
++ fi
++else
++ { echo "$as_me:$LINENO: creating cache $cache_file" >&5
++echo "$as_me: creating cache $cache_file" >&6;}
++ >$cache_file
++fi
++
++# Check that the precious variables saved in the cache have kept the same
++# value.
++ac_cache_corrupted=false
++for ac_var in `(set) 2>&1 |
++ sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do
++ eval ac_old_set=\$ac_cv_env_${ac_var}_set
++ eval ac_new_set=\$ac_env_${ac_var}_set
++ eval ac_old_val="\$ac_cv_env_${ac_var}_value"
++ eval ac_new_val="\$ac_env_${ac_var}_value"
++ case $ac_old_set,$ac_new_set in
++ set,)
++ { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
++echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
++ ac_cache_corrupted=: ;;
++ ,set)
++ { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
++echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
++ ac_cache_corrupted=: ;;
++ ,);;
++ *)
++ if test "x$ac_old_val" != "x$ac_new_val"; then
++ { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
++echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
++ { echo "$as_me:$LINENO: former value: $ac_old_val" >&5
++echo "$as_me: former value: $ac_old_val" >&2;}
++ { echo "$as_me:$LINENO: current value: $ac_new_val" >&5
++echo "$as_me: current value: $ac_new_val" >&2;}
++ ac_cache_corrupted=:
++ fi;;
++ esac
++ # Pass precious variables to config.status.
++ if test "$ac_new_set" = set; then
++ case $ac_new_val in
++ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
++ ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
++ *) ac_arg=$ac_var=$ac_new_val ;;
++ esac
++ case " $ac_configure_args " in
++ *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
++ *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
++ esac
++ fi
++done
++if $ac_cache_corrupted; then
++ { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
++echo "$as_me: error: changes in the environment can compromise the build" >&2;}
++ { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
++echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
++ { (exit 1); exit 1; }; }
++fi
++
++ac_ext=c
++ac_cpp='$CPP $CPPFLAGS'
++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
++ac_compiler_gnu=$ac_cv_c_compiler_gnu
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++# This works around the fact that libtool configuration may change LD
++# for this particular configuration, but some shells, instead of
++# keeping the changes in LD private, export them just because LD is
++# exported.
++ORIGINAL_LD_FOR_MULTILIBS=$LD
++
++ac_aux_dir=
++for ac_dir in . $srcdir/.; do
++ if test -f $ac_dir/install-sh; then
++ ac_aux_dir=$ac_dir
++ ac_install_sh="$ac_aux_dir/install-sh -c"
++ break
++ elif test -f $ac_dir/install.sh; then
++ ac_aux_dir=$ac_dir
++ ac_install_sh="$ac_aux_dir/install.sh -c"
++ break
++ elif test -f $ac_dir/shtool; then
++ ac_aux_dir=$ac_dir
++ ac_install_sh="$ac_aux_dir/shtool install -c"
++ break
++ fi
++done
++if test -z "$ac_aux_dir"; then
++ { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in . $srcdir/." >&5
++echo "$as_me: error: cannot find install-sh or install.sh in . $srcdir/." >&2;}
++ { (exit 1); exit 1; }; }
++fi
++ac_config_guess="$SHELL $ac_aux_dir/config.guess"
++ac_config_sub="$SHELL $ac_aux_dir/config.sub"
++ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure.
++
++
++# Make sure we can run config.sub.
++$ac_config_sub sun4 >/dev/null 2>&1 ||
++ { { echo "$as_me:$LINENO: error: cannot run $ac_config_sub" >&5
++echo "$as_me: error: cannot run $ac_config_sub" >&2;}
++ { (exit 1); exit 1; }; }
++
++echo "$as_me:$LINENO: checking build system type" >&5
++echo $ECHO_N "checking build system type... $ECHO_C" >&6
++if test "${ac_cv_build+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ ac_cv_build_alias=$build_alias
++test -z "$ac_cv_build_alias" &&
++ ac_cv_build_alias=`$ac_config_guess`
++test -z "$ac_cv_build_alias" &&
++ { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5
++echo "$as_me: error: cannot guess build type; you must specify one" >&2;}
++ { (exit 1); exit 1; }; }
++ac_cv_build=`$ac_config_sub $ac_cv_build_alias` ||
++ { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_build_alias failed" >&5
++echo "$as_me: error: $ac_config_sub $ac_cv_build_alias failed" >&2;}
++ { (exit 1); exit 1; }; }
++
++fi
++echo "$as_me:$LINENO: result: $ac_cv_build" >&5
++echo "${ECHO_T}$ac_cv_build" >&6
++build=$ac_cv_build
++build_cpu=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
++build_vendor=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
++build_os=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
++
++
++echo "$as_me:$LINENO: checking host system type" >&5
++echo $ECHO_N "checking host system type... $ECHO_C" >&6
++if test "${ac_cv_host+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ ac_cv_host_alias=$host_alias
++test -z "$ac_cv_host_alias" &&
++ ac_cv_host_alias=$ac_cv_build_alias
++ac_cv_host=`$ac_config_sub $ac_cv_host_alias` ||
++ { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_host_alias failed" >&5
++echo "$as_me: error: $ac_config_sub $ac_cv_host_alias failed" >&2;}
++ { (exit 1); exit 1; }; }
++
++fi
++echo "$as_me:$LINENO: result: $ac_cv_host" >&5
++echo "${ECHO_T}$ac_cv_host" >&6
++host=$ac_cv_host
++host_cpu=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
++host_vendor=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
++host_os=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
++
++
++am__api_version="1.6"
++# Find a good install program. We prefer a C program (faster),
++# so one script is as good as another. But avoid the broken or
++# incompatible versions:
++# SysV /etc/install, /usr/sbin/install
++# SunOS /usr/etc/install
++# IRIX /sbin/install
++# AIX /bin/install
++# AmigaOS /C/install, which installs bootblocks on floppy discs
++# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
++# AFS /usr/afsws/bin/install, which mishandles nonexistent args
++# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
++# ./install, which can be erroneously created by make from ./install.sh.
++echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
++echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6
++if test -z "$INSTALL"; then
++if test "${ac_cv_path_install+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++ IFS=$as_save_IFS
++ test -z "$as_dir" && as_dir=.
++ # Account for people who put trailing slashes in PATH elements.
++case $as_dir/ in
++ ./ | .// | /cC/* | \
++ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
++ /usr/ucb/* ) ;;
++ *)
++ # OSF1 and SCO ODT 3.0 have their own names for install.
++ # Don't use installbsd from OSF since it installs stuff as root
++ # by default.
++ for ac_prog in ginstall scoinst install; do
++ for ac_exec_ext in '' $ac_executable_extensions; do
++ if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
++ if test $ac_prog = install &&
++ grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
++ # AIX install. It has an incompatible calling convention.
++ :
++ elif test $ac_prog = install &&
++ grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
++ # program-specific install script used by HP pwplus--don't use.
++ :
++ else
++ ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
++ break 3
++ fi
++ fi
++ done
++ done
++ ;;
++esac
++done
++
++
++fi
++ if test "${ac_cv_path_install+set}" = set; then
++ INSTALL=$ac_cv_path_install
++ else
++ # As a last resort, use the slow shell script. We don't cache a
++ # path for INSTALL within a source directory, because that will
++ # break other packages using the cache if that directory is
++ # removed, or if the path is relative.
++ INSTALL=$ac_install_sh
++ fi
++fi
++echo "$as_me:$LINENO: result: $INSTALL" >&5
++echo "${ECHO_T}$INSTALL" >&6
++
++# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
++# It thinks the first close brace ends the variable substitution.
++test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
++
++test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
++
++test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
++
++echo "$as_me:$LINENO: checking whether build environment is sane" >&5
++echo $ECHO_N "checking whether build environment is sane... $ECHO_C" >&6
++# Just in case
++sleep 1
++echo timestamp > conftest.file
++# Do `set' in a subshell so we don't clobber the current shell's
++# arguments. Must try -L first in case configure is actually a
++# symlink; some systems play weird games with the mod time of symlinks
++# (eg FreeBSD returns the mod time of the symlink's containing
++# directory).
++if (
++ set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null`
++ if test "$*" = "X"; then
++ # -L didn't work.
++ set X `ls -t $srcdir/configure conftest.file`
++ fi
++ rm -f conftest.file
++ if test "$*" != "X $srcdir/configure conftest.file" \
++ && test "$*" != "X conftest.file $srcdir/configure"; then
++
++ # If neither matched, then we have a broken ls. This can happen
++ # if, for instance, CONFIG_SHELL is bash and it inherits a
++ # broken ls alias from the environment. This has actually
++ # happened. Such a system could not be considered "sane".
++ { { echo "$as_me:$LINENO: error: ls -t appears to fail. Make sure there is not a broken
++alias in your environment" >&5
++echo "$as_me: error: ls -t appears to fail. Make sure there is not a broken
++alias in your environment" >&2;}
++ { (exit 1); exit 1; }; }
++ fi
++
++ test "$2" = conftest.file
++ )
++then
++ # Ok.
++ :
++else
++ { { echo "$as_me:$LINENO: error: newly created file is older than distributed files!
++Check your system clock" >&5
++echo "$as_me: error: newly created file is older than distributed files!
++Check your system clock" >&2;}
++ { (exit 1); exit 1; }; }
++fi
++echo "$as_me:$LINENO: result: yes" >&5
++echo "${ECHO_T}yes" >&6
++test "$program_prefix" != NONE &&
++ program_transform_name="s,^,$program_prefix,;$program_transform_name"
++# Use a double $ so make ignores it.
++test "$program_suffix" != NONE &&
++ program_transform_name="s,\$,$program_suffix,;$program_transform_name"
++# Double any \ or $. echo might interpret backslashes.
++# By default was `s,x,x', remove it if useless.
++cat <<\_ACEOF >conftest.sed
++s/[\\$]/&&/g;s/;s,x,x,$//
++_ACEOF
++program_transform_name=`echo $program_transform_name | sed -f conftest.sed`
++rm conftest.sed
++
++
++# expand $ac_aux_dir to an absolute path
++am_aux_dir=`cd $ac_aux_dir && pwd`
++
++test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing"
++# Use eval to expand $SHELL
++if eval "$MISSING --run true"; then
++ am_missing_run="$MISSING --run "
++else
++ am_missing_run=
++ { echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5
++echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;}
++fi
++
++for ac_prog in gawk mawk nawk awk
++do
++ # Extract the first word of "$ac_prog", so it can be a program name with args.
++set dummy $ac_prog; ac_word=$2
++echo "$as_me:$LINENO: checking for $ac_word" >&5
++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
++if test "${ac_cv_prog_AWK+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ if test -n "$AWK"; then
++ ac_cv_prog_AWK="$AWK" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++ IFS=$as_save_IFS
++ test -z "$as_dir" && as_dir=.
++ for ac_exec_ext in '' $ac_executable_extensions; do
++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++ ac_cv_prog_AWK="$ac_prog"
++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
++ break 2
++ fi
++done
++done
++
++fi
++fi
++AWK=$ac_cv_prog_AWK
++if test -n "$AWK"; then
++ echo "$as_me:$LINENO: result: $AWK" >&5
++echo "${ECHO_T}$AWK" >&6
++else
++ echo "$as_me:$LINENO: result: no" >&5
++echo "${ECHO_T}no" >&6
++fi
++
++ test -n "$AWK" && break
++done
++
++echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \${MAKE}" >&5
++echo $ECHO_N "checking whether ${MAKE-make} sets \${MAKE}... $ECHO_C" >&6
++set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,./+-,__p_,'`
++if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ cat >conftest.make <<\_ACEOF
++all:
++ @echo 'ac_maketemp="${MAKE}"'
++_ACEOF
++# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
++eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=`
++if test -n "$ac_maketemp"; then
++ eval ac_cv_prog_make_${ac_make}_set=yes
++else
++ eval ac_cv_prog_make_${ac_make}_set=no
++fi
++rm -f conftest.make
++fi
++if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
++ echo "$as_me:$LINENO: result: yes" >&5
++echo "${ECHO_T}yes" >&6
++ SET_MAKE=
++else
++ echo "$as_me:$LINENO: result: no" >&5
++echo "${ECHO_T}no" >&6
++ SET_MAKE="MAKE=${MAKE-make}"
++fi
++
++
++# Check whether --enable-multilib or --disable-multilib was given.
++if test "${enable_multilib+set}" = set; then
++ enableval="$enable_multilib"
++ case "${enableval}" in
++ yes) multilib=yes ;;
++ no) multilib=no ;;
++ *) { { echo "$as_me:$LINENO: error: bad value ${enableval} for multilib option" >&5
++echo "$as_me: error: bad value ${enableval} for multilib option" >&2;}
++ { (exit 1); exit 1; }; } ;;
++ esac
++else
++ multilib=yes
++fi;
++
++if test "${srcdir}" = "."; then
++ if test "${with_target_subdir}" != "." -a -n "${with_target_subdir}"; then
++ gc_basedir="${srcdir}/${with_multisrctop}../."
++ else
++ gc_basedir="${srcdir}/${with_multisrctop}."
++ fi
++else
++ gc_basedir="${srcdir}/."
++fi
++
++ac_aux_dir=
++for ac_dir in $gc_basedir/.. $srcdir/$gc_basedir/..; do
++ if test -f $ac_dir/install-sh; then
++ ac_aux_dir=$ac_dir
++ ac_install_sh="$ac_aux_dir/install-sh -c"
++ break
++ elif test -f $ac_dir/install.sh; then
++ ac_aux_dir=$ac_dir
++ ac_install_sh="$ac_aux_dir/install.sh -c"
++ break
++ elif test -f $ac_dir/shtool; then
++ ac_aux_dir=$ac_dir
++ ac_install_sh="$ac_aux_dir/shtool install -c"
++ break
++ fi
++done
++if test -z "$ac_aux_dir"; then
++ { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $gc_basedir/.. $srcdir/$gc_basedir/.." >&5
++echo "$as_me: error: cannot find install-sh or install.sh in $gc_basedir/.. $srcdir/$gc_basedir/.." >&2;}
++ { (exit 1); exit 1; }; }
++fi
++ac_config_guess="$SHELL $ac_aux_dir/config.guess"
++ac_config_sub="$SHELL $ac_aux_dir/config.sub"
++ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure.
++
++if :; then :; else
++ # This overrides the previous occurrence for automake, but not for
++ # autoconf, which is exactly what we want.
++ ac_aux_dir=
++for ac_dir in .. $srcdir/..; do
++ if test -f $ac_dir/install-sh; then
++ ac_aux_dir=$ac_dir
++ ac_install_sh="$ac_aux_dir/install-sh -c"
++ break
++ elif test -f $ac_dir/install.sh; then
++ ac_aux_dir=$ac_dir
++ ac_install_sh="$ac_aux_dir/install.sh -c"
++ break
++ elif test -f $ac_dir/shtool; then
++ ac_aux_dir=$ac_dir
++ ac_install_sh="$ac_aux_dir/shtool install -c"
++ break
++ fi
++done
++if test -z "$ac_aux_dir"; then
++ { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in .. $srcdir/.." >&5
++echo "$as_me: error: cannot find install-sh or install.sh in .. $srcdir/.." >&2;}
++ { (exit 1); exit 1; }; }
++fi
++ac_config_guess="$SHELL $ac_aux_dir/config.guess"
++ac_config_sub="$SHELL $ac_aux_dir/config.sub"
++ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure.
++
++fi
++
++echo "$as_me:$LINENO: checking target system type" >&5
++echo $ECHO_N "checking target system type... $ECHO_C" >&6
++if test "${ac_cv_target+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ ac_cv_target_alias=$target_alias
++test "x$ac_cv_target_alias" = "x" &&
++ ac_cv_target_alias=$ac_cv_host_alias
++ac_cv_target=`$ac_config_sub $ac_cv_target_alias` ||
++ { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_target_alias failed" >&5
++echo "$as_me: error: $ac_config_sub $ac_cv_target_alias failed" >&2;}
++ { (exit 1); exit 1; }; }
++
++fi
++echo "$as_me:$LINENO: result: $ac_cv_target" >&5
++echo "${ECHO_T}$ac_cv_target" >&6
++target=$ac_cv_target
++target_cpu=`echo $ac_cv_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
++target_vendor=`echo $ac_cv_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
++target_os=`echo $ac_cv_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
++
++
++# The aliases save the names the user supplied, while $host etc.
++# will get canonicalized.
++test -n "$target_alias" &&
++ test "$program_prefix$program_suffix$program_transform_name" = \
++ NONENONEs,x,x, &&
++ program_prefix=${target_alias}-
++
++# This works around an automake problem.
++mkinstalldirs="`cd $ac_aux_dir && ${PWDCMD-pwd}`/mkinstalldirs"
++
++
++ # test to see if srcdir already configured
++if test "`cd $srcdir && pwd`" != "`pwd`" &&
++ test -f $srcdir/config.status; then
++ { { echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5
++echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;}
++ { (exit 1); exit 1; }; }
++fi
++
++# Define the identity of the package.
++ PACKAGE=gc
++ VERSION=6.1a1
++
++
++# Some tools Automake needs.
++
++ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"}
++
++
++AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"}
++
++
++AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"}
++
++
++AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"}
++
++
++MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
++
++
++AMTAR=${AMTAR-"${am_missing_run}tar"}
++
++install_sh=${install_sh-"$am_aux_dir/install-sh"}
++
++# Installed binaries are usually stripped using `strip' when the user
++# run `make install-strip'. However `strip' might not be the right
++# tool to use in cross-compilation environments, therefore Automake
++# will honor the `STRIP' environment variable to overrule this program.
++if test "$cross_compiling" != no; then
++ if test -n "$ac_tool_prefix"; then
++ # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
++set dummy ${ac_tool_prefix}strip; ac_word=$2
++echo "$as_me:$LINENO: checking for $ac_word" >&5
++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
++if test "${ac_cv_prog_STRIP+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ if test -n "$STRIP"; then
++ ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++ IFS=$as_save_IFS
++ test -z "$as_dir" && as_dir=.
++ for ac_exec_ext in '' $ac_executable_extensions; do
++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++ ac_cv_prog_STRIP="${ac_tool_prefix}strip"
++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
++ break 2
++ fi
++done
++done
++
++fi
++fi
++STRIP=$ac_cv_prog_STRIP
++if test -n "$STRIP"; then
++ echo "$as_me:$LINENO: result: $STRIP" >&5
++echo "${ECHO_T}$STRIP" >&6
++else
++ echo "$as_me:$LINENO: result: no" >&5
++echo "${ECHO_T}no" >&6
++fi
++
++fi
++if test -z "$ac_cv_prog_STRIP"; then
++ ac_ct_STRIP=$STRIP
++ # Extract the first word of "strip", so it can be a program name with args.
++set dummy strip; ac_word=$2
++echo "$as_me:$LINENO: checking for $ac_word" >&5
++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
++if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ if test -n "$ac_ct_STRIP"; then
++ ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++ IFS=$as_save_IFS
++ test -z "$as_dir" && as_dir=.
++ for ac_exec_ext in '' $ac_executable_extensions; do
++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++ ac_cv_prog_ac_ct_STRIP="strip"
++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
++ break 2
++ fi
++done
++done
++
++ test -z "$ac_cv_prog_ac_ct_STRIP" && ac_cv_prog_ac_ct_STRIP=":"
++fi
++fi
++ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
++if test -n "$ac_ct_STRIP"; then
++ echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5
++echo "${ECHO_T}$ac_ct_STRIP" >&6
++else
++ echo "$as_me:$LINENO: result: no" >&5
++echo "${ECHO_T}no" >&6
++fi
++
++ STRIP=$ac_ct_STRIP
++else
++ STRIP="$ac_cv_prog_STRIP"
++fi
++
++fi
++INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s"
++
++# We need awk for the "check" target. The system "awk" is bad on
++# some platforms.
++
++
++
++
++# AC_CHECK_TOOL does AC_REQUIRE (AC_CANONICAL_BUILD). If we don't
++# run it explicitly here, it will be run implicitly before
++# NEWLIB_CONFIGURE, which doesn't work because that means that it will
++# be run before AC_CANONICAL_HOST.
++
++
++if test -n "$ac_tool_prefix"; then
++ # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args.
++set dummy ${ac_tool_prefix}as; ac_word=$2
++echo "$as_me:$LINENO: checking for $ac_word" >&5
++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
++if test "${ac_cv_prog_AS+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ if test -n "$AS"; then
++ ac_cv_prog_AS="$AS" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++ IFS=$as_save_IFS
++ test -z "$as_dir" && as_dir=.
++ for ac_exec_ext in '' $ac_executable_extensions; do
++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++ ac_cv_prog_AS="${ac_tool_prefix}as"
++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
++ break 2
++ fi
++done
++done
++
++fi
++fi
++AS=$ac_cv_prog_AS
++if test -n "$AS"; then
++ echo "$as_me:$LINENO: result: $AS" >&5
++echo "${ECHO_T}$AS" >&6
++else
++ echo "$as_me:$LINENO: result: no" >&5
++echo "${ECHO_T}no" >&6
++fi
++
++fi
++if test -z "$ac_cv_prog_AS"; then
++ ac_ct_AS=$AS
++ # Extract the first word of "as", so it can be a program name with args.
++set dummy as; ac_word=$2
++echo "$as_me:$LINENO: checking for $ac_word" >&5
++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
++if test "${ac_cv_prog_ac_ct_AS+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ if test -n "$ac_ct_AS"; then
++ ac_cv_prog_ac_ct_AS="$ac_ct_AS" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++ IFS=$as_save_IFS
++ test -z "$as_dir" && as_dir=.
++ for ac_exec_ext in '' $ac_executable_extensions; do
++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++ ac_cv_prog_ac_ct_AS="as"
++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
++ break 2
++ fi
++done
++done
++
++fi
++fi
++ac_ct_AS=$ac_cv_prog_ac_ct_AS
++if test -n "$ac_ct_AS"; then
++ echo "$as_me:$LINENO: result: $ac_ct_AS" >&5
++echo "${ECHO_T}$ac_ct_AS" >&6
++else
++ echo "$as_me:$LINENO: result: no" >&5
++echo "${ECHO_T}no" >&6
++fi
++
++ AS=$ac_ct_AS
++else
++ AS="$ac_cv_prog_AS"
++fi
++
++if test -n "$ac_tool_prefix"; then
++ # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
++set dummy ${ac_tool_prefix}ar; ac_word=$2
++echo "$as_me:$LINENO: checking for $ac_word" >&5
++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
++if test "${ac_cv_prog_AR+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ if test -n "$AR"; then
++ ac_cv_prog_AR="$AR" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++ IFS=$as_save_IFS
++ test -z "$as_dir" && as_dir=.
++ for ac_exec_ext in '' $ac_executable_extensions; do
++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++ ac_cv_prog_AR="${ac_tool_prefix}ar"
++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
++ break 2
++ fi
++done
++done
++
++fi
++fi
++AR=$ac_cv_prog_AR
++if test -n "$AR"; then
++ echo "$as_me:$LINENO: result: $AR" >&5
++echo "${ECHO_T}$AR" >&6
++else
++ echo "$as_me:$LINENO: result: no" >&5
++echo "${ECHO_T}no" >&6
++fi
++
++fi
++if test -z "$ac_cv_prog_AR"; then
++ ac_ct_AR=$AR
++ # Extract the first word of "ar", so it can be a program name with args.
++set dummy ar; ac_word=$2
++echo "$as_me:$LINENO: checking for $ac_word" >&5
++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
++if test "${ac_cv_prog_ac_ct_AR+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ if test -n "$ac_ct_AR"; then
++ ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++ IFS=$as_save_IFS
++ test -z "$as_dir" && as_dir=.
++ for ac_exec_ext in '' $ac_executable_extensions; do
++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++ ac_cv_prog_ac_ct_AR="ar"
++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
++ break 2
++ fi
++done
++done
++
++fi
++fi
++ac_ct_AR=$ac_cv_prog_ac_ct_AR
++if test -n "$ac_ct_AR"; then
++ echo "$as_me:$LINENO: result: $ac_ct_AR" >&5
++echo "${ECHO_T}$ac_ct_AR" >&6
++else
++ echo "$as_me:$LINENO: result: no" >&5
++echo "${ECHO_T}no" >&6
++fi
++
++ AR=$ac_ct_AR
++else
++ AR="$ac_cv_prog_AR"
++fi
++
++if test -n "$ac_tool_prefix"; then
++ # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
++set dummy ${ac_tool_prefix}ranlib; ac_word=$2
++echo "$as_me:$LINENO: checking for $ac_word" >&5
++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
++if test "${ac_cv_prog_RANLIB+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ if test -n "$RANLIB"; then
++ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++ IFS=$as_save_IFS
++ test -z "$as_dir" && as_dir=.
++ for ac_exec_ext in '' $ac_executable_extensions; do
++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++ ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
++ break 2
++ fi
++done
++done
++
++fi
++fi
++RANLIB=$ac_cv_prog_RANLIB
++if test -n "$RANLIB"; then
++ echo "$as_me:$LINENO: result: $RANLIB" >&5
++echo "${ECHO_T}$RANLIB" >&6
++else
++ echo "$as_me:$LINENO: result: no" >&5
++echo "${ECHO_T}no" >&6
++fi
++
++fi
++if test -z "$ac_cv_prog_RANLIB"; then
++ ac_ct_RANLIB=$RANLIB
++ # Extract the first word of "ranlib", so it can be a program name with args.
++set dummy ranlib; ac_word=$2
++echo "$as_me:$LINENO: checking for $ac_word" >&5
++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
++if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ if test -n "$ac_ct_RANLIB"; then
++ ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++ IFS=$as_save_IFS
++ test -z "$as_dir" && as_dir=.
++ for ac_exec_ext in '' $ac_executable_extensions; do
++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++ ac_cv_prog_ac_ct_RANLIB="ranlib"
++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
++ break 2
++ fi
++done
++done
++
++ test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":"
++fi
++fi
++ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
++if test -n "$ac_ct_RANLIB"; then
++ echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5
++echo "${ECHO_T}$ac_ct_RANLIB" >&6
++else
++ echo "$as_me:$LINENO: result: no" >&5
++echo "${ECHO_T}no" >&6
++fi
++
++ RANLIB=$ac_ct_RANLIB
++else
++ RANLIB="$ac_cv_prog_RANLIB"
++fi
++
++
++# Find a good install program. We prefer a C program (faster),
++# so one script is as good as another. But avoid the broken or
++# incompatible versions:
++# SysV /etc/install, /usr/sbin/install
++# SunOS /usr/etc/install
++# IRIX /sbin/install
++# AIX /bin/install
++# AmigaOS /C/install, which installs bootblocks on floppy discs
++# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
++# AFS /usr/afsws/bin/install, which mishandles nonexistent args
++# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
++# ./install, which can be erroneously created by make from ./install.sh.
++echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
++echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6
++if test -z "$INSTALL"; then
++if test "${ac_cv_path_install+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++ IFS=$as_save_IFS
++ test -z "$as_dir" && as_dir=.
++ # Account for people who put trailing slashes in PATH elements.
++case $as_dir/ in
++ ./ | .// | /cC/* | \
++ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
++ /usr/ucb/* ) ;;
++ *)
++ # OSF1 and SCO ODT 3.0 have their own names for install.
++ # Don't use installbsd from OSF since it installs stuff as root
++ # by default.
++ for ac_prog in ginstall scoinst install; do
++ for ac_exec_ext in '' $ac_executable_extensions; do
++ if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
++ if test $ac_prog = install &&
++ grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
++ # AIX install. It has an incompatible calling convention.
++ :
++ elif test $ac_prog = install &&
++ grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
++ # program-specific install script used by HP pwplus--don't use.
++ :
++ else
++ ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
++ break 3
++ fi
++ fi
++ done
++ done
++ ;;
++esac
++done
++
++
++fi
++ if test "${ac_cv_path_install+set}" = set; then
++ INSTALL=$ac_cv_path_install
++ else
++ # As a last resort, use the slow shell script. We don't cache a
++ # path for INSTALL within a source directory, because that will
++ # break other packages using the cache if that directory is
++ # removed, or if the path is relative.
++ INSTALL=$ac_install_sh
++ fi
++fi
++echo "$as_me:$LINENO: result: $INSTALL" >&5
++echo "${ECHO_T}$INSTALL" >&6
++
++# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
++# It thinks the first close brace ends the variable substitution.
++test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
++
++test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
++
++test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
++
++
++echo "$as_me:$LINENO: checking whether to enable maintainer-specific portions of Makefiles" >&5
++echo $ECHO_N "checking whether to enable maintainer-specific portions of Makefiles... $ECHO_C" >&6
++ # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given.
++if test "${enable_maintainer_mode+set}" = set; then
++ enableval="$enable_maintainer_mode"
++ USE_MAINTAINER_MODE=$enableval
++else
++ USE_MAINTAINER_MODE=no
++fi;
++ echo "$as_me:$LINENO: result: $USE_MAINTAINER_MODE" >&5
++echo "${ECHO_T}$USE_MAINTAINER_MODE" >&6
++
++
++if test $USE_MAINTAINER_MODE = yes; then
++ MAINTAINER_MODE_TRUE=
++ MAINTAINER_MODE_FALSE='#'
++else
++ MAINTAINER_MODE_TRUE='#'
++ MAINTAINER_MODE_FALSE=
++fi
++
++ MAINT=$MAINTAINER_MODE_TRUE
++
++
++
++# We need AC_EXEEXT to keep automake happy in cygnus mode. However,
++# at least currently, we never actually build a program, so we never
++# need to use $(EXEEXT). Moreover, the test for EXEEXT normally
++# fails, because we are probably configuring with a cross compiler
++# which can't create executables. So we include AC_EXEEXT to keep
++# automake happy, but we don't execute it, since we don't care about
++# the result.
++if false; then
++ # autoconf 2.50 runs AC_EXEEXT by default, and the macro expands
++ # to nothing, so nothing would remain between `then' and `fi' if it
++ # were not for the `:' below.
++ :
++
++fi
++
++. ${srcdir}/configure.host
++
++case ${gc_basedir} in
++/* | A-Za-z:/\\*) gc_flagbasedir=${gc_basedir} ;;
++*) gc_flagbasedir='$(top_builddir)/'${gc_basedir} ;;
++esac
++
++gc_cflags="${gc_cflags} -I"'$(top_builddir)'"/./targ-include -I${gc_flagbasedir}/libc/include"
++case "${host}" in
++ *-*-cygwin32*)
++ gc_cflags="${gc_cflags} -I${gc_flagbasedir}/../winsup/include"
++ ;;
++esac
++
++
++GC_CFLAGS=${gc_cflags}
++
++
++
++# Check whether --enable-shared or --disable-shared was given.
++if test "${enable_shared+set}" = set; then
++ enableval="$enable_shared"
++ p=${PACKAGE-default}
++case $enableval in
++yes) enable_shared=yes ;;
++no) enable_shared=no ;;
++*)
++ enable_shared=no
++ # Look at the argument we got. We use all the common list separators.
++ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
++ for pkg in $enableval; do
++ if test "X$pkg" = "X$p"; then
++ enable_shared=yes
++ fi
++ done
++ IFS="$ac_save_ifs"
++ ;;
++esac
++else
++ enable_shared=yes
++fi;
++# Check whether --enable-static or --disable-static was given.
++if test "${enable_static+set}" = set; then
++ enableval="$enable_static"
++ p=${PACKAGE-default}
++case $enableval in
++yes) enable_static=yes ;;
++no) enable_static=no ;;
++*)
++ enable_static=no
++ # Look at the argument we got. We use all the common list separators.
++ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
++ for pkg in $enableval; do
++ if test "X$pkg" = "X$p"; then
++ enable_static=yes
++ fi
++ done
++ IFS="$ac_save_ifs"
++ ;;
++esac
++else
++ enable_static=yes
++fi;
++# Check whether --enable-fast-install or --disable-fast-install was given.
++if test "${enable_fast_install+set}" = set; then
++ enableval="$enable_fast_install"
++ p=${PACKAGE-default}
++case $enableval in
++yes) enable_fast_install=yes ;;
++no) enable_fast_install=no ;;
++*)
++ enable_fast_install=no
++ # Look at the argument we got. We use all the common list separators.
++ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
++ for pkg in $enableval; do
++ if test "X$pkg" = "X$p"; then
++ enable_fast_install=yes
++ fi
++ done
++ IFS="$ac_save_ifs"
++ ;;
++esac
++else
++ enable_fast_install=yes
++fi;
++rm -f .deps 2>/dev/null
++mkdir .deps 2>/dev/null
++if test -d .deps; then
++ DEPDIR=.deps
++else
++ # MS-DOS does not allow filenames that begin with a dot.
++ DEPDIR=_deps
++fi
++rmdir .deps 2>/dev/null
++
++
++ ac_config_commands="$ac_config_commands depfiles"
++
++
++am_make=${MAKE-make}
++cat > confinc << 'END'
++doit:
++ @echo done
++END
++# If we don't find an include directive, just comment out the code.
++echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5
++echo $ECHO_N "checking for style of include used by $am_make... $ECHO_C" >&6
++am__include="#"
++am__quote=
++_am_result=none
++# First try GNU make style include.
++echo "include confinc" > confmf
++# We grep out `Entering directory' and `Leaving directory'
++# messages which can occur if `w' ends up in MAKEFLAGS.
++# In particular we don't look at `^make:' because GNU make might
++# be invoked under some other name (usually "gmake"), in which
++# case it prints its new name instead of `make'.
++if test "`$am_make -s -f confmf 2> /dev/null | fgrep -v 'ing directory'`" = "done"; then
++ am__include=include
++ am__quote=
++ _am_result=GNU
++fi
++# Now try BSD make style include.
++if test "$am__include" = "#"; then
++ echo '.include "confinc"' > confmf
++ if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then
++ am__include=.include
++ am__quote="\""
++ _am_result=BSD
++ fi
++fi
++
++
++echo "$as_me:$LINENO: result: $_am_result" >&5
++echo "${ECHO_T}$_am_result" >&6
++rm -f confinc confmf
++
++# Check whether --enable-dependency-tracking or --disable-dependency-tracking was given.
++if test "${enable_dependency_tracking+set}" = set; then
++ enableval="$enable_dependency_tracking"
++
++fi;
++if test "x$enable_dependency_tracking" != xno; then
++ am_depcomp="$ac_aux_dir/depcomp"
++ AMDEPBACKSLASH='\'
++fi
++
++
++if test "x$enable_dependency_tracking" != xno; then
++ AMDEP_TRUE=
++ AMDEP_FALSE='#'
++else
++ AMDEP_TRUE='#'
++ AMDEP_FALSE=
++fi
++
++
++
++ac_ext=c
++ac_cpp='$CPP $CPPFLAGS'
++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
++ac_compiler_gnu=$ac_cv_c_compiler_gnu
++if test -n "$ac_tool_prefix"; then
++ # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
++set dummy ${ac_tool_prefix}gcc; ac_word=$2
++echo "$as_me:$LINENO: checking for $ac_word" >&5
++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
++if test "${ac_cv_prog_CC+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ if test -n "$CC"; then
++ ac_cv_prog_CC="$CC" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++ IFS=$as_save_IFS
++ test -z "$as_dir" && as_dir=.
++ for ac_exec_ext in '' $ac_executable_extensions; do
++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++ ac_cv_prog_CC="${ac_tool_prefix}gcc"
++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
++ break 2
++ fi
++done
++done
++
++fi
++fi
++CC=$ac_cv_prog_CC
++if test -n "$CC"; then
++ echo "$as_me:$LINENO: result: $CC" >&5
++echo "${ECHO_T}$CC" >&6
++else
++ echo "$as_me:$LINENO: result: no" >&5
++echo "${ECHO_T}no" >&6
++fi
++
++fi
++if test -z "$ac_cv_prog_CC"; then
++ ac_ct_CC=$CC
++ # Extract the first word of "gcc", so it can be a program name with args.
++set dummy gcc; ac_word=$2
++echo "$as_me:$LINENO: checking for $ac_word" >&5
++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
++if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ if test -n "$ac_ct_CC"; then
++ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++ IFS=$as_save_IFS
++ test -z "$as_dir" && as_dir=.
++ for ac_exec_ext in '' $ac_executable_extensions; do
++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++ ac_cv_prog_ac_ct_CC="gcc"
++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
++ break 2
++ fi
++done
++done
++
++fi
++fi
++ac_ct_CC=$ac_cv_prog_ac_ct_CC
++if test -n "$ac_ct_CC"; then
++ echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
++echo "${ECHO_T}$ac_ct_CC" >&6
++else
++ echo "$as_me:$LINENO: result: no" >&5
++echo "${ECHO_T}no" >&6
++fi
++
++ CC=$ac_ct_CC
++else
++ CC="$ac_cv_prog_CC"
++fi
++
++if test -z "$CC"; then
++ if test -n "$ac_tool_prefix"; then
++ # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
++set dummy ${ac_tool_prefix}cc; ac_word=$2
++echo "$as_me:$LINENO: checking for $ac_word" >&5
++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
++if test "${ac_cv_prog_CC+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ if test -n "$CC"; then
++ ac_cv_prog_CC="$CC" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++ IFS=$as_save_IFS
++ test -z "$as_dir" && as_dir=.
++ for ac_exec_ext in '' $ac_executable_extensions; do
++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++ ac_cv_prog_CC="${ac_tool_prefix}cc"
++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
++ break 2
++ fi
++done
++done
++
++fi
++fi
++CC=$ac_cv_prog_CC
++if test -n "$CC"; then
++ echo "$as_me:$LINENO: result: $CC" >&5
++echo "${ECHO_T}$CC" >&6
++else
++ echo "$as_me:$LINENO: result: no" >&5
++echo "${ECHO_T}no" >&6
++fi
++
++fi
++if test -z "$ac_cv_prog_CC"; then
++ ac_ct_CC=$CC
++ # Extract the first word of "cc", so it can be a program name with args.
++set dummy cc; ac_word=$2
++echo "$as_me:$LINENO: checking for $ac_word" >&5
++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
++if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ if test -n "$ac_ct_CC"; then
++ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++ IFS=$as_save_IFS
++ test -z "$as_dir" && as_dir=.
++ for ac_exec_ext in '' $ac_executable_extensions; do
++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++ ac_cv_prog_ac_ct_CC="cc"
++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
++ break 2
++ fi
++done
++done
++
++fi
++fi
++ac_ct_CC=$ac_cv_prog_ac_ct_CC
++if test -n "$ac_ct_CC"; then
++ echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
++echo "${ECHO_T}$ac_ct_CC" >&6
++else
++ echo "$as_me:$LINENO: result: no" >&5
++echo "${ECHO_T}no" >&6
++fi
++
++ CC=$ac_ct_CC
++else
++ CC="$ac_cv_prog_CC"
++fi
++
++fi
++if test -z "$CC"; then
++ # Extract the first word of "cc", so it can be a program name with args.
++set dummy cc; ac_word=$2
++echo "$as_me:$LINENO: checking for $ac_word" >&5
++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
++if test "${ac_cv_prog_CC+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ if test -n "$CC"; then
++ ac_cv_prog_CC="$CC" # Let the user override the test.
++else
++ ac_prog_rejected=no
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++ IFS=$as_save_IFS
++ test -z "$as_dir" && as_dir=.
++ for ac_exec_ext in '' $ac_executable_extensions; do
++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
++ ac_prog_rejected=yes
++ continue
++ fi
++ ac_cv_prog_CC="cc"
++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
++ break 2
++ fi
++done
++done
++
++if test $ac_prog_rejected = yes; then
++ # We found a bogon in the path, so make sure we never use it.
++ set dummy $ac_cv_prog_CC
++ shift
++ if test $@%:@ != 0; then
++ # We chose a different compiler from the bogus one.
++ # However, it has the same basename, so the bogon will be chosen
++ # first if we set CC to just the basename; use the full file name.
++ shift
++ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
++ fi
++fi
++fi
++fi
++CC=$ac_cv_prog_CC
++if test -n "$CC"; then
++ echo "$as_me:$LINENO: result: $CC" >&5
++echo "${ECHO_T}$CC" >&6
++else
++ echo "$as_me:$LINENO: result: no" >&5
++echo "${ECHO_T}no" >&6
++fi
++
++fi
++if test -z "$CC"; then
++ if test -n "$ac_tool_prefix"; then
++ for ac_prog in cl
++ do
++ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
++set dummy $ac_tool_prefix$ac_prog; ac_word=$2
++echo "$as_me:$LINENO: checking for $ac_word" >&5
++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
++if test "${ac_cv_prog_CC+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ if test -n "$CC"; then
++ ac_cv_prog_CC="$CC" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++ IFS=$as_save_IFS
++ test -z "$as_dir" && as_dir=.
++ for ac_exec_ext in '' $ac_executable_extensions; do
++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++ ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
++ break 2
++ fi
++done
++done
++
++fi
++fi
++CC=$ac_cv_prog_CC
++if test -n "$CC"; then
++ echo "$as_me:$LINENO: result: $CC" >&5
++echo "${ECHO_T}$CC" >&6
++else
++ echo "$as_me:$LINENO: result: no" >&5
++echo "${ECHO_T}no" >&6
++fi
++
++ test -n "$CC" && break
++ done
++fi
++if test -z "$CC"; then
++ ac_ct_CC=$CC
++ for ac_prog in cl
++do
++ # Extract the first word of "$ac_prog", so it can be a program name with args.
++set dummy $ac_prog; ac_word=$2
++echo "$as_me:$LINENO: checking for $ac_word" >&5
++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
++if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ if test -n "$ac_ct_CC"; then
++ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++ IFS=$as_save_IFS
++ test -z "$as_dir" && as_dir=.
++ for ac_exec_ext in '' $ac_executable_extensions; do
++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++ ac_cv_prog_ac_ct_CC="$ac_prog"
++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
++ break 2
++ fi
++done
++done
++
++fi
++fi
++ac_ct_CC=$ac_cv_prog_ac_ct_CC
++if test -n "$ac_ct_CC"; then
++ echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
++echo "${ECHO_T}$ac_ct_CC" >&6
++else
++ echo "$as_me:$LINENO: result: no" >&5
++echo "${ECHO_T}no" >&6
++fi
++
++ test -n "$ac_ct_CC" && break
++done
++
++ CC=$ac_ct_CC
++fi
++
++fi
++
++
++test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH" >&5
++echo "$as_me: error: no acceptable C compiler found in \$PATH" >&2;}
++ { (exit 1); exit 1; }; }
++
++# Provide some information about the compiler.
++echo "$as_me:$LINENO:" \
++ "checking for C compiler version" >&5
++ac_compiler=`set X $ac_compile; echo $2`
++{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
++ (eval $ac_compiler --version </dev/null >&5) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); }
++{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
++ (eval $ac_compiler -v </dev/null >&5) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); }
++{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
++ (eval $ac_compiler -V </dev/null >&5) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); }
++
++cat >conftest.$ac_ext <<_ACEOF
++#line $LINENO "configure"
++#include "confdefs.h"
++
++int
++main ()
++{
++
++ ;
++ return 0;
++}
++_ACEOF
++ac_clean_files_save=$ac_clean_files
++ac_clean_files="$ac_clean_files a.out a.exe"
++# Try to create an executable without -o first, disregard a.out.
++# It will help us diagnose broken compilers, and finding out an intuition
++# of exeext.
++echo "$as_me:$LINENO: checking for C compiler default output" >&5
++echo $ECHO_N "checking for C compiler default output... $ECHO_C" >&6
++ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
++if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5
++ (eval $ac_link_default) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); }; then
++ # Find the output, starting from the most likely. This scheme is
++# not robust to junk in `.', hence go to wildcards (a.*) only as a last
++# resort.
++
++# Be careful to initialize this variable, since it used to be cached.
++# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile.
++ac_cv_exeext=
++for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.*; do
++ test -f "$ac_file" || continue
++ case $ac_file in
++ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;;
++ a.out ) # We found the default executable, but exeext='' is most
++ # certainly right.
++ break;;
++ *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
++ # FIXME: I believe we export ac_cv_exeext for Libtool --akim.
++ export ac_cv_exeext
++ break;;
++ * ) break;;
++ esac
++done
++else
++ echo "$as_me: failed program was:" >&5
++cat conftest.$ac_ext >&5
++{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
++check \`config.log' for details." >&5
++echo "$as_me: error: C compiler cannot create executables
++check \`config.log' for details." >&2;}
++ { (exit 77); exit 77; }; }
++fi
++
++ac_exeext=$ac_cv_exeext
++echo "$as_me:$LINENO: result: $ac_file" >&5
++echo "${ECHO_T}$ac_file" >&6
++
++# Check the compiler produces executables we can run. If not, either
++# the compiler is broken, or we cross compile.
++echo "$as_me:$LINENO: checking whether the C compiler works" >&5
++echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6
++# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
++# If not cross compiling, check that we can run a simple program.
++if test "$cross_compiling" != yes; then
++ if { ac_try='./$ac_file'
++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++ (eval $ac_try) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); }; }; then
++ cross_compiling=no
++ else
++ if test "$cross_compiling" = maybe; then
++ cross_compiling=yes
++ else
++ { { echo "$as_me:$LINENO: error: cannot run C compiled programs.
++If you meant to cross compile, use \`--host'." >&5
++echo "$as_me: error: cannot run C compiled programs.
++If you meant to cross compile, use \`--host'." >&2;}
++ { (exit 1); exit 1; }; }
++ fi
++ fi
++fi
++echo "$as_me:$LINENO: result: yes" >&5
++echo "${ECHO_T}yes" >&6
++
++rm -f a.out a.exe conftest$ac_cv_exeext
++ac_clean_files=$ac_clean_files_save
++# Check the compiler produces executables we can run. If not, either
++# the compiler is broken, or we cross compile.
++echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
++echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6
++echo "$as_me:$LINENO: result: $cross_compiling" >&5
++echo "${ECHO_T}$cross_compiling" >&6
++
++echo "$as_me:$LINENO: checking for suffix of executables" >&5
++echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6
++if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
++ (eval $ac_link) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); }; then
++ # If both `conftest.exe' and `conftest' are `present' (well, observable)
++# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
++# work properly (i.e., refer to `conftest.exe'), while it won't with
++# `rm'.
++for ac_file in conftest.exe conftest conftest.*; do
++ test -f "$ac_file" || continue
++ case $ac_file in
++ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;;
++ *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
++ export ac_cv_exeext
++ break;;
++ * ) break;;
++ esac
++done
++else
++ { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link" >&5
++echo "$as_me: error: cannot compute suffix of executables: cannot compile and link" >&2;}
++ { (exit 1); exit 1; }; }
++fi
++
++rm -f conftest$ac_cv_exeext
++echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
++echo "${ECHO_T}$ac_cv_exeext" >&6
++
++rm -f conftest.$ac_ext
++EXEEXT=$ac_cv_exeext
++ac_exeext=$EXEEXT
++echo "$as_me:$LINENO: checking for suffix of object files" >&5
++echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6
++if test "${ac_cv_objext+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ cat >conftest.$ac_ext <<_ACEOF
++#line $LINENO "configure"
++#include "confdefs.h"
++
++int
++main ()
++{
++
++ ;
++ return 0;
++}
++_ACEOF
++rm -f conftest.o conftest.obj
++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
++ (eval $ac_compile) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); }; then
++ for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do
++ case $ac_file in
++ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;;
++ *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
++ break;;
++ esac
++done
++else
++ echo "$as_me: failed program was:" >&5
++cat conftest.$ac_ext >&5
++{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile" >&5
++echo "$as_me: error: cannot compute suffix of object files: cannot compile" >&2;}
++ { (exit 1); exit 1; }; }
++fi
++
++rm -f conftest.$ac_cv_objext conftest.$ac_ext
++fi
++echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
++echo "${ECHO_T}$ac_cv_objext" >&6
++OBJEXT=$ac_cv_objext
++ac_objext=$OBJEXT
++echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
++echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6
++if test "${ac_cv_c_compiler_gnu+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ cat >conftest.$ac_ext <<_ACEOF
++#line $LINENO "configure"
++#include "confdefs.h"
++
++int
++main ()
++{
++#ifndef __GNUC__
++ choke me
++#endif
++
++ ;
++ return 0;
++}
++_ACEOF
++rm -f conftest.$ac_objext
++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
++ (eval $ac_compile) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); } &&
++ { ac_try='test -s conftest.$ac_objext'
++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++ (eval $ac_try) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); }; }; then
++ ac_compiler_gnu=yes
++else
++ echo "$as_me: failed program was:" >&5
++cat conftest.$ac_ext >&5
++ac_compiler_gnu=no
++fi
++rm -f conftest.$ac_objext conftest.$ac_ext
++ac_cv_c_compiler_gnu=$ac_compiler_gnu
++
++fi
++echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
++echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6
++GCC=`test $ac_compiler_gnu = yes && echo yes`
++ac_test_CFLAGS=${CFLAGS+set}
++ac_save_CFLAGS=$CFLAGS
++CFLAGS="-g"
++echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
++echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6
++if test "${ac_cv_prog_cc_g+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ cat >conftest.$ac_ext <<_ACEOF
++#line $LINENO "configure"
++#include "confdefs.h"
++
++int
++main ()
++{
++
++ ;
++ return 0;
++}
++_ACEOF
++rm -f conftest.$ac_objext
++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
++ (eval $ac_compile) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); } &&
++ { ac_try='test -s conftest.$ac_objext'
++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++ (eval $ac_try) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); }; }; then
++ ac_cv_prog_cc_g=yes
++else
++ echo "$as_me: failed program was:" >&5
++cat conftest.$ac_ext >&5
++ac_cv_prog_cc_g=no
++fi
++rm -f conftest.$ac_objext conftest.$ac_ext
++fi
++echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
++echo "${ECHO_T}$ac_cv_prog_cc_g" >&6
++if test "$ac_test_CFLAGS" = set; then
++ CFLAGS=$ac_save_CFLAGS
++elif test $ac_cv_prog_cc_g = yes; then
++ if test "$GCC" = yes; then
++ CFLAGS="-g -O2"
++ else
++ CFLAGS="-g"
++ fi
++else
++ if test "$GCC" = yes; then
++ CFLAGS="-O2"
++ else
++ CFLAGS=
++ fi
++fi
++echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5
++echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6
++if test "${ac_cv_prog_cc_stdc+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ ac_cv_prog_cc_stdc=no
++ac_save_CC=$CC
++cat >conftest.$ac_ext <<_ACEOF
++#line $LINENO "configure"
++#include "confdefs.h"
++#include <stdarg.h>
++#include <stdio.h>
++#include <sys/types.h>
++#include <sys/stat.h>
++/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
++struct buf { int x; };
++FILE * (*rcsopen) (struct buf *, struct stat *, int);
++static char *e (p, i)
++ char **p;
++ int i;
++{
++ return p[i];
++}
++static char *f (char * (*g) (char **, int), char **p, ...)
++{
++ char *s;
++ va_list v;
++ va_start (v,p);
++ s = g (p, va_arg (v,int));
++ va_end (v);
++ return s;
++}
++int test (int i, double x);
++struct s1 {int (*f) (int a);};
++struct s2 {int (*f) (double a);};
++int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
++int argc;
++char **argv;
++int
++main ()
++{
++return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
++ ;
++ return 0;
++}
++_ACEOF
++# Don't try gcc -ansi; that turns off useful extensions and
++# breaks some systems' header files.
++# AIX -qlanglvl=ansi
++# Ultrix and OSF/1 -std1
++# HP-UX 10.20 and later -Ae
++# HP-UX older versions -Aa -D_HPUX_SOURCE
++# SVR4 -Xc -D__EXTENSIONS__
++for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
++do
++ CC="$ac_save_CC $ac_arg"
++ rm -f conftest.$ac_objext
++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
++ (eval $ac_compile) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); } &&
++ { ac_try='test -s conftest.$ac_objext'
++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++ (eval $ac_try) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); }; }; then
++ ac_cv_prog_cc_stdc=$ac_arg
++break
++else
++ echo "$as_me: failed program was:" >&5
++cat conftest.$ac_ext >&5
++fi
++rm -f conftest.$ac_objext
++done
++rm -f conftest.$ac_ext conftest.$ac_objext
++CC=$ac_save_CC
++
++fi
++
++case "x$ac_cv_prog_cc_stdc" in
++ x|xno)
++ echo "$as_me:$LINENO: result: none needed" >&5
++echo "${ECHO_T}none needed" >&6 ;;
++ *)
++ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
++echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
++ CC="$CC $ac_cv_prog_cc_stdc" ;;
++esac
++
++# Some people use a C++ compiler to compile C. Since we use `exit',
++# in C++ we need to declare it. In case someone uses the same compiler
++# for both compiling C and C++ we need to have the C++ compiler decide
++# the declaration of exit, since it's the most demanding environment.
++cat >conftest.$ac_ext <<_ACEOF
++@%:@ifndef __cplusplus
++ choke me
++@%:@endif
++_ACEOF
++rm -f conftest.$ac_objext
++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
++ (eval $ac_compile) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); } &&
++ { ac_try='test -s conftest.$ac_objext'
++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++ (eval $ac_try) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); }; }; then
++ for ac_declaration in \
++ ''\
++ '#include <stdlib.h>' \
++ 'extern "C" void std::exit (int) throw (); using std::exit;' \
++ 'extern "C" void std::exit (int); using std::exit;' \
++ 'extern "C" void exit (int) throw ();' \
++ 'extern "C" void exit (int);' \
++ 'void exit (int);'
++do
++ cat >conftest.$ac_ext <<_ACEOF
++#line $LINENO "configure"
++#include "confdefs.h"
++@%:@include <stdlib.h>
++$ac_declaration
++int
++main ()
++{
++exit (42);
++ ;
++ return 0;
++}
++_ACEOF
++rm -f conftest.$ac_objext
++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
++ (eval $ac_compile) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); } &&
++ { ac_try='test -s conftest.$ac_objext'
++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++ (eval $ac_try) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); }; }; then
++ :
++else
++ echo "$as_me: failed program was:" >&5
++cat conftest.$ac_ext >&5
++continue
++fi
++rm -f conftest.$ac_objext conftest.$ac_ext
++ cat >conftest.$ac_ext <<_ACEOF
++#line $LINENO "configure"
++#include "confdefs.h"
++$ac_declaration
++int
++main ()
++{
++exit (42);
++ ;
++ return 0;
++}
++_ACEOF
++rm -f conftest.$ac_objext
++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
++ (eval $ac_compile) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); } &&
++ { ac_try='test -s conftest.$ac_objext'
++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++ (eval $ac_try) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); }; }; then
++ break
++else
++ echo "$as_me: failed program was:" >&5
++cat conftest.$ac_ext >&5
++fi
++rm -f conftest.$ac_objext conftest.$ac_ext
++done
++rm -f conftest*
++if test -n "$ac_declaration"; then
++ echo '#ifdef __cplusplus' >>confdefs.h
++ echo $ac_declaration >>confdefs.h
++ echo '#endif' >>confdefs.h
++fi
++
++else
++ echo "$as_me: failed program was:" >&5
++cat conftest.$ac_ext >&5
++fi
++rm -f conftest.$ac_objext conftest.$ac_ext
++ac_ext=c
++ac_cpp='$CPP $CPPFLAGS'
++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
++ac_compiler_gnu=$ac_cv_c_compiler_gnu
++
++depcc="$CC" am_compiler_list=
++
++echo "$as_me:$LINENO: checking dependency style of $depcc" >&5
++echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6
++if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
++ # We make a subdir and do the tests there. Otherwise we can end up
++ # making bogus files that we don't know about and never remove. For
++ # instance it was reported that on HP-UX the gcc test will end up
++ # making a dummy file named `D' -- because `-MD' means `put the output
++ # in D'.
++ mkdir conftest.dir
++ # Copy depcomp to subdir because otherwise we won't find it if we're
++ # using a relative directory.
++ cp "$am_depcomp" conftest.dir
++ cd conftest.dir
++
++ am_cv_CC_dependencies_compiler_type=none
++ if test "$am_compiler_list" = ""; then
++ am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
++ fi
++ for depmode in $am_compiler_list; do
++ # We need to recreate these files for each test, as the compiler may
++ # overwrite some of them when testing with obscure command lines.
++ # This happens at least with the AIX C compiler.
++ echo '#include "conftest.h"' > conftest.c
++ echo 'int i;' > conftest.h
++ echo "${am__include} ${am__quote}conftest.Po${am__quote}" > confmf
++
++ case $depmode in
++ nosideeffect)
++ # after this tag, mechanisms are not by side-effect, so they'll
++ # only be used when explicitly requested
++ if test "x$enable_dependency_tracking" = xyes; then
++ continue
++ else
++ break
++ fi
++ ;;
++ none) break ;;
++ esac
++ # We check with `-c' and `-o' for the sake of the "dashmstdout"
++ # mode. It turns out that the SunPro C++ compiler does not properly
++ # handle `-M -o', and we need to detect this.
++ if depmode=$depmode \
++ source=conftest.c object=conftest.o \
++ depfile=conftest.Po tmpdepfile=conftest.TPo \
++ $SHELL ./depcomp $depcc -c conftest.c -o conftest.o >/dev/null 2>&1 &&
++ grep conftest.h conftest.Po > /dev/null 2>&1 &&
++ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
++ am_cv_CC_dependencies_compiler_type=$depmode
++ break
++ fi
++ done
++
++ cd ..
++ rm -rf conftest.dir
++else
++ am_cv_CC_dependencies_compiler_type=none
++fi
++
++fi
++echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5
++echo "${ECHO_T}$am_cv_CC_dependencies_compiler_type" >&6
++CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type
++
++
++# Find the correct PATH separator. Usually this is `:', but
++# DJGPP uses `;' like DOS.
++if test "X${PATH_SEPARATOR+set}" != Xset; then
++ UNAME=${UNAME-`uname 2>/dev/null`}
++ case X$UNAME in
++ *-DOS) lt_cv_sys_path_separator=';' ;;
++ *) lt_cv_sys_path_separator=':' ;;
++ esac
++ PATH_SEPARATOR=$lt_cv_sys_path_separator
++fi
++
++
++# Check whether --with-gnu-ld or --without-gnu-ld was given.
++if test "${with_gnu_ld+set}" = set; then
++ withval="$with_gnu_ld"
++ test "$withval" = no || with_gnu_ld=yes
++else
++ with_gnu_ld=no
++fi;
++ac_prog=ld
++if test "$GCC" = yes; then
++ # Check if gcc -print-prog-name=ld gives a path.
++ echo "$as_me:$LINENO: checking for ld used by GCC" >&5
++echo $ECHO_N "checking for ld used by GCC... $ECHO_C" >&6
++ case $host in
++ *-*-mingw*)
++ # gcc leaves a trailing carriage return which upsets mingw
++ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
++ *)
++ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
++ esac
++ case $ac_prog in
++ # Accept absolute paths.
++ [\\/]* | [A-Za-z]:[\\/]*)
++ re_direlt='/[^/][^/]*/\.\./'
++ # Canonicalize the path of ld
++ ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
++ while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
++ ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
++ done
++ test -z "$LD" && LD="$ac_prog"
++ ;;
++ "")
++ # If it fails, then pretend we aren't using GCC.
++ ac_prog=ld
++ ;;
++ *)
++ # If it is relative, then search for the first ld in PATH.
++ with_gnu_ld=unknown
++ ;;
++ esac
++elif test "$with_gnu_ld" = yes; then
++ echo "$as_me:$LINENO: checking for GNU ld" >&5
++echo $ECHO_N "checking for GNU ld... $ECHO_C" >&6
++else
++ echo "$as_me:$LINENO: checking for non-GNU ld" >&5
++echo $ECHO_N "checking for non-GNU ld... $ECHO_C" >&6
++fi
++if test "${lt_cv_path_LD+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ if test -z "$LD"; then
++ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
++ for ac_dir in $PATH; do
++ test -z "$ac_dir" && ac_dir=.
++ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
++ lt_cv_path_LD="$ac_dir/$ac_prog"
++ # Check to see if the program is GNU ld. I'd rather use --version,
++ # but apparently some GNU ld's only accept -v.
++ # Break only if it was the GNU/non-GNU ld that we prefer.
++ if "$lt_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
++ test "$with_gnu_ld" != no && break
++ else
++ test "$with_gnu_ld" != yes && break
++ fi
++ fi
++ done
++ IFS="$ac_save_ifs"
++else
++ lt_cv_path_LD="$LD" # Let the user override the test with a path.
++fi
++fi
++
++LD="$lt_cv_path_LD"
++if test -n "$LD"; then
++ echo "$as_me:$LINENO: result: $LD" >&5
++echo "${ECHO_T}$LD" >&6
++else
++ echo "$as_me:$LINENO: result: no" >&5
++echo "${ECHO_T}no" >&6
++fi
++test -z "$LD" && { { echo "$as_me:$LINENO: error: no acceptable ld found in \$PATH" >&5
++echo "$as_me: error: no acceptable ld found in \$PATH" >&2;}
++ { (exit 1); exit 1; }; }
++echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5
++echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6
++if test "${lt_cv_prog_gnu_ld+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ # I'd rather use --version here, but apparently some GNU ld's only accept -v.
++if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
++ lt_cv_prog_gnu_ld=yes
++else
++ lt_cv_prog_gnu_ld=no
++fi
++fi
++echo "$as_me:$LINENO: result: $lt_cv_prog_gnu_ld" >&5
++echo "${ECHO_T}$lt_cv_prog_gnu_ld" >&6
++with_gnu_ld=$lt_cv_prog_gnu_ld
++
++
++echo "$as_me:$LINENO: checking for $LD option to reload object files" >&5
++echo $ECHO_N "checking for $LD option to reload object files... $ECHO_C" >&6
++if test "${lt_cv_ld_reload_flag+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ lt_cv_ld_reload_flag='-r'
++fi
++echo "$as_me:$LINENO: result: $lt_cv_ld_reload_flag" >&5
++echo "${ECHO_T}$lt_cv_ld_reload_flag" >&6
++reload_flag=$lt_cv_ld_reload_flag
++test -n "$reload_flag" && reload_flag=" $reload_flag"
++
++echo "$as_me:$LINENO: checking for BSD-compatible nm" >&5
++echo $ECHO_N "checking for BSD-compatible nm... $ECHO_C" >&6
++if test "${lt_cv_path_NM+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ if test -n "$NM"; then
++ # Let the user override the test.
++ lt_cv_path_NM="$NM"
++else
++ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
++ for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do
++ test -z "$ac_dir" && ac_dir=.
++ tmp_nm=$ac_dir/${ac_tool_prefix}nm
++ if test -f $tmp_nm || test -f $tmp_nm$ac_exeext ; then
++ # Check to see if the nm accepts a BSD-compat flag.
++ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
++ # nm: unknown option "B" ignored
++ # Tru64's nm complains that /dev/null is an invalid object file
++ if ($tmp_nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep '(/dev/null|Invalid file or object type)' >/dev/null; then
++ lt_cv_path_NM="$tmp_nm -B"
++ break
++ elif ($tmp_nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
++ lt_cv_path_NM="$tmp_nm -p"
++ break
++ else
++ lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
++ continue # so that we can try to find one that supports BSD flags
++ fi
++ fi
++ done
++ IFS="$ac_save_ifs"
++ test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm
++fi
++fi
++
++NM="$lt_cv_path_NM"
++echo "$as_me:$LINENO: result: $NM" >&5
++echo "${ECHO_T}$NM" >&6
++
++echo "$as_me:$LINENO: checking whether ln -s works" >&5
++echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6
++LN_S=$as_ln_s
++if test "$LN_S" = "ln -s"; then
++ echo "$as_me:$LINENO: result: yes" >&5
++echo "${ECHO_T}yes" >&6
++else
++ echo "$as_me:$LINENO: result: no, using $LN_S" >&5
++echo "${ECHO_T}no, using $LN_S" >&6
++fi
++
++echo "$as_me:$LINENO: checking how to recognise dependant libraries" >&5
++echo $ECHO_N "checking how to recognise dependant libraries... $ECHO_C" >&6
++if test "${lt_cv_deplibs_check_method+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ lt_cv_file_magic_cmd='$MAGIC_CMD'
++lt_cv_file_magic_test_file=
++lt_cv_deplibs_check_method='unknown'
++# Need to set the preceding variable on all platforms that support
++# interlibrary dependencies.
++# 'none' -- dependencies not supported.
++# `unknown' -- same as none, but documents that we really don't know.
++# 'pass_all' -- all dependencies passed with no checks.
++# 'test_compile' -- check by making test program.
++# 'file_magic [[regex]]' -- check by looking for files in library path
++# which responds to the $file_magic_cmd with a given egrep regex.
++# If you have `file' or equivalent on your system and you're not sure
++# whether `pass_all' will *always* work, you probably want this one.
++
++case $host_os in
++aix4* | aix5*)
++ lt_cv_deplibs_check_method=pass_all
++ ;;
++
++beos*)
++ lt_cv_deplibs_check_method=pass_all
++ ;;
++
++bsdi4*)
++ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'
++ lt_cv_file_magic_cmd='/usr/bin/file -L'
++ lt_cv_file_magic_test_file=/shlib/libc.so
++ ;;
++
++cygwin* | mingw* | pw32*)
++ lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
++ lt_cv_file_magic_cmd='$OBJDUMP -f'
++ ;;
++
++darwin* | rhapsody*)
++ lt_cv_deplibs_check_method='file_magic Mach-O dynamically linked shared library'
++ lt_cv_file_magic_cmd='/usr/bin/file -L'
++ case "$host_os" in
++ rhapsody* | darwin1.[012])
++ lt_cv_file_magic_test_file='/System/Library/Frameworks/System.framework/System'
++ ;;
++ *) # Darwin 1.3 on
++ lt_cv_file_magic_test_file='/usr/lib/libSystem.dylib'
++ ;;
++ esac
++ ;;
++
++freebsd*)
++ if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
++ case $host_cpu in
++ i*86 )
++ # Not sure whether the presence of OpenBSD here was a mistake.
++ # Let's accept both of them until this is cleared up.
++ lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD)/i[3-9]86 (compact )?demand paged shared library'
++ lt_cv_file_magic_cmd=/usr/bin/file
++ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
++ ;;
++ esac
++ else
++ lt_cv_deplibs_check_method=pass_all
++ fi
++ ;;
++
++gnu*)
++ lt_cv_deplibs_check_method=pass_all
++ ;;
++
++hpux10.20*|hpux11*)
++ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library'
++ lt_cv_file_magic_cmd=/usr/bin/file
++ lt_cv_file_magic_test_file=/usr/lib/libc.sl
++ ;;
++
++irix5* | irix6*)
++ case $host_os in
++ irix5*)
++ # this will be overridden with pass_all, but let us keep it just in case
++ lt_cv_deplibs_check_method="file_magic ELF 32-bit MSB dynamic lib MIPS - version 1"
++ ;;
++ *)
++ case $LD in
++ *-32|*"-32 ") libmagic=32-bit;;
++ *-n32|*"-n32 ") libmagic=N32;;
++ *-64|*"-64 ") libmagic=64-bit;;
++ *) libmagic=never-match;;
++ esac
++ # this will be overridden with pass_all, but let us keep it just in case
++ lt_cv_deplibs_check_method="file_magic ELF ${libmagic} MSB mips-[1234] dynamic lib MIPS - version 1"
++ ;;
++ esac
++ lt_cv_file_magic_test_file=`echo /lib${libsuff}/libc.so*`
++ lt_cv_deplibs_check_method=pass_all
++ ;;
++
++# This must be Linux ELF.
++linux-gnu*)
++ case $host_cpu in
++ alpha* | hppa* | i*86 | powerpc* | sparc* | ia64* )
++ lt_cv_deplibs_check_method=pass_all ;;
++ *)
++ # glibc up to 2.1.1 does not perform some relocations on ARM
++ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' ;;
++ esac
++ lt_cv_file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so`
++ ;;
++
++netbsd*)
++ if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
++ lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so\.[0-9]+\.[0-9]+$'
++ else
++ lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so$'
++ fi
++ ;;
++
++newos6*)
++ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)'
++ lt_cv_file_magic_cmd=/usr/bin/file
++ lt_cv_file_magic_test_file=/usr/lib/libnls.so
++ ;;
++
++openbsd*)
++ lt_cv_file_magic_cmd=/usr/bin/file
++ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
++ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
++ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB shared object'
++ else
++ lt_cv_deplibs_check_method='file_magic OpenBSD.* shared library'
++ fi
++ ;;
++
++osf3* | osf4* | osf5*)
++ # this will be overridden with pass_all, but let us keep it just in case
++ lt_cv_deplibs_check_method='file_magic COFF format alpha shared library'
++ lt_cv_file_magic_test_file=/shlib/libc.so
++ lt_cv_deplibs_check_method=pass_all
++ ;;
++
++sco3.2v5*)
++ lt_cv_deplibs_check_method=pass_all
++ ;;
++
++solaris*)
++ lt_cv_deplibs_check_method=pass_all
++ lt_cv_file_magic_test_file=/lib/libc.so
++ ;;
++
++sysv5uw[78]* | sysv4*uw2*)
++ lt_cv_deplibs_check_method=pass_all
++ ;;
++
++sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
++ case $host_vendor in
++ motorola)
++ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'
++ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
++ ;;
++ ncr)
++ lt_cv_deplibs_check_method=pass_all
++ ;;
++ sequent)
++ lt_cv_file_magic_cmd='/bin/file'
++ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'
++ ;;
++ sni)
++ lt_cv_file_magic_cmd='/bin/file'
++ lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib"
++ lt_cv_file_magic_test_file=/lib/libc.so
++ ;;
++ esac
++ ;;
++esac
++
++fi
++echo "$as_me:$LINENO: result: $lt_cv_deplibs_check_method" >&5
++echo "${ECHO_T}$lt_cv_deplibs_check_method" >&6
++file_magic_cmd=$lt_cv_file_magic_cmd
++deplibs_check_method=$lt_cv_deplibs_check_method
++
++
++
++
++
++
++
++# Check for command to grab the raw symbol name followed by C symbol from nm.
++echo "$as_me:$LINENO: checking command to parse $NM output" >&5
++echo $ECHO_N "checking command to parse $NM output... $ECHO_C" >&6
++if test "${lt_cv_sys_global_symbol_pipe+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++
++# These are sane defaults that work on at least a few old systems.
++# [They come from Ultrix. What could be older than Ultrix?!! ;)]
++
++# Character class describing NM global symbol codes.
++symcode='[BCDEGRST]'
++
++# Regexp to match symbols that can be accessed directly from C.
++sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
++
++# Transform the above into a raw symbol and a C symbol.
++symxfrm='\1 \2\3 \3'
++
++# Transform an extracted symbol line into a proper C declaration
++lt_cv_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern char \1;/p'"
++
++# Transform an extracted symbol line into symbol name and symbol address
++lt_cv_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode \([^ ]*\) \([^ ]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'"
++
++# Define system-specific variables.
++case $host_os in
++aix*)
++ symcode='[BCDT]'
++ ;;
++cygwin* | mingw* | pw32*)
++ symcode='[ABCDGISTW]'
++ ;;
++hpux*) # Its linker distinguishes data from code symbols
++ lt_cv_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern char \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
++ lt_cv_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'"
++ ;;
++irix*)
++ symcode='[BCDEGRST]'
++ ;;
++solaris* | sysv5*)
++ symcode='[BDT]'
++ ;;
++sysv4)
++ symcode='[DFNSTU]'
++ ;;
++esac
++
++# Handle CRLF in mingw tool chain
++opt_cr=
++case $host_os in
++mingw*)
++ opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp
++ ;;
++esac
++
++# If we're using GNU nm, then use its standard symbol codes.
++if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then
++ symcode='[ABCDGISTW]'
++fi
++
++# Try without a prefix undercore, then with it.
++for ac_symprfx in "" "_"; do
++
++ # Write the raw and C identifiers.
++lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*\($ac_symprfx\)$sympat$opt_cr$/$symxfrm/p'"
++
++ # Check to see that the pipe works correctly.
++ pipe_works=no
++ rm -f conftest*
++ cat > conftest.$ac_ext <<EOF
++#ifdef __cplusplus
++extern "C" {
++#endif
++char nm_test_var;
++void nm_test_func(){}
++#ifdef __cplusplus
++}
++#endif
++int main(){nm_test_var='a';nm_test_func();return(0);}
++EOF
++
++ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
++ (eval $ac_compile) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); }; then
++ # Now try to grab the symbols.
++ nlist=conftest.nm
++ if { (eval echo "$as_me:$LINENO: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist\"") >&5
++ (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); } && test -s "$nlist"; then
++ # Try sorting and uniquifying the output.
++ if sort "$nlist" | uniq > "$nlist"T; then
++ mv -f "$nlist"T "$nlist"
++ else
++ rm -f "$nlist"T
++ fi
++
++ # Make sure that we snagged all the symbols we need.
++ if egrep ' nm_test_var$' "$nlist" >/dev/null; then
++ if egrep ' nm_test_func$' "$nlist" >/dev/null; then
++ cat <<EOF > conftest.$ac_ext
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++EOF
++ # Now generate the symbol file.
++ eval "$lt_cv_global_symbol_to_cdecl"' < "$nlist" >> conftest.$ac_ext'
++
++ cat <<EOF >> conftest.$ac_ext
++#if defined (__STDC__) && __STDC__
++# define lt_ptr void *
++#else
++# define lt_ptr char *
++# define const
++#endif
++
++/* The mapping between symbol names and symbols. */
++const struct {
++ const char *name;
++ lt_ptr address;
++}
++lt_preloaded_symbols[] =
++{
++EOF
++ sed "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (lt_ptr) \&\2},/" < "$nlist" >> conftest.$ac_ext
++ cat <<\EOF >> conftest.$ac_ext
++ {0, (lt_ptr) 0}
++};
++
++#ifdef __cplusplus
++}
++#endif
++EOF
++ # Now try linking the two files.
++ mv conftest.$ac_objext conftstm.$ac_objext
++ save_LIBS="$LIBS"
++ save_CFLAGS="$CFLAGS"
++ LIBS="conftstm.$ac_objext"
++ CFLAGS="$CFLAGS$no_builtin_flag"
++ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
++ (eval $ac_link) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); } && test -s conftest; then
++ pipe_works=yes
++ fi
++ LIBS="$save_LIBS"
++ CFLAGS="$save_CFLAGS"
++ else
++ echo "cannot find nm_test_func in $nlist" >&5
++ fi
++ else
++ echo "cannot find nm_test_var in $nlist" >&5
++ fi
++ else
++ echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5
++ fi
++ else
++ echo "$progname: failed program was:" >&5
++ cat conftest.$ac_ext >&5
++ fi
++ rm -f conftest* conftst*
++
++ # Do not use the global_symbol_pipe unless it works.
++ if test "$pipe_works" = yes; then
++ break
++ else
++ lt_cv_sys_global_symbol_pipe=
++ fi
++done
++
++fi
++
++global_symbol_pipe="$lt_cv_sys_global_symbol_pipe"
++if test -z "$lt_cv_sys_global_symbol_pipe"; then
++ global_symbol_to_cdecl=
++ global_symbol_to_c_name_address=
++else
++ global_symbol_to_cdecl="$lt_cv_global_symbol_to_cdecl"
++ global_symbol_to_c_name_address="$lt_cv_global_symbol_to_c_name_address"
++fi
++if test -z "$global_symbol_pipe$global_symbol_to_cdec$global_symbol_to_c_name_address";
++then
++ echo "$as_me:$LINENO: result: failed" >&5
++echo "${ECHO_T}failed" >&6
++else
++ echo "$as_me:$LINENO: result: ok" >&5
++echo "${ECHO_T}ok" >&6
++fi
++
++ac_ext=c
++ac_cpp='$CPP $CPPFLAGS'
++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
++ac_compiler_gnu=$ac_cv_c_compiler_gnu
++echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
++echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6
++# On Suns, sometimes $CPP names a directory.
++if test -n "$CPP" && test -d "$CPP"; then
++ CPP=
++fi
++if test -z "$CPP"; then
++ if test "${ac_cv_prog_CPP+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ # Double quotes because CPP needs to be expanded
++ for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
++ do
++ ac_preproc_ok=false
++for ac_c_preproc_warn_flag in '' yes
++do
++ # Use a header file that comes with gcc, so configuring glibc
++ # with a fresh cross-compiler works.
++ # On the NeXT, cc -E runs the code through the compiler's parser,
++ # not just through cpp. "Syntax error" is here to catch this case.
++ cat >conftest.$ac_ext <<_ACEOF
++#line $LINENO "configure"
++#include "confdefs.h"
++@%:@include <assert.h>
++ Syntax error
++_ACEOF
++if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
++ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
++ ac_status=$?
++ grep -v '^ *+' conftest.er1 >conftest.err
++ rm -f conftest.er1
++ cat conftest.err >&5
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); } >/dev/null; then
++ if test -s conftest.err; then
++ ac_cpp_err=$ac_c_preproc_warn_flag
++ else
++ ac_cpp_err=
++ fi
++else
++ ac_cpp_err=yes
++fi
++if test -z "$ac_cpp_err"; then
++ :
++else
++ echo "$as_me: failed program was:" >&5
++ cat conftest.$ac_ext >&5
++ # Broken: fails on valid input.
++continue
++fi
++rm -f conftest.err conftest.$ac_ext
++
++ # OK, works on sane cases. Now check whether non-existent headers
++ # can be detected and how.
++ cat >conftest.$ac_ext <<_ACEOF
++#line $LINENO "configure"
++#include "confdefs.h"
++@%:@include <ac_nonexistent.h>
++_ACEOF
++if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
++ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
++ ac_status=$?
++ grep -v '^ *+' conftest.er1 >conftest.err
++ rm -f conftest.er1
++ cat conftest.err >&5
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); } >/dev/null; then
++ if test -s conftest.err; then
++ ac_cpp_err=$ac_c_preproc_warn_flag
++ else
++ ac_cpp_err=
++ fi
++else
++ ac_cpp_err=yes
++fi
++if test -z "$ac_cpp_err"; then
++ # Broken: success on invalid input.
++continue
++else
++ echo "$as_me: failed program was:" >&5
++ cat conftest.$ac_ext >&5
++ # Passes both tests.
++ac_preproc_ok=:
++break
++fi
++rm -f conftest.err conftest.$ac_ext
++
++done
++# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
++rm -f conftest.err conftest.$ac_ext
++if $ac_preproc_ok; then
++ break
++fi
++
++ done
++ ac_cv_prog_CPP=$CPP
++
++fi
++ CPP=$ac_cv_prog_CPP
++else
++ ac_cv_prog_CPP=$CPP
++fi
++echo "$as_me:$LINENO: result: $CPP" >&5
++echo "${ECHO_T}$CPP" >&6
++ac_preproc_ok=false
++for ac_c_preproc_warn_flag in '' yes
++do
++ # Use a header file that comes with gcc, so configuring glibc
++ # with a fresh cross-compiler works.
++ # On the NeXT, cc -E runs the code through the compiler's parser,
++ # not just through cpp. "Syntax error" is here to catch this case.
++ cat >conftest.$ac_ext <<_ACEOF
++#line $LINENO "configure"
++#include "confdefs.h"
++@%:@include <assert.h>
++ Syntax error
++_ACEOF
++if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
++ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
++ ac_status=$?
++ grep -v '^ *+' conftest.er1 >conftest.err
++ rm -f conftest.er1
++ cat conftest.err >&5
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); } >/dev/null; then
++ if test -s conftest.err; then
++ ac_cpp_err=$ac_c_preproc_warn_flag
++ else
++ ac_cpp_err=
++ fi
++else
++ ac_cpp_err=yes
++fi
++if test -z "$ac_cpp_err"; then
++ :
++else
++ echo "$as_me: failed program was:" >&5
++ cat conftest.$ac_ext >&5
++ # Broken: fails on valid input.
++continue
++fi
++rm -f conftest.err conftest.$ac_ext
++
++ # OK, works on sane cases. Now check whether non-existent headers
++ # can be detected and how.
++ cat >conftest.$ac_ext <<_ACEOF
++#line $LINENO "configure"
++#include "confdefs.h"
++@%:@include <ac_nonexistent.h>
++_ACEOF
++if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
++ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
++ ac_status=$?
++ grep -v '^ *+' conftest.er1 >conftest.err
++ rm -f conftest.er1
++ cat conftest.err >&5
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); } >/dev/null; then
++ if test -s conftest.err; then
++ ac_cpp_err=$ac_c_preproc_warn_flag
++ else
++ ac_cpp_err=
++ fi
++else
++ ac_cpp_err=yes
++fi
++if test -z "$ac_cpp_err"; then
++ # Broken: success on invalid input.
++continue
++else
++ echo "$as_me: failed program was:" >&5
++ cat conftest.$ac_ext >&5
++ # Passes both tests.
++ac_preproc_ok=:
++break
++fi
++rm -f conftest.err conftest.$ac_ext
++
++done
++# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
++rm -f conftest.err conftest.$ac_ext
++if $ac_preproc_ok; then
++ :
++else
++ { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check" >&5
++echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check" >&2;}
++ { (exit 1); exit 1; }; }
++fi
++
++ac_ext=c
++ac_cpp='$CPP $CPPFLAGS'
++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
++ac_compiler_gnu=$ac_cv_c_compiler_gnu
++
++
++echo "$as_me:$LINENO: checking for egrep" >&5
++echo $ECHO_N "checking for egrep... $ECHO_C" >&6
++if test "${ac_cv_prog_egrep+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ if echo a | (grep -E '(a|b)') >/dev/null 2>&1
++ then ac_cv_prog_egrep='grep -E'
++ else ac_cv_prog_egrep='egrep'
++ fi
++fi
++echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5
++echo "${ECHO_T}$ac_cv_prog_egrep" >&6
++ EGREP=$ac_cv_prog_egrep
++
++
++echo "$as_me:$LINENO: checking for ANSI C header files" >&5
++echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
++if test "${ac_cv_header_stdc+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ cat >conftest.$ac_ext <<_ACEOF
++#line $LINENO "configure"
++#include "confdefs.h"
++#include <stdlib.h>
++#include <stdarg.h>
++#include <string.h>
++#include <float.h>
++
++_ACEOF
++if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
++ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
++ ac_status=$?
++ grep -v '^ *+' conftest.er1 >conftest.err
++ rm -f conftest.er1
++ cat conftest.err >&5
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); } >/dev/null; then
++ if test -s conftest.err; then
++ ac_cpp_err=$ac_c_preproc_warn_flag
++ else
++ ac_cpp_err=
++ fi
++else
++ ac_cpp_err=yes
++fi
++if test -z "$ac_cpp_err"; then
++ ac_cv_header_stdc=yes
++else
++ echo "$as_me: failed program was:" >&5
++ cat conftest.$ac_ext >&5
++ ac_cv_header_stdc=no
++fi
++rm -f conftest.err conftest.$ac_ext
++
++if test $ac_cv_header_stdc = yes; then
++ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
++ cat >conftest.$ac_ext <<_ACEOF
++#line $LINENO "configure"
++#include "confdefs.h"
++#include <string.h>
++
++_ACEOF
++if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
++ $EGREP "memchr" >/dev/null 2>&1; then
++ :
++else
++ ac_cv_header_stdc=no
++fi
++rm -f conftest*
++
++fi
++
++if test $ac_cv_header_stdc = yes; then
++ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
++ cat >conftest.$ac_ext <<_ACEOF
++#line $LINENO "configure"
++#include "confdefs.h"
++#include <stdlib.h>
++
++_ACEOF
++if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
++ $EGREP "free" >/dev/null 2>&1; then
++ :
++else
++ ac_cv_header_stdc=no
++fi
++rm -f conftest*
++
++fi
++
++if test $ac_cv_header_stdc = yes; then
++ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
++ if test "$cross_compiling" = yes; then
++ :
++else
++ cat >conftest.$ac_ext <<_ACEOF
++#line $LINENO "configure"
++#include "confdefs.h"
++#include <ctype.h>
++#if ((' ' & 0x0FF) == 0x020)
++# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
++# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
++#else
++# define ISLOWER(c) (('a' <= (c) && (c) <= 'i') \
++ || ('j' <= (c) && (c) <= 'r') \
++ || ('s' <= (c) && (c) <= 'z'))
++# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
++#endif
++
++#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
++int
++main ()
++{
++ int i;
++ for (i = 0; i < 256; i++)
++ if (XOR (islower (i), ISLOWER (i))
++ || toupper (i) != TOUPPER (i))
++ exit(2);
++ exit (0);
++}
++_ACEOF
++rm -f conftest$ac_exeext
++if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
++ (eval $ac_link) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++ (eval $ac_try) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); }; }; then
++ :
++else
++ echo "$as_me: program exited with status $ac_status" >&5
++echo "$as_me: failed program was:" >&5
++cat conftest.$ac_ext >&5
++( exit $ac_status )
++ac_cv_header_stdc=no
++fi
++rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
++fi
++fi
++fi
++echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
++echo "${ECHO_T}$ac_cv_header_stdc" >&6
++if test $ac_cv_header_stdc = yes; then
++
++cat >>confdefs.h <<\_ACEOF
++@%:@define STDC_HEADERS 1
++_ACEOF
++
++fi
++
++# On IRIX 5.3, sys/types and inttypes.h are conflicting.
++
++
++
++
++
++
++
++
++
++for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
++ inttypes.h stdint.h unistd.h
++do
++as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
++echo "$as_me:$LINENO: checking for $ac_header" >&5
++echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
++if eval "test \"\${$as_ac_Header+set}\" = set"; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ cat >conftest.$ac_ext <<_ACEOF
++#line $LINENO "configure"
++#include "confdefs.h"
++$ac_includes_default
++
++@%:@include <$ac_header>
++_ACEOF
++rm -f conftest.$ac_objext
++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
++ (eval $ac_compile) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); } &&
++ { ac_try='test -s conftest.$ac_objext'
++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++ (eval $ac_try) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); }; }; then
++ eval "$as_ac_Header=yes"
++else
++ echo "$as_me: failed program was:" >&5
++cat conftest.$ac_ext >&5
++eval "$as_ac_Header=no"
++fi
++rm -f conftest.$ac_objext conftest.$ac_ext
++fi
++echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
++echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
++if test `eval echo '${'$as_ac_Header'}'` = yes; then
++ cat >>confdefs.h <<_ACEOF
++@%:@define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
++_ACEOF
++
++fi
++
++done
++
++
++
++for ac_header in dlfcn.h
++do
++as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
++if eval "test \"\${$as_ac_Header+set}\" = set"; then
++ echo "$as_me:$LINENO: checking for $ac_header" >&5
++echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
++if eval "test \"\${$as_ac_Header+set}\" = set"; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++fi
++echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
++echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
++else
++ # Is the header compilable?
++echo "$as_me:$LINENO: checking $ac_header usability" >&5
++echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
++cat >conftest.$ac_ext <<_ACEOF
++#line $LINENO "configure"
++#include "confdefs.h"
++$ac_includes_default
++@%:@include <$ac_header>
++_ACEOF
++rm -f conftest.$ac_objext
++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
++ (eval $ac_compile) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); } &&
++ { ac_try='test -s conftest.$ac_objext'
++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++ (eval $ac_try) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); }; }; then
++ ac_header_compiler=yes
++else
++ echo "$as_me: failed program was:" >&5
++cat conftest.$ac_ext >&5
++ac_header_compiler=no
++fi
++rm -f conftest.$ac_objext conftest.$ac_ext
++echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
++echo "${ECHO_T}$ac_header_compiler" >&6
++
++# Is the header present?
++echo "$as_me:$LINENO: checking $ac_header presence" >&5
++echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
++cat >conftest.$ac_ext <<_ACEOF
++#line $LINENO "configure"
++#include "confdefs.h"
++@%:@include <$ac_header>
++_ACEOF
++if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
++ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
++ ac_status=$?
++ grep -v '^ *+' conftest.er1 >conftest.err
++ rm -f conftest.er1
++ cat conftest.err >&5
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); } >/dev/null; then
++ if test -s conftest.err; then
++ ac_cpp_err=$ac_c_preproc_warn_flag
++ else
++ ac_cpp_err=
++ fi
++else
++ ac_cpp_err=yes
++fi
++if test -z "$ac_cpp_err"; then
++ ac_header_preproc=yes
++else
++ echo "$as_me: failed program was:" >&5
++ cat conftest.$ac_ext >&5
++ ac_header_preproc=no
++fi
++rm -f conftest.err conftest.$ac_ext
++echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
++echo "${ECHO_T}$ac_header_preproc" >&6
++
++# So? What about this header?
++case $ac_header_compiler:$ac_header_preproc in
++ yes:no )
++ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
++echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
++ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
++echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;};;
++ no:yes )
++ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
++echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
++ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
++echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
++ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
++echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;};;
++esac
++echo "$as_me:$LINENO: checking for $ac_header" >&5
++echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
++if eval "test \"\${$as_ac_Header+set}\" = set"; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ eval "$as_ac_Header=$ac_header_preproc"
++fi
++echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
++echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
++
++fi
++if test `eval echo '${'$as_ac_Header'}'` = yes; then
++ cat >>confdefs.h <<_ACEOF
++@%:@define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
++_ACEOF
++
++fi
++
++done
++
++
++
++
++
++# Only perform the check for file, if the check method requires it
++case $deplibs_check_method in
++file_magic*)
++ if test "$file_magic_cmd" = '$MAGIC_CMD'; then
++ echo "$as_me:$LINENO: checking for ${ac_tool_prefix}file" >&5
++echo $ECHO_N "checking for ${ac_tool_prefix}file... $ECHO_C" >&6
++if test "${lt_cv_path_MAGIC_CMD+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ case $MAGIC_CMD in
++ /*)
++ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
++ ;;
++ ?:/*)
++ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a dos path.
++ ;;
++ *)
++ ac_save_MAGIC_CMD="$MAGIC_CMD"
++ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
++ ac_dummy="/usr/bin:$PATH"
++ for ac_dir in $ac_dummy; do
++ test -z "$ac_dir" && ac_dir=.
++ if test -f $ac_dir/${ac_tool_prefix}file; then
++ lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file"
++ if test -n "$file_magic_test_file"; then
++ case $deplibs_check_method in
++ "file_magic "*)
++ file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`"
++ MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
++ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
++ egrep "$file_magic_regex" > /dev/null; then
++ :
++ else
++ cat <<EOF 1>&2
++
++*** Warning: the command libtool uses to detect shared libraries,
++*** $file_magic_cmd, produces output that libtool cannot recognize.
++*** The result is that libtool may fail to recognize shared libraries
++*** as such. This will affect the creation of libtool libraries that
++*** depend on shared libraries, but programs linked with such libtool
++*** libraries will work regardless of this problem. Nevertheless, you
++*** may want to report the problem to your system manager and/or to
++*** bug-libtool@gnu.org
++
++EOF
++ fi ;;
++ esac
++ fi
++ break
++ fi
++ done
++ IFS="$ac_save_ifs"
++ MAGIC_CMD="$ac_save_MAGIC_CMD"
++ ;;
++esac
++fi
++
++MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
++if test -n "$MAGIC_CMD"; then
++ echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5
++echo "${ECHO_T}$MAGIC_CMD" >&6
++else
++ echo "$as_me:$LINENO: result: no" >&5
++echo "${ECHO_T}no" >&6
++fi
++
++if test -z "$lt_cv_path_MAGIC_CMD"; then
++ if test -n "$ac_tool_prefix"; then
++ echo "$as_me:$LINENO: checking for file" >&5
++echo $ECHO_N "checking for file... $ECHO_C" >&6
++if test "${lt_cv_path_MAGIC_CMD+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ case $MAGIC_CMD in
++ /*)
++ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
++ ;;
++ ?:/*)
++ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a dos path.
++ ;;
++ *)
++ ac_save_MAGIC_CMD="$MAGIC_CMD"
++ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
++ ac_dummy="/usr/bin:$PATH"
++ for ac_dir in $ac_dummy; do
++ test -z "$ac_dir" && ac_dir=.
++ if test -f $ac_dir/file; then
++ lt_cv_path_MAGIC_CMD="$ac_dir/file"
++ if test -n "$file_magic_test_file"; then
++ case $deplibs_check_method in
++ "file_magic "*)
++ file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`"
++ MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
++ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
++ egrep "$file_magic_regex" > /dev/null; then
++ :
++ else
++ cat <<EOF 1>&2
++
++*** Warning: the command libtool uses to detect shared libraries,
++*** $file_magic_cmd, produces output that libtool cannot recognize.
++*** The result is that libtool may fail to recognize shared libraries
++*** as such. This will affect the creation of libtool libraries that
++*** depend on shared libraries, but programs linked with such libtool
++*** libraries will work regardless of this problem. Nevertheless, you
++*** may want to report the problem to your system manager and/or to
++*** bug-libtool@gnu.org
++
++EOF
++ fi ;;
++ esac
++ fi
++ break
++ fi
++ done
++ IFS="$ac_save_ifs"
++ MAGIC_CMD="$ac_save_MAGIC_CMD"
++ ;;
++esac
++fi
++
++MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
++if test -n "$MAGIC_CMD"; then
++ echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5
++echo "${ECHO_T}$MAGIC_CMD" >&6
++else
++ echo "$as_me:$LINENO: result: no" >&5
++echo "${ECHO_T}no" >&6
++fi
++
++ else
++ MAGIC_CMD=:
++ fi
++fi
++
++ fi
++ ;;
++esac
++
++if test -n "$ac_tool_prefix"; then
++ # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
++set dummy ${ac_tool_prefix}ranlib; ac_word=$2
++echo "$as_me:$LINENO: checking for $ac_word" >&5
++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
++if test "${ac_cv_prog_RANLIB+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ if test -n "$RANLIB"; then
++ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++ IFS=$as_save_IFS
++ test -z "$as_dir" && as_dir=.
++ for ac_exec_ext in '' $ac_executable_extensions; do
++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++ ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
++ break 2
++ fi
++done
++done
++
++fi
++fi
++RANLIB=$ac_cv_prog_RANLIB
++if test -n "$RANLIB"; then
++ echo "$as_me:$LINENO: result: $RANLIB" >&5
++echo "${ECHO_T}$RANLIB" >&6
++else
++ echo "$as_me:$LINENO: result: no" >&5
++echo "${ECHO_T}no" >&6
++fi
++
++fi
++if test -z "$ac_cv_prog_RANLIB"; then
++ ac_ct_RANLIB=$RANLIB
++ # Extract the first word of "ranlib", so it can be a program name with args.
++set dummy ranlib; ac_word=$2
++echo "$as_me:$LINENO: checking for $ac_word" >&5
++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
++if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ if test -n "$ac_ct_RANLIB"; then
++ ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++ IFS=$as_save_IFS
++ test -z "$as_dir" && as_dir=.
++ for ac_exec_ext in '' $ac_executable_extensions; do
++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++ ac_cv_prog_ac_ct_RANLIB="ranlib"
++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
++ break 2
++ fi
++done
++done
++
++ test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":"
++fi
++fi
++ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
++if test -n "$ac_ct_RANLIB"; then
++ echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5
++echo "${ECHO_T}$ac_ct_RANLIB" >&6
++else
++ echo "$as_me:$LINENO: result: no" >&5
++echo "${ECHO_T}no" >&6
++fi
++
++ RANLIB=$ac_ct_RANLIB
++else
++ RANLIB="$ac_cv_prog_RANLIB"
++fi
++
++if test -n "$ac_tool_prefix"; then
++ # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
++set dummy ${ac_tool_prefix}strip; ac_word=$2
++echo "$as_me:$LINENO: checking for $ac_word" >&5
++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
++if test "${ac_cv_prog_STRIP+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ if test -n "$STRIP"; then
++ ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++ IFS=$as_save_IFS
++ test -z "$as_dir" && as_dir=.
++ for ac_exec_ext in '' $ac_executable_extensions; do
++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++ ac_cv_prog_STRIP="${ac_tool_prefix}strip"
++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
++ break 2
++ fi
++done
++done
++
++fi
++fi
++STRIP=$ac_cv_prog_STRIP
++if test -n "$STRIP"; then
++ echo "$as_me:$LINENO: result: $STRIP" >&5
++echo "${ECHO_T}$STRIP" >&6
++else
++ echo "$as_me:$LINENO: result: no" >&5
++echo "${ECHO_T}no" >&6
++fi
++
++fi
++if test -z "$ac_cv_prog_STRIP"; then
++ ac_ct_STRIP=$STRIP
++ # Extract the first word of "strip", so it can be a program name with args.
++set dummy strip; ac_word=$2
++echo "$as_me:$LINENO: checking for $ac_word" >&5
++echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
++if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ if test -n "$ac_ct_STRIP"; then
++ ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
++else
++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++ IFS=$as_save_IFS
++ test -z "$as_dir" && as_dir=.
++ for ac_exec_ext in '' $ac_executable_extensions; do
++ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++ ac_cv_prog_ac_ct_STRIP="strip"
++ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
++ break 2
++ fi
++done
++done
++
++ test -z "$ac_cv_prog_ac_ct_STRIP" && ac_cv_prog_ac_ct_STRIP=":"
++fi
++fi
++ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
++if test -n "$ac_ct_STRIP"; then
++ echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5
++echo "${ECHO_T}$ac_ct_STRIP" >&6
++else
++ echo "$as_me:$LINENO: result: no" >&5
++echo "${ECHO_T}no" >&6
++fi
++
++ STRIP=$ac_ct_STRIP
++else
++ STRIP="$ac_cv_prog_STRIP"
++fi
++
++
++enable_dlopen=no
++enable_win32_dll=no
++
++# Check whether --enable-libtool-lock or --disable-libtool-lock was given.
++if test "${enable_libtool_lock+set}" = set; then
++ enableval="$enable_libtool_lock"
++
++fi;
++test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
++
++# Some flags need to be propagated to the compiler or linker for good
++# libtool support.
++case $host in
++*-*-irix6*)
++ # Find out which ABI we are using.
++ echo '#line __oline__ "configure"' > conftest.$ac_ext
++ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
++ (eval $ac_compile) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); }; then
++ case `/usr/bin/file conftest.$ac_objext` in
++ *32-bit*)
++ LD="${LD-ld} -32"
++ ;;
++ *N32*)
++ LD="${LD-ld} -n32"
++ ;;
++ *64-bit*)
++ LD="${LD-ld} -64"
++ ;;
++ esac
++ fi
++ rm -rf conftest*
++ ;;
++
++*-*-sco3.2v5*)
++ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
++ SAVE_CFLAGS="$CFLAGS"
++ CFLAGS="$CFLAGS -belf"
++ echo "$as_me:$LINENO: checking whether the C compiler needs -belf" >&5
++echo $ECHO_N "checking whether the C compiler needs -belf... $ECHO_C" >&6
++if test "${lt_cv_cc_needs_belf+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++
++
++ ac_ext=c
++ac_cpp='$CPP $CPPFLAGS'
++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
++ac_compiler_gnu=$ac_cv_c_compiler_gnu
++
++ cat >conftest.$ac_ext <<_ACEOF
++#line $LINENO "configure"
++#include "confdefs.h"
++
++int
++main ()
++{
++
++ ;
++ return 0;
++}
++_ACEOF
++rm -f conftest.$ac_objext conftest$ac_exeext
++if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
++ (eval $ac_link) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); } &&
++ { ac_try='test -s conftest$ac_exeext'
++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++ (eval $ac_try) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); }; }; then
++ lt_cv_cc_needs_belf=yes
++else
++ echo "$as_me: failed program was:" >&5
++cat conftest.$ac_ext >&5
++lt_cv_cc_needs_belf=no
++fi
++rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
++ ac_ext=c
++ac_cpp='$CPP $CPPFLAGS'
++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
++ac_compiler_gnu=$ac_cv_c_compiler_gnu
++
++fi
++echo "$as_me:$LINENO: result: $lt_cv_cc_needs_belf" >&5
++echo "${ECHO_T}$lt_cv_cc_needs_belf" >&6
++ if test x"$lt_cv_cc_needs_belf" != x"yes"; then
++ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
++ CFLAGS="$SAVE_CFLAGS"
++ fi
++ ;;
++
++
++esac
++
++# Sed substitution that helps us do robust quoting. It backslashifies
++# metacharacters that are still active within double-quoted strings.
++Xsed='sed -e s/^X//'
++sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g'
++
++# Same as above, but do not quote variable references.
++double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g'
++
++# Sed substitution to delay expansion of an escaped shell variable in a
++# double_quote_subst'ed string.
++delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
++
++# Constants:
++rm="rm -f"
++
++# Global variables:
++default_ofile=libtool
++can_build_shared=yes
++
++# All known linkers require a `.a' archive for static linking (except M$VC,
++# which needs '.lib').
++libext=a
++ltmain="$ac_aux_dir/ltmain.sh"
++ofile="$default_ofile"
++with_gnu_ld="$lt_cv_prog_gnu_ld"
++need_locks="$enable_libtool_lock"
++
++old_CC="$CC"
++old_CFLAGS="$CFLAGS"
++
++# Set sane defaults for various variables
++test -z "$AR" && AR=ar
++test -z "$AR_FLAGS" && AR_FLAGS=cru
++test -z "$AS" && AS=as
++test -z "$CC" && CC=cc
++test -z "$DLLTOOL" && DLLTOOL=dlltool
++test -z "$LD" && LD=ld
++test -z "$LN_S" && LN_S="ln -s"
++test -z "$MAGIC_CMD" && MAGIC_CMD=file
++test -z "$NM" && NM=nm
++test -z "$OBJDUMP" && OBJDUMP=objdump
++test -z "$RANLIB" && RANLIB=:
++test -z "$STRIP" && STRIP=:
++test -z "$ac_objext" && ac_objext=o
++
++if test x"$host" != x"$build"; then
++ ac_tool_prefix=${host_alias}-
++else
++ ac_tool_prefix=
++fi
++
++# Transform linux* to *-*-linux-gnu*, to support old configure scripts.
++case $host_os in
++linux-gnu*) ;;
++linux*) host=`echo $host | sed 's/^\(.*-.*-linux\)\(.*\)$/\1-gnu\2/'`
++esac
++
++case $host_os in
++aix3*)
++ # AIX sometimes has problems with the GCC collect2 program. For some
++ # reason, if we set the COLLECT_NAMES environment variable, the problems
++ # vanish in a puff of smoke.
++ if test "X${COLLECT_NAMES+set}" != Xset; then
++ COLLECT_NAMES=
++ export COLLECT_NAMES
++ fi
++ ;;
++esac
++
++# Determine commands to create old-style static archives.
++old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs'
++old_postinstall_cmds='chmod 644 $oldlib'
++old_postuninstall_cmds=
++
++if test -n "$RANLIB"; then
++ case $host_os in
++ openbsd*)
++ old_postinstall_cmds="\$RANLIB -t \$oldlib~$old_postinstall_cmds"
++ ;;
++ *)
++ old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds"
++ ;;
++ esac
++ old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
++fi
++
++# Allow CC to be a program name with arguments.
++set dummy $CC
++compiler="$2"
++
++echo "$as_me:$LINENO: checking for objdir" >&5
++echo $ECHO_N "checking for objdir... $ECHO_C" >&6
++rm -f .libs 2>/dev/null
++mkdir .libs 2>/dev/null
++if test -d .libs; then
++ objdir=.libs
++else
++ # MS-DOS does not allow filenames that begin with a dot.
++ objdir=_libs
++fi
++rmdir .libs 2>/dev/null
++echo "$as_me:$LINENO: result: $objdir" >&5
++echo "${ECHO_T}$objdir" >&6
++
++
++
++# Check whether --with-pic or --without-pic was given.
++if test "${with_pic+set}" = set; then
++ withval="$with_pic"
++ pic_mode="$withval"
++else
++ pic_mode=default
++fi;
++test -z "$pic_mode" && pic_mode=default
++
++# We assume here that the value for lt_cv_prog_cc_pic will not be cached
++# in isolation, and that seeing it set (from the cache) indicates that
++# the associated values are set (in the cache) correctly too.
++echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5
++echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6
++if test "${lt_cv_prog_cc_pic+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ lt_cv_prog_cc_pic=
++ lt_cv_prog_cc_shlib=
++ lt_cv_prog_cc_wl=
++ lt_cv_prog_cc_static=
++ lt_cv_prog_cc_no_builtin=
++ lt_cv_prog_cc_can_build_shared=$can_build_shared
++
++ if test "$GCC" = yes; then
++ lt_cv_prog_cc_wl='-Wl,'
++ lt_cv_prog_cc_static='-static'
++
++ case $host_os in
++ aix*)
++ # Below there is a dirty hack to force normal static linking with -ldl
++ # The problem is because libdl dynamically linked with both libc and
++ # libC (AIX C++ library), which obviously doesn't included in libraries
++ # list by gcc. This cause undefined symbols with -static flags.
++ # This hack allows C programs to be linked with "-static -ldl", but
++ # not sure about C++ programs.
++ lt_cv_prog_cc_static="$lt_cv_prog_cc_static ${lt_cv_prog_cc_wl}-lC"
++ ;;
++ amigaos*)
++ # FIXME: we need at least 68020 code to build shared libraries, but
++ # adding the `-m68020' flag to GCC prevents building anything better,
++ # like `-m68040'.
++ lt_cv_prog_cc_pic='-m68020 -resident32 -malways-restore-a4'
++ ;;
++ beos* | irix5* | irix6* | osf3* | osf4* | osf5*)
++ # PIC is the default for these OSes.
++ ;;
++ darwin* | rhapsody*)
++ # PIC is the default on this platform
++ # Common symbols not allowed in MH_DYLIB files
++ lt_cv_prog_cc_pic='-fno-common'
++ ;;
++ cygwin* | mingw* | pw32* | os2*)
++ # This hack is so that the source file can tell whether it is being
++ # built for inclusion in a dll (and should export symbols for example).
++ lt_cv_prog_cc_pic='-DDLL_EXPORT'
++ ;;
++ sysv4*MP*)
++ if test -d /usr/nec; then
++ lt_cv_prog_cc_pic=-Kconform_pic
++ fi
++ ;;
++ *)
++ lt_cv_prog_cc_pic='-fPIC'
++ ;;
++ esac
++ else
++ # PORTME Check for PIC flags for the system compiler.
++ case $host_os in
++ aix3* | aix4* | aix5*)
++ lt_cv_prog_cc_wl='-Wl,'
++ # All AIX code is PIC.
++ if test "$host_cpu" = ia64; then
++ # AIX 5 now supports IA64 processor
++ lt_cv_prog_cc_static='-Bstatic'
++ else
++ lt_cv_prog_cc_static='-bnso -bI:/lib/syscalls.exp'
++ fi
++ ;;
++
++ hpux9* | hpux10* | hpux11*)
++ # Is there a better lt_cv_prog_cc_static that works with the bundled CC?
++ lt_cv_prog_cc_wl='-Wl,'
++ lt_cv_prog_cc_static="${lt_cv_prog_cc_wl}-a ${lt_cv_prog_cc_wl}archive"
++ lt_cv_prog_cc_pic='+Z'
++ ;;
++
++ irix5* | irix6*)
++ lt_cv_prog_cc_wl='-Wl,'
++ lt_cv_prog_cc_static='-non_shared'
++ # PIC (with -KPIC) is the default.
++ ;;
++
++ cygwin* | mingw* | pw32* | os2*)
++ # This hack is so that the source file can tell whether it is being
++ # built for inclusion in a dll (and should export symbols for example).
++ lt_cv_prog_cc_pic='-DDLL_EXPORT'
++ ;;
++
++ newsos6)
++ lt_cv_prog_cc_pic='-KPIC'
++ lt_cv_prog_cc_static='-Bstatic'
++ ;;
++
++ osf3* | osf4* | osf5*)
++ # All OSF/1 code is PIC.
++ lt_cv_prog_cc_wl='-Wl,'
++ lt_cv_prog_cc_static='-non_shared'
++ ;;
++
++ sco3.2v5*)
++ lt_cv_prog_cc_pic='-Kpic'
++ lt_cv_prog_cc_static='-dn'
++ lt_cv_prog_cc_shlib='-belf'
++ ;;
++
++ solaris*)
++ lt_cv_prog_cc_pic='-KPIC'
++ lt_cv_prog_cc_static='-Bstatic'
++ lt_cv_prog_cc_wl='-Wl,'
++ ;;
++
++ sunos4*)
++ lt_cv_prog_cc_pic='-PIC'
++ lt_cv_prog_cc_static='-Bstatic'
++ lt_cv_prog_cc_wl='-Qoption ld '
++ ;;
++
++ sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
++ lt_cv_prog_cc_pic='-KPIC'
++ lt_cv_prog_cc_static='-Bstatic'
++ if test "x$host_vendor" = xsni; then
++ lt_cv_prog_cc_wl='-LD'
++ else
++ lt_cv_prog_cc_wl='-Wl,'
++ fi
++ ;;
++
++ uts4*)
++ lt_cv_prog_cc_pic='-pic'
++ lt_cv_prog_cc_static='-Bstatic'
++ ;;
++
++ sysv4*MP*)
++ if test -d /usr/nec ;then
++ lt_cv_prog_cc_pic='-Kconform_pic'
++ lt_cv_prog_cc_static='-Bstatic'
++ fi
++ ;;
++
++ *)
++ lt_cv_prog_cc_can_build_shared=no
++ ;;
++ esac
++ fi
++
++fi
++
++if test -z "$lt_cv_prog_cc_pic"; then
++ echo "$as_me:$LINENO: result: none" >&5
++echo "${ECHO_T}none" >&6
++else
++ echo "$as_me:$LINENO: result: $lt_cv_prog_cc_pic" >&5
++echo "${ECHO_T}$lt_cv_prog_cc_pic" >&6
++
++ # Check to make sure the pic_flag actually works.
++ echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_cv_prog_cc_pic works" >&5
++echo $ECHO_N "checking if $compiler PIC flag $lt_cv_prog_cc_pic works... $ECHO_C" >&6
++ if test "${lt_cv_prog_cc_pic_works+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ save_CFLAGS="$CFLAGS"
++ CFLAGS="$CFLAGS $lt_cv_prog_cc_pic -DPIC"
++ cat >conftest.$ac_ext <<_ACEOF
++#line $LINENO "configure"
++#include "confdefs.h"
++
++int
++main ()
++{
++
++ ;
++ return 0;
++}
++_ACEOF
++rm -f conftest.$ac_objext
++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
++ (eval $ac_compile) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); } &&
++ { ac_try='test -s conftest.$ac_objext'
++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++ (eval $ac_try) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); }; }; then
++ case $host_os in
++ hpux9* | hpux10* | hpux11*)
++ # On HP-UX, both CC and GCC only warn that PIC is supported... then
++ # they create non-PIC objects. So, if there were any warnings, we
++ # assume that PIC is not supported.
++ if test -s conftest.err; then
++ lt_cv_prog_cc_pic_works=no
++ else
++ lt_cv_prog_cc_pic_works=yes
++ fi
++ ;;
++ *)
++ lt_cv_prog_cc_pic_works=yes
++ ;;
++ esac
++
++else
++ echo "$as_me: failed program was:" >&5
++cat conftest.$ac_ext >&5
++ lt_cv_prog_cc_pic_works=no
++
++fi
++rm -f conftest.$ac_objext conftest.$ac_ext
++ CFLAGS="$save_CFLAGS"
++
++fi
++
++
++ if test "X$lt_cv_prog_cc_pic_works" = Xno; then
++ lt_cv_prog_cc_pic=
++ lt_cv_prog_cc_can_build_shared=no
++ else
++ lt_cv_prog_cc_pic=" $lt_cv_prog_cc_pic"
++ fi
++
++ echo "$as_me:$LINENO: result: $lt_cv_prog_cc_pic_works" >&5
++echo "${ECHO_T}$lt_cv_prog_cc_pic_works" >&6
++fi
++
++# Check for any special shared library compilation flags.
++if test -n "$lt_cv_prog_cc_shlib"; then
++ { echo "$as_me:$LINENO: WARNING: \`$CC' requires \`$lt_cv_prog_cc_shlib' to build shared libraries" >&5
++echo "$as_me: WARNING: \`$CC' requires \`$lt_cv_prog_cc_shlib' to build shared libraries" >&2;}
++ if echo "$old_CC $old_CFLAGS " | egrep -e "[ ]$lt_cv_prog_cc_shlib[ ]" >/dev/null; then :
++ else
++ { echo "$as_me:$LINENO: WARNING: add \`$lt_cv_prog_cc_shlib' to the CC or CFLAGS env variable and reconfigure" >&5
++echo "$as_me: WARNING: add \`$lt_cv_prog_cc_shlib' to the CC or CFLAGS env variable and reconfigure" >&2;}
++ lt_cv_prog_cc_can_build_shared=no
++ fi
++fi
++
++echo "$as_me:$LINENO: checking if $compiler static flag $lt_cv_prog_cc_static works" >&5
++echo $ECHO_N "checking if $compiler static flag $lt_cv_prog_cc_static works... $ECHO_C" >&6
++if test "${lt_cv_prog_cc_static_works+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ lt_cv_prog_cc_static_works=no
++ save_LDFLAGS="$LDFLAGS"
++ LDFLAGS="$LDFLAGS $lt_cv_prog_cc_static"
++ cat >conftest.$ac_ext <<_ACEOF
++#line $LINENO "configure"
++#include "confdefs.h"
++
++int
++main ()
++{
++
++ ;
++ return 0;
++}
++_ACEOF
++rm -f conftest.$ac_objext conftest$ac_exeext
++if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
++ (eval $ac_link) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); } &&
++ { ac_try='test -s conftest$ac_exeext'
++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++ (eval $ac_try) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); }; }; then
++ lt_cv_prog_cc_static_works=yes
++else
++ echo "$as_me: failed program was:" >&5
++cat conftest.$ac_ext >&5
++fi
++rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
++ LDFLAGS="$save_LDFLAGS"
++
++fi
++
++
++# Belt *and* braces to stop my trousers falling down:
++test "X$lt_cv_prog_cc_static_works" = Xno && lt_cv_prog_cc_static=
++echo "$as_me:$LINENO: result: $lt_cv_prog_cc_static_works" >&5
++echo "${ECHO_T}$lt_cv_prog_cc_static_works" >&6
++
++pic_flag="$lt_cv_prog_cc_pic"
++special_shlib_compile_flags="$lt_cv_prog_cc_shlib"
++wl="$lt_cv_prog_cc_wl"
++link_static_flag="$lt_cv_prog_cc_static"
++no_builtin_flag="$lt_cv_prog_cc_no_builtin"
++can_build_shared="$lt_cv_prog_cc_can_build_shared"
++
++
++# Check to see if options -o and -c are simultaneously supported by compiler
++echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5
++echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6
++if test "${lt_cv_compiler_c_o+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++
++$rm -r conftest 2>/dev/null
++mkdir conftest
++cd conftest
++echo "int some_variable = 0;" > conftest.$ac_ext
++mkdir out
++# According to Tom Tromey, Ian Lance Taylor reported there are C compilers
++# that will create temporary files in the current directory regardless of
++# the output directory. Thus, making CWD read-only will cause this test
++# to fail, enabling locking or at least warning the user not to do parallel
++# builds.
++chmod -w .
++save_CFLAGS="$CFLAGS"
++CFLAGS="$CFLAGS -o out/conftest2.$ac_objext"
++compiler_c_o=no
++if { (eval echo configure:__oline__: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.$ac_objext; then
++ # The compiler can only warn and ignore the option if not recognized
++ # So say no if there are warnings
++ if test -s out/conftest.err; then
++ lt_cv_compiler_c_o=no
++ else
++ lt_cv_compiler_c_o=yes
++ fi
++else
++ # Append any errors to the config.log.
++ cat out/conftest.err 1>&5
++ lt_cv_compiler_c_o=no
++fi
++CFLAGS="$save_CFLAGS"
++chmod u+w .
++$rm conftest* out/*
++rmdir out
++cd ..
++rmdir conftest
++$rm -r conftest 2>/dev/null
++
++fi
++
++compiler_c_o=$lt_cv_compiler_c_o
++echo "$as_me:$LINENO: result: $compiler_c_o" >&5
++echo "${ECHO_T}$compiler_c_o" >&6
++
++if test x"$compiler_c_o" = x"yes"; then
++ # Check to see if we can write to a .lo
++ echo "$as_me:$LINENO: checking if $compiler supports -c -o file.lo" >&5
++echo $ECHO_N "checking if $compiler supports -c -o file.lo... $ECHO_C" >&6
++ if test "${lt_cv_compiler_o_lo+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++
++ lt_cv_compiler_o_lo=no
++ save_CFLAGS="$CFLAGS"
++ CFLAGS="$CFLAGS -c -o conftest.lo"
++ save_objext="$ac_objext"
++ ac_objext=lo
++ cat >conftest.$ac_ext <<_ACEOF
++#line $LINENO "configure"
++#include "confdefs.h"
++
++int
++main ()
++{
++int some_variable = 0;
++ ;
++ return 0;
++}
++_ACEOF
++rm -f conftest.$ac_objext
++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
++ (eval $ac_compile) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); } &&
++ { ac_try='test -s conftest.$ac_objext'
++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++ (eval $ac_try) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); }; }; then
++ # The compiler can only warn and ignore the option if not recognized
++ # So say no if there are warnings
++ if test -s conftest.err; then
++ lt_cv_compiler_o_lo=no
++ else
++ lt_cv_compiler_o_lo=yes
++ fi
++
++else
++ echo "$as_me: failed program was:" >&5
++cat conftest.$ac_ext >&5
++fi
++rm -f conftest.$ac_objext conftest.$ac_ext
++ ac_objext="$save_objext"
++ CFLAGS="$save_CFLAGS"
++
++fi
++
++ compiler_o_lo=$lt_cv_compiler_o_lo
++ echo "$as_me:$LINENO: result: $compiler_o_lo" >&5
++echo "${ECHO_T}$compiler_o_lo" >&6
++else
++ compiler_o_lo=no
++fi
++
++# Check to see if we can do hard links to lock some files if needed
++hard_links="nottested"
++if test "$compiler_c_o" = no && test "$need_locks" != no; then
++ # do not overwrite the value of need_locks provided by the user
++ echo "$as_me:$LINENO: checking if we can lock with hard links" >&5
++echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6
++ hard_links=yes
++ $rm conftest*
++ ln conftest.a conftest.b 2>/dev/null && hard_links=no
++ touch conftest.a
++ ln conftest.a conftest.b 2>&5 || hard_links=no
++ ln conftest.a conftest.b 2>/dev/null && hard_links=no
++ echo "$as_me:$LINENO: result: $hard_links" >&5
++echo "${ECHO_T}$hard_links" >&6
++ if test "$hard_links" = no; then
++ { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
++echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
++ need_locks=warn
++ fi
++else
++ need_locks=no
++fi
++
++if test "$GCC" = yes; then
++ # Check to see if options -fno-rtti -fno-exceptions are supported by compiler
++ echo "$as_me:$LINENO: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
++echo $ECHO_N "checking if $compiler supports -fno-rtti -fno-exceptions... $ECHO_C" >&6
++ echo "int some_variable = 0;" > conftest.$ac_ext
++ save_CFLAGS="$CFLAGS"
++ CFLAGS="$CFLAGS -fno-rtti -fno-exceptions -c conftest.$ac_ext"
++ compiler_rtti_exceptions=no
++ cat >conftest.$ac_ext <<_ACEOF
++#line $LINENO "configure"
++#include "confdefs.h"
++
++int
++main ()
++{
++int some_variable = 0;
++ ;
++ return 0;
++}
++_ACEOF
++rm -f conftest.$ac_objext
++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
++ (eval $ac_compile) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); } &&
++ { ac_try='test -s conftest.$ac_objext'
++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++ (eval $ac_try) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); }; }; then
++ # The compiler can only warn and ignore the option if not recognized
++ # So say no if there are warnings
++ if test -s conftest.err; then
++ compiler_rtti_exceptions=no
++ else
++ compiler_rtti_exceptions=yes
++ fi
++
++else
++ echo "$as_me: failed program was:" >&5
++cat conftest.$ac_ext >&5
++fi
++rm -f conftest.$ac_objext conftest.$ac_ext
++ CFLAGS="$save_CFLAGS"
++ echo "$as_me:$LINENO: result: $compiler_rtti_exceptions" >&5
++echo "${ECHO_T}$compiler_rtti_exceptions" >&6
++
++ if test "$compiler_rtti_exceptions" = "yes"; then
++ no_builtin_flag=' -fno-builtin -fno-rtti -fno-exceptions'
++ else
++ no_builtin_flag=' -fno-builtin'
++ fi
++fi
++
++# See if the linker supports building shared libraries.
++echo "$as_me:$LINENO: checking whether the linker ($LD) supports shared libraries" >&5
++echo $ECHO_N "checking whether the linker ($LD) supports shared libraries... $ECHO_C" >&6
++
++allow_undefined_flag=
++no_undefined_flag=
++need_lib_prefix=unknown
++need_version=unknown
++# when you set need_version to no, make sure it does not cause -set_version
++# flags to be left without arguments
++archive_cmds=
++archive_expsym_cmds=
++old_archive_from_new_cmds=
++old_archive_from_expsyms_cmds=
++export_dynamic_flag_spec=
++whole_archive_flag_spec=
++thread_safe_flag_spec=
++hardcode_into_libs=no
++hardcode_libdir_flag_spec=
++hardcode_libdir_separator=
++hardcode_direct=no
++hardcode_minus_L=no
++hardcode_shlibpath_var=unsupported
++runpath_var=
++link_all_deplibs=unknown
++always_export_symbols=no
++export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | sed '\''s/.* //'\'' | sort | uniq > $export_symbols'
++# include_expsyms should be a list of space-separated symbols to be *always*
++# included in the symbol list
++include_expsyms=
++# exclude_expsyms can be an egrep regular expression of symbols to exclude
++# it will be wrapped by ` (' and `)$', so one must not match beginning or
++# end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
++# as well as any symbol that contains `d'.
++exclude_expsyms="_GLOBAL_OFFSET_TABLE_"
++# Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
++# platforms (ab)use it in PIC code, but their linkers get confused if
++# the symbol is explicitly referenced. Since portable code cannot
++# rely on this symbol name, it's probably fine to never include it in
++# preloaded symbol tables.
++extract_expsyms_cmds=
++
++case $host_os in
++cygwin* | mingw* | pw32*)
++ # FIXME: the MSVC++ port hasn't been tested in a loooong time
++ # When not using gcc, we currently assume that we are using
++ # Microsoft Visual C++.
++ if test "$GCC" != yes; then
++ with_gnu_ld=no
++ fi
++ ;;
++openbsd*)
++ with_gnu_ld=no
++ ;;
++esac
++
++ld_shlibs=yes
++if test "$with_gnu_ld" = yes; then
++ # If archive_cmds runs LD, not CC, wlarc should be empty
++ wlarc='${wl}'
++
++ # See if GNU ld supports shared libraries.
++ case $host_os in
++ aix3* | aix4* | aix5*)
++ # On AIX, the GNU linker is very broken
++ # Note:Check GNU linker on AIX 5-IA64 when/if it becomes available.
++ ld_shlibs=no
++ cat <<EOF 1>&2
++
++*** Warning: the GNU linker, at least up to release 2.9.1, is reported
++*** to be unable to reliably create shared libraries on AIX.
++*** Therefore, libtool is disabling shared libraries support. If you
++*** really care for shared libraries, you may want to modify your PATH
++*** so that a non-GNU linker is found, and then restart.
++
++EOF
++ ;;
++
++ amigaos*)
++ archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
++ hardcode_libdir_flag_spec='-L$libdir'
++ hardcode_minus_L=yes
++
++ # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports
++ # that the semantics of dynamic libraries on AmigaOS, at least up
++ # to version 4, is to share data among multiple programs linked
++ # with the same dynamic library. Since this doesn't match the
++ # behavior of shared libraries on other platforms, we can use
++ # them.
++ ld_shlibs=no
++ ;;
++
++ beos*)
++ if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
++ allow_undefined_flag=unsupported
++ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
++ # support --undefined. This deserves some investigation. FIXME
++ archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
++ else
++ ld_shlibs=no
++ fi
++ ;;
++
++ cygwin* | mingw* | pw32*)
++ # hardcode_libdir_flag_spec is actually meaningless, as there is
++ # no search path for DLLs.
++ hardcode_libdir_flag_spec='-L$libdir'
++ allow_undefined_flag=unsupported
++ always_export_symbols=yes
++
++ extract_expsyms_cmds='test -f $output_objdir/impgen.c || \
++ sed -e "/^# \/\* impgen\.c starts here \*\//,/^# \/\* impgen.c ends here \*\// { s/^# //;s/^# *$//; p; }" -e d < $''0 > $output_objdir/impgen.c~
++ test -f $output_objdir/impgen.exe || (cd $output_objdir && \
++ if test "x$HOST_CC" != "x" ; then $HOST_CC -o impgen impgen.c ; \
++ else $CC -o impgen impgen.c ; fi)~
++ $output_objdir/impgen $dir/$soroot > $output_objdir/$soname-def'
++
++ old_archive_from_expsyms_cmds='$DLLTOOL --as=$AS --dllname $soname --def $output_objdir/$soname-def --output-lib $output_objdir/$newlib'
++
++ # cygwin and mingw dlls have different entry points and sets of symbols
++ # to exclude.
++ # FIXME: what about values for MSVC?
++ dll_entry=__cygwin_dll_entry@12
++ dll_exclude_symbols=DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12~
++ case $host_os in
++ mingw*)
++ # mingw values
++ dll_entry=_DllMainCRTStartup@12
++ dll_exclude_symbols=DllMain@12,DllMainCRTStartup@12,DllEntryPoint@12~
++ ;;
++ esac
++
++ # mingw and cygwin differ, and it's simplest to just exclude the union
++ # of the two symbol sets.
++ dll_exclude_symbols=DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12,DllMainCRTStartup@12,DllEntryPoint@12
++
++ # recent cygwin and mingw systems supply a stub DllMain which the user
++ # can override, but on older systems we have to supply one (in ltdll.c)
++ if test "x$lt_cv_need_dllmain" = "xyes"; then
++ ltdll_obj='$output_objdir/$soname-ltdll.'"$ac_objext "
++ ltdll_cmds='test -f $output_objdir/$soname-ltdll.c || sed -e "/^# \/\* ltdll\.c starts here \*\//,/^# \/\* ltdll.c ends here \*\// { s/^# //; p; }" -e d < $''0 > $output_objdir/$soname-ltdll.c~
++ test -f $output_objdir/$soname-ltdll.$ac_objext || (cd $output_objdir && $CC -c $soname-ltdll.c)~'
++ else
++ ltdll_obj=
++ ltdll_cmds=
++ fi
++
++ # Extract the symbol export list from an `--export-all' def file,
++ # then regenerate the def file from the symbol export list, so that
++ # the compiled dll only exports the symbol export list.
++ # Be careful not to strip the DATA tag left be newer dlltools.
++ export_symbols_cmds="$ltdll_cmds"'
++ $DLLTOOL --export-all --exclude-symbols '$dll_exclude_symbols' --output-def $output_objdir/$soname-def '$ltdll_obj'$libobjs $convenience~
++ sed -e "1,/EXPORTS/d" -e "s/ @ [0-9]*//" -e "s/ *;.*$//" < $output_objdir/$soname-def > $export_symbols'
++
++ # If the export-symbols file already is a .def file (1st line
++ # is EXPORTS), use it as is.
++ # If DATA tags from a recent dlltool are present, honour them!
++ archive_expsym_cmds='if test "x`head -1 $export_symbols`" = xEXPORTS; then
++ cp $export_symbols $output_objdir/$soname-def;
++ else
++ echo EXPORTS > $output_objdir/$soname-def;
++ _lt_hint=1;
++ cat $export_symbols | while read symbol; do
++ set dummy \$symbol;
++ case \$# in
++ 2) echo " \$2 @ \$_lt_hint ; " >> $output_objdir/$soname-def;;
++ *) echo " \$2 @ \$_lt_hint \$3 ; " >> $output_objdir/$soname-def;;
++ esac;
++ _lt_hint=`expr 1 + \$_lt_hint`;
++ done;
++ fi~
++ '"$ltdll_cmds"'
++ $CC -Wl,--base-file,$output_objdir/$soname-base '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags~
++ $DLLTOOL --as=$AS --dllname $soname --exclude-symbols '$dll_exclude_symbols' --def $output_objdir/$soname-def --base-file $output_objdir/$soname-base --output-exp $output_objdir/$soname-exp~
++ $CC -Wl,--base-file,$output_objdir/$soname-base $output_objdir/$soname-exp '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags~
++ $DLLTOOL --as=$AS --dllname $soname --exclude-symbols '$dll_exclude_symbols' --def $output_objdir/$soname-def --base-file $output_objdir/$soname-base --output-exp $output_objdir/$soname-exp --output-lib $output_objdir/$libname.dll.a~
++ $CC $output_objdir/$soname-exp '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags'
++ ;;
++
++ netbsd*)
++ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
++ archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
++ wlarc=
++ else
++ archive_cmds='$CC -shared -nodefaultlibs $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
++ archive_expsym_cmds='$CC -shared -nodefaultlibs $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
++ fi
++ ;;
++
++ solaris* | sysv5*)
++ if $LD -v 2>&1 | egrep 'BFD 2\.8' > /dev/null; then
++ ld_shlibs=no
++ cat <<EOF 1>&2
++
++*** Warning: The releases 2.8.* of the GNU linker cannot reliably
++*** create shared libraries on Solaris systems. Therefore, libtool
++*** is disabling shared libraries support. We urge you to upgrade GNU
++*** binutils to release 2.9.1 or newer. Another option is to modify
++*** your PATH or compiler configuration so that the native linker is
++*** used, and then restart.
++
++EOF
++ elif $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
++ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
++ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
++ else
++ ld_shlibs=no
++ fi
++ ;;
++
++ sunos4*)
++ archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
++ wlarc=
++ hardcode_direct=yes
++ hardcode_shlibpath_var=no
++ ;;
++
++ *)
++ if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
++ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
++ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
++ else
++ ld_shlibs=no
++ fi
++ ;;
++ esac
++
++ if test "$ld_shlibs" = yes; then
++ runpath_var=LD_RUN_PATH
++ hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir'
++ export_dynamic_flag_spec='${wl}--export-dynamic'
++ case $host_os in
++ cygwin* | mingw* | pw32*)
++ # dlltool doesn't understand --whole-archive et. al.
++ whole_archive_flag_spec=
++ ;;
++ *)
++ # ancient GNU ld didn't support --whole-archive et. al.
++ if $LD --help 2>&1 | egrep 'no-whole-archive' > /dev/null; then
++ whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
++ else
++ whole_archive_flag_spec=
++ fi
++ ;;
++ esac
++ fi
++else
++ # PORTME fill in a description of your system's linker (not GNU ld)
++ case $host_os in
++ aix3*)
++ allow_undefined_flag=unsupported
++ always_export_symbols=yes
++ archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
++ # Note: this linker hardcodes the directories in LIBPATH if there
++ # are no directories specified by -L.
++ hardcode_minus_L=yes
++ if test "$GCC" = yes && test -z "$link_static_flag"; then
++ # Neither direct hardcoding nor static linking is supported with a
++ # broken collect2.
++ hardcode_direct=unsupported
++ fi
++ ;;
++
++ aix4* | aix5*)
++ if test "$host_cpu" = ia64; then
++ # On IA64, the linker does run time linking by default, so we don't
++ # have to do anything special.
++ aix_use_runtimelinking=no
++ exp_sym_flag='-Bexport'
++ no_entry_flag=""
++ else
++ aix_use_runtimelinking=no
++
++ # Test if we are trying to use run time linking or normal
++ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
++ # need to do runtime linking.
++ case $host_os in aix4.[23]|aix4.[23].*|aix5*)
++ for ld_flag in $LDFLAGS; do
++ if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
++ aix_use_runtimelinking=yes
++ break
++ fi
++ done
++ esac
++
++ exp_sym_flag='-bexport'
++ no_entry_flag='-bnoentry'
++ fi
++
++ # When large executables or shared objects are built, AIX ld can
++ # have problems creating the table of contents. If linking a library
++ # or program results in "error TOC overflow" add -mminimal-toc to
++ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
++ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
++
++ hardcode_direct=yes
++ archive_cmds=''
++ hardcode_libdir_separator=':'
++ if test "$GCC" = yes; then
++ case $host_os in aix4.[012]|aix4.[012].*)
++ collect2name=`${CC} -print-prog-name=collect2`
++ if test -f "$collect2name" && \
++ strings "$collect2name" | grep resolve_lib_name >/dev/null
++ then
++ # We have reworked collect2
++ hardcode_direct=yes
++ else
++ # We have old collect2
++ hardcode_direct=unsupported
++ # It fails to find uninstalled libraries when the uninstalled
++ # path is not listed in the libpath. Setting hardcode_minus_L
++ # to unsupported forces relinking
++ hardcode_minus_L=yes
++ hardcode_libdir_flag_spec='-L$libdir'
++ hardcode_libdir_separator=
++ fi
++ esac
++
++ shared_flag='-shared'
++ else
++ # not using gcc
++ if test "$host_cpu" = ia64; then
++ shared_flag='${wl}-G'
++ else
++ if test "$aix_use_runtimelinking" = yes; then
++ shared_flag='${wl}-G'
++ else
++ shared_flag='${wl}-bM:SRE'
++ fi
++ fi
++ fi
++
++ # It seems that -bexpall can do strange things, so it is better to
++ # generate a list of symbols to export.
++ always_export_symbols=yes
++ if test "$aix_use_runtimelinking" = yes; then
++ # Warning - without using the other runtime loading flags (-brtl),
++ # -berok will link without error, but may produce a broken library.
++ allow_undefined_flag='-berok'
++ hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:/usr/lib:/lib'
++ archive_expsym_cmds="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag"
++ else
++ if test "$host_cpu" = ia64; then
++ hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
++ allow_undefined_flag="-z nodefs"
++ archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname ${wl}-h$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols"
++ else
++ hardcode_libdir_flag_spec='${wl}-bnolibpath ${wl}-blibpath:$libdir:/usr/lib:/lib'
++ # Warning - without using the other run time loading flags,
++ # -berok will link without error, but may produce a broken library.
++ allow_undefined_flag='${wl}-berok'
++ # This is a bit strange, but is similar to how AIX traditionally builds
++ # it's shared libraries.
++ archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols"' ~$AR -crlo $objdir/$libname$release.a $objdir/$soname'
++ fi
++ fi
++ ;;
++
++ amigaos*)
++ archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
++ hardcode_libdir_flag_spec='-L$libdir'
++ hardcode_minus_L=yes
++ # see comment about different semantics on the GNU ld section
++ ld_shlibs=no
++ ;;
++
++ cygwin* | mingw* | pw32*)
++ # When not using gcc, we currently assume that we are using
++ # Microsoft Visual C++.
++ # hardcode_libdir_flag_spec is actually meaningless, as there is
++ # no search path for DLLs.
++ hardcode_libdir_flag_spec=' '
++ allow_undefined_flag=unsupported
++ # Tell ltmain to make .lib files, not .a files.
++ libext=lib
++ # FIXME: Setting linknames here is a bad hack.
++ archive_cmds='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | sed -e '\''s/ -lc$//'\''` -link -dll~linknames='
++ # The linker will automatically build a .lib file if we build a DLL.
++ old_archive_from_new_cmds='true'
++ # FIXME: Should let the user specify the lib program.
++ old_archive_cmds='lib /OUT:$oldlib$oldobjs$old_deplibs'
++ fix_srcfile_path='`cygpath -w "$srcfile"`'
++ ;;
++
++ darwin* | rhapsody*)
++ case "$host_os" in
++ rhapsody* | darwin1.[012])
++ allow_undefined_flag='-undefined suppress'
++ ;;
++ *) # Darwin 1.3 on
++ allow_undefined_flag='-flat_namespace -undefined suppress'
++ ;;
++ esac
++ # FIXME: Relying on posixy $() will cause problems for
++ # cross-compilation, but unfortunately the echo tests do not
++ # yet detect zsh echo's removal of \ escapes.
++ archive_cmds='$nonopt $(test "x$module" = xyes && echo -bundle || echo -dynamiclib) $allow_undefined_flag -o $lib $libobjs $deplibs$linker_flags -install_name $rpath/$soname $verstring'
++ # We need to add '_' to the symbols in $export_symbols first
++ #archive_expsym_cmds="$archive_cmds"' && strip -s $export_symbols'
++ hardcode_direct=yes
++ hardcode_shlibpath_var=no
++ whole_archive_flag_spec='-all_load $convenience'
++ ;;
++
++ freebsd1*)
++ ld_shlibs=no
++ ;;
++
++ # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
++ # support. Future versions do this automatically, but an explicit c++rt0.o
++ # does not break anything, and helps significantly (at the cost of a little
++ # extra space).
++ freebsd2.2*)
++ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
++ hardcode_libdir_flag_spec='-R$libdir'
++ hardcode_direct=yes
++ hardcode_shlibpath_var=no
++ ;;
++
++ # Unfortunately, older versions of FreeBSD 2 do not have this feature.
++ freebsd2*)
++ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
++ hardcode_direct=yes
++ hardcode_minus_L=yes
++ hardcode_shlibpath_var=no
++ ;;
++
++ # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
++ freebsd*)
++ archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
++ hardcode_libdir_flag_spec='-R$libdir'
++ hardcode_direct=yes
++ hardcode_shlibpath_var=no
++ ;;
++
++ hpux9* | hpux10* | hpux11*)
++ case $host_os in
++ hpux9*) archive_cmds='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' ;;
++ *) archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' ;;
++ esac
++ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
++ hardcode_libdir_separator=:
++ hardcode_direct=yes
++ hardcode_minus_L=yes # Not in the search PATH, but as the default
++ # location of the library.
++ export_dynamic_flag_spec='${wl}-E'
++ ;;
++
++ irix5* | irix6*)
++ if test "$GCC" = yes; then
++ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
++ else
++ archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
++ fi
++ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
++ hardcode_libdir_separator=:
++ link_all_deplibs=yes
++ ;;
++
++ netbsd*)
++ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
++ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
++ else
++ archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF
++ fi
++ hardcode_libdir_flag_spec='-R$libdir'
++ hardcode_direct=yes
++ hardcode_shlibpath_var=no
++ ;;
++
++ newsos6)
++ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
++ hardcode_direct=yes
++ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
++ hardcode_libdir_separator=:
++ hardcode_shlibpath_var=no
++ ;;
++
++ openbsd*)
++ hardcode_direct=yes
++ hardcode_shlibpath_var=no
++ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
++ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $linker_flags'
++ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
++ export_dynamic_flag_spec='${wl}-E'
++ else
++ case "$host_os" in
++ openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
++ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
++ hardcode_libdir_flag_spec='-R$libdir'
++ ;;
++ *)
++ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $linker_flags'
++ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
++ ;;
++ esac
++ fi
++ ;;
++
++ os2*)
++ hardcode_libdir_flag_spec='-L$libdir'
++ hardcode_minus_L=yes
++ allow_undefined_flag=unsupported
++ archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
++ old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
++ ;;
++
++ osf3*)
++ if test "$GCC" = yes; then
++ allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
++ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
++ else
++ allow_undefined_flag=' -expect_unresolved \*'
++ archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
++ fi
++ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
++ hardcode_libdir_separator=:
++ ;;
++
++ osf4* | osf5*) # as osf3* with the addition of -msym flag
++ if test "$GCC" = yes; then
++ allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
++ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
++ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
++ else
++ allow_undefined_flag=' -expect_unresolved \*'
++ archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
++ archive_expsym_cmds='for i in `cat $export_symbols`; do printf "-exported_symbol " >> $lib.exp; echo "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~
++ $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib~$rm $lib.exp'
++
++ #Both c and cxx compiler support -rpath directly
++ hardcode_libdir_flag_spec='-rpath $libdir'
++ fi
++ hardcode_libdir_separator=:
++ ;;
++
++ sco3.2v5*)
++ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
++ hardcode_shlibpath_var=no
++ runpath_var=LD_RUN_PATH
++ hardcode_runpath_var=yes
++ export_dynamic_flag_spec='${wl}-Bexport'
++ ;;
++
++ solaris*)
++ # gcc --version < 3.0 without binutils cannot create self contained
++ # shared libraries reliably, requiring libgcc.a to resolve some of
++ # the object symbols generated in some cases. Libraries that use
++ # assert need libgcc.a to resolve __eprintf, for example. Linking
++ # a copy of libgcc.a into every shared library to guarantee resolving
++ # such symbols causes other problems: According to Tim Van Holder
++ # <tim.van.holder@pandora.be>, C++ libraries end up with a separate
++ # (to the application) exception stack for one thing.
++ no_undefined_flag=' -z defs'
++ if test "$GCC" = yes; then
++ case `$CC --version 2>/dev/null` in
++ [12].*)
++ cat <<EOF 1>&2
++
++*** Warning: Releases of GCC earlier than version 3.0 cannot reliably
++*** create self contained shared libraries on Solaris systems, without
++*** introducing a dependency on libgcc.a. Therefore, libtool is disabling
++*** -no-undefined support, which will at least allow you to build shared
++*** libraries. However, you may find that when you link such libraries
++*** into an application without using GCC, you have to manually add
++*** \`gcc --print-libgcc-file-name\` to the link command. We urge you to
++*** upgrade to a newer version of GCC. Another option is to rebuild your
++*** current GCC to use the GNU linker from GNU binutils 2.9.1 or newer.
++
++EOF
++ no_undefined_flag=
++ ;;
++ esac
++ fi
++ # $CC -shared without GNU ld will not create a library from C++
++ # object files and a static libstdc++, better avoid it by now
++ archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
++ archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
++ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
++ hardcode_libdir_flag_spec='-R$libdir'
++ hardcode_shlibpath_var=no
++ case $host_os in
++ solaris2.[0-5] | solaris2.[0-5].*) ;;
++ *) # Supported since Solaris 2.6 (maybe 2.5.1?)
++ whole_archive_flag_spec='-z allextract$convenience -z defaultextract' ;;
++ esac
++ link_all_deplibs=yes
++ ;;
++
++ sunos4*)
++ if test "x$host_vendor" = xsequent; then
++ # Use $CC to link under sequent, because it throws in some extra .o
++ # files that make .init and .fini sections work.
++ archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
++ else
++ archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
++ fi
++ hardcode_libdir_flag_spec='-L$libdir'
++ hardcode_direct=yes
++ hardcode_minus_L=yes
++ hardcode_shlibpath_var=no
++ ;;
++
++ sysv4)
++ if test "x$host_vendor" = xsno; then
++ archive_cmds='$LD -G -Bsymbolic -h $soname -o $lib $libobjs $deplibs $linker_flags'
++ hardcode_direct=yes # is this really true???
++ else
++ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
++ hardcode_direct=no #Motorola manual says yes, but my tests say they lie
++ fi
++ runpath_var='LD_RUN_PATH'
++ hardcode_shlibpath_var=no
++ ;;
++
++ sysv4.3*)
++ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
++ hardcode_shlibpath_var=no
++ export_dynamic_flag_spec='-Bexport'
++ ;;
++
++ sysv5*)
++ no_undefined_flag=' -z text'
++ # $CC -shared without GNU ld will not create a library from C++
++ # object files and a static libstdc++, better avoid it by now
++ archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
++ archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
++ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
++ hardcode_libdir_flag_spec=
++ hardcode_shlibpath_var=no
++ runpath_var='LD_RUN_PATH'
++ ;;
++
++ uts4*)
++ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
++ hardcode_libdir_flag_spec='-L$libdir'
++ hardcode_shlibpath_var=no
++ ;;
++
++ dgux*)
++ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
++ hardcode_libdir_flag_spec='-L$libdir'
++ hardcode_shlibpath_var=no
++ ;;
++
++ sysv4*MP*)
++ if test -d /usr/nec; then
++ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
++ hardcode_shlibpath_var=no
++ runpath_var=LD_RUN_PATH
++ hardcode_runpath_var=yes
++ ld_shlibs=yes
++ fi
++ ;;
++
++ sysv4.2uw2*)
++ archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags'
++ hardcode_direct=yes
++ hardcode_minus_L=no
++ hardcode_shlibpath_var=no
++ hardcode_runpath_var=yes
++ runpath_var=LD_RUN_PATH
++ ;;
++
++ sysv5uw7* | unixware7*)
++ no_undefined_flag='${wl}-z ${wl}text'
++ if test "$GCC" = yes; then
++ archive_cmds='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
++ else
++ archive_cmds='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
++ fi
++ runpath_var='LD_RUN_PATH'
++ hardcode_shlibpath_var=no
++ ;;
++
++ *)
++ ld_shlibs=no
++ ;;
++ esac
++fi
++echo "$as_me:$LINENO: result: $ld_shlibs" >&5
++echo "${ECHO_T}$ld_shlibs" >&6
++test "$ld_shlibs" = no && can_build_shared=no
++
++# Check hardcoding attributes.
++echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5
++echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6
++hardcode_action=
++if test -n "$hardcode_libdir_flag_spec" || \
++ test -n "$runpath_var"; then
++
++ # We can hardcode non-existant directories.
++ if test "$hardcode_direct" != no &&
++ # If the only mechanism to avoid hardcoding is shlibpath_var, we
++ # have to relink, otherwise we might link with an installed library
++ # when we should be linking with a yet-to-be-installed one
++ ## test "$hardcode_shlibpath_var" != no &&
++ test "$hardcode_minus_L" != no; then
++ # Linking always hardcodes the temporary library directory.
++ hardcode_action=relink
++ else
++ # We can link without hardcoding, and we can hardcode nonexisting dirs.
++ hardcode_action=immediate
++ fi
++else
++ # We cannot hardcode anything, or else we can only hardcode existing
++ # directories.
++ hardcode_action=unsupported
++fi
++echo "$as_me:$LINENO: result: $hardcode_action" >&5
++echo "${ECHO_T}$hardcode_action" >&6
++
++striplib=
++old_striplib=
++echo "$as_me:$LINENO: checking whether stripping libraries is possible" >&5
++echo $ECHO_N "checking whether stripping libraries is possible... $ECHO_C" >&6
++if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then
++ test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
++ test -z "$striplib" && striplib="$STRIP --strip-unneeded"
++ echo "$as_me:$LINENO: result: yes" >&5
++echo "${ECHO_T}yes" >&6
++else
++ echo "$as_me:$LINENO: result: no" >&5
++echo "${ECHO_T}no" >&6
++fi
++
++reload_cmds='$LD$reload_flag -o $output$reload_objs'
++test -z "$deplibs_check_method" && deplibs_check_method=unknown
++
++# PORTME Fill in your ld.so characteristics
++echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5
++echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6
++library_names_spec=
++libname_spec='lib$name'
++soname_spec=
++postinstall_cmds=
++postuninstall_cmds=
++finish_cmds=
++finish_eval=
++shlibpath_var=
++shlibpath_overrides_runpath=unknown
++version_type=none
++dynamic_linker="$host_os ld.so"
++sys_lib_dlsearch_path_spec="/lib /usr/lib"
++sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
++
++case $host_os in
++aix3*)
++ version_type=linux
++ library_names_spec='${libname}${release}.so$versuffix $libname.a'
++ shlibpath_var=LIBPATH
++
++ # AIX has no versioning support, so we append a major version to the name.
++ soname_spec='${libname}${release}.so$major'
++ ;;
++
++aix4* | aix5*)
++ version_type=linux
++ if test "$host_cpu" = ia64; then
++ # AIX 5 supports IA64
++ library_names_spec='${libname}${release}.so$major ${libname}${release}.so$versuffix $libname.so'
++ shlibpath_var=LD_LIBRARY_PATH
++ else
++ # With GCC up to 2.95.x, collect2 would create an import file
++ # for dependence libraries. The import file would start with
++ # the line `#! .'. This would cause the generated library to
++ # depend on `.', always an invalid library. This was fixed in
++ # development snapshots of GCC prior to 3.0.
++ case $host_os in
++ aix4 | aix4.[01] | aix4.[01].*)
++ if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
++ echo ' yes '
++ echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then
++ :
++ else
++ can_build_shared=no
++ fi
++ ;;
++ esac
++ # AIX (on Power*) has no versioning support, so currently we can
++ # not hardcode correct soname into executable. Probably we can
++ # add versioning support to collect2, so additional links can
++ # be useful in future.
++ if test "$aix_use_runtimelinking" = yes; then
++ # If using run time linking (on AIX 4.2 or later) use lib<name>.so
++ # instead of lib<name>.a to let people know that these are not
++ # typical AIX shared libraries.
++ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
++ else
++ # We preserve .a as extension for shared libraries through AIX4.2
++ # and later when we are not doing run time linking.
++ library_names_spec='${libname}${release}.a $libname.a'
++ soname_spec='${libname}${release}.so$major'
++ fi
++ shlibpath_var=LIBPATH
++ fi
++ ;;
++
++amigaos*)
++ library_names_spec='$libname.ixlibrary $libname.a'
++ # Create ${libname}_ixlibrary.a entries in /sys/libs.
++ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "(cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a)"; (cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a) || exit 1; done'
++ ;;
++
++beos*)
++ library_names_spec='${libname}.so'
++ dynamic_linker="$host_os ld.so"
++ shlibpath_var=LIBRARY_PATH
++ ;;
++
++bsdi4*)
++ version_type=linux
++ need_version=no
++ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
++ soname_spec='${libname}${release}.so$major'
++ finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
++ shlibpath_var=LD_LIBRARY_PATH
++ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
++ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
++ export_dynamic_flag_spec=-rdynamic
++ # the default ld.so.conf also contains /usr/contrib/lib and
++ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
++ # libtool to hard-code these into programs
++ ;;
++
++cygwin* | mingw* | pw32*)
++ version_type=windows
++ need_version=no
++ need_lib_prefix=no
++ case $GCC,$host_os in
++ yes,cygwin*)
++ library_names_spec='$libname.dll.a'
++ soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll'
++ postinstall_cmds='dlpath=`bash 2>&1 -c '\''. $dir/${file}i;echo \$dlname'\''`~
++ dldir=$destdir/`dirname \$dlpath`~
++ test -d \$dldir || mkdir -p \$dldir~
++ $install_prog .libs/$dlname \$dldir/$dlname'
++ postuninstall_cmds='dldll=`bash 2>&1 -c '\''. $file; echo \$dlname'\''`~
++ dlpath=$dir/\$dldll~
++ $rm \$dlpath'
++ ;;
++ yes,mingw*)
++ library_names_spec='${libname}`echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll'
++ sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | sed -e "s/^libraries://" -e "s/;/ /g"`
++ ;;
++ yes,pw32*)
++ library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | sed -e 's/./-/g'`${versuffix}.dll'
++ ;;
++ *)
++ library_names_spec='${libname}`echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll $libname.lib'
++ ;;
++ esac
++ dynamic_linker='Win32 ld.exe'
++ # FIXME: first we should search . and the directory the executable is in
++ shlibpath_var=PATH
++ ;;
++
++darwin* | rhapsody*)
++ dynamic_linker="$host_os dyld"
++ version_type=darwin
++ need_lib_prefix=no
++ need_version=no
++ # FIXME: Relying on posixy $() will cause problems for
++ # cross-compilation, but unfortunately the echo tests do not
++ # yet detect zsh echo's removal of \ escapes.
++ library_names_spec='${libname}${release}${versuffix}.$(test .$module = .yes && echo so || echo dylib) ${libname}${release}${major}.$(test .$module = .yes && echo so || echo dylib) ${libname}.$(test .$module = .yes && echo so || echo dylib)'
++ soname_spec='${libname}${release}${major}.$(test .$module = .yes && echo so || echo dylib)'
++ shlibpath_overrides_runpath=yes
++ shlibpath_var=DYLD_LIBRARY_PATH
++ ;;
++
++freebsd1*)
++ dynamic_linker=no
++ ;;
++
++freebsd*)
++ objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout`
++ version_type=freebsd-$objformat
++ case $version_type in
++ freebsd-elf*)
++ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so'
++ need_version=no
++ need_lib_prefix=no
++ ;;
++ freebsd-*)
++ library_names_spec='${libname}${release}.so$versuffix $libname.so$versuffix'
++ need_version=yes
++ ;;
++ esac
++ shlibpath_var=LD_LIBRARY_PATH
++ case $host_os in
++ freebsd2*)
++ shlibpath_overrides_runpath=yes
++ ;;
++ *)
++ shlibpath_overrides_runpath=no
++ hardcode_into_libs=yes
++ ;;
++ esac
++ ;;
++
++gnu*)
++ version_type=linux
++ need_lib_prefix=no
++ need_version=no
++ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so${major} ${libname}.so'
++ soname_spec='${libname}${release}.so$major'
++ shlibpath_var=LD_LIBRARY_PATH
++ hardcode_into_libs=yes
++ ;;
++
++hpux9* | hpux10* | hpux11*)
++ # Give a soname corresponding to the major version so that dld.sl refuses to
++ # link against other versions.
++ dynamic_linker="$host_os dld.sl"
++ version_type=sunos
++ need_lib_prefix=no
++ need_version=no
++ shlibpath_var=SHLIB_PATH
++ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
++ library_names_spec='${libname}${release}.sl$versuffix ${libname}${release}.sl$major $libname.sl'
++ soname_spec='${libname}${release}.sl$major'
++ # HP-UX runs *really* slowly unless shared libraries are mode 555.
++ postinstall_cmds='chmod 555 $lib'
++ ;;
++
++irix5* | irix6*)
++ version_type=irix
++ need_lib_prefix=no
++ need_version=no
++ soname_spec='${libname}${release}.so$major'
++ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so $libname.so'
++ case $host_os in
++ irix5*)
++ libsuff= shlibsuff=
++ ;;
++ *)
++ case $LD in # libtool.m4 will add one of these switches to LD
++ *-32|*"-32 ") libsuff= shlibsuff= libmagic=32-bit;;
++ *-n32|*"-n32 ") libsuff=32 shlibsuff=N32 libmagic=N32;;
++ *-64|*"-64 ") libsuff=64 shlibsuff=64 libmagic=64-bit;;
++ *) libsuff= shlibsuff= libmagic=never-match;;
++ esac
++ ;;
++ esac
++ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
++ shlibpath_overrides_runpath=no
++ sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
++ sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
++ ;;
++
++# No shared lib support for Linux oldld, aout, or coff.
++linux-gnuoldld* | linux-gnuaout* | linux-gnucoff*)
++ dynamic_linker=no
++ ;;
++
++# This must be Linux ELF.
++linux-gnu*)
++ version_type=linux
++ need_lib_prefix=no
++ need_version=no
++ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
++ soname_spec='${libname}${release}.so$major'
++ finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
++ shlibpath_var=LD_LIBRARY_PATH
++ shlibpath_overrides_runpath=no
++ # This implies no fast_install, which is unacceptable.
++ # Some rework will be needed to allow for fast_install
++ # before this can be enabled.
++ hardcode_into_libs=yes
++
++ # We used to test for /lib/ld.so.1 and disable shared libraries on
++ # powerpc, because MkLinux only supported shared libraries with the
++ # GNU dynamic linker. Since this was broken with cross compilers,
++ # most powerpc-linux boxes support dynamic linking these days and
++ # people can always --disable-shared, the test was removed, and we
++ # assume the GNU/Linux dynamic linker is in use.
++ dynamic_linker='GNU/Linux ld.so'
++ ;;
++
++netbsd*)
++ version_type=sunos
++ need_lib_prefix=no
++ need_version=no
++ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
++ library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix'
++ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
++ dynamic_linker='NetBSD (a.out) ld.so'
++ else
++ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so ${libname}.so'
++ soname_spec='${libname}${release}.so$major'
++ dynamic_linker='NetBSD ld.elf_so'
++ fi
++ shlibpath_var=LD_LIBRARY_PATH
++ shlibpath_overrides_runpath=yes
++ hardcode_into_libs=yes
++ ;;
++
++newsos6)
++ version_type=linux
++ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
++ shlibpath_var=LD_LIBRARY_PATH
++ shlibpath_overrides_runpath=yes
++ ;;
++
++openbsd*)
++ version_type=sunos
++ need_lib_prefix=no
++ need_version=no
++ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
++ case "$host_os" in
++ openbsd2.[89] | openbsd2.[89].*)
++ shlibpath_overrides_runpath=no
++ ;;
++ *)
++ shlibpath_overrides_runpath=yes
++ ;;
++ esac
++ else
++ shlibpath_overrides_runpath=yes
++ fi
++ library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix'
++ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
++ shlibpath_var=LD_LIBRARY_PATH
++ ;;
++
++os2*)
++ libname_spec='$name'
++ need_lib_prefix=no
++ library_names_spec='$libname.dll $libname.a'
++ dynamic_linker='OS/2 ld.exe'
++ shlibpath_var=LIBPATH
++ ;;
++
++osf3* | osf4* | osf5*)
++ version_type=osf
++ need_version=no
++ soname_spec='${libname}${release}.so'
++ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so'
++ shlibpath_var=LD_LIBRARY_PATH
++ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
++ sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
++ ;;
++
++sco3.2v5*)
++ version_type=osf
++ soname_spec='${libname}${release}.so$major'
++ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
++ shlibpath_var=LD_LIBRARY_PATH
++ ;;
++
++solaris*)
++ version_type=linux
++ need_lib_prefix=no
++ need_version=no
++ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
++ soname_spec='${libname}${release}.so$major'
++ shlibpath_var=LD_LIBRARY_PATH
++ shlibpath_overrides_runpath=yes
++ hardcode_into_libs=yes
++ # ldd complains unless libraries are executable
++ postinstall_cmds='chmod +x $lib'
++ ;;
++
++sunos4*)
++ version_type=sunos
++ library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix'
++ finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
++ shlibpath_var=LD_LIBRARY_PATH
++ shlibpath_overrides_runpath=yes
++ if test "$with_gnu_ld" = yes; then
++ need_lib_prefix=no
++ fi
++ need_version=yes
++ ;;
++
++sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
++ version_type=linux
++ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
++ soname_spec='${libname}${release}.so$major'
++ shlibpath_var=LD_LIBRARY_PATH
++ case $host_vendor in
++ sni)
++ shlibpath_overrides_runpath=no
++ ;;
++ motorola)
++ need_lib_prefix=no
++ need_version=no
++ shlibpath_overrides_runpath=no
++ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
++ ;;
++ esac
++ ;;
++
++uts4*)
++ version_type=linux
++ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
++ soname_spec='${libname}${release}.so$major'
++ shlibpath_var=LD_LIBRARY_PATH
++ ;;
++
++dgux*)
++ version_type=linux
++ need_lib_prefix=no
++ need_version=no
++ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
++ soname_spec='${libname}${release}.so$major'
++ shlibpath_var=LD_LIBRARY_PATH
++ ;;
++
++sysv4*MP*)
++ if test -d /usr/nec ;then
++ version_type=linux
++ library_names_spec='$libname.so.$versuffix $libname.so.$major $libname.so'
++ soname_spec='$libname.so.$major'
++ shlibpath_var=LD_LIBRARY_PATH
++ fi
++ ;;
++
++*)
++ dynamic_linker=no
++ ;;
++esac
++echo "$as_me:$LINENO: result: $dynamic_linker" >&5
++echo "${ECHO_T}$dynamic_linker" >&6
++test "$dynamic_linker" = no && can_build_shared=no
++
++# Report the final consequences.
++echo "$as_me:$LINENO: checking if libtool supports shared libraries" >&5
++echo $ECHO_N "checking if libtool supports shared libraries... $ECHO_C" >&6
++echo "$as_me:$LINENO: result: $can_build_shared" >&5
++echo "${ECHO_T}$can_build_shared" >&6
++
++echo "$as_me:$LINENO: checking whether to build shared libraries" >&5
++echo $ECHO_N "checking whether to build shared libraries... $ECHO_C" >&6
++test "$can_build_shared" = "no" && enable_shared=no
++
++# On AIX, shared libraries and static libraries use the same namespace, and
++# are all built from PIC.
++case "$host_os" in
++aix3*)
++ test "$enable_shared" = yes && enable_static=no
++ if test -n "$RANLIB"; then
++ archive_cmds="$archive_cmds~\$RANLIB \$lib"
++ postinstall_cmds='$RANLIB $lib'
++ fi
++ ;;
++
++aix4*)
++ if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
++ test "$enable_shared" = yes && enable_static=no
++ fi
++ ;;
++esac
++echo "$as_me:$LINENO: result: $enable_shared" >&5
++echo "${ECHO_T}$enable_shared" >&6
++
++echo "$as_me:$LINENO: checking whether to build static libraries" >&5
++echo $ECHO_N "checking whether to build static libraries... $ECHO_C" >&6
++# Make sure either enable_shared or enable_static is yes.
++test "$enable_shared" = yes || enable_static=yes
++echo "$as_me:$LINENO: result: $enable_static" >&5
++echo "${ECHO_T}$enable_static" >&6
++
++if test "$hardcode_action" = relink; then
++ # Fast installation is not supported
++ enable_fast_install=no
++elif test "$shlibpath_overrides_runpath" = yes ||
++ test "$enable_shared" = no; then
++ # Fast installation is not necessary
++ enable_fast_install=needless
++fi
++
++variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
++if test "$GCC" = yes; then
++ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
++fi
++
++if test "x$enable_dlopen" != xyes; then
++ enable_dlopen=unknown
++ enable_dlopen_self=unknown
++ enable_dlopen_self_static=unknown
++else
++ lt_cv_dlopen=no
++ lt_cv_dlopen_libs=
++
++ case $host_os in
++ beos*)
++ lt_cv_dlopen="load_add_on"
++ lt_cv_dlopen_libs=
++ lt_cv_dlopen_self=yes
++ ;;
++
++ cygwin* | mingw* | pw32*)
++ lt_cv_dlopen="LoadLibrary"
++ lt_cv_dlopen_libs=
++ ;;
++
++ *)
++ echo "$as_me:$LINENO: checking for shl_load" >&5
++echo $ECHO_N "checking for shl_load... $ECHO_C" >&6
++if test "${ac_cv_func_shl_load+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ cat >conftest.$ac_ext <<_ACEOF
++#line $LINENO "configure"
++#include "confdefs.h"
++/* System header to define __stub macros and hopefully few prototypes,
++ which can conflict with char shl_load (); below. */
++#include <assert.h>
++/* Override any gcc2 internal prototype to avoid an error. */
++#ifdef __cplusplus
++extern "C"
++#endif
++/* We use char because int might match the return type of a gcc2
++ builtin and then its argument prototype would still apply. */
++char shl_load ();
++char (*f) ();
++
++int
++main ()
++{
++/* The GNU C library defines this for functions which it implements
++ to always fail with ENOSYS. Some functions are actually named
++ something starting with __ and the normal name is an alias. */
++#if defined (__stub_shl_load) || defined (__stub___shl_load)
++choke me
++#else
++f = shl_load;
++#endif
++
++ ;
++ return 0;
++}
++_ACEOF
++rm -f conftest.$ac_objext conftest$ac_exeext
++if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
++ (eval $ac_link) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); } &&
++ { ac_try='test -s conftest$ac_exeext'
++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++ (eval $ac_try) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); }; }; then
++ ac_cv_func_shl_load=yes
++else
++ echo "$as_me: failed program was:" >&5
++cat conftest.$ac_ext >&5
++ac_cv_func_shl_load=no
++fi
++rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
++fi
++echo "$as_me:$LINENO: result: $ac_cv_func_shl_load" >&5
++echo "${ECHO_T}$ac_cv_func_shl_load" >&6
++if test $ac_cv_func_shl_load = yes; then
++ lt_cv_dlopen="shl_load"
++else
++ echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5
++echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6
++if test "${ac_cv_lib_dld_shl_load+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ ac_check_lib_save_LIBS=$LIBS
++LIBS="-ldld $LIBS"
++cat >conftest.$ac_ext <<_ACEOF
++#line $LINENO "configure"
++#include "confdefs.h"
++
++/* Override any gcc2 internal prototype to avoid an error. */
++#ifdef __cplusplus
++extern "C"
++#endif
++/* We use char because int might match the return type of a gcc2
++ builtin and then its argument prototype would still apply. */
++char shl_load ();
++int
++main ()
++{
++shl_load ();
++ ;
++ return 0;
++}
++_ACEOF
++rm -f conftest.$ac_objext conftest$ac_exeext
++if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
++ (eval $ac_link) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); } &&
++ { ac_try='test -s conftest$ac_exeext'
++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++ (eval $ac_try) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); }; }; then
++ ac_cv_lib_dld_shl_load=yes
++else
++ echo "$as_me: failed program was:" >&5
++cat conftest.$ac_ext >&5
++ac_cv_lib_dld_shl_load=no
++fi
++rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
++LIBS=$ac_check_lib_save_LIBS
++fi
++echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5
++echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6
++if test $ac_cv_lib_dld_shl_load = yes; then
++ lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld"
++else
++ echo "$as_me:$LINENO: checking for dlopen" >&5
++echo $ECHO_N "checking for dlopen... $ECHO_C" >&6
++if test "${ac_cv_func_dlopen+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ cat >conftest.$ac_ext <<_ACEOF
++#line $LINENO "configure"
++#include "confdefs.h"
++/* System header to define __stub macros and hopefully few prototypes,
++ which can conflict with char dlopen (); below. */
++#include <assert.h>
++/* Override any gcc2 internal prototype to avoid an error. */
++#ifdef __cplusplus
++extern "C"
++#endif
++/* We use char because int might match the return type of a gcc2
++ builtin and then its argument prototype would still apply. */
++char dlopen ();
++char (*f) ();
++
++int
++main ()
++{
++/* The GNU C library defines this for functions which it implements
++ to always fail with ENOSYS. Some functions are actually named
++ something starting with __ and the normal name is an alias. */
++#if defined (__stub_dlopen) || defined (__stub___dlopen)
++choke me
++#else
++f = dlopen;
++#endif
++
++ ;
++ return 0;
++}
++_ACEOF
++rm -f conftest.$ac_objext conftest$ac_exeext
++if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
++ (eval $ac_link) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); } &&
++ { ac_try='test -s conftest$ac_exeext'
++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++ (eval $ac_try) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); }; }; then
++ ac_cv_func_dlopen=yes
++else
++ echo "$as_me: failed program was:" >&5
++cat conftest.$ac_ext >&5
++ac_cv_func_dlopen=no
++fi
++rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
++fi
++echo "$as_me:$LINENO: result: $ac_cv_func_dlopen" >&5
++echo "${ECHO_T}$ac_cv_func_dlopen" >&6
++if test $ac_cv_func_dlopen = yes; then
++ lt_cv_dlopen="dlopen"
++else
++ echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5
++echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6
++if test "${ac_cv_lib_dl_dlopen+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ ac_check_lib_save_LIBS=$LIBS
++LIBS="-ldl $LIBS"
++cat >conftest.$ac_ext <<_ACEOF
++#line $LINENO "configure"
++#include "confdefs.h"
++
++/* Override any gcc2 internal prototype to avoid an error. */
++#ifdef __cplusplus
++extern "C"
++#endif
++/* We use char because int might match the return type of a gcc2
++ builtin and then its argument prototype would still apply. */
++char dlopen ();
++int
++main ()
++{
++dlopen ();
++ ;
++ return 0;
++}
++_ACEOF
++rm -f conftest.$ac_objext conftest$ac_exeext
++if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
++ (eval $ac_link) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); } &&
++ { ac_try='test -s conftest$ac_exeext'
++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++ (eval $ac_try) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); }; }; then
++ ac_cv_lib_dl_dlopen=yes
++else
++ echo "$as_me: failed program was:" >&5
++cat conftest.$ac_ext >&5
++ac_cv_lib_dl_dlopen=no
++fi
++rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
++LIBS=$ac_check_lib_save_LIBS
++fi
++echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5
++echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6
++if test $ac_cv_lib_dl_dlopen = yes; then
++ lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
++else
++ echo "$as_me:$LINENO: checking for dlopen in -lsvld" >&5
++echo $ECHO_N "checking for dlopen in -lsvld... $ECHO_C" >&6
++if test "${ac_cv_lib_svld_dlopen+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ ac_check_lib_save_LIBS=$LIBS
++LIBS="-lsvld $LIBS"
++cat >conftest.$ac_ext <<_ACEOF
++#line $LINENO "configure"
++#include "confdefs.h"
++
++/* Override any gcc2 internal prototype to avoid an error. */
++#ifdef __cplusplus
++extern "C"
++#endif
++/* We use char because int might match the return type of a gcc2
++ builtin and then its argument prototype would still apply. */
++char dlopen ();
++int
++main ()
++{
++dlopen ();
++ ;
++ return 0;
++}
++_ACEOF
++rm -f conftest.$ac_objext conftest$ac_exeext
++if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
++ (eval $ac_link) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); } &&
++ { ac_try='test -s conftest$ac_exeext'
++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++ (eval $ac_try) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); }; }; then
++ ac_cv_lib_svld_dlopen=yes
++else
++ echo "$as_me: failed program was:" >&5
++cat conftest.$ac_ext >&5
++ac_cv_lib_svld_dlopen=no
++fi
++rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
++LIBS=$ac_check_lib_save_LIBS
++fi
++echo "$as_me:$LINENO: result: $ac_cv_lib_svld_dlopen" >&5
++echo "${ECHO_T}$ac_cv_lib_svld_dlopen" >&6
++if test $ac_cv_lib_svld_dlopen = yes; then
++ lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"
++else
++ echo "$as_me:$LINENO: checking for dld_link in -ldld" >&5
++echo $ECHO_N "checking for dld_link in -ldld... $ECHO_C" >&6
++if test "${ac_cv_lib_dld_dld_link+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ ac_check_lib_save_LIBS=$LIBS
++LIBS="-ldld $LIBS"
++cat >conftest.$ac_ext <<_ACEOF
++#line $LINENO "configure"
++#include "confdefs.h"
++
++/* Override any gcc2 internal prototype to avoid an error. */
++#ifdef __cplusplus
++extern "C"
++#endif
++/* We use char because int might match the return type of a gcc2
++ builtin and then its argument prototype would still apply. */
++char dld_link ();
++int
++main ()
++{
++dld_link ();
++ ;
++ return 0;
++}
++_ACEOF
++rm -f conftest.$ac_objext conftest$ac_exeext
++if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
++ (eval $ac_link) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); } &&
++ { ac_try='test -s conftest$ac_exeext'
++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++ (eval $ac_try) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); }; }; then
++ ac_cv_lib_dld_dld_link=yes
++else
++ echo "$as_me: failed program was:" >&5
++cat conftest.$ac_ext >&5
++ac_cv_lib_dld_dld_link=no
++fi
++rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
++LIBS=$ac_check_lib_save_LIBS
++fi
++echo "$as_me:$LINENO: result: $ac_cv_lib_dld_dld_link" >&5
++echo "${ECHO_T}$ac_cv_lib_dld_dld_link" >&6
++if test $ac_cv_lib_dld_dld_link = yes; then
++ lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"
++fi
++
++
++fi
++
++
++fi
++
++
++fi
++
++
++fi
++
++
++fi
++
++ ;;
++ esac
++
++ if test "x$lt_cv_dlopen" != xno; then
++ enable_dlopen=yes
++ else
++ enable_dlopen=no
++ fi
++
++ case $lt_cv_dlopen in
++ dlopen)
++ save_CPPFLAGS="$CPPFLAGS"
++ test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
++
++ save_LDFLAGS="$LDFLAGS"
++ eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
++
++ save_LIBS="$LIBS"
++ LIBS="$lt_cv_dlopen_libs $LIBS"
++
++ echo "$as_me:$LINENO: checking whether a program can dlopen itself" >&5
++echo $ECHO_N "checking whether a program can dlopen itself... $ECHO_C" >&6
++if test "${lt_cv_dlopen_self+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ if test "$cross_compiling" = yes; then :
++ lt_cv_dlopen_self=cross
++else
++ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
++ lt_status=$lt_dlunknown
++ cat > conftest.$ac_ext <<EOF
++#line __oline__ "configure"
++#include "confdefs.h"
++
++#if HAVE_DLFCN_H
++#include <dlfcn.h>
++#endif
++
++#include <stdio.h>
++
++#ifdef RTLD_GLOBAL
++# define LT_DLGLOBAL RTLD_GLOBAL
++#else
++# ifdef DL_GLOBAL
++# define LT_DLGLOBAL DL_GLOBAL
++# else
++# define LT_DLGLOBAL 0
++# endif
++#endif
++
++/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
++ find out it does not work in some platform. */
++#ifndef LT_DLLAZY_OR_NOW
++# ifdef RTLD_LAZY
++# define LT_DLLAZY_OR_NOW RTLD_LAZY
++# else
++# ifdef DL_LAZY
++# define LT_DLLAZY_OR_NOW DL_LAZY
++# else
++# ifdef RTLD_NOW
++# define LT_DLLAZY_OR_NOW RTLD_NOW
++# else
++# ifdef DL_NOW
++# define LT_DLLAZY_OR_NOW DL_NOW
++# else
++# define LT_DLLAZY_OR_NOW 0
++# endif
++# endif
++# endif
++# endif
++#endif
++
++#ifdef __cplusplus
++extern "C" void exit (int);
++#endif
++
++void fnord() { int i=42;}
++int main ()
++{
++ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
++ int status = $lt_dlunknown;
++
++ if (self)
++ {
++ if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
++ else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
++ /* dlclose (self); */
++ }
++
++ exit (status);
++}
++EOF
++ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
++ (eval $ac_link) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then
++ (./conftest; exit; ) 2>/dev/null
++ lt_status=$?
++ case x$lt_status in
++ x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;;
++ x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;;
++ x$lt_unknown|x*) lt_cv_dlopen_self=no ;;
++ esac
++ else :
++ # compilation failed
++ lt_cv_dlopen_self=no
++ fi
++fi
++rm -fr conftest*
++
++
++fi
++echo "$as_me:$LINENO: result: $lt_cv_dlopen_self" >&5
++echo "${ECHO_T}$lt_cv_dlopen_self" >&6
++
++ if test "x$lt_cv_dlopen_self" = xyes; then
++ LDFLAGS="$LDFLAGS $link_static_flag"
++ echo "$as_me:$LINENO: checking whether a statically linked program can dlopen itself" >&5
++echo $ECHO_N "checking whether a statically linked program can dlopen itself... $ECHO_C" >&6
++if test "${lt_cv_dlopen_self_static+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ if test "$cross_compiling" = yes; then :
++ lt_cv_dlopen_self_static=cross
++else
++ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
++ lt_status=$lt_dlunknown
++ cat > conftest.$ac_ext <<EOF
++#line __oline__ "configure"
++#include "confdefs.h"
++
++#if HAVE_DLFCN_H
++#include <dlfcn.h>
++#endif
++
++#include <stdio.h>
++
++#ifdef RTLD_GLOBAL
++# define LT_DLGLOBAL RTLD_GLOBAL
++#else
++# ifdef DL_GLOBAL
++# define LT_DLGLOBAL DL_GLOBAL
++# else
++# define LT_DLGLOBAL 0
++# endif
++#endif
++
++/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
++ find out it does not work in some platform. */
++#ifndef LT_DLLAZY_OR_NOW
++# ifdef RTLD_LAZY
++# define LT_DLLAZY_OR_NOW RTLD_LAZY
++# else
++# ifdef DL_LAZY
++# define LT_DLLAZY_OR_NOW DL_LAZY
++# else
++# ifdef RTLD_NOW
++# define LT_DLLAZY_OR_NOW RTLD_NOW
++# else
++# ifdef DL_NOW
++# define LT_DLLAZY_OR_NOW DL_NOW
++# else
++# define LT_DLLAZY_OR_NOW 0
++# endif
++# endif
++# endif
++# endif
++#endif
++
++#ifdef __cplusplus
++extern "C" void exit (int);
++#endif
++
++void fnord() { int i=42;}
++int main ()
++{
++ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
++ int status = $lt_dlunknown;
++
++ if (self)
++ {
++ if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
++ else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
++ /* dlclose (self); */
++ }
++
++ exit (status);
++}
++EOF
++ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
++ (eval $ac_link) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then
++ (./conftest; exit; ) 2>/dev/null
++ lt_status=$?
++ case x$lt_status in
++ x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;;
++ x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;;
++ x$lt_unknown|x*) lt_cv_dlopen_self_static=no ;;
++ esac
++ else :
++ # compilation failed
++ lt_cv_dlopen_self_static=no
++ fi
++fi
++rm -fr conftest*
++
++
++fi
++echo "$as_me:$LINENO: result: $lt_cv_dlopen_self_static" >&5
++echo "${ECHO_T}$lt_cv_dlopen_self_static" >&6
++ fi
++
++ CPPFLAGS="$save_CPPFLAGS"
++ LDFLAGS="$save_LDFLAGS"
++ LIBS="$save_LIBS"
++ ;;
++ esac
++
++ case $lt_cv_dlopen_self in
++ yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
++ *) enable_dlopen_self=unknown ;;
++ esac
++
++ case $lt_cv_dlopen_self_static in
++ yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
++ *) enable_dlopen_self_static=unknown ;;
++ esac
++fi
++
++
++if test "$enable_shared" = yes && test "$GCC" = yes; then
++ case $archive_cmds in
++ *'~'*)
++ # FIXME: we may have to deal with multi-command sequences.
++ ;;
++ '$CC '*)
++ # Test whether the compiler implicitly links with -lc since on some
++ # systems, -lgcc has to come before -lc. If gcc already passes -lc
++ # to ld, don't add -lc before -lgcc.
++ echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5
++echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6
++ if test "${lt_cv_archive_cmds_need_lc+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ $rm conftest*
++ echo 'static int dummy;' > conftest.$ac_ext
++
++ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
++ (eval $ac_compile) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); }; then
++ soname=conftest
++ lib=conftest
++ libobjs=conftest.$ac_objext
++ deplibs=
++ wl=$lt_cv_prog_cc_wl
++ compiler_flags=-v
++ linker_flags=-v
++ verstring=
++ output_objdir=.
++ libname=conftest
++ save_allow_undefined_flag=$allow_undefined_flag
++ allow_undefined_flag=
++ if { (eval echo "$as_me:$LINENO: \"$archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5
++ (eval $archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); }
++ then
++ lt_cv_archive_cmds_need_lc=no
++ else
++ lt_cv_archive_cmds_need_lc=yes
++ fi
++ allow_undefined_flag=$save_allow_undefined_flag
++ else
++ cat conftest.err 1>&5
++ fi
++fi
++
++ echo "$as_me:$LINENO: result: $lt_cv_archive_cmds_need_lc" >&5
++echo "${ECHO_T}$lt_cv_archive_cmds_need_lc" >&6
++ ;;
++ esac
++fi
++need_lc=${lt_cv_archive_cmds_need_lc-yes}
++
++# The second clause should only fire when bootstrapping the
++# libtool distribution, otherwise you forgot to ship ltmain.sh
++# with your package, and you will get complaints that there are
++# no rules to generate ltmain.sh.
++if test -f "$ltmain"; then
++ :
++else
++ # If there is no Makefile yet, we rely on a make rule to execute
++ # `config.status --recheck' to rerun these tests and create the
++ # libtool script then.
++ test -f Makefile && make "$ltmain"
++fi
++
++if test -f "$ltmain"; then
++ trap "$rm \"${ofile}T\"; exit 1" 1 2 15
++ $rm -f "${ofile}T"
++
++ echo creating $ofile
++
++ # Now quote all the things that may contain metacharacters while being
++ # careful not to overquote the AC_SUBSTed values. We take copies of the
++ # variables and quote the copies for generation of the libtool script.
++ for var in echo old_CC old_CFLAGS \
++ AR AR_FLAGS CC LD LN_S NM SHELL \
++ reload_flag reload_cmds wl \
++ pic_flag link_static_flag no_builtin_flag export_dynamic_flag_spec \
++ thread_safe_flag_spec whole_archive_flag_spec libname_spec \
++ library_names_spec soname_spec \
++ RANLIB old_archive_cmds old_archive_from_new_cmds old_postinstall_cmds \
++ old_postuninstall_cmds archive_cmds archive_expsym_cmds postinstall_cmds \
++ postuninstall_cmds extract_expsyms_cmds old_archive_from_expsyms_cmds \
++ old_striplib striplib file_magic_cmd export_symbols_cmds \
++ deplibs_check_method allow_undefined_flag no_undefined_flag \
++ finish_cmds finish_eval global_symbol_pipe global_symbol_to_cdecl \
++ global_symbol_to_c_name_address \
++ hardcode_libdir_flag_spec hardcode_libdir_separator \
++ sys_lib_search_path_spec sys_lib_dlsearch_path_spec \
++ compiler_c_o compiler_o_lo need_locks exclude_expsyms include_expsyms; do
++
++ case $var in
++ reload_cmds | old_archive_cmds | old_archive_from_new_cmds | \
++ old_postinstall_cmds | old_postuninstall_cmds | \
++ export_symbols_cmds | archive_cmds | archive_expsym_cmds | \
++ extract_expsyms_cmds | old_archive_from_expsyms_cmds | \
++ postinstall_cmds | postuninstall_cmds | \
++ finish_cmds | sys_lib_search_path_spec | sys_lib_dlsearch_path_spec)
++ # Double-quote double-evaled strings.
++ eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\""
++ ;;
++ *)
++ eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\""
++ ;;
++ esac
++ done
++
++ cat <<__EOF__ > "${ofile}T"
++#! $SHELL
++
++# `$echo "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
++# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP)
++# NOTE: Changes made to this file will be lost: look at ltmain.sh.
++#
++# Copyright (C) 1996-2000 Free Software Foundation, Inc.
++# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
++#
++# This program is free software; you can redistribute it and/or modify
++# it under the terms of the GNU General Public License as published by
++# the Free Software Foundation; either version 2 of the License, or
++# (at your option) any later version.
++#
++# This program is distributed in the hope that it will be useful, but
++# WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++# General Public License for more details.
++#
++# You should have received a copy of the GNU General Public License
++# along with this program; if not, write to the Free Software
++# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++#
++# As a special exception to the GNU General Public License, if you
++# distribute this file as part of a program that contains a
++# configuration script generated by Autoconf, you may include it under
++# the same distribution terms that you use for the rest of that program.
++
++# Sed that helps us avoid accidentally triggering echo(1) options like -n.
++Xsed="sed -e s/^X//"
++
++# The HP-UX ksh and POSIX shell print the target directory to stdout
++# if CDPATH is set.
++if test "X\${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi
++
++# ### BEGIN LIBTOOL CONFIG
++
++# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
++
++# Shell to use when invoking shell scripts.
++SHELL=$lt_SHELL
++
++# Whether or not to build shared libraries.
++build_libtool_libs=$enable_shared
++
++# Whether or not to build static libraries.
++build_old_libs=$enable_static
++
++# Whether or not to add -lc for building shared libraries.
++build_libtool_need_lc=$need_lc
++
++# Whether or not to optimize for fast installation.
++fast_install=$enable_fast_install
++
++# The host system.
++host_alias=$host_alias
++host=$host
++
++# An echo program that does not interpret backslashes.
++echo=$lt_echo
++
++# The archiver.
++AR=$lt_AR
++AR_FLAGS=$lt_AR_FLAGS
++
++# The default C compiler.
++CC=$lt_CC
++
++# Is the compiler the GNU C compiler?
++with_gcc=$GCC
++
++# The linker used to build libraries.
++LD=$lt_LD
++
++# Whether we need hard or soft links.
++LN_S=$lt_LN_S
++
++# A BSD-compatible nm program.
++NM=$lt_NM
++
++# A symbol stripping program
++STRIP=$STRIP
++
++# Used to examine libraries when file_magic_cmd begins "file"
++MAGIC_CMD=$MAGIC_CMD
++
++# Used on cygwin: DLL creation program.
++DLLTOOL="$DLLTOOL"
++
++# Used on cygwin: object dumper.
++OBJDUMP="$OBJDUMP"
++
++# Used on cygwin: assembler.
++AS="$AS"
++
++# The name of the directory that contains temporary libtool files.
++objdir=$objdir
++
++# How to create reloadable object files.
++reload_flag=$lt_reload_flag
++reload_cmds=$lt_reload_cmds
++
++# How to pass a linker flag through the compiler.
++wl=$lt_wl
++
++# Object file suffix (normally "o").
++objext="$ac_objext"
++
++# Old archive suffix (normally "a").
++libext="$libext"
++
++# Executable file suffix (normally "").
++exeext="$exeext"
++
++# Additional compiler flags for building library objects.
++pic_flag=$lt_pic_flag
++pic_mode=$pic_mode
++
++# Does compiler simultaneously support -c and -o options?
++compiler_c_o=$lt_compiler_c_o
++
++# Can we write directly to a .lo ?
++compiler_o_lo=$lt_compiler_o_lo
++
++# Must we lock files when doing compilation ?
++need_locks=$lt_need_locks
++
++# Do we need the lib prefix for modules?
++need_lib_prefix=$need_lib_prefix
++
++# Do we need a version for libraries?
++need_version=$need_version
++
++# Whether dlopen is supported.
++dlopen_support=$enable_dlopen
++
++# Whether dlopen of programs is supported.
++dlopen_self=$enable_dlopen_self
++
++# Whether dlopen of statically linked programs is supported.
++dlopen_self_static=$enable_dlopen_self_static
++
++# Compiler flag to prevent dynamic linking.
++link_static_flag=$lt_link_static_flag
++
++# Compiler flag to turn off builtin functions.
++no_builtin_flag=$lt_no_builtin_flag
++
++# Compiler flag to allow reflexive dlopens.
++export_dynamic_flag_spec=$lt_export_dynamic_flag_spec
++
++# Compiler flag to generate shared objects directly from archives.
++whole_archive_flag_spec=$lt_whole_archive_flag_spec
++
++# Compiler flag to generate thread-safe objects.
++thread_safe_flag_spec=$lt_thread_safe_flag_spec
++
++# Library versioning type.
++version_type=$version_type
++
++# Format of library name prefix.
++libname_spec=$lt_libname_spec
++
++# List of archive names. First name is the real one, the rest are links.
++# The last name is the one that the linker finds with -lNAME.
++library_names_spec=$lt_library_names_spec
++
++# The coded name of the library, if different from the real name.
++soname_spec=$lt_soname_spec
++
++# Commands used to build and install an old-style archive.
++RANLIB=$lt_RANLIB
++old_archive_cmds=$lt_old_archive_cmds
++old_postinstall_cmds=$lt_old_postinstall_cmds
++old_postuninstall_cmds=$lt_old_postuninstall_cmds
++
++# Create an old-style archive from a shared archive.
++old_archive_from_new_cmds=$lt_old_archive_from_new_cmds
++
++# Create a temporary old-style archive to link instead of a shared archive.
++old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds
++
++# Commands used to build and install a shared archive.
++archive_cmds=$lt_archive_cmds
++archive_expsym_cmds=$lt_archive_expsym_cmds
++postinstall_cmds=$lt_postinstall_cmds
++postuninstall_cmds=$lt_postuninstall_cmds
++
++# Commands to strip libraries.
++old_striplib=$lt_old_striplib
++striplib=$lt_striplib
++
++# Method to check whether dependent libraries are shared objects.
++deplibs_check_method=$lt_deplibs_check_method
++
++# Command to use when deplibs_check_method == file_magic.
++file_magic_cmd=$lt_file_magic_cmd
++
++# Flag that allows shared libraries with undefined symbols to be built.
++allow_undefined_flag=$lt_allow_undefined_flag
++
++# Flag that forces no undefined symbols.
++no_undefined_flag=$lt_no_undefined_flag
++
++# Commands used to finish a libtool library installation in a directory.
++finish_cmds=$lt_finish_cmds
++
++# Same as above, but a single script fragment to be evaled but not shown.
++finish_eval=$lt_finish_eval
++
++# Take the output of nm and produce a listing of raw symbols and C names.
++global_symbol_pipe=$lt_global_symbol_pipe
++
++# Transform the output of nm in a proper C declaration
++global_symbol_to_cdecl=$lt_global_symbol_to_cdecl
++
++# Transform the output of nm in a C name address pair
++global_symbol_to_c_name_address=$lt_global_symbol_to_c_name_address
++
++# This is the shared library runtime path variable.
++runpath_var=$runpath_var
++
++# This is the shared library path variable.
++shlibpath_var=$shlibpath_var
++
++# Is shlibpath searched before the hard-coded library search path?
++shlibpath_overrides_runpath=$shlibpath_overrides_runpath
++
++# How to hardcode a shared library path into an executable.
++hardcode_action=$hardcode_action
++
++# Whether we should hardcode library paths into libraries.
++hardcode_into_libs=$hardcode_into_libs
++
++# Flag to hardcode \$libdir into a binary during linking.
++# This must work even if \$libdir does not exist.
++hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec
++
++# Whether we need a single -rpath flag with a separated argument.
++hardcode_libdir_separator=$lt_hardcode_libdir_separator
++
++# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the
++# resulting binary.
++hardcode_direct=$hardcode_direct
++
++# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
++# resulting binary.
++hardcode_minus_L=$hardcode_minus_L
++
++# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
++# the resulting binary.
++hardcode_shlibpath_var=$hardcode_shlibpath_var
++
++# Variables whose values should be saved in libtool wrapper scripts and
++# restored at relink time.
++variables_saved_for_relink="$variables_saved_for_relink"
++
++# Whether libtool must link a program against all its dependency libraries.
++link_all_deplibs=$link_all_deplibs
++
++# Compile-time system search path for libraries
++sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
++
++# Run-time system search path for libraries
++sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
++
++# Fix the shell variable \$srcfile for the compiler.
++fix_srcfile_path="$fix_srcfile_path"
++
++# Set to yes if exported symbols are required.
++always_export_symbols=$always_export_symbols
++
++# The commands to list exported symbols.
++export_symbols_cmds=$lt_export_symbols_cmds
++
++# The commands to extract the exported symbol list from a shared archive.
++extract_expsyms_cmds=$lt_extract_expsyms_cmds
++
++# Symbols that should not be listed in the preloaded symbols.
++exclude_expsyms=$lt_exclude_expsyms
++
++# Symbols that must always be exported.
++include_expsyms=$lt_include_expsyms
++
++# ### END LIBTOOL CONFIG
++
++__EOF__
++
++ case $host_os in
++ aix3*)
++ cat <<\EOF >> "${ofile}T"
++
++# AIX sometimes has problems with the GCC collect2 program. For some
++# reason, if we set the COLLECT_NAMES environment variable, the problems
++# vanish in a puff of smoke.
++if test "X${COLLECT_NAMES+set}" != Xset; then
++ COLLECT_NAMES=
++ export COLLECT_NAMES
++fi
++EOF
++ ;;
++ esac
++
++ case $host_os in
++ cygwin* | mingw* | pw32* | os2*)
++ cat <<'EOF' >> "${ofile}T"
++ # This is a source program that is used to create dlls on Windows
++ # Don't remove nor modify the starting and closing comments
++# /* ltdll.c starts here */
++# #define WIN32_LEAN_AND_MEAN
++# #include <windows.h>
++# #undef WIN32_LEAN_AND_MEAN
++# #include <stdio.h>
++#
++# #ifndef __CYGWIN__
++# # ifdef __CYGWIN32__
++# # define __CYGWIN__ __CYGWIN32__
++# # endif
++# #endif
++#
++# #ifdef __cplusplus
++# extern "C" {
++# #endif
++# BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved);
++# #ifdef __cplusplus
++# }
++# #endif
++#
++# #ifdef __CYGWIN__
++# #include <cygwin/cygwin_dll.h>
++# DECLARE_CYGWIN_DLL( DllMain );
++# #endif
++# HINSTANCE __hDllInstance_base;
++#
++# BOOL APIENTRY
++# DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved)
++# {
++# __hDllInstance_base = hInst;
++# return TRUE;
++# }
++# /* ltdll.c ends here */
++ # This is a source program that is used to create import libraries
++ # on Windows for dlls which lack them. Don't remove nor modify the
++ # starting and closing comments
++# /* impgen.c starts here */
++# /* Copyright (C) 1999-2000 Free Software Foundation, Inc.
++#
++# This file is part of GNU libtool.
++#
++# This program is free software; you can redistribute it and/or modify
++# it under the terms of the GNU General Public License as published by
++# the Free Software Foundation; either version 2 of the License, or
++# (at your option) any later version.
++#
++# This program is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++# GNU General Public License for more details.
++#
++# You should have received a copy of the GNU General Public License
++# along with this program; if not, write to the Free Software
++# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++# */
++#
++# #include <stdio.h> /* for printf() */
++# #include <unistd.h> /* for open(), lseek(), read() */
++# #include <fcntl.h> /* for O_RDONLY, O_BINARY */
++# #include <string.h> /* for strdup() */
++#
++# /* O_BINARY isn't required (or even defined sometimes) under Unix */
++# #ifndef O_BINARY
++# #define O_BINARY 0
++# #endif
++#
++# static unsigned int
++# pe_get16 (fd, offset)
++# int fd;
++# int offset;
++# {
++# unsigned char b[2];
++# lseek (fd, offset, SEEK_SET);
++# read (fd, b, 2);
++# return b[0] + (b[1]<<8);
++# }
++#
++# static unsigned int
++# pe_get32 (fd, offset)
++# int fd;
++# int offset;
++# {
++# unsigned char b[4];
++# lseek (fd, offset, SEEK_SET);
++# read (fd, b, 4);
++# return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24);
++# }
++#
++# static unsigned int
++# pe_as32 (ptr)
++# void *ptr;
++# {
++# unsigned char *b = ptr;
++# return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24);
++# }
++#
++# int
++# main (argc, argv)
++# int argc;
++# char *argv[];
++# {
++# int dll;
++# unsigned long pe_header_offset, opthdr_ofs, num_entries, i;
++# unsigned long export_rva, export_size, nsections, secptr, expptr;
++# unsigned long name_rvas, nexp;
++# unsigned char *expdata, *erva;
++# char *filename, *dll_name;
++#
++# filename = argv[1];
++#
++# dll = open(filename, O_RDONLY|O_BINARY);
++# if (dll < 1)
++# return 1;
++#
++# dll_name = filename;
++#
++# for (i=0; filename[i]; i++)
++# if (filename[i] == '/' || filename[i] == '\\' || filename[i] == ':')
++# dll_name = filename + i +1;
++#
++# pe_header_offset = pe_get32 (dll, 0x3c);
++# opthdr_ofs = pe_header_offset + 4 + 20;
++# num_entries = pe_get32 (dll, opthdr_ofs + 92);
++#
++# if (num_entries < 1) /* no exports */
++# return 1;
++#
++# export_rva = pe_get32 (dll, opthdr_ofs + 96);
++# export_size = pe_get32 (dll, opthdr_ofs + 100);
++# nsections = pe_get16 (dll, pe_header_offset + 4 +2);
++# secptr = (pe_header_offset + 4 + 20 +
++# pe_get16 (dll, pe_header_offset + 4 + 16));
++#
++# expptr = 0;
++# for (i = 0; i < nsections; i++)
++# {
++# char sname[8];
++# unsigned long secptr1 = secptr + 40 * i;
++# unsigned long vaddr = pe_get32 (dll, secptr1 + 12);
++# unsigned long vsize = pe_get32 (dll, secptr1 + 16);
++# unsigned long fptr = pe_get32 (dll, secptr1 + 20);
++# lseek(dll, secptr1, SEEK_SET);
++# read(dll, sname, 8);
++# if (vaddr <= export_rva && vaddr+vsize > export_rva)
++# {
++# expptr = fptr + (export_rva - vaddr);
++# if (export_rva + export_size > vaddr + vsize)
++# export_size = vsize - (export_rva - vaddr);
++# break;
++# }
++# }
++#
++# expdata = (unsigned char*)malloc(export_size);
++# lseek (dll, expptr, SEEK_SET);
++# read (dll, expdata, export_size);
++# erva = expdata - export_rva;
++#
++# nexp = pe_as32 (expdata+24);
++# name_rvas = pe_as32 (expdata+32);
++#
++# printf ("EXPORTS\n");
++# for (i = 0; i<nexp; i++)
++# {
++# unsigned long name_rva = pe_as32 (erva+name_rvas+i*4);
++# printf ("\t%s @ %ld ;\n", erva+name_rva, 1+ i);
++# }
++#
++# return 0;
++# }
++# /* impgen.c ends here */
++
++EOF
++ ;;
++ esac
++
++ # We use sed instead of cat because bash on DJGPP gets confused if
++ # if finds mixed CR/LF and LF-only lines. Since sed operates in
++ # text mode, it properly converts lines to CR/LF. This bash problem
++ # is reportedly fixed, but why not run on old versions too?
++ sed '$q' "$ltmain" >> "${ofile}T" || (rm -f "${ofile}T"; exit 1)
++
++ mv -f "${ofile}T" "$ofile" || \
++ (rm -f "$ofile" && cp "${ofile}T" "$ofile" && rm -f "${ofile}T")
++ chmod +x "$ofile"
++fi
++
++
++
++
++
++# This can be used to rebuild libtool when needed
++LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh"
++
++# Always use our own libtool.
++LIBTOOL='$(SHELL) $(top_builddir)/libtool'
++
++# Prevent multiple expansion
++
++
++
++
++# Check whether --with-target-subdir or --without-target-subdir was given.
++if test "${with_target_subdir+set}" = set; then
++ withval="$with_target_subdir"
++
++fi;
++
++# Check whether --with-cross-host or --without-cross-host was given.
++if test "${with_cross_host+set}" = set; then
++ withval="$with_cross_host"
++
++fi;
++
++echo "$as_me:$LINENO: checking whether to enable maintainer-specific portions of Makefiles" >&5
++echo $ECHO_N "checking whether to enable maintainer-specific portions of Makefiles... $ECHO_C" >&6
++ # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given.
++if test "${enable_maintainer_mode+set}" = set; then
++ enableval="$enable_maintainer_mode"
++ USE_MAINTAINER_MODE=$enableval
++else
++ USE_MAINTAINER_MODE=no
++fi;
++ echo "$as_me:$LINENO: result: $USE_MAINTAINER_MODE" >&5
++echo "${ECHO_T}$USE_MAINTAINER_MODE" >&6
++
++
++if test $USE_MAINTAINER_MODE = yes; then
++ MAINTAINER_MODE_TRUE=
++ MAINTAINER_MODE_FALSE='#'
++else
++ MAINTAINER_MODE_TRUE='#'
++ MAINTAINER_MODE_FALSE=
++fi
++
++ MAINT=$MAINTAINER_MODE_TRUE
++
++
++# automake wants to see AC_EXEEXT. But we don't need it. And having
++# it is actually a problem, because the compiler we're passed can't
++# necessarily do a full link. So we fool automake here.
++if false; then
++ # autoconf 2.50 runs AC_EXEEXT by default, and the macro expands
++ # to nothing, so nothing would remain between `then' and `fi' if it
++ # were not for the `:' below.
++ :
++
++fi
++
++echo "$as_me:$LINENO: checking for thread model used by GCC" >&5
++echo $ECHO_N "checking for thread model used by GCC... $ECHO_C" >&6
++THREADS=`$CC -v 2>&1 | sed -n 's/^Thread model: //p'`
++if test -z "$THREADS"; then
++ THREADS=no
++fi
++echo "$as_me:$LINENO: result: $THREADS" >&5
++echo "${ECHO_T}$THREADS" >&6
++
++# Check whether --enable-parallel-mark or --disable-parallel-mark was given.
++if test "${enable_parallel_mark+set}" = set; then
++ enableval="$enable_parallel_mark"
++ case "$THREADS" in
++ no | none | single)
++ { { echo "$as_me:$LINENO: error: Parallel mark requires --enable-threads=x spec" >&5
++echo "$as_me: error: Parallel mark requires --enable-threads=x spec" >&2;}
++ { (exit 1); exit 1; }; }
++ ;;
++ esac
++
++fi;
++
++INCLUDES=-I${srcdir}/include
++THREADLIBS=
++case "$THREADS" in
++ no | none | single)
++ THREADS=none
++ ;;
++ posix | pthreads)
++ THREADS=posix
++ THREADLIBS=-lpthread
++ case "$host" in
++ x86-*-linux* | ia64-*-linux* | i586-*-linux* | i686-*-linux* | x86_64-*-linux* )
++ cat >>confdefs.h <<\_ACEOF
++@%:@define GC_LINUX_THREADS 1
++_ACEOF
++
++ cat >>confdefs.h <<\_ACEOF
++@%:@define _REENTRANT 1
++_ACEOF
++
++ if test "${enable_parallel_mark}"; then
++ cat >>confdefs.h <<\_ACEOF
++@%:@define PARALLEL_MARK 1
++_ACEOF
++
++ fi
++ cat >>confdefs.h <<\_ACEOF
++@%:@define THREAD_LOCAL_ALLOC 1
++_ACEOF
++
++ ;;
++ *-*-linux*)
++ cat >>confdefs.h <<\_ACEOF
++@%:@define GC_LINUX_THREADS 1
++_ACEOF
++
++ cat >>confdefs.h <<\_ACEOF
++@%:@define _REENTRANT 1
++_ACEOF
++
++ ;;
++ *-*-hpux*)
++ { echo "$as_me:$LINENO: WARNING: \"Only HP/UX 11 threads are supported.\"" >&5
++echo "$as_me: WARNING: \"Only HP/UX 11 threads are supported.\"" >&2;}
++ cat >>confdefs.h <<\_ACEOF
++@%:@define GC_HPUX_THREADS 1
++_ACEOF
++
++ cat >>confdefs.h <<\_ACEOF
++@%:@define _POSIX_C_SOURCE 199506L
++_ACEOF
++
++ if test "${enable_parallel_mark}" = yes; then
++ cat >>confdefs.h <<\_ACEOF
++@%:@define PARALLEL_MARK 1
++_ACEOF
++
++ fi
++ cat >>confdefs.h <<\_ACEOF
++@%:@define THREAD_LOCAL_ALLOC 1
++_ACEOF
++
++ THREADLIBS="-lpthread -lrt"
++ ;;
++ *-*-freebsd*)
++ { echo "$as_me:$LINENO: WARNING: \"FreeBSD does not yet fully support threads with Boehm GC.\"" >&5
++echo "$as_me: WARNING: \"FreeBSD does not yet fully support threads with Boehm GC.\"" >&2;}
++ cat >>confdefs.h <<\_ACEOF
++@%:@define GC_FREEBSD_THREADS 1
++_ACEOF
++
++ INCLUDES="$INCLUDES -pthread"
++ THREADLIBS=-pthread
++ ;;
++ *-*-solaris*)
++ cat >>confdefs.h <<\_ACEOF
++@%:@define GC_SOLARIS_THREADS 1
++_ACEOF
++
++ cat >>confdefs.h <<\_ACEOF
++@%:@define GC_SOLARIS_PTHREADS 1
++_ACEOF
++
++ ;;
++ *-*-irix*)
++ cat >>confdefs.h <<\_ACEOF
++@%:@define GC_IRIX_THREADS 1
++_ACEOF
++
++ ;;
++ *-*-cygwin*)
++ THREADLIBS=
++ ;;
++ *-*-darwin*)
++ cat >>confdefs.h <<\_ACEOF
++@%:@define GC_DARWIN_THREADS 1
++_ACEOF
++
++ cat >>confdefs.h <<\_ACEOF
++@%:@define THREAD_LOCAL_ALLOC 1
++_ACEOF
++
++ if test "${enable_parallel_mark}" = yes; then
++ cat >>confdefs.h <<\_ACEOF
++@%:@define PARALLEL_MARK 1
++_ACEOF
++
++ fi
++ ;;
++ esac
++ ;;
++ win32)
++ cat >>confdefs.h <<\_ACEOF
++@%:@define GC_WIN32_THREADS 1
++_ACEOF
++
++ cat >>confdefs.h <<\_ACEOF
++@%:@define NO_GETENV 1
++_ACEOF
++
++ ;;
++ decosf1 | irix | mach | os2 | solaris | dce | vxworks)
++ { { echo "$as_me:$LINENO: error: thread package $THREADS not yet supported" >&5
++echo "$as_me: error: thread package $THREADS not yet supported" >&2;}
++ { (exit 1); exit 1; }; }
++ ;;
++ *)
++ { { echo "$as_me:$LINENO: error: $THREADS is an unknown thread package" >&5
++echo "$as_me: error: $THREADS is an unknown thread package" >&2;}
++ { (exit 1); exit 1; }; }
++ ;;
++esac
++
++
++case "$host" in
++ powerpc-*-darwin*)
++ powerpc_darwin=true
++ ;;
++esac
++
++
++if test x$powerpc_darwin = xtrue; then
++ POWERPC_DARWIN_TRUE=
++ POWERPC_DARWIN_FALSE='#'
++else
++ POWERPC_DARWIN_TRUE='#'
++ POWERPC_DARWIN_FALSE=
++fi
++
++
++# We never want libdl on darwin. It is a fake libdl that just ends up making
++# dyld calls anyway
++case "$host" in
++ *-*-darwin*) ;;
++ *)
++ echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5
++echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6
++if test "${ac_cv_lib_dl_dlopen+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ ac_check_lib_save_LIBS=$LIBS
++LIBS="-ldl $LIBS"
++cat >conftest.$ac_ext <<_ACEOF
++#line $LINENO "configure"
++#include "confdefs.h"
++
++/* Override any gcc2 internal prototype to avoid an error. */
++#ifdef __cplusplus
++extern "C"
++#endif
++/* We use char because int might match the return type of a gcc2
++ builtin and then its argument prototype would still apply. */
++char dlopen ();
++int
++main ()
++{
++dlopen ();
++ ;
++ return 0;
++}
++_ACEOF
++rm -f conftest.$ac_objext conftest$ac_exeext
++if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
++ (eval $ac_link) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); } &&
++ { ac_try='test -s conftest$ac_exeext'
++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++ (eval $ac_try) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); }; }; then
++ ac_cv_lib_dl_dlopen=yes
++else
++ echo "$as_me: failed program was:" >&5
++cat conftest.$ac_ext >&5
++ac_cv_lib_dl_dlopen=no
++fi
++rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
++LIBS=$ac_check_lib_save_LIBS
++fi
++echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5
++echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6
++if test $ac_cv_lib_dl_dlopen = yes; then
++ EXTRA_TEST_LIBS="$EXTRA_TEST_LIBS -ldl"
++fi
++
++ ;;
++esac
++
++
++
++target_all=libgcjgc.la
++
++
++
++TARGET_ECOS="no"
++
++# Check whether --with-ecos or --without-ecos was given.
++if test "${with_ecos+set}" = set; then
++ withval="$with_ecos"
++ TARGET_ECOS="$with_ecos"
++
++fi;
++
++addobjs=
++CXXINCLUDES=
++case "$TARGET_ECOS" in
++ no)
++ ;;
++ *)
++ cat >>confdefs.h <<\_ACEOF
++@%:@define ECOS 1
++_ACEOF
++
++ CXXINCLUDES="-I${TARGET_ECOS}/include"
++ addobjs="$addobjs ecos.lo"
++ ;;
++esac
++
++
++
++
++
++machdep=
++case "$host" in
++ alpha*-*-openbsd*)
++ machdep="alpha_mach_dep.lo"
++ if test x"${ac_cv_lib_dl_dlopen}" != xyes ; then
++ { echo "$as_me:$LINENO: WARNING: OpenBSD/Alpha without dlopen(). Shared library support is disabled" >&5
++echo "$as_me: WARNING: OpenBSD/Alpha without dlopen(). Shared library support is disabled" >&2;}
++ # Check whether --enable-shared or --disable-shared was given.
++if test "${enable_shared+set}" = set; then
++ enableval="$enable_shared"
++ p=${PACKAGE-default}
++case $enableval in
++yes) enable_shared=yes ;;
++no) enable_shared=no ;;
++*)
++ enable_shared=no
++ # Look at the argument we got. We use all the common list separators.
++ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
++ for pkg in $enableval; do
++ if test "X$pkg" = "X$p"; then
++ enable_shared=yes
++ fi
++ done
++ IFS="$ac_save_ifs"
++ ;;
++esac
++else
++ enable_shared=no
++fi;
++ fi
++ ;;
++ alpha*-*-*)
++ machdep="alpha_mach_dep.lo"
++ ;;
++ i?86-*-solaris2.[89]*)
++ cat >>confdefs.h <<\_ACEOF
++@%:@define SOLARIS25_PROC_VDB_BUG_FIXED 1
++_ACEOF
++
++ ;;
++ mipstx39-*-elf*)
++ machdep="mips_ultrix_mach_dep.lo"
++ cat >>confdefs.h <<\_ACEOF
++@%:@define STACKBASE __stackbase
++_ACEOF
++
++ cat >>confdefs.h <<\_ACEOF
++@%:@define DATASTART_IS_ETEXT 1
++_ACEOF
++
++ ;;
++ mips-dec-ultrix*)
++ machdep="mips_ultrix_mach-dep.lo"
++ ;;
++ mips*-*-linux*)
++ ;;
++ mips-*-*)
++ machdep="mips_sgi_mach_dep.lo"
++ cat >>confdefs.h <<\_ACEOF
++@%:@define NO_EXECUTE_PERMISSION 1
++_ACEOF
++
++ ;;
++ sparc-sun-solaris2.3*)
++ machdep="sparc_mach_dep.lo"
++ cat >>confdefs.h <<\_ACEOF
++@%:@define SUNOS53_SHARED_LIB 1
++_ACEOF
++
++ ;;
++ sparc-sun-solaris2.*)
++ machdep="sparc_mach_dep.lo"
++ ;;
++ ia64-*-*)
++ machdep="mach_dep.lo ia64_save_regs_in_stack.lo"
++ ;;
++esac
++if test x"$machdep" = x; then
++ machdep="mach_dep.lo"
++fi
++addobjs="$addobjs $machdep"
++
++
++case "$host" in
++ sparc-sun-solaris2*)
++ if test "$GCC" = yes; then
++ new_CFLAGS=
++ for i in $CFLAGS; do
++ case "$i" in
++ -O*)
++ ;;
++ *)
++ new_CFLAGS="$new_CFLAGS $i"
++ ;;
++ esac
++ done
++ CFLAGS="$new_CFLAGS"
++ fi
++ ;;
++esac
++
++MY_CFLAGS="$CFLAGS"
++
++
++cat >>confdefs.h <<\_ACEOF
++@%:@define SILENT 1
++_ACEOF
++
++cat >>confdefs.h <<\_ACEOF
++@%:@define NO_SIGNALS 1
++_ACEOF
++
++cat >>confdefs.h <<\_ACEOF
++@%:@define NO_EXECUTE_PERMISSION 1
++_ACEOF
++
++cat >>confdefs.h <<\_ACEOF
++@%:@define ALL_INTERIOR_POINTERS 1
++_ACEOF
++
++
++cat >>confdefs.h <<\_ACEOF
++@%:@define JAVA_FINALIZATION 1
++_ACEOF
++
++cat >>confdefs.h <<\_ACEOF
++@%:@define GC_GCJ_SUPPORT 1
++_ACEOF
++
++cat >>confdefs.h <<\_ACEOF
++@%:@define ATOMIC_UNCOLLECTABLE 1
++_ACEOF
++
++
++if test -n "${with_cross_host}"; then
++ cat >>confdefs.h <<\_ACEOF
++@%:@define NO_SIGSET 1
++_ACEOF
++
++ cat >>confdefs.h <<\_ACEOF
++@%:@define NO_DEBUGGING 1
++_ACEOF
++
++fi
++
++# Check whether --enable-full-debug or --disable-full-debug was given.
++if test "${enable_full_debug+set}" = set; then
++ enableval="$enable_full_debug"
++ if test "$enable_full_debug" = "yes"; then
++ { echo "$as_me:$LINENO: WARNING: \"Must define GC_DEBUG and use debug alloc. in clients.\"" >&5
++echo "$as_me: WARNING: \"Must define GC_DEBUG and use debug alloc. in clients.\"" >&2;}
++ cat >>confdefs.h <<\_ACEOF
++@%:@define KEEP_BACK_PTRS 1
++_ACEOF
++
++ cat >>confdefs.h <<\_ACEOF
++@%:@define DBG_HDRS_ALL 1
++_ACEOF
++
++ case $host in
++ ia64-*-linux* )
++ cat >>confdefs.h <<\_ACEOF
++@%:@define MAKE_BACK_GRAPH 1
++_ACEOF
++
++ ;;
++ x86-*-linux* | i586-*-linux* | i686-*-linux* | x86_64-*-linux* )
++ cat >>confdefs.h <<\_ACEOF
++@%:@define MAKE_BACK_GRAPH 1
++_ACEOF
++
++ { echo "$as_me:$LINENO: WARNING: \"Client must not use -fomit-frame-pointer.\"" >&5
++echo "$as_me: WARNING: \"Client must not use -fomit-frame-pointer.\"" >&2;}
++ cat >>confdefs.h <<\_ACEOF
++@%:@define SAVE_CALL_COUNT 8
++_ACEOF
++
++ ;;
++ esac
++ fi
++fi;
++
++
++
++if test -z "$with_cross_host"; then
++ USE_LIBDIR_TRUE=
++ USE_LIBDIR_FALSE='#'
++else
++ USE_LIBDIR_TRUE='#'
++ USE_LIBDIR_FALSE=
++fi
++
++
++if test "${multilib}" = "yes"; then
++ multilib_arg="--enable-multilib"
++else
++ multilib_arg=
++fi
++
++ ac_config_files="$ac_config_files Makefile include/Makefile"
++ ac_config_commands="$ac_config_commands default"
++cat >confcache <<\_ACEOF
++# This file is a shell script that caches the results of configure
++# tests run on this system so they can be shared between configure
++# scripts and configure runs, see configure's option --config-cache.
++# It is not useful on other systems. If it contains results you don't
++# want to keep, you may remove or edit it.
++#
++# config.status only pays attention to the cache file if you give it
++# the --recheck option to rerun configure.
++#
++# `ac_cv_env_foo' variables (set or unset) will be overridden when
++# loading this file, other *unset* `ac_cv_foo' will be assigned the
++# following values.
++
++_ACEOF
++
++# The following way of writing the cache mishandles newlines in values,
++# but we know of no workaround that is simple, portable, and efficient.
++# So, don't put newlines in cache variables' values.
++# Ultrix sh set writes to stderr and can't be redirected directly,
++# and sets the high bit in the cache file unless we assign to the vars.
++{
++ (set) 2>&1 |
++ case `(ac_space=' '; set | grep ac_space) 2>&1` in
++ *ac_space=\ *)
++ # `set' does not quote correctly, so add quotes (double-quote
++ # substitution turns \\\\ into \\, and sed turns \\ into \).
++ sed -n \
++ "s/'/'\\\\''/g;
++ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
++ ;;
++ *)
++ # `set' quotes correctly as required by POSIX, so do not add quotes.
++ sed -n \
++ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
++ ;;
++ esac;
++} |
++ sed '
++ t clear
++ : clear
++ s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
++ t end
++ /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
++ : end' >>confcache
++if cmp -s $cache_file confcache; then :; else
++ if test -w $cache_file; then
++ test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
++ cat confcache >$cache_file
++ else
++ echo "not updating unwritable cache $cache_file"
++ fi
++fi
++rm -f confcache
++
++test "x$prefix" = xNONE && prefix=$ac_default_prefix
++# Let make expand exec_prefix.
++test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
++
++# VPATH may cause trouble with some makes, so we remove $(srcdir),
++# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
++# trailing colons and then remove the whole line if VPATH becomes empty
++# (actually we leave an empty line to preserve line numbers).
++if test "x$srcdir" = x.; then
++ ac_vpsub='/^[ ]*VPATH[ ]*=/{
++s/:*\$(srcdir):*/:/;
++s/:*\${srcdir}:*/:/;
++s/:*@srcdir@:*/:/;
++s/^\([^=]*=[ ]*\):*/\1/;
++s/:*$//;
++s/^[^=]*=[ ]*$//;
++}'
++fi
++
++# Transform confdefs.h into DEFS.
++# Protect against shell expansion while executing Makefile rules.
++# Protect against Makefile macro expansion.
++#
++# If the first sed substitution is executed (which looks for macros that
++# take arguments), then we branch to the quote section. Otherwise,
++# look for a macro that doesn't take arguments.
++cat >confdef2opt.sed <<\_ACEOF
++t clear
++: clear
++s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\),-D\1=\2,g
++t quote
++s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\),-D\1=\2,g
++t quote
++d
++: quote
++s,[ `~#$^&*(){}\\|;'"<>?],\\&,g
++s,\[,\\&,g
++s,\],\\&,g
++s,\$,$$,g
++p
++_ACEOF
++# We use echo to avoid assuming a particular line-breaking character.
++# The extra dot is to prevent the shell from consuming trailing
++# line-breaks from the sub-command output. A line-break within
++# single-quotes doesn't work because, if this script is created in a
++# platform that uses two characters for line-breaks (e.g., DOS), tr
++# would break.
++ac_LF_and_DOT=`echo; echo .`
++DEFS=`sed -n -f confdef2opt.sed confdefs.h | tr "$ac_LF_and_DOT" ' .'`
++rm -f confdef2opt.sed
++
++
++ac_libobjs=
++ac_ltlibobjs=
++for ac_i in : $LIB@&t@OBJS; do test "x$ac_i" = x: && continue
++ # 1. Remove the extension, and $U if already installed.
++ ac_i=`echo "$ac_i" |
++ sed 's/\$U\././;s/\.o$//;s/\.obj$//'`
++ # 2. Add them.
++ ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext"
++ ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo'
++done
++LIB@&t@OBJS=$ac_libobjs
++
++LTLIBOBJS=$ac_ltlibobjs
++
++
++if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then
++ { { echo "$as_me:$LINENO: error: conditional \"MAINTAINER_MODE\" was never defined.
++Usually this means the macro was only invoked conditionally." >&5
++echo "$as_me: error: conditional \"MAINTAINER_MODE\" was never defined.
++Usually this means the macro was only invoked conditionally." >&2;}
++ { (exit 1); exit 1; }; }
++fi
++if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then
++ { { echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined.
++Usually this means the macro was only invoked conditionally." >&5
++echo "$as_me: error: conditional \"AMDEP\" was never defined.
++Usually this means the macro was only invoked conditionally." >&2;}
++ { (exit 1); exit 1; }; }
++fi
++if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then
++ { { echo "$as_me:$LINENO: error: conditional \"MAINTAINER_MODE\" was never defined.
++Usually this means the macro was only invoked conditionally." >&5
++echo "$as_me: error: conditional \"MAINTAINER_MODE\" was never defined.
++Usually this means the macro was only invoked conditionally." >&2;}
++ { (exit 1); exit 1; }; }
++fi
++if test -z "${POWERPC_DARWIN_TRUE}" && test -z "${POWERPC_DARWIN_FALSE}"; then
++ { { echo "$as_me:$LINENO: error: conditional \"POWERPC_DARWIN\" was never defined.
++Usually this means the macro was only invoked conditionally." >&5
++echo "$as_me: error: conditional \"POWERPC_DARWIN\" was never defined.
++Usually this means the macro was only invoked conditionally." >&2;}
++ { (exit 1); exit 1; }; }
++fi
++if test -z "${USE_LIBDIR_TRUE}" && test -z "${USE_LIBDIR_FALSE}"; then
++ { { echo "$as_me:$LINENO: error: conditional \"USE_LIBDIR\" was never defined.
++Usually this means the macro was only invoked conditionally." >&5
++echo "$as_me: error: conditional \"USE_LIBDIR\" was never defined.
++Usually this means the macro was only invoked conditionally." >&2;}
++ { (exit 1); exit 1; }; }
++fi
++
++: ${CONFIG_STATUS=./config.status}
++ac_clean_files_save=$ac_clean_files
++ac_clean_files="$ac_clean_files $CONFIG_STATUS"
++{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
++echo "$as_me: creating $CONFIG_STATUS" >&6;}
++cat >$CONFIG_STATUS <<_ACEOF
++#! $SHELL
++# Generated by $as_me.
++# Run this file to recreate the current configuration.
++# Compiler output produced by configure, useful for debugging
++# configure, is in config.log if it exists.
++
++debug=false
++SHELL=\${CONFIG_SHELL-$SHELL}
++_ACEOF
++
++cat >>$CONFIG_STATUS <<\_ACEOF
++## --------------------- ##
++## M4sh Initialization. ##
++## --------------------- ##
++
++# Be Bourne compatible
++if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
++ emulate sh
++ NULLCMD=:
++ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
++ # is contrary to our usage. Disable this feature.
++ alias -g '${1+"$@"}'='"$@"'
++elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
++ set -o posix
++fi
++
++# Support unset when possible.
++if (FOO=FOO; unset FOO) >/dev/null 2>&1; then
++ as_unset=unset
++else
++ as_unset=false
++fi
++
++
++# Work around bugs in pre-3.0 UWIN ksh.
++$as_unset ENV MAIL MAILPATH
++PS1='$ '
++PS2='> '
++PS4='+ '
++
++# NLS nuisances.
++for as_var in LANG LANGUAGE LC_ALL LC_COLLATE LC_CTYPE LC_NUMERIC LC_MESSAGES LC_TIME
++do
++ if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then
++ eval $as_var=C; export $as_var
++ else
++ $as_unset $as_var
++ fi
++done
++
++# Required to use basename.
++if expr a : '\(a\)' >/dev/null 2>&1; then
++ as_expr=expr
++else
++ as_expr=false
++fi
++
++if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
++ as_basename=basename
++else
++ as_basename=false
++fi
++
++
++# Name of the executable.
++as_me=`$as_basename "$0" ||
++$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
++ X"$0" : 'X\(//\)$' \| \
++ X"$0" : 'X\(/\)$' \| \
++ . : '\(.\)' 2>/dev/null ||
++echo X/"$0" |
++ sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
++ /^X\/\(\/\/\)$/{ s//\1/; q; }
++ /^X\/\(\/\).*/{ s//\1/; q; }
++ s/.*/./; q'`
++
++
++# PATH needs CR, and LINENO needs CR and PATH.
++# Avoid depending upon Character Ranges.
++as_cr_letters='abcdefghijklmnopqrstuvwxyz'
++as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
++as_cr_Letters=$as_cr_letters$as_cr_LETTERS
++as_cr_digits='0123456789'
++as_cr_alnum=$as_cr_Letters$as_cr_digits
++
++# The user is always right.
++if test "${PATH_SEPARATOR+set}" != set; then
++ echo "#! /bin/sh" >conftest.sh
++ echo "exit 0" >>conftest.sh
++ chmod +x conftest.sh
++ if (PATH="/nonexistent;."; conftest.sh) >/dev/null 2>&1; then
++ PATH_SEPARATOR=';'
++ else
++ PATH_SEPARATOR=:
++ fi
++ rm -f conftest.sh
++fi
++
++
++ as_lineno_1=$LINENO
++ as_lineno_2=$LINENO
++ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
++ test "x$as_lineno_1" != "x$as_lineno_2" &&
++ test "x$as_lineno_3" = "x$as_lineno_2" || {
++ # Find who we are. Look in the path if we contain no path at all
++ # relative or not.
++ case $0 in
++ *[\\/]* ) as_myself=$0 ;;
++ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++ IFS=$as_save_IFS
++ test -z "$as_dir" && as_dir=.
++ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
++done
++
++ ;;
++ esac
++ # We did not find ourselves, most probably we were run as `sh COMMAND'
++ # in which case we are not to be found in the path.
++ if test "x$as_myself" = x; then
++ as_myself=$0
++ fi
++ if test ! -f "$as_myself"; then
++ { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
++echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
++ { (exit 1); exit 1; }; }
++ fi
++ case $CONFIG_SHELL in
++ '')
++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
++do
++ IFS=$as_save_IFS
++ test -z "$as_dir" && as_dir=.
++ for as_base in sh bash ksh sh5; do
++ case $as_dir in
++ /*)
++ if ("$as_dir/$as_base" -c '
++ as_lineno_1=$LINENO
++ as_lineno_2=$LINENO
++ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
++ test "x$as_lineno_1" != "x$as_lineno_2" &&
++ test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then
++ $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
++ $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
++ CONFIG_SHELL=$as_dir/$as_base
++ export CONFIG_SHELL
++ exec "$CONFIG_SHELL" "$0" ${1+"$@"}
++ fi;;
++ esac
++ done
++done
++;;
++ esac
++
++ # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
++ # uniformly replaced by the line number. The first 'sed' inserts a
++ # line-number line before each line; the second 'sed' does the real
++ # work. The second script uses 'N' to pair each line-number line
++ # with the numbered line, and appends trailing '-' during
++ # substitution so that $LINENO is not a special case at line end.
++ # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
++ # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-)
++ sed '=' <$as_myself |
++ sed '
++ N
++ s,$,-,
++ : loop
++ s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
++ t loop
++ s,-$,,
++ s,^['$as_cr_digits']*\n,,
++ ' >$as_me.lineno &&
++ chmod +x $as_me.lineno ||
++ { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5
++echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;}
++ { (exit 1); exit 1; }; }
++
++ # Don't try to exec as it changes $[0], causing all sort of problems
++ # (the dirname of $[0] is not the place where we might find the
++ # original and so on. Autoconf is especially sensible to this).
++ . ./$as_me.lineno
++ # Exit status is that of the last command.
++ exit
++}
++
++
++case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
++ *c*,-n*) ECHO_N= ECHO_C='
++' ECHO_T=' ' ;;
++ *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;;
++ *) ECHO_N= ECHO_C='\c' ECHO_T= ;;
++esac
++
++if expr a : '\(a\)' >/dev/null 2>&1; then
++ as_expr=expr
++else
++ as_expr=false
++fi
++
++rm -f conf$$ conf$$.exe conf$$.file
++echo >conf$$.file
++if ln -s conf$$.file conf$$ 2>/dev/null; then
++ # We could just check for DJGPP; but this test a) works b) is more generic
++ # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
++ if test -f conf$$.exe; then
++ # Don't use ln at all; we don't have any links
++ as_ln_s='cp -p'
++ else
++ as_ln_s='ln -s'
++ fi
++elif ln conf$$.file conf$$ 2>/dev/null; then
++ as_ln_s=ln
++else
++ as_ln_s='cp -p'
++fi
++rm -f conf$$ conf$$.exe conf$$.file
++
++if mkdir -p . 2>/dev/null; then
++ as_mkdir_p=:
++else
++ as_mkdir_p=false
++fi
++
++as_executable_p="test -f"
++
++# Sed expression to map a string onto a valid CPP name.
++as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g"
++
++# Sed expression to map a string onto a valid variable name.
++as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g"
++
++
++# IFS
++# We need space, tab and new line, in precisely that order.
++as_nl='
++'
++IFS=" $as_nl"
++
++# CDPATH.
++$as_unset CDPATH
++
++exec 6>&1
++
++# Open the log real soon, to keep \$[0] and so on meaningful, and to
++# report actual input values of CONFIG_FILES etc. instead of their
++# values after options handling. Logging --version etc. is OK.
++exec 5>>config.log
++{
++ echo
++ sed 'h;s/./-/g;s/^.../@%:@@%:@ /;s/...$/ @%:@@%:@/;p;x;p;x' <<_ASBOX
++@%:@@%:@ Running $as_me. @%:@@%:@
++_ASBOX
++} >&5
++cat >&5 <<_CSEOF
++
++This file was extended by $as_me, which was
++generated by GNU Autoconf 2.54. Invocation command line was
++
++ CONFIG_FILES = $CONFIG_FILES
++ CONFIG_HEADERS = $CONFIG_HEADERS
++ CONFIG_LINKS = $CONFIG_LINKS
++ CONFIG_COMMANDS = $CONFIG_COMMANDS
++ $ $0 $@
++
++_CSEOF
++echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5
++echo >&5
++_ACEOF
++
++# Files that config.status was made for.
++if test -n "$ac_config_files"; then
++ echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS
++fi
++
++if test -n "$ac_config_headers"; then
++ echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS
++fi
++
++if test -n "$ac_config_links"; then
++ echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS
++fi
++
++if test -n "$ac_config_commands"; then
++ echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS
++fi
++
++cat >>$CONFIG_STATUS <<\_ACEOF
++
++ac_cs_usage="\
++\`$as_me' instantiates files from templates according to the
++current configuration.
++
++Usage: $0 [OPTIONS] [FILE]...
++
++ -h, --help print this help, then exit
++ -V, --version print version number, then exit
++ -d, --debug don't remove temporary files
++ --recheck update $as_me by reconfiguring in the same conditions
++ --file=FILE[:TEMPLATE]
++ instantiate the configuration file FILE
++
++Configuration files:
++$config_files
++
++Configuration commands:
++$config_commands
++
++Report bugs to <bug-autoconf@gnu.org>."
++_ACEOF
++
++cat >>$CONFIG_STATUS <<_ACEOF
++ac_cs_version="\\
++config.status
++configured by $0, generated by GNU Autoconf 2.54,
++ with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
++
++Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001
++Free Software Foundation, Inc.
++This config.status script is free software; the Free Software Foundation
++gives unlimited permission to copy, distribute and modify it."
++srcdir=$srcdir
++INSTALL="$INSTALL"
++_ACEOF
++
++cat >>$CONFIG_STATUS <<\_ACEOF
++# If no file are specified by the user, then we need to provide default
++# value. By we need to know if files were specified by the user.
++ac_need_defaults=:
++while test $# != 0
++do
++ case $1 in
++ --*=*)
++ ac_option=`expr "x$1" : 'x\([^=]*\)='`
++ ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
++ ac_shift=:
++ ;;
++ -*)
++ ac_option=$1
++ ac_optarg=$2
++ ac_shift=shift
++ ;;
++ *) # This is not an option, so the user has probably given explicit
++ # arguments.
++ ac_option=$1
++ ac_need_defaults=false;;
++ esac
++
++ case $ac_option in
++ # Handling of the options.
++_ACEOF
++cat >>$CONFIG_STATUS <<_ACEOF
++ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
++ echo "running $SHELL $0 " $ac_configure_args " --no-create --no-recursion"
++ exec $SHELL $0 $ac_configure_args --no-create --no-recursion ;;
++_ACEOF
++cat >>$CONFIG_STATUS <<\_ACEOF
++ --version | --vers* | -V )
++ echo "$ac_cs_version"; exit 0 ;;
++ --he | --h)
++ # Conflict between --help and --header
++ { { echo "$as_me:$LINENO: error: ambiguous option: $1
++Try \`$0 --help' for more information." >&5
++echo "$as_me: error: ambiguous option: $1
++Try \`$0 --help' for more information." >&2;}
++ { (exit 1); exit 1; }; };;
++ --help | --hel | -h )
++ echo "$ac_cs_usage"; exit 0 ;;
++ --debug | --d* | -d )
++ debug=: ;;
++ --file | --fil | --fi | --f )
++ $ac_shift
++ CONFIG_FILES="$CONFIG_FILES $ac_optarg"
++ ac_need_defaults=false;;
++ --header | --heade | --head | --hea )
++ $ac_shift
++ CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
++ ac_need_defaults=false;;
++
++ # This is an error.
++ -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
++Try \`$0 --help' for more information." >&5
++echo "$as_me: error: unrecognized option: $1
++Try \`$0 --help' for more information." >&2;}
++ { (exit 1); exit 1; }; } ;;
++
++ *) ac_config_targets="$ac_config_targets $1" ;;
++
++ esac
++ shift
++done
++
++_ACEOF
++
++cat >>$CONFIG_STATUS <<_ACEOF
++#
++# INIT-COMMANDS section.
++#
++
++AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"
++srcdir=${srcdir}
++host=${host}
++target=${target}
++with_multisubdir=${with_multisubdir}
++ac_configure_args="${multilib_arg} ${ac_configure_args}"
++CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
++gc_basedir=${gc_basedir}
++CC="${CC}"
++DEFS="$DEFS"
++
++
++_ACEOF
++
++
++
++cat >>$CONFIG_STATUS <<\_ACEOF
++for ac_config_target in $ac_config_targets
++do
++ case "$ac_config_target" in
++ # Handling of arguments.
++ "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
++ "include/Makefile" ) CONFIG_FILES="$CONFIG_FILES include/Makefile" ;;
++ "depfiles" ) CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
++ "default" ) CONFIG_COMMANDS="$CONFIG_COMMANDS default" ;;
++ *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
++echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
++ { (exit 1); exit 1; }; };;
++ esac
++done
++
++# If the user did not use the arguments to specify the items to instantiate,
++# then the envvar interface is used. Set only those that are not.
++# We use the long form for the default assignment because of an extremely
++# bizarre bug on SunOS 4.1.3.
++if $ac_need_defaults; then
++ test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
++ test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
++fi
++
++# Create a temporary directory, and hook for its removal unless debugging.
++$debug ||
++{
++ trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0
++ trap '{ (exit 1); exit 1; }' 1 2 13 15
++}
++
++# Create a (secure) tmp directory for tmp files.
++: ${TMPDIR=/tmp}
++{
++ tmp=`(umask 077 && mktemp -d -q "$TMPDIR/csXXXXXX") 2>/dev/null` &&
++ test -n "$tmp" && test -d "$tmp"
++} ||
++{
++ tmp=$TMPDIR/cs$$-$RANDOM
++ (umask 077 && mkdir $tmp)
++} ||
++{
++ echo "$me: cannot create a temporary directory in $TMPDIR" >&2
++ { (exit 1); exit 1; }
++}
++
++_ACEOF
++
++cat >>$CONFIG_STATUS <<_ACEOF
++
++#
++# CONFIG_FILES section.
++#
++
++# No need to generate the scripts if there are no CONFIG_FILES.
++# This happens for instance when ./config.status config.h
++if test -n "\$CONFIG_FILES"; then
++ # Protect against being on the right side of a sed subst in config.status.
++ sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g;
++ s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF
++s,@SHELL@,$SHELL,;t t
++s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t
++s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t
++s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t
++s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t
++s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t
++s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t
++s,@exec_prefix@,$exec_prefix,;t t
++s,@prefix@,$prefix,;t t
++s,@program_transform_name@,$program_transform_name,;t t
++s,@bindir@,$bindir,;t t
++s,@sbindir@,$sbindir,;t t
++s,@libexecdir@,$libexecdir,;t t
++s,@datadir@,$datadir,;t t
++s,@sysconfdir@,$sysconfdir,;t t
++s,@sharedstatedir@,$sharedstatedir,;t t
++s,@localstatedir@,$localstatedir,;t t
++s,@libdir@,$libdir,;t t
++s,@includedir@,$includedir,;t t
++s,@oldincludedir@,$oldincludedir,;t t
++s,@infodir@,$infodir,;t t
++s,@mandir@,$mandir,;t t
++s,@build_alias@,$build_alias,;t t
++s,@host_alias@,$host_alias,;t t
++s,@target_alias@,$target_alias,;t t
++s,@DEFS@,$DEFS,;t t
++s,@ECHO_C@,$ECHO_C,;t t
++s,@ECHO_N@,$ECHO_N,;t t
++s,@ECHO_T@,$ECHO_T,;t t
++s,@LIBS@,$LIBS,;t t
++s,@gc_basedir@,$gc_basedir,;t t
++s,@build@,$build,;t t
++s,@build_cpu@,$build_cpu,;t t
++s,@build_vendor@,$build_vendor,;t t
++s,@build_os@,$build_os,;t t
++s,@host@,$host,;t t
++s,@host_cpu@,$host_cpu,;t t
++s,@host_vendor@,$host_vendor,;t t
++s,@host_os@,$host_os,;t t
++s,@target@,$target,;t t
++s,@target_cpu@,$target_cpu,;t t
++s,@target_vendor@,$target_vendor,;t t
++s,@target_os@,$target_os,;t t
++s,@mkinstalldirs@,$mkinstalldirs,;t t
++s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t
++s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t
++s,@INSTALL_DATA@,$INSTALL_DATA,;t t
++s,@PACKAGE@,$PACKAGE,;t t
++s,@VERSION@,$VERSION,;t t
++s,@ACLOCAL@,$ACLOCAL,;t t
++s,@AUTOCONF@,$AUTOCONF,;t t
++s,@AUTOMAKE@,$AUTOMAKE,;t t
++s,@AUTOHEADER@,$AUTOHEADER,;t t
++s,@MAKEINFO@,$MAKEINFO,;t t
++s,@AMTAR@,$AMTAR,;t t
++s,@install_sh@,$install_sh,;t t
++s,@STRIP@,$STRIP,;t t
++s,@ac_ct_STRIP@,$ac_ct_STRIP,;t t
++s,@INSTALL_STRIP_PROGRAM@,$INSTALL_STRIP_PROGRAM,;t t
++s,@AWK@,$AWK,;t t
++s,@SET_MAKE@,$SET_MAKE,;t t
++s,@AS@,$AS,;t t
++s,@ac_ct_AS@,$ac_ct_AS,;t t
++s,@AR@,$AR,;t t
++s,@ac_ct_AR@,$ac_ct_AR,;t t
++s,@RANLIB@,$RANLIB,;t t
++s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t
++s,@MAINTAINER_MODE_TRUE@,$MAINTAINER_MODE_TRUE,;t t
++s,@MAINTAINER_MODE_FALSE@,$MAINTAINER_MODE_FALSE,;t t
++s,@MAINT@,$MAINT,;t t
++s,@GC_CFLAGS@,$GC_CFLAGS,;t t
++s,@CC@,$CC,;t t
++s,@CFLAGS@,$CFLAGS,;t t
++s,@LDFLAGS@,$LDFLAGS,;t t
++s,@CPPFLAGS@,$CPPFLAGS,;t t
++s,@ac_ct_CC@,$ac_ct_CC,;t t
++s,@EXEEXT@,$EXEEXT,;t t
++s,@OBJEXT@,$OBJEXT,;t t
++s,@DEPDIR@,$DEPDIR,;t t
++s,@am__include@,$am__include,;t t
++s,@am__quote@,$am__quote,;t t
++s,@AMDEP_TRUE@,$AMDEP_TRUE,;t t
++s,@AMDEP_FALSE@,$AMDEP_FALSE,;t t
++s,@AMDEPBACKSLASH@,$AMDEPBACKSLASH,;t t
++s,@CCDEPMODE@,$CCDEPMODE,;t t
++s,@LN_S@,$LN_S,;t t
++s,@ECHO@,$ECHO,;t t
++s,@CPP@,$CPP,;t t
++s,@EGREP@,$EGREP,;t t
++s,@LIBTOOL@,$LIBTOOL,;t t
++s,@THREADLIBS@,$THREADLIBS,;t t
++s,@POWERPC_DARWIN_TRUE@,$POWERPC_DARWIN_TRUE,;t t
++s,@POWERPC_DARWIN_FALSE@,$POWERPC_DARWIN_FALSE,;t t
++s,@EXTRA_TEST_LIBS@,$EXTRA_TEST_LIBS,;t t
++s,@target_all@,$target_all,;t t
++s,@CXX@,$CXX,;t t
++s,@INCLUDES@,$INCLUDES,;t t
++s,@CXXINCLUDES@,$CXXINCLUDES,;t t
++s,@addobjs@,$addobjs,;t t
++s,@MY_CFLAGS@,$MY_CFLAGS,;t t
++s,@USE_LIBDIR_TRUE@,$USE_LIBDIR_TRUE,;t t
++s,@USE_LIBDIR_FALSE@,$USE_LIBDIR_FALSE,;t t
++s,@LIB@&t@OBJS@,$LIB@&t@OBJS,;t t
++s,@LTLIBOBJS@,$LTLIBOBJS,;t t
++CEOF
++
++_ACEOF
++
++ cat >>$CONFIG_STATUS <<\_ACEOF
++ # Split the substitutions into bite-sized pieces for seds with
++ # small command number limits, like on Digital OSF/1 and HP-UX.
++ ac_max_sed_lines=48
++ ac_sed_frag=1 # Number of current file.
++ ac_beg=1 # First line for current file.
++ ac_end=$ac_max_sed_lines # Line after last line for current file.
++ ac_more_lines=:
++ ac_sed_cmds=
++ while $ac_more_lines; do
++ if test $ac_beg -gt 1; then
++ sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
++ else
++ sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
++ fi
++ if test ! -s $tmp/subs.frag; then
++ ac_more_lines=false
++ else
++ # The purpose of the label and of the branching condition is to
++ # speed up the sed processing (if there are no `@' at all, there
++ # is no need to browse any of the substitutions).
++ # These are the two extra sed commands mentioned above.
++ (echo ':t
++ /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed
++ if test -z "$ac_sed_cmds"; then
++ ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
++ else
++ ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
++ fi
++ ac_sed_frag=`expr $ac_sed_frag + 1`
++ ac_beg=$ac_end
++ ac_end=`expr $ac_end + $ac_max_sed_lines`
++ fi
++ done
++ if test -z "$ac_sed_cmds"; then
++ ac_sed_cmds=cat
++ fi
++fi # test -n "$CONFIG_FILES"
++
++_ACEOF
++cat >>$CONFIG_STATUS <<\_ACEOF
++for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
++ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
++ case $ac_file in
++ - | *:- | *:-:* ) # input from stdin
++ cat >$tmp/stdin
++ ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
++ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
++ *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
++ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
++ * ) ac_file_in=$ac_file.in ;;
++ esac
++
++ # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
++ ac_dir=`(dirname "$ac_file") 2>/dev/null ||
++$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
++ X"$ac_file" : 'X\(//\)[^/]' \| \
++ X"$ac_file" : 'X\(//\)$' \| \
++ X"$ac_file" : 'X\(/\)' \| \
++ . : '\(.\)' 2>/dev/null ||
++echo X"$ac_file" |
++ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
++ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
++ /^X\(\/\/\)$/{ s//\1/; q; }
++ /^X\(\/\).*/{ s//\1/; q; }
++ s/.*/./; q'`
++ { if $as_mkdir_p; then
++ mkdir -p "$ac_dir"
++ else
++ as_dir="$ac_dir"
++ as_dirs=
++ while test ! -d "$as_dir"; do
++ as_dirs="$as_dir $as_dirs"
++ as_dir=`(dirname "$as_dir") 2>/dev/null ||
++$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
++ X"$as_dir" : 'X\(//\)[^/]' \| \
++ X"$as_dir" : 'X\(//\)$' \| \
++ X"$as_dir" : 'X\(/\)' \| \
++ . : '\(.\)' 2>/dev/null ||
++echo X"$as_dir" |
++ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
++ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
++ /^X\(\/\/\)$/{ s//\1/; q; }
++ /^X\(\/\).*/{ s//\1/; q; }
++ s/.*/./; q'`
++ done
++ test ! -n "$as_dirs" || mkdir $as_dirs
++ fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
++echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
++ { (exit 1); exit 1; }; }; }
++
++ ac_builddir=.
++
++if test "$ac_dir" != .; then
++ ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
++ # A "../" for each directory in $ac_dir_suffix.
++ ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
++else
++ ac_dir_suffix= ac_top_builddir=
++fi
++
++case $srcdir in
++ .) # No --srcdir option. We are building in place.
++ ac_srcdir=.
++ if test -z "$ac_top_builddir"; then
++ ac_top_srcdir=.
++ else
++ ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
++ fi ;;
++ [\\/]* | ?:[\\/]* ) # Absolute path.
++ ac_srcdir=$srcdir$ac_dir_suffix;
++ ac_top_srcdir=$srcdir ;;
++ *) # Relative path.
++ ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
++ ac_top_srcdir=$ac_top_builddir$srcdir ;;
++esac
++# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be
++# absolute.
++ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd`
++ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd`
++ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd`
++ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd`
++
++
++ case $INSTALL in
++ [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
++ *) ac_INSTALL=$ac_top_builddir$INSTALL ;;
++ esac
++
++ if test x"$ac_file" != x-; then
++ { echo "$as_me:$LINENO: creating $ac_file" >&5
++echo "$as_me: creating $ac_file" >&6;}
++ rm -f "$ac_file"
++ fi
++ # Let's still pretend it is `configure' which instantiates (i.e., don't
++ # use $as_me), people would be surprised to read:
++ # /* config.h. Generated by config.status. */
++ if test x"$ac_file" = x-; then
++ configure_input=
++ else
++ configure_input="$ac_file. "
++ fi
++ configure_input=$configure_input"Generated from `echo $ac_file_in |
++ sed 's,.*/,,'` by configure."
++
++ # First look for the input files in the build tree, otherwise in the
++ # src tree.
++ ac_file_inputs=`IFS=:
++ for f in $ac_file_in; do
++ case $f in
++ -) echo $tmp/stdin ;;
++ [\\/$]*)
++ # Absolute (can't be DOS-style, as IFS=:)
++ test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
++echo "$as_me: error: cannot find input file: $f" >&2;}
++ { (exit 1); exit 1; }; }
++ echo $f;;
++ *) # Relative
++ if test -f "$f"; then
++ # Build tree
++ echo $f
++ elif test -f "$srcdir/$f"; then
++ # Source tree
++ echo $srcdir/$f
++ else
++ # /dev/null tree
++ { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
++echo "$as_me: error: cannot find input file: $f" >&2;}
++ { (exit 1); exit 1; }; }
++ fi;;
++ esac
++ done` || { (exit 1); exit 1; }
++_ACEOF
++cat >>$CONFIG_STATUS <<_ACEOF
++ sed "$ac_vpsub
++$extrasub
++_ACEOF
++cat >>$CONFIG_STATUS <<\_ACEOF
++:t
++/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
++s,@configure_input@,$configure_input,;t t
++s,@srcdir@,$ac_srcdir,;t t
++s,@abs_srcdir@,$ac_abs_srcdir,;t t
++s,@top_srcdir@,$ac_top_srcdir,;t t
++s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t
++s,@builddir@,$ac_builddir,;t t
++s,@abs_builddir@,$ac_abs_builddir,;t t
++s,@top_builddir@,$ac_top_builddir,;t t
++s,@abs_top_builddir@,$ac_abs_top_builddir,;t t
++s,@INSTALL@,$ac_INSTALL,;t t
++" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out
++ rm -f $tmp/stdin
++ if test x"$ac_file" != x-; then
++ mv $tmp/out $ac_file
++ else
++ cat $tmp/out
++ rm -f $tmp/out
++ fi
++
++done
++_ACEOF
++cat >>$CONFIG_STATUS <<\_ACEOF
++
++#
++# CONFIG_COMMANDS section.
++#
++for ac_file in : $CONFIG_COMMANDS; do test "x$ac_file" = x: && continue
++ ac_dest=`echo "$ac_file" | sed 's,:.*,,'`
++ ac_source=`echo "$ac_file" | sed 's,[^:]*:,,'`
++ ac_dir=`(dirname "$ac_dest") 2>/dev/null ||
++$as_expr X"$ac_dest" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
++ X"$ac_dest" : 'X\(//\)[^/]' \| \
++ X"$ac_dest" : 'X\(//\)$' \| \
++ X"$ac_dest" : 'X\(/\)' \| \
++ . : '\(.\)' 2>/dev/null ||
++echo X"$ac_dest" |
++ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
++ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
++ /^X\(\/\/\)$/{ s//\1/; q; }
++ /^X\(\/\).*/{ s//\1/; q; }
++ s/.*/./; q'`
++ ac_builddir=.
++
++if test "$ac_dir" != .; then
++ ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
++ # A "../" for each directory in $ac_dir_suffix.
++ ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
++else
++ ac_dir_suffix= ac_top_builddir=
++fi
++
++case $srcdir in
++ .) # No --srcdir option. We are building in place.
++ ac_srcdir=.
++ if test -z "$ac_top_builddir"; then
++ ac_top_srcdir=.
++ else
++ ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
++ fi ;;
++ [\\/]* | ?:[\\/]* ) # Absolute path.
++ ac_srcdir=$srcdir$ac_dir_suffix;
++ ac_top_srcdir=$srcdir ;;
++ *) # Relative path.
++ ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
++ ac_top_srcdir=$ac_top_builddir$srcdir ;;
++esac
++# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be
++# absolute.
++ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd`
++ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd`
++ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd`
++ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd`
++
++
++ { echo "$as_me:$LINENO: executing $ac_dest commands" >&5
++echo "$as_me: executing $ac_dest commands" >&6;}
++ case $ac_dest in
++ depfiles ) test x"$AMDEP_TRUE" != x"" || for mf in $CONFIG_FILES; do
++ # Strip MF so we end up with the name of the file.
++ mf=`echo "$mf" | sed -e 's/:.*$//'`
++ if (sed 1q $mf | fgrep 'generated by automake') > /dev/null 2>&1; then
++ dirpart=`(dirname "$mf") 2>/dev/null ||
++$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
++ X"$mf" : 'X\(//\)[^/]' \| \
++ X"$mf" : 'X\(//\)$' \| \
++ X"$mf" : 'X\(/\)' \| \
++ . : '\(.\)' 2>/dev/null ||
++echo X"$mf" |
++ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
++ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
++ /^X\(\/\/\)$/{ s//\1/; q; }
++ /^X\(\/\).*/{ s//\1/; q; }
++ s/.*/./; q'`
++ else
++ continue
++ fi
++ grep '^DEP_FILES *= *[^ @%:@]' < "$mf" > /dev/null || continue
++ # Extract the definition of DEP_FILES from the Makefile without
++ # running `make'.
++ DEPDIR=`sed -n -e '/^DEPDIR = / s///p' < "$mf"`
++ test -z "$DEPDIR" && continue
++ # When using ansi2knr, U may be empty or an underscore; expand it
++ U=`sed -n -e '/^U = / s///p' < "$mf"`
++ test -d "$dirpart/$DEPDIR" || mkdir "$dirpart/$DEPDIR"
++ # We invoke sed twice because it is the simplest approach to
++ # changing $(DEPDIR) to its actual value in the expansion.
++ for file in `sed -n -e '
++ /^DEP_FILES = .*\\\\$/ {
++ s/^DEP_FILES = //
++ :loop
++ s/\\\\$//
++ p
++ n
++ /\\\\$/ b loop
++ p
++ }
++ /^DEP_FILES = / s/^DEP_FILES = //p' < "$mf" | \
++ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
++ # Make sure the directory exists.
++ test -f "$dirpart/$file" && continue
++ fdir=`(dirname "$file") 2>/dev/null ||
++$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
++ X"$file" : 'X\(//\)[^/]' \| \
++ X"$file" : 'X\(//\)$' \| \
++ X"$file" : 'X\(/\)' \| \
++ . : '\(.\)' 2>/dev/null ||
++echo X"$file" |
++ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
++ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
++ /^X\(\/\/\)$/{ s//\1/; q; }
++ /^X\(\/\).*/{ s//\1/; q; }
++ s/.*/./; q'`
++ { if $as_mkdir_p; then
++ mkdir -p $dirpart/$fdir
++ else
++ as_dir=$dirpart/$fdir
++ as_dirs=
++ while test ! -d "$as_dir"; do
++ as_dirs="$as_dir $as_dirs"
++ as_dir=`(dirname "$as_dir") 2>/dev/null ||
++$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
++ X"$as_dir" : 'X\(//\)[^/]' \| \
++ X"$as_dir" : 'X\(//\)$' \| \
++ X"$as_dir" : 'X\(/\)' \| \
++ . : '\(.\)' 2>/dev/null ||
++echo X"$as_dir" |
++ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
++ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
++ /^X\(\/\/\)$/{ s//\1/; q; }
++ /^X\(\/\).*/{ s//\1/; q; }
++ s/.*/./; q'`
++ done
++ test ! -n "$as_dirs" || mkdir $as_dirs
++ fi || { { echo "$as_me:$LINENO: error: cannot create directory $dirpart/$fdir" >&5
++echo "$as_me: error: cannot create directory $dirpart/$fdir" >&2;}
++ { (exit 1); exit 1; }; }; }
++
++ # echo "creating $dirpart/$file"
++ echo '# dummy' > "$dirpart/$file"
++ done
++done
++ ;;
++ default )
++echo "$DEFS" > boehm-cflags
++
++if test -n "$CONFIG_FILES"; then
++ LD="${ORIGINAL_LD_FOR_MULTILIBS}"
++ ac_file=Makefile . ${gc_basedir}/../config-ml.in
++fi ;;
++ esac
++done
++_ACEOF
++
++cat >>$CONFIG_STATUS <<\_ACEOF
++
++{ (exit 0); exit 0; }
++_ACEOF
++chmod +x $CONFIG_STATUS
++ac_clean_files=$ac_clean_files_save
++
++
++# configure is writing to config.log, and then calls config.status.
++# config.status does its own redirection, appending to config.log.
++# Unfortunately, on DOS this fails, as config.log is still kept open
++# by configure, so config.status won't be able to write to it; its
++# output is simply discarded. So we exec the FD to /dev/null,
++# effectively closing config.log, so it can be properly (re)opened and
++# appended to by config.status. When coming back to configure, we
++# need to make the FD available again.
++if test "$no_create" != yes; then
++ ac_cs_success=:
++ exec 5>/dev/null
++ $SHELL $CONFIG_STATUS || ac_cs_success=false
++ exec 5>>config.log
++ # Use ||, not &&, to avoid exiting from the if with $? = 1, which
++ # would make configure fail if this is the last instruction.
++ $ac_cs_success || { (exit 1); exit 1; }
++fi
++
+diff -buNr boehm-gc/autom4te.cache/requests boehm-gc/autom4te.cache/requests
+--- boehm-gc/autom4te.cache/requests Wed Dec 31 16:00:00 1969
++++ boehm-gc/autom4te.cache/requests Sat Sep 13 02:10:15 2003
+@@ -0,0 +1,198 @@
++# This file was created by autom4te-2.54.
++# It contains the lists of macros which have been traced.
++# It can be safely removed.
++
++@request = (
++ bless( [
++ '0',
++ 0,
++ [
++ '/sw/share/autoconf'
++ ],
++ [
++ '/sw/share/autoconf/autoconf/autoconf.m4f',
++ 'aclocal.m4',
++ 'configure.in'
++ ],
++ {
++ 'm4_pattern_forbid' => 1,
++ 'AC_C_VOLATILE' => 1,
++ 'AC_TYPE_OFF_T' => 1,
++ 'AC_FUNC_CLOSEDIR_VOID' => 1,
++ 'AC_REPLACE_FNMATCH' => 1,
++ 'AC_PROG_LIBTOOL' => 1,
++ 'AC_FUNC_STAT' => 1,
++ 'AC_FUNC_WAIT3' => 1,
++ 'AC_HEADER_TIME' => 1,
++ 'AC_FUNC_LSTAT' => 1,
++ 'AC_STRUCT_TM' => 1,
++ 'AM_AUTOMAKE_VERSION' => 1,
++ 'AC_FUNC_GETMNTENT' => 1,
++ 'AC_TYPE_MODE_T' => 1,
++ 'AC_FUNC_STRTOD' => 1,
++ 'AC_CHECK_HEADERS' => 1,
++ 'AC_FUNC_STRNLEN' => 1,
++ 'AC_PROG_CXX' => 1,
++ 'AC_PATH_X' => 1,
++ 'AC_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK' => 1,
++ 'AC_PROG_AWK' => 1,
++ 'AC_HEADER_STDC' => 1,
++ 'AC_HEADER_MAJOR' => 1,
++ 'AC_FUNC_ERROR_AT_LINE' => 1,
++ 'AC_PROG_GCC_TRADITIONAL' => 1,
++ 'AC_LIBSOURCE' => 1,
++ 'AC_FUNC_MBRTOWC' => 1,
++ 'AC_STRUCT_ST_BLOCKS' => 1,
++ 'AC_TYPE_SIGNAL' => 1,
++ 'AC_TYPE_UID_T' => 1,
++ 'AC_CONFIG_AUX_DIR' => 1,
++ 'AC_PROG_MAKE_SET' => 1,
++ 'm4_pattern_allow' => 1,
++ 'AC_DEFINE_TRACE_LITERAL' => 1,
++ 'AC_FUNC_STRERROR_R' => 1,
++ 'AC_PROG_CC' => 1,
++ 'AC_FUNC_FORK' => 1,
++ 'AC_DECL_SYS_SIGLIST' => 1,
++ 'AC_FUNC_STRCOLL' => 1,
++ 'AC_FUNC_VPRINTF' => 1,
++ 'AC_PROG_YACC' => 1,
++ 'AC_INIT' => 1,
++ 'AC_STRUCT_TIMEZONE' => 1,
++ 'AC_FUNC_CHOWN' => 1,
++ 'AC_SUBST' => 1,
++ 'AC_FUNC_ALLOCA' => 1,
++ 'AC_CANONICAL_HOST' => 1,
++ 'AC_FUNC_GETPGRP' => 1,
++ 'AC_PROG_RANLIB' => 1,
++ 'AM_INIT_AUTOMAKE' => 1,
++ 'AC_FUNC_SETPGRP' => 1,
++ 'AC_CONFIG_SUBDIRS' => 1,
++ 'AC_FUNC_MMAP' => 1,
++ 'AC_FUNC_REALLOC' => 1,
++ 'AC_TYPE_SIZE_T' => 1,
++ 'AC_CHECK_TYPES' => 1,
++ 'AC_CHECK_MEMBERS' => 1,
++ 'AM_MAINTAINER_MODE' => 1,
++ 'AC_FUNC_UTIME_NULL' => 1,
++ 'AC_FUNC_SELECT_ARGTYPES' => 1,
++ 'AC_FUNC_STRFTIME' => 1,
++ 'AC_HEADER_STAT' => 1,
++ 'AC_C_INLINE' => 1,
++ 'AC_PROG_CPP' => 1,
++ 'AC_TYPE_PID_T' => 1,
++ 'AC_PROG_LEX' => 1,
++ 'AC_C_CONST' => 1,
++ 'AC_CONFIG_FILES' => 1,
++ 'include' => 1,
++ 'AC_FUNC_SETVBUF_REVERSED' => 1,
++ 'AC_PROG_INSTALL' => 1,
++ 'AM_GNU_GETTEXT' => 1,
++ 'AC_CHECK_LIB' => 1,
++ 'AC_FUNC_OBSTACK' => 1,
++ 'AC_FUNC_MALLOC' => 1,
++ 'AC_FUNC_GETGROUPS' => 1,
++ 'AC_FUNC_GETLOADAVG' => 1,
++ 'AH_OUTPUT' => 1,
++ 'AC_FUNC_FSEEKO' => 1,
++ 'AM_PROG_CC_C_O' => 1,
++ 'AC_FUNC_MKTIME' => 1,
++ 'AC_CANONICAL_SYSTEM' => 1,
++ 'AM_CONDITIONAL' => 1,
++ 'AC_CONFIG_HEADERS' => 1,
++ 'AC_HEADER_SYS_WAIT' => 1,
++ 'AC_PROG_LN_S' => 1,
++ 'AC_FUNC_MEMCMP' => 1,
++ 'm4_include' => 1,
++ 'AC_HEADER_DIRENT' => 1,
++ 'AC_CHECK_FUNCS' => 1
++ }
++ ], 'Request' ),
++ bless( [
++ '1',
++ 1,
++ [
++ '/sw/share/autoconf-2.54'
++ ],
++ [
++ '--reload-state=/sw/share/autoconf-2.54/autoconf/autoconf.m4f',
++ 'aclocal.m4',
++ 'configure.in'
++ ],
++ {
++ 'm4_pattern_forbid' => 1,
++ 'AC_TYPE_OFF_T' => 1,
++ 'AC_PROG_LIBTOOL' => 1,
++ 'AC_FUNC_STAT' => 1,
++ 'AC_HEADER_TIME' => 1,
++ 'AC_FUNC_WAIT3' => 1,
++ 'AC_STRUCT_TM' => 1,
++ 'AC_FUNC_LSTAT' => 1,
++ 'AC_TYPE_MODE_T' => 1,
++ 'AC_FUNC_STRTOD' => 1,
++ 'AC_CHECK_HEADERS' => 1,
++ 'AC_PROG_CXX' => 1,
++ 'AC_PATH_X' => 1,
++ 'AC_PROG_AWK' => 1,
++ 'AC_HEADER_STDC' => 1,
++ 'AC_HEADER_MAJOR' => 1,
++ 'AC_FUNC_ERROR_AT_LINE' => 1,
++ 'AC_PROG_GCC_TRADITIONAL' => 1,
++ 'AC_LIBSOURCE' => 1,
++ 'AC_STRUCT_ST_BLOCKS' => 1,
++ 'AC_TYPE_SIGNAL' => 1,
++ 'AC_TYPE_UID_T' => 1,
++ 'AC_PROG_MAKE_SET' => 1,
++ 'm4_pattern_allow' => 1,
++ 'AC_DEFINE_TRACE_LITERAL' => 1,
++ 'AM_PROG_LIBTOOL' => 1,
++ 'AC_FUNC_STRERROR_R' => 1,
++ 'AC_PROG_CC' => 1,
++ 'AC_FUNC_FORK' => 1,
++ 'AC_DECL_SYS_SIGLIST' => 1,
++ 'AC_FUNC_STRCOLL' => 1,
++ 'AC_FUNC_VPRINTF' => 1,
++ 'AC_PROG_YACC' => 1,
++ 'AC_STRUCT_TIMEZONE' => 1,
++ 'AC_FUNC_CHOWN' => 1,
++ 'AC_SUBST' => 1,
++ 'AC_FUNC_ALLOCA' => 1,
++ 'AC_FUNC_GETPGRP' => 1,
++ 'AC_PROG_RANLIB' => 1,
++ 'AC_FUNC_SETPGRP' => 1,
++ 'AC_FUNC_MMAP' => 1,
++ 'AC_TYPE_SIZE_T' => 1,
++ 'AC_CHECK_TYPES' => 1,
++ 'AC_FUNC_UTIME_NULL' => 1,
++ 'AC_FUNC_STRFTIME' => 1,
++ 'AC_HEADER_STAT' => 1,
++ 'AC_C_INLINE' => 1,
++ 'AC_PROG_CPP' => 1,
++ 'AC_C_CONST' => 1,
++ 'AC_PROG_LEX' => 1,
++ 'AC_TYPE_PID_T' => 1,
++ 'AC_CONFIG_FILES' => 1,
++ 'include' => 1,
++ 'AC_FUNC_SETVBUF_REVERSED' => 1,
++ 'AC_FUNC_FNMATCH' => 1,
++ 'AC_PROG_INSTALL' => 1,
++ 'AM_GNU_GETTEXT' => 1,
++ 'AC_FUNC_OBSTACK' => 1,
++ 'AC_CHECK_LIB' => 1,
++ 'AC_FUNC_MALLOC' => 1,
++ 'AC_FUNC_GETGROUPS' => 1,
++ 'AC_FUNC_GETLOADAVG' => 1,
++ 'AH_OUTPUT' => 1,
++ 'AC_FUNC_FSEEKO' => 1,
++ 'AC_FUNC_MKTIME' => 1,
++ 'AM_CONDITIONAL' => 1,
++ 'AC_CONFIG_HEADERS' => 1,
++ 'AC_HEADER_SYS_WAIT' => 1,
++ 'AC_PROG_LN_S' => 1,
++ 'AC_FUNC_MEMCMP' => 1,
++ 'm4_include' => 1,
++ 'AC_HEADER_DIRENT' => 1,
++ 'AC_CHECK_FUNCS' => 1
++ }
++ ], 'Request' )
++ );
++
+diff -buNr boehm-gc/autom4te.cache/traces.0 boehm-gc/autom4te.cache/traces.0
+--- boehm-gc/autom4te.cache/traces.0 Wed Dec 31 16:00:00 1969
++++ boehm-gc/autom4te.cache/traces.0 Sat Sep 13 02:10:15 2003
+@@ -0,0 +1,185 @@
++m4trace:configure.in:16: -1- AC_INIT([gcj_mlc.c])
++m4trace:configure.in:16: -1- m4_pattern_forbid([^_?A[CHUM]_])
++m4trace:configure.in:16: -1- m4_pattern_forbid([_AC_])
++m4trace:configure.in:16: -1- m4_pattern_forbid([^LIBOBJS$], [do not use LIBOBJS directly, use AC_LIBOBJ (see section `AC_LIBOBJ vs LIBOBJS'])
++m4trace:configure.in:16: -1- m4_pattern_allow([^AS_FLAGS$])
++m4trace:configure.in:16: -1- m4_pattern_forbid([^_?m4_])
++m4trace:configure.in:16: -1- m4_pattern_forbid([^dnl$])
++m4trace:configure.in:16: -1- m4_pattern_forbid([^_?AS_])
++m4trace:configure.in:16: -1- AC_SUBST([SHELL], [${CONFIG_SHELL-/bin/sh}])
++m4trace:configure.in:16: -1- AC_SUBST([PATH_SEPARATOR])
++m4trace:configure.in:16: -1- AC_SUBST([PACKAGE_NAME], [m4_ifdef([AC_PACKAGE_NAME], ['AC_PACKAGE_NAME'])])
++m4trace:configure.in:16: -1- AC_SUBST([PACKAGE_TARNAME], [m4_ifdef([AC_PACKAGE_TARNAME], ['AC_PACKAGE_TARNAME'])])
++m4trace:configure.in:16: -1- AC_SUBST([PACKAGE_VERSION], [m4_ifdef([AC_PACKAGE_VERSION], ['AC_PACKAGE_VERSION'])])
++m4trace:configure.in:16: -1- AC_SUBST([PACKAGE_STRING], [m4_ifdef([AC_PACKAGE_STRING], ['AC_PACKAGE_STRING'])])
++m4trace:configure.in:16: -1- AC_SUBST([PACKAGE_BUGREPORT], [m4_ifdef([AC_PACKAGE_BUGREPORT], ['AC_PACKAGE_BUGREPORT'])])
++m4trace:configure.in:16: -1- AC_SUBST([exec_prefix], [NONE])
++m4trace:configure.in:16: -1- AC_SUBST([prefix], [NONE])
++m4trace:configure.in:16: -1- AC_SUBST([program_transform_name], [s,x,x,])
++m4trace:configure.in:16: -1- AC_SUBST([bindir], ['${exec_prefix}/bin'])
++m4trace:configure.in:16: -1- AC_SUBST([sbindir], ['${exec_prefix}/sbin'])
++m4trace:configure.in:16: -1- AC_SUBST([libexecdir], ['${exec_prefix}/libexec'])
++m4trace:configure.in:16: -1- AC_SUBST([datadir], ['${prefix}/share'])
++m4trace:configure.in:16: -1- AC_SUBST([sysconfdir], ['${prefix}/etc'])
++m4trace:configure.in:16: -1- AC_SUBST([sharedstatedir], ['${prefix}/com'])
++m4trace:configure.in:16: -1- AC_SUBST([localstatedir], ['${prefix}/var'])
++m4trace:configure.in:16: -1- AC_SUBST([libdir], ['${exec_prefix}/lib'])
++m4trace:configure.in:16: -1- AC_SUBST([includedir], ['${prefix}/include'])
++m4trace:configure.in:16: -1- AC_SUBST([oldincludedir], ['/usr/include'])
++m4trace:configure.in:16: -1- AC_SUBST([infodir], ['${prefix}/info'])
++m4trace:configure.in:16: -1- AC_SUBST([mandir], ['${prefix}/man'])
++m4trace:configure.in:16: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_NAME])
++m4trace:configure.in:16: -1- AH_OUTPUT([PACKAGE_NAME], [/* Define to the full name of this package. */
++#undef PACKAGE_NAME])
++m4trace:configure.in:16: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_TARNAME])
++m4trace:configure.in:16: -1- AH_OUTPUT([PACKAGE_TARNAME], [/* Define to the one symbol short name of this package. */
++#undef PACKAGE_TARNAME])
++m4trace:configure.in:16: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_VERSION])
++m4trace:configure.in:16: -1- AH_OUTPUT([PACKAGE_VERSION], [/* Define to the version of this package. */
++#undef PACKAGE_VERSION])
++m4trace:configure.in:16: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_STRING])
++m4trace:configure.in:16: -1- AH_OUTPUT([PACKAGE_STRING], [/* Define to the full name and version of this package. */
++#undef PACKAGE_STRING])
++m4trace:configure.in:16: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_BUGREPORT])
++m4trace:configure.in:16: -1- AH_OUTPUT([PACKAGE_BUGREPORT], [/* Define to the address where bug reports for this package should be sent. */
++#undef PACKAGE_BUGREPORT])
++m4trace:configure.in:16: -1- AC_SUBST([build_alias])
++m4trace:configure.in:16: -1- AC_SUBST([host_alias])
++m4trace:configure.in:16: -1- AC_SUBST([target_alias])
++m4trace:configure.in:16: -1- AC_SUBST([DEFS])
++m4trace:configure.in:16: -1- AC_SUBST([ECHO_C])
++m4trace:configure.in:16: -1- AC_SUBST([ECHO_N])
++m4trace:configure.in:16: -1- AC_SUBST([ECHO_T])
++m4trace:configure.in:16: -1- AC_SUBST([LIBS])
++m4trace:configure.in:25: -1- AC_CONFIG_AUX_DIR([.])
++m4trace:configure.in:27: -1- AC_SUBST([gc_basedir])
++m4trace:configure.in:27: -1- AC_CONFIG_AUX_DIR([$gc_basedir/..])
++m4trace:configure.in:27: -1- AC_CONFIG_AUX_DIR([..])
++m4trace:configure.in:27: -1- AC_CANONICAL_SYSTEM
++m4trace:configure.in:27: -1- AC_CANONICAL_HOST
++m4trace:configure.in:27: -1- AC_SUBST([build], [$ac_cv_build])
++m4trace:configure.in:27: -1- AC_SUBST([build_cpu], [`echo $ac_cv_build | sed 's/^\([[^-]]*\)-\([[^-]]*\)-\(.*\)$/\1/'`])
++m4trace:configure.in:27: -1- AC_SUBST([build_vendor], [`echo $ac_cv_build | sed 's/^\([[^-]]*\)-\([[^-]]*\)-\(.*\)$/\2/'`])
++m4trace:configure.in:27: -1- AC_SUBST([build_os], [`echo $ac_cv_build | sed 's/^\([[^-]]*\)-\([[^-]]*\)-\(.*\)$/\3/'`])
++m4trace:configure.in:27: -1- AC_SUBST([host], [$ac_cv_host])
++m4trace:configure.in:27: -1- AC_SUBST([host_cpu], [`echo $ac_cv_host | sed 's/^\([[^-]]*\)-\([[^-]]*\)-\(.*\)$/\1/'`])
++m4trace:configure.in:27: -1- AC_SUBST([host_vendor], [`echo $ac_cv_host | sed 's/^\([[^-]]*\)-\([[^-]]*\)-\(.*\)$/\2/'`])
++m4trace:configure.in:27: -1- AC_SUBST([host_os], [`echo $ac_cv_host | sed 's/^\([[^-]]*\)-\([[^-]]*\)-\(.*\)$/\3/'`])
++m4trace:configure.in:27: -1- AC_SUBST([target], [$ac_cv_target])
++m4trace:configure.in:27: -1- AC_SUBST([target_cpu], [`echo $ac_cv_target | sed 's/^\([[^-]]*\)-\([[^-]]*\)-\(.*\)$/\1/'`])
++m4trace:configure.in:27: -1- AC_SUBST([target_vendor], [`echo $ac_cv_target | sed 's/^\([[^-]]*\)-\([[^-]]*\)-\(.*\)$/\2/'`])
++m4trace:configure.in:27: -1- AC_SUBST([target_os], [`echo $ac_cv_target | sed 's/^\([[^-]]*\)-\([[^-]]*\)-\(.*\)$/\3/'`])
++m4trace:configure.in:27: -1- AC_SUBST([mkinstalldirs])
++m4trace:configure.in:27: -1- AM_INIT_AUTOMAKE([gc], [6.0], [no-define])
++m4trace:configure.in:27: -1- AC_PROG_INSTALL
++m4trace:configure.in:27: -1- AC_SUBST([INSTALL_PROGRAM])
++m4trace:configure.in:27: -1- AC_SUBST([INSTALL_SCRIPT])
++m4trace:configure.in:27: -1- AC_SUBST([INSTALL_DATA])
++m4trace:configure.in:27: -1- AC_SUBST([PACKAGE])
++m4trace:configure.in:27: -1- AC_SUBST([VERSION])
++m4trace:configure.in:27: -2- AC_DEFINE_TRACE_LITERAL([PACKAGE])
++m4trace:configure.in:27: -2- AH_OUTPUT([PACKAGE], [/* Name of package */
++#undef PACKAGE])
++m4trace:configure.in:27: -2- AC_DEFINE_TRACE_LITERAL([VERSION])
++m4trace:configure.in:27: -2- AH_OUTPUT([VERSION], [/* Version number of package */
++#undef VERSION])
++m4trace:configure.in:27: -1- AC_SUBST([ACLOCAL])
++m4trace:configure.in:27: -1- AC_SUBST([AUTOCONF])
++m4trace:configure.in:27: -1- AC_SUBST([AUTOMAKE])
++m4trace:configure.in:27: -1- AC_SUBST([AUTOHEADER])
++m4trace:configure.in:27: -1- AC_SUBST([MAKEINFO])
++m4trace:configure.in:27: -1- AC_PROG_MAKE_SET
++m4trace:configure.in:27: -1- AC_SUBST([SET_MAKE])
++m4trace:configure.in:27: -1- AC_SUBST([CC])
++m4trace:configure.in:27: -1- AC_SUBST([CC])
++m4trace:configure.in:27: -1- AC_SUBST([CXX])
++m4trace:configure.in:27: -1- AC_SUBST([AS])
++m4trace:configure.in:27: -1- AC_SUBST([ac_ct_AS])
++m4trace:configure.in:27: -1- AC_SUBST([AR])
++m4trace:configure.in:27: -1- AC_SUBST([ac_ct_AR])
++m4trace:configure.in:27: -1- AC_SUBST([RANLIB])
++m4trace:configure.in:27: -1- AC_SUBST([ac_ct_RANLIB])
++m4trace:configure.in:27: -1- AC_PROG_INSTALL
++m4trace:configure.in:27: -1- AC_SUBST([INSTALL_PROGRAM])
++m4trace:configure.in:27: -1- AC_SUBST([INSTALL_SCRIPT])
++m4trace:configure.in:27: -1- AC_SUBST([INSTALL_DATA])
++m4trace:configure.in:27: -1- AM_MAINTAINER_MODE
++m4trace:configure.in:27: -1- AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes])
++m4trace:configure.in:27: -1- AC_SUBST([MAINTAINER_MODE_TRUE])
++m4trace:configure.in:27: -1- AC_SUBST([MAINTAINER_MODE_FALSE])
++m4trace:configure.in:27: -1- AC_SUBST([MAINT])
++m4trace:configure.in:27: -1- AC_SUBST([GC_CFLAGS])
++m4trace:configure.in:29: -1- AC_PROG_LIBTOOL
++m4trace:configure.in:29: -1- AC_PROG_LN_S
++m4trace:configure.in:29: -1- AC_SUBST([LN_S], [$as_ln_s])
++m4trace:configure.in:29: -1- AC_SUBST([RANLIB])
++m4trace:configure.in:29: -1- AC_SUBST([ac_ct_RANLIB])
++m4trace:configure.in:29: -1- AC_SUBST([STRIP])
++m4trace:configure.in:29: -1- AC_SUBST([ac_ct_STRIP])
++m4trace:configure.in:29: -1- AC_SUBST([LIBTOOL])
++m4trace:configure.in:29: -1- AC_SUBST([CXXCPP])
++m4trace:configure.in:29: -1- AC_SUBST([CPPFLAGS])
++m4trace:configure.in:29: -1- AC_SUBST([CXXCPP])
++m4trace:configure.in:38: -1- AM_MAINTAINER_MODE
++m4trace:configure.in:38: -1- AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes])
++m4trace:configure.in:38: -1- AC_SUBST([MAINTAINER_MODE_TRUE])
++m4trace:configure.in:38: -1- AC_SUBST([MAINTAINER_MODE_FALSE])
++m4trace:configure.in:38: -1- AC_SUBST([MAINT])
++m4trace:configure.in:77: -1- AC_DEFINE_TRACE_LITERAL([GC_LINUX_THREADS])
++m4trace:configure.in:78: -1- AC_DEFINE_TRACE_LITERAL([_REENTRANT])
++m4trace:configure.in:80: -1- AC_DEFINE_TRACE_LITERAL([PARALLEL_MARK])
++m4trace:configure.in:82: -1- AC_DEFINE_TRACE_LITERAL([THREAD_LOCAL_ALLOC])
++m4trace:configure.in:85: -1- AC_DEFINE_TRACE_LITERAL([GC_LINUX_THREADS])
++m4trace:configure.in:86: -1- AC_DEFINE_TRACE_LITERAL([_REENTRANT])
++m4trace:configure.in:90: -1- AC_DEFINE_TRACE_LITERAL([GC_HPUX_THREADS])
++m4trace:configure.in:91: -1- AC_DEFINE_TRACE_LITERAL([_POSIX_C_SOURCE])
++m4trace:configure.in:93: -1- AC_DEFINE_TRACE_LITERAL([PARALLEL_MARK])
++m4trace:configure.in:95: -1- AC_DEFINE_TRACE_LITERAL([THREAD_LOCAL_ALLOC])
++m4trace:configure.in:100: -1- AC_DEFINE_TRACE_LITERAL([GC_FREEBSD_THREADS])
++m4trace:configure.in:105: -1- AC_DEFINE_TRACE_LITERAL([GC_SOLARIS_THREADS])
++m4trace:configure.in:106: -1- AC_DEFINE_TRACE_LITERAL([GC_SOLARIS_PTHREADS])
++m4trace:configure.in:109: -1- AC_DEFINE_TRACE_LITERAL([GC_IRIX_THREADS])
++m4trace:configure.in:117: -1- AC_DEFINE_TRACE_LITERAL([GC_DARWIN_THREADS])
++m4trace:configure.in:118: -1- AC_DEFINE_TRACE_LITERAL([THREAD_LOCAL_ALLOC])
++m4trace:configure.in:120: -1- AC_DEFINE_TRACE_LITERAL([PARALLEL_MARK])
++m4trace:configure.in:124: -1- AC_DEFINE_TRACE_LITERAL([GC_WIN32_THREADS])
++m4trace:configure.in:125: -1- AC_DEFINE_TRACE_LITERAL([NO_GETENV])
++m4trace:configure.in:134: -1- AC_SUBST([THREADLIBS])
++m4trace:configure.in:141: -1- AM_CONDITIONAL([POWERPC_DARWIN], [test x$powerpc_darwin = xtrue])
++m4trace:configure.in:141: -1- AC_SUBST([POWERPC_DARWIN_TRUE])
++m4trace:configure.in:141: -1- AC_SUBST([POWERPC_DARWIN_FALSE])
++m4trace:configure.in:148: -1- AC_CHECK_LIB([dl], [dlopen], [EXTRA_TEST_LIBS="$EXTRA_TEST_LIBS -ldl"])
++m4trace:configure.in:152: -1- AC_SUBST([EXTRA_TEST_LIBS])
++m4trace:configure.in:155: -1- AC_SUBST([target_all])
++m4trace:configure.in:156: -1- AC_SUBST([target_alias])
++m4trace:configure.in:174: -1- AC_DEFINE_TRACE_LITERAL([ECOS])
++m4trace:configure.in:179: -1- AC_SUBST([CXX])
++m4trace:configure.in:181: -1- AC_SUBST([INCLUDES])
++m4trace:configure.in:182: -1- AC_SUBST([CXXINCLUDES])
++m4trace:configure.in:197: -1- AC_DEFINE_TRACE_LITERAL([SOLARIS25_PROC_VDB_BUG_FIXED])
++m4trace:configure.in:201: -1- AC_DEFINE_TRACE_LITERAL([STACKBASE])
++m4trace:configure.in:202: -1- AC_DEFINE_TRACE_LITERAL([DATASTART_IS_ETEXT])
++m4trace:configure.in:211: -1- AC_DEFINE_TRACE_LITERAL([NO_EXECUTE_PERMISSION])
++m4trace:configure.in:215: -1- AC_DEFINE_TRACE_LITERAL([SUNOS53_SHARED_LIB])
++m4trace:configure.in:228: -1- AC_SUBST([addobjs])
++m4trace:configure.in:252: -1- AC_SUBST([MY_CFLAGS])
++m4trace:configure.in:256: -1- AC_DEFINE_TRACE_LITERAL([SILENT])
++m4trace:configure.in:257: -1- AC_DEFINE_TRACE_LITERAL([NO_SIGNALS])
++m4trace:configure.in:258: -1- AC_DEFINE_TRACE_LITERAL([NO_EXECUTE_PERMISSION])
++m4trace:configure.in:259: -1- AC_DEFINE_TRACE_LITERAL([ALL_INTERIOR_POINTERS])
++m4trace:configure.in:262: -1- AC_DEFINE_TRACE_LITERAL([JAVA_FINALIZATION])
++m4trace:configure.in:263: -1- AC_DEFINE_TRACE_LITERAL([GC_GCJ_SUPPORT])
++m4trace:configure.in:264: -1- AC_DEFINE_TRACE_LITERAL([ATOMIC_UNCOLLECTABLE])
++m4trace:configure.in:270: -1- AC_DEFINE_TRACE_LITERAL([NO_SIGSET])
++m4trace:configure.in:271: -1- AC_DEFINE_TRACE_LITERAL([NO_DEBUGGING])
++m4trace:configure.in:290: -1- AC_DEFINE_TRACE_LITERAL([KEEP_BACK_PTRS])
++m4trace:configure.in:290: -1- AC_DEFINE_TRACE_LITERAL([DBG_HDRS_ALL])
++m4trace:configure.in:290: -1- AC_DEFINE_TRACE_LITERAL([MAKE_BACK_GRAPH])
++m4trace:configure.in:290: -1- AC_DEFINE_TRACE_LITERAL([MAKE_BACK_GRAPH])
++m4trace:configure.in:290: -1- AC_DEFINE_TRACE_LITERAL([SAVE_CALL_COUNT])
++m4trace:configure.in:292: -1- AM_CONDITIONAL([USE_LIBDIR], [test -z "$with_cross_host"])
++m4trace:configure.in:292: -1- AC_SUBST([USE_LIBDIR_TRUE])
++m4trace:configure.in:292: -1- AC_SUBST([USE_LIBDIR_FALSE])
++m4trace:configure.in:317: -1- AC_CONFIG_FILES([Makefile include/Makefile])
++m4trace:configure.in:317: -1- AC_SUBST([LIB@&t@OBJS], [$ac_libobjs])
++m4trace:configure.in:317: -1- AC_SUBST([LTLIBOBJS], [$ac_ltlibobjs])
+diff -buNr boehm-gc/autom4te.cache/traces.1 boehm-gc/autom4te.cache/traces.1
+--- boehm-gc/autom4te.cache/traces.1 Wed Dec 31 16:00:00 1969
++++ boehm-gc/autom4te.cache/traces.1 Sat Sep 13 02:10:15 2003
+@@ -0,0 +1,250 @@
++m4trace:aclocal.m4:166: -1- m4_pattern_allow([^AM_[A-Z]+FLAGS$])
++m4trace:configure.in:16: -1- m4_pattern_forbid([^_?A[CHUM]_])
++m4trace:configure.in:16: -1- m4_pattern_forbid([_AC_])
++m4trace:configure.in:16: -1- m4_pattern_forbid([^LIBOBJS$], [do not use LIBOBJS directly, use AC_LIBOBJ (see section `AC_LIBOBJ vs LIBOBJS'])
++m4trace:configure.in:16: -1- m4_pattern_allow([^AS_FLAGS$])
++m4trace:configure.in:16: -1- m4_pattern_forbid([^_?m4_])
++m4trace:configure.in:16: -1- m4_pattern_forbid([^dnl$])
++m4trace:configure.in:16: -1- m4_pattern_forbid([^_?AS_])
++m4trace:configure.in:16: -1- AC_SUBST([SHELL], [${CONFIG_SHELL-/bin/sh}])
++m4trace:configure.in:16: -1- AC_SUBST([PATH_SEPARATOR])
++m4trace:configure.in:16: -1- AC_SUBST([PACKAGE_NAME], [m4_ifdef([AC_PACKAGE_NAME], ['AC_PACKAGE_NAME'])])
++m4trace:configure.in:16: -1- AC_SUBST([PACKAGE_TARNAME], [m4_ifdef([AC_PACKAGE_TARNAME], ['AC_PACKAGE_TARNAME'])])
++m4trace:configure.in:16: -1- AC_SUBST([PACKAGE_VERSION], [m4_ifdef([AC_PACKAGE_VERSION], ['AC_PACKAGE_VERSION'])])
++m4trace:configure.in:16: -1- AC_SUBST([PACKAGE_STRING], [m4_ifdef([AC_PACKAGE_STRING], ['AC_PACKAGE_STRING'])])
++m4trace:configure.in:16: -1- AC_SUBST([PACKAGE_BUGREPORT], [m4_ifdef([AC_PACKAGE_BUGREPORT], ['AC_PACKAGE_BUGREPORT'])])
++m4trace:configure.in:16: -1- AC_SUBST([exec_prefix], [NONE])
++m4trace:configure.in:16: -1- AC_SUBST([prefix], [NONE])
++m4trace:configure.in:16: -1- AC_SUBST([program_transform_name], [s,x,x,])
++m4trace:configure.in:16: -1- AC_SUBST([bindir], ['${exec_prefix}/bin'])
++m4trace:configure.in:16: -1- AC_SUBST([sbindir], ['${exec_prefix}/sbin'])
++m4trace:configure.in:16: -1- AC_SUBST([libexecdir], ['${exec_prefix}/libexec'])
++m4trace:configure.in:16: -1- AC_SUBST([datadir], ['${prefix}/share'])
++m4trace:configure.in:16: -1- AC_SUBST([sysconfdir], ['${prefix}/etc'])
++m4trace:configure.in:16: -1- AC_SUBST([sharedstatedir], ['${prefix}/com'])
++m4trace:configure.in:16: -1- AC_SUBST([localstatedir], ['${prefix}/var'])
++m4trace:configure.in:16: -1- AC_SUBST([libdir], ['${exec_prefix}/lib'])
++m4trace:configure.in:16: -1- AC_SUBST([includedir], ['${prefix}/include'])
++m4trace:configure.in:16: -1- AC_SUBST([oldincludedir], ['/usr/include'])
++m4trace:configure.in:16: -1- AC_SUBST([infodir], ['${prefix}/info'])
++m4trace:configure.in:16: -1- AC_SUBST([mandir], ['${prefix}/man'])
++m4trace:configure.in:16: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_NAME])
++m4trace:configure.in:16: -1- AH_OUTPUT([PACKAGE_NAME], [/* Define to the full name of this package. */
++#undef PACKAGE_NAME])
++m4trace:configure.in:16: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_TARNAME])
++m4trace:configure.in:16: -1- AH_OUTPUT([PACKAGE_TARNAME], [/* Define to the one symbol short name of this package. */
++#undef PACKAGE_TARNAME])
++m4trace:configure.in:16: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_VERSION])
++m4trace:configure.in:16: -1- AH_OUTPUT([PACKAGE_VERSION], [/* Define to the version of this package. */
++#undef PACKAGE_VERSION])
++m4trace:configure.in:16: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_STRING])
++m4trace:configure.in:16: -1- AH_OUTPUT([PACKAGE_STRING], [/* Define to the full name and version of this package. */
++#undef PACKAGE_STRING])
++m4trace:configure.in:16: -1- AC_DEFINE_TRACE_LITERAL([PACKAGE_BUGREPORT])
++m4trace:configure.in:16: -1- AH_OUTPUT([PACKAGE_BUGREPORT], [/* Define to the address where bug reports for this package should be sent. */
++#undef PACKAGE_BUGREPORT])
++m4trace:configure.in:16: -1- AC_SUBST([build_alias])
++m4trace:configure.in:16: -1- AC_SUBST([host_alias])
++m4trace:configure.in:16: -1- AC_SUBST([target_alias])
++m4trace:configure.in:16: -1- AC_SUBST([DEFS])
++m4trace:configure.in:16: -1- AC_SUBST([ECHO_C])
++m4trace:configure.in:16: -1- AC_SUBST([ECHO_N])
++m4trace:configure.in:16: -1- AC_SUBST([ECHO_T])
++m4trace:configure.in:16: -1- AC_SUBST([LIBS])
++m4trace:configure.in:27: -1- AC_SUBST([gc_basedir])
++m4trace:configure.in:27: -1- AC_SUBST([build], [$ac_cv_build])
++m4trace:configure.in:27: -1- AC_SUBST([build_cpu], [`echo $ac_cv_build | sed 's/^\([[^-]]*\)-\([[^-]]*\)-\(.*\)$/\1/'`])
++m4trace:configure.in:27: -1- AC_SUBST([build_vendor], [`echo $ac_cv_build | sed 's/^\([[^-]]*\)-\([[^-]]*\)-\(.*\)$/\2/'`])
++m4trace:configure.in:27: -1- AC_SUBST([build_os], [`echo $ac_cv_build | sed 's/^\([[^-]]*\)-\([[^-]]*\)-\(.*\)$/\3/'`])
++m4trace:configure.in:27: -1- AC_SUBST([host], [$ac_cv_host])
++m4trace:configure.in:27: -1- AC_SUBST([host_cpu], [`echo $ac_cv_host | sed 's/^\([[^-]]*\)-\([[^-]]*\)-\(.*\)$/\1/'`])
++m4trace:configure.in:27: -1- AC_SUBST([host_vendor], [`echo $ac_cv_host | sed 's/^\([[^-]]*\)-\([[^-]]*\)-\(.*\)$/\2/'`])
++m4trace:configure.in:27: -1- AC_SUBST([host_os], [`echo $ac_cv_host | sed 's/^\([[^-]]*\)-\([[^-]]*\)-\(.*\)$/\3/'`])
++m4trace:configure.in:27: -1- AC_SUBST([target], [$ac_cv_target])
++m4trace:configure.in:27: -1- AC_SUBST([target_cpu], [`echo $ac_cv_target | sed 's/^\([[^-]]*\)-\([[^-]]*\)-\(.*\)$/\1/'`])
++m4trace:configure.in:27: -1- AC_SUBST([target_vendor], [`echo $ac_cv_target | sed 's/^\([[^-]]*\)-\([[^-]]*\)-\(.*\)$/\2/'`])
++m4trace:configure.in:27: -1- AC_SUBST([target_os], [`echo $ac_cv_target | sed 's/^\([[^-]]*\)-\([[^-]]*\)-\(.*\)$/\3/'`])
++m4trace:configure.in:27: -1- AC_SUBST([mkinstalldirs])
++m4trace:configure.in:27: -1- AC_PROG_INSTALL
++m4trace:configure.in:27: -1- AC_SUBST([INSTALL_PROGRAM])
++m4trace:configure.in:27: -1- AC_SUBST([INSTALL_SCRIPT])
++m4trace:configure.in:27: -1- AC_SUBST([INSTALL_DATA])
++m4trace:configure.in:27: -1- AC_SUBST([PACKAGE], [gc])
++m4trace:configure.in:27: -1- AC_SUBST([VERSION], [6.1a1])
++m4trace:configure.in:27: -1- AC_SUBST([ACLOCAL])
++m4trace:configure.in:27: -1- AC_SUBST([AUTOCONF])
++m4trace:configure.in:27: -1- AC_SUBST([AUTOMAKE])
++m4trace:configure.in:27: -1- AC_SUBST([AUTOHEADER])
++m4trace:configure.in:27: -1- AC_SUBST([MAKEINFO])
++m4trace:configure.in:27: -1- AC_SUBST([AMTAR])
++m4trace:configure.in:27: -1- AC_SUBST([install_sh])
++m4trace:configure.in:27: -1- AC_SUBST([STRIP])
++m4trace:configure.in:27: -1- AC_SUBST([ac_ct_STRIP])
++m4trace:configure.in:27: -1- AC_SUBST([INSTALL_STRIP_PROGRAM])
++m4trace:configure.in:27: -1- AC_PROG_AWK
++m4trace:configure.in:27: -1- AC_SUBST([AWK])
++m4trace:configure.in:27: -1- AC_PROG_MAKE_SET
++m4trace:configure.in:27: -1- AC_SUBST([SET_MAKE])
++m4trace:configure.in:27: -1- AC_SUBST([AS])
++m4trace:configure.in:27: -1- AC_SUBST([ac_ct_AS])
++m4trace:configure.in:27: -1- AC_SUBST([AR])
++m4trace:configure.in:27: -1- AC_SUBST([ac_ct_AR])
++m4trace:configure.in:27: -1- AC_SUBST([RANLIB])
++m4trace:configure.in:27: -1- AC_SUBST([ac_ct_RANLIB])
++m4trace:configure.in:27: -1- AC_PROG_INSTALL
++m4trace:configure.in:27: -1- AC_SUBST([INSTALL_PROGRAM])
++m4trace:configure.in:27: -1- AC_SUBST([INSTALL_SCRIPT])
++m4trace:configure.in:27: -1- AC_SUBST([INSTALL_DATA])
++m4trace:configure.in:27: -1- AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes])
++m4trace:configure.in:27: -1- AC_SUBST([MAINTAINER_MODE_TRUE])
++m4trace:configure.in:27: -1- AC_SUBST([MAINTAINER_MODE_FALSE])
++m4trace:configure.in:27: -1- AC_SUBST([MAINT])
++m4trace:configure.in:27: -1- AC_SUBST([GC_CFLAGS])
++m4trace:configure.in:29: -1- AM_PROG_LIBTOOL
++m4trace:configure.in:29: -1- AC_PROG_LIBTOOL
++m4trace:configure.in:29: -1- AC_PROG_CC
++m4trace:configure.in:29: -1- AC_SUBST([CC])
++m4trace:configure.in:29: -1- AC_SUBST([CFLAGS])
++m4trace:configure.in:29: -1- AC_SUBST([LDFLAGS])
++m4trace:configure.in:29: -1- AC_SUBST([CPPFLAGS])
++m4trace:configure.in:29: -1- AC_SUBST([CC])
++m4trace:configure.in:29: -1- AC_SUBST([ac_ct_CC])
++m4trace:configure.in:29: -1- AC_SUBST([CC])
++m4trace:configure.in:29: -1- AC_SUBST([ac_ct_CC])
++m4trace:configure.in:29: -1- AC_SUBST([CC])
++m4trace:configure.in:29: -1- AC_SUBST([CC])
++m4trace:configure.in:29: -1- AC_SUBST([ac_ct_CC])
++m4trace:configure.in:29: -1- AC_SUBST([EXEEXT], [$ac_cv_exeext])
++m4trace:configure.in:29: -1- AC_SUBST([OBJEXT], [$ac_cv_objext])
++m4trace:configure.in:29: -1- AC_SUBST([DEPDIR])
++m4trace:configure.in:29: -1- AC_SUBST([am__include])
++m4trace:configure.in:29: -1- AC_SUBST([am__quote])
++m4trace:configure.in:29: -1- AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
++m4trace:configure.in:29: -1- AC_SUBST([AMDEP_TRUE])
++m4trace:configure.in:29: -1- AC_SUBST([AMDEP_FALSE])
++m4trace:configure.in:29: -1- AC_SUBST([AMDEPBACKSLASH])
++m4trace:configure.in:29: -1- AC_SUBST([CCDEPMODE], [depmode=$am_cv_CC_dependencies_compiler_type])
++m4trace:configure.in:29: -1- AC_PROG_LN_S
++m4trace:configure.in:29: -1- AC_SUBST([LN_S], [$as_ln_s])
++m4trace:configure.in:29: -1- AC_SUBST([ECHO])
++m4trace:configure.in:29: -1- AC_SUBST([RANLIB])
++m4trace:configure.in:29: -1- AC_SUBST([ac_ct_RANLIB])
++m4trace:configure.in:29: -1- AC_SUBST([STRIP])
++m4trace:configure.in:29: -1- AC_SUBST([ac_ct_STRIP])
++m4trace:configure.in:29: -1- AC_CHECK_LIB([dld], [shl_load], [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld"], [AC_CHECK_FUNC([dlopen],
++ [lt_cv_dlopen="dlopen"],
++ [AC_CHECK_LIB([dl], [dlopen],
++ [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],
++ [AC_CHECK_LIB([svld], [dlopen],
++ [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"],
++ [AC_CHECK_LIB([dld], [dld_link],
++ [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"])
++ ])
++ ])
++ ])
++ ])
++m4trace:configure.in:29: -1- AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], [AC_CHECK_LIB([svld], [dlopen],
++ [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"],
++ [AC_CHECK_LIB([dld], [dld_link],
++ [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"])
++ ])
++ ])
++m4trace:configure.in:29: -1- AC_CHECK_LIB([svld], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], [AC_CHECK_LIB([dld], [dld_link],
++ [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"])
++ ])
++m4trace:configure.in:29: -1- AC_CHECK_LIB([dld], [dld_link], [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"])
++m4trace:configure.in:29: -1- AC_CHECK_HEADERS([dlfcn.h])
++m4trace:configure.in:29: -1- AH_OUTPUT([HAVE_DLFCN_H], [/* Define to 1 if you have the <dlfcn.h> header file. */
++#undef HAVE_DLFCN_H])
++m4trace:configure.in:29: -1- AC_HEADER_STDC
++m4trace:configure.in:29: -1- AC_PROG_CPP
++m4trace:configure.in:29: -1- AC_SUBST([CPP])
++m4trace:configure.in:29: -1- AC_SUBST([CPPFLAGS])
++m4trace:configure.in:29: -1- AC_SUBST([CPP])
++m4trace:configure.in:29: -1- AC_SUBST([EGREP])
++m4trace:configure.in:29: -1- AC_DEFINE_TRACE_LITERAL([STDC_HEADERS])
++m4trace:configure.in:29: -1- AH_OUTPUT([STDC_HEADERS], [/* Define to 1 if you have the ANSI C header files. */
++#undef STDC_HEADERS])
++m4trace:configure.in:29: -1- AC_CHECK_HEADERS([sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
++ inttypes.h stdint.h unistd.h], [], [], [$ac_includes_default])
++m4trace:configure.in:29: -1- AH_OUTPUT([HAVE_SYS_TYPES_H], [/* Define to 1 if you have the <sys/types.h> header file. */
++#undef HAVE_SYS_TYPES_H])
++m4trace:configure.in:29: -1- AH_OUTPUT([HAVE_SYS_STAT_H], [/* Define to 1 if you have the <sys/stat.h> header file. */
++#undef HAVE_SYS_STAT_H])
++m4trace:configure.in:29: -1- AH_OUTPUT([HAVE_STDLIB_H], [/* Define to 1 if you have the <stdlib.h> header file. */
++#undef HAVE_STDLIB_H])
++m4trace:configure.in:29: -1- AH_OUTPUT([HAVE_STRING_H], [/* Define to 1 if you have the <string.h> header file. */
++#undef HAVE_STRING_H])
++m4trace:configure.in:29: -1- AH_OUTPUT([HAVE_MEMORY_H], [/* Define to 1 if you have the <memory.h> header file. */
++#undef HAVE_MEMORY_H])
++m4trace:configure.in:29: -1- AH_OUTPUT([HAVE_STRINGS_H], [/* Define to 1 if you have the <strings.h> header file. */
++#undef HAVE_STRINGS_H])
++m4trace:configure.in:29: -1- AH_OUTPUT([HAVE_INTTYPES_H], [/* Define to 1 if you have the <inttypes.h> header file. */
++#undef HAVE_INTTYPES_H])
++m4trace:configure.in:29: -1- AH_OUTPUT([HAVE_STDINT_H], [/* Define to 1 if you have the <stdint.h> header file. */
++#undef HAVE_STDINT_H])
++m4trace:configure.in:29: -1- AH_OUTPUT([HAVE_UNISTD_H], [/* Define to 1 if you have the <unistd.h> header file. */
++#undef HAVE_UNISTD_H])
++m4trace:configure.in:29: -1- AC_SUBST([LIBTOOL])
++m4trace:configure.in:38: -1- AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes])
++m4trace:configure.in:38: -1- AC_SUBST([MAINTAINER_MODE_TRUE])
++m4trace:configure.in:38: -1- AC_SUBST([MAINTAINER_MODE_FALSE])
++m4trace:configure.in:38: -1- AC_SUBST([MAINT])
++m4trace:configure.in:77: -1- AC_DEFINE_TRACE_LITERAL([GC_LINUX_THREADS])
++m4trace:configure.in:78: -1- AC_DEFINE_TRACE_LITERAL([_REENTRANT])
++m4trace:configure.in:80: -1- AC_DEFINE_TRACE_LITERAL([PARALLEL_MARK])
++m4trace:configure.in:82: -1- AC_DEFINE_TRACE_LITERAL([THREAD_LOCAL_ALLOC])
++m4trace:configure.in:85: -1- AC_DEFINE_TRACE_LITERAL([GC_LINUX_THREADS])
++m4trace:configure.in:86: -1- AC_DEFINE_TRACE_LITERAL([_REENTRANT])
++m4trace:configure.in:90: -1- AC_DEFINE_TRACE_LITERAL([GC_HPUX_THREADS])
++m4trace:configure.in:91: -1- AC_DEFINE_TRACE_LITERAL([_POSIX_C_SOURCE])
++m4trace:configure.in:93: -1- AC_DEFINE_TRACE_LITERAL([PARALLEL_MARK])
++m4trace:configure.in:95: -1- AC_DEFINE_TRACE_LITERAL([THREAD_LOCAL_ALLOC])
++m4trace:configure.in:100: -1- AC_DEFINE_TRACE_LITERAL([GC_FREEBSD_THREADS])
++m4trace:configure.in:105: -1- AC_DEFINE_TRACE_LITERAL([GC_SOLARIS_THREADS])
++m4trace:configure.in:106: -1- AC_DEFINE_TRACE_LITERAL([GC_SOLARIS_PTHREADS])
++m4trace:configure.in:109: -1- AC_DEFINE_TRACE_LITERAL([GC_IRIX_THREADS])
++m4trace:configure.in:115: -1- AC_DEFINE_TRACE_LITERAL([GC_DARWIN_THREADS])
++m4trace:configure.in:116: -1- AC_DEFINE_TRACE_LITERAL([THREAD_LOCAL_ALLOC])
++m4trace:configure.in:118: -1- AC_DEFINE_TRACE_LITERAL([PARALLEL_MARK])
++m4trace:configure.in:124: -1- AC_DEFINE_TRACE_LITERAL([GC_WIN32_THREADS])
++m4trace:configure.in:125: -1- AC_DEFINE_TRACE_LITERAL([NO_GETENV])
++m4trace:configure.in:134: -1- AC_SUBST([THREADLIBS])
++m4trace:configure.in:141: -1- AM_CONDITIONAL([POWERPC_DARWIN], [test x$powerpc_darwin = xtrue])
++m4trace:configure.in:141: -1- AC_SUBST([POWERPC_DARWIN_TRUE])
++m4trace:configure.in:141: -1- AC_SUBST([POWERPC_DARWIN_FALSE])
++m4trace:configure.in:148: -1- AC_CHECK_LIB([dl], [dlopen], [EXTRA_TEST_LIBS="$EXTRA_TEST_LIBS -ldl"])
++m4trace:configure.in:152: -1- AC_SUBST([EXTRA_TEST_LIBS])
++m4trace:configure.in:155: -1- AC_SUBST([target_all])
++m4trace:configure.in:156: -1- AC_SUBST([target_alias])
++m4trace:configure.in:174: -1- AC_DEFINE_TRACE_LITERAL([ECOS])
++m4trace:configure.in:179: -1- AC_SUBST([CXX])
++m4trace:configure.in:181: -1- AC_SUBST([INCLUDES])
++m4trace:configure.in:182: -1- AC_SUBST([CXXINCLUDES])
++m4trace:configure.in:197: -1- AC_DEFINE_TRACE_LITERAL([SOLARIS25_PROC_VDB_BUG_FIXED])
++m4trace:configure.in:201: -1- AC_DEFINE_TRACE_LITERAL([STACKBASE])
++m4trace:configure.in:202: -1- AC_DEFINE_TRACE_LITERAL([DATASTART_IS_ETEXT])
++m4trace:configure.in:211: -1- AC_DEFINE_TRACE_LITERAL([NO_EXECUTE_PERMISSION])
++m4trace:configure.in:215: -1- AC_DEFINE_TRACE_LITERAL([SUNOS53_SHARED_LIB])
++m4trace:configure.in:228: -1- AC_SUBST([addobjs])
++m4trace:configure.in:252: -1- AC_SUBST([MY_CFLAGS])
++m4trace:configure.in:256: -1- AC_DEFINE_TRACE_LITERAL([SILENT])
++m4trace:configure.in:257: -1- AC_DEFINE_TRACE_LITERAL([NO_SIGNALS])
++m4trace:configure.in:258: -1- AC_DEFINE_TRACE_LITERAL([NO_EXECUTE_PERMISSION])
++m4trace:configure.in:259: -1- AC_DEFINE_TRACE_LITERAL([ALL_INTERIOR_POINTERS])
++m4trace:configure.in:262: -1- AC_DEFINE_TRACE_LITERAL([JAVA_FINALIZATION])
++m4trace:configure.in:263: -1- AC_DEFINE_TRACE_LITERAL([GC_GCJ_SUPPORT])
++m4trace:configure.in:264: -1- AC_DEFINE_TRACE_LITERAL([ATOMIC_UNCOLLECTABLE])
++m4trace:configure.in:270: -1- AC_DEFINE_TRACE_LITERAL([NO_SIGSET])
++m4trace:configure.in:271: -1- AC_DEFINE_TRACE_LITERAL([NO_DEBUGGING])
++m4trace:configure.in:290: -1- AC_DEFINE_TRACE_LITERAL([KEEP_BACK_PTRS])
++m4trace:configure.in:290: -1- AC_DEFINE_TRACE_LITERAL([DBG_HDRS_ALL])
++m4trace:configure.in:290: -1- AC_DEFINE_TRACE_LITERAL([MAKE_BACK_GRAPH])
++m4trace:configure.in:290: -1- AC_DEFINE_TRACE_LITERAL([MAKE_BACK_GRAPH])
++m4trace:configure.in:290: -1- AC_DEFINE_TRACE_LITERAL([SAVE_CALL_COUNT])
++m4trace:configure.in:292: -1- AM_CONDITIONAL([USE_LIBDIR], [test -z "$with_cross_host"])
++m4trace:configure.in:292: -1- AC_SUBST([USE_LIBDIR_TRUE])
++m4trace:configure.in:292: -1- AC_SUBST([USE_LIBDIR_FALSE])
++m4trace:configure.in:317: -1- AC_CONFIG_FILES([Makefile include/Makefile])
++m4trace:configure.in:317: -1- AC_SUBST([LIB@&t@OBJS], [$ac_libobjs])
++m4trace:configure.in:317: -1- AC_SUBST([LTLIBOBJS], [$ac_ltlibobjs])
+diff -buNr boehm-gc/backgraph.c boehm-gc/backgraph.c
+--- boehm-gc/backgraph.c Wed Jan 30 18:48:45 2002
++++ boehm-gc/backgraph.c Sat Sep 13 02:10:15 2003
+@@ -307,6 +307,7 @@
+ }
+ while (currentp < (word *)(p + gc_descr)) {
+ word current = *currentp++;
++ FIXUP_POINTER(current);
+ if (current >= (word)GC_least_plausible_heap_addr &&
+ current <= (word)GC_greatest_plausible_heap_addr) {
+ ptr_t target = GC_base((GC_PTR)current);
+diff -buNr boehm-gc/configure boehm-gc/configure
+--- boehm-gc/configure Tue May 13 17:18:14 2003
++++ boehm-gc/configure Sat Sep 13 02:10:15 2003
+@@ -61,7 +61,6 @@
+ program_transform_name=s,x,x,
+ silent=
+ site=
+-sitefile=
+ srcdir=
+ target=NONE
+ verbose=
+@@ -176,7 +175,6 @@
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+- --site-file=FILE use FILE as the site file
+ --version print the version of autoconf that created configure
+ Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+@@ -347,11 +345,6 @@
+ -site=* | --site=* | --sit=*)
+ site="$ac_optarg" ;;
+
+- -site-file | --site-file | --site-fil | --site-fi | --site-f)
+- ac_prev=sitefile ;;
+- -site-file=* | --site-file=* | --site-fil=* | --site-fi=* | --site-f=*)
+- sitefile="$ac_optarg" ;;
+-
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+@@ -517,16 +510,12 @@
+ srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+ # Prefer explicitly selected file to automatically selected ones.
+-if test -z "$sitefile"; then
+- if test -z "$CONFIG_SITE"; then
++if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+- fi
+-else
+- CONFIG_SITE="$sitefile"
+ fi
+ for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+@@ -604,7 +593,7 @@
+ # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+ # ./install, which can be erroneously created by make from ./install.sh.
+ echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+-echo "configure:608: checking for a BSD compatible install" >&5
++echo "configure:597: checking for a BSD compatible install" >&5
+ if test -z "$INSTALL"; then
+ if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+@@ -657,7 +646,7 @@
+ test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+ echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6
+-echo "configure:661: checking whether build environment is sane" >&5
++echo "configure:650: checking whether build environment is sane" >&5
+ # Just in case
+ sleep 1
+ echo timestamp > conftestfile
+@@ -714,7 +703,7 @@
+ test "$program_transform_name" = "" && program_transform_name="s,x,x,"
+
+ echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
+-echo "configure:718: checking whether ${MAKE-make} sets \${MAKE}" >&5
++echo "configure:707: checking whether ${MAKE-make} sets \${MAKE}" >&5
+ set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
+ if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+@@ -747,12 +736,12 @@
+ fi
+
+ echo $ac_n "checking for Cygwin environment""... $ac_c" 1>&6
+-echo "configure:751: checking for Cygwin environment" >&5
++echo "configure:740: checking for Cygwin environment" >&5
+ if eval "test \"`echo '$''{'ac_cv_cygwin'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+ else
+ cat > conftest.$ac_ext <<EOF
+-#line 756 "configure"
++#line 745 "configure"
+ #include "confdefs.h"
+
+ int main() {
+@@ -763,7 +752,7 @@
+ return __CYGWIN__;
+ ; return 0; }
+ EOF
+-if { (eval echo configure:767: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
++if { (eval echo configure:756: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_cygwin=yes
+ else
+@@ -780,19 +769,19 @@
+ CYGWIN=
+ test "$ac_cv_cygwin" = yes && CYGWIN=yes
+ echo $ac_n "checking for mingw32 environment""... $ac_c" 1>&6
+-echo "configure:784: checking for mingw32 environment" >&5
++echo "configure:773: checking for mingw32 environment" >&5
+ if eval "test \"`echo '$''{'ac_cv_mingw32'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+ else
+ cat > conftest.$ac_ext <<EOF
+-#line 789 "configure"
++#line 778 "configure"
+ #include "confdefs.h"
+
+ int main() {
+ return __MINGW32__;
+ ; return 0; }
+ EOF
+-if { (eval echo configure:796: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
++if { (eval echo configure:785: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_mingw32=yes
+ else
+@@ -903,7 +892,7 @@
+ fi
+
+ echo $ac_n "checking host system type""... $ac_c" 1>&6
+-echo "configure:907: checking host system type" >&5
++echo "configure:896: checking host system type" >&5
+
+ host_alias=$host
+ case "$host_alias" in
+@@ -924,7 +913,7 @@
+ echo "$ac_t""$host" 1>&6
+
+ echo $ac_n "checking target system type""... $ac_c" 1>&6
+-echo "configure:928: checking target system type" >&5
++echo "configure:917: checking target system type" >&5
+
+ target_alias=$target
+ case "$target_alias" in
+@@ -942,7 +931,7 @@
+ echo "$ac_t""$target" 1>&6
+
+ echo $ac_n "checking build system type""... $ac_c" 1>&6
+-echo "configure:946: checking build system type" >&5
++echo "configure:935: checking build system type" >&5
+
+ build_alias=$build
+ case "$build_alias" in
+@@ -982,7 +971,7 @@
+
+ missing_dir=`cd $ac_aux_dir && pwd`
+ echo $ac_n "checking for working aclocal""... $ac_c" 1>&6
+-echo "configure:986: checking for working aclocal" >&5
++echo "configure:975: checking for working aclocal" >&5
+ # Run test in a subshell; some versions of sh will print an error if
+ # an executable is not found, even if stderr is redirected.
+ # Redirect stdin to placate older versions of autoconf. Sigh.
+@@ -995,7 +984,7 @@
+ fi
+
+ echo $ac_n "checking for working autoconf""... $ac_c" 1>&6
+-echo "configure:999: checking for working autoconf" >&5
++echo "configure:988: checking for working autoconf" >&5
+ # Run test in a subshell; some versions of sh will print an error if
+ # an executable is not found, even if stderr is redirected.
+ # Redirect stdin to placate older versions of autoconf. Sigh.
+@@ -1008,7 +997,7 @@
+ fi
+
+ echo $ac_n "checking for working automake""... $ac_c" 1>&6
+-echo "configure:1012: checking for working automake" >&5
++echo "configure:1001: checking for working automake" >&5
+ # Run test in a subshell; some versions of sh will print an error if
+ # an executable is not found, even if stderr is redirected.
+ # Redirect stdin to placate older versions of autoconf. Sigh.
+@@ -1021,7 +1010,7 @@
+ fi
+
+ echo $ac_n "checking for working autoheader""... $ac_c" 1>&6
+-echo "configure:1025: checking for working autoheader" >&5
++echo "configure:1014: checking for working autoheader" >&5
+ # Run test in a subshell; some versions of sh will print an error if
+ # an executable is not found, even if stderr is redirected.
+ # Redirect stdin to placate older versions of autoconf. Sigh.
+@@ -1034,7 +1023,7 @@
+ fi
+
+ echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6
+-echo "configure:1038: checking for working makeinfo" >&5
++echo "configure:1027: checking for working makeinfo" >&5
+ # Run test in a subshell; some versions of sh will print an error if
+ # an executable is not found, even if stderr is redirected.
+ # Redirect stdin to placate older versions of autoconf. Sigh.
+@@ -1060,7 +1049,7 @@
+ # Extract the first word of "gcc", so it can be a program name with args.
+ set dummy gcc; ac_word=$2
+ echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+-echo "configure:1064: checking for $ac_word" >&5
++echo "configure:1053: checking for $ac_word" >&5
+ if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+ else
+@@ -1090,7 +1079,7 @@
+ # Extract the first word of "cc", so it can be a program name with args.
+ set dummy cc; ac_word=$2
+ echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+-echo "configure:1094: checking for $ac_word" >&5
++echo "configure:1083: checking for $ac_word" >&5
+ if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+ else
+@@ -1139,7 +1128,7 @@
+ fi
+
+ echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+-echo "configure:1143: checking whether we are using GNU C" >&5
++echo "configure:1132: checking whether we are using GNU C" >&5
+ if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+ else
+@@ -1148,7 +1137,7 @@
+ yes;
+ #endif
+ EOF
+-if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1152: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
++if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1141: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ ac_cv_prog_gcc=yes
+ else
+ ac_cv_prog_gcc=no
+@@ -1163,7 +1152,7 @@
+ ac_save_CFLAGS="$CFLAGS"
+ CFLAGS=
+ echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+-echo "configure:1167: checking whether ${CC-cc} accepts -g" >&5
++echo "configure:1156: checking whether ${CC-cc} accepts -g" >&5
+ if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+ else
+@@ -1200,7 +1189,7 @@
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+ set dummy $ac_prog; ac_word=$2
+ echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+-echo "configure:1204: checking for $ac_word" >&5
++echo "configure:1193: checking for $ac_word" >&5
+ if eval "test \"`echo '$''{'ac_cv_prog_CXX'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+ else
+@@ -1233,7 +1222,7 @@
+ test -z "$CXX" && { echo "configure: error: no acceptable c++ found in \$PATH" 1>&2; exit 1; }
+
+ echo $ac_n "checking whether we are using GNU C++""... $ac_c" 1>&6
+-echo "configure:1237: checking whether we are using GNU C++" >&5
++echo "configure:1226: checking whether we are using GNU C++" >&5
+ if eval "test \"`echo '$''{'ac_cv_prog_gxx'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+ else
+@@ -1242,7 +1231,7 @@
+ yes;
+ #endif
+ EOF
+-if { ac_try='${CXX-g++} -E conftest.C'; { (eval echo configure:1246: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
++if { ac_try='${CXX-g++} -E conftest.C'; { (eval echo configure:1235: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ ac_cv_prog_gxx=yes
+ else
+ ac_cv_prog_gxx=no
+@@ -1257,7 +1246,7 @@
+ ac_save_CXXFLAGS="$CXXFLAGS"
+ CXXFLAGS=
+ echo $ac_n "checking whether ${CXX-g++} accepts -g""... $ac_c" 1>&6
+-echo "configure:1261: checking whether ${CXX-g++} accepts -g" >&5
++echo "configure:1250: checking whether ${CXX-g++} accepts -g" >&5
+ if eval "test \"`echo '$''{'ac_cv_prog_cxx_g'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+ else
+@@ -1290,7 +1279,7 @@
+ # NEWLIB_CONFIGURE, which doesn't work because that means that it will
+ # be run before AC_CANONICAL_HOST.
+ echo $ac_n "checking build system type""... $ac_c" 1>&6
+-echo "configure:1294: checking build system type" >&5
++echo "configure:1283: checking build system type" >&5
+
+ build_alias=$build
+ case "$build_alias" in
+@@ -1311,7 +1300,7 @@
+ # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args.
+ set dummy ${ac_tool_prefix}as; ac_word=$2
+ echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+-echo "configure:1315: checking for $ac_word" >&5
++echo "configure:1304: checking for $ac_word" >&5
+ if eval "test \"`echo '$''{'ac_cv_prog_AS'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+ else
+@@ -1343,7 +1332,7 @@
+ # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
+ set dummy ${ac_tool_prefix}ar; ac_word=$2
+ echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+-echo "configure:1347: checking for $ac_word" >&5
++echo "configure:1336: checking for $ac_word" >&5
+ if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+ else
+@@ -1375,7 +1364,7 @@
+ # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+ set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+ echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+-echo "configure:1379: checking for $ac_word" >&5
++echo "configure:1368: checking for $ac_word" >&5
+ if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+ else
+@@ -1407,7 +1396,7 @@
+ # Extract the first word of "ranlib", so it can be a program name with args.
+ set dummy ranlib; ac_word=$2
+ echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+-echo "configure:1411: checking for $ac_word" >&5
++echo "configure:1400: checking for $ac_word" >&5
+ if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+ else
+@@ -1452,7 +1441,7 @@
+ # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+ # ./install, which can be erroneously created by make from ./install.sh.
+ echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+-echo "configure:1456: checking for a BSD compatible install" >&5
++echo "configure:1445: checking for a BSD compatible install" >&5
+ if test -z "$INSTALL"; then
+ if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+@@ -1506,7 +1495,7 @@
+
+
+ echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6
+-echo "configure:1510: checking whether to enable maintainer-specific portions of Makefiles" >&5
++echo "configure:1499: checking whether to enable maintainer-specific portions of Makefiles" >&5
+ # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given.
+ if test "${enable_maintainer_mode+set}" = set; then
+ enableval="$enable_maintainer_mode"
+@@ -1544,7 +1533,7 @@
+
+
+ echo $ac_n "checking for executable suffix""... $ac_c" 1>&6
+-echo "configure:1548: checking for executable suffix" >&5
++echo "configure:1537: checking for executable suffix" >&5
+ if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+ else
+@@ -1554,10 +1543,10 @@
+ rm -f conftest*
+ echo 'int main () { return 0; }' > conftest.$ac_ext
+ ac_cv_exeext=
+- if { (eval echo configure:1558: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
++ if { (eval echo configure:1547: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+ for file in conftest.*; do
+ case $file in
+- *.c | *.o | *.obj | *.ilk | *.pdb) ;;
++ *.c | *.o | *.obj) ;;
+ *) ac_cv_exeext=`echo $file | sed -e s/conftest//` ;;
+ esac
+ done
+@@ -1676,7 +1665,7 @@
+ if test "$GCC" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ echo $ac_n "checking for ld used by GCC""... $ac_c" 1>&6
+-echo "configure:1680: checking for ld used by GCC" >&5
++echo "configure:1669: checking for ld used by GCC" >&5
+ case $host in
+ *-*-mingw*)
+ # gcc leaves a trailing carriage return which upsets mingw
+@@ -1706,10 +1695,10 @@
+ esac
+ elif test "$with_gnu_ld" = yes; then
+ echo $ac_n "checking for GNU ld""... $ac_c" 1>&6
+-echo "configure:1710: checking for GNU ld" >&5
++echo "configure:1699: checking for GNU ld" >&5
+ else
+ echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6
+-echo "configure:1713: checking for non-GNU ld" >&5
++echo "configure:1702: checking for non-GNU ld" >&5
+ fi
+ if eval "test \"`echo '$''{'lt_cv_path_LD'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+@@ -1744,7 +1733,7 @@
+ fi
+ test -z "$LD" && { echo "configure: error: no acceptable ld found in \$PATH" 1>&2; exit 1; }
+ echo $ac_n "checking if the linker ($LD) is GNU ld""... $ac_c" 1>&6
+-echo "configure:1748: checking if the linker ($LD) is GNU ld" >&5
++echo "configure:1737: checking if the linker ($LD) is GNU ld" >&5
+ if eval "test \"`echo '$''{'lt_cv_prog_gnu_ld'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+ else
+@@ -1761,7 +1750,7 @@
+
+
+ echo $ac_n "checking for $LD option to reload object files""... $ac_c" 1>&6
+-echo "configure:1765: checking for $LD option to reload object files" >&5
++echo "configure:1754: checking for $LD option to reload object files" >&5
+ if eval "test \"`echo '$''{'lt_cv_ld_reload_flag'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+ else
+@@ -1773,7 +1762,7 @@
+ test -n "$reload_flag" && reload_flag=" $reload_flag"
+
+ echo $ac_n "checking for BSD-compatible nm""... $ac_c" 1>&6
+-echo "configure:1777: checking for BSD-compatible nm" >&5
++echo "configure:1766: checking for BSD-compatible nm" >&5
+ if eval "test \"`echo '$''{'lt_cv_path_NM'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+ else
+@@ -1811,7 +1800,7 @@
+ echo "$ac_t""$NM" 1>&6
+
+ echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
+-echo "configure:1815: checking whether ln -s works" >&5
++echo "configure:1804: checking whether ln -s works" >&5
+ if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+ else
+@@ -1832,7 +1821,7 @@
+ fi
+
+ echo $ac_n "checking how to recognise dependant libraries""... $ac_c" 1>&6
+-echo "configure:1836: checking how to recognise dependant libraries" >&5
++echo "configure:1825: checking how to recognise dependant libraries" >&5
+ if eval "test \"`echo '$''{'lt_cv_deplibs_check_method'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+ else
+@@ -2005,13 +1994,13 @@
+ deplibs_check_method=$lt_cv_deplibs_check_method
+
+ echo $ac_n "checking for object suffix""... $ac_c" 1>&6
+-echo "configure:2009: checking for object suffix" >&5
++echo "configure:1998: checking for object suffix" >&5
+ if eval "test \"`echo '$''{'ac_cv_objext'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+ else
+ rm -f conftest*
+ echo 'int i = 1;' > conftest.$ac_ext
+-if { (eval echo configure:2015: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
++if { (eval echo configure:2004: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ for ac_file in conftest.*; do
+ case $ac_file in
+ *.c) ;;
+@@ -2035,7 +2024,7 @@
+ file_magic*)
+ if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+ echo $ac_n "checking for ${ac_tool_prefix}file""... $ac_c" 1>&6
+-echo "configure:2039: checking for ${ac_tool_prefix}file" >&5
++echo "configure:2028: checking for ${ac_tool_prefix}file" >&5
+ if eval "test \"`echo '$''{'lt_cv_path_MAGIC_CMD'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+ else
+@@ -2097,7 +2086,7 @@
+ if test -z "$lt_cv_path_MAGIC_CMD"; then
+ if test -n "$ac_tool_prefix"; then
+ echo $ac_n "checking for file""... $ac_c" 1>&6
+-echo "configure:2101: checking for file" >&5
++echo "configure:2090: checking for file" >&5
+ if eval "test \"`echo '$''{'lt_cv_path_MAGIC_CMD'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+ else
+@@ -2168,7 +2157,7 @@
+ # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+ set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+ echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+-echo "configure:2172: checking for $ac_word" >&5
++echo "configure:2161: checking for $ac_word" >&5
+ if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+ else
+@@ -2200,7 +2189,7 @@
+ # Extract the first word of "ranlib", so it can be a program name with args.
+ set dummy ranlib; ac_word=$2
+ echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+-echo "configure:2204: checking for $ac_word" >&5
++echo "configure:2193: checking for $ac_word" >&5
+ if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+ else
+@@ -2235,7 +2224,7 @@
+ # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+ set dummy ${ac_tool_prefix}strip; ac_word=$2
+ echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+-echo "configure:2239: checking for $ac_word" >&5
++echo "configure:2228: checking for $ac_word" >&5
+ if eval "test \"`echo '$''{'ac_cv_prog_STRIP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+ else
+@@ -2267,7 +2256,7 @@
+ # Extract the first word of "strip", so it can be a program name with args.
+ set dummy strip; ac_word=$2
+ echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+-echo "configure:2271: checking for $ac_word" >&5
++echo "configure:2260: checking for $ac_word" >&5
+ if eval "test \"`echo '$''{'ac_cv_prog_STRIP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+ else
+@@ -2334,21 +2323,8 @@
+ case $host in
+ *-*-irix6*)
+ # Find out which ABI we are using.
+- echo '#line 2338 "configure"' > conftest.$ac_ext
+- if { (eval echo configure:2339: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+- if test "$lt_cv_prog_gnu_ld" = yes; then
+- case `/usr/bin/file conftest.$ac_objext` in
+- *32-bit*)
+- LD="${LD-ld} -melf32bsmip"
+- ;;
+- *N32*)
+- LD="${LD-ld} -melf32bmipn32"
+- ;;
+- *64-bit*)
+- LD="${LD-ld} -melf64bmip"
+- ;;
+- esac
+- else
++ echo '#line 2327 "configure"' > conftest.$ac_ext
++ if { (eval echo configure:2328: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -32"
+@@ -2361,14 +2337,13 @@
+ ;;
+ esac
+ fi
+- fi
+ rm -rf conftest*
+ ;;
+
+ ia64-*-hpux*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+- if { (eval echo configure:2372: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
++ if { (eval echo configure:2347: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ case "`/usr/bin/file conftest.o`" in
+ *ELF-32*)
+ HPUX_IA64_MODE="32"
+@@ -2384,7 +2359,7 @@
+ x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+- if { (eval echo configure:2388: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
++ if { (eval echo configure:2363: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ case "`/usr/bin/file conftest.o`" in
+ *32-bit*)
+ case $host in
+@@ -2428,7 +2403,7 @@
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -belf"
+ echo $ac_n "checking whether the C compiler needs -belf""... $ac_c" 1>&6
+-echo "configure:2432: checking whether the C compiler needs -belf" >&5
++echo "configure:2407: checking whether the C compiler needs -belf" >&5
+ if eval "test \"`echo '$''{'lt_cv_cc_needs_belf'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+ else
+@@ -2441,14 +2416,14 @@
+ cross_compiling=$ac_cv_prog_cc_cross
+
+ cat > conftest.$ac_ext <<EOF
+-#line 2445 "configure"
++#line 2420 "configure"
+ #include "confdefs.h"
+
+ int main() {
+
+ ; return 0; }
+ EOF
+-if { (eval echo configure:2452: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
++if { (eval echo configure:2427: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ lt_cv_cc_needs_belf=yes
+ else
+@@ -2478,7 +2453,7 @@
+ esac
+
+ echo $ac_n "checking how to run the C++ preprocessor""... $ac_c" 1>&6
+-echo "configure:2482: checking how to run the C++ preprocessor" >&5
++echo "configure:2457: checking how to run the C++ preprocessor" >&5
+ if test -z "$CXXCPP"; then
+ if eval "test \"`echo '$''{'ac_cv_prog_CXXCPP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+@@ -2491,12 +2466,12 @@
+ cross_compiling=$ac_cv_prog_cxx_cross
+ CXXCPP="${CXX-g++} -E"
+ cat > conftest.$ac_ext <<EOF
+-#line 2495 "configure"
++#line 2470 "configure"
+ #include "confdefs.h"
+ #include <stdlib.h>
+ EOF
+ ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+-{ (eval echo configure:2500: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
++{ (eval echo configure:2475: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+ if test -z "$ac_err"; then
+ :
+@@ -2643,7 +2618,7 @@
+
+
+ echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6
+-echo "configure:2647: checking whether to enable maintainer-specific portions of Makefiles" >&5
++echo "configure:2622: checking whether to enable maintainer-specific portions of Makefiles" >&5
+ # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given.
+ if test "${enable_maintainer_mode+set}" = set; then
+ enableval="$enable_maintainer_mode"
+@@ -2676,7 +2651,7 @@
+
+
+ echo $ac_n "checking for executable suffix""... $ac_c" 1>&6
+-echo "configure:2680: checking for executable suffix" >&5
++echo "configure:2655: checking for executable suffix" >&5
+ if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+ else
+@@ -2686,10 +2661,10 @@
+ rm -f conftest*
+ echo 'int main () { return 0; }' > conftest.$ac_ext
+ ac_cv_exeext=
+- if { (eval echo configure:2690: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
++ if { (eval echo configure:2665: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+ for file in conftest.*; do
+ case $file in
+- *.c | *.o | *.obj | *.ilk | *.pdb) ;;
++ *.c | *.o | *.obj) ;;
+ *) ac_cv_exeext=`echo $file | sed -e s/conftest//` ;;
+ esac
+ done
+@@ -2709,7 +2684,7 @@
+ fi
+
+ echo $ac_n "checking for thread model used by GCC""... $ac_c" 1>&6
+-echo "configure:2713: checking for thread model used by GCC" >&5
++echo "configure:2688: checking for thread model used by GCC" >&5
+ THREADS=`$CC -v 2>&1 | sed -n 's/^Thread model: //p'`
+ if test -z "$THREADS"; then
+ THREADS=no
+@@ -2818,6 +2793,22 @@
+ *-*-cygwin*)
+ THREADLIBS=
+ ;;
++ *-*-darwin*)
++ cat >> confdefs.h <<\EOF
++#define GC_DARWIN_THREADS 1
++EOF
++
++ cat >> confdefs.h <<\EOF
++#define THREAD_LOCAL_ALLOC 1
++EOF
++
++ if test "${enable_parallel_mark}" = yes; then
++ cat >> confdefs.h <<\EOF
++#define PARALLEL_MARK 1
++EOF
++
++ fi
++ ;;
+ esac
+ ;;
+ win32)
+@@ -2829,12 +2820,6 @@
+ #define NO_GETENV 1
+ EOF
+
+- if test $enable_shared = yes; then
+- cat >> confdefs.h <<\EOF
+-#define GC_DLL 1
+-EOF
+-
+- fi
+ ;;
+ decosf1 | irix | mach | os2 | solaris | dce | vxworks)
+ { echo "configure: error: thread package $THREADS not yet supported" 1>&2; exit 1; }
+@@ -2845,8 +2830,28 @@
+ esac
+
+
+-echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6
+-echo "configure:2850: checking for dlopen in -ldl" >&5
++case "$host" in
++ powerpc-*-darwin*)
++ powerpc_darwin=true
++ ;;
++esac
++
++
++if test x$powerpc_darwin = xtrue; then
++ POWERPC_DARWIN_TRUE=
++ POWERPC_DARWIN_FALSE='#'
++else
++ POWERPC_DARWIN_TRUE='#'
++ POWERPC_DARWIN_FALSE=
++fi
++
++# We never want libdl on darwin. It is a fake libdl that just ends up making
++# dyld calls anyway
++case "$host" in
++ *-*-darwin*) ;;
++ *)
++ echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6
++echo "configure:2855: checking for dlopen in -ldl" >&5
+ ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'`
+ if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+@@ -2854,7 +2859,7 @@
+ ac_save_LIBS="$LIBS"
+ LIBS="-ldl $LIBS"
+ cat > conftest.$ac_ext <<EOF
+-#line 2858 "configure"
++#line 2863 "configure"
+ #include "confdefs.h"
+ /* Override any gcc2 internal prototype to avoid an error. */
+ /* We use char because int might match the return type of a gcc2
+@@ -2865,7 +2870,7 @@
+ dlopen()
+ ; return 0; }
+ EOF
+-if { (eval echo configure:2869: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
++if { (eval echo configure:2874: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+ else
+@@ -2885,6 +2890,9 @@
+ echo "$ac_t""no" 1>&6
+ fi
+
++ ;;
++esac
++
+
+
+ target_all=libgcjgc.la
+@@ -3100,17 +3108,15 @@
+ fi
+
+
+-if test -n "$with_cross_host" &&
+- test x"$with_cross_host" != x"no"; then
+- toolexecdir='$(exec_prefix)/$(target_alias)'
+- toolexeclibdir='$(toolexecdir)/lib'
+-else
+- toolexecdir='$(libdir)/gcc-lib/$(target_alias)'
+- toolexeclibdir='$(libdir)'
+-fi
+-toolexeclibdir=$toolexeclibdir/`$CC -print-multi-os-directory`
+
+
++if test -z "$with_cross_host"; then
++ USE_LIBDIR_TRUE=
++ USE_LIBDIR_FALSE='#'
++else
++ USE_LIBDIR_TRUE='#'
++ USE_LIBDIR_FALSE=
++fi
+
+ if test "${multilib}" = "yes"; then
+ multilib_arg="--enable-multilib"
+@@ -3307,14 +3313,16 @@
+ s%@LIBTOOL@%$LIBTOOL%g
+ s%@CXXCPP@%$CXXCPP%g
+ s%@THREADLIBS@%$THREADLIBS%g
++s%@POWERPC_DARWIN_TRUE@%$POWERPC_DARWIN_TRUE%g
++s%@POWERPC_DARWIN_FALSE@%$POWERPC_DARWIN_FALSE%g
+ s%@EXTRA_TEST_LIBS@%$EXTRA_TEST_LIBS%g
+ s%@target_all@%$target_all%g
+ s%@INCLUDES@%$INCLUDES%g
+ s%@CXXINCLUDES@%$CXXINCLUDES%g
+ s%@addobjs@%$addobjs%g
+ s%@MY_CFLAGS@%$MY_CFLAGS%g
+-s%@toolexecdir@%$toolexecdir%g
+-s%@toolexeclibdir@%$toolexeclibdir%g
++s%@USE_LIBDIR_TRUE@%$USE_LIBDIR_TRUE%g
++s%@USE_LIBDIR_FALSE@%$USE_LIBDIR_FALSE%g
+
+ CEOF
+ EOF
+@@ -3323,7 +3331,7 @@
+
+ # Split the substitutions into bite-sized pieces for seds with
+ # small command number limits, like on Digital OSF/1 and HP-UX.
+-ac_max_sed_cmds=60 # Maximum number of lines to put in a sed script.
++ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ ac_file=1 # Number of current file.
+ ac_beg=1 # First line for current file.
+ ac_end=$ac_max_sed_cmds # Line after last line for current file.
+@@ -3425,7 +3433,6 @@
+ CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
+ gc_basedir=${gc_basedir}
+ CC="${CC}"
+-ORIGINAL_LD_FOR_MULTILIBS="${ORIGINAL_LD_FOR_MULTILIBS}"
+ DEFS="$DEFS"
+
+ EOF
+diff -buNr boehm-gc/configure.in boehm-gc/configure.in
+--- boehm-gc/configure.in Mon Apr 28 13:55:07 2003
++++ boehm-gc/configure.in Sat Sep 13 02:10:15 2003
+@@ -1,4 +1,4 @@
+-# Copyright (c) 1999, 2000, 2001, 2002, 2003 by Red Hat, Inc. All rights reserved.
++# Copyright (c) 1999, 2000, 2001, 2002 by Red Hat, Inc. All rights reserved.
+ #
+ # THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
+ # OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
+@@ -111,14 +111,18 @@
+ *-*-cygwin*)
+ THREADLIBS=
+ ;;
++ *-*-darwin*)
++ AC_DEFINE(GC_DARWIN_THREADS)
++ AC_DEFINE(THREAD_LOCAL_ALLOC)
++ if test "${enable_parallel_mark}" = yes; then
++ AC_DEFINE(PARALLEL_MARK)
++ fi
++ ;;
+ esac
+ ;;
+ win32)
+ AC_DEFINE(GC_WIN32_THREADS)
+ AC_DEFINE(NO_GETENV)
+- if test $enable_shared = yes; then
+- AC_DEFINE(GC_DLL)
+- fi
+ ;;
+ decosf1 | irix | mach | os2 | solaris | dce | vxworks)
+ AC_MSG_ERROR(thread package $THREADS not yet supported)
+@@ -129,7 +133,22 @@
+ esac
+ AC_SUBST(THREADLIBS)
+
+-AC_CHECK_LIB(dl, dlopen, EXTRA_TEST_LIBS="$EXTRA_TEST_LIBS -ldl")
++case "$host" in
++ powerpc-*-darwin*)
++ powerpc_darwin=true
++ ;;
++esac
++AM_CONDITIONAL(POWERPC_DARWIN,test x$powerpc_darwin = xtrue)
++
++# We never want libdl on darwin. It is a fake libdl that just ends up making
++# dyld calls anyway
++case "$host" in
++ *-*-darwin*) ;;
++ *)
++ AC_CHECK_LIB(dl, dlopen, EXTRA_TEST_LIBS="$EXTRA_TEST_LIBS -ldl")
++ ;;
++esac
++
+ AC_SUBST(EXTRA_TEST_LIBS)
+
+ target_all=libgcjgc.la
+@@ -270,17 +289,7 @@
+ esac ]
+ fi)
+
+-if test -n "$with_cross_host" &&
+- test x"$with_cross_host" != x"no"; then
+- toolexecdir='$(exec_prefix)/$(target_alias)'
+- toolexeclibdir='$(toolexecdir)/lib'
+-else
+- toolexecdir='$(libdir)/gcc-lib/$(target_alias)'
+- toolexeclibdir='$(libdir)'
+-fi
+-toolexeclibdir=$toolexeclibdir/`$CC -print-multi-os-directory`
+-AC_SUBST(toolexecdir)
+-AC_SUBST(toolexeclibdir)
++AM_CONDITIONAL(USE_LIBDIR, test -z "$with_cross_host")
+
+ if test "${multilib}" = "yes"; then
+ multilib_arg="--enable-multilib"
+@@ -304,6 +313,5 @@
+ CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
+ gc_basedir=${gc_basedir}
+ CC="${CC}"
+-ORIGINAL_LD_FOR_MULTILIBS="${ORIGINAL_LD_FOR_MULTILIBS}"
+ DEFS="$DEFS"
+ )
+diff -buNr boehm-gc/configure.in~ boehm-gc/configure.in~
+--- boehm-gc/configure.in~ Wed Dec 31 16:00:00 1969
++++ boehm-gc/configure.in~ Sat Sep 13 02:10:15 2003
+@@ -0,0 +1,317 @@
++# Copyright (c) 1999, 2000, 2001, 2002 by Red Hat, Inc. All rights reserved.
++#
++# THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
++# OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
++#
++# Permission is hereby granted to use or copy this program
++# for any purpose, provided the above notices are retained on all copies.
++# Permission to modify the code and to distribute modified code is granted,
++# provided the above notices are retained, and a notice that the code was
++# modified is included with the above copyright notice.
++#
++# Original author: Tom Tromey
++
++dnl Process this file with autoconf to produce configure.
++
++AC_INIT(gcj_mlc.c)
++
++# This works around the fact that libtool configuration may change LD
++# for this particular configuration, but some shells, instead of
++# keeping the changes in LD private, export them just because LD is
++# exported.
++ORIGINAL_LD_FOR_MULTILIBS=$LD
++
++dnl Can't be done in GC_CONFIGURE because that confuses automake.
++AC_CONFIG_AUX_DIR(.)
++
++GC_CONFIGURE(.)
++
++AM_PROG_LIBTOOL
++
++dnl We use these options to decide which functions to include.
++AC_ARG_WITH(target-subdir,
++[ --with-target-subdir=SUBDIR
++ configuring with a cross compiler])
++AC_ARG_WITH(cross-host,
++[ --with-cross-host=HOST configuring with a cross compiler])
++
++AM_MAINTAINER_MODE
++# automake wants to see AC_EXEEXT. But we don't need it. And having
++# it is actually a problem, because the compiler we're passed can't
++# necessarily do a full link. So we fool automake here.
++if false; then
++ # autoconf 2.50 runs AC_EXEEXT by default, and the macro expands
++ # to nothing, so nothing would remain between `then' and `fi' if it
++ # were not for the `:' below.
++ :
++ AC_EXEEXT
++fi
++
++AC_MSG_CHECKING([for thread model used by GCC])
++THREADS=`$CC -v 2>&1 | sed -n 's/^Thread model: //p'`
++if test -z "$THREADS"; then
++ THREADS=no
++fi
++AC_MSG_RESULT([$THREADS])
++
++AC_ARG_ENABLE(parallel-mark,
++[ --enable-parallel-mark parallelize marking and free list construction],
++ [case "$THREADS" in
++ no | none | single)
++ AC_MSG_ERROR([Parallel mark requires --enable-threads=x spec])
++ ;;
++ esac]
++)
++
++INCLUDES=-I${srcdir}/include
++THREADLIBS=
++case "$THREADS" in
++ no | none | single)
++ THREADS=none
++ ;;
++ posix | pthreads)
++ THREADS=posix
++ THREADLIBS=-lpthread
++ case "$host" in
++ x86-*-linux* | ia64-*-linux* | i586-*-linux* | i686-*-linux* | x86_64-*-linux* )
++ AC_DEFINE(GC_LINUX_THREADS)
++ AC_DEFINE(_REENTRANT)
++ if test "${enable_parallel_mark}"; then
++ AC_DEFINE(PARALLEL_MARK)
++ fi
++ AC_DEFINE(THREAD_LOCAL_ALLOC)
++ ;;
++ *-*-linux*)
++ AC_DEFINE(GC_LINUX_THREADS)
++ AC_DEFINE(_REENTRANT)
++ ;;
++ *-*-hpux*)
++ AC_MSG_WARN("Only HP/UX 11 threads are supported.")
++ AC_DEFINE(GC_HPUX_THREADS)
++ AC_DEFINE(_POSIX_C_SOURCE,199506L)
++ if test "${enable_parallel_mark}" = yes; then
++ AC_DEFINE(PARALLEL_MARK)
++ fi
++ AC_DEFINE(THREAD_LOCAL_ALLOC)
++ THREADLIBS="-lpthread -lrt"
++ ;;
++ *-*-freebsd*)
++ AC_MSG_WARN("FreeBSD does not yet fully support threads with Boehm GC.")
++ AC_DEFINE(GC_FREEBSD_THREADS)
++ INCLUDES="$INCLUDES -pthread"
++ THREADLIBS=-pthread
++ ;;
++ *-*-solaris*)
++ AC_DEFINE(GC_SOLARIS_THREADS)
++ AC_DEFINE(GC_SOLARIS_PTHREADS)
++ ;;
++ *-*-irix*)
++ AC_DEFINE(GC_IRIX_THREADS)
++ ;;
++ *-*-cygwin*)
++ THREADLIBS=
++ ;;
++ esac
++ ;;
++ *-*-darwin*)
++ AC_DEFINE(GC_DARWIN_THREADS)
++ AC_DEFINE(THREAD_LOCAL_ALLOC)
++ if test "${enable_parallel_mark}" = yes; then
++ AC_DEFINE(PARALLEL_MARK)
++ fi
++ ;;
++ win32)
++ AC_DEFINE(GC_WIN32_THREADS)
++ AC_DEFINE(NO_GETENV)
++ ;;
++ decosf1 | irix | mach | os2 | solaris | dce | vxworks)
++ AC_MSG_ERROR(thread package $THREADS not yet supported)
++ ;;
++ *)
++ AC_MSG_ERROR($THREADS is an unknown thread package)
++ ;;
++esac
++AC_SUBST(THREADLIBS)
++
++case "$host" in
++ powerpc-*-darwin*)
++ powerpc_darwin=true
++ ;;
++esac
++AM_CONDITIONAL(POWERPC_DARWIN,test x$powerpc_darwin = xtrue)
++
++# We never want libdl on darwin. It is a fake libdl that just ends up making
++# dyld calls anyway
++case "$host" in
++ *-*-darwin*) ;;
++ *)
++ AC_CHECK_LIB(dl, dlopen, EXTRA_TEST_LIBS="$EXTRA_TEST_LIBS -ldl")
++ ;;
++esac
++
++AC_SUBST(EXTRA_TEST_LIBS)
++
++target_all=libgcjgc.la
++AC_SUBST(target_all)
++AC_SUBST(target_alias)
++
++dnl If the target is an eCos system, use the appropriate eCos
++dnl I/O routines.
++dnl FIXME: this should not be a local option but a global target
++dnl system; at present there is no eCos target.
++TARGET_ECOS="no"
++AC_ARG_WITH(ecos,
++[ --with-ecos enable runtime eCos target support],
++TARGET_ECOS="$with_ecos"
++)
++
++addobjs=
++CXXINCLUDES=
++case "$TARGET_ECOS" in
++ no)
++ ;;
++ *)
++ AC_DEFINE(ECOS)
++ CXXINCLUDES="-I${TARGET_ECOS}/include"
++ addobjs="$addobjs ecos.lo"
++ ;;
++esac
++AC_SUBST(CXX)
++
++AC_SUBST(INCLUDES)
++AC_SUBST(CXXINCLUDES)
++
++machdep=
++case "$host" in
++ alpha*-*-openbsd*)
++ machdep="alpha_mach_dep.lo"
++ if test x"${ac_cv_lib_dl_dlopen}" != xyes ; then
++ AC_MSG_WARN(OpenBSD/Alpha without dlopen(). Shared library support is disabled)
++ AM_DISABLE_SHARED
++ fi
++ ;;
++ alpha*-*-*)
++ machdep="alpha_mach_dep.lo"
++ ;;
++ i?86-*-solaris2.[[89]]*)
++ AC_DEFINE(SOLARIS25_PROC_VDB_BUG_FIXED)
++ ;;
++ mipstx39-*-elf*)
++ machdep="mips_ultrix_mach_dep.lo"
++ AC_DEFINE(STACKBASE, __stackbase)
++ AC_DEFINE(DATASTART_IS_ETEXT)
++ ;;
++ mips-dec-ultrix*)
++ machdep="mips_ultrix_mach-dep.lo"
++ ;;
++ mips*-*-linux*)
++ ;;
++ mips-*-*)
++ machdep="mips_sgi_mach_dep.lo"
++ AC_DEFINE(NO_EXECUTE_PERMISSION)
++ ;;
++ sparc-sun-solaris2.3*)
++ machdep="sparc_mach_dep.lo"
++ AC_DEFINE(SUNOS53_SHARED_LIB)
++ ;;
++ sparc-sun-solaris2.*)
++ machdep="sparc_mach_dep.lo"
++ ;;
++ ia64-*-*)
++ machdep="mach_dep.lo ia64_save_regs_in_stack.lo"
++ ;;
++esac
++if test x"$machdep" = x; then
++ machdep="mach_dep.lo"
++fi
++addobjs="$addobjs $machdep"
++AC_SUBST(addobjs)
++
++dnl As of 4.13a2, the collector will not properly work on Solaris when
++dnl built with gcc and -O. So we remove -O in the appropriate case.
++case "$host" in
++ sparc-sun-solaris2*)
++ if test "$GCC" = yes; then
++ new_CFLAGS=
++ for i in $CFLAGS; do
++ case "$i" in
++ -O*)
++ ;;
++ *)
++ new_CFLAGS="$new_CFLAGS $i"
++ ;;
++ esac
++ done
++ CFLAGS="$new_CFLAGS"
++ fi
++ ;;
++esac
++
++dnl We need to override the top-level CFLAGS. This is how we do it.
++MY_CFLAGS="$CFLAGS"
++AC_SUBST(MY_CFLAGS)
++
++dnl Include defines that have become de facto standard.
++dnl ALL_INTERIOR_POINTERS can be overridden in startup code.
++AC_DEFINE(SILENT)
++AC_DEFINE(NO_SIGNALS)
++AC_DEFINE(NO_EXECUTE_PERMISSION)
++AC_DEFINE(ALL_INTERIOR_POINTERS)
++
++dnl By default, make the library as general as possible.
++AC_DEFINE(JAVA_FINALIZATION)
++AC_DEFINE(GC_GCJ_SUPPORT)
++AC_DEFINE(ATOMIC_UNCOLLECTABLE)
++
++dnl This is something of a hack. When cross-compiling we turn off
++dnl some functionality. These is only correct when targetting an
++dnl embedded system. FIXME.
++if test -n "${with_cross_host}"; then
++ AC_DEFINE(NO_SIGSET)
++ AC_DEFINE(NO_DEBUGGING)
++fi
++
++AC_ARG_ENABLE(full-debug,
++[ --enable-full-debug include full support for pointer backtracing etc.],
++[ if test "$enable_full_debug" = "yes"; then
++ AC_MSG_WARN("Must define GC_DEBUG and use debug alloc. in clients.")
++ AC_DEFINE(KEEP_BACK_PTRS)
++ AC_DEFINE(DBG_HDRS_ALL)
++ case $host in
++ ia64-*-linux* )
++ AC_DEFINE(MAKE_BACK_GRAPH)
++ ;;
++ x86-*-linux* | i586-*-linux* | i686-*-linux* | x86_64-*-linux* )
++ AC_DEFINE(MAKE_BACK_GRAPH)
++ AC_MSG_WARN("Client must not use -fomit-frame-pointer.")
++ AC_DEFINE(SAVE_CALL_COUNT, 8)
++ ;;
++ esac ]
++ fi)
++
++AM_CONDITIONAL(USE_LIBDIR, test -z "$with_cross_host")
++
++if test "${multilib}" = "yes"; then
++ multilib_arg="--enable-multilib"
++else
++ multilib_arg=
++fi
++
++AC_OUTPUT(Makefile include/Makefile, [
++dnl Put all the -D options in a file.
++echo "$DEFS" > boehm-cflags
++
++if test -n "$CONFIG_FILES"; then
++ LD="${ORIGINAL_LD_FOR_MULTILIBS}"
++ ac_file=Makefile . ${gc_basedir}/../config-ml.in
++fi],
++srcdir=${srcdir}
++host=${host}
++target=${target}
++with_multisubdir=${with_multisubdir}
++ac_configure_args="${multilib_arg} ${ac_configure_args}"
++CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
++gc_basedir=${gc_basedir}
++CC="${CC}"
++DEFS="$DEFS"
++)
+diff -buNr boehm-gc/darwin_stop_world.c boehm-gc/darwin_stop_world.c
+--- boehm-gc/darwin_stop_world.c Wed Dec 31 16:00:00 1969
++++ boehm-gc/darwin_stop_world.c Sat Sep 13 02:10:15 2003
+@@ -0,0 +1,200 @@
++#include "private/pthread_support.h"
++
++# if defined(GC_DARWIN_THREADS)
++
++#define DEBUG_THREADS 0
++
++/* From "Inside Mac OS X - Mach-O Runtime Architecture" published by Apple
++ Page 49:
++ "The space beneath the stack pointer, where a new stack frame would normally
++ be allocated, is called the red zone. This area as shown in Figure 3-2 may
++ be used for any purpose as long as a new stack frame does not need to be
++ added to the stack."
++
++ Page 50: "If a leaf procedure's red zone usage would exceed 224 bytes, then
++ it must set up a stack frame just like routines that call other routines."
++*/
++#define PPC_RED_ZONE_SIZE 224
++
++void GC_push_all_stacks() {
++ int i;
++ kern_return_t r;
++ GC_thread p;
++ pthread_t me;
++ ptr_t lo, hi;
++# if defined(POWERPC)
++ ppc_thread_state_t state;
++# else
++# error FIXME for non-ppc OS X
++# endif
++ mach_msg_type_number_t thread_state_count = MACHINE_THREAD_STATE_COUNT;
++
++ me = pthread_self();
++ if (!GC_thr_initialized) GC_thr_init();
++
++ for(i=0;i<THREAD_TABLE_SZ;i++) {
++ for(p=GC_threads[i];p!=0;p=p->next) {
++ if(p -> flags & FINISHED) continue;
++ if(pthread_equal(p->id,me)) {
++ lo = GC_approx_sp();
++ } else {
++ /* Get the thread state (registers, etc) */
++ r = thread_get_state(
++ p->stop_info.mach_thread,
++ MACHINE_THREAD_STATE,
++ (natural_t*)&state,
++ &thread_state_count);
++ if(r != KERN_SUCCESS) ABORT("thread_get_state failed");
++
++ #ifdef POWERPC
++ lo = (void*)(state.r1 - PPC_RED_ZONE_SIZE);
++
++ GC_push_one(state.r0);
++ GC_push_one(state.r2);
++ GC_push_one(state.r3);
++ GC_push_one(state.r4);
++ GC_push_one(state.r5);
++ GC_push_one(state.r6);
++ GC_push_one(state.r7);
++ GC_push_one(state.r8);
++ GC_push_one(state.r9);
++ GC_push_one(state.r10);
++ GC_push_one(state.r11);
++ GC_push_one(state.r12);
++ GC_push_one(state.r13);
++ GC_push_one(state.r14);
++ GC_push_one(state.r15);
++ GC_push_one(state.r16);
++ GC_push_one(state.r17);
++ GC_push_one(state.r18);
++ GC_push_one(state.r19);
++ GC_push_one(state.r20);
++ GC_push_one(state.r21);
++ GC_push_one(state.r22);
++ GC_push_one(state.r23);
++ GC_push_one(state.r24);
++ GC_push_one(state.r25);
++ GC_push_one(state.r26);
++ GC_push_one(state.r27);
++ GC_push_one(state.r28);
++ GC_push_one(state.r29);
++ GC_push_one(state.r30);
++ GC_push_one(state.r31);
++ #else
++ # error FIXME for non-PPC darwin
++ #endif /* !POWERPC */
++ } /* p != me */
++ if(p->flags & MAIN_THREAD)
++ hi = GC_stackbottom;
++ else
++ hi = p->stack_end;
++ #if DEBUG_THREADS
++ GC_printf3("Darwin: Stack for thread 0x%lx = [%lx,%lx)\n",
++ (unsigned long) p -> id,
++ (unsigned long) lo,
++ (unsigned long) hi
++ );
++ #endif
++ GC_push_all_stack(lo,hi);
++ } /* for(p=GC_threads[i]...) */
++ } /* for(i=0;i<THREAD_TABLE_SZ...) */
++}
++
++/* Caller holds allocation lock. */
++void GC_stop_world()
++{
++ int i;
++ GC_thread p;
++ pthread_t my_thread = pthread_self();
++ kern_return_t kern_result;
++
++ #if DEBUG_THREADS
++ GC_printf1("Stopping the world from 0x%lx\n", pthread_self());
++ #endif
++
++ /* Make sure all free list construction has stopped before we start. */
++ /* No new construction can start, since free list construction is */
++ /* required to acquire and release the GC lock before it starts, */
++ /* and we have the lock. */
++# ifdef PARALLEL_MARK
++ GC_acquire_mark_lock();
++ GC_ASSERT(GC_fl_builder_count == 0);
++ /* We should have previously waited for it to become zero. */
++# endif /* PARALLEL_MARK */
++
++ for (i = 0; i < THREAD_TABLE_SZ; i++) {
++ for (p = GC_threads[i]; p != 0; p = p -> next) {
++ if (p -> id == my_thread) continue;
++ if (p -> flags & FINISHED) continue;
++ if (p -> thread_blocked) /* Will wait */ continue;
++
++ #if DEBUG_THREADS
++ GC_printf1("Suspending thread 0x%lx\n", p -> id);
++ #endif
++
++ /* Suspend the thread */
++ kern_result = thread_suspend(p->stop_info.mach_thread);
++ if(kern_result != KERN_SUCCESS) ABORT("thread_suspend failed");
++ }
++ }
++
++# ifdef MPROTECT_VDB
++ if(GC_incremental) {
++ extern void GC_mprotect_stop();
++ GC_mprotect_stop();
++ }
++# endif
++
++# ifdef PARALLEL_MARK
++ GC_release_mark_lock();
++# endif
++ #if DEBUG_THREADS
++ GC_printf1("World stopped from 0x%lx\n", pthread_self());
++ #endif
++}
++
++/* Caller holds allocation lock, and has held it continuously since */
++/* the world stopped. */
++void GC_start_world()
++{
++ pthread_t my_thread = pthread_self();
++ int i;
++ GC_thread p;
++ kern_return_t kern_result;
++
++# if DEBUG_THREADS
++ GC_printf0("World starting\n");
++# endif
++
++# ifdef MPROTECT_VDB
++ if(GC_incremental) {
++ extern void GC_mprotect_resume();
++ GC_mprotect_resume();
++ }
++# endif
++
++ for (i = 0; i < THREAD_TABLE_SZ; i++) {
++ for (p = GC_threads[i]; p != 0; p = p -> next) {
++ if (p -> id == my_thread) continue;
++ if (p -> flags & FINISHED) continue;
++ if (p -> thread_blocked) continue;
++
++ #if DEBUG_THREADS
++ GC_printf1("Resuming 0x%lx\n", p -> id);
++ #endif
++
++ /* Resume the thread */
++ kern_result = thread_resume(p->stop_info.mach_thread);
++ if(kern_result != KERN_SUCCESS) ABORT("thread_resume failed");
++ }
++ }
++ #if DEBUG_THREADS
++ GC_printf0("World started\n");
++ #endif
++}
++
++void GC_stop_init() {
++
++}
++
++#endif
+diff -buNr boehm-gc/dbg_mlc.c boehm-gc/dbg_mlc.c
+--- boehm-gc/dbg_mlc.c Tue Feb 12 21:38:39 2002
++++ boehm-gc/dbg_mlc.c Sat Sep 13 02:10:15 2003
+@@ -60,7 +60,7 @@
+ # include <stdlib.h>
+
+ # if defined(LINUX) || defined(SUNOS4) || defined(SUNOS5) \
+- || defined(HPUX) || defined(IRIX) || defined(OSF1)
++ || defined(HPUX) || defined(IRIX5) || defined(OSF1)
+ # define RANDOM() random()
+ # else
+ # define RANDOM() (long)rand()
+@@ -228,6 +228,8 @@
+
+ #endif /* KEEP_BACK_PTRS */
+
++# define CROSSES_HBLK(p, sz) \
++ (((word)(p + sizeof(oh) + sz - 1) ^ (word)p) >= HBLKSIZE)
+ /* Store debugging info into p. Return displaced pointer. */
+ /* Assumes we don't hold allocation lock. */
+ ptr_t GC_store_debug_info(p, sz, string, integer)
+@@ -243,6 +245,8 @@
+ /* But that's expensive. And this way things should only appear */
+ /* inconsistent while we're in the handler. */
+ LOCK();
++ GC_ASSERT(GC_size(p) >= sizeof(oh) + sz);
++ GC_ASSERT(!(SMALL_OBJ(sz) && CROSSES_HBLK(p, sz)));
+ # ifdef KEEP_BACK_PTRS
+ ((oh *)p) -> oh_back_ptr = HIDE_BACK_PTR(NOT_MARKED);
+ # endif
+@@ -275,6 +279,8 @@
+ /* There is some argument that we should disable signals here. */
+ /* But that's expensive. And this way things should only appear */
+ /* inconsistent while we're in the handler. */
++ GC_ASSERT(GC_size(p) >= sizeof(oh) + sz);
++ GC_ASSERT(!(SMALL_OBJ(sz) && CROSSES_HBLK(p, sz)));
+ # ifdef KEEP_BACK_PTRS
+ ((oh *)p) -> oh_back_ptr = HIDE_BACK_PTR(NOT_MARKED);
+ # endif
+@@ -324,10 +330,11 @@
+ {
+ register oh * ohdr = (oh *)GC_base(p);
+
++ GC_ASSERT(!I_HOLD_LOCK());
+ GC_err_printf1("0x%lx (", ((unsigned long)ohdr + sizeof(oh)));
+ GC_err_puts(ohdr -> oh_string);
+ # ifdef SHORT_DBG_HDRS
+- GC_err_printf1(":%ld, sz=%ld)\n", (unsigned long)(ohdr -> oh_int));
++ GC_err_printf1(":%ld)\n", (unsigned long)(ohdr -> oh_int));
+ # else
+ GC_err_printf2(":%ld, sz=%ld)\n", (unsigned long)(ohdr -> oh_int),
+ (unsigned long)(ohdr -> oh_sz));
+@@ -342,6 +349,7 @@
+ ptr_t p;
+ # endif
+ {
++ GC_ASSERT(!I_HOLD_LOCK());
+ if (GC_HAS_DEBUG_INFO(p)) {
+ GC_print_obj(p);
+ } else {
+@@ -355,6 +363,7 @@
+ {
+ register oh * ohdr = (oh *)GC_base(p);
+
++ GC_ASSERT(!I_HOLD_LOCK());
+ GC_err_printf2("0x%lx in object at 0x%lx(", (unsigned long)clobbered_addr,
+ (unsigned long)p);
+ if (clobbered_addr <= (ptr_t)(&(ohdr -> oh_sz))
+@@ -376,14 +385,18 @@
+
+ void GC_check_heap_proc GC_PROTO((void));
+
++void GC_print_all_smashed_proc GC_PROTO((void));
++
+ void GC_do_nothing() {}
+
+ void GC_start_debugging()
+ {
+ # ifndef SHORT_DBG_HDRS
+ GC_check_heap = GC_check_heap_proc;
++ GC_print_all_smashed = GC_print_all_smashed_proc;
+ # else
+ GC_check_heap = GC_do_nothing;
++ GC_print_all_smashed = GC_do_nothing;
+ # endif
+ GC_print_heap_obj = GC_debug_print_heap_obj_proc;
+ GC_debugging_started = TRUE;
+@@ -429,6 +442,62 @@
+ return (GC_store_debug_info(result, (word)lb, s, (word)i));
+ }
+
++# ifdef __STDC__
++ GC_PTR GC_debug_malloc_ignore_off_page(size_t lb, GC_EXTRA_PARAMS)
++# else
++ GC_PTR GC_debug_malloc_ignore_off_page(lb, s, i)
++ size_t lb;
++ char * s;
++ int i;
++# ifdef GC_ADD_CALLER
++ --> GC_ADD_CALLER not implemented for K&R C
++# endif
++# endif
++{
++ GC_PTR result = GC_malloc_ignore_off_page(lb + DEBUG_BYTES);
++
++ if (result == 0) {
++ GC_err_printf1("GC_debug_malloc_ignore_off_page(%ld) returning NIL (",
++ (unsigned long) lb);
++ GC_err_puts(s);
++ GC_err_printf1(":%ld)\n", (unsigned long)i);
++ return(0);
++ }
++ if (!GC_debugging_started) {
++ GC_start_debugging();
++ }
++ ADD_CALL_CHAIN(result, ra);
++ return (GC_store_debug_info(result, (word)lb, s, (word)i));
++}
++
++# ifdef __STDC__
++ GC_PTR GC_debug_malloc_atomic_ignore_off_page(size_t lb, GC_EXTRA_PARAMS)
++# else
++ GC_PTR GC_debug_malloc_atomic_ignore_off_page(lb, s, i)
++ size_t lb;
++ char * s;
++ int i;
++# ifdef GC_ADD_CALLER
++ --> GC_ADD_CALLER not implemented for K&R C
++# endif
++# endif
++{
++ GC_PTR result = GC_malloc_atomic_ignore_off_page(lb + DEBUG_BYTES);
++
++ if (result == 0) {
++ GC_err_printf1("GC_debug_malloc_atomic_ignore_off_page(%ld)"
++ " returning NIL (", (unsigned long) lb);
++ GC_err_puts(s);
++ GC_err_printf1(":%ld)\n", (unsigned long)i);
++ return(0);
++ }
++ if (!GC_debugging_started) {
++ GC_start_debugging();
++ }
++ ADD_CALL_CHAIN(result, ra);
++ return (GC_store_debug_info(result, (word)lb, s, (word)i));
++}
++
+ # ifdef DBG_HDRS_ALL
+ /*
+ * An allocation function for internal use.
+@@ -447,7 +516,7 @@
+ (unsigned long) lb);
+ return(0);
+ }
+- ADD_CALL_CHAIN(result, ra);
++ ADD_CALL_CHAIN(result, GC_RETURN_ADDR);
+ return (GC_store_debug_info_inner(result, (word)lb, "INTERNAL", (word)0));
+ }
+
+@@ -461,7 +530,7 @@
+ (unsigned long) lb);
+ return(0);
+ }
+- ADD_CALL_CHAIN(result, ra);
++ ADD_CALL_CHAIN(result, GC_RETURN_ADDR);
+ return (GC_store_debug_info_inner(result, (word)lb, "INTERNAL", (word)0));
+ }
+ # endif
+@@ -592,7 +661,7 @@
+ int i;
+ # endif
+ {
+- GC_PTR result = GC_malloc_uncollectable(lb + DEBUG_BYTES);
++ GC_PTR result = GC_malloc_uncollectable(lb + UNCOLLECTABLE_DEBUG_BYTES);
+
+ if (result == 0) {
+ GC_err_printf1("GC_debug_malloc_uncollectable(%ld) returning NIL (",
+@@ -618,7 +687,8 @@
+ int i;
+ # endif
+ {
+- GC_PTR result = GC_malloc_atomic_uncollectable(lb + DEBUG_BYTES);
++ GC_PTR result =
++ GC_malloc_atomic_uncollectable(lb + UNCOLLECTABLE_DEBUG_BYTES);
+
+ if (result == 0) {
+ GC_err_printf1(
+@@ -774,6 +844,45 @@
+ }
+
+ #ifndef SHORT_DBG_HDRS
++
++/* List of smashed objects. We defer printing these, since we can't */
++/* always print them nicely with the allocation lock held. */
++/* We put them here instead of in GC_arrays, since it may be useful to */
++/* be able to look at them with the debugger. */
++#define MAX_SMASHED 20
++ptr_t GC_smashed[MAX_SMASHED];
++unsigned GC_n_smashed = 0;
++
++# if defined(__STDC__) || defined(__cplusplus)
++ void GC_add_smashed(ptr_t smashed)
++# else
++ void GC_add_smashed(smashed)
++ ptr_t smashed;
++#endif
++{
++ GC_ASSERT(GC_is_marked(GC_base(smashed)));
++ GC_smashed[GC_n_smashed] = smashed;
++ if (GC_n_smashed < MAX_SMASHED - 1) ++GC_n_smashed;
++ /* In case of overflow, we keep the first MAX_SMASHED-1 */
++ /* entries plus the last one. */
++ GC_have_errors = TRUE;
++}
++
++/* Print all objects on the list. Clear the list. */
++void GC_print_all_smashed_proc ()
++{
++ unsigned i;
++
++ GC_ASSERT(!I_HOLD_LOCK());
++ if (GC_n_smashed == 0) return;
++ GC_err_printf0("GC_check_heap_block: found smashed heap objects:\n");
++ for (i = 0; i < GC_n_smashed; ++i) {
++ GC_print_smashed_obj(GC_base(GC_smashed[i]), GC_smashed[i]);
++ GC_smashed[i] = 0;
++ }
++ GC_n_smashed = 0;
++}
++
+ /* Check all marked objects in the given block for validity */
+ /*ARGSUSED*/
+ # if defined(__STDC__) || defined(__cplusplus)
+@@ -802,11 +911,7 @@
+ && GC_HAS_DEBUG_INFO((ptr_t)p)) {
+ ptr_t clobbered = GC_check_annotated_obj((oh *)p);
+
+- if (clobbered != 0) {
+- GC_err_printf0(
+- "GC_check_heap_block: found smashed location at ");
+- GC_print_smashed_obj((ptr_t)p, clobbered);
+- }
++ if (clobbered != 0) GC_add_smashed(clobbered);
+ }
+ word_no += sz;
+ p += sz;
+@@ -819,9 +924,11 @@
+ void GC_check_heap_proc()
+ {
+ # ifndef SMALL_CONFIG
+- if (sizeof(oh) & (2 * sizeof(word) - 1) != 0) {
+- ABORT("Alignment problem: object header has inappropriate size\n");
+- }
++# ifdef ALIGN_DOUBLE
++ GC_STATIC_ASSERT((sizeof(oh) & (2 * sizeof(word) - 1)) == 0);
++# else
++ GC_STATIC_ASSERT((sizeof(oh) & (sizeof(word) - 1)) == 0);
++# endif
+ # endif
+ GC_apply_to_all_blocks(GC_check_heap_block, (word)0);
+ }
+@@ -908,7 +1015,7 @@
+ ptr_t base = GC_base(obj);
+ if (0 == base || (ptr_t)obj - base != sizeof(oh)) {
+ GC_err_printf1(
+- "GC_register_finalizer called with non-base-pointer 0x%lx\n",
++ "GC_debug_register_finalizer called with non-base-pointer 0x%lx\n",
+ obj);
+ }
+ if (0 == fn) {
+@@ -940,7 +1047,7 @@
+ ptr_t base = GC_base(obj);
+ if (0 == base || (ptr_t)obj - base != sizeof(oh)) {
+ GC_err_printf1(
+- "GC_register_finalizer_no_order called with non-base-pointer 0x%lx\n",
++ "GC_debug_register_finalizer_no_order called with non-base-pointer 0x%lx\n",
+ obj);
+ }
+ if (0 == fn) {
+@@ -973,7 +1080,7 @@
+ ptr_t base = GC_base(obj);
+ if (0 == base || (ptr_t)obj - base != sizeof(oh)) {
+ GC_err_printf1(
+- "GC_register_finalizer_ignore_self called with non-base-pointer 0x%lx\n",
++ "GC_debug_register_finalizer_ignore_self called with non-base-pointer 0x%lx\n",
+ obj);
+ }
+ if (0 == fn) {
+diff -buNr boehm-gc/dyn_load.c boehm-gc/dyn_load.c
+--- boehm-gc/dyn_load.c Mon Mar 3 22:38:30 2003
++++ boehm-gc/dyn_load.c Sun Sep 14 19:37:09 2003
+@@ -1,3 +1,4 @@
++#define __private_extern__
+ /*
+ * Copyright (c) 1991-1994 by Xerox Corporation. All rights reserved.
+ * Copyright (c) 1997 by Silicon Graphics. All rights reserved.
+@@ -55,9 +56,10 @@
+ !defined(MSWIN32) && !defined(MSWINCE) && \
+ !(defined(ALPHA) && defined(OSF1)) && \
+ !defined(HPUX) && !(defined(LINUX) && defined(__ELF__)) && \
+- !defined(RS6000) && !defined(SCO_ELF) && \
++ !defined(RS6000) && !defined(SCO_ELF) && !defined(DGUX) && \
+ !(defined(FREEBSD) && defined(__ELF__)) && \
+- !(defined(NETBSD) && defined(__ELF__)) && !defined(HURD)
++ !(defined(NETBSD) && defined(__ELF__)) && !defined(HURD) && \
++ !defined(DARWIN)
+ --> We only know how to find data segments of dynamic libraries for the
+ --> above. Additional SVR4 variants might not be too
+ --> hard to add.
+@@ -80,7 +82,7 @@
+ #endif
+
+ #if defined(LINUX) && defined(__ELF__) || defined(SCO_ELF) || \
+- (defined(FREEBSD) && defined(__ELF__)) || \
++ (defined(FREEBSD) && defined(__ELF__)) || defined(DGUX) || \
+ (defined(NETBSD) && defined(__ELF__)) || defined(HURD)
+ # include <stddef.h>
+ # include <elf.h>
+@@ -264,7 +266,7 @@
+ # endif /* SUNOS */
+
+ #if defined(LINUX) && defined(__ELF__) || defined(SCO_ELF) || \
+- (defined(FREEBSD) && defined(__ELF__)) || \
++ (defined(FREEBSD) && defined(__ELF__)) || defined(DGUX) || \
+ (defined(NETBSD) && defined(__ELF__)) || defined(HURD)
+
+
+@@ -282,56 +284,23 @@
+ /* Repeatedly read until buffer is filled, or EOF is encountered */
+ /* Defined in os_dep.c. */
+
+-static char *parse_map_entry(char *buf_ptr, word *start, word *end,
++char *GC_parse_map_entry(char *buf_ptr, word *start, word *end,
+ char *prot_buf, unsigned int *maj_dev);
++word GC_apply_to_maps(word (*fn)(char *));
++ /* From os_dep.c */
+
+-void GC_register_dynamic_libraries()
++word GC_register_map_entries(char *maps)
+ {
+- int f;
+- int result;
+ char prot_buf[5];
+- int maps_size;
+- char maps_temp[32768];
+- char *maps_buf;
+- char *buf_ptr;
++ char *buf_ptr = maps;
+ int count;
+ word start, end;
+- unsigned int maj_dev, min_dev;
++ unsigned int maj_dev;
+ word least_ha, greatest_ha;
+ unsigned i;
+ word datastart = (word)(DATASTART);
+
+- /* Read /proc/self/maps */
+- /* Note that we may not allocate, and thus can't use stdio. */
+- f = open("/proc/self/maps", O_RDONLY);
+- if (-1 == f) ABORT("Couldn't open /proc/self/maps");
+- /* stat() doesn't work for /proc/self/maps, so we have to
+- read it to find out how large it is... */
+- maps_size = 0;
+- do {
+- result = GC_repeat_read(f, maps_temp, sizeof(maps_temp));
+- if (result <= 0) ABORT("Couldn't read /proc/self/maps");
+- maps_size += result;
+- } while (result == sizeof(maps_temp));
+-
+- if (maps_size > sizeof(maps_temp)) {
+- /* If larger than our buffer, close and re-read it. */
+- close(f);
+- f = open("/proc/self/maps", O_RDONLY);
+- if (-1 == f) ABORT("Couldn't open /proc/self/maps");
+- maps_buf = alloca(maps_size);
+- if (NULL == maps_buf) ABORT("/proc/self/maps alloca failed");
+- result = GC_repeat_read(f, maps_buf, maps_size);
+- if (result <= 0) ABORT("Couldn't read /proc/self/maps");
+- } else {
+- /* Otherwise use the fixed size buffer */
+- maps_buf = maps_temp;
+- }
+-
+- close(f);
+- maps_buf[result] = '\0';
+- buf_ptr = maps_buf;
+- /* Compute heap bounds. Should be done by add_to_heap? */
++ /* Compute heap bounds. FIXME: Should be done by add_to_heap? */
+ least_ha = (word)(-1);
+ greatest_ha = 0;
+ for (i = 0; i < GC_n_heap_sects; ++i) {
+@@ -342,11 +311,10 @@
+ }
+ if (greatest_ha < (word)GC_scratch_last_end_ptr)
+ greatest_ha = (word)GC_scratch_last_end_ptr;
+- for (;;) {
+-
+- buf_ptr = parse_map_entry(buf_ptr, &start, &end, prot_buf, &maj_dev);
+- if (buf_ptr == NULL) return;
+
++ for (;;) {
++ buf_ptr = GC_parse_map_entry(buf_ptr, &start, &end, prot_buf, &maj_dev);
++ if (buf_ptr == NULL) return 1;
+ if (prot_buf[1] == 'w') {
+ /* This is a writable mapping. Add it to */
+ /* the root set unless it is already otherwise */
+@@ -358,16 +326,7 @@
+ # ifdef THREADS
+ if (GC_segment_is_thread_stack(start, end)) continue;
+ # endif
+- /* The rest of this assumes that there is no mapping */
+- /* spanning the beginning of the data segment, or extending */
+- /* beyond the entire heap at both ends. */
+- /* Empirically these assumptions hold. */
+-
+- if (start < (word)DATAEND && end > (word)DATAEND) {
+- /* Rld may use space at the end of the main data */
+- /* segment. Thus we add that in. */
+- start = (word)DATAEND;
+- }
++ /* We no longer exclude the main data segment. */
+ if (start < least_ha && end > least_ha) {
+ end = least_ha;
+ }
+@@ -378,6 +337,13 @@
+ GC_add_roots_inner((char *)start, (char *)end, TRUE);
+ }
+ }
++ return 1;
++}
++
++void GC_register_dynamic_libraries()
++{
++ if (!GC_apply_to_maps(GC_register_map_entries))
++ ABORT("Failed to read /proc for library registration.");
+ }
+
+ /* We now take care of the main data segment ourselves: */
+@@ -387,60 +353,6 @@
+ }
+
+ # define HAVE_REGISTER_MAIN_STATIC_DATA
+-//
+-// parse_map_entry parses an entry from /proc/self/maps so we can
+-// locate all writable data segments that belong to shared libraries.
+-// The format of one of these entries and the fields we care about
+-// is as follows:
+-// XXXXXXXX-XXXXXXXX r-xp 00000000 30:05 260537 name of mapping...\n
+-// ^^^^^^^^ ^^^^^^^^ ^^^^ ^^
+-// start end prot maj_dev
+-// 0 9 18 32
+-//
+-// The parser is called with a pointer to the entry and the return value
+-// is either NULL or is advanced to the next entry(the byte after the
+-// trailing '\n'.)
+-//
+-#define OFFSET_MAP_START 0
+-#define OFFSET_MAP_END 9
+-#define OFFSET_MAP_PROT 18
+-#define OFFSET_MAP_MAJDEV 32
+-
+-static char *parse_map_entry(char *buf_ptr, word *start, word *end,
+- char *prot_buf, unsigned int *maj_dev)
+-{
+- int i;
+- unsigned int val;
+- char *tok;
+-
+- if (buf_ptr == NULL || *buf_ptr == '\0') {
+- return NULL;
+- }
+-
+- memcpy(prot_buf, buf_ptr+OFFSET_MAP_PROT, 4); // do the protections first
+- prot_buf[4] = '\0';
+-
+- if (prot_buf[1] == 'w') { // we can skip all of this if it's not writable
+-
+- tok = buf_ptr;
+- buf_ptr[OFFSET_MAP_START+8] = '\0';
+- *start = strtoul(tok, NULL, 16);
+-
+- tok = buf_ptr+OFFSET_MAP_END;
+- buf_ptr[OFFSET_MAP_END+8] = '\0';
+- *end = strtoul(tok, NULL, 16);
+-
+- buf_ptr += OFFSET_MAP_MAJDEV;
+- tok = buf_ptr;
+- while (*buf_ptr != ':') buf_ptr++;
+- *buf_ptr++ = '\0';
+- *maj_dev = strtoul(tok, NULL, 16);
+- }
+-
+- while (*buf_ptr && *buf_ptr++ != '\n');
+-
+- return buf_ptr;
+-}
+
+ #endif /* USE_PROC_FOR_LIBRARIES */
+
+@@ -508,6 +420,7 @@
+ GC_add_roots_inner(DATASTART2, (char *)(DATAEND2), TRUE);
+ # endif
+ }
++
+ return TRUE;
+ } else {
+ return FALSE;
+@@ -630,6 +543,7 @@
+ /* The type is a lie, since the real type doesn't make sense here, */
+ /* and we only test for NULL. */
+
++
+ /* We use /proc to track down all parts of the address space that are */
+ /* mapped by the process, and throw out regions we know we shouldn't */
+ /* worry about. This may also work under other SVR4 variants. */
+@@ -1056,7 +970,122 @@
+ }
+ #endif /* RS6000 */
+
++#ifdef DARWIN
++
++#include <mach-o/dyld.h>
++#include <mach-o/getsect.h>
++
++/*#define DARWIN_DEBUG*/
++
++const static struct {
++ const char *seg;
++ const char *sect;
++} GC_dyld_sections[] = {
++ { SEG_DATA, SECT_DATA },
++ { SEG_DATA, SECT_BSS },
++ { SEG_DATA, SECT_COMMON }
++};
++
++#ifdef DARWIN_DEBUG
++static const char *GC_dyld_name_for_hdr(struct mach_header *hdr) {
++ unsigned long i,c;
++ c = _dyld_image_count();
++ for(i=0;i<c;i++) if(_dyld_get_image_header(i) == hdr)
++ return _dyld_get_image_name(i);
++ return NULL;
++}
++#endif
++
++/* This should never be called by a thread holding the lock */
++static void GC_dyld_image_add(struct mach_header* hdr, unsigned long slide) {
++ unsigned long start,end,i;
++ const struct section *sec;
++ for(i=0;i<sizeof(GC_dyld_sections)/sizeof(GC_dyld_sections[0]);i++) {
++ sec = getsectbynamefromheader(
++ hdr,GC_dyld_sections[i].seg,GC_dyld_sections[i].sect);
++ if(sec == NULL || sec->size == 0) continue;
++ start = slide + sec->addr;
++ end = start + sec->size;
++# ifdef DARWIN_DEBUG
++ GC_printf4("Adding section at %p-%p (%lu bytes) from image %s\n",
++ start,end,sec->size,GC_dyld_name_for_hdr(hdr));
++# endif
++ GC_add_roots((char*)start,(char*)end);
++ }
++# ifdef DARWIN_DEBUG
++ GC_print_static_roots();
++# endif
++}
++
++/* This should never be called by a thread holding the lock */
++static void GC_dyld_image_remove(struct mach_header* hdr, unsigned long slide) {
++ unsigned long start,end,i;
++ const struct section *sec;
++ for(i=0;i<sizeof(GC_dyld_sections)/sizeof(GC_dyld_sections[0]);i++) {
++ sec = getsectbynamefromheader(
++ hdr,GC_dyld_sections[i].seg,GC_dyld_sections[i].sect);
++ if(sec == NULL || sec->size == 0) continue;
++ start = slide + sec->addr;
++ end = start + sec->size;
++# ifdef DARWIN_DEBUG
++ GC_printf4("Removing section at %p-%p (%lu bytes) from image %s\n",
++ start,end,sec->size,GC_dyld_name_for_hdr(hdr));
++# endif
++ GC_remove_roots((char*)start,(char*)end);
++ }
++# ifdef DARWIN_DEBUG
++ GC_print_static_roots();
++# endif
++}
++
++void GC_register_dynamic_libraries() {
++ /* Currently does nothing. The callbacks are setup by GC_init_dyld()
++ The dyld library takes it from there. */
++}
++
++/* The _dyld_* functions have an internal lock so no _dyld functions
++ can be called while the world is stopped without the risk of a deadlock.
++ Because of this we MUST setup callbacks BEFORE we ever stop the world.
++ This should be called BEFORE any thread in created and WITHOUT the
++ allocation lock held. */
++
++void GC_init_dyld() {
++ static GC_bool initialized = FALSE;
++
++ if(initialized) return;
++
++# ifdef DARWIN_DEBUG
++ GC_printf0("Forcing full bind of GC code...\n");
++# endif
++ if(!_dyld_bind_fully_image_containing_address((unsigned long*)GC_malloc))
++ GC_abort("_dyld_bind_fully_image_containing_addres failed");
++
++# ifdef DARWIN_DEBUG
++ GC_printf0("Registering dyld callbacks...\n");
++# endif
++
++ /* Apple's Documentation:
++ When you call _dyld_register_func_for_add_image, the dynamic linker runtime
++ calls the specified callback (func) once for each of the images that is
++ currently loaded into the program. When a new image is added to the program,
++ your callback is called again with the mach_header for the new image, and the virtual memory slide amount of the new image.
++
++ This WILL properly register existing and all future libraries
++ */
++
++ _dyld_register_func_for_add_image(GC_dyld_image_add);
++ _dyld_register_func_for_remove_image(GC_dyld_image_remove);
++ initialized = TRUE;
++}
++
++#define HAVE_REGISTER_MAIN_STATIC_DATA
++GC_bool GC_register_main_static_data()
++{
++ /* Already done through dyld callbacks */
++ return FALSE;
++}
+
++#endif /* DARWIN */
+
+ #else /* !DYNAMIC_LOADING */
+
+diff -buNr boehm-gc/dyn_load.c.rej boehm-gc/dyn_load.c.rej
+--- boehm-gc/dyn_load.c.rej Wed Dec 31 16:00:00 1969
++++ boehm-gc/dyn_load.c.rej Sat Sep 13 02:10:15 2003
+@@ -0,0 +1,50 @@
++***************
++*** 284,290 ****
++ /* Defined in os_dep.c. */
++
++ char *GC_parse_map_entry(char *buf_ptr, word *start, word *end,
++- char *prot_buf, unsigned int *maj_dev);
++ word GC_apply_to_maps(word (*fn)(char *));
++ /* From os_dep.c */
++
++--- 284,290 ----
++ /* Defined in os_dep.c. */
++
++ char *GC_parse_map_entry(char *buf_ptr, word *start, word *end,
+++ char *prot_buf, unsigned int *maj_dev);
++ word GC_apply_to_maps(word (*fn)(char *));
++ /* From os_dep.c */
++
++***************
++*** 335,341 ****
++ if (start >= least_ha && end <= greatest_ha) continue;
++ GC_add_roots_inner((char *)start, (char *)end, TRUE);
++ }
++- }
++ return 1;
++ }
++
++--- 335,341 ----
++ if (start >= least_ha && end <= greatest_ha) continue;
++ GC_add_roots_inner((char *)start, (char *)end, TRUE);
++ }
+++ }
++ return 1;
++ }
++
++***************
++*** 971,976 ****
++
++ #ifdef DARWIN
++
++ #include <mach-o/dyld.h>
++ #include <mach-o/getsect.h>
++
++--- 971,977 ----
++
++ #ifdef DARWIN
++
+++ #define __private_extern__
++ #include <mach-o/dyld.h>
++ #include <mach-o/getsect.h>
++
+diff -buNr boehm-gc/finalize.c boehm-gc/finalize.c
+--- boehm-gc/finalize.c Mon Feb 11 20:37:53 2002
++++ boehm-gc/finalize.c Sat Sep 13 02:10:15 2003
+@@ -207,7 +207,8 @@
+ UNLOCK();
+ ENABLE_SIGNALS();
+ # endif
+- new_dl = GC_oom_fn(sizeof(struct disappearing_link));
++ new_dl = (struct disappearing_link *)
++ GC_oom_fn(sizeof(struct disappearing_link));
+ if (0 == new_dl) {
+ GC_finalization_failures++;
+ return(0);
+@@ -433,7 +434,8 @@
+ UNLOCK();
+ ENABLE_SIGNALS();
+ # endif
+- new_fo = GC_oom_fn(sizeof(struct finalizable_object));
++ new_fo = (struct finalizable_object *)
++ GC_oom_fn(sizeof(struct finalizable_object));
+ if (0 == new_fo) {
+ GC_finalization_failures++;
+ return;
+@@ -759,8 +761,9 @@
+ /* Should be called without allocation lock. */
+ int GC_invoke_finalizers()
+ {
+- register struct finalizable_object * curr_fo;
+- register int count = 0;
++ struct finalizable_object * curr_fo;
++ int count = 0;
++ word mem_freed_before;
+ DCL_LOCK_STATE;
+
+ while (GC_finalize_now != 0) {
+@@ -768,6 +771,9 @@
+ DISABLE_SIGNALS();
+ LOCK();
+ # endif
++ if (count == 0) {
++ mem_freed_before = GC_mem_freed;
++ }
+ curr_fo = GC_finalize_now;
+ # ifdef THREADS
+ if (curr_fo != 0) GC_finalize_now = fo_next(curr_fo);
+@@ -789,6 +795,11 @@
+ GC_free((GC_PTR)curr_fo);
+ # endif
+ }
++ if (count != 0 && mem_freed_before != GC_mem_freed) {
++ LOCK();
++ GC_finalizer_mem_freed += (GC_mem_freed - mem_freed_before);
++ UNLOCK();
++ }
+ return count;
+ }
+
+@@ -801,7 +812,9 @@
+ if (GC_finalize_now == 0) return;
+ if (!GC_finalize_on_demand) {
+ (void) GC_invoke_finalizers();
++# ifndef THREADS
+ GC_ASSERT(GC_finalize_now == 0);
++# endif /* Otherwise GC can run concurrently and add more */
+ return;
+ }
+ if (GC_finalizer_notifier != (void (*) GC_PROTO((void)))0
+@@ -839,3 +852,17 @@
+ return(result);
+ }
+
++#if !defined(NO_DEBUGGING)
++
++void GC_print_finalization_stats()
++{
++ struct finalizable_object *fo = GC_finalize_now;
++ size_t ready = 0;
++
++ GC_printf2("%lu finalization table entries; %lu disappearing links\n",
++ GC_fo_entries, GC_dl_entries);
++ for (; 0 != fo; fo = fo_next(fo)) ++ready;
++ GC_printf1("%lu objects are eligible for immediate finalization\n", ready);
++}
++
++#endif /* NO_DEBUGGING */
+diff -buNr boehm-gc/gc_dlopen.c boehm-gc/gc_dlopen.c
+--- boehm-gc/gc_dlopen.c Tue Oct 16 02:01:35 2001
++++ boehm-gc/gc_dlopen.c Sat Sep 13 02:10:15 2003
+@@ -19,12 +19,14 @@
+ /*
+ * This used to be in dyn_load.c. It was extracted into a separate file
+ * to avoid having to link against libdl.{a,so} if the client doesn't call
+- * dlopen. -HB
++ * dlopen. Of course this fails if the collector is in a dynamic
++ * library. -HB
+ */
+
+ #include "private/gc_priv.h"
+
+-# if defined(GC_PTHREADS) || defined(GC_SOLARIS_THREADS)
++# if (defined(GC_PTHREADS) && !defined(GC_DARWIN_THREADS)) \
++ || defined(GC_SOLARIS_THREADS)
+
+ # if defined(dlopen) && !defined(GC_USE_LD_WRAP)
+ /* To support various threads pkgs, gc.h interposes on dlopen by */
+@@ -44,19 +46,14 @@
+ /* calls in either a multithreaded environment, or if the library */
+ /* initialization code allocates substantial amounts of GC'ed memory. */
+ /* But I don't know of a better solution. */
+- /* This can still deadlock if the client explicitly starts a GC */
+- /* during the dlopen. He shouldn't do that. */
+- static GC_bool disable_gc_for_dlopen()
++ static void disable_gc_for_dlopen()
+ {
+- GC_bool result;
+ LOCK();
+- result = GC_dont_gc;
+ while (GC_incremental && GC_collection_in_progress()) {
+ GC_collect_a_little_inner(1000);
+ }
+- GC_dont_gc = TRUE;
++ ++GC_dont_gc;
+ UNLOCK();
+- return(result);
+ }
+
+ /* Redefine dlopen to guarantee mutual exclusion with */
+@@ -74,10 +71,9 @@
+ #endif
+ {
+ void * result;
+- GC_bool dont_gc_save;
+
+ # ifndef USE_PROC_FOR_LIBRARIES
+- dont_gc_save = disable_gc_for_dlopen();
++ disable_gc_for_dlopen();
+ # endif
+ # ifdef GC_USE_LD_WRAP
+ result = (void *)__real_dlopen(path, mode);
+@@ -85,7 +81,7 @@
+ result = dlopen(path, mode);
+ # endif
+ # ifndef USE_PROC_FOR_LIBRARIES
+- GC_dont_gc = dont_gc_save;
++ GC_enable(); /* undoes disable_gc_for_dlopen */
+ # endif
+ return(result);
+ }
+diff -buNr boehm-gc/gcj_mlc.c boehm-gc/gcj_mlc.c
+--- boehm-gc/gcj_mlc.c Mon Feb 11 20:37:53 2002
++++ boehm-gc/gcj_mlc.c Sat Sep 13 02:10:15 2003
+@@ -157,6 +157,7 @@
+ GC_words_allocd += lw;
+ }
+ *(void **)op = ptr_to_struct_containing_descr;
++ GC_ASSERT(((void **)op)[1] == 0);
+ UNLOCK();
+ } else {
+ LOCK();
+diff -buNr boehm-gc/if_mach.c boehm-gc/if_mach.c
+--- boehm-gc/if_mach.c Fri Aug 17 11:30:45 2001
++++ boehm-gc/if_mach.c Sat Sep 13 02:10:15 2003
+@@ -14,7 +14,7 @@
+ if (strcmp(MACH_TYPE, argv[1]) != 0) return(0);
+ if (strcmp(OS_TYPE, "") != 0 && strcmp(argv[2], "") != 0
+ && strcmp(OS_TYPE, argv[2]) != 0) return(0);
+- printf("^^^^Starting command^^^^\n");
++ fprintf(stderr, "^^^^Starting command^^^^\n");
+ fflush(stdout);
+ execvp(argv[3], argv+3);
+ perror("Couldn't execute");
+diff -buNr boehm-gc/include/Makefile.in boehm-gc/include/Makefile.in
+--- boehm-gc/include/Makefile.in Tue Dec 31 09:52:45 2002
++++ boehm-gc/include/Makefile.in Sat Sep 13 02:10:15 2003
+@@ -1,6 +1,8 @@
+-# Makefile.in generated automatically by automake 1.4 from Makefile.am
++# Makefile.in generated by automake 1.6.3 from Makefile.am.
++# @configure_input@
+
+-# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
++# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
++# Free Software Foundation, Inc.
+ # This Makefile.in is free software; the Free Software Foundation
+ # gives unlimited permission to copy and/or distribute it,
+ # with or without modifications, as long as this notice is preserved.
+@@ -10,7 +12,7 @@
+ # even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ # PARTICULAR PURPOSE.
+
+-
++@SET_MAKE@
+ SHELL = @SHELL@
+
+ srcdir = @srcdir@
+@@ -31,13 +33,9 @@
+ mandir = @mandir@
+ includedir = @includedir@
+ oldincludedir = /usr/include
+-
+-DESTDIR =
+-
+ pkgdatadir = $(datadir)/@PACKAGE@
+ pkglibdir = $(libdir)/@PACKAGE@
+ pkgincludedir = $(includedir)/@PACKAGE@
+-
+ top_builddir = ..
+
+ ACLOCAL = @ACLOCAL@
+@@ -45,12 +43,16 @@
+ AUTOMAKE = @AUTOMAKE@
+ AUTOHEADER = @AUTOHEADER@
+
++am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+ INSTALL = @INSTALL@
+-INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
++INSTALL_PROGRAM = @INSTALL_PROGRAM@
+ INSTALL_DATA = @INSTALL_DATA@
++install_sh_DATA = $(install_sh) -c -m 644
++install_sh_PROGRAM = $(install_sh) -c
++install_sh_SCRIPT = $(install_sh) -c
+ INSTALL_SCRIPT = @INSTALL_SCRIPT@
++INSTALL_HEADER = $(INSTALL_DATA)
+ transform = @program_transform_name@
+-
+ NORMAL_INSTALL = :
+ PRE_INSTALL = :
+ POST_INSTALL = :
+@@ -63,171 +65,190 @@
+ host_triplet = @host@
+ target_alias = @target_alias@
+ target_triplet = @target@
++
++EXEEXT = @EXEEXT@
++OBJEXT = @OBJEXT@
++PATH_SEPARATOR = @PATH_SEPARATOR@
++AMTAR = @AMTAR@
+ AR = @AR@
+ AS = @AS@
++AWK = @AWK@
+ CC = @CC@
+ CPP = @CPP@
+ CXX = @CXX@
+ CXXCPP = @CXXCPP@
+ CXXINCLUDES = @CXXINCLUDES@
++DEPDIR = @DEPDIR@
+ DLLTOOL = @DLLTOOL@
+-EXEEXT = @EXEEXT@
++ECHO = @ECHO@
++EGREP = @EGREP@
+ EXTRA_TEST_LIBS = @EXTRA_TEST_LIBS@
++F77 = @F77@
+ GCJ = @GCJ@
+ GCJFLAGS = @GCJFLAGS@
+ GC_CFLAGS = @GC_CFLAGS@
+ INCLUDES = @INCLUDES@
++INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+ LIBTOOL = @LIBTOOL@
+ LN_S = @LN_S@
+ MAINT = @MAINT@
+-MAKEINFO = @MAKEINFO@
+ MY_CFLAGS = @MY_CFLAGS@
+ OBJDUMP = @OBJDUMP@
+-OBJEXT = @OBJEXT@
+ PACKAGE = @PACKAGE@
+ RANLIB = @RANLIB@
++RC = @RC@
+ STRIP = @STRIP@
+ THREADLIBS = @THREADLIBS@
+ VERSION = @VERSION@
+ addobjs = @addobjs@
++am__include = @am__include@
++am__quote = @am__quote@
+ gc_basedir = @gc_basedir@
++install_sh = @install_sh@
+ mkinstalldirs = @mkinstalldirs@
+ target_all = @target_all@
+-
+ AUTOMAKE_OPTIONS = foreign
+
+ noinst_HEADERS = gc.h gc_backptr.h gc_local_alloc.h \
+ gc_pthread_redirects.h gc_cpp.h
+
++subdir = include
+ CONFIG_CLEAN_FILES =
++depcomp =
++am__depfiles_maybe =
++DIST_SOURCES =
+ HEADERS = $(noinst_HEADERS)
+
+-DIST_COMMON = Makefile.am Makefile.in
+-
++all: all-am
+
+-DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+-
+-TAR = gtar
+-GZIP_ENV = --best
+-all: all-redirect
+ .SUFFIXES:
+ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+- cd $(top_srcdir) && $(AUTOMAKE) --cygnus include/Makefile
++ cd $(top_srcdir) && \
++ $(AUTOMAKE) --cygnus include/Makefile
++Makefile: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.in $(top_builddir)/config.status
++ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
+
+-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+- cd $(top_builddir) \
+- && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
++mostlyclean-libtool:
++ -rm -f *.lo
+
++clean-libtool:
++ -rm -rf .libs _libs
++
++distclean-libtool:
++ -rm -f libtool
++uninstall-info-am:
++
++ETAGS = etags
++ETAGSFLAGS =
+
+ tags: TAGS
+
+-ID: $(HEADERS) $(SOURCES) $(LISP)
+- list='$(SOURCES) $(HEADERS)'; \
+- unique=`for i in $$list; do echo $$i; done | \
+- awk ' { files[$$0] = 1; } \
++ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
++ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
++ unique=`for i in $$list; do \
++ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
++ done | \
++ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+- here=`pwd` && cd $(srcdir) \
+- && mkid -f$$here/ID $$unique $(LISP)
++ mkid -fID $$unique
+
+-TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
++TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
++ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+- list='$(SOURCES) $(HEADERS)'; \
+- unique=`for i in $$list; do echo $$i; done | \
+- awk ' { files[$$0] = 1; } \
++ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
++ unique=`for i in $$list; do \
++ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
++ done | \
++ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+- test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+- || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
+-
+-mostlyclean-tags:
+-
+-clean-tags:
++ test -z "$(ETAGS_ARGS)$$tags$$unique" \
++ || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
++ $$tags $$unique
++
++GTAGS:
++ here=`$(am__cd) $(top_builddir) && pwd` \
++ && cd $(top_srcdir) \
++ && gtags -i $(GTAGS_ARGS) $$here
+
+ distclean-tags:
+- -rm -f TAGS ID
+-
+-maintainer-clean-tags:
+-
+-distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+-
+-subdir = include
+-
+-distdir: $(DISTFILES)
+- @for file in $(DISTFILES); do \
+- if test -f $$file; then d=.; else d=$(srcdir); fi; \
+- if test -d $$d/$$file; then \
+- cp -pr $$d/$$file $(distdir)/$$file; \
+- else \
+- test -f $(distdir)/$$file \
+- || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+- || cp -p $$d/$$file $(distdir)/$$file || :; \
+- fi; \
+- done
+-info-am:
+-info: info-am
+-dvi-am:
+-dvi: dvi-am
++ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH
+ check-am:
+ check: check-am
+-installcheck-am:
+-installcheck: installcheck-am
+-install-info-am:
+-install-info: install-info-am
+-install-exec-am:
+-install-exec: install-exec-am
++all-am: Makefile $(HEADERS)
+
+-install-data-am:
+-install-data: install-data-am
++installdirs:
+
+-install-am: all-am
+- @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+ install: install-am
+-uninstall-am:
++install-exec: install-exec-am
++install-data: install-data-am
+ uninstall: uninstall-am
+-all-am: Makefile $(HEADERS)
+-all-redirect: all-am
+-install-strip:
+- $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+-installdirs:
+
++install-am: all-am
++ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
++installcheck: installcheck-am
++install-strip:
++ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
++ INSTALL_STRIP_FLAG=-s \
++ `test -z '$(STRIP)' || \
++ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+ mostlyclean-generic:
+
+ clean-generic:
+
+ distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+- -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+ maintainer-clean-generic:
+-mostlyclean-am: mostlyclean-tags mostlyclean-generic
++ @echo "This command is intended for maintainers to use"
++ @echo "it deletes files that may require special tools to rebuild."
++clean: clean-am
+
+-mostlyclean: mostlyclean-am
++clean-am: clean-generic clean-libtool mostlyclean-am
+
+-clean-am: clean-tags clean-generic mostlyclean-am
++distclean: distclean-am
+
+-clean: clean-am
++distclean-am: clean-am distclean-generic distclean-libtool \
++ distclean-tags
+
+-distclean-am: distclean-tags distclean-generic clean-am
+- -rm -f libtool
++dvi: dvi-am
+
+-distclean: distclean-am
++dvi-am:
+
+-maintainer-clean-am: maintainer-clean-tags maintainer-clean-generic \
+- distclean-am
+- @echo "This command is intended for maintainers to use;"
+- @echo "it deletes files that may require special tools to rebuild."
++info: info-am
++
++info-am:
++
++install-data-am:
++
++install-exec-am:
++
++install-info:
++
++install-man:
++
++installcheck-am:
+
+ maintainer-clean: maintainer-clean-am
+
+-.PHONY: tags mostlyclean-tags distclean-tags clean-tags \
+-maintainer-clean-tags distdir info-am info dvi-am dvi check check-am \
+-installcheck-am installcheck install-info-am install-info \
+-install-exec-am install-exec install-data-am install-data install-am \
+-install uninstall-am uninstall all-redirect all-am all installdirs \
+-mostlyclean-generic distclean-generic clean-generic \
+-maintainer-clean-generic clean mostlyclean distclean maintainer-clean
++maintainer-clean-am: distclean-am maintainer-clean-generic
++
++mostlyclean: mostlyclean-am
++
++mostlyclean-am: mostlyclean-generic mostlyclean-libtool
++
++uninstall-am:
+
++.PHONY: GTAGS all all-am check check-am clean clean-generic \
++ clean-libtool distclean distclean-generic distclean-libtool \
++ distclean-tags dvi dvi-am info info-am install install-am \
++ install-data install-data-am install-exec install-exec-am \
++ install-info install-info-am install-man install-strip \
++ installcheck installcheck-am installdirs maintainer-clean \
++ maintainer-clean-generic mostlyclean mostlyclean-generic \
++ mostlyclean-libtool tags uninstall uninstall-am \
++ uninstall-info-am
+
+ # Tell versions [3.59,3.63) of GNU make to not export all variables.
+ # Otherwise a system limit (for SysV at least) may be exceeded.
+diff -buNr boehm-gc/include/gc.h boehm-gc/include/gc.h
+--- boehm-gc/include/gc.h Mon Feb 11 20:37:56 2002
++++ boehm-gc/include/gc.h Sat Sep 13 02:10:15 2003
+@@ -30,91 +30,7 @@
+
+ # define _GC_H
+
+-/*
+- * Some tests for old macros. These violate our namespace rules and will
+- * disappear shortly. Use the GC_ names.
+- */
+-#if defined(SOLARIS_THREADS) || defined(_SOLARIS_THREADS)
+-# define GC_SOLARIS_THREADS
+-#endif
+-#if defined(_SOLARIS_PTHREADS)
+-# define GC_SOLARIS_PTHREADS
+-#endif
+-#if defined(IRIX_THREADS)
+-# define GC_IRIX_THREADS
+-#endif
+-#if defined(HPUX_THREADS)
+-# define GC_HPUX_THREADS
+-#endif
+-#if defined(OSF1_THREADS)
+-# define GC_OSF1_THREADS
+-#endif
+-#if defined(LINUX_THREADS)
+-# define GC_LINUX_THREADS
+-#endif
+-#if defined(WIN32_THREADS)
+-# define GC_WIN32_THREADS
+-#endif
+-#if defined(USE_LD_WRAP)
+-# define GC_USE_LD_WRAP
+-#endif
+-
+-#if !defined(_REENTRANT) && (defined(GC_SOLARIS_THREADS) \
+- || defined(GC_SOLARIS_PTHREADS) \
+- || defined(GC_HPUX_THREADS) \
+- || defined(GC_LINUX_THREADS))
+-# define _REENTRANT
+- /* Better late than never. This fails if system headers that */
+- /* depend on this were previously included. */
+-#endif
+-
+-#if defined(GC_SOLARIS_PTHREADS) && !defined(GC_SOLARIS_THREADS)
+-# define GC_SOLARIS_THREADS
+-#endif
+-
+-# if defined(GC_SOLARIS_PTHREADS) || defined(GC_FREEBSD_THREADS) || \
+- defined(GC_IRIX_THREADS) || defined(GC_LINUX_THREADS) || \
+- defined(GC_HPUX_THREADS) || defined(GC_OSF1_THREADS)
+-# define GC_PTHREADS
+-# endif
+-
+-# define __GC
+-# include <stddef.h>
+-# ifdef _WIN32_WCE
+-/* Yet more kluges for WinCE */
+-# include <stdlib.h> /* size_t is defined here */
+- typedef long ptrdiff_t; /* ptrdiff_t is not defined */
+-# endif
+-
+-#if defined(__MINGW32__) &&defined(_DLL) && !defined(GC_NOT_DLL)
+-# ifdef GC_BUILD
+-# define GC_API __declspec(dllexport)
+-# else
+-# define GC_API __declspec(dllimport)
+-# endif
+-#endif
+-
+-#if (defined(__DMC__) || defined(_MSC_VER)) \
+- && (defined(_DLL) && !defined(GC_NOT_DLL) \
+- || defined(GC_DLL))
+-# ifdef GC_BUILD
+-# define GC_API extern __declspec(dllexport)
+-# else
+-# define GC_API __declspec(dllimport)
+-# endif
+-#endif
+-
+-#if defined(__WATCOMC__) && defined(GC_DLL)
+-# ifdef GC_BUILD
+-# define GC_API extern __declspec(dllexport)
+-# else
+-# define GC_API extern __declspec(dllimport)
+-# endif
+-#endif
+-
+-#ifndef GC_API
+-#define GC_API extern
+-#endif
++# include "gc_config_macros.h"
+
+ # if defined(__STDC__) || defined(__cplusplus)
+ # define GC_PROTO(args) args
+@@ -154,7 +70,7 @@
+ /* Env variable GC_NPROC is set to > 1, or */
+ /* GC_NPROC is not set and this is an MP. */
+ /* If GC_parallel is set, incremental */
+- /* collection is aonly partially functional, */
++ /* collection is only partially functional, */
+ /* and may not be desirable. */
+
+
+@@ -215,8 +131,14 @@
+ /* thread, which will call GC_invoke_finalizers */
+ /* in response. */
+
+-GC_API int GC_dont_gc; /* Dont collect unless explicitly requested, e.g. */
+- /* because it's not safe. */
++GC_API int GC_dont_gc; /* != 0 ==> Dont collect. In versions 7.2a1+, */
++ /* this overrides explicit GC_gcollect() calls. */
++ /* Used as a counter, so that nested enabling */
++ /* and disabling work correctly. Should */
++ /* normally be updated with GC_enable() and */
++ /* GC_disable() calls. */
++ /* Direct assignment to GC_dont_gc is */
++ /* deprecated. */
+
+ GC_API int GC_dont_expand;
+ /* Dont expand heap unless explicitly requested */
+@@ -296,15 +218,6 @@
+ /* Interferes with blacklisting. */
+ /* Wizards only. */
+
+-/* Public procedures */
+-
+-/* Initialize the collector. This is only required when using thread-local
+- * allocation, since unlike the regular allocation routines, GC_local_malloc
+- * is not self-initializing. If you use GC_local_malloc you should arrange
+- * to call this somehow (e.g. from a constructor) before doing any allocation.
+- */
+-GC_API void GC_init GC_PROTO((void));
+-
+ GC_API unsigned long GC_time_limit;
+ /* If incremental collection is enabled, */
+ /* We try to terminate collections */
+@@ -316,9 +229,18 @@
+ /* enabled. */
+ # define GC_TIME_UNLIMITED 999999
+ /* Setting GC_time_limit to this value */
+- /* will disable the "pause time exceeded */
++ /* will disable the "pause time exceeded"*/
+ /* tests. */
+
++/* Public procedures */
++
++/* Initialize the collector. This is only required when using thread-local
++ * allocation, since unlike the regular allocation routines, GC_local_malloc
++ * is not self-initializing. If you use GC_local_malloc you should arrange
++ * to call this somehow (e.g. from a constructor) before doing any allocation.
++ */
++GC_API void GC_init GC_PROTO((void));
++
+ /*
+ * general purpose allocation routines, with roughly malloc calling conv.
+ * The atomic versions promise that no relevant pointers are contained
+@@ -419,17 +341,21 @@
+ GC_API void GC_add_roots GC_PROTO((char * low_address,
+ char * high_address_plus_1));
+
++/* Remove a root segment. Wizards only. */
++GC_API void GC_remove_roots GC_PROTO((char * low_address,
++ char * high_address_plus_1));
++
+ /* Add a displacement to the set of those considered valid by the */
+ /* collector. GC_register_displacement(n) means that if p was returned */
+ /* by GC_malloc, then (char *)p + n will be considered to be a valid */
+-/* pointer to n. N must be small and less than the size of p. */
++/* pointer to p. N must be small and less than the size of p. */
+ /* (All pointers to the interior of objects from the stack are */
+ /* considered valid in any case. This applies to heap objects and */
+ /* static data.) */
+ /* Preferably, this should be called before any other GC procedures. */
+ /* Calling it later adds to the probability of excess memory */
+ /* retention. */
+-/* This is a no-op if the collector was compiled with recognition of */
++/* This is a no-op if the collector has recognition of */
+ /* arbitrary interior pointers enabled, which is now the default. */
+ GC_API void GC_register_displacement GC_PROTO((GC_word n));
+
+@@ -464,9 +390,18 @@
+ GC_API size_t GC_get_bytes_since_gc GC_PROTO((void));
+
+ /* Return the total number of bytes allocated in this process. */
+-/* Never decreases. */
++/* Never decreases, except due to wrapping. */
+ GC_API size_t GC_get_total_bytes GC_PROTO((void));
+
++/* Disable garbage collection. Even GC_gcollect calls will be */
++/* ineffective. */
++GC_API void GC_disable GC_PROTO((void));
++
++/* Reenable garbage collection. GC_diable() and GC_enable() calls */
++/* nest. Garbage collection is enabled if the number of calls to both */
++/* both functions is equal. */
++GC_API void GC_enable GC_PROTO((void));
++
+ /* Enable incremental/generational collection. */
+ /* Not advisable unless dirty bits are */
+ /* available or most heap objects are */
+@@ -474,7 +409,11 @@
+ /* Don't use in leak finding mode. */
+ /* Ignored if GC_dont_gc is true. */
+ /* Only the generational piece of this is */
+-/* functional if GC_parallel is TRUE. */
++/* functional if GC_parallel is TRUE */
++/* or if GC_time_limit is GC_TIME_UNLIMITED. */
++/* Causes GC_local_gcj_malloc() to revert to */
++/* locked allocation. Must be called */
++/* before any GC_local_gcj_malloc() calls. */
+ GC_API void GC_enable_incremental GC_PROTO((void));
+
+ /* Does incremental mode write-protect pages? Returns zero or */
+@@ -518,6 +457,42 @@
+ # define GC_RETURN_ADDR (GC_word)__return_address
+ #endif
+
++#ifdef __linux__
++# include <features.h>
++# if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1 || __GLIBC__ > 2) \
++ && !defined(__ia64__)
++# define GC_HAVE_BUILTIN_BACKTRACE
++# define GC_CAN_SAVE_CALL_STACKS
++# endif
++# if defined(__i386__) || defined(__x86_64__)
++# define GC_CAN_SAVE_CALL_STACKS
++# endif
++#endif
++
++#if defined(__sparc__)
++# define GC_CAN_SAVE_CALL_STACKS
++#endif
++
++/* If we're on an a platform on which we can't save call stacks, but */
++/* gcc is normally used, we go ahead and define GC_ADD_CALLER. */
++/* We make this decision independent of whether gcc is actually being */
++/* used, in order to keep the interface consistent, and allow mixing */
++/* of compilers. */
++/* This may also be desirable if it is possible but expensive to */
++/* retrieve the call chain. */
++#if (defined(__linux__) || defined(__NetBSD__) || defined(__OpenBSD__) \
++ || defined(__FreeBSD__)) & !defined(GC_CAN_SAVE_CALL_STACKS)
++# define GC_ADD_CALLER
++# if __GNUC__ >= 3 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95)
++ /* gcc knows how to retrieve return address, but we don't know */
++ /* how to generate call stacks. */
++# define GC_RETURN_ADDR (GC_word)__builtin_return_address(0)
++# else
++ /* Just pass 0 for gcc compatibility. */
++# define GC_RETURN_ADDR 0
++# endif
++#endif
++
+ #ifdef GC_ADD_CALLER
+ # define GC_EXTRAS GC_RETURN_ADDR, __FILE__, __LINE__
+ # define GC_EXTRA_PARAMS GC_word ra, GC_CONST char * s, int i
+@@ -536,18 +511,42 @@
+ GC_PROTO((size_t size_in_bytes, GC_EXTRA_PARAMS));
+ GC_API GC_PTR GC_debug_malloc_stubborn
+ GC_PROTO((size_t size_in_bytes, GC_EXTRA_PARAMS));
++GC_API GC_PTR GC_debug_malloc_ignore_off_page
++ GC_PROTO((size_t size_in_bytes, GC_EXTRA_PARAMS));
++GC_API GC_PTR GC_debug_malloc_atomic_ignore_off_page
++ GC_PROTO((size_t size_in_bytes, GC_EXTRA_PARAMS));
+ GC_API void GC_debug_free GC_PROTO((GC_PTR object_addr));
+ GC_API GC_PTR GC_debug_realloc
+ GC_PROTO((GC_PTR old_object, size_t new_size_in_bytes,
+ GC_EXTRA_PARAMS));
+-
+ GC_API void GC_debug_change_stubborn GC_PROTO((GC_PTR));
+ GC_API void GC_debug_end_stubborn_change GC_PROTO((GC_PTR));
++
++/* Routines that allocate objects with debug information (like the */
++/* above), but just fill in dummy file and line number information. */
++/* Thus they can serve as drop-in malloc/realloc replacements. This */
++/* can be useful for two reasons: */
++/* 1) It allows the collector to be built with DBG_HDRS_ALL defined */
++/* even if some allocation calls come from 3rd party libraries */
++/* that can't be recompiled. */
++/* 2) On some platforms, the file and line information is redundant, */
++/* since it can be reconstructed from a stack trace. On such */
++/* platforms it may be more convenient not to recompile, e.g. for */
++/* leak detection. This can be accomplished by instructing the */
++/* linker to replace malloc/realloc with these. */
++GC_API GC_PTR GC_debug_malloc_replacement GC_PROTO((size_t size_in_bytes));
++GC_API GC_PTR GC_debug_realloc_replacement
++ GC_PROTO((GC_PTR object_addr, size_t size_in_bytes));
++
+ # ifdef GC_DEBUG
+ # define GC_MALLOC(sz) GC_debug_malloc(sz, GC_EXTRAS)
+ # define GC_MALLOC_ATOMIC(sz) GC_debug_malloc_atomic(sz, GC_EXTRAS)
+-# define GC_MALLOC_UNCOLLECTABLE(sz) GC_debug_malloc_uncollectable(sz, \
+- GC_EXTRAS)
++# define GC_MALLOC_UNCOLLECTABLE(sz) \
++ GC_debug_malloc_uncollectable(sz, GC_EXTRAS)
++# define GC_MALLOC_IGNORE_OFF_PAGE(sz) \
++ GC_debug_malloc_ignore_off_page(sz, GC_EXTRAS)
++# define GC_MALLOC_ATOMIC_IGNORE_OFF_PAGE(sz) \
++ GC_debug_malloc_atomic_ignore_off_page(sz, GC_EXTRAS)
+ # define GC_REALLOC(old, sz) GC_debug_realloc(old, sz, GC_EXTRAS)
+ # define GC_FREE(p) GC_debug_free(p)
+ # define GC_REGISTER_FINALIZER(p, f, d, of, od) \
+@@ -566,6 +565,10 @@
+ # define GC_MALLOC(sz) GC_malloc(sz)
+ # define GC_MALLOC_ATOMIC(sz) GC_malloc_atomic(sz)
+ # define GC_MALLOC_UNCOLLECTABLE(sz) GC_malloc_uncollectable(sz)
++# define GC_MALLOC_IGNORE_OFF_PAGE(sz) \
++ GC_malloc_ignore_off_page(sz)
++# define GC_MALLOC_ATOMIC_IGNORE_OFF_PAGE(sz) \
++ GC_malloc_atomic_ignore_off_page(sz)
+ # define GC_REALLOC(old, sz) GC_realloc(old, sz)
+ # define GC_FREE(p) GC_free(p)
+ # define GC_REGISTER_FINALIZER(p, f, d, of, od) \
+@@ -644,7 +647,8 @@
+ /* itself. There is a stylistic argument that this is wrong, */
+ /* but it's unavoidable for C++, since the compiler may */
+ /* silently introduce these. It's also benign in that specific */
+-/* case. */
++/* case. And it helps if finalizable objects are split to */
++/* avoid cycles. */
+ /* Note that cd will still be viewed as accessible, even if it */
+ /* refers to the object itself. */
+ GC_API void GC_register_finalizer_ignore_self
+@@ -717,11 +721,6 @@
+ /* Undoes a registration by either of the above two */
+ /* routines. */
+
+-/* Auxiliary fns to make finalization work correctly with displaced */
+-/* pointers introduced by the debugging allocators. */
+-GC_API GC_PTR GC_make_closure GC_PROTO((GC_finalization_proc fn, GC_PTR data));
+-GC_API void GC_debug_invoke_finalizer GC_PROTO((GC_PTR obj, GC_PTR data));
+-
+ /* Returns !=0 if GC_invoke_finalizers has something to do. */
+ GC_API int GC_should_invoke_finalizers GC_PROTO((void));
+
+@@ -739,6 +738,10 @@
+ GC_API GC_warn_proc GC_set_warn_proc GC_PROTO((GC_warn_proc p));
+ /* Returns old warning procedure. */
+
++GC_API GC_word GC_set_free_space_divisor GC_PROTO((GC_word value));
++ /* Set free_space_divisor. See above for definition. */
++ /* Returns old value. */
++
+ /* The following is intended to be used by a higher level */
+ /* (e.g. Java-like) finalization facility. It is expected */
+ /* that finalization code will arrange for hidden pointers to */
+@@ -875,12 +878,16 @@
+
+ #if defined(GC_WIN32_THREADS)
+ # include <windows.h>
++# include <winbase.h>
+
+ /*
+ * All threads must be created using GC_CreateThread, so that they will be
+- * recorded in the thread table.
++ * recorded in the thread table. For backwards compatibility, this is not
++ * technically true if the GC is built as a dynamic library, since it can
++ * and does then use DllMain to keep track of thread creations. But new code
++ * should be built to call GC_CreateThread.
+ */
+- HANDLE WINAPI GC_CreateThread(
++ GC_API HANDLE GC_CreateThread(
+ LPSECURITY_ATTRIBUTES lpThreadAttributes,
+ DWORD dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress,
+ LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId );
+@@ -914,13 +921,18 @@
+ # define GC_INIT() { extern end, etext; \
+ GC_noop(&end, &etext); }
+ #else
+-# if (defined(__CYGWIN32__) && defined(GC_USE_DLL)) || defined (_AIX)
++# if defined(__CYGWIN32__) && defined(GC_DLL) || defined (_AIX)
+ /*
+- * Similarly gnu-win32 DLLs need explicit initialization
++ * Similarly gnu-win32 DLLs need explicit initialization from
++ * the main program, as does AIX.
+ */
+ # define GC_INIT() { GC_add_roots(DATASTART, DATAEND); }
+ # else
++# if defined(__APPLE__) && defined(__MACH__)
++# define GC_INIT() { GC_init(); }
++# else
+ # define GC_INIT()
++# endif
+ # endif
+ #endif
+
+diff -buNr boehm-gc/include/gc_allocator.h boehm-gc/include/gc_allocator.h
+--- boehm-gc/include/gc_allocator.h Wed Dec 31 16:00:00 1969
++++ boehm-gc/include/gc_allocator.h Sat Sep 13 02:10:15 2003
+@@ -0,0 +1,232 @@
++/*
++ * Copyright (c) 1996-1997
++ * Silicon Graphics Computer Systems, Inc.
++ *
++ * Permission to use, copy, modify, distribute and sell this software
++ * and its documentation for any purpose is hereby granted without fee,
++ * provided that the above copyright notice appear in all copies and
++ * that both that copyright notice and this permission notice appear
++ * in supporting documentation. Silicon Graphics makes no
++ * representations about the suitability of this software for any
++ * purpose. It is provided "as is" without express or implied warranty.
++ *
++ * Copyright (c) 2002
++ * Hewlett-Packard Company
++ *
++ * Permission to use, copy, modify, distribute and sell this software
++ * and its documentation for any purpose is hereby granted without fee,
++ * provided that the above copyright notice appear in all copies and
++ * that both that copyright notice and this permission notice appear
++ * in supporting documentation. Hewlett-Packard Company makes no
++ * representations about the suitability of this software for any
++ * purpose. It is provided "as is" without express or implied warranty.
++ */
++
++/*
++ * This implements standard-conforming allocators that interact with
++ * the garbage collector. Gc_alloctor<T> allocates garbage-collectable
++ * objects of type T. Traceable_allocator<T> allocates objects that
++ * are not temselves garbage collected, but are scanned by the
++ * collector for pointers to collectable objects. Traceable_alloc
++ * should be used for explicitly managed STL containers that may
++ * point to collectable objects.
++ *
++ * This code was derived from an earlier version of the GNU C++ standard
++ * library, which itself was derived from the SGI STL implementation.
++ */
++
++#include "gc.h" // For size_t
++
++/* First some helpers to allow us to dispatch on whether or not a type
++ * is known to be pointerfree.
++ * These are private, except that the client may invoke the
++ * GC_DECLARE_PTRFREE macro.
++ */
++
++struct GC_true_type {};
++struct GC_false_type {};
++
++template <class GC_tp>
++struct GC_type_traits {
++ GC_false_type GC_is_ptr_free;
++};
++
++# define GC_DECLARE_PTRFREE(T) \
++template<> struct GC_type_traits<T> { GC_true_type GC_is_ptr_free; }
++
++GC_DECLARE_PTRFREE(signed char);
++GC_DECLARE_PTRFREE(unsigned char);
++GC_DECLARE_PTRFREE(signed short);
++GC_DECLARE_PTRFREE(unsigned short);
++GC_DECLARE_PTRFREE(signed int);
++GC_DECLARE_PTRFREE(unsigned int);
++GC_DECLARE_PTRFREE(signed long);
++GC_DECLARE_PTRFREE(unsigned long);
++GC_DECLARE_PTRFREE(float);
++GC_DECLARE_PTRFREE(double);
++/* The client may want to add others. */
++
++// In the following GC_Tp is GC_true_type iff we are allocating a
++// pointerfree object.
++template <class GC_Tp>
++inline void * GC_selective_alloc(size_t n, GC_Tp) {
++ return GC_MALLOC(n);
++}
++
++template <>
++inline void * GC_selective_alloc<GC_true_type>(size_t n, GC_true_type) {
++ return GC_MALLOC_ATOMIC(n);
++}
++
++/* Now the public gc_allocator<T> class:
++ */
++template <class GC_Tp>
++class gc_allocator {
++public:
++ typedef size_t size_type;
++ typedef ptrdiff_t difference_type;
++ typedef GC_Tp* pointer;
++ typedef const GC_Tp* const_pointer;
++ typedef GC_Tp& reference;
++ typedef const GC_Tp& const_reference;
++ typedef GC_Tp value_type;
++
++ template <class GC_Tp1> struct rebind {
++ typedef gc_allocator<GC_Tp1> other;
++ };
++
++ gc_allocator() {}
++# ifndef _MSC_VER
++ // I'm not sure why this is needed here in addition to the following.
++ // The standard specifies it for the standard allocator, but VC++ rejects
++ // it. -HB
++ gc_allocator(const gc_allocator&) throw() {}
++# endif
++ template <class GC_Tp1> gc_allocator(const gc_allocator<GC_Tp1>&) throw() {}
++ ~gc_allocator() throw() {}
++
++ pointer address(reference GC_x) const { return &GC_x; }
++ const_pointer address(const_reference GC_x) const { return &GC_x; }
++
++ // GC_n is permitted to be 0. The C++ standard says nothing about what
++ // the return value is when GC_n == 0.
++ GC_Tp* allocate(size_type GC_n, const void* = 0) {
++ GC_type_traits<GC_Tp> traits;
++ return static_cast<GC_Tp *>
++ (GC_selective_alloc(GC_n * sizeof(GC_Tp),
++ traits.GC_is_ptr_free));
++ }
++
++ // __p is not permitted to be a null pointer.
++ void deallocate(pointer __p, size_type GC_n)
++ { GC_FREE(__p); }
++
++ size_type max_size() const throw()
++ { return size_t(-1) / sizeof(GC_Tp); }
++
++ void construct(pointer __p, const GC_Tp& __val) { new(__p) GC_Tp(__val); }
++ void destroy(pointer __p) { __p->~GC_Tp(); }
++};
++
++template<>
++class gc_allocator<void> {
++ typedef size_t size_type;
++ typedef ptrdiff_t difference_type;
++ typedef void* pointer;
++ typedef const void* const_pointer;
++ typedef void value_type;
++
++ template <class GC_Tp1> struct rebind {
++ typedef gc_allocator<GC_Tp1> other;
++ };
++};
++
++
++template <class GC_T1, class GC_T2>
++inline bool operator==(const gc_allocator<GC_T1>&, const gc_allocator<GC_T2>&)
++{
++ return true;
++}
++
++template <class GC_T1, class GC_T2>
++inline bool operator!=(const gc_allocator<GC_T1>&, const gc_allocator<GC_T2>&)
++{
++ return false;
++}
++
++/*
++ * And the public traceable_allocator class.
++ */
++
++// Note that we currently don't specialize the pointer-free case, since a
++// pointer-free traceable container doesn't make that much sense,
++// though it could become an issue due to abstraction boundaries.
++template <class GC_Tp>
++class traceable_allocator {
++public:
++ typedef size_t size_type;
++ typedef ptrdiff_t difference_type;
++ typedef GC_Tp* pointer;
++ typedef const GC_Tp* const_pointer;
++ typedef GC_Tp& reference;
++ typedef const GC_Tp& const_reference;
++ typedef GC_Tp value_type;
++
++ template <class GC_Tp1> struct rebind {
++ typedef traceable_allocator<GC_Tp1> other;
++ };
++
++ traceable_allocator() throw() {}
++# ifndef _MSC_VER
++ traceable_allocator(const traceable_allocator&) throw() {}
++# endif
++ template <class GC_Tp1> traceable_allocator
++ (const traceable_allocator<GC_Tp1>&) throw() {}
++ ~traceable_allocator() throw() {}
++
++ pointer address(reference GC_x) const { return &GC_x; }
++ const_pointer address(const_reference GC_x) const { return &GC_x; }
++
++ // GC_n is permitted to be 0. The C++ standard says nothing about what
++ // the return value is when GC_n == 0.
++ GC_Tp* allocate(size_type GC_n, const void* = 0) {
++ return static_cast<GC_Tp*>(GC_MALLOC_UNCOLLECTABLE(GC_n * sizeof(GC_Tp)));
++ }
++
++ // __p is not permitted to be a null pointer.
++ void deallocate(pointer __p, size_type GC_n)
++ { GC_FREE(__p); }
++
++ size_type max_size() const throw()
++ { return size_t(-1) / sizeof(GC_Tp); }
++
++ void construct(pointer __p, const GC_Tp& __val) { new(__p) GC_Tp(__val); }
++ void destroy(pointer __p) { __p->~GC_Tp(); }
++};
++
++template<>
++class traceable_allocator<void> {
++ typedef size_t size_type;
++ typedef ptrdiff_t difference_type;
++ typedef void* pointer;
++ typedef const void* const_pointer;
++ typedef void value_type;
++
++ template <class GC_Tp1> struct rebind {
++ typedef traceable_allocator<GC_Tp1> other;
++ };
++};
++
++
++template <class GC_T1, class GC_T2>
++inline bool operator==(const traceable_allocator<GC_T1>&, const traceable_allocator<GC_T2>&)
++{
++ return true;
++}
++
++template <class GC_T1, class GC_T2>
++inline bool operator!=(const traceable_allocator<GC_T1>&, const traceable_allocator<GC_T2>&)
++{
++ return false;
++}
++
+diff -buNr boehm-gc/include/gc_config_macros.h boehm-gc/include/gc_config_macros.h
+--- boehm-gc/include/gc_config_macros.h Wed Dec 31 16:00:00 1969
++++ boehm-gc/include/gc_config_macros.h Sat Sep 13 02:10:15 2003
+@@ -0,0 +1,142 @@
++/*
++ * This should never be included directly. It is included only from gc.h.
++ * We separate it only to make gc.h more suitable as documentation.
++ *
++ * Some tests for old macros. These violate our namespace rules and will
++ * disappear shortly. Use the GC_ names.
++ */
++#if defined(SOLARIS_THREADS) || defined(_SOLARIS_THREADS)
++# define GC_SOLARIS_THREADS
++#endif
++#if defined(_SOLARIS_PTHREADS)
++# define GC_SOLARIS_PTHREADS
++#endif
++#if defined(IRIX_THREADS)
++# define GC_IRIX_THREADS
++#endif
++#if defined(DGUX_THREADS)
++# if !defined(GC_DGUX386_THREADS)
++# define GC_DGUX386_THREADS
++# endif
++#endif
++#if defined(HPUX_THREADS)
++# define GC_HPUX_THREADS
++#endif
++#if defined(OSF1_THREADS)
++# define GC_OSF1_THREADS
++#endif
++#if defined(LINUX_THREADS)
++# define GC_LINUX_THREADS
++#endif
++#if defined(WIN32_THREADS)
++# define GC_WIN32_THREADS
++#endif
++#if defined(USE_LD_WRAP)
++# define GC_USE_LD_WRAP
++#endif
++
++#if !defined(_REENTRANT) && (defined(GC_SOLARIS_THREADS) \
++ || defined(GC_SOLARIS_PTHREADS) \
++ || defined(GC_HPUX_THREADS) \
++ || defined(GC_LINUX_THREADS))
++# define _REENTRANT
++ /* Better late than never. This fails if system headers that */
++ /* depend on this were previously included. */
++#endif
++
++#if defined(GC_DGUX386_THREADS) && !defined(_POSIX4A_DRAFT10_SOURCE)
++# define _POSIX4A_DRAFT10_SOURCE 1
++#endif
++
++# if defined(GC_SOLARIS_PTHREADS) || defined(GC_FREEBSD_THREADS) || \
++ defined(GC_IRIX_THREADS) || defined(GC_LINUX_THREADS) || \
++ defined(GC_HPUX_THREADS) || defined(GC_OSF1_THREADS) || \
++ defined(GC_DGUX386_THREADS) || defined(GC_DARWIN_THREADS) || \
++ (defined(GC_WIN32_THREADS) && defined(__CYGWIN32__))
++# define GC_PTHREADS
++# endif
++
++#if defined(GC_THREADS) && !defined(GC_PTHREADS)
++# if defined(__linux__)
++# define GC_LINUX_THREADS
++# define GC_PTHREADS
++# endif
++# if !defined(LINUX) && (defined(_PA_RISC1_1) || defined(_PA_RISC2_0) \
++ || defined(hppa) || defined(__HPPA))
++# define GC_HPUX_THREADS
++# define GC_PTHREADS
++# endif
++# if !defined(__linux__) && (defined(__alpha) || defined(__alpha__))
++# define GC_OSF1_THREADS
++# define GC_PTHREADS
++# endif
++# if defined(__mips) && !defined(__linux__)
++# define GC_IRIX_THREADS
++# define GC_PTHREADS
++# endif
++# if defined(__sparc) && !defined(__linux__)
++# define GC_SOLARIS_PTHREADS
++# define GC_PTHREADS
++# endif
++# if defined(__APPLE__) && defined(__MACH__) && defined(__ppc__)
++# define GC_DARWIN_THREADS
++# define GC_PTHREADS
++# endif
++# if !defined(GC_PTHREADS) && defined(__FreeBSD__)
++# define GC_FREEBSD_THREADS
++# define GC_PTHREADS
++# endif
++# if defined(DGUX) && (defined(i386) || defined(__i386__))
++# define GC_DGUX386_THREADS
++# define GC_PTHREADS
++# endif
++#endif /* GC_THREADS */
++
++#if defined(GC_THREADS) && !defined(GC_PTHREADS) && defined(MSWIN32)
++# define GC_WIN32_THREADS
++#endif
++
++#if defined(GC_SOLARIS_PTHREADS) && !defined(GC_SOLARIS_THREADS)
++# define GC_SOLARIS_THREADS
++#endif
++
++# define __GC
++# include <stddef.h>
++# ifdef _WIN32_WCE
++/* Yet more kluges for WinCE */
++# include <stdlib.h> /* size_t is defined here */
++ typedef long ptrdiff_t; /* ptrdiff_t is not defined */
++# endif
++
++#if defined(_DLL) && !defined(GC_NOT_DLL) && !defined(GC_DLL)
++# define GC_DLL
++#endif
++
++#if defined(__MINGW32__) && defined(GC_DLL)
++# ifdef GC_BUILD
++# define GC_API __declspec(dllexport)
++# else
++# define GC_API __declspec(dllimport)
++# endif
++#endif
++
++#if (defined(__DMC__) || defined(_MSC_VER)) && defined(GC_DLL)
++# ifdef GC_BUILD
++# define GC_API extern __declspec(dllexport)
++# else
++# define GC_API __declspec(dllimport)
++# endif
++#endif
++
++#if defined(__WATCOMC__) && defined(GC_DLL)
++# ifdef GC_BUILD
++# define GC_API extern __declspec(dllexport)
++# else
++# define GC_API extern __declspec(dllimport)
++# endif
++#endif
++
++#ifndef GC_API
++#define GC_API extern
++#endif
++
+diff -buNr boehm-gc/include/gc_cpp.h boehm-gc/include/gc_cpp.h
+--- boehm-gc/include/gc_cpp.h Fri Aug 17 18:04:43 2001
++++ boehm-gc/include/gc_cpp.h Sat Sep 13 02:10:15 2003
+@@ -134,7 +134,9 @@
+ #include "gc.h"
+
+ #ifndef THINK_CPLUS
+-#define _cdecl
++# define GC_cdecl
++#else
++# define GC_cdecl _cdecl
+ #endif
+
+ #if ! defined( GC_NO_OPERATOR_NEW_ARRAY ) \
+@@ -159,12 +161,22 @@
+ class gc {public:
+ inline void* operator new( size_t size );
+ inline void* operator new( size_t size, GCPlacement gcp );
++ inline void* operator new( size_t size, void *p );
++ /* Must be redefined here, since the other overloadings */
++ /* hide the global definition. */
+ inline void operator delete( void* obj );
++# ifndef __BORLANDC__ /* Confuses the Borland compiler. */
++ inline void operator delete( void*, void* );
++# endif
+
+ #ifdef GC_OPERATOR_NEW_ARRAY
+ inline void* operator new[]( size_t size );
+ inline void* operator new[]( size_t size, GCPlacement gcp );
++ inline void* operator new[]( size_t size, void *p );
+ inline void operator delete[]( void* obj );
++# ifndef __BORLANDC__
++ inline void gc::operator delete[]( void*, void* );
++# endif
+ #endif /* GC_OPERATOR_NEW_ARRAY */
+ };
+ /*
+@@ -176,7 +188,7 @@
+ inline gc_cleanup();
+ inline virtual ~gc_cleanup();
+ private:
+- inline static void _cdecl cleanup( void* obj, void* clientData );};
++ inline static void GC_cdecl cleanup( void* obj, void* clientData );};
+ /*
+ Instances of classes derived from "gc_cleanup" will be allocated
+ in the collected heap by default. When the collector discovers an
+@@ -211,7 +223,6 @@
+ classes derived from "gc_cleanup" or containing members derived
+ from "gc_cleanup". */
+
+-#ifdef GC_OPERATOR_NEW_ARRAY
+
+ #ifdef _MSC_VER
+ /** This ensures that the system default operator new[] doesn't get
+@@ -220,42 +231,24 @@
+ * There seems to be really redirect new in this environment without
+ * including this everywhere.
+ */
+- inline void *operator new[]( size_t size )
+- {
+- return GC_MALLOC_UNCOLLECTABLE( size );
+- }
+-
+- inline void operator delete[](void* obj)
+- {
+- GC_FREE(obj);
+- };
++ void *operator new[]( size_t size );
+
+- inline void* operator new( size_t size)
+- {
+- return GC_MALLOC_UNCOLLECTABLE( size);
+- };
++ void operator delete[](void* obj);
+
+- inline void operator delete(void* obj)
+- {
+- GC_FREE(obj);
+- };
++ void* operator new( size_t size);
+
++ void operator delete(void* obj);
+
+-// This new operator is used by VC++ in case of Debug builds !
+- inline void* operator new( size_t size,
++ // This new operator is used by VC++ in case of Debug builds !
++ void* operator new( size_t size,
+ int ,//nBlockUse,
+ const char * szFileName,
+- int nLine
+- ) {
+-# ifndef GC_DEBUG
+- return GC_malloc_uncollectable( size );
+-# else
+- return GC_debug_malloc_uncollectable(size, szFileName, nLine);
+-# endif
+- }
+-
++ int nLine );
+ #endif /* _MSC_VER */
+
++
++#ifdef GC_OPERATOR_NEW_ARRAY
++
+ inline void* operator new[](
+ size_t size,
+ GCPlacement gcp,
+@@ -283,9 +276,15 @@
+ else
+ return GC_MALLOC_UNCOLLECTABLE( size );}
+
++inline void* gc::operator new( size_t size, void *p ) {
++ return p;}
++
+ inline void gc::operator delete( void* obj ) {
+ GC_FREE( obj );}
+
++#ifndef __BORLANDC__
++ inline void gc::operator delete( void*, void* ) {}
++#endif
+
+ #ifdef GC_OPERATOR_NEW_ARRAY
+
+@@ -295,14 +294,21 @@
+ inline void* gc::operator new[]( size_t size, GCPlacement gcp ) {
+ return gc::operator new( size, gcp );}
+
++inline void* gc::operator new[]( size_t size, void *p ) {
++ return p;}
++
+ inline void gc::operator delete[]( void* obj ) {
+ gc::operator delete( obj );}
+
++#ifndef __BORLANDC__
++ inline void gc::operator delete[]( void*, void* ) {}
++#endif
++
+ #endif /* GC_OPERATOR_NEW_ARRAY */
+
+
+ inline gc_cleanup::~gc_cleanup() {
+- GC_REGISTER_FINALIZER_IGNORE_SELF( GC_base(this), 0, 0, 0, 0 );}
++ GC_register_finalizer_ignore_self( GC_base(this), 0, 0, 0, 0 );}
+
+ inline void gc_cleanup::cleanup( void* obj, void* displ ) {
+ ((gc_cleanup*) ((char*) obj + (ptrdiff_t) displ))->~gc_cleanup();}
+diff -buNr boehm-gc/include/gc_local_alloc.h boehm-gc/include/gc_local_alloc.h
+--- boehm-gc/include/gc_local_alloc.h Fri Aug 17 11:30:50 2001
++++ boehm-gc/include/gc_local_alloc.h Sat Sep 13 02:10:15 2003
+@@ -33,6 +33,9 @@
+ * -DTHREAD_LOCAL_ALLOC, which is currently supported only on Linux.
+ *
+ * The debugging allocators use standard, not thread-local allocation.
++ *
++ * These routines normally require an explicit call to GC_init(), though
++ * that may be done from a constructor function.
+ */
+
+ #ifndef GC_LOCAL_ALLOC_H
+diff -buNr boehm-gc/include/gc_mark.h boehm-gc/include/gc_mark.h
+--- boehm-gc/include/gc_mark.h Fri Aug 17 11:30:50 2001
++++ boehm-gc/include/gc_mark.h Sat Sep 13 02:10:15 2003
+@@ -129,7 +129,9 @@
+ /* be reserved for exceptional cases. That will ensure that */
+ /* performance of this call is not extremely performance critical. */
+ /* (Otherwise we would need to inline GC_mark_and_push completely, */
+-/* which would tie the client code to a fixed colllector version.) */
++/* which would tie the client code to a fixed collector version.) */
++/* Note that mark procedures should explicitly call FIXUP_POINTER() */
++/* if required. */
+ struct GC_ms_entry *GC_mark_and_push
+ GC_PROTO((GC_PTR obj,
+ struct GC_ms_entry * mark_stack_ptr,
+diff -buNr boehm-gc/include/gc_pthread_redirects.h boehm-gc/include/gc_pthread_redirects.h
+--- boehm-gc/include/gc_pthread_redirects.h Tue Oct 16 21:55:28 2001
++++ boehm-gc/include/gc_pthread_redirects.h Sat Sep 13 02:10:15 2003
+@@ -52,15 +52,21 @@
+ int GC_pthread_create(pthread_t *new_thread,
+ const pthread_attr_t *attr,
+ void *(*start_routine)(void *), void *arg);
++#ifndef GC_DARWIN_THREADS
+ int GC_pthread_sigmask(int how, const sigset_t *set, sigset_t *oset);
++#endif
+ int GC_pthread_join(pthread_t thread, void **retval);
+ int GC_pthread_detach(pthread_t thread);
+
+ # define pthread_create GC_pthread_create
++#ifndef GC_DARWIN_THREADS
+ # define pthread_sigmask GC_pthread_sigmask
++#endif
+ # define pthread_join GC_pthread_join
+ # define pthread_detach GC_pthread_detach
++#ifndef GC_DARWIN_THREADS
+ # define dlopen GC_dlopen
++#endif
+
+ #endif /* GC_xxxxx_THREADS */
+
+diff -buNr boehm-gc/include/gc_typed.h boehm-gc/include/gc_typed.h
+--- boehm-gc/include/gc_typed.h Fri Aug 17 11:30:50 2001
++++ boehm-gc/include/gc_typed.h Sat Sep 13 02:10:15 2003
+@@ -29,14 +29,21 @@
+ # include "gc.h"
+ # endif
+
++#ifdef __cplusplus
++ extern "C" {
++#endif
+ typedef GC_word * GC_bitmap;
+ /* The least significant bit of the first word is one if */
+ /* the first word in the object may be a pointer. */
+
++# define GC_WORDSZ (8*sizeof(GC_word))
+ # define GC_get_bit(bm, index) \
+- (((bm)[divWORDSZ(index)] >> modWORDSZ(index)) & 1)
++ (((bm)[index/GC_WORDSZ] >> (index%GC_WORDSZ)) & 1)
+ # define GC_set_bit(bm, index) \
+- (bm)[divWORDSZ(index)] |= (word)1 << modWORDSZ(index)
++ (bm)[index/GC_WORDSZ] |= ((GC_word)1 << (index%GC_WORDSZ))
++# define GC_WORD_OFFSET(t, f) (offsetof(t,f)/sizeof(GC_word))
++# define GC_WORD_LEN(t) (sizeof(t)/ sizeof(GC_word))
++# define GC_BITMAP_SIZE(t) ((GC_WORD_LEN(t) + GC_WORDSZ-1)/GC_WORDSZ)
+
+ typedef GC_word GC_descr;
+
+@@ -57,6 +64,16 @@
+ /* is intended to be called once per type, not once */
+ /* per allocation. */
+
++/* It is possible to generate a descriptor for a C type T with */
++/* word aligned pointer fields f1, f2, ... as follows: */
++/* */
++/* GC_descr T_descr;
++/* GC_word T_bitmap[GC_BITMAP_SIZE(T)] = {0}; */
++/* GC_set_bit(T_bitmap, GC_WORD_OFFSET(T,f1)); */
++/* GC_set_bit(T_bitmap, GC_WORD_OFFSET(T,f2)); */
++/* ... */
++/* T_descr = GC_make_descriptor(T_bitmap, GC_WORD_LEN(T)); */
++
+ GC_API GC_PTR GC_malloc_explicitly_typed
+ GC_PROTO((size_t size_in_bytes, GC_descr d));
+ /* Allocate an object whose layout is described by d. */
+@@ -79,15 +96,18 @@
+ /* Returned object is cleared. */
+
+ #ifdef GC_DEBUG
+-# define GC_MALLOC_EXPLICTLY_TYPED(bytes, d) GC_MALLOC(bytes)
+-# define GC_CALLOC_EXPLICTLY_TYPED(n, bytes, d) GC_MALLOC(n*bytes)
++# define GC_MALLOC_EXPLICITLY_TYPED(bytes, d) GC_MALLOC(bytes)
++# define GC_CALLOC_EXPLICITLY_TYPED(n, bytes, d) GC_MALLOC(n*bytes)
+ #else
+-# define GC_MALLOC_EXPLICTLY_TYPED(bytes, d) \
++# define GC_MALLOC_EXPLICITLY_TYPED(bytes, d) \
+ GC_malloc_explicitly_typed(bytes, d)
+-# define GC_CALLOC_EXPLICTLY_TYPED(n, bytes, d) \
++# define GC_CALLOC_EXPLICITLY_TYPED(n, bytes, d) \
+ GC_calloc_explicitly_typed(n, bytes, d)
+ #endif /* !GC_DEBUG */
+
++#ifdef __cplusplus
++ } /* matches extern "C" */
++#endif
+
+ #endif /* _GC_TYPED_H */
+
+diff -buNr boehm-gc/include/new_gc_alloc.h boehm-gc/include/new_gc_alloc.h
+--- boehm-gc/include/new_gc_alloc.h Tue Oct 16 02:01:38 2001
++++ boehm-gc/include/new_gc_alloc.h Sat Sep 13 02:10:15 2003
+@@ -64,6 +64,14 @@
+ #endif
+ #endif
+
++/* A hack to deal with gcc 3.1. If you are using gcc3.1 and later, */
++/* you should probably really use gc_allocator.h instead. */
++#if defined (__GNUC__) && \
++ (__GNUC > 3 || (__GNUC__ == 3 && (__GNUC_MINOR__ >= 1)))
++# define simple_alloc __simple_alloc
++#endif
++
++
+
+ #define GC_ALLOC_H
+
+diff -buNr boehm-gc/include/private/darwin_semaphore.h boehm-gc/include/private/darwin_semaphore.h
+--- boehm-gc/include/private/darwin_semaphore.h Wed Dec 31 16:00:00 1969
++++ boehm-gc/include/private/darwin_semaphore.h Sat Sep 13 02:10:15 2003
+@@ -0,0 +1,68 @@
++#ifndef GC_DARWIN_SEMAPHORE_H
++#define GC_DARWIN_SEMAPHORE_H
++
++#if !defined(GC_DARWIN_THREADS)
++#error darwin_semaphore.h included with GC_DARWIN_THREADS not defined
++#endif
++
++/*
++ This is a very simple semaphore implementation for darwin. It
++ is implemented in terms of pthreads calls so it isn't async signal
++ safe. This isn't a problem because signals aren't used to
++ suspend threads on darwin.
++*/
++
++typedef struct {
++ pthread_mutex_t mutex;
++ pthread_cond_t cond;
++ int value;
++} sem_t;
++
++static int sem_init(sem_t *sem, int pshared, int value) {
++ int ret;
++ if(pshared)
++ GC_abort("sem_init with pshared set");
++ sem->value = value;
++
++ ret = pthread_mutex_init(&sem->mutex,NULL);
++ if(ret < 0) return -1;
++ ret = pthread_cond_init(&sem->cond,NULL);
++ if(ret < 0) return -1;
++ return 0;
++}
++
++static int sem_post(sem_t *sem) {
++ if(pthread_mutex_lock(&sem->mutex) < 0)
++ return -1;
++ sem->value++;
++ if(pthread_cond_signal(&sem->cond) < 0) {
++ pthread_mutex_unlock(&sem->mutex);
++ return -1;
++ }
++ if(pthread_mutex_unlock(&sem->mutex) < 0)
++ return -1;
++ return 0;
++}
++
++static int sem_wait(sem_t *sem) {
++ if(pthread_mutex_lock(&sem->mutex) < 0)
++ return -1;
++ while(sem->value == 0) {
++ pthread_cond_wait(&sem->cond,&sem->mutex);
++ }
++ sem->value--;
++ if(pthread_mutex_unlock(&sem->mutex) < 0)
++ return -1;
++ return 0;
++}
++
++static int sem_destroy(sem_t *sem) {
++ int ret;
++ ret = pthread_cond_destroy(&sem->cond);
++ if(ret < 0) return -1;
++ ret = pthread_mutex_destroy(&sem->mutex);
++ if(ret < 0) return -1;
++ return 0;
++}
++
++#endif
+diff -buNr boehm-gc/include/private/darwin_stop_world.h boehm-gc/include/private/darwin_stop_world.h
+--- boehm-gc/include/private/darwin_stop_world.h Wed Dec 31 16:00:00 1969
++++ boehm-gc/include/private/darwin_stop_world.h Sat Sep 13 02:10:15 2003
+@@ -0,0 +1,15 @@
++#ifndef GC_DARWIN_STOP_WORLD_H
++#define GC_DARWIN_STOP_WORLD_H
++
++#if !defined(GC_DARWIN_THREADS)
++#error darwin_stop_world.h included without GC_DARWIN_THREADS defined
++#endif
++
++#include <mach/mach.h>
++#include <mach/thread_act.h>
++
++struct thread_stop_info {
++ mach_port_t mach_thread;
++};
++
++#endif
+diff -buNr boehm-gc/include/private/dbg_mlc.h boehm-gc/include/private/dbg_mlc.h
+--- boehm-gc/include/private/dbg_mlc.h Mon Feb 11 20:37:57 2002
++++ boehm-gc/include/private/dbg_mlc.h Sat Sep 13 02:10:15 2003
+@@ -115,16 +115,24 @@
+
+ #ifdef SHORT_DBG_HDRS
+ # define DEBUG_BYTES (sizeof (oh))
++# define UNCOLLECTABLE_DEBUG_BYTES DEBUG_BYTES
+ #else
+ /* Add space for END_FLAG, but use any extra space that was already */
+ /* added to catch off-the-end pointers. */
+-# define DEBUG_BYTES (sizeof (oh) + sizeof (word) - EXTRA_BYTES)
++ /* For uncollectable objects, the extra byte is not added. */
++# define UNCOLLECTABLE_DEBUG_BYTES (sizeof (oh) + sizeof (word))
++# define DEBUG_BYTES (UNCOLLECTABLE_DEBUG_BYTES - EXTRA_BYTES)
+ #endif
+ #define USR_PTR_FROM_BASE(p) ((ptr_t)(p) + sizeof(oh))
+
+ /* Round bytes to words without adding extra byte at end. */
+ #define SIMPLE_ROUNDED_UP_WORDS(n) BYTES_TO_WORDS((n) + WORDS_TO_BYTES(1) - 1)
+
++/* ADD_CALL_CHAIN stores a (partial) call chain into an object */
++/* header. It may be called with or without the allocation */
++/* lock. */
++/* PRINT_CALL_CHAIN prints the call chain stored in an object */
++/* to stderr. It requires that we do not hold the lock. */
+ #ifdef SAVE_CALL_CHAIN
+ # define ADD_CALL_CHAIN(base, ra) GC_save_callers(((oh *)(base)) -> oh_ci)
+ # define PRINT_CALL_CHAIN(base) GC_print_callers(((oh *)(base)) -> oh_ci)
+diff -buNr boehm-gc/include/private/gc_hdrs.h boehm-gc/include/private/gc_hdrs.h
+--- boehm-gc/include/private/gc_hdrs.h Fri Aug 17 18:04:43 2001
++++ boehm-gc/include/private/gc_hdrs.h Sat Sep 13 02:10:15 2003
+@@ -70,7 +70,7 @@
+ #define ADVANCE(p, hhdr, source) \
+ { \
+ hdr * new_hdr = GC_invalid_header; \
+- p = GC_FIND_START(p, hhdr, &new_hdr, (word)source); \
++ p = GC_find_start(p, hhdr, &new_hdr); \
+ hhdr = new_hdr; \
+ }
+
+diff -buNr boehm-gc/include/private/gc_locks.h boehm-gc/include/private/gc_locks.h
+--- boehm-gc/include/private/gc_locks.h Fri Sep 27 13:40:06 2002
++++ boehm-gc/include/private/gc_locks.h Sat Sep 13 02:10:15 2003
+@@ -145,23 +145,24 @@
+ # if defined(POWERPC)
+ inline static int GC_test_and_set(volatile unsigned int *addr) {
+ int oldval;
+- int temp = 1; // locked value
++ int temp = 1; /* locked value */
+
+ __asm__ __volatile__(
+- "1:\tlwarx %0,0,%3\n" // load and reserve
+- "\tcmpwi %0, 0\n" // if load is
+- "\tbne 2f\n" // non-zero, return already set
+- "\tstwcx. %2,0,%1\n" // else store conditional
+- "\tbne- 1b\n" // retry if lost reservation
+- "2:\t\n" // oldval is zero if we set
++ "1:\tlwarx %0,0,%3\n" /* load and reserve */
++ "\tcmpwi %0, 0\n" /* if load is */
++ "\tbne 2f\n" /* non-zero, return already set */
++ "\tstwcx. %2,0,%1\n" /* else store conditional */
++ "\tbne- 1b\n" /* retry if lost reservation */
++ "\tsync\n" /* import barrier */
++ "2:\t\n" /* oldval is zero if we set */
+ : "=&r"(oldval), "=p"(addr)
+ : "r"(temp), "1"(addr)
+- : "memory");
+- return (int)oldval;
++ : "cr0","memory");
++ return oldval;
+ }
+ # define GC_TEST_AND_SET_DEFINED
+ inline static void GC_clear(volatile unsigned int *addr) {
+- __asm__ __volatile__("eieio" ::: "memory");
++ __asm__ __volatile__("eieio" : : : "memory");
+ *(addr) = 0;
+ }
+ # define GC_CLEAR_DEFINED
+@@ -191,8 +192,11 @@
+ return oldvalue;
+ }
+ # define GC_TEST_AND_SET_DEFINED
+- /* Should probably also define GC_clear, since it needs */
+- /* a memory barrier ?? */
++ inline static void GC_clear(volatile unsigned int *addr) {
++ __asm__ __volatile__("mb" : : : "memory");
++ *(addr) = 0;
++ }
++# define GC_CLEAR_DEFINED
+ # endif /* ALPHA */
+ # ifdef ARM32
+ inline static int GC_test_and_set(volatile unsigned int *addr) {
+@@ -224,8 +228,16 @@
+ # endif
+ # endif /* __GNUC__ */
+ # if (defined(ALPHA) && !defined(__GNUC__))
+-# define GC_test_and_set(addr) __cxx_test_and_set_atomic(addr, 1)
++# ifndef OSF1
++ --> We currently assume that if gcc is not used, we are
++ --> running under Tru64.
++# endif
++# include <machine/builtins.h>
++# include <c_asm.h>
++# define GC_test_and_set(addr) __ATOMIC_EXCH_LONG(addr, 1)
+ # define GC_TEST_AND_SET_DEFINED
++# define GC_clear(addr) { asm("mb"); *(volatile unsigned *)addr = 0; }
++# define GC_CLEAR_DEFINED
+ # endif
+ # if defined(MSWIN32)
+ # define GC_test_and_set(addr) InterlockedExchange((LPLONG)addr,1)
+@@ -238,7 +250,11 @@
+ # define GC_TEST_AND_SET_DEFINED
+ # elif __mips < 3 || !(defined (_ABIN32) || defined(_ABI64)) \
+ || !defined(_COMPILER_VERSION) || _COMPILER_VERSION < 700
+-# define GC_test_and_set(addr) test_and_set(addr, 1)
++# ifdef __GNUC__
++# define GC_test_and_set(addr) _test_and_set(addr,1)
++# else
++# define GC_test_and_set(addr) test_and_set(addr,1)
++# endif
+ # else
+ # define GC_test_and_set(addr) __test_and_set(addr,1)
+ # define GC_clear(addr) __lock_release(addr);
+@@ -279,7 +295,7 @@
+ # endif
+
+ # if defined(GC_PTHREADS) && !defined(GC_SOLARIS_THREADS) \
+- && !defined(GC_IRIX_THREADS)
++ && !defined(GC_IRIX_THREADS) && !defined(GC_WIN32_THREADS)
+ # define NO_THREAD (pthread_t)(-1)
+ # include <pthread.h>
+ # if defined(PARALLEL_MARK)
+@@ -310,12 +326,12 @@
+ {
+ char result;
+ __asm__ __volatile__("lock; cmpxchgl %2, %0; setz %1"
+- : "=m"(*(addr)), "=r"(result)
+- : "r" (new_val), "0"(*(addr)), "a"(old) : "memory");
++ : "+m"(*(addr)), "=r"(result)
++ : "r" (new_val), "a"(old) : "memory");
+ return (GC_bool) result;
+ }
+ # endif /* !GENERIC_COMPARE_AND_SWAP */
+- inline static void GC_memory_write_barrier()
++ inline static void GC_memory_barrier()
+ {
+ /* We believe the processor ensures at least processor */
+ /* consistent ordering. Thus a compiler barrier */
+@@ -323,6 +339,37 @@
+ __asm__ __volatile__("" : : : "memory");
+ }
+ # endif /* I386 */
++
++# if defined(POWERPC)
++# if !defined(GENERIC_COMPARE_AND_SWAP)
++ /* Returns TRUE if the comparison succeeded. */
++ inline static GC_bool GC_compare_and_exchange(volatile GC_word *addr,
++ GC_word old, GC_word new_val)
++ {
++ int result, dummy;
++ __asm__ __volatile__(
++ "1:\tlwarx %0,0,%5\n"
++ "\tcmpw %0,%4\n"
++ "\tbne 2f\n"
++ "\tstwcx. %3,0,%2\n"
++ "\tbne- 1b\n"
++ "\tsync\n"
++ "\tli %1, 1\n"
++ "\tb 3f\n"
++ "2:\tli %1, 0\n"
++ "3:\t\n"
++ : "=&r" (dummy), "=r" (result), "=p" (addr)
++ : "r" (new_val), "r" (old), "2"(addr)
++ : "cr0","memory");
++ return (GC_bool) result;
++ }
++# endif /* !GENERIC_COMPARE_AND_SWAP */
++ inline static void GC_memory_barrier()
++ {
++ __asm__ __volatile__("sync" : : : "memory");
++ }
++# endif /* POWERPC */
++
+ # if defined(IA64)
+ # if !defined(GENERIC_COMPARE_AND_SWAP)
+ inline static GC_bool GC_compare_and_exchange(volatile GC_word *addr,
+@@ -337,12 +384,52 @@
+ # endif /* !GENERIC_COMPARE_AND_SWAP */
+ # if 0
+ /* Shouldn't be needed; we use volatile stores instead. */
+- inline static void GC_memory_write_barrier()
++ inline static void GC_memory_barrier()
+ {
+ __asm__ __volatile__("mf" : : : "memory");
+ }
+ # endif /* 0 */
+ # endif /* IA64 */
++# if defined(ALPHA)
++# if !defined(GENERIC_COMPARE_AND_SWAP)
++# if defined(__GNUC__)
++ inline static GC_bool GC_compare_and_exchange(volatile GC_word *addr,
++ GC_word old, GC_word new_val)
++ {
++ unsigned long was_equal;
++ unsigned long temp;
++
++ __asm__ __volatile__(
++ "1: ldq_l %0,%1\n"
++ " cmpeq %0,%4,%2\n"
++ " mov %3,%0\n"
++ " beq %2,2f\n"
++ " stq_c %0,%1\n"
++ " beq %0,1b\n"
++ "2:\n"
++ " mb\n"
++ :"=&r" (temp), "=m" (*addr), "=&r" (was_equal)
++ : "r" (new_val), "Ir" (old)
++ :"memory");
++ return was_equal;
++ }
++# else /* !__GNUC__ */
++ inline static GC_bool GC_compare_and_exchange(volatile GC_word *addr,
++ GC_word old, GC_word new_val)
++ {
++ return __CMP_STORE_QUAD(addr, old, new_val, addr);
++ }
++# endif /* !__GNUC__ */
++# endif /* !GENERIC_COMPARE_AND_SWAP */
++# ifdef __GNUC__
++ inline static void GC_memory_barrier()
++ {
++ __asm__ __volatile__("mb" : : : "memory");
++ }
++# else
++# define GC_memory_barrier() asm("mb")
++# endif /* !__GNUC__ */
++# endif /* ALPHA */
+ # if defined(S390)
+ # if !defined(GENERIC_COMPARE_AND_SWAP)
+ inline static GC_bool GC_compare_and_exchange(volatile C_word *addr,
+@@ -434,8 +521,12 @@
+ { GC_ASSERT(I_HOLD_LOCK()); UNSET_LOCK_HOLDER(); \
+ pthread_mutex_unlock(&GC_allocate_ml); }
+ # else /* !GC_ASSERTIONS */
++# if defined(NO_PTHREAD_TRYLOCK)
++# define LOCK() GC_lock();
++# else /* !defined(NO_PTHREAD_TRYLOCK) */
+ # define LOCK() \
+ { if (0 != pthread_mutex_trylock(&GC_allocate_ml)) GC_lock(); }
++# endif
+ # define UNLOCK() pthread_mutex_unlock(&GC_allocate_ml)
+ # endif /* !GC_ASSERTIONS */
+ # endif /* USE_PTHREAD_LOCKS */
+@@ -478,11 +569,18 @@
+ }
+ # define EXIT_GC() GC_collecting = 0;
+ # endif /* GC_IRIX_THREADS */
+-# ifdef GC_WIN32_THREADS
++# if defined(GC_WIN32_THREADS)
++# if defined(GC_PTHREADS)
++# include <pthread.h>
++ extern pthread_mutex_t GC_allocate_ml;
++# define LOCK() pthread_mutex_lock(&GC_allocate_ml)
++# define UNLOCK() pthread_mutex_unlock(&GC_allocate_ml)
++# else
+ # include <windows.h>
+ GC_API CRITICAL_SECTION GC_allocate_ml;
+ # define LOCK() EnterCriticalSection(&GC_allocate_ml);
+ # define UNLOCK() LeaveCriticalSection(&GC_allocate_ml);
++# endif
+ # endif
+ # ifndef SET_LOCK_HOLDER
+ # define SET_LOCK_HOLDER()
+diff -buNr boehm-gc/include/private/gc_pmark.h boehm-gc/include/private/gc_pmark.h
+--- boehm-gc/include/private/gc_pmark.h Mon Feb 11 20:37:57 2002
++++ boehm-gc/include/private/gc_pmark.h Sat Sep 13 02:10:15 2003
+@@ -137,7 +137,7 @@
+ #ifdef __STDC__
+ # ifdef PRINT_BLACK_LIST
+ ptr_t GC_find_start(ptr_t current, hdr *hhdr, hdr **new_hdr_p,
+- ptr_t source);
++ word source);
+ # else
+ ptr_t GC_find_start(ptr_t current, hdr *hhdr, hdr **new_hdr_p);
+ # endif
+@@ -145,7 +145,7 @@
+ ptr_t GC_find_start();
+ #endif
+
+-mse *GC_signal_mark_stack_overflow(mse *msp);
++mse * GC_signal_mark_stack_overflow GC_PROTO((mse *msp));
+
+ # ifdef GATHERSTATS
+ # define ADD_TO_ATOMIC(sz) GC_atomic_in_use += (sz)
+@@ -174,14 +174,6 @@
+ } \
+ }
+
+-#ifdef PRINT_BLACK_LIST
+-# define GC_FIND_START(current, hhdr, new_hdr_p, source) \
+- GC_find_start(current, hhdr, new_hdr_p, source)
+-#else
+-# define GC_FIND_START(current, hhdr, new_hdr_p, source) \
+- GC_find_start(current, hhdr, new_hdr_p)
+-#endif
+-
+ /* Push the contents of current onto the mark stack if it is a valid */
+ /* ptr to a currently unmarked object. Mark it. */
+ /* If we assumed a standard-conforming compiler, we could probably */
+@@ -195,8 +187,7 @@
+ GET_HDR(my_current, my_hhdr); \
+ if (IS_FORWARDING_ADDR_OR_NIL(my_hhdr)) { \
+ hdr * new_hdr = GC_invalid_header; \
+- my_current = GC_FIND_START(my_current, my_hhdr, \
+- &new_hdr, (word)source); \
++ my_current = GC_find_start(my_current, my_hhdr, &new_hdr); \
+ my_hhdr = new_hdr; \
+ } \
+ PUSH_CONTENTS_HDR(my_current, mark_stack_top, mark_stack_limit, \
+@@ -290,21 +281,39 @@
+
+ /*
+ * Push a single value onto mark stack. Mark from the object pointed to by p.
++ * Invoke FIXUP_POINTER(p) before any further processing.
+ * P is considered valid even if it is an interior pointer.
+ * Previously marked objects are not pushed. Hence we make progress even
+ * if the mark stack overflows.
+ */
++
++# if NEED_FIXUP_POINTER
++ /* Try both the raw version and the fixed up one. */
+ # define GC_PUSH_ONE_STACK(p, source) \
+ if ((ptr_t)(p) >= (ptr_t)GC_least_plausible_heap_addr \
+ && (ptr_t)(p) < (ptr_t)GC_greatest_plausible_heap_addr) { \
+ PUSH_ONE_CHECKED_STACK(p, source); \
++ } \
++ FIXUP_POINTER(p); \
++ if ((ptr_t)(p) >= (ptr_t)GC_least_plausible_heap_addr \
++ && (ptr_t)(p) < (ptr_t)GC_greatest_plausible_heap_addr) { \
++ PUSH_ONE_CHECKED_STACK(p, source); \
+ }
++# else /* !NEED_FIXUP_POINTER */
++# define GC_PUSH_ONE_STACK(p, source) \
++ if ((ptr_t)(p) >= (ptr_t)GC_least_plausible_heap_addr \
++ && (ptr_t)(p) < (ptr_t)GC_greatest_plausible_heap_addr) { \
++ PUSH_ONE_CHECKED_STACK(p, source); \
++ }
++# endif
++
+
+ /*
+ * As above, but interior pointer recognition as for
+ * normal for heap pointers.
+ */
+ # define GC_PUSH_ONE_HEAP(p,source) \
++ FIXUP_POINTER(p); \
+ if ((ptr_t)(p) >= (ptr_t)GC_least_plausible_heap_addr \
+ && (ptr_t)(p) < (ptr_t)GC_greatest_plausible_heap_addr) { \
+ GC_mark_stack_top = GC_mark_and_push( \
+diff -buNr boehm-gc/include/private/gc_priv.h boehm-gc/include/private/gc_priv.h
+--- boehm-gc/include/private/gc_priv.h Tue Mar 4 09:56:49 2003
++++ boehm-gc/include/private/gc_priv.h Sat Sep 13 02:10:15 2003
+@@ -30,6 +30,12 @@
+ # define BSD_TIME
+ #endif
+
++#ifdef DGUX
++# include <sys/types.h>
++# include <sys/time.h>
++# include <sys/resource.h>
++#endif /* DGUX */
++
+ #ifdef BSD_TIME
+ # include <sys/types.h>
+ # include <sys/time.h>
+@@ -210,7 +216,6 @@
+ # define ALIGN_DOUBLE
+ #endif
+
+-
+ /* ALIGN_DOUBLE requires MERGE_SIZES at present. */
+ # if defined(ALIGN_DOUBLE) && !defined(MERGE_SIZES)
+ # define MERGE_SIZES
+@@ -347,7 +352,8 @@
+ # include <string.h>
+ # define BCOPY_EXISTS
+ # endif
+-# if defined(MACOSX)
++# if defined(DARWIN)
++# include <string.h>
+ # define BCOPY_EXISTS
+ # endif
+
+@@ -360,68 +366,6 @@
+ # define BZERO(x,n) bzero((char *)(x),(int)(n))
+ # endif
+
+-/* HBLKSIZE aligned allocation. 0 is taken to mean failure */
+-/* space is assumed to be cleared. */
+-/* In the case os USE_MMAP, the argument must also be a */
+-/* physical page size. */
+-/* GET_MEM is currently not assumed to retrieve 0 filled space, */
+-/* though we should perhaps take advantage of the case in which */
+-/* does. */
+-struct hblk; /* See below. */
+-# ifdef PCR
+- char * real_malloc();
+-# define GET_MEM(bytes) HBLKPTR(real_malloc((size_t)bytes + GC_page_size) \
+- + GC_page_size-1)
+-# else
+-# ifdef OS2
+- void * os2_alloc(size_t bytes);
+-# define GET_MEM(bytes) HBLKPTR((ptr_t)os2_alloc((size_t)bytes \
+- + GC_page_size) \
+- + GC_page_size-1)
+-# else
+-# if defined(NEXT) || defined(MACOSX) || defined(DOS4GW) || \
+- (defined(AMIGA) && !defined(GC_AMIGA_FASTALLOC)) || \
+- (defined(SUNOS5) && !defined(USE_MMAP))
+-# define GET_MEM(bytes) HBLKPTR((size_t) \
+- calloc(1, (size_t)bytes + GC_page_size) \
+- + GC_page_size-1)
+-# else
+-# ifdef MSWIN32
+- extern ptr_t GC_win32_get_mem();
+-# define GET_MEM(bytes) (struct hblk *)GC_win32_get_mem(bytes)
+-# else
+-# ifdef MACOS
+-# if defined(USE_TEMPORARY_MEMORY)
+- extern Ptr GC_MacTemporaryNewPtr(size_t size,
+- Boolean clearMemory);
+-# define GET_MEM(bytes) HBLKPTR( \
+- GC_MacTemporaryNewPtr(bytes + GC_page_size, true) \
+- + GC_page_size-1)
+-# else
+-# define GET_MEM(bytes) HBLKPTR( \
+- NewPtrClear(bytes + GC_page_size) + GC_page_size-1)
+-# endif
+-# else
+-# ifdef MSWINCE
+- extern ptr_t GC_wince_get_mem();
+-# define GET_MEM(bytes) (struct hblk *)GC_wince_get_mem(bytes)
+-# else
+-# if defined(AMIGA) && defined(GC_AMIGA_FASTALLOC)
+- extern void *GC_amiga_get_mem(size_t size);
+- define GET_MEM(bytes) HBLKPTR((size_t) \
+- GC_amiga_get_mem((size_t)bytes + GC_page_size) \
+- + GC_page_size-1)
+-# else
+- extern ptr_t GC_unix_get_mem();
+-# define GET_MEM(bytes) (struct hblk *)GC_unix_get_mem(bytes)
+-# endif
+-# endif
+-# endif
+-# endif
+-# endif
+-# endif
+-# endif
+-
+ /* Delay any interrupts or signals that may abort this thread. Data */
+ /* structures are in a consistent state outside this pair of calls. */
+ /* ANSI C allows both to be empty (though the standard isn't very */
+@@ -486,7 +430,7 @@
+ # ifdef SMALL_CONFIG
+ # define ABORT(msg) abort();
+ # else
+- GC_API void GC_abort();
++ GC_API void GC_abort GC_PROTO((GC_CONST char * msg));
+ # define ABORT(msg) GC_abort(msg);
+ # endif
+ # endif
+@@ -646,9 +590,10 @@
+ */
+
+ # ifdef LARGE_CONFIG
+-# define LOG_PHT_ENTRIES 19 /* Collisions likely at 512K blocks, */
+- /* which is >= 2GB. Each table takes */
+- /* 64KB. */
++# define LOG_PHT_ENTRIES 20 /* Collisions likely at 1M blocks, */
++ /* which is >= 4GB. Each table takes */
++ /* 128KB, some of which may never be */
++ /* touched. */
+ # else
+ # ifdef SMALL_CONFIG
+ # define LOG_PHT_ENTRIES 14 /* Collisions are likely if heap grows */
+@@ -656,7 +601,7 @@
+ /* Each hash table occupies 2K bytes. */
+ # else /* default "medium" configuration */
+ # define LOG_PHT_ENTRIES 16 /* Collisions are likely if heap grows */
+- /* to more than 16K hblks >= 256MB. */
++ /* to more than 64K hblks >= 256MB. */
+ /* Each hash table occupies 8K bytes. */
+ # endif
+ # endif
+@@ -897,6 +842,10 @@
+ word _mem_freed;
+ /* Number of explicitly deallocated words of memory */
+ /* since last collection. */
++ word _finalizer_mem_freed;
++ /* Words of memory explicitly deallocated while */
++ /* finalizers were running. Used to approximate mem. */
++ /* explicitly deallocated by finalizers. */
+ ptr_t _scratch_end_ptr;
+ ptr_t _scratch_last_end_ptr;
+ /* Used by headers.c, and can easily appear to point to */
+@@ -957,7 +906,7 @@
+ /* OFFSET_TOO_BIG if the value j would be too */
+ /* large to fit in the entry. (Note that the */
+ /* size of these entries matters, both for */
+- /* space consumption and for cache utilization. */
++ /* space consumption and for cache utilization.) */
+ # define OFFSET_TOO_BIG 0xfe
+ # define OBJ_INVALID 0xff
+ # define MAP_ENTRY(map, bytes) (map)[bytes]
+@@ -1067,6 +1016,7 @@
+ # define GC_words_finalized GC_arrays._words_finalized
+ # define GC_non_gc_bytes_at_gc GC_arrays._non_gc_bytes_at_gc
+ # define GC_mem_freed GC_arrays._mem_freed
++# define GC_finalizer_mem_freed GC_arrays._finalizer_mem_freed
+ # define GC_scratch_end_ptr GC_arrays._scratch_end_ptr
+ # define GC_scratch_last_end_ptr GC_arrays._scratch_last_end_ptr
+ # define GC_mark_procs GC_arrays._mark_procs
+@@ -1201,17 +1151,19 @@
+ /* header structure associated with */
+ /* block. */
+
+-extern GC_bool GC_is_initialized; /* GC_init() has been run. */
+-
+ extern GC_bool GC_objects_are_marked; /* There are marked objects in */
+ /* the heap. */
+
+ #ifndef SMALL_CONFIG
+ extern GC_bool GC_incremental;
+ /* Using incremental/generational collection. */
++# define TRUE_INCREMENTAL \
++ (GC_incremental && GC_time_limit != GC_TIME_UNLIMITED)
++ /* True incremental, not just generational, mode */
+ #else
+ # define GC_incremental FALSE
+ /* Hopefully allow optimizer to remove some code. */
++# define TRUE_INCREMENTAL FALSE
+ #endif
+
+ extern GC_bool GC_dirty_maintained;
+@@ -1229,6 +1181,10 @@
+ extern long GC_large_alloc_warn_suppressed;
+ /* Number of warnings suppressed so far. */
+
++#ifdef THREADS
++ extern GC_bool GC_world_stopped;
++#endif
++
+ /* Operations */
+ # ifndef abs
+ # define abs(x) ((x) < 0? (-(x)) : (x))
+@@ -1452,6 +1408,7 @@
+ /* Set all mark bits associated with */
+ /* a free list. */
+ void GC_add_roots_inner GC_PROTO((char * b, char * e, GC_bool tmp));
++void GC_remove_roots_inner GC_PROTO((char * b, char * e));
+ GC_bool GC_is_static_root GC_PROTO((ptr_t p));
+ /* Is the address p in one of the registered static */
+ /* root sections? */
+@@ -1624,6 +1581,8 @@
+ /* until the blocks are available or */
+ /* until it fails by returning FALSE. */
+
++extern GC_bool GC_is_initialized; /* GC_init() has been run. */
++
+ #if defined(MSWIN32) || defined(MSWINCE)
+ void GC_deinit GC_PROTO((void));
+ /* Free any resources allocated by */
+@@ -1666,6 +1625,8 @@
+ /* free list nonempty, and return its */
+ /* head. */
+
++void GC_free_inner(GC_PTR p);
++
+ void GC_init_headers GC_PROTO((void));
+ struct hblkhdr * GC_install_header GC_PROTO((struct hblk *h));
+ /* Install a header for block h. */
+@@ -1695,6 +1656,12 @@
+ /* finalizers to be run, and we haven't called */
+ /* this procedure yet this GC cycle. */
+
++GC_API GC_PTR GC_make_closure GC_PROTO((GC_finalization_proc fn, GC_PTR data));
++GC_API void GC_debug_invoke_finalizer GC_PROTO((GC_PTR obj, GC_PTR data));
++ /* Auxiliary fns to make finalization work */
++ /* correctly with displaced pointers introduced */
++ /* by the debugging allocators. */
++
+ void GC_add_to_heap GC_PROTO((struct hblk *p, word bytes));
+ /* Add a HBLKSIZE aligned chunk to the heap. */
+
+@@ -1704,16 +1671,36 @@
+ /* description of the object to stderr. */
+ extern void (*GC_check_heap) GC_PROTO((void));
+ /* Check that all objects in the heap with */
+- /* debugging info are intact. Print */
+- /* descriptions of any that are not. */
++ /* debugging info are intact. */
++ /* Add any that are not to GC_smashed list. */
++extern void (*GC_print_all_smashed) GC_PROTO((void));
++ /* Print GC_smashed if it's not empty. */
++ /* Clear GC_smashed list. */
++extern void GC_print_all_errors GC_PROTO((void));
++ /* Print smashed and leaked objects, if any. */
++ /* Clear the lists of such objects. */
+ extern void (*GC_print_heap_obj) GC_PROTO((ptr_t p));
+ /* If possible print s followed by a more */
+ /* detailed description of the object */
+ /* referred to by p. */
++#if defined(LINUX) && defined(__ELF__) && !defined(SMALL_CONFIG)
++ void GC_print_address_map GC_PROTO((void));
++ /* Print an address map of the process. */
++#endif
+
++extern GC_bool GC_have_errors; /* We saw a smashed or leaked object. */
++ /* Call error printing routine */
++ /* occasionally. */
+ extern GC_bool GC_print_stats; /* Produce at least some logging output */
+ /* Set from environment variable. */
+
++#ifndef NO_DEBUGGING
++ extern GC_bool GC_dump_regularly; /* Generate regular debugging dumps. */
++# define COND_DUMP if (GC_dump_regularly) GC_dump();
++#else
++# define COND_DUMP
++#endif
++
+ /* Macros used for collector internal allocation. */
+ /* These assume the collector lock is held. */
+ #ifdef DBG_HDRS_ALL
+@@ -1785,6 +1772,7 @@
+ void GC_print_hblkfreelist GC_PROTO((void));
+ void GC_print_heap_sects GC_PROTO((void));
+ void GC_print_static_roots GC_PROTO((void));
++void GC_print_finalization_stats GC_PROTO((void));
+ void GC_dump GC_PROTO((void));
+
+ #ifdef KEEP_BACK_PTRS
+@@ -1866,6 +1854,10 @@
+ # define GC_ASSERT(expr)
+ # endif
+
++/* Check a compile time assertion at compile time. The error */
++/* message for failure is a bit baroque, but ... */
++# define GC_STATIC_ASSERT(expr) sizeof(char[(expr)? 1 : -1])
++
+ # if defined(PARALLEL_MARK) || defined(THREAD_LOCAL_ALLOC)
+ /* We need additional synchronization facilities from the thread */
+ /* support. We believe these are less performance critical */
+@@ -1911,7 +1903,7 @@
+ /* in Linux glibc, but it's not exported.) Thus we continue to use */
+ /* the same hard-coded signals we've always used. */
+ # if !defined(SIG_SUSPEND)
+-# if defined(GC_LINUX_THREADS)
++# if defined(GC_LINUX_THREADS) || defined(GC_DGUX386_THREADS)
+ # if defined(SPARC) && !defined(SIGPWR)
+ /* SPARC/Linux doesn't properly define SIGPWR in <signal.h>.
+ * It is aliased to SIGLOST in asm/signal.h, though. */
+diff -buNr boehm-gc/include/private/gcconfig.h boehm-gc/include/private/gcconfig.h
+--- boehm-gc/include/private/gcconfig.h Wed Apr 9 17:08:01 2003
++++ boehm-gc/include/private/gcconfig.h Sat Sep 13 02:10:15 2003
+@@ -14,10 +14,24 @@
+ * modified is included with the above copyright notice.
+ */
+
++/*
++ * This header is private to the gc. It is almost always included from
++ * gc_priv.h. However it is possible to include it by itself if just the
++ * configuration macros are needed. In that
++ * case, a few declarations relying on types declared in gc_priv.h will be
++ * omitted.
++ */
++
+ #ifndef GCCONFIG_H
+
+ # define GCCONFIG_H
+
++# ifndef GC_PRIVATE_H
++ /* Fake ptr_t declaration, just to avoid compilation errors. */
++ /* This avoids many instances if "ifndef GC_PRIVATE_H" below. */
++ typedef struct GC_undefined_struct * ptr_t;
++# endif
++
+ /* Machine dependent parameters. Some tuning parameters can be found */
+ /* near the top of gc_private.h. */
+
+@@ -44,7 +58,7 @@
+ # endif
+
+ /* Determine the machine type: */
+-# if defined(__arm__) || defined(__thumb__)
++# if defined(__XSCALE__)
+ # define ARM32
+ # if !defined(LINUX)
+ # define NOSYS
+@@ -95,8 +109,8 @@
+ # if defined(nec_ews) || defined(_nec_ews)
+ # define EWS4800
+ # endif
+-# if !defined(LINUX) && !defined(EWS4800) && !defined(NETBSD)
+-# if defined(ultrix) || defined(__ultrix)
++# if !defined(LINUX) && !defined(EWS4800)
++# if defined(ultrix) || defined(__ultrix) || defined(__NetBSD__)
+ # define ULTRIX
+ # else
+ # if defined(_SYSTYPE_SVR4) || defined(SYSTYPE_SVR4) \
+@@ -107,6 +121,16 @@
+ # endif
+ # endif
+ # endif /* !LINUX */
++# if defined(__NetBSD__) && defined(__MIPSEL__)
++# undef ULTRIX
++# endif
++# define mach_type_known
++# endif
++# if defined(DGUX) && (defined(i386) || defined(__i386__))
++# define I386
++# ifndef _USING_DGUX
++# define _USING_DGUX
++# endif
+ # define mach_type_known
+ # endif
+ # if defined(sequent) && (defined(i386) || defined(__i386__))
+@@ -198,6 +222,10 @@
+ # define IA64
+ # define mach_type_known
+ # endif
++# if defined(LINUX) && defined(__arm__)
++# define ARM32
++# define mach_type_known
++# endif
+ # if defined(LINUX) && (defined(powerpc) || defined(__powerpc__))
+ # define POWERPC
+ # define mach_type_known
+@@ -237,19 +265,19 @@
+ # define MACOS
+ # define mach_type_known
+ # endif
+-# if defined(__MWERKS__) && defined(__powerc)
++# if defined(__MWERKS__) && defined(__powerc) && !defined(__MACH__)
+ # define POWERPC
+ # define MACOS
+ # define mach_type_known
+ # endif
+ # if defined(macosx) || \
+ defined(__APPLE__) && defined(__MACH__) && defined(__ppc__)
+-# define MACOSX
++# define DARWIN
+ # define POWERPC
+ # define mach_type_known
+ # endif
+ # if defined(__APPLE__) && defined(__MACH__) && defined(__i386__)
+-# define MACOSX
++# define DARWIN
+ # define I386
+ --> Not really supported, but at least we recognize it.
+ # endif
+@@ -291,7 +319,7 @@
+ # define CX_UX
+ # define mach_type_known
+ # endif
+-# if defined(DGUX)
++# if defined(DGUX) && defined(m88k)
+ # define M88K
+ /* DGUX defined */
+ # define mach_type_known
+@@ -425,8 +453,6 @@
+ /* IA64 ==> Intel IPF */
+ /* (e.g. Itanium) */
+ /* (LINUX and HPUX) */
+- /* IA64_32 ==> IA64 w/32 bit ABI */
+- /* (HPUX) */
+ /* SH ==> Hitachi SuperH */
+ /* (LINUX & MSWINCE) */
+ /* X86_64 ==> AMD x86-64 */
+@@ -450,15 +476,17 @@
+ * defining it to be 1 will always work, but perform poorly.
+ *
+ * DATASTART is the beginning of the data segment.
+- * On UNIX systems, the collector will scan the area between DATASTART
++ * On some platforms SEARCH_FOR_DATA_START is defined.
++ * SEARCH_FOR_DATASTART will cause GC_data_start to
++ * be set to an address determined by accessing data backwards from _end
++ * until an unmapped page is found. DATASTART will be defined to be
++ * GC_data_start.
++ * On UNIX-like systems, the collector will scan the area between DATASTART
+ * and DATAEND for root pointers.
+ *
+ * DATAEND, if not `end' where `end' is defined as ``extern int end[];''.
+ * RTH suggests gaining access to linker script synth'd values with
+ * this idiom instead of `&end' where `end' is defined as ``extern int end;'' .
+- * Otherwise, ``GCC will assume these are in .sdata/.sbss'' and it will, e.g.,
+- * cause failures on alpha*-*-* with ``-msmall-data or -fpic'' or mips-*-*
+- * without any special options.
+ *
+ * ALIGN_DOUBLE of GC_malloc should return blocks aligned to twice
+ * the pointer size.
+@@ -470,8 +498,13 @@
+ * 1) define STACK_GROWS_UP if the stack grows toward higher addresses, and
+ * 2) define exactly one of
+ * STACKBOTTOM (should be defined to be an expression)
++ * LINUX_STACKBOTTOM
+ * HEURISTIC1
+ * HEURISTIC2
++ * If STACKBOTTOM is defined, then it's value will be used directly as the
++ * stack base. If LINUX_STACKBOTTOM is defined, then it will be determined
++ * with a method appropriate for most Linux systems. Currently we look
++ * first for __libc_stack_end, and if that fails read it from /proc.
+ * If either of the last two macros are defined, then STACKBOTTOM is computed
+ * during collector startup using one of the following two heuristics:
+ * HEURISTIC1: Take an address inside GC_init's frame, and round it up to
+@@ -536,6 +569,9 @@
+ * An architecture may also define CLEAR_DOUBLE(x) to be a fast way to
+ * clear the two words at GC_malloc-aligned address x. By default,
+ * word stores of 0 are used instead.
++ *
++ * HEAP_START may be defined as the initial address hint for mmap-based
++ * allocation.
+ */
+
+ /* If we are using a recent version of gcc, we can use __builtin_unwind_init()
+@@ -571,7 +607,7 @@
+ # define DYNAMIC_LOADING
+ # include <features.h>
+ # if defined(__GLIBC__)&& __GLIBC__>=2
+-# define LINUX_DATA_START
++# define SEARCH_FOR_DATA_START
+ # else /* !GLIBC2 */
+ extern char **__environ;
+ # define DATASTART ((ptr_t)(&__environ))
+@@ -669,23 +705,42 @@
+ # define ALIGNMENT 4 /* Guess. Can someone verify? */
+ /* This was 2, but that didn't sound right. */
+ # define OS_TYPE "LINUX"
+-# define DYNAMIC_LOADING
++ /* HEURISTIC1 has been reliably reported to fail for a 32-bit */
++ /* executable on a 64 bit kernel. */
+ # define LINUX_STACKBOTTOM
+- /* Stack usually starts at 0x80000000 */
+-# define LINUX_DATA_START
++# define DYNAMIC_LOADING
++# define SEARCH_FOR_DATA_START
+ extern int _end[];
+ # define DATAEND (_end)
+ # endif
+-# ifdef MACOSX
++# ifdef DARWIN
+ /* There are reasons to suspect this may not be reliable. */
+ # define ALIGNMENT 4
+-# define OS_TYPE "MACOSX"
++# define OS_TYPE "DARWIN"
++# define DYNAMIC_LOADING
++ /* XXX: see get_end(3), get_etext() and get_end() should not be used.
++ These aren't used when dyld support is enabled (it is by default) */
+ # define DATASTART ((ptr_t) get_etext())
++# define DATAEND ((ptr_t) get_end())
+ # define STACKBOTTOM ((ptr_t) 0xc0000000)
+-# define DATAEND /* not needed */
+-# undef MPROTECT_VDB
++# define USE_MMAP
++# define USE_MMAP_ANON
++# define USE_ASM_PUSH_REGS
++ /* This is potentially buggy. It needs more testing. See the comments in
++ os_dep.c */
++# define MPROTECT_VDB
+ # include <unistd.h>
+ # define GETPAGESIZE() getpagesize()
++# if defined(USE_PPC_PREFETCH) && defined(__GNUC__)
++ /* The performance impact of prefetches is untested */
++# define PREFETCH(x) \
++ __asm__ __volatile__ ("dcbt 0,%0" : : "r" ((const void *) (x)))
++# define PREFETCH_FOR_WRITE(x) \
++ __asm__ __volatile__ ("dcbtst 0,%0" : : "r" ((const void *) (x)))
++# endif
++ /* There seems to be some issues with trylock hanging on darwin. This
++ should be looked into some more */
++# define NO_PTHREAD_TRYLOCK
+ # endif
+ # ifdef NETBSD
+ # define ALIGNMENT 4
+@@ -746,8 +801,8 @@
+ # define OS_TYPE "SUNOS5"
+ extern int _etext[];
+ extern int _end[];
+- extern char * GC_SysVGetDataStart();
+-# define DATASTART (ptr_t)GC_SysVGetDataStart(0x10000, _etext)
++ extern ptr_t GC_SysVGetDataStart();
++# define DATASTART GC_SysVGetDataStart(0x10000, _etext)
+ # define DATAEND (_end)
+ # if !defined(USE_MMAP) && defined(REDIRECT_MALLOC)
+ # define USE_MMAP
+@@ -801,9 +856,9 @@
+ # endif
+ # ifdef DRSNX
+ # define OS_TYPE "DRSNX"
+- extern char * GC_SysVGetDataStart();
++ extern ptr_t GC_SysVGetDataStart();
+ extern int etext[];
+-# define DATASTART (ptr_t)GC_SysVGetDataStart(0x10000, etext)
++# define DATASTART GC_SysVGetDataStart(0x10000, etext)
+ # define MPROTECT_VDB
+ # define STACKBOTTOM ((ptr_t) 0xdfff0000)
+ # define DYNAMIC_LOADING
+@@ -819,13 +874,14 @@
+ extern int _etext[];
+ # define DATAEND (_end)
+ # define SVR4
++ extern ptr_t GC_SysVGetDataStart();
+ # ifdef __arch64__
++# define DATASTART GC_SysVGetDataStart(0x100000, _etext)
+ /* libc_stack_end is not set reliably for sparc64 */
+-# define STACKBOTTOM ((ptr_t) 0x80000000000)
+-# define DATASTART (ptr_t)GC_SysVGetDataStart(0x100000, _etext)
++# define STACKBOTTOM ((ptr_t) 0x80000000000ULL)
+ # else
++# define DATASTART GC_SysVGetDataStart(0x10000, _etext)
+ # define LINUX_STACKBOTTOM
+-# define DATASTART (ptr_t)GC_SysVGetDataStart(0x10000, _etext)
+ # endif
+ # endif
+ # ifdef OPENBSD
+@@ -876,7 +932,7 @@
+ # ifdef SUNOS5
+ # define OS_TYPE "SUNOS5"
+ extern int _etext[], _end[];
+- extern char * GC_SysVGetDataStart();
++ extern ptr_t GC_SysVGetDataStart();
+ # define DATASTART GC_SysVGetDataStart(0x1000, _etext)
+ # define DATAEND (_end)
+ /* # define STACKBOTTOM ((ptr_t)(_start)) worked through 2.7, */
+@@ -921,6 +977,28 @@
+ # define DYNAMIC_LOADING
+ # define ELF_CLASS ELFCLASS32
+ # endif
++# ifdef DGUX
++# define OS_TYPE "DGUX"
++ extern int _etext, _end;
++ extern ptr_t GC_SysVGetDataStart();
++# define DATASTART GC_SysVGetDataStart(0x1000, &_etext)
++# define DATAEND (&_end)
++# define STACK_GROWS_DOWN
++# define HEURISTIC2
++# include <unistd.h>
++# define GETPAGESIZE() sysconf(_SC_PAGESIZE)
++# define DYNAMIC_LOADING
++# ifndef USE_MMAP
++# define USE_MMAP
++# endif /* USE_MMAP */
++# define MAP_FAILED (void *) -1
++# ifdef USE_MMAP
++# define HEAP_START (ptr_t)0x40000000
++# else /* USE_MMAP */
++# define HEAP_START DATAEND
++# endif /* USE_MMAP */
++# endif /* DGUX */
++
+ # ifdef LINUX
+ # ifndef __GNUC__
+ /* The Intel compiler doesn't like inline assembly */
+@@ -944,6 +1022,9 @@
+ /* possibly because Linux threads is itself a malloc client */
+ /* and can't deal with the signals. */
+ # endif
++# define HEAP_START 0x1000
++ /* This encourages mmap to give us low addresses, */
++ /* thus allowing the heap to grow to ~3GB */
+ # ifdef __ELF__
+ # define DYNAMIC_LOADING
+ # ifdef UNDEFINED /* includes ro data */
+@@ -952,7 +1033,7 @@
+ # endif
+ # include <features.h>
+ # if defined(__GLIBC__) && __GLIBC__ >= 2
+-# define LINUX_DATA_START
++# define SEARCH_FOR_DATA_START
+ # else
+ extern char **__environ;
+ # define DATASTART ((ptr_t)(&__environ))
+@@ -1061,16 +1142,9 @@
+ # ifdef __ELF__
+ # define DYNAMIC_LOADING
+ # endif
+-/* Handle unmapped hole i386*-*-freebsd[45]* may put between etext and edata. */
+ extern char etext[];
+- extern char edata[];
+- extern char end[];
+-# define NEED_FIND_LIMIT
+-# define DATASTART ((ptr_t)(etext))
+-# define MIN(x,y) ((x) < (y) ? (x) : (y))
+-# define DATAEND (MIN (GC_find_limit (DATASTART, TRUE), DATASTART2))
+-# define DATASTART2 ((ptr_t)(edata))
+-# define DATAEND2 ((ptr_t)(end))
++ extern char * GC_FreeBSDGetDataStart();
++# define DATASTART GC_FreeBSDGetDataStart(0x1000, &etext)
+ # endif
+ # ifdef NETBSD
+ # define OS_TYPE "NETBSD"
+@@ -1149,7 +1223,11 @@
+ # define DATASTART ((ptr_t)(__data_start))
+ # define ALIGNMENT 4
+ # define USE_GENERIC_PUSH_REGS
++# if __GLIBC__ == 2 && __GLIBC_MINOR__ >= 2 || __GLIBC__ > 2
+ # define LINUX_STACKBOTTOM
++# else
++# define STACKBOTTOM 0x80000000
++# endif
+ # endif /* Linux */
+ # ifdef EWS4800
+ # define HEURISTIC2
+@@ -1222,15 +1300,21 @@
+ # define DATAEND /* not needed */
+ # endif
+ # if defined(NETBSD)
+-# define OS_TYPE "NETBSD"
++ /* This also checked for __MIPSEL__ . Why? NETBSD recognition */
++ /* should be handled at the top of the file. */
+ # define ALIGNMENT 4
++# define OS_TYPE "NETBSD"
+ # define HEURISTIC2
+ # define USE_GENERIC_PUSH_REGS
+- extern int _fdata[];
+-# define DATASTART ((ptr_t)(_fdata))
+- extern int _end[];
+-# define DATAEND ((ptr_t)(_end))
++# ifdef __ELF__
++ extern int etext[];
++# define DATASTART GC_data_start
++# define NEED_FIND_LIMIT
+ # define DYNAMIC_LOADING
++# else
++# define DATASTART ((ptr_t) 0x10000000)
++# define STACKBOTTOM ((ptr_t) 0x7ffff000)
++# endif /* _ELF_ */
+ # endif
+ # endif
+
+@@ -1239,15 +1323,16 @@
+ # ifdef __64BIT__
+ # define ALIGNMENT 8
+ # define CPP_WORDSZ 64
++# define STACKBOTTOM 0x1000000000000000
+ # else
+ # define ALIGNMENT 4
+ # define CPP_WORDSZ 32
++# define STACKBOTTOM ((ptr_t)((ulong)&errno))
+ # endif
+ extern int _data[], _end[];
+ # define DATASTART ((ptr_t)((ulong)_data))
+ # define DATAEND ((ptr_t)((ulong)_end))
+ extern int errno;
+-# define STACKBOTTOM ((ptr_t)((ulong)&errno))
+ # define USE_GENERIC_PUSH_REGS
+ # define DYNAMIC_LOADING
+ /* For really old versions of AIX, this may have to be removed. */
+@@ -1311,15 +1396,23 @@
+ # define OS_TYPE "LINUX"
+ # define LINUX_STACKBOTTOM
+ # define DYNAMIC_LOADING
+-# define LINUX_DATA_START
++# define SEARCH_FOR_DATA_START
+ extern int _end[];
+-# define DATAEND (_end)
++# define DATAEND (&_end)
+ # endif /* LINUX */
+ # endif /* HP_PA */
+
+ # ifdef ALPHA
+ # define MACH_TYPE "ALPHA"
+ # define ALIGNMENT 8
++# define CPP_WORDSZ 64
++# ifndef LINUX
++# define USE_GENERIC_PUSH_REGS
++ /* Gcc and probably the DEC/Compaq compiler spill pointers to preserved */
++ /* fp registers in some cases when the target is a 21264. The assembly */
++ /* code doesn't handle that yet, and version dependencies make that a */
++ /* bit tricky. Do the easy thing for now. */
++# endif
+ # ifdef NETBSD
+ # define OS_TYPE "NETBSD"
+ # define HEURISTIC2
+@@ -1327,13 +1420,11 @@
+ # define ELFCLASS32 32
+ # define ELFCLASS64 64
+ # define ELF_CLASS ELFCLASS64
+-# define CPP_WORDSZ 64
+ # define DYNAMIC_LOADING
+ # endif
+ # ifdef OPENBSD
+ # define OS_TYPE "OPENBSD"
+ # define HEURISTIC2
+-# define CPP_WORDSZ 64
+ # ifdef __ELF__ /* since OpenBSD/Alpha 2.9 */
+ # define DATASTART GC_data_start
+ # define ELFCLASS32 32
+@@ -1357,17 +1448,16 @@
+ extern char edata[];
+ extern char end[];
+ # define NEED_FIND_LIMIT
+-# define DATASTART ((ptr_t)(etext))
++# define DATASTART ((ptr_t)(&etext))
+ # define DATAEND (GC_find_limit (DATASTART, TRUE))
+-# define DATASTART2 ((ptr_t)(edata))
+-# define DATAEND2 ((ptr_t)(end))
+-# define CPP_WORDSZ 64
++# define DATASTART2 ((ptr_t)(&edata))
++# define DATAEND2 ((ptr_t)(&end))
+ # endif
+ # ifdef OSF1
+ # define OS_TYPE "OSF1"
+ # define DATASTART ((ptr_t) 0x140000000)
+ extern int _end[];
+-# define DATAEND ((ptr_t) _end)
++# define DATAEND ((ptr_t) &_end)
+ extern char ** environ;
+ /* round up from the value of environ to the nearest page boundary */
+ /* Probably breaks if putenv is called before collector */
+@@ -1380,17 +1470,17 @@
+ /* This is currently unused, since we disabled HEURISTIC2 */
+ extern int __start[];
+ # define HEURISTIC2_LIMIT ((ptr_t)((word)(__start) & ~(getpagesize()-1)))
+-# define CPP_WORDSZ 64
++# ifndef GC_OSF1_THREADS
++ /* Unresolved signal issues with threads. */
+ # define MPROTECT_VDB
++# endif
+ # define DYNAMIC_LOADING
+ # endif
+ # ifdef LINUX
+ # define OS_TYPE "LINUX"
+-# define CPP_WORDSZ 64
+ # define STACKBOTTOM ((ptr_t) 0x120000000)
+ # ifdef __ELF__
+ # define SEARCH_FOR_DATA_START
+-# define DATASTART GC_data_start
+ # define DYNAMIC_LOADING
+ # else
+ # define DATASTART ((ptr_t) 0x140000000)
+@@ -1468,7 +1558,6 @@
+ extern char * GC_register_stackbottom;
+ # define BACKING_STORE_BASE ((ptr_t)GC_register_stackbottom)
+ # define SEARCH_FOR_DATA_START
+-# define DATASTART GC_data_start
+ # ifdef __GNUC__
+ # define DYNAMIC_LOADING
+ # else
+@@ -1502,13 +1591,15 @@
+ # endif
+ # ifdef DGUX
+ # define OS_TYPE "DGUX"
+- extern char * GC_SysVGetDataStart();
+-# define DATASTART (ptr_t)GC_SysVGetDataStart(0x10000, etext)
++ extern ptr_t GC_SysVGetDataStart();
++# define DATASTART GC_SysVGetDataStart(0x10000, etext)
+ # endif
+ # define STACKBOTTOM ((char*)0xf0000000) /* determined empirically */
+ # endif
+
+ # ifdef S370
++ /* If this still works, and if anyone cares, this should probably */
++ /* be moved to the S390 category. */
+ # define MACH_TYPE "S370"
+ # define ALIGNMENT 4 /* Required by hardware */
+ # define USE_GENERIC_PUSH_REGS
+@@ -1517,8 +1608,8 @@
+ extern int etext[];
+ extern int _etext[];
+ extern int _end[];
+- extern char * GC_SysVGetDataStart();
+-# define DATASTART (ptr_t)GC_SysVGetDataStart(0x10000, _etext)
++ extern ptr_t GC_SysVGetDataStart();
++# define DATASTART GC_SysVGetDataStart(0x10000, _etext)
+ # define DATAEND (_end)
+ # define HEURISTIC2
+ # endif
+@@ -1576,7 +1667,7 @@
+ # define DYNAMIC_LOADING
+ # include <features.h>
+ # if defined(__GLIBC__) && __GLIBC__ >= 2
+-# define LINUX_DATA_START
++# define SEARCH_FOR_DATA_START
+ # else
+ extern char **__environ;
+ # define DATASTART ((ptr_t)(&__environ))
+@@ -1623,7 +1714,7 @@
+ # define STACKBOTTOM ((ptr_t) 0x7c000000)
+ # define USE_GENERIC_PUSH_REGS
+ # define DYNAMIC_LOADING
+-# define LINUX_DATA_START
++# define SEARCH_FOR_DATA_START
+ extern int _end[];
+ # define DATAEND (_end)
+ # endif
+@@ -1640,7 +1731,9 @@
+ # define MACH_TYPE "X86_64"
+ # define ALIGNMENT 8
+ # define CPP_WORDSZ 64
++# ifndef HBLKSIZE
+ # define HBLKSIZE 4096
++# endif
+ # define CACHE_LINE_SIZE 64
+ # define USE_GENERIC_PUSH_REGS
+ # ifdef LINUX
+@@ -1660,7 +1753,7 @@
+ # define DATASTART ((ptr_t)((((word) (_etext)) + 0xfff) & ~0xfff))
+ # endif
+ # include <features.h>
+-# define LINUX_DATA_START
++# define SEARCH_FOR_DATA_START
+ extern int _end[];
+ # define DATAEND (_end)
+ # else
+@@ -1674,19 +1767,6 @@
+ # endif
+ # endif
+
+-#ifdef LINUX_DATA_START
+- /* Some Linux distributions arrange to define __data_start. Some */
+- /* define data_start as a weak symbol. The latter is technically */
+- /* broken, since the user program may define data_start, in which */
+- /* case we lose. Nonetheless, we try both, prefering __data_start. */
+- /* We assume gcc. */
+-# pragma weak __data_start
+- extern int __data_start[];
+-# pragma weak data_start
+- extern int data_start[];
+-# define DATASTART ((ptr_t)(__data_start != 0? __data_start : data_start))
+-#endif
+-
+ #if defined(LINUX) && defined(REDIRECT_MALLOC)
+ /* Rld appears to allocate some memory with its own allocator, and */
+ /* some through malloc, which might be redirected. To make this */
+@@ -1742,8 +1822,8 @@
+ # endif
+
+ # if defined(SVR4) || defined(LINUX) || defined(IRIX) || defined(HPUX) \
+- || defined(OPENBSD) || defined(NETBSD) || defined(FREEBSD) \
+- || defined(BSD) || defined(_AIX) || defined(MACOSX) || defined(OSF1)
++ || defined(OPENBSD) || defined(NETBSD) || defined(FREEBSD) || defined(DGUX) \
++ || defined(BSD) || defined(AIX) || defined(DARWIN) || defined(OSF1)
+ # define UNIX_LIKE /* Basic Unix-like system calls work. */
+ # endif
+
+@@ -1762,13 +1842,13 @@
+ # endif
+
+ # ifdef SRC_M3
+-/* Postponed for now. */
++ /* Postponed for now. */
+ # undef PROC_VDB
+ # undef MPROTECT_VDB
+ # endif
+
+ # ifdef SMALL_CONFIG
+-/* Presumably not worth the space it takes. */
++ /* Presumably not worth the space it takes. */
+ # undef PROC_VDB
+ # undef MPROTECT_VDB
+ # endif
+@@ -1808,8 +1888,9 @@
+ /* platforms as well, though it should be avoided in win32. */
+ # endif /* LINUX */
+
+-# if defined(SEARCH_FOR_DATA_START) && defined(GC_PRIVATE_H)
++# if defined(SEARCH_FOR_DATA_START)
+ extern ptr_t GC_data_start;
++# define DATASTART GC_data_start
+ # endif
+
+ # ifndef CLEAR_DOUBLE
+@@ -1818,28 +1899,25 @@
+ ((word*)x)[1] = 0;
+ # endif /* CLEAR_DOUBLE */
+
+-/* Internally we use GC_SOLARIS_THREADS to test for either old or pthreads. */
++ /* Internally we use GC_SOLARIS_THREADS to test for either old or pthreads. */
+ # if defined(GC_SOLARIS_PTHREADS) && !defined(GC_SOLARIS_THREADS)
+ # define GC_SOLARIS_THREADS
+ # endif
+
+ # if defined(GC_IRIX_THREADS) && !defined(IRIX5)
+---> inconsistent configuration
++ --> inconsistent configuration
+ # endif
+ # if defined(GC_LINUX_THREADS) && !defined(LINUX)
+---> inconsistent configuration
++ --> inconsistent configuration
+ # endif
+ # if defined(GC_SOLARIS_THREADS) && !defined(SUNOS5)
+---> inconsistent configuration
++ --> inconsistent configuration
+ # endif
+ # if defined(GC_HPUX_THREADS) && !defined(HPUX)
+---> inconsistent configuration
++ --> inconsistent configuration
+ # endif
+-# if defined(GC_WIN32_THREADS) && !defined(MSWIN32)
+- /* Ideally CYGWIN32 should work, in addition to MSWIN32. I suspect */
+- /* the necessary code is mostly there, but nobody has actually made */
+- /* sure the right combination of pieces is compiled in, etc. */
+---> inconsistent configuration
++# if defined(GC_WIN32_THREADS) && !defined(MSWIN32) && !defined(CYGWIN32)
++ --> inconsistent configuration
+ # endif
+
+ # if defined(PCR) || defined(SRC_M3) || \
+@@ -1848,8 +1926,8 @@
+ # define THREADS
+ # endif
+
+-# if defined(HP_PA) || defined(M88K) || defined(POWERPC) && !defined(MACOSX) \
+- || defined(LINT) || defined(MSWINCE) \
++# if defined(HP_PA) || defined(M88K) || defined(POWERPC) && !defined(DARWIN) \
++ || defined(LINT) || defined(MSWINCE) || defined(ARM32) \
+ || (defined(I386) && defined(__LCC__))
+ /* Use setjmp based hack to mark from callee-save registers. */
+ /* The define should move to the individual platform */
+@@ -1862,36 +1940,26 @@
+ /* include assembly code to do it well. */
+ # endif
+
+-/* Can we save call chain in objects for debugging? */
+-/* SET NFRAMES (# of saved frames) and NARGS (#of args for each frame) */
+-/* to reasonable values for the platform. */
+-/* Set SAVE_CALL_CHAIN if we can. SAVE_CALL_COUNT can be specified at */
+-/* build time, though we feel free to adjust it slightly. */
+-/* Define NEED_CALLINFO if we either save the call stack or */
+-/* GC_ADD_CALLER is defined. */
+-#ifdef LINUX
+-# include <features.h>
+-# if __GLIBC__ == 2 && __GLIBC_MINOR__ >= 1 || __GLIBC__ > 2
+-# define HAVE_BUILTIN_BACKTRACE
+-# endif
+-#endif
++ /* Can we save call chain in objects for debugging? */
++ /* SET NFRAMES (# of saved frames) and NARGS (#of args for each */
++ /* frame) to reasonable values for the platform. */
++ /* Set SAVE_CALL_CHAIN if we can. SAVE_CALL_COUNT can be specified */
++ /* at build time, though we feel free to adjust it slightly. */
++ /* Define NEED_CALLINFO if we either save the call stack or */
++ /* GC_ADD_CALLER is defined. */
++ /* GC_CAN_SAVE_CALL_STACKS is set in gc.h. */
+
+ #if defined(SPARC)
+-# define CAN_SAVE_CALL_STACKS
+ # define CAN_SAVE_CALL_ARGS
+ #endif
+ #if (defined(I386) || defined(X86_64)) && defined(LINUX)
+ /* SAVE_CALL_CHAIN is supported if the code is compiled to save */
+ /* frame pointers by default, i.e. no -fomit-frame-pointer flag. */
+-# define CAN_SAVE_CALL_STACKS
+ # define CAN_SAVE_CALL_ARGS
+ #endif
+-#if defined(HAVE_BUILTIN_BACKTRACE) && !defined(CAN_SAVE_CALL_STACKS)
+-# define CAN_SAVE_CALL_STACKS
+-#endif
+
+ # if defined(SAVE_CALL_COUNT) && !defined(GC_ADD_CALLER) \
+- && defined(CAN_SAVE_CALL_STACKS)
++ && defined(GC_CAN_SAVE_CALL_STACKS)
+ # define SAVE_CALL_CHAIN
+ # endif
+ # ifdef SAVE_CALL_CHAIN
+@@ -1919,5 +1987,97 @@
+ # if defined(MAKE_BACK_GRAPH) && !defined(DBG_HDRS_ALL)
+ # define DBG_HDRS_ALL
+ # endif
++
++# if defined(POINTER_MASK) && !defined(POINTER_SHIFT)
++# define POINTER_SHIFT 0
++# endif
++
++# if defined(POINTER_SHIFT) && !defined(POINTER_MASK)
++# define POINTER_MASK ((GC_word)(-1))
++# endif
++
++# if !defined(FIXUP_POINTER) && defined(POINTER_MASK)
++# define FIXUP_POINTER(p) (p) = ((p) & (POINTER_MASK) << POINTER_SHIFT)
++# endif
++
++# if defined(FIXUP_POINTER)
++# define NEED_FIXUP_POINTER 1
++# else
++# define NEED_FIXUP_POINTER 0
++# define FIXUP_POINTER(p)
++# endif
++
++#ifdef GC_PRIVATE_H
++ /* This relies on some type definitions from gc_priv.h, from */
++ /* where it's normally included. */
++ /* */
++ /* How to get heap memory from the OS: */
++ /* Note that sbrk()-like allocation is preferred, since it */
++ /* usually makes it possible to merge consecutively allocated */
++ /* chunks. It also avoids unintented recursion with */
++ /* -DREDIRECT_MALLOC. */
++ /* GET_MEM() returns a HLKSIZE aligned chunk. */
++ /* 0 is taken to mean failure. */
++ /* In the case os USE_MMAP, the argument must also be a */
++ /* physical page size. */
++ /* GET_MEM is currently not assumed to retrieve 0 filled space, */
++ /* though we should perhaps take advantage of the case in which */
++ /* does. */
++ struct hblk; /* See gc_priv.h. */
++# ifdef PCR
++ char * real_malloc();
++# define GET_MEM(bytes) HBLKPTR(real_malloc((size_t)bytes + GC_page_size) \
++ + GC_page_size-1)
++# else
++# ifdef OS2
++ void * os2_alloc(size_t bytes);
++# define GET_MEM(bytes) HBLKPTR((ptr_t)os2_alloc((size_t)bytes \
++ + GC_page_size) \
++ + GC_page_size-1)
++# else
++# if defined(NEXT) || defined(DOS4GW) || \
++ (defined(AMIGA) && !defined(GC_AMIGA_FASTALLOC)) || \
++ (defined(SUNOS5) && !defined(USE_MMAP))
++# define GET_MEM(bytes) HBLKPTR((size_t) \
++ calloc(1, (size_t)bytes + GC_page_size) \
++ + GC_page_size-1)
++# else
++# ifdef MSWIN32
++ extern ptr_t GC_win32_get_mem();
++# define GET_MEM(bytes) (struct hblk *)GC_win32_get_mem(bytes)
++# else
++# ifdef MACOS
++# if defined(USE_TEMPORARY_MEMORY)
++ extern Ptr GC_MacTemporaryNewPtr(size_t size,
++ Boolean clearMemory);
++# define GET_MEM(bytes) HBLKPTR( \
++ GC_MacTemporaryNewPtr(bytes + GC_page_size, true) \
++ + GC_page_size-1)
++# else
++# define GET_MEM(bytes) HBLKPTR( \
++ NewPtrClear(bytes + GC_page_size) + GC_page_size-1)
++# endif
++# else
++# ifdef MSWINCE
++ extern ptr_t GC_wince_get_mem();
++# define GET_MEM(bytes) (struct hblk *)GC_wince_get_mem(bytes)
++# else
++# if defined(AMIGA) && defined(GC_AMIGA_FASTALLOC)
++ extern void *GC_amiga_get_mem(size_t size);
++ define GET_MEM(bytes) HBLKPTR((size_t) \
++ GC_amiga_get_mem((size_t)bytes + GC_page_size) \
++ + GC_page_size-1)
++# else
++ extern ptr_t GC_unix_get_mem();
++# define GET_MEM(bytes) (struct hblk *)GC_unix_get_mem(bytes)
++# endif
++# endif
++# endif
++# endif
++# endif
++# endif
++# endif
++
++#endif /* GC_PRIVATE_H */
+
+ # endif /* GCCONFIG_H */
+diff -buNr boehm-gc/include/private/pthread_stop_world.h boehm-gc/include/private/pthread_stop_world.h
+--- boehm-gc/include/private/pthread_stop_world.h Wed Dec 31 16:00:00 1969
++++ boehm-gc/include/private/pthread_stop_world.h Sat Sep 13 02:10:15 2003
+@@ -0,0 +1,12 @@
++#ifndef GC_PTHREAD_STOP_WORLD_H
++#define GC_PTHREAD_STOP_WORLD_H
++
++struct thread_stop_info {
++ int signal;
++ word last_stop_count; /* GC_last_stop_count value when thread */
++ /* last successfully handled a suspend */
++ /* signal. */
++ ptr_t stack_ptr; /* Valid only when stopped. */
++};
++
++#endif
+diff -buNr boehm-gc/include/private/pthread_support.h boehm-gc/include/private/pthread_support.h
+--- boehm-gc/include/private/pthread_support.h Wed Dec 31 16:00:00 1969
++++ boehm-gc/include/private/pthread_support.h Sat Sep 13 02:10:15 2003
+@@ -0,0 +1,97 @@
++#ifndef GC_PTHREAD_SUPPORT_H
++#define GC_PTHREAD_SUPPORT_H
++
++# include "private/gc_priv.h"
++
++# if defined(GC_PTHREADS) && !defined(GC_SOLARIS_THREADS) \
++ && !defined(GC_IRIX_THREADS) && !defined(GC_WIN32_THREADS)
++
++#if defined(GC_DARWIN_THREADS)
++# include "private/darwin_stop_world.h"
++#else
++# include "private/pthread_stop_world.h"
++#endif
++
++/* We use the allocation lock to protect thread-related data structures. */
++
++/* The set of all known threads. We intercept thread creation and */
++/* joins. */
++/* Protected by allocation/GC lock. */
++/* Some of this should be declared volatile, but that's inconsistent */
++/* with some library routine declarations. */
++typedef struct GC_Thread_Rep {
++ struct GC_Thread_Rep * next; /* More recently allocated threads */
++ /* with a given pthread id come */
++ /* first. (All but the first are */
++ /* guaranteed to be dead, but we may */
++ /* not yet have registered the join.) */
++ pthread_t id;
++ /* Extra bookkeeping information the stopping code uses */
++ struct thread_stop_info stop_info;
++
++ short flags;
++# define FINISHED 1 /* Thread has exited. */
++# define DETACHED 2 /* Thread is intended to be detached. */
++# define MAIN_THREAD 4 /* True for the original thread only. */
++ short thread_blocked; /* Protected by GC lock. */
++ /* Treated as a boolean value. If set, */
++ /* thread will acquire GC lock before */
++ /* doing any pointer manipulations, and */
++ /* has set its sp value. Thus it does */
++ /* not need to be sent a signal to stop */
++ /* it. */
++ ptr_t stack_end; /* Cold end of the stack. */
++# ifdef IA64
++ ptr_t backing_store_end;
++ ptr_t backing_store_ptr;
++# endif
++ void * status; /* The value returned from the thread. */
++ /* Used only to avoid premature */
++ /* reclamation of any data it might */
++ /* reference. */
++# ifdef THREAD_LOCAL_ALLOC
++# if CPP_WORDSZ == 64 && defined(ALIGN_DOUBLE)
++# define GRANULARITY 16
++# define NFREELISTS 49
++# else
++# define GRANULARITY 8
++# define NFREELISTS 65
++# endif
++ /* The ith free list corresponds to size i*GRANULARITY */
++# define INDEX_FROM_BYTES(n) ((ADD_SLOP(n) + GRANULARITY - 1)/GRANULARITY)
++# define BYTES_FROM_INDEX(i) ((i) * GRANULARITY - EXTRA_BYTES)
++# define SMALL_ENOUGH(bytes) (ADD_SLOP(bytes) <= \
++ (NFREELISTS-1)*GRANULARITY)
++ ptr_t ptrfree_freelists[NFREELISTS];
++ ptr_t normal_freelists[NFREELISTS];
++# ifdef GC_GCJ_SUPPORT
++ ptr_t gcj_freelists[NFREELISTS];
++# endif
++ /* Free lists contain either a pointer or a small count */
++ /* reflecting the number of granules allocated at that */
++ /* size. */
++ /* 0 ==> thread-local allocation in use, free list */
++ /* empty. */
++ /* > 0, <= DIRECT_GRANULES ==> Using global allocation, */
++ /* too few objects of this size have been */
++ /* allocated by this thread. */
++ /* >= HBLKSIZE => pointer to nonempty free list. */
++ /* > DIRECT_GRANULES, < HBLKSIZE ==> transition to */
++ /* local alloc, equivalent to 0. */
++# define DIRECT_GRANULES (HBLKSIZE/GRANULARITY)
++ /* Don't use local free lists for up to this much */
++ /* allocation. */
++# endif
++} * GC_thread;
++
++# define THREAD_TABLE_SZ 128 /* Must be power of 2 */
++extern volatile GC_thread GC_threads[THREAD_TABLE_SZ];
++
++extern GC_bool GC_thr_initialized;
++
++GC_thread GC_lookup_thread(pthread_t id);
++
++void GC_stop_init();
++
++#endif /* GC_PTHREADS && !GC_SOLARIS_THREADS.... etc */
++#endif /* GC_PTHREAD_SUPPORT_H */
+diff -buNr boehm-gc/include/private/solaris_threads.h boehm-gc/include/private/solaris_threads.h
+--- boehm-gc/include/private/solaris_threads.h Tue Oct 23 16:21:39 2001
++++ boehm-gc/include/private/solaris_threads.h Sat Sep 13 02:10:15 2003
+@@ -16,7 +16,8 @@
+ # define DETACHED 2 /* Thread is intended to be detached. */
+ # define CLIENT_OWNS_STACK 4
+ /* Stack was supplied by client. */
+-# define SUSPENDED 8 /* Currently suspended. */
++# define SUSPNDED 8 /* Currently suspended. */
++ /* SUSPENDED is used insystem header. */
+ ptr_t stack;
+ size_t stack_size;
+ cond_t join_cv;
+diff -buNr boehm-gc/include/private/specific.h boehm-gc/include/private/specific.h
+--- boehm-gc/include/private/specific.h Fri Mar 29 14:52:13 2002
++++ boehm-gc/include/private/specific.h Sat Sep 13 02:10:15 2003
+@@ -85,7 +85,7 @@
+ unsigned hash_val = CACHE_HASH(qtid);
+ tse * volatile * entry_ptr = key -> cache + hash_val;
+ tse * entry = *entry_ptr; /* Must be loaded only once. */
+- if (entry -> qtid == qtid) {
++ if (EXPECT(entry -> qtid == qtid, 1)) {
+ GC_ASSERT(entry -> thread == pthread_self());
+ return entry -> value;
+ }
+diff -buNr boehm-gc/irix_threads.c boehm-gc/irix_threads.c
+--- boehm-gc/irix_threads.c Sun May 19 10:36:14 2002
++++ boehm-gc/irix_threads.c Sat Sep 13 02:10:15 2003
+@@ -41,6 +41,10 @@
+ #undef pthread_join
+ #undef pthread_detach
+
++#ifdef HANDLE_FORK
++ --> Not yet supported. Try porting the code from linux_threads.c.
++#endif
++
+ void GC_thr_init();
+
+ #if 0
+diff -buNr boehm-gc/mach_dep.c boehm-gc/mach_dep.c
+--- boehm-gc/mach_dep.c Thu Jul 18 13:06:00 2002
++++ boehm-gc/mach_dep.c Sat Sep 13 02:10:15 2003
+@@ -74,7 +74,7 @@
+ /* on your architecture. Run the test_setjmp program to see whether */
+ /* there is any chance it will work. */
+
+-#ifndef USE_GENERIC_PUSH_REGS
++#if !defined(USE_GENERIC_PUSH_REGS) && !defined(USE_ASM_PUSH_REGS)
+ void GC_push_regs()
+ {
+ # ifdef RT
+@@ -228,7 +228,8 @@
+ || ( defined(I386) && defined(FREEBSD) && defined(__ELF__) ) \
+ || ( defined(I386) && defined(NETBSD) && defined(__ELF__) ) \
+ || ( defined(I386) && defined(OPENBSD) && defined(__ELF__) ) \
+- || ( defined(I386) && defined(HURD) && defined(__ELF__) )
++ || ( defined(I386) && defined(HURD) && defined(__ELF__) ) \
++ || ( defined(I386) && defined(DGUX) )
+
+ /* This is modified for Linux with ELF (Note: _ELF_ only) */
+ /* This section handles FreeBSD with ELF. */
+@@ -377,7 +378,7 @@
+ /* other machines... */
+ # if !defined(M68K) && !defined(VAX) && !defined(RT)
+ # if !defined(SPARC) && !defined(I386) && !defined(NS32K)
+-# if !defined(POWERPC) && !defined(UTS4)
++# if !(defined(POWERPC) && defined(LINUX)) && !defined(UTS4)
+ # if !defined(PJ) && !(defined(MIPS) && defined(LINUX))
+ --> bad news <--
+ # endif
+@@ -385,7 +386,7 @@
+ # endif
+ # endif
+ }
+-#endif /* !USE_GENERIC_PUSH_REGS */
++#endif /* !USE_GENERIC_PUSH_REGS && !USE_ASM_PUSH_REGS */
+
+ #if defined(USE_GENERIC_PUSH_REGS)
+ void GC_generic_push_regs(cold_gc_frame)
+diff -buNr boehm-gc/malloc.c boehm-gc/malloc.c
+--- boehm-gc/malloc.c Mon Feb 11 20:37:53 2002
++++ boehm-gc/malloc.c Sat Sep 13 02:10:15 2003
+@@ -182,6 +182,7 @@
+ ptr_t result;
+ DCL_LOCK_STATE;
+
++ if (GC_have_errors) GC_print_all_errors();
+ GC_INVOKE_FINALIZERS();
+ if (SMALL_OBJ(lb)) {
+ DISABLE_SIGNALS();
+@@ -294,6 +295,11 @@
+ return(GENERAL_MALLOC((word)lb, NORMAL));
+ }
+ /* See above comment on signals. */
++ GC_ASSERT(0 == obj_link(op)
++ || (word)obj_link(op)
++ <= (word)GC_greatest_plausible_heap_addr
++ && (word)obj_link(op)
++ >= (word)GC_least_plausible_heap_addr);
+ *opp = obj_link(op);
+ obj_link(op) = 0;
+ GC_words_allocd += lw;
+@@ -338,6 +344,7 @@
+ return((GC_PTR)REDIRECT_MALLOC(n*lb));
+ }
+
++#ifndef strdup
+ # include <string.h>
+ # ifdef __STDC__
+ char *strdup(const char *s)
+@@ -346,11 +353,16 @@
+ char *s;
+ # endif
+ {
+- size_t len = strlen + 1;
++ size_t len = strlen(s) + 1;
+ char * result = ((char *)REDIRECT_MALLOC(len+1));
+ BCOPY(s, result, len+1);
+ return result;
+ }
++#endif /* !defined(strdup) */
++ /* If strdup is macro defined, we assume that it actually calls malloc, */
++ /* and thus the right thing will happen even without overriding it. */
++ /* This seems to be true on most Linux systems. */
++
+ # endif /* REDIRECT_MALLOC */
+
+ /* Explicitly deallocate an object p. */
+@@ -373,6 +385,7 @@
+ /* Required by ANSI. It's not my fault ... */
+ h = HBLKPTR(p);
+ hhdr = HDR(h);
++ GC_ASSERT(GC_base(p) == p);
+ # if defined(REDIRECT_MALLOC) && \
+ (defined(GC_SOLARIS_THREADS) || defined(GC_LINUX_THREADS) \
+ || defined(__MINGW32__)) /* Should this be MSWIN32 in general? */
+@@ -454,7 +467,10 @@
+ }
+ #endif /* THREADS */
+
+-# ifdef REDIRECT_MALLOC
++# if defined(REDIRECT_MALLOC) && !defined(REDIRECT_FREE)
++# define REDIRECT_FREE GC_free
++# endif
++# ifdef REDIRECT_FREE
+ # ifdef __STDC__
+ void free(GC_PTR p)
+ # else
+@@ -463,7 +479,7 @@
+ # endif
+ {
+ # ifndef IGNORE_FREE
+- GC_free(p);
++ REDIRECT_FREE(p);
+ # endif
+ }
+ # endif /* REDIRECT_MALLOC */
+diff -buNr boehm-gc/mallocx.c boehm-gc/mallocx.c
+--- boehm-gc/mallocx.c Fri Aug 17 18:04:43 2001
++++ boehm-gc/mallocx.c Sat Sep 13 02:10:15 2003
+@@ -142,7 +142,11 @@
+ }
+ }
+
+-# if defined(REDIRECT_MALLOC) || defined(REDIRECT_REALLOC)
++# if defined(REDIRECT_MALLOC) && !defined(REDIRECT_REALLOC)
++# define REDIRECT_REALLOC GC_realloc
++# endif
++
++# ifdef REDIRECT_REALLOC
+ # ifdef __STDC__
+ GC_PTR realloc(GC_PTR p, size_t lb)
+ # else
+@@ -151,13 +155,9 @@
+ size_t lb;
+ # endif
+ {
+-# ifdef REDIRECT_REALLOC
+ return(REDIRECT_REALLOC(p, lb));
+-# else
+- return(GC_realloc(p, lb));
+-# endif
+ }
+-# endif /* REDIRECT_MALLOC */
++# endif /* REDIRECT_REALLOC */
+
+
+ /* The same thing, except caller does not hold allocation lock. */
+@@ -177,6 +177,7 @@
+ lw = ROUNDED_UP_WORDS(lb);
+ n_blocks = OBJ_SZ_TO_BLOCKS(lw);
+ init = GC_obj_kinds[k].ok_init;
++ if (GC_have_errors) GC_print_all_errors();
+ GC_INVOKE_FINALIZERS();
+ DISABLE_SIGNALS();
+ LOCK();
+@@ -286,6 +287,7 @@
+ register ptr_t op;
+ DCL_LOCK_STATE;
+
++ if (GC_have_errors) GC_print_all_errors();
+ GC_INVOKE_FINALIZERS();
+ DISABLE_SIGNALS();
+ LOCK();
+@@ -354,6 +356,7 @@
+ return;
+ }
+ lw = ALIGNED_WORDS(lb);
++ if (GC_have_errors) GC_print_all_errors();
+ GC_INVOKE_FINALIZERS();
+ DISABLE_SIGNALS();
+ LOCK();
+@@ -375,6 +378,7 @@
+ while ((hbp = *rlh) != 0) {
+ hhdr = HDR(hbp);
+ *rlh = hhdr -> hb_next;
++ hhdr -> hb_last_reclaimed = (unsigned short) GC_gc_no;
+ # ifdef PARALLEL_MARK
+ {
+ signed_word my_words_allocd_tmp = GC_words_allocd_tmp;
+@@ -574,6 +578,44 @@
+ return((GC_PTR) op);
+ }
+ }
++
++#ifdef __STDC__
++/* Not well tested nor integrated. */
++/* Debug version is tricky and currently missing. */
++#include <limits.h>
++
++GC_PTR GC_memalign(size_t align, size_t lb)
++{
++ size_t new_lb;
++ size_t offset;
++ ptr_t result;
++
++# ifdef ALIGN_DOUBLE
++ if (align <= WORDS_TO_BYTES(2) && lb > align) return GC_malloc(lb);
++# endif
++ if (align <= WORDS_TO_BYTES(1)) return GC_malloc(lb);
++ if (align >= HBLKSIZE/2 || lb >= HBLKSIZE/2) {
++ if (align > HBLKSIZE) return GC_oom_fn(LONG_MAX-1024) /* Fail */;
++ return GC_malloc(lb <= HBLKSIZE? HBLKSIZE : lb);
++ /* Will be HBLKSIZE aligned. */
++ }
++ /* We could also try to make sure that the real rounded-up object size */
++ /* is a multiple of align. That would be correct up to HBLKSIZE. */
++ new_lb = lb + align - 1;
++ result = GC_malloc(new_lb);
++ offset = (word)result % align;
++ if (offset != 0) {
++ offset = align - offset;
++ if (!GC_all_interior_pointers) {
++ if (offset >= VALID_OFFSET_SZ) return GC_malloc(HBLKSIZE);
++ GC_register_displacement(offset);
++ }
++ }
++ result = (GC_PTR) ((ptr_t)result + offset);
++ GC_ASSERT((word)result % align == 0);
++ return result;
++}
++#endif
+
+ # ifdef ATOMIC_UNCOLLECTABLE
+ /* Allocate lb bytes of pointerfree, untraced, uncollectable data */
+diff -buNr boehm-gc/mark.c boehm-gc/mark.c
+--- boehm-gc/mark.c Fri Mar 29 14:52:12 2002
++++ boehm-gc/mark.c Sat Sep 13 02:10:15 2003
+@@ -19,6 +19,10 @@
+ # include <stdio.h>
+ # include "private/gc_pmark.h"
+
++#if defined(MSWIN32) && defined(__GNUC__)
++# include <excpt.h>
++#endif
++
+ /* We put this here to minimize the risk of inlining. */
+ /*VARARGS*/
+ #ifdef __WATCOMC__
+@@ -261,20 +265,20 @@
+ /* remains valid until all marking is complete. */
+ /* A zero value indicates that it's OK to miss some */
+ /* register values. */
+-GC_bool GC_mark_some(cold_gc_frame)
+-ptr_t cold_gc_frame;
++/* We hold the allocation lock. In the case of */
++/* incremental collection, the world may not be stopped.*/
++#ifdef MSWIN32
++ /* For win32, this is called after we establish a structured */
++ /* exception handler, in case Windows unmaps one of our root */
++ /* segments. See below. In either case, we acquire the */
++ /* allocator lock long before we get here. */
++ GC_bool GC_mark_some_inner(cold_gc_frame)
++ ptr_t cold_gc_frame;
++#else
++ GC_bool GC_mark_some(cold_gc_frame)
++ ptr_t cold_gc_frame;
++#endif
+ {
+-#if defined(MSWIN32) && !defined(__GNUC__)
+- /* Windows 98 appears to asynchronously create and remove writable */
+- /* memory mappings, for reasons we haven't yet understood. Since */
+- /* we look for writable regions to determine the root set, we may */
+- /* try to mark from an address range that disappeared since we */
+- /* started the collection. Thus we have to recover from faults here. */
+- /* This code does not appear to be necessary for Windows 95/NT/2000. */
+- /* Note that this code should never generate an incremental GC write */
+- /* fault. */
+- __try {
+-#endif /* defined(MSWIN32) && !defined(__GNUC__) */
+ switch(GC_mark_state) {
+ case MS_NONE:
+ return(FALSE);
+@@ -395,23 +399,130 @@
+ ABORT("GC_mark_some: bad state");
+ return(FALSE);
+ }
+-#if defined(MSWIN32) && !defined(__GNUC__)
++}
++
++
++#ifdef MSWIN32
++
++# ifdef __GNUC__
++
++ typedef struct {
++ EXCEPTION_REGISTRATION ex_reg;
++ void *alt_path;
++ } ext_ex_regn;
++
++
++ static EXCEPTION_DISPOSITION mark_ex_handler(
++ struct _EXCEPTION_RECORD *ex_rec,
++ void *est_frame,
++ struct _CONTEXT *context,
++ void *disp_ctxt)
++ {
++ if (ex_rec->ExceptionCode == STATUS_ACCESS_VIOLATION) {
++ ext_ex_regn *xer = (ext_ex_regn *)est_frame;
++
++ /* Unwind from the inner function assuming the standard */
++ /* function prologue. */
++ /* Assumes code has not been compiled with */
++ /* -fomit-frame-pointer. */
++ context->Esp = context->Ebp;
++ context->Ebp = *((DWORD *)context->Esp);
++ context->Esp = context->Esp - 8;
++
++ /* Resume execution at the "real" handler within the */
++ /* wrapper function. */
++ context->Eip = (DWORD )(xer->alt_path);
++
++ return ExceptionContinueExecution;
++
++ } else {
++ return ExceptionContinueSearch;
++ }
++ }
++# endif /* __GNUC__ */
++
++
++ GC_bool GC_mark_some(cold_gc_frame)
++ ptr_t cold_gc_frame;
++ {
++ GC_bool ret_val;
++
++# ifndef __GNUC__
++ /* Windows 98 appears to asynchronously create and remove */
++ /* writable memory mappings, for reasons we haven't yet */
++ /* understood. Since we look for writable regions to */
++ /* determine the root set, we may try to mark from an */
++ /* address range that disappeared since we started the */
++ /* collection. Thus we have to recover from faults here. */
++ /* This code does not appear to be necessary for Windows */
++ /* 95/NT/2000. Note that this code should never generate */
++ /* an incremental GC write fault. */
++
++ __try {
++
++# else /* __GNUC__ */
++
++ /* Manually install an exception handler since GCC does */
++ /* not yet support Structured Exception Handling (SEH) on */
++ /* Win32. */
++
++ ext_ex_regn er;
++
++ er.alt_path = &&handle_ex;
++ er.ex_reg.handler = mark_ex_handler;
++ asm volatile ("movl %%fs:0, %0" : "=r" (er.ex_reg.prev));
++ asm volatile ("movl %0, %%fs:0" : : "r" (&er));
++
++# endif /* __GNUC__ */
++
++ ret_val = GC_mark_some_inner(cold_gc_frame);
++
++# ifndef __GNUC__
++
+ } __except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
+ EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
++
++# else /* __GNUC__ */
++
++ /* Prevent GCC from considering the following code unreachable */
++ /* and thus eliminating it. */
++ if (er.alt_path != 0)
++ goto rm_handler;
++
++handle_ex:
++ /* Execution resumes from here on an access violation. */
++
++# endif /* __GNUC__ */
++
+ # ifdef CONDPRINT
+ if (GC_print_stats) {
+ GC_printf0("Caught ACCESS_VIOLATION in marker. "
+ "Memory mapping disappeared.\n");
+ }
+ # endif /* CONDPRINT */
++
+ /* We have bad roots on the stack. Discard mark stack. */
+ /* Rescan from marked objects. Redetermine roots. */
+ GC_invalidate_mark_state();
+ scan_ptr = 0;
+- return FALSE;
++
++ ret_val = FALSE;
++
++# ifndef __GNUC__
++
+ }
+-#endif /* defined(MSWIN32) && !defined(__GNUC__) */
+-}
++
++# else /* __GNUC__ */
++
++rm_handler:
++ /* Uninstall the exception handler */
++ asm volatile ("mov %0, %%fs:0" : : "r" (er.ex_reg.prev));
++
++# endif /* __GNUC__ */
++
++ return ret_val;
++ }
++#endif /* MSWIN32 */
+
+
+ GC_bool GC_mark_stack_empty()
+@@ -434,13 +545,7 @@
+ /* for the large object. */
+ /* - just return current if it does not point to a large object. */
+ /*ARGSUSED*/
+-# ifdef PRINT_BLACK_LIST
+- ptr_t GC_find_start(current, hhdr, new_hdr_p, source)
+- ptr_t source;
+-# else
+- ptr_t GC_find_start(current, hhdr, new_hdr_p)
+-# define source 0
+-# endif
++ptr_t GC_find_start(current, hhdr, new_hdr_p)
+ register ptr_t current;
+ register hdr *hhdr, **new_hdr_p;
+ {
+@@ -468,7 +573,6 @@
+ } else {
+ return(current);
+ }
+-# undef source
+ }
+
+ void GC_invalidate_mark_state()
+@@ -546,8 +650,8 @@
+ /* Large length. */
+ /* Process part of the range to avoid pushing too much on the */
+ /* stack. */
+- GC_ASSERT(descr < GC_greatest_plausible_heap_addr
+- - GC_least_plausible_heap_addr);
++ GC_ASSERT(descr < (word)GC_greatest_plausible_heap_addr
++ - (word)GC_least_plausible_heap_addr);
+ # ifdef PARALLEL_MARK
+ # define SHARE_BYTES 2048
+ if (descr > SHARE_BYTES && GC_parallel
+@@ -578,6 +682,7 @@
+ while (descr != 0) {
+ if ((signed_word)descr < 0) {
+ current = *current_p;
++ FIXUP_POINTER(current);
+ if ((ptr_t)current >= least_ha && (ptr_t)current < greatest_ha) {
+ PREFETCH(current);
+ HC_PUSH_CONTENTS((ptr_t)current, mark_stack_top,
+@@ -652,6 +757,7 @@
+ PREFETCH((ptr_t)limit - PREF_DIST*CACHE_LINE_SIZE);
+ GC_ASSERT(limit >= current_p);
+ deferred = *limit;
++ FIXUP_POINTER(deferred);
+ limit = (word *)((char *)limit - ALIGNMENT);
+ if ((ptr_t)deferred >= least_ha && (ptr_t)deferred < greatest_ha) {
+ PREFETCH(deferred);
+@@ -661,6 +767,7 @@
+ /* Unroll once, so we don't do too many of the prefetches */
+ /* based on limit. */
+ deferred = *limit;
++ FIXUP_POINTER(deferred);
+ limit = (word *)((char *)limit - ALIGNMENT);
+ if ((ptr_t)deferred >= least_ha && (ptr_t)deferred < greatest_ha) {
+ PREFETCH(deferred);
+@@ -675,6 +782,7 @@
+ /* Since HC_PUSH_CONTENTS expands to a lot of code, */
+ /* we don't. */
+ current = *current_p;
++ FIXUP_POINTER(current);
+ PREFETCH((ptr_t)current_p + PREF_DIST*CACHE_LINE_SIZE);
+ if ((ptr_t)current >= least_ha && (ptr_t)current < greatest_ha) {
+ /* Prefetch the contents of the object we just pushed. It's */
+@@ -726,22 +834,33 @@
+ mse *top = local - 1;
+ unsigned i = 0;
+
++ /* Make sure that prior writes to the mark stack are visible. */
++ /* On some architectures, the fact that the reads are */
++ /* volatile should suffice. */
++# if !defined(IA64) && !defined(HP_PA) && !defined(I386)
++ GC_memory_barrier();
++# endif
+ GC_ASSERT(high >= low-1 && high - low + 1 <= GC_mark_stack_size);
+ for (p = low; p <= high && i <= max; ++p) {
+ word descr = *(volatile word *) &(p -> mse_descr);
++ /* In the IA64 memory model, the following volatile store is */
++ /* ordered after this read of descr. Thus a thread must read */
++ /* the original nonzero value. HP_PA appears to be similar, */
++ /* and if I'm reading the P4 spec correctly, X86 is probably */
++ /* also OK. In some other cases we need a barrier. */
++# if !defined(IA64) && !defined(HP_PA) && !defined(I386)
++ GC_memory_barrier();
++# endif
+ if (descr != 0) {
+ *(volatile word *) &(p -> mse_descr) = 0;
++ /* More than one thread may get this entry, but that's only */
++ /* a minor performance problem. */
+ ++top;
+ top -> mse_descr = descr;
+ top -> mse_start = p -> mse_start;
+ GC_ASSERT( top -> mse_descr & GC_DS_TAGS != GC_DS_LENGTH ||
+ top -> mse_descr < GC_greatest_plausible_heap_addr
+ - GC_least_plausible_heap_addr);
+- /* There is no synchronization here. We assume that at */
+- /* least one thread will see the original descriptor. */
+- /* Otherwise we need a barrier. */
+- /* More than one thread may get this entry, but that's only */
+- /* a minor performance problem. */
+ /* If this is a big object, count it as */
+ /* size/256 + 1 objects. */
+ ++i;
+@@ -778,7 +897,7 @@
+ BCOPY(low, my_start, stack_size * sizeof(mse));
+ GC_ASSERT(GC_mark_stack_top = my_top);
+ # if !defined(IA64) && !defined(HP_PA)
+- GC_memory_write_barrier();
++ GC_memory_barrier();
+ # endif
+ /* On IA64, the volatile write acts as a release barrier. */
+ GC_mark_stack_top = my_top + stack_size;
+@@ -1342,7 +1461,7 @@
+ # define GC_least_plausible_heap_addr least_ha
+
+ if (top == 0) return;
+- /* check all pointers in range and put in push if they appear */
++ /* check all pointers in range and push if they appear */
+ /* to be valid. */
+ lim = t - 1 /* longword */;
+ for (p = b; p <= lim; p = (word *)(((char *)p) + ALIGNMENT)) {
+@@ -1366,7 +1485,7 @@
+ ptr_t top;
+ ptr_t cold_gc_frame;
+ {
+- if (GC_all_interior_pointers) {
++ if (!NEED_FIXUP_POINTER && GC_all_interior_pointers) {
+ # define EAGER_BYTES 1024
+ /* Push the hot end of the stack eagerly, so that register values */
+ /* saved inside GC frames are marked before they disappear. */
+@@ -1375,6 +1494,7 @@
+ GC_push_all_stack(bottom, top);
+ return;
+ }
++ GC_ASSERT(bottom <= cold_gc_frame && cold_gc_frame <= top);
+ # ifdef STACK_GROWS_DOWN
+ GC_push_all(cold_gc_frame - sizeof(ptr_t), top);
+ GC_push_all_eager(bottom, cold_gc_frame);
+@@ -1395,7 +1515,7 @@
+ ptr_t bottom;
+ ptr_t top;
+ {
+- if (GC_all_interior_pointers) {
++ if (!NEED_FIXUP_POINTER && GC_all_interior_pointers) {
+ GC_push_all(bottom, top);
+ } else {
+ GC_push_all_eager(bottom, top);
+diff -buNr boehm-gc/mark_rts.c boehm-gc/mark_rts.c
+--- boehm-gc/mark_rts.c Mon Mar 3 22:38:29 2003
++++ boehm-gc/mark_rts.c Sat Sep 13 02:10:15 2003
+@@ -275,33 +275,72 @@
+ }
+
+ /* Internal use only; lock held. */
+-void GC_remove_tmp_roots()
++static void GC_remove_root_at_pos(i)
++int i;
+ {
+- register int i;
+-
+- for (i = 0; i < n_root_sets; ) {
+- if (GC_static_roots[i].r_tmp) {
+- GC_root_size -=
+- (GC_static_roots[i].r_end - GC_static_roots[i].r_start);
++ GC_root_size -= (GC_static_roots[i].r_end - GC_static_roots[i].r_start);
+ GC_static_roots[i].r_start = GC_static_roots[n_root_sets-1].r_start;
+ GC_static_roots[i].r_end = GC_static_roots[n_root_sets-1].r_end;
+ GC_static_roots[i].r_tmp = GC_static_roots[n_root_sets-1].r_tmp;
+ n_root_sets--;
+- } else {
+- i++;
+- }
+- }
+-# if !defined(MSWIN32) && !defined(MSWINCE)
+- {
++}
++
++#if !defined(MSWIN32) && !defined(MSWINCE)
++static void GC_rebuild_root_index()
++{
+ register int i;
+
+ for (i = 0; i < RT_SIZE; i++) GC_root_index[i] = 0;
+ for (i = 0; i < n_root_sets; i++)
+ add_roots_to_index(GC_static_roots + i);
++}
++#endif
++
++/* Internal use only; lock held. */
++void GC_remove_tmp_roots()
++{
++ register int i;
++
++ for (i = 0; i < n_root_sets; ) {
++ if (GC_static_roots[i].r_tmp) {
++ GC_remove_root_at_pos(i);
++ } else {
++ i++;
+ }
+-# endif
++ }
++ #if !defined(MSWIN32) && !defined(MSWINCE)
++ GC_rebuild_root_index();
++ #endif
++}
++
++#if !defined(MSWIN32) && !defined(MSWINCE)
++void GC_remove_roots(b, e)
++char * b; char * e;
++{
++ DCL_LOCK_STATE;
+
++ DISABLE_SIGNALS();
++ LOCK();
++ GC_remove_roots_inner(b, e);
++ UNLOCK();
++ ENABLE_SIGNALS();
++}
++
++/* Should only be called when the lock is held */
++void GC_remove_roots_inner(b,e)
++char * b; char * e;
++{
++ int i;
++ for (i = 0; i < n_root_sets; ) {
++ if (GC_static_roots[i].r_start >= (ptr_t)b && GC_static_roots[i].r_end <= (ptr_t)e) {
++ GC_remove_root_at_pos(i);
++ } else {
++ i++;
++ }
++ }
++ GC_rebuild_root_index();
+ }
++#endif /* !defined(MSWIN32) && !defined(MSWINCE) */
+
+ #if defined(MSWIN32) || defined(_WIN32_WCE_EMULATION)
+ /* Workaround for the OS mapping and unmapping behind our back: */
+@@ -573,8 +612,11 @@
+
+ /* Mark thread local free lists, even if their mark */
+ /* descriptor excludes the link field. */
++ /* If the world is not stopped, this is unsafe. It is */
++ /* also unnecessary, since we will do this again with the */
++ /* world stopped. */
+ # ifdef THREAD_LOCAL_ALLOC
+- GC_mark_thread_local_free_lists();
++ if (GC_world_stopped) GC_mark_thread_local_free_lists();
+ # endif
+
+ /*
+diff -buNr boehm-gc/misc.c boehm-gc/misc.c
+--- boehm-gc/misc.c Mon Mar 3 22:38:30 2003
++++ boehm-gc/misc.c Sat Sep 13 02:10:15 2003
+@@ -46,8 +46,10 @@
+ # ifdef GC_SOLARIS_THREADS
+ mutex_t GC_allocate_ml; /* Implicitly initialized. */
+ # else
+-# ifdef GC_WIN32_THREADS
+-# if !defined(GC_NOT_DLL) && (defined(_DLL) || defined(GC_DLL))
++# if defined(GC_WIN32_THREADS)
++# if defined(GC_PTHREADS)
++ pthread_mutex_t GC_allocate_ml = PTHREAD_MUTEX_INITIALIZER;
++# elif defined(GC_DLL)
+ __declspec(dllexport) CRITICAL_SECTION GC_allocate_ml;
+ # else
+ CRITICAL_SECTION GC_allocate_ml;
+@@ -90,6 +92,7 @@
+ /* defined here so we don't have to load debug_malloc.o */
+
+ void (*GC_check_heap) GC_PROTO((void)) = (void (*) GC_PROTO((void)))0;
++void (*GC_print_all_smashed) GC_PROTO((void)) = (void (*) GC_PROTO((void)))0;
+
+ void (*GC_start_call_back) GC_PROTO((void)) = (void (*) GC_PROTO((void)))0;
+
+@@ -109,6 +112,10 @@
+
+ GC_bool GC_print_back_height = 0;
+
++#ifndef NO_DEBUGGING
++ GC_bool GC_dump_regularly = 0; /* Generate regular debugging dumps. */
++#endif
++
+ #ifdef FIND_LEAK
+ int GC_find_leak = 1;
+ #else
+@@ -137,6 +144,13 @@
+
+ extern signed_word GC_mem_found;
+
++void * GC_project2(arg1, arg2)
++void *arg1;
++void *arg2;
++{
++ return arg2;
++}
++
+ # ifdef MERGE_SIZES
+ /* Set things up so that GC_size_map[i] >= words(i), */
+ /* but not too much bigger */
+@@ -455,7 +469,7 @@
+
+ DISABLE_SIGNALS();
+
+-#ifdef MSWIN32
++#if defined(GC_WIN32_THREADS) && !defined(GC_PTHREADS)
+ if (!GC_is_initialized) InitializeCriticalSection(&GC_allocate_ml);
+ #endif /* MSWIN32 */
+
+@@ -473,6 +487,15 @@
+ GC_init_parallel();
+ }
+ # endif /* PARALLEL_MARK || THREAD_LOCAL_ALLOC */
++
++# if defined(DYNAMIC_LOADING) && defined(DARWIN)
++ {
++ /* This must be called WITHOUT the allocation lock held
++ and before any threads are created */
++ extern void GC_init_dyld();
++ GC_init_dyld();
++ }
++# endif
+ }
+
+ #if defined(MSWIN32) || defined(MSWINCE)
+@@ -485,6 +508,22 @@
+
+ extern void GC_setpagesize();
+
++
++#ifdef MSWIN32
++extern GC_bool GC_no_win32_dlls;
++#else
++# define GC_no_win32_dlls FALSE
++#endif
++
++void GC_exit_check GC_PROTO((void))
++{
++ GC_gcollect();
++}
++
++#ifdef SEARCH_FOR_DATA_START
++ extern void GC_init_linux_data_start GC_PROTO((void));
++#endif
++
+ #ifdef UNIX_LIKE
+
+ extern void GC_set_and_save_fault_handler GC_PROTO((void (*handler)(int)));
+@@ -495,12 +534,23 @@
+ GC_err_printf1("Caught signal %d: looping in handler\n", sig);
+ for(;;);
+ }
+-#endif
+
+-#ifdef MSWIN32
+-extern GC_bool GC_no_win32_dlls;
+-#else
+-# define GC_no_win32_dlls FALSE
++static GC_bool installed_looping_handler = FALSE;
++
++void maybe_install_looping_handler()
++{
++ /* Install looping handler before the write fault handler, so we */
++ /* handle write faults correctly. */
++ if (!installed_looping_handler && 0 != GETENV("GC_LOOP_ON_ABORT")) {
++ GC_set_and_save_fault_handler(looping_handler);
++ installed_looping_handler = TRUE;
++ }
++}
++
++#else /* !UNIX_LIKE */
++
++# define maybe_install_looping_handler()
++
+ #endif
+
+ void GC_init_inner()
+@@ -517,12 +567,19 @@
+ # if defined(MSWIN32) || defined(MSWINCE)
+ InitializeCriticalSection(&GC_write_cs);
+ # endif
+-
+ if (0 != GETENV("GC_PRINT_STATS")) {
+ GC_print_stats = 1;
+ }
++# ifndef NO_DEBUGGING
++ if (0 != GETENV("GC_DUMP_REGULARLY")) {
++ GC_dump_regularly = 1;
++ }
++# endif
+ if (0 != GETENV("GC_FIND_LEAK")) {
+ GC_find_leak = 1;
++# ifdef __STDC__
++ atexit(GC_exit_check);
++# endif
+ }
+ if (0 != GETENV("GC_ALL_INTERIOR_POINTERS")) {
+ GC_all_interior_pointers = 1;
+@@ -560,11 +617,7 @@
+ }
+ }
+ }
+-# ifdef UNIX_LIKE
+- if (0 != GETENV("GC_LOOP_ON_ABORT")) {
+- GC_set_and_save_fault_handler(looping_handler);
+- }
+-# endif
++ maybe_install_looping_handler();
+ /* Adjust normal object descriptor for extra allocation. */
+ if (ALIGNMENT > GC_DS_TAGS && EXTRA_BYTES != 0) {
+ GC_obj_kinds[NORMAL].ok_descriptor = ((word)(-ALIGNMENT) | GC_DS_LENGTH);
+@@ -599,11 +652,21 @@
+ # if defined(LINUX) && defined(IA64)
+ GC_register_stackbottom = GC_get_register_stack_base();
+ # endif
++ } else {
++# if defined(LINUX) && defined(IA64)
++ if (GC_register_stackbottom == 0) {
++ WARN("GC_register_stackbottom should be set with GC_stackbottom", 0);
++ /* The following is likely to fail, since we rely on */
++ /* alignment properties that may not hold with a user set */
++ /* GC_stackbottom. */
++ GC_register_stackbottom = GC_get_register_stack_base();
+ }
+ # endif
+- GC_ASSERT(sizeof (ptr_t) == sizeof(word));
+- GC_ASSERT(sizeof (signed_word) == sizeof(word));
+- GC_ASSERT(sizeof (struct hblk) == HBLKSIZE);
++ }
++# endif
++ GC_STATIC_ASSERT(sizeof (ptr_t) == sizeof(word));
++ GC_STATIC_ASSERT(sizeof (signed_word) == sizeof(word));
++ GC_STATIC_ASSERT(sizeof (struct hblk) == HBLKSIZE);
+ # ifndef THREADS
+ # if defined(STACK_GROWS_UP) && defined(STACK_GROWS_DOWN)
+ ABORT(
+@@ -642,6 +705,18 @@
+ initial_heap_sz = divHBLKSZ(initial_heap_sz);
+ }
+ }
++ {
++ char * sz_str = GETENV("GC_MAXIMUM_HEAP_SIZE");
++ if (sz_str != NULL) {
++ word max_heap_sz = (word)atol(sz_str);
++ if (max_heap_sz < initial_heap_sz * HBLKSIZE) {
++ WARN("Bad maximum heap size %s - ignoring it.\n",
++ sz_str);
++ }
++ if (0 == GC_max_retries) GC_max_retries = 2;
++ GC_set_max_heap_size(max_heap_sz);
++ }
++ }
+ if (!GC_expand_hp_inner(initial_heap_sz)) {
+ GC_err_printf0("Can't start up: not enough memory\n");
+ EXIT();
+@@ -677,6 +752,7 @@
+ GC_incremental = TRUE;
+ }
+ # endif /* !SMALL_CONFIG */
++ COND_DUMP;
+ /* Get black list set up and/or incrmental GC started */
+ if (!GC_dont_precollect || GC_incremental) GC_gcollect_inner();
+ GC_is_initialized = TRUE;
+@@ -713,6 +789,7 @@
+ GC_setpagesize();
+ if (GC_no_win32_dlls) goto out;
+ # ifndef GC_SOLARIS_THREADS
++ maybe_install_looping_handler(); /* Before write fault handler! */
+ GC_dirty_init();
+ # endif
+ if (!GC_is_initialized) {
+@@ -932,6 +1009,17 @@
+ return(result);
+ }
+
++# if defined(__STDC__) || defined(__cplusplus)
++ GC_word GC_set_free_space_divisor (GC_word value)
++# else
++ GC_word GC_set_free_space_divisor (value)
++ GC_word value;
++# endif
++{
++ GC_word old = GC_free_space_divisor;
++ GC_free_space_divisor = value;
++ return old;
++}
+
+ #ifndef PCR
+ void GC_abort(msg)
+@@ -958,122 +1046,18 @@
+ }
+ #endif
+
+-#ifdef NEED_CALLINFO
+-
+-#ifdef HAVE_BUILTIN_BACKTRACE
+-# include <execinfo.h>
+-# ifdef LINUX
+-# include <unistd.h>
+-# endif
+-#endif
+-
+-void GC_print_callers (info)
+-struct callinfo info[NFRAMES];
+-{
+- register int i;
+-
+-# if NFRAMES == 1
+- GC_err_printf0("\tCaller at allocation:\n");
+-# else
+- GC_err_printf0("\tCall chain at allocation:\n");
+-# endif
+- for (i = 0; i < NFRAMES; i++) {
+- if (info[i].ci_pc == 0) break;
+-# if NARGS > 0
+- {
+- int j;
+-
+- GC_err_printf0("\t\targs: ");
+- for (j = 0; j < NARGS; j++) {
+- if (j != 0) GC_err_printf0(", ");
+- GC_err_printf2("%d (0x%X)", ~(info[i].ci_arg[j]),
+- ~(info[i].ci_arg[j]));
+- }
+- GC_err_printf0("\n");
+- }
+-# endif
+-# if defined(HAVE_BUILTIN_BACKTRACE) && !defined(REDIRECT_MALLOC)
+- /* Unfortunately backtrace_symbols calls malloc, which makes */
+- /* it dangersous if that has been redirected. */
+- {
+- char **sym_name =
+- backtrace_symbols((void **)(&(info[i].ci_pc)), 1);
+- char *name = sym_name[0];
+- GC_bool found_it = (strchr(name, '(') != 0);
+- FILE *pipe;
+-# ifdef LINUX
+- if (!found_it) {
+-# define EXE_SZ 100
+- static char exe_name[EXE_SZ];
+-# define CMD_SZ 200
+- char cmd_buf[CMD_SZ];
+-# define RESULT_SZ 200
+- static char result_buf[RESULT_SZ];
+- size_t result_len;
+- static GC_bool found_exe_name = FALSE;
+- static GC_bool will_fail = FALSE;
+- int ret_code;
+- /* Unfortunately, this is the common case for the */
+- /* main executable. */
+- /* Try to get it via a hairy and expensive scheme. */
+- /* First we get the name of the executable: */
+- if (will_fail) goto out;
+- if (!found_exe_name) {
+- ret_code = readlink("/proc/self/exe", exe_name, EXE_SZ);
+- if (ret_code < 0 || ret_code >= EXE_SZ || exe_name[0] != '/') {
+- will_fail = TRUE; /* Dont try again. */
+- goto out;
+- }
+- exe_name[ret_code] = '\0';
+- found_exe_name = TRUE;
+- }
+- /* Then we use popen to start addr2line -e <exe> <addr> */
+- /* There are faster ways to do this, but hopefully this */
+- /* isn't time critical. */
+- sprintf(cmd_buf, "/usr/bin/addr2line -e %s 0x%lx", exe_name,
+- (unsigned long)info[i].ci_pc);
+- pipe = popen(cmd_buf, "r");
+- if (pipe < 0 || fgets(result_buf, RESULT_SZ, pipe) == 0) {
+- will_fail = TRUE;
+- goto out;
+- }
+- result_len = strlen(result_buf);
+- if (result_buf[result_len - 1] == '\n') --result_len;
+- if (result_buf[0] == '?'
+- || result_buf[result_len-2] == ':'
+- && result_buf[result_len-1] == '0')
+- goto out;
+- if (result_len < RESULT_SZ - 25) {
+- /* Add in hex address */
+- sprintf(result_buf + result_len, " [0x%lx]",
+- (unsigned long)info[i].ci_pc);
+- }
+- name = result_buf;
+- pclose(pipe);
+- out:
+- }
+-# endif
+- GC_err_printf1("\t\t%s\n", name);
+- free(sym_name);
+- }
+-# else
+- GC_err_printf1("\t\t##PC##= 0x%lx\n", info[i].ci_pc);
+-# endif
+- }
+-}
+-
+-#endif /* SAVE_CALL_CHAIN */
+-
+-/* Needed by SRC_M3, gcj, and should perhaps be the official interface */
+-/* to GC_dont_gc. */
+ void GC_enable()
+ {
++ LOCK();
+ GC_dont_gc--;
++ UNLOCK();
+ }
+
+ void GC_disable()
+ {
++ LOCK();
+ GC_dont_gc++;
++ UNLOCK();
+ }
+
+ #if !defined(NO_DEBUGGING)
+@@ -1088,6 +1072,8 @@
+ GC_print_hblkfreelist();
+ GC_printf0("\n***Blocks in use:\n");
+ GC_print_block_list();
++ GC_printf0("\n***Finalization statistics:\n");
++ GC_print_finalization_stats();
+ }
+
+ #endif /* NO_DEBUGGING */
+diff -buNr boehm-gc/os_dep.c boehm-gc/os_dep.c
+--- boehm-gc/os_dep.c Fri Jul 19 01:54:43 2002
++++ boehm-gc/os_dep.c Sat Sep 13 02:10:15 2003
+@@ -80,12 +80,15 @@
+ # define NEED_FIND_LIMIT
+ # endif
+
+-#ifdef NEED_FIND_LIMIT
+-# include <setjmp.h>
+-#endif
+-
+ #if defined(FREEBSD) && defined(I386)
+ # include <machine/trap.h>
++# if !defined(PCR)
++# define NEED_FIND_LIMIT
++# endif
++#endif
++
++#ifdef NEED_FIND_LIMIT
++# include <setjmp.h>
+ #endif
+
+ #ifdef AMIGA
+@@ -129,6 +132,11 @@
+ # define jmp_buf sigjmp_buf
+ #endif
+
++#ifdef DARWIN
++/* for get_etext and friends */
++#include <mach-o/getsect.h>
++#endif
++
+ #ifdef DJGPP
+ /* Apparently necessary for djgpp 2.01. May cause problems with */
+ /* other versions. */
+@@ -147,6 +155,155 @@
+ # define OPT_PROT_EXEC 0
+ #endif
+
++#if defined(LINUX) && \
++ (defined(USE_PROC_FOR_LIBRARIES) || defined(IA64) || !defined(SMALL_CONFIG))
++
++/* We need to parse /proc/self/maps, either to find dynamic libraries, */
++/* and/or to find the register backing store base (IA64). Do it once */
++/* here. */
++
++#define READ read
++
++/* Repeatedly perform a read call until the buffer is filled or */
++/* we encounter EOF. */
++ssize_t GC_repeat_read(int fd, char *buf, size_t count)
++{
++ ssize_t num_read = 0;
++ ssize_t result;
++
++ while (num_read < count) {
++ result = READ(fd, buf + num_read, count - num_read);
++ if (result < 0) return result;
++ if (result == 0) break;
++ num_read += result;
++ }
++ return num_read;
++}
++
++/*
++ * Apply fn to a buffer containing the contents of /proc/self/maps.
++ * Return the result of fn or, if we failed, 0.
++ */
++
++word GC_apply_to_maps(word (*fn)(char *))
++{
++ int f;
++ int result;
++ int maps_size;
++ char maps_temp[32768];
++ char *maps_buf;
++
++ /* Read /proc/self/maps */
++ /* Note that we may not allocate, and thus can't use stdio. */
++ f = open("/proc/self/maps", O_RDONLY);
++ if (-1 == f) return 0;
++ /* stat() doesn't work for /proc/self/maps, so we have to
++ read it to find out how large it is... */
++ maps_size = 0;
++ do {
++ result = GC_repeat_read(f, maps_temp, sizeof(maps_temp));
++ if (result <= 0) return 0;
++ maps_size += result;
++ } while (result == sizeof(maps_temp));
++
++ if (maps_size > sizeof(maps_temp)) {
++ /* If larger than our buffer, close and re-read it. */
++ close(f);
++ f = open("/proc/self/maps", O_RDONLY);
++ if (-1 == f) return 0;
++ maps_buf = alloca(maps_size);
++ if (NULL == maps_buf) return 0;
++ result = GC_repeat_read(f, maps_buf, maps_size);
++ if (result <= 0) return 0;
++ } else {
++ /* Otherwise use the fixed size buffer */
++ maps_buf = maps_temp;
++ }
++
++ close(f);
++ maps_buf[result] = '\0';
++
++ /* Apply fn to result. */
++ return fn(maps_buf);
++}
++
++#endif /* Need GC_apply_to_maps */
++
++#if defined(LINUX) && (defined(USE_PROC_FOR_LIBRARIES) || defined(IA64))
++//
++// GC_parse_map_entry parses an entry from /proc/self/maps so we can
++// locate all writable data segments that belong to shared libraries.
++// The format of one of these entries and the fields we care about
++// is as follows:
++// XXXXXXXX-XXXXXXXX r-xp 00000000 30:05 260537 name of mapping...\n
++// ^^^^^^^^ ^^^^^^^^ ^^^^ ^^
++// start end prot maj_dev
++// 0 9 18 32
++//
++// For 64 bit ABIs:
++// 0 17 34 56
++//
++// The parser is called with a pointer to the entry and the return value
++// is either NULL or is advanced to the next entry(the byte after the
++// trailing '\n'.)
++//
++#if CPP_WORDSZ == 32
++# define OFFSET_MAP_START 0
++# define OFFSET_MAP_END 9
++# define OFFSET_MAP_PROT 18
++# define OFFSET_MAP_MAJDEV 32
++# define ADDR_WIDTH 8
++#endif
++
++#if CPP_WORDSZ == 64
++# define OFFSET_MAP_START 0
++# define OFFSET_MAP_END 17
++# define OFFSET_MAP_PROT 34
++# define OFFSET_MAP_MAJDEV 56
++# define ADDR_WIDTH 16
++#endif
++
++/*
++ * Assign various fields of the first line in buf_ptr to *start, *end,
++ * *prot_buf and *maj_dev. Only *prot_buf may be set for unwritable maps.
++ */
++char *GC_parse_map_entry(char *buf_ptr, word *start, word *end,
++ char *prot_buf, unsigned int *maj_dev)
++{
++ int i;
++ char *tok;
++
++ if (buf_ptr == NULL || *buf_ptr == '\0') {
++ return NULL;
++ }
++
++ memcpy(prot_buf, buf_ptr+OFFSET_MAP_PROT, 4); // do the protections first
++ prot_buf[4] = '\0';
++
++ if (prot_buf[1] == 'w') { // we can skip all of this if it's not writable
++
++ tok = buf_ptr;
++ buf_ptr[OFFSET_MAP_START+ADDR_WIDTH] = '\0';
++ *start = strtoul(tok, NULL, 16);
++
++ tok = buf_ptr+OFFSET_MAP_END;
++ buf_ptr[OFFSET_MAP_END+ADDR_WIDTH] = '\0';
++ *end = strtoul(tok, NULL, 16);
++
++ buf_ptr += OFFSET_MAP_MAJDEV;
++ tok = buf_ptr;
++ while (*buf_ptr != ':') buf_ptr++;
++ *buf_ptr++ = '\0';
++ *maj_dev = strtoul(tok, NULL, 16);
++ }
++
++ while (*buf_ptr && *buf_ptr++ != '\n');
++
++ return buf_ptr;
++}
++
++#endif /* Need to parse /proc/self/maps. */
++
+ #if defined(SEARCH_FOR_DATA_START)
+ /* The I386 case can be handled without a search. The Alpha case */
+ /* used to be handled differently as well, but the rules changed */
+@@ -154,6 +311,11 @@
+ /* cover all versions. */
+
+ # ifdef LINUX
++ /* Some Linux distributions arrange to define __data_start. Some */
++ /* define data_start as a weak symbol. The latter is technically */
++ /* broken, since the user program may define data_start, in which */
++ /* case we lose. Nonetheless, we try both, prefering __data_start. */
++ /* We assume gcc-compatible pragmas. */
+ # pragma weak __data_start
+ extern int __data_start[];
+ # pragma weak data_start
+@@ -169,16 +331,16 @@
+
+ # ifdef LINUX
+ /* Try the easy approaches first: */
+- if (__data_start != 0) {
+- GC_data_start = (ptr_t)__data_start;
++ if ((ptr_t)__data_start != 0) {
++ GC_data_start = (ptr_t)(__data_start);
+ return;
+ }
+- if (data_start != 0) {
+- GC_data_start = (ptr_t)data_start;
++ if ((ptr_t)data_start != 0) {
++ GC_data_start = (ptr_t)(data_start);
+ return;
+ }
+ # endif /* LINUX */
+- GC_data_start = GC_find_limit((ptr_t)_end, FALSE);
++ GC_data_start = GC_find_limit((ptr_t)(_end), FALSE);
+ }
+ #endif
+
+@@ -617,7 +779,8 @@
+ }
+
+ /* Return the first nonaddressible location > p (up) or */
+- /* the smallest location q s.t. [q,p] is addressible (!up). */
++ /* the smallest location q s.t. [q,p) is addressable (!up). */
++ /* We assume that p (up) or p-1 (!up) is addressable. */
+ ptr_t GC_find_limit(p, up)
+ ptr_t p;
+ GC_bool up;
+@@ -650,18 +813,18 @@
+ }
+ # endif
+
+-# if defined(ECOS) || defined(NOSYS)
+-ptr_t GC_get_stack_base()
+-{
++#if defined(ECOS) || defined(NOSYS)
++ ptr_t GC_get_stack_base()
++ {
+ return STACKBOTTOM;
+-}
+-
+-#else
++ }
++#endif
+
+ #ifdef LINUX_STACKBOTTOM
+
+ #include <sys/types.h>
+ #include <sys/stat.h>
++#include <ctype.h>
+
+ # define STAT_SKIP 27 /* Number of fields preceding startstack */
+ /* field in /proc/self/stat */
+@@ -670,6 +833,33 @@
+ extern ptr_t __libc_stack_end;
+
+ # ifdef IA64
++ /* Try to read the backing store base from /proc/self/maps. */
++ /* We look for the writable mapping with a 0 major device, */
++ /* which is as close to our frame as possible, but below it.*/
++ static word backing_store_base_from_maps(char *maps)
++ {
++ char prot_buf[5];
++ char *buf_ptr = maps;
++ word start, end;
++ unsigned int maj_dev;
++ word current_best = 0;
++ word dummy;
++
++ for (;;) {
++ buf_ptr = GC_parse_map_entry(buf_ptr, &start, &end, prot_buf, &maj_dev);
++ if (buf_ptr == NULL) return current_best;
++ if (prot_buf[1] == 'w' && maj_dev == 0) {
++ if (end < (word)(&dummy) && start > current_best) current_best = start;
++ }
++ }
++ return current_best;
++ }
++
++ static word backing_store_base_from_proc(void)
++ {
++ return GC_apply_to_maps(backing_store_base_from_maps);
++ }
++
+ # pragma weak __libc_ia64_register_backing_store_base
+ extern ptr_t __libc_ia64_register_backing_store_base;
+
+@@ -683,9 +873,15 @@
+ /* Hence we check for both nonzero address and value. */
+ return __libc_ia64_register_backing_store_base;
+ } else {
+- word result = (word)GC_stackbottom - BACKING_STORE_DISPLACEMENT;
++ word result = backing_store_base_from_proc();
++ if (0 == result) {
++ /* Use dumb heuristics. Works only for default configuration. */
++ result = (word)GC_stackbottom - BACKING_STORE_DISPLACEMENT;
+ result += BACKING_STORE_ALIGNMENT - 1;
+ result &= ~(BACKING_STORE_ALIGNMENT - 1);
++ /* Verify that it's at least readable. If not, we goofed. */
++ GC_noop1(*(word *)result);
++ }
+ return (ptr_t)result;
+ }
+ }
+@@ -697,11 +893,8 @@
+ /* using direct I/O system calls in order to avoid calling malloc */
+ /* in case REDIRECT_MALLOC is defined. */
+ # define STAT_BUF_SIZE 4096
+-# if defined(GC_USE_LD_WRAP)
+-# define STAT_READ __real_read
+-# else
+ # define STAT_READ read
+-# endif
++ /* Should probably call the real read, if read is wrapped. */
+ char stat_buf[STAT_BUF_SIZE];
+ int f;
+ char c;
+@@ -710,7 +903,16 @@
+
+ /* First try the easy way. This should work for glibc 2.2 */
+ if (0 != &__libc_stack_end) {
++# ifdef IA64
++ /* Some versions of glibc set the address 16 bytes too */
++ /* low while the initialization code is running. */
++ if (((word)__libc_stack_end & 0xfff) + 0x10 < 0x1000) {
++ return __libc_stack_end + 0x10;
++ } /* Otherwise it's not safe to add 16 bytes and we fall */
++ /* back to using /proc. */
++# else
+ return __libc_stack_end;
++# endif
+ }
+ f = open("/proc/self/stat", O_RDONLY);
+ if (f < 0 || STAT_READ(f, stat_buf, STAT_BUF_SIZE) < 2 * STAT_SKIP) {
+@@ -764,8 +966,11 @@
+
+ ptr_t GC_get_stack_base()
+ {
++# if defined(HEURISTIC1) || defined(HEURISTIC2) || \
++ defined(LINUX_STACKBOTTOM) || defined(FREEBSD_STACKBOTTOM)
+ word dummy;
+ ptr_t result;
++# endif
+
+ # define STACKBOTTOM_ALIGNMENT_M1 ((word)STACK_GRAN - 1)
+
+@@ -814,7 +1019,6 @@
+ return(result);
+ # endif /* STACKBOTTOM */
+ }
+-# endif /* NOSYS ECOS */
+
+ # endif /* ! AMIGA, !OS 2, ! MS Windows, !BEOS */
+
+@@ -924,15 +1128,14 @@
+ /* Unfortunately, we have to handle win32s very differently from NT, */
+ /* Since VirtualQuery has very different semantics. In particular, */
+ /* under win32s a VirtualQuery call on an unmapped page returns an */
+- /* invalid result. Under GC_register_data_segments is a noop and */
++ /* invalid result. Under NT, GC_register_data_segments is a noop and */
+ /* all real work is done by GC_register_dynamic_libraries. Under */
+ /* win32s, we cannot find the data segments associated with dll's. */
+- /* We rgister the main data segment here. */
+-# ifdef __GCC__
+- GC_bool GC_no_win32_dlls = TRUE; /* GCC can't do SEH, so we can't use VirtualQuery */
+-# else
++ /* We register the main data segment here. */
+ GC_bool GC_no_win32_dlls = FALSE;
+-# endif
++ /* This used to be set for gcc, to avoid dealing with */
++ /* the structured exception handling issues. But we now have */
++ /* assembly code to do that right. */
+
+ void GC_init_win32()
+ {
+@@ -965,35 +1168,101 @@
+ }
+ # endif
+
+- /* Is p the start of either the malloc heap, or of one of our */
+- /* heap sections? */
+- GC_bool GC_is_heap_base (ptr_t p)
+- {
+-
+- register unsigned i;
+-
+ # ifndef REDIRECT_MALLOC
+- static ptr_t malloc_heap_pointer = 0;
++ /* We maintain a linked list of AllocationBase values that we know */
++ /* correspond to malloc heap sections. Currently this is only called */
++ /* during a GC. But there is some hope that for long running */
++ /* programs we will eventually see most heap sections. */
+
+- if (0 == malloc_heap_pointer) {
+- MEMORY_BASIC_INFORMATION buf;
+- void *pTemp = malloc( 1 );
+- register DWORD result = VirtualQuery(pTemp, &buf, sizeof(buf));
++ /* In the long run, it would be more reliable to occasionally walk */
++ /* the malloc heap with HeapWalk on the default heap. But that */
++ /* apparently works only for NT-based Windows. */
+
+- free( pTemp );
++ /* In the long run, a better data structure would also be nice ... */
++ struct GC_malloc_heap_list {
++ void * allocation_base;
++ struct GC_malloc_heap_list *next;
++ } *GC_malloc_heap_l = 0;
+
++ /* Is p the base of one of the malloc heap sections we already know */
++ /* about? */
++ GC_bool GC_is_malloc_heap_base(ptr_t p)
++ {
++ struct GC_malloc_heap_list *q = GC_malloc_heap_l;
++
++ while (0 != q) {
++ if (q -> allocation_base == p) return TRUE;
++ q = q -> next;
++ }
++ return FALSE;
++ }
+
++ void *GC_get_allocation_base(void *p)
++ {
++ MEMORY_BASIC_INFORMATION buf;
++ DWORD result = VirtualQuery(p, &buf, sizeof(buf));
+ if (result != sizeof(buf)) {
+ ABORT("Weird VirtualQuery result");
+ }
+- malloc_heap_pointer = (ptr_t)(buf.AllocationBase);
++ return buf.AllocationBase;
+ }
+- if (p == malloc_heap_pointer) return(TRUE);
++
++ size_t GC_max_root_size = 100000; /* Appr. largest root size. */
++
++ void GC_add_current_malloc_heap()
++ {
++ struct GC_malloc_heap_list *new_l =
++ malloc(sizeof(struct GC_malloc_heap_list));
++ void * candidate = GC_get_allocation_base(new_l);
++
++ if (new_l == 0) return;
++ if (GC_is_malloc_heap_base(candidate)) {
++ /* Try a little harder to find malloc heap. */
++ size_t req_size = 10000;
++ do {
++ void *p = malloc(req_size);
++ if (0 == p) { free(new_l); return; }
++ candidate = GC_get_allocation_base(p);
++ free(p);
++ req_size *= 2;
++ } while (GC_is_malloc_heap_base(candidate)
++ && req_size < GC_max_root_size/10 && req_size < 500000);
++ if (GC_is_malloc_heap_base(candidate)) {
++ free(new_l); return;
++ }
++ }
++# ifdef CONDPRINT
++ if (GC_print_stats)
++ GC_printf1("Found new system malloc AllocationBase at 0x%lx\n",
++ candidate);
++# endif
++ new_l -> allocation_base = candidate;
++ new_l -> next = GC_malloc_heap_l;
++ GC_malloc_heap_l = new_l;
++ }
++# endif /* REDIRECT_MALLOC */
++
++ /* Is p the start of either the malloc heap, or of one of our */
++ /* heap sections? */
++ GC_bool GC_is_heap_base (ptr_t p)
++ {
++
++ unsigned i;
++
++# ifndef REDIRECT_MALLOC
++ static word last_gc_no = -1;
++
++ if (last_gc_no != GC_gc_no) {
++ GC_add_current_malloc_heap();
++ last_gc_no = GC_gc_no;
++ }
++ if (GC_root_size > GC_max_root_size) GC_max_root_size = GC_root_size;
++ if (GC_is_malloc_heap_base(p)) return TRUE;
+ # endif
+ for (i = 0; i < GC_n_heap_bases; i++) {
+- if (GC_heap_bases[i] == p) return(TRUE);
++ if (GC_heap_bases[i] == p) return TRUE;
+ }
+- return(FALSE);
++ return FALSE ;
+ }
+
+ # ifdef MSWIN32
+@@ -1043,7 +1312,7 @@
+
+ # if (defined(SVR4) || defined(AUX) || defined(DGUX) \
+ || (defined(LINUX) && defined(SPARC))) && !defined(PCR)
+-char * GC_SysVGetDataStart(max_page_size, etext_addr)
++ptr_t GC_SysVGetDataStart(max_page_size, etext_addr)
+ int max_page_size;
+ int * etext_addr;
+ {
+@@ -1069,12 +1338,45 @@
+ /* string constants in the text segment, but after etext. */
+ /* Use plan B. Note that we now know there is a gap between */
+ /* text and data segments, so plan A bought us something. */
+- result = (char *)GC_find_limit((ptr_t)(DATAEND) - MIN_PAGE_SIZE, FALSE);
++ result = (char *)GC_find_limit((ptr_t)(DATAEND), FALSE);
+ }
+- return((char *)result);
++ return((ptr_t)result);
+ }
+ # endif
+
++# if defined(FREEBSD) && defined(I386) && !defined(PCR)
++/* Its unclear whether this should be identical to the above, or */
++/* whether it should apply to non-X86 architectures. */
++/* For now we don't assume that there is always an empty page after */
++/* etext. But in some cases there actually seems to be slightly more. */
++/* This also deals with holes between read-only data and writable data. */
++ptr_t GC_FreeBSDGetDataStart(max_page_size, etext_addr)
++int max_page_size;
++int * etext_addr;
++{
++ word text_end = ((word)(etext_addr) + sizeof(word) - 1)
++ & ~(sizeof(word) - 1);
++ /* etext rounded to word boundary */
++ VOLATILE word next_page = (text_end + (word)max_page_size - 1)
++ & ~((word)max_page_size - 1);
++ VOLATILE ptr_t result = (ptr_t)text_end;
++ GC_setup_temporary_fault_handler();
++ if (setjmp(GC_jmp_buf) == 0) {
++ /* Try reading at the address. */
++ /* This should happen before there is another thread. */
++ for (; next_page < (word)(DATAEND); next_page += (word)max_page_size)
++ *(VOLATILE char *)next_page;
++ GC_reset_fault_handler();
++ } else {
++ GC_reset_fault_handler();
++ /* As above, we go to plan B */
++ result = GC_find_limit((ptr_t)(DATAEND), FALSE);
++ }
++ return(result);
++}
++
++# endif
++
+
+ #ifdef AMIGA
+
+@@ -1086,8 +1388,7 @@
+
+ void GC_register_data_segments()
+ {
+-# if !defined(PCR) && !defined(SRC_M3) && !defined(NEXT) && !defined(MACOS) \
+- && !defined(MACOSX)
++# if !defined(PCR) && !defined(SRC_M3) && !defined(MACOS)
+ # if defined(REDIRECT_MALLOC) && defined(GC_SOLARIS_THREADS)
+ /* As of Solaris 2.3, the Solaris threads implementation */
+ /* allocates the data structure for the initial thread with */
+@@ -1104,9 +1405,6 @@
+ # endif
+ # endif
+ # endif
+-# if !defined(PCR) && (defined(NEXT) || defined(MACOSX))
+- GC_add_roots_inner(DATASTART, (char *) get_end(), FALSE);
+-# endif
+ # if defined(MACOS)
+ {
+ # if defined(THINK_C)
+@@ -1216,18 +1514,28 @@
+ ptr_t GC_unix_get_mem(bytes)
+ word bytes;
+ {
+- static GC_bool initialized = FALSE;
+- static int fd;
+ void *result;
+ static ptr_t last_addr = HEAP_START;
+
++# ifndef USE_MMAP_ANON
++ static GC_bool initialized = FALSE;
++ static int fd;
++
+ if (!initialized) {
+ fd = open("/dev/zero", O_RDONLY);
++ fcntl(fd, F_SETFD, FD_CLOEXEC);
+ initialized = TRUE;
+ }
++# endif
++
+ if (bytes & (GC_page_size -1)) ABORT("Bad GET_MEM arg");
++# ifdef USE_MMAP_ANON
++ result = mmap(last_addr, bytes, PROT_READ | PROT_WRITE | OPT_PROT_EXEC,
++ GC_MMAP_FLAGS | MAP_ANON, -1, 0/* offset */);
++# else
+ result = mmap(last_addr, bytes, PROT_READ | PROT_WRITE | OPT_PROT_EXEC,
+ GC_MMAP_FLAGS, fd, 0/* offset */);
++# endif
+ if (result == MAP_FAILED) return(0);
+ last_addr = (ptr_t)result + bytes + GC_page_size - 1;
+ last_addr = (ptr_t)((word)last_addr & ~(GC_page_size - 1));
+@@ -1322,7 +1630,15 @@
+ result = (ptr_t) GlobalAlloc(0, bytes + HBLKSIZE);
+ result = (ptr_t)(((word)result + HBLKSIZE) & ~(HBLKSIZE-1));
+ } else {
+- result = (ptr_t) VirtualAlloc(NULL, bytes,
++ /* VirtualProtect only works on regions returned by a */
++ /* single VirtualAlloc call. Thus we allocate one */
++ /* extra page, which will prevent merging of blocks */
++ /* in separate regions, and eliminate any temptation */
++ /* to call VirtualProtect on a range spanning regions. */
++ /* This wastes a small amount of memory, and risks */
++ /* increased fragmentation. But better alternatives */
++ /* would require effort. */
++ result = (ptr_t) VirtualAlloc(NULL, bytes + 1,
+ MEM_COMMIT | MEM_RESERVE,
+ PAGE_EXECUTE_READWRITE);
+ }
+@@ -1378,6 +1694,10 @@
+ /* Reserve more pages */
+ word res_bytes = (bytes + GC_sysinfo.dwAllocationGranularity-1)
+ & ~(GC_sysinfo.dwAllocationGranularity-1);
++ /* If we ever support MPROTECT_VDB here, we will probably need to */
++ /* ensure that res_bytes is strictly > bytes, so that VirtualProtect */
++ /* never spans regions. It seems to be OK for a VirtualFree argument */
++ /* to span regions, so we should be OK for now. */
+ result = (ptr_t) VirtualAlloc(NULL, res_bytes,
+ MEM_RESERVE | MEM_TOP_DOWN,
+ PAGE_EXECUTE_READWRITE);
+@@ -1508,6 +1828,7 @@
+ }
+ # else
+ if (-1 == zero_descr) zero_descr = open("/dev/zero", O_RDWR);
++ fcntl(zero_descr, F_SETFD, FD_CLOEXEC);
+ if (0 == start_addr) return;
+ result = mmap(start_addr, len, PROT_READ | PROT_WRITE | OPT_PROT_EXEC,
+ MAP_FIXED | MAP_PRIVATE, zero_descr, 0);
+@@ -1694,7 +2015,6 @@
+ * make sure that other system calls are similarly protected
+ * or write only to the stack.
+ */
+-
+ GC_bool GC_dirty_maintained = FALSE;
+
+ # ifdef DEFAULT_VDB
+@@ -1708,6 +2028,9 @@
+ /* Initialize virtual dirty bit implementation. */
+ void GC_dirty_init()
+ {
++#ifdef PRINTSTATS
++ GC_printf0("Initializing DEFAULT_VDB...\n");
++#endif
+ GC_dirty_maintained = TRUE;
+ }
+
+@@ -1776,17 +2099,21 @@
+ /*
+ * This implementation maintains dirty bits itself by catching write
+ * faults and keeping track of them. We assume nobody else catches
+- * SIGBUS or SIGSEGV. We assume no write faults occur in system calls
+- * except as a result of a read system call. This means clients must
+- * either ensure that system calls do not touch the heap, or must
+- * provide their own wrappers analogous to the one for read.
++ * SIGBUS or SIGSEGV. We assume no write faults occur in system calls.
++ * This means that clients must ensure that system calls don't write
++ * to the write-protected heap. Probably the best way to do this is to
++ * ensure that system calls write at most to POINTERFREE objects in the
++ * heap, and do even that only if we are on a platform on which those
++ * are not protected. Another alternative is to wrap system calls
++ * (see example for read below), but the current implementation holds
++ * a lock across blocking calls, making it problematic for multithreaded
++ * applications.
+ * We assume the page size is a multiple of HBLKSIZE.
+- * This implementation is currently SunOS 4.X and IRIX 5.X specific, though we
+- * tried to use portable code where easily possible. It is known
+- * not to work under a number of other systems.
++ * We prefer them to be the same. We avoid protecting POINTERFREE
++ * objects only if they are the same.
+ */
+
+-# if !defined(MSWIN32) && !defined(MSWINCE)
++# if !defined(MSWIN32) && !defined(MSWINCE) && !defined(DARWIN)
+
+ # include <sys/mman.h>
+ # include <signal.h>
+@@ -1805,6 +2132,23 @@
+
+ # else
+
++# ifdef DARWIN
++ /* Using vm_protect (mach syscall) over mprotect (BSD syscall) seems to
++ decrease the likelihood of some of the problems described below. */
++ #include <mach/vm_map.h>
++ extern mach_port_t GC_task_self;
++ #define PROTECT(addr,len) \
++ if(vm_protect(GC_task_self,(vm_address_t)(addr),(vm_size_t)(len), \
++ FALSE,VM_PROT_READ) != KERN_SUCCESS) { \
++ ABORT("vm_portect failed"); \
++ }
++ #define UNPROTECT(addr,len) \
++ if(vm_protect(GC_task_self,(vm_address_t)(addr),(vm_size_t)(len), \
++ FALSE,VM_PROT_READ|VM_PROT_WRITE) != KERN_SUCCESS) { \
++ ABORT("vm_portect failed"); \
++ }
++# else
++
+ # ifndef MSWINCE
+ # include <signal.h>
+ # endif
+@@ -1822,20 +2166,22 @@
+ &protect_junk)) { \
+ ABORT("un-VirtualProtect failed"); \
+ }
+-
+-# endif
++# endif /* !DARWIN */
++# endif /* MSWIN32 || MSWINCE || DARWIN */
+
+ #if defined(SUNOS4) || defined(FREEBSD)
+ typedef void (* SIG_PF)();
+-#endif
++#endif /* SUNOS4 || FREEBSD */
++
+ #if defined(SUNOS5SIGS) || defined(OSF1) || defined(LINUX) \
+- || defined(MACOSX) || defined(HURD)
++ || defined(HURD)
+ # ifdef __STDC__
+ typedef void (* SIG_PF)(int);
+ # else
+ typedef void (* SIG_PF)();
+ # endif
+-#endif
++#endif /* SUNOS5SIGS || OSF1 || LINUX || HURD */
++
+ #if defined(MSWIN32)
+ typedef LPTOP_LEVEL_EXCEPTION_FILTER SIG_PF;
+ # undef SIG_DFL
+@@ -1849,7 +2195,8 @@
+
+ #if defined(IRIX5) || defined(OSF1) || defined(HURD)
+ typedef void (* REAL_SIG_PF)(int, int, struct sigcontext *);
+-#endif
++#endif /* IRIX5 || OSF1 || HURD */
++
+ #if defined(SUNOS5SIGS)
+ # ifdef HPUX
+ # define SIGINFO __siginfo
+@@ -1861,13 +2208,14 @@
+ # else
+ typedef void (* REAL_SIG_PF)();
+ # endif
+-#endif
++#endif /* SUNOS5SIGS */
++
+ #if defined(LINUX)
+ # if __GLIBC__ > 2 || __GLIBC__ == 2 && __GLIBC_MINOR__ >= 2
+ typedef struct sigcontext s_c;
+ # else /* glibc < 2.2 */
+ # include <linux/version.h>
+-# if (LINUX_VERSION_CODE >= 0x20100) && !defined(M68K) || defined(ALPHA)
++# if (LINUX_VERSION_CODE >= 0x20100) && !defined(M68K) || defined(ALPHA) || defined(ARM32)
+ typedef struct sigcontext s_c;
+ # else
+ typedef struct sigcontext_struct s_c;
+@@ -1895,139 +2243,14 @@
+ return (char *)faultaddr;
+ }
+ # endif /* !ALPHA */
+-# endif
+-
+-# if defined(MACOSX) /* Should also test for PowerPC? */
+- typedef void (* REAL_SIG_PF)(int, int, struct sigcontext *);
+-
+-/* Decodes the machine instruction which was responsible for the sending of the
+- SIGBUS signal. Sadly this is the only way to find the faulting address because
+- the signal handler doesn't get it directly from the kernel (although it is
+- available on the Mach level, but droppped by the BSD personality before it
+- calls our signal handler...)
+- This code should be able to deal correctly with all PPCs starting from the
+- 601 up to and including the G4s (including Velocity Engine). */
+-#define EXTRACT_OP1(iw) (((iw) & 0xFC000000) >> 26)
+-#define EXTRACT_OP2(iw) (((iw) & 0x000007FE) >> 1)
+-#define EXTRACT_REGA(iw) (((iw) & 0x001F0000) >> 16)
+-#define EXTRACT_REGB(iw) (((iw) & 0x03E00000) >> 21)
+-#define EXTRACT_REGC(iw) (((iw) & 0x0000F800) >> 11)
+-#define EXTRACT_DISP(iw) ((short *) &(iw))[1]
+-
+-static char *get_fault_addr(struct sigcontext *scp)
+-{
+- unsigned int instr = *((unsigned int *) scp->sc_ir);
+- unsigned int * regs = &((unsigned int *) scp->sc_regs)[2];
+- int disp = 0, tmp;
+- unsigned int baseA = 0, baseB = 0;
+- unsigned int addr, alignmask = 0xFFFFFFFF;
+-
+-#ifdef GC_DEBUG_DECODER
+- GC_err_printf1("Instruction: 0x%lx\n", instr);
+- GC_err_printf1("Opcode 1: d\n", (int)EXTRACT_OP1(instr));
+-#endif
+- switch(EXTRACT_OP1(instr)) {
+- case 38: /* stb */
+- case 39: /* stbu */
+- case 54: /* stfd */
+- case 55: /* stfdu */
+- case 52: /* stfs */
+- case 53: /* stfsu */
+- case 44: /* sth */
+- case 45: /* sthu */
+- case 47: /* stmw */
+- case 36: /* stw */
+- case 37: /* stwu */
+- tmp = EXTRACT_REGA(instr);
+- if(tmp > 0)
+- baseA = regs[tmp];
+- disp = EXTRACT_DISP(instr);
+- break;
+- case 31:
+-#ifdef GC_DEBUG_DECODER
+- GC_err_printf1("Opcode 2: %d\n", (int)EXTRACT_OP2(instr));
+-#endif
+- switch(EXTRACT_OP2(instr)) {
+- case 86: /* dcbf */
+- case 54: /* dcbst */
+- case 1014: /* dcbz */
+- case 247: /* stbux */
+- case 215: /* stbx */
+- case 759: /* stfdux */
+- case 727: /* stfdx */
+- case 983: /* stfiwx */
+- case 695: /* stfsux */
+- case 663: /* stfsx */
+- case 918: /* sthbrx */
+- case 439: /* sthux */
+- case 407: /* sthx */
+- case 661: /* stswx */
+- case 662: /* stwbrx */
+- case 150: /* stwcx. */
+- case 183: /* stwux */
+- case 151: /* stwx */
+- case 135: /* stvebx */
+- case 167: /* stvehx */
+- case 199: /* stvewx */
+- case 231: /* stvx */
+- case 487: /* stvxl */
+- tmp = EXTRACT_REGA(instr);
+- if(tmp > 0)
+- baseA = regs[tmp];
+- baseB = regs[EXTRACT_REGC(instr)];
+- /* determine Altivec alignment mask */
+- switch(EXTRACT_OP2(instr)) {
+- case 167: /* stvehx */
+- alignmask = 0xFFFFFFFE;
+- break;
+- case 199: /* stvewx */
+- alignmask = 0xFFFFFFFC;
+- break;
+- case 231: /* stvx */
+- alignmask = 0xFFFFFFF0;
+- break;
+- case 487: /* stvxl */
+- alignmask = 0xFFFFFFF0;
+- break;
+- }
+- break;
+- case 725: /* stswi */
+- tmp = EXTRACT_REGA(instr);
+- if(tmp > 0)
+- baseA = regs[tmp];
+- break;
+- default: /* ignore instruction */
+-#ifdef GC_DEBUG_DECODER
+- GC_err_printf("Ignored by inner handler\n");
+-#endif
+- return NULL;
+- break;
+- }
+- break;
+- default: /* ignore instruction */
+-#ifdef GC_DEBUG_DECODER
+- GC_err_printf("Ignored by main handler\n");
+-#endif
+- return NULL;
+- break;
+- }
+-
+- addr = (baseA + baseB) + disp;
+- addr &= alignmask;
+-#ifdef GC_DEBUG_DECODER
+- GC_err_printf1("BaseA: %d\n", baseA);
+- GC_err_printf1("BaseB: %d\n", baseB);
+- GC_err_printf1("Disp: %d\n", disp);
+- GC_err_printf1("Address: %d\n", addr);
+-#endif
+- return (char *)addr;
+-}
+-#endif /* MACOSX */
++# endif /* LINUX */
+
++#ifndef DARWIN
+ SIG_PF GC_old_bus_handler;
+ SIG_PF GC_old_segv_handler; /* Also old MSWIN32 ACCESS_VIOLATION filter */
++#endif /* !DARWIN */
+
+-#ifdef THREADS
++#if defined(THREADS)
+ /* We need to lock around the bitmap update in the write fault handler */
+ /* in order to avoid the risk of losing a bit. We do this with a */
+ /* test-and-set spin lock if we know how to do that. Otherwise we */
+@@ -2076,6 +2299,7 @@
+ #endif /* !THREADS */
+
+ /*ARGSUSED*/
++#if !defined(DARWIN)
+ # if defined (SUNOS4) || defined(FREEBSD)
+ void GC_write_fault_handler(sig, code, scp, addr)
+ int sig, code;
+@@ -2091,7 +2315,8 @@
+ # define SIG_OK (sig == SIGBUS)
+ # define CODE_OK (code == BUS_PAGE_FAULT)
+ # endif
+-# endif
++# endif /* SUNOS4 || FREEBSD */
++
+ # if defined(IRIX5) || defined(OSF1) || defined(HURD)
+ # include <errno.h>
+ void GC_write_fault_handler(int sig, int code, struct sigcontext *scp)
+@@ -2107,7 +2332,8 @@
+ # define SIG_OK (sig == SIGBUS || sig == SIGSEGV)
+ # define CODE_OK TRUE
+ # endif
+-# endif
++# endif /* IRIX5 || OSF1 || HURD */
++
+ # if defined(LINUX)
+ # if defined(ALPHA) || defined(M68K)
+ void GC_write_fault_handler(int sig, int code, s_c * sc)
+@@ -2115,15 +2341,20 @@
+ # if defined(IA64) || defined(HP_PA)
+ void GC_write_fault_handler(int sig, siginfo_t * si, s_c * scp)
+ # else
++# if defined(ARM32)
++ void GC_write_fault_handler(int sig, int a2, int a3, int a4, s_c sc)
++# else
+ void GC_write_fault_handler(int sig, s_c sc)
+ # endif
+ # endif
++# endif
+ # define SIG_OK (sig == SIGSEGV)
+ # define CODE_OK TRUE
+ /* Empirically c.trapno == 14, on IA32, but is that useful? */
+ /* Should probably consider alignment issues on other */
+ /* architectures. */
+-# endif
++# endif /* LINUX */
++
+ # if defined(SUNOS5SIGS)
+ # ifdef __STDC__
+ void GC_write_fault_handler(int sig, struct SIGINFO *scp, void * context)
+@@ -2144,13 +2375,7 @@
+ # define SIG_OK (sig == SIGSEGV)
+ # define CODE_OK (scp -> si_code == SEGV_ACCERR)
+ # endif
+-# endif
+-
+-# if defined(MACOSX)
+- void GC_write_fault_handler(int sig, int code, struct sigcontext *scp)
+-# define SIG_OK (sig == SIGBUS)
+-# define CODE_OK (code == 0 /* experimentally determined */)
+-# endif
++# endif /* SUNOS5SIGS */
+
+ # if defined(MSWIN32) || defined(MSWINCE)
+ LONG WINAPI GC_write_fault_handler(struct _EXCEPTION_POINTERS *exc_info)
+@@ -2158,7 +2383,7 @@
+ STATUS_ACCESS_VIOLATION)
+ # define CODE_OK (exc_info -> ExceptionRecord -> ExceptionInformation[0] == 1)
+ /* Write fault */
+-# endif
++# endif /* MSWIN32 || MSWINCE */
+ {
+ register unsigned i;
+ # if defined(HURD)
+@@ -2218,6 +2443,9 @@
+ # if defined(POWERPC)
+ char * addr = (char *) (sc.regs->dar);
+ # else
++# if defined(ARM32)
++ char * addr = (char *)sc.fault_address;
++# else
+ --> architecture not supported
+ # endif
+ # endif
+@@ -2225,8 +2453,6 @@
+ # endif
+ # endif
+ # endif
+-# if defined(MACOSX)
+- char * addr = get_fault_addr(scp);
+ # endif
+ # if defined(MSWIN32) || defined(MSWINCE)
+ char * addr = (char *) (exc_info -> ExceptionRecord
+@@ -2291,9 +2517,6 @@
+ (*(REAL_SIG_PF)old_handler) (sig, code, scp);
+ return;
+ # endif
+-# ifdef MACOSX
+- (*(REAL_SIG_PF)old_handler) (sig, code, scp);
+-# endif
+ # ifdef MSWIN32
+ return((*old_handler)(exc_info));
+ # endif
+@@ -2335,10 +2558,11 @@
+ ABORT("Unexpected bus error or segmentation fault");
+ #endif
+ }
++#endif /* !DARWIN */
+
+ /*
+ * We hold the allocation lock. We expect block h to be written
+- * shortly. Ensure that all pages cvontaining any part of the n hblks
++ * shortly. Ensure that all pages containing any part of the n hblks
+ * starting at h are no longer protected. If is_ptrfree is false,
+ * also ensure that they will subsequently appear to be dirty.
+ */
+@@ -2367,6 +2591,7 @@
+ UNPROTECT(h_trunc, (ptr_t)h_end - (ptr_t)h_trunc);
+ }
+
++#if !defined(DARWIN)
+ void GC_dirty_init()
+ {
+ # if defined(SUNOS5SIGS) || defined(IRIX5) || defined(LINUX) || \
+@@ -2389,13 +2614,6 @@
+ (void)sigaddset(&act.sa_mask, SIG_SUSPEND);
+ # endif /* SIG_SUSPEND */
+ # endif
+-# if defined(MACOSX)
+- struct sigaction act, oldact;
+-
+- act.sa_flags = SA_RESTART;
+- act.sa_handler = GC_write_fault_handler;
+- sigemptyset(&act.sa_mask);
+-# endif
+ # ifdef PRINTSTATS
+ GC_printf0("Inititalizing mprotect virtual dirty bit implementation\n");
+ # endif
+@@ -2435,9 +2653,12 @@
+ sigaction(SIGSEGV, 0, &oldact);
+ sigaction(SIGSEGV, &act, 0);
+ # else
+- sigaction(SIGSEGV, &act, &oldact);
++ {
++ int res = sigaction(SIGSEGV, &act, &oldact);
++ if (res != 0) ABORT("Sigaction failed");
++ }
+ # endif
+-# if defined(_sigargs) || defined(HURD)
++# if defined(_sigargs) || defined(HURD) || !defined(SA_SIGINFO)
+ /* This is Irix 5.x, not 6.x. Irix 5.x does not have */
+ /* sa_sigaction. */
+ GC_old_segv_handler = oldact.sa_handler;
+@@ -2458,7 +2679,7 @@
+ # endif
+ }
+ # endif
+-# if defined(MACOSX) || defined(HPUX) || defined(LINUX) || defined(HURD)
++# if defined(HPUX) || defined(LINUX) || defined(HURD)
+ sigaction(SIGBUS, &act, &oldact);
+ GC_old_bus_handler = oldact.sa_handler;
+ if (GC_old_bus_handler == SIG_IGN) {
+@@ -2470,7 +2691,7 @@
+ GC_err_printf0("Replaced other SIGBUS handler\n");
+ # endif
+ }
+-# endif /* MACOS || HPUX || LINUX */
++# endif /* HPUX || LINUX || HURD */
+ # if defined(MSWIN32)
+ GC_old_segv_handler = SetUnhandledExceptionFilter(GC_write_fault_handler);
+ if (GC_old_segv_handler != NULL) {
+@@ -2482,6 +2703,7 @@
+ }
+ # endif
+ }
++#endif /* !DARWIN */
+
+ int GC_incremental_protection_needs()
+ {
+@@ -2628,15 +2850,23 @@
+ ((ptr_t)end_block - (ptr_t)start_block) + HBLKSIZE);
+ }
+
+-#if !defined(MSWIN32) && !defined(MSWINCE) && !defined(THREADS) \
+- && !defined(GC_USE_LD_WRAP)
++#if 0
++
++/* We no longer wrap read by default, since that was causing too many */
++/* problems. It is preferred that the client instead avoids writing */
++/* to the write-protected heap with a system call. */
++/* This still serves as sample code if you do want to wrap system calls.*/
++
++#if !defined(MSWIN32) && !defined(MSWINCE) && !defined(GC_USE_LD_WRAP)
+ /* Replacement for UNIX system call. */
+ /* Other calls that write to the heap should be handled similarly. */
+ /* Note that this doesn't work well for blocking reads: It will hold */
+-/* tha allocation lock for the entur duration of the call. Multithreaded */
++/* the allocation lock for the entire duration of the call. Multithreaded */
+ /* clients should really ensure that it won't block, either by setting */
+ /* the descriptor nonblocking, or by calling select or poll first, to */
+ /* make sure that input is available. */
++/* Another, preferred alternative is to ensure that system calls never */
++/* write to the protected heap (see above). */
+ # if defined(__STDC__) && !defined(SUNOS4)
+ # include <unistd.h>
+ # include <sys/uio.h>
+@@ -2706,6 +2936,8 @@
+ /* actually calls. */
+ #endif
+
++#endif /* 0 */
++
+ /*ARGSUSED*/
+ GC_bool GC_page_was_ever_dirty(h)
+ struct hblk *h;
+@@ -2721,13 +2953,6 @@
+ {
+ }
+
+-# else /* !MPROTECT_VDB */
+-
+-# ifdef GC_USE_LD_WRAP
+- ssize_t __wrap_read(int fd, void *buf, size_t nbyte)
+- { return __real_read(fd, buf, nbyte); }
+-# endif
+-
+ # endif /* MPROTECT_VDB */
+
+ # ifdef PROC_VDB
+@@ -2806,6 +3031,7 @@
+ }
+ GC_proc_fd = syscall(SYS_ioctl, fd, PIOCOPENPD, 0);
+ close(fd);
++ syscall(SYS_fcntl, GC_proc_fd, F_SETFD, FD_CLOEXEC);
+ if (GC_proc_fd < 0) {
+ ABORT("/proc ioctl failed");
+ }
+@@ -3045,6 +3271,553 @@
+
+ # endif /* PCR_VDB */
+
++#if defined(MPROTECT_VDB) && defined(DARWIN)
++/* The following sources were used as a *reference* for this exception handling
++ code:
++ 1. Apple's mach/xnu documentation
++ 2. Timothy J. Wood's "Mach Exception Handlers 101" post to the
++ omnigroup's macosx-dev list.
++ www.omnigroup.com/mailman/archive/macosx-dev/2000-June/002030.html
++ 3. macosx-nat.c from Apple's GDB source code.
++*/
++
++/* There seem to be numerous problems with darwin's mach exception handling.
++ I'm pretty sure they are not problems in my code. Search for
++ BROKEN_EXCEPTION_HANDLING for more information. */
++#define BROKEN_EXCEPTION_HANDLING
++
++#include <mach/mach.h>
++#include <mach/mach_error.h>
++#include <mach/thread_status.h>
++#include <mach/exception.h>
++#include <mach/task.h>
++#include <pthread.h>
++
++/* These are not defined in any header, although they are documented */
++extern boolean_t exc_server(mach_msg_header_t *,mach_msg_header_t *);
++extern kern_return_t exception_raise(
++ mach_port_t,mach_port_t,mach_port_t,
++ exception_type_t,exception_data_t,mach_msg_type_number_t);
++extern kern_return_t exception_raise_state(
++ mach_port_t,mach_port_t,mach_port_t,
++ exception_type_t,exception_data_t,mach_msg_type_number_t,
++ thread_state_flavor_t*,thread_state_t,mach_msg_type_number_t,
++ thread_state_t,mach_msg_type_number_t*);
++extern kern_return_t exception_raise_state_identity(
++ mach_port_t,mach_port_t,mach_port_t,
++ exception_type_t,exception_data_t,mach_msg_type_number_t,
++ thread_state_flavor_t*,thread_state_t,mach_msg_type_number_t,
++ thread_state_t,mach_msg_type_number_t*);
++
++
++#define MAX_EXCEPTION_PORTS 16
++
++static mach_port_t GC_task_self;
++
++static struct {
++ mach_msg_type_number_t count;
++ exception_mask_t masks[MAX_EXCEPTION_PORTS];
++ exception_handler_t ports[MAX_EXCEPTION_PORTS];
++ exception_behavior_t behaviors[MAX_EXCEPTION_PORTS];
++ thread_state_flavor_t flavors[MAX_EXCEPTION_PORTS];
++} GC_old_exc_ports;
++
++static struct {
++ mach_port_t exception;
++#if defined(THREADS)
++ mach_port_t reply;
++#endif
++} GC_ports;
++
++typedef struct {
++ mach_msg_header_t head;
++} GC_msg_t;
++
++typedef enum {
++ GC_MP_NORMAL, GC_MP_DISCARDING, GC_MP_STOPPED
++} GC_mprotect_state_t;
++
++/* FIXME: 1 and 2 seem to be safe to use in the msgh_id field,
++ but it isn't documented. Use the source and see if they
++ should be ok. */
++#define ID_STOP 1
++#define ID_RESUME 2
++
++/* These values are only used on the reply port */
++#define ID_ACK 3
++
++#if defined(THREADS)
++
++GC_mprotect_state_t GC_mprotect_state;
++
++/* The following should ONLY be called when the world is stopped */
++static void GC_mprotect_thread_notify(mach_msg_id_t id) {
++ struct {
++ GC_msg_t msg;
++ mach_msg_trailer_t trailer;
++ } buf;
++ mach_msg_return_t r;
++ /* remote, local */
++ buf.msg.head.msgh_bits =
++ MACH_MSGH_BITS(MACH_MSG_TYPE_MAKE_SEND,0);
++ buf.msg.head.msgh_size = sizeof(buf.msg);
++ buf.msg.head.msgh_remote_port = GC_ports.exception;
++ buf.msg.head.msgh_local_port = MACH_PORT_NULL;
++ buf.msg.head.msgh_id = id;
++
++ r = mach_msg(
++ &buf.msg.head,
++ MACH_SEND_MSG|MACH_RCV_MSG|MACH_RCV_LARGE,
++ sizeof(buf.msg),
++ sizeof(buf),
++ GC_ports.reply,
++ MACH_MSG_TIMEOUT_NONE,
++ MACH_PORT_NULL);
++ if(r != MACH_MSG_SUCCESS)
++ ABORT("mach_msg failed in GC_mprotect_thread_notify");
++ if(buf.msg.head.msgh_id != ID_ACK)
++ ABORT("invalid ack in GC_mprotect_thread_notify");
++}
++
++/* Should only be called by the mprotect thread */
++static void GC_mprotect_thread_reply() {
++ GC_msg_t msg;
++ mach_msg_return_t r;
++ /* remote, local */
++ msg.head.msgh_bits =
++ MACH_MSGH_BITS(MACH_MSG_TYPE_MAKE_SEND,0);
++ msg.head.msgh_size = sizeof(msg);
++ msg.head.msgh_remote_port = GC_ports.reply;
++ msg.head.msgh_local_port = MACH_PORT_NULL;
++ msg.head.msgh_id = ID_ACK;
++
++ r = mach_msg(
++ &msg.head,
++ MACH_SEND_MSG,
++ sizeof(msg),
++ 0,
++ MACH_PORT_NULL,
++ MACH_MSG_TIMEOUT_NONE,
++ MACH_PORT_NULL);
++ if(r != MACH_MSG_SUCCESS)
++ ABORT("mach_msg failed in GC_mprotect_thread_reply");
++}
++
++void GC_mprotect_stop() {
++ GC_mprotect_thread_notify(ID_STOP);
++}
++void GC_mprotect_resume() {
++ GC_mprotect_thread_notify(ID_RESUME);
++}
++
++#else /* !THREADS */
++/* The compiler should optimize away any GC_mprotect_state computations */
++#define GC_mprotect_state GC_MP_NORMAL
++#endif
++
++static void *GC_mprotect_thread(void *arg) {
++ mach_msg_return_t r;
++ /* These two structures contain some private kernel data. We don't need to
++ access any of it so we don't bother defining a proper struct. The
++ correct definitions are in the xnu source code. */
++ struct {
++ mach_msg_header_t head;
++ char data[256];
++ } reply;
++ struct {
++ mach_msg_header_t head;
++ mach_msg_body_t msgh_body;
++ char data[1024];
++ } msg;
++
++ mach_msg_id_t id;
++
++ for(;;) {
++ r = mach_msg(
++ &msg.head,
++ MACH_RCV_MSG|MACH_RCV_LARGE|
++ (GC_mprotect_state == GC_MP_DISCARDING ? MACH_RCV_TIMEOUT : 0),
++ 0,
++ sizeof(msg),
++ GC_ports.exception,
++ GC_mprotect_state == GC_MP_DISCARDING ? 0 : MACH_MSG_TIMEOUT_NONE,
++ MACH_PORT_NULL);
++
++ id = r == MACH_MSG_SUCCESS ? msg.head.msgh_id : -1;
++
++#if defined(THREADS)
++ if(GC_mprotect_state == GC_MP_DISCARDING) {
++ if(r == MACH_RCV_TIMED_OUT) {
++ GC_mprotect_state = GC_MP_STOPPED;
++ GC_mprotect_thread_reply();
++ continue;
++ }
++ if(r == MACH_MSG_SUCCESS && (id == ID_STOP || id == ID_RESUME))
++ ABORT("out of order mprotect thread request");
++ }
++#endif
++
++ if(r != MACH_MSG_SUCCESS) {
++ GC_err_printf2("mach_msg failed with %d %s\n",
++ (int)r,mach_error_string(r));
++ ABORT("mach_msg failed");
++ }
++
++ switch(id) {
++#if defined(THREADS)
++ case ID_STOP:
++ if(GC_mprotect_state != GC_MP_NORMAL)
++ ABORT("Called mprotect_stop when state wasn't normal");
++ GC_mprotect_state = GC_MP_DISCARDING;
++ break;
++ case ID_RESUME:
++ if(GC_mprotect_state != GC_MP_STOPPED)
++ ABORT("Called mprotect_resume when state wasn't stopped");
++ GC_mprotect_state = GC_MP_NORMAL;
++ GC_mprotect_thread_reply();
++ break;
++#endif /* THREADS */
++ default:
++ /* Handle the message (calls catch_exception_raise) */
++ if(!exc_server(&msg.head,&reply.head))
++ ABORT("exc_server failed");
++ /* Send the reply */
++ r = mach_msg(
++ &reply.head,
++ MACH_SEND_MSG,
++ reply.head.msgh_size,
++ 0,
++ MACH_PORT_NULL,
++ MACH_MSG_TIMEOUT_NONE,
++ MACH_PORT_NULL);
++ if(r != MACH_MSG_SUCCESS) {
++ /* This will fail if the thread dies, but the thread shouldn't
++ die... */
++ #ifdef BROKEN_EXCEPTION_HANDLING
++ GC_err_printf2(
++ "mach_msg failed with %d %s while sending exc reply\n",
++ (int)r,mach_error_string(r));
++ #else
++ ABORT("mach_msg failed while sending exception reply");
++ #endif
++ }
++ } /* switch */
++ } /* for(;;) */
++ /* NOT REACHED */
++ return NULL;
++}
++
++/* All this SIGBUS code shouldn't be necessary. All protection faults should
++ be going throught the mach exception handler. However, it seems a SIGBUS is
++ occasionally sent for some unknown reason. Even more odd, it seems to be
++ meaningless and safe to ignore. */
++#ifdef BROKEN_EXCEPTION_HANDLING
++
++typedef void (* SIG_PF)();
++static SIG_PF GC_old_bus_handler;
++
++/* Updates to this aren't atomic, but the SIGBUSs seem pretty rare.
++ Even if this doesn't get updated property, it isn't really a problem */
++static int GC_sigbus_count;
++
++static void GC_darwin_sigbus(int num,siginfo_t *sip,void *context) {
++ if(num != SIGBUS) ABORT("Got a non-sigbus signal in the sigbus handler");
++
++ /* Ugh... some seem safe to ignore, but too many in a row probably means
++ trouble. GC_sigbus_count is reset for each mach exception that is
++ handled */
++ if(GC_sigbus_count >= 8) {
++ ABORT("Got more than 8 SIGBUSs in a row!");
++ } else {
++ GC_sigbus_count++;
++ GC_err_printf0("GC: WARNING: Ignoring SIGBUS.\n");
++ }
++}
++#endif /* BROKEN_EXCEPTION_HANDLING */
++
++void GC_dirty_init() {
++ kern_return_t r;
++ mach_port_t me;
++ pthread_t thread;
++ pthread_attr_t attr;
++ exception_mask_t mask;
++
++# ifdef PRINTSTATS
++ GC_printf0("Inititalizing mach/darwin mprotect virtual dirty bit "
++ "implementation\n");
++# endif
++# ifdef BROKEN_EXCEPTION_HANDLING
++ GC_err_printf0("GC: WARNING: Enabling workarounds for various darwin "
++ "exception handling bugs.\n");
++# endif
++ GC_dirty_maintained = TRUE;
++ if (GC_page_size % HBLKSIZE != 0) {
++ GC_err_printf0("Page size not multiple of HBLKSIZE\n");
++ ABORT("Page size not multiple of HBLKSIZE");
++ }
++
++ GC_task_self = me = mach_task_self();
++
++ r = mach_port_allocate(me,MACH_PORT_RIGHT_RECEIVE,&GC_ports.exception);
++ if(r != KERN_SUCCESS) ABORT("mach_port_allocate failed (exception port)");
++
++ r = mach_port_insert_right(me,GC_ports.exception,GC_ports.exception,
++ MACH_MSG_TYPE_MAKE_SEND);
++ if(r != KERN_SUCCESS)
++ ABORT("mach_port_insert_right failed (exception port)");
++
++ #if defined(THREADS)
++ r = mach_port_allocate(me,MACH_PORT_RIGHT_RECEIVE,&GC_ports.reply);
++ if(r != KERN_SUCCESS) ABORT("mach_port_allocate failed (reply port)");
++ #endif
++
++ /* The exceptions we want to catch */
++ mask = EXC_MASK_BAD_ACCESS;
++
++ r = task_get_exception_ports(
++ me,
++ mask,
++ GC_old_exc_ports.masks,
++ &GC_old_exc_ports.count,
++ GC_old_exc_ports.ports,
++ GC_old_exc_ports.behaviors,
++ GC_old_exc_ports.flavors
++ );
++ if(r != KERN_SUCCESS) ABORT("task_get_exception_ports failed");
++
++ r = task_set_exception_ports(
++ me,
++ mask,
++ GC_ports.exception,
++ EXCEPTION_DEFAULT,
++ MACHINE_THREAD_STATE
++ );
++ if(r != KERN_SUCCESS) ABORT("task_set_exception_ports failed");
++
++ if(pthread_attr_init(&attr) != 0) ABORT("pthread_attr_init failed");
++ if(pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED) != 0)
++ ABORT("pthread_attr_setdetachedstate failed");
++
++# undef pthread_create
++ /* This will call the real pthread function, not our wrapper */
++ if(pthread_create(&thread,&attr,GC_mprotect_thread,NULL) != 0)
++ ABORT("pthread_create failed");
++ pthread_attr_destroy(&attr);
++
++ /* Setup the sigbus handler for ignoring the meaningless SIGBUSs */
++ #ifdef BROKEN_EXCEPTION_HANDLING
++ {
++ struct sigaction sa, oldsa;
++ sa.sa_handler = (SIG_PF)GC_darwin_sigbus;
++ sigemptyset(&sa.sa_mask);
++ sa.sa_flags = SA_RESTART|SA_SIGINFO;
++ if(sigaction(SIGBUS,&sa,&oldsa) < 0) ABORT("sigaction");
++ GC_old_bus_handler = (SIG_PF)oldsa.sa_handler;
++ if (GC_old_bus_handler != SIG_DFL) {
++# ifdef PRINTSTATS
++ GC_err_printf0("Replaced other SIGBUS handler\n");
++# endif
++ }
++ }
++ #endif /* BROKEN_EXCEPTION_HANDLING */
++}
++
++/* The source code for Apple's GDB was used as a reference for the exception
++ forwarding code. This code is similar to be GDB code only because there is
++ only one way to do it. */
++static kern_return_t GC_forward_exception(
++ mach_port_t thread,
++ mach_port_t task,
++ exception_type_t exception,
++ exception_data_t data,
++ mach_msg_type_number_t data_count
++) {
++ int i;
++ kern_return_t r;
++ mach_port_t port;
++ exception_behavior_t behavior;
++ thread_state_flavor_t flavor;
++
++ thread_state_data_t thread_state;
++ mach_msg_type_number_t thread_state_count = THREAD_STATE_MAX;
++
++ for(i=0;i<GC_old_exc_ports.count;i++)
++ if(GC_old_exc_ports.masks[i] & (1 << exception))
++ break;
++ if(i==GC_old_exc_ports.count) ABORT("No handler for exception!");
++
++ port = GC_old_exc_ports.ports[i];
++ behavior = GC_old_exc_ports.behaviors[i];
++ flavor = GC_old_exc_ports.flavors[i];
++
++ if(behavior != EXCEPTION_DEFAULT) {
++ r = thread_get_state(thread,flavor,thread_state,&thread_state_count);
++ if(r != KERN_SUCCESS)
++ ABORT("thread_get_state failed in forward_exception");
++ }
++
++ switch(behavior) {
++ case EXCEPTION_DEFAULT:
++ r = exception_raise(port,thread,task,exception,data,data_count);
++ break;
++ case EXCEPTION_STATE:
++ r = exception_raise_state(port,thread,task,exception,data,
++ data_count,&flavor,thread_state,thread_state_count,
++ thread_state,&thread_state_count);
++ break;
++ case EXCEPTION_STATE_IDENTITY:
++ r = exception_raise_state_identity(port,thread,task,exception,data,
++ data_count,&flavor,thread_state,thread_state_count,
++ thread_state,&thread_state_count);
++ break;
++ default:
++ r = KERN_FAILURE; /* make gcc happy */
++ ABORT("forward_exception: unknown behavior");
++ break;
++ }
++
++ if(behavior != EXCEPTION_DEFAULT) {
++ r = thread_set_state(thread,flavor,thread_state,thread_state_count);
++ if(r != KERN_SUCCESS)
++ ABORT("thread_set_state failed in forward_exception");
++ }
++
++ return r;
++}
++
++#define FWD() GC_forward_exception(thread,task,exception,code,code_count)
++
++/* This violates the namespace rules but there isn't anything that can be done
++ about it. The exception handling stuff is hard coded to call this */
++kern_return_t
++catch_exception_raise(
++ mach_port_t exception_port,mach_port_t thread,mach_port_t task,
++ exception_type_t exception,exception_data_t code,
++ mach_msg_type_number_t code_count
++) {
++ kern_return_t r;
++ char *addr;
++ struct hblk *h;
++ int i;
++#ifdef POWERPC
++ thread_state_flavor_t flavor = PPC_EXCEPTION_STATE;
++ mach_msg_type_number_t exc_state_count = PPC_EXCEPTION_STATE_COUNT;
++ ppc_exception_state_t exc_state;
++#else
++# error FIXME for non-ppc darwin
++#endif
++
++
++ if(exception != EXC_BAD_ACCESS || code[0] != KERN_PROTECTION_FAILURE) {
++ #ifdef DEBUG_EXCEPTION_HANDLING
++ /* We aren't interested, pass it on to the old handler */
++ GC_printf3("Exception: 0x%x Code: 0x%x 0x%x in catch....\n",
++ exception,
++ code_count > 0 ? code[0] : -1,
++ code_count > 1 ? code[1] : -1);
++ #endif
++ return FWD();
++ }
++
++ r = thread_get_state(thread,flavor,
++ (natural_t*)&exc_state,&exc_state_count);
++ if(r != KERN_SUCCESS) {
++ /* The thread is supposed to be suspended while the exception handler
++ is called. This shouldn't fail. */
++ #ifdef BROKEN_EXCEPTION_HANDLING
++ GC_err_printf0("thread_get_state failed in "
++ "catch_exception_raise\n");
++ return KERN_SUCCESS;
++ #else
++ ABORT("thread_get_state failed in catch_exception_raise");
++ #endif
++ }
++
++ /* This is the address that caused the fault */
++ addr = (char*) exc_state.dar;
++
++ if((HDR(addr)) == 0) {
++ /* Ugh... just like the SIGBUS problem above, it seems we get a bogus
++ KERN_PROTECTION_FAILURE every once and a while. We wait till we get
++ a bunch in a row before doing anything about it. If a "real" fault
++ ever occurres it'll just keep faulting over and over and we'll hit
++ the limit pretty quickly. */
++ #ifdef BROKEN_EXCEPTION_HANDLING
++ static char *last_fault;
++ static int last_fault_count;
++
++ if(addr != last_fault) {
++ last_fault = addr;
++ last_fault_count = 0;
++ }
++ if(++last_fault_count < 32) {
++ if(last_fault_count == 1)
++ GC_err_printf1(
++ "GC: WARNING: Ignoring KERN_PROTECTION_FAILURE at %p\n",
++ addr);
++ return KERN_SUCCESS;
++ }
++
++ GC_err_printf1("Unexpected KERN_PROTECTION_FAILURE at %p\n",addr);
++ /* Can't pass it along to the signal handler because that is
++ ignoring SIGBUS signals. We also shouldn't call ABORT here as
++ signals don't always work too well from the exception handler. */
++ GC_err_printf0("Aborting\n");
++ exit(EXIT_FAILURE);
++ #else /* BROKEN_EXCEPTION_HANDLING */
++ /* Pass it along to the next exception handler
++ (which should call SIGBUS/SIGSEGV) */
++ return FWD();
++ #endif /* !BROKEN_EXCEPTION_HANDLING */
++ }
++
++ #ifdef BROKEN_EXCEPTION_HANDLING
++ /* Reset the number of consecutive SIGBUSs */
++ GC_sigbus_count = 0;
++ #endif
++
++ if(GC_mprotect_state == GC_MP_NORMAL) { /* common case */
++ h = (struct hblk*)((word)addr & ~(GC_page_size-1));
++ UNPROTECT(h, GC_page_size);
++ for (i = 0; i < divHBLKSZ(GC_page_size); i++) {
++ register int index = PHT_HASH(h+i);
++ async_set_pht_entry_from_index(GC_dirty_pages, index);
++ }
++ } else if(GC_mprotect_state == GC_MP_DISCARDING) {
++ /* Lie to the thread for now. No sense UNPROTECT()ing the memory
++ when we're just going to PROTECT() it again later. The thread
++ will just fault again once it resumes */
++ } else {
++ /* Shouldn't happen, i don't think */
++ GC_printf0("KERN_PROTECTION_FAILURE while world is stopped\n");
++ return FWD();
++ }
++ return KERN_SUCCESS;
++}
++#undef FWD
++
++/* These should never be called, but just in case... */
++kern_return_t catch_exception_raise_state(mach_port_name_t exception_port,
++ int exception, exception_data_t code, mach_msg_type_number_t codeCnt,
++ int flavor, thread_state_t old_state, int old_stateCnt,
++ thread_state_t new_state, int new_stateCnt)
++{
++ ABORT("catch_exception_raise_state");
++ return(KERN_INVALID_ARGUMENT);
++}
++kern_return_t catch_exception_raise_state_identity(
++ mach_port_name_t exception_port, mach_port_t thread, mach_port_t task,
++ int exception, exception_data_t code, mach_msg_type_number_t codeCnt,
++ int flavor, thread_state_t old_state, int old_stateCnt,
++ thread_state_t new_state, int new_stateCnt)
++{
++ ABORT("catch_exception_raise_state_identity");
++ return(KERN_INVALID_ARGUMENT);
++}
++
++
++#endif /* DARWIN && MPROTECT_VDB */
++
+ # ifndef HAVE_INCREMENTAL_PROTECTION_NEEDS
+ int GC_incremental_protection_needs()
+ {
+@@ -3105,19 +3878,20 @@
+ # endif
+ #endif /* SPARC */
+
+-#ifdef SAVE_CALL_CHAIN
++#ifdef NEED_CALLINFO
+ /* Fill in the pc and argument information for up to NFRAMES of my */
+ /* callers. Ignore my frame and my callers frame. */
+
+ #ifdef LINUX
+-# include <features.h>
+-# if __GLIBC__ == 2 && __GLIBC_MINOR__ >= 1 || __GLIBC__ > 2
+-# define HAVE_BUILTIN_BACKTRACE
+-# endif
++# include <unistd.h>
+ #endif
+
++#endif /* NEED_CALLINFO */
++
++#ifdef SAVE_CALL_CHAIN
++
+ #if NARGS == 0 && NFRAMES % 2 == 0 /* No padding */ \
+- && defined(HAVE_BUILTIN_BACKTRACE)
++ && defined(GC_HAVE_BUILTIN_BACKTRACE)
+
+ #include <execinfo.h>
+
+@@ -3188,31 +3962,139 @@
+
+ #endif /* SAVE_CALL_CHAIN */
+
+-#if defined(LINUX) && defined(__ELF__) && \
+- (!defined(SMALL_CONFIG) || defined(USE_PROC_FOR_LIBRARIES))
+-#ifdef GC_USE_LD_WRAP
+-# define READ __real_read
+-#else
+-# define READ read
+-#endif
+-
++#ifdef NEED_CALLINFO
+
+-/* Repeatedly perform a read call until the buffer is filled or */
+-/* we encounter EOF. */
+-ssize_t GC_repeat_read(int fd, char *buf, size_t count)
++/* Print info to stderr. We do NOT hold the allocation lock */
++void GC_print_callers (info)
++struct callinfo info[NFRAMES];
+ {
+- ssize_t num_read = 0;
+- ssize_t result;
++ register int i;
++ static int reentry_count = 0;
++ GC_bool stop = FALSE;
+
+- while (num_read < count) {
+- result = READ(fd, buf + num_read, count - num_read);
+- if (result < 0) return result;
+- if (result == 0) break;
+- num_read += result;
++ LOCK();
++ ++reentry_count;
++ UNLOCK();
++
++# if NFRAMES == 1
++ GC_err_printf0("\tCaller at allocation:\n");
++# else
++ GC_err_printf0("\tCall chain at allocation:\n");
++# endif
++ for (i = 0; i < NFRAMES && !stop ; i++) {
++ if (info[i].ci_pc == 0) break;
++# if NARGS > 0
++ {
++ int j;
++
++ GC_err_printf0("\t\targs: ");
++ for (j = 0; j < NARGS; j++) {
++ if (j != 0) GC_err_printf0(", ");
++ GC_err_printf2("%d (0x%X)", ~(info[i].ci_arg[j]),
++ ~(info[i].ci_arg[j]));
+ }
+- return num_read;
++ GC_err_printf0("\n");
++ }
++# endif
++ if (reentry_count > 1) {
++ /* We were called during an allocation during */
++ /* a previous GC_print_callers call; punt. */
++ GC_err_printf1("\t\t##PC##= 0x%lx\n", info[i].ci_pc);
++ continue;
++ }
++ {
++# ifdef LINUX
++ FILE *pipe;
++# endif
++# if defined(GC_HAVE_BUILTIN_BACKTRACE)
++ char **sym_name =
++ backtrace_symbols((void **)(&(info[i].ci_pc)), 1);
++ char *name = sym_name[0];
++# else
++ char buf[40];
++ char *name = buf;
++ sprintf(buf, "##PC##= 0x%lx", info[i].ci_pc);
++# endif
++# if defined(LINUX) && !defined(SMALL_CONFIG)
++ /* Try for a line number. */
++ {
++# define EXE_SZ 100
++ static char exe_name[EXE_SZ];
++# define CMD_SZ 200
++ char cmd_buf[CMD_SZ];
++# define RESULT_SZ 200
++ static char result_buf[RESULT_SZ];
++ size_t result_len;
++ static GC_bool found_exe_name = FALSE;
++ static GC_bool will_fail = FALSE;
++ int ret_code;
++ /* Try to get it via a hairy and expensive scheme. */
++ /* First we get the name of the executable: */
++ if (will_fail) goto out;
++ if (!found_exe_name) {
++ ret_code = readlink("/proc/self/exe", exe_name, EXE_SZ);
++ if (ret_code < 0 || ret_code >= EXE_SZ
++ || exe_name[0] != '/') {
++ will_fail = TRUE; /* Dont try again. */
++ goto out;
++ }
++ exe_name[ret_code] = '\0';
++ found_exe_name = TRUE;
++ }
++ /* Then we use popen to start addr2line -e <exe> <addr> */
++ /* There are faster ways to do this, but hopefully this */
++ /* isn't time critical. */
++ sprintf(cmd_buf, "/usr/bin/addr2line -f -e %s 0x%lx", exe_name,
++ (unsigned long)info[i].ci_pc);
++ pipe = popen(cmd_buf, "r");
++ if (pipe == NULL
++ || (result_len = fread(result_buf, 1, RESULT_SZ - 1, pipe))
++ == 0) {
++ if (pipe != NULL) pclose(pipe);
++ will_fail = TRUE;
++ goto out;
++ }
++ if (result_buf[result_len - 1] == '\n') --result_len;
++ result_buf[result_len] = 0;
++ if (result_buf[0] == '?'
++ || result_buf[result_len-2] == ':'
++ && result_buf[result_len-1] == '0') {
++ pclose(pipe);
++ goto out;
++ }
++ /* Get rid of embedded newline, if any. Test for "main" */
++ {
++ char * nl = strchr(result_buf, '\n');
++ if (nl != NULL && nl < result_buf + result_len) {
++ *nl = ':';
++ }
++ if (strncmp(result_buf, "main", nl - result_buf) == 0) {
++ stop = TRUE;
++ }
++ }
++ if (result_len < RESULT_SZ - 25) {
++ /* Add in hex address */
++ sprintf(result_buf + result_len, " [0x%lx]",
++ (unsigned long)info[i].ci_pc);
++ }
++ name = result_buf;
++ pclose(pipe);
++ out:;
++ }
++# endif /* LINUX */
++ GC_err_printf1("\t\t%s\n", name);
++# if defined(GC_HAVE_BUILTIN_BACKTRACE)
++ free(sym_name); /* May call GC_free; that's OK */
++# endif
++ }
++ }
++ LOCK();
++ --reentry_count;
++ UNLOCK();
+ }
+-#endif /* LINUX && ... */
++
++#endif /* NEED_CALLINFO */
++
+
+
+ #if defined(LINUX) && defined(__ELF__) && !defined(SMALL_CONFIG)
+@@ -3220,20 +4102,16 @@
+ /* Dump /proc/self/maps to GC_stderr, to enable looking up names for
+ addresses in FIND_LEAK output. */
+
++static word dump_maps(char *maps)
++{
++ GC_err_write(maps, strlen(maps));
++ return 1;
++}
++
+ void GC_print_address_map()
+ {
+- int f;
+- int result;
+- char maps_temp[32768];
+ GC_err_printf0("---------- Begin address map ----------\n");
+- f = open("/proc/self/maps", O_RDONLY);
+- if (-1 == f) ABORT("Couldn't open /proc/self/maps");
+- do {
+- result = GC_repeat_read(f, maps_temp, sizeof(maps_temp));
+- if (result <= 0) ABORT("Couldn't read /proc/self/maps");
+- GC_err_write(maps_temp, result);
+- } while (result == sizeof(maps_temp));
+-
++ GC_apply_to_maps(dump_maps);
+ GC_err_printf0("---------- End address map ----------\n");
+ }
+
+diff -buNr boehm-gc/powerpc_darwin_mach_dep.s boehm-gc/powerpc_darwin_mach_dep.s
+--- boehm-gc/powerpc_darwin_mach_dep.s Wed Dec 31 16:00:00 1969
++++ boehm-gc/powerpc_darwin_mach_dep.s Sat Sep 13 02:10:15 2003
+@@ -0,0 +1,84 @@
++
++; GC_push_regs function. Under some optimization levels GCC will clobber
++; some of the non-volatile registers before we get a chance to save them
++; therefore, this can't be inline asm.
++
++.text
++ .align 2
++ .globl _GC_push_regs
++_GC_push_regs:
++
++ ; Prolog
++ mflr r0
++ stw r0,8(r1)
++ stwu r1,-80(r1)
++
++ ; Push r13-r31
++ mr r3,r13
++ bl L_GC_push_one$stub
++ mr r3,r14
++ bl L_GC_push_one$stub
++ mr r3,r15
++ bl L_GC_push_one$stub
++ mr r3,r16
++ bl L_GC_push_one$stub
++ mr r3,r17
++ bl L_GC_push_one$stub
++ mr r3,r18
++ bl L_GC_push_one$stub
++ mr r3,r19
++ bl L_GC_push_one$stub
++ mr r3,r20
++ bl L_GC_push_one$stub
++ mr r3,r21
++ bl L_GC_push_one$stub
++ mr r3,r22
++ bl L_GC_push_one$stub
++ mr r3,r23
++ bl L_GC_push_one$stub
++ mr r3,r24
++ bl L_GC_push_one$stub
++ mr r3,r25
++ bl L_GC_push_one$stub
++ mr r3,r26
++ bl L_GC_push_one$stub
++ mr r3,r27
++ bl L_GC_push_one$stub
++ mr r3,r28
++ bl L_GC_push_one$stub
++ mr r3,r29
++ bl L_GC_push_one$stub
++ mr r3,r30
++ bl L_GC_push_one$stub
++ mr r3,r31
++ bl L_GC_push_one$stub
++
++ ;
++ lwz r0,88(r1)
++ addi r1,r1,80
++ mtlr r0
++
++ ; Return
++ blr
++
++; PIC stuff, generated by GCC
++
++.data
++.picsymbol_stub
++L_GC_push_one$stub:
++ .indirect_symbol _GC_push_one
++ mflr r0
++ bcl 20,31,L0$_GC_push_one
++L0$_GC_push_one:
++ mflr r11
++ addis r11,r11,ha16(L_GC_push_one$lazy_ptr-L0$_GC_push_one)
++ mtlr r0
++ lwz r12,lo16(L_GC_push_one$lazy_ptr-L0$_GC_push_one)(r11)
++ mtctr r12
++ addi r11,r11,lo16(L_GC_push_one$lazy_ptr-L0$_GC_push_one)
++ bctr
++.data
++.lazy_symbol_pointer
++L_GC_push_one$lazy_ptr:
++ .indirect_symbol _GC_push_one
++ .long dyld_stub_binding_helper
+diff -buNr boehm-gc/pthread_stop_world.c boehm-gc/pthread_stop_world.c
+--- boehm-gc/pthread_stop_world.c Wed Dec 31 16:00:00 1969
++++ boehm-gc/pthread_stop_world.c Sat Sep 13 02:10:15 2003
+@@ -0,0 +1,445 @@
++#include "private/pthread_support.h"
++
++#if defined(GC_PTHREADS) && !defined(GC_SOLARIS_THREADS) \
++ && !defined(GC_IRIX_THREADS) && !defined(GC_WIN32_THREADS) \
++ && !defined(GC_DARWIN_THREADS)
++
++#include <signal.h>
++#include <semaphore.h>
++#include <errno.h>
++#include <unistd.h>
++
++#if DEBUG_THREADS
++
++#ifndef NSIG
++# if defined(MAXSIG)
++# define NSIG (MAXSIG+1)
++# elif defined(_NSIG)
++# define NSIG _NSIG
++# elif defined(__SIGRTMAX)
++# define NSIG (__SIGRTMAX+1)
++# else
++ --> please fix it
++# endif
++#endif
++
++void GC_print_sig_mask()
++{
++ sigset_t blocked;
++ int i;
++
++ if (pthread_sigmask(SIG_BLOCK, NULL, &blocked) != 0)
++ ABORT("pthread_sigmask");
++ GC_printf0("Blocked: ");
++ for (i = 1; i < NSIG; i++) {
++ if (sigismember(&blocked, i)) { GC_printf1("%ld ",(long) i); }
++ }
++ GC_printf0("\n");
++}
++
++#endif
++
++word GC_stop_count; /* Incremented at the beginning of GC_stop_world. */
++
++#ifdef GC_OSF1_THREADS
++ GC_bool GC_retry_signals = TRUE;
++#else
++ GC_bool GC_retry_signals = FALSE;
++#endif
++
++/*
++ * We use signals to stop threads during GC.
++ *
++ * Suspended threads wait in signal handler for SIG_THR_RESTART.
++ * That's more portable than semaphores or condition variables.
++ * (We do use sem_post from a signal handler, but that should be portable.)
++ *
++ * The thread suspension signal SIG_SUSPEND is now defined in gc_priv.h.
++ * Note that we can't just stop a thread; we need it to save its stack
++ * pointer(s) and acknowledge.
++ */
++
++#ifndef SIG_THR_RESTART
++# if defined(GC_HPUX_THREADS) || defined(GC_OSF1_THREADS)
++# ifdef _SIGRTMIN
++# define SIG_THR_RESTART _SIGRTMIN + 5
++# else
++# define SIG_THR_RESTART SIGRTMIN + 5
++# endif
++# else
++# define SIG_THR_RESTART SIGXCPU
++# endif
++#endif
++
++sem_t GC_suspend_ack_sem;
++
++void GC_suspend_handler(int sig)
++{
++ int dummy;
++ pthread_t my_thread = pthread_self();
++ GC_thread me;
++ sigset_t mask;
++# ifdef PARALLEL_MARK
++ word my_mark_no = GC_mark_no;
++ /* Marker can't proceed until we acknowledge. Thus this is */
++ /* guaranteed to be the mark_no correspending to our */
++ /* suspension, i.e. the marker can't have incremented it yet. */
++# endif
++ word my_stop_count = GC_stop_count;
++
++ if (sig != SIG_SUSPEND) ABORT("Bad signal in suspend_handler");
++
++#if DEBUG_THREADS
++ GC_printf1("Suspending 0x%lx\n", my_thread);
++#endif
++
++ me = GC_lookup_thread(my_thread);
++ /* The lookup here is safe, since I'm doing this on behalf */
++ /* of a thread which holds the allocation lock in order */
++ /* to stop the world. Thus concurrent modification of the */
++ /* data structure is impossible. */
++ if (me -> stop_info.last_stop_count == my_stop_count) {
++ /* Duplicate signal. OK if we are retrying. */
++ if (!GC_retry_signals) {
++ WARN("Duplicate suspend signal in thread %lx\n",
++ pthread_self());
++ }
++ return;
++ }
++# ifdef SPARC
++ me -> stop_info.stack_ptr = (ptr_t)GC_save_regs_in_stack();
++# else
++ me -> stop_info.stack_ptr = (ptr_t)(&dummy);
++# endif
++# ifdef IA64
++ me -> backing_store_ptr = (ptr_t)GC_save_regs_in_stack();
++# endif
++
++ /* Tell the thread that wants to stop the world that this */
++ /* thread has been stopped. Note that sem_post() is */
++ /* the only async-signal-safe primitive in LinuxThreads. */
++ sem_post(&GC_suspend_ack_sem);
++ me -> stop_info.last_stop_count = my_stop_count;
++
++ /* Wait until that thread tells us to restart by sending */
++ /* this thread a SIG_THR_RESTART signal. */
++ /* SIG_THR_RESTART should be masked at this point. Thus there */
++ /* is no race. */
++ if (sigfillset(&mask) != 0) ABORT("sigfillset() failed");
++ if (sigdelset(&mask, SIG_THR_RESTART) != 0) ABORT("sigdelset() failed");
++# ifdef NO_SIGNALS
++ if (sigdelset(&mask, SIGINT) != 0) ABORT("sigdelset() failed");
++ if (sigdelset(&mask, SIGQUIT) != 0) ABORT("sigdelset() failed");
++ if (sigdelset(&mask, SIGTERM) != 0) ABORT("sigdelset() failed");
++ if (sigdelset(&mask, SIGABRT) != 0) ABORT("sigdelset() failed");
++# endif
++ do {
++ me->stop_info.signal = 0;
++ sigsuspend(&mask); /* Wait for signal */
++ } while (me->stop_info.signal != SIG_THR_RESTART);
++ /* If the RESTART signal gets lost, we can still lose. That should be */
++ /* less likely than losing the SUSPEND signal, since we don't do much */
++ /* between the sem_post and sigsuspend. */
++ /* We'd need more handshaking to work around that, since we don't want */
++ /* to accidentally leave a RESTART signal pending, thus causing us to */
++ /* continue prematurely in a future round. */
++
++#if DEBUG_THREADS
++ GC_printf1("Continuing 0x%lx\n", my_thread);
++#endif
++}
++
++void GC_restart_handler(int sig)
++{
++ pthread_t my_thread = pthread_self();
++ GC_thread me;
++
++ if (sig != SIG_THR_RESTART) ABORT("Bad signal in suspend_handler");
++
++ /* Let the GC_suspend_handler() know that we got a SIG_THR_RESTART. */
++ /* The lookup here is safe, since I'm doing this on behalf */
++ /* of a thread which holds the allocation lock in order */
++ /* to stop the world. Thus concurrent modification of the */
++ /* data structure is impossible. */
++ me = GC_lookup_thread(my_thread);
++ me->stop_info.signal = SIG_THR_RESTART;
++
++ /*
++ ** Note: even if we didn't do anything useful here,
++ ** it would still be necessary to have a signal handler,
++ ** rather than ignoring the signals, otherwise
++ ** the signals will not be delivered at all, and
++ ** will thus not interrupt the sigsuspend() above.
++ */
++
++#if DEBUG_THREADS
++ GC_printf1("In GC_restart_handler for 0x%lx\n", pthread_self());
++#endif
++}
++
++# ifdef IA64
++# define IF_IA64(x) x
++# else
++# define IF_IA64(x)
++# endif
++/* We hold allocation lock. Should do exactly the right thing if the */
++/* world is stopped. Should not fail if it isn't. */
++void GC_push_all_stacks()
++{
++ int i;
++ GC_thread p;
++ ptr_t lo, hi;
++ /* On IA64, we also need to scan the register backing store. */
++ IF_IA64(ptr_t bs_lo; ptr_t bs_hi;)
++ pthread_t me = pthread_self();
++
++ if (!GC_thr_initialized) GC_thr_init();
++ #if DEBUG_THREADS
++ GC_printf1("Pushing stacks from thread 0x%lx\n", (unsigned long) me);
++ #endif
++ for (i = 0; i < THREAD_TABLE_SZ; i++) {
++ for (p = GC_threads[i]; p != 0; p = p -> next) {
++ if (p -> flags & FINISHED) continue;
++ if (pthread_equal(p -> id, me)) {
++# ifdef SPARC
++ lo = (ptr_t)GC_save_regs_in_stack();
++# else
++ lo = GC_approx_sp();
++# endif
++ IF_IA64(bs_hi = (ptr_t)GC_save_regs_in_stack();)
++ } else {
++ lo = p -> stop_info.stack_ptr;
++ IF_IA64(bs_hi = p -> backing_store_ptr;)
++ }
++ if ((p -> flags & MAIN_THREAD) == 0) {
++ hi = p -> stack_end;
++ IF_IA64(bs_lo = p -> backing_store_end);
++ } else {
++ /* The original stack. */
++ hi = GC_stackbottom;
++ IF_IA64(bs_lo = BACKING_STORE_BASE;)
++ }
++ #if DEBUG_THREADS
++ GC_printf3("Stack for thread 0x%lx = [%lx,%lx)\n",
++ (unsigned long) p -> id,
++ (unsigned long) lo, (unsigned long) hi);
++ #endif
++ if (0 == lo) ABORT("GC_push_all_stacks: sp not set!\n");
++# ifdef STACK_GROWS_UP
++ /* We got them backwards! */
++ GC_push_all_stack(hi, lo);
++# else
++ GC_push_all_stack(lo, hi);
++# endif
++# ifdef IA64
++ if (pthread_equal(p -> id, me)) {
++ GC_push_all_eager(bs_lo, bs_hi);
++ } else {
++ GC_push_all_stack(bs_lo, bs_hi);
++ }
++# endif
++ }
++ }
++}
++
++/* There seems to be a very rare thread stopping problem. To help us */
++/* debug that, we save the ids of the stopping thread. */
++pthread_t GC_stopping_thread;
++int GC_stopping_pid;
++
++/* We hold the allocation lock. Suspend all threads that might */
++/* still be running. Return the number of suspend signals that */
++/* were sent. */
++int GC_suspend_all()
++{
++ int n_live_threads = 0;
++ int i;
++ GC_thread p;
++ int result;
++ pthread_t my_thread = pthread_self();
++
++ GC_stopping_thread = my_thread; /* debugging only. */
++ GC_stopping_pid = getpid(); /* debugging only. */
++ for (i = 0; i < THREAD_TABLE_SZ; i++) {
++ for (p = GC_threads[i]; p != 0; p = p -> next) {
++ if (p -> id != my_thread) {
++ if (p -> flags & FINISHED) continue;
++ if (p -> stop_info.last_stop_count == GC_stop_count) continue;
++ if (p -> thread_blocked) /* Will wait */ continue;
++ n_live_threads++;
++ #if DEBUG_THREADS
++ GC_printf1("Sending suspend signal to 0x%lx\n", p -> id);
++ #endif
++
++ result = pthread_kill(p -> id, SIG_SUSPEND);
++ switch(result) {
++ case ESRCH:
++ /* Not really there anymore. Possible? */
++ n_live_threads--;
++ break;
++ case 0:
++ break;
++ default:
++ ABORT("pthread_kill failed");
++ }
++ }
++ }
++ }
++ return n_live_threads;
++}
++
++/* Caller holds allocation lock. */
++void GC_stop_world()
++{
++ int i;
++ int n_live_threads;
++ int code;
++
++ #if DEBUG_THREADS
++ GC_printf1("Stopping the world from 0x%lx\n", pthread_self());
++ #endif
++
++ /* Make sure all free list construction has stopped before we start. */
++ /* No new construction can start, since free list construction is */
++ /* required to acquire and release the GC lock before it starts, */
++ /* and we have the lock. */
++# ifdef PARALLEL_MARK
++ GC_acquire_mark_lock();
++ GC_ASSERT(GC_fl_builder_count == 0);
++ /* We should have previously waited for it to become zero. */
++# endif /* PARALLEL_MARK */
++ ++GC_stop_count;
++ n_live_threads = GC_suspend_all();
++
++ if (GC_retry_signals) {
++ unsigned long wait_usecs = 0; /* Total wait since retry. */
++# define WAIT_UNIT 3000
++# define RETRY_INTERVAL 100000
++ for (;;) {
++ int ack_count;
++
++ sem_getvalue(&GC_suspend_ack_sem, &ack_count);
++ if (ack_count == n_live_threads) break;
++ if (wait_usecs > RETRY_INTERVAL) {
++ int newly_sent = GC_suspend_all();
++
++# ifdef CONDPRINT
++ if (GC_print_stats) {
++ GC_printf1("Resent %ld signals after timeout\n",
++ newly_sent);
++ }
++# endif
++ sem_getvalue(&GC_suspend_ack_sem, &ack_count);
++ if (newly_sent < n_live_threads - ack_count) {
++ WARN("Lost some threads during GC_stop_world?!\n",0);
++ n_live_threads = ack_count + newly_sent;
++ }
++ wait_usecs = 0;
++ }
++ usleep(WAIT_UNIT);
++ wait_usecs += WAIT_UNIT;
++ }
++ }
++ for (i = 0; i < n_live_threads; i++) {
++ if (0 != (code = sem_wait(&GC_suspend_ack_sem))) {
++ GC_err_printf1("Sem_wait returned %ld\n", (unsigned long)code);
++ ABORT("sem_wait for handler failed");
++ }
++ }
++# ifdef PARALLEL_MARK
++ GC_release_mark_lock();
++# endif
++ #if DEBUG_THREADS
++ GC_printf1("World stopped from 0x%lx\n", pthread_self());
++ #endif
++ GC_stopping_thread = 0; /* debugging only */
++}
++
++/* Caller holds allocation lock, and has held it continuously since */
++/* the world stopped. */
++void GC_start_world()
++{
++ pthread_t my_thread = pthread_self();
++ register int i;
++ register GC_thread p;
++ register int n_live_threads = 0;
++ register int result;
++
++# if DEBUG_THREADS
++ GC_printf0("World starting\n");
++# endif
++
++ for (i = 0; i < THREAD_TABLE_SZ; i++) {
++ for (p = GC_threads[i]; p != 0; p = p -> next) {
++ if (p -> id != my_thread) {
++ if (p -> flags & FINISHED) continue;
++ if (p -> thread_blocked) continue;
++ n_live_threads++;
++ #if DEBUG_THREADS
++ GC_printf1("Sending restart signal to 0x%lx\n", p -> id);
++ #endif
++
++ result = pthread_kill(p -> id, SIG_THR_RESTART);
++ switch(result) {
++ case ESRCH:
++ /* Not really there anymore. Possible? */
++ n_live_threads--;
++ break;
++ case 0:
++ break;
++ default:
++ ABORT("pthread_kill failed");
++ }
++ }
++ }
++ }
++ #if DEBUG_THREADS
++ GC_printf0("World started\n");
++ #endif
++}
++
++void GC_stop_init() {
++ struct sigaction act;
++
++ if (sem_init(&GC_suspend_ack_sem, 0, 0) != 0)
++ ABORT("sem_init failed");
++
++ act.sa_flags = SA_RESTART;
++ if (sigfillset(&act.sa_mask) != 0) {
++ ABORT("sigfillset() failed");
++ }
++# ifdef NO_SIGNALS
++ if (sigdelset(&act.sa_mask, SIGINT) != 0
++ || sigdelset(&act.sa_mask, SIGQUIT != 0)
++ || sigdelset(&act.sa_mask, SIGABRT != 0)
++ || sigdelset(&act.sa_mask, SIGTERM != 0)) {
++ ABORT("sigdelset() failed");
++ }
++# endif
++
++ /* SIG_THR_RESTART is unmasked by the handler when necessary. */
++ act.sa_handler = GC_suspend_handler;
++ if (sigaction(SIG_SUSPEND, &act, NULL) != 0) {
++ ABORT("Cannot set SIG_SUSPEND handler");
++ }
++
++ act.sa_handler = GC_restart_handler;
++ if (sigaction(SIG_THR_RESTART, &act, NULL) != 0) {
++ ABORT("Cannot set SIG_THR_RESTART handler");
++ }
++
++ /* Check for GC_RETRY_SIGNALS. */
++ if (0 != GETENV("GC_RETRY_SIGNALS")) {
++ GC_retry_signals = TRUE;
++ }
++ if (0 != GETENV("GC_NO_RETRY_SIGNALS")) {
++ GC_retry_signals = FALSE;
++ }
++# ifdef CONDPRINT
++ if (GC_print_stats && GC_retry_signals) {
++ GC_printf0("Will retry suspend signal if necessary.\n");
++ }
++# endif
++}
++
++#endif
+diff -buNr boehm-gc/pthread_support.c boehm-gc/pthread_support.c
+--- boehm-gc/pthread_support.c Wed Dec 31 16:00:00 1969
++++ boehm-gc/pthread_support.c Sat Sep 13 02:10:15 2003
+@@ -0,0 +1,1568 @@
++/*
++ * Copyright (c) 1994 by Xerox Corporation. All rights reserved.
++ * Copyright (c) 1996 by Silicon Graphics. All rights reserved.
++ * Copyright (c) 1998 by Fergus Henderson. All rights reserved.
++ * Copyright (c) 2000-2001 by Hewlett-Packard Company. All rights reserved.
++ *
++ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
++ * OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
++ *
++ * Permission is hereby granted to use or copy this program
++ * for any purpose, provided the above notices are retained on all copies.
++ * Permission to modify the code and to distribute modified code is granted,
++ * provided the above notices are retained, and a notice that the code was
++ * modified is included with the above copyright notice.
++ */
++/*
++ * Support code for LinuxThreads, the clone()-based kernel
++ * thread package for Linux which is included in libc6.
++ *
++ * This code relies on implementation details of LinuxThreads,
++ * (i.e. properties not guaranteed by the Pthread standard),
++ * though this version now does less of that than the other Pthreads
++ * support code.
++ *
++ * Note that there is a lot of code duplication between linux_threads.c
++ * and thread support for some of the other Posix platforms; any changes
++ * made here may need to be reflected there too.
++ */
++ /* DG/UX ix86 support <takis@xfree86.org> */
++/*
++ * Linux_threads.c now also includes some code to support HPUX and
++ * OSF1 (Compaq Tru64 Unix, really). The OSF1 support is not yet
++ * functional. The OSF1 code is based on Eric Benson's
++ * patch, though that was originally against hpux_irix_threads. The code
++ * here is completely untested. With 0.0000001% probability, it might
++ * actually work.
++ *
++ * Eric also suggested an alternate basis for a lock implementation in
++ * his code:
++ * + #elif defined(OSF1)
++ * + unsigned long GC_allocate_lock = 0;
++ * + msemaphore GC_allocate_semaphore;
++ * + # define GC_TRY_LOCK() \
++ * + ((msem_lock(&GC_allocate_semaphore, MSEM_IF_NOWAIT) == 0) \
++ * + ? (GC_allocate_lock = 1) \
++ * + : 0)
++ * + # define GC_LOCK_TAKEN GC_allocate_lock
++ */
++
++/*#define DEBUG_THREADS 1*/
++/*#define GC_ASSERTIONS*/
++
++# include "private/pthread_support.h"
++
++# if defined(GC_PTHREADS) && !defined(GC_SOLARIS_THREADS) \
++ && !defined(GC_IRIX_THREADS) && !defined(GC_WIN32_THREADS)
++
++# if defined(GC_HPUX_THREADS) && !defined(USE_PTHREAD_SPECIFIC) \
++ && !defined(USE_HPUX_TLS)
++# define USE_HPUX_TLS
++# endif
++
++# if (defined(GC_DGUX386_THREADS) || defined(GC_OSF1_THREADS) || \
++ defined(GC_DARWIN_THREADS)) && !defined(USE_PTHREAD_SPECIFIC)
++# define USE_PTHREAD_SPECIFIC
++# endif
++
++# if defined(GC_DGUX386_THREADS) && !defined(_POSIX4A_DRAFT10_SOURCE)
++# define _POSIX4A_DRAFT10_SOURCE 1
++# endif
++
++# if defined(GC_DGUX386_THREADS) && !defined(_USING_POSIX4A_DRAFT10)
++# define _USING_POSIX4A_DRAFT10 1
++# endif
++
++# ifdef THREAD_LOCAL_ALLOC
++# if !defined(USE_PTHREAD_SPECIFIC) && !defined(USE_HPUX_TLS)
++# include "private/specific.h"
++# endif
++# if defined(USE_PTHREAD_SPECIFIC)
++# define GC_getspecific pthread_getspecific
++# define GC_setspecific pthread_setspecific
++# define GC_key_create pthread_key_create
++ typedef pthread_key_t GC_key_t;
++# endif
++# if defined(USE_HPUX_TLS)
++# define GC_getspecific(x) (x)
++# define GC_setspecific(key, v) ((key) = (v), 0)
++# define GC_key_create(key, d) 0
++ typedef void * GC_key_t;
++# endif
++# endif
++# include <stdlib.h>
++# include <pthread.h>
++# include <sched.h>
++# include <time.h>
++# include <errno.h>
++# include <unistd.h>
++# include <sys/mman.h>
++# include <sys/time.h>
++# include <sys/types.h>
++# include <sys/stat.h>
++# include <fcntl.h>
++
++#if defined(GC_DARWIN_THREADS)
++# include "private/darwin_semaphore.h"
++#else
++# include <semaphore.h>
++#endif /* !GC_DARWIN_THREADS */
++
++#if defined(GC_DARWIN_THREADS)
++# include <sys/sysctl.h>
++#endif /* GC_DARWIN_THREADS */
++
++
++
++#if defined(GC_DGUX386_THREADS)
++# include <sys/dg_sys_info.h>
++# include <sys/_int_psem.h>
++ /* sem_t is an uint in DG/UX */
++ typedef unsigned int sem_t;
++#endif /* GC_DGUX386_THREADS */
++
++#ifndef __GNUC__
++# define __inline__
++#endif
++
++#ifdef GC_USE_LD_WRAP
++# define WRAP_FUNC(f) __wrap_##f
++# define REAL_FUNC(f) __real_##f
++#else
++# define WRAP_FUNC(f) GC_##f
++# if !defined(GC_DGUX386_THREADS)
++# define REAL_FUNC(f) f
++# else /* GC_DGUX386_THREADS */
++# define REAL_FUNC(f) __d10_##f
++# endif /* GC_DGUX386_THREADS */
++# undef pthread_create
++# if !defined(GC_DARWIN_THREADS)
++# undef pthread_sigmask
++# endif
++# undef pthread_join
++# undef pthread_detach
++#endif
++
++void GC_thr_init();
++
++static GC_bool parallel_initialized = FALSE;
++
++void GC_init_parallel();
++
++# if defined(THREAD_LOCAL_ALLOC) && !defined(DBG_HDRS_ALL)
++
++/* We don't really support thread-local allocation with DBG_HDRS_ALL */
++
++#ifdef USE_HPUX_TLS
++ __thread
++#endif
++GC_key_t GC_thread_key;
++
++static GC_bool keys_initialized;
++
++/* Recover the contents of the freelist array fl into the global one gfl.*/
++/* Note that the indexing scheme differs, in that gfl has finer size */
++/* resolution, even if not all entries are used. */
++/* We hold the allocator lock. */
++static void return_freelists(ptr_t *fl, ptr_t *gfl)
++{
++ int i;
++ ptr_t q, *qptr;
++ size_t nwords;
++
++ for (i = 1; i < NFREELISTS; ++i) {
++ nwords = i * (GRANULARITY/sizeof(word));
++ qptr = fl + i;
++ q = *qptr;
++ if ((word)q >= HBLKSIZE) {
++ if (gfl[nwords] == 0) {
++ gfl[nwords] = q;
++ } else {
++ /* Concatenate: */
++ for (; (word)q >= HBLKSIZE; qptr = &(obj_link(q)), q = *qptr);
++ GC_ASSERT(0 == q);
++ *qptr = gfl[nwords];
++ gfl[nwords] = fl[i];
++ }
++ }
++ /* Clear fl[i], since the thread structure may hang around. */
++ /* Do it in a way that is likely to trap if we access it. */
++ fl[i] = (ptr_t)HBLKSIZE;
++ }
++}
++
++/* We statically allocate a single "size 0" object. It is linked to */
++/* itself, and is thus repeatedly reused for all size 0 allocation */
++/* requests. (Size 0 gcj allocation requests are incorrect, and */
++/* we arrange for those to fault asap.) */
++static ptr_t size_zero_object = (ptr_t)(&size_zero_object);
++
++/* Each thread structure must be initialized. */
++/* This call must be made from the new thread. */
++/* Caller holds allocation lock. */
++void GC_init_thread_local(GC_thread p)
++{
++ int i;
++
++ if (!keys_initialized) {
++ if (0 != GC_key_create(&GC_thread_key, 0)) {
++ ABORT("Failed to create key for local allocator");
++ }
++ keys_initialized = TRUE;
++ }
++ if (0 != GC_setspecific(GC_thread_key, p)) {
++ ABORT("Failed to set thread specific allocation pointers");
++ }
++ for (i = 1; i < NFREELISTS; ++i) {
++ p -> ptrfree_freelists[i] = (ptr_t)1;
++ p -> normal_freelists[i] = (ptr_t)1;
++# ifdef GC_GCJ_SUPPORT
++ p -> gcj_freelists[i] = (ptr_t)1;
++# endif
++ }
++ /* Set up the size 0 free lists. */
++ p -> ptrfree_freelists[0] = (ptr_t)(&size_zero_object);
++ p -> normal_freelists[0] = (ptr_t)(&size_zero_object);
++# ifdef GC_GCJ_SUPPORT
++ p -> gcj_freelists[0] = (ptr_t)(-1);
++# endif
++}
++
++#ifdef GC_GCJ_SUPPORT
++ extern ptr_t * GC_gcjobjfreelist;
++#endif
++
++/* We hold the allocator lock. */
++void GC_destroy_thread_local(GC_thread p)
++{
++ /* We currently only do this from the thread itself or from */
++ /* the fork handler for a child process. */
++# ifndef HANDLE_FORK
++ GC_ASSERT(GC_getspecific(GC_thread_key) == (void *)p);
++# endif
++ return_freelists(p -> ptrfree_freelists, GC_aobjfreelist);
++ return_freelists(p -> normal_freelists, GC_objfreelist);
++# ifdef GC_GCJ_SUPPORT
++ return_freelists(p -> gcj_freelists, GC_gcjobjfreelist);
++# endif
++}
++
++extern GC_PTR GC_generic_malloc_many();
++
++GC_PTR GC_local_malloc(size_t bytes)
++{
++ if (EXPECT(!SMALL_ENOUGH(bytes),0)) {
++ return(GC_malloc(bytes));
++ } else {
++ int index = INDEX_FROM_BYTES(bytes);
++ ptr_t * my_fl;
++ ptr_t my_entry;
++# if defined(REDIRECT_MALLOC) && !defined(USE_PTHREAD_SPECIFIC)
++ GC_key_t k = GC_thread_key;
++# endif
++ void * tsd;
++
++# if defined(REDIRECT_MALLOC) && !defined(USE_PTHREAD_SPECIFIC)
++ if (EXPECT(0 == k, 0)) {
++ /* This can happen if we get called when the world is */
++ /* being initialized. Whether we can actually complete */
++ /* the initialization then is unclear. */
++ GC_init_parallel();
++ k = GC_thread_key;
++ }
++# endif
++ tsd = GC_getspecific(GC_thread_key);
++# ifdef GC_ASSERTIONS
++ LOCK();
++ GC_ASSERT(tsd == (void *)GC_lookup_thread(pthread_self()));
++ UNLOCK();
++# endif
++ my_fl = ((GC_thread)tsd) -> normal_freelists + index;
++ my_entry = *my_fl;
++ if (EXPECT((word)my_entry >= HBLKSIZE, 1)) {
++ ptr_t next = obj_link(my_entry);
++ GC_PTR result = (GC_PTR)my_entry;
++ *my_fl = next;
++ obj_link(my_entry) = 0;
++ PREFETCH_FOR_WRITE(next);
++ return result;
++ } else if ((word)my_entry - 1 < DIRECT_GRANULES) {
++ *my_fl = my_entry + index + 1;
++ return GC_malloc(bytes);
++ } else {
++ GC_generic_malloc_many(BYTES_FROM_INDEX(index), NORMAL, my_fl);
++ if (*my_fl == 0) return GC_oom_fn(bytes);
++ return GC_local_malloc(bytes);
++ }
++ }
++}
++
++GC_PTR GC_local_malloc_atomic(size_t bytes)
++{
++ if (EXPECT(!SMALL_ENOUGH(bytes), 0)) {
++ return(GC_malloc_atomic(bytes));
++ } else {
++ int index = INDEX_FROM_BYTES(bytes);
++ ptr_t * my_fl = ((GC_thread)GC_getspecific(GC_thread_key))
++ -> ptrfree_freelists + index;
++ ptr_t my_entry = *my_fl;
++
++ if (EXPECT((word)my_entry >= HBLKSIZE, 1)) {
++ GC_PTR result = (GC_PTR)my_entry;
++ *my_fl = obj_link(my_entry);
++ return result;
++ } else if ((word)my_entry - 1 < DIRECT_GRANULES) {
++ *my_fl = my_entry + index + 1;
++ return GC_malloc_atomic(bytes);
++ } else {
++ GC_generic_malloc_many(BYTES_FROM_INDEX(index), PTRFREE, my_fl);
++ /* *my_fl is updated while the collector is excluded; */
++ /* the free list is always visible to the collector as */
++ /* such. */
++ if (*my_fl == 0) return GC_oom_fn(bytes);
++ return GC_local_malloc_atomic(bytes);
++ }
++ }
++}
++
++#ifdef GC_GCJ_SUPPORT
++
++#include "include/gc_gcj.h"
++
++#ifdef GC_ASSERTIONS
++ extern GC_bool GC_gcj_malloc_initialized;
++#endif
++
++extern int GC_gcj_kind;
++
++GC_PTR GC_local_gcj_malloc(size_t bytes,
++ void * ptr_to_struct_containing_descr)
++{
++ GC_ASSERT(GC_gcj_malloc_initialized);
++ if (EXPECT(!SMALL_ENOUGH(bytes), 0)) {
++ return GC_gcj_malloc(bytes, ptr_to_struct_containing_descr);
++ } else {
++ int index = INDEX_FROM_BYTES(bytes);
++ ptr_t * my_fl = ((GC_thread)GC_getspecific(GC_thread_key))
++ -> gcj_freelists + index;
++ ptr_t my_entry = *my_fl;
++ if (EXPECT((word)my_entry >= HBLKSIZE, 1)) {
++ GC_PTR result = (GC_PTR)my_entry;
++ GC_ASSERT(!GC_incremental);
++ /* We assert that any concurrent marker will stop us. */
++ /* Thus it is impossible for a mark procedure to see the */
++ /* allocation of the next object, but to see this object */
++ /* still containing a free list pointer. Otherwise the */
++ /* marker might find a random "mark descriptor". */
++ *(volatile ptr_t *)my_fl = obj_link(my_entry);
++ /* We must update the freelist before we store the pointer. */
++ /* Otherwise a GC at this point would see a corrupted */
++ /* free list. */
++ /* A memory barrier is probably never needed, since the */
++ /* action of stopping this thread will cause prior writes */
++ /* to complete. */
++ GC_ASSERT(((void * volatile *)result)[1] == 0);
++ *(void * volatile *)result = ptr_to_struct_containing_descr;
++ return result;
++ } else if ((word)my_entry - 1 < DIRECT_GRANULES) {
++ if (!GC_incremental) *my_fl = my_entry + index + 1;
++ /* In the incremental case, we always have to take this */
++ /* path. Thus we leave the counter alone. */
++ return GC_gcj_malloc(bytes, ptr_to_struct_containing_descr);
++ } else {
++ GC_generic_malloc_many(BYTES_FROM_INDEX(index), GC_gcj_kind, my_fl);
++ if (*my_fl == 0) return GC_oom_fn(bytes);
++ return GC_local_gcj_malloc(bytes, ptr_to_struct_containing_descr);
++ }
++ }
++}
++
++#endif /* GC_GCJ_SUPPORT */
++
++# else /* !THREAD_LOCAL_ALLOC && !DBG_HDRS_ALL */
++
++# define GC_destroy_thread_local(t)
++
++# endif /* !THREAD_LOCAL_ALLOC */
++
++#if 0
++/*
++To make sure that we're using LinuxThreads and not some other thread
++package, we generate a dummy reference to `pthread_kill_other_threads_np'
++(was `__pthread_initial_thread_bos' but that disappeared),
++which is a symbol defined in LinuxThreads, but (hopefully) not in other
++thread packages.
++
++We no longer do this, since this code is now portable enough that it might
++actually work for something else.
++*/
++void (*dummy_var_to_force_linux_threads)() = pthread_kill_other_threads_np;
++#endif /* 0 */
++
++#if defined(SPARC) || defined(IA64)
++ extern word GC_save_regs_in_stack();
++#endif
++
++long GC_nprocs = 1; /* Number of processors. We may not have */
++ /* access to all of them, but this is as good */
++ /* a guess as any ... */
++
++#ifdef PARALLEL_MARK
++
++# ifndef MAX_MARKERS
++# define MAX_MARKERS 16
++# endif
++
++static ptr_t marker_sp[MAX_MARKERS] = {0};
++
++void * GC_mark_thread(void * id)
++{
++ word my_mark_no = 0;
++
++ marker_sp[(word)id] = GC_approx_sp();
++ for (;; ++my_mark_no) {
++ /* GC_mark_no is passed only to allow GC_help_marker to terminate */
++ /* promptly. This is important if it were called from the signal */
++ /* handler or from the GC lock acquisition code. Under Linux, it's */
++ /* not safe to call it from a signal handler, since it uses mutexes */
++ /* and condition variables. Since it is called only here, the */
++ /* argument is unnecessary. */
++ if (my_mark_no < GC_mark_no || my_mark_no > GC_mark_no + 2) {
++ /* resynchronize if we get far off, e.g. because GC_mark_no */
++ /* wrapped. */
++ my_mark_no = GC_mark_no;
++ }
++# ifdef DEBUG_THREADS
++ GC_printf1("Starting mark helper for mark number %ld\n", my_mark_no);
++# endif
++ GC_help_marker(my_mark_no);
++ }
++}
++
++extern long GC_markers; /* Number of mark threads we would */
++ /* like to have. Includes the */
++ /* initiating thread. */
++
++pthread_t GC_mark_threads[MAX_MARKERS];
++
++#define PTHREAD_CREATE REAL_FUNC(pthread_create)
++
++static void start_mark_threads()
++{
++ unsigned i;
++ pthread_attr_t attr;
++
++ if (GC_markers > MAX_MARKERS) {
++ WARN("Limiting number of mark threads\n", 0);
++ GC_markers = MAX_MARKERS;
++ }
++ if (0 != pthread_attr_init(&attr)) ABORT("pthread_attr_init failed");
++
++ if (0 != pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED))
++ ABORT("pthread_attr_setdetachstate failed");
++
++# if defined(HPUX) || defined(GC_DGUX386_THREADS)
++ /* Default stack size is usually too small: fix it. */
++ /* Otherwise marker threads or GC may run out of */
++ /* space. */
++# define MIN_STACK_SIZE (8*HBLKSIZE*sizeof(word))
++ {
++ size_t old_size;
++ int code;
++
++ if (pthread_attr_getstacksize(&attr, &old_size) != 0)
++ ABORT("pthread_attr_getstacksize failed\n");
++ if (old_size < MIN_STACK_SIZE) {
++ if (pthread_attr_setstacksize(&attr, MIN_STACK_SIZE) != 0)
++ ABORT("pthread_attr_setstacksize failed\n");
++ }
++ }
++# endif /* HPUX || GC_DGUX386_THREADS */
++# ifdef CONDPRINT
++ if (GC_print_stats) {
++ GC_printf1("Starting %ld marker threads\n", GC_markers - 1);
++ }
++# endif
++ for (i = 0; i < GC_markers - 1; ++i) {
++ if (0 != PTHREAD_CREATE(GC_mark_threads + i, &attr,
++ GC_mark_thread, (void *)(word)i)) {
++ WARN("Marker thread creation failed, errno = %ld.\n", errno);
++ }
++ }
++}
++
++#else /* !PARALLEL_MARK */
++
++static __inline__ void start_mark_threads()
++{
++}
++
++#endif /* !PARALLEL_MARK */
++
++/* Defining INSTALL_LOOPING_SEGV_HANDLER causes SIGSEGV and SIGBUS to */
++/* result in an infinite loop in a signal handler. This can be very */
++/* useful for debugging, since (as of RH7) gdb still seems to have */
++/* serious problems with threads. */
++#ifdef INSTALL_LOOPING_SEGV_HANDLER
++void GC_looping_handler(int sig)
++{
++ GC_printf3("Signal %ld in thread %lx, pid %ld\n",
++ sig, pthread_self(), getpid());
++ for (;;);
++}
++#endif
++
++GC_bool GC_thr_initialized = FALSE;
++
++volatile GC_thread GC_threads[THREAD_TABLE_SZ];
++
++void GC_push_thread_structures GC_PROTO((void))
++{
++ GC_push_all((ptr_t)(GC_threads), (ptr_t)(GC_threads)+sizeof(GC_threads));
++# if defined(THREAD_LOCAL_ALLOC) && !defined(DBG_HDRS_ALL)
++ GC_push_all((ptr_t)(&GC_thread_key),
++ (ptr_t)(&GC_thread_key)+sizeof(&GC_thread_key));
++# endif
++}
++
++#ifdef THREAD_LOCAL_ALLOC
++/* We must explicitly mark ptrfree and gcj free lists, since the free */
++/* list links wouldn't otherwise be found. We also set them in the */
++/* normal free lists, since that involves touching less memory than if */
++/* we scanned them normally. */
++void GC_mark_thread_local_free_lists(void)
++{
++ int i, j;
++ GC_thread p;
++ ptr_t q;
++
++ for (i = 0; i < THREAD_TABLE_SZ; ++i) {
++ for (p = GC_threads[i]; 0 != p; p = p -> next) {
++ for (j = 1; j < NFREELISTS; ++j) {
++ q = p -> ptrfree_freelists[j];
++ if ((word)q > HBLKSIZE) GC_set_fl_marks(q);
++ q = p -> normal_freelists[j];
++ if ((word)q > HBLKSIZE) GC_set_fl_marks(q);
++# ifdef GC_GCJ_SUPPORT
++ q = p -> gcj_freelists[j];
++ if ((word)q > HBLKSIZE) GC_set_fl_marks(q);
++# endif /* GC_GCJ_SUPPORT */
++ }
++ }
++ }
++}
++#endif /* THREAD_LOCAL_ALLOC */
++
++static struct GC_Thread_Rep first_thread;
++
++/* Add a thread to GC_threads. We assume it wasn't already there. */
++/* Caller holds allocation lock. */
++GC_thread GC_new_thread(pthread_t id)
++{
++ int hv = ((word)id) % THREAD_TABLE_SZ;
++ GC_thread result;
++ static GC_bool first_thread_used = FALSE;
++
++ if (!first_thread_used) {
++ result = &first_thread;
++ first_thread_used = TRUE;
++ } else {
++ result = (struct GC_Thread_Rep *)
++ GC_INTERNAL_MALLOC(sizeof(struct GC_Thread_Rep), NORMAL);
++ }
++ if (result == 0) return(0);
++ result -> id = id;
++ result -> next = GC_threads[hv];
++ GC_threads[hv] = result;
++ GC_ASSERT(result -> flags == 0 && result -> thread_blocked == 0);
++ return(result);
++}
++
++/* Delete a thread from GC_threads. We assume it is there. */
++/* (The code intentionally traps if it wasn't.) */
++/* Caller holds allocation lock. */
++void GC_delete_thread(pthread_t id)
++{
++ int hv = ((word)id) % THREAD_TABLE_SZ;
++ register GC_thread p = GC_threads[hv];
++ register GC_thread prev = 0;
++
++ while (!pthread_equal(p -> id, id)) {
++ prev = p;
++ p = p -> next;
++ }
++ if (prev == 0) {
++ GC_threads[hv] = p -> next;
++ } else {
++ prev -> next = p -> next;
++ }
++ GC_INTERNAL_FREE(p);
++}
++
++/* If a thread has been joined, but we have not yet */
++/* been notified, then there may be more than one thread */
++/* in the table with the same pthread id. */
++/* This is OK, but we need a way to delete a specific one. */
++void GC_delete_gc_thread(pthread_t id, GC_thread gc_id)
++{
++ int hv = ((word)id) % THREAD_TABLE_SZ;
++ register GC_thread p = GC_threads[hv];
++ register GC_thread prev = 0;
++
++ while (p != gc_id) {
++ prev = p;
++ p = p -> next;
++ }
++ if (prev == 0) {
++ GC_threads[hv] = p -> next;
++ } else {
++ prev -> next = p -> next;
++ }
++ GC_INTERNAL_FREE(p);
++}
++
++/* Return a GC_thread corresponding to a given thread_t. */
++/* Returns 0 if it's not there. */
++/* Caller holds allocation lock or otherwise inhibits */
++/* updates. */
++/* If there is more than one thread with the given id we */
++/* return the most recent one. */
++GC_thread GC_lookup_thread(pthread_t id)
++{
++ int hv = ((word)id) % THREAD_TABLE_SZ;
++ register GC_thread p = GC_threads[hv];
++
++ while (p != 0 && !pthread_equal(p -> id, id)) p = p -> next;
++ return(p);
++}
++
++#ifdef HANDLE_FORK
++/* Remove all entries from the GC_threads table, except the */
++/* one for the current thread. We need to do this in the child */
++/* process after a fork(), since only the current thread */
++/* survives in the child. */
++void GC_remove_all_threads_but_me(void)
++{
++ pthread_t self = pthread_self();
++ int hv;
++ GC_thread p, next, me;
++
++ for (hv = 0; hv < THREAD_TABLE_SZ; ++hv) {
++ me = 0;
++ for (p = GC_threads[hv]; 0 != p; p = next) {
++ next = p -> next;
++ if (p -> id == self) {
++ me = p;
++ p -> next = 0;
++ } else {
++# ifdef THREAD_LOCAL_ALLOC
++ if (!(p -> flags & FINISHED)) {
++ GC_destroy_thread_local(p);
++ }
++# endif /* THREAD_LOCAL_ALLOC */
++ if (p != &first_thread) GC_INTERNAL_FREE(p);
++ }
++ }
++ GC_threads[hv] = me;
++ }
++}
++#endif /* HANDLE_FORK */
++
++#ifdef USE_PROC_FOR_LIBRARIES
++int GC_segment_is_thread_stack(ptr_t lo, ptr_t hi)
++{
++ int i;
++ GC_thread p;
++
++# ifdef PARALLEL_MARK
++ for (i = 0; i < GC_markers; ++i) {
++ if (marker_sp[i] > lo & marker_sp[i] < hi) return 1;
++ }
++# endif
++ for (i = 0; i < THREAD_TABLE_SZ; i++) {
++ for (p = GC_threads[i]; p != 0; p = p -> next) {
++ if (0 != p -> stack_end) {
++# ifdef STACK_GROWS_UP
++ if (p -> stack_end >= lo && p -> stack_end < hi) return 1;
++# else /* STACK_GROWS_DOWN */
++ if (p -> stack_end > lo && p -> stack_end <= hi) return 1;
++# endif
++ }
++ }
++ }
++ return 0;
++}
++#endif /* USE_PROC_FOR_LIBRARIES */
++
++#ifdef GC_LINUX_THREADS
++/* Return the number of processors, or i<= 0 if it can't be determined. */
++int GC_get_nprocs()
++{
++ /* Should be "return sysconf(_SC_NPROCESSORS_ONLN);" but that */
++ /* appears to be buggy in many cases. */
++ /* We look for lines "cpu<n>" in /proc/stat. */
++# define STAT_BUF_SIZE 4096
++# define STAT_READ read
++ /* If read is wrapped, this may need to be redefined to call */
++ /* the real one. */
++ char stat_buf[STAT_BUF_SIZE];
++ int f;
++ word result = 1;
++ /* Some old kernels only have a single "cpu nnnn ..." */
++ /* entry in /proc/stat. We identify those as */
++ /* uniprocessors. */
++ size_t i, len = 0;
++
++ f = open("/proc/stat", O_RDONLY);
++ if (f < 0 || (len = STAT_READ(f, stat_buf, STAT_BUF_SIZE)) < 100) {
++ WARN("Couldn't read /proc/stat\n", 0);
++ return -1;
++ }
++ for (i = 0; i < len - 100; ++i) {
++ if (stat_buf[i] == '\n' && stat_buf[i+1] == 'c'
++ && stat_buf[i+2] == 'p' && stat_buf[i+3] == 'u') {
++ int cpu_no = atoi(stat_buf + i + 4);
++ if (cpu_no >= result) result = cpu_no + 1;
++ }
++ }
++ close(f);
++ return result;
++}
++#endif /* GC_LINUX_THREADS */
++
++/* We hold the GC lock. Wait until an in-progress GC has finished. */
++/* Repeatedly RELEASES GC LOCK in order to wait. */
++/* If wait_for_all is true, then we exit with the GC lock held and no */
++/* collection in progress; otherwise we just wait for the current GC */
++/* to finish. */
++extern GC_bool GC_collection_in_progress();
++void GC_wait_for_gc_completion(GC_bool wait_for_all)
++{
++ if (GC_incremental && GC_collection_in_progress()) {
++ int old_gc_no = GC_gc_no;
++
++ /* Make sure that no part of our stack is still on the mark stack, */
++ /* since it's about to be unmapped. */
++ while (GC_incremental && GC_collection_in_progress()
++ && (wait_for_all || old_gc_no == GC_gc_no)) {
++ ENTER_GC();
++ GC_collect_a_little_inner(1);
++ EXIT_GC();
++ UNLOCK();
++ sched_yield();
++ LOCK();
++ }
++ }
++}
++
++#ifdef HANDLE_FORK
++/* Procedures called before and after a fork. The goal here is to make */
++/* it safe to call GC_malloc() in a forked child. It's unclear that is */
++/* attainable, since the single UNIX spec seems to imply that one */
++/* should only call async-signal-safe functions, and we probably can't */
++/* quite guarantee that. But we give it our best shot. (That same */
++/* spec also implies that it's not safe to call the system malloc */
++/* between fork() and exec(). Thus we're doing no worse than it. */
++
++/* Called before a fork() */
++void GC_fork_prepare_proc(void)
++{
++ /* Acquire all relevant locks, so that after releasing the locks */
++ /* the child will see a consistent state in which monitor */
++ /* invariants hold. Unfortunately, we can't acquire libc locks */
++ /* we might need, and there seems to be no guarantee that libc */
++ /* must install a suitable fork handler. */
++ /* Wait for an ongoing GC to finish, since we can't finish it in */
++ /* the (one remaining thread in) the child. */
++ LOCK();
++# if defined(PARALLEL_MARK) || defined(THREAD_LOCAL_ALLOC)
++ GC_wait_for_reclaim();
++# endif
++ GC_wait_for_gc_completion(TRUE);
++# if defined(PARALLEL_MARK) || defined(THREAD_LOCAL_ALLOC)
++ GC_acquire_mark_lock();
++# endif
++}
++
++/* Called in parent after a fork() */
++void GC_fork_parent_proc(void)
++{
++# if defined(PARALLEL_MARK) || defined(THREAD_LOCAL_ALLOC)
++ GC_release_mark_lock();
++# endif
++ UNLOCK();
++}
++
++/* Called in child after a fork() */
++void GC_fork_child_proc(void)
++{
++ /* Clean up the thread table, so that just our thread is left. */
++# if defined(PARALLEL_MARK) || defined(THREAD_LOCAL_ALLOC)
++ GC_release_mark_lock();
++# endif
++ GC_remove_all_threads_but_me();
++# ifdef PARALLEL_MARK
++ /* Turn off parallel marking in the child, since we are probably */
++ /* just going to exec, and we would have to restart mark threads. */
++ GC_markers = 1;
++ GC_parallel = FALSE;
++# endif /* PARALLEL_MARK */
++ UNLOCK();
++}
++#endif /* HANDLE_FORK */
++
++#if defined(GC_DGUX386_THREADS)
++/* Return the number of processors, or i<= 0 if it can't be determined. */
++int GC_get_nprocs()
++{
++ /* <takis@XFree86.Org> */
++ int numCpus;
++ struct dg_sys_info_pm_info pm_sysinfo;
++ int status =0;
++
++ status = dg_sys_info((long int *) &pm_sysinfo,
++ DG_SYS_INFO_PM_INFO_TYPE, DG_SYS_INFO_PM_CURRENT_VERSION);
++ if (status < 0)
++ /* set -1 for error */
++ numCpus = -1;
++ else
++ /* Active CPUs */
++ numCpus = pm_sysinfo.idle_vp_count;
++
++# ifdef DEBUG_THREADS
++ GC_printf1("Number of active CPUs in this system: %d\n", numCpus);
++# endif
++ return(numCpus);
++}
++#endif /* GC_DGUX386_THREADS */
++
++/* We hold the allocation lock. */
++void GC_thr_init()
++{
++# ifndef GC_DARWIN_THREADS
++ int dummy;
++# endif
++ GC_thread t;
++
++ if (GC_thr_initialized) return;
++ GC_thr_initialized = TRUE;
++
++# ifdef HANDLE_FORK
++ /* Prepare for a possible fork. */
++ pthread_atfork(GC_fork_prepare_proc, GC_fork_parent_proc,
++ GC_fork_child_proc);
++# endif /* HANDLE_FORK */
++ /* Add the initial thread, so we can stop it. */
++ t = GC_new_thread(pthread_self());
++# ifdef GC_DARWIN_THREADS
++ t -> stop_info.mach_thread = mach_thread_self();
++# else
++ t -> stop_info.stack_ptr = (ptr_t)(&dummy);
++# endif
++ t -> flags = DETACHED | MAIN_THREAD;
++
++ GC_stop_init();
++
++ /* Set GC_nprocs. */
++ {
++ char * nprocs_string = GETENV("GC_NPROCS");
++ GC_nprocs = -1;
++ if (nprocs_string != NULL) GC_nprocs = atoi(nprocs_string);
++ }
++ if (GC_nprocs <= 0) {
++# if defined(GC_HPUX_THREADS)
++ GC_nprocs = pthread_num_processors_np();
++# endif
++# if defined(GC_OSF1_THREADS)
++ GC_nprocs = sysconf(_SC_NPROCESSORS_ONLN);
++ if (GC_nprocs <= 0) GC_nprocs = 1;
++# endif
++# if defined(GC_FREEBSD_THREADS)
++ GC_nprocs = 1;
++# endif
++# if defined(GC_DARWIN_THREADS)
++ int ncpus = 1;
++ size_t len = sizeof(ncpus);
++ sysctl((int[2]) {CTL_HW, HW_NCPU}, 2, &ncpus, &len, NULL, 0);
++ GC_nprocs = ncpus;
++# endif
++# if defined(GC_LINUX_THREADS) || defined(GC_DGUX386_THREADS)
++ GC_nprocs = GC_get_nprocs();
++# endif
++ }
++ if (GC_nprocs <= 0) {
++ WARN("GC_get_nprocs() returned %ld\n", GC_nprocs);
++ GC_nprocs = 2;
++# ifdef PARALLEL_MARK
++ GC_markers = 1;
++# endif
++ } else {
++# ifdef PARALLEL_MARK
++ {
++ char * markers_string = GETENV("GC_MARKERS");
++ if (markers_string != NULL) {
++ GC_markers = atoi(markers_string);
++ } else {
++ GC_markers = GC_nprocs;
++ }
++ }
++# endif
++ }
++# ifdef PARALLEL_MARK
++# ifdef CONDPRINT
++ if (GC_print_stats) {
++ GC_printf2("Number of processors = %ld, "
++ "number of marker threads = %ld\n", GC_nprocs, GC_markers);
++ }
++# endif
++ if (GC_markers == 1) {
++ GC_parallel = FALSE;
++# ifdef CONDPRINT
++ if (GC_print_stats) {
++ GC_printf0("Single marker thread, turning off parallel marking\n");
++ }
++# endif
++ } else {
++ GC_parallel = TRUE;
++ /* Disable true incremental collection, but generational is OK. */
++ GC_time_limit = GC_TIME_UNLIMITED;
++ }
++# endif
++}
++
++
++/* Perform all initializations, including those that */
++/* may require allocation. */
++/* Called without allocation lock. */
++/* Must be called before a second thread is created. */
++/* Called without allocation lock. */
++void GC_init_parallel()
++{
++ if (parallel_initialized) return;
++ parallel_initialized = TRUE;
++
++ /* GC_init() calls us back, so set flag first. */
++ if (!GC_is_initialized) GC_init();
++ /* If we are using a parallel marker, start the helper threads. */
++# ifdef PARALLEL_MARK
++ if (GC_parallel) start_mark_threads();
++# endif
++ /* Initialize thread local free lists if used. */
++# if defined(THREAD_LOCAL_ALLOC) && !defined(DBG_HDRS_ALL)
++ LOCK();
++ GC_init_thread_local(GC_lookup_thread(pthread_self()));
++ UNLOCK();
++# endif
++}
++
++
++#if !defined(GC_DARWIN_THREADS)
++int WRAP_FUNC(pthread_sigmask)(int how, const sigset_t *set, sigset_t *oset)
++{
++ sigset_t fudged_set;
++
++ if (set != NULL && (how == SIG_BLOCK || how == SIG_SETMASK)) {
++ fudged_set = *set;
++ sigdelset(&fudged_set, SIG_SUSPEND);
++ set = &fudged_set;
++ }
++ return(REAL_FUNC(pthread_sigmask)(how, set, oset));
++}
++#endif /* !GC_DARWIN_THREADS */
++
++/* Wrappers for functions that are likely to block for an appreciable */
++/* length of time. Must be called in pairs, if at all. */
++/* Nothing much beyond the system call itself should be executed */
++/* between these. */
++
++void GC_start_blocking(void) {
++# define SP_SLOP 128
++ GC_thread me;
++ LOCK();
++ me = GC_lookup_thread(pthread_self());
++ GC_ASSERT(!(me -> thread_blocked));
++# ifdef SPARC
++ me -> stop_info.stack_ptr = (ptr_t)GC_save_regs_in_stack();
++# else
++# ifndef GC_DARWIN_THREADS
++ me -> stop_info.stack_ptr = (ptr_t)GC_approx_sp();
++# endif
++# endif
++# ifdef IA64
++ me -> backing_store_ptr = (ptr_t)GC_save_regs_in_stack() + SP_SLOP;
++# endif
++ /* Add some slop to the stack pointer, since the wrapped call may */
++ /* end up pushing more callee-save registers. */
++# ifndef GC_DARWIN_THREADS
++# ifdef STACK_GROWS_UP
++ me -> stop_info.stack_ptr += SP_SLOP;
++# else
++ me -> stop_info.stack_ptr -= SP_SLOP;
++# endif
++# endif
++ me -> thread_blocked = TRUE;
++ UNLOCK();
++}
++
++void GC_end_blocking(void) {
++ GC_thread me;
++ LOCK(); /* This will block if the world is stopped. */
++ me = GC_lookup_thread(pthread_self());
++ GC_ASSERT(me -> thread_blocked);
++ me -> thread_blocked = FALSE;
++ UNLOCK();
++}
++
++#if defined(GC_DGUX386_THREADS)
++#define __d10_sleep sleep
++#endif /* GC_DGUX386_THREADS */
++
++/* A wrapper for the standard C sleep function */
++int WRAP_FUNC(sleep) (unsigned int seconds)
++{
++ int result;
++
++ GC_start_blocking();
++ result = REAL_FUNC(sleep)(seconds);
++ GC_end_blocking();
++ return result;
++}
++
++struct start_info {
++ void *(*start_routine)(void *);
++ void *arg;
++ word flags;
++ sem_t registered; /* 1 ==> in our thread table, but */
++ /* parent hasn't yet noticed. */
++};
++
++/* Called at thread exit. */
++/* Never called for main thread. That's OK, since it */
++/* results in at most a tiny one-time leak. And */
++/* linuxthreads doesn't reclaim the main threads */
++/* resources or id anyway. */
++void GC_thread_exit_proc(void *arg)
++{
++ GC_thread me;
++
++ LOCK();
++ me = GC_lookup_thread(pthread_self());
++ GC_destroy_thread_local(me);
++ if (me -> flags & DETACHED) {
++ GC_delete_thread(pthread_self());
++ } else {
++ me -> flags |= FINISHED;
++ }
++# if defined(THREAD_LOCAL_ALLOC) && !defined(USE_PTHREAD_SPECIFIC) \
++ && !defined(USE_HPUX_TLS) && !defined(DBG_HDRS_ALL)
++ GC_remove_specific(GC_thread_key);
++# endif
++ GC_wait_for_gc_completion(FALSE);
++ UNLOCK();
++}
++
++int WRAP_FUNC(pthread_join)(pthread_t thread, void **retval)
++{
++ int result;
++ GC_thread thread_gc_id;
++
++ LOCK();
++ thread_gc_id = GC_lookup_thread(thread);
++ /* This is guaranteed to be the intended one, since the thread id */
++ /* cant have been recycled by pthreads. */
++ UNLOCK();
++ result = REAL_FUNC(pthread_join)(thread, retval);
++# if defined (GC_FREEBSD_THREADS)
++ /* On FreeBSD, the wrapped pthread_join() sometimes returns (what
++ appears to be) a spurious EINTR which caused the test and real code
++ to gratuitously fail. Having looked at system pthread library source
++ code, I see how this return code may be generated. In one path of
++ code, pthread_join() just returns the errno setting of the thread
++ being joined. This does not match the POSIX specification or the
++ local man pages thus I have taken the liberty to catch this one
++ spurious return value properly conditionalized on GC_FREEBSD_THREADS. */
++ if (result == EINTR) result = 0;
++# endif
++ if (result == 0) {
++ LOCK();
++ /* Here the pthread thread id may have been recycled. */
++ GC_delete_gc_thread(thread, thread_gc_id);
++ UNLOCK();
++ }
++ return result;
++}
++
++int
++WRAP_FUNC(pthread_detach)(pthread_t thread)
++{
++ int result;
++ GC_thread thread_gc_id;
++
++ LOCK();
++ thread_gc_id = GC_lookup_thread(thread);
++ UNLOCK();
++ result = REAL_FUNC(pthread_detach)(thread);
++ if (result == 0) {
++ LOCK();
++ thread_gc_id -> flags |= DETACHED;
++ /* Here the pthread thread id may have been recycled. */
++ if (thread_gc_id -> flags & FINISHED) {
++ GC_delete_gc_thread(thread, thread_gc_id);
++ }
++ UNLOCK();
++ }
++ return result;
++}
++
++void * GC_start_routine(void * arg)
++{
++ int dummy;
++ struct start_info * si = arg;
++ void * result;
++ GC_thread me;
++ pthread_t my_pthread;
++ void *(*start)(void *);
++ void *start_arg;
++
++ my_pthread = pthread_self();
++# ifdef DEBUG_THREADS
++ GC_printf1("Starting thread 0x%lx\n", my_pthread);
++ GC_printf1("pid = %ld\n", (long) getpid());
++ GC_printf1("sp = 0x%lx\n", (long) &arg);
++# endif
++ LOCK();
++ me = GC_new_thread(my_pthread);
++#ifdef GC_DARWIN_THREADS
++ me -> stop_info.mach_thread = mach_thread_self();
++#else
++ me -> stop_info.stack_ptr = 0;
++#endif
++ me -> flags = si -> flags;
++ /* me -> stack_end = GC_linux_stack_base(); -- currently (11/99) */
++ /* doesn't work because the stack base in /proc/self/stat is the */
++ /* one for the main thread. There is a strong argument that that's */
++ /* a kernel bug, but a pervasive one. */
++# ifdef STACK_GROWS_DOWN
++ me -> stack_end = (ptr_t)(((word)(&dummy) + (GC_page_size - 1))
++ & ~(GC_page_size - 1));
++# ifndef GC_DARWIN_THREADS
++ me -> stop_info.stack_ptr = me -> stack_end - 0x10;
++# endif
++ /* Needs to be plausible, since an asynchronous stack mark */
++ /* should not crash. */
++# else
++ me -> stack_end = (ptr_t)((word)(&dummy) & ~(GC_page_size - 1));
++ me -> stop_info.stack_ptr = me -> stack_end + 0x10;
++# endif
++ /* This is dubious, since we may be more than a page into the stack, */
++ /* and hence skip some of it, though it's not clear that matters. */
++# ifdef IA64
++ me -> backing_store_end = (ptr_t)
++ (GC_save_regs_in_stack() & ~(GC_page_size - 1));
++ /* This is also < 100% convincing. We should also read this */
++ /* from /proc, but the hook to do so isn't there yet. */
++# endif /* IA64 */
++ UNLOCK();
++ start = si -> start_routine;
++# ifdef DEBUG_THREADS
++ GC_printf1("start_routine = 0x%lx\n", start);
++# endif
++ start_arg = si -> arg;
++ sem_post(&(si -> registered)); /* Last action on si. */
++ /* OK to deallocate. */
++ pthread_cleanup_push(GC_thread_exit_proc, 0);
++# if defined(THREAD_LOCAL_ALLOC) && !defined(DBG_HDRS_ALL)
++ LOCK();
++ GC_init_thread_local(me);
++ UNLOCK();
++# endif
++ result = (*start)(start_arg);
++#if DEBUG_THREADS
++ GC_printf1("Finishing thread 0x%x\n", pthread_self());
++#endif
++ me -> status = result;
++ me -> flags |= FINISHED;
++ pthread_cleanup_pop(1);
++ /* Cleanup acquires lock, ensuring that we can't exit */
++ /* while a collection that thinks we're alive is trying to stop */
++ /* us. */
++ return(result);
++}
++
++int
++WRAP_FUNC(pthread_create)(pthread_t *new_thread,
++ const pthread_attr_t *attr,
++ void *(*start_routine)(void *), void *arg)
++{
++ int result;
++ int detachstate;
++ word my_flags = 0;
++ struct start_info * si;
++ /* This is otherwise saved only in an area mmapped by the thread */
++ /* library, which isn't visible to the collector. */
++
++ /* We resist the temptation to muck with the stack size here, */
++ /* even if the default is unreasonably small. That's the client's */
++ /* responsibility. */
++
++ LOCK();
++ si = (struct start_info *)GC_INTERNAL_MALLOC(sizeof(struct start_info),
++ NORMAL);
++ UNLOCK();
++ if (!parallel_initialized) GC_init_parallel();
++ if (0 == si) return(ENOMEM);
++ sem_init(&(si -> registered), 0, 0);
++ si -> start_routine = start_routine;
++ si -> arg = arg;
++ LOCK();
++ if (!GC_thr_initialized) GC_thr_init();
++# ifdef GC_ASSERTIONS
++ {
++ int stack_size;
++ if (NULL == attr) {
++ pthread_attr_t my_attr;
++ pthread_attr_init(&my_attr);
++ pthread_attr_getstacksize(&my_attr, &stack_size);
++ } else {
++ pthread_attr_getstacksize(attr, &stack_size);
++ }
++ GC_ASSERT(stack_size >= (8*HBLKSIZE*sizeof(word)));
++ /* Our threads may need to do some work for the GC. */
++ /* Ridiculously small threads won't work, and they */
++ /* probably wouldn't work anyway. */
++ }
++# endif
++ if (NULL == attr) {
++ detachstate = PTHREAD_CREATE_JOINABLE;
++ } else {
++ pthread_attr_getdetachstate(attr, &detachstate);
++ }
++ if (PTHREAD_CREATE_DETACHED == detachstate) my_flags |= DETACHED;
++ si -> flags = my_flags;
++ UNLOCK();
++# ifdef DEBUG_THREADS
++ GC_printf1("About to start new thread from thread 0x%X\n",
++ pthread_self());
++# endif
++
++ result = REAL_FUNC(pthread_create)(new_thread, attr, GC_start_routine, si);
++
++# ifdef DEBUG_THREADS
++ GC_printf1("Started thread 0x%X\n", *new_thread);
++# endif
++ /* Wait until child has been added to the thread table. */
++ /* This also ensures that we hold onto si until the child is done */
++ /* with it. Thus it doesn't matter whether it is otherwise */
++ /* visible to the collector. */
++ while (0 != sem_wait(&(si -> registered))) {
++ if (EINTR != errno) ABORT("sem_wait failed");
++ }
++ sem_destroy(&(si -> registered));
++ LOCK();
++ GC_INTERNAL_FREE(si);
++ UNLOCK();
++
++ return(result);
++}
++
++#ifdef GENERIC_COMPARE_AND_SWAP
++ pthread_mutex_t GC_compare_and_swap_lock = PTHREAD_MUTEX_INITIALIZER;
++
++ GC_bool GC_compare_and_exchange(volatile GC_word *addr,
++ GC_word old, GC_word new_val)
++ {
++ GC_bool result;
++ pthread_mutex_lock(&GC_compare_and_swap_lock);
++ if (*addr == old) {
++ *addr = new_val;
++ result = TRUE;
++ } else {
++ result = FALSE;
++ }
++ pthread_mutex_unlock(&GC_compare_and_swap_lock);
++ return result;
++ }
++
++ GC_word GC_atomic_add(volatile GC_word *addr, GC_word how_much)
++ {
++ GC_word old;
++ pthread_mutex_lock(&GC_compare_and_swap_lock);
++ old = *addr;
++ *addr = old + how_much;
++ pthread_mutex_unlock(&GC_compare_and_swap_lock);
++ return old;
++ }
++
++#endif /* GENERIC_COMPARE_AND_SWAP */
++/* Spend a few cycles in a way that can't introduce contention with */
++/* othre threads. */
++void GC_pause()
++{
++ int i;
++# ifndef __GNUC__
++ volatile word dummy = 0;
++# endif
++
++ for (i = 0; i < 10; ++i) {
++# ifdef __GNUC__
++ __asm__ __volatile__ (" " : : : "memory");
++# else
++ /* Something that's unlikely to be optimized away. */
++ GC_noop(++dummy);
++# endif
++ }
++}
++
++#define SPIN_MAX 1024 /* Maximum number of calls to GC_pause before */
++ /* give up. */
++
++VOLATILE GC_bool GC_collecting = 0;
++ /* A hint that we're in the collector and */
++ /* holding the allocation lock for an */
++ /* extended period. */
++
++#if !defined(USE_SPIN_LOCK) || defined(PARALLEL_MARK)
++/* If we don't want to use the below spinlock implementation, either */
++/* because we don't have a GC_test_and_set implementation, or because */
++/* we don't want to risk sleeping, we can still try spinning on */
++/* pthread_mutex_trylock for a while. This appears to be very */
++/* beneficial in many cases. */
++/* I suspect that under high contention this is nearly always better */
++/* than the spin lock. But it's a bit slower on a uniprocessor. */
++/* Hence we still default to the spin lock. */
++/* This is also used to acquire the mark lock for the parallel */
++/* marker. */
++
++/* Here we use a strict exponential backoff scheme. I don't know */
++/* whether that's better or worse than the above. We eventually */
++/* yield by calling pthread_mutex_lock(); it never makes sense to */
++/* explicitly sleep. */
++
++void GC_generic_lock(pthread_mutex_t * lock)
++{
++#ifndef NO_PTHREAD_TRYLOCK
++ unsigned pause_length = 1;
++ unsigned i;
++
++ if (0 == pthread_mutex_trylock(lock)) return;
++ for (; pause_length <= SPIN_MAX; pause_length <<= 1) {
++ for (i = 0; i < pause_length; ++i) {
++ GC_pause();
++ }
++ switch(pthread_mutex_trylock(lock)) {
++ case 0:
++ return;
++ case EBUSY:
++ break;
++ default:
++ ABORT("Unexpected error from pthread_mutex_trylock");
++ }
++ }
++#endif /* !NO_PTHREAD_TRYLOCK */
++ pthread_mutex_lock(lock);
++}
++
++#endif /* !USE_SPIN_LOCK || PARALLEL_MARK */
++
++#if defined(USE_SPIN_LOCK)
++
++/* Reasonably fast spin locks. Basically the same implementation */
++/* as STL alloc.h. This isn't really the right way to do this. */
++/* but until the POSIX scheduling mess gets straightened out ... */
++
++volatile unsigned int GC_allocate_lock = 0;
++
++
++void GC_lock()
++{
++# define low_spin_max 30 /* spin cycles if we suspect uniprocessor */
++# define high_spin_max SPIN_MAX /* spin cycles for multiprocessor */
++ static unsigned spin_max = low_spin_max;
++ unsigned my_spin_max;
++ static unsigned last_spins = 0;
++ unsigned my_last_spins;
++ int i;
++
++ if (!GC_test_and_set(&GC_allocate_lock)) {
++ return;
++ }
++ my_spin_max = spin_max;
++ my_last_spins = last_spins;
++ for (i = 0; i < my_spin_max; i++) {
++ if (GC_collecting || GC_nprocs == 1) goto yield;
++ if (i < my_last_spins/2 || GC_allocate_lock) {
++ GC_pause();
++ continue;
++ }
++ if (!GC_test_and_set(&GC_allocate_lock)) {
++ /*
++ * got it!
++ * Spinning worked. Thus we're probably not being scheduled
++ * against the other process with which we were contending.
++ * Thus it makes sense to spin longer the next time.
++ */
++ last_spins = i;
++ spin_max = high_spin_max;
++ return;
++ }
++ }
++ /* We are probably being scheduled against the other process. Sleep. */
++ spin_max = low_spin_max;
++yield:
++ for (i = 0;; ++i) {
++ if (!GC_test_and_set(&GC_allocate_lock)) {
++ return;
++ }
++# define SLEEP_THRESHOLD 12
++ /* Under Linux very short sleeps tend to wait until */
++ /* the current time quantum expires. On old Linux */
++ /* kernels nanosleep(<= 2ms) just spins under Linux. */
++ /* (Under 2.4, this happens only for real-time */
++ /* processes.) We want to minimize both behaviors */
++ /* here. */
++ if (i < SLEEP_THRESHOLD) {
++ sched_yield();
++ } else {
++ struct timespec ts;
++
++ if (i > 24) i = 24;
++ /* Don't wait for more than about 15msecs, even */
++ /* under extreme contention. */
++ ts.tv_sec = 0;
++ ts.tv_nsec = 1 << i;
++ nanosleep(&ts, 0);
++ }
++ }
++}
++
++#else /* !USE_SPINLOCK */
++void GC_lock()
++{
++#ifndef NO_PTHREAD_TRYLOCK
++ if (1 == GC_nprocs || GC_collecting) {
++ pthread_mutex_lock(&GC_allocate_ml);
++ } else {
++ GC_generic_lock(&GC_allocate_ml);
++ }
++#else /* !NO_PTHREAD_TRYLOCK */
++ pthread_mutex_lock(&GC_allocate_ml);
++#endif /* !NO_PTHREAD_TRYLOCK */
++}
++
++#endif /* !USE_SPINLOCK */
++
++#if defined(PARALLEL_MARK) || defined(THREAD_LOCAL_ALLOC)
++
++#ifdef GC_ASSERTIONS
++ pthread_t GC_mark_lock_holder = NO_THREAD;
++#endif
++
++#if 0
++ /* Ugly workaround for a linux threads bug in the final versions */
++ /* of glibc2.1. Pthread_mutex_trylock sets the mutex owner */
++ /* field even when it fails to acquire the mutex. This causes */
++ /* pthread_cond_wait to die. Remove for glibc2.2. */
++ /* According to the man page, we should use */
++ /* PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP, but that isn't actually */
++ /* defined. */
++ static pthread_mutex_t mark_mutex =
++ {0, 0, 0, PTHREAD_MUTEX_ERRORCHECK_NP, {0, 0}};
++#else
++ static pthread_mutex_t mark_mutex = PTHREAD_MUTEX_INITIALIZER;
++#endif
++
++static pthread_cond_t builder_cv = PTHREAD_COND_INITIALIZER;
++
++void GC_acquire_mark_lock()
++{
++/*
++ if (pthread_mutex_lock(&mark_mutex) != 0) {
++ ABORT("pthread_mutex_lock failed");
++ }
++*/
++ GC_generic_lock(&mark_mutex);
++# ifdef GC_ASSERTIONS
++ GC_mark_lock_holder = pthread_self();
++# endif
++}
++
++void GC_release_mark_lock()
++{
++ GC_ASSERT(GC_mark_lock_holder == pthread_self());
++# ifdef GC_ASSERTIONS
++ GC_mark_lock_holder = NO_THREAD;
++# endif
++ if (pthread_mutex_unlock(&mark_mutex) != 0) {
++ ABORT("pthread_mutex_unlock failed");
++ }
++}
++
++/* Collector must wait for a freelist builders for 2 reasons: */
++/* 1) Mark bits may still be getting examined without lock. */
++/* 2) Partial free lists referenced only by locals may not be scanned */
++/* correctly, e.g. if they contain "pointer-free" objects, since the */
++/* free-list link may be ignored. */
++void GC_wait_builder()
++{
++ GC_ASSERT(GC_mark_lock_holder == pthread_self());
++# ifdef GC_ASSERTIONS
++ GC_mark_lock_holder = NO_THREAD;
++# endif
++ if (pthread_cond_wait(&builder_cv, &mark_mutex) != 0) {
++ ABORT("pthread_cond_wait failed");
++ }
++ GC_ASSERT(GC_mark_lock_holder == NO_THREAD);
++# ifdef GC_ASSERTIONS
++ GC_mark_lock_holder = pthread_self();
++# endif
++}
++
++void GC_wait_for_reclaim()
++{
++ GC_acquire_mark_lock();
++ while (GC_fl_builder_count > 0) {
++ GC_wait_builder();
++ }
++ GC_release_mark_lock();
++}
++
++void GC_notify_all_builder()
++{
++ GC_ASSERT(GC_mark_lock_holder == pthread_self());
++ if (pthread_cond_broadcast(&builder_cv) != 0) {
++ ABORT("pthread_cond_broadcast failed");
++ }
++}
++
++#endif /* PARALLEL_MARK || THREAD_LOCAL_ALLOC */
++
++#ifdef PARALLEL_MARK
++
++static pthread_cond_t mark_cv = PTHREAD_COND_INITIALIZER;
++
++void GC_wait_marker()
++{
++ GC_ASSERT(GC_mark_lock_holder == pthread_self());
++# ifdef GC_ASSERTIONS
++ GC_mark_lock_holder = NO_THREAD;
++# endif
++ if (pthread_cond_wait(&mark_cv, &mark_mutex) != 0) {
++ ABORT("pthread_cond_wait failed");
++ }
++ GC_ASSERT(GC_mark_lock_holder == NO_THREAD);
++# ifdef GC_ASSERTIONS
++ GC_mark_lock_holder = pthread_self();
++# endif
++}
++
++void GC_notify_all_marker()
++{
++ if (pthread_cond_broadcast(&mark_cv) != 0) {
++ ABORT("pthread_cond_broadcast failed");
++ }
++}
++
++#endif /* PARALLEL_MARK */
++
++# endif /* GC_LINUX_THREADS and friends */
++
+diff -buNr boehm-gc/ptr_chck.c boehm-gc/ptr_chck.c
+--- boehm-gc/ptr_chck.c Fri Aug 17 11:30:46 2001
++++ boehm-gc/ptr_chck.c Sat Sep 13 02:10:15 2003
+@@ -79,7 +79,7 @@
+ return(p);
+ }
+ sz = WORDS_TO_BYTES(hhdr -> hb_sz);
+- if (sz > WORDS_TO_BYTES(MAXOBJSZ)) {
++ if (sz > MAXOBJBYTES) {
+ base = (ptr_t)HBLKPTR(p);
+ limit = base + sz;
+ if ((ptr_t)p >= limit) {
+@@ -165,7 +165,7 @@
+ pdispl = HBLKDISPL(p);
+ map_entry = MAP_ENTRY((hhdr -> hb_map), pdispl);
+ if (map_entry == OBJ_INVALID
+- || sz > MAXOBJSZ && (ptr_t)p >= (ptr_t)h + sz) {
++ || sz > MAXOBJBYTES && (ptr_t)p >= (ptr_t)h + sz) {
+ goto fail;
+ }
+ return(p);
+diff -buNr boehm-gc/reclaim.c boehm-gc/reclaim.c
+--- boehm-gc/reclaim.c Fri Mar 29 14:52:12 2002
++++ boehm-gc/reclaim.c Sat Sep 13 02:10:15 2003
+@@ -27,10 +27,43 @@
+ /* nonzero. */
+ #endif /* PARALLEL_MARK */
+
+-static void report_leak(p, sz)
+-ptr_t p;
+-word sz;
++/* We defer printing of leaked objects until we're done with the GC */
++/* cycle, since the routine for printing objects needs to run outside */
++/* the collector, e.g. without the allocation lock. */
++#define MAX_LEAKED 40
++ptr_t GC_leaked[MAX_LEAKED];
++unsigned GC_n_leaked = 0;
++
++GC_bool GC_have_errors = FALSE;
++
++void GC_add_leaked(leaked)
++ptr_t leaked;
++{
++ if (GC_n_leaked < MAX_LEAKED) {
++ GC_have_errors = TRUE;
++ GC_leaked[GC_n_leaked++] = leaked;
++ /* Make sure it's not reclaimed this cycle */
++ GC_set_mark_bit(leaked);
++ }
++}
++
++static GC_bool printing_errors = FALSE;
++/* Print all objects on the list after printing any smashed objs. */
++/* Clear both lists. */
++void GC_print_all_errors ()
+ {
++ unsigned i;
++
++ LOCK();
++ if (printing_errors) {
++ UNLOCK();
++ return;
++ }
++ printing_errors = TRUE;
++ UNLOCK();
++ if (GC_debugging_started) GC_print_all_smashed();
++ for (i = 0; i < GC_n_leaked; ++i) {
++ ptr_t p = GC_leaked[i];
+ if (HDR(p) -> hb_obj_kind == PTRFREE) {
+ GC_err_printf0("Leaked atomic object at ");
+ } else {
+@@ -38,12 +71,17 @@
+ }
+ GC_print_heap_obj(p);
+ GC_err_printf0("\n");
++ GC_free(p);
++ GC_leaked[i] = 0;
++ }
++ GC_n_leaked = 0;
++ printing_errors = FALSE;
+ }
+
++
+ # define FOUND_FREE(hblk, word_no) \
+ { \
+- report_leak((ptr_t)hblk + WORDS_TO_BYTES(word_no), \
+- HDR(hblk) -> hb_sz); \
++ GC_add_leaked((ptr_t)hblk + WORDS_TO_BYTES(word_no)); \
+ }
+
+ /*
+@@ -866,7 +904,7 @@
+ * Clear *flp.
+ * This must be done before dropping a list of free gcj-style objects,
+ * since may otherwise end up with dangling "descriptor" pointers.
+- * It may help for other pointer-containg objects.
++ * It may help for other pointer-containing objects.
+ */
+ void GC_clear_fl_links(flp)
+ ptr_t *flp;
+diff -buNr boehm-gc/solaris_pthreads.c boehm-gc/solaris_pthreads.c
+--- boehm-gc/solaris_pthreads.c Mon Feb 11 20:37:53 2002
++++ boehm-gc/solaris_pthreads.c Sat Sep 13 02:10:15 2003
+@@ -13,9 +13,8 @@
+ /*
+ * Support code for Solaris threads. Provides functionality we wish Sun
+ * had provided. Relies on some information we probably shouldn't rely on.
+- * Modified Peter C. for Solaris Posix Threads.
++ * Modified by Peter C. for Solaris Posix Threads.
+ */
+-/* Boehm, September 14, 1994 4:44 pm PDT */
+
+ # if defined(GC_SOLARIS_PTHREADS)
+ # include "private/gc_priv.h"
+diff -buNr boehm-gc/solaris_threads.c boehm-gc/solaris_threads.c
+--- boehm-gc/solaris_threads.c Mon Feb 11 20:37:53 2002
++++ boehm-gc/solaris_threads.c Sat Sep 13 02:10:15 2003
+@@ -37,6 +37,10 @@
+ # include <unistd.h>
+ # include <errno.h>
+
++#ifdef HANDLE_FORK
++ --> Not yet supported. Try porting the code from linux_threads.c.
++#endif
++
+ /*
+ * This is the default size of the LWP arrays. If there are more LWPs
+ * than this when a stop-the-world GC happens, set_max_lwps will be
+@@ -361,7 +365,7 @@
+ sizeof (prgregset_t)) != 0) {
+ int j;
+
+- for(j = 0; j < NGREG; j++)
++ for(j = 0; j < NPRGREG; j++)
+ {
+ GC_printf3("%i: %x -> %x\n", j,
+ GC_lwp_registers[i][j],
+@@ -821,7 +825,7 @@
+ if (result == 0) {
+ t = GC_lookup_thread(target_thread);
+ if (t == 0) ABORT("thread unknown to GC");
+- t -> flags |= SUSPENDED;
++ t -> flags |= SUSPNDED;
+ }
+ UNLOCK();
+ return(result);
+@@ -837,7 +841,7 @@
+ if (result == 0) {
+ t = GC_lookup_thread(target_thread);
+ if (t == 0) ABORT("thread unknown to GC");
+- t -> flags &= ~SUSPENDED;
++ t -> flags &= ~SUSPNDED;
+ }
+ UNLOCK();
+ return(result);
+@@ -923,7 +927,7 @@
+ my_flags |= CLIENT_OWNS_STACK;
+ }
+ if (flags & THR_DETACHED) my_flags |= DETACHED;
+- if (flags & THR_SUSPENDED) my_flags |= SUSPENDED;
++ if (flags & THR_SUSPENDED) my_flags |= SUSPNDED;
+ result = thr_create(stack, stack_size, start_routine,
+ arg, flags & ~THR_DETACHED, &my_new_thread);
+ if (result == 0) {
+diff -buNr boehm-gc/threadlibs.c boehm-gc/threadlibs.c
+--- boehm-gc/threadlibs.c Mon Feb 11 20:37:53 2002
++++ boehm-gc/threadlibs.c Sat Sep 13 02:10:15 2003
+@@ -4,13 +4,14 @@
+ int main()
+ {
+ # if defined(GC_USE_LD_WRAP)
+- printf("-Wl,--wrap -Wl,read -Wl,--wrap -Wl,dlopen "
++ printf("-Wl,--wrap -Wl,dlopen "
+ "-Wl,--wrap -Wl,pthread_create -Wl,--wrap -Wl,pthread_join "
+ "-Wl,--wrap -Wl,pthread_detach "
+ "-Wl,--wrap -Wl,pthread_sigmask -Wl,--wrap -Wl,sleep\n");
+ # endif
+ # if defined(GC_LINUX_THREADS) || defined(GC_IRIX_THREADS) \
+- || defined(GC_FREEBSD_THREADS) || defined(GC_SOLARIS_PTHREADS)
++ || defined(GC_FREEBSD_THREADS) || defined(GC_SOLARIS_PTHREADS) \
++ || defined(GC_MACOSX_THREADS)
+ printf("-lpthread\n");
+ # endif
+ # if defined(GC_HPUX_THREADS) || defined(GC_OSF1_THREADS)
+@@ -18,6 +19,17 @@
+ # endif
+ # if defined(GC_SOLARIS_THREADS) && !defined(GC_SOLARIS_PTHREADS)
+ printf("-lthread -ldl\n");
++# endif
++# if defined(GC_WIN32_THREADS) && defined(CYGWIN32)
++ printf("-lpthread\n");
++# endif
++# if defined(GC_OSF1_THREADS)
++ printf("-lpthread -lrt");
++# endif
++ /* You need GCC 3.0.3 to build this one! */
++ /* DG/UX native gcc doesnt know what "-pthread" is */
++# if defined(GC_DGUX386_THREADS)
++ printf("-ldl -pthread\n");
+ # endif
+ return 0;
+ }
+diff -buNr boehm-gc/typd_mlc.c boehm-gc/typd_mlc.c
+--- boehm-gc/typd_mlc.c Fri Aug 17 11:30:46 2001
++++ boehm-gc/typd_mlc.c Sat Sep 13 02:10:15 2003
+@@ -437,6 +437,7 @@
+ for (; bm != 0; bm >>= 1, current_p++) {
+ if (bm & 1) {
+ current = *current_p;
++ FIXUP_POINTER(current);
+ if ((ptr_t)current >= least_ha && (ptr_t)current <= greatest_ha) {
+ PUSH_CONTENTS((ptr_t)current, mark_stack_ptr,
+ mark_stack_limit, current_p, exit1);
+@@ -674,7 +675,7 @@
+ if( !FASTLOCK_SUCCEEDED() || (op = *opp) == 0 ) {
+ FASTUNLOCK();
+ op = (ptr_t)GENERAL_MALLOC((word)lb, GC_explicit_kind);
+- if (0 == op) return(0);
++ if (0 == op) return 0;
+ # ifdef MERGE_SIZES
+ lw = GC_size_map[lb]; /* May have been uninitialized. */
+ # endif
+diff -buNr boehm-gc/version.h boehm-gc/version.h
+--- boehm-gc/version.h Mon Feb 11 20:37:53 2002
++++ boehm-gc/version.h Sat Sep 13 02:10:15 2003
+@@ -1,8 +1,25 @@
+-#define GC_VERSION_MAJOR 6
+-#define GC_VERSION_MINOR 1
+-#define GC_ALPHA_VERSION 3
++/* The version here should match that in configure/configure.in */
++/* Eventually this one may become unnecessary. For now we need */
++/* it to keep the old-style build process working. */
++#define GC_TMP_VERSION_MAJOR 6
++#define GC_TMP_VERSION_MINOR 2
++#define GC_TMP_ALPHA_VERSION 5
+
++#if defined(GC_VERSION_MAJOR)
++# if GC_TMP_VERSION_MAJOR != GC_VERSION_MAJOR || \
++ GC_TMP_VERSION_MINOR != GC_VERSION_MINOR || \
++ GC_TMP_ALPHA_VERSION != GC_ALPHA_VERSION
++# error Inconsistent version info. Check version.h and configure.in.
++# endif
++#else
++# define GC_VERSION_MAJOR GC_TMP_VERSION_MAJOR
++# define GC_VERSION_MINOR GC_TMP_VERSION_MINOR
++# define GC_ALPHA_VERSION GC_TMP_ALPHA_VERSION
++#endif
++
++#ifndef GC_NOT_ALPHA
+ # define GC_NOT_ALPHA 0xff
++#endif
+
+ #ifndef GC_NO_VERSION_VAR
+
+
+--- boehm-gc/win32_threads.c Fri Sep 26 16:46:24 2003
++++ boehm-gc/win32_threads.c Fri Sep 26 16:46:46 2003
+@@ -337,7 +337,7 @@
+
+ #if !defined(MSWINCE) && !(defined(__MINGW32__) && !defined(_DLL))
+
+-HANDLE WINAPI GC_CreateThread(
++GC_API HANDLE GC_CreateThread(
+ LPSECURITY_ATTRIBUTES lpThreadAttributes,
+ DWORD dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress,
+ LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId )
+@@ -357,7 +357,7 @@
+
+ DWORD WINAPI thread_start(LPVOID arg);
+
+-HANDLE WINAPI GC_CreateThread(
++GC_API HANDLE GC_CreateThread(
+ LPSECURITY_ATTRIBUTES lpThreadAttributes,
+ DWORD dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress,
+ LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId )
--- /dev/null
+--- libstdc++-v3/config/io/basic_file_stdio.cc Thu Sep 4 00:11:15 2003
++++ libstdc++-v3/config/io/basic_file_stdio.cc Thu Sep 4 00:27:58 2003
+@@ -239,14 +239,6 @@
+ streamsize
+ __basic_file<char>::showmanyc_helper()
+ {
+-#ifdef FIONREAD
+- // Pipes and sockets.
+- int __num = 0;
+- int __r = ioctl(this->fd(), FIONREAD, &__num);
+- if (!__r && __num >= 0)
+- return __num;
+-#endif
+-
+ #ifdef _GLIBCPP_HAVE_POLL
+ // Cheap test.
+ struct pollfd __pfd[1];
--- /dev/null
+--- libjava/posix.cc Mon Jul 7 01:38:36 2003
++++ libjava/posix.cc Mon Jul 7 01:38:44 2003
+@@ -15,6 +15,7 @@
+ #include <stdlib.h>
+ #include <errno.h>
+ #include <signal.h>
++#include <stdio.h>
+
+ #include <jvm.h>
+ #include <java/lang/Thread.h>
--- /dev/null
+--- libjava/java/util/Locale.java Wed Nov 27 14:41:07 2002
++++ libjava/java/util/Locale.java Wed Sep 10 00:10:27 2003
+@@ -193,10 +193,16 @@
+ * null. Note the logic in the main constructor, to detect when
+ * bootstrapping has completed.
+ */
+- private static Locale defaultLocale =
++
++ // XWT-specific hack: we're having a lot of trouble with Locales
++ // and static linkage, so we force this to a known locale.
++ private static Locale defaultLocale = new Locale("en", "", "");
++
++ /*
+ new Locale(System.getProperty("user.language", "en"),
+ System.getProperty("user.region", ""),
+ System.getProperty("user.variant", ""));
++ */
+
+ /**
+ * Convert new iso639 codes to the old ones.
--- /dev/null
+I *think* this bug has been fixed in the 3.4 tree. Unfortunately this
+code changed significantly between 3.3 and 3.4 so it wasn't possible to
+backport the fix.
+
+If the GCC tree is ever updated to 3.4 this patch won't apply. It can
+probably be safely removed.
+
+-Brian
+
+
+--- gcc/config/mips/mips.c.orig Mon Dec 29 06:30:42 2003
++++ gcc/config/mips/mips.c Mon Dec 29 07:16:35 2003
+@@ -10535,11 +10535,13 @@
+ int len, size, sec;
+ const char *name, *prefix;
+ char *string;
+- static const char *const prefixes[4][2] = {
++ static const char *const prefixes[6][2] = {
+ { ".text.", ".gnu.linkonce.t." },
+ { ".rodata.", ".gnu.linkonce.r." },
+ { ".data.", ".gnu.linkonce.d." },
+- { ".sdata.", ".gnu.linkonce.s." }
++ { ".sdata.", ".gnu.linkonce.sb." },
++ { ".bss.", ".gnu.linkonce.b." },
++ { ".sbss.", ".gnu.linkonce.sb." }
+ };
+
+ name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
+@@ -10551,8 +10553,9 @@
+ if (TREE_CODE (decl) == FUNCTION_DECL)
+ sec = 0;
+ else if (DECL_INITIAL (decl) == 0
+- || DECL_INITIAL (decl) == error_mark_node)
+- sec = 2;
++ || DECL_INITIAL (decl) == error_mark_node
++ || initializer_zerop (DECL_INITIAL (decl)))
++ sec = (size > 0 && size <= mips_section_threshold) ? 5 : 4;
+ else if ((TARGET_EMBEDDED_PIC || TARGET_MIPS16)
+ && TREE_CODE (decl) == STRING_CST
+ && !flag_writable_strings)
--- /dev/null
+diff -u boehm-gc/mach_dep.c boehm-gc/mach_dep.c
+--- boehm-gc/mach_dep.c Thu Jul 18 13:06:00 2002
++++ boehm-gc/mach_dep.c Tue Jan 20 17:00:36 2004
+@@ -368,9 +368,13 @@
+ # if defined(PJ)
+ {
+ register int * sp asm ("optop");
++#ifdef LINUX
++ extern ptr_t GC_linux_stack_base(void);
++ GC_push_all_stack (sp, GC_linux_stack_base());
++#elseif
+ extern int *__libc_stack_end;
+-
+ GC_push_all_stack (sp, __libc_stack_end);
++#endif
+ }
+ # endif
+
+diff -u boehm-gc/os_dep.c boehm-gc/os_dep.c
+--- boehm-gc/os_dep.c Fri Jul 19 01:54:43 2002
++++ boehm-gc/os_dep.c Tue Jan 20 16:59:10 2004
+@@ -666,8 +666,8 @@
+ # define STAT_SKIP 27 /* Number of fields preceding startstack */
+ /* field in /proc/self/stat */
+
+-# pragma weak __libc_stack_end
+- extern ptr_t __libc_stack_end;
++//# pragma weak __libc_stack_end
++// extern ptr_t __libc_stack_end;
+
+ # ifdef IA64
+ # pragma weak __libc_ia64_register_backing_store_base
+@@ -709,9 +709,11 @@
+ size_t i, buf_offset = 0;
+
+ /* First try the easy way. This should work for glibc 2.2 */
++#ifdef NEVERDEFINEDBECAUSEWEDONTWANTTHIS
+ if (0 != &__libc_stack_end) {
+ return __libc_stack_end;
+ }
++#endif
+ f = open("/proc/self/stat", O_RDONLY);
+ if (f < 0 || STAT_READ(f, stat_buf, STAT_BUF_SIZE) < 2 * STAT_SKIP) {
+ ABORT("Couldn't read /proc/self/stat");
+
--- /dev/null
+--- libjava/Makefile.in Tue May 13 17:18:14 2003
++++ libjava/Makefile.in Fri Jul 4 02:38:46 2003
+@@ -141,7 +141,8 @@
+ @XLIB_AWT_TRUE@xlib_includes = @XLIB_AWT_TRUE@-I../libstdc++-v3/include -I../libstdc++-v3/include/$(target_alias) -I$(srcdir)/../libstdc++-v3/libsupc++
+ @XLIB_AWT_FALSE@xlib_includes =
+
+-toolexeclib_LTLIBRARIES = libgcj.la lib-org-xml-sax.la lib-org-w3c-dom.la $(cond_x_ltlibrary)
++toolexeclib_LTLIBRARIES = libgcj.la $(cond_x_ltlibrary)
++#lib-org-xml-sax.la lib-org-w3c-dom.la
+ toolexecmainlib_DATA = libgcj.spec
+
+ jardir = $(datadir)/java
+@@ -149,7 +150,8 @@
+
+ secdir = $(libdir)/security
+
+-@NATIVE_TRUE@bin_PROGRAMS = @NATIVE_TRUE@jv-convert gij rmic rmiregistry
++@NATIVE_TRUE@bin_PROGRAMS = @NATIVE_TRUE@jv-convert gij
++#rmic rmiregistry
+
+ bin_SCRIPTS = addr2name.awk
+ @CANADIAN_TRUE@@NULL_TARGET_TRUE@ZIP = @CANADIAN_TRUE@@NULL_TARGET_TRUE@$(MULTIBUILDTOP)../$(COMPPATH)/fastjar/jar
+@@ -295,9 +297,9 @@
+ all_java_source_files = \
+ $(java_source_files) \
+ $(built_java_source_files) \
+- $(lib_org_xml_sax_la_SOURCES) \
+- $(lib_org_w3c_dom_la_SOURCES) \
+- $(x_java_source_files)
++# $(lib_org_xml_sax_la_SOURCES) \
++# $(lib_org_w3c_dom_la_SOURCES) \
++# $(x_java_source_files)
+
+
+ all_java_class_files = $(all_java_source_files:.java=.class)
+@@ -2060,10 +2062,11 @@
+ java/util/zip/ZipFile.java \
+ java/util/zip/ZipInputStream.java \
+ java/util/zip/ZipOutputStream.java \
+-$(rmi_java_source_files) \
+-$(awt_java_source_files) \
+-$(convert_source_files) \
+-$(javax_source_files)
++java/awt/AWTPermission.java \
++$(convert_source_files)
++#$(rmi_java_source_files) \
++#$(awt_java_source_files) \
++#$(javax_source_files)
+
+
+ java_source_files = $(special_java_source_files) $(ordinary_java_source_files)
+@@ -2360,7 +2363,7 @@
+ gnu/gcj/xlib/natXExposeEvent.lo gnu/gcj/xlib/natXImage.lo \
+ gnu/gcj/xlib/natXUnmapEvent.lo
+ @NATIVE_TRUE@bin_PROGRAMS = jv-convert$(EXEEXT) gij$(EXEEXT) \
+-@NATIVE_TRUE@rmic$(EXEEXT) rmiregistry$(EXEEXT)
++#@NATIVE_TRUE@rmic$(EXEEXT) rmiregistry$(EXEEXT)
+ @NATIVE_TRUE@@MAINTAINER_MODE_TRUE@noinst_PROGRAMS = \
+ @NATIVE_TRUE@@MAINTAINER_MODE_TRUE@gen-from-JIS$(EXEEXT)
+ PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS)
+@@ -3827,8 +3830,10 @@
+ .deps/org/xml/sax/helpers/XMLReaderFactory.P .deps/posix-threads.P \
+ .deps/posix.P .deps/prims.P .deps/resolve.P .deps/verify.P \
+ .deps/win32-threads.P .deps/win32.P
+-SOURCES = $(libgcj_la_SOURCES) $(EXTRA_libgcj_la_SOURCES) $(lib_org_xml_sax_la_SOURCES) $(lib_org_w3c_dom_la_SOURCES) $(lib_gnu_awt_xlib_la_SOURCES) $(EXTRA_lib_gnu_awt_xlib_la_SOURCES) $(jv_convert_SOURCES) $(EXTRA_jv_convert_SOURCES) $(gij_SOURCES) $(rmic_SOURCES) $(EXTRA_rmic_SOURCES) $(rmiregistry_SOURCES) $(EXTRA_rmiregistry_SOURCES) $(gen_from_JIS_SOURCES) $(EXTRA_gen_from_JIS_SOURCES)
+-OBJECTS = $(libgcj_la_OBJECTS) $(lib_org_xml_sax_la_OBJECTS) $(lib_org_w3c_dom_la_OBJECTS) $(lib_gnu_awt_xlib_la_OBJECTS) $(jv_convert_OBJECTS) $(gij_OBJECTS) $(rmic_OBJECTS) $(rmiregistry_OBJECTS) $(gen_from_JIS_OBJECTS)
++SOURCES = $(libgcj_la_SOURCES) $(EXTRA_libgcj_la_SOURCES) $(jv_convert_SOURCES) $(EXTRA_jv_convert_SOURCES) $(gij_SOURCES) $(gen_from_JIS_SOURCES) $(EXTRA_gen_from_JIS_SOURCE)
++#$(lib_org_xml_sax_la_SOURCES) $(lib_org_w3c_dom_la_SOURCES) $(lib_gnu_awt_xlib_la_SOURCES) $(EXTRA_lib_gnu_awt_xlib_la_SOURCES) $(rmic_SOURCES) $(EXTRA_rmic_SOURCES) $(rmiregistry_SOURCES) $(EXTRA_rmiregistry_SOURCES)
++OBJECTS = $(libgcj_la_OBJECTS) $(jv_convert_OBJECTS) $(gij_OBJECTS) $(rmic_OBJECTS) $(gen_from_JIS_OBJECTS)
++#$(lib_org_xml_sax_la_OBJECTS) $(lib_org_w3c_dom_la_OBJECTS) $(lib_gnu_awt_xlib_la_OBJECTS) $(rmiregistry_OBJECTS)
+
+ all: all-redirect
+ .SUFFIXES:
+@@ -4380,7 +4385,8 @@
+
+ $(c_files): java/lang/fdlibm.h java/lang/ieeefp.h java/lang/mprec.h
+
+-$(javao_files) $(x_javao_files) $(lib_org_w3c_dom_la_OBJECTS) $(lib_org_xml_sax_la_OBJECTS): %.lo: %.java
++#$(lib_org_w3c_dom_la_OBJECTS) $(lib_org_xml_sax_la_OBJECTS)
++$(javao_files) $(x_javao_files): %.lo: %.java
+ $(GCJCOMPILE) -o $@ $<
+
+ libgcj.la: $(libgcj_la_OBJECTS) $(libgcj_la_DEPENDENCIES)
--- /dev/null
+--- gcc/config/mips/mips.md Thu Aug 21 12:04:35 2003
++++ gcc/config/mips/mips.md Thu Aug 21 12:05:59 2003
+@@ -4843,155 +4843,6 @@
+ ;; ??? There could be HImode variants for the ulh/ulhu/ush macros.
+ ;; It isn't clear whether this will give better code.
+
+-;; Only specify the mode operand 1, the rest are assumed to be word_mode.
+-(define_expand "extv"
+- [(set (match_operand 0 "register_operand" "")
+- (sign_extract (match_operand:QI 1 "memory_operand" "")
+- (match_operand 2 "immediate_operand" "")
+- (match_operand 3 "immediate_operand" "")))]
+- "!TARGET_MIPS16"
+- "
+-{
+- /* If the field does not start on a byte boundary, then fail. */
+- if (INTVAL (operands[3]) % 8 != 0)
+- FAIL;
+-
+- /* MIPS I and MIPS II can only handle a 32bit field. */
+- if (!TARGET_64BIT && INTVAL (operands[2]) != 32)
+- FAIL;
+-
+- /* MIPS III and MIPS IV can handle both 32bit and 64bit fields. */
+- if (TARGET_64BIT
+- && INTVAL (operands[2]) != 64
+- && INTVAL (operands[2]) != 32)
+- FAIL;
+-
+- /* This can happen for a 64 bit target, when extracting a value from
+- a 64 bit union member. extract_bit_field doesn't verify that our
+- source matches the predicate, so we force it to be a MEM here. */
+- if (GET_CODE (operands[1]) != MEM)
+- FAIL;
+-
+- /* Change the mode to BLKmode for aliasing purposes. */
+- operands[1] = adjust_address (operands[1], BLKmode, 0);
+- set_mem_size (operands[1], GEN_INT (INTVAL (operands[2]) / BITS_PER_UNIT));
+-
+- /* Otherwise, emit a l[wd]l/l[wd]r pair to load the value. */
+- if (INTVAL (operands[2]) == 64)
+- emit_insn (gen_movdi_uld (operands[0], operands[1]));
+- else
+- {
+- if (TARGET_64BIT)
+- {
+- operands[0] = gen_lowpart (SImode, operands[0]);
+- if (operands[0] == NULL_RTX)
+- FAIL;
+- }
+- emit_insn (gen_movsi_ulw (operands[0], operands[1]));
+- }
+- DONE;
+-}")
+-
+-;; Only specify the mode operand 1, the rest are assumed to be word_mode.
+-(define_expand "extzv"
+- [(set (match_operand 0 "register_operand" "")
+- (zero_extract (match_operand:QI 1 "memory_operand" "")
+- (match_operand 2 "immediate_operand" "")
+- (match_operand 3 "immediate_operand" "")))]
+- "!TARGET_MIPS16"
+- "
+-{
+- /* If the field does not start on a byte boundary, then fail. */
+- if (INTVAL (operands[3]) % 8 != 0)
+- FAIL;
+-
+- /* MIPS I and MIPS II can only handle a 32bit field. */
+- if (!TARGET_64BIT && INTVAL (operands[2]) != 32)
+- FAIL;
+-
+- /* MIPS III and MIPS IV can handle both 32bit and 64bit fields. */
+- if (TARGET_64BIT
+- && INTVAL (operands[2]) != 64
+- && INTVAL (operands[2]) != 32)
+- FAIL;
+-
+- /* This can happen for a 64 bit target, when extracting a value from
+- a 64 bit union member. extract_bit_field doesn't verify that our
+- source matches the predicate, so we force it to be a MEM here. */
+- if (GET_CODE (operands[1]) != MEM)
+- FAIL;
+-
+- /* Change the mode to BLKmode for aliasing purposes. */
+- operands[1] = adjust_address (operands[1], BLKmode, 0);
+- set_mem_size (operands[1], GEN_INT (INTVAL (operands[2]) / BITS_PER_UNIT));
+-
+- /* Otherwise, emit a lwl/lwr pair to load the value. */
+- if (INTVAL (operands[2]) == 64)
+- emit_insn (gen_movdi_uld (operands[0], operands[1]));
+- else
+- {
+- if (TARGET_64BIT)
+- {
+- operands[0] = gen_lowpart (SImode, operands[0]);
+- if (operands[0] == NULL_RTX)
+- FAIL;
+- }
+- emit_insn (gen_movsi_ulw (operands[0], operands[1]));
+- }
+- DONE;
+-}")
+-
+-;; Only specify the mode operands 0, the rest are assumed to be word_mode.
+-(define_expand "insv"
+- [(set (zero_extract (match_operand:QI 0 "memory_operand" "")
+- (match_operand 1 "immediate_operand" "")
+- (match_operand 2 "immediate_operand" ""))
+- (match_operand 3 "register_operand" ""))]
+- "!TARGET_MIPS16"
+- "
+-{
+- /* If the field does not start on a byte boundary, then fail. */
+- if (INTVAL (operands[2]) % 8 != 0)
+- FAIL;
+-
+- /* MIPS I and MIPS II can only handle a 32bit field. */
+- if (!TARGET_64BIT && INTVAL (operands[1]) != 32)
+- FAIL;
+-
+- /* MIPS III and MIPS IV can handle both 32bit and 64bit fields. */
+- if (TARGET_64BIT
+- && INTVAL (operands[1]) != 64
+- && INTVAL (operands[1]) != 32)
+- FAIL;
+-
+- /* This can happen for a 64 bit target, when storing into a 32 bit union
+- member. store_bit_field doesn't verify that our target matches the
+- predicate, so we force it to be a MEM here. */
+- if (GET_CODE (operands[0]) != MEM)
+- FAIL;
+-
+- /* Change the mode to BLKmode for aliasing purposes. */
+- operands[0] = adjust_address (operands[0], BLKmode, 0);
+- set_mem_size (operands[0], GEN_INT (INTVAL (operands[1]) / BITS_PER_UNIT));
+-
+- /* Otherwise, emit a s[wd]l/s[wd]r pair to load the value. */
+- if (INTVAL (operands[1]) == 64)
+- emit_insn (gen_movdi_usd (operands[0], operands[3]));
+- else
+- {
+- if (TARGET_64BIT)
+- {
+- operands[3] = gen_lowpart (SImode, operands[3]);
+- if (operands[3] == NULL_RTX)
+- FAIL;
+- }
+- emit_insn (gen_movsi_usw (operands[0], operands[3]));
+- }
+- DONE;
+-}")
+-
+-;; unaligned word moves generated by the bit field patterns
+-
+ (define_insn "movsi_ulw"
+ [(set (match_operand:SI 0 "register_operand" "=&d,&d")
+ (unspec:SI [(match_operand:BLK 1 "general_operand" "R,o")]
+--- gcc/config/mips/mips.c Fri Jan 31 15:51:23 2003
++++ gcc/config/mips/mips.c Thu Aug 21 20:04:19 2003
+@@ -4027,34 +4027,6 @@
+ bytes -= 8;
+ }
+
+- /* ??? Fails because of a MIPS assembler bug? */
+- else if (TARGET_64BIT && bytes >= 8
+- && ! TARGET_SR71K
+- && ! TARGET_MIPS16)
+- {
+- if (BYTES_BIG_ENDIAN)
+- {
+- load_store[num].load = "ldl\t%0,%1\n\tldr\t%0,%2";
+- load_store[num].load_nop = "ldl\t%0,%1\n\tldr\t%0,%2%#";
+- load_store[num].store = "sdl\t%0,%1\n\tsdr\t%0,%2";
+- load_store[num].last_store = "sdr\t%0,%2";
+- load_store[num].final = "sdl\t%0,%1";
+- }
+- else
+- {
+- load_store[num].load = "ldl\t%0,%2\n\tldr\t%0,%1";
+- load_store[num].load_nop = "ldl\t%0,%2\n\tldr\t%0,%1%#";
+- load_store[num].store = "sdl\t%0,%2\n\tsdr\t%0,%1";
+- load_store[num].last_store = "sdr\t%0,%1";
+- load_store[num].final = "sdl\t%0,%2";
+- }
+-
+- load_store[num].mode = DImode;
+- offset += 8;
+- bytes -= 8;
+- use_lwl_lwr = 1;
+- }
+-
+ else if (bytes >= 4 && align >= 4)
+ {
+ load_store[num].load = "lw\t%0,%1";
+@@ -4065,33 +4037,6 @@
+ load_store[num].mode = SImode;
+ offset += 4;
+ bytes -= 4;
+- }
+-
+- else if (bytes >= 4
+- && ! TARGET_SR71K
+- && ! TARGET_MIPS16)
+- {
+- if (BYTES_BIG_ENDIAN)
+- {
+- load_store[num].load = "lwl\t%0,%1\n\tlwr\t%0,%2";
+- load_store[num].load_nop = "lwl\t%0,%1\n\tlwr\t%0,%2%#";
+- load_store[num].store = "swl\t%0,%1\n\tswr\t%0,%2";
+- load_store[num].last_store = "swr\t%0,%2";
+- load_store[num].final = "swl\t%0,%1";
+- }
+- else
+- {
+- load_store[num].load = "lwl\t%0,%2\n\tlwr\t%0,%1";
+- load_store[num].load_nop = "lwl\t%0,%2\n\tlwr\t%0,%1%#";
+- load_store[num].store = "swl\t%0,%2\n\tswr\t%0,%1";
+- load_store[num].last_store = "swr\t%0,%1";
+- load_store[num].final = "swl\t%0,%2";
+- }
+-
+- load_store[num].mode = SImode;
+- offset += 4;
+- bytes -= 4;
+- use_lwl_lwr = 1;
+ }
+
+ else if (bytes >= 2 && align >= 2)
--- /dev/null
+--- configure.in Sun Sep 7 22:38:26 2003
++++ configure.in Sun Sep 7 22:38:31 2003
+@@ -528,7 +528,7 @@
+ noconfigdirs="$noconfigdirs gdb target-newlib target-libgloss ${libgcj}"
+ ;;
+ powerpc-*-darwin*)
+- noconfigdirs="$noconfigdirs bfd binutils ld gas opcodes gdb gprof ${libgcj}"
++ noconfigdirs="$noconfigdirs bfd binutils ld gas opcodes gdb gprof ${libgcj} target-libstdc++-v3"
+ ;;
+ powerpc-*-eabi)
+ noconfigdirs="$noconfigdirs ${libgcj}"
+@@ -610,6 +610,7 @@
+ fi
+ ;;
+ sparc-*-solaris* | sparc64-*-solaris* | sparcv9-*-solaris*)
++ noconfigdirs="$noconfigdirs target-libstdc++-v3"
+ ;;
+ v810-*-*)
+ noconfigdirs="$noconfigdirs bfd binutils gas gcc gdb ld ${libstdcxx_version} opcodes target-libgloss ${libgcj}"
--- /dev/null
+--- gcc/Makefile.in Tue Apr 22 08:50:48 2003
++++ gcc/Makefile.in Sun Sep 7 20:51:05 2003
+@@ -2915,11 +2915,7 @@
+
+ # Install the library.
+ install-libgcc: libgcc.mk libgcc.a installdirs
+- if $(RANLIB_TEST_FOR_TARGET); then \
+ r_f_t=$(RANLIB_FOR_TARGET); \
+- else \
+- r_f_t=: ; \
+- fi; \
+ $(MAKE) GCC_FOR_TARGET="$(GCC_FOR_TARGET)" \
+ BUILD_PREFIX="$(BUILD_PREFIX)" BUILD_PREFIX_1="$(BUILD_PREFIX_1)" \
+ AR_FOR_TARGET="$(AR_FOR_TARGET)" \
+@@ -2942,11 +2938,7 @@
+
+ # Install multiple versions of libgcc.a.
+ install-multilib: stmp-multilib installdirs
+- if $(RANLIB_TEST_FOR_TARGET); then \
+ r_f_t=$(RANLIB_FOR_TARGET); \
+- else \
+- r_f_t=: ; \
+- fi; \
+ $(MAKE) GCC_FOR_TARGET="$(GCC_FOR_TARGET)" \
+ BUILD_PREFIX="$(BUILD_PREFIX)" BUILD_PREFIX_1="$(BUILD_PREFIX_1)" \
+ AR_FOR_TARGET="$(AR_FOR_TARGET)" \
+@@ -3552,9 +3544,7 @@
+ -if [ -f collect-ld$(exeext) ] ; then (cd stage1 && $(LN_S) ../collect-ld$(exeext) .) ; else true ; fi
+ -rm -f stage1/libgcc.a stage1/libgcc_eh.a
+ -cp libgcc.a stage1
+- -if $(RANLIB_TEST_FOR_TARGET) ; then \
+ $(RANLIB_FOR_TARGET) stage1/libgcc.a; \
+- else true; fi
+ -if [ -f libgcc_eh.a ] ; then cp libgcc_eh.a stage1; \
+ if $(RANLIB_TEST_FOR_TARGET) ; then \
+ $(RANLIB_FOR_TARGET) stage1/libgcc_eh.a; \
+@@ -3581,13 +3571,9 @@
+ -if [ -f collect-ld$(exeext) ] ; then (cd stage2 && $(LN_S) ../collect-ld$(exeext) .) ; else true ; fi
+ -rm -f stage2/libgcc.a stage2/libgcc_eh.a
+ -cp libgcc.a stage2
+- -if $(RANLIB_TEST_FOR_TARGET) ; then \
+ $(RANLIB_FOR_TARGET) stage2/libgcc.a; \
+- else true; fi
+ -if [ -f libgcc_eh.a ] ; then cp libgcc_eh.a stage2; \
+- if $(RANLIB_TEST_FOR_TARGET) ; then \
+ $(RANLIB_FOR_TARGET) stage2/libgcc_eh.a; \
+- else true; fi; fi
+ -for f in .. $(EXTRA_MULTILIB_PARTS); do if [ x$${f} != x.. ]; then \
+ cp stage2/$${f} . ; \
+ else true; \
+@@ -3610,13 +3596,9 @@
+ -if [ -f collect-ld$(exeext) ] ; then (cd stage3 && $(LN_S) ../collect-ld$(exeext) .) ; else true ; fi
+ -rm -f stage3/libgcc.a stage3/libgcc_eh.a
+ -cp libgcc.a stage3
+- -if $(RANLIB_TEST_FOR_TARGET) ; then \
+ $(RANLIB_FOR_TARGET) stage3/libgcc.a; \
+- else true; fi
+ -if [ -f libgcc_eh.a ] ; then cp libgcc_eh.a stage3; \
+- if $(RANLIB_TEST_FOR_TARGET) ; then \
+ $(RANLIB_FOR_TARGET) stage3/libgcc_eh.a; \
+- else true; fi; fi
+ -for f in .. $(EXTRA_MULTILIB_PARTS); do if [ x$${f} != x.. ]; then \
+ cp stage3/$${f} . ; \
+ else true; \
+@@ -3639,13 +3621,9 @@
+ -if [ -f collect-ld$(exeext) ] ; then (cd stage4 && $(LN_S) ../collect-ld$(exeext) .) ; else true ; fi
+ -rm -f stage4/libgcc.a stage4/libgcc_eh.a
+ -cp libgcc.a stage4
+- -if $(RANLIB_TEST_FOR_TARGET) ; then \
+ $(RANLIB_FOR_TARGET) stage4/libgcc.a; \
+- else true; fi
+ -if [ -f libgcc_eh.a ] ; then cp libgcc_eh.a stage4; \
+- if $(RANLIB_TEST_FOR_TARGET) ; then \
+ $(RANLIB_FOR_TARGET) stage4/libgcc_eh.a; \
+- else true; fi; fi
+ -for f in .. $(EXTRA_MULTILIB_PARTS); do if [ x$${f} != x.. ]; then \
+ cp stage4/$${f} . ; \
+ else true; \
+--- gcc/mklibgcc.in Sun Jan 26 03:35:07 2003
++++ gcc/mklibgcc.in Sun Sep 7 20:49:48 2003
+@@ -312,9 +312,7 @@
+ echo "${dir}/libgcc.a: $libgcc_a_objs"
+ echo " -rm -rf ${dir}/libgcc.a"
+ echo ' $(AR_CREATE_FOR_TARGET)' ${dir}/libgcc.a $libgcc_a_objs
+- echo ' if $(RANLIB_TEST_FOR_TARGET) ; then' \\
+ echo ' $(RANLIB_FOR_TARGET)' ${dir}/libgcc.a ';' \\
+- echo ' else true; fi;'
+
+ if [ "$SHLIB_LINK" ]; then
+
--- /dev/null
+--- gcc/config/sparc/gmon-sol2.c Sun Sep 15 05:03:42 2002
++++ gcc/config/sparc/gmon-sol2.c Sat Jul 12 05:43:17 2003
+@@ -1,3 +1,4 @@
++#define PATH_MAX 254
+ /*-
+ * Copyright (c) 1991 The Regents of the University of California.
+ * All rights reserved.
+diff -ur libjava/configure gcc-3.3+/libjava/configure
+--- libjava/configure Tue May 13 17:18:14 2003
++++ libjava/configure Tue Jul 15 02:41:51 2003
+@@ -3331,6 +3331,10 @@
+ THREADLDFLAGS=-pthread
+ THREADSPEC=-lc_r
+ ;;
++ *-solaris*)
++ THREADLIBS=-lpthread -lsocket -lnsl -ldl
++ THREADSPEC=-lpthread -lsocket -lnsl -ldl
++ ;;
+ *)
+ THREADLIBS=-lpthread
+ THREADSPEC=-lpthread
+diff -ur libjava/configure.in gcc-3.3+/libjava/configure.in
+--- libjava/configure.in Fri Mar 28 15:42:56 2003
++++ libjava/configure.in Tue Jul 15 02:17:07 2003
+@@ -402,6 +402,10 @@
+ THREADLDFLAGS=-pthread
+ THREADSPEC=-lc_r
+ ;;
++ *-*-solaris*)
++ THREADLIBS=-lpthread -lsocket -lnsl -ldl
++ THREADSPEC=-lpthread -lsocket -lnsl -ldl
++ ;;
+ *)
+ THREADLIBS=-lpthread
+ THREADSPEC=-lpthread
+--- gcc/config/t-slibgcc-sld Sun Jan 26 03:35:07 2003
++++ gcc/config/t-slibgcc-sld Wed Oct 15 00:01:12 2003
+@@ -10,7 +10,7 @@
+
+ SHLIB_LINK = $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) -shared -nodefaultlibs \
+ -Wl,-h,$(SHLIB_SONAME) -Wl,-z,text -Wl,-z,defs \
+- -Wl,-M,$(SHLIB_MAP) -o $(SHLIB_NAME) \
++ -o $(SHLIB_NAME) \
+ @multilib_flags@ $(SHLIB_OBJS) -lc && \
+ rm -f $(SHLIB_SOLINK) && \
+ $(LN_S) $(SHLIB_NAME) $(SHLIB_SOLINK)
--- /dev/null
+diff -rBub boehm-gc/configureboehm-gc/configure
+--- boehm-gc/configure Tue May 13 17:18:14 2003
++++ boehm-gc/configure Mon Mar 1 01:03:55 2004
+@@ -1181,9 +1181,9 @@
+ if test "$ac_test_CFLAGS" = set; then
+ CFLAGS="$ac_save_CFLAGS"
+ elif test $ac_cv_prog_cc_g = yes; then
+- CFLAGS="-g -O2"
++ CFLAGS="-g -Os -ffunction-sections -fdata-sections"
+ else
+- CFLAGS="-O2"
++ CFLAGS="-Os -ffunction-sections -fdata-sections"
+ fi
+ else
+ GCC=
+@@ -1275,9 +1275,9 @@
+ if test "$ac_test_CXXFLAGS" = set; then
+ CXXFLAGS="$ac_save_CXXFLAGS"
+ elif test $ac_cv_prog_cxx_g = yes; then
+- CXXFLAGS="-g -O2"
++ CXXFLAGS="-g -Os -ffunction-sections -fdata-sections"
+ else
+- CXXFLAGS="-O2"
++ CXXFLAGS="-Os -ffunction-sections -fdata-sections"
+ fi
+ else
+ GXX=
+diff -rBub gcc/dwarf2out.cgcc/dwarf2out.c
+--- gcc/dwarf2out.c Mon May 5 09:59:20 2003
++++ gcc/dwarf2out.c Sat Feb 28 02:37:20 2004
+@@ -1040,6 +1040,8 @@
+ else if (!flag_asynchronous_unwind_tables && cfa.reg != STACK_POINTER_REGNUM)
+ return;
+
++ if (frame_pointer_needed) return;
++
+ if (GET_CODE (insn) == BARRIER)
+ {
+ /* When we see a BARRIER, we know to reset args_size to 0. Usually
+diff -rBub gcc/java/class.cgcc/java/class.c
+--- gcc/java/class.c Fri Feb 28 12:53:07 2003
++++ gcc/java/class.c Mon Mar 1 00:20:15 2004
+@@ -971,7 +971,7 @@
+ tree type;
+ {
+ int is_compiled = is_compiled_class (type);
+- if (is_compiled)
++ if (is_compiled || flag_inhibit_reflection)
+ {
+ tree ref, decl_name, decl;
+ if (TREE_CODE (type) == POINTER_TYPE)
+@@ -1199,13 +1199,17 @@
+ int resolved = is_compiled_class (type);
+
+ START_RECORD_CONSTRUCTOR (finit, field_type_node);
++ if (!flag_inhibit_reflection) {
+ PUSH_FIELD_VALUE (finit, "name", build_utf8_ref (DECL_NAME (fdecl)));
++ } else {
++ PUSH_FIELD_VALUE (finit, "name", null_pointer_node);
++ }
+ if (resolved)
+ type = build_class_ref (type);
+ else
+ {
++ if (!flag_inhibit_reflection) {
+ tree signature = build_java_signature (type);
+-
+ type = build_utf8_ref (unmangle_classname
+ (IDENTIFIER_POINTER (signature),
+ IDENTIFIER_LENGTH (signature)));
+@@ -1209,6 +1213,9 @@
+ type = build_utf8_ref (unmangle_classname
+ (IDENTIFIER_POINTER (signature),
+ IDENTIFIER_LENGTH (signature)));
++ } else {
++ type = null_pointer_node;
++ }
+ }
+ PUSH_FIELD_VALUE (finit, "type", type);
+
+@@ -1244,6 +1251,7 @@
+ tree code;
+ #define ACC_TRANSLATED 0x4000
+ int accflags = get_access_flags_from_decl (mdecl) | ACC_TRANSLATED;
++ int emitNames = 0;
+
+ if (!flag_indirect_dispatch && DECL_VINDEX (mdecl) != NULL_TREE)
+ index = DECL_VINDEX (mdecl);
+@@ -1254,6 +1262,12 @@
+ if (DECL_RTL_SET_P (mdecl))
+ code = build1 (ADDR_EXPR, nativecode_ptr_type_node, mdecl);
+ START_RECORD_CONSTRUCTOR (minit, method_type_node);
++
++ emitNames = !flag_inhibit_reflection;
++ if (!METHOD_STATIC(mdecl)) emitNames = 1;
++ if (DECL_CLINIT_P(mdecl)) emitNames = 1;
++ if ((METHOD_STATIC(mdecl) && (strcmp(IDENTIFIER_POINTER(DECL_NAME(mdecl)),"main") == 0))) emitNames = 1;
++ if (emitNames) {
+ PUSH_FIELD_VALUE (minit, "name",
+ build_utf8_ref (DECL_CONSTRUCTOR_P (mdecl) ?
+ init_identifier_node
+@@ -1266,6 +1280,10 @@
+ (IDENTIFIER_POINTER(signature),
+ IDENTIFIER_LENGTH(signature)))));
+ }
++ } else {
++ PUSH_FIELD_VALUE (minit, "name", null_pointer_node);
++ PUSH_FIELD_VALUE (minit, "signature", null_pointer_node);
++ }
+ PUSH_FIELD_VALUE (minit, "accflags", build_int_2 (accflags, 0));
+ PUSH_FIELD_VALUE (minit, "index", index);
+ PUSH_FIELD_VALUE (minit, "ncode", code);
+@@ -1273,6 +1291,7 @@
+ {
+ /* Compute the `throws' information for the method. */
+ tree table = null_pointer_node;
++ if (!flag_inhibit_reflection)
+ if (DECL_FUNCTION_THROWS (mdecl) != NULL_TREE)
+ {
+ int length = 1 + list_length (DECL_FUNCTION_THROWS (mdecl));
+@@ -1473,6 +1493,7 @@
+ DECL_INITIAL (field) = initial;
+ }
+ else
++ if (!flag_inhibit_reflection)
+ {
+ instance_field_count++;
+ instance_fields = tree_cons (NULL_TREE, init, instance_fields);
+@@ -1480,6 +1501,9 @@
+ }
+ }
+ field_count = static_field_count + instance_field_count;
++
++ // we have to leave this here; part of the class initialization is the process
++ // of replacing utf8const's with String objects
+ if (field_count > 0)
+ {
+ static_fields = nreverse (static_fields);
+@@ -1550,7 +1574,7 @@
+ super = CLASSTYPE_SUPER (type);
+ if (super == NULL_TREE)
+ super = null_pointer_node;
+- else if (assume_compiled (IDENTIFIER_POINTER (DECL_NAME (type_decl))))
++ else if (flag_inhibit_reflection || (assume_compiled (IDENTIFIER_POINTER (DECL_NAME (type_decl)))))
+ super = build_class_ref (super);
+ else
+ {
+@@ -1576,7 +1600,7 @@
+ tree child = TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type), i);
+ tree iclass = BINFO_TYPE (child);
+ tree index;
+- if (assume_compiled (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (iclass)))))
++ if (flag_inhibit_reflection || (assume_compiled (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (iclass))))))
+ index = build_class_ref (iclass);
+ else
+ {
+@@ -2225,6 +2249,7 @@
+ index = 0;
+ method_list = otable_methods;
+ list = NULL_TREE;
++ if (!flag_inhibit_reflection)
+ while (method_list != NULL_TREE)
+ {
+ method = TREE_VALUE (method_list);
+diff -rBub gcc/java/constants.cgcc/java/constants.c
+--- gcc/java/constants.c Mon Nov 18 07:46:32 2002
++++ gcc/java/constants.c Mon Mar 1 00:20:32 2004
+@@ -430,9 +430,13 @@
+ int i;
+ for (i = outgoing_cpool->count; --i > 0; )
+ {
++ if (!flag_inhibit_reflection) {
+ tags_list
+ = tree_cons (NULL_TREE, get_tag_node (outgoing_cpool->tags[i]),
+ tags_list);
++ } else {
++ tags_list = null_pointer_node;
++ }
+ data_list
+ = tree_cons (NULL_TREE, build_utf8_ref ((tree)outgoing_cpool->data[i]),
+ data_list);
+@@ -446,7 +450,9 @@
+ index_type = build_index_type (max_index);
+
+ /* Add dummy 0'th element of constant pool. */
++ if (!flag_inhibit_reflection) {
+ tags_list = tree_cons (NULL_TREE, get_tag_node (0), tags_list);
++ }
+ data_list = tree_cons (NULL_TREE, null_pointer_node, data_list);
+
+ data_decl = TREE_OPERAND (build_constant_data_ref (), 0);
+@@ -458,6 +464,7 @@
+ rest_of_decl_compilation (data_decl, (char *) 0, 1, 0);
+ data_value = build_address_of (data_decl);
+
++ if (!flag_inhibit_reflection) {
+ tags_type = build_array_type (unsigned_byte_type_node, index_type);
+ tags_decl = build_decl (VAR_DECL, mangled_classname ("_CT_",
+ current_class),
+@@ -467,6 +474,9 @@
+ NULL_TREE, tags_list);
+ rest_of_decl_compilation (tags_decl, (char*) 0, 1, 0);
+ tags_value = build_address_of (tags_decl);
++ } else {
++ tags_value = null_pointer_node;
++ }
+ }
+ else
+ {
+diff -rBub gcc/java/java-tree.hgcc/java/java-tree.h
+--- gcc/java/java-tree.h Mon Nov 18 10:13:35 2002
++++ gcc/java/java-tree.h Thu Feb 26 15:01:38 2004
+@@ -225,6 +225,9 @@
+ /* Encoding used for source files. */
+ extern const char *current_encoding;
+
++/** don't emit reflection information */
++extern int flag_inhibit_reflection;
++
+ /* The Java .class file that provides main_class; the main input file. */
+ extern struct JCF *current_jcf;
+
+diff -rBub gcc/java/lang.cgcc/java/lang.c
+--- gcc/java/lang.c Sun Jan 5 07:03:25 2003
++++ gcc/java/lang.c Thu Feb 26 15:01:38 2004
+@@ -171,6 +171,9 @@
+ /* The encoding of the source file. */
+ const char *current_encoding = NULL;
+
++/** don't emit reflection information */
++int flag_inhibit_reflection = 0;
++
+ /* When nonzero, report the now deprecated empty statements. */
+ int flag_extraneous_semicolon;
+
+@@ -431,6 +434,13 @@
+ {
+ flag_inline_functions = 1;
+ flag_really_inline = 1;
++ return 1;
++ }
++#undef ARG
++#define ARG "-finhibit-reflection"
++ if (strncmp (p, ARG, sizeof (ARG) - 1) == 0)
++ {
++ flag_inhibit_reflection = 1;
+ return 1;
+ }
+ #undef ARG
+diff -rBub libjava/Makefile.inlibjava/Makefile.in
+--- libjava/Makefile.in Mon Mar 1 01:45:58 2004
++++ libjava/Makefile.in Sun Feb 29 22:09:27 2004
+@@ -174,10 +174,10 @@
+
+ WARNINGS = -W -Wall
+ AM_CXXFLAGS = -fno-rtti -fnon-call-exceptions \
+- -fdollars-in-identifiers \
++ -fdollars-in-identifiers -ffunction-sections -fdata-sections \
+ -Wswitch-enum \
+ @LIBGCJ_CXXFLAGS@ @X_CFLAGS@ $(WARNINGS) -D_GNU_SOURCE \
+- -DPREFIX="\"$(prefix)\""
++ -DPREFIX="\"$(prefix)\"" -Os
+
+ @USING_GCC_TRUE@AM_CFLAGS = @USING_GCC_TRUE@@LIBGCJ_CFLAGS@ $(WARNINGS)
+ @USING_GCC_FALSE@AM_CFLAGS = @USING_GCC_FALSE@@LIBGCJ_CFLAGS@
+diff -rBub libjava/boehm.cclibjava/boehm.cc
+--- libjava/boehm.cc Thu Jan 2 21:19:53 2003
++++ libjava/boehm.cc Mon Mar 1 00:21:04 2004
+@@ -17,6 +17,7 @@
+
+ #include <java/lang/Class.h>
+ #include <java/lang/reflect/Modifier.h>
++#include <java/lang/VirtualMachineError.h>
+ #include <java-interp.h>
+
+ // More nastiness: the GC wants to define TRUE and FALSE. We don't
+@@ -147,6 +149,7 @@
+ for (int i = 0; i < c->method_count; ++i)
+ {
+ p = (ptr_t) c->methods[i].name;
++ if (p == NULL) continue;
+ MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c,
+ cm1label);
+ p = (ptr_t) c->methods[i].signature;
+@@ -164,9 +167,11 @@
+
+ #ifndef COMPACT_FIELDS
+ p = (ptr_t) field->name;
++ if (p == NULL) continue;
+ MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c, c8alabel);
+ #endif
+ p = (ptr_t) field->type;
++ if (p == NULL) continue;
+ MAYBE_MARK (p, mark_stack_ptr, mark_stack_limit, c, c8blabel);
+
+ // For the interpreter, we also need to mark the memory
+@@ -258,6 +263,7 @@
+ // Note: occasionally `klass' can be null. For instance, this
+ // can happen if a GC occurs between the point where an object
+ // is allocated and where the vtbl slot is set.
++ throw new java::lang::VirtualMachineError();
+ while (klass && klass != &java::lang::Object::class$)
+ {
+ jfieldID field = JvGetFirstInstanceField (klass);
+diff -rBub libjava/configurelibjava/configure
+--- libjava/configure Mon Mar 1 01:45:59 2004
++++ libjava/configure Sun Feb 29 22:13:11 2004
+@@ -1180,13 +1180,13 @@
+ CFLAGS="$ac_save_CFLAGS"
+ elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+- CFLAGS="-g -O2"
++ CFLAGS="-g -Os"
+ else
+ CFLAGS="-g"
+ fi
+ else
+ if test "$GCC" = yes; then
+- CFLAGS="-O2"
++ CFLAGS="-Os"
+ else
+ CFLAGS=
+ fi
+@@ -1287,9 +1287,9 @@
+ if test "$ac_test_CXXFLAGS" = set; then
+ CXXFLAGS="$ac_save_CXXFLAGS"
+ elif test $ac_cv_prog_cxx_g = yes; then
+- CXXFLAGS="-g -O2"
++ CXXFLAGS="-g -Os"
+ else
+- CXXFLAGS="-O2"
++ CXXFLAGS="-Os"
+ fi
+ else
+ GXX=
+@@ -1683,6 +1683,9 @@
+
+
+
++cat >> confdefs.h <<\EOF
++#undef USE_LTDL
++EOF
+
+
+ # Only use libltdl for native builds.
+@@ -1697,9 +1700,9 @@
+
+
+ DIRLTDL=libltdl
+- cat >> confdefs.h <<\EOF
+-#define USE_LTDL 1
+-EOF
++# cat >> confdefs.h <<\EOF
++##define USE_LTDL 1
++#EOF
+
+ # Sigh. Libtool's macro doesn't do the right thing.
+ INCLTDL="-I\$(top_srcdir)/libltdl $INCLTDL"
+@@ -5644,7 +5647,7 @@
+ fi
+ fi
+
+- test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2"
++ test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -Os"
+
+
+
+@@ -5798,7 +5801,7 @@
+ echo $ac_n "checking for g++ -ffloat-store bug""... $ac_c" 1>&6
+ echo "configure:5796: checking for g++ -ffloat-store bug" >&5
+ save_CFLAGS="$CFLAGS"
+-CFLAGS="-x c++ -O2 -ffloat-store"
++CFLAGS="-x c++ -Os -ffloat-store"
+ cat > conftest.$ac_ext <<EOF
+ #line 5800 "configure"
+ #include "confdefs.h"
+diff -rBub libjava/configure.inlibjava/configure.in
+--- libjava/configure.in Mon Mar 1 01:45:59 2004
++++ libjava/configure.in Mon Mar 1 00:28:09 2004
+@@ -825,7 +825,7 @@
+ dnl Work around a g++ bug. Reported to gcc-bugs@gcc.gnu.org on Jan 22, 2000.
+ AC_MSG_CHECKING([for g++ -ffloat-store bug])
+ save_CFLAGS="$CFLAGS"
+-CFLAGS="-x c++ -O2 -ffloat-store"
++CFLAGS="-x c++ -Os -ffloat-store"
+ AC_TRY_COMPILE([#include <math.h>], ,
+ [AC_MSG_RESULT(no)],
+ [AC_DEFINE(__NO_MATH_INLINES)
+diff -rBub libjava/gnu/gcj/convert/BytesToUnicode.javalibjava/gnu/gcj/convert/BytesToUnicode.java
+--- libjava/gnu/gcj/convert/BytesToUnicode.java Mon Jul 30 13:24:17 2001
++++ libjava/gnu/gcj/convert/BytesToUnicode.java Fri Feb 27 04:17:13 2004
+@@ -65,7 +65,7 @@
+ }
+ catch (Throwable ex)
+ {
+- return new Input_8859_1();
++ throw new UnsatisfiedLinkError();
+ }
+ }
+
+@@ -100,6 +100,7 @@
+ }
+ catch (Throwable ex)
+ {
++ /*
+ try
+ {
+ // We pass the original name to iconv and let it handle
+@@ -108,9 +109,10 @@
+ }
+ catch (Throwable _)
+ {
++ */
+ throw new java.io.UnsupportedEncodingException(encoding
+ + " (" + ex + ')');
+- }
++ //}
+ }
+ }
+
+diff -rBub libjava/gnu/gcj/convert/IOConverter.javalibjava/gnu/gcj/convert/IOConverter.java
+--- libjava/gnu/gcj/convert/IOConverter.java Sun Sep 16 19:28:53 2001
++++ libjava/gnu/gcj/convert/IOConverter.java Sun Feb 29 01:53:14 2004
+@@ -20,7 +20,7 @@
+
+ // True if we have to do byte-order conversions on iconv()
+ // arguments.
+- static protected boolean iconv_byte_swap;
++ static protected boolean iconv_byte_swap = false;
+
+ static
+ {
+@@ -64,7 +64,7 @@
+ hash.put ("cseucpkdfmtjapanese", "EUCJIS");
+ hash.put ("euc-jp", "EUCJIS");
+
+- iconv_byte_swap = iconv_init ();
++ //iconv_byte_swap = iconv_init ();
+ }
+
+ private static native boolean iconv_init ();
+diff -rBub libjava/gnu/gcj/convert/UnicodeToBytes.javalibjava/gnu/gcj/convert/UnicodeToBytes.java
+--- libjava/gnu/gcj/convert/UnicodeToBytes.java Fri Aug 17 20:56:01 2001
++++ libjava/gnu/gcj/convert/UnicodeToBytes.java Fri Feb 27 04:17:02 2004
+@@ -63,7 +63,8 @@
+ }
+ catch (Throwable ex)
+ {
+- return new Output_8859_1();
++ throw new UnsatisfiedLinkError();
++ //return new Output_8859_1();
+ }
+ }
+
+@@ -97,6 +98,7 @@
+ }
+ catch (Throwable ex)
+ {
++ /*
+ try
+ {
+ // We pass the original name to iconv and let it handle
+@@ -105,10 +107,11 @@
+ }
+ catch (Throwable _)
+ {
++ */
+ // Put the original exception in the throwable.
+ throw new java.io.UnsupportedEncodingException(encoding + " ("
+ + ex + ')');
+- }
++ //}
+ }
+ }
+
+diff -rBub libjava/gnu/gcj/runtime/FirstThread.javalibjava/gnu/gcj/runtime/FirstThread.java
+--- libjava/gnu/gcj/runtime/FirstThread.java Wed Oct 10 15:25:43 2001
++++ libjava/gnu/gcj/runtime/FirstThread.java Fri Feb 27 05:05:29 2004
+@@ -90,8 +90,10 @@
+ // classes are linked in. Otherwise bootstrapping fails. These
+ // classes are only referred to via Class.forName(), so we add an
+ // explicit mention of them here.
++ /*
+ static final Class Kcert = java.security.cert.Certificate.class;
+ static final Class Kfile = gnu.gcj.protocol.file.Handler.class;
+ static final Class Khttp = gnu.gcj.protocol.http.Handler.class;
+ static final Class Kjar = gnu.gcj.protocol.jar.Handler.class;
++ */
+ }
+diff -rBub libjava/gnu/gcj/runtime/VMClassLoader.javalibjava/gnu/gcj/runtime/VMClassLoader.java
+--- libjava/gnu/gcj/runtime/VMClassLoader.java Sun Dec 8 16:03:59 2002
++++ libjava/gnu/gcj/runtime/VMClassLoader.java Fri Feb 27 04:20:56 2004
+@@ -14,13 +14,15 @@
+ import java.util.StringTokenizer;
+ import java.net.URL;
+
+-public final class VMClassLoader extends java.net.URLClassLoader
++public final class VMClassLoader extends java.lang.ClassLoader //java.net.URLClassLoader
+ {
+ private VMClassLoader ()
+ {
++ /*
+ super (init());
++ */
+ }
+-
++ /*
+ private static URL[] init()
+ {
+ StringTokenizer st
+@@ -40,7 +42,7 @@
+ }
+ catch (java.net.MalformedURLException x)
+ {
+- /* Ignore this path element */
++ // Ignore this path element
+ }
+ }
+ // Add core:/ to the end of the java.class.path so any resources
+@@ -58,7 +60,7 @@
+ p.copyInto (urls);
+ return urls;
+ }
+-
++*/
+ /** This is overridden to search the internal hash table, which
+ * will only search existing linked-in classes. This will make
+ * the default implementation of loadClass (in ClassLoader) work right.
+diff -rBub libjava/gnu/gcj/runtime/natVMClassLoader.cclibjava/gnu/gcj/runtime/natVMClassLoader.cc
+--- libjava/gnu/gcj/runtime/natVMClassLoader.cc Tue Dec 10 19:15:14 2002
++++ libjava/gnu/gcj/runtime/natVMClassLoader.cc Fri Feb 27 04:22:00 2004
+@@ -60,8 +60,9 @@
+ }
+
+ // Now try loading using the interpreter.
++ /*
+ if (! klass)
+ klass = java::net::URLClassLoader::findClass (name);
+-
++ */
+ return klass;
+ }
+diff -rBub libjava/java/lang/Class.javalibjava/java/lang/Class.java
+--- libjava/java/lang/Class.java Tue Sep 3 14:33:46 2002
++++ libjava/java/lang/Class.java Sat Feb 28 22:48:09 2004
+@@ -241,6 +241,7 @@
+ */
+ public ProtectionDomain getProtectionDomain()
+ {
++ /*
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkPermission(ClassLoader.protectionDomainPermission);
+@@ -248,9 +249,12 @@
+ ProtectionDomain protectionDomain = getProtectionDomain0();
+
+ if (protectionDomain == null)
++ */
+ return ClassLoader.unknownProtectionDomain;
++ /*
+ else
+ return protectionDomain;
++ */
+ }
+
+ public String toString ()
+diff -rBub libjava/java/lang/ClassLoader.javalibjava/java/lang/ClassLoader.java
+--- libjava/java/lang/ClassLoader.java Fri Jan 24 11:38:24 2003
++++ libjava/java/lang/ClassLoader.java Sat Feb 28 21:07:31 2004
+@@ -345,8 +345,8 @@
+ // FIXME: should there be a special protection domain used for native code?
+
+ // The permission required to check what a classes protection domain is.
+- static final Permission protectionDomainPermission
+- = new RuntimePermission("getProtectionDomain");
++ //static final Permission protectionDomainPermission;
++ //= new RuntimePermission("getProtectionDomain");
+ // The protection domain returned if we cannot determine it.
+ static ProtectionDomain unknownProtectionDomain;
+ // Protection domain to use when a class is defined without one specified.
+@@ -355,12 +355,14 @@
+ static
+ {
+ Permissions permissions = new Permissions();
+- permissions.add(new AllPermission());
+- unknownProtectionDomain = new ProtectionDomain(null, permissions);
++ //permissions.add(new AllPermission());
++ //unknownProtectionDomain = new ProtectionDomain(null, permissions);
+
++ /*
+ CodeSource cs = new CodeSource(null, null);
+ defaultProtectionDomain =
+ new ProtectionDomain(cs, Policy.getPolicy().getPermissions(cs));
++ */
+ }
+
+ /**
+diff -rBub libjava/java/lang/SecurityManager.javalibjava/java/lang/SecurityManager.java
+--- libjava/java/lang/SecurityManager.java Sun Dec 1 08:16:19 2002
++++ libjava/java/lang/SecurityManager.java Fri Feb 27 02:08:27 2004
+@@ -297,7 +297,8 @@
+ public Object getSecurityContext()
+ {
+ // XXX Should be: return AccessController.getContext();
+- return new SecurityContext(getClassContext());
++ //return new SecurityContext(getClassContext());
++ return null;
+ }
+
+ /**
+diff -rBub libjava/java/lang/natClass.cclibjava/java/lang/natClass.cc
+--- libjava/java/lang/natClass.cc Thu May 1 14:52:35 2003
++++ libjava/java/lang/natClass.cc Mon Mar 1 01:00:12 2004
+@@ -72,8 +72,10 @@
+
+ _Jv_Utf8Const *name = _Jv_makeUtf8Const (buffer, length);
+
++ /*
+ if (! _Jv_VerifyClassName (name))
+ throw new java::lang::ClassNotFoundException (className);
++ */
+
+ jclass klass = (buffer[0] == '['
+ ? _Jv_FindClassFromSignature (name->data, loader)
+@@ -1518,7 +1520,7 @@
+ return;
+
+ klass->otable->state = 1;
+-
++ return;
+ int index = 0;
+ _Jv_MethodSymbol sym = klass->otable_syms[0];
+
+diff -rBub libjava/java/lang/natClassLoader.cclibjava/java/lang/natClassLoader.cc
+--- libjava/java/lang/natClassLoader.cc Thu Dec 19 11:32:17 2002
++++ libjava/java/lang/natClassLoader.cc Sun Feb 29 23:55:48 2004
+@@ -195,6 +195,7 @@
+ _Jv_Constants *pool = &klass->constants;
+ for (int index = 1; index < pool->size; ++index)
+ {
++ /*
+ if (pool->tags[index] == JV_CONSTANT_Class)
+ {
+ _Jv_Utf8Const *name = pool->data[index].utf8;
+@@ -217,12 +218,13 @@
+ }
+ else if (pool->tags[index] == JV_CONSTANT_String)
+ {
++ */
+ jstring str;
+
+ str = _Jv_NewStringUtf8Const (pool->data[index].utf8);
+ pool->data[index].o = str;
+- pool->tags[index] |= JV_CONSTANT_ResolvedFlag;
+- }
++ //pool->tags[index] |= JV_CONSTANT_ResolvedFlag;
++ //}
+ }
+
+ #ifdef INTERPRETER
+@@ -253,10 +255,10 @@
+
+ if (klass->vtable == NULL)
+ _Jv_MakeVTable(klass);
+-
++ /*
+ if (klass->otable != NULL && klass->otable->state == 0)
+ _Jv_LinkOffsetTable(klass);
+-
++ */
+ klass->notifyAll ();
+
+ _Jv_PushClass (klass);
+diff -rBub libjava/java/security/Security.javalibjava/java/security/Security.java
+--- libjava/java/security/Security.java Tue Dec 31 14:49:37 2002
++++ libjava/java/security/Security.java Sat Feb 28 21:33:32 2004
+@@ -60,9 +60,11 @@
+
+ static
+ {
++ /*
+ String base = System.getProperty("gnu.classpath.home.url");
+ loadProviders(base, System.getProperty("gnu.classpath.vm.shortname"));
+ loadProviders(base, "classpath");
++ */
+ }
+
+ // This class can't be instantiated.
+diff -rBub libjava/libgcj.spec.inlibjava/libgcj.spec.in
+--- libjava/libgcj.spec.in Wed Feb 12 18:09:27 2003
++++ libjava/libgcj.spec.in Sun Feb 29 17:15:19 2004
+@@ -4,6 +4,7 @@
+ # to link with libgcj.
+ #
+ %rename lib liborig
+-*lib: -lgcj -lm @LIBICONV@ @GCSPEC@ @THREADSPEC@ @ZLIBSPEC@ @SYSTEMSPEC@ %(libgcc) %(liborig)
++*lib: -lm @LIBICONV@ @GCSPEC@ @THREADSPEC@ @ZLIBSPEC@ @SYSTEMSPEC@ %(libgcc) %(liborig)
++
++*jc1: @HASH_SYNC_SPEC@ @DIVIDESPEC@ @CHECKREFSPEC@ @JC1GCSPEC@ @EXCEPTIONSPEC@ @BACKTRACESPEC@ @IEEESPEC@ -fkeep-inline-functions -fno-omit-frame-pointer -Os -ffunction-sections -fdata-sections
+
+-*jc1: @HASH_SYNC_SPEC@ @DIVIDESPEC@ @CHECKREFSPEC@ @JC1GCSPEC@ @EXCEPTIONSPEC@ @BACKTRACESPEC@ @IEEESPEC@ -fkeep-inline-functions
+diff -rBub libjava/prims.cclibjava/prims.cc
+--- libjava/prims.cc Fri Apr 25 09:02:21 2003
++++ libjava/prims.cc Sat Feb 28 20:32:25 2004
+@@ -165,6 +165,7 @@
+ {
+ int len;
+ _Jv_ushort *aptr, *bptr;
++ if (a == NULL || b == NULL) return false;
+ if (a == b)
+ return true;
+ if (a->hash != b->hash)
+@@ -188,6 +189,7 @@
+ jboolean
+ _Jv_equal (Utf8Const* a, jstring str, jint hash)
+ {
++ if (a == NULL) return false;
+ if (a->hash != (_Jv_ushort) hash)
+ return false;
+ jint len = str->length();
+@@ -210,6 +212,7 @@
+ jboolean
+ _Jv_equaln (Utf8Const *a, jstring str, jint n)
+ {
++ if (a == NULL) return false;
+ jint len = str->length();
+ jint i = 0;
+ jchar *sptr = _Jv_GetStringChars (str);
+@@ -936,7 +939,7 @@
+
+ _Jv_platform_initialize ();
+
+- _Jv_JNI_Init ();
++ // _Jv_JNI_Init ();
+
+ _Jv_GCInitializeFinalizers (&::gnu::gcj::runtime::FinalizerThread::finalizerReady);
+
+--- gcc/toplev.c Mon May 5 14:55:26 2003
++++ gcc/toplev.c Wed Mar 10 05:10:33 2004
+@@ -975,6 +975,7 @@
+ if `-fSTRING' is seen as an option.
+ (If `-fno-STRING' is seen as an option, the opposite value is stored.) */
+
++static int ignoreme;
+ static const lang_independent_options f_options[] =
+ {
+ {"eliminate-dwarf2-dups", &flag_eliminate_dwarf2_dups, 1,
+@@ -1188,6 +1189,8 @@
+ N_("Trap for signed overflow in addition / subtraction / multiplication") },
+ { "new-ra", &flag_new_regalloc, 1,
+ N_("Use graph coloring register allocation.") },
++ { "inhibit-reflection", &ignoreme, 1,
++ N_("ignored.") },
+ };
+
+ /* Table of language-specific options. */
--- /dev/null
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+\f
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+\f
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+\f
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+\f
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+\f
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) 19yy name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
--- /dev/null
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+\f
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+\f
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+\f
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+\f
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+\f
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+\f
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+\f
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+\f
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+\f
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
+
+
--- /dev/null
+gnu.regexp README
+-----------------
+
+This is open source software distributed under the terms of the GNU
+Lesser General Public License. See the COPYING.LIB file for details.
+Some included utilities are distributed under the terms of the GNU
+General Public License, a copy of which is included in the file COPYING.
+
+INSTALLING
+
+Copy the gnu.regexp jar file (located in the 'lib' directory)
+to your usual installation directory for Java archives.
+
+To use gnu.regexp, you will need to include it in your classpath
+setting. Typically this is done by adding an entry to your CLASSPATH
+variable setting with the full path to the JAR file, e.g.
+ csh: % setenv CLASSPATH ${CLASSPATH}:/usr/java/lib/gnu-regexp-1.1.x.jar
+ bash: % export CLASSPATH=${CLASSPATH}:/usr/java/lib/gnu-regexp-1.1.x.jar
+ DOS: > set CLASSPATH %CLASSPATH%;C:\Java\lib\gnu-regexp-1.1.x.jar
+Various shells and operating systems may have slightly different methods.
+Consult your Java virtual machine documentation for details. You may also
+specify the -classpath option to the java executable, e.g.
+compile: % javac -classpath /usr/java/lib/gnu-regexp-1.1.x.jar MyClass.java
+execute: % java -classpath /usr/java/lib/gnu-regexp-1.1.x.jar MyClass
+
+DOCUMENTATION
+
+HTML documentation is provided in the 'docs' directory. This is basically
+a snapshot of the official gnu.regexp web site (see below for URL). The
+documentation files are:
+ docs/index.html -- general package information
+ docs/changes.html -- change history
+ docs/credits.html -- credits and contributors
+ docs/faq.html -- frequently asked questions
+ docs/syntax.html -- supported/unsupported syntax and usage notes
+ docs/reapplet.html -- demo applet HTML wrapper
+ docs/api/*.html -- javadoc generated info
+
+For additional help, you can try emailing <help-java-regexp@gnu.org>.
+
+UTILITIES
+
+gnu.regexp comes with a number of simple utility programs intended to test
+and demonstrate its features. These are not compiled into the Java archive
+file, but can be found in the 'src/gnu/regexp/util' directory. To run the
+Grep and Egrep programs, you'll need to install the gnu.getopt package,
+available at http://www.urbanophile.com/~arenn/hacking/download.html, and put
+those class files in your classpath as well.
+
+HACKING
+
+You are free to fold, spindle, mutilate and modify this library,
+provided you follow the terms outlined in COPYING.LIB. The gnu.regexp
+project team gratefully accepts any bug fixes or enhancements you may
+come up with (see the TODO file if you're in need of some ideas). A
+few parameters at the top of the Makefile in the 'src' directory
+need to be edited to match your local system setup.
+
+BUG REPORTS
+
+Send bug reports to <bug-java-regexp@gnu.org>, or join the gnu.regexp
+mailing list by sending a "subscribe" message to
+<regexp-request@cacas.org>. It helps if you can send a code sample
+showing the regular expression you were using and how you were using
+it.
+
+LATEST VERSION
+
+You can always obtain info about the latest version of gnu.regexp at
+http://www.cacas.org/java/gnu/regexp/. New versions are also announced on
+the regexp mailing list (see above).
+
+Thanks!
+
+Wes Biggs <wes@cacas.org>
--- /dev/null
+gnu.regexp TODO
+---------------
+These are items that have yet to be implemented or are part of the
+general wish list for gnu.regexp. You can contribute to this program
+and get your name permanently embedded in the distribution if you care
+to take on any of these tasks. See the contact info in the README.
+
+Bugs / Problems with the engine:
+
+ Using a ')' in a character class which is within a () grouping
+triggers an REException while parsing. Workaround is to put a backslash
+in front of the literal ')'.
+ The leftmost longest rule is not strictly adhered to. For example,
+the expression ".*?z?", given input "xyz", should match the whole string,
+not the empty string.
+
+Missing operators:
+
+ [.symbol.] -- collating symbol (POSIX)
+ [=class=] -- equivalence class (POSIX)
+
+I18n support:
+
+ Some POSIX char classes ([:alpha:]) are locale sensitive, others need work
+ Ranges (e.g. [a-z]) should be locale sensitive
+ Should use collation elements, not chars, for things like Spanish "ll"
+ REG_ICASE is not very friendly with Cyrillic and other locales.
+ Messages used for exceptions should be localizable.
+
+Performance:
+
+ Engine speed needs some major work.
+
+Miscellaneous/Requests for Enhancements:
+
+ "Free software needs free manuals" -- you heard the man...
+
+ Some features have been added to Perl between 5.0 and 5.6. Should the
+PERL5 syntax support these, or should a new syntax be added? Which should
+be the default?
+
+ There could be a flag to enforce strict POSIX leftmost-longest matching.
+
+ gnu.regexp.util.Tests should be fleshed out, or perhaps changed to use JUnit.
+
+ It might make sense for getMatchEnumeration() to optionally return matches
+in reverse order, so that the indices were valid all the way through,
+even if you were doing text replacement on the way.
+
+ Support J2ME CLDC limited APIs as optional target:
+Should be straightforward, but need to avoid use of
+REFilter(InputStream|Reader) classes, as well as all references to
+java.io.Serializable. RESyntax needs to replace java.util.BitSet with
+a home-grown version. Other than that, it should work. May want to
+package separately (e.g. gnu.regexp-1.0.8-j2me-cldc.jar).
+
+ Add support for named subgroups: "(?P<name>...)" (match) and "(?P=name)"
+(recall, like \n). Add the ability to get at an enumeration of names.
+
+ Support associative-array style interface that allows users to define
+their own substitution behavior on matches. Perhaps a Substitutor interface
+with String substitute(REMatch match), and then RE.substituteAll(input,
+Substitutor) variations.
+
+ Support excluded subrange syntax as in Unicode recommendations, e.g.
+"[a-z-[m-p]]" being a through z except for m through p.
+
+ Add a split() method.
+
+ Provide a build.xml file for Ant.
\ No newline at end of file
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Sun Oct 21 14:27:45 PDT 2001 -->
+<TITLE>
+All Classes
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+<FONT size="+1" CLASS="FrameHeadingFont">
+<B>All Classes</B></FONT>
+<BR>
+
+<TABLE BORDER="0" WIDTH="100%">
+<TR>
+<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="gnu/regexp/CharIndexed.html" TARGET="classFrame"><I>CharIndexed</I></A>
+<BR>
+<A HREF="gnu/regexp/util/Egrep.html" TARGET="classFrame">Egrep</A>
+<BR>
+<A HREF="gnu/regexp/util/Grep.html" TARGET="classFrame">Grep</A>
+<BR>
+<A HREF="gnu/regexp/RE.html" TARGET="classFrame">RE</A>
+<BR>
+<A HREF="gnu/regexp/util/REApplet.html" TARGET="classFrame">REApplet</A>
+<BR>
+<A HREF="gnu/regexp/REException.html" TARGET="classFrame">REException</A>
+<BR>
+<A HREF="gnu/regexp/REFilterInputStream.html" TARGET="classFrame">REFilterInputStream</A>
+<BR>
+<A HREF="gnu/regexp/REFilterReader.html" TARGET="classFrame">REFilterReader</A>
+<BR>
+<A HREF="gnu/regexp/REMatch.html" TARGET="classFrame">REMatch</A>
+<BR>
+<A HREF="gnu/regexp/REMatchEnumeration.html" TARGET="classFrame">REMatchEnumeration</A>
+<BR>
+<A HREF="gnu/regexp/RESyntax.html" TARGET="classFrame">RESyntax</A>
+<BR>
+<A HREF="gnu/regexp/util/RETest.html" TARGET="classFrame">RETest</A>
+<BR>
+<A HREF="gnu/regexp/util/Tests.html" TARGET="classFrame">Tests</A>
+<BR>
+<A HREF="gnu/regexp/UncheckedRE.html" TARGET="classFrame">UncheckedRE</A>
+<BR>
+</FONT></TD>
+</TR>
+</TABLE>
+
+</BODY>
+</HTML>
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Sun Oct 21 14:27:45 PDT 2001 -->
+<TITLE>
+: Deprecated List
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A> </TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> <FONT CLASS="NavBarFont1Rev"><B>Deprecated</B></FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A> </TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ PREV
+ NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="index.html" TARGET="_top"><B>FRAMES</B></A>
+ <A HREF="deprecated-list.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<CENTER>
+<H2>
+<B>Deprecated API</B></H2>
+</CENTER>
+
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Deprecated Classes</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="gnu/regexp/REFilterInputStream.html">gnu.regexp.REFilterInputStream</A>
+<BR>
+ <I>This class cannot properly handle all character
+ encodings. For proper handling, use the REFilterReader
+ class instead.</I> </TD>
+</TR>
+</TABLE>
+
+<P>
+
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Deprecated Methods</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="gnu/regexp/REMatch.html#getSubEndIndex(int)">gnu.regexp.REMatch.getSubEndIndex(int)</A>
+<BR>
+ <I>Use getEndIndex(int) instead</I> </TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><A HREF="gnu/regexp/REMatch.html#getSubStartIndex(int)">gnu.regexp.REMatch.getSubStartIndex(int)</A>
+<BR>
+ <I>Use getStartIndex(int) instead.</I> </TD>
+</TR>
+</TABLE>
+
+<P>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A> </TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> <FONT CLASS="NavBarFont1Rev"><B>Deprecated</B></FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A> </TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ PREV
+ NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="index.html" TARGET="_top"><B>FRAMES</B></A>
+ <A HREF="deprecated-list.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Sun Oct 21 14:27:45 PDT 2001 -->
+<TITLE>
+: Interface CharIndexed
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A> </TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> <FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A> </TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ PREV CLASS
+ NEXT CLASS</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../index.html" TARGET="_top"><B>FRAMES</B></A>
+ <A HREF="CharIndexed.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: INNER | <A HREF="#field_summary">FIELD</A> | CONSTR | <A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: <A HREF="#field_detail">FIELD</A> | CONSTR | <A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+gnu.regexp</FONT>
+<BR>
+Interface CharIndexed</H2>
+<HR>
+<DL>
+<DT>public interface <B>CharIndexed</B></DL>
+
+<P>
+Defines the interface used internally so that different types of source
+ text can be accessed in the same way. Built-in concrete classes provide
+ support for String, StringBuffer, InputStream and char[] types.
+ A class that is CharIndexed supports the notion of a cursor within a
+ block of text. The cursor must be able to be advanced via the move()
+ method. The charAt() method returns the character at the cursor position
+ plus a given offset.
+<P>
+<DL>
+<DT><B>Author: </B><DD><A HREF="mailto:wes@cacas.org">Wes Biggs</A></DD>
+</DL>
+<HR>
+
+<P>
+<!-- ======== INNER CLASS SUMMARY ======== -->
+
+
+<!-- =========== FIELD SUMMARY =========== -->
+
+<A NAME="field_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Field Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static char</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/CharIndexed.html#OUT_OF_BOUNDS">OUT_OF_BOUNDS</A></B></CODE>
+
+<BR>
+ Defines a constant (0xFFFF was somewhat arbitrarily chosen)
+ that can be returned by the charAt() function indicating that
+ the specified index is out of range.</TD>
+</TR>
+</TABLE>
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE> char</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/CharIndexed.html#charAt(int)">charAt</A></B>(int index)</CODE>
+
+<BR>
+ Returns the character at the given offset past the current cursor
+ position in the input.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE> boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/CharIndexed.html#isValid()">isValid</A></B>()</CODE>
+
+<BR>
+ Returns true if the most recent move() operation placed the cursor
+ position at a valid position in the input.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE> boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/CharIndexed.html#move(int)">move</A></B>(int index)</CODE>
+
+<BR>
+ Shifts the input buffer by a given number of positions.</TD>
+</TR>
+</TABLE>
+
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+<A NAME="field_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Field Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="OUT_OF_BOUNDS"><!-- --></A><H3>
+OUT_OF_BOUNDS</H3>
+<PRE>
+public static final char <B>OUT_OF_BOUNDS</B></PRE>
+<DL>
+<DD>Defines a constant (0xFFFF was somewhat arbitrarily chosen)
+ that can be returned by the charAt() function indicating that
+ the specified index is out of range.</DL>
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="charAt(int)"><!-- --></A><H3>
+charAt</H3>
+<PRE>
+public char <B>charAt</B>(int index)</PRE>
+<DL>
+<DD>Returns the character at the given offset past the current cursor
+ position in the input. The index of the current position is zero.
+ It is possible for this method to be called with a negative index.
+ This happens when using the '^' operator in multiline matching mode
+ or the '\b' or '\<' word boundary operators. In any case, the lower
+ bound is currently fixed at -2 (for '^' with a two-character newline).<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>index</CODE> - the offset position in the character field to examine<DT><B>Returns:</B><DD>the character at the specified index, or the OUT_OF_BOUNDS
+ character defined by this interface.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="move(int)"><!-- --></A><H3>
+move</H3>
+<PRE>
+public boolean <B>move</B>(int index)</PRE>
+<DL>
+<DD>Shifts the input buffer by a given number of positions. Returns
+ true if the new cursor position is valid.</DL>
+<HR>
+
+<A NAME="isValid()"><!-- --></A><H3>
+isValid</H3>
+<PRE>
+public boolean <B>isValid</B>()</PRE>
+<DL>
+<DD>Returns true if the most recent move() operation placed the cursor
+ position at a valid position in the input.</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A> </TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> <FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A> </TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ PREV CLASS
+ NEXT CLASS</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../index.html" TARGET="_top"><B>FRAMES</B></A>
+ <A HREF="CharIndexed.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: INNER | <A HREF="#field_summary">FIELD</A> | CONSTR | <A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: <A HREF="#field_detail">FIELD</A> | CONSTR | <A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Sun Oct 21 14:27:45 PDT 2001 -->
+<TITLE>
+: Class RE
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A> </TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> <FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A> </TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ PREV CLASS
+ <A HREF="../../gnu/regexp/REFilterInputStream.html"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../index.html" TARGET="_top"><B>FRAMES</B></A>
+ <A HREF="RE.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: INNER | <A HREF="#field_summary">FIELD</A> | <A HREF="#constructor_summary">CONSTR</A> | <A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: <A HREF="#field_detail">FIELD</A> | <A HREF="#constructor_detail">CONSTR</A> | <A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+gnu.regexp</FONT>
+<BR>
+Class RE</H2>
+<PRE>
+java.lang.Object
+ |
+ +--gnu.regexp.REToken
+ |
+ +--<B>gnu.regexp.RE</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD>java.io.Serializable</DD>
+</DL>
+<DL>
+<DT><B>Direct Known Subclasses:</B> <DD><A HREF="../../gnu/regexp/UncheckedRE.html">UncheckedRE</A></DD>
+</DL>
+<HR>
+<DL>
+<DT>public class <B>RE</B><DT>extends gnu.regexp.REToken</DL>
+
+<P>
+RE provides the user interface for compiling and matching regular
+ expressions.
+ <P>
+ A regular expression object (class RE) is compiled by constructing it
+ from a String, StringBuffer or character array, with optional
+ compilation flags (below)
+ and an optional syntax specification (see RESyntax; if not specified,
+ <code>RESyntax.RE_SYNTAX_PERL5</code> is used).
+ <P>
+ Various methods attempt to match input text against a compiled
+ regular expression. These methods are:
+ <LI><code>isMatch</code>: returns true if the input text in its entirety
+ matches the regular expression pattern.
+ <LI><code>getMatch</code>: returns the first match found in the input text,
+ or null if no match is found.
+ <LI><code>getAllMatches</code>: returns an array of all non-overlapping
+ matches found in the input text. If no matches are found, the array is
+ zero-length.
+ <LI><code>substitute</code>: substitute the first occurence of the pattern
+ in the input text with a replacement string (which may include
+ metacharacters $0-$9, see REMatch.substituteInto).
+ <LI><code>substituteAll</code>: same as above, but repeat for each match
+ before returning.
+ <LI><code>getMatchEnumeration</code>: returns an REMatchEnumeration object
+ that allows iteration over the matches (see REMatchEnumeration for some
+ reasons why you may want to do this instead of using <code>getAllMatches</code>.
+ <P>
+
+ These methods all have similar argument lists. The input can be a
+ String, a character array, a StringBuffer, a Reader or an
+ InputStream of some sort. Note that when using a Reader or
+ InputStream, the stream read position cannot be guaranteed after
+ attempting a match (this is not a bug, but a consequence of the way
+ regular expressions work). Using an REMatchEnumeration can
+ eliminate most positioning problems.
+
+ <P>
+
+ The optional index argument specifies the offset from the beginning
+ of the text at which the search should start (see the descriptions
+ of some of the execution flags for how this can affect positional
+ pattern operators). For a Reader or InputStream, this means an
+ offset from the current read position, so subsequent calls with the
+ same index argument on a Reader or an InputStream will not
+ necessarily access the same position on the stream, whereas
+ repeated searches at a given index in a fixed string will return
+ consistent results.
+
+ <P>
+ You can optionally affect the execution environment by using a
+ combination of execution flags (constants listed below).
+
+ <P>
+ All operations on a regular expression are performed in a
+ thread-safe manner.
+<P>
+<DL>
+<DT><B>Version: </B><DD>1.1.4-dev, to be released</DD>
+<DT><B>Author: </B><DD><A HREF="mailto:wes@cacas.org">Wes Biggs</A></DD>
+<DT><B>See Also: </B><DD><A HREF="../../serialized-form.html#gnu.regexp.RE">Serialized Form</A></DL>
+<HR>
+
+<P>
+<!-- ======== INNER CLASS SUMMARY ======== -->
+
+
+<!-- =========== FIELD SUMMARY =========== -->
+
+<A NAME="field_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Field Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RE.html#REG_ANCHORINDEX">REG_ANCHORINDEX</A></B></CODE>
+
+<BR>
+ Execution flag.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RE.html#REG_DOT_NEWLINE">REG_DOT_NEWLINE</A></B></CODE>
+
+<BR>
+ Compilation flag.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RE.html#REG_ICASE">REG_ICASE</A></B></CODE>
+
+<BR>
+ Compilation flag.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RE.html#REG_MULTILINE">REG_MULTILINE</A></B></CODE>
+
+<BR>
+ Compilation flag.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RE.html#REG_NO_INTERPOLATE">REG_NO_INTERPOLATE</A></B></CODE>
+
+<BR>
+ Execution flag.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RE.html#REG_NOTBOL">REG_NOTBOL</A></B></CODE>
+
+<BR>
+ Execution flag.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RE.html#REG_NOTEOL">REG_NOTEOL</A></B></CODE>
+
+<BR>
+ Execution flag.</TD>
+</TR>
+</TABLE>
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../gnu/regexp/RE.html#RE(java.lang.Object)">RE</A></B>(java.lang.Object pattern)</CODE>
+
+<BR>
+ Constructs a regular expression pattern buffer without any compilation
+ flags set, and using the default syntax (RESyntax.RE_SYNTAX_PERL5).</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../gnu/regexp/RE.html#RE(java.lang.Object, int)">RE</A></B>(java.lang.Object pattern,
+ int cflags)</CODE>
+
+<BR>
+ Constructs a regular expression pattern buffer using the specified
+ compilation flags and the default syntax (RESyntax.RE_SYNTAX_PERL5).</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../gnu/regexp/RE.html#RE(java.lang.Object, int, gnu.regexp.RESyntax)">RE</A></B>(java.lang.Object pattern,
+ int cflags,
+ <A HREF="../../gnu/regexp/RESyntax.html">RESyntax</A> syntax)</CODE>
+
+<BR>
+ Constructs a regular expression pattern buffer using the specified
+ compilation flags and regular expression syntax.</TD>
+</TR>
+</TABLE>
+
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE> <A HREF="../../gnu/regexp/REMatch.html">REMatch</A>[]</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RE.html#getAllMatches(java.lang.Object)">getAllMatches</A></B>(java.lang.Object input)</CODE>
+
+<BR>
+ Returns an array of all matches found in the input.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE> <A HREF="../../gnu/regexp/REMatch.html">REMatch</A>[]</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RE.html#getAllMatches(java.lang.Object, int)">getAllMatches</A></B>(java.lang.Object input,
+ int index)</CODE>
+
+<BR>
+ Returns an array of all matches found in the input,
+ beginning at the specified index position.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE> <A HREF="../../gnu/regexp/REMatch.html">REMatch</A>[]</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RE.html#getAllMatches(java.lang.Object, int, int)">getAllMatches</A></B>(java.lang.Object input,
+ int index,
+ int eflags)</CODE>
+
+<BR>
+ Returns an array of all matches found in the input string,
+ beginning at the specified index position and using the specified
+ execution flags.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE> <A HREF="../../gnu/regexp/REMatch.html">REMatch</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RE.html#getMatch(java.lang.Object)">getMatch</A></B>(java.lang.Object input)</CODE>
+
+<BR>
+ Returns the first match found in the input.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE> <A HREF="../../gnu/regexp/REMatch.html">REMatch</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RE.html#getMatch(java.lang.Object, int)">getMatch</A></B>(java.lang.Object input,
+ int index)</CODE>
+
+<BR>
+ Returns the first match found in the input, beginning
+ the search at the specified index.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE> <A HREF="../../gnu/regexp/REMatch.html">REMatch</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RE.html#getMatch(java.lang.Object, int, int)">getMatch</A></B>(java.lang.Object input,
+ int index,
+ int eflags)</CODE>
+
+<BR>
+ Returns the first match found in the input, beginning
+ the search at the specified index, and using the specified
+ execution flags.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE> <A HREF="../../gnu/regexp/REMatch.html">REMatch</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RE.html#getMatch(java.lang.Object, int, int, java.lang.StringBuffer)">getMatch</A></B>(java.lang.Object input,
+ int index,
+ int eflags,
+ java.lang.StringBuffer buffer)</CODE>
+
+<BR>
+ Returns the first match found in the input, beginning the search
+ at the specified index, and using the specified execution flags.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE> <A HREF="../../gnu/regexp/REMatchEnumeration.html">REMatchEnumeration</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RE.html#getMatchEnumeration(java.lang.Object)">getMatchEnumeration</A></B>(java.lang.Object input)</CODE>
+
+<BR>
+ Returns an REMatchEnumeration that can be used to iterate over the
+ matches found in the input text.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE> <A HREF="../../gnu/regexp/REMatchEnumeration.html">REMatchEnumeration</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RE.html#getMatchEnumeration(java.lang.Object, int)">getMatchEnumeration</A></B>(java.lang.Object input,
+ int index)</CODE>
+
+<BR>
+ Returns an REMatchEnumeration that can be used to iterate over the
+ matches found in the input text.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE> <A HREF="../../gnu/regexp/REMatchEnumeration.html">REMatchEnumeration</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RE.html#getMatchEnumeration(java.lang.Object, int, int)">getMatchEnumeration</A></B>(java.lang.Object input,
+ int index,
+ int eflags)</CODE>
+
+<BR>
+ Returns an REMatchEnumeration that can be used to iterate over the
+ matches found in the input text.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE> int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RE.html#getMinimumLength()">getMinimumLength</A></B>()</CODE>
+
+<BR>
+ Returns the minimum number of characters that could possibly
+ constitute a match of this regular expression.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE> int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RE.html#getNumSubs()">getNumSubs</A></B>()</CODE>
+
+<BR>
+ Returns the maximum number of subexpressions in this regular expression.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE> boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RE.html#isMatch(java.lang.Object)">isMatch</A></B>(java.lang.Object input)</CODE>
+
+<BR>
+ Checks if the regular expression matches the input in its entirety.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE> boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RE.html#isMatch(java.lang.Object, int)">isMatch</A></B>(java.lang.Object input,
+ int index)</CODE>
+
+<BR>
+ Checks if the input string, starting from index, is an exact match of
+ this regular expression.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE> boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RE.html#isMatch(java.lang.Object, int, int)">isMatch</A></B>(java.lang.Object input,
+ int index,
+ int eflags)</CODE>
+
+<BR>
+ Checks if the input, starting from index and using the specified
+ execution flags, is an exact match of this regular expression.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE> java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RE.html#substitute(java.lang.Object, java.lang.String)">substitute</A></B>(java.lang.Object input,
+ java.lang.String replace)</CODE>
+
+<BR>
+ Substitutes the replacement text for the first match found in the input.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE> java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RE.html#substitute(java.lang.Object, java.lang.String, int)">substitute</A></B>(java.lang.Object input,
+ java.lang.String replace,
+ int index)</CODE>
+
+<BR>
+ Substitutes the replacement text for the first match found in the input
+ beginning at the specified index position.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE> java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RE.html#substitute(java.lang.Object, java.lang.String, int, int)">substitute</A></B>(java.lang.Object input,
+ java.lang.String replace,
+ int index,
+ int eflags)</CODE>
+
+<BR>
+ Substitutes the replacement text for the first match found in the input
+ string, beginning at the specified index position and using the
+ specified execution flags.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE> java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RE.html#substituteAll(java.lang.Object, java.lang.String)">substituteAll</A></B>(java.lang.Object input,
+ java.lang.String replace)</CODE>
+
+<BR>
+ Substitutes the replacement text for each non-overlapping match found
+ in the input text.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE> java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RE.html#substituteAll(java.lang.Object, java.lang.String, int)">substituteAll</A></B>(java.lang.Object input,
+ java.lang.String replace,
+ int index)</CODE>
+
+<BR>
+ Substitutes the replacement text for each non-overlapping match found
+ in the input text, starting at the specified index.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE> java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RE.html#substituteAll(java.lang.Object, java.lang.String, int, int)">substituteAll</A></B>(java.lang.Object input,
+ java.lang.String replace,
+ int index,
+ int eflags)</CODE>
+
+<BR>
+ Substitutes the replacement text for each non-overlapping match found
+ in the input text, starting at the specified index and using the
+ specified execution flags.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE> java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RE.html#toString()">toString</A></B>()</CODE>
+
+<BR>
+ Return a human readable form of the compiled regular expression,
+ useful for debugging.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RE.html#version()">version</A></B>()</CODE>
+
+<BR>
+ Returns a string representing the version of the gnu.regexp package.</TD>
+</TR>
+</TABLE>
+ <A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Methods inherited from class java.lang.Object</B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>equals, getClass, hashCode, notify, notifyAll, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+<A NAME="field_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Field Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="REG_ICASE"><!-- --></A><H3>
+REG_ICASE</H3>
+<PRE>
+public static final int <B>REG_ICASE</B></PRE>
+<DL>
+<DD>Compilation flag. Do not differentiate case. Subsequent
+ searches using this RE will be case insensitive.</DL>
+<HR>
+
+<A NAME="REG_DOT_NEWLINE"><!-- --></A><H3>
+REG_DOT_NEWLINE</H3>
+<PRE>
+public static final int <B>REG_DOT_NEWLINE</B></PRE>
+<DL>
+<DD>Compilation flag. The match-any-character operator (dot)
+ will match a newline character. When set this overrides the syntax
+ bit RE_DOT_NEWLINE (see RESyntax for details). This is equivalent to
+ the "/s" operator in Perl.</DL>
+<HR>
+
+<A NAME="REG_MULTILINE"><!-- --></A><H3>
+REG_MULTILINE</H3>
+<PRE>
+public static final int <B>REG_MULTILINE</B></PRE>
+<DL>
+<DD>Compilation flag. Use multiline mode. In this mode, the ^ and $
+ anchors will match based on newlines within the input. This is
+ equivalent to the "/m" operator in Perl.</DL>
+<HR>
+
+<A NAME="REG_NOTBOL"><!-- --></A><H3>
+REG_NOTBOL</H3>
+<PRE>
+public static final int <B>REG_NOTBOL</B></PRE>
+<DL>
+<DD>Execution flag.
+ The match-beginning operator (^) will not match at the beginning
+ of the input string. Useful for matching on a substring when you
+ know the context of the input is such that position zero of the
+ input to the match test is not actually position zero of the text.
+ <P>
+ This example demonstrates the results of various ways of matching on
+ a substring.
+ <P>
+ <CODE>
+ String s = "food bar fool";<BR>
+ RE exp = new RE("^foo.");<BR>
+ REMatch m0 = exp.getMatch(s);<BR>
+ REMatch m1 = exp.getMatch(s.substring(8));<BR>
+ REMatch m2 = exp.getMatch(s.substring(8),0,RE.REG_NOTBOL); <BR>
+ REMatch m3 = exp.getMatch(s,8); <BR>
+ REMatch m4 = exp.getMatch(s,8,RE.REG_ANCHORINDEX); <BR>
+ <P>
+ // Results:<BR>
+ // m0 = "food"<BR>
+ // m1 = "fool"<BR>
+ // m2 = null<BR>
+ // m3 = null<BR>
+ // m4 = "fool"<BR>
+ </CODE></DL>
+<HR>
+
+<A NAME="REG_NOTEOL"><!-- --></A><H3>
+REG_NOTEOL</H3>
+<PRE>
+public static final int <B>REG_NOTEOL</B></PRE>
+<DL>
+<DD>Execution flag.
+ The match-end operator ($) does not match at the end
+ of the input string. Useful for matching on substrings.</DL>
+<HR>
+
+<A NAME="REG_ANCHORINDEX"><!-- --></A><H3>
+REG_ANCHORINDEX</H3>
+<PRE>
+public static final int <B>REG_ANCHORINDEX</B></PRE>
+<DL>
+<DD>Execution flag.
+ When a match method is invoked that starts matching at a non-zero
+ index into the input, treat the input as if it begins at the index
+ given. The effect of this flag is that the engine does not "see"
+ any text in the input before the given index. This is useful so
+ that the match-beginning operator (^) matches not at position 0
+ in the input string, but at the position the search started at
+ (based on the index input given to the getMatch function). See
+ the example under REG_NOTBOL. It also affects the use of the \<
+ and \b operators.</DL>
+<HR>
+
+<A NAME="REG_NO_INTERPOLATE"><!-- --></A><H3>
+REG_NO_INTERPOLATE</H3>
+<PRE>
+public static final int <B>REG_NO_INTERPOLATE</B></PRE>
+<DL>
+<DD>Execution flag.
+ The substitute and substituteAll methods will not attempt to
+ interpolate occurrences of $1-$9 in the replacement text with
+ the corresponding subexpressions. For example, you may want to
+ replace all matches of "one dollar" with "$1".</DL>
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="RE(java.lang.Object)"><!-- --></A><H3>
+RE</H3>
+<PRE>
+public <B>RE</B>(java.lang.Object pattern)
+ throws <A HREF="../../gnu/regexp/REException.html">REException</A></PRE>
+<DL>
+<DD>Constructs a regular expression pattern buffer without any compilation
+ flags set, and using the default syntax (RESyntax.RE_SYNTAX_PERL5).<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>pattern</CODE> - A regular expression pattern, in the form of a String,
+ StringBuffer or char[]. Other input types will be converted to
+ strings using the toString() method.<DT><B>Throws:</B><DD><CODE><A HREF="../../gnu/regexp/REException.html">REException</A></CODE> - The input pattern could not be parsed.<DD><CODE>NullPointerException</CODE> - The pattern was null.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="RE(java.lang.Object, int)"><!-- --></A><H3>
+RE</H3>
+<PRE>
+public <B>RE</B>(java.lang.Object pattern,
+ int cflags)
+ throws <A HREF="../../gnu/regexp/REException.html">REException</A></PRE>
+<DL>
+<DD>Constructs a regular expression pattern buffer using the specified
+ compilation flags and the default syntax (RESyntax.RE_SYNTAX_PERL5).<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>pattern</CODE> - A regular expression pattern, in the form of a String,
+ StringBuffer, or char[]. Other input types will be converted to
+ strings using the toString() method.<DD><CODE>cflags</CODE> - The logical OR of any combination of the compilation flags listed above.<DT><B>Throws:</B><DD><CODE><A HREF="../../gnu/regexp/REException.html">REException</A></CODE> - The input pattern could not be parsed.<DD><CODE>NullPointerException</CODE> - The pattern was null.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="RE(java.lang.Object, int, gnu.regexp.RESyntax)"><!-- --></A><H3>
+RE</H3>
+<PRE>
+public <B>RE</B>(java.lang.Object pattern,
+ int cflags,
+ <A HREF="../../gnu/regexp/RESyntax.html">RESyntax</A> syntax)
+ throws <A HREF="../../gnu/regexp/REException.html">REException</A></PRE>
+<DL>
+<DD>Constructs a regular expression pattern buffer using the specified
+ compilation flags and regular expression syntax.<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>pattern</CODE> - A regular expression pattern, in the form of a String,
+ StringBuffer, or char[]. Other input types will be converted to
+ strings using the toString() method.<DD><CODE>cflags</CODE> - The logical OR of any combination of the compilation flags listed above.<DD><CODE>syntax</CODE> - The type of regular expression syntax to use.<DT><B>Throws:</B><DD><CODE><A HREF="../../gnu/regexp/REException.html">REException</A></CODE> - The input pattern could not be parsed.<DD><CODE>NullPointerException</CODE> - The pattern was null.</DL>
+</DD>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="version()"><!-- --></A><H3>
+version</H3>
+<PRE>
+public static final java.lang.String <B>version</B>()</PRE>
+<DL>
+<DD>Returns a string representing the version of the gnu.regexp package.</DL>
+<HR>
+
+<A NAME="isMatch(java.lang.Object)"><!-- --></A><H3>
+isMatch</H3>
+<PRE>
+public boolean <B>isMatch</B>(java.lang.Object input)</PRE>
+<DL>
+<DD>Checks if the regular expression matches the input in its entirety.<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>input</CODE> - The input text.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isMatch(java.lang.Object, int)"><!-- --></A><H3>
+isMatch</H3>
+<PRE>
+public boolean <B>isMatch</B>(java.lang.Object input,
+ int index)</PRE>
+<DL>
+<DD>Checks if the input string, starting from index, is an exact match of
+ this regular expression.<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>input</CODE> - The input text.<DD><CODE>index</CODE> - The offset index at which the search should be begin.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="isMatch(java.lang.Object, int, int)"><!-- --></A><H3>
+isMatch</H3>
+<PRE>
+public boolean <B>isMatch</B>(java.lang.Object input,
+ int index,
+ int eflags)</PRE>
+<DL>
+<DD>Checks if the input, starting from index and using the specified
+ execution flags, is an exact match of this regular expression.<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>input</CODE> - The input text.<DD><CODE>index</CODE> - The offset index at which the search should be begin.<DD><CODE>eflags</CODE> - The logical OR of any execution flags above.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getNumSubs()"><!-- --></A><H3>
+getNumSubs</H3>
+<PRE>
+public int <B>getNumSubs</B>()</PRE>
+<DL>
+<DD>Returns the maximum number of subexpressions in this regular expression.
+ If the expression contains branches, the value returned will be the
+ maximum subexpressions in any of the branches.</DL>
+<HR>
+
+<A NAME="getMinimumLength()"><!-- --></A><H3>
+getMinimumLength</H3>
+<PRE>
+public int <B>getMinimumLength</B>()</PRE>
+<DL>
+<DD>Returns the minimum number of characters that could possibly
+ constitute a match of this regular expression.</DL>
+<HR>
+
+<A NAME="getAllMatches(java.lang.Object)"><!-- --></A><H3>
+getAllMatches</H3>
+<PRE>
+public <A HREF="../../gnu/regexp/REMatch.html">REMatch</A>[] <B>getAllMatches</B>(java.lang.Object input)</PRE>
+<DL>
+<DD>Returns an array of all matches found in the input.
+
+ If the regular expression allows the empty string to match, it will
+ substitute matches at all positions except the end of the input.<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>input</CODE> - The input text.<DT><B>Returns:</B><DD>a non-null (but possibly zero-length) array of matches</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getAllMatches(java.lang.Object, int)"><!-- --></A><H3>
+getAllMatches</H3>
+<PRE>
+public <A HREF="../../gnu/regexp/REMatch.html">REMatch</A>[] <B>getAllMatches</B>(java.lang.Object input,
+ int index)</PRE>
+<DL>
+<DD>Returns an array of all matches found in the input,
+ beginning at the specified index position.
+
+ If the regular expression allows the empty string to match, it will
+ substitute matches at all positions except the end of the input.<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>input</CODE> - The input text.<DD><CODE>index</CODE> - The offset index at which the search should be begin.<DT><B>Returns:</B><DD>a non-null (but possibly zero-length) array of matches</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getAllMatches(java.lang.Object, int, int)"><!-- --></A><H3>
+getAllMatches</H3>
+<PRE>
+public <A HREF="../../gnu/regexp/REMatch.html">REMatch</A>[] <B>getAllMatches</B>(java.lang.Object input,
+ int index,
+ int eflags)</PRE>
+<DL>
+<DD>Returns an array of all matches found in the input string,
+ beginning at the specified index position and using the specified
+ execution flags.
+
+ If the regular expression allows the empty string to match, it will
+ substitute matches at all positions except the end of the input.<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>input</CODE> - The input text.<DD><CODE>index</CODE> - The offset index at which the search should be begin.<DD><CODE>eflags</CODE> - The logical OR of any execution flags above.<DT><B>Returns:</B><DD>a non-null (but possibly zero-length) array of matches</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getMatch(java.lang.Object)"><!-- --></A><H3>
+getMatch</H3>
+<PRE>
+public <A HREF="../../gnu/regexp/REMatch.html">REMatch</A> <B>getMatch</B>(java.lang.Object input)</PRE>
+<DL>
+<DD>Returns the first match found in the input. If no match is found,
+ null is returned.<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>input</CODE> - The input text.<DT><B>Returns:</B><DD>An REMatch instance referencing the match, or null if none.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getMatch(java.lang.Object, int)"><!-- --></A><H3>
+getMatch</H3>
+<PRE>
+public <A HREF="../../gnu/regexp/REMatch.html">REMatch</A> <B>getMatch</B>(java.lang.Object input,
+ int index)</PRE>
+<DL>
+<DD>Returns the first match found in the input, beginning
+ the search at the specified index. If no match is found,
+ returns null.<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>input</CODE> - The input text.<DD><CODE>index</CODE> - The offset within the text to begin looking for a match.<DT><B>Returns:</B><DD>An REMatch instance referencing the match, or null if none.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getMatch(java.lang.Object, int, int)"><!-- --></A><H3>
+getMatch</H3>
+<PRE>
+public <A HREF="../../gnu/regexp/REMatch.html">REMatch</A> <B>getMatch</B>(java.lang.Object input,
+ int index,
+ int eflags)</PRE>
+<DL>
+<DD>Returns the first match found in the input, beginning
+ the search at the specified index, and using the specified
+ execution flags. If no match is found, returns null.<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>input</CODE> - The input text.<DD><CODE>index</CODE> - The offset index at which the search should be begin.<DD><CODE>eflags</CODE> - The logical OR of any execution flags above.<DT><B>Returns:</B><DD>An REMatch instance referencing the match, or null if none.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getMatch(java.lang.Object, int, int, java.lang.StringBuffer)"><!-- --></A><H3>
+getMatch</H3>
+<PRE>
+public <A HREF="../../gnu/regexp/REMatch.html">REMatch</A> <B>getMatch</B>(java.lang.Object input,
+ int index,
+ int eflags,
+ java.lang.StringBuffer buffer)</PRE>
+<DL>
+<DD>Returns the first match found in the input, beginning the search
+ at the specified index, and using the specified execution flags.
+ If no match is found, returns null. If a StringBuffer is
+ provided and is non-null, the contents of the input text from the
+ index to the beginning of the match (or to the end of the input,
+ if there is no match) are appended to the StringBuffer.<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>input</CODE> - The input text.<DD><CODE>index</CODE> - The offset index at which the search should be begin.<DD><CODE>eflags</CODE> - The logical OR of any execution flags above.<DD><CODE>buffer</CODE> - The StringBuffer to save pre-match text in.<DT><B>Returns:</B><DD>An REMatch instance referencing the match, or null if none.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getMatchEnumeration(java.lang.Object)"><!-- --></A><H3>
+getMatchEnumeration</H3>
+<PRE>
+public <A HREF="../../gnu/regexp/REMatchEnumeration.html">REMatchEnumeration</A> <B>getMatchEnumeration</B>(java.lang.Object input)</PRE>
+<DL>
+<DD>Returns an REMatchEnumeration that can be used to iterate over the
+ matches found in the input text.<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>input</CODE> - The input text.<DT><B>Returns:</B><DD>A non-null REMatchEnumeration instance.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getMatchEnumeration(java.lang.Object, int)"><!-- --></A><H3>
+getMatchEnumeration</H3>
+<PRE>
+public <A HREF="../../gnu/regexp/REMatchEnumeration.html">REMatchEnumeration</A> <B>getMatchEnumeration</B>(java.lang.Object input,
+ int index)</PRE>
+<DL>
+<DD>Returns an REMatchEnumeration that can be used to iterate over the
+ matches found in the input text.<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>input</CODE> - The input text.<DD><CODE>index</CODE> - The offset index at which the search should be begin.<DT><B>Returns:</B><DD>A non-null REMatchEnumeration instance, with its input cursor
+ set to the index position specified.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getMatchEnumeration(java.lang.Object, int, int)"><!-- --></A><H3>
+getMatchEnumeration</H3>
+<PRE>
+public <A HREF="../../gnu/regexp/REMatchEnumeration.html">REMatchEnumeration</A> <B>getMatchEnumeration</B>(java.lang.Object input,
+ int index,
+ int eflags)</PRE>
+<DL>
+<DD>Returns an REMatchEnumeration that can be used to iterate over the
+ matches found in the input text.<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>input</CODE> - The input text.<DD><CODE>index</CODE> - The offset index at which the search should be begin.<DD><CODE>eflags</CODE> - The logical OR of any execution flags above.<DT><B>Returns:</B><DD>A non-null REMatchEnumeration instance, with its input cursor
+ set to the index position specified.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="substitute(java.lang.Object, java.lang.String)"><!-- --></A><H3>
+substitute</H3>
+<PRE>
+public java.lang.String <B>substitute</B>(java.lang.Object input,
+ java.lang.String replace)</PRE>
+<DL>
+<DD>Substitutes the replacement text for the first match found in the input.<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>input</CODE> - The input text.<DD><CODE>replace</CODE> - The replacement text, which may contain $x metacharacters (see REMatch.substituteInto).<DT><B>Returns:</B><DD>A String interpolating the substituted text.<DT><B>See Also: </B><DD><A HREF="../../gnu/regexp/REMatch.html#substituteInto(java.lang.String)"><CODE>REMatch.substituteInto(java.lang.String)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="substitute(java.lang.Object, java.lang.String, int)"><!-- --></A><H3>
+substitute</H3>
+<PRE>
+public java.lang.String <B>substitute</B>(java.lang.Object input,
+ java.lang.String replace,
+ int index)</PRE>
+<DL>
+<DD>Substitutes the replacement text for the first match found in the input
+ beginning at the specified index position. Specifying an index
+ effectively causes the regular expression engine to throw away the
+ specified number of characters.<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>input</CODE> - The input text.<DD><CODE>replace</CODE> - The replacement text, which may contain $x metacharacters (see REMatch.substituteInto).<DD><CODE>index</CODE> - The offset index at which the search should be begin.<DT><B>Returns:</B><DD>A String containing the substring of the input, starting
+ at the index position, and interpolating the substituted text.<DT><B>See Also: </B><DD><A HREF="../../gnu/regexp/REMatch.html#substituteInto(java.lang.String)"><CODE>REMatch.substituteInto(java.lang.String)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="substitute(java.lang.Object, java.lang.String, int, int)"><!-- --></A><H3>
+substitute</H3>
+<PRE>
+public java.lang.String <B>substitute</B>(java.lang.Object input,
+ java.lang.String replace,
+ int index,
+ int eflags)</PRE>
+<DL>
+<DD>Substitutes the replacement text for the first match found in the input
+ string, beginning at the specified index position and using the
+ specified execution flags.<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>input</CODE> - The input text.<DD><CODE>replace</CODE> - The replacement text, which may contain $x metacharacters (see REMatch.substituteInto).<DD><CODE>index</CODE> - The offset index at which the search should be begin.<DD><CODE>eflags</CODE> - The logical OR of any execution flags above.<DT><B>Returns:</B><DD>A String containing the substring of the input, starting
+ at the index position, and interpolating the substituted text.<DT><B>See Also: </B><DD><A HREF="../../gnu/regexp/REMatch.html#substituteInto(java.lang.String)"><CODE>REMatch.substituteInto(java.lang.String)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="substituteAll(java.lang.Object, java.lang.String)"><!-- --></A><H3>
+substituteAll</H3>
+<PRE>
+public java.lang.String <B>substituteAll</B>(java.lang.Object input,
+ java.lang.String replace)</PRE>
+<DL>
+<DD>Substitutes the replacement text for each non-overlapping match found
+ in the input text.<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>input</CODE> - The input text.<DD><CODE>replace</CODE> - The replacement text, which may contain $x metacharacters (see REMatch.substituteInto).<DT><B>Returns:</B><DD>A String interpolating the substituted text.<DT><B>See Also: </B><DD><A HREF="../../gnu/regexp/REMatch.html#substituteInto(java.lang.String)"><CODE>REMatch.substituteInto(java.lang.String)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="substituteAll(java.lang.Object, java.lang.String, int)"><!-- --></A><H3>
+substituteAll</H3>
+<PRE>
+public java.lang.String <B>substituteAll</B>(java.lang.Object input,
+ java.lang.String replace,
+ int index)</PRE>
+<DL>
+<DD>Substitutes the replacement text for each non-overlapping match found
+ in the input text, starting at the specified index.
+
+ If the regular expression allows the empty string to match, it will
+ substitute matches at all positions except the end of the input.<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>input</CODE> - The input text.<DD><CODE>replace</CODE> - The replacement text, which may contain $x metacharacters (see REMatch.substituteInto).<DD><CODE>index</CODE> - The offset index at which the search should be begin.<DT><B>Returns:</B><DD>A String containing the substring of the input, starting
+ at the index position, and interpolating the substituted text.<DT><B>See Also: </B><DD><A HREF="../../gnu/regexp/REMatch.html#substituteInto(java.lang.String)"><CODE>REMatch.substituteInto(java.lang.String)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="substituteAll(java.lang.Object, java.lang.String, int, int)"><!-- --></A><H3>
+substituteAll</H3>
+<PRE>
+public java.lang.String <B>substituteAll</B>(java.lang.Object input,
+ java.lang.String replace,
+ int index,
+ int eflags)</PRE>
+<DL>
+<DD>Substitutes the replacement text for each non-overlapping match found
+ in the input text, starting at the specified index and using the
+ specified execution flags.<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>input</CODE> - The input text.<DD><CODE>replace</CODE> - The replacement text, which may contain $x metacharacters (see REMatch.substituteInto).<DD><CODE>index</CODE> - The offset index at which the search should be begin.<DD><CODE>eflags</CODE> - The logical OR of any execution flags above.<DT><B>Returns:</B><DD>A String containing the substring of the input, starting
+ at the index position, and interpolating the substituted text.<DT><B>See Also: </B><DD><A HREF="../../gnu/regexp/REMatch.html#substituteInto(java.lang.String)"><CODE>REMatch.substituteInto(java.lang.String)</CODE></A></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="toString()"><!-- --></A><H3>
+toString</H3>
+<PRE>
+public java.lang.String <B>toString</B>()</PRE>
+<DL>
+<DD>Return a human readable form of the compiled regular expression,
+ useful for debugging.<DD><DL>
+<DT><B>Overrides:</B><DD><CODE>toString</CODE> in class <CODE>java.lang.Object</CODE></DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A> </TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> <FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A> </TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ PREV CLASS
+ <A HREF="../../gnu/regexp/REFilterInputStream.html"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../index.html" TARGET="_top"><B>FRAMES</B></A>
+ <A HREF="RE.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: INNER | <A HREF="#field_summary">FIELD</A> | <A HREF="#constructor_summary">CONSTR</A> | <A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: <A HREF="#field_detail">FIELD</A> | <A HREF="#constructor_detail">CONSTR</A> | <A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Sun Oct 21 14:27:46 PDT 2001 -->
+<TITLE>
+: Class REException
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A> </TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> <FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A> </TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ PREV CLASS
+ NEXT CLASS</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../index.html" TARGET="_top"><B>FRAMES</B></A>
+ <A HREF="REException.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: INNER | <A HREF="#field_summary">FIELD</A> | CONSTR | <A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: <A HREF="#field_detail">FIELD</A> | CONSTR | <A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+gnu.regexp</FONT>
+<BR>
+Class REException</H2>
+<PRE>
+java.lang.Object
+ |
+ +--java.lang.Throwable
+ |
+ +--java.lang.Exception
+ |
+ +--<B>gnu.regexp.REException</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD>java.io.Serializable</DD>
+</DL>
+<HR>
+<DL>
+<DT>public class <B>REException</B><DT>extends java.lang.Exception</DL>
+
+<P>
+This is the regular expression exception class. An exception of this type
+ defines the three attributes:
+ <OL>
+ <LI> A descriptive message of the error.
+ <LI> An integral type code equivalent to one of the statically
+ defined symbols listed below.
+ <LI> The approximate position in the input string where the error
+ occurred.
+ </OL>
+<P>
+<DL>
+<DT><B>Author: </B><DD><A HREF="mailto:wes@cacas.org">Wes Biggs</A></DD>
+<DT><B>See Also: </B><DD><A HREF="../../serialized-form.html#gnu.regexp.REException">Serialized Form</A></DL>
+<HR>
+
+<P>
+<!-- ======== INNER CLASS SUMMARY ======== -->
+
+
+<!-- =========== FIELD SUMMARY =========== -->
+
+<A NAME="field_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Field Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/REException.html#REG_BADBR">REG_BADBR</A></B></CODE>
+
+<BR>
+ Error flag.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/REException.html#REG_BADPAT">REG_BADPAT</A></B></CODE>
+
+<BR>
+ Error flag.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/REException.html#REG_BADRPT">REG_BADRPT</A></B></CODE>
+
+<BR>
+ Error flag.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/REException.html#REG_EBRACE">REG_EBRACE</A></B></CODE>
+
+<BR>
+ Error flag.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/REException.html#REG_EBRACK">REG_EBRACK</A></B></CODE>
+
+<BR>
+ Error flag.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/REException.html#REG_ECTYPE">REG_ECTYPE</A></B></CODE>
+
+<BR>
+ Error flag.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/REException.html#REG_EEND">REG_EEND</A></B></CODE>
+
+<BR>
+ Error flag.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/REException.html#REG_EPAREN">REG_EPAREN</A></B></CODE>
+
+<BR>
+ Error flag.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/REException.html#REG_ERANGE">REG_ERANGE</A></B></CODE>
+
+<BR>
+ Error flag.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/REException.html#REG_ESCAPE">REG_ESCAPE</A></B></CODE>
+
+<BR>
+ Error flag.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/REException.html#REG_ESIZE">REG_ESIZE</A></B></CODE>
+
+<BR>
+ Error flag.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/REException.html#REG_ESPACE">REG_ESPACE</A></B></CODE>
+
+<BR>
+ Error flag.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/REException.html#REG_ESUBREG">REG_ESUBREG</A></B></CODE>
+
+<BR>
+ Error flag.</TD>
+</TR>
+</TABLE>
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE> java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/REException.html#getMessage()">getMessage</A></B>()</CODE>
+
+<BR>
+ Reports the descriptive message associated with this exception
+ as well as its index position in the string or character array
+ being compiled.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE> int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/REException.html#getPosition()">getPosition</A></B>()</CODE>
+
+<BR>
+ Returns the position, relative to the string or character array being
+ compiled, where the error occurred.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE> int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/REException.html#getType()">getType</A></B>()</CODE>
+
+<BR>
+ Returns the type of the exception, one of the constants listed above.</TD>
+</TR>
+</TABLE>
+ <A NAME="methods_inherited_from_class_java.lang.Throwable"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Methods inherited from class java.lang.Throwable</B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>fillInStackTrace, getLocalizedMessage, printStackTrace, printStackTrace, printStackTrace, toString</CODE></TD>
+</TR>
+</TABLE>
+ <A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Methods inherited from class java.lang.Object</B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>equals, getClass, hashCode, notify, notifyAll, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+<A NAME="field_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Field Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="REG_BADRPT"><!-- --></A><H3>
+REG_BADRPT</H3>
+<PRE>
+public static final int <B>REG_BADRPT</B></PRE>
+<DL>
+<DD>Error flag.
+ Invalid use of repetition operators such as using
+ `*' as the first character.</DL>
+<HR>
+
+<A NAME="REG_BADBR"><!-- --></A><H3>
+REG_BADBR</H3>
+<PRE>
+public static final int <B>REG_BADBR</B></PRE>
+<DL>
+<DD>Error flag.
+ Invalid use of back reference operator.</DL>
+<HR>
+
+<A NAME="REG_EBRACE"><!-- --></A><H3>
+REG_EBRACE</H3>
+<PRE>
+public static final int <B>REG_EBRACE</B></PRE>
+<DL>
+<DD>Error flag.
+ Un-matched brace interval operators.</DL>
+<HR>
+
+<A NAME="REG_EBRACK"><!-- --></A><H3>
+REG_EBRACK</H3>
+<PRE>
+public static final int <B>REG_EBRACK</B></PRE>
+<DL>
+<DD>Error flag.
+ Un-matched bracket list operators.</DL>
+<HR>
+
+<A NAME="REG_ERANGE"><!-- --></A><H3>
+REG_ERANGE</H3>
+<PRE>
+public static final int <B>REG_ERANGE</B></PRE>
+<DL>
+<DD>Error flag.
+ Invalid use of the range operator, eg. the ending
+ point of the range occurs prior to the starting
+ point.</DL>
+<HR>
+
+<A NAME="REG_ECTYPE"><!-- --></A><H3>
+REG_ECTYPE</H3>
+<PRE>
+public static final int <B>REG_ECTYPE</B></PRE>
+<DL>
+<DD>Error flag.
+ Unknown character class name. <B>Not implemented</B>.</DL>
+<HR>
+
+<A NAME="REG_EPAREN"><!-- --></A><H3>
+REG_EPAREN</H3>
+<PRE>
+public static final int <B>REG_EPAREN</B></PRE>
+<DL>
+<DD>Error flag.
+ Un-matched parenthesis group operators.</DL>
+<HR>
+
+<A NAME="REG_ESUBREG"><!-- --></A><H3>
+REG_ESUBREG</H3>
+<PRE>
+public static final int <B>REG_ESUBREG</B></PRE>
+<DL>
+<DD>Error flag.
+ Invalid back reference to a subexpression.</DL>
+<HR>
+
+<A NAME="REG_EEND"><!-- --></A><H3>
+REG_EEND</H3>
+<PRE>
+public static final int <B>REG_EEND</B></PRE>
+<DL>
+<DD>Error flag.
+ Non specific error. <B>Not implemented</B>.</DL>
+<HR>
+
+<A NAME="REG_ESCAPE"><!-- --></A><H3>
+REG_ESCAPE</H3>
+<PRE>
+public static final int <B>REG_ESCAPE</B></PRE>
+<DL>
+<DD>Error flag.
+ Invalid escape sequence. <B>Not implemented</B>.</DL>
+<HR>
+
+<A NAME="REG_BADPAT"><!-- --></A><H3>
+REG_BADPAT</H3>
+<PRE>
+public static final int <B>REG_BADPAT</B></PRE>
+<DL>
+<DD>Error flag.
+ Invalid use of pattern operators such as group or list.</DL>
+<HR>
+
+<A NAME="REG_ESIZE"><!-- --></A><H3>
+REG_ESIZE</H3>
+<PRE>
+public static final int <B>REG_ESIZE</B></PRE>
+<DL>
+<DD>Error flag.
+ Compiled regular expression requires a pattern
+ buffer larger than 64Kb. <B>Not implemented</B>.</DL>
+<HR>
+
+<A NAME="REG_ESPACE"><!-- --></A><H3>
+REG_ESPACE</H3>
+<PRE>
+public static final int <B>REG_ESPACE</B></PRE>
+<DL>
+<DD>Error flag.
+ The regex routines ran out of memory. <B>Not implemented</B>.</DL>
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="getType()"><!-- --></A><H3>
+getType</H3>
+<PRE>
+public int <B>getType</B>()</PRE>
+<DL>
+<DD>Returns the type of the exception, one of the constants listed above.</DL>
+<HR>
+
+<A NAME="getPosition()"><!-- --></A><H3>
+getPosition</H3>
+<PRE>
+public int <B>getPosition</B>()</PRE>
+<DL>
+<DD>Returns the position, relative to the string or character array being
+ compiled, where the error occurred. This position is generally the point
+ where the error was detected, not necessarily the starting index of
+ a bad subexpression.</DL>
+<HR>
+
+<A NAME="getMessage()"><!-- --></A><H3>
+getMessage</H3>
+<PRE>
+public java.lang.String <B>getMessage</B>()</PRE>
+<DL>
+<DD>Reports the descriptive message associated with this exception
+ as well as its index position in the string or character array
+ being compiled.<DD><DL>
+<DT><B>Overrides:</B><DD><CODE>getMessage</CODE> in class <CODE>java.lang.Throwable</CODE></DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A> </TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> <FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A> </TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ PREV CLASS
+ NEXT CLASS</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../index.html" TARGET="_top"><B>FRAMES</B></A>
+ <A HREF="REException.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: INNER | <A HREF="#field_summary">FIELD</A> | CONSTR | <A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: <A HREF="#field_detail">FIELD</A> | CONSTR | <A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Sun Oct 21 14:27:45 PDT 2001 -->
+<TITLE>
+: Class REFilterInputStream
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A> </TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> <FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A> </TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../gnu/regexp/RE.html"><B>PREV CLASS</B></A>
+ <A HREF="../../gnu/regexp/REFilterReader.html"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../index.html" TARGET="_top"><B>FRAMES</B></A>
+ <A HREF="REFilterInputStream.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: INNER | FIELD | <A HREF="#constructor_summary">CONSTR</A> | <A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: FIELD | <A HREF="#constructor_detail">CONSTR</A> | <A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+gnu.regexp</FONT>
+<BR>
+Class REFilterInputStream</H2>
+<PRE>
+java.lang.Object
+ |
+ +--java.io.InputStream
+ |
+ +--java.io.FilterInputStream
+ |
+ +--<B>gnu.regexp.REFilterInputStream</B>
+</PRE>
+<HR>
+<B>Deprecated.</B> <I>This class cannot properly handle all character
+ encodings. For proper handling, use the REFilterReader
+ class instead.</I>
+<P>
+<DL>
+<DT>public class <B>REFilterInputStream</B><DT>extends java.io.FilterInputStream</DL>
+
+<P>
+Replaces instances of a given RE found within an InputStream
+ with replacement text. The replacements are interpolated into the
+ stream when a match is found.
+<P>
+<DL>
+<DT><B>Author: </B><DD><A HREF="mailto:wes@cacas.org">Wes Biggs</A></DD>
+</DL>
+<HR>
+
+<P>
+<!-- ======== INNER CLASS SUMMARY ======== -->
+
+
+<!-- =========== FIELD SUMMARY =========== -->
+
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../gnu/regexp/REFilterInputStream.html#REFilterInputStream(java.io.InputStream, gnu.regexp.RE, java.lang.String)">REFilterInputStream</A></B>(java.io.InputStream stream,
+ <A HREF="../../gnu/regexp/RE.html">RE</A> expr,
+ java.lang.String replace)</CODE>
+
+<BR>
+ <B>Deprecated.</B> Creates an REFilterInputStream.</TD>
+</TR>
+</TABLE>
+
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE> boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/REFilterInputStream.html#markSupported()">markSupported</A></B>()</CODE>
+
+<BR>
+ <B>Deprecated.</B> Returns false.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE> int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/REFilterInputStream.html#read()">read</A></B>()</CODE>
+
+<BR>
+ <B>Deprecated.</B> Reads the next byte from the stream per the general contract of
+ InputStream.read().</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE> int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/REFilterInputStream.html#read(byte[])">read</A></B>(byte[] b)</CODE>
+
+<BR>
+ <B>Deprecated.</B> Reads from the stream into the provided array.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE> int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/REFilterInputStream.html#read(byte[], int, int)">read</A></B>(byte[] b,
+ int off,
+ int len)</CODE>
+
+<BR>
+ <B>Deprecated.</B> Reads from the stream into the provided array.</TD>
+</TR>
+</TABLE>
+ <A NAME="methods_inherited_from_class_java.io.FilterInputStream"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Methods inherited from class java.io.FilterInputStream</B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>available, close, mark, reset, skip</CODE></TD>
+</TR>
+</TABLE>
+ <A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Methods inherited from class java.lang.Object</B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="REFilterInputStream(java.io.InputStream, gnu.regexp.RE, java.lang.String)"><!-- --></A><H3>
+REFilterInputStream</H3>
+<PRE>
+public <B>REFilterInputStream</B>(java.io.InputStream stream,
+ <A HREF="../../gnu/regexp/RE.html">RE</A> expr,
+ java.lang.String replace)</PRE>
+<DL>
+<DD><B>Deprecated.</B> <DD>Creates an REFilterInputStream. When reading from this stream,
+ occurrences of patterns matching the supplied regular expression
+ will be replaced with the supplied replacement text (the
+ metacharacters $0 through $9 may be used to refer to the full
+ match or subexpression matches).<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>stream</CODE> - The InputStream to be filtered.<DD><CODE>expr</CODE> - The regular expression to search for.<DD><CODE>replace</CODE> - The text pattern to replace matches with.</DL>
+</DD>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="read()"><!-- --></A><H3>
+read</H3>
+<PRE>
+public int <B>read</B>()</PRE>
+<DL>
+<DD><B>Deprecated.</B> <DD>Reads the next byte from the stream per the general contract of
+ InputStream.read(). Returns -1 on error or end of stream.<DD><DL>
+<DT><B>Overrides:</B><DD><CODE>read</CODE> in class <CODE>java.io.FilterInputStream</CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="markSupported()"><!-- --></A><H3>
+markSupported</H3>
+<PRE>
+public boolean <B>markSupported</B>()</PRE>
+<DL>
+<DD><B>Deprecated.</B> <DD>Returns false. REFilterInputStream does not support mark() and
+ reset() methods.<DD><DL>
+<DT><B>Overrides:</B><DD><CODE>markSupported</CODE> in class <CODE>java.io.FilterInputStream</CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="read(byte[], int, int)"><!-- --></A><H3>
+read</H3>
+<PRE>
+public int <B>read</B>(byte[] b,
+ int off,
+ int len)</PRE>
+<DL>
+<DD><B>Deprecated.</B> <DD>Reads from the stream into the provided array.<DD><DL>
+<DT><B>Overrides:</B><DD><CODE>read</CODE> in class <CODE>java.io.FilterInputStream</CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="read(byte[])"><!-- --></A><H3>
+read</H3>
+<PRE>
+public int <B>read</B>(byte[] b)</PRE>
+<DL>
+<DD><B>Deprecated.</B> <DD>Reads from the stream into the provided array.<DD><DL>
+<DT><B>Overrides:</B><DD><CODE>read</CODE> in class <CODE>java.io.FilterInputStream</CODE></DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A> </TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> <FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A> </TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../gnu/regexp/RE.html"><B>PREV CLASS</B></A>
+ <A HREF="../../gnu/regexp/REFilterReader.html"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../index.html" TARGET="_top"><B>FRAMES</B></A>
+ <A HREF="REFilterInputStream.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: INNER | FIELD | <A HREF="#constructor_summary">CONSTR</A> | <A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: FIELD | <A HREF="#constructor_detail">CONSTR</A> | <A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Sun Oct 21 14:27:45 PDT 2001 -->
+<TITLE>
+: Class REFilterReader
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A> </TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> <FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A> </TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../gnu/regexp/REFilterInputStream.html"><B>PREV CLASS</B></A>
+ <A HREF="../../gnu/regexp/REMatch.html"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../index.html" TARGET="_top"><B>FRAMES</B></A>
+ <A HREF="REFilterReader.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: INNER | FIELD | <A HREF="#constructor_summary">CONSTR</A> | <A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: FIELD | <A HREF="#constructor_detail">CONSTR</A> | <A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+gnu.regexp</FONT>
+<BR>
+Class REFilterReader</H2>
+<PRE>
+java.lang.Object
+ |
+ +--java.io.Reader
+ |
+ +--java.io.FilterReader
+ |
+ +--<B>gnu.regexp.REFilterReader</B>
+</PRE>
+<HR>
+<DL>
+<DT>public class <B>REFilterReader</B><DT>extends java.io.FilterReader</DL>
+
+<P>
+Replaces instances of a given RE with replacement text.
+<P>
+<DL>
+<DT><B>Since: </B><DD>gnu.regexp 1.1.0</DD>
+<DT><B>Author: </B><DD><A HREF="http://www.csis.hku.hk/~sdlee/">Lee Sau Dan</A></DD>
+</DL>
+<HR>
+
+<P>
+<!-- ======== INNER CLASS SUMMARY ======== -->
+
+
+<!-- =========== FIELD SUMMARY =========== -->
+
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../gnu/regexp/REFilterReader.html#REFilterReader(java.io.Reader, gnu.regexp.RE, java.lang.String)">REFilterReader</A></B>(java.io.Reader stream,
+ <A HREF="../../gnu/regexp/RE.html">RE</A> expr,
+ java.lang.String replace)</CODE>
+
+<BR>
+ Creates an REFilterReader.</TD>
+</TR>
+</TABLE>
+
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE> boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/REFilterReader.html#markSupported()">markSupported</A></B>()</CODE>
+
+<BR>
+ Returns false.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE> int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/REFilterReader.html#read()">read</A></B>()</CODE>
+
+<BR>
+ Reads the next character from the stream per the general contract of
+ Reader.read().</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE> int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/REFilterReader.html#read(char[])">read</A></B>(char[] b)</CODE>
+
+<BR>
+ Reads from the stream into the provided array.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE> int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/REFilterReader.html#read(char[], int, int)">read</A></B>(char[] b,
+ int off,
+ int len)</CODE>
+
+<BR>
+ Reads from the stream into the provided array.</TD>
+</TR>
+</TABLE>
+ <A NAME="methods_inherited_from_class_java.io.FilterReader"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Methods inherited from class java.io.FilterReader</B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>close, mark, ready, reset, skip</CODE></TD>
+</TR>
+</TABLE>
+ <A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Methods inherited from class java.lang.Object</B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="REFilterReader(java.io.Reader, gnu.regexp.RE, java.lang.String)"><!-- --></A><H3>
+REFilterReader</H3>
+<PRE>
+public <B>REFilterReader</B>(java.io.Reader stream,
+ <A HREF="../../gnu/regexp/RE.html">RE</A> expr,
+ java.lang.String replace)</PRE>
+<DL>
+<DD>Creates an REFilterReader. When reading from this stream,
+ occurrences of patterns matching the supplied regular expression
+ will be replaced with the supplied replacement text (the
+ metacharacters $0 through $9 may be used to refer to the full
+ match or subexpression matches.<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>stream</CODE> - The Reader to be filtered.<DD><CODE>expr</CODE> - The regular expression to search for.<DD><CODE>replace</CODE> - The text pattern to replace matches with.</DL>
+</DD>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="read()"><!-- --></A><H3>
+read</H3>
+<PRE>
+public int <B>read</B>()</PRE>
+<DL>
+<DD>Reads the next character from the stream per the general contract of
+ Reader.read(). Returns -1 on error or end of stream.<DD><DL>
+<DT><B>Overrides:</B><DD><CODE>read</CODE> in class <CODE>java.io.FilterReader</CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="markSupported()"><!-- --></A><H3>
+markSupported</H3>
+<PRE>
+public boolean <B>markSupported</B>()</PRE>
+<DL>
+<DD>Returns false. REFilterReader does not support mark() and
+ reset() methods.<DD><DL>
+<DT><B>Overrides:</B><DD><CODE>markSupported</CODE> in class <CODE>java.io.FilterReader</CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="read(char[], int, int)"><!-- --></A><H3>
+read</H3>
+<PRE>
+public int <B>read</B>(char[] b,
+ int off,
+ int len)</PRE>
+<DL>
+<DD>Reads from the stream into the provided array.<DD><DL>
+<DT><B>Overrides:</B><DD><CODE>read</CODE> in class <CODE>java.io.FilterReader</CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="read(char[])"><!-- --></A><H3>
+read</H3>
+<PRE>
+public int <B>read</B>(char[] b)</PRE>
+<DL>
+<DD>Reads from the stream into the provided array.<DD><DL>
+<DT><B>Overrides:</B><DD><CODE>read</CODE> in class <CODE>java.io.Reader</CODE></DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A> </TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> <FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A> </TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../gnu/regexp/REFilterInputStream.html"><B>PREV CLASS</B></A>
+ <A HREF="../../gnu/regexp/REMatch.html"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../index.html" TARGET="_top"><B>FRAMES</B></A>
+ <A HREF="REFilterReader.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: INNER | FIELD | <A HREF="#constructor_summary">CONSTR</A> | <A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: FIELD | <A HREF="#constructor_detail">CONSTR</A> | <A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Sun Oct 21 14:27:45 PDT 2001 -->
+<TITLE>
+: Class REMatch
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A> </TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> <FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A> </TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../gnu/regexp/REFilterReader.html"><B>PREV CLASS</B></A>
+ <A HREF="../../gnu/regexp/REMatchEnumeration.html"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../index.html" TARGET="_top"><B>FRAMES</B></A>
+ <A HREF="REMatch.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: INNER | FIELD | CONSTR | <A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: FIELD | CONSTR | <A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+gnu.regexp</FONT>
+<BR>
+Class REMatch</H2>
+<PRE>
+java.lang.Object
+ |
+ +--<B>gnu.regexp.REMatch</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD>java.lang.Cloneable, java.io.Serializable</DD>
+</DL>
+<HR>
+<DL>
+<DT>public final class <B>REMatch</B><DT>extends java.lang.Object<DT>implements java.io.Serializable, java.lang.Cloneable</DL>
+
+<P>
+An instance of this class represents a match
+ completed by a gnu.regexp matching function. It can be used
+ to obtain relevant information about the location of a match
+ or submatch.
+<P>
+<DL>
+<DT><B>Author: </B><DD><A HREF="mailto:wes@cacas.org">Wes Biggs</A></DD>
+<DT><B>See Also: </B><DD><A HREF="../../serialized-form.html#gnu.regexp.REMatch">Serialized Form</A></DL>
+<HR>
+
+<P>
+<!-- ======== INNER CLASS SUMMARY ======== -->
+
+
+<!-- =========== FIELD SUMMARY =========== -->
+
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE> java.lang.Object</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/REMatch.html#clone()">clone</A></B>()</CODE>
+
+<BR>
+ </TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE> int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/REMatch.html#getEndIndex()">getEndIndex</A></B>()</CODE>
+
+<BR>
+ Returns the index within the input string where the match in
+ its entirety ends.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE> int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/REMatch.html#getEndIndex(int)">getEndIndex</A></B>(int sub)</CODE>
+
+<BR>
+ Returns the index within the input string used to generate this match
+ where subexpression number <i>sub</i> ends, or <code>-1</code> if
+ the subexpression does not exist.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE> int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/REMatch.html#getStartIndex()">getStartIndex</A></B>()</CODE>
+
+<BR>
+ Returns the index within the input text where the match in its entirety
+ began.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE> int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/REMatch.html#getStartIndex(int)">getStartIndex</A></B>(int sub)</CODE>
+
+<BR>
+ Returns the index within the input string used to generate this match
+ where subexpression number <i>sub</i> begins, or <code>-1</code> if
+ the subexpression does not exist.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE> int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/REMatch.html#getSubEndIndex(int)">getSubEndIndex</A></B>(int sub)</CODE>
+
+<BR>
+ <B>Deprecated.</B> <I>Use getEndIndex(int) instead</I></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE> int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/REMatch.html#getSubStartIndex(int)">getSubStartIndex</A></B>(int sub)</CODE>
+
+<BR>
+ <B>Deprecated.</B> <I>Use getStartIndex(int) instead.</I></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE> java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/REMatch.html#substituteInto(java.lang.String)">substituteInto</A></B>(java.lang.String input)</CODE>
+
+<BR>
+ Substitute the results of this match to create a new string.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE> java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/REMatch.html#toString()">toString</A></B>()</CODE>
+
+<BR>
+ Returns the string matching the pattern.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE> java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/REMatch.html#toString(int)">toString</A></B>(int sub)</CODE>
+
+<BR>
+ Returns the string matching the given subexpression.</TD>
+</TR>
+</TABLE>
+ <A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Methods inherited from class java.lang.Object</B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>equals, getClass, hashCode, notify, notifyAll, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="clone()"><!-- --></A><H3>
+clone</H3>
+<PRE>
+public java.lang.Object <B>clone</B>()</PRE>
+<DL>
+<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="toString()"><!-- --></A><H3>
+toString</H3>
+<PRE>
+public java.lang.String <B>toString</B>()</PRE>
+<DL>
+<DD>Returns the string matching the pattern. This makes it convenient
+ to write code like the following:
+ <P>
+ <code>
+ REMatch myMatch = myExpression.getMatch(myString);<br>
+ if (myMatch != null) System.out.println("Regexp found: "+myMatch);
+ </code><DD><DL>
+<DT><B>Overrides:</B><DD><CODE>toString</CODE> in class <CODE>java.lang.Object</CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getStartIndex()"><!-- --></A><H3>
+getStartIndex</H3>
+<PRE>
+public int <B>getStartIndex</B>()</PRE>
+<DL>
+<DD>Returns the index within the input text where the match in its entirety
+ began.<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getEndIndex()"><!-- --></A><H3>
+getEndIndex</H3>
+<PRE>
+public int <B>getEndIndex</B>()</PRE>
+<DL>
+<DD>Returns the index within the input string where the match in
+ its entirety ends. The return value is the next position after
+ the end of the string; therefore, a match created by the
+ following call:
+
+ <P>
+ <code>REMatch myMatch = myExpression.getMatch(myString);</code>
+ <P>
+ can be viewed (given that myMatch is not null) by creating
+ <P>
+ <code>String theMatch = myString.substring(myMatch.getStartIndex(),
+ myMatch.getEndIndex());</code>
+ <P>
+ But you can save yourself that work, since the <code>toString()</code>
+ method (above) does exactly that for you.<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="toString(int)"><!-- --></A><H3>
+toString</H3>
+<PRE>
+public java.lang.String <B>toString</B>(int sub)</PRE>
+<DL>
+<DD>Returns the string matching the given subexpression. The subexpressions
+ are indexed starting with one, not zero. That is, the subexpression
+ identified by the first set of parentheses in a regular expression
+ could be retrieved from an REMatch by calling match.toString(1).<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>sub</CODE> - Index of the subexpression.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getSubStartIndex(int)"><!-- --></A><H3>
+getSubStartIndex</H3>
+<PRE>
+public int <B>getSubStartIndex</B>(int sub)</PRE>
+<DL>
+<DD><B>Deprecated.</B> <I>Use getStartIndex(int) instead.</I>
+<P>
+<DD>Returns the index within the input string used to generate this match
+ where subexpression number <i>sub</i> begins, or <code>-1</code> if
+ the subexpression does not exist. The initial position is zero.<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>sub</CODE> - Subexpression index</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getStartIndex(int)"><!-- --></A><H3>
+getStartIndex</H3>
+<PRE>
+public int <B>getStartIndex</B>(int sub)</PRE>
+<DL>
+<DD>Returns the index within the input string used to generate this match
+ where subexpression number <i>sub</i> begins, or <code>-1</code> if
+ the subexpression does not exist. The initial position is zero.<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>sub</CODE> - Subexpression index<DT><B>Since: </B><DD>gnu.regexp 1.1.0</DD>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getSubEndIndex(int)"><!-- --></A><H3>
+getSubEndIndex</H3>
+<PRE>
+public int <B>getSubEndIndex</B>(int sub)</PRE>
+<DL>
+<DD><B>Deprecated.</B> <I>Use getEndIndex(int) instead</I>
+<P>
+<DD>Returns the index within the input string used to generate this match
+ where subexpression number <i>sub</i> ends, or <code>-1</code> if
+ the subexpression does not exist. The initial position is zero.<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>sub</CODE> - Subexpression index</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getEndIndex(int)"><!-- --></A><H3>
+getEndIndex</H3>
+<PRE>
+public int <B>getEndIndex</B>(int sub)</PRE>
+<DL>
+<DD>Returns the index within the input string used to generate this match
+ where subexpression number <i>sub</i> ends, or <code>-1</code> if
+ the subexpression does not exist. The initial position is zero.<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>sub</CODE> - Subexpression index</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="substituteInto(java.lang.String)"><!-- --></A><H3>
+substituteInto</H3>
+<PRE>
+public java.lang.String <B>substituteInto</B>(java.lang.String input)</PRE>
+<DL>
+<DD>Substitute the results of this match to create a new string.
+ This is patterned after PERL, so the tokens to watch out for are
+ <code>$0</code> through <code>$9</code>. <code>$0</code> matches
+ the full substring matched; <code>$<i>n</i></code> matches
+ subexpression number <i>n</i>.<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>input</CODE> - A string consisting of literals and <code>$<i>n</i></code> tokens.</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A> </TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> <FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A> </TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../gnu/regexp/REFilterReader.html"><B>PREV CLASS</B></A>
+ <A HREF="../../gnu/regexp/REMatchEnumeration.html"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../index.html" TARGET="_top"><B>FRAMES</B></A>
+ <A HREF="REMatch.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: INNER | FIELD | CONSTR | <A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: FIELD | CONSTR | <A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Sun Oct 21 14:27:45 PDT 2001 -->
+<TITLE>
+: Class REMatchEnumeration
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A> </TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> <FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A> </TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../gnu/regexp/REMatch.html"><B>PREV CLASS</B></A>
+ <A HREF="../../gnu/regexp/RESyntax.html"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../index.html" TARGET="_top"><B>FRAMES</B></A>
+ <A HREF="REMatchEnumeration.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: INNER | FIELD | CONSTR | <A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: FIELD | CONSTR | <A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+gnu.regexp</FONT>
+<BR>
+Class REMatchEnumeration</H2>
+<PRE>
+java.lang.Object
+ |
+ +--<B>gnu.regexp.REMatchEnumeration</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD>java.util.Enumeration, java.io.Serializable</DD>
+</DL>
+<HR>
+<DL>
+<DT>public class <B>REMatchEnumeration</B><DT>extends java.lang.Object<DT>implements java.util.Enumeration, java.io.Serializable</DL>
+
+<P>
+An REMatchEnumeration enumerates regular expression matches over a
+ given input text. You obtain a reference to an enumeration using
+ the <code>getMatchEnumeration()</code> methods on an instance of
+ RE.
+
+ <P>
+
+ REMatchEnumeration does lazy computation; that is, it will not
+ search for a match until it needs to. If you'd rather just get all
+ the matches at once in a big array, use the
+ <code>getAllMatches()</code> methods on RE. However, using an
+ enumeration can help speed performance when the entire text does
+ not need to be searched immediately.
+
+ <P>
+
+ The enumerated type is especially useful when searching on a Reader
+ or InputStream, because the InputStream read position cannot be
+ guaranteed after calling <code>getMatch()</code> (see the
+ description of that method for an explanation of why). Enumeration
+ also saves a lot of overhead required when calling
+ <code>getMatch()</code> multiple times.
+<P>
+<DL>
+<DT><B>Author: </B><DD><A HREF="mailto:wes@cacas.org">Wes Biggs</A></DD>
+<DT><B>See Also: </B><DD><A HREF="../../serialized-form.html#gnu.regexp.REMatchEnumeration">Serialized Form</A></DL>
+<HR>
+
+<P>
+<!-- ======== INNER CLASS SUMMARY ======== -->
+
+
+<!-- =========== FIELD SUMMARY =========== -->
+
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE> boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/REMatchEnumeration.html#hasMoreElements()">hasMoreElements</A></B>()</CODE>
+
+<BR>
+ Returns true if there are more matches in the input text.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE> boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/REMatchEnumeration.html#hasMoreMatches()">hasMoreMatches</A></B>()</CODE>
+
+<BR>
+ Returns true if there are more matches in the input text.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE> boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/REMatchEnumeration.html#hasMoreMatches(java.lang.StringBuffer)">hasMoreMatches</A></B>(java.lang.StringBuffer buffer)</CODE>
+
+<BR>
+ Returns true if there are more matches in the input text.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE> java.lang.Object</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/REMatchEnumeration.html#nextElement()">nextElement</A></B>()</CODE>
+
+<BR>
+ Returns the next match in the input text.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE> <A HREF="../../gnu/regexp/REMatch.html">REMatch</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/REMatchEnumeration.html#nextMatch()">nextMatch</A></B>()</CODE>
+
+<BR>
+ Returns the next match in the input text.</TD>
+</TR>
+</TABLE>
+ <A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Methods inherited from class java.lang.Object</B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="hasMoreElements()"><!-- --></A><H3>
+hasMoreElements</H3>
+<PRE>
+public boolean <B>hasMoreElements</B>()</PRE>
+<DL>
+<DD>Returns true if there are more matches in the input text.<DD><DL>
+<DT><B>Specified by: </B><DD><CODE>hasMoreElements</CODE> in interface <CODE>java.util.Enumeration</CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="hasMoreMatches()"><!-- --></A><H3>
+hasMoreMatches</H3>
+<PRE>
+public boolean <B>hasMoreMatches</B>()</PRE>
+<DL>
+<DD>Returns true if there are more matches in the input text.<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="hasMoreMatches(java.lang.StringBuffer)"><!-- --></A><H3>
+hasMoreMatches</H3>
+<PRE>
+public boolean <B>hasMoreMatches</B>(java.lang.StringBuffer buffer)</PRE>
+<DL>
+<DD>Returns true if there are more matches in the input text.
+ Saves the text leading up to the match (or to the end of the input)
+ in the specified buffer.<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="nextElement()"><!-- --></A><H3>
+nextElement</H3>
+<PRE>
+public java.lang.Object <B>nextElement</B>()
+ throws java.util.NoSuchElementException</PRE>
+<DL>
+<DD>Returns the next match in the input text.<DD><DL>
+<DT><B>Specified by: </B><DD><CODE>nextElement</CODE> in interface <CODE>java.util.Enumeration</CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="nextMatch()"><!-- --></A><H3>
+nextMatch</H3>
+<PRE>
+public <A HREF="../../gnu/regexp/REMatch.html">REMatch</A> <B>nextMatch</B>()
+ throws java.util.NoSuchElementException</PRE>
+<DL>
+<DD>Returns the next match in the input text. This method is provided
+ for convenience to avoid having to explicitly cast the return value
+ to class REMatch.<DD><DL>
+</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A> </TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> <FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A> </TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../gnu/regexp/REMatch.html"><B>PREV CLASS</B></A>
+ <A HREF="../../gnu/regexp/RESyntax.html"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../index.html" TARGET="_top"><B>FRAMES</B></A>
+ <A HREF="REMatchEnumeration.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: INNER | FIELD | CONSTR | <A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: FIELD | CONSTR | <A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Sun Oct 21 14:27:45 PDT 2001 -->
+<TITLE>
+: Class RESyntax
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A> </TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> <FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A> </TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../gnu/regexp/REMatchEnumeration.html"><B>PREV CLASS</B></A>
+ <A HREF="../../gnu/regexp/UncheckedRE.html"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../index.html" TARGET="_top"><B>FRAMES</B></A>
+ <A HREF="RESyntax.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: INNER | <A HREF="#field_summary">FIELD</A> | <A HREF="#constructor_summary">CONSTR</A> | <A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: <A HREF="#field_detail">FIELD</A> | <A HREF="#constructor_detail">CONSTR</A> | <A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+gnu.regexp</FONT>
+<BR>
+Class RESyntax</H2>
+<PRE>
+java.lang.Object
+ |
+ +--<B>gnu.regexp.RESyntax</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD>java.io.Serializable</DD>
+</DL>
+<HR>
+<DL>
+<DT>public final class <B>RESyntax</B><DT>extends java.lang.Object<DT>implements java.io.Serializable</DL>
+
+<P>
+An RESyntax specifies the way a regular expression will be compiled.
+ This class provides a number of predefined useful constants for
+ emulating popular regular expression syntaxes. Additionally the
+ user may construct his or her own syntax, using any combination of the
+ syntax bit constants. The syntax is an optional argument to any of the
+ matching methods on class RE.
+<P>
+<DL>
+<DT><B>Author: </B><DD><A HREF="mailto:wes@cacas.org">Wes Biggs</A></DD>
+<DT><B>See Also: </B><DD><A HREF="../../serialized-form.html#gnu.regexp.RESyntax">Serialized Form</A></DL>
+<HR>
+
+<P>
+<!-- ======== INNER CLASS SUMMARY ======== -->
+
+
+<!-- =========== FIELD SUMMARY =========== -->
+
+<A NAME="field_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Field Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RESyntax.html#RE_BACKSLASH_ESCAPE_IN_LISTS">RE_BACKSLASH_ESCAPE_IN_LISTS</A></B></CODE>
+
+<BR>
+ Syntax bit.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RESyntax.html#RE_BK_PLUS_QM">RE_BK_PLUS_QM</A></B></CODE>
+
+<BR>
+ Syntax bit.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RESyntax.html#RE_CHAR_CLASS_ESC_IN_LISTS">RE_CHAR_CLASS_ESC_IN_LISTS</A></B></CODE>
+
+<BR>
+ Syntax bit.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RESyntax.html#RE_CHAR_CLASS_ESCAPES">RE_CHAR_CLASS_ESCAPES</A></B></CODE>
+
+<BR>
+ Syntax bit.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RESyntax.html#RE_CHAR_CLASSES">RE_CHAR_CLASSES</A></B></CODE>
+
+<BR>
+ Syntax bit.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RESyntax.html#RE_COMMENTS">RE_COMMENTS</A></B></CODE>
+
+<BR>
+ Syntax bit.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RESyntax.html#RE_CONTEXT_INDEP_ANCHORS">RE_CONTEXT_INDEP_ANCHORS</A></B></CODE>
+
+<BR>
+ Syntax bit.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RESyntax.html#RE_CONTEXT_INDEP_OPS">RE_CONTEXT_INDEP_OPS</A></B></CODE>
+
+<BR>
+ Syntax bit.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RESyntax.html#RE_CONTEXT_INVALID_OPS">RE_CONTEXT_INVALID_OPS</A></B></CODE>
+
+<BR>
+ Syntax bit.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RESyntax.html#RE_DOT_NEWLINE">RE_DOT_NEWLINE</A></B></CODE>
+
+<BR>
+ Syntax bit.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RESyntax.html#RE_DOT_NOT_NULL">RE_DOT_NOT_NULL</A></B></CODE>
+
+<BR>
+ Syntax bit.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RESyntax.html#RE_HAT_LISTS_NOT_NEWLINE">RE_HAT_LISTS_NOT_NEWLINE</A></B></CODE>
+
+<BR>
+ Syntax bit.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RESyntax.html#RE_INTERVALS">RE_INTERVALS</A></B></CODE>
+
+<BR>
+ Syntax bit.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RESyntax.html#RE_LIMITED_OPS">RE_LIMITED_OPS</A></B></CODE>
+
+<BR>
+ Syntax bit.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RESyntax.html#RE_LOOKAHEAD">RE_LOOKAHEAD</A></B></CODE>
+
+<BR>
+ Syntax bit.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RESyntax.html#RE_NEWLINE_ALT">RE_NEWLINE_ALT</A></B></CODE>
+
+<BR>
+ Syntax bit.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RESyntax.html#RE_NO_BK_BRACES">RE_NO_BK_BRACES</A></B></CODE>
+
+<BR>
+ Syntax bit.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RESyntax.html#RE_NO_BK_PARENS">RE_NO_BK_PARENS</A></B></CODE>
+
+<BR>
+ Syntax bit.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RESyntax.html#RE_NO_BK_REFS">RE_NO_BK_REFS</A></B></CODE>
+
+<BR>
+ Syntax bit.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RESyntax.html#RE_NO_BK_VBAR">RE_NO_BK_VBAR</A></B></CODE>
+
+<BR>
+ Syntax bit.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RESyntax.html#RE_NO_EMPTY_RANGES">RE_NO_EMPTY_RANGES</A></B></CODE>
+
+<BR>
+ Syntax bit.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RESyntax.html#RE_PURE_GROUPING">RE_PURE_GROUPING</A></B></CODE>
+
+<BR>
+ Syntax bit.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RESyntax.html#RE_STINGY_OPS">RE_STINGY_OPS</A></B></CODE>
+
+<BR>
+ Syntax bit.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RESyntax.html#RE_STRING_ANCHORS">RE_STRING_ANCHORS</A></B></CODE>
+
+<BR>
+ Syntax bit.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static <A HREF="../../gnu/regexp/RESyntax.html">RESyntax</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RESyntax.html#RE_SYNTAX_AWK">RE_SYNTAX_AWK</A></B></CODE>
+
+<BR>
+ Predefined syntax.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static <A HREF="../../gnu/regexp/RESyntax.html">RESyntax</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RESyntax.html#RE_SYNTAX_ED">RE_SYNTAX_ED</A></B></CODE>
+
+<BR>
+ Predefined syntax.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static <A HREF="../../gnu/regexp/RESyntax.html">RESyntax</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RESyntax.html#RE_SYNTAX_EGREP">RE_SYNTAX_EGREP</A></B></CODE>
+
+<BR>
+ Predefined syntax.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static <A HREF="../../gnu/regexp/RESyntax.html">RESyntax</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RESyntax.html#RE_SYNTAX_EMACS">RE_SYNTAX_EMACS</A></B></CODE>
+
+<BR>
+ Predefined syntax.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static <A HREF="../../gnu/regexp/RESyntax.html">RESyntax</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RESyntax.html#RE_SYNTAX_GREP">RE_SYNTAX_GREP</A></B></CODE>
+
+<BR>
+ Predefined syntax.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static <A HREF="../../gnu/regexp/RESyntax.html">RESyntax</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RESyntax.html#RE_SYNTAX_PERL4">RE_SYNTAX_PERL4</A></B></CODE>
+
+<BR>
+ Predefined syntax.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static <A HREF="../../gnu/regexp/RESyntax.html">RESyntax</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RESyntax.html#RE_SYNTAX_PERL4_S">RE_SYNTAX_PERL4_S</A></B></CODE>
+
+<BR>
+ Predefined syntax.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static <A HREF="../../gnu/regexp/RESyntax.html">RESyntax</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RESyntax.html#RE_SYNTAX_PERL5">RE_SYNTAX_PERL5</A></B></CODE>
+
+<BR>
+ Predefined syntax.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static <A HREF="../../gnu/regexp/RESyntax.html">RESyntax</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RESyntax.html#RE_SYNTAX_PERL5_S">RE_SYNTAX_PERL5_S</A></B></CODE>
+
+<BR>
+ Predefined syntax.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static <A HREF="../../gnu/regexp/RESyntax.html">RESyntax</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RESyntax.html#RE_SYNTAX_POSIX_AWK">RE_SYNTAX_POSIX_AWK</A></B></CODE>
+
+<BR>
+ Predefined syntax.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static <A HREF="../../gnu/regexp/RESyntax.html">RESyntax</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RESyntax.html#RE_SYNTAX_POSIX_BASIC">RE_SYNTAX_POSIX_BASIC</A></B></CODE>
+
+<BR>
+ Predefined syntax.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static <A HREF="../../gnu/regexp/RESyntax.html">RESyntax</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RESyntax.html#RE_SYNTAX_POSIX_EGREP">RE_SYNTAX_POSIX_EGREP</A></B></CODE>
+
+<BR>
+ Predefined syntax.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static <A HREF="../../gnu/regexp/RESyntax.html">RESyntax</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RESyntax.html#RE_SYNTAX_POSIX_EXTENDED">RE_SYNTAX_POSIX_EXTENDED</A></B></CODE>
+
+<BR>
+ Predefined syntax.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static <A HREF="../../gnu/regexp/RESyntax.html">RESyntax</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RESyntax.html#RE_SYNTAX_POSIX_MINIMAL_BASIC">RE_SYNTAX_POSIX_MINIMAL_BASIC</A></B></CODE>
+
+<BR>
+ Predefined syntax.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static <A HREF="../../gnu/regexp/RESyntax.html">RESyntax</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RESyntax.html#RE_SYNTAX_POSIX_MINIMAL_EXTENDED">RE_SYNTAX_POSIX_MINIMAL_EXTENDED</A></B></CODE>
+
+<BR>
+ Predefined syntax.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static <A HREF="../../gnu/regexp/RESyntax.html">RESyntax</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RESyntax.html#RE_SYNTAX_SED">RE_SYNTAX_SED</A></B></CODE>
+
+<BR>
+ Predefined syntax.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RESyntax.html#RE_UNMATCHED_RIGHT_PAREN_ORD">RE_UNMATCHED_RIGHT_PAREN_ORD</A></B></CODE>
+
+<BR>
+ Syntax bit.</TD>
+</TR>
+</TABLE>
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../gnu/regexp/RESyntax.html#RESyntax()">RESyntax</A></B>()</CODE>
+
+<BR>
+ Construct a new syntax object with all bits turned off.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../gnu/regexp/RESyntax.html#RESyntax(gnu.regexp.RESyntax)">RESyntax</A></B>(<A HREF="../../gnu/regexp/RESyntax.html">RESyntax</A> other)</CODE>
+
+<BR>
+ Construct a new syntax object with all bits set the same
+ as the other syntax.</TD>
+</TR>
+</TABLE>
+
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE> <A HREF="../../gnu/regexp/RESyntax.html">RESyntax</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RESyntax.html#clear(int)">clear</A></B>(int index)</CODE>
+
+<BR>
+ Clear a given bit in this syntax.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE> boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RESyntax.html#get(int)">get</A></B>(int index)</CODE>
+
+<BR>
+ Check if a given bit is set in this syntax.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE> java.lang.String</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RESyntax.html#getLineSeparator()">getLineSeparator</A></B>()</CODE>
+
+<BR>
+ Returns the currently active line separator string.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE> <A HREF="../../gnu/regexp/RESyntax.html">RESyntax</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RESyntax.html#makeFinal()">makeFinal</A></B>()</CODE>
+
+<BR>
+ Called internally when constructing predefined syntaxes
+ so their interpretation cannot vary.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE> <A HREF="../../gnu/regexp/RESyntax.html">RESyntax</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RESyntax.html#set(int)">set</A></B>(int index)</CODE>
+
+<BR>
+ Set a given bit in this syntax.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE> <A HREF="../../gnu/regexp/RESyntax.html">RESyntax</A></CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../gnu/regexp/RESyntax.html#setLineSeparator(java.lang.String)">setLineSeparator</A></B>(java.lang.String aSeparator)</CODE>
+
+<BR>
+ Changes the line separator string for regular expressions
+ created using this RESyntax.</TD>
+</TR>
+</TABLE>
+ <A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Methods inherited from class java.lang.Object</B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+<A NAME="field_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Field Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="RE_BACKSLASH_ESCAPE_IN_LISTS"><!-- --></A><H3>
+RE_BACKSLASH_ESCAPE_IN_LISTS</H3>
+<PRE>
+public static final int <B>RE_BACKSLASH_ESCAPE_IN_LISTS</B></PRE>
+<DL>
+<DD>Syntax bit. Backslash is an escape character in lists.</DL>
+<HR>
+
+<A NAME="RE_BK_PLUS_QM"><!-- --></A><H3>
+RE_BK_PLUS_QM</H3>
+<PRE>
+public static final int <B>RE_BK_PLUS_QM</B></PRE>
+<DL>
+<DD>Syntax bit. Use \? instead of ? and \+ instead of +.</DL>
+<HR>
+
+<A NAME="RE_CHAR_CLASSES"><!-- --></A><H3>
+RE_CHAR_CLASSES</H3>
+<PRE>
+public static final int <B>RE_CHAR_CLASSES</B></PRE>
+<DL>
+<DD>Syntax bit. POSIX character classes ([:...:]) in lists are allowed.</DL>
+<HR>
+
+<A NAME="RE_CONTEXT_INDEP_ANCHORS"><!-- --></A><H3>
+RE_CONTEXT_INDEP_ANCHORS</H3>
+<PRE>
+public static final int <B>RE_CONTEXT_INDEP_ANCHORS</B></PRE>
+<DL>
+<DD>Syntax bit. ^ and $ are special everywhere.
+ <B>Not implemented.</B></DL>
+<HR>
+
+<A NAME="RE_CONTEXT_INDEP_OPS"><!-- --></A><H3>
+RE_CONTEXT_INDEP_OPS</H3>
+<PRE>
+public static final int <B>RE_CONTEXT_INDEP_OPS</B></PRE>
+<DL>
+<DD>Syntax bit. Repetition operators are only special in valid positions.
+ <B>Not implemented.</B></DL>
+<HR>
+
+<A NAME="RE_CONTEXT_INVALID_OPS"><!-- --></A><H3>
+RE_CONTEXT_INVALID_OPS</H3>
+<PRE>
+public static final int <B>RE_CONTEXT_INVALID_OPS</B></PRE>
+<DL>
+<DD>Syntax bit. Repetition and alternation operators are invalid
+ at start and end of pattern and other places.
+ <B>Not implemented</B>.</DL>
+<HR>
+
+<A NAME="RE_DOT_NEWLINE"><!-- --></A><H3>
+RE_DOT_NEWLINE</H3>
+<PRE>
+public static final int <B>RE_DOT_NEWLINE</B></PRE>
+<DL>
+<DD>Syntax bit. Match-any-character operator (.) matches a newline.</DL>
+<HR>
+
+<A NAME="RE_DOT_NOT_NULL"><!-- --></A><H3>
+RE_DOT_NOT_NULL</H3>
+<PRE>
+public static final int <B>RE_DOT_NOT_NULL</B></PRE>
+<DL>
+<DD>Syntax bit. Match-any-character operator (.) does not match a null.</DL>
+<HR>
+
+<A NAME="RE_INTERVALS"><!-- --></A><H3>
+RE_INTERVALS</H3>
+<PRE>
+public static final int <B>RE_INTERVALS</B></PRE>
+<DL>
+<DD>Syntax bit. Intervals ({x}, {x,}, {x,y}) are allowed.</DL>
+<HR>
+
+<A NAME="RE_LIMITED_OPS"><!-- --></A><H3>
+RE_LIMITED_OPS</H3>
+<PRE>
+public static final int <B>RE_LIMITED_OPS</B></PRE>
+<DL>
+<DD>Syntax bit. No alternation (|), match one-or-more (+), or
+ match zero-or-one (?) operators.</DL>
+<HR>
+
+<A NAME="RE_NEWLINE_ALT"><!-- --></A><H3>
+RE_NEWLINE_ALT</H3>
+<PRE>
+public static final int <B>RE_NEWLINE_ALT</B></PRE>
+<DL>
+<DD>Syntax bit. Newline is an alternation operator.</DL>
+<HR>
+
+<A NAME="RE_NO_BK_BRACES"><!-- --></A><H3>
+RE_NO_BK_BRACES</H3>
+<PRE>
+public static final int <B>RE_NO_BK_BRACES</B></PRE>
+<DL>
+<DD>Syntax bit. Intervals use { } instead of \{ \}</DL>
+<HR>
+
+<A NAME="RE_NO_BK_PARENS"><!-- --></A><H3>
+RE_NO_BK_PARENS</H3>
+<PRE>
+public static final int <B>RE_NO_BK_PARENS</B></PRE>
+<DL>
+<DD>Syntax bit. Grouping uses ( ) instead of \( \).</DL>
+<HR>
+
+<A NAME="RE_NO_BK_REFS"><!-- --></A><H3>
+RE_NO_BK_REFS</H3>
+<PRE>
+public static final int <B>RE_NO_BK_REFS</B></PRE>
+<DL>
+<DD>Syntax bit. Backreferences not allowed.</DL>
+<HR>
+
+<A NAME="RE_NO_BK_VBAR"><!-- --></A><H3>
+RE_NO_BK_VBAR</H3>
+<PRE>
+public static final int <B>RE_NO_BK_VBAR</B></PRE>
+<DL>
+<DD>Syntax bit. Alternation uses | instead of \|</DL>
+<HR>
+
+<A NAME="RE_NO_EMPTY_RANGES"><!-- --></A><H3>
+RE_NO_EMPTY_RANGES</H3>
+<PRE>
+public static final int <B>RE_NO_EMPTY_RANGES</B></PRE>
+<DL>
+<DD>Syntax bit. <B>Not implemented</B>.</DL>
+<HR>
+
+<A NAME="RE_UNMATCHED_RIGHT_PAREN_ORD"><!-- --></A><H3>
+RE_UNMATCHED_RIGHT_PAREN_ORD</H3>
+<PRE>
+public static final int <B>RE_UNMATCHED_RIGHT_PAREN_ORD</B></PRE>
+<DL>
+<DD>Syntax bit. An unmatched right parenthesis (')' or '\)', depending
+ on RE_NO_BK_PARENS) will throw an exception when compiling.</DL>
+<HR>
+
+<A NAME="RE_HAT_LISTS_NOT_NEWLINE"><!-- --></A><H3>
+RE_HAT_LISTS_NOT_NEWLINE</H3>
+<PRE>
+public static final int <B>RE_HAT_LISTS_NOT_NEWLINE</B></PRE>
+<DL>
+<DD>Syntax bit. <B>Not implemented.</B></DL>
+<HR>
+
+<A NAME="RE_STINGY_OPS"><!-- --></A><H3>
+RE_STINGY_OPS</H3>
+<PRE>
+public static final int <B>RE_STINGY_OPS</B></PRE>
+<DL>
+<DD>Syntax bit. Stingy matching is allowed (+?, *?, ??, {x,y}?).</DL>
+<HR>
+
+<A NAME="RE_CHAR_CLASS_ESCAPES"><!-- --></A><H3>
+RE_CHAR_CLASS_ESCAPES</H3>
+<PRE>
+public static final int <B>RE_CHAR_CLASS_ESCAPES</B></PRE>
+<DL>
+<DD>Syntax bit. Allow character class escapes (\d, \D, \s, \S, \w, \W).</DL>
+<HR>
+
+<A NAME="RE_PURE_GROUPING"><!-- --></A><H3>
+RE_PURE_GROUPING</H3>
+<PRE>
+public static final int <B>RE_PURE_GROUPING</B></PRE>
+<DL>
+<DD>Syntax bit. Allow use of (?:xxx) grouping (subexpression is not saved).</DL>
+<HR>
+
+<A NAME="RE_LOOKAHEAD"><!-- --></A><H3>
+RE_LOOKAHEAD</H3>
+<PRE>
+public static final int <B>RE_LOOKAHEAD</B></PRE>
+<DL>
+<DD>Syntax bit. Allow use of (?=xxx) and (?!xxx) apply the subexpression
+ to the text following the current position without consuming that text.</DL>
+<HR>
+
+<A NAME="RE_STRING_ANCHORS"><!-- --></A><H3>
+RE_STRING_ANCHORS</H3>
+<PRE>
+public static final int <B>RE_STRING_ANCHORS</B></PRE>
+<DL>
+<DD>Syntax bit. Allow beginning- and end-of-string anchors (\A, \Z).</DL>
+<HR>
+
+<A NAME="RE_COMMENTS"><!-- --></A><H3>
+RE_COMMENTS</H3>
+<PRE>
+public static final int <B>RE_COMMENTS</B></PRE>
+<DL>
+<DD>Syntax bit. Allow embedded comments, (?#comment), as in Perl5.</DL>
+<HR>
+
+<A NAME="RE_CHAR_CLASS_ESC_IN_LISTS"><!-- --></A><H3>
+RE_CHAR_CLASS_ESC_IN_LISTS</H3>
+<PRE>
+public static final int <B>RE_CHAR_CLASS_ESC_IN_LISTS</B></PRE>
+<DL>
+<DD>Syntax bit. Allow character class escapes within lists, as in Perl5.</DL>
+<HR>
+
+<A NAME="RE_SYNTAX_AWK"><!-- --></A><H3>
+RE_SYNTAX_AWK</H3>
+<PRE>
+public static final <A HREF="../../gnu/regexp/RESyntax.html">RESyntax</A> <B>RE_SYNTAX_AWK</B></PRE>
+<DL>
+<DD>Predefined syntax.
+ Emulates regular expression support in the awk utility.</DL>
+<HR>
+
+<A NAME="RE_SYNTAX_ED"><!-- --></A><H3>
+RE_SYNTAX_ED</H3>
+<PRE>
+public static final <A HREF="../../gnu/regexp/RESyntax.html">RESyntax</A> <B>RE_SYNTAX_ED</B></PRE>
+<DL>
+<DD>Predefined syntax.
+ Emulates regular expression support in the ed utility.</DL>
+<HR>
+
+<A NAME="RE_SYNTAX_EGREP"><!-- --></A><H3>
+RE_SYNTAX_EGREP</H3>
+<PRE>
+public static final <A HREF="../../gnu/regexp/RESyntax.html">RESyntax</A> <B>RE_SYNTAX_EGREP</B></PRE>
+<DL>
+<DD>Predefined syntax.
+ Emulates regular expression support in the egrep utility.</DL>
+<HR>
+
+<A NAME="RE_SYNTAX_EMACS"><!-- --></A><H3>
+RE_SYNTAX_EMACS</H3>
+<PRE>
+public static final <A HREF="../../gnu/regexp/RESyntax.html">RESyntax</A> <B>RE_SYNTAX_EMACS</B></PRE>
+<DL>
+<DD>Predefined syntax.
+ Emulates regular expression support in the GNU Emacs editor.</DL>
+<HR>
+
+<A NAME="RE_SYNTAX_GREP"><!-- --></A><H3>
+RE_SYNTAX_GREP</H3>
+<PRE>
+public static final <A HREF="../../gnu/regexp/RESyntax.html">RESyntax</A> <B>RE_SYNTAX_GREP</B></PRE>
+<DL>
+<DD>Predefined syntax.
+ Emulates regular expression support in the grep utility.</DL>
+<HR>
+
+<A NAME="RE_SYNTAX_POSIX_AWK"><!-- --></A><H3>
+RE_SYNTAX_POSIX_AWK</H3>
+<PRE>
+public static final <A HREF="../../gnu/regexp/RESyntax.html">RESyntax</A> <B>RE_SYNTAX_POSIX_AWK</B></PRE>
+<DL>
+<DD>Predefined syntax.
+ Emulates regular expression support in the POSIX awk specification.</DL>
+<HR>
+
+<A NAME="RE_SYNTAX_POSIX_BASIC"><!-- --></A><H3>
+RE_SYNTAX_POSIX_BASIC</H3>
+<PRE>
+public static final <A HREF="../../gnu/regexp/RESyntax.html">RESyntax</A> <B>RE_SYNTAX_POSIX_BASIC</B></PRE>
+<DL>
+<DD>Predefined syntax.
+ Emulates POSIX basic regular expression support.</DL>
+<HR>
+
+<A NAME="RE_SYNTAX_POSIX_EGREP"><!-- --></A><H3>
+RE_SYNTAX_POSIX_EGREP</H3>
+<PRE>
+public static final <A HREF="../../gnu/regexp/RESyntax.html">RESyntax</A> <B>RE_SYNTAX_POSIX_EGREP</B></PRE>
+<DL>
+<DD>Predefined syntax.
+ Emulates regular expression support in the POSIX egrep specification.</DL>
+<HR>
+
+<A NAME="RE_SYNTAX_POSIX_EXTENDED"><!-- --></A><H3>
+RE_SYNTAX_POSIX_EXTENDED</H3>
+<PRE>
+public static final <A HREF="../../gnu/regexp/RESyntax.html">RESyntax</A> <B>RE_SYNTAX_POSIX_EXTENDED</B></PRE>
+<DL>
+<DD>Predefined syntax.
+ Emulates POSIX extended regular expression support.</DL>
+<HR>
+
+<A NAME="RE_SYNTAX_POSIX_MINIMAL_BASIC"><!-- --></A><H3>
+RE_SYNTAX_POSIX_MINIMAL_BASIC</H3>
+<PRE>
+public static final <A HREF="../../gnu/regexp/RESyntax.html">RESyntax</A> <B>RE_SYNTAX_POSIX_MINIMAL_BASIC</B></PRE>
+<DL>
+<DD>Predefined syntax.
+ Emulates POSIX basic minimal regular expressions.</DL>
+<HR>
+
+<A NAME="RE_SYNTAX_POSIX_MINIMAL_EXTENDED"><!-- --></A><H3>
+RE_SYNTAX_POSIX_MINIMAL_EXTENDED</H3>
+<PRE>
+public static final <A HREF="../../gnu/regexp/RESyntax.html">RESyntax</A> <B>RE_SYNTAX_POSIX_MINIMAL_EXTENDED</B></PRE>
+<DL>
+<DD>Predefined syntax.
+ Emulates POSIX extended minimal regular expressions.</DL>
+<HR>
+
+<A NAME="RE_SYNTAX_SED"><!-- --></A><H3>
+RE_SYNTAX_SED</H3>
+<PRE>
+public static final <A HREF="../../gnu/regexp/RESyntax.html">RESyntax</A> <B>RE_SYNTAX_SED</B></PRE>
+<DL>
+<DD>Predefined syntax.
+ Emulates regular expression support in the sed utility.</DL>
+<HR>
+
+<A NAME="RE_SYNTAX_PERL4"><!-- --></A><H3>
+RE_SYNTAX_PERL4</H3>
+<PRE>
+public static final <A HREF="../../gnu/regexp/RESyntax.html">RESyntax</A> <B>RE_SYNTAX_PERL4</B></PRE>
+<DL>
+<DD>Predefined syntax.
+ Emulates regular expression support in Larry Wall's perl, version 4,</DL>
+<HR>
+
+<A NAME="RE_SYNTAX_PERL4_S"><!-- --></A><H3>
+RE_SYNTAX_PERL4_S</H3>
+<PRE>
+public static final <A HREF="../../gnu/regexp/RESyntax.html">RESyntax</A> <B>RE_SYNTAX_PERL4_S</B></PRE>
+<DL>
+<DD>Predefined syntax.
+ Emulates regular expression support in Larry Wall's perl, version 4,
+ using single line mode (/s modifier).</DL>
+<HR>
+
+<A NAME="RE_SYNTAX_PERL5"><!-- --></A><H3>
+RE_SYNTAX_PERL5</H3>
+<PRE>
+public static final <A HREF="../../gnu/regexp/RESyntax.html">RESyntax</A> <B>RE_SYNTAX_PERL5</B></PRE>
+<DL>
+<DD>Predefined syntax.
+ Emulates regular expression support in Larry Wall's perl, version 5.</DL>
+<HR>
+
+<A NAME="RE_SYNTAX_PERL5_S"><!-- --></A><H3>
+RE_SYNTAX_PERL5_S</H3>
+<PRE>
+public static final <A HREF="../../gnu/regexp/RESyntax.html">RESyntax</A> <B>RE_SYNTAX_PERL5_S</B></PRE>
+<DL>
+<DD>Predefined syntax.
+ Emulates regular expression support in Larry Wall's perl, version 5,
+ using single line mode (/s modifier).</DL>
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="RESyntax()"><!-- --></A><H3>
+RESyntax</H3>
+<PRE>
+public <B>RESyntax</B>()</PRE>
+<DL>
+<DD>Construct a new syntax object with all bits turned off.
+ This is equivalent to RE_SYNTAX_EMACS.</DL>
+<HR>
+
+<A NAME="RESyntax(gnu.regexp.RESyntax)"><!-- --></A><H3>
+RESyntax</H3>
+<PRE>
+public <B>RESyntax</B>(<A HREF="../../gnu/regexp/RESyntax.html">RESyntax</A> other)</PRE>
+<DL>
+<DD>Construct a new syntax object with all bits set the same
+ as the other syntax.</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="makeFinal()"><!-- --></A><H3>
+makeFinal</H3>
+<PRE>
+public <A HREF="../../gnu/regexp/RESyntax.html">RESyntax</A> <B>makeFinal</B>()</PRE>
+<DL>
+<DD>Called internally when constructing predefined syntaxes
+ so their interpretation cannot vary. Conceivably useful
+ for your syntaxes as well. Causes IllegalAccessError to
+ be thrown if any attempt to modify the syntax is made.<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Returns:</B><DD>this object for convenient chaining</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="get(int)"><!-- --></A><H3>
+get</H3>
+<PRE>
+public boolean <B>get</B>(int index)</PRE>
+<DL>
+<DD>Check if a given bit is set in this syntax.<DD><DL>
+</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="set(int)"><!-- --></A><H3>
+set</H3>
+<PRE>
+public <A HREF="../../gnu/regexp/RESyntax.html">RESyntax</A> <B>set</B>(int index)</PRE>
+<DL>
+<DD>Set a given bit in this syntax.<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>index</CODE> - the constant (RESyntax.RE_xxx) bit to set.<DT><B>Returns:</B><DD>a reference to this object for easy chaining.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="clear(int)"><!-- --></A><H3>
+clear</H3>
+<PRE>
+public <A HREF="../../gnu/regexp/RESyntax.html">RESyntax</A> <B>clear</B>(int index)</PRE>
+<DL>
+<DD>Clear a given bit in this syntax.<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>index</CODE> - the constant (RESyntax.RE_xxx) bit to clear.<DT><B>Returns:</B><DD>a reference to this object for easy chaining.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="setLineSeparator(java.lang.String)"><!-- --></A><H3>
+setLineSeparator</H3>
+<PRE>
+public <A HREF="../../gnu/regexp/RESyntax.html">RESyntax</A> <B>setLineSeparator</B>(java.lang.String aSeparator)</PRE>
+<DL>
+<DD>Changes the line separator string for regular expressions
+ created using this RESyntax. The default separator is the
+ value returned by the system property "line.separator", which
+ should be correct when reading platform-specific files from a
+ filesystem. However, many programs may collect input from
+ sources where the line separator is differently specified (for
+ example, in the applet environment, the text box widget
+ interprets line breaks as single-character newlines,
+ regardless of the host platform.
+
+ Note that setting the line separator to a character or
+ characters that have specific meaning within the current syntax
+ can cause unexpected chronosynclastic infundibula.<DD><DL>
+</DL>
+</DD>
+<DD><DL>
+<DT><B>Returns:</B><DD>this object for convenient chaining</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="getLineSeparator()"><!-- --></A><H3>
+getLineSeparator</H3>
+<PRE>
+public java.lang.String <B>getLineSeparator</B>()</PRE>
+<DL>
+<DD>Returns the currently active line separator string. The default
+ is the platform-dependent system property "line.separator".<DD><DL>
+</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A> </TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> <FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A> </TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../gnu/regexp/REMatchEnumeration.html"><B>PREV CLASS</B></A>
+ <A HREF="../../gnu/regexp/UncheckedRE.html"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../index.html" TARGET="_top"><B>FRAMES</B></A>
+ <A HREF="RESyntax.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: INNER | <A HREF="#field_summary">FIELD</A> | <A HREF="#constructor_summary">CONSTR</A> | <A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: <A HREF="#field_detail">FIELD</A> | <A HREF="#constructor_detail">CONSTR</A> | <A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Sun Oct 21 14:27:46 PDT 2001 -->
+<TITLE>
+: Class UncheckedRE
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A> </TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> <FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A> </TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../gnu/regexp/RESyntax.html"><B>PREV CLASS</B></A>
+ NEXT CLASS</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../index.html" TARGET="_top"><B>FRAMES</B></A>
+ <A HREF="UncheckedRE.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: INNER | <A HREF="#fields_inherited_from_class_gnu.regexp.RE">FIELD</A> | <A HREF="#constructor_summary">CONSTR</A> | <A HREF="#methods_inherited_from_class_gnu.regexp.RE">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: FIELD | <A HREF="#constructor_detail">CONSTR</A> | METHOD</FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+gnu.regexp</FONT>
+<BR>
+Class UncheckedRE</H2>
+<PRE>
+java.lang.Object
+ |
+ +--gnu.regexp.REToken
+ |
+ +--<A HREF="../../gnu/regexp/RE.html">gnu.regexp.RE</A>
+ |
+ +--<B>gnu.regexp.UncheckedRE</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD>java.io.Serializable</DD>
+</DL>
+<HR>
+<DL>
+<DT>public final class <B>UncheckedRE</B><DT>extends <A HREF="../../gnu/regexp/RE.html">RE</A></DL>
+
+<P>
+UncheckedRE is a subclass of RE that allows programmers an easier means
+ of programmatically precompiling regular expressions. It is constructed
+ and used in exactly the same manner as an instance of the RE class; the
+ only difference is that its constructors do not throw REException.
+ Instead, if a syntax error is encountered during construction, a
+ RuntimeException will be thrown.
+ <P>
+ Note that this makes UncheckedRE dangerous if constructed with
+ dynamic data. Do not use UncheckedRE unless you are completely sure
+ that all input being passed to it contains valid, well-formed
+ regular expressions for the syntax specified.
+<P>
+<DL>
+<DT><B>Since: </B><DD>gnu.regexp 1.1.4</DD>
+<DT><B>Author: </B><DD><A HREF="mailto:wes@cacas.org">Wes Biggs</A></DD>
+<DT><B>See Also: </B><DD><A HREF="../../gnu/regexp/RE.html"><CODE>RE</CODE></A>, <A HREF="../../serialized-form.html#gnu.regexp.UncheckedRE">Serialized Form</A></DL>
+<HR>
+
+<P>
+<!-- ======== INNER CLASS SUMMARY ======== -->
+
+
+<!-- =========== FIELD SUMMARY =========== -->
+
+<A NAME="fields_inherited_from_class_gnu.regexp.RE"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Fields inherited from class gnu.regexp.<A HREF="../../gnu/regexp/RE.html">RE</A></B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="../../gnu/regexp/RE.html#REG_ANCHORINDEX">REG_ANCHORINDEX</A>, <A HREF="../../gnu/regexp/RE.html#REG_DOT_NEWLINE">REG_DOT_NEWLINE</A>, <A HREF="../../gnu/regexp/RE.html#REG_ICASE">REG_ICASE</A>, <A HREF="../../gnu/regexp/RE.html#REG_MULTILINE">REG_MULTILINE</A>, <A HREF="../../gnu/regexp/RE.html#REG_NO_INTERPOLATE">REG_NO_INTERPOLATE</A>, <A HREF="../../gnu/regexp/RE.html#REG_NOTBOL">REG_NOTBOL</A>, <A HREF="../../gnu/regexp/RE.html#REG_NOTEOL">REG_NOTEOL</A></CODE></TD>
+</TR>
+</TABLE>
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../gnu/regexp/UncheckedRE.html#UncheckedRE(java.lang.Object)">UncheckedRE</A></B>(java.lang.Object pattern)</CODE>
+
+<BR>
+ Constructs a regular expression pattern buffer without any compilation
+ flags set, and using the default syntax (RESyntax.RE_SYNTAX_PERL5).</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../gnu/regexp/UncheckedRE.html#UncheckedRE(java.lang.Object, int)">UncheckedRE</A></B>(java.lang.Object pattern,
+ int cflags)</CODE>
+
+<BR>
+ Constructs a regular expression pattern buffer using the specified
+ compilation flags and the default syntax (RESyntax.RE_SYNTAX_PERL5).</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../gnu/regexp/UncheckedRE.html#UncheckedRE(java.lang.Object, int, gnu.regexp.RESyntax)">UncheckedRE</A></B>(java.lang.Object pattern,
+ int cflags,
+ <A HREF="../../gnu/regexp/RESyntax.html">RESyntax</A> syntax)</CODE>
+
+<BR>
+ Constructs a regular expression pattern buffer using the specified
+ compilation flags and regular expression syntax.</TD>
+</TR>
+</TABLE>
+
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="methods_inherited_from_class_gnu.regexp.RE"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Methods inherited from class gnu.regexp.<A HREF="../../gnu/regexp/RE.html">RE</A></B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><A HREF="../../gnu/regexp/RE.html#getAllMatches(java.lang.Object)">getAllMatches</A>, <A HREF="../../gnu/regexp/RE.html#getAllMatches(java.lang.Object, int)">getAllMatches</A>, <A HREF="../../gnu/regexp/RE.html#getAllMatches(java.lang.Object, int, int)">getAllMatches</A>, <A HREF="../../gnu/regexp/RE.html#getMatch(java.lang.Object)">getMatch</A>, <A HREF="../../gnu/regexp/RE.html#getMatch(java.lang.Object, int)">getMatch</A>, <A HREF="../../gnu/regexp/RE.html#getMatch(java.lang.Object, int, int)">getMatch</A>, <A HREF="../../gnu/regexp/RE.html#getMatch(java.lang.Object, int, int, java.lang.StringBuffer)">getMatch</A>, <A HREF="../../gnu/regexp/RE.html#getMatchEnumeration(java.lang.Object)">getMatchEnumeration</A>, <A HREF="../../gnu/regexp/RE.html#getMatchEnumeration(java.lang.Object, int)">getMatchEnumeration</A>, <A HREF="../../gnu/regexp/RE.html#getMatchEnumeration(java.lang.Object, int, int)">getMatchEnumeration</A>, <A HREF="../../gnu/regexp/RE.html#getMinimumLength()">getMinimumLength</A>, <A HREF="../../gnu/regexp/RE.html#getNumSubs()">getNumSubs</A>, <A HREF="../../gnu/regexp/RE.html#isMatch(java.lang.Object)">isMatch</A>, <A HREF="../../gnu/regexp/RE.html#isMatch(java.lang.Object, int)">isMatch</A>, <A HREF="../../gnu/regexp/RE.html#isMatch(java.lang.Object, int, int)">isMatch</A>, <A HREF="../../gnu/regexp/RE.html#substitute(java.lang.Object, java.lang.String)">substitute</A>, <A HREF="../../gnu/regexp/RE.html#substitute(java.lang.Object, java.lang.String, int)">substitute</A>, <A HREF="../../gnu/regexp/RE.html#substitute(java.lang.Object, java.lang.String, int, int)">substitute</A>, <A HREF="../../gnu/regexp/RE.html#substituteAll(java.lang.Object, java.lang.String)">substituteAll</A>, <A HREF="../../gnu/regexp/RE.html#substituteAll(java.lang.Object, java.lang.String, int)">substituteAll</A>, <A HREF="../../gnu/regexp/RE.html#substituteAll(java.lang.Object, java.lang.String, int, int)">substituteAll</A>, <A HREF="../../gnu/regexp/RE.html#toString()">toString</A>, <A HREF="../../gnu/regexp/RE.html#version()">version</A></CODE></TD>
+</TR>
+</TABLE>
+ <A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Methods inherited from class java.lang.Object</B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>equals, getClass, hashCode, notify, notifyAll, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="UncheckedRE(java.lang.Object)"><!-- --></A><H3>
+UncheckedRE</H3>
+<PRE>
+public <B>UncheckedRE</B>(java.lang.Object pattern)</PRE>
+<DL>
+<DD>Constructs a regular expression pattern buffer without any compilation
+ flags set, and using the default syntax (RESyntax.RE_SYNTAX_PERL5).<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>pattern</CODE> - A regular expression pattern, in the form of a String,
+ StringBuffer or char[]. Other input types will be converted to
+ strings using the toString() method.<DT><B>Throws:</B><DD><CODE>java.lang.RuntimeException</CODE> - The input pattern could not be parsed.<DD><CODE>NullPointerException</CODE> - The pattern was null.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="UncheckedRE(java.lang.Object, int)"><!-- --></A><H3>
+UncheckedRE</H3>
+<PRE>
+public <B>UncheckedRE</B>(java.lang.Object pattern,
+ int cflags)</PRE>
+<DL>
+<DD>Constructs a regular expression pattern buffer using the specified
+ compilation flags and the default syntax (RESyntax.RE_SYNTAX_PERL5).<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>pattern</CODE> - A regular expression pattern, in the form of a String,
+ StringBuffer, or char[]. Other input types will be converted to
+ strings using the toString() method.<DD><CODE>cflags</CODE> - The logical OR of any combination of the compilation flags in the RE class.<DT><B>Throws:</B><DD><CODE>java.lang.RuntimeException</CODE> - The input pattern could not be parsed.<DD><CODE>NullPointerException</CODE> - The pattern was null.</DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="UncheckedRE(java.lang.Object, int, gnu.regexp.RESyntax)"><!-- --></A><H3>
+UncheckedRE</H3>
+<PRE>
+public <B>UncheckedRE</B>(java.lang.Object pattern,
+ int cflags,
+ <A HREF="../../gnu/regexp/RESyntax.html">RESyntax</A> syntax)</PRE>
+<DL>
+<DD>Constructs a regular expression pattern buffer using the specified
+ compilation flags and regular expression syntax.<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>pattern</CODE> - A regular expression pattern, in the form of a String,
+ StringBuffer, or char[]. Other input types will be converted to
+ strings using the toString() method.<DD><CODE>cflags</CODE> - The logical OR of any combination of the compilation flags in the RE class.<DD><CODE>syntax</CODE> - The type of regular expression syntax to use.<DT><B>Throws:</B><DD><CODE>java.lang.RuntimeException</CODE> - The input pattern could not be parsed.<DD><CODE>NullPointerException</CODE> - The pattern was null.</DL>
+</DD>
+</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A> </TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> <FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A> </TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../gnu/regexp/RESyntax.html"><B>PREV CLASS</B></A>
+ NEXT CLASS</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../index.html" TARGET="_top"><B>FRAMES</B></A>
+ <A HREF="UncheckedRE.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: INNER | <A HREF="#fields_inherited_from_class_gnu.regexp.RE">FIELD</A> | <A HREF="#constructor_summary">CONSTR</A> | <A HREF="#methods_inherited_from_class_gnu.regexp.RE">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: FIELD | <A HREF="#constructor_detail">CONSTR</A> | METHOD</FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Sun Oct 21 14:27:45 PDT 2001 -->
+<TITLE>
+: Package gnu.regexp
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+<FONT size="+1" CLASS="FrameTitleFont">
+<A HREF="../../gnu/regexp/package-summary.html" TARGET="classFrame">gnu.regexp</A></FONT>
+<TABLE BORDER="0" WIDTH="100%">
+<TR>
+<TD NOWRAP><FONT size="+1" CLASS="FrameHeadingFont">
+Interfaces</FONT>
+<FONT CLASS="FrameItemFont">
+<BR>
+<A HREF="CharIndexed.html" TARGET="classFrame"><I>CharIndexed</I></A></FONT></TD>
+</TR>
+</TABLE>
+
+
+<TABLE BORDER="0" WIDTH="100%">
+<TR>
+<TD NOWRAP><FONT size="+1" CLASS="FrameHeadingFont">
+Classes</FONT>
+<FONT CLASS="FrameItemFont">
+<BR>
+<A HREF="RE.html" TARGET="classFrame">RE</A>
+<BR>
+<A HREF="REFilterInputStream.html" TARGET="classFrame">REFilterInputStream</A>
+<BR>
+<A HREF="REFilterReader.html" TARGET="classFrame">REFilterReader</A>
+<BR>
+<A HREF="REMatch.html" TARGET="classFrame">REMatch</A>
+<BR>
+<A HREF="REMatchEnumeration.html" TARGET="classFrame">REMatchEnumeration</A>
+<BR>
+<A HREF="RESyntax.html" TARGET="classFrame">RESyntax</A>
+<BR>
+<A HREF="UncheckedRE.html" TARGET="classFrame">UncheckedRE</A></FONT></TD>
+</TR>
+</TABLE>
+
+
+<TABLE BORDER="0" WIDTH="100%">
+<TR>
+<TD NOWRAP><FONT size="+1" CLASS="FrameHeadingFont">
+Exceptions</FONT>
+<FONT CLASS="FrameItemFont">
+<BR>
+<A HREF="REException.html" TARGET="classFrame">REException</A></FONT></TD>
+</TR>
+</TABLE>
+
+
+</BODY>
+</HTML>
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Sun Oct 21 14:27:45 PDT 2001 -->
+<TITLE>
+: Package gnu.regexp
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A> </TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> <FONT CLASS="NavBarFont1Rev"><B>Package</B></FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A> </TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ PREV PACKAGE
+ <A HREF="../../gnu/regexp/util/package-summary.html"><B>NEXT PACKAGE</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../index.html" TARGET="_top"><B>FRAMES</B></A>
+ <A HREF="package-summary.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<H2>
+Package gnu.regexp
+</H2>
+
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Interface Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="CharIndexed.html"><I>CharIndexed</I></A></B></TD>
+<TD>Defines the interface used internally so that different types of source
+ text can be accessed in the same way.</TD>
+</TR>
+</TABLE>
+
+
+<P>
+
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Class Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="RE.html">RE</A></B></TD>
+<TD>RE provides the user interface for compiling and matching regular
+ expressions.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="REFilterInputStream.html">REFilterInputStream</A></B></TD>
+<TD><B>Deprecated.</B> <I>This class cannot properly handle all character
+ encodings.</I></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="REFilterReader.html">REFilterReader</A></B></TD>
+<TD>Replaces instances of a given RE with replacement text.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="REMatch.html">REMatch</A></B></TD>
+<TD>An instance of this class represents a match
+ completed by a gnu.regexp matching function.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="REMatchEnumeration.html">REMatchEnumeration</A></B></TD>
+<TD>An REMatchEnumeration enumerates regular expression matches over a
+ given input text.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="RESyntax.html">RESyntax</A></B></TD>
+<TD>An RESyntax specifies the way a regular expression will be compiled.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="UncheckedRE.html">UncheckedRE</A></B></TD>
+<TD>UncheckedRE is a subclass of RE that allows programmers an easier means
+ of programmatically precompiling regular expressions.</TD>
+</TR>
+</TABLE>
+
+
+<P>
+
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Exception Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="REException.html">REException</A></B></TD>
+<TD>This is the regular expression exception class.</TD>
+</TR>
+</TABLE>
+
+
+<P>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A> </TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> <FONT CLASS="NavBarFont1Rev"><B>Package</B></FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A> </TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ PREV PACKAGE
+ <A HREF="../../gnu/regexp/util/package-summary.html"><B>NEXT PACKAGE</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../index.html" TARGET="_top"><B>FRAMES</B></A>
+ <A HREF="package-summary.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Sun Oct 21 14:27:45 PDT 2001 -->
+<TITLE>
+: gnu.regexp Class Hierarchy
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT> </TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> <FONT CLASS="NavBarFont1Rev"><B>Tree</B></FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A> </TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ PREV
+ <A HREF="../../gnu/regexp/util/package-tree.html"><B>NEXT</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../index.html" TARGET="_top"><B>FRAMES</B></A>
+ <A HREF="package-tree.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<CENTER>
+<H2>
+Hierarchy For Package gnu.regexp
+</H2>
+</CENTER>
+<DL>
+<DT><B>Package Hierarchies: </B><DD><A HREF="../../overview-tree.html">All Packages</A></DL>
+<HR>
+<H2>
+Class Hierarchy
+</H2>
+<UL>
+<LI TYPE="circle">class java.lang.Object<UL>
+<LI TYPE="circle">class java.io.InputStream<UL>
+<LI TYPE="circle">class java.io.FilterInputStream<UL>
+<LI TYPE="circle">class gnu.regexp.<A HREF="../../gnu/regexp/REFilterInputStream.html"><B>REFilterInputStream</B></A></UL>
+</UL>
+<LI TYPE="circle">class java.io.Reader<UL>
+<LI TYPE="circle">class java.io.FilterReader<UL>
+<LI TYPE="circle">class gnu.regexp.<A HREF="../../gnu/regexp/REFilterReader.html"><B>REFilterReader</B></A></UL>
+</UL>
+<LI TYPE="circle">class gnu.regexp.<A HREF="../../gnu/regexp/REMatch.html"><B>REMatch</B></A> (implements java.lang.Cloneable, java.io.Serializable)
+<LI TYPE="circle">class gnu.regexp.<A HREF="../../gnu/regexp/REMatchEnumeration.html"><B>REMatchEnumeration</B></A> (implements java.util.Enumeration, java.io.Serializable)
+<LI TYPE="circle">class gnu.regexp.<A HREF="../../gnu/regexp/RESyntax.html"><B>RESyntax</B></A> (implements java.io.Serializable)
+<LI TYPE="circle">class gnu.regexp.REToken (implements java.io.Serializable)
+<UL>
+<LI TYPE="circle">class gnu.regexp.<A HREF="../../gnu/regexp/RE.html"><B>RE</B></A><UL>
+<LI TYPE="circle">class gnu.regexp.<A HREF="../../gnu/regexp/UncheckedRE.html"><B>UncheckedRE</B></A></UL>
+</UL>
+<LI TYPE="circle">class java.lang.Throwable (implements java.io.Serializable)
+<UL>
+<LI TYPE="circle">class java.lang.Exception<UL>
+<LI TYPE="circle">class gnu.regexp.<A HREF="../../gnu/regexp/REException.html"><B>REException</B></A></UL>
+</UL>
+</UL>
+</UL>
+<H2>
+Interface Hierarchy
+</H2>
+<UL>
+<LI TYPE="circle">interface gnu.regexp.<A HREF="../../gnu/regexp/CharIndexed.html"><B>CharIndexed</B></A></UL>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT> </TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> <FONT CLASS="NavBarFont1Rev"><B>Tree</B></FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A> </TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ PREV
+ <A HREF="../../gnu/regexp/util/package-tree.html"><B>NEXT</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../index.html" TARGET="_top"><B>FRAMES</B></A>
+ <A HREF="package-tree.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Sun Oct 21 14:27:46 PDT 2001 -->
+<TITLE>
+: Class Egrep
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A> </TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> <FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A> </TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ PREV CLASS
+ <A HREF="../../../gnu/regexp/util/Grep.html"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html" TARGET="_top"><B>FRAMES</B></A>
+ <A HREF="Egrep.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: INNER | FIELD | CONSTR | <A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: FIELD | CONSTR | <A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+gnu.regexp.util</FONT>
+<BR>
+Class Egrep</H2>
+<PRE>
+java.lang.Object
+ |
+ +--<B>gnu.regexp.util.Egrep</B>
+</PRE>
+<HR>
+<DL>
+<DT>public class <B>Egrep</B><DT>extends java.lang.Object</DL>
+
+<P>
+This is a front end to the gnu.regexp.util.Grep class which sets the
+ syntax used to RE_SYNTAX_EGREP, which aims to emulate the standard UNIX
+ egrep command.
+<P>
+<DL>
+<DT><B>Version: </B><DD>1.01</DD>
+<DT><B>Author: </B><DD><A HREF="mailto:wes@cacas.org">Wes Biggs</A></DD>
+</DL>
+<HR>
+
+<P>
+<!-- ======== INNER CLASS SUMMARY ======== -->
+
+
+<!-- =========== FIELD SUMMARY =========== -->
+
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../gnu/regexp/util/Egrep.html#main(java.lang.String[])">main</A></B>(java.lang.String[] argv)</CODE>
+
+<BR>
+ Invokes Grep.grep() using the RE_SYNTAX_EGREP syntax and the
+ command line arguments specified.</TD>
+</TR>
+</TABLE>
+ <A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Methods inherited from class java.lang.Object</B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="main(java.lang.String[])"><!-- --></A><H3>
+main</H3>
+<PRE>
+public static void <B>main</B>(java.lang.String[] argv)</PRE>
+<DL>
+<DD>Invokes Grep.grep() using the RE_SYNTAX_EGREP syntax and the
+ command line arguments specified. Output is sent to System.out.
+ For a list of options, use the argument "--help".</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A> </TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> <FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A> </TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ PREV CLASS
+ <A HREF="../../../gnu/regexp/util/Grep.html"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html" TARGET="_top"><B>FRAMES</B></A>
+ <A HREF="Egrep.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: INNER | FIELD | CONSTR | <A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: FIELD | CONSTR | <A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Sun Oct 21 14:27:46 PDT 2001 -->
+<TITLE>
+: Class Grep
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A> </TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> <FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A> </TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../gnu/regexp/util/Egrep.html"><B>PREV CLASS</B></A>
+ <A HREF="../../../gnu/regexp/util/REApplet.html"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html" TARGET="_top"><B>FRAMES</B></A>
+ <A HREF="Grep.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: INNER | FIELD | CONSTR | <A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: FIELD | CONSTR | <A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+gnu.regexp.util</FONT>
+<BR>
+Class Grep</H2>
+<PRE>
+java.lang.Object
+ |
+ +--<B>gnu.regexp.util.Grep</B>
+</PRE>
+<HR>
+<DL>
+<DT>public class <B>Grep</B><DT>extends java.lang.Object</DL>
+
+<P>
+Grep is a pure-Java clone of the GNU grep utility. As such, it is much
+ slower and not as full-featured, but it has the advantage of being
+ available on any system with a Java virtual machine.
+<P>
+<DL>
+<DT><B>Version: </B><DD>1.03</DD>
+<DT><B>Author: </B><DD><A HREF="mailto:wes@cacas.org">Wes Biggs</A>
+ <A HREF="http://www.csis.hku.hk/~sdlee/">Lee Sau Dan</A>
+ <A HREF="http://www.capital.net/~dittmer/">Ulf Dittmer</A></DD>
+</DL>
+<HR>
+
+<P>
+<!-- ======== INNER CLASS SUMMARY ======== -->
+
+
+<!-- =========== FIELD SUMMARY =========== -->
+
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static int</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../gnu/regexp/util/Grep.html#grep(java.lang.String[], gnu.regexp.RESyntax, java.io.PrintStream)">grep</A></B>(java.lang.String[] argv,
+ <A HREF="../../../gnu/regexp/RESyntax.html">RESyntax</A> syntax,
+ java.io.PrintStream out)</CODE>
+
+<BR>
+ Runs Grep with the specified arguments.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../gnu/regexp/util/Grep.html#main(java.lang.String[])">main</A></B>(java.lang.String[] argv)</CODE>
+
+<BR>
+ Invokes the grep() function below with the command line arguments
+ and using the RESyntax.RE_SYNTAX_GREP syntax, which attempts to
+ emulate the traditional UNIX grep syntax.</TD>
+</TR>
+</TABLE>
+ <A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Methods inherited from class java.lang.Object</B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="main(java.lang.String[])"><!-- --></A><H3>
+main</H3>
+<PRE>
+public static void <B>main</B>(java.lang.String[] argv)</PRE>
+<DL>
+<DD>Invokes the grep() function below with the command line arguments
+ and using the RESyntax.RE_SYNTAX_GREP syntax, which attempts to
+ emulate the traditional UNIX grep syntax.</DL>
+<HR>
+
+<A NAME="grep(java.lang.String[], gnu.regexp.RESyntax, java.io.PrintStream)"><!-- --></A><H3>
+grep</H3>
+<PRE>
+public static int <B>grep</B>(java.lang.String[] argv,
+ <A HREF="../../../gnu/regexp/RESyntax.html">RESyntax</A> syntax,
+ java.io.PrintStream out)</PRE>
+<DL>
+<DD>Runs Grep with the specified arguments. For a list of
+ supported options, specify "--help".
+
+ This is the meat of the grep routine, but unlike main(), you can
+ specify your own syntax and PrintStream to use for output.</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A> </TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> <FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A> </TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../gnu/regexp/util/Egrep.html"><B>PREV CLASS</B></A>
+ <A HREF="../../../gnu/regexp/util/REApplet.html"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html" TARGET="_top"><B>FRAMES</B></A>
+ <A HREF="Grep.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: INNER | FIELD | CONSTR | <A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: FIELD | CONSTR | <A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Sun Oct 21 14:27:46 PDT 2001 -->
+<TITLE>
+: Class REApplet
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A> </TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> <FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A> </TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../gnu/regexp/util/Grep.html"><B>PREV CLASS</B></A>
+ <A HREF="../../../gnu/regexp/util/RETest.html"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html" TARGET="_top"><B>FRAMES</B></A>
+ <A HREF="REApplet.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: INNER | <A HREF="#fields_inherited_from_class_java.awt.Component">FIELD</A> | <A HREF="#constructor_summary">CONSTR</A> | <A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: FIELD | <A HREF="#constructor_detail">CONSTR</A> | <A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+gnu.regexp.util</FONT>
+<BR>
+Class REApplet</H2>
+<PRE>
+java.lang.Object
+ |
+ +--java.awt.Component
+ |
+ +--java.awt.Container
+ |
+ +--java.awt.Panel
+ |
+ +--java.applet.Applet
+ |
+ +--<B>gnu.regexp.util.REApplet</B>
+</PRE>
+<DL>
+<DT><B>All Implemented Interfaces:</B> <DD>javax.accessibility.Accessible, java.awt.image.ImageObserver, java.awt.MenuContainer, java.io.Serializable</DD>
+</DL>
+<HR>
+<DL>
+<DT>public class <B>REApplet</B><DT>extends java.applet.Applet</DL>
+
+<P>
+This is a simple applet to demonstrate the capabilities of gnu.regexp.
+ To run it, use appletviewer on the reapplet.html file included in the
+ documentation directory.
+<P>
+<DL>
+<DT><B>Version: </B><DD>1.02</DD>
+<DT><B>Author: </B><DD><A HREF="mailto:wes@cacas.org">Wes Biggs</A></DD>
+<DT><B>See Also: </B><DD><A HREF="../../../serialized-form.html#gnu.regexp.util.REApplet">Serialized Form</A></DL>
+<HR>
+
+<P>
+<!-- ======== INNER CLASS SUMMARY ======== -->
+
+
+<!-- =========== FIELD SUMMARY =========== -->
+
+<A NAME="fields_inherited_from_class_java.awt.Component"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Fields inherited from class java.awt.Component</B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>BOTTOM_ALIGNMENT, CENTER_ALIGNMENT, LEFT_ALIGNMENT, RIGHT_ALIGNMENT, TOP_ALIGNMENT</CODE></TD>
+</TR>
+</TABLE>
+ <A NAME="fields_inherited_from_class_java.awt.image.ImageObserver"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Fields inherited from interface java.awt.image.ImageObserver</B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>ABORT, ALLBITS, ERROR, FRAMEBITS, HEIGHT, PROPERTIES, SOMEBITS, WIDTH</CODE></TD>
+</TR>
+</TABLE>
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+<A NAME="constructor_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Constructor Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE><B><A HREF="../../../gnu/regexp/util/REApplet.html#REApplet()">REApplet</A></B>()</CODE>
+
+<BR>
+ Creates an REApplet.</TD>
+</TR>
+</TABLE>
+
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE> boolean</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../gnu/regexp/util/REApplet.html#action(java.awt.Event, java.lang.Object)">action</A></B>(java.awt.Event e,
+ java.lang.Object arg)</CODE>
+
+<BR>
+ Handles events in the applet.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE> void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../gnu/regexp/util/REApplet.html#init()">init</A></B>()</CODE>
+
+<BR>
+ Initializes the applet and constructs GUI elements.</TD>
+</TR>
+</TABLE>
+ <A NAME="methods_inherited_from_class_java.applet.Applet"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Methods inherited from class java.applet.Applet</B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>destroy, getAccessibleContext, getAppletContext, getAppletInfo, getAudioClip, getAudioClip, getCodeBase, getDocumentBase, getImage, getImage, getLocale, getParameter, getParameterInfo, isActive, newAudioClip, play, play, resize, resize, setStub, showStatus, start, stop</CODE></TD>
+</TR>
+</TABLE>
+ <A NAME="methods_inherited_from_class_java.awt.Panel"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Methods inherited from class java.awt.Panel</B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>addNotify</CODE></TD>
+</TR>
+</TABLE>
+ <A NAME="methods_inherited_from_class_java.awt.Container"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Methods inherited from class java.awt.Container</B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>add, add, add, add, add, addContainerListener, countComponents, deliverEvent, doLayout, findComponentAt, findComponentAt, getAlignmentX, getAlignmentY, getComponent, getComponentAt, getComponentAt, getComponentCount, getComponents, getInsets, getLayout, getListeners, getMaximumSize, getMinimumSize, getPreferredSize, insets, invalidate, isAncestorOf, layout, list, list, locate, minimumSize, paint, paintComponents, preferredSize, print, printComponents, remove, remove, removeAll, removeContainerListener, removeNotify, setFont, setLayout, update, validate</CODE></TD>
+</TR>
+</TABLE>
+ <A NAME="methods_inherited_from_class_java.awt.Component"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Methods inherited from class java.awt.Component</B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>add, addComponentListener, addFocusListener, addHierarchyBoundsListener, addHierarchyListener, addInputMethodListener, addKeyListener, addMouseListener, addMouseMotionListener, addPropertyChangeListener, addPropertyChangeListener, bounds, checkImage, checkImage, contains, contains, createImage, createImage, disable, dispatchEvent, enable, enable, enableInputMethods, getBackground, getBounds, getBounds, getColorModel, getComponentOrientation, getCursor, getDropTarget, getFont, getFontMetrics, getForeground, getGraphics, getGraphicsConfiguration, getHeight, getInputContext, getInputMethodRequests, getLocation, getLocation, getLocationOnScreen, getName, getParent, getPeer, getSize, getSize, getToolkit, getTreeLock, getWidth, getX, getY, gotFocus, handleEvent, hasFocus, hide, imageUpdate, inside, isDisplayable, isDoubleBuffered, isEnabled, isFocusTraversable, isLightweight, isOpaque, isShowing, isValid, isVisible, keyDown, keyUp, list, list, list, location, lostFocus, mouseDown, mouseDrag, mouseEnter, mouseExit, mouseMove, mouseUp, move, nextFocus, paintAll, postEvent, prepareImage, prepareImage, printAll, remove, removeComponentListener, removeFocusListener, removeHierarchyBoundsListener, removeHierarchyListener, removeInputMethodListener, removeKeyListener, removeMouseListener, removeMouseMotionListener, removePropertyChangeListener, removePropertyChangeListener, repaint, repaint, repaint, repaint, requestFocus, reshape, setBackground, setBounds, setBounds, setComponentOrientation, setCursor, setDropTarget, setEnabled, setForeground, setLocale, setLocation, setLocation, setName, setSize, setSize, setVisible, show, show, size, toString, transferFocus</CODE></TD>
+</TR>
+</TABLE>
+ <A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Methods inherited from class java.lang.Object</B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>equals, getClass, hashCode, notify, notifyAll, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+<A NAME="constructor_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Constructor Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="REApplet()"><!-- --></A><H3>
+REApplet</H3>
+<PRE>
+public <B>REApplet</B>()</PRE>
+<DL>
+<DD>Creates an REApplet.</DL>
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="init()"><!-- --></A><H3>
+init</H3>
+<PRE>
+public void <B>init</B>()</PRE>
+<DL>
+<DD>Initializes the applet and constructs GUI elements.<DD><DL>
+<DT><B>Overrides:</B><DD><CODE>init</CODE> in class <CODE>java.applet.Applet</CODE></DL>
+</DD>
+</DL>
+<HR>
+
+<A NAME="action(java.awt.Event, java.lang.Object)"><!-- --></A><H3>
+action</H3>
+<PRE>
+public boolean <B>action</B>(java.awt.Event e,
+ java.lang.Object arg)</PRE>
+<DL>
+<DD>Handles events in the applet. Returns true if the indicated event
+ was handled, false for all other events.<DD><DL>
+<DT><B>Overrides:</B><DD><CODE>action</CODE> in class <CODE>java.awt.Component</CODE></DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A> </TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> <FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A> </TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../gnu/regexp/util/Grep.html"><B>PREV CLASS</B></A>
+ <A HREF="../../../gnu/regexp/util/RETest.html"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html" TARGET="_top"><B>FRAMES</B></A>
+ <A HREF="REApplet.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: INNER | <A HREF="#fields_inherited_from_class_java.awt.Component">FIELD</A> | <A HREF="#constructor_summary">CONSTR</A> | <A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: FIELD | <A HREF="#constructor_detail">CONSTR</A> | <A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Sun Oct 21 14:27:46 PDT 2001 -->
+<TITLE>
+: Class RETest
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A> </TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> <FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A> </TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../gnu/regexp/util/REApplet.html"><B>PREV CLASS</B></A>
+ <A HREF="../../../gnu/regexp/util/Tests.html"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html" TARGET="_top"><B>FRAMES</B></A>
+ <A HREF="RETest.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: INNER | FIELD | CONSTR | <A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: FIELD | CONSTR | <A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+gnu.regexp.util</FONT>
+<BR>
+Class RETest</H2>
+<PRE>
+java.lang.Object
+ |
+ +--<B>gnu.regexp.util.RETest</B>
+</PRE>
+<HR>
+<DL>
+<DT>public class <B>RETest</B><DT>extends java.lang.Object</DL>
+
+<P>
+RETest provides a simple way to test regular expressions.
+ It runs from the command line using the Java interpreter.
+ To use it, enter the following from a command prompt (provided
+ that the Java system knows where to find the RETest bytecodes):
+ <BR><CODE>java gnu.regexp.util.RETest [regExp] [inputString]</CODE><BR>
+ where <i>regExp</i> is a regular expression (you'll probably have
+ to escape shell meta-characters) and <i>inputString</i> is the string
+ to match against (again, put it in quotes or escape any shell meta-
+ characters).
+ <P>
+ The test function will report the package version number, whether
+ the expression matches the input string, what the match it found was,
+ and the contents of any subexpressions, if applicable.
+ <P>
+ You may optionally add a third integer argument which is the number of
+ times to repeat the test. When this option is used, RETest will report
+ average compile and match times.
+<P>
+<DL>
+<DT><B>Version: </B><DD>1.01</DD>
+<DT><B>Author: </B><DD><A HREF="mailto:wes@cacas.org">Wes Biggs</A></DD>
+</DL>
+<HR>
+
+<P>
+<!-- ======== INNER CLASS SUMMARY ======== -->
+
+
+<!-- =========== FIELD SUMMARY =========== -->
+
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../gnu/regexp/util/RETest.html#main(java.lang.String[])">main</A></B>(java.lang.String[] argv)</CODE>
+
+<BR>
+ Invokes the test function with the command line arguments specified.</TD>
+</TR>
+</TABLE>
+ <A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Methods inherited from class java.lang.Object</B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="main(java.lang.String[])"><!-- --></A><H3>
+main</H3>
+<PRE>
+public static void <B>main</B>(java.lang.String[] argv)
+ throws <A HREF="../../../gnu/regexp/REException.html">REException</A></PRE>
+<DL>
+<DD>Invokes the test function with the command line arguments specified.
+ See class description for usage notes.<DD><DL>
+<DT><B>Parameters:</B><DD><CODE>argv</CODE> - The command line arguments.<DT><B>Throws:</B><DD><CODE><A HREF="../../../gnu/regexp/REException.html">REException</A></CODE> - There was an error compiling or executing the regular expression.</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A> </TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> <FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A> </TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../gnu/regexp/util/REApplet.html"><B>PREV CLASS</B></A>
+ <A HREF="../../../gnu/regexp/util/Tests.html"><B>NEXT CLASS</B></A></FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html" TARGET="_top"><B>FRAMES</B></A>
+ <A HREF="RETest.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: INNER | FIELD | CONSTR | <A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: FIELD | CONSTR | <A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Sun Oct 21 14:27:46 PDT 2001 -->
+<TITLE>
+: Class Tests
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A> </TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> <FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A> </TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../gnu/regexp/util/RETest.html"><B>PREV CLASS</B></A>
+ NEXT CLASS</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html" TARGET="_top"><B>FRAMES</B></A>
+ <A HREF="Tests.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: INNER | FIELD | CONSTR | <A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: FIELD | CONSTR | <A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<!-- ======== START OF CLASS DATA ======== -->
+<H2>
+<FONT SIZE="-1">
+gnu.regexp.util</FONT>
+<BR>
+Class Tests</H2>
+<PRE>
+java.lang.Object
+ |
+ +--<B>gnu.regexp.util.Tests</B>
+</PRE>
+<HR>
+<DL>
+<DT>public class <B>Tests</B><DT>extends java.lang.Object</DL>
+
+<P>
+This is a very basic testsuite application for gnu.regexp.
+<P>
+<DL>
+<DT><B>Version: </B><DD>1.1.1</DD>
+<DT><B>Author: </B><DD><A HREF="mailto:wes@cacas.org">Wes Biggs</A></DD>
+</DL>
+<HR>
+
+<P>
+<!-- ======== INNER CLASS SUMMARY ======== -->
+
+
+<!-- =========== FIELD SUMMARY =========== -->
+
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+
+
+<!-- ========== METHOD SUMMARY =========== -->
+
+<A NAME="method_summary"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Method Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD ALIGN="right" VALIGN="top" WIDTH="1%"><FONT SIZE="-1">
+<CODE>static void</CODE></FONT></TD>
+<TD><CODE><B><A HREF="../../../gnu/regexp/util/Tests.html#main(java.lang.String[])">main</A></B>(java.lang.String[] argv)</CODE>
+
+<BR>
+ Runs the testsuite.</TD>
+</TR>
+</TABLE>
+ <A NAME="methods_inherited_from_class_java.lang.Object"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#EEEEFF" CLASS="TableSubHeadingColor">
+<TD><B>Methods inherited from class java.lang.Object</B></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD><CODE>equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait</CODE></TD>
+</TR>
+</TABLE>
+
+<P>
+
+<!-- ============ FIELD DETAIL =========== -->
+
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+
+
+<!-- ============ METHOD DETAIL ========== -->
+
+<A NAME="method_detail"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Method Detail</B></FONT></TD>
+</TR>
+</TABLE>
+
+<A NAME="main(java.lang.String[])"><!-- --></A><H3>
+main</H3>
+<PRE>
+public static void <B>main</B>(java.lang.String[] argv)
+ throws <A HREF="../../../gnu/regexp/REException.html">REException</A></PRE>
+<DL>
+<DD>Runs the testsuite. No command line arguments are necessary.<DD><DL>
+<DT><B>Throws:</B><DD><CODE><A HREF="../../../gnu/regexp/REException.html">REException</A></CODE> - An error occurred compiling a regular expression.</DL>
+</DD>
+</DL>
+<!-- ========= END OF CLASS DATA ========= -->
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A> </TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> <FONT CLASS="NavBarFont1Rev"><B>Class</B></FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A> </TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../gnu/regexp/util/RETest.html"><B>PREV CLASS</B></A>
+ NEXT CLASS</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html" TARGET="_top"><B>FRAMES</B></A>
+ <A HREF="Tests.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+<TR>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+ SUMMARY: INNER | FIELD | CONSTR | <A HREF="#method_summary">METHOD</A></FONT></TD>
+<TD VALIGN="top" CLASS="NavBarCell3"><FONT SIZE="-2">
+DETAIL: FIELD | CONSTR | <A HREF="#method_detail">METHOD</A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Sun Oct 21 14:27:45 PDT 2001 -->
+<TITLE>
+: Package gnu.regexp.util
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+<FONT size="+1" CLASS="FrameTitleFont">
+<A HREF="../../../gnu/regexp/util/package-summary.html" TARGET="classFrame">gnu.regexp.util</A></FONT>
+<TABLE BORDER="0" WIDTH="100%">
+<TR>
+<TD NOWRAP><FONT size="+1" CLASS="FrameHeadingFont">
+Classes</FONT>
+<FONT CLASS="FrameItemFont">
+<BR>
+<A HREF="Egrep.html" TARGET="classFrame">Egrep</A>
+<BR>
+<A HREF="Grep.html" TARGET="classFrame">Grep</A>
+<BR>
+<A HREF="REApplet.html" TARGET="classFrame">REApplet</A>
+<BR>
+<A HREF="RETest.html" TARGET="classFrame">RETest</A>
+<BR>
+<A HREF="Tests.html" TARGET="classFrame">Tests</A></FONT></TD>
+</TR>
+</TABLE>
+
+
+</BODY>
+</HTML>
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Sun Oct 21 14:27:45 PDT 2001 -->
+<TITLE>
+: Package gnu.regexp.util
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A> </TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> <FONT CLASS="NavBarFont1Rev"><B>Package</B></FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A> </TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../gnu/regexp/package-summary.html"><B>PREV PACKAGE</B></A>
+ NEXT PACKAGE</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html" TARGET="_top"><B>FRAMES</B></A>
+ <A HREF="package-summary.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<H2>
+Package gnu.regexp.util
+</H2>
+
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Class Summary</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="Egrep.html">Egrep</A></B></TD>
+<TD>This is a front end to the gnu.regexp.util.Grep class which sets the
+ syntax used to RE_SYNTAX_EGREP, which aims to emulate the standard UNIX
+ egrep command.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="Grep.html">Grep</A></B></TD>
+<TD>Grep is a pure-Java clone of the GNU grep utility.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="REApplet.html">REApplet</A></B></TD>
+<TD>This is a simple applet to demonstrate the capabilities of gnu.regexp.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="RETest.html">RETest</A></B></TD>
+<TD>RETest provides a simple way to test regular expressions.</TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="15%"><B><A HREF="Tests.html">Tests</A></B></TD>
+<TD>This is a very basic testsuite application for gnu.regexp.</TD>
+</TR>
+</TABLE>
+
+
+<P>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A> </TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> <FONT CLASS="NavBarFont1Rev"><B>Package</B></FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A> </TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../gnu/regexp/package-summary.html"><B>PREV PACKAGE</B></A>
+ NEXT PACKAGE</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html" TARGET="_top"><B>FRAMES</B></A>
+ <A HREF="package-summary.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Sun Oct 21 14:27:45 PDT 2001 -->
+<TITLE>
+: gnu.regexp.util Class Hierarchy
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT> </TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> <FONT CLASS="NavBarFont1Rev"><B>Tree</B></FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A> </TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../gnu/regexp/package-tree.html"><B>PREV</B></A>
+ NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html" TARGET="_top"><B>FRAMES</B></A>
+ <A HREF="package-tree.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<CENTER>
+<H2>
+Hierarchy For Package gnu.regexp.util
+</H2>
+</CENTER>
+<DL>
+<DT><B>Package Hierarchies: </B><DD><A HREF="../../../overview-tree.html">All Packages</A></DL>
+<HR>
+<H2>
+Class Hierarchy
+</H2>
+<UL>
+<LI TYPE="circle">class java.lang.Object<UL>
+<LI TYPE="circle">class java.awt.Component (implements java.awt.image.ImageObserver, java.awt.MenuContainer, java.io.Serializable)
+<UL>
+<LI TYPE="circle">class java.awt.Container<UL>
+<LI TYPE="circle">class java.awt.Panel (implements javax.accessibility.Accessible)
+<UL>
+<LI TYPE="circle">class java.applet.Applet<UL>
+<LI TYPE="circle">class gnu.regexp.util.<A HREF="../../../gnu/regexp/util/REApplet.html"><B>REApplet</B></A></UL>
+</UL>
+</UL>
+</UL>
+<LI TYPE="circle">class gnu.regexp.util.<A HREF="../../../gnu/regexp/util/Egrep.html"><B>Egrep</B></A><LI TYPE="circle">class gnu.regexp.util.<A HREF="../../../gnu/regexp/util/Grep.html"><B>Grep</B></A><LI TYPE="circle">class gnu.regexp.util.<A HREF="../../../gnu/regexp/util/RETest.html"><B>RETest</B></A><LI TYPE="circle">class gnu.regexp.util.<A HREF="../../../gnu/regexp/util/Tests.html"><B>Tests</B></A></UL>
+</UL>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="package-summary.html"><FONT CLASS="NavBarFont1"><B>Package</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT> </TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> <FONT CLASS="NavBarFont1Rev"><B>Tree</B></FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="../../../help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A> </TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../gnu/regexp/package-tree.html"><B>PREV</B></A>
+ NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="../../../index.html" TARGET="_top"><B>FRAMES</B></A>
+ <A HREF="package-tree.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Sun Oct 21 14:27:46 PDT 2001 -->
+<TITLE>
+: API Help
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A> </TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> <FONT CLASS="NavBarFont1Rev"><B>Help</B></FONT> </TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ PREV
+ NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="index.html" TARGET="_top"><B>FRAMES</B></A>
+ <A HREF="help-doc.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<CENTER>
+<H1>
+How This API Document Is Organized</H1>
+</CENTER>
+This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.<H3>
+Overview</H3>
+<BLOCKQUOTE>
+
+<P>
+The <A HREF="overview-summary.html">Overview</A> page is the front page of this API document and provides a list of all packages with a summary for each. This page can also contain an overall description of the set of packages.</BLOCKQUOTE>
+<H3>
+Package</H3>
+<BLOCKQUOTE>
+
+<P>
+Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain four categories:<UL>
+<LI>Interfaces (italic)<LI>Classes<LI>Exceptions<LI>Errors</UL>
+</BLOCKQUOTE>
+<H3>
+Class/Interface</H3>
+<BLOCKQUOTE>
+
+<P>
+Each class, interface, inner class and inner interface has its own separate page. Each of these pages has three sections consisting of a class/interface description, summary tables, and detailed member descriptions:<UL>
+<LI>Class inheritance diagram<LI>Direct Subclasses<LI>All Known Subinterfaces<LI>All Known Implementing Classes<LI>Class/interface declaration<LI>Class/interface description
+<P>
+<LI>Inner Class Summary<LI>Field Summary<LI>Constructor Summary<LI>Method Summary
+<P>
+<LI>Field Detail<LI>Constructor Detail<LI>Method Detail</UL>
+Each summary entry contains the first sentence from the detailed description for that item. The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.</BLOCKQUOTE>
+<H3>
+Tree (Class Hierarchy)</H3>
+<BLOCKQUOTE>
+There is a <A HREF="overview-tree.html">Class Hierarchy</A> page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by inheritance structure starting with <code>java.lang.Object</code>. The interfaces do not inherit from <code>java.lang.Object</code>.<UL>
+<LI>When viewing the Overview page, clicking on "Tree" displays the hierarchy for all packages.<LI>When viewing a particular package, class or interface page, clicking "Tree" displays the hierarchy for only that package.</UL>
+</BLOCKQUOTE>
+<H3>
+Deprecated API</H3>
+<BLOCKQUOTE>
+The <A HREF="deprecated-list.html">Deprecated API</A> page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.</BLOCKQUOTE>
+<H3>
+Index</H3>
+<BLOCKQUOTE>
+The <A HREF="index-all.html">Index</A> contains an alphabetic list of all classes, interfaces, constructors, methods, and fields.</BLOCKQUOTE>
+<H3>
+Prev/Next</H3>
+These links take you to the next or previous class, interface, package, or related page.<H3>
+Frames/No Frames</H3>
+These links show and hide the HTML frames. All pages are available with or without frames.
+<P>
+<H3>
+Serialized Form</H3>
+Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description.
+<P>
+<FONT SIZE="-1">
+<EM>
+This help file applies to API documentation generated using the standard doclet. </EM>
+</FONT>
+<BR>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A> </TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> <FONT CLASS="NavBarFont1Rev"><B>Help</B></FONT> </TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ PREV
+ NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="index.html" TARGET="_top"><B>FRAMES</B></A>
+ <A HREF="help-doc.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Sun Oct 21 14:27:45 PDT 2001 -->
+<TITLE>
+: Index
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A> </TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> <FONT CLASS="NavBarFont1Rev"><B>Index</B></FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A> </TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ PREV
+ NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="index.html" TARGET="_top"><B>FRAMES</B></A>
+ <A HREF="index-all.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<A HREF="#_A_">A</A> <A HREF="#_C_">C</A> <A HREF="#_E_">E</A> <A HREF="#_G_">G</A> <A HREF="#_H_">H</A> <A HREF="#_I_">I</A> <A HREF="#_M_">M</A> <A HREF="#_N_">N</A> <A HREF="#_O_">O</A> <A HREF="#_R_">R</A> <A HREF="#_S_">S</A> <A HREF="#_T_">T</A> <A HREF="#_U_">U</A> <A HREF="#_V_">V</A> <HR>
+<A NAME="_A_"><!-- --></A><H2>
+<B>A</B></H2>
+<DL>
+<DT><A HREF="gnu/regexp/util/REApplet.html#action(java.awt.Event, java.lang.Object)"><B>action(Event, Object)</B></A> -
+Method in class gnu.regexp.util.<A HREF="gnu/regexp/util/REApplet.html">REApplet</A>
+<DD>Handles events in the applet.
+</DL>
+<HR>
+<A NAME="_C_"><!-- --></A><H2>
+<B>C</B></H2>
+<DL>
+<DT><A HREF="gnu/regexp/CharIndexed.html#charAt(int)"><B>charAt(int)</B></A> -
+Method in interface gnu.regexp.<A HREF="gnu/regexp/CharIndexed.html">CharIndexed</A>
+<DD>Returns the character at the given offset past the current cursor
+ position in the input.
+<DT><A HREF="gnu/regexp/CharIndexed.html"><B>CharIndexed</B></A> - interface gnu.regexp.<A HREF="gnu/regexp/CharIndexed.html">CharIndexed</A>.<DD>Defines the interface used internally so that different types of source
+ text can be accessed in the same way.<DT><A HREF="gnu/regexp/RESyntax.html#clear(int)"><B>clear(int)</B></A> -
+Method in class gnu.regexp.<A HREF="gnu/regexp/RESyntax.html">RESyntax</A>
+<DD>Clear a given bit in this syntax.
+<DT><A HREF="gnu/regexp/REMatch.html#clone()"><B>clone()</B></A> -
+Method in class gnu.regexp.<A HREF="gnu/regexp/REMatch.html">REMatch</A>
+<DD>
+</DL>
+<HR>
+<A NAME="_E_"><!-- --></A><H2>
+<B>E</B></H2>
+<DL>
+<DT><A HREF="gnu/regexp/util/Egrep.html"><B>Egrep</B></A> - class gnu.regexp.util.<A HREF="gnu/regexp/util/Egrep.html">Egrep</A>.<DD>This is a front end to the gnu.regexp.util.Grep class which sets the
+ syntax used to RE_SYNTAX_EGREP, which aims to emulate the standard UNIX
+ egrep command.</DL>
+<HR>
+<A NAME="_G_"><!-- --></A><H2>
+<B>G</B></H2>
+<DL>
+<DT><A HREF="gnu/regexp/RESyntax.html#get(int)"><B>get(int)</B></A> -
+Method in class gnu.regexp.<A HREF="gnu/regexp/RESyntax.html">RESyntax</A>
+<DD>Check if a given bit is set in this syntax.
+<DT><A HREF="gnu/regexp/RE.html#getAllMatches(java.lang.Object)"><B>getAllMatches(Object)</B></A> -
+Method in class gnu.regexp.<A HREF="gnu/regexp/RE.html">RE</A>
+<DD>Returns an array of all matches found in the input.
+<DT><A HREF="gnu/regexp/RE.html#getAllMatches(java.lang.Object, int)"><B>getAllMatches(Object, int)</B></A> -
+Method in class gnu.regexp.<A HREF="gnu/regexp/RE.html">RE</A>
+<DD>Returns an array of all matches found in the input,
+ beginning at the specified index position.
+<DT><A HREF="gnu/regexp/RE.html#getAllMatches(java.lang.Object, int, int)"><B>getAllMatches(Object, int, int)</B></A> -
+Method in class gnu.regexp.<A HREF="gnu/regexp/RE.html">RE</A>
+<DD>Returns an array of all matches found in the input string,
+ beginning at the specified index position and using the specified
+ execution flags.
+<DT><A HREF="gnu/regexp/REMatch.html#getEndIndex()"><B>getEndIndex()</B></A> -
+Method in class gnu.regexp.<A HREF="gnu/regexp/REMatch.html">REMatch</A>
+<DD>Returns the index within the input string where the match in
+ its entirety ends.
+<DT><A HREF="gnu/regexp/REMatch.html#getEndIndex(int)"><B>getEndIndex(int)</B></A> -
+Method in class gnu.regexp.<A HREF="gnu/regexp/REMatch.html">REMatch</A>
+<DD>Returns the index within the input string used to generate this match
+ where subexpression number <i>sub</i> ends, or <code>-1</code> if
+ the subexpression does not exist.
+<DT><A HREF="gnu/regexp/RESyntax.html#getLineSeparator()"><B>getLineSeparator()</B></A> -
+Method in class gnu.regexp.<A HREF="gnu/regexp/RESyntax.html">RESyntax</A>
+<DD>Returns the currently active line separator string.
+<DT><A HREF="gnu/regexp/RE.html#getMatch(java.lang.Object)"><B>getMatch(Object)</B></A> -
+Method in class gnu.regexp.<A HREF="gnu/regexp/RE.html">RE</A>
+<DD>Returns the first match found in the input.
+<DT><A HREF="gnu/regexp/RE.html#getMatch(java.lang.Object, int)"><B>getMatch(Object, int)</B></A> -
+Method in class gnu.regexp.<A HREF="gnu/regexp/RE.html">RE</A>
+<DD>Returns the first match found in the input, beginning
+ the search at the specified index.
+<DT><A HREF="gnu/regexp/RE.html#getMatch(java.lang.Object, int, int)"><B>getMatch(Object, int, int)</B></A> -
+Method in class gnu.regexp.<A HREF="gnu/regexp/RE.html">RE</A>
+<DD>Returns the first match found in the input, beginning
+ the search at the specified index, and using the specified
+ execution flags.
+<DT><A HREF="gnu/regexp/RE.html#getMatch(java.lang.Object, int, int, java.lang.StringBuffer)"><B>getMatch(Object, int, int, StringBuffer)</B></A> -
+Method in class gnu.regexp.<A HREF="gnu/regexp/RE.html">RE</A>
+<DD>Returns the first match found in the input, beginning the search
+ at the specified index, and using the specified execution flags.
+<DT><A HREF="gnu/regexp/RE.html#getMatchEnumeration(java.lang.Object)"><B>getMatchEnumeration(Object)</B></A> -
+Method in class gnu.regexp.<A HREF="gnu/regexp/RE.html">RE</A>
+<DD>Returns an REMatchEnumeration that can be used to iterate over the
+ matches found in the input text.
+<DT><A HREF="gnu/regexp/RE.html#getMatchEnumeration(java.lang.Object, int)"><B>getMatchEnumeration(Object, int)</B></A> -
+Method in class gnu.regexp.<A HREF="gnu/regexp/RE.html">RE</A>
+<DD>Returns an REMatchEnumeration that can be used to iterate over the
+ matches found in the input text.
+<DT><A HREF="gnu/regexp/RE.html#getMatchEnumeration(java.lang.Object, int, int)"><B>getMatchEnumeration(Object, int, int)</B></A> -
+Method in class gnu.regexp.<A HREF="gnu/regexp/RE.html">RE</A>
+<DD>Returns an REMatchEnumeration that can be used to iterate over the
+ matches found in the input text.
+<DT><A HREF="gnu/regexp/REException.html#getMessage()"><B>getMessage()</B></A> -
+Method in class gnu.regexp.<A HREF="gnu/regexp/REException.html">REException</A>
+<DD>Reports the descriptive message associated with this exception
+ as well as its index position in the string or character array
+ being compiled.
+<DT><A HREF="gnu/regexp/RE.html#getMinimumLength()"><B>getMinimumLength()</B></A> -
+Method in class gnu.regexp.<A HREF="gnu/regexp/RE.html">RE</A>
+<DD>Returns the minimum number of characters that could possibly
+ constitute a match of this regular expression.
+<DT><A HREF="gnu/regexp/RE.html#getNumSubs()"><B>getNumSubs()</B></A> -
+Method in class gnu.regexp.<A HREF="gnu/regexp/RE.html">RE</A>
+<DD>Returns the maximum number of subexpressions in this regular expression.
+<DT><A HREF="gnu/regexp/REException.html#getPosition()"><B>getPosition()</B></A> -
+Method in class gnu.regexp.<A HREF="gnu/regexp/REException.html">REException</A>
+<DD>Returns the position, relative to the string or character array being
+ compiled, where the error occurred.
+<DT><A HREF="gnu/regexp/REMatch.html#getStartIndex()"><B>getStartIndex()</B></A> -
+Method in class gnu.regexp.<A HREF="gnu/regexp/REMatch.html">REMatch</A>
+<DD>Returns the index within the input text where the match in its entirety
+ began.
+<DT><A HREF="gnu/regexp/REMatch.html#getStartIndex(int)"><B>getStartIndex(int)</B></A> -
+Method in class gnu.regexp.<A HREF="gnu/regexp/REMatch.html">REMatch</A>
+<DD>Returns the index within the input string used to generate this match
+ where subexpression number <i>sub</i> begins, or <code>-1</code> if
+ the subexpression does not exist.
+<DT><A HREF="gnu/regexp/REMatch.html#getSubEndIndex(int)"><B>getSubEndIndex(int)</B></A> -
+Method in class gnu.regexp.<A HREF="gnu/regexp/REMatch.html">REMatch</A>
+<DD><B>Deprecated.</B> <I>Use getEndIndex(int) instead</I>
+<DT><A HREF="gnu/regexp/REMatch.html#getSubStartIndex(int)"><B>getSubStartIndex(int)</B></A> -
+Method in class gnu.regexp.<A HREF="gnu/regexp/REMatch.html">REMatch</A>
+<DD><B>Deprecated.</B> <I>Use getStartIndex(int) instead.</I>
+<DT><A HREF="gnu/regexp/REException.html#getType()"><B>getType()</B></A> -
+Method in class gnu.regexp.<A HREF="gnu/regexp/REException.html">REException</A>
+<DD>Returns the type of the exception, one of the constants listed above.
+<DT><A HREF="gnu/regexp/package-summary.html"><B>gnu.regexp</B></A> - package gnu.regexp<DD> <DT><A HREF="gnu/regexp/util/package-summary.html"><B>gnu.regexp.util</B></A> - package gnu.regexp.util<DD> <DT><A HREF="gnu/regexp/util/Grep.html"><B>Grep</B></A> - class gnu.regexp.util.<A HREF="gnu/regexp/util/Grep.html">Grep</A>.<DD>Grep is a pure-Java clone of the GNU grep utility.<DT><A HREF="gnu/regexp/util/Grep.html#grep(java.lang.String[], gnu.regexp.RESyntax, java.io.PrintStream)"><B>grep(String[], RESyntax, PrintStream)</B></A> -
+Static method in class gnu.regexp.util.<A HREF="gnu/regexp/util/Grep.html">Grep</A>
+<DD>Runs Grep with the specified arguments.
+</DL>
+<HR>
+<A NAME="_H_"><!-- --></A><H2>
+<B>H</B></H2>
+<DL>
+<DT><A HREF="gnu/regexp/REMatchEnumeration.html#hasMoreElements()"><B>hasMoreElements()</B></A> -
+Method in class gnu.regexp.<A HREF="gnu/regexp/REMatchEnumeration.html">REMatchEnumeration</A>
+<DD>Returns true if there are more matches in the input text.
+<DT><A HREF="gnu/regexp/REMatchEnumeration.html#hasMoreMatches()"><B>hasMoreMatches()</B></A> -
+Method in class gnu.regexp.<A HREF="gnu/regexp/REMatchEnumeration.html">REMatchEnumeration</A>
+<DD>Returns true if there are more matches in the input text.
+<DT><A HREF="gnu/regexp/REMatchEnumeration.html#hasMoreMatches(java.lang.StringBuffer)"><B>hasMoreMatches(StringBuffer)</B></A> -
+Method in class gnu.regexp.<A HREF="gnu/regexp/REMatchEnumeration.html">REMatchEnumeration</A>
+<DD>Returns true if there are more matches in the input text.
+</DL>
+<HR>
+<A NAME="_I_"><!-- --></A><H2>
+<B>I</B></H2>
+<DL>
+<DT><A HREF="gnu/regexp/util/REApplet.html#init()"><B>init()</B></A> -
+Method in class gnu.regexp.util.<A HREF="gnu/regexp/util/REApplet.html">REApplet</A>
+<DD>Initializes the applet and constructs GUI elements.
+<DT><A HREF="gnu/regexp/RE.html#isMatch(java.lang.Object)"><B>isMatch(Object)</B></A> -
+Method in class gnu.regexp.<A HREF="gnu/regexp/RE.html">RE</A>
+<DD>Checks if the regular expression matches the input in its entirety.
+<DT><A HREF="gnu/regexp/RE.html#isMatch(java.lang.Object, int)"><B>isMatch(Object, int)</B></A> -
+Method in class gnu.regexp.<A HREF="gnu/regexp/RE.html">RE</A>
+<DD>Checks if the input string, starting from index, is an exact match of
+ this regular expression.
+<DT><A HREF="gnu/regexp/RE.html#isMatch(java.lang.Object, int, int)"><B>isMatch(Object, int, int)</B></A> -
+Method in class gnu.regexp.<A HREF="gnu/regexp/RE.html">RE</A>
+<DD>Checks if the input, starting from index and using the specified
+ execution flags, is an exact match of this regular expression.
+<DT><A HREF="gnu/regexp/CharIndexed.html#isValid()"><B>isValid()</B></A> -
+Method in interface gnu.regexp.<A HREF="gnu/regexp/CharIndexed.html">CharIndexed</A>
+<DD>Returns true if the most recent move() operation placed the cursor
+ position at a valid position in the input.
+</DL>
+<HR>
+<A NAME="_M_"><!-- --></A><H2>
+<B>M</B></H2>
+<DL>
+<DT><A HREF="gnu/regexp/util/RETest.html#main(java.lang.String[])"><B>main(String[])</B></A> -
+Static method in class gnu.regexp.util.<A HREF="gnu/regexp/util/RETest.html">RETest</A>
+<DD>Invokes the test function with the command line arguments specified.
+<DT><A HREF="gnu/regexp/util/Tests.html#main(java.lang.String[])"><B>main(String[])</B></A> -
+Static method in class gnu.regexp.util.<A HREF="gnu/regexp/util/Tests.html">Tests</A>
+<DD>Runs the testsuite.
+<DT><A HREF="gnu/regexp/util/Grep.html#main(java.lang.String[])"><B>main(String[])</B></A> -
+Static method in class gnu.regexp.util.<A HREF="gnu/regexp/util/Grep.html">Grep</A>
+<DD>Invokes the grep() function below with the command line arguments
+ and using the RESyntax.RE_SYNTAX_GREP syntax, which attempts to
+ emulate the traditional UNIX grep syntax.
+<DT><A HREF="gnu/regexp/util/Egrep.html#main(java.lang.String[])"><B>main(String[])</B></A> -
+Static method in class gnu.regexp.util.<A HREF="gnu/regexp/util/Egrep.html">Egrep</A>
+<DD>Invokes Grep.grep() using the RE_SYNTAX_EGREP syntax and the
+ command line arguments specified.
+<DT><A HREF="gnu/regexp/RESyntax.html#makeFinal()"><B>makeFinal()</B></A> -
+Method in class gnu.regexp.<A HREF="gnu/regexp/RESyntax.html">RESyntax</A>
+<DD>Called internally when constructing predefined syntaxes
+ so their interpretation cannot vary.
+<DT><A HREF="gnu/regexp/REFilterInputStream.html#markSupported()"><B>markSupported()</B></A> -
+Method in class gnu.regexp.<A HREF="gnu/regexp/REFilterInputStream.html">REFilterInputStream</A>
+<DD><B>Deprecated.</B> Returns false.
+<DT><A HREF="gnu/regexp/REFilterReader.html#markSupported()"><B>markSupported()</B></A> -
+Method in class gnu.regexp.<A HREF="gnu/regexp/REFilterReader.html">REFilterReader</A>
+<DD>Returns false.
+<DT><A HREF="gnu/regexp/CharIndexed.html#move(int)"><B>move(int)</B></A> -
+Method in interface gnu.regexp.<A HREF="gnu/regexp/CharIndexed.html">CharIndexed</A>
+<DD>Shifts the input buffer by a given number of positions.
+</DL>
+<HR>
+<A NAME="_N_"><!-- --></A><H2>
+<B>N</B></H2>
+<DL>
+<DT><A HREF="gnu/regexp/REMatchEnumeration.html#nextElement()"><B>nextElement()</B></A> -
+Method in class gnu.regexp.<A HREF="gnu/regexp/REMatchEnumeration.html">REMatchEnumeration</A>
+<DD>Returns the next match in the input text.
+<DT><A HREF="gnu/regexp/REMatchEnumeration.html#nextMatch()"><B>nextMatch()</B></A> -
+Method in class gnu.regexp.<A HREF="gnu/regexp/REMatchEnumeration.html">REMatchEnumeration</A>
+<DD>Returns the next match in the input text.
+</DL>
+<HR>
+<A NAME="_O_"><!-- --></A><H2>
+<B>O</B></H2>
+<DL>
+<DT><A HREF="gnu/regexp/CharIndexed.html#OUT_OF_BOUNDS"><B>OUT_OF_BOUNDS</B></A> -
+Static variable in interface gnu.regexp.<A HREF="gnu/regexp/CharIndexed.html">CharIndexed</A>
+<DD>Defines a constant (0xFFFF was somewhat arbitrarily chosen)
+ that can be returned by the charAt() function indicating that
+ the specified index is out of range.
+</DL>
+<HR>
+<A NAME="_R_"><!-- --></A><H2>
+<B>R</B></H2>
+<DL>
+<DT><A HREF="gnu/regexp/RE.html"><B>RE</B></A> - class gnu.regexp.<A HREF="gnu/regexp/RE.html">RE</A>.<DD>RE provides the user interface for compiling and matching regular
+ expressions.<DT><A HREF="gnu/regexp/RESyntax.html#RE_BACKSLASH_ESCAPE_IN_LISTS"><B>RE_BACKSLASH_ESCAPE_IN_LISTS</B></A> -
+Static variable in class gnu.regexp.<A HREF="gnu/regexp/RESyntax.html">RESyntax</A>
+<DD>Syntax bit.
+<DT><A HREF="gnu/regexp/RESyntax.html#RE_BK_PLUS_QM"><B>RE_BK_PLUS_QM</B></A> -
+Static variable in class gnu.regexp.<A HREF="gnu/regexp/RESyntax.html">RESyntax</A>
+<DD>Syntax bit.
+<DT><A HREF="gnu/regexp/RESyntax.html#RE_CHAR_CLASS_ESC_IN_LISTS"><B>RE_CHAR_CLASS_ESC_IN_LISTS</B></A> -
+Static variable in class gnu.regexp.<A HREF="gnu/regexp/RESyntax.html">RESyntax</A>
+<DD>Syntax bit.
+<DT><A HREF="gnu/regexp/RESyntax.html#RE_CHAR_CLASS_ESCAPES"><B>RE_CHAR_CLASS_ESCAPES</B></A> -
+Static variable in class gnu.regexp.<A HREF="gnu/regexp/RESyntax.html">RESyntax</A>
+<DD>Syntax bit.
+<DT><A HREF="gnu/regexp/RESyntax.html#RE_CHAR_CLASSES"><B>RE_CHAR_CLASSES</B></A> -
+Static variable in class gnu.regexp.<A HREF="gnu/regexp/RESyntax.html">RESyntax</A>
+<DD>Syntax bit.
+<DT><A HREF="gnu/regexp/RESyntax.html#RE_COMMENTS"><B>RE_COMMENTS</B></A> -
+Static variable in class gnu.regexp.<A HREF="gnu/regexp/RESyntax.html">RESyntax</A>
+<DD>Syntax bit.
+<DT><A HREF="gnu/regexp/RESyntax.html#RE_CONTEXT_INDEP_ANCHORS"><B>RE_CONTEXT_INDEP_ANCHORS</B></A> -
+Static variable in class gnu.regexp.<A HREF="gnu/regexp/RESyntax.html">RESyntax</A>
+<DD>Syntax bit.
+<DT><A HREF="gnu/regexp/RESyntax.html#RE_CONTEXT_INDEP_OPS"><B>RE_CONTEXT_INDEP_OPS</B></A> -
+Static variable in class gnu.regexp.<A HREF="gnu/regexp/RESyntax.html">RESyntax</A>
+<DD>Syntax bit.
+<DT><A HREF="gnu/regexp/RESyntax.html#RE_CONTEXT_INVALID_OPS"><B>RE_CONTEXT_INVALID_OPS</B></A> -
+Static variable in class gnu.regexp.<A HREF="gnu/regexp/RESyntax.html">RESyntax</A>
+<DD>Syntax bit.
+<DT><A HREF="gnu/regexp/RESyntax.html#RE_DOT_NEWLINE"><B>RE_DOT_NEWLINE</B></A> -
+Static variable in class gnu.regexp.<A HREF="gnu/regexp/RESyntax.html">RESyntax</A>
+<DD>Syntax bit.
+<DT><A HREF="gnu/regexp/RESyntax.html#RE_DOT_NOT_NULL"><B>RE_DOT_NOT_NULL</B></A> -
+Static variable in class gnu.regexp.<A HREF="gnu/regexp/RESyntax.html">RESyntax</A>
+<DD>Syntax bit.
+<DT><A HREF="gnu/regexp/RESyntax.html#RE_HAT_LISTS_NOT_NEWLINE"><B>RE_HAT_LISTS_NOT_NEWLINE</B></A> -
+Static variable in class gnu.regexp.<A HREF="gnu/regexp/RESyntax.html">RESyntax</A>
+<DD>Syntax bit.
+<DT><A HREF="gnu/regexp/RESyntax.html#RE_INTERVALS"><B>RE_INTERVALS</B></A> -
+Static variable in class gnu.regexp.<A HREF="gnu/regexp/RESyntax.html">RESyntax</A>
+<DD>Syntax bit.
+<DT><A HREF="gnu/regexp/RESyntax.html#RE_LIMITED_OPS"><B>RE_LIMITED_OPS</B></A> -
+Static variable in class gnu.regexp.<A HREF="gnu/regexp/RESyntax.html">RESyntax</A>
+<DD>Syntax bit.
+<DT><A HREF="gnu/regexp/RESyntax.html#RE_LOOKAHEAD"><B>RE_LOOKAHEAD</B></A> -
+Static variable in class gnu.regexp.<A HREF="gnu/regexp/RESyntax.html">RESyntax</A>
+<DD>Syntax bit.
+<DT><A HREF="gnu/regexp/RESyntax.html#RE_NEWLINE_ALT"><B>RE_NEWLINE_ALT</B></A> -
+Static variable in class gnu.regexp.<A HREF="gnu/regexp/RESyntax.html">RESyntax</A>
+<DD>Syntax bit.
+<DT><A HREF="gnu/regexp/RESyntax.html#RE_NO_BK_BRACES"><B>RE_NO_BK_BRACES</B></A> -
+Static variable in class gnu.regexp.<A HREF="gnu/regexp/RESyntax.html">RESyntax</A>
+<DD>Syntax bit.
+<DT><A HREF="gnu/regexp/RESyntax.html#RE_NO_BK_PARENS"><B>RE_NO_BK_PARENS</B></A> -
+Static variable in class gnu.regexp.<A HREF="gnu/regexp/RESyntax.html">RESyntax</A>
+<DD>Syntax bit.
+<DT><A HREF="gnu/regexp/RESyntax.html#RE_NO_BK_REFS"><B>RE_NO_BK_REFS</B></A> -
+Static variable in class gnu.regexp.<A HREF="gnu/regexp/RESyntax.html">RESyntax</A>
+<DD>Syntax bit.
+<DT><A HREF="gnu/regexp/RESyntax.html#RE_NO_BK_VBAR"><B>RE_NO_BK_VBAR</B></A> -
+Static variable in class gnu.regexp.<A HREF="gnu/regexp/RESyntax.html">RESyntax</A>
+<DD>Syntax bit.
+<DT><A HREF="gnu/regexp/RESyntax.html#RE_NO_EMPTY_RANGES"><B>RE_NO_EMPTY_RANGES</B></A> -
+Static variable in class gnu.regexp.<A HREF="gnu/regexp/RESyntax.html">RESyntax</A>
+<DD>Syntax bit.
+<DT><A HREF="gnu/regexp/RESyntax.html#RE_PURE_GROUPING"><B>RE_PURE_GROUPING</B></A> -
+Static variable in class gnu.regexp.<A HREF="gnu/regexp/RESyntax.html">RESyntax</A>
+<DD>Syntax bit.
+<DT><A HREF="gnu/regexp/RESyntax.html#RE_STINGY_OPS"><B>RE_STINGY_OPS</B></A> -
+Static variable in class gnu.regexp.<A HREF="gnu/regexp/RESyntax.html">RESyntax</A>
+<DD>Syntax bit.
+<DT><A HREF="gnu/regexp/RESyntax.html#RE_STRING_ANCHORS"><B>RE_STRING_ANCHORS</B></A> -
+Static variable in class gnu.regexp.<A HREF="gnu/regexp/RESyntax.html">RESyntax</A>
+<DD>Syntax bit.
+<DT><A HREF="gnu/regexp/RESyntax.html#RE_SYNTAX_AWK"><B>RE_SYNTAX_AWK</B></A> -
+Static variable in class gnu.regexp.<A HREF="gnu/regexp/RESyntax.html">RESyntax</A>
+<DD>Predefined syntax.
+<DT><A HREF="gnu/regexp/RESyntax.html#RE_SYNTAX_ED"><B>RE_SYNTAX_ED</B></A> -
+Static variable in class gnu.regexp.<A HREF="gnu/regexp/RESyntax.html">RESyntax</A>
+<DD>Predefined syntax.
+<DT><A HREF="gnu/regexp/RESyntax.html#RE_SYNTAX_EGREP"><B>RE_SYNTAX_EGREP</B></A> -
+Static variable in class gnu.regexp.<A HREF="gnu/regexp/RESyntax.html">RESyntax</A>
+<DD>Predefined syntax.
+<DT><A HREF="gnu/regexp/RESyntax.html#RE_SYNTAX_EMACS"><B>RE_SYNTAX_EMACS</B></A> -
+Static variable in class gnu.regexp.<A HREF="gnu/regexp/RESyntax.html">RESyntax</A>
+<DD>Predefined syntax.
+<DT><A HREF="gnu/regexp/RESyntax.html#RE_SYNTAX_GREP"><B>RE_SYNTAX_GREP</B></A> -
+Static variable in class gnu.regexp.<A HREF="gnu/regexp/RESyntax.html">RESyntax</A>
+<DD>Predefined syntax.
+<DT><A HREF="gnu/regexp/RESyntax.html#RE_SYNTAX_PERL4"><B>RE_SYNTAX_PERL4</B></A> -
+Static variable in class gnu.regexp.<A HREF="gnu/regexp/RESyntax.html">RESyntax</A>
+<DD>Predefined syntax.
+<DT><A HREF="gnu/regexp/RESyntax.html#RE_SYNTAX_PERL4_S"><B>RE_SYNTAX_PERL4_S</B></A> -
+Static variable in class gnu.regexp.<A HREF="gnu/regexp/RESyntax.html">RESyntax</A>
+<DD>Predefined syntax.
+<DT><A HREF="gnu/regexp/RESyntax.html#RE_SYNTAX_PERL5"><B>RE_SYNTAX_PERL5</B></A> -
+Static variable in class gnu.regexp.<A HREF="gnu/regexp/RESyntax.html">RESyntax</A>
+<DD>Predefined syntax.
+<DT><A HREF="gnu/regexp/RESyntax.html#RE_SYNTAX_PERL5_S"><B>RE_SYNTAX_PERL5_S</B></A> -
+Static variable in class gnu.regexp.<A HREF="gnu/regexp/RESyntax.html">RESyntax</A>
+<DD>Predefined syntax.
+<DT><A HREF="gnu/regexp/RESyntax.html#RE_SYNTAX_POSIX_AWK"><B>RE_SYNTAX_POSIX_AWK</B></A> -
+Static variable in class gnu.regexp.<A HREF="gnu/regexp/RESyntax.html">RESyntax</A>
+<DD>Predefined syntax.
+<DT><A HREF="gnu/regexp/RESyntax.html#RE_SYNTAX_POSIX_BASIC"><B>RE_SYNTAX_POSIX_BASIC</B></A> -
+Static variable in class gnu.regexp.<A HREF="gnu/regexp/RESyntax.html">RESyntax</A>
+<DD>Predefined syntax.
+<DT><A HREF="gnu/regexp/RESyntax.html#RE_SYNTAX_POSIX_EGREP"><B>RE_SYNTAX_POSIX_EGREP</B></A> -
+Static variable in class gnu.regexp.<A HREF="gnu/regexp/RESyntax.html">RESyntax</A>
+<DD>Predefined syntax.
+<DT><A HREF="gnu/regexp/RESyntax.html#RE_SYNTAX_POSIX_EXTENDED"><B>RE_SYNTAX_POSIX_EXTENDED</B></A> -
+Static variable in class gnu.regexp.<A HREF="gnu/regexp/RESyntax.html">RESyntax</A>
+<DD>Predefined syntax.
+<DT><A HREF="gnu/regexp/RESyntax.html#RE_SYNTAX_POSIX_MINIMAL_BASIC"><B>RE_SYNTAX_POSIX_MINIMAL_BASIC</B></A> -
+Static variable in class gnu.regexp.<A HREF="gnu/regexp/RESyntax.html">RESyntax</A>
+<DD>Predefined syntax.
+<DT><A HREF="gnu/regexp/RESyntax.html#RE_SYNTAX_POSIX_MINIMAL_EXTENDED"><B>RE_SYNTAX_POSIX_MINIMAL_EXTENDED</B></A> -
+Static variable in class gnu.regexp.<A HREF="gnu/regexp/RESyntax.html">RESyntax</A>
+<DD>Predefined syntax.
+<DT><A HREF="gnu/regexp/RESyntax.html#RE_SYNTAX_SED"><B>RE_SYNTAX_SED</B></A> -
+Static variable in class gnu.regexp.<A HREF="gnu/regexp/RESyntax.html">RESyntax</A>
+<DD>Predefined syntax.
+<DT><A HREF="gnu/regexp/RESyntax.html#RE_UNMATCHED_RIGHT_PAREN_ORD"><B>RE_UNMATCHED_RIGHT_PAREN_ORD</B></A> -
+Static variable in class gnu.regexp.<A HREF="gnu/regexp/RESyntax.html">RESyntax</A>
+<DD>Syntax bit.
+<DT><A HREF="gnu/regexp/RE.html#RE(java.lang.Object)"><B>RE(Object)</B></A> -
+Constructor for class gnu.regexp.<A HREF="gnu/regexp/RE.html">RE</A>
+<DD>Constructs a regular expression pattern buffer without any compilation
+ flags set, and using the default syntax (RESyntax.RE_SYNTAX_PERL5).
+<DT><A HREF="gnu/regexp/RE.html#RE(java.lang.Object, int)"><B>RE(Object, int)</B></A> -
+Constructor for class gnu.regexp.<A HREF="gnu/regexp/RE.html">RE</A>
+<DD>Constructs a regular expression pattern buffer using the specified
+ compilation flags and the default syntax (RESyntax.RE_SYNTAX_PERL5).
+<DT><A HREF="gnu/regexp/RE.html#RE(java.lang.Object, int, gnu.regexp.RESyntax)"><B>RE(Object, int, RESyntax)</B></A> -
+Constructor for class gnu.regexp.<A HREF="gnu/regexp/RE.html">RE</A>
+<DD>Constructs a regular expression pattern buffer using the specified
+ compilation flags and regular expression syntax.
+<DT><A HREF="gnu/regexp/REFilterInputStream.html#read()"><B>read()</B></A> -
+Method in class gnu.regexp.<A HREF="gnu/regexp/REFilterInputStream.html">REFilterInputStream</A>
+<DD><B>Deprecated.</B> Reads the next byte from the stream per the general contract of
+ InputStream.read().
+<DT><A HREF="gnu/regexp/REFilterReader.html#read()"><B>read()</B></A> -
+Method in class gnu.regexp.<A HREF="gnu/regexp/REFilterReader.html">REFilterReader</A>
+<DD>Reads the next character from the stream per the general contract of
+ Reader.read().
+<DT><A HREF="gnu/regexp/REFilterInputStream.html#read(byte[])"><B>read(byte[])</B></A> -
+Method in class gnu.regexp.<A HREF="gnu/regexp/REFilterInputStream.html">REFilterInputStream</A>
+<DD><B>Deprecated.</B> Reads from the stream into the provided array.
+<DT><A HREF="gnu/regexp/REFilterInputStream.html#read(byte[], int, int)"><B>read(byte[], int, int)</B></A> -
+Method in class gnu.regexp.<A HREF="gnu/regexp/REFilterInputStream.html">REFilterInputStream</A>
+<DD><B>Deprecated.</B> Reads from the stream into the provided array.
+<DT><A HREF="gnu/regexp/REFilterReader.html#read(char[])"><B>read(char[])</B></A> -
+Method in class gnu.regexp.<A HREF="gnu/regexp/REFilterReader.html">REFilterReader</A>
+<DD>Reads from the stream into the provided array.
+<DT><A HREF="gnu/regexp/REFilterReader.html#read(char[], int, int)"><B>read(char[], int, int)</B></A> -
+Method in class gnu.regexp.<A HREF="gnu/regexp/REFilterReader.html">REFilterReader</A>
+<DD>Reads from the stream into the provided array.
+<DT><A HREF="gnu/regexp/util/REApplet.html"><B>REApplet</B></A> - class gnu.regexp.util.<A HREF="gnu/regexp/util/REApplet.html">REApplet</A>.<DD>This is a simple applet to demonstrate the capabilities of gnu.regexp.<DT><A HREF="gnu/regexp/util/REApplet.html#REApplet()"><B>REApplet()</B></A> -
+Constructor for class gnu.regexp.util.<A HREF="gnu/regexp/util/REApplet.html">REApplet</A>
+<DD>Creates an REApplet.
+<DT><A HREF="gnu/regexp/REException.html"><B>REException</B></A> - exception gnu.regexp.<A HREF="gnu/regexp/REException.html">REException</A>.<DD>This is the regular expression exception class.<DT><A HREF="gnu/regexp/REFilterInputStream.html"><B>REFilterInputStream</B></A> - class gnu.regexp.<A HREF="gnu/regexp/REFilterInputStream.html">REFilterInputStream</A>.<DD><B>Deprecated.</B> <I>This class cannot properly handle all character
+ encodings. For proper handling, use the REFilterReader
+ class instead.</I><DT><A HREF="gnu/regexp/REFilterInputStream.html#REFilterInputStream(java.io.InputStream, gnu.regexp.RE, java.lang.String)"><B>REFilterInputStream(InputStream, RE, String)</B></A> -
+Constructor for class gnu.regexp.<A HREF="gnu/regexp/REFilterInputStream.html">REFilterInputStream</A>
+<DD><B>Deprecated.</B> Creates an REFilterInputStream.
+<DT><A HREF="gnu/regexp/REFilterReader.html"><B>REFilterReader</B></A> - class gnu.regexp.<A HREF="gnu/regexp/REFilterReader.html">REFilterReader</A>.<DD>Replaces instances of a given RE with replacement text.<DT><A HREF="gnu/regexp/REFilterReader.html#REFilterReader(java.io.Reader, gnu.regexp.RE, java.lang.String)"><B>REFilterReader(Reader, RE, String)</B></A> -
+Constructor for class gnu.regexp.<A HREF="gnu/regexp/REFilterReader.html">REFilterReader</A>
+<DD>Creates an REFilterReader.
+<DT><A HREF="gnu/regexp/RE.html#REG_ANCHORINDEX"><B>REG_ANCHORINDEX</B></A> -
+Static variable in class gnu.regexp.<A HREF="gnu/regexp/RE.html">RE</A>
+<DD>Execution flag.
+<DT><A HREF="gnu/regexp/REException.html#REG_BADBR"><B>REG_BADBR</B></A> -
+Static variable in class gnu.regexp.<A HREF="gnu/regexp/REException.html">REException</A>
+<DD>Error flag.
+<DT><A HREF="gnu/regexp/REException.html#REG_BADPAT"><B>REG_BADPAT</B></A> -
+Static variable in class gnu.regexp.<A HREF="gnu/regexp/REException.html">REException</A>
+<DD>Error flag.
+<DT><A HREF="gnu/regexp/REException.html#REG_BADRPT"><B>REG_BADRPT</B></A> -
+Static variable in class gnu.regexp.<A HREF="gnu/regexp/REException.html">REException</A>
+<DD>Error flag.
+<DT><A HREF="gnu/regexp/RE.html#REG_DOT_NEWLINE"><B>REG_DOT_NEWLINE</B></A> -
+Static variable in class gnu.regexp.<A HREF="gnu/regexp/RE.html">RE</A>
+<DD>Compilation flag.
+<DT><A HREF="gnu/regexp/REException.html#REG_EBRACE"><B>REG_EBRACE</B></A> -
+Static variable in class gnu.regexp.<A HREF="gnu/regexp/REException.html">REException</A>
+<DD>Error flag.
+<DT><A HREF="gnu/regexp/REException.html#REG_EBRACK"><B>REG_EBRACK</B></A> -
+Static variable in class gnu.regexp.<A HREF="gnu/regexp/REException.html">REException</A>
+<DD>Error flag.
+<DT><A HREF="gnu/regexp/REException.html#REG_ECTYPE"><B>REG_ECTYPE</B></A> -
+Static variable in class gnu.regexp.<A HREF="gnu/regexp/REException.html">REException</A>
+<DD>Error flag.
+<DT><A HREF="gnu/regexp/REException.html#REG_EEND"><B>REG_EEND</B></A> -
+Static variable in class gnu.regexp.<A HREF="gnu/regexp/REException.html">REException</A>
+<DD>Error flag.
+<DT><A HREF="gnu/regexp/REException.html#REG_EPAREN"><B>REG_EPAREN</B></A> -
+Static variable in class gnu.regexp.<A HREF="gnu/regexp/REException.html">REException</A>
+<DD>Error flag.
+<DT><A HREF="gnu/regexp/REException.html#REG_ERANGE"><B>REG_ERANGE</B></A> -
+Static variable in class gnu.regexp.<A HREF="gnu/regexp/REException.html">REException</A>
+<DD>Error flag.
+<DT><A HREF="gnu/regexp/REException.html#REG_ESCAPE"><B>REG_ESCAPE</B></A> -
+Static variable in class gnu.regexp.<A HREF="gnu/regexp/REException.html">REException</A>
+<DD>Error flag.
+<DT><A HREF="gnu/regexp/REException.html#REG_ESIZE"><B>REG_ESIZE</B></A> -
+Static variable in class gnu.regexp.<A HREF="gnu/regexp/REException.html">REException</A>
+<DD>Error flag.
+<DT><A HREF="gnu/regexp/REException.html#REG_ESPACE"><B>REG_ESPACE</B></A> -
+Static variable in class gnu.regexp.<A HREF="gnu/regexp/REException.html">REException</A>
+<DD>Error flag.
+<DT><A HREF="gnu/regexp/REException.html#REG_ESUBREG"><B>REG_ESUBREG</B></A> -
+Static variable in class gnu.regexp.<A HREF="gnu/regexp/REException.html">REException</A>
+<DD>Error flag.
+<DT><A HREF="gnu/regexp/RE.html#REG_ICASE"><B>REG_ICASE</B></A> -
+Static variable in class gnu.regexp.<A HREF="gnu/regexp/RE.html">RE</A>
+<DD>Compilation flag.
+<DT><A HREF="gnu/regexp/RE.html#REG_MULTILINE"><B>REG_MULTILINE</B></A> -
+Static variable in class gnu.regexp.<A HREF="gnu/regexp/RE.html">RE</A>
+<DD>Compilation flag.
+<DT><A HREF="gnu/regexp/RE.html#REG_NO_INTERPOLATE"><B>REG_NO_INTERPOLATE</B></A> -
+Static variable in class gnu.regexp.<A HREF="gnu/regexp/RE.html">RE</A>
+<DD>Execution flag.
+<DT><A HREF="gnu/regexp/RE.html#REG_NOTBOL"><B>REG_NOTBOL</B></A> -
+Static variable in class gnu.regexp.<A HREF="gnu/regexp/RE.html">RE</A>
+<DD>Execution flag.
+<DT><A HREF="gnu/regexp/RE.html#REG_NOTEOL"><B>REG_NOTEOL</B></A> -
+Static variable in class gnu.regexp.<A HREF="gnu/regexp/RE.html">RE</A>
+<DD>Execution flag.
+<DT><A HREF="gnu/regexp/REMatch.html"><B>REMatch</B></A> - class gnu.regexp.<A HREF="gnu/regexp/REMatch.html">REMatch</A>.<DD>An instance of this class represents a match
+ completed by a gnu.regexp matching function.<DT><A HREF="gnu/regexp/REMatchEnumeration.html"><B>REMatchEnumeration</B></A> - class gnu.regexp.<A HREF="gnu/regexp/REMatchEnumeration.html">REMatchEnumeration</A>.<DD>An REMatchEnumeration enumerates regular expression matches over a
+ given input text.<DT><A HREF="gnu/regexp/RESyntax.html"><B>RESyntax</B></A> - class gnu.regexp.<A HREF="gnu/regexp/RESyntax.html">RESyntax</A>.<DD>An RESyntax specifies the way a regular expression will be compiled.<DT><A HREF="gnu/regexp/RESyntax.html#RESyntax()"><B>RESyntax()</B></A> -
+Constructor for class gnu.regexp.<A HREF="gnu/regexp/RESyntax.html">RESyntax</A>
+<DD>Construct a new syntax object with all bits turned off.
+<DT><A HREF="gnu/regexp/RESyntax.html#RESyntax(gnu.regexp.RESyntax)"><B>RESyntax(RESyntax)</B></A> -
+Constructor for class gnu.regexp.<A HREF="gnu/regexp/RESyntax.html">RESyntax</A>
+<DD>Construct a new syntax object with all bits set the same
+ as the other syntax.
+<DT><A HREF="gnu/regexp/util/RETest.html"><B>RETest</B></A> - class gnu.regexp.util.<A HREF="gnu/regexp/util/RETest.html">RETest</A>.<DD>RETest provides a simple way to test regular expressions.</DL>
+<HR>
+<A NAME="_S_"><!-- --></A><H2>
+<B>S</B></H2>
+<DL>
+<DT><A HREF="gnu/regexp/RESyntax.html#set(int)"><B>set(int)</B></A> -
+Method in class gnu.regexp.<A HREF="gnu/regexp/RESyntax.html">RESyntax</A>
+<DD>Set a given bit in this syntax.
+<DT><A HREF="gnu/regexp/RESyntax.html#setLineSeparator(java.lang.String)"><B>setLineSeparator(String)</B></A> -
+Method in class gnu.regexp.<A HREF="gnu/regexp/RESyntax.html">RESyntax</A>
+<DD>Changes the line separator string for regular expressions
+ created using this RESyntax.
+<DT><A HREF="gnu/regexp/RE.html#substitute(java.lang.Object, java.lang.String)"><B>substitute(Object, String)</B></A> -
+Method in class gnu.regexp.<A HREF="gnu/regexp/RE.html">RE</A>
+<DD>Substitutes the replacement text for the first match found in the input.
+<DT><A HREF="gnu/regexp/RE.html#substitute(java.lang.Object, java.lang.String, int)"><B>substitute(Object, String, int)</B></A> -
+Method in class gnu.regexp.<A HREF="gnu/regexp/RE.html">RE</A>
+<DD>Substitutes the replacement text for the first match found in the input
+ beginning at the specified index position.
+<DT><A HREF="gnu/regexp/RE.html#substitute(java.lang.Object, java.lang.String, int, int)"><B>substitute(Object, String, int, int)</B></A> -
+Method in class gnu.regexp.<A HREF="gnu/regexp/RE.html">RE</A>
+<DD>Substitutes the replacement text for the first match found in the input
+ string, beginning at the specified index position and using the
+ specified execution flags.
+<DT><A HREF="gnu/regexp/RE.html#substituteAll(java.lang.Object, java.lang.String)"><B>substituteAll(Object, String)</B></A> -
+Method in class gnu.regexp.<A HREF="gnu/regexp/RE.html">RE</A>
+<DD>Substitutes the replacement text for each non-overlapping match found
+ in the input text.
+<DT><A HREF="gnu/regexp/RE.html#substituteAll(java.lang.Object, java.lang.String, int)"><B>substituteAll(Object, String, int)</B></A> -
+Method in class gnu.regexp.<A HREF="gnu/regexp/RE.html">RE</A>
+<DD>Substitutes the replacement text for each non-overlapping match found
+ in the input text, starting at the specified index.
+<DT><A HREF="gnu/regexp/RE.html#substituteAll(java.lang.Object, java.lang.String, int, int)"><B>substituteAll(Object, String, int, int)</B></A> -
+Method in class gnu.regexp.<A HREF="gnu/regexp/RE.html">RE</A>
+<DD>Substitutes the replacement text for each non-overlapping match found
+ in the input text, starting at the specified index and using the
+ specified execution flags.
+<DT><A HREF="gnu/regexp/REMatch.html#substituteInto(java.lang.String)"><B>substituteInto(String)</B></A> -
+Method in class gnu.regexp.<A HREF="gnu/regexp/REMatch.html">REMatch</A>
+<DD>Substitute the results of this match to create a new string.
+</DL>
+<HR>
+<A NAME="_T_"><!-- --></A><H2>
+<B>T</B></H2>
+<DL>
+<DT><A HREF="gnu/regexp/util/Tests.html"><B>Tests</B></A> - class gnu.regexp.util.<A HREF="gnu/regexp/util/Tests.html">Tests</A>.<DD>This is a very basic testsuite application for gnu.regexp.<DT><A HREF="gnu/regexp/REMatch.html#toString()"><B>toString()</B></A> -
+Method in class gnu.regexp.<A HREF="gnu/regexp/REMatch.html">REMatch</A>
+<DD>Returns the string matching the pattern.
+<DT><A HREF="gnu/regexp/RE.html#toString()"><B>toString()</B></A> -
+Method in class gnu.regexp.<A HREF="gnu/regexp/RE.html">RE</A>
+<DD>Return a human readable form of the compiled regular expression,
+ useful for debugging.
+<DT><A HREF="gnu/regexp/REMatch.html#toString(int)"><B>toString(int)</B></A> -
+Method in class gnu.regexp.<A HREF="gnu/regexp/REMatch.html">REMatch</A>
+<DD>Returns the string matching the given subexpression.
+</DL>
+<HR>
+<A NAME="_U_"><!-- --></A><H2>
+<B>U</B></H2>
+<DL>
+<DT><A HREF="gnu/regexp/UncheckedRE.html"><B>UncheckedRE</B></A> - class gnu.regexp.<A HREF="gnu/regexp/UncheckedRE.html">UncheckedRE</A>.<DD>UncheckedRE is a subclass of RE that allows programmers an easier means
+ of programmatically precompiling regular expressions.<DT><A HREF="gnu/regexp/UncheckedRE.html#UncheckedRE(java.lang.Object)"><B>UncheckedRE(Object)</B></A> -
+Constructor for class gnu.regexp.<A HREF="gnu/regexp/UncheckedRE.html">UncheckedRE</A>
+<DD>Constructs a regular expression pattern buffer without any compilation
+ flags set, and using the default syntax (RESyntax.RE_SYNTAX_PERL5).
+<DT><A HREF="gnu/regexp/UncheckedRE.html#UncheckedRE(java.lang.Object, int)"><B>UncheckedRE(Object, int)</B></A> -
+Constructor for class gnu.regexp.<A HREF="gnu/regexp/UncheckedRE.html">UncheckedRE</A>
+<DD>Constructs a regular expression pattern buffer using the specified
+ compilation flags and the default syntax (RESyntax.RE_SYNTAX_PERL5).
+<DT><A HREF="gnu/regexp/UncheckedRE.html#UncheckedRE(java.lang.Object, int, gnu.regexp.RESyntax)"><B>UncheckedRE(Object, int, RESyntax)</B></A> -
+Constructor for class gnu.regexp.<A HREF="gnu/regexp/UncheckedRE.html">UncheckedRE</A>
+<DD>Constructs a regular expression pattern buffer using the specified
+ compilation flags and regular expression syntax.
+</DL>
+<HR>
+<A NAME="_V_"><!-- --></A><H2>
+<B>V</B></H2>
+<DL>
+<DT><A HREF="gnu/regexp/RE.html#version()"><B>version()</B></A> -
+Static method in class gnu.regexp.<A HREF="gnu/regexp/RE.html">RE</A>
+<DD>Returns a string representing the version of the gnu.regexp package.
+</DL>
+<HR>
+<A HREF="#_A_">A</A> <A HREF="#_C_">C</A> <A HREF="#_E_">E</A> <A HREF="#_G_">G</A> <A HREF="#_H_">H</A> <A HREF="#_I_">I</A> <A HREF="#_M_">M</A> <A HREF="#_N_">N</A> <A HREF="#_O_">O</A> <A HREF="#_R_">R</A> <A HREF="#_S_">S</A> <A HREF="#_T_">T</A> <A HREF="#_U_">U</A> <A HREF="#_V_">V</A>
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A> </TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> <FONT CLASS="NavBarFont1Rev"><B>Index</B></FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A> </TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ PREV
+ NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="index.html" TARGET="_top"><B>FRAMES</B></A>
+ <A HREF="index-all.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN""http://www.w3.org/TR/REC-html40/loose.dtd>
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Sun Oct 21 14:27:45 PDT 2001-->
+<TITLE>
+Generated Documentation (Untitled)
+</TITLE>
+</HEAD>
+<FRAMESET cols="20%,80%">
+<FRAMESET rows="30%,70%">
+<FRAME src="overview-frame.html" name="packageListFrame">
+<FRAME src="allclasses-frame.html" name="packageFrame">
+</FRAMESET>
+<FRAME src="overview-summary.html" name="classFrame">
+</FRAMESET>
+<NOFRAMES>
+<H2>
+Frame Alert</H2>
+
+<P>
+This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client.
+<BR>
+Link to <A HREF="overview-summary.html">Non-frame version.</A></NOFRAMES>
+</HTML>
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Sun Oct 21 14:27:45 PDT 2001 -->
+<TITLE>
+: Overview
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<TABLE BORDER="0" WIDTH="100%">
+<TR>
+<TD NOWRAP><FONT size="+1" CLASS="FrameTitleFont">
+<B></B></FONT></TD>
+</TR>
+</TABLE>
+
+<TABLE BORDER="0" WIDTH="100%">
+<TR>
+<TD NOWRAP><FONT CLASS="FrameItemFont"><A HREF="allclasses-frame.html" TARGET="packageFrame">All Classes</A></FONT>
+<P>
+<FONT size="+1" CLASS="FrameHeadingFont">
+Packages</FONT>
+<BR>
+<FONT CLASS="FrameItemFont"><A HREF="gnu/regexp/package-frame.html" TARGET="packageFrame">gnu.regexp</A></FONT>
+<BR>
+<FONT CLASS="FrameItemFont"><A HREF="gnu/regexp/util/package-frame.html" TARGET="packageFrame">gnu.regexp.util</A></FONT>
+<BR>
+</TD>
+</TR>
+</TABLE>
+
+<P>
+
+</BODY>
+</HTML>
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Sun Oct 21 14:27:45 PDT 2001 -->
+<TITLE>
+: Overview
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> <FONT CLASS="NavBarFont1Rev"><B>Overview</B></FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A> </TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ PREV
+ NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="index.html" TARGET="_top"><B>FRAMES</B></A>
+ <A HREF="overview-summary.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Packages</B></FONT></TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="20%"><B><A HREF="gnu/regexp/package-summary.html">gnu.regexp</A></B></TD>
+<TD> </TD>
+</TR>
+<TR BGCOLOR="white" CLASS="TableRowColor">
+<TD WIDTH="20%"><B><A HREF="gnu/regexp/util/package-summary.html">gnu.regexp.util</A></B></TD>
+<TD> </TD>
+</TR>
+</TABLE>
+
+<P>
+ <HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> <FONT CLASS="NavBarFont1Rev"><B>Overview</B></FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A> </TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ PREV
+ NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="index.html" TARGET="_top"><B>FRAMES</B></A>
+ <A HREF="overview-summary.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Sun Oct 21 14:27:45 PDT 2001 -->
+<TITLE>
+: Class Hierarchy
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT> </TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> <FONT CLASS="NavBarFont1Rev"><B>Tree</B></FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A> </TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ PREV
+ NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="index.html" TARGET="_top"><B>FRAMES</B></A>
+ <A HREF="overview-tree.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<CENTER>
+<H2>
+Hierarchy For All Packages</H2>
+</CENTER>
+<DL>
+<DT><B>Package Hierarchies: </B><DD><A HREF="gnu/regexp/package-tree.html">gnu.regexp</A>, <A HREF="gnu/regexp/util/package-tree.html">gnu.regexp.util</A></DL>
+<HR>
+<H2>
+Class Hierarchy
+</H2>
+<UL>
+<LI TYPE="circle">class java.lang.Object<UL>
+<LI TYPE="circle">class java.awt.Component (implements java.awt.image.ImageObserver, java.awt.MenuContainer, java.io.Serializable)
+<UL>
+<LI TYPE="circle">class java.awt.Container<UL>
+<LI TYPE="circle">class java.awt.Panel (implements javax.accessibility.Accessible)
+<UL>
+<LI TYPE="circle">class java.applet.Applet<UL>
+<LI TYPE="circle">class gnu.regexp.util.<A HREF="gnu/regexp/util/REApplet.html"><B>REApplet</B></A></UL>
+</UL>
+</UL>
+</UL>
+<LI TYPE="circle">class gnu.regexp.util.<A HREF="gnu/regexp/util/Egrep.html"><B>Egrep</B></A><LI TYPE="circle">class gnu.regexp.util.<A HREF="gnu/regexp/util/Grep.html"><B>Grep</B></A><LI TYPE="circle">class java.io.InputStream<UL>
+<LI TYPE="circle">class java.io.FilterInputStream<UL>
+<LI TYPE="circle">class gnu.regexp.<A HREF="gnu/regexp/REFilterInputStream.html"><B>REFilterInputStream</B></A></UL>
+</UL>
+<LI TYPE="circle">class java.io.Reader<UL>
+<LI TYPE="circle">class java.io.FilterReader<UL>
+<LI TYPE="circle">class gnu.regexp.<A HREF="gnu/regexp/REFilterReader.html"><B>REFilterReader</B></A></UL>
+</UL>
+<LI TYPE="circle">class gnu.regexp.<A HREF="gnu/regexp/REMatch.html"><B>REMatch</B></A> (implements java.lang.Cloneable, java.io.Serializable)
+<LI TYPE="circle">class gnu.regexp.<A HREF="gnu/regexp/REMatchEnumeration.html"><B>REMatchEnumeration</B></A> (implements java.util.Enumeration, java.io.Serializable)
+<LI TYPE="circle">class gnu.regexp.<A HREF="gnu/regexp/RESyntax.html"><B>RESyntax</B></A> (implements java.io.Serializable)
+<LI TYPE="circle">class gnu.regexp.util.<A HREF="gnu/regexp/util/RETest.html"><B>RETest</B></A><LI TYPE="circle">class gnu.regexp.REToken (implements java.io.Serializable)
+<UL>
+<LI TYPE="circle">class gnu.regexp.<A HREF="gnu/regexp/RE.html"><B>RE</B></A><UL>
+<LI TYPE="circle">class gnu.regexp.<A HREF="gnu/regexp/UncheckedRE.html"><B>UncheckedRE</B></A></UL>
+</UL>
+<LI TYPE="circle">class gnu.regexp.util.<A HREF="gnu/regexp/util/Tests.html"><B>Tests</B></A><LI TYPE="circle">class java.lang.Throwable (implements java.io.Serializable)
+<UL>
+<LI TYPE="circle">class java.lang.Exception<UL>
+<LI TYPE="circle">class gnu.regexp.<A HREF="gnu/regexp/REException.html"><B>REException</B></A></UL>
+</UL>
+</UL>
+</UL>
+<H2>
+Interface Hierarchy
+</H2>
+<UL>
+<LI TYPE="circle">interface gnu.regexp.<A HREF="gnu/regexp/CharIndexed.html"><B>CharIndexed</B></A></UL>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT> </TD>
+ <TD BGCOLOR="#FFFFFF" CLASS="NavBarCell1Rev"> <FONT CLASS="NavBarFont1Rev"><B>Tree</B></FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A> </TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ PREV
+ NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="index.html" TARGET="_top"><B>FRAMES</B></A>
+ <A HREF="overview-tree.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
--- /dev/null
+gnu.regexp
+gnu.regexp.util
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Sun Oct 21 14:27:45 PDT 2001 -->
+<TITLE>
+
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<BR>
+
+<BR>
+
+<BR>
+<CENTER>
+The front page has been relocated.Please see:
+<BR>
+ <A HREF="index.html">Frame version</A>
+<BR>
+ <A HREF="overview-summary.html">Non-frame version.</A></CENTER>
+
+</BODY>
+</HTML>
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN""http://www.w3.org/TR/REC-html40/frameset.dtd">
+<!--NewPage-->
+<HTML>
+<HEAD>
+<!-- Generated by javadoc on Sun Oct 21 14:27:46 PDT 2001 -->
+<TITLE>
+Serialized Form
+</TITLE>
+<LINK REL ="stylesheet" TYPE="text/css" HREF="stylesheet.css" TITLE="Style">
+</HEAD>
+<BODY BGCOLOR="white">
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_top"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_top_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A> </TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ PREV
+ NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="index.html" TARGET="_top"><B>FRAMES</B></A>
+ <A HREF="serialized-form.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+<CENTER>
+<H1>
+Serialized Form</H1>
+</CENTER>
+<HR SIZE="4" NOSHADE>
+
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TD ALIGN="center"><FONT SIZE="+2">
+<B>Package</B> <B>gnu.regexp</B></FONT></TD>
+</TR>
+</TABLE>
+
+<P>
+<A NAME="gnu.regexp.RE"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Class <A HREF="gnu/regexp/RE.html">gnu.regexp.RE</A> implements Serializable</B></FONT></TD>
+</TR>
+</TABLE>
+
+<P>
+<A NAME="serializedForm"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Serialized Fields</B></FONT></TD>
+</TR>
+</TABLE>
+
+<H3>
+firstToken</H3>
+<PRE>
+gnu.regexp.REToken <B>firstToken</B></PRE>
+<DL>
+</DL>
+<HR>
+
+<H3>
+lastToken</H3>
+<PRE>
+gnu.regexp.REToken <B>lastToken</B></PRE>
+<DL>
+</DL>
+<HR>
+
+<H3>
+numSubs</H3>
+<PRE>
+int <B>numSubs</B></PRE>
+<DL>
+</DL>
+<HR>
+
+<H3>
+minimumLength</H3>
+<PRE>
+int <B>minimumLength</B></PRE>
+<DL>
+<DD>Minimum length, in characters, of any possible match.</DL>
+
+<P>
+<A NAME="gnu.regexp.REException"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Class <A HREF="gnu/regexp/REException.html">gnu.regexp.REException</A> implements Serializable</B></FONT></TD>
+</TR>
+</TABLE>
+
+<P>
+<A NAME="serializedForm"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Serialized Fields</B></FONT></TD>
+</TR>
+</TABLE>
+
+<H3>
+type</H3>
+<PRE>
+int <B>type</B></PRE>
+<DL>
+</DL>
+<HR>
+
+<H3>
+pos</H3>
+<PRE>
+int <B>pos</B></PRE>
+<DL>
+</DL>
+
+<P>
+<A NAME="gnu.regexp.REMatch"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Class <A HREF="gnu/regexp/REMatch.html">gnu.regexp.REMatch</A> implements Serializable</B></FONT></TD>
+</TR>
+</TABLE>
+
+<P>
+<A NAME="serializedForm"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Serialized Fields</B></FONT></TD>
+</TR>
+</TABLE>
+
+<H3>
+matchedText</H3>
+<PRE>
+java.lang.String <B>matchedText</B></PRE>
+<DL>
+</DL>
+<HR>
+
+<H3>
+eflags</H3>
+<PRE>
+int <B>eflags</B></PRE>
+<DL>
+</DL>
+<HR>
+
+<H3>
+offset</H3>
+<PRE>
+int <B>offset</B></PRE>
+<DL>
+</DL>
+<HR>
+
+<H3>
+anchor</H3>
+<PRE>
+int <B>anchor</B></PRE>
+<DL>
+</DL>
+<HR>
+
+<H3>
+index</H3>
+<PRE>
+int <B>index</B></PRE>
+<DL>
+</DL>
+<HR>
+
+<H3>
+start</H3>
+<PRE>
+int[] <B>start</B></PRE>
+<DL>
+</DL>
+<HR>
+
+<H3>
+end</H3>
+<PRE>
+int[] <B>end</B></PRE>
+<DL>
+</DL>
+<HR>
+
+<H3>
+next</H3>
+<PRE>
+<A HREF="gnu/regexp/REMatch.html">REMatch</A> <B>next</B></PRE>
+<DL>
+</DL>
+
+<P>
+<A NAME="gnu.regexp.REMatchEnumeration"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Class <A HREF="gnu/regexp/REMatchEnumeration.html">gnu.regexp.REMatchEnumeration</A> implements Serializable</B></FONT></TD>
+</TR>
+</TABLE>
+
+<P>
+<A NAME="serializedForm"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Serialized Fields</B></FONT></TD>
+</TR>
+</TABLE>
+
+<H3>
+more</H3>
+<PRE>
+int <B>more</B></PRE>
+<DL>
+</DL>
+<HR>
+
+<H3>
+match</H3>
+<PRE>
+<A HREF="gnu/regexp/REMatch.html">REMatch</A> <B>match</B></PRE>
+<DL>
+</DL>
+<HR>
+
+<H3>
+expr</H3>
+<PRE>
+<A HREF="gnu/regexp/RE.html">RE</A> <B>expr</B></PRE>
+<DL>
+</DL>
+<HR>
+
+<H3>
+input</H3>
+<PRE>
+<A HREF="gnu/regexp/CharIndexed.html">CharIndexed</A> <B>input</B></PRE>
+<DL>
+</DL>
+<HR>
+
+<H3>
+eflags</H3>
+<PRE>
+int <B>eflags</B></PRE>
+<DL>
+</DL>
+<HR>
+
+<H3>
+index</H3>
+<PRE>
+int <B>index</B></PRE>
+<DL>
+</DL>
+
+<P>
+<A NAME="gnu.regexp.RESyntax"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Class <A HREF="gnu/regexp/RESyntax.html">gnu.regexp.RESyntax</A> implements Serializable</B></FONT></TD>
+</TR>
+</TABLE>
+
+<P>
+<A NAME="serializedForm"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Serialized Fields</B></FONT></TD>
+</TR>
+</TABLE>
+
+<H3>
+bits</H3>
+<PRE>
+java.util.BitSet <B>bits</B></PRE>
+<DL>
+</DL>
+<HR>
+
+<H3>
+isFinal</H3>
+<PRE>
+boolean <B>isFinal</B></PRE>
+<DL>
+</DL>
+<HR>
+
+<H3>
+lineSeparator</H3>
+<PRE>
+java.lang.String <B>lineSeparator</B></PRE>
+<DL>
+</DL>
+
+<P>
+<A NAME="gnu.regexp.UncheckedRE"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Class <A HREF="gnu/regexp/UncheckedRE.html">gnu.regexp.UncheckedRE</A> implements Serializable</B></FONT></TD>
+</TR>
+</TABLE>
+
+<P>
+
+<P>
+<HR SIZE="4" NOSHADE>
+
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TD ALIGN="center"><FONT SIZE="+2">
+<B>Package</B> <B>gnu.regexp.util</B></FONT></TD>
+</TR>
+</TABLE>
+
+<P>
+<A NAME="gnu.regexp.util.REApplet"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableSubHeadingColor">
+<TD COLSPAN=2><FONT SIZE="+2">
+<B>Class <A HREF="gnu/regexp/util/REApplet.html">gnu.regexp.util.REApplet</A> implements Serializable</B></FONT></TD>
+</TR>
+</TABLE>
+
+<P>
+<A NAME="serializedForm"><!-- --></A>
+<TABLE BORDER="1" CELLPADDING="3" CELLSPACING="0" WIDTH="100%">
+<TR BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
+<TD COLSPAN=1><FONT SIZE="+2">
+<B>Serialized Fields</B></FONT></TD>
+</TR>
+</TABLE>
+
+<H3>
+l1</H3>
+<PRE>
+java.awt.Label <B>l1</B></PRE>
+<DL>
+</DL>
+<HR>
+
+<H3>
+l2</H3>
+<PRE>
+java.awt.Label <B>l2</B></PRE>
+<DL>
+</DL>
+<HR>
+
+<H3>
+l3</H3>
+<PRE>
+java.awt.Label <B>l3</B></PRE>
+<DL>
+</DL>
+<HR>
+
+<H3>
+l4</H3>
+<PRE>
+java.awt.Label <B>l4</B></PRE>
+<DL>
+</DL>
+<HR>
+
+<H3>
+b</H3>
+<PRE>
+java.awt.Button <B>b</B></PRE>
+<DL>
+</DL>
+<HR>
+
+<H3>
+tf</H3>
+<PRE>
+java.awt.TextField <B>tf</B></PRE>
+<DL>
+</DL>
+<HR>
+
+<H3>
+input</H3>
+<PRE>
+java.awt.TextArea <B>input</B></PRE>
+<DL>
+</DL>
+<HR>
+
+<H3>
+output</H3>
+<PRE>
+java.awt.TextArea <B>output</B></PRE>
+<DL>
+</DL>
+<HR>
+
+<H3>
+insens</H3>
+<PRE>
+java.awt.Checkbox <B>insens</B></PRE>
+<DL>
+</DL>
+<HR>
+
+<H3>
+syntax</H3>
+<PRE>
+java.awt.Choice <B>syntax</B></PRE>
+<DL>
+</DL>
+
+<P>
+<HR>
+
+<!-- ========== START OF NAVBAR ========== -->
+<A NAME="navbar_bottom"><!-- --></A>
+<TABLE BORDER="0" WIDTH="100%" CELLPADDING="1" CELLSPACING="0">
+<TR>
+<TD COLSPAN=2 BGCOLOR="#EEEEFF" CLASS="NavBarCell1">
+<A NAME="navbar_bottom_firstrow"><!-- --></A>
+<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">
+ <TR ALIGN="center" VALIGN="top">
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-summary.html"><FONT CLASS="NavBarFont1"><B>Overview</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Package</FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <FONT CLASS="NavBarFont1">Class</FONT> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="overview-tree.html"><FONT CLASS="NavBarFont1"><B>Tree</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="deprecated-list.html"><FONT CLASS="NavBarFont1"><B>Deprecated</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="index-all.html"><FONT CLASS="NavBarFont1"><B>Index</B></FONT></A> </TD>
+ <TD BGCOLOR="#EEEEFF" CLASS="NavBarCell1"> <A HREF="help-doc.html"><FONT CLASS="NavBarFont1"><B>Help</B></FONT></A> </TD>
+ </TR>
+</TABLE>
+</TD>
+<TD ALIGN="right" VALIGN="top" ROWSPAN=3><EM>
+</EM>
+</TD>
+</TR>
+
+<TR>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ PREV
+ NEXT</FONT></TD>
+<TD BGCOLOR="white" CLASS="NavBarCell2"><FONT SIZE="-2">
+ <A HREF="index.html" TARGET="_top"><B>FRAMES</B></A>
+ <A HREF="serialized-form.html" TARGET="_top"><B>NO FRAMES</B></A></FONT></TD>
+</TR>
+</TABLE>
+<!-- =========== END OF NAVBAR =========== -->
+
+<HR>
+
+</BODY>
+</HTML>
--- /dev/null
+/* Javadoc style sheet */
+
+/* Define colors, fonts and other style attributes here to override the defaults */
+
+/* Page background color */
+body { background-color: #FFFFFF }
+
+/* Table colors */
+.TableHeadingColor { background: #CCCCFF } /* Dark mauve */
+.TableSubHeadingColor { background: #EEEEFF } /* Light mauve */
+.TableRowColor { background: #FFFFFF } /* White */
+
+/* Font used in left-hand frame lists */
+.FrameTitleFont { font-size: normal; font-family: normal }
+.FrameHeadingFont { font-size: normal; font-family: normal }
+.FrameItemFont { font-size: normal; font-family: normal }
+
+/* Example of smaller, sans-serif font in frames */
+/* .FrameItemFont { font-size: 10pt; font-family: Helvetica, Arial, sans-serif } */
+
+/* Navigation bar fonts and colors */
+.NavBarCell1 { background-color:#EEEEFF;}/* Light mauve */
+.NavBarCell1Rev { background-color:#00008B;}/* Dark Blue */
+.NavBarFont1 { font-family: Arial, Helvetica, sans-serif; color:#000000;}
+.NavBarFont1Rev { font-family: Arial, Helvetica, sans-serif; color:#FFFFFF;}
+
+.NavBarCell2 { font-family: Arial, Helvetica, sans-serif; background-color:#FFFFFF;}
+.NavBarCell3 { font-family: Arial, Helvetica, sans-serif; background-color:#FFFFFF;}
+
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>package gnu.regexp - Regular Expressions for Java</TITLE>
+</HEAD>
+<BODY BGCOLOR=WHITE TEXT=BLACK>
+<FONT SIZE="+2"><B><CODE>package gnu.regexp;</CODE></B><HR NOSHADE>
+Change History</FONT><BR>
+<FONT SIZE="-1">This page was last updated on 21 October 2001</FONT>
+<P>
+<B>1.1.4 (21 October 2001)</B><BR>
+Patch to Makefile to include language resource files in the applet JAR. (Andrew G. Hammond)<BR>
+Updates to gnu.regexp.util.Grep to add "-z" option, expand ZIP files. (Ulf Dittmer)<BR>
+Some updates and clarifications to Javadoc, especially for substitute() methods. (Wes Biggs)<BR>
+Fix to RE constructor for some uses of alternation operator failing due to minimumLength being set incorrectly. (Marcus Abels)<BR>
+Added UncheckedRE subclass to provide constructors that are declared without exceptions (useful for static initializers). (Wes Biggs)<BR>
+The getMatchEnumeration() methods that took an integer index offset resulted in REMatch objects with incorrect values for their start and end indices (the correct text was matched, but the values from getStartIndex() and getEndIndex() methods were incorrect). This has been fixed. (Wes Biggs)<BR>
+
+<P>
+<B>1.1.3a (18 June 2001)</B><BR>
+No code changes; distribution was missing a file.<BR>
+<P>
+<B>1.1.3 (18 June 2001)</B><BR>
+Change method signatures in REFilterReader to correctly override the Reader interface. Patch from Doug Seifert.<BR>
+Fixed a bug in getMinimumLength() for expressions using alternation; because of this and the optimization introduced in 1.1.2, some matches were failing. (Wes Biggs)<BR>
+Il8n support: all error messages are now stored in MessagesBundle.properties (Alan Moore)<BR>
+Lookaheads, both positive and negative, are now supported, thanks to a patch from Shashank Bapat.<BR>
+Parse intervals more in accordance with POSIX, i.e., if they don't exactly match one of {n}, {n,}, or {n,m}, the characters are matched literally. (Alan Moore)<BR>
+Throw more exceptions when quantifiers (?, *, +, {}) appear in places where they are invalid, e.g., after a zero-width assertion (word boundary, lookahead), or after another quantifier. (Alan Moore)<BR>
+Fixed two instances where incomplete patterns would cause ArrayIndexOutOfBoundsExceptions instead of REExceptions. (Alan Moore)<BR>
+ASCII escapes \n, \r, and \t in [] lists are now supported. (Alan Moore)<BR>
+<P>
+<B>1.1.2 (11 April 2001)</B><BR>
+Fix REMatchEnumeration handling zero-length matches.<BR>
+Declare classes "final" as much as possible, for speed.<BR>
+Optimize match loop by checking remaining buffer against minimum length.<BR>
+Fix '\b' and '\<' support to work correctly if before any consuming operators in the RE. Thanks to Alan Moore for identifying the problem and a fix.<BR>
+Correct support for '^' in multiline match mode when used with an InputStream or Reader. Thanks to James Flynn for his suggestions and contributions.<BR>
+Code cleanup to get rid of some bizarre variable names and so forth.<BR>
+
+<P>
+<B>1.1.1 (16 February 2001)</B><BR>
+Better leftmost longest support (re-fixes alternation isMatch() issue).<BR>
+Fix for over-consuming behavior of character class/alternation.<BR>
+Fixed subexpression index reporting.<BR>
+Support for '\b', '\B', '\<' and '\>'.<BR>
+<P>
+
+<B>1.1.0 (6 February 2001)</B><BR>
+Many internal changes should result in speed increases.<BR>
+Fixed an issue where subexpression indices would not be correctly saved, causing StringIndexOutOfBoundsExceptions to be thrown from REMatch.<BR>
+Fixed a bug where subexpressions would not be found when nested and combined with alternation. (For example, "((A)B|(C)D)" would match "AB", but would not report subexpression #2.)<BR>
+Fixed a bug compiling expressions of the form "(())a".<BR>
+Fixed a problem where using the empty string as replacement text within a REFilterInputStream would throw an exception.<BR>
+Added a FAQ in the docs directory. Added known bugs to the TODO.<BR>
+Added REG_NO_INTERPOLATE execution bit, which allows substitution text to include $1-$9 without being interpolated. Suggested by Daniel Lescohier.<BR>
+Lee Sau Dan submitted support for using Readers, providing both CharIndexedReader and REFilterReader classes. As a consequence, this version is no longer compatible with JDK 1.0. However, Readers provide much better support for reading text in various encodings, and the use of InputStream to do the same has been deprecated.<BR>
+Clarified (in the javadoc) the semantics of getAllMatches() and substituteAll() when combined with REs that may match the empty string.<BR>
+RE constructors and match functions will convert any unrecognized Object input to a String using the class's toString() method, so it is no longer possible to get IllegalArgumentExceptions. Suggested by Nic Ferrier.<BR>
+Regular expressions are now serializable. Of course, it may be nearly as efficient to send the pattern string and recompile the RE on the other side.<BR>
+Incorporated a patch from Oleksandr Lytvyn to allow RE.isMatch() to return true if any alternation in the pattern allows the full input to be matched, not just the first alternation.<BR>
+Altered the [:print:] character class to correctly match all printable characters and space, not just alphanumerics. Caught by Richard Trahan.<BR>
+The alphanumeric match sequence (\w) now matches the underscore (_) character. Thanks to Aryaguna for pointing out the discrepancy.<BR>
+The start (^) and end ($) tokens, when used in multiline mode, now recognize multi-character newline sequences. In related news, you can override the platform-dependent line separator string by calling the setLineSeparator() method on RESyntax. REApplet has been modified to use this approach.<BR>
+Predefined RESyntax objects are now immutable, and attempts to modify them throw IllegalAccessErrors. User-defined syntaxes can also be made immutable by calling the makeFinal() method.<BR>
+RESyntax.clear(int) has been introduced as a parallel to RESyntax.set(int).<BR>
+CharIndexed is now a public interface, enabling developers to provide their own implementations that may be passed into getMatch(). Suggested by Ernie Rael.<BR>
+Expressions ending with an open subexpression token ('(') now correctly throw compilation exceptions.<BR>
+Noted in the documentation for REMatch.toString(int) that the index is one-based. Thanks to Daniel Rall for bringing it to attention.<BR>
+Fixed documentation note error regarding REG_DOT_NEWLINE. Thanks to Christophe Vigny for pointing this out.<BR>
+Deprecated getSub(Start|End)Index(int) in favor of the new get(Start|End)Index(int) overloading. Added a note in the JavaDoc that these are zero-based indices, per a suggestion by Chris Cobb.<BR>
+Fixed a bug where the regular expression "^$" would not match an empty string (or empty line, in multiline mode). Many thanks to James Jensen.<BR>
+Added better file condition error handling code to Grep utility, courtesy of Jon Schewe.<BR>
+The license (COPYING.LIB) has been changed to the GNU Lesser General Public License (the successor of the Library GPL). The change is only in name.<BR>
+
+<P>
+<B>1.0.8</B> (21 March 1999)<BR>
+Fixed handling of POSIX character classes (not used in default syntax).<BR>
+Added Tap, the evil water droplet, to the home page (thanks to Jim Blair, corvus@gnu.org).<BR>
+Changed the demo applet to support selectable syntax.<BR>
+<P>
+<B>1.0.7</B> (3 March 1999)<BR>
+Fixed NullPointerException when compiling expressions starting with '+' or '*'.<BR>
+Fixed reporting of subexpression start indices in certain cases.<BR>
+Removed static initializer in REToken.java to aid in compiling on non-compliant platforms.<BR>
+Fixed endless loop caused by array read in REFilterInputStream.<BR>
+Fixed ArrayIndexOutOfBoundsExceptions that could be thrown from REMatch.toString(int).<BR>
+Updated all doc comment versions to 1.0.7.<BR>
+Added a few tests to the test cottage (it's not big enough to be a suite).<BR>
+
+<P>
+
+<B>1.0.6</B> (18 November 1998)<BR>
+Fixed bug in subexpression position reporting.<BR>
+Fixed some bugs with zero-length regular expressions.<BR>
+More documentation for gnu.regexp.util classes.<BR>
+Makefile changes for Cygwin compatibility.<BR>
+Added credits.html file.<BR>
+Fixed paths to API docs in HTML.<BR>
+
+<P>
+
+<B>1.0.5</B> (8 November 1998)<BR>
+Added gnu.regexp.REFilterInputStream class.<BR>
+New directory structure for distribution.<BR>
+Added gnu.regexp.util.Tests class, a limited testsuite.<BR>
+Fixed bug in backreferences (\1, \2...) introduced in 1.0.4.<BR>
+Fixed bug in handling of literal '-' within bracketed lists.<BR>
+Changes to Makefile to work with Cygnus/Win32 systems.<BR>
+General enhancements to Makefile.<BR>
+Added TODO and CONTENTS files to distribution.<BR>
+Added support for Perl5 escapes (\w,\d,\s, etc.) within bracketed lists.<BR>
+Added matching syntax bit, RE_CHAR_CLASS_ESC_IN_LISTS.<BR>
+
+<P>
+
+<B>1.0.4</B> (8 October 1998)<BR>
+Added getMinimumLength method.<BR>
+Added Makefile to distribution.<BR>
+Added HTML to distribution.<BR>
+Added gnu/regexp/util/REApplet.java demo applet to distribution.<BR>
+Added support for pure grouping (?:...) operator.<BR>
+Added support for comment (?#...) operator.<BR>
+Minor changes for compatibility with guavac compiler.<BR>
+Fixed some quirks with including dashes in lists.<BR>
+Fixed some documentation errors.<BR>
+Fixed 1.0.3 bug in REMatch reporting skipped subexpressions.<BR>
+Fixed some major problems with alternation nested in subexpressions.<BR>
+Fixed some pathological cases that would cause infinite loops.<BR>
+
+<P>
+
+<B>1.0.3</B> (19 August 1998)<BR>
+Added REMatchEnumeration and getMatchEnumeration methods.<BR>
+Added support for compiling patterns from StringBuffers.<BR>
+Added support for matching, substituting, searching against StringBuffer, char[] and InputStream.<BR>
+Added toString(int) to REMatch to get subexpression matches easily.<BR>
+Added getMatch() with StringBuffer argument to save contents leading up to a match.<BR>
+substitute() and substituteAll() can now take $0 - $9 metacharacters.<BR>
+General optimizations.<BR>
+Source code cleanup, toward GNU coding standards.<BR>
+More and better javadoc documentation.<BR>
+getAllMatches() now returns non-overlapping matches as it should.<BR>
+All classes in 1.0.3 are JDK 1.0.2 compatible and should work in applets.<BR>
+
+RETest is no longer in the JAR as it is not needed in an execution
+environment. Source code is provided in the gnu/regexp/util
+directory.<BR>
+
+gnu/regexp/util also contains a pure-Java implementation of GNU grep
+and egrep, for your amusement and use on non-GNU operating systems
+which lack such rudimentary text processing facilities. Grep and
+Egrep require <A HREF="http://www.urbanophile.com/arenn/hacking/download.html">gnu.getopt</A>
+to compile and run.<BR>
+
+Note that due to certain API changes, you will need to recompile any source code that uses gnu.regexp against the 1.0.3 classes. No code changes are necessary.<BR>
+
+<P>
+
+<B>1.02a</B> (23 July 1998)<BR>
+No code changes. Added README, changed LICENSE to LGPL and changed
+copyright messages on source files. JAR file compiled with -O flag.
+
+<P>
+
+<B>1.02</B> (15 June 1998)<BR>
+Support for nested subexpressions. More debugging support.
+Fixed bug when escaping braces with a backslash.
+<P>
+
+<B>1.01</B> (1 June 1998)<BR>
+Fixed bug in list operator ( [...] ) which was causing the RE compiler to
+interpret the closing ']' as a literal.
+
+<P>
+
+<B>1.00</B> (22 May 1998)<BR>
+New API using RESyntax. New framework for "multiline" and "single
+line" matching. Default support for most Perl 5 constructs, including
+the following operators: \A, \d, \D, \w, \W, \s, \S, \Z, stingy
+matching (*?, ??, +?). Some string optimizations should speed up most
+matches. REG_NEWLINE wasn't working correctly in 0.07, it's gone and
+replaced by REG_MULTILINE (semantics matching Perl's "/m"
+operator). Support for POSIX character classes such as [:alpha:]
+within lists. General code cleanup and added comments.
+
+<P>
+
+<B>0.07</B> (10 April 1998)<BR>
+Added more default-argument versions of methods; added REG_ANCHORINDEX flag for substring processing; fixed bug in isMatch() for expressions with top-level branches; fixed bug in getMatch() for zero-length input never matching.
+
+<P>
+
+<B>0.06</B> (3 March 1998)<BR>
+First general release.
+
+<P>
+
+<FONT SIZE="-1">
+<A HREF="index.html">[gnu.regexp]</A>
+<A HREF="syntax.html">[syntax and usage]</A>
+<A HREF="api/index.html">[api documentation]</A>
+<A HREF="reapplet.html">[test applet]</A>
+<A HREF="faq.html">[faq]</A>
+<A HREF="credits.html">[credits]</A>
+</FONT>
+</BODY>
+</HTML>
+
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>package gnu.regexp - Regular Expressions for Java</TITLE>
+</HEAD>
+<BODY BGCOLOR=WHITE TEXT=BLACK>
+<FONT SIZE="+2"><B><CODE>package gnu.regexp;</CODE></B><HR NOSHADE>
+Credits</FONT><BR>
+<FONT SIZE="-1">This page was last updated on 6 February 2001</FONT>
+
+<P>
+
+<B>Shashank Bapat</B> contributed support for lookahead operators.<BR>
+<B>Wes Biggs</B> is the primary author of gnu.regexp and its maintainer.<BR>
+<B>Richard Bullington III</B> contributed a number of Makefile fixes.<BR>
+<B>David Crawford</B> wrote the nested subexpression code.<BR>
+<B>Lee Sau Dan</B> provided JDK 1.1 Reader support.<BR>
+<B>Paul Frantz</B> contributed a number of bug fixes.<BR>
+<B>Alan Moore</B> contributed a number of bug fixes.<BR>
+<B>Aaron Renn</B> is the author of gnu.getopt, used by Grep and Egrep.<BR>
+<B>Doug Seifert</B> helped with testing and defining the API.<BR>
+<B>Jason Venner</B> helped with API development.<BR>
+
+<P>
+
+Thanks to everyone else who has contributed or helped others use and learn
+gnu.regexp. This project would not be a success without the time and
+dedication of everyone involved.
+
+<P>
+
+<FONT SIZE="-1">
+<A HREF="index.html">[gnu.regexp]</A>
+<A HREF="syntax.html">[syntax and usage]</A>
+<A HREF="api/index.html">[api documentation]</A>
+<A HREF="reapplet.html">[test applet]</A>
+<A HREF="faq.html">[faq]</A>
+<A HREF="changes.html">[change history]</A>
+</FONT>
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>package gnu.regexp - Regular Expressions for Java</TITLE>
+</HEAD>
+<BODY BGCOLOR=WHITE TEXT=BLACK>
+<FONT SIZE="+2"><B><CODE>package gnu.regexp;</CODE></B><HR NOSHADE>
+Frequently Asked Questions</FONT><BR>
+<FONT SIZE="-1">This page was last updated on 26 January 2001</FONT>
+<P>
+<B>Thread safety</B><BR>
+<I>Is the package threadsafe?</I>
+<BR>
+<BR>
+Yes, by design. Once a RE object is compiled, it is never modified. Runtime data is attached to REMatch objects, which are created for each thread executing one of the match methods.
+<P>
+<B>Subexpression Indices</B><BR>
+<I>I have a regular expression that looks like "(Hello)World|(Foo)Bar". When I try to match the text "HelloWorldFooBar", the first match returns "HelloWorld" and its first subexpression is "Hello", both of which are correct. For the second match I get "FooBar", but the first subexpression is empty. What gives?</I>
+<BR>
+<BR>
+The behavior is correct. The subexpressions are numbered according to their position in the entire regular expression. Therefore the subexpression that matches "Foo" in the second match is subexpression number two.
+<P>
+<B>Getopt classes</B><BR>
+<I>When I try to compile the classes in gnu.regexp.util, I get errors saying gnu.getopt.Getopt and gnu.getopt.LongOpt cannot be found. Are they missing from the distribution?</I>
+<BR>
+<BR>
+While it's not necessary to compile the example classes in gnu.regexp.util, to do so you'll need to acquire Aaron Renn's excellent getopt package, which is also free software, but maintained separately. You can find it <A HREF="http://www.urbanophile.com/arenn/hacking/download.html">on his web site</A>.
+<P>
+<B>Examples</B><BR>
+<I>Where can I get some examples of real-world regular expressions?</I>
+<BR>
+<BR>
+You could buy a book. Or you could search the web. Or you could join the mailing list and ask there. Or you could contribute some so this answer is more helpful.
+<P>
+<B>Package naming</B><BR>
+<I>The official Sun recommendations on package naming conventions state that one should use a top-level domain name, reversed, for publicly distributed packages. Why aren't you using org.gnu.regexp instead of gnu.regexp?</I>
+<BR>
+<BR>
+Because I like gnu.regexp better. If you don't, feel free to repackage it. Such is open source. Before you flame me, realize that this conversation has been played out many, many times (and thus earns its place on this FAQ), and for many, many different gnu.* packages with many, many different maintainers. Until I get an official recommendation from the FSF to the contrary, it's going to be gnu.regexp.
+<P>
+<B>Compile Problems</B><BR>
+<I>I get an error compiling RESyntax.java. Is there a bug?</I>
+<BR>
+<BR>
+There is a problem with certain versions of javac and their support of static initializers. If you encounter it, first compile RESyntax.java (javac RESyntax.java), then proceed with compiling the rest of the classes.
+<P>
+<B>Java Versions</B><BR>
+<I>Why doesn't gnu.regexp 1.1.0 and above work on Java 1.0.2?</I><BR>
+<BR>
+Because dependencies on the java.io.Reader and java.io.Serializable classes were introduced into the package with version 1.1.0. Fortunately, unless you are running a Homebrew Computer Club antique, you quite likely can run a Java 1.1 or Java 2 virtual machine on your system.
+<P>
+<B>Two GNU Java Regular Expression Packages</B><BR>
+<I>Are there two GNU java regexp projects? Why don't you join efforts?</I>
+<BR>
+<BR>
+Yes, there are, and I've corresponded briefly with the author of
+gnu.rex. His package serves a different niche (smaller footprint,
+fewer features). Unifying them with a single front-end might be worth
+a shot. If you are interested in contributing to uniting the
+projects, let us know.
+<P>
+<B>License Terms</B><BR>
+<I>I saw that gnu.regexp was licensed under
+the LGPL (Lesser GNU General Public License). Can I get a formal
+statement of the legal situation of using this software from you?</I>
+<BR>
+<BR>
+The Free Software Foundation has a number of articles
+that discuss the legal ramifications of the LGPL. See <a
+href="http://www.gnu.org/">the GNU site</a> for details.
+<P>
+<I>Can I get an affidavit of Y2K compliance from you?</I>
+<BR>
+<BR>
+As an independent developer, it is not feasible for me to guarantee
+Y2K compliance, POSIX compliance, or make any other warranties. That
+being said, there are currently (version 1.1.3) no aspects of the
+regular expression library that refer in any way to date- or
+time-related functions or APIs, so gnu.regexp is unlikely in the
+extreme to cause any Y2K issues.
+<P>
+<B>Donations, Etc.</B><BR>
+<I>This is a great utility. Can I send you money?</I>
+<BR>
+<BR>
+Actually, I just <i>wish</i> this was a frequently asked question.
+But seriously, I would much prefer that if you feel the urge, you
+donate to the Free Software Foundation on behalf of gnu.regexp. Apart
+from helping fund important software development efforts, your gift is
+also tax deductible, and they'll send you a keen t-shirt if you're
+lucky.
+<P>
+<FONT SIZE="-1">
+<A HREF="index.html">[gnu.regexp]</A>
+<A HREF="changes.html">[change history]</A>
+<A HREF="syntax.html">[syntax and usage]</A>
+<A HREF="api/index.html">[api documentation]</A>
+<A HREF="reapplet.html">[test applet]</A>
+<A HREF="credits.html">[credits]</A>
+</FONT>
+</BODY>
+</HTML>
+
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 FINAL//EN">
+<HTML>
+<HEAD>
+<TITLE>package gnu.regexp - Regular Expressions for Java</TITLE>
+<LINK REV=MADE HREF="mailto:wes@cacas.org">
+</HEAD>
+<BODY BGCOLOR=WHITE TEXT=BLACK>
+<FONT SIZE="+2"><STRONG><CODE>package gnu.regexp;</CODE></STRONG>
+<BR CLEAR=ALL>
+<HR NOSHADE>
+<APPLET CODE="Animation.class" CODEBASE="http://www.gnu.org/graphics" WIDTH="130" HEIGHT="86" ALIGN=RIGHT>
+<PARAM name="base-name" value="drop">
+<PARAM name="extension" value="jpg">
+<PARAM name="num-images" value="15">
+<PARAM name="image-sequence" value="1..10,9,7,5,3,1">
+<PARAM name="frame-delay" value="30">
+<PARAM name="inner-loop-repeat" value="2">
+<PARAM name="loop-delay" value="10000">
+<PARAM name="outer-loop-repeat" value="0">
+<A HREF="http://www.gnu.org/graphics/drop-1.jpg"><IMG SRC="http://www.gnu.org/graphics/drop-1.jpg" ALT=" [image of the evil water droplet] " WIDTH="130" HEIGHT="86" BORDER="0"> (jpeg 3k)</A>
+<A HREF="http://www.gnu.org/philosophy/gif.html">no gifs due to patent problems</A>
+</applet>
+
+Regular Expressions for Java</FONT><BR>
+<FONT SIZE="-1">This page was last updated on 21 October 2001</FONT>
+<P>
+<STRONG><A NAME="latest">Latest Version</A></STRONG>
+<BR>
+The latest version of the package is 1.1.4. Download <A HREF="ftp://ftp.tralfamadore.com/pub/java/gnu.regexp-1.1.4.tar.gz">gnu.regexp-1.1.4.tar.gz</A>. You may need to rename the file if your browser changes it.<BR>
+The GZIPped file includes the Java archive library and
+the complete source code. Versions 1.1.0 and above of gnu.regexp require Java 1.1 or higher.
+<P>
+<STRONG><A NAME="latest">Java 1.0 Compatibility Version</A></STRONG>
+<BR>
+The previous version of the package was 1.0.8, released in March 1999. Download <A HREF="ftp://ftp.tralfamadore.com/pub/java/gnu.regexp-1.0.8.tar.gz">gnu.regexp-1.0.8.tar.gz</A>. You may need to rename the file if your browser changes it.<BR>
+The GZIPped file includes the Java archive library and
+the complete source code. Versions 1.0.8 and below are compatible with Java 1.0. Please note that the compatibility version is not being actively maintained.
+<P>
+<STRONG>Reference material (for latest version):</STRONG><BR>
+<A HREF="api/index.html">API documentation</A> (javadoc generated)<BR>
+<A HREF="syntax.html">Syntax and usage notes</A><BR>
+<A HREF="changes.html">Change history</A><BR>
+<A HREF="reapplet.html">Test applet</A><BR>
+<A HREF="faq.html">Frequently asked questions</A><BR>
+<A HREF="credits.html">Credits</A><BR>
+
+
+<P>
+
+<STRONG>Technical Notes</STRONG>
+<BR>
+
+The gnu.regexp package is a pure-Java implementation of a traditional
+(non-POSIX) NFA regular expression engine. Its syntax can emulate
+many popular development tools, including awk, sed, emacs, perl and
+grep. For a relatively complete list of supported and non-supported
+syntax, refer to the <A HREF="syntax.html">syntax and usage notes</A>.<BR>
+
+<P>
+<STRONG>Terms of Use</STRONG>
+<BR>
+
+The regexp library is distributed under the terms of the <A
+HREF="http://www.gnu.org/copyleft/lesser.html">GNU Lesser General
+Public License</A>. The COPYING.LIB file included
+in the distribution contains the details. This program is <A
+HREF="http://www.gnu.org/philosophy/free-sw.html">free software</A>.
+You are encouraged to adapt it to your own needs, and contribute to
+the program's ongoing development.
+
+<P>
+<STRONG>Installation</STRONG>
+<BR>
+1. Download the <A HREF="#latest">latest version</A>.<BR>
+2. Use GNU tar to extract the files.<BR>
+<BLOCKQUOTE>
+<CODE>tar xvzf gnu.regexp-1.1.4.tar.gz</CODE><BR>
+</BLOCKQUOTE>
+<BR>
+3. You will be left with the HTML-formatted documentation, a Java archive file containing the compressed bytecode for the gnu.regexp package, and the complete library source as well as source to a number of related utilities.<BR>
+4. Add the .jar file to your CLASSPATH setting. See the README file for help.
+<P>
+<STRONG>Mailing List</STRONG>
+<BR>
+To join a mailing list of gnu.regexp users and developers, send an email with the word "subscribe" in the subject to <A HREF="mailto:regexp-request@cacas.org">regexp-request@cacas.org</A>. You will be automatically subscribed.
+<P>
+Mailing list <A HREF="http://www.thispc.com/pipermail/regexp/">archives</A> are available.
+<P>
+<STRONG>Contribute</STRONG>
+<BR>
+If you would like to help contribute to the ongoing development of the package,
+or if you have suggestions for future enhancements and functionality,
+please send email to <a href="mailto:wes@cacas.org">wes@cacas.org</A> or better yet subscribe to the list.
+<P>
+<STRONG>Some applications built with gnu.regexp</STRONG><BR>
+<A HREF="http://www.enhydra.org/">Enhydra</A>, an open source application server<BR>
+<A HREF="http://www.xmlblaster.org/">xmlBlaster</A>, open source message-oriented middleware<BR>
+<A HREF="http://www.arlut.utexas.edu/gash2">Ganymede</A>, an RMI-based directory management system<BR>
+<A HREF="http://www.microstate.com/hamilton/">Hamilton</A>, an enterprise application server<BR>
+<A HREF="http://jedit.sourceforge.net/">jEdit</A>, a GUI text editor<BR>
+<A HREF="http://muffin.doit.org/">Muffin</A>, a filtering proxy web server<BR>
+<A HREF="http://www.jext.org/">Jext</A>, a GUI text editor<BR>
+<A HREF="http://www.sourceforge.net/projects/gutenpalm">GutenPalm</A>, document compressor for PalmOS<BR>
+<A HREF="http://www.mckoi.com/database/">Mckoi SQL Database</A>, an open source SQL-92 database system<BR>
+<A HREF="mailto:wes@cacas.org">Link to your application here!</A><BR>
+<P>
+<STRONG>Relevant links</STRONG><BR>
+<A HREF="http://www.gnu.org/software/java/java.html">GNU Java Software</A><BR>
+<A HREF="http://www.gnu.org/software/classpath/classpath.html">GNU Classpath Project</A><BR>
+<A HREF="http://java.sun.com/">JavaSoft (Sun)</A><BR>
+<A HREF="http://www.blackdown.org/java-linux.html">Java-Linux Porting Project</A><BR>
+<A HREF="http://www.transvirtual.com/">Kaffe OpenVM</A><BR>
+<A HREF="http://www.hungry.com/products/japhar/">Japhar free VM</A><BR>
+
+</BODY>
+</HTML>
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>package gnu.regexp - Regular Expressions for Java</TITLE>
+</HEAD>
+<BODY BGCOLOR=WHITE TEXT=BLACK>
+<FONT SIZE="+2"><B><CODE>package gnu.regexp;</CODE></B><HR NOSHADE>
+Test Applet</FONT><BR>
+<FONT SIZE="-1">This page was last updated on 20 March 1999</FONT>
+
+<P>
+<STRONG>About the Applet</STRONG><BR>
+
+The applet below (if your browser supports Java applets, that is) lets
+you play around with the gnu.regexp engine by compiling regular
+expressions and testing them against arbitrary input text (if you
+like, cut and paste into the input textarea). The applet JAR is about 27K
+in size, and includes the gnu.regexp library (24K).
+
+<P>
+<STRONG>Basic Usage</STRONG><BR>
+
+To get started, click the "Match" button using the defaults. You
+should see two matches found. Turn on the "ignore case" feature and
+click "Match" again. A third match will be found. Then try your own
+regular expressions (the applet defaults to a Perl5-like syntax) and
+input texts.
+
+<P>
+<STRONG>Troubleshooting</STRONG><BR>
+
+If the applet won't start, you may have an incompatible version of gnu.regexp
+in your browser's classpath setting (usually the gnu.regexp library will be downloaded for you by the browser). You can remedy this by quitting the browser and adjusting your classpath setting to exclude gnu.regexp before relaunching.
+
+<P>
+
+<TABLE BORDER=0 BGCOLOR=BLACK CELLSPACING=0 CELLPADDING=1>
+<TR><TD><APPLET archive="gnu-regexp-applet.jar" code="gnu/regexp/util/REApplet.class" width=500 height=200>
+<PARAM NAME="input" VALUE="A man, a plan, a canal: Panama.">
+<PARAM NAME="regexp" VALUE="a\s+\w+">
+<PARAM NAME="syntax" VALUE="perl 5">
+</APPLET></TD></TR></TABLE>
+
+<P>
+
+<FONT SIZE="-1">
+<A HREF="index.html">[gnu.regexp]</A>
+<A HREF="syntax.html">[syntax and usage]</A>
+<A HREF="changes.html">[change history]</A>
+<A HREF="api/packages.html">[api documentation]</A>
+<A HREF="faq.html">[faq]</A>
+<A HREF="credits.html">[credits]</A>
+</FONT>
+</BODY>
+</HTML>
+
+
--- /dev/null
+<HTML>
+<HEAD>
+<TITLE>package gnu.regexp - Regular Expressions for Java</TITLE>
+</HEAD>
+<BODY BGCOLOR=WHITE TEXT=BLACK>
+<FONT SIZE="+2"><B><CODE>package gnu.regexp;</CODE></B></FONT>
+<HR NOSHADE>
+<FONT SIZE="+2">Syntax and Usage Notes</FONT><BR>
+<FONT SIZE="-1">This page was last updated on 22 June 2001</FONT>
+<P>
+<B>Brief Background</B>
+<BR>
+
+A regular expression consists of a character string where some
+characters are given special meaning with regard to pattern matching.
+Regular expressions have been in use from the early days of computing,
+and provide a powerful and efficient way to parse, interpret and
+search and replace text within an application.
+
+<P>
+<B>Supported Syntax</B>
+<BR>
+Within a regular expression, the following characters have special meaning:<BR>
+<UL>
+<LI><B><I>Positional Operators</I></B><BR>
+<blockquote>
+<code>^</code> matches at the beginning of a line<SUP><A HREF="#note1">1</A></SUP><BR>
+<code>$</code> matches at the end of a line<SUP><A HREF="#note2">2</A></SUP><BR>
+<code>\A</code> matches the start of the entire string<BR>
+<code>\Z</code> matches the end of the entire string<BR>
+<code>\b</code> matches at a word break (Perl5 syntax only)<BR>
+<code>\B</code> matches at a non-word break (opposite of \b) (Perl5 syntax only)<BR>
+<code>\<</code> matches at the start of a word (egrep syntax only)<BR>
+<code>\></code> matches at the end of a word (egrep syntax only)<BR>
+</blockquote>
+
+<li>
+<B><I>One-Character Operators</I></B><BR>
+<blockquote>
+<code>.</code> matches any single character<SUP><A HREF="#note3">3</A></SUP><BR>
+<code>\d</code> matches any decimal digit<BR>
+<code>\D</code> matches any non-digit<BR>
+<code>\n</code> matches a newline character<BR>
+<code>\r</code> matches a return character<BR>
+<code>\s</code> matches any whitespace character<BR>
+<code>\S</code> matches any non-whitespace character<BR>
+<code>\t</code> matches a horizontal tab character<BR>
+<code>\w</code> matches any word (alphanumeric) character<BR>
+<code>\W</code> matches any non-word (alphanumeric) character<BR>
+<code>\<i>x</i></code> matches the character <i>x</i>, if <i>x</i> is not one of the above listed escape sequences.<BR>
+</blockquote>
+
+<li>
+<B><I>Character Class Operator</I></B><BR>
+<blockquote>
+<code>[<i>abc</i>]</code> matches any character in the set <i>a</i>, <i>b</i> or <i>c</i><BR>
+<code>[^<i>abc</i>]</code> matches any character not in the set <i>a</i>, <i>b</i> or <i>c</i><BR>
+<code>[<i>a-z</i>]</code> matches any character in the range <i>a</i> to <i>z</i>, inclusive<BR>
+A leading or trailing dash will be interpreted literally.<BR>
+</blockquote>
+
+Within a character class expression, the following sequences have special meaning if the syntax bit RE_CHAR_CLASSES is on:<BR>
+<blockquote>
+<code>[:alnum:]</code> Any alphanumeric character<br>
+<code>[:alpha:]</code> Any alphabetical character<br>
+<code>[:blank:]</code> A space or horizontal tab<br>
+<code>[:cntrl:]</code> A control character<br>
+<code>[:digit:]</code> A decimal digit<br>
+<code>[:graph:]</code> A non-space, non-control character<br>
+<code>[:lower:]</code> A lowercase letter<br>
+<code>[:print:]</code> Same as graph, but also space and tab<br>
+<code>[:punct:]</code> A punctuation character<br>
+<code>[:space:]</code> Any whitespace character, including newline and return<br>
+<code>[:upper:]</code> An uppercase letter<br>
+<code>[:xdigit:]</code> A valid hexadecimal digit<br>
+</blockquote>
+
+<li>
+<B><I>Subexpressions and Backreferences</I></B><BR>
+<blockquote>
+<code>(<i>abc</i>)</code> matches whatever the expression <i>abc</i> would match, and saves it as a subexpression. Also used for grouping.<BR>
+<code>(?:<i>...</i>)</code> pure grouping operator, does not save contents<BR>
+<code>(?#<i>...</i>)</code> embedded comment, ignored by engine<BR>
+<code>\<i>n</i></code> where 0 < <i>n</i> < 10, matches the same thing the <i>n</i><super>th</super> subexpression matched.<BR>
+</blockquote>
+
+<li>
+<B><I>Branching (Alternation) Operator</I></B><BR>
+<blockquote>
+<code><i>a</i>|<i>b</i></code> matches whatever the expression <i>a</i> would match, or whatever the expression <i>b</i> would match.<BR>
+</blockquote>
+
+<li>
+<B><I>Repeating Operators</I></B><BR>
+These symbols operate on the previous atomic expression.
+<blockquote>
+<code>?</code> matches the preceding expression or the null string<BR>
+<code>*</code> matches the null string or any number of repetitions of the preceding expression<BR>
+<code>+</code> matches one or more repetitions of the preceding expression<BR>
+<code>{<i>m</i>}</code> matches exactly <i>m</i> repetitions of the one-character expression<BR>
+<code>{<i>m</i>,<i>n</i>}</code> matches between <i>m</i> and <i>n</i> repetitions of the preceding expression, inclusive<BR>
+<code>{<i>m</i>,}</code> matches <i>m</i> or more repetitions of the preceding expression<BR>
+</blockquote>
+<li>
+<B><I>Stingy (Minimal) Matching</I></B><BR>
+
+If a repeating operator (above) is immediately followed by a
+<code>?</code>, the repeating operator will stop at the smallest
+number of repetitions that can complete the rest of the match.
+<p>
+<li>
+<B><I>Lookahead</I></B><BR>
+Lookahead refers to the ability to match part of an expression without consuming any of the input text. There are two variations to this:<P>
+<blockquote>
+<code>(?=<i>foo</i>)</code> matches at any position where <i>foo</i> would match, but does not consume any characters of the input.<BR>
+<code>(?!<i>foo</i>)</code> matches at any position where <i>foo</i> would not match, but does not consume any characters of the input.<BR>
+</blockquote>
+
+</UL>
+<P>
+<B>Unsupported Syntax</B>
+<BR>
+
+Some flavors of regular expression utilities support additional escape
+sequences, and this is not meant to be an exhaustive list. In the
+future, <code>gnu.regexp</code> may support some or all of the
+following:<BR>
+
+<blockquote>
+<code>(?<i>mods</i>)</code> inlined compilation/execution modifiers (Perl5)<BR>
+<code>\G</code> end of previous match (Perl5)<BR>
+<code>[.<i>symbol</i>.]</code> collating symbol in class expression (POSIX)<BR>
+<code>[=<i>class</i>=]</code> equivalence class in class expression (POSIX)<BR>
+<code>s/foo/bar/</code> style expressions as in sed and awk <I>(note: these can be accomplished through other means in the API)</I>
+</blockquote>
+
+<P>
+<B>Java Integration</B>
+<BR>
+
+In a Java environment, a regular expression operates on a string of
+Unicode characters, represented either as an instance of
+<code>java.lang.String</code> or as an array of the primitive
+<code>char</code> type. This means that the unit of matching is a
+Unicode character, not a single byte. Generally this will not present
+problems in a Java program, because Java takes pains to ensure that
+all textual data uses the Unicode standard.
+
+<P>
+
+Because Java string processing takes care of certain escape sequences,
+they are not implemented in <code>gnu.regexp</code>. You should be
+aware that the following escape sequences are handled by the Java
+compiler if found in the Java source:<BR>
+
+<blockquote>
+<code>\b</code> backspace<BR>
+<code>\f</code> form feed<BR>
+<code>\n</code> newline<BR>
+<code>\r</code> carriage return<BR>
+<code>\t</code> horizontal tab<BR>
+<code>\"</code> double quote<BR>
+<code>\'</code> single quote<BR>
+<code>\\</code> backslash<BR>
+<code>\<i>xxx</i></code> character, in octal (000-377)<BR>
+<code>\u<i>xxxx</i></code> Unicode character, in hexadecimal (0000-FFFF)<BR>
+</blockquote>
+
+In addition, note that the <code>\u</code> escape sequences are
+meaningful anywhere in a Java program, not merely within a singly- or
+doubly-quoted character string, and are converted prior to any of the
+other escape sequences. For example, the line <BR>
+
+<code>gnu.regexp.RE exp = new gnu.regexp.RE("\u005cn");</code><BR>
+
+would be converted by first replacing <code>\u005c</code> with a
+backslash, then converting <code>\n</code> to a newline. By the time
+the RE constructor is called, it will be passed a String object
+containing only the Unicode newline character.
+
+<P>
+
+The POSIX character classes (above), and the equivalent shorthand
+escapes (<code>\d</code>, <code>\w</code> and the like) are
+implemented to use the <code>java.lang.Character</code> static
+functions whenever possible. For example, <code>\w</code> and
+<code>[:alnum:]</code> (the latter only from within a class
+expression) will invoke the Java function
+<code>Character.isLetterOrDigit()</code> when executing. It is
+<i>always</i> better to use the POSIX expressions than a range such as
+<code>[a-zA-Z0-9]</code>, because the latter will not match any letter
+characters in non-ISO 9660 encodings (for example, the umlaut
+character, "<code>ü</code>").
+
+<P>
+<B>Reference Material</B>
+<BR>
+<UL>
+<LI><B><I>Print Books and Publications</I></B><BR>
+Friedl, Jeffrey E.F., <A HREF="http://www.oreilly.com/catalog/regex/"><I>Mastering Regular Expressions</I></A>. O'Reilly & Associates, Inc., Sebastopol, California, 1997.<BR>
+<P>
+<LI><B><I>Software Manuals and Guides</I></B><BR>
+Berry, Karl and Hargreaves, Kathryn A., <A HREF="http://www.cs.utah.edu/csinfo/texinfo/regex/regex_toc.html">GNU Info Regex Manual Edition 0.12a</A>, 19 September 1992.<BR>
+<code>perlre(1)</code> man page (Perl Programmer's Reference Guide)<BR>
+<code>regcomp(3)</code> man page (GNU C)<BR>
+<code>gawk(1)</code> man page (GNU utilities)<BR>
+<code>sed(1)</code> man page (GNU utilities)<BR>
+<code>ed(1)</code> man page (GNU utilities)<BR>
+<code>grep(1)</code> man page (GNU utilities)<BR>
+<code>regexp(n)</code> and <code>regsub(n)</code> man pages (TCL)<BR>
+</UL>
+
+<P>
+<B>Notes</B>
+<BR>
+<SUP><A NAME="note1">1</A></SUP> but see the REG_NOTBOL and REG_MULTILINE flags<BR>
+<SUP><A NAME="note2">2</A></SUP> but see the REG_NOTEOL and REG_MULTILINE flags<BR>
+<SUP><A NAME="note3">3</A></SUP> but see the REG_MULTILINE flag<BR>
+<P>
+<FONT SIZE="-1">
+<A HREF="index.html">[gnu.regexp]</A>
+<A HREF="changes.html">[change history]</A>
+<A HREF="api/index.html">[api documentation]</A>
+<A HREF="reapplet.html">[test applet]</A>
+<A HREF="faq.html">[faq]</A>
+<A HREF="credits.html">[credits]</A>
+</FONT>
+
+</BODY>
+</HTML>
+
--- /dev/null
+#
+# Makefile for gnu.regexp for use with GNU make
+# Copyright (C) 1998-2001 Wes Biggs
+#
+# This library is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published
+# by the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+
+# It's not strictly necessary to use this file -- most of what it does
+# you can do by running 'javac gnu/regexp/*.java'. However, it does allow
+# convenient building of the following targets:
+#
+# make (no args): builds all the gnu.regexp.* classes, and the JAR file
+# make install: copies the JAR to your designated INSTALLDIR (see below)
+# make applet: builds the demo applet and its JAR
+# make utils: builds the gnu.regexp.util.* classes (requires gnu.getopt)
+# make javadocs: build the source documentation
+# make dist: build the distribution tar.gz file (requires GNU tar)
+# make clean: deletes all class files and JARs
+#
+# You may need to edit some of the paths or compiler defaults below.
+
+# This is the directory where .class files will be placed
+LIBDIR = ../lib
+LIBDIR32 = ..\lib
+
+# Note that these conditional makefile statements require GNU make
+# The special treatment for cygwin32 relies on the OSTYPE environment
+# variable. Because the Cygwin tools are still in beta, it's been
+# changing. This needs to be "cygwin32" for Beta 19 and higher beta versions,
+# "win32" for earlier versions, and just "cygwin" for recent releases.
+ifeq ($(OSTYPE),cygwin)
+FSEP = \\
+PSEP = ;
+LIBPATH = $(LIBDIR32)
+else
+FSEP = /
+PSEP = :
+LIBPATH = $(LIBDIR)
+endif
+
+JAVAFLAGSCLASSPATH = -classpath ".$(PSEP)$(LIBPATH)$(PSEP)${CLASSPATH}"
+GNUREGEXPPATH = gnu${FSEP}regexp${FSEP}
+GNUREGEXPUTILPATH = ${GNUREGEXPPATH}util${FSEP}
+
+# Change JAVAC variable to your java compiler.
+# Change JAVAFLAGS variable to any java flags you want to compile with.
+
+JAVAC = jikes
+JAVAFLAGS = -O
+
+#JAVAC = javac
+#JAVAFLAGS = -O
+
+JAVACOMPILE = $(JAVAC) -d "$(LIBPATH)" $(JAVAFLAGSCLASSPATH) $(JAVAFLAGS)
+
+# This is the directory the gnu.regexp JAR file will be installed in when
+# you do a 'make install'
+INSTALLDIR = /usr/local/java/lib
+
+# This is where the applet JAR goes
+DOCSDIR = ../docs
+# This is where the generated javadocs will go when you do a 'make javadocs'
+APIDOCSDIR = ../docs/api
+
+GNUREGEXPVERSION = 1.1.4
+
+GNUREGEXPCORECLASSES = \
+ $(LIBDIR)/gnu/regexp/RESyntax.class \
+ $(LIBDIR)/gnu/regexp/CharIndexed.class \
+ $(LIBDIR)/gnu/regexp/REMatch.class \
+ $(LIBDIR)/gnu/regexp/REToken.class \
+ $(LIBDIR)/gnu/regexp/REException.class \
+ $(LIBDIR)/gnu/regexp/RETokenChar.class \
+ $(LIBDIR)/gnu/regexp/RETokenRange.class \
+ $(LIBDIR)/gnu/regexp/RETokenPOSIX.class \
+ $(LIBDIR)/gnu/regexp/RETokenOneOf.class \
+ $(LIBDIR)/gnu/regexp/RETokenAny.class \
+ $(LIBDIR)/gnu/regexp/RETokenEndSub.class \
+ $(LIBDIR)/gnu/regexp/RETokenWordBoundary.class \
+ $(LIBDIR)/gnu/regexp/RETokenRepeated.class \
+ $(LIBDIR)/gnu/regexp/RETokenBackRef.class \
+ $(LIBDIR)/gnu/regexp/RETokenLookAhead.class \
+ $(LIBDIR)/gnu/regexp/CharIndexedString.class \
+ $(LIBDIR)/gnu/regexp/CharIndexedCharArray.class \
+ $(LIBDIR)/gnu/regexp/CharIndexedStringBuffer.class \
+ $(LIBDIR)/gnu/regexp/CharIndexedInputStream.class \
+ $(LIBDIR)/gnu/regexp/CharIndexedReader.class \
+ $(LIBDIR)/gnu/regexp/IntPair.class \
+ $(LIBDIR)/gnu/regexp/CharUnit.class \
+ $(LIBDIR)/gnu/regexp/RE.class \
+ $(LIBDIR)/gnu/regexp/UncheckedRE.class \
+ $(LIBDIR)/gnu/regexp/RETokenStart.class \
+ $(LIBDIR)/gnu/regexp/RETokenEnd.class \
+ $(LIBDIR)/gnu/regexp/REMatchEnumeration.class \
+ $(LIBDIR)/gnu/regexp/MessagesBundle.properties
+
+GNUREGEXPCLASSES = ${GNUREGEXPCORECLASSES} \
+ $(LIBDIR)/gnu/regexp/REFilterInputStream.class \
+ $(LIBDIR)/gnu/regexp/REFilterReader.class
+
+GNUREGEXPUTILCLASSES = \
+ $(LIBDIR)/gnu/regexp/util/Grep.class \
+ $(LIBDIR)/gnu/regexp/util/Egrep.class \
+ $(LIBDIR)/gnu/regexp/util/Tests.class \
+ $(LIBDIR)/gnu/regexp/util/RETest.class
+
+GNUREGEXPAPPLETCLASSES = ${GNUREGEXPCORECLASSES} \
+ $(LIBDIR)/gnu/regexp/util/REApplet.class
+
+gnu.regexp: $(GNUREGEXPCLASSES) $(LIBDIR)/gnu-regexp-${GNUREGEXPVERSION}.jar
+
+all: gnu.regexp applet utils
+
+applet: $(DOCSDIR)/gnu-regexp-applet.jar
+
+
+install: $(LIBDIR)/gnu-regexp-${GNUREGEXPVERSION}.jar
+ cp -f $(LIBDIR)/gnu-regexp-${GNUREGEXPVERSION}.jar ${INSTALLDIR}
+
+utils: ${GNUREGEXPUTILCLASSES}
+
+clean:
+ rm -f ${GNUREGEXPCLASSES} ${GNUREGEXPUTILCLASSES} ${GNUREGEXPAPPLETCLASSES}
+ rm -f $(LIBDIR)/gnu-regexp-${GNUREGEXPVERSION}.jar
+ rm -f $(DOCSDIR)/gnu-regexp-applet.jar
+
+GNUREGEXPDIR = gnu.regexp-${GNUREGEXPVERSION}
+
+# This constitutes the official distribution
+dist: $(LIBDIR)/gnu-regexp-${GNUREGEXPVERSION}.jar
+ rm -f ../.CONTENTS
+ sed 's/^/$(GNUREGEXPDIR)\//' < ../CONTENTS > ../.CONTENTS
+ cd ../..; tar cvzf $(GNUREGEXPDIR).tar.gz -T $(GNUREGEXPDIR)/.CONTENTS
+
+javadocs:
+ mkdir -p ${APIDOCSDIR}
+ javadoc -d ${APIDOCSDIR} -author -version -public gnu.regexp gnu.regexp.util
+
+$(LIBDIR)/gnu-regexp-${GNUREGEXPVERSION}.jar: ${GNUREGEXPCLASSES}
+ cd $(LIBDIR); jar cvf gnu-regexp-${GNUREGEXPVERSION}.jar gnu/regexp/*.class gnu/regexp/*.properties
+
+$(DOCSDIR)/gnu-regexp-applet.jar: ${GNUREGEXPCLASSES} $(LIBDIR)/gnu/regexp/util/REApplet.class
+ cd $(LIBDIR); jar cvf gnu-regexp-applet.jar gnu/regexp/*.class gnu/regexp/*.properties gnu/regexp/util/REApplet.class; mv gnu-regexp-applet.jar $(DOCSDIR)
+
+# Special rules for gnu.regexp.IntPair and gnu.regexp.CharUnit inner classes
+#
+$(LIBDIR)/gnu/regexp/IntPair.class $(LIBDIR)/gnu/regexp/CharUnit.class $(LIBDIR)/gnu/regexp/RE.class : gnu/regexp/RE.java
+
+# Common rule for compiling a java file
+$(LIBDIR)/gnu/regexp/%.class: gnu/regexp/%.java
+ $(JAVACOMPILE) $<
+
+# Properties files just get copied
+$(LIBDIR)/gnu/regexp/%.properties: gnu/regexp/%.properties
+ cp $< $@
--- /dev/null
+/*
+ * gnu/regexp/CharIndexed.java
+ * Copyright (C) 1998-2001 Wes Biggs
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package gnu.regexp;
+
+/**
+ * Defines the interface used internally so that different types of source
+ * text can be accessed in the same way. Built-in concrete classes provide
+ * support for String, StringBuffer, InputStream and char[] types.
+ * A class that is CharIndexed supports the notion of a cursor within a
+ * block of text. The cursor must be able to be advanced via the move()
+ * method. The charAt() method returns the character at the cursor position
+ * plus a given offset.
+ *
+ * @author <A HREF="mailto:wes@cacas.org">Wes Biggs</A>
+ */
+public interface CharIndexed {
+ /**
+ * Defines a constant (0xFFFF was somewhat arbitrarily chosen)
+ * that can be returned by the charAt() function indicating that
+ * the specified index is out of range.
+ */
+ char OUT_OF_BOUNDS = '\uFFFF';
+
+ /**
+ * Returns the character at the given offset past the current cursor
+ * position in the input. The index of the current position is zero.
+ * It is possible for this method to be called with a negative index.
+ * This happens when using the '^' operator in multiline matching mode
+ * or the '\b' or '\<' word boundary operators. In any case, the lower
+ * bound is currently fixed at -2 (for '^' with a two-character newline).
+ *
+ * @param index the offset position in the character field to examine
+ * @return the character at the specified index, or the OUT_OF_BOUNDS
+ * character defined by this interface.
+ */
+ char charAt(int index);
+
+ /**
+ * Shifts the input buffer by a given number of positions. Returns
+ * true if the new cursor position is valid.
+ */
+ boolean move(int index);
+
+ /**
+ * Returns true if the most recent move() operation placed the cursor
+ * position at a valid position in the input.
+ */
+ boolean isValid();
+}
--- /dev/null
+/*
+ * gnu/regexp/CharIndexedCharArray.java
+ * Copyright (C) 1998-2001 Wes Biggs
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package gnu.regexp;
+import java.io.Serializable;
+
+class CharIndexedCharArray implements CharIndexed, Serializable {
+ private char[] s;
+ private int anchor;
+
+ CharIndexedCharArray(char[] str, int index) {
+ s = str;
+ anchor = index;
+ }
+
+ public char charAt(int index) {
+ int pos = anchor + index;
+ return ((pos < s.length) && (pos >= 0)) ? s[pos] : OUT_OF_BOUNDS;
+ }
+
+ public boolean isValid() {
+ return (anchor < s.length);
+ }
+
+ public boolean move(int index) {
+ return ((anchor += index) < s.length);
+ }
+}
--- /dev/null
+/*
+ * gnu/regexp/CharIndexedReader.java
+ * Copyright (C) 1998-2001 Wes Biggs
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package gnu.regexp;
+import java.io.InputStream;
+import java.io.BufferedInputStream;
+import java.io.IOException;
+
+// TODO: move(x) shouldn't rely on calling next() x times
+
+class CharIndexedInputStream implements CharIndexed {
+ private static final int BUFFER_INCREMENT = 1024;
+ private static final int UNKNOWN = Integer.MAX_VALUE; // value for end
+
+ private BufferedInputStream br;
+
+ // so that we don't try to reset() right away
+ private int index = -1;
+
+ private int bufsize = BUFFER_INCREMENT;
+
+ private int end = UNKNOWN;
+
+ private char cached = OUT_OF_BOUNDS;
+
+ // Big enough for a \r\n pair
+ // lookBehind[0] = most recent
+ // lookBehind[1] = second most recent
+ private char[] lookBehind = new char[] { OUT_OF_BOUNDS, OUT_OF_BOUNDS };
+
+ CharIndexedInputStream(InputStream str, int index) {
+ if (str instanceof BufferedInputStream) br = (BufferedInputStream) str;
+ else br = new BufferedInputStream(str,BUFFER_INCREMENT);
+ next();
+ if (index > 0) move(index);
+ }
+
+ private boolean next() {
+ if (end == 1) return false;
+ end--; // closer to end
+
+ try {
+ if (index != -1) {
+ br.reset();
+ }
+ int i = br.read();
+ br.mark(bufsize);
+ if (i == -1) {
+ end = 1;
+ cached = OUT_OF_BOUNDS;
+ return false;
+ }
+ cached = (char) i;
+ index = 1;
+ } catch (IOException e) {
+ e.printStackTrace();
+ cached = OUT_OF_BOUNDS;
+ return false;
+ }
+ return true;
+ }
+
+ public char charAt(int index) {
+ if (index == 0) {
+ return cached;
+ } else if (index >= end) {
+ return OUT_OF_BOUNDS;
+ } else if (index == -1) {
+ return lookBehind[0];
+ } else if (index == -2) {
+ return lookBehind[1];
+ } else if (index < -2) {
+ return OUT_OF_BOUNDS;
+ } else if (index >= bufsize) {
+ // Allocate more space in the buffer.
+ try {
+ while (bufsize <= index) bufsize += BUFFER_INCREMENT;
+ br.reset();
+ br.mark(bufsize);
+ br.skip(index-1);
+ } catch (IOException e) { }
+ } else if (this.index != index) {
+ try {
+ br.reset();
+ br.skip(index-1);
+ } catch (IOException e) { }
+ }
+ char ch = OUT_OF_BOUNDS;
+
+ try {
+ int i = br.read();
+ this.index = index+1; // this.index is index of next pos relative to charAt(0)
+ if (i == -1) {
+ // set flag that next should fail next time?
+ end = index;
+ return ch;
+ }
+ ch = (char) i;
+ } catch (IOException ie) { }
+
+ return ch;
+ }
+
+ public boolean move(int index) {
+ // move read position [index] clicks from 'charAt(0)'
+ boolean retval = true;
+ while (retval && (index-- > 0)) retval = next();
+ return retval;
+ }
+
+ public boolean isValid() {
+ return (cached != OUT_OF_BOUNDS);
+ }
+}
+
--- /dev/null
+/*
+ * gnu/regexp/CharIndexedReader.java
+ * Copyright (C) 2001 Lee Sau Dan
+ * Based on gnu.regexp.CharIndexedInputStream by Wes Biggs
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package gnu.regexp;
+import java.io.Reader;
+import java.io.BufferedReader;
+import java.io.IOException;
+
+// TODO: move(x) shouldn't rely on calling next() x times
+
+class CharIndexedReader implements CharIndexed {
+ private static final int BUFFER_INCREMENT = 1024;
+ private static final int UNKNOWN = Integer.MAX_VALUE; // value for end
+
+ private final BufferedReader br;
+ // so that we don't try to reset() right away
+ private int index = -1;
+
+ private int bufsize = BUFFER_INCREMENT;
+
+ private int end = UNKNOWN;
+
+ private char cached = OUT_OF_BOUNDS;
+
+ // Big enough for a \r\n pair
+ // lookBehind[0] = most recent
+ // lookBehind[1] = second most recent
+ private char[] lookBehind = new char[] { OUT_OF_BOUNDS, OUT_OF_BOUNDS };
+
+ CharIndexedReader(Reader reader, int index) {
+ if (reader instanceof BufferedReader) {
+ br = (BufferedReader) reader;
+ } else {
+ br = new BufferedReader(reader,BUFFER_INCREMENT);
+ }
+ next();
+ if (index > 0) move(index);
+ }
+
+ private boolean next() {
+ lookBehind[1] = lookBehind[0];
+ lookBehind[0] = cached;
+
+ if (end == 1) {
+ cached = OUT_OF_BOUNDS;
+ return false;
+ }
+ end--; // closer to end
+
+ try {
+ if (index != -1) {
+ br.reset();
+ }
+ int i = br.read();
+ br.mark(bufsize);
+ if (i == -1) {
+ end = 1;
+ cached = OUT_OF_BOUNDS;
+ return false;
+ }
+
+ // convert the byte read into a char
+ cached = (char) i;
+ index = 1;
+ } catch (IOException e) {
+ e.printStackTrace();
+ cached = OUT_OF_BOUNDS;
+ return false;
+ }
+ return true;
+ }
+
+ public char charAt(int index) {
+ if (index == 0) {
+ return cached;
+ } else if (index >= end) {
+ return OUT_OF_BOUNDS;
+ } else if (index >= bufsize) {
+ // Allocate more space in the buffer.
+ try {
+ while (bufsize <= index) bufsize += BUFFER_INCREMENT;
+ br.reset();
+ br.mark(bufsize);
+ br.skip(index-1);
+ } catch (IOException e) { }
+ } else if (this.index != index) {
+ try {
+ br.reset();
+ br.skip(index-1);
+ } catch (IOException e) { }
+ } else if (index == -1) {
+ return lookBehind[0];
+ } else if (index == -2) {
+ return lookBehind[1];
+ } else if (index < -2) {
+ return OUT_OF_BOUNDS;
+ }
+
+ char ch = OUT_OF_BOUNDS;
+
+ try {
+ int i = br.read();
+ this.index = index+1; // this.index is index of next pos relative to charAt(0)
+ if (i == -1) {
+ // set flag that next should fail next time?
+ end = index;
+ return ch;
+ }
+ ch = (char) i;
+ } catch (IOException ie) { }
+
+ return ch;
+ }
+
+ public boolean move(int index) {
+ // move read position [index] clicks from 'charAt(0)'
+ boolean retval = true;
+ while (retval && (index-- > 0)) retval = next();
+ return retval;
+ }
+
+ public boolean isValid() {
+ return (cached != OUT_OF_BOUNDS);
+ }
+}
--- /dev/null
+/*
+ * gnu/regexp/CharIndexedString.java
+ * Copyright (C) 1998-2001 Wes Biggs
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package gnu.regexp;
+import java.io.Serializable;
+
+class CharIndexedString implements CharIndexed, Serializable {
+ private String s;
+ private int anchor;
+ private int len;
+
+ CharIndexedString(String str, int index) {
+ s = str;
+ len = s.length();
+ anchor = index;
+ }
+
+ public char charAt(int index) {
+ int pos = anchor + index;
+ return ((pos < len) && (pos >= 0)) ? s.charAt(pos) : OUT_OF_BOUNDS;
+ }
+
+ public boolean isValid() {
+ return (anchor < len);
+ }
+
+ public boolean move(int index) {
+ return ((anchor += index) < len);
+ }
+}
--- /dev/null
+/*
+ * gnu/regexp/CharIndexedStringBuffer.java
+ * Copyright (C) 1998-2001 Wes Biggs
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package gnu.regexp;
+import java.io.Serializable;
+
+class CharIndexedStringBuffer implements CharIndexed, Serializable {
+ private StringBuffer s;
+ private int anchor;
+
+ CharIndexedStringBuffer(StringBuffer str, int index) {
+ s = str;
+ anchor = index;
+ }
+
+ public char charAt(int index) {
+ int pos = anchor + index;
+ return ((pos < s.length()) && (pos >= 0)) ? s.charAt(pos) : OUT_OF_BOUNDS;
+ }
+
+ public boolean isValid() {
+ return (anchor < s.length());
+ }
+
+ public boolean move(int index) {
+ return ((anchor += index) < s.length());
+ }
+}
--- /dev/null
+# Localized error messages for gnu.regexp
+
+# Prefix for REException messages
+error.prefix=At position {0} in regular expression pattern:
+
+# REException (parse error) messages
+repeat.assertion=repeated token is zero-width assertion
+repeat.chained=attempted to repeat a token that is already repeated
+repeat.no.token=quantifier (?*+{}) without preceding token
+repeat.empty.token=repeated token may be empty
+unmatched.brace=unmatched brace
+unmatched.bracket=unmatched bracket
+unmatched.paren=unmatched parenthesis
+interval.no.end=expected end of interval
+class.no.end=expected end of character class
+subexpr.no.end=expected end of subexpression
+interval.order=interval minimum is greater than maximum
+interval.error=interval is empty or contains illegal chracters
+ends.with.backslash=backslash at end of pattern
+
+# RESyntax message
+syntax.final=Syntax has been declared final and cannot be modified
--- /dev/null
+/*
+ * gnu/regexp/RE.java
+ * Copyright (C) 1998-2001 Wes Biggs
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package gnu.regexp;
+import java.io.InputStream;
+import java.io.Reader;
+import java.io.Serializable;
+import java.util.Locale;
+import java.util.PropertyResourceBundle;
+import java.util.ResourceBundle;
+import java.util.Vector;
+
+class IntPair implements Serializable {
+ public int first, second;
+}
+
+class CharUnit implements Serializable {
+ public char ch;
+ public boolean bk;
+}
+
+/**
+ * RE provides the user interface for compiling and matching regular
+ * expressions.
+ * <P>
+ * A regular expression object (class RE) is compiled by constructing it
+ * from a String, StringBuffer or character array, with optional
+ * compilation flags (below)
+ * and an optional syntax specification (see RESyntax; if not specified,
+ * <code>RESyntax.RE_SYNTAX_PERL5</code> is used).
+ * <P>
+ * Various methods attempt to match input text against a compiled
+ * regular expression. These methods are:
+ * <LI><code>isMatch</code>: returns true if the input text in its entirety
+ * matches the regular expression pattern.
+ * <LI><code>getMatch</code>: returns the first match found in the input text,
+ * or null if no match is found.
+ * <LI><code>getAllMatches</code>: returns an array of all non-overlapping
+ * matches found in the input text. If no matches are found, the array is
+ * zero-length.
+ * <LI><code>substitute</code>: substitute the first occurence of the pattern
+ * in the input text with a replacement string (which may include
+ * metacharacters $0-$9, see REMatch.substituteInto).
+ * <LI><code>substituteAll</code>: same as above, but repeat for each match
+ * before returning.
+ * <LI><code>getMatchEnumeration</code>: returns an REMatchEnumeration object
+ * that allows iteration over the matches (see REMatchEnumeration for some
+ * reasons why you may want to do this instead of using <code>getAllMatches</code>.
+ * <P>
+ *
+ * These methods all have similar argument lists. The input can be a
+ * String, a character array, a StringBuffer, a Reader or an
+ * InputStream of some sort. Note that when using a Reader or
+ * InputStream, the stream read position cannot be guaranteed after
+ * attempting a match (this is not a bug, but a consequence of the way
+ * regular expressions work). Using an REMatchEnumeration can
+ * eliminate most positioning problems.
+ *
+ * <P>
+ *
+ * The optional index argument specifies the offset from the beginning
+ * of the text at which the search should start (see the descriptions
+ * of some of the execution flags for how this can affect positional
+ * pattern operators). For a Reader or InputStream, this means an
+ * offset from the current read position, so subsequent calls with the
+ * same index argument on a Reader or an InputStream will not
+ * necessarily access the same position on the stream, whereas
+ * repeated searches at a given index in a fixed string will return
+ * consistent results.
+ *
+ * <P>
+ * You can optionally affect the execution environment by using a
+ * combination of execution flags (constants listed below).
+ *
+ * <P>
+ * All operations on a regular expression are performed in a
+ * thread-safe manner.
+ *
+ * @author <A HREF="mailto:wes@cacas.org">Wes Biggs</A>
+ * @version 1.1.4-dev, to be released
+ */
+
+public class RE extends REToken {
+ // This String will be returned by getVersion()
+ private static final String VERSION = "1.1.4-dev";
+
+ // The localized strings are kept in a separate file
+ private static ResourceBundle messages = PropertyResourceBundle.getBundle("gnu/regexp/MessagesBundle", Locale.getDefault());
+
+ // These are, respectively, the first and last tokens in our linked list
+ // If there is only one token, firstToken == lastToken
+ private REToken firstToken, lastToken;
+
+ // This is the number of subexpressions in this regular expression,
+ // with a minimum value of zero. Returned by getNumSubs()
+ private int numSubs;
+
+ /** Minimum length, in characters, of any possible match. */
+ private int minimumLength;
+
+ /**
+ * Compilation flag. Do not differentiate case. Subsequent
+ * searches using this RE will be case insensitive.
+ */
+ public static final int REG_ICASE = 2;
+
+ /**
+ * Compilation flag. The match-any-character operator (dot)
+ * will match a newline character. When set this overrides the syntax
+ * bit RE_DOT_NEWLINE (see RESyntax for details). This is equivalent to
+ * the "/s" operator in Perl.
+ */
+ public static final int REG_DOT_NEWLINE = 4;
+
+ /**
+ * Compilation flag. Use multiline mode. In this mode, the ^ and $
+ * anchors will match based on newlines within the input. This is
+ * equivalent to the "/m" operator in Perl.
+ */
+ public static final int REG_MULTILINE = 8;
+
+ /**
+ * Execution flag.
+ * The match-beginning operator (^) will not match at the beginning
+ * of the input string. Useful for matching on a substring when you
+ * know the context of the input is such that position zero of the
+ * input to the match test is not actually position zero of the text.
+ * <P>
+ * This example demonstrates the results of various ways of matching on
+ * a substring.
+ * <P>
+ * <CODE>
+ * String s = "food bar fool";<BR>
+ * RE exp = new RE("^foo.");<BR>
+ * REMatch m0 = exp.getMatch(s);<BR>
+ * REMatch m1 = exp.getMatch(s.substring(8));<BR>
+ * REMatch m2 = exp.getMatch(s.substring(8),0,RE.REG_NOTBOL); <BR>
+ * REMatch m3 = exp.getMatch(s,8); <BR>
+ * REMatch m4 = exp.getMatch(s,8,RE.REG_ANCHORINDEX); <BR>
+ * <P>
+ * // Results:<BR>
+ * // m0 = "food"<BR>
+ * // m1 = "fool"<BR>
+ * // m2 = null<BR>
+ * // m3 = null<BR>
+ * // m4 = "fool"<BR>
+ * </CODE>
+ */
+ public static final int REG_NOTBOL = 16;
+
+ /**
+ * Execution flag.
+ * The match-end operator ($) does not match at the end
+ * of the input string. Useful for matching on substrings.
+ */
+ public static final int REG_NOTEOL = 32;
+
+ /**
+ * Execution flag.
+ * When a match method is invoked that starts matching at a non-zero
+ * index into the input, treat the input as if it begins at the index
+ * given. The effect of this flag is that the engine does not "see"
+ * any text in the input before the given index. This is useful so
+ * that the match-beginning operator (^) matches not at position 0
+ * in the input string, but at the position the search started at
+ * (based on the index input given to the getMatch function). See
+ * the example under REG_NOTBOL. It also affects the use of the \<
+ * and \b operators.
+ */
+ public static final int REG_ANCHORINDEX = 64;
+
+ /**
+ * Execution flag.
+ * The substitute and substituteAll methods will not attempt to
+ * interpolate occurrences of $1-$9 in the replacement text with
+ * the corresponding subexpressions. For example, you may want to
+ * replace all matches of "one dollar" with "$1".
+ */
+ public static final int REG_NO_INTERPOLATE = 128;
+
+ /** Returns a string representing the version of the gnu.regexp package. */
+ public static final String version() {
+ return VERSION;
+ }
+
+ // Retrieves a message from the ResourceBundle
+ static final String getLocalizedMessage(String key) {
+ return messages.getString(key);
+ }
+
+ /**
+ * Constructs a regular expression pattern buffer without any compilation
+ * flags set, and using the default syntax (RESyntax.RE_SYNTAX_PERL5).
+ *
+ * @param pattern A regular expression pattern, in the form of a String,
+ * StringBuffer or char[]. Other input types will be converted to
+ * strings using the toString() method.
+ * @exception REException The input pattern could not be parsed.
+ * @exception NullPointerException The pattern was null.
+ */
+ public RE(Object pattern) throws REException {
+ this(pattern,0,RESyntax.RE_SYNTAX_PERL5,0,0);
+ }
+
+ /**
+ * Constructs a regular expression pattern buffer using the specified
+ * compilation flags and the default syntax (RESyntax.RE_SYNTAX_PERL5).
+ *
+ * @param pattern A regular expression pattern, in the form of a String,
+ * StringBuffer, or char[]. Other input types will be converted to
+ * strings using the toString() method.
+ * @param cflags The logical OR of any combination of the compilation flags listed above.
+ * @exception REException The input pattern could not be parsed.
+ * @exception NullPointerException The pattern was null.
+ */
+ public RE(Object pattern, int cflags) throws REException {
+ this(pattern,cflags,RESyntax.RE_SYNTAX_PERL5,0,0);
+ }
+
+ /**
+ * Constructs a regular expression pattern buffer using the specified
+ * compilation flags and regular expression syntax.
+ *
+ * @param pattern A regular expression pattern, in the form of a String,
+ * StringBuffer, or char[]. Other input types will be converted to
+ * strings using the toString() method.
+ * @param cflags The logical OR of any combination of the compilation flags listed above.
+ * @param syntax The type of regular expression syntax to use.
+ * @exception REException The input pattern could not be parsed.
+ * @exception NullPointerException The pattern was null.
+ */
+ public RE(Object pattern, int cflags, RESyntax syntax) throws REException {
+ this(pattern,cflags,syntax,0,0);
+ }
+
+ // internal constructor used for alternation
+ private RE(REToken first, REToken last,int subs, int subIndex, int minLength) {
+ super(subIndex);
+ firstToken = first;
+ lastToken = last;
+ numSubs = subs;
+ minimumLength = minLength;
+ addToken(new RETokenEndSub(subIndex));
+ }
+
+ private RE(Object patternObj, int cflags, RESyntax syntax, int myIndex, int nextSub) throws REException {
+ super(myIndex); // Subexpression index of this token.
+ initialize(patternObj, cflags, syntax, myIndex, nextSub);
+ }
+
+ // For use by subclasses
+ protected RE() { super(0); }
+
+ // The meat of construction
+ protected void initialize(Object patternObj, int cflags, RESyntax syntax, int myIndex, int nextSub) throws REException {
+ char[] pattern;
+ if (patternObj instanceof String) {
+ pattern = ((String) patternObj).toCharArray();
+ } else if (patternObj instanceof char[]) {
+ pattern = (char[]) patternObj;
+ } else if (patternObj instanceof StringBuffer) {
+ pattern = new char [((StringBuffer) patternObj).length()];
+ ((StringBuffer) patternObj).getChars(0,pattern.length,pattern,0);
+ } else {
+ pattern = patternObj.toString().toCharArray();
+ }
+
+ int pLength = pattern.length;
+
+ numSubs = 0; // Number of subexpressions in this token.
+ Vector branches = null;
+
+ // linked list of tokens (sort of -- some closed loops can exist)
+ firstToken = lastToken = null;
+
+ // Precalculate these so we don't pay for the math every time we
+ // need to access them.
+ boolean insens = ((cflags & REG_ICASE) > 0);
+
+ // Parse pattern into tokens. Does anyone know if it's more efficient
+ // to use char[] than a String.charAt()? I'm assuming so.
+
+ // index tracks the position in the char array
+ int index = 0;
+
+ // this will be the current parse character (pattern[index])
+ CharUnit unit = new CharUnit();
+
+ // This is used for {x,y} calculations
+ IntPair minMax = new IntPair();
+
+ // Buffer a token so we can create a TokenRepeated, etc.
+ REToken currentToken = null;
+ char ch;
+
+ while (index < pLength) {
+ // read the next character unit (including backslash escapes)
+ index = getCharUnit(pattern,index,unit);
+
+ // ALTERNATION OPERATOR
+ // \| or | (if RE_NO_BK_VBAR) or newline (if RE_NEWLINE_ALT)
+ // not available if RE_LIMITED_OPS is set
+
+ // TODO: the '\n' literal here should be a test against REToken.newline,
+ // which unfortunately may be more than a single character.
+ if ( ( (unit.ch == '|' && (syntax.get(RESyntax.RE_NO_BK_VBAR) ^ unit.bk))
+ || (syntax.get(RESyntax.RE_NEWLINE_ALT) && (unit.ch == '\n') && !unit.bk) )
+ && !syntax.get(RESyntax.RE_LIMITED_OPS)) {
+ // make everything up to here be a branch. create vector if nec.
+ addToken(currentToken);
+ RE theBranch = new RE(firstToken, lastToken, numSubs, subIndex, minimumLength);
+ minimumLength = 0;
+ if (branches == null) {
+ branches = new Vector();
+ }
+ branches.addElement(theBranch);
+ firstToken = lastToken = currentToken = null;
+ }
+
+ // INTERVAL OPERATOR:
+ // {x} | {x,} | {x,y} (RE_INTERVALS && RE_NO_BK_BRACES)
+ // \{x\} | \{x,\} | \{x,y\} (RE_INTERVALS && !RE_NO_BK_BRACES)
+ //
+ // OPEN QUESTION:
+ // what is proper interpretation of '{' at start of string?
+
+ else if ((unit.ch == '{') && syntax.get(RESyntax.RE_INTERVALS) && (syntax.get(RESyntax.RE_NO_BK_BRACES) ^ unit.bk)) {
+ int newIndex = getMinMax(pattern,index,minMax,syntax);
+ if (newIndex > index) {
+ if (minMax.first > minMax.second)
+ throw new REException(getLocalizedMessage("interval.order"),REException.REG_BADRPT,newIndex);
+ if (currentToken == null)
+ throw new REException(getLocalizedMessage("repeat.no.token"),REException.REG_BADRPT,newIndex);
+ if (currentToken instanceof RETokenRepeated)
+ throw new REException(getLocalizedMessage("repeat.chained"),REException.REG_BADRPT,newIndex);
+ if (currentToken instanceof RETokenWordBoundary || currentToken instanceof RETokenWordBoundary)
+ throw new REException(getLocalizedMessage("repeat.assertion"),REException.REG_BADRPT,newIndex);
+ if ((currentToken.getMinimumLength() == 0) && (minMax.second == Integer.MAX_VALUE))
+ throw new REException(getLocalizedMessage("repeat.empty.token"),REException.REG_BADRPT,newIndex);
+ index = newIndex;
+ currentToken = setRepeated(currentToken,minMax.first,minMax.second,index);
+ }
+ else {
+ addToken(currentToken);
+ currentToken = new RETokenChar(subIndex,unit.ch,insens);
+ }
+ }
+
+ // LIST OPERATOR:
+ // [...] | [^...]
+
+ else if ((unit.ch == '[') && !unit.bk) {
+ Vector options = new Vector();
+ boolean negative = false;
+ char lastChar = 0;
+ if (index == pLength) throw new REException(getLocalizedMessage("unmatched.bracket"),REException.REG_EBRACK,index);
+
+ // Check for initial caret, negation
+ if ((ch = pattern[index]) == '^') {
+ negative = true;
+ if (++index == pLength) throw new REException(getLocalizedMessage("class.no.end"),REException.REG_EBRACK,index);
+ ch = pattern[index];
+ }
+
+ // Check for leading right bracket literal
+ if (ch == ']') {
+ lastChar = ch;
+ if (++index == pLength) throw new REException(getLocalizedMessage("class.no.end"),REException.REG_EBRACK,index);
+ }
+
+ while ((ch = pattern[index++]) != ']') {
+ if ((ch == '-') && (lastChar != 0)) {
+ if (index == pLength) throw new REException(getLocalizedMessage("class.no.end"),REException.REG_EBRACK,index);
+ if ((ch = pattern[index]) == ']') {
+ options.addElement(new RETokenChar(subIndex,lastChar,insens));
+ lastChar = '-';
+ } else {
+ options.addElement(new RETokenRange(subIndex,lastChar,ch,insens));
+ lastChar = 0;
+ index++;
+ }
+ } else if ((ch == '\\') && syntax.get(RESyntax.RE_BACKSLASH_ESCAPE_IN_LISTS)) {
+ if (index == pLength) throw new REException(getLocalizedMessage("class.no.end"),REException.REG_EBRACK,index);
+ int posixID = -1;
+ boolean negate = false;
+ char asciiEsc = 0;
+ if (("dswDSW".indexOf(pattern[index]) != -1) && syntax.get(RESyntax.RE_CHAR_CLASS_ESC_IN_LISTS)) {
+ switch (pattern[index]) {
+ case 'D':
+ negate = true;
+ case 'd':
+ posixID = RETokenPOSIX.DIGIT;
+ break;
+ case 'S':
+ negate = true;
+ case 's':
+ posixID = RETokenPOSIX.SPACE;
+ break;
+ case 'W':
+ negate = true;
+ case 'w':
+ posixID = RETokenPOSIX.ALNUM;
+ break;
+ }
+ }
+ else if ("nrt".indexOf(pattern[index]) != -1) {
+ switch (pattern[index]) {
+ case 'n':
+ asciiEsc = '\n';
+ break;
+ case 't':
+ asciiEsc = '\t';
+ break;
+ case 'r':
+ asciiEsc = '\r';
+ break;
+ }
+ }
+ if (lastChar != 0) options.addElement(new RETokenChar(subIndex,lastChar,insens));
+
+ if (posixID != -1) {
+ options.addElement(new RETokenPOSIX(subIndex,posixID,insens,negate));
+ } else if (asciiEsc != 0) {
+ lastChar = asciiEsc;
+ } else {
+ lastChar = pattern[index];
+ }
+ ++index;
+ } else if ((ch == '[') && (syntax.get(RESyntax.RE_CHAR_CLASSES)) && (index < pLength) && (pattern[index] == ':')) {
+ StringBuffer posixSet = new StringBuffer();
+ index = getPosixSet(pattern,index+1,posixSet);
+ int posixId = RETokenPOSIX.intValue(posixSet.toString());
+ if (posixId != -1)
+ options.addElement(new RETokenPOSIX(subIndex,posixId,insens,false));
+ } else {
+ if (lastChar != 0) options.addElement(new RETokenChar(subIndex,lastChar,insens));
+ lastChar = ch;
+ }
+ if (index == pLength) throw new REException(getLocalizedMessage("class.no.end"),REException.REG_EBRACK,index);
+ } // while in list
+ // Out of list, index is one past ']'
+
+ if (lastChar != 0) options.addElement(new RETokenChar(subIndex,lastChar,insens));
+
+ // Create a new RETokenOneOf
+ addToken(currentToken);
+ options.trimToSize();
+ currentToken = new RETokenOneOf(subIndex,options,negative);
+ }
+
+ // SUBEXPRESSIONS
+ // (...) | \(...\) depending on RE_NO_BK_PARENS
+
+ else if ((unit.ch == '(') && (syntax.get(RESyntax.RE_NO_BK_PARENS) ^ unit.bk)) {
+ boolean pure = false;
+ boolean comment = false;
+ boolean lookAhead = false;
+ boolean negativelh = false;
+ if ((index+1 < pLength) && (pattern[index] == '?')) {
+ switch (pattern[index+1]) {
+ case '!':
+ if (syntax.get(RESyntax.RE_LOOKAHEAD)) {
+ pure = true;
+ negativelh = true;
+ lookAhead = true;
+ index += 2;
+ }
+ break;
+ case '=':
+ if (syntax.get(RESyntax.RE_LOOKAHEAD)) {
+ pure = true;
+ lookAhead = true;
+ index += 2;
+ }
+ break;
+ case ':':
+ if (syntax.get(RESyntax.RE_PURE_GROUPING)) {
+ pure = true;
+ index += 2;
+ }
+ break;
+ case '#':
+ if (syntax.get(RESyntax.RE_COMMENTS)) {
+ comment = true;
+ }
+ break;
+ default:
+ throw new REException(getLocalizedMessage("repeat.no.token"), REException.REG_BADRPT, index);
+ }
+ }
+
+ if (index >= pLength) {
+ throw new REException(getLocalizedMessage("unmatched.paren"), REException.REG_ESUBREG,index);
+ }
+
+ // find end of subexpression
+ int endIndex = index;
+ int nextIndex = index;
+ int nested = 0;
+
+ while ( ((nextIndex = getCharUnit(pattern,endIndex,unit)) > 0)
+ && !(nested == 0 && (unit.ch == ')') && (syntax.get(RESyntax.RE_NO_BK_PARENS) ^ unit.bk)) )
+ if ((endIndex = nextIndex) >= pLength)
+ throw new REException(getLocalizedMessage("subexpr.no.end"),REException.REG_ESUBREG,nextIndex);
+ else if (unit.ch == '(' && (syntax.get(RESyntax.RE_NO_BK_PARENS) ^ unit.bk))
+ nested++;
+ else if (unit.ch == ')' && (syntax.get(RESyntax.RE_NO_BK_PARENS) ^ unit.bk))
+ nested--;
+
+ // endIndex is now position at a ')','\)'
+ // nextIndex is end of string or position after ')' or '\)'
+
+ if (comment) index = nextIndex;
+ else { // not a comment
+ // create RE subexpression as token.
+ addToken(currentToken);
+ if (!pure) {
+ numSubs++;
+ }
+
+ int useIndex = (pure || lookAhead) ? 0 : nextSub + numSubs;
+ currentToken = new RE(String.valueOf(pattern,index,endIndex-index).toCharArray(),cflags,syntax,useIndex,nextSub + numSubs);
+ numSubs += ((RE) currentToken).getNumSubs();
+
+ if (lookAhead) {
+ currentToken = new RETokenLookAhead(currentToken,negativelh);
+ }
+
+ index = nextIndex;
+ } // not a comment
+ } // subexpression
+
+ // UNMATCHED RIGHT PAREN
+ // ) or \) throw exception if
+ // !syntax.get(RESyntax.RE_UNMATCHED_RIGHT_PAREN_ORD)
+ else if (!syntax.get(RESyntax.RE_UNMATCHED_RIGHT_PAREN_ORD) && ((unit.ch == ')') && (syntax.get(RESyntax.RE_NO_BK_PARENS) ^ unit.bk))) {
+ throw new REException(getLocalizedMessage("unmatched.paren"),REException.REG_EPAREN,index);
+ }
+
+ // START OF LINE OPERATOR
+ // ^
+
+ else if ((unit.ch == '^') && !unit.bk) {
+ addToken(currentToken);
+ currentToken = null;
+ addToken(new RETokenStart(subIndex,((cflags & REG_MULTILINE) > 0) ? syntax.getLineSeparator() : null));
+ }
+
+ // END OF LINE OPERATOR
+ // $
+
+ else if ((unit.ch == '$') && !unit.bk) {
+ addToken(currentToken);
+ currentToken = null;
+ addToken(new RETokenEnd(subIndex,((cflags & REG_MULTILINE) > 0) ? syntax.getLineSeparator() : null));
+ }
+
+ // MATCH-ANY-CHARACTER OPERATOR (except possibly newline and null)
+ // .
+
+ else if ((unit.ch == '.') && !unit.bk) {
+ addToken(currentToken);
+ currentToken = new RETokenAny(subIndex,syntax.get(RESyntax.RE_DOT_NEWLINE) || ((cflags & REG_DOT_NEWLINE) > 0),syntax.get(RESyntax.RE_DOT_NOT_NULL));
+ }
+
+ // ZERO-OR-MORE REPEAT OPERATOR
+ // *
+
+ else if ((unit.ch == '*') && !unit.bk) {
+ if (currentToken == null)
+ throw new REException(getLocalizedMessage("repeat.no.token"),REException.REG_BADRPT,index);
+ if (currentToken instanceof RETokenRepeated)
+ throw new REException(getLocalizedMessage("repeat.chained"),REException.REG_BADRPT,index);
+ if (currentToken instanceof RETokenWordBoundary || currentToken instanceof RETokenWordBoundary)
+ throw new REException(getLocalizedMessage("repeat.assertion"),REException.REG_BADRPT,index);
+ if (currentToken.getMinimumLength() == 0)
+ throw new REException(getLocalizedMessage("repeat.empty.token"),REException.REG_BADRPT,index);
+ currentToken = setRepeated(currentToken,0,Integer.MAX_VALUE,index);
+ }
+
+ // ONE-OR-MORE REPEAT OPERATOR
+ // + | \+ depending on RE_BK_PLUS_QM
+ // not available if RE_LIMITED_OPS is set
+
+ else if ((unit.ch == '+') && !syntax.get(RESyntax.RE_LIMITED_OPS) && (!syntax.get(RESyntax.RE_BK_PLUS_QM) ^ unit.bk)) {
+ if (currentToken == null)
+ throw new REException(getLocalizedMessage("repeat.no.token"),REException.REG_BADRPT,index);
+ if (currentToken instanceof RETokenRepeated)
+ throw new REException(getLocalizedMessage("repeat.chained"),REException.REG_BADRPT,index);
+ if (currentToken instanceof RETokenWordBoundary || currentToken instanceof RETokenWordBoundary)
+ throw new REException(getLocalizedMessage("repeat.assertion"),REException.REG_BADRPT,index);
+ if (currentToken.getMinimumLength() == 0)
+ throw new REException(getLocalizedMessage("repeat.empty.token"),REException.REG_BADRPT,index);
+ currentToken = setRepeated(currentToken,1,Integer.MAX_VALUE,index);
+ }
+
+ // ZERO-OR-ONE REPEAT OPERATOR / STINGY MATCHING OPERATOR
+ // ? | \? depending on RE_BK_PLUS_QM
+ // not available if RE_LIMITED_OPS is set
+ // stingy matching if RE_STINGY_OPS is set and it follows a quantifier
+
+ else if ((unit.ch == '?') && !syntax.get(RESyntax.RE_LIMITED_OPS) && (!syntax.get(RESyntax.RE_BK_PLUS_QM) ^ unit.bk)) {
+ if (currentToken == null) throw new REException(getLocalizedMessage("repeat.no.token"),REException.REG_BADRPT,index);
+
+ // Check for stingy matching on RETokenRepeated
+ if (currentToken instanceof RETokenRepeated) {
+ if (syntax.get(RESyntax.RE_STINGY_OPS) && !((RETokenRepeated)currentToken).isStingy())
+ ((RETokenRepeated)currentToken).makeStingy();
+ else
+ throw new REException(getLocalizedMessage("repeat.chained"),REException.REG_BADRPT,index);
+ }
+ else if (currentToken instanceof RETokenWordBoundary || currentToken instanceof RETokenWordBoundary)
+ throw new REException(getLocalizedMessage("repeat.assertion"),REException.REG_BADRPT,index);
+ else
+ currentToken = setRepeated(currentToken,0,1,index);
+ }
+
+ // BACKREFERENCE OPERATOR
+ // \1 \2 ... \9
+ // not available if RE_NO_BK_REFS is set
+
+ else if (unit.bk && Character.isDigit(unit.ch) && !syntax.get(RESyntax.RE_NO_BK_REFS)) {
+ addToken(currentToken);
+ currentToken = new RETokenBackRef(subIndex,Character.digit(unit.ch,10),insens);
+ }
+
+ // START OF STRING OPERATOR
+ // \A if RE_STRING_ANCHORS is set
+
+ else if (unit.bk && (unit.ch == 'A') && syntax.get(RESyntax.RE_STRING_ANCHORS)) {
+ addToken(currentToken);
+ currentToken = new RETokenStart(subIndex,null);
+ }
+
+ // WORD BREAK OPERATOR
+ // \b if ????
+
+ else if (unit.bk && (unit.ch == 'b') && syntax.get(RESyntax.RE_STRING_ANCHORS)) {
+ addToken(currentToken);
+ currentToken = new RETokenWordBoundary(subIndex, RETokenWordBoundary.BEGIN | RETokenWordBoundary.END, false);
+ }
+
+ // WORD BEGIN OPERATOR
+ // \< if ????
+ else if (unit.bk && (unit.ch == '<')) {
+ addToken(currentToken);
+ currentToken = new RETokenWordBoundary(subIndex, RETokenWordBoundary.BEGIN, false);
+ }
+
+ // WORD END OPERATOR
+ // \> if ????
+ else if (unit.bk && (unit.ch == '>')) {
+ addToken(currentToken);
+ currentToken = new RETokenWordBoundary(subIndex, RETokenWordBoundary.END, false);
+ }
+
+ // NON-WORD BREAK OPERATOR
+ // \B if ????
+
+ else if (unit.bk && (unit.ch == 'B') && syntax.get(RESyntax.RE_STRING_ANCHORS)) {
+ addToken(currentToken);
+ currentToken = new RETokenWordBoundary(subIndex, RETokenWordBoundary.BEGIN | RETokenWordBoundary.END, true);
+ }
+
+
+ // DIGIT OPERATOR
+ // \d if RE_CHAR_CLASS_ESCAPES is set
+
+ else if (unit.bk && (unit.ch == 'd') && syntax.get(RESyntax.RE_CHAR_CLASS_ESCAPES)) {
+ addToken(currentToken);
+ currentToken = new RETokenPOSIX(subIndex,RETokenPOSIX.DIGIT,insens,false);
+ }
+
+ // NON-DIGIT OPERATOR
+ // \D
+
+ else if (unit.bk && (unit.ch == 'D') && syntax.get(RESyntax.RE_CHAR_CLASS_ESCAPES)) {
+ addToken(currentToken);
+ currentToken = new RETokenPOSIX(subIndex,RETokenPOSIX.DIGIT,insens,true);
+ }
+
+ // NEWLINE ESCAPE
+ // \n
+
+ else if (unit.bk && (unit.ch == 'n')) {
+ addToken(currentToken);
+ currentToken = new RETokenChar(subIndex,'\n',false);
+ }
+
+ // RETURN ESCAPE
+ // \r
+
+ else if (unit.bk && (unit.ch == 'r')) {
+ addToken(currentToken);
+ currentToken = new RETokenChar(subIndex,'\r',false);
+ }
+
+ // WHITESPACE OPERATOR
+ // \s if RE_CHAR_CLASS_ESCAPES is set
+
+ else if (unit.bk && (unit.ch == 's') && syntax.get(RESyntax.RE_CHAR_CLASS_ESCAPES)) {
+ addToken(currentToken);
+ currentToken = new RETokenPOSIX(subIndex,RETokenPOSIX.SPACE,insens,false);
+ }
+
+ // NON-WHITESPACE OPERATOR
+ // \S
+
+ else if (unit.bk && (unit.ch == 'S') && syntax.get(RESyntax.RE_CHAR_CLASS_ESCAPES)) {
+ addToken(currentToken);
+ currentToken = new RETokenPOSIX(subIndex,RETokenPOSIX.SPACE,insens,true);
+ }
+
+ // TAB ESCAPE
+ // \t
+
+ else if (unit.bk && (unit.ch == 't')) {
+ addToken(currentToken);
+ currentToken = new RETokenChar(subIndex,'\t',false);
+ }
+
+ // ALPHANUMERIC OPERATOR
+ // \w
+
+ else if (unit.bk && (unit.ch == 'w') && syntax.get(RESyntax.RE_CHAR_CLASS_ESCAPES)) {
+ addToken(currentToken);
+ currentToken = new RETokenPOSIX(subIndex,RETokenPOSIX.ALNUM,insens,false);
+ }
+
+ // NON-ALPHANUMERIC OPERATOR
+ // \W
+
+ else if (unit.bk && (unit.ch == 'W') && syntax.get(RESyntax.RE_CHAR_CLASS_ESCAPES)) {
+ addToken(currentToken);
+ currentToken = new RETokenPOSIX(subIndex,RETokenPOSIX.ALNUM,insens,true);
+ }
+
+ // END OF STRING OPERATOR
+ // \Z
+
+ else if (unit.bk && (unit.ch == 'Z') && syntax.get(RESyntax.RE_STRING_ANCHORS)) {
+ addToken(currentToken);
+ currentToken = new RETokenEnd(subIndex,null);
+ }
+
+ // NON-SPECIAL CHARACTER (or escape to make literal)
+ // c | \* for example
+
+ else { // not a special character
+ addToken(currentToken);
+ currentToken = new RETokenChar(subIndex,unit.ch,insens);
+ }
+ } // end while
+
+ // Add final buffered token and an EndSub marker
+ addToken(currentToken);
+
+ if (branches != null) {
+ branches.addElement(new RE(firstToken,lastToken,numSubs,subIndex,minimumLength));
+ branches.trimToSize(); // compact the Vector
+ minimumLength = 0;
+ firstToken = lastToken = null;
+ addToken(new RETokenOneOf(subIndex,branches,false));
+ }
+ else addToken(new RETokenEndSub(subIndex));
+
+ }
+
+ private static int getCharUnit(char[] input, int index, CharUnit unit) throws REException {
+ unit.ch = input[index++];
+ if (unit.bk = (unit.ch == '\\'))
+ if (index < input.length)
+ unit.ch = input[index++];
+ else throw new REException(getLocalizedMessage("ends.with.backslash"),REException.REG_ESCAPE,index);
+ return index;
+ }
+
+ /**
+ * Checks if the regular expression matches the input in its entirety.
+ *
+ * @param input The input text.
+ */
+ public boolean isMatch(Object input) {
+ return isMatch(input,0,0);
+ }
+
+ /**
+ * Checks if the input string, starting from index, is an exact match of
+ * this regular expression.
+ *
+ * @param input The input text.
+ * @param index The offset index at which the search should be begin.
+ */
+ public boolean isMatch(Object input,int index) {
+ return isMatch(input,index,0);
+ }
+
+
+ /**
+ * Checks if the input, starting from index and using the specified
+ * execution flags, is an exact match of this regular expression.
+ *
+ * @param input The input text.
+ * @param index The offset index at which the search should be begin.
+ * @param eflags The logical OR of any execution flags above.
+ */
+ public boolean isMatch(Object input,int index,int eflags) {
+ return isMatchImpl(makeCharIndexed(input,index),index,eflags);
+ }
+
+ private boolean isMatchImpl(CharIndexed input, int index, int eflags) {
+ if (firstToken == null) // Trivial case
+ return (input.charAt(0) == CharIndexed.OUT_OF_BOUNDS);
+ REMatch m = new REMatch(numSubs, index, eflags);
+ if (firstToken.match(input, m)) {
+ while (m != null) {
+ if (input.charAt(m.index) == CharIndexed.OUT_OF_BOUNDS) {
+ return true;
+ }
+ m = m.next;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns the maximum number of subexpressions in this regular expression.
+ * If the expression contains branches, the value returned will be the
+ * maximum subexpressions in any of the branches.
+ */
+ public int getNumSubs() {
+ return numSubs;
+ }
+
+ // Overrides REToken.setUncle
+ void setUncle(REToken uncle) {
+ if (lastToken != null) {
+ lastToken.setUncle(uncle);
+ } else super.setUncle(uncle); // to deal with empty subexpressions
+ }
+
+ // Overrides REToken.chain
+
+ boolean chain(REToken next) {
+ super.chain(next);
+ setUncle(next);
+ return true;
+ }
+
+ /**
+ * Returns the minimum number of characters that could possibly
+ * constitute a match of this regular expression.
+ */
+ public int getMinimumLength() {
+ return minimumLength;
+ }
+
+ /**
+ * Returns an array of all matches found in the input.
+ *
+ * If the regular expression allows the empty string to match, it will
+ * substitute matches at all positions except the end of the input.
+ *
+ * @param input The input text.
+ * @return a non-null (but possibly zero-length) array of matches
+ */
+ public REMatch[] getAllMatches(Object input) {
+ return getAllMatches(input,0,0);
+ }
+
+ /**
+ * Returns an array of all matches found in the input,
+ * beginning at the specified index position.
+ *
+ * If the regular expression allows the empty string to match, it will
+ * substitute matches at all positions except the end of the input.
+ *
+ * @param input The input text.
+ * @param index The offset index at which the search should be begin.
+ * @return a non-null (but possibly zero-length) array of matches
+ */
+ public REMatch[] getAllMatches(Object input, int index) {
+ return getAllMatches(input,index,0);
+ }
+
+ /**
+ * Returns an array of all matches found in the input string,
+ * beginning at the specified index position and using the specified
+ * execution flags.
+ *
+ * If the regular expression allows the empty string to match, it will
+ * substitute matches at all positions except the end of the input.
+ *
+ * @param input The input text.
+ * @param index The offset index at which the search should be begin.
+ * @param eflags The logical OR of any execution flags above.
+ * @return a non-null (but possibly zero-length) array of matches
+ */
+ public REMatch[] getAllMatches(Object input, int index, int eflags) {
+ return getAllMatchesImpl(makeCharIndexed(input,index),index,eflags);
+ }
+
+ // this has been changed since 1.03 to be non-overlapping matches
+ private REMatch[] getAllMatchesImpl(CharIndexed input, int index, int eflags) {
+ Vector all = new Vector();
+ REMatch m = null;
+ while ((m = getMatchImpl(input,index,eflags,null)) != null) {
+ all.addElement(m);
+ index = m.getEndIndex();
+ if (m.end[0] == 0) { // handle pathological case of zero-length match
+ index++;
+ input.move(1);
+ } else {
+ input.move(m.end[0]);
+ }
+ if (!input.isValid()) break;
+ }
+ REMatch[] mset = new REMatch[all.size()];
+ all.copyInto(mset);
+ return mset;
+ }
+
+ /* Implements abstract method REToken.match() */
+ boolean match(CharIndexed input, REMatch mymatch) {
+ if (firstToken == null) return next(input, mymatch);
+
+ // Note the start of this subexpression
+ mymatch.start[subIndex] = mymatch.index;
+
+ return firstToken.match(input, mymatch);
+ }
+
+ /**
+ * Returns the first match found in the input. If no match is found,
+ * null is returned.
+ *
+ * @param input The input text.
+ * @return An REMatch instance referencing the match, or null if none.
+ */
+ public REMatch getMatch(Object input) {
+ return getMatch(input,0,0);
+ }
+
+ /**
+ * Returns the first match found in the input, beginning
+ * the search at the specified index. If no match is found,
+ * returns null.
+ *
+ * @param input The input text.
+ * @param index The offset within the text to begin looking for a match.
+ * @return An REMatch instance referencing the match, or null if none.
+ */
+ public REMatch getMatch(Object input, int index) {
+ return getMatch(input,index,0);
+ }
+
+ /**
+ * Returns the first match found in the input, beginning
+ * the search at the specified index, and using the specified
+ * execution flags. If no match is found, returns null.
+ *
+ * @param input The input text.
+ * @param index The offset index at which the search should be begin.
+ * @param eflags The logical OR of any execution flags above.
+ * @return An REMatch instance referencing the match, or null if none.
+ */
+ public REMatch getMatch(Object input, int index, int eflags) {
+ return getMatch(input,index,eflags,null);
+ }
+
+ /**
+ * Returns the first match found in the input, beginning the search
+ * at the specified index, and using the specified execution flags.
+ * If no match is found, returns null. If a StringBuffer is
+ * provided and is non-null, the contents of the input text from the
+ * index to the beginning of the match (or to the end of the input,
+ * if there is no match) are appended to the StringBuffer.
+ *
+ * @param input The input text.
+ * @param index The offset index at which the search should be begin.
+ * @param eflags The logical OR of any execution flags above.
+ * @param buffer The StringBuffer to save pre-match text in.
+ * @return An REMatch instance referencing the match, or null if none. */
+ public REMatch getMatch(Object input, int index, int eflags, StringBuffer buffer) {
+ return getMatchImpl(makeCharIndexed(input,index),index,eflags,buffer);
+ }
+
+ REMatch getMatchImpl(CharIndexed input, int anchor, int eflags, StringBuffer buffer) {
+ // Create a new REMatch to hold results
+ REMatch mymatch = new REMatch(numSubs, anchor, eflags);
+ do {
+ // Optimization: check if anchor + minimumLength > length
+ if (minimumLength == 0 || input.charAt(minimumLength-1) != CharIndexed.OUT_OF_BOUNDS) {
+ if (match(input, mymatch)) {
+ // Find longest match of them all to observe leftmost longest
+ REMatch longest = mymatch;
+ while ((mymatch = mymatch.next) != null) {
+ if (mymatch.index > longest.index) {
+ longest = mymatch;
+ }
+ }
+
+ longest.end[0] = longest.index;
+ longest.finish(input);
+ return longest;
+ }
+ }
+ mymatch.clear(++anchor);
+ // Append character to buffer if needed
+ if (buffer != null && input.charAt(0) != CharIndexed.OUT_OF_BOUNDS) {
+ buffer.append(input.charAt(0));
+ }
+ } while (input.move(1));
+
+ return null;
+ }
+
+ /**
+ * Returns an REMatchEnumeration that can be used to iterate over the
+ * matches found in the input text.
+ *
+ * @param input The input text.
+ * @return A non-null REMatchEnumeration instance.
+ */
+ public REMatchEnumeration getMatchEnumeration(Object input) {
+ return getMatchEnumeration(input,0,0);
+ }
+
+
+ /**
+ * Returns an REMatchEnumeration that can be used to iterate over the
+ * matches found in the input text.
+ *
+ * @param input The input text.
+ * @param index The offset index at which the search should be begin.
+ * @return A non-null REMatchEnumeration instance, with its input cursor
+ * set to the index position specified.
+ */
+ public REMatchEnumeration getMatchEnumeration(Object input, int index) {
+ return getMatchEnumeration(input,index,0);
+ }
+
+ /**
+ * Returns an REMatchEnumeration that can be used to iterate over the
+ * matches found in the input text.
+ *
+ * @param input The input text.
+ * @param index The offset index at which the search should be begin.
+ * @param eflags The logical OR of any execution flags above.
+ * @return A non-null REMatchEnumeration instance, with its input cursor
+ * set to the index position specified.
+ */
+ public REMatchEnumeration getMatchEnumeration(Object input, int index, int eflags) {
+ return new REMatchEnumeration(this,makeCharIndexed(input,index),index,eflags);
+ }
+
+
+ /**
+ * Substitutes the replacement text for the first match found in the input.
+ *
+ * @param input The input text.
+ * @param replace The replacement text, which may contain $x metacharacters (see REMatch.substituteInto).
+ * @return A String interpolating the substituted text.
+ * @see REMatch#substituteInto
+ */
+ public String substitute(Object input,String replace) {
+ return substitute(input,replace,0,0);
+ }
+
+ /**
+ * Substitutes the replacement text for the first match found in the input
+ * beginning at the specified index position. Specifying an index
+ * effectively causes the regular expression engine to throw away the
+ * specified number of characters.
+ *
+ * @param input The input text.
+ * @param replace The replacement text, which may contain $x metacharacters (see REMatch.substituteInto).
+ * @param index The offset index at which the search should be begin.
+ * @return A String containing the substring of the input, starting
+ * at the index position, and interpolating the substituted text.
+ * @see REMatch#substituteInto
+ */
+ public String substitute(Object input,String replace,int index) {
+ return substitute(input,replace,index,0);
+ }
+
+ /**
+ * Substitutes the replacement text for the first match found in the input
+ * string, beginning at the specified index position and using the
+ * specified execution flags.
+ *
+ * @param input The input text.
+ * @param replace The replacement text, which may contain $x metacharacters (see REMatch.substituteInto).
+ * @param index The offset index at which the search should be begin.
+ * @param eflags The logical OR of any execution flags above.
+ * @return A String containing the substring of the input, starting
+ * at the index position, and interpolating the substituted text.
+ * @see REMatch#substituteInto
+ */
+ public String substitute(Object input,String replace,int index,int eflags) {
+ return substituteImpl(makeCharIndexed(input,index),replace,index,eflags);
+ }
+
+ private String substituteImpl(CharIndexed input,String replace,int index,int eflags) {
+ StringBuffer buffer = new StringBuffer();
+ REMatch m = getMatchImpl(input,index,eflags,buffer);
+ if (m==null) return buffer.toString();
+ buffer.append( ((eflags & REG_NO_INTERPOLATE) > 0) ?
+ replace : m.substituteInto(replace) );
+ if (input.move(m.end[0])) {
+ do {
+ buffer.append(input.charAt(0));
+ } while (input.move(1));
+ }
+ return buffer.toString();
+ }
+
+ /**
+ * Substitutes the replacement text for each non-overlapping match found
+ * in the input text.
+ *
+ * @param input The input text.
+ * @param replace The replacement text, which may contain $x metacharacters (see REMatch.substituteInto).
+ * @return A String interpolating the substituted text.
+ * @see REMatch#substituteInto
+ */
+ public String substituteAll(Object input,String replace) {
+ return substituteAll(input,replace,0,0);
+ }
+
+ /**
+ * Substitutes the replacement text for each non-overlapping match found
+ * in the input text, starting at the specified index.
+ *
+ * If the regular expression allows the empty string to match, it will
+ * substitute matches at all positions except the end of the input.
+ *
+ * @param input The input text.
+ * @param replace The replacement text, which may contain $x metacharacters (see REMatch.substituteInto).
+ * @param index The offset index at which the search should be begin.
+ * @return A String containing the substring of the input, starting
+ * at the index position, and interpolating the substituted text.
+ * @see REMatch#substituteInto
+ */
+ public String substituteAll(Object input,String replace,int index) {
+ return substituteAll(input,replace,index,0);
+ }
+
+ /**
+ * Substitutes the replacement text for each non-overlapping match found
+ * in the input text, starting at the specified index and using the
+ * specified execution flags.
+ *
+ * @param input The input text.
+ * @param replace The replacement text, which may contain $x metacharacters (see REMatch.substituteInto).
+ * @param index The offset index at which the search should be begin.
+ * @param eflags The logical OR of any execution flags above.
+ * @return A String containing the substring of the input, starting
+ * at the index position, and interpolating the substituted text.
+ * @see REMatch#substituteInto
+ */
+ public String substituteAll(Object input,String replace,int index,int eflags) {
+ return substituteAllImpl(makeCharIndexed(input,index),replace,index,eflags);
+ }
+
+ private String substituteAllImpl(CharIndexed input,String replace,int index,int eflags) {
+ StringBuffer buffer = new StringBuffer();
+ REMatch m;
+ while ((m = getMatchImpl(input,index,eflags,buffer)) != null) {
+ buffer.append( ((eflags & REG_NO_INTERPOLATE) > 0) ?
+ replace : m.substituteInto(replace) );
+ index = m.getEndIndex();
+ if (m.end[0] == 0) {
+ char ch = input.charAt(0);
+ if (ch != CharIndexed.OUT_OF_BOUNDS)
+ buffer.append(ch);
+ input.move(1);
+ } else {
+ input.move(m.end[0]);
+ }
+
+ if (!input.isValid()) break;
+ }
+ return buffer.toString();
+ }
+
+ /* Helper function for constructor */
+ private void addToken(REToken next) {
+ if (next == null) return;
+ minimumLength += next.getMinimumLength();
+ if (firstToken == null) {
+ lastToken = firstToken = next;
+ } else {
+ // if chain returns false, it "rejected" the token due to
+ // an optimization, and next was combined with lastToken
+ if (lastToken.chain(next)) {
+ lastToken = next;
+ }
+ }
+ }
+
+ private static REToken setRepeated(REToken current, int min, int max, int index) throws REException {
+ if (current == null) throw new REException(getLocalizedMessage("repeat.no.token"),REException.REG_BADRPT,index);
+ return new RETokenRepeated(current.subIndex,current,min,max);
+ }
+
+ private static int getPosixSet(char[] pattern,int index,StringBuffer buf) {
+ // Precondition: pattern[index-1] == ':'
+ // we will return pos of closing ']'.
+ int i;
+ for (i=index; i<(pattern.length-1); i++) {
+ if ((pattern[i] == ':') && (pattern[i+1] == ']'))
+ return i+2;
+ buf.append(pattern[i]);
+ }
+ return index; // didn't match up
+ }
+
+ private int getMinMax(char[] input,int index,IntPair minMax,RESyntax syntax) throws REException {
+ // Precondition: input[index-1] == '{', minMax != null
+
+ boolean mustMatch = !syntax.get(RESyntax.RE_NO_BK_BRACES);
+ int startIndex = index;
+ if (index == input.length) {
+ if (mustMatch)
+ throw new REException(getLocalizedMessage("unmatched.brace"),REException.REG_EBRACE,index);
+ else
+ return startIndex;
+ }
+
+ int min,max=0;
+ CharUnit unit = new CharUnit();
+ StringBuffer buf = new StringBuffer();
+
+ // Read string of digits
+ do {
+ index = getCharUnit(input,index,unit);
+ if (Character.isDigit(unit.ch))
+ buf.append(unit.ch);
+ } while ((index != input.length) && Character.isDigit(unit.ch));
+
+ // Check for {} tomfoolery
+ if (buf.length() == 0) {
+ if (mustMatch)
+ throw new REException(getLocalizedMessage("interval.error"),REException.REG_EBRACE,index);
+ else
+ return startIndex;
+ }
+
+ min = Integer.parseInt(buf.toString());
+
+ if ((unit.ch == '}') && (syntax.get(RESyntax.RE_NO_BK_BRACES) ^ unit.bk))
+ max = min;
+ else if (index == input.length)
+ if (mustMatch)
+ throw new REException(getLocalizedMessage("interval.no.end"),REException.REG_EBRACE,index);
+ else
+ return startIndex;
+ else if ((unit.ch == ',') && !unit.bk) {
+ buf = new StringBuffer();
+ // Read string of digits
+ while (((index = getCharUnit(input,index,unit)) != input.length) && Character.isDigit(unit.ch))
+ buf.append(unit.ch);
+
+ if (!((unit.ch == '}') && (syntax.get(RESyntax.RE_NO_BK_BRACES) ^ unit.bk)))
+ if (mustMatch)
+ throw new REException(getLocalizedMessage("interval.error"),REException.REG_EBRACE,index);
+ else
+ return startIndex;
+
+ // This is the case of {x,}
+ if (buf.length() == 0) max = Integer.MAX_VALUE;
+ else max = Integer.parseInt(buf.toString());
+ } else
+ if (mustMatch)
+ throw new REException(getLocalizedMessage("interval.error"),REException.REG_EBRACE,index);
+ else
+ return startIndex;
+
+ // We know min and max now, and they are valid.
+
+ minMax.first = min;
+ minMax.second = max;
+
+ // return the index following the '}'
+ return index;
+ }
+
+ /**
+ * Return a human readable form of the compiled regular expression,
+ * useful for debugging.
+ */
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ dump(sb);
+ return sb.toString();
+ }
+
+ void dump(StringBuffer os) {
+ os.append('(');
+ if (subIndex == 0)
+ os.append("?:");
+ if (firstToken != null)
+ firstToken.dumpAll(os);
+ os.append(')');
+ }
+
+ // Cast input appropriately or throw exception
+ private static CharIndexed makeCharIndexed(Object input, int index) {
+ // We could let a String fall through to final input, but since
+ // it's the most likely input type, we check it first.
+ if (input instanceof String)
+ return new CharIndexedString((String) input,index);
+ else if (input instanceof char[])
+ return new CharIndexedCharArray((char[]) input,index);
+ else if (input instanceof StringBuffer)
+ return new CharIndexedStringBuffer((StringBuffer) input,index);
+ else if (input instanceof InputStream)
+ return new CharIndexedInputStream((InputStream) input,index);
+ else if (input instanceof Reader)
+ return new CharIndexedReader((Reader) input, index);
+ else if (input instanceof CharIndexed)
+ return (CharIndexed) input; // do we lose index info?
+ else
+ return new CharIndexedString(input.toString(), index);
+ }
+}
--- /dev/null
+/*
+ * gnu/regexp/REException.java
+ * Copyright (C) 1998-2001 Wes Biggs
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package gnu.regexp;
+
+import java.text.MessageFormat;
+
+/**
+ * This is the regular expression exception class. An exception of this type
+ * defines the three attributes:
+ * <OL>
+ * <LI> A descriptive message of the error.
+ * <LI> An integral type code equivalent to one of the statically
+ * defined symbols listed below.
+ * <LI> The approximate position in the input string where the error
+ * occurred.
+ * </OL>
+ *
+ * @author <A HREF="mailto:wes@cacas.org">Wes Biggs</A>
+ */
+
+public class REException extends Exception {
+ private int type;
+ private int pos;
+
+ // Error conditions from GNU regcomp(3) manual
+
+ /**
+ * Error flag.
+ * Invalid use of repetition operators such as using
+ * `*' as the first character.
+ */
+ public static final int REG_BADRPT = 1;
+
+ /**
+ * Error flag.
+ * Invalid use of back reference operator.
+ */
+ public static final int REG_BADBR = 2;
+
+ /**
+ * Error flag.
+ * Un-matched brace interval operators.
+ */
+ public static final int REG_EBRACE = 3;
+
+ /**
+ * Error flag.
+ * Un-matched bracket list operators.
+ */
+ public static final int REG_EBRACK = 4;
+
+ /**
+ * Error flag.
+ * Invalid use of the range operator, eg. the ending
+ * point of the range occurs prior to the starting
+ * point.
+ */
+ public static final int REG_ERANGE = 5;
+
+ /**
+ * Error flag.
+ * Unknown character class name. <B>Not implemented</B>.
+ */
+ public static final int REG_ECTYPE = 6;
+
+ /**
+ * Error flag.
+ * Un-matched parenthesis group operators.
+ */
+ public static final int REG_EPAREN = 7;
+
+ /**
+ * Error flag.
+ * Invalid back reference to a subexpression.
+ */
+ public static final int REG_ESUBREG = 8;
+
+ /**
+ * Error flag.
+ * Non specific error. <B>Not implemented</B>.
+ */
+ public static final int REG_EEND = 9;
+
+ /**
+ * Error flag.
+ * Invalid escape sequence. <B>Not implemented</B>.
+ */
+ public static final int REG_ESCAPE = 10;
+
+ /**
+ * Error flag.
+ * Invalid use of pattern operators such as group or list.
+ */
+ public static final int REG_BADPAT = 11;
+
+ /**
+ * Error flag.
+ * Compiled regular expression requires a pattern
+ * buffer larger than 64Kb. <B>Not implemented</B>.
+ */
+ public static final int REG_ESIZE = 12;
+
+ /**
+ * Error flag.
+ * The regex routines ran out of memory. <B>Not implemented</B>.
+ */
+ public static final int REG_ESPACE = 13;
+
+ REException(String msg, int type, int position) {
+ super(msg);
+ this.type = type;
+ this.pos = position;
+ }
+
+ /**
+ * Returns the type of the exception, one of the constants listed above.
+ */
+
+ public int getType() {
+ return type;
+ }
+
+ /**
+ * Returns the position, relative to the string or character array being
+ * compiled, where the error occurred. This position is generally the point
+ * where the error was detected, not necessarily the starting index of
+ * a bad subexpression.
+ */
+ public int getPosition() {
+ return pos;
+ }
+
+ /**
+ * Reports the descriptive message associated with this exception
+ * as well as its index position in the string or character array
+ * being compiled.
+ */
+ public String getMessage() {
+ Object[] args = {new Integer(pos)};
+ StringBuffer sb = new StringBuffer();
+ String prefix = RE.getLocalizedMessage("error.prefix");
+ sb.append(MessageFormat.format(prefix, args));
+ sb.append('\n');
+ sb.append(super.getMessage());
+ return sb.toString();
+ }
+}
--- /dev/null
+/*
+ * gnu/regexp/REFilterInputStream.java
+ * Copyright (C) 1998-2001 Wes Biggs
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package gnu.regexp;
+import java.io.FilterInputStream;
+import java.io.InputStream;
+
+/**
+ * Replaces instances of a given RE found within an InputStream
+ * with replacement text. The replacements are interpolated into the
+ * stream when a match is found.
+ *
+ * @author <A HREF="mailto:wes@cacas.org">Wes Biggs</A>
+ * @deprecated This class cannot properly handle all character
+ * encodings. For proper handling, use the REFilterReader
+ * class instead.
+ */
+
+public class REFilterInputStream extends FilterInputStream {
+
+ private RE expr;
+ private String replace;
+ private String buffer;
+ private int bufpos;
+ private int offset;
+ private CharIndexedInputStream stream;
+
+ /**
+ * Creates an REFilterInputStream. When reading from this stream,
+ * occurrences of patterns matching the supplied regular expression
+ * will be replaced with the supplied replacement text (the
+ * metacharacters $0 through $9 may be used to refer to the full
+ * match or subexpression matches).
+ *
+ * @param stream The InputStream to be filtered.
+ * @param expr The regular expression to search for.
+ * @param replace The text pattern to replace matches with.
+ */
+ public REFilterInputStream(InputStream stream, RE expr, String replace) {
+ super(stream);
+ this.stream = new CharIndexedInputStream(stream,0);
+ this.expr = expr;
+ this.replace = replace;
+ }
+
+ /**
+ * Reads the next byte from the stream per the general contract of
+ * InputStream.read(). Returns -1 on error or end of stream.
+ */
+ public int read() {
+ // If we have buffered replace data, use it.
+ if ((buffer != null) && (bufpos < buffer.length())) {
+ return (int) buffer.charAt(bufpos++);
+ }
+
+ // check if input is at a valid position
+ if (!stream.isValid()) return -1;
+
+ REMatch mymatch = new REMatch(expr.getNumSubs(),offset,0);
+ if (expr.match(stream, mymatch)) {
+ mymatch.end[0] = mymatch.index;
+ mymatch.finish(stream);
+ stream.move(mymatch.toString().length());
+ offset += mymatch.toString().length();
+ buffer = mymatch.substituteInto(replace);
+ bufpos = 1;
+
+ // This is prone to infinite loops if replace string turns out empty.
+ if (buffer.length() > 0) {
+ return buffer.charAt(0);
+ }
+ }
+ char ch = stream.charAt(0);
+ if (ch == CharIndexed.OUT_OF_BOUNDS) return -1;
+ stream.move(1);
+ offset++;
+ return ch;
+ }
+
+ /**
+ * Returns false. REFilterInputStream does not support mark() and
+ * reset() methods.
+ */
+ public boolean markSupported() {
+ return false;
+ }
+
+ /** Reads from the stream into the provided array. */
+ public int read(byte[] b, int off, int len) {
+ int i;
+ int ok = 0;
+ while (len-- > 0) {
+ i = read();
+ if (i == -1) return (ok == 0) ? -1 : ok;
+ b[off++] = (byte) i;
+ ok++;
+ }
+ return ok;
+ }
+
+ /** Reads from the stream into the provided array. */
+ public int read(byte[] b) {
+ return read(b,0,b.length);
+ }
+}
--- /dev/null
+/*
+ * gnu/regexp/REFilterReader.java
+ * Copyright (C) 2001 Lee Sau Dan
+ * Based on gnu.regexp.REFilterInputStream by Wes Biggs
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package gnu.regexp;
+import java.io.FilterReader;
+import java.io.Reader;
+
+/**
+ * Replaces instances of a given RE with replacement text.
+ *
+ * @author <A HREF="http://www.csis.hku.hk/~sdlee/">Lee Sau Dan</A>
+ * @since gnu.regexp 1.1.0
+ */
+
+public class REFilterReader extends FilterReader {
+
+ private RE expr;
+ private String replace;
+ private String buffer;
+ private int bufpos;
+ private int offset;
+ private CharIndexedReader stream;
+
+ /**
+ * Creates an REFilterReader. When reading from this stream,
+ * occurrences of patterns matching the supplied regular expression
+ * will be replaced with the supplied replacement text (the
+ * metacharacters $0 through $9 may be used to refer to the full
+ * match or subexpression matches.
+ *
+ * @param stream The Reader to be filtered.
+ * @param expr The regular expression to search for.
+ * @param replace The text pattern to replace matches with.
+ */
+ public REFilterReader(Reader stream, RE expr, String replace) {
+ super(stream);
+ this.stream = new CharIndexedReader(stream,0);
+ this.expr = expr;
+ this.replace = replace;
+ }
+
+ /**
+ * Reads the next character from the stream per the general contract of
+ * Reader.read(). Returns -1 on error or end of stream.
+ */
+ public int read() {
+ // If we have buffered replace data, use it.
+ if ((buffer != null) && (bufpos < buffer.length())) {
+ return (int) buffer.charAt(bufpos++);
+ }
+
+ // check if input is at a valid position
+ if (!stream.isValid()) return -1;
+
+ REMatch mymatch = new REMatch(expr.getNumSubs(),offset,0);
+ if (expr.match(stream,mymatch)) {
+ mymatch.end[0] = mymatch.index;
+ mymatch.finish(stream);
+ stream.move(mymatch.toString().length());
+ offset += mymatch.toString().length();
+ buffer = mymatch.substituteInto(replace);
+ bufpos = 1;
+
+ if (buffer.length() > 0) {
+ return buffer.charAt(0);
+ }
+ }
+ char ch = stream.charAt(0);
+ if (ch == CharIndexed.OUT_OF_BOUNDS) return -1;
+ stream.move(1);
+ offset++;
+ return ch;
+ }
+
+ /**
+ * Returns false. REFilterReader does not support mark() and
+ * reset() methods.
+ */
+ public boolean markSupported() {
+ return false;
+ }
+
+ /** Reads from the stream into the provided array. */
+ public int read(char[] b, int off, int len) {
+ int i;
+ int ok = 0;
+ while (len-- > 0) {
+ i = read();
+ if (i == -1) return (ok == 0) ? -1 : ok;
+ b[off++] = (char) i;
+ ok++;
+ }
+ return ok;
+ }
+
+ /** Reads from the stream into the provided array. */
+ public int read(char[] b) {
+ return read(b,0,b.length);
+ }
+}
--- /dev/null
+/*
+ * gnu/regexp/REMatch.java
+ * Copyright (C) 1998-2001 Wes Biggs
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package gnu.regexp;
+import java.io.Serializable;
+
+/**
+ * An instance of this class represents a match
+ * completed by a gnu.regexp matching function. It can be used
+ * to obtain relevant information about the location of a match
+ * or submatch.
+ *
+ * @author <A HREF="mailto:wes@cacas.org">Wes Biggs</A>
+ */
+public final class REMatch implements Serializable, Cloneable {
+ private String matchedText;
+
+ // These variables are package scope for fast access within the engine
+ int eflags; // execution flags this match was made using
+
+ // Offset in source text where match was tried. This is zero-based;
+ // the actual position in the source text is given by (offset + anchor).
+ int offset;
+
+ // Anchor position refers to the index into the source input
+ // at which the matching operation began.
+ // This is also useful for the ANCHORINDEX option.
+ int anchor;
+
+ // Package scope; used by RE.
+ int index; // used while matching to mark current match position in input
+ int[] start; // start positions (relative to offset) for each (sub)exp.
+ int[] end; // end positions for the same
+ REMatch next; // other possibility (to avoid having to use arrays)
+
+ public Object clone() {
+ try {
+ REMatch copy = (REMatch) super.clone();
+ copy.next = null;
+
+ copy.start = (int[]) start.clone();
+ copy.end = (int[]) end.clone();
+
+ return copy;
+ } catch (CloneNotSupportedException e) {
+ throw new Error(); // doesn't happen
+ }
+ }
+
+ void assignFrom(REMatch other) {
+ start = other.start;
+ end = other.end;
+ index = other.index;
+ // need to deep clone?
+ next = other.next;
+ }
+
+ REMatch(int subs, int anchor, int eflags) {
+ start = new int[subs+1];
+ end = new int[subs+1];
+ this.anchor = anchor;
+ this.eflags = eflags;
+ clear(anchor);
+ }
+
+ void finish(CharIndexed text) {
+ start[0] = 0;
+ StringBuffer sb = new StringBuffer();
+ int i;
+ for (i = 0; i < end[0]; i++)
+ sb.append(text.charAt(i));
+ matchedText = sb.toString();
+ for (i = 0; i < start.length; i++) {
+ // If any subexpressions didn't terminate, they don't count
+ // TODO check if this code ever gets hit
+ if ((start[i] == -1) ^ (end[i] == -1)) {
+ start[i] = -1;
+ end[i] = -1;
+ }
+ }
+ next = null; // cut off alternates
+ }
+
+ /** Clears the current match and moves the offset to the new index. */
+ void clear(int index) {
+ offset = index;
+ this.index = 0;
+ for (int i = 0; i < start.length; i++) {
+ start[i] = end[i] = -1;
+ }
+ next = null; // cut off alternates
+ }
+
+ /**
+ * Returns the string matching the pattern. This makes it convenient
+ * to write code like the following:
+ * <P>
+ * <code>
+ * REMatch myMatch = myExpression.getMatch(myString);<br>
+ * if (myMatch != null) System.out.println("Regexp found: "+myMatch);
+ * </code>
+ */
+ public String toString() {
+ return matchedText;
+ }
+
+ /**
+ * Returns the index within the input text where the match in its entirety
+ * began.
+ */
+ public int getStartIndex() {
+ return offset + start[0];
+ }
+
+ /**
+ * Returns the index within the input string where the match in
+ * its entirety ends. The return value is the next position after
+ * the end of the string; therefore, a match created by the
+ * following call:
+ *
+ * <P>
+ * <code>REMatch myMatch = myExpression.getMatch(myString);</code>
+ * <P>
+ * can be viewed (given that myMatch is not null) by creating
+ * <P>
+ * <code>String theMatch = myString.substring(myMatch.getStartIndex(),
+ * myMatch.getEndIndex());</code>
+ * <P>
+ * But you can save yourself that work, since the <code>toString()</code>
+ * method (above) does exactly that for you.
+ */
+ public int getEndIndex() {
+ return offset + end[0];
+ }
+
+ /**
+ * Returns the string matching the given subexpression. The subexpressions
+ * are indexed starting with one, not zero. That is, the subexpression
+ * identified by the first set of parentheses in a regular expression
+ * could be retrieved from an REMatch by calling match.toString(1).
+ *
+ * @param sub Index of the subexpression.
+ */
+ public String toString(int sub) {
+ if ((sub >= start.length) || (start[sub] == -1)) return "";
+ return (matchedText.substring(start[sub],end[sub]));
+ }
+
+ /**
+ * Returns the index within the input string used to generate this match
+ * where subexpression number <i>sub</i> begins, or <code>-1</code> if
+ * the subexpression does not exist. The initial position is zero.
+ *
+ * @param sub Subexpression index
+ * @deprecated Use getStartIndex(int) instead.
+ */
+ public int getSubStartIndex(int sub) {
+ if (sub >= start.length) return -1;
+ int x = start[sub];
+ return (x == -1) ? x : offset + x;
+ }
+
+ /**
+ * Returns the index within the input string used to generate this match
+ * where subexpression number <i>sub</i> begins, or <code>-1</code> if
+ * the subexpression does not exist. The initial position is zero.
+ *
+ * @param sub Subexpression index
+ * @since gnu.regexp 1.1.0
+ */
+ public int getStartIndex(int sub) {
+ if (sub >= start.length) return -1;
+ int x = start[sub];
+ return (x == -1) ? x : offset + x;
+ }
+
+ /**
+ * Returns the index within the input string used to generate this match
+ * where subexpression number <i>sub</i> ends, or <code>-1</code> if
+ * the subexpression does not exist. The initial position is zero.
+ *
+ * @param sub Subexpression index
+ * @deprecated Use getEndIndex(int) instead
+ */
+ public int getSubEndIndex(int sub) {
+ if (sub >= start.length) return -1;
+ int x = end[sub];
+ return (x == -1) ? x : offset + x;
+ }
+
+ /**
+ * Returns the index within the input string used to generate this match
+ * where subexpression number <i>sub</i> ends, or <code>-1</code> if
+ * the subexpression does not exist. The initial position is zero.
+ *
+ * @param sub Subexpression index
+ */
+ public int getEndIndex(int sub) {
+ if (sub >= start.length) return -1;
+ int x = end[sub];
+ return (x == -1) ? x : offset + x;
+ }
+
+ /**
+ * Substitute the results of this match to create a new string.
+ * This is patterned after PERL, so the tokens to watch out for are
+ * <code>$0</code> through <code>$9</code>. <code>$0</code> matches
+ * the full substring matched; <code>$<i>n</i></code> matches
+ * subexpression number <i>n</i>.
+ *
+ * @param input A string consisting of literals and <code>$<i>n</i></code> tokens.
+ */
+ public String substituteInto(String input) {
+ // a la Perl, $0 is whole thing, $1 - $9 are subexpressions
+ StringBuffer output = new StringBuffer();
+ int pos;
+ for (pos = 0; pos < input.length()-1; pos++) {
+ if ((input.charAt(pos) == '$') && (Character.isDigit(input.charAt(pos+1)))) {
+ int val = Character.digit(input.charAt(++pos),10);
+ if (val < start.length) {
+ output.append(toString(val));
+ }
+ } else output.append(input.charAt(pos));
+ }
+ if (pos < input.length()) output.append(input.charAt(pos));
+ return output.toString();
+ }
+}
--- /dev/null
+/*
+ * gnu/regexp/REMatchEnumeration.java
+ * Copyright (C) 1998-2001 Wes Biggs
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package gnu.regexp;
+import java.io.Serializable;
+import java.util.Enumeration;
+import java.util.NoSuchElementException;
+
+/**
+ * An REMatchEnumeration enumerates regular expression matches over a
+ * given input text. You obtain a reference to an enumeration using
+ * the <code>getMatchEnumeration()</code> methods on an instance of
+ * RE.
+ *
+ * <P>
+ *
+ * REMatchEnumeration does lazy computation; that is, it will not
+ * search for a match until it needs to. If you'd rather just get all
+ * the matches at once in a big array, use the
+ * <code>getAllMatches()</code> methods on RE. However, using an
+ * enumeration can help speed performance when the entire text does
+ * not need to be searched immediately.
+ *
+ * <P>
+ *
+ * The enumerated type is especially useful when searching on a Reader
+ * or InputStream, because the InputStream read position cannot be
+ * guaranteed after calling <code>getMatch()</code> (see the
+ * description of that method for an explanation of why). Enumeration
+ * also saves a lot of overhead required when calling
+ * <code>getMatch()</code> multiple times.
+ *
+ * @author <A HREF="mailto:wes@cacas.org">Wes Biggs</A>
+ */
+public class REMatchEnumeration implements Enumeration, Serializable {
+ private static final int YES = 1;
+ private static final int MAYBE = 0;
+ private static final int NO = -1;
+
+ private int more;
+ private REMatch match;
+ private RE expr;
+ private CharIndexed input;
+ private int eflags;
+ private int index;
+
+ // Package scope constructor is used by RE.getMatchEnumeration()
+ REMatchEnumeration(RE expr, CharIndexed input, int index, int eflags) {
+ more = MAYBE;
+ this.expr = expr;
+ this.input = input;
+ this.index = index;
+ this.eflags = eflags;
+ }
+
+ /** Returns true if there are more matches in the input text. */
+ public boolean hasMoreElements() {
+ return hasMoreMatches(null);
+ }
+
+ /** Returns true if there are more matches in the input text. */
+ public boolean hasMoreMatches() {
+ return hasMoreMatches(null);
+ }
+
+ /** Returns true if there are more matches in the input text.
+ * Saves the text leading up to the match (or to the end of the input)
+ * in the specified buffer.
+ */
+ public boolean hasMoreMatches(StringBuffer buffer) {
+ if (more == MAYBE) {
+ match = expr.getMatchImpl(input,index,eflags,buffer);
+ if (match != null) {
+ input.move((match.end[0] > 0) ? match.end[0] : 1);
+
+ index = (match.end[0] > 0) ? match.end[0] + match.offset : index + 1;
+ more = YES;
+ } else more = NO;
+ }
+ return (more == YES);
+ }
+
+ /** Returns the next match in the input text. */
+ public Object nextElement() throws NoSuchElementException {
+ return nextMatch();
+ }
+
+ /**
+ * Returns the next match in the input text. This method is provided
+ * for convenience to avoid having to explicitly cast the return value
+ * to class REMatch.
+ */
+ public REMatch nextMatch() throws NoSuchElementException {
+ if (hasMoreElements()) {
+ more = (input.isValid()) ? MAYBE : NO;
+ return match;
+ }
+ throw new NoSuchElementException();
+ }
+}
+
--- /dev/null
+/*
+ * gnu/regexp/RESyntax.java
+ * Copyright (C) 1998-2001 Wes Biggs
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package gnu.regexp;
+import java.io.Serializable;
+import java.util.BitSet;
+
+/**
+ * An RESyntax specifies the way a regular expression will be compiled.
+ * This class provides a number of predefined useful constants for
+ * emulating popular regular expression syntaxes. Additionally the
+ * user may construct his or her own syntax, using any combination of the
+ * syntax bit constants. The syntax is an optional argument to any of the
+ * matching methods on class RE.
+ *
+ * @author <A HREF="mailto:wes@cacas.org">Wes Biggs</A>
+ */
+
+public final class RESyntax implements Serializable {
+ static final String DEFAULT_LINE_SEPARATOR = System.getProperty("line.separator");
+
+ private static final String SYNTAX_IS_FINAL = RE.getLocalizedMessage("syntax.final");
+
+ private BitSet bits;
+
+ // true for the constant defined syntaxes
+ private boolean isFinal = false;
+
+ private String lineSeparator = DEFAULT_LINE_SEPARATOR;
+
+ // Values for constants are bit indexes
+
+ /**
+ * Syntax bit. Backslash is an escape character in lists.
+ */
+ public static final int RE_BACKSLASH_ESCAPE_IN_LISTS = 0;
+
+ /**
+ * Syntax bit. Use \? instead of ? and \+ instead of +.
+ */
+ public static final int RE_BK_PLUS_QM = 1;
+
+ /**
+ * Syntax bit. POSIX character classes ([:...:]) in lists are allowed.
+ */
+ public static final int RE_CHAR_CLASSES = 2;
+
+ /**
+ * Syntax bit. ^ and $ are special everywhere.
+ * <B>Not implemented.</B>
+ */
+ public static final int RE_CONTEXT_INDEP_ANCHORS = 3;
+
+ /**
+ * Syntax bit. Repetition operators are only special in valid positions.
+ * <B>Not implemented.</B>
+ */
+ public static final int RE_CONTEXT_INDEP_OPS = 4;
+
+ /**
+ * Syntax bit. Repetition and alternation operators are invalid
+ * at start and end of pattern and other places.
+ * <B>Not implemented</B>.
+ */
+ public static final int RE_CONTEXT_INVALID_OPS = 5;
+
+ /**
+ * Syntax bit. Match-any-character operator (.) matches a newline.
+ */
+ public static final int RE_DOT_NEWLINE = 6;
+
+ /**
+ * Syntax bit. Match-any-character operator (.) does not match a null.
+ */
+ public static final int RE_DOT_NOT_NULL = 7;
+
+ /**
+ * Syntax bit. Intervals ({x}, {x,}, {x,y}) are allowed.
+ */
+ public static final int RE_INTERVALS = 8;
+
+ /**
+ * Syntax bit. No alternation (|), match one-or-more (+), or
+ * match zero-or-one (?) operators.
+ */
+ public static final int RE_LIMITED_OPS = 9;
+
+ /**
+ * Syntax bit. Newline is an alternation operator.
+ */
+ public static final int RE_NEWLINE_ALT = 10; // impl.
+
+ /**
+ * Syntax bit. Intervals use { } instead of \{ \}
+ */
+ public static final int RE_NO_BK_BRACES = 11;
+
+ /**
+ * Syntax bit. Grouping uses ( ) instead of \( \).
+ */
+ public static final int RE_NO_BK_PARENS = 12;
+
+ /**
+ * Syntax bit. Backreferences not allowed.
+ */
+ public static final int RE_NO_BK_REFS = 13;
+
+ /**
+ * Syntax bit. Alternation uses | instead of \|
+ */
+ public static final int RE_NO_BK_VBAR = 14;
+
+ /**
+ * Syntax bit. <B>Not implemented</B>.
+ */
+ public static final int RE_NO_EMPTY_RANGES = 15;
+
+ /**
+ * Syntax bit. An unmatched right parenthesis (')' or '\)', depending
+ * on RE_NO_BK_PARENS) will throw an exception when compiling.
+ */
+ public static final int RE_UNMATCHED_RIGHT_PAREN_ORD = 16;
+
+ /**
+ * Syntax bit. <B>Not implemented.</B>
+ */
+ public static final int RE_HAT_LISTS_NOT_NEWLINE = 17;
+
+ /**
+ * Syntax bit. Stingy matching is allowed (+?, *?, ??, {x,y}?).
+ */
+ public static final int RE_STINGY_OPS = 18;
+
+ /**
+ * Syntax bit. Allow character class escapes (\d, \D, \s, \S, \w, \W).
+ */
+ public static final int RE_CHAR_CLASS_ESCAPES = 19;
+
+ /**
+ * Syntax bit. Allow use of (?:xxx) grouping (subexpression is not saved).
+ */
+ public static final int RE_PURE_GROUPING = 20;
+
+ /**
+ * Syntax bit. Allow use of (?=xxx) and (?!xxx) apply the subexpression
+ * to the text following the current position without consuming that text.
+ */
+ public static final int RE_LOOKAHEAD = 21;
+
+ /**
+ * Syntax bit. Allow beginning- and end-of-string anchors (\A, \Z).
+ */
+ public static final int RE_STRING_ANCHORS = 22;
+
+ /**
+ * Syntax bit. Allow embedded comments, (?#comment), as in Perl5.
+ */
+ public static final int RE_COMMENTS = 23;
+
+ /**
+ * Syntax bit. Allow character class escapes within lists, as in Perl5.
+ */
+ public static final int RE_CHAR_CLASS_ESC_IN_LISTS = 24;
+
+ private static final int BIT_TOTAL = 25;
+
+ /**
+ * Predefined syntax.
+ * Emulates regular expression support in the awk utility.
+ */
+ public static final RESyntax RE_SYNTAX_AWK;
+
+ /**
+ * Predefined syntax.
+ * Emulates regular expression support in the ed utility.
+ */
+ public static final RESyntax RE_SYNTAX_ED;
+
+ /**
+ * Predefined syntax.
+ * Emulates regular expression support in the egrep utility.
+ */
+ public static final RESyntax RE_SYNTAX_EGREP;
+
+ /**
+ * Predefined syntax.
+ * Emulates regular expression support in the GNU Emacs editor.
+ */
+ public static final RESyntax RE_SYNTAX_EMACS;
+
+ /**
+ * Predefined syntax.
+ * Emulates regular expression support in the grep utility.
+ */
+ public static final RESyntax RE_SYNTAX_GREP;
+
+ /**
+ * Predefined syntax.
+ * Emulates regular expression support in the POSIX awk specification.
+ */
+ public static final RESyntax RE_SYNTAX_POSIX_AWK;
+
+ /**
+ * Predefined syntax.
+ * Emulates POSIX basic regular expression support.
+ */
+ public static final RESyntax RE_SYNTAX_POSIX_BASIC;
+
+ /**
+ * Predefined syntax.
+ * Emulates regular expression support in the POSIX egrep specification.
+ */
+ public static final RESyntax RE_SYNTAX_POSIX_EGREP;
+
+ /**
+ * Predefined syntax.
+ * Emulates POSIX extended regular expression support.
+ */
+ public static final RESyntax RE_SYNTAX_POSIX_EXTENDED;
+
+ /**
+ * Predefined syntax.
+ * Emulates POSIX basic minimal regular expressions.
+ */
+ public static final RESyntax RE_SYNTAX_POSIX_MINIMAL_BASIC;
+
+ /**
+ * Predefined syntax.
+ * Emulates POSIX extended minimal regular expressions.
+ */
+ public static final RESyntax RE_SYNTAX_POSIX_MINIMAL_EXTENDED;
+
+ /**
+ * Predefined syntax.
+ * Emulates regular expression support in the sed utility.
+ */
+ public static final RESyntax RE_SYNTAX_SED;
+
+ /**
+ * Predefined syntax.
+ * Emulates regular expression support in Larry Wall's perl, version 4,
+ */
+ public static final RESyntax RE_SYNTAX_PERL4;
+
+ /**
+ * Predefined syntax.
+ * Emulates regular expression support in Larry Wall's perl, version 4,
+ * using single line mode (/s modifier).
+ */
+ public static final RESyntax RE_SYNTAX_PERL4_S; // single line mode (/s)
+
+ /**
+ * Predefined syntax.
+ * Emulates regular expression support in Larry Wall's perl, version 5.
+ */
+ public static final RESyntax RE_SYNTAX_PERL5;
+
+ /**
+ * Predefined syntax.
+ * Emulates regular expression support in Larry Wall's perl, version 5,
+ * using single line mode (/s modifier).
+ */
+ public static final RESyntax RE_SYNTAX_PERL5_S;
+
+ static {
+ // Define syntaxes
+
+ RE_SYNTAX_EMACS = new RESyntax().makeFinal();
+
+ RESyntax RE_SYNTAX_POSIX_COMMON = new RESyntax()
+ .set(RE_CHAR_CLASSES)
+ .set(RE_DOT_NEWLINE)
+ .set(RE_DOT_NOT_NULL)
+ .set(RE_INTERVALS)
+ .set(RE_NO_EMPTY_RANGES)
+ .makeFinal();
+
+ RE_SYNTAX_POSIX_BASIC = new RESyntax(RE_SYNTAX_POSIX_COMMON)
+ .set(RE_BK_PLUS_QM)
+ .makeFinal();
+
+ RE_SYNTAX_POSIX_EXTENDED = new RESyntax(RE_SYNTAX_POSIX_COMMON)
+ .set(RE_CONTEXT_INDEP_ANCHORS)
+ .set(RE_CONTEXT_INDEP_OPS)
+ .set(RE_NO_BK_BRACES)
+ .set(RE_NO_BK_PARENS)
+ .set(RE_NO_BK_VBAR)
+ .set(RE_UNMATCHED_RIGHT_PAREN_ORD)
+ .makeFinal();
+
+ RE_SYNTAX_AWK = new RESyntax()
+ .set(RE_BACKSLASH_ESCAPE_IN_LISTS)
+ .set(RE_DOT_NOT_NULL)
+ .set(RE_NO_BK_PARENS)
+ .set(RE_NO_BK_REFS)
+ .set(RE_NO_BK_VBAR)
+ .set(RE_NO_EMPTY_RANGES)
+ .set(RE_UNMATCHED_RIGHT_PAREN_ORD)
+ .makeFinal();
+
+ RE_SYNTAX_POSIX_AWK = new RESyntax(RE_SYNTAX_POSIX_EXTENDED)
+ .set(RE_BACKSLASH_ESCAPE_IN_LISTS)
+ .makeFinal();
+
+ RE_SYNTAX_GREP = new RESyntax()
+ .set(RE_BK_PLUS_QM)
+ .set(RE_CHAR_CLASSES)
+ .set(RE_HAT_LISTS_NOT_NEWLINE)
+ .set(RE_INTERVALS)
+ .set(RE_NEWLINE_ALT)
+ .makeFinal();
+
+ RE_SYNTAX_EGREP = new RESyntax()
+ .set(RE_CHAR_CLASSES)
+ .set(RE_CONTEXT_INDEP_ANCHORS)
+ .set(RE_CONTEXT_INDEP_OPS)
+ .set(RE_HAT_LISTS_NOT_NEWLINE)
+ .set(RE_NEWLINE_ALT)
+ .set(RE_NO_BK_PARENS)
+ .set(RE_NO_BK_VBAR)
+ .makeFinal();
+
+ RE_SYNTAX_POSIX_EGREP = new RESyntax(RE_SYNTAX_EGREP)
+ .set(RE_INTERVALS)
+ .set(RE_NO_BK_BRACES)
+ .makeFinal();
+
+ /* P1003.2/D11.2, section 4.20.7.1, lines 5078ff. */
+
+ RE_SYNTAX_ED = new RESyntax(RE_SYNTAX_POSIX_BASIC)
+ .makeFinal();
+
+ RE_SYNTAX_SED = new RESyntax(RE_SYNTAX_POSIX_BASIC)
+ .makeFinal();
+
+ RE_SYNTAX_POSIX_MINIMAL_BASIC = new RESyntax(RE_SYNTAX_POSIX_COMMON)
+ .set(RE_LIMITED_OPS)
+ .makeFinal();
+
+ /* Differs from RE_SYNTAX_POSIX_EXTENDED in that RE_CONTEXT_INVALID_OPS
+ replaces RE_CONTEXT_INDEP_OPS and RE_NO_BK_REFS is added. */
+
+ RE_SYNTAX_POSIX_MINIMAL_EXTENDED = new RESyntax(RE_SYNTAX_POSIX_COMMON)
+ .set(RE_CONTEXT_INDEP_ANCHORS)
+ .set(RE_CONTEXT_INVALID_OPS)
+ .set(RE_NO_BK_BRACES)
+ .set(RE_NO_BK_PARENS)
+ .set(RE_NO_BK_REFS)
+ .set(RE_NO_BK_VBAR)
+ .set(RE_UNMATCHED_RIGHT_PAREN_ORD)
+ .makeFinal();
+
+ /* There is no official Perl spec, but here's a "best guess" */
+
+ RE_SYNTAX_PERL4 = new RESyntax()
+ .set(RE_BACKSLASH_ESCAPE_IN_LISTS)
+ .set(RE_CONTEXT_INDEP_ANCHORS)
+ .set(RE_CONTEXT_INDEP_OPS) // except for '{', apparently
+ .set(RE_INTERVALS)
+ .set(RE_NO_BK_BRACES)
+ .set(RE_NO_BK_PARENS)
+ .set(RE_NO_BK_VBAR)
+ .set(RE_NO_EMPTY_RANGES)
+ .set(RE_CHAR_CLASS_ESCAPES) // \d,\D,\w,\W,\s,\S
+ .makeFinal();
+
+ RE_SYNTAX_PERL4_S = new RESyntax(RE_SYNTAX_PERL4)
+ .set(RE_DOT_NEWLINE)
+ .makeFinal();
+
+ RE_SYNTAX_PERL5 = new RESyntax(RE_SYNTAX_PERL4)
+ .set(RE_PURE_GROUPING) // (?:)
+ .set(RE_STINGY_OPS) // *?,??,+?,{}?
+ .set(RE_LOOKAHEAD) // (?=)(?!)
+ .set(RE_STRING_ANCHORS) // \A,\Z
+ .set(RE_CHAR_CLASS_ESC_IN_LISTS)// \d,\D,\w,\W,\s,\S within []
+ .set(RE_COMMENTS) // (?#)
+ .makeFinal();
+
+ RE_SYNTAX_PERL5_S = new RESyntax(RE_SYNTAX_PERL5)
+ .set(RE_DOT_NEWLINE)
+ .makeFinal();
+ }
+
+ /**
+ * Construct a new syntax object with all bits turned off.
+ * This is equivalent to RE_SYNTAX_EMACS.
+ */
+ public RESyntax() {
+ bits = new BitSet(BIT_TOTAL);
+ }
+
+ /**
+ * Called internally when constructing predefined syntaxes
+ * so their interpretation cannot vary. Conceivably useful
+ * for your syntaxes as well. Causes IllegalAccessError to
+ * be thrown if any attempt to modify the syntax is made.
+ *
+ * @return this object for convenient chaining
+ */
+ public RESyntax makeFinal() {
+ isFinal = true;
+ return this;
+ }
+
+ /**
+ * Construct a new syntax object with all bits set the same
+ * as the other syntax.
+ */
+ public RESyntax(RESyntax other) {
+ bits = (BitSet) other.bits.clone();
+ }
+
+ /**
+ * Check if a given bit is set in this syntax.
+ */
+ public boolean get(int index) {
+ return bits.get(index);
+ }
+
+ /**
+ * Set a given bit in this syntax.
+ *
+ * @param index the constant (RESyntax.RE_xxx) bit to set.
+ * @return a reference to this object for easy chaining.
+ */
+ public RESyntax set(int index) {
+ if (isFinal) throw new IllegalAccessError(SYNTAX_IS_FINAL);
+ bits.set(index);
+ return this;
+ }
+
+ /**
+ * Clear a given bit in this syntax.
+ *
+ * @param index the constant (RESyntax.RE_xxx) bit to clear.
+ * @return a reference to this object for easy chaining.
+ */
+ public RESyntax clear(int index) {
+ if (isFinal) throw new IllegalAccessError(SYNTAX_IS_FINAL);
+ bits.clear(index);
+ return this;
+ }
+
+ /**
+ * Changes the line separator string for regular expressions
+ * created using this RESyntax. The default separator is the
+ * value returned by the system property "line.separator", which
+ * should be correct when reading platform-specific files from a
+ * filesystem. However, many programs may collect input from
+ * sources where the line separator is differently specified (for
+ * example, in the applet environment, the text box widget
+ * interprets line breaks as single-character newlines,
+ * regardless of the host platform.
+ *
+ * Note that setting the line separator to a character or
+ * characters that have specific meaning within the current syntax
+ * can cause unexpected chronosynclastic infundibula.
+ *
+ * @return this object for convenient chaining
+ */
+ public RESyntax setLineSeparator(String aSeparator) {
+ if (isFinal) throw new IllegalAccessError(SYNTAX_IS_FINAL);
+ lineSeparator = aSeparator;
+ return this;
+ }
+
+ /**
+ * Returns the currently active line separator string. The default
+ * is the platform-dependent system property "line.separator".
+ */
+ public String getLineSeparator() {
+ return lineSeparator;
+ }
+}
--- /dev/null
+/*
+ * gnu/regexp/REToken.java
+ * Copyright (C) 1998-2001 Wes Biggs
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package gnu.regexp;
+import java.io.Serializable;
+
+abstract class REToken implements Serializable {
+
+ protected REToken next = null;
+ protected REToken uncle = null;
+ protected int subIndex;
+
+ protected REToken(int subIndex) {
+ this.subIndex = subIndex;
+ }
+
+ int getMinimumLength() {
+ return 0;
+ }
+
+ void setUncle(REToken anUncle) {
+ uncle = anUncle;
+ }
+
+ /** Returns true if the match succeeded, false if it failed. */
+ abstract boolean match(CharIndexed input, REMatch mymatch);
+
+ /** Returns true if the rest of the tokens match, false if they fail. */
+ protected boolean next(CharIndexed input, REMatch mymatch) {
+ if (next == null) {
+ if (uncle == null) {
+ return true;
+ } else {
+ return uncle.match(input, mymatch);
+ }
+ } else {
+ return next.match(input, mymatch);
+ }
+ }
+
+ boolean chain(REToken token) {
+ next = token;
+ return true; // Token was accepted
+ }
+
+ abstract void dump(StringBuffer os);
+
+ void dumpAll(StringBuffer os) {
+ dump(os);
+ if (next != null) next.dumpAll(os);
+ }
+}
--- /dev/null
+/*
+ * gnu/regexp/RETokenAny.java
+ * Copyright (C) 1998-2001 Wes Biggs
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package gnu.regexp;
+
+final class RETokenAny extends REToken {
+ /** True if '.' can match a newline (RE_DOT_NEWLINE) */
+ private boolean newline;
+
+ /** True if '.' can't match a null (RE_DOT_NOT_NULL) */
+ private boolean matchNull;
+
+ RETokenAny(int subIndex, boolean newline, boolean matchNull) {
+ super(subIndex);
+ this.newline = newline;
+ this.matchNull = matchNull;
+ }
+
+ int getMinimumLength() {
+ return 1;
+ }
+
+ boolean match(CharIndexed input, REMatch mymatch) {
+ char ch = input.charAt(mymatch.index);
+ if ((ch == CharIndexed.OUT_OF_BOUNDS)
+ || (!newline && (ch == '\n'))
+ || (matchNull && (ch == 0))) {
+ return false;
+ }
+ ++mymatch.index;
+ return next(input, mymatch);
+ }
+
+ void dump(StringBuffer os) {
+ os.append('.');
+ }
+}
+
--- /dev/null
+/*
+ * gnu/regexp/RETokenBackRef.java
+ * Copyright (C) 1998-2001 Wes Biggs
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package gnu.regexp;
+
+final class RETokenBackRef extends REToken {
+ private int num;
+ private boolean insens;
+
+ RETokenBackRef(int subIndex, int num, boolean insens) {
+ super(subIndex);
+ this.num = num;
+ this.insens = insens;
+ }
+
+ // should implement getMinimumLength() -- any ideas?
+
+ boolean match(CharIndexed input, REMatch mymatch) {
+ int b,e;
+ b = mymatch.start[num];
+ e = mymatch.end[num];
+ if ((b==-1)||(e==-1)) return false; // this shouldn't happen, but...
+ for (int i=b; i<e; i++) {
+ if (input.charAt(mymatch.index+i-b) != input.charAt(i)) {
+ return false;
+ }
+ }
+ mymatch.index += e-b;
+ return next(input, mymatch);
+ }
+
+ void dump(StringBuffer os) {
+ os.append('\\').append(num);
+ }
+}
+
+
--- /dev/null
+/*
+ * gnu/regexp/RETokenChar.java
+ * Copyright (C) 1998-2001 Wes Biggs
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package gnu.regexp;
+
+final class RETokenChar extends REToken {
+ private char[] ch;
+ private boolean insens;
+
+ RETokenChar(int subIndex, char c, boolean ins) {
+ super(subIndex);
+ ch = new char [1];
+ ch[0] = (insens = ins) ? Character.toLowerCase(c) : c;
+ }
+
+ int getMinimumLength() {
+ return ch.length;
+ }
+
+ boolean match(CharIndexed input, REMatch mymatch) {
+ int z = ch.length;
+ char c;
+ for (int i=0; i<z; i++) {
+ c = input.charAt(mymatch.index+i);
+ if (( (insens) ? Character.toLowerCase(c) : c ) != ch[i]) {
+ return false;
+ }
+ }
+ mymatch.index += z;
+
+ return next(input, mymatch);
+ }
+
+ // Overrides REToken.chain() to optimize for strings
+ boolean chain(REToken next) {
+ if (next instanceof RETokenChar) {
+ RETokenChar cnext = (RETokenChar) next;
+ // assume for now that next can only be one character
+ int newsize = ch.length + cnext.ch.length;
+
+ char[] chTemp = new char [newsize];
+
+ System.arraycopy(ch,0,chTemp,0,ch.length);
+ System.arraycopy(cnext.ch,0,chTemp,ch.length,cnext.ch.length);
+
+ ch = chTemp;
+ return false;
+ } else return super.chain(next);
+ }
+
+ void dump(StringBuffer os) {
+ os.append(ch);
+ }
+}
+
+
--- /dev/null
+/*
+ * gnu/regexp/RETokenEnd.java
+ * Copyright (C) 1998-2001 Wes Biggs
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package gnu.regexp;
+
+final class RETokenEnd extends REToken {
+ /**
+ * Indicates whether this token should match on a line break.
+ */
+ private String newline;
+
+ RETokenEnd(int subIndex,String newline) {
+ super(subIndex);
+ this.newline = newline;
+ }
+
+ boolean match(CharIndexed input, REMatch mymatch) {
+ char ch = input.charAt(mymatch.index);
+ if (ch == CharIndexed.OUT_OF_BOUNDS)
+ return ((mymatch.eflags & RE.REG_NOTEOL)>0) ?
+ false : next(input, mymatch);
+ if (newline != null) {
+ char z;
+ int i = 0; // position in newline
+ do {
+ z = newline.charAt(i);
+ if (ch != z) return false;
+ ++i;
+ ch = input.charAt(mymatch.index + i);
+ } while (i < newline.length());
+
+ return next(input, mymatch);
+ }
+ return false;
+ }
+
+ void dump(StringBuffer os) {
+ os.append('$');
+ }
+}
--- /dev/null
+/*
+ * gnu/regexp/RETokenEndSub.java
+ * Copyright (C) 2001 Wes Biggs
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package gnu.regexp;
+
+final class RETokenEndSub extends REToken {
+ RETokenEndSub(int subIndex) {
+ super(subIndex);
+ }
+
+ boolean match(CharIndexed input, REMatch mymatch) {
+ mymatch.end[subIndex] = mymatch.index;
+ return next(input, mymatch);
+ }
+
+ void dump(StringBuffer os) {
+ // handled by RE
+ }
+}
--- /dev/null
+/*
+ * gnu/regexp/RETokenOneOf.java
+ * Copyright (C) 1998-2001 Wes Biggs
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package gnu.regexp;
+
+/**
+ * @since gnu.regexp 1.1.3
+ * @author Shashank Bapat
+ */
+final class RETokenLookAhead extends REToken
+{
+ REToken re;
+ boolean negative;
+
+ RETokenLookAhead(REToken re, boolean negative) throws REException {
+ super(0);
+ this.re = re;
+ this.negative = negative;
+ }
+
+ boolean match(CharIndexed input, REMatch mymatch)
+ {
+ REMatch trymatch = (REMatch)mymatch.clone();
+ REMatch trymatch1 = (REMatch)mymatch.clone();
+ REMatch newMatch = null;
+ if (re.match(input, trymatch)) {
+ if (negative) return false;
+ if (next(input, trymatch1))
+ newMatch = trymatch1;
+ }
+
+ if (newMatch != null) {
+ if (negative) return false;
+ //else
+ mymatch.assignFrom(newMatch);
+ return true;
+ }
+ else { // no match
+ if (negative)
+ return next(input, mymatch);
+ //else
+ return false;
+ }
+ }
+
+ void dump(StringBuffer os) {
+ os.append("(?");
+ os.append(negative ? '!' : '=');
+ re.dumpAll(os);
+ os.append(')');
+ }
+}
+
--- /dev/null
+/*
+ * gnu/regexp/RETokenOneOf.java
+ * Copyright (C) 1998-2001 Wes Biggs
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package gnu.regexp;
+import java.util.Vector;
+
+final class RETokenOneOf extends REToken {
+ private Vector options;
+ private boolean negative;
+
+ // This constructor is used for convenience when we know the set beforehand,
+ // e.g. \d --> new RETokenOneOf("0123456789",false, ..)
+ // \D --> new RETokenOneOf("0123456789",true, ..)
+
+ RETokenOneOf(int subIndex, String optionsStr, boolean negative, boolean insens) {
+ super(subIndex);
+ options = new Vector();
+ this.negative = negative;
+ for (int i = 0; i < optionsStr.length(); i++)
+ options.addElement(new RETokenChar(subIndex,optionsStr.charAt(i),insens));
+ }
+
+ RETokenOneOf(int subIndex, Vector options, boolean negative) {
+ super(subIndex);
+ this.options = options;
+ this.negative = negative;
+ }
+
+ int getMinimumLength() {
+ int min = Integer.MAX_VALUE;
+ int x;
+ for (int i=0; i < options.size(); i++) {
+ if ((x = ((REToken) options.elementAt(i)).getMinimumLength()) < min)
+ min = x;
+ }
+ return min;
+ }
+
+ boolean match(CharIndexed input, REMatch mymatch) {
+ if (negative && (input.charAt(mymatch.index) == CharIndexed.OUT_OF_BOUNDS))
+ return false;
+
+ REMatch newMatch = null;
+ REMatch last = null;
+ REToken tk;
+ boolean isMatch;
+ for (int i=0; i < options.size(); i++) {
+ tk = (REToken) options.elementAt(i);
+ REMatch tryMatch = (REMatch) mymatch.clone();
+ if (tk.match(input, tryMatch)) { // match was successful
+ if (negative) return false;
+
+ if (next(input, tryMatch)) {
+ // Add tryMatch to list of possibilities.
+ if (last == null) {
+ newMatch = tryMatch;
+ last = tryMatch;
+ } else {
+ last.next = tryMatch;
+ last = tryMatch;
+ }
+ } // next succeeds
+ } // is a match
+ } // try next option
+
+ if (newMatch != null) {
+ if (negative) {
+ return false;
+ } else {
+ // set contents of mymatch equal to newMatch
+
+ // try each one that matched
+ mymatch.assignFrom(newMatch);
+ return true;
+ }
+ } else {
+ if (negative) {
+ ++mymatch.index;
+ return next(input, mymatch);
+ } else {
+ return false;
+ }
+ }
+
+ // index+1 works for [^abc] lists, not for generic lookahead (--> index)
+ }
+
+ void dump(StringBuffer os) {
+ os.append(negative ? "[^" : "(?:");
+ for (int i = 0; i < options.size(); i++) {
+ if (!negative && (i > 0)) os.append('|');
+ ((REToken) options.elementAt(i)).dumpAll(os);
+ }
+ os.append(negative ? ']' : ')');
+ }
+}
--- /dev/null
+/*
+ * gnu/regexp/RETokenPOSIX.java
+ * Copyright (C) 1998-2001 Wes Biggs
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package gnu.regexp;
+
+final class RETokenPOSIX extends REToken {
+ int type;
+ boolean insens;
+ boolean negated;
+
+ static final int ALNUM = 0;
+ static final int ALPHA = 1;
+ static final int BLANK = 2;
+ static final int CNTRL = 3;
+ static final int DIGIT = 4;
+ static final int GRAPH = 5;
+ static final int LOWER = 6;
+ static final int PRINT = 7;
+ static final int PUNCT = 8;
+ static final int SPACE = 9;
+ static final int UPPER = 10;
+ static final int XDIGIT = 11;
+
+ // Array indices correspond to constants defined above.
+ static final String[] s_nameTable = {
+ "alnum", "alpha", "blank", "cntrl", "digit", "graph", "lower",
+ "print", "punct", "space", "upper", "xdigit"
+ };
+
+ // The RE constructor uses this to look up the constant for a string
+ static int intValue(String key) {
+ for (int i = 0; i < s_nameTable.length; i++) {
+ if (s_nameTable[i].equals(key)) return i;
+ }
+ return -1;
+ }
+
+ RETokenPOSIX(int subIndex, int type, boolean insens, boolean negated) {
+ super(subIndex);
+ this.type = type;
+ this.insens = insens;
+ this.negated = negated;
+ }
+
+ int getMinimumLength() {
+ return 1;
+ }
+
+ boolean match(CharIndexed input, REMatch mymatch) {
+ char ch = input.charAt(mymatch.index);
+ if (ch == CharIndexed.OUT_OF_BOUNDS)
+ return false;
+
+ boolean retval = false;
+ switch (type) {
+ case ALNUM:
+ // Note that there is some debate over whether '_' should be included
+ retval = Character.isLetterOrDigit(ch) || (ch == '_');
+ break;
+ case ALPHA:
+ retval = Character.isLetter(ch);
+ break;
+ case BLANK:
+ retval = ((ch == ' ') || (ch == '\t'));
+ break;
+ case CNTRL:
+ retval = Character.isISOControl(ch);
+ break;
+ case DIGIT:
+ retval = Character.isDigit(ch);
+ break;
+ case GRAPH:
+ retval = (!(Character.isWhitespace(ch) || Character.isISOControl(ch)));
+ break;
+ case LOWER:
+ retval = ((insens && Character.isLetter(ch)) || Character.isLowerCase(ch));
+ break;
+ case PRINT:
+ retval = (!(Character.isWhitespace(ch) || Character.isISOControl(ch)))
+ || (ch == ' ');
+ break;
+ case PUNCT:
+ // This feels sloppy, especially for non-U.S. locales.
+ retval = ("`~!@#$%^&*()-_=+[]{}\\|;:'\"/?,.<>".indexOf(ch)!=-1);
+ break;
+ case SPACE:
+ retval = Character.isWhitespace(ch);
+ break;
+ case UPPER:
+ retval = ((insens && Character.isLetter(ch)) || Character.isUpperCase(ch));
+ break;
+ case XDIGIT:
+ retval = (Character.isDigit(ch) || ("abcdefABCDEF".indexOf(ch)!=-1));
+ break;
+ }
+
+ if (negated) retval = !retval;
+ if (retval) {
+ ++mymatch.index;
+ return next(input, mymatch);
+ }
+ else return false;
+ }
+
+ void dump(StringBuffer os) {
+ if (negated) os.append('^');
+ os.append("[:" + s_nameTable[type] + ":]");
+ }
+}
--- /dev/null
+/*
+ * gnu/regexp/RETokenRange.java
+ * Copyright (C) 1998-2001 Wes Biggs
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package gnu.regexp;
+
+final class RETokenRange extends REToken {
+ private char lo, hi;
+ private boolean insens;
+
+ RETokenRange(int subIndex, char lo, char hi, boolean ins) {
+ super(subIndex);
+ this.lo = (insens = ins) ? Character.toLowerCase(lo) : lo;
+ this.hi = ins ? Character.toLowerCase(hi) : hi;
+ }
+
+ int getMinimumLength() {
+ return 1;
+ }
+
+ boolean match(CharIndexed input, REMatch mymatch) {
+ char c = input.charAt(mymatch.index);
+ if (c == CharIndexed.OUT_OF_BOUNDS) return false;
+ if (insens) c = Character.toLowerCase(c);
+ if ((c >= lo) && (c <= hi)) {
+ ++mymatch.index;
+ return next(input, mymatch);
+ }
+ return false;
+ }
+
+ void dump(StringBuffer os) {
+ os.append(lo).append('-').append(hi);
+ }
+}
+
--- /dev/null
+/*
+ * gnu/regexp/RETokenRepeated.java
+ * Copyright (C) 1998-2001 Wes Biggs
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package gnu.regexp;
+import java.util.Vector;
+
+final class RETokenRepeated extends REToken {
+ private REToken token;
+ private int min,max;
+ private boolean stingy;
+
+ RETokenRepeated(int subIndex, REToken token, int min, int max) {
+ super(subIndex);
+ this.token = token;
+ this.min = min;
+ this.max = max;
+ }
+
+ /** Sets the minimal matching mode to true. */
+ void makeStingy() {
+ stingy = true;
+ }
+
+ /** Queries if this token has minimal matching enabled. */
+ boolean isStingy() {
+ return stingy;
+ }
+
+ /**
+ * The minimum length of a repeated token is the minimum length
+ * of the token multiplied by the minimum number of times it must
+ * match.
+ */
+ int getMinimumLength() {
+ return (min * token.getMinimumLength());
+ }
+
+ // We do need to save every possible point, but the number of clone()
+ // invocations here is really a killer for performance on non-stingy
+ // repeat operators. I'm open to suggestions...
+
+ // Hypothetical question: can you have a RE that matches 1 times,
+ // 3 times, 5 times, but not 2 times or 4 times? Does having
+ // the subexpression back-reference operator allow that?
+
+ boolean match(CharIndexed input, REMatch mymatch) {
+ // number of times we've matched so far
+ int numRepeats = 0;
+
+ // Possible positions for the next repeat to match at
+ REMatch newMatch = mymatch;
+ REMatch last = null;
+ REMatch current;
+
+ // Add the '0-repeats' index
+ // positions.elementAt(z) == position [] in input after <<z>> matches
+ Vector positions = new Vector();
+ positions.addElement(newMatch);
+
+ // Declare variables used in loop
+ REMatch doables;
+ REMatch doablesLast;
+ REMatch recurrent;
+
+ do {
+ // Check for stingy match for each possibility.
+ if (stingy && (numRepeats >= min)) {
+ REMatch result = matchRest(input, newMatch);
+ if (result != null) {
+ mymatch.assignFrom(result);
+ return true;
+ }
+ }
+
+ doables = null;
+ doablesLast = null;
+
+ // try next repeat at all possible positions
+ for (current = newMatch; current != null; current = current.next) {
+ recurrent = (REMatch) current.clone();
+ if (token.match(input, recurrent)) {
+ // add all items in current to doables array
+ if (doables == null) {
+ doables = recurrent;
+ doablesLast = recurrent;
+ } else {
+ // Order these from longest to shortest
+ // Start by assuming longest (more repeats)
+ doablesLast.next = recurrent;
+ }
+ // Find new doablesLast
+ while (doablesLast.next != null) {
+ doablesLast = doablesLast.next;
+ }
+ }
+ }
+ // if none of the possibilities worked out, break out of do/while
+ if (doables == null) break;
+
+ // reassign where the next repeat can match
+ newMatch = doables;
+
+ // increment how many repeats we've successfully found
+ ++numRepeats;
+
+ positions.addElement(newMatch);
+ } while (numRepeats < max);
+
+ // If there aren't enough repeats, then fail
+ if (numRepeats < min) return false;
+
+ // We're greedy, but ease off until a true match is found
+ int posIndex = positions.size();
+
+ // At this point we've either got too many or just the right amount.
+ // See if this numRepeats works with the rest of the regexp.
+ REMatch allResults = null;
+ REMatch allResultsLast = null;
+
+ REMatch results = null;
+ while (--posIndex >= min) {
+ newMatch = (REMatch) positions.elementAt(posIndex);
+ results = matchRest(input, newMatch);
+ if (results != null) {
+ if (allResults == null) {
+ allResults = results;
+ allResultsLast = results;
+ } else {
+ // Order these from longest to shortest
+ // Start by assuming longest (more repeats)
+ allResultsLast.next = results;
+ }
+ // Find new doablesLast
+ while (allResultsLast.next != null) {
+ allResultsLast = allResultsLast.next;
+ }
+ }
+ // else did not match rest of the tokens, try again on smaller sample
+ }
+ if (allResults != null) {
+ mymatch.assignFrom(allResults); // does this get all?
+ return true;
+ }
+ // If we fall out, no matches.
+ return false;
+ }
+
+ private REMatch matchRest(CharIndexed input, final REMatch newMatch) {
+ REMatch current, single;
+ REMatch doneIndex = null;
+ REMatch doneIndexLast = null;
+ // Test all possible matches for this number of repeats
+ for (current = newMatch; current != null; current = current.next) {
+ // clone() separates a single match from the chain
+ single = (REMatch) current.clone();
+ if (next(input, single)) {
+ // chain results to doneIndex
+ if (doneIndex == null) {
+ doneIndex = single;
+ doneIndexLast = single;
+ } else {
+ doneIndexLast.next = single;
+ }
+ // Find new doneIndexLast
+ while (doneIndexLast.next != null) {
+ doneIndexLast = doneIndexLast.next;
+ }
+ }
+ }
+ return doneIndex;
+ }
+
+ void dump(StringBuffer os) {
+ os.append("(?:");
+ token.dumpAll(os);
+ os.append(')');
+ if ((max == Integer.MAX_VALUE) && (min <= 1))
+ os.append( (min == 0) ? '*' : '+' );
+ else if ((min == 0) && (max == 1))
+ os.append('?');
+ else {
+ os.append('{').append(min);
+ if (max > min) {
+ os.append(',');
+ if (max != Integer.MAX_VALUE) os.append(max);
+ }
+ os.append('}');
+ }
+ if (stingy) os.append('?');
+ }
+}
--- /dev/null
+/*
+ * gnu/regexp/RETokenStart.java
+ * Copyright (C) 1998-2001 Wes Biggs
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package gnu.regexp;
+
+class RETokenStart extends REToken {
+ private String newline; // matches after a newline
+
+ RETokenStart(int subIndex, String newline) {
+ super(subIndex);
+ this.newline = newline;
+ }
+
+ boolean match(CharIndexed input, REMatch mymatch) {
+ // charAt(index-n) may be unknown on a Reader/InputStream. FIXME
+ // Match after a newline if in multiline mode
+
+ if (newline != null) {
+ int len = newline.length();
+ if (mymatch.offset >= len) {
+ boolean found = true;
+ char z;
+ int i = 0; // position in REToken.newline
+ char ch = input.charAt(mymatch.index - len);
+ do {
+ z = newline.charAt(i);
+ if (ch != z) {
+ found = false;
+ break;
+ }
+ ++i;
+ ch = input.charAt(mymatch.index - len + i);
+ } while (i < len);
+
+ if (found) return next(input, mymatch);
+ }
+ }
+
+ // Don't match at all if REG_NOTBOL is set.
+ if ((mymatch.eflags & RE.REG_NOTBOL) > 0) return false;
+
+ if ((mymatch.eflags & RE.REG_ANCHORINDEX) > 0)
+ return (mymatch.anchor == mymatch.offset) ?
+ next(input, mymatch) : false;
+ else
+ return ((mymatch.index == 0) && (mymatch.offset == 0)) ?
+ next(input, mymatch) : false;
+ }
+
+ void dump(StringBuffer os) {
+ os.append('^');
+ }
+}
--- /dev/null
+/*
+ * gnu/regexp/RETokenWordBoundary.java
+ * Copyright (C) 2001 Wes Biggs
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package gnu.regexp;
+
+/**
+ * Represents a combination lookahead/lookbehind for POSIX [:alnum:].
+ */
+final class RETokenWordBoundary extends REToken {
+ private boolean negated;
+ private int where;
+ static final int BEGIN = 1;
+ static final int END = 2;
+
+ RETokenWordBoundary(int subIndex, int where, boolean negated) {
+ super(subIndex);
+ this.where = where;
+ this.negated = negated;
+ }
+
+ boolean match(CharIndexed input, REMatch mymatch) {
+ // Word boundary means input[index-1] was a word character
+ // and input[index] is not, or input[index] is a word character
+ // and input[index-1] was not
+ // In the string "one two three", these positions match:
+ // |o|n|e| |t|w|o| |t|h|r|e|e|
+ // ^ ^ ^ ^ ^ ^
+ boolean after = false; // is current character a letter or digit?
+ boolean before = false; // is previous character a letter or digit?
+ char ch;
+
+ // TODO: Also check REG_ANCHORINDEX vs. anchor
+ if (((mymatch.eflags & RE.REG_ANCHORINDEX) != RE.REG_ANCHORINDEX)
+ || (mymatch.offset + mymatch.index > mymatch.anchor)) {
+ if ((ch = input.charAt(mymatch.index - 1)) != CharIndexed.OUT_OF_BOUNDS) {
+ before = Character.isLetterOrDigit(ch) || (ch == '_');
+ }
+ }
+
+ if ((ch = input.charAt(mymatch.index)) != CharIndexed.OUT_OF_BOUNDS) {
+ after = Character.isLetterOrDigit(ch) || (ch == '_');
+ }
+
+ // if (before) and (!after), we're at end (\>)
+ // if (after) and (!before), we're at beginning (\<)
+ boolean doNext = false;
+
+ if ((where & BEGIN) == BEGIN) {
+ doNext = after && !before;
+ }
+ if ((where & END) == END) {
+ doNext ^= before && !after;
+ }
+
+ if (negated) doNext = !doNext;
+
+ return (doNext ? next(input, mymatch) : false);
+ }
+
+ void dump(StringBuffer os) {
+ if (where == (BEGIN | END)) {
+ os.append( negated ? "\\B" : "\\b" );
+ } else if (where == BEGIN) {
+ os.append("\\<");
+ } else {
+ os.append("\\>");
+ }
+ }
+}
--- /dev/null
+/*
+ * gnu/regexp/UncheckedRE.java
+ * Copyright (C) 2001 Wes Biggs
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package gnu.regexp;
+
+/**
+ * UncheckedRE is a subclass of RE that allows programmers an easier means
+ * of programmatically precompiling regular expressions. It is constructed
+ * and used in exactly the same manner as an instance of the RE class; the
+ * only difference is that its constructors do not throw REException.
+ * Instead, if a syntax error is encountered during construction, a
+ * RuntimeException will be thrown.
+ * <P>
+ * Note that this makes UncheckedRE dangerous if constructed with
+ * dynamic data. Do not use UncheckedRE unless you are completely sure
+ * that all input being passed to it contains valid, well-formed
+ * regular expressions for the syntax specified.
+ *
+ * @author <A HREF="mailto:wes@cacas.org">Wes Biggs</A>
+ * @see gnu.regexp.RE
+ * @since gnu.regexp 1.1.4
+ */
+
+public final class UncheckedRE extends RE {
+ /**
+ * Constructs a regular expression pattern buffer without any compilation
+ * flags set, and using the default syntax (RESyntax.RE_SYNTAX_PERL5).
+ *
+ * @param pattern A regular expression pattern, in the form of a String,
+ * StringBuffer or char[]. Other input types will be converted to
+ * strings using the toString() method.
+ * @exception RuntimeException The input pattern could not be parsed.
+ * @exception NullPointerException The pattern was null.
+ */
+ public UncheckedRE(Object pattern) {
+ this(pattern,0,RESyntax.RE_SYNTAX_PERL5);
+ }
+
+ /**
+ * Constructs a regular expression pattern buffer using the specified
+ * compilation flags and the default syntax (RESyntax.RE_SYNTAX_PERL5).
+ *
+ * @param pattern A regular expression pattern, in the form of a String,
+ * StringBuffer, or char[]. Other input types will be converted to
+ * strings using the toString() method.
+ * @param cflags The logical OR of any combination of the compilation flags in the RE class.
+ * @exception RuntimeException The input pattern could not be parsed.
+ * @exception NullPointerException The pattern was null.
+ */
+ public UncheckedRE(Object pattern, int cflags) {
+ this(pattern,cflags,RESyntax.RE_SYNTAX_PERL5);
+ }
+
+ /**
+ * Constructs a regular expression pattern buffer using the specified
+ * compilation flags and regular expression syntax.
+ *
+ * @param pattern A regular expression pattern, in the form of a String,
+ * StringBuffer, or char[]. Other input types will be converted to
+ * strings using the toString() method.
+ * @param cflags The logical OR of any combination of the compilation flags in the RE class.
+ * @param syntax The type of regular expression syntax to use.
+ * @exception RuntimeException The input pattern could not be parsed.
+ * @exception NullPointerException The pattern was null.
+ */
+ public UncheckedRE(Object pattern, int cflags, RESyntax syntax) {
+ try {
+ initialize(pattern,cflags,syntax,0,0);
+ } catch (REException e) {
+ throw new RuntimeException(e.getMessage());
+ }
+ }
+}
+
+
--- /dev/null
+/*
+ * gnu/regexp/util/Egrep.java
+ * Copyright (C) 1998 Wes Biggs
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package gnu.regexp.util;
+import gnu.regexp.RESyntax;
+
+/**
+ * This is a front end to the gnu.regexp.util.Grep class which sets the
+ * syntax used to RE_SYNTAX_EGREP, which aims to emulate the standard UNIX
+ * egrep command.
+ *
+ * @author <A HREF="mailto:wes@cacas.org">Wes Biggs</A>
+ * @version 1.01
+ * @use gnu.getopt
+ */
+public class Egrep {
+ private Egrep() { }
+
+ /**
+ * Invokes Grep.grep() using the RE_SYNTAX_EGREP syntax and the
+ * command line arguments specified. Output is sent to System.out.
+ * For a list of options, use the argument "--help".
+ */
+ public static void main(String[] argv) {
+ System.exit(Grep.grep(argv,RESyntax.RE_SYNTAX_EGREP,System.out));
+ }
+}
+
--- /dev/null
+/*
+ * gnu/regexp/util/Grep.java
+ * Copyright (C) 1998 Wes Biggs
+ * Copyright (C) 2001 Lee Sau Dan for the use of Reader for handling file I/O
+ * Copyright (C) 2001 Ulf Dittmer for support of grepping into ZIP files
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package gnu.regexp.util;
+
+import gnu.getopt.Getopt;
+import gnu.getopt.LongOpt;
+import gnu.regexp.RE;
+import gnu.regexp.REException;
+import gnu.regexp.REMatch;
+import gnu.regexp.RESyntax;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.io.UnsupportedEncodingException;
+import java.util.Enumeration;
+import java.util.Vector;
+import java.util.zip.*;
+
+
+/**
+ * Grep is a pure-Java clone of the GNU grep utility. As such, it is much
+ * slower and not as full-featured, but it has the advantage of being
+ * available on any system with a Java virtual machine.
+ *
+ * @author <A HREF="mailto:wes@cacas.org">Wes Biggs</A>
+ * <A HREF="http://www.csis.hku.hk/~sdlee/">Lee Sau Dan</A>
+ * <A HREF="http://www.capital.net/~dittmer/">Ulf Dittmer</A>
+ * @version 1.03
+ * @use gnu.getopt
+ */
+public class Grep {
+ private static final int BYTE_OFFSET = 0;
+ private static final int COUNT = 1;
+ private static final int LINE_NUMBER = 2;
+ private static final int QUIET = 3;
+ private static final int SILENT = 4;
+ private static final int NO_FILENAME = 5;
+ private static final int REVERT_MATCH = 6;
+ private static final int FILES_WITH_MATCHES = 7;
+ private static final int LINE_REGEXP = 8;
+ private static final int FILES_WITHOUT_MATCH = 9;
+ private static final int EXPAND_ZIP_FILES = 10;
+
+ private static final String PROGNAME = "gnu.regexp.util.Grep";
+ private static final String PROGVERSION = "1.03";
+
+ private Grep() { }
+ /**
+ * Invokes the grep() function below with the command line arguments
+ * and using the RESyntax.RE_SYNTAX_GREP syntax, which attempts to
+ * emulate the traditional UNIX grep syntax.
+ */
+ public static void main(String[] argv) {
+ System.exit(grep(argv, RESyntax.RE_SYNTAX_GREP, System.out));
+ }
+
+ /**
+ * Runs Grep with the specified arguments. For a list of
+ * supported options, specify "--help".
+ *
+ * This is the meat of the grep routine, but unlike main(), you can
+ * specify your own syntax and PrintStream to use for output.
+ */
+ public static int grep(String[] argv, RESyntax syntax, PrintStream out) {
+ // use gnu.getopt to read arguments
+ int cflags = 0;
+
+ boolean[] options = new boolean [10];
+
+ String encoding = null;
+
+ LongOpt[] longOptions = {
+ new LongOpt("byte-offset", LongOpt.NO_ARGUMENT, null, 'b'),
+ new LongOpt("count", LongOpt.NO_ARGUMENT, null, 'c'),
+ new LongOpt("no-filename", LongOpt.NO_ARGUMENT, null, 'h'),
+ new LongOpt("ignore-case", LongOpt.NO_ARGUMENT, null, 'i'),
+ new LongOpt("files-with-matches", LongOpt.NO_ARGUMENT, null, 'l'),
+ new LongOpt("help", LongOpt.NO_ARGUMENT, null, '!'),
+ new LongOpt("line-number", LongOpt.NO_ARGUMENT, null, 'n'),
+ new LongOpt("quiet", LongOpt.NO_ARGUMENT, null, 'q'),
+ new LongOpt("silent", LongOpt.NO_ARGUMENT, null, 'q'),
+ new LongOpt("no-messages", LongOpt.NO_ARGUMENT, null, 's'),
+ new LongOpt("revert-match", LongOpt.NO_ARGUMENT, null, 'v'),
+ new LongOpt("line-regexp", LongOpt.NO_ARGUMENT, null, 'x'),
+ new LongOpt("extended-regexp", LongOpt.NO_ARGUMENT, null, 'E'),
+ new LongOpt("fixed-strings", LongOpt.NO_ARGUMENT, null, 'F'), // TODO
+ new LongOpt("basic-regexp", LongOpt.NO_ARGUMENT, null, 'G'),
+ new LongOpt("files-without-match", LongOpt.NO_ARGUMENT, null, 'L'),
+ new LongOpt("version", LongOpt.NO_ARGUMENT, null, 'V'),
+ new LongOpt("zip", LongOpt.NO_ARGUMENT, null, 'z'),
+ new LongOpt("encoding", LongOpt.REQUIRED_ARGUMENT, null, 'N')
+ };
+
+ Getopt g = new Getopt(PROGNAME, argv, "bchilnqsvxyEFGLVzN:", longOptions);
+ int c;
+ String arg;
+ while ((c = g.getopt()) != -1) {
+ switch (c) {
+ case 'b':
+ options[BYTE_OFFSET] = true;
+ break;
+ case 'c':
+ options[COUNT] = true;
+ break;
+ case 'h':
+ options[NO_FILENAME] = true;
+ break;
+ case 'i':
+ case 'y':
+ cflags |= RE.REG_ICASE;
+ break;
+ case 'l':
+ options[FILES_WITH_MATCHES] = true;
+ break;
+ case 'n':
+ options[LINE_NUMBER] = true;
+ break;
+ case 'q':
+ options[QUIET] = true;
+ break;
+ case 's':
+ options[SILENT] = true;
+ break;
+ case 'v':
+ options[REVERT_MATCH] = true;
+ break;
+ case 'x':
+ options[LINE_REGEXP] = true;
+ break;
+ case 'E': // TODO: check compatibility with grep
+ syntax = RESyntax.RE_SYNTAX_EGREP;
+ break;
+ case 'F': // TODO: fixed strings
+ break;
+ case 'G':
+ syntax = RESyntax.RE_SYNTAX_GREP;
+ break;
+ case 'L':
+ options[FILES_WITHOUT_MATCH] = true;
+ break;
+ case 'V':
+ System.err.println(PROGNAME+' '+PROGVERSION);
+ return 0;
+ case 'z':
+ options[EXPAND_ZIP_FILES] = true;
+ break;
+ case 'N':
+ encoding = g.getOptarg();
+ try { // try out this encoding now. If not found, fall back to default
+ "".getBytes(encoding);
+ } catch (UnsupportedEncodingException uee) {
+ System.err.println(PROGNAME+": (Warning)"
+ + " Unsupported Encoding: " + encoding
+ + "; reverting to default");
+ encoding = null;
+ }
+ break;
+ case '!': // help
+ try {
+ BufferedReader br = new BufferedReader(new InputStreamReader((Grep.class).getResourceAsStream("GrepUsage.txt"),"UTF8"));
+ String line;
+ while ((line = br.readLine()) != null)
+ out.println(line);
+ } catch (IOException ie) { }
+ return 0;
+ }
+ }
+
+ InputStream is = null;
+ RE pattern = null;
+ if (g.getOptind() >= argv.length) {
+ System.err.println("Usage: java " + PROGNAME + " [OPTION]... PATTERN [FILE]...");
+ System.err.println("Try `java " + PROGNAME + " --help' for more information.");
+ return 2;
+ }
+ try {
+ pattern = new RE(argv[g.getOptind()],cflags,syntax);
+ } catch (REException e) {
+ System.err.println("Error in expression: "+e);
+ return 2;
+ }
+
+ boolean notFound = true;
+ if (argv.length >= g.getOptind()+2) {
+ for (int i = g.getOptind() + 1; i < argv.length; i++) {
+ boolean no_filename = (argv.length == g.getOptind()+2)
+ || options[NO_FILENAME];
+ if (argv[i].equals("-")) {
+ final String filename = no_filename ? null : "(standard input)";
+ if (processStream(pattern,System.in,encoding,options,filename,null,out))
+ notFound = false;
+ } else {
+ final String filename = no_filename ? null : argv[i];
+ try {
+ File file = new File(argv[i]);
+ if(file.isDirectory()) {
+ System.err.println(PROGNAME + ": " + argv[i] + ": Is a directory");
+ } else if(!file.canRead()) {
+ System.err.println(PROGNAME + ": " + argv[i] + ": Permission denied");
+ } else if (options[EXPAND_ZIP_FILES] && argv[i].endsWith(".zip")) {
+ // iterate over all files within this ZIP file
+ try {
+ ZipFile zf = new ZipFile(file);
+ Enumeration list = zf.entries();
+ while (list.hasMoreElements()) {
+ ZipEntry ze = (ZipEntry) list.nextElement();
+ if (! ze.isDirectory()) {
+ if (processStream(pattern, zf.getInputStream(ze), encoding, options, filename, ze.getName(), out))
+ notFound = false;
+ }
+ }
+ } catch (Exception ex) {
+ System.err.println(PROGNAME + ": " + argv[i] + ": Problem reading ZIP file");
+ return 2;
+ }
+ } else {
+ if (processStream(pattern,
+ new FileInputStream(argv[i]),
+ encoding, options, filename, null, out))
+ notFound = false;
+ }
+ } catch (FileNotFoundException e) {
+ if (!options[SILENT])
+ System.err.println(PROGNAME+": "+e);
+ }
+ }
+ }
+ } else {
+ if (processStream(pattern,System.in,encoding,options,null,null,out))
+ notFound = false;
+ }
+ return notFound ? 1 : 0;
+ }
+
+ private static boolean processStream(RE pattern, InputStream is,
+ String encoding, boolean[] options,
+ String filename, String zipName,
+ PrintStream out) {
+ try {
+ final InputStreamReader isr = encoding == null?
+ new InputStreamReader(is) : new InputStreamReader(is,encoding);
+ final BufferedReader r = new BufferedReader(isr);
+ return processReader(pattern, r, options, filename, zipName, out);
+ } catch (UnsupportedEncodingException uee) {
+ /* since grep() should have checked that the 'encoding' parameter
+ is valid, it should be impossible that this exception would
+ happen. Of, sso, it is a logic error.
+ */
+ throw new Error(PROGNAME + ": programming logic error");
+ }
+ }
+
+ private static String fileNameString (String fileName, String zipName) {
+ if (zipName == null)
+ return fileName;
+ else
+ return zipName + " in " + fileName;
+ }
+
+ private static boolean processReader(RE pattern,
+ BufferedReader br,
+ boolean[] options, String filename,
+ String zipName, PrintStream out) {
+
+ int newlineLen = System.getProperty("line.separator").length();
+ int count = 0;
+ long atByte = 0;
+ int atLine = 1;
+ String line;
+ REMatch match;
+
+ try {
+ while ((line = br.readLine()) != null) {
+ match = pattern.getMatch(line);
+ if (((options[LINE_REGEXP] && pattern.isMatch(line))
+ || (!options[LINE_REGEXP] && (match != null)))
+ ^ options[REVERT_MATCH]) {
+ count++;
+ if (!options[COUNT]) {
+ if (options[QUIET]) {
+ return true;
+ }
+ if (options[FILES_WITH_MATCHES]) {
+ if (filename != null)
+ out.println(fileNameString(filename, zipName));
+ return true;
+ }
+ if (options[FILES_WITHOUT_MATCH]) {
+ return false;
+ }
+ if (filename != null) {
+ out.print(fileNameString(filename, zipName));
+ out.print(':');
+ }
+ if (options[LINE_NUMBER]) {
+ out.print(atLine);
+ out.print(':');
+ }
+ if (options[BYTE_OFFSET]) {
+ out.print(atByte + match.getStartIndex() );
+ out.print(':');
+ }
+ out.println(line);
+ }
+ } // a match
+ atByte += line.length() + newlineLen; // could be troublesome...
+ atLine++;
+ } // a valid line
+ br.close();
+
+ if (options[COUNT]) {
+ if (filename != null)
+ out.println(fileNameString(filename, zipName)+':');
+ out.println(count);
+ }
+ if (options[FILES_WITHOUT_MATCH] && count==0) {
+ if (filename != null)
+ out.println(fileNameString(filename, zipName));
+ }
+ } catch (IOException e) {
+ System.err.println(PROGNAME+": "+e);
+ }
+ return ((count > 0) ^ options[REVERT_MATCH]);
+ }
+}
--- /dev/null
+Usage: java gnu.regexp.util.Grep [OPTION]... PATTERN [FILE] ...
+Search for PATTERN in each FILE or standard input.
+Most options same as GNU grep.
+
+Regexp selection and interpretation:
+ -E, --extended-regexp PATTERN is an extended regular expression
+ -G, --basic-regexp PATTERN is a basic regular expression
+ -i, --ignore-case ignore case distinctions
+Unsupported (may be available in a future release):
+ -e, --regexp=PATTERN use PATTERN as a regular expression
+ -f, --file=FILE obtain PATTERN from FILE
+ -F, --fixed-regexp PATTERN is a fixed string separated by newlines
+ -w, --word-regexp force PATTERN to match only whole words
+ -x, --line-regexp force PATTERN to match only whole lines
+
+Miscellaneous:
+ -s, --no-messages suppress error messages
+ -v, --revert-match select non-matching lines
+ -N, --encoding use the specified file encoding
+ -z, --zip expand ZIP files
+ -V, --version print version information and exit
+ --help display this help and exit
+
+Output control:
+ -b, --byte-offset print the byte offset with output lines
+ -n, --line-number print line number with output lines
+ -h, --no-filename suppress the prefixing filename on output
+ -q, --quiet, --silent suppress all normal output
+ -L, --files-without-match only print FILE names containing no match
+ -l, --files-with-matches only print FILE names containing matches
+ -c, --count only print a count of matching lines per FILE
+Unsupported (may be available in a future release):
+ -H, --with-filename print the filename for each match
+
+Context control:
+Unsupported (may be available in a future release):
+ -B, --before-context=NUM print NUM lines of leading context
+ -A, --after-context=NUM print NUM lines of trailing context
+ -NUM same as both -B NUM and -A NUM
+ -C, --context same as -2
+ -U, --binary do not strip CR characters at EOL (MSDOS)
+ -u, --unix-byte-offsets report offsets as if CRs were not there (MSDOS)
+
+With no FILE, or when FILE is -, read standard input. If less than
+two FILEs given, assume -h. Exit with 0 if matches, with 1 if none.
+Exit with 2 if syntax errors or system errors.
+
+Report bugs to <wes@cacas.org>.
--- /dev/null
+/*
+ * gnu/regexp/util/REApplet.java
+ * Copyright (C) 1998 Wes Biggs
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+package gnu.regexp.util;
+import java.applet.*;
+import java.awt.*;
+import gnu.regexp.*;
+
+/**
+ * This is a simple applet to demonstrate the capabilities of gnu.regexp.
+ * To run it, use appletviewer on the reapplet.html file included in the
+ * documentation directory.
+ *
+ * @author <A HREF="mailto:wes@cacas.org">Wes Biggs</A>
+ * @version 1.02
+ */
+public class REApplet extends Applet {
+ private Label l1, l2, l3, l4;
+ private Button b;
+ private TextField tf;
+ private TextArea input, output;
+ private Checkbox insens;
+ private Choice syntax;
+ private static String[] names = new String[] {
+ "awk", "ed", "egrep", "emacs", "grep", "POSIX awk", "POSIX basic",
+ "POSIX egrep", "POSIX extended", "POSIX minimal basic",
+ "POSIX minimal extended", "sed", "perl 4", "perl 4 (singe line)",
+ "perl 5", "perl 5 (single line)"
+ };
+
+ private static RESyntax[] values = new RESyntax[] {
+ new RESyntax(RESyntax.RE_SYNTAX_AWK).setLineSeparator("\n"),
+ new RESyntax(RESyntax.RE_SYNTAX_ED).setLineSeparator("\n"),
+ new RESyntax(RESyntax.RE_SYNTAX_EGREP).setLineSeparator("\n"),
+ new RESyntax(RESyntax.RE_SYNTAX_EMACS).setLineSeparator("\n"),
+ new RESyntax(RESyntax.RE_SYNTAX_GREP).setLineSeparator("\n"),
+ new RESyntax(RESyntax.RE_SYNTAX_POSIX_AWK).setLineSeparator("\n"),
+ new RESyntax(RESyntax.RE_SYNTAX_POSIX_BASIC).setLineSeparator("\n"),
+ new RESyntax(RESyntax.RE_SYNTAX_POSIX_EGREP).setLineSeparator("\n"),
+ new RESyntax(RESyntax.RE_SYNTAX_POSIX_EXTENDED).setLineSeparator("\n"),
+ new RESyntax(RESyntax.RE_SYNTAX_POSIX_MINIMAL_BASIC).setLineSeparator("\n"),
+ new RESyntax(RESyntax.RE_SYNTAX_POSIX_MINIMAL_EXTENDED).setLineSeparator("\n"),
+ new RESyntax(RESyntax.RE_SYNTAX_SED).setLineSeparator("\n"),
+ new RESyntax(RESyntax.RE_SYNTAX_PERL4).setLineSeparator("\n"),
+ new RESyntax(RESyntax.RE_SYNTAX_PERL4_S).setLineSeparator("\n"),
+ new RESyntax(RESyntax.RE_SYNTAX_PERL5).setLineSeparator("\n"),
+ new RESyntax(RESyntax.RE_SYNTAX_PERL5_S).setLineSeparator("\n")
+ };
+
+ /** Creates an REApplet. */
+ public REApplet() { super(); }
+
+ /** Initializes the applet and constructs GUI elements. */
+ public void init() {
+ // test run RE stuff to cache gnu.regexp.* classes.
+ try {
+ RE x = new RE("^.*(w[x])\1$");
+ REMatchEnumeration xx = x.getMatchEnumeration("wxwx");
+ while (xx.hasMoreMatches()) xx.nextMatch().toString();
+ } catch (REException arg) { }
+
+ setBackground(Color.lightGray);
+
+ /*
+ Layout looks like this:
+
+ [0,0:[0,0: Regular Expression] [1,0: Textbox]
+ [0,1: Expression Syntax] [1,1: [0,0: Choice] [1,0: Checkbox]]
+ [1,2: Button]]
+ [0,1: Input Text] [1,1: Match]
+ [0,2: Textarea] [1,2: Textarea]
+ */
+
+ GridBagLayout gbag = new GridBagLayout();
+ setLayout(gbag);
+ GridBagConstraints c = new GridBagConstraints();
+ Panel p = new Panel();
+ GridBagLayout gbag2 = new GridBagLayout();
+ p.setLayout(gbag2);
+
+ c.anchor = GridBagConstraints.WEST;
+ c.weightx = 1.0;
+
+ // [0,0: Regular Expression]
+ c.gridx = 0;
+ c.gridy = 0;
+ l1 = new Label("Regular Expression");
+ gbag2.setConstraints(l1,c);
+ p.add(l1);
+
+ // [1,0: TextField]
+ c.gridx = 1;
+ tf = new TextField(getParameter("regexp"),30);
+ gbag2.setConstraints(tf,c);
+ p.add(tf);
+
+ // [0,1: Expression Syntax]
+ c.gridx = 0;
+ c.gridy = 1;
+ l4 = new Label("Expression Syntax");
+ gbag2.setConstraints(l4,c);
+ p.add(l4);
+
+ // [1,1: subpanel]
+ Panel p2 = new Panel();
+ GridBagLayout gbag3 = new GridBagLayout();
+ p2.setLayout(gbag3);
+ c.gridx = 1;
+ gbag2.setConstraints(p2,c);
+ p.add(p2);
+
+ // Subpanel [0,0: Choice]
+ c.gridx = 0;
+ c.gridy = 0;
+ syntax = new Choice();
+ for (int i = 0; i < names.length; i++) syntax.addItem(names[i]);
+ String zz = getParameter("syntax");
+ if (zz != null) {
+ try {
+ syntax.select(getParameter("syntax"));
+ } catch (IllegalArgumentException e) { }
+ }
+
+ gbag3.setConstraints(syntax,c);
+ p2.add(syntax);
+
+ c.gridx = 1;
+ insens = new Checkbox("Ignore case",false);
+ gbag3.setConstraints(insens,c);
+ p2.add(insens);
+
+ // Next Row
+ c.gridx = 1;
+ c.gridy = 2;
+ b = new Button("Match");
+ gbag2.setConstraints(b,c);
+ p.add(b);
+
+ // Add the entire upper panel.
+ c.gridwidth = 2;
+ c.gridheight = 1;
+ c.gridx = 0;
+ c.gridy = 0;
+ c.anchor = GridBagConstraints.CENTER;
+ gbag.setConstraints(p,c);
+ add(p);
+
+ c.gridwidth = 1;
+ c.gridheight = 1;
+
+ // Main: [0,1]:
+ l2 = new Label("Input Text");
+ c.gridwidth = 1;
+ c.gridx = 0;
+ c.gridy = 1;
+ gbag.setConstraints(l2,c);
+ add(l2);
+
+ l3 = new Label("Matches Found");
+ c.gridx = 1;
+ gbag.setConstraints(l3,c);
+ add(l3);
+
+ input = new TextArea(getParameter("input"),5,30);
+ c.gridx = 0;
+ c.gridy = 2;
+ gbag.setConstraints(input,c);
+ add(input);
+
+ c.gridx = 1;
+ output = new TextArea(5,30);
+ output.setEditable(false);
+ c.gridwidth = GridBagConstraints.REMAINDER;
+ gbag.setConstraints(output,c);
+ add(output);
+ }
+
+ /**
+ * Handles events in the applet. Returns true if the indicated event
+ * was handled, false for all other events.
+ */
+ public boolean action(Event e, Object arg) {
+ Object target = e.target;
+
+ if (target == b) { // match
+ try {
+ String expr = tf.getText();
+ RE reg = null;
+ RESyntax res = values[syntax.getSelectedIndex()];
+ reg = new RE(expr,insens.getState() ? RE.REG_ICASE | RE.REG_MULTILINE : RE.REG_MULTILINE, res);
+ REMatchEnumeration en = reg.getMatchEnumeration(input.getText());
+ StringBuffer sb = new StringBuffer();
+ int matchNum = 0;
+ while (en.hasMoreMatches()) {
+ sb.append(String.valueOf(++matchNum));
+ sb.append(". ");
+ sb.append(en.nextMatch().toString());
+ sb.append('\n');
+ }
+ output.setText(sb.toString());
+ } catch (REException err) {
+ output.setText("Expression compilation error: " + err.getMessage());
+ }
+ return true;
+ } else return false;
+ }
+}
--- /dev/null
+/*
+ * gnu/regexp/util/RETest.java
+ * Copyright (C) 1998-2001 Wes Biggs
+ *
+ * This file is in the public domain. However, the gnu.regexp library
+ * proper is licensed under the terms of the GNU Lesser General Public
+ * License (see the file COPYING.LIB for details).
+ */
+package gnu.regexp.util;
+import gnu.regexp.*;
+
+/**
+ * RETest provides a simple way to test regular expressions.
+ * It runs from the command line using the Java interpreter.
+ * To use it, enter the following from a command prompt (provided
+ * that the Java system knows where to find the RETest bytecodes):
+ * <BR><CODE>java gnu.regexp.util.RETest [regExp] [inputString]</CODE><BR>
+ * where <i>regExp</i> is a regular expression (you'll probably have
+ * to escape shell meta-characters) and <i>inputString</i> is the string
+ * to match against (again, put it in quotes or escape any shell meta-
+ * characters).
+ * <P>
+ * The test function will report the package version number, whether
+ * the expression matches the input string, what the match it found was,
+ * and the contents of any subexpressions, if applicable.
+ * <P>
+ * You may optionally add a third integer argument which is the number of
+ * times to repeat the test. When this option is used, RETest will report
+ * average compile and match times.
+ *
+ * @author <A HREF="mailto:wes@cacas.org">Wes Biggs</A>
+ * @version 1.01
+ */
+public class RETest {
+ private RETest() { }
+
+ /**
+ * Invokes the test function with the command line arguments specified.
+ * See class description for usage notes.
+ *
+ * @param argv
+ * The command line arguments.
+ *
+ * @exception REException
+ * There was an error compiling or executing the regular expression.
+ */
+ public static void main(String argv[]) throws REException {
+ System.out.println("gnu.regexp version "+RE.version());
+
+ int numRepeats = 1;
+ if (argv.length == 3)
+ numRepeats = Integer.parseInt(argv[2]);
+ if (argv.length < 2) {
+ System.out.println("usage: java gnu.regexp.util.RETest regExp inputString [numRepeats]");
+ System.exit(1);
+ }
+
+ // Construct the regular expression
+
+ RE expression = null;
+ long begin = System.currentTimeMillis();
+
+ for (int rpt = 0; rpt < numRepeats; rpt++)
+ expression = new RE(argv[0]);
+
+ long end = System.currentTimeMillis();
+
+ if (numRepeats>1) {
+ System.out.println("Compiling "+numRepeats+" times took "+(end-begin)+" ms");
+ System.out.println("Average compile time: "+((end-begin)/numRepeats)+" ms");
+ }
+
+ // Display regular expression
+ System.out.println(" Input Text: "+argv[1]);
+ System.out.println("Regular Expression: "+argv[0]);
+ System.out.println(" Compiled Form: "+expression);
+ System.out.println(" Minimum Length: "+expression.getMinimumLength());
+
+ // Is the input in its entirety a match?
+ System.out.println(" isMatch() returns: "+expression.isMatch(argv[1]));
+
+ REMatch[] matches = expression.getAllMatches(argv[1]);
+ System.out.println(" getAllMatches(): " + matches.length + " matches");
+ for (int i = 0; i < matches.length; i++) {
+ System.out.println("Match " + i + " (" + matches[i].getStartIndex()
+ + "," + matches[i].getEndIndex() + "): "
+ + matches[i]);
+ }
+
+ // Get the first match
+ REMatch match = null;
+
+ begin = System.currentTimeMillis();
+
+ for (int rpt = 0; rpt < numRepeats; rpt++)
+ match = expression.getMatch(argv[1]);
+
+ end = System.currentTimeMillis();
+
+ if (numRepeats>1) {
+ System.out.println("Finding first match "+numRepeats+" times took "+(end-begin)+" ms");
+ System.out.println("Average match time: "+((end-begin)/numRepeats)+" ms");
+ }
+
+ if (match == null)
+ System.out.println("Expression did not find a match.");
+ else {
+ // Report the full match indices
+
+ System.out.println("Match found from position "
+ + match.getStartIndex() + " to position "
+ + match.getEndIndex());
+
+ // Take advantage of REMatch.toString() to print match text
+
+ System.out.println("Match was: '" + match + "'");
+
+ // Report subexpression positions
+
+ for (int i=1; i <= expression.getNumSubs(); i++) {
+ if (match.getStartIndex(i) > -1) {
+ System.out.println("Subexpression #" + i + ": from position "
+ + match.getStartIndex(i) + " to position "
+ + match.getEndIndex(i));
+
+ // Note how the $n is constructed for substituteInto
+
+ System.out.println(match.substituteInto("The subexpression matched this text: '$"+i+"'"));
+ }
+ }
+ }
+
+ // Here's a substitute test.
+ System.out.println("substitute(): " + expression.substitute(argv[1],"<!--$0-->"));
+ System.out.println("substituteAll(): " + expression.substituteAll(argv[1],"<!--$0-->"));
+ }
+}
--- /dev/null
+/*
+ * gnu/regexp/util/Tests.java -- Simple testsuite for gnu.regexp package
+ * Copyright (C) 1998-2001 Wes Biggs
+ *
+ * This file is in the public domain. However, the gnu.regexp library
+ * proper is licensed under the terms of the GNU Lesser General Public
+ * License (see the file COPYING.LIB for details).
+ */
+
+package gnu.regexp.util;
+import gnu.regexp.*;
+import java.io.StringBufferInputStream;
+import java.io.StringReader;
+
+/**
+ * This is a very basic testsuite application for gnu.regexp.
+ *
+ * @author <A HREF="mailto:wes@cacas.org">Wes Biggs</A>
+ * @version 1.1.1
+ */
+public class Tests {
+ private Tests() { }
+
+ private static void check(RE expr, String input, String expect, int id) {
+ // Test it using all possible input types
+ check(expr.getMatch(input),expect,id, "String");
+ check(expr.getMatch(new StringBuffer(input)),expect,id, "StringBuffer");
+ check(expr.getMatch(input.toCharArray()),expect,id, "char[]");
+ check(expr.getMatch(new StringReader(input)),expect,id, "Reader");
+ check(expr.getMatch(new StringBufferInputStream(input)),expect,id, "InputStream");
+ }
+ private static void check(REMatch m, String expect, int x, String type) {
+ if ((m == null) || !m.toString().equals(expect)) System.out.print("*** Failed");
+ else System.out.print("Passed");
+ System.out.println(" test #"+x + " (" + type + ")");
+ }
+
+ /**
+ * Runs the testsuite. No command line arguments are necessary.
+ *
+ * @exception REException An error occurred compiling a regular expression.
+ */
+ public static void main(String[] argv) throws REException {
+ RE e;
+
+
+ e = new RE("(.*)z");
+ check(e,("xxz"),"xxz",1);
+
+ e = new RE(".*z");
+ check(e,("xxz"),"xxz",2);
+
+ e = new RE("(x|xy)z");
+ check(e,("xz"),"xz",3);
+ check(e,("xyz"),"xyz",4);
+
+ e = new RE("(x)+z");
+ check(e,("xxz"),"xxz",5);
+
+ e = new RE("abc");
+ check(e,("xyzabcdef"),"abc",6);
+
+ e = new RE("^start.*end$");
+ check(e,("start here and go to the end"),"start here and go to the end",7);
+
+ e = new RE("(x|xy)+z");
+ check(e,("xxyz"),"xxyz",8);
+
+ e = new RE("type=([^ \t]+)[ \t]+exts=([^ \t\n\r]+)");
+ check(e,("type=text/html exts=htm,html"),"type=text/html exts=htm,html",9);
+
+ e = new RE("(x)\\1");
+ check(e,("zxxz"),"xx", 10);
+
+ e = new RE("(x*)(y)\\2\\1");
+ check(e,("xxxyyxx"),"xxyyxx",11);
+
+ e = new RE("[-go]+");
+ check(e,("go-go"),"go-go",12);
+
+ e = new RE("[\\w-]+");
+ check(e,("go-go"),"go-go",13);
+
+ e = new RE("^start.*?end");
+ check(e,("start here and end in the middle, not the very end"),"start here and end",14);
+
+ e = new RE("\\d\\s\\w\\n\\r");
+ check(e,(" 9\tX\n\r "),"9\tX\n\r",15);
+
+ e = new RE("zow",RE.REG_ICASE);
+ check(e,("ZoW"),"ZoW",16);
+
+ e = new RE("(\\d+)\\D*(\\d+)\\D*(\\d)+");
+ check(e,("size--10 by 20 by 30 feet"),"10 by 20 by 30",17);
+
+ e = new RE("(ab)(.*?)(d)");
+ REMatch m = e.getMatch("abcd");
+ check(m,"abcd",18, "String");
+ System.out.println(((m.toString(2).equals("c")) ? "Pass" : "*** Fail")
+ + "ed test #19");
+
+ e = new RE("^$");
+ check(e,(""),"",20);
+
+ e = new RE("a*");
+ check(e,(""),"",21);
+ check(e,("a"),"a",22);
+ check(e,("aa"),"aa",23);
+
+ e = new RE("(([12]))?");
+ check(e,("12"),"1",24);
+
+ e = new RE("(.*)?b");
+ check(e,("ab"),"ab",25);
+
+ e = new RE("(.*)?-(.*)");
+ check(e,("a-b"), "a-b", 26);
+
+ e = new RE("(a)b");
+ check(e,("aab"), "ab", 27);
+
+ e = new RE("[M]iss");
+ check(e,("one Mississippi"), "Miss", 28);
+
+ e = new RE("\\S Miss");
+ check(e,("one Mississippi"), "e Miss", 29);
+
+ e = new RE("a*");
+ check(e,("b"),"",30);
+ check(e,("ab"),"a",31);
+ check(e,("aab"),"aa",32);
+
+ // Single character should match anywhere in String
+ e = new RE("a");
+ check(e,("a"),"a", 33);
+ check(e,("ab"),"a", 34);
+ check(e,("ba"),"a", 35);
+ check(e,("bab"),"a", 36);
+
+ }
+}
--- /dev/null
+--- javaDependencies.pl.in Mon Jan 26 20:17:37 2004
++++ javaDependencies.pl.in Mon Jan 26 20:17:54 2004
+@@ -85,8 +85,8 @@
+ my ($magic, $minor, $major) = unpack("Nnn", $buff);
+
+ die "Wrong magic $magic" if $magic != 0xcafebabe;
+- die "Wrong minor $minor" if $minor > 3;
+- die "Wrong minor $major" if $major != 45;
++# die "Wrong minor $minor" if $minor > 3;
++# die "Wrong minor $major" if $major != 45;
+
+ readInBuff 2 or die "Can't read cpool length";
+
--- /dev/null
+--- jode/obfuscator/ClassIdentifier.java.in Sun Aug 12 11:24:14 2001
++++ jode/obfuscator/ClassIdentifier.java.in Mon Jan 26 19:08:36 2004
+@@ -478,6 +478,7 @@
+ ClassIdentifier ancestor = this;
+ while(true) {
+ addIfaces(newIfaces, ancestor);
++ if (ancestor.superName == null) break;
+ ClassIdentifier superident
+ = Main.getClassBundle().getClassIdentifier(ancestor.superName);
+ if (superident == null || superident.isReachable())
--- /dev/null
+--- ../libmspack.orig/mspack/Makefile Sat Jul 26 10:44:57 2003
++++ mspack/Makefile Sun Nov 2 17:12:35 2003
+@@ -1,12 +1,13 @@
+ CC=gcc
+ RM=rm -f
+ AR=ar
++RANLIB=ranlib
+
+ WARNINGS=-Wall -Wsign-compare -Wconversion -pedantic
+ LARGEFILE=-std=c99 -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
+ DEBUG=-g -DDEBUG
+ OPTIM=-O3
+-CFLAGS= $(WARNINGS) $(LARGEFILE) $(DEBUG) $(OPTIM) -I.
++CFLAGS= $(WARNINGS) $(LARGEFILE) $(DEBUG) $(OPTIM) -I. -DMSPACK_NO_DEFAULT_SYSTEM
+
+ all: libmspack.a
+
+@@ -27,6 +28,7 @@
+ libmspack.a: $(OBJS)
+ -$(RM) $@
+ $(AR) q $@ $(OBJS)
++ $(RANLIB) $@
+
+ .c.o:
+ $(CC) $(CFLAGS) -o $@ -c $<
--- /dev/null
+diff -ru ../newlib-1.11.0.orig/libgloss/configure ./libgloss/configure
+--- ../newlib-1.11.0.orig/libgloss/configure Fri Oct 25 14:35:21 2002
++++ ./libgloss/configure Sun Aug 31 06:51:40 2003
+@@ -762,6 +762,9 @@
+ mips*-*-pe)
+ configdirs="wince"
+ ;;
++ mips*-unknown-elf*)
++ configdirs="${configdirs}"
++ ;;
+ mips*-*-*)
+ configdirs="${configdirs} mips testsuite"
+ ;;
+@@ -818,7 +821,7 @@
+ # Extract the first word of "gcc", so it can be a program name with args.
+ set dummy gcc; ac_word=$2
+ echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+-echo "configure:822: checking for $ac_word" >&5
++echo "configure:825: checking for $ac_word" >&5
+ if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+ else
+@@ -848,7 +851,7 @@
+ # Extract the first word of "cc", so it can be a program name with args.
+ set dummy cc; ac_word=$2
+ echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+-echo "configure:852: checking for $ac_word" >&5
++echo "configure:855: checking for $ac_word" >&5
+ if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+ else
+@@ -897,7 +900,7 @@
+ fi
+
+ echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+-echo "configure:901: checking whether we are using GNU C" >&5
++echo "configure:904: checking whether we are using GNU C" >&5
+ if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+ else
+@@ -906,7 +909,7 @@
+ yes;
+ #endif
+ EOF
+-if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:910: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
++if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:913: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ ac_cv_prog_gcc=yes
+ else
+ ac_cv_prog_gcc=no
+@@ -921,7 +924,7 @@
+ ac_save_CFLAGS="$CFLAGS"
+ CFLAGS=
+ echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+-echo "configure:925: checking whether ${CC-cc} accepts -g" >&5
++echo "configure:928: checking whether ${CC-cc} accepts -g" >&5
+ if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+ else
+@@ -953,7 +956,7 @@
+ # Extract the first word of "ar", so it can be a program name with args.
+ set dummy ar; ac_word=$2
+ echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+-echo "configure:957: checking for $ac_word" >&5
++echo "configure:960: checking for $ac_word" >&5
+ if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+ else
+@@ -987,7 +990,7 @@
+ # Extract the first word of "ranlib", so it can be a program name with args.
+ set dummy ranlib; ac_word=$2
+ echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+-echo "configure:991: checking for $ac_word" >&5
++echo "configure:994: checking for $ac_word" >&5
+ if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+ else
+diff -ru ../newlib-1.11.0.orig/libgloss/configure.in ./libgloss/configure.in
+--- ../newlib-1.11.0.orig/libgloss/configure.in Fri Oct 25 14:35:21 2002
++++ ./libgloss/configure.in Sun Aug 31 06:44:47 2003
+@@ -73,6 +73,9 @@
+ mips*-*-pe)
+ configdirs="wince"
+ ;;
++ mips*-unknown-elf*)
++ configdirs="${configdirs}"
++ ;;
+ mips*-*-*)
+ configdirs="${configdirs} mips testsuite"
+ ;;
+Only in ./libgloss: configure.in~
+Only in ./libgloss: configure.old
+diff -ru ../newlib-1.11.0.orig/newlib/configure.host ./newlib/configure.host
+--- ../newlib-1.11.0.orig/newlib/configure.host Thu Dec 19 21:32:43 2002
++++ ./newlib/configure.host Fri Sep 5 18:26:20 2003
+@@ -508,6 +508,10 @@
+ newlib_cflags="${newlib_cflags}"
+ syscall_dir=syscalls
+ ;;
++ mips*-unknown-elf*)
++ newlib_cflags="${newlib_cflags} -DREENTRANT_SYSCALLS_PROVIDED"
++ syscall_dir=syscalls
++ ;;
+ mmix-*)
+ syscall_dir=syscalls
+ # We need every symbol 32-bit aligned, so the invalid
+Only in ./newlib: configure.host~
+Only in ./newlib/libc/stdlib: mprec.c
--- /dev/null
+JAVAC = javac
+sources = $(shell find src -name '*.java')
+classes = $(sources:src/%.java=build/%.class)
+dats = org/ibex/net/ssl/rootcerts.dat
+
+jar_sources = \
+ $(shell find src/org/ibex/crypto -name '*.java') \
+ src/org/ibex/net/SSL.java \
+ src/org/ibex/net/ssl/RootCerts.java
+jar_classes = $(jar_sources:src/%.java=build/%.class)
+jar = BriSSL.jar
+
+all: $(classes) $(dats:%=build/%)
+
+$(classes): $(sources)
+ @mkdir -p build
+ $(JAVAC) -d build $(sources)
+
+build/%.dat: src/%.dat
+ @mkdir -p `dirname $@`
+ cp $^ $@
+
+$(jar): $(classes)
+ cd build && jar cf ../$@ $(jar_classes:build/%.class=%*.class)
+
+test: all
+ java -cp build org.ibex.net.ssl.Test www.paypal.com 443
+
+clean:
+ rm -rf build/*
+
+# This stuff is only for Brian to use
+# We should probably verify this file somehow
+tmp/.havecacertrs:
+ @mkdir -p tmp
+ wget -O - http://ftp.debian.org/debian/pool/main/c/ca-certificates/ca-certificates_20020323.tar.gz | gzip -dc | tar -C tmp -xf-
+ cd tmp/ca-certificates/mozilla && \
+ make all \
+ for f in *.pem; do \
+ openssl x509 -in "$$f" -out "$$f.der" -outform der; \
+ done
+ touch $@
+
+update-rootcerts: tmp/.havecacerts src/org/ibex/net/ssl/GenCompactCAList.java
+ java -cp build org.ibex.net.ssl.GenCompactCAList binary tmp/ca-certificates/mozilla/*.der > src/org/ibex/net/ssl/rootcerts.dat
+ java -cp build org.ibex.net.ssl.GenCompactCAList class tmp/ca-certificates/mozilla/*.der > src/org/ibex/net/ssl/RootCerts.java
+
+sizecheck:
+ @for c in $(jar_classes); do \
+ for f in `echo $$c|sed 's,\.class$$,,;'`*.class; do gzip -c $$f; done | wc -c | tr -d '\n'; \
+ echo -e "\t`echo $$c | sed 's,build/org/ibex,,;s,\.class$$,,;s,/,.,g;'`"; \
+ done | sort -rn | awk '{ sum += $$1; print } END { print sum,"Total"; }'
--- /dev/null
+src/com/brian_web/*
+-------------------
+src/com/brian_web/net/SSL.java is Copyright 2004 Brian Alliet and
+Copyright 2003 Adam Megacz. It is released under the GNU Lesser
+General Public License with the exception of the portion of clause 6a
+after the semicolon (aka the "obnoxious relink clause")
+
+src/com/brian_web/{x509,der} are Copyright 2004 Brian Alliet and
+Copyright 2000 The Legion Of The Bouncy Castle
+(http://www.bouncycastle.org) and is released under the Bouncy
+Castle License below.
+
+The rest of src/com/brian_web is Copyright 2004 Brian Alliet
+are released under the GNU Lesser General Public License (below).
+
+src/org/bouncycastle/*
+----------------------
+src/org/bouncycastle is Copyright 2000 The Legion Of The Bouncy Castle
+(http://www.bouncycastle.org) and is released under the following license:
+
+-- Bouncy Castle License --
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to
+deal in the Software without restriction, including without limitation the
+rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN THE SOFTWARE.
+-- End --
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+\f
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+\f
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+\f
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+\f
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+\f
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+\f
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+\f
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+\f
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+\f
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
+
+
--- /dev/null
+package org.ibex.crypto;
+
+public class Base36 {
+ public static String encode(long l) {
+ StringBuffer ret = new StringBuffer();
+ while (l > 0) {
+ if ((l % 36) < 10) ret.append((char)(((int)'0') + (int)(l % 36)));
+ else ret.append((char)(((int)'A') + (int)((l % 36) - 10)));
+ l /= 36;
+ }
+ return ret.toString();
+ }
+}
--- /dev/null
+package org.ibex.crypto;
+
+public class Base64
+{
+ private static final byte[] encodingTable =
+ {
+ (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G',
+ (byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L', (byte)'M', (byte)'N',
+ (byte)'O', (byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U',
+ (byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z',
+ (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g',
+ (byte)'h', (byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n',
+ (byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t', (byte)'u',
+ (byte)'v',
+ (byte)'w', (byte)'x', (byte)'y', (byte)'z',
+ (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6',
+ (byte)'7', (byte)'8', (byte)'9',
+ (byte)'+', (byte)'/'
+ };
+
+ /**
+ * encode the input data producong a base 64 encoded byte array.
+ *
+ * @return a byte array containing the base 64 encoded data.
+ */
+ public static byte[] encode(
+ byte[] data)
+ {
+ byte[] bytes;
+
+ int modulus = data.length % 3;
+ if (modulus == 0)
+ {
+ bytes = new byte[4 * data.length / 3];
+ }
+ else
+ {
+ bytes = new byte[4 * ((data.length / 3) + 1)];
+ }
+
+ int dataLength = (data.length - modulus);
+ int a1, a2, a3;
+ for (int i = 0, j = 0; i < dataLength; i += 3, j += 4)
+ {
+ a1 = data[i] & 0xff;
+ a2 = data[i + 1] & 0xff;
+ a3 = data[i + 2] & 0xff;
+
+ bytes[j] = encodingTable[(a1 >>> 2) & 0x3f];
+ bytes[j + 1] = encodingTable[((a1 << 4) | (a2 >>> 4)) & 0x3f];
+ bytes[j + 2] = encodingTable[((a2 << 2) | (a3 >>> 6)) & 0x3f];
+ bytes[j + 3] = encodingTable[a3 & 0x3f];
+ }
+
+ /*
+ * process the tail end.
+ */
+ int b1, b2, b3;
+ int d1, d2;
+
+ switch (modulus)
+ {
+ case 0: /* nothing left to do */
+ break;
+ case 1:
+ d1 = data[data.length - 1] & 0xff;
+ b1 = (d1 >>> 2) & 0x3f;
+ b2 = (d1 << 4) & 0x3f;
+
+ bytes[bytes.length - 4] = encodingTable[b1];
+ bytes[bytes.length - 3] = encodingTable[b2];
+ bytes[bytes.length - 2] = (byte)'=';
+ bytes[bytes.length - 1] = (byte)'=';
+ break;
+ case 2:
+ d1 = data[data.length - 2] & 0xff;
+ d2 = data[data.length - 1] & 0xff;
+
+ b1 = (d1 >>> 2) & 0x3f;
+ b2 = ((d1 << 4) | (d2 >>> 4)) & 0x3f;
+ b3 = (d2 << 2) & 0x3f;
+
+ bytes[bytes.length - 4] = encodingTable[b1];
+ bytes[bytes.length - 3] = encodingTable[b2];
+ bytes[bytes.length - 2] = encodingTable[b3];
+ bytes[bytes.length - 1] = (byte)'=';
+ break;
+ }
+
+ return bytes;
+ }
+
+ /*
+ * set up the decoding table.
+ */
+ private static final byte[] decodingTable;
+
+ static
+ {
+ decodingTable = new byte[128];
+
+ for (int i = 'A'; i <= 'Z'; i++)
+ {
+ decodingTable[i] = (byte)(i - 'A');
+ }
+
+ for (int i = 'a'; i <= 'z'; i++)
+ {
+ decodingTable[i] = (byte)(i - 'a' + 26);
+ }
+
+ for (int i = '0'; i <= '9'; i++)
+ {
+ decodingTable[i] = (byte)(i - '0' + 52);
+ }
+
+ decodingTable['+'] = 62;
+ decodingTable['/'] = 63;
+ }
+
+ /**
+ * decode the base 64 encoded input data.
+ *
+ * @return a byte array representing the decoded data.
+ */
+ public static byte[] decode(
+ byte[] data)
+ {
+ byte[] bytes;
+ byte b1, b2, b3, b4;
+
+ if (data[data.length - 2] == '=')
+ {
+ bytes = new byte[(((data.length / 4) - 1) * 3) + 1];
+ }
+ else if (data[data.length - 1] == '=')
+ {
+ bytes = new byte[(((data.length / 4) - 1) * 3) + 2];
+ }
+ else
+ {
+ bytes = new byte[((data.length / 4) * 3)];
+ }
+
+ for (int i = 0, j = 0; i < data.length - 4; i += 4, j += 3)
+ {
+ b1 = decodingTable[data[i]];
+ b2 = decodingTable[data[i + 1]];
+ b3 = decodingTable[data[i + 2]];
+ b4 = decodingTable[data[i + 3]];
+
+ bytes[j] = (byte)((b1 << 2) | (b2 >> 4));
+ bytes[j + 1] = (byte)((b2 << 4) | (b3 >> 2));
+ bytes[j + 2] = (byte)((b3 << 6) | b4);
+ }
+
+ if (data[data.length - 2] == '=')
+ {
+ b1 = decodingTable[data[data.length - 4]];
+ b2 = decodingTable[data[data.length - 3]];
+
+ bytes[bytes.length - 1] = (byte)((b1 << 2) | (b2 >> 4));
+ }
+ else if (data[data.length - 1] == '=')
+ {
+ b1 = decodingTable[data[data.length - 4]];
+ b2 = decodingTable[data[data.length - 3]];
+ b3 = decodingTable[data[data.length - 2]];
+
+ bytes[bytes.length - 2] = (byte)((b1 << 2) | (b2 >> 4));
+ bytes[bytes.length - 1] = (byte)((b2 << 4) | (b3 >> 2));
+ }
+ else
+ {
+ b1 = decodingTable[data[data.length - 4]];
+ b2 = decodingTable[data[data.length - 3]];
+ b3 = decodingTable[data[data.length - 2]];
+ b4 = decodingTable[data[data.length - 1]];
+
+ bytes[bytes.length - 3] = (byte)((b1 << 2) | (b2 >> 4));
+ bytes[bytes.length - 2] = (byte)((b2 << 4) | (b3 >> 2));
+ bytes[bytes.length - 1] = (byte)((b3 << 6) | b4);
+ }
+
+ return bytes;
+ }
+
+ /**
+ * decode the base 64 encoded String data.
+ *
+ * @return a byte array representing the decoded data.
+ */
+ public static byte[] decode(
+ String data)
+ {
+ byte[] bytes;
+ byte b1, b2, b3, b4;
+
+ if (data.charAt(data.length() - 2) == '=')
+ {
+ bytes = new byte[(((data.length() / 4) - 1) * 3) + 1];
+ }
+ else if (data.charAt(data.length() - 1) == '=')
+ {
+ bytes = new byte[(((data.length() / 4) - 1) * 3) + 2];
+ }
+ else
+ {
+ bytes = new byte[((data.length() / 4) * 3)];
+ }
+
+ for (int i = 0, j = 0; i < data.length() - 4; i += 4, j += 3)
+ {
+ b1 = decodingTable[data.charAt(i)];
+ b2 = decodingTable[data.charAt(i + 1)];
+ b3 = decodingTable[data.charAt(i + 2)];
+ b4 = decodingTable[data.charAt(i + 3)];
+
+ bytes[j] = (byte)((b1 << 2) | (b2 >> 4));
+ bytes[j + 1] = (byte)((b2 << 4) | (b3 >> 2));
+ bytes[j + 2] = (byte)((b3 << 6) | b4);
+ }
+
+ if (data.charAt(data.length() - 2) == '=')
+ {
+ b1 = decodingTable[data.charAt(data.length() - 4)];
+ b2 = decodingTable[data.charAt(data.length() - 3)];
+
+ bytes[bytes.length - 1] = (byte)((b1 << 2) | (b2 >> 4));
+ }
+ else if (data.charAt(data.length() - 1) == '=')
+ {
+ b1 = decodingTable[data.charAt(data.length() - 4)];
+ b2 = decodingTable[data.charAt(data.length() - 3)];
+ b3 = decodingTable[data.charAt(data.length() - 2)];
+
+ bytes[bytes.length - 2] = (byte)((b1 << 2) | (b2 >> 4));
+ bytes[bytes.length - 1] = (byte)((b2 << 4) | (b3 >> 2));
+ }
+ else
+ {
+ b1 = decodingTable[data.charAt(data.length() - 4)];
+ b2 = decodingTable[data.charAt(data.length() - 3)];
+ b3 = decodingTable[data.charAt(data.length() - 2)];
+ b4 = decodingTable[data.charAt(data.length() - 1)];
+
+ bytes[bytes.length - 3] = (byte)((b1 << 2) | (b2 >> 4));
+ bytes[bytes.length - 2] = (byte)((b2 << 4) | (b3 >> 2));
+ bytes[bytes.length - 1] = (byte)((b3 << 6) | b4);
+ }
+
+ return bytes;
+ }
+}
--- /dev/null
+/*
+ * org.ibex.der.* - By Brian Alliet
+ * Copyright (C) 2004 Brian Alliet
+ *
+ * Based on Bouncy Castle by The Legion Of The Bouncy Castle
+ * Copyright (c) 2000 The Legion Of The Bouncy Castle
+ * (http://www.bouncycastle.org)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDER.S BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+package org.ibex.crypto;
+import java.io.IOException;
+import java.io.*;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+import java.math.BigInteger;
+
+public class DER {
+ public static class Null {
+ final static Null instance = new Null();
+ private Null() { /* noop */ }
+ public boolean equals(Object o) { return o == this; }
+ }
+
+ public static class TaggedObject {
+ public final Object object;
+ public final int tag;
+ public TaggedObject(int tag, Object object) { this.tag = tag; this.object = object; }
+ }
+
+ public static class UnknownObject {
+ public final byte[] data;
+ public final int tag;
+ public UnknownObject(int tag,byte[] data) { this.tag = tag; this.data = data; }
+ }
+
+ public static class BitString {
+ public final int paddingBits;
+ public final byte[] data;
+
+ public BitString(int paddingBits, byte[] data) {
+ this.paddingBits = paddingBits;
+ this.data = data;
+ }
+ }
+
+ public static class Exception extends java.io.IOException {
+ public Exception(String s) { super(s); }
+ }
+
+ public static class InputStream extends FilterInputStream {
+ private static final int MAX_OBJECT_SIZE = 4*1024*1024;
+
+ private int limit;
+ public int bytesLeft() { return limit < 0 ? Integer.MAX_VALUE : limit-pos; }
+ private int pos;
+ public int getPos() { return pos; }
+
+ // hack around gcj bug
+ public static DER.InputStream New(java.io.InputStream is) { return new DER.InputStream(is); }
+ public InputStream(java.io.InputStream is) { this(is,-1); }
+ public InputStream(java.io.InputStream is, int limit) {
+ super(is);
+ this.limit = limit;
+ }
+
+ public int read() throws IOException {
+ if(limit >= 0 && pos >= limit) return -1;
+ int n = super.read();
+ if(n != -1) {
+ pos++;
+ }
+ return n;
+ }
+
+ public int read(byte[] buf, int start, int len) throws IOException {
+ if(limit >= 0) {
+ if(pos >= limit) return -1;
+ len = Math.min(len,limit-pos);
+ }
+ int n = super.read(buf,start,len);
+ if(n != -1) {
+ pos += n;
+ }
+ return n;
+ }
+
+ protected void readFully(byte[] buf) throws IOException {
+ int pos = 0;
+ int left = buf.length;
+ while(left > 0) {
+ int n = read(buf,pos,left);
+ if(n == -1) throw new EOFException();
+ pos += n;
+ left -=n;
+ }
+ }
+
+ protected int readByte() throws IOException {
+ int n = read();
+ if(n == -1) throw new EOFException();
+ return n;
+ }
+
+ // From bouncycastle
+ private int readLength() throws IOException {
+ int length = read();
+ if (length < 0) throw new IOException("EOF found when length expected");
+ if (length == 0x80) return -1; // indefinite-length encoding
+ if (length > 127) {
+ int size = length & 0x7f;
+ length = 0;
+ for (int i = 0; i < size; i++) {
+ int next = read();
+ if (next < 0) throw new IOException("EOF found reading length");
+ length = (length << 8) + next;
+ }
+ }
+ return length;
+ }
+
+ public InputStream getSequenceStream() throws IOException {
+ int tag = readByte();
+ int length = readLength();
+ if(length < 0) throw new Exception("Indefinite length objects not supported");
+ if(tag != (CONSTRUCTED|0x10)) throw new Exception("Constructed Sequence expected");
+ return new InputStream(this,length);
+ }
+
+ private static final int CONSTRUCTED = 0x20;
+ public Object readObject() throws IOException {
+ int tag = readByte();
+ int length = readLength();
+ if(length < 0) throw new Exception("Indefinite length objects not supported");
+ if(length > MAX_OBJECT_SIZE) throw new Exception("Object too large");
+
+ switch(tag) {
+ case 0x01: return buildBoolean(length); // Boolean
+ case 0x02: return buildInteger(length); // Integer
+ case 0x03: return buildBitString(length); // Bit String
+ case 0x04: return buildOctetString(length); // Octet String
+ case 0x05: return Null.instance; // NULL
+ case 0x06: return buildObjectIdentifier(length); // Object Identifier
+
+ case 0x13: // PrintableString
+ // It is incorrect to treat this as an IA5String but the T.61 standard is way too old and backwards
+ // to be worth supporting
+ case 0x14: // T.61 String
+ case 0x16: // IA5String
+ return buildIA5String(length);
+ case 0x17: return buildTime(length,false);// UTC Time
+ case 0x18: return buildTime(length,true); // Generalizd Time
+
+ case CONSTRUCTED | 0x10: // Constructed Sequence
+ case CONSTRUCTED | 0x11: // Constructed Set
+ {
+ return buildSequence(length);
+ }
+ default: {
+ if((tag & 0x80) != 0) {
+ if ((tag & 0x1f) == 0x1f) throw new Exception("Unsupported high tag ecountered");
+ // tagged object - bottom 5 bits are tag
+ if(length == 0)
+ return new TaggedObject(tag&0x1,((tag & CONSTRUCTED) == 0) ? (Object)Null.instance : (Object)new Vector());
+ if((tag & CONSTRUCTED) == 0)
+ return new TaggedObject(tag&0x1f,buildOctetString(length));
+
+ InputStream dis = new InputStream(this,length);
+ Object o = dis.readObject();
+ if(dis.bytesLeft() == 0) return new TaggedObject(tag&0x1f,o);
+ Vector v = new Vector();
+ v.add(o);
+ return buildSequence(dis,v);
+ } else {
+ return new UnknownObject(tag,readBytes(length));
+ }
+ }
+ }
+ }
+
+ protected Vector buildSequence(int length) throws IOException { return buildSequence(new InputStream(this,length),new Vector()); }
+ protected Vector buildSequence(InputStream dis,Vector v) throws IOException {
+ try {
+ for(;;) v.add(dis.readObject());
+ } catch(EOFException e) {
+ return v;
+ }
+ }
+
+ protected byte[] readBytes(int length) throws IOException {
+ byte[] buf = new byte[length];
+ readFully(buf);
+ return buf;
+ }
+
+ protected BigInteger buildInteger(int length) throws IOException { return new BigInteger(readBytes(length)); }
+
+ // From bouncycastle
+ protected String buildObjectIdentifier(int length) throws IOException {
+ byte[] bytes = readBytes(length);
+ StringBuffer objId = new StringBuffer();
+ int value = 0;
+ boolean first = true;
+
+ for (int i = 0; i != bytes.length; i++)
+ {
+ int b = bytes[i] & 0xff;
+
+ value = value * 128 + (b & 0x7f);
+ if ((b & 0x80) == 0) // end of number reached
+ {
+ if (first)
+ {
+ switch (value / 40)
+ {
+ case 0:
+ objId.append('0');
+ break;
+ case 1:
+ objId.append('1');
+ value -= 40;
+ break;
+ default:
+ objId.append('2');
+ value -= 80;
+ }
+ first = false;
+ }
+
+ objId.append('.');
+ objId.append(Integer.toString(value));
+ value = 0;
+ }
+ }
+ return objId.toString();
+ }
+
+ protected String buildIA5String(int length) throws IOException {
+ byte[] buf = readBytes(length);
+ char[] buf2 = new char[buf.length];
+ for(int i=0;i<buf.length;i++) buf2[i] = (char)(buf[i]&0xff);
+ return new String(buf2);
+ }
+
+ private static final SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMddHHmmssz");
+ protected Date buildTime(int length, boolean generalized) throws IOException {
+ String s = buildIA5String(length);
+ if(!generalized && s.length() > 0) {
+ if(s.charAt(0) < '5') s = "20" + s;
+ else s = "19" + s;
+ }
+ switch(s.length()) {
+ case 13: s = s.substring(0,12) + "00GMT+00:00"; break; // YYYYMMDDhhmmZ
+ case 15: s = s.substring(0,14) + "GMT+00:00"; break; // YYYYMMDDhhmmssZ
+ case 17: s = s.substring(0,12) + "00GMT" + s.substring(12,15) + ":" + s.substring(15,17); break; // YYYYMMDDhhmm+hh'mm'
+ case 19: s = s.substring(0,14) + "GMT" + s.substring(14, 17) + ":" + s.substring(17, 19); // YYYYMMDDhhmmss+hh'mm'
+ default: throw new Exception("Unknown time format " + s);
+ }
+ try {
+ return dateF.parse(s);
+ } catch(ParseException e) {
+ throw new Exception("Coudln't parse time: " + e.getMessage());
+ }
+ }
+
+ protected BitString buildBitString(int length) throws IOException {
+ if(length < 1) throw new Exception("bit string too short");
+ int padding = read();
+ if(padding == -1) throw new IOException("unexpected eof");
+ return new BitString(padding,readBytes(length-1));
+ }
+
+ protected byte[] buildOctetString(int length) throws IOException { return readBytes(length); }
+
+ protected Boolean buildBoolean(int length) throws IOException {
+ byte[] bytes = readBytes(length);
+ return bytes[0] != 0 ? Boolean.TRUE : Boolean.FALSE;
+ }
+
+ /*
+ public static void main(String[] args) throws Exception {
+ InputStream is = new InputStream(new FileInputStream(args[0]));
+ try {
+ for(;;) dump(is.readObject(),"");
+ } catch(EOFException e) {
+ System.err.println("EOF");
+ }
+ }
+ public static void dump(Object o, String indent) {
+ if(o instanceof Vector) {
+ Vector v = (Vector) o;
+ System.out.println(indent + "Sequence/Set");
+ for(int i=0;i<v.size();i++) {
+ dump(v.elementAt(i),indent + i + ": ");
+ }
+ } else if(o instanceof TaggedObject){
+ dump(((TaggedObject)o).object,indent + "Tagged object: ");
+ } else if(o instanceof byte[]) {
+ System.err.println(indent + "<Byte Array>");
+ } else {
+ System.err.println(indent + o.toString());
+ }
+ }*/
+ }
+}
--- /dev/null
+/* Copyright (c) 2000 The Legion Of The Bouncy Castle
+ * (http://www.bouncycastle.org)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDER.S BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+package org.ibex.crypto;
+
+/**
+ * base implementation of MD4 family style digest as outlined in
+ * "Handbook of Applied Cryptography", pages 344 - 347.
+ */
+public abstract class Digest {
+ private byte[] xBuf;
+ private int xBufOff;
+ private long byteCount;
+
+ protected Digest() { xBuf = new byte[4]; xBufOff = 0; }
+ public void update(byte in) {
+ xBuf[xBufOff++] = in;
+ if (xBufOff == xBuf.length) {
+ processWord(xBuf, 0);
+ xBufOff = 0;
+ }
+ byteCount++;
+ }
+
+ public void update(byte[] in, int inOff, int len) {
+ // fill the current word
+ while ((xBufOff != 0) && (len > 0)) {
+ update(in[inOff]);
+ inOff++;
+ len--;
+ }
+
+ // process whole words.
+ while (len > xBuf.length) {
+ processWord(in, inOff);
+ inOff += xBuf.length;
+ len -= xBuf.length;
+ byteCount += xBuf.length;
+ }
+
+ // load in the remainder.
+ while (len > 0) {
+ update(in[inOff]);
+ inOff++;
+ len--;
+ }
+ }
+
+ protected void finish() {
+ long bitLength = (byteCount << 3);
+ // add the pad bytes.
+ update((byte)128);
+ while (xBufOff != 0) update((byte)0);
+ processLength(bitLength);
+ processBlock();
+ }
+
+ public void reset() {
+ byteCount = 0;
+ xBufOff = 0;
+ for ( int i = 0; i < xBuf.length; i++) xBuf[i] = 0;
+ }
+
+ protected abstract void processWord(byte[] in, int inOff);
+ protected abstract void processLength(long bitLength);
+ protected abstract void processBlock();
+ public abstract int getDigestSize();
+ public abstract void doFinal(byte[] out, int outOff);
+}
--- /dev/null
+package org.ibex.crypto;
+
+public class HMAC extends Digest {
+ private final Digest h;
+ private final byte[] digest;
+ private final byte[] k_ipad = new byte[64];
+ private final byte[] k_opad = new byte[64];
+
+ public int getDigestSize() { return h.getDigestSize(); }
+ public HMAC(Digest h, byte[] key) {
+ this.h = h;
+ if(key.length > 64) {
+ h.reset();
+ h.update(key,0,key.length);
+ key = new byte[h.getDigestSize()];
+ h.doFinal(key,0);
+ }
+ digest = new byte[h.getDigestSize()];
+ for(int i=0;i<64;i++) {
+ byte b = i < key.length ? key[i] : 0;
+ k_ipad[i] = (byte)(b ^ 0x36);
+ k_opad[i] = (byte)(b ^ 0x5C);
+ }
+ reset();
+ }
+ public void reset() {
+ h.reset();
+ h.update(k_ipad,0,64);
+ }
+ public void update(byte[] b, int off, int len) { h.update(b,off,len); }
+ public void doFinal(byte[] out, int off){
+ h.doFinal(digest,0);
+ h.update(k_opad,0,64);
+ h.update(digest,0,digest.length);
+ h.doFinal(out,off);
+ reset();
+ }
+ protected void processWord(byte[] in, int inOff) {}
+ protected void processLength(long bitLength) {}
+ protected void processBlock() {}
+}
--- /dev/null
+/* Copyright (c) 2000 The Legion Of The Bouncy Castle
+ * (http://www.bouncycastle.org)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDER.S BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+package org.ibex.crypto;
+
+/* implementation of MD2
+ * as outlined in RFC1319 by B.Kaliski from RSA Laboratories April 1992
+ */
+public class MD2 extends Digest
+{
+ private static final int DIGEST_LENGTH = 16;
+
+ /* X buffer */
+ private byte[] X = new byte[48];
+ private int xOff;
+ /* M buffer */
+ private byte[] M = new byte[16];
+ private int mOff;
+ /* check sum */
+ private byte[] C = new byte[16];
+ //private int COff;
+
+ public MD2()
+ {
+ reset();
+ }
+
+ /**
+ * return the size, in bytes, of the digest produced by this message digest.
+ *
+ * @return the size, in bytes, of the digest produced by this message digest.
+ */
+ public int getDigestSize()
+ {
+ return DIGEST_LENGTH;
+ }
+ /**
+ * close the digest, producing the final digest value. The doFinal
+ * call leaves the digest reset.
+ *
+ * @param out the array the digest is to be copied into.
+ * @param outOff the offset into the out array the digest is to start at.
+ */
+ public void doFinal(byte[] out, int outOff)
+ {
+ // add padding
+ byte paddingByte = (byte)(M.length-mOff);
+ for (int i=mOff;i<M.length;i++)
+ {
+ M[i] = paddingByte;
+ }
+ //do final check sum
+ processCheckSum(M);
+ // do final block process
+ processBlock(M);
+
+ processBlock(C);
+
+ System.arraycopy(X,xOff,out,outOff,16);
+
+ reset();
+ }
+ /**
+ * reset the digest back to it's initial state.
+ */
+ public void reset()
+ {
+ xOff = 0;
+ for (int i = 0; i != X.length; i++)
+ {
+ X[i] = 0;
+ }
+ mOff = 0;
+ for (int i = 0; i != M.length; i++)
+ {
+ M[i] = 0;
+ }
+ //COff = 0;
+ for (int i = 0; i != C.length; i++)
+ {
+ C[i] = 0;
+ }
+ }
+ /**
+ * update the message digest with a single byte.
+ *
+ * @param in the input byte to be entered.
+ */
+ public void update(byte in)
+ {
+ M[mOff++] = in;
+
+ if (mOff == 16)
+ {
+ processCheckSum(M);
+ processBlock(M);
+ mOff = 0;
+ }
+ }
+
+ /**
+ * update the message digest with a block of bytes.
+ *
+ * @param in the byte array containing the data.
+ * @param inOff the offset into the byte array where the data starts.
+ * @param len the length of the data.
+ */
+ public void update(byte[] in, int inOff, int len)
+ {
+ //
+ // fill the current word
+ //
+ while ((mOff != 0) && (len > 0))
+ {
+ update(in[inOff]);
+ inOff++;
+ len--;
+ }
+
+ //
+ // process whole words.
+ //
+ while (len > 16)
+ {
+ System.arraycopy(in,inOff,M,0,16);
+ processCheckSum(M);
+ processBlock(M);
+ len -= 16;
+ inOff += 16;
+ }
+
+ //
+ // load in the remainder.
+ //
+ while (len > 0)
+ {
+ update(in[inOff]);
+ inOff++;
+ len--;
+ }
+ }
+ protected void processCheckSum(byte[] m)
+ {
+ int L = C[15];
+ for (int i=0;i<16;i++)
+ {
+ C[i] ^= S[(m[i] ^ L) & 0xff];
+ L = C[i];
+ }
+ }
+ protected void processBlock(byte[] m)
+ {
+ for (int i=0;i<16;i++)
+ {
+ X[i+16] = m[i];
+ X[i+32] = (byte)(m[i] ^ X[i]);
+ }
+ // encrypt block
+ int t = 0;
+
+ for (int j=0;j<18;j++)
+ {
+ for (int k=0;k<48;k++)
+ {
+ t = X[k] ^= S[t];
+ t = t & 0xff;
+ }
+ t = (t + j)%256;
+ }
+ }
+ // 256-byte random permutation constructed from the digits of PI
+ private static final byte[] S = {
+ (byte)41,(byte)46,(byte)67,(byte)201,(byte)162,(byte)216,(byte)124,
+ (byte)1,(byte)61,(byte)54,(byte)84,(byte)161,(byte)236,(byte)240,
+ (byte)6,(byte)19,(byte)98,(byte)167,(byte)5,(byte)243,(byte)192,
+ (byte)199,(byte)115,(byte)140,(byte)152,(byte)147,(byte)43,(byte)217,
+ (byte)188,(byte)76,(byte)130,(byte)202,(byte)30,(byte)155,(byte)87,
+ (byte)60,(byte)253,(byte)212,(byte)224,(byte)22,(byte)103,(byte)66,
+ (byte)111,(byte)24,(byte)138,(byte)23,(byte)229,(byte)18,(byte)190,
+ (byte)78,(byte)196,(byte)214,(byte)218,(byte)158,(byte)222,(byte)73,
+ (byte)160,(byte)251,(byte)245,(byte)142,(byte)187,(byte)47,(byte)238,
+ (byte)122,(byte)169,(byte)104,(byte)121,(byte)145,(byte)21,(byte)178,
+ (byte)7,(byte)63,(byte)148,(byte)194,(byte)16,(byte)137,(byte)11,
+ (byte)34,(byte)95,(byte)33,(byte)128,(byte)127,(byte)93,(byte)154,
+ (byte)90,(byte)144,(byte)50,(byte)39,(byte)53,(byte)62,(byte)204,
+ (byte)231,(byte)191,(byte)247,(byte)151,(byte)3,(byte)255,(byte)25,
+ (byte)48,(byte)179,(byte)72,(byte)165,(byte)181,(byte)209,(byte)215,
+ (byte)94,(byte)146,(byte)42,(byte)172,(byte)86,(byte)170,(byte)198,
+ (byte)79,(byte)184,(byte)56,(byte)210,(byte)150,(byte)164,(byte)125,
+ (byte)182,(byte)118,(byte)252,(byte)107,(byte)226,(byte)156,(byte)116,
+ (byte)4,(byte)241,(byte)69,(byte)157,(byte)112,(byte)89,(byte)100,
+ (byte)113,(byte)135,(byte)32,(byte)134,(byte)91,(byte)207,(byte)101,
+ (byte)230,(byte)45,(byte)168,(byte)2,(byte)27,(byte)96,(byte)37,
+ (byte)173,(byte)174,(byte)176,(byte)185,(byte)246,(byte)28,(byte)70,
+ (byte)97,(byte)105,(byte)52,(byte)64,(byte)126,(byte)15,(byte)85,
+ (byte)71,(byte)163,(byte)35,(byte)221,(byte)81,(byte)175,(byte)58,
+ (byte)195,(byte)92,(byte)249,(byte)206,(byte)186,(byte)197,(byte)234,
+ (byte)38,(byte)44,(byte)83,(byte)13,(byte)110,(byte)133,(byte)40,
+ (byte)132, 9,(byte)211,(byte)223,(byte)205,(byte)244,(byte)65,
+ (byte)129,(byte)77,(byte)82,(byte)106,(byte)220,(byte)55,(byte)200,
+ (byte)108,(byte)193,(byte)171,(byte)250,(byte)36,(byte)225,(byte)123,
+ (byte)8,(byte)12,(byte)189,(byte)177,(byte)74,(byte)120,(byte)136,
+ (byte)149,(byte)139,(byte)227,(byte)99,(byte)232,(byte)109,(byte)233,
+ (byte)203,(byte)213,(byte)254,(byte)59,(byte)0,(byte)29,(byte)57,
+ (byte)242,(byte)239,(byte)183,(byte)14,(byte)102,(byte)88,(byte)208,
+ (byte)228,(byte)166,(byte)119,(byte)114,(byte)248,(byte)235,(byte)117,
+ (byte)75,(byte)10,(byte)49,(byte)68,(byte)80,(byte)180,(byte)143,
+ (byte)237,(byte)31,(byte)26,(byte)219,(byte)153,(byte)141,(byte)51,
+ (byte)159,(byte)17,(byte)131,(byte)20
+ };
+
+
+ protected void processWord(byte[] in, int inOff) {}
+ protected void processLength(long bitLength) {}
+ protected void processBlock() {}
+}
--- /dev/null
+/* Copyright (c) 2000 The Legion Of The Bouncy Castle
+ * (http://www.bouncycastle.org)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDER.S BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+package org.ibex.crypto;
+
+/**
+ * implementation of MD5 as outlined in "Handbook of Applied Cryptography", pages 346 - 347.
+ */
+public class MD5
+ extends Digest
+{
+ private static final int DIGEST_LENGTH = 16;
+
+ private int H1, H2, H3, H4; // IV's
+
+ private int[] X = new int[16];
+ private int xOff;
+
+ /**
+ * Standard constructor
+ */
+ public MD5()
+ {
+ reset();
+ }
+
+ public int getDigestSize()
+ {
+ return DIGEST_LENGTH;
+ }
+
+ protected void processWord(
+ byte[] in,
+ int inOff)
+ {
+ X[xOff++] = (in[inOff] & 0xff) | ((in[inOff + 1] & 0xff) << 8)
+ | ((in[inOff + 2] & 0xff) << 16) | ((in[inOff + 3] & 0xff) << 24);
+
+ if (xOff == 16)
+ {
+ processBlock();
+ }
+ }
+
+ protected void processLength(
+ long bitLength)
+ {
+ if (xOff > 14)
+ {
+ processBlock();
+ }
+
+ X[14] = (int)(bitLength & 0xffffffff);
+ X[15] = (int)(bitLength >>> 32);
+ }
+
+ private void unpackWord(
+ int word,
+ byte[] out,
+ int outOff)
+ {
+ out[outOff] = (byte)word;
+ out[outOff + 1] = (byte)(word >>> 8);
+ out[outOff + 2] = (byte)(word >>> 16);
+ out[outOff + 3] = (byte)(word >>> 24);
+ }
+
+ public void doFinal(
+ byte[] out,
+ int outOff)
+ {
+ finish();
+
+ unpackWord(H1, out, outOff);
+ unpackWord(H2, out, outOff + 4);
+ unpackWord(H3, out, outOff + 8);
+ unpackWord(H4, out, outOff + 12);
+
+ reset();
+ }
+
+ /**
+ * reset the chaining variables to the IV values.
+ */
+ public void reset()
+ {
+ super.reset();
+
+ H1 = 0x67452301;
+ H2 = 0xefcdab89;
+ H3 = 0x98badcfe;
+ H4 = 0x10325476;
+
+ xOff = 0;
+
+ for (int i = 0; i != X.length; i++)
+ {
+ X[i] = 0;
+ }
+ }
+
+ /*
+ * rotate int x left n bits.
+ */
+ private int rotateLeft(
+ int x,
+ int n)
+ {
+ return (x << n) | (x >>> (32 - n));
+ }
+
+ /*
+ * F, G, H and I are the basic MD5 functions.
+ */
+ private int F(
+ int u,
+ int v,
+ int w)
+ {
+ return (u & v) | (~u & w);
+ }
+
+ private int G(
+ int u,
+ int v,
+ int w)
+ {
+ return (u & w) | (v & ~w);
+ }
+
+ private int H(
+ int u,
+ int v,
+ int w)
+ {
+ return u ^ v ^ w;
+ }
+
+ private int K(
+ int u,
+ int v,
+ int w)
+ {
+ return v ^ (u | ~w);
+ }
+
+ protected void processBlock()
+ {
+ int a = H1;
+ int b = H2;
+ int c = H3;
+ int d = H4;
+
+ //
+ // Round 1 - F cycle, 16 times.
+ //
+ a = rotateLeft((a + F(b, c, d) + X[ 0] + 0xd76aa478), 7) + b;
+ d = rotateLeft((d + F(a, b, c) + X[ 1] + 0xe8c7b756), 12) + a;
+ c = rotateLeft((c + F(d, a, b) + X[ 2] + 0x242070db), 17) + d;
+ b = rotateLeft((b + F(c, d, a) + X[ 3] + 0xc1bdceee), 22) + c;
+ a = rotateLeft((a + F(b, c, d) + X[ 4] + 0xf57c0faf), 7) + b;
+ d = rotateLeft((d + F(a, b, c) + X[ 5] + 0x4787c62a), 12) + a;
+ c = rotateLeft((c + F(d, a, b) + X[ 6] + 0xa8304613), 17) + d;
+ b = rotateLeft((b + F(c, d, a) + X[ 7] + 0xfd469501), 22) + c;
+ a = rotateLeft((a + F(b, c, d) + X[ 8] + 0x698098d8), 7) + b;
+ d = rotateLeft((d + F(a, b, c) + X[ 9] + 0x8b44f7af), 12) + a;
+ c = rotateLeft((c + F(d, a, b) + X[10] + 0xffff5bb1), 17) + d;
+ b = rotateLeft((b + F(c, d, a) + X[11] + 0x895cd7be), 22) + c;
+ a = rotateLeft((a + F(b, c, d) + X[12] + 0x6b901122), 7) + b;
+ d = rotateLeft((d + F(a, b, c) + X[13] + 0xfd987193), 12) + a;
+ c = rotateLeft((c + F(d, a, b) + X[14] + 0xa679438e), 17) + d;
+ b = rotateLeft((b + F(c, d, a) + X[15] + 0x49b40821), 22) + c;
+
+ //
+ // Round 2 - G cycle, 16 times.
+ //
+ a = rotateLeft((a + G(b, c, d) + X[ 1] + 0xf61e2562), 5) + b;
+ d = rotateLeft((d + G(a, b, c) + X[ 6] + 0xc040b340), 9) + a;
+ c = rotateLeft((c + G(d, a, b) + X[11] + 0x265e5a51), 14) + d;
+ b = rotateLeft((b + G(c, d, a) + X[ 0] + 0xe9b6c7aa), 20) + c;
+ a = rotateLeft((a + G(b, c, d) + X[ 5] + 0xd62f105d), 5) + b;
+ d = rotateLeft((d + G(a, b, c) + X[10] + 0x02441453), 9) + a;
+ c = rotateLeft((c + G(d, a, b) + X[15] + 0xd8a1e681), 14) + d;
+ b = rotateLeft((b + G(c, d, a) + X[ 4] + 0xe7d3fbc8), 20) + c;
+ a = rotateLeft((a + G(b, c, d) + X[ 9] + 0x21e1cde6), 5) + b;
+ d = rotateLeft((d + G(a, b, c) + X[14] + 0xc33707d6), 9) + a;
+ c = rotateLeft((c + G(d, a, b) + X[ 3] + 0xf4d50d87), 14) + d;
+ b = rotateLeft((b + G(c, d, a) + X[ 8] + 0x455a14ed), 20) + c;
+ a = rotateLeft((a + G(b, c, d) + X[13] + 0xa9e3e905), 5) + b;
+ d = rotateLeft((d + G(a, b, c) + X[ 2] + 0xfcefa3f8), 9) + a;
+ c = rotateLeft((c + G(d, a, b) + X[ 7] + 0x676f02d9), 14) + d;
+ b = rotateLeft((b + G(c, d, a) + X[12] + 0x8d2a4c8a), 20) + c;
+
+ //
+ // Round 3 - H cycle, 16 times.
+ //
+ a = rotateLeft((a + H(b, c, d) + X[ 5] + 0xfffa3942), 4) + b;
+ d = rotateLeft((d + H(a, b, c) + X[ 8] + 0x8771f681), 11) + a;
+ c = rotateLeft((c + H(d, a, b) + X[11] + 0x6d9d6122), 16) + d;
+ b = rotateLeft((b + H(c, d, a) + X[14] + 0xfde5380c), 23) + c;
+ a = rotateLeft((a + H(b, c, d) + X[ 1] + 0xa4beea44), 4) + b;
+ d = rotateLeft((d + H(a, b, c) + X[ 4] + 0x4bdecfa9), 11) + a;
+ c = rotateLeft((c + H(d, a, b) + X[ 7] + 0xf6bb4b60), 16) + d;
+ b = rotateLeft((b + H(c, d, a) + X[10] + 0xbebfbc70), 23) + c;
+ a = rotateLeft((a + H(b, c, d) + X[13] + 0x289b7ec6), 4) + b;
+ d = rotateLeft((d + H(a, b, c) + X[ 0] + 0xeaa127fa), 11) + a;
+ c = rotateLeft((c + H(d, a, b) + X[ 3] + 0xd4ef3085), 16) + d;
+ b = rotateLeft((b + H(c, d, a) + X[ 6] + 0x04881d05), 23) + c;
+ a = rotateLeft((a + H(b, c, d) + X[ 9] + 0xd9d4d039), 4) + b;
+ d = rotateLeft((d + H(a, b, c) + X[12] + 0xe6db99e5), 11) + a;
+ c = rotateLeft((c + H(d, a, b) + X[15] + 0x1fa27cf8), 16) + d;
+ b = rotateLeft((b + H(c, d, a) + X[ 2] + 0xc4ac5665), 23) + c;
+
+ //
+ // Round 4 - K cycle, 16 times.
+ //
+ a = rotateLeft((a + K(b, c, d) + X[ 0] + 0xf4292244), 6) + b;
+ d = rotateLeft((d + K(a, b, c) + X[ 7] + 0x432aff97), 10) + a;
+ c = rotateLeft((c + K(d, a, b) + X[14] + 0xab9423a7), 15) + d;
+ b = rotateLeft((b + K(c, d, a) + X[ 5] + 0xfc93a039), 21) + c;
+ a = rotateLeft((a + K(b, c, d) + X[12] + 0x655b59c3), 6) + b;
+ d = rotateLeft((d + K(a, b, c) + X[ 3] + 0x8f0ccc92), 10) + a;
+ c = rotateLeft((c + K(d, a, b) + X[10] + 0xffeff47d), 15) + d;
+ b = rotateLeft((b + K(c, d, a) + X[ 1] + 0x85845dd1), 21) + c;
+ a = rotateLeft((a + K(b, c, d) + X[ 8] + 0x6fa87e4f), 6) + b;
+ d = rotateLeft((d + K(a, b, c) + X[15] + 0xfe2ce6e0), 10) + a;
+ c = rotateLeft((c + K(d, a, b) + X[ 6] + 0xa3014314), 15) + d;
+ b = rotateLeft((b + K(c, d, a) + X[13] + 0x4e0811a1), 21) + c;
+ a = rotateLeft((a + K(b, c, d) + X[ 4] + 0xf7537e82), 6) + b;
+ d = rotateLeft((d + K(a, b, c) + X[11] + 0xbd3af235), 10) + a;
+ c = rotateLeft((c + K(d, a, b) + X[ 2] + 0x2ad7d2bb), 15) + d;
+ b = rotateLeft((b + K(c, d, a) + X[ 9] + 0xeb86d391), 21) + c;
+
+ H1 += a;
+ H2 += b;
+ H3 += c;
+ H4 += d;
+
+ //
+ // reset the offset and clean out the word buffer.
+ //
+ xOff = 0;
+ for (int i = 0; i != X.length; i++)
+ {
+ X[i] = 0;
+ }
+ }
+}
--- /dev/null
+package org.ibex.crypto;
+import java.security.SecureRandom;
+
+public class PKCS1 {
+ private final RSA rsa;
+ private final SecureRandom srand;
+ public PKCS1(RSA rsa) { this(rsa,new SecureRandom()); }
+ public PKCS1(RSA rsa,SecureRandom srand) { this.rsa = rsa; this.srand = srand; }
+
+ public byte[] encode(byte[] in) {
+ int size = rsa.getInputBlockSize();
+ if(in.length > size - 11) throw new IllegalArgumentException("message too long");
+ byte[] buf = new byte[size];
+ byte[] rand = new byte[size - in.length - 2];
+ srand.nextBytes(rand);
+ for(int i=0;i<rand.length;i++) while(rand[i] == 0) rand[i] = (byte)srand.nextInt();
+ int p=0;
+ buf[p++] = 0x02;
+ System.arraycopy(rand,0,buf,p,rand.length);
+ p+=rand.length;
+ buf[p++] = 0x0;
+ System.arraycopy(in,0,buf,p,in.length);
+
+ return rsa.process(buf);
+ }
+
+ public byte[] decode(byte[] in) throws Exn {
+ byte[] buf = rsa.process(in);
+ if(buf.length < 10) throw new Exn("Data too short");
+ if(buf[0] != 2 && buf[0] != 1) throw new Exn("Data not in correct format " + (buf[0]&0xff));
+ int start = 9;
+ while(start < buf.length && buf[start] != 0) start++;
+ if(start == buf.length) throw new Exn("No null separator");
+ start++;
+ byte[] ret = new byte[buf.length - start];
+ System.arraycopy(buf,start,ret,0,ret.length);
+ return ret;
+ }
+
+ public static class Exn extends Exception { public Exn(String s) { super(s); } }
+}
--- /dev/null
+package org.ibex.crypto;
+
+
+public class RC4 {
+ private final byte[] s = new byte[256];
+ private int x,y;
+
+ public RC4(byte[] k) {
+ for(int i=0;i<256;i++) s[i] = (byte)i;
+ for(int i=0,j=0;i<256;i++) {
+ j = (j + (s[i]&0xff) + (k[i%k.length]&0xff))&0xff;
+ byte tmp = s[i];
+ s[i] = s[j];
+ s[j] = tmp;
+ }
+ }
+
+ public void process(byte[] in, int ip, byte[] out, int op, int len) {
+ int x = this.x;
+ int y = this.y;
+ byte[] s = this.s;
+ for(int i=0;i<len;i++) {
+ x = (x + 1) & 0xff;
+ y = (y + (s[x]&0xff)) & 0xff;
+ byte tmp = s[x];
+ s[x] = s[y];
+ s[y] = tmp;
+ int t = ((s[x]&0xff) + (s[y]&0xff))&0xff;
+ int k = s[t];
+ out[op+i] = (byte)((in[ip+i]&0xff)^k);
+ }
+ this.x = x;
+ this.y = y;
+ }
+}
--- /dev/null
+package org.ibex.crypto;
+import java.math.BigInteger;
+import java.util.*;
+
+public class RSA {
+ private final BigInteger pq;
+ private final BigInteger e;
+ private final boolean reverse;
+
+ public RSA(BigInteger pq, BigInteger e, boolean reverse) {
+ this.pq = pq;
+ this.e = e;
+ this.reverse = reverse;
+ }
+
+ public int getInputBlockSize() { return (pq.bitLength()+7) / 8 - (reverse ? 0 : 1); }
+ public int getOutputBlockSize() { return (pq.bitLength()+7) / 8 - (reverse ? 1 : 0); }
+
+ public byte[] process(byte[] in) {
+ // output block is the same size as the modulus (rounded up)
+ int outSize = getOutputBlockSize();
+ BigInteger t = new BigInteger(1,in);
+ BigInteger c = t.modPow(e,pq);
+ byte[] cbytes = c.toByteArray();
+ if(cbytes.length > outSize || (reverse && cbytes[0] == 0)) {
+ if(cbytes[0] != 0) throw new RuntimeException("should never happen");
+ byte[] buf = new byte[outSize];
+ System.arraycopy(cbytes,1,buf,0,outSize);
+ return buf;
+ } else if(!reverse && cbytes.length < outSize) {
+ // output needs to be exactly outSize in length
+ byte[] buf = new byte[outSize];
+ System.arraycopy(cbytes,0,buf,outSize-cbytes.length,cbytes.length);
+ return buf;
+ } else {
+ return cbytes;
+ }
+ }
+
+ public static class PublicKey {
+ public final BigInteger modulus;
+ public final BigInteger exponent;
+
+ public PublicKey(Object o) {
+ Vector seq = (Vector) o;
+ modulus = (BigInteger) seq.elementAt(0);
+ exponent = (BigInteger) seq.elementAt(1);
+ }
+ }
+
+}
--- /dev/null
+/* Copyright (c) 2000 The Legion Of The Bouncy Castle
+ * (http://www.bouncycastle.org)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDER.S BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+package org.ibex.crypto;
+
+/**
+ * implementation of SHA-1 as outlined in "Handbook of Applied Cryptography", pages 346 - 349.
+ *
+ * It is interesting to ponder why the, apart from the extra IV, the other difference here from MD5
+ * is the "endienness" of the word processing!
+ */
+public class SHA1
+ extends Digest
+{
+ private static final int DIGEST_LENGTH = 20;
+
+ private int H1, H2, H3, H4, H5;
+
+ private int[] X = new int[80];
+ private int xOff;
+
+ /**
+ * Standard constructor
+ */
+ public SHA1()
+ {
+ reset();
+ }
+
+ public int getDigestSize()
+ {
+ return DIGEST_LENGTH;
+ }
+
+ protected void processWord(
+ byte[] in,
+ int inOff)
+ {
+ X[xOff++] = ((in[inOff] & 0xff) << 24) | ((in[inOff + 1] & 0xff) << 16)
+ | ((in[inOff + 2] & 0xff) << 8) | ((in[inOff + 3] & 0xff));
+
+ if (xOff == 16)
+ {
+ processBlock();
+ }
+ }
+
+ private void unpackWord(
+ int word,
+ byte[] out,
+ int outOff)
+ {
+ out[outOff] = (byte)(word >>> 24);
+ out[outOff + 1] = (byte)(word >>> 16);
+ out[outOff + 2] = (byte)(word >>> 8);
+ out[outOff + 3] = (byte)word;
+ }
+
+ protected void processLength(
+ long bitLength)
+ {
+ if (xOff > 14)
+ {
+ processBlock();
+ }
+
+ X[14] = (int)(bitLength >>> 32);
+ X[15] = (int)(bitLength & 0xffffffff);
+ }
+
+ public void doFinal(
+ byte[] out,
+ int outOff)
+ {
+ finish();
+
+ unpackWord(H1, out, outOff);
+ unpackWord(H2, out, outOff + 4);
+ unpackWord(H3, out, outOff + 8);
+ unpackWord(H4, out, outOff + 12);
+ unpackWord(H5, out, outOff + 16);
+
+ reset();
+ }
+
+ /**
+ * reset the chaining variables
+ */
+ public void reset()
+ {
+ super.reset();
+
+ H1 = 0x67452301;
+ H2 = 0xefcdab89;
+ H3 = 0x98badcfe;
+ H4 = 0x10325476;
+ H5 = 0xc3d2e1f0;
+
+ xOff = 0;
+ for (int i = 0; i != X.length; i++)
+ {
+ X[i] = 0;
+ }
+ }
+
+ private int f(
+ int u,
+ int v,
+ int w)
+ {
+ return ((u & v) | ((~u) & w));
+ }
+
+ private int h(
+ int u,
+ int v,
+ int w)
+ {
+ return (u ^ v ^ w);
+ }
+
+ private int g(
+ int u,
+ int v,
+ int w)
+ {
+ return ((u & v) | (u & w) | (v & w));
+ }
+
+ private int rotateLeft(
+ int x,
+ int n)
+ {
+ return (x << n) | (x >>> (32 - n));
+ }
+
+ protected void processBlock()
+ {
+ //
+ // expand 16 word block into 80 word block.
+ //
+ for (int i = 16; i <= 79; i++)
+ {
+ X[i] = rotateLeft((X[i - 3] ^ X[i - 8] ^ X[i - 14] ^ X[i - 16]), 1);
+ }
+
+ //
+ // set up working variables.
+ //
+ int A = H1;
+ int B = H2;
+ int C = H3;
+ int D = H4;
+ int E = H5;
+
+ //
+ // round 1
+ //
+ for (int j = 0; j <= 19; j++)
+ {
+ int t = rotateLeft(A, 5) + f(B, C, D) + E + X[j] + 0x5a827999;
+
+ E = D;
+ D = C;
+ C = rotateLeft(B, 30);
+ B = A;
+ A = t;
+ }
+
+ //
+ // round 2
+ //
+ for (int j = 20; j <= 39; j++)
+ {
+ int t = rotateLeft(A, 5) + h(B, C, D) + E + X[j] + 0x6ed9eba1;
+
+ E = D;
+ D = C;
+ C = rotateLeft(B, 30);
+ B = A;
+ A = t;
+ }
+
+ //
+ // round 3
+ //
+ for (int j = 40; j <= 59; j++)
+ {
+ int t = rotateLeft(A, 5) + g(B, C, D) + E + X[j] + 0x8f1bbcdc;
+
+ E = D;
+ D = C;
+ C = rotateLeft(B, 30);
+ B = A;
+ A = t;
+ }
+
+ //
+ // round 4
+ //
+ for (int j = 60; j <= 79; j++)
+ {
+ int t = rotateLeft(A, 5) + h(B, C, D) + E + X[j] + 0xca62c1d6;
+
+ E = D;
+ D = C;
+ C = rotateLeft(B, 30);
+ B = A;
+ A = t;
+ }
+
+ H1 += A;
+ H2 += B;
+ H3 += C;
+ H4 += D;
+ H5 += E;
+
+ //
+ // reset the offset and clean out the word buffer.
+ //
+ xOff = 0;
+ for (int i = 0; i != X.length; i++)
+ {
+ X[i] = 0;
+ }
+ }
+}
--- /dev/null
+/*
+ * com.brian_web.x509.* - By Brian Alliet
+ * Copyright (C) 2004 Brian Alliet
+ *
+ * Based on Bouncy Castle by The Legion Of The Bouncy Castle
+ * Copyright (c) 2000 The Legion Of The Bouncy Castle
+ * (http://www.bouncycastle.org)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDER.S BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+package org.ibex.crypto;
+
+import java.io.*;
+import java.util.*;
+
+public class X509 {
+ public static class Certificate {
+ public static final String RSA_ENCRYPTION = "1.2.840.113549.1.1.1";
+ public static final String MD2_WITH_RSA_ENCRYPTION = "1.2.840.113549.1.1.2";
+ public static final String MD4_WITH_RSA_ENCRYPTION = "1.2.840.113549.1.1.3";
+ public static final String MD5_WITH_RSA_ENCRYPTION = "1.2.840.113549.1.1.4";
+ public static final String SHA1_WITH_RSA_ENCRYPTION = "1.2.840.113549.1.1.5";
+
+ public static final String BASIC_CONSTRAINTS = "2.5.29.19";
+
+ private final byte[] certBytes;
+ private final byte[] tbsCertBytes;
+
+ public final Number version;
+ public final Number serialNo;
+ public final X509.Name issuer;
+ public final Date startDate;
+ public final Date endDate;
+ public final X509.Name subject;
+
+ public final AlgorithmIdentifier publicKeyAlgorithm;
+ public final DER.BitString publicKey;
+
+ public final Object issuerUniqueID;
+ public final Object subjectUniqueID;
+
+ public final Vector extensions;
+
+ public final DER.BitString signature;
+ public final AlgorithmIdentifier signatureAlgorithm;
+
+ public final BC basicContraints;
+
+
+ public Certificate(InputStream is) throws IOException {
+ int i;
+ RecordingInputStream certIS = new RecordingInputStream(is);
+ DER.InputStream certSequence = DER.InputStream.New(certIS).getSequenceStream();
+ RecordingInputStream tbsCertIS = new RecordingInputStream(certSequence);
+
+ try {
+ Vector tbsSequence = (Vector) DER.InputStream.New(tbsCertIS).readObject();
+ tbsCertBytes = tbsCertIS.getBytes();
+ signatureAlgorithm = new AlgorithmIdentifier(certSequence.readObject());
+ signature = (DER.BitString) certSequence.readObject();
+
+ i=0;
+ if(tbsSequence.elementAt(i) instanceof DER.TaggedObject)
+ version = (Number)((DER.TaggedObject)tbsSequence.elementAt(i++)).object;
+ else
+ version = new Integer(0);
+
+ serialNo = (Number) tbsSequence.elementAt(i++);
+ AlgorithmIdentifier signatureAlgorithm2 = new AlgorithmIdentifier(tbsSequence.elementAt(i++));
+ if(!signatureAlgorithm2.equals(signatureAlgorithm))
+ throw new DER.Exception("AlgoritmIdentifier mismatch " + signatureAlgorithm + " vs " + signatureAlgorithm2);
+ issuer = new X509.Name(tbsSequence.elementAt(i++));
+
+ Vector validity = (Vector) tbsSequence.elementAt(i++);
+ startDate = (Date) validity.elementAt(0);
+ endDate = (Date) validity.elementAt(1);
+
+ subject = new X509.Name(tbsSequence.elementAt(i++));
+
+ Vector publicKeyInfo = (Vector) tbsSequence.elementAt(i++);
+ publicKeyAlgorithm = new AlgorithmIdentifier(publicKeyInfo.elementAt(0));
+ publicKey = (DER.BitString) publicKeyInfo.elementAt(1);
+
+ Object issuerUniqueID_=null,subjectUniqueID_=null;
+ Vector extensions_=null;
+ for(;i < tbsSequence.size();i++) {
+ DER.TaggedObject to = (DER.TaggedObject) tbsSequence.elementAt(i);
+ switch(to.tag) {
+ case 1: issuerUniqueID_ = to.object; break;
+ case 2: subjectUniqueID_ = to.object; break;
+ case 3: extensions_ = (Vector) to.object; break;
+ }
+ }
+ issuerUniqueID = issuerUniqueID_;
+ subjectUniqueID = subjectUniqueID_;
+ extensions = extensions_;
+
+ BC bc = null;
+
+ if(extensions != null) {
+ for(Enumeration e = extensions.elements(); e.hasMoreElements(); ) {
+ Vector extension = (Vector) e.nextElement();
+ String oid = (String) extension.elementAt(0);
+ byte[] data = (byte[]) extension.elementAt(extension.size()-1);
+ if(oid.equals(BASIC_CONSTRAINTS))
+ bc = new BC(DER.InputStream.New(new ByteArrayInputStream(data)).readObject());
+ }
+ }
+ basicContraints = bc;
+ } catch(RuntimeException e) {
+ e.printStackTrace();
+ throw new DER.Exception("Invalid x509 Certificate");
+ }
+ certBytes = certIS.getBytes();
+ }
+
+
+ public String getSubjectField(String fieldID) { return subject.get(fieldID); }
+ public String getCN() { return getSubjectField(X509.Name.CN); }
+
+ public boolean isValid() {
+ Date now = new Date();
+ return !now.after(endDate) && !now.before(startDate);
+ }
+
+ public RSA.PublicKey getRSAPublicKey() throws DER.Exception {
+ if(!RSA_ENCRYPTION.equals(publicKeyAlgorithm.id)) throw new DER.Exception("This isn't an RSA public key");
+ try {
+ return new RSA.PublicKey(DER.InputStream.New(new ByteArrayInputStream(publicKey.data)).readObject());
+ } catch(IOException e) {
+ throw new DER.Exception(e.getMessage());
+ } catch(RuntimeException e) {
+ throw new DER.Exception("Invalid RSA Public Key " + e.getMessage());
+ }
+ }
+
+ public boolean isSignedBy(Certificate signer) throws DER.Exception {
+ return isSignedWith(signer.getRSAPublicKey());
+ }
+ public boolean isSignedWith(RSA.PublicKey rsapk) throws DER.Exception {
+ try {
+ Digest digest;
+ if(signatureAlgorithm.id.equals(MD5_WITH_RSA_ENCRYPTION)) digest = new MD5();
+ else if(signatureAlgorithm.id.equals(SHA1_WITH_RSA_ENCRYPTION)) digest = new SHA1();
+ else if(signatureAlgorithm.id.equals(MD2_WITH_RSA_ENCRYPTION)) digest = new MD2();
+ else throw new DER.Exception("Unknown signing algorithm: " + signatureAlgorithm.id);
+
+ PKCS1 pkcs1 = new PKCS1(new RSA(rsapk.modulus,rsapk.exponent,true));
+ byte[] d = pkcs1.decode(signature.data);
+
+ Vector v = (Vector) DER.InputStream.New(new ByteArrayInputStream(d)).readObject();
+ byte[] signedDigest = (byte[]) v.elementAt(1);
+
+ if(signedDigest.length != digest.getDigestSize()) return false;
+
+ digest.update(tbsCertBytes,0,tbsCertBytes.length);
+ byte[] ourDigest = new byte[digest.getDigestSize()];
+ digest.doFinal(ourDigest,0);
+
+ for(int i=0;i<digest.getDigestSize();i++) if(ourDigest[i] != signedDigest[i]) return false;
+ return true;
+ }
+ catch(RuntimeException e) { e.printStackTrace(); return false; }
+ catch(PKCS1.Exn e) { e.printStackTrace(); return false; }
+ catch(IOException e) { e.printStackTrace(); return false; }
+ }
+
+ public byte[] getMD5Fingerprint() { return getFingerprint(new MD5()); }
+ public byte[] getSHA1Fingerprint() { return getFingerprint(new SHA1()); }
+ public byte[] getFingerprint(Digest h) {
+ h.update(certBytes,0,certBytes.length);
+ byte[] digest = new byte[h.getDigestSize()];
+ h.doFinal(digest,0);
+ return digest;
+ }
+
+ private class RecordingInputStream extends FilterInputStream {
+ public ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ private boolean on = true;
+ public void on() { on = true; }
+ public void off() { on = false; }
+ public RecordingInputStream(InputStream is) { super(is); }
+ public int read() throws IOException {
+ int n = super.read();
+ if(n != -1 && on) baos.write(n);
+ return n;
+ }
+ public int read(byte[] buf, int off, int len) throws IOException {
+ int n = super.read(buf,off,len);
+ if(n != -1 && on) baos.write(buf,off,n);
+ return n;
+ }
+ public byte[] getBytes() { return baos.toByteArray(); }
+ }
+
+ public static class BC {
+ public final boolean isCA;
+ public final Number pathLenConstraint;
+ BC(Object o) {
+ Vector seq = (Vector) o;
+ isCA = seq.size() > 0 ? ((Boolean) seq.elementAt(0)).booleanValue() : false;
+ pathLenConstraint = seq.size() > 1 ? (Number) seq.elementAt(1) : null;
+ }
+ }
+
+ public static class AlgorithmIdentifier {
+ public final String id;
+ public final Object parameters;
+
+ AlgorithmIdentifier(Object o) {
+ Vector seq = (Vector) o;
+ id = (String) seq.elementAt(0);
+ parameters = seq.elementAt(1);
+ }
+ public boolean equals(Object o_) {
+ if(o_ == this) return true;
+ if(!(o_ instanceof AlgorithmIdentifier)) return false;
+ AlgorithmIdentifier o = (AlgorithmIdentifier) o_;
+ return o.id.equals(id) && o.parameters.equals(parameters);
+ }
+ public int hashCode() { return id.hashCode() ^ parameters.hashCode(); }
+ }
+
+ /*public static void main(String[] args) throws Exception {
+ Certificate cert = new Certificate(new FileInputStream(args[0]));
+ System.err.println("CN: " + cert.getCN());
+ System.err.println("Subject: " + cert.subject);
+ System.err.println("Issuer: " + cert.issuer);
+ System.err.println("Start Date: " + cert.startDate);
+ System.err.println("End Date: " + cert.endDate);
+ System.err.println("SHA1 Fingerprint: " + prettyBytes(cert.getSHA1Fingerprint()));
+ RSA.PublicKey key = cert.getRSA.PublicKey();
+ System.err.println("Modulus: " + prettyBytes(key.modulus.toByteArray()));
+ System.err.println("Exponent: " + key.exponent);
+ System.err.println("Signature: " + prettyBytes(cert.signature.data));
+ }
+
+ public static String prettyBytes(byte[] fp) {
+ StringBuffer sb = new StringBuffer(fp.length*3);
+ for(int i=0;i<fp.length;i++) {
+ if(i>0) sb.append(":");
+ sb.append("0123456789abcdef".charAt((fp[i] & 0xf0) >>> 4));
+ sb.append("0123456789abcdef".charAt((fp[i] & 0x0f) >>> 0));
+ }
+ return sb.toString();
+ }*/
+ }
+
+ public static class Name {
+ // Some common OIDs
+ public static final String C = "2.5.4.6";
+ public static final String O = "2.5.4.10";
+ public static final String T = "2.5.4.12";
+ public static final String SN = "2.5.4.5";
+ public static final String L = "2.5.4.7";
+ public static final String ST = "2.5.4.8";
+ public static final String OU = "2.5.4.11";
+ public static final String CN = "2.5.4.3";
+ public static final String E = "1.2.840.113549.1.9.1";
+
+ private final Vector keys = new Vector();
+ private final Vector values = new Vector();
+
+ public Name(Object seq_) throws DER.Exception {
+ try {
+ Vector seq = (Vector) seq_;
+ for(Enumeration e = seq.elements();e.hasMoreElements();) {
+ Vector component = (Vector) ((Vector)e.nextElement()).elementAt(0);
+ keys.add(component.elementAt(0));
+ values.add(component.elementAt(1));
+ }
+ } catch(RuntimeException e) {
+ e.printStackTrace();
+ throw new DER.Exception("Invalid Name " + e.toString());
+ }
+ }
+
+ public boolean equals(Object o_) {
+ if(o_ instanceof String) return toString().equals(o_);
+ if(!(o_ instanceof Name)) return false;
+ Name o = (Name) o_;
+ if(keys.size() != o.keys.size()) return false;
+ int size = keys.size();
+ for(int i=0;i<size;i++) {
+ String oid = (String) keys.elementAt(i);
+ String oid2 = (String) o.keys.elementAt(i);
+ if(!oid.equals(oid2)) return false;
+
+ String val1 = (String) values.elementAt(i);
+ String val2 = (String) o.values.elementAt(i);
+ if(val1.equals(val2)) continue;
+
+ val1 = val1.trim().toLowerCase();
+ val2 = val2.trim().toLowerCase();
+ if(val1.equals(val2)) continue;
+
+ val1 = removeExtraSpaces(val1);
+ val2 = removeExtraSpaces(val2);
+ if(val1.equals(val2)) continue;
+
+ return false;
+ }
+ return true;
+ }
+
+ public int hashCode() { return keys.hashCode() ^ values.hashCode(); }
+
+ public String get(String fieldID) {
+ int i = keys.indexOf(fieldID);
+ return i == -1 ? null : (String)values.elementAt(i);
+ }
+
+ public String[] getOIDs() {
+ String[] ret = new String[keys.size()];
+ keys.copyInto(ret);
+ return ret;
+ }
+
+ public String[] getValues() {
+ String[] ret = new String[values.size()];
+ values.copyInto(ret);
+ return ret;
+ }
+
+ private static String removeExtraSpaces(String s) {
+ if(s.indexOf(' ') == -1) return s;
+ StringBuffer sb = new StringBuffer(s.length());
+ int l = s.length();
+ boolean inWhitespace = false;
+ for(int i=0;i<l;i++) {
+ if(s.charAt(i) == ' ') {
+ if(inWhitespace) continue;
+ inWhitespace = true;
+ } else if(inWhitespace) {
+ inWhitespace = false;
+ }
+ sb.append(s.charAt(i));
+ }
+ return sb.toString();
+ }
+
+ private final static Hashtable oidMap = new Hashtable();
+ static {
+ oidMap.put(Name.C,"C");
+ oidMap.put(Name.O,"O");
+ oidMap.put(Name.T,"T");
+ oidMap.put(Name.SN,"SN");
+ oidMap.put(Name.L,"L");
+ oidMap.put(Name.ST,"ST");
+ oidMap.put(Name.OU,"OU");
+ oidMap.put(Name.CN,"CN");
+ oidMap.put(Name.E,"E");
+ }
+
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ int size = keys.size();
+ for(int i=0;i<size;i++) {
+ if(sb.length() > 0) sb.append(",");
+ String fieldID = (String) keys.elementAt(i);
+ String fieldName = (String) oidMap.get(fieldID);
+ sb.append(fieldName != null ? fieldName : fieldID).append("=").append(values.elementAt(i));
+ }
+ return sb.toString();
+ }
+ }
+}
--- /dev/null
+/*
+ * org.ibex.net.SSL - By Brian Alliet
+ * Copyright (C) 2004 Brian Alliet
+ *
+ * Based on TinySSL by Adam Megacz
+ * Copyright (C) 2003 Adam Megacz <adam@xwt.org> all rights reserved.
+ *
+ * You may modify, copy, and redistribute this code under the terms of
+ * the GNU Lesser General Public License version 2.1, with the exception
+ * of the portion of clause 6a after the semicolon (aka the "obnoxious
+ * relink clause")
+ */
+
+package org.ibex.net;
+
+import org.ibex.crypto.*;
+import java.security.SecureRandom;
+
+import java.net.Socket;
+import java.net.SocketException;
+
+import java.io.*;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Random;
+import java.util.Vector;
+
+// FEATURE: Server socket
+
+public class SSL extends Socket {
+ private String hostname;
+
+ private int negotiated;
+
+ private boolean tls = true;
+ private boolean sha;
+
+ private final DataInputStream rawIS;
+ private final DataOutputStream rawOS;
+
+ private final InputStream sslIS;
+ private final OutputStream sslOS;
+
+ private byte[] sessionID;
+
+ private Digest clientWriteMACDigest;
+ private Digest serverWriteMACDigest;
+ private byte[] masterSecret;
+
+ private RC4 writeRC4;
+ private RC4 readRC4;
+
+ private long serverSequenceNumber;
+ private long clientSequenceNumber;
+
+ private int warnings;
+ private boolean closed;
+
+ // These are only used during negotiation
+ private byte[] serverRandom;
+ private byte[] clientRandom;
+ private byte[] preMasterSecret;
+
+ // Buffers
+ private byte[] mac;
+
+ private byte[] pending = new byte[16384];
+ private int pendingStart;
+ private int pendingLength;
+
+ private byte[] sendRecordBuf = new byte[16384];
+
+ private int handshakeDataStart;
+ private int handshakeDataLength;
+ private byte[] readRecordBuf = new byte[16384+20]; // 20 == sizeof(sha1 hash)
+ private byte[] readRecordScratch = new byte[16384+20];
+
+ private ByteArrayOutputStream handshakesBuffer;
+
+ // End Buffers
+
+ // Static variables
+ private final static byte[] pad1 = new byte[48];
+ private final static byte[] pad2 = new byte[48];
+ private final static byte[] pad1_sha = new byte[40];
+ private final static byte[] pad2_sha = new byte[40];
+
+ static {
+ for(int i=0; i<pad1.length; i++) pad1[i] = (byte)0x36;
+ for(int i=0; i<pad2.length; i++) pad2[i] = (byte)0x5C;
+ for(int i=0; i<pad1_sha.length; i++) pad1_sha[i] = (byte)0x36;
+ for(int i=0; i<pad2_sha.length; i++) pad2_sha[i] = (byte)0x5C;
+ }
+
+ private final static Hashtable caKeys = new Hashtable();
+ private static VerifyCallback verifyCallback;
+
+ //
+ // Constructors
+ //
+ public SSL(String host) throws IOException { this(host,443); }
+ public SSL(String host, int port) throws IOException { this(host,port,true); }
+ public SSL(String host, int port, boolean negotiate) throws IOException { this(host,port,negotiate,null); }
+ public SSL(String host, int port, State state) throws IOException { this(host,port,true,state); }
+ public SSL(String host, int port, boolean negotiate, State state) throws IOException {
+ super(host,port);
+ hostname = host;
+ rawIS = new DataInputStream(new BufferedInputStream(super.getInputStream()));
+ rawOS = new DataOutputStream(new BufferedOutputStream(super.getOutputStream()));
+ sslIS = new SSLInputStream();
+ sslOS = new SSLOutputStream();
+ if(negotiate) negotiate(state);
+ }
+
+ public synchronized void setTLS(boolean b) { if(negotiated!=0) throw new IllegalStateException("already negotiated"); tls = b; }
+
+ public void negotiate() throws IOException { negotiate(null); }
+ public synchronized void negotiate(State state) throws IOException {
+ if(negotiated != 0) throw new IllegalStateException("already negotiated");
+
+ handshakesBuffer = new ByteArrayOutputStream();
+
+ try {
+ sendClientHello(state != null ? state.sessionID : null);
+ flush();
+ debug("sent ClientHello (" + (tls?"TLSv1.0":"SSLv3.0")+")");
+
+ receiveServerHello();
+ debug("got ServerHello (" + (tls?"TLSv1.0":"SSLv3.0")+")");
+
+ boolean resume =
+ state != null && sessionID.length == state.sessionID.length &&
+ eq(state.sessionID,0,sessionID,0,sessionID.length);
+
+ if(resume)
+ negotiateResume(state);
+ else
+ negotiateNew();
+
+ // we're done with these now
+ clientRandom = serverRandom = preMasterSecret = null;
+ handshakesBuffer = null;
+
+ log("Negotiation with " + hostname + " complete (" + (tls?"TLSv1.0":"SSLv3.0")+")");
+ } finally {
+ if((negotiated & 3) != 3) {
+ negotiated = 0;
+ try { super.close(); } catch(IOException e) { /* ignore */ }
+ closed = true;
+ }
+ }
+ }
+
+ private void negotiateResume(State state) throws IOException {
+ masterSecret = state.masterSecret;
+
+ initCrypto();
+ log("initializec crypto");
+
+ receiveChangeCipherSpec();
+ debug("Received ChangeCipherSpec");
+ negotiated |= 2;
+ receieveFinished();
+ debug("Received Finished");
+
+ sendChangeCipherSpec();
+ debug("Sent ChangeCipherSpec");
+ negotiated |= 1;
+ sendFinished();
+ debug("Sent Finished");
+ }
+
+ private void negotiateNew() throws IOException {
+ X509.Certificate[] certs = receiveServerCertificates();
+ debug("got Certificate");
+
+ boolean gotCertificateRequest = false;
+ OUTER: for(;;) {
+ byte[] buf = readHandshake();
+ switch(buf[0]) {
+ case 14: // ServerHelloDone
+ if(buf.length != 4) throw new Exn("ServerHelloDone contained trailing garbage");
+ debug("got ServerHelloDone");
+ break OUTER;
+ case 13: // CertificateRequest
+ debug("Got a CertificateRequest message but we don't suport client certificates");
+ gotCertificateRequest = true;
+ break;
+ default:
+ throw new Exn("unknown handshake type " + buf[0]);
+ }
+ }
+
+ if(gotCertificateRequest)
+ sendHandshake((byte)11,new byte[3]); // send empty cert list
+
+ try {
+ if(!hostname.equalsIgnoreCase(certs[0].getCN()))
+ throw new Exn("Certificate is for " + certs[0].getCN() + " not " + hostname);
+ verifyCerts(certs);
+ } catch(Exn e) {
+ if(verifyCallback == null) throw e;
+ synchronized(SSL.class) {
+ if(!verifyCallback.checkCerts(certs,hostname,e)) throw e;
+ }
+ }
+
+ computeMasterSecret();
+
+ sendClientKeyExchange(certs[0]);
+ debug("sent ClientKeyExchange");
+
+ initCrypto();
+
+ sendChangeCipherSpec();
+ debug("sent ChangeCipherSpec");
+ negotiated |= 1;
+ sendFinished();
+ debug("sent Finished");
+ flush();
+
+ receiveChangeCipherSpec();
+ debug("got ChangeCipherSpec");
+ negotiated |= 2;
+ receieveFinished();
+ debug("got Finished");
+ }
+
+ public State getSessionState() {
+ if((negotiated&3)!=3 || !closed || warnings != 0) return null;
+ return new State(sessionID,masterSecret);
+ }
+ public boolean isActive() { return !closed; }
+ public boolean isNegotiated() { return (negotiated&3) == 3; }
+
+ private void sendClientHello(byte[] sessionID) throws IOException {
+ if(sessionID != null && sessionID.length > 256) throw new IllegalArgumentException("sessionID");
+ // 2 = version, 32 = randomvalue, 1 = sessionID size, 2 = cipher list size, 4 = the two ciphers,
+ // 2 = compression length/no compression
+ int p = 0;
+ byte[] buf = new byte[2+32+1+(sessionID == null ? 0 : sessionID.length)+2+2+4];
+ buf[p++] = 0x03; // major version
+ buf[p++] = tls ? (byte)0x01 : (byte)0x00;
+
+ clientRandom = new byte[32];
+ int now = (int)(System.currentTimeMillis() / 1000L);
+ new Random().nextBytes(clientRandom);
+ clientRandom[0] = (byte)(now>>>24);
+ clientRandom[1] = (byte)(now>>>16);
+ clientRandom[2] = (byte)(now>>>8);
+ clientRandom[3] = (byte)(now>>>0);
+ System.arraycopy(clientRandom,0,buf,p,32);
+ p += 32;
+
+ buf[p++] = sessionID != null ? (byte)sessionID.length : 0;
+ if(sessionID != null && sessionID.length != 0) System.arraycopy(sessionID,0,buf,p,sessionID.length);
+ p += sessionID != null ? sessionID.length : 0;
+ buf[p++] = 0x00; // 4 bytes of ciphers
+ buf[p++] = 0x04;
+ buf[p++] = 0x00; // SSL_RSA_WITH_RC4_128_SHA
+ buf[p++] = 0x05;
+ buf[p++] = 0x00; // SSL_RSA_WITH_RC4_128_MD5
+ buf[p++] = 0x04;
+
+ buf[p++] = 0x01;
+ buf[p++] = 0x00;
+
+ sendHandshake((byte)1,buf);
+ flush();
+ }
+
+ private void receiveServerHello() throws IOException {
+ // ServerHello
+ byte[] buf = readHandshake();
+ if(buf[0] != 2) throw new Exn("expected a ServerHello message");
+
+ if(buf.length < 6 + 32 + 1) throw new Exn("ServerHello too small");
+ if(buf.length < 6 + 32 + 1 + buf[6+32] + 3) throw new Exn("ServerHello too small " + buf.length+" "+buf[6+32]);
+
+ if(buf[4] != 0x03 || !(buf[5]==0x00 || buf[5]==0x01)) throw new Exn("server wants to use version " + buf[4] + "." + buf[5]);
+ tls = buf[5] == 0x01;
+ int p = 6;
+ serverRandom = new byte[32];
+ System.arraycopy(buf,p,serverRandom,0,32);
+ p += 32;
+ sessionID = new byte[buf[p++]&0xff];
+ if(sessionID.length != 0) System.arraycopy(buf,p,sessionID,0,sessionID.length);
+ p += sessionID.length;
+ int cipher = ((buf[p]&0xff)<<8) | (buf[p+1]&0xff);
+ p += 2;
+ switch(cipher) {
+ case 0x0004: sha = false; debug("Using SSL_RSA_WITH_RC4_128_MD5"); break;
+ case 0x0005: sha = true; debug("Using SSL_RSA_WITH_RC4_128_SHA"); break;
+ default: throw new Exn("Unsupported cipher " + cipher);
+ }
+ mac = new byte[sha ? 20 : 16];
+ if(buf[p++] != 0x0) throw new Exn("unsupported compression " + buf[p-1]);
+ }
+
+ private X509.Certificate[] receiveServerCertificates() throws IOException {
+ byte[] buf = readHandshake();
+ if(buf[0] != 11) throw new Exn("expected a Certificate message");
+ if((((buf[4]&0xff)<<16)|((buf[5]&0xff)<<8)|((buf[6]&0xff)<<0)) != buf.length-7) throw new Exn("size mismatch in Certificate message");
+ int p = 7;
+ int count = 0;
+
+ for(int i=p;i<buf.length-3;i+=((buf[p+0]&0xff)<<16)|((buf[p+1]&0xff)<<8)|((buf[p+2]&0xff)<<0)) count++;
+ if(count == 0) throw new Exn("server didn't provide any certificates");
+ X509.Certificate[] certs = new X509.Certificate[count];
+ count = 0;
+ while(p < buf.length) {
+ int len = ((buf[p+0]&0xff)<<16)|((buf[p+1]&0xff)<<8)|((buf[p+2]&0xff)<<0);
+ p += 3;
+ if(p + len > buf.length) throw new Exn("Certificate message cut short");
+ certs[count++] = new X509.Certificate(new ByteArrayInputStream(buf,p,len));
+ p += len;
+ }
+ return certs;
+ }
+
+ private void sendClientKeyExchange(X509.Certificate serverCert) throws IOException {
+ byte[] encryptedPreMasterSecret;
+ RSA.PublicKey pks = serverCert.getRSAPublicKey();
+ PKCS1 pkcs1 = new PKCS1(new RSA(pks.modulus,pks.exponent,false),random);
+ encryptedPreMasterSecret = pkcs1.encode(preMasterSecret);
+ byte[] buf;
+ if(tls) {
+ buf = new byte[encryptedPreMasterSecret.length+2];
+ buf[0] = (byte) (encryptedPreMasterSecret.length>>>8);
+ buf[1] = (byte) (encryptedPreMasterSecret.length>>>0);
+ System.arraycopy(encryptedPreMasterSecret,0,buf,2,encryptedPreMasterSecret.length);
+ } else {
+ // ugh... netscape didn't send the length bytes and now every SSLv3 implementation
+ // must implement this bug
+ buf = encryptedPreMasterSecret;
+ }
+ sendHandshake((byte)16,buf);
+ }
+
+ private void sendChangeCipherSpec() throws IOException {
+ sendRecord((byte)20,new byte[] { 0x01 });
+ }
+
+ private void computeMasterSecret() {
+ preMasterSecret = new byte[48];
+ preMasterSecret[0] = 0x03; // version_high
+ preMasterSecret[1] = tls ? (byte) 0x01 : (byte) 0x00; // version_low
+ randomBytes(preMasterSecret,2,46);
+
+ if(tls) {
+ masterSecret = tlsPRF(48,preMasterSecret,getBytes("master secret"),concat(clientRandom,serverRandom));
+ } else {
+ masterSecret = concat(new byte[][] {
+ md5(new byte[][] { preMasterSecret,
+ sha1(new byte[][] { new byte[] { 0x41 }, preMasterSecret, clientRandom, serverRandom })}),
+ md5(new byte[][] { preMasterSecret,
+ sha1(new byte[][] { new byte[] { 0x42, 0x42 }, preMasterSecret, clientRandom, serverRandom })}),
+ md5(new byte[][] { preMasterSecret,
+ sha1(new byte[][] { new byte[] { 0x43, 0x43, 0x43 }, preMasterSecret, clientRandom, serverRandom })})
+ } );
+ }
+ }
+
+ public void initCrypto() {
+ byte[] keyMaterial;
+
+ if(tls) {
+ keyMaterial = tlsPRF(
+ (mac.length + 16 + 0)*2, // MAC len + key len + iv len
+ masterSecret,
+ getBytes("key expansion"),
+ concat(serverRandom,clientRandom)
+ );
+ } else {
+ keyMaterial = new byte[] { };
+ for(int i=0; keyMaterial.length < 72; i++) {
+ byte[] crap = new byte[i + 1];
+ for(int j=0; j<crap.length; j++) crap[j] = (byte)(((byte)0x41) + ((byte)i));
+ keyMaterial = concat(new byte[][] { keyMaterial,
+ md5(new byte[][] { masterSecret,
+ sha1(new byte[][] { crap, masterSecret, serverRandom, clientRandom }) }) });
+ }
+ }
+
+ byte[] clientWriteMACSecret = new byte[mac.length];
+ byte[] serverWriteMACSecret = new byte[mac.length];
+ byte[] clientWriteKey = new byte[16];
+ byte[] serverWriteKey = new byte[16];
+
+ int p = 0;
+ System.arraycopy(keyMaterial, p, clientWriteMACSecret, 0, mac.length); p += mac.length;
+ System.arraycopy(keyMaterial, p, serverWriteMACSecret, 0, mac.length); p += mac.length;
+ System.arraycopy(keyMaterial, p, clientWriteKey, 0, 16); p += 16;
+ System.arraycopy(keyMaterial, p, serverWriteKey, 0, 16); p += 16;
+
+ Digest inner;
+
+ writeRC4 = new RC4(clientWriteKey);
+ inner = sha ? (Digest)new SHA1() : (Digest)new MD5();
+ clientWriteMACDigest = tls ? (Digest) new HMAC(inner,clientWriteMACSecret) : (Digest)new SSLv3HMAC(inner,clientWriteMACSecret);
+
+ readRC4 = new RC4(serverWriteKey);
+ inner = sha ? (Digest)new SHA1() : (Digest)new MD5();
+ serverWriteMACDigest = tls ? (Digest)new HMAC(inner,serverWriteMACSecret) : (Digest)new SSLv3HMAC(inner,serverWriteMACSecret);
+ }
+
+ private void sendFinished() throws IOException {
+ byte[] handshakes = handshakesBuffer.toByteArray();
+ if(tls) {
+ sendHandshake((byte)20, tlsPRF(
+ 12,
+ masterSecret,
+ getBytes("client finished"),
+ concat(md5(handshakes),sha1(handshakes))));
+
+ } else {
+ sendHandshake((byte)20, concat(new byte[][] {
+ md5(new byte[][] { masterSecret, pad2,
+ md5(new byte[][] { handshakes, new byte[] { (byte)0x43, (byte)0x4C, (byte)0x4E, (byte)0x54 },
+ masterSecret, pad1 }) }),
+ sha1(new byte[][] { masterSecret, pad2_sha,
+ sha1(new byte[][] { handshakes, new byte[] { (byte)0x43, (byte)0x4C, (byte)0x4E, (byte)0x54 },
+ masterSecret, pad1_sha } ) })
+ }));
+ }
+ }
+
+ private void receiveChangeCipherSpec() throws IOException {
+ int size = readRecord((byte)20);
+ if(size == -1) throw new Exn("got eof when expecting a ChangeCipherSpec message");
+ if(size != 1 || readRecordBuf[0] != 0x01) throw new Exn("Invalid ChangeCipherSpec message");
+ }
+
+ private void receieveFinished() throws IOException {
+ byte[] handshakes = handshakesBuffer.toByteArray();
+ byte[] buf = readHandshake();
+ if(buf[0] != 20) throw new Exn("expected a Finished message");
+ byte[] expected;
+
+ if(tls) {
+ if(buf.length != 4 + 12) throw new Exn("Finished message too short");
+ expected = tlsPRF(
+ 12,masterSecret,
+ getBytes("server finished"),
+ concat(md5(handshakes),sha1(handshakes)));
+ } else {
+ if(buf.length != 4 + 16 +20) throw new Exn("Finished message too short");
+ expected = concat(new byte[][] {
+ md5(new byte[][] { masterSecret, pad2,
+ md5(new byte[][] { handshakes, new byte[] { (byte)0x53, (byte)0x52, (byte)0x56, (byte)0x52 },
+ masterSecret, pad1 }) }),
+ sha1(new byte[][] { masterSecret, pad2_sha,
+ sha1(new byte[][] { handshakes, new byte[] { (byte)0x53, (byte)0x52, (byte)0x56, (byte)0x52 },
+ masterSecret, pad1_sha } ) } ) } );
+ }
+ if(!eq(expected,0,buf,4,expected.length)) throw new Exn("server finished message mismatch");
+ }
+
+ private void flush() throws IOException { rawOS.flush(); }
+
+ private void sendHandshake(byte type, byte[] payload) throws IOException {
+ if(payload.length > (1<<24)) throw new IllegalArgumentException("payload.length");
+ byte[] buf = new byte[4+payload.length];
+ buf[0] = type;
+ buf[1] = (byte)(payload.length>>>16);
+ buf[2] = (byte)(payload.length>>>8);
+ buf[3] = (byte)(payload.length>>>0);
+ System.arraycopy(payload,0,buf,4,payload.length);
+ handshakesBuffer.write(buf);
+ sendRecord((byte)22,buf);
+ }
+
+ private void sendRecord(byte proto, byte[] buf) throws IOException { sendRecord(proto,buf,0,buf.length); }
+ private void sendRecord(byte proto, byte[] payload, int off, int totalLen) throws IOException {
+ int macLength = (negotiated & 1) != 0 ? mac.length : 0;
+ while(totalLen > 0) {
+ int len = min(totalLen,16384-macLength);
+ rawOS.writeByte(proto);
+ rawOS.writeShort(tls ? 0x0301 : 0x0300);
+ if((negotiated & 1) != 0) {
+ computeMAC(proto,payload,off,len,clientWriteMACDigest,clientSequenceNumber);
+ // FEATURE: Encode in place
+ writeRC4.process(payload,off,sendRecordBuf,0,len);
+ writeRC4.process(mac,0,sendRecordBuf,len,macLength);
+ rawOS.writeShort(len + macLength);
+ rawOS.write(sendRecordBuf,0, len +macLength);
+ clientSequenceNumber++;
+ } else {
+ rawOS.writeShort(len);
+ rawOS.write(payload,off,len);
+ }
+ totalLen -= len;
+ off += len;
+ }
+ }
+
+ private byte[] readHandshake() throws IOException {
+ if(handshakeDataLength == 0) {
+ handshakeDataStart = 0;
+ handshakeDataLength = readRecord((byte)22);
+ if(handshakeDataLength == -1) throw new Exn("got eof when expecting a handshake packet");
+ }
+ byte[] buf = readRecordBuf;
+ int len = ((buf[handshakeDataStart+1]&0xff)<<16)|((buf[handshakeDataStart+2]&0xff)<<8)|((buf[handshakeDataStart+3]&0xff)<<0);
+ // Handshake messages can theoretically span multiple records, but in practice this does not occur
+ if(len > handshakeDataLength) {
+ sendAlert(true,10); // 10 == unexpected message
+ throw new Exn("handshake message size too large " + len + " vs " + (handshakeDataLength-handshakeDataStart));
+ }
+ byte[] ret = new byte[4+len];
+ System.arraycopy(buf,handshakeDataStart,ret,0,ret.length);
+ handshakeDataLength -= ret.length;
+ handshakeDataStart += ret.length;
+ handshakesBuffer.write(ret);
+ return ret;
+ }
+
+ private int readRecord(byte reqProto) throws IOException {
+ int macLength = (negotiated & 2) != 0 ? mac.length : 0;
+ for(;;) {
+ byte proto;
+ int version, len;
+
+ try {
+ proto = rawIS.readByte();
+ } catch(EOFException e) {
+ // this may or may not be an error. it is up to the application protocol
+ closed = true;
+ super.close();
+ throw new PrematureCloseExn();
+ }
+ try {
+ version = rawIS.readShort();
+ if(version != 0x0300 && version != 0x0301) throw new Exn("invalid version ");
+ len = rawIS.readShort();
+ if(len <= 0 || len > 16384+((negotiated&2)!=0 ? macLength : 0)) throw new Exn("invalid length " + len);
+ rawIS.readFully((negotiated&2)!=0 ? readRecordScratch : readRecordBuf,0,len);
+ } catch(EOFException e) {
+ // an EOF here is always an error (we don't pass the EOF back on to the app
+ // because it isn't a "legitimate" eof)
+ throw new Exn("Hit EOF too early");
+ }
+
+ if((negotiated & 2) != 0) {
+ if(len < macLength) throw new Exn("packet size < macLength");
+ // FEATURE: Decode in place
+ readRC4.process(readRecordScratch,0,readRecordBuf,0,len);
+ computeMAC(proto,readRecordBuf,0,len-macLength,serverWriteMACDigest,serverSequenceNumber);
+ for(int i=0;i<macLength;i++)
+ if(mac[i] != readRecordBuf[len-macLength+i])
+ throw new Exn("mac mismatch");
+ len -= macLength;
+ serverSequenceNumber++;
+ }
+
+ if(proto == reqProto) return len;
+
+ switch(proto) {
+ case 21: { // ALERT
+ if(len != 2) throw new Exn("invalid lengh for alert");
+ int level = readRecordBuf[0];
+ int desc = readRecordBuf[1];
+ if(level == 1) {
+ if(desc == 0) { // CloseNotify
+ debug("Server requested connection closure");
+ try {
+ sendCloseNotify();
+ } catch(SocketException e) { /* incomplete close, thats ok */ }
+ closed = true;
+ super.close();
+ return -1;
+ } else {
+ warnings++;
+ log("SSL ALERT WARNING: desc: " + desc);
+ }
+ } else if(level == 2) {
+ throw new Exn("SSL ALERT FATAL: desc: " +desc);
+ } else {
+ throw new Exn("invalid alert level");
+ }
+ break;
+ }
+ case 22: { // Handshake
+ int type = readRecordBuf[0];
+ int hslen = ((readRecordBuf[1]&0xff)<<16)|((readRecordBuf[2]&0xff)<<8)|((readRecordBuf[3]&0xff)<<0);
+ if(hslen > len - 4) throw new Exn("Multiple sequential handshake messages received after negotiation");
+ if(type == 0) { // HellloRequest
+ if(tls) sendAlert(false,100); // politely refuse, 100 == NoRegnegotiation
+ } else {
+ throw new Exn("Unexpected Handshake type: " + type);
+ }
+ }
+ default: throw new Exn("Unexpected protocol: " + proto);
+ }
+ }
+ }
+
+ private static void longToBytes(long l, byte[] buf, int off) {
+ for(int i=0;i<8;i++) buf[off+i] = (byte)(l>>>(8*(7-i)));
+ }
+ private void computeMAC(byte proto, byte[] payload, int off, int len, Digest digest, long sequenceNumber) {
+ if(tls) {
+ longToBytes(sequenceNumber,mac,0);
+ mac[8] = proto;
+ mac[9] = 0x03; // version
+ mac[10] = 0x01;
+ mac[11] = (byte)(len>>>8);
+ mac[12] = (byte)(len>>>0);
+
+ digest.update(mac,0,13);
+ digest.update(payload,off,len);
+ digest.doFinal(mac,0);
+ } else {
+ longToBytes(sequenceNumber, mac, 0);
+ mac[8] = proto;
+ mac[9] = (byte)(len>>>8);
+ mac[10] = (byte)(len>>>0);
+
+ digest.update(mac, 0, 11);
+ digest.update(payload, off, len);
+ digest.doFinal(mac, 0);
+ }
+ }
+
+ private void sendCloseNotify() throws IOException { sendRecord((byte)21, new byte[] { 0x01, 0x00 }); }
+ private void sendAlert(boolean fatal, int message) throws IOException {
+ byte[] buf = new byte[] { fatal ? (byte)2 :(byte)1, (byte)message };
+ sendRecord((byte)21,buf);
+ flush();
+ }
+
+ //
+ // Hash functions
+ //
+
+ // Shared digest objects
+ private MD5 masterMD5 = new MD5();
+ private SHA1 masterSHA1 = new SHA1();
+
+ private byte[] md5(byte[] in) { return md5( new byte[][] { in }); }
+ private byte[] md5(byte[][] inputs) {
+ masterMD5.reset();
+ for(int i=0; i<inputs.length; i++) masterMD5.update(inputs[i], 0, inputs[i].length);
+ byte[] ret = new byte[masterMD5.getDigestSize()];
+ masterMD5.doFinal(ret, 0);
+ return ret;
+ }
+
+ private byte[] sha1(byte[] in) { return sha1(new byte[][] { in }); }
+ private byte[] sha1(byte[][] inputs) {
+ masterSHA1.reset();
+ for(int i=0; i<inputs.length; i++) masterSHA1.update(inputs[i], 0, inputs[i].length);
+ byte[] ret = new byte[masterSHA1.getDigestSize()];
+ masterSHA1.doFinal(ret, 0);
+ return ret;
+ }
+
+ /* RFC-2246
+ PRF(secret, label, seed) = P_MD5(S1, label + seed) XOR P_SHA-1(S2, label + seed);
+ L_S = length in bytes of secret;
+ L_S1 = L_S2 = ceil(L_S / 2);
+
+ The secret is partitioned into two halves (with the possibility of
+ one shared byte) as described above, S1 taking the first L_S1 bytes
+ and S2 the last L_S2 bytes.
+
+ P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) +
+ HMAC_hash(secret, A(2) + seed) +
+ HMAC_hash(secret, A(3) + seed) + ...
+
+ A(0) = seed
+ A(i) = HMAC_hash(secret, A(i-1))
+ */
+ private byte[] tlsPRF(int size,byte[] secret, byte[] label, byte[] seed) {
+ if(size > 112) throw new IllegalArgumentException("size > 112");
+ seed = concat(label,seed);
+
+ int half_length = (secret.length + 1) / 2;
+ byte[] s1 = new byte[half_length];
+ System.arraycopy(secret,0,s1,0,half_length);
+ byte[] s2 = new byte[half_length];
+ System.arraycopy(secret,secret.length - half_length, s2, 0, half_length);
+
+ Digest hmac_md5 = new HMAC(new MD5(),s1);
+ Digest hmac_sha = new HMAC(new SHA1(),s2);
+
+ byte[] md5out = new byte[112];
+ byte[] shaout = new byte[120];
+ byte[] digest = new byte[20];
+ int n;
+
+ n = 0;
+ hmac_md5.update(seed,0,seed.length);
+ hmac_md5.doFinal(digest,0);
+
+ // digest == md5_a_1
+ while(n < size) {
+ hmac_md5.update(digest,0,16);
+ hmac_md5.update(seed,0,seed.length);
+ hmac_md5.doFinal(md5out,n);
+ hmac_md5.update(digest,0,16);
+ hmac_md5.doFinal(digest,0);
+ n += 16;
+ }
+
+ n = 0;
+ hmac_sha.update(seed,0,seed.length);
+ hmac_sha.doFinal(digest,0);
+
+ while(n < size) {
+ hmac_sha.update(digest,0,20);
+ hmac_sha.update(seed,0,seed.length);
+ hmac_sha.doFinal(shaout,n);
+ hmac_sha.update(digest,0,20);
+ hmac_sha.doFinal(digest,0);
+ n += 20;
+ }
+
+ byte[] ret = new byte[size];
+ for(int i=0;i<size;i++) ret[i] = (byte)(md5out[i] ^ shaout[i]);
+ return ret;
+ }
+
+ public static class SSLv3HMAC extends Digest {
+ private final Digest h;
+ private final byte[] digest;
+ private final byte[] key;
+ private final int padSize;
+
+ public int getDigestSize() { return h.getDigestSize(); }
+
+ public SSLv3HMAC(Digest h, byte[] key) {
+ this.h = h;
+ this.key = key;
+ switch(h.getDigestSize()) {
+ case 16: padSize = 48; break;
+ case 20: padSize = 40; break;
+ default: throw new IllegalArgumentException("unsupported digest size");
+ }
+ digest = new byte[h.getDigestSize()];
+ reset();
+ }
+ public void reset() {
+ h.reset();
+ h.update(key,0,key.length);
+ h.update(pad1,0,padSize);
+ }
+ public void update(byte[] b, int off, int len) { h.update(b,off,len); }
+ public void doFinal(byte[] out, int off){
+ h.doFinal(digest,0);
+ h.update(key,0,key.length);
+ h.update(pad2,0,padSize);
+ h.update(digest,0,digest.length);
+ h.doFinal(out,off);
+ reset();
+ }
+ protected void processWord(byte[] in, int inOff) {}
+ protected void processLength(long bitLength) {}
+ protected void processBlock() {}
+ }
+
+ //
+ // Static Methods
+ //
+
+ private static SecureRandom random = new SecureRandom();
+ public static synchronized void randomBytes(byte[] buf, int off, int len) {
+ byte[] bytes = new byte[len];
+ random.nextBytes(bytes);
+ System.arraycopy(bytes,0,buf,off,len);
+ }
+
+ public static byte[] concat(byte[] a, byte[] b) { return concat(new byte[][] { a, b }); }
+ public static byte[] concat(byte[] a, byte[] b, byte[] c) { return concat(new byte[][] { a, b, c }); }
+ public static byte[] concat(byte[][] inputs) {
+ int total = 0;
+ for(int i=0; i<inputs.length; i++) total += inputs[i].length;
+ byte[] ret = new byte[total];
+ for(int i=0,pos=0; i<inputs.length;pos+=inputs[i].length,i++)
+ System.arraycopy(inputs[i], 0, ret, pos, inputs[i].length);
+ return ret;
+ }
+
+ public static byte[] getBytes(String s) {
+ try {
+ return s.getBytes("US-ASCII");
+ } catch (UnsupportedEncodingException e) {
+ return null; // will never happen
+ }
+ }
+
+ public static boolean eq(byte[] a, int aoff, byte[] b, int boff, int len){
+ for(int i=0;i<len;i++) if(a[aoff+i] != b[boff+i]) return false;
+ return true;
+ }
+
+ //
+ // InputStream/OutputStream/Socket interfaces
+ //
+ public OutputStream getOutputStream() { return sslOS; }
+ public InputStream getInputStream() { return sslIS; }
+ public synchronized void close() throws IOException {
+ if(!closed) {
+ if(negotiated != 0) {
+ sendCloseNotify();
+ flush();
+ // don't bother sending a close_notify back to the server
+ // this is an incomplete close which is allowed by the spec
+ }
+ super.close();
+ closed = true;
+ }
+ }
+
+ private int read(byte[] buf, int off, int len) throws IOException {
+ if(pendingLength == 0) {
+ if(closed) return -1;
+ int readLen = readRecord((byte)23);
+ if(readLen == -1) return -1; // EOF
+ len = min(len,readLen);
+ System.arraycopy(readRecordBuf,0,buf,off,len);
+ if(readLen > len) System.arraycopy(readRecordBuf,len,pending,0,readLen-len);
+ pendingStart = 0;
+ pendingLength = readLen - len;
+ return len;
+ } else {
+ len = min(len,pendingLength);
+ System.arraycopy(pending,pendingStart,buf,off,len);
+ pendingLength -= len;
+ pendingStart += len;
+ return len;
+ }
+ }
+
+ private void write(byte[] buf, int off, int len) throws IOException {
+ if(closed) throw new SocketException("Socket closed");
+ sendRecord((byte)23,buf,off,len);
+ flush();
+ }
+
+ private class SSLInputStream extends InputStream {
+ public int available() throws IOException {
+ synchronized(SSL.this) {
+ return negotiated != 0 ? pendingLength : rawIS.available();
+ }
+ }
+ public int read() throws IOException {
+ synchronized(SSL.this) {
+ if(negotiated==0) return rawIS.read();
+ if(pendingLength > 0) {
+ pendingLength--;
+ return pending[pendingStart++];
+ } else {
+ byte[] buf = new byte[1];
+ int n = read(buf);
+ return n == -1 ? -1 : buf[0]&0xff;
+ }
+ }
+ }
+ public int read(byte[] buf, int off, int len) throws IOException {
+ synchronized(SSL.this) {
+ return negotiated!=0 ? SSL.this.read(buf,off,len) : rawIS.read(buf,off,len);
+ }
+ }
+ public long skip(long n) throws IOException {
+ synchronized(SSL.this) {
+ if(negotiated==0) return rawIS.skip(n);
+ if(pendingLength > 0) {
+ n = min((int)n,pendingLength);
+ pendingLength -= n;
+ pendingStart += n;
+ return n;
+ }
+ return super.skip(n);
+ }
+ }
+ }
+
+ private class SSLOutputStream extends OutputStream {
+ public void flush() throws IOException { rawOS.flush(); }
+ public void write(int b) throws IOException { write(new byte[] { (byte)b }); }
+ public void write(byte[] buf, int off, int len) throws IOException {
+ synchronized(SSL.this) {
+ if(negotiated!=0)
+ SSL.this.write(buf,off,len);
+ else
+ rawOS.write(buf,off,len);
+ }
+ }
+ }
+
+ public static class Exn extends IOException { public Exn(String s) { super(s); } }
+ public static class PrematureCloseExn extends Exn {
+ public PrematureCloseExn() { super("Connection was closed by the remote WITHOUT a close_noify"); }
+ }
+
+ public static boolean debugOn = false;
+ private static void debug(Object o) { if(debugOn) System.err.println("[BriSSL-Debug] " + o.toString()); }
+ private static void log(Object o) { System.err.println("[BriSSL] " + o.toString()); }
+
+ private static void verifyCerts(X509.Certificate[] certs) throws DER.Exception, Exn {
+ try {
+ verifyCerts_(certs);
+ } catch(RuntimeException e) {
+ e.printStackTrace();
+ throw new Exn("Error while verifying certificates: " + e);
+ }
+ }
+
+ private static void verifyCerts_(X509.Certificate[] certs) throws DER.Exception, Exn {
+ boolean ignoreLast = false;
+ for(int i=0;i<certs.length;i++) {
+ debug("Cert " + i + ": " + certs[i].subject + " ok");
+ if(!certs[i].isValid())
+ throw new Exn("Certificate " + i + " in certificate chain is not valid (" + certs[i].startDate + " - " + certs[i].endDate + ")");
+ if(i != 0) {
+ X509.Certificate.BC bc = certs[i].basicContraints;
+ if(bc == null) {
+ if(i == certs.length - 1) {
+ ignoreLast = true;
+ break;
+ }
+ throw new Exn("CA-cert lacks Basic Constraints");
+ } else {
+ if(!bc.isCA) throw new Exn("non-CA certificate used for signing");
+ if(bc.pathLenConstraint != null && bc.pathLenConstraint.longValue() < i-1) throw new Exn("CA cert can't be used this deep");
+ }
+ }
+ if(i != certs.length - 1) {
+ if(!certs[i].issuer.equals(certs[i+1].subject))
+ throw new Exn("Issuer for certificate " + i + " does not match next in chain");
+ if(!certs[i].isSignedBy(certs[i+1]))
+ throw new Exn("Certificate " + i + " in chain is not signed by the next certificate");
+ }
+ }
+
+ X509.Certificate cert = certs[ignoreLast ? certs.length - 2 : certs.length-1];
+
+ RSA.PublicKey pks = (RSA.PublicKey) caKeys.get(cert.issuer);
+ if(pks == null) throw new Exn("Certificate is signed by an unknown CA (" + cert.issuer + ")");
+ if(!cert.isSignedWith(pks)) throw new Exn("Certificate is not signed by its CA");
+ log("" + cert.subject + " is signed by " + cert.issuer);
+ }
+
+ public static void addCACert(byte[] b) throws IOException { addCACert(new ByteArrayInputStream(b)); }
+ public static void addCACert(InputStream is) throws IOException { addCACert(new X509.Certificate(is)); }
+ public static void addCACert(X509.Certificate cert) throws DER.Exception { addCAKey(cert.subject,cert.getRSAPublicKey()); }
+ public static void addCAKey(X509.Name subject, RSA.PublicKey pks) {
+ synchronized(caKeys) {
+ if(caKeys.get(subject) != null)
+ throw new IllegalArgumentException(subject.toString() + " already exists!");
+ caKeys.put(subject,pks);
+ }
+ }
+
+ static {
+ try {
+ // This will force a <clinit> which'll load the certs
+ Class.forName("org.ibex.net.ssl.RootCerts");
+ log("Loaded root keys from org.ibex.net.ssl.RootCerts");
+ } catch(ClassNotFoundException e) {
+ InputStream is = SSL.class.getClassLoader().getResourceAsStream("org.ibex/net/ssl/rootcerts.dat");
+ if(is != null) {
+ try {
+ addCompactCAKeys(is);
+ log("Loaded root certs from rootcerts.dat");
+ } catch(IOException e2) {
+ log("Error loading certs from rootcerts.dat: " + e2.getMessage());
+ }
+ }
+ }
+ }
+
+ public static int addCompactCAKeys(InputStream is) throws IOException {
+ synchronized(caKeys) {
+ try {
+ Vector seq = (Vector) new DER.InputStream(is).readObject();
+ for(Enumeration e = seq.elements(); e.hasMoreElements();) {
+ Vector seq2 = (Vector) e.nextElement();
+ X509.Name subject = new X509.Name(seq2.elementAt(0));
+ RSA.PublicKey pks = new RSA.PublicKey(seq2.elementAt(1));
+ addCAKey(subject,pks);
+ }
+ return seq.size();
+ } catch(RuntimeException e) {
+ e.printStackTrace();
+ throw new IOException("error while reading stream: " + e);
+ }
+ }
+ }
+
+ public static synchronized void setVerifyCallback(VerifyCallback cb) { verifyCallback = cb; }
+
+ // State Info
+ public static class State {
+ byte[] sessionID;
+ byte[] masterSecret;
+ State(byte[] sessionID, byte[] masterSecret) {
+ this.sessionID = sessionID;
+ this.masterSecret = masterSecret;
+ }
+ }
+
+ public interface VerifyCallback {
+ public boolean checkCerts(X509.Certificate[] certs, String hostname, Exn exn);
+ }
+
+ // Helper methods
+ private static final int min(int a, int b) { return a < b ? a : b; }
+}
--- /dev/null
+package org.ibex.net.ssl;
+
+import java.io.*;
+//import org.bouncycastle.asn1.*;
+//import org.bouncycastle.asn1.x509.*;
+
+public class GenCompactCAList {
+ /*
+ public static void main(String[] args) throws Exception {
+ if(args.length < 2) throw new Exception("Usage: GenCAList format file(s)");
+ String format = args[0];
+ DER.EncodableVector vec = new DEREncodableVector();
+ for(int i=1;i<args.length;i++) {
+ X509.CertificateStructure x509 = new X509.CertificateStructure((ASN1Sequence) new ASN1InputStream(new FileInputStream(args[i])).readObject());
+ X509.Name subject = x509.getSubject();
+ SubjectPublicKeyInfo pki = x509.getSubjectPublicKeyInfo();
+ RSA.PublicKeyStructure rsa = new RSA.PublicKeyStructure((ASN1Sequence) pki.getPublicKey());
+ DER.EncodableVector vec2 = new DEREncodableVector();
+ vec2.add(subject);
+ vec2.add(rsa);
+ vec.add(new DERSequence(vec2));
+ }
+ if(format.equals("binary")) {
+ DER.OutputStream dos = new DEROutputStream(System.out);
+ dos.writeObject(new DERSequence(vec));
+ dos.close();
+ } else if(format.equals("class")){
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ DER.OutputStream dos = new DEROutputStream(baos);
+ dos.writeObject(new DERSequence(vec));
+ dos.close();
+ baos.close();
+ byte[] buf = baos.toByteArray();
+ StringBuffer sb = new StringBuffer();
+ for(int i=0;i<buf.length;i+=7) {
+ long l = 0;
+ for(int j=0;j<7;j++) {
+ l <<= 8;
+ byte b = (i+j < buf.length) ? buf[i+j] : -1;
+ l |= (b & 0xffL);
+ }
+ for(int j=0;j<8;j++) {
+ char c = (char) ((l>>>(7*(7-j)))&0x7f);
+ if(c=='\n') sb.append("\\n");
+ else if(c=='\r') sb.append("\\r");
+ else if(c=='\\') sb.append("\\\\");
+ else if(c=='"') sb.append("\\\"");
+ else if(c >= 32 && c <= 126) sb.append(c);
+ else sb.append("\\" + toOctal3(c));
+ }
+ }
+ System.out.println("package org.ibex.net.ssl;");
+ System.out.println("public final class RootCerts {");
+ System.out.println(" private final static String DATA = \"" + sb.toString() + "\";");
+ System.out.print(
+ " static {\n" +
+ " try {\n" +
+ " org.ibex.net.SSL.addCompactCAKeys(new java.io.ByteArrayInputStream(unpack(DATA)));\n" +
+ " } catch(Exception e) {\n" +
+ " System.err.println(\"Error loading root CA keys: \" + e.getMessage());\n" +
+ " }\n" +
+ " }\n");
+ System.out.println(" public static void load() { }"); // force clinit
+ System.out.print(
+ " private static byte[] unpack(String s) {\n" +
+ " int len = s.length();\n" +
+ " if(len % 8 != 0) throw new IllegalArgumentException(\"not a multiple of 8\");\n" +
+ " byte[] ret = new byte[(len / 8) * 7];\n" +
+ " for(int i=0; i<len; i += 8) {\n" +
+ " long l = 0;\n" +
+ " for(int j=0;j<8;j++) {\n" +
+ " l <<= 7;\n" +
+ " l |= (s.charAt(i + j) & 0x7fL);\n" +
+ " }\n" +
+ " int base = (i / 8) * 7;\n" +
+ " for(int j=6; j>=0; j--) {\n" +
+ " ret[base + j] = (byte)(l & 0xff);\n" +
+ " l >>>= 8;\n" +
+ " }\n" +
+ " }\n" +
+ " return ret;\n" +
+ " }");
+ System.out.println("}");
+ } else {
+ throw new Error("unknown format");
+ }
+ }
+
+ private final static String toOctal3(int n) {
+ char[] buf = new char[3];
+ for(int i=2;i>=0;i--) {
+ buf[i] = (char) ('0' + (n & 7));
+ n >>= 3;
+ }
+ return new String(buf);
+ }
+ */
+}
--- /dev/null
+package org.ibex.net.ssl;
+public final class RootCerts {
+ private final static String DATA = "\030 Oi\031B\004\001M\014\020\030ID\0260\004A@5(\020\014\023\001\025*3\010,`\011\003\000jP &\002\"\020f\021\031@\"\006\001U @8L\024W0\\m\006K9Nt7[F\0219@*\006\001U @PL\034A!\020%d*\r\036M\026\010\011\024r\014\\1\014L\002p0\r*\004\001Db\004\n\011\002.\"Piti\001$o7]\004\004\032\004b$\030\010@`I*\014HC=aP\010$\002\026\nX,Fk%\\@2\032,w\033%Nt9\035.7!9Fo6L\020 \010(\005\002\000@ \013\016L#`<U(08!\031K\002P@\016\0206\006F\036y\022;UX\rS\006V7Sv\007\034C3@1\"\r#_<f4\024,eA+\026)a\014`(\0034D$`\033\005 *J%C%\035V\032[~p6(t\021NIq>4\nHEq?\037L\014\027H{ajbF\036G^\013I0h_F\037\011@A&:@*zgGl\017=5x=q(\030:BLZ\016T[\032}4\"K{\003\031^\004\nh~yVzLF(,r\036\011\002 hJ\031\035:rYad\025\ngPV/\000s*_}Z}VBYv9\026\034G\013\007:')i^nsg-b\003TN\011!32\022*e6F1\033g\004UF;3K_K\026[\010>\005f\011W\014)&\nZ\002S\017\"e,m\037\014ogh\000B-Jt\024\026:2T>%%'o~x o\027W\011#i;H/\037y1P\011c\"gT\0241!\001\001\001\000`\020\000\004a\002\000_f\006yD\0260\004A@5(\020\014\023\001\024hS\010P`\022\003\000jP (&\013 Y\014E#Ijs:\010\010\024\021DL0\022\001@5(\020\026\023\016P,F\"Qdu9]\004\004+ahe9\033L\026a\001(T(\010\011f+Qno9\032f\022\021@@\006\001U @\030L2A2\031\nG\023Uft\020\021/\007#\025dn0[\004\004\032\004@R7[nC\004\010\002\n\001 @\020\010\002ow\r\014|o\020\000\010-\034x\011e_4?<6\003y[/hG6g7S1\011N/$\024S\017Y\034~zJ^$}P\030kG\017gy-U\002k-\027\024e\013(\005A\022zmKR_mc\025?\033N\005Qqz\"AV\\\nl?A\036?t\014Sg&+\021\020*:8ex=q\035M\020\007@u1C*/\005\021yt\036Bj(7\032yR:^\005YiN\031$qc3(\030\001,8N:8\003a@*G&Pi\023\006\022\nZ2`O\021jg$|\0231_g'|\026K>wW!5m4'\023\017-w\033(\025{I4q\004\rv7K\026HYP%\006\1778\000^\ra$N-V@prmE\025\004.\021:*>mvM6\023],fDhK>$W]!@\004_S\006ri5\026\0041\r^N3GUNUOW\032)kQVpQ-K6iPMq-Jp{}{}\025jO*4-\011` \030\004\000\001\030 @\027)AJ1\005L\001\0200\r*\004\003\004`%\032\024b\024\030\004@`\032T\010\n\011Bh\026#\021(r:\\nB\002\005\0041\016L\00300\r*\004\005DbD\013\021HT9\035.7!\001(T(\010\011f+Qno9\032f\022\011@>\006\001U @\030L0A2\031\nG\023Uft\020\020mF\013Mf \030H\0104\011\001$o7]\006\010\020\004\024\002A\000 \020\004Z-T\020R,\016\023/PA\003C\033l'\0038\023\021s8\023.\037wV'\004!&:{j\006-ZtPAm6)\013\016\\x=Hh\006bo\000Z(\ry\002eJ\"\nw\006\021\001^uSm\037xZV`E9n\031\032:\025\027\004\03704<`\004o)vF\035S\1771N+GJ{^lVbm5:\027%R:\036CF7IH~pA$S\026\0136\0320\004#n\023}\031\020W\014~\004]b-L\\R]\021yE;\021y`\001D.=1g_RK_5\026rb\0252H\037#+\031S^oK\036\026upa[\026\011\002-_,j54$\0310\005B.!\036]\004\022\033\024h+]^\013\032\036[Bv\034fTDL:\030tW[TIU\0173\033i\016\013I]\0101L:HpKw/DM\031\\1aWC\005xcG4*h\016.,|3d\\7Zp$\030l,5lI~cx\0119\025\0318??&@@0\010\000\0020A\000.C\003\020b\013\030\002 `\032T\010\006\011@J4)D(0\011\001@5(\020\024\023\005P,F\"Qdu9]\004\004\n\010b\035\030\006``\032T\010\013\011E\010\026#\021(r:\\nB\002Q(P\020\023LW#]^r5L$\003\000x\014\003*A\0001\030]\002d2\025\016'+Mh (\035,&c%F !P$\005\023=^t\030 @\020P\n\004\001\000@\035\021QB\037\003D\005\030\022\006`y\033GFo`\033RwZ4thj/b\035B\006\0042\005\r\024^f*\020\n^Vl>J+;Sr\033;h9eh7\026\177I}y.adf\014x9xq;\024h\017`CE\0223\002\020a\1776&9\036Xp\014\\\016\027|uc\002aAz\016=\007L!v\031\027@~_,'>M\010\036\023}GtZ\022g7\0346'\021{\003*QI\034`; \001ScyE\011nvG8\011g]fD2Bax\010|_cCgn\007\034\177J\031\024\\\026[\004\027fH0\006[\010Kzllj{#\177n\037>(&jtwVw\020\000F\036O\007k\0253y;+QH\010Y\027.8dR?\010lo\011\004\020@R-D=wFB\007vjR\022\r\001@9O@>,\017sgI\010y7 \016\\Q\013k2e\r\024\005k\001UZ.\027'h\020#(uL Y4Q\034X\020cS}\003\003z\002\001@ \000\011B\004\001;L\014s\010,`\011\003\000jP \030&\002)Q&\021!@$\006\001U @PL\026A2\031\nG\023Uft\020\020(#\010t`\033\003\000jP ,&\024 Y\014E#Ijs:\010\nE\"@@N2]\016v{IV1\021L\004\0200\r*\004\001Dc$\013\021HT9\035.7!\001\"u0[\r\0263%Jd\020\020h\022\002I^o:\014\020 \010(\005\002\000@ \016 z5~n\002+(=\022>G_\004+z|\020i[1\017\017\027E_R0Z{\001Aa+\010\026\177x\035G\017.\025u\010[]Tx6#R\011\006\005THT\003BR\010B<8EI\177\021\004S+L98/\0043n\026UMN\001,|+T7N`xR}Ad\023kF\177\rs\032\017\005\\Q}\025:Sk\035Br\004U?>l=Rc8\025(\0375GD3 7\\\004WqyRJ?Cd-G>Z\010\010fE\031O\006TD\"fB%qz:m)?\034z\001uP/x\022n\007`Lq-^\005$_\016[\035+Q0\006\0351>?`\177E\013\037d\022'YC_\011E OW\037hK\"\037@`t:o\011;\037>M\001mR\001B,!oC\021`UF_\000S8e\033\002-j]\020\017G\032t8 \031Ll[:IMT\027D$k![i7\014St4\016{\"6v*\000\177L\013mKK\0271i\001\000`\020\000\004a\002\000GF\010\014<b\013\030\002 `\032T\010\006\011@JU\031DN0\022A@5(\020\024\023\017\020-V+IRc0[D\004+a`r2\\n2\002\r^m8\030-gI0@I7\030ec\011\030`$\003\000jP ,&\035 [,W\023%Fa7\010\010WCAde9\\d\005#\025Fh7\033mF{\035Re9L%s\0014\014\003*A\0001\031\031\002m2\\M\026\033\005\\ \"^\016\007\023\025fs\020\020lW\023QRf4Xl\027#\024@A:]\r\006{IRt<L\020\030H\n\003\001\0002>$LJ\013J~E%\033(\032lDv?\021\n\037J\rN\177E\011r r%ya\010x\034r\017>]\0322\027\001'3**8$)\031.]-MJ<5\031\036AP\"n\023/Z\000)d*#zD_\004\024\000_\033\025\014\034x/r7-\031s^H\177Rd\037\\\022V\r\037 0\0017DbE\021L\003\002:&\017\\<f\007|[l\030=\011e[yZ\017\006\033\0313)dmln\010VdH\033\013\037\020\020\014\002\000\000L\020 \r\034a\001K\014!3\000$\014\003*A\000a\030\011*S\030If\002(\030\006U\002\002B1r\005Ze9\032,6\0138@E<\034\016&+Mf ![mW\003\005\\y\026\010\011\026s\014\\1\023\014\004@0\r*\004\005DcT\0135Jr4Xl\026q\001\nx8\034LW\033L@T2Xm\006s=Xo3Z,W\031Dl0\032\001@5(\020\006\023\026P-V+IRc0[D\004+a`r2\\n2\002\035Xo1\030-B\002\rJr:\032,fK\rBt2H\010\027+QPo9\032.GIB\004\001\005\000P \010\004\001p\022\011LbwoVJ9\\*8J\037\026&\036\024r)\"3\025BBm!_F\r/=\027JCvPbnWWC\000\0017jA6H)^qU\004\\f\0231m\n\034*&i3-(e14;\002u$\001@Q\013\005\011(# _\036RVs |\031q\0250Q47E\022I2e\027\036H\0350m\177\011\017kpz)t\033z\017J\023F\014iuW\002@2_?F\013>[\03393u\025vcgym\033R\021\007i\0315u\037D\ru$r/zb\034HS<kF\020'\00582\030f\n~\014*Z+.X\026 :9S*e^2\0020o;(=vw8<i\013Y)%\002g+e\026oD\"o6y@p\000\007_\032yIAZ3d&gW~\0251cVY\021ZZwd\005C=\034\006,-\030(ec\021\011Q9-~G{fY2Rh\033g7E\\*K7T@\026x+\017Xm<~(H\010}5P\020\014\002\000\000L\020 \013\\`g\030Bf\000H\030\006U\002\001B0\022%\n1\011\014\002\0000\r*\004\005\004a\024\023\005Xt4[-w\023\024b\023\030\004 `\032T\010\013\011BH7K\011Jr*\034NW\033Pb/\030\013 `\032T\010\003\011IH&\0131hi6[n&)\001\006y1\031.%#Ijs:\010\0106{\021J )Z,vs%\\g\020\024Mv{Pa\002\000B@(\020\004\002\000d\0343!@J\034zm~3/b\006_Xy=\001\030u4\177~3MgMV$LPXl'l_!\034s\000<V-gO\nF}B=qD[\035'p'\020Ei\000\034zP*Fh_hQ6<\013V>g!\017s\002<\022\002\035SU/rTw\000/]\016]\025a^\032=\023\014;\032mZ jI\003Wz$N^\r\010\024P+!wi8-v3BD\027\022@c\\3u\022\002\035:n\"G;\010ZNv=;gT\023CIlZ#]N/.@M!daU,\004\023WDz,\001UA\035\026\0079CZqjC=/L&Q,Hg\013O\024\021D;WN;\023oP\010FN4\002k\020I\026\003v~|A~h@\001\007\000Xl\036;j=4\013\036\n\035a\032-\020\011K6<vj$E\024\005F+R\033i\014q\023\177@b]kF\\,dm\002\".\034g@`fa8dk2l6>xJ`]6h\010\006\001\000\000&\010\017<`a\030Bf\000H\030\006U\002\001B0\022%\n1\011\014\002\0000\r*\004\005\004a\024\023\005Xt4[-w\023\024b\023\030\004 `\032T\010\013\011BH7K\011Jr*\034NW\033Pb)\030\011``\032T\010\003\011H\010&\0131hi6[n&)\001\006y1\031.%#Ijs:\010\011V{\011Rl2H\n&{=h0@b (\014\004\001#6l'\00553y5+\010;l\004A:&#`Xgl<? Bce{^SB\034\016|DAy\"`/\\i\024V}\010D 2?PD9q|+6\032-+FS\001\026G#\n n5^Aj/`Ju\036\002/\026f\011\r\026\006)#ZF+UjEItG\0206\011^\000Z\"P\027XmBh$c^\004)%q\030$\035q\011@^0=>\"\017^Kw4R]O-\n\001jZ\0274\"\030@@0\010\000\0020A\000-#\002hb\013\030\002 `\032T\010\006\011@I\024)D$0\010\001@5(\020\024\023\004PL\026cQRm7\\LS\010L`\021\003\000jP ,&\n!^,&+I(r:\\nC\011\010` \003\000jP \014&\031!\030-G#%Zo9\031$\004\033eDe9\025\016'+Mh )\033mw!B\004\001\005\000P \010\004\001#\002.d*\\`zWt\011N)UUsT\024x\\\036DV\0011X8k8q,S\03227t\025o6`\011\002[;2A;\034bQ\030_k$#4\022uN\0352\014w\000A\025@*'\\!oS\016#x{Uf\02155\002<w\037 \"@St9LS\n\032-rca:2C%((0e\016WVV%CbS)0rRg\\\017aM/_rR\011Kx!^U`px#x\001\026(\rKM8;\034QMtwk>\035KOEPD!\022\002=\026\003\005$W\027L\017uZL\005~-\033P:d\005T,F\023\006\037VJcp$\001Gjvd\006=<p^W/(\003W\027PCr\177~\025vZ7OIdlr:snu\0227gIH\013\027\023o\027\022#)Ocr$`B\\\003f%\033n\030uls[PcS..t1LwV@`cp<#.k\177r=\016.JPj:6!\\\023FG\020\020\014\002\000\000L\020 \rda\001T\014!3\000$\014\003*A\000a\030\011\006A\030Bf\000H\030\006U\002\002\0020\022=\0341\010\014\001`0\r*\004\003D`u#=do7\035\rs\010``\026\003\000jP (&\017!\030-fZ\025\\g4[LR\002%\\c\027\014%\023\001\034\014\003*A\0011\031\001\006e9\035\r\0263%Fa:\032-vq\001\002u:\032\rw\023%hy\020\021\r\0273%fi7[F\021\031@\"\006\001U @\030L\024b0[M6+9Ni7\031&\022\001@<\006\004JPdD\033n\r\000B \0210EFa \030L\026s-Jn3Z-f)9Fo6L\020 \010(\005\002\000@ \r<\013PM \011:\177B\023\027bPuH,< .VmL\036u<\010B3^\034)U\0251EB\003yu\036_/ \023&#\nC{z<G\033f:ww*nP\030G\013\014\030(Ndo\033*I=%st}:\007^bvdReLm\036IMov95t\017Vhe\011D$B\011\025\017\0262\0275b\027,?53\r\023\024dL?p\016brlMIt+'\031q\031\023yj\016:\0353)M`/=,_\005#8V`C>O^#_3B\005\011zC+qW2\025\023\\*55.Ayu^\032xN\003\027-G6{ZO#$o\011UAF\007\017>J\037\")o\03038\016S\\CoD@D\\#\003m T\004\032\007s\013i+KGC\006W>\000e\013 `\rCE\031>rTJ\031Iq6\n\007pO(=\006\034-MH`.2V2W(yMa|%1m\021O \025cy{77869\025\001\000`\020\000\004a\002\000RF\010\rlb\013\030\002 `\032T\010\006\011@H$)D\"0\007A@5(\020\016\023\004\020N'+Mfe6\034f\021\031@\"\006\001U @PL\024B2[\n6K\035\\ '\025F\023A@l\006\001U @XL^B2[\n6K\035\\ 'XM&+\rh (\035,&c%fh4[Lr\002\rJr:\032,fK\rBt2H\010\027+QPo9\032.GIDJ0\021A@5(\020\006\023\016\020LVbMRg7\010\011v\023)Jc:\010\n\007+\011Xi9Z\r\026s\034@C L$3\001\004\014\011\025!I\0107\\\032\001\004@\"a#]Jb6X.7#\025d@1\031-G\033%Nn\027\030LS\004\006\022\002@` \014!8?6_{P$\006ws7\027\020:Yp\026bZh\011OF\022T\007\033~2l\035r/_~t&?h=f\021OH6ApIqm_\013evlY|JE~m\027E@\002}0--BH<?\\g2+#XD\016vgOY,\020\002`\021\000('p\014IGl*H\007\005_:)X\020{\010h5i`\022`D\025`,hYX\030~3?9\021)oPO$t5l!IPd>\013U\"D\004\003\000@\000\023\004\010\002B\030 63\010,`\011\003\000jP \030&\002!\021&\021\011@\036\006\001U @8L\020B9\035.7\033\025Xs\030Df\001\010\030\006U\002\002B0R\011Jl)Z,vq\001\034V\030M\006\003\020\030\006U\002\002b2Z\011Jl)Z,vq\001&e1].&)\001&e9\035LW\021\001\006e9\035\r\0263%Fa:\031$\004\013Uhh7\\M\027#db!\030\007``\032T\010\003\011F\010&+1&i3[D\005\033\025Fu9\031$\005\033\025dv2\\D\004\032\004b#\030\010 `I*\014HC=aP\010$\002\026\n\035lV\0235Bs:\031.$\003\011Jl9Z,vq9De\030 1\020\024\006\002\000k\000\"'DKp\004!\037y\0349\n\007|>\021n\003\001-\022\013\037\rH\011\001#4!9`j?\026\023\"\026 0\n?}:MF\022,dvm\026f=\034]kZ@\033mfto\0141\n8\014e8\002SY\037fD@E_i( :\032\026XuY@C\020$\014p\n\011<E\026\011\020\013~b\0241;-'BF\0311E9G\032X\026\000o \003\037xb\002##(2Cyw\022_Vn{|&RN` \030\004\000\001\030 @\033IB\003(\030Bf\000H\030\006U\002\001B0\022\r\0021\005L\001\0200\r*\004\004\004`$z8b\020\030\003@`\032T\010\007\011AjF{I^n:\033f\021A@,\006\001U @PL\036C2\\ND+9Ni7\031$\004K9F.\030J&\0028\030\006U\002\002b2\002\rJr:\032,fK\rBt4[mb\002\005jt4\033n&KQr \"\032.fKMRo7\014\"3\000D\014\003*A\0001\030)Fe9\035\014Vs\035Rn2L$\003\000x\014\011\025!I\0107\\\032\001\004@\"a\013\rB@1Y.'#\025\\g4[LRs\r^m\030 @\020P\n\004\001\000@\035Z&]\"\024PZ<Vo[_]\037]\006g*b7^\0320Lo\011Ig,Oi\r\001S\005O0.Zq~\003N$|G\010#\0317\025]\031?\035f%g$1a#zL\013D\021Zm\037\021$AxHHhhjQ:\030\021\007\020\035Fj[.6?\014gPu!i\010us\013\026%i]l#Fsd2Zc@ hw\021kD$pR\000-=3Hlj)\027\036L \032aL=\017)`\003\016HsNn\037S3.\000Sbx\001\010I2r1\004p\177C73(**mk3\0321\022*\001-G\021!,\\0FH\\P\013\002\n3\"?!_u\177s\037\014T O\030z\005\002\007\035`~('e\035o0rN`)\006b80bF\013\001Q\006*M!]\003\024UnP\r:d-_uymE=0R\005t\005u#1u8}YYB{q\010l5:u\021Yi%,{\023E\004sG\023s</\"\036\002\001@ \000\011B\003{\030\033&\020Y@\022\006\001U @0L\004D\"L#C\000h\014\003*A\001!\030M\010e:]\0166\033!J *\031-F+-^m\020\020(s\010t`\033\003\000jP ,&\024*\031-F*MJc\020\025\016'+Mh !Y-g#\025d1\020L\003p0\r*\004\001Dc\004#\025jt9Xm\006)\001(e6\031-6{4@R7[nB\002\r\0020@b (\014\004\001]\002K\037\020-Nr\022kZ.\037?),0\004\025bD\033nv\032N\033%u;\007/bzQ\r>qY\003\026{\031\031n\016\006e9R\005\000IBCPp|#FYSu\023A0G+\032vh\014\030J_5\\w2S>hF\001t\004El*Qy?_t$+t+}|\005.ik-\000=\005L\011W\0314!IJV\022\020\\\001\022g\021%_C\003P\000\r/\017qW=\024 \031\017\010\035\007\0309D@@0\010\000\0020@tF\0041D\0260\004A@5(\020\014\023\001\025*3\011\020`\"\003\000jP (&\033\"\032,vKQBl\020\024m\026;9Bt:\\LR\002Qdu9]\004\004\033<\\1\010L\001p0\r*\004\005Da\004\"M(C H\010S\011B\003\007\001 0\020\005\001Y\001TsfAq\023;~C\n\031Mt\014_y/5\010-\027!h`3\004s\0000rRQ\011\032-s\nVrI9\000\001\007vNJb\"\rdIL?3\003$#s\026lT';!NedJ:\0207`nk\007\177{C=|.l\034oM\017@Li^\037\034GPx>\000\0316\016%\010'8Z*TSy\022MvhT;p\011\030\000e\000U\016p\004\00412\003j\"hMhv\033-/+!5b\002\000@f\010\020\006t0@j&\020Y@\022\006\001U @0L\004u9L!S\000,\014\003*A\001\001\030\021*t0Z\006\0219@*\006\001U @8L\034S0[\016B\0021Bk2H\0106KQr1\022\014\004 0\r*\004\005\004c4#%Ni:\030-B\002MRg7\030.G+IJ *\034NW\033P@C7KF\021\011@\036\006\001U @XL\020D)U\0104\011\00101\030EF\001 \030\006U\002\000b0j\021&T\020\024Mv{Q\006A\020\026\006\023\011\004`\037\003\002%(2\"\rw\006@!\020\010X$c0P\014FK\035fi3]\016'+Mh.1[mS\004\010\002\n\001 @\020\010\003%F\023-\\z)w\003D45*\006zO\no$Da\033E<XHFE\r*\030]>Z|teg)?0(1422\177q\033TUa|PF\0363gI\017n[o,K4\np31Iw$DFunB\0034n\002GZ25\\+\010\031N}\026 wp,l\\l Y\024\017#\005\026\030\022Cr\025+ lja\002\017\031Ah\035]\036)JA\"hh\000e[\014\002}#l\024V\004&5\006J8#K\010,WBN\0265ET\013?-\004sr\023\004&)\017[\026\011\024VI\033\036k\\\011l,\037S\022zI\010}Q\033\036\005.\"KH^+yd?Bg2F\020CL<Hh5W8\003@\025v<pH\003Iu\0167\030\022|9\0212\020\032 k>\r\026Hi[\025fQca3FiKg'\033\037]\024e\001\0020+\010\014p\021l~Gg9\013Y2\002k4M*HCg\011XD IY8n^ \030\004\000\001\030 :#\002\030b\013\030\002 `\032T\010\006\011@JU\031DH0\021\001@5(\020\024\023\rQ\r\026;%ha6\010\n6K\035\\a:\035.&)\001(r:\\nB\002\r^.\030D&\000x\030\006U\002\002b0B\021&T!P$\004)Ha\001C@P\030\010\002\177\023GEr.yL&\030uD\017tpZ\177\177\003#e(-q=y\022)DHEX\0077`pkp\032o\"oW\037H.S\030G81`joY [a\034\"vNu \003ag\007\026hA(DFB~sz;BRG\n\017yms\027a(8}ir32\031<c-=}r$O\177$\nO^B4\007LclJ,0\\b\023\035m)]^#\011vaCdBVh\031\035sd+8\0066)\035\001\000 3\004\010\003:\030 5\023\010,`\011\003\000jP \030&\002:\\f\020i@\026\006\001U @@L\010U:\030-\003\010\\`\025\003\000jP \034&\016)X-G!\001\030a5Y$\004\033%hy\030I\006\002\020\030\006U\002\002B1Z\021Rg4]\014\026a\001&i3[L\027#Ude\020\025\016'+Mh ![ec\010D`\017\003\000jP ,&\010\"\024jD\032\004@X\031\014\"c\000P\014\003*A\0001\0305\010S*\010\n&{=hC H\013\003\021DB0\017AA\022T\031\021\006{C \020H\004,\0221X(\006#%Ns4YnG\023Uft\027\030mviB\004\001\005\000P \010\004\001\\:|\021L\003V-\032`\030Cr7_\011aM:\\\0053M7\031f@(J@\"mUSvC `s\022%\036\0248\016\013jw=\024\026G\007~5+c1y&t\r\036BL>d`^k8mk*3\025*IOi\024\000r-g\026`\005M\003b_K-2r+<_#OrThw\003cq\004\014_|N~By6v\005cs\021/\\\002.\000D\017{%N\004\023{\021.$JFI\027Jb4w\034^p\001%=\031BuW(\n\013'2\024\005\\(d20`\011[<NOz.Lk+\033(-\033T kPTB\r3\\[j\034*\026{\007\017kn\024\026\025\031PP)9\031s\r\036)\005m'hc\020]-ey:lchK~Cmf\035w>?\027\001FM\026\0342A\024&hy\007d\nB^lW\010FBvUVnAnO\033CYJHm\002%\026#\014E9}Qnh,2\014DeB;0\020\014\002\000\000L\020 \np`L\030Bf\000H\030\006U\002\001B0\023\rB1\011\014\002\0000\r*\004\005\004a\024)5\006e9\035\r\0263db\022\030\004\000`\032T\010\013\011B)\024!\001\006e7\035\014W\021D*0\011A@5(\020\006\023\006\021%T\033\025dt4YO\022\002\r\0020A\000! \024\010\002\001\000.S:3F\000U:\022%\025+X7G\033%&\002aH\022Qw\014\024F[\"\016Gl\n\001!;}_(M\010\026jX\007%.P\021(c(\010\005|m8\004\007\020(f\rI\\\027\000$A\023y4\016\0270hE\\9.V\017,1\rMi]Ef\"7#X\0224!e\034egJOf\"\003>lUc!)HEnl\r9~\031\025iE\022Lqa\n[ \005*&\016$ey\002dEb3em\036[z\034\0260ta>56Z'\033\177!37\002mR\001K&\036F_dB~Mi@\035\\|3~O\034~o'G@\034\r$_j3pR6&T*Y\033_\007\"\033nG\006\nx\007M\033\023\001LKg=0L-\0212U\006\020X>:\026\035\023e?wCUT@MQ\023e1b=K=\032#AAB\014\017M\013T\177d)\\kXNc\\@'B2y<\025G\rjh\025h4\rW[*\032\013nB,\004\003\000@\000\023\004\010\002\\\030\023\006\020Y@\022\006\001U @0L\004c0L\"#\000@\014\003*A\001!\030%\n-!Y.'#%Ly\030DF\001\000\030\006U\002\002b0J%\010 !Y-g#\025d1\nL\00200\r*\004\001DaD)5\006e9\035\r\0263d@R L\020 \010(\005\002\000@ \reBn%}{AKVbFr\"\003e*\037\r\020\004h}\006\007 \030\020\016/Mxs5^\005\032\022RuFZ&2\000\rE~/\006|.\027t{$\006PQW}ds\001~01W\006r}4OVl\n*\0002\001^U)J@\0332^>+Ts\016n\031[4 r=CEPg\014]sa\032dv9#8O\024R`K=\0249\003KL\022\036\034\0160m\0318i\025\020&h:r!0;oK \003vRb\013a/8\021\035\004\027wc\nc\014\014 nvV\030\016\007C-?F\021\007?OWxVso!\002A,yO\025\031}pr7W!%\034\034~UYu/\0179^+\034&;M3'&\024\023ra\017\033:UD;3yVJGi7G[*?D\035o0\002\n<XA!3&E8bp#\"*uu\030T`8WF#E@eC1[\030%-0`5\014-gj>c\010Q?BDaj\031{\001\000`\020\000\004a\002\000Pf\010\rPb\024\030\004@`\032T\010\n\011BhVsQdu9]\005fs\025h1 \014\007`0\r*\004\005E\006w;]n.2[NG\023Uft\027\033LW!=\016C!P+t\032A& 4[L6{I`.\020\030O\022\003IJf\027\010\005\006c%Zi:\034d\006c%Bb\027\n&\022)@F\006\001U @XL8(1J$\003\021@`0\020\021-g#Ijs:\013Mf+P@L4[-\027#\025H1\031L\006\0200\r*\004\001De$+9hr:\\nBs9Jt\020\020mFK\025\\t\020\020lW\023QRf4Xl\027#%^n\020\020.W#!^r4]\017\023\004\006\022\002@` \011\033Ri6r1)=5\005P\17715=O:E/39\022S\017.B\023IVXyTiU\"jB5\025\\K!ro\\:b\035\\\036\\\\\022\024\"?\nPK\004WJ%9\177\016\001blr{\\2\025\0224D$\013`\014__j)i[_f\007<K\025\011<NIWtU\002A\\XKkU$\010Ug?cpz6fYfVm\022R%,o,o/dOdJYzc|J\000^y\r\017R\\\024\004\003\000@\000\023\004\010\002I\030 7#\010P`\022\003\000jP (&\013\"[NG\023Uft\027\033LW!D~0\036A@5(\020\026\024\033\035nw99Jn:\034NW\033P\\n2]\005u\032M\030_!T\n2\003%\\c7\\N\002q\001Dy\020\034LV18@(6\032-VKQf 6\032,\026\0218R1\022L\00400\r*\004\005DcBC\014R \031\014\006\003\001\001\nn:\034NW\033P\\n2]\004\004c%Zi:\031,C\011h`8\003\000jP \014&1\"[NG\023Uft\027\033LW!\001&e1].&)\001&e9\035LW\021\001\006e9\035\r\0263%Fa:\032-vq\001\002u:\032\rw\023%hy\030 1\020\024\006\002\000cp+tsGcNx\030\020`~I0\177iLrrh^Du\030-2f!\030^haQ\025:CWL\0003M\nys\027\016\"M\\|m\036t\020\016\033U5\"*\032\002l^\177U\0173U.WF$\rDV\014}\013%Pa,HE-\032M\011d)N=+\0360v .\023rl|\034\001{N\033}\037\032\\@h\030\005Yjg\011Bs~B\\mH.@\006ms\030)Z7\035Cty^\031\002\011b \030\004\000\001\030 @\034)B\0034\030E\006\001\020\030\006U\002\002B0Z\025\\t9\035.7!9\\e:\014(\003\001x\014\003*A\0011!]nw;KLVsQdu9]\005fs\025h/!T\n5yH`4\034\010\r\026s\r^r8\013D\006\023d@r2YEb\001!Xi6Z.G\031\001Xi0XEbIDJ0\021A@5(\020\026\023\016\n\0142I\000b9\034N$\004+9hr:\\nBs9Jt\020\023\r\026k%he2\014&3\001D\014\003*A\0001\031)\nn:\034NW\033P\\n2]\004\004\033\025dt4YM\026\033\005hi7[D\004\013Uhh7\\M\027#d@(\031\014\006CA$a\002\000B@(\020\004\002\000VS):HJ\r2u(d\0008T,d\025\ni=\r|\026J&c]X\003ZJg[^\010\014\003M\005H40\0335\031/:^\\\035S\003,N\026\032N_\0023P8>[[GY~)\020(\036X`5\030kvqL5R`?\010\010\031\\Ui(\002 \001~tJ(3PA&g\010\005}0w<u+Mr0om;)I+BE\020i*n.2(\033g\\EiL\014q\177\027[B'\002vDR#\037n\002Q=Dhlr~\032?<8F,\013A7R,dd\016f3n)bW^\032f*M:<k'\026,y$\007y\027i\n\013\026Q\021N\002LJXWvdd&\003\\I@\035k[?ww\020BUA\005\030\n?\027Z\"HiC8fSxz\014]=\036B[o<\001\016\nHJA8\002 &Io\001dK\"#?|\021z9lU\005A\007\023;vy\033\037C\014\010,&2\raVjp\000~\010\010\006\001\000\000&\010\020\005,0@r&\020Y@\022\006\001U @0L\004U)L\"C\000H\014\003*A\001!\030-\nn:\034NW\033P\\n2]\006\024AA\014\006\001U @XP~w;]ef+9hr:\\nBs9Jt\027PmFK\025\\t/Ph\025z%\\f7Kh5\002L@i7\030mw\023@\\ 1\036$\007\023\025L.\020\033\r\026k%hs\020\033\r\026\013\010\\1\022L\00400\r*\004\005DcBC\014R \030N'\023I\001\nn:\034NW\033P\\n2]\004\004c%Zi:\031,C\011L`1\003\000jP \014&*\"[NG\023Uft\027\033LW!\001\006l4Y-g!\001\006e9\035\r\0263%Fa:\032-vq\001\002u:\032\rw\023%hy\030 0p\024\006\002\000d\016S\025qD/_V\011my\003oH\031\177Q43&\0137AT\023~\006G*\011}O]/\034~\006\024QJ+xu8\r\016dO+0!Zk4\177\033^\010{Y^0\022K3Xa\033w_R\006\014\n\032If<U|>v\0369C=\003Y.Go\016V\022;\035a7*SPY~\037L-j|F*n\0035\000tj,XV#F\000E\026h\034\020Iol9\004oC_F9@*'\031\036^{b` \010\014a\002\000T\006\010\016\014b\013\030\002 `\032T\010\006\011@JU\031D(0\011\001@5(\020\024\023\005Q-g#Ijs:\013Mf+Pb;\030\016 `\032T\010\013\011LNw;\\\\e7\035\016'+Mh.7\031.Bz\r S\020\032-f\033=dp\027\010\014'I\001de3\013D\002C1Rm4]\0162\0031Ra1\013E\023\011\024`#\003\000jP ,&\034\024\030e\022\001Dr9\034H\010VsQdu9]\005fs\025h &\032-VKQJd\030NF\003@\030\006U\002\000b3\n\025\\t9\035.7!9\\e:\010\n6+\rjr2H\n6+Ile9\010\0106+Ihi3\032,6\013QRo7\010\010\027+QPo9\032.GIB\003\007\001 0\020\0064Q\003\032\025\0038OL\037/\033d&\037}<b`dj\035\013\020AQmOyr37D\024d]Q~P \\~##S8R8f\002&\006\025\016 l [Y\017fB)}rfqi`\003\023z\035L{F\r%\r\025d\025_\0226SM2As\001=\026Z3?_\004Jl\n2\"3\023#dL\033\007 \004+j4MY?\016o\014!\177~n\011\025FrA^A\016-8\rD,\0310n*K7\031\006\002\000@f\010\016t`O\030Bf\000H\030\006U\002\001B0\022U&1\010\014\001`0\r*\004\005\004`t+Eji3\030/\003\0118`,\003\000jP ,&%\"\\.VK\031Bx\020\024\016&+5Ru6H\0106+Ihi3\032,6\013QJ ].FC=di:\036&\010\014$\005\001@@\031j\010\032\034\006f\002\001<\014\032Q^\0205!PvD\033DOzM-MO\0042#P\rxT\"H\011^N\005Ao\033\027fR<fn^kW<~\031\0260?X[<U3SqJ!PJ~=4$+x\022\020zcv4JpF\006\034zB8]`\027MHG.e~do!\">ky\007IO3fF\023\024\030}l\0225@^),\014pCa=L#&+\022x.Wz-Ej5\177_\004\014\005X\010\006\001\000\000&\010\016p`N\030Bf\000H\030\006U\002\001B0\022U&1\010\014\001`0\r*\004\005\004`t+Eji3\030/\003\0114`+\003\000jP ,&$\"\\.VK\031Bx\020\024lV\033Ude\020\020lW\023QRf4Xl\027#\024@A:]\r\006{IRt<L\020\030H\n\003\001\0000+[\naN\0101;T\011Q4>\0106d\"FD`\024\036\1776@FxN\010b\020pz\027f:>\005p.\000\037\0028ilq\"RP#\022Yq5Tkp-O\026g@/h \024;}]\000B=N\010\000(O~>~\000fu\007:-J|\021|\001a\031\nUr17D\037\0275-x&A\0149L&V&\nbD<;WJzns\r\n{bv+u\006KFP\007NQ\016=|)}p1w\020\020\014\002\000\000L\020\036AA41\005L\001\0200\r*\004\003\004`%*Lb\034\030\006@`\032T\010\n\011DhW\013URf0^\004\005\033\025Fu9\031$\004K9F.\030K&\002X\030\006U\002\000b2\"\025bu4YL\027A\001&e1].&)\001\016l7XL\026a\001JB:\\m\026s\025fs\020\020h\022iDa\001D@P\030\010\002ug\013d\000&-DhU\036\0228%\016W?'hMq}\017\036\002s TL\011\\vB\027\023\036\025\\=GP&J\014V]qN\032:\027v~)Si4sL(kNOn\024s\rW\034|\035~\000lfj>M1/\001w|f5&\035\nbG\001\003zN\"Dt\022\036\033\021%RR\010pmp8Y\006=dEej\013\034\0064g\035\037hrn\\\024f!\016\017Ccs\001\\vN\031p\\.#\006a\001\000`\020\000\004a\001pL\n3\010,`\011\003\000jP \030&\002*Tf\021a@4\006\001U @PL&E8]-\0263\005p )Y,7+IJ $[L2qDL0\022\001@5(\020\006\023\016Q.\027+%La<\010\n6+\rjr2H\014T\023Ufi7\031.7\031\001\006A\026L&\010\014$\005\001@@\031bxfx\027[]{i\035%>Z\006Eis h\031\030z\010[\025NS\010h#<\026C.\026\n\003\0201Ut-\024BQ\"P=12`l27xJ\006\023\023s}(g\025\"&gi\035AJPpQ\007&\022\034\r\rHh\001\\ZP6(.phC\025|TIE*k\n\017\034\023hoS7p.\032uCWg/EpX\0350\014E$',_\"\035sS:V_\025\016\014 \025@${\177#t`\030\010\006\001\000\000&\010\016p`N\030Bf\000H\030\006U\002\001B0\022U&1\013L\002P0\r*\004\005\004ad+Eji3\030/\002\002MJc:\\LS\011\030`$\003\000jP ,&\035\"\\.VK\031Bx\020\024lV\033Ude\020\031('+MRn2\\n2\002\r\002-\031\014\020\030H\n\003\001\0009\007\023LL<R\003\006e\0037be#\024q=XuH#=\177:|{#S\005\017\177A<}Lt\r?\0112\007pwK-Q\022,B\035vEf\011E5\026\022d`\022\r\017\024\010k\024\016LEFXM\013\\\0246 8\014U$\0066M\026/q\016\0239|\011s[P$CH\0344\036\027\030+\n\000H\027eRwxZ_(nqf\007\031\0039js\027))uL+(I\024''\017<~\001UVoH7P\020\014\002\000\000L\020 \025da\001T\014!3\000$\014\003*A\000a\030\011\006A\030Bf\000H\030\006U\002\002\0020\022=\0341\010\014\001`0\r*\004\003D`u#=do7\035\rs\010``\026\003\000jP (&\017#\033n'\"\025\\g4[LR\002%\\c\027\014%\023\001\034\014\003*A\0011\031\001\006e9\035\r\0263%Fa:\032-vq\001\002u:\032\rw\023%hy\020\021\r\0273%fi7[F\021\031@\"\006\001U @\030L\024f7\\NF+9Ni7\031&\022\001@<\006\004JPdD\033n\r\000B \0210EFa \031Mw\023QJn3Z-f)9Fo6L\020 \020(\005\002\001\000 \014U{\014nN\000xqk?8F\rhi\001aoRb@\022\014Pu\006l{]o`\033,\032BP\025\034yzW&W\024\022Rn>\021;Q\007&#-\035]VGY\024W-{\034y\020\016iN-8\021FY\022U#\0075Q\"M\034iI:\027\027s~ #k\016R\027/o\0215Ug.g@yq\021oitZi0r\0230oj\n8g5\032Wz;\021Q\007\\l.Rr@4\034|.)\014\027D=\024t\030\035AX%\033\016,\000\026$-\006\002\017\006hAW8\027hHy\004Z2 H\020\027;q\004<pN~|v\024\\\011\021sav\002g\03531O\026La],\007KW1\022b\016\017\007\033#D&FS;3l8\030\014;\022\006 \006R\0368mwy\004yva3,oAdG\007!W\\p\006=&\016\010YaH/G\011+K\n`WU\\WB\025[9869z0\007\003dQ\021\014,\001{\004=q\n\031\003lky\027\0307Of\013h\005\023J6\013^\000E\014T/\"({@\024pY\033\020>\035<+<n[\006d(~WC\027Z`\020\020)(\\\010\020\003z2L\032G_q\035G.G\031(%/V6&\003y\003z>\024EL\016E@\016=\001SK%\025dFP{(Z|(@Eh\027\0335L\010n&\031\023h&\022\017i\034C2V`\024]P~_=*09SUr\005\034(NtRY8zI\031)Np*`CF$z\020S[pqCA\036\016,K7\010\020\001PgEz\033\\J3\036*:\010\rvm-\022\037PoVjUb97\016Y\027\025:\035\017ydu\031n \037cU\033HQh\010\032 A\r\011'\011`c\034Xw?@63\031\036Gl9\024\0307}\\\0273\"dRq\031E\002\037yy65\022=5MZOm;\021/lLt\027wB\003DwP\007#\003\nAo\007K\035S>aiM\010\010\006\001\000\000&\010\020\004\0060:L!3\000$\014\003*A\000a\030\011*S\030F\006\0010\030\006U\002\002B0z\035(E\020\020mw\023A^r0]\r\026{8b'\030\011 `\032T\010\013\011GHu\"\024@C<XLW\022Qdu9]\004\005\033=Xu:\032-vsLX $[L2qDF0\020A@5(\020\006\023\r\021jD)\001\006y1\031.%#Ijs:\010\010vc=Da6\010\n&{=h0@b (\014\004\001\025\007h\026o\002B9h=1q\014nt.\016\027,\022M\000lz\016{%\030\010TS\016\006d$\022|EaH\032=\037MCbOB7\024\034l\007}J.S\003gj?K51\024i+qVl!O\000s;6).=d1e)#G\025i8\002sY\010.?fR,k\016AZd5\005*\022\000'\0364p~\001BUaUD\035\013xia5)\033$M\0058\022\020\003xH+G<m\003p)<vbL@@0\010\000\0020@wf\005\011D\0260\004A@5(\020\014\023\001\022J\003\010|`\035\003\000jP (&\026!^,&+I(r:\\nB\002)Bp0[EB\002%\\c\027\014$\023\000|\014\003*A\0001\030a\006y1\031.%#Ijs:\010\011$\nA\002N\020\024Mv{P@C L\020\030H\n\003\001\000-u_f)\016\020;\"?V=3Hs\003\037\020\024Xw-5>\003Hz\1772LT:j\030Ok\026_gd,6\026aPk\r{n,E9 \026!-7NOvqp.C\021B$c|\"\037n$wU}yM\030C.\026~c5\023SH6<\027H\001,h]+-Ay0v\037dK\021D\035@\010Bu .:68fu\"C1$+H_*+U<@>\r\007b:NA{as!\004g.]p\020\014\002\000\000L\020\036AA41\005L\001\0200\r*\004\003\004`$R@b\037\030\007 `\032T\010\n\011EH7K\011Jr*\034NW\033P@J0\\\014\026q0@I7\030ec\011(`(\003\000jP \014&!!^,&+I(r:\\nB\002)\002P SD\005\033\025Fu9\031$\005\033\025dv2\\D\004\032\004a\001D@P\030\010\002X&Qh7\006{+\000,\011>;3\010\026%g~~ZH\rRqU\02552\017WA\006e~\004B\\W3790wF6\031]\037/\000\017\017y\021\\6\0309y3sd#b\032\011Q\037gOK\006&JCa?\004x(\007\020[\n|\022w\007b(l\031XZ\177\032_C\016\037\007L\\slt/j\"uE=*TkQNo;/H[KF\030]Ps\022\035_\020\0228\0344\001\"\013i\027\031\002mI\001\000`\020\000\004a\002\000`\006\007\001D\0260\004A@5(\020\014\023\001\025*3\010``\026\003\000jP (&\017#U\010R\002\r^r8\033n&\013QRo7\014$s\001\024\014\003*A\0011\030y\016T\"H\0107K\011Jr*\034NW\033P@S7[\016W#%^n9K\004\004K9F.\030GF\001`\030\006U\002\000b1*\035(E\020\020o\026\023\025dT9\035.7!\001$o7]\004\003)B\004\001\005\000P \010\004\001<\011\033GxSqu\027\000{\003kYe4\002z\036\010J\022 7\016=R*'UavGYkrI[>w\026}\nm&*rp\034J\034wk|$\024\"@;J\177d0\013;8'rsH\0235#CW\025\016.*_@\031fZS:q\027,r \032\n1\rA{~\\Ei$w\017Na\001\006.{a@]vk0pz\025J\036\036&A)Uy:\035L{\034\177\026G\014z\013v5YZR,\177b\037\014\013|\026T\025\032G(\rPFyl*\010%\002i\016C(x3e\\nwx~\007W\\\026(\035-K\003m\032%7!<1f\006\014<$\033$-Bsr9\025-[~4\016?=sN{\006|9\010gW*>\014e}\003\037s\016yQ\026\036q\003\031[mdpg\001E\034\005@\034m\013U95$-\010\011T\023\033\025u+_\nL\017nG\0261{8\037MK(\037y|#-z\016i^,~\031?D\020\020\014\002\000\000L\020\035\031A\n1\005L\001\0200\r*\004\003\004`%*Lb\030\030\005@`\032T\010\n\011Chu\"\024@C7\\N\006{IBt4[mc\010p`\032\003\000jP \014&\023#U\010R\002\rrb2\\JG\023Uft\020\024Mv{Pa\001D@P\030\010\002qf'n[9Cqb|WQ\026}\030=\rY292<\n\n\035G]\0221S)5ugEo<P)E3FXKa gn?'\037hA\0264\021,\036\033J#8?%|\014e&Sz+\177j\025J(zZ\022\032\005X4\023\032\0238T\014hWo?\013\005O`)ze+ HYBw\005\010D]\"=\013*co<Y6\177sTT#H,a\023\000\036HIi++4\r\0001N8J\022xp\003\001\000`\020\000\004a\002\000[f\005yD\0260\004A@5(\020\014\023\001\020HS\010d`\027\003\000jP (&\020#[\rv\023\005XS4Ymb\0039l-9X&\021!@$\006\001U @XL\026P0\\NFs\025ds\020\020h\023\010|`\035\003\000jP \014&\026#[\rv\023\005XS4Ymb\002ABr:\033LW\023L@C L\020 \010(\005\002\000@ \r\0213p2V\022B'Q_\020)Hi5hc8<\016`\r\0068G\024fq\013\007\017\010##\006\030\032\024\005a1zc\024A\023v\031T|\001xc\004&\\3%w\030\001+ \0004!Yg&\014e\000\004 NF\017av7\013UG<\031.q\rs\0300\016(\001R;'Zx\024\033L\007R\026|{\177:_[\020Pk\013\037Y\177\032\neL\020zDt`\036@\0019g%\002gTklM\"[X@h^i\r]IEgszl\004K\005mQ\002\000F$\000VnxrvSFEW=1\025Sr\033$Va,C\026\000O\014c<Q(\004J\014$+\0261W#\"E\003!,scjA\003\0067H\ro7w\035S\014xf,d?[\032/\033#rGU%,7\006\013oAw#\022rnM@\014!\026\ny\013;f)L\nBP\023\025#\013Z}}_`/\017KD8F/\013\"Y)4`YG\023\010\035\013\nV=\001\000`\020\000\004a\002\000_&\006iD\0260\004A@5(\020\014\023\001\020HS\010d`\027\003\000jP (&\020#[\rv\023\005XS4Ymb\0039l-9X&\021Y@2\006\001U @XL$P9\032-V\013Ir ![\014\027\033L@1\020\020h\023\011\030`$\003\000jP \014&\035#[\rv\023\005XS4Ymb\002Adi6X.'I\001\006l0\\n2\001D@C L\020 \010(\005\002\000@ \013i\000jGhJ\032`E\014$9\021Qa[k@BR\007\025f\031-\030hW5{\017d\033g\006\006)\022\031[eVC\031^v\003s\025s\037W7\034MRs\\E\020A\023I8|h\030\001!&[\027\002fm\035\017yL=\0102Z\035'>\020X\017f]oOiJ&\n\021r\032:Q<\006\nY\nm!#\007W\026.M$\011-s/.YAP0\024\0268u\032MlZ=\002,k~QNwl|\030)C|rb9\\w=N<X uJ\030\034 \017F[\032)s6{\"\013$\017w]4|Bt2\033dp1y\027}\007)S;}\021\020WF$\035hH`\026\002@F\027f?y&`D\011w*\033LhK-\025VMsL\013mL%K^b+N@~\022a\026\027/!c\030Sp]\013jVY3J\1778@?W*Ao&_k\004Ol3\003H%?]SB\006;\177FV\011\\Im#h\023E9\021)\001\000`\020\000\004a\002\000_&\006iD\0260\004A@5(\020\014\023\001\020HS\010d`\027\003\000jP (&\020#[\rv\023\005XS4Ymb\0039l-9X&\021Y@2\006\001U @XL$P9\032-V\013Ir ![\014\027\033L@2\020\020h\023\011\030`$\003\000jP \014&\035#[\rv\023\005XS4Ymb\002Adi6X.'I\001\006l0\\n2\001H@C L\020 \010(\005\002\000@ \011\0243}oz\0211a:\005]|l/d\026},\r\035)0%@\004t\177\016Bn\017tT>{ 1JY$I\036\\ZA=\016N\022V%\177a45'M\nmzjg0 \"?\r2c\027L:9juXw:q&|~m;\024\0208\002\027m\034H\r\001R-=\177/O\\v7SB<v\r\"\033JT\017{x\011mv\027\177\0348Cqt\004V_0NKSc\023\0222\025@\005\177w\007!L%!VO:Z\nnFpP\022(=u\002$t\\$\034~a\020.{K#2\022$\035\003!|q\030$6\026\007\000st(>\017$l`\000k>\0367$v9\025b]\rC[>\024l\025Jg\014D\027)?D]=(\000-{B:,o0J8fq^&Tj\014p\037#R(t}pl\005Yfs[95kp~|f;\011x\031\034K\1778\024\036h\032ek\004\003\031K\002fz\023\r\000)I\037M\025\006w\001\000`\020\000\004a\002\000_&\006iD\0260\004A@5(\020\014\023\001\020HS\010d`\027\003\000jP (&\020#[\rv\023\005XS4Ymb\0039l-9X&\021Y@2\006\001U @XL$P9\032-V\013Ir ![\014\027\033L@3\020\020h\023\011\030`$\003\000jP \014&\035#[\rv\023\005XS4Ymb\002Adi6X.'I\001\006l0\\n2\001L@C L\020 \010(\005\002\000@ \011\ny,ek0\030\000$r~Gb\027\0177QD\003y,%S\036\030r\010/n\025QzoU3\001jPlejj'\014:rU\0368G\002Q\010\005\014\014I3({WqNx5-t'W\033r[H/\0256#>oaWP\032\0246tY\024uJ]p*=KD\0020lH::\nHc\025L\020So%;9\002\032\005$k/\007nHH#(8~\013#f6\001\034\177us^L[npR1Xi<xj Q%y_\014{a\0119\022\027,{\037 \037\017\022(\013>\024.\0147\034\017\0242\031}Cv \177\"\002)I'\023h={\035,o^@j\007deO$\\O\022\026`\011]\004k?\010o>1^\030\037\005~\016x-H\026+yUH7E\021*!p9\022;afD\"xPWmk\1773p~c0-\021\026;LDDP\n@(jWW=,@3]dm;\0118ZqP\023Jw\030;)@uW\001\000`\020\000\004a\002\000Yf\0059D\0260\004A@5(\020\014\023\001\020HS\010d`\027\003\000jP (&\020#[\rv\023\005XS4Ymb\0039l-9X&\021\001@\034\006\001U @XL\016R7[nB\002\r\0021\rL\003\0200\r*\004\001Db$;1^b0[\n6K\035\\ )\033mw!\001\006A\030 @\020P\n\004\001\000@\033 w\0323\rg(|4|)}{xbp2+/TH\017|%+\005f*\021\002/>\006\036GDg33cMn<6H\025{QXL:5/\024`\014Z_'\016-\0112u1b1`\007PO!#\0064+\r'~\033]$1 \025\016;j\016v\020]w~:*/\024E{`6u&S\0049<C9|H\036NUUcY\"'%1dpo\003\017\021\006JlTMbijKC2\023LM~'LW\027{\011zDGI\023b-Vn\035\ri\032\021CQFqhk\023T\035\006t\0061-+5YU<\005RZ\027'\020\n\034:~\" M\036s*$b8)h7<\017\r\026XX\026\0319;bv\035X|A\021UB*6tC\034{\033]\027\027\002\036\"\"(XbgM:c. IA\014@dWQ#*I\r3\020UWAM\037ra+\002l\014Pi <\027OS>=D\026G?Ur)'oy\034C\036\002\001@ \000\011B\004\001\\L\020\032AD\0260\004A@5(\020\014\023\001\020h\023\010,`\011\003\000jP &\002'SF\021\001@\034\006\001U @8L\016T7\\MvsQ^1\014\014\002`0\r*\004\005\004atk\005Rl\"[LvK9J $[L2qDR0\023A@5(\020\026\023\020\020lW\023QRf4Xl\027#%^n\020\020.W#!^r4]\017\022\002\021Rv4\\m\026{8b\023\030\004 `\032T\010\003\011BMV\013%Xe7\031m\026s\024b \030\007@`I*\014HC=aP\010$\002\026\010Xl\024\0035Bi6\031-f;%\\e\027\030mviB\004\001\005\000P \010\004\001)<gv\024}\027\017c\"fOji]=Q&;\023'.GT.=?{kf\020\031\014I}&7uQ>S\rn\034b]e\022&\\>-+!^:1-\013\013pMc!v)W\037w\005Oakz5\1775Z\023=}a\r(\r\0246Q,dP\034%\031)nL'H&\014\031O\033v('h&`h\006aB[\r,YcBE\000k%\013q{\rY~\025X\027\177Lc 2b#nseLTV?blJ\014*9fhPtX\020\002\006E;i\024\011=U*K4V6h5k\036EW\036/0\016\021\023G\036aQ Vo\014AE$'~%*\\M28S]g[(\013>\020;eMS\021+\027\010{\001z\0342\016H]\030sN*R\013S\027<]x8@\027\026\030$#Z12]T\002`\031.FB1^k/a8\031pmC\032\005S\032z\031:>\001V\025v6Ua(G_\016q\0076O1o\020\020\014\002\000\000L\020 \n,a\001^\014!3\000$\014\003*A\000a\030\011\010E\030D\006\000p\030\006U\002\002\0020:!Bm1\035.&9D 0\007\001@5(\020\016\023\003R\014\026k\011jr3L'#\001`\014\003*A\001!\031E(C\020\025\016'+MhC2[NF+H@f7\\D\005\033\025Fu9\032.GI\001Rn\020\021\014\027#\004@N2]\016v{IVs\020\021mV\022 b\"\030\010\000`\032T\010\013\011F*D\031\001(r:\\nD\033\025\\t2\\D\004\0331Bs9H\006\002\002\r\0021\024L\004p0$U\006$!^ph\004\022\001\013\006L6+Ihi3\032,6\013QJ@:\034NW\033QFe7\035\014W\0219He\030 1\020\024\006\002\000o_<ku\177+p\027[)`vGA\r\005_g5'\"\025bX'e\014,+\r9YLd\177)\037\024\032&\025\002&]RdFYG);\037PB\013%@Ej\016\010i\034Bh\030G@G7[5Ie0I(0N 3\023w\010eO\031:(OC~\0071\013\021r\0143\\(C+.7Co$794\0140`W\037QU4P~@\020A,\002\0176Mk:Qb\014g\034u|U\177kH~f(` \030\004\000\001\030 @\024YB\003<\030Bf\000H\030\006U\002\001B0\022\021\n1\010\014\001`0\r*\004\004\004`tC\005Zb:\\Ls\010@`\016\003\000jP \034&\007$\030-V\023Udg\030NF\003@\030\006U\002\002B3\nQ\006 *\034NW\033Q\006e7\035\014W\021\001Lo9\010\n6+\rjr4]\017\022\003%\\ \"\030.F\011\001\034e:\035mw\023-f #[,$ADD0\020\001@5(\020\026\023\014U\0102\002Qdu9]\0106+9he9\010\0106c\005fs\020\014$\004\032\004b)\030\011``I*\014HC=aP\010$\002\026\r\030lW\023QRf4Xl\027#\025\000t9\035.7#\rJn:\031.\"s\021J0@b (\014\004\0010\024zvG5N]W[\026vEw\036{cXg\011\020\"]7!Uv/q\030o{:0j{\016;G>-\000%\013U\n!z#w],($@x\n\017V\"\027!>\035\000R\177&\000\021tRRf\\C$I\0069<eTQdE\005G\026d\004\020S\003%.t\"p\013(6\033*=p\032\nwiET$FQ2sqE|h3\014Mb#7X2\0332(\034W@bDd(l\034Pn@6\017@@0\010\000\0020A\000)3\004\006x1\005L\001\0200\r*\004\003\004`$\"\024b\020\030\003@`\032T\010\010\011Ai\006\0135Du9\031f\021\001@\034\006\001U @8L\016H0[,'+IN1\035\014\007\0000\r*\004\005\004f\025\"\014@T9\035.7\"\rJn:\031.\"\003\031^r\020\024lV\033Udi:\036$\006K8@D0]\014\022\0029Jt;[n&[L@G6XI\003\011\010` \003\000jP ,&\031*\020d\005#Ijs:\020lVsQJr\020\020mF\013Mf \031\010\0104\011DR0\023AA\022T\031\021\006{C \020H\004,\0321Y.'#%Li1X.F*\001hr:\\nF\033\025\\t2\\Ef#\024a\001D@P\030\010\00348t;& \001%c\003\000C7x`\0079Zc+'\032%&\024/jbkFB}!F1=,kn*\"\"v*CU\016\\{3(lP4rw\026IX<\011E/\025V-ca!3\000r$NA5\031 \0277no_7\034\016\030Rp\005)|S/\"Z\026ZO!2=\rR\004VW\0237:B-.\026^?_\005D{p)Fl\017<kc\022OV\"lpgF9{~\025s5:q\036\r\001\000`\020\000\004a\002\000Rf\010\rpb\013\030\002 `\032T\010\006\011@HD)D 0\007\001@5(\020\020\023\003R\014\026k\011jr3L\"\003\0008\014\003*A\000q\030\035\020a6XNW\023\034b:\030\016\000`\032T\010\n\011L*D\031\001(r:\\nD\033\025\\t2\\D\0063=d )Y,7+IRt<H\r\026q\001\010a:\030$\004s\025hw7\\M7\031\001\016m1\022\006\022\021@@\006\001U @XL2T!H\nG\023Uft!Y-g#\025d ![\014\027\033L@3\020\020h\023\011$`'\003\002%(2\"\rw\006@!\020\010X4c2\\NFK\031Rc0]\014T\003Qdu9]\0146+9he9\013LF)B\003\011\001 0\020\005ZiA\032A%`l7Y \032C@q\036LPI\032j\001X\037<.s]YN\006ky\004T\027QF\033(VMlS@'0G\002\013y#/\034P\002mqX\003Z\177]\020.=Wjm\027TXO?WLt\031Q)3*b-&pGH%%\030mH?)J,q\024\n\0258i\"\r_]{\\0ctaVaTU8ztO\0345p\024>8\025VW$Q\0266w)IOi#O%\003]n\002\001@ \000\011B\004\001%L\020\033aD\0260\004A@5(\020\014\023\001\021\010S\010@`\016\003\000jP &\007$\030-V\023Udg\030D\006\000p\030\006U\002\001b0:!Bm1\035.&9Dt0\034\001@5(\020\024\023\030U\0102\002Qdu9]\0106+9he9\010\014f{H@S2XnW\023%hy\020\032-b\002\021Bt0H\011f+Qno9\032n2\002\035Zb$\014$#\001\000\014\003*A\0011\030e(C\020\025\016'+MhC2[NF+H@C6\030.7\031\000h !P&\022I@N\006\004JPdD\033n\r\000B \0210iFe9\035\r\0263%Fa:\031(\007#Ijs:\030lVsQJr\027\031\014S\004\006\022\002@` \013y=GV\033\036v nM+u2\033\034b*w\r4d\005\027\")b\007k+\030TU-%K#z\010s\034\022.sPfU\014z5\016A#TLe77\022{-;l]U`IiCbmAu\024ie\023!d\014&0T\036ERw<\rma^@7\025x\027KJF`U.NahJ\022S-?\000+w\004\022\023bRE}av\026\031Vuq2\"\027vLz3+C(tRL(|~&bT\004\003\000@\000\023\004\010\002Z\030 93\010,`\011\003\000jP \030&\002-\020&\021)@&\006\001U @@L\030W2\\nF+I\\ !X.\006)D$0\010\001@5(\020\016\023\004Pl\027\003\024@T7]mc\010h`\030\003\000jP (&\021*\032\014\027;QJ ![mg\033UXt4[Ls\011 `&\003\000jP ,&\037!Y.'#%Li1X.FK=\\ )Y.'3%Fe9H\010FKYRs4[mc\011\004`\037\003\000jP \014&\030*\032\014\027;QJ (\031.'\033=\\a6\010\010&\013MRc\020\020h\023\011 `&\003\002%(2\"\rw\006@!\020\010X2p2\\N6{9Bl\026XL\027\033%F@:\032\014\027;QJ.1[mS\004\006\022\002@` \013er&S6p\n\004|\010+f$%\006Z2j|o!>At?9nu971TLn,WP\036\032LQ}#34Br\0270\\D\007KZXE\014M\027`F{fy-\004\030Mm\r\022\001h^\023\027p\r'\005:+\001t\004\034\035\023b\021vP?\0303)\007\014GSD\004(b?T\026\007\007.{]\013|@\nD.*`Y89\000m<<9q'^\024^BHOXm6\030hod9\031\004\004\003\000@\000\023\004\010\002`\030 :\023\010,`\011\003\000jP \030&\002-\020&\021)@&\006\001U @@L\030W2\\nF+I\\ !X.\006)D$0\010\001@5(\020\016\023\004Pl\027\003\024@T7]mc\010h`\030\003\000jP (&\021*\032\014\027;QJ ![mg\033UXt4[Ls\011 `&\003\000jP ,&\037!Y.'#%Li1X.FK=\\ )Y.'3%Fe9H\010FKYRs4[mc\011\020`\"\003\000jP \014&\033*\032\014\027;QJ (\031.'\033=\\a6\010\010g\023\025Jm0Z-B\002\r\0021\025L\005\0200$U\006$!^ph\004\022\001\013\007\016\006+Ifo7\030-Bk\031de2[,\026K1\000t4\030.w#\024\\c7[&\010\014$\005\001@@\032FN_)0J\031\0137\017%\017X\006\0246nSJ#0B\027ORh6\036{\0117pR+TPt\035\020EF\031\036?\025=R}wpf\016\035C:T=mg\035\0262\006X!#9\011,>9Q~B4\036q\017P\007\n0\002G\007<=_\031$\031=-u0\013g7/2\024QW-gSp\031%%U/p0dR\177O&Dm+*v8\022\002\r)F\036cZQf\022\037kg7e-1\003KH\010\006\001\000\000&\010\020\005<0@sf\020Y@\022\006\001U @0L\004Z L\"S\000L\014\003*A\001\001\0301.e9]\014W\0238@C0\\\014S\010H`\020\003\000jP \034&\011!X.\006)\001(o;[F\021Q@0\006\001U @PL\"T4\030.w#\024@C7[N7+1hi7\031f\022A@L\006\001U @XL>C2\\NFK\031Rc0]\r\026{8@S2\\NfK\rJs\020\021\r\0273%fi7[F\022\031@B\006\001U @\030L4T4\030.w#\024@P2\\N6{9Bl\020\024\016&+5Ru6H\0104\011DT0\024\001A\022T\031\021\006{C \020H\004,\0338\031.'\033=\\a6\013.\007\023\025Zi:[(\007#!Bw:\031%f\033=Z0@b (\014\004\001I36?\000:\023\0379F\013^\n\017<&E6\001;}q\034,Q\033\020\"\026c0wm\177\004\017Q\024{K\033!&_f\001G\006f[\\g$E9\035P\031\rrHET\0336l|~$&g+\010\0117.doH5|7HcgWG1\030\"S@q\007<,Bh\020nVj+=bU2&\037x|\000p>\031Yq\001\024\021:};@\016J\030\006f\023D\"S])7rL7&d\025K5\010:@@0\010\000\0020A\000+S\004\007\0341\005L\001\0200\r*\004\003\004`%R\004b\025\030\004``\032T\010\010\011C\nv+Mhe9\033D\004\033\005`e\030DF\001\000\030\006U\002\001b0J\rBp2H\nF{]\\1\016L\00300\r*\004\005\004bE#!Bw:\031$\004\033=\\s:[\016FK9N 1Xf\022A@L\006\001U @XL>C2\\NFK\031Rc0]\r\026{8@S2\\NfK\rJs\020\021\r\0273%fi7[F\022\011@>\006\001U @\030L0T4\030.w#\024@P9\031-VKUZ )Y.'3\025d !P&\022A@L\006\004JPdD\033n\r\000B \0210e`r2[-\027+4Zs2\\Nf+I\000t4\030.w#\024\\c7[&\010\014$\005\001@@\032#1YU\013kpK9vj\002A1#g\016r$\010Uk4\035q`n*\026#{c\004ATtRz\nm 4<v/u\025\\:|\032\033\036\013}sk#\025j\002&{y0M\010BQl&z\006>Bt\rI\001BG\036R'KKJ@\011bq\034\014^>BU\027sdD76B\024S8\021\037\027K<?M(u\0069mHe\032c\021\011\002o01\raf?U\001q_\"\011\033g '#C8\010\006\001\000\000&\010\020\005&0@q\006\020Y@\022\006\001U @0L\004Z L\"S\000L\014\003*A\001\001\0301.e9]\014W\0238@C0\\\014S\010H`\020\003\000jP \034&\011!X.\006)\001(o;[F\021i@6\006\001U @PL(T4\030.w#\024@C7[N7+1hi7\031d\006\033\014b(\030\011@`\032T\010\013\011Gh6+Ihi3\032,6\013QRo7\010\n6+Ili1Y.2\002\021Rv4\\m\026{8b\031\030\005``\032T\010\003\011D\nFC\005nt2H\n6+Ile9\010\0104\011DL0\022\001A\022T\031\021\006{C \020H\004,\0279Y.'3\025d-1Y.'#M\000t4\030.w#\024\\c7[&\010\014$\005\001@@\032:\"A]H\177UM>6=;6u\003\r\007*\036E*a6PB/rQt#T;(-T@tJ!C`{W\023i\004\030>P34`n\nF .JK\000bmS3\031w\011T\014\"\016\031_u{Fd\004\\\030_uEV)[\013i\034Ao('\002\011\"\0119?O\0206p\005\004\024g.L!wX?)\005ZTOW85G\007\001dlVv\013Frh{oMG,\025UL\"\0115Pph\010\006\001\000\000&\010\020\00440@bf\020Y@\022\006\001U @0L\004Z L\"S\000L\014\003*A\001\001\0301.e9]\014W\0238@C0\\\014S\010P`\022\003\000jP \034&\013\"\035.&\023\005\\v4[\rF)D\0360\006A@5(\020\024\023\003\025\r\006\013]he\030G&\001X\030\006U\002\002b1\"QPa;]\014R\002\rJr:\032,fK\rBt4[mc\010|`\035\003\000jP \014&\026*\032\014\027;QJ *\032-V+Mha6\\\r\026s\034@C L\020\030H\n\003\001\0005E5CaBEC\024}##m#\034vl\034bp`\035~p\027u\002>NiIp\037\013\024pX\034s*\030\030\027\177Z>.tNPR Ty[#A\014<\034{\011\024\r\026[tckgY!G'A\003ir%md\037o\002GN0k\020 \017l|Q_<oRK\\vl\024qHp]=%\003`&)\017\033\001,5\013y>\0078Qy\013,8d@\013$A\003\030}W}_U\\]\n|\"\006p\020\014\002\000\000L\020 C\034`W\030Cf\000h\030\006U\002\002B02QPa;]\014S\011\004`\037\003\000jP ,&\030*\032\014\027;QJ *[M\0273\025ds0[\004\004\032\004@R7[nC\011\004`\037\003\000jP \014&\030*\032\014\027;QJ *[M\0273\025ds0[\004\004\032\004@R7[nC\004\010\020\n\001 A\000\010\003E\011\002[87}6M\011\035?w<>6:7Xx:\"\010z6a\025\005<wZ]\036U\0364\027?Ndz>S/\035K%5'\032\013\000]0[K{\ny#h@.\027WSro6d!gM{#om)p**\030q\032\034-4[,!Vb\037_(_kSm\020TY\0074S\025K\035'-T\036CTztp}p\025E&qYNI\026>K<]wm\017{EjV V&^YM4f(|Z*\030+\003\014g\034kA\013<[\014Jc\022\033\017w\037eVUR\\d\026%\003H\025(\034N\011om|hnD\020)P\010yt\032\026/uN,\032?dG\177\035sH\003NdU>vH\014L\0177n\00602em|JJ\025=\005TNxUh!\014J\011\031DVVPymDEv)\020\0031=:\017|C=S\037\024'U(hB\030n\007\002g<U3\0375)$n255K\027\"8\0070'a[\036\037V:@<\005)\013:v;{\021moS\036y\021\0337\0258\017k\031\004)gCqSwD\013kD5F4Is\021rM \021\"(\001@M\026Fc.]\013\r0t=\020$x\026*=&ey\023G\037%(<&&\030-CS /\"!Y\017\016`WAo_d*x\0025AeNf:X3\030Z)!$d2d\036\027\0267ZjVp[\030a\".,R,d \"#)*GkOvb\030i@wKK\\$\005><\004+gUQ\016\027\022C8;i\013\"zX\0344KEh\026U7\013_ WaHQ=g\006HXu\010o~\036M|&\010{Db\006YM\004xz}tfA\023q\"hNVBgH*it^\034f\033\003ri_\024Wt\001*%&T0YDan\016\002a4R\036\037T\016qs4TTr\025!)\011bCEZYT'2k\\\017_m\014~\011!\\\017pMT\030\026F\177T;x8F9J&xd9jE\037xFys\032\031B4Cl\0201W%&|D[$9LJ\022\017Jv\025ojD@B \r^PgDk}j\007?>)\031\n\0042{R\177o\020FI\034&$\0141\010QA\014L^\014\005\031\"t\"\016bQT|b\r^q\005=fP[XTLr|.>vSP\036I\037dWjH\026o\031\023owpH]\027\031&+\"\021\003s>t\030}Qr2~U\010W\016\n|BT[S}v\0035\014f|%\rNW,\003t7mg4I\033N?gE>b2\010\016aRH\020\004\024?G>$Q\014\014Q1\010c\000?\ra*lr_\023rA\031\030mx\010\022.%\004%{\011\035Z7)<\036\0013\007bgFwpw\025>\017Zg~j\011#;)\024Bzq\"g(CuK\022HM/\003\034j:\021\011]\000\027'\007\n{&m\005\022\026f*\\\022>r\034\rA?\013TQCeOs\024!>\027\007\\\035\003R\037JIril2eY#;F7wH\024\000z%$G#'ba(0@]m%s\013lpFbC\"A\013!OF\006^cj\024\016vk-\014J a:Y\002}r-b;\032q\014\035\001\npZ\034&'a*2}[r2fioY\020p\"~)XXN?$\017zdPV23oG\005\003Zq. n:r\016\024\022L02\0245\016\020i\033+M{|^$fWEz\17774|2MbZCrR\026\\+vKqZ=\024\001K\002>DV\0219hH\rrE(ek76?=W0\023rSCmV\017\n\r\177a~\r\004\nQ\016;Pi'%L\\0\\\007V\003Z\021E$\n\\\034\021\025'\177\017P\023\027\0240\010o:8\026%\016}`}8$::\014\025g\003_ f\006sco\0040y7u\003-]KE\030\033q]\004i=0`A]4Li#\030V]8d&\021\"92'<\026~}c\035}Mf&nViX\031*`KRwD&5}tPv\025\"~\000\004(\020EL'Fl\020Ty?\036C'\017\r\017\016\020j|t@4Kn\013G2DF\022?=6FQl8Yn${\036C\0357\022ST#\023p\"L|$\016\024Y\021\027eDWQo\035bg-\000|\020\010n\002\\Wrs\013bZ\034\010qS&[N\023&?]`\035=\026AD\006=D\017BO\030 \0229}5{1%\"L\022f\037\033J\\\032SI\005DvZc(|H8]_4>%_JW*Tt^[E\021\002+\025d-a\022#\025\030l\rq\\G4\0000Zm@Dsz9ZB;\030\017SoJ\035D)\n45B)d.\006t\022)0\036H)\035rpK3X[\014\014p0\027\026\004~fa$\023\000Gz''s|Aw0\177%+[\035\022Q@2*D986IbVo\034\\/x'\005\003Cps\005(I\001$.ACmCI}\026-\013+\005_\001\022X\0009}\023;\030\030~\005\\\005\020Q}.<\\\036'L)h9Z;@\002?@\027*E\027:2X\177O\r-aarTZ4k\001\020p\011\002%\036K\005\013m/]P\022\r<gpb3\007O;\027*e0c=g\036JFR_\r14\036lZ\0245{29q=%^mJ\035h}\007O\035IY\003T4Ja`R>C`o\022Du+cL\021.(\001\025\003F\r\nn\026+#y8=\010\020\007\033\007\016%M1\037)f8\026[\027.<UXd@\000^ N\021laN?8;\004`6!@y\011trD\006a\013x_gB\000cXU\000J\0022R.c=.gVc!dj%\002\036(Vjx\0037\027\010\004>3)\020\014gQ\004\025\030e\004rGeByA\023M*L%n\001\"\006\016\027,\n\00068K!}Tq1\006I\007U<X\022w:$0\\'[}x@\003\013C\002.\rC2Q7(\007Bi5Sng~M'\"\014@T2c@\0174h\034 \011\\Kn=@a|gLA\011p7q!GBfsT\004vg\026\033~T]eIdNwSA\022gv#}&}w:5\004}+=h@4\005\032RU\023x_/Hg\035\007:j^\027)[gs\\$?\011\016\016\026u\011cIF,h,959&NCj,Y?M6\000\007u6i~\020doWTPn\177!{\027q\023w4P Me%\013\177._XVO#H\003Bef\010yG\005\0315\013`\020\014t>L(w\007HVWo?q\016\177\013#^[Ut6\007,$J\\w\nGa]/\002L\011NN\005M\017}js|D\003h\1778\011\010r .\031#Y5'\035n\017\nhbevh\r\013\021W\rmX\000cFYfz\002%1QKa}J\023e#8\013Snp:\\2h\016ghX\037Uf<lkBO\011zkT\027_\025QGP\010K(Q@\034a\rq\\\0372\005!\033Zv1?SnLi\\^dR8uaQ&)*6=N\"\033C\000\035];\035\177msUC|7)w,3N&\024N>2n\017.\022Sg\027N3\r8|D\017>gB6qR\0014\r\031'&N?G~Bi!qL*e/1tD_L+\006\0168]K7<4A|m\006a\037mQ?k\010-\r[`%\024vv;v\032\014.\026o79 \0045\"\036@M\031!\007H5L\002uiJp)\032nNmQl(J;\006\013\n'b$<O\023&6z\031V\010lL)\006Fwi{\022\025FK\026=Rf_\022\032(S\030EMy\0329\\\022L&E\024P$-2v0\037[)\026*\036\013\\\002\027T#=d\016Il8\0115\r !B27y\024\030\0119xc9>E\026-q`DgW \030\004\000\001\030 @\033yB\003.\030Bf\000H\030\006U\002\001B0\022\r\0021\005L\001\0200\r*\004\004\004`$z8b\020\030\003@`\032T\010\007\011AjF{I^n:\033f\021Q@0\006\001U @PL\"T9\030,F+I\nn3Z-f)\001\022n1KF\022I@N\006\001U @XL@C2\\NFK\031Rc0]\r\026{8@A:]\r\006{IRt<H\010FKYRs4[mc\010T`\023\003\000jP \014&\014:\034L\026#\025de7\031m\026s\024b\"\030\010\000`I*\014HC=aP\010$\002\026\011Xl\024\003Qda2\031.&+9Ni7\031%f\033=Z0A\000! \024\010\002\001\0003d_J\001\0379$7v8\006gk?>:>GL?D\024\007\026-q5a\nHZe)\177-m\177F\037\023/\011;V&#e\177%*8]U\0078/=\017}xWP3.<Z\024\036<,\005\030@A\034Z<D\026\031z\016=< Aq_8M\020\036jEo\022Z#n0FYdd\027n\014*\034miD?b^(\007uV\013>Q)I;%+dN2$sj\004pM\020\n\010b\020LY`\021+M\002yd\037~1et\007#=2&!v\007Qpv\004\016w\"z]O)*\024W8\035i|t\027\004\024\036\020P$X_\006\013|f(\036<:W})Q>%I[I\033\021\026=;/\006amoxDjPw\020&Q\r\037MGXLA*\021\0047n2p\022\003\026qx\007(\007\000\006\0273G\ns\034|e\007qR\011U|$*u|[^\034\037j%&ya\007;\0002k\032\033\0024Vd\010I)<\004\003\000@\000\023\004\007x07\014!3\000$\014\003*A\000a\030\011*S\030I&\002\030\030\006U\002\002B1bU\\i:\031,B\002Mha:\031.2\002A^s:\030-B\002MJr;\032,6)D20\013A@5(\020\026\023\010\035nw99js8\034ef\033=Z/!T\n3\010t`\033\003\000jP \014&\024*Tj\005\031\001 r7Y\016V\033QRo7\010\0104\011\000b0@b (\014\004\001Fk.={\022LqJi\035aFaXP0a4\005\000\023abN\006b(,:dO3H\002\004}$]4\036[\036\010D\003-iFFjj\030_\"Mm(iZg(_Xz*\027Jh\037\037`mb\022>A=t\014\013\0111J^\177&Qa\024\013t\004\034=kt\177v;GozUT<<sI\036\0263Z1\021S?+XHT\004BE\036XQ\nB\005\177aW0\014?'2b\024*#}_P'@@0\010\000\0020@}\006\0061D\0260\004A@5(\020\014\023\001\025*3\011\024`#\003\000jP (&\034*[M\027#\025H )]\014\027#\025f (\033n7#\005X )Y.'3%Fe\030F&\0018\030\006U\002\002b1\003]nw\027\035.7\003L\\c7[%t\032A&1\nL\00200\r*\004\001DaE*M S\020\024Mv{P@C L\020\030H\n\003\001\000-u\022-1GZX$Yy!Z`\004\177EMg0\0217uc\017\023|5e\004&*~r7\014\024\"edX$xF\021=\033\177\nO\004RITEOj\0379\rSF&.}(1!\032s^\036\033%F7U&}o9\ne=JDyzx6MS+n$rle\017tyo\026q\003Xp(\017\031i(}Ro`G\001\026\026\\f_zaf_y\022\006^*\021\027P?5 \001t\021[X\022v\032\020\020\014\002\000\000L\020 \n(a\001]L$C\001\010\014\003*A\000q\030m,a6\032(6+Ih +\030-FK\021Bt4[mb\0029Jt;[n&YD.0\nA@5(\020\024\023\007\025L\026c%\006e9\035\005B\002%\\c\027\014&S\001L\014\003*A\0011\0311,a6\032(6+Ih ![\014\027\033L@1\020\024\rvc%Fy\020\025L\026c%Ha:\032-vq\001\002u:\032\rw\023%hy\030H&\001x\030\006U\002\000b1C!ht8\016Er{]nw\027\035L\026c%Fe9\035\005f\033=Z/\030H\006\001p\030\022*C\022\020o84\002\011\000EB\026K9Lo \035L\026c%Fe9\035\005f\033=Z0@b (\014\004\001X,`O(Mb-:S\013m\006z`]'*\007\000fwSU\r$/\006\031 _as'/\026+AV$vX4\024Z(\007.\000\001DD!H#q\177\010Hs<p\037k?4FDor;SQ?g%D\000u2h7)_\005EB:\032Gtg\177\016p2\006@j\001n\001k;H)Q!\0207\030\036pa~H\n0;DV\002Cc\004opA\002h\\jW$5lrP\0073Qn\003:?8@@0\010\000\0020A\000)#\004\006v1\022\014\004 0\r*\004\003Dc53\005Xi!Y.'!\001,a6\032,F\013QRo7\010\011f+Qno9\032f\0219@*\006\001U @PL\034V0[\r\024\033\025dt\026\010\011\026s\014\\1\032L\00600\r*\004\005DeE3\005Xi!Y.'!\001\006l0\\n2\001H@P7[\r\026\033d@V0[\r\026#\005hi7[D\004\013Uhh7\\M\027#db!\030\007``\032T\010\003\011F\r\007#Q`:\027Knw;\\\\v0[\r\026\033\025dt\027\030mvi<b \030\007@`I*\014HC=aP\010$\002\026\010Z-f3=\000v0[\r\026\033\025dt\027\030mviB\003\011\001 0\020\0068tqe95<Bf$Ukj{\007 ;snl}JT:eJG\007\001*]g.06\036\027\n5nLaO\034;\027T\014'Z%!\002$FX)=3>7*\"j3MTk\037+%M%KT$DeR\"48P7m8\030*Pw~8y\0325b\013s\000p$# Rlr63|gu+p6?Z\027lG\031SG4\011/pv'c4\022\177Md|\rM\007;w^mbs'n\002\001@ \000\011B\004\001%\014\020\033YDH0\021\001@5(\020\016\023\rUL\026c%\006e9\035\004\0053\005Xi2\030.FK=\\ '\031.G;=dk\030Ef\001(\030\006U\002\002B0rYBl4PlW\023PX $[L2qDj0\031A@5(\020\026\023\026\025L\026c%\006e9\035\004\004\0331Bs9H\0062\002A^l4Xo\022\002YBl4Y\014\027#%^n\020\020.W#!^r4]\017\023\011\004`\037\003\000jP \014&\0304\035\016G\001h^/;]nrsYBl4XlW\023P\\c7[%s\011\000`\036\003\002%(2\"\rw\006@!\020\010X\"i7\031Mt\003YBl4XlW\023P\\c7[&\010\014$\005\001@@\0349BF,\034t56\0204\005TWa\\NY\035/\037\036S?\03612K,-&gfT% \\\004&Ai\030Q`Su;M|{=-;_\033\034\"IL?9BI<<v\004J/ll\022\033K~\004\004 c\011\024BB0`Z;\0336\025gO;^O\004\016\032\014#\016[MP-\\UBq\016\n{US\031/\036G\002\027\016W\010*0$L\n4tJfK]|-h6\023\007gSq4\nSx\010\006\001\000\000&\010\020\005\0020@lF\022!@D\006\001U @8L6V0[\r\024\033\025dt\020\025L\026c%Ha:\032-vq\001\034e:\035mw\023,b\027\030\005 `\032T\010\n\011CJf\0131RC2\\NBa\001\022n1KF\022a@T\006\001U @XLFC6\030.7\031\000b +\030-FK\021Bt4[mb\002\005jt4\033n&KQr \026H\011t\032M 1\020L\003p0\r*\004\001Dc\006CQhp\035\013ew;]n.;\030-FK\rJr:\013Mf+P^1\020\014\003`0$U\006$!^ph\004\022\001\013\004-\026s\031^@;\030-FK\rJr:\013L6{4a\001D@P\030\010\003\017\014\027ix4\004\034v=kq\023%@QH\naB\007\026\020k\037Ruj>\026KR\025J\007\026Nle\011$Nh<xGUWq&\016.t:=\021'\007-c8\000\005o*f\0229nL0[\021/d\000l-)J\017\")$(I$VPG![4TDslL:u)v\027\037\023\177=}\004He\036x(;-&*\001\025g7#Ko\017B\033s\007\n<\016\177`)oh'\1771A\177iEY\001\000`\020\000\004a\001vL\013s\010,`\011\003\000jP \030&\002*Tf\0219@*\006\001U @PL\034V2\\M\025\033%Nn\026\010\011\026s\014\\1\033L\006P0\r*\004\005Ded\0331Bs9H\006B\002Ajb6\032,2\002Adi6X.'I\001\006e9\035\r\0263%Fa:\032-vq\001\002u:\032\rw\023%hy\030 1\020\024\006\002\000h,N_3c!.-\024\036NJBS\037F5}y\014Qahi\011\022\0074&\013Vok\034`\010\\e\000x'24=r4eNGrzu\177S\006:Xd\010Mv\000XNA\001Im#\002$tB|S\013b{|\026C\006vTyq\000tQN_O6G{\011^y\014\n3%#w}'K\003\n\036J.N{Y+\036\036\023\\p'M5\034M\033v0g7Ve\033<6f}\001(\007Gp#j \030\004\000\001\030 =S\002|b\013\030\002 `\032T\010\006\011@JU\031D.0\nA@5(\020\024\023\007\025LW\023%&i3[EB\002%\\c\027\014&s\001T\014\003*A\0011\0319\006l0\\n2\001D@P:XMFK\014@P9\032-V\013Ir !Y.'#%Li1X.FK=\\ ].FC=di:\036&\010\014$\005\001@@\034QM}[#+\030%YJ!cv3wW\030o.o\036C \001)\010;t8\022khhD\013JsT(\0232\"t\032\037f\031-`eC VB\006\020yP\0326\020P\\{{\"`rk70>a.VQ(\037jB 44c,?l\006M<<hgD\0029Q GDN\"UM\021{`\005\000m7\010y\011&v6dXkL/\003.-C^t\0339J`{\030.E\"yFUnQY{-X\010\006\001\000\000&\010\020\005 0@p&\020Y@\022\006\001U @0L\004U)L\"s\000T\014\003*A\001!\0309,e9\032*6K\035\\,\020\022-f\0318b<\030\016@`\032T\010\013\011Lh6c\005fs\020\014$\005\003UDl4Xd\005\003IRm0\\O\022\002\rJr:\032,fK\rBt4[mb\002\005jt4\033n&KQr \026H\010s\021Dt0\034\001@5(\020\026\023\030J\0142I\000b9\034N\004\0053\025di)Z,vq0@I7\030eb\0014@F7\\D\006\013Uhh7\\M\027S\025H :\\lR\003=\\l<L#s\000t\014\003*A\0011\030Y,e9\032*6K\035\\ *\034NW\033P@N2]\016v{IV0@b (\014\004\001*h.Wa16q\003j2Z }ql1e%\033\001lN\030V\001/\033\026xi^R\033\033NU0)+SoPpr\010EK\n?#wR\016yV2\037FpC$T\013\035 M=9\027.-]U\026'p\nM[\031'{<^\021)5\020`n8J0W\037H\"ztel:8>x\031\004G5\027\033+\r\033vmCm\"a7)Ox>#E7rM\033D\014#T\011 /N9\021uWg:@@0\010\000\0020A\000;3\004\007\0241\005L\001\0200\r*\004\003\004`%*Lb\027\030\005 `\032T\010\n\011CJf+IRS4Ymba\001\022n1KF\021y@:\006\001U @XL,V2\\M\025\033%Nn\020\025\016'+Mh '\031.G;=dk\030NF\003@\030\006U\002\002b3\011!F)\020\014'\023Id@V2\\M\025\033%Nn\026\010\011\026s\014\\ \026H\010f{H@a:]\r\006{IRz2Y\004\007+MJ 7[MGIE\n0!A@5(\020\006\023\036\025LW\023%&i3[D\004\0331Bs9H\006\022\002Ajb6\032,2\002Adi6X.'I\001\006e9\035\r\0263%Fa:\032-vq\001\002u:\032\rw\023%hy\020\013$\0049La\002\000B@(\020\004\002\000na\032KMSs'l<`GDs<=n\033\00216eu]\022\024,l\006\034LY\006k\000`F\n)Q\031G~\010\031T>n\rr\033jS8*N*\011}|#45l\005xao\002\022JWcP\013\001u\r\016\0378{\014\01736)H\014\016=_r\0100Voy\011DHApN\000]FV\030Hm]3/\000\020!ZFU454#0&Y+\020IJ@54\177J\n8\025LU4\014\035Jx_\011oG@`\177pOw)-\031Lm?PyI\007U:\177\017JM>I2xmO\rl}\000&\000\r.\004z\017\022|gK2T\014-N9]d]3nYB4_Qs;\032s`2?\021z+MY&{-*r\0035$1Gvt)],9\\$\\QJ#`\026g6\037\035m\032pzY\017\001\nA\011*|\014OQbV\021\014\016wm*Shc\rS\"Tm\010T<\033{\025W\037K\035Z\023h\010\006\001\000\000&\010\020\004l0@if\0219@*\006\001U @PL\034V2\\M\025\033%Nn\026\010\011\026s\014\\1\017L\003P0\r*\004\005Dbe3\025di)Z,vq\001(r:\\nB\0029Jt;[n&YDv0\034A@5(\020\026\023\031\025\014W\0235f 7YD\007+MJ 0]\004\006CQhp9NEr{]nw\027\035LW\023%fi3[Ef\033=Z/)\024\010\022\001!F)\030\014\006\022q@X\006\001U @\030LJC6\030.7\031\000b (\035,&c%F (\034M\026k\005dy\020\023h5\032@@R2\\n\006{9He9\014\020\030H\n\003\001\000.=Ushtw/sKsRKyM2=n\033+=U\026c\0262%,Q:/-KX\021\017(M\neip\023gY4Do\036B2\177u4Ql^fr2+\000'\037A\0006R[\003\003\0268-u]%(P\022\022Xbsi\031!-MjB!\004b\037P^\003\0075\036bpm\010Z\006Wx\016b 1^\1774mz\014\003.\011<9#Hf\021a\n\036z\032o\023l &<_\024m,c:\000P\020\014\002\000\000L\020\036iA>1\005L\001\0200\r*\004\003\004`%*Lb\027\030\005 `\032T\010\n\011CJf+IRS4Ymba\001\022n1KF\0239@j\006\001U @XL\\C6\030.7\031\000d (\035,&c%F (\034M\026k\005dy\020\020lW\023QRf4Xl\027#%^n\020\020.W#!^r4]\017\023\004\006\022\002@` \0132j\027#\006ZD8\034\001WO\034a~B\010Lf\006&\0114.jT%\027bip\013Oj\007A\020(\037\"xT\032|PX\r7sdYz\003\003g*wX6oXt_ry!$_A_)<#jox3\007p\005'roBG\026)!\"]\rQM$wd\014D\007;\n`\0225g/OL\004\033\007suM\025|\177RmB\036U!\002\023\021\003\030q\017\006qu\006$D8\022<u_r\024`\000|\004\003\000@\000\023\004\010\002P\030 8\023\010,`\011\003\000jP \030&\002*Tf\0219@*\006\001U @PL\034V2\\M\025\033%Nn\026\010\011\026s\014\\1\036\014\007 0\r*\004\005Df4\0331Bs9H\006\"\002Ajb6\032,2\002Adi6X.'I\001\006e9\035\r\0263%Fa:\032-vq\001\002u:\032\rw\023%hy\020\013$\0049Hb:\030\016\000`\032T\010\013\011L%\006\031$@1\034N'\002\002YJr4Tm\026;8X $[L2q\000Z #\033n\"\003\005jt4\033n&KiJd\020\035.6)\001^n6\036&\021y@:\006\001U @XL,V2\\M\025\033%Nn\020\025\016'+Mh '\031.G;=dk\030 1\020\024\006\002\000Sb\000\022\013PYg\r\000~\011G\006.<\007H!\017\014s7\027tf_L\020\020\014\023_\027j,F0<,\011\025EK@\005R,f&#zmB-.<A\036!\031g\002{L.A\002g#\005\004\011K\025&O$\023tcj *\"\013\004#'R[\017\000:E{\030[\031\0363>2'\003}<o\"1q\0366zhh7js\006dU\036+\026\022_T#\007\013,HTa\177\006[\036Rh9[N?]` \030\004\000\001\030 @\035YB\003J\030Bf\000H\030\006U\002\001B0\022U&1\013L\002P0\r*\004\005\004ae3\025di)Z,vq0@I7\030ec\010|`\035\003\000jP ,&\026+\031.&JMRg7\010\nG\023Uft\020\023LW#]^r5L'#\001`\014\003*A\0011\031DPc\024H\006\023Idr +\031.&JMRg7\013\004\004K9F.\020\013$\0043=d 0].FC=di=\031,B\003Ufe\020\033mfcdbE\030\020``\032T\010\003\011O\nf+IRS4Ymb\002\rXa9\\d\003\021\001 u1\033\r\026\031\001 r4[,\027\023d@C2\\NFK\031Rc0]\r\026{8@A:]\r\006{IRt<H\005R\002\034f0A\000! \024\010\002\001\000+a n\013*,mYw\022o\026('ni7n\005A\033\017YX*cfYyCz3'h6.E\010q8;\n#'\0135q/x\0322\035 ^#\0161=,Zu57E\027q\0068N\023O\001(yYEt\023l\007{\035\030\010o\013VK\010\177\004:\002\006SC&\000g/n<\007H\003]cI\rnR@Y\005^\017\022V4S\030QF\006\"{\005u\"0\004nyoaR\007d3\000A\005\02552\01366\027 f\014[[?u\000UY\024\003E5;\031\r;S8r\0026N1;;m\011\024* \036\004 *k\0255S#)4\0311f\020F=\017f?dg ,cG1A\010wXcvi>\\W6vj\034I(i\034n4\003M435\026MjGk\016C3J!\002MAP1:\02420.mi+\014c|Z\031`B5\006oy\0113E|D,\nB|\010}y\006^b*\011B\017b\022W\003t$\004\003\000@\000\023\004\010\0026\030 4s\010\\`\025\003\000jP (&\016+\031.&JMRg7\013\004\004K9F.\030Gf\001h\030\006U\002\002b12YJr4Tm\026;8@T9\035.7!\001\034e:\035mw\023,b;\030\016 `\032T\010\013\011LJF+IZs\020\033lb\003Ufe\020\030.B\003!ht8\034g\"y=nw;KNf+IRs4Ymbs\r^m\027TJ\004\011\000Pc\024L\006\003\0118`,\003\000jP \014&%![\014\027\033L@2\020\024\016V\0231Rc\020\024\016&K5Br<H\011t\032M )\031.7\003=\\d2\\F\010\014$\005\001@@\032\014S\014ba?Q\006G`\025z\013\036ZR\014[e\026w\005\017i<9\017K@1\013/icx}\010Cd:\ng!\032IChRi\004+:\004R@GxdoS\011\177\030T\016\022j{Hnm\017\0165\025\005\023\004\031`\034\001\001\033W.=\013]UOF7S\024C\"b1JME!{\032E\017bI*.gEd\001\"hc>i\037x-++\nw?9V\006r\035:\0036(b\021;\011~'\177\030\030\010\006\001\000\000&\010\0174`_\030Bf\000H\030\006U\002\001B0\022U&1\013L\002P0\r*\004\005\004ae3\025di)Z,vq0@I7\030ec\011\\`5\003\000jP ,&.![\014\027\033L@3\020\024\016V\0231Rc\020\024\016&K5Br<H\0106+Ihi3\032,6\013QRo7\010\010\027+QPo9\032.GIB\003\011\001 0\020\006%8YO<C8P\004)4\0107`D\006oFWWZHT\004>\010\014\005t&=Nd#Ow\000K\001y\027n*T\021\000ZW0\006\037<\037si\035f4\000U\010o]52\013\"1Q8w\021\037\031t&1NW\016Hso'P^\007.|\025\020c#D\006|`\037xV\010kw\001$m$da\\{\014hAK)i0^9v|}M?DD)O8v\n{!z\023EHL2KP\026B\026N\002\001@ \000\011B\004\001(\014\020\034\011D\0260\004A@5(\020\014\023\001\025*3\010\\`\025\003\000jP (&\016+\031.&JMRg7\013\004\004K9F.\030O\006\003P\030\006U\002\002b3\032\rXa9\\d\003\031\001 u1\033\r\026\031\001 r4[,\027\023d@C2\\NFK\031Rc0]\r\026{8@A:]\r\006{IRt<H\005R\002\034d1\035\014\007\0000\r*\004\005Df\022C\014R \030N'\023A\001,e9\032*6K\035\\,\020\022-f\0318@-\020\021Mw\021\001Bu:\032\rw\023%te2\010\016W\033\024@o7\033\017\023\010|`\035\003\000jP ,&\026+\031.&JMRg7\010\nG\023Uft\020\023LW#]^r5L\020\030H\n\003\001\0003\013m\010E:\\4t\025=\035eTLLGk\031AB\034\026BH\010fj\034\177TBH\020N\0136gxR;!O\010\\\036;|i\177\022._\003OB\030~'c\017\037\"#|XeYN\034d \001\r\014\014\002rd\016\021.|>a]uJJ'E\007 iW<\007u\013S5\007\021JchU:y}E}rT@'/U\027\033U\006\006}l\002G\031\014y]b^6d4X?\011Xt9\011'W\014p\020\014\002\000\000L\020 \016la\001e\014!3\000$\014\003*A\000a\030\011*S\030Ef\001(\030\006U\002\002B0rYJr4Tm\026;8X $[L2qD>0\016A@5(\020\026\023\013\025LW\023%&i3[D\005#Ijs:\010\011f+Qno9\032f\023Q@p\006\001U @XLb(1J$\003\011dr9\020\025LW\023%&i3[EB\002%\\c\027\010\005R\002\031^r\020\030.W#!^r4^LV!\001js2H\rvs1r1\"L\01000\r*\004\001DgE3\025di)Z,vq\001\006l0\\n2\001L@P:XMFK\014@P9\032-V\013Ir !Y.'#%Li1X.FK=\\ ].FC=di:\036$\002i\001\0163\030 @\020P\n\004\001\000@\031;Tq%|<\007c!s<679o?\014K.(\022\030\023~\0032\037kPHB^Q>\"Ja`EH\004on\024aH9.b\006\004\"\006>jeFu\033j\021 c_\"m4Ta,i\014r23!h^\024K7\001\000\010Xh^Y\032#&y\003\013Y\025P,.yP,3QXgWWp!\022!9l\\Ng\031\033\\\032tL*\0348/\004\004i<1^I\"\035\006d\025.\021\r:/n\031\030\"TQ\0212e,\017\0240Dz\033ME\017Z*@\017owK\025.>\nH\014`A>+\023_jHr}!\r\027x\004\\/v\010\024+(yNn5]\r7q\0034le#\006L,U1\0367!&\\\016:S_\003\010,\013Sr+pgC=B;3U\177;+ez iT#\030S\023e=\030z9s\010oUBY3`w\031&$:\006kahI&[cK\034x\032$v\025W\"M\013J^.\002\001@ \000\011B\004\001\033\014\020\0329D.0\nA@5(\020\024\023\007\025LW\023%&i3[EB\002%\\c\027\014#s\000t\014\003*A\0011\030Y,e9\032*6K\035\\ *\034NW\033P@N2]\016v{IV1\035L\007\0200\r*\004\005Df%#\025dm9H\rv1\001js2H\014\027!\001Pt:\034\0163Q<^w;]eg3\025di9Z,vq9Fo6Kj%\002\004@(1J&\003\001D\\0\026\001@5(\020\006\023\022PmF\013Mf \031H\n\007+\011Xi1H\n\007\023%Za9\036$\004z\r&P\020\024LW\033A^n2\031.#\004\006\022\002@` \017\017\020\020\016Ann^\032#K8mi^\013M/R<11kc*o \002*\004;\014NE-9;\022w\032[kMM]=A@&Y}VX\002LZb8scx}eZ\031\024soX\"y{vl\030]7\034\036@>5aw\0350\007c([ZxF\020y|\021\030\\Gk!OYgF}V3C\004\"-\023\024es\007o'A ^?\002v`B\r\177BE3?GK<\013ZZ\\\005B[JT\004\003\000@\000\023\004\010\002P\030 8\023\010,`\011\003\000jP \030&\002*Tf\0219@*\006\001U @PL\034V2\\M\025\033%Nn\026\010\011\026s\014\\1\036\014\007 0\r*\004\005Df4\0331Bs9H\006B\002Ajb6\032,2\002Adi6X.'I\001\006e9\035\r\0263%Fa:\032-vq\001\002u:\032\rw\023%hy\020\013$\0049Hb:\030\016\000`\032T\010\013\011L%\006\031$@1\034N'\002\002YJr4Tm\026;8X $[L2q\000Z #\033n\"\003\005jt4\033n&KiJd\020\035.6)\001^n6\036&\021y@:\006\001U @XL,V2\\M\025\033%Nn\020\025\016'+Mh '\031.G;=dk\030 1\020\024\006\002\000]<\034L\177g\011.BU\027\020:_s\017b_m\001\017c\010\027X\021\033N\031AgU\025\030E+FC\030\034vJ\0137uuU\\Yd$LR\005D<~\000@\033xp,1J\0012w3:E-^X\"vb8a\006x\024&rRC\017(1 ;EZ*UAP-\rnY?JWbl%4\003C6Z&h1a}t\006\037l\000zHz22q^8P,bcQ\030\035!Z81cf\000\024G` \030\004\000\001\030 @\035YB\003J\030Bf\000H\030\006U\002\001B0\022U&1\013L\002P0\r*\004\005\004ae3\025di)Z,vq0@I7\030ec\010|`\035\003\000jP ,&\026+\031.&JMRg7\010\nG\023Uft\020\023LW#]^r5L'#\001`\014\003*A\0011\031DPc\024H\006\023Idr +\031.&JMRg7\013\004\004K9F.\020\013$\0043=d 0].FC=di=\031,B\003Ufe\020\033mfcdbE\030\020``\032T\010\003\011O\nf+IRS4Ymb\002\rXa9\\d\003!\001 u1\033\r\026\031\001 r4[,\027\023d@C2\\NFK\031Rc0]\r\026{8@A:]\r\006{IRt<H\005R\002\034f0A\000! \024\010\002\001\000+9:(ESF,j~\030}T2\017+3YK(|AdO\011DT_\001feDV;m\004\017Iu\007m7:oEyh\020\177\034N@3\\|\"HC\0274Jh\023[H\0130OiC.T<TXl\027\004*k7Lc6J6\002z*\022&\003r8iZ#dAvB\014R{\014SD\n`<\"^s(V\024T\020nh\031[U\035\013\031p\0107\nG\034,\011!#\014f5`]\0019O\023:?\035y+\003t,1\030riy\032K\010R\003\\ Kri\024q\000\0200\026xy9Fq:,`F\003y\020\006m\0331\026\027:\005O@Ff8\006YTi_+\022#-vqn\027L'\016\r\026%ZP\013alR!lmf\004\177ul.>Nd\013\rR\036e#^.\001\037\004dv44! \014jkQ5O\003-Uo'\027\177\001\014\010<81M\014e\006P}\0239~F\014\033\032[\177IK2~x\014\004\003\000@\000\023\004\007R0/L!3\000$\014\003*A\000a\030\011*S\030H\006\001p\030\006U\002\002B1:I&A\020\021\014\027#\004@S2XnW\023%hy\026\010\011\026s\014\\1\027\014\005@0\r*\004\005DdU\033\025Fu9\031$\005\033\025dv2\\D\004\033\025dt4YM\026\033\005hi7[D\004\013Uhh7\\M\027#da\001B@O`\004K\034z`kP3rjU\011AUuB(\005l\014VkQba_\035k\032^\014E \017K\004 \0249\033|<\021bE A\r\020Z\0147*z6\022\010\nZv4 3 -\011\027I%I,b\022YY\010\003c~x\ne[\004\003Y.\001\033El>M]iN\032B\022VL\022\027\021m\034R\032\011KI!\nf8\036\nu)\025!1f:4`V\0319f8m8\031i\016.t[Vd\007O0\020\014\002\000\000L\020 \0114a\001O\014\"s\000T\014\003*A\001!\0309,e9\032*6K\035\\,\020\022-f\0318b\037\030\007 `\032T\010\013\011EJf+IRS4Ymb\002Qdu9]\004\004s\025hw7\\M3\011l`9\003\000jP ,&2*\031.&kL@o3\010\016W\033\024@a:\010\r\007#Q`s\035\013ew;]n.;\031.&KMRg7\013L6{4^R(\020$\002C\014R0\030\014$S\001\014\014\003*A\0001\030q&e1].&)\001&e9\035LW\021\001\036C)T\004\005\023\025fp7[LF+Ha\001D@P\030\010\002pQLY\020Pw:f\n4<\027v\033X:Sz\177\024\027D0gnO}\027cNj6\017&Qu\030y\003PK\"/9lkn!Q\030:\022\014!\025w\011\0247W_4L;\177\\\177r+-&\033dW3\034,\030\036\006jQ\\B\000\011\035D\"S\r$cI6=O0\003\037D=\023/P!\036\024qk3!K'E4rH*i\025\"q\026\036:h\023W\034e;\001iV=B^lk\\\0101\026\037\001\000`\020\000\004a\002\000M\006\010\r\024b\027\030\005 `\032T\010\n\011CJf+IRS4Ymba\001\022n1KF\021y@:\006\001U @XL,V2\\M\025\033%Nn\020\025\016'+Mh '\031.G;=dk\030Nf\003H\030\006U\002\002b3\022QJr6\\d\006{\030@u9Y$\006\013P@h:\035\016\007\031h^/;]nrsYJr4\\m\026;8\\c7[%w\023AB \024\030e\023\001@b,\030\n@`\032T\010\003\011Hjf+IRS4Ymb\002QRm2H\n7#\005Zp4[Lr\002\005jt4\033n&KQr !P&\010\014$\005\001@@\032!LuOB\000\010+\026\026:h\011\021\021\r\030W`JZm{![9Y|Np.rCt@K\007a\030(rNfzT\\\030yBcuS4\031M^C8\0365AnP\nOg\001q\035P$w\020ItFQ?Q\030!#S6\n_2y\023\001Q\001\030\0374\032r(B\003\024^AiyfY('oKU\013~.!\014F]);g\013PDCs<d\010(Jnt=\004@\026\025$\0177;\023\007(\010\006\001\000\000&\010\020\005:0&L!3\000$\014\003*A\000a\030\011*S\030C&\000X\030\006U\002\002B0\"Y\022S L%s\0014\014\003*A\0011\031\031,i9X$\004K9he9\033L\027#%^n0[\004\005\033\025dv4XlR\002\005fs7Xm\026\013QRo7\014\020 \010(\005\002\000@ \014(u\032s e<\022\005QXlg\031}'(\032YD\0020L\002x\"%O\020;-jN%b&+(_]Ul\031xJB9\037OH;O\"%=S\n+4mp/?G(Z-BwBO f\036q4H\021EjH\\\025`#Q\020G`pz #\001H4\034\025ek.x ;aJ5Kw\0028e8Vf.m\014L\n8J1\022Mty\"\032\n`#{T\r\024t26hPMf\011\026$B/4\"T\r4\022RX&C\0355)vt\n#\022\037,\025zr\007`;\027Y\031Qr9\036ms#%\000\030=Q\177s('\033u`\037jJH \004fJBqU\001\"x+AkX\032_\003%pi2\036\032q'8'XQ|_w+\004plj\011V-;\"\020\0313C]>\r~y\016M:Y\011'&mL|\0050Y\0335Lw\025l\"p\\ Ll#([|r\016Jn{\177#4;91w\001\000`\020\000\004a\002\000\\&\006\011D\0260\004A@5(\020\014\023\001\025*3\0104`\013\003\000jP (&\004+\022*4\011D^0\026A@5(\020\026\023\023\025M\027\033\004@I7\035\014W\0239Bt4[mf\0130@S2\\NfK\rJ \\n6{\rRa:\032-vqD$0\010\001@5(\020\006\023\004Qj\002\002I^o:\010\006#\004\010\002\n\001 @\020\010\002R\0018-5,\"\003a+5\011L\027Hd\001|_ffuH2^o2\006\177\rTV($4Lb\027\006+FV:(Bu;\0218 \0038:n{Fn;{jx\026NA\023$XA\032\177\"]E\011.,\016Rh\\HiqPL\016'9iVU`\nmD Qa}[$/i\rxF9Soe#L=(\026\025+\007-]\031s-\0214P\020kuZNph\\\031\011=sE|,\002NK\016_Z\003\007%\014\017^0|5\034|?Ku\031QHJ\013wd\n7Qk=YV\017MlD\006vaI\03468E`\011^eg\017EDr\177AQKZ#x- \025Ggm\017p!5\024`%d9\0116v?.=\034b26XaHTtc\016z\"u-\005\030\"\036\r\006$7aJW]\n}s41Uzlv(O%+;\004kC#K\022RX2Bm\014@ny\003;XM\030`\014\030ddjg` \030\004\000\001\030 @\027\011AB1\005L\001\0200\r*\004\003\004`%*Lb\r\030\002``\032T\010\n\011A\ndJM\0021\027L\005P0\r*\004\005Dde3%fa\020\022-g#\025dn0]\r\026{9Bl\020\024lW\023YRc2H\010\027\033M^c4X.FK=\\1\011\014\002\0000\r*\004\001Da\024:@@R7[nB\001La\002\000B@(\020\004\002\000];\010;ASU#3wnpH|4\020Q\007U\024tU\030tsC\033Ff\0321PU~Br$iO#$E\014HL>&\022\027{q}F8 \004Ea8\ra>x)L+sD\026\027\027RK3~J.\024Zn&c\007\010uIT\010Lu2\021]#Z3IR+\\_\034*C6T^\034G#/Z\0308\023\002U%7#at \020\034\005:~[\0022^Fldn~NX;,z7},F$\013\031\017\001b5;HI4\003^h\004P\022L\025\\fIAy9\032q4@7H\006\007R\001[4y\034kw\005<}uo0\nD\030'c\177 \034H:=C5)GaZGLBp>.#\\BFbU\026\011\00331l+,\027g\003Qg'lI>}\007l\013C\032^\007\003\037GPJCf!\037KSD-cTEH7\013zm\006-ma\006\025r~\011\032\036)B\024~.,:'J%bIC(\010\006\001\000\000&\010\017<`a\030Bf\000H\030\006U\002\001B0\022U&1\006L\00100\r*\004\005\004`E2%&A\030Kf\002h\030\006U\002\002b22YRs0H\011\026sQJr7\030.FK=\\a6\010\n6+Ili1Y$\004\013Mfo1Z,\027#%^n\030DF\001\000\030\006U\002\000b0J\035 )\033mw!\000h0@b (\014\004\0018u|\021z\007\033cc\000\017kg\024z\\\004\007}\011|v+4b\031z]eV\013\003v\027\016\021\033 7\037!W.&\033\037vMG[1\rH\0302\000a\034\016A+pp\003 \014F|\177[I[\0221ftjyOi4-F]\002Fy\031g\033|\"O\017\000/`\n\022\035D us%'*\\\032$\021o=eS6nSA|_U\005eDZnajBu\r\032@GR+\033G7:0\023]\033 @@0\010\000\0020@{f\006\011D\0260\004A@5(\020\014\023\001\025*3\0104`\013\003\000jP (&\004+\022*4\011D^0\026A@5(\020\026\023\023\025M\027\033\004@I7\035\014W\0239Bt4[mf\0130@S2\\NfK\rJ \\n6{\rRa:\032-vqD$0\010\001@5(\020\006\023\004Qj\002\002I^o:\010\006S\004\006\022\002@` \nh\001]rP\037\006\021\010q\0030\033cp:\022\017\027\027/@D\010H5]<\025,>\032+\023_XG\022Zg\024v<n\017fU\017L\024\007,`Im('\025LH8fKd\020>\025bO}P\000y\016XSap3p\026\023pX#:^JL\n^m\003QPo\0117x\006\\\007J])eC\022B\"~\035D(fN\036\004v]3Gxk\037-\003GP.\017U\032YFL\033Ldc,7b&Y\014\004\003\000@\000\023\004\010\003\035\030 1C\010,`\011\003\000jP \030&\002*Tf\020i@\026\006\001U @@L\010U:\030-\003\010\\`\025\003\000jP \034&\016)X-G!\001\030a5Y$\004\033%hy\030F\006\0010\030\006U\002\002B0zaFe9\035\004\004*h@b<H\010E\032Pb\030\030\005@`\032T\010\003\011Ck\006\033\025dt\020\021+\"\003\011r \"\024jC\011\004`\037\003\002%(2\"\rw\006@!\020\010X$c0P\014FK\035fi3]\016'+Mh.1[mS\004\010\002\n\001 @\020\010\002ZT\0147VK\177^[h:*]X[r\037Bj\035#-,\022s61?\021\036\177\022.aI>c[G\0054G\032'S`1\013wSu\016\031;D,\017w\r(\002w8\03540\0165\005\023A\003.' 6\n\011\032\016\177R\014(E\0270\025e*5mM\031E-r\036\016\031>VT/yE\013*T'\026iAm'\033C\022+h\024\035\0308j\011Z\010xDuh6\002\000{6\002??GQ}\177 \000E6h\0075\0301%\nij{2K\004\001\013f\016x|*\003F\r-\r\"W\032_)k\000\025L~`*I>6c:\017z\003zC~:9\006\004\005@|t\010.LEP%/qWx9gS\025\000\030\005\013|\014Y@sWVm9X-g0!nnG\034O2\022C17W\026T\035rV9\\p,\034oc2\023N\030C3\005\034tvy_k\r:>\035\032%kU-+:)\024%\r}$|w\034 \030\004\000\001\030 @\024Y@v1\020L\003p0\r*\004\005\004c\005C\rJr:\010\011\026sQJr7\030.FK=\\a6\010\011\026s\014\\1\013\014\002@0\r*\004\005DaUC\rJr:\010\n&{=h !P&\010\020\004\024\002A\000 \020\005\"haEG#CtAvp\031\020\rXh[\02450X6^\027l+Iz\010+h\010o\036\"N+\025;[\003! \031wB\025\030h\022\017\035FB:NR\017L,=eU\025&EBTN]\\yR;!\001;w\017\025`VWD\004\022;-$jc]A($\031\011\177?8\027Z2E\025*(\020\022r4L>O?\036P\005\000hF^r\023\002 S '\013+\000djz\r1LTL\010SB\037.t\0142'\026cooEFK0YpZ?UH\030>Q\"^(8\021K\006E\020\0043Vrj\024(ZLun jDW;/I~\006\034 IWlH=hj~Y\002J\035R\032\nD1J}\030YA\024=\r\025[&=d\036\004}l\005\005Aj ox&\022-[\"\033a\007#wN`2W\"M6`Of:\020BO92`f)/\033U\014S&E>G\001HUoEL9*RCEQ\022bKh@@0\010\000\0020@sF\004\001DB0\017A@5(\020\024\023\014\026\0146+Ih $[NF+I\\a:\032-vs\005X $[L2qD60\014A@5(\020\026\023\011\026\0146+Ih )\033mw!\001\006A\020\014&\003\021Pa\001D@P\030\010\003->\033b\"\032M\013nG\026\nYvP\000Le\024\021\024HW\023= !U3\024#.xn\\1yl3\016mSt\033xYA,I\021\\'T+SE\021^\032\010\004\027V[%EDLTXN\0339\005B\025\036)r#[L\"-@o|;\011N,k3vg$DX`Ob@R\016\001\007\014TJ\016\031 \017HV\006\034+\010jU#q\030\026w2D\016)\034WI\016K\031a\001\027\016\023+he{k\001\000`\020\000\004a\002\000SF\003qDB0\017A@5(\020\024\023\014\026\0146+Ih $[NF+I\\a:\032-vs\005X $[L2qD20\013A@5(\020\026\023\010\026\0146+Ih )\033mw!\001\006A\020\035F\023\004\010\002\n\001 @\020\010\003\003\022U|Vc)X\004H\007a>Dq>\004efR\027k\r\\{3=kW#\021R\014<L/\177\013\005wwBf=A\0319a9\rRHin\016\"\011fH\031nC]\017lnLJq|\030\037%\027(Aip&.=2|\017\036sG\032,J\035:bV\177\035Ef!L`{\02055OJJ'\026< &#j#\rU|8C`\030|v]dg\013Dva\"\007tK)\"\016O\003p]LGf`2dI[0!&fE\032j\034u'\017{GH\031UX6\035\004\027\036sJ\007\006\036o\023\004j\033\001x.\011ar\026f_\004#\027yoQH\177\032[u&\030[J\031z5#9\0178Z+3\023p\001U<\0061\025}mvA3\001~p\\p\001b:F\024a|^!^jU|\034c\027ci\027\020C#\036B~(\036j xx\006?4\002P\0307/iw,r\1771\020/(R&b\025]\021M${` \030\004\000\001\030 :\023\002\014b!\030\007``\032T\010\n\011F\013\006\033\025dt\020\022-g#\025dn0]\r\026{9Bl\020\022-f\0318b\036\030\007\000`\032T\010\013\011E+\006\033\025dt\020\024Mv{P@C H\016c\011\000b0\031\r\006\010\014$\005\001@@\024pN\017%)S\006.\016a'RE=M\\\016Q{\023\0318\020\032\0333\003i]\021qk\027Lt=%_\r,0\007\033\000.6\020\n>6ElFxh\0318\032\025)\030\014so9Qcpt\031LgzI\024@(\023\027%\007\n\032\014 \036L\005:_\031\033z\037zHD\0023vsj7\022g'Q\035d5\007#9=\001x0pp\016;06Dw=<#\017B)bqO>\025\007/yExU\0179wh\010\006\001\000\000&\010\020\005T0-\014!3\000$\014\003*A\000a\030\011.W\030DF\001\000\030\006U\002\002B0K\011JT)\025*5#\025H1\rL\003\0200\r*\004\001Db&\023\025(R*TjF+\020@R7[nB\002\r\002s\030FF\001@\030\006U\002\000b1\013\011JT)\025*5#\025H )\033mw!\001\006A\030 @\020P\n\004\001\000@\032K#Mt\023\005\016\nP\rz\022Vpe\023m%y5k%\r\016Q[\004SDpk!\006\001\005pH\177m\032\017Ry\003\r0Q\020~G7\022X}?\0229V}\037j\037\r/_AMufxuyVz%\026='K-`t\014t\030<\035t<\177\037hM9v\023#Xh;>JTyr\004_\005O\037\011\n&`2\034e,q.\037{\010\023\017U11|c\002@s%5g\003xUe?Q%vw\007\"_b?\005@dgVTd\023\034@r-4k|\014,$m>c~\031\007 c8fqpE3M\007_%<9\rr\033->i\002fgM-\014\034X]_\011\032\177|tv\000d\022s{]M\177~.0:;1T<;W4aQ\034j:1~V!z\027\013eZ}zAe|k_o\0116IoC\021Az\031\001\\\\q\0017R,CN\031n1<C0\0117\030uDUXGD\000h5Z'\023\n\002\001@ \000\017\177\177\177";
+ static {
+ try {
+ org.ibex.net.SSL.addCompactCAKeys(new java.io.ByteArrayInputStream(unpack(DATA)));
+ } catch(Exception e) {
+ System.err.println("Error loading root CA keys: " + e.getMessage());
+ }
+ }
+ public static void load() { /* force clinit */ }
+ private static byte[] unpack(String s) {
+ int len = s.length();
+ if(len % 8 != 0) throw new IllegalArgumentException("not a multiple of 8");
+ byte[] ret = new byte[(len / 8) * 7];
+ for(int i=0; i<len; i += 8) {
+ long l = 0;
+ for(int j=0;j<8;j++) {
+ l <<= 7;
+ l |= (s.charAt(i + j) & 0x7fL);
+ }
+ int base = (i / 8) * 7;
+ for(int j=6; j>=0; j--) {
+ ret[base + j] = (byte)(l & 0xff);
+ l >>>= 8;
+ }
+ }
+ return ret;
+ }}
--- /dev/null
+package org.ibex.net.ssl;
+
+import javax.swing.*;
+
+import java.awt.*;
+
+import org.ibex.net.SSL;
+import org.ibex.crypto.*;
+
+public class SwingVerifyCallback extends JDialog implements SSL.VerifyCallback {
+ private Component owner;
+
+ public SwingVerifyCallback(Component owner) {
+ this.owner = owner;
+ }
+ /*
+ super(owner,"Certificate Verification",true);
+ setModal(true);
+
+ JTextPane tp = new JTextPane();
+ doc = tp.getStyledDocument();
+ JScrollPane sp = new JScrollPane();
+ sp.setPreferredSize(new Dimension(400,300));
+ sp.setViewportView(tp);
+ sp.setAutoscrolls(false);
+
+ this.setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE);
+ JComponent bottom = new JPanel(new FlowLayout(FlowLayout.RIGHT));
+ JButton accept = new JButton("Accept");
+ JButton reject = new JButton("Reject");
+ accept.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) {
+ accepted = true;
+ hide();
+ }});
+ reject.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) {
+ accepted = false;
+ hide();
+ }});
+ bottom.add(accept);
+ bottom.add(reject);
+ getContentPane().add(BorderLayout.CENTER,sp);
+ getContentPane().add(BorderLayout.SOUTH,bottom);
+ pack();
+ }*/
+
+ public static String prettyFingerprint(byte[] fp) {
+ StringBuffer sb = new StringBuffer(fp.length*3);
+ for(int i=0;i<fp.length;i++) {
+ if(i>0) sb.append(":");
+ sb.append("0123456789abcdef".charAt((fp[i] & 0xf0) >>> 4));
+ sb.append("0123456789abcdef".charAt((fp[i] & 0x0f) >>> 0));
+ }
+ return sb.toString();
+ }
+
+ public synchronized boolean checkCerts(X509.Certificate[] certs, String hostname, SSL.Exn exn) {
+ final boolean[] ret = new boolean[1];
+ JTextArea ta = new JTextArea();
+ ta.append("Subject: " + certs[0].subject + "\n");
+ ta.append("Issuer: " + certs[0].issuer + "\n");
+ ta.append("Start Date: " + certs[0].startDate + "\n");
+ ta.append("End Date: " + certs[0].endDate + "\n");
+ ta.append("MD5: " + prettyFingerprint(certs[0].getMD5Fingerprint()) + "\n");
+ ta.append("SHA1: " + prettyFingerprint(certs[0].getSHA1Fingerprint()) + "\n");
+ ta.setEditable(false);
+ ta.setOpaque(false);
+ JScrollPane sp = new JScrollPane(ta);
+ sp.setPreferredSize(new Dimension(300,150));
+ final Object[] messages = new Object[] {
+ "The SSL Certificate the server presented could not be verified.",
+ exn.getMessage(),
+ sp,
+ };
+ Runnable r = new Runnable() { public void run() {
+ int n = JOptionPane.showOptionDialog(
+ owner,
+ messages,
+ "Confirm Server Certificate",
+ 0,
+ JOptionPane.WARNING_MESSAGE,
+ null,
+ new Object[] { "Accept", "Reject" },
+ "Accept");
+ ret[0] = n == 0;
+
+ } };
+ if(SwingUtilities.isEventDispatchThread()) {
+ r.run();
+ } else {
+ try {
+ SwingUtilities.invokeAndWait(r);
+ } catch(Exception e) {
+ e.printStackTrace();
+ }
+ }
+ return ret[0];
+ }
+
+}
--- /dev/null
+package org.ibex.net.ssl;
+
+import org.ibex.net.SSL;
+import java.io.*;
+
+public class Test {
+ public static void main(String[] args) throws Exception {
+ SSL.debugOn = true;
+ if(args.length < 2) { System.err.println("Usage: SSL host port"); }
+ String host = args[0];
+ int port = Integer.parseInt(args[1]);
+ SSL ssl = new SSL(host,port);
+ //ssl.setTLS(false);
+ ssl.getOutputStream().write(SSL.getBytes("GET / HTTP/1.0\r\nHost: " + host + "\r\n\r\n"));
+ cat(ssl.getInputStream());
+ ssl.close();
+
+ // try to resume
+ ssl = new SSL(host,port,ssl.getSessionState());
+ ssl.getOutputStream().write(SSL.getBytes("GET / HTTP/1.0\r\nHost: " + host + "\r\n\r\n"));
+ cat(ssl.getInputStream());
+ ssl.close();
+ }
+ private static void cat(InputStream is) throws IOException {
+ BufferedReader br = new BufferedReader(new InputStreamReader(is));
+ String line;
+ int count = 100;
+ try {
+ while((line = br.readLine()) != null && --count >= 0) System.out.println(line);
+ } catch(SSL.PrematureCloseExn e) { /* ignore */ }
+ }
+}
--- /dev/null
+#
+# What to build
+#
+
+# Java sources that are part of the compiler/interpreter
+java_sources = $(wildcard src/org/xwt/mips/*.java) $(wildcard src/org/xwt/mips/util/*.java)
+
+# C sources that are part of the compiler/interpreter
+mips_sources = crt0.c support_aux.c
+mips_asm_sources = support.s
+
+mips2java_root = $(shell pwd)
+build = $(mips2java_root)/build
+tasks = upstream/tasks
+
+#
+# MIPS Settings (don't change these)
+#
+flags = -march=mips1
+MIPS_CC = mips-unknown-elf-gcc
+MIPS_CXX = mips-unknown-elf-g++
+
+# Be VERY careful about changing any of these as they can break binary
+# compatibility and create hard to find bugs
+mips_optflags = -O3 -g \
+ -mmemcpy \
+ -ffunction-sections -fdata-sections \
+ -falign-functions=512 \
+ -fno-rename-registers \
+ -fno-schedule-insns \
+ -fno-delayed-branch \
+ -freduce-all-givs
+
+MIPS_CFLAGS = $(mips_optflags) $(flags) -I. -Wall -Wno-unused -Werror
+MIPS_LD = mips-unknown-elf-gcc
+MIPS_LDFLAGS= \
+ $(flags) -L$(build)/org/xwt/mips --static \
+ -T $(mips2java_root)/src/org/xwt/mips/linker.ld -Wl,--gc-sections
+MIPS_STRIP = mips-unknown-elf-strip
+
+# Java compiler/VM settings
+JAVAC = javac
+JAVA = java
+ifeq ($(firstword $(JAVAC)),gcj)
+ JAVAC_NODEBUG_FLAGS = -g0
+else
+ JAVAC_NODEBUG_FLAGS = -g:none
+endif
+
+bcel_jar = upstream/build/bcel-5.1/bcel-5.1.jar
+classpath = build:$(bcel_jar)
+
+GCJ = gcj
+EXE_EXT =
+
+#####
+
+java_classes = $(java_sources:src/%.java=build/%.class)
+mips_objects = $(mips_sources:%.c=build/org/xwt/mips/%.o) $(mips_asm_sources:%.s=build/org/xwt/mips/%.o)
+
+usr = $(mips2java_root)/upstream/install
+PATH := $(usr)/bin:$(PATH)
+export PATH
+
+#
+# General Build Stuff
+#
+all: $(java_classes) $(mips_objects)
+ifdef NATIVE_MIPS2JAVA_COMPILER
+all: build/mips2java$(EXE_EXT) $(mips_objects)
+endif
+
+$(tasks)/%:
+ $(MAKE) -C upstream tasks/$* usr="$(usr)" MIPS_LDFLAGS="$(MIPS_LDFLAGS)" MIPS_CFLAGS="$(flags) $(mips_optflags)"
+
+upstream_clean_%:
+ $(MAKE) -C upstream clean_$* usr="$(usr)"
+
+errno_h = $(usr)/mips-unknown-elf/include/sys/errno.h
+$(errno_h): $(tasks)/build_newlib
+
+unistd_h = $(usr)/mips-unknown-elf/include/sys/unistd.h
+$(unistd_h): $(tasks)/build_newlib
+
+#
+# Interpreter/Compiler/Runtime Java Compilation
+#
+
+# This works around a gcj -C bug
+ifeq ($(firstword $(JAVAC)),gcj)
+build/org/xwt/mips/util/.Dummy.class:
+ mkdir -p `dirname $@`
+ touch $@
+$(java_classes): build/org/xwt/mips/util/.Dummy.class
+endif
+
+$(java_classes): $(java_sources) $(bcel_jar)
+ $(JAVAC) -classpath $(classpath) -d build $(java_sources)
+
+$(bcel_jar): upstream/tasks/extract_bcel
+ @true
+
+# GCJ Stuff
+# FIXME: We're cramming more than we need into the binary here
+build/mips2java$(EXE_EXT): $(java_sources) $(java_gen_sources)
+ @mkdir -p `dirname $@`
+ $(GCJ) -s -o $@ --main=org.xwt.mips.Compiler $(java_sources) $(java_gen_sources)
+
+#
+# MIPS Binary compilation
+#
+build/%.o: src/%.c $(tasks)/full_toolchain
+ @mkdir -p `dirname $@`
+ $(MIPS_CC) $(MIPS_CFLAGS) $($(notdir $*)_CFLAGS) -c -o $@ $<
+
+build/%.o: src/%.s $(tasks)/full_toolchain
+ @mkdir -p `dirname $@`
+ $(MIPS_CC) -x assembler-with-cpp -c -o $@ $<
+
+%.s: %.c $(tasks)/full_toolchain
+ $(MIPS_CC) $(MIPS_CFLAGS) $($(notdir $*)_CFLAGS) -c -S -o $@ $<
+
+build/%.mips: build/%.o $(mips_objects)
+ $(MIPS_LD) -o $@ $< $(MIPS_LDFLAGS) $($(notdir $*)_LDFLAGS)
+
+build/%.mips: src/%.cc $(tasks)/full_toolchain $(mips_objects)
+ @mkdir -p `dirname $@`
+ $(MIPS_CXX) $(MIPS_CFLAGS) $($(notdir $*)_CFLAGS) $(MIPS_LDFLAGS) $($(notdir $*)_LDFLAGS) -o $@ $<
+
+build/%.mips.stripped: build/%.mips
+ cp $< $@
+ $(MIPS_STRIP) -s $@
+
+# MIPS Compiler generated class compilation
+ifdef DO_JAVASOURCE
+
+build/%.java: build/%.mips build/org/xwt/mips/JavaSourceCompiler.class
+ $(JAVA) -cp $(classpath) org.xwt.mips.Compiler -outformat javasource $(compiler_flags) $($(notdir $*)_COMPILERFLAGS) $(subst /,.,$*) $< > build/$*.java
+
+build/%.class: build/%.java build/org/xwt/mips/Runtime.class
+ $(JAVAC) $(JAVAC_NODEBUG_FLAGS) -classpath build -d build $<
+else
+
+build/%.class: build/%.mips build/org/xwt/mips/ClassFileCompiler.class
+ $(JAVA) -cp $(classpath) org.xwt.mips.Compiler -outformat class -outfile $@ $(compiler_flags) $($(notdir $*)_COMPILERFLAGS) $(subst /,.,$*) $<
+
+
+endif
+
+# General Java Class compilation
+build/%.class: src/%.java
+ $(JAVAC) -classpath build -d build $<
+
+clean:
+ rm -rf build/tests build/org/xwt/mips *.jar build/mips2java$(EXE_EXT)
+
+#
+# env.sh
+#
+env.sh: Makefile $(tasks)/full_toolchain build/org/xwt/mips/Compiler.class
+ @rm -f "$@~"
+ @echo 'PATH="$(mips2java_root)/build:$(usr)/bin:$$PATH"; export PATH' >> $@~
+ @echo 'CC=mips-unknown-elf-gcc; export CC' >> $@~
+ @echo 'CXX=mips-unknown-elf-g++; export CXX' >> $@~
+ @echo 'AS=mips-unknown-elf-as; export AS' >> $@~
+ @echo 'AR=mips-unknown-elf-ar; export AR' >> $@~
+ @echo 'LD=mips-unknown-elf-ld; export LD' >> $@~
+ @echo 'RANLIB=mips-unknown-elf-ranlib; export RANLIB' >> $@~
+ @echo 'CFLAGS="$(mips_optflags)"; export CFLAGS' >> $@~
+ @echo 'CXXFLAGS="$(mips_optflags)"; export CXXFLAGS' >> $@~
+ @echo 'LDFLAGS="$(MIPS_LDFLAGS)"; export LDFLAGS' >> $@~
+ @echo 'CLASSPATH=$(mips2java_root)/build:$(mips2java_root)/$(bcel_jar):.; export CLASSPATH' >> $@~
+ @mv "$@~" "$@"
+ @echo "$@ created successfully"
+
+#
+# Runtime.jar
+#
+
+runtime_util_classes = SeekableData SeekableByteArray SeekableFile SeekableInputStream
+runtime_classes = Runtime Registers UsermodeConstants $(runtime_util_classes:%=util/%)
+unixruntime_classes = $(runtime_classes) UnixRuntime
+
+runtime.jar: $(runtime_classes:%=build/org/xwt/mips/%.class)
+ cd build && jar cf ../$@ $(runtime_classes:%=org/xwt/mips/%*.class)
+
+unixruntime.jar: $(unixruntime_classes:%=build/org/xwt/mips/%.class)
+ cd build && jar cf ../$@ $(unixruntime_classes:%=org/xwt/mips/%*.class)
+
+# This is only for Brian to use... don't mess with it
+rebuild-constants: src/org/xwt/mips/syscalls.h $(errno_h) $(unistd_h)
+ @mkdir -p `dirname $@`
+ cat $^ | ( \
+ echo "// THIS FILE IS AUTOGENERATED! DO NOT EDIT!"; \
+ echo "// run \"make rebuild-constants\" if it needs to be updated"; \
+ echo ""; \
+ echo "package org.xwt.mips;"; \
+ echo "public interface UsermodeConstants {"; \
+ tr '\t' ' ' | sed -n ' \
+ s/ */ /g; \
+ s/ *# *define \([A-Z_][A-Za-z0-9_]*\) \([0-9][0-9x]*\)/ public static final int \1 = \2;/p'; \
+ echo "}"; \
+ ) > src/org/xwt/mips/UsermodeConstants.java
+
+#
+# Tests
+# These are simply here for convenience. They aren't required
+# to build or run mips2java
+#
+
+build/tests/Env.class: build/org/xwt/mips/Runtime.class build/org/xwt/mips/Interpreter.class
+
+# Generic Hello Worldish test
+test: build/tests/Test.class
+ $(JAVA) -cp build tests.Test "arg 1" "arg 2" "arg 3"
+inttest: build/tests/Test.mips build/org/xwt/mips/Interpreter.class
+ $(JAVA) -cp build org.xwt.mips.Interpreter build/tests/Test.mips "arg 1" "arg 2" "arg 3"
+cxxtest: build/tests/CXXTest.class
+ $(JAVA) -cp build tests.CXXTest
+
+# CallTest
+build/tests/CallTest.class: build/tests/Test.class
+calltest: build/tests/CallTest.class
+ $(JAVA) -cp build tests.CallTest `date|perl -pe 's/\D+/ /g;'` `id -u`
+
+# FDTest
+build/tests/FDTest.class: build/tests/Test.class
+fdtest: build/tests/FDTest.class
+ $(JAVA) -cp build tests.FDTest
+
+
+# Simple
+Simple_LDFLAGS = -nostdlib
+simpletest: build/tests/Simple.class
+ $(JAVA) -cp build tests.Simple
+
+# Paranoia
+Paranoia_CFLAGS = "-Wno-error"
+Paranoia_LDFLAGS = -lm
+paranoiatest: build/tests/Paranoia.class
+ $(JAVA) -cp build tests.Paranoia
+
+#
+# Freetype Stuff
+#
+FreeType_CFLAGS = -Iupstream/build/freetype/include
+FreeType_LDFLAGS = -Lupstream/build/freetype/objs -lfreetype
+
+FreeTypeDemoHelper_CFLAGS = $(FreeType_CFLAGS)
+FreeTypeDemoHelper_LDFLAGS = $(FreeType_LDFLAGS)
+build/tests/FreeTypeDemoHelper.o: $(mips_objects) $(tasks)/build_freetype
+build/tests/FreeTypeDemoHelper.mips:
+build/tests/FreeTypeDemo.class: build/tests/FreeTypeDemoHelper.class
+
+FTBench_CFLAGS = $(FreeType_CFLAGS)
+FTBench_LDFLAGS = $(FreeType_LDFLAGS)
+build/tests/FTBench.o: $(tasks)/build_freetype
+
+#
+# MSPack Stuff
+#
+MSPackHelper_CFLAGS = -Iupstream/build/libmspack/mspack
+MSPackHelper_LDFLAGS = -Lupstream/build/libmspack/mspack -lmspack
+build/tests/MSPackHelper.o: $(mips_objects) $(tasks)/build_libmspack
+build/tests/MSPack.class: build/tests/MSPackHelper.class
+
+MSPackBench_CFLAGS = -Iupstream/build/libmspack/mspack
+MSPackBench_LDFLAGS = -Lupstream/build/libmspack/mspack -lmspack
+build/tests/MSPackBench.o: $(tasks)/build_libmspack
+
+#
+# Echo
+#
+build/tests/Echo.class: build/tests/EchoHelper.class
+
+#
+# Libjpeg
+#
+DJpeg_COMPILERFLAGS = -o onepage,pagesize=8m
+build/tests/DJpeg.mips: $(mips_objects) $(tasks)/build_libjpeg
+ @mkdir -p `dirname $@`
+ cp upstream/build/libjpeg/djpeg $@
+
+#
+# Busybox
+#
+BusyBox_COMPILERFLAGS = -o unixruntime
+build/tests/BusyBox.mips: $(mips_object) $(tasks)/build_busybox
+ @mkdir -p `dirname $@`
+ cp upstream/build/busybox/busybox $@
+
+busyboxtest: build/tests/BusyBox.class
+ $(JAVA) -cp build tests.BusyBox ash
+
+#
+# Boehm GC
+#
+build/tests/GCTest.mips: $(mips_objects) $(tasks)/build_boehmgc
+ @mkdir -p `dirname $@`
+ cp upstream/build/boehmgc/gctest $@
+
+boehmgctest: build/tests/Env.class build/tests/GCTest.class
+ $(JAVA) -cp build tests.Env GC_PRINT_STATS=1 tests.GCTest
+
+
+#
+# Speed tests
+#
+
+build/tests/SpeedTest.class: build/org/xwt/mips/Runtime.class
+
+tmp/thebride_1280.jpg:
+ @mkdir -p tmp
+ cd tmp && wget http://www.kill-bill.com/images/wallpaper/thebride_1280.jpg
+
+oldspeedtest: build/tests/DJpeg.class tmp/thebride_1280.jpg
+ bash -c "time $(JAVA) -cp build tests.DJpeg -targa -outfile tmp/thebride_1280.tga tmp/thebride_1280.jpg"
+ @echo "e90f6b915aee2fc0d2eb9fc60ace6203 tmp/thebride_1280.tga" | md5sum -c && echo "MD5 is OK"
+
+djpegspeedtest: build/tests/SpeedTest.class build/tests/DJpeg.class tmp/thebride_1280.jpg
+ @echo "Running DJpeg test..."
+ @$(JAVA) -cp build tests.SpeedTest tests.DJpeg 8 -targa -outfile tmp/thebride_1280.tga tmp/thebride_1280.jpg
+
+mspackspeedtest: build/tests/SpeedTest.class build/tests/MSPackBench.class
+ @if [ -e tmp/mspack/comic32.exe ]; then \
+ echo "Running MSPackBench test..."; \
+ cd tmp/mspack && $(JAVA) -cp ../../build tests.SpeedTest tests.MSPackBench 20 *32.exe; \
+ else \
+ echo "Run \"make check\" to get the MS True Type fonts for the MSPackBench test"; \
+ fi
+
+speedtest: build/tests/SpeedTest.class build/tests/DJpeg.class build/tests/FTBench.class tmp/thebride_1280.jpg build/tests/MSPackBench.class
+ @echo "Running DJpeg test..."
+ @$(JAVA) -cp build tests.SpeedTest tests.DJpeg 10 -targa -outfile tmp/thebride_1280.tga tmp/thebride_1280.jpg
+ @if [ -e tmp/mspack/Comic.TTF ]; then \
+ echo "Running FTBench test..."; \
+ $(JAVA) -cp build tests.SpeedTest tests.FTBench 10 tmp/mspack/Comic.TTF tmp/mspack/Comic.TTF.render; \
+ else \
+ echo "Run \"make check\" to get Arial.TTF for the FTBench test"; \
+ fi
+ @if false && [ -e tmp/mspack/comic32.exe ]; then \
+ echo "Running MSPackBench test..."; \
+ cd tmp/mspack && $(JAVA) -cp ../../build tests.SpeedTest tests.MSPackBench 10 *32.exe; \
+ else \
+ echo "Run \"make check\" to get the MS True Type fonts for the MSPackBench test"; \
+ fi
+
+intspeed: build/tests/DJpeg.mips build/org/xwt/mips/Interpreter.class tmp/thebride_1280.jpg
+ time $(JAVA) -cp build org.xwt.mips.Interpreter build/tests/DJpeg.mips -targa -outfile tmp/thebride_1280.tga tmp/thebride_1280.jpg
+ @echo "e90f6b915aee2fc0d2eb9fc60ace6203 tmp/thebride_1280.tga" | md5sum -c && echo "MD5 is OK"
+
+#
+# Verification checks
+#
+
+check: $(patsubst %,build/tests/%.class, FTBench MSPackBench DJpeg GCTest) tmp/thebride_1280.jpg
+ @/bin/bash ./src/tests/check.sh running_from_make
+
+compiletests: $(patsubst %,build/tests/%.class,FTBench MSPackBench DJpeg Test FreeTypeDemoHelper MSPackHelper EchoHelper BusyBox GCTest Fork)
+ @true
+
+
+# IVME Paper
+doc/nestedvm.ivme04.pdf: doc/nestedvm.ivme04.tex doc/acmconf.cls
+ cd doc; pdflatex nestedvm.ivme04.tex && ./pst2pdf && pdflatex nestedvm.ivme04.tex
+
+pdf: doc/nestedvm.ivme04.pdf
+ open doc/nestedvm.ivme04.pdf
--- /dev/null
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+\f
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+\f
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+\f
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+\f
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+\f
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+\f
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+\f
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+\f
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+\f
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
+
+
--- /dev/null
+January 11, 2003
+ * [brian] Added Unistd.h as an interface so we can use its constants in
+ Runtime
+ * [brian] -o lessconstants option to compiler to emit all constants as
+ an addition of a field value and a small constant. This
+ prevents the classfile constant pool from overflowing on large
+ applications. This has a small performance impact.
+ * [brian] Added stubs for the rmdir syscall and a minimal implementation
+ of sysconf
+ * [brian] Emit data segments as a series of <32k strings to avoid
+ hitting classfile limits
+January 10, 2003
+ * [brian] The compiler now outputs data segments as Strings rather than
+ huge int arrays.
+ * [brian] Cleaned up Makefile and upstream/Makefile to separate the
+ required mips2java stuff from the tests. Ideally the tests
+ should be completelly separate from the main makefile but
+ keeping them integrated allows for better dependency checking
+ and faster builds.
+January 8, 2003
+ * Much thanks goes to Mohan Embar for discovering and fixing most
+ of the issues below.
+ * [brian] Updated Makefile to allow bulding with gcj
+ (make JAVAC="gcj -C" JAVA="gij")
+ * [brian] Updated Runtime.java to silently ignore SecurityExceptions
+ thrown from System.getProperty()
+ * [brian] Compiler now uses a PrintWriter for output rather than
+ PrintStream and properly closes the file on exit
+ * [brian] Made the htojava script a bourne shell script rather than a
+ perl script to remove the dependency on perl.
+December 29, 2003
+ * [brian] Changed build process to use -ffunction-sections,
+ -fdata-sections, and --gc-sections
+ * [brian] Update support.s to use function sections
+ * [brian] Make the interpreter report the pc/sourceline of
+ exceptions.
+ * [brian] Remove stdio calls from FreeTypeHelper
+ * [brian] Added gcc patch to fix -fdata-sections bug
+ * [brian] Added freetype patch to avoid stdio
+December 2, 2003
+ * [brian] Cleaned up a bunch of //FEATUREs and //FIXMEs. No major
+ changes, just cleanup.
+November 30, 2003
+ * [brian] Added crude support for O_APPEND and O_TRUNC
+
+November 29, 2003
+ * [brian] Moved all sources under org/xwt/mips - modified Makefiles
+ accordingly.
+ * [brian] Added org.xwt.mips.util tree containing SeekableData,
+ SeekableByteArray, SeekableFile, and SeekableInputStream.
+ * [brian] Made ELF.java use SeekableData rather than RandomAccessFile
+ * [brian] Made Runtime.java use org.xwt.mips.util.Seekable* for most
+ file operations.
+ * [brian] Added construtors to Interpreter.java that accept an InputStream
+ or SeekableData.
+ * [brian] Added support for the /dev/fd/n namespace and /dev/{null,zero}
+ * [brian] Added test/FDTest.java example and updated tests/Test.c
+ * [brian] Fixed absolute pathame bug on Win32
+
\ No newline at end of file
--- /dev/null
+% ACMCONF DOCUMENT CLASS
+% adapted from ARTICLE document style by Ken Traub
+% Hacked for [preprint] option by Olin Shivers 4/91
+% Fixed up for LaTeX version 2e [compatibility mode] by Peter Lee 10/9
+% (with help from Simon Peyton Jones)
+% Converted to a LaTeX2e document class by David A. Berson 11/94
+%
+% ARTICLE DOCUMENT STYLE -- Released 16 March 1988
+% for LaTeX version 2.09
+% Copyright (C) 1988 by Leslie Lamport
+
+% To do:
+% - Possibly move the commands related to 9pt size to a file size9.clo
+% and write the stuff to unpack both acmconf.cls and size9.clo files
+% from a single distribution file.
+
+%%% ACMCONF is a document class for producing two-column camera-ready pages for
+%%% ACM conferences, according to ACM specifications. The main features of
+%%% this class are:
+%%%
+%%% 1) Two columns.
+%%% 2) Side and top margins of 4.5pc, bottom margin of 7.5pc, column gutter of
+%%% 2pc, hence columns are 20pc wide and 54pc tall. (6pc = 1in, approx)
+%%% 3) First page has title information, and an extra 4.5pc of space at the
+%%% bottom of the first column for the ACM copyright notice. (You must
+%%% use one of the commands \copyrightspace or \toappear{} to obtain this
+%%% space.)
+%%% 4) Text is 9pt on 10pt baselines; titles are 9pt bold sans-serif.
+%%% (The acmconf.sty from which acmconf.cls was derived actually uses
+%%% 9pt bold roman for section titles. Functionally, I have left this
+%%% as is. I have added a commented out alternate defination of
+%%% \acmtitlestyle that uses sans-serif) --DAB
+%%%
+%%% This document class supports a [preprint] class option that allows you
+%%% to run off a copy for a preprint -- with page numbers, "to appear"
+%%% information, and so forth. This is documented below.
+
+%%% There are a few restrictions you must observe:
+%%%
+%%% 1) You cannot change the font size; ACM wants you to use 9pt.
+%%% 3) You must start your paper with the \maketitle command. Prior to the
+%%% \maketitle you must have \title and \author commands. If you have a
+%%% \date command it will be ignored; no date appears on the paper, since
+%%% the proceedings will have a date on the front cover.
+%%% Optionally, you may have an \affiliation command with text, such
+%%% as company or university name and address, that will be centered
+%%% just below the author(s).
+%%% 4) Marginal paragraphs, tables of contents, lists of figures and tables,
+%%% and page headings are all forbidden.
+%%% 5) The `figure' environment will produce a figure one column wide; if you
+%%% want one that is two columns wide, use `figure*'. Ditto for the
+%%% `table' and `table*' environments.
+%%%
+%%% Page Headings:
+%%% Normally, \pagestyle commands are ignored --- pages have no headings or
+%%% numbers. ACM will number the pages for you when they are inserted into the
+%%% proceedings (you should put page numbers on the BACK of each page, though,
+%%% in case someone drops your paper on the floor).
+%%%
+%%% If the [preprint] option is present, then \pagestyle commands are obeyed,
+%%% and the default is \pagestyle{plain}. The [twoside] option is also
+%%% useful when using headers.
+%%%
+%%% The [draft] and [final] options as used in the article class are also
+%%% supported.
+%%%
+%%%
+%%% Copyright Space:
+%%% You leave space at the bottom of page 1/column 1 one with the
+%%% \copyrightspace command. Alternatively, you can use the
+%%% \toappear{...} command. Normally, this turns into an unnumbered
+%%% footnote 4.5pc high. If [preprint] is on, then this space is
+%%% filled with the {...} text; otherwise, it's blank. You must put
+%%% one of these commands in the text of page 1/column 1 *after* all the
+%%% other footnotes that go on page1/column 1, of course.
+%%%
+%%% A typical usage looks like this:
+%%% \toappear{To appear in the Ninth AES Conference on Midevil Lithuanian
+%%% Embalming Technique, June 1991, Alfaretta, Georgia.
+%%% Also available as Technical Report CMU-CS-91-119,
+%%% Cranberry Melon School of Cucumber Science.}
+%%% This will be included in the preprint, and left out of the conference
+%%% version.
+%%%
+%%% Acmconf defines two useful conditionals.
+%%% - \ifacmconf{true-stuff}{false-stuff}
+%%% expands to true-stuff.
+%%% - \ifpreprint true-stuff \else else-stuff \fi
+%%% expands to true-stuff if the [preprint] option is being used,
+%%% otherwise it expands to else-stuff.
+%%% \ifacmconf is a latex command; \ifpreprint is a real latex conditional.
+%%%
+%%% WARNING:
+%%% Some dvi-ps converters heuristically allow chars to drift from their
+%%% true positions a few pixels. This loses noticeably with the 9pt sans-serif
+%%% bold font used for section headers. You turn this hackery off in our
+%%% dvi-ps converters with the -e option:
+%%% dvips -e 0 foo.dvi >foo.ps
+
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesClass{acmconf}[1994/11/27 Alternative LaTeX document class]
+\typeout{Bugs to berson@cs.pitt.edu}
+
+%
+% Define the conditionals and command for the options.
+%
+\newif\if@acmconf\@acmconftrue
+\long\def\ifacmconf#1#2{\if@acmconf#1\else#2\fi}
+\newif\ifpreprint
+
+%
+% Declare and process the options
+%
+\DeclareOption{draft}{\PassOptionsToClass{draft}{article}}
+\DeclareOption{final}{\PassOptionsToClass{final}{article}}
+\DeclareOption{twocolumn}{\PassOptionsToClass{twocolumn}{article}}
+\DeclareOption{twoside}{\PassOptionsToClass{twoside}{article}}
+\DeclareOption{preprint}{\preprintfalse}
+%\DeclareOption{preprint}{\preprinttrue}
+%
+% Let them off with just a warning for any other option
+%
+\DeclareOption*{\ClassWarningNoLine{acmconf}{Unknown option `\CurrentOption'}}
+%\DeclareOption*{\ClassError{acmconf}
+% {The `\CurrentOption' option is not supported}
+% {Remove the `\CurrentOption' option from the
+% \protect\documentclass\space line.}}
+
+\ExecuteOptions{twocolumn}
+\ProcessOptions
+
+%
+% This class simply modifies a few behaviors of the article class,
+% so load it now
+%
+\LoadClass{article}
+
+
+%**********************************************************************
+%
+% The following commands would normally be in a file such as
+% size9.clo for the article class. Since the size isn't really an
+% option, I include them here. I have followed the order of the commands
+% as found in size10.clo.
+%
+% I could test for the presence of % the file size9.clo and load it when
+% availale, instead of executing these commands.
+%
+
+%
+% Set the font sizes and spacing
+%
+\renewcommand\baselinestretch{1}
+
+\renewcommand\normalsize{%
+ \@setfontsize\normalsize\@ixpt\@xpt
+ \abovedisplayskip 9\p@ \@plus2\p@ \@minus4.5\p@%
+ \abovedisplayshortskip \z@ \@plus3\p@%
+ \belowdisplayshortskip 5.4\p@ \@plus3\p@ \@minus3\p@%
+ \belowdisplayskip \abovedisplayskip
+ \let\@listi\@listI}
+\normalsize
+\renewcommand\small{%
+ \@setfontsize\small\@viiipt{9}%
+ \abovedisplayskip 7.6\p@ \@plus 3\p@ \@minus 4\p@%
+ \abovedisplayshortskip \z@ \@plus2\p@%
+ \belowdisplayshortskip 3.6\p@ \@plus2\p@ \@minus 2\p@
+ \def\@listi{\leftmargin\leftmargini
+ \topsep 4\p@ \@plus 2\p@ \@minus 2\p@
+ \parsep 2\p@ \@plus 1\p@ \@minus 1\p@
+ \itemsep \parsep}
+ \belowdisplayskip \abovedisplayskip
+}
+\renewcommand\footnotesize{%
+ \@setfontsize\footnotesize\@viipt{8}
+ \abovedisplayskip 6.4\p@ \@plus 2\p@ \@minus 4\p@%
+ \abovedisplayshortskip \z@ \@plus 1\p@%
+ \belowdisplayshortskip 2.7\p@ \@plus 1\p@ \@minus 2\p@
+ \def\@listi{\leftmargin\leftmargini
+ \topsep 3\p@ \@plus 1\p@ \@minus 1\p@
+ \parsep 2\p@ \@plus 1\p@ \@minus 1\p@
+ \itemsep \parsep}%
+ \belowdisplayskip \abovedisplayskip
+}
+\renewcommand\scriptsize{\@setfontsize\scriptsize\@viipt{8pt}}
+\renewcommand\tiny{\@setfontsize\tiny\@vpt{6pt}}
+\renewcommand\large{\@setfontsize\large\@xipt{13.6\p@}}
+\renewcommand\Large{\@setfontsize\Large\@xiipt{14\p@}}
+\renewcommand\LARGE{\@setfontsize\LARGE\@xivpt{18\p@}}
+\renewcommand\huge{\@setfontsize\huge\@xviipt{22\p@}}
+\renewcommand\Huge{\@setfontsize\Huge\@xxpt{25\p@}}
+
+\setlength\parindent{13.5\p@} % This is what normally used for one
+ % column. Should it be 1em for us?
+\setlength\headheight{0\p@}
+\setlength\headsep{0\p@}
+\setlength\headheight{0\p@}
+\setlength\headsep{0\p@}
+\setlength\footskip{30\p@}
+%
+% There was no \topskip or \@maxdepth in the original acmconf.sty.
+% Thus, we inherit
+%\topskip 10pt
+%\maxdepth .5\topskip
+% from size10.clo loaded via article.cls
+%
+\setlength\textwidth{39pc}
+\setlength\textheight{650\p@}
+\setlength\oddsidemargin{5.5pc}
+\addtolength\oddsidemargin{-1in} % Correct for LaTeX gratuittousness
+\setlength\evensidemargin{5.5pc}
+\addtolength\evensidemargin{-1in} % Correct for LaTeX gratuittousness
+\setlength\marginparwidth{0\p@} % Margin pars are not allowed.
+\setlength\marginparsep{11\p@}
+\setlength\marginparpush{5\p@}
+\setlength\topmargin{5.5pc}
+\addtolength\topmargin{-1in} % Correct for LaTeX gratuitousness
+%
+% I wonder if these next three lines should only be executed if
+% the preprint option is in effect? -- DAB
+%
+%% Must redefine the top margin so there's room for headers and
+%% page numbers if you are using the preprint option. Footers
+%% are OK as is. Olin.
+\addtolength\topmargin{-37\p@} % Leave 37pt above text for headers
+\setlength\headheight{12\p@}
+\setlength\headsep{25\p@}
+
+\setlength\footnotesep{5.6\p@}
+\setlength{\skip\footins}{8.1\p@ \@plus 4\p@ \@minus 2\p@}
+\setlength\floatsep{11\p@ \@plus 2\p@ \@minus 2\p@}
+\setlength\textfloatsep{18\p@ \@plus 2\p@ \@minus 4\p@}
+\setlength\intextsep{11\p@ \@plus 2\p@ \@minus 2\p@}
+\setlength\dblfloatsep{11\p@ \@plus 2\p@ \@minus 2\p@}
+\setlength\dbltextfloatsep{18\p@ \@plus 2\p@ \@minus 4\p@}
+%
+% These values will be inherited from the default size10.clo file
+% included when we load the base article class. I include them
+% here for completeness in case we split out the size9.clo file someday.
+% --DAB
+\setlength\@fptop{0\p@ \@plus 1fil}
+\setlength\@fpsep{8\p@ \@plus 2fil}
+\setlength\@fpbot{0\p@ \@plus 1fil}
+\setlength\@dblfptop{0\p@ \@plus 1fil}
+\setlength\@dblfpsep{8\p@ \@plus 2fil}
+\setlength\@dblfpbot{0\p@ \@plus 1fil}
+\setlength\partopsep{2\p@ \@plus 1\p@ \@minus 1\p@}
+%
+% I think that all of these should be renewcommands. I also think
+% that \setlength should be used. But, they are not in the size10.clo
+% file that I am following. --DAB
+%
+\renewcommand\@listI{\leftmargin\leftmargini
+ \parsep 3.6\p@ \@plus 2\p@ \@minus 1\p@%
+ \topsep 7.2\p@ \@plus 2\p@ \@minus 4\p@%
+ \itemsep 3.6\p@ \@plus 2\p@ \@minus 1\p@}
+\let\@listi\@listI
+\@listi
+\def\@listii {\leftmargin\leftmarginii
+ \labelwidth\leftmarginii
+ \advance\labelwidth-\labelsep
+ \topsep 3.6\p@ \@plus 2\p@ \@minus 1\p@
+ \parsep 1.8\p@ \@plus 0.9\p@ \@minus 0.9\p@
+ \itemsep \parsep}
+\def\@listiii{\leftmargin\leftmarginiii
+ \labelwidth\leftmarginiii
+ \advance\labelwidth-\labelsep
+ \topsep 1.8\p@ plus 0.9\p@ minus 0.9\p@
+ \parsep \z@
+ \partopsep 1\p@ plus 0\p@ minus 1\p@
+ \itemsep \topsep}
+\def\@listiv {\leftmargin\leftmarginiv
+ \labelwidth\leftmarginiv
+ \advance\labelwidth-\labelsep}
+\def\@listv {\leftmargin\leftmarginv
+ \labelwidth\leftmarginv
+ \advance\labelwidth-\labelsep}
+\def\@listvi {\leftmargin\leftmarginvi
+ \labelwidth\leftmarginvi
+ \advance\labelwidth-\labelsep}
+%
+% End of the "size9.clo" commands
+%**********************************************************************
+
+%
+% here's a few things that I didn't find in either article.cls or
+% size10.clo, so I left them here. --DAB
+%
+\setlength\columnsep{3pc} % Space between columns
+\setlength\columnseprule{0\p@} % Width of rule between columns.
+\hfuzz 1pt % Allow some variation in column width, otherwise it's
+ % too hard to typeset in narrow columns.
+
+
+%**********************************************************************
+%
+% Now we get on with overriding things found in article.cls
+%
+\setlength\parindent{13.5\p@}
+
+%
+% This command is used to format section headings. The format is the only
+% thing that differs between these section commands and the ones in
+% article.cls.
+%
+% Although the original documentation says that sans-serif is supposed to be
+% used for section titles, the file as I received uses roman. The
+% commented out line implements sans-serif. Be sure to comment out the
+% \bfseries line if you switch.
+% --DAB
+%
+\newcommand\@acmtitlestyle{\normalsize\sffamily\bfseries}
+%\newcommand\@acmtitlestyle{\normalsize\sffamily}
+
+\renewcommand\section{\@startsection {section}{1}{\z@}%
+ {-3.5ex \@plus -1ex \@minus -.2ex}%
+ {2.3ex \@plus .2ex}%
+ {\@acmtitlestyle}}
+\renewcommand\subsection{\@startsection{subsection}{2}{\z@}%
+ {-3.25ex \@plus -1ex \@minus -.2ex}%
+ {1.5ex \@plus .2ex}%
+ {\@acmtitlestyle}}
+\renewcommand\subsubsection{\@startsection{subsubsection}{3}{\z@}%
+ {-3.25ex \@plus -1ex \@minus -.2ex}%
+ {1.5ex \@plus .2ex}%
+ {\@acmtitlestyle}}
+\renewcommand\paragraph{\@startsection{paragraph}{4}{\z@}%
+ {3.25ex \@plus 1ex \@minus .2ex}%
+ {-1em}%
+ {\@acmtitlestyle}}
+\renewcommand\subparagraph{\@startsection{subparagraph}{4}{\parindent}%
+ {3.25ex \@plus 1ex \@minus .2ex}%
+ {-1em}%
+ {\@acmtitlestyle}}
+
+\setcounter{secnumdepth}{3}
+
+\setlength\arraycolsep{4.5\p@}
+\setlength\tabcolsep{5.4\p@}
+\setlength\doublerulesep{1.8\p@}
+
+\setlength\fboxsep{2.7\p@}
+\setlength\fboxrule{.4\p@}
+
+\def\tableofcontents{\ClassError{acmconf}%
+ {\protect\tableofcontents: Tables of contents are not allowed in the `acmconf' document class}%
+ {Remove the \protect\tableofcontents\space command from the file}}
+
+\def\listoffigures{\ClassError{acmconf}%
+ {\protect\listoffigures: Lists of figures are not allowed in the `acmconf' document class}%
+ {Remove the \protect\listoffigures\space command from the file}}
+
+\def\listoftables{\ClassError{acmconf}%
+ {\protect\listoftables: Lists of tables are not allowed in the `acmconf' document class}%
+ {Remove the \protect\listoftables\space command from the file}}
+\let\l@table\l@figure
+
+%
+% Added \@makefntext definition so that the mark would not over print
+% the beginning of the \thanks text. --DAB
+%
+\def\maketitle{\par
+ \begingroup
+ \def\thefootnote{\fnsymbol{footnote}}%
+ \def\@makefnmark{\hbox to 0pt{$\m@th^{\@thefnmark}$\hss}}%
+ \long\def\@makefntext##1{\parindent 1em\noindent
+ \hbox to1.8em{\hss$\m@th^{\@thefnmark}$}##1}%
+ \if@twocolumn
+ \twocolumn[\@maketitle]
+ \else \newpage
+ \global\@topnum\z@ % Prevents figures from going at top of page.
+ \@maketitle \fi
+ \thispagestyle{plain}\@thanks % UE: Changed {empty} to {plain}
+ \endgroup
+ \setcounter{footnote}{0}
+ \let\maketitle\relax
+ \let\@maketitle\relax
+ \gdef\@thanks{}\gdef\@author{}\gdef\@title{}\gdef\@affili{}\let\thanks\relax}
+
+%
+% extra declarations needed for our version of @maketitle
+%
+\newbox\@acmtitlebox
+\gdef\affili{}
+\def\affiliation#1{\gdef\affili{#1}}
+
+%
+% The modified @maketitle
+%
+\def\@maketitle{\newpage
+ \null
+ \setbox\@acmtitlebox\vbox{%
+ \vskip 2em % Vertical space above title.
+ \begin{center}
+ {\LARGE \@title \par} % Title set in \LARGE size.
+ \vskip 1.5em % Vertical space after title.
+ {\large % each author set in \large, in a
+ \lineskip .5em % tabular environment
+ \begin{tabular}[t]{c}\@author
+ \end{tabular}\par}
+ \vskip 1em
+ \begin{center}
+ {\large \affili}
+ \end{center}
+ \vskip 1.5em % Vertical space after author.
+ \end{center}}
+ \dimen0=\ht\@acmtitlebox
+ \advance\dimen0 by -13.5pc\relax
+ \unvbox\@acmtitlebox
+ \ifdim\dimen0<0.0pt\relax\vskip-\dimen0\fi}
+
+\long\def\unmarkedfootnote#1{{\long\def\@makefntext##1{##1}\footnotetext{#1}}}
+
+%% Use one of \copyrightspace or \toappear{To appear in the ACM ...}
+\def\copyrightspace{\unmarkedfootnote{\vrule height 4.5pc
+ width 0in depth 0in}}
+
+%% \small is bigger than \footnotesize.
+\def\toappear#1%
+ {\ifpreprint \unmarkedfootnote{\vrule height 2.25pc%
+ depth 2.25pc width 0in%
+ \parbox{2.8in}{\small #1}}%
+ \else \copyrightspace \fi}
+
+\def\marginpar{\ClassError{acmconf}%
+ {The \protect\marginpar command is not allowed in the `acmconf' document class}%
+ {Remove the \protect\marginpar\space command from the file}}
+
+\mark{{}{}} % Initializes TeX's marks
+
+%% Headings are ignored unless the [preprint] option is in force.
+\ifpreprint\else % preprint off -- all \pagestyle commands ==> \pagestyle{empty}.
+% \let\ps@plain\ps@empty % UE: Commented this line out
+ \let\ps@headings\ps@empty
+ \let\ps@myheadings\ps@empty
+\fi
+
+\raggedbottom % Ragged bottom
+
+\endinput
+%%
+%% End of file `acmconf.cls'.
--- /dev/null
+%PDF-1.3\r%âãÏÓ\r
+4 0 obj<</Contents 80 0 R/Type/Page/Parent 5 0 R/MediaBox[0.0 0.0 520.0 300.11914]/BleedBox[0.0 0.0 520.0 300.0]/TrimBox[0.0 0.0 520.0 300.0]/ArtBox[0.88965 0.60059 519.97266 300.11914]/Resources<</ExtGState<</GS0 24 0 R>>/Properties<</MC0<</Color[20224.0 32768.0 32768.0]/Title(Layer 1)/Visible true/Preview true/Editable true/Printed true/Dimmed true>>>>>>>>\rendobj\r5 0 obj<</Count 1/Kids[4 0 R]/Type/Pages>>\rendobj\r19 0 obj<</Pages 5 0 R/Type/Catalog/Metadata 81 0 R>>\rendobj\r20 0 obj<</ModDate(D:20040320030520-08'00')/CreationDate(D:20040320030043-08'00')/Creator(Excel)/Producer(Mac OS X 10.3.3 Quartz PDFContext)>>\rendobj\r22 0 obj null\rendobj\r24 0 obj<</Type/ExtGState/SA true/OP false/op false/OPM 0/ca 1.0/CA 1.0/BM/Normal/SMask/None/AIS false>>\rendobj\r79 0 obj 178184\rendobj\r80 0 obj<</Length 79 0 R>>stream\r
+/Layer /MC0 BDC \rq\r1 0 0 -1 0 0 cm\r1 -0.71973 m\r1 -0.71973 519.86133 -0.71973 519.86133 -0.71973 c\r519.86133 -0.71973 519.86133 -300 519.86133 -300 c\r519.86133 -300 1 -300 1 -300 c\r1 -300 1 -0.71973 1 -0.71973 c\rh\rW n\r1 1 1 rg\r0 i \r/GS0 gs\r1.38965 -299.61914 m\r1.38965 -299.61914 519.47266 -299.61914 519.47266 -299.61914 c\r519.47266 -299.61914 519.47266 -1.10059 519.47266 -1.10059 c\r519.47266 -1.10059 1.38965 -1.10059 1.38965 -1.10059 c\r1.38965 -1.10059 1.38965 -299.61914 1.38965 -299.61914 c\rh\rf\r0 0 0 RG\r1 w 10 M 0 j 0 J []0 d \r1.38965 -299.61914 m\r1.38965 -299.61914 519.47266 -299.61914 519.47266 -299.61914 c\r519.47266 -299.61914 519.47266 -1.10059 519.47266 -1.10059 c\r519.47266 -1.10059 1.38965 -1.10059 1.38965 -1.10059 c\r1.38965 -1.10059 1.38965 -299.61914 1.38965 -299.61914 c\rh\rS\r0.75294 0.75294 0.75294 rg\r43.65576 -245.04297 m\r43.65576 -245.04297 442.20117 -245.04297 442.20117 -245.04297 c\r442.20117 -245.04297 442.20117 -48.82324 442.20117 -48.82324 c\r442.20117 -48.82324 43.65576 -48.82324 43.65576 -48.82324 c\r43.65576 -48.82324 43.65576 -245.04297 43.65576 -245.04297 c\rf\rQ\rq\r1 0 0 -1 0 0 cm\r43.52539 -47.93457 m\r43.52539 -47.93457 442.07129 -47.93457 442.07129 -47.93457 c\r442.07129 -47.93457 442.07129 -246.18555 442.07129 -246.18555 c\r442.07129 -246.18555 43.52539 -246.18555 43.52539 -246.18555 c\r43.52539 -246.18555 43.52539 -47.93457 43.52539 -47.93457 c\rh\rW n\r0 0 0 RG\r0 i 1 w 10 M 0 j 0 J []0 d \r/GS0 gs\r43.65576 -81.56738 m\r43.65576 -81.56738 442.20117 -81.56738 442.20117 -81.56738 c\rS\rQ\rq\r1 0 0 -1 0 0 cm\r43.52539 -47.93457 m\r43.52539 -47.93457 442.07129 -47.93457 442.07129 -47.93457 c\r442.07129 -47.93457 442.07129 -246.18555 442.07129 -246.18555 c\r442.07129 -246.18555 43.52539 -246.18555 43.52539 -246.18555 c\r43.52539 -246.18555 43.52539 -47.93457 43.52539 -47.93457 c\rh\rW n\r0 0 0 RG\r0 i 1 w 10 M 0 j 0 J []0 d \r/GS0 gs\r43.65576 -114.31348 m\r43.65576 -114.31348 442.20117 -114.31348 442.20117 -114.31348 c\rS\rQ\rq\r1 0 0 -1 0 0 cm\r43.52539 -47.93457 m\r43.52539 -47.93457 442.07129 -47.93457 442.07129 -47.93457 c\r442.07129 -47.93457 442.07129 -246.18555 442.07129 -246.18555 c\r442.07129 -246.18555 43.52539 -246.18555 43.52539 -246.18555 c\r43.52539 -246.18555 43.52539 -47.93457 43.52539 -47.93457 c\rh\rW n\r0 0 0 RG\r0 i 1 w 10 M 0 j 0 J []0 d \r/GS0 gs\r43.65576 -146.80566 m\r43.65576 -146.80566 442.20117 -146.80566 442.20117 -146.80566 c\rS\rQ\rq\r1 0 0 -1 0 0 cm\r43.52539 -47.93457 m\r43.52539 -47.93457 442.07129 -47.93457 442.07129 -47.93457 c\r442.07129 -47.93457 442.07129 -246.18555 442.07129 -246.18555 c\r442.07129 -246.18555 43.52539 -246.18555 43.52539 -246.18555 c\r43.52539 -246.18555 43.52539 -47.93457 43.52539 -47.93457 c\rh\rW n\r0 0 0 RG\r0 i 1 w 10 M 0 j 0 J []0 d \r/GS0 gs\r43.65576 -179.55176 m\r43.65576 -179.55176 442.20117 -179.55176 442.20117 -179.55176 c\rS\rQ\rq\r1 0 0 -1 0 0 cm\r43.52539 -47.93457 m\r43.52539 -47.93457 442.07129 -47.93457 442.07129 -47.93457 c\r442.07129 -47.93457 442.07129 -246.18555 442.07129 -246.18555 c\r442.07129 -246.18555 43.52539 -246.18555 43.52539 -246.18555 c\r43.52539 -246.18555 43.52539 -47.93457 43.52539 -47.93457 c\rh\rW n\r0 0 0 RG\r0 i 1 w 10 M 0 j 0 J []0 d \r/GS0 gs\r43.65576 -212.29736 m\r43.65576 -212.29736 442.20117 -212.29736 442.20117 -212.29736 c\rS\rQ\rq\r1 0 0 -1 0 0 cm\r43.52539 -47.93457 m\r43.52539 -47.93457 442.07129 -47.93457 442.07129 -47.93457 c\r442.07129 -47.93457 442.07129 -246.18555 442.07129 -246.18555 c\r442.07129 -246.18555 43.52539 -246.18555 43.52539 -246.18555 c\r43.52539 -246.18555 43.52539 -47.93457 43.52539 -47.93457 c\rh\rW n\r0 0 0 RG\r0 i 1 w 10 M 0 j 0 J []0 d \r/GS0 gs\r43.65576 -245.04297 m\r43.65576 -245.04297 442.20117 -245.04297 442.20117 -245.04297 c\rS\rQ\rq\r1 0 0 -1 0 0 cm\r1 -0.71973 m\r1 -0.71973 519.86133 -0.71973 519.86133 -0.71973 c\r519.86133 -0.71973 519.86133 -300 519.86133 -300 c\r519.86133 -300 1 -300 1 -300 c\r1 -300 1 -0.71973 1 -0.71973 c\rh\rW n\r0.50197 0.50197 0.50197 RG\r0 i 4 w 10 M 0 j 0 J []0 d \r/GS0 gs\r43.65576 -245.04297 m\r43.65576 -245.04297 442.20117 -245.04297 442.20117 -245.04297 c\r442.20117 -245.04297 442.20117 -48.82324 442.20117 -48.82324 c\r442.20117 -48.82324 43.65576 -48.82324 43.65576 -48.82324 c\r43.65576 -48.82324 43.65576 -245.04297 43.65576 -245.04297 c\rh\rS\rQ\rq\r1 0 0 -1 0 0 cm\r43.52539 -48.94922 m\r43.52539 -48.94922 442.33105 -48.94922 442.33105 -48.94922 c\r442.33105 -48.94922 442.33105 -245.16992 442.33105 -245.16992 c\r442.33105 -245.16992 43.52539 -245.16992 43.52539 -245.16992 c\r43.52539 -245.16992 43.52539 -48.94922 43.52539 -48.94922 c\rh\rW n\r0.60001 0.60001 1 rg\r0 i \r/GS0 gs\r60.25049 -134.11426 m\r60.25049 -134.11426 82.03125 -134.11426 82.03125 -134.11426 c\r82.03125 -134.11426 82.03125 -48.82324 82.03125 -48.82324 c\r82.03125 -48.82324 60.25049 -48.82324 60.25049 -48.82324 c\r60.25049 -48.82324 60.25049 -134.11426 60.25049 -134.11426 c\rh\rf\r0 0 0 RG\r4 w 10 M 0 j 0 J []0 d \r60.25049 -134.11426 m\r60.25049 -134.11426 82.03125 -134.11426 82.03125 -134.11426 c\r82.03125 -134.11426 82.03125 -48.82324 82.03125 -48.82324 c\r82.03125 -48.82324 60.25049 -48.82324 60.25049 -48.82324 c\r60.25049 -48.82324 60.25049 -134.11426 60.25049 -134.11426 c\rh\rS\rQ\rq\r1 0 0 -1 0 0 cm\r43.52539 -48.94922 m\r43.52539 -48.94922 442.33105 -48.94922 442.33105 -48.94922 c\r442.33105 -48.94922 442.33105 -245.16992 442.33105 -245.16992 c\r442.33105 -245.16992 43.52539 -245.16992 43.52539 -245.16992 c\r43.52539 -245.16992 43.52539 -48.94922 43.52539 -48.94922 c\rh\rW n\r0.60001 0.60001 1 rg\r0 i \r/GS0 gs\r159.82178 -130.81348 m\r159.82178 -130.81348 181.86279 -130.81348 181.86279 -130.81348 c\r181.86279 -130.81348 181.86279 -48.82324 181.86279 -48.82324 c\r181.86279 -48.82324 159.82178 -48.82324 159.82178 -48.82324 c\r159.82178 -48.82324 159.82178 -130.81348 159.82178 -130.81348 c\rh\rf\r0 0 0 RG\r4 w 10 M 0 j 0 J []0 d \r159.82178 -130.81348 m\r159.82178 -130.81348 181.86279 -130.81348 181.86279 -130.81348 c\r181.86279 -130.81348 181.86279 -48.82324 181.86279 -48.82324 c\r181.86279 -48.82324 159.82178 -48.82324 159.82178 -48.82324 c\r159.82178 -48.82324 159.82178 -130.81348 159.82178 -130.81348 c\rh\rS\rQ\rq\r1 0 0 -1 0 0 cm\r43.52539 -48.94922 m\r43.52539 -48.94922 442.33105 -48.94922 442.33105 -48.94922 c\r442.33105 -48.94922 442.33105 -245.16992 442.33105 -245.16992 c\r442.33105 -245.16992 43.52539 -245.16992 43.52539 -245.16992 c\r43.52539 -245.16992 43.52539 -48.94922 43.52539 -48.94922 c\rh\rW n\r0.60001 0.60001 1 rg\r0 i \r/GS0 gs\r259.65332 -137.66699 m\r259.65332 -137.66699 281.43457 -137.66699 281.43457 -137.66699 c\r281.43457 -137.66699 281.43457 -48.82324 281.43457 -48.82324 c\r281.43457 -48.82324 259.65332 -48.82324 259.65332 -48.82324 c\r259.65332 -48.82324 259.65332 -137.66699 259.65332 -137.66699 c\rh\rf\r0 0 0 RG\r4 w 10 M 0 j 0 J []0 d \r259.65332 -137.66699 m\r259.65332 -137.66699 281.43457 -137.66699 281.43457 -137.66699 c\r281.43457 -137.66699 281.43457 -48.82324 281.43457 -48.82324 c\r281.43457 -48.82324 259.65332 -48.82324 259.65332 -48.82324 c\r259.65332 -48.82324 259.65332 -137.66699 259.65332 -137.66699 c\rh\rS\rQ\rq\r1 0 0 -1 0 0 cm\r43.52539 -48.94922 m\r43.52539 -48.94922 442.33105 -48.94922 442.33105 -48.94922 c\r442.33105 -48.94922 442.33105 -245.16992 442.33105 -245.16992 c\r442.33105 -245.16992 43.52539 -245.16992 43.52539 -245.16992 c\r43.52539 -245.16992 43.52539 -48.94922 43.52539 -48.94922 c\rh\rW n\r0.60001 0.60001 1 rg\r0 i \r/GS0 gs\r359.22559 -144.01367 m\r359.22559 -144.01367 381.00586 -144.01367 381.00586 -144.01367 c\r381.00586 -144.01367 381.00586 -48.82324 381.00586 -48.82324 c\r381.00586 -48.82324 359.22559 -48.82324 359.22559 -48.82324 c\r359.22559 -48.82324 359.22559 -144.01367 359.22559 -144.01367 c\rh\rf\r0 0 0 RG\r4 w 10 M 0 j 0 J []0 d \r359.22559 -144.01367 m\r359.22559 -144.01367 381.00586 -144.01367 381.00586 -144.01367 c\r381.00586 -144.01367 381.00586 -48.82324 381.00586 -48.82324 c\r381.00586 -48.82324 359.22559 -48.82324 359.22559 -48.82324 c\r359.22559 -48.82324 359.22559 -144.01367 359.22559 -144.01367 c\rh\rS\rQ\rq\r1 0 0 -1 0 0 cm\r43.52539 -48.94922 m\r43.52539 -48.94922 442.33105 -48.94922 442.33105 -48.94922 c\r442.33105 -48.94922 442.33105 -245.16992 442.33105 -245.16992 c\r442.33105 -245.16992 43.52539 -245.16992 43.52539 -245.16992 c\r43.52539 -245.16992 43.52539 -48.94922 43.52539 -48.94922 c\rh\rW n\r0.60001 0.2 0.39999 rg\r0 i \r/GS0 gs\r82.29102 -115.33008 m\r82.29102 -115.33008 104.33154 -115.33008 104.33154 -115.33008 c\r104.33154 -115.33008 104.33154 -48.82324 104.33154 -48.82324 c\r104.33154 -48.82324 82.29102 -48.82324 82.29102 -48.82324 c\r82.29102 -48.82324 82.29102 -115.33008 82.29102 -115.33008 c\rh\rf\r0 0 0 RG\r4 w 10 M 0 j 0 J []0 d \r82.29102 -115.33008 m\r82.29102 -115.33008 104.33154 -115.33008 104.33154 -115.33008 c\r104.33154 -115.33008 104.33154 -48.82324 104.33154 -48.82324 c\r104.33154 -48.82324 82.29102 -48.82324 82.29102 -48.82324 c\r82.29102 -48.82324 82.29102 -115.33008 82.29102 -115.33008 c\rh\rS\rQ\rq\r1 0 0 -1 0 0 cm\r43.52539 -48.94922 m\r43.52539 -48.94922 442.33105 -48.94922 442.33105 -48.94922 c\r442.33105 -48.94922 442.33105 -245.16992 442.33105 -245.16992 c\r442.33105 -245.16992 43.52539 -245.16992 43.52539 -245.16992 c\r43.52539 -245.16992 43.52539 -48.94922 43.52539 -48.94922 c\rh\rW n\r0.60001 0.2 0.39999 rg\r0 i \r/GS0 gs\r182.12158 -109.74512 m\r182.12158 -109.74512 203.90332 -109.74512 203.90332 -109.74512 c\r203.90332 -109.74512 203.90332 -48.82324 203.90332 -48.82324 c\r203.90332 -48.82324 182.12158 -48.82324 182.12158 -48.82324 c\r182.12158 -48.82324 182.12158 -109.74512 182.12158 -109.74512 c\rh\rf\r0 0 0 RG\r4 w 10 M 0 j 0 J []0 d \r182.12158 -109.74512 m\r182.12158 -109.74512 203.90332 -109.74512 203.90332 -109.74512 c\r203.90332 -109.74512 203.90332 -48.82324 203.90332 -48.82324 c\r203.90332 -48.82324 182.12158 -48.82324 182.12158 -48.82324 c\r182.12158 -48.82324 182.12158 -109.74512 182.12158 -109.74512 c\rh\rS\rQ\rq\r1 0 0 -1 0 0 cm\r43.52539 -48.94922 m\r43.52539 -48.94922 442.33105 -48.94922 442.33105 -48.94922 c\r442.33105 -48.94922 442.33105 -245.16992 442.33105 -245.16992 c\r442.33105 -245.16992 43.52539 -245.16992 43.52539 -245.16992 c\r43.52539 -245.16992 43.52539 -48.94922 43.52539 -48.94922 c\rh\rW n\r0.60001 0.2 0.39999 rg\r0 i \r/GS0 gs\r281.69336 -107.20703 m\r281.69336 -107.20703 303.7334 -107.20703 303.7334 -107.20703 c\r303.7334 -107.20703 303.7334 -48.82324 303.7334 -48.82324 c\r303.7334 -48.82324 281.69336 -48.82324 281.69336 -48.82324 c\r281.69336 -48.82324 281.69336 -107.20703 281.69336 -107.20703 c\rh\rf\r0 0 0 RG\r4 w 10 M 0 j 0 J []0 d \r281.69336 -107.20703 m\r281.69336 -107.20703 303.7334 -107.20703 303.7334 -107.20703 c\r303.7334 -107.20703 303.7334 -48.82324 303.7334 -48.82324 c\r303.7334 -48.82324 281.69336 -48.82324 281.69336 -48.82324 c\r281.69336 -48.82324 281.69336 -107.20703 281.69336 -107.20703 c\rh\rS\rQ\rq\r1 0 0 -1 0 0 cm\r43.52539 -48.94922 m\r43.52539 -48.94922 442.33105 -48.94922 442.33105 -48.94922 c\r442.33105 -48.94922 442.33105 -245.16992 442.33105 -245.16992 c\r442.33105 -245.16992 43.52539 -245.16992 43.52539 -245.16992 c\r43.52539 -245.16992 43.52539 -48.94922 43.52539 -48.94922 c\rh\rW n\r0.60001 0.2 0.39999 rg\r0 i \r/GS0 gs\r381.26465 -110.76074 m\r381.26465 -110.76074 403.30566 -110.76074 403.30566 -110.76074 c\r403.30566 -110.76074 403.30566 -48.82324 403.30566 -48.82324 c\r403.30566 -48.82324 381.26465 -48.82324 381.26465 -48.82324 c\r381.26465 -48.82324 381.26465 -110.76074 381.26465 -110.76074 c\rh\rf\r0 0 0 RG\r4 w 10 M 0 j 0 J []0 d \r381.26465 -110.76074 m\r381.26465 -110.76074 403.30566 -110.76074 403.30566 -110.76074 c\r403.30566 -110.76074 403.30566 -48.82324 403.30566 -48.82324 c\r403.30566 -48.82324 381.26465 -48.82324 381.26465 -48.82324 c\r381.26465 -48.82324 381.26465 -110.76074 381.26465 -110.76074 c\rh\rS\rQ\rq\r1 0 0 -1 0 0 cm\r43.52539 -48.94922 m\r43.52539 -48.94922 442.33105 -48.94922 442.33105 -48.94922 c\r442.33105 -48.94922 442.33105 -245.16992 442.33105 -245.16992 c\r442.33105 -245.16992 43.52539 -245.16992 43.52539 -245.16992 c\r43.52539 -245.16992 43.52539 -48.94922 43.52539 -48.94922 c\rh\rW n\r1 1 0.8 rg\r0 i \r/GS0 gs\r104.59131 -208.23633 m\r104.59131 -208.23633 126.37207 -208.23633 126.37207 -208.23633 c\r126.37207 -208.23633 126.37207 -48.82324 126.37207 -48.82324 c\r126.37207 -48.82324 104.59131 -48.82324 104.59131 -48.82324 c\r104.59131 -48.82324 104.59131 -208.23633 104.59131 -208.23633 c\rh\rf\r0 0 0 RG\r4 w 10 M 0 j 0 J []0 d \r104.59131 -208.23633 m\r104.59131 -208.23633 126.37207 -208.23633 126.37207 -208.23633 c\r126.37207 -208.23633 126.37207 -48.82324 126.37207 -48.82324 c\r126.37207 -48.82324 104.59131 -48.82324 104.59131 -48.82324 c\r104.59131 -48.82324 104.59131 -208.23633 104.59131 -208.23633 c\rh\rS\rQ\rq\r1 0 0 -1 0 0 cm\r43.52539 -48.94922 m\r43.52539 -48.94922 442.33105 -48.94922 442.33105 -48.94922 c\r442.33105 -48.94922 442.33105 -245.16992 442.33105 -245.16992 c\r442.33105 -245.16992 43.52539 -245.16992 43.52539 -245.16992 c\r43.52539 -245.16992 43.52539 -48.94922 43.52539 -48.94922 c\rh\rW n\r1 1 0.8 rg\r0 i \r/GS0 gs\r204.16211 -187.16699 m\r204.16211 -187.16699 226.20313 -187.16699 226.20313 -187.16699 c\r226.20313 -187.16699 226.20313 -48.82324 226.20313 -48.82324 c\r226.20313 -48.82324 204.16211 -48.82324 204.16211 -48.82324 c\r204.16211 -48.82324 204.16211 -187.16699 204.16211 -187.16699 c\rh\rf\r0 0 0 RG\r4 w 10 M 0 j 0 J []0 d \r204.16211 -187.16699 m\r204.16211 -187.16699 226.20313 -187.16699 226.20313 -187.16699 c\r226.20313 -187.16699 226.20313 -48.82324 226.20313 -48.82324 c\r226.20313 -48.82324 204.16211 -48.82324 204.16211 -48.82324 c\r204.16211 -48.82324 204.16211 -187.16699 204.16211 -187.16699 c\rh\rS\rQ\rq\r1 0 0 -1 0 0 cm\r43.52539 -48.94922 m\r43.52539 -48.94922 442.33105 -48.94922 442.33105 -48.94922 c\r442.33105 -48.94922 442.33105 -245.16992 442.33105 -245.16992 c\r442.33105 -245.16992 43.52539 -245.16992 43.52539 -245.16992 c\r43.52539 -245.16992 43.52539 -48.94922 43.52539 -48.94922 c\rh\rW n\r1 1 0.8 rg\r0 i \r/GS0 gs\r303.99316 -178.02881 m\r303.99316 -178.02881 325.77539 -178.02881 325.77539 -178.02881 c\r325.77539 -178.02881 325.77539 -48.82324 325.77539 -48.82324 c\r325.77539 -48.82324 303.99316 -48.82324 303.99316 -48.82324 c\r303.99316 -48.82324 303.99316 -178.02881 303.99316 -178.02881 c\rh\rf\r0 0 0 RG\r4 w 10 M 0 j 0 J []0 d \r303.99316 -178.02881 m\r303.99316 -178.02881 325.77539 -178.02881 325.77539 -178.02881 c\r325.77539 -178.02881 325.77539 -48.82324 325.77539 -48.82324 c\r325.77539 -48.82324 303.99316 -48.82324 303.99316 -48.82324 c\r303.99316 -48.82324 303.99316 -178.02881 303.99316 -178.02881 c\rh\rS\rQ\rq\r1 0 0 -1 0 0 cm\r43.52539 -48.94922 m\r43.52539 -48.94922 442.33105 -48.94922 442.33105 -48.94922 c\r442.33105 -48.94922 442.33105 -245.16992 442.33105 -245.16992 c\r442.33105 -245.16992 43.52539 -245.16992 43.52539 -245.16992 c\r43.52539 -245.16992 43.52539 -48.94922 43.52539 -48.94922 c\rh\rW n\r1 1 0.8 rg\r0 i \r/GS0 gs\r403.56543 -207.2207 m\r403.56543 -207.2207 425.3457 -207.2207 425.3457 -207.2207 c\r425.3457 -207.2207 425.3457 -48.82324 425.3457 -48.82324 c\r425.3457 -48.82324 403.56543 -48.82324 403.56543 -48.82324 c\r403.56543 -48.82324 403.56543 -207.2207 403.56543 -207.2207 c\rh\rf\r0 0 0 RG\r4 w 10 M 0 j 0 J []0 d \r403.56543 -207.2207 m\r403.56543 -207.2207 425.3457 -207.2207 425.3457 -207.2207 c\r425.3457 -207.2207 425.3457 -48.82324 425.3457 -48.82324 c\r425.3457 -48.82324 403.56543 -48.82324 403.56543 -48.82324 c\r403.56543 -48.82324 403.56543 -207.2207 403.56543 -207.2207 c\rh\rS\rQ\rq\r1 0 0 -1 0 0 cm\r1 -0.71973 m\r1 -0.71973 519.86133 -0.71973 519.86133 -0.71973 c\r519.86133 -0.71973 519.86133 -300 519.86133 -300 c\r519.86133 -300 1 -300 1 -300 c\r1 -300 1 -0.71973 1 -0.71973 c\rh\rW n\r0 0 0 RG\r0 i 1 w 10 M 0 j 0 J []0 d \r/GS0 gs\r43.65576 -245.04297 m\r43.65576 -245.04297 43.65576 -48.82324 43.65576 -48.82324 c\rS\r40.80322 -48.82324 m\r40.80322 -48.82324 43.65576 -48.82324 43.65576 -48.82324 c\rS\r40.80322 -81.56738 m\r40.80322 -81.56738 43.65576 -81.56738 43.65576 -81.56738 c\rS\r40.80322 -114.31348 m\r40.80322 -114.31348 43.65576 -114.31348 43.65576 -114.31348 c\rS\r40.80322 -146.80566 m\r40.80322 -146.80566 43.65576 -146.80566 43.65576 -146.80566 c\rS\r40.80322 -179.55176 m\r40.80322 -179.55176 43.65576 -179.55176 43.65576 -179.55176 c\rS\r40.80322 -212.29736 m\r40.80322 -212.29736 43.65576 -212.29736 43.65576 -212.29736 c\rS\r40.80322 -245.04297 m\r40.80322 -245.04297 43.65576 -245.04297 43.65576 -245.04297 c\rS\r43.65576 -48.82324 m\r43.65576 -48.82324 442.20117 -48.82324 442.20117 -48.82324 c\rS\r43.65576 -46.03027 m\r43.65576 -46.03027 43.65576 -48.82324 43.65576 -48.82324 c\rS\r143.22656 -46.03027 m\r143.22656 -46.03027 143.22656 -48.82324 143.22656 -48.82324 c\rS\r243.05762 -46.03027 m\r243.05762 -46.03027 243.05762 -48.82324 243.05762 -48.82324 c\rS\r342.62891 -46.03027 m\r342.62891 -46.03027 342.62891 -48.82324 342.62891 -48.82324 c\rS\r442.20117 -46.03027 m\r442.20117 -46.03027 442.20117 -48.82324 442.20117 -48.82324 c\rS\rQ\rq\r1 0 0 -1 0 0 cm\r76.97559 -267.00098 m\r76.97559 -267.00098 443.62793 -267.00098 443.62793 -267.00098 c\r443.62793 -267.00098 443.62793 -289.59277 443.62793 -289.59277 c\r443.62793 -289.59277 76.97559 -289.59277 76.97559 -289.59277 c\r76.97559 -289.59277 76.97559 -267.00098 76.97559 -267.00098 c\rh\rW n\r0 0 0 rg\r0 i \r/GS0 gs\r437.80469 -275.5166 m\r437.80469 -275.5166 437.80469 -278.94287 437.80469 -278.94287 c\r437.64551 -279.00977 437.47559 -279.05713 437.2998 -279.08594 c\r437.12305 -279.11523 436.95996 -279.12939 436.8125 -279.12939 c\r436.21387 -279.12939 435.76563 -278.94629 435.46582 -278.57959 c\r435.16699 -278.2124 435.01758 -277.70361 435.01758 -277.05273 c\r435.01758 -276.36865 435.13867 -275.87207 435.37793 -275.56348 c\r435.61816 -275.25439 436.00293 -275.09961 436.53516 -275.09961 c\r436.74023 -275.09961 436.95996 -275.13818 437.19238 -275.21484 c\r437.42285 -275.29199 437.62891 -275.39209 437.80469 -275.5166 c\rh\r440.09082 -273.60107 m\r440.09082 -273.60107 437.80469 -273.60107 437.80469 -273.60107 c\r437.80469 -273.60107 437.80469 -274.32617 437.80469 -274.32617 c\r437.41309 -274.01172 437.0459 -273.78076 436.7041 -273.63232 c\r436.36328 -273.48438 435.96875 -273.41016 435.52051 -273.41016 c\r434.65625 -273.41016 433.96484 -273.73682 433.44531 -274.38965 c\r432.92676 -275.04297 432.66895 -275.92285 432.66895 -277.03027 c\r432.66895 -277.62158 432.75488 -278.14502 432.93066 -278.60156 c\r433.10449 -279.05811 433.34375 -279.4502 433.64844 -279.77637 c\r433.93555 -280.08643 434.2832 -280.32715 434.69141 -280.49854 c\r435.10059 -280.66992 435.51074 -280.75586 435.91992 -280.75586 c\r436.34668 -280.75586 436.69434 -280.71143 436.96582 -280.62256 c\r437.23828 -280.53369 437.51855 -280.4209 437.80469 -280.28467 c\r437.80469 -280.28467 437.80469 -283.24658 437.80469 -283.24658 c\r437.80469 -283.24658 440.09082 -283.24658 440.09082 -283.24658 c\r440.09082 -283.24658 440.09082 -273.60107 440.09082 -273.60107 c\rh\r428.73047 -275.38672 m\r428.87793 -275.56396 428.98828 -275.77783 429.0625 -276.02734 c\r429.13574 -276.27637 429.17285 -276.62207 429.17285 -277.06348 c\r429.17285 -277.47168 429.13477 -277.81396 429.05957 -278.09082 c\r428.9834 -278.36719 428.87793 -278.58789 428.74316 -278.75293 c\r428.6084 -278.92188 428.44629 -279.0415 428.25488 -279.11182 c\r428.06543 -279.18164 427.86133 -279.2168 427.64258 -279.2168 c\r427.42383 -279.2168 427.22754 -279.18799 427.05762 -279.13037 c\r426.88574 -279.07275 426.72266 -278.95703 426.56641 -278.78418 c\r426.42676 -278.62305 426.31641 -278.40234 426.23438 -278.12207 c\r426.15137 -277.84082 426.11035 -277.48877 426.11035 -277.06348 c\r426.11035 -276.68408 426.14648 -276.35498 426.21875 -276.07666 c\r426.29004 -275.79834 426.39551 -275.57422 426.53418 -275.40527 c\r426.66992 -275.24414 426.83105 -275.12695 427.01953 -275.05273 c\r427.20703 -274.97852 427.4209 -274.94092 427.66211 -274.94092 c\r427.86719 -274.94092 428.06445 -274.9751 428.25195 -275.04346 c\r428.43945 -275.11133 428.59961 -275.22559 428.73047 -275.38672 c\rh\r431.53125 -277.07617 m\r431.53125 -275.93262 431.19141 -275.03223 430.51074 -274.37402 c\r429.8291 -273.71582 428.87402 -273.38672 427.64258 -273.38672 c\r426.41113 -273.38672 425.45508 -273.71582 424.77344 -274.37402 c\r424.09375 -275.03223 423.75195 -275.93262 423.75195 -277.07617 c\r423.75195 -278.22705 424.0957 -279.13086 424.78027 -279.7876 c\r425.46582 -280.44385 426.41992 -280.77148 427.64258 -280.77148 c\r428.88184 -280.77148 429.84082 -280.44189 430.5166 -279.78125 c\r431.19336 -279.12061 431.53125 -278.21875 431.53125 -277.07617 c\rh\r422.17969 -273.60107 m\r422.17969 -273.60107 419.89355 -273.60107 419.89355 -273.60107 c\r419.89355 -273.60107 419.89355 -277.05664 419.89355 -277.05664 c\r419.89355 -277.33789 419.87891 -277.61768 419.84961 -277.89746 c\r419.82031 -278.17676 419.76953 -278.38232 419.69727 -278.51416 c\r419.61328 -278.66797 419.49023 -278.7793 419.32715 -278.84961 c\r419.16406 -278.91992 418.93848 -278.95557 418.64746 -278.95557 c\r418.44141 -278.95557 418.23047 -278.92188 418.01855 -278.85547 c\r417.80469 -278.78955 417.57324 -278.68408 417.3252 -278.53906 c\r417.3252 -278.53906 417.3252 -273.60107 417.3252 -273.60107 c\r417.3252 -273.60107 415.04102 -273.60107 415.04102 -273.60107 c\r415.04102 -273.60107 415.04102 -283.24658 415.04102 -283.24658 c\r415.04102 -283.24658 417.3252 -283.24658 417.3252 -283.24658 c\r417.3252 -283.24658 417.3252 -279.79443 417.3252 -279.79443 c\r417.73047 -280.10498 418.11816 -280.34277 418.49121 -280.50781 c\r418.86426 -280.67285 419.27734 -280.75586 419.7334 -280.75586 c\r420.49902 -280.75586 421.09863 -280.53662 421.53223 -280.09863 c\r421.96289 -279.66016 422.17969 -279.00488 422.17969 -278.1333 c\r422.17969 -278.1333 422.17969 -273.60107 422.17969 -273.60107 c\rh\r413.67383 -273.66406 m\r413.42969 -273.60205 413.16895 -273.55322 412.89453 -273.51807 c\r412.62012 -273.4834 412.28418 -273.46582 411.88672 -273.46582 c\r411.00098 -273.46582 410.33984 -273.64111 409.90723 -273.9917 c\r409.47461 -274.34277 409.25781 -274.94336 409.25781 -275.79297 c\r409.25781 -275.79297 409.25781 -279.04199 409.25781 -279.04199 c\r409.25781 -279.04199 408.31738 -279.04199 408.31738 -279.04199 c\r408.31738 -279.04199 408.31738 -280.55762 408.31738 -280.55762 c\r408.31738 -280.55762 409.25781 -280.55762 409.25781 -280.55762 c\r409.25781 -280.55762 409.25781 -282.54883 409.25781 -282.54883 c\r409.25781 -282.54883 411.54297 -282.54883 411.54297 -282.54883 c\r411.54297 -282.54883 411.54297 -280.55762 411.54297 -280.55762 c\r411.54297 -280.55762 413.67383 -280.55762 413.67383 -280.55762 c\r413.67383 -280.55762 413.67383 -279.04199 413.67383 -279.04199 c\r413.67383 -279.04199 411.54297 -279.04199 411.54297 -279.04199 c\r411.54297 -279.04199 411.54297 -276.57813 411.54297 -276.57813 c\r411.54297 -276.33447 411.54492 -276.12207 411.54883 -275.94043 c\r411.55273 -275.75928 411.58691 -275.5957 411.65137 -275.45117 c\r411.70996 -275.30664 411.81348 -275.19238 411.96387 -275.10791 c\r412.11328 -275.02344 412.33105 -274.98096 412.61719 -274.98096 c\r412.73633 -274.98096 412.89063 -275.00635 413.08203 -275.05615 c\r413.27441 -275.10693 413.4082 -275.15332 413.48438 -275.19531 c\r413.48438 -275.19531 413.67383 -275.19531 413.67383 -275.19531 c\r413.67383 -275.19531 413.67383 -273.66406 413.67383 -273.66406 c\rh\r405.25195 -277.97168 m\r405.23828 -278.4375 405.12109 -278.78809 404.89648 -279.02295 c\r404.67285 -279.25781 404.3252 -279.37598 403.85156 -279.37598 c\r403.41406 -279.37598 403.05371 -279.26416 402.77051 -279.0415 c\r402.48828 -278.81885 402.33008 -278.4624 402.2959 -277.97168 c\r402.2959 -277.97168 405.25195 -277.97168 405.25195 -277.97168 c\rh\r407.52148 -276.6626 m\r407.52148 -276.6626 402.30273 -276.6626 402.30273 -276.6626 c\r402.33594 -276.12109 402.54785 -275.70703 402.93848 -275.41992 c\r403.33008 -275.13232 403.90527 -274.98926 404.66602 -274.98926 c\r405.14648 -274.98926 405.61426 -275.07275 406.06543 -275.24121 c\r406.51855 -275.40918 406.87598 -275.58936 407.1377 -275.78223 c\r407.1377 -275.78223 407.3916 -275.78223 407.3916 -275.78223 c\r407.3916 -275.78223 407.3916 -273.99316 407.3916 -273.99316 c\r406.87695 -273.7915 406.38965 -273.64453 405.93359 -273.55469 c\r405.47852 -273.46338 404.97461 -273.41797 404.4209 -273.41797 c\r402.99414 -273.41797 401.90039 -273.73145 401.14063 -274.35889 c\r400.38184 -274.98584 400.00098 -275.87939 400.00098 -277.03955 c\r400.00098 -278.18652 400.36035 -279.09521 401.08008 -279.76563 c\r401.79883 -280.43652 402.78516 -280.77148 404.03809 -280.77148 c\r405.19531 -280.77148 406.06445 -280.48535 406.64746 -279.91357 c\r407.22949 -279.34131 407.52148 -278.51758 407.52148 -277.44336 c\r407.52148 -277.44336 407.52148 -276.6626 407.52148 -276.6626 c\rh\r398.23535 -273.60107 m\r398.23535 -273.60107 395.82031 -273.60107 395.82031 -273.60107 c\r395.82031 -273.60107 395.82031 -279.77637 395.82031 -279.77637 c\r395.82031 -279.77637 394.07227 -275.7666 394.07227 -275.7666 c\r394.07227 -275.7666 392.39258 -275.7666 392.39258 -275.7666 c\r392.39258 -275.7666 390.64355 -279.77637 390.64355 -279.77637 c\r390.64355 -279.77637 390.64355 -273.60107 390.64355 -273.60107 c\r390.64355 -273.60107 388.34961 -273.60107 388.34961 -273.60107 c\r388.34961 -273.60107 388.34961 -282.82617 388.34961 -282.82617 c\r388.34961 -282.82617 391.1748 -282.82617 391.1748 -282.82617 c\r391.1748 -282.82617 393.29883 -278.19629 393.29883 -278.19629 c\r393.29883 -278.19629 395.41602 -282.82617 395.41602 -282.82617 c\r395.41602 -282.82617 398.23535 -282.82617 398.23535 -282.82617 c\r398.23535 -282.82617 398.23535 -273.60107 398.23535 -273.60107 c\rh\r382.49609 -278.43164 m\r382.49609 -278.43164 382.29492 -278.43164 382.29492 -278.43164 c\r382.19922 -278.46338 382.04199 -278.48682 381.82813 -278.50293 c\r381.61426 -278.51904 381.43555 -278.52686 381.29297 -278.52686 c\r380.96875 -278.52686 380.68457 -278.50586 380.43652 -278.46484 c\r380.18848 -278.42334 379.92188 -278.35303 379.63477 -278.25439 c\r379.63477 -278.25439 379.63477 -273.60107 379.63477 -273.60107 c\r379.63477 -273.60107 377.35156 -273.60107 377.35156 -273.60107 c\r377.35156 -273.60107 377.35156 -280.55762 377.35156 -280.55762 c\r377.35156 -280.55762 379.63477 -280.55762 379.63477 -280.55762 c\r379.63477 -280.55762 379.63477 -279.53467 379.63477 -279.53467 c\r380.13574 -279.95605 380.57129 -280.23633 380.94141 -280.37402 c\r381.31055 -280.5127 381.65039 -280.58105 381.96191 -280.58105 c\r382.04004 -280.58105 382.13086 -280.5791 382.23145 -280.5752 c\r382.33301 -280.5708 382.42188 -280.56445 382.49609 -280.55664 c\r382.49609 -280.55664 382.49609 -278.43164 382.49609 -278.43164 c\rh\r373.47559 -277.97168 m\r373.46191 -278.4375 373.34277 -278.78809 373.12012 -279.02295 c\r372.89648 -279.25781 372.54883 -279.37598 372.07617 -279.37598 c\r371.63672 -279.37598 371.27539 -279.26416 370.99316 -279.0415 c\r370.71094 -278.81885 370.55273 -278.4624 370.51855 -277.97168 c\r370.51855 -277.97168 373.47559 -277.97168 373.47559 -277.97168 c\rh\r375.74414 -276.6626 m\r375.74414 -276.6626 370.52441 -276.6626 370.52441 -276.6626 c\r370.55859 -276.12109 370.77051 -275.70703 371.16211 -275.41992 c\r371.55273 -275.13232 372.12891 -274.98926 372.88867 -274.98926 c\r373.37012 -274.98926 373.83594 -275.07275 374.28906 -275.24121 c\r374.74121 -275.40918 375.09766 -275.58936 375.36035 -275.78223 c\r375.36035 -275.78223 375.61426 -275.78223 375.61426 -275.78223 c\r375.61426 -275.78223 375.61426 -273.99316 375.61426 -273.99316 c\r375.09863 -273.7915 374.61328 -273.64453 374.15723 -273.55469 c\r373.70117 -273.46338 373.19629 -273.41797 372.64355 -273.41797 c\r371.2168 -273.41797 370.12207 -273.73145 369.36328 -274.35889 c\r368.60352 -274.98584 368.22461 -275.87939 368.22461 -277.03955 c\r368.22461 -278.18652 368.58301 -279.09521 369.30371 -279.76563 c\r370.02246 -280.43652 371.00781 -280.77148 372.26172 -280.77148 c\r373.41797 -280.77148 374.28711 -280.48535 374.87012 -279.91357 c\r375.45215 -279.34131 375.74414 -278.51758 375.74414 -277.44336 c\r375.74414 -277.44336 375.74414 -276.6626 375.74414 -276.6626 c\rh\r364.75293 -277.13428 m\r364.75293 -277.81152 364.63379 -278.30273 364.39746 -278.60791 c\r364.16309 -278.91357 363.78906 -279.06592 363.2793 -279.06592 c\r363.06445 -279.06592 362.8418 -279.03369 362.61621 -278.96973 c\r362.38867 -278.90625 362.1709 -278.81445 361.96484 -278.69434 c\r361.96484 -278.69434 361.96484 -275.19678 361.96484 -275.19678 c\r362.11719 -275.13867 362.27832 -275.10156 362.45117 -275.08496 c\r362.62402 -275.06885 362.79492 -275.06055 362.96289 -275.06055 c\r363.56543 -275.06055 364.01563 -275.23242 364.30957 -275.57715 c\r364.60449 -275.92188 364.75293 -276.44092 364.75293 -277.13428 c\rh\r367.10156 -277.17871 m\r367.10156 -276.60449 367.01172 -276.08203 366.83398 -275.61035 c\r366.6543 -275.13965 366.41895 -274.75098 366.12695 -274.44531 c\r365.82422 -274.12305 365.48047 -273.87891 365.09668 -273.71338 c\r364.71289 -273.54834 364.30078 -273.46582 363.8623 -273.46582 c\r363.45801 -273.46582 363.11328 -273.50781 362.83105 -273.59277 c\r362.54785 -273.67725 362.26074 -273.7959 361.96484 -273.94922 c\r361.96484 -273.94922 361.96484 -271.04639 361.96484 -271.04639 c\r361.96484 -271.04639 359.67969 -271.04639 359.67969 -271.04639 c\r359.67969 -271.04639 359.67969 -280.55762 359.67969 -280.55762 c\r359.67969 -280.55762 361.96484 -280.55762 361.96484 -280.55762 c\r361.96484 -280.55762 361.96484 -279.83252 361.96484 -279.83252 c\r362.31543 -280.10498 362.67188 -280.32715 363.03711 -280.49854 c\r363.40234 -280.66992 363.82324 -280.75586 364.29883 -280.75586 c\r365.18457 -280.75586 365.87402 -280.4375 366.36426 -279.80127 c\r366.85645 -279.16455 367.10156 -278.29053 367.10156 -277.17871 c\rh\r353.73145 -275.80908 m\r353.73145 -275.09033 353.40234 -274.51025 352.74414 -274.07031 c\r352.08594 -273.63037 351.18457 -273.41016 350.04199 -273.41016 c\r349.4082 -273.41016 348.83496 -273.46826 348.32031 -273.58398 c\r347.80469 -273.7002 347.3916 -273.82813 347.08008 -273.96875 c\r347.08008 -273.96875 347.08008 -275.80615 347.08008 -275.80615 c\r347.08008 -275.80615 347.28711 -275.80615 347.28711 -275.80615 c\r347.40137 -275.72754 347.5332 -275.64209 347.68359 -275.54883 c\r347.83301 -275.45605 348.0459 -275.35596 348.31738 -275.24854 c\r348.55469 -275.15332 348.82227 -275.07178 349.12109 -275.00342 c\r349.4209 -274.93555 349.74121 -274.90137 350.08301 -274.90137 c\r350.5293 -274.90137 350.86035 -274.94971 351.0752 -275.04639 c\r351.29102 -275.14307 351.39844 -275.28564 351.39844 -275.47461 c\r351.39844 -275.64404 351.33398 -275.7666 351.20801 -275.84326 c\r351.08203 -275.91992 350.8418 -275.99316 350.4873 -276.06348 c\r350.31934 -276.10059 350.09082 -276.14063 349.80176 -276.18408 c\r349.5127 -276.22754 349.25 -276.28027 349.01465 -276.34229 c\r348.37012 -276.50732 347.89063 -276.76465 347.58008 -277.11377 c\r347.26758 -277.46338 347.11035 -277.89844 347.11035 -278.41895 c\r347.11035 -279.08887 347.43457 -279.64551 348.08301 -280.08936 c\r348.73047 -280.53369 349.61426 -280.75586 350.73828 -280.75586 c\r351.26953 -280.75586 351.77832 -280.70313 352.26563 -280.59766 c\r352.75293 -280.49268 353.13379 -280.38037 353.4082 -280.26025 c\r353.4082 -280.26025 353.4082 -278.50293 353.4082 -278.50293 c\r353.4082 -278.50293 353.21191 -278.50293 353.21191 -278.50293 c\r352.87598 -278.72803 352.49023 -278.91113 352.05859 -279.05273 c\r351.62695 -279.19385 351.18848 -279.26416 350.74707 -279.26416 c\r350.38086 -279.26416 350.07129 -279.21533 349.82227 -279.1167 c\r349.57031 -279.01807 349.44531 -278.87842 349.44531 -278.69775 c\r349.44531 -278.53223 349.50195 -278.40625 349.61523 -278.31982 c\r349.73047 -278.23291 349.99707 -278.146 350.41895 -278.05957 c\r350.65137 -278.01367 350.90039 -277.96973 351.16797 -277.92627 c\r351.43652 -277.88281 351.7041 -277.82813 351.97363 -277.76172 c\r352.57227 -277.60889 353.01563 -277.36768 353.30176 -277.03955 c\r353.58887 -276.71094 353.73145 -276.30078 353.73145 -275.80908 c\rh\r345.46582 -273.60107 m\r345.46582 -273.60107 343.18066 -273.60107 343.18066 -273.60107 c\r343.18066 -273.60107 343.18066 -277.05664 343.18066 -277.05664 c\r343.18066 -277.33789 343.16504 -277.61768 343.13574 -277.89746 c\r343.10645 -278.17676 343.05566 -278.38232 342.9834 -278.51416 c\r342.89941 -278.66797 342.77539 -278.7793 342.61328 -278.84961 c\r342.45117 -278.91992 342.22363 -278.95557 341.93359 -278.95557 c\r341.72656 -278.95557 341.51758 -278.92188 341.30371 -278.85547 c\r341.09082 -278.78955 340.86035 -278.68408 340.61035 -278.53906 c\r340.61035 -278.53906 340.61035 -273.60107 340.61035 -273.60107 c\r340.61035 -273.60107 338.32617 -273.60107 338.32617 -273.60107 c\r338.32617 -273.60107 338.32617 -280.55762 338.32617 -280.55762 c\r338.32617 -280.55762 340.61035 -280.55762 340.61035 -280.55762 c\r340.61035 -280.55762 340.61035 -279.79443 340.61035 -279.79443 c\r341.01563 -280.10498 341.40332 -280.34277 341.77637 -280.50781 c\r342.14941 -280.67285 342.56348 -280.75586 343.01953 -280.75586 c\r343.78613 -280.75586 344.38477 -280.53662 344.81738 -280.09863 c\r345.24902 -279.66016 345.46582 -279.00488 345.46582 -278.1333 c\r345.46582 -278.1333 345.46582 -273.60107 345.46582 -273.60107 c\rh\r333.87793 -275.38672 m\r334.02539 -275.56396 334.13672 -275.77783 334.20996 -276.02734 c\r334.28418 -276.27637 334.32129 -276.62207 334.32129 -277.06348 c\r334.32129 -277.47168 334.2832 -277.81396 334.20703 -278.09082 c\r334.13184 -278.36719 334.02539 -278.58789 333.89063 -278.75293 c\r333.75586 -278.92188 333.59277 -279.0415 333.40332 -279.11182 c\r333.21387 -279.18164 333.00977 -279.2168 332.79102 -279.2168 c\r332.57129 -279.2168 332.37598 -279.18799 332.20508 -279.13037 c\r332.0332 -279.07275 331.87012 -278.95703 331.71484 -278.78418 c\r331.57422 -278.62305 331.46387 -278.40234 331.38184 -278.12207 c\r331.2998 -277.84082 331.25879 -277.48877 331.25879 -277.06348 c\r331.25879 -276.68408 331.29395 -276.35498 331.36621 -276.07666 c\r331.43848 -275.79834 331.54297 -275.57422 331.68262 -275.40527 c\r331.81738 -275.24414 331.97852 -275.12695 332.16602 -275.05273 c\r332.35449 -274.97852 332.56934 -274.94092 332.80957 -274.94092 c\r333.0166 -274.94092 333.21289 -274.9751 333.40039 -275.04346 c\r333.58789 -275.11133 333.74707 -275.22559 333.87793 -275.38672 c\rh\r336.67969 -277.07617 m\r336.67969 -275.93262 336.33887 -275.03223 335.6582 -274.37402 c\r334.97754 -273.71582 334.02148 -273.38672 332.79102 -273.38672 c\r331.55859 -273.38672 330.60352 -273.71582 329.92188 -274.37402 c\r329.24121 -275.03223 328.90039 -275.93262 328.90039 -277.07617 c\r328.90039 -278.22705 329.24316 -279.13086 329.92773 -279.7876 c\r330.61426 -280.44385 331.56738 -280.77148 332.79102 -280.77148 c\r334.02832 -280.77148 334.98828 -280.44189 335.66504 -279.78125 c\r336.34082 -279.12061 336.67969 -278.21875 336.67969 -277.07617 c\rh\r327.27051 -273.60107 m\r327.27051 -273.60107 324.98438 -273.60107 324.98438 -273.60107 c\r324.98438 -273.60107 324.98438 -280.55762 324.98438 -280.55762 c\r324.98438 -280.55762 327.27051 -280.55762 327.27051 -280.55762 c\r327.27051 -280.55762 327.27051 -273.60107 327.27051 -273.60107 c\rh\r327.33496 -281.55713 m\r327.33496 -281.55713 324.91992 -281.55713 324.91992 -281.55713 c\r324.91992 -281.55713 324.91992 -283.24658 324.91992 -283.24658 c\r324.91992 -283.24658 327.33496 -283.24658 327.33496 -283.24658 c\r327.33496 -283.24658 327.33496 -281.55713 327.33496 -281.55713 c\rh\r323.61914 -273.66406 m\r323.37402 -273.60205 323.11426 -273.55322 322.83984 -273.51807 c\r322.56543 -273.4834 322.22852 -273.46582 321.83301 -273.46582 c\r320.94434 -273.46582 320.28516 -273.64111 319.85156 -273.9917 c\r319.41992 -274.34277 319.20313 -274.94336 319.20313 -275.79297 c\r319.20313 -275.79297 319.20313 -279.04199 319.20313 -279.04199 c\r319.20313 -279.04199 318.2627 -279.04199 318.2627 -279.04199 c\r318.2627 -279.04199 318.2627 -280.55762 318.2627 -280.55762 c\r318.2627 -280.55762 319.20313 -280.55762 319.20313 -280.55762 c\r319.20313 -280.55762 319.20313 -282.54883 319.20313 -282.54883 c\r319.20313 -282.54883 321.48828 -282.54883 321.48828 -282.54883 c\r321.48828 -282.54883 321.48828 -280.55762 321.48828 -280.55762 c\r321.48828 -280.55762 323.61914 -280.55762 323.61914 -280.55762 c\r323.61914 -280.55762 323.61914 -279.04199 323.61914 -279.04199 c\r323.61914 -279.04199 321.48828 -279.04199 321.48828 -279.04199 c\r321.48828 -279.04199 321.48828 -276.57813 321.48828 -276.57813 c\r321.48828 -276.33447 321.49023 -276.12207 321.49414 -275.94043 c\r321.49805 -275.75928 321.53223 -275.5957 321.5957 -275.45117 c\r321.65527 -275.30664 321.75879 -275.19238 321.9082 -275.10791 c\r322.05762 -275.02344 322.27637 -274.98096 322.56348 -274.98096 c\r322.68164 -274.98096 322.83496 -275.00635 323.02734 -275.05615 c\r323.21875 -275.10693 323.35352 -275.15332 323.42969 -275.19531 c\r323.42969 -275.19531 323.61914 -275.19531 323.61914 -275.19531 c\r323.61914 -275.19531 323.61914 -273.66406 323.61914 -273.66406 c\rh\r315.15039 -273.41797 m\r314.53027 -273.41797 313.96387 -273.49023 313.45215 -273.63477 c\r312.93945 -273.77979 312.49316 -274.00293 312.11426 -274.3042 c\r311.73926 -274.60596 311.44824 -274.98584 311.24121 -275.44482 c\r311.03418 -275.90332 310.93164 -276.44043 310.93164 -277.05566 c\r310.93164 -277.70459 311.04199 -278.26465 311.26367 -278.73535 c\r311.48438 -279.20654 311.79395 -279.59668 312.19141 -279.90674 c\r312.57324 -280.2002 313.01758 -280.41504 313.51855 -280.55127 c\r314.02051 -280.6875 314.54102 -280.75586 315.08203 -280.75586 c\r315.56543 -280.75586 316.0127 -280.7041 316.42285 -280.60059 c\r316.83203 -280.49756 317.21289 -280.36328 317.56738 -280.19824 c\r317.56738 -280.19824 317.56738 -278.29688 317.56738 -278.29688 c\r317.56738 -278.29688 317.24609 -278.29688 317.24609 -278.29688 c\r317.15723 -278.37061 317.0498 -278.45703 316.92578 -278.55615 c\r316.80176 -278.65479 316.64941 -278.75195 316.46777 -278.84668 c\r316.29492 -278.93701 316.10449 -279.01221 315.89941 -279.07178 c\r315.69238 -279.13135 315.45313 -279.16162 315.17871 -279.16162 c\r314.57227 -279.16162 314.10547 -278.97266 313.77832 -278.59473 c\r313.45215 -278.2168 313.28906 -277.7041 313.28906 -277.05566 c\r313.28906 -276.38721 313.45703 -275.87939 313.79102 -275.53271 c\r314.12598 -275.18604 314.60156 -275.0127 315.2168 -275.0127 c\r315.50391 -275.0127 315.76172 -275.04492 315.99121 -275.10889 c\r316.2207 -275.17236 316.41113 -275.24805 316.5625 -275.33447 c\r316.70605 -275.41699 316.83203 -275.50391 316.94141 -275.59473 c\r317.05078 -275.68555 317.15332 -275.77441 317.24609 -275.86133 c\r317.24609 -275.86133 317.56738 -275.86133 317.56738 -275.86133 c\r317.56738 -275.86133 317.56738 -273.95801 317.56738 -273.95801 c\r317.20898 -273.79199 316.83496 -273.66064 316.44434 -273.56348 c\r316.05469 -273.4668 315.62305 -273.41797 315.15039 -273.41797 c\rh\r309.30078 -273.60107 m\r309.30078 -273.60107 307.01563 -273.60107 307.01563 -273.60107 c\r307.01563 -273.60107 307.01563 -274.37061 307.01563 -274.37061 c\r306.59473 -274.05664 306.20801 -273.81787 305.8584 -273.65479 c\r305.50977 -273.49219 305.0918 -273.41016 304.60742 -273.41016 c\r303.82324 -273.41016 303.21973 -273.63086 302.79688 -274.07275 c\r302.37402 -274.51465 302.16211 -275.16748 302.16211 -276.03027 c\r302.16211 -276.03027 302.16211 -280.55762 302.16211 -280.55762 c\r302.16211 -280.55762 304.44727 -280.55762 304.44727 -280.55762 c\r304.44727 -280.55762 304.44727 -277.10645 304.44727 -277.10645 c\r304.44727 -276.75537 304.45898 -276.46289 304.48242 -276.22998 c\r304.50488 -275.99658 304.55859 -275.80371 304.64355 -275.65088 c\r304.72363 -275.49805 304.84473 -275.38623 305.00684 -275.31592 c\r305.16895 -275.24609 305.39551 -275.21094 305.6875 -275.21094 c\r305.88184 -275.21094 306.0957 -275.24609 306.33203 -275.31592 c\r306.56836 -275.38623 306.7959 -275.48975 307.01563 -275.62598 c\r307.01563 -275.62598 307.01563 -280.55762 307.01563 -280.55762 c\r307.01563 -280.55762 309.30078 -280.55762 309.30078 -280.55762 c\r309.30078 -280.55762 309.30078 -273.60107 309.30078 -273.60107 c\rh\r300.91992 -278.43164 m\r300.91992 -278.43164 300.71777 -278.43164 300.71777 -278.43164 c\r300.62207 -278.46338 300.4668 -278.48682 300.25195 -278.50293 c\r300.03809 -278.51904 299.85938 -278.52686 299.71777 -278.52686 c\r299.39355 -278.52686 299.1084 -278.50586 298.86035 -278.46484 c\r298.6123 -278.42334 298.3457 -278.35303 298.05957 -278.25439 c\r298.05957 -278.25439 298.05957 -273.60107 298.05957 -273.60107 c\r298.05957 -273.60107 295.77539 -273.60107 295.77539 -273.60107 c\r295.77539 -273.60107 295.77539 -280.55762 295.77539 -280.55762 c\r295.77539 -280.55762 298.05957 -280.55762 298.05957 -280.55762 c\r298.05957 -280.55762 298.05957 -279.53467 298.05957 -279.53467 c\r298.55957 -279.95605 298.99414 -280.23633 299.36426 -280.37402 c\r299.73438 -280.5127 300.07422 -280.58105 300.38477 -280.58105 c\r300.46387 -280.58105 300.55469 -280.5791 300.65625 -280.5752 c\r300.75586 -280.5708 300.84473 -280.56445 300.91992 -280.55664 c\r300.91992 -280.55664 300.91992 -278.43164 300.91992 -278.43164 c\rh\r294.4082 -273.66406 m\r294.16406 -273.60205 293.9043 -273.55322 293.62988 -273.51807 c\r293.35547 -273.4834 293.01953 -273.46582 292.62207 -273.46582 c\r291.73535 -273.46582 291.0752 -273.64111 290.64258 -273.9917 c\r290.20898 -274.34277 289.99219 -274.94336 289.99219 -275.79297 c\r289.99219 -275.79297 289.99219 -279.04199 289.99219 -279.04199 c\r289.99219 -279.04199 289.05273 -279.04199 289.05273 -279.04199 c\r289.05273 -279.04199 289.05273 -280.55762 289.05273 -280.55762 c\r289.05273 -280.55762 289.99219 -280.55762 289.99219 -280.55762 c\r289.99219 -280.55762 289.99219 -282.54883 289.99219 -282.54883 c\r289.99219 -282.54883 292.27734 -282.54883 292.27734 -282.54883 c\r292.27734 -282.54883 292.27734 -280.55762 292.27734 -280.55762 c\r292.27734 -280.55762 294.4082 -280.55762 294.4082 -280.55762 c\r294.4082 -280.55762 294.4082 -279.04199 294.4082 -279.04199 c\r294.4082 -279.04199 292.27734 -279.04199 292.27734 -279.04199 c\r292.27734 -279.04199 292.27734 -276.57813 292.27734 -276.57813 c\r292.27734 -276.33447 292.2793 -276.12207 292.28418 -275.94043 c\r292.28906 -275.75928 292.32129 -275.5957 292.38574 -275.45117 c\r292.44434 -275.30664 292.54883 -275.19238 292.69922 -275.10791 c\r292.84766 -275.02344 293.06543 -274.98096 293.35352 -274.98096 c\r293.4707 -274.98096 293.62695 -275.00635 293.81738 -275.05615 c\r294.00977 -275.10693 294.14355 -275.15332 294.21875 -275.19531 c\r294.21875 -275.19531 294.4082 -275.19531 294.4082 -275.19531 c\r294.4082 -275.19531 294.4082 -273.66406 294.4082 -273.66406 c\rh\r288.34961 -275.80908 m\r288.34961 -275.09033 288.02051 -274.51025 287.36133 -274.07031 c\r286.70313 -273.63037 285.80273 -273.41016 284.6582 -273.41016 c\r284.02637 -273.41016 283.45117 -273.46826 282.93652 -273.58398 c\r282.42188 -273.7002 282.00879 -273.82813 281.69531 -273.96875 c\r281.69531 -273.96875 281.69531 -275.80615 281.69531 -275.80615 c\r281.69531 -275.80615 281.90527 -275.80615 281.90527 -275.80615 c\r282.01855 -275.72754 282.15039 -275.64209 282.2998 -275.54883 c\r282.4502 -275.45605 282.66113 -275.35596 282.93555 -275.24854 c\r283.17188 -275.15332 283.44043 -275.07178 283.73828 -275.00342 c\r284.03906 -274.93555 284.35938 -274.90137 284.7002 -274.90137 c\r285.14746 -274.90137 285.47754 -274.94971 285.69336 -275.04639 c\r285.9082 -275.14307 286.01563 -275.28564 286.01563 -275.47461 c\r286.01563 -275.64404 285.95215 -275.7666 285.8252 -275.84326 c\r285.69922 -275.91992 285.45801 -275.99316 285.10547 -276.06348 c\r284.93652 -276.10059 284.70703 -276.14063 284.41895 -276.18408 c\r284.13086 -276.22754 283.86719 -276.28027 283.63184 -276.34229 c\r282.98633 -276.50732 282.50879 -276.76465 282.19727 -277.11377 c\r281.88477 -277.46338 281.72949 -277.89844 281.72949 -278.41895 c\r281.72949 -279.08887 282.05273 -279.64551 282.70117 -280.08936 c\r283.34766 -280.53369 284.23242 -280.75586 285.35547 -280.75586 c\r285.88672 -280.75586 286.39551 -280.70313 286.88281 -280.59766 c\r287.37109 -280.49268 287.75098 -280.38037 288.02441 -280.26025 c\r288.02441 -280.26025 288.02441 -278.50293 288.02441 -278.50293 c\r288.02441 -278.50293 287.83008 -278.50293 287.83008 -278.50293 c\r287.49121 -278.72803 287.10742 -278.91113 286.67676 -279.05273 c\r286.24316 -279.19385 285.80664 -279.26416 285.36426 -279.26416 c\r284.99805 -279.26416 284.68945 -279.21533 284.4375 -279.1167 c\r284.18848 -279.01807 284.0625 -278.87842 284.0625 -278.69775 c\r284.0625 -278.53223 284.12012 -278.40625 284.2334 -278.31982 c\r284.3457 -278.23291 284.61426 -278.146 285.03613 -278.05957 c\r285.26758 -278.01367 285.51758 -277.96973 285.78613 -277.92627 c\r286.05371 -277.88281 286.32129 -277.82813 286.5918 -277.76172 c\r287.19043 -277.60889 287.63184 -277.36768 287.91992 -277.03955 c\r288.20605 -276.71094 288.34961 -276.30078 288.34961 -275.80908 c\rh\r280.08398 -273.60107 m\r280.08398 -273.60107 277.79688 -273.60107 277.79688 -273.60107 c\r277.79688 -273.60107 277.79688 -277.05664 277.79688 -277.05664 c\r277.79688 -277.33789 277.7832 -277.61768 277.75293 -277.89746 c\r277.72363 -278.17676 277.67383 -278.38232 277.60156 -278.51416 c\r277.5166 -278.66797 277.39453 -278.7793 277.23047 -278.84961 c\r277.06934 -278.91992 276.8418 -278.95557 276.5498 -278.95557 c\r276.34473 -278.95557 276.13574 -278.92188 275.92188 -278.85547 c\r275.70801 -278.78955 275.47656 -278.68408 275.22852 -278.53906 c\r275.22852 -278.53906 275.22852 -273.60107 275.22852 -273.60107 c\r275.22852 -273.60107 272.94336 -273.60107 272.94336 -273.60107 c\r272.94336 -273.60107 272.94336 -280.55762 272.94336 -280.55762 c\r272.94336 -280.55762 275.22852 -280.55762 275.22852 -280.55762 c\r275.22852 -280.55762 275.22852 -279.79443 275.22852 -279.79443 c\r275.63281 -280.10498 276.02148 -280.34277 276.39453 -280.50781 c\r276.76758 -280.67285 277.18066 -280.75586 277.63574 -280.75586 c\r278.40332 -280.75586 279.00195 -280.53662 279.43457 -280.09863 c\r279.86621 -279.66016 280.08398 -279.00488 280.08398 -278.1333 c\r280.08398 -278.1333 280.08398 -273.60107 280.08398 -273.60107 c\rh\r271.08984 -273.60107 m\r271.08984 -273.60107 265.56445 -273.60107 265.56445 -273.60107 c\r265.56445 -273.60107 265.56445 -275.23486 265.56445 -275.23486 c\r265.56445 -275.23486 267.11328 -275.23486 267.11328 -275.23486 c\r267.11328 -275.23486 267.11328 -281.19238 267.11328 -281.19238 c\r267.11328 -281.19238 265.56445 -281.19238 265.56445 -281.19238 c\r265.56445 -281.19238 265.56445 -282.82617 265.56445 -282.82617 c\r265.56445 -282.82617 271.08984 -282.82617 271.08984 -282.82617 c\r271.08984 -282.82617 271.08984 -281.19238 271.08984 -281.19238 c\r271.08984 -281.19238 269.54297 -281.19238 269.54297 -281.19238 c\r269.54297 -281.19238 269.54297 -275.23486 269.54297 -275.23486 c\r269.54297 -275.23486 271.08984 -275.23486 271.08984 -275.23486 c\r271.08984 -275.23486 271.08984 -273.60107 271.08984 -273.60107 c\rh\r259.89893 -276.5 m\r259.89893 -275.5918 259.50537 -274.854 258.71826 -274.28564 c\r257.93018 -273.71777 256.86133 -273.43408 255.50977 -273.43408 c\r254.729 -273.43408 254.04834 -273.50098 253.46729 -273.63574 c\r252.88672 -273.76953 252.34326 -273.94092 251.83691 -274.14746 c\r251.83691 -274.14746 251.83691 -276.36133 251.83691 -276.36133 c\r251.83691 -276.36133 252.10303 -276.36133 252.10303 -276.36133 c\r252.60498 -275.96826 253.1665 -275.6665 253.78906 -275.45605 c\r254.41113 -275.24463 255.01025 -275.13965 255.58447 -275.13965 c\r255.73193 -275.13965 255.92676 -275.15186 256.16699 -275.17676 c\r256.40771 -275.20117 256.604 -275.24268 256.75586 -275.30078 c\r256.94141 -275.37451 257.09424 -275.46729 257.21436 -275.57813 c\r257.33545 -275.68994 257.39502 -275.85449 257.39502 -276.07324 c\r257.39502 -276.27539 257.30762 -276.4502 257.13232 -276.59619 c\r256.95703 -276.74316 256.70068 -276.85547 256.36328 -276.93408 c\r256.00879 -277.0166 255.63281 -277.09424 255.23828 -277.1665 c\r254.84375 -277.23877 254.47461 -277.33057 254.12842 -277.44238 c\r253.33496 -277.69434 252.76367 -278.03564 252.41504 -278.46729 c\r252.06689 -278.89893 251.89307 -279.43457 251.89307 -280.0752 c\r251.89307 -280.93408 252.28662 -281.63477 253.07471 -282.17822 c\r253.86279 -282.72119 254.87402 -282.99316 256.1123 -282.99316 c\r256.73291 -282.99316 257.34668 -282.93408 257.95215 -282.81641 c\r258.55762 -282.69873 259.0835 -282.55078 259.52637 -282.37305 c\r259.52637 -282.37305 259.52637 -280.24805 259.52637 -280.24805 c\r259.52637 -280.24805 259.26709 -280.24805 259.26709 -280.24805 c\r258.88672 -280.54541 258.42041 -280.79443 257.87012 -280.99463 c\r257.31934 -281.19482 256.75684 -281.29541 256.18311 -281.29541 c\r255.979 -281.29541 255.77832 -281.28125 255.57861 -281.25488 c\r255.37793 -281.22852 255.18359 -281.17773 254.99805 -281.10352 c\r254.8335 -281.0415 254.69238 -280.94727 254.57422 -280.82129 c\r254.45557 -280.69531 254.39648 -280.55176 254.39648 -280.39111 c\r254.39648 -280.14746 254.4917 -279.96045 254.68115 -279.83008 c\r254.87109 -279.7002 255.22998 -279.58154 255.75781 -279.47412 c\r256.10352 -279.40381 256.43701 -279.33545 256.75586 -279.26953 c\r257.07422 -279.20313 257.41602 -279.1123 257.78467 -278.99707 c\r258.50635 -278.76563 259.03906 -278.45068 259.38281 -278.05225 c\r259.72705 -277.65381 259.89893 -277.13672 259.89893 -276.5 c\rh\r248.11865 -279.86426 m\r248.11865 -280.12354 248.04688 -280.34668 247.90332 -280.53418 c\r247.75928 -280.72119 247.59082 -280.85156 247.40088 -280.92627 c\r247.14697 -281.02441 246.89941 -281.0791 246.6582 -281.08936 c\r246.41699 -281.09961 246.09521 -281.10498 245.69434 -281.10498 c\r245.69434 -281.10498 245.27441 -281.10498 245.27441 -281.10498 c\r245.27441 -281.10498 245.27441 -278.35205 245.27441 -278.35205 c\r245.27441 -278.35205 245.97266 -278.35205 245.97266 -278.35205 c\r246.3877 -278.35205 246.729 -278.37695 246.99805 -278.42578 c\r247.2666 -278.47559 247.4917 -278.57422 247.67334 -278.72266 c\r247.83057 -278.854 247.94385 -279.01172 248.01318 -279.19434 c\r248.08398 -279.37793 248.11865 -279.60107 248.11865 -279.86426 c\rh\r250.62988 -279.91504 m\r250.62988 -279.50195 250.55566 -279.09863 250.4082 -278.7041 c\r250.26074 -278.30957 250.0498 -277.97852 249.77539 -277.70996 c\r249.39844 -277.34619 248.97949 -277.07129 248.51611 -276.88574 c\r248.05322 -276.7002 247.47852 -276.60693 246.78955 -276.60693 c\r246.78955 -276.60693 245.27441 -276.60693 245.27441 -276.60693 c\r245.27441 -276.60693 245.27441 -273.60107 245.27441 -273.60107 c\r245.27441 -273.60107 242.84326 -273.60107 242.84326 -273.60107 c\r242.84326 -273.60107 242.84326 -282.82617 242.84326 -282.82617 c\r242.84326 -282.82617 246.84863 -282.82617 246.84863 -282.82617 c\r247.44775 -282.82617 247.9541 -282.77539 248.36572 -282.67432 c\r248.77734 -282.57324 249.14209 -282.42139 249.4585 -282.21924 c\r249.83838 -281.97559 250.12891 -281.66357 250.33057 -281.28418 c\r250.53076 -280.90381 250.62988 -280.44727 250.62988 -279.91504 c\rh\r240.87012 -273.60107 m\r240.87012 -273.60107 235.34375 -273.60107 235.34375 -273.60107 c\r235.34375 -273.60107 235.34375 -275.23486 235.34375 -275.23486 c\r235.34375 -275.23486 236.89014 -275.23486 236.89014 -275.23486 c\r236.89014 -275.23486 236.89014 -281.19238 236.89014 -281.19238 c\r236.89014 -281.19238 235.34375 -281.19238 235.34375 -281.19238 c\r235.34375 -281.19238 235.34375 -282.82617 235.34375 -282.82617 c\r235.34375 -282.82617 240.87012 -282.82617 240.87012 -282.82617 c\r240.87012 -282.82617 240.87012 -281.19238 240.87012 -281.19238 c\r240.87012 -281.19238 239.32129 -281.19238 239.32129 -281.19238 c\r239.32129 -281.19238 239.32129 -275.23486 239.32129 -275.23486 c\r239.32129 -275.23486 240.87012 -275.23486 240.87012 -275.23486 c\r240.87012 -275.23486 240.87012 -273.60107 240.87012 -273.60107 c\rh\r233.35986 -273.60107 m\r233.35986 -273.60107 230.94482 -273.60107 230.94482 -273.60107 c\r230.94482 -273.60107 230.94482 -279.77637 230.94482 -279.77637 c\r230.94482 -279.77637 229.19531 -275.7666 229.19531 -275.7666 c\r229.19531 -275.7666 227.51563 -275.7666 227.51563 -275.7666 c\r227.51563 -275.7666 225.76758 -279.77637 225.76758 -279.77637 c\r225.76758 -279.77637 225.76758 -273.60107 225.76758 -273.60107 c\r225.76758 -273.60107 223.47363 -273.60107 223.47363 -273.60107 c\r223.47363 -273.60107 223.47363 -282.82617 223.47363 -282.82617 c\r223.47363 -282.82617 226.29932 -282.82617 226.29932 -282.82617 c\r226.29932 -282.82617 228.42188 -278.19629 228.42188 -278.19629 c\r228.42188 -278.19629 230.53857 -282.82617 230.53857 -282.82617 c\r230.53857 -282.82617 233.35986 -282.82617 233.35986 -282.82617 c\r233.35986 -282.82617 233.35986 -273.60107 233.35986 -273.60107 c\rh\r218.05713 -281.60449 m\r218.05713 -281.60449 217.88721 -281.60449 217.88721 -281.60449 c\r217.78662 -281.63428 217.6543 -281.66797 217.49268 -281.70605 c\r217.33057 -281.74414 217.15723 -281.76318 216.97168 -281.76318 c\r216.52539 -281.76318 216.22363 -281.68408 216.06592 -281.52734 c\r215.9082 -281.36963 215.8291 -281.06494 215.8291 -280.61328 c\r215.8291 -280.61328 215.8291 -280.55762 215.8291 -280.55762 c\r215.8291 -280.55762 217.5874 -280.55762 217.5874 -280.55762 c\r217.5874 -280.55762 217.5874 -279.04199 217.5874 -279.04199 c\r217.5874 -279.04199 215.90234 -279.04199 215.90234 -279.04199 c\r215.90234 -279.04199 215.90234 -273.60107 215.90234 -273.60107 c\r215.90234 -273.60107 213.61719 -273.60107 213.61719 -273.60107 c\r213.61719 -273.60107 213.61719 -279.04199 213.61719 -279.04199 c\r213.61719 -279.04199 212.64453 -279.04199 212.64453 -279.04199 c\r212.64453 -279.04199 212.64453 -280.55762 212.64453 -280.55762 c\r212.64453 -280.55762 213.61719 -280.55762 213.61719 -280.55762 c\r213.61719 -280.55762 213.61719 -280.75 213.61719 -280.75 c\r213.61719 -281.60303 213.84814 -282.24365 214.31104 -282.66992 c\r214.77295 -283.09668 215.47314 -283.31006 216.41016 -283.31006 c\r216.74854 -283.31006 217.05469 -283.29883 217.3291 -283.27588 c\r217.604 -283.25342 217.84619 -283.22266 218.05713 -283.18555 c\r218.05713 -283.18555 218.05713 -281.60449 218.05713 -281.60449 c\rh\r208.99951 -275.38672 m\r209.14697 -275.56396 209.25781 -275.77783 209.33154 -276.02734 c\r209.40527 -276.27637 209.44238 -276.62207 209.44238 -277.06348 c\r209.44238 -277.47168 209.4043 -277.81396 209.32861 -278.09082 c\r209.25293 -278.36719 209.14697 -278.58789 209.01172 -278.75293 c\r208.87744 -278.92188 208.71484 -279.0415 208.52441 -279.11182 c\r208.33447 -279.18164 208.12988 -279.2168 207.91113 -279.2168 c\r207.69141 -279.2168 207.49658 -279.18799 207.32568 -279.13037 c\r207.1543 -279.07275 206.99072 -278.95703 206.83496 -278.78418 c\r206.69531 -278.62305 206.58496 -278.40234 206.50244 -278.12207 c\r206.42041 -277.84082 206.37988 -277.48877 206.37988 -277.06348 c\r206.37988 -276.68408 206.41504 -276.35498 206.48633 -276.07666 c\r206.55859 -275.79834 206.66406 -275.57422 206.80322 -275.40527 c\r206.93848 -275.24414 207.09961 -275.12695 207.2876 -275.05273 c\r207.4751 -274.97852 207.68945 -274.94092 207.93018 -274.94092 c\r208.13672 -274.94092 208.3335 -274.9751 208.52148 -275.04346 c\r208.70898 -275.11133 208.86865 -275.22559 208.99951 -275.38672 c\rh\r211.80029 -277.07617 m\r211.80029 -275.93262 211.45996 -275.03223 210.7793 -274.37402 c\r210.09814 -273.71582 209.14209 -273.38672 207.91113 -273.38672 c\r206.67969 -273.38672 205.72412 -273.71582 205.04248 -274.37402 c\r204.36182 -275.03223 204.02148 -275.93262 204.02148 -277.07617 c\r204.02148 -278.22705 204.36377 -279.13086 205.04932 -279.7876 c\r205.73438 -280.44385 206.68799 -280.77148 207.91113 -280.77148 c\r209.1499 -280.77148 210.10889 -280.44189 210.78516 -279.78125 c\r211.46191 -279.12061 211.80029 -278.21875 211.80029 -277.07617 c\rh\r198.80762 -278.43164 m\r198.80762 -278.43164 198.60645 -278.43164 198.60645 -278.43164 c\r198.50977 -278.46338 198.35449 -278.48682 198.14014 -278.50293 c\r197.92529 -278.51904 197.74756 -278.52686 197.60449 -278.52686 c\r197.28125 -278.52686 196.99561 -278.50586 196.74756 -278.46484 c\r196.49951 -278.42334 196.2334 -278.35303 195.94727 -278.25439 c\r195.94727 -278.25439 195.94727 -273.60107 195.94727 -273.60107 c\r195.94727 -273.60107 193.6626 -273.60107 193.6626 -273.60107 c\r193.6626 -273.60107 193.6626 -280.55762 193.6626 -280.55762 c\r193.6626 -280.55762 195.94727 -280.55762 195.94727 -280.55762 c\r195.94727 -280.55762 195.94727 -279.53467 195.94727 -279.53467 c\r196.44775 -279.95605 196.88184 -280.23633 197.25195 -280.37402 c\r197.62109 -280.5127 197.96143 -280.58105 198.27197 -280.58105 c\r198.35205 -280.58105 198.44287 -280.5791 198.54346 -280.5752 c\r198.64404 -280.5708 198.73193 -280.56445 198.80762 -280.55664 c\r198.80762 -280.55664 198.80762 -278.43164 198.80762 -278.43164 c\rh\r189.78613 -277.97168 m\r189.77344 -278.4375 189.65479 -278.78809 189.43164 -279.02295 c\r189.20801 -279.25781 188.85986 -279.37598 188.38672 -279.37598 c\r187.94775 -279.37598 187.5874 -279.26416 187.30469 -279.0415 c\r187.02148 -278.81885 186.86377 -278.4624 186.83008 -277.97168 c\r186.83008 -277.97168 189.78613 -277.97168 189.78613 -277.97168 c\rh\r192.0542 -276.6626 m\r192.0542 -276.6626 186.83643 -276.6626 186.83643 -276.6626 c\r186.86963 -276.12109 187.08252 -275.70703 187.47314 -275.41992 c\r187.86377 -275.13232 188.43945 -274.98926 189.19971 -274.98926 c\r189.68164 -274.98926 190.14844 -275.07275 190.60059 -275.24121 c\r191.05273 -275.40918 191.41016 -275.58936 191.67139 -275.78223 c\r191.67139 -275.78223 191.92529 -275.78223 191.92529 -275.78223 c\r191.92529 -275.78223 191.92529 -273.99316 191.92529 -273.99316 c\r191.41016 -273.7915 190.9248 -273.64453 190.46875 -273.55469 c\r190.01221 -273.46338 189.5083 -273.41797 188.95508 -273.41797 c\r187.52783 -273.41797 186.43506 -273.73145 185.6748 -274.35889 c\r184.91553 -274.98584 184.53467 -275.87939 184.53467 -277.03955 c\r184.53467 -278.18652 184.89502 -279.09521 185.61426 -279.76563 c\r186.33398 -280.43652 187.32031 -280.77148 188.57324 -280.77148 c\r189.72949 -280.77148 190.59912 -280.48535 191.18164 -279.91357 c\r191.76367 -279.34131 192.0542 -278.51758 192.0542 -277.44336 c\r192.0542 -277.44336 192.0542 -276.6626 192.0542 -276.6626 c\rh\r181.06348 -277.1333 m\r181.06348 -277.75293 180.95605 -278.22998 180.74121 -278.56445 c\r180.52588 -278.89844 180.14307 -279.06592 179.59082 -279.06592 c\r179.37598 -279.06592 179.15479 -279.03369 178.92676 -278.96973 c\r178.69971 -278.90625 178.48193 -278.81445 178.27588 -278.69434 c\r178.27588 -278.69434 178.27588 -275.20068 178.27588 -275.20068 c\r178.44043 -275.14307 178.59619 -275.10352 178.74414 -275.08301 c\r178.89111 -275.0625 179.06836 -275.05225 179.27441 -275.05225 c\r179.87695 -275.05225 180.32617 -275.22559 180.62061 -275.57275 c\r180.91602 -275.91943 181.06348 -276.43994 181.06348 -277.1333 c\rh\r183.41357 -277.17871 m\r183.41357 -276.08398 183.10449 -275.19092 182.48633 -274.50098 c\r181.86865 -273.81055 181.09766 -273.46582 180.17383 -273.46582 c\r179.77734 -273.46582 179.42969 -273.50684 179.12988 -273.58887 c\r178.83057 -273.6709 178.5459 -273.79053 178.27588 -273.94775 c\r178.27588 -273.94775 178.18115 -273.60107 178.18115 -273.60107 c\r178.18115 -273.60107 175.99121 -273.60107 175.99121 -273.60107 c\r175.99121 -273.60107 175.99121 -283.24658 175.99121 -283.24658 c\r175.99121 -283.24658 178.27588 -283.24658 178.27588 -283.24658 c\r178.27588 -283.24658 178.27588 -279.83838 178.27588 -279.83838 c\r178.62598 -280.11133 178.9834 -280.33203 179.34863 -280.50146 c\r179.71289 -280.6709 180.13379 -280.75586 180.61084 -280.75586 c\r181.50928 -280.75586 182.20117 -280.43848 182.68555 -279.80469 c\r183.1709 -279.16992 183.41357 -278.29492 183.41357 -277.17871 c\rh\r169.21875 -278.53906 m\r169.21875 -278.53906 169.21875 -273.60107 169.21875 -273.60107 c\r169.21875 -273.60107 166.93311 -273.60107 166.93311 -273.60107 c\r166.93311 -273.60107 166.93311 -277.08105 166.93311 -277.08105 c\r166.93311 -277.42041 166.9248 -277.7085 166.90771 -277.94678 c\r166.89111 -278.18506 166.84473 -278.37793 166.76855 -278.52686 c\r166.69238 -278.67578 166.57764 -278.78467 166.42285 -278.85254 c\r166.26904 -278.9209 166.05225 -278.95557 165.77344 -278.95557 c\r165.55029 -278.95557 165.33252 -278.91064 165.12109 -278.82178 c\r164.91016 -278.73291 164.72021 -278.63867 164.55078 -278.53906 c\r164.55078 -278.53906 164.55078 -273.60107 164.55078 -273.60107 c\r164.55078 -273.60107 162.26563 -273.60107 162.26563 -273.60107 c\r162.26563 -273.60107 162.26563 -280.55762 162.26563 -280.55762 c\r162.26563 -280.55762 164.55078 -280.55762 164.55078 -280.55762 c\r164.55078 -280.55762 164.55078 -279.79443 164.55078 -279.79443 c\r164.94336 -280.09619 165.31836 -280.33203 165.67627 -280.50146 c\r166.03564 -280.6709 166.43164 -280.75586 166.86572 -280.75586 c\r167.33447 -280.75586 167.74707 -280.65332 168.10547 -280.44922 c\r168.46387 -280.24463 168.74414 -279.94336 168.94678 -279.54688 c\r169.40234 -279.92285 169.84473 -280.21875 170.27441 -280.43359 c\r170.70459 -280.64844 171.12646 -280.75586 171.53955 -280.75586 c\r172.30664 -280.75586 172.88965 -280.53076 173.28809 -280.08008 c\r173.68652 -279.62939 173.88574 -278.97998 173.88574 -278.1333 c\r173.88574 -278.1333 173.88574 -273.60107 173.88574 -273.60107 c\r173.88574 -273.60107 171.60107 -273.60107 171.60107 -273.60107 c\r171.60107 -273.60107 171.60107 -277.08105 171.60107 -277.08105 c\r171.60107 -277.4248 171.59277 -277.71436 171.5791 -277.94971 c\r171.56396 -278.18604 171.51807 -278.37793 171.44238 -278.52686 c\r171.37061 -278.67578 171.25635 -278.78467 171.1001 -278.85254 c\r170.94336 -278.9209 170.72412 -278.95557 170.44141 -278.95557 c\r170.25098 -278.95557 170.06494 -278.92285 169.88379 -278.85889 c\r169.70264 -278.79492 169.47998 -278.68848 169.21875 -278.53906 c\rh\r160.125 -273.60107 m\r160.125 -273.60107 157.83984 -273.60107 157.83984 -273.60107 c\r157.83984 -273.60107 157.83984 -274.37061 157.83984 -274.37061 c\r157.41846 -274.05664 157.0332 -273.81787 156.68359 -273.65479 c\r156.3335 -273.49219 155.91602 -273.41016 155.43213 -273.41016 c\r154.64844 -273.41016 154.04492 -273.63086 153.62061 -274.07275 c\r153.19775 -274.51465 152.98584 -275.16748 152.98584 -276.03027 c\r152.98584 -276.03027 152.98584 -280.55762 152.98584 -280.55762 c\r152.98584 -280.55762 155.27148 -280.55762 155.27148 -280.55762 c\r155.27148 -280.55762 155.27148 -277.10645 155.27148 -277.10645 c\r155.27148 -276.75537 155.28271 -276.46289 155.30615 -276.22998 c\r155.3291 -275.99658 155.38281 -275.80371 155.46729 -275.65088 c\r155.54785 -275.49805 155.66895 -275.38623 155.83105 -275.31592 c\r155.99365 -275.24609 156.2207 -275.21094 156.51123 -275.21094 c\r156.70508 -275.21094 156.92041 -275.24609 157.15674 -275.31592 c\r157.39307 -275.38623 157.62061 -275.48975 157.83984 -275.62598 c\r157.83984 -275.62598 157.83984 -280.55762 157.83984 -280.55762 c\r157.83984 -280.55762 160.125 -280.55762 160.125 -280.55762 c\r160.125 -280.55762 160.125 -273.60107 160.125 -273.60107 c\rh\r150.76416 -273.60107 m\r150.76416 -273.60107 148.42139 -273.60107 148.42139 -273.60107 c\r148.42139 -273.60107 144.41113 -279.93311 144.41113 -279.93311 c\r144.41113 -279.93311 144.41113 -273.60107 144.41113 -273.60107 c\r144.41113 -273.60107 142.18311 -273.60107 142.18311 -273.60107 c\r142.18311 -273.60107 142.18311 -282.82617 142.18311 -282.82617 c\r142.18311 -282.82617 145.09082 -282.82617 145.09082 -282.82617 c\r145.09082 -282.82617 148.53564 -277.5415 148.53564 -277.5415 c\r148.53564 -277.5415 148.53564 -282.82617 148.53564 -282.82617 c\r148.53564 -282.82617 150.76416 -282.82617 150.76416 -282.82617 c\r150.76416 -282.82617 150.76416 -273.60107 150.76416 -273.60107 c\rh\r135.47852 -273.60107 m\r135.47852 -273.60107 133.19336 -273.60107 133.19336 -273.60107 c\r133.19336 -273.60107 133.19336 -283.24658 133.19336 -283.24658 c\r133.19336 -283.24658 135.47852 -283.24658 135.47852 -283.24658 c\r135.47852 -283.24658 135.47852 -273.60107 135.47852 -273.60107 c\rh\r128.83545 -275.42676 m\r128.83545 -275.42676 128.83545 -276.86914 128.83545 -276.86914 c\r128.52783 -276.84424 128.19336 -276.81006 127.83496 -276.76709 c\r127.47607 -276.72363 127.2041 -276.67383 127.01855 -276.61572 c\r126.79053 -276.54639 126.61621 -276.44434 126.49609 -276.31104 c\r126.37598 -276.17725 126.31543 -276.00195 126.31543 -275.78418 c\r126.31543 -275.63965 126.32813 -275.52295 126.35352 -275.43262 c\r126.37891 -275.34229 126.44238 -275.25586 126.54346 -275.17383 c\r126.64063 -275.09131 126.75635 -275.03076 126.8916 -274.9917 c\r127.02686 -274.95313 127.23779 -274.93359 127.52441 -274.93359 c\r127.75244 -274.93359 127.9834 -274.97852 128.21826 -275.06885 c\r128.45313 -275.15967 128.6582 -275.27832 128.83545 -275.42676 c\rh\r128.83545 -274.33838 m\r128.71338 -274.24707 128.56152 -274.1377 128.37988 -274.00977 c\r128.19824 -273.88135 128.02686 -273.78076 127.8667 -273.70605 c\r127.64307 -273.60693 127.41113 -273.53467 127.16992 -273.48828 c\r126.92969 -273.44189 126.66553 -273.41797 126.37891 -273.41797 c\r125.70313 -273.41797 125.1377 -273.62256 124.68164 -274.03174 c\r124.22607 -274.44043 123.99805 -274.96338 123.99805 -275.59961 c\r123.99805 -276.10791 124.11377 -276.52295 124.34619 -276.84521 c\r124.57813 -277.16748 124.90771 -277.42139 125.33398 -277.60742 c\r125.75635 -277.79346 126.27979 -277.92578 126.9043 -278.00391 c\r127.5293 -278.08252 128.17676 -278.14063 128.84863 -278.17773 c\r128.84863 -278.17773 128.84863 -278.21484 128.84863 -278.21484 c\r128.84863 -278.59668 128.68799 -278.86035 128.36719 -279.00586 c\r128.04688 -279.15234 127.57471 -279.2251 126.9502 -279.2251 c\r126.57422 -279.2251 126.17432 -279.16016 125.74805 -279.03125 c\r125.32227 -278.90186 125.01611 -278.80273 124.83057 -278.73291 c\r124.83057 -278.73291 124.62207 -278.73291 124.62207 -278.73291 c\r124.62207 -278.73291 124.62207 -280.40918 124.62207 -280.40918 c\r124.8623 -280.47119 125.25391 -280.54443 125.7959 -280.62939 c\r126.33789 -280.71338 126.88135 -280.75586 127.42529 -280.75586 c\r128.7207 -280.75586 129.65625 -280.56055 130.23242 -280.17041 c\r130.80811 -279.78027 131.09619 -279.16748 131.09619 -278.3335 c\r131.09619 -278.3335 131.09619 -273.60107 131.09619 -273.60107 c\r131.09619 -273.60107 128.83545 -273.60107 128.83545 -273.60107 c\r128.83545 -273.60107 128.83545 -274.33838 128.83545 -274.33838 c\rh\r117.76074 -278.53906 m\r117.76074 -278.53906 117.76074 -273.60107 117.76074 -273.60107 c\r117.76074 -273.60107 115.4751 -273.60107 115.4751 -273.60107 c\r115.4751 -273.60107 115.4751 -277.08105 115.4751 -277.08105 c\r115.4751 -277.42041 115.4668 -277.7085 115.44971 -277.94678 c\r115.43262 -278.18506 115.38623 -278.37793 115.31055 -278.52686 c\r115.23438 -278.67578 115.11963 -278.78467 114.96484 -278.85254 c\r114.81055 -278.9209 114.59424 -278.95557 114.31543 -278.95557 c\r114.0918 -278.95557 113.87451 -278.91064 113.66309 -278.82178 c\r113.45215 -278.73291 113.26221 -278.63867 113.09229 -278.53906 c\r113.09229 -278.53906 113.09229 -273.60107 113.09229 -273.60107 c\r113.09229 -273.60107 110.80762 -273.60107 110.80762 -273.60107 c\r110.80762 -273.60107 110.80762 -280.55762 110.80762 -280.55762 c\r110.80762 -280.55762 113.09229 -280.55762 113.09229 -280.55762 c\r113.09229 -280.55762 113.09229 -279.79443 113.09229 -279.79443 c\r113.48486 -280.09619 113.85986 -280.33203 114.21826 -280.50146 c\r114.57715 -280.6709 114.97314 -280.75586 115.40771 -280.75586 c\r115.87598 -280.75586 116.28906 -280.65332 116.64746 -280.44922 c\r117.00586 -280.24463 117.28613 -279.94336 117.48877 -279.54688 c\r117.94385 -279.92285 118.38672 -280.21875 118.81641 -280.43359 c\r119.24658 -280.64844 119.66846 -280.75586 120.08154 -280.75586 c\r120.84863 -280.75586 121.43164 -280.53076 121.83008 -280.08008 c\r122.22803 -279.62939 122.42773 -278.97998 122.42773 -278.1333 c\r122.42773 -278.1333 122.42773 -273.60107 122.42773 -273.60107 c\r122.42773 -273.60107 120.14258 -273.60107 120.14258 -273.60107 c\r120.14258 -273.60107 120.14258 -277.08105 120.14258 -277.08105 c\r120.14258 -277.4248 120.13477 -277.71436 120.12061 -277.94971 c\r120.10596 -278.18604 120.06006 -278.37793 119.98389 -278.52686 c\r119.91211 -278.67578 119.79785 -278.78467 119.64209 -278.85254 c\r119.48535 -278.9209 119.26563 -278.95557 118.98291 -278.95557 c\r118.79297 -278.95557 118.60693 -278.92285 118.42529 -278.85889 c\r118.24414 -278.79492 118.02197 -278.68848 117.76074 -278.53906 c\rh\r108.66699 -273.60107 m\r108.66699 -273.60107 106.38184 -273.60107 106.38184 -273.60107 c\r106.38184 -273.60107 106.38184 -280.55762 106.38184 -280.55762 c\r106.38184 -280.55762 108.66699 -280.55762 108.66699 -280.55762 c\r108.66699 -280.55762 108.66699 -273.60107 108.66699 -273.60107 c\rh\r108.73193 -281.55713 m\r108.73193 -281.55713 106.31641 -281.55713 106.31641 -281.55713 c\r106.31641 -281.55713 106.31641 -283.24658 106.31641 -283.24658 c\r106.31641 -283.24658 108.73193 -283.24658 108.73193 -283.24658 c\r108.73193 -283.24658 108.73193 -281.55713 108.73193 -281.55713 c\rh\r105.01563 -273.66406 m\r104.77051 -273.60205 104.51074 -273.55322 104.23633 -273.51807 c\r103.96191 -273.4834 103.62598 -273.46582 103.229 -273.46582 c\r102.34229 -273.46582 101.68164 -273.64111 101.24902 -273.9917 c\r100.81592 -274.34277 100.59961 -274.94336 100.59961 -275.79297 c\r100.59961 -275.79297 100.59961 -279.04199 100.59961 -279.04199 c\r100.59961 -279.04199 99.65967 -279.04199 99.65967 -279.04199 c\r99.65967 -279.04199 99.65967 -280.55762 99.65967 -280.55762 c\r99.65967 -280.55762 100.59961 -280.55762 100.59961 -280.55762 c\r100.59961 -280.55762 100.59961 -282.54883 100.59961 -282.54883 c\r100.59961 -282.54883 102.88428 -282.54883 102.88428 -282.54883 c\r102.88428 -282.54883 102.88428 -280.55762 102.88428 -280.55762 c\r102.88428 -280.55762 105.01563 -280.55762 105.01563 -280.55762 c\r105.01563 -280.55762 105.01563 -279.04199 105.01563 -279.04199 c\r105.01563 -279.04199 102.88428 -279.04199 102.88428 -279.04199 c\r102.88428 -279.04199 102.88428 -276.57813 102.88428 -276.57813 c\r102.88428 -276.33447 102.88623 -276.12207 102.89063 -275.94043 c\r102.89502 -275.75928 102.92871 -275.5957 102.99219 -275.45117 c\r103.05078 -275.30664 103.15576 -275.19238 103.30469 -275.10791 c\r103.45508 -275.02344 103.67285 -274.98096 103.95996 -274.98096 c\r104.07813 -274.98096 104.23242 -275.00635 104.4248 -275.05615 c\r104.6167 -275.10693 104.75 -275.15332 104.82568 -275.19531 c\r104.82568 -275.19531 105.01563 -275.19531 105.01563 -275.19531 c\r105.01563 -275.19531 105.01563 -273.66406 105.01563 -273.66406 c\rh\r96.47998 -277.13428 m\r96.47998 -277.81152 96.36182 -278.30273 96.12549 -278.60791 c\r95.88965 -278.91357 95.51709 -279.06592 95.00732 -279.06592 c\r94.7915 -279.06592 94.5708 -279.03369 94.34326 -278.96973 c\r94.11523 -278.90625 93.89893 -278.81445 93.69238 -278.69434 c\r93.69238 -278.69434 93.69238 -275.19678 93.69238 -275.19678 c\r93.84375 -275.13867 94.00684 -275.10156 94.17871 -275.08496 c\r94.35156 -275.06885 94.52246 -275.06055 94.69092 -275.06055 c\r95.29346 -275.06055 95.74219 -275.23242 96.0376 -275.57715 c\r96.33252 -275.92188 96.47998 -276.44092 96.47998 -277.13428 c\rh\r98.82959 -277.17871 m\r98.82959 -276.60449 98.74023 -276.08203 98.56055 -275.61035 c\r98.38135 -275.13965 98.14648 -274.75098 97.85498 -274.44531 c\r97.55127 -274.12305 97.20801 -273.87891 96.82422 -273.71338 c\r96.43994 -273.54834 96.0293 -273.46582 95.59082 -273.46582 c\r95.18506 -273.46582 94.8418 -273.50781 94.55908 -273.59277 c\r94.27637 -273.67725 93.9873 -273.7959 93.69238 -273.94922 c\r93.69238 -273.94922 93.69238 -271.04639 93.69238 -271.04639 c\r93.69238 -271.04639 91.40674 -271.04639 91.40674 -271.04639 c\r91.40674 -271.04639 91.40674 -280.55762 91.40674 -280.55762 c\r91.40674 -280.55762 93.69238 -280.55762 93.69238 -280.55762 c\r93.69238 -280.55762 93.69238 -279.83252 93.69238 -279.83252 c\r94.04199 -280.10498 94.3999 -280.32715 94.76416 -280.49854 c\r95.12939 -280.66992 95.5498 -280.75586 96.02686 -280.75586 c\r96.9126 -280.75586 97.60156 -280.4375 98.09277 -279.80127 c\r98.58398 -279.16455 98.82959 -278.29053 98.82959 -277.17871 c\rh\r86.45654 -275.87891 m\r86.69287 -276.15918 86.86816 -276.48975 86.98242 -276.87158 c\r87.09619 -277.25293 87.15283 -277.70117 87.15283 -278.21631 c\r87.15283 -278.76904 87.0874 -279.23877 86.95703 -279.62646 c\r86.82617 -280.01416 86.65527 -280.32715 86.44434 -280.56689 c\r86.22803 -280.81348 85.98047 -280.99316 85.69922 -281.10449 c\r85.41846 -281.21582 85.12646 -281.27148 84.82227 -281.27148 c\r84.51416 -281.27148 84.22412 -281.21777 83.95166 -281.11035 c\r83.67871 -281.00342 83.42871 -280.82617 83.20117 -280.5791 c\r82.99023 -280.34766 82.81787 -280.02979 82.68506 -279.62305 c\r82.55225 -279.21729 82.48584 -278.74609 82.48584 -278.20996 c\r82.48584 -277.66211 82.55029 -277.19531 82.67871 -276.80957 c\r82.80762 -276.42432 82.97754 -276.10986 83.18848 -275.8667 c\r83.39941 -275.62305 83.64648 -275.44434 83.92969 -275.32861 c\r84.2124 -275.21338 84.50977 -275.15527 84.82227 -275.15527 c\r85.13477 -275.15527 85.43262 -275.21436 85.71533 -275.33154 c\r85.99805 -275.44922 86.24512 -275.63184 86.45654 -275.87891 c\rh\r89.68115 -278.20996 m\r89.68115 -276.74023 89.25098 -275.57275 88.38867 -274.70752 c\r87.52734 -273.84277 86.33643 -273.41016 84.81592 -273.41016 c\r83.2998 -273.41016 82.11133 -273.84277 81.25 -274.70752 c\r80.38818 -275.57275 79.95752 -276.74023 79.95752 -278.20996 c\r79.95752 -279.69287 80.38818 -280.86426 81.25 -281.7251 c\r82.11133 -282.58594 83.2998 -283.0166 84.81592 -283.0166 c\r86.32813 -283.0166 87.51709 -282.58594 88.38281 -281.7251 c\r89.24805 -280.86426 89.68115 -279.69287 89.68115 -278.20996 c\rh\rf\rQ\rq\r1 0 0 -1 0 0 cm\r1 -0.71973 m\r1 -0.71973 519.86133 -0.71973 519.86133 -0.71973 c\r519.86133 -0.71973 519.86133 -300 519.86133 -300 c\r519.86133 -300 1 -300 1 -300 c\r1 -300 1 -0.71973 1 -0.71973 c\rh\rW n\r0 0 0 rg\r0 i \r/GS0 gs\r34.56543 -47.16406 m\r34.66846 -47.39941 34.73877 -47.6748 34.77588 -47.99316 c\r34.8125 -48.30859 34.83057 -48.69141 34.83057 -49.13672 c\r34.83057 -49.57715 34.8125 -49.95898 34.77588 -50.2832 c\r34.73877 -50.6084 34.66699 -50.88281 34.56104 -51.1084 c\r34.45703 -51.33105 34.31641 -51.49902 34.13818 -51.6123 c\r33.95898 -51.72559 33.72949 -51.78125 33.44971 -51.78125 c\r33.17188 -51.78125 32.94189 -51.72559 32.76025 -51.6123 c\r32.5791 -51.49902 32.43506 -51.3291 32.3291 -51.09961 c\r32.22852 -50.88477 32.15967 -50.60547 32.12354 -50.26074 c\r32.08643 -49.91699 32.06787 -49.53906 32.06787 -49.12793 c\r32.06787 -48.67676 32.0835 -48.29883 32.11621 -47.99512 c\r32.14893 -47.69043 32.21826 -47.41797 32.32471 -47.17773 c\r32.42188 -46.95117 32.56055 -46.78027 32.73828 -46.66016 c\r32.91748 -46.54297 33.15381 -46.48242 33.44971 -46.48242 c\r33.72705 -46.48242 33.95703 -46.53906 34.14014 -46.65234 c\r34.32324 -46.76563 34.46484 -46.93652 34.56543 -47.16406 c\rh\r35.72998 -49.13672 m\r35.72998 -47.97656 35.54492 -47.125 35.17432 -46.58301 c\r34.80371 -46.04102 34.22852 -45.76855 33.44971 -45.76855 c\r32.6582 -45.76855 32.08008 -46.04395 31.71533 -46.59375 c\r31.3501 -47.14355 31.16846 -47.98828 31.16846 -49.12793 c\r31.16846 -50.27637 31.35254 -51.12402 31.72168 -51.67383 c\r32.09082 -52.22168 32.6665 -52.49609 33.44971 -52.49609 c\r34.24072 -52.49609 34.81836 -52.2168 35.18311 -51.66016 c\r35.54785 -51.10352 35.72998 -50.26172 35.72998 -49.13672 c\rh\rf\r35.36523 -78.64844 m\r35.36523 -78.64844 31.79199 -78.64844 31.79199 -78.64844 c\r31.79199 -78.64844 31.79199 -79.30762 31.79199 -79.30762 c\r31.79199 -79.30762 33.16992 -79.30762 33.16992 -79.30762 c\r33.16992 -79.30762 33.16992 -83.63965 33.16992 -83.63965 c\r33.16992 -83.63965 31.79199 -83.63965 31.79199 -83.63965 c\r31.79199 -83.63965 31.79199 -84.22656 31.79199 -84.22656 c\r31.97852 -84.22656 32.17871 -84.24121 32.3916 -84.27148 c\r32.60449 -84.30273 32.76611 -84.34668 32.87598 -84.4043 c\r33.01221 -84.47656 33.12012 -84.56934 33.19824 -84.68066 c\r33.27637 -84.79297 33.32178 -84.94141 33.3335 -85.12988 c\r33.3335 -85.12988 34.02051 -85.12988 34.02051 -85.12988 c\r34.02051 -85.12988 34.02051 -79.30762 34.02051 -79.30762 c\r34.02051 -79.30762 35.36523 -79.30762 35.36523 -79.30762 c\r35.36523 -79.30762 35.36523 -78.64844 35.36523 -78.64844 c\rh\rf\r35.72998 -111.39453 m\r35.72998 -111.39453 31.27344 -111.39453 31.27344 -111.39453 c\r31.27344 -111.39453 31.27344 -112.30566 31.27344 -112.30566 c\r31.5835 -112.56543 31.89453 -112.82617 32.20605 -113.08594 c\r32.51758 -113.34668 32.80762 -113.60449 33.07617 -113.86328 c\r33.64307 -114.40039 34.03125 -114.82813 34.24072 -115.14355 c\r34.45068 -115.46094 34.55566 -115.80273 34.55566 -116.1709 c\r34.55566 -116.50488 34.44238 -116.76758 34.2168 -116.95801 c\r33.99023 -117.14648 33.6748 -117.24219 33.27002 -117.24219 c\r33.00146 -117.24219 32.71045 -117.19531 32.39746 -117.10059 c\r32.08398 -117.00684 31.77832 -116.86328 31.47998 -116.6709 c\r31.47998 -116.6709 31.43604 -116.6709 31.43604 -116.6709 c\r31.43604 -116.6709 31.43604 -117.58398 31.43604 -117.58398 c\r31.64551 -117.68457 31.9248 -117.77734 32.27441 -117.86035 c\r32.62451 -117.94531 32.96289 -117.98633 33.29004 -117.98633 c\r33.96582 -117.98633 34.49561 -117.82715 34.87939 -117.50781 c\r35.26318 -117.18945 35.45459 -116.75586 35.45459 -116.20996 c\r35.45459 -115.96387 35.42334 -115.73535 35.35986 -115.52441 c\r35.2959 -115.31152 35.20215 -115.1084 35.07861 -114.91895 c\r34.96338 -114.73926 34.82861 -114.56348 34.67432 -114.38965 c\r34.51904 -114.2168 34.33105 -114.02441 34.10938 -113.81348 c\r33.79395 -113.50977 33.46826 -113.2168 33.13184 -112.93164 c\r32.79541 -112.64648 32.48145 -112.38379 32.18994 -112.14063 c\r32.18994 -112.14063 35.72998 -112.14063 35.72998 -112.14063 c\r35.72998 -112.14063 35.72998 -111.39453 35.72998 -111.39453 c\rh\rf\r35.16162 -146.99805 m\r35.30322 -146.87402 35.41992 -146.7168 35.51172 -146.5293 c\r35.60352 -146.34082 35.64941 -146.09863 35.64941 -145.80078 c\r35.64941 -145.50488 35.59424 -145.23438 35.48535 -144.98828 c\r35.37549 -144.74316 35.22217 -144.5293 35.02393 -144.34668 c\r34.80225 -144.14355 34.54102 -143.99414 34.24072 -143.89746 c\r33.94043 -143.80078 33.6123 -143.75195 33.25391 -143.75195 c\r32.88721 -143.75195 32.52637 -143.79492 32.17188 -143.88086 c\r31.81641 -143.96582 31.52539 -144.05957 31.29834 -144.16113 c\r31.29834 -144.16113 31.29834 -145.06836 31.29834 -145.06836 c\r31.29834 -145.06836 31.36475 -145.06836 31.36475 -145.06836 c\r31.61621 -144.90527 31.9126 -144.76855 32.25293 -144.66016 c\r32.59375 -144.55176 32.92236 -144.49805 33.23975 -144.49805 c\r33.42578 -144.49805 33.62402 -144.52832 33.83496 -144.58887 c\r34.04541 -144.65039 34.21484 -144.74023 34.34619 -144.85938 c\r34.48193 -144.98633 34.5835 -145.12793 34.6499 -145.28125 c\r34.7168 -145.43555 34.75 -145.62988 34.75 -145.86523 c\r34.75 -146.09668 34.71191 -146.29004 34.63672 -146.44238 c\r34.56055 -146.59473 34.45605 -146.71387 34.32227 -146.80078 c\r34.18896 -146.8916 34.02686 -146.95313 33.83691 -146.98633 c\r33.64648 -147.01953 33.44189 -147.03613 33.22217 -147.03613 c\r33.22217 -147.03613 32.82129 -147.03613 32.82129 -147.03613 c\r32.82129 -147.03613 32.82129 -147.75 32.82129 -147.75 c\r32.82129 -147.75 33.13232 -147.75 33.13232 -147.75 c\r33.58252 -147.75 33.94189 -147.8418 34.20996 -148.02637 c\r34.47803 -148.20996 34.6123 -148.47949 34.6123 -148.83301 c\r34.6123 -148.98926 34.57813 -149.12646 34.51074 -149.24414 c\r34.44238 -149.36133 34.34766 -149.45801 34.22656 -149.5332 c\r34.09961 -149.60889 33.96338 -149.66113 33.81885 -149.68994 c\r33.67432 -149.71875 33.50977 -149.7334 33.32715 -149.7334 c\r33.04688 -149.7334 32.74805 -149.68359 32.43213 -149.58398 c\r32.11572 -149.48438 31.81738 -149.34375 31.53662 -149.16211 c\r31.53662 -149.16211 31.49268 -149.16211 31.49268 -149.16211 c\r31.49268 -149.16211 31.49268 -150.07031 31.49268 -150.07031 c\r31.70264 -150.17188 31.98193 -150.26514 32.33252 -150.35059 c\r32.68213 -150.43604 33.021 -150.479 33.34961 -150.479 c\r33.6709 -150.479 33.95459 -150.4502 34.19971 -150.39209 c\r34.44531 -150.33447 34.6665 -150.24219 34.86426 -150.11475 c\r35.07764 -149.97607 35.23828 -149.80811 35.34766 -149.61182 c\r35.45654 -149.41553 35.51172 -149.18604 35.51172 -148.92285 c\r35.51172 -148.56445 35.38184 -148.25195 35.12354 -147.98438 c\r34.86523 -147.7168 34.55957 -147.54883 34.20801 -147.47852 c\r34.20801 -147.47852 34.20801 -147.41895 34.20801 -147.41895 c\r34.34961 -147.39551 34.5127 -147.34766 34.6958 -147.27344 c\r34.87939 -147.19922 35.03418 -147.10742 35.16162 -146.99805 c\rh\rf\r34.06104 -179.14746 m\r34.06104 -179.14746 34.06104 -182.06348 34.06104 -182.06348 c\r34.06104 -182.06348 31.50342 -179.14746 31.50342 -179.14746 c\r31.50342 -179.14746 34.06104 -179.14746 34.06104 -179.14746 c\rh\r35.89258 -178.44922 m\r35.89258 -178.44922 34.91211 -178.44922 34.91211 -178.44922 c\r34.91211 -178.44922 34.91211 -176.63281 34.91211 -176.63281 c\r34.91211 -176.63281 34.06104 -176.63281 34.06104 -176.63281 c\r34.06104 -176.63281 34.06104 -178.44922 34.06104 -178.44922 c\r34.06104 -178.44922 30.90088 -178.44922 30.90088 -178.44922 c\r30.90088 -178.44922 30.90088 -179.44678 30.90088 -179.44678 c\r30.90088 -179.44678 34.09619 -183.08984 34.09619 -183.08984 c\r34.09619 -183.08984 34.91211 -183.08984 34.91211 -183.08984 c\r34.91211 -183.08984 34.91211 -179.14746 34.91211 -179.14746 c\r34.91211 -179.14746 35.89258 -179.14746 35.89258 -179.14746 c\r35.89258 -179.14746 35.89258 -178.44922 35.89258 -178.44922 c\rh\rf\r35.68994 -211.42822 m\r35.68994 -211.12793 35.63379 -210.84033 35.521 -210.56592 c\r35.40869 -210.29102 35.25488 -210.06006 35.06006 -209.87207 c\r34.84717 -209.66992 34.59326 -209.51416 34.29932 -209.40576 c\r34.00537 -209.29785 33.66406 -209.24365 33.27637 -209.24365 c\r32.91553 -209.24365 32.56836 -209.28027 32.23486 -209.354 c\r31.8999 -209.42822 31.61816 -209.51709 31.38672 -209.62109 c\r31.38672 -209.62109 31.38672 -210.53711 31.38672 -210.53711 c\r31.38672 -210.53711 31.44922 -210.53711 31.44922 -210.53711 c\r31.69189 -210.38525 31.97559 -210.25537 32.30078 -210.14893 c\r32.62646 -210.04248 32.9458 -209.98926 33.25977 -209.98926 c\r33.46973 -209.98926 33.67285 -210.01855 33.86963 -210.07617 c\r34.06592 -210.13379 34.2417 -210.23535 34.39551 -210.37988 c\r34.52539 -210.50439 34.62402 -210.65332 34.68994 -210.82666 c\r34.75732 -211 34.79053 -211.20166 34.79053 -211.42969 c\r34.79053 -211.65283 34.75098 -211.84082 34.67334 -211.99414 c\r34.59424 -212.14746 34.48584 -212.27051 34.34668 -212.36279 c\r34.19287 -212.47314 34.00586 -212.55029 33.78467 -212.59521 c\r33.56445 -212.63965 33.31836 -212.6626 33.04688 -212.6626 c\r32.78564 -212.6626 32.53516 -212.64502 32.29395 -212.60986 c\r32.05322 -212.57422 31.84521 -212.53906 31.67041 -212.50391 c\r31.67041 -212.50391 31.67041 -215.83545 31.67041 -215.83545 c\r31.67041 -215.83545 35.64941 -215.83545 35.64941 -215.83545 c\r35.64941 -215.83545 35.64941 -215.07373 35.64941 -215.07373 c\r35.64941 -215.07373 32.52148 -215.07373 32.52148 -215.07373 c\r32.52148 -215.07373 32.52148 -213.35791 32.52148 -213.35791 c\r32.64844 -213.36914 32.77881 -213.37793 32.9126 -213.3833 c\r33.0459 -213.38916 33.16113 -213.39209 33.25928 -213.39209 c\r33.61768 -213.39209 33.93164 -213.36279 34.20117 -213.30371 c\r34.4707 -213.24414 34.71826 -213.13916 34.94336 -212.98877 c\r35.18066 -212.83057 35.36377 -212.625 35.49414 -212.37354 c\r35.625 -212.12256 35.68994 -211.80713 35.68994 -211.42822 c\rh\rf\r34.93604 -244.18652 m\r34.93604 -244.4541 34.89551 -244.67627 34.81494 -244.85205 c\r34.7334 -245.02734 34.60059 -245.18066 34.41504 -245.31006 c\r34.2793 -245.40234 34.12891 -245.46289 33.96387 -245.4917 c\r33.79883 -245.521 33.62646 -245.53516 33.44678 -245.53516 c\r33.19629 -245.53516 32.96387 -245.50635 32.74854 -245.44824 c\r32.5332 -245.39111 32.31201 -245.30176 32.08545 -245.18066 c\r32.07959 -245.11719 32.07568 -245.05615 32.07227 -244.99707 c\r32.06885 -244.9375 32.06787 -244.86328 32.06787 -244.77393 c\r32.06787 -244.31836 32.11523 -243.95898 32.21143 -243.6958 c\r32.30713 -243.43164 32.43848 -243.22363 32.60742 -243.0708 c\r32.74219 -242.94385 32.88965 -242.85059 33.04688 -242.79199 c\r33.2041 -242.73242 33.37646 -242.70313 33.56152 -242.70313 c\r33.98877 -242.70313 34.32471 -242.83057 34.56934 -243.08594 c\r34.81396 -243.34082 34.93604 -243.70752 34.93604 -244.18652 c\rh\r35.83594 -244.21875 m\r35.83594 -243.5625 35.61523 -243.02686 35.17334 -242.61182 c\r34.73242 -242.19678 34.19141 -241.98926 33.55078 -241.98926 c\r33.22559 -241.98926 32.93066 -242.03857 32.66504 -242.13721 c\r32.39941 -242.23535 32.16406 -242.38135 31.96094 -242.5752 c\r31.70703 -242.81543 31.51123 -243.13379 31.37402 -243.52979 c\r31.2373 -243.92676 31.16846 -244.40381 31.16846 -244.9624 c\r31.16846 -245.53516 31.23096 -246.04297 31.35693 -246.48584 c\r31.48193 -246.92871 31.68262 -247.32227 31.95752 -247.6665 c\r32.2168 -247.99365 32.55225 -248.24854 32.96289 -248.43262 c\r33.37305 -248.61621 33.85156 -248.7085 34.39795 -248.7085 c\r34.57227 -248.7085 34.71826 -248.70117 34.83643 -248.68652 c\r34.95459 -248.67188 35.07422 -248.646 35.1958 -248.6084 c\r35.1958 -248.6084 35.1958 -247.78027 35.1958 -247.78027 c\r35.1958 -247.78027 35.15137 -247.78027 35.15137 -247.78027 c\r35.06885 -247.82373 34.94385 -247.86475 34.77734 -247.90381 c\r34.61084 -247.94287 34.44043 -247.9624 34.2666 -247.9624 c\r33.63281 -247.9624 33.12646 -247.76758 32.74902 -247.37793 c\r32.37109 -246.98828 32.15186 -246.46191 32.08984 -245.79834 c\r32.3374 -245.94531 32.58154 -246.05762 32.82178 -246.13428 c\r33.06201 -246.21094 33.33984 -246.24902 33.65527 -246.24902 c\r33.93555 -246.24902 34.18213 -246.22363 34.396 -246.17285 c\r34.60986 -246.12256 34.8291 -246.02051 35.05273 -245.86719 c\r35.31201 -245.69092 35.50781 -245.46826 35.63867 -245.19922 c\r35.77002 -244.93066 35.83594 -244.60352 35.83594 -244.21875 c\rh\rf\r100.67432 -34.76563 m\r100.67432 -35.03418 100.63379 -35.25586 100.55273 -35.43164 c\r100.47119 -35.60742 100.33887 -35.75977 100.15332 -35.88965 c\r100.01758 -35.98242 99.8667 -36.04199 99.70166 -36.07129 c\r99.53662 -36.09961 99.36426 -36.11426 99.18506 -36.11426 c\r98.93408 -36.11426 98.70166 -36.08594 98.48633 -36.02734 c\r98.271 -35.9707 98.05078 -35.88086 97.82373 -35.76172 c\r97.81738 -35.69727 97.81348 -35.63477 97.80957 -35.57715 c\r97.80713 -35.51758 97.80566 -35.44336 97.80566 -35.35449 c\r97.80566 -34.89746 97.85352 -34.53809 97.94922 -34.27637 c\r98.04541 -34.01172 98.17725 -33.80273 98.34473 -33.65039 c\r98.48047 -33.52441 98.62744 -33.43066 98.78516 -33.37109 c\r98.94189 -33.31348 99.11426 -33.28223 99.2998 -33.28223 c\r99.72656 -33.28223 100.06299 -33.41016 100.30713 -33.66602 c\r100.55225 -33.9209 100.67432 -34.28711 100.67432 -34.76563 c\rh\r101.57373 -34.79883 m\r101.57373 -34.1416 101.35303 -33.60645 100.91162 -33.19141 c\r100.47021 -32.77637 99.9292 -32.56934 99.28857 -32.56934 c\r98.96387 -32.56934 98.66895 -32.61816 98.40283 -32.7168 c\r98.1377 -32.81543 97.90332 -32.96094 97.69922 -33.1543 c\r97.44531 -33.39551 97.24902 -33.71387 97.11182 -34.10938 c\r96.97461 -34.50586 96.90625 -34.9834 96.90625 -35.54199 c\r96.90625 -36.11426 96.96875 -36.62305 97.09473 -37.06543 c\r97.22021 -37.50879 97.42041 -37.90137 97.69531 -38.24609 c\r97.95459 -38.57324 98.29004 -38.8291 98.70068 -39.0127 c\r99.11133 -39.19629 99.58936 -39.28711 100.13623 -39.28711 c\r100.31006 -39.28711 100.45703 -39.28125 100.5752 -39.2666 c\r100.69287 -39.25195 100.8125 -39.22559 100.93359 -39.18848 c\r100.93359 -39.18848 100.93359 -38.36035 100.93359 -38.36035 c\r100.93359 -38.36035 100.88916 -38.36035 100.88916 -38.36035 c\r100.80664 -38.40332 100.68164 -38.44434 100.51514 -38.48438 c\r100.34912 -38.52344 100.17871 -38.54199 100.00439 -38.54199 c\r99.37061 -38.54199 98.86475 -38.34766 98.48682 -37.95703 c\r98.10938 -37.56738 97.88965 -37.04199 97.82764 -36.37793 c\r98.0752 -36.52539 98.31934 -36.63672 98.55957 -36.71387 c\r98.80029 -36.79004 99.07764 -36.8291 99.39404 -36.8291 c\r99.67334 -36.8291 99.91992 -36.80371 100.13477 -36.75293 c\r100.34814 -36.70215 100.56689 -36.59961 100.79102 -36.44727 c\r101.05029 -36.27051 101.24609 -36.04883 101.37646 -35.78027 c\r101.5083 -35.51074 101.57373 -35.18262 101.57373 -34.79883 c\rh\r95.65625 -34.75391 m\r95.65625 -34.4541 95.59961 -34.16602 95.48682 -33.8916 c\r95.375 -33.61719 95.2207 -33.38574 95.02588 -33.19727 c\r94.81299 -32.99512 94.55908 -32.83984 94.26514 -32.73145 c\r93.97119 -32.62305 93.62988 -32.56934 93.24268 -32.56934 c\r92.88184 -32.56934 92.53467 -32.60645 92.20068 -32.67871 c\r91.86621 -32.75391 91.58398 -32.84277 91.35254 -32.94629 c\r91.35254 -32.94629 91.35254 -33.86328 91.35254 -33.86328 c\r91.35254 -33.86328 91.41504 -33.86328 91.41504 -33.86328 c\r91.65771 -33.70996 91.94141 -33.58203 92.2666 -33.47461 c\r92.59277 -33.36816 92.91162 -33.31543 93.22559 -33.31543 c\r93.43555 -33.31543 93.63867 -33.34473 93.83545 -33.40234 c\r94.03223 -33.45996 94.20752 -33.56152 94.36133 -33.70605 c\r94.4917 -33.83008 94.58984 -33.97852 94.65625 -34.15234 c\r94.72314 -34.3252 94.75684 -34.52734 94.75684 -34.75488 c\r94.75684 -34.97852 94.7168 -35.16602 94.63916 -35.31934 c\r94.56006 -35.47266 94.45166 -35.5957 94.3125 -35.68945 c\r94.15869 -35.79883 93.97168 -35.87598 93.75098 -35.91992 c\r93.53076 -35.96582 93.28467 -35.98828 93.0127 -35.98828 c\r92.75146 -35.98828 92.50146 -35.96973 92.26025 -35.93457 c\r92.01904 -35.89941 91.81152 -35.86426 91.63623 -35.8291 c\r91.63623 -35.8291 91.63623 -39.16113 91.63623 -39.16113 c\r91.63623 -39.16113 95.61523 -39.16113 95.61523 -39.16113 c\r95.61523 -39.16113 95.61523 -38.39941 95.61523 -38.39941 c\r95.61523 -38.39941 92.4873 -38.39941 92.4873 -38.39941 c\r92.4873 -38.39941 92.4873 -36.68262 92.4873 -36.68262 c\r92.61426 -36.69531 92.74512 -36.70313 92.87842 -36.70898 c\r93.01221 -36.71582 93.12744 -36.71777 93.2251 -36.71777 c\r93.5835 -36.71777 93.89795 -36.68848 94.16699 -36.62891 c\r94.43701 -36.56934 94.68457 -36.46484 94.90918 -36.31445 c\r95.14648 -36.15625 95.33008 -35.9502 95.45996 -35.69922 c\r95.59082 -35.44727 95.65625 -35.13281 95.65625 -34.75391 c\rh\r89.92383 -32.7041 m\r89.92383 -32.7041 85.46729 -32.7041 85.46729 -32.7041 c\r85.46729 -32.7041 85.46729 -33.61523 85.46729 -33.61523 c\r85.77783 -33.875 86.08838 -34.13574 86.3999 -34.39551 c\r86.71143 -34.65625 87.00195 -34.91406 87.27002 -35.17188 c\r87.83691 -35.70996 88.22461 -36.1377 88.43457 -36.45313 c\r88.64404 -36.76953 88.74951 -37.1123 88.74951 -37.47852 c\r88.74951 -37.81445 88.63623 -38.07715 88.41016 -38.26563 c\r88.18457 -38.45508 87.86914 -38.5498 87.46387 -38.5498 c\r87.19531 -38.5498 86.9043 -38.50293 86.59131 -38.40918 c\r86.27783 -38.31641 85.97217 -38.17188 85.67383 -37.97949 c\r85.67383 -37.97949 85.62939 -37.97949 85.62939 -37.97949 c\r85.62939 -37.97949 85.62939 -38.8916 85.62939 -38.8916 c\r85.83887 -38.99316 86.11816 -39.08496 86.46777 -39.16992 c\r86.81836 -39.25488 87.15674 -39.2959 87.48389 -39.2959 c\r88.15967 -39.2959 88.68945 -39.13672 89.07324 -38.81641 c\r89.45654 -38.49805 89.64893 -38.06445 89.64893 -37.51953 c\r89.64893 -37.27344 89.61719 -37.04395 89.55371 -36.83105 c\r89.49023 -36.61914 89.39697 -36.41797 89.27246 -36.22852 c\r89.15723 -36.04883 89.02295 -35.87305 88.86816 -35.69922 c\r88.71289 -35.52539 88.52441 -35.33398 88.30371 -35.12305 c\r87.98828 -34.81934 87.66211 -34.52539 87.32617 -34.24121 c\r86.98926 -33.95605 86.67529 -33.69238 86.3833 -33.44922 c\r86.3833 -33.44922 89.92383 -33.44922 89.92383 -33.44922 c\r89.92383 -33.44922 89.92383 -32.7041 89.92383 -32.7041 c\rh\rf\r200.04346 -37.66406 m\r200.04346 -37.97559 199.92285 -38.22363 199.68018 -38.40723 c\r199.43848 -38.59375 199.12939 -38.68457 198.75391 -38.68457 c\r198.38379 -38.68457 198.08105 -38.59766 197.84473 -38.42383 c\r197.60889 -38.24805 197.49121 -38.0127 197.49121 -37.7168 c\r197.49121 -37.50684 197.5498 -37.32617 197.66943 -37.17383 c\r197.78809 -37.02148 197.96875 -36.88477 198.20996 -36.76563 c\r198.31885 -36.71387 198.47559 -36.64551 198.68018 -36.56055 c\r198.88477 -36.47559 199.08398 -36.40723 199.27832 -36.35254 c\r199.56689 -36.54297 199.76611 -36.74219 199.87744 -36.94922 c\r199.98779 -37.15527 200.04346 -37.39355 200.04346 -37.66406 c\rh\r200.18115 -34.41797 m\r200.18115 -34.68359 200.12109 -34.89746 200.00195 -35.05859 c\r199.88281 -35.21973 199.64941 -35.38086 199.30176 -35.54297 c\r199.1626 -35.60742 199.01074 -35.66602 198.8457 -35.72168 c\r198.68066 -35.77637 198.46094 -35.85449 198.1875 -35.95117 c\r197.92334 -35.81055 197.71143 -35.61621 197.55176 -35.37402 c\r197.39209 -35.13086 197.3125 -34.85449 197.3125 -34.54883 c\r197.3125 -34.15625 197.44922 -33.83398 197.72314 -33.57813 c\r197.99609 -33.32324 198.34326 -33.19531 198.76465 -33.19531 c\r199.19385 -33.19531 199.53711 -33.30469 199.79492 -33.52148 c\r200.05225 -33.73926 200.18115 -34.03809 200.18115 -34.41797 c\rh\r201.09668 -34.50195 m\r201.09668 -33.94336 200.875 -33.47852 200.43018 -33.1084 c\r199.98633 -32.73926 199.42725 -32.55273 198.75488 -32.55273 c\r198.04053 -32.55273 197.47217 -32.73438 197.04834 -33.09668 c\r196.62451 -33.45801 196.41309 -33.9209 196.41309 -34.48438 c\r196.41309 -34.84375 196.51904 -35.16797 196.73193 -35.45996 c\r196.94434 -35.75098 197.24365 -35.98047 197.63037 -36.15137 c\r197.63037 -36.15137 197.63037 -36.17871 197.63037 -36.17871 c\r197.27588 -36.3623 197.01514 -36.56445 196.84521 -36.78613 c\r196.67627 -37.00488 196.59131 -37.2793 196.59131 -37.61035 c\r196.59131 -38.0957 196.79492 -38.50195 197.20166 -38.8252 c\r197.60938 -39.14941 198.12646 -39.3125 198.75488 -39.3125 c\r199.41309 -39.3125 199.9375 -39.15723 200.32959 -38.84766 c\r200.72217 -38.53809 200.91797 -38.14453 200.91797 -37.66602 c\r200.91797 -37.375 200.82617 -37.08789 200.64063 -36.80469 c\r200.45605 -36.52344 200.18408 -36.30273 199.82568 -36.14355 c\r199.82568 -36.14355 199.82568 -36.11621 199.82568 -36.11621 c\r200.2373 -35.94336 200.55225 -35.72949 200.77002 -35.47461 c\r200.9873 -35.21973 201.09668 -34.89551 201.09668 -34.50195 c\rh\r195.26807 -32.7041 m\r195.26807 -32.7041 190.81104 -32.7041 190.81104 -32.7041 c\r190.81104 -32.7041 190.81104 -33.61523 190.81104 -33.61523 c\r191.12109 -33.875 191.43164 -34.13574 191.74316 -34.39551 c\r192.05469 -34.65625 192.34521 -34.91406 192.61328 -35.17188 c\r193.18018 -35.70996 193.56885 -36.1377 193.77881 -36.45313 c\r193.98828 -36.76953 194.09277 -37.1123 194.09277 -37.47852 c\r194.09277 -37.81445 193.97998 -38.07715 193.75391 -38.26563 c\r193.52783 -38.45508 193.2124 -38.5498 192.80811 -38.5498 c\r192.53857 -38.5498 192.24854 -38.50293 191.93457 -38.40918 c\r191.62158 -38.31641 191.31641 -38.17188 191.01758 -37.97949 c\r191.01758 -37.97949 190.97314 -37.97949 190.97314 -37.97949 c\r190.97314 -37.97949 190.97314 -38.8916 190.97314 -38.8916 c\r191.18262 -38.99316 191.4624 -39.08496 191.81201 -39.16992 c\r192.16162 -39.25488 192.50049 -39.2959 192.82813 -39.2959 c\r193.50391 -39.2959 194.03369 -39.13672 194.41699 -38.81641 c\r194.80078 -38.49805 194.99268 -38.06445 194.99268 -37.51953 c\r194.99268 -37.27344 194.96094 -37.04395 194.89697 -36.83105 c\r194.8335 -36.61914 194.74023 -36.41797 194.61621 -36.22852 c\r194.50146 -36.04883 194.36621 -35.87305 194.21143 -35.69922 c\r194.05664 -35.52539 193.86865 -35.33398 193.64697 -35.12305 c\r193.33154 -34.81934 193.00537 -34.52539 192.66992 -34.24121 c\r192.33301 -33.95605 192.01904 -33.69238 191.72705 -33.44922 c\r191.72705 -33.44922 195.26807 -33.44922 195.26807 -33.44922 c\r195.26807 -33.44922 195.26807 -32.7041 195.26807 -32.7041 c\rh\r189.13135 -32.7041 m\r189.13135 -32.7041 185.55762 -32.7041 185.55762 -32.7041 c\r185.55762 -32.7041 185.55762 -33.36328 185.55762 -33.36328 c\r185.55762 -33.36328 186.93555 -33.36328 186.93555 -33.36328 c\r186.93555 -33.36328 186.93555 -37.69238 186.93555 -37.69238 c\r186.93555 -37.69238 185.55762 -37.69238 185.55762 -37.69238 c\r185.55762 -37.69238 185.55762 -38.28027 185.55762 -38.28027 c\r185.74365 -38.28027 185.94385 -38.2959 186.15723 -38.32715 c\r186.37061 -38.35547 186.53223 -38.40137 186.64111 -38.45898 c\r186.77783 -38.53125 186.88477 -38.62305 186.96387 -38.73535 c\r187.04199 -38.84668 187.08691 -38.99609 187.09961 -39.18457 c\r187.09961 -39.18457 187.78613 -39.18457 187.78613 -39.18457 c\r187.78613 -39.18457 187.78613 -33.36328 187.78613 -33.36328 c\r187.78613 -33.36328 189.13135 -33.36328 189.13135 -33.36328 c\r189.13135 -33.36328 189.13135 -32.7041 189.13135 -32.7041 c\rh\rf\r296.28223 -35.21777 m\r296.28223 -35.21777 296.28223 -38.13477 296.28223 -38.13477 c\r296.28223 -38.13477 293.72461 -35.21777 293.72461 -35.21777 c\r293.72461 -35.21777 296.28223 -35.21777 296.28223 -35.21777 c\rh\r298.11328 -34.51953 m\r298.11328 -34.51953 297.13184 -34.51953 297.13184 -34.51953 c\r297.13184 -34.51953 297.13184 -32.7041 297.13184 -32.7041 c\r297.13184 -32.7041 296.28223 -32.7041 296.28223 -32.7041 c\r296.28223 -32.7041 296.28223 -34.51953 296.28223 -34.51953 c\r296.28223 -34.51953 293.12207 -34.51953 293.12207 -34.51953 c\r293.12207 -34.51953 293.12207 -35.51758 293.12207 -35.51758 c\r293.12207 -35.51758 296.31836 -39.16113 296.31836 -39.16113 c\r296.31836 -39.16113 297.13184 -39.16113 297.13184 -39.16113 c\r297.13184 -39.16113 297.13184 -35.21777 297.13184 -35.21777 c\r297.13184 -35.21777 298.11328 -35.21777 298.11328 -35.21777 c\r298.11328 -35.21777 298.11328 -34.51953 298.11328 -34.51953 c\rh\r291.38477 -34.76563 m\r291.38477 -35.03418 291.34375 -35.25586 291.26465 -35.43164 c\r291.18262 -35.60742 291.04883 -35.75977 290.86328 -35.88965 c\r290.72754 -35.98242 290.57715 -36.04199 290.41211 -36.07129 c\r290.24805 -36.09961 290.0752 -36.11426 289.89551 -36.11426 c\r289.64551 -36.11426 289.41211 -36.08594 289.19727 -36.02734 c\r288.98145 -35.9707 288.76172 -35.88086 288.53418 -35.76172 c\r288.52832 -35.69727 288.52441 -35.63477 288.52148 -35.57715 c\r288.5166 -35.51758 288.51563 -35.44336 288.51563 -35.35449 c\r288.51563 -34.89746 288.56348 -34.53809 288.65918 -34.27637 c\r288.75586 -34.01172 288.8877 -33.80273 289.05566 -33.65039 c\r289.19043 -33.52441 289.33691 -33.43066 289.49609 -33.37109 c\r289.65234 -33.31348 289.8252 -33.28223 290.01074 -33.28223 c\r290.4375 -33.28223 290.77344 -33.41016 291.01758 -33.66602 c\r291.2627 -33.9209 291.38477 -34.28711 291.38477 -34.76563 c\rh\r292.28418 -34.79883 m\r292.28418 -34.1416 292.06348 -33.60645 291.62207 -33.19141 c\r291.18066 -32.77637 290.63965 -32.56934 289.99902 -32.56934 c\r289.6748 -32.56934 289.37891 -32.61816 289.11328 -32.7168 c\r288.84766 -32.81543 288.61328 -32.96094 288.40918 -33.1543 c\r288.15625 -33.39551 287.95996 -33.71387 287.82227 -34.10938 c\r287.68555 -34.50586 287.61719 -34.9834 287.61719 -35.54199 c\r287.61719 -36.11426 287.67969 -36.62305 287.80469 -37.06543 c\r287.93066 -37.50879 288.13086 -37.90137 288.40527 -38.24609 c\r288.66504 -38.57324 289.00098 -38.8291 289.41113 -39.0127 c\r289.82227 -39.19629 290.30078 -39.28711 290.84766 -39.28711 c\r291.02051 -39.28711 291.16699 -39.28125 291.28516 -39.2666 c\r291.40332 -39.25195 291.52344 -39.22559 291.64355 -39.18848 c\r291.64355 -39.18848 291.64355 -38.36035 291.64355 -38.36035 c\r291.64355 -38.36035 291.60059 -38.36035 291.60059 -38.36035 c\r291.5166 -38.40332 291.39258 -38.44434 291.22559 -38.48438 c\r291.05859 -38.52344 290.88965 -38.54199 290.71582 -38.54199 c\r290.08105 -38.54199 289.5752 -38.34766 289.19824 -37.95703 c\r288.82031 -37.56738 288.60059 -37.04199 288.53906 -36.37793 c\r288.78613 -36.52539 289.0293 -36.63672 289.27148 -36.71387 c\r289.51074 -36.79004 289.78906 -36.8291 290.10449 -36.8291 c\r290.38379 -36.8291 290.63086 -36.80371 290.8457 -36.75293 c\r291.05762 -36.70215 291.27734 -36.59961 291.50195 -36.44727 c\r291.76074 -36.27051 291.95605 -36.04883 292.08789 -35.78027 c\r292.21875 -35.51074 292.28418 -35.18262 292.28418 -34.79883 c\rh\rf\r397.52246 -32.7041 m\r397.52246 -32.7041 393.06641 -32.7041 393.06641 -32.7041 c\r393.06641 -32.7041 393.06641 -33.61523 393.06641 -33.61523 c\r393.37695 -33.875 393.68652 -34.13574 393.99805 -34.39551 c\r394.31055 -34.65625 394.59961 -34.91406 394.86816 -35.17188 c\r395.43555 -35.70996 395.82227 -36.1377 396.0332 -36.45313 c\r396.24219 -36.76953 396.34766 -37.1123 396.34766 -37.47852 c\r396.34766 -37.81445 396.23438 -38.07715 396.00781 -38.26563 c\r395.7832 -38.45508 395.46777 -38.5498 395.0625 -38.5498 c\r394.79297 -38.5498 394.50293 -38.50293 394.18945 -38.40918 c\r393.87598 -38.31641 393.57031 -38.17188 393.27148 -37.97949 c\r393.27148 -37.97949 393.22656 -37.97949 393.22656 -37.97949 c\r393.22656 -37.97949 393.22656 -38.8916 393.22656 -38.8916 c\r393.4375 -38.99316 393.7168 -39.08496 394.06641 -39.16992 c\r394.41602 -39.25488 394.75488 -39.2959 395.08203 -39.2959 c\r395.75879 -39.2959 396.28809 -39.13672 396.67188 -38.81641 c\r397.05566 -38.49805 397.24707 -38.06445 397.24707 -37.51953 c\r397.24707 -37.27344 397.21484 -37.04395 397.15137 -36.83105 c\r397.08789 -36.61914 396.99512 -36.41797 396.87109 -36.22852 c\r396.75488 -36.04883 396.62109 -35.87305 396.4668 -35.69922 c\r396.31152 -35.52539 396.12305 -35.33398 395.90234 -35.12305 c\r395.58594 -34.81934 395.26074 -34.52539 394.92383 -34.24121 c\r394.58789 -33.95605 394.27441 -33.69238 393.98242 -33.44922 c\r393.98242 -33.44922 397.52246 -33.44922 397.52246 -33.44922 c\r397.52246 -33.44922 397.52246 -32.7041 397.52246 -32.7041 c\rh\r391.18164 -35.81543 m\r391.32227 -35.69141 391.44043 -35.53418 391.53223 -35.3457 c\r391.62402 -35.1582 391.66895 -34.91504 391.66895 -34.61719 c\r391.66895 -34.32129 391.61523 -34.05176 391.50488 -33.80566 c\r391.39551 -33.55957 391.24219 -33.34668 391.04395 -33.16406 c\r390.82227 -32.96094 390.56152 -32.81152 390.26172 -32.71387 c\r389.96094 -32.61719 389.63184 -32.56934 389.27344 -32.56934 c\r388.90723 -32.56934 388.54785 -32.6123 388.19141 -32.69727 c\r387.83691 -32.78223 387.5459 -32.87598 387.31738 -32.97754 c\r387.31738 -32.97754 387.31738 -33.88574 387.31738 -33.88574 c\r387.31738 -33.88574 387.38477 -33.88574 387.38477 -33.88574 c\r387.63672 -33.72266 387.93262 -33.58594 388.27441 -33.47656 c\r388.61328 -33.36914 388.94238 -33.31543 389.25977 -33.31543 c\r389.44629 -33.31543 389.64453 -33.3457 389.85449 -33.40625 c\r390.06543 -33.4668 390.23535 -33.55664 390.36621 -33.67676 c\r390.50195 -33.80371 390.60352 -33.94434 390.66992 -34.09863 c\r390.73633 -34.25195 390.76953 -34.44727 390.76953 -34.68164 c\r390.76953 -34.91406 390.73242 -35.10645 390.65625 -35.25977 c\r390.58008 -35.41113 390.47559 -35.53125 390.34277 -35.61914 c\r390.20801 -35.70801 390.04785 -35.76953 389.85645 -35.80273 c\r389.66699 -35.83691 389.46191 -35.85352 389.24316 -35.85352 c\r389.24316 -35.85352 388.8418 -35.85352 388.8418 -35.85352 c\r388.8418 -35.85352 388.8418 -36.56738 388.8418 -36.56738 c\r388.8418 -36.56738 389.15332 -36.56738 389.15332 -36.56738 c\r389.60254 -36.56738 389.96191 -36.66016 390.23047 -36.84375 c\r390.49805 -37.02734 390.63281 -37.2959 390.63281 -37.64941 c\r390.63281 -37.80664 390.59863 -37.94336 390.53027 -38.06055 c\r390.46191 -38.17773 390.36816 -38.27539 390.24609 -38.34961 c\r390.11914 -38.42578 389.98438 -38.47754 389.83887 -38.50684 c\r389.69336 -38.53516 389.53027 -38.5498 389.34668 -38.5498 c\r389.06641 -38.5498 388.76758 -38.5 388.45117 -38.40137 c\r388.13574 -38.30078 387.83691 -38.16113 387.55664 -37.97949 c\r387.55664 -37.97949 387.5127 -37.97949 387.5127 -37.97949 c\r387.5127 -37.97949 387.5127 -38.88672 387.5127 -38.88672 c\r387.72168 -38.98828 388.00293 -39.08203 388.35156 -39.16797 c\r388.70215 -39.25195 389.04199 -39.2959 389.36914 -39.2959 c\r389.69043 -39.2959 389.97461 -39.2666 390.2207 -39.20898 c\r390.46484 -39.15137 390.6875 -39.05859 390.88477 -38.93262 c\r391.09766 -38.79297 391.25879 -38.625 391.36719 -38.42773 c\r391.47754 -38.23242 391.53223 -38.00293 391.53223 -37.74023 c\r391.53223 -37.38086 391.40234 -37.06934 391.14453 -36.80078 c\r390.88477 -36.53418 390.5791 -36.36523 390.22754 -36.2959 c\r390.22754 -36.2959 390.22754 -36.23633 390.22754 -36.23633 c\r390.37012 -36.21289 390.53223 -36.16406 390.71582 -36.09082 c\r390.89844 -36.01758 391.05469 -35.9248 391.18164 -35.81543 c\rh\rf\rQ\rq\r1 0 0 -1 0 0 cm\r178.88037 -13.91992 m\r178.88037 -13.91992 306.45703 -13.91992 306.45703 -13.91992 c\r306.45703 -13.91992 306.45703 -28.13477 306.45703 -28.13477 c\r306.45703 -28.13477 178.88037 -28.13477 178.88037 -28.13477 c\r178.88037 -28.13477 178.88037 -13.91992 178.88037 -13.91992 c\rh\rW n\r0 0 0 rg\r0 i \r/GS0 gs\r302.11914 -18.81152 m\r302.11914 -18.81152 302.11914 -21.20605 302.11914 -21.20605 c\r302.00684 -21.25293 301.88867 -21.28613 301.76465 -21.30566 c\r301.64063 -21.3252 301.52734 -21.33594 301.42383 -21.33594 c\r301.00488 -21.33594 300.69043 -21.20801 300.47949 -20.95215 c\r300.27051 -20.69531 300.16602 -20.33984 300.16602 -19.88574 c\r300.16602 -19.40625 300.25 -19.05957 300.41797 -18.84473 c\r300.58691 -18.62793 300.85645 -18.52051 301.22754 -18.52051 c\r301.37402 -18.52051 301.52734 -18.54688 301.68848 -18.60059 c\r301.85156 -18.6543 301.99414 -18.72461 302.11914 -18.81152 c\rh\r303.71484 -17.47266 m\r303.71484 -17.47266 302.11914 -17.47266 302.11914 -17.47266 c\r302.11914 -17.47266 302.11914 -17.98145 302.11914 -17.98145 c\r301.84375 -17.76074 301.58594 -17.59863 301.34668 -17.49414 c\r301.10645 -17.39063 300.8291 -17.33887 300.51563 -17.33887 c\r299.9082 -17.33887 299.42383 -17.56738 299.05957 -18.02441 c\r298.69531 -18.48145 298.5127 -19.09668 298.5127 -19.87109 c\r298.5127 -20.28516 298.57422 -20.65234 298.69727 -20.97168 c\r298.81934 -21.29004 298.98828 -21.56543 299.20117 -21.79395 c\r299.40234 -22.01074 299.64648 -22.17871 299.93262 -22.29883 c\r300.2207 -22.41797 300.50879 -22.47852 300.7959 -22.47852 c\r301.09375 -22.47852 301.33887 -22.44727 301.53027 -22.38574 c\r301.7207 -22.32324 301.91699 -22.24512 302.11914 -22.14941 c\r302.11914 -22.14941 302.11914 -24.22363 302.11914 -24.22363 c\r302.11914 -24.22363 303.71484 -24.22363 303.71484 -24.22363 c\r303.71484 -24.22363 303.71484 -17.47266 303.71484 -17.47266 c\rh\r295.76855 -18.72168 m\r295.87109 -18.84668 295.94922 -18.99512 296.00098 -19.1709 c\r296.05273 -19.34668 296.07813 -19.58789 296.07813 -19.89844 c\r296.07813 -20.18457 296.05176 -20.4248 295.99805 -20.61816 c\r295.94531 -20.81152 295.87109 -20.96582 295.77637 -21.08203 c\r295.68164 -21.20215 295.56836 -21.28418 295.43555 -21.33398 c\r295.30176 -21.38379 295.1582 -21.4082 295.00488 -21.4082 c\r294.85156 -21.4082 294.71387 -21.3877 294.59473 -21.34766 c\r294.47461 -21.30664 294.35938 -21.22559 294.25098 -21.10449 c\r294.15234 -20.99121 294.0752 -20.83594 294.01758 -20.63965 c\r293.95996 -20.44336 293.93066 -20.19531 293.93066 -19.89844 c\r293.93066 -19.63184 293.95703 -19.40039 294.00586 -19.20605 c\r294.05664 -19.00977 294.12988 -18.85254 294.22949 -18.73535 c\r294.32324 -18.62109 294.43555 -18.53906 294.56738 -18.4873 c\r294.69922 -18.43555 294.84961 -18.40918 295.01855 -18.40918 c\r295.16309 -18.40918 295.30078 -18.43359 295.43164 -18.48145 c\r295.56445 -18.52832 295.67676 -18.60938 295.76855 -18.72168 c\rh\r297.73145 -19.90625 m\r297.73145 -19.10547 297.49316 -18.47461 297.01563 -18.01465 c\r296.53809 -17.55371 295.86719 -17.32227 295.00488 -17.32227 c\r294.14258 -17.32227 293.4707 -17.55371 292.99414 -18.01465 c\r292.5166 -18.47461 292.27734 -19.10547 292.27734 -19.90625 c\r292.27734 -20.71191 292.51855 -21.34668 292.99805 -21.80469 c\r293.47852 -22.26563 294.14746 -22.49512 295.00488 -22.49512 c\r295.87305 -22.49512 296.54492 -22.26367 297.01953 -21.80078 c\r297.49414 -21.33789 297.73145 -20.70703 297.73145 -19.90625 c\rh\r291.18066 -17.47266 m\r291.18066 -17.47266 289.58398 -17.47266 289.58398 -17.47266 c\r289.58398 -17.47266 289.58398 -19.88965 289.58398 -19.88965 c\r289.58398 -20.08594 289.57324 -20.28223 289.55273 -20.47852 c\r289.53223 -20.67285 289.49707 -20.81738 289.44531 -20.90918 c\r289.38672 -21.01563 289.2998 -21.09473 289.18555 -21.14355 c\r289.07129 -21.19336 288.91211 -21.21777 288.70703 -21.21777 c\r288.56152 -21.21777 288.41406 -21.19434 288.26465 -21.14844 c\r288.11426 -21.10254 287.95117 -21.02832 287.77637 -20.92676 c\r287.77637 -20.92676 287.77637 -17.47266 287.77637 -17.47266 c\r287.77637 -17.47266 286.18066 -17.47266 286.18066 -17.47266 c\r286.18066 -17.47266 286.18066 -24.22363 286.18066 -24.22363 c\r286.18066 -24.22363 287.77637 -24.22363 287.77637 -24.22363 c\r287.77637 -24.22363 287.77637 -21.80664 287.77637 -21.80664 c\r288.06055 -22.02344 288.33203 -22.18945 288.59473 -22.30469 c\r288.85645 -22.4209 289.14648 -22.47852 289.46582 -22.47852 c\r290.00293 -22.47852 290.42383 -22.3252 290.72559 -22.01953 c\r291.0293 -21.71191 291.18066 -21.25391 291.18066 -20.64355 c\r291.18066 -20.64355 291.18066 -17.47266 291.18066 -17.47266 c\rh\r285.21875 -17.5166 m\r285.04785 -17.47266 284.86621 -17.43945 284.67383 -17.41504 c\r284.48145 -17.39063 284.24707 -17.37793 283.96973 -17.37793 c\r283.34961 -17.37793 282.88867 -17.50195 282.58594 -17.74805 c\r282.28223 -17.99316 282.13281 -18.41406 282.13281 -19.00977 c\r282.13281 -19.00977 282.13281 -21.28809 282.13281 -21.28809 c\r282.13281 -21.28809 281.47656 -21.28809 281.47656 -21.28809 c\r281.47656 -21.28809 281.47656 -22.34375 281.47656 -22.34375 c\r281.47656 -22.34375 282.13281 -22.34375 282.13281 -22.34375 c\r282.13281 -22.34375 282.13281 -23.74023 282.13281 -23.74023 c\r282.13281 -23.74023 283.72852 -23.74023 283.72852 -23.74023 c\r283.72852 -23.74023 283.72852 -22.34375 283.72852 -22.34375 c\r283.72852 -22.34375 285.21875 -22.34375 285.21875 -22.34375 c\r285.21875 -22.34375 285.21875 -21.28809 285.21875 -21.28809 c\r285.21875 -21.28809 283.72852 -21.28809 283.72852 -21.28809 c\r283.72852 -21.28809 283.72852 -19.55664 283.72852 -19.55664 c\r283.72852 -19.38477 283.72949 -19.23535 283.73242 -19.1084 c\r283.73535 -18.98047 283.75879 -18.86523 283.80371 -18.76367 c\r283.84473 -18.66309 283.91699 -18.58203 284.02246 -18.52246 c\r284.12695 -18.46289 284.2793 -18.43359 284.47949 -18.43359 c\r284.5625 -18.43359 284.66992 -18.45117 284.80469 -18.48633 c\r284.93945 -18.52246 285.0332 -18.55469 285.08594 -18.58398 c\r285.08594 -18.58398 285.21875 -18.58398 285.21875 -18.58398 c\r285.21875 -18.58398 285.21875 -17.5166 285.21875 -17.5166 c\rh\r279.33008 -20.53516 m\r279.32129 -20.8623 279.23828 -21.10645 279.08203 -21.27148 c\r278.92578 -21.4375 278.68066 -21.51953 278.34961 -21.51953 c\r278.04395 -21.51953 277.79004 -21.44141 277.5918 -21.28418 c\r277.39453 -21.12891 277.28418 -20.87988 277.25977 -20.53516 c\r277.25977 -20.53516 279.33008 -20.53516 279.33008 -20.53516 c\rh\r280.91895 -19.62305 m\r280.91895 -19.62305 277.26367 -19.62305 277.26367 -19.62305 c\r277.28809 -19.23828 277.43652 -18.94336 277.70898 -18.73926 c\r277.98438 -18.53516 278.3877 -18.43359 278.9209 -18.43359 c\r279.25781 -18.43359 279.58496 -18.49316 279.90234 -18.61523 c\r280.2168 -18.73535 280.46875 -18.86523 280.65234 -19.00391 c\r280.65234 -19.00391 280.83008 -19.00391 280.83008 -19.00391 c\r280.83008 -19.00391 280.83008 -17.75 280.83008 -17.75 c\r280.46875 -17.6084 280.12891 -17.50586 279.80859 -17.44238 c\r279.49023 -17.37793 279.13574 -17.34668 278.74902 -17.34668 c\r277.74902 -17.34668 276.9834 -17.56641 276.4502 -18.00586 c\r275.91797 -18.44434 275.65137 -19.06934 275.65137 -19.88184 c\r275.65137 -20.68555 275.9043 -21.32129 276.4082 -21.79004 c\r276.91113 -22.25977 277.60156 -22.49512 278.47949 -22.49512 c\r279.29102 -22.49512 279.89844 -22.29492 280.30664 -21.89453 c\r280.71484 -21.49512 280.91895 -20.91992 280.91895 -20.16895 c\r280.91895 -20.16895 280.91895 -19.62305 280.91895 -19.62305 c\rh\r274.41309 -17.47266 m\r274.41309 -17.47266 272.71191 -17.47266 272.71191 -17.47266 c\r272.71191 -17.47266 272.71191 -21.7959 272.71191 -21.7959 c\r272.71191 -21.7959 271.49316 -18.98926 271.49316 -18.98926 c\r271.49316 -18.98926 270.32422 -18.98926 270.32422 -18.98926 c\r270.32422 -18.98926 269.10645 -21.7959 269.10645 -21.7959 c\r269.10645 -21.7959 269.10645 -17.47266 269.10645 -17.47266 c\r269.10645 -17.47266 267.50195 -17.47266 267.50195 -17.47266 c\r267.50195 -17.47266 267.50195 -23.93066 267.50195 -23.93066 c\r267.50195 -23.93066 269.47754 -23.93066 269.47754 -23.93066 c\r269.47754 -23.93066 270.95605 -20.68945 270.95605 -20.68945 c\r270.95605 -20.68945 272.43066 -23.93066 272.43066 -23.93066 c\r272.43066 -23.93066 274.41309 -23.93066 274.41309 -23.93066 c\r274.41309 -23.93066 274.41309 -17.47266 274.41309 -17.47266 c\rh\r263.40527 -20.85254 m\r263.40527 -20.85254 263.2627 -20.85254 263.2627 -20.85254 c\r263.19434 -20.87598 263.08496 -20.89355 262.93457 -20.90625 c\r262.78418 -20.91895 262.65918 -20.9248 262.55859 -20.9248 c\r262.33105 -20.9248 262.13086 -20.90918 261.95703 -20.88184 c\r261.78223 -20.85254 261.5957 -20.80273 261.39355 -20.73242 c\r261.39355 -20.73242 261.39355 -17.47266 261.39355 -17.47266 c\r261.39355 -17.47266 259.79883 -17.47266 259.79883 -17.47266 c\r259.79883 -17.47266 259.79883 -22.34375 259.79883 -22.34375 c\r259.79883 -22.34375 261.39355 -22.34375 261.39355 -22.34375 c\r261.39355 -22.34375 261.39355 -21.62793 261.39355 -21.62793 c\r261.74609 -21.92285 262.05078 -22.11914 262.31152 -22.21582 c\r262.57031 -22.31055 262.80957 -22.36035 263.02734 -22.36035 c\r263.08398 -22.36035 263.14746 -22.3584 263.21875 -22.35547 c\r263.28906 -22.35254 263.35059 -22.34863 263.40527 -22.3418 c\r263.40527 -22.3418 263.40527 -20.85254 263.40527 -20.85254 c\rh\r257.08691 -20.53516 m\r257.07715 -20.8623 256.99414 -21.10645 256.83789 -21.27148 c\r256.68164 -21.4375 256.43701 -21.51953 256.10596 -21.51953 c\r255.79883 -21.51953 255.54639 -21.44141 255.34814 -21.28418 c\r255.1499 -21.12891 255.03906 -20.87988 255.01611 -20.53516 c\r255.01611 -20.53516 257.08691 -20.53516 257.08691 -20.53516 c\rh\r258.67383 -19.62305 m\r258.67383 -19.62305 255.02002 -19.62305 255.02002 -19.62305 c\r255.04443 -19.23828 255.19189 -18.94336 255.46631 -18.73926 c\r255.74072 -18.53516 256.14355 -18.43359 256.67529 -18.43359 c\r257.01318 -18.43359 257.34033 -18.49316 257.65674 -18.61523 c\r257.97412 -18.73535 258.22461 -18.86523 258.4082 -19.00391 c\r258.4082 -19.00391 258.58496 -19.00391 258.58496 -19.00391 c\r258.58496 -19.00391 258.58496 -17.75 258.58496 -17.75 c\r258.22461 -17.6084 257.88477 -17.50586 257.56543 -17.44238 c\r257.24561 -17.37793 256.8916 -17.34668 256.50488 -17.34668 c\r255.50439 -17.34668 254.73877 -17.56641 254.20703 -18.00586 c\r253.67383 -18.44434 253.40674 -19.06934 253.40674 -19.88184 c\r253.40674 -20.68555 253.66016 -21.32129 254.16357 -21.79004 c\r254.66699 -22.25977 255.35889 -22.49512 256.23633 -22.49512 c\r257.0459 -22.49512 257.6543 -22.29492 258.06201 -21.89453 c\r258.47168 -21.49512 258.67383 -20.91992 258.67383 -20.16895 c\r258.67383 -20.16895 258.67383 -19.62305 258.67383 -19.62305 c\rh\r250.8877 -21.85645 m\r250.8877 -22.03711 250.8374 -22.19336 250.7373 -22.3252 c\r250.63818 -22.45605 250.52246 -22.54785 250.38916 -22.60059 c\r250.21191 -22.66797 250.04102 -22.70703 249.87256 -22.71387 c\r249.70557 -22.7207 249.48193 -22.72461 249.20117 -22.72461 c\r249.20117 -22.72461 248.90967 -22.72461 248.90967 -22.72461 c\r248.90967 -22.72461 248.90967 -20.79688 248.90967 -20.79688 c\r248.90967 -20.79688 249.39551 -20.79688 249.39551 -20.79688 c\r249.68457 -20.79688 249.92188 -20.81445 250.1084 -20.84863 c\r250.29541 -20.88379 250.45264 -20.95313 250.5791 -21.05664 c\r250.68799 -21.14844 250.7666 -21.25977 250.81543 -21.3877 c\r250.86426 -21.51563 250.8877 -21.67188 250.8877 -21.85645 c\rh\r252.65381 -21.8916 m\r252.65381 -21.60254 252.60303 -21.31934 252.49951 -21.04395 c\r252.39648 -20.76758 252.24805 -20.53516 252.05615 -20.34766 c\r251.79297 -20.09277 251.50049 -19.90039 251.17627 -19.77051 c\r250.85352 -19.63965 250.45068 -19.57617 249.96924 -19.57617 c\r249.96924 -19.57617 248.90967 -19.57617 248.90967 -19.57617 c\r248.90967 -19.57617 248.90967 -17.47266 248.90967 -17.47266 c\r248.90967 -17.47266 247.20898 -17.47266 247.20898 -17.47266 c\r247.20898 -17.47266 247.20898 -23.93066 247.20898 -23.93066 c\r247.20898 -23.93066 250.00977 -23.93066 250.00977 -23.93066 c\r250.42822 -23.93066 250.78174 -23.89551 251.07129 -23.82422 c\r251.35791 -23.75293 251.61328 -23.64746 251.83447 -23.50488 c\r252.10059 -23.33594 252.30322 -23.11621 252.44482 -22.85059 c\r252.58398 -22.58398 252.65381 -22.26563 252.65381 -21.8916 c\rh\r242.95313 -19.01758 m\r242.95313 -18.51367 242.72314 -18.1084 242.26318 -17.80078 c\r241.80273 -17.49219 241.17188 -17.33887 240.37305 -17.33887 c\r239.93115 -17.33887 239.5293 -17.37891 239.16895 -17.46094 c\r238.80957 -17.54102 238.52002 -17.62988 238.30225 -17.72949 c\r238.30225 -17.72949 238.30225 -19.01172 238.30225 -19.01172 c\r238.30225 -19.01172 238.44775 -19.01172 238.44775 -19.01172 c\r238.52783 -18.95703 238.61963 -18.89746 238.72412 -18.83203 c\r238.82959 -18.7666 238.97705 -18.69629 239.16895 -18.62109 c\r239.33398 -18.55469 239.52197 -18.49805 239.73096 -18.4502 c\r239.94092 -18.40137 240.16504 -18.37793 240.40381 -18.37793 c\r240.71631 -18.37793 240.94824 -18.41211 241.09814 -18.48047 c\r241.24902 -18.54785 241.32373 -18.64941 241.32373 -18.78223 c\r241.32373 -18.90137 241.2793 -18.9873 241.19238 -19.04102 c\r241.10352 -19.09473 240.93604 -19.14648 240.6875 -19.19531 c\r240.56982 -19.2207 240.41016 -19.25 240.20752 -19.2793 c\r240.00586 -19.30957 239.82275 -19.34668 239.65674 -19.38965 c\r239.20654 -19.50586 238.87207 -19.68555 238.65332 -19.93066 c\r238.43506 -20.1748 238.32617 -20.47852 238.32617 -20.84473 c\r238.32617 -21.3125 238.55322 -21.70117 239.00439 -22.0127 c\r239.45752 -22.32324 240.07617 -22.47852 240.85938 -22.47852 c\r241.23096 -22.47852 241.58789 -22.44141 241.92725 -22.36914 c\r242.26904 -22.29492 242.53516 -22.21582 242.72607 -22.13086 c\r242.72607 -22.13086 242.72607 -20.90039 242.72607 -20.90039 c\r242.72607 -20.90039 242.58984 -20.90039 242.58984 -20.90039 c\r242.354 -21.05957 242.08447 -21.18945 241.78271 -21.28906 c\r241.47998 -21.38965 241.17529 -21.43945 240.86621 -21.43945 c\r240.6084 -21.43945 240.39307 -21.4043 240.21826 -21.33496 c\r240.04297 -21.26563 239.9541 -21.16699 239.9541 -21.03809 c\r239.9541 -20.92285 239.99463 -20.83496 240.07422 -20.77441 c\r240.15381 -20.71387 240.34082 -20.65234 240.63623 -20.5918 c\r240.79883 -20.56055 240.97363 -20.52832 241.15918 -20.49902 c\r241.34717 -20.46875 241.53467 -20.42969 241.72412 -20.38379 c\r242.14258 -20.27637 242.45166 -20.10938 242.65234 -19.87891 c\r242.85254 -19.64844 242.95313 -19.36133 242.95313 -19.01758 c\rh\r237.17188 -17.47266 m\r237.17188 -17.47266 235.57617 -17.47266 235.57617 -17.47266 c\r235.57617 -17.47266 235.57617 -19.88965 235.57617 -19.88965 c\r235.57617 -20.08594 235.56494 -20.28223 235.54395 -20.47852 c\r235.52393 -20.67285 235.48828 -20.81738 235.4375 -20.90918 c\r235.37842 -21.01563 235.29053 -21.09473 235.17676 -21.14355 c\r235.0625 -21.19336 234.90381 -21.21777 234.69922 -21.21777 c\r234.55322 -21.21777 234.40576 -21.19434 234.25586 -21.14844 c\r234.10596 -21.10254 233.94336 -21.02832 233.76953 -20.92676 c\r233.76953 -20.92676 233.76953 -17.47266 233.76953 -17.47266 c\r233.76953 -17.47266 232.17188 -17.47266 232.17188 -17.47266 c\r232.17188 -17.47266 232.17188 -22.34375 232.17188 -22.34375 c\r232.17188 -22.34375 233.76953 -22.34375 233.76953 -22.34375 c\r233.76953 -22.34375 233.76953 -21.80664 233.76953 -21.80664 c\r234.05225 -22.02344 234.32471 -22.18945 234.58594 -22.30469 c\r234.84766 -22.4209 235.13818 -22.47852 235.45752 -22.47852 c\r235.99463 -22.47852 236.41553 -22.3252 236.71729 -22.01953 c\r237.02148 -21.71191 237.17188 -21.25391 237.17188 -20.64355 c\r237.17188 -20.64355 237.17188 -17.47266 237.17188 -17.47266 c\rh\r229.0625 -18.72168 m\r229.16699 -18.84668 229.24414 -18.99512 229.2959 -19.1709 c\r229.34766 -19.34668 229.37402 -19.58789 229.37402 -19.89844 c\r229.37402 -20.18457 229.34668 -20.4248 229.29395 -20.61816 c\r229.24072 -20.81152 229.16699 -20.96582 229.07227 -21.08203 c\r228.97705 -21.20215 228.86328 -21.28418 228.72998 -21.33398 c\r228.59766 -21.38379 228.4541 -21.4082 228.2998 -21.4082 c\r228.14551 -21.4082 228.0083 -21.3877 227.88916 -21.34766 c\r227.77002 -21.30664 227.65381 -21.22559 227.54541 -21.10449 c\r227.44727 -20.99121 227.37012 -20.83594 227.31201 -20.63965 c\r227.25537 -20.44336 227.22607 -20.19531 227.22607 -19.89844 c\r227.22607 -19.63184 227.25098 -19.40039 227.30176 -19.20605 c\r227.35254 -19.00977 227.42627 -18.85254 227.52295 -18.73535 c\r227.61816 -18.62109 227.73096 -18.53906 227.86279 -18.4873 c\r227.99414 -18.43555 228.14355 -18.40918 228.31201 -18.40918 c\r228.45801 -18.40918 228.59668 -18.43359 228.72803 -18.48145 c\r228.85889 -18.52832 228.9707 -18.60938 229.0625 -18.72168 c\rh\r231.02588 -19.90625 m\r231.02588 -19.10547 230.7876 -18.47461 230.31104 -18.01465 c\r229.83301 -17.55371 229.1626 -17.32227 228.2998 -17.32227 c\r227.43701 -17.32227 226.76563 -17.55371 226.28857 -18.01465 c\r225.81201 -18.47461 225.57324 -19.10547 225.57324 -19.90625 c\r225.57324 -20.71191 225.81299 -21.34668 226.29297 -21.80469 c\r226.77393 -22.26563 227.44287 -22.49512 228.2998 -22.49512 c\r229.16895 -22.49512 229.84033 -22.26367 230.31494 -21.80078 c\r230.78955 -21.33789 231.02588 -20.70703 231.02588 -19.90625 c\rh\r224.42969 -17.47266 m\r224.42969 -17.47266 222.83447 -17.47266 222.83447 -17.47266 c\r222.83447 -17.47266 222.83447 -22.34375 222.83447 -22.34375 c\r222.83447 -22.34375 224.42969 -22.34375 224.42969 -22.34375 c\r224.42969 -22.34375 224.42969 -17.47266 224.42969 -17.47266 c\rh\r224.4707 -23.04199 m\r224.4707 -23.04199 222.79297 -23.04199 222.79297 -23.04199 c\r222.79297 -23.04199 222.79297 -24.22363 222.79297 -24.22363 c\r222.79297 -24.22363 224.4707 -24.22363 224.4707 -24.22363 c\r224.4707 -24.22363 224.4707 -23.04199 224.4707 -23.04199 c\rh\r221.87207 -17.5166 m\r221.70117 -17.47266 221.52002 -17.43945 221.32764 -17.41504 c\r221.13574 -17.39063 220.90039 -17.37793 220.62305 -17.37793 c\r220.00244 -17.37793 219.5415 -17.50195 219.23828 -17.74805 c\r218.93555 -17.99316 218.78516 -18.41406 218.78516 -19.00977 c\r218.78516 -19.00977 218.78516 -21.28809 218.78516 -21.28809 c\r218.78516 -21.28809 218.12793 -21.28809 218.12793 -21.28809 c\r218.12793 -21.28809 218.12793 -22.34375 218.12793 -22.34375 c\r218.12793 -22.34375 218.78516 -22.34375 218.78516 -22.34375 c\r218.78516 -22.34375 218.78516 -23.74023 218.78516 -23.74023 c\r218.78516 -23.74023 220.37988 -23.74023 220.37988 -23.74023 c\r220.37988 -23.74023 220.37988 -22.34375 220.37988 -22.34375 c\r220.37988 -22.34375 221.87207 -22.34375 221.87207 -22.34375 c\r221.87207 -22.34375 221.87207 -21.28809 221.87207 -21.28809 c\r221.87207 -21.28809 220.37988 -21.28809 220.37988 -21.28809 c\r220.37988 -21.28809 220.37988 -19.55664 220.37988 -19.55664 c\r220.37988 -19.38477 220.38184 -19.23535 220.38574 -19.1084 c\r220.38867 -18.98047 220.41211 -18.86523 220.45654 -18.76367 c\r220.49707 -18.66309 220.57031 -18.58203 220.67578 -18.52246 c\r220.7793 -18.46289 220.93311 -18.43359 221.13379 -18.43359 c\r221.21582 -18.43359 221.32324 -18.45117 221.4585 -18.48633 c\r221.59277 -18.52246 221.68652 -18.55469 221.73926 -18.58398 c\r221.73926 -18.58398 221.87207 -18.58398 221.87207 -18.58398 c\r221.87207 -18.58398 221.87207 -17.5166 221.87207 -17.5166 c\rh\r215.95215 -17.34668 m\r215.51758 -17.34668 215.12061 -17.39648 214.76123 -17.49805 c\r214.40234 -17.59863 214.08936 -17.75586 213.82324 -17.9668 c\r213.56055 -18.17773 213.35645 -18.44434 213.21191 -18.76367 c\r213.06689 -19.08398 212.99463 -19.45996 212.99463 -19.89063 c\r212.99463 -20.34473 213.07178 -20.7373 213.22705 -21.06543 c\r213.38232 -21.39551 213.59863 -21.66895 213.87646 -21.88574 c\r214.146 -22.08984 214.45605 -22.24121 214.80762 -22.33594 c\r215.15918 -22.43066 215.52441 -22.47852 215.90283 -22.47852 c\r216.24268 -22.47852 216.55615 -22.44336 216.84326 -22.37109 c\r217.12939 -22.29883 217.39697 -22.20313 217.64551 -22.08789 c\r217.64551 -22.08789 217.64551 -20.75781 217.64551 -20.75781 c\r217.64551 -20.75781 217.41992 -20.75781 217.41992 -20.75781 c\r217.35791 -20.80957 217.2832 -20.86914 217.1958 -20.93848 c\r217.10889 -21.00781 217.00195 -21.07422 216.875 -21.14063 c\r216.75391 -21.2041 216.62061 -21.25684 216.47607 -21.29785 c\r216.33203 -21.33984 216.16357 -21.36035 215.97119 -21.36035 c\r215.54639 -21.36035 215.21924 -21.22852 214.99072 -20.96484 c\r214.76172 -20.70215 214.64697 -20.34375 214.64697 -19.89063 c\r214.64697 -19.4248 214.76416 -19.06934 214.99902 -18.82813 c\r215.23438 -18.58594 215.56689 -18.46484 215.99805 -18.46484 c\r216.19873 -18.46484 216.37988 -18.4873 216.54053 -18.53027 c\r216.70166 -18.57617 216.83545 -18.62793 216.94141 -18.6875 c\r217.04199 -18.74512 217.13037 -18.80566 217.20703 -18.86719 c\r217.28418 -18.93066 217.35449 -18.99121 217.41992 -19.05078 c\r217.41992 -19.05078 217.64551 -19.05078 217.64551 -19.05078 c\r217.64551 -19.05078 217.64551 -17.72266 217.64551 -17.72266 c\r217.39453 -17.60742 217.13184 -17.5166 216.8584 -17.44824 c\r216.58496 -17.37988 216.28271 -17.34668 215.95215 -17.34668 c\rh\r211.85596 -17.47266 m\r211.85596 -17.47266 210.25977 -17.47266 210.25977 -17.47266 c\r210.25977 -17.47266 210.25977 -18.00977 210.25977 -18.00977 c\r209.96387 -17.79102 209.69434 -17.62402 209.44873 -17.50977 c\r209.20361 -17.39551 208.91113 -17.33887 208.57129 -17.33887 c\r208.02197 -17.33887 207.59863 -17.49316 207.30176 -17.80273 c\r207.00537 -18.11133 206.85645 -18.56836 206.85645 -19.17285 c\r206.85645 -19.17285 206.85645 -22.34375 206.85645 -22.34375 c\r206.85645 -22.34375 208.45264 -22.34375 208.45264 -22.34375 c\r208.45264 -22.34375 208.45264 -19.92676 208.45264 -19.92676 c\r208.45264 -19.68164 208.46143 -19.47656 208.47754 -19.31348 c\r208.49365 -19.15039 208.53174 -19.01367 208.59082 -18.90723 c\r208.64746 -18.80078 208.73242 -18.72266 208.84668 -18.67285 c\r208.96094 -18.62402 209.12012 -18.59961 209.32568 -18.59961 c\r209.4624 -18.59961 209.61279 -18.62402 209.77881 -18.67285 c\r209.94531 -18.72266 210.10547 -18.79492 210.25977 -18.88965 c\r210.25977 -18.88965 210.25977 -22.34375 210.25977 -22.34375 c\r210.25977 -22.34375 211.85596 -22.34375 211.85596 -22.34375 c\r211.85596 -22.34375 211.85596 -17.47266 211.85596 -17.47266 c\rh\r205.99219 -20.85254 m\r205.99219 -20.85254 205.85107 -20.85254 205.85107 -20.85254 c\r205.78271 -20.87598 205.67334 -20.89355 205.52344 -20.90625 c\r205.37305 -20.91895 205.24756 -20.9248 205.14746 -20.9248 c\r204.91992 -20.9248 204.71924 -20.90918 204.54541 -20.88184 c\r204.37109 -20.85254 204.18311 -20.80273 203.98291 -20.73242 c\r203.98291 -20.73242 203.98291 -17.47266 203.98291 -17.47266 c\r203.98291 -17.47266 202.38672 -17.47266 202.38672 -17.47266 c\r202.38672 -17.47266 202.38672 -22.34375 202.38672 -22.34375 c\r202.38672 -22.34375 203.98291 -22.34375 203.98291 -22.34375 c\r203.98291 -22.34375 203.98291 -21.62793 203.98291 -21.62793 c\r204.33447 -21.92285 204.63965 -22.11914 204.89941 -22.21582 c\r205.15869 -22.31055 205.39795 -22.36035 205.61621 -22.36035 c\r205.67188 -22.36035 205.73584 -22.3584 205.80664 -22.35547 c\r205.87744 -22.35254 205.93945 -22.34863 205.99219 -22.3418 c\r205.99219 -22.3418 205.99219 -20.85254 205.99219 -20.85254 c\rh\r201.4248 -17.5166 m\r201.25342 -17.47266 201.07178 -17.43945 200.87988 -17.41504 c\r200.6875 -17.39063 200.45313 -17.37793 200.17529 -17.37793 c\r199.55518 -17.37793 199.09424 -17.50195 198.7915 -17.74805 c\r198.48877 -17.99316 198.3374 -18.41406 198.3374 -19.00977 c\r198.3374 -19.00977 198.3374 -21.28809 198.3374 -21.28809 c\r198.3374 -21.28809 197.68066 -21.28809 197.68066 -21.28809 c\r197.68066 -21.28809 197.68066 -22.34375 197.68066 -22.34375 c\r197.68066 -22.34375 198.3374 -22.34375 198.3374 -22.34375 c\r198.3374 -22.34375 198.3374 -23.74023 198.3374 -23.74023 c\r198.3374 -23.74023 199.93408 -23.74023 199.93408 -23.74023 c\r199.93408 -23.74023 199.93408 -22.34375 199.93408 -22.34375 c\r199.93408 -22.34375 201.4248 -22.34375 201.4248 -22.34375 c\r201.4248 -22.34375 201.4248 -21.28809 201.4248 -21.28809 c\r201.4248 -21.28809 199.93408 -21.28809 199.93408 -21.28809 c\r199.93408 -21.28809 199.93408 -19.55664 199.93408 -19.55664 c\r199.93408 -19.38477 199.93506 -19.23535 199.93799 -19.1084 c\r199.94092 -18.98047 199.96436 -18.86523 200.00879 -18.76367 c\r200.05029 -18.66309 200.12354 -18.58203 200.22803 -18.52246 c\r200.33252 -18.46289 200.48535 -18.43359 200.68555 -18.43359 c\r200.76855 -18.43359 200.87695 -18.45117 201.01172 -18.48633 c\r201.14502 -18.52246 201.23828 -18.55469 201.29199 -18.58398 c\r201.29199 -18.58398 201.4248 -18.58398 201.4248 -18.58398 c\r201.4248 -18.58398 201.4248 -17.5166 201.4248 -17.5166 c\rh\r197.18555 -19.01758 m\r197.18555 -18.51367 196.95557 -18.1084 196.49512 -17.80078 c\r196.03516 -17.49219 195.40527 -17.33887 194.60498 -17.33887 c\r194.1626 -17.33887 193.76172 -17.37891 193.40186 -17.46094 c\r193.0415 -17.54102 192.75244 -17.62988 192.53418 -17.72949 c\r192.53418 -17.72949 192.53418 -19.01172 192.53418 -19.01172 c\r192.53418 -19.01172 192.68018 -19.01172 192.68018 -19.01172 c\r192.75977 -18.95703 192.85254 -18.89746 192.95703 -18.83203 c\r193.06152 -18.7666 193.20996 -18.69629 193.40186 -18.62109 c\r193.56738 -18.55469 193.75439 -18.49805 193.96387 -18.4502 c\r194.17334 -18.40137 194.39697 -18.37793 194.63672 -18.37793 c\r194.94922 -18.37793 195.18066 -18.41211 195.33154 -18.48047 c\r195.48145 -18.54785 195.55664 -18.64941 195.55664 -18.78223 c\r195.55664 -18.90137 195.51221 -18.9873 195.42432 -19.04102 c\r195.33545 -19.09473 195.16797 -19.14648 194.92041 -19.19531 c\r194.80225 -19.2207 194.64209 -19.25 194.43994 -19.2793 c\r194.23828 -19.30957 194.05518 -19.34668 193.88965 -19.38965 c\r193.43848 -19.50586 193.104 -19.68555 192.88574 -19.93066 c\r192.66748 -20.1748 192.55811 -20.47852 192.55811 -20.84473 c\r192.55811 -21.3125 192.78467 -21.70117 193.2373 -22.0127 c\r193.68994 -22.32324 194.30859 -22.47852 195.09229 -22.47852 c\r195.46387 -22.47852 195.81982 -22.44141 196.16016 -22.36914 c\r196.50049 -22.29492 196.76758 -22.21582 196.95898 -22.13086 c\r196.95898 -22.13086 196.95898 -20.90039 196.95898 -20.90039 c\r196.95898 -20.90039 196.82129 -20.90039 196.82129 -20.90039 c\r196.58594 -21.05957 196.31689 -21.18945 196.01465 -21.28906 c\r195.71289 -21.38965 195.40723 -21.43945 195.09814 -21.43945 c\r194.8418 -21.43945 194.625 -21.4043 194.4502 -21.33496 c\r194.2749 -21.26563 194.1875 -21.16699 194.1875 -21.03809 c\r194.1875 -20.92285 194.22705 -20.83496 194.30664 -20.77441 c\r194.38623 -20.71387 194.57373 -20.65234 194.86865 -20.5918 c\r195.03076 -20.56055 195.20508 -20.52832 195.39209 -20.49902 c\r195.57959 -20.46875 195.76709 -20.42969 195.95654 -20.38379 c\r196.375 -20.27637 196.68457 -20.10938 196.88477 -19.87891 c\r197.08496 -19.64844 197.18555 -19.36133 197.18555 -19.01758 c\rh\r191.40381 -17.47266 m\r191.40381 -17.47266 189.80859 -17.47266 189.80859 -17.47266 c\r189.80859 -17.47266 189.80859 -19.88965 189.80859 -19.88965 c\r189.80859 -20.08594 189.79785 -20.28223 189.77686 -20.47852 c\r189.75586 -20.67285 189.72021 -20.81738 189.67041 -20.90918 c\r189.61035 -21.01563 189.52393 -21.09473 189.40918 -21.14355 c\r189.29541 -21.19336 189.13574 -21.21777 188.93164 -21.21777 c\r188.78564 -21.21777 188.63818 -21.19434 188.48828 -21.14844 c\r188.33838 -21.10254 188.17578 -21.02832 188.00098 -20.92676 c\r188.00098 -20.92676 188.00098 -17.47266 188.00098 -17.47266 c\r188.00098 -17.47266 186.40479 -17.47266 186.40479 -17.47266 c\r186.40479 -17.47266 186.40479 -22.34375 186.40479 -22.34375 c\r186.40479 -22.34375 188.00098 -22.34375 188.00098 -22.34375 c\r188.00098 -22.34375 188.00098 -21.80664 188.00098 -21.80664 c\r188.28467 -22.02344 188.55713 -22.18945 188.81885 -22.30469 c\r189.08008 -22.4209 189.37061 -22.47852 189.68945 -22.47852 c\r190.22754 -22.47852 190.64697 -22.3252 190.9502 -22.01953 c\r191.25293 -21.71191 191.40381 -21.25391 191.40381 -20.64355 c\r191.40381 -20.64355 191.40381 -17.47266 191.40381 -17.47266 c\rh\r185.104 -17.47266 m\r185.104 -17.47266 181.24658 -17.47266 181.24658 -17.47266 c\r181.24658 -17.47266 181.24658 -18.61523 181.24658 -18.61523 c\r181.24658 -18.61523 182.32471 -18.61523 182.32471 -18.61523 c\r182.32471 -18.61523 182.32471 -22.78809 182.32471 -22.78809 c\r182.32471 -22.78809 181.24658 -22.78809 181.24658 -22.78809 c\r181.24658 -22.78809 181.24658 -23.93066 181.24658 -23.93066 c\r181.24658 -23.93066 185.104 -23.93066 185.104 -23.93066 c\r185.104 -23.93066 185.104 -22.78809 185.104 -22.78809 c\r185.104 -22.78809 184.02637 -22.78809 184.02637 -22.78809 c\r184.02637 -22.78809 184.02637 -18.61523 184.02637 -18.61523 c\r184.02637 -18.61523 185.104 -18.61523 185.104 -18.61523 c\r185.104 -18.61523 185.104 -17.47266 185.104 -17.47266 c\rh\rf\rQ\rq\r1 0 0 -1 0 0 cm\r16.29932 -126.37109 m\r16.29932 -126.37109 27.18945 -126.37109 27.18945 -126.37109 c\r27.18945 -126.37109 27.18945 -167.74854 27.18945 -167.74854 c\r27.18945 -167.74854 16.29932 -167.74854 16.29932 -167.74854 c\r16.29932 -167.74854 16.29932 -126.37109 16.29932 -126.37109 c\rh\rW n\r0 0 0 rg\r0 i \r/GS0 gs\r24.00732 -160.14307 m\r24.00732 -160.14307 21.56152 -160.14307 21.56152 -160.14307 c\r21.51416 -160.03369 21.47998 -159.91797 21.45947 -159.79688 c\r21.43896 -159.67529 21.42822 -159.56396 21.42822 -159.4624 c\r21.42822 -159.05273 21.55908 -158.74463 21.82129 -158.53906 c\r22.08301 -158.33398 22.44678 -158.23145 22.91162 -158.23145 c\r23.39941 -158.23145 23.75391 -158.31396 23.97412 -158.47852 c\r24.19482 -158.64355 24.30518 -158.90771 24.30518 -159.27197 c\r24.30518 -159.41357 24.27734 -159.56396 24.22266 -159.72266 c\r24.16846 -159.88184 24.09668 -160.02197 24.00732 -160.14307 c\rh\r24.09912 -147.60059 m\r23.97217 -147.70117 23.81934 -147.77734 23.64014 -147.82813 c\r23.46143 -147.87891 23.21436 -147.9043 22.89795 -147.9043 c\r22.60547 -147.9043 22.35986 -147.87793 22.16211 -147.82617 c\r21.96436 -147.77344 21.80615 -147.70117 21.68799 -147.60938 c\r21.56689 -147.5166 21.48096 -147.4043 21.43115 -147.27441 c\r21.38086 -147.14453 21.35547 -147.00391 21.35547 -146.85352 c\r21.35547 -146.70313 21.37598 -146.56934 21.41699 -146.45215 c\r21.45898 -146.33496 21.54199 -146.22168 21.66553 -146.11523 c\r21.78076 -146.01953 21.93896 -145.94336 22.13965 -145.88672 c\r22.34082 -145.83008 22.59375 -145.80176 22.89795 -145.80176 c\r23.16992 -145.80176 23.40576 -145.82715 23.60449 -145.87598 c\r23.8042 -145.9248 23.96484 -145.99805 24.08594 -146.09375 c\r24.20117 -146.18555 24.28564 -146.2959 24.33887 -146.42578 c\r24.39111 -146.55469 24.41846 -146.70117 24.41846 -146.86621 c\r24.41846 -147.00781 24.39453 -147.14355 24.34473 -147.27246 c\r24.29639 -147.40137 24.21436 -147.51074 24.09912 -147.60059 c\rh\r22.24658 -136.66211 m\r21.91309 -136.65234 21.6626 -136.57227 21.49463 -136.41895 c\r21.32568 -136.26563 21.24219 -136.02734 21.24219 -135.70215 c\r21.24219 -135.40137 21.32178 -135.1543 21.48096 -134.96094 c\r21.64063 -134.7666 21.896 -134.65723 22.24658 -134.63477 c\r22.24658 -134.63477 22.24658 -136.66211 22.24658 -136.66211 c\rh\r25.50391 -141.85449 m\r25.50391 -141.42969 25.45215 -141.04102 25.34912 -140.68945 c\r25.24609 -140.33789 25.08594 -140.03223 24.87109 -139.77246 c\r24.65527 -139.51367 24.38428 -139.31445 24.05615 -139.17285 c\r23.72852 -139.03027 23.34473 -138.95996 22.90479 -138.95996 c\r22.44141 -138.95996 22.04102 -139.03613 21.70508 -139.1875 c\r21.36865 -139.34082 21.08936 -139.55078 20.86816 -139.82422 c\r20.6582 -140.08691 20.50537 -140.39063 20.40771 -140.73535 c\r20.31006 -141.08008 20.26123 -141.4375 20.26123 -141.80762 c\r20.26123 -142.13965 20.29834 -142.44727 20.37207 -142.72754 c\r20.4458 -143.00781 20.54199 -143.26953 20.66016 -143.51367 c\r20.66016 -143.51367 22.01953 -143.51367 22.01953 -143.51367 c\r22.01953 -143.51367 22.01953 -143.29199 22.01953 -143.29199 c\r21.9668 -143.23145 21.90576 -143.1582 21.83496 -143.07324 c\r21.76465 -142.98828 21.6958 -142.88281 21.62793 -142.75879 c\r21.56348 -142.64063 21.51025 -142.51074 21.46777 -142.36914 c\r21.42529 -142.22656 21.4043 -142.0625 21.4043 -141.875 c\r21.4043 -141.45801 21.53857 -141.1377 21.80811 -140.91406 c\r22.07715 -140.68945 22.44238 -140.57813 22.90479 -140.57813 c\r23.38184 -140.57813 23.74365 -140.69336 23.99121 -140.92285 c\r24.23828 -141.15234 24.36133 -141.47852 24.36133 -141.90039 c\r24.36133 -142.09668 24.33936 -142.27441 24.29395 -142.43164 c\r24.24854 -142.58887 24.19531 -142.71973 24.13379 -142.82422 c\r24.07568 -142.92188 24.01416 -143.00879 23.9502 -143.08398 c\r23.88623 -143.15918 23.82324 -143.22852 23.76221 -143.29199 c\r23.76221 -143.29199 23.76221 -143.51367 23.76221 -143.51367 c\r23.76221 -143.51367 25.11963 -143.51367 25.11963 -143.51367 c\r25.23779 -143.26758 25.33105 -143.00977 25.40039 -142.74316 c\r25.46924 -142.47559 25.50391 -142.17969 25.50391 -141.85449 c\rh\r25.37451 -155.53906 m\r25.37451 -155.53906 25.37451 -153.97656 25.37451 -153.97656 c\r25.37451 -153.97656 22.90576 -153.97656 22.90576 -153.97656 c\r22.70508 -153.97656 22.50488 -153.96582 22.30518 -153.9458 c\r22.10645 -153.92529 21.95898 -153.89063 21.86426 -153.84131 c\r21.75537 -153.7832 21.67578 -153.69824 21.625 -153.58643 c\r21.57471 -153.47461 21.5498 -153.31836 21.5498 -153.11816 c\r21.5498 -152.97559 21.57324 -152.83105 21.62109 -152.68408 c\r21.66846 -152.5376 21.74316 -152.37842 21.84668 -152.20752 c\r21.84668 -152.20752 25.37451 -152.20752 25.37451 -152.20752 c\r25.37451 -152.20752 25.37451 -150.64502 25.37451 -150.64502 c\r25.37451 -150.64502 20.39893 -150.64502 20.39893 -150.64502 c\r20.39893 -150.64502 20.39893 -152.20752 20.39893 -152.20752 c\r20.39893 -152.20752 20.94824 -152.20752 20.94824 -152.20752 c\r20.72656 -152.48486 20.55664 -152.75195 20.43848 -153.00781 c\r20.32031 -153.26367 20.26123 -153.54785 20.26123 -153.86035 c\r20.26123 -154.38672 20.41797 -154.79785 20.73145 -155.09473 c\r21.04395 -155.39111 21.5127 -155.53906 22.13574 -155.53906 c\r22.13574 -155.53906 25.37451 -155.53906 25.37451 -155.53906 c\rh\r23.79736 -167.40869 m\r24.31152 -167.40869 24.72607 -167.18359 25.04004 -166.73291 c\r25.35498 -166.28223 25.51221 -165.66553 25.51221 -164.8833 c\r25.51221 -164.44971 25.4707 -164.05664 25.38818 -163.70459 c\r25.30566 -163.35254 25.21387 -163.06934 25.11377 -162.85547 c\r25.11377 -162.85547 23.80273 -162.85547 23.80273 -162.85547 c\r23.80273 -162.85547 23.80273 -162.99805 23.80273 -162.99805 c\r23.8584 -163.07617 23.91992 -163.1665 23.98682 -163.26953 c\r24.05322 -163.37158 24.125 -163.5166 24.20215 -163.70459 c\r24.27002 -163.86621 24.3291 -164.0498 24.37793 -164.25488 c\r24.42627 -164.45996 24.45068 -164.6792 24.45068 -164.91309 c\r24.45068 -165.21924 24.41553 -165.44629 24.3457 -165.59326 c\r24.27637 -165.74023 24.17334 -165.81445 24.03711 -165.81445 c\r23.91553 -165.81445 23.82813 -165.771 23.77344 -165.68457 c\r23.71826 -165.59814 23.66602 -165.43311 23.61621 -165.19092 c\r23.58936 -165.0752 23.56104 -164.91895 23.5293 -164.72119 c\r23.49854 -164.52393 23.46094 -164.34424 23.4165 -164.18262 c\r23.29834 -163.74072 23.11426 -163.41357 22.86523 -163.19971 c\r22.61523 -162.98584 22.30371 -162.87939 21.93213 -162.87939 c\r21.45361 -162.87939 21.05566 -163.10107 20.73779 -163.54346 c\r20.41992 -163.98682 20.26123 -164.5918 20.26123 -165.35986 c\r20.26123 -165.72363 20.29932 -166.07227 20.37402 -166.40527 c\r20.44922 -166.73877 20.53027 -166.99902 20.61621 -167.18652 c\r20.61621 -167.18652 21.87402 -167.18652 21.87402 -167.18652 c\r21.87402 -167.18652 21.87402 -167.05273 21.87402 -167.05273 c\r21.71094 -166.82178 21.57861 -166.55859 21.47656 -166.26318 c\r21.37402 -165.96729 21.32275 -165.66797 21.32275 -165.36523 c\r21.32275 -165.11426 21.35889 -164.90283 21.43018 -164.73145 c\r21.50098 -164.55957 21.60156 -164.47363 21.73291 -164.47363 c\r21.85107 -164.47363 21.94141 -164.51221 22.00244 -164.59082 c\r22.06494 -164.66846 22.12695 -164.85156 22.18896 -165.14063 c\r22.22168 -165.29883 22.25342 -165.46973 22.28467 -165.65332 c\r22.31494 -165.83643 22.35498 -166.02051 22.40186 -166.20508 c\r22.51123 -166.61523 22.68359 -166.91797 22.91797 -167.11426 c\r23.15283 -167.31055 23.44629 -167.40869 23.79736 -167.40869 c\rh\r23.17871 -138.2168 m\r23.17871 -138.2168 23.17871 -134.63867 23.17871 -134.63867 c\r23.57178 -134.66211 23.87305 -134.80762 24.08154 -135.07617 c\r24.28955 -135.34375 24.39453 -135.73828 24.39453 -136.26074 c\r24.39453 -136.59082 24.33252 -136.91113 24.20801 -137.2207 c\r24.08496 -137.53125 23.95215 -137.77637 23.81055 -137.95605 c\r23.81055 -137.95605 23.81055 -138.12988 23.81055 -138.12988 c\r23.81055 -138.12988 25.09229 -138.12988 25.09229 -138.12988 c\r25.23682 -137.77637 25.34131 -137.44434 25.40625 -137.12988 c\r25.47119 -136.81836 25.50391 -136.4707 25.50391 -136.09277 c\r25.50391 -135.11426 25.28027 -134.36426 24.83154 -133.84277 c\r24.38232 -133.32031 23.74365 -133.06055 22.91455 -133.06055 c\r22.09375 -133.06055 21.44385 -133.30762 20.96484 -133.7998 c\r20.48486 -134.29395 20.24512 -134.9707 20.24512 -135.83008 c\r20.24512 -136.62207 20.44922 -137.21875 20.85791 -137.61719 c\r21.26709 -138.01758 21.85449 -138.2168 22.62109 -138.2168 c\r22.62109 -138.2168 23.17871 -138.2168 23.17871 -138.2168 c\rh\r22.88916 -149.52246 m\r23.70703 -149.52246 24.35156 -149.28857 24.82178 -148.82227 c\r25.29297 -148.35449 25.52832 -147.69824 25.52832 -146.85352 c\r25.52832 -146.00781 25.29297 -145.35254 24.82178 -144.88477 c\r24.35156 -144.41797 23.70703 -144.18457 22.88916 -144.18457 c\r22.06543 -144.18457 21.41846 -144.41895 20.94922 -144.88867 c\r20.47998 -145.35938 20.24512 -146.01465 20.24512 -146.85352 c\r20.24512 -147.7041 20.48145 -148.36133 20.9541 -148.82617 c\r21.42627 -149.29004 22.07129 -149.52246 22.88916 -149.52246 c\rh\r23.30176 -132.36816 m\r23.95166 -132.36816 24.47998 -132.09961 24.88721 -131.56055 c\r25.29297 -131.02051 25.49609 -130.28809 25.49609 -129.3623 c\r25.49609 -128.82813 25.44824 -128.36328 25.35205 -127.96387 c\r25.25635 -127.56738 25.13428 -127.19434 24.98633 -126.84766 c\r24.98633 -126.84766 23.40576 -126.84766 23.40576 -126.84766 c\r23.40576 -126.84766 23.40576 -127.03027 23.40576 -127.03027 c\r23.68652 -127.37305 23.90283 -127.75977 24.0542 -128.18555 c\r24.20508 -128.61328 24.28076 -129.02148 24.28076 -129.41406 c\r24.28076 -129.51563 24.27148 -129.64941 24.25342 -129.81445 c\r24.23633 -129.97852 24.20605 -130.1123 24.16504 -130.21777 c\r24.11133 -130.34375 24.04395 -130.44922 23.96436 -130.53223 c\r23.88428 -130.61426 23.76514 -130.65625 23.6084 -130.65625 c\r23.46289 -130.65625 23.33838 -130.5957 23.2334 -130.47656 c\r23.12842 -130.35547 23.04785 -130.17969 22.9917 -129.94922 c\r22.93311 -129.70605 22.87744 -129.44922 22.82568 -129.17871 c\r22.77441 -128.9082 22.70801 -128.65527 22.62842 -128.41895 c\r22.44824 -127.875 22.20361 -127.48242 21.89453 -127.24512 c\r21.58594 -127.00684 21.20264 -126.8877 20.74463 -126.8877 c\r20.13037 -126.8877 19.62842 -127.15625 19.23975 -127.69629 c\r18.85156 -128.23535 18.65674 -128.92871 18.65674 -129.77734 c\r18.65674 -130.20117 18.69922 -130.62207 18.7832 -131.03711 c\r18.86719 -131.45117 18.97266 -131.81055 19.09961 -132.11426 c\r19.09961 -132.11426 20.61816 -132.11426 20.61816 -132.11426 c\r20.61816 -132.11426 20.61816 -131.93652 20.61816 -131.93652 c\r20.40674 -131.67676 20.229 -131.3584 20.08691 -130.98047 c\r19.94385 -130.60352 19.87256 -130.21777 19.87256 -129.82422 c\r19.87256 -129.68457 19.88184 -129.54688 19.90088 -129.41016 c\r19.9209 -129.27148 19.95654 -129.13965 20.00977 -129.01367 c\r20.05371 -128.90039 20.12109 -128.80273 20.21094 -128.72266 c\r20.30078 -128.6416 20.40332 -128.60059 20.51855 -128.60059 c\r20.69287 -128.60059 20.82715 -128.66602 20.91992 -128.79688 c\r21.01318 -128.92578 21.09766 -129.17188 21.1748 -129.5332 c\r21.22461 -129.76953 21.27393 -129.99805 21.3208 -130.21582 c\r21.36816 -130.43457 21.43311 -130.66797 21.51563 -130.91992 c\r21.68164 -131.41504 21.90674 -131.7793 22.19189 -132.01563 c\r22.47705 -132.25098 22.84717 -132.36816 23.30176 -132.36816 c\rh\r25.37451 -161.70605 m\r25.37451 -161.70605 25.37451 -160.14307 25.37451 -160.14307 c\r25.37451 -160.14307 24.85596 -160.14307 24.85596 -160.14307 c\r25.08057 -159.87354 25.24609 -159.62158 25.35303 -159.38721 c\r25.4585 -159.15234 25.51221 -158.88086 25.51221 -158.57422 c\r25.51221 -157.97998 25.27881 -157.50488 24.8125 -157.14795 c\r24.34521 -156.7915 23.71631 -156.61328 22.92432 -156.61328 c\r22.50195 -156.61328 22.12793 -156.67383 21.80127 -156.79346 c\r21.4751 -156.91406 21.19531 -157.07861 20.96143 -157.28711 c\r20.73975 -157.48389 20.56787 -157.72314 20.44531 -158.00488 c\r20.32324 -158.28564 20.26123 -158.56689 20.26123 -158.84814 c\r20.26123 -159.14014 20.29297 -159.38037 20.35645 -159.56738 c\r20.41992 -159.75439 20.50098 -159.94629 20.59863 -160.14307 c\r20.59863 -160.14307 18.47852 -160.14307 18.47852 -160.14307 c\r18.47852 -160.14307 18.47852 -161.70605 18.47852 -161.70605 c\r18.47852 -161.70605 25.37451 -161.70605 25.37451 -161.70605 c\rh\rf\rQ\rq\r1 0 0 -1 0 0 cm\r1 -0.71973 m\r1 -0.71973 519.86133 -0.71973 519.86133 -0.71973 c\r519.86133 -0.71973 519.86133 -300 519.86133 -300 c\r519.86133 -300 1 -300 1 -300 c\r1 -300 1 -0.71973 1 -0.71973 c\rh\rW n\r1 1 1 rg\r0 i \r/GS0 gs\r451.01758 -167.875 m\r451.01758 -167.875 511.69336 -167.875 511.69336 -167.875 c\r511.69336 -167.875 511.69336 -125.99121 511.69336 -125.99121 c\r511.69336 -125.99121 451.01758 -125.99121 451.01758 -125.99121 c\r451.01758 -125.99121 451.01758 -167.875 451.01758 -167.875 c\rh\rf\r0 0 0 RG\r1 w 10 M 0 j 0 J []0 d \r451.01758 -167.875 m\r451.01758 -167.875 511.69336 -167.875 511.69336 -167.875 c\r511.69336 -167.875 511.69336 -125.99121 511.69336 -125.99121 c\r511.69336 -125.99121 451.01758 -125.99121 451.01758 -125.99121 c\r451.01758 -125.99121 451.01758 -167.875 451.01758 -167.875 c\rh\rS\rQ\rq\r1 0 0 -1 0 0 cm\r451.14746 -126.37109 m\r451.14746 -126.37109 511.56348 -126.37109 511.56348 -126.37109 c\r511.56348 -126.37109 511.56348 -167.74854 511.56348 -167.74854 c\r511.56348 -167.74854 451.14746 -167.74854 451.14746 -167.74854 c\r451.14746 -167.74854 451.14746 -126.37109 451.14746 -126.37109 c\rh\rW n\r0.60001 0.60001 1 rg\r0 i \r/GS0 gs\r454.12891 -163.56006 m\r454.12891 -163.56006 459.83398 -163.56006 459.83398 -163.56006 c\r459.83398 -163.56006 459.83398 -157.9751 459.83398 -157.9751 c\r459.83398 -157.9751 454.12891 -157.9751 454.12891 -157.9751 c\r454.12891 -157.9751 454.12891 -163.56006 454.12891 -163.56006 c\rh\rf\r0 0 0 RG\r4 w 10 M 0 j 0 J []0 d \r454.12891 -163.56006 m\r454.12891 -163.56006 459.83398 -163.56006 459.83398 -163.56006 c\r459.83398 -163.56006 459.83398 -157.9751 459.83398 -157.9751 c\r459.83398 -157.9751 454.12891 -157.9751 454.12891 -157.9751 c\r454.12891 -157.9751 454.12891 -163.56006 454.12891 -163.56006 c\rh\rS\r0 0 0 rg\r491.11133 -158.92383 m\r491.11133 -158.92383 491.11133 -161.57227 491.11133 -161.57227 c\r490.88867 -161.6709 490.68262 -161.74121 490.49121 -161.78369 c\r490.2998 -161.8252 490.11035 -161.84668 489.91992 -161.84668 c\r489.45996 -161.84668 489.09766 -161.6958 488.83398 -161.39404 c\r488.57031 -161.09229 488.43848 -160.6543 488.43848 -160.08057 c\r488.43848 -159.53613 488.53613 -159.12256 488.73145 -158.84131 c\r488.92676 -158.56006 489.25195 -158.41943 489.70508 -158.41943 c\r489.94922 -158.41943 490.19336 -158.46533 490.43848 -158.55664 c\r490.68262 -158.64746 490.90723 -158.77051 491.11133 -158.92383 c\rh\r491.94629 -158.14795 m\r491.94629 -157.32666 491.75586 -156.72314 491.37305 -156.33936 c\r490.99121 -155.95459 490.40332 -155.76221 489.6084 -155.76221 c\r489.34473 -155.76221 489.08887 -155.78027 488.83691 -155.81592 c\r488.58691 -155.85205 488.34082 -155.90332 488.09766 -155.96973 c\r488.09766 -155.96973 488.09766 -156.80127 488.09766 -156.80127 c\r488.09766 -156.80127 488.1416 -156.80127 488.1416 -156.80127 c\r488.27734 -156.74902 488.49414 -156.68408 488.79102 -156.60742 c\r489.08789 -156.53027 489.38379 -156.49219 489.67969 -156.49219 c\r489.96582 -156.49219 490.20117 -156.5249 490.3877 -156.5918 c\r490.57422 -156.6582 490.71973 -156.75098 490.82324 -156.86914 c\r490.92578 -156.98145 491.00098 -157.11816 491.0459 -157.27637 c\r491.08984 -157.43555 491.11133 -157.61328 491.11133 -157.81006 c\r491.11133 -157.81006 491.11133 -158.25195 491.11133 -158.25195 c\r490.86035 -158.05518 490.61914 -157.9082 490.38965 -157.81152 c\r490.16016 -157.71436 489.86719 -157.66602 489.5127 -157.66602 c\r488.91992 -157.66602 488.44922 -157.875 488.10059 -158.29346 c\r487.75293 -158.71191 487.57813 -159.30078 487.57813 -160.0625 c\r487.57813 -160.479 487.63867 -160.83887 487.75879 -161.14111 c\r487.87988 -161.44385 488.04297 -161.70508 488.25 -161.9248 c\r488.44238 -162.13037 488.67676 -162.29053 488.95215 -162.40479 c\r489.22754 -162.51904 489.50195 -162.57617 489.77344 -162.57617 c\r490.0625 -162.57617 490.30273 -162.54785 490.49707 -162.4917 c\r490.68945 -162.43506 490.89648 -162.34912 491.11133 -162.2334 c\r491.11133 -162.2334 491.16406 -162.44141 491.16406 -162.44141 c\r491.16406 -162.44141 491.94629 -162.44141 491.94629 -162.44141 c\r491.94629 -162.44141 491.94629 -158.14795 491.94629 -158.14795 c\rh\r485.84961 -160.56152 m\r485.84668 -160.98828 485.73438 -161.31836 485.51953 -161.55176 c\r485.30176 -161.78516 484.97168 -161.90186 484.52734 -161.90186 c\r484.08203 -161.90186 483.72656 -161.77344 483.46191 -161.51709 c\r483.19824 -161.26025 483.04883 -160.94189 483.01367 -160.56152 c\r483.01367 -160.56152 485.84961 -160.56152 485.84961 -160.56152 c\rh\r486.65918 -159.93457 m\r486.65918 -159.93457 483.01367 -159.93457 483.01367 -159.93457 c\r483.01367 -159.63721 483.05859 -159.37793 483.15039 -159.15674 c\r483.24219 -158.93604 483.36719 -158.75488 483.52734 -158.61328 c\r483.67969 -158.47461 483.8623 -158.37061 484.07422 -158.30176 c\r484.28516 -158.23193 484.51758 -158.19727 484.77246 -158.19727 c\r485.1084 -158.19727 485.44727 -158.26318 485.78906 -158.39502 c\r486.12988 -158.52734 486.37207 -158.65674 486.51758 -158.78467 c\r486.51758 -158.78467 486.5625 -158.78467 486.5625 -158.78467 c\r486.5625 -158.78467 486.5625 -157.89258 486.5625 -157.89258 c\r486.28125 -157.77637 485.99512 -157.6792 485.70313 -157.60059 c\r485.41016 -157.52295 485.10352 -157.4834 484.78223 -157.4834 c\r483.96094 -157.4834 483.32031 -157.70117 482.86133 -158.13623 c\r482.40039 -158.57129 482.1709 -159.18945 482.1709 -159.99072 c\r482.1709 -160.7832 482.39063 -161.41211 482.83203 -161.87744 c\r483.27246 -162.34326 483.85449 -162.57617 484.57324 -162.57617 c\r485.24121 -162.57617 485.75586 -162.38525 486.11719 -162.00342 c\r486.47754 -161.62207 486.65918 -161.07959 486.65918 -160.37744 c\r486.65918 -160.37744 486.65918 -159.93457 486.65918 -159.93457 c\rh\r480.37305 -160.05273 m\r480.37305 -160.63818 480.27148 -161.07471 480.06641 -161.36475 c\r479.86133 -161.65381 479.54688 -161.79883 479.12305 -161.79883 c\r478.88281 -161.79883 478.64063 -161.74854 478.39648 -161.64648 c\r478.1543 -161.54541 477.9209 -161.41211 477.69824 -161.24756 c\r477.69824 -161.24756 477.69824 -158.49854 477.69824 -158.49854 c\r477.93555 -158.39404 478.14063 -158.32324 478.31055 -158.28564 c\r478.48145 -158.24805 478.67383 -158.22949 478.8916 -158.22949 c\r479.35742 -158.22949 479.7207 -158.38281 479.98145 -158.68945 c\r480.24219 -158.99609 480.37305 -159.45068 480.37305 -160.05273 c\rh\r481.23145 -160.07666 m\r481.23145 -159.68359 481.17383 -159.32422 481.05957 -158.99854 c\r480.94238 -158.67285 480.78125 -158.39746 480.56934 -158.17188 c\r480.37402 -157.95752 480.14453 -157.79248 479.87793 -157.67529 c\r479.61328 -157.55811 479.33203 -157.49902 479.03613 -157.49902 c\r478.7793 -157.49902 478.54492 -157.52686 478.33691 -157.58154 c\r478.12891 -157.63623 477.91504 -157.72217 477.69824 -157.83789 c\r477.69824 -157.83789 477.69824 -155.80957 477.69824 -155.80957 c\r477.69824 -155.80957 476.86426 -155.80957 476.86426 -155.80957 c\r476.86426 -155.80957 476.86426 -162.44141 476.86426 -162.44141 c\r476.86426 -162.44141 477.69824 -162.44141 477.69824 -162.44141 c\r477.69824 -162.44141 477.69824 -161.93408 477.69824 -161.93408 c\r477.9209 -162.11621 478.1709 -162.26904 478.44727 -162.39209 c\r478.72461 -162.51465 479.02051 -162.57617 479.33398 -162.57617 c\r479.93262 -162.57617 480.39844 -162.35547 480.73242 -161.91455 c\r481.06543 -161.47314 481.23145 -160.86035 481.23145 -160.07666 c\rh\r475.28906 -163.25 m\r475.28906 -163.25 474.34277 -163.25 474.34277 -163.25 c\r474.34277 -163.25 474.34277 -164.09912 474.34277 -164.09912 c\r474.34277 -164.09912 475.28906 -164.09912 475.28906 -164.09912 c\r475.28906 -164.09912 475.28906 -163.25 475.28906 -163.25 c\rh\r475.2334 -157.47949 m\r475.2334 -156.91309 475.08496 -156.48486 474.78906 -156.19531 c\r474.49414 -155.90674 474.09863 -155.76221 473.60156 -155.76221 c\r473.4834 -155.76221 473.32715 -155.77344 473.13477 -155.79688 c\r472.94043 -155.81934 472.77832 -155.84863 472.64844 -155.8833 c\r472.64844 -155.8833 472.64844 -156.6582 472.64844 -156.6582 c\r472.64844 -156.6582 472.69238 -156.6582 472.69238 -156.6582 c\r472.77539 -156.62744 472.88672 -156.5918 473.02734 -156.55176 c\r473.16797 -156.51172 473.30469 -156.49219 473.43652 -156.49219 c\r473.65039 -156.49219 473.82129 -156.521 473.9502 -156.57861 c\r474.08008 -156.63672 474.17871 -156.72314 474.24414 -156.83887 c\r474.30859 -156.95459 474.35059 -157.09424 474.36914 -157.25732 c\r474.38867 -157.4209 474.39941 -157.62012 474.39941 -157.85449 c\r474.39941 -157.85449 474.39941 -161.75928 474.39941 -161.75928 c\r474.39941 -161.75928 473.36914 -161.75928 473.36914 -161.75928 c\r473.36914 -161.75928 473.36914 -162.44141 473.36914 -162.44141 c\r473.36914 -162.44141 475.2334 -162.44141 475.2334 -162.44141 c\r475.2334 -162.44141 475.2334 -157.47949 475.2334 -157.47949 c\rh\r471.59766 -160.03125 m\r471.59766 -160.61035 471.49902 -161.0498 471.30371 -161.34912 c\r471.10742 -161.64941 470.79199 -161.79883 470.35645 -161.79883 c\r470.1123 -161.79883 469.86621 -161.74756 469.61719 -161.64453 c\r469.36816 -161.54199 469.13672 -161.40967 468.92285 -161.24756 c\r468.92285 -161.24756 468.92285 -158.46729 468.92285 -158.46729 c\r469.16016 -158.36328 469.36523 -158.29102 469.53516 -158.25 c\r469.70508 -158.20947 469.89941 -158.18945 470.11621 -158.18945 c\r470.57813 -158.18945 470.94141 -158.33789 471.20313 -158.63477 c\r471.46582 -158.93164 471.59766 -159.39697 471.59766 -160.03125 c\rh\r472.45605 -160.05518 m\r472.45605 -159.64941 472.39746 -159.28516 472.28027 -158.96094 c\r472.16406 -158.63721 472.00586 -158.36523 471.80664 -158.14502 c\r471.59766 -157.91699 471.36621 -157.74561 471.11328 -157.63135 c\r470.8623 -157.5166 470.58496 -157.45996 470.28223 -157.45996 c\r470.00098 -157.45996 469.75586 -157.49219 469.54395 -157.55762 c\r469.33496 -157.62256 469.12695 -157.70996 468.92285 -157.81982 c\r468.92285 -157.81982 468.87012 -157.59473 468.87012 -157.59473 c\r468.87012 -157.59473 468.08887 -157.59473 468.08887 -157.59473 c\r468.08887 -157.59473 468.08887 -164.34521 468.08887 -164.34521 c\r468.08887 -164.34521 468.92285 -164.34521 468.92285 -164.34521 c\r468.92285 -164.34521 468.92285 -161.93359 468.92285 -161.93359 c\r469.15625 -162.12158 469.40527 -162.27637 469.66895 -162.396 c\r469.93359 -162.51563 470.22949 -162.57617 470.55859 -162.57617 c\r471.14551 -162.57617 471.60742 -162.35645 471.94727 -161.91699 c\r472.28516 -161.47656 472.45605 -160.85596 472.45605 -160.05518 c\rh\r466.43555 -157.59473 m\r466.43555 -157.59473 465.60156 -157.59473 465.60156 -157.59473 c\r465.60156 -157.59473 465.60156 -162.44141 465.60156 -162.44141 c\r465.60156 -162.44141 466.43555 -162.44141 466.43555 -162.44141 c\r466.43555 -162.44141 466.43555 -157.59473 466.43555 -157.59473 c\rh\r466.49414 -163.25 m\r466.49414 -163.25 465.54492 -163.25 465.54492 -163.25 c\r465.54492 -163.25 465.54492 -164.09912 465.54492 -164.09912 c\r465.54492 -164.09912 466.49414 -164.09912 466.49414 -164.09912 c\r466.49414 -164.09912 466.49414 -163.25 466.49414 -163.25 c\rh\r463.9502 -157.59473 m\r463.9502 -157.59473 463.11523 -157.59473 463.11523 -157.59473 c\r463.11523 -157.59473 463.11523 -164.34521 463.11523 -164.34521 c\r463.11523 -164.34521 463.9502 -164.34521 463.9502 -164.34521 c\r463.9502 -164.34521 463.9502 -157.59473 463.9502 -157.59473 c\rh\rf\r0.60001 0.2 0.39999 rg\r454.12891 -149.59863 m\r454.12891 -149.59863 459.83398 -149.59863 459.83398 -149.59863 c\r459.83398 -149.59863 459.83398 -144.01367 459.83398 -144.01367 c\r459.83398 -144.01367 454.12891 -144.01367 454.12891 -144.01367 c\r454.12891 -144.01367 454.12891 -149.59863 454.12891 -149.59863 c\rh\rf\r454.12891 -149.59863 m\r454.12891 -149.59863 459.83398 -149.59863 459.83398 -149.59863 c\r459.83398 -149.59863 459.83398 -144.01367 459.83398 -144.01367 c\r459.83398 -144.01367 454.12891 -144.01367 454.12891 -144.01367 c\r454.12891 -144.01367 454.12891 -149.59863 454.12891 -149.59863 c\rh\rS\r0 0 0 rg\r483.57129 -143.67676 m\r483.41504 -143.63574 483.24414 -143.60352 483.05957 -143.57715 c\r482.875 -143.55078 482.70996 -143.53809 482.56543 -143.53809 c\r482.06055 -143.53809 481.67676 -143.6709 481.41309 -143.9375 c\r481.15137 -144.2041 481.01953 -144.63086 481.01953 -145.21875 c\r481.01953 -145.21875 481.01953 -147.79785 481.01953 -147.79785 c\r481.01953 -147.79785 480.45996 -147.79785 480.45996 -147.79785 c\r480.45996 -147.79785 480.45996 -148.47949 480.45996 -148.47949 c\r480.45996 -148.47949 481.01953 -148.47949 481.01953 -148.47949 c\r481.01953 -148.47949 481.01953 -149.87646 481.01953 -149.87646 c\r481.01953 -149.87646 481.85352 -149.87646 481.85352 -149.87646 c\r481.85352 -149.87646 481.85352 -148.47949 481.85352 -148.47949 c\r481.85352 -148.47949 483.57129 -148.47949 483.57129 -148.47949 c\r483.57129 -148.47949 483.57129 -147.79785 483.57129 -147.79785 c\r483.57129 -147.79785 481.85352 -147.79785 481.85352 -147.79785 c\r481.85352 -147.79785 481.85352 -145.58594 481.85352 -145.58594 c\r481.85352 -145.33105 481.86035 -145.13184 481.87109 -144.98828 c\r481.88281 -144.84473 481.92383 -144.71094 481.99512 -144.58594 c\r482.06055 -144.4707 482.14844 -144.38574 482.26367 -144.33203 c\r482.37695 -144.27832 482.5498 -144.25195 482.7832 -144.25195 c\r482.91992 -144.25195 483.06055 -144.27148 483.20801 -144.31152 c\r483.35547 -144.35059 483.46191 -144.38379 483.52734 -144.41016 c\r483.52734 -144.41016 483.57129 -144.41016 483.57129 -144.41016 c\r483.57129 -144.41016 483.57129 -143.67676 483.57129 -143.67676 c\rh\r478.9248 -146.59961 m\r478.92188 -147.02637 478.81055 -147.35645 478.59375 -147.59082 c\r478.37695 -147.82422 478.04688 -147.94043 477.60352 -147.94043 c\r477.1582 -147.94043 476.80176 -147.8125 476.53809 -147.55566 c\r476.27344 -147.29883 476.12305 -146.98047 476.08789 -146.59961 c\r476.08789 -146.59961 478.9248 -146.59961 478.9248 -146.59961 c\rh\r479.73438 -145.97266 m\r479.73438 -145.97266 476.08789 -145.97266 476.08789 -145.97266 c\r476.08789 -145.67578 476.13477 -145.41602 476.22559 -145.19629 c\r476.31738 -144.97461 476.44336 -144.79395 476.60254 -144.65234 c\r476.75586 -144.51367 476.93848 -144.40918 477.14844 -144.33984 c\r477.36035 -144.27051 477.59277 -144.23633 477.84668 -144.23633 c\r478.18457 -144.23633 478.52246 -144.30176 478.86426 -144.43359 c\r479.20508 -144.56543 479.44824 -144.69531 479.59277 -144.82324 c\r479.59277 -144.82324 479.63672 -144.82324 479.63672 -144.82324 c\r479.63672 -144.82324 479.63672 -143.93066 479.63672 -143.93066 c\r479.35742 -143.81543 479.07031 -143.71777 478.77734 -143.63965 c\r478.48535 -143.56152 478.17871 -143.52246 477.8584 -143.52246 c\r477.03711 -143.52246 476.39648 -143.73926 475.93555 -144.1748 c\r475.47559 -144.61035 475.24512 -145.22852 475.24512 -146.0293 c\r475.24512 -146.82227 475.46582 -147.45117 475.90723 -147.91602 c\r476.34766 -148.38184 476.92969 -148.61426 477.64844 -148.61426 c\r478.31641 -148.61426 478.83105 -148.42383 479.19238 -148.04199 c\r479.55371 -147.66016 479.73438 -147.11816 479.73438 -146.41602 c\r479.73438 -146.41602 479.73438 -145.97266 479.73438 -145.97266 c\rh\r473.51465 -146.59961 m\r473.51172 -147.02637 473.40234 -147.35645 473.18457 -147.59082 c\r472.96777 -147.82422 472.63867 -147.94043 472.19531 -147.94043 c\r471.74902 -147.94043 471.39258 -147.8125 471.12891 -147.55566 c\r470.86523 -147.29883 470.71484 -146.98047 470.67871 -146.59961 c\r470.67871 -146.59961 473.51465 -146.59961 473.51465 -146.59961 c\rh\r474.32617 -145.97266 m\r474.32617 -145.97266 470.67871 -145.97266 470.67871 -145.97266 c\r470.67871 -145.67578 470.72461 -145.41602 470.81641 -145.19629 c\r470.9082 -144.97461 471.03418 -144.79395 471.19238 -144.65234 c\r471.34668 -144.51367 471.5293 -144.40918 471.74023 -144.33984 c\r471.95117 -144.27051 472.18457 -144.23633 472.43848 -144.23633 c\r472.77441 -144.23633 473.11426 -144.30176 473.45508 -144.43359 c\r473.7959 -144.56543 474.03906 -144.69531 474.18359 -144.82324 c\r474.18359 -144.82324 474.22754 -144.82324 474.22754 -144.82324 c\r474.22754 -144.82324 474.22754 -143.93066 474.22754 -143.93066 c\r473.94727 -143.81543 473.66113 -143.71777 473.36914 -143.63965 c\r473.07813 -143.56152 472.77051 -143.52246 472.44824 -143.52246 c\r471.62695 -143.52246 470.9873 -143.73926 470.52734 -144.1748 c\r470.06738 -144.61035 469.83594 -145.22852 469.83594 -146.0293 c\r469.83594 -146.82227 470.05664 -147.45117 470.49902 -147.91602 c\r470.93945 -148.38184 471.51953 -148.61426 472.24121 -148.61426 c\r472.90723 -148.61426 473.4209 -148.42383 473.7832 -148.04199 c\r474.14551 -147.66016 474.32617 -147.11816 474.32617 -146.41602 c\r474.32617 -146.41602 474.32617 -145.97266 474.32617 -145.97266 c\rh\r469.39648 -147.5918 m\r469.39648 -147.5918 469.35254 -147.5918 469.35254 -147.5918 c\r469.22852 -147.61914 469.1084 -147.63965 468.99219 -147.65234 c\r468.87598 -147.66406 468.7373 -147.6709 468.5791 -147.6709 c\r468.32129 -147.6709 468.07422 -147.61523 467.83496 -147.50391 c\r467.5957 -147.39258 467.36523 -147.24902 467.14453 -147.07227 c\r467.14453 -147.07227 467.14453 -143.63281 467.14453 -143.63281 c\r467.14453 -143.63281 466.31055 -143.63281 466.31055 -143.63281 c\r466.31055 -143.63281 466.31055 -148.47949 466.31055 -148.47949 c\r466.31055 -148.47949 467.14453 -148.47949 467.14453 -148.47949 c\r467.14453 -148.47949 467.14453 -147.76367 467.14453 -147.76367 c\r467.47461 -148.02441 467.76563 -148.20898 468.01855 -148.31738 c\r468.27051 -148.42578 468.52734 -148.47949 468.79004 -148.47949 c\r468.93457 -148.47949 469.04004 -148.47656 469.10449 -148.46875 c\r469.16895 -148.46191 469.2666 -148.44824 469.39648 -148.42773 c\r469.39648 -148.42773 469.39648 -147.5918 469.39648 -147.5918 c\rh\r465.77246 -149.59082 m\r465.77246 -149.59082 465.72852 -149.59082 465.72852 -149.59082 c\r465.63672 -149.61621 465.51758 -149.64258 465.36914 -149.66943 c\r465.22266 -149.69629 465.09375 -149.70947 464.98145 -149.70947 c\r464.62305 -149.70947 464.36523 -149.63281 464.20508 -149.47852 c\r464.04395 -149.32471 463.96289 -149.04639 463.96289 -148.64453 c\r463.96289 -148.64453 463.96289 -148.47949 463.96289 -148.47949 c\r463.96289 -148.47949 465.46484 -148.47949 465.46484 -148.47949 c\r465.46484 -148.47949 465.46484 -147.79785 465.46484 -147.79785 c\r465.46484 -147.79785 463.99023 -147.79785 463.99023 -147.79785 c\r463.99023 -147.79785 463.99023 -143.63281 463.99023 -143.63281 c\r463.99023 -143.63281 463.15527 -143.63281 463.15527 -143.63281 c\r463.15527 -143.63281 463.15527 -147.79785 463.15527 -147.79785 c\r463.15527 -147.79785 462.59668 -147.79785 462.59668 -147.79785 c\r462.59668 -147.79785 462.59668 -148.47949 462.59668 -148.47949 c\r462.59668 -148.47949 463.15527 -148.47949 463.15527 -148.47949 c\r463.15527 -148.47949 463.15527 -148.63965 463.15527 -148.63965 c\r463.15527 -149.21436 463.30176 -149.65527 463.59375 -149.9624 c\r463.88574 -150.27002 464.30859 -150.42334 464.85938 -150.42334 c\r465.04688 -150.42334 465.21387 -150.41504 465.36328 -150.39746 c\r465.51172 -150.37988 465.64746 -150.35986 465.77246 -150.33643 c\r465.77246 -150.33643 465.77246 -149.59082 465.77246 -149.59082 c\rh\rf\r498.87988 -146.59961 m\r498.87695 -147.02637 498.7666 -147.35645 498.5498 -147.59082 c\r498.33301 -147.82422 498.00293 -147.94043 497.55957 -147.94043 c\r497.11328 -147.94043 496.75781 -147.8125 496.49316 -147.55566 c\r496.22949 -147.29883 496.0791 -146.98047 496.04395 -146.59961 c\r496.04395 -146.59961 498.87988 -146.59961 498.87988 -146.59961 c\rh\r499.68945 -145.97266 m\r499.68945 -145.97266 496.04395 -145.97266 496.04395 -145.97266 c\r496.04395 -145.67578 496.08984 -145.41602 496.18164 -145.19629 c\r496.27344 -144.97461 496.39746 -144.79395 496.55762 -144.65234 c\r496.71191 -144.51367 496.89355 -144.40918 497.10547 -144.33984 c\r497.31641 -144.27051 497.54883 -144.23633 497.80371 -144.23633 c\r498.14063 -144.23633 498.47852 -144.30176 498.82031 -144.43359 c\r499.16016 -144.56543 499.4043 -144.69531 499.54883 -144.82324 c\r499.54883 -144.82324 499.59277 -144.82324 499.59277 -144.82324 c\r499.59277 -144.82324 499.59277 -143.93066 499.59277 -143.93066 c\r499.3125 -143.81543 499.02637 -143.71777 498.73438 -143.63965 c\r498.44141 -143.56152 498.13477 -143.52246 497.81348 -143.52246 c\r496.99316 -143.52246 496.35156 -143.73926 495.8916 -144.1748 c\r495.43066 -144.61035 495.20117 -145.22852 495.20117 -146.0293 c\r495.20117 -146.82227 495.42188 -147.45117 495.86328 -147.91602 c\r496.30371 -148.38184 496.88477 -148.61426 497.60449 -148.61426 c\r498.27246 -148.61426 498.78613 -148.42383 499.14844 -148.04199 c\r499.50879 -147.66016 499.68945 -147.11816 499.68945 -146.41602 c\r499.68945 -146.41602 499.68945 -145.97266 499.68945 -145.97266 c\rh\r493.4043 -146.0918 m\r493.4043 -146.67676 493.30078 -147.11328 493.09668 -147.40332 c\r492.89258 -147.69238 492.57813 -147.83789 492.15332 -147.83789 c\r491.91406 -147.83789 491.67188 -147.78711 491.42871 -147.68555 c\r491.18555 -147.58398 490.95313 -147.45117 490.73047 -147.28613 c\r490.73047 -147.28613 490.73047 -144.53711 490.73047 -144.53711 c\r490.96777 -144.43262 491.17188 -144.36133 491.3418 -144.32422 c\r491.5127 -144.28613 491.70605 -144.26758 491.92285 -144.26758 c\r492.38867 -144.26758 492.75195 -144.4209 493.01172 -144.72754 c\r493.27441 -145.03516 493.4043 -145.48926 493.4043 -146.0918 c\rh\r494.2627 -146.11523 m\r494.2627 -145.72168 494.20605 -145.3623 494.08984 -145.03711 c\r493.97461 -144.71191 493.81055 -144.43652 493.60059 -144.21094 c\r493.40625 -143.99707 493.1748 -143.83105 492.91016 -143.71387 c\r492.64453 -143.59668 492.36426 -143.53809 492.06836 -143.53809 c\r491.81055 -143.53809 491.57617 -143.56543 491.36719 -143.62012 c\r491.1582 -143.67578 490.94629 -143.76074 490.73047 -143.87598 c\r490.73047 -143.87598 490.73047 -141.84863 490.73047 -141.84863 c\r490.73047 -141.84863 489.89551 -141.84863 489.89551 -141.84863 c\r489.89551 -141.84863 489.89551 -148.47949 489.89551 -148.47949 c\r489.89551 -148.47949 490.73047 -148.47949 490.73047 -148.47949 c\r490.73047 -148.47949 490.73047 -147.97266 490.73047 -147.97266 c\r490.95215 -148.15527 491.20117 -148.30762 491.47852 -148.43066 c\r491.75586 -148.55273 492.05176 -148.61426 492.36523 -148.61426 c\r492.96387 -148.61426 493.42969 -148.39453 493.76367 -147.95313 c\r494.09668 -147.51172 494.2627 -146.89941 494.2627 -146.11523 c\rh\r488.81055 -148.47949 m\r488.81055 -148.47949 485.91504 -141.84863 485.91504 -141.84863 c\r485.91504 -141.84863 485.02832 -141.84863 485.02832 -141.84863 c\r485.02832 -141.84863 485.94727 -143.86914 485.94727 -143.86914 c\r485.94727 -143.86914 483.97168 -148.47949 483.97168 -148.47949 c\r483.97168 -148.47949 484.87695 -148.47949 484.87695 -148.47949 c\r484.87695 -148.47949 486.40039 -144.8877 486.40039 -144.8877 c\r486.40039 -144.8877 487.9375 -148.47949 487.9375 -148.47949 c\r487.9375 -148.47949 488.81055 -148.47949 488.81055 -148.47949 c\rh\rf\r1 1 0.8 rg\r454.12891 -135.63672 m\r454.12891 -135.63672 459.83398 -135.63672 459.83398 -135.63672 c\r459.83398 -135.63672 459.83398 -130.05273 459.83398 -130.05273 c\r459.83398 -130.05273 454.12891 -130.05273 454.12891 -130.05273 c\r454.12891 -130.05273 454.12891 -135.63672 454.12891 -135.63672 c\rh\rf\r454.12891 -135.63672 m\r454.12891 -135.63672 459.83398 -135.63672 459.83398 -135.63672 c\r459.83398 -135.63672 459.83398 -130.05273 459.83398 -130.05273 c\r459.83398 -130.05273 454.12891 -130.05273 454.12891 -130.05273 c\r454.12891 -130.05273 454.12891 -135.63672 454.12891 -135.63672 c\rh\rS\r0 0 0 rg\r507.63477 -129.67285 m\r507.63477 -129.67285 506.54199 -129.67285 506.54199 -129.67285 c\r506.54199 -129.67285 504.55176 -131.79395 504.55176 -131.79395 c\r504.55176 -131.79395 504.01367 -131.29004 504.01367 -131.29004 c\r504.01367 -131.29004 504.01367 -129.67285 504.01367 -129.67285 c\r504.01367 -129.67285 503.17773 -129.67285 503.17773 -129.67285 c\r503.17773 -129.67285 503.17773 -136.42285 503.17773 -136.42285 c\r503.17773 -136.42285 504.01367 -136.42285 504.01367 -136.42285 c\r504.01367 -136.42285 504.01367 -132.0918 504.01367 -132.0918 c\r504.01367 -132.0918 506.41602 -134.51855 506.41602 -134.51855 c\r506.41602 -134.51855 507.46484 -134.51855 507.46484 -134.51855 c\r507.46484 -134.51855 505.16699 -132.2793 505.16699 -132.2793 c\r505.16699 -132.2793 507.63477 -129.67285 507.63477 -129.67285 c\rh\r502.07324 -129.97168 m\r501.79492 -129.8418 501.53125 -129.74023 501.28223 -129.66797 c\r501.0332 -129.59668 500.76758 -129.56055 500.4873 -129.56055 c\r500.12988 -129.56055 499.80273 -129.6123 499.50391 -129.71484 c\r499.20703 -129.81738 498.95117 -129.97266 498.73828 -130.18066 c\r498.52344 -130.38965 498.35547 -130.65234 498.23828 -130.97168 c\r498.12012 -131.29004 498.06055 -131.66211 498.06055 -132.08594 c\r498.06055 -132.87891 498.2832 -133.50195 498.72852 -133.95313 c\r499.17188 -134.4043 499.75879 -134.63086 500.4873 -134.63086 c\r500.76953 -134.63086 501.04883 -134.59082 501.32227 -134.5127 c\r501.5957 -134.43457 501.8457 -134.33887 502.07324 -134.22656 c\r502.07324 -134.22656 502.07324 -133.32031 502.07324 -133.32031 c\r502.07324 -133.32031 502.02832 -133.32031 502.02832 -133.32031 c\r501.77344 -133.51172 501.51172 -133.65918 501.24121 -133.76172 c\r500.9707 -133.86426 500.70703 -133.91602 500.4502 -133.91602 c\r499.97656 -133.91602 499.60352 -133.76074 499.33008 -133.45117 c\r499.05762 -133.14063 498.91992 -132.68652 498.91992 -132.08594 c\r498.91992 -131.50488 499.05469 -131.05664 499.32129 -130.74414 c\r499.58887 -130.43066 499.96484 -130.27441 500.4502 -130.27441 c\r500.61816 -130.27441 500.78906 -130.29688 500.96484 -130.33887 c\r501.13867 -130.38086 501.29492 -130.43652 501.43457 -130.50586 c\r501.55469 -130.56445 501.66992 -130.62891 501.77441 -130.69629 c\r501.88086 -130.76367 501.96582 -130.82129 502.02832 -130.87012 c\r502.02832 -130.87012 502.07324 -130.87012 502.07324 -130.87012 c\r502.07324 -130.87012 502.07324 -129.97168 502.07324 -129.97168 c\rh\r495.96973 -130.8623 m\r495.96973 -130.8623 495.96973 -132.21777 495.96973 -132.21777 c\r495.71777 -132.20313 495.41895 -132.18262 495.07715 -132.15332 c\r494.7334 -132.12402 494.46484 -132.08105 494.26367 -132.02637 c\r494.02637 -131.95898 493.83301 -131.85645 493.68652 -131.71484 c\r493.54004 -131.57324 493.46582 -131.37891 493.46582 -131.13281 c\r493.46582 -130.85352 493.55176 -130.64355 493.72168 -130.50195 c\r493.8916 -130.36035 494.15234 -130.29004 494.50195 -130.29004 c\r494.79395 -130.29004 495.05859 -130.3457 495.2998 -130.45898 c\r495.54102 -130.57031 495.76465 -130.70508 495.96973 -130.8623 c\rh\r496.80469 -129.67285 m\r496.80469 -129.67285 495.96973 -129.67285 495.96973 -129.67285 c\r495.96973 -129.67285 495.96973 -130.18945 495.96973 -130.18945 c\r495.89551 -130.13965 495.7959 -130.07031 495.67285 -129.98242 c\r495.54688 -129.89355 495.4248 -129.82324 495.30859 -129.77148 c\r495.16992 -129.70605 495.00977 -129.64941 494.83203 -129.60449 c\r494.65234 -129.55859 494.44043 -129.53613 494.2002 -129.53613 c\r493.75586 -129.53613 493.37891 -129.68164 493.07031 -129.97168 c\r492.76172 -130.26172 492.60742 -130.62988 492.60742 -131.0791 c\r492.60742 -131.44727 492.6875 -131.74414 492.84766 -131.97168 c\r493.00781 -132.19922 493.2373 -132.37695 493.53418 -132.50684 c\r493.83398 -132.63672 494.19434 -132.72559 494.61523 -132.77246 c\r495.03613 -132.81836 495.48828 -132.85352 495.96973 -132.87695 c\r495.96973 -132.87695 495.96973 -133.00293 495.96973 -133.00293 c\r495.96973 -133.18945 495.93652 -133.34375 495.87012 -133.46484 c\r495.80469 -133.58691 495.70898 -133.68457 495.58594 -133.75391 c\r495.46875 -133.82031 495.32715 -133.86621 495.16309 -133.88867 c\r494.99805 -133.91113 494.8252 -133.92383 494.64648 -133.92383 c\r494.42871 -133.92383 494.18555 -133.89453 493.91895 -133.83789 c\r493.65039 -133.78125 493.37402 -133.69922 493.08789 -133.5918 c\r493.08789 -133.5918 493.04492 -133.5918 493.04492 -133.5918 c\r493.04492 -133.5918 493.04492 -134.41797 493.04492 -134.41797 c\r493.20703 -134.45996 493.44238 -134.50879 493.74707 -134.56055 c\r494.05469 -134.61133 494.35645 -134.6377 494.65527 -134.6377 c\r495.00195 -134.6377 495.30664 -134.60938 495.56348 -134.55273 c\r495.82227 -134.49609 496.04492 -134.40039 496.2334 -134.26465 c\r496.41895 -134.13086 496.56055 -133.95898 496.65918 -133.74805 c\r496.75586 -133.53613 496.80469 -133.27539 496.80469 -132.96191 c\r496.80469 -132.96191 496.80469 -129.67285 496.80469 -129.67285 c\rh\r490.81055 -132.13086 m\r490.81055 -132.71582 490.70801 -133.15234 490.50293 -133.44238 c\r490.29883 -133.73145 489.98438 -133.87598 489.56055 -133.87598 c\r489.31934 -133.87598 489.07813 -133.8252 488.83398 -133.72363 c\r488.5918 -133.62207 488.3584 -133.49023 488.13574 -133.3252 c\r488.13574 -133.3252 488.13574 -130.5752 488.13574 -130.5752 c\r488.37305 -130.47168 488.57715 -130.40039 488.74707 -130.3623 c\r488.91797 -130.3252 489.11133 -130.30664 489.32813 -130.30664 c\r489.79395 -130.30664 490.15723 -130.45996 490.41895 -130.76758 c\r490.67969 -131.07324 490.81055 -131.52734 490.81055 -132.13086 c\rh\r491.66895 -132.15332 m\r491.66895 -131.76074 491.61133 -131.40137 491.49609 -131.0752 c\r491.37988 -130.75098 491.21777 -130.47363 491.00684 -130.24902 c\r490.81152 -130.03516 490.58105 -129.86914 490.31543 -129.75293 c\r490.0498 -129.63574 489.76953 -129.57617 489.47363 -129.57617 c\r489.2168 -129.57617 488.98242 -129.60449 488.77441 -129.65918 c\r488.56445 -129.71387 488.35254 -129.7998 488.13574 -129.91504 c\r488.13574 -129.91504 488.13574 -127.8877 488.13574 -127.8877 c\r488.13574 -127.8877 487.30078 -127.8877 487.30078 -127.8877 c\r487.30078 -127.8877 487.30078 -134.51855 487.30078 -134.51855 c\r487.30078 -134.51855 488.13574 -134.51855 488.13574 -134.51855 c\r488.13574 -134.51855 488.13574 -134.01074 488.13574 -134.01074 c\r488.3584 -134.19336 488.60645 -134.3457 488.88477 -134.46973 c\r489.16211 -134.5918 489.45801 -134.65332 489.77051 -134.65332 c\r490.36914 -134.65332 490.83496 -134.43164 491.16992 -133.99219 c\r491.50293 -133.5498 491.66895 -132.93848 491.66895 -132.15332 c\rh\r485.7998 -131.92383 m\r486.00879 -131.70898 486.11426 -131.42676 486.11426 -131.07324 c\r486.11426 -130.63086 485.92773 -130.26953 485.55273 -129.98535 c\r485.17773 -129.70215 484.66699 -129.56055 484.01953 -129.56055 c\r483.6543 -129.56055 483.31641 -129.60352 483.01172 -129.68945 c\r482.7041 -129.77344 482.44824 -129.86816 482.24023 -129.96875 c\r482.24023 -129.96875 482.24023 -130.88477 482.24023 -130.88477 c\r482.24023 -130.88477 482.28516 -130.88477 482.28516 -130.88477 c\r482.54785 -130.68848 482.83984 -130.53223 483.16211 -130.41602 c\r483.48242 -130.30078 483.79199 -130.24219 484.08594 -130.24219 c\r484.45215 -130.24219 484.73828 -130.30176 484.94434 -130.41797 c\r485.15234 -130.53516 485.25488 -130.71875 485.25488 -130.96973 c\r485.25488 -131.16016 485.19922 -131.30469 485.08789 -131.40332 c\r484.97461 -131.50098 484.75879 -131.58594 484.44238 -131.6543 c\r484.32324 -131.68066 484.16992 -131.71191 483.97852 -131.74609 c\r483.78906 -131.78027 483.61621 -131.81934 483.45898 -131.8584 c\r483.02539 -131.97168 482.71875 -132.13672 482.53711 -132.35449 c\r482.35645 -132.57324 482.26563 -132.8418 482.26563 -133.15918 c\r482.26563 -133.35742 482.30762 -133.5459 482.3916 -133.72363 c\r482.47559 -133.89941 482.60352 -134.05566 482.77539 -134.19531 c\r482.94043 -134.33105 483.15137 -134.43848 483.40625 -134.51855 c\r483.66309 -134.59766 483.94922 -134.6377 484.26563 -134.6377 c\r484.56055 -134.6377 484.86133 -134.60156 485.16309 -134.53125 c\r485.4668 -134.46094 485.71875 -134.37402 485.91992 -134.27344 c\r485.91992 -134.27344 485.91992 -133.40039 485.91992 -133.40039 c\r485.91992 -133.40039 485.875 -133.40039 485.875 -133.40039 c\r485.66309 -133.55664 485.4043 -133.6875 485.10156 -133.79395 c\r484.79688 -133.90137 484.5 -133.95508 484.20703 -133.95508 c\r483.90332 -133.95508 483.64648 -133.89746 483.43848 -133.78223 c\r483.22754 -133.66797 483.12402 -133.49512 483.12402 -133.2666 c\r483.12402 -133.06836 483.1875 -132.91797 483.31348 -132.81641 c\r483.43848 -132.71582 483.63867 -132.63281 483.91504 -132.56934 c\r484.06836 -132.53613 484.24121 -132.50098 484.43066 -132.46582 c\r484.62109 -132.43066 484.7793 -132.39941 484.90723 -132.37012 c\r485.29297 -132.2832 485.59082 -132.13477 485.7998 -131.92383 c\r485.7998 -131.92383 485.7998 -131.92383 485.7998 -131.92383 c\rh\r480.96289 -129.67285 m\r480.96289 -129.67285 480.12793 -129.67285 480.12793 -129.67285 c\r480.12793 -129.67285 480.12793 -132.43164 480.12793 -132.43164 c\r480.12793 -132.63867 480.11719 -132.84082 480.09863 -133.03418 c\r480.08008 -133.22754 480.03906 -133.38281 479.97754 -133.49805 c\r479.90918 -133.62207 479.8125 -133.71777 479.68555 -133.78125 c\r479.55859 -133.84473 479.375 -133.87598 479.13672 -133.87598 c\r478.90332 -133.87598 478.66992 -133.81836 478.43652 -133.70508 c\r478.20508 -133.58984 477.97168 -133.44434 477.73828 -133.26953 c\r477.74707 -133.20215 477.75391 -133.12402 477.76172 -133.03711 c\r477.76758 -132.94922 477.76953 -132.86133 477.76953 -132.77441 c\r477.76953 -132.77441 477.76953 -129.67285 477.76953 -129.67285 c\r477.76953 -129.67285 476.93457 -129.67285 476.93457 -129.67285 c\r476.93457 -129.67285 476.93457 -132.43164 476.93457 -132.43164 c\r476.93457 -132.64551 476.92578 -132.84863 476.90625 -133.04102 c\r476.8877 -133.23438 476.84766 -133.38672 476.78516 -133.50293 c\r476.7168 -133.62793 476.61914 -133.7207 476.49219 -133.7832 c\r476.36523 -133.8457 476.18164 -133.87598 475.94336 -133.87598 c\r475.7168 -133.87598 475.48926 -133.82031 475.26074 -133.71094 c\r475.03223 -133.60156 474.80469 -133.46094 474.57813 -133.29004 c\r474.57813 -133.29004 474.57813 -129.67285 474.57813 -129.67285 c\r474.57813 -129.67285 473.74219 -129.67285 473.74219 -129.67285 c\r473.74219 -129.67285 473.74219 -134.51855 473.74219 -134.51855 c\r473.74219 -134.51855 474.57813 -134.51855 474.57813 -134.51855 c\r474.57813 -134.51855 474.57813 -133.98047 474.57813 -133.98047 c\r474.83789 -134.19238 475.0957 -134.35645 475.35449 -134.47559 c\r475.6123 -134.59375 475.8877 -134.65332 476.17969 -134.65332 c\r476.51758 -134.65332 476.80176 -134.58398 477.03711 -134.44434 c\r477.27148 -134.30566 477.44629 -134.11426 477.56152 -133.86816 c\r477.89844 -134.14453 478.20508 -134.3457 478.48242 -134.46973 c\r478.75977 -134.59082 479.05566 -134.65332 479.37305 -134.65332 c\r479.91504 -134.65332 480.31641 -134.49219 480.57422 -134.16992 c\r480.83301 -133.84766 480.96289 -133.39746 480.96289 -132.81836 c\r480.96289 -132.81836 480.96289 -129.67285 480.96289 -129.67285 c\rh\r471.59766 -132.1084 m\r471.59766 -132.6875 471.49902 -133.12695 471.30371 -133.42578 c\r471.10742 -133.72559 470.79199 -133.87598 470.35645 -133.87598 c\r470.1123 -133.87598 469.86621 -133.8252 469.61719 -133.72168 c\r469.36816 -133.61914 469.13672 -133.48633 468.92285 -133.3252 c\r468.92285 -133.3252 468.92285 -130.54395 468.92285 -130.54395 c\r469.16016 -130.44141 469.36523 -130.36914 469.53516 -130.32715 c\r469.70508 -130.28711 469.89941 -130.26758 470.11621 -130.26758 c\r470.57813 -130.26758 470.94141 -130.41504 471.20313 -130.71191 c\r471.46582 -131.00879 471.59766 -131.47363 471.59766 -132.1084 c\rh\r472.45605 -132.13281 m\r472.45605 -131.72656 472.39746 -131.3623 472.28027 -131.03809 c\r472.16406 -130.71387 472.00586 -130.44336 471.80664 -130.22168 c\r471.59766 -129.99512 471.36621 -129.82324 471.11328 -129.70801 c\r470.8623 -129.59375 470.58496 -129.53613 470.28223 -129.53613 c\r470.00098 -129.53613 469.75586 -129.56934 469.54395 -129.63574 c\r469.33496 -129.69922 469.12695 -129.78711 468.92285 -129.89746 c\r468.92285 -129.89746 468.87012 -129.67285 468.87012 -129.67285 c\r468.87012 -129.67285 468.08887 -129.67285 468.08887 -129.67285 c\r468.08887 -129.67285 468.08887 -136.42285 468.08887 -136.42285 c\r468.08887 -136.42285 468.92285 -136.42285 468.92285 -136.42285 c\r468.92285 -136.42285 468.92285 -134.01074 468.92285 -134.01074 c\r469.15625 -134.19824 469.40527 -134.35352 469.66895 -134.47363 c\r469.93359 -134.59277 470.22949 -134.65332 470.55859 -134.65332 c\r471.14551 -134.65332 471.60742 -134.43457 471.94727 -133.99414 c\r472.28516 -133.55371 472.45605 -132.93359 472.45605 -132.13281 c\rh\r466.43555 -129.67285 m\r466.43555 -129.67285 465.60156 -129.67285 465.60156 -129.67285 c\r465.60156 -129.67285 465.60156 -134.51855 465.60156 -134.51855 c\r465.60156 -134.51855 466.43555 -134.51855 466.43555 -134.51855 c\r466.43555 -134.51855 466.43555 -129.67285 466.43555 -129.67285 c\rh\r466.49414 -135.32715 m\r466.49414 -135.32715 465.54492 -135.32715 465.54492 -135.32715 c\r465.54492 -135.32715 465.54492 -136.17676 465.54492 -136.17676 c\r465.54492 -136.17676 466.49414 -136.17676 466.49414 -136.17676 c\r466.49414 -136.17676 466.49414 -135.32715 466.49414 -135.32715 c\rh\r463.9502 -129.67285 m\r463.9502 -129.67285 463.11523 -129.67285 463.11523 -129.67285 c\r463.11523 -129.67285 463.11523 -136.42285 463.11523 -136.42285 c\r463.11523 -136.42285 463.9502 -136.42285 463.9502 -136.42285 c\r463.9502 -136.42285 463.9502 -129.67285 463.9502 -129.67285 c\rh\rf\rQ\rq\r1 0 0 -1 0 0 cm\r1.25928 -0.97363 m\r1.25928 -0.97363 519.60156 -0.97363 519.60156 -0.97363 c\r519.60156 -0.97363 519.60156 -299.74658 519.60156 -299.74658 c\r519.60156 -299.74658 1.25928 -299.74658 1.25928 -299.74658 c\r1.25928 -299.74658 1.25928 -0.97363 1.25928 -0.97363 c\rh\rW n\r0 0 0 RG\r0 i 1 w 10 M 0 j 0 J []0 d \r/GS0 gs\r1.38965 -299.61914 m\r1.38965 -299.61914 519.47266 -299.61914 519.47266 -299.61914 c\r519.47266 -299.61914 519.47266 -1.10059 519.47266 -1.10059 c\r519.47266 -1.10059 1.38965 -1.10059 1.38965 -1.10059 c\r1.38965 -1.10059 1.38965 -299.61914 1.38965 -299.61914 c\rh\rS\rEMC \rQ\r\rendstream\rendobj\r81 0 obj<</Length 20080/Type/Metadata/Subtype/XML>>stream\r
+<?xpacket begin='' id='W5M0MpCehiHzreSzNTczkc9d'?>
+<?adobe-xap-filters esc="CRLF"?>\r
+<x:xmpmeta xmlns:x='adobe:ns:meta/' x:xmptk='XMP toolkit 2.9.1-13, framework 1.6'>\r
+<rdf:RDF xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#' xmlns:iX='http://ns.adobe.com/iX/1.0/'>\r
+<rdf:Description rdf:about='uuid:7a069029-7a5e-11d8-b649-000a956e58ec' xmlns:pdf='http://ns.adobe.com/pdf/1.3/' pdf:Producer='Mac OS X 10.3.3 Quartz PDFContext'></rdf:Description>\r
+<rdf:Description rdf:about='uuid:7a069029-7a5e-11d8-b649-000a956e58ec' xmlns:xap='http://ns.adobe.com/xap/1.0/'\r
+ xmlns:xapGImg='http://ns.adobe.com/xap/1.0/g/img/' xap:ModifyDate='2004-03-20T03:05:20-08:00' xap:CreateDate='2004-03-20T03:00:43-08:00' xap:CreatorTool='Excel' xap:MetadataDate='2004-03-20T03:05:20-08:00'><xap:Thumbnails><rdf:Alt><rdf:li rdf:parseType='Resource'><xapGImg:format>JPEG</xapGImg:format><xapGImg:width>256</xapGImg:width><xapGImg:height>148</xapGImg:height><xapGImg:image>/9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA
AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK
DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f
Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgAlAEAAwER
AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA
AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB
UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE
1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ
qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy
obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp
0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo
+DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A7Z5D8h+Rp/I3l2efy7pk
s0umWbyyvZ27MzNboWZmKVJJ6nFU9/5V75A/6lnSv+kG2/5oxV3/ACr3yB/1LOlf9INt/wA0Yq7/
AJV75A/6lnSv+kG2/wCaMVd/yr3yB/1LOlf9INt/zRirv+Ve+QP+pZ0r/pBtv+aMVd/yr3yB/wBS
zpX/AEg23/NGKu/5V75A/wCpZ0r/AKQbb/mjFXf8q98gf9SzpX/SDbf80Yq7/lXvkD/qWdK/6Qbb
/mjFXf8AKvfIH/Us6V/0g23/ADRirv8AlXvkD/qWdK/6Qbb/AJoxV3/KvfIH/Us6V/0g23/NGKu/
5V75A/6lnSv+kG2/5oxV3/KvfIH/AFLOlf8ASDbf80Yq7/lXvkD/AKlnSv8ApBtv+aMVd/yr3yB/
1LOlf9INt/zRirv+Ve+QP+pZ0r/pBtv+aMVd/wAq98gf9SzpX/SDbf8ANGKu/wCVe+QP+pZ0r/pB
tv8AmjFXf8q98gf9SzpX/SDbf80Yq7/lXvkD/qWdK/6Qbb/mjFXf8q98gf8AUs6V/wBINt/zRirv
+Ve+QP8AqWdK/wCkG2/5oxV3/KvfIH/Us6V/0g23/NGKu/5V75A/6lnSv+kG2/5oxV3/ACr3yB/1
LOlf9INt/wA0Yq7/AJV75A/6lnSv+kG2/wCaMVd/yr3yB/1LOlf9INt/zRirv+Ve+QP+pZ0r/pBt
v+aMVd/yr3yB/wBSzpX/AEg23/NGKpF588h+RoPI3mKeDy7pkU0WmXjxSpZ26srLbuVZWCVBB6HF
U9/L3/lAPLP/AGyrH/qGTFWQYq7FXYqlvmXTr/UvLuqadp92bC/vLSeC0vVrWGWWNkSQU3+BiDti
rxCf8uvzp0qNbTQLxdOOpzH/AEaz1CeS0tWgsfT+tS3FxbtIfXuR6zRBN/s1qWOKqo/Kb84bXVb6
ez1pOUk949vqP1uQy+le6ja3DKiNCfRItopUIDEFjttiqrceQf8AnIhNBltrTzQsmoSehILie7cN
HIgu1cRssNODA2pIcGtH774qmuq/lR5y1TyNeaDNqC2t9feaZNYkvbeZw8VjNeGYmNuIpKsbfCvS
vfFUr0b8v/z90rT9Oso9btXUu0+pypcvHxla/vbiX04/QYOs8d1DX4l4lKU6Yq6//LL87bjTZLSX
zE1+s6lZ4bm7IWqCwmjZGWCqN9Yiu/ioaKU264qrTeR/+cjF+rmLzVbMg067hMZmflHcypc+hzf0
F9Yp6sA9aimqV49eSrKvOHlL8zZtE0Sx8reYWiubQSjUbu8m4zSSuFMMrOkEgkSFuVYuK8xQchTF
Uhb8m/Mbfl3qnl9NRNvrWs+Yv0rd6sJmeVbf68jiRXIBMi20Yop25bVpirG0/Iz8woJkE81rrE63
GuTS6vPdSwSynU7YR28hhWORVKTcpOPPatK98Vbk/wCce/O9ppXl2z03WFuZbaf63qgu7mSOzhkZ
IFdYbVYZjJQQNxdZY35MTUBtlWXefPIPnjUvO95rflxLexeews7ODVheSR3MbR3qS3LLEIXQc7bl
EDyxVINT/LX8+tTilsrjzNH+jhYyW8am7lSWSZZGeBmeKBaMRxWRm5bdPDFUwuvJf57R6PdS6frt
dUubi5SO0ub9mit7R7Vo7Zo5ha8nlimfk3JRz4r9nFVO8/Lr84LzU4bu+1f6z9S1U3UYTUZIYprK
WOaMRrAttSJoRJGGUs4kodx1xVRi/Lv897TSorCw8xW9rFDptpaxrFOVVZIre1jkWOP6vRGE0dxJ
63M8w6rxHZVPvLPlH84bLzho11qmvrd+W7GO8ivraWZnlmV5rn6oxCxRh5FieDmzsfsnuPiVYwvl
T/nInU4NcuLTXP0WJbyVLO2vJ2MkkEd7MVaLhCfqwNuyKtC3Km/HFWVaV5K/MufyH5u0/wAy6z9e
8wa1YzWWmqs3+iRGTT1i5rxijZC100hYgfZ40AxViafk1+cOh2mqr5c82+td3o0pUurlzDKbewju
oTbqwSYJwSS3+On7wqxalaFVY35R/nREZ7mHXlGsRzXt7a36XshQzXccNI/SeAcIxJG3KnUU2GKp
prPkL8+rqLVIk8xwS211dVFuLp4GmgZ7o/BILWT6oqxTW6NEofl6bHkOW6r1jyrp13pnljSNNvGD
XdlZW1vcMpLKZIolRyGNCRyXriqaYq7FXYqx/wDML/lAPM3/AGyr7/qGfFXfl7/ygHln/tlWP/UM
mKsgxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV
2Ksf/ML/AJQDzN/2yr7/AKhnxV35e/8AKAeWf+2VY/8AUMmKo/zDZ6je6FqFnptybLULi3kjtboG
hjkZSFYMA3Gh/aoadaHFWCea9V85aHJ5R0iDVRFPd29xFqM3prcc5baKNg/OcF26kVNOXU4qh/0v
57/6mH/pzt/6Yq79L+e/+ph/6c7f+mKu/S/nv/qYf+nO3/pirv0v57/6mH/pzt/6Yq79L+e/+ph/
6c7f+mKu/S/nv/qYf+nO3/pirv0v57/6mH/pzt/6Yq79L+e/+ph/6c7f+mKu/S/nv/qYf+nO3/pi
rv0v57/6mH/pzt/6Yq79L+e/+ph/6c7f+mKu/S/nv/qYf+nO3/pirv0v57/6mH/pzt/6Yq79L+e/
+ph/6c7f+mKu/S/nv/qYf+nO3/pirv0v57/6mH/pzt/6Yq79L+e/+ph/6c7f+mKu/S/nv/qYf+nO
3/pirv0v57/6mH/pzt/6Yq79L+e/+ph/6c7f+mKu/S/nv/qYf+nO3/pirv0v57/6mH/pzt/6Yq79
L+e/+ph/6c7f+mKu/S/nv/qYf+nO3/pirLPy81fVNU0WebUrj6zcRXcsAl4JHVUC0+FAo74qyjFX
Yq7FWP8A5hf8oB5m/wC2Vff9Qz4q78vf+UA8s/8AbKsf+oZMVZBirzX80v8AlLPJ/wD28v8AkzHi
qFxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2Ksh/Kz/jg3v/AG0L
j/jXFWZ4q7FXYqx/8wv+UA8zf9sq+/6hnxV35e/8oB5Z/wC2VY/9QyYqmWuW19daLf21hIYb2e3l
itphJ6RSR0Kq4kCTcSpNQeDfI4q8u8+2mvQal5Dt7q5gOox296lxLxlnQzCCLmwZ5EkdT25UPf2x
VS9DX/8AlttP+kWT/soxV3oa/wD8ttp/0iyf9lGKu9DX/wDlttP+kWT/ALKMVYTcec/zJn81azoH
lzy8muvof1b65cRcYQPrcPqx/DLOOvxDYnpkJ5Ix5lNKdz52/NHS9T0i08xeV10e31i8jsILuUpK
olkqfsxzk7AE4IZYy5FaZ16Gv/8ALbaf9Isn/ZRliHehr/8Ay22n/SLJ/wBlGKu9DX/+W20/6RZP
+yjFXehr/wDy22n/AEiyf9lGKu9DX/8AlttP+kWT/soxV3oa/wD8ttp/0iyf9lGKu9DX/wDlttP+
kWT/ALKMVd6Gv/8ALbaf9Isn/ZRirvQ1/wD5bbT/AKRZP+yjFXehr/8Ay22n/SLJ/wBlGKu9DX/+
W20/6RZP+yjFXehr/wDy22n/AEiyf9lGKu9DX/8AlttP+kWT/soxV3oa/wD8ttp/0iyf9lGKu9DX
/wDlttP+kWT/ALKMVd6Gv/8ALbaf9Isn/ZRiqRec/M2reVtHGp3Dx3itNFbx29taOZGeZuKgBrlR
1xVKP8a/mV/1JGtf9wpv+yvKvGh3hNJx5N8yar5q0GLWbWWG2ileSP0J7RxIrROY2rxuWHVctQ9M
/KgOPL12HIZ/r8/JlFATRakAk0+/FWaYq7FXYqx/8wv+UA8zf9sq+/6hnxV35e/8oB5Z/wC2VY/9
QyYqyDFXmv5pf8pZ5P8A+3l/yZjxVC4q7FXYqkv5Mf8Ak2fzS/7cP/UHLmBrenxZRV/+chP96Py/
/wDAlt/+TUmR0f1H3JkmebFg7FXYq7FUn1rzh5W0OdLfWNVtrCeVPUjjuJVjZkqRyAJ6VGKpf/yt
H8uv+pj0/wD6SE/rirKMVdirsVdirsVdirsVdirsVdirBPzj/wCUc03/ALbGnf8AJ8ZGXIq+h80j
a+dfyQ/5QGH/AJjL7/qKkzeDk1PX/wArP+ODe/8AbQuP+NcKszxV2KuxVj/5hf8AKAeZv+2Vff8A
UM+Ku/L3/lAPLP8A2yrH/qGTFU31KG+n0+5hsLlbO9kjZLe7aMTCJyKK/pkoH4nehOKvK/zAtNdg
1PyHb3N5DNqMNteR3Ny0TOrzpbxCSSgeMkNQ+Hj7Yqoehr//AC22n/SLJ/2UYq70Nf8A+W20/wCk
WT/soxV3oa//AMttp/0iyf8AZRiqB/JFbhfzT/NAXDpJN/uC5PGhjU/6JLSilpCNv8rMDW9Piyii
f+ciRKZPIIiZUkPmS34MyllB9KShKgrX78jo/qPuTJV9DX/+W20/6RZP+yjNiwd6Gv8A/Lbaf9Is
n/ZRirvQ1/8A5bbT/pFk/wCyjFXehr//AC22n/SLJ/2UYqxjR9Gt9S/P6wtdet7TVIf8OzusUlsD
ECLpQDwlaYchU75jaokQ2TFOf+ckPJ3lHTvyX8xXmn6Hp9ndxfU/SuLe1hikXlfQK3F0UMKqSDmJ
p5kzG7I8kd6Gv/8ALbaf9Isn/ZRm0YO9DX/+W20/6RZP+yjFXehr/wDy22n/AEiyf9lGKu9DX/8A
lttP+kWT/soxVi/nHXvPWl6joOl6L+jbzUNdu2tIRdRTwxqwTmCWSZz28MjKQiLKr9WsP+ciNL0q
91O5svLRtrGCW5nCS3hbhChduIJFTRdsoGqgTSeFH+U9U8x655Z0zWJLizgfULaO4aFbaVgpkUNQ
E3ArTMlCbehr/wDy22n/AEiyf9lGKu9DX/8AlttP+kWT/soxV3oa/wD8ttp/0iyf9lGKsJ/NqLVl
0HTTc3MEsX6Y0+qxwPG1fXFPiaaQfhkZcir6SzSNr5q/JiLVm8jRG2ubeOL65e0SSB5G/wB6Xr8Q
mjH4ZvByantP5UBx5euw5DP9fn5MooCaLUgEmn34VZpirsVdirH/AMwv+UA8zf8AbKvv+oZ8Vd+X
v/KAeWf+2VY/9QyYqw38sPMfm7UvzD882OtuVtLCWBbGzFwlxHCCZBxSkUDfEAGPXsDuMVRH5pf8
pZ5P/wC3l/yZjxVC4q7FXYqkv5Mf+TZ/NL/tw/8AUHLmBrenxZRV/wDnIT/ej8v/APwJbf8A5NSZ
HR/UfcmSZ5sWDsVdirsVYz5f/wDWidP/APAauP8AqLXMXV/R8WUU/wD+cn//ACRnmX/ox/7qFvmH
pv7wMpclfNs1uxV2KuxVhvmz/wAmH+XH/bZb/kwcqz/QUjm9f/MH/lAvMv8A2yr3/qHfNVj+oe9m
XlX5Xf8AkuvLn/bPt/8AiAzdNbKMVdirsVYJ+cf/ACjmm/8AbY07/k+MjLkVfQ+aRtfOv5If8oDD
/wAxl9/1FSZvByamTateeY7P8odbn8ufWTrS6jN9SjsxIZnk2IVVi+Nq0+yOuFWI/l/rf55XGmPP
rOk6xcyi/SJ/ry6jYyJacUZ3WNJULftLUBv4YSrO7bXfOM8cbw+VtQnDKWmH6U1GL0T9YMSxnm59
U8FqWTp9qnEjArLPJUB13y/DqWpWuoaXdyM6vZvqGoErwYr1aVOW4+0BQ9RtiqF86WaWWieaIIZr
h4X8vXrtHPcz3C8hHIKgTPJxNPDFU9/L3/lAPLP/AGyrH/qGTFWCeSU1M/mB+ZkFrGyTkwNagmSJ
Fkk9cD4mDKjMAr7Bq1DVFeIVUPO9r5lhvPIEGpXcEmsR2t4l7cem0iPcLBEJXFGhqrb02GKrfQ1/
/lttP+kWT/soxV3oa/8A8ttp/wBIsn/ZRirvQ1//AJbbT/pFk/7KMVQP5IrcL+af5oC4dJJv9wXJ
40Man/RJaUUtIRt/lZga3p8WUUT/AM5EiUyeQREypIfMlvwZlLKD6UlCVBWv35HR/UfcmSr6Gv8A
/Lbaf9Isn/ZRmxYO9DX/APlttP8ApFk/7KMVd6Gv/wDLbaf9Isn/AGUYq70Nf/5bbT/pFk/7KMVS
Lyol6v8AzkNYC7ljlf8Aw3ccWijaIAfW12IZ5f15i6v6Piyiyb/nJ/8A8kZ5l/6Mf+6hb5h6b+8D
KXJDehr/APy22n/SLJ/2UZtmtRvJtUsraS6vNUsLa1hHKWea3eONF8WZrkAD54qkv+PNA/6nLy//
AMHH/wBlmKpnpeqTavC8+la5pmoQxtwkltYjMqtSvEtHdMAaHpiqQ+Yo9SX8xfy6+tzwyr+mG4iK
FoiD6J6lpZa5Vn+gpHN7R+YP/KBeZf8AtlXv/UO+arH9Q97MvHPyzh1o/l95eMV3bJEbCDgr20jM
BwGxYTrX7s3TWyK4Gvw28s31u0b00Z+P1WQV4itP96MVeXaR+av5t6xpsGpad5QtJ7K4BaGX65Gn
IBip+F5FYbjuMy8egzTiJRGx8wxMgE+8leevO+u+YL/Q9W0200S8sLeO5K1N3yWVqD+7lVR9+U5c
MscuGQopBtv82otWXQdNNzcwSxfpjT6rHA8bV9cU+JppB+GUS5FL6SzSNr5q/JiLVm8jRG2ubeOL
65e0SSB5G/3pevxCaMfhm8HJqZjfWvme6/KXVLby47/4jl1ORNPeB1t2+sEDiUd2ATfxb6cKoP8A
KTy1/wA5E2drdt5m1GSC45TfV4dUuYr9WrCvonlA8hCiVSGFRsxNCaYpLMWT88LaO4uWuNNvjCga
1s44fRMzLETxlYySUMkvwngRxFG33XFCO8uj8231uN9al09NES6vEmRIj9ZkhRmS1daPxRXCq/Vm
38Oiq/8AML/jleZv/Acvv+IPiqbfl7/ygHln/tlWP/UMmKsX/LTyT5l0Tzl5x1zWrayiXX54ZraS
0kmdz6XqKxdZCVXkOLfDTw3psqt/NL/lLPJ//by/5Mx4q8o/N2K5vPMHk7Skvruxtr+4u0uWs5mg
dgkKuvxL4Ed8yNJiGTIInkUSNBIvMvkCLTfLmq6jb+YNcNxZWdxcQh7+QrziiZ15AAbVGbnP2Xij
CUhdgFrEzb03yHNNP5G8uzzyNLNLplm8srkszM1uhZmY7kk9TnPNq/8AJj/ybP5pf9uH/qDlzA1v
T4soq/8AzkJ/vR+X/wD4Etv/AMmpMjo/qPuTJM82LBhf5q+Y9d0HQbGbRJYob681G2shJMnqIFn5
CpX5gZKEeKQHepSPj+c//V/0v/pDb+ubj+Rp/wA4NfiMh/KrzHq3mLyZbapqzo9881xHI0S8FIim
ZBRfkuaYii2Iny//AOtE6f8A+A1cf9Ra5iav6Piyin//ADk//wCSM8y/9GP/AHULfMPTf3gZS5K+
bZrYf+b/AP5LPzD/AMwjf8SGKpHo3krybJo9jJJoOnPI9vEzu1pASSUBJJKZ2GPTYjEemPLuDjmR
XfkxbW9rL5wt7aJILeLXJkihjUIiqI0AVVWgAGcvq4gZZAcrb48k482f+TD/AC4/7bLf8mDmFn+g
shzev/mD/wAoF5l/7ZV7/wBQ75qsf1D3sy8q/K7/AMl15c/7Z9v/AMQGbprZBqP/ABz7n/jE/wDx
E4q8y/KL/wAlzon/ABik/wCTz513Z39xH8dWifNFeUf/ACcHmL/tl2f/ABM5o+1v774Bsx8kw/OP
/lHNN/7bGnf8nxmrlyLN9D5pG186/kh/ygMP/MZff9RUmbwcmplGpeVdW81flDruhaVGJLy81CZE
BZFAB4gsS7IKCvjhViPkL8jfzD8t6bJbj1LCQ38d76dhJGY3SNUHpsz3kcg+OOteRxVncvlb81Vt
4xBrOrG55SPcSSizKS1mEkYCLej0wsYKEId8VU7Dyv8Am6n1Y32rahNGsIS7tQLXg7F2baT66JPh
5fa25UCkBcVTTUNP8wW3kTX11dLiSW28v38D39x6AaZ2WVwQkM0/GiUr0HhttirLfy9/5QDyz/2y
rH/qGTFU01gX50m8GnoJL8wyC1RpPRBlKkJWTjJw3/a4mnhiryvz3b+YI7/yDDe3UT6pHa3cd3PJ
H6nO4S3iEsh4PEPjIJoKU/DFXnX5hx6ivnjyJ9bnhmBub3h6UTRU/wBHFa8pJa5m9n/38fx0Yz5J
j55/5QnzB/2zbz/kw+dNqv7qX9U/c0x5vKvL/mb8zYdB02Gz80/V7OO1gS2t/qFo/pxrGoRObLyb
iu1Tuc5AY3f4uyuKIlxcxfL9r1r/AJxYu9Wu/NX5hXGr3n1/UH/Q/r3fppDzpDcBf3cYCiigDbNd
rxRH47nBzYfCmY3dMm/5yJEpk8giJlSQ+ZLfgzKWUH0pKEqCtfvyvR/Ufc0yVfQ1/wD5bbT/AKRZ
P+yjNiwYD+cceqLo+hG6uIJY/wBO2HwxQPG1eTb8mlk/Vlun/vI+8feg8mU52rjvGPy5/Nq60Hyv
Fp0WmXNxGk1xIJY7USqfUlZ6c/rEVaV/lzhyCS58NPkkLESQzz8nfOUvmn894LuW1ltHg0C4i9Oa
H0GI+so1Qvqz1G/WuYmsHo+KJY5QNSFPSf8AnJ//AMkZ5l/6Mf8AuoW+YWm/vAiXJDehr/8Ay22n
/SLJ/wBlGbZrYl+bMWsj8uNfM11bPELVuapbyIxHIdGM7gfdiqL0L/jiaf8A8w0P/JsZ2+L6B7nG
Lzvyl+Y/lzyzrXm601LWYdOlm1m4lSKWzurosoCpyDQEKN1Ioc5HWf30v6xciPJN7f8AMHy/5p/M
3yDb6Xq8OpSW2qmSRIrO5tSoaJgCWnJDfIZg5/oLIc30Z+YP/KBeZf8AtlXv/UO+arH9Q97MvHPy
zh1o/l95eMV3bJEbCDgr20jMBwGxYTrX7s3TWn2oQ699Qua3lqR6T1AtZP5T/wAvGKsC/KL/AMlz
on/GKT/k8+dd2d/cR/HVonzYrq/nfV/LX5q61LpmnC/kksrWGRWNKADmG+0n81M0fam+c+4OTpsE
8gqItDeZvzQ8x+YV0nTNQ0dbG3fVLJ/XBBPJJgQP7x+vyzWziQC3ZNLkxi5Cg+1M0TB81fkxFqze
RojbXNvHF9cvaJJA8jf70vX4hNGPwzeDk1PafyoDjy9dhyGf6/PyZRQE0WpAJNPvwqzTFXYq7FWP
/mF/ygHmb/tlX3/UM+Ku/L3/AJQDyz/2yrH/AKhkxVkGKvNfzS/5Szyf/wBvL/kzHiry38zf+U38
hf8AMVff9Q4zN7P/AL+P46MZ8kR55/5QnzB/2zbz/kw+dNqv7qX9U/c0x5vJdB/44enf8wsP/Jtc
5SPJ7fTf3Uf6o+567/zir/ylH5hf9uf/AJM3GavtDmPx3Og1/wDfy+H3BlX/ADkJ/vR+X/8A4Etv
/wAmpMq0f1H3OFJM82LB53+dn/HC0L/tvaf/AMSbLdP/AHkfePvQeSf52rjvnnyN/wAo7D/xkl/5
OHOMhyev7M/uR8fvek/kJ/5PYf8AbBm/6iFzC1/0uv7V/vR/V/SXrf8Azk//AOSM8y/9GP8A3ULf
Nfpv7wOtlyV82zWw/wDN/wD8ln5h/wCYRv8AiQxVboX/ABxNP/5hof8Ak2M7fF9A9zjF4jZf8pV5
s/7as/8AxNs5bP8A3s/6xem7G+gp15T/APJv+Q/+Y9/+IDMDV/QV7X/h+P6H1n+YP/KBeZf+2Ve/
9Q75psf1D3umLyr8rv8AyXXlz/tn2/8AxAZumtkGo/8AHPuf+MT/APETirzL8ov/ACXOif8AGKT/
AJPPnXdnf3Efx1aJ82C+Zf8Ayauuf8w1r/ybXNN2h/fy+H3O87E5y9yX61/vTov/AG1bP/k5muzf
SXO7V/uvi+68550L51/JD/lAYf8AmMvv+oqTN4OTU9f/ACs/44N7/wBtC4/41wqzPFXYq7FWP/mF
/wAoB5m/7ZV9/wBQz4q78vf+UA8s/wDbKsf+oZMVTfUVu20+6WzYpdtDILZxxBEhU8COYdftfzKR
7Yq8t/MWPXP0x5FW4mhXUBb3gumaMyL9YFvF6p+BogVJrSgH8MVea/mHHqK+ePIn1ueGYG5veHpR
NFT/AEcVryklrmb2f/fx/HRjPkmPnn/lCfMH/bNvP+TD502q/upf1T9zTHm8l0H/AI4enf8AMLD/
AMm1zlI8nt9N/dR/qj7nrv8Azir/AMpR+YX/AG5/+TNxmr7Q5j8dzoNf/fy+H3BlH/ORIlMnkERM
qSHzJb8GZSyg+lJQlQVr9+VaP6j7nCkq+hr/APy22n/SLJ/2UZsWDAfzjj1RdH0I3VxBLH+nbD4Y
oHjavJt+TSyfqy3T/wB5H3j70HkynO1cd88+Rv8AlHYf+Mkv/Jw5xkOT1/Zn9yPj970n8hP/ACew
/wC2DN/1ELmFr/pdf2r/AHo/q/pL1v8A5yf/APJGeZf+jH/uoW+a/Tf3gdbLkhvQ1/8A5bbT/pFk
/wCyjNs1sS/NmLWR+XGvma6tniFq3NUt5EYjkOjGdwPuxVF6F/xxNP8A+YaH/k2M7fF9A9zjF4jZ
f8pV5s/7as//ABNs5bP/AHs/6xem7G+gp15T/wDJv+Q/+Y9/+IDMDV/QV7X/AIfj+h9Z/mD/AMoF
5l/7ZV7/ANQ75psf1D3umLxz8s4daP5feXjFd2yRGwg4K9tIzAcBsWE61+7N01p9qEOvfULmt5ak
ek9QLWT+U/8ALxirAvyi/wDJc6J/xik/5PPnXdnf3Efx1aJ82C+Zf/Jq65/zDWv/ACbXNN2h/fy+
H3O87E5y9yX61/vTov8A21bP/k5muzfSXO7V/uvi+68550L5q/JiLVm8jRG2ubeOL65e0SSB5G/3
pevxCaMfhm8HJqe0/lQHHl67DkM/1+fkyigJotSASaffhVmmKuxV2Ksf/ML/AJQDzN/2yr7/AKhn
xV35e/8AKAeWf+2VY/8AUMmKsgxV5r+aX/KWeT/+3l/yZjxV5b+Zv/Kb+Qv+Yq+/6hxmb2f/AH8f
x0Yz5Ijzz/yhPmD/ALZt5/yYfOm1X91L+qfuaY83kug/8cPTv+YWH/k2ucpHk9vpv7qP9Ufc9d/5
xV/5Sj8wv+3P/wAmbjNX2hzH47nQa/8Av5fD7gyr/nIT/ej8v/8AwJbf/k1JlWj+o+5wpJnmxYPO
/wA7P+OFoX/be0//AIk2W6f+8j7x96DyT/O1cd88+Rv+Udh/4yS/8nDnGQ5PX9mf3I+P3vSfyE/8
nsP+2DN/1ELmFr/pdf2r/ej+r+kvW/8AnJ//AMkZ5l/6Mf8AuoW+a/Tf3gdbLkr5tmth/wCb/wD5
LPzD/wAwjf8AEhiq3Qv+OJp//MND/wAmxnb4voHucYvEbL/lKvNn/bVn/wCJtnLZ/wC9n/WL03Y3
0FOvKf8A5N/yH/zHv/xAZgav6Cva/wDD8f0PrP8AMH/lAvMv/bKvf+od802P6h73TF5V+V3/AJLr
y5/2z7f/AIgM3TWyDUf+Ofc/8Yn/AOInFXmX5Rf+S50T/jFJ/wAnnzruzv7iP46tE+bBfMv/AJNX
XP8AmGtf+Ta5pu0P7+Xw+53nYnOXuS/Wv96dF/7atn/yczXZvpLndq/3Xxfdec86F86/kh/ygMP/
ADGX3/UVJm8HJqev/lZ/xwb3/toXH/GuFWZ4q7FXYqx/8wv+UA8zf9sq+/6hnxV35e/8oB5Z/wC2
VY/9QyYqmWuJqj6NfJpLiLU2gkFnIQp4ylTxI5hkrXpyBHiCMVYJ5q8oeftY/wAKXcE1i2o6VBON
Se8LqGmniRCQIF4n7JrxAFegpirEfNH5NfmhrmqaNqQv9EtrjRZJpYFpdyI5mQIQ4oh2A7HLcOU4
5iQ5hBFqOq/k5+cep6XeabPq3l1YL2CS2laOC+DhJUKMVJkYVo21Rmdk7VySiYkR3Fdf1sRAMetP
+cY/zNtbSG1j1vRTHBGsSForupCAKK0I32zXiZdrDtTJGIiBHYef62R/l/8Ak9+cnka/1m90nVfL
s8uufVvra3cF86r9UV1j9P05IiKiU8qk/RmPmxDJzcPNnOSRkeZTLzb+XP50+a59Fk1fUfLaJol/
HqVulpDfRF5I1KhXaSSb4aN2GDFgjA2GolMpfJn5rqoKPobtyUEc7sbFgGO69hvlyEj85fk9+Zvm
awtLSS+0W2NneQ30br9berwElVYFR8JrvvkoS4SCOit/8qt/Or/q6eW/+ke//wCqubT+WMvdH7f1
tfhhhulf84s/mTplktpBrmjNGhZgZIrotViWPTj45rBMh2WDtCeKPCAK/HmnflH8hvza8rebP8Ua
frGgS34tGsfSuIbxofTdw5PFHRuVR/NT2yrNAZBRadRqZZZcRrlTIvPn5f8A54+dfKl95Z1XUvLM
NhqHpetLa2+oJMPRmSdeLSSyL9qMVqp2ynHpoxNi2glMJfJn5rrE7RvobyBSUTndjkQNhUr3zIQl
nmn8q/zN8w+Xr/RZrrRYIr6IxPMhuyygkGoBSnbFUFaflJ+c1raw20eq+XDHAixoWgvqkIAorSQe
GbSPa+UCqj9v62Hhhi0X/OMH5lx6hqN8ut6KZtSuHup1MV1xDuSSE3qBv3JzAnmMpGXebc7TayeE
VED4onTv+ccPzSsPMekeYIda0NrzRpjPaxvFdmJmYUpIAwYjbswyrJ6xRXU6yeauIDZ6HrGgfn7q
2kX2l3F/5US3v7eW1maO21EOEmQxsVJnYVo21RmKNJEG93G4kt8uflh+Z2h6DYaPFc6JNFYQJbpK
5uwzCNaVICZlMUW3kf8ANa4syksmhxPNHxkXldniWWhFQtDTFWLeXPyP/N7QNFtdHs9X8vyW1opW
N5oL1pCGYv8AEVdB1bwzY4e08mOAiBGh7/1sDAFKb7/nGr8z7zzBda5LrWiLd3kcccqLFdiMCJQo
4gktXbffMbNqZZJmRqy5el1MsN8Nb96jdf8AOMH5mXL2rvreig2lxHdR8Yrrd4TyUNUnbxymUuIU
26jXzyx4SB+Pi9Y+qf8AOQv/AC2+Uv8ApF1L/sozC/Jw7y4nExfyb+UX5m+WNDTSYbzRblElmmMr
/W1JM0jSEUCnYFsy2L0n8vdB1nRdDlttXMH12W6mnb6qzNHxcgLQuFO4WtMVZPirsVdirH/zC/5Q
DzN/2yr7/qGfFXfl7/ygHln/ALZVj/1DJirIMVdirsVdirz3zB+Vuqatq17qUXmBrCW4mWS2EFu1
YFSIx7Vn4tIeVfV416UpQUVZd5Z0ebRtCtNMlufrj2ysv1jh6dVLllHHk/2VIXdiTSpJOKppirsV
dirsVYl5s8l6lrt3NLBqwsoJreCAwmGWUo0M7StLGyzwqjuj8OQXkNmBqFoqjPJPla58t6bc2dxq
UmqPcXT3XryqVK+oqAoAWk25IW69ScVZDirsVdirsVY/518s3vmLSobK01N9KkiuEuDOieqGEYai
MnOMEBmDippVRUEbYqreVPL0+g6bLZTancas8lzPc/W7ziZv37l+JKBV2J7KB4ACgCqdYq7FXYq7
FUBrumNqmj3enrIsRuozGJHRpFWvcorxk/8ABYqk/kjyhfeXIrtbzVDqclyLdQ/pvEFFvCIakNLN
yd+PJ3rUn2CgKsnxV2KuxV2KuxV2Ksf/ADC/5QDzN/2yr7/qGfFXfl7/AMoB5Z/7ZVj/ANQyYqyD
FXYq7FXYq7FXYq7FXYq7FXYq8ok/Ibjf6jead5nv9JbULm8upIdP/wBGi5Xqyq/JI3VXZTKpDMK/
AuKtx/kRJDp97bQebtXjnu+dLoTy8laUsZpCnqcGd+ezUHGgp3qqpt+QCSXrXs3mrVZbsiUR3Tyy
NKhcSiN0ZpGVHjM7EFFXtx471VRX/KltTF5DcL551xQtxaTzxC4k4yC0jjQR0LkcWMbMag/a3qQD
iqy+/IWwfUtT1XS/MOp6Pqer6i2o389lKYlkUs7LA6IUDKplO7deh22xVEa/+Rukazqej6lJrOow
XWi29nb28kczM0jWd2Lv1ZmkLtIzOP2ieJ37Yql2nf8AOP31W7hvZvN+sXV9A0bpeyTOZw0bk/bL
tUFPgKsCKe1AFU68rflLNonmHT9auvM2pazLp9vJbxw38jSrWUtydeTNQkOOVak0602xV6FirsVd
irsVdirsVdirsVdirsVdirsVY/8AmF/ygHmb/tlX3/UM+KsS8l/8rY/wdoP1D9A/Uf0dafVfX+ue
r6XoJ6fqcPh58acqbVxVOf8AkM3/AH7n/T9irv8AkM3/AH7n/T9irv8AkM3/AH7n/T9irv8AkM3/
AH7n/T9irv8AkM3/AH7n/T9irv8AkM3/AH7n/T9irv8AkM3/AH7n/T9irv8AkM3/AH7n/T9irv8A
kM3/AH7n/T9irv8AkM3/AH7n/T9irv8AkM3/AH7n/T9irv8AkM3/AH7n/T9irv8AkM3/AH7n/T9i
rv8AkM3/AH7n/T9irv8AkM3/AH7n/T9irv8AkM3/AH7n/T9irv8AkM3/AH7n/T9irv8AkM3/AH7n
/T9irv8AkM3/AH7n/T9irv8AkM3/AH7n/T9irv8AkM3/AH7n/T9irv8AkM3/AH7n/T9irv8AkM3/
AH7n/T9irv8AkM3/AH7n/T9irv8AkM3/AH7n/T9irv8AkM3/AH7n/T9irv8AkM3/AH7n/T9irv8A
kM3/AH7n/T9irv8AkM3/AH7n/T9irv8AkM3/AH7n/T9iqTedP+Vsf4O176/+gfqP6Ou/rXofXPV9
L0H9T0+fw8+NeNdq4q//2Q==</xapGImg:image></rdf:li></rdf:Alt></xap:Thumbnails></rdf:Description>\r
+<rdf:Description rdf:about='uuid:7a069029-7a5e-11d8-b649-000a956e58ec' xmlns:xapMM='http://ns.adobe.com/xap/1.0/mm/' xapMM:DocumentID='uuid:ee245c78-7a5d-11d8-b649-000a956e58ec'/>\r
+<rdf:Description rdf:about='uuid:7a069029-7a5e-11d8-b649-000a956e58ec' xmlns:dc='http://purl.org/dc/elements/1.1/' dc:format='application/pdf'/>\r
+</rdf:RDF>\r
+</x:xmpmeta>\r
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<?xpacket end='w'?>\rendstream\rendobj\rxref\r0 82\r0000000001 65535 f\r
+0000000002 00001 f\r
+0000000003 00001 f\r
+0000000006 00001 f\r
+0000000016 00000 n\r
+0000000384 00000 n\r
+0000000007 00001 f\r
+0000000008 00001 f\r
+0000000009 00001 f\r
+0000000010 00001 f\r
+0000000011 00001 f\r
+0000000012 00001 f\r
+0000000013 00001 f\r
+0000000014 00001 f\r
+0000000015 00001 f\r
+0000000016 00001 f\r
+0000000017 00001 f\r
+0000000018 00001 f\r
+0000000021 00001 f\r
+0000000434 00000 n\r
+0000000495 00000 n\r
+0000000023 00001 f\r
+0000000645 00000 n\r
+0000000025 00001 f\r
+0000000666 00000 n\r
+0000000026 00001 f\r
+0000000027 00001 f\r
+0000000028 00001 f\r
+0000000029 00001 f\r
+0000000030 00001 f\r
+0000000031 00001 f\r
+0000000032 00001 f\r
+0000000033 00001 f\r
+0000000034 00001 f\r
+0000000035 00001 f\r
+0000000036 00001 f\r
+0000000037 00001 f\r
+0000000038 00001 f\r
+0000000039 00001 f\r
+0000000040 00001 f\r
+0000000041 00001 f\r
+0000000042 00001 f\r
+0000000043 00001 f\r
+0000000044 00001 f\r
+0000000045 00001 f\r
+0000000046 00001 f\r
+0000000047 00001 f\r
+0000000048 00001 f\r
+0000000049 00001 f\r
+0000000050 00001 f\r
+0000000051 00001 f\r
+0000000052 00001 f\r
+0000000053 00001 f\r
+0000000054 00001 f\r
+0000000055 00001 f\r
+0000000056 00001 f\r
+0000000057 00001 f\r
+0000000058 00001 f\r
+0000000059 00001 f\r
+0000000060 00001 f\r
+0000000061 00001 f\r
+0000000062 00001 f\r
+0000000063 00001 f\r
+0000000064 00001 f\r
+0000000065 00001 f\r
+0000000066 00001 f\r
+0000000067 00001 f\r
+0000000068 00001 f\r
+0000000069 00001 f\r
+0000000070 00001 f\r
+0000000071 00001 f\r
+0000000072 00001 f\r
+0000000073 00001 f\r
+0000000074 00001 f\r
+0000000075 00001 f\r
+0000000076 00001 f\r
+0000000077 00001 f\r
+0000000078 00001 f\r
+0000000000 00001 f\r
+0000000778 00000 n\r
+0000000801 00000 n\r
+0000179037 00000 n\r
+trailer\r<</Size 82/Root 19 0 R/Info 20 0 R/ID[<7a04c2147a5e11d8b649000a956e58ec><7a04c2147a5e11d8b649000a956e58ec>]>>\rstartxref\r199194\r%%EOF\r
\ No newline at end of file
--- /dev/null
+@inproceedings{mohca,
+ author = "Scott Malabarba and Premkumar T. Devanbu and Aaron Stearns",
+ title = "MoHCA-Java: A Tool for C++ to Java Conversion Support",
+ booktitle = "International Conference on Software Engineering",
+ pages = "650-653",
+ year = "1999",
+ note = "citeseer.ist.psu.edu/malabarba99mohcajava.html" }
+
+@book{java,
+ author = "James Gosling and others",
+ title = "The {Java} Language Specification",
+ publisher = "GOTOP Information Inc.",
+ year = "1996",
+ address = "5F, No.7, Lane 50, Sec.3 Nan Kang Road Taipei, Taiwan; Unit 1905, Metro Plaza Tower 2, No. 223 Hing Fong Road, Kwai Chung, N.T., Hong Kong",
+ note = "citeseer.ist.psu.edu/gosling96java.html" }
+
+@article{capp,
+ title = "Cappuccino -- A C++ To Java Translator",
+ author = "Frank Buddrus and Jorg Schodel",
+ journal = "Proceedings of the 1998 ACM symposium on Applied Computing",
+ year = "1998" }
+
+@misc{hotspot,
+ title = "The Java Hotspot performance engine architecture",
+ note = "http://java.sun.com/products/hotspot/whitepaper.html",
+ year = "1999" }
+
+@article{KR,
+ author = "Kernighan, B. W. and Ritchie, D. M.",
+ year = "1979",
+ title = "The C Programming Language",
+ publisher = "Englewood Cliffs, NJ: Prentice-Hall" }
+
+@article{soustroup,
+ author = "B. Stroustrup.",
+ title = "The C++ Programming Language",
+ publisher = "Addison-Wesley",
+ year = "1997" }
+
+@misc{csharp,
+ title = "The C\# Programming Language",
+ note = "http://download.microsoft.com/download/0/a/c/0acb3585-3f3f-4169-ad61-efc9f0176788/CSharp.zip" }
+
+@article{jni,
+ title = "The JavaTM Native Interface: Programmer's Guide and Specification",
+ author = "Sheng Liang",
+ publisher = "Addison Wesley Longman, Inc.",
+ year = "1999" }
+
+@misc{cni,
+ title = "The Cygnus Native Interface for C++/Java Integration",
+ note = "http://gcc.gnu.org/java/papers/cni/t1.html" }
+
+@misc{j2me,
+ note = "http://java.sun.com/j2me/docs/index.html" }
+
+@misc{parrot,
+ note = "http://www.parrotcode.org" }
+
+@misc{python,
+ note = "http://www.python.org" }
+
+@misc{jazillian,
+ note = "http://www.jazillian.com/" }
+
+@misc{c2j,
+ note = "http://www.soften.ktu.lt/~stonis/c2java/" }
+
+@article{c2jpp,
+ note = "C2J ?C to Java translator",
+ year = "September 2001",
+ author = "Novosoft",
+ note = "http://www.novosoftus.com/NS2B.nsf/w1/C2J" }
+
+@article{ephedra,
+ author = "J. Martin",
+ title = "Ephedra: A C to Java Migration Environment",
+ publisher = "PhD thesis, University of Victoria",
+ year = "2002",
+ note = "http://www.rigi.csc.uvic.ca/?jmartin/Ephedra" }
+
+@article{egcsjvm,
+ author = "T. Waddington",
+ title = "Java Backend for GCC",
+ note = "http://archive.csee.uq.edu.au/?csmweb/uqbt.html\#gccjvm",
+ year = "November 2000" }
+
+@misc{gcc,
+ note = "http://gcc.gnu.org/" }
+
+@misc{jikes,
+ note = "http://www-124.ibm.com/developerworks/oss/jikes/" }
+
+@misc{msil,
+ note = "http://research.microsoft.com/~emeijer/Papers/CLR.pdf" }
+
+@misc{ibex,
+ note = "http://www.ibex.org" }
+
--- /dev/null
+\documentclass{article}
+\input tmp.inputs
+\pagestyle{empty}
+\usepackage{amssymb,amsbsy}
+\begin{document}
+\newlength{\MyLength}
+\settowidth{\MyLength}{machine code}
+\newcommand{\MyBox}[1]{\makebox[\MyLength][c]{#1}}
+\begin{psmatrix}[colsep=2,rowsep=0]
+ & \\[0pt]
+ [name=s0]\MyBox{unsafe source} & [name=s1]\MyBox{safe source} \\[0pt]
+ [name=s00]\MyBox{\tt (.c)} & [name=s11]\MyBox{\tt (.java)} \\[0pt]
+ & \\[0pt]
+ & \\[0pt]
+ & \\[0pt]
+ [name=b0]\MyBox{machine code} & [name=b1]\MyBox{safe bytecode} \\[0pt]
+ [name=b00]\MyBox{\tt (.o)} & [name=b11]\MyBox{\tt (.class)} \\
+ & \\[0pt]
+ \psset{nodesep=5pt,arrows=->}
+\end{psmatrix}
+\end{document}
--- /dev/null
+\documentclass{article}
+\input tmp.inputs
+\pagestyle{empty}
+\usepackage{amssymb,amsbsy}
+\begin{document}
+\newlength{\MyLength}
+\settowidth{\MyLength}{xmachine codex}
+\newcommand{\MyBox}[1]{\makebox[\MyLength]{#1}}
+\psmatrix[colsep=2,rowsep=0,nrot=:D]
+ & \\[0pt]
+ [name=s0]\MyBox{unsafe source} & [name=s1]\MyBox{safe source} \\[0pt]
+ & \\[0pt]
+ & \\[0pt]
+ & \\[0pt]
+ & \\[0pt]
+ & \\[0pt]
+ [name=b0]\MyBox{machine code} & [name=b1]\MyBox{safe bytecode} \\[0pt]
+ & \\[0pt]
+ \psset{nodesep=5pt,arrows=->}
+ \ncline{s0}{b0}\bput{:U}{\tt gcc}
+ \ncline{s1}{b0}\bput{:D}{\tt gcj}
+ \ncline{s1}{b1}\aput{:U}{\tt javac}
+ \ncline{b1}{b0}\aput{:D}{\tt gcj}\bput{:D}{JITs}
+\endpsmatrix
+\end{document}
--- /dev/null
+\documentclass{article}
+\input tmp.inputs
+\pagestyle{empty}
+\usepackage{amssymb,amsbsy}
+\begin{document}
+\newlength{\MyLength}
+\settowidth{\MyLength}{xmachine codex}
+\newcommand{\MyBox}[1]{\makebox[\MyLength]{#1}}
+\psmatrix[colsep=2,rowsep=0,nrot=:U]
+ & \\[0pt]
+ & \\[0pt]
+ [name=s0]\MyBox{unsafe source} & [name=s1]\MyBox{safe source} \\[0pt]
+ & \\[0pt]
+ & \\[0pt]
+ & \\[0pt]
+ & \\[0pt]
+ & \\[0pt]
+ [name=b0]\MyBox{machine code} & [name=b1]\MyBox{safe bytecode} \\[0pt]
+ & \\[0pt]
+ \psset{nodesep=5pt,arrows=->}
+ \ncline{s0}{s1}\aput{:U}{source-to}\bput{:U}{source}
+ \ncline{s1}{b1}\aput{:U}{\tt javac}
+\endpsmatrix
+\end{document}
--- /dev/null
+\documentclass{article}
+\input tmp.inputs
+\pagestyle{empty}
+\usepackage{amssymb,amsbsy}
+\begin{document}
+\newlength{\MyLength}
+\settowidth{\MyLength}{xmachine codex}
+\newcommand{\MyBox}[1]{\makebox[\MyLength]{#1}}
+\psmatrix[colsep=2,rowsep=0,nrot=:U]
+ & \\[0pt]
+ [name=s0]\MyBox{unsafe source} & [name=s1]\MyBox{safe source} \\[0pt]
+ & \\[0pt]
+ & \\[0pt]
+ & \\[0pt]
+ & \\[0pt]
+ & \\[0pt]
+ [name=b0]\MyBox{machine code} & [name=b1]\MyBox{safe bytecode} \\[0pt]
+ & \\[0pt]
+ \psset{nodesep=5pt,arrows=->}
+ \ncline{s0}{b1}\bput{:U}{source-to-binary}
+\endpsmatrix
+\end{document}
--- /dev/null
+\documentclass{article}
+\input tmp.inputs
+\pagestyle{empty}
+\usepackage{amssymb,amsbsy}
+\begin{document}
+\newlength{\MyLength}
+\settowidth{\MyLength}{xmachine codex}
+\newcommand{\MyBox}[1]{\makebox[\MyLength]{#1}}
+\psmatrix[colsep=2,rowsep=0,nrot=:U]
+ & \\[0pt]
+ & \\[0pt]
+ [name=s0]\MyBox{unsafe source} & [name=s1]\MyBox{safe source} \\[0pt]
+ & \\[0pt]
+ & \\[0pt]
+ & \\[0pt]
+ & \\[0pt]
+ & \\[0pt]
+ [name=b0]\MyBox{machine code} & [name=b1]\MyBox{safe bytecode} \\[0pt]
+ \psset{nodesep=5pt,arrows=->}
+ \ncline{s0}{b0}\bput{:U}{\tt gcc}
+ \ncline{s1}{b1}\aput{:U}{\tt javac}
+ \ncline{b0}{s1}\naput{\tt NestedVM}
+\endpsmatrix
+\end{document}
--- /dev/null
+\documentclass{article}
+\input tmp.inputs
+\pagestyle{empty}
+\usepackage{amssymb,amsbsy}
+\begin{document}
+\newlength{\MyLength}
+\settowidth{\MyLength}{xmachine codex}
+\newcommand{\MyBox}[1]{\makebox[\MyLength]{#1}}
+\psmatrix[colsep=2,rowsep=0,nrot=:U]
+ & \\[0pt]
+ [name=s0]\MyBox{unsafe source} & [name=s1]\MyBox{safe source} \\[0pt]
+ & \\[0pt]
+ & \\[0pt]
+ & \\[0pt]
+ & \\[0pt]
+ & \\[0pt]
+ [name=b0]\MyBox{machine code} & [name=b1]\MyBox{safe bytecode} \\[0pt]
+ & \\[0pt]
+ \psset{nodesep=5pt,arrows=->}
+ \ncline{s0}{b0}\bput{:U}{\tt gcc}
+ \ncline{b0}{b1}\naput{\tt NestedVM}
+\endpsmatrix
+\end{document}
--- /dev/null
+\relax
+\bibstyle{amsplain}
+\citation{KR}
+\citation{soustroup}
+\citation{java}
+\citation{csharp}
+\citation{jni}
+\citation{cni}
+\citation{j2me}
+\citation{msil}
+\citation{parrot}
+\citation{python}
+\@writefile{toc}{\contentsline {section}{\numberline {1}Introduction}{1}}
+\@writefile{toc}{\contentsline {section}{\numberline {2}Approaches to Translation}{1}}
+\citation{jazillian}
+\citation{mohca}
+\citation{c2j}
+\citation{c2jpp}
+\citation{capp}
+\citation{ephedra}
+\citation{egcsjvm}
+\citation{gcc}
+\@writefile{toc}{\contentsline {section}{\numberline {3}Existing Work}{2}}
+\@writefile{toc}{\contentsline {subsection}{\numberline {3.1}Source-to-Source Translation}{2}}
+\@writefile{toc}{\contentsline {subsubsection}{\numberline {3.1.1}Incomplete Translation}{2}}
+\@writefile{toc}{\contentsline {subsubsection}{\numberline {3.1.2}Partial Domain Translation}{2}}
+\@writefile{toc}{\contentsline {subsection}{\numberline {3.2}Source-to-Binary Translation}{2}}
+\@writefile{toc}{\contentsline {section}{\numberline {4}NestedVM}{3}}
+\@writefile{toc}{\contentsline {subsection}{\numberline {4.1}Why MIPS?}{3}}
+\@writefile{toc}{\contentsline {subsection}{\numberline {4.2}Binary-to-Source}{3}}
+\citation{jikes}
+\@writefile{lof}{\contentsline {figure}{\numberline {1}{\ignorespaces Trampoline transformation necessitated by Java's 64kb method size limit}}{4}}
+\newlabel{code1}{{1}{4}}
+\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.2.1}Optimizations}{4}}
+\citation{hotspot}
+\@writefile{toc}{\contentsline {subsection}{\numberline {4.3}Binary-to-Binary}{6}}
+\@writefile{toc}{\contentsline {subsubsection}{\numberline {4.3.1}Compiler Flags}{7}}
+\@writefile{toc}{\contentsline {section}{\numberline {5}The NestedVM Runtime}{7}}
+\@writefile{toc}{\contentsline {subsection}{\numberline {5.1}The Runtime Class}{7}}
+\citation{msil}
+\bibdata{nestedvm}
+\bibcite{j2me}{1}
+\bibcite{msil}{2}
+\bibcite{parrot}{3}
+\bibcite{python}{4}
+\bibcite{jazillian}{5}
+\bibcite{c2j}{6}
+\bibcite{gcc}{7}
+\bibcite{jikes}{8}
+\bibcite{csharp}{9}
+\bibcite{cni}{10}
+\bibcite{hotspot}{11}
+\bibcite{capp}{12}
+\bibcite{java}{13}
+\bibcite{KR}{14}
+\bibcite{jni}{15}
+\bibcite{mohca}{16}
+\bibcite{ephedra}{17}
+\bibcite{c2jpp}{18}
+\bibcite{soustroup}{19}
+\bibcite{egcsjvm}{20}
+\@writefile{toc}{\contentsline {section}{\numberline {6}Future Directions}{8}}
+\@writefile{toc}{\contentsline {section}{\numberline {7}Conclusion}{8}}
+\@writefile{toc}{\contentsline {section}{\numberline {8}Appendix: Testing Methodology}{8}}
--- /dev/null
+\providecommand{\bysame}{\leavevmode\hbox to3em{\hrulefill}\thinspace}
+\providecommand{\MR}{\relax\ifhmode\unskip\space\fi MR }
+% \MRhref is called by the amsart/book/proc definition of \MR.
+\providecommand{\MRhref}[2]{%
+ \href{http://www.ams.org/mathscinet-getitem?mr=#1}{#2}
+}
+\providecommand{\href}[2]{#2}
+\begin{thebibliography}{10}
+
+\bibitem{j2me}
+http://java.sun.com/j2me/docs/index.html.
+
+\bibitem{msil}
+http://research.microsoft.com/~emeijer/Papers/CLR.pdf.
+
+\bibitem{parrot}
+http://www.parrotcode.org.
+
+\bibitem{python}
+http://www.python.org.
+
+\bibitem{jazillian}
+http://www.jazillian.com/.
+
+\bibitem{c2j}
+http://www.soften.ktu.lt/~stonis/c2java/.
+
+\bibitem{gcc}
+http://gcc.gnu.org/.
+
+\bibitem{jikes}
+http://www-124.ibm.com/developerworks/oss/jikes/.
+
+\bibitem{csharp}
+\emph{The c\# programming language},
+ http://download.microsoft.com/download/0/a/c/0acb3585-3f3f-4169-ad61-efc9f01%
+76788/CSharp.zip.
+
+\bibitem{cni}
+\emph{The cygnus native interface for c++/java integration},
+ http://gcc.gnu.org/java/papers/cni/t1.html.
+
+\bibitem{hotspot}
+\emph{The java hotspot performance engine architecture}, 1999,
+ http://java.sun.com/products/hotspot/whitepaper.html.
+
+\bibitem{capp}
+Frank Buddrus and Jorg Schodel, \emph{Cappuccino -- a c++ to java translator},
+ Proceedings of the 1998 ACM symposium on Applied Computing (1998).
+
+\bibitem{java}
+James Gosling et~al., \emph{The {Java} language specification}, GOTOP
+ Information Inc., 5F, No.7, Lane 50, Sec.3 Nan Kang Road Taipei, Taiwan; Unit
+ 1905, Metro Plaza Tower 2, No. 223 Hing Fong Road, Kwai Chung, N.T., Hong
+ Kong, 1996, citeseer.ist.psu.edu/gosling96java.html.
+
+\bibitem{KR}
+B.~W. Kernighan and D.~M. Ritchie, \emph{The c programming language}, (1979).
+
+\bibitem{jni}
+Sheng Liang, \emph{The javatm native interface: Programmer's guide and
+ specification}, (1999).
+
+\bibitem{mohca}
+Scott Malabarba, Premkumar~T. Devanbu, and Aaron Stearns, \emph{Mohca-java: A
+ tool for c++ to java conversion support}, International Conference on
+ Software Engineering, 1999, citeseer.ist.psu.edu/malabarba99mohcajava.html,
+ pp.~650--653.
+
+\bibitem{ephedra}
+J.~Martin, \emph{Ephedra: A c to java migration environment}, (2002),
+ http://www.rigi.csc.uvic.ca/?jmartin/Ephedra.
+
+\bibitem{c2jpp}
+Novosoft, (September 2001), C2J ?C to Java translator.
+
+\bibitem{soustroup}
+B.~Stroustrup., \emph{The c++ programming language}, (1997).
+
+\bibitem{egcsjvm}
+T.~Waddington, \emph{Java backend for gcc}, (November 2000),
+ http://archive.csee.uq.edu.au/?csmweb/uqbt.html\#gccjvm.
+
+\end{thebibliography}
--- /dev/null
+This is BibTeX, Version 0.99c (Web2C 7.4.5)
+The top-level auxiliary file: nestedvm.ivme04.aux
+The style file: amsplain.bst
+Database file #1: nestedvm.bib
+Warning--I'm ignoring c2jpp's extra "note" field
+--line 73 of file nestedvm.bib
+Warning--to sort, need author or key in csharp
+Warning--to sort, need author or key in cni
+Warning--to sort, need author or key in j2me
+Warning--to sort, need author or key in msil
+Warning--to sort, need author or key in parrot
+Warning--to sort, need author or key in python
+Warning--to sort, need author or key in jazillian
+Warning--to sort, need author or key in c2j
+Warning--to sort, need author or key in gcc
+Warning--to sort, need author or key in jikes
+Warning--to sort, need author or key in hotspot
+Warning--missing pages in capp
+Warning--missing journal name in KR
+Warning--missing pages in KR
+Warning--missing journal name in jni
+Warning--missing pages in jni
+Warning--missing journal name in ephedra
+Warning--missing pages in ephedra
+Warning--missing title in c2jpp
+Warning--missing journal name in c2jpp
+Warning--missing pages in c2jpp
+Warning--missing journal name in soustroup
+Warning--missing pages in soustroup
+Warning--missing journal name in egcsjvm
+Warning--missing pages in egcsjvm
+You've used 20 entries,
+ 2213 wiz_defined-function locations,
+ 574 strings with 5810 characters,
+and the built_in function-call counts, 4059 in all, are:
+= -- 309
+> -- 103
+< -- 0
++ -- 55
+- -- 28
+* -- 254
+:= -- 559
+add.period$ -- 20
+call.type$ -- 20
+change.case$ -- 64
+chr.to.int$ -- 0
+cite$ -- 45
+duplicate$ -- 223
+empty$ -- 482
+format.name$ -- 28
+if$ -- 901
+int.to.chr$ -- 0
+int.to.str$ -- 20
+missing$ -- 30
+newline$ -- 70
+num.names$ -- 18
+pop$ -- 214
+preamble$ -- 1
+purify$ -- 53
+quote$ -- 0
+skip$ -- 110
+stack$ -- 0
+substring$ -- 135
+swap$ -- 33
+text.length$ -- 0
+text.prefix$ -- 0
+top$ -- 0
+type$ -- 78
+warning$ -- 25
+while$ -- 20
+width$ -- 22
+write$ -- 139
+(There were 26 warnings)
--- /dev/null
+This is pdfTeX, Version 3.14159-1.10b (Web2C 7.4.5) (format=pdflatex 2004.2.3) 20 MAR 2004 07:30
+**nestedvm.ivme04.tex
+(./nestedvm.ivme04.tex{/usr/local/share/texmf-local/pdftex/config/pdftex.cfg}
+LaTeX2e <2001/06/01>
+Babel <v3.7h> and hyphenation patterns for american, french, german, ngerman, n
+ohyphenation, loaded.
+(./acmconf.cls
+Document Class: acmconf 1994/11/27 Alternative LaTeX document class
+Bugs to berson@cs.pitt.edu
+(/usr/local/share/texmf-local/tex/latex/base/article.cls
+Document Class: article 2001/04/21 v1.4e Standard LaTeX document class
+(/usr/local/share/texmf-local/tex/latex/base/size10.clo
+File: size10.clo 2001/04/21 v1.4e Standard LaTeX file (size option)
+)
+\c@part=\count79
+\c@section=\count80
+\c@subsection=\count81
+\c@subsubsection=\count82
+\c@paragraph=\count83
+\c@subparagraph=\count84
+\c@figure=\count85
+\c@table=\count86
+\abovecaptionskip=\skip41
+\belowcaptionskip=\skip42
+\bibindent=\dimen102
+)
+\@acmtitlebox=\box26
+)
+(/usr/local/share/texmf-local/tex/latex/graphics/graphicx.sty
+Package: graphicx 1999/02/16 v1.0f Enhanced LaTeX Graphics (DPC,SPQR)
+
+(/usr/local/share/texmf-local/tex/latex/graphics/keyval.sty
+Package: keyval 1999/03/16 v1.13 key=value parser (DPC)
+\KV@toks@=\toks14
+)
+(/usr/local/share/texmf-local/tex/latex/graphics/graphics.sty
+Package: graphics 2001/07/07 v1.0n Standard LaTeX Graphics (DPC,SPQR)
+
+(/usr/local/share/texmf-local/tex/latex/graphics/trig.sty
+Package: trig 1999/03/16 v1.09 sin cos tan (DPC)
+)
+(/usr/local/share/texmf-local/tex/latex/config/graphics.cfg
+File: graphics.cfg 2001/08/31 v1.1 graphics configuration of teTeX/TeXLive
+)
+Package graphics Info: Driver file: pdftex.def on input line 80.
+
+(/usr/local/share/texmf-local/tex/latex/graphics/pdftex.def
+File: pdftex.def 2002/06/19 v0.03k graphics/color for pdftex
+\Gread@gobject=\count87
+))
+\Gin@req@height=\dimen103
+\Gin@req@width=\dimen104
+)
+(/usr/local/share/texmf-local/tex/latex/tools/multicol.sty
+Package: multicol 2000/07/10 v1.5z multicolumn formatting (FMi)
+\c@tracingmulticols=\count88
+\mult@box=\box27
+\multicol@leftmargin=\dimen105
+\c@unbalance=\count89
+\c@collectmore=\count90
+\doublecol@number=\count91
+\multicoltolerance=\count92
+\multicolpretolerance=\count93
+\full@width=\dimen106
+\page@free=\dimen107
+\premulticols=\dimen108
+\postmulticols=\dimen109
+\multicolsep=\skip43
+\multicolbaselineskip=\skip44
+\partial@page=\box28
+\last@line=\box29
+\mult@rightbox=\box30
+\mult@grightbox=\box31
+\mult@gfirstbox=\box32
+\mult@firstbox=\box33
+\@tempa=\box34
+\@tempa=\box35
+\@tempa=\box36
+\@tempa=\box37
+\@tempa=\box38
+\@tempa=\box39
+\@tempa=\box40
+\@tempa=\box41
+\@tempa=\box42
+\@tempa=\box43
+\@tempa=\box44
+\@tempa=\box45
+\@tempa=\box46
+\@tempa=\box47
+\@tempa=\box48
+\@tempa=\box49
+\@tempa=\box50
+\c@columnbadness=\count94
+\c@finalcolumnbadness=\count95
+\last@try=\dimen110
+\multicolovershoot=\dimen111
+\multicolundershoot=\dimen112
+\mult@nat@firstbox=\box51
+\colbreak@box=\box52
+)
+(/usr/local/share/texmf-local/tex/latex/amsfonts/amssymb.sty
+Package: amssymb 2002/01/22 v2.2d
+
+(/usr/local/share/texmf-local/tex/latex/amsfonts/amsfonts.sty
+Package: amsfonts 2001/10/25 v2.2f
+\@emptytoks=\toks15
+\symAMSa=\mathgroup4
+\symAMSb=\mathgroup5
+LaTeX Font Info: Overwriting math alphabet `\mathfrak' in version `bold'
+(Font) U/euf/m/n --> U/euf/b/n on input line 132.
+))
+(/usr/local/share/texmf-local/tex/latex/amsmath/amsmath.sty
+Package: amsmath 2000/07/18 v2.13 AMS math features
+\@mathmargin=\skip45
+
+For additional information on amsmath, use the `?' option.
+(/usr/local/share/texmf-local/tex/latex/amsmath/amstext.sty
+Package: amstext 2000/06/29 v2.01
+
+(/usr/local/share/texmf-local/tex/latex/amsmath/amsgen.sty
+File: amsgen.sty 1999/11/30 v2.0
+\@emptytoks=\toks16
+\ex@=\dimen113
+))
+(/usr/local/share/texmf-local/tex/latex/amsmath/amsbsy.sty
+Package: amsbsy 1999/11/29 v1.2d
+\pmbraise@=\dimen114
+)
+(/usr/local/share/texmf-local/tex/latex/amsmath/amsopn.sty
+Package: amsopn 1999/12/14 v2.01 operator names
+)
+\inf@bad=\count96
+LaTeX Info: Redefining \frac on input line 211.
+\uproot@=\count97
+\leftroot@=\count98
+LaTeX Info: Redefining \overline on input line 307.
+\classnum@=\count99
+\DOTSCASE@=\count100
+LaTeX Info: Redefining \ldots on input line 379.
+LaTeX Info: Redefining \dots on input line 382.
+LaTeX Info: Redefining \cdots on input line 467.
+\Mathstrutbox@=\box53
+\strutbox@=\box54
+\big@size=\dimen115
+LaTeX Font Info: Redeclaring font encoding OML on input line 567.
+LaTeX Font Info: Redeclaring font encoding OMS on input line 568.
+\macc@depth=\count101
+\c@MaxMatrixCols=\count102
+\dotsspace@=\muskip10
+\c@parentequation=\count103
+\dspbrk@lvl=\count104
+\tag@help=\toks17
+\row@=\count105
+\column@=\count106
+\maxfields@=\count107
+\andhelp@=\toks18
+\eqnshift@=\dimen116
+\alignsep@=\dimen117
+\tagshift@=\dimen118
+\tagwidth@=\dimen119
+\totwidth@=\dimen120
+\lineht@=\dimen121
+\@envbody=\toks19
+\multlinegap=\skip46
+\multlinetaggap=\skip47
+\mathdisplay@stack=\toks20
+LaTeX Info: Redefining \[ on input line 2666.
+LaTeX Info: Redefining \] on input line 2667.
+)
+(/usr/local/share/texmf-local/tex/latex/graphics/epsfig.sty
+Package: epsfig 1999/02/16 v1.7a (e)psfig emulation (SPQR)
+\epsfxsize=\dimen122
+\epsfysize=\dimen123
+)
+(/usr/local/share/texmf-local/tex/latex/base/alltt.sty
+Package: alltt 1997/06/16 v2.0g defines alltt environment
+)
+(/usr/local/share/texmf-local/tex/latex/psnfss/palatino.sty
+Package: palatino 2002/09/08 PSNFSS-v9.0a (SPQR)
+) (./pdftricks.sty
+Package: pdftricks 2001/09/30 1.15 psTricks support in PDF (CVRACL)
+
+
+Package pdftricks Warning: ****************************************
+(pdftricks) Package pdftricks v,1.15 loaded
+(pdftricks) [psTricks support in PDF (CVR, ACL)]
+(pdftricks) ****************************************.
+
+(/usr/local/share/texmf-local/tex/latex/graphics/color.sty
+Package: color 1999/02/16 v1.0i Standard LaTeX Color (DPC)
+
+(/usr/local/share/texmf-local/tex/latex/config/color.cfg
+File: color.cfg 2001/08/31 v1.1 color configuration of teTeX/TeXLive
+)
+Package color Info: Driver file: pdftex.def on input line 125.
+)
+touch /tmp/w18-test-2004320450
+system()...disabled.
+
+
+Package pdftricks Warning: ****************************************
+(pdftricks) No \write 18 capability.
+(pdftricks) You'll have to run a script by yourself!
+(pdftricks) ****************************************.
+
+\PDFStream=\write3
+Special stream 'pdfpic'
+\c@psfig=\count108
+\c@arraylength=\count109
+\c@ArrayIndex=\count110
+\c@zeroCtr=\count111
+\c@recordCtr=\count112
+\c@Ctr=\count113
+\c@f@irstCtr=\count114
+\c@s@econdCtr=\count115
+)
+\CVinputs=\write4
+\openout4 = `tmp.inputs'.
+
+
+(/usr/local/share/texmf-local/tex/latex/misc/parskip.sty
+Package: parskip 2001/04/09 non-zero parskip adjustments
+)
+(/usr/local/share/texmf-local/tex/latex/tools/tabularx.sty
+Package: tabularx 1999/01/07 v2.07 `tabularx' package (DPC)
+
+(/usr/local/share/texmf-local/tex/latex/tools/array.sty
+Package: array 1998/05/13 v2.3m Tabular extension package (FMi)
+\col@sep=\dimen124
+\extrarowheight=\dimen125
+\NC@list=\toks21
+\extratabsurround=\skip48
+\backup@length=\skip49
+)
+\TX@col@width=\dimen126
+\TX@old@table=\dimen127
+\TX@old@col=\dimen128
+\TX@target=\dimen129
+\TX@delta=\dimen130
+\TX@cols=\count116
+\TX@ftn=\toks22
+)
+(./nestedvm.ivme04.aux)
+\openout1 = `nestedvm.ivme04.aux'.
+
+LaTeX Font Info: Checking defaults for OML/cmm/m/it on input line 30.
+LaTeX Font Info: ... okay on input line 30.
+LaTeX Font Info: Checking defaults for T1/cmr/m/n on input line 30.
+LaTeX Font Info: ... okay on input line 30.
+LaTeX Font Info: Checking defaults for OT1/cmr/m/n on input line 30.
+LaTeX Font Info: ... okay on input line 30.
+LaTeX Font Info: Checking defaults for OMS/cmsy/m/n on input line 30.
+LaTeX Font Info: ... okay on input line 30.
+LaTeX Font Info: Checking defaults for OMX/cmex/m/n on input line 30.
+LaTeX Font Info: ... okay on input line 30.
+LaTeX Font Info: Checking defaults for U/cmr/m/n on input line 30.
+LaTeX Font Info: ... okay on input line 30.
+LaTeX Font Info: Try loading font information for OT1+ppl on input line 30.
+
+(/usr/local/share/texmf-local/tex/latex/psnfss/ot1ppl.fd
+File: ot1ppl.fd 2001/06/04 font definitions for OT1/ppl.
+)
+(/usr/local/share/texmf-local/tex/context/base/supp-pdf.tex
+(/usr/local/share/texmf-local/tex/context/base/supp-mis.tex
+loading : Context Support Macros / Missing
+\protectiondepth=\count117
+\scratchcounter=\count118
+\scratchtoks=\toks23
+\scratchdimen=\dimen131
+\scratchskip=\skip50
+\scratchmuskip=\muskip11
+\scratchbox=\box55
+\scratchread=\read1
+\scratchwrite=\write5
+\zeropoint=\dimen132
+\minusone=\count119
+\thousandpoint=\dimen133
+\emptytoks=\toks24
+\nextbox=\box56
+\nextdepth=\dimen134
+\everyline=\toks25
+\!!counta=\count120
+\!!countb=\count121
+\recursecounter=\count122
+)
+loading : Context Support Macros / PDF
+\nofMPsegments=\count123
+\nofMParguments=\count124
+\everyMPtoPDFconversion=\toks26
+)
+LaTeX Font Info: Font shape `OT1/ppl/bx/n' in size <14.4> not available
+(Font) Font shape `OT1/ppl/b/n' tried instead on input line 32.
+LaTeX Font Info: Try loading font information for OT1+phv on input line 32.
+ (/usr/local/share/texmf-local/tex/latex/psnfss/ot1phv.fd
+File: ot1phv.fd 2001/06/04 scalable font definitions for OT1/phv.
+)
+LaTeX Font Info: Font shape `OT1/phv/bx/n' in size <14.4> not available
+(Font) Font shape `OT1/phv/b/n' tried instead on input line 32.
+LaTeX Font Info: Try loading font information for U+msa on input line 32.
+
+(/usr/local/share/texmf-local/tex/latex/amsfonts/umsa.fd
+File: umsa.fd 2002/01/19 v2.2g AMS font definitions
+)
+LaTeX Font Info: Try loading font information for U+msb on input line 32.
+
+(/usr/local/share/texmf-local/tex/latex/amsfonts/umsb.fd
+File: umsb.fd 2002/01/19 v2.2g AMS font definitions
+)
+LaTeX Font Info: Try loading font information for OT1+pcr on input line 32.
+
+(/usr/local/share/texmf-local/tex/latex/psnfss/ot1pcr.fd
+File: ot1pcr.fd 2001/06/04 font definitions for OT1/pcr.
+)
+LaTeX Font Info: Font shape `OT1/phv/bx/n' in size <9> not available
+(Font) Font shape `OT1/phv/b/n' tried instead on input line 34.
+LaTeX Font Info: Try loading font information for OMS+ppl on input line 46.
+
+(/usr/local/share/texmf-local/tex/latex/psnfss/omsppl.fd
+File: omsppl.fd
+)
+LaTeX Font Info: Font shape `OMS/ppl/m/n' in size <9> not available
+(Font) Font shape `OMS/cmsy/m/n' tried instead on input line 46.
+
+Underfull \hbox (badness 3386) in paragraph at lines 52--59
+/pplr7t@9.0pt/a binary-to-source and binary-to-binary trans-la-tor
+ []
+
+
+Underfull \hbox (badness 2600) in paragraph at lines 52--59
+/pplr7t@9.0pt/tar-get-ing the Java Vir-tual Ma-chine. NestedVM-
+ []
+
+
+Underfull \hbox (badness 4229) in paragraph at lines 79--85
+/pplr7t@9.0pt/hib-ited in a num-ber of con-texts, in-clud-ing ap-
+ []
+
+
+Underfull \hbox (badness 2165) in paragraph at lines 79--85
+/pplr7t@9.0pt/plets en-vi-ron-ments and servlet con-tain-ers with a
+ []
+
+Opening PDFStream=nestedvm.ivme04-fig1.tex
+\openout3 = `nestedvm.ivme04-fig1.tex'.
+
+
+<nestedvm.ivme04-fig1.pdf, id=1, 175.65625pt x 81.30376pt>
+File: nestedvm.ivme04-fig1.pdf Graphic file (type pdf)
+
+<use nestedvm.ivme04-fig1.pdf> Opening PDFStream=nestedvm.ivme04-fig2.tex
+\openout3 = `nestedvm.ivme04-fig2.tex'.
+
+
+<nestedvm.ivme04-fig2.pdf, id=2, 186.6975pt x 109.40875pt>
+File: nestedvm.ivme04-fig2.pdf Graphic file (type pdf)
+
+<use nestedvm.ivme04-fig2.pdf> [1{/usr/local/share/texmf-local/dvips/config/pdf
+tex.map}
+
+
+ <./nestedvm.ivme04-fig1.pdf>]
+Underfull \hbox (badness 1783) in paragraph at lines 164--166
+/pplr7t@9.0pt/The most com-mon tech-nique em-ployed is par-tial
+ []
+
+Opening PDFStream=nestedvm.ivme04-fig3.tex
+\openout3 = `nestedvm.ivme04-fig3.tex'.
+
+
+<nestedvm.ivme04-fig3.pdf, id=37, 186.6975pt x 109.40875pt>
+File: nestedvm.ivme04-fig3.pdf Graphic file (type pdf)
+
+<use nestedvm.ivme04-fig3.pdf>
+Underfull \hbox (badness 1005) in paragraph at lines 204--209
+[]/pplr7t@9.0pt/Unfortunately such deep anal-y-sis is in-tractible for
+ []
+
+
+Underfull \hbox (badness 1014) in paragraph at lines 210--217
+/pplr7t@9.0pt/specific trans-la-tors rather than a sin-gle trans-la-tion
+ []
+
+Opening PDFStream=nestedvm.ivme04-fig4.tex
+\openout3 = `nestedvm.ivme04-fig4.tex'.
+
+
+<nestedvm.ivme04-fig4.pdf, id=38, 192.72pt x 109.40875pt>
+File: nestedvm.ivme04-fig4.pdf Graphic file (type pdf)
+
+<use nestedvm.ivme04-fig4.pdf> [2 <./nestedvm.ivme04-fig2.pdf> <./nestedvm.ivme
+04-fig3.pdf> <./nestedvm.ivme04-fig4.pdf>]
+LaTeX Font Info: Font shape `OT1/ppl/bx/n' in size <9> not available
+(Font) Font shape `OT1/ppl/b/n' tried instead on input line 287.
+
+Underfull \hbox (badness 4013) in paragraph at lines 317--325
+[]/pplr7t@9.0pt/NestedVM of-fers to-tal sup-port for all non-
+ []
+
+
+Underfull \hbox (badness 1097) in paragraph at lines 317--325
+/pplr7t@9.0pt/found on a MIPS /pcrr7t@9.0pt/R2000 /pplr7t@9.0pt/CPU, in-clud-in
+g the
+ []
+
+
+Underfull \hbox (badness 2772) in paragraph at lines 392--396
+/pplr7t@9.0pt/The sim-plest op-er-a-tional mode for Nest-edVM is
+ []
+
+Opening PDFStream=nestedvm.ivme04-fig5.tex
+\openout3 = `nestedvm.ivme04-fig5.tex'.
+
+
+<nestedvm.ivme04-fig5.pdf, id=72, 186.6975pt x 97.36375pt>
+File: nestedvm.ivme04-fig5.pdf Graphic file (type pdf)
+
+<use nestedvm.ivme04-fig5.pdf>
+Overfull \hbox (37.89pt too wide) in paragraph at lines 419--503
+[]$[]$
+ []
+
+[3 <./nestedvm.ivme04-fig5.pdf>] <chart1.pdf, id=90, 794.97pt x 614.295pt>
+File: chart1.pdf Graphic file (type pdf)
+
+<use chart1.pdf>
+Overfull \hbox (0.81pt too wide) in paragraph at lines 538--539
+[][]
+ []
+
+[4 <./chart1.pdf>]
+Underfull \hbox (badness 1092) in paragraph at lines 574--577
+[]/pplr7t@9.0pt/This prob-lem was sur-mounted by switch-ing on a
+ []
+
+<chart5.pdf, id=109, 794.97pt x 614.295pt>
+File: chart5.pdf Graphic file (type pdf)
+ <use chart5.pdf>
+Overfull \hbox (0.81pt too wide) in paragraph at lines 583--584
+[][]
+ []
+
+<chart6.pdf, id=110, 794.97pt x 614.295pt>
+File: chart6.pdf Graphic file (type pdf)
+ <use chart6.pdf>
+Overfull \hbox (0.81pt too wide) in paragraph at lines 585--586
+[][]
+ []
+
+
+Underfull \hbox (badness 1990) in paragraph at lines 591--594
+/pplr7t@9.0pt/ment can be coded as a /pcrr7t@9.0pt/TABLESWITCH/pplr7t@9.0pt/, t
+he
+ []
+
+
+Underfull \hbox (badness 10000) in paragraph at lines 595--599
+[]/pplr7t@9.0pt/Hybrid Interpretive-JIT com-pil-ers such as
+ []
+
+
+Underfull \hbox (badness 2277) in paragraph at lines 614--623
+/pplr7t@9.0pt/and ev-ery branch in-struc-tion's des-ti-na-tion is
+ []
+
+
+Underfull \hbox (badness 10000) in paragraph at lines 652--661
+[]/pplr7t@9.0pt/One sub-op-ti-mal so-lu-tion was to ex-press con-
+ []
+
+
+Underfull \hbox (badness 2990) in paragraph at lines 652--661
+/pplr7t@9.0pt/stants as off-sets from a few cen-tral val-ues; for
+ []
+
+
+Underfull \hbox (badness 10000) in paragraph at lines 652--661
+/pplr7t@9.0pt/ex-am-ple ``/pcrr7t@9.0pt/pc = N[]0x00010000 + 0x10/pplr7t@9.0pt/
+'' (where
+ []
+
+
+Underfull \hbox (badness 1067) in paragraph at lines 652--661
+/pplr7t@9.0pt/di-rectly to /pcrr7t@9.0pt/.class /pplr7t@9.0pt/files (with-out t
+he in-ter-me-di-ate
+ []
+
+Opening PDFStream=nestedvm.ivme04-fig6.tex
+\openout3 = `nestedvm.ivme04-fig6.tex'.
+
+ [5 <./chart5.pdf> <./chart6.pdf>]
+<nestedvm.ivme04-fig6.pdf, id=149, 186.6975pt x 108.405pt>
+File: nestedvm.ivme04-fig6.pdf Graphic file (type pdf)
+
+<use nestedvm.ivme04-fig6.pdf>
+Underfull \hbox (badness 1418) in paragraph at lines 698--703
+[]/pplr7t@9.0pt/Direct com-pi-la-tion to /pcrr7t@9.0pt/.class /pplr7t@9.0pt/fil
+es opens up
+ []
+
+
+Underfull \hbox (badness 4120) in paragraph at lines 698--703
+/pplr7t@9.0pt/lat-ing MIPS bi-na-ries and load-ing them via
+ []
+
+
+Underfull \hbox (badness 10000) in paragraph at lines 698--703
+/pcrr7t@9.0pt/ClassLoader.fromBytes() /pplri7t@9.0pt/at de-ploy-ment
+ []
+
+<chart7.pdf, id=150, 794.97pt x 614.295pt>
+File: chart7.pdf Graphic file (type pdf)
+ <use chart7.pdf>
+Overfull \hbox (0.81pt too wide) in paragraph at lines 710--711
+[][]
+ []
+
+[6 <./nestedvm.ivme04-fig6.pdf> <./chart7.pdf>]
+Underfull \hbox (badness 1052) in paragraph at lines 822--829
+/pcrr7t@9.0pt/-fno-schedule-insns /pplr7t@9.0pt/in-struc-tion, /pcrr7t@9.0pt/gc
+c /pplr7t@9.0pt/will
+ []
+
+<chart4.pdf, id=185, 794.97pt x 614.295pt>
+File: chart4.pdf Graphic file (type pdf)
+ <use chart4.pdf>
+Overfull \hbox (0.81pt too wide) in paragraph at lines 849--850
+[][]
+ []
+
+<chart3.pdf, id=186, 794.97pt x 614.295pt>
+File: chart3.pdf Graphic file (type pdf)
+ <use chart3.pdf>
+Overfull \hbox (0.81pt too wide) in paragraph at lines 851--852
+[][]
+ []
+
+
+Underfull \hbox (badness 1661) in paragraph at lines 880--887
+[]/pplr7t@9.0pt/The run-time pro-vides ac-cess to the host file
+ []
+
+
+Underfull \hbox (badness 4378) in paragraph at lines 880--887
+/pplr7t@9.0pt/stan-dard UNIX syscalls (/pcrr7t@9.0pt/read()/pplr7t@9.0pt/, /pcr
+r7t@9.0pt/write()/pplr7t@9.0pt/,
+ []
+
+[7 <./chart4.pdf> <./chart3.pdf>]
+Underfull \hbox (badness 7869) in paragraph at lines 888--891
+[]/pplr7t@9.0pt/It pro-vides gen-eral OS ser-vices, in-clud-ing
+ []
+
+
+Underfull \hbox (badness 2245) in paragraph at lines 932--938
+/pplr7t@9.0pt/jpeg and writ-ing a tga. The /pcrr7t@9.0pt/mspack /pplr7t@9.0pt/t
+est con-
+ []
+
+(./nestedvm.ivme04.bbl
+Underfull \hbox (badness 10000) in paragraph at lines 14--15
+[]/pplr7t@9.0pt/http://research.microsoft.com/ emei-
+ []
+
+
+Overfull \hbox (28.85645pt too wide) in paragraph at lines 32--33
+[]/pplr7t@9.0pt/http://www-124.ibm.com/developerworks/oss/jikes/.
+ []
+
+
+Underfull \hbox (badness 10000) in paragraph at lines 35--38
+[]/pplri7t@9.0pt/The c# pro-gram-ming lan-guage/pplr7t@9.0pt/,
+ []
+
+
+Overfull \hbox (53.16565pt too wide) in paragraph at lines 35--38
+/pplr7t@9.0pt/http://download.microsoft.com/download/0/a/c/0acb3585-
+ []
+
+
+Underfull \hbox (badness 10000) in paragraph at lines 44--46
+[]/pplri7t@9.0pt/The java hotspot per-for-mance
+ []
+
+
+Underfull \hbox (badness 10000) in paragraph at lines 44--46
+/pplri7t@9.0pt/en-gine ar-chi-tec-ture/pplr7t@9.0pt/, 1999,
+ []
+
+
+Overfull \hbox (35.9659pt too wide) in paragraph at lines 44--46
+/pplr7t@9.0pt/http://java.sun.com/products/hotspot/whitepaper.html.
+ []
+
+
+Underfull \hbox (badness 10000) in paragraph at lines 65--69
+[]/pplr7t@9.0pt/Scott Mal-abarba, Premku-mar T. De-vanbu,
+ []
+
+
+Underfull \hbox (badness 4752) in paragraph at lines 65--69
+/pplr7t@9.0pt/and Aaron Stearns, /pplri7t@9.0pt/Mohca-java: A tool for
+ []
+
+
+Underfull \hbox (badness 5607) in paragraph at lines 65--69
+/pplri7t@9.0pt/c++ to java con-ver-sion sup-port/pplr7t@9.0pt/, In-ter-na-tiona
+l
+ []
+
+
+Underfull \hbox (badness 10000) in paragraph at lines 65--69
+/pplr7t@9.0pt/seer.ist.psu.edu/malabarba99mohcajava.html,
+ []
+
+
+Underfull \hbox (badness 10000) in paragraph at lines 71--73
+[]/pplr7t@9.0pt/J. Mar-tin, /pplri7t@9.0pt/Ephedra: A c to java
+ []
+
+
+Underfull \hbox (badness 10000) in paragraph at lines 71--73
+/pplri7t@9.0pt/mi-gra-tion en-vi-ron-ment/pplr7t@9.0pt/, (2002),
+ []
+
+
+Underfull \hbox (badness 1348) in paragraph at lines 78--79
+[]/pplr7t@9.0pt/B. Strous-trup., /pplri7t@9.0pt/The c++ pro-gram-ming lan-guage
+/pplr7t@9.0pt/,
+ []
+
+
+Underfull \hbox (badness 10000) in paragraph at lines 81--83
+[]/pplr7t@9.0pt/T. Wadding-ton, /pplri7t@9.0pt/Java back-
+ []
+
+
+Underfull \hbox (badness 10000) in paragraph at lines 81--83
+/pplri7t@9.0pt/end for gcc/pplr7t@9.0pt/, (Novem-ber 2000),
+ []
+
+
+Overfull \hbox (45.57799pt too wide) in paragraph at lines 81--83
+/pplr7t@9.0pt/http://archive.csee.uq.edu.au/?csmweb/uqbt.html#gccjvm.
+ []
+
+) [8] (./nestedvm.ivme04.aux) )
+Here is how much of TeX's memory you used:
+ 2493 strings out of 95437
+ 30804 string characters out of 1189862
+ 103318 words of memory out of 1000001
+ 5419 multiletter control sequences out of 10000+50000
+ 26163 words of font info for 74 fonts, out of 500000 for 1000
+ 14 hyphenation exceptions out of 1000
+ 29i,15n,24p,218b,509s stack positions out of 1500i,500n,5000p,200000b,5000s
+ 228 PDF objects out of 300000
+ 0 named destinations out of 131072
+ 60 words of extra memory for PDF output out of 65536
+{/usr/local/share/texmf-local/dvips/psnfss/8r.en
+c}</usr/local/share/texmf-local/fonts/type1/urw/palatino/uplb8a.pfb>{/usr/local
+/share/texmf-local/dvips/tetex/f7b6d320.enc}</usr/local/share/texmf-local/fonts
+/type1/bluesky/cm/cmr10.pfb>{/usr/local/share/texmf-local/dvips/tetex/09fbbfac.
+enc}</usr/local/share/texmf-local/fonts/type1/bluesky/cm/cmtt10.pfb>{/usr/local
+/share/texmf-local/dvips/tetex/bbad153f.enc}</usr/local/share/texmf-local/fonts
+/type1/bluesky/cm/cmsy9.pfb></usr/local/share/texmf-local/fonts/type1/urw/palat
+ino/uplr8a.pfb></usr/local/share/texmf-local/fonts/type1/urw/palatino/uplri8a.p
+fb>
+Output written on nestedvm.ivme04.pdf (8 pages, 268208 bytes).
--- /dev/null
+\documentclass{acmconf}
+\usepackage{graphicx}
+\usepackage{multicol}
+\usepackage{amssymb,amsmath,epsfig,alltt}
+\sloppy
+\usepackage{palatino}
+\usepackage{pdftricks}
+\begin{psinputs}
+ \usepackage{pstricks}
+ \usepackage{pst-node}
+\end{psinputs}
+\usepackage{parskip}
+\usepackage{tabularx}
+\usepackage{alltt}
+\bibliographystyle{amsplain}
+
+\title{\textbf{\textsf{
+Complete Translation of Unsafe Native Code to Safe Bytecode
+}}}
+\date{}
+\author{\begin{tabular}{@{}c@{}}
+ {\em {Brian Alliet}} \\
+ {Rochester Institute of Technology}\\
+ {\tt bja8464@cs.rit.edu}
+ \end{tabular}\hskip 1in\begin{tabular}{@{}c@{}}
+ {\em {Adam Megacz}} \\
+ {University of California, Berkeley} \\
+ {\tt megacz@cs.berkeley.edu}
+\end{tabular}}
+\begin{document}
+
+\maketitle
+
+\begin{abstract}
+
+Most existing techniques for using code written in an unsafe language
+within a safe virtual machine involve transformations from one source
+code language (such as C) to another (such as Java) and then to
+virtual machine bytecodes. We present an alternative approach which
+uses a standard compiler to turn unsafe source code into unsafe MIPS
+binaries, which are then translated into safe virtual machine
+bytecodes. This approach offers four key advantages over existing
+techniques:
+
+\begin{itemize}
+\item Total coverage of all language features
+\item No post-translation human intervention
+\item No build process modifications
+\item Bug-for-bug compiler compatability
+\end{itemize}
+
+We have implemented this technique in NestedVM, a binary-to-source and
+binary-to-binary translator targeting the Java Virtual Machine.
+NestedVM-translated versions of the {\tt libfreetype}, {\tt libjpeg},
+and {\tt libmspack} libraries are currently in production use.
+Performance measurements indicate a best case performance within 3x of
+native code and worst case typically within 10x, making it an
+attractive solution for code which is not performance-critical.
+
+\end{abstract}
+
+\section{Introduction}
+
+Unsafe languages such as C \cite{KR} and C++ \cite{soustroup} have
+been in use much longer than any of today's widely accepted safe
+languages such as Java \cite{java} and C\# \cite{csharp}. Consequently, there is
+a huge library of software written in these languages. Although safe
+languages offer substantial benefits, their comparatively young age
+often puts them at a disadvantage when breadth of existing support
+code is an important criterion.
+
+The typical solution to this dilemma is to use a native interface such
+as JNI \cite{jni} or CNI \cite{cni} to invoke unsafe code from within a
+virtual machine or otherwise safe environment. Unfortunately, there
+are a number of situations in which this is not an acceptable
+solution. These situations can be broadly classified into two
+categories: {\it security concerns} and {\it portability concerns}.
+
+Using Java as an example, JNI and CNI are prohibited in a number of
+contexts, including applets environments and servlet containers with a
+{\tt SecurityManager}. Additionally, even in the context of trusted
+code, {\tt native} methods invoked via JNI are susceptible to buffer
+overflow and heap corruption attacks which are not a concern for
+verified bytecode.
+
+The second class of disadvantages revolves around portability
+concerns; native interfaces require the native library to be compiled
+ahead of time, for every architecture on which they will be
+deployed. This is unworkable for situations in which the full set of
+target architectures is not known at deployment time. Additionally,
+some JVM platform variants such as J2ME \cite{j2me} simply do not offer
+support for native code.
+
+The technique we present here uses typical compiler to compile unsafe
+code into a MIPS binary, which is then translated on an
+instruction-by-instruction basis into Java bytecode. The technique
+presented here is general; we anticipate that it can be applied to
+other secure virtual machines such as Microsoft's .NET \cite{msil}, Perl
+Parrot \cite{parrot}, or Python bytecode \cite{python}.
+
+\section{Approaches to Translation}
+
+The four program representations of interest in this context, along
+with their specific types in the C-to-JVM instantiation of the
+problem are shown in the following diagram:
+
+\begin{pdfpic}
+\newlength{\MyLength}
+\settowidth{\MyLength}{machine code}
+\newcommand{\MyBox}[1]{\makebox[\MyLength][c]{#1}}
+\begin{psmatrix}[colsep=2,rowsep=0]
+ & \\[0pt]
+ [name=s0]\MyBox{unsafe source} & [name=s1]\MyBox{safe source} \\[0pt]
+ [name=s00]\MyBox{\tt (.c)} & [name=s11]\MyBox{\tt (.java)} \\[0pt]
+ & \\[0pt]
+ & \\[0pt]
+ & \\[0pt]
+ [name=b0]\MyBox{machine code} & [name=b1]\MyBox{safe bytecode} \\[0pt]
+ [name=b00]\MyBox{\tt (.o)} & [name=b11]\MyBox{\tt (.class)} \\
+ & \\[0pt]
+ \psset{nodesep=5pt,arrows=->}
+\end{psmatrix}
+\end{pdfpic}
+
+To illustrate the context of this diagram, the following arcs show the
+translations performed by a few familiar tools:
+
+\begin{pdfpic}
+\newlength{\MyLength}
+\settowidth{\MyLength}{xmachine codex}
+\newcommand{\MyBox}[1]{\makebox[\MyLength]{#1}}
+\psmatrix[colsep=2,rowsep=0,nrot=:D]
+ & \\[0pt]
+ [name=s0]\MyBox{unsafe source} & [name=s1]\MyBox{safe source} \\[0pt]
+ & \\[0pt]
+ & \\[0pt]
+ & \\[0pt]
+ & \\[0pt]
+ & \\[0pt]
+ [name=b0]\MyBox{machine code} & [name=b1]\MyBox{safe bytecode} \\[0pt]
+ & \\[0pt]
+ \psset{nodesep=5pt,arrows=->}
+ \ncline{s0}{b0}\bput{:U}{\tt gcc}
+ \ncline{s1}{b0}\bput{:D}{\tt gcj}
+ \ncline{s1}{b1}\aput{:U}{\tt javac}
+ \ncline{b1}{b0}\aput{:D}{\tt gcj}\bput{:D}{JITs}
+\endpsmatrix
+\end{pdfpic}
+
+Techniques for translating unsafe code into VM bytecode generally fall
+into four categories, which we expand upon in the next two sections:
+
+\begin{itemize}
+\item source-to-source translation
+\item source-to-binary translation
+\item binary-to-source translation
+\item binary-to-binary translation
+\end{itemize}
+
+\section{Existing Work}
+
+\subsection{Source-to-Source Translation}
+
+The most common technique employed is partial translation from unsafe
+source code to safe source code:
+
+\begin{pdfpic}
+\newlength{\MyLength}
+\settowidth{\MyLength}{xmachine codex}
+\newcommand{\MyBox}[1]{\makebox[\MyLength]{#1}}
+\psmatrix[colsep=2,rowsep=0,nrot=:U]
+ & \\[0pt]
+ & \\[0pt]
+ [name=s0]\MyBox{unsafe source} & [name=s1]\MyBox{safe source} \\[0pt]
+ & \\[0pt]
+ & \\[0pt]
+ & \\[0pt]
+ & \\[0pt]
+ & \\[0pt]
+ [name=b0]\MyBox{machine code} & [name=b1]\MyBox{safe bytecode} \\[0pt]
+ & \\[0pt]
+ \psset{nodesep=5pt,arrows=->}
+ \ncline{s0}{s1}\aput{:U}{source-to}\bput{:U}{source}
+ \ncline{s1}{b1}\aput{:U}{\tt javac}
+\endpsmatrix
+\end{pdfpic}
+
+A number of existing systems employ this technique; they can
+be divided into two categories: those which perform a partial
+translation which is completed by a human, and those which perform a
+total translation but fail (yield an error) on a large class of input
+programs.
+
+
+\subsubsection{Incomplete Translation}
+
+Jazillian \cite{jazillian} is a commercial solution which produces
+extremely readable Java source code from C source code, but ony
+translates a small portion of the C language. Jazillian is unique in
+that in addition to {\it language migration}, it also performs {\it
+API migration}; for example, Jazillian is intelligent enough
+to translate {\tt char*~s1~=~strcpy(s2)} into {\tt String~s1~=~s2}.
+
+Unfortunately such deep analysis is intractible for most of the C
+language and standard library; Jazillian's documentation notes that
+{\it ``This is not your father's language translator. It's not
+generating ugly code that's guaranteed to work out of the
+box... Jazillian does not always produce code that works correctly.''}
+
+MoHCA-Java \cite{mohca} is the other major tool in this category, and steps
+beyond Jazillian by providing tools for analysis of the source C++
+abstract syntax tree. Additionally, MoHCA-Java's analysis engine is
+extensible, making it a platform for constructing application-specific
+translators rather than a single translation tool. However,
+MoHCA-Java does not always generate complete Java code for all of the C++
+programs which it accepts.
+
+
+\subsubsection{Partial Domain Translation}
+
+The c2j \cite{c2j}, c2j++ \cite{c2jpp}, Cappucinno \cite{capp},
+and Ephedra \cite{ephedra} systems each provide support for complete
+translation of a {\it subset} of the source language (C or C++). Each
+of the four tools supports a progressively greater subset than the one
+preceding it; however none covers the entire input language.
+
+Ephedra, the most advanced of the four, supports most of the C++
+language, and claims to produce ``human readable'' Java code as
+output. Notable omissions from the input domain include support for
+fully general pointer arithmetic, casting between unrelated types, and
+reading from a {\tt union} via a different member than the one most
+recently written.
+
+Unfortunately, when the program being translated is large and complex,
+it is quite likely that it will use an unsupported feature in at least
+one place. In the absence of a programmer who understands the source
+program, a single anomoly is often enough to render the entire
+translation process useless. As a result, these tools are mainly
+useful as an {\it aid} to programmers who could normally perform the
+conversion themselves, but want to save time by automating most of the
+process.
+
+
+\subsection{Source-to-Binary Translation}
+
+Source-to-binary translation involves a compiler for the unsafe
+language which has been modified to emit safe bytecode.
+
+\begin{pdfpic}
+\newlength{\MyLength}
+\settowidth{\MyLength}{xmachine codex}
+\newcommand{\MyBox}[1]{\makebox[\MyLength]{#1}}
+\psmatrix[colsep=2,rowsep=0,nrot=:U]
+ & \\[0pt]
+ [name=s0]\MyBox{unsafe source} & [name=s1]\MyBox{safe source} \\[0pt]
+ & \\[0pt]
+ & \\[0pt]
+ & \\[0pt]
+ & \\[0pt]
+ & \\[0pt]
+ [name=b0]\MyBox{machine code} & [name=b1]\MyBox{safe bytecode} \\[0pt]
+ & \\[0pt]
+ \psset{nodesep=5pt,arrows=->}
+ \ncline{s0}{b1}\bput{:U}{source-to-binary}
+\endpsmatrix
+\end{pdfpic}
+
+The primary occupant of this category is {\tt egcs-jvm}
+\cite{egcsjvm}, an experimental ``JVM backend'' for the GNU Compiler
+Collection ( {\tt gcc} ) \cite{gcc}. Since {\tt gcc} employs a highlym
+odular architecture, it {\it is} possible to add RTL code generators
+for nonstandard processors. However, {\tt gcc}'s parsing, RTL
+generation, and optimization layers make fundamental assumptions (such
+as the availability of pointer math) which cannot be directly
+supported; thus the compiler still fails for a substantial class of
+input programs.
+
+
+
+\section{NestedVM}
+
+The principal difference between NestedVM and other approaches is that
+NestedVM {\it does not} attempt to deal with source code as an input.
+This leads immediately to three advantages:
+
+\begin{itemize}
+\item {\bf Total coverage of all language features}
+
+ Because NestedVM does not attempt to implement the parsing and
+ code generation steps of compilation, it is freed from the
+ extremely complex task of faithfully implementing languages
+ which are often not fully or formally specified (such as C and
+ C++).
+
+\item {\bf No build process modifications}
+
+ NestedVM does not modify existing build processes, which can be
+ extremely complex and dependent on strange preprocessor usage as
+ well as the complex interplay between compiler switches and
+ header file locations.
+
+\item {\bf Bug-for-bug compiler compatability}
+
+ Since NestedVM uses the compiler's {\it output} as its own {\it
+ input}, it ensures that programs which are inadvertently
+ dependent on the vagaries of a particular compiler can still be
+ used.
+
+\end{itemize}
+
+NestedVM's approach carries a fourth benefit as well, arising from its
+totality:
+
+\begin{itemize}
+\item {\bf No post-translation human intervention}
+
+ NestedVM offers total support for all non-privileged
+ instructions, registers, and resources found on a MIPS {\tt
+ R2000} CPU, including the add/multiply unit and floating point
+ coprocessor. As such, it constitutes a total function mapping
+ from the entire domain of (non-kernel-mode) programs onto (a
+ subset of) the semantics of the Java Virtual Machine. This
+ ensures that the translation process is fully automated and
+ always succeeds for valid input binaries.
+\end{itemize}
+
+This is a much more important factor than is obvious at first glance.
+If post-translation human intervention is required, then the {\it
+human becomes part of the build process}. This means that if a third
+party library used in the project needs to be upgraded, {\it a human
+must intervene} in the rebuild process. In addition to slowing the
+process and introducing opportunities for error, this task often
+requires specialized knowledge which becomes tied to the particular
+individual performing this task, rather than being encoded in build
+scripts which persist throughout the lifetime of the project.
+
+\subsection{Why MIPS?}
+
+We chose MIPS as a source format for three reasons: the availability
+of tools to compile legacy code into MIPS binaries, the close
+similarity between the MIPS ISA and the Java Virtual Machine, and the
+relatively high degree of program structure that can be inferred from
+ABI-adherent binaries.
+
+The MIPS architecture has been around for quite some time, and is well
+supported by the GNU Compiler Collection, which is capable of
+compiling C, C++, Java, Fortran, Pascal, and Objective C
+into MIPS binaries.
+
+The MIPS R2000 ISA bears a striking similarity to the Java Virtual
+Machine:
+
+\begin{itemize}
+
+\item Most of the instructions in the original MIPS ISA operate only
+ on 32-bit aligned memory locations. This allows NestedVM to
+ represent memory as a Java {\tt int[]} array without introducing
+ additional overhead. The remaining non-aligned memory load
+ instructions are only rarely emitted by most compilers since
+ they carry a performance penalty on physical MIPS
+ implementations.
+
+\item Unlike its predecessor, the R2000 supports 32-bit by 32-bit
+ multiply and divide instructions as well as a single and double
+ precision floating point unit. These capabilities map nicely
+ onto Java's arithmetic instructions.
+
+\end{itemize}
+
+Finally, the MIPS ISA and ABI convey quite a bit of information about
+program structure. This information can be used for optimization
+purposes:
+
+\begin{itemize}
+
+\item The structure of MIPS branching and jump instructions make it
+ easy to infer the set of likely target instructions.
+
+\item The MIPS ABI specifies particular registers as caller-save and
+ callee-save, as well as designating a register for the return
+ address after a function call. This allows NestedVM to optimize
+ many operations for the common case of ABI-adherent binaries.
+
+\item All MIPS instructions are exactly 32 bits long.
+
+\end{itemize}
+
+
+
+\subsection{Binary-to-Source}
+
+The simplest operational mode for NestedVM is binary-to-source
+translation. In this mode, NestedVM translates MIPS binaries into
+Java source code, which is then fed to a Java compiler in order to
+produce bytecode files:
+
+\begin{pdfpic}
+\newlength{\MyLength}
+\settowidth{\MyLength}{xmachine codex}
+\newcommand{\MyBox}[1]{\makebox[\MyLength]{#1}}
+\psmatrix[colsep=2,rowsep=0,nrot=:U]
+ & \\[0pt]
+ & \\[0pt]
+ [name=s0]\MyBox{unsafe source} & [name=s1]\MyBox{safe source} \\[0pt]
+ & \\[0pt]
+ & \\[0pt]
+ & \\[0pt]
+ & \\[0pt]
+ & \\[0pt]
+ [name=b0]\MyBox{machine code} & [name=b1]\MyBox{safe bytecode} \\[0pt]
+ \psset{nodesep=5pt,arrows=->}
+ \ncline{s0}{b0}\bput{:U}{\tt gcc}
+ \ncline{s1}{b1}\aput{:U}{\tt javac}
+ \ncline{b0}{s1}\naput{\tt NestedVM}
+\endpsmatrix
+\end{pdfpic}
+
+\begin{figure*}[t]
+\begin{minipage}[c]{7in}%
+\begin{multicols}{2}
+{\footnotesize\begin{verbatim}
+private final static int r0 = 0;
+private int r1, r2, r3,...,r30;
+private int r31 = 0xdeadbeef;
+private int pc = ENTRY_POINT;
+
+public void run() {
+ for(;;) {
+ switch(pc) {
+ case 0x10000:
+ r29 = r29 - 32;
+ case 0x10004:
+ r1 = r4 + r5;
+ case 0x10008:
+ if(r1 == r6) {
+ /* delay slot */
+ r1 = r1 + 1;
+ pc = 0x10018:
+ continue;
+ }
+ case 0x1000C:
+ r1 = r1 + 1;
+ case 0x10010:
+ r31 = 0x10018;
+ pc = 0x10210;
+ continue;
+ case 0x10014:
+ /* nop */
+ case 0x10018:
+ pc = r31;
+ continue;
+ ...
+ case 0xdeadbeef:
+ System.err.println(``Exited.'');
+ System.exit(1);
+ }
+ }
+}
+\end{verbatim}}
+\vspace{1in}
+{\footnotesize\begin{verbatim}
+public void run_0x10000() {
+ for(;;) {
+ switch(pc) {
+ case 0x10000:
+ ...
+ case 0x10004:
+ ...
+ ...
+ case 0x10010:
+ r31 = 0x10018;
+ pc = 0x10210;
+ return;
+ ...
+ }
+ }
+}
+
+pubic void run_0x10200() {
+ for(;;) {
+ switch(pc) {
+ case 0x10200:
+ ...
+ case 0x10204:
+ ...
+ }
+ }
+}
+
+public void trampoline() {
+ for(;;) {
+ switch(pc&0xfffffe00) {
+ case 0x10000: run_0x10000(); break;
+ case 0x10200: run_0x10200(); break;
+ case 0xdeadbe00:
+ ...
+ }
+ }
+}
+\end{verbatim}}
+\end{multicols}
+\end{minipage}
+\caption{\label{code1} Trampoline transformation necessitated by Java's 64kb method size limit}
+\end{figure*}
+
+Translating unsafe code for use within a JVM proceeds as follows:
+
+\begin{enumerate}
+
+\item Compile the source code to a statically linked binary, targeting
+ the MIPS R2000 ISA. Typically this will involve linking against
+ {\tt libc}, which translates system requests (such as {\tt
+ open()}, {\tt read()}, or {\tt write()}) into appropriate
+ invocations of the MIPS {\tt SYSCALL} instruction.
+
+\item Invoke {\tt NestedVM} on the statically linked binary.
+
+\item Compile the resulting {\tt .java} code using {\tt jikes}
+ \cite{jikes} or {\tt javac}.
+
+\item From java code, invoke the {\tt run()} method on the generated
+ class. This is equivalent to the {\tt main()} entry point.
+
+\end{enumerate}
+
+\subsubsection{Optimizations}
+
+Generating Java source code instead of bytecode frees NestedVM from
+having to perform simple constant propagation optimizations, as most
+Java compilers already do this. A recurring example is the treatment
+of the {\tt r0} register, which is fixed as {\tt 0} in the MIPS ISA.
+
+Lacking the ability to generate specially optimized bytecode
+sequences, a straightforward mapping of the general purpose hardware
+registers to 32 {\tt int} fields turned out to be optimal.
+
+
+\epsfig{file=chart1,width=3in}
+
+Unfortunately, Java imposes a 64kb limit on the size of the bytecode
+for a single method. This presents a problem for NestedVM, and
+necessitates a {\it trampoline transformation}, as shown in
+Figure~\ref{code1}. With this trampoline in place, large binaries can
+be handled without much difficulty -- fortunately, there is no
+corresponding limit on the size of a classfile as a whole.
+
+One difficulty that arose as a result of using the trampoline
+transformation was the fact that {\tt javac} and {\tt jikes} are
+unable to properly optimize its switch statements. For example, the
+following code is compiled into a comparatively inefficient {\tt
+LOOKUPSWITCH}:
+
+{\footnotesize
+\begin{verbatim}
+ switch(pc&0xffffff00) {
+ case 0x00000100: run_100(); break;
+ case 0x00000200: run_200(); break;
+ case 0x00000300: run_300(); break;
+ }
+\end{verbatim}}
+
+{\footnotesize
+\begin{verbatim}
+ switch(pc>>>8) {
+ case 0x1: run_100();
+ case 0x2: run_200();
+ case 0x3: run_300();
+ }
+\end{verbatim}}
+
+This problem was surmounted by switching on a denser set of {\tt case}
+values, which is more amenable to the {\tt TABLESWITCH} structure.
+This change alone nearly doubled the speed of the compiled binary.
+
+The next performance improvement came from tuning the size of the
+methods invoked from the trampoline. Trial and error led to the
+conclusion that HotSpot \cite{hotspot}, the most popular JVM, performs
+best when 128 MIPS instructions are mapped to each method.
+
+\epsfig{file=chart5,width=3in}
+
+\epsfig{file=chart6,width=3in}
+
+This phenomenon is due to two factors:
+
+\begin{itemize}
+
+\item While the trampoline method's {\tt switch} statement can be
+ coded as a {\tt TABLESWITCH}, the {\tt switch} statement
+ within the individual methods is to sparse to encode this way.
+
+\item Hybrid Interpretive-JIT compilers such as HotSpot generally
+ favor smaller methods since they are easier to compile and are
+ better candidates for compilation in ``normal'' programs (unlike
+ NestedVM programs).
+
+\end{itemize}
+
+After tuning method sizes, our next performance boost came from
+eliminating exraneous case branches. Having case statements before
+each instruction prevents JIT compilers from being able to optimize
+across instruction boundaries, since control flow can enter the body
+of a {\tt switch} statement at any of the {\tt case}s. In order to
+eliminate unnecessary case statements we needed to identify all
+possible jump targets. Jump targets can come from three sources:
+
+Putting more than 256 instructions in each method lead to a severe
+performance penalty. Apparently Hotspot does not handle very large methods
+well. In some tests the simple moving from 256 to 512 instructions per
+method decreased performance by a factor of 10.
+
+Put chart here
+
+The next big optimization was eliminating unnecessary case
+statements. Having case statements before each instruction prevents
+JIT compilers from being able to optimize across instruction
+boundaries. In order to eliminate unnecessary case statements every
+possible address that could be jumped to directly needed to be
+identified. The sources for possible jump targets come from 3 places.
+
+\begin{itemize}
+
+\item {\bf The {\tt .text} segment}
+
+ Every instruction in the text segment is scanned, and every
+ branch instruction's destination is added to the list of
+ possible branch targets. In addition, any function that sets
+ the link register is added to the list \footnote{actually {\tt addr+8}}.
+ Finally, combinations of {\tt LUI} (Load Upper Immediate) and
+ {\tt ADDIU} (Add Immediate Unsigned) are scanned for possible
+ addresses in the {\tt .text} segment since this combination of
+ instructions is often used to load a 32-bit word into a
+ register.
+
+\item {\bf The {\tt .data} segment}
+
+ When compiling {\tt switch} statements, compilers often use a
+ jump table stored in the {\tt .data} segment. Unfortunately
+ they typically do not identify these jump tables in any way.
+ Therefore, the entire {\tt .data} segment is conservatively
+ scanned for possible addresses in the {\tt .text} segment.
+
+\item {\bf The symbol table}
+
+ This is mainly used as a backup. Scanning the {\tt .text} and
+ {\tt .data} segments should identify any possible jump targets;
+ however, adding all function symbols in the ELF symbol table
+ also catches functions that are never called directly from the
+ MIPS binary, such as those invoked only via the NestedVM
+ runtime's {\tt call()} method.
+
+\end{itemize}
+
+Eliminating unnecessary {\tt case} statements provided a 10-25\% speed
+increase.
+
+Despite all the above optimizations, one insurmountable obstacle
+remained: the Java {\tt .class} file format limits the constant pool
+to 65535 entries. Every integer literal greater than {\tt 32767}
+requires an entry in this pool, and each branch instruction generates
+one of these.
+
+One suboptimal solution was to express constants as offsets from a few
+central values; for example ``{\tt pc~=~N\_0x00010000~+~0x10}'' (where
+{\tt N\_0x000100000} is a non-final field to prevent {\tt javac} from
+inlining it). This was sufficient to get reasonably large binaries to
+compile, and caused only a small (approximately 5\%) performance
+degredation and a similarly small increase in the size of the {\tt
+.class} file. However, as we will see in the next section, compiling
+directly to {\tt .class} files (without the intermediate {\tt .java}
+file) eliminates this problem entirely.
+
+
+\subsection{Binary-to-Binary}
+
+After implementing the binary-to-source compiler, a binary-to-binary
+translation mode was added.
+
+\begin{pdfpic}
+\newlength{\MyLength}
+\settowidth{\MyLength}{xmachine codex}
+\newcommand{\MyBox}[1]{\makebox[\MyLength]{#1}}
+\psmatrix[colsep=2,rowsep=0,nrot=:U]
+ & \\[0pt]
+ [name=s0]\MyBox{unsafe source} & [name=s1]\MyBox{safe source} \\[0pt]
+ & \\[0pt]
+ & \\[0pt]
+ & \\[0pt]
+ & \\[0pt]
+ & \\[0pt]
+ [name=b0]\MyBox{machine code} & [name=b1]\MyBox{safe bytecode} \\[0pt]
+ & \\[0pt]
+ \psset{nodesep=5pt,arrows=->}
+ \ncline{s0}{b0}\bput{:U}{\tt gcc}
+ \ncline{b0}{b1}\naput{\tt NestedVM}
+\endpsmatrix
+\end{pdfpic}
+
+This mode has several advantages:
+
+\begin{itemize}
+
+\item There are quite a few interesting bytecode sequences that cannot
+ be generated as a result of compiling Java source code.
+
+\item Directly generating {\tt .class} files Eliminates the
+ time-consuming {\tt javac} step.
+
+\item Direct compilation to {\tt .class} files opens up the
+ interesting possibility of dynamically translating MIPS binaries
+ and loading them via {\tt ClassLoader.fromBytes()} {\it at
+ deployment time}, eliminating the need to compile binaries ahead
+ of time.
+
+\end{itemize}
+
+Most of the performance improvemen where made where in the handling of
+branch instructions and in taking advantage of the JVM stack to
+eliminate unnecessary {\tt LOAD}s and {\tt STORE}s to local variables.
+
+\epsfig{file=chart7,width=3in}
+
+The first optimization gained by direct bytecode generation came from
+the use of the JVM {\tt GOTO} instruction. Despite the fact that the
+Java {\it language} does not have a {\tt goto} keyword, the VM does in
+fact have a corresponding instruction which is used quite heavily by
+{\tt javac}. NestedVM's binary-to-binary mode exploits this
+instruction to avoid emitting inefficient {\tt switch..case}
+structures.
+
+Related to the {\tt GOTO} instruction is branch statement
+optimization. When emitting source code, NestedVM translates branches
+into Java source code like this:
+
+{\footnotesize\begin{verbatim}
+ if (condition) {
+ pc = TARGET;
+ continue;
+ }
+\end{verbatim}}
+
+This requires a branch in the JVM {\it regardless} of whether the MIPS
+branch is actually taken. If {\tt condition} is false the JVM has to
+jump over the code to set {\tt pc} and go back to the {\tt switch}
+statemenmt; if {\tt condition} is true the JVM has to jump to the {\tt
+switch} block. By generating bytecode directly, NestedVM is able to
+emit a JVM bytecode branching directly to the address corresponding to
+the target of the MIPS branch. In the case where the branch is not
+taken the JVM doesn't branch at all.
+
+A side effect of the previous two optimizations is a solution to the
+excess constant pool entries problem. When jumps are implemented as
+{\tt GOTO}s and branches are taken directly, the {\tt pc} field does
+not need to be set. This eliminates a huge number of constant pool
+entries. The {\tt .class} file constant pool size limit is still
+present, but it is less likely to be encountered.
+
+Implementation of the MIPS delay slot offers another opportunity for
+bytecode-level optimization. In order to take advantage of
+instructions already in the pipeline, the MIPS ISA specifies that the
+instruction after a jump or branch is always executed, even if the
+jump/branch is taken. This instruction is referred to as the ``delay
+slot\footnote{Newer MIPS CPUs have pipelines that are much larger than
+early MIPS CPUs, so they have to discard instructions anyways}.'' The
+instruction in the delay slot is actually executed {\it before} the
+branch is taken. To further complicate matters, values from the
+register file are loaded {\it before} the delay slot is executed.
+
+Fortunately there is a very elegent solution to this problem which can
+be expressed in JVM bytecode. When a branch instruction is
+encountered, the registers needed for the comparison are pushed onto
+the stack to prepare for the JVM branch instruction. Then, {\it
+after} the values are on the stack the delay slot instruction is
+emitted, followed by the actual JVM branch instruction. Because the
+values were pushed to the stack before the delay slot was executed, any
+changes the delay slot made to the registers are not visible to the
+branch bytecode.
+
+One final advantage that generating bytecode directly allows is a
+reduction in the size of the ultimate {\tt .class} file. All the
+optimizations above lead to more compact bytecode as a beneficial side
+effect; in addition, NestedVM performs a few additional optimizations.
+
+When encountering the following {\tt switch} block, both {\tt javac}
+and {\tt jikes} generate redundant bytecode.
+
+{\footnotesize\begin{verbatim}
+ switch(pc>>>8) {
+ case 0x1: run_1(); break;
+ case 0x2: run_2(); break
+ ...
+ case 0x100: run_100(); break;
+ }
+\end{verbatim}}
+
+The first bytecode in each case arm in the switch statement is {\tt
+ALOAD\_0} to prepare for a {\tt INVOKESPECIAL} call. By simply
+lifting this bytecode outside of the {\tt switch} statement, each {\tt
+case} arm shrinks by one instruction.
+
+\subsubsection{Compiler Flags}
+
+Although NestedVM perfectly emulates a MIPS R2000 CPU, its performance
+profile is nothing like that of actual silicon. In particular, {\tt
+gcc} makes several optimizations that increase performance on an
+actually MIPS CPU but actually decrease the performance of
+NestedVM-generated bytecode. We found the following compiler options
+could be used to improve performance:
+
+\begin{itemize}
+
+\item {\tt -falign-functions}
+
+ Normally a function's location in memory has no effect on its
+ execution speed. However, in the NestedVM binary translator,
+ the {\tt .text} segment is split on power-of-two boundaries. If
+ a function starts near the end of one of these boundaries, a
+ performance critical part of the function winds up spanning two
+ Java methods. Telling {\tt gcc} to align all functions along
+ these boundaries decreases the chance of this sort of splitting.
+
+\item {\tt -fno-rename-registers}
+
+ On an actual silicon chip, using additional registers carries no
+ performance penalty (as long as none are spilled to the stack).
+ However, when generating bytecode, using {\it fewer}
+ ``registers'' helps the JVM optimize the machine code it
+ generates by simplifying the constraints it needs to deal with.
+ Disabling register renaming has this effect.
+
+\item {\tt -fno-schedule-insns}
+
+ Results of MIPS load operations are not available until {\it
+ two} instructions after the load. Without the {\tt
+ -fno-schedule-insns} instruction, {\tt gcc} will attempt to
+ reorder instructions to do other useful work during this period
+ of unavailability. NestedVM is under no such constraint, so
+ removing this reordering typically generates simpler machine
+ code.
+
+\item {\tt -mmemcpy}
+
+ Enabling this instruction causes {\tt gcc} to use the system
+ {\tt memcpy()} routine instead of generating loads and stores.
+ As explained in the next section, the NestedVM runtime
+ implements {\tt memcpy()} using {\tt System.arraycopy()}, which
+ is substantially more efficient.
+
+NestedVM has two primary ways of executing code, the interpreter, and the
+binary translators. Both the interpreter and the output from the binary
+translators sit on top of a Runtime class. This class provides the public
+interface to both the interpreter and the translated binaries.
+
+The Runtime class does the work that the operating system usually does.
+Conceptually the Runtime class can be thought of as the operating system and
+its subclasses (translated binaries and the interpreter) the CPU. The
+Runtime fulfills 5 primary goals:
+
+\item {\tt -fno-rename-registers} Some processors can better schedule
+ code when registers aren't reused for two different purposes. By
+ default GCC will try to use as many registers as possibly when
+ it can. This excess use of registers just confuses JIT's trying
+ to compile the output from the binary translator. All the JIT
+ compilers we tested do much better with a few frequently used
+ registers.
+
+\item {\tt -fno-delayed-branch} The MIPS CPU has a delay slot (see
+ above). Earlier versions of NestedVM didn't efficiently emulate
+ delay slots. This option causes GCC to avoid using delay slots
+ for anything (a NOP is simply placed in the delay slot). This
+ had a small performance benefit. However, recent versions of
+ NestedVM emulate delay slots with no performance overhead so
+ this options has little effect. Nonetheless, these delay slots
+ provide no benefit under NestedVM either so they are avoided
+ with this option.
+
+\end{itemize}
+
+The effects of the various optimizations presented in this chapter are
+summarized in the table below.
+
+\epsfig{file=chart4,width=3in}
+
+\epsfig{file=chart3,width=3in}
+
+\section{The NestedVM Runtime}
+
+In addition to binary-to-source and binary-to-binary translation,
+NestedVM also includes a MIPS binary interpreter. All three
+translation approaches expose the same API to both the translated
+binary and the surrounding VM (including peer Java code).
+
+\subsection{The Runtime Class}
+
+The runtime fulfills four roles:
+
+\begin{itemize}
+
+\item It provides a simple, consistent external interface. The method
+ of actually executing the code (currently only translated
+ binaries and the interpreter) can be changed without any code
+ changes to the caller because only runtime exposes a public
+ interface. This includes methods to pass arguments to the
+ binary's {\tt main()} function, read and write from memory, and
+ call individual functions in the binary.
+
+\item It manages the process's memory. The runtime class contains
+ large {\tt int[]} arrays that represent the process`s entire
+ memory space. Subclasses read and write to these arrays as
+ required by the instructions they are executing, and can expand
+ their memory space using the {\tt sbrk} system call.
+
+\item The runtime provides access to the host file system and standard
+ I/O streams. Subclasses of {\tt runtime} can access the file
+ system through standard UNIX syscalls ({\tt read()}, {\tt
+ write()}, {\tt open()}, etc). The runtime manages the file
+ descriptor table that maps UNIX file descriptors to Java {\tt
+ RandomAccessFile}s, {\tt InputStream}s, {\tt OutputStream}s, and
+ {\tt Socket}s.
+
+\item It provides general OS services, including {\tt sleep()}, {\tt
+ gettimeofday()}, {\tt getpagesize()}, {\tt sysconf()}, {\tt
+ fcntl()}, and so on.
+
+\end{itemize}
+
+\section{Future Directions}
+
+Although we have only implemented it for the Java Virtual Machine, our
+technique generalizes to other safe bytecode architectures. In
+particular we would like to demonstrate this generality by retargeting
+the translator to the Microsoft Intermediate Language \cite{msil}.
+
+Additionally, we would like to explore other uses for dynamic loading
+of translated MIPS binaries by combining NestedVM (which itself is
+written in Java) and the {\tt ClassLoader.fromBytes()} mechanism.
+
+
+\section{Conclusion}
+
+We have presented a novel technique for using libraries written in
+unsafe languages within a safe virtual machine without resorting to
+native interfaces. We have implemented this technique in NestedVM,
+which is currently used by the Ibex project\footnote{{\tt
+http://www.ibex.org}} to perform font rasterization (via {\tt
+libfreetype}), JPEG decoding (via {\tt libjpeg}), and CAB archive
+extraction (via {\tt libmspack}), three libraries for which no
+equivalent Java classes exist.
+
+NestedVM is available under an open source license, and can be
+obtained from
+\begin{verbatim}
+ http://nestedvm.ibex.org
+\end{verbatim}
+
+
+\section{Appendix: Testing Methodology}
+
+The MIPS binaries can also invoke a special method of Runtime called
+callJava().When the MIPS binary invokes the {\tt CALL\_JAVA} syscall
+(usually done through the {\tt \_call\_java()} function provided by
+the NestedVM support library) the callJava() method in Runtime is
+invoked with the arguments passes to the syscall.
+
+{\footnotesize\begin{verbatim}
+
+// Java
+private Runtime rt = new MyBinary() {
+ pubilc int callJava(int a, int b, int c, int d) {
+ System.err.println("Got " + a + " " + b);
+ }
+};
+public void foo() { rt.run(); }
+
+/* C */
+void main(int argc, char **argv) {
+ _call_java(1,2);
+}
+
+\end{verbatim}}
+
+These two methods can even be combined. MIPS can call Java through the
+CALL\_JAVA syscall, which can in turn invoke a MIPS function in the
+binary with the call() method.\r\r Users preferring a simpler
+communication mechanism can also use Java StreamÕs and file
+descriptors. Runtime provides a simple interface for mapping a Java
+Input or OutputStream to a File Descriptor.
+
+Users preferring a simpler communication mechanism can also use Java
+Stream's and file descriptors. Runtime provides a simple interface for
+mapping a Java Input or OutputStream to a File Descriptor.
+
+%Java source code can create a copy of the translated binary by
+%instantiating the corresponding class, which extends {\tt Runtime}.
+%Invoking the {\tt main()} method on this class is equivalent to
+%calling the {\tt main()} function within the binary; the {\tt String}
+%arguments to this function are copied into the binary's memory space
+%and made available as {\tt **argv} and {\tt argc}.
+
+%The translated binary communicates with the rest of the VM by
+%executing MIPS {\tt SYSCALL} instructions, which are translated into
+%invocations of the {\tt syscall()} method. This calls back to the
+%native Java world, which can manipulate the binary's environment by
+%reading and writing to its memory space, checking its exit status,
+%pausing the VM, and restarting the VM.
+
+
+%\subsection{Virtualization}
+
+%The {\tt Runtime} class implements the majority of the standard {\tt
+%libc} syscalls, providing a complete interface to the filesystem,
+%network socket library, time of day, (Brian: what else goes here?).
+
+%\begin{itemize}
+
+%\item ability to provide the same interface to CNI code and
+ % NestedVMified code
+
+%\item security advantages (chroot the {\tt fork()}ed process)
+ %
+%\end{itemize}
+
+
+\section{Future Directions}
+
+\section{Conclusion}
+
+\section{Appendix A: Testing Environment}
+
+All times are measured in seconds. These were all run on a dual 1ghz
+G4 running OS X 10.3.1 with Apple's latest VM (JDK 1.4.1\_01-27). Each
+*************
+/* C */
+void do_work(int n) {
+ int i;
+ int ret=0;
+ for(i=0;i<n;i++) ret += i;
+ return n;
+}
+
+\end{verbatim}}
+
+The MIPS binaries can also invoke a special method of Runtime called
+callJava().When the MIPS binary invokes the {\tt CALL\_JAVA} syscall
+(usually done through the {\tt \_call\_java()} function provided by
+the NestedVM support library) the callJava() method in Runtime is
+invoked with the arguments passes to the syscall.
+
+{\footnotesize\begin{verbatim}
+
+// Java
+private Runtime rt = new MyBinary() {
+ pubilc int callJava(int a, int b, int c, int d) {
+ System.err.println("Got " + a + " " + b);
+ }
+};
+public void foo() { rt.run(); }
+
+/* C */
+void main(int argc, char **argv) {
+ _call_java(1,2);
+}
+
+\end{verbatim}}
+
+These two methods can even be combined. MIPS can call Java through the
+CALL\_JAVA syscall, which can in turn invoke a MIPS function in the binary
+with the call() method.
+
+Users preferring a simpler communication mechanism can also use Java
+Stream's and file descriptors. Runtime provides a simple interface for
+mapping a Java Input or OutputStream to a File Descriptor.
+
+%Java source code can create a copy of the translated binary by
+%instantiating the corresponding class, which extends {\tt Runtime}.
+%Invoking the {\tt main()} method on this class is equivalent to
+%calling the {\tt main()} function within the binary; the {\tt String}
+%arguments to this function are copied into the binary's memory space
+%and made available as {\tt **argv} and {\tt argc}.
+
+%The translated binary communicates with the rest of the VM by
+%executing MIPS {\tt SYSCALL} instructions, which are translated into
+%invocations of the {\tt syscall()} method. This calls back to the
+%native Java world, which can manipulate the binary's environment by
+%reading and writing to its memory space, checking its exit status,
+%pausing the VM, and restarting the VM.
+
+
+%\subsection{Virtualization}
+
+%The {\tt Runtime} class implements the majority of the standard {\tt
+%libc} syscalls, providing a complete interface to the filesystem,
+%network socket library, time of day, (Brian: what else goes here?).
+
+%\begin{itemize}
+
+%\item ability to provide the same interface to CNI code and
+ % NestedVMified code
+
+%\item security advantages (chroot the {\tt fork()}ed process)
+ %
+%\end{itemize}
+
+
+\section{Future Directions}
+
+\section{Conclusion}
+
+\section{Appendix A: Testing Environment}
+
+All times are measured in seconds. These were all run on a dual 1ghz
+G4 running OS X 10.3.1 with Apple's latest VM (JDK 1.4.1\_01-27). Each
+*************
+All times are measured in seconds. These were all run on a dual 1Ghz
+Macintosh G4 running Apple's latest JVM (Sun HotSpot JDK 1.4.1). Each
+^ ^ ^ ^ ^ ^ ^
+test was run 8 times within a single VM. The highest and lowest times
+were removed and the remaining 6 were averaged. In each case only the
+first run differed significantly from the rest.
+
+The libjpeg test consisted of decoding a 1280x1024 jpeg
+(thebride\_1280.jpg) and writing a tga. The mspack test consisted of
+extracting all members from arial32.exe, comic32.exe, times32.exe, and
+verdan32.exe. The freetype test consisted of rendering characters
+32-127 of Comic.TTF at sizes from 8 to 48 incrementing by 4. (That is
+about 950 individual glyphs).
+
+\section{References}
+
+\end{document}
+
--- /dev/null
+%
+% pdftricks.sty
+%
+% Copyright (c) 2001, Radhakrishnan CV <cvr@river-valley.com>
+% Rajagopal CV <cvr3@river-valley.com>
+% http://www.river-valley.com
+%
+% River Valley Technologies, Software Technology Park,
+% Trivandrum, India 695034
+%
+% Tel: +91 471 33 7501/7502
+%
+% Antoine Chambert-Loir
+% <chambert@math.polytechnique.fr>
+% http://www.math.polytechnique.fr/~chambert
+%
+% Ecole polytechnique, Palaiseau Cedex, France
+%
+%
+% This program is free software; you can redistribute it and/or
+% modify it under the terms of the GNU General Public License
+% as published by the Free Software Foundation; either version 2
+% of the License, or (at your option) any later version.
+%
+% This program is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with this program (gpl.txt); if not, write to the Free
+% Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+% MA 02111-1307, USA.
+%
+% $Id: pdftricks.sty,v 1.15 2001/09/30 11:21:23 cvr Exp $
+%
+\NeedsTeXFormat{LaTeX2e}
+\def\Fileversion$#1: #2 ${\gdef\fileversion{#2}}
+\def\Filedate$#1: #2 #3 ${\gdef\filedate{#2}}
+\Fileversion$Revision: 1.15 $
+\Filedate$Date: 2001/09/30 11:21:23 $
+\ProvidesPackage{pdftricks}
+ [\filedate\space\fileversion\space psTricks support in PDF (CVRACL)]
+\PackageWarningNoLine{pdftricks}
+ {****************************************\MessageBreak
+ Package pdftricks v,\fileversion\space loaded\MessageBreak
+ [psTricks support in PDF (CVR, ACL)]\MessageBreak
+ ****************************************}
+\RequirePackage{graphicx,color}
+\newif\if@debug\@debugfalse
+\newif\ifPDFTshell
+\newif\ifPDFTnopdf
+\newif\ifnoprocess \noprocessfalse
+\newif\ifmiktex \miktexfalse
+\DeclareOption{debug}{\@debugtrue}
+\DeclareOption{noshell}{\PDFTshellfalse}
+\DeclareOption{shell}{\PDFTshelltrue}
+\DeclareOption{miktex}{\global\miktextrue}
+\ExecuteOptions{shell}
+\ProcessOptions\relax
+\ifPDFTshell
+% we must set it to false if \write18 doesn't work.
+% Hack given by Thierry Bouche (Thanks !)
+\def\tmpfile{/tmp/w18-test-\the\year\the\month\the\day\the\time}
+\ifmiktex%
+ \immediate\write18{rem >"\tmpfile"}%%%%%% LDL-2
+\else
+ \immediate\write18{touch \tmpfile} %%%%%% LDL-1
+\fi
+\ifmiktex
+ \IfFileExists{\tmpfile.}{\PDFTshelltrue}{\PDFTshellfalse} %%%%%% LDL-4
+\else
+ \IfFileExists{\tmpfile}{\PDFTshelltrue}{\PDFTshellfalse} %%%%%% LDL-3
+\fi
+\fi
+\ifPDFTshell
+ \PackageWarningNoLine{pdftricks}
+ {****************************************\MessageBreak
+ Using \csname write\endcsname18 capability \MessageBreak
+ for producing PDF-figures. \MessageBreak
+ ****************************************}
+\else
+ \PackageWarningNoLine{pdftricks}
+ {****************************************\MessageBreak
+ No \csname write\endcsname18 capability.\MessageBreak
+ You'll have to run a script by yourself!\MessageBreak
+ ****************************************}
+\fi
+
+% warning! the definition of FIGURES if pst2pdf must be set accordingly !!
+\def\PDFTfigname{\jobname-fig\thepsfig}
+\def\PDFTWarning#1#2{\if@debug\PackageWarning{#1}{#2}\fi}
+\def\PDFTWarningNoLine#1#2{\if@debug\PackageWarningNoLine{#1}{#2}\fi}
+\def\makeinnocent#1{\catcode`#1=12 }
+\def\csarg#1#2{\expandafter#1\csname#2\endcsname}
+\def\latexname{lplain}\def\latexename{LaTeX2e}
+\newwrite\PDFStream
+
+\long\def\ProcessStream#1% start it all of
+ {\begingroup%
+ \def\CurrentStream{#1}%
+ \let\do\makeinnocent \dospecials
+ \makeinnocent\^^L% and whatever other special cases
+ \endlinechar`\^^M \catcode`\^^M=12 \xStream}
+{\catcode`\^^M=12 \endlinechar=-1 %
+ \gdef\xStream#1^^M{%
+ \expandafter\ProcessStreamLine}
+ \gdef\ProcessStreamLine#1^^M{\def\test{#1}
+ \csarg\ifx{End\CurrentStream Test}\test
+ \edef\next{\noexpand\EndOfStream{\CurrentStream}}%
+ \else \ThisStream{#1}\let\next\ProcessStreamLine
+ \fi \next}
+}
+\long\def\streaminfo{\string\end{document}}
+\def\CSstringmeaning#1{\expandafter\CSgobblearrow\meaning#1}
+\def\CSstringcsnoescape#1{\expandafter\CSgobbleescape\string#1}
+{\escapechar-1
+\expandafter\expandafter\expandafter\gdef
+ \expandafter\expandafter\expandafter\CSgobblearrow
+ \expandafter\string\csname macro:->\endcsname{}
+}
+\def\CSgobbleescape#1{\ifnum`\\=`#1 \else #1\fi}
+\def\WriteStreamLine#1{\def\CStmp{#1}%
+ \immediate\write\PDFStream{\CSstringmeaning\CStmp}}
+
+\def\AfterIncludedStream
+ {\immediate\closeout\PDFStream %changed on 2001/1/20
+ \relax
+ }%
+\def\BeforeIncludedStream
+ {\stepcounter{psfig}\xdef\PDFCutFile{\PDFTfigname.tex}%
+ \message{Opening PDFStream=\PDFCutFile}%
+ \immediate\openout\PDFStream=\PDFCutFile
+ \immediate\write\PDFStream{\string\documentclass{article}}
+ \immediate\write\PDFStream{\string\input\space tmp.inputs}
+ \immediate\write\PDFStream{\string\pagestyle{empty}}
+ \immediate\write\PDFStream{\string\usepackage{amssymb,amsbsy}}
+ \immediate\write\PDFStream{\string\begin{document}}
+ \let\ThisStream\WriteStreamLine}
+\long\def\specialstream #1#2#3{%
+ \message{Special stream '#1'}%
+ \csarg\def{After#1Stream}{#2\AfterIncludedStream#3}%
+ \csarg\def{#1}{\BeforeIncludedStream\relax
+ \ProcessStream{#1}}%
+ \PDFEndDef{#1}}
+\def\EndOfStream#1{\endgroup\end{#1}%
+ \csname After#1Stream\endcsname}
+\def\PDFEndDef#1{{\escapechar=-1\relax
+ \csarg\xdef{End#1Test}{\string\\end\string\{#1\string\}}%
+ }}
+%%
+%% The real meat of psfile manipulation starts here.
+%%
+%%
+\AtEndDocument{\endPShook%
+ \ifPDFTnopdf
+ \PackageWarningNoLine{pdftricks}
+ {******************************************\MessageBreak
+ Some PDF files of images were not found.\MessageBreak
+ Run the script `pst2pdf' before the next\MessageBreak
+ run of pdfLaTeX\MessageBreak
+ ******************************************}
+ \fi
+}
+\gdef\endPShook{}
+\def\noprocess{\global\noprocesstrue
+ \PackageWarning{pdftricks}
+ {******************************************\MessageBreak
+ Figure Number: \PDFTfigname\space is not processed \MessageBreak
+ ******************************************\MessageBreak}
+}
+\specialstream{pdfpic}{%
+ \immediate\write\PDFStream{\streaminfo}}
+ {\psgraphicsinclude\global\noprocessfalse}
+\newcounter{psfig}
+\newif\if@pdfGINwidth
+\newif\if@pdfGINheight
+\newif\if@pdfGINscale
+\long\gdef\psgraphicsinclude{%
+ \@ifundefined{Fig\thepsfig}
+ {\PDFTWarningNoLine{pdftricks}
+ {******************************************\MessageBreak
+ ************ Processing Fig: \thepsfig\space**********\MessageBreak
+ ******************************************}
+ }
+ {\noprocess}
+ \ifPDFTshell\ifnoprocess\relax\else
+ \IfFileExists{\PDFTfigname.tex}{%
+ \immediate\write18{latex -interaction=batchmode \PDFTfigname}
+ \PDFTWarningNoLine{pdftricks}
+ {******************************************\MessageBreak
+ \PDFTfigname.tex converted to \PDFTfigname.dvi\MessageBreak
+ ******************************************}
+ }{}
+ \IfFileExists{\PDFTfigname.dvi}{%
+ \immediate\write18{dvips -o \PDFTfigname.ps \PDFTfigname}
+ \immediate\write18{ps2eps -f \PDFTfigname.ps}
+ \PDFTWarningNoLine{pdftricks}
+ {******************************************\MessageBreak
+ \PDFTfigname.eps generated\MessageBreak
+ ******************************************}
+ }{}
+ \IfFileExists{\PDFTfigname.eps}{%
+ \immediate\write18{epstopdf \PDFTfigname.eps}
+ \PDFTWarningNoLine{pdftricks}
+ {******************************************\MessageBreak
+ \PDFTfigname.eps converted to \PDFTfigname.pdf\MessageBreak
+ ******************************************}
+ }{}
+ \ifmiktex%
+ \immediate\write18{del \PDFTfigname.aux \PDFTfigname.dvi \PDFTfigname.log \PDFTfigname.eps} %%%%%% LDL-6
+ \else
+ \immediate\write18{rm \PDFTfigname.aux \PDFTfigname.dvi \PDFTfigname.log \PDFTfigname.eps} %%%%%% LDL-5
+ \fi\fi
+ \fi
+ \IfFileExists{\PDFTfigname.pdf}%
+ {\begin{center}
+ \bgroup\fboxsep\@PDFboxsep\fboxrule\@PDFboxrule%
+ \color{\@PDFgraphiccolor}%
+ \fcolorbox{\@PDFgraphiclinecolor}{\@PDFgraphicbackground}%
+ {\if@pdfGINwidth%
+ \includegraphics[width=\@PDFgraphicwidth]{\PDFTfigname}\else%
+ \if@pdfGINheight%
+ \includegraphics[height=\@PDFgraphicheight]{\PDFTfigname}\else%
+ \if@pdfGINscale%
+ \includegraphics[scale=\@PDFgraphicscale]{\PDFTfigname}\else%
+ \includegraphics{\PDFTfigname}\fi\fi\fi%
+ }\egroup\end{center}%
+ \global\@pdfGINwidthfalse\let\@PDFgraphicwidth\relax
+ \global\@pdfGINheightfalse\let\@PDFgraphicheight\relax
+ \global\@pdfGINscalefalse\let\@PDFgraphicscale\relax
+ }{\PDFTnopdftrue}
+ \gdef\@PDFgraphiclinecolor{white}
+ \gdef\@PDFgraphicbackground{white}
+ \gdef\@PDFboxsep{0pt}
+ \gdef\@PDFboxrule{0pt}
+}
+\definecolor{gray30}{gray}{.70}
+\definecolor{gray10}{gray}{.90}
+\RequirePackage{keyval}
+\def\configure[#1][#2]{\setkeys{#1}{#2}
+ \PDFTWarning{pdftricks}{Reconfigured #1 parameter(s)\MessageBreak #2\MessageBreak}
+ }
+\define@key{pdfgraphic}{width} {\gdef\@PDFgraphicwidth{#1}\global\@pdfGINwidthtrue}
+\define@key{pdfgraphic}{height} {\gdef\@PDFgraphicheight{#1}\global\@pdfGINheighttrue}
+\define@key{pdfgraphic}{scale} {\gdef\@PDFgraphicscale{#1}\global\@pdfGINscaletrue}
+\define@key{pdfgraphic}{color} {\gdef\@PDFgraphiccolor{#1}}
+\define@key{pdfgraphic}{linecolor} {\gdef\@PDFgraphiclinecolor{#1}}
+\define@key{pdfgraphic}{background}{\gdef\@PDFgraphicbackground{#1}}
+\define@key{pdfgraphic}{linewidth} {\gdef\@PDFboxrule{#1}}
+\define@key{pdfgraphic}{rulesep} {\gdef\@PDFboxsep{#1}}
+\gdef\@PDFgraphiccolor{black}
+\gdef\@PDFgraphiclinecolor{white}
+\gdef\@PDFgraphicbackground{white}
+\gdef\@PDFboxrule{0pt}
+\gdef\@PDFboxsep{0pt}
+%%
+%% Tweak to grab all the packages used in the master doc.
+%% This forces you to load pdftricks as the first package.
+%%
+\newenvironment{psinputs}{\begingroup
+ \newwrite\CVinputs
+ \immediate\openout\CVinputs=tmp.inputs
+ \def\usepackage{\@ifnextchar[\@CVUsepackage\@@CVUsepackage}
+ \def\@CVUsepackage[##1]##2{\immediate\write\CVinputs%
+ {\string\usepackage[##1]{##2}}}
+ \def\@@CVUsepackage##1{\immediate\write\CVinputs%
+ {\string\usepackage{##1}}}
+ }
+ {\endgroup\immediate\closeout\CVinputs}
+%%
+%% Arrays to keep the fig numbers
+%%
+\newcounter{arraylength}%
+\newcounter{ArrayIndex}%
+\newcounter{zeroCtr}%
+\newcounter{recordCtr}
+\setcounter{recordCtr}{1}
+\newcounter{Ctr}
+\def\DeclareArray#1{\Array{#1}[0]{}}%
+%
+\def\Array#1[#2]#3{%
+ \expandafter\gdef\csname #1#2\endcsname{#3}%
+ \expandafter\gdef\csname #1\endcsname[##1]{\csname #1##1\endcsname}}%
+%
+\def\getArraylength#1{\setcounter{arraylength}{0}%
+ \loop\expandafter\ifx\csname #1\thearraylength\endcsname\relax%
+ \else\stepcounter{arraylength}\repeat}%
+%
+\def\addToArray#1#2{\setcounter{arraylength}{0}%
+ \loop\expandafter\ifx\csname #1\thearraylength\endcsname\relax%
+ \else\stepcounter{arraylength}\repeat%
+ \Array{#1}[\thearraylength]{#2}}%
+%
+\def\clearArray#1{\getArraylength{#1}%
+ \loop\ifnum\c@arraylength >0%
+ \global\expandafter\let\csname #1\thearraylength\endcsname\relax%
+ \addtocounter{arraylength}{-1}\repeat}%
+%
+\long\def\ArrayIterator#1#2{%
+ \setcounter{ArrayIndex}{1}\getArraylength{#1}%
+ \setcounter{zeroCtr}{\c@arraylength}%
+ \loop\ifnum\c@ArrayIndex<\c@zeroCtr{#2}%
+ \stepcounter{ArrayIndex}\repeat%
+}%
+\def\@nnil{\@nil}
+\def\@empty{}
+\def\@cvrstop#1\@@#2{}
+%%
+%% Equivalent of \@tfor and \@for where any delimiter can be
+%% provided instead of LaTeX's default comma character
+%%
+\long\def\cvr@delimfor#1#2#3{\DeclareArray{#1}\clearArray{#1}%
+ \long\def\@icvrloop##1#2##2\@@##3{\def##3{##1}\ifx ##3\@nnil%
+ \expandafter\@cvrstop \else\addToArray{#1}{##1}%
+ \relax\expandafter\@icvrloop\fi##2\@@##3}%
+ \long\def\@cvrloop##1#2##2#2##3\@@##4{\addToArray{#1}{##1}%
+ \def##4{##1}\ifx ##4\@nnil \else%
+ \def##4{##2}\def\y@y{##2}\ifx\y@y\@nnil\else%
+ \addToArray{#1}{##2}\fi\ifx ##4\@nnil \else%
+ \@icvrloop ##3\@@##4\fi\fi}%
+ \expandafter\def\expandafter\@fortmp\expandafter{#3}%
+ \ifx\@fortmp\@empty \else%
+ \expandafter\@cvrloop#3#2\@nil#2\@nil\@@\@ee@\fi}%
+%
+% Dont look into the following code. It is harmful
+% for your eyes and brain as well.
+%
+\newcounter{f@irstCtr}
+\newcounter{s@econdCtr}
+\long\gdef\NoProcess[#1]{%
+ \long\def\@i@@noprocess##1,##2\@@##3{\def##3{##1}\ifx ##3\@nnil%
+ \expandafter\@cvrstop \else
+ \expandafter\hyphencheck##1-@-*[*]
+ \relax\expandafter\@i@@noprocess\fi##2\@@##3}%
+ \long\def\@@@noprocess##1,##2,##3\@@##4{
+ \expandafter\hyphencheck##1-@-*[*]
+ \def##4{##1}\ifx ##4\@nnil \else%
+ \def##4{##2}\def\y@y{##2}\ifx\y@y\@nnil\else%
+ \expandafter\hyphencheck##2-@-*[*]
+ \fi\ifx ##4\@nnil \else%
+ \@i@@noprocess ##3\@@##4\fi\fi}%
+ \expandafter\def\expandafter\@fortmp\expandafter{#1}%
+ \ifx\@fortmp\@empty \else%
+ \expandafter\@@@noprocess#1,\@nil,\@nil\@@\@ee@\fi}%
+\def\d@d#1[*]{}
+\def\hyphencheck#1-#2-#3{\def\r@r{@}\def\s@s{*}\edef\c@c{#3}
+ \ifx\c@c\r@r
+ \setcounter{f@irstCtr}{#1}
+ \setcounter{s@econdCtr}{#2}
+ \stepcounter{s@econdCtr}
+ \loop\ifnum\thes@econdCtr > \thef@irstCtr%
+ \expandafter\edef\csname Fig\thef@irstCtr\endcsname{TRUE}
+ \stepcounter{f@irstCtr}
+ \repeat%
+ \else\ifx\c@c\s@s%
+ \expandafter\edef\csname Fig#1\endcsname{TRUE}
+ \fi\fi\d@d}
+
+%%
+%%
+%% End of file `pdftricks.sty'
+%%
--- /dev/null
+#! /bin/bash
+# pst2pdf
+# PSTricks 2 PDF converter :
+# Usage: "pst2pdf" produces PDF files for all files of the form *-fig*.tex
+# "pst2pdf <FILE>" only considers FILE-fig.tex
+# It removes intermediary files at the end.
+
+FILE=$1
+if test -z $FILE; then
+ FIGURES=`ls *-fig*.tex`;
+else
+ FIGURES=`ls -- $FILE-fig*.tex`;
+fi
+
+for f in $FIGURES ; do
+ fig=`basename $f .tex`
+ latex $fig
+ dvips -Ppdf -E -o $fig.eps $fig
+ epstopdf $fig.eps
+ rm $fig.eps $fig.dvi $fig.log $fig.aux
+done
+
--- /dev/null
+\usepackage{pstricks}
+\usepackage{pst-node}
--- /dev/null
+package org.xwt.mips;
+
+import java.io.*;
+import org.xwt.mips.util.*;
+
+import org.apache.bcel.generic.*;
+
+// FEATURE: Use BCEL to do peephole optimization
+// FEATURE: Special mode to support single-precision only - regs are floats not ints
+
+/* FEATURE: Span large binaries across several classfiles
+ * We should be able to do this with no performance penalty
+ * Every method in the inner classes is static and takes the main class as an arg
+ * This makes them look just like methods in the main class because arg1 gets loaded into
+ * local register 0
+ */
+
+/* FEATURE: smarter with local regs
+ * Be even smarter with the use of local registers. We need to only load fields into
+ * local regs when they are actually used and only write to fields if the regs could have
+ * changed. This should allow us to put more regs in local vars. Right now putting all used
+ * regs local vars makes code like this slower.
+ *
+ * void work(int a, int b) {
+ * if(a == b) {
+ * fast path
+ * return;
+ * }
+ * real work
+ * }
+ * Because all the regs used in "real work" are loaded/restored even for fast path
+ */
+
+
+public class ClassFileCompiler extends Compiler implements org.apache.bcel.Constants {
+ /** The stream to write the compiled output to */
+ private OutputStream os;
+ private PrintStream warn = System.err;
+
+ private ClassGen cl;
+ private ConstantPoolGen cp;
+ private InstructionList clinitExtras = new InstructionList();
+ private InstructionList initExtras = new InstructionList();
+ private InstructionFactory fac;
+
+ // Handy wrappers around the BCEL functions
+ private InstructionList insnList;
+ private void selectMethod(MethodGen m) { insnList = m.getInstructionList(); }
+ private void selectList(InstructionList l) { insnList = l; }
+ private InstructionHandle a(Instruction i) { return insnList.append(i); }
+ private BranchHandle a(BranchInstruction i) { return insnList.append(i); }
+ private InstructionHandle a(InstructionList l) { return insnList.append(l); }
+ private InstructionHandle a(CompoundInstruction c) { return insnList.append(c); }
+
+ // This works around a bug in InstructionList
+ // FEATURE: fix this in bcel, send them a patch, etc
+ private static class FixedInstructionList extends InstructionList {
+ public void move(InstructionHandle start, InstructionHandle end, InstructionHandle target) {
+ InstructionHandle extra = target != null && target == getEnd() ? append(InstructionConstants.NOP) : null;
+ super.move(start,end,target);
+ if(extra != null) try { delete(extra); } catch (TargetLostException e) { /* won't happen */ }
+ }
+ }
+
+ private MethodGen newMethod(int flags, Type ret, Type[] args, String name) {
+ return new MethodGen(flags,ret,args,null,name,fullClassName,new FixedInstructionList(),cp);
+ }
+
+ public ClassFileCompiler(String path, String className, OutputStream os) throws IOException { this(new SeekableFile(path),className,os); }
+ public ClassFileCompiler(SeekableData binary, String className, OutputStream os) throws IOException {
+ super(binary,className);
+ this.os = os;
+ }
+
+ public void setWarnWriter(PrintStream warn) { this.warn = warn; }
+
+ protected void _go() throws Exn, IOException {
+ if(lessConstants) throw new Exn("ClassFileCompiler doesn't support -o lessconstants");
+ if(!pruneCases) throw new Exn("-o prunecases MUST be enabled for ClassFileCompiler");
+
+ // Class
+ cl = new ClassGen(fullClassName,runtimeClass,source,ACC_SUPER|ACC_PUBLIC,null);
+ cp = cl.getConstantPool();
+ fac = new InstructionFactory(cl,cp);
+
+ // Fields
+ cl.addField(new FieldGen(ACC_PRIVATE,Type.INT,"pc",cp).getField());
+ for(int i=1;i<32;i++)
+ cl.addField(new FieldGen(ACC_PRIVATE,Type.INT,"r"+i,cp).getField());
+ for(int i=0;i<32;i++)
+ cl.addField(new FieldGen(ACC_PRIVATE,Type.INT,"f"+i,cp).getField());
+
+ cl.addField(new FieldGen(ACC_PRIVATE,Type.INT,"hi",cp).getField());
+ cl.addField(new FieldGen(ACC_PRIVATE,Type.INT,"lo",cp).getField());
+ cl.addField(new FieldGen(ACC_PRIVATE,Type.INT,"fcsr",cp).getField());
+
+ if(onePage) {
+ cl.addField(new FieldGen(ACC_PRIVATE|ACC_FINAL,new ArrayType(Type.INT,1),"page",cp).getField());
+
+ selectList(initExtras);
+ a(InstructionConstants.ALOAD_0);
+ a(InstructionConstants.DUP);
+ a(fac.createFieldAccess(fullClassName,"readPages",new ArrayType(Type.INT, 2), GETFIELD));
+ pushConst(0);
+ a(InstructionConstants.AALOAD);
+ a(fac.createFieldAccess(fullClassName,"page",new ArrayType(Type.INT,1), PUTFIELD));
+ }
+
+ if(supportCall)
+ cl.addField(new FieldGen(ACC_PRIVATE|ACC_STATIC|ACC_FINAL,Type.getType("L"+hashClass.replace('.','/')+";"),"symbols",cp).getField());
+
+ int highestAddr = 0;
+
+ for(int i=0;i<elf.sheaders.length;i++) {
+ ELF.SHeader sheader = elf.sheaders[i];
+ String name = sheader.name;
+ // if this section doesn't get loaded into our address space don't worry about it
+ if(sheader.addr == 0x0) continue;
+
+ highestAddr = Math.max(highestAddr, sheader.addr + sheader.size);
+
+ if(name.equals(".text"))
+ emitText(sheader.addr, new DataInputStream(sheader.getInputStream()),sheader.size);
+ else if(name.equals(".data") || name.equals(".sdata") || name.equals(".rodata") || name.equals(".ctors") || name.equals(".dtors"))
+ emitData(sheader.addr, new DataInputStream(sheader.getInputStream()), sheader.size,name.equals(".rodata"));
+ else if(name.equals(".bss") || name.equals(".sbss"))
+ emitBSS(sheader.addr,sheader.size);
+ else
+ throw new Exn("Unknown segment: " + name);
+ }
+
+ ELF.SHeader text = elf.sectionWithName(".text");
+
+ // Trampoline
+ MethodGen tramp = newMethod(ACC_PRIVATE,Type.VOID, Type.NO_ARGS, "trampoline");
+ tramp.addException("org.xwt.mips.Runtime$ExecutionException");
+ selectMethod(tramp);
+
+ InstructionHandle start = a(InstructionConstants.ALOAD_0);
+ a(fac.createFieldAccess(fullClassName,"state",Type.INT, GETFIELD));
+ pushConst(Runtime.RUNNING);
+ BranchInstruction stateCheck = InstructionFactory.createBranchInstruction(IF_ICMPNE,null);
+ a(stateCheck);
+ a(InstructionConstants.ALOAD_0);
+ a(InstructionConstants.ALOAD_0);
+ a(fac.createFieldAccess(fullClassName,"pc",Type.INT, GETFIELD));
+ pushConst(methodShift);
+ a(InstructionConstants.IUSHR);
+
+ int beg = text.addr >>> methodShift;
+ int end = ((text.addr + text.size) >>> methodShift);
+
+ // This data is redundant but BCEL wants it
+ int[] matches = new int[end-beg];
+ for(int i=beg;i<end;i++) matches[i-beg] = i;
+ TABLESWITCH ts = new TABLESWITCH(matches,new InstructionHandle[matches.length],null);
+ a(ts);
+ for(int n=beg;n<end;n++){
+ InstructionHandle h = a(fac.createInvoke(fullClassName,"run_"+toHex(n<<methodShift),Type.VOID,Type.NO_ARGS,INVOKESPECIAL));
+ a(InstructionFactory.createBranchInstruction(GOTO,start));
+ ts.setTarget(n-beg,h);
+ }
+
+ ts.setTarget(a(InstructionConstants.POP)); // default case
+ a(fac.createNew("org.xwt.mips.Runtime$ExecutionException"));
+ a(InstructionConstants.DUP);
+ a(fac.createNew("java.lang.StringBuffer"));
+ a(InstructionConstants.DUP);
+ a(new PUSH(cp,"Jumped to invalid address in trampoline (r2: "));
+ a(fac.createInvoke("java.lang.StringBuffer","<init>",Type.VOID,new Type[]{Type.STRING},INVOKESPECIAL));
+ a(InstructionConstants.ALOAD_0);
+ a(fac.createFieldAccess(fullClassName,"r2",Type.INT, GETFIELD));
+ a(fac.createInvoke("java.lang.StringBuffer","append",Type.STRINGBUFFER,new Type[]{Type.INT},INVOKEVIRTUAL));
+ a(new PUSH(cp," pc:"));
+ a(fac.createInvoke("java.lang.StringBuffer","append",Type.STRINGBUFFER,new Type[]{Type.STRING},INVOKEVIRTUAL));
+ a(InstructionConstants.ALOAD_0);
+ a(fac.createFieldAccess(fullClassName,"pc",Type.INT, GETFIELD));
+ a(fac.createInvoke("java.lang.StringBuffer","append",Type.STRINGBUFFER,new Type[]{Type.INT},INVOKEVIRTUAL));
+ a(new PUSH(cp,')'));
+ a(fac.createInvoke("java.lang.StringBuffer","append",Type.STRINGBUFFER,new Type[]{Type.CHAR},INVOKEVIRTUAL));
+ a(fac.createInvoke("java.lang.StringBuffer","toString",Type.STRING,Type.NO_ARGS,INVOKEVIRTUAL));
+ a(fac.createInvoke("org.xwt.mips.Runtime$ExecutionException","<init>",Type.VOID,new Type[]{Type.STRING},INVOKESPECIAL));
+ a(InstructionConstants.ATHROW);
+
+ stateCheck.setTarget(a(InstructionConstants.RETURN));
+
+ tramp.setMaxStack();
+ tramp.setMaxLocals();
+ try {
+ cl.addMethod(tramp.getMethod());
+ } catch(ClassGenException e) {
+ e.printStackTrace(warn);
+ throw new Exn("Generation of the trampoline method failed. Try increasing maxInsnPerMethod");
+ }
+
+ MethodGen init = newMethod(ACC_PUBLIC,Type.VOID, Type.NO_ARGS, "<init>");
+ selectMethod(init);
+ // Constructor
+ a(InstructionConstants.ALOAD_0);
+ pushConst(pageSize);
+ pushConst(totalPages);
+ pushConst(fastMem ? 0 : 1);
+ a(fac.createInvoke(runtimeClass,"<init>",Type.VOID,new Type[]{Type.INT,Type.INT,Type.BOOLEAN},INVOKESPECIAL));
+ a(InstructionConstants.ALOAD_0);
+ pushConst(gp.addr);
+ a(fac.createFieldAccess(fullClassName,"gp",Type.INT, PUTFIELD));
+
+ a(InstructionConstants.ALOAD_0);
+ pushConst(elf.header.entry);
+ a(fac.createFieldAccess(fullClassName,"entryPoint",Type.INT, PUTFIELD));
+
+ a(InstructionConstants.ALOAD_0);
+ pushConst(onePage ? ((highestAddr+4095)&~4095) : ((highestAddr+pageSize-1)&~(pageSize-1)));
+ a(fac.createFieldAccess(fullClassName,"brkAddr",Type.INT, PUTFIELD));
+
+ if(userInfo != null) {
+ a(InstructionConstants.ALOAD_0);
+ pushConst(userInfo.addr);
+ a(fac.createFieldAccess(fullClassName,"userInfoBase",Type.INT, PUTFIELD));
+ a(InstructionConstants.ALOAD_0);
+ pushConst(userInfo.size);
+ a(fac.createFieldAccess(fullClassName,"userInfoSize",Type.INT, PUTFIELD));
+ }
+ a(initExtras);
+ a(InstructionConstants.ALOAD_0);
+ pushConst(Runtime.INITIALIZED);
+ a(fac.createFieldAccess(fullClassName,"state",Type.INT, PUTFIELD));
+ a(InstructionConstants.RETURN);
+ init.setMaxLocals();
+ init.setMaxStack();
+ cl.addMethod(init.getMethod());
+
+ MethodGen clinit = newMethod(ACC_PRIVATE|ACC_STATIC,Type.VOID, Type.NO_ARGS, "<clinit>");
+ selectMethod(clinit);
+ a(clinitExtras);
+
+ if(supportCall) {
+ a(fac.createNew(hashClass));
+ a(InstructionConstants.DUP);
+ a(InstructionConstants.DUP);
+ a(fac.createInvoke(hashClass,"<init>",Type.VOID,Type.NO_ARGS,INVOKESPECIAL));
+ a(fac.createFieldAccess(fullClassName,"symbols",Type.getType("L"+hashClass.replace('.','/')+";"), PUTSTATIC));
+ ELF.Symbol[] symbols = elf.getSymtab().symbols;
+ for(int i=0;i<symbols.length;i++) {
+ ELF.Symbol s = symbols[i];
+ if(s.type == ELF.Symbol.STT_FUNC && s.binding == ELF.Symbol.STB_GLOBAL && (s.name.equals("_call_helper") || !s.name.startsWith("_"))) {
+ a(InstructionConstants.DUP);
+ a(new PUSH(cp,s.name));
+ a(fac.createNew("java.lang.Integer"));
+ a(InstructionConstants.DUP);
+ a(new PUSH(cp,s.addr));
+ a(fac.createInvoke("java.lang.Integer","<init>",Type.VOID,new Type[]{Type.INT},INVOKESPECIAL));
+ a(fac.createInvoke(hashClass,"put",Type.OBJECT,new Type[]{Type.OBJECT,Type.OBJECT},INVOKEVIRTUAL));
+ a(InstructionConstants.POP);
+ }
+ }
+ a(InstructionConstants.POP);
+ }
+
+ a(InstructionConstants.RETURN);
+ clinit.setMaxLocals();
+ clinit.setMaxStack();
+ cl.addMethod(clinit.getMethod());
+
+ if(supportCall) {
+ MethodGen lookupSymbol = newMethod(ACC_PROTECTED,Type.INT,new Type[]{Type.STRING},"lookupSymbol");
+ selectMethod(lookupSymbol);
+ a(fac.createFieldAccess(fullClassName,"symbols",Type.getType("L"+hashClass.replace('.','/')+";"), GETSTATIC));
+ a(InstructionConstants.ALOAD_1);
+ a(fac.createInvoke(hashClass,"get",Type.OBJECT,new Type[]{Type.OBJECT},INVOKEVIRTUAL));
+ a(InstructionConstants.DUP);
+ BranchHandle bh = a(InstructionFactory.createBranchInstruction(IFNULL,null));
+ a(fac.createCheckCast(new ObjectType("java.lang.Integer")));
+ a(fac.createInvoke("java.lang.Integer","intValue",Type.INT,Type.NO_ARGS,INVOKEVIRTUAL));
+ a(InstructionConstants.IRETURN);
+ bh.setTarget(a(InstructionConstants.ICONST_M1));
+ a(InstructionConstants.IRETURN);
+ lookupSymbol.setMaxLocals();
+ lookupSymbol.setMaxStack();
+ cl.addMethod(lookupSymbol.getMethod());
+ }
+
+ MethodGen setCPUState = newMethod(ACC_PROTECTED,Type.VOID,new Type[]{Type.getType("Lorg/xwt/mips/Runtime$CPUState;")},"setCPUState");
+ selectMethod(setCPUState);
+ a(InstructionConstants.ALOAD_1);
+ a(fac.createFieldAccess("org.xwt.mips.Runtime$CPUState","r",new ArrayType(Type.INT,1),GETFIELD));
+ a(InstructionConstants.ASTORE_2);
+ for(int i=1;i<32;i++) {
+ a(InstructionConstants.ALOAD_0);
+ a(InstructionConstants.ALOAD_2);
+ pushConst(i);
+ a(InstructionConstants.IALOAD);
+ a(fac.createFieldAccess(fullClassName,"r"+i,Type.INT, PUTFIELD));
+ }
+ a(InstructionConstants.ALOAD_1);
+ a(fac.createFieldAccess("org.xwt.mips.Runtime$CPUState","f",new ArrayType(Type.INT,1),GETFIELD));
+ a(InstructionConstants.ASTORE_2);
+ for(int i=0;i<32;i++) {
+ a(InstructionConstants.ALOAD_0);
+ a(InstructionConstants.ALOAD_2);
+ pushConst(i);
+ a(InstructionConstants.IALOAD);
+ a(fac.createFieldAccess(fullClassName,"f"+i,Type.INT, PUTFIELD));
+ }
+ a(InstructionConstants.ALOAD_0);
+ a(InstructionConstants.ALOAD_1);
+ a(fac.createFieldAccess("org.xwt.mips.Runtime$CPUState","hi",Type.INT,GETFIELD));
+ a(fac.createFieldAccess(fullClassName,"hi",Type.INT, PUTFIELD));
+ a(InstructionConstants.ALOAD_0);
+ a(InstructionConstants.ALOAD_1);
+ a(fac.createFieldAccess("org.xwt.mips.Runtime$CPUState","lo",Type.INT,GETFIELD));
+ a(fac.createFieldAccess(fullClassName,"lo",Type.INT, PUTFIELD));
+ a(InstructionConstants.ALOAD_0);
+ a(InstructionConstants.ALOAD_1);
+ a(fac.createFieldAccess("org.xwt.mips.Runtime$CPUState","fcsr",Type.INT,GETFIELD));
+ a(fac.createFieldAccess(fullClassName,"fcsr",Type.INT, PUTFIELD));
+ a(InstructionConstants.ALOAD_0);
+ a(InstructionConstants.ALOAD_1);
+ a(fac.createFieldAccess("org.xwt.mips.Runtime$CPUState","pc",Type.INT,GETFIELD));
+ a(fac.createFieldAccess(fullClassName,"pc",Type.INT, PUTFIELD));
+ a(InstructionConstants.RETURN);
+ setCPUState.setMaxLocals();
+ setCPUState.setMaxStack();
+ cl.addMethod(setCPUState.getMethod());
+
+ MethodGen getCPUState = newMethod(ACC_PROTECTED,Type.getType("Lorg/xwt/mips/Runtime$CPUState;"),Type.NO_ARGS,"getCPUState");
+ selectMethod(getCPUState);
+ a(fac.createNew("org.xwt.mips.Runtime$CPUState"));
+ a(InstructionConstants.DUP);
+ a(fac.createInvoke("org.xwt.mips.Runtime$CPUState","<init>",Type.VOID,Type.NO_ARGS,INVOKESPECIAL));
+ a(InstructionConstants.ASTORE_1);
+
+ a(InstructionConstants.ALOAD_1);
+ a(fac.createFieldAccess("org.xwt.mips.Runtime$CPUState","r",new ArrayType(Type.INT,1),GETFIELD));
+ a(InstructionConstants.ASTORE_2);
+ for(int i=1;i<32;i++) {
+ a(InstructionConstants.ALOAD_2);
+ pushConst(i);
+ a(InstructionConstants.ALOAD_0);
+ a(fac.createFieldAccess(fullClassName,"r"+i,Type.INT, GETFIELD));
+ a(InstructionConstants.IASTORE);
+ }
+
+ a(InstructionConstants.ALOAD_1);
+ a(fac.createFieldAccess("org.xwt.mips.Runtime$CPUState","f",new ArrayType(Type.INT,1),GETFIELD));
+ a(InstructionConstants.ASTORE_2);
+ for(int i=0;i<32;i++) {
+ a(InstructionConstants.ALOAD_2);
+ pushConst(i);
+ a(InstructionConstants.ALOAD_0);
+ a(fac.createFieldAccess(fullClassName,"f"+i,Type.INT, GETFIELD));
+ a(InstructionConstants.IASTORE);
+ }
+ a(InstructionConstants.ALOAD_1);
+ a(InstructionConstants.ALOAD_0);
+ a(fac.createFieldAccess(fullClassName,"hi",Type.INT, GETFIELD));
+ a(fac.createFieldAccess("org.xwt.mips.Runtime$CPUState","hi",Type.INT,PUTFIELD));
+ a(InstructionConstants.ALOAD_1);
+ a(InstructionConstants.ALOAD_0);
+ a(fac.createFieldAccess(fullClassName,"lo",Type.INT, GETFIELD));
+ a(fac.createFieldAccess("org.xwt.mips.Runtime$CPUState","lo",Type.INT,PUTFIELD));
+ a(InstructionConstants.ALOAD_1);
+ a(InstructionConstants.ALOAD_0);
+ a(fac.createFieldAccess(fullClassName,"fcsr",Type.INT, GETFIELD));
+ a(fac.createFieldAccess("org.xwt.mips.Runtime$CPUState","fcsr",Type.INT,PUTFIELD));
+ a(InstructionConstants.ALOAD_1);
+ a(InstructionConstants.ALOAD_0);
+ a(fac.createFieldAccess(fullClassName,"pc",Type.INT, GETFIELD));
+ a(fac.createFieldAccess("org.xwt.mips.Runtime$CPUState","pc",Type.INT,PUTFIELD));
+
+ a(InstructionConstants.ALOAD_1);
+ a(InstructionConstants.ARETURN);
+ getCPUState.setMaxLocals();
+ getCPUState.setMaxStack();
+ cl.addMethod(getCPUState.getMethod());
+
+
+ MethodGen execute = newMethod(ACC_PROTECTED,Type.VOID,Type.NO_ARGS,"_execute");
+ selectMethod(execute);
+ a(InstructionConstants.ALOAD_0);
+ a(fac.createInvoke(fullClassName,"trampoline",Type.VOID,Type.NO_ARGS,INVOKESPECIAL));
+ a(InstructionConstants.RETURN);
+ execute.setMaxLocals();
+ execute.setMaxStack();
+ cl.addMethod(execute.getMethod());
+
+
+ MethodGen main = newMethod(ACC_STATIC|ACC_PUBLIC,Type.VOID,new Type[]{new ArrayType(Type.STRING,1)},"main");
+ selectMethod(main);
+ a(fac.createNew(fullClassName));
+ a(InstructionConstants.DUP);
+ a(fac.createInvoke(fullClassName,"<init>",Type.VOID,Type.NO_ARGS,INVOKESPECIAL));
+ a(new PUSH(cp,fullClassName));
+ a(InstructionConstants.ALOAD_0);
+ a(fac.createInvoke(fullClassName,"run",Type.INT,new Type[]{Type.STRING,new ArrayType(Type.STRING,1)},INVOKEVIRTUAL));
+ a(fac.createInvoke("java.lang.System","exit",Type.VOID,new Type[]{Type.INT},INVOKESTATIC));
+ a(InstructionConstants.RETURN);
+ main.setMaxLocals();
+ main.setMaxStack();
+ cl.addMethod(main.getMethod());
+
+ cl.getJavaClass().dump(os);
+ }
+
+ private static int initDataCount;
+ private void emitData(int addr, DataInputStream dis, int size, boolean readOnly) throws Exn,IOException {
+ if((addr&3)!=0 || (size&3)!=0) throw new Exn("Data section on weird boundaries");
+ int last = addr + size;
+ while(addr < last) {
+ int segSize = Math.min(size,28000); // must be a multiple of 56
+ StringBuffer sb = new StringBuffer();
+ for(int i=0;i<segSize;i+=7) {
+ long l = 0;
+ for(int j=0;j<7;j++) {
+ l <<= 8;
+ byte b = (i+j < size) ? dis.readByte() : 1;
+ l |= (b & 0xffL);
+ }
+ for(int j=0;j<8;j++)
+ sb.append((char) ((l>>>(7*(7-j)))&0x7f));
+ }
+ String fieldname = "_data" + (++initDataCount);
+ cl.addField(new FieldGen(ACC_PRIVATE|ACC_STATIC|ACC_FINAL,new ArrayType(Type.INT,1),fieldname,cp).getField());
+
+ selectList(clinitExtras);
+ a(new PUSH(cp,sb.toString()));
+ a(new PUSH(cp,segSize/4));
+ a(fac.createInvoke("org.xwt.mips.Runtime","decodeData",new ArrayType(Type.INT,1),new Type[]{Type.STRING,Type.INT},INVOKESTATIC));
+ a(fac.createPutStatic(fullClassName,fieldname,new ArrayType(Type.INT,1)));
+
+ selectList(initExtras);
+ a(InstructionConstants.ALOAD_0);
+ a(fac.createGetStatic(fullClassName,fieldname,new ArrayType(Type.INT,1)));
+ a(new PUSH(cp,addr));
+ a(new PUSH(cp,readOnly));
+ a(fac.createInvoke(fullClassName,"initPages",Type.VOID,new Type[]{new ArrayType(Type.INT,1),Type.INT,Type.BOOLEAN},INVOKEVIRTUAL));
+
+ addr += segSize;
+ size -= segSize;
+ }
+ dis.close();
+ }
+
+ private void emitBSS(int addr, int size) throws Exn {
+ if((addr&3)!=0) throw new Exn("BSS section on weird boundaries");
+ size = (size+3)&~3;
+ int count = size/4;
+ selectList(initExtras);
+ a(InstructionConstants.ALOAD_0);
+ a(new PUSH(cp,addr));
+ a(new PUSH(cp,count));
+ a(fac.createInvoke(fullClassName,"clearPages",Type.VOID,new Type[]{Type.INT,Type.INT},INVOKEVIRTUAL));
+ }
+
+ // method state info
+ private boolean textDone;
+ private int startOfMethod = 0;
+ private int endOfMethod = 0;
+ private boolean unreachable = false;
+ private InstructionHandle[] jumpHandles;
+ private InstructionHandle defaultHandle;
+ private InstructionHandle returnHandle;
+ private InstructionHandle realStart;
+ private MethodGen curMethod;
+
+ private boolean jumpable(int addr) { return jumpableAddresses.contains(new Integer(addr)); }
+
+ private void emitText(int addr, DataInputStream dis, int size) throws Exn,IOException {
+ if(textDone) throw new Exn("Multiple text segments");
+ textDone = true;
+
+ if((addr&3)!=0 || (size&3)!=0) throw new Exn("Section on weird boundaries");
+ int count = size/4;
+ int insn,nextInsn=-1;
+ boolean skipNext = true;
+
+ for(int i=0;i<count;i++,addr+=4) {
+ insn = skipNext ? dis.readInt() : nextInsn;
+ nextInsn = (i == count-1) ? -1 : dis.readInt();
+ if(addr >= endOfMethod) { endMethod(addr); startMethod(addr); }
+ if(jumpHandles[(addr-startOfMethod)/4] != null) {
+ // Move the fake jump target to the current location
+ insnList.move(jumpHandles[(addr-startOfMethod)/4],insnList.getEnd());
+ unreachable = false;
+ } else if(unreachable) {
+ continue;
+ }
+ try {
+ skipNext = emitInstruction(addr,insn,nextInsn);
+ } catch(RuntimeException e) {
+ warn.println("Exception at " + toHex(addr));
+ throw e;
+ }
+ if(skipNext) { addr+=4; i++; }
+ }
+ endMethod(0);
+ dis.close();
+ }
+
+ private void startMethod(int first) {
+ startOfMethod = first & methodMask;
+ endOfMethod = startOfMethod + maxBytesPerMethod;
+ curMethod = newMethod(ACC_PRIVATE,Type.VOID,Type.NO_ARGS,"run_" + toHex(startOfMethod));
+ selectMethod(curMethod);
+
+ int[] buf = new int[maxBytesPerMethod/4];
+ jumpHandles = new InstructionHandle[maxBytesPerMethod/4];
+ int n=0;
+ for(int addr=first;addr<endOfMethod;addr+=4) {
+ if(jumpable(addr)) {
+ buf[n++] = addr;
+ // append NOPs for GOTO jumps (these will be moved to the correct location later)
+ jumpHandles[(addr-startOfMethod)/4] = a(InstructionConstants.NOP);
+ }
+ }
+
+ // append NOP for default case (throw exn) (this will be moved later)
+ defaultHandle = a(InstructionConstants.NOP);
+ returnHandle = a(InstructionConstants.NOP);
+
+ int[] matches = new int[n];
+ System.arraycopy(buf,0,matches,0,n);
+ InstructionHandle[] targets = new InstructionHandle[n];
+ for(int i=0;i<matches.length;i++)
+ targets[i] = jumpHandles[(matches[i]-startOfMethod)/4];
+
+
+ // First instruction of the actual method - everything above this should be removed
+ // before we get to the end
+ realStart = a(InstructionConstants.NOP);
+
+ if(onePage) {
+ a(InstructionConstants.ALOAD_0);
+ a(fac.createFieldAccess(fullClassName,"page",new ArrayType(Type.INT,1), GETFIELD));
+ a(InstructionConstants.ASTORE_2);
+ } else {
+ a(InstructionConstants.ALOAD_0);
+ a(fac.createFieldAccess(fullClassName,"readPages",new ArrayType(Type.INT,2), GETFIELD));
+ a(InstructionConstants.ASTORE_2);
+ a(InstructionConstants.ALOAD_0);
+ a(fac.createFieldAccess(fullClassName,"writePages",new ArrayType(Type.INT,2), GETFIELD));
+ a(InstructionFactory.createStore(Type.OBJECT,3));
+ }
+
+ LOOKUPSWITCH initialSwitch = new LOOKUPSWITCH(matches,targets,defaultHandle);
+ a(InstructionConstants.ALOAD_0);
+ a(fac.createFieldAccess(fullClassName,"pc",Type.INT, GETFIELD));
+ a(initialSwitch);
+ }
+
+ private void endMethod(int firstAddrOfNext) {
+ if(startOfMethod == 0) return;
+
+ if(!unreachable) {
+ preSetPC();
+ pushConst(firstAddrOfNext);
+ setPC();
+ // mark the start of the next method as jumpable
+ jumpableAddresses.add(new Integer(firstAddrOfNext));
+ }
+
+ insnList.move(returnHandle,insnList.getEnd());
+ fixupRegs();
+ a(InstructionConstants.RETURN);
+
+ // move the default jump target (lookupswitch) to before the throw
+ insnList.move(defaultHandle,insnList.getEnd());
+ if(debugCompiler) {
+ a(fac.createNew("org.xwt.mips.Runtime$ExecutionException"));
+ a(InstructionConstants.DUP);
+ a(fac.createNew("java.lang.StringBuffer"));
+ a(InstructionConstants.DUP);
+ a(new PUSH(cp,"Jumped to invalid address: "));
+ a(fac.createInvoke("java.lang.StringBuffer","<init>",Type.VOID,new Type[]{Type.STRING},INVOKESPECIAL));
+ a(InstructionConstants.ALOAD_0);
+ a(fac.createFieldAccess(fullClassName,"pc",Type.INT, GETFIELD));
+ a(fac.createInvoke("java.lang.StringBuffer","append",Type.STRINGBUFFER,new Type[]{Type.INT},INVOKEVIRTUAL));
+ a(fac.createInvoke("java.lang.StringBuffer","toString",Type.STRING,Type.NO_ARGS,INVOKEVIRTUAL));
+ a(fac.createInvoke("org.xwt.mips.Runtime$ExecutionException","<init>",Type.VOID,new Type[]{Type.STRING},INVOKESPECIAL));
+ a(InstructionConstants.ATHROW);
+ } else {
+ a(fac.createNew("org.xwt.mips.Runtime$ExecutionException"));
+ a(InstructionConstants.DUP);
+ a(new PUSH(cp,"Jumped to invalid address"));
+ a(fac.createInvoke("org.xwt.mips.Runtime$ExecutionException","<init>",Type.VOID,new Type[]{Type.STRING},INVOKESPECIAL));
+ a(InstructionConstants.ATHROW);
+ }
+
+ if(insnList.getStart() != realStart) {
+ System.err.println(insnList);
+ throw new Error("A jumpHandle wasn't moved into place");
+ }
+
+ curMethod.removeNOPs();
+ curMethod.setMaxLocals();
+ curMethod.setMaxStack();
+
+ cl.addMethod(curMethod.getMethod());
+
+ endOfMethod = startOfMethod = 0;
+ }
+
+
+ private void leaveMethod() {
+ a(InstructionFactory.createBranchInstruction(GOTO,returnHandle));
+ }
+
+ private void branch(int pc, int target) {
+ if((pc&methodMask) == (target&methodMask)) {
+ a(InstructionFactory.createBranchInstruction(GOTO,jumpHandles[(target-startOfMethod)/4]));
+ } else {
+ preSetPC();
+ pushConst(target);
+ setPC();
+ leaveMethod();
+ }
+ }
+
+ // This assumes everything needed by ifInsn is already on the stack
+ private boolean doIfInstruction(short op, int pc, int target, int nextInsn) throws Exn {
+ emitInstruction(-1,nextInsn,-1); // delay slot
+ BranchHandle h;
+ IfInstruction ifInsn = (IfInstruction) InstructionFactory.createBranchInstruction(op,null);
+ if((target&methodMask) == (pc&methodMask)) {
+ h = a(ifInsn);
+ h.setTarget(jumpHandles[(target-startOfMethod)/4]);
+ } else {
+ h = a(ifInsn.negate());
+ branch(pc,target);
+ h.setTarget(a(InstructionConstants.NOP));
+ }
+ if(!jumpable(pc+4)) return true; // done - skip it
+
+ //System.err.println("Delay slot is jumpable - This code is untested + " + toHex(nextInsn));
+ if(pc+4==endOfMethod) {
+ // the delay slot is at the start of the next method
+ jumpableAddresses.add(new Integer(pc+8)); // make the 2nd insn of the next method jumpable
+ branch(pc,pc+8); // jump over it
+ //System.err.println("delay slot: " + toHex(pc+8));
+ unreachable = true;
+ return false; // we still need to output it
+ } else {
+ //System.err.println("jumped over delay slot: " + toHex(pc+4));
+ // add another copy and jump over
+ h = a(InstructionFactory.createBranchInstruction(GOTO,null));
+ insnList.move(jumpHandles[(pc+4-startOfMethod)/4],insnList.getEnd());
+ emitInstruction(-1,nextInsn,-1); // delay slot
+ h.setTarget(a(InstructionConstants.NOP));
+ return true;
+ }
+ }
+
+ private boolean emitInstruction(int pc, int insn, int nextInsn) throws Exn {
+ if(insn == -1) throw new Exn("insn is -1");
+
+ int op = (insn >>> 26) & 0xff; // bits 26-31
+ int rs = (insn >>> 21) & 0x1f; // bits 21-25
+ int rt = (insn >>> 16) & 0x1f; // bits 16-20
+ int ft = (insn >>> 16) & 0x1f;
+ int rd = (insn >>> 11) & 0x1f; // bits 11-15
+ int fs = (insn >>> 11) & 0x1f;
+ int shamt = (insn >>> 6) & 0x1f; // bits 6-10
+ int fd = (insn >>> 6) & 0x1f;
+ int subcode = insn & 0x3f; // bits 0-5
+ int breakCode = (insn >>> 6) & 0xfffff; // bits 6-20
+
+ int jumpTarget = (insn & 0x03ffffff); // bits 0-25
+ int unsignedImmediate = insn & 0xffff;
+ int signedImmediate = (insn << 16) >> 16;
+ int branchTarget = signedImmediate;
+
+ // temporaries
+ BranchHandle b1,b2;
+
+ switch(op) {
+ case 0: {
+ switch(subcode) {
+ case 0: // SLL
+ if(insn == 0) break;
+ preSetReg(R+rd);
+ pushRegWZ(R+rt);
+ pushConst(shamt);
+ a(InstructionConstants.ISHL);
+ setReg();
+ break;
+ case 2: // SRL
+ preSetReg(R+rd);
+ pushRegWZ(R+rt);
+ pushConst(shamt);
+ a(InstructionConstants.IUSHR);
+ setReg();
+ break;
+ case 3: // SRA
+ preSetReg(R+rd);
+ pushRegWZ(R+rt);
+ pushConst(shamt);
+ a(InstructionConstants.ISHR);
+ setReg();
+ break;
+ case 4: // SLLV
+ preSetReg(R+rd);
+ pushRegWZ(R+rt);
+ pushRegWZ(R+rs);
+ a(InstructionConstants.ISHL);
+ setReg();
+ break;
+ case 6: // SRLV
+ preSetReg(R+rd);
+ pushRegWZ(R+rt);
+ pushRegWZ(R+rs);
+ a(InstructionConstants.IUSHR);
+ setReg();
+ break;
+ case 7: // SRAV
+ preSetReg(R+rd);
+ pushRegWZ(R+rt);
+ pushRegWZ(R+rs);
+ a(InstructionConstants.ISHR);
+ setReg();
+ break;
+ case 8: // JR
+ if(pc == -1) throw new Exn("pc modifying insn in delay slot");
+ emitInstruction(-1,nextInsn,-1);
+ preSetPC();
+ pushRegWZ(R+rs);
+ setPC();
+ leaveMethod();
+ unreachable = true;
+ break;
+ case 9: // JALR
+ if(pc == -1) throw new Exn("pc modifying insn in delay slot");
+ emitInstruction(-1,nextInsn,-1);
+ preSetPC();
+ pushRegWZ(R+rs);
+ setPC();
+
+ preSetReg(R+RA);
+ pushConst(pc+8);
+ setReg();
+ leaveMethod();
+ unreachable = true;
+ break;
+ case 12: // SYSCALL
+ preSetPC();
+ pushConst(pc);
+ setPC();
+
+ restoreChangedRegs();
+
+ preSetReg(R+V0);
+ a(InstructionConstants.ALOAD_0);
+ pushRegZ(R+V0);
+ pushRegZ(R+A0);
+ pushRegZ(R+A1);
+ pushRegZ(R+A2);
+ pushRegZ(R+A3);
+ a(fac.createInvoke(fullClassName,"syscall",Type.INT,new Type[]{Type.INT,Type.INT,Type.INT,Type.INT,Type.INT},INVOKEVIRTUAL));
+ setReg();
+
+ a(InstructionConstants.ALOAD_0);
+ a(fac.createFieldAccess(fullClassName,"state",Type.INT, GETFIELD));
+ pushConst(Runtime.RUNNING);
+ b1 = a(InstructionFactory.createBranchInstruction(IF_ICMPEQ,null));
+ preSetPC();
+ pushConst(pc+4);
+ setPC();
+ leaveMethod();
+ b1.setTarget(a(InstructionConstants.NOP));
+
+ break;
+ case 13: // BREAK
+ a(fac.createNew("org.xwt.mips.Runtime$ExecutionException"));
+ a(InstructionConstants.DUP);
+ a(new PUSH(cp,"BREAK Code " + toHex(breakCode)));
+ a(fac.createInvoke("org.xwt.mips.Runtime$ExecutionException","<init>",Type.VOID,new Type[]{Type.STRING},INVOKESPECIAL));
+ a(InstructionConstants.ATHROW);
+ unreachable = true;
+ break;
+ case 16: // MFHI
+ preSetReg(R+rd);
+ pushReg(HI);
+ setReg();
+ break;
+ case 17: // MTHI
+ preSetReg(HI);
+ pushRegZ(R+rs);
+ setReg();
+ break;
+ case 18: // MFLO
+ preSetReg(R+rd);
+ pushReg(LO);
+ setReg();
+ break;
+ case 19: // MTLO
+ preSetReg(LO);
+ pushRegZ(R+rs);
+ setReg();
+ break;
+ case 24: // MULT
+ pushRegWZ(R+rs);
+ a(InstructionConstants.I2L);
+ pushRegWZ(R+rt);
+ a(InstructionConstants.I2L);
+ a(InstructionConstants.LMUL);
+ a(InstructionConstants.DUP2);
+
+ a(InstructionConstants.L2I);
+ if(preSetReg(LO))
+ a(InstructionConstants.SWAP);
+ setReg();
+
+ pushConst(32);
+ a(InstructionConstants.LUSHR);
+ a(InstructionConstants.L2I);
+ if(preSetReg(HI))
+ a(InstructionConstants.SWAP);
+ setReg();
+
+ break;
+ case 25: // MULTU
+ pushRegWZ(R+rs);
+ a(InstructionConstants.I2L);
+ pushConst(0xffffffffL);
+ a(InstructionConstants.LAND);
+ pushRegWZ(R+rt);
+ a(InstructionConstants.I2L);
+ pushConst(0xffffffffL);
+ a(InstructionConstants.LAND);
+ a(InstructionConstants.LMUL);
+ a(InstructionConstants.DUP2);
+
+ a(InstructionConstants.L2I);
+ if(preSetReg(LO))
+ a(InstructionConstants.SWAP);
+ setReg();
+
+ pushConst(32);
+ a(InstructionConstants.LUSHR);
+ a(InstructionConstants.L2I);
+ if(preSetReg(HI))
+ a(InstructionConstants.SWAP);
+ setReg();
+
+ break;
+ case 26: // DIV
+ pushRegWZ(R+rs);
+ pushRegWZ(R+rt);
+ a(InstructionConstants.DUP2);
+
+ a(InstructionConstants.IDIV);
+ if(preSetReg(LO))
+ a(InstructionConstants.SWAP);
+ setReg();
+
+ a(InstructionConstants.IREM);
+ if(preSetReg(HI))
+ a(InstructionConstants.SWAP);
+ setReg();
+
+ break;
+ case 27: { // DIVU
+ pushRegWZ(R+rt);
+ a(InstructionConstants.DUP);
+ setTmp();
+ b1 = a(InstructionFactory.createBranchInstruction(IFEQ,null));
+
+ pushRegWZ(R+rs);
+ a(InstructionConstants.I2L);
+ pushConst(0xffffffffL);
+ a(InstructionConstants.LAND);
+ a(InstructionConstants.DUP2);
+ pushTmp();
+ a(InstructionConstants.I2L);
+ pushConst(0xffffffffL);
+
+ a(InstructionConstants.LAND);
+ a(InstructionConstants.DUP2_X2);
+ a(InstructionConstants.LDIV);
+
+ a(InstructionConstants.L2I);
+ if(preSetReg(LO))
+ a(InstructionConstants.SWAP);
+ setReg();
+
+ a(InstructionConstants.LREM);
+ a(InstructionConstants.L2I);
+ if(preSetReg(HI))
+ a(InstructionConstants.SWAP);
+ setReg();
+
+ b1.setTarget(a(InstructionConstants.NOP));
+
+ break;
+ }
+ case 32: // ADD
+ throw new Exn("ADD (add with oveflow trap) not suported");
+ case 33: // ADDU
+ preSetReg(R+rd);
+ if(rt != 0 && rs != 0) {
+ pushReg(R+rs);
+ pushReg(R+rt);
+ a(InstructionConstants.IADD);
+ } else if(rs != 0) {
+ pushReg(R+rs);
+ } else {
+ pushRegZ(R+rt);
+ }
+ setReg();
+ break;
+ case 34: // SUB
+ throw new Exn("SUB (add with oveflow trap) not suported");
+ case 35: // SUBU
+ preSetReg(R+rd);
+ if(rt != 0 && rs != 0) {
+ pushReg(R+rs);
+ pushReg(R+rt);
+ a(InstructionConstants.ISUB);
+ } else if(rt != 0) {
+ pushReg(R+rt);
+ a(InstructionConstants.INEG);
+ } else {
+ pushRegZ(R+rs);
+ }
+ setReg();
+ break;
+ case 36: // AND
+ preSetReg(R+rd);
+ pushRegWZ(R+rs);
+ pushRegWZ(R+rt);
+ a(InstructionConstants.IAND);
+ setReg();
+ break;
+ case 37: // OR
+ preSetReg(R+rd);
+ pushRegWZ(R+rs);
+ pushRegWZ(R+rt);
+ a(InstructionConstants.IOR);
+ setReg();
+ break;
+ case 38: // XOR
+ preSetReg(R+rd);
+ pushRegWZ(R+rs);
+ pushRegWZ(R+rt);
+ a(InstructionConstants.IXOR);
+ setReg();
+ break;
+ case 39: // NOR
+ preSetReg(R+rd);
+ if(rs != 0 || rt != 0) {
+ if(rs != 0 && rt != 0) {
+ pushReg(R+rs);
+ pushReg(R+rt);
+ a(InstructionConstants.IOR);
+ } else if(rs != 0) {
+ pushReg(R+rs);
+ } else {
+ pushReg(R+rt);
+ }
+ a(InstructionConstants.ICONST_M1);
+ a(InstructionConstants.IXOR);
+ } else {
+ pushConst(-1);
+ }
+ setReg();
+ break;
+ case 42: // SLT
+ preSetReg(R+rd);
+ if(rs != rt) {
+ pushRegZ(R+rs);
+ pushRegZ(R+rt);
+ b1 = a(InstructionFactory.createBranchInstruction(IF_ICMPLT,null));
+ a(InstructionConstants.ICONST_0);
+ b2 = a(InstructionFactory.createBranchInstruction(GOTO,null));
+ b1.setTarget(a(InstructionConstants.ICONST_1));
+ b2.setTarget(a(InstructionConstants.NOP));
+ } else {
+ pushConst(0);
+ }
+ setReg();
+ break;
+ case 43: // SLTU
+ preSetReg(R+rd);
+ if(rs != rt) {
+ if(rs != 0) {
+ pushReg(R+rs);
+ a(InstructionConstants.I2L);
+ pushConst(0xffffffffL);
+ a(InstructionConstants.LAND);
+ pushReg(R+rt);
+ a(InstructionConstants.I2L);
+ pushConst(0xffffffffL);
+ a(InstructionConstants.LAND);
+ a(InstructionConstants.LCMP);
+ b1 = a(InstructionFactory.createBranchInstruction(IFLT,null));
+ } else {
+ pushReg(R+rt);
+ b1 = a(InstructionFactory.createBranchInstruction(IFNE,null));
+ }
+ a(InstructionConstants.ICONST_0);
+ b2 = a(InstructionFactory.createBranchInstruction(GOTO,null));
+ b1.setTarget(a(InstructionConstants.ICONST_1));
+ b2.setTarget(a(InstructionConstants.NOP));
+ } else {
+ pushConst(0);
+ }
+ setReg();
+ break;
+ default:
+ throw new RuntimeException("Illegal instruction 0/" + subcode);
+ }
+ break;
+ }
+ case 1: {
+ switch(rt) {
+ case 0: // BLTZ
+ if(pc == -1) throw new Exn("pc modifying insn in delay slot");
+ pushRegWZ(R+rs);
+ return doIfInstruction(IFLT,pc,pc+branchTarget*4+4,nextInsn);
+ case 1: // BGEZ
+ if(pc == -1) throw new Exn("pc modifying insn in delay slot");
+ pushRegWZ(R+rs);
+ return doIfInstruction(IFGE,pc,pc+branchTarget*4+4,nextInsn);
+ case 16: // BLTZAL
+ if(pc == -1) throw new Exn("pc modifying insn in delay slot");
+ pushRegWZ(R+rs);
+ b1 = a(InstructionFactory.createBranchInstruction(IFGE,null));
+ emitInstruction(-1,nextInsn,-1);
+ preSetReg(R+RA);
+ pushConst(pc+8);
+ setReg();
+ branch(pc,pc+branchTarget*4+4);
+ b1.setTarget(a(InstructionConstants.NOP));
+ break;
+ case 17: // BGEZAL
+ if(pc == -1) throw new Exn("pc modifying insn in delay slot");
+ b1 = null;
+ if(rs != 0) { // r0 is always >= 0
+ pushRegWZ(R+rs);
+ b1 = a(InstructionFactory.createBranchInstruction(IFLT,null));
+ }
+ emitInstruction(-1,nextInsn,-1);
+ preSetReg(R+RA);
+ pushConst(pc+8);
+ setReg();
+ branch(pc,pc+branchTarget*4+4);
+ if(b1 != null) b1.setTarget(a(InstructionConstants.NOP));
+ if(b1 == null) unreachable = true;
+ break;
+ default:
+ throw new RuntimeException("Illegal Instruction 1/" + rt);
+ }
+ break;
+ }
+ case 2: { // J
+ if(pc == -1) throw new Exn("pc modifying insn in delay slot");
+ emitInstruction(-1,nextInsn,-1);
+ branch(pc,(pc&0xf0000000)|(jumpTarget << 2));
+ unreachable = true;
+ break;
+ }
+ case 3: { // JAL
+ if(pc == -1) throw new Exn("pc modifying insn in delay slot");
+ int target = (pc&0xf0000000)|(jumpTarget << 2);
+ emitInstruction(-1,nextInsn,-1);
+ if(optimizedMemcpy && (target == memcpy || target == memset)) {
+ a(InstructionConstants.ALOAD_0);
+ pushRegZ(R+4);
+ pushRegZ(R+5);
+ pushRegZ(R+6);
+ a(fac.createInvoke(fullClassName,target==memcpy ? "memcpy" : "memset", Type.VOID, new Type[]{Type.INT,Type.INT,Type.INT},INVOKEVIRTUAL));
+ preSetReg(R+2);
+ pushReg(R+4);
+ setReg();
+ branch(pc,pc+8);
+ } else {
+ preSetReg(R+RA);
+ pushConst(pc+8);
+ setReg();
+ branch(pc, target);
+ }
+ unreachable = true;
+ break;
+ }
+ case 4: // BEQ
+ if(pc == -1) throw new Exn("pc modifying insn in delay slot");
+ if(rs == rt) {
+ emitInstruction(-1,nextInsn,-1);
+ branch(pc,pc+branchTarget*4+4);
+ unreachable = true;
+ } else if(rs == 0 || rt == 0) {
+ pushReg(rt == 0 ? R+rs : R+rt);
+ return doIfInstruction(IFEQ,pc,pc+branchTarget*4+4,nextInsn);
+ } else {
+ pushReg(R+rs);
+ pushReg(R+rt);
+ return doIfInstruction(IF_ICMPEQ,pc,pc+branchTarget*4+4,nextInsn);
+ }
+ break;
+ case 5: // BNE
+ if(pc == -1) throw new Exn("pc modifying insn in delay slot");
+ pushRegWZ(R+rs);
+ if(rt == 0) {
+ return doIfInstruction(IFNE,pc,pc+branchTarget*4+4,nextInsn);
+ } else {
+ pushReg(R+rt);
+ return doIfInstruction(IF_ICMPNE,pc,pc+branchTarget*4+4,nextInsn);
+ }
+ case 6: //BLEZ
+ if(pc == -1) throw new Exn("pc modifying insn in delay slot");
+ pushRegWZ(R+rs);
+ return doIfInstruction(IFLE,pc,pc+branchTarget*4+4,nextInsn);
+ case 7: //BGTZ
+ if(pc == -1) throw new Exn("pc modifying insn in delay slot");
+ pushRegWZ(R+rs);
+ return doIfInstruction(IFGT,pc,pc+branchTarget*4+4,nextInsn);
+ case 8: // ADDI
+ throw new Exn("ADDI (add immediate with oveflow trap) not suported");
+ case 9: // ADDIU
+ preSetReg(R+rt);
+ addiu(rs,signedImmediate);
+ setReg();
+ break;
+ case 10: // SLTI
+ preSetReg(R+rt);
+ pushRegWZ(R+rs);
+ pushConst(signedImmediate);
+ b1 = a(InstructionFactory.createBranchInstruction(IF_ICMPLT,null));
+ a(InstructionConstants.ICONST_0);
+ b2 = a(InstructionFactory.createBranchInstruction(GOTO,null));
+ b1.setTarget(a(InstructionConstants.ICONST_1));
+ b2.setTarget(a(InstructionConstants.NOP));
+ setReg();
+ break;
+ case 11: // SLTIU
+ preSetReg(R+rt);
+ pushRegWZ(R+rs);
+ a(InstructionConstants.I2L);
+ pushConst(0xffffffffL);
+ a(InstructionConstants.LAND);
+ pushConst((long)unsignedImmediate);
+ a(InstructionConstants.LCMP);
+
+ b1 = a(InstructionFactory.createBranchInstruction(IFLT,null));
+ a(InstructionConstants.ICONST_0);
+ b2 = a(InstructionFactory.createBranchInstruction(GOTO,null));
+ b1.setTarget(a(InstructionConstants.ICONST_1));
+ b2.setTarget(a(InstructionConstants.NOP));
+
+ setReg();
+ break;
+ case 12: // ANDI
+ preSetReg(R+rt);
+ pushRegWZ(R+rs);
+ pushConst(unsignedImmediate);
+ a(InstructionConstants.IAND);
+ setReg();
+ break;
+ case 13: // ORI
+ preSetReg(R+rt);
+ if(rs != 0 && unsignedImmediate != 0) {
+ pushReg(R+rs);
+ pushConst(unsignedImmediate);
+ a(InstructionConstants.IOR);
+ } else if(rs != 0){
+ pushReg(R+rs);
+ } else {
+ pushConst(unsignedImmediate);
+ }
+ setReg();
+ break;
+ case 14: // XORI
+ preSetReg(R+rt);
+ pushRegWZ(R+rs);
+ pushConst(unsignedImmediate);
+ a(InstructionConstants.IXOR);
+ setReg();
+ break;
+ case 15: // LUI
+ preSetReg(R+rt);
+ pushConst(unsignedImmediate << 16);
+ setReg();
+ break;
+ case 16:
+ throw new Exn("TLB/Exception support not implemented");
+ case 17: { // FPU
+ switch(rs) {
+ case 0: // MFC.1
+ preSetReg(R+rt);
+ pushReg(F+rd);
+ setReg();
+ break;
+ case 2: // CFC.1
+ if(fs != 31) throw new Exn("FCR " + fs + " unavailable");
+ preSetReg(R+rt);
+ pushReg(FCSR);
+ setReg();
+ break;
+ case 4: // MTC.1
+ preSetReg(F+rd);
+ if(rt != 0)
+ pushReg(R+rt);
+ else
+ pushConst(0);
+ setReg();
+ break;
+ case 6: // CTC.1
+ if(fs != 31) throw new Exn("FCR " + fs + " unavailable");
+ preSetReg(FCSR);
+ pushReg(R+rt);
+ setReg();
+ break;
+ case 8: {// BC1F, BC1T
+ pushReg(FCSR);
+ pushConst(0x800000);
+ a(InstructionConstants.IAND);
+ return doIfInstruction(((insn>>>16)&1) == 0 ? IFEQ : IFNE,pc,pc+branchTarget*4+4,nextInsn);
+ }
+ case 16:
+ case 17:
+ { // Single/Double math
+ boolean d = rs == 17;
+ switch(subcode) {
+ case 0: // ADD.X
+ preSetDouble(F+fd,d);
+ pushDouble(F+fs,d);
+ pushDouble(F+ft,d);
+ a(d ? InstructionConstants.DADD : InstructionConstants.FADD);
+ setDouble(d);
+ break;
+ case 1: // SUB.X
+ preSetDouble(F+fd,d);
+ pushDouble(F+fs,d);
+ pushDouble(F+ft,d);
+ a(d ? InstructionConstants.DSUB : InstructionConstants.FSUB);
+ setDouble(d);
+ break;
+ case 2: // MUL.X
+ preSetDouble(F+fd,d);
+ pushDouble(F+fs,d);
+ pushDouble(F+ft,d);
+ a(d ? InstructionConstants.DMUL : InstructionConstants.FMUL);
+ setDouble(d);
+ break;
+ case 3: // DIV.X
+ preSetDouble(F+fd,d);
+ pushDouble(F+fs,d);
+ pushDouble(F+ft,d);
+ a(d ? InstructionConstants.DDIV : InstructionConstants.FDIV);
+ setDouble(d);
+ break;
+ case 5: // ABS.X
+ preSetDouble(F+fd,d);
+ // NOTE: We can't use fneg/dneg here since they'll turn +0.0 into -0.0
+
+ pushDouble(F+fs,d);
+ a(d ? InstructionConstants.DUP2 : InstructionConstants.DUP);
+ a(d ? InstructionConstants.DCONST_0 : InstructionConstants.FCONST_0);
+ a(d ? InstructionConstants.DCMPG : InstructionConstants.FCMPG);
+
+ b1 = a(InstructionFactory.createBranchInstruction(IFGT,null));
+ a(d ? InstructionConstants.DCONST_0 : InstructionConstants.FCONST_0);
+ if(d) {
+ a(InstructionConstants.DUP2_X2);
+ a(InstructionConstants.POP2);
+ } else {
+ a(InstructionConstants.POP);
+ }
+ a(InstructionConstants.DSUB);
+
+ b1.setTarget(setDouble(d));
+
+ break;
+ case 6: // MOV.X
+ preSetReg(F+fd);
+ pushReg(F+fs);
+ setReg();
+
+ preSetReg(F+fd+1);
+ pushReg(F+fs+1);
+ setReg();
+
+ break;
+ case 7: // NEG.X
+ preSetDouble(F+fd,d);
+ pushDouble(F+fs,d);
+ a(d ? InstructionConstants.DNEG : InstructionConstants.FNEG);
+ setDouble(d);
+ break;
+ case 32: // CVT.S.X
+ preSetFloat(F+fd);
+ pushDouble(F+fd,d);
+ if(d) a(InstructionConstants.D2F);
+ setFloat();
+ break;
+ case 33: // CVT.D.X
+ preSetDouble(F+fd);
+ pushDouble(F+fd,d);
+ if(!d) a(InstructionConstants.F2D);
+ setDouble();
+ break;
+ case 36: { // CVT.W.D
+ int[] matches = new int[4];
+ for(int i=0;i<4;i++) matches[i] = i;
+
+ TABLESWITCH ts = new TABLESWITCH(matches,new InstructionHandle[4], null);
+
+ preSetReg(F+fd);
+ pushDouble(F+fs,d);
+ pushReg(FCSR);
+ a(InstructionConstants.ICONST_3);
+ a(InstructionConstants.IAND);
+ a(ts);
+
+ // Round towards plus infinity
+ ts.setTarget(2,a(InstructionConstants.NOP));
+ if(!d) a(InstructionConstants.F2D); // Ugh.. java.lang.Math doesn't have a float ceil/floor
+ a(fac.createInvoke("java.lang.Math","ceil",Type.DOUBLE,new Type[]{Type.DOUBLE},INVOKESTATIC));
+ if(!d) a(InstructionConstants.D2F);
+ b1 = a(InstructionFactory.createBranchInstruction(GOTO,null));
+
+ // Round to nearest
+ ts.setTarget(0,d ? pushConst(0.5d) : pushConst(0.5f));
+ a(d ? InstructionConstants.DADD : InstructionConstants.FADD);
+ // fall through
+
+ // Round towards minus infinity
+ ts.setTarget(3,a(InstructionConstants.NOP));
+ if(!d) a(InstructionConstants.F2D);
+ a(fac.createInvoke("java.lang.Math","floor",Type.DOUBLE,new Type[]{Type.DOUBLE},INVOKESTATIC));
+ if(!d) a(InstructionConstants.D2F);
+
+ InstructionHandle h = a(d ? InstructionConstants.D2I : InstructionConstants.F2I);
+ setReg();
+
+ ts.setTarget(1,h);
+ ts.setTarget(h);
+ b1.setTarget(h);
+
+ break;
+ }
+ case 50: // C.EQ.D
+ case 60: // C.LT.D
+ case 62: // C.LE.D
+ preSetReg(FCSR);
+ pushReg(FCSR);
+ pushConst(~0x800000);
+ a(InstructionConstants.IAND);
+ pushDouble(F+fs,d);
+ pushDouble(F+ft,d);
+ a(d ? InstructionConstants.DCMPG : InstructionConstants.FCMPG);
+ switch(subcode) {
+ case 50: b1 = a(InstructionFactory.createBranchInstruction(IFEQ,null)); break;
+ case 60: b1 = a(InstructionFactory.createBranchInstruction(IFLT,null)); break;
+ case 62: b1 = a(InstructionFactory.createBranchInstruction(IFLE,null)); break;
+ default: b1 = null;
+ }
+
+ pushConst(0x000000);
+ b2 = a(InstructionFactory.createBranchInstruction(GOTO,null));
+ b1.setTarget(pushConst(0x800000));
+ b2.setTarget(a(InstructionConstants.IOR));
+ setReg();
+ break;
+ default: throw new Exn("Invalid Instruction 17/" + rs + "/" + subcode);
+ }
+ break;
+ }
+ case 20: { // Integer
+ switch(subcode) {
+ case 32: // CVT.S.W
+ preSetFloat(F+fd);
+ pushReg(F+fs);
+ a(InstructionConstants.I2F);
+ setFloat();
+ break;
+ case 33: // CVT.D.W
+ preSetDouble(F+fd);
+ pushReg(F+fs);
+ a(InstructionConstants.I2D);
+ setDouble();
+ break;
+ default: throw new Exn("Invalid Instruction 17/" + rs + "/" + subcode);
+ }
+ break;
+ }
+ default:
+ throw new Exn("Invalid Instruction 17/" + rs);
+ }
+ break;
+ }
+ case 18: case 19:
+ throw new Exn("coprocessor 2 and 3 instructions not available");
+ case 32: { // LB
+ preSetReg(R+rt);
+ addiu(R+rs,signedImmediate);
+ setTmp();
+ preMemRead();
+ pushTmp();
+ memRead(true);
+ pushTmp();
+
+ a(InstructionConstants.ICONST_M1);
+ a(InstructionConstants.IXOR);
+ a(InstructionConstants.ICONST_3);
+ a(InstructionConstants.IAND);
+ a(InstructionConstants.ICONST_3);
+ a(InstructionConstants.ISHL);
+ a(InstructionConstants.IUSHR);
+ a(InstructionConstants.I2B);
+ setReg();
+ break;
+ }
+ case 33: { // LH
+ preSetReg(R+rt);
+ addiu(R+rs,signedImmediate);
+ setTmp();
+ preMemRead();
+ pushTmp();
+ memRead(true);
+ pushTmp();
+
+ a(InstructionConstants.ICONST_M1);
+ a(InstructionConstants.IXOR);
+ a(InstructionConstants.ICONST_2);
+ a(InstructionConstants.IAND);
+ a(InstructionConstants.ICONST_3);
+ a(InstructionConstants.ISHL);
+ a(InstructionConstants.IUSHR);
+ a(InstructionConstants.I2S);
+ setReg();
+ break;
+ }
+ case 34: { // LWL;
+ preSetReg(R+rt);
+ addiu(R+rs,signedImmediate);
+ setTmp(); // addr
+
+ pushRegWZ(R+rt);
+ pushConst(0x00ffffff);
+ pushTmp();
+
+ a(InstructionConstants.ICONST_M1);
+ a(InstructionConstants.IXOR);
+ a(InstructionConstants.ICONST_3);
+ a(InstructionConstants.IAND);
+ a(InstructionConstants.ICONST_3);
+ a(InstructionConstants.ISHL);
+ a(InstructionConstants.IUSHR);
+ a(InstructionConstants.IAND);
+
+ preMemRead();
+ pushTmp();
+ memRead(true);
+ pushTmp();
+
+ a(InstructionConstants.ICONST_3);
+ a(InstructionConstants.IAND);
+ a(InstructionConstants.ICONST_3);
+ a(InstructionConstants.ISHL);
+ a(InstructionConstants.ISHL);
+ a(InstructionConstants.IOR);
+
+ setReg();
+
+ break;
+
+ }
+ case 35: // LW
+ preSetReg(R+rt);
+ memRead(R+rs,signedImmediate);
+ setReg();
+ break;
+ case 36: { // LBU
+ preSetReg(R+rt);
+ addiu(R+rs,signedImmediate);
+ setTmp();
+ preMemRead();
+ pushTmp();
+ memRead(true);
+ pushTmp();
+
+ a(InstructionConstants.ICONST_M1);
+ a(InstructionConstants.IXOR);
+ a(InstructionConstants.ICONST_3);
+ a(InstructionConstants.IAND);
+ a(InstructionConstants.ICONST_3);
+ a(InstructionConstants.ISHL);
+ a(InstructionConstants.IUSHR);
+ pushConst(0xff);
+ a(InstructionConstants.IAND);
+ setReg();
+ break;
+ }
+ case 37: { // LHU
+ preSetReg(R+rt);
+ addiu(R+rs,signedImmediate);
+ setTmp();
+ preMemRead();
+ pushTmp();
+ memRead(true);
+ pushTmp();
+
+ a(InstructionConstants.ICONST_M1);
+ a(InstructionConstants.IXOR);
+ a(InstructionConstants.ICONST_2);
+ a(InstructionConstants.IAND);
+ a(InstructionConstants.ICONST_3);
+ a(InstructionConstants.ISHL);
+ a(InstructionConstants.IUSHR);
+
+ // chars are unsigend so this works
+ a(InstructionConstants.I2C);
+ setReg();
+ break;
+ }
+ case 38: { // LWR
+ preSetReg(R+rt);
+ addiu(R+rs,signedImmediate);
+ setTmp(); // addr
+
+ pushRegWZ(R+rt);
+ pushConst(0xffffff00);
+ pushTmp();
+
+ a(InstructionConstants.ICONST_3);
+ a(InstructionConstants.IAND);
+ a(InstructionConstants.ICONST_3);
+ a(InstructionConstants.ISHL);
+ a(InstructionConstants.ISHL);
+ a(InstructionConstants.IAND);
+
+ preMemRead();
+ pushTmp();
+ memRead(true);
+ pushTmp();
+
+ a(InstructionConstants.ICONST_M1);
+ a(InstructionConstants.IXOR);
+ a(InstructionConstants.ICONST_3);
+ a(InstructionConstants.IAND);
+ a(InstructionConstants.ICONST_3);
+ a(InstructionConstants.ISHL);
+ a(InstructionConstants.IUSHR);
+ a(InstructionConstants.IOR);
+
+
+ setReg();
+ break;
+ }
+ case 40: { // SB
+ addiu(R+rs,signedImmediate);
+ setTmp(); // addr
+
+ // FEATURE: DO the preMemRead(true) thing for the rest of the S* instructions
+ preMemRead(true);
+ pushTmp();
+ memRead(true);
+
+ pushConst(0xff000000);
+ pushTmp();
+
+ a(InstructionConstants.ICONST_3);
+ a(InstructionConstants.IAND);
+ a(InstructionConstants.ICONST_3);
+ a(InstructionConstants.ISHL);
+ a(InstructionConstants.IUSHR);
+ a(InstructionConstants.ICONST_M1);
+ a(InstructionConstants.IXOR);
+ a(InstructionConstants.IAND);
+
+ if(rt != 0) {
+ pushReg(R+rt);
+ pushConst(0xff);
+ a(InstructionConstants.IAND);
+ } else {
+ pushConst(0);
+ }
+ pushTmp();
+
+ a(InstructionConstants.ICONST_M1);
+ a(InstructionConstants.IXOR);
+ a(InstructionConstants.ICONST_3);
+ a(InstructionConstants.IAND);
+ a(InstructionConstants.ICONST_3);
+ a(InstructionConstants.ISHL);
+ a(InstructionConstants.ISHL);
+ a(InstructionConstants.IOR);
+
+ memWrite();
+
+ break;
+ }
+ case 41: { // SH
+ preMemWrite1();
+
+ addiu(R+rs,signedImmediate);
+
+ a(InstructionConstants.DUP);
+ setTmp(); // addr
+
+ preMemWrite2(true);
+
+ preMemRead();
+ pushTmp();
+ memRead(true);
+
+ pushConst(0xffff);
+ pushTmp();
+
+ a(InstructionConstants.ICONST_2);
+ a(InstructionConstants.IAND);
+ a(InstructionConstants.ICONST_3);
+ a(InstructionConstants.ISHL);
+ a(InstructionConstants.ISHL);
+ a(InstructionConstants.IAND);
+
+ if(rt != 0) {
+ pushReg(R+rt);
+ pushConst(0xffff);
+ a(InstructionConstants.IAND);
+ } else {
+ pushConst(0);
+ }
+ pushTmp();
+
+ a(InstructionConstants.ICONST_M1);
+ a(InstructionConstants.IXOR);
+ a(InstructionConstants.ICONST_2);
+ a(InstructionConstants.IAND);
+ a(InstructionConstants.ICONST_3);
+ a(InstructionConstants.ISHL);
+ a(InstructionConstants.ISHL);
+ a(InstructionConstants.IOR);
+
+ memWrite();
+
+ break;
+ }
+ case 42: { // SWL
+ preMemWrite1();
+
+ addiu(R+rs,signedImmediate);
+ a(InstructionConstants.DUP);
+ setTmp(); // addr
+
+ preMemWrite2(true);
+
+ preMemRead();
+ pushTmp();
+ memRead(true);
+
+ pushConst(0xffffff00);
+ pushTmp();
+
+ a(InstructionConstants.ICONST_M1);
+ a(InstructionConstants.IXOR);
+ a(InstructionConstants.ICONST_3);
+ a(InstructionConstants.IAND);
+ a(InstructionConstants.ICONST_3);
+ a(InstructionConstants.ISHL);
+ a(InstructionConstants.ISHL);
+ a(InstructionConstants.IAND);
+
+ pushRegWZ(R+rt);
+ pushTmp();
+
+ a(InstructionConstants.ICONST_3);
+ a(InstructionConstants.IAND);
+ a(InstructionConstants.ICONST_3);
+ a(InstructionConstants.ISHL);
+ a(InstructionConstants.IUSHR);
+ a(InstructionConstants.IOR);
+
+ memWrite();
+ break;
+
+ }
+ case 43: // SW
+ preMemWrite1();
+ preMemWrite2(R+rs,signedImmediate);
+ pushRegZ(R+rt);
+ memWrite();
+ break;
+ case 46: { // SWR
+ preMemWrite1();
+
+ addiu(R+rs,signedImmediate);
+ a(InstructionConstants.DUP);
+ setTmp(); // addr
+
+ preMemWrite2(true);
+
+ preMemRead();
+ pushTmp();
+ memRead(true);
+
+ pushConst(0x00ffffff);
+ pushTmp();
+
+ a(InstructionConstants.ICONST_3);
+ a(InstructionConstants.IAND);
+ a(InstructionConstants.ICONST_3);
+ a(InstructionConstants.ISHL);
+ a(InstructionConstants.IUSHR);
+ a(InstructionConstants.IAND);
+
+ pushRegWZ(R+rt);
+ pushTmp();
+
+ a(InstructionConstants.ICONST_M1);
+ a(InstructionConstants.IXOR);
+ a(InstructionConstants.ICONST_3);
+ a(InstructionConstants.IAND);
+ a(InstructionConstants.ICONST_3);
+ a(InstructionConstants.ISHL);
+ a(InstructionConstants.ISHL);
+ a(InstructionConstants.IOR);
+
+ memWrite();
+ break;
+ }
+ // FEATURE: This need to be atomic if we ever support threads (see SWC0/SC)
+ case 48: // LWC0/LL
+ preSetReg(R+rt);
+ memRead(R+rs,signedImmediate);
+ setReg();
+ break;
+
+ case 49: // LWC1
+ preSetReg(F+rt);
+ memRead(R+rs,signedImmediate);
+ setReg();
+ break;
+
+ /* FEATURE: This needs to fail (set rt to 0) if the memory location was modified
+ * between the LL and SC if we every support threads.
+ */
+ case 56: // SWC0/SC
+ preSetReg(R+rt);
+ preMemWrite1();
+ preMemWrite2(R+rs,signedImmediate);
+ pushReg(R+rt);
+ memWrite();
+ pushConst(1);
+ setReg();
+ break;
+
+ case 57: // SWC1
+ preMemWrite1();
+ preMemWrite2(R+rs,signedImmediate);
+ pushReg(F+rt);
+ memWrite();
+ break;
+ default:
+ throw new Exn("Invalid Instruction: " + op + " at " + toHex(pc));
+ }
+ return false;
+ }
+
+ // Helper functions for emitText
+
+ private static final int R = 0;
+ private static final int F = 32;
+ private static final int HI = 64;
+ private static final int LO = 65;
+ private static final int FCSR = 66;
+ private static final int REG_COUNT=67;
+
+ private int[] regLocalMapping = new int[REG_COUNT];
+ private int[] regLocalReadCount = new int[REG_COUNT];
+ private int[] regLocalWriteCount = new int[REG_COUNT];
+ private int nextAvailLocal;
+
+ private int getLocalForReg(int reg) {
+ if(regLocalMapping[reg] != 0) return regLocalMapping[reg];
+ if(nextAvailLocal == 0) nextAvailLocal = onePage ? 3 : 4;
+ regLocalMapping[reg] = nextAvailLocal++;
+ return regLocalMapping[reg];
+ }
+
+ private void fixupRegs() {
+ InstructionHandle prev = realStart;
+ for(int i=0;i<REG_COUNT;i++) {
+ if(regLocalMapping[i] == 0) continue;
+
+ prev = insnList.append(prev,InstructionConstants.ALOAD_0);
+ prev = insnList.append(prev,fac.createFieldAccess(fullClassName,regField(i),Type.INT, GETFIELD));
+ prev = insnList.append(prev,InstructionFactory.createStore(Type.INT,regLocalMapping[i]));
+
+ if(regLocalWriteCount[i] > 0) {
+ a(InstructionConstants.ALOAD_0);
+ a(InstructionFactory.createLoad(Type.INT,regLocalMapping[i]));
+ a(fac.createFieldAccess(fullClassName,regField(i),Type.INT, PUTFIELD));
+ }
+
+ regLocalMapping[i] = regLocalReadCount[i] = regLocalWriteCount[i] = 0;
+ }
+ nextAvailLocal = 0;
+ }
+
+ private void restoreChangedRegs() {
+ for(int i=0;i<REG_COUNT;i++) {
+ if(regLocalWriteCount[i] > 0) {
+ a(InstructionConstants.ALOAD_0);
+ a(InstructionFactory.createLoad(Type.INT,regLocalMapping[i]));
+ a(fac.createFieldAccess(fullClassName,regField(i),Type.INT, PUTFIELD));
+ }
+ }
+ }
+
+ private String regField(int reg) {
+ String field;
+ switch(reg) {
+ case HI: field = "hi"; break;
+ case LO: field = "lo"; break;
+ case FCSR: field = "fcsr"; break;
+ default:
+ if(reg > R && reg < R+32) field="r"+(reg-R);
+ else if(reg >= F && reg < F+32) field="f"+(reg-F);
+ else throw new IllegalArgumentException(""+reg);
+ }
+ return field;
+ }
+
+ private boolean doLocal(int reg) {
+ //return false;
+ return reg == R+2 || reg == R+3 || reg == R+4 || reg == R+29;
+ }
+
+ private InstructionHandle pushRegWZ(int reg) {
+ if(reg == R+0) {
+ warn.println("Warning: Pushing r0!");
+ new Exception().printStackTrace(warn);
+ }
+ return pushRegZ(reg);
+ }
+
+ private InstructionHandle pushRegZ(int reg) {
+ if(reg == R+0) return pushConst(0);
+ else return pushReg(reg);
+ }
+
+
+ private InstructionHandle pushReg(int reg) {
+ InstructionHandle h;
+ if(doLocal(reg)) {
+ regLocalReadCount[reg]++;
+ h = a(InstructionFactory.createLoad(Type.INT,getLocalForReg(reg)));
+ } else {
+ h = a(InstructionConstants.ALOAD_0);
+ a(fac.createFieldAccess(fullClassName,regField(reg),Type.INT, GETFIELD));
+ }
+ return h;
+ }
+
+ private int preSetRegStackPos;
+ private int[] preSetRegStack = new int[8];
+
+ // This can push ONE or ZERO words to the stack. If it pushed one it returns true
+ private boolean preSetReg(int reg) {
+ regField(reg); // just to check for validity
+ preSetRegStack[preSetRegStackPos] = reg;
+ preSetRegStackPos++;
+ if(doLocal(reg)) {
+ return false;
+ } else {
+ a(InstructionConstants.ALOAD_0);
+ return true;
+ }
+ }
+
+ private InstructionHandle setReg() {
+ if(preSetRegStackPos==0) throw new RuntimeException("didn't do preSetReg");
+ preSetRegStackPos--;
+ int reg = preSetRegStack[preSetRegStackPos];
+ InstructionHandle h;
+ if(doLocal(reg)) {
+ h = a(InstructionFactory.createStore(Type.INT,getLocalForReg(reg)));
+ regLocalWriteCount[reg]++;
+ } else {
+ h = a(fac.createFieldAccess(fullClassName,regField(reg),Type.INT, PUTFIELD));
+ }
+ return h;
+ }
+
+ private InstructionHandle preSetPC() { return a(InstructionConstants.ALOAD_0); }
+ private InstructionHandle setPC() { return a(fac.createFieldAccess(fullClassName,"pc",Type.INT, PUTFIELD)); }
+
+ //unused - private InstructionHandle pushFloat(int reg) throws CompilationException { return pushDouble(reg,false); }
+ //unused - private InstructionHandle pushDouble(int reg) throws CompilationException { return pushDouble(reg,true); }
+ private InstructionHandle pushDouble(int reg, boolean d) throws Exn {
+ if(reg < F || reg >= F+32) throw new IllegalArgumentException(""+reg);
+ InstructionHandle h;
+ if(d) {
+ if(reg == F+31) throw new Exn("Tried to use a double in f31");
+ h = pushReg(reg+1);
+ a(InstructionConstants.I2L);
+ pushConst(32);
+ a(InstructionConstants.LSHL);
+ pushReg(reg);
+ a(InstructionConstants.I2L);
+ pushConst(0xffffffffL);
+ a(InstructionConstants.LAND);
+ a(InstructionConstants.LOR);
+ //p("invokestatic java/lang/Double/longBitsToDouble(J)D");
+ a(fac.createInvoke("java.lang.Double","longBitsToDouble",Type.DOUBLE,new Type[]{Type.LONG},INVOKESTATIC));
+ } else {
+ h = pushReg(reg);
+ a(fac.createInvoke("java.lang.Float","intBitsToFloat",Type.FLOAT,new Type[]{Type.INT},INVOKESTATIC));
+ }
+ return h;
+ }
+
+ private void preSetFloat(int reg) { preSetDouble(reg,false); }
+ private void preSetDouble(int reg) { preSetDouble(reg,true); }
+ private void preSetDouble(int reg, boolean d) { preSetReg(reg); }
+
+ private InstructionHandle setFloat() throws Exn { return setDouble(false); }
+ private InstructionHandle setDouble() throws Exn { return setDouble(true); }
+ private InstructionHandle setDouble(boolean d) throws Exn {
+ int reg = preSetRegStack[preSetRegStackPos-1];
+ if(reg < F || reg >= F+32) throw new IllegalArgumentException(""+reg);
+ //p("invokestatic java/lang/Double/doubleToLongBits(D)J");
+ InstructionHandle h;
+ if(d) {
+ if(reg == F+31) throw new Exn("Tried to use a double in f31");
+ h = a(fac.createInvoke("java.lang.Double","doubleToLongBits",Type.LONG,new Type[]{Type.DOUBLE},INVOKESTATIC));
+ a(InstructionConstants.DUP2);
+ pushConst(32);
+ a(InstructionConstants.LUSHR);
+ a(InstructionConstants.L2I);
+ if(preSetReg(reg+1))
+ a(InstructionConstants.SWAP);
+ setReg();
+ a(InstructionConstants.L2I);
+ setReg(); // preSetReg was already done for this by preSetDouble
+ } else {
+ h = a(fac.createInvoke("java.lang.Float","floatToRawIntBits",Type.INT,new Type[]{Type.FLOAT},INVOKESTATIC));
+ setReg();
+ }
+ return h;
+ }
+
+ private InstructionHandle pushConst(int n) {
+ if(n >= 0 && n <= 5) {
+ switch(n) {
+ case 0: return a(InstructionConstants.ICONST_0);
+ case 1: return a(InstructionConstants.ICONST_1);
+ case 2: return a(InstructionConstants.ICONST_2);
+ case 3: return a(InstructionConstants.ICONST_3);
+ case 4: return a(InstructionConstants.ICONST_4);
+ case 5: return a(InstructionConstants.ICONST_5);
+ default: return null;
+ }
+ } else if(n == -1) {
+ return a(InstructionConstants.ICONST_M1);
+ } else if(n >= -128 && n <= 127) {
+ return a(new BIPUSH((byte) n));
+ } else if(n >= -32768 && n <= 32767) {
+ return a(new SIPUSH((short) n));
+ } else {
+ return a(new PUSH(cp,n));
+ }
+ }
+
+ private InstructionHandle pushConst(long l) { return a(new PUSH(cp,l)); }
+ private InstructionHandle pushConst(float f) { return a(new PUSH(cp,f)); }
+ private InstructionHandle pushConst(double d) { return a(new PUSH(cp,d)); }
+
+ private void pushTmp() { a(InstructionConstants.ILOAD_1); }
+ private void setTmp() { a(InstructionConstants.ISTORE_1); }
+
+ private void addiu(int reg, int offset) {
+ if(reg != R+0 && offset != 0) {
+ pushReg(reg);
+ pushConst(offset);
+ a(InstructionConstants.IADD);
+ } else if(reg != R+0) {
+ pushReg(reg);
+ } else {
+ pushConst(offset);
+ }
+ }
+ private int memWriteStage;
+ private void preMemWrite1() {
+ if(memWriteStage!=0) throw new Error("pending preMemWrite1/2");
+ memWriteStage=1;
+ if(onePage)
+ a(InstructionConstants.ALOAD_2);
+ else if(fastMem)
+ a(InstructionFactory.createLoad(Type.OBJECT,3));
+ else
+ a(InstructionConstants.ALOAD_0);
+ }
+
+ private void preMemWrite2(int reg, int offset) {
+ addiu(reg,offset);
+ preMemWrite2();
+ }
+
+ private void preMemWrite2() { preMemWrite2(false); }
+ private void preMemWrite2(boolean addrInTmp) {
+ if(memWriteStage!=1) throw new Error("pending preMemWrite2 or no preMemWrite1");
+ memWriteStage=2;
+
+ if(nullPointerCheck) {
+ a(InstructionConstants.DUP);
+ a(InstructionConstants.ALOAD_0);
+ a(InstructionConstants.SWAP);
+ a(fac.createInvoke(fullClassName,"nullPointerCheck",Type.VOID,new Type[]{Type.INT},INVOKEVIRTUAL));
+ }
+
+ if(onePage) {
+ a(InstructionConstants.ICONST_2);
+ a(InstructionConstants.IUSHR);
+ } else if(fastMem) {
+ if(!addrInTmp)
+ a(InstructionConstants.DUP_X1);
+ pushConst(pageShift);
+ a(InstructionConstants.IUSHR);
+ a(InstructionConstants.AALOAD);
+ if(addrInTmp)
+ pushTmp();
+ else
+ a(InstructionConstants.SWAP);
+ a(InstructionConstants.ICONST_2);
+ a(InstructionConstants.IUSHR);
+ pushConst((pageSize>>2)-1);
+ a(InstructionConstants.IAND);
+ }
+ }
+
+ // pops an address and value off the stack, sets *addr to value
+ private void memWrite() {
+ if(memWriteStage!=2) throw new Error("didn't do preMemWrite1 or preMemWrite2");
+ memWriteStage=0;
+
+ if(onePage) {
+ a(InstructionConstants.IASTORE);
+ } else if(fastMem) {
+ a(InstructionConstants.IASTORE);
+ } else {
+ a(fac.createInvoke(fullClassName,"unsafeMemWrite",Type.VOID,new Type[]{Type.INT,Type.INT},INVOKEVIRTUAL));
+ }
+
+ }
+
+ // reads the word at r[reg]+offset
+ private void memRead(int reg, int offset) {
+ preMemRead();
+ addiu(reg,offset);
+ memRead();
+ }
+
+ private boolean didPreMemRead;
+ private boolean preMemReadDoPreWrite;
+
+ private void preMemRead() { preMemRead(false); }
+ private void preMemRead(boolean preWrite) {
+ if(didPreMemRead) throw new Error("pending preMemRead");
+ didPreMemRead = true;
+ preMemReadDoPreWrite = preWrite;
+ if(onePage)
+ a(InstructionConstants.ALOAD_2);
+ else if(fastMem)
+ a(InstructionFactory.createLoad(Type.OBJECT,preWrite ? 3 : 2));
+ else
+ a(InstructionConstants.ALOAD_0);
+ }
+ // memRead pops an address off the stack, reads the value at that addr, and pushed the value
+ // preMemRead MUST be called BEFORE the addresses is pushed
+ private void memRead() { memRead(false); }
+
+ private void memRead(boolean addrInTmp) {
+ if(!didPreMemRead) throw new Error("didn't do preMemRead");
+ didPreMemRead = false;
+ if(preMemReadDoPreWrite)
+ memWriteStage=2;
+
+ if(nullPointerCheck) {
+ a(InstructionConstants.DUP);
+ a(InstructionConstants.ALOAD_0);
+ a(InstructionConstants.SWAP);
+ a(fac.createInvoke(fullClassName,"nullPointerCheck",Type.VOID,new Type[]{Type.INT},INVOKEVIRTUAL));
+ }
+
+ if(onePage) {
+ // p(target + "= page[(" + addr + ")>>>2];");
+ a(InstructionConstants.ICONST_2);
+ a(InstructionConstants.IUSHR);
+ if(preMemReadDoPreWrite)
+ a(InstructionConstants.DUP2);
+ a(InstructionConstants.IALOAD);
+ } else if(fastMem) {
+ //p(target + " = readPages[("+addr+")>>>"+pageShift+"][(("+addr+")>>>2)&"+toHex((pageSize>>2)-1)+"];");
+
+ if(!addrInTmp)
+ a(InstructionConstants.DUP_X1);
+ pushConst(pageShift);
+ a(InstructionConstants.IUSHR);
+ a(InstructionConstants.AALOAD);
+ if(addrInTmp)
+ pushTmp();
+ else
+ a(InstructionConstants.SWAP);
+ a(InstructionConstants.ICONST_2);
+ a(InstructionConstants.IUSHR);
+ pushConst((pageSize>>2)-1);
+ a(InstructionConstants.IAND);
+ if(preMemReadDoPreWrite)
+ a(InstructionConstants.DUP2);
+ a(InstructionConstants.IALOAD);
+
+ } else {
+ if(preMemReadDoPreWrite)
+ a(InstructionConstants.DUP2);
+ a(fac.createInvoke(fullClassName,"unsafeMemWrite",Type.INT,new Type[]{Type.INT},INVOKEVIRTUAL));
+ }
+ }
+
+
+ // This might come in handy for something else
+ /*private boolean touchesReg(int insn, int reg) {
+ if((reg < R+0 || reg >= R+32) && reg != FCSR) throw new IllegalArgumentException(""+reg);
+ if(reg == R+0) return false; // r0 is never modified
+ int op = (insn >>> 26) & 0xff; // bits 26-31
+ int subcode = insn & 0x3f; // bits 0-5
+ int rd = (insn >>> 11) & 0x1f; // bits 11-15
+ int rt = (insn >>> 16) & 0x1f; // bits 16-20
+ int rs = (insn >>> 21) & 0x1f; // bits 21-25
+
+ switch(op) {
+ case 0:
+ if(subcode >= 0 && subcode <= 7) return reg == R+rd; // Shift ops
+ if(subcode >= 32 && subcode <= 43) return reg == R+rd; // Other math ops
+ if(subcode >= 24 && subcode <= 27) return reg == HI || reg == LO; // MULT/DIV
+ break;
+ case 13: return false; // BREAK
+ case 17:
+ switch(rs) {
+ case 0: return reg == R+rt; // MFC.1
+ case 2: return reg == R+rt; // CFC.1
+ case 4: return false; // MTC.1
+ case 6: return false; // CTC.1
+ case 16: // Single
+ case 17: // Double
+ if(subcode == 50 || subcode == 60 || subcode == 62) return reg == FCSR;
+ return false; // everything else just touches f0-f31
+ case 20: return false; // Integer - just touches f0-f31
+ }
+ break;
+ default:
+ if(op >= 8 && op <= 15) return reg == R+rt; // XXXI instructions
+ if(op >= 40 && op <= 46) return false; // Memory WRITE ops
+ if(op == 49) return reg == F+rt; // LWC1
+ if(op == 57) return false; // SWC1
+ break;
+ }
+ warn.println("Unknown instruction in touchesReg()- assuming it modifies all regs " + op + " " + subcode);
+ new Exception().fillInStackTrace().printStackTrace(warn);
+ return true;
+ }*/
+}
--- /dev/null
+package org.xwt.mips;
+
+import java.io.*;
+
+// FEATURE: This is just a quick hack, it is really ugly and broken
+
+public class ClassLoader extends java.lang.ClassLoader {
+ public Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
+ Class c;
+ if(name.startsWith("mips.")) {
+ String path = name.substring(5).replace('.','/') + ".mips";
+ try {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ new ClassFileCompiler(path,name,bos).go();
+ bos.close();
+ byte[] buf = bos.toByteArray();
+ c = defineClass(name,buf,0,buf.length);
+ } catch(IOException e) {
+ throw new ClassNotFoundException(name);
+ } catch(Compiler.Exn e) {
+ throw new ClassNotFoundException(e.getMessage());
+ }
+ } else {
+ c = findSystemClass(name);
+ }
+
+ if(c == null) throw new ClassNotFoundException(name);
+ if(resolve) resolveClass(c);
+ return c;
+ }
+
+ public Class classFromBinary(String path) throws ClassNotFoundException {
+ if(!path.endsWith(".mips")) throw new IllegalArgumentException("isn't a .mips");
+ return loadClass("mips." + path.substring(0,path.length()-5).replace('/','.'));
+ }
+
+ public Runtime runtimeFromBinary(String path) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
+ return (Runtime) classFromBinary(path).newInstance();
+ }
+
+ public static void main(String[] args) throws Exception {
+ System.exit(new ClassLoader().runtimeFromBinary(args[0]).run(args));
+ }
+}
--- /dev/null
+// Copyright 2003 Adam Megacz, see the COPYING file for licensing [GPL]
+
+package org.xwt.mips;
+
+import java.util.*;
+import java.io.*;
+
+import org.xwt.mips.util.SeekableData;
+import org.xwt.mips.util.SeekableFile;
+
+public abstract class Compiler implements Registers {
+ /** The ELF binary being read */
+ protected ELF elf;
+
+ /** The name of the class beging generated */
+ protected final String fullClassName;
+
+ /** The name of the binary this class is begin generated from */
+ protected String source = "unknown.mips.binary";
+ public void setSource(String source) { this.source = source; }
+
+ /** Thrown when the compilation fails for some reason */
+ protected static class Exn extends Exception { public Exn(String s) { super(s); } }
+
+ // Set this to true to enable fast memory access
+ // When this is enabled a Java RuntimeException will be thrown when a page fault occures. When it is disabled
+ // a FaultException will be throw which is easier to catch and deal with, however. as the name implies, this is slower
+ protected boolean fastMem = true;
+
+ // This MUST be a power of two. If it is not horrible things will happen
+ // NOTE: This value can be much higher without breaking the classfile
+ // specs (around 1024) but Hotstop seems to do much better with smaller
+ // methods.
+ protected int maxInsnPerMethod = 128;
+
+ // non-configurable
+ protected int maxBytesPerMethod;
+ protected int methodMask;
+ protected int methodShift;
+ protected void maxInsnPerMethodInit() throws Exn {
+ if((maxInsnPerMethod&(maxInsnPerMethod-1)) != 0) throw new Exn("maxBytesPerMethod is not a power of two");
+ maxBytesPerMethod = maxInsnPerMethod*4;
+ methodMask = ~(maxBytesPerMethod-1);
+ while(maxBytesPerMethod>>>methodShift != 1) methodShift++;
+ }
+
+ // True to try to determine which case statement are needed and only include them
+ protected boolean pruneCases = true;
+
+ protected boolean assumeTailCalls = true;
+
+ protected boolean optimizedMemcpy = true;
+
+ // True to insert some code in the output to help diagnore compiler problems
+ protected boolean debugCompiler = false;
+
+ // True to print various statistics about the compilation
+ protected boolean printStats = false;
+
+ // True to generate runtime statistics that slow execution down significantly
+ protected boolean runtimeStats = false;
+
+ protected boolean supportCall = true;
+
+ protected boolean nullPointerCheck = false;
+
+ protected String runtimeClass = "org.xwt.mips.Runtime";
+
+ protected String hashClass = "java.util.Hashtable";
+
+ protected boolean unixRuntime;
+
+ protected boolean lessConstants = false;
+
+ protected int pageSize = 4096;
+ protected int totalPages = 65536;
+ protected int pageShift;
+ protected boolean onePage;
+
+ protected void pageSizeInit() throws Exn {
+ try {
+ Runtime.checkPageSize(pageSize,totalPages);
+ } catch(IllegalArgumentException e) {
+ throw new Exn(e.getMessage());
+ }
+ while(pageSize>>>pageShift != 1) pageShift++;
+ }
+
+ /** The address of the memcpy function in the binary (used for optimizedMemcpy) */
+ protected int memcpy;
+
+ /** The address of the memset function in the binary (used for optimizedMemcpy) */
+ protected int memset;
+
+ /** A set of all addresses that can be jumped too (only available if pruneCases == true) */
+ protected Set jumpableAddresses;
+
+ /** Some important symbols */
+ ELF.Symbol userInfo, gp;
+
+ private static void usage() {
+ System.err.println("Usage: java Compiler [-outfile output.java] [-o options] [-dumpoptions] <classname> <binary.mips>");
+ System.err.println("-o takes mount(8) like options and can be specified multiple times");
+ System.err.println("Available options:");
+ for(int i=0;i<options.length;i+=2)
+ System.err.print(options[i] + ": " + wrapAndIndent(options[i+1],18-2-options[i].length(),18,62));
+ System.exit(1);
+ }
+
+ public static void main(String[] args) throws IOException {
+ String outfile = null;
+ String o = null;
+ String className = null;
+ String mipsBinaryFileName = null;
+ String outformat = null;
+ boolean dumpOptions = false;
+ int arg = 0;
+ while(args.length-arg > 0) {
+ if(args[arg].equals("-outfile")) {
+ arg++;
+ if(arg==args.length) usage();
+ outfile = args[arg];
+ } else if(args[arg].equals("-outformat")) {
+ arg++;
+ if(arg==args.length) usage();
+ outformat = args[arg];
+ } else if(args[arg].equals("-o")) {
+ arg++;
+ if(arg==args.length) usage();
+ if(o==null || o.length() == 0)
+ o = args[arg];
+ else if(args[arg].length() != 0)
+ o += "," + args[arg];
+ } else if(args[arg].equals("-dumpoptions")) {
+ dumpOptions = true;
+ } else if(className == null) {
+ className = args[arg];
+ } else if(mipsBinaryFileName == null) {
+ mipsBinaryFileName = args[arg];
+ } else {
+ usage();
+ }
+ arg++;
+ }
+ if(className == null || mipsBinaryFileName == null) usage();
+
+ SeekableData mipsBinary = new SeekableFile(mipsBinaryFileName);
+
+ Writer w = null;
+ OutputStream os = null;
+ Compiler comp = null;
+ if(outformat == null || outformat.equals("class")) {
+ if(outfile == null) {
+ System.err.println("Refusing to write a classfile to stdout - use -outfile foo.class");
+ System.exit(1);
+ }
+ os = new FileOutputStream(outfile);
+ comp = new ClassFileCompiler(mipsBinary,className,os);
+ } else if(outformat.equals("javasource") || outformat .equals("java")) {
+ w = outfile == null ? new OutputStreamWriter(System.out): new FileWriter(outfile);
+ comp = new JavaSourceCompiler(mipsBinary,className,w);
+ } else {
+ System.err.println("Unknown output format: " + outformat);
+ System.exit(1);
+ }
+
+ comp.parseOptions(o);
+ comp.setSource(mipsBinaryFileName);
+
+ if(dumpOptions) {
+ System.err.println("== Options ==");
+ for(int i=0;i<options.length;i+=2)
+ System.err.println(options[i] + ": " + comp.getOption(options[i]).get());
+ System.err.println("== End Options ==");
+ }
+
+ try {
+ comp.go();
+ } catch(Exn e) {
+ System.err.println("Compiler Error: " + e.getMessage());
+ System.exit(1);
+ } finally {
+ if(w != null) w.close();
+ if(os != null) os.close();
+ }
+ }
+
+ public Compiler(SeekableData binary, String fullClassName) throws IOException {
+ this.fullClassName = fullClassName;
+ elf = new ELF(binary);
+
+ if(elf.header.type != ELF.ELFHeader.ET_EXEC) throw new IOException("Binary is not an executable");
+ if(elf.header.machine != ELF.ELFHeader.EM_MIPS) throw new IOException("Binary is not for the MIPS I Architecture");
+ if(elf.ident.data != ELF.ELFIdent.ELFDATA2MSB) throw new IOException("Binary is not big endian");
+ }
+
+ protected abstract void _go() throws Exn, IOException;
+
+ private boolean used;
+ public void go() throws Exn, IOException {
+ if(used) throw new RuntimeException("Compiler instances are good for one shot only");
+ used = true;
+
+ if(onePage && pageSize <= 4096) pageSize = 4*1024*1024;
+ if(nullPointerCheck && !fastMem) throw new Exn("fastMem must be enabled for nullPointerCheck to be of any use");
+ if(onePage && !fastMem) throw new Exn("fastMem must be enabled for onePage to be of any use");
+ if(totalPages == 1 && !onePage) throw new Exn("totalPages == 1 and onePage is not set");
+ if(onePage) totalPages = 1;
+
+ maxInsnPerMethodInit();
+ pageSizeInit();
+
+ // Get a copy of the symbol table in the elf binary
+ ELF.Symtab symtab = elf.getSymtab();
+ if(symtab == null) throw new Exn("Binary has no symtab (did you strip it?)");
+ ELF.Symbol sym;
+
+ // Check for some functions we can override
+ sym = symtab.getGlobalSymbol("memcpy");
+ memcpy = sym == null ? -1 : sym.addr;
+
+ sym = symtab.getGlobalSymbol("memset");
+ memset = sym == null ? -1 : sym.addr;
+
+ userInfo = symtab.getGlobalSymbol("user_info");
+ gp = symtab.getGlobalSymbol("_gp");
+ if(gp == null) throw new Exn("no _gp symbol (did you strip the binary?)");
+
+ if(pruneCases) {
+ // Find all possible branches
+ jumpableAddresses = new HashSet();
+
+ jumpableAddresses.add(new Integer(elf.header.entry));
+
+ ELF.SHeader text = elf.sectionWithName(".text");
+ if(text == null) throw new Exn("No .text segment");
+
+ findBranchesInSymtab(symtab,jumpableAddresses);
+
+ for(int i=0;i<elf.sheaders.length;i++) {
+ ELF.SHeader sheader = elf.sheaders[i];
+ String name = sheader.name;
+ // if this section doesn't get loaded into our address space don't worry about it
+ if(sheader.addr == 0x0) continue;
+ if(name.equals(".data") || name.equals(".sdata") || name.equals(".rodata") || name.equals(".ctors") || name.equals(".dtors"))
+ findBranchesInData(new DataInputStream(sheader.getInputStream()),sheader.size,jumpableAddresses,text.addr,text.addr+text.size);
+ }
+
+ findBranchesInText(text.addr,new DataInputStream(text.getInputStream()),text.size,jumpableAddresses);
+ }
+
+ if(unixRuntime && runtimeClass.startsWith("org.xwt.mips.")) runtimeClass = "org.xwt.mips.UnixRuntime";
+
+ for(int i=0;i<elf.sheaders.length;i++) {
+ String name = elf.sheaders[i].name;
+ if(elf.sheaders[i].addr != 0 && !(
+ name.equals(".text")|| name.equals(".data") || name.equals(".sdata") || name.equals(".rodata") ||
+ name.equals(".ctors") || name.equals(".dtors") || name.equals(".bss") || name.equals(".sbss")))
+ throw new Exn("Unknown section: " + name);
+ }
+ _go();
+ }
+
+ private void findBranchesInSymtab(ELF.Symtab symtab, Set jumps) {
+ ELF.Symbol[] symbols = symtab.symbols;
+ int n=0;
+ for(int i=0;i<symbols.length;i++) {
+ ELF.Symbol s = symbols[i];
+ if(s.type == ELF.Symbol.STT_FUNC) {
+ if(jumps.add(new Integer(s.addr))) {
+ //System.err.println("Adding symbol from symtab: " + s.name + " at " + toHex(s.addr));
+ n++;
+ }
+ }
+ }
+ if(printStats) System.err.println("Found " + n + " additional possible branch targets in Symtab");
+ }
+
+ private void findBranchesInText(int base, DataInputStream dis, int size, Set jumps) throws IOException {
+ int count = size/4;
+ int pc = base;
+ int n=0;
+ int[] lui_val = new int[32];
+ int[] lui_pc = new int[32];
+ //Interpreter inter = new Interpreter(source);
+
+ for(int i=0;i<count;i++,pc+=4) {
+ int insn = dis.readInt();
+ int op = (insn >>> 26) & 0xff;
+ int rs = (insn >>> 21) & 0x1f;
+ int rt = (insn >>> 16) & 0x1f;
+ int signedImmediate = (insn << 16) >> 16;
+ int unsignedImmediate = insn & 0xffff;
+ int branchTarget = signedImmediate;
+ int jumpTarget = (insn & 0x03ffffff);
+ int subcode = insn & 0x3f;
+
+ switch(op) {
+ case 0:
+ switch(subcode) {
+ case 9: // JALR
+ if(jumps.add(new Integer(pc+8))) n++; // return address
+ break;
+ case 12: // SYSCALL
+ if(jumps.add(new Integer(pc+4))) n++;
+ break;
+ }
+ break;
+ case 1:
+ switch(rt) {
+ case 16: // BLTZAL
+ case 17: // BGTZAL
+ if(jumps.add(new Integer(pc+8))) n++; // return address
+ // fall through
+ case 0: // BLTZ
+ case 1: // BGEZ
+ if(jumps.add(new Integer(pc+branchTarget*4+4))) n++;
+ break;
+ }
+ break;
+ case 3: // JAL
+ if(jumps.add(new Integer(pc+8))) n++; // return address
+ // fall through
+ case 2: // J
+ if(jumps.add(new Integer((pc&0xf0000000)|(jumpTarget << 2)))) n++;
+ break;
+ case 4: // BEQ
+ case 5: // BNE
+ case 6: // BLEZ
+ case 7: // BGTZ
+ if(jumps.add(new Integer(pc+branchTarget*4+4))) n++;
+ break;
+ case 9: { // ADDIU
+ if(pc - lui_pc[rs] <= 4*32) {
+ int t = (lui_val[rs]<<16)+signedImmediate;
+ if((t&3)==0 && t >= base && t < base+size) {
+ if(jumps.add(new Integer(t))) {
+ //System.err.println("Possible jump to " + toHex(t) + " (" + inter.sourceLine(t) + ") from " + toHex(pc) + " (" + inter.sourceLine(pc) + ")");
+ n++;
+ }
+ }
+ // we just blew it away
+ if(rt == rs) lui_pc[rs] = 0;
+ }
+ break;
+ }
+ case 15: { // LUI
+ lui_val[rt] = unsignedImmediate;
+ lui_pc[rt] = pc;
+ break;
+ }
+
+ case 17: // FPU Instructions
+ switch(rs) {
+ case 8: // BC1F, BC1T
+ if(jumps.add(new Integer(pc+branchTarget*4+4))) n++;
+ break;
+ }
+ break;
+ }
+ }
+ dis.close();
+ if(printStats) System.err.println("Found " + n + " additional possible branch targets in Text segment");
+ }
+
+ private void findBranchesInData(DataInputStream dis, int size, Set jumps, int textStart, int textEnd) throws IOException {
+ int count = size/4;
+ int n=0;
+ for(int i=0;i<count;i++) {
+ int word = dis.readInt();
+ if((word&3)==0 && word >= textStart && word < textEnd) {
+ if(jumps.add(new Integer(word))) {
+ //System.err.println("Added " + toHex(word) + " as possible branch target (fron data segment)");
+ n++;
+ }
+ }
+ }
+ dis.close();
+ if(n>0 && printStats) System.err.println("Found " + n + " additional possible branch targets in Data segment");
+ }
+
+ // Helper functions for pretty output
+ protected final static String toHex(int n) { return "0x" + Long.toString(n & 0xffffffffL, 16); }
+ protected final static String toHex8(int n) {
+ String s = Long.toString(n & 0xffffffffL, 16);
+ StringBuffer sb = new StringBuffer("0x");
+ for(int i=8-s.length();i>0;i--) sb.append('0');
+ sb.append(s);
+ return sb.toString();
+ }
+
+ protected final static String toOctal3(int n) {
+ char[] buf = new char[3];
+ for(int i=2;i>=0;i--) {
+ buf[i] = (char) ('0' + (n & 7));
+ n >>= 3;
+ }
+ return new String(buf);
+ }
+
+ // Option parsing
+ private class Option {
+ private java.lang.reflect.Field field;
+ public Option(String name) throws NoSuchFieldException { field = name==null ? null : Compiler.class.getDeclaredField(name); }
+ public void set(Object val) {
+ if(field == null) return;
+ try {
+ field.setAccessible(true);
+ field.set(Compiler.this,val);
+ } catch(IllegalAccessException e) {
+ System.err.println(e);
+ }
+ }
+ public Object get() {
+ if(field == null) return null;
+ try {
+ field.setAccessible(true);
+ return field.get(Compiler.this);
+ } catch(IllegalAccessException e) {
+ System.err.println(e); return null;
+ }
+ }
+ public Class getType() { return field == null ? null : field.getType(); }
+ }
+
+ private static String[] options = {
+ "fastMem", "Enable fast memory access - RuntimeExceptions will be thrown on faults",
+ "nullPointerCheck", "Enables checking at runtime for null pointer accessses (slows things down a bit, only applicable with fastMem)",
+ "maxInsnPerMethod", "Maximum number of MIPS instructions per java method (128 is optimal with Hotspot)",
+ "pruneCases", "Remove unnecessary case 0xAABCCDD blocks from methods - may break some weird code",
+ "assumeTailCalls", "Assume the JIT optimizes tail calls",
+ "optimizedMemcpy", "Use an optimized java version of memcpy where possible",
+ "debugCompiler", "Output information in the generated code for debugging the compiler - will slow down generated code significantly",
+ "printStats", "Output some useful statistics about the compilation",
+ "runtimeStats", "Keep track of some statistics at runtime in the generated code - will slow down generated code significantly",
+ "supportCall", "Keep a stripped down version of the symbol table in the generated code to support the call() method",
+ "runtimeClass", "Full classname of the Runtime class (default: Runtime) - use this is you put Runtime in a package",
+ "hashClass", "Full classname of a Hashtable class (default: java.util.HashMap) - this must support get() and put()",
+ "unixRuntime", "Use the UnixRuntime (has support for fork, wai, du, pipe, etc)",
+ "pageSize", "The page size (must be a power of two)",
+ "totalPages", "Total number of pages (total mem = pageSize*totalPages, must be a power of two)",
+ "onePage", "One page hack (FIXME: document this better)",
+ "lessConstants", "Use less constants at the cost of speed (FIXME: document this better)"
+ };
+
+ private Option getOption(String name) {
+ name = name.toLowerCase();
+ try {
+ for(int i=0;i<options.length;i+=2)
+ if(options[i].toLowerCase().equals(name))
+ return new Option(options[i]);
+ return null;
+ } catch(NoSuchFieldException e) {
+ return null;
+ }
+ }
+
+ public void parseOptions(String opts) {
+ if(opts == null || opts.length() == 0) return;
+ StringTokenizer st = new StringTokenizer(opts,",");
+ while(st.hasMoreElements()) {
+ String tok = st.nextToken();
+ String key;
+ String val;
+ if(tok.indexOf("=") != -1) {
+ key = tok.substring(0,tok.indexOf("="));
+ val = tok.substring(tok.indexOf("=")+1);
+ } else if(tok.startsWith("no")) {
+ key = tok.substring(2);
+ val = "false";
+ } else {
+ key = tok;
+ val = "true";
+ }
+ Option opt = getOption(key);
+ if(opt == null) {
+ System.err.println("WARNING: No such option: " + key);
+ continue;
+ }
+
+ if(opt.getType() == String.class)
+ opt.set(val);
+ else if(opt.getType() == Integer.TYPE)
+ try {
+ opt.set(parseInt(val));
+ } catch(NumberFormatException e) {
+ System.err.println("WARNING: " + val + " is not an integer");
+ }
+ else if(opt.getType() == Boolean.TYPE)
+ opt.set(new Boolean(val.toLowerCase().equals("true")||val.toLowerCase().equals("yes")));
+ else
+ throw new Error("Unknown type: " + opt.getType());
+ }
+ }
+
+ private static Integer parseInt(String s) {
+ int mult = 1;
+ s = s.toLowerCase();
+ if(!s.startsWith("0x") && s.endsWith("m")) { s = s.substring(0,s.length()-1); mult = 1024*1024; }
+ else if(!s.startsWith("0x") && s.endsWith("k")) { s = s.substring(0,s.length()-1); mult = 1024; }
+ int n;
+ if(s.length() > 2 && s.startsWith("0x")) n = Integer.parseInt(s.substring(2),16);
+ else n = Integer.parseInt(s);
+ return new Integer(n*mult);
+ }
+
+ private static String wrapAndIndent(String s, int firstindent, int indent, int width) {
+ StringTokenizer st = new StringTokenizer(s," ");
+ StringBuffer sb = new StringBuffer();
+ for(int i=0;i<firstindent;i++)
+ sb.append(' ');
+ int sofar = 0;
+ while(st.hasMoreTokens()) {
+ String tok = st.nextToken();
+ if(tok.length() + sofar + 1 > width && sofar > 0) {
+ sb.append('\n');
+ for(int i=0;i<indent;i++) sb.append(' ');
+ sofar = 0;
+ } else if(sofar > 0) {
+ sb.append(' ');
+ sofar++;
+ }
+ sb.append(tok);
+ sofar += tok.length();
+ }
+ sb.append('\n');
+ return sb.toString();
+ }
+
+ // This ugliness is to work around a gcj static linking bug (Bug 12908)
+ // The best solution is to force gnu.java.locale.Calendar to be linked in but this'll do
+ protected static String dateTime() {
+ try {
+ return new Date().toString();
+ } catch(RuntimeException e) {
+ return "<unknown>";
+ }
+ }
+}
+
--- /dev/null
+package org.xwt.mips;
+
+import org.xwt.mips.util.*;
+import java.io.*;
+
+public class ELF {
+ private SeekableData data;
+
+ public ELFIdent ident;
+ public ELFHeader header;
+ public PHeader[] pheaders;
+ public SHeader[] sheaders;
+
+ private byte[] stringTable;
+
+ private boolean sectionReaderActive;
+
+
+ private void readFully(byte[] buf) throws IOException {
+ int len = buf.length;
+ int pos = 0;
+ while(len > 0) {
+ int n = data.read(buf,pos,len);
+ if(n == -1) throw new IOException("EOF");
+ pos += n;
+ len -= n;
+ }
+ }
+
+ private int readIntBE() throws IOException {
+ byte[] buf = new byte[4];
+ readFully(buf);
+ return ((buf[0]&0xff)<<24)|((buf[1]&0xff)<<16)|((buf[2]&0xff)<<8)|((buf[3]&0xff)<<0);
+ }
+ private int readInt() throws IOException {
+ int x = readIntBE();
+ if(ident!=null && ident.data == ELFIdent.ELFDATA2LSB)
+ x = ((x<<24)&0xff000000) | ((x<<8)&0xff0000) | ((x>>>8)&0xff00) | ((x>>24)&0xff);
+ return x;
+ }
+
+ private short readShortBE() throws IOException {
+ byte[] buf = new byte[2];
+ readFully(buf);
+ return (short)(((buf[0]&0xff)<<8)|((buf[1]&0xff)<<0));
+ }
+ private short readShort() throws IOException {
+ short x = readShortBE();
+ if(ident!=null && ident.data == ELFIdent.ELFDATA2LSB)
+ x = (short)((((x<<8)&0xff00) | ((x>>8)&0xff))&0xffff);
+ return x;
+ }
+
+ private byte readByte() throws IOException {
+ byte[] buf = new byte[1];
+ readFully(buf);
+ return buf[0];
+ }
+
+ public class ELFIdent {
+ private static final int ELF_MAGIC = 0x7f454c46; // '\177', 'E', 'L', 'F'
+
+ public static final int ELFCLASSNONE = 0;
+ public static final int ELFCLASS32 = 1;
+ public static final int ELFCLASS64 = 2;
+ public byte klass;
+
+
+ public static final int ELFDATANONE = 0;
+ public static final int ELFDATA2LSB = 1;
+ public static final int ELFDATA2MSB = 2;
+ public byte data;
+ public byte osabi;
+ public byte abiversion;
+
+ ELFIdent() throws IOException {
+ if(readIntBE() != ELF_MAGIC) throw new ELFException("Bad Magic (is: " );
+
+ klass = readByte();
+ if(klass != ELFCLASS32) throw new ELFException("org.xwt.mips.ELF does not suport 64-bit binaries");
+
+ data = readByte();
+ if(data != ELFDATA2LSB && data != ELFDATA2MSB) throw new ELFException("Unknown byte order");
+
+ readByte(); // version
+ osabi = readByte();
+ abiversion = readByte();
+ for(int i=0;i<7;i++) readByte(); // padding
+ }
+ }
+
+ public class ELFHeader {
+ public static final short ET_EXEC = 2;
+ public short type;
+
+ public static final short EM_MIPS = 8;
+ public short machine;
+
+ public int version;
+ public int entry;
+ public int phoff;
+ public int shoff;
+ public int flags;
+ public short ehsize;
+ public short phentsize;
+ public short phnum;
+ public short shentsize;
+ public short shnum;
+ public short shstrndx;
+
+ ELFHeader() throws IOException {
+ type = readShort();
+ machine = readShort();
+ version = readInt();
+ if(version != 1) throw new ELFException("version != 1");
+ entry = readInt();
+ phoff = readInt();
+ shoff = readInt();
+ flags = readInt();
+ ehsize = readShort();
+ phentsize = readShort();
+ phnum = readShort();
+ shentsize = readShort();
+ shnum = readShort();
+ shstrndx = readShort();
+ }
+ }
+
+ public class PHeader {
+ public int type;
+ public int offset;
+ public int vaddr;
+ public int paddr;
+ public int filesz;
+ public int memsz;
+ public int flags;
+ public int align;
+
+ public static final int PF_X = 0x1;
+ public static final int PF_W = 0x2;
+ public static final int PF_R = 0x4;
+
+ public static final int PT_LOAD = 1;
+
+ PHeader() throws IOException {
+ type = readInt();
+ offset = readInt();
+ vaddr = readInt();
+ paddr = readInt();
+ filesz = readInt();
+ memsz = readInt();
+ flags = readInt();
+ align = readInt();
+ if(filesz > memsz) throw new ELFException("ELF inconsistency: filesz > memsz (" + toHex(filesz) + " > " + toHex(memsz) + ")");
+ }
+
+ public boolean writable() { return (flags & PF_W) != 0; }
+
+ public InputStream getInputStream() throws IOException {
+ return new BufferedInputStream(new SectionInputStream(
+ offset,offset+filesz));
+ }
+ }
+
+ public class SHeader {
+ int nameidx;
+ public String name;
+ public int type;
+ public int flags;
+ public int addr;
+ public int offset;
+ public int size;
+ public int link;
+ public int info;
+ public int addralign;
+ public int entsize;
+
+ public static final int SHT_SYMTAB = 2;
+ public static final int SHT_STRTAB = 3;
+ public static final int SHT_NOBITS = 8;
+
+ SHeader() throws IOException {
+ nameidx = readInt();
+ type = readInt();
+ flags = readInt();
+ addr = readInt();
+ offset = readInt();
+ size = readInt();
+ link = readInt();
+ info = readInt();
+ addralign = readInt();
+ entsize = readInt();
+ }
+
+ public InputStream getInputStream() throws IOException {
+ return new BufferedInputStream(new SectionInputStream(
+ offset, type == SHT_NOBITS ? 0 : offset+size));
+ }
+
+ public boolean isText() { return name.equals(".text"); }
+ public boolean isData() { return name.equals(".data") || name.equals(".sdata") || name.equals(".rodata") || name.equals(".ctors") || name.equals(".dtors"); }
+ public boolean isBSS() { return name.equals(".bss") || name.equals(".sbss"); }
+ }
+
+ public ELF(String file) throws IOException, ELFException { this(new SeekableFile(file,false)); }
+ public ELF(SeekableData data) throws IOException, ELFException {
+ this.data = data;
+ ident = new ELFIdent();
+ header = new ELFHeader();
+ pheaders = new PHeader[header.phnum];
+ for(int i=0;i<header.phnum;i++) {
+ data.seek(header.phoff+i*header.phentsize);
+ pheaders[i] = new PHeader();
+ }
+ sheaders = new SHeader[header.shnum];
+ for(int i=0;i<header.shnum;i++) {
+ data.seek(header.shoff+i*header.shentsize);
+ sheaders[i] = new SHeader();
+ }
+ if(header.shstrndx < 0 || header.shstrndx >= header.shnum) throw new ELFException("Bad shstrndx");
+ data.seek(sheaders[header.shstrndx].offset);
+ stringTable = new byte[sheaders[header.shstrndx].size];
+ readFully(stringTable);
+
+ for(int i=0;i<header.shnum;i++) {
+ SHeader s = sheaders[i];
+ s.name = getString(s.nameidx);
+ }
+ }
+
+ private String getString(int off) { return getString(off,stringTable); }
+ private String getString(int off,byte[] strtab) {
+ StringBuffer sb = new StringBuffer();
+ if(off < 0 || off >= strtab.length) return "<invalid strtab entry>";
+ while(off >= 0 && off < strtab.length && strtab[off] != 0) sb.append((char)strtab[off++]);
+ return sb.toString();
+ }
+
+ public SHeader sectionWithName(String name) {
+ for(int i=0;i<sheaders.length;i++)
+ if(sheaders[i].name.equals(name))
+ return sheaders[i];
+ return null;
+ }
+
+ public class ELFException extends IOException { ELFException(String s) { super(s); } }
+
+ private class SectionInputStream extends InputStream {
+ private int pos;
+ private int maxpos;
+ SectionInputStream(int start, int end) throws IOException {
+ if(sectionReaderActive)
+ throw new IOException("Section reader already active");
+ sectionReaderActive = true;
+ pos = start;
+ data.seek(pos);
+ maxpos = end;
+ }
+
+ private int bytesLeft() { return maxpos - pos; }
+ public int read() throws IOException {
+ byte[] buf = new byte[1];
+ return read(buf,0,1) == -1 ? -1 : (buf[0]&0xff);
+ }
+ public int read(byte[] b, int off, int len) throws IOException {
+ int n = data.read(b,off,Math.min(len,bytesLeft())); if(n > 0) pos += n; return n;
+ }
+ public void close() { sectionReaderActive = false; }
+ }
+
+ private Symtab _symtab;
+ public Symtab getSymtab() throws IOException {
+ if(_symtab != null) return _symtab;
+
+ if(sectionReaderActive) throw new ELFException("Can't read the symtab while a section reader is active");
+
+ SHeader sh = sectionWithName(".symtab");
+ if(sh == null || sh.type != SHeader.SHT_SYMTAB) return null;
+
+ SHeader sth = sectionWithName(".strtab");
+ if(sth == null || sth.type != SHeader.SHT_STRTAB) return null;
+
+ byte[] strtab = new byte[sth.size];
+ DataInputStream dis = new DataInputStream(sth.getInputStream());
+ dis.readFully(strtab);
+ dis.close();
+
+ return _symtab = new Symtab(sh.offset, sh.size,strtab);
+ }
+
+ public class Symtab {
+ public Symbol[] symbols;
+
+ Symtab(int off, int size, byte[] strtab) throws IOException {
+ data.seek(off);
+ int count = size/16;
+ symbols = new Symbol[count];
+ for(int i=0;i<count;i++) symbols[i] = new Symbol(strtab);
+ }
+
+ public Symbol getSymbol(String name) {
+ Symbol sym = null;
+ for(int i=0;i<symbols.length;i++) {
+ if(symbols[i].name.equals(name)) {
+ if(sym == null)
+ sym = symbols[i];
+ else
+ System.err.println("WARNING: Multiple symbol matches for " + name);
+ }
+ }
+ return sym;
+ }
+
+ public Symbol getGlobalSymbol(String name) {
+ for(int i=0;i<symbols.length;i++)
+ if(symbols[i].binding == Symbol.STB_GLOBAL && symbols[i].name.equals(name))
+ return symbols[i];
+ return null;
+ }
+ }
+
+ public class Symbol {
+ public String name;
+ public int addr;
+ public int size;
+ public byte info;
+ public byte type;
+ public byte binding;
+ public byte other;
+ public SHeader sheader;
+
+ public final static int STT_FUNC = 2;
+ public final static int STB_GLOBAL = 1;
+
+ Symbol(byte[] strtab) throws IOException {
+ name = getString(readInt(),strtab);
+ addr = readInt();
+ size = readInt();
+ info = readByte();
+ type = (byte)(info&0xf);
+ binding = (byte)(info>>4);
+ other = readByte();
+ // FEATURE: This should point to some other entry or something
+ readShort();
+ }
+ }
+
+ private static String toHex(int n) { return "0x" + Long.toString(n & 0xffffffffL, 16); }
+
+ public static void main(String[] args) throws IOException {
+ ELF elf = new ELF(new SeekableInputStream(new FileInputStream(args[0])));
+ System.out.println("Type: " + toHex(elf.header.type));
+ System.out.println("Machine: " + toHex(elf.header.machine));
+ System.out.println("Entry: " + toHex(elf.header.entry));
+ for(int i=0;i<elf.pheaders.length;i++) {
+ ELF.PHeader ph = elf.pheaders[i];
+ System.out.println("PHeader " + toHex(i));
+ System.out.println("\tOffset: " + ph.offset);
+ System.out.println("\tVaddr: " + toHex(ph.vaddr));
+ System.out.println("\tFile Size: " + ph.filesz);
+ System.out.println("\tMem Size: " + ph.memsz);
+ }
+ for(int i=0;i<elf.sheaders.length;i++) {
+ ELF.SHeader sh = elf.sheaders[i];
+ System.out.println("SHeader " + toHex(i));
+ System.out.println("\tName: " + sh.name);
+ System.out.println("\tOffset: " + sh.offset);
+ System.out.println("\tAddr: " + toHex(sh.addr));
+ System.out.println("\tSize: " + sh.size);
+ System.out.println("\tType: " + toHex(sh.type));
+ }
+ Symtab symtab = elf.getSymtab();
+ if(symtab != null) {
+ System.out.println("Symbol table:");
+ for(int i=0;i<symtab.symbols.length;i++)
+ System.out.println("\t" + symtab.symbols[i].name + " -> " + toHex(symtab.symbols[i].addr));
+ } else {
+ System.out.println("Symbol table: None");
+ }
+ }
+}
--- /dev/null
+// Copyright 2003 Brian Alliet
+// Based on org.xwt.imp.MIPS by Adam Megacz
+// Portions Copyright 2003 Adam Megacz
+
+package org.xwt.mips;
+
+import org.xwt.mips.util.*;
+import java.io.*;
+
+public class Interpreter extends UnixRuntime {
+ // Registers
+ private int[] registers = new int[32];
+ private int hi,lo;
+
+ // Floating Point Registers
+ private int[] fpregs = new int[32];
+ // 24-31 - unused
+ // 23 - conditional bit
+ // 18-22 - unused
+ // 12-17 - cause bits (unimplemented)
+ // 7-11 - enables bits (unimplemented)
+ // 2-6 - flags (unimplemented)
+ // 0-1 - rounding mode (only implemented for fixed point conversions)
+ private int fcsr;
+
+ private int pc;
+
+ // The filename if the binary we're running
+ public String image;
+ private ELF.Symtab symtab;
+
+ // Register Operations
+ private final void setFC(boolean b) { fcsr = (fcsr&~0x800000) | (b ? 0x800000 : 0x000000); }
+ private final int roundingMode() { return fcsr & 3; /* bits 0-1 */ }
+ private final double getDouble(int r) {
+ return Double.longBitsToDouble(((fpregs[r+1]&0xffffffffL) << 32) | (fpregs[r]&0xffffffffL));
+ }
+ private final void setDouble(int r, double d) {
+ long l = Double.doubleToLongBits(d);
+ fpregs[r+1] = (int)(l >>> 32); fpregs[r] = (int)l;
+ }
+ private final float getFloat(int r) { return Float.intBitsToFloat(fpregs[r]); }
+ private final void setFloat(int r, float f) { fpregs[r] = Float.floatToRawIntBits(f); }
+
+ protected void _execute() throws ExecutionException {
+ try {
+ runSome();
+ } catch(ExecutionException e) {
+ e.setLocation(toHex(pc) + ": " + sourceLine(pc));
+ throw e;
+ }
+ }
+
+ // Main interpretor
+ // the return value is meaningless, its just to catch people typing "return" by accident
+ private final int runSome() throws FaultException,ExecutionException {
+ int[] r = registers;
+ int[] f = fpregs;
+ int pc = this.pc;
+ int nextPC = pc + 4;
+ try {
+ OUTER: for(;;) {
+ int insn;
+ try {
+ insn = readPages[pc>>>PAGE_SHIFT][(pc>>>2)&PAGE_WORDS-1];
+ } catch (RuntimeException e) {
+ insn = memRead(pc);
+ }
+
+ int op = (insn >>> 26) & 0xff; // bits 26-31
+ int rs = (insn >>> 21) & 0x1f; // bits 21-25
+ int rt = (insn >>> 16) & 0x1f; // bits 16-20
+ int ft = (insn >>> 16) & 0x1f;
+ int rd = (insn >>> 11) & 0x1f; // bits 11-15
+ int fs = (insn >>> 11) & 0x1f;
+ int shamt = (insn >>> 6) & 0x1f; // bits 6-10
+ int fd = (insn >>> 6) & 0x1f;
+ int subcode = insn & 0x3f; // bits 0-5
+
+ int jumpTarget = (insn & 0x03ffffff); // bits 0-25
+ int unsignedImmediate = insn & 0xffff;
+ int signedImmediate = (insn << 16) >> 16;
+ int branchTarget = signedImmediate;
+
+ int tmp, addr; // temporaries
+
+ r[ZERO] = 0;
+
+ switch(op) {
+ case 0: {
+ switch(subcode) {
+ case 0: // SLL
+ if(insn == 0) break;
+ r[rd] = r[rt] << shamt;
+ break;
+ case 2: // SRL
+ r[rd] = r[rt] >>> shamt;
+ break;
+ case 3: // SRA
+ r[rd] = r[rt] >> shamt;
+ break;
+ case 4: // SLLV
+ r[rd] = r[rt] << (r[rs]&0x1f);
+ break;
+ case 6: // SRLV
+ r[rd] = r[rt] >>> (r[rs]&0x1f);
+ break;
+ case 7: // SRAV
+ r[rd] = r[rt] >> (r[rs]&0x1f);
+ break;
+ case 8: // JR
+ tmp = r[rs]; pc += 4; nextPC = tmp;
+ continue OUTER;
+ case 9: // JALR
+ tmp = r[rs]; pc += 4; r[rd] = pc+4; nextPC = tmp;
+ continue OUTER;
+ case 12: // SYSCALL
+ this.pc = pc;
+ r[V0] = syscall(r[V0],r[A0],r[A1],r[A2],r[A3]);
+ if(state != RUNNING) { this.pc = nextPC; break OUTER; }
+ break;
+ case 13: // BREAK
+ throw new ExecutionException("Break");
+ case 16: // MFHI
+ r[rd] = hi;
+ break;
+ case 17: // MTHI
+ hi = r[rs];
+ break;
+ case 18: // MFLO
+ r[rd] = lo;
+ break;
+ case 19: // MTLO
+ lo = r[rs];
+ break;
+ case 24: { // MULT
+ long hilo = (long)(r[rs]) * ((long)r[rt]);
+ hi = (int) (hilo >>> 32);
+ lo = (int) hilo;
+ break;
+ }
+ case 25: { // MULTU
+ long hilo = (r[rs] & 0xffffffffL) * (r[rt] & 0xffffffffL);
+ hi = (int) (hilo >>> 32);
+ lo = (int) hilo;
+ break;
+ }
+ case 26: // DIV
+ hi = r[rs]%r[rt];
+ lo = r[rs]/r[rt];
+ break;
+ case 27: // DIVU
+ if(rt != 0) {
+ hi = (int)((r[rs] & 0xffffffffL) % (r[rt] & 0xffffffffL));
+ lo = (int)((r[rs] & 0xffffffffL) / (r[rt] & 0xffffffffL));
+ }
+ break;
+ case 32: // ADD
+ throw new ExecutionException("ADD (add with oveflow trap) not suported");
+ /*This must trap on overflow
+ r[rd] = r[rs] + r[rt];
+ break;*/
+ case 33: // ADDU
+ r[rd] = r[rs] + r[rt];
+ break;
+ case 34: // SUB
+ throw new ExecutionException("SUB (sub with oveflow trap) not suported");
+ /*This must trap on overflow
+ r[rd] = r[rs] - r[rt];
+ break;*/
+ case 35: // SUBU
+ r[rd] = r[rs] - r[rt];
+ break;
+ case 36: // AND
+ r[rd] = r[rs] & r[rt];
+ break;
+ case 37: // OR
+ r[rd] = r[rs] | r[rt];
+ break;
+ case 38: // XOR
+ r[rd] = r[rs] ^ r[rt];
+ break;
+ case 39: // NOR
+ r[rd] = ~(r[rs] | r[rt]);
+ break;
+ case 42: // SLT
+ r[rd] = r[rs] < r[rt] ? 1 : 0;
+ break;
+ case 43: // SLTU
+ r[rd] = ((r[rs] & 0xffffffffL) < (r[rt] & 0xffffffffL)) ? 1 : 0;
+ break;
+ default:
+ throw new ExecutionException("Illegal instruction 0/" + subcode);
+ }
+ break;
+ }
+ case 1: {
+ switch(rt) {
+ case 0: // BLTZ
+ if(r[rs] < 0) {
+ pc += 4; tmp = pc + branchTarget*4; nextPC = tmp;
+ continue OUTER;
+ }
+ break;
+ case 1: // BGEZ
+ if(r[rs] >= 0) {
+ pc += 4; tmp = pc + branchTarget*4; nextPC = tmp;
+ continue OUTER;
+ }
+ break;
+ case 16: // BLTZAL
+ if(r[rs] < 0) {
+ pc += 4; r[RA] = pc+4; tmp = pc + branchTarget*4; nextPC = tmp;
+ continue OUTER;
+ }
+ break;
+ case 17: // BGEZAL
+ if(r[rs] >= 0) {
+ pc += 4; r[RA] = pc+4; tmp = pc + branchTarget*4; nextPC = tmp;
+ continue OUTER;
+ }
+ break;
+ default:
+ throw new ExecutionException("Illegal Instruction");
+ }
+ break;
+ }
+ case 2: { // J
+ tmp = (pc&0xf0000000) | (jumpTarget << 2);
+ pc+=4; nextPC = tmp;
+ continue OUTER;
+ }
+ case 3: { // JAL
+ tmp = (pc&0xf0000000) | (jumpTarget << 2);
+ pc+=4; r[RA] = pc+4; nextPC = tmp;
+ continue OUTER;
+ }
+ case 4: // BEQ
+ if(r[rs] == r[rt]) {
+ pc += 4; tmp = pc + branchTarget*4; nextPC = tmp;
+ continue OUTER;
+ }
+ break;
+ case 5: // BNE
+ if(r[rs] != r[rt]) {
+ pc += 4; tmp = pc + branchTarget*4; nextPC = tmp;
+ continue OUTER;
+ }
+ break;
+ case 6: //BLEZ
+ if(r[rs] <= 0) {
+ pc += 4; tmp = pc + branchTarget*4; nextPC = tmp;
+ continue OUTER;
+ }
+ break;
+ case 7: //BGTZ
+ if(r[rs] > 0) {
+ pc += 4; tmp = pc + branchTarget*4; nextPC = tmp;
+ continue OUTER;
+ }
+ break;
+ case 8: // ADDI
+ r[rt] = r[rs] + signedImmediate;
+ break;
+ case 9: // ADDIU
+ r[rt] = r[rs] + signedImmediate;
+ break;
+ case 10: // SLTI
+ r[rt] = r[rs] < signedImmediate ? 1 : 0;
+ break;
+ case 11: // SLTIU
+ r[rt] = (r[rs]&0xffffffffL) < (unsignedImmediate&0xffffffffL) ? 1 : 0;
+ break;
+ case 12: // ANDI
+ r[rt] = r[rs] & unsignedImmediate;
+ break;
+ case 13: // ORI
+ r[rt] = r[rs] | unsignedImmediate;
+ break;
+ case 14: // XORI
+ r[rt] = r[rs] ^ unsignedImmediate;
+ break;
+ case 15: // LUI
+ r[rt] = unsignedImmediate << 16;
+ break;
+ case 16:
+ throw new ExecutionException("TLB/Exception support not implemented");
+ case 17: { // FPU
+ boolean debug = false;
+ String line = debug ? sourceLine(pc) : "";
+ boolean debugon = debug && (line.indexOf("dtoa.c:51") >= 0 || line.indexOf("dtoa.c:52") >= 0 || line.indexOf("test.c") >= 0);
+ if(rs > 8 && debugon)
+ System.out.println(" FP Op: " + op + "/" + rs + "/" + subcode + " " + line);
+ if(roundingMode() != 0 && rs != 6 /*CTC.1*/ && !((rs==16 || rs==17) && subcode == 36 /* CVT.W.Z */))
+ throw new ExecutionException("Non-cvt.w.z operation attempted with roundingMode != round to nearest");
+ switch(rs) {
+ case 0: // MFC.1
+ r[rt] = f[rd];
+ break;
+ case 2: // CFC.1
+ if(fs != 31) throw new ExecutionException("FCR " + fs + " unavailable");
+ r[rt] = fcsr;
+ break;
+ case 4: // MTC.1
+ f[rd] = r[rt];
+ break;
+ case 6: // CTC.1
+ if(fs != 31) throw new ExecutionException("FCR " + fs + " unavailable");
+ fcsr = r[rt];
+ break;
+ case 8: // BC1F, BC1T
+ if(((fcsr&0x800000)!=0) == (((insn>>>16)&1)!=0)) {
+ pc += 4; tmp = pc + branchTarget*4; nextPC = tmp;
+ continue OUTER;
+ }
+ break;
+ case 16: { // Single
+ switch(subcode) {
+ case 0: // ADD.S
+ setFloat(fd,getFloat(fs)+getFloat(ft));
+ break;
+ case 1: // SUB.S
+ setFloat(fd,getFloat(fs)-getFloat(ft));
+ break;
+ case 2: // MUL.S
+ setFloat(fd,getFloat(fs)*getFloat(ft));
+ break;
+ case 3: // DIV.S
+ setFloat(fd,getFloat(fs)/getFloat(ft));
+ break;
+ case 5: // ABS.S
+ setFloat(fd,Math.abs(getFloat(fs)));
+ break;
+ case 6: // MOV.S
+ f[fd] = f[fs];
+ break;
+ case 7: // NEG.S
+ setFloat(fd,-getFloat(fs));
+ break;
+ case 33: // CVT.D.S
+ setDouble(fd,getFloat(fs));
+ break;
+ case 36: // CVT.W.S
+ switch(roundingMode()) {
+ case 0: f[fd] = (int)Math.floor(getFloat(fs)+0.5f); break; // Round to nearest
+ case 1: f[fd] = (int)getFloat(fs); break; // Round towards zero
+ case 2: f[fd] = (int)Math.ceil(getFloat(fs)); break; // Round towards plus infinity
+ case 3: f[fd] = (int)Math.floor(getFloat(fs)); break; // Round towards minus infinity
+ }
+ break;
+ case 50: // C.EQ.S
+ setFC(getFloat(fs) == getFloat(ft));
+ break;
+ case 60: // C.LT.S
+ setFC(getFloat(fs) < getFloat(ft));
+ break;
+ default: throw new ExecutionException("Invalid Instruction 17/" + rs + "/" + subcode + " at " + sourceLine(pc));
+ }
+ break;
+ }
+ case 17: { // Double
+ switch(subcode) {
+ case 0: // ADD.D
+ setDouble(fd,getDouble(fs)+getDouble(ft));
+ break;
+ case 1: // SUB.D
+ if(debugon) System.out.println("f" + fd + " = f" + fs + " (" + getDouble(fs) + ") - f" + ft + " (" + getDouble(ft) + ")");
+ setDouble(fd,getDouble(fs)-getDouble(ft));
+ break;
+ case 2: // MUL.D
+ if(debugon) System.out.println("f" + fd + " = f" + fs + " (" + getDouble(fs) + ") * f" + ft + " (" + getDouble(ft) + ")");
+ setDouble(fd,getDouble(fs)*getDouble(ft));
+ if(debugon) System.out.println("f" + fd + " = " + getDouble(fd));
+ break;
+ case 3: // DIV.D
+ setDouble(fd,getDouble(fs)/getDouble(ft));
+ break;
+ case 5: // ABS.D
+ setDouble(fd,Math.abs(getDouble(fs)));
+ break;
+ case 6: // MOV.D
+ f[fd] = f[fs];
+ f[fd+1] = f[fs+1];
+ break;
+ case 7: // NEG.D
+ setDouble(fd,-getDouble(fs));
+ break;
+ case 32: // CVT.S.D
+ setFloat(fd,(float)getDouble(fs));
+ break;
+ case 36: // CVT.W.D
+ if(debugon) System.out.println("CVT.W.D rm: " + roundingMode() + " f" + fs + ":" + getDouble(fs));
+ switch(roundingMode()) {
+ case 0: f[fd] = (int)Math.floor(getDouble(fs)+0.5); break; // Round to nearest
+ case 1: f[fd] = (int)getDouble(fs); break; // Round towards zero
+ case 2: f[fd] = (int)Math.ceil(getDouble(fs)); break; // Round towards plus infinity
+ case 3: f[fd] = (int)Math.floor(getDouble(fs)); break; // Round towards minus infinity
+ }
+ if(debugon) System.out.println("CVT.W.D: f" + fd + ":" + f[fd]);
+ break;
+ case 50: // C.EQ.D
+ setFC(getDouble(fs) == getDouble(ft));
+ break;
+ case 60: // C.LT.D
+ setFC(getDouble(fs) < getDouble(ft));
+ break;
+ case 62: // C.LE.D
+ setFC(getDouble(fs) <= getDouble(ft));
+ break;
+ default: throw new ExecutionException("Invalid Instruction 17/" + rs + "/" + subcode + " at " + sourceLine(pc));
+ }
+ break;
+ }
+ case 20: { // Integer
+ switch(subcode) {
+ case 33: // CVT.D.W
+ setDouble(fd,f[fs]);
+ break;
+ default: throw new ExecutionException("Invalid Instruction 17/" + rs + "/" + subcode + " at " + sourceLine(pc));
+ }
+ break;
+ }
+ default:
+ throw new ExecutionException("Invalid Instruction 17/" + rs);
+ }
+ break;
+ }
+ case 18: case 19:
+ throw new ExecutionException("No coprocessor installed");
+ case 32: { // LB
+ addr = r[rs] + signedImmediate;
+ try {
+ tmp = readPages[addr>>>PAGE_SHIFT][(addr>>>2)&(PAGE_WORDS-1)];
+ } catch(RuntimeException e) {
+ tmp = memRead(addr&~3);
+ }
+ switch(addr&3) {
+ case 0: tmp = (tmp>>>24)&0xff; break;
+ case 1: tmp = (tmp>>>16)&0xff; break;
+ case 2: tmp = (tmp>>> 8)&0xff; break;
+ case 3: tmp = (tmp>>> 0)&0xff; break;
+ }
+ if((tmp&0x80)!=0) tmp |= 0xffffff00; // sign extend
+ r[rt] = tmp;
+ break;
+ }
+ case 33: { // LH
+ addr = r[rs] + signedImmediate;
+ try {
+ tmp = readPages[addr>>>PAGE_SHIFT][(addr>>>2)&(PAGE_WORDS-1)];
+ } catch(RuntimeException e) {
+ tmp = memRead(addr&~3);
+ }
+ switch(addr&2) {
+ case 0: tmp = (tmp>>>16)&0xffff; break;
+ case 2: tmp = (tmp>>> 0)&0xffff; break;
+ }
+ if((tmp&0x8000)!=0) tmp |= 0xffff0000; // sign extend
+ r[rt] = tmp;
+ break;
+ }
+ case 34: { // LWL;
+ addr = r[rs] + signedImmediate;
+ try {
+ tmp = readPages[addr>>>PAGE_SHIFT][(addr>>>2)&(PAGE_WORDS-1)];
+ } catch(RuntimeException e) {
+ tmp = memRead(addr&~3);
+ }
+ switch(addr&3) {
+ case 0: r[rt] = (r[rt]&0x00000000)|(tmp<< 0); break;
+ case 1: r[rt] = (r[rt]&0x000000ff)|(tmp<< 8); break;
+ case 2: r[rt] = (r[rt]&0x0000ffff)|(tmp<<16); break;
+ case 3: r[rt] = (r[rt]&0x00ffffff)|(tmp<<24); break;
+ }
+ break;
+ }
+ case 35: // LW
+ addr = r[rs] + signedImmediate;
+ try {
+ r[rt] = readPages[addr>>>PAGE_SHIFT][(addr>>>2)&(PAGE_WORDS-1)];
+ } catch(RuntimeException e) {
+ r[rt] = memRead(addr);
+ }
+ break;
+ case 36: { // LBU
+ addr = r[rs] + signedImmediate;
+ try {
+ tmp = readPages[addr>>>PAGE_SHIFT][(addr>>>2)&(PAGE_WORDS-1)];
+ } catch(RuntimeException e) {
+ tmp = memRead(addr);
+ }
+ switch(addr&3) {
+ case 0: r[rt] = (tmp>>>24)&0xff; break;
+ case 1: r[rt] = (tmp>>>16)&0xff; break;
+ case 2: r[rt] = (tmp>>> 8)&0xff; break;
+ case 3: r[rt] = (tmp>>> 0)&0xff; break;
+ }
+ break;
+ }
+ case 37: { // LHU
+ addr = r[rs] + signedImmediate;
+ try {
+ tmp = readPages[addr>>>PAGE_SHIFT][(addr>>>2)&(PAGE_WORDS-1)];
+ } catch(RuntimeException e) {
+ tmp = memRead(addr&~3);
+ }
+ switch(addr&2) {
+ case 0: r[rt] = (tmp>>>16)&0xffff; break;
+ case 2: r[rt] = (tmp>>> 0)&0xffff; break;
+ }
+ break;
+ }
+ case 38: { // LWR
+ addr = r[rs] + signedImmediate;
+ try {
+ tmp = readPages[addr>>>PAGE_SHIFT][(addr>>>2)&(PAGE_WORDS-1)];
+ } catch(RuntimeException e) {
+ tmp = memRead(addr&~3);
+ }
+ switch(addr&3) {
+ case 0: r[rt] = (r[rt]&0xffffff00)|(tmp>>>24); break;
+ case 1: r[rt] = (r[rt]&0xffff0000)|(tmp>>>16); break;
+ case 2: r[rt] = (r[rt]&0xff000000)|(tmp>>> 8); break;
+ case 3: r[rt] = (r[rt]&0x00000000)|(tmp>>> 0); break;
+ }
+ break;
+ }
+ case 40: { // SB
+ addr = r[rs] + signedImmediate;
+ try {
+ tmp = readPages[addr>>>PAGE_SHIFT][(addr>>>2)&(PAGE_WORDS-1)];
+ } catch(RuntimeException e) {
+ tmp = memRead(addr&~3);
+ }
+ switch(addr&3) {
+ case 0: tmp = (tmp&0x00ffffff) | ((r[rt]&0xff)<<24); break;
+ case 1: tmp = (tmp&0xff00ffff) | ((r[rt]&0xff)<<16); break;
+ case 2: tmp = (tmp&0xffff00ff) | ((r[rt]&0xff)<< 8); break;
+ case 3: tmp = (tmp&0xffffff00) | ((r[rt]&0xff)<< 0); break;
+ }
+ try {
+ writePages[addr>>>PAGE_SHIFT][(addr>>>2)&(PAGE_WORDS-1)] = tmp;
+ } catch(RuntimeException e) {
+ memWrite(addr&~3,tmp);
+ }
+ break;
+ }
+ case 41: { // SH
+ addr = r[rs] + signedImmediate;
+ try {
+ tmp = readPages[addr>>>PAGE_SHIFT][(addr>>>2)&(PAGE_WORDS-1)];
+ } catch(RuntimeException e) {
+ tmp = memRead(addr&~3);
+ }
+ switch(addr&2) {
+ case 0: tmp = (tmp&0x0000ffff) | ((r[rt]&0xffff)<<16); break;
+ case 2: tmp = (tmp&0xffff0000) | ((r[rt]&0xffff)<< 0); break;
+ }
+ try {
+ writePages[addr>>>PAGE_SHIFT][(addr>>>2)&(PAGE_WORDS-1)] = tmp;
+ } catch(RuntimeException e) {
+ memWrite(addr&~3,tmp);
+ }
+ break;
+ }
+ case 42: { // SWL
+ addr = r[rs] + signedImmediate;
+ tmp = memRead(addr&~3);
+ switch(addr&3) {
+ case 0: tmp=(tmp&0x00000000)|(r[rt]>>> 0); break;
+ case 1: tmp=(tmp&0xff000000)|(r[rt]>>> 8); break;
+ case 2: tmp=(tmp&0xffff0000)|(r[rt]>>>16); break;
+ case 3: tmp=(tmp&0xffffff00)|(r[rt]>>>24); break;
+ }
+ try {
+ writePages[addr>>>PAGE_SHIFT][(addr>>>2)&(PAGE_WORDS-1)] = tmp;
+ } catch(RuntimeException e) {
+ memWrite(addr&~3,tmp);
+ }
+ break;
+ }
+ case 43: // SW
+ addr = r[rs] + signedImmediate;
+ try {
+ writePages[addr>>>PAGE_SHIFT][(addr>>>2)&(PAGE_WORDS-1)] = r[rt];
+ } catch(RuntimeException e) {
+ memWrite(addr&~3,r[rt]);
+ }
+ break;
+ case 46: { // SWR
+ addr = r[rs] + signedImmediate;
+ tmp = memRead(addr&~3);
+ switch(addr&3) {
+ case 0: tmp=(tmp&0x00ffffff)|(r[rt]<<24); break;
+ case 1: tmp=(tmp&0x0000ffff)|(r[rt]<<16); break;
+ case 2: tmp=(tmp&0x000000ff)|(r[rt]<< 8); break;
+ case 3: tmp=(tmp&0x00000000)|(r[rt]<< 0); break;
+ }
+ memWrite(addr&~3,tmp);
+ break;
+ }
+ // FEATURE: Needs to be atomic w/ threads
+ case 48: // LWC0/LL
+ r[rt] = memRead(r[rs] + signedImmediate);
+ break;
+ case 49: // LWC1
+ f[rt] = memRead(r[rs] + signedImmediate);
+ break;
+ // FEATURE: Needs to be atomic w/ threads
+ case 56:
+ memWrite(r[rs] + signedImmediate,r[rt]);
+ r[rt] = 1;
+ break;
+ case 57: // SWC1
+ memWrite(r[rs] + signedImmediate,f[rt]);
+ break;
+ default:
+ throw new ExecutionException("Invalid Instruction: " + op);
+ }
+ pc = nextPC;
+ nextPC = pc + 4;
+ } // for(;;)
+ } catch(ExecutionException e) {
+ this.pc = pc;
+ throw e;
+ }
+ return 0;
+ }
+
+ public int lookupSymbol(String name) {
+ ELF.Symbol sym = symtab.getGlobalSymbol(name);
+ return sym == null ? -1 : sym.addr;
+ }
+
+ // Image loading function
+ private void loadImage(SeekableData data) throws IOException {
+ if(state != UNINITIALIZED) throw new IllegalStateException("loadImage called on initialized runtime");
+
+ ELF elf = new ELF(data);
+ symtab = elf.getSymtab();
+
+ if(elf.header.type != ELF.ELFHeader.ET_EXEC) throw new IOException("Binary is not an executable");
+ if(elf.header.machine != ELF.ELFHeader.EM_MIPS) throw new IOException("Binary is not for the MIPS I Architecture");
+ if(elf.ident.data != ELF.ELFIdent.ELFDATA2MSB) throw new IOException("Binary is not big endian");
+
+ entryPoint = elf.header.entry;
+
+ ELF.Symtab symtab = elf.getSymtab();
+ if(symtab == null) throw new IOException("No symtab in binary (did you strip it?)");
+ ELF.Symbol userInfo = symtab.getGlobalSymbol("user_info");
+ ELF.Symbol gpsym = symtab.getGlobalSymbol("_gp");
+
+ if(gpsym == null) throw new IOException("NO _gp symbol!");
+ gp = gpsym.addr;
+
+ if(userInfo != null) {
+ userInfoBase = userInfo.addr;
+ userInfoSize = userInfo.size;
+ }
+
+ ELF.PHeader[] pheaders = elf.pheaders;
+ int brk = 0;
+ for(int i=0;i<pheaders.length;i++) {
+ ELF.PHeader ph = pheaders[i];
+ if(ph.type != ELF.PHeader.PT_LOAD) continue;
+ int memsize = ph.memsz;
+ int filesize = ph.filesz;
+ if(memsize == 0) continue;
+ if(memsize < 0) throw new IOException("pheader size too large");
+ int addr = ph.vaddr;
+ if(addr == 0x0) throw new IOException("pheader vaddr == 0x0");
+ brk = max(addr+memsize,brk);
+
+ for(int j=0;j<memsize+PAGE_SIZE-1;j+=PAGE_SIZE) {
+ int page = (j+addr) >>> PAGE_SHIFT;
+ if(readPages[page] == null)
+ readPages[page] = new int[PAGE_WORDS];
+ if(ph.writable()) writePages[page] = readPages[page];
+ }
+ if(filesize != 0) {
+ filesize = filesize & ~3;
+ DataInputStream dis = new DataInputStream(ph.getInputStream());
+ do {
+ readPages[addr >>> PAGE_SHIFT][(addr >>> 2)&(PAGE_WORDS-1)] = dis.readInt();
+ addr+=4;
+ filesize-=4;
+ } while(filesize > 0);
+ dis.close();
+ }
+ }
+ brkAddr = (brk+PAGE_SIZE-1)&~(PAGE_SIZE-1);
+ state = INITIALIZED;
+ }
+
+ protected void setCPUState(CPUState state) {
+ for(int i=1;i<32;i++) registers[i] = state.r[i];
+ for(int i=0;i<32;i++) fpregs[i] = state.f[i];
+ hi=state.hi; lo=state.lo; fcsr=state.fcsr;
+ pc=state.pc;
+ }
+
+ protected CPUState getCPUState() {
+ CPUState state = new CPUState();
+ for(int i=1;i<32;i++) state.r[i] = registers[i];
+ for(int i=0;i<32;i++) state.f[i] = fpregs[i];
+ state.hi=hi; state.lo=lo; state.fcsr=fcsr;
+ state.pc=pc;
+ return state;
+ }
+
+ // This is package private for fork() which does all kinds of ugly things behind the scenes
+ Interpreter() { super(4096,65536,true); }
+ public Interpreter(SeekableData data) throws IOException { this(); loadImage(data); }
+ public Interpreter(String filename) throws IOException {
+ this(new SeekableFile(filename,false));
+ image = filename;
+ }
+ public Interpreter(InputStream is) throws IOException { this(new SeekableInputStream(is)); }
+
+ // Debug functions
+ // NOTE: This probably requires a jdk > 1.1, however, it is only used for debugging
+ private java.util.HashMap sourceLineCache;
+ public String sourceLine(int pc) {
+ final String addr2line = "mips-unknown-elf-addr2line";
+ String line = (String) (sourceLineCache == null ? null : sourceLineCache.get(new Integer(pc)));
+ if(line != null) return line;
+ if(image==null) return null;
+ try {
+ Process p = java.lang.Runtime.getRuntime().exec(new String[]{addr2line,"-e",image,toHex(pc)});
+ line = new BufferedReader(new InputStreamReader(p.getInputStream())).readLine();
+ if(line == null) return null;
+ while(line.startsWith("../")) line = line.substring(3);
+ if(sourceLineCache == null) sourceLineCache = new java.util.HashMap();
+ sourceLineCache.put(new Integer(pc),line);
+ return line;
+ } catch(IOException e) {
+ return null;
+ }
+ }
+
+ public class DebugShutdownHook implements Runnable {
+ public void run() {
+ int pc = Interpreter.this.pc;
+ if(getState() == RUNNING)
+ System.err.print("\nCPU Executing " + toHex(pc) + ": " + sourceLine(pc) + "\n");
+ }
+ }
+
+ public static void main(String[] argv) throws Exception {
+ String image = argv[0];
+ Interpreter emu = new Interpreter(image);
+ java.lang.Runtime.getRuntime().addShutdownHook(new Thread(emu.new DebugShutdownHook()));
+ int status = emu.run(argv);
+ System.err.println("Exit status: " + status);
+ System.exit(status);
+ }
+}
--- /dev/null
+package org.xwt.mips;
+
+import java.util.*;
+import java.io.*;
+import org.xwt.mips.util.SeekableData;
+
+public class JavaSourceCompiler extends Compiler {
+ /** Stores the "case r XXX: ... run_YYYY();" blocks generated by the emitText method/ */
+ private StringBuffer runs = new StringBuffer();
+ /** Stores the "initData" and "cleadData" calls generated by the emitData and emitBSS methods */
+ private StringBuffer inits = new StringBuffer();
+ /** Stores lines to go in the class scope */
+ private StringBuffer classLevel = new StringBuffer();
+
+ /** The stream to write the compiled output to */
+ private PrintWriter out;
+
+ /** Prints a blank line to the output stream */
+ private void p() { out.println(); }
+ /** prints the given string (indented by <i>indent</i>*4 spaces) to the output stream */
+ private void p(String s) { out.println(indents[indent] + s); }
+ private void pblock(StringBuffer sb) { out.print(sb.toString()); }
+
+ /** Used by the p() method to add indentation */
+ private int indent;
+
+ private static String indents[] = new String[16];
+ static { String s=""; for(int i=0;i<indents.length;i++,s=s+" ") indents[i] = s; }
+
+ public JavaSourceCompiler(SeekableData binary, String className, Writer w) throws IOException {
+ super(binary,className);
+ out = new PrintWriter(w);
+ }
+
+ protected void _go() throws Exn, IOException {
+ String packageName;
+ String className;
+ if (fullClassName.indexOf('.') != -1) {
+ packageName = fullClassName.substring(0, fullClassName.lastIndexOf('.'));
+ className = fullClassName.substring(fullClassName.lastIndexOf('.') + 1);
+ } else {
+ className = fullClassName;
+ packageName = null;
+ }
+
+ p("/* This file was generated from " + source + " by Mips2Java on " + dateTime() + " */");
+ if (packageName != null) p("package " + packageName + ";");
+ if(runtimeStats) p("import java.util.*;");
+ p();
+ p("public class " + className + " extends " + runtimeClass + " {");
+ indent++;
+
+ p("/* program counter */");
+ p("private int pc = 0;");
+ if(debugCompiler)
+ p("private int lastPC = 0;");
+ p();
+ p("/* General Purpose registers */");
+ p("private final static int r0 = 0;");
+ p("private int r1, r2, r3, r4, r5, r6, r7,");
+ p(" r8, r9, r10, r11, r12, r13, r14, r15,");
+ p(" r16, r17, r18, r19, r20, r21, r22, r23,");
+ p(" r24, r25, r26, r27, r28, r29, r30, r31,");
+ p(" hi = 0, lo = 0;");
+ p("/* FP registers */");
+ p("private int f0, f1, f2, f3, f4, f5, f6, f7,");
+ p(" f8, f9, f10, f11, f12, f13, f14, f15,");
+ p(" f16, f17, f18, f19, f20, f21, f22, f23,");
+ p(" f24, f25, f26, f27, f28, f29, f30, f31;");
+ p("/* FP Control Register */");
+ p("private int fcsr = 0;");
+ p();
+
+ if(onePage) p("private final int[] page = readPages[0];");
+
+ // Generate main body functions (run_XXXX() blocks, _data[] arrays, etc)
+ int highestAddr = 0;
+
+ for(int i=0;i<elf.sheaders.length;i++) {
+ ELF.SHeader sheader = elf.sheaders[i];
+ String name = sheader.name;
+ // if this section doesn't get loaded into our address space don't worry about it
+ if(sheader.addr == 0x0) continue;
+
+ highestAddr = Math.max(highestAddr, sheader.addr + sheader.size);
+
+ if(name.equals(".text"))
+ emitText(sheader.addr, new DataInputStream(sheader.getInputStream()),sheader.size);
+ else if(name.equals(".data") || name.equals(".sdata") || name.equals(".rodata") || name.equals(".ctors") || name.equals(".dtors"))
+ emitData(sheader.addr, new DataInputStream(sheader.getInputStream()), sheader.size,name.equals(".rodata"));
+ else if(name.equals(".bss") || name.equals(".sbss"))
+ emitBSS(sheader.addr,sheader.size);
+ else
+ throw new Exn("Unknown segment: " + name);
+ }
+ p();
+
+ pblock(classLevel);
+ p();
+
+ // Trampoline (dispatch calls to the appropriate run_XXX() methods
+ p("private final void trampoline() throws ExecutionException {");
+ indent++;
+ p("while(state == RUNNING) {");
+ indent++;
+ p("switch(pc>>>" + methodShift+ ") {");
+ //p("switch(pc&" + toHex(methodMask) + ") {");
+ indent++;
+ pblock(runs);
+ p("default: throw new ExecutionException(\"invalid address 0x\" + Long.toString(this.pc&0xffffffffL,16) + \": r2: \" + r2);");
+ indent--; p("}");
+ indent--; p("}");
+ indent--; p("}");
+ p();
+
+ // Constructor
+ p("public " + className + "() {");
+ indent++;
+ p("super(" + pageSize + "," + totalPages + "," + (fastMem?"false":"true") + ");");
+ p("entryPoint = " + toHex(elf.header.entry) + ";");
+ if(userInfo != null) {
+ p("userInfoBase=" + toHex(userInfo.addr) + ";");
+ p("userInfoSize=" + userInfo.size + ";");
+ }
+ p("gp = " + toHex(gp.addr) + ";");
+ if(onePage)
+ p("brkAddr = " + toHex((highestAddr+4095)&~4095) + ";");
+ else
+ p("brkAddr = " + toHex((highestAddr+pageSize-1)&~(pageSize-1)) + ";");
+ pblock(inits);
+ p("state = INITIALIZED;");
+ indent--;
+ p("}");
+ p();
+
+ // main() function
+ p("public static void main(String[] args) throws Exception {");
+ indent++;
+ p("" + className + " me = new " + className + "();");
+ p("int status = me.run(\"" + fullClassName + "\",args);");
+ if(runtimeStats) p("me.printStats();");
+ p("System.exit(status);");
+ indent--;
+ p("}");
+ p();
+
+ // Runtime abstract methods
+ p("protected void _execute() throws ExecutionException { trampoline(); }");
+ p();
+
+ p("protected void setCPUState(CPUState state) {");
+ indent++;
+ for(int i=1;i<32;i++) p("r" + i + "=state.r[" + i + "];");
+ for(int i=0;i<32;i++) p("f" + i + "=state.f[" + i + "];");
+ p("hi=state.hi; lo=state.lo; fcsr=state.fcsr;");
+ p("pc=state.pc;");
+ indent--;
+ p("}");
+ p("protected CPUState getCPUState() {");
+ indent++;
+ p("CPUState state = new CPUState();");
+ for(int i=1;i<32;i++) p("state.r[" + i + "]=r" + i+ ";");
+ for(int i=0;i<32;i++) p("state.f[" + i + "]=f" + i +";");
+ p("state.hi=hi; state.lo=lo; state.fcsr=fcsr;");
+ p("state.pc=pc;");
+ p("return state;");
+ indent--;
+ p("}");
+ p();
+
+ if(supportCall) {
+ p("private static final " + hashClass + " symbols = new " + hashClass + "();");
+ p("static {");
+ indent++;
+ ELF.Symbol[] symbols = elf.getSymtab().symbols;
+ for(int i=0;i<symbols.length;i++) {
+ ELF.Symbol s = symbols[i];
+ if(s.type == ELF.Symbol.STT_FUNC && s.binding == ELF.Symbol.STB_GLOBAL && (s.name.equals("_call_helper") || !s.name.startsWith("_")))
+ p("symbols.put(\"" + s.name + "\",new Integer(" + toHex(s.addr) + "));");
+ }
+ indent--;
+ p("}");
+ p("public int lookupSymbol(String symbol) { Integer i = (Integer) symbols.get(symbol); return i==null ? -1 : i.intValue(); }");
+ p();
+ }
+
+ // Runtime stats
+ if(runtimeStats) {
+ p("private HashMap counters = new HashMap();");
+ p("private void inc(String k) { Long i = (Long)counters.get(k); counters.put(k,new Long(i==null ? 1 : i.longValue() + 1)); }");
+ p("private void printStats() {");
+ p(" Iterator i = new TreeSet(counters.keySet()).iterator();");
+ p(" while(i.hasNext()) { Object o = i.next(); System.err.println(\"\" + o + \": \" + counters.get(o)); }");
+ p("}");
+ p();
+ }
+
+ indent--;
+ p("}");
+ }
+
+ private int startOfMethod = 0;
+ private int endOfMethod = 0;
+
+ private void startMethod(int addr) {
+ addr &= ~(maxBytesPerMethod-1);
+ startOfMethod = addr;
+ endOfMethod = addr + maxBytesPerMethod;
+ String methodName = "run_" + Long.toString(addr & 0xffffffffL, 16);
+ runs.append(indents[4] + "case " + toHex(addr>>>methodShift) + ": " + methodName + "(); break; \n");
+ //runs.append(indents[4] + "case " + toHex(addr&methodMask) + ": " + methodName + "(); break; \n");
+
+ p("private final void " + methodName + "() throws ExecutionException { /"+"* " + toHex(addr) + " - " + toHex(endOfMethod) + " *" + "/");
+ indent++;
+ p("int addr, tmp;");
+ p("for(;;) {");
+ indent++;
+ p("switch(pc) {");
+ indent++;
+ }
+
+ private void endMethod() { endMethod(endOfMethod); }
+ private void endMethod(int lastAddr) {
+ if(startOfMethod == 0) return;
+ // FEATURE: We should be able to use if(!unreachable) here (i think)
+ // This isn't strictly necessary; its just here to work around unreachable code errors
+ p("case " + toHex(lastAddr) + ":");
+ indent++;
+ p("pc=" + constant(lastAddr) + ";");
+ leaveMethod();
+ indent--;
+ if(debugCompiler)
+ p("default: throw new ExecutionException(\"invalid address 0x\" + Long.toString(pc&0xffffffffL,16) + \" (got here from 0x\" + Long.toString(lastPC&0xffffffffL,16)+\")\");");
+ else
+ p("default: throw new ExecutionException(\"invalid address 0x\" + Long.toString(pc&0xffffffffL,16));");
+ indent--;
+ p("}"); // end switch
+ p("/* NOT REACHED */");
+ indent--;
+ p("}"); // end for
+ indent--;
+ p("}"); // end method
+ endOfMethod = startOfMethod = 0;
+ }
+
+ private HashMap relativeAddrs = new HashMap();
+ private String constant(int target) {
+ if(target >= 4096 && lessConstants) {
+ int n = target & ~1023;
+ String var = "N_" + toHex8(n);
+ if(relativeAddrs.get(new Integer(n)) == null) {
+ relativeAddrs.put(new Integer(n),Boolean.TRUE);
+ classLevel.append(indents[1] + "private static int " + var + " = " + toHex(n) + ";\n");
+ }
+ return "(" + var + " + " + toHex(target - n) + ")";
+ } else {
+ return toHex(target);
+ }
+ }
+
+ private void branch(int pc, int target) {
+ if(debugCompiler) p("lastPC = " + toHex(pc) + ";");
+ p("pc=" + constant(target) + ";");
+ if(target == 0)
+ p("throw new ExecutionException(\"Branch to addr 0x0\");");
+ else if((pc&methodMask) == (target&methodMask))
+ p("continue;");
+ else if(assumeTailCalls)
+ p("run_" + Long.toString((target&methodMask)&0xffffffffL, 16) + "(); return;");
+ else
+ leaveMethod();
+ }
+
+ private void leaveMethod() {
+ p("return;");
+ }
+
+ private boolean textDone;
+ private void emitText(int addr, DataInputStream dis, int size) throws Exn,IOException {
+ if(textDone) throw new Exn("Multiple text segments");
+ textDone = true;
+
+ if((addr&3)!=0 || (size&3)!=0) throw new Exn("Section on weird boundaries");
+ int count = size/4;
+ int nextInsn = dis.readInt();
+ if(nextInsn == -1) throw new Error("Actually read -1 at " + toHex(addr));
+ int insn;
+
+ for(int i=0;i<count;i++,addr+=4) {
+ insn = nextInsn;
+ nextInsn = (i == count-1) ? -1 : dis.readInt();
+ if(addr >= endOfMethod) { endMethod(); startMethod(addr); }
+ if(jumpableAddresses==null || addr == startOfMethod || jumpableAddresses.contains(new Integer(addr))) {
+ p("case " + toHex(addr) + ":");
+ unreachable = false;
+ } else if(unreachable) {
+ continue;
+ } else if(debugCompiler) {
+ p("/" + "* pc = " + toHex(addr) + "*" + "/");
+ }
+ indent++;
+ emitInstruction(addr,insn,nextInsn);
+ indent--;
+ }
+ endMethod(addr);
+ p();
+ dis.close();
+ }
+
+ private int initDataCount = 0;
+ private void emitData(int addr, DataInputStream dis, int size, boolean readOnly) throws Exn,IOException {
+ if((addr&3)!=0 || (size&3)!=0) throw new Exn("Data section on weird boundaries");
+ int last = addr + size;
+ while(addr < last) {
+ int segSize = Math.min(size,28000); // must be a multiple of 56
+ StringBuffer sb = new StringBuffer();
+ for(int i=0;i<segSize;i+=7) {
+ long l = 0;
+ for(int j=0;j<7;j++) {
+ l <<= 8;
+ byte b = (i+j < size) ? dis.readByte() : 1;
+ l |= (b & 0xffL);
+ }
+ for(int j=0;j<8;j++) {
+ char c = (char) ((l>>>(7*(7-j)))&0x7f);
+ if(c=='\n') sb.append("\\n");
+ else if(c=='\r') sb.append("\\r");
+ else if(c=='\\') sb.append("\\\\");
+ else if(c=='"') sb.append("\\\"");
+ else if(c >= 32 && c <= 126) sb.append(c);
+ else sb.append("\\" + toOctal3(c));
+ }
+ }
+ String varname = "_data" + (++initDataCount);
+ p("private static final int[] " + varname + " = decodeData(\"" + sb.toString() + "\"," + toHex(segSize/4) + ");");
+ inits.append(indents[2] + "initPages(" + varname +"," + toHex(addr) + "," + (readOnly?"true":"false") + ");\n");
+ addr += segSize;
+ size -= segSize;
+ }
+ dis.close();
+ }
+
+ private void emitBSS(int addr, int size) throws Exn {
+ if((addr&3)!=0) throw new Exn("BSS section on weird boundaries");
+ size = (size+3)&~3;
+ int count = size/4;
+ inits.append(indents[2] + "clearPages(" + toHex(addr) + "," + toHex(count) + ");\n");
+ }
+
+ // True if the current code path is unreachable (any instruction with a case statement is reachable)
+ private boolean unreachable = false;
+
+ private void emitInstruction(int pc, int insn, int nextInsn) throws IOException,Exn {
+ if(insn == -1) throw new Error("insn is -1");
+
+ int op = (insn >>> 26) & 0xff; // bits 26-31
+ int rs = (insn >>> 21) & 0x1f; // bits 21-25
+ int rt = (insn >>> 16) & 0x1f; // bits 16-20
+ int ft = (insn >>> 16) & 0x1f;
+ int rd = (insn >>> 11) & 0x1f; // bits 11-15
+ int fs = (insn >>> 11) & 0x1f;
+ int shamt = (insn >>> 6) & 0x1f; // bits 6-10
+ int fd = (insn >>> 6) & 0x1f;
+ int subcode = insn & 0x3f; // bits 0-5
+
+ int jumpTarget = (insn & 0x03ffffff); // bits 0-25
+ int unsignedImmediate = insn & 0xffff;
+ int signedImmediate = (insn << 16) >> 16;
+ int branchTarget = signedImmediate;
+
+ int tmp; // temporaries
+
+ //if(pc%64==0) p("System.err.println(\"Executing: " + toHex(pc) + "\");");
+ //p("/" + "*" + (pc == -1 ? "Delay Slot" : toHex(pc)) + " *" + "/ ");
+ if(pc==-1) p("/" + "* Next insn is delay slot *" + "/ ");
+
+ if(runtimeStats && op != 0) p("inc(\"opcode: " + op + "\");");
+ switch(op) {
+ case 0: {
+ if(runtimeStats && insn != 0) p("inc(\"opcode: 0/" + subcode + "\");");
+ switch(subcode) {
+ case 0: // SLL
+ if(insn != 0)
+ p( "r"+rd+" = r"+rt+" << "+shamt+";");
+ break;
+ case 2: // SRL
+ p( "r"+rd+" = r"+rt+" >>> "+shamt+";");
+ break;
+ case 3: // SRA
+ p( "r"+rd+" = r"+rt+" >> "+shamt+";");
+ break;
+ case 4: // SLLV
+ p( "r"+rd+" = r"+rt+" << (r"+rs+"&0x1f);");
+ break;
+ case 6: // SRLV
+ p( "r"+rd+" = r"+rt+" >>> (r"+rs+"&0x1f);");
+ break;
+ case 7: // SRAV
+ p( "r"+rd+" = r"+rt+" >> (r"+rs+"&0x1f);");
+ break;
+ case 8: // JR
+ if(pc == -1) throw new Error("pc modifying insn in delay slot");
+ emitInstruction(-1,nextInsn,-1);
+ if(debugCompiler) p("lastPC = " + toHex(pc) + ";");
+ p("pc=r" + rs + ";");
+ leaveMethod();
+ unreachable = true;
+ break;
+ case 9: // JALR
+ if(pc == -1) throw new Error("pc modifying insn in delay slot");
+ emitInstruction(-1,nextInsn,-1);
+ if(debugCompiler) p("lastPC = " + toHex(pc) + ";");
+ p("pc=r" + rs + ";");
+ p("r" + RA + "=" + constant(pc+8 /*skip this insn and delay slot*/) + ";");
+ leaveMethod();
+ unreachable = true;
+ break;
+ case 12: // SYSCALL
+ p("pc = " + toHex(pc) + ";");
+ p( "r"+V0+" = syscall(r"+V0+",r"+A0+",r"+A1+",r"+A2+",r"+A3+");");
+ p("if (state != RUNNING) {");
+ indent++;
+ p("pc = " + toHex(pc+4) + ";");
+ leaveMethod();
+ indent--;
+ p("}");
+ break;
+ case 13: // BREAK
+ p( "throw new ExecutionException(\"Break\");");
+ break;
+ case 16: // MFHI
+ p( "r"+rd+" = hi;");
+ break;
+ case 17: // MTHI
+ p( "hi = r"+rs+";");
+ break;
+ case 18: // MFLO
+ p( "r"+rd+" = lo;");
+ break;
+ case 19: // MTLO
+ p( "lo = r"+rs+";");
+ break;
+ case 24: // MULT
+ p( "{ long hilo = (long)(r"+rs+") * ((long)r"+rt+"); " +
+ "hi = (int) (hilo >>> 32); " +
+ "lo = (int) hilo; }");
+ break;
+ case 25: // MULTU
+ p( "{ long hilo = (r"+rs+" & 0xffffffffL) * (r"+rt+" & 0xffffffffL); " +
+ "hi = (int) (hilo >>> 32); " +
+ "lo = (int) hilo; } ");
+ break;
+ case 26: // DIV
+ p( "hi = r"+rs+"%r"+rt+"; lo = r"+rs+"/r"+rt+";");
+ break;
+ case 27: // DIVU
+ p("if(r"+rt+"!=0) {");
+ p( "hi = (int)((r"+rs+" & 0xffffffffL) % (r"+rt+" & 0xffffffffL)); " +
+ "lo = (int)((r"+rs+" & 0xffffffffL) / (r"+rt+" & 0xffffffffL));");
+ p("}");
+ break;
+ case 32: // ADD
+ throw new Exn("ADD (add with oveflow trap) not suported");
+ /*This must trap on overflow
+ p( "r"+rd+" = r"+rs+" + r"+rt+";");
+ break;*/
+ case 33: // ADDU
+ p( "r"+rd+" = r"+rs+" + r"+rt+";");
+ break;
+ case 34: // SUB
+ throw new Exn("SUB (add with oveflow trap) not suported");
+ /*This must trap on overflow
+ p( "r"+rd+" = r"+rs+" - r"+rt+";");
+ break;*/
+ case 35: // SUBU
+ p( "r"+rd+" = r"+rs+" - r"+rt+";");
+ break;
+ case 36: // AND
+ p( "r"+rd+" = r"+rs+" & r"+rt+";");
+ break;
+ case 37: // OR
+ p( "r"+rd+" = r"+rs+" | r"+rt+";");
+ break;
+ case 38: // XOR
+ p( "r"+rd+" = r"+rs+" ^ r"+rt+";");
+ break;
+ case 39: // NOR
+ p( "r"+rd+" = ~(r"+rs+" | r"+rt+");");
+ break;
+ case 42: // SLT
+ p( "r"+rd+" = r"+rs+" < r"+rt+" ? 1 : 0;");
+ break;
+ case 43: // SLTU
+ p( "r"+rd+" = ((r"+rs+" & 0xffffffffL) < (r"+rt+" & 0xffffffffL)) ? 1 : 0;");
+ break;
+ default:
+ throw new RuntimeException("Illegal instruction 0/" + subcode);
+ }
+ break;
+ }
+ case 1: {
+ switch(rt) {
+ case 0: // BLTZ
+ if(pc == -1) throw new Error("pc modifying insn in delay slot");
+ p("if(r" + rs + " < 0) {");
+ indent++;
+ emitInstruction(-1,nextInsn,-1);
+ branch(pc,pc+branchTarget*4+4);
+ indent--;
+ p("}");
+ break;
+ case 1: // BGEZ
+ if(pc == -1) throw new Error("pc modifying insn in delay slot");
+ p("if(r" + rs + " >= 0) {");
+ indent++;
+ emitInstruction(-1,nextInsn,-1);
+ branch(pc,pc+branchTarget*4+4);
+ indent--;
+ p("}");
+ break;
+ case 16: // BLTZAL
+ if(pc == -1) throw new Error("pc modifying insn in delay slot");
+ p("if(r" + rs + " < 0) {");
+ indent++;
+ emitInstruction(-1,nextInsn,-1);
+ p("r" + RA + "=" + constant(pc+8 /*skip this insn and delay slot*/) + ";");
+ branch(pc,pc+branchTarget*4+4);
+ indent--;
+ p("}");
+ break;
+ case 17: // BGEZAL
+ if(pc == -1) throw new Error("pc modifying insn in delay slot");
+ p("if(r" + rs + " >= 0) {");
+ indent++;
+ emitInstruction(-1,nextInsn,-1);
+ p("r" + RA + "=" + constant(pc+8 /*skip this insn and delay slot*/) + ";");
+ branch(pc,pc+branchTarget*4+4);
+ indent--;
+ p("}");
+ break;
+ default:
+ throw new RuntimeException("Illegal Instruction 1/" + rt);
+ }
+ break;
+ }
+ case 2: { // J
+ if(pc == -1) throw new Error("pc modifying insn in delay slot");
+ emitInstruction(-1,nextInsn,-1);
+ branch(pc,(pc&0xf0000000)|(jumpTarget << 2));
+ unreachable = true;
+ break;
+ }
+ case 3: { // JAL
+ if(pc == -1) throw new Error("pc modifying insn in delay slot");
+ int target = (pc&0xf0000000)|(jumpTarget << 2);
+ emitInstruction(-1,nextInsn,-1);
+ if(optimizedMemcpy && (target == memcpy || target == memset)) {
+ if(target == memcpy)
+ p("memcpy(r4,r5,r6);");
+ else if(target == memset)
+ p("memset(r4,r5,r6);");
+ p("r2 = r4;");
+ branch(pc,pc+8);
+ } else {
+ p("r" + RA + "=" + constant(pc+8 /*skip this insn and delay slot*/) + ";");
+ branch(pc, target);
+ }
+ unreachable = true;
+ break;
+ }
+ case 4: // BEQ
+ if(pc == -1) throw new Error("pc modifying insn in delay slot");
+ p("if(r" + rs + " == r" + rt + ") {");
+ indent++;
+ emitInstruction(-1,nextInsn,-1);
+ branch(pc,pc+branchTarget*4+4);
+ indent--;
+ p("}");
+ break;
+ case 5: // BNE
+ if(pc == -1) throw new Error("pc modifying insn in delay slot");
+ p("if(r" + rs + " != r" + rt + ") {");
+ indent++;
+ emitInstruction(-1,nextInsn,-1);
+ branch(pc,pc+branchTarget*4+4);
+ indent--;
+ p("}");
+ break;
+ case 6: //BLEZ
+ if(pc == -1) throw new Error("pc modifying insn in delay slot");
+ p("if(r" + rs + " <= 0) {");
+ indent++;
+ emitInstruction(-1,nextInsn,-1);
+ branch(pc,pc+branchTarget*4+4);
+ indent--;
+ p("}");
+ break;
+ case 7: //BGTZ
+ if(pc == -1) throw new Error("pc modifying insn in delay slot");
+ p("if(r" + rs + " > 0) {");
+ indent++;
+ emitInstruction(-1,nextInsn,-1);
+ branch(pc,pc+branchTarget*4+4);
+ indent--;
+ p("}");
+ break;
+ case 8: // ADDI
+ p( "r"+rt+" = r"+rs+" + "+signedImmediate +";");
+ break;
+ case 9: // ADDIU
+ p( "r"+rt+" = r"+rs+" + "+signedImmediate+";");
+ break;
+ case 10: // SLTI
+ p( "r"+rt+" = r"+rs+" < "+signedImmediate+" ? 1 : 0;");
+ break;
+ case 11: // SLTIU
+ p( "r"+rt+" = (r"+rs+"&0xffffffffL) < ("+unsignedImmediate+"&0xffffffffL) ? 1 : 0;");
+ break;
+ case 12: // ANDI
+ p( "r"+rt+" = r"+rs+" & "+unsignedImmediate+";");
+ break;
+ case 13: // ORI
+ p( "r"+rt+" = r"+rs+" | "+unsignedImmediate+";");
+ break;
+ case 14: // XORI
+ p( "r"+rt+" = r"+rs+" ^ "+unsignedImmediate+";");
+ break;
+ case 15: // LUI
+ p( "r"+rt+" = "+unsignedImmediate+" << 16;");
+ break;
+ case 16:
+ throw new Exn("TLB/Exception support not implemented");
+ case 17: { // FPU
+ switch(rs) {
+ case 0: // MFC.1
+ p( "r"+rt+" = f"+rd+";");
+ break;
+ case 2: // CFC.1
+ if(fs != 31) throw new Exn("FCR " + fs + " unavailable");
+ p( "r"+rt+" = fcsr;");
+ break;
+ case 4: // MTC.1
+ p( "f"+rd+" = r"+rt+";");
+ break;
+ case 6: // CTC.1
+ if(fs != 31) throw new Exn("FCR " + fs + " unavailable");
+ p( "fcsr = r"+rt+";");
+ break;
+ case 8: {// BC1F, BC1T
+ tmp = (insn>>>16)&1;
+ p("if(((fcsr&0x800000)!=0) == (" + tmp + "!=0)) {");
+ indent++;
+ emitInstruction(-1,nextInsn,-1);
+ branch(pc,pc+branchTarget*4+4);
+ indent--;
+ p("}");
+ break;
+ }
+ case 16: { // Single
+ switch(subcode) {
+ case 0: // ADD.S
+ p(setFloat(fd,getFloat(fs)+"+"+getFloat(ft)));
+ break;
+ case 1: // SUB.S
+ p(setFloat(fd,getFloat(fs)+"-"+getFloat(ft)));
+ break;
+ case 2: // MUL.S
+ p(setFloat(fd,getFloat(fs)+"*"+getFloat(ft)));
+ break;
+ case 3: // DIV.S
+ p(setFloat(fd,getFloat(fs)+"/"+getFloat(ft)));
+ break;
+ case 5: // ABS.S
+ p(setFloat(fd,"Math.abs("+getFloat(fs)+")"));
+ break;
+ case 6: // MOV.S
+ p("f"+fd+" = f"+fs+"; // MOV.S");
+ break;
+ case 7: // NEG.S
+ p(setFloat(fd,"-"+getFloat(fs)));
+ break;
+ case 33: // CVT.D.S
+ p(setDouble(fd,"(float)"+getFloat(fs)));
+ break;
+ case 36: // CVT.W.D
+ p("switch(fcsr & 3) {");
+ indent++;
+ p("case 0: f"+fd+" = (int)Math.floor("+getFloat(fs)+"+0.5); break; // Round to nearest");
+ p("case 1: f"+fd+" = (int)"+getFloat(fs)+"; break; // Round towards zero");
+ p("case 2: f"+fd+" = (int)Math.ceil("+getFloat(fs)+"); break; // Round towards plus infinity");
+ p("case 3: f"+fd+" = (int)Math.floor("+getFloat(fs)+"); break; // Round towards minus infinity");
+ indent--;
+ p("}");
+ break;
+ case 50: // C.EQ.S
+ p("fcsr = (fcsr&~0x800000) | (("+getFloat(fs)+"=="+getFloat(ft)+") ? 0x800000 : 0x000000);");
+ break;
+ case 60: // C.LT.S
+ p("fcsr = (fcsr&~0x800000) | (("+getFloat(fs)+"<"+getFloat(ft)+") ? 0x800000 : 0x000000);");
+ break;
+ case 62: // C.LE.S
+ p("fcsr = (fcsr&~0x800000) | (("+getFloat(fs)+"<="+getFloat(ft)+") ? 0x800000 : 0x000000);");
+ break;
+ default: throw new Exn("Invalid Instruction 17/" + rs + "/" + subcode);
+ }
+ break;
+ }
+ case 17: { // Double
+ switch(subcode) {
+ case 0: // ADD.D
+ p(setDouble(fd,getDouble(fs)+"+"+getDouble(ft)));
+ break;
+ case 1: // SUB.D
+ p(setDouble(fd,getDouble(fs)+"-"+getDouble(ft)));
+ break;
+ case 2: // MUL.D
+ p(setDouble(fd,getDouble(fs)+"*"+getDouble(ft)));
+ break;
+ case 3: // DIV.D
+ p(setDouble(fd,getDouble(fs)+"/"+getDouble(ft)));
+ break;
+ case 5: // ABS.D
+ p(setDouble(fd,"Math.abs("+getDouble(fs)+")"));
+ break;
+ case 6: // MOV.D
+ p("f"+fd+" = f"+fs+";");
+ p("f"+(fd+1)+" = f"+(fs+1)+";");
+ break;
+ case 7: // NEG.D
+ p(setDouble(fd,"-"+getDouble(fs)));
+ break;
+ case 32: // CVT.S.D
+ p(setFloat(fd,"(float)"+getDouble(fs)));
+ break;
+ case 36: // CVT.W.D
+ p("switch(fcsr & 3) {");
+ indent++;
+ p("case 0: f"+fd+" = (int)Math.floor("+getDouble(fs)+"+0.5); break; // Round to nearest");
+ p("case 1: f"+fd+" = (int)"+getDouble(fs)+"; break; // Round towards zero");
+ p("case 2: f"+fd+" = (int)Math.ceil("+getDouble(fs)+"); break; // Round towards plus infinity");
+ p("case 3: f"+fd+" = (int)Math.floor("+getDouble(fs)+"); break; // Round towards minus infinity");
+ indent--;
+ p("}");
+ break;
+ case 50: // C.EQ.D
+ p("fcsr = (fcsr&~0x800000) | (("+getDouble(fs)+"=="+getDouble(ft)+") ? 0x800000 : 0x000000);");
+ break;
+ case 60: // C.LT.D
+ p("fcsr = (fcsr&~0x800000) | (("+getDouble(fs)+"<"+getDouble(ft)+") ? 0x800000 : 0x000000);");
+ break;
+ case 62: // C.LE.D
+ p("fcsr = (fcsr&~0x800000) | (("+getDouble(fs)+"<="+getDouble(ft)+") ? 0x800000 : 0x000000);");
+ break;
+ default: throw new Exn("Invalid Instruction 17/" + rs + "/" + subcode);
+ }
+ break;
+ }
+ case 20: { // Integer
+ switch(subcode) {
+ case 32: // CVT.S.W
+ p(" // CVS.S.W");
+ p(setFloat(fd,"((float)f"+fs+")"));
+ break;
+ case 33: // CVT.D.W
+ p(setDouble(fd,"((double)f"+fs+")"));
+ break;
+ default: throw new Exn("Invalid Instruction 17/" + rs + "/" + subcode);
+ }
+ break;
+ }
+ default:
+ throw new Exn("Invalid Instruction 17/" + rs);
+ }
+ break;
+ }
+ case 18: case 19:
+ throw new Exn("coprocessor 2 and 3 instructions not available");
+ case 32: { // LB
+ if(runtimeStats) p("inc(\"LB\");");
+ p("addr=r" + rs +"+"+signedImmediate + ";");
+ memRead("addr","tmp");
+ p("tmp = (tmp>>>(((~addr)&3)<<3)) & 0xff;");
+ p("if((tmp&0x80)!=0) tmp |= 0xffffff00; /* sign extend */");
+ p("r"+rt+" = tmp;");
+ break;
+ }
+ case 33: { // LH
+ if(runtimeStats) p("inc(\"LH\");");
+ p("addr=r" + rs +"+"+signedImmediate + ";");
+ memRead("addr","tmp");
+ p("tmp = (tmp>>>(((~addr)&2)<<3)) & 0xffff;");
+ p("if((tmp&0x8000)!=0) tmp |= 0xffff0000; /* sign extend */");
+ p("r"+rt+" = tmp;");
+ break;
+ }
+ case 34: { // LWL;
+ p("addr=r" + rs +"+"+signedImmediate + ";");
+ memRead("addr","tmp");
+ p("r" + rt + " = (r"+rt+"&(0x00ffffff>>>(((~addr)&3)<<3)))|(tmp<<((addr&3)<<3));");
+ break;
+ /*p("addr=r" + rs +"+"+signedImmediate + ";");
+ memRead("addr&~3","tmp");
+ p("switch(addr&3) {");
+ indent++;
+ p("case 0: r"+rt+" = (r"+rt+"&0x00000000)|(tmp<< 0); break;");
+ p("case 1: r"+rt+" = (r"+rt+"&0x000000ff)|(tmp<< 8); break;");
+ p("case 2: r"+rt+" = (r"+rt+"&0x0000ffff)|(tmp<<16); break;");
+ p("case 3: r"+rt+" = (r"+rt+"&0x00ffffff)|(tmp<<24); break;");
+ indent--;
+ p("}");
+ break;*/
+ }
+ case 35: // LW
+ if(runtimeStats) p("inc(\"LW\");");
+ memRead("r" + rs +"+"+signedImmediate,"r"+rt);
+ break;
+ case 36: { // LBU
+ p("addr=r" + rs +"+"+signedImmediate + ";");
+ memRead("addr","tmp");
+ p("tmp = (tmp>>>(((~addr)&3)<<3)) & 0xff;");
+ p("r"+rt+" = tmp;");
+ break;
+ }
+ case 37: { // LHU
+ p("addr=r" + rs +"+"+signedImmediate + ";");
+ memRead("addr","tmp");
+ p("tmp = (tmp>>>(((~addr)&2)<<3)) & 0xffff;");
+ p("r"+rt+" = tmp;");
+ break;
+ }
+ case 38: { // LWR
+ p("addr=r" + rs +"+"+signedImmediate + ";");
+ memRead("addr","tmp");
+ p("r" + rt + " = (r"+rt+"&(0xffffff00<<((addr&3)<<3)))|(tmp>>>(((~addr)&3)<<3));");
+ break;
+
+ /*p("addr=r" + rs +"+"+signedImmediate + ";");
+ memRead("addr&~3","tmp");
+ p("switch(addr&3) {");
+ indent++;
+ p("case 0: r"+rt+" = (r"+rt+"&0xffffff00)|(tmp>>>24); break;");
+ p("case 1: r"+rt+" = (r"+rt+"&0xffff0000)|(tmp>>>16); break;");
+ p("case 2: r"+rt+" = (r"+rt+"&0xff000000)|(tmp>>> 8); break;");
+ p("case 3: r"+rt+" = (r"+rt+"&0x00000000)|(tmp>>> 0); break;");
+ indent--;
+ p("}");
+ break;*/
+
+ }
+ case 40: { // SB
+ if(runtimeStats) p("inc(\"SB\");");
+ p("addr=r" + rs +"+"+signedImmediate + ";");
+ memRead("addr","tmp");
+ p("tmp = (tmp&~(0xff000000>>>((addr&3)<<3)))|((r"+rt+"&0xff)<<(((~addr)&3)<<3));");
+ memWrite("addr","tmp");
+ break;
+ }
+ case 41: { // SH
+ if(runtimeStats) p("inc(\"SH\");");
+ p("addr=r" + rs +"+"+signedImmediate + ";");
+ memRead("addr","tmp");
+ p("tmp = (tmp&(0xffff<<((addr&2)<<3)))|((r" + rt + "&0xffff)<<(((~addr)&2)<<3));");
+ memWrite("addr","tmp");
+ break;
+ }
+ case 42: { // SWL
+ p(" // SWL");
+ p("addr=r" + rs +"+"+signedImmediate + ";");
+ memRead("addr","tmp");
+ p("tmp = (tmp&(0xffffff00<<(((~addr)&3)<<3)))|(r"+rt+">>>((addr&3)<<3));");
+ memWrite("addr","tmp");
+ break;
+ }
+ case 43: // SW
+ if(runtimeStats) p("inc(\"SW\");");
+ memWrite("r"+rs+"+"+signedImmediate,"r" + rt);
+ break;
+ case 46: { // SWR
+ p(" // SWR");
+ p("addr=r" + rs +"+"+signedImmediate + ";");
+ memRead("addr","tmp");
+ p("tmp = (tmp&(0x00ffffff>>>((addr&3)<<3)))|(r"+rt+"<<(((~addr)&3)<<3));");
+ memWrite("addr","tmp");
+ break;
+ }
+ // FEATURE: Need to be atomic if threads
+ case 48: // LWC0/LL
+ memRead("r"+rs+"+"+signedImmediate,"r"+rt);
+ break;
+ case 49: // LWC1
+ memRead("r"+rs+"+"+signedImmediate,"f"+rt);
+ break;
+ // FEATURE: Needs to be atomic if threads
+ case 56: // SWC1/SC
+ memWrite("r"+rs+"+"+signedImmediate,"r"+rt);
+ p("r" + rt + "=1;");
+ break;
+ case 57: // SWC1
+ memWrite("r"+rs+"+"+signedImmediate,"f"+rt);
+ break;
+ default:
+ throw new Exn("Invalid Instruction: " + op + " at " + toHex(pc));
+ }
+ }
+
+ // Helper functions for emitText
+ // NOTE: memWrite and memRead MUST discard the last two bits of addr
+ private void memWrite(String addr, String target) {
+ if(nullPointerCheck) p("nullPointerCheck(" + addr + ");");
+ if(onePage)
+ p("page[(" + addr + ")>>>2] = " + target + ";");
+ else if(fastMem)
+ p("writePages[("+addr+")>>>"+pageShift+"][(("+addr+")>>>2)&"+toHex((pageSize>>2)-1)+"] = " + target + ";");
+ else
+ p("unsafeMemWrite(" + addr + "," + target + ");");
+ }
+ private void memRead(String addr, String target) {
+ if(nullPointerCheck) p("nullPointerCheck(" + addr + ");");
+ if(onePage)
+ p(target + "= page[(" + addr + ")>>>2];");
+ else if(fastMem)
+ p(target + " = readPages[("+addr+")>>>"+pageShift+"][(("+addr+")>>>2)&"+toHex((pageSize>>2)-1)+"];");
+ else
+ p(target + " = unsafeMemRead(" + addr + ");");
+ }
+ private static String getFloat(int r) { return "(Float.intBitsToFloat(f"+r+"))"; }
+ private static String getDouble(int r) {
+ return "(Double.longBitsToDouble(((f"+(r+1)+"&0xffffffffL) << 32) | (f"+r+"&0xffffffffL)))";
+ }
+ private static String setFloat(int r, String expr) { return "f"+r+"=Float.floatToRawIntBits("+expr+");"; }
+ private static String setDouble(int r, String expr) {
+ return "{ long l = Double.doubleToLongBits("+expr+"); "+
+ "f"+(r+1)+" = (int)(l >>> 32); f"+r+" = (int)l; }";
+ }
+}
+
\ No newline at end of file
--- /dev/null
+package org.xwt.mips;
+
+interface Registers {
+ // Register Names
+ public final static int ZERO = 0; // Immutable, hardwired to 0
+ public final static int AT = 1; // Reserved for assembler
+ public final static int K0 = 26; // Reserved for kernel
+ public final static int K1 = 27; // Reserved for kernel
+ public final static int GP = 28; // Global pointer (the middle of .sdata/.sbss)
+ public final static int SP = 29; // Stack pointer
+ public final static int FP = 30; // Frame Pointer
+ public final static int RA = 31; // Return Address
+
+ // Return values (caller saved)
+ public final static int V0 = 2;
+ public final static int V1 = 3;
+ // Argument Registers (caller saved)
+ public final static int A0 = 4;
+ public final static int A1 = 5;
+ public final static int A2 = 6;
+ public final static int A3 = 7;
+ // Temporaries (caller saved)
+ public final static int T0 = 8;
+ public final static int T1 = 9;
+ public final static int T2 = 10;
+ public final static int T3 = 11;
+ public final static int T4 = 12;
+ public final static int T5 = 13;
+ public final static int T6 = 14;
+ public final static int T7 = 15;
+ public final static int T8 = 24;
+ public final static int T9 = 25;
+ // Saved (callee saved)
+ public final static int S0 = 16;
+ public final static int S1 = 17;
+ public final static int S2 = 18;
+ public final static int S3 = 19;
+ public final static int S4 = 20;
+ public final static int S5 = 21;
+ public final static int S6 = 22;
+ public final static int S7 = 23;
+}
--- /dev/null
+// Copyright 2003 Brian Alliet
+// Based on org.xwt.imp.MIPS by Adam Megacz
+// Portions Copyright 2003 Adam Megacz
+
+package org.xwt.mips;
+
+import org.xwt.mips.util.*;
+import java.io.*;
+import java.util.Arrays;
+
+// FEATURE: Look over the public API, make sure we're exposing a bare minimum
+// (we might make this an interface in the future)
+
+public abstract class Runtime implements UsermodeConstants,Registers {
+ /** Pages are 4k in size */
+ protected final int PAGE_SIZE;
+ protected final int PAGE_WORDS;
+ protected final int PAGE_SHIFT;
+ protected final int TOTAL_PAGES;
+ /** This is the upper limit of the pages allocated by the sbrk() syscall. */
+ protected final int BRK_LIMIT;
+ protected final int STACK_BOTTOM;
+
+ /** This is the maximum size of command line arguments */
+ public final static int ARGS_MAX = 1024*1024;
+
+ /** True if we allow empty pages (_emptyPage) to exist in memory.
+ Empty pages are pages which are allocated by the program but do not contain any
+ data yet (they are all 0s). If empty pages are allowed subclasses must always
+ access main memory with the memRead and memWrite functions */
+ private final boolean allowEmptyPages;
+ /** the "empty page" */
+ private final static int[] _emptyPage = new int[0];
+
+ protected final static boolean isEmptyPage(int[] page) { return page == _emptyPage; }
+
+ /** Returns a new empty page (_emptyPage is empty pages are enabled or a new zero'd page) */
+ private final int[] emptyPage() { return allowEmptyPages ? _emptyPage : new int[PAGE_WORDS]; }
+
+ /** Readable main memory pages */
+ protected final int[][] readPages;
+ /** Writable main memory pages.
+ If the page is writable writePages[x] == readPages[x]; if not writePages[x] == null. */
+ protected final int[][] writePages;
+
+ /** The current break between the heap and unallocated memory */
+ protected int brkAddr;
+
+ /** The program's entry point */
+ protected int entryPoint;
+
+ /** The location of the _user_info block (or 0 is there is none) */
+ protected int userInfoBase;
+ protected int userInfoSize;
+
+ /** The location of the global pointer */
+ protected int gp;
+
+ /** When the process started */
+ private long startTime;
+
+ /** State constant: There is no program loaded in memory */
+ public final static int UNINITIALIZED = 0;
+ /** Text/Data loaded in memory */
+ public final static int INITIALIZED = 1;
+ /** Program is executing instructions */
+ public final static int RUNNING = 2;
+ /** Prgram has been started but is paused */
+ public final static int PAUSED = 3;
+ /** Program is executing a callJava() method */
+ public final static int CALLJAVA = 4;
+ /** Program has exited (it cannot currently be restarted) */
+ public final static int DONE = 5;
+
+ /** The current state (UNINITIALIZED, INITIALIZED, RUNNING, PAUSED, or DONE) */
+ protected int state = UNINITIALIZED;
+ /** @see Runtime#state state */
+ public final int getState() { return state; }
+
+ /** The exit status if the process (only valid if state==DONE)
+ @see Runtime#state */
+ protected int exitStatus;
+ public ExecutionException exitException;
+
+ /** Maximum number of open file descriptors */
+ final static int OPEN_MAX = 256;
+ /** Table containing all open file descriptors. (Entries are null if the fd is not in use */
+ FD[] fds = new FD[OPEN_MAX];
+
+ /** Temporary buffer for read/write operations */
+ private byte[] _byteBuf = null;
+ /** Max size of temporary buffer
+ @see Runtime#_byteBuf */
+ private final static int MAX_CHUNK = 15*1024*1024;
+
+ /** Subclasses should actually execute program in this method. They should continue
+ executing until state != RUNNING. Only syscall() can modify state. It is safe
+ to only check the state attribute after a call to syscall() */
+ protected abstract void _execute() throws ExecutionException;
+
+ /** Subclasses should return the address of the symbol <i>symbol</i> or -1 it it doesn't exits in this method
+ This method is only required if the call() function is used */
+ protected int lookupSymbol(String symbol) { return -1; }
+
+ /** Subclasses should returns a CPUState object representing the cpu state */
+ protected abstract CPUState getCPUState();
+
+ /** Subclasses should set the CPUState to the state held in <i>state</i> */
+ protected abstract void setCPUState(CPUState state);
+
+ static void checkPageSize(int pageSize, int totalPages) throws IllegalArgumentException {
+ if(pageSize < 256) throw new IllegalArgumentException("pageSize too small");
+ if((pageSize&(pageSize-1)) != 0) throw new IllegalArgumentException("pageSize must be a power of two");
+ if((totalPages&(totalPages-1)) != 0) throw new IllegalArgumentException("totalPages must be a power of two");
+ if(totalPages != 1 && totalPages < 256) throw new IllegalArgumentException("totalPages too small");
+ if(totalPages * pageSize < 4*1024*1024) throw new IllegalArgumentException("total memory too small (" + totalPages + "*" + pageSize + ")");
+ }
+
+ protected Runtime(int pageSize, int totalPages, boolean allowEmptyPages) {
+ this.allowEmptyPages = allowEmptyPages;
+
+ checkPageSize(pageSize,totalPages);
+
+ PAGE_SIZE = pageSize;
+ PAGE_WORDS = pageSize>>>2;
+ int pageShift = 0;
+ while(pageSize>>>pageShift != 1) pageShift++;
+ PAGE_SHIFT = pageShift;
+
+ TOTAL_PAGES = totalPages;
+
+ readPages = new int[TOTAL_PAGES][];
+ writePages = new int[TOTAL_PAGES][];
+
+ if(TOTAL_PAGES == 1) {
+ readPages[0] = writePages[0] = new int[PAGE_WORDS];
+ BRK_LIMIT = STACK_BOTTOM = 0;
+ } else {
+ int stackPages = max(TOTAL_PAGES>>>8,(1024*1024)>>>PAGE_SHIFT);
+ STACK_BOTTOM = (TOTAL_PAGES - stackPages) * PAGE_SIZE;
+ // leave some unmapped pages between the stack and the heap
+ BRK_LIMIT = STACK_BOTTOM - 4*PAGE_SIZE;
+
+ for(int i=0;i<stackPages;i++)
+ readPages[TOTAL_PAGES-1-i] = writePages[TOTAL_PAGES-1-i] = emptyPage();
+ }
+
+ addFD(new StdinFD(System.in));
+ addFD(new StdoutFD(System.out));
+ addFD(new StdoutFD(System.err));
+ }
+
+ /** Copy everything from <i>src</i> to <i>addr</i> initializing uninitialized pages if required.
+ Newly initalized pages will be marked read-only if <i>ro</i> is set */
+ protected final void initPages(int[] src, int addr, boolean ro) {
+ for(int i=0;i<src.length;) {
+ int page = addr >>> PAGE_SHIFT;
+ int start = (addr&(PAGE_SIZE-1))>>2;
+ int elements = min(PAGE_WORDS-start,src.length-i);
+ if(readPages[page]==null) {
+ initPage(page,ro);
+ } else if(!ro) {
+ if(writePages[page] == null) writePages[page] = readPages[page];
+ }
+ System.arraycopy(src,i,readPages[page],start,elements);
+ i += elements;
+ addr += elements*4;
+ }
+ }
+
+ /** Initialize <i>words</i> of pages starting at <i>addr</i> to 0 */
+ protected final void clearPages(int addr, int words) {
+ for(int i=0;i<words;) {
+ int page = addr >>> PAGE_SHIFT;
+ int start = (addr&(PAGE_SIZE-1))>>2;
+ int elements = min(PAGE_WORDS-start,words-i);
+ if(readPages[page]==null) {
+ readPages[page] = writePages[page] = emptyPage();
+ } else {
+ if(writePages[page] == null) writePages[page] = readPages[page];
+ for(int j=start;j<start+elements;j++) writePages[page][j] = 0;
+ }
+ i += elements;
+ addr += elements*4;
+ }
+ }
+
+ /** Copies <i>length</i> bytes from the processes memory space starting at
+ <i>addr</i> INTO a java byte array <i>a</i> */
+ public final void copyin(int addr, byte[] buf, int count) throws ReadFaultException {
+ int x=0;
+ if((addr&3)!=0) {
+ int word = memRead(addr&~3);
+ switch(addr&3) {
+ case 1: buf[x++] = (byte)((word>>>16)&0xff); if(--count==0) break;
+ case 2: buf[x++] = (byte)((word>>> 8)&0xff); if(--count==0) break;
+ case 3: buf[x++] = (byte)((word>>> 0)&0xff); if(--count==0) break;
+ }
+ addr = (addr&~3)+4;
+ }
+ if((count&~3) != 0) {
+ int c = count>>>2;
+ int a = addr>>>2;
+ while(c != 0) {
+ int[] page = readPages[a >>> (PAGE_SHIFT-2)];
+ if(page == null) throw new ReadFaultException(a<<2);
+ int index = a&(PAGE_WORDS-1);
+ int n = min(c,PAGE_WORDS-index);
+ if(page != _emptyPage) {
+ for(int i=0;i<n;i++,x+=4) {
+ int word = page[index+i];
+ buf[x+0] = (byte)((word>>>24)&0xff); buf[x+1] = (byte)((word>>>16)&0xff);
+ buf[x+2] = (byte)((word>>> 8)&0xff); buf[x+3] = (byte)((word>>> 0)&0xff);
+ }
+ }
+ a += n; c -=n;
+ }
+ addr = a<<2; count &=3;
+ }
+ if(count != 0) {
+ int word = memRead(addr);
+ switch(count) {
+ case 3: buf[x+2] = (byte)((word>>>8)&0xff);
+ case 2: buf[x+1] = (byte)((word>>>16)&0xff);
+ case 1: buf[x+0] = (byte)((word>>>24)&0xff);
+ }
+ }
+ }
+
+ /** Copies <i>length</i> bytes OUT OF the java array <i>a</i> into the processes memory
+ space at <i>addr</i> */
+ public final void copyout(byte[] buf, int addr, int count) throws FaultException {
+ int x=0;
+ if((addr&3)!=0) {
+ int word = memRead(addr&~3);
+ switch(addr&3) {
+ case 1: word = (word&0xff00ffff)|((buf[x++]&0xff)<<16); if(--count==0) break;
+ case 2: word = (word&0xffff00ff)|((buf[x++]&0xff)<< 8); if(--count==0) break;
+ case 3: word = (word&0xffffff00)|((buf[x++]&0xff)<< 0); if(--count==0) break;
+ }
+ memWrite(addr&~3,word);
+ addr += x;
+ }
+ if((count&~3) != 0) {
+ int c = count>>>2;
+ int a = addr>>>2;
+ while(c != 0) {
+ int[] page = writePages[a >>> (PAGE_SHIFT-2)];
+ if(page == null) throw new WriteFaultException(a<<2);
+ if(page == _emptyPage) page = initPage(a >>> (PAGE_SHIFT-2));
+ int index = a&(PAGE_WORDS-1);
+ int n = min(c,PAGE_WORDS-index);
+ for(int i=0;i<n;i++,x+=4)
+ page[index+i] = ((buf[x+0]&0xff)<<24)|((buf[x+1]&0xff)<<16)|((buf[x+2]&0xff)<<8)|((buf[x+3]&0xff)<<0);
+ a += n; c -=n;
+ }
+ addr = a<<2; count&=3;
+ }
+ if(count != 0) {
+ int word = memRead(addr);
+ switch(count) {
+ case 1: word = (word&0x00ffffff)|((buf[x+0]&0xff)<<24); break;
+ case 2: word = (word&0x0000ffff)|((buf[x+0]&0xff)<<24)|((buf[x+1]&0xff)<<16); break;
+ case 3: word = (word&0x000000ff)|((buf[x+0]&0xff)<<24)|((buf[x+1]&0xff)<<16)|((buf[x+2]&0xff)<<8); break;
+ }
+ memWrite(addr,word);
+ }
+ }
+
+ public final void memcpy(int dst, int src, int count) throws FaultException {
+ if((dst&3) == 0 && (src&3)==0) {
+ if((count&~3) != 0) {
+ int c = count>>2;
+ int s = src>>>2;
+ int d = dst>>>2;
+ while(c != 0) {
+ int[] srcPage = readPages[s>>>(PAGE_SHIFT-2)];
+ if(srcPage == null) throw new ReadFaultException(s<<2);
+ int[] dstPage = writePages[d>>>(PAGE_SHIFT-2)];
+ if(dstPage == null) throw new WriteFaultException(d<<2);
+ int srcIndex = (s&(PAGE_WORDS-1));
+ int dstIndex = (d&(PAGE_WORDS-1));
+ int n = min(c,PAGE_WORDS-max(srcIndex,dstIndex));
+ if(srcPage != _emptyPage) {
+ if(dstPage == _emptyPage) dstPage = initPage(d>>>(PAGE_SHIFT-2));
+ System.arraycopy(srcPage,srcIndex,dstPage,dstIndex,n);
+ } else if(srcPage == _emptyPage && dstPage != _emptyPage) {
+ Arrays.fill(dstPage,dstIndex,dstIndex+n,0);
+ }
+ s += n; d += n; c -= n;
+ }
+ src = s<<2; dst = d<<2; count&=3;
+ }
+ if(count != 0) {
+ int word1 = memRead(src);
+ int word2 = memRead(dst);
+ switch(count) {
+ case 1: memWrite(dst,(word1&0xff000000)|(word2&0x00ffffff)); break;
+ case 2: memWrite(dst,(word1&0xffff0000)|(word2&0x0000ffff)); break;
+ case 3: memWrite(dst,(word1&0xffffff00)|(word2&0x000000ff)); break;
+ }
+ }
+ } else {
+ while(count > 0) {
+ int n = min(count,MAX_CHUNK);
+ byte[] buf = byteBuf(n);
+ copyin(src,buf,n);
+ copyout(buf,dst,n);
+ count -= n; src += n; dst += n;
+ }
+ }
+ }
+
+ public final void memset(int addr, int ch, int count) throws FaultException {
+ int fourBytes = ((ch&0xff)<<24)|((ch&0xff)<<16)|((ch&0xff)<<8)|((ch&0xff)<<0);
+ if((addr&3)!=0) {
+ int word = memRead(addr&~3);
+ switch(addr&3) {
+ case 1: word = (word&0xff00ffff)|((ch&0xff)<<16); if(--count==0) break;
+ case 2: word = (word&0xffff00ff)|((ch&0xff)<< 8); if(--count==0) break;
+ case 3: word = (word&0xffffff00)|((ch&0xff)<< 0); if(--count==0) break;
+ }
+ memWrite(addr&~3,word);
+ addr = (addr&~3)+4;
+ }
+ if((count&~3) != 0) {
+ int c = count>>2;
+ int a = addr>>>2;
+ while(c != 0) {
+ int[] page = readPages[a>>>(PAGE_SHIFT-2)];
+ if(page == null) throw new WriteFaultException(a<<2);
+ int index = (a&(PAGE_WORDS-1));
+ int n = min(c,PAGE_WORDS-index);
+ if(page != _emptyPage || ch != 0) {
+ if(page == _emptyPage) page = initPage(a>>>(PAGE_SHIFT-2));
+ Arrays.fill(page,index,index+n,fourBytes);
+ }
+ a += n; c -= n;
+ }
+ addr = a<<2; count&=3;
+ }
+ if(count != 0) {
+ int word = memRead(addr);
+ switch(count) {
+ case 1: word = (word&0x00ffffff)|(fourBytes&0xff000000); break;
+ case 2: word = (word&0x0000ffff)|(fourBytes&0xffff0000); break;
+ case 3: word = (word&0x000000ff)|(fourBytes&0xffffff00); break;
+ }
+ memWrite(addr,word);
+ }
+ }
+
+ /** Read a word from the processes memory at <i>addr</i> */
+ public final int memRead(int addr) throws ReadFaultException {
+ if((addr & 3) != 0) throw new ReadFaultException(addr);
+ return unsafeMemRead(addr);
+ }
+
+ protected final int unsafeMemRead(int addr) throws ReadFaultException {
+ int page = addr >>> PAGE_SHIFT;
+ int entry = (addr >>> 2) & (PAGE_WORDS-1);
+ try {
+ return readPages[page][entry];
+ } catch(ArrayIndexOutOfBoundsException e) {
+ if(page < 0) throw e; // should never happen
+ if(page >= readPages.length) throw new ReadFaultException(addr);
+ if(readPages[page] != _emptyPage) throw e; // should never happen
+ initPage(page);
+ return 0;
+ } catch(NullPointerException e) {
+ throw new ReadFaultException(addr);
+ }
+ }
+
+ /** Writes a word to the processes memory at <i>addr</i> */
+ public final void memWrite(int addr, int value) throws WriteFaultException {
+ if((addr & 3) != 0) throw new WriteFaultException(addr);
+ unsafeMemWrite(addr,value);
+ }
+
+ protected final void unsafeMemWrite(int addr, int value) throws WriteFaultException {
+ int page = addr >>> PAGE_SHIFT;
+ int entry = (addr>>>2)&(PAGE_WORDS-1);
+ try {
+ writePages[page][entry] = value;
+ } catch(ArrayIndexOutOfBoundsException e) {
+ if(page < 0) throw e;// should never happen
+ if(page >= writePages.length) throw new WriteFaultException(addr);
+ if(readPages[page] != _emptyPage) throw e; // should never happen
+ initPage(page);
+ writePages[page][entry] = value;
+ } catch(NullPointerException e) {
+ throw new WriteFaultException(addr);
+ }
+ }
+
+ /** Created a new non-empty writable page at page number <i>page</i> */
+ private final int[] initPage(int page) { return initPage(page,false); }
+ /** Created a new non-empty page at page number <i>page</i>. If <i>ro</i> is set the page will be read-only */
+ private final int[] initPage(int page, boolean ro) {
+ int[] buf = new int[PAGE_WORDS];
+ writePages[page] = ro ? null : buf;
+ readPages[page] = buf;
+ return buf;
+ }
+
+ /** Returns the exit status of the process. (only valid if state == DONE)
+ @see Runtime#state */
+ public final int exitStatus() {
+ if(state != DONE) throw new IllegalStateException("exitStatus() called in an inappropriate state");
+ return exitStatus;
+ }
+
+ private int addStringArray(String[] strings, int topAddr) {
+ int count = strings.length;
+ int total = 0; /* null last table entry */
+ for(int i=0;i<count;i++) total += strings[i].length() + 1;
+ if(total >= ARGS_MAX) throw new IllegalArgumentException("arguments/environ too big");
+ total += (count+1)*4;
+ int start = (topAddr - total)&~3;
+ int addr = start + (count+1)*4;
+ int[] table = new int[count+1];
+ try {
+ for(int i=0;i<count;i++) {
+ byte[] a = getBytes(strings[i]);
+ table[i] = addr;
+ copyout(a,addr,a.length);
+ memset(addr+a.length,0,1);
+ addr += a.length + 1;
+ }
+ addr=start;
+ for(int i=0;i<count+1;i++) {
+ memWrite(addr,table[i]);
+ addr += 4;
+ }
+ } catch(FaultException e) {
+ // should never happen
+ throw new Error(e.toString());
+ }
+ return start;
+ }
+
+ protected String[] createEnv(String[] extra) { if(extra == null) extra = new String[0]; return extra; }
+
+ /** Sets word number <i>index</i> in the _user_info table to <i>word</i>
+ * The user_info table is a chunk of memory in the program's memory defined by the
+ * symbol "user_info". The compiler/interpreter automatically determine the size
+ * and location of the user_info table from the ELF symbol table. setUserInfo and
+ * getUserInfo are used to modify the words in the user_info table. */
+ public void setUserInfo(int index, int word) {
+ if(index < 0 || index >= userInfoSize/4) throw new IndexOutOfBoundsException("setUserInfo called with index >= " + (userInfoSize/4));
+ try {
+ memWrite(userInfoBase+index*4,word);
+ } catch(FaultException e) { throw new Error("should never happen: " + e); }
+ }
+
+ /** Returns the word in the _user_info table entry <i>index</i>
+ @see Runtime#setUserInfo(int,int) setUserInfo */
+ public int getUserInfo(int index) {
+ if(index < 0 || index >= userInfoSize/4) throw new IndexOutOfBoundsException("setUserInfo called with index >= " + (userInfoSize/4));
+ try {
+ return memRead(userInfoBase+index*4);
+ } catch(FaultException e) { throw new Error("should never happen: " + e); }
+ }
+
+ /** Calls _execute() (subclass's execute()) and catches exceptions */
+ private void __execute() {
+ try {
+ _execute();
+ } catch(FaultException e) {
+ e.printStackTrace();
+ sys_exit(128+11); // SIGSEGV
+ exitException = e;
+ } catch(ExecutionException e) {
+ e.printStackTrace();
+ System.err.println(e);
+ sys_exit(128+4); // SIGILL
+ exitException = e;
+ }
+ }
+
+ /** Executes the process until the PAUSE syscall is invoked or the process exits. Returns true if the process exited. */
+ public final boolean execute() {
+ if(state != PAUSED) throw new IllegalStateException("execute() called in inappropriate state");
+ if(startTime == 0) startTime = System.currentTimeMillis();
+ state = RUNNING;
+ __execute();
+ if(state != PAUSED && state != DONE) throw new IllegalStateException("execute() ended up in an inappropriate state (" + state + ")");
+ return state == DONE;
+ }
+
+ public final int run() { return run(null); }
+ public final int run(String argv0, String[] rest) {
+ String[] args = new String[rest.length+1];
+ System.arraycopy(rest,0,args,1,rest.length);
+ args[0] = argv0;
+ return run(args);
+ }
+ public final int run(String[] args) { return run(args,null); }
+
+ /** Runs the process until it exits and returns the exit status.
+ If the process executes the PAUSE syscall execution will be paused for 500ms and a warning will be displayed */
+ public final int run(String[] args, String[] env) {
+ start(args,env);
+ for(;;) {
+ if(execute()) break;
+ System.err.println("WARNING: Pause requested while executing run()");
+ try { Thread.sleep(500); } catch(InterruptedException e) { /* noop */ }
+ }
+ return exitStatus();
+ }
+
+ public final void start() { start(null); }
+ public final void start(String[] args) { start(args,null); }
+
+ /** Initializes the process and prepairs it to be executed with execute() */
+ public final void start(String[] args, String[] environ) {
+ int sp, argsAddr, envAddr;
+ if(state != INITIALIZED) throw new IllegalStateException("start() called in inappropriate state");
+
+ if(args == null) args = new String[]{getClass().getName()};
+
+ sp = TOTAL_PAGES*PAGE_SIZE-512;
+ sp = argsAddr = addStringArray(args,sp);
+ sp = envAddr = addStringArray(createEnv(environ),sp);
+ sp &= ~15;
+
+ CPUState cpuState = new CPUState();
+ cpuState.r[A0] = argsAddr;
+ cpuState.r[A1] = envAddr;
+ cpuState.r[SP] = sp;
+ cpuState.r[RA] = 0xdeadbeef;
+ cpuState.r[GP] = gp;
+ cpuState.pc = entryPoint;
+ setCPUState(cpuState);
+
+ state = PAUSED;
+
+ _start();
+ }
+
+ /** Hook for subclasses to do their own startup */
+ protected void _start() { /* noop */ }
+
+ public final int call(String sym) throws CallException { return call(sym,0,0,0,0,0,0,0); }
+ public final int call(String sym, int a0) throws CallException { return call(sym,a0,0,0,0,0,0,0); }
+ public final int call(String sym, int a0, int a1) throws CallException { return call(sym,a0,a1,0,0,0,0,0); }
+ public final int call(String sym, int a0, int a1, int a2) throws CallException { return call(sym,a0,a1,a2,0,0,0,0); }
+ public final int call(String sym, int a0, int a1, int a2, int a3) throws CallException { return call(sym,a0,a1,a2,a3,0,0,0); }
+ public final int call(String sym, int a0, int a1, int a2, int a3, int a4) throws CallException { return call(sym,a0,a1,a2,a3,a4,0,0); }
+ public final int call(String sym, int a0, int a1, int a2, int a3, int a4, int a5) throws CallException { return call(sym,a0,a1,a2,a3,a4,a5,0); }
+
+ /** Calls a function in the process with the given arguments */
+ public final int call(String sym, int a0, int a1, int a2, int a3, int a4, int a5, int a6) throws CallException {
+ int func = lookupSymbol(sym);
+ if(func == -1) throw new CallException(sym + " not found");
+ int helper = lookupSymbol("_call_helper");
+ if(helper == -1) throw new CallException("_call_helper not found");
+ return call(helper,func,a0,a1,a2,a3,a4,a5,a6);
+ }
+
+ /** Executes the code at <i>addr</i> in the process setting A0-A3 and S0-S3 to the given arguments
+ and returns the contents of V1 when the the pause syscall is invoked */
+ public final int call(int addr, int a0, int a1, int a2, int a3, int s0, int s1, int s2, int s3) {
+ if(state != PAUSED && state != CALLJAVA) throw new IllegalStateException("call() called in inappropriate state");
+ int oldState = state;
+ CPUState saved = getCPUState();
+ CPUState cpustate = new CPUState();
+ cpustate.r[SP] = saved.r[SP]&~15;
+ cpustate.r[RA] = 0xdeadbeef;
+ cpustate.r[A0] = a0;
+ cpustate.r[A1] = a1;
+ cpustate.r[A2] = a2;
+ cpustate.r[A3] = a3;
+ cpustate.r[S0] = s0;
+ cpustate.r[S1] = s1;
+ cpustate.r[S2] = s2;
+ cpustate.r[S3] = s3;
+ cpustate.r[GP] = gp;
+ cpustate.pc = addr;
+
+ state = RUNNING;
+
+ setCPUState(cpustate);
+ __execute();
+ cpustate = getCPUState();
+ setCPUState(saved);
+
+ if(state != PAUSED)
+ System.out.println("WARNING: Process exit()ed while servicing a call() request");
+ else
+ state = oldState;
+
+ return cpustate.r[V1];
+ }
+
+ // FEATURE: This is ugly - we should have some kind of way to specify a callback rather than requiring subclassing
+ protected int callJava(int a, int b, int c, int d) {
+ System.err.println("WARNING: Default implementation of callJava() called with args " + toHex(a) + "," + toHex(b) + "," + toHex(c) + "," + toHex(d));
+ return 0;
+ }
+
+ /** Determines if the process can access <i>fileName</i>. The default implementation simply logs
+ the request and allows it */
+ protected boolean allowFileAccess(String fileName, boolean write) {
+ //System.err.println("Allowing " + (write?"write":"read-only") + " access to " + fileName);
+ return true;
+ }
+
+ /** Allocated an entry in the FileDescriptor table for <i>fd</i> and returns the number.
+ Returns -1 if the table is full. This can be used by subclasses to use custom file
+ descriptors */
+ public int addFD(FD fd) {
+ int i;
+ for(i=0;i<OPEN_MAX;i++) if(fds[i] == null) break;
+ if(i==OPEN_MAX) return -1;
+ fds[i] = fd;
+ return i;
+ }
+
+ /** Closes file descriptor <i>fdn</i> and removes it from the file descriptor table */
+ public boolean closeFD(int fdn) {
+ if(fdn < 0 || fdn >= OPEN_MAX) return false;
+ if(fds[fdn] == null) return false;
+ fds[fdn].close();
+ fds[fdn] = null;
+ return true;
+ }
+
+ // FEATURE: These should be pulled in from UsermodeConstants but fcntl.h is hard to parse
+ public static final int RD_ONLY = 0;
+ public static final int WR_ONLY = 1;
+ public static final int RDWR = 2;
+
+ public static final int O_CREAT = 0x0200;
+ public static final int O_EXCL = 0x0800;
+ public static final int O_APPEND = 0x0008;
+ public static final int O_TRUNC = 0x0400;
+ public static final int O_NONBLOCK = 0x4000;
+
+ // FEATURE: Lots of duplicate code between this and UnixRuntime.HostFS.open()
+ protected FD open(String path, int flags, int mode) throws IOException {
+ final File f = new File(path);
+ // NOTE: createNewFile is a Java2 function
+ if((flags & (O_EXCL|O_CREAT)) == (O_EXCL|O_CREAT))
+ if(!f.createNewFile()) throw new ErrnoException(EEXIST);
+ if(!f.exists() && (flags&O_CREAT) == 0) return null;
+ if(f.isDirectory()) return null;
+ final SeekableFile sf = new SeekableFile(path,mode!=RD_ONLY);
+ if((flags&O_TRUNC)!=0) sf.setLength(0);
+ return new SeekableFD(sf,flags) {
+ protected FStat _fstat() { return new HostFStat(f) {
+ public int size() {
+ try { return sf.length(); } catch(IOException e) { return 0; }
+ }
+ };}
+ };
+ }
+
+ /** The open syscall */
+ private int sys_open(int addr, int flags, int mode) {
+ if((flags & O_NONBLOCK) != 0) {
+ System.err.println("WARNING: O_NONBLOCK not supported");
+ return -EOPNOTSUPP;
+ }
+
+ try {
+ FD fd = open(cstring(addr),flags,mode);
+ if(fd == null) return -ENOENT;
+ int fdn = addFD(fd);
+ if(fdn == -1) {
+ fd.close();
+ return -ENFILE;
+ }
+ return fdn;
+ }
+ catch(ErrnoException e) { return -e.errno; }
+ catch(FileNotFoundException e) {
+ if(e.getMessage() != null && e.getMessage().indexOf("Permission denied") >= 0) return -EACCES;
+ return -ENOENT;
+ }
+ catch(IOException e) { return -EIO; }
+ catch(FaultException e) { return -EFAULT; }
+ }
+
+ /** The write syscall */
+ private int sys_write(int fdn, int addr, int count) {
+ count = Math.min(count,MAX_CHUNK);
+ if(fdn < 0 || fdn >= OPEN_MAX) return -EBADFD;
+ if(fds[fdn] == null || !fds[fdn].writable()) return -EBADFD;
+ try {
+ byte[] buf = byteBuf(count);
+ copyin(addr,buf,count);
+ return fds[fdn].write(buf,0,count);
+ } catch(FaultException e) {
+ System.err.println(e);
+ return -EFAULT;
+ } catch(IOException e) {
+ // FEATURE: We should support signals and send a SIGPIPE
+ if(e.getMessage().equals("Pipe closed")) return sys_exit(128+13);
+ System.err.println(e);
+ return -EIO;
+ }
+ }
+
+ /** The read syscall */
+ private int sys_read(int fdn, int addr, int count) {
+ count = Math.min(count,MAX_CHUNK);
+ if(fdn < 0 || fdn >= OPEN_MAX) return -EBADFD;
+ if(fds[fdn] == null || !fds[fdn].readable()) return -EBADFD;
+ try {
+ byte[] buf = byteBuf(count);
+ int n = fds[fdn].read(buf,0,count);
+ copyout(buf,addr,n);
+ return n;
+ } catch(FaultException e) {
+ System.err.println(e);
+ return -EFAULT;
+ } catch(IOException e) {
+ System.err.println(e);
+ return -EIO;
+ }
+ }
+
+ /** The close syscall */
+ private int sys_close(int fdn) {
+ return closeFD(fdn) ? 0 : -EBADFD;
+ }
+
+
+ /** The seek syscall */
+ private int sys_lseek(int fdn, int offset, int whence) {
+ if(fdn < 0 || fdn >= OPEN_MAX) return -EBADFD;
+ if(fds[fdn] == null) return -EBADFD;
+ if(whence != SEEK_SET && whence != SEEK_CUR && whence != SEEK_END) return -EINVAL;
+ try {
+ int n = fds[fdn].seek(offset,whence);
+ return n < 0 ? -ESPIPE : n;
+ } catch(IOException e) {
+ return -ESPIPE;
+ }
+ }
+
+ /** The stat/fstat syscall helper */
+ int stat(FStat fs, int addr) {
+ try {
+ memWrite(addr+0,(fs.dev()<<16)|(fs.inode()&0xffff)); // st_dev (top 16), // st_ino (bottom 16)
+ memWrite(addr+4,((fs.type()&0xf000))|(fs.mode()&0xfff)); // st_mode
+ memWrite(addr+8,1<<16); // st_nlink (top 16) // st_uid (bottom 16)
+ memWrite(addr+12,0); // st_gid (top 16) // st_rdev (bottom 16)
+ memWrite(addr+16,fs.size()); // st_size
+ memWrite(addr+20,fs.atime()); // st_atime
+ // memWrite(addr+24,0) // st_spare1
+ memWrite(addr+28,fs.mtime()); // st_mtime
+ // memWrite(addr+32,0) // st_spare2
+ memWrite(addr+36,fs.ctime()); // st_ctime
+ // memWrite(addr+40,0) // st_spare3
+ memWrite(addr+44,fs.blksize()); // st_bklsize;
+ memWrite(addr+48,fs.blocks()); // st_blocks
+ // memWrite(addr+52,0) // st_spare4[0]
+ // memWrite(addr+56,0) // st_spare4[1]
+ } catch(FaultException e) {
+ System.err.println(e);
+ return -EFAULT;
+ }
+ return 0;
+ }
+
+ /** The fstat syscall */
+ private int sys_fstat(int fdn, int addr) {
+ if(fdn < 0 || fdn >= OPEN_MAX) return -EBADFD;
+ if(fds[fdn] == null) return -EBADFD;
+ return stat(fds[fdn].fstat(),addr);
+ }
+
+ /*
+ struct timeval {
+ long tv_sec;
+ long tv_usec;
+ };
+ */
+ private int sys_gettimeofday(int timevalAddr, int timezoneAddr) {
+ long now = System.currentTimeMillis();
+ int tv_sec = (int)(now / 1000);
+ int tv_usec = (int)((now%1000)*1000);
+ try {
+ memWrite(timevalAddr+0,tv_sec);
+ memWrite(timevalAddr+4,tv_usec);
+ return 0;
+ } catch(FaultException e) {
+ return -EFAULT;
+ }
+ }
+
+ private int sys_sleep(int sec) {
+ if(sec < 0) sec = Integer.MAX_VALUE;
+ try {
+ Thread.sleep((long)sec*1000);
+ return 0;
+ } catch(InterruptedException e) {
+ return -1;
+ }
+ }
+
+ /*
+ #define _CLOCKS_PER_SEC_ 1000
+ #define _CLOCK_T_ unsigned long
+ struct tms {
+ clock_t tms_utime;
+ clock_t tms_stime;
+ clock_t tms_cutime;
+ clock_t tms_cstime;
+ };*/
+
+ private int sys_times(int tms) {
+ long now = System.currentTimeMillis();
+ int userTime = (int)((now - startTime)/16);
+ int sysTime = (int)((now - startTime)/16);
+
+ try {
+ if(tms!=0) {
+ memWrite(tms+0,userTime);
+ memWrite(tms+4,sysTime);
+ memWrite(tms+8,userTime);
+ memWrite(tms+12,sysTime);
+ }
+ } catch(FaultException e) {
+ return -EFAULT;
+ }
+ return (int)now;
+ }
+
+ private int sys_sysconf(int n) {
+ switch(n) {
+ case _SC_CLK_TCK: return 1000;
+ default:
+ System.err.println("WARNING: Attempted to use unknown sysconf key: " + n);
+ return -EINVAL;
+ }
+ }
+
+ /** The sbrk syscall. This can also be used by subclasses to allocate memory.
+ <i>incr</i> is how much to increase the break by */
+ public int sbrk(int incr) {
+ if(incr < 0) return -ENOMEM;
+ if(incr==0) return brkAddr;
+ incr = (incr+3)&~3;
+ int oldBrk = brkAddr;
+ int newBrk = oldBrk + incr;
+ if(TOTAL_PAGES == 1) {
+ CPUState state = getCPUState();
+ if(newBrk >= state.r[SP] - 65536) {
+ System.err.println("WARNING: brk too close to stack pointer");
+ return -ENOMEM;
+ }
+ } else if(newBrk >= BRK_LIMIT) {
+ System.err.println("WARNING: Hit BRK_LIMIT");
+ return -ENOMEM;
+ }
+ if(TOTAL_PAGES != 1) {
+ try {
+ for(int i=(oldBrk+PAGE_SIZE-1)>>>PAGE_SHIFT;i<((newBrk+PAGE_SIZE-1)>>>PAGE_SHIFT);i++)
+ readPages[i] = writePages[i] = emptyPage();
+ } catch(OutOfMemoryError e) {
+ System.err.println("WARNING: Caught OOM Exception in sbrk: " + e);
+ return -ENOMEM;
+ }
+ }
+ brkAddr = newBrk;
+ return oldBrk;
+ }
+
+ /** The getpid syscall */
+ private int sys_getpid() { return getPid(); }
+ protected int getPid() { return 1; }
+
+ private int sys_calljava(int a, int b, int c, int d) {
+ if(state != RUNNING) throw new IllegalStateException("wound up calling sys_calljava while not in RUNNING");
+ state = CALLJAVA;
+ int ret = callJava(a,b,c,d);
+ state = RUNNING;
+ return ret;
+ }
+
+ private int sys_pause() {
+ state = PAUSED;
+ return 0;
+ }
+
+ private int sys_getpagesize() { return TOTAL_PAGES == 1 ? 4096 : PAGE_SIZE; }
+
+ private int sys_isatty(int fdn) {
+ if(fdn < 0 || fdn >= OPEN_MAX) return -EBADFD;
+ if(fds[fdn] == null) return -EBADFD;
+ return fds[fdn].isatty() ? 1 : 0;
+ }
+
+
+ /** Hook for subclasses to do something when the process exits (MUST set state = DONE) */
+ protected void _exit() { state = DONE; }
+ private int sys_exit(int status) {
+ exitStatus = status;
+ for(int i=0;i<fds.length;i++) if(fds[i] != null) sys_close(i);
+ _exit();
+ return 0;
+ }
+
+ private int sys_fcntl(int fdn, int cmd, int arg) {
+ final int F_DUPFD = 0;
+ final int F_GETFL = 3;
+ int i;
+
+ if(fdn < 0 || fdn >= OPEN_MAX) return -EBADFD;
+ if(fds[fdn] == null) return -EBADFD;
+ FD fd = fds[fdn];
+
+ switch(cmd) {
+ case F_DUPFD:
+ if(arg < 0 || arg >= OPEN_MAX) return -EINVAL;
+ for(i=arg;i<OPEN_MAX;i++) if(fds[i]==null) break;
+ if(i==OPEN_MAX) return -EMFILE;
+ fds[i] = fd.dup();
+ return 0;
+ case F_GETFL:
+ int flags = 0;
+ if(fd.writable() && fd.readable()) flags = 2;
+ else if(fd.writable()) flags = 1;
+ return flags;
+ default:
+ System.err.println("WARNING: Unknown fcntl command: " + cmd);
+ return -ENOSYS;
+ }
+ }
+
+ /** The syscall dispatcher.
+ The should be called by subclasses when the syscall instruction is invoked.
+ <i>syscall</i> should be the contents of V0 and <i>a</i>, <i>b</i>, <i>c</i>, and <i>d</i> should be
+ the contenst of A0, A1, A2, and A3. The call MAY change the state
+ @see Runtime#state state */
+ protected int syscall(int syscall, int a, int b, int c, int d) {
+ switch(syscall) {
+ case SYS_null: return 0;
+ case SYS_exit: return sys_exit(a);
+ case SYS_pause: return sys_pause();
+ case SYS_write: return sys_write(a,b,c);
+ case SYS_fstat: return sys_fstat(a,b);
+ case SYS_sbrk: return sbrk(a);
+ case SYS_open: return sys_open(a,b,c);
+ case SYS_close: return sys_close(a);
+ case SYS_read: return sys_read(a,b,c);
+ case SYS_lseek: return sys_lseek(a,b,c);
+ case SYS_getpid: return sys_getpid();
+ case SYS_calljava: return sys_calljava(a,b,c,d);
+ case SYS_gettimeofday: return sys_gettimeofday(a,b);
+ case SYS_sleep: return sys_sleep(a);
+ case SYS_times: return sys_times(a);
+ case SYS_getpagesize: return sys_getpagesize();
+ case SYS_isatty: return sys_isatty(a);
+ case SYS_fcntl: return sys_fcntl(a,b,c);
+ case SYS_sysconf: return sys_sysconf(a);
+
+ case SYS_kill:
+ case SYS_fork:
+ case SYS_pipe:
+ case SYS_dup2:
+ case SYS_waitpid:
+ case SYS_stat:
+ case SYS_mkdir:
+ case SYS_getcwd:
+ case SYS_chdir:
+ System.err.println("Attempted to use a UnixRuntime syscall in Runtime (" + syscall + ")");
+ return -ENOSYS;
+ default:
+ System.err.println("Attempted to use unknown syscall: " + syscall);
+ return -ENOSYS;
+ }
+ }
+
+ public int xmalloc(int size) { int p=malloc(size); if(p==0) throw new RuntimeException("malloc() failed"); return p; }
+ public int xrealloc(int addr,int newsize) { int p=realloc(addr,newsize); if(p==0) throw new RuntimeException("realloc() failed"); return p; }
+ public int realloc(int addr, int newsize) { try { return call("realloc",addr,newsize); } catch(CallException e) { return 0; } }
+ public int malloc(int size) { try { return call("malloc",size); } catch(CallException e) { return 0; } }
+ public void free(int p) { try { if(p!=0) call("free",p); } catch(CallException e) { /*noop*/ } }
+
+ /** Helper function to create a cstring in main memory */
+ public int strdup(String s) {
+ byte[] a;
+ if(s == null) s = "(null)";
+ byte[] a2 = getBytes(s);
+ a = new byte[a2.length+1];
+ System.arraycopy(a2,0,a,0,a2.length);
+ int addr = malloc(a.length);
+ if(addr == 0) return 0;
+ try {
+ copyout(a,addr,a.length);
+ } catch(FaultException e) {
+ free(addr);
+ return 0;
+ }
+ return addr;
+ }
+
+ /** Helper function to read a cstring from main memory */
+ public String cstring(int addr) throws ReadFaultException {
+ StringBuffer sb = new StringBuffer();
+ for(;;) {
+ int word = memRead(addr&~3);
+ switch(addr&3) {
+ case 0: if(((word>>>24)&0xff)==0) return sb.toString(); sb.append((char)((word>>>24)&0xff)); addr++;
+ case 1: if(((word>>>16)&0xff)==0) return sb.toString(); sb.append((char)((word>>>16)&0xff)); addr++;
+ case 2: if(((word>>> 8)&0xff)==0) return sb.toString(); sb.append((char)((word>>> 8)&0xff)); addr++;
+ case 3: if(((word>>> 0)&0xff)==0) return sb.toString(); sb.append((char)((word>>> 0)&0xff)); addr++;
+ }
+ }
+ }
+
+ /** File Descriptor class */
+ public static abstract class FD {
+ private int refCount = 1;
+
+ /** returns true if the fd is readable */
+ public boolean readable() { return false; }
+ /** returns true if the fd is writable */
+ public boolean writable() { return false; }
+
+ /** Read some bytes. Should return the number of bytes read, 0 on EOF, or throw an IOException on error */
+ public int read(byte[] a, int off, int length) throws IOException { throw new IOException("no definition"); }
+ /** Write. Should return the number of bytes written or throw an IOException on error */
+ public int write(byte[] a, int off, int length) throws IOException { throw new IOException("no definition"); }
+
+ /** Seek in the filedescriptor. Whence is SEEK_SET, SEEK_CUR, or SEEK_END. Should return -1 on error or the new position. */
+ public int seek(int n, int whence) throws IOException { return -1; }
+
+ /** Should return true if this is a tty */
+ public boolean isatty() { return false; }
+
+ private FStat cachedFStat = null;
+ public final FStat fstat() {
+ if(cachedFStat == null) cachedFStat = _fstat();
+ return cachedFStat;
+ }
+
+ protected abstract FStat _fstat();
+
+ /** Closes the fd */
+ public final void close() { if(--refCount==0) _close(); }
+ protected void _close() { /* noop*/ }
+
+ FD dup() { refCount++; return this; }
+ }
+
+ /** FileDescriptor class for normal files */
+ public abstract static class SeekableFD extends FD {
+ private final int flags;
+ private final SeekableData data;
+ public boolean readable() { return (flags&3) != WR_ONLY; }
+ public boolean writable() { return (flags&3) != RD_ONLY; }
+
+ SeekableFD(SeekableData data, int flags) { this.data = data; this.flags = flags; }
+
+ protected abstract FStat _fstat();
+
+ public int seek(int n, int whence) throws IOException {
+ switch(whence) {
+ case SEEK_SET: break;
+ case SEEK_CUR: n += data.pos(); break;
+ case SEEK_END: n += data.length(); break;
+ default: return -1;
+ }
+ data.seek(n);
+ return n;
+ }
+
+ public int write(byte[] a, int off, int length) throws IOException {
+ // NOTE: There is race condition here but we can't fix it in pure java
+ if((flags&O_APPEND) != 0) seek(0,SEEK_END);
+ return data.write(a,off,length);
+ }
+
+ public int read(byte[] a, int off, int length) throws IOException {
+ int n = data.read(a,off,length);
+ return n < 0 ? 0 : n;
+ }
+
+ protected void _close() { try { data.close(); } catch(IOException e) { /*ignore*/ } }
+ }
+
+ public static class OutputStreamFD extends FD {
+ private OutputStream os;
+ public boolean writable() { return true; }
+ public OutputStreamFD(OutputStream os) { this.os = os; }
+ public int write(byte[] a, int off, int length) throws IOException { os.write(a,off,length); return length; }
+ public void _close() { try { os.close(); } catch(IOException e) { /*ignore*/ } }
+ public FStat _fstat() { return new FStat(); }
+ }
+
+ public static class InputStreamFD extends FD {
+ private InputStream is;
+ public boolean readable() { return true; }
+ public InputStreamFD(InputStream is) { this.is = is; }
+ public int read(byte[] a, int off, int length) throws IOException { int n = is.read(a,off,length); return n < 0 ? 0 : n; }
+ public void _close() { try { is.close(); } catch(IOException e) { /*ignore*/ } }
+ public FStat _fstat() { return new FStat(); }
+ }
+
+ protected static class StdinFD extends InputStreamFD {
+ public StdinFD(InputStream is) { super(is); }
+ public void _close() { /* noop */ }
+ public FStat _fstat() { return new FStat() { public int type() { return S_IFCHR; } }; }
+ public boolean isatty() { return true; }
+ }
+ protected static class StdoutFD extends OutputStreamFD {
+ public StdoutFD(OutputStream os) { super(os); }
+ public void _close() { /* noop */ }
+ public FStat _fstat() { return new FStat() { public int type() { return S_IFCHR; } }; }
+ public boolean isatty() { return true; }
+ }
+
+ public static class FStat {
+ public static final int S_IFIFO = 0010000;
+ public static final int S_IFCHR = 0020000;
+ public static final int S_IFDIR = 0040000;
+ public static final int S_IFREG = 0100000;
+
+ public int dev() { return -1; }
+ // FEATURE: inode numbers are calculated inconsistently throught the runtime
+ public int inode() { return hashCode() & 0xfffff; }
+ public int mode() { return 0; }
+ public int type() { return S_IFIFO; }
+ public int nlink() { return 0; }
+ public int uid() { return 0; }
+ public int gid() { return 0; }
+ public int size() { return 0; }
+ public int atime() { return 0; }
+ public int mtime() { return 0; }
+ public int ctime() { return 0; }
+ public int blksize() { return 512; }
+ public int blocks() { return (size()+blksize()-1)/blksize(); }
+ }
+
+ protected static class HostFStat extends FStat {
+ private final File f;
+ private final boolean executable;
+ public HostFStat(File f) {
+ this.f = f;
+ String name = f.getName();
+ // FEATURE: This is ugly.. maybe we should do a file(1) type check
+ executable = name.endsWith(".mips") || name.endsWith(".sh");
+ }
+ public int dev() { return 1; }
+ public int inode() { return f.getName().hashCode() & 0xffff; }
+ public int type() { return f.isDirectory() ? S_IFDIR : S_IFREG; }
+ public int nlink() { return 1; }
+ public int mode() {
+ int mode = 0;
+ boolean canread = f.canRead();
+ if(canread && (executable || f.isDirectory())) mode |= 0111;
+ if(canread) mode |= 0444;
+ if(f.canWrite()) mode |= 0222;
+ return mode;
+ }
+ public int size() { return (int) f.length(); }
+ public int mtime() { return (int)(f.lastModified()/1000); }
+ }
+
+ // Exceptions
+ public class ReadFaultException extends FaultException {
+ public ReadFaultException(int addr) { super(addr); }
+ }
+ public class WriteFaultException extends FaultException {
+ public WriteFaultException(int addr) { super(addr); }
+ }
+ public abstract class FaultException extends ExecutionException {
+ public int addr;
+ public FaultException(int addr) { super("fault at: " + toHex(addr)); this.addr = addr; }
+ }
+ public static class ExecutionException extends Exception {
+ private String message = "(null)";
+ private String location = "(unknown)";
+ public ExecutionException() { /* noop */ }
+ public ExecutionException(String s) { if(s != null) message = s; }
+ void setLocation(String s) { location = s == null ? "(unknown)" : s; }
+ public final String getMessage() { return message + " at " + location; }
+ }
+ public static class CallException extends Exception {
+ public CallException(String s) { super(s); }
+ }
+
+ protected static class ErrnoException extends IOException {
+ public int errno;
+ public ErrnoException(int errno) { super("Errno: " + errno); this.errno = errno; }
+ }
+
+ // CPU State
+ protected static class CPUState {
+ public CPUState() { /* noop */ }
+ /* GPRs */
+ public int[] r = new int[32];
+ /* Floating point regs */
+ public int[] f = new int[32];
+ public int hi, lo;
+ public int fcsr;
+ public int pc;
+ }
+
+ // Null pointer check helper function
+ protected final void nullPointerCheck(int addr) throws ExecutionException {
+ if(TOTAL_PAGES==1 ? addr < 65536 : (addr>>>PAGE_SHIFT) < 16)
+ throw new ExecutionException("Attempted to dereference a null pointer " + toHex(addr));
+ }
+
+ // Utility functions
+ private byte[] byteBuf(int size) {
+ if(_byteBuf==null) _byteBuf = new byte[size];
+ else if(_byteBuf.length < size)
+ _byteBuf = new byte[min(max(_byteBuf.length*2,size),MAX_CHUNK)];
+ return _byteBuf;
+ }
+
+ protected static String getSystemProperty(String key) {
+ try {
+ return System.getProperty(key);
+ } catch(SecurityException e) {
+ return null;
+ }
+ }
+
+ /** Decode an packed string.. FEATURE: document this better */
+ protected static final int[] decodeData(String s, int words) {
+ if(s.length() % 8 != 0) throw new IllegalArgumentException("string length must be a multiple of 8");
+ if((s.length() / 8) * 7 < words*4) throw new IllegalArgumentException("string isn't big enough");
+ int[] buf = new int[words];
+ int prev = 0, left=0;
+ for(int i=0,n=0;n<words;i+=8) {
+ long l = 0;
+ for(int j=0;j<8;j++) { l <<= 7; l |= s.charAt(i+j) & 0x7f; }
+ if(left > 0) buf[n++] = prev | (int)(l>>>(56-left));
+ if(n < words) buf[n++] = (int) (l >>> (24-left));
+ left = (left + 8) & 0x1f;
+ prev = (int)(l << left);
+ }
+ return buf;
+ }
+
+ protected static byte[] getBytes(String s) {
+ try {
+ return s.getBytes("ISO-8859-1");
+ } catch(UnsupportedEncodingException e) {
+ return null; // should never happen
+ }
+ }
+
+ protected final static String toHex(int n) { return "0x" + Long.toString(n & 0xffffffffL, 16); }
+ protected final static int min(int a, int b) { return a < b ? a : b; }
+ protected final static int max(int a, int b) { return a > b ? a : b; }
+}
--- /dev/null
+package org.xwt.mips;
+
+import org.xwt.mips.util.*;
+import java.io.*;
+import java.util.*;
+
+public abstract class UnixRuntime extends Runtime {
+ /** The pid of this "process" */
+ private int pid;
+ private int ppid;
+ protected int getPid() { return pid; }
+
+ /** processes filesystem */
+ private FS fs;
+ public FS getFS() { return fs; }
+ public void setFS(FS fs) {
+ if(state >= RUNNING) throw new IllegalStateException("Can't change fs while process is running");
+ this.fs = fs;
+ }
+
+ /** proceses current working directory */
+ private String cwd;
+
+ /* Static stuff */
+ // FEATURE: Most of this is O(n) or worse - fix it
+ private final Object waitNotification = new Object();
+ private final static int MAX_TASKS = 256;
+ private final static UnixRuntime[] tasks = new UnixRuntime[MAX_TASKS];
+ private static int addTask(UnixRuntime rt) {
+ synchronized(tasks) {
+ for(int i=1;i<MAX_TASKS;i++) {
+ if(tasks[i] == null) {
+ tasks[i] = rt;
+ rt.pid = i;
+ return i;
+ }
+ }
+ return -1;
+ }
+ }
+ private static void removeTask(UnixRuntime rt) {
+ synchronized(tasks) {
+ for(int i=1;i<MAX_TASKS;i++)
+ if(tasks[i] == rt) { tasks[i] = null; break; }
+ }
+ }
+
+ public UnixRuntime(int pageSize, int totalPages, boolean allowEmptyPages) {
+ super(pageSize,totalPages,allowEmptyPages);
+
+ HostFS root = new HostFS();
+ fs = new UnixOverlayFS(root);
+
+ String dir = root.hostCWD();
+ try {
+ chdir(dir == null ? "/" : dir);
+ } catch(FileNotFoundException e) {
+ e.printStackTrace();
+ cwd = "/";
+ }
+ }
+
+ // NOTE: getDisplayName() is a Java2 function
+ private static String posixTZ() {
+ StringBuffer sb = new StringBuffer();
+ TimeZone zone = TimeZone.getDefault();
+ int off = zone.getRawOffset() / 1000;
+ sb.append(zone.getDisplayName(false,TimeZone.SHORT));
+ if(off > 0) sb.append("-");
+ else off = -off;
+ sb.append(off/3600); off = off%3600;
+ if(off > 0) sb.append(":").append(off/60); off=off%60;
+ if(off > 0) sb.append(":").append(off);
+ if(zone.useDaylightTime())
+ sb.append(zone.getDisplayName(true,TimeZone.SHORT));
+ return sb.toString();
+ }
+
+ private static boolean envHas(String key,String[] environ) {
+ for(int i=0;i<environ.length;i++)
+ if(environ[i]!=null && environ[i].startsWith(key + "=")) return true;
+ return false;
+ }
+
+ protected String[] createEnv(String[] extra) {
+ String[] defaults = new String[5];
+ int n=0;
+ if(extra == null) extra = new String[0];
+ if(!envHas("USER",extra) && getSystemProperty("user.name") != null)
+ defaults[n++] = "USER=" + getSystemProperty("user.name");
+ if(!envHas("HOME",extra) && getSystemProperty("user.name") != null)
+ defaults[n++] = "HOME=" + getSystemProperty("user.home");
+ if(!envHas("SHELL",extra)) defaults[n++] = "SHELL=/bin/sh";
+ if(!envHas("TERM",extra)) defaults[n++] = "TERM=vt100";
+ if(!envHas("TZ",extra)) defaults[n++] = "TZ=" + posixTZ();
+ String[] env = new String[extra.length+n];
+ for(int i=0;i<n;i++) env[i] = defaults[i];
+ for(int i=0;i<extra.length;i++) env[n++] = extra[i];
+ return env;
+ }
+
+ protected void _start() {
+ if(addTask(this) < 0) throw new Error("Task list full");
+ }
+
+ protected void _exit() {
+ synchronized(tasks) {
+ if(ppid == 0) removeTask(this);
+ for(int i=0;i<MAX_TASKS;i++) {
+ if(tasks[i] != null && tasks[i].ppid == pid) {
+ if(tasks[i].state == DONE) removeTask(tasks[i]);
+ else tasks[i].ppid = 0;
+ }
+ }
+ state = DONE;
+ if(ppid != 0) synchronized(tasks[ppid].waitNotification) { tasks[ppid].waitNotification.notify(); }
+ }
+ }
+
+ protected int syscall(int syscall, int a, int b, int c, int d) {
+ switch(syscall) {
+ case SYS_kill: return sys_kill(a,b);
+ case SYS_fork: return sys_fork();
+ case SYS_pipe: return sys_pipe(a);
+ case SYS_dup2: return sys_dup2(a,b);
+ case SYS_waitpid: return sys_waitpid(a,b,c);
+ case SYS_stat: return sys_stat(a,b);
+ case SYS_mkdir: return sys_mkdir(a,b);
+ case SYS_getcwd: return sys_getcwd(a,b);
+ case SYS_chdir: return sys_chdir(a);
+
+ default: return super.syscall(syscall,a,b,c,d);
+ }
+ }
+
+ protected FD open(String path, int flags, int mode) throws IOException { return fs.open(cleanupPath(path),flags,mode); }
+
+ // FEATURE: Allow simple, broken signal delivery to other processes
+ // (check if a signal was delivered before and after syscalls)
+ // FEATURE: Implement raise() in terms of call("raise",...) - kinda cheap, but it keeps the complexity in newlib
+ /** The kill syscall.
+ SIGSTOP, SIGTSTO, SIGTTIN, and SIGTTOUT pause the process.
+ SIGCONT, SIGCHLD, SIGIO, and SIGWINCH are ignored.
+ Anything else terminates the process. */
+ private int sys_kill(int pid, int signal) {
+ // This will only be called by raise() in newlib to invoke the default handler
+ // We don't have to worry about actually delivering the signal
+ if(pid != pid) return -ESRCH;
+ if(signal < 0 || signal >= 32) return -EINVAL;
+ switch(signal) {
+ case 0: return 0;
+ case 17: // SIGSTOP
+ case 18: // SIGTSTP
+ case 21: // SIGTTIN
+ case 22: // SIGTTOU
+ state = PAUSED;
+ break;
+ case 19: // SIGCONT
+ case 20: // SIGCHLD
+ case 23: // SIGIO
+ case 28: // SIGWINCH
+ break;
+ default: {
+ String msg = "Terminating on signal: " + signal + "\n";
+ exitStatus = 1;
+ state = DONE;
+ if(fds[2]==null) {
+ System.out.print(msg);
+ } else {
+ try {
+ byte[] b = getBytes(msg);
+ fds[2].write(b,0,b.length);
+ }
+ catch(IOException e) { /* ignore */ }
+ }
+ }
+ }
+ return 0;
+ }
+
+ private int sys_waitpid(int pid, int statusAddr, int options) {
+ final int WNOHANG = 1;
+ if((options & ~(WNOHANG)) != 0) return -EINVAL;
+ if(pid !=-1 && (pid <= 0 || pid >= MAX_TASKS)) return -ECHILD;
+ for(;;) {
+ synchronized(tasks) {
+ UnixRuntime task = null;
+ if(pid == -1) {
+ for(int i=0;i<MAX_TASKS;i++) {
+ if(tasks[i] != null && tasks[i].ppid == this.pid && tasks[i].state == DONE) {
+ task = tasks[i];
+ break;
+ }
+ }
+ } else if(tasks[pid] != null && tasks[pid].ppid == this.pid && tasks[pid].state == DONE) {
+ task = tasks[pid];
+ }
+
+ if(task != null) {
+ removeTask(task);
+ try {
+ if(statusAddr!=0) memWrite(statusAddr,task.exitStatus()<<8);
+ } catch(FaultException e) {
+ return -EFAULT;
+ }
+
+ return task.pid;
+ }
+ }
+ if((options&WNOHANG)!=0) return 0;
+ synchronized(waitNotification) {
+ try { waitNotification.wait(); } catch(InterruptedException e) { /* ignore */ }
+ }
+ }
+ }
+
+ // Great ugliness lies within.....
+ private int sys_fork() {
+ CPUState state = getCPUState();
+ int sp = state.r[SP];
+ final UnixRuntime r;
+ try {
+ r = (UnixRuntime) getClass().newInstance();
+ } catch(Exception e) {
+ System.err.println(e);
+ return -ENOMEM;
+ }
+ int child_pid = addTask(r);
+ if(child_pid < 0) return -ENOMEM;
+
+ r.ppid = pid;
+ r.brkAddr = brkAddr;
+ r.fds = new FD[OPEN_MAX];
+ for(int i=0;i<OPEN_MAX;i++) if(fds[i] != null) r.fds[i] = fds[i].dup();
+ r.cwd = cwd;
+ r.fs = fs;
+ for(int i=0;i<TOTAL_PAGES;i++) {
+ if(readPages[i] == null) continue;
+ if(isEmptyPage(writePages[i])) {
+ r.readPages[i] = r.writePages[i] = writePages[i];
+ } else if(writePages[i] != null) {
+ r.readPages[i] = r.writePages[i] = new int[PAGE_WORDS];
+ if(STACK_BOTTOM == 0 || i*PAGE_SIZE < STACK_BOTTOM || i*PAGE_SIZE >= sp-PAGE_SIZE*2)
+ System.arraycopy(writePages[i],0,r.writePages[i],0,PAGE_WORDS);
+ } else {
+ r.readPages[i] = r.readPages[i];
+ }
+ }
+ state.r[V0] = 0;
+ state.pc += 4;
+ r.setCPUState(state);
+ r.state = PAUSED;
+
+ new Thread() {
+ public void run() {
+ try {
+ while(!r.execute());
+ } catch(Exception e) {
+ System.err.println("Forked process threw exception: ");
+ e.printStackTrace();
+ }
+ }
+ }.start();
+
+ return child_pid;
+ }
+
+ private int sys_pipe(int addr) {
+ PipedOutputStream writerStream = new PipedOutputStream();
+ PipedInputStream readerStream;
+ try {
+ readerStream = new PipedInputStream(writerStream);
+ } catch(IOException e) {
+ return -EIO;
+ }
+ FD reader = new InputStreamFD(readerStream);
+ FD writer = new OutputStreamFD(writerStream);
+ int fd1 = addFD(reader);
+ if(fd1 < 0) return -ENFILE;
+ int fd2 = addFD(writer);
+ if(fd2 < 0) { closeFD(fd1); return -ENFILE; }
+ try {
+ memWrite(addr,fd1);
+ memWrite(addr+4,fd2);
+ } catch(FaultException e) {
+ closeFD(fd1);
+ closeFD(fd2);
+ return -EFAULT;
+ }
+ return 0;
+ }
+
+ private int sys_dup2(int oldd, int newd) {
+ if(oldd == newd) return 0;
+ if(oldd < 0 || oldd >= OPEN_MAX) return -EBADFD;
+ if(newd < 0 || newd >= OPEN_MAX) return -EBADFD;
+ if(fds[oldd] == null) return -EBADFD;
+ if(fds[newd] != null) fds[newd].close();
+ fds[newd] = fds[oldd].dup();
+ return 0;
+ }
+
+ private int sys_stat(int cstring, int addr) {
+ try {
+ String path = cleanupPath(cstring(cstring));
+ return stat(fs.stat(path),addr);
+ }
+ catch(ErrnoException e) { return -e.errno; }
+ catch(FileNotFoundException e) {
+ if(e.getMessage() != null && e.getMessage().indexOf("Permission denied") >= 0) return -EACCES;
+ return -ENOENT;
+ }
+ catch(IOException e) { return -EIO; }
+ catch(FaultException e) { return -EFAULT; }
+ }
+
+
+ private int sys_mkdir(int cstring, int mode) {
+ try {
+ fs.mkdir(cleanupPath(cstring(cstring)));
+ return 0;
+ }
+ catch(ErrnoException e) { return -e.errno; }
+ catch(FileNotFoundException e) { return -ENOENT; }
+ catch(IOException e) { return -EIO; }
+ catch(FaultException e) { return -EFAULT; }
+ }
+
+
+ private int sys_getcwd(int addr, int size) {
+ byte[] b = getBytes(cwd);
+ if(size == 0) return -EINVAL;
+ if(size < b.length+1) return -ERANGE;
+ if(!new File(cwd).exists()) return -ENOENT;
+ try {
+ copyout(b,addr,b.length);
+ memset(addr+b.length+1,0,1);
+ return addr;
+ } catch(FaultException e) {
+ return -EFAULT;
+ }
+ }
+
+ private int sys_chdir(int addr) {
+ try {
+ String path = cleanupPath(cstring(addr));
+ System.err.println("Chdir: " + cstring(addr) + " -> " + path + " pwd: " + cwd);
+ if(fs.stat(path).type() != FStat.S_IFDIR) return -ENOTDIR;
+ cwd = path;
+ System.err.println("Now: " + cwd);
+ return 0;
+ }
+ catch(ErrnoException e) { return -e.errno; }
+ catch(FileNotFoundException e) { return -ENOENT; }
+ catch(IOException e) { return -EIO; }
+ catch(FaultException e) { return -EFAULT; }
+ }
+
+ public void chdir(String dir) throws FileNotFoundException {
+ if(state >= RUNNING) throw new IllegalStateException("Can't chdir while process is running");
+ try {
+ dir = cleanupPath(dir);
+ if(fs.stat(dir).type() != FStat.S_IFDIR) throw new FileNotFoundException();
+ } catch(IOException e) {
+ throw new FileNotFoundException();
+ }
+ cwd = dir;
+ }
+
+ public abstract static class FS {
+ public FD open(String path, int flags, int mode) throws IOException { throw new FileNotFoundException(); }
+ public FStat stat(String path) throws IOException { throw new FileNotFoundException(); }
+ public void mkdir(String path) throws IOException { throw new ErrnoException(ENOTDIR); }
+
+ public static FD directoryFD(String[] files, int hashCode) throws IOException {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ DataOutputStream dos = new DataOutputStream(bos);
+ for(int i=0;i<files.length;i++) {
+ byte[] b = getBytes(files[i]);
+ int inode = (files[i].hashCode() ^ hashCode) & 0xfffff;
+ dos.writeInt(inode);
+ dos.writeInt(b.length);
+ dos.write(b,0,b.length);
+ }
+ final byte[] data = bos.toByteArray();
+ return new SeekableFD(new SeekableByteArray(data,false),RD_ONLY) {
+ protected FStat _fstat() { return new FStat() {
+ public int length() { return data.length; }
+ public int type() { return S_IFDIR; }
+ }; }
+ };
+ }
+ }
+
+ private static boolean needsCleanup(String path) {
+ if(path.indexOf("//") != -1) return true;
+ if(path.indexOf('.') != -1) {
+ if(path.length() == 1) return true;
+ if(path.equals("..")) return true;
+ if(path.startsWith("./") || path.indexOf("/./") != -1 || path.endsWith("/.")) return true;
+ if(path.startsWith("../") || path.indexOf("/../") != -1 || path.endsWith("/..")) return true;
+ }
+ return false;
+ }
+
+ // FIXME: This is probably still buggy
+ // FEATURE: Remove some of the "should never happen checks"
+ protected String cleanupPath(String p) throws ErrnoException {
+ if(p.length() == 0) throw new ErrnoException(ENOENT);
+ if(needsCleanup(p)) {
+ char[] in = p.toCharArray();
+ char[] out;
+ int outp ;
+ if(in[0] == '/') {
+ out = new char[in.length];
+ outp = 0;
+ } else {
+ out = new char[cwd.length() + in.length + 1];
+ outp = cwd.length();
+ for(int i=0;i<outp;i++) out[i] = cwd.charAt(i);
+ if(outp == 0 || out[0] != '/') throw new Error("should never happen");
+ }
+ int inLength = in.length;
+ int inp = 0;
+ while(inp<inLength) {
+ if(inp == 0 || in[inp] == '/') {
+ while(inp < inLength && in[inp] == '/') inp++;
+ if(inp == inLength) break;
+ if(in[inp] == '.') {
+ if(inp+1 == inLength) break;
+ if(in[inp+1] == '.' && (inp+2 == inLength || in[inp+2] == '/')) {
+ inp+=2;
+ if(outp == 0) continue;
+ do { outp--; } while(outp > 0 && out[outp] != '/');
+ } else if(in[inp+1] == '/') {
+ inp++;
+ } else {
+ out[outp++] = '/';
+ }
+ } else {
+ out[outp++] = '/';
+ out[outp++] = in[inp++];
+ }
+ } else {
+ out[outp++] = in[inp++];
+ }
+ }
+ if(outp == 0) out[outp++] = '/';
+ return new String(out,0,outp);
+ } else {
+ if(p.startsWith("/")) return p;
+ StringBuffer sb = new StringBuffer(cwd);
+ if(!cwd.equals("/")) sb.append('/');
+ return sb.append(p).toString();
+ }
+ }
+
+ // FEATURE: Probably should make this more general - support mountpoints, etc
+ public class UnixOverlayFS extends FS {
+ private final FS root;
+ private final FS dev = new DevFS();
+ public UnixOverlayFS(FS root) {
+ this.root = root;
+ }
+ private String devPath(String path) {
+ if(path.startsWith("/dev")) {
+ if(path.length() == 4) return "/";
+ if(path.charAt(4) == '/') return path.substring(4);
+ }
+ return null;
+ }
+ public FD open(String path, int flags, int mode) throws IOException{
+ String dp = devPath(path);
+ return dp == null ? root.open(path,flags,mode) : dev.open(dp,flags,mode);
+ }
+ public FStat stat(String path) throws IOException {
+ String dp = devPath(path);
+ return dp == null ? root.stat(path) : dev.stat(dp);
+ }
+ public void mkdir(String path) throws IOException {
+ String dp = devPath(path);
+ if(dp == null) root.mkdir(path);
+ else dev.mkdir(dp);
+ }
+ }
+
+ // FIXME: This is totally broken on non-unix hosts - need to do some kind of cygwin type mapping
+ public static class HostFS extends FS {
+ public static String fixPath(String path) throws FileNotFoundException {
+ return path;
+ }
+
+ public String hostCWD() {
+ return getSystemProperty("user.dir");
+ }
+
+ // FEATURE: This shares a lot with Runtime.open
+ public FD open(String path, int flags, int mode) throws IOException {
+ path = fixPath(path);
+ final File f = new File(path);
+ // NOTE: createNewFile is a Java2 function
+ if((flags & (O_EXCL|O_CREAT)) == (O_EXCL|O_CREAT))
+ if(!f.createNewFile()) throw new ErrnoException(EEXIST);
+ if(!f.exists() && (flags&O_CREAT) == 0) return null;
+ if(f.isDirectory()) {
+ if((flags&3)!=RD_ONLY) throw new ErrnoException(EACCES);
+ return directoryFD(f.list(),path.hashCode());
+ }
+ final SeekableFile sf = new SeekableFile(path,(flags&3)!=RD_ONLY);
+ if((flags&O_TRUNC)!=0) sf.setLength(0);
+ return new SeekableFD(sf,mode) {
+ protected FStat _fstat() { return new HostFStat(f) {
+ public int size() {
+ try { return sf.length(); } catch(IOException e) { return 0; }
+ }
+ };}
+ };
+ }
+
+ public FStat stat(String path) throws FileNotFoundException {
+ File f = new File(fixPath(path));
+ if(!f.exists()) throw new FileNotFoundException();
+ return new HostFStat(f);
+ }
+
+ public void mkdir(String path) throws IOException {
+ File f = new File(fixPath(path));
+ if(f.exists() && f.isDirectory()) throw new ErrnoException(EEXIST);
+ if(f.exists()) throw new ErrnoException(ENOTDIR);
+ File parent = f.getParentFile();
+ if(parent!=null && (!parent.exists() || !parent.isDirectory())) throw new ErrnoException(ENOTDIR);
+ if(!f.mkdir()) throw new ErrnoException(EIO);
+ }
+ }
+
+ private static class DevFStat extends FStat {
+ public int dev() { return 1; }
+ public int mode() { return 0666; }
+ public int type() { return S_IFCHR; }
+ public int nlink() { return 1; }
+ }
+ private static FD devZeroFD = new FD() {
+ public boolean readable() { return true; }
+ public boolean writable() { return true; }
+ public int read(byte[] a, int off, int length) { Arrays.fill(a,off,off+length,(byte)0); return length; }
+ public int write(byte[] a, int off, int length) { return length; }
+ public int seek(int n, int whence) { return 0; }
+ public FStat _fstat() { return new DevFStat(); }
+ };
+ private static FD devNullFD = new FD() {
+ public boolean readable() { return true; }
+ public boolean writable() { return true; }
+ public int read(byte[] a, int off, int length) { return 0; }
+ public int write(byte[] a, int off, int length) { return length; }
+ public int seek(int n, int whence) { return 0; }
+ public FStat _fstat() { return new DevFStat(); }
+ };
+
+ public class DevFS extends FS {
+ public FD open(String path, int mode, int flags) throws IOException {
+ if(path.equals("/null")) return devNullFD;
+ if(path.equals("/zero")) return devZeroFD;
+ if(path.startsWith("/fd/")) {
+ int n;
+ try {
+ n = Integer.parseInt(path.substring(4));
+ } catch(NumberFormatException e) {
+ throw new FileNotFoundException();
+ }
+ if(n < 0 || n >= OPEN_MAX) throw new FileNotFoundException();
+ if(fds[n] == null) throw new FileNotFoundException();
+ return fds[n].dup();
+ }
+ if(path.equals("/fd")) {
+ int count=0;
+ for(int i=0;i<OPEN_MAX;i++) if(fds[i] != null) count++;
+ String[] files = new String[count];
+ count = 0;
+ for(int i=0;i<OPEN_MAX;i++) if(fds[i] != null) files[count++] = Integer.toString(i);
+ return directoryFD(files,hashCode());
+ }
+ if(path.equals("/")) {
+ String[] files = { "null", "zero", "fd" };
+ return directoryFD(files,hashCode());
+ }
+ throw new FileNotFoundException();
+ }
+
+ public FStat stat(String path) throws IOException {
+ if(path.equals("/null")) return devNullFD.fstat();
+ if(path.equals("/zero")) return devZeroFD.fstat();
+ if(path.startsWith("/fd/")) {
+ int n;
+ try {
+ n = Integer.parseInt(path.substring(4));
+ } catch(NumberFormatException e) {
+ throw new FileNotFoundException();
+ }
+ if(n < 0 || n >= OPEN_MAX) throw new FileNotFoundException();
+ if(fds[n] == null) throw new FileNotFoundException();
+ return fds[n].fstat();
+ }
+ if(path.equals("/fd")) return new FStat() { public int type() { return S_IFDIR; } public int mode() { return 0444; }};
+ if(path.equals("/")) return new FStat() { public int type() { return S_IFDIR; } public int mode() { return 0444; }};
+ throw new FileNotFoundException();
+ }
+
+ public void mkdir(String path) throws IOException { throw new ErrnoException(EACCES); }
+ }
+}
--- /dev/null
+// THIS FILE IS AUTOGENERATED! DO NOT EDIT!
+// run "make rebuild-constants" if it needs to be updated
+
+package org.xwt.mips;
+public interface UsermodeConstants {
+ public static final int SYS_null = 0;
+ public static final int SYS_exit = 1;
+ public static final int SYS_pause = 2;
+ public static final int SYS_open = 3;
+ public static final int SYS_close = 4;
+ public static final int SYS_read = 5;
+ public static final int SYS_write = 6;
+ public static final int SYS_sbrk = 7;
+ public static final int SYS_fstat = 8;
+ public static final int SYS_isatty = 9;
+ public static final int SYS_lseek = 10;
+ public static final int SYS_kill = 11;
+ public static final int SYS_getpid = 12;
+ public static final int SYS_calljava = 13;
+ public static final int SYS_stat = 14;
+ public static final int SYS_gettimeofday = 15;
+ public static final int SYS_sleep = 16;
+ public static final int SYS_times = 17;
+ public static final int SYS_mkdir = 18;
+ public static final int SYS_getpagesize = 19;
+ public static final int SYS_unlink = 20;
+ public static final int SYS_utime = 21;
+ public static final int SYS_chdir = 22;
+ public static final int SYS_pipe = 23;
+ public static final int SYS_dup2 = 24;
+ public static final int SYS_fork = 25;
+ public static final int SYS_waitpid = 26;
+ public static final int SYS_getcwd = 27;
+ public static final int SYS_execve = 28;
+ public static final int SYS_fcntl = 29;
+ public static final int SYS_rmdir = 30;
+ public static final int SYS_sysconf = 31;
+ public static final int EPERM = 1; /* Not super-user */
+ public static final int ENOENT = 2; /* No such file or directory */
+ public static final int ESRCH = 3; /* No such process */
+ public static final int EINTR = 4; /* Interrupted system call */
+ public static final int EIO = 5; /* I/O error */
+ public static final int ENXIO = 6; /* No such device or address */
+ public static final int E2BIG = 7; /* Arg list too long */
+ public static final int ENOEXEC = 8; /* Exec format error */
+ public static final int EBADF = 9; /* Bad file number */
+ public static final int ECHILD = 10; /* No children */
+ public static final int EAGAIN = 11; /* No more processes */
+ public static final int ENOMEM = 12; /* Not enough core */
+ public static final int EACCES = 13; /* Permission denied */
+ public static final int EFAULT = 14; /* Bad address */
+ public static final int ENOTBLK = 15; /* Block device required */
+ public static final int EBUSY = 16; /* Mount device busy */
+ public static final int EEXIST = 17; /* File exists */
+ public static final int EXDEV = 18; /* Cross-device link */
+ public static final int ENODEV = 19; /* No such device */
+ public static final int ENOTDIR = 20; /* Not a directory */
+ public static final int EISDIR = 21; /* Is a directory */
+ public static final int EINVAL = 22; /* Invalid argument */
+ public static final int ENFILE = 23; /* Too many open files in system */
+ public static final int EMFILE = 24; /* Too many open files */
+ public static final int ENOTTY = 25; /* Not a typewriter */
+ public static final int ETXTBSY = 26; /* Text file busy */
+ public static final int EFBIG = 27; /* File too large */
+ public static final int ENOSPC = 28; /* No space left on device */
+ public static final int ESPIPE = 29; /* Illegal seek */
+ public static final int EROFS = 30; /* Read only file system */
+ public static final int EMLINK = 31; /* Too many links */
+ public static final int EPIPE = 32; /* Broken pipe */
+ public static final int EDOM = 33; /* Math arg out of domain of func */
+ public static final int ERANGE = 34; /* Math result not representable */
+ public static final int ENOMSG = 35; /* No message of desired type */
+ public static final int EIDRM = 36; /* Identifier removed */
+ public static final int ECHRNG = 37; /* Channel number out of range */
+ public static final int EL2NSYNC = 38; /* Level 2 not synchronized */
+ public static final int EL3HLT = 39; /* Level 3 halted */
+ public static final int EL3RST = 40; /* Level 3 reset */
+ public static final int ELNRNG = 41; /* Link number out of range */
+ public static final int EUNATCH = 42; /* Protocol driver not attached */
+ public static final int ENOCSI = 43; /* No CSI structure available */
+ public static final int EL2HLT = 44; /* Level 2 halted */
+ public static final int EDEADLK = 45; /* Deadlock condition */
+ public static final int ENOLCK = 46; /* No record locks available */
+ public static final int EBADE = 50; /* Invalid exchange */
+ public static final int EBADR = 51; /* Invalid request descriptor */
+ public static final int EXFULL = 52; /* Exchange full */
+ public static final int ENOANO = 53; /* No anode */
+ public static final int EBADRQC = 54; /* Invalid request code */
+ public static final int EBADSLT = 55; /* Invalid slot */
+ public static final int EDEADLOCK = 56; /* File locking deadlock error */
+ public static final int EBFONT = 57; /* Bad font file fmt */
+ public static final int ENOSTR = 60; /* Device not a stream */
+ public static final int ENODATA = 61; /* No data (for no delay io) */
+ public static final int ETIME = 62; /* Timer expired */
+ public static final int ENOSR = 63; /* Out of streams resources */
+ public static final int ENONET = 64; /* Machine is not on the network */
+ public static final int ENOPKG = 65; /* Package not installed */
+ public static final int EREMOTE = 66; /* The object is remote */
+ public static final int ENOLINK = 67; /* The link has been severed */
+ public static final int EADV = 68; /* Advertise error */
+ public static final int ESRMNT = 69; /* Srmount error */
+ public static final int ECOMM = 70; /* Communication error on send */
+ public static final int EPROTO = 71; /* Protocol error */
+ public static final int EMULTIHOP = 74; /* Multihop attempted */
+ public static final int ELBIN = 75; /* Inode is remote (not really error) */
+ public static final int EDOTDOT = 76; /* Cross mount point (not really error) */
+ public static final int EBADMSG = 77; /* Trying to read unreadable message */
+ public static final int EFTYPE = 79; /* Inappropriate file type or format */
+ public static final int ENOTUNIQ = 80; /* Given log. name not unique */
+ public static final int EBADFD = 81; /* f.d. invalid for this operation */
+ public static final int EREMCHG = 82; /* Remote address changed */
+ public static final int ELIBACC = 83; /* Can't access a needed shared lib */
+ public static final int ELIBBAD = 84; /* Accessing a corrupted shared lib */
+ public static final int ELIBSCN = 85; /* .lib section in a.out corrupted */
+ public static final int ELIBMAX = 86; /* Attempting to link in too many libs */
+ public static final int ELIBEXEC = 87; /* Attempting to exec a shared library */
+ public static final int ENOSYS = 88; /* Function not implemented */
+ public static final int ENMFILE = 89; /* No more files */
+ public static final int ENOTEMPTY = 90; /* Directory not empty */
+ public static final int ENAMETOOLONG = 91; /* File or path name too long */
+ public static final int ELOOP = 92; /* Too many symbolic links */
+ public static final int EOPNOTSUPP = 95; /* Operation not supported on transport endpoint */
+ public static final int EPFNOSUPPORT = 96; /* Protocol family not supported */
+ public static final int ECONNRESET = 104; /* Connection reset by peer */
+ public static final int ENOBUFS = 105; /* No buffer space available */
+ public static final int EAFNOSUPPORT = 106; /* Address family not supported by protocol family */
+ public static final int EPROTOTYPE = 107; /* Protocol wrong type for socket */
+ public static final int ENOTSOCK = 108; /* Socket operation on non-socket */
+ public static final int ENOPROTOOPT = 109; /* Protocol not available */
+ public static final int ESHUTDOWN = 110; /* Can't send after socket shutdown */
+ public static final int ECONNREFUSED = 111; /* Connection refused */
+ public static final int EADDRINUSE = 112; /* Address already in use */
+ public static final int ECONNABORTED = 113; /* Connection aborted */
+ public static final int ENETUNREACH = 114; /* Network is unreachable */
+ public static final int ENETDOWN = 115; /* Network interface is not configured */
+ public static final int ETIMEDOUT = 116; /* Connection timed out */
+ public static final int EHOSTDOWN = 117; /* Host is down */
+ public static final int EHOSTUNREACH = 118; /* Host is unreachable */
+ public static final int EINPROGRESS = 119; /* Connection already in progress */
+ public static final int EALREADY = 120; /* Socket already connected */
+ public static final int EDESTADDRREQ = 121; /* Destination address required */
+ public static final int EMSGSIZE = 122; /* Message too long */
+ public static final int EPROTONOSUPPORT = 123; /* Unknown protocol */
+ public static final int ESOCKTNOSUPPORT = 124; /* Socket type not supported */
+ public static final int EADDRNOTAVAIL = 125; /* Address not available */
+ public static final int ENETRESET = 126;
+ public static final int EISCONN = 127; /* Socket is already connected */
+ public static final int ENOTCONN = 128; /* Socket is not connected */
+ public static final int ETOOMANYREFS = 129;
+ public static final int EPROCLIM = 130;
+ public static final int EUSERS = 131;
+ public static final int EDQUOT = 132;
+ public static final int ESTALE = 133;
+ public static final int ENOTSUP = 134; /* Not supported */
+ public static final int ENOMEDIUM = 135; /* No medium (in tape drive) */
+ public static final int ENOSHARE = 136; /* No such host or network path */
+ public static final int ECASECLASH = 137; /* Filename exists with different case */
+ public static final int EILSEQ = 138;
+ public static final int EOVERFLOW = 139; /* Value too large for defined data type */
+ public static final int __ELASTERROR = 2000; /* Users can add values starting here */
+ public static final int F_OK = 0;
+ public static final int R_OK = 4;
+ public static final int W_OK = 2;
+ public static final int X_OK = 1;
+ public static final int SEEK_SET = 0;
+ public static final int SEEK_CUR = 1;
+ public static final int SEEK_END = 2;
+ public static final int STDIN_FILENO = 0; /* standard input file descriptor */
+ public static final int STDOUT_FILENO = 1; /* standard output file descriptor */
+ public static final int STDERR_FILENO = 2; /* standard error file descriptor */
+ public static final int _SC_ARG_MAX = 0;
+ public static final int _SC_CHILD_MAX = 1;
+ public static final int _SC_CLK_TCK = 2;
+ public static final int _SC_NGROUPS_MAX = 3;
+ public static final int _SC_OPEN_MAX = 4;
+ public static final int _SC_JOB_CONTROL = 5;
+ public static final int _SC_SAVED_IDS = 6;
+ public static final int _SC_VERSION = 7;
+ public static final int _SC_PAGESIZE = 8;
+ public static final int _SC_NPROCESSORS_CONF = 9;
+ public static final int _SC_NPROCESSORS_ONLN = 10;
+ public static final int _SC_PHYS_PAGES = 11;
+ public static final int _SC_AVPHYS_PAGES = 12;
+ public static final int _SC_MQ_OPEN_MAX = 13;
+ public static final int _SC_MQ_PRIO_MAX = 14;
+ public static final int _SC_RTSIG_MAX = 15;
+ public static final int _SC_SEM_NSEMS_MAX = 16;
+ public static final int _SC_SEM_VALUE_MAX = 17;
+ public static final int _SC_SIGQUEUE_MAX = 18;
+ public static final int _SC_TIMER_MAX = 19;
+ public static final int _SC_TZNAME_MAX = 20;
+ public static final int _SC_ASYNCHRONOUS_IO = 21;
+ public static final int _SC_FSYNC = 22;
+ public static final int _SC_MAPPED_FILES = 23;
+ public static final int _SC_MEMLOCK = 24;
+ public static final int _SC_MEMLOCK_RANGE = 25;
+ public static final int _SC_MEMORY_PROTECTION = 26;
+ public static final int _SC_MESSAGE_PASSING = 27;
+ public static final int _SC_PRIORITIZED_IO = 28;
+ public static final int _SC_REALTIME_SIGNALS = 29;
+ public static final int _SC_SEMAPHORES = 30;
+ public static final int _SC_SHARED_MEMORY_OBJECTS = 31;
+ public static final int _SC_SYNCHRONIZED_IO = 32;
+ public static final int _SC_TIMERS = 33;
+ public static final int _SC_AIO_LISTIO_MAX = 34;
+ public static final int _SC_AIO_MAX = 35;
+ public static final int _SC_AIO_PRIO_DELTA_MAX = 36;
+ public static final int _SC_DELAYTIMER_MAX = 37;
+ public static final int _SC_THREAD_KEYS_MAX = 38;
+ public static final int _SC_THREAD_STACK_MIN = 39;
+ public static final int _SC_THREAD_THREADS_MAX = 40;
+ public static final int _SC_TTY_NAME_MAX = 41;
+ public static final int _SC_THREADS = 42;
+ public static final int _SC_THREAD_ATTR_STACKADDR = 43;
+ public static final int _SC_THREAD_ATTR_STACKSIZE = 44;
+ public static final int _SC_THREAD_PRIORITY_SCHEDULING = 45;
+ public static final int _SC_THREAD_PRIO_INHERIT = 46;
+ public static final int _SC_THREAD_PRIO_PROTECT = 47;
+ public static final int _SC_THREAD_PROCESS_SHARED = 48;
+ public static final int _SC_THREAD_SAFE_FUNCTIONS = 49;
+ public static final int _SC_GETGR_R_SIZE_MAX = 50;
+ public static final int _SC_GETPW_R_SIZE_MAX = 51;
+ public static final int _SC_LOGIN_NAME_MAX = 52;
+ public static final int _SC_THREAD_DESTRUCTOR_ITERATIONS = 53;
+ public static final int _SC_STREAM_MAX = 100;
+ public static final int _SC_PRIORITY_SCHEDULING = 101;
+ public static final int _PC_LINK_MAX = 0;
+ public static final int _PC_MAX_CANON = 1;
+ public static final int _PC_MAX_INPUT = 2;
+ public static final int _PC_NAME_MAX = 3;
+ public static final int _PC_PATH_MAX = 4;
+ public static final int _PC_PIPE_BUF = 5;
+ public static final int _PC_CHOWN_RESTRICTED = 6;
+ public static final int _PC_NO_TRUNC = 7;
+ public static final int _PC_VDISABLE = 8;
+ public static final int _PC_ASYNC_IO = 9;
+ public static final int _PC_PRIO_IO = 10;
+ public static final int _PC_SYNC_IO = 11;
+ public static final int _PC_POSIX_PERMISSIONS = 90;
+ public static final int _PC_POSIX_SECURITY = 91;
+ public static final int MAXPATHLEN = 1024;
+}
--- /dev/null
+#include <stddef.h>
+
+extern int _gp[];
+
+extern int main(int argc, char **argv, char **envp);
+extern void exit(int status);
+extern int atexit(void (*f)());
+
+/* For constuctors/destructors */
+extern void _init();
+extern void _fini();
+
+char **environ;
+
+void _start(char **argv, char **environ_) {
+ int argc;
+
+ environ = environ_;
+
+ /* Call global constructors */
+ _init();
+
+ /* Register _fini() to be called on exit */
+ atexit(_fini);
+
+ /* Count the arguments */
+ for(argc=0;argv[argc];argc++);
+
+ /* Call main and exit */
+ exit(main(argc,argv,environ));
+}
--- /dev/null
+ENTRY(_start)
+INPUT(support.o support_aux.o)
+GROUP(-lc -lgcc)
+/*GROUP(-lgcc)*/
+__DYNAMIC = 0;
+
+SECTIONS {
+ . = 0x10000;
+ .text : {
+ KEEP(*(.init))
+ KEEP(*(.fini))
+ KEEP(*(.text))
+ *(.text.*)
+ *(.gnu.linkonce.t*)
+ }
+
+ _etext = .;
+
+ .ctors :
+ {
+ KEEP (*crtbegin.o(.ctors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*(.ctors))
+ }
+
+ .dtors :
+ {
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*(.dtors))
+ }
+
+ . = ALIGN(4k);
+
+ .rodata : {
+ *(.rodata*) *(.gnu.linkonce.r*)
+ *(.gcc_except_table)
+ KEEP(*(.eh_frame)) KEEP(*(.jcr))
+ }
+
+ .data : {
+ *(.data*) *(.gnu.linkonce.d*)
+ }
+
+ . = ALIGN(16);
+ _gp = . + 0x8000;
+ .sdata : {
+ *(.rosdata*) *(.sdata*) *(.gnu.linkonce.s*)
+ }
+ .sbss : {
+ *(.sbss*) *(.scommon*)
+ }
+ .bss : {
+ *(.bss*) *(.gnu.linkonce.b*) *(COMMON)
+ }
+
+ _end = .;
+}
--- /dev/null
+#include "syscalls.h"
+
+#define zero $0
+#define v0 $2
+#define v1 $3
+#define a0 $4
+#define a1 $5
+#define a2 $6
+#define a3 $7
+#define t0 $8
+#define t1 $9
+#define ra $31
+
+/* We intentionally don't take advantage of delay slots because
+ the compiler removes them anyway */
+
+.set noreorder;
+
+#define SYSCALL(name) SYSCALL2(name,SYS_##name)
+#define SYSCALL2(name,number) \
+ .section .text.name,"ax",@progbits; \
+ .align 2; \
+ .globl name; \
+ .ent name; \
+name: \
+ li v0, number; \
+ syscall; \
+ j ra; \
+ nop; \
+ .end name;
+
+#define SYSCALL_R(name) \
+ .section .text._##name##_r,"ax",@progbits; \
+ .align 2; \
+ .globl _##name##_r; \
+ .ent _##name##_r; \
+_##name##_r: \
+ li v0, SYS_##name; \
+ move t0, a0; \
+ move a0, a1; \
+ move a1, a2; \
+ move a2, a3; \
+ syscall; \
+ addu t1,v0,255; \
+ sltu t1,t1,255; \
+ bne t1,zero,$L##name##_errno;\
+ nop; \
+ j ra; \
+ nop; \
+$L##name##_errno: \
+ move a0, t0; \
+ move a1, v0; \
+ j _syscall_set_errno; \
+ nop; \
+ .end _##name##_r;
+
+
+ .align 2
+ .globl _call_helper
+ .ent _call_helper
+_call_helper:
+ subu $sp,$sp,32
+
+ /* addr */
+ move $2,$4
+
+ /* args 1-4 */
+ move $4,$5
+ move $5,$6
+ move $6,$7
+ move $7,$16
+
+ /* args 5 and 6 */
+ sw $17,16($sp)
+ sw $18,20($sp)
+
+ /* call the func */
+ jal $31,$2
+ nop
+
+ move $3,$2
+ li $2,SYS_pause
+ syscall
+
+ /* shouldn't get here */
+ li $2,SYS_exit
+ li $3,1
+ syscall
+
+ .end _call_helper
+
+SYSCALL2(_exit,SYS_exit)
+SYSCALL2(_pause,SYS_pause)
+SYSCALL_R(open)
+SYSCALL_R(close)
+SYSCALL_R(read)
+SYSCALL_R(write)
+SYSCALL_R(sbrk)
+SYSCALL_R(fstat)
+SYSCALL(isatty)
+SYSCALL_R(lseek)
+SYSCALL_R(kill)
+SYSCALL_R(getpid)
+SYSCALL2(_call_java,SYS_calljava)
+SYSCALL_R(stat)
+SYSCALL_R(gettimeofday)
+SYSCALL(sleep)
+SYSCALL_R(times)
+SYSCALL_R(mkdir)
+SYSCALL(getpagesize)
+SYSCALL_R(unlink)
+SYSCALL_R(utime)
+SYSCALL_R(chdir)
+SYSCALL_R(pipe)
+SYSCALL_R(dup2)
+SYSCALL_R(fork)
+SYSCALL_R(waitpid)
+SYSCALL_R(getcwd)
+SYSCALL_R(execve)
+SYSCALL_R(fcntl)
+SYSCALL_R(rmdir)
+SYSCALL_R(sysconf)
--- /dev/null
+#include <sys/stat.h>
+#include <sys/dirent.h>
+#include <sys/types.h>
+#include <utime.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+int _syscall_set_errno(struct _reent *ptr, int err) {
+ ptr->_errno = -err;
+ return -1;
+}
+
+extern int _stat_r(struct _reent *ptr, const char *path, struct stat *sb);
+int _lstat_r(struct _reent *ptr, const char *path, struct stat *sb) {
+ return _stat_r(ptr,path,sb);
+}
+
+uid_t getuid() { return 0; }
+gid_t getgid() { return 0; }
+uid_t geteuid() { return 0; }
+gid_t getegid() { return 0; }
+int getgroups(int gidsetlen, gid_t *gidset) {
+ if(gidsetlen) *gidset = 0;
+ return 1;
+}
+mode_t umask(mode_t new) { return 0022; }
+
+static int syscall_nosys(struct _reent *ptr) {
+ ptr->_errno = ENOSYS;
+ return -1;
+}
+
+int _access_r(struct _reent *ptr, const char *pathname, int mode) {
+ struct stat statbuf;
+ if(_stat_r(ptr,pathname,&statbuf) < 0) return -1;
+ return 0;
+}
+
+/* FIXME: These should be in newlib */
+int access(const char *pathname, int mode) { return _access_r(_REENT,pathname,mode); }
+extern int _rmdir_r(struct _reent *ptr, const char *pathname);
+int rmdir(const char *pathname) { return _rmdir_r(_REENT,pathname); }
+extern long _sysconf_r(struct _reent *ptr, int n);
+long sysconf(int n) { return _sysconf_r(_REENT,n); }
+
+#define SYSCALL_NOSYS_R(name) int _##name##_r(struct _reent *ptr) { return syscall_nosys(ptr); }
+
+SYSCALL_NOSYS_R(link)
+SYSCALL_NOSYS_R(symlink)
+SYSCALL_NOSYS_R(readlink)
+SYSCALL_NOSYS_R(chown)
+SYSCALL_NOSYS_R(fchown)
+SYSCALL_NOSYS_R(chmod)
+SYSCALL_NOSYS_R(fchmod)
+
+static int read_fully(int fd, void *buf, size_t size) {
+ int n;
+ while(size) {
+ n = read(fd,buf,size);
+ if(n <= 0) return -1;
+ size -= n;
+ buf += n;
+ }
+ return 0;
+}
+
+DIR *opendir(const char *path) {
+ struct stat sb;
+ int fd;
+ DIR *dir;
+
+ fd = open(path,O_RDONLY);
+ if(fd < 0) return NULL;
+
+ if(fstat(fd,&sb) < 0 || !S_ISDIR(sb.st_mode)) {
+ close(fd);
+ errno = ENOTDIR;
+ return NULL;
+ }
+
+ dir = malloc(sizeof(*dir));
+ if(dir == NULL) {
+ close(fd);
+ errno = ENOMEM;
+ return NULL;
+ }
+ dir->dd_fd = fd;
+ dir->dd_pos = 0;
+ return dir;
+}
+
+static int readdir_r(DIR *dir,struct dirent *entry, struct dirent **result) {
+ struct {
+ int inode;
+ int name_len;
+ } h;
+ if(dir->dd_fd < 0) return -1;
+again:
+ if(read_fully(dir->dd_fd,&h,sizeof(h)) < 0) goto fail;
+ if(h.name_len < 0 || h.name_len >= sizeof(entry->d_name)-1) goto fail;
+
+ entry->d_ino = h.inode;
+ if(read_fully(dir->dd_fd,entry->d_name,h.name_len) < 0) goto fail;
+
+ entry->d_name[h.name_len] = '\0';
+ dir->dd_pos += h.name_len + 8;
+
+ if(result) *result = entry;
+ return 0;
+fail:
+ if(result) *result = NULL;
+ return -1;
+}
+
+struct dirent *readdir(DIR *dir) { return readdir_r(dir,&dir->ent,NULL) == 0 ? &dir->ent : NULL; }
+
+int closedir(DIR *dir) {
+ close(dir->dd_fd);
+ free(dir);
+ return 0;
+}
--- /dev/null
+#define SYS_null 0
+#define SYS_exit 1
+#define SYS_pause 2
+#define SYS_open 3
+#define SYS_close 4
+#define SYS_read 5
+#define SYS_write 6
+#define SYS_sbrk 7
+#define SYS_fstat 8
+#define SYS_isatty 9
+#define SYS_lseek 10
+#define SYS_kill 11
+#define SYS_getpid 12
+#define SYS_calljava 13
+#define SYS_stat 14
+#define SYS_gettimeofday 15
+#define SYS_sleep 16
+#define SYS_times 17
+#define SYS_mkdir 18
+#define SYS_getpagesize 19
+#define SYS_unlink 20
+#define SYS_utime 21
+#define SYS_chdir 22
+#define SYS_pipe 23
+#define SYS_dup2 24
+#define SYS_fork 25
+#define SYS_waitpid 26
+#define SYS_getcwd 27
+#define SYS_execve 28
+#define SYS_fcntl 29
+#define SYS_rmdir 30
+#define SYS_sysconf 31
--- /dev/null
+package org.xwt.mips.util;
+
+import java.io.IOException;
+
+public class SeekableByteArray implements SeekableData {
+ protected byte[] data;
+ protected int pos;
+ private final boolean writable;
+
+ public SeekableByteArray(byte[] data, boolean writable) {
+ this.data = data;
+ this.pos = 0;
+ this.writable = writable;
+ }
+
+ public int read(byte[] buf, int off, int len) {
+ len = Math.min(len,data.length-pos);
+ if(len <= 0) return -1;
+ System.arraycopy(data,pos,buf,off,len);
+ pos += len;
+ return len;
+ }
+
+ public int write(byte[] buf, int off, int len) throws IOException {
+ if(!writable) throw new IOException("read-only data");
+ len = Math.min(len,data.length-pos);
+ if(len <= 0) throw new IOException("no space");
+ System.arraycopy(buf,off,data,pos,len);
+ pos += len;
+ return len;
+ }
+
+ public int length() { return data.length; }
+ public int pos() { return pos; }
+ public void seek(int pos) { this.pos = pos; }
+ public void close() { /*noop*/ }
+}
--- /dev/null
+package org.xwt.mips.util;
+
+import java.io.IOException;
+
+public interface SeekableData {
+ public int read(byte[] buf, int offset, int length) throws IOException;
+ public int write(byte[] buf, int offset, int length) throws IOException;
+ public int length() throws IOException;
+ public void seek(int pos) throws IOException;
+ public void close() throws IOException;
+ public int pos() throws IOException;
+}
--- /dev/null
+package org.xwt.mips.util;
+
+import java.io.*;
+
+public class SeekableFile implements SeekableData {
+ private final RandomAccessFile raf;
+
+ public SeekableFile(String fileName) throws IOException { this(fileName,false); }
+ public SeekableFile(String fileName, boolean writable) throws IOException { this(new File(fileName),writable); }
+
+ public SeekableFile(File file, boolean writable) throws IOException {
+ raf = new RandomAccessFile(file,writable ? "rw" : "r");
+ }
+
+ // NOTE: RandomAccessFile.setLength() is a Java2 function
+ public void setLength(int n) throws IOException { raf.setLength(n); }
+
+ public int read(byte[] buf, int offset, int length) throws IOException { return raf.read(buf,offset,length); }
+ public int write(byte[] buf, int offset, int length) throws IOException { raf.write(buf,offset,length); return length; }
+ public void seek(int pos) throws IOException{ raf.seek(pos); }
+ public int pos() throws IOException { return (int) raf.getFilePointer(); }
+ public int length() throws IOException { return (int)raf.length(); }
+ public void close() throws IOException { raf.close(); }
+}
--- /dev/null
+package org.xwt.mips.util;
+
+import java.io.*;
+
+public class SeekableInputStream implements SeekableData {
+ private byte[] buffer = new byte[4096];
+ private int bytesRead = 0;
+ private boolean eof = false;
+ private int pos;
+ private InputStream is;
+
+ public SeekableInputStream(InputStream is) { this.is = is; }
+
+ public int read(byte[] outbuf, int off, int len) throws IOException {
+ if(pos >= bytesRead && !eof) readTo(pos + 1);
+ len = Math.min(len,bytesRead-pos);
+ if(len <= 0) return -1;
+ System.arraycopy(buffer,pos,outbuf,off,len);
+ pos += len;
+ return len;
+ }
+
+ private void readTo(int target) throws IOException {
+ if(target >= buffer.length) {
+ byte[] buf2 = new byte[Math.max(buffer.length+Math.min(buffer.length,65536),target)];
+ System.arraycopy(buffer,0,buf2,0,bytesRead);
+ buffer = buf2;
+ }
+ while(bytesRead < target) {
+ int n = is.read(buffer,bytesRead,buffer.length-bytesRead);
+ if(n == -1) {
+ eof = true;
+ break;
+ }
+ bytesRead += n;
+ }
+ }
+
+ public int length() throws IOException {
+ while(!eof) readTo(bytesRead+4096);
+ return bytesRead;
+ }
+
+ public int write(byte[] buf, int off, int len) throws IOException { throw new IOException("read-only"); }
+ public void seek(int pos) { this.pos = pos; }
+ public int pos() { return pos; }
+ public void close() throws IOException { is.close(); }
+}
--- /dev/null
+#include <iostream>
+
+using namespace std;
+
+class Test {
+public:
+ Test();
+ ~Test();
+ void sayhi();
+};
+
+class Exn {
+public:
+ Exn() { }
+};
+
+
+Test test;
+
+int main(int argc,char *argv[]) {
+ printf("Name: %p\n",typeid(const char*).name());
+ printf("Name: %s\n",typeid(const char*).name());
+ printf("Is pointer: %d\n",typeid(const char*).__is_pointer_p ());
+ printf("Name: %p\n",typeid(int).name());
+ printf("Name: %s\n",typeid(int).name());
+ printf("Is pointer: %d\n",typeid(int).__is_pointer_p ());
+
+ try {
+ test.sayhi();
+ } catch(char *e) {
+ printf("sayhi threw: %s\n",e);
+ } catch(const char *e) {
+ printf("sayhi threw: const char *:%s\n",e);
+ } catch(int n) {
+ printf("sayhi threw: %d\n",n);
+ }
+ return 0;
+}
+
+Test::Test() {
+ cout << "Test's constructor" << endl;
+}
+
+Test::~Test() {
+ cout << "Test's destructor" << endl;
+}
+
+void Test::sayhi() {
+ static char exn[] = "Non-const!";
+ cout << "Hello, World from Test" << endl;
+ cout << "Now throwing an exception" << endl;
+ throw "Hello, Exception Handling!";
+ //throw exn;
+}
--- /dev/null
+package tests;
+
+import org.xwt.mips.Runtime;
+import org.xwt.mips.Interpreter;
+import java.io.*;
+import java.util.*;
+
+public class CallTest {
+ public static void main(String[] args) throws Exception {
+ int a1 = args.length > 0 ? Integer.parseInt(args[0]) : 0;
+ int a2 = args.length > 1 ? Integer.parseInt(args[1]) : 0;
+ int a3 = args.length > 2 ? Integer.parseInt(args[2]) : 0;
+ int a4 = args.length > 3 ? Integer.parseInt(args[3]) : 0;
+ int a5 = args.length > 4 ? Integer.parseInt(args[4]) : 0;
+ int a6 = args.length > 5 ? Integer.parseInt(args[5]) : 0;
+
+ System.out.println("Version is: " + System.getProperty("os.version"));
+ Runtime rt;
+ if(a1 == 99) // yeah.. this is ugly
+ rt = new Interpreter("build/tests/Test.mips");
+ else
+ rt = new Test() {
+ protected int callJava(int a, int b, int c, int d) {
+ switch(a) {
+ case 1: return strdup("OS: " + System.getProperty("os.name"));
+ case 2: return strdup(System.getProperty("os.version"));
+ case 3: return strdup(new Date().toString());
+ case 4: return allocFDEnt(new OutputStreamFD(new CustomOS()));
+ case 5:
+ System.out.println("In callJava() in Java");
+ try { call("backinmips"); } catch(CallException e) { }
+ System.out.println("Back in callJava() in Java");
+ return 0;
+ default: return super.callJava(a,b,c,d);
+ }
+ }
+ };
+ System.out.println("Runtime: " + rt);
+
+ rt.start(new String[]{"Test","calltest"});
+ rt.execute();
+
+ System.out.println("== Start of CallTest ==");
+ System.out.println("Back in java... calling callme()");
+ int ret = rt.call("callme",a1,a2,a3,a4,a5,a6);
+ System.out.println("callme returned: " + ret);
+
+ int addr = rt.strdup("Hello, World from java");
+ rt.call("echo",addr,4);
+ rt.free(addr);
+ System.out.println("== End of CallTest ==");
+
+ rt.execute();
+ System.exit(rt.exitStatus());
+ }
+
+ private static class CustomOS extends OutputStream {
+ public CustomOS() { }
+ public void write(int b) { byte[] a = new byte[1]; a[0] = (byte)(b&0xff); write(a,0,1); }
+ public void write(byte[] b, int off, int len) {
+ int len2 = len;
+ while(b[len2-1]=='\n') len2--;
+ System.out.println("This just in from MIPS: " + new String(b,off,len2));
+ }
+ }
+}
--- /dev/null
+package tests;
+
+import java.net.*;
+
+import org.xwt.mips.Runtime;
+
+public class Echo {
+ private static final int PORT = 2000;
+ public static void main(String[] args) throws Exception {
+ ServerSocket sock = new ServerSocket(PORT);
+ System.err.println("Listening on " + PORT);
+ for(;;) new Client(sock.accept()).go();
+ }
+
+ private static class Client implements Runnable {
+ private Socket sock;
+ public Client(Socket sock) { this.sock = sock; }
+ public void go() { new Thread(this).start(); }
+ public void run() {
+ try {
+ Runtime task = new EchoHelper();
+ int status = task.run(
+ new String[]{"EchoHelper"},
+ null,
+ new Runtime.InputStreamFD(sock.getInputStream()),
+ new Runtime.OutputStreamFD(sock.getOutputStream()),
+ null
+ );
+ System.err.println("Exit status: " + status);
+ } catch(Exception e) {
+ System.err.println(e);
+ }
+ }
+ }
+}
--- /dev/null
+#include <stdio.h>
+#include <string.h>
+
+int main() {
+ char buf[1024];
+ char *p;
+ printf("Hello! Welcome to EchoHelper.c\n");
+ while(fgets(buf,sizeof(buf),stdin) != NULL) {
+ for(p=buf;*p && *p!='\n' && *p!='\r';p++);
+ *p = '\0';
+ fprintf(stdout,"You said: %s\n",buf);
+ fprintf(stderr,"They said: %s\n",buf);
+ if(strcmp(buf,"exit")==0) break;
+ }
+ return 0;
+}
--- /dev/null
+package tests;
+
+import org.xwt.mips.Runtime;
+import org.xwt.mips.Interpreter;
+
+class Env {
+ public static void main(String[] args) throws Exception {
+ int n = 0;
+ while(n < args.length && args[n].indexOf("=") != -1) n++;
+
+ if(n==args.length) {
+ System.err.println("Usage: Env [name=value ...] classname [args ...]");
+ System.exit(1);
+ }
+
+ String[] env = new String[n];
+ String[] appArgs = new String[args.length-n-1];
+ for(int i=0;i<n;i++) env[i] = args[i];
+ String className = args[n];
+ for(int i=n+1;i<args.length;i++) appArgs[i-n-1] = args[i];
+
+ Runtime rt;
+ if(className.endsWith(".mips")) {
+ rt = new Interpreter(className);
+ } else {
+ Class c = Class.forName(className);
+ if(!Runtime.class.isAssignableFrom(c)) { System.err.println(className + " isn't a MIPS compiled class"); System.exit(1); }
+ rt = (Runtime) c.newInstance();
+ }
+ System.exit(rt.run(appArgs,env));
+ }
+}
--- /dev/null
+package tests;
+
+import org.xwt.mips.Runtime;
+
+public class FDTest {
+ public static void main(String[] args) throws Exception {
+ Runtime rt = new Test();
+ int fd = rt.allocFDEnt(new Runtime.SeekableInputStreamFD(System.in));
+ int status = rt.run(new String[]{"test","fdtest","/dev/fd/" + fd});
+ System.err.println("Exit status: " + status);
+ }
+}
+
+
+
\ No newline at end of file
--- /dev/null
+#include <stdio.h>
+#include <freetype/freetype.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#define FT_Check(expr) do { \
+ if((expr) != 0) { \
+ fprintf(stderr,#expr " failed\n"); \
+ exit(EXIT_FAILURE); \
+ } \
+} while(0)
+
+#define BMP_WIDTH 800
+#define BMP_HEIGHT 600
+
+static char buf[BMP_WIDTH*BMP_HEIGHT];
+
+int main(int argc, char **argv) {
+ char *ttf;
+ char *out;
+ FT_Library library;
+ FT_Face face;
+ FT_GlyphSlot glyph;
+ int num_glyphs;
+ int c;
+ int glyph_index;
+ int loc_x;
+ int loc_y;
+ int glyph_width;
+ int glyph_height;
+ int i,j;
+ int fd;
+ char *p;
+ int n,count;
+ char *glyph_buf;
+ int pixel_size;
+
+ if(argc < 3) {
+ fprintf(stderr,"Usage: %s ttf bmp\n",argv[0]);
+ exit(1);
+ }
+
+ ttf = argv[1];
+ out = argv[2];
+
+ memset(buf,'\377',BMP_WIDTH*BMP_HEIGHT);
+
+ FT_Check(FT_Init_FreeType(&library));
+ FT_Check(FT_New_Face(library,ttf,0,&face));
+
+ loc_y = loc_x = 0;
+ for(pixel_size=8;pixel_size<48;pixel_size+=4) {
+ FT_Check(FT_Set_Pixel_Sizes(face,0,pixel_size));
+ for(c=32;c<127;c++) {
+ glyph_index = FT_Get_Char_Index(face,c);
+ FT_Check(FT_Load_Glyph(face,glyph_index,FT_LOAD_DEFAULT));
+ FT_Check(FT_Render_Glyph(face->glyph, ft_render_mode_normal));
+ glyph = face->glyph;
+ glyph_width = glyph->bitmap.width;
+ glyph_height = glyph->bitmap.rows;
+ glyph_buf = glyph->bitmap.buffer;
+ if(loc_x + glyph_width + glyph->bitmap_left >= BMP_WIDTH) {
+ loc_x = 0;
+ loc_y += pixel_size;
+ if(loc_y >= BMP_HEIGHT-pixel_size) goto done;
+ }
+
+ for(i=0;i<glyph_height;i++)
+ for(j=0;j<glyph_width;j++)
+ buf[(loc_y+i)*BMP_WIDTH+loc_x+j] &= (~glyph_buf[i*glyph_width+j]);
+ loc_x += face->glyph->advance.x/64;
+ }
+ }
+done:
+
+ if((fd = open(out,O_CREAT|O_WRONLY,0644)) < 0) {
+ perror("open");
+ exit(1);
+ }
+ p = buf;
+ count = BMP_WIDTH*BMP_HEIGHT;
+
+ while(count) {
+ n = write(fd,p,count);
+ if(n < 0) {
+ perror("write");
+ exit(1);
+ }
+ count -=n;
+ p += n;
+ }
+ close(fd);
+
+ return 0;
+}
--- /dev/null
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/wait.h>
+
+int main() {
+ fprintf(stderr,"In the main process (pid: %d), about to fork\n",getpid());
+ pid_t pid = fork();
+ int status;
+ int i;
+
+ switch(pid) {
+ case -1: perror("fork"); break;
+ case 0:
+ fprintf(stderr,"In the forked process (pid: %d), sleeping for 2 sec\n",getpid());
+ sleep(2);
+ fprintf(stderr,"Child done sleeping... exiting\n");
+ _exit(0);
+ break;
+ default:
+ fprintf(stderr,"In the main process (child is: %d) waiting for child\n",pid);
+ if(waitpid(pid,&status,0) < 0)
+ perror("waitpid");
+ else
+ fprintf(stderr,"Child process exited (status: %d)\n",status);
+ }
+
+ pid = fork();
+ if(pid==0) {
+ fprintf(stderr,"1st fork (pid: %d)\n",getpid());
+ if(fork()==0) {
+ fprintf(stderr,"2nd fork (pid: %d).. sleeping\n",getpid());
+ sleep(5);
+ fprintf(stderr,"2nd fork exiting\n");
+ _exit(0);
+ }
+ _exit(0);
+ } else {
+ waitpid(pid,NULL,0);
+ fprintf(stderr,"1st fork terminated\n");
+ }
+ fprintf(stderr,"Sleeping for a bit\n");
+ sleep(10);
+ fprintf(stderr,"Next few pids should be sequential\n");
+ for(i=0;i<10;i++) {
+ if(fork() == 0) {
+ fprintf(stderr,"I am a child %d\n",getpid());
+ sleep(i%4);
+ _exit(0);
+ }
+ }
+ for(i=0;i<10;i++) fprintf(stderr,"Waited on %d\n",waitpid(-1,NULL,0));
+
+ return 0;
+}
--- /dev/null
+package tests;
+
+import org.xwt.mips.Runtime;
+import org.xwt.mips.Interpreter;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.image.*;
+import java.awt.event.*;
+import java.io.*;
+
+public class FreeTypeDemo {
+ private JFrame frame;
+ private static final int OURWIDTH=640;
+ private static final int OURHEIGHT=256;
+ private static final int BASELINE=160;
+ private byte[] render = new byte[OURWIDTH*OURHEIGHT];
+ private int size = 72;
+ private StringBuffer sb = new StringBuffer();
+ private View view;
+ private Image image;
+
+ private Runnable renderThread;
+ private String theText;
+ private boolean renderNeeded;
+
+ private String name;
+ private Runtime rt;
+
+ int renderAddr;
+ int stringAddr;
+ int stringSize;
+
+ public static void main(String[] argv) throws Exception {
+ new FreeTypeDemo(argv);
+ }
+
+ public FreeTypeDemo(String[] argv) throws Exception {
+ if(argv.length >= 2 && argv[1].startsWith("int")) {
+ name = "Interpreter";
+ rt = new Interpreter("build/FreeTypeDemoHelper.mips");
+ } else {
+ rt = new FreeTypeDemoHelper();
+ name = "Compiler";
+ }
+
+ rt.start(new String[]{ "freetype.mips"});
+ if(rt.execute()) throw new Error("freetype.mips exited");
+
+ byte[] font = InputStreamToByteArray.convert(new FileInputStream(argv[0]));
+ int fontAddr = rt.malloc(font.length);
+ if(fontAddr == 0) throw new Error("malloc() failed");
+ rt.copyout(font,fontAddr,font.length);
+
+ rt.setUserInfo(0,fontAddr);
+ rt.setUserInfo(1,font.length);
+
+ renderAddr = rt.malloc(OURWIDTH*OURHEIGHT);
+ if(renderAddr == 0) throw new Error("malloc() failed");
+
+ if(rt.execute()) throw new Error("freetype.mips exited (" + rt.getUserInfo(1) +")");
+
+ createImage();
+
+ frame = new JFrame("FreeTypeDemo - " + name);
+ frame.setSize(OURWIDTH,OURHEIGHT);
+ view = new View();
+ frame.getContentPane().add(view,BorderLayout.CENTER);
+ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ frame.show();
+ view.requestFocus();
+ renderThread = new Runnable() {
+ public void run() {
+ try {
+ for(;;) {
+ synchronized(this) { while(!renderNeeded) wait(); renderNeeded = false; }
+ renderText(theText==null ? "" : theText);
+ }
+ } catch(Exception e) { throw new Error(e); }
+ }
+ };
+ new Thread(renderThread).start();
+ keyPress('\n');
+ }
+
+ private static ColorModel cmodel = new DirectColorModel(8, 0xff,0xff,0xff);
+ private void createImage() {
+ for(int i=0;i<OURHEIGHT;i++)
+ for(int j=0;j<OURWIDTH;j++)
+ render[i*OURWIDTH+j] = (byte)((~(render[i*OURWIDTH+j]&0xff))&0xff);
+ image = Toolkit.getDefaultToolkit().createImage(new MemoryImageSource(OURWIDTH, OURHEIGHT, cmodel, render, 0, OURWIDTH));
+ MediaTracker mediatracker = new MediaTracker(new Canvas());
+ mediatracker.addImage(image, 1);
+ try { mediatracker.waitForAll(); } catch (InterruptedException e) { }
+ mediatracker.removeImage(image);
+ }
+ private void renderText(String s) {
+ try {
+ byte[] b = (s+"\0").getBytes("UTF-16BE");
+ if(stringSize < b.length) {
+ System.err.println("reallocing the string space");
+ if(stringAddr != 0) rt.free(stringAddr);
+ stringAddr = rt.malloc(b.length*2);
+ if(stringAddr == 0) throw new Error("malloc failed");
+ stringSize = b.length*2;
+ }
+ rt.copyout(b,stringAddr,b.length);
+ long start = System.currentTimeMillis();
+ if(rt.call("render",stringAddr,size,renderAddr,OURWIDTH,OURHEIGHT,BASELINE)==0) throw new Error("render() failed");
+ System.out.println(name + ": Render of: " + s + " took " + (System.currentTimeMillis()-start) + " ms");
+ rt.copyin(renderAddr,render,render.length);
+ createImage();
+ view.repaint();
+ } catch(Exception e) {
+ throw new Error(e);
+ }
+ }
+
+ private void keyPress(char c) {
+ if(c == '\n' || c == '\r') {
+ sb.setLength(0);
+ theText = "Press any key";
+ } else if(c == '+' || c == '-') {
+ size += (c=='+'?1:-1) * 8;
+ System.out.println("New size: " + size);
+ } else {
+ sb.append(c);
+ theText = sb.toString();
+ }
+ synchronized(renderThread) { renderNeeded = true; renderThread.notify(); }
+ }
+
+ public class View extends JComponent {
+ public void paintComponent(Graphics g) {
+ g.drawImage(image,0,0,OURWIDTH,OURHEIGHT,0,0,OURWIDTH,OURHEIGHT,null);
+ }
+ public View() {
+ addKeyListener(new KeyAdapter() {
+ public void keyTyped(KeyEvent e) {
+ keyPress(e.getKeyChar());
+ }
+ });
+ setPreferredSize(new Dimension(OURWIDTH,OURHEIGHT));
+ }
+ }
+ private static class InputStreamToByteArray {
+
+ /** scratch space for isToByteArray() */
+ private static byte[] workspace = new byte[16 * 1024];
+ /** Trivial method to completely read an InputStream */
+ public static synchronized byte[] convert(InputStream is) throws IOException {
+ int pos = 0;
+ while (true) {
+ int numread = is.read(workspace, pos, workspace.length - pos);
+ if (numread == -1) break;
+ else if (pos + numread < workspace.length) pos += numread;
+ else {
+ pos += numread;
+ byte[] temp = new byte[workspace.length * 2];
+ System.arraycopy(workspace, 0, temp, 0, workspace.length);
+ workspace = temp;
+ }
+ }
+ byte[] ret = new byte[pos];
+ System.arraycopy(workspace, 0, ret, 0, pos);
+ return ret;
+ }
+ }
+}
+
--- /dev/null
+// Copyright 2003 Adam Megacz, see the COPYING file for licensing [GPL]
+
+#include <unistd.h>
+#include <freetype/freetype.h>
+
+FT_Library library; /* handle to library */
+FT_Face face; /* handle to face object */
+
+#define FT_Check(expr,err) do { \
+ if((expr) != 0) { \
+ errprint(#expr " failed\n"); \
+ return err; \
+ } \
+} while(0)
+
+#define max(a,b) ((a) > (b) ? (a) : (b))
+#define min(a,b) ((a) < (b) ? (a) : (b))
+
+static int errprint(const char *s) {
+ int l = strlen(s);
+ int n;
+ while(l) {
+ n = write(STDERR_FILENO,s,l);
+ if(n < 0) return n;
+ l -= n;
+ s += n;
+ }
+ return 0;
+}
+
+void draw(FT_GlyphSlot glyph,int x, char *buf, int buf_width, int buf_height, int baseline) {
+ int y = max(baseline - glyph->bitmap_top,0);
+ int rows = glyph->bitmap.rows;
+ int width = glyph->bitmap.width;
+ int i,j;
+ x = x + glyph->bitmap_left;
+ if(x + width >= buf_width) return;
+ if(y + rows >= buf_height) return;
+ //if(buf == NULL) fprintf(stderr,"ABout to dereference %p\n",buf);
+ for(i=0;i<rows;i++)
+ for(j=0;j<width;j++)
+ buf[(i+y)*buf_width+x+j] |= glyph->bitmap.buffer[i*width+j];
+}
+
+/* Prevent --gc-sections from blowing this away */
+int render(short *s, int size, char *buf, int buf_width, int buf_height, int baseline) __attribute__((section(".text")));
+int render(short *s, int size, char *buf, int buf_width, int buf_height, int baseline) {
+ int glyph_index;
+ int x = 0;
+ FT_Check(FT_Set_Pixel_Sizes(face,0,size),0);
+ memset(buf,'\0',buf_width*buf_height);
+ //fprintf(stderr,"Rendering %d pt %c... at %p (%dx%d)\n",size,*s,buf,buf_width,buf_height);
+ while(*s) {
+ glyph_index = FT_Get_Char_Index(face,*s);
+ FT_Check(FT_Load_Glyph(face,glyph_index,FT_LOAD_DEFAULT),0);
+ FT_Check(FT_Render_Glyph(face->glyph,FT_RENDER_MODE_NORMAL/*256color antialiased*/),0);
+ draw(face->glyph,x,buf,buf_width,buf_height,baseline);
+ x += face->glyph->advance.x/64;
+ s++;
+ }
+ return 1;
+}
+
+char * user_info[2];
+extern void _pause();
+
+int main(int argc,char** argv) {
+ char *fontdata;
+ int fontsize;
+
+ _pause();
+
+ fontdata = user_info[0];
+ fontsize = (int)user_info[1];
+
+ //fprintf(stderr,"Initializng freetype with a %d byte font at %p\n", fontsize, fontdata);
+
+ FT_Check(FT_Init_FreeType(&library),EXIT_FAILURE);
+ FT_Check(FT_New_Memory_Face(library, fontdata,fontsize, 0, &face),EXIT_FAILURE);
+
+ errprint("Freetype initialized\n");
+ _pause();
+ errprint("Unpaused\n");
+
+ /* not reached */
+ return EXIT_FAILURE;
+}
--- /dev/null
+#include <stdio.h>
+
+int main() {
+ puts("Hello, World");
+ return 0;
+}
--- /dev/null
+package tests;
+
+import org.xwt.mips.Runtime;
+import java.io.*;
+
+public class MSPack {
+ private String[] fileNames;
+ private int[] lengths;
+ private byte[][] data;
+
+ public static class MSPackException extends IOException { public MSPackException(String s) { super(s); } }
+
+ public MSPack(InputStream cabIS) throws IOException {
+ byte[] cab = InputStreamToByteArray.convert(cabIS);
+ try {
+ //Interpreter vm = new Interpreter("mspack.mips");
+ MSPackHelper vm = new MSPackHelper();
+
+ int cabAddr = vm.sbrk(cab.length);
+ if(cabAddr < 0) throw new MSPackException("sbrk failed");
+
+ vm.copyout(cab,cabAddr,cab.length);
+
+ vm.setUserInfo(0,cabAddr);
+ vm.setUserInfo(1,cab.length);
+
+ int status = vm.run(new String[]{ "mspack.mips"} );
+ if(status != 0) throw new MSPackException("mspack.mips failed (" + status + ")");
+
+ /*static struct {
+ char *filename;
+ char *data;
+ int length;
+ } output_table[MAX_MEMBERS+1]; */
+
+ int filesTable = vm.getUserInfo(2);
+ int count=0;
+ while(vm.memRead(filesTable+count*12) != 0) count++;
+
+ fileNames = new String[count];
+ data = new byte[count][];
+ lengths = new int[count];
+
+ for(int i=0,addr=filesTable;i<count;i++,addr+=12) {
+ int length = vm.memRead(addr+8);
+ data[i] = new byte[length];
+ lengths[i] = length;
+ fileNames[i] = vm.cstring(vm.memRead(addr));
+ System.out.println("" + fileNames[i]);
+ vm.copyin(vm.memRead(addr+4),data[i],length);
+ }
+ } catch(Runtime.ExecutionException e) {
+ e.printStackTrace();
+ throw new MSPackException("mspack.mips crashed");
+ }
+ }
+
+ public String[] getFileNames() { return fileNames; }
+ public int[] getLengths() { return lengths; }
+ public InputStream getInputStream(int index) { return new ByteArrayInputStream(data[index]); }
+ public InputStream getInputStream(String fileName) {
+ for(int i=0;i<fileNames.length;i++) {
+ if(fileName.equalsIgnoreCase(fileNames[i])) return getInputStream(i);
+ }
+ return null;
+ }
+
+ public static void main(String[] args) throws IOException {
+ MSPack pack = new MSPack(new FileInputStream(args[0]));
+ String[] files = pack.getFileNames();
+ for(int i=0;i<files.length;i++)
+ System.out.println(i + ": " + files[i] + ": " + pack.getLengths()[i]);
+ System.out.println("Writing " + files[files.length-1]);
+ InputStream is = pack.getInputStream(files.length-1);
+ OutputStream os = new FileOutputStream(files[files.length-1]);
+ int n;
+ byte[] buf = new byte[4096];
+ while((n = is.read(buf)) != -1) os.write(buf,0,n);
+ os.close();
+ is.close();
+ }
+ private static class InputStreamToByteArray {
+
+ /** scratch space for isToByteArray() */
+ private static byte[] workspace = new byte[16 * 1024];
+ /** Trivial method to completely read an InputStream */
+ public static synchronized byte[] convert(InputStream is) throws IOException {
+ int pos = 0;
+ while (true) {
+ int numread = is.read(workspace, pos, workspace.length - pos);
+ if (numread == -1) break;
+ else if (pos + numread < workspace.length) pos += numread;
+ else {
+ pos += numread;
+ byte[] temp = new byte[workspace.length * 2];
+ System.arraycopy(workspace, 0, temp, 0, workspace.length);
+ workspace = temp;
+ }
+ }
+ byte[] ret = new byte[pos];
+ System.arraycopy(workspace, 0, ret, 0, pos);
+ return ret;
+ }
+ }
+}
+
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <sys/fcntl.h>
+
+#include "mspack.h"
+
+int main(int argc, char **argv) {
+ struct mscab_decompressor *decomp;
+ struct mscabd_cabinet *cab;
+ struct mscabd_file *file;
+ int i;
+
+ if(argc < 2) {
+ fprintf(stderr,"Usage: %s cab\n",argv[0]);
+ exit(1);
+ }
+
+
+ decomp = mspack_create_cab_decompressor(NULL);
+ if(!decomp) exit(1);
+
+ for(i=1;i<argc;i++) {
+ cab = decomp->search(decomp,argv[i]);
+ if(!cab) exit(2);
+
+ for(file = cab->files;file;file=file->next)
+ decomp->extract(decomp,file,file->filename);
+
+ decomp->close(decomp,cab);
+ }
+ mspack_destroy_cab_decompressor(decomp);
+
+ return 0;
+}
--- /dev/null
+/*
+UserInfo:
+ On start:
+ 0: Addr of CAB/EXE
+ 1: Length of CAB/EXE
+ On Edit:
+ 2: Addr of output_table array
+
+Exit codes:
+ 0: Success
+ 1: Internal Error
+ 2: Invalid CAB
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <sys/fcntl.h>
+
+#include "mspack.h"
+
+#define MAX(a,b) (((a)>(b))?(a):(b))
+#define MIN(a,b) (((a)<(b))?(a):(b))
+#define MAX_MEMBERS 64
+
+char *xstrdup(const char *s) {
+ char *ret = strdup(s);
+ if(ret == NULL) exit(1);
+ return ret;
+}
+
+typedef struct {
+ char *addr;
+ int pos;
+ int size;
+ int length;
+ int writable;
+} mem_buf_t;
+
+static mem_buf_t *cab_mem_buf = NULL;
+
+static void mem_buf_grow(mem_buf_t *buf,size_t newsize) {
+ size_t new_len;
+ char *p;
+ if(buf->length < 0) exit(1);
+ if(newsize <= buf->length) return;
+ new_len = MAX(buf->length ? buf->length*2 : 65536,newsize);
+ p = realloc(buf->addr,new_len);
+ if(p == NULL) exit(1);
+ buf->addr = p;
+ buf->length = new_len;
+}
+
+static struct {
+ char *filename;
+ mem_buf_t buf;
+} write_buf_table[MAX_MEMBERS];
+
+static struct {
+ char *filename;
+ char *data;
+ int length;
+} output_table[MAX_MEMBERS+1];
+
+static struct mspack_file *my_open(struct mspack_system *sys, char *filename, int mode) {
+ mem_buf_t *buf = NULL;
+ int i;
+ if(strcmp(filename,"/dev/cab")==0) {
+ if(mode != MSPACK_SYS_OPEN_READ) return NULL;
+ buf = cab_mem_buf;
+ } else {
+ if(mode != MSPACK_SYS_OPEN_WRITE) return NULL;
+
+ for(i=0;i<MAX_MEMBERS;i++) {
+ if(write_buf_table[i].filename == NULL) {
+ printf("%s in %d\n",filename,i);
+ write_buf_table[i].filename = xstrdup(filename);
+ buf = &write_buf_table[i].buf;
+ buf->writable = 1;
+ break;
+ }
+ }
+ }
+
+ return (struct mspack_file *) buf;
+}
+
+static void my_close(struct mspack_file *buf_) {
+ mem_buf_t *buf = (mem_buf_t*) buf_;
+ /* NO OP */
+}
+
+static int my_read(struct mspack_file *buf_, void *out, int count) {
+ mem_buf_t *buf = (mem_buf_t*) buf_;
+ count = MIN(buf->size - buf->pos, count);
+ memcpy(out,buf->addr + buf->pos,count);
+ buf->pos += count;
+ return count;
+}
+
+static int my_write(struct mspack_file *buf_, void *in, int count) {
+ mem_buf_t *buf = (mem_buf_t*) buf_;
+ if(!buf->writable) return -1;
+ if(buf->length < buf->pos + count) mem_buf_grow(buf,buf->pos + count);
+ memcpy(buf->addr+buf->pos,in,count);
+ buf->pos += count;
+ buf->size = MAX(buf->size,buf->pos);
+ return count;
+}
+
+static int my_seek(struct mspack_file *buf_, off_t off, int mode) {
+ mem_buf_t *buf = (mem_buf_t*) buf_;
+ int newpos;
+ switch(mode) {
+ case MSPACK_SYS_SEEK_START: newpos = off; break;
+ case MSPACK_SYS_SEEK_CUR: newpos = buf->pos + off; break;
+ case MSPACK_SYS_SEEK_END: newpos = buf->size - off; break;
+ default: return -1;
+ }
+ if(newpos < 0) return -1;
+ if(newpos > buf->size) {
+ if(!buf->writable) return -1;
+ if(newpos > buf->length)
+ mem_buf_grow(buf,newpos);
+ }
+ buf->pos = newpos;
+ return 0;
+}
+
+static off_t my_tell(struct mspack_file *buf_) {
+ mem_buf_t *buf = (mem_buf_t*) buf_;
+ return buf ? buf->pos : 0;
+}
+
+static void my_message(struct mspack_file *file, char *format, ...) {
+ va_list ap;
+ va_start(ap, format);
+ vfprintf(stderr, format, ap);
+ va_end(ap);
+ fputc((int) '\n', stderr);
+ fflush(stderr);
+}
+
+static void *my_alloc(struct mspack_system *sys, size_t size) { return malloc(size); }
+static void my_free(void *p) { free(p); }
+static void my_copy(void *src, void *dest, size_t bytes) { memcpy(dest, src, bytes); }
+
+static struct mspack_system my_system = {
+ &my_open,
+ &my_close,
+ &my_read,
+ &my_write,
+ &my_seek,
+ &my_tell,
+ &my_message,
+ &my_alloc,
+ &my_free,
+ &my_copy,
+ NULL
+};
+
+char *user_info[4];
+
+int main(int argc, char **argv) {
+ struct mscab_decompressor *decomp;
+ struct mscabd_cabinet *cab;
+ struct mscabd_file *file;
+ mem_buf_t mem_buf;
+ size_t size = (size_t)user_info[1];
+ int i;
+
+ mem_buf.addr = user_info[0];
+ mem_buf.pos = mem_buf.writable = 0;
+ mem_buf.length = -1;
+ mem_buf.size = size;
+
+ cab_mem_buf = &mem_buf;
+
+ decomp = mspack_create_cab_decompressor(&my_system);
+ if(!decomp) exit(1);
+
+ cab = decomp->search(decomp,"/dev/cab");
+ if(!cab) exit(2);
+
+ for(file = cab->files;file;file=file->next)
+ decomp->extract(decomp,file,file->filename);
+
+ decomp->close(decomp,cab);
+ mspack_destroy_cab_decompressor(decomp);
+
+ printf("Success!\n");
+
+ for(i=0;i<MAX_MEMBERS && write_buf_table[i].filename;i++) {
+ output_table[i].filename = write_buf_table[i].filename;
+ output_table[i].data = write_buf_table[i].buf.addr;
+ output_table[i].length = write_buf_table[i].buf.size;
+ }
+
+ user_info[2] = (char*) output_table;
+
+ /*
+ if(output_table[0].filename) {
+ printf("%s in 0\n",write_buf_table[0].filename);
+ fp = fopen(output_table[0].filename,"wb");
+ if(fp) {
+ fwrite(output_table[0].data,1,output_table[0].length,fp);
+ fclose(fp);
+ printf("Wrote: %s\n",output_table[0].filename);
+ }
+ }
+ */
+
+ return 0;
+}
--- /dev/null
+/* A C version of Kahan's Floating Point Test "Paranoia"
+
+ Thos Sumner, UCSF, Feb. 1985
+ David Gay, BTL, Jan. 1986
+
+ This is a rewrite from the Pascal version by
+
+ B. A. Wichmann, 18 Jan. 1985
+
+ (and does NOT exhibit good C programming style).
+
+ Adjusted to use Standard C headers 19 Jan. 1992 (dmg);
+ compile with -DKR_headers or insert
+#define KR_headers
+ at the beginning if you have an old-style C compiler.
+
+(C) Apr 19 1983 in BASIC version by:
+ Professor W. M. Kahan,
+ 567 Evans Hall
+ Electrical Engineering & Computer Science Dept.
+ University of California
+ Berkeley, California 94720
+ USA
+
+converted to Pascal by:
+ B. A. Wichmann
+ National Physical Laboratory
+ Teddington Middx
+ TW11 OLW
+ UK
+
+converted to C by:
+
+ David M. Gay and Thos Sumner
+ AT&T Bell Labs Computer Center, Rm. U-76
+ 600 Mountain Avenue University of California
+ Murray Hill, NJ 07974 San Francisco, CA 94143
+ USA USA
+
+with simultaneous corrections to the Pascal source (reflected
+in the Pascal source available over netlib).
+[A couple of bug fixes from dgh = sun!dhough incorporated 31 July 1986.]
+
+Reports of results on various systems from all the versions
+of Paranoia are being collected by Richard Karpinski at the
+same address as Thos Sumner. This includes sample outputs,
+bug reports, and criticisms.
+
+You may copy this program freely if you acknowledge its source.
+Comments on the Pascal version to NPL, please.
+
+
+The C version catches signals from floating-point exceptions.
+If signal(SIGFPE,...) is unavailable in your environment, you may
+#define NOSIGNAL to comment out the invocations of signal.
+
+This source file is too big for some C compilers, but may be split
+into pieces. Comments containing "SPLIT" suggest convenient places
+for this splitting. At the end of these comments is an "ed script"
+(for the UNIX(tm) editor ed) that will do this splitting.
+
+By #defining Single when you compile this source, you may obtain
+a single-precision C version of Paranoia.
+
+
+The following is from the introductory commentary from Wichmann's work:
+
+The BASIC program of Kahan is written in Microsoft BASIC using many
+facilities which have no exact analogy in Pascal. The Pascal
+version below cannot therefore be exactly the same. Rather than be
+a minimal transcription of the BASIC program, the Pascal coding
+follows the conventional style of block-structured languages. Hence
+the Pascal version could be useful in producing versions in other
+structured languages.
+
+Rather than use identifiers of minimal length (which therefore have
+little mnemonic significance), the Pascal version uses meaningful
+identifiers as follows [Note: A few changes have been made for C]:
+
+
+BASIC C BASIC C BASIC C
+
+ A J S StickyBit
+ A1 AInverse J0 NoErrors T
+ B Radix [Failure] T0 Underflow
+ B1 BInverse J1 NoErrors T2 ThirtyTwo
+ B2 RadixD2 [SeriousDefect] T5 OneAndHalf
+ B9 BMinusU2 J2 NoErrors T7 TwentySeven
+ C [Defect] T8 TwoForty
+ C1 CInverse J3 NoErrors U OneUlp
+ D [Flaw] U0 UnderflowThreshold
+ D4 FourD K PageNo U1
+ E0 L Milestone U2
+ E1 M V
+ E2 Exp2 N V0
+ E3 N1 V8
+ E5 MinSqEr O Zero V9
+ E6 SqEr O1 One W
+ E7 MaxSqEr O2 Two X
+ E8 O3 Three X1
+ E9 O4 Four X8
+ F1 MinusOne O5 Five X9 Random1
+ F2 Half O8 Eight Y
+ F3 Third O9 Nine Y1
+ F6 P Precision Y2
+ F9 Q Y9 Random2
+ G1 GMult Q8 Z
+ G2 GDiv Q9 Z0 PseudoZero
+ G3 GAddSub R Z1
+ H R1 RMult Z2
+ H1 HInverse R2 RDiv Z9
+ I R3 RAddSub
+ IO NoTrials R4 RSqrt
+ I3 IEEE R9 Random9
+
+ SqRWrng
+
+All the variables in BASIC are true variables and in consequence,
+the program is more difficult to follow since the "constants" must
+be determined (the glossary is very helpful). The Pascal version
+uses Real constants, but checks are added to ensure that the values
+are correctly converted by the compiler.
+
+The major textual change to the Pascal version apart from the
+identifiersis that named procedures are used, inserting parameters
+wherehelpful. New procedures are also introduced. The
+correspondence is as follows:
+
+
+BASIC Pascal
+lines
+
+ 90- 140 Pause
+ 170- 250 Instructions
+ 380- 460 Heading
+ 480- 670 Characteristics
+ 690- 870 History
+2940-2950 Random
+3710-3740 NewD
+4040-4080 DoesYequalX
+4090-4110 PrintIfNPositive
+4640-4850 TestPartialUnderflow
+
+=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
+
+Below is an "ed script" that splits para.c into 10 files
+of the form part[1-8].c, subs.c, and msgs.c, plus a header
+file, paranoia.h, that these files require.
+
+r paranoia.c
+$
+?SPLIT
+ .d
++d
+-,$w msgs.c
+-,$d
+?SPLIT
+ .d
++d
+-,$w subs.c
+-,$d
+?part8
++d
+?include
+ .,$w part8.c
+ .,$d
+-d
+?part7
++d
+?include
+ .,$w part7.c
+ .,$d
+-d
+?part6
++d
+?include
+ .,$w part6.c
+ .,$d
+-d
+?part5
++d
+?include
+ .,$w part5.c
+ .,$d
+-d
+?part4
++d
+?include
+ .,$w part4.c
+ .,$d
+-d
+?part3
++d
+?include
+ .,$w part3.c
+ .,$d
+-d
+?part2
++d
+?include
+ .,$w part2.c
+ .,$d
+?SPLIT
+ .d
+1,/^#include/-1d
+1,$w part1.c
+/Computed constants/,$d
+1,$s/^int/extern &/
+1,$s/^FLOAT/extern &/
+1,$s/^char/extern &/
+1,$s! = .*!;!
+/^Guard/,/^Round/s/^/extern /
+/^jmp_buf/s/^/extern /
+/^Sig_type/s/^/extern /
+s/$/\
+extern void sigfpe(INT);/
+w paranoia.h
+q
+
+*/
+
+#include <stdio.h>
+#ifndef NOSIGNAL
+#include <signal.h>
+#endif
+#include <setjmp.h>
+
+#ifdef Single
+#define FLOAT float
+#define FABS(x) (float)fabs((double)(x))
+#define FLOOR(x) (float)floor((double)(x))
+#define LOG(x) (float)log((double)(x))
+#define POW(x,y) (float)pow((double)(x),(double)(y))
+#define SQRT(x) (float)sqrt((double)(x))
+#else
+#define FLOAT double
+#define FABS(x) fabs(x)
+#define FLOOR(x) floor(x)
+#define LOG(x) log(x)
+#define POW(x,y) pow(x,y)
+#define SQRT(x) sqrt(x)
+#endif
+
+jmp_buf ovfl_buf;
+#ifdef KR_headers
+#define VOID /* void */
+#define INT /* int */
+#define FP /* FLOAT */
+#define CHARP /* char * */
+#define CHARPP /* char ** */
+extern double fabs(), floor(), log(), pow(), sqrt();
+extern void exit();
+typedef void (*Sig_type)();
+FLOAT Sign(), Random();
+extern void BadCond();
+extern void SqXMinX();
+extern void TstCond();
+extern void notify();
+extern int read();
+#else
+#define VOID void
+#define INT int
+#define FP FLOAT
+#define CHARP char *
+#define CHARPP char **
+#ifdef __STDC__
+#include <stdlib.h>
+#include <math.h>
+#else
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern double fabs(double), floor(double), log(double);
+extern double pow(double,double), sqrt(double);
+extern void exit(INT);
+#ifdef __cplusplus
+ }
+#endif
+#endif
+typedef void (*Sig_type)(int);
+FLOAT Sign(FLOAT), Random(void);
+extern void BadCond(int, char*);
+extern void SqXMinX(int);
+extern void TstCond(int, int, char*);
+extern void notify(char*);
+extern int read(int, char*, int);
+#endif
+#undef V9
+extern void Characteristics(VOID);
+extern void Heading(VOID);
+extern void History(VOID);
+extern void Instructions(VOID);
+extern void IsYeqX(VOID);
+extern void NewD(VOID);
+extern void Pause(VOID);
+extern void PrintIfNPositive(VOID);
+extern void SR3750(VOID);
+extern void SR3980(VOID);
+extern void TstPtUf(VOID);
+
+Sig_type sigsave;
+
+#define KEYBOARD 0
+
+FLOAT Radix, BInvrse, RadixD2, BMinusU2;
+
+/*Small floating point constants.*/
+FLOAT Zero = 0.0;
+FLOAT Half = 0.5;
+FLOAT One = 1.0;
+FLOAT Two = 2.0;
+FLOAT Three = 3.0;
+FLOAT Four = 4.0;
+FLOAT Five = 5.0;
+FLOAT Eight = 8.0;
+FLOAT Nine = 9.0;
+FLOAT TwentySeven = 27.0;
+FLOAT ThirtyTwo = 32.0;
+FLOAT TwoForty = 240.0;
+FLOAT MinusOne = -1.0;
+FLOAT OneAndHalf = 1.5;
+/*Integer constants*/
+int NoTrials = 20; /*Number of tests for commutativity. */
+#define False 0
+#define True 1
+
+/* Definitions for declared types
+ Guard == (Yes, No);
+ Rounding == (Chopped, Rounded, Other);
+ Message == packed array [1..40] of char;
+ Class == (Flaw, Defect, Serious, Failure);
+ */
+#define Yes 1
+#define No 0
+#define Chopped 2
+#define Rounded 1
+#define Other 0
+#define Flaw 3
+#define Defect 2
+#define Serious 1
+#define Failure 0
+typedef int Guard, Rounding, Class;
+typedef char Message;
+
+/* Declarations of Variables */
+int Indx;
+char ch[8];
+FLOAT AInvrse, A1;
+FLOAT C, CInvrse;
+FLOAT D, FourD;
+FLOAT E0, E1, Exp2, E3, MinSqEr;
+FLOAT SqEr, MaxSqEr, E9;
+FLOAT Third;
+FLOAT F6, F9;
+FLOAT H, HInvrse;
+int I;
+FLOAT StickyBit, J;
+FLOAT MyZero;
+FLOAT Precision;
+FLOAT Q, Q9;
+FLOAT R, Random9;
+FLOAT T, Underflow, S;
+FLOAT OneUlp, UfThold, U1, U2;
+FLOAT V, V0, V9;
+FLOAT W;
+FLOAT X, X1, X2, X8, Random1;
+FLOAT Y, Y1, Y2, Random2;
+FLOAT Z, PseudoZero, Z1, Z2, Z9;
+int ErrCnt[4];
+int fpecount;
+int Milestone;
+int PageNo;
+int M, N, N1;
+Guard GMult, GDiv, GAddSub;
+Rounding RMult, RDiv, RAddSub, RSqrt;
+int Break, Done, NotMonot, Monot, Anomaly, IEEE,
+ SqRWrng, UfNGrad;
+/* Computed constants. */
+/*U1 gap below 1.0, i.e, 1.0-U1 is next number below 1.0 */
+/*U2 gap above 1.0, i.e, 1.0+U2 is next number above 1.0 */
+
+/* floating point exception receiver */
+ void
+sigfpe(INT x)
+{
+ fpecount++;
+ printf("\n* * * FLOATING-POINT ERROR %d * * *\n", x);
+ fflush(stdout);
+ if (sigsave) {
+#ifndef NOSIGNAL
+ signal(SIGFPE, sigsave);
+#endif
+ sigsave = 0;
+ longjmp(ovfl_buf, 1);
+ }
+ exit(1);
+}
+
+main(VOID)
+{
+ /* First two assignments use integer right-hand sides. */
+ Zero = 0;
+ One = 1;
+ Two = One + One;
+ Three = Two + One;
+ Four = Three + One;
+ Five = Four + One;
+ Eight = Four + Four;
+ Nine = Three * Three;
+ TwentySeven = Nine * Three;
+ ThirtyTwo = Four * Eight;
+ TwoForty = Four * Five * Three * Four;
+ MinusOne = -One;
+ Half = One / Two;
+ OneAndHalf = One + Half;
+ ErrCnt[Failure] = 0;
+ ErrCnt[Serious] = 0;
+ ErrCnt[Defect] = 0;
+ ErrCnt[Flaw] = 0;
+ PageNo = 1;
+ /*=============================================*/
+ Milestone = 0;
+ /*=============================================*/
+#ifndef NOSIGNAL
+ signal(SIGFPE, sigfpe);
+#endif
+ Instructions();
+ Pause();
+ Heading();
+ Pause();
+ Characteristics();
+ Pause();
+ History();
+ Pause();
+ /*=============================================*/
+ Milestone = 7;
+ /*=============================================*/
+ printf("Program is now RUNNING tests on small integers:\n");
+
+ TstCond (Failure, (Zero + Zero == Zero) && (One - One == Zero)
+ && (One > Zero) && (One + One == Two),
+ "0+0 != 0, 1-1 != 0, 1 <= 0, or 1+1 != 2");
+ Z = - Zero;
+ if (Z != 0.0) {
+ ErrCnt[Failure] = ErrCnt[Failure] + 1;
+ printf("Comparison alleges that -0.0 is Non-zero!\n");
+ U2 = 0.001;
+ Radix = 1;
+ TstPtUf();
+ }
+ TstCond (Failure, (Three == Two + One) && (Four == Three + One)
+ && (Four + Two * (- Two) == Zero)
+ && (Four - Three - One == Zero),
+ "3 != 2+1, 4 != 3+1, 4+2*(-2) != 0, or 4-3-1 != 0");
+ TstCond (Failure, (MinusOne == (0 - One))
+ && (MinusOne + One == Zero ) && (One + MinusOne == Zero)
+ && (MinusOne + FABS(One) == Zero)
+ && (MinusOne + MinusOne * MinusOne == Zero),
+ "-1+1 != 0, (-1)+abs(1) != 0, or -1+(-1)*(-1) != 0");
+ TstCond (Failure, Half + MinusOne + Half == Zero,
+ "1/2 + (-1) + 1/2 != 0");
+ /*=============================================*/
+ /*SPLIT
+ {
+ extern void part2(VOID), part3(VOID), part4(VOID),
+ part5(VOID), part6(VOID), part7(VOID);
+ int part8(VOID);
+
+ part2();
+ part3();
+ part4();
+ part5();
+ part6();
+ part7();
+ return part8();
+ }
+ }
+#include "paranoia.h"
+void part2(VOID){
+*/
+ Milestone = 10;
+ /*=============================================*/
+ TstCond (Failure, (Nine == Three * Three)
+ && (TwentySeven == Nine * Three) && (Eight == Four + Four)
+ && (ThirtyTwo == Eight * Four)
+ && (ThirtyTwo - TwentySeven - Four - One == Zero),
+ "9 != 3*3, 27 != 9*3, 32 != 8*4, or 32-27-4-1 != 0");
+ TstCond (Failure, (Five == Four + One) &&
+ (TwoForty == Four * Five * Three * Four)
+ && (TwoForty / Three - Four * Four * Five == Zero)
+ && ( TwoForty / Four - Five * Three * Four == Zero)
+ && ( TwoForty / Five - Four * Three * Four == Zero),
+ "5 != 4+1, 240/3 != 80, 240/4 != 60, or 240/5 != 48");
+ if (ErrCnt[Failure] == 0) {
+ printf("-1, 0, 1/2, 1, 2, 3, 4, 5, 9, 27, 32 & 240 are O.K.\n");
+ printf("\n");
+ }
+ printf("Searching for Radix and Precision.\n");
+ W = One;
+ do {
+ W = W + W;
+ Y = W + One;
+ Z = Y - W;
+ Y = Z - One;
+ } while (MinusOne + FABS(Y) < Zero);
+ /*.. now W is just big enough that |((W+1)-W)-1| >= 1 ...*/
+ Precision = Zero;
+ Y = One;
+ do {
+ Radix = W + Y;
+ Y = Y + Y;
+ Radix = Radix - W;
+ } while ( Radix == Zero);
+ if (Radix < Two) Radix = One;
+ printf("Radix = %f .\n", Radix);
+ if (Radix != 1) {
+ W = One;
+ do {
+ Precision = Precision + One;
+ W = W * Radix;
+ Y = W + One;
+ } while ((Y - W) == One);
+ }
+ /*... now W == Radix^Precision is barely too big to satisfy (W+1)-W == 1
+ ...*/
+ U1 = One / W;
+ U2 = Radix * U1;
+ printf("Closest relative separation found is U1 = %.7e .\n\n", U1);
+ printf("Recalculating radix and precision\n ");
+
+ /*save old values*/
+ E0 = Radix;
+ E1 = U1;
+ E9 = U2;
+ E3 = Precision;
+
+ X = Four / Three;
+ Third = X - One;
+ F6 = Half - Third;
+ X = F6 + F6;
+ X = FABS(X - Third);
+ if (X < U2) X = U2;
+
+ /*... now X = (unknown no.) ulps of 1+...*/
+ do {
+ U2 = X;
+ Y = Half * U2 + ThirtyTwo * U2 * U2;
+ Y = One + Y;
+ X = Y - One;
+ } while ( ! ((U2 <= X) || (X <= Zero)));
+
+ /*... now U2 == 1 ulp of 1 + ... */
+ X = Two / Three;
+ F6 = X - Half;
+ Third = F6 + F6;
+ X = Third - Half;
+ X = FABS(X + F6);
+ if (X < U1) X = U1;
+
+ /*... now X == (unknown no.) ulps of 1 -... */
+ do {
+ U1 = X;
+ Y = Half * U1 + ThirtyTwo * U1 * U1;
+ Y = Half - Y;
+ X = Half + Y;
+ Y = Half - X;
+ X = Half + Y;
+ } while ( ! ((U1 <= X) || (X <= Zero)));
+ /*... now U1 == 1 ulp of 1 - ... */
+ if (U1 == E1) printf("confirms closest relative separation U1 .\n");
+ else printf("gets better closest relative separation U1 = %.7e .\n", U1);
+ W = One / U1;
+ F9 = (Half - U1) + Half;
+ Radix = FLOOR(0.01 + U2 / U1);
+ if (Radix == E0) printf("Radix confirmed.\n");
+ else printf("MYSTERY: recalculated Radix = %.7e .\n", Radix);
+ TstCond (Defect, Radix <= Eight + Eight,
+ "Radix is too big: roundoff problems");
+ TstCond (Flaw, (Radix == Two) || (Radix == 10)
+ || (Radix == One), "Radix is not as good as 2 or 10");
+ /*=============================================*/
+ Milestone = 20;
+ /*=============================================*/
+ TstCond (Failure, F9 - Half < Half,
+ "(1-U1)-1/2 < 1/2 is FALSE, prog. fails?");
+ X = F9;
+ I = 1;
+ Y = X - Half;
+ Z = Y - Half;
+ TstCond (Failure, (X != One)
+ || (Z == Zero), "Comparison is fuzzy,X=1 but X-1/2-1/2 != 0");
+ X = One + U2;
+ I = 0;
+ /*=============================================*/
+ Milestone = 25;
+ /*=============================================*/
+ /*... BMinusU2 = nextafter(Radix, 0) */
+ BMinusU2 = Radix - One;
+ BMinusU2 = (BMinusU2 - U2) + One;
+ /* Purify Integers */
+ if (Radix != One) {
+ X = - TwoForty * LOG(U1) / LOG(Radix);
+ Y = FLOOR(Half + X);
+ if (FABS(X - Y) * Four < One) X = Y;
+ Precision = X / TwoForty;
+ Y = FLOOR(Half + Precision);
+ if (FABS(Precision - Y) * TwoForty < Half) Precision = Y;
+ }
+ if ((Precision != FLOOR(Precision)) || (Radix == One)) {
+ printf("Precision cannot be characterized by an Integer number\n");
+ printf("of significant digits but, by itself, this is a minor flaw.\n");
+ }
+ if (Radix == One)
+ printf("logarithmic encoding has precision characterized solely by U1.\n");
+ else printf("The number of significant digits of the Radix is %f .\n",
+ Precision);
+ TstCond (Serious, U2 * Nine * Nine * TwoForty < One,
+ "Precision worse than 5 decimal figures ");
+ /*=============================================*/
+ Milestone = 30;
+ /*=============================================*/
+ /* Test for extra-precise subepressions */
+ X = FABS(((Four / Three - One) - One / Four) * Three - One / Four);
+ do {
+ Z2 = X;
+ X = (One + (Half * Z2 + ThirtyTwo * Z2 * Z2)) - One;
+ } while ( ! ((Z2 <= X) || (X <= Zero)));
+ X = Y = Z = FABS((Three / Four - Two / Three) * Three - One / Four);
+ do {
+ Z1 = Z;
+ Z = (One / Two - ((One / Two - (Half * Z1 + ThirtyTwo * Z1 * Z1))
+ + One / Two)) + One / Two;
+ } while ( ! ((Z1 <= Z) || (Z <= Zero)));
+ do {
+ do {
+ Y1 = Y;
+ Y = (Half - ((Half - (Half * Y1 + ThirtyTwo * Y1 * Y1)) + Half
+ )) + Half;
+ } while ( ! ((Y1 <= Y) || (Y <= Zero)));
+ X1 = X;
+ X = ((Half * X1 + ThirtyTwo * X1 * X1) - F9) + F9;
+ } while ( ! ((X1 <= X) || (X <= Zero)));
+ if ((X1 != Y1) || (X1 != Z1)) {
+ BadCond(Serious, "Disagreements among the values X1, Y1, Z1,\n");
+ printf("respectively %.7e, %.7e, %.7e,\n", X1, Y1, Z1);
+ printf("are symptoms of inconsistencies introduced\n");
+ printf("by extra-precise evaluation of arithmetic subexpressions.\n");
+ notify("Possibly some part of this");
+ if ((X1 == U1) || (Y1 == U1) || (Z1 == U1)) printf(
+ "That feature is not tested further by this program.\n") ;
+ }
+ else {
+ if ((Z1 != U1) || (Z2 != U2)) {
+ if ((Z1 >= U1) || (Z2 >= U2)) {
+ BadCond(Failure, "");
+ notify("Precision");
+ printf("\tU1 = %.7e, Z1 - U1 = %.7e\n",U1,Z1-U1);
+ printf("\tU2 = %.7e, Z2 - U2 = %.7e\n",U2,Z2-U2);
+ }
+ else {
+ if ((Z1 <= Zero) || (Z2 <= Zero)) {
+ printf("Because of unusual Radix = %f", Radix);
+ printf(", or exact rational arithmetic a result\n");
+ printf("Z1 = %.7e, or Z2 = %.7e ", Z1, Z2);
+ notify("of an\nextra-precision");
+ }
+ if (Z1 != Z2 || Z1 > Zero) {
+ X = Z1 / U1;
+ Y = Z2 / U2;
+ if (Y > X) X = Y;
+ Q = - LOG(X);
+ printf("Some subexpressions appear to be calculated extra\n");
+ printf("precisely with about %g extra B-digits, i.e.\n",
+ (Q / LOG(Radix)));
+ printf("roughly %g extra significant decimals.\n",
+ Q / LOG(10.));
+ }
+ printf("That feature is not tested further by this program.\n");
+ }
+ }
+ }
+ Pause();
+ /*=============================================*/
+ /*SPLIT
+ }
+#include "paranoia.h"
+void part3(VOID){
+*/
+ Milestone = 35;
+ /*=============================================*/
+ if (Radix >= Two) {
+ X = W / (Radix * Radix);
+ Y = X + One;
+ Z = Y - X;
+ T = Z + U2;
+ X = T - Z;
+ TstCond (Failure, X == U2,
+ "Subtraction is not normalized X=Y,X+Z != Y+Z!");
+ if (X == U2) printf(
+ "Subtraction appears to be normalized, as it should be.");
+ }
+ printf("\nChecking for guard digit in *, /, and -.\n");
+ Y = F9 * One;
+ Z = One * F9;
+ X = F9 - Half;
+ Y = (Y - Half) - X;
+ Z = (Z - Half) - X;
+ X = One + U2;
+ T = X * Radix;
+ R = Radix * X;
+ X = T - Radix;
+ X = X - Radix * U2;
+ T = R - Radix;
+ T = T - Radix * U2;
+ X = X * (Radix - One);
+ T = T * (Radix - One);
+ if ((X == Zero) && (Y == Zero) && (Z == Zero) && (T == Zero)) GMult = Yes;
+ else {
+ GMult = No;
+ TstCond (Serious, False,
+ "* lacks a Guard Digit, so 1*X != X");
+ }
+ Z = Radix * U2;
+ X = One + Z;
+ Y = FABS((X + Z) - X * X) - U2;
+ X = One - U2;
+ Z = FABS((X - U2) - X * X) - U1;
+ TstCond (Failure, (Y <= Zero)
+ && (Z <= Zero), "* gets too many final digits wrong.\n");
+ Y = One - U2;
+ X = One + U2;
+ Z = One / Y;
+ Y = Z - X;
+ X = One / Three;
+ Z = Three / Nine;
+ X = X - Z;
+ T = Nine / TwentySeven;
+ Z = Z - T;
+ TstCond(Defect, X == Zero && Y == Zero && Z == Zero,
+ "Division lacks a Guard Digit, so error can exceed 1 ulp\n\
+or 1/3 and 3/9 and 9/27 may disagree");
+ Y = F9 / One;
+ X = F9 - Half;
+ Y = (Y - Half) - X;
+ X = One + U2;
+ T = X / One;
+ X = T - X;
+ if ((X == Zero) && (Y == Zero) && (Z == Zero)) GDiv = Yes;
+ else {
+ GDiv = No;
+ TstCond (Serious, False,
+ "Division lacks a Guard Digit, so X/1 != X");
+ }
+ X = One / (One + U2);
+ Y = X - Half - Half;
+ TstCond (Serious, Y < Zero,
+ "Computed value of 1/1.000..1 >= 1");
+ X = One - U2;
+ Y = One + Radix * U2;
+ Z = X * Radix;
+ T = Y * Radix;
+ R = Z / Radix;
+ StickyBit = T / Radix;
+ X = R - X;
+ Y = StickyBit - Y;
+ TstCond (Failure, X == Zero && Y == Zero,
+ "* and/or / gets too many last digits wrong");
+ Y = One - U1;
+ X = One - F9;
+ Y = One - Y;
+ T = Radix - U2;
+ Z = Radix - BMinusU2;
+ T = Radix - T;
+ if ((X == U1) && (Y == U1) && (Z == U2) && (T == U2)) GAddSub = Yes;
+ else {
+ GAddSub = No;
+ TstCond (Serious, False,
+ "- lacks Guard Digit, so cancellation is obscured");
+ }
+ if (F9 != One && F9 - One >= Zero) {
+ BadCond(Serious, "comparison alleges (1-U1) < 1 although\n");
+ printf(" subtraction yields (1-U1) - 1 = 0 , thereby vitiating\n");
+ printf(" such precautions against division by zero as\n");
+ printf(" ... if (X == 1.0) {.....} else {.../(X-1.0)...}\n");
+ }
+ if (GMult == Yes && GDiv == Yes && GAddSub == Yes) printf(
+ " *, /, and - appear to have guard digits, as they should.\n");
+ /*=============================================*/
+ Milestone = 40;
+ /*=============================================*/
+ Pause();
+ printf("Checking rounding on multiply, divide and add/subtract.\n");
+ RMult = Other;
+ RDiv = Other;
+ RAddSub = Other;
+ RadixD2 = Radix / Two;
+ A1 = Two;
+ Done = False;
+ do {
+ AInvrse = Radix;
+ do {
+ X = AInvrse;
+ AInvrse = AInvrse / A1;
+ } while ( ! (FLOOR(AInvrse) != AInvrse));
+ Done = (X == One) || (A1 > Three);
+ if (! Done) A1 = Nine + One;
+ } while ( ! (Done));
+ if (X == One) A1 = Radix;
+ AInvrse = One / A1;
+ X = A1;
+ Y = AInvrse;
+ Done = False;
+ do {
+ Z = X * Y - Half;
+ TstCond (Failure, Z == Half,
+ "X * (1/X) differs from 1");
+ Done = X == Radix;
+ X = Radix;
+ Y = One / X;
+ } while ( ! (Done));
+ Y2 = One + U2;
+ Y1 = One - U2;
+ X = OneAndHalf - U2;
+ Y = OneAndHalf + U2;
+ Z = (X - U2) * Y2;
+ T = Y * Y1;
+ Z = Z - X;
+ T = T - X;
+ X = X * Y2;
+ Y = (Y + U2) * Y1;
+ X = X - OneAndHalf;
+ Y = Y - OneAndHalf;
+ if ((X == Zero) && (Y == Zero) && (Z == Zero) && (T <= Zero)) {
+ X = (OneAndHalf + U2) * Y2;
+ Y = OneAndHalf - U2 - U2;
+ Z = OneAndHalf + U2 + U2;
+ T = (OneAndHalf - U2) * Y1;
+ X = X - (Z + U2);
+ StickyBit = Y * Y1;
+ S = Z * Y2;
+ T = T - Y;
+ Y = (U2 - Y) + StickyBit;
+ Z = S - (Z + U2 + U2);
+ StickyBit = (Y2 + U2) * Y1;
+ Y1 = Y2 * Y1;
+ StickyBit = StickyBit - Y2;
+ Y1 = Y1 - Half;
+ if ((X == Zero) && (Y == Zero) && (Z == Zero) && (T == Zero)
+ && ( StickyBit == Zero) && (Y1 == Half)) {
+ RMult = Rounded;
+ printf("Multiplication appears to round correctly.\n");
+ }
+ else if ((X + U2 == Zero) && (Y < Zero) && (Z + U2 == Zero)
+ && (T < Zero) && (StickyBit + U2 == Zero)
+ && (Y1 < Half)) {
+ RMult = Chopped;
+ printf("Multiplication appears to chop.\n");
+ }
+ else printf("* is neither chopped nor correctly rounded.\n");
+ if ((RMult == Rounded) && (GMult == No)) notify("Multiplication");
+ }
+ else printf("* is neither chopped nor correctly rounded.\n");
+ /*=============================================*/
+ Milestone = 45;
+ /*=============================================*/
+ Y2 = One + U2;
+ Y1 = One - U2;
+ Z = OneAndHalf + U2 + U2;
+ X = Z / Y2;
+ T = OneAndHalf - U2 - U2;
+ Y = (T - U2) / Y1;
+ Z = (Z + U2) / Y2;
+ X = X - OneAndHalf;
+ Y = Y - T;
+ T = T / Y1;
+ Z = Z - (OneAndHalf + U2);
+ T = (U2 - OneAndHalf) + T;
+ if (! ((X > Zero) || (Y > Zero) || (Z > Zero) || (T > Zero))) {
+ X = OneAndHalf / Y2;
+ Y = OneAndHalf - U2;
+ Z = OneAndHalf + U2;
+ X = X - Y;
+ T = OneAndHalf / Y1;
+ Y = Y / Y1;
+ T = T - (Z + U2);
+ Y = Y - Z;
+ Z = Z / Y2;
+ Y1 = (Y2 + U2) / Y2;
+ Z = Z - OneAndHalf;
+ Y2 = Y1 - Y2;
+ Y1 = (F9 - U1) / F9;
+ if ((X == Zero) && (Y == Zero) && (Z == Zero) && (T == Zero)
+ && (Y2 == Zero) && (Y2 == Zero)
+ && (Y1 - Half == F9 - Half )) {
+ RDiv = Rounded;
+ printf("Division appears to round correctly.\n");
+ if (GDiv == No) notify("Division");
+ }
+ else if ((X < Zero) && (Y < Zero) && (Z < Zero) && (T < Zero)
+ && (Y2 < Zero) && (Y1 - Half < F9 - Half)) {
+ RDiv = Chopped;
+ printf("Division appears to chop.\n");
+ }
+ }
+ if (RDiv == Other) printf("/ is neither chopped nor correctly rounded.\n");
+ BInvrse = One / Radix;
+ TstCond (Failure, (BInvrse * Radix - Half == Half),
+ "Radix * ( 1 / Radix ) differs from 1");
+ /*=============================================*/
+ /*SPLIT
+ }
+#include "paranoia.h"
+void part4(VOID){
+*/
+ Milestone = 50;
+ /*=============================================*/
+ TstCond (Failure, ((F9 + U1) - Half == Half)
+ && ((BMinusU2 + U2 ) - One == Radix - One),
+ "Incomplete carry-propagation in Addition");
+ X = One - U1 * U1;
+ Y = One + U2 * (One - U2);
+ Z = F9 - Half;
+ X = (X - Half) - Z;
+ Y = Y - One;
+ if ((X == Zero) && (Y == Zero)) {
+ RAddSub = Chopped;
+ printf("Add/Subtract appears to be chopped.\n");
+ }
+ if (GAddSub == Yes) {
+ X = (Half + U2) * U2;
+ Y = (Half - U2) * U2;
+ X = One + X;
+ Y = One + Y;
+ X = (One + U2) - X;
+ Y = One - Y;
+ if ((X == Zero) && (Y == Zero)) {
+ X = (Half + U2) * U1;
+ Y = (Half - U2) * U1;
+ X = One - X;
+ Y = One - Y;
+ X = F9 - X;
+ Y = One - Y;
+ if ((X == Zero) && (Y == Zero)) {
+ RAddSub = Rounded;
+ printf("Addition/Subtraction appears to round correctly.\n");
+ if (GAddSub == No) notify("Add/Subtract");
+ }
+ else printf("Addition/Subtraction neither rounds nor chops.\n");
+ }
+ else printf("Addition/Subtraction neither rounds nor chops.\n");
+ }
+ else printf("Addition/Subtraction neither rounds nor chops.\n");
+ S = One;
+ X = One + Half * (One + Half);
+ Y = (One + U2) * Half;
+ Z = X - Y;
+ T = Y - X;
+ StickyBit = Z + T;
+ if (StickyBit != Zero) {
+ S = Zero;
+ BadCond(Flaw, "(X - Y) + (Y - X) is non zero!\n");
+ }
+ StickyBit = Zero;
+ if ((GMult == Yes) && (GDiv == Yes) && (GAddSub == Yes)
+ && (RMult == Rounded) && (RDiv == Rounded)
+ && (RAddSub == Rounded) && (FLOOR(RadixD2) == RadixD2)) {
+ printf("Checking for sticky bit.\n");
+ X = (Half + U1) * U2;
+ Y = Half * U2;
+ Z = One + Y;
+ T = One + X;
+ if ((Z - One <= Zero) && (T - One >= U2)) {
+ Z = T + Y;
+ Y = Z - X;
+ if ((Z - T >= U2) && (Y - T == Zero)) {
+ X = (Half + U1) * U1;
+ Y = Half * U1;
+ Z = One - Y;
+ T = One - X;
+ if ((Z - One == Zero) && (T - F9 == Zero)) {
+ Z = (Half - U1) * U1;
+ T = F9 - Z;
+ Q = F9 - Y;
+ if ((T - F9 == Zero) && (F9 - U1 - Q == Zero)) {
+ Z = (One + U2) * OneAndHalf;
+ T = (OneAndHalf + U2) - Z + U2;
+ X = One + Half / Radix;
+ Y = One + Radix * U2;
+ Z = X * Y;
+ if (T == Zero && X + Radix * U2 - Z == Zero) {
+ if (Radix != Two) {
+ X = Two + U2;
+ Y = X / Two;
+ if ((Y - One == Zero)) StickyBit = S;
+ }
+ else StickyBit = S;
+ }
+ }
+ }
+ }
+ }
+ }
+ if (StickyBit == One) printf("Sticky bit apparently used correctly.\n");
+ else printf("Sticky bit used incorrectly or not at all.\n");
+ TstCond (Flaw, !(GMult == No || GDiv == No || GAddSub == No ||
+ RMult == Other || RDiv == Other || RAddSub == Other),
+ "lack(s) of guard digits or failure(s) to correctly round or chop\n\
+(noted above) count as one flaw in the final tally below");
+ /*=============================================*/
+ Milestone = 60;
+ /*=============================================*/
+ printf("\n");
+ printf("Does Multiplication commute? ");
+ printf("Testing on %d random pairs.\n", NoTrials);
+ Random9 = SQRT(3.0);
+ Random1 = Third;
+ I = 1;
+ do {
+ X = Random();
+ Y = Random();
+ Z9 = Y * X;
+ Z = X * Y;
+ Z9 = Z - Z9;
+ I = I + 1;
+ } while ( ! ((I > NoTrials) || (Z9 != Zero)));
+ if (I == NoTrials) {
+ Random1 = One + Half / Three;
+ Random2 = (U2 + U1) + One;
+ Z = Random1 * Random2;
+ Y = Random2 * Random1;
+ Z9 = (One + Half / Three) * ((U2 + U1) + One) - (One + Half /
+ Three) * ((U2 + U1) + One);
+ }
+ if (! ((I == NoTrials) || (Z9 == Zero)))
+ BadCond(Defect, "X * Y == Y * X trial fails.\n");
+ else printf(" No failures found in %d integer pairs.\n", NoTrials);
+ /*=============================================*/
+ Milestone = 70;
+ /*=============================================*/
+ printf("\nRunning test of square root(x).\n");
+ TstCond (Failure, (Zero == SQRT(Zero))
+ && (- Zero == SQRT(- Zero))
+ && (One == SQRT(One)), "Square root of 0.0, -0.0 or 1.0 wrong");
+ MinSqEr = Zero;
+ MaxSqEr = Zero;
+ J = Zero;
+ X = Radix;
+ OneUlp = U2;
+ SqXMinX (Serious);
+ X = BInvrse;
+ OneUlp = BInvrse * U1;
+ SqXMinX (Serious);
+ X = U1;
+ OneUlp = U1 * U1;
+ SqXMinX (Serious);
+ if (J != Zero) Pause();
+ printf("Testing if sqrt(X * X) == X for %d Integers X.\n", NoTrials);
+ J = Zero;
+ X = Two;
+ Y = Radix;
+ if ((Radix != One)) do {
+ X = Y;
+ Y = Radix * Y;
+ } while ( ! ((Y - X >= NoTrials)));
+ OneUlp = X * U2;
+ I = 1;
+ while (I <= NoTrials) {
+ X = X + One;
+ SqXMinX (Defect);
+ if (J > Zero) break;
+ I = I + 1;
+ }
+ printf("Test for sqrt monotonicity.\n");
+ I = - 1;
+ X = BMinusU2;
+ Y = Radix;
+ Z = Radix + Radix * U2;
+ NotMonot = False;
+ Monot = False;
+ while ( ! (NotMonot || Monot)) {
+ I = I + 1;
+ X = SQRT(X);
+ Q = SQRT(Y);
+ Z = SQRT(Z);
+ if ((X > Q) || (Q > Z)) NotMonot = True;
+ else {
+ Q = FLOOR(Q + Half);
+ if (!(I > 0 || Radix == Q * Q)) Monot = True;
+ else if (I > 0) {
+ if (I > 1) Monot = True;
+ else {
+ Y = Y * BInvrse;
+ X = Y - U1;
+ Z = Y + U1;
+ }
+ }
+ else {
+ Y = Q;
+ X = Y - U2;
+ Z = Y + U2;
+ }
+ }
+ }
+ if (Monot) printf("sqrt has passed a test for Monotonicity.\n");
+ else {
+ BadCond(Defect, "");
+ printf("sqrt(X) is non-monotonic for X near %.7e .\n", Y);
+ }
+ /*=============================================*/
+ /*SPLIT
+ }
+#include "paranoia.h"
+void part5(VOID){
+*/
+ Milestone = 80;
+ /*=============================================*/
+ MinSqEr = MinSqEr + Half;
+ MaxSqEr = MaxSqEr - Half;
+ Y = (SQRT(One + U2) - One) / U2;
+ SqEr = (Y - One) + U2 / Eight;
+ if (SqEr > MaxSqEr) MaxSqEr = SqEr;
+ SqEr = Y + U2 / Eight;
+ if (SqEr < MinSqEr) MinSqEr = SqEr;
+ Y = ((SQRT(F9) - U2) - (One - U2)) / U1;
+ SqEr = Y + U1 / Eight;
+ if (SqEr > MaxSqEr) MaxSqEr = SqEr;
+ SqEr = (Y + One) + U1 / Eight;
+ if (SqEr < MinSqEr) MinSqEr = SqEr;
+ OneUlp = U2;
+ X = OneUlp;
+ for( Indx = 1; Indx <= 3; ++Indx) {
+ Y = SQRT((X + U1 + X) + F9);
+ Y = ((Y - U2) - ((One - U2) + X)) / OneUlp;
+ Z = ((U1 - X) + F9) * Half * X * X / OneUlp;
+ SqEr = (Y + Half) + Z;
+ if (SqEr < MinSqEr) MinSqEr = SqEr;
+ SqEr = (Y - Half) + Z;
+ if (SqEr > MaxSqEr) MaxSqEr = SqEr;
+ if (((Indx == 1) || (Indx == 3)))
+ X = OneUlp * Sign (X) * FLOOR(Eight / (Nine * SQRT(OneUlp)));
+ else {
+ OneUlp = U1;
+ X = - OneUlp;
+ }
+ }
+ /*=============================================*/
+ Milestone = 85;
+ /*=============================================*/
+ SqRWrng = False;
+ Anomaly = False;
+ RSqrt = Other; /* ~dgh */
+ if (Radix != One) {
+ printf("Testing whether sqrt is rounded or chopped.\n");
+ D = FLOOR(Half + POW(Radix, One + Precision - FLOOR(Precision)));
+ /* ... == Radix^(1 + fract) if (Precision == Integer + fract. */
+ X = D / Radix;
+ Y = D / A1;
+ if ((X != FLOOR(X)) || (Y != FLOOR(Y))) {
+ Anomaly = True;
+ }
+ else {
+ X = Zero;
+ Z2 = X;
+ Y = One;
+ Y2 = Y;
+ Z1 = Radix - One;
+ FourD = Four * D;
+ do {
+ if (Y2 > Z2) {
+ Q = Radix;
+ Y1 = Y;
+ do {
+ X1 = FABS(Q + FLOOR(Half - Q / Y1) * Y1);
+ Q = Y1;
+ Y1 = X1;
+ } while ( ! (X1 <= Zero));
+ if (Q <= One) {
+ Z2 = Y2;
+ Z = Y;
+ }
+ }
+ Y = Y + Two;
+ X = X + Eight;
+ Y2 = Y2 + X;
+ if (Y2 >= FourD) Y2 = Y2 - FourD;
+ } while ( ! (Y >= D));
+ X8 = FourD - Z2;
+ Q = (X8 + Z * Z) / FourD;
+ X8 = X8 / Eight;
+ if (Q != FLOOR(Q)) Anomaly = True;
+ else {
+ Break = False;
+ do {
+ X = Z1 * Z;
+ X = X - FLOOR(X / Radix) * Radix;
+ if (X == One)
+ Break = True;
+ else
+ Z1 = Z1 - One;
+ } while ( ! (Break || (Z1 <= Zero)));
+ if ((Z1 <= Zero) && (! Break)) Anomaly = True;
+ else {
+ if (Z1 > RadixD2) Z1 = Z1 - Radix;
+ do {
+ NewD();
+ } while ( ! (U2 * D >= F9));
+ if (D * Radix - D != W - D) Anomaly = True;
+ else {
+ Z2 = D;
+ I = 0;
+ Y = D + (One + Z) * Half;
+ X = D + Z + Q;
+ SR3750();
+ Y = D + (One - Z) * Half + D;
+ X = D - Z + D;
+ X = X + Q + X;
+ SR3750();
+ NewD();
+ if (D - Z2 != W - Z2) Anomaly = True;
+ else {
+ Y = (D - Z2) + (Z2 + (One - Z) * Half);
+ X = (D - Z2) + (Z2 - Z + Q);
+ SR3750();
+ Y = (One + Z) * Half;
+ X = Q;
+ SR3750();
+ if (I == 0) Anomaly = True;
+ }
+ }
+ }
+ }
+ }
+ if ((I == 0) || Anomaly) {
+ BadCond(Failure, "Anomalous arithmetic with Integer < ");
+ printf("Radix^Precision = %.7e\n", W);
+ printf(" fails test whether sqrt rounds or chops.\n");
+ SqRWrng = True;
+ }
+ }
+ if (! Anomaly) {
+ if (! ((MinSqEr < Zero) || (MaxSqEr > Zero))) {
+ RSqrt = Rounded;
+ printf("Square root appears to be correctly rounded.\n");
+ }
+ else {
+ if ((MaxSqEr + U2 > U2 - Half) || (MinSqEr > Half)
+ || (MinSqEr + Radix < Half)) SqRWrng = True;
+ else {
+ RSqrt = Chopped;
+ printf("Square root appears to be chopped.\n");
+ }
+ }
+ }
+ if (SqRWrng) {
+ printf("Square root is neither chopped nor correctly rounded.\n");
+ printf("Observed errors run from %.7e ", MinSqEr - Half);
+ printf("to %.7e ulps.\n", Half + MaxSqEr);
+ TstCond (Serious, MaxSqEr - MinSqEr < Radix * Radix,
+ "sqrt gets too many last digits wrong");
+ }
+ /*=============================================*/
+ Milestone = 90;
+ /*=============================================*/
+ Pause();
+ printf("Testing powers Z^i for small Integers Z and i.\n");
+ N = 0;
+ /* ... test powers of zero. */
+ I = 0;
+ Z = -Zero;
+ M = 3;
+ Break = False;
+ do {
+ X = One;
+ SR3980();
+ if (I <= 10) {
+ I = 1023;
+ SR3980();
+ }
+ if (Z == MinusOne) Break = True;
+ else {
+ Z = MinusOne;
+ /* .. if(-1)^N is invalid, replace MinusOne by One. */
+ I = - 4;
+ }
+ } while ( ! Break);
+ PrintIfNPositive();
+ N1 = N;
+ N = 0;
+ Z = A1;
+ M = (int)FLOOR(Two * LOG(W) / LOG(A1));
+ Break = False;
+ do {
+ X = Z;
+ I = 1;
+ SR3980();
+ if (Z == AInvrse) Break = True;
+ else Z = AInvrse;
+ } while ( ! (Break));
+ /*=============================================*/
+ Milestone = 100;
+ /*=============================================*/
+ /* Powers of Radix have been tested, */
+ /* next try a few primes */
+ M = NoTrials;
+ Z = Three;
+ do {
+ X = Z;
+ I = 1;
+ SR3980();
+ do {
+ Z = Z + Two;
+ } while ( Three * FLOOR(Z / Three) == Z );
+ } while ( Z < Eight * Three );
+ if (N > 0) {
+ printf("Errors like this may invalidate financial calculations\n");
+ printf("\tinvolving interest rates.\n");
+ }
+ PrintIfNPositive();
+ N += N1;
+ if (N == 0) printf("... no discrepancies found.\n");
+ if (N > 0) Pause();
+ else printf("\n");
+ /*=============================================*/
+ /*SPLIT
+ }
+#include "paranoia.h"
+void part6(VOID){
+*/
+ Milestone = 110;
+ /*=============================================*/
+ printf("Seeking Underflow thresholds UfThold and E0.\n");
+ D = U1;
+ if (Precision != FLOOR(Precision)) {
+ D = BInvrse;
+ X = Precision;
+ do {
+ D = D * BInvrse;
+ X = X - One;
+ } while ( X > Zero);
+ }
+ Y = One;
+ Z = D;
+ /* ... D is power of 1/Radix < 1. */
+ do {
+ C = Y;
+ Y = Z;
+ Z = Y * Y;
+ } while ((Y > Z) && (Z + Z > Z));
+ Y = C;
+ Z = Y * D;
+ do {
+ C = Y;
+ Y = Z;
+ Z = Y * D;
+ } while ((Y > Z) && (Z + Z > Z));
+ if (Radix < Two) HInvrse = Two;
+ else HInvrse = Radix;
+ H = One / HInvrse;
+ /* ... 1/HInvrse == H == Min(1/Radix, 1/2) */
+ CInvrse = One / C;
+ E0 = C;
+ Z = E0 * H;
+ /* ...1/Radix^(BIG Integer) << 1 << CInvrse == 1/C */
+ do {
+ Y = E0;
+ E0 = Z;
+ Z = E0 * H;
+ } while ((E0 > Z) && (Z + Z > Z));
+ UfThold = E0;
+ E1 = Zero;
+ Q = Zero;
+ E9 = U2;
+ S = One + E9;
+ D = C * S;
+ if (D <= C) {
+ E9 = Radix * U2;
+ S = One + E9;
+ D = C * S;
+ if (D <= C) {
+ BadCond(Failure, "multiplication gets too many last digits wrong.\n");
+ Underflow = E0;
+ Y1 = Zero;
+ PseudoZero = Z;
+ Pause();
+ }
+ }
+ else {
+ Underflow = D;
+ PseudoZero = Underflow * H;
+ UfThold = Zero;
+ do {
+ Y1 = Underflow;
+ Underflow = PseudoZero;
+ if (E1 + E1 <= E1) {
+ Y2 = Underflow * HInvrse;
+ E1 = FABS(Y1 - Y2);
+ Q = Y1;
+ if ((UfThold == Zero) && (Y1 != Y2)) UfThold = Y1;
+ }
+ PseudoZero = PseudoZero * H;
+ } while ((Underflow > PseudoZero)
+ && (PseudoZero + PseudoZero > PseudoZero));
+ }
+ /* Comment line 4530 .. 4560 */
+ if (PseudoZero != Zero) {
+ printf("\n");
+ Z = PseudoZero;
+ /* ... Test PseudoZero for "phoney- zero" violates */
+ /* ... PseudoZero < Underflow or PseudoZero < PseudoZero + PseudoZero
+ ... */
+ if (PseudoZero <= Zero) {
+ BadCond(Failure, "Positive expressions can underflow to an\n");
+ printf("allegedly negative value\n");
+ printf("PseudoZero that prints out as: %g .\n", PseudoZero);
+ X = - PseudoZero;
+ if (X <= Zero) {
+ printf("But -PseudoZero, which should be\n");
+ printf("positive, isn't; it prints out as %g .\n", X);
+ }
+ }
+ else {
+ BadCond(Flaw, "Underflow can stick at an allegedly positive\n");
+ printf("value PseudoZero that prints out as %g .\n", PseudoZero);
+ }
+ TstPtUf();
+ }
+ /*=============================================*/
+ Milestone = 120;
+ /*=============================================*/
+ if (CInvrse * Y > CInvrse * Y1) {
+ S = H * S;
+ E0 = Underflow;
+ }
+ if (! ((E1 == Zero) || (E1 == E0))) {
+ BadCond(Defect, "");
+ if (E1 < E0) {
+ printf("Products underflow at a higher");
+ printf(" threshold than differences.\n");
+ if (PseudoZero == Zero)
+ E0 = E1;
+ }
+ else {
+ printf("Difference underflows at a higher");
+ printf(" threshold than products.\n");
+ }
+ }
+ printf("Smallest strictly positive number found is E0 = %g .\n", E0);
+ Z = E0;
+ TstPtUf();
+ Underflow = E0;
+ if (N == 1) Underflow = Y;
+ I = 4;
+ if (E1 == Zero) I = 3;
+ if (UfThold == Zero) I = I - 2;
+ UfNGrad = True;
+ switch (I) {
+ case 1:
+ UfThold = Underflow;
+ if ((CInvrse * Q) != ((CInvrse * Y) * S)) {
+ UfThold = Y;
+ BadCond(Failure, "Either accuracy deteriorates as numbers\n");
+ printf("approach a threshold = %.17e\n", UfThold);;
+ printf(" coming down from %.17e\n", C);
+ printf(" or else multiplication gets too many last digits wrong.\n");
+ }
+ Pause();
+ break;
+
+ case 2:
+ BadCond(Failure, "Underflow confuses Comparison, which alleges that\n");
+ printf("Q == Y while denying that |Q - Y| == 0; these values\n");
+ printf("print out as Q = %.17e, Y = %.17e .\n", Q, Y2);
+ printf ("|Q - Y| = %.17e .\n" , FABS(Q - Y2));
+ UfThold = Q;
+ break;
+
+ case 3:
+ X = X;
+ break;
+
+ case 4:
+ if ((Q == UfThold) && (E1 == E0)
+ && (FABS( UfThold - E1 / E9) <= E1)) {
+ UfNGrad = False;
+ printf("Underflow is gradual; it incurs Absolute Error =\n");
+ printf("(roundoff in UfThold) < E0.\n");
+ Y = E0 * CInvrse;
+ Y = Y * (OneAndHalf + U2);
+ X = CInvrse * (One + U2);
+ Y = Y / X;
+ IEEE = (Y == E0);
+ }
+ }
+ if (UfNGrad) {
+ printf("\n");
+ sigsave = sigfpe;
+ if (setjmp(ovfl_buf)) {
+ printf("Underflow / UfThold failed!\n");
+ R = H + H;
+ }
+ else R = SQRT(Underflow / UfThold);
+ sigsave = 0;
+ if (R <= H) {
+ Z = R * UfThold;
+ X = Z * (One + R * H * (One + H));
+ }
+ else {
+ Z = UfThold;
+ X = Z * (One + H * H * (One + H));
+ }
+ if (! ((X == Z) || (X - Z != Zero))) {
+ BadCond(Flaw, "");
+ printf("X = %.17e\n\tis not equal to Z = %.17e .\n", X, Z);
+ Z9 = X - Z;
+ printf("yet X - Z yields %.17e .\n", Z9);
+ printf(" Should this NOT signal Underflow, ");
+ printf("this is a SERIOUS DEFECT\nthat causes ");
+ printf("confusion when innocent statements like\n");;
+ printf(" if (X == Z) ... else");
+ printf(" ... (f(X) - f(Z)) / (X - Z) ...\n");
+ printf("encounter Division by Zero although actually\n");
+ sigsave = sigfpe;
+ if (setjmp(ovfl_buf)) printf("X / Z fails!\n");
+ else printf("X / Z = 1 + %g .\n", (X / Z - Half) - Half);
+ sigsave = 0;
+ }
+ }
+ printf("The Underflow threshold is %.17e, %s\n", UfThold,
+ " below which");
+ printf("calculation may suffer larger Relative error than ");
+ printf("merely roundoff.\n");
+ Y2 = U1 * U1;
+ Y = Y2 * Y2;
+ Y2 = Y * U1;
+ if (Y2 <= UfThold) {
+ if (Y > E0) {
+ BadCond(Defect, "");
+ I = 5;
+ }
+ else {
+ BadCond(Serious, "");
+ I = 4;
+ }
+ printf("Range is too narrow; U1^%d Underflows.\n", I);
+ }
+ /*=============================================*/
+ /*SPLIT
+ }
+#include "paranoia.h"
+void part7(VOID){
+*/
+ Milestone = 130;
+ /*=============================================*/
+ Y = - FLOOR(Half - TwoForty * LOG(UfThold) / LOG(HInvrse)) / TwoForty;
+ Y2 = Y + Y;
+ printf("Since underflow occurs below the threshold\n");
+ printf("UfThold = (%.17e) ^ (%.17e)\nonly underflow ", HInvrse, Y);
+ printf("should afflict the expression\n\t(%.17e) ^ (%.17e);\n",
+ HInvrse, Y2);
+ printf("actually calculating yields:");
+ if (setjmp(ovfl_buf)) {
+ sigsave = 0;
+ BadCond(Serious, "trap on underflow.\n");
+ }
+ else {
+ sigsave = sigfpe;
+ V9 = POW(HInvrse, Y2);
+ sigsave = 0;
+ printf(" %.17e .\n", V9);
+ if (! ((V9 >= Zero) && (V9 <= (Radix + Radix + E9) * UfThold))) {
+ BadCond(Serious, "this is not between 0 and underflow\n");
+ printf(" threshold = %.17e .\n", UfThold);
+ }
+ else if (! (V9 > UfThold * (One + E9)))
+ printf("This computed value is O.K.\n");
+ else {
+ BadCond(Defect, "this is not between 0 and underflow\n");
+ printf(" threshold = %.17e .\n", UfThold);
+ }
+ }
+ /*=============================================*/
+ Milestone = 140;
+ /*=============================================*/
+ printf("\n");
+ /* ...calculate Exp2 == exp(2) == 7.389056099... */
+ X = Zero;
+ I = 2;
+ Y = Two * Three;
+ Q = Zero;
+ N = 0;
+ do {
+ Z = X;
+ I = I + 1;
+ Y = Y / (I + I);
+ R = Y + Q;
+ X = Z + R;
+ Q = (Z - X) + R;
+ } while(X > Z);
+ Z = (OneAndHalf + One / Eight) + X / (OneAndHalf * ThirtyTwo);
+ X = Z * Z;
+ Exp2 = X * X;
+ X = F9;
+ Y = X - U1;
+ printf("Testing X^((X + 1) / (X - 1)) vs. exp(2) = %.17e as X -> 1.\n",
+ Exp2);
+ for(I = 1;;) {
+ Z = X - BInvrse;
+ Z = (X + One) / (Z - (One - BInvrse));
+ Q = POW(X, Z) - Exp2;
+ if (FABS(Q) > TwoForty * U2) {
+ N = 1;
+ V9 = (X - BInvrse) - (One - BInvrse);
+ BadCond(Defect, "Calculated");
+ printf(" %.17e for\n", POW(X,Z));
+ printf("\t(1 + (%.17e) ^ (%.17e);\n", V9, Z);
+ printf("\tdiffers from correct value by %.17e .\n", Q);
+ printf("\tThis much error may spoil financial\n");
+ printf("\tcalculations involving tiny interest rates.\n");
+ break;
+ }
+ else {
+ Z = (Y - X) * Two + Y;
+ X = Y;
+ Y = Z;
+ Z = One + (X - F9)*(X - F9);
+ if (Z > One && I < NoTrials) I++;
+ else {
+ if (X > One) {
+ if (N == 0)
+ printf("Accuracy seems adequate.\n");
+ break;
+ }
+ else {
+ X = One + U2;
+ Y = U2 + U2;
+ Y += X;
+ I = 1;
+ }
+ }
+ }
+ }
+ /*=============================================*/
+ Milestone = 150;
+ /*=============================================*/
+ printf("Testing powers Z^Q at four nearly extreme values.\n");
+ N = 0;
+ Z = A1;
+ Q = FLOOR(Half - LOG(C) / LOG(A1));
+ Break = False;
+ do {
+ X = CInvrse;
+ Y = POW(Z, Q);
+ IsYeqX();
+ Q = - Q;
+ X = C;
+ Y = POW(Z, Q);
+ IsYeqX();
+ if (Z < One) Break = True;
+ else Z = AInvrse;
+ } while ( ! (Break));
+ PrintIfNPositive();
+ if (N == 0) printf(" ... no discrepancies found.\n");
+ printf("\n");
+
+ /*=============================================*/
+ Milestone = 160;
+ /*=============================================*/
+ Pause();
+ printf("Searching for Overflow threshold:\n");
+ printf("This may generate an error.\n");
+ Y = - CInvrse;
+ V9 = HInvrse * Y;
+ sigsave = sigfpe;
+ if (setjmp(ovfl_buf)) { I = 0; V9 = Y; goto overflow; }
+ do {
+ V = Y;
+ Y = V9;
+ V9 = HInvrse * Y;
+ } while(V9 < Y);
+ I = 1;
+overflow:
+ sigsave = 0;
+ Z = V9;
+ printf("Can `Z = -Y' overflow?\n");
+ printf("Trying it on Y = %.17e .\n", Y);
+ V9 = - Y;
+ V0 = V9;
+ if (V - Y == V + V0) printf("Seems O.K.\n");
+ else {
+ printf("finds a ");
+ BadCond(Flaw, "-(-Y) differs from Y.\n");
+ }
+ if (Z != Y) {
+ BadCond(Serious, "");
+ printf("overflow past %.17e\n\tshrinks to %.17e .\n", Y, Z);
+ }
+ if (I) {
+ Y = V * (HInvrse * U2 - HInvrse);
+ Z = Y + ((One - HInvrse) * U2) * V;
+ if (Z < V0) Y = Z;
+ if (Y < V0) V = Y;
+ if (V0 - V < V0) V = V0;
+ }
+ else {
+ V = Y * (HInvrse * U2 - HInvrse);
+ V = V + ((One - HInvrse) * U2) * Y;
+ }
+ printf("Overflow threshold is V = %.17e .\n", V);
+ if (I) printf("Overflow saturates at V0 = %.17e .\n", V0);
+ else printf("There is no saturation value because \
+the system traps on overflow.\n");
+ V9 = V * One;
+ printf("No Overflow should be signaled for V * 1 = %.17e\n", V9);
+ V9 = V / One;
+ printf(" nor for V / 1 = %.17e .\n", V9);
+ printf("Any overflow signal separating this * from the one\n");
+ printf("above is a DEFECT.\n");
+ /*=============================================*/
+ Milestone = 170;
+ /*=============================================*/
+ if (!(-V < V && -V0 < V0 && -UfThold < V && UfThold < V)) {
+ BadCond(Failure, "Comparisons involving ");
+ printf("+-%g, +-%g\nand +-%g are confused by Overflow.",
+ V, V0, UfThold);
+ }
+ /*=============================================*/
+ Milestone = 175;
+ /*=============================================*/
+ printf("\n");
+ for(Indx = 1; Indx <= 3; ++Indx) {
+ switch (Indx) {
+ case 1: Z = UfThold; break;
+ case 2: Z = E0; break;
+ case 3: Z = PseudoZero; break;
+ }
+ if (Z != Zero) {
+ V9 = SQRT(Z);
+ Y = V9 * V9;
+ if (Y / (One - Radix * E9) < Z
+ || Y > (One + Radix * E9) * Z) { /* dgh: + E9 --> * E9 */
+ if (V9 > U1) BadCond(Serious, "");
+ else BadCond(Defect, "");
+ printf("Comparison alleges that what prints as Z = %.17e\n", Z);
+ printf(" is too far from sqrt(Z) ^ 2 = %.17e .\n", Y);
+ }
+ }
+ }
+ /*=============================================*/
+ Milestone = 180;
+ /*=============================================*/
+ for(Indx = 1; Indx <= 2; ++Indx) {
+ if (Indx == 1) Z = V;
+ else Z = V0;
+ V9 = SQRT(Z);
+ X = (One - Radix * E9) * V9;
+ V9 = V9 * X;
+ if (((V9 < (One - Two * Radix * E9) * Z) || (V9 > Z))) {
+ Y = V9;
+ if (X < W) BadCond(Serious, "");
+ else BadCond(Defect, "");
+ printf("Comparison alleges that Z = %17e\n", Z);
+ printf(" is too far from sqrt(Z) ^ 2 (%.17e) .\n", Y);
+ }
+ }
+ /*=============================================*/
+ /*SPLIT
+ }
+#include "paranoia.h"
+int part8(VOID){
+*/
+ Milestone = 190;
+ /*=============================================*/
+ Pause();
+ X = UfThold * V;
+ Y = Radix * Radix;
+ if (X*Y < One || X > Y) {
+ if (X * Y < U1 || X > Y/U1) BadCond(Defect, "Badly");
+ else BadCond(Flaw, "");
+
+ printf(" unbalanced range; UfThold * V = %.17e\n\t%s\n",
+ X, "is too far from 1.\n");
+ }
+ /*=============================================*/
+ Milestone = 200;
+ /*=============================================*/
+ for (Indx = 1; Indx <= 5; ++Indx) {
+ X = F9;
+ switch (Indx) {
+ case 2: X = One + U2; break;
+ case 3: X = V; break;
+ case 4: X = UfThold; break;
+ case 5: X = Radix;
+ }
+ Y = X;
+ sigsave = sigfpe;
+ if (setjmp(ovfl_buf))
+ printf(" X / X traps when X = %g\n", X);
+ else {
+ V9 = (Y / X - Half) - Half;
+ if (V9 == Zero) continue;
+ if (V9 == - U1 && Indx < 5) BadCond(Flaw, "");
+ else BadCond(Serious, "");
+ printf(" X / X differs from 1 when X = %.17e\n", X);
+ printf(" instead, X / X - 1/2 - 1/2 = %.17e .\n", V9);
+ }
+ sigsave = 0;
+ }
+ /*=============================================*/
+ Milestone = 210;
+ /*=============================================*/
+ MyZero = Zero;
+ printf("\n");
+ printf("What message and/or values does Division by Zero produce?\n") ;
+#ifndef NOPAUSE
+ printf("This can interupt your program. You can ");
+ printf("skip this part if you wish.\n");
+ printf("Do you wish to compute 1 / 0? ");
+ fflush(stdout);
+ read (KEYBOARD, ch, 8);
+ if ((ch[0] == 'Y') || (ch[0] == 'y')) {
+#endif
+ sigsave = sigfpe;
+ printf(" Trying to compute 1 / 0 produces ...");
+ if (!setjmp(ovfl_buf)) printf(" %.7e .\n", One / MyZero);
+ sigsave = 0;
+#ifndef NOPAUSE
+ }
+ else printf("O.K.\n");
+ printf("\nDo you wish to compute 0 / 0? ");
+ fflush(stdout);
+ read (KEYBOARD, ch, 80);
+ if ((ch[0] == 'Y') || (ch[0] == 'y')) {
+#endif
+ sigsave = sigfpe;
+ printf("\n Trying to compute 0 / 0 produces ...");
+ if (!setjmp(ovfl_buf)) printf(" %.7e .\n", Zero / MyZero);
+ sigsave = 0;
+#ifndef NOPAUSE
+ }
+ else printf("O.K.\n");
+#endif
+ /*=============================================*/
+ Milestone = 220;
+ /*=============================================*/
+ Pause();
+ printf("\n");
+ {
+ static char *msg[] = {
+ "FAILUREs encountered =",
+ "SERIOUS DEFECTs discovered =",
+ "DEFECTs discovered =",
+ "FLAWs discovered =" };
+ int i;
+ for(i = 0; i < 4; i++) if (ErrCnt[i])
+ printf("The number of %-29s %d.\n",
+ msg[i], ErrCnt[i]);
+ }
+ printf("\n");
+ if ((ErrCnt[Failure] + ErrCnt[Serious] + ErrCnt[Defect]
+ + ErrCnt[Flaw]) > 0) {
+ if ((ErrCnt[Failure] + ErrCnt[Serious] + ErrCnt[
+ Defect] == 0) && (ErrCnt[Flaw] > 0)) {
+ printf("The arithmetic diagnosed seems ");
+ printf("Satisfactory though flawed.\n");
+ }
+ if ((ErrCnt[Failure] + ErrCnt[Serious] == 0)
+ && ( ErrCnt[Defect] > 0)) {
+ printf("The arithmetic diagnosed may be Acceptable\n");
+ printf("despite inconvenient Defects.\n");
+ }
+ if ((ErrCnt[Failure] + ErrCnt[Serious]) > 0) {
+ printf("The arithmetic diagnosed has ");
+ printf("unacceptable Serious Defects.\n");
+ }
+ if (ErrCnt[Failure] > 0) {
+ printf("Potentially fatal FAILURE may have spoiled this");
+ printf(" program's subsequent diagnoses.\n");
+ }
+ }
+ else {
+ printf("No failures, defects nor flaws have been discovered.\n");
+ if (! ((RMult == Rounded) && (RDiv == Rounded)
+ && (RAddSub == Rounded) && (RSqrt == Rounded)))
+ printf("The arithmetic diagnosed seems Satisfactory.\n");
+ else {
+ if (StickyBit >= One &&
+ (Radix - Two) * (Radix - Nine - One) == Zero) {
+ printf("Rounding appears to conform to ");
+ printf("the proposed IEEE standard P");
+ if ((Radix == Two) &&
+ ((Precision - Four * Three * Two) *
+ ( Precision - TwentySeven -
+ TwentySeven + One) == Zero))
+ printf("754");
+ else printf("854");
+ if (IEEE) printf(".\n");
+ else {
+ printf(",\nexcept for possibly Double Rounding");
+ printf(" during Gradual Underflow.\n");
+ }
+ }
+ printf("The arithmetic diagnosed appears to be Excellent!\n");
+ }
+ }
+ if (fpecount)
+ printf("\nA total of %d floating point exceptions were registered.\n",
+ fpecount);
+ printf("END OF TEST.\n");
+ return 0;
+ }
+
+/*SPLIT subs.c
+#include "paranoia.h"
+*/
+
+ FLOAT
+Sign (FP X)
+#ifdef KR_headers
+FLOAT X;
+#endif
+{ return X >= 0. ? 1.0 : -1.0; }
+
+ void
+Pause(VOID)
+{
+#ifndef NOPAUSE
+ char ch[8];
+
+ printf("\nTo continue, press RETURN");
+ fflush(stdout);
+ read(KEYBOARD, ch, 8);
+#endif
+ printf("\nDiagnosis resumes after milestone Number %d", Milestone);
+ printf(" Page: %d\n\n", PageNo);
+ ++Milestone;
+ ++PageNo;
+ }
+
+ void
+TstCond (INT K, INT Valid, CHARP T)
+#ifdef KR_headers
+int K, Valid;
+char *T;
+#endif
+{ if (! Valid) { BadCond(K,T); printf(".\n"); } }
+
+ void
+BadCond(INT K, CHARP T)
+#ifdef KR_headers
+int K;
+char *T;
+#endif
+{
+ static char *msg[] = { "FAILURE", "SERIOUS DEFECT", "DEFECT", "FLAW" };
+
+ ErrCnt [K] = ErrCnt [K] + 1;
+ printf("%s: %s", msg[K], T);
+ }
+
+
+ FLOAT
+Random(VOID)
+/* Random computes
+ X = (Random1 + Random9)^5
+ Random1 = X - FLOOR(X) + 0.000005 * X;
+ and returns the new value of Random1
+*/
+{
+ FLOAT X, Y;
+
+ X = Random1 + Random9;
+ Y = X * X;
+ Y = Y * Y;
+ X = X * Y;
+ Y = X - FLOOR(X);
+ Random1 = Y + X * 0.000005;
+ return(Random1);
+ }
+
+ void
+SqXMinX (INT ErrKind)
+#ifdef KR_headers
+int ErrKind;
+#endif
+{
+ FLOAT XA, XB;
+
+ XB = X * BInvrse;
+ XA = X - XB;
+ SqEr = ((SQRT(X * X) - XB) - XA) / OneUlp;
+ if (SqEr != Zero) {
+ if (SqEr < MinSqEr) MinSqEr = SqEr;
+ if (SqEr > MaxSqEr) MaxSqEr = SqEr;
+ J = J + 1.0;
+ BadCond(ErrKind, "\n");
+ printf("sqrt( %.17e) - %.17e = %.17e\n", X * X, X, OneUlp * SqEr);
+ printf("\tinstead of correct value 0 .\n");
+ }
+ }
+
+ void
+NewD(VOID)
+{
+ X = Z1 * Q;
+ X = FLOOR(Half - X / Radix) * Radix + X;
+ Q = (Q - X * Z) / Radix + X * X * (D / Radix);
+ Z = Z - Two * X * D;
+ if (Z <= Zero) {
+ Z = - Z;
+ Z1 = - Z1;
+ }
+ D = Radix * D;
+ }
+
+ void
+SR3750(VOID)
+{
+ if (! ((X - Radix < Z2 - Radix) || (X - Z2 > W - Z2))) {
+ I = I + 1;
+ X2 = SQRT(X * D);
+ Y2 = (X2 - Z2) - (Y - Z2);
+ X2 = X8 / (Y - Half);
+ X2 = X2 - Half * X2 * X2;
+ SqEr = (Y2 + Half) + (Half - X2);
+ if (SqEr < MinSqEr) MinSqEr = SqEr;
+ SqEr = Y2 - X2;
+ if (SqEr > MaxSqEr) MaxSqEr = SqEr;
+ }
+ }
+
+ void
+IsYeqX(VOID)
+{
+ if (Y != X) {
+ if (N <= 0) {
+ if (Z == Zero && Q <= Zero)
+ printf("WARNING: computing\n");
+ else BadCond(Defect, "computing\n");
+ printf("\t(%.17e) ^ (%.17e)\n", Z, Q);
+ printf("\tyielded %.17e;\n", Y);
+ printf("\twhich compared unequal to correct %.17e ;\n",
+ X);
+ printf("\t\tthey differ by %.17e .\n", Y - X);
+ }
+ N = N + 1; /* ... count discrepancies. */
+ }
+ }
+
+ void
+SR3980(VOID)
+{
+ do {
+ Q = (FLOAT) I;
+ Y = POW(Z, Q);
+ IsYeqX();
+ if (++I > M) break;
+ X = Z * X;
+ } while ( X < W );
+ }
+
+ void
+PrintIfNPositive(VOID)
+{
+ if (N > 0) printf("Similar discrepancies have occurred %d times.\n", N);
+ }
+
+ void
+TstPtUf(VOID)
+{
+ N = 0;
+ if (Z != Zero) {
+ printf("Since comparison denies Z = 0, evaluating ");
+ printf("(Z + Z) / Z should be safe.\n");
+ sigsave = sigfpe;
+ if (setjmp(ovfl_buf)) goto very_serious;
+ Q9 = (Z + Z) / Z;
+ printf("What the machine gets for (Z + Z) / Z is %.17e .\n",
+ Q9);
+ if (FABS(Q9 - Two) < Radix * U2) {
+ printf("This is O.K., provided Over/Underflow");
+ printf(" has NOT just been signaled.\n");
+ }
+ else {
+ if ((Q9 < One) || (Q9 > Two)) {
+very_serious:
+ N = 1;
+ ErrCnt [Serious] = ErrCnt [Serious] + 1;
+ printf("This is a VERY SERIOUS DEFECT!\n");
+ }
+ else {
+ N = 1;
+ ErrCnt [Defect] = ErrCnt [Defect] + 1;
+ printf("This is a DEFECT!\n");
+ }
+ }
+ sigsave = 0;
+ V9 = Z * One;
+ Random1 = V9;
+ V9 = One * Z;
+ Random2 = V9;
+ V9 = Z / One;
+ if ((Z == Random1) && (Z == Random2) && (Z == V9)) {
+ if (N > 0) Pause();
+ }
+ else {
+ N = 1;
+ BadCond(Defect, "What prints as Z = ");
+ printf("%.17e\n\tcompares different from ", Z);
+ if (Z != Random1) printf("Z * 1 = %.17e ", Random1);
+ if (! ((Z == Random2)
+ || (Random2 == Random1)))
+ printf("1 * Z == %g\n", Random2);
+ if (! (Z == V9)) printf("Z / 1 = %.17e\n", V9);
+ if (Random2 != Random1) {
+ ErrCnt [Defect] = ErrCnt [Defect] + 1;
+ BadCond(Defect, "Multiplication does not commute!\n");
+ printf("\tComparison alleges that 1 * Z = %.17e\n",
+ Random2);
+ printf("\tdiffers from Z * 1 = %.17e\n", Random1);
+ }
+ Pause();
+ }
+ }
+ }
+
+ void
+notify(CHARP s)
+#ifdef KR_headers
+ char *s;
+#endif
+{
+ printf("%s test appears to be inconsistent...\n", s);
+ printf(" PLEASE NOTIFY KARPINKSI!\n");
+ }
+
+/*SPLIT msgs.c
+#include "paranoia.h"
+*/
+
+ void
+msglist(CHARPP s)
+#ifdef KR_headers
+char **s;
+#endif
+{ while(*s) printf("%s\n", *s++); }
+
+ void
+Instructions(VOID)
+{
+ static char *instr[] = {
+ "Lest this program stop prematurely, i.e. before displaying\n",
+ " `END OF TEST',\n",
+ "try to persuade the computer NOT to terminate execution when an",
+ "error like Over/Underflow or Division by Zero occurs, but rather",
+ "to persevere with a surrogate value after, perhaps, displaying some",
+ "warning. If persuasion avails naught, don't despair but run this",
+ "program anyway to see how many milestones it passes, and then",
+ "amend it to make further progress.\n",
+ "Answer questions with Y, y, N or n (unless otherwise indicated).\n",
+ 0};
+
+ msglist(instr);
+ }
+
+ void
+Heading(VOID)
+{
+ static char *head[] = {
+ "Users are invited to help debug and augment this program so it will",
+ "cope with unanticipated and newly uncovered arithmetic pathologies.\n",
+ "Please send suggestions and interesting results to",
+ "\tRichard Karpinski",
+ "\tComputer Center U-76",
+ "\tUniversity of California",
+ "\tSan Francisco, CA 94143-0704, USA\n",
+ "In doing so, please include the following information:",
+#ifdef Single
+ "\tPrecision:\tsingle;",
+#else
+ "\tPrecision:\tdouble;",
+#endif
+ "\tVersion:\t10 February 1989;",
+ "\tComputer:\n",
+ "\tCompiler:\n",
+ "\tOptimization level:\n",
+ "\tOther relevant compiler options:",
+ 0};
+
+ msglist(head);
+ }
+
+ void
+Characteristics(VOID)
+{
+ static char *chars[] = {
+ "Running this program should reveal these characteristics:",
+ " Radix = 1, 2, 4, 8, 10, 16, 100, 256 ...",
+ " Precision = number of significant digits carried.",
+ " U2 = Radix/Radix^Precision = One Ulp",
+ "\t(OneUlpnit in the Last Place) of 1.000xxx .",
+ " U1 = 1/Radix^Precision = One Ulp of numbers a little less than 1.0 .",
+ " Adequacy of guard digits for Mult., Div. and Subt.",
+ " Whether arithmetic is chopped, correctly rounded, or something else",
+ "\tfor Mult., Div., Add/Subt. and Sqrt.",
+ " Whether a Sticky Bit used correctly for rounding.",
+ " UnderflowThreshold = an underflow threshold.",
+ " E0 and PseudoZero tell whether underflow is abrupt, gradual, or fuzzy.",
+ " V = an overflow threshold, roughly.",
+ " V0 tells, roughly, whether Infinity is represented.",
+ " Comparisions are checked for consistency with subtraction",
+ "\tand for contamination with pseudo-zeros.",
+ " Sqrt is tested. Y^X is not tested.",
+ " Extra-precise subexpressions are revealed but NOT YET tested.",
+ " Decimal-Binary conversion is NOT YET tested for accuracy.",
+ 0};
+
+ msglist(chars);
+ }
+
+ void
+History(VOID)
+{ /* History */
+ /* Converted from Brian Wichmann's Pascal version to C by Thos Sumner,
+ with further massaging by David M. Gay. */
+
+ static char *hist[] = {
+ "The program attempts to discriminate among",
+ " FLAWs, like lack of a sticky bit,",
+ " Serious DEFECTs, like lack of a guard digit, and",
+ " FAILUREs, like 2+2 == 5 .",
+ "Failures may confound subsequent diagnoses.\n",
+ "The diagnostic capabilities of this program go beyond an earlier",
+ "program called `MACHAR', which can be found at the end of the",
+ "book `Software Manual for the Elementary Functions' (1980) by",
+ "W. J. Cody and W. Waite. Although both programs try to discover",
+ "the Radix, Precision and range (over/underflow thresholds)",
+ "of the arithmetic, this program tries to cope with a wider variety",
+ "of pathologies, and to say how well the arithmetic is implemented.",
+ "\nThe program is based upon a conventional radix representation for",
+ "floating-point numbers, but also allows logarithmic encoding",
+ "as used by certain early WANG machines.\n",
+ "BASIC version of this program (C) 1983 by Prof. W. M. Kahan;",
+ "see source comments for more history.",
+ 0};
+
+ msglist(hist);
+ }
--- /dev/null
+#include <string.h>
+
+char *a = "bar";
+
+volatile char buf[] = "Hello World";
+
+int _start() {
+ return strlen("foo");
+}
--- /dev/null
+package tests;
+
+import org.xwt.mips.Runtime;
+import org.xwt.mips.Interpreter;
+
+class SpeedTest {
+ private static long start,end;
+ private static long now() { return System.currentTimeMillis(); }
+ private static void start() { start = now(); }
+ private static void end() { end = now(); }
+ private static float diff() { return ((float)(end-start))/1000; }
+
+ public static void main(String[] args) throws Exception {
+ float d;
+
+ if(args.length < 2) { System.err.println("Usage: SpeedTest {classname|mips binary} number_of_runs args"); System.exit(1); }
+ String className = args[0];
+ int runs = Integer.parseInt(args[1]);
+ if(runs < 5) throw new Error("Runs must be >= 5");
+ String[] appArgs = new String[args.length-1];
+ appArgs[0] = className;
+ for(int i=2;i<args.length;i++) appArgs[i-1] = args[i];
+
+ Class c = null;
+ boolean binary = className.endsWith(".mips");
+ if(!binary) {
+ start();
+ c = Class.forName(className);
+ end();
+ d = diff();
+ System.out.println("Class.forName() took " + d + "sec");
+
+ start();
+ c.newInstance();
+ end();
+ d = diff();
+ System.out.println("c.newInstance() took " + d + "sec");
+
+ if(!Runtime.class.isAssignableFrom(c)) { System.err.println(className + " isn't a MIPS compiled class"); System.exit(1); }
+ } else {
+ throw new Error("Interpreter not supported in speedtest");
+ }
+
+ float times[] = new float[runs];
+
+ for(int i=0;i<runs;i++) {
+ //Runtime runtime = binary ? new Interpreter(className) : (Runtime) c.newInstance();
+ Runtime runtime = (Runtime) c.newInstance();
+ System.gc();
+ start();
+ int status = runtime.run(appArgs);
+ if(status != 0) { System.err.println(className + " failed with exit status: " + status); System.exit(1); }
+ end();
+ times[i] = diff();
+ System.err.println("Run " + (i+1) + ": " + times[i] + " sec");
+ }
+
+ java.util.Arrays.sort(times);
+
+ System.out.println("Best: " + times[0]);
+ System.out.println("Worst: " + times[times.length-1]);
+ float sum = 0.0f;
+ for(int i=2;i<times.length-2;i++)
+ sum += times[i];
+ float avg = sum / (times.length-4);
+ System.out.println("Avg of middle " + (times.length-4) + ": " + avg);
+ }
+}
--- /dev/null
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/fcntl.h>
+#include <sys/unistd.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <sys/signal.h>
+#include <time.h>
+#include <dirent.h>
+#include <wchar.h>
+#include <math.h>
+
+char *user_info[1024];
+
+extern void _pause();
+extern int _call_java(int a, int b, int c, int d);
+
+void suckram();
+
+int main(int argc, char **argv) {
+ int i,n,fd;
+ time_t now;
+ DIR *dir;
+ struct dirent *dent;
+ char buf[1024];
+ unsigned char ubuf[1024];
+ unsigned short sbuf[1024];
+ char *s;
+
+ printf("Entered main()\n");
+
+ if(argc > 1 && strcmp(argv[1],"calltest")==0) {
+ printf("pausing for call test\n");
+ _pause();
+ printf("unpaused from call test\n");
+
+ for(i=1;i<=3;i++) {
+ char *s = (char*)_call_java(i,0,0,0);
+ printf("_call_java(%d,0,0,0) = \"%s\" (%d chars)\n",i,s,strlen(s));
+ free(s);
+ }
+ fd = _call_java(4,0,0,0);
+ if(fd != -1) {
+ FILE *fp;
+ fprintf(stderr,"fd: %i\n",fd);
+ fp = fdopen(fd,"w");
+ if(fp != NULL) {
+ fprintf(fp,"It worked! fp is %p - Hello, Java!\n",fp);
+ fclose(fp);
+ } else {
+ fprintf(stderr,"fdopen failed\n");
+ close(fd);
+ }
+ } else {
+ fprintf(stderr,"fd == -1\n");
+ }
+
+ printf("In main() in MIPS\n");
+ _call_java(5,0,0,0);
+ printf("Back in main() in MIPS\n");
+ } else if(argc > 2 && strcmp(argv[1],"fdtest")==0) {
+ printf("opening %s\n",argv[2]);
+ fd = open(argv[2],O_RDONLY);
+ if(fd < 0) { perror("open"); exit(1); }
+
+ printf("reading up to 64 bytes\n");
+ n = read(fd,buf,64);
+ if(n < 0) {perror("read"); exit(1); }
+ printf("read %d bytes\n",n);
+ for(i=0;i<n;i++) if(buf[i]=='\n' || buf[i]=='\r') { buf[i] = '\0'; break; }
+ printf("Read \"%s\"...\n",n == 0 ? NULL : buf);
+
+ printf("seeking back to pos 4...\n");
+ if(lseek(fd,4,SEEK_SET) < 0) { perror("lseek"); exit(1); }
+
+ printf("reading up to 64 bytes\n");
+ n = read(fd,buf,64);
+ if(n < 0) {perror("read"); exit(1); }
+ printf("read %d bytes\n",n);
+ for(i=0;i<n;i++) if(buf[i]=='\n' || buf[i]=='\r') { buf[i] = '\0'; break; }
+ printf("Read \"%s\"...\n",n == 0 ? NULL : buf);
+
+ printf("reading up to 64 bytes\n");
+ n = read(fd,buf,64);
+ if(n < 0) {perror("read"); exit(1); }
+ printf("read %d bytes\n",n);
+ for(i=0;i<n;i++) if(buf[i]=='\n' || buf[i]=='\r') { buf[i] = '\0'; break; }
+ printf("Read \"%s\"...\n",n == 0 ? NULL : buf);
+ } else if(argc > 1 && strcmp(argv[1],"fptest")==0) {
+ double d = 0.0;
+ while(d != 10.0) {
+ printf("d: %f\n",d);
+ d += 2.5;
+ }
+ } else if(argc > 1 && strcmp(argv[1],"nullderef")==0) {
+ volatile int *mem = 0;
+ *mem = 1;
+ } else {
+ printf("%d\n", 0xffffff);
+ printf("%u\n", 0xffffffU);
+ printf("%li\n",0xffffffL);
+ printf("%lu\n",0xffffffUL);
+
+
+ for(i=0;i<argc;i++)
+ printf("argv[%d] = \"%s\"\n",i,argv[i]);
+ for(i=0;user_info[i];i++)
+ printf("user_info[%d] = \"%s\"\n",i,user_info[i]);
+
+ printf("getenv(\"USER\") = \"%s\"\n",getenv("USER"));
+ printf("getenv(\"HOME\") = \"%s\"\n",getenv("HOME"));
+ printf("getenv(\"TZ\") = \"%s\"\n",getenv("TZ"));
+
+ time(&now);
+ tzset();
+ printf("%s %s %d\n",tzname[0],tzname[1],(int)_timezone);
+
+ printf("Running ctime\n");
+ s = ctime(&now);
+ printf("ctime returned: %p\n",s);
+ printf("Current time: %s",s);
+
+ printf("Trying to open /nonexistent\n");
+ fd = open("/nonexistent",O_RDONLY);
+ if(fd < 0) perror("open");
+ else close(fd);
+
+ printf("Tyring to mkdir .mkdirtest\n");
+ if(mkdir(".mkdirtest",0700) < 0) perror("mkdir");
+
+ printf("Trying to opendir /\n");
+ dir = opendir("/");
+ if(dir) {
+ while((dent=readdir(dir))!=NULL)
+ printf("\t[%s] %lu\n",dent->d_name,dent->d_ino);
+ closedir(dir);
+ } else {
+ perror("opendir");
+ }
+
+
+#if 0
+ printf("Sleeping...\n");
+ sleep(1);
+ printf("Done\n");
+#endif
+
+ fd = open("test.txt",O_RDONLY);
+ if(fd != -1) {
+ printf("Opened test.txt\n");
+ n = read(fd,sbuf,sizeof(sbuf));
+ printf("n: %d\n",n);
+ if(n < 0) perror("read");
+ ubuf[n] = '\0';
+ printf("buf: %s\n",buf);
+ for(i=0;i<n/2;i++) {
+ printf("Char %d: [%x]\n",i,sbuf[i]);
+ }
+ }
+
+ {
+ static double f = 1.574;
+ int n;
+ printf("%e\n",f);
+ f += 20.001;
+ f *= -2.0;
+ n = (int) f;
+ printf("%el\n",f);
+ printf("%d\n",n);
+ printf("%e\n",f);
+ printf("%e\n",fabs(f));
+ }
+ }
+
+ printf("exiting\n");
+ return 0;
+}
+
+void suckram() {
+ int total = 0;
+ fprintf(stderr,"Eating up all available memory\n");
+ while(malloc(1024*1024) != NULL) total ++;
+ fprintf(stderr,"Ate up %d megs\n",total);
+}
+
+__attribute__((constructor)) static void my_ctor() { printf("Constructor!\n"); }
+__attribute__((destructor)) static void my_dtor() { printf("Destructor!\n"); }
+
+int callme(int a1,int a2, int a3, int a4, int a5, int a6) __attribute__((section(".text")));
+int callme(int a1,int a2, int a3, int a4, int a5, int a6) {
+ printf("You said: %d %d %d %d %d %d\n",a1,a2,a3,a4,a5,a6);
+ return a1+a2+a3+a4+a5+a6;
+}
+
+void echo(const char *string, int count) __attribute__((section(".text")));
+void echo(const char *string, int count) {
+ int i;
+ for(i=0;i<count;i++)
+ printf("%d: %s\n",i,string);
+}
+
+void backinmips() __attribute__((section(".text")));
+void backinmips() {
+ fprintf(stderr,"In backinmips() in mips\n");
+}
--- /dev/null
+#!/bin/sh -e
+
+[ -z "$JAVA" ] && JAVA=java
+
+CLASSPATH="$(pwd)/build"; export CLASSPATH
+if [ "$1" != "running_from_make" ]; then
+ echo "Please don't run this scipt directly. Use make check" >&2
+ exit 1
+fi
+
+INT="$2"
+
+cd tmp
+
+if [ ! -e .skipmspack ]; then
+
+mkdir -p mspack
+cd mspack
+rm -f *.TTT *.inf FONTINST.EXE *.DLL *.TXT;
+for f in \
+ andale32.exe arial32.exe arialb32.exe comic32.exe courie32.exe georgi32.exe \
+ impact32.exe times32.exe trebuc32.exe verdan32.exe webdin32.exe; \
+do
+ [ -e "$f" ] || wget "http://dist.xwt.org/corefonts/$f" || rm -f "$f"
+ [ -e "$f" ] || exit 1
+done
+
+echo "Extracting MS Core Fonts using MSPackBench..."
+$JAVA tests.MSPackBench *32.exe
+
+cat <<EOF | md5sum -cv
+663974c9fe3ba55b228724fd4d4e445f AndaleMo.TTF
+3e7043e8125f1c8998347310f2c315bc AriBlk.TTF
+f11c0317db527bdd80fa0afa04703441 Arial.TTF
+34cd8fd9e4fae9f075d4c9a2c971d065 Arialbd.TTF
+a2b3bcdb39097b6aed17a766652b92b2 Arialbi.TTF
+25633f73d92a0646e733e50cf2cc3b07 Ariali.TTF
+a50f9c96a76356e3d01013e0b042989f Comic.TTF
+81d64ec3675c4adc14e9ad2c5c8103a7 Comicbd.TTF
+f4b306eed95aa7d274840533be635532 Georgia.TTF
+c61b355a5811e56ed3d7cea5d67c900e Georgiab.TTF
+1e4e5d1975bdf4a5c648afbf8872fa13 Georgiai.TTF
+e5d52bbfff45e1044381bacb7fc8e300 Georgiaz.TTF
+8fc622c3a2e2d992ec059cca61e3dfc0 Impact.TTF
+4f97f4d6ba74767259ccfb242ce0e3f7 Times.TTF
+ed6e29caf3843142d739232aa8642158 Timesbd.TTF
+6d2bd425ff00a79dd02e4c95f689861b Timesbi.TTF
+957dd4f17296522dead302ab4fcdfa8d Timesi.TTF
+055460df9ab3c8aadd3330bd30805f11 Trebucbd.ttf
+3ba52ab1fa0cd726e7868e9c6673902c Verdana.TTF
+a2b4dc9afc18e76cfcaa0071fa7cd0da Verdanab.TTF
+24b3a293c865a2c265280f017fb24ba5 Verdanai.TTF
+f7310c29df0070530c48a47f2dca9014 Verdanaz.TTF
+1a56b45a66b07b4c576d5ead048ed992 Webdings.TTF
+20f23317e90516cbb7d38bd53b3d1c5b cour.ttf
+7d94f95bf383769b51379d095139f2d7 courbd.ttf
+da414c01f951b020bb09a4165d3fb5fa courbi.ttf
+167e27add66e9e8eb0d28a1235dd3bda couri.ttf
+70e7be8567bc05f771b59abd9d696407 trebuc.ttf
+fb5d68cb58c6ad7e88249d65f6900740 trebucbi.ttf
+8f308fe77b584e20b246aa1f8403d2e9 trebucit.ttf
+663974c9fe3ba55b228724fd4d4e445f AndaleMo.TTF
+3e7043e8125f1c8998347310f2c315bc AriBlk.TTF
+f11c0317db527bdd80fa0afa04703441 Arial.TTF
+34cd8fd9e4fae9f075d4c9a2c971d065 Arialbd.TTF
+a2b3bcdb39097b6aed17a766652b92b2 Arialbi.TTF
+25633f73d92a0646e733e50cf2cc3b07 Ariali.TTF
+a50f9c96a76356e3d01013e0b042989f Comic.TTF
+81d64ec3675c4adc14e9ad2c5c8103a7 Comicbd.TTF
+f4b306eed95aa7d274840533be635532 Georgia.TTF
+c61b355a5811e56ed3d7cea5d67c900e Georgiab.TTF
+1e4e5d1975bdf4a5c648afbf8872fa13 Georgiai.TTF
+e5d52bbfff45e1044381bacb7fc8e300 Georgiaz.TTF
+8fc622c3a2e2d992ec059cca61e3dfc0 Impact.TTF
+4f97f4d6ba74767259ccfb242ce0e3f7 Times.TTF
+ed6e29caf3843142d739232aa8642158 Timesbd.TTF
+6d2bd425ff00a79dd02e4c95f689861b Timesbi.TTF
+957dd4f17296522dead302ab4fcdfa8d Timesi.TTF
+055460df9ab3c8aadd3330bd30805f11 Trebucbd.ttf
+3ba52ab1fa0cd726e7868e9c6673902c Verdana.TTF
+a2b4dc9afc18e76cfcaa0071fa7cd0da Verdanab.TTF
+24b3a293c865a2c265280f017fb24ba5 Verdanai.TTF
+f7310c29df0070530c48a47f2dca9014 Verdanaz.TTF
+1a56b45a66b07b4c576d5ead048ed992 Webdings.TTF
+20f23317e90516cbb7d38bd53b3d1c5b cour.ttf
+7d94f95bf383769b51379d095139f2d7 courbd.ttf
+da414c01f951b020bb09a4165d3fb5fa courbi.ttf
+167e27add66e9e8eb0d28a1235dd3bda couri.ttf
+70e7be8567bc05f771b59abd9d696407 trebuc.ttf
+fb5d68cb58c6ad7e88249d65f6900740 trebucbi.ttf
+8f308fe77b584e20b246aa1f8403d2e9 trebucit.ttf
+EOF
+
+echo "Core Fonts extracted successfully!"
+
+cd ..
+
+fi
+
+if [ ! -e .skipdjpeg ]; then
+echo "Decoding some jpegs with DJpeg..."
+
+rm -f *.tga
+
+[ -e banner.jpg ] || wget http://www.xwt.org/image/banner.jpg
+[ -e banner.jpg ] || exit 1
+
+$JAVA tests.DJpeg -targa -outfile thebride_1280.tga thebride_1280.jpg
+echo "e90f6b915aee2fc0d2eb9fc60ace6203 thebride_1280.tga" | md5sum -cv
+
+$JAVA tests.DJpeg -targa -outfile banner.tga banner.jpg
+echo "4c7cc29ae2094191a9b0308cf9a04fbd banner.tga" | md5sum -cv
+
+echo "JPEGs decoded successfully!"
+
+fi
+
+if [ ! -e .skipfreetype ]; then
+
+cd mspack
+
+echo "Rendering some fonts with FTBench..."
+if ! [ -e Verdana.TTF -a -e Arial.TTF -a -e Comic.TTF ]; then
+ echo "Can't find the corefonts - did the mspack test complete?"
+ exit 1
+fi
+
+rm -f *.render
+
+for f in Verdana.TTF Arial.TTF Comic.TTF; do
+ $JAVA tests.FTBench "$f" "$f".render
+done
+
+cat <<EOF|md5sum -cv
+e33b9db5a413af214b2524265af18026 Arial.TTF.render
+61dee4f697a61ebc1b47decbed04b2da Comic.TTF.render
+d5a6d39a63e49c597ed860913e27d2bb Verdana.TTF.render
+EOF
+
+echo "Fonts rendered successfully"
+cd ..
+
+fi
+
+if [ ! -e .skipgc ]; then
+
+echo "Running gctest from the boehm-gc library..."
+$JAVA tests.GCTest
+
+fi
+
+if [ ! -e .busybox -a -e ../build/tests/BusyBox.class ]; then
+ echo "Running busybox's md5sum command on some ttfs"
+ $JAVA tests.BusyBox ash -c "md5sum mspack/*.ttf > md5.1"
+ md5sum mspack/*.ttf > md5.2
+ cmp md5.1 md5.2 && echo "The BusyBox md5sum command and sh work properly!"
+fi
+
+cat <<EOF
+* * * * * * * * * * * * * * * * * * * * *
+* All tests completed with no failures *
+* * * * * * * * * * * * * * * * * * * * *
+
+EOF
--- /dev/null
+# Inspired by XWT's Makefile.upstream
+
+version_gcc = 3.3.3
+url_gcc-core = http://mirrors.rcn.net/pub/sourceware/gcc/releases/gcc-$(version_gcc)/gcc-core-$(version_gcc).tar.gz
+url_gcc-c++ = http://mirrors.rcn.net/pub/sourceware/gcc/releases/gcc-$(version_gcc)/gcc-g++-$(version_gcc).tar.gz
+patches_gcc = gcc-fixes.patch gcc-fdata-sections-bss.patch
+configure_gcc = --target=mips-unknown-elf --disable-threads --with-gnu-ld --with-gnu-as --with-newlib=yes --enable-sjlj-exceptions --enable-languages="c"
+configure_gcc_step2 = $(configure_gcc) --enable-languages="c,c++"
+
+version_binutils = 2.14
+url_binutils = ftp://ftp.gnu.org/gnu/binutils/binutils-$(version_binutils).tar.gz
+patches_binutils = binutils-no64.patch
+configure_binutils = --target=mips-unknown-elf
+
+version_newlib = 1.11.0
+url_newlib = http://mirrors.rcn.net/pub/sourceware/newlib/newlib-$(version_newlib).tar.gz
+patches_newlib = newlib-mips.patch newlib-tzset.patch newlib-malloc.patch
+configure_newlib = --enable-multilib --target=mips-unknown-elf
+
+url_openbsdglob = http://www.brianweb.net/xwt/openbsdglob.tar.gz
+url_regex = ftp://ftp.zoo.toronto.edu/pub/regex.shar
+
+version_bcel = 5.1
+url_bcel = http://mirrors.mix5.com/apache/jakarta/bcel/binaries/bcel-$(version_bcel).tar.gz
+
+.SECONDARY: # This is broken in gmake < 3.79.1
+
+upstream = $(shell pwd)
+root = $(shell dirname "`pwd`")
+usr = $(upstream)/install
+
+PATH := $(usr)/bin:$(PATH)
+export PATH
+
+# Solaris' patch doesn't work, use gnu patch on solaris
+PATCH = $(shell test `uname` = SunOS && echo gpatch || echo patch)
+
+tasks/full_toolchain: tasks/build_binutils tasks/build_gcc_step2 tasks/build_libc
+ touch $@
+
+tasks/build_gcc: tasks/build_binutils
+tasks/build_newlib: tasks/build_gcc
+
+tasks/build_libc: tasks/build_newlib tasks/build_regex tasks/build_openbsdglob
+ rm -f $(usr)/mips-unknown-elf/lib/crt0.o
+ ln -s $(root)/build/org/xwt/mips/crt0.o $(usr)/mips-unknown-elf/lib/crt0.o
+ echo '#include <unistd.h>' > $(usr)/mips-unknown-elf/include/getopt.h
+ touch $@
+
+clean_%:
+ rm -rf "build/$(*)"*
+ rm -f "tasks/build_$*" "tasks/patch_$*" "tasks/extract_$*"
+
+tasks/download_%:
+ if [ -z "$(url_$*)" ]; then echo "No url for $*" >&2; false; fi
+ mkdir -p download
+ cd download && wget --passive-ftp -N $(url_$*)
+ touch $@
+
+tasks/download_gcc: tasks/download_gcc-core tasks/download_gcc-c++
+ touch $@
+
+tasks/extract_%: tasks/download_%
+ mkdir -p build
+ cd build && \
+ gzip -dc ../download/$*-$(version_$*).tar.gz | tar xf - && \
+ rm -f $* && \
+ ln -s $*-$(version_$*) $*
+ touch $@
+
+tasks/extract_gcc: tasks/download_gcc
+ mkdir -p build
+ cd build && gzip -dc ../download/gcc-core-$(version_gcc).tar.gz | tar xf -
+ cd build && gzip -dc ../download/gcc-g++-$(version_gcc).tar.gz | tar xf -
+ touch $@
+
+tasks/patch_%: tasks/extract_%
+ cd build/$*-$(version_$*) && \
+ for p in $(patches_$*) end; do \
+ [ "$$p" = "end" ] || $(PATCH) -p0 < ../../patches/$$p || exit 1; \
+ done
+ touch $@
+
+tasks/build_%: tasks/patch_%
+ mkdir -p $(usr)
+ @[ "$*" = "newlib" ] && rm -f $(usr)/mips-unknown-elf/lib/crt0.o || true
+ mkdir -p build/$*-obj && cd build/$*-obj && \
+ ../$*-$(version_$*)/configure --prefix=$(usr) $(configure_$*) && \
+ $(MAKE) TARGET_CFLAGS="$(MIPS_CFLAGS)" && \
+ $(MAKE) install
+ touch $@
+
+tasks/build_gcc_step2: tasks/patch_gcc tasks/build_libc
+ mkdir -p $(usr)
+ mkdir -p build/gcc-obj && cd build/gcc-obj && \
+ ../gcc-$(version_gcc)/configure --prefix=$(usr) $(configure_gcc_step2) && \
+ $(MAKE) TARGET_CFLAGS="$(MIPS_CFLAGS)" && \
+ $(MAKE) install
+ touch $@
+
+tasks/build_openbsdglob: tasks/download_openbsdglob tasks/build_newlib
+ @mkdir -p $(usr)/mips-unknown-elf/{include,lib}
+ cd build && gzip -dc ../download/openbsdglob.tar.gz | tar xf -
+ cd build/openbsdglob && \
+ mips-unknown-elf-gcc '-Dissetugid()=0' -DARG_MAX=65536 $(MIPS_CFLAGS) -I. -c -o glob.o glob.c && \
+ mips-unknown-elf-gcc -O2 -Wall -Werror -I. -c -o fnmatch.o fnmatch.c && \
+ mips-unknown-elf-ar cr libglob.a *.o && \
+ mips-unknown-elf-ranlib libglob.a && \
+ cp *.h $(usr)/mips-unknown-elf/include && \
+ cp *.a $(usr)/mips-unknown-elf/lib
+ touch $@
+
+tasks/build_regex: tasks/download_regex tasks/build_newlib
+ @mkdir -p $(usr)/mips-unknown-elf/{include,lib}
+ mkdir -p build/regex build/regex/fake
+ cd build/regex && \
+ sh ../../download/regex.shar && \
+ make CC=mips-unknown-elf-gcc CFLAGS="-I. $(MIPS_CFLAGS)" regcomp.o regexec.o regerror.o regfree.o && \
+ mips-unknown-elf-ar cr libregex.a regcomp.o regexec.o regerror.o regfree.o && \
+ mips-unknown-elf-ranlib libregex.a && \
+ cp regex.h $(usr)/mips-unknown-elf/include && \
+ cp libregex.a $(usr)/mips-unknown-elf/lib
+ touch $@
+
+
+#
+# Tests
+# These are simply here for convenience. They aren't required
+# to build or run mips2java
+#
+
+tasks/build_freetype: tasks/full_toolchain
+tasks/build_libjpeg: tasks/full_toolchain
+tasks/build_boehmgc: tasks/full_toolchain
+tasks/build_libmspack: tasks/full_toolchain
+tasks/build_freetype: tasks/full_toolchain
+
+version_libjpeg = 6b
+url_libjpeg = http://www.ijg.org/files/jpegsrc.v$(version_libjpeg).tar.gz
+
+version_libmspack = 20030726
+url_libmspack = http://www.kyz.uklinux.net/downloads/libmspack-$(version_libmspack).tar.gz
+patches_libmspack = libmspack.patch
+
+version_freetype = 2.1.4
+url_freetype = http://umn.dl.sourceforge.net/sourceforge/freetype/freetype-$(version_freetype).tar.gz
+patches_freetype = freetype.patch ft-nostdio.patch
+
+version_boehmgc = 6.3alpha2
+url_boehmgc = http://www.hpl.hp.com/personal/Hans_Boehm/gc/gc_source/gc$(version_boehmgc).tar.gz
+patches_boehmgc = boehm-gc.patch
+
+version_busybox = 0.60.5
+url_busybox = http://busybox.net/downloads/busybox-$(version_busybox).tar.gz
+patches_busybox = busybox.patch
+
+
+tasks/extract_libjpeg: tasks/download_libjpeg
+ mkdir -p build
+ cd build && \
+ gzip -dc ../download/jpegsrc.v$(version_libjpeg).tar.gz | tar xf - && \
+ mv jpeg-$(version_libjpeg) libjpeg-$(version_libjpeg) && \
+ rm -f libjpeg && \
+ ln -s libjpeg-$(version_libjpeg) libjpeg
+ touch $@
+
+tasks/build_libjpeg: tasks/patch_libjpeg
+ cd build/libjpeg-$(version_libjpeg) && \
+ ./configure && \
+ make CC="mips-unknown-elf-gcc" \
+ AR="mips-unknown-elf-ar rc" \
+ AR2="mips-unknown-elf-ranlib" \
+ CFLAGS="$(MIPS_CFLAGS)" \
+ LDFLAGS="$(MIPS_LDFLAGS)"
+ touch $@
+
+tasks/extract_libmspack: tasks/download_libmspack
+ mkdir -p build
+ cd build && \
+ gzip -dc ../download/libmspack-$(version_libmspack).tar.gz | tar xf - && \
+ mv libmspack libmspack-$(version_libmspack) && \
+ rm -f libmspack && \
+ ln -s libmspack-$(version_libmspack) libmspack
+ touch $@
+
+tasks/build_libmspack: tasks/patch_libmspack tasks/full_toolchain
+ cd build/libmspack-$(version_libmspack)/mspack && \
+ make CC="mips-unknown-elf-gcc" \
+ AR="mips-unknown-elf-ar" \
+ RANLIB="mips-unknown-elf-ranlib" \
+ OPTIM="$(MIPS_CFLAGS)"
+ touch $@
+
+tasks/build_freetype: tasks/patch_freetype tasks/full_toolchain
+ cd build/freetype-$(version_freetype) && \
+ $(MAKE) setup ansi && \
+ $(MAKE) CC="mips-unknown-elf-gcc" \
+ CFLAGS="-c $(MIPS_CFLAGS)" \
+ AR="mips-unknown-elf-ar" \
+ RANLIB="mips-unknown-elf-ranlib" && \
+ mips-unknown-elf-ranlib objs/libfreetype.a
+ touch $@
+
+tasks/extract_boehmgc: tasks/download_boehmgc
+ mkdir -p build
+ cd build && \
+ rm -rf gc$(version_boehmgc) && \
+ gzip -dc ../download/gc$(version_boehmgc).tar.gz | tar xf - && \
+ rm -f boehmgc boehmgc-$(version_boehmgc) && \
+ ln -s gc$(version_boehmgc) boehmgc && \
+ ln -s gc$(version_boehmgc) boehmgc-$(version_boehmgc)
+ touch $@
+
+tasks/build_boehmgc: tasks/patch_boehmgc tasks/full_toolchain
+ cd build/gc$(version_boehmgc) && \
+ CC="mips-unknown-elf-gcc" CFLAGS="$(MIPS_CFLAGS)" LDFLAGS="$(MIPS_LDFLAGS)" \
+ ./configure --host=mips-unknown-elf --disable-shared --disable-threads && \
+ make && \
+ make gctest
+ touch $@
+
+tasks/build_busybox: tasks/patch_busybox tasks/full_toolchain
+ cd build && \
+ rm -f busybox && \
+ ln -s busybox-$(version_busybox) busybox
+ cd build/busybox && $(MAKE) SHELL=/bin/bash LDFLAGS="$(MIPS_LDFLAGS)" CFLAGS_EXTRA="$(MIPS_CFLAGS) -g"
+ touch $@
--- /dev/null
+diff -ru ../binutils-2.14/bfd/config.bfd ./bfd/config.bfd
+--- ../binutils-2.14/bfd/config.bfd Mon Jun 2 16:35:20 2003
++++ ./bfd/config.bfd Mon Sep 1 01:06:32 2003
+@@ -777,6 +777,10 @@
+ targ_defvec=bfd_elf32_littlemips_vec
+ targ_selvecs="bfd_elf32_bigmips_vec bfd_elf64_bigmips_vec bfd_elf64_littlemips_vec"
+ ;;
++ mips*-unknown-elf*)
++ targ_defvec=bfd_elf32_bigmips_vec
++ targ_selvecs=bfd_elf32_littlemips_vec
++ ;;
+ mips*-*-elf* | mips*-*-rtems* | mips*-*-vxworks*)
+ targ_defvec=bfd_elf32_bigmips_vec
+ targ_selvecs="bfd_elf32_littlemips_vec bfd_elf64_bigmips_vec bfd_elf64_littlemips_vec"
+Only in ./bfd: config.bfd.old
+Only in ./bfd: config.bfd~
+diff -ru ../binutils-2.14/ld/configure.tgt ./ld/configure.tgt
+--- ../binutils-2.14/ld/configure.tgt Thu Jun 12 10:25:52 2003
++++ ./ld/configure.tgt Mon Sep 1 01:07:42 2003
+@@ -405,6 +405,7 @@
+ mips*vr5000el-*-elf*) targ_emul=elf32l4300 ;;
+ mips*vr5000-*-elf*) targ_emul=elf32b4300 ;;
+ mips*el-*-elf*) targ_emul=elf32elmip ;;
++mips*-unknown-elf*) targ_emul=elf32ebmip ;;
+ mips*-*-elf*) targ_emul=elf32ebmip ;;
+ mips*el-*-rtems*) targ_emul=elf32elmip ;;
+ mips*-*-rtems*) targ_emul=elf32ebmip ;;
+Only in ./ld: configure.tgt.old
+Only in ./ld: configure.tgt~
--- /dev/null
+diff -ruN ../gc6.3alpha2/configure ./configure
+--- ../gc6.3alpha2/configure Wed Oct 1 19:34:32 2003
++++ ./configure Wed Nov 19 04:17:25 2003
+@@ -1,7 +1,7 @@
+ #! /bin/sh
+ # From configure.in Revision: 1.2 .
+ # Guess values for system-dependent variables and create Makefiles.
+-# Generated by GNU Autoconf 2.53 for gc 6.3alpha2.
++# Generated by GNU Autoconf 2.57 for gc 6.3alpha2.
+ #
+ # Report bugs to <Hans.Boehm@hp.com>.
+ #
+@@ -9,173 +9,6 @@
+ # Free Software Foundation, Inc.
+ # This configure script is free software; the Free Software Foundation
+ # gives unlimited permission to copy, distribute and modify it.
+-
+-# Find the correct PATH separator. Usually this is `:', but
+-# DJGPP uses `;' like DOS.
+-if test "X${PATH_SEPARATOR+set}" != Xset; then
+- UNAME=${UNAME-`uname 2>/dev/null`}
+- case X$UNAME in
+- *-DOS) lt_cv_sys_path_separator=';' ;;
+- *) lt_cv_sys_path_separator=':' ;;
+- esac
+- PATH_SEPARATOR=$lt_cv_sys_path_separator
+-fi
+-
+-
+-# Check that we are running under the correct shell.
+-SHELL=${CONFIG_SHELL-/bin/sh}
+-
+-case X$ECHO in
+-X*--fallback-echo)
+- # Remove one level of quotation (which was required for Make).
+- ECHO=`echo "$ECHO" | sed 's,\\\\\$\\$0,'$0','`
+- ;;
+-esac
+-
+-echo=${ECHO-echo}
+-if test "X$1" = X--no-reexec; then
+- # Discard the --no-reexec flag, and continue.
+- shift
+-elif test "X$1" = X--fallback-echo; then
+- # Avoid inline document here, it may be left over
+- :
+-elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then
+- # Yippee, $echo works!
+- :
+-else
+- # Restart under the correct shell.
+- exec $SHELL "$0" --no-reexec ${1+"$@"}
+-fi
+-
+-if test "X$1" = X--fallback-echo; then
+- # used as fallback echo
+- shift
+- cat <<EOF
+-
+-EOF
+- exit 0
+-fi
+-
+-# The HP-UX ksh and POSIX shell print the target directory to stdout
+-# if CDPATH is set.
+-if test "X${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi
+-
+-if test -z "$ECHO"; then
+-if test "X${echo_test_string+set}" != Xset; then
+-# find a string as large as possible, as long as the shell can cope with it
+- for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do
+- # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
+- if (echo_test_string="`eval $cmd`") 2>/dev/null &&
+- echo_test_string="`eval $cmd`" &&
+- (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null
+- then
+- break
+- fi
+- done
+-fi
+-
+-if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
+- echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` &&
+- test "X$echo_testing_string" = "X$echo_test_string"; then
+- :
+-else
+- # The Solaris, AIX, and Digital Unix default echo programs unquote
+- # backslashes. This makes it impossible to quote backslashes using
+- # echo "$something" | sed 's/\\/\\\\/g'
+- #
+- # So, first we look for a working echo in the user's PATH.
+-
+- IFS="${IFS= }"; save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+- for dir in $PATH /usr/ucb; do
+- if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
+- test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
+- echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` &&
+- test "X$echo_testing_string" = "X$echo_test_string"; then
+- echo="$dir/echo"
+- break
+- fi
+- done
+- IFS="$save_ifs"
+-
+- if test "X$echo" = Xecho; then
+- # We didn't find a better echo, so look for alternatives.
+- if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' &&
+- echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` &&
+- test "X$echo_testing_string" = "X$echo_test_string"; then
+- # This shell has a builtin print -r that does the trick.
+- echo='print -r'
+- elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) &&
+- test "X$CONFIG_SHELL" != X/bin/ksh; then
+- # If we have ksh, try running configure again with it.
+- ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
+- export ORIGINAL_CONFIG_SHELL
+- CONFIG_SHELL=/bin/ksh
+- export CONFIG_SHELL
+- exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"}
+- else
+- # Try using printf.
+- echo='printf %s\n'
+- if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
+- echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` &&
+- test "X$echo_testing_string" = "X$echo_test_string"; then
+- # Cool, printf works
+- :
+- elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` &&
+- test "X$echo_testing_string" = 'X\t' &&
+- echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+- test "X$echo_testing_string" = "X$echo_test_string"; then
+- CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL
+- export CONFIG_SHELL
+- SHELL="$CONFIG_SHELL"
+- export SHELL
+- echo="$CONFIG_SHELL $0 --fallback-echo"
+- elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` &&
+- test "X$echo_testing_string" = 'X\t' &&
+- echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+- test "X$echo_testing_string" = "X$echo_test_string"; then
+- echo="$CONFIG_SHELL $0 --fallback-echo"
+- else
+- # maybe with a smaller string...
+- prev=:
+-
+- for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do
+- if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null
+- then
+- break
+- fi
+- prev="$cmd"
+- done
+-
+- if test "$prev" != 'sed 50q "$0"'; then
+- echo_test_string=`eval $prev`
+- export echo_test_string
+- exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"}
+- else
+- # Oops. We lost completely, so just stick with echo.
+- echo=echo
+- fi
+- fi
+- fi
+- fi
+-fi
+-fi
+-
+-# Copy echo and quote the copy suitably for passing to libtool from
+-# the Makefile, instead of quoting the original, which is used later.
+-ECHO=$echo
+-if test "X$ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then
+- ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo"
+-fi
+-
+-
+-
+-if expr a : '\(a\)' >/dev/null 2>&1; then
+- as_expr=expr
+-else
+- as_expr=false
+-fi
+-
+-
+ ## --------------------- ##
+ ## M4sh Initialization. ##
+ ## --------------------- ##
+@@ -184,11 +17,13 @@
+ if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
++ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
++ # is contrary to our usage. Disable this feature.
++ alias -g '${1+"$@"}'='"$@"'
+ elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+ set -o posix
+ fi
+
+-# NLS nuisances.
+ # Support unset when possible.
+ if (FOO=FOO; unset FOO) >/dev/null 2>&1; then
+ as_unset=unset
+@@ -196,34 +31,42 @@
+ as_unset=false
+ fi
+
+-(set +x; test -n "`(LANG=C; export LANG) 2>&1`") &&
+- { $as_unset LANG || test "${LANG+set}" != set; } ||
+- { LANG=C; export LANG; }
+-(set +x; test -n "`(LC_ALL=C; export LC_ALL) 2>&1`") &&
+- { $as_unset LC_ALL || test "${LC_ALL+set}" != set; } ||
+- { LC_ALL=C; export LC_ALL; }
+-(set +x; test -n "`(LC_TIME=C; export LC_TIME) 2>&1`") &&
+- { $as_unset LC_TIME || test "${LC_TIME+set}" != set; } ||
+- { LC_TIME=C; export LC_TIME; }
+-(set +x; test -n "`(LC_CTYPE=C; export LC_CTYPE) 2>&1`") &&
+- { $as_unset LC_CTYPE || test "${LC_CTYPE+set}" != set; } ||
+- { LC_CTYPE=C; export LC_CTYPE; }
+-(set +x; test -n "`(LANGUAGE=C; export LANGUAGE) 2>&1`") &&
+- { $as_unset LANGUAGE || test "${LANGUAGE+set}" != set; } ||
+- { LANGUAGE=C; export LANGUAGE; }
+-(set +x; test -n "`(LC_COLLATE=C; export LC_COLLATE) 2>&1`") &&
+- { $as_unset LC_COLLATE || test "${LC_COLLATE+set}" != set; } ||
+- { LC_COLLATE=C; export LC_COLLATE; }
+-(set +x; test -n "`(LC_NUMERIC=C; export LC_NUMERIC) 2>&1`") &&
+- { $as_unset LC_NUMERIC || test "${LC_NUMERIC+set}" != set; } ||
+- { LC_NUMERIC=C; export LC_NUMERIC; }
+-(set +x; test -n "`(LC_MESSAGES=C; export LC_MESSAGES) 2>&1`") &&
+- { $as_unset LC_MESSAGES || test "${LC_MESSAGES+set}" != set; } ||
+- { LC_MESSAGES=C; export LC_MESSAGES; }
++
++# Work around bugs in pre-3.0 UWIN ksh.
++$as_unset ENV MAIL MAILPATH
++PS1='$ '
++PS2='> '
++PS4='+ '
++
++# NLS nuisances.
++for as_var in \
++ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
++ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
++ LC_TELEPHONE LC_TIME
++do
++ if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then
++ eval $as_var=C; export $as_var
++ else
++ $as_unset $as_var
++ fi
++done
++
++# Required to use basename.
++if expr a : '\(a\)' >/dev/null 2>&1; then
++ as_expr=expr
++else
++ as_expr=false
++fi
++
++if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
++ as_basename=basename
++else
++ as_basename=false
++fi
+
+
+ # Name of the executable.
+-as_me=`(basename "$0") 2>/dev/null ||
++as_me=`$as_basename "$0" ||
+ $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)$' \| \
+@@ -234,6 +77,7 @@
+ /^X\/\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+
++
+ # PATH needs CR, and LINENO needs CR and PATH.
+ # Avoid depending upon Character Ranges.
+ as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+@@ -244,15 +88,15 @@
+
+ # The user is always right.
+ if test "${PATH_SEPARATOR+set}" != set; then
+- echo "#! /bin/sh" >conftest.sh
+- echo "exit 0" >>conftest.sh
+- chmod +x conftest.sh
+- if (PATH=".;."; conftest.sh) >/dev/null 2>&1; then
++ echo "#! /bin/sh" >conf$$.sh
++ echo "exit 0" >>conf$$.sh
++ chmod +x conf$$.sh
++ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+ PATH_SEPARATOR=';'
+ else
+ PATH_SEPARATOR=:
+ fi
+- rm -f conftest.sh
++ rm -f conf$$.sh
+ fi
+
+
+@@ -300,6 +144,8 @@
+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then
++ $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
++ $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+ CONFIG_SHELL=$as_dir/$as_base
+ export CONFIG_SHELL
+ exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+@@ -372,6 +218,12 @@
+ fi
+ rm -f conf$$ conf$$.exe conf$$.file
+
++if mkdir -p . 2>/dev/null; then
++ as_mkdir_p=:
++else
++ as_mkdir_p=false
++fi
++
+ as_executable_p="test -f"
+
+ # Sed expression to map a string onto a valid CPP name.
+@@ -388,7 +240,166 @@
+ IFS=" $as_nl"
+
+ # CDPATH.
+-$as_unset CDPATH || test "${CDPATH+set}" != set || { CDPATH=$PATH_SEPARATOR; export CDPATH; }
++$as_unset CDPATH
++
++
++# Find the correct PATH separator. Usually this is `:', but
++# DJGPP uses `;' like DOS.
++if test "X${PATH_SEPARATOR+set}" != Xset; then
++ UNAME=${UNAME-`uname 2>/dev/null`}
++ case X$UNAME in
++ *-DOS) lt_cv_sys_path_separator=';' ;;
++ *) lt_cv_sys_path_separator=':' ;;
++ esac
++ PATH_SEPARATOR=$lt_cv_sys_path_separator
++fi
++
++
++# Check that we are running under the correct shell.
++SHELL=${CONFIG_SHELL-/bin/sh}
++
++case X$ECHO in
++X*--fallback-echo)
++ # Remove one level of quotation (which was required for Make).
++ ECHO=`echo "$ECHO" | sed 's,\\\\\$\\$0,'$0','`
++ ;;
++esac
++
++echo=${ECHO-echo}
++if test "X$1" = X--no-reexec; then
++ # Discard the --no-reexec flag, and continue.
++ shift
++elif test "X$1" = X--fallback-echo; then
++ # Avoid inline document here, it may be left over
++ :
++elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then
++ # Yippee, $echo works!
++ :
++else
++ # Restart under the correct shell.
++ exec $SHELL "$0" --no-reexec ${1+"$@"}
++fi
++
++if test "X$1" = X--fallback-echo; then
++ # used as fallback echo
++ shift
++ cat <<EOF
++
++EOF
++ exit 0
++fi
++
++# The HP-UX ksh and POSIX shell print the target directory to stdout
++# if CDPATH is set.
++if test "X${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi
++
++if test -z "$ECHO"; then
++if test "X${echo_test_string+set}" != Xset; then
++# find a string as large as possible, as long as the shell can cope with it
++ for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do
++ # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
++ if (echo_test_string="`eval $cmd`") 2>/dev/null &&
++ echo_test_string="`eval $cmd`" &&
++ (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null
++ then
++ break
++ fi
++ done
++fi
++
++if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
++ echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` &&
++ test "X$echo_testing_string" = "X$echo_test_string"; then
++ :
++else
++ # The Solaris, AIX, and Digital Unix default echo programs unquote
++ # backslashes. This makes it impossible to quote backslashes using
++ # echo "$something" | sed 's/\\/\\\\/g'
++ #
++ # So, first we look for a working echo in the user's PATH.
++
++ IFS="${IFS= }"; save_ifs="$IFS"; IFS=$PATH_SEPARATOR
++ for dir in $PATH /usr/ucb; do
++ if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
++ test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
++ echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` &&
++ test "X$echo_testing_string" = "X$echo_test_string"; then
++ echo="$dir/echo"
++ break
++ fi
++ done
++ IFS="$save_ifs"
++
++ if test "X$echo" = Xecho; then
++ # We didn't find a better echo, so look for alternatives.
++ if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' &&
++ echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` &&
++ test "X$echo_testing_string" = "X$echo_test_string"; then
++ # This shell has a builtin print -r that does the trick.
++ echo='print -r'
++ elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) &&
++ test "X$CONFIG_SHELL" != X/bin/ksh; then
++ # If we have ksh, try running configure again with it.
++ ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
++ export ORIGINAL_CONFIG_SHELL
++ CONFIG_SHELL=/bin/ksh
++ export CONFIG_SHELL
++ exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"}
++ else
++ # Try using printf.
++ echo='printf %s\n'
++ if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
++ echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` &&
++ test "X$echo_testing_string" = "X$echo_test_string"; then
++ # Cool, printf works
++ :
++ elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` &&
++ test "X$echo_testing_string" = 'X\t' &&
++ echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
++ test "X$echo_testing_string" = "X$echo_test_string"; then
++ CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL
++ export CONFIG_SHELL
++ SHELL="$CONFIG_SHELL"
++ export SHELL
++ echo="$CONFIG_SHELL $0 --fallback-echo"
++ elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` &&
++ test "X$echo_testing_string" = 'X\t' &&
++ echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
++ test "X$echo_testing_string" = "X$echo_test_string"; then
++ echo="$CONFIG_SHELL $0 --fallback-echo"
++ else
++ # maybe with a smaller string...
++ prev=:
++
++ for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do
++ if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null
++ then
++ break
++ fi
++ prev="$cmd"
++ done
++
++ if test "$prev" != 'sed 50q "$0"'; then
++ echo_test_string=`eval $prev`
++ export echo_test_string
++ exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"}
++ else
++ # Oops. We lost completely, so just stick with echo.
++ echo=echo
++ fi
++ fi
++ fi
++ fi
++fi
++fi
++
++# Copy echo and quote the copy suitably for passing to libtool from
++# the Makefile, instead of quoting the original, which is used later.
++ECHO=$echo
++if test "X$ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then
++ ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo"
++fi
++
+
+
+ # Name of the host.
+@@ -402,6 +413,7 @@
+ # Initializations.
+ #
+ ac_default_prefix=/usr/local
++ac_config_libobj_dir=.
+ cross_compiling=no
+ subdirs=
+ MFLAGS=
+@@ -458,6 +470,8 @@
+ # include <unistd.h>
+ #endif"
+
++ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO AMTAR install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM AWK SET_MAKE GC_VERSION CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE CXX CXXFLAGS ac_ct_CXX CXXDEPMODE CCAS CCASFLAGS AR ac_ct_AR RANLIB ac_ct_RANLIB MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT GC_CFLAGS THREADLIBS POWERPC_DARWIN_TRUE POWERPC_DARWIN_FALSE EXTRA_TEST_LIBS target_all CPLUSPLUS_TRUE CPLUSPLUS_FALSE INCLUDES CXXINCLUDES addobjs addincludes addlibs addtests LN_S ECHO CPP EGREP LIBTOOL MY_CFLAGS USE_LIBDIR_TRUE USE_LIBDIR_FALSE LIBOBJS LTLIBOBJS'
++ac_subst_files=''
+
+ # Initialize some variables set by options.
+ ac_init_help=
+@@ -881,6 +895,9 @@
+ { (exit 1); exit 1; }; }
+ fi
+ fi
++(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null ||
++ { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2
++ { (exit 1); exit 1; }; }
+ srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
+ ac_env_build_alias_set=${build_alias+set}
+ ac_env_build_alias_value=$build_alias
+@@ -1080,7 +1097,7 @@
+ # Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be
+ # absolute.
+ ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd`
+-ac_abs_top_builddir=`cd "$ac_dir" && cd $ac_top_builddir && pwd`
++ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd`
+ ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd`
+ ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd`
+
+@@ -1107,7 +1124,7 @@
+ if $ac_init_version; then
+ cat <<\_ACEOF
+ gc configure 6.3alpha2
+-generated by GNU Autoconf 2.53
++generated by GNU Autoconf 2.57
+
+ Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002
+ Free Software Foundation, Inc.
+@@ -1122,7 +1139,7 @@
+ running configure, to aid debugging if configure makes a mistake.
+
+ It was created by gc $as_me 6.3alpha2, which was
+-generated by GNU Autoconf 2.53. Invocation command line was
++generated by GNU Autoconf 2.57. Invocation command line was
+
+ $ $0 $@
+
+@@ -1174,27 +1191,54 @@
+
+ # Keep a trace of the command line.
+ # Strip out --no-create and --no-recursion so they do not pile up.
++# Strip out --silent because we don't want to record it for future runs.
+ # Also quote any args containing shell meta-characters.
++# Make two passes to allow for proper duplicate-argument suppression.
+ ac_configure_args=
++ac_configure_args0=
++ac_configure_args1=
+ ac_sep=
+-for ac_arg
++ac_must_keep_next=false
++for ac_pass in 1 2
+ do
+- case $ac_arg in
+- -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+- | --no-cr | --no-c | -n ) continue ;;
+- -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+- | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+- continue ;;
+- *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+- ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+- esac
+- case " $ac_configure_args " in
+- *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
+- *) ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
+- ac_sep=" " ;;
+- esac
+- # Get rid of the leading space.
++ for ac_arg
++ do
++ case $ac_arg in
++ -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
++ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
++ | -silent | --silent | --silen | --sile | --sil)
++ continue ;;
++ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
++ ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
++ esac
++ case $ac_pass in
++ 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
++ 2)
++ ac_configure_args1="$ac_configure_args1 '$ac_arg'"
++ if test $ac_must_keep_next = true; then
++ ac_must_keep_next=false # Got value, back to normal.
++ else
++ case $ac_arg in
++ *=* | --config-cache | -C | -disable-* | --disable-* \
++ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
++ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
++ | -with-* | --with-* | -without-* | --without-* | --x)
++ case "$ac_configure_args0 " in
++ "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
++ esac
++ ;;
++ -* ) ac_must_keep_next=true ;;
++ esac
++ fi
++ ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
++ # Get rid of the leading space.
++ ac_sep=" "
++ ;;
++ esac
++ done
+ done
++$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
++$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
+
+ # When interrupted or exit'd, cleanup temporary files, and complete
+ # config.log. We remove comments because anyway the quotes in there
+@@ -1205,6 +1249,7 @@
+ # Save into config.log some information that might help in debugging.
+ {
+ echo
++
+ cat <<\_ASBOX
+ ## ---------------- ##
+ ## Cache variables. ##
+@@ -1227,6 +1272,35 @@
+ esac;
+ }
+ echo
++
++ cat <<\_ASBOX
++## ----------------- ##
++## Output variables. ##
++## ----------------- ##
++_ASBOX
++ echo
++ for ac_var in $ac_subst_vars
++ do
++ eval ac_val=$`echo $ac_var`
++ echo "$ac_var='"'"'$ac_val'"'"'"
++ done | sort
++ echo
++
++ if test -n "$ac_subst_files"; then
++ cat <<\_ASBOX
++## ------------- ##
++## Output files. ##
++## ------------- ##
++_ASBOX
++ echo
++ for ac_var in $ac_subst_files
++ do
++ eval ac_val=$`echo $ac_var`
++ echo "$ac_var='"'"'$ac_val'"'"'"
++ done | sort
++ echo
++ fi
++
+ if test -s confdefs.h; then
+ cat <<\_ASBOX
+ ## ----------- ##
+@@ -1234,7 +1308,7 @@
+ ## ----------- ##
+ _ASBOX
+ echo
+- sed "/^$/d" confdefs.h
++ sed "/^$/d" confdefs.h | sort
+ echo
+ fi
+ test "$ac_signal" != 0 &&
+@@ -1399,6 +1473,7 @@
+
+
+
++
+ ## version must conform to [0-9]+[.][0-9]+(alpha[0-9]+)?
+
+ ac_aux_dir=
+@@ -1743,15 +1818,15 @@
+ test -n "$AWK" && break
+ done
+
+-echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \${MAKE}" >&5
+-echo $ECHO_N "checking whether ${MAKE-make} sets \${MAKE}... $ECHO_C" >&6
++echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5
++echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6
+ set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,./+-,__p_,'`
+ if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+ else
+ cat >conftest.make <<\_ACEOF
+ all:
+- @echo 'ac_maketemp="${MAKE}"'
++ @echo 'ac_maketemp="$(MAKE)"'
+ _ACEOF
+ # GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+ eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=`
+@@ -2116,9 +2191,7 @@
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+- set dummy "$as_dir/$ac_word" ${1+"$@"}
+- shift
+- ac_cv_prog_CC="$@"
++ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+ fi
+ fi
+ fi
+@@ -2223,8 +2296,10 @@
+ fi
+
+
+-test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH" >&5
+-echo "$as_me: error: no acceptable C compiler found in \$PATH" >&2;}
++test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
++See \`config.log' for more details." >&5
++echo "$as_me: error: no acceptable C compiler found in \$PATH
++See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+
+ # Provide some information about the compiler.
+@@ -2249,14 +2324,12 @@
+
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+
+-#ifdef F77_DUMMY_MAIN
+-# ifdef __cplusplus
+- extern "C"
+-# endif
+- int F77_DUMMY_MAIN() { return 1; }
+-#endif
+ int
+ main ()
+ {
+@@ -2266,7 +2339,7 @@
+ }
+ _ACEOF
+ ac_clean_files_save=$ac_clean_files
+-ac_clean_files="$ac_clean_files a.out a.exe"
++ac_clean_files="$ac_clean_files a.out a.exe b.out"
+ # Try to create an executable without -o first, disregard a.out.
+ # It will help us diagnose broken compilers, and finding out an intuition
+ # of exeext.
+@@ -2285,26 +2358,39 @@
+ # Be careful to initialize this variable, since it used to be cached.
+ # Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile.
+ ac_cv_exeext=
+-for ac_file in `ls a_out.exe a.exe conftest.exe 2>/dev/null;
+- ls a.out conftest 2>/dev/null;
+- ls a.* conftest.* 2>/dev/null`; do
++# b.out is created by i960 compilers.
++for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out
++do
++ test -f "$ac_file" || continue
+ case $ac_file in
+- *.$ac_ext | *.o | *.obj | *.xcoff | *.tds | *.d | *.pdb | *.xSYM ) ;;
+- a.out ) # We found the default executable, but exeext='' is most
+- # certainly right.
+- break;;
+- *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+- # FIXME: I believe we export ac_cv_exeext for Libtool --akim.
+- export ac_cv_exeext
+- break;;
+- * ) break;;
++ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj )
++ ;;
++ conftest.$ac_ext )
++ # This is the source file.
++ ;;
++ [ab].out )
++ # We found the default executable, but exeext='' is most
++ # certainly right.
++ break;;
++ *.* )
++ ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
++ # FIXME: I believe we export ac_cv_exeext for Libtool,
++ # but it would be cool to find out if it's true. Does anybody
++ # maintain Libtool? --akim.
++ export ac_cv_exeext
++ break;;
++ * )
++ break;;
+ esac
+ done
+ else
+ echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
+-{ { echo "$as_me:$LINENO: error: C compiler cannot create executables" >&5
+-echo "$as_me: error: C compiler cannot create executables" >&2;}
++sed 's/^/| /' conftest.$ac_ext >&5
++
++{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
++See \`config.log' for more details." >&5
++echo "$as_me: error: C compiler cannot create executables
++See \`config.log' for more details." >&2;}
+ { (exit 77); exit 77; }; }
+ fi
+
+@@ -2331,9 +2417,11 @@
+ cross_compiling=yes
+ else
+ { { echo "$as_me:$LINENO: error: cannot run C compiled programs.
+-If you meant to cross compile, use \`--host'." >&5
++If you meant to cross compile, use \`--host'.
++See \`config.log' for more details." >&5
+ echo "$as_me: error: cannot run C compiled programs.
+-If you meant to cross compile, use \`--host'." >&2;}
++If you meant to cross compile, use \`--host'.
++See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+ fi
+@@ -2341,7 +2429,7 @@
+ echo "$as_me:$LINENO: result: yes" >&5
+ echo "${ECHO_T}yes" >&6
+
+-rm -f a.out a.exe conftest$ac_cv_exeext
++rm -f a.out a.exe conftest$ac_cv_exeext b.out
+ ac_clean_files=$ac_clean_files_save
+ # Check the compiler produces executables we can run. If not, either
+ # the compiler is broken, or we cross compile.
+@@ -2361,9 +2449,10 @@
+ # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
+ # work properly (i.e., refer to `conftest.exe'), while it won't with
+ # `rm'.
+-for ac_file in `(ls conftest.exe; ls conftest; ls conftest.*) 2>/dev/null`; do
++for ac_file in conftest.exe conftest conftest.*; do
++ test -f "$ac_file" || continue
+ case $ac_file in
+- *.$ac_ext | *.o | *.obj | *.xcoff | *.tds | *.d | *.pdb ) ;;
++ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;;
+ *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ export ac_cv_exeext
+ break;;
+@@ -2371,8 +2460,10 @@
+ esac
+ done
+ else
+- { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link" >&5
+-echo "$as_me: error: cannot compute suffix of executables: cannot compile and link" >&2;}
++ { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
++See \`config.log' for more details." >&5
++echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
++See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+
+@@ -2390,14 +2481,12 @@
+ else
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+
+-#ifdef F77_DUMMY_MAIN
+-# ifdef __cplusplus
+- extern "C"
+-# endif
+- int F77_DUMMY_MAIN() { return 1; }
+-#endif
+ int
+ main ()
+ {
+@@ -2414,16 +2503,19 @@
+ (exit $ac_status); }; then
+ for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do
+ case $ac_file in
+- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb ) ;;
++ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;;
+ *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+ break;;
+ esac
+ done
+ else
+ echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
+-{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile" >&5
+-echo "$as_me: error: cannot compute suffix of object files: cannot compile" >&2;}
++sed 's/^/| /' conftest.$ac_ext >&5
++
++{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
++See \`config.log' for more details." >&5
++echo "$as_me: error: cannot compute suffix of object files: cannot compile
++See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+
+@@ -2440,14 +2532,12 @@
+ else
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+
+-#ifdef F77_DUMMY_MAIN
+-# ifdef __cplusplus
+- extern "C"
+-# endif
+- int F77_DUMMY_MAIN() { return 1; }
+-#endif
+ int
+ main ()
+ {
+@@ -2474,7 +2564,8 @@
+ ac_compiler_gnu=yes
+ else
+ echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
+ ac_compiler_gnu=no
+ fi
+ rm -f conftest.$ac_objext conftest.$ac_ext
+@@ -2494,14 +2585,12 @@
+ else
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+
+-#ifdef F77_DUMMY_MAIN
+-# ifdef __cplusplus
+- extern "C"
+-# endif
+- int F77_DUMMY_MAIN() { return 1; }
+-#endif
+ int
+ main ()
+ {
+@@ -2525,7 +2614,8 @@
+ ac_cv_prog_cc_g=yes
+ else
+ echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
+ ac_cv_prog_cc_g=no
+ fi
+ rm -f conftest.$ac_objext conftest.$ac_ext
+@@ -2547,6 +2637,102 @@
+ CFLAGS=
+ fi
+ fi
++echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5
++echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6
++if test "${ac_cv_prog_cc_stdc+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ ac_cv_prog_cc_stdc=no
++ac_save_CC=$CC
++cat >conftest.$ac_ext <<_ACEOF
++#line $LINENO "configure"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
++#include <stdarg.h>
++#include <stdio.h>
++#include <sys/types.h>
++#include <sys/stat.h>
++/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
++struct buf { int x; };
++FILE * (*rcsopen) (struct buf *, struct stat *, int);
++static char *e (p, i)
++ char **p;
++ int i;
++{
++ return p[i];
++}
++static char *f (char * (*g) (char **, int), char **p, ...)
++{
++ char *s;
++ va_list v;
++ va_start (v,p);
++ s = g (p, va_arg (v,int));
++ va_end (v);
++ return s;
++}
++int test (int i, double x);
++struct s1 {int (*f) (int a);};
++struct s2 {int (*f) (double a);};
++int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
++int argc;
++char **argv;
++int
++main ()
++{
++return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
++ ;
++ return 0;
++}
++_ACEOF
++# Don't try gcc -ansi; that turns off useful extensions and
++# breaks some systems' header files.
++# AIX -qlanglvl=ansi
++# Ultrix and OSF/1 -std1
++# HP-UX 10.20 and later -Ae
++# HP-UX older versions -Aa -D_HPUX_SOURCE
++# SVR4 -Xc -D__EXTENSIONS__
++for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
++do
++ CC="$ac_save_CC $ac_arg"
++ rm -f conftest.$ac_objext
++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
++ (eval $ac_compile) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); } &&
++ { ac_try='test -s conftest.$ac_objext'
++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++ (eval $ac_try) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); }; }; then
++ ac_cv_prog_cc_stdc=$ac_arg
++break
++else
++ echo "$as_me: failed program was:" >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
++fi
++rm -f conftest.$ac_objext
++done
++rm -f conftest.$ac_ext conftest.$ac_objext
++CC=$ac_save_CC
++
++fi
++
++case "x$ac_cv_prog_cc_stdc" in
++ x|xno)
++ echo "$as_me:$LINENO: result: none needed" >&5
++echo "${ECHO_T}none needed" >&6 ;;
++ *)
++ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
++echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
++ CC="$CC $ac_cv_prog_cc_stdc" ;;
++esac
++
+ # Some people use a C++ compiler to compile C. Since we use `exit',
+ # in C++ we need to declare it. In case someone uses the same compiler
+ # for both compiling C and C++ we need to have the C++ compiler decide
+@@ -2579,15 +2765,13 @@
+ do
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+ #include <stdlib.h>
+ $ac_declaration
+-#ifdef F77_DUMMY_MAIN
+-# ifdef __cplusplus
+- extern "C"
+-# endif
+- int F77_DUMMY_MAIN() { return 1; }
+-#endif
+ int
+ main ()
+ {
+@@ -2611,20 +2795,19 @@
+ :
+ else
+ echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
+ continue
+ fi
+ rm -f conftest.$ac_objext conftest.$ac_ext
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+ $ac_declaration
+-#ifdef F77_DUMMY_MAIN
+-# ifdef __cplusplus
+- extern "C"
+-# endif
+- int F77_DUMMY_MAIN() { return 1; }
+-#endif
+ int
+ main ()
+ {
+@@ -2648,7 +2831,8 @@
+ break
+ else
+ echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
+ fi
+ rm -f conftest.$ac_objext conftest.$ac_ext
+ done
+@@ -2661,7 +2845,8 @@
+
+ else
+ echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
+ fi
+ rm -f conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
+@@ -2680,7 +2865,7 @@
+ rmdir .deps 2>/dev/null
+
+
+-ac_config_commands="$ac_config_commands depfiles"
++ ac_config_commands="$ac_config_commands depfiles"
+
+
+ am_make=${MAKE-make}
+@@ -2932,14 +3117,12 @@
+ else
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+
+-#ifdef F77_DUMMY_MAIN
+-# ifdef __cplusplus
+- extern "C"
+-# endif
+- int F77_DUMMY_MAIN() { return 1; }
+-#endif
+ int
+ main ()
+ {
+@@ -2966,7 +3149,8 @@
+ ac_compiler_gnu=yes
+ else
+ echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
+ ac_compiler_gnu=no
+ fi
+ rm -f conftest.$ac_objext conftest.$ac_ext
+@@ -2986,14 +3170,12 @@
+ else
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+
+-#ifdef F77_DUMMY_MAIN
+-# ifdef __cplusplus
+- extern "C"
+-# endif
+- int F77_DUMMY_MAIN() { return 1; }
+-#endif
+ int
+ main ()
+ {
+@@ -3017,7 +3199,8 @@
+ ac_cv_prog_cxx_g=yes
+ else
+ echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
+ ac_cv_prog_cxx_g=no
+ fi
+ rm -f conftest.$ac_objext conftest.$ac_ext
+@@ -3050,15 +3233,13 @@
+ do
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+ #include <stdlib.h>
+ $ac_declaration
+-#ifdef F77_DUMMY_MAIN
+-# ifdef __cplusplus
+- extern "C"
+-# endif
+- int F77_DUMMY_MAIN() { return 1; }
+-#endif
+ int
+ main ()
+ {
+@@ -3082,20 +3263,19 @@
+ :
+ else
+ echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
+ continue
+ fi
+ rm -f conftest.$ac_objext conftest.$ac_ext
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+ $ac_declaration
+-#ifdef F77_DUMMY_MAIN
+-# ifdef __cplusplus
+- extern "C"
+-# endif
+- int F77_DUMMY_MAIN() { return 1; }
+-#endif
+ int
+ main ()
+ {
+@@ -3119,7 +3299,8 @@
+ break
+ else
+ echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
+ fi
+ rm -f conftest.$ac_objext conftest.$ac_ext
+ done
+@@ -3751,7 +3932,11 @@
+ LIBS="-ldl $LIBS"
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+
+ /* Override any gcc2 internal prototype to avoid an error. */
+ #ifdef __cplusplus
+@@ -3760,12 +3945,6 @@
+ /* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+ char dlopen ();
+-#ifdef F77_DUMMY_MAIN
+-# ifdef __cplusplus
+- extern "C"
+-# endif
+- int F77_DUMMY_MAIN() { return 1; }
+-#endif
+ int
+ main ()
+ {
+@@ -3789,7 +3968,8 @@
+ ac_cv_lib_dl_dlopen=yes
+ else
+ echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
+ ac_cv_lib_dl_dlopen=no
+ fi
+ rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+@@ -3936,6 +4116,13 @@
+ ;;
+ mips*-*-linux*)
+ ;;
++ mips-unknown-elf*)
++ machdep="mips2java_mach_dep.lo"
++ cat >>confdefs.h <<\_ACEOF
++#define MIPS2JAVA 1
++_ACEOF
++
++ ;;
+ mips-*-*)
+ machdep="mips_sgi_mach_dep.lo"
+ cat >>confdefs.h <<\_ACEOF
+@@ -4595,18 +4782,28 @@
+ do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
++ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
++ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
+-#include <assert.h>
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
++#ifdef __STDC__
++# include <limits.h>
++#else
++# include <assert.h>
++#endif
+ Syntax error
+ _ACEOF
+ if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+- egrep -v '^ *\+' conftest.er1 >conftest.err
++ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+@@ -4623,7 +4820,8 @@
+ :
+ else
+ echo "$as_me: failed program was:" >&5
+- cat conftest.$ac_ext >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
+ # Broken: fails on valid input.
+ continue
+ fi
+@@ -4633,13 +4831,17 @@
+ # can be detected and how.
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+ #include <ac_nonexistent.h>
+ _ACEOF
+ if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+- egrep -v '^ *\+' conftest.er1 >conftest.err
++ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+@@ -4657,7 +4859,8 @@
+ continue
+ else
+ echo "$as_me: failed program was:" >&5
+- cat conftest.$ac_ext >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
+ # Passes both tests.
+ ac_preproc_ok=:
+ break
+@@ -4686,18 +4889,28 @@
+ do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
++ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
++ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
+-#include <assert.h>
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
++#ifdef __STDC__
++# include <limits.h>
++#else
++# include <assert.h>
++#endif
+ Syntax error
+ _ACEOF
+ if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+- egrep -v '^ *\+' conftest.er1 >conftest.err
++ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+@@ -4714,7 +4927,8 @@
+ :
+ else
+ echo "$as_me: failed program was:" >&5
+- cat conftest.$ac_ext >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
+ # Broken: fails on valid input.
+ continue
+ fi
+@@ -4724,13 +4938,17 @@
+ # can be detected and how.
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+ #include <ac_nonexistent.h>
+ _ACEOF
+ if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+- egrep -v '^ *\+' conftest.er1 >conftest.err
++ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+@@ -4748,7 +4966,8 @@
+ continue
+ else
+ echo "$as_me: failed program was:" >&5
+- cat conftest.$ac_ext >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
+ # Passes both tests.
+ ac_preproc_ok=:
+ break
+@@ -4761,8 +4980,10 @@
+ if $ac_preproc_ok; then
+ :
+ else
+- { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check" >&5
+-echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check" >&2;}
++ { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
++See \`config.log' for more details." >&5
++echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
++See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+
+@@ -4773,6 +4994,21 @@
+ ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
++echo "$as_me:$LINENO: checking for egrep" >&5
++echo $ECHO_N "checking for egrep... $ECHO_C" >&6
++if test "${ac_cv_prog_egrep+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ if echo a | (grep -E '(a|b)') >/dev/null 2>&1
++ then ac_cv_prog_egrep='grep -E'
++ else ac_cv_prog_egrep='egrep'
++ fi
++fi
++echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5
++echo "${ECHO_T}$ac_cv_prog_egrep" >&6
++ EGREP=$ac_cv_prog_egrep
++
++
+ echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+ echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
+ if test "${ac_cv_header_stdc+set}" = set; then
+@@ -4780,48 +5016,59 @@
+ else
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+ #include <stdlib.h>
+ #include <stdarg.h>
+ #include <string.h>
+ #include <float.h>
+
++int
++main ()
++{
++
++ ;
++ return 0;
++}
+ _ACEOF
+-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+- (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
++rm -f conftest.$ac_objext
++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
++ (eval $ac_compile) 2>&5
+ ac_status=$?
+- egrep -v '^ *\+' conftest.er1 >conftest.err
+- rm -f conftest.er1
+- cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+- (exit $ac_status); } >/dev/null; then
+- if test -s conftest.err; then
+- ac_cpp_err=$ac_c_preproc_warn_flag
+- else
+- ac_cpp_err=
+- fi
+-else
+- ac_cpp_err=yes
+-fi
+-if test -z "$ac_cpp_err"; then
++ (exit $ac_status); } &&
++ { ac_try='test -s conftest.$ac_objext'
++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++ (eval $ac_try) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); }; }; then
+ ac_cv_header_stdc=yes
+ else
+ echo "$as_me: failed program was:" >&5
+- cat conftest.$ac_ext >&5
+- ac_cv_header_stdc=no
++sed 's/^/| /' conftest.$ac_ext >&5
++
++ac_cv_header_stdc=no
+ fi
+-rm -f conftest.err conftest.$ac_ext
++rm -f conftest.$ac_objext conftest.$ac_ext
+
+ if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+ #include <string.h>
+
+ _ACEOF
+ if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+- egrep "memchr" >/dev/null 2>&1; then
++ $EGREP "memchr" >/dev/null 2>&1; then
+ :
+ else
+ ac_cv_header_stdc=no
+@@ -4834,12 +5081,16 @@
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+ #include <stdlib.h>
+
+ _ACEOF
+ if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+- egrep "free" >/dev/null 2>&1; then
++ $EGREP "free" >/dev/null 2>&1; then
+ :
+ else
+ ac_cv_header_stdc=no
+@@ -4855,13 +5106,18 @@
+ else
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+ #include <ctype.h>
+ #if ((' ' & 0x0FF) == 0x020)
+ # define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+ # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+ #else
+-# define ISLOWER(c) (('a' <= (c) && (c) <= 'i') \
++# define ISLOWER(c) \
++ (('a' <= (c) && (c) <= 'i') \
+ || ('j' <= (c) && (c) <= 'r') \
+ || ('s' <= (c) && (c) <= 'z'))
+ # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+@@ -4894,11 +5150,12 @@
+ else
+ echo "$as_me: program exited with status $ac_status" >&5
+ echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
+ ( exit $ac_status )
+ ac_cv_header_stdc=no
+ fi
+-rm -f core core.* *.core conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
++rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+ fi
+ fi
+ fi
+@@ -4933,7 +5190,11 @@
+ else
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+ $ac_includes_default
+
+ #include <$ac_header>
+@@ -4953,7 +5214,8 @@
+ eval "$as_ac_Header=yes"
+ else
+ echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
+ eval "$as_ac_Header=no"
+ fi
+ rm -f conftest.$ac_objext conftest.$ac_ext
+@@ -4988,7 +5250,11 @@
+ echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+ $ac_includes_default
+ #include <$ac_header>
+ _ACEOF
+@@ -5007,7 +5273,8 @@
+ ac_header_compiler=yes
+ else
+ echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
+ ac_header_compiler=no
+ fi
+ rm -f conftest.$ac_objext conftest.$ac_ext
+@@ -5019,13 +5286,17 @@
+ echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+ #include <$ac_header>
+ _ACEOF
+ if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+- egrep -v '^ *\+' conftest.er1 >conftest.err
++ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+@@ -5042,7 +5313,8 @@
+ ac_header_preproc=yes
+ else
+ echo "$as_me: failed program was:" >&5
+- cat conftest.$ac_ext >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
+ ac_header_preproc=no
+ fi
+ rm -f conftest.err conftest.$ac_ext
+@@ -5055,14 +5327,32 @@
+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+ echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;};;
++echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
++ (
++ cat <<\_ASBOX
++## ------------------------------------ ##
++## Report this to bug-autoconf@gnu.org. ##
++## ------------------------------------ ##
++_ASBOX
++ ) |
++ sed "s/^/$as_me: WARNING: /" >&2
++ ;;
+ no:yes )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+ echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+ echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;};;
++echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
++ (
++ cat <<\_ASBOX
++## ------------------------------------ ##
++## Report this to bug-autoconf@gnu.org. ##
++## ------------------------------------ ##
++_ASBOX
++ ) |
++ sed "s/^/$as_me: WARNING: /" >&2
++ ;;
+ esac
+ echo "$as_me:$LINENO: checking for $ac_header" >&5
+ echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+@@ -5403,7 +5693,7 @@
+ case $host in
+ *-*-irix6*)
+ # Find out which ABI we are using.
+- echo '#line 5406 "configure"' > conftest.$ac_ext
++ echo '#line 5696 "configure"' > conftest.$ac_ext
+ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+@@ -5443,14 +5733,12 @@
+
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+
+-#ifdef F77_DUMMY_MAIN
+-# ifdef __cplusplus
+- extern "C"
+-# endif
+- int F77_DUMMY_MAIN() { return 1; }
+-#endif
+ int
+ main ()
+ {
+@@ -5474,7 +5762,8 @@
+ lt_cv_cc_needs_belf=yes
+ else
+ echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
+ lt_cv_cc_needs_belf=no
+ fi
+ rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+@@ -5777,14 +6066,12 @@
+ CFLAGS="$CFLAGS $lt_cv_prog_cc_pic -DPIC"
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+
+-#ifdef F77_DUMMY_MAIN
+-# ifdef __cplusplus
+- extern "C"
+-# endif
+- int F77_DUMMY_MAIN() { return 1; }
+-#endif
+ int
+ main ()
+ {
+@@ -5823,7 +6110,8 @@
+
+ else
+ echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
+ lt_cv_prog_cc_pic_works=no
+
+ fi
+@@ -5866,14 +6154,12 @@
+ LDFLAGS="$LDFLAGS $lt_cv_prog_cc_static"
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+
+-#ifdef F77_DUMMY_MAIN
+-# ifdef __cplusplus
+- extern "C"
+-# endif
+- int F77_DUMMY_MAIN() { return 1; }
+-#endif
+ int
+ main ()
+ {
+@@ -5897,7 +6183,8 @@
+ lt_cv_prog_cc_static_works=yes
+ else
+ echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
+ fi
+ rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS="$save_LDFLAGS"
+@@ -5939,7 +6226,7 @@
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -o out/conftest2.$ac_objext"
+ compiler_c_o=no
+-if { (eval echo configure:5942: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.$ac_objext; then
++if { (eval echo configure:6229: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.$ac_objext; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s out/conftest.err; then
+@@ -5981,14 +6268,12 @@
+ ac_objext=lo
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+
+-#ifdef F77_DUMMY_MAIN
+-# ifdef __cplusplus
+- extern "C"
+-# endif
+- int F77_DUMMY_MAIN() { return 1; }
+-#endif
+ int
+ main ()
+ {
+@@ -6019,7 +6304,8 @@
+
+ else
+ echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
+ fi
+ rm -f conftest.$ac_objext conftest.$ac_ext
+ ac_objext="$save_objext"
+@@ -6067,14 +6353,12 @@
+ compiler_rtti_exceptions=no
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+
+-#ifdef F77_DUMMY_MAIN
+-# ifdef __cplusplus
+- extern "C"
+-# endif
+- int F77_DUMMY_MAIN() { return 1; }
+-#endif
+ int
+ main ()
+ {
+@@ -6105,7 +6389,8 @@
+
+ else
+ echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
+ fi
+ rm -f conftest.$ac_objext conftest.$ac_ext
+ CFLAGS="$save_CFLAGS"
+@@ -7326,37 +7611,44 @@
+ else
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+ /* System header to define __stub macros and hopefully few prototypes,
+- which can conflict with char shl_load (); below. */
+-#include <assert.h>
++ which can conflict with char shl_load (); below.
++ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
++ <limits.h> exists even on freestanding compilers. */
++#ifdef __STDC__
++# include <limits.h>
++#else
++# include <assert.h>
++#endif
+ /* Override any gcc2 internal prototype to avoid an error. */
+ #ifdef __cplusplus
+ extern "C"
++{
+ #endif
+ /* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+ char shl_load ();
+-char (*f) ();
+-
+-#ifdef F77_DUMMY_MAIN
+-# ifdef __cplusplus
+- extern "C"
+-# endif
+- int F77_DUMMY_MAIN() { return 1; }
+-#endif
+-int
+-main ()
+-{
+ /* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+ #if defined (__stub_shl_load) || defined (__stub___shl_load)
+ choke me
+ #else
+-f = shl_load;
++char (*f) () = shl_load;
++#endif
++#ifdef __cplusplus
++}
+ #endif
+
++int
++main ()
++{
++return f != shl_load;
+ ;
+ return 0;
+ }
+@@ -7376,7 +7668,8 @@
+ ac_cv_func_shl_load=yes
+ else
+ echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
+ ac_cv_func_shl_load=no
+ fi
+ rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+@@ -7395,7 +7688,11 @@
+ LIBS="-ldld $LIBS"
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+
+ /* Override any gcc2 internal prototype to avoid an error. */
+ #ifdef __cplusplus
+@@ -7404,12 +7701,6 @@
+ /* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+ char shl_load ();
+-#ifdef F77_DUMMY_MAIN
+-# ifdef __cplusplus
+- extern "C"
+-# endif
+- int F77_DUMMY_MAIN() { return 1; }
+-#endif
+ int
+ main ()
+ {
+@@ -7433,7 +7724,8 @@
+ ac_cv_lib_dld_shl_load=yes
+ else
+ echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
+ ac_cv_lib_dld_shl_load=no
+ fi
+ rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+@@ -7451,37 +7743,44 @@
+ else
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+ /* System header to define __stub macros and hopefully few prototypes,
+- which can conflict with char dlopen (); below. */
+-#include <assert.h>
++ which can conflict with char dlopen (); below.
++ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
++ <limits.h> exists even on freestanding compilers. */
++#ifdef __STDC__
++# include <limits.h>
++#else
++# include <assert.h>
++#endif
+ /* Override any gcc2 internal prototype to avoid an error. */
+ #ifdef __cplusplus
+ extern "C"
++{
+ #endif
+ /* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+ char dlopen ();
+-char (*f) ();
+-
+-#ifdef F77_DUMMY_MAIN
+-# ifdef __cplusplus
+- extern "C"
+-# endif
+- int F77_DUMMY_MAIN() { return 1; }
+-#endif
+-int
+-main ()
+-{
+ /* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+ #if defined (__stub_dlopen) || defined (__stub___dlopen)
+ choke me
+ #else
+-f = dlopen;
++char (*f) () = dlopen;
++#endif
++#ifdef __cplusplus
++}
+ #endif
+
++int
++main ()
++{
++return f != dlopen;
+ ;
+ return 0;
+ }
+@@ -7501,7 +7800,8 @@
+ ac_cv_func_dlopen=yes
+ else
+ echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
+ ac_cv_func_dlopen=no
+ fi
+ rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+@@ -7520,7 +7820,11 @@
+ LIBS="-ldl $LIBS"
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+
+ /* Override any gcc2 internal prototype to avoid an error. */
+ #ifdef __cplusplus
+@@ -7529,12 +7833,6 @@
+ /* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+ char dlopen ();
+-#ifdef F77_DUMMY_MAIN
+-# ifdef __cplusplus
+- extern "C"
+-# endif
+- int F77_DUMMY_MAIN() { return 1; }
+-#endif
+ int
+ main ()
+ {
+@@ -7558,7 +7856,8 @@
+ ac_cv_lib_dl_dlopen=yes
+ else
+ echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
+ ac_cv_lib_dl_dlopen=no
+ fi
+ rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+@@ -7578,7 +7877,11 @@
+ LIBS="-lsvld $LIBS"
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+
+ /* Override any gcc2 internal prototype to avoid an error. */
+ #ifdef __cplusplus
+@@ -7587,12 +7890,6 @@
+ /* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+ char dlopen ();
+-#ifdef F77_DUMMY_MAIN
+-# ifdef __cplusplus
+- extern "C"
+-# endif
+- int F77_DUMMY_MAIN() { return 1; }
+-#endif
+ int
+ main ()
+ {
+@@ -7616,7 +7913,8 @@
+ ac_cv_lib_svld_dlopen=yes
+ else
+ echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
+ ac_cv_lib_svld_dlopen=no
+ fi
+ rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+@@ -7636,7 +7934,11 @@
+ LIBS="-ldld $LIBS"
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+
+ /* Override any gcc2 internal prototype to avoid an error. */
+ #ifdef __cplusplus
+@@ -7645,12 +7947,6 @@
+ /* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+ char dld_link ();
+-#ifdef F77_DUMMY_MAIN
+-# ifdef __cplusplus
+- extern "C"
+-# endif
+- int F77_DUMMY_MAIN() { return 1; }
+-#endif
+ int
+ main ()
+ {
+@@ -7674,7 +7970,8 @@
+ ac_cv_lib_dld_dld_link=yes
+ else
+ echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
+ ac_cv_lib_dld_dld_link=no
+ fi
+ rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+@@ -7732,7 +8029,7 @@
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<EOF
+-#line 7735 "configure"
++#line 8032 "configure"
+ #include "confdefs.h"
+
+ #if HAVE_DLFCN_H
+@@ -7830,7 +8127,7 @@
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<EOF
+-#line 7833 "configure"
++#line 8130 "configure"
+ #include "confdefs.h"
+
+ #if HAVE_DLFCN_H
+@@ -8575,7 +8872,11 @@
+ echo $ECHO_N "checking sys/dg_sys_info.h usability... $ECHO_C" >&6
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+ $ac_includes_default
+ #include <sys/dg_sys_info.h>
+ _ACEOF
+@@ -8594,7 +8895,8 @@
+ ac_header_compiler=yes
+ else
+ echo "$as_me: failed program was:" >&5
+-cat conftest.$ac_ext >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
+ ac_header_compiler=no
+ fi
+ rm -f conftest.$ac_objext conftest.$ac_ext
+@@ -8606,13 +8908,17 @@
+ echo $ECHO_N "checking sys/dg_sys_info.h presence... $ECHO_C" >&6
+ cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+-#include "confdefs.h"
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
+ #include <sys/dg_sys_info.h>
+ _ACEOF
+ if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+- egrep -v '^ *\+' conftest.er1 >conftest.err
++ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+@@ -8629,7 +8935,8 @@
+ ac_header_preproc=yes
+ else
+ echo "$as_me: failed program was:" >&5
+- cat conftest.$ac_ext >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
+ ac_header_preproc=no
+ fi
+ rm -f conftest.err conftest.$ac_ext
+@@ -8642,14 +8949,32 @@
+ { echo "$as_me:$LINENO: WARNING: sys/dg_sys_info.h: accepted by the compiler, rejected by the preprocessor!" >&5
+ echo "$as_me: WARNING: sys/dg_sys_info.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: sys/dg_sys_info.h: proceeding with the preprocessor's result" >&5
+-echo "$as_me: WARNING: sys/dg_sys_info.h: proceeding with the preprocessor's result" >&2;};;
++echo "$as_me: WARNING: sys/dg_sys_info.h: proceeding with the preprocessor's result" >&2;}
++ (
++ cat <<\_ASBOX
++## ------------------------------------ ##
++## Report this to bug-autoconf@gnu.org. ##
++## ------------------------------------ ##
++_ASBOX
++ ) |
++ sed "s/^/$as_me: WARNING: /" >&2
++ ;;
+ no:yes )
+ { echo "$as_me:$LINENO: WARNING: sys/dg_sys_info.h: present but cannot be compiled" >&5
+ echo "$as_me: WARNING: sys/dg_sys_info.h: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: sys/dg_sys_info.h: check for missing prerequisite headers?" >&5
+ echo "$as_me: WARNING: sys/dg_sys_info.h: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: sys/dg_sys_info.h: proceeding with the preprocessor's result" >&5
+-echo "$as_me: WARNING: sys/dg_sys_info.h: proceeding with the preprocessor's result" >&2;};;
++echo "$as_me: WARNING: sys/dg_sys_info.h: proceeding with the preprocessor's result" >&2;}
++ (
++ cat <<\_ASBOX
++## ------------------------------------ ##
++## Report this to bug-autoconf@gnu.org. ##
++## ------------------------------------ ##
++_ASBOX
++ ) |
++ sed "s/^/$as_me: WARNING: /" >&2
++ ;;
+ esac
+ echo "$as_me:$LINENO: checking for sys/dg_sys_info.h" >&5
+ echo $ECHO_N "checking for sys/dg_sys_info.h... $ECHO_C" >&6
+@@ -8880,8 +9205,8 @@
+ fi
+
+
+-ac_config_files="$ac_config_files Makefile doc/Makefile include/Makefile"
+-ac_config_commands="$ac_config_commands default"
++ ac_config_files="$ac_config_files Makefile doc/Makefile include/Makefile"
++ ac_config_commands="$ac_config_commands default"
+ cat >confcache <<\_ACEOF
+ # This file is a shell script that caches the results of configure
+ # tests run on this system so they can be shared between configure
+@@ -8892,7 +9217,7 @@
+ # config.status only pays attention to the cache file if you give it
+ # the --recheck option to rerun configure.
+ #
+-# `ac_cv_env_foo' variables (set or unset) will be overriden when
++# `ac_cv_env_foo' variables (set or unset) will be overridden when
+ # loading this file, other *unset* `ac_cv_foo' will be assigned the
+ # following values.
+
+@@ -8927,7 +9252,7 @@
+ t end
+ /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+ : end' >>confcache
+-if cmp -s $cache_file confcache; then :; else
++if diff $cache_file confcache >/dev/null 2>&1; then :; else
+ if test -w $cache_file; then
+ test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
+ cat confcache >$cache_file
+@@ -8989,6 +9314,21 @@
+ rm -f confdef2opt.sed
+
+
++ac_libobjs=
++ac_ltlibobjs=
++for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
++ # 1. Remove the extension, and $U if already installed.
++ ac_i=`echo "$ac_i" |
++ sed 's/\$U\././;s/\.o$//;s/\.obj$//'`
++ # 2. Add them.
++ ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext"
++ ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo'
++done
++LIBOBJS=$ac_libobjs
++
++LTLIBOBJS=$ac_ltlibobjs
++
++
+ if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then
+ { { echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined.
+ Usually this means the macro was only invoked conditionally." >&5
+@@ -9038,11 +9378,12 @@
+ # configure, is in config.log if it exists.
+
+ debug=false
++ac_cs_recheck=false
++ac_cs_silent=false
+ SHELL=\${CONFIG_SHELL-$SHELL}
+ _ACEOF
+
+ cat >>$CONFIG_STATUS <<\_ACEOF
+-
+ ## --------------------- ##
+ ## M4sh Initialization. ##
+ ## --------------------- ##
+@@ -9051,11 +9392,13 @@
+ if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
++ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
++ # is contrary to our usage. Disable this feature.
++ alias -g '${1+"$@"}'='"$@"'
+ elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+ set -o posix
+ fi
+
+-# NLS nuisances.
+ # Support unset when possible.
+ if (FOO=FOO; unset FOO) >/dev/null 2>&1; then
+ as_unset=unset
+@@ -9063,34 +9406,42 @@
+ as_unset=false
+ fi
+
+-(set +x; test -n "`(LANG=C; export LANG) 2>&1`") &&
+- { $as_unset LANG || test "${LANG+set}" != set; } ||
+- { LANG=C; export LANG; }
+-(set +x; test -n "`(LC_ALL=C; export LC_ALL) 2>&1`") &&
+- { $as_unset LC_ALL || test "${LC_ALL+set}" != set; } ||
+- { LC_ALL=C; export LC_ALL; }
+-(set +x; test -n "`(LC_TIME=C; export LC_TIME) 2>&1`") &&
+- { $as_unset LC_TIME || test "${LC_TIME+set}" != set; } ||
+- { LC_TIME=C; export LC_TIME; }
+-(set +x; test -n "`(LC_CTYPE=C; export LC_CTYPE) 2>&1`") &&
+- { $as_unset LC_CTYPE || test "${LC_CTYPE+set}" != set; } ||
+- { LC_CTYPE=C; export LC_CTYPE; }
+-(set +x; test -n "`(LANGUAGE=C; export LANGUAGE) 2>&1`") &&
+- { $as_unset LANGUAGE || test "${LANGUAGE+set}" != set; } ||
+- { LANGUAGE=C; export LANGUAGE; }
+-(set +x; test -n "`(LC_COLLATE=C; export LC_COLLATE) 2>&1`") &&
+- { $as_unset LC_COLLATE || test "${LC_COLLATE+set}" != set; } ||
+- { LC_COLLATE=C; export LC_COLLATE; }
+-(set +x; test -n "`(LC_NUMERIC=C; export LC_NUMERIC) 2>&1`") &&
+- { $as_unset LC_NUMERIC || test "${LC_NUMERIC+set}" != set; } ||
+- { LC_NUMERIC=C; export LC_NUMERIC; }
+-(set +x; test -n "`(LC_MESSAGES=C; export LC_MESSAGES) 2>&1`") &&
+- { $as_unset LC_MESSAGES || test "${LC_MESSAGES+set}" != set; } ||
+- { LC_MESSAGES=C; export LC_MESSAGES; }
++
++# Work around bugs in pre-3.0 UWIN ksh.
++$as_unset ENV MAIL MAILPATH
++PS1='$ '
++PS2='> '
++PS4='+ '
++
++# NLS nuisances.
++for as_var in \
++ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
++ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
++ LC_TELEPHONE LC_TIME
++do
++ if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then
++ eval $as_var=C; export $as_var
++ else
++ $as_unset $as_var
++ fi
++done
++
++# Required to use basename.
++if expr a : '\(a\)' >/dev/null 2>&1; then
++ as_expr=expr
++else
++ as_expr=false
++fi
++
++if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
++ as_basename=basename
++else
++ as_basename=false
++fi
+
+
+ # Name of the executable.
+-as_me=`(basename "$0") 2>/dev/null ||
++as_me=`$as_basename "$0" ||
+ $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)$' \| \
+@@ -9101,6 +9452,7 @@
+ /^X\/\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+
++
+ # PATH needs CR, and LINENO needs CR and PATH.
+ # Avoid depending upon Character Ranges.
+ as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+@@ -9111,15 +9463,15 @@
+
+ # The user is always right.
+ if test "${PATH_SEPARATOR+set}" != set; then
+- echo "#! /bin/sh" >conftest.sh
+- echo "exit 0" >>conftest.sh
+- chmod +x conftest.sh
+- if (PATH=".;."; conftest.sh) >/dev/null 2>&1; then
++ echo "#! /bin/sh" >conf$$.sh
++ echo "exit 0" >>conf$$.sh
++ chmod +x conf$$.sh
++ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+ PATH_SEPARATOR=';'
+ else
+ PATH_SEPARATOR=:
+ fi
+- rm -f conftest.sh
++ rm -f conf$$.sh
+ fi
+
+
+@@ -9168,6 +9520,8 @@
+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then
++ $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
++ $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+ CONFIG_SHELL=$as_dir/$as_base
+ export CONFIG_SHELL
+ exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+@@ -9241,6 +9595,12 @@
+ fi
+ rm -f conf$$ conf$$.exe conf$$.file
+
++if mkdir -p . 2>/dev/null; then
++ as_mkdir_p=:
++else
++ as_mkdir_p=false
++fi
++
+ as_executable_p="test -f"
+
+ # Sed expression to map a string onto a valid CPP name.
+@@ -9257,7 +9617,7 @@
+ IFS=" $as_nl"
+
+ # CDPATH.
+-$as_unset CDPATH || test "${CDPATH+set}" != set || { CDPATH=$PATH_SEPARATOR; export CDPATH; }
++$as_unset CDPATH
+
+ exec 6>&1
+
+@@ -9274,7 +9634,7 @@
+ cat >&5 <<_CSEOF
+
+ This file was extended by gc $as_me 6.3alpha2, which was
+-generated by GNU Autoconf 2.53. Invocation command line was
++generated by GNU Autoconf 2.57. Invocation command line was
+
+ CONFIG_FILES = $CONFIG_FILES
+ CONFIG_HEADERS = $CONFIG_HEADERS
+@@ -9314,6 +9674,7 @@
+
+ -h, --help print this help, then exit
+ -V, --version print version number, then exit
++ -q, --quiet do not print progress messages
+ -d, --debug don't remove temporary files
+ --recheck update $as_me by reconfiguring in the same conditions
+ --file=FILE[:TEMPLATE]
+@@ -9331,7 +9692,7 @@
+ cat >>$CONFIG_STATUS <<_ACEOF
+ ac_cs_version="\\
+ gc config.status 6.3alpha2
+-configured by $0, generated by GNU Autoconf 2.53,
++configured by $0, generated by GNU Autoconf 2.57,
+ with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
+
+ Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001
+@@ -9352,25 +9713,25 @@
+ --*=*)
+ ac_option=`expr "x$1" : 'x\([^=]*\)='`
+ ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
+- shift
+- set dummy "$ac_option" "$ac_optarg" ${1+"$@"}
+- shift
++ ac_shift=:
++ ;;
++ -*)
++ ac_option=$1
++ ac_optarg=$2
++ ac_shift=shift
+ ;;
+- -*);;
+ *) # This is not an option, so the user has probably given explicit
+ # arguments.
++ ac_option=$1
+ ac_need_defaults=false;;
+ esac
+
+- case $1 in
++ case $ac_option in
+ # Handling of the options.
+ _ACEOF
+-cat >>$CONFIG_STATUS <<_ACEOF
+- -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+- echo "running $SHELL $0 " $ac_configure_args " --no-create --no-recursion"
+- exec $SHELL $0 $ac_configure_args --no-create --no-recursion ;;
+-_ACEOF
+ cat >>$CONFIG_STATUS <<\_ACEOF
++ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
++ ac_cs_recheck=: ;;
+ --version | --vers* | -V )
+ echo "$ac_cs_version"; exit 0 ;;
+ --he | --h)
+@@ -9385,13 +9746,16 @@
+ --debug | --d* | -d )
+ debug=: ;;
+ --file | --fil | --fi | --f )
+- shift
+- CONFIG_FILES="$CONFIG_FILES $1"
++ $ac_shift
++ CONFIG_FILES="$CONFIG_FILES $ac_optarg"
+ ac_need_defaults=false;;
+ --header | --heade | --head | --hea )
+- shift
+- CONFIG_HEADERS="$CONFIG_HEADERS $1"
++ $ac_shift
++ CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
+ ac_need_defaults=false;;
++ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
++ | -silent | --silent | --silen | --sile | --sil | --si | --s)
++ ac_cs_silent=: ;;
+
+ # This is an error.
+ -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
+@@ -9406,6 +9770,20 @@
+ shift
+ done
+
++ac_configure_extra_args=
++
++if $ac_cs_silent; then
++ exec 6>/dev/null
++ ac_configure_extra_args="$ac_configure_extra_args --silent"
++fi
++
++_ACEOF
++cat >>$CONFIG_STATUS <<_ACEOF
++if \$ac_cs_recheck; then
++ echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
++ exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
++fi
++
+ _ACEOF
+
+ cat >>$CONFIG_STATUS <<_ACEOF
+@@ -9450,6 +9828,9 @@
+ test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
+ fi
+
++# Have a temporary directory for convenience. Make it in the build tree
++# simply because there is no reason to put it here, and in addition,
++# creating and moving files from /tmp can sometimes cause problems.
+ # Create a temporary directory, and hook for its removal unless debugging.
+ $debug ||
+ {
+@@ -9458,17 +9839,17 @@
+ }
+
+ # Create a (secure) tmp directory for tmp files.
+-: ${TMPDIR=/tmp}
++
+ {
+- tmp=`(umask 077 && mktemp -d -q "$TMPDIR/csXXXXXX") 2>/dev/null` &&
++ tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` &&
+ test -n "$tmp" && test -d "$tmp"
+ } ||
+ {
+- tmp=$TMPDIR/cs$$-$RANDOM
++ tmp=./confstat$$-$RANDOM
+ (umask 077 && mkdir $tmp)
+ } ||
+ {
+- echo "$me: cannot create a temporary directory in $TMPDIR" >&2
++ echo "$me: cannot create a temporary directory in ." >&2
+ { (exit 1); exit 1; }
+ }
+
+@@ -9590,10 +9971,13 @@
+ s,@LN_S@,$LN_S,;t t
+ s,@ECHO@,$ECHO,;t t
+ s,@CPP@,$CPP,;t t
++s,@EGREP@,$EGREP,;t t
+ s,@LIBTOOL@,$LIBTOOL,;t t
+ s,@MY_CFLAGS@,$MY_CFLAGS,;t t
+ s,@USE_LIBDIR_TRUE@,$USE_LIBDIR_TRUE,;t t
+ s,@USE_LIBDIR_FALSE@,$USE_LIBDIR_FALSE,;t t
++s,@LIBOBJS@,$LIBOBJS,;t t
++s,@LTLIBOBJS@,$LTLIBOBJS,;t t
+ CEOF
+
+ _ACEOF
+@@ -9664,25 +10048,30 @@
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+- { case "$ac_dir" in
+- [\\/]* | ?:[\\/]* ) as_incr_dir=;;
+- *) as_incr_dir=.;;
+-esac
+-as_dummy="$ac_dir"
+-for as_mkdir_dir in `IFS='/\\'; set X $as_dummy; shift; echo "$@"`; do
+- case $as_mkdir_dir in
+- # Skip DOS drivespec
+- ?:) as_incr_dir=$as_mkdir_dir ;;
+- *)
+- as_incr_dir=$as_incr_dir/$as_mkdir_dir
+- test -d "$as_incr_dir" ||
+- mkdir "$as_incr_dir" ||
+- { { echo "$as_me:$LINENO: error: cannot create \"$ac_dir\"" >&5
+-echo "$as_me: error: cannot create \"$ac_dir\"" >&2;}
+- { (exit 1); exit 1; }; }
+- ;;
+- esac
+-done; }
++ { if $as_mkdir_p; then
++ mkdir -p "$ac_dir"
++ else
++ as_dir="$ac_dir"
++ as_dirs=
++ while test ! -d "$as_dir"; do
++ as_dirs="$as_dir $as_dirs"
++ as_dir=`(dirname "$as_dir") 2>/dev/null ||
++$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
++ X"$as_dir" : 'X\(//\)[^/]' \| \
++ X"$as_dir" : 'X\(//\)$' \| \
++ X"$as_dir" : 'X\(/\)' \| \
++ . : '\(.\)' 2>/dev/null ||
++echo X"$as_dir" |
++ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
++ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
++ /^X\(\/\/\)$/{ s//\1/; q; }
++ /^X\(\/\).*/{ s//\1/; q; }
++ s/.*/./; q'`
++ done
++ test ! -n "$as_dirs" || mkdir $as_dirs
++ fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
++echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
++ { (exit 1); exit 1; }; }; }
+
+ ac_builddir=.
+
+@@ -9712,7 +10101,7 @@
+ # Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be
+ # absolute.
+ ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd`
+-ac_abs_top_builddir=`cd "$ac_dir" && cd $ac_top_builddir && pwd`
++ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd`
+ ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd`
+ ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd`
+
+@@ -9842,7 +10231,7 @@
+ # Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be
+ # absolute.
+ ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd`
+-ac_abs_top_builddir=`cd "$ac_dir" && cd $ac_top_builddir && pwd`
++ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd`
+ ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd`
+ ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd`
+
+@@ -9911,25 +10300,30 @@
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+- { case $dirpart/$fdir in
+- [\\/]* | ?:[\\/]* ) as_incr_dir=;;
+- *) as_incr_dir=.;;
+-esac
+-as_dummy=$dirpart/$fdir
+-for as_mkdir_dir in `IFS='/\\'; set X $as_dummy; shift; echo "$@"`; do
+- case $as_mkdir_dir in
+- # Skip DOS drivespec
+- ?:) as_incr_dir=$as_mkdir_dir ;;
+- *)
+- as_incr_dir=$as_incr_dir/$as_mkdir_dir
+- test -d "$as_incr_dir" ||
+- mkdir "$as_incr_dir" ||
+- { { echo "$as_me:$LINENO: error: cannot create $dirpart/$fdir" >&5
+-echo "$as_me: error: cannot create $dirpart/$fdir" >&2;}
+- { (exit 1); exit 1; }; }
+- ;;
+- esac
+-done; }
++ { if $as_mkdir_p; then
++ mkdir -p $dirpart/$fdir
++ else
++ as_dir=$dirpart/$fdir
++ as_dirs=
++ while test ! -d "$as_dir"; do
++ as_dirs="$as_dir $as_dirs"
++ as_dir=`(dirname "$as_dir") 2>/dev/null ||
++$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
++ X"$as_dir" : 'X\(//\)[^/]' \| \
++ X"$as_dir" : 'X\(//\)$' \| \
++ X"$as_dir" : 'X\(/\)' \| \
++ . : '\(.\)' 2>/dev/null ||
++echo X"$as_dir" |
++ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
++ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
++ /^X\(\/\/\)$/{ s//\1/; q; }
++ /^X\(\/\).*/{ s//\1/; q; }
++ s/.*/./; q'`
++ done
++ test ! -n "$as_dirs" || mkdir $as_dirs
++ fi || { { echo "$as_me:$LINENO: error: cannot create directory $dirpart/$fdir" >&5
++echo "$as_me: error: cannot create directory $dirpart/$fdir" >&2;}
++ { (exit 1); exit 1; }; }; }
+
+ # echo "creating $dirpart/$file"
+ echo '# dummy' > "$dirpart/$file"
+@@ -9958,8 +10352,11 @@
+ # need to make the FD available again.
+ if test "$no_create" != yes; then
+ ac_cs_success=:
++ ac_config_status_args=
++ test "$silent" = yes &&
++ ac_config_status_args="$ac_config_status_args --quiet"
+ exec 5>/dev/null
+- $SHELL $CONFIG_STATUS || ac_cs_success=false
++ $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+ exec 5>>config.log
+ # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+ # would make configure fail if this is the last instruction.
+diff -ruN ../gc6.3alpha2/configure.in ./configure.in
+--- ../gc6.3alpha2/configure.in Mon Sep 29 14:13:34 2003
++++ ./configure.in Wed Nov 19 04:17:15 2003
+@@ -275,6 +275,10 @@
+ ;;
+ mips*-*-linux*)
+ ;;
++ mips-unknown-elf*)
++ machdep="mips2java_mach_dep.lo"
++ AC_DEFINE(MIPS2JAVA)
++ ;;
+ mips-*-*)
+ machdep="mips_sgi_mach_dep.lo"
+ AC_DEFINE(NO_EXECUTE_PERMISSION)
+diff -ruN ../gc6.3alpha2/include/private/gcconfig.h ./include/private/gcconfig.h
+--- ../gc6.3alpha2/include/private/gcconfig.h Wed Sep 3 14:16:01 2003
++++ ./include/private/gcconfig.h Wed Nov 19 04:47:25 2003
+@@ -115,7 +115,7 @@
+ # if defined(nec_ews) || defined(_nec_ews)
+ # define EWS4800
+ # endif
+-# if !defined(LINUX) && !defined(EWS4800)
++# if !defined(LINUX) && !defined(EWS4800) && !defined(MIPS2JAVA)
+ # if defined(ultrix) || defined(__ultrix) || defined(__NetBSD__)
+ # define ULTRIX
+ # else
+@@ -1236,6 +1236,16 @@
+
+ # ifdef MIPS
+ # define MACH_TYPE "MIPS"
++
++# ifdef MIPS2JAVA
++extern int _etext[];
++extern int _end[];
++# define ALIGNMENT 4
++# define STACKBOTTOM 0x10000000
++# define DATASTART (_etext)
++# define DATAEND (_end)
++# endif /* MIPS2JAVA */
++
+ # ifdef LINUX
+ /* This was developed for a linuxce style platform. Probably */
+ /* needs to be tweaked for workstation class machines. */
+diff -ruN ../gc6.3alpha2/mips2java_mach_dep.s ./mips2java_mach_dep.s
+--- ../gc6.3alpha2/mips2java_mach_dep.s Wed Dec 31 19:00:00 1969
++++ ./mips2java_mach_dep.s Wed Nov 19 04:56:28 2003
+@@ -0,0 +1,43 @@
++ .set noreorder
++ .text
++ .align 2
++ .globl GC_push_regs
++ .ent GC_push_regs
++GC_push_regs:
++ subu $sp,$sp,24
++ sw $31,20($sp)
++
++ jal GC_push_one
++ move $4,$1
++ jal GC_push_one
++ move $4,$16
++ jal GC_push_one
++ move $4,$17
++ jal GC_push_one
++ move $4,$18
++ jal GC_push_one
++ move $4,$19
++ jal GC_push_one
++ move $4,$20
++ jal GC_push_one
++ move $4,$21
++ jal GC_push_one
++ move $4,$22
++ jal GC_push_one
++ move $4,$23
++ jal GC_push_one
++ move $4,$26
++ jal GC_push_one
++ move $4,$27
++ jal GC_push_one
++ move $4,$28
++ jal GC_push_one
++ move $4,$29
++ jal GC_push_one
++ move $4,$30
++
++ lw $31,20($sp)
++ j $31
++ addu $sp,$sp,24
++
++ .end GC_push_regs
+diff -ruN ../gc6.3alpha2/os_dep.c ./os_dep.c
+--- ../gc6.3alpha2/os_dep.c Mon Sep 22 18:49:47 2003
++++ ./os_dep.c Wed Nov 19 04:12:13 2003
+@@ -497,7 +497,7 @@
+ # if !defined(PCR) && !defined(AMIGA) && !defined(MSWIN32) \
+ && !defined(MSWINCE) \
+ && !defined(MACOS) && !defined(DJGPP) && !defined(DOS4GW) \
+- && !defined(NOSYS) && !defined(ECOS)
++ && !defined(NOSYS) && !defined(ECOS) && !defined(MIPS2JAVA) \
+
+ # if defined(sigmask) && !defined(UTS4) && !defined(HURD)
+ /* Use the traditional BSD interface */
--- /dev/null
+Only in .: BusyBox.class
+Only in .: BusyBox.java
+diff -ur ../busybox-0.60.5/Config.h ./Config.h
+--- ../busybox-0.60.5/Config.h Tue Sep 17 18:04:28 2002
++++ ./Config.h Tue Nov 25 11:05:07 2003
+@@ -12,95 +12,95 @@
+ #define BB_ASH
+ #define BB_BASENAME
+ #define BB_CAT
+-#define BB_CHGRP
+-#define BB_CHMOD
+-#define BB_CHOWN
+-#define BB_CHROOT
+-#define BB_CHVT
++//#define BB_CHGRP
++//#define BB_CHMOD
++//#define BB_CHOWN
++//#define BB_CHROOT
++//#define BB_CHVT
+ #define BB_CLEAR
+-//#define BB_CMP
+-#define BB_CP
++#define BB_CMP
++//#define BB_CP
+ //#define BB_CPIO
+ #define BB_CUT
+ #define BB_DATE
+ //#define BB_DC
+-#define BB_DD
++//#define BB_DD
+ //#define BB_DEALLOCVT
+-#define BB_DF
++//#define BB_DF
+ #define BB_DIRNAME
+-#define BB_DMESG
++//#define BB_DMESG
+ //#define BB_DOS2UNIX
+ //#define BB_DPKG
+ //#define BB_DPKG_DEB
+ //#define BB_DUTMP
+-#define BB_DU
++//#define BB_DU
+ //#define BB_DUMPKMAP
+ #define BB_ECHO
+-#define BB_ENV
++//#define BB_ENV
+ //#define BB_EXPR
+ //#define BB_FBSET
+ //#define BB_FDFLUSH
+-#define BB_FIND
+-#define BB_FREE
++//#define BB_FIND
++//#define BB_FREE
+ //#define BB_FREERAMDISK
+ //#define BB_FSCK_MINIX
+ //#define BB_GETOPT
+ #define BB_GREP
+-#define BB_GUNZIP
++//#define BB_GUNZIP
+ #define BB_GZIP
+-#define BB_HALT
++//#define BB_HALT
+ #define BB_HEAD
+ //#define BB_HOSTID
+ //#define BB_HOSTNAME
+ //#define BB_HUSH
+-#define BB_ID
++//#define BB_ID
+ //#define BB_IFCONFIG
+-#define BB_INIT
++//#define BB_INIT
+ //#define BB_INSMOD
+-#define BB_KILL
+-#define BB_KILLALL
+-#define BB_KLOGD
++//#define BB_KILL
++//#define BB_KILLALL
++//#define BB_KLOGD
+ //#define BB_LASH
+ //#define BB_LENGTH
+-#define BB_LN
++//#define BB_LN
+ //#define BB_LOADACM
+ //#define BB_LOADFONT
+ //#define BB_LOADKMAP
+-#define BB_LOGGER
++//#define BB_LOGGER
+ //#define BB_LOGNAME
+ //#define BB_LOSETUP
+ #define BB_LS
+-#define BB_LSMOD
++//#define BB_LSMOD
+ //#define BB_MAKEDEVS
+-//#define BB_MD5SUM
++#define BB_MD5SUM
+ #define BB_MKDIR
+ //#define BB_MKFIFO
+ //#define BB_MKFS_MINIX
+-#define BB_MKNOD
+-#define BB_MKSWAP
++//#define BB_MKNOD
++//#define BB_MKSWAP
+ //#define BB_MKTEMP
+-#define BB_MODPROBE
+-#define BB_MORE
+-#define BB_MOUNT
++//#define BB_MODPROBE
++//#define BB_MORE
++//#define BB_MOUNT
+ //#define BB_MSH
+ //#define BB_MT
+-#define BB_MV
++//#define BB_MV
+ //#define BB_NC
+ //#define BB_NSLOOKUP
+-#define BB_PIDOF
++//#define BB_PIDOF
+ //#define BB_PING
+ //#define BB_PIVOT_ROOT
+-#define BB_POWEROFF
+-//#define BB_PRINTF
+-#define BB_PS
+-#define BB_PWD
++//#define BB_POWEROFF
++#define BB_PRINTF
++//#define BB_PS
++//#define BB_PWD
+ //#define BB_RDATE
+ //#define BB_READLINK
+-#define BB_REBOOT
++//#define BB_REBOOT
+ //#define BB_RENICE
+ #define BB_RESET
+-#define BB_RM
+-#define BB_RMDIR
++//#define BB_RM
++//#define BB_RMDIR
+ //#define BB_RMMOD
+ //#define BB_ROUTE
+ //#define BB_RPM2CPIO
+@@ -109,13 +109,13 @@
+ #define BB_SLEEP
+ #define BB_SORT
+ //#define BB_STTY
+-#define BB_SWAPONOFF
+-#define BB_SYNC
+-#define BB_SYSLOGD
++//#define BB_SWAPONOFF
++//#define BB_SYNC
++//#define BB_SYSLOGD
+ #define BB_TAIL
+-#define BB_TAR
+-//#define BB_TEE
+-//#define BB_TEST
++//#define BB_TAR
++#define BB_TEE
++#define BB_TEST
+ //#define BB_TELNET
+ //#define BB_TFTP
+ //#define BB_TIME
+@@ -124,15 +124,15 @@
+ //#define BB_TR
+ //#define BB_TRACEROUTE
+ #define BB_TRUE_FALSE
+-#define BB_TTY
++//#define BB_TTY
+ //#define BB_UNIX2DOS
+ //#define BB_UUENCODE
+ //#define BB_UUDECODE
+-#define BB_UMOUNT
++//#define BB_UMOUNT
+ #define BB_UNIQ
+-#define BB_UNAME
++//#define BB_UNAME
+ //#define BB_UPDATE
+-#define BB_UPTIME
++//#define BB_UPTIME
+ //#define BB_USLEEP
+ //#define BB_VI
+ //#define BB_WATCHDOG
+@@ -140,7 +140,7 @@
+ //#define BB_WGET
+ #define BB_WHICH
+ #define BB_WHOAMI
+-#define BB_XARGS
++//#define BB_XARGS
+ #define BB_YES
+ // End of Applications List
+ //
+@@ -182,13 +182,13 @@
+ //#define BB_FEATURE_USE_DEVPS_PATCH
+ //
+ // show verbose usage messages
+-#define BB_FEATURE_VERBOSE_USAGE
++//#define BB_FEATURE_VERBOSE_USAGE
+ //
+ // Use termios to manipulate the screen ('more' is prettier with this on)
+ //#define BB_FEATURE_USE_TERMIOS
+ //
+ // calculate terminal & column widths (for more, ls, and telnet)
+-#define BB_FEATURE_AUTOWIDTH
++//#define BB_FEATURE_AUTOWIDTH
+ //
+ // show username/groupnames for ls
+ #define BB_FEATURE_LS_USERNAME
+@@ -271,11 +271,11 @@
+ //
+ // Enable command line editing in the shell.
+ // Only relevant if a shell is enabled. On by default.
+-#define BB_FEATURE_COMMAND_EDITING
++//#define BB_FEATURE_COMMAND_EDITING
+ //
+ // Enable tab completion in the shell. This is now working quite nicely.
+ // This feature adds a bit over 4k. Only relevant if a shell is enabled.
+-#define BB_FEATURE_COMMAND_TAB_COMPLETION
++//#define BB_FEATURE_COMMAND_TAB_COMPLETION
+ //
+ // Attempts to match usernames in a ~-prefixed path
+ //#define BB_FEATURE_COMMAND_USERNAME_COMPLETION
+@@ -284,7 +284,7 @@
+ //were shell builtins. Nice for staticly linking an emergency rescue shell,
+ //among other things. Off by default.
+ // Only relevant if a shell is enabled.
+-//#define BB_FEATURE_SH_STANDALONE_SHELL
++#define BB_FEATURE_SH_STANDALONE_SHELL
+ //
+ //When this is enabled, busybox shell applets can be called using full path
+ //names. This causes applets (i.e., most busybox commands) to override
+@@ -306,7 +306,7 @@
+ // are doing is running scripts). Disabing this is bad for interactive
+ // use, since when you hit ^C in an application, it will also kill the
+ // shell. This adds about 2.5k on an x86 system.
+-#define BB_FEATURE_ASH_JOB_CONTROL
++//#define BB_FEATURE_ASH_JOB_CONTROL
+ //
+ //Turn on extra fbset options
+ //#define BB_FEATURE_FBSET_FANCY
+@@ -371,7 +371,7 @@
+ #define BB_FEATURE_FIND_TYPE
+ //
+ // Support for the find -perm option.
+-#define BB_FEATURE_FIND_PERM
++//#define BB_FEATURE_FIND_PERM
+ //
+ // Support for the find -mtime option.
+ #define BB_FEATURE_FIND_MTIME
+@@ -420,7 +420,10 @@
+ // Nothing beyond this point should ever be touched by
+ // mere mortals so leave this stuff alone.
+ //
++#ifdef _GNU_SOURCE
+ #include <features.h>
++#endif
++
+ #if defined(__uClinux__)
+ #undef BB_ASH /* Not even a chance it will work */
+ #undef BB_RPM2CPIO /* Uses gz_open(), which uses fork() */
+diff -ur ../busybox-0.60.5/Makefile ./Makefile
+--- ../busybox-0.60.5/Makefile Sun Oct 27 00:47:54 2002
++++ ./Makefile Tue Nov 25 11:27:30 2003
+@@ -49,7 +49,7 @@
+ # just 1.4k to the binary size (which is a _lot_ less then glibc NSS costs).
+ # Note that if you want hostname resolution to work with glibc, you still need
+ # the libnss_* libraries.
+-USE_SYSTEM_PWD_GRP = true
++USE_SYSTEM_PWD_GRP = false
+
+ # This enables compiling with dmalloc ( http://dmalloc.com/ )
+ # which is an excellent public domain mem leak and malloc problem
+@@ -83,7 +83,7 @@
+
+ # If you are running a cross compiler, you may want to set this
+ # to something more interesting, like "powerpc-linux-".
+-CROSS =
++CROSS = mips-unknown-elf-
+ CC = $(CROSS)gcc
+ AR = $(CROSS)ar
+ STRIP = $(CROSS)strip
+@@ -106,11 +106,11 @@
+ #
+ # For other libraries, you are on your own...
+ #LDFLAGS+=-nostdlib
+-#LIBRARIES = $(LIBCDIR)/lib/libc.a -lgcc
++LIBRARIES = -lglob -lregex
+ #CROSS_CFLAGS+=-nostdinc -I$(LIBCDIR)/include -I$(GCCINCDIR)
+ #GCCINCDIR = $(shell gcc -print-search-dirs | sed -ne "s/install: \(.*\)/\1include/gp")
+
+-WARNINGS = -Wall -Wshadow
++WARNINGS = -Wall -Wshadow -Werror -Wno-unused
+
+ ARFLAGS = -r
+
+@@ -181,9 +181,9 @@
+ LDFLAGS += -Wl,-warn-common
+ STRIPCMD = /bin/true -Since_we_are_debugging
+ else
+- CFLAGS += $(WARNINGS) $(OPTIMIZATIONS) -D_GNU_SOURCE
+- LDFLAGS += -s -Wl,-warn-common
+- STRIPCMD = $(STRIP) -s --remove-section=.note --remove-section=.comment
++ CFLAGS += $(WARNINGS) $(OPTIMIZATIONS) -DNEWLIB_ASH
++ LDFLAGS += -Wl,-warn-common
++ STRIPCMD = true
+ endif
+ ifeq ($(strip $(DOSTATIC)),true)
+ LDFLAGS += --static
+@@ -260,7 +260,7 @@
+ PWD_LIB = libpwd.a
+ PWD_CSRC=__getpwent.c pwent.c getpwnam.c getpwuid.c putpwent.c getpw.c \
+ fgetpwent.c __getgrent.c grent.c getgrnam.c getgrgid.c fgetgrent.c \
+- initgroups.c setgroups.c
++ initgroups.c
+ PWD_OBJS=$(patsubst %.c,$(PWD_GRP)/%.o, $(PWD_CSRC))
+ ifneq ($(strip $(BB_SRC_DIR)),)
+ PWD_CFLAGS = -I- -I.
+@@ -273,19 +273,19 @@
+ LIBBB = libbb
+ LIBBB_LIB = libbb.a
+ LIBBB_CSRC= ask_confirmation.c chomp.c concat_path_file.c copy_file.c \
+-copy_file_chunk.c libc5.c device_open.c error_msg.c inode_hash.c \
+-error_msg_and_die.c fgets_str.c find_mount_point.c find_pid_by_name.c \
+-find_root_device.c full_read.c full_write.c get_console.c \
++copy_file_chunk.c device_open.c error_msg.c inode_hash.c \
++error_msg_and_die.c fgets_str.c find_pid_by_name.c \
++find_root_device.c full_read.c full_write.c \
+ get_last_path_component.c get_line_from_file.c gz_open.c human_readable.c \
+-isdirectory.c kernel_version.c loop.c mode_string.c module_syscalls.c mtab.c \
++isdirectory.c mode_string.c \
+ mtab_file.c my_getgrnam.c my_getgrgid.c my_getpwnam.c my_getpwnamegid.c \
+ my_getpwuid.c parse_mode.c parse_number.c perror_msg.c perror_msg_and_die.c \
+ print_file.c process_escape_sequence.c read_package_field.c recursive_action.c \
+-safe_read.c safe_strncpy.c syscalls.c syslog_msg_with_name.c time_string.c \
++safe_read.c safe_strncpy.c time_string.c \
+ trim.c unzip.c vdprintf.c verror_msg.c vperror_msg.c wfopen.c xfuncs.c \
+-xgetcwd.c xreadlink.c xregcomp.c interface.c remove_file.c last_char_is.c \
+-copyfd.c vherror_msg.c herror_msg.c herror_msg_and_die.c xgethostbyname.c \
+-dirname.c make_directory.c create_icmp_socket.c u_signal_names.c arith.c \
++xgetcwd.c xreadlink.c xregcomp.c remove_file.c last_char_is.c \
++copyfd.c herror_msg.c herror_msg_and_die.c \
++dirname.c make_directory.c u_signal_names.c arith.c \
+ simplify_path.c
+ LIBBB_OBJS=$(patsubst %.c,$(LIBBB)/%.o, $(LIBBB_CSRC))
+ ifeq ($(strip $(BB_SRC_DIR)),)
+diff -ur ../busybox-0.60.5/ash.c ./ash.c
+--- ../busybox-0.60.5/ash.c Tue Oct 22 18:14:29 2002
++++ ./ash.c Tue Nov 25 11:17:08 2003
+@@ -84,11 +84,15 @@
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
++#ifndef NEWLIB_ASH
+ #include <sysexits.h>
++#endif
+ #include <unistd.h>
+ #include <sys/stat.h>
+ #include <sys/cdefs.h>
++#ifndef NEWLIB_ASH
+ #include <sys/ioctl.h>
++#endif
+ #include <sys/param.h>
+ #include <sys/resource.h>
+ #include <sys/time.h>
+@@ -268,6 +272,7 @@
+ * more fun than worrying about efficiency and portability. :-))
+ */
+
++#ifndef NEWLIB_ASH
+ static void onint(void);
+ static volatile int suppressint;
+ static volatile int intpending;
+@@ -287,6 +292,16 @@
+ #define CLEAR_PENDING_INT intpending = 0
+ #define int_pending() intpending
+
++#else
++
++#define INTON
++#define INTOFF
++#define FORCEINTON
++#define CLEAR_PENDING_INT
++#define int_pending() 0
++
++#endif
++
+
+ typedef void *pointer;
+
+@@ -1556,7 +1571,9 @@
+ #endif
+ static int unsetcmd(int, char **);
+ static int waitcmd(int, char **);
++#ifndef NEWLIB_ASH
+ static int ulimitcmd(int, char **);
++#endif
+ static int timescmd(int, char **);
+
+ #ifdef CONFIG_ASH_MATH_SUPPORT
+@@ -1647,10 +1664,14 @@
+ {BUILTIN_NOSPEC "setvar", setvarcmd},
+ {BUILTIN_SPECIAL "shift", shiftcmd},
+ {BUILTIN_SPECIAL "times", timescmd},
++#ifndef NEWLIB_ASH
+ {BUILTIN_SPECIAL "trap", trapcmd},
++#endif
+ {BUILTIN_REGULAR "true", true_main},
+ {BUILTIN_NOSPEC "type", typecmd},
++#ifndef NEWLIB_ASH
+ {BUILTIN_NOSPEC "ulimit", ulimitcmd},
++#endif
+ {BUILTIN_REGULAR "umask", umaskcmd},
+ #ifdef CONFIG_ASH_ALIAS
+ {BUILTIN_REGULAR "unalias", unaliascmd},
+@@ -1918,6 +1939,8 @@
+ * just defensive programming.)
+ */
+
++#ifndef NEWLIB_ASH
++
+ static void onint(void)
+ {
+ sigset_t mysigset;
+@@ -1937,6 +1960,7 @@
+ /* NOTREACHED */
+ }
+
++#endif
+
+ static char *commandname; /* currently executing command */
+
+@@ -2086,7 +2110,7 @@
+ }
+
+
+-#ifdef CONFIG_ASH_OPTIMIZE_FOR_SIZE
++#if defined(CONFIG_ASH_OPTIMIZE_FOR_SIZE) && !defined(NEWLIB_ASH)
+ static void __inton()
+ {
+ if (--suppressint == 0 && intpending) {
+@@ -5597,7 +5621,6 @@
+
+ static void init(void)
+ {
+-
+ /* from cd.c: */
+ {
+ curdir = nullstr;
+@@ -5621,8 +5644,10 @@
+ }
+ }
+
++#ifndef NEWLIB_ASH
+ snprintf(ppid, sizeof(ppid), "%d", (int) getppid());
+ setvar("PPID", ppid, 0);
++#endif
+ }
+ }
+
+@@ -6214,12 +6239,16 @@
+ else /* WIFSIGNALED(ps->status) */
+ #endif
+ i = WTERMSIG(ps->status);
++#ifndef NEWLIB_ASH
+ if ((i & 0x7F) < NSIG && sys_siglist[i & 0x7F])
+ strcpy(s, sys_siglist[i & 0x7F]);
+ else
++#endif
+ snprintf(s, 64, "Signal %d", i & 0x7F);
++#ifndef NEWLIB_ASH
+ if (WCOREDUMP(ps->status))
+ strcat(s, " (core dumped)");
++#endif
+ }
+ out1str(s);
+ col += strlen(s);
+@@ -6641,7 +6670,11 @@
+ #endif
+ if (block == 0)
+ flags |= WNOHANG;
++#ifndef NEWLIB_ASH
+ return wait3(status, flags, (struct rusage *) NULL);
++#else
++ return waitpid(-1,status,flags);
++#endif
+ }
+
+ static int dowait(int block, struct job *job)
+@@ -6700,7 +6733,9 @@
+ }
+ INTON;
+ if (!rootshell || !iflag || (job && thisjob == job)) {
++#ifndef NEWLIB_ASH
+ core = WCOREDUMP(status);
++#endif
+ #ifdef BB_FEATURE_ASH_JOB_CONTROL
+ if (WIFSTOPPED(status))
+ sig = WSTOPSIG(status);
+@@ -6718,12 +6753,16 @@
+ if (sig == SIGTSTP && rootshell && iflag)
+ out2fmt("%%%ld ", (long) (job - jobtab + 1));
+ #endif
++#ifndef NEWLIB_ASH
+ if (sig < NSIG && sys_siglist[sig])
+ out2str(sys_siglist[sig]);
+ else
++#endif
+ out2fmt("Signal %d", sig);
++#ifndef NEWLIB_ASH
+ if (core)
+ out2str(" - core dumped");
++#endif
+ out2c('\n');
+ } else {
+ TRACE(("Not printing status: status=%d, sig=%d\n", status, sig));
+@@ -7993,6 +8032,8 @@
+ {NULL, 0, 0}
+ };
+
++#ifndef NEWLIB_ASH
++
+ static int ulimitcmd(int argc, char **argv)
+ {
+ static const char unlimited_string[] = "unlimited";
+@@ -8118,6 +8159,8 @@
+ return 0;
+ }
+
++#endif /* !NEWLIB_ASH */
++
+ /*
+ * prefix -- see if pfx is a prefix of string.
+ */
+@@ -11426,6 +11469,8 @@
+ * The trap builtin.
+ */
+
++#ifndef NEWLIB_ASH
++
+ static int trapcmd(int argc, char **argv)
+ {
+ char *action;
+@@ -11475,6 +11520,7 @@
+ return 0;
+ }
+
++#endif /*!NEWLIB_ASH */
+
+ /*
+ * Set the signal handler for the specified signal. The routine figures
+@@ -11485,7 +11531,9 @@
+ {
+ int action;
+ char *t;
++#ifndef NEWLIB_ASH
+ struct sigaction act;
++#endif
+
+ if ((t = trap[signo]) == NULL)
+ action = S_DFL;
+@@ -11527,6 +11575,7 @@
+ /*
+ * current setting unknown
+ */
++#ifndef NEWLIB_ASH
+ if (sigaction(signo, 0, &act) == -1) {
+ /*
+ * Pretend it worked; maybe we should give a warning
+@@ -11536,6 +11585,7 @@
+ return;
+ }
+ if (act.sa_handler == SIG_IGN) {
++
+ if (mflag && (signo == SIGTSTP ||
+ signo == SIGTTIN || signo == SIGTTOU)) {
+ *t = S_IGN; /* don't hard ignore these */
+@@ -11544,15 +11594,22 @@
+ } else {
+ *t = S_RESET; /* force to be set */
+ }
++#else
++ *t = S_DFL;
++#endif
+ }
+ if (*t == S_HARD_IGN || *t == action)
+ return;
++ *t = action;
++#ifndef NEWLIB_ASH
+ act.sa_handler = ((action == S_CATCH) ? onsig
+ : ((action == S_IGN) ? SIG_IGN : SIG_DFL));
+- *t = action;
+ act.sa_flags = 0;
+ sigemptyset(&act.sa_mask);
+ sigaction(signo, &act, 0);
++#else
++ signal(signo,((action == S_CATCH) ? onsig : ((action == S_IGN) ? SIG_IGN : SIG_DFL)));
++#endif
+ }
+
+ /*
+@@ -11574,10 +11631,12 @@
+
+ static void onsig(int signo)
+ {
++#ifndef NEWLIB_ASH
+ if (signo == SIGINT && trap[SIGINT] == NULL) {
+ onint();
+ return;
+ }
++#endif
+ gotsig[signo - 1] = 1;
+ pendingsigs++;
+ }
+@@ -12153,6 +12212,7 @@
+
+ static struct var **findvar(struct var **vpp, const char *name)
+ {
++ int n=0;
+ for (; *vpp; vpp = &(*vpp)->next) {
+ if (varequal((*vpp)->text, name)) {
+ break;
+@@ -12168,8 +12228,11 @@
+ static int timescmd(int argc, char **argv)
+ {
+ struct tms buf;
++#ifdef NEWLIB_ASH
++ long int clk_tck = _CLOCKS_PER_SEC_;
++#else
+ long int clk_tck = sysconf(_SC_CLK_TCK);
+-
++#endif
+ times(&buf);
+ printf("%dm%fs %dm%fs\n%dm%fs %dm%fs\n",
+ (int) (buf.tms_utime / clk_tck / 60),
+diff -ur ../busybox-0.60.5/busybox.h ./busybox.h
+--- ../busybox-0.60.5/busybox.h Fri Mar 15 21:11:46 2002
++++ ./busybox.h Tue Nov 25 11:10:52 2003
+@@ -37,8 +37,9 @@
+ #include "dmalloc.h"
+ #endif
+
++#ifdef _GNU_SOURCE
+ #include <features.h>
+-
++#endif
+
+ enum Location {
+ _BB_DIR_ROOT = 0,
+@@ -85,7 +86,9 @@
+
+ /* Bit map related macros -- libc5 doens't provide these... sigh. */
+ #ifndef setbit
++#ifndef NBBY
+ #define NBBY CHAR_BIT
++#endif
+ #define setbit(a,i) ((a)[(i)/NBBY] |= 1<<((i)%NBBY))
+ #define clrbit(a,i) ((a)[(i)/NBBY] &= ~(1<<((i)%NBBY)))
+ #define isset(a,i) ((a)[(i)/NBBY] & (1<<((i)%NBBY)))
+Only in ../busybox-0.60.5: busybox.links
+diff -ur ../busybox-0.60.5/busybox.sh ./busybox.sh
+--- ../busybox-0.60.5/busybox.sh Wed Sep 26 02:20:54 2001
++++ ./busybox.sh Tue Nov 25 10:57:58 2003
+@@ -5,7 +5,7 @@
+
+ RAW=` \
+ $CC -E -dM ${1:-Config.h} | \
+- sed -n -e '/^.*BB_FEATURE.*$/d;s/^#define.*\<BB_\(.*\)\>/\1.c/gp;' \
++ sed -n -e '/^.*BB_FEATURE.*$/d;s/^#define.*BB_\([A-Z0-9_]*\)/\1.c/gp;' \
+ | tr A-Z a-z | sort
+ `
+ test "${RAW}" != "" || exit
+diff -ur ../busybox-0.60.5/date.c ./date.c
+--- ../busybox-0.60.5/date.c Sat Jun 15 10:35:13 2002
++++ ./date.c Tue Nov 25 11:26:25 2003
+@@ -210,9 +210,7 @@
+
+ /* if setting time, set it */
+ if (set_time) {
+- if (stime(&tm) < 0) {
+- perror_msg("cannot set date");
+- }
++ perror_msg("cannot set date");
+ }
+ }
+
+Only in ../busybox-0.60.5/docs: BusyBox.1
+Only in ../busybox-0.60.5/docs: BusyBox.html
+Only in ../busybox-0.60.5/docs: BusyBox.txt
+Only in ../busybox-0.60.5/docs: busybox.pod
+diff -ur ../busybox-0.60.5/libbb/libbb.h ./libbb/libbb.h
+--- ../busybox-0.60.5/libbb/libbb.h Wed Sep 18 15:21:07 2002
++++ ./libbb/libbb.h Tue Nov 25 11:10:27 2003
+@@ -25,8 +25,6 @@
+ #include <sys/stat.h>
+ #include <sys/types.h>
+
+-#include <netdb.h>
+-
+ #ifndef _BB_INTERNAL_H_
+ #include "../busybox.h"
+ #endif
+@@ -35,7 +33,9 @@
+ #include "dmalloc.h"
+ #endif
+
++#ifdef _GNU_SOURCE
+ #include <features.h>
++#endif
+
+ #if (__GNU_LIBRARY__ < 5) && (!defined __dietlibc__)
+ /* libc5 doesn't define socklen_t */
+diff -ur ../busybox-0.60.5/ls.c ./ls.c
+--- ../busybox-0.60.5/ls.c Mon Sep 16 01:53:01 2002
++++ ./ls.c Tue Nov 25 11:29:41 2003
+@@ -43,7 +43,7 @@
+
+ enum {
+ TERMINAL_WIDTH = 80, /* use 79 if terminal has linefold bug */
+- COLUMN_WIDTH = 14, /* default if AUTOWIDTH not defined */
++ COLUMN_WIDTH = 18, /* default if AUTOWIDTH not defined */
+ COLUMN_GAP = 2, /* includes the file type char */
+ };
+
+@@ -61,8 +61,10 @@
+ #include <stdlib.h>
+ #include <fcntl.h>
+ #include <signal.h>
++#ifdef BB_FEATURE_AUTOWIDTH
+ #include <termios.h>
+ #include <sys/ioctl.h>
++#endif
+ #include "busybox.h"
+
+ #ifdef BB_FEATURE_LS_TIMESTAMPS
+@@ -484,7 +486,7 @@
+ column_width = COLUMN_WIDTH;
+ }
+ #else
+- ncols= TERMINAL_WIDTH;
++ ncols= (int) (TERMINAL_WIDTH / (COLUMN_WIDTH+COLUMN_GAP));
+ #endif
+ switch (style_fmt) {
+ case STYLE_LONG: /* one record per line, extended info */
+diff -ur ../busybox-0.60.5/md5sum.c ./md5sum.c
+--- ../busybox-0.60.5/md5sum.c Tue Oct 22 18:13:57 2002
++++ ./md5sum.c Tue Nov 25 11:22:37 2003
+@@ -44,13 +44,17 @@
+ #include <getopt.h>
+ #include <stdlib.h>
+ #include <string.h>
+-#include <endian.h>
+ #include <sys/types.h>
+ #if defined HAVE_LIMITS_H
+ # include <limits.h>
+ #endif
+ #include "busybox.h"
+
++typedef unsigned int u_int32_t;
++#ifndef __P
++#define __P(x) x
++#endif
++
+ /* For some silly reason, this file uses backwards TRUE and FALSE conventions */
+ #undef TRUE
+ #undef FALSE
+@@ -146,11 +150,7 @@
+ //----------------------------------------------------------------------------
+
+ /* Handle endian-ness */
+-#if __BYTE_ORDER == __LITTLE_ENDIAN
+- #define SWAP(n) (n)
+-#else
+- #define SWAP(n) ((n << 24) | ((n&65280)<<8) | ((n&16711680)>>8) | (n>>24))
+-#endif
++#define SWAP(n) ((n << 24) | ((n&65280)<<8) | ((n&16711680)>>8) | (n>>24))
+
+
+
+diff -ur ../busybox-0.60.5/printf.c ./printf.c
+--- ../busybox-0.60.5/printf.c Mon Mar 19 14:25:49 2001
++++ ./printf.c Tue Nov 25 11:22:49 2003
+@@ -57,6 +57,10 @@
+ #include <ctype.h>
+ #include "busybox.h"
+
++#ifndef __P
++#define __P(x) x
++#endif
++
+
+ #ifndef S_IFMT
+ static const int S_IFMT = 0170000;
+diff -ur ../busybox-0.60.5/pwd_grp/grp.h ./pwd_grp/grp.h
+--- ../busybox-0.60.5/pwd_grp/grp.h Sat Jan 27 03:24:39 2001
++++ ./pwd_grp/grp.h Tue Nov 25 11:05:36 2003
+@@ -5,8 +5,14 @@
+ #include <grp.h>
+ #else
+
++#ifndef __P
++#define __P(x) x
++#endif
++
+ #include <sys/types.h>
++#ifdef _GNU_SOURCE
+ #include <features.h>
++#endif
+ #include <stdio.h>
+
+ /* The group structure */
+diff -ur ../busybox-0.60.5/pwd_grp/pwd.h ./pwd_grp/pwd.h
+--- ../busybox-0.60.5/pwd_grp/pwd.h Sat Jan 27 03:24:39 2001
++++ ./pwd_grp/pwd.h Tue Nov 25 11:05:09 2003
+@@ -5,8 +5,14 @@
+ #include <pwd.h>
+ #else
+
++#ifndef __P
++#define __P(x) x
++#endif
++
+ #include <sys/types.h>
++#ifdef _GNU_SOURCE
+ #include <features.h>
++#endif
+ #include <stdio.h>
+
+ /* The passwd structure. */
--- /dev/null
+--- include/freetype/config/ftmodule.h Thu Jul 31 12:59:06 2003
++++ include/freetype/config/ftmodule.h Thu Jul 31 12:59:17 2003
+@@ -1,4 +1,5 @@
+ FT_USE_MODULE(autohint_module_class)
++/*
+ FT_USE_MODULE(cff_driver_class)
+ FT_USE_MODULE(t1cid_driver_class)
+ FT_USE_MODULE(pcf_driver_class)
+@@ -7,13 +8,15 @@
+ FT_USE_MODULE(psnames_module_class)
+ FT_USE_MODULE(pshinter_module_class)
+ FT_USE_MODULE(ft_raster1_renderer_class)
++*/
+ FT_USE_MODULE(sfnt_module_class)
+ FT_USE_MODULE(ft_smooth_renderer_class)
+ FT_USE_MODULE(ft_smooth_lcd_renderer_class)
+ FT_USE_MODULE(ft_smooth_lcdv_renderer_class)
+ FT_USE_MODULE(tt_driver_class)
++/*
+ FT_USE_MODULE(t1_driver_class)
+ FT_USE_MODULE(t42_driver_class)
+ FT_USE_MODULE(pfr_driver_class)
+ FT_USE_MODULE(winfnt_driver_class)
+-
++*/
--- /dev/null
+--- src/base/ftsystem.c.origf Mon Dec 29 05:45:54 2003
++++ src/base/ftsystem.c Mon Dec 29 05:46:08 2003
+@@ -32,7 +32,8 @@
+ #include FT_ERRORS_H
+ #include FT_TYPES_H
+
+-#include <stdio.h>
++#include <fcntl.h>
++#include <unistd.h>
+ #include <stdlib.h>
+
+
+@@ -151,7 +152,7 @@
+
+ /* We use the macro STREAM_FILE for convenience to extract the */
+ /* system-specific stream handle from a given FreeType stream object */
+-#define STREAM_FILE( stream ) ( (FILE*)stream->descriptor.pointer )
++#define STREAM_FD( stream ) ( (int)stream->descriptor.value )
+
+
+ /*************************************************************************/
+@@ -168,7 +169,7 @@
+ FT_CALLBACK_DEF( void )
+ ft_ansi_stream_close( FT_Stream stream )
+ {
+- fclose( STREAM_FILE( stream ) );
++ close(STREAM_FD(stream));
+
+ stream->descriptor.pointer = NULL;
+ stream->size = 0;
+@@ -202,14 +203,14 @@
+ unsigned char* buffer,
+ unsigned long count )
+ {
+- FILE* file;
++ int fd;
+
+
+- file = STREAM_FILE( stream );
++ fd = STREAM_FD( stream );
+
+- fseek( file, offset, SEEK_SET );
++ if(lseek( fd, offset, SEEK_SET ) < 0) return 0;
+
+- return (unsigned long)fread( buffer, 1, count, file );
++ return (unsigned long) read(fd,buffer,count);
+ }
+
+
+@@ -219,14 +220,14 @@
+ FT_Stream_Open( FT_Stream stream,
+ const char* filepathname )
+ {
+- FILE* file;
++ int fd,n;
+
+
+ if ( !stream )
+ return FT_Err_Invalid_Stream_Handle;
+
+- file = fopen( filepathname, "rb" );
+- if ( !file )
++ fd = open( filepathname, O_RDONLY);
++ if (fd < 0)
+ {
+ FT_ERROR(( "FT_Stream_Open:" ));
+ FT_ERROR(( " could not open `%s'\n", filepathname ));
+@@ -234,11 +235,11 @@
+ return FT_Err_Cannot_Open_Resource;
+ }
+
+- fseek( file, 0, SEEK_END );
+- stream->size = ftell( file );
+- fseek( file, 0, SEEK_SET );
++ n = lseek( fd, 0, SEEK_END );
++ stream-> size = n < 0 ? 0 : n;
++ lseek( fd, 0, SEEK_SET );
+
+- stream->descriptor.pointer = file;
++ stream->descriptor.value = fd;
+ stream->pathname.pointer = (char*)filepathname;
+ stream->pos = 0;
+
--- /dev/null
+--- gcc/config/mips/mips.c.orig Mon Dec 29 06:30:42 2003
++++ gcc/config/mips/mips.c Mon Dec 29 07:16:35 2003
+@@ -10535,11 +10535,13 @@
+ int len, size, sec;
+ const char *name, *prefix;
+ char *string;
+- static const char *const prefixes[4][2] = {
++ static const char *const prefixes[6][2] = {
+ { ".text.", ".gnu.linkonce.t." },
+ { ".rodata.", ".gnu.linkonce.r." },
+ { ".data.", ".gnu.linkonce.d." },
+- { ".sdata.", ".gnu.linkonce.s." }
++ { ".sdata.", ".gnu.linkonce.s." },
++ { ".bss.", ".gnu.linkonce.b." },
++ { ".sbss.", ".gnu.linkonce.sb." }
+ };
+
+ name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
+@@ -10551,8 +10553,9 @@
+ if (TREE_CODE (decl) == FUNCTION_DECL)
+ sec = 0;
+ else if (DECL_INITIAL (decl) == 0
+- || DECL_INITIAL (decl) == error_mark_node)
+- sec = 2;
++ || DECL_INITIAL (decl) == error_mark_node
++ || initializer_zerop (DECL_INITIAL (decl)))
++ sec = (size > 0 && size <= mips_section_threshold) ? 5 : 4;
+ else if ((TARGET_EMBEDDED_PIC || TARGET_MIPS16)
+ && TREE_CODE (decl) == STRING_CST
+ && !flag_writable_strings)
--- /dev/null
+diff -urN ../gcc-3.3.1/gcc/builtin-attrs.def ./gcc/builtin-attrs.def
+--- ../gcc-3.3.1/gcc/builtin-attrs.def Tue Mar 4 09:37:20 2003
++++ ./gcc/builtin-attrs.def Wed Aug 27 00:09:45 2003
+@@ -110,6 +110,7 @@
+ ATTR_NOTHROW_LIST)
+
+ /* Construct a tree for a format attribute. */
++#if 0
+ #define DEF_FORMAT_ATTRIBUTE(TYPE, FA, VALUES) \
+ DEF_ATTR_TREE_LIST (CONCAT4 (ATTR_,TYPE,_,VALUES), ATTR_NULL, \
+ CONCAT2 (ATTR_,TYPE), CONCAT2 (ATTR_LIST_,VALUES)) \
+@@ -128,6 +129,32 @@
+ DEF_FORMAT_ATTRIBUTE(STRFTIME,3,3_0)
+ DEF_FORMAT_ATTRIBUTE(STRFMON,3,3_4)
+ #undef DEF_FORMAT_ATTRIBUTE
++#else
++DEF_ATTR_TREE_LIST (ATTR_PRINTF_1_0, ATTR_NULL, ATTR_PRINTF, ATTR_LIST_1_0)
++DEF_ATTR_TREE_LIST (ATTR_FORMAT_PRINTF_1_0, ATTR_FORMAT, ATTR_PRINTF_1_0, ATTR_NONNULL_1)
++DEF_ATTR_TREE_LIST (ATTR_PRINTF_1_2, ATTR_NULL, ATTR_PRINTF, ATTR_LIST_1_2)
++DEF_ATTR_TREE_LIST (ATTR_FORMAT_PRINTF_1_2, ATTR_FORMAT, ATTR_PRINTF_1_2, ATTR_NONNULL_1)
++DEF_ATTR_TREE_LIST (ATTR_PRINTF_2_0, ATTR_NULL, ATTR_PRINTF, ATTR_LIST_2_0)
++DEF_ATTR_TREE_LIST (ATTR_FORMAT_PRINTF_2_0, ATTR_FORMAT, ATTR_PRINTF_2_0, ATTR_NONNULL_2)
++DEF_ATTR_TREE_LIST (ATTR_PRINTF_2_3, ATTR_NULL, ATTR_PRINTF, ATTR_LIST_2_3)
++DEF_ATTR_TREE_LIST (ATTR_FORMAT_PRINTF_2_3, ATTR_FORMAT, ATTR_PRINTF_2_3, ATTR_NONNULL_2)
++DEF_ATTR_TREE_LIST (ATTR_PRINTF_3_0, ATTR_NULL, ATTR_PRINTF, ATTR_LIST_3_0)
++DEF_ATTR_TREE_LIST (ATTR_FORMAT_PRINTF_3_0, ATTR_FORMAT, ATTR_PRINTF_3_0, ATTR_NONNULL_3)
++DEF_ATTR_TREE_LIST (ATTR_PRINTF_3_4, ATTR_NULL, ATTR_PRINTF, ATTR_LIST_3_4)
++DEF_ATTR_TREE_LIST (ATTR_FORMAT_PRINTF_3_4, ATTR_FORMAT, ATTR_PRINTF_3_4, ATTR_NONNULL_3)
++DEF_ATTR_TREE_LIST (ATTR_SCANF_1_0, ATTR_NULL, ATTR_SCANF, ATTR_LIST_1_0)
++DEF_ATTR_TREE_LIST (ATTR_FORMAT_SCANF_1_0, ATTR_FORMAT, ATTR_SCANF_1_0, ATTR_NONNULL_1)
++DEF_ATTR_TREE_LIST (ATTR_SCANF_1_2, ATTR_NULL, ATTR_SCANF, ATTR_LIST_1_2)
++DEF_ATTR_TREE_LIST (ATTR_FORMAT_SCANF_1_2, ATTR_FORMAT, ATTR_SCANF_1_2, ATTR_NONNULL_1)
++DEF_ATTR_TREE_LIST (ATTR_SCANF_2_0, ATTR_NULL, ATTR_SCANF, ATTR_LIST_2_0)
++DEF_ATTR_TREE_LIST (ATTR_FORMAT_SCANF_2_0, ATTR_FORMAT, ATTR_SCANF_2_0, ATTR_NONNULL_2)
++DEF_ATTR_TREE_LIST (ATTR_SCANF_2_3, ATTR_NULL, ATTR_SCANF, ATTR_LIST_2_3)
++DEF_ATTR_TREE_LIST (ATTR_FORMAT_SCANF_2_3, ATTR_FORMAT, ATTR_SCANF_2_3, ATTR_NONNULL_2)
++DEF_ATTR_TREE_LIST (ATTR_STRFTIME_3_0, ATTR_NULL, ATTR_STRFTIME, ATTR_LIST_3_0)
++DEF_ATTR_TREE_LIST (ATTR_FORMAT_STRFTIME_3_0, ATTR_FORMAT, ATTR_STRFTIME_3_0, ATTR_NONNULL_3)
++DEF_ATTR_TREE_LIST (ATTR_STRFMON_3_4, ATTR_NULL, ATTR_STRFMON, ATTR_LIST_3_4)
++DEF_ATTR_TREE_LIST (ATTR_FORMAT_STRFMON_3_4, ATTR_FORMAT, ATTR_STRFMON_3_4, ATTR_NONNULL_3)
++#endif
+
+ /* Construct a tree for a format_arg attribute. */
+ #define DEF_FORMAT_ARG_ATTRIBUTE(FA) \
+diff -urN ../gcc-3.3.1/gcc/config/mips/t-unknown ./gcc/config/mips/t-unknown
+--- ../gcc-3.3.1/gcc/config/mips/t-unknown Wed Dec 31 19:00:00 1969
++++ ./gcc/config/mips/t-unknown Mon Sep 1 01:19:35 2003
+@@ -0,0 +1,3 @@
++MULTILIB_OPTIONS=
++MULTILIB_DIRNAMES =
++MULTILIB_MATCHES =
+diff -urN ../gcc-3.3.1/gcc/config.gcc ./gcc/config.gcc
+--- ../gcc-3.3.1/gcc/config.gcc Fri Jun 27 07:44:22 2003
++++ ./gcc/config.gcc Sun Aug 31 12:39:12 2003
+@@ -1932,6 +1932,10 @@
+ target_cpu_default="MASK_64BIT|MASK_FLOAT64|MASK_GAS"
+ tm_defines="MIPS_ISA_DEFAULT=64 MIPS_CPU_STRING_DEFAULT=\\\"sb1\\\" MIPS_ABI_DEFAULT=ABI_O64"
+ ;;
++mips*-unknown-elf*)
++ tm_file="${tm_file} mips/elf.h"
++ tmake_file="mips/t-elf mips/t-unknown"
++ ;;
+ mips-*-elf* | mipsel-*-elf*)
+ tm_file="${tm_file} mips/elf.h"
+ tmake_file=mips/t-elf
--- /dev/null
+--- ../libmspack.orig/mspack/Makefile Sat Jul 26 10:44:57 2003
++++ mspack/Makefile Sun Nov 2 17:12:35 2003
+@@ -1,12 +1,13 @@
+ CC=gcc
+ RM=rm -f
+ AR=ar
++RANLIB=ranlib
+
+ WARNINGS=-Wall -Wsign-compare -Wconversion -pedantic
+ LARGEFILE=-std=c99 -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
+ DEBUG=-g -DDEBUG
+ OPTIM=-O3
+-CFLAGS= $(WARNINGS) $(LARGEFILE) $(DEBUG) $(OPTIM) -I.
++CFLAGS= $(WARNINGS) $(LARGEFILE) $(OPTIM) -I. #-DMSPACK_NO_DEFAULT_SYSTEM
+
+ all: libmspack.a
+
+@@ -27,6 +28,7 @@
+ libmspack.a: $(OBJS)
+ -$(RM) $@
+ $(AR) q $@ $(OBJS)
++ $(RANLIB) $@
+
+ .c.o:
+ $(CC) $(CFLAGS) -o $@ -c $<
--- /dev/null
+--- newlib/libc/stdlib/mallocr.c.old Sun Nov 23 18:41:21 2003
++++ newlib/libc/stdlib/mallocr.c Sun Nov 23 18:43:03 2003
+@@ -301,7 +301,8 @@
+ #define SEPARATE_OBJECTS
+ #define HAVE_MMAP 0
+ #define MORECORE(size) _sbrk_r(reent_ptr, (size))
+-#define MORECORE_CLEARS 0
++#define MORECORE_CLEARS 1
++#define malloc_getpagesize getpagesize()
+ #define MALLOC_LOCK __malloc_lock(reent_ptr)
+ #define MALLOC_UNLOCK __malloc_unlock(reent_ptr)
+
+@@ -310,7 +311,7 @@
+ # undef WIN32
+ #endif
+
+-#ifndef _WIN32
++#if !defined(_WIN32) && !defined(malloc_getpagesize)
+ #ifdef SMALL_MEMORY
+ #define malloc_getpagesize (128)
+ #else
--- /dev/null
+diff -urN ../newlib-1.11.0.orig/libgloss/configure ./libgloss/configure
+--- ../newlib-1.11.0.orig/libgloss/configure Tue Nov 25 09:05:13 2003
++++ ./libgloss/configure Mon Nov 24 20:12:14 2003
+@@ -762,6 +762,9 @@
+ mips*-*-pe)
+ configdirs="wince"
+ ;;
++ mips*-unknown-elf*)
++ configdirs="${configdirs}"
++ ;;
+ mips*-*-*)
+ configdirs="${configdirs} mips testsuite"
+ ;;
+@@ -818,7 +821,7 @@
+ # Extract the first word of "gcc", so it can be a program name with args.
+ set dummy gcc; ac_word=$2
+ echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+-echo "configure:822: checking for $ac_word" >&5
++echo "configure:825: checking for $ac_word" >&5
+ if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+ else
+@@ -848,7 +851,7 @@
+ # Extract the first word of "cc", so it can be a program name with args.
+ set dummy cc; ac_word=$2
+ echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+-echo "configure:852: checking for $ac_word" >&5
++echo "configure:855: checking for $ac_word" >&5
+ if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+ else
+@@ -897,7 +900,7 @@
+ fi
+
+ echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+-echo "configure:901: checking whether we are using GNU C" >&5
++echo "configure:904: checking whether we are using GNU C" >&5
+ if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+ else
+@@ -906,7 +909,7 @@
+ yes;
+ #endif
+ EOF
+-if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:910: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
++if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:913: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ ac_cv_prog_gcc=yes
+ else
+ ac_cv_prog_gcc=no
+@@ -921,7 +924,7 @@
+ ac_save_CFLAGS="$CFLAGS"
+ CFLAGS=
+ echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+-echo "configure:925: checking whether ${CC-cc} accepts -g" >&5
++echo "configure:928: checking whether ${CC-cc} accepts -g" >&5
+ if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+ else
+@@ -953,7 +956,7 @@
+ # Extract the first word of "ar", so it can be a program name with args.
+ set dummy ar; ac_word=$2
+ echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+-echo "configure:957: checking for $ac_word" >&5
++echo "configure:960: checking for $ac_word" >&5
+ if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+ else
+@@ -987,7 +990,7 @@
+ # Extract the first word of "ranlib", so it can be a program name with args.
+ set dummy ranlib; ac_word=$2
+ echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+-echo "configure:991: checking for $ac_word" >&5
++echo "configure:994: checking for $ac_word" >&5
+ if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+ else
+diff -urN ../newlib-1.11.0.orig/libgloss/configure.in ./libgloss/configure.in
+--- ../newlib-1.11.0.orig/libgloss/configure.in Tue Nov 25 09:05:13 2003
++++ ./libgloss/configure.in Mon Nov 24 20:12:14 2003
+@@ -73,6 +73,9 @@
+ mips*-*-pe)
+ configdirs="wince"
+ ;;
++ mips*-unknown-elf*)
++ configdirs="${configdirs}"
++ ;;
+ mips*-*-*)
+ configdirs="${configdirs} mips testsuite"
+ ;;
+diff -urN ../newlib-1.11.0.orig/newlib/configure.host ./newlib/configure.host
+--- ../newlib-1.11.0.orig/newlib/configure.host Tue Nov 25 09:05:13 2003
++++ ./newlib/configure.host Tue Nov 25 08:30:02 2003
+@@ -356,6 +356,9 @@
+ m8*-bug-*)
+ sys_dir=m88kbug
+ ;;
++ mips*-unknown-elf*)
++ sys_dir=mipsunknown
++ ;;
+ mips*-dec-*)
+ sys_dir=decstation
+ ;;
+@@ -508,6 +511,10 @@
+ newlib_cflags="${newlib_cflags}"
+ syscall_dir=syscalls
+ ;;
++ mips*-unknown-elf*)
++ newlib_cflags="${newlib_cflags} -DREENTRANT_SYSCALLS_PROVIDED -DHAVE_GETTIMEOFDAY -DHAVE_FCNTL"
++ syscall_dir=syscalls
++ ;;
+ mmix-*)
+ syscall_dir=syscalls
+ # We need every symbol 32-bit aligned, so the invalid
+diff -urN ../newlib-1.11.0.orig/newlib/libc/include/paths.h ./newlib/libc/include/paths.h
+--- ../newlib-1.11.0.orig/newlib/libc/include/paths.h Thu Feb 17 14:39:46 2000
++++ ./newlib/libc/include/paths.h Tue Nov 25 09:48:09 2003
+@@ -3,5 +3,6 @@
+
+ #define _PATH_DEV "/dev/"
+ #define _PATH_BSHELL "/bin/sh"
++#define _PATH_DEVNULL "/dev/null"
+
+ #endif /* _PATHS_H_ */
+diff -urN ../newlib-1.11.0.orig/newlib/libc/include/stdlib.h ./newlib/libc/include/stdlib.h
+--- ../newlib-1.11.0.orig/newlib/libc/include/stdlib.h Fri Dec 6 13:58:50 2002
++++ ./newlib/libc/include/stdlib.h Tue Nov 25 09:50:46 2003
+@@ -158,10 +158,12 @@
+ _VOID _EXFUN(cfree,(_PTR));
+ #else
+ char * _EXFUN(realpath,(const char *, char *));
++#endif
+ void _EXFUN(unsetenv,(const char *__string));
+ void _EXFUN(_unsetenv_r,(struct _reent *, const char *__string));
+ int _EXFUN(random,(_VOID));
+ long _EXFUN(srandom,(unsigned __seed));
++#ifdef __CYGWIN__
+ char * _EXFUN(ptsname, (int));
+ int _EXFUN(grantpt, (int));
+ int _EXFUN(unlockpt,(int));
+diff -urN ../newlib-1.11.0.orig/newlib/libc/include/sys/signal.h ./newlib/libc/include/sys/signal.h
+--- ../newlib-1.11.0.orig/newlib/libc/include/sys/signal.h Wed Jul 24 14:18:07 2002
++++ ./newlib/libc/include/sys/signal.h Tue Nov 25 09:56:00 2003
+@@ -142,6 +142,8 @@
+ int _EXFUN(pthread_sigmask, (int how, const sigset_t *set, sigset_t *oset));
+ #endif
+
++int _EXFUN(kill, (int, int));
++
+ /* protos for functions found in winsup sources for CYGWIN */
+ #if defined(__CYGWIN__) || defined(__rtems__)
+ #undef sigaddset
+@@ -150,7 +152,6 @@
+ <sys/types.h> always defines pid_t to be int. If that ever
+ changes, then we will need to do something else, perhaps along the
+ lines of <machine/types.h>. */
+-int _EXFUN(kill, (int, int));
+ int _EXFUN(killpg, (pid_t, int));
+ int _EXFUN(sigaction, (int, const struct sigaction *, struct sigaction *));
+ int _EXFUN(sigaddset, (sigset_t *, const int));
+diff -urN ../newlib-1.11.0.orig/newlib/libc/include/sys/stat.h ./newlib/libc/include/sys/stat.h
+--- ../newlib-1.11.0.orig/newlib/libc/include/sys/stat.h Sat Feb 23 15:46:28 2002
++++ ./newlib/libc/include/sys/stat.h Tue Nov 25 09:41:35 2003
+@@ -127,7 +127,7 @@
+ int _EXFUN(stat,( const char *__path, struct stat *__sbuf ));
+ mode_t _EXFUN(umask,( mode_t __mask ));
+
+-#if defined(__rtems__) || defined(__CYGWIN__)
++#if defined(__rtems__) || defined(__CYGWIN__) || 1
+ int _EXFUN(lstat,( const char *__path, struct stat *__buf ));
+ int _EXFUN(mknod,( const char *__path, mode_t __mode, dev_t __dev ));
+ #endif
+diff -urN ../newlib-1.11.0.orig/newlib/libc/include/sys/unistd.h ./newlib/libc/include/sys/unistd.h
+--- ../newlib-1.11.0.orig/newlib/libc/include/sys/unistd.h Sun Aug 18 02:08:39 2002
++++ ./newlib/libc/include/sys/unistd.h Tue Nov 25 09:46:58 2003
+@@ -158,9 +158,9 @@
+ #endif
+ char * _EXFUN(mktemp, (char *));
+ int _EXFUN(sync, (void));
++#endif
+ int _EXFUN(readlink, (const char *__path, char *__buf, int __buflen));
+ int _EXFUN(symlink, (const char *__name1, const char *__name2));
+-#endif
+
+ #define F_OK 0
+ #define R_OK 4
+diff -urN ../newlib-1.11.0.orig/newlib/libc/sys/mipsunknown/Makefile.am ./newlib/libc/sys/mipsunknown/Makefile.am
+--- ../newlib-1.11.0.orig/newlib/libc/sys/mipsunknown/Makefile.am Wed Dec 31 19:00:00 1969
++++ ./newlib/libc/sys/mipsunknown/Makefile.am Mon Nov 24 21:04:11 2003
+@@ -0,0 +1,14 @@
++## Process this file with automake to generate Makefile.in
++
++AUTOMAKE_OPTIONS = cygnus
++
++INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS)
++
++noinst_LIBRARIES = lib.a
++
++lib_a_SOURCES = syscalls.c
++
++all: crt0.o
++
++ACLOCAL_AMFLAGS = -I ../../..
++CONFIG_STATUS_DEPENDENCIES = $(newlib_basedir)/configure.host
+diff -urN ../newlib-1.11.0.orig/newlib/libc/sys/mipsunknown/Makefile.in ./newlib/libc/sys/mipsunknown/Makefile.in
+--- ../newlib-1.11.0.orig/newlib/libc/sys/mipsunknown/Makefile.in Wed Dec 31 19:00:00 1969
++++ ./newlib/libc/sys/mipsunknown/Makefile.in Mon Nov 24 21:04:22 2003
+@@ -0,0 +1,329 @@
++# Makefile.in generated automatically by automake 1.4 from Makefile.am
++
++# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
++# This Makefile.in is free software; the Free Software Foundation
++# gives unlimited permission to copy and/or distribute it,
++# with or without modifications, as long as this notice is preserved.
++
++# This program is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
++# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
++# PARTICULAR PURPOSE.
++
++
++SHELL = @SHELL@
++
++srcdir = @srcdir@
++top_srcdir = @top_srcdir@
++VPATH = @srcdir@
++prefix = @prefix@
++exec_prefix = @exec_prefix@
++
++bindir = @bindir@
++sbindir = @sbindir@
++libexecdir = @libexecdir@
++datadir = @datadir@
++sysconfdir = @sysconfdir@
++sharedstatedir = @sharedstatedir@
++localstatedir = @localstatedir@
++libdir = @libdir@
++infodir = @infodir@
++mandir = @mandir@
++includedir = @includedir@
++oldincludedir = /usr/include
++
++DESTDIR =
++
++pkgdatadir = $(datadir)/@PACKAGE@
++pkglibdir = $(libdir)/@PACKAGE@
++pkgincludedir = $(includedir)/@PACKAGE@
++
++top_builddir = .
++
++ACLOCAL = @ACLOCAL@
++AUTOCONF = @AUTOCONF@
++AUTOMAKE = @AUTOMAKE@
++AUTOHEADER = @AUTOHEADER@
++
++INSTALL = @INSTALL@
++INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
++INSTALL_DATA = @INSTALL_DATA@
++INSTALL_SCRIPT = @INSTALL_SCRIPT@
++transform = @program_transform_name@
++
++NORMAL_INSTALL = :
++PRE_INSTALL = :
++POST_INSTALL = :
++NORMAL_UNINSTALL = :
++PRE_UNINSTALL = :
++POST_UNINSTALL = :
++build_alias = @build_alias@
++build_triplet = @build@
++host_alias = @host_alias@
++host_triplet = @host@
++target_alias = @target_alias@
++target_triplet = @target@
++AR = @AR@
++AS = @AS@
++CC = @CC@
++CPP = @CPP@
++EXEEXT = @EXEEXT@
++LDFLAGS = @LDFLAGS@
++MAINT = @MAINT@
++MAKEINFO = @MAKEINFO@
++NEWLIB_CFLAGS = @NEWLIB_CFLAGS@
++OBJEXT = @OBJEXT@
++PACKAGE = @PACKAGE@
++RANLIB = @RANLIB@
++VERSION = @VERSION@
++aext = @aext@
++libm_machine_dir = @libm_machine_dir@
++machine_dir = @machine_dir@
++newlib_basedir = @newlib_basedir@
++oext = @oext@
++sys_dir = @sys_dir@
++
++AUTOMAKE_OPTIONS = cygnus
++
++INCLUDES = $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS)
++
++noinst_LIBRARIES = lib.a
++
++lib_a_SOURCES = syscalls.c
++
++ACLOCAL_AMFLAGS = -I ../../..
++CONFIG_STATUS_DEPENDENCIES = $(newlib_basedir)/configure.host
++ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
++mkinstalldirs = $(SHELL) $(top_srcdir)/../../../../mkinstalldirs
++CONFIG_CLEAN_FILES =
++LIBRARIES = $(noinst_LIBRARIES)
++
++
++DEFS = @DEFS@ -I. -I$(srcdir)
++CPPFLAGS = @CPPFLAGS@
++LIBS = @LIBS@
++lib_a_LIBADD =
++lib_a_OBJECTS = syscalls.o
++CFLAGS = @CFLAGS@
++COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
++CCLD = $(CC)
++LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
++DIST_COMMON = Makefile.am Makefile.in aclocal.m4 configure configure.in
++
++
++DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
++
++TAR = gnutar
++GZIP_ENV = --best
++SOURCES = $(lib_a_SOURCES)
++OBJECTS = $(lib_a_OBJECTS)
++
++all: all-redirect
++.SUFFIXES:
++.SUFFIXES: .S .c .o .s
++$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
++ cd $(top_srcdir) && $(AUTOMAKE) --cygnus Makefile
++
++Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
++ cd $(top_builddir) \
++ && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
++
++$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ configure.in \
++ ../../../acinclude.m4 ../../../aclocal.m4 \
++ ../../../libtool.m4
++ cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
++
++config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
++ $(SHELL) ./config.status --recheck
++$(srcdir)/configure: @MAINTAINER_MODE_TRUE@$(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
++ cd $(srcdir) && $(AUTOCONF)
++
++mostlyclean-noinstLIBRARIES:
++
++clean-noinstLIBRARIES:
++ -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
++
++distclean-noinstLIBRARIES:
++
++maintainer-clean-noinstLIBRARIES:
++
++.c.o:
++ $(COMPILE) -c $<
++
++.s.o:
++ $(COMPILE) -c $<
++
++.S.o:
++ $(COMPILE) -c $<
++
++mostlyclean-compile:
++ -rm -f *.o core *.core
++
++clean-compile:
++
++distclean-compile:
++ -rm -f *.tab.c
++
++maintainer-clean-compile:
++
++lib.a: $(lib_a_OBJECTS) $(lib_a_DEPENDENCIES)
++ -rm -f lib.a
++ $(AR) cru lib.a $(lib_a_OBJECTS) $(lib_a_LIBADD)
++ $(RANLIB) lib.a
++
++tags: TAGS
++
++ID: $(HEADERS) $(SOURCES) $(LISP)
++ list='$(SOURCES) $(HEADERS)'; \
++ unique=`for i in $$list; do echo $$i; done | \
++ awk ' { files[$$0] = 1; } \
++ END { for (i in files) print i; }'`; \
++ here=`pwd` && cd $(srcdir) \
++ && mkid -f$$here/ID $$unique $(LISP)
++
++TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
++ tags=; \
++ here=`pwd`; \
++ list='$(SOURCES) $(HEADERS)'; \
++ unique=`for i in $$list; do echo $$i; done | \
++ awk ' { files[$$0] = 1; } \
++ END { for (i in files) print i; }'`; \
++ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
++ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
++
++mostlyclean-tags:
++
++clean-tags:
++
++distclean-tags:
++ -rm -f TAGS ID
++
++maintainer-clean-tags:
++
++distdir = $(PACKAGE)-$(VERSION)
++top_distdir = $(distdir)
++
++# This target untars the dist file and tries a VPATH configuration. Then
++# it guarantees that the distribution is self-contained by making another
++# tarfile.
++distcheck: dist
++ -rm -rf $(distdir)
++ GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz
++ mkdir $(distdir)/=build
++ mkdir $(distdir)/=inst
++ dc_install_base=`cd $(distdir)/=inst && pwd`; \
++ cd $(distdir)/=build \
++ && ../configure --srcdir=.. --prefix=$$dc_install_base \
++ && $(MAKE) $(AM_MAKEFLAGS) \
++ && $(MAKE) $(AM_MAKEFLAGS) dvi \
++ && $(MAKE) $(AM_MAKEFLAGS) check \
++ && $(MAKE) $(AM_MAKEFLAGS) install \
++ && $(MAKE) $(AM_MAKEFLAGS) installcheck \
++ && $(MAKE) $(AM_MAKEFLAGS) dist
++ -rm -rf $(distdir)
++ @banner="$(distdir).tar.gz is ready for distribution"; \
++ dashes=`echo "$$banner" | sed s/./=/g`; \
++ echo "$$dashes"; \
++ echo "$$banner"; \
++ echo "$$dashes"
++dist: distdir
++ -chmod -R a+r $(distdir)
++ GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
++ -rm -rf $(distdir)
++dist-all: distdir
++ -chmod -R a+r $(distdir)
++ GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
++ -rm -rf $(distdir)
++distdir: $(DISTFILES)
++ -rm -rf $(distdir)
++ mkdir $(distdir)
++ -chmod 777 $(distdir)
++ @for file in $(DISTFILES); do \
++ if test -f $$file; then d=.; else d=$(srcdir); fi; \
++ if test -d $$d/$$file; then \
++ cp -pr $$/$$file $(distdir)/$$file; \
++ else \
++ test -f $(distdir)/$$file \
++ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
++ || cp -p $$d/$$file $(distdir)/$$file || :; \
++ fi; \
++ done
++info-am:
++info: info-am
++dvi-am:
++dvi: dvi-am
++check-am:
++check: check-am
++installcheck-am:
++installcheck: installcheck-am
++install-info-am:
++install-info: install-info-am
++install-exec-am:
++install-exec: install-exec-am
++
++install-data-am:
++install-data: install-data-am
++
++install-am: all-am
++ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
++install: install-am
++uninstall-am:
++uninstall: uninstall-am
++all-am: Makefile $(LIBRARIES)
++all-redirect: all-am
++install-strip:
++ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
++installdirs:
++
++
++mostlyclean-generic:
++
++clean-generic:
++
++distclean-generic:
++ -rm -f Makefile $(CONFIG_CLEAN_FILES)
++ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
++
++maintainer-clean-generic:
++mostlyclean-am: mostlyclean-noinstLIBRARIES mostlyclean-compile \
++ mostlyclean-tags mostlyclean-generic
++
++mostlyclean: mostlyclean-am
++
++clean-am: clean-noinstLIBRARIES clean-compile clean-tags clean-generic \
++ mostlyclean-am
++
++clean: clean-am
++
++distclean-am: distclean-noinstLIBRARIES distclean-compile \
++ distclean-tags distclean-generic clean-am
++
++distclean: distclean-am
++ -rm -f config.status
++
++maintainer-clean-am: maintainer-clean-noinstLIBRARIES \
++ maintainer-clean-compile maintainer-clean-tags \
++ maintainer-clean-generic distclean-am
++ @echo "This command is intended for maintainers to use;"
++ @echo "it deletes files that may require special tools to rebuild."
++
++maintainer-clean: maintainer-clean-am
++ -rm -f config.status
++
++.PHONY: mostlyclean-noinstLIBRARIES distclean-noinstLIBRARIES \
++clean-noinstLIBRARIES maintainer-clean-noinstLIBRARIES \
++mostlyclean-compile distclean-compile clean-compile \
++maintainer-clean-compile tags mostlyclean-tags distclean-tags \
++clean-tags maintainer-clean-tags distdir info-am info dvi-am dvi check \
++check-am installcheck-am installcheck install-info-am install-info \
++install-exec-am install-exec install-data-am install-data install-am \
++install uninstall-am uninstall all-redirect all-am all installdirs \
++mostlyclean-generic distclean-generic clean-generic \
++maintainer-clean-generic clean mostlyclean distclean maintainer-clean
++
++
++all: crt0.o
++
++# Tell versions [3.59,3.63) of GNU make to not export all variables.
++# Otherwise a system limit (for SysV at least) may be exceeded.
++.NOEXPORT:
+diff -urN ../newlib-1.11.0.orig/newlib/libc/sys/mipsunknown/aclocal.m4 ./newlib/libc/sys/mipsunknown/aclocal.m4
+--- ../newlib-1.11.0.orig/newlib/libc/sys/mipsunknown/aclocal.m4 Wed Dec 31 19:00:00 1969
++++ ./newlib/libc/sys/mipsunknown/aclocal.m4 Mon Nov 24 20:40:47 2003
+@@ -0,0 +1,324 @@
++dnl aclocal.m4 generated automatically by aclocal 1.4
++
++dnl Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
++dnl This file is free software; the Free Software Foundation
++dnl gives unlimited permission to copy and/or distribute it,
++dnl with or without modifications, as long as this notice is preserved.
++
++dnl This program is distributed in the hope that it will be useful,
++dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without
++dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A
++dnl PARTICULAR PURPOSE.
++
++dnl This provides configure definitions used by all the newlib
++dnl configure.in files.
++
++dnl Basic newlib configury. This calls basic introductory stuff,
++dnl including AM_INIT_AUTOMAKE and AC_CANONICAL_HOST. It also runs
++dnl configure.host. The only argument is the relative path to the top
++dnl newlib directory.
++
++AC_DEFUN(NEWLIB_CONFIGURE,
++[
++dnl Default to --enable-multilib
++AC_ARG_ENABLE(multilib,
++[ --enable-multilib build many library versions (default)],
++[case "${enableval}" in
++ yes) multilib=yes ;;
++ no) multilib=no ;;
++ *) AC_MSG_ERROR(bad value ${enableval} for multilib option) ;;
++ esac], [multilib=yes])dnl
++
++dnl Support --enable-target-optspace
++AC_ARG_ENABLE(target-optspace,
++[ --enable-target-optspace optimize for space],
++[case "${enableval}" in
++ yes) target_optspace=yes ;;
++ no) target_optspace=no ;;
++ *) AC_MSG_ERROR(bad value ${enableval} for target-optspace option) ;;
++ esac], [target_optspace=])dnl
++
++dnl Support --enable-malloc-debugging - currently only supported for Cygwin
++AC_ARG_ENABLE(malloc-debugging,
++[ --enable-malloc-debugging indicate malloc debugging requested],
++[case "${enableval}" in
++ yes) malloc_debugging=yes ;;
++ no) malloc_debugging=no ;;
++ *) AC_MSG_ERROR(bad value ${enableval} for malloc-debugging option) ;;
++ esac], [malloc_debugging=])dnl
++
++dnl Support --enable-newlib-mb
++AC_ARG_ENABLE(newlib-mb,
++[ --enable-newlib-mb enable multibyte support],
++[case "${enableval}" in
++ yes) newlib_mb=yes ;;
++ no) newlib_mb=no ;;
++ *) AC_MSG_ERROR(bad value ${enableval} for newlib-mb option) ;;
++ esac], [newlib_mb=])dnl
++
++dnl Support --enable-newlib-multithread
++AC_ARG_ENABLE(newlib-multithread,
++[ --enable-newlib-multithread enable support for multiple threads],
++[case "${enableval}" in
++ yes) newlib_multithread=yes ;;
++ no) newlib_multithread=no ;;
++ *) AC_MSG_ERROR(bad value ${enableval} for newlib-multithread option) ;;
++ esac], [newlib_multithread=yes])dnl
++
++dnl Support --enable-newlib-elix-level
++AC_ARG_ENABLE(newlib-elix-level,
++[ --enable-newlib-elix-level supply desired elix library level (1-4)],
++[case "${enableval}" in
++ 0) newlib_elix_level=0 ;;
++ 1) newlib_elix_level=1 ;;
++ 2) newlib_elix_level=2 ;;
++ 3) newlib_elix_level=3 ;;
++ 4) newlib_elix_level=4 ;;
++ *) AC_MSG_ERROR(bad value ${enableval} for newlib-elix-level option) ;;
++ esac], [newlib_elix_level=0])dnl
++
++dnl Support --disable-newlib-io-float
++AC_ARG_ENABLE(newlib-io-float,
++[ --disable-newlib-io-float disable printf/scanf family float support],
++[case "${enableval}" in
++ yes) newlib_io_float=yes ;;
++ no) newlib_io_float=no ;;
++ *) AC_MSG_ERROR(bad value ${enableval} for newlib-io-float option) ;;
++ esac], [newlib_io_float=yes])dnl
++
++
++dnl We may get other options which we don't document:
++dnl --with-target-subdir, --with-multisrctop, --with-multisubdir
++
++test -z "[$]{with_target_subdir}" && with_target_subdir=.
++
++if test "[$]{srcdir}" = "."; then
++ if test "[$]{with_target_subdir}" != "."; then
++ newlib_basedir="[$]{srcdir}/[$]{with_multisrctop}../$1"
++ else
++ newlib_basedir="[$]{srcdir}/[$]{with_multisrctop}$1"
++ fi
++else
++ newlib_basedir="[$]{srcdir}/$1"
++fi
++AC_SUBST(newlib_basedir)
++
++AC_CANONICAL_SYSTEM
++
++AM_INIT_AUTOMAKE(newlib, 1.11.0)
++
++# FIXME: We temporarily define our own version of AC_PROG_CC. This is
++# copied from autoconf 2.12, but does not call AC_PROG_CC_WORKS. We
++# are probably using a cross compiler, which will not be able to fully
++# link an executable. This should really be fixed in autoconf
++# itself.
++
++AC_DEFUN(LIB_AC_PROG_CC,
++[AC_BEFORE([$0], [AC_PROG_CPP])dnl
++AC_CHECK_PROG(CC, gcc, gcc)
++if test -z "$CC"; then
++ AC_CHECK_PROG(CC, cc, cc, , , /usr/ucb/cc)
++ test -z "$CC" && AC_MSG_ERROR([no acceptable cc found in \$PATH])
++fi
++
++AC_PROG_CC_GNU
++
++if test $ac_cv_prog_gcc = yes; then
++ GCC=yes
++dnl Check whether -g works, even if CFLAGS is set, in case the package
++dnl plays around with CFLAGS (such as to build both debugging and
++dnl normal versions of a library), tasteless as that idea is.
++ ac_test_CFLAGS="${CFLAGS+set}"
++ ac_save_CFLAGS="$CFLAGS"
++ CFLAGS=
++ AC_PROG_CC_G
++ if test "$ac_test_CFLAGS" = set; then
++ CFLAGS="$ac_save_CFLAGS"
++ elif test $ac_cv_prog_cc_g = yes; then
++ CFLAGS="-g -O2"
++ else
++ CFLAGS="-O2"
++ fi
++else
++ GCC=
++ test "${CFLAGS+set}" = set || CFLAGS="-g"
++fi
++])
++
++LIB_AC_PROG_CC
++
++AC_CHECK_TOOL(AS, as)
++AC_CHECK_TOOL(AR, ar)
++AC_CHECK_TOOL(RANLIB, ranlib, :)
++
++AC_PROG_INSTALL
++
++AM_MAINTAINER_MODE
++
++# We need AC_EXEEXT to keep automake happy in cygnus mode. However,
++# at least currently, we never actually build a program, so we never
++# need to use $(EXEEXT). Moreover, the test for EXEEXT normally
++# fails, because we are probably configuring with a cross compiler
++# which can't create executables. So we include AC_EXEEXT to keep
++# automake happy, but we don't execute it, since we don't care about
++# the result.
++if false; then
++ AC_EXEEXT
++fi
++
++. [$]{newlib_basedir}/configure.host
++
++newlib_cflags="[$]{newlib_cflags} -fno-builtin"
++
++NEWLIB_CFLAGS=${newlib_cflags}
++AC_SUBST(NEWLIB_CFLAGS)
++
++LDFLAGS=${ldflags}
++AC_SUBST(LDFLAGS)
++
++AM_CONDITIONAL(ELIX_LEVEL_0, test x[$]{newlib_elix_level} = x0)
++AM_CONDITIONAL(ELIX_LEVEL_1, test x[$]{newlib_elix_level} = x1)
++AM_CONDITIONAL(ELIX_LEVEL_2, test x[$]{newlib_elix_level} = x2)
++AM_CONDITIONAL(ELIX_LEVEL_3, test x[$]{newlib_elix_level} = x3)
++AM_CONDITIONAL(ELIX_LEVEL_4, test x[$]{newlib_elix_level} = x4)
++
++AM_CONDITIONAL(USE_LIBTOOL, test x[$]{use_libtool} = xyes)
++
++# Hard-code OBJEXT. Normally it is set by AC_OBJEXT, but we
++# use oext, which is set in configure.host based on the target platform.
++OBJEXT=${oext}
++
++AC_SUBST(OBJEXT)
++AC_SUBST(oext)
++AC_SUBST(aext)
++
++AC_SUBST(libm_machine_dir)
++AC_SUBST(machine_dir)
++AC_SUBST(sys_dir)
++])
++
++# Do all the work for Automake. This macro actually does too much --
++# some checks are only needed if your package does certain things.
++# But this isn't really a big deal.
++
++# serial 1
++
++dnl Usage:
++dnl AM_INIT_AUTOMAKE(package,version, [no-define])
++
++AC_DEFUN(AM_INIT_AUTOMAKE,
++[AC_REQUIRE([AC_PROG_INSTALL])
++PACKAGE=[$1]
++AC_SUBST(PACKAGE)
++VERSION=[$2]
++AC_SUBST(VERSION)
++dnl test to see if srcdir already configured
++if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
++ AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
++fi
++ifelse([$3],,
++AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
++AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package]))
++AC_REQUIRE([AM_SANITY_CHECK])
++AC_REQUIRE([AC_ARG_PROGRAM])
++dnl FIXME This is truly gross.
++missing_dir=`cd $ac_aux_dir && pwd`
++AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir)
++AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir)
++AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir)
++AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir)
++AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir)
++AC_REQUIRE([AC_PROG_MAKE_SET])])
++
++#
++# Check to make sure that the build environment is sane.
++#
++
++AC_DEFUN(AM_SANITY_CHECK,
++[AC_MSG_CHECKING([whether build environment is sane])
++# Just in case
++sleep 1
++echo timestamp > conftestfile
++# Do `set' in a subshell so we don't clobber the current shell's
++# arguments. Must try -L first in case configure is actually a
++# symlink; some systems play weird games with the mod time of symlinks
++# (eg FreeBSD returns the mod time of the symlink's containing
++# directory).
++if (
++ set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null`
++ if test "[$]*" = "X"; then
++ # -L didn't work.
++ set X `ls -t $srcdir/configure conftestfile`
++ fi
++ if test "[$]*" != "X $srcdir/configure conftestfile" \
++ && test "[$]*" != "X conftestfile $srcdir/configure"; then
++
++ # If neither matched, then we have a broken ls. This can happen
++ # if, for instance, CONFIG_SHELL is bash and it inherits a
++ # broken ls alias from the environment. This has actually
++ # happened. Such a system could not be considered "sane".
++ AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
++alias in your environment])
++ fi
++
++ test "[$]2" = conftestfile
++ )
++then
++ # Ok.
++ :
++else
++ AC_MSG_ERROR([newly created file is older than distributed files!
++Check your system clock])
++fi
++rm -f conftest*
++AC_MSG_RESULT(yes)])
++
++dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY)
++dnl The program must properly implement --version.
++AC_DEFUN(AM_MISSING_PROG,
++[AC_MSG_CHECKING(for working $2)
++# Run test in a subshell; some versions of sh will print an error if
++# an executable is not found, even if stderr is redirected.
++# Redirect stdin to placate older versions of autoconf. Sigh.
++if ($2 --version) < /dev/null > /dev/null 2>&1; then
++ $1=$2
++ AC_MSG_RESULT(found)
++else
++ $1="$3/missing $2"
++ AC_MSG_RESULT(missing)
++fi
++AC_SUBST($1)])
++
++# Add --enable-maintainer-mode option to configure.
++# From Jim Meyering
++
++# serial 1
++
++AC_DEFUN(AM_MAINTAINER_MODE,
++[AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
++ dnl maintainer-mode is disabled by default
++ AC_ARG_ENABLE(maintainer-mode,
++[ --enable-maintainer-mode enable make rules and dependencies not useful
++ (and sometimes confusing) to the casual installer],
++ USE_MAINTAINER_MODE=$enableval,
++ USE_MAINTAINER_MODE=no)
++ AC_MSG_RESULT($USE_MAINTAINER_MODE)
++ AM_CONDITIONAL(MAINTAINER_MODE, test $USE_MAINTAINER_MODE = yes)
++ MAINT=$MAINTAINER_MODE_TRUE
++ AC_SUBST(MAINT)dnl
++]
++)
++
++# Define a conditional.
++
++AC_DEFUN(AM_CONDITIONAL,
++[AC_SUBST($1_TRUE)
++AC_SUBST($1_FALSE)
++if $2; then
++ $1_TRUE=
++ $1_FALSE='#'
++else
++ $1_TRUE='#'
++ $1_FALSE=
++fi])
++
+diff -urN ../newlib-1.11.0.orig/newlib/libc/sys/mipsunknown/configure ./newlib/libc/sys/mipsunknown/configure
+--- ../newlib-1.11.0.orig/newlib/libc/sys/mipsunknown/configure Wed Dec 31 19:00:00 1969
++++ ./newlib/libc/sys/mipsunknown/configure Mon Nov 24 20:43:05 2003
+@@ -0,0 +1,1863 @@
++#! /bin/sh
++
++# Guess values for system-dependent variables and create Makefiles.
++# Generated automatically using autoconf version 2.13
++# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
++#
++# This configure script is free software; the Free Software Foundation
++# gives unlimited permission to copy, distribute and modify it.
++
++# Defaults:
++ac_help=
++ac_default_prefix=/usr/local
++# Any additions from configure.in:
++ac_help="$ac_help
++ --enable-multilib build many library versions (default)"
++ac_help="$ac_help
++ --enable-target-optspace optimize for space"
++ac_help="$ac_help
++ --enable-malloc-debugging indicate malloc debugging requested"
++ac_help="$ac_help
++ --enable-newlib-mb enable multibyte support"
++ac_help="$ac_help
++ --enable-newlib-multithread enable support for multiple threads"
++ac_help="$ac_help
++ --enable-newlib-elix-level supply desired elix library level (1-4)"
++ac_help="$ac_help
++ --disable-newlib-io-float disable printf/scanf family float support"
++ac_help="$ac_help
++ --enable-maintainer-mode enable make rules and dependencies not useful
++ (and sometimes confusing) to the casual installer"
++
++# Initialize some variables set by options.
++# The variables have the same names as the options, with
++# dashes changed to underlines.
++build=NONE
++cache_file=./config.cache
++exec_prefix=NONE
++host=NONE
++no_create=
++nonopt=NONE
++no_recursion=
++prefix=NONE
++program_prefix=NONE
++program_suffix=NONE
++program_transform_name=s,x,x,
++silent=
++site=
++sitefile=
++srcdir=
++target=NONE
++verbose=
++x_includes=NONE
++x_libraries=NONE
++bindir='${exec_prefix}/bin'
++sbindir='${exec_prefix}/sbin'
++libexecdir='${exec_prefix}/libexec'
++datadir='${prefix}/share'
++sysconfdir='${prefix}/etc'
++sharedstatedir='${prefix}/com'
++localstatedir='${prefix}/var'
++libdir='${exec_prefix}/lib'
++includedir='${prefix}/include'
++oldincludedir='/usr/include'
++infodir='${prefix}/info'
++mandir='${prefix}/man'
++
++# Initialize some other variables.
++subdirs=
++MFLAGS= MAKEFLAGS=
++SHELL=${CONFIG_SHELL-/bin/sh}
++# Maximum number of lines to put in a shell here document.
++ac_max_here_lines=12
++
++ac_prev=
++for ac_option
++do
++
++ # If the previous option needs an argument, assign it.
++ if test -n "$ac_prev"; then
++ eval "$ac_prev=\$ac_option"
++ ac_prev=
++ continue
++ fi
++
++ case "$ac_option" in
++ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
++ *) ac_optarg= ;;
++ esac
++
++ # Accept the important Cygnus configure options, so we can diagnose typos.
++
++ case "$ac_option" in
++
++ -bindir | --bindir | --bindi | --bind | --bin | --bi)
++ ac_prev=bindir ;;
++ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
++ bindir="$ac_optarg" ;;
++
++ -build | --build | --buil | --bui | --bu)
++ ac_prev=build ;;
++ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
++ build="$ac_optarg" ;;
++
++ -cache-file | --cache-file | --cache-fil | --cache-fi \
++ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
++ ac_prev=cache_file ;;
++ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
++ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
++ cache_file="$ac_optarg" ;;
++
++ -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
++ ac_prev=datadir ;;
++ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
++ | --da=*)
++ datadir="$ac_optarg" ;;
++
++ -disable-* | --disable-*)
++ ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
++ # Reject names that are not valid shell variable names.
++ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
++ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
++ fi
++ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
++ eval "enable_${ac_feature}=no" ;;
++
++ -enable-* | --enable-*)
++ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
++ # Reject names that are not valid shell variable names.
++ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
++ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
++ fi
++ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
++ case "$ac_option" in
++ *=*) ;;
++ *) ac_optarg=yes ;;
++ esac
++ eval "enable_${ac_feature}='$ac_optarg'" ;;
++
++ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
++ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
++ | --exec | --exe | --ex)
++ ac_prev=exec_prefix ;;
++ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
++ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
++ | --exec=* | --exe=* | --ex=*)
++ exec_prefix="$ac_optarg" ;;
++
++ -gas | --gas | --ga | --g)
++ # Obsolete; use --with-gas.
++ with_gas=yes ;;
++
++ -help | --help | --hel | --he)
++ # Omit some internal or obsolete options to make the list less imposing.
++ # This message is too long to be a string in the A/UX 3.1 sh.
++ cat << EOF
++Usage: configure [options] [host]
++Options: [defaults in brackets after descriptions]
++Configuration:
++ --cache-file=FILE cache test results in FILE
++ --help print this message
++ --no-create do not create output files
++ --quiet, --silent do not print \`checking...' messages
++ --site-file=FILE use FILE as the site file
++ --version print the version of autoconf that created configure
++Directory and file names:
++ --prefix=PREFIX install architecture-independent files in PREFIX
++ [$ac_default_prefix]
++ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
++ [same as prefix]
++ --bindir=DIR user executables in DIR [EPREFIX/bin]
++ --sbindir=DIR system admin executables in DIR [EPREFIX/sbin]
++ --libexecdir=DIR program executables in DIR [EPREFIX/libexec]
++ --datadir=DIR read-only architecture-independent data in DIR
++ [PREFIX/share]
++ --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]
++ --sharedstatedir=DIR modifiable architecture-independent data in DIR
++ [PREFIX/com]
++ --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var]
++ --libdir=DIR object code libraries in DIR [EPREFIX/lib]
++ --includedir=DIR C header files in DIR [PREFIX/include]
++ --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include]
++ --infodir=DIR info documentation in DIR [PREFIX/info]
++ --mandir=DIR man documentation in DIR [PREFIX/man]
++ --srcdir=DIR find the sources in DIR [configure dir or ..]
++ --program-prefix=PREFIX prepend PREFIX to installed program names
++ --program-suffix=SUFFIX append SUFFIX to installed program names
++ --program-transform-name=PROGRAM
++ run sed PROGRAM on installed program names
++EOF
++ cat << EOF
++Host type:
++ --build=BUILD configure for building on BUILD [BUILD=HOST]
++ --host=HOST configure for HOST [guessed]
++ --target=TARGET configure for TARGET [TARGET=HOST]
++Features and packages:
++ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
++ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
++ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
++ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
++ --x-includes=DIR X include files are in DIR
++ --x-libraries=DIR X library files are in DIR
++EOF
++ if test -n "$ac_help"; then
++ echo "--enable and --with options recognized:$ac_help"
++ fi
++ exit 0 ;;
++
++ -host | --host | --hos | --ho)
++ ac_prev=host ;;
++ -host=* | --host=* | --hos=* | --ho=*)
++ host="$ac_optarg" ;;
++
++ -includedir | --includedir | --includedi | --included | --include \
++ | --includ | --inclu | --incl | --inc)
++ ac_prev=includedir ;;
++ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
++ | --includ=* | --inclu=* | --incl=* | --inc=*)
++ includedir="$ac_optarg" ;;
++
++ -infodir | --infodir | --infodi | --infod | --info | --inf)
++ ac_prev=infodir ;;
++ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
++ infodir="$ac_optarg" ;;
++
++ -libdir | --libdir | --libdi | --libd)
++ ac_prev=libdir ;;
++ -libdir=* | --libdir=* | --libdi=* | --libd=*)
++ libdir="$ac_optarg" ;;
++
++ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
++ | --libexe | --libex | --libe)
++ ac_prev=libexecdir ;;
++ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
++ | --libexe=* | --libex=* | --libe=*)
++ libexecdir="$ac_optarg" ;;
++
++ -localstatedir | --localstatedir | --localstatedi | --localstated \
++ | --localstate | --localstat | --localsta | --localst \
++ | --locals | --local | --loca | --loc | --lo)
++ ac_prev=localstatedir ;;
++ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
++ | --localstate=* | --localstat=* | --localsta=* | --localst=* \
++ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
++ localstatedir="$ac_optarg" ;;
++
++ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
++ ac_prev=mandir ;;
++ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
++ mandir="$ac_optarg" ;;
++
++ -nfp | --nfp | --nf)
++ # Obsolete; use --without-fp.
++ with_fp=no ;;
++
++ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
++ | --no-cr | --no-c)
++ no_create=yes ;;
++
++ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
++ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
++ no_recursion=yes ;;
++
++ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
++ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
++ | --oldin | --oldi | --old | --ol | --o)
++ ac_prev=oldincludedir ;;
++ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
++ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
++ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
++ oldincludedir="$ac_optarg" ;;
++
++ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
++ ac_prev=prefix ;;
++ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
++ prefix="$ac_optarg" ;;
++
++ -program-prefix | --program-prefix | --program-prefi | --program-pref \
++ | --program-pre | --program-pr | --program-p)
++ ac_prev=program_prefix ;;
++ -program-prefix=* | --program-prefix=* | --program-prefi=* \
++ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
++ program_prefix="$ac_optarg" ;;
++
++ -program-suffix | --program-suffix | --program-suffi | --program-suff \
++ | --program-suf | --program-su | --program-s)
++ ac_prev=program_suffix ;;
++ -program-suffix=* | --program-suffix=* | --program-suffi=* \
++ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
++ program_suffix="$ac_optarg" ;;
++
++ -program-transform-name | --program-transform-name \
++ | --program-transform-nam | --program-transform-na \
++ | --program-transform-n | --program-transform- \
++ | --program-transform | --program-transfor \
++ | --program-transfo | --program-transf \
++ | --program-trans | --program-tran \
++ | --progr-tra | --program-tr | --program-t)
++ ac_prev=program_transform_name ;;
++ -program-transform-name=* | --program-transform-name=* \
++ | --program-transform-nam=* | --program-transform-na=* \
++ | --program-transform-n=* | --program-transform-=* \
++ | --program-transform=* | --program-transfor=* \
++ | --program-transfo=* | --program-transf=* \
++ | --program-trans=* | --program-tran=* \
++ | --progr-tra=* | --program-tr=* | --program-t=*)
++ program_transform_name="$ac_optarg" ;;
++
++ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
++ | -silent | --silent | --silen | --sile | --sil)
++ silent=yes ;;
++
++ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
++ ac_prev=sbindir ;;
++ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
++ | --sbi=* | --sb=*)
++ sbindir="$ac_optarg" ;;
++
++ -sharedstatedir | --sharedstatedir | --sharedstatedi \
++ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
++ | --sharedst | --shareds | --shared | --share | --shar \
++ | --sha | --sh)
++ ac_prev=sharedstatedir ;;
++ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
++ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
++ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
++ | --sha=* | --sh=*)
++ sharedstatedir="$ac_optarg" ;;
++
++ -site | --site | --sit)
++ ac_prev=site ;;
++ -site=* | --site=* | --sit=*)
++ site="$ac_optarg" ;;
++
++ -site-file | --site-file | --site-fil | --site-fi | --site-f)
++ ac_prev=sitefile ;;
++ -site-file=* | --site-file=* | --site-fil=* | --site-fi=* | --site-f=*)
++ sitefile="$ac_optarg" ;;
++
++ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
++ ac_prev=srcdir ;;
++ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
++ srcdir="$ac_optarg" ;;
++
++ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
++ | --syscon | --sysco | --sysc | --sys | --sy)
++ ac_prev=sysconfdir ;;
++ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
++ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
++ sysconfdir="$ac_optarg" ;;
++
++ -target | --target | --targe | --targ | --tar | --ta | --t)
++ ac_prev=target ;;
++ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
++ target="$ac_optarg" ;;
++
++ -v | -verbose | --verbose | --verbos | --verbo | --verb)
++ verbose=yes ;;
++
++ -version | --version | --versio | --versi | --vers)
++ echo "configure generated by autoconf version 2.13"
++ exit 0 ;;
++
++ -with-* | --with-*)
++ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
++ # Reject names that are not valid shell variable names.
++ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
++ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
++ fi
++ ac_package=`echo $ac_package| sed 's/-/_/g'`
++ case "$ac_option" in
++ *=*) ;;
++ *) ac_optarg=yes ;;
++ esac
++ eval "with_${ac_package}='$ac_optarg'" ;;
++
++ -without-* | --without-*)
++ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
++ # Reject names that are not valid shell variable names.
++ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
++ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
++ fi
++ ac_package=`echo $ac_package| sed 's/-/_/g'`
++ eval "with_${ac_package}=no" ;;
++
++ --x)
++ # Obsolete; use --with-x.
++ with_x=yes ;;
++
++ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
++ | --x-incl | --x-inc | --x-in | --x-i)
++ ac_prev=x_includes ;;
++ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
++ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
++ x_includes="$ac_optarg" ;;
++
++ -x-libraries | --x-libraries | --x-librarie | --x-librari \
++ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
++ ac_prev=x_libraries ;;
++ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
++ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
++ x_libraries="$ac_optarg" ;;
++
++ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
++ ;;
++
++ *)
++ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
++ echo "configure: warning: $ac_option: invalid host type" 1>&2
++ fi
++ if test "x$nonopt" != xNONE; then
++ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
++ fi
++ nonopt="$ac_option"
++ ;;
++
++ esac
++done
++
++if test -n "$ac_prev"; then
++ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
++fi
++
++trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
++
++# File descriptor usage:
++# 0 standard input
++# 1 file creation
++# 2 errors and warnings
++# 3 some systems may open it to /dev/tty
++# 4 used on the Kubota Titan
++# 6 checking for... messages and results
++# 5 compiler messages saved in config.log
++if test "$silent" = yes; then
++ exec 6>/dev/null
++else
++ exec 6>&1
++fi
++exec 5>./config.log
++
++echo "\
++This file contains any messages produced by compilers while
++running configure, to aid debugging if configure makes a mistake.
++" 1>&5
++
++# Strip out --no-create and --no-recursion so they do not pile up.
++# Also quote any args containing shell metacharacters.
++ac_configure_args=
++for ac_arg
++do
++ case "$ac_arg" in
++ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
++ | --no-cr | --no-c) ;;
++ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
++ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
++ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
++ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
++ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
++ esac
++done
++
++# NLS nuisances.
++# Only set these to C if already set. These must not be set unconditionally
++# because not all systems understand e.g. LANG=C (notably SCO).
++# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
++# Non-C LC_CTYPE values break the ctype check.
++if test "${LANG+set}" = set; then LANG=C; export LANG; fi
++if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
++if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
++if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
++
++# confdefs.h avoids OS command line length limits that DEFS can exceed.
++rm -rf conftest* confdefs.h
++# AIX cpp loses on an empty file, so make sure it contains at least a newline.
++echo > confdefs.h
++
++# A filename unique to this package, relative to the directory that
++# configure is in, which we can look for to find out if srcdir is correct.
++ac_unique_file=syscalls.c
++
++# Find the source files, if location was not specified.
++if test -z "$srcdir"; then
++ ac_srcdir_defaulted=yes
++ # Try the directory containing this script, then its parent.
++ ac_prog=$0
++ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
++ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
++ srcdir=$ac_confdir
++ if test ! -r $srcdir/$ac_unique_file; then
++ srcdir=..
++ fi
++else
++ ac_srcdir_defaulted=no
++fi
++if test ! -r $srcdir/$ac_unique_file; then
++ if test "$ac_srcdir_defaulted" = yes; then
++ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
++ else
++ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
++ fi
++fi
++srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
++
++# Prefer explicitly selected file to automatically selected ones.
++if test -z "$sitefile"; then
++ if test -z "$CONFIG_SITE"; then
++ if test "x$prefix" != xNONE; then
++ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
++ else
++ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
++ fi
++ fi
++else
++ CONFIG_SITE="$sitefile"
++fi
++for ac_site_file in $CONFIG_SITE; do
++ if test -r "$ac_site_file"; then
++ echo "loading site script $ac_site_file"
++ . "$ac_site_file"
++ fi
++done
++
++if test -r "$cache_file"; then
++ echo "loading cache $cache_file"
++ . $cache_file
++else
++ echo "creating cache $cache_file"
++ > $cache_file
++fi
++
++ac_ext=c
++# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
++ac_cpp='$CPP $CPPFLAGS'
++ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
++ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
++cross_compiling=$ac_cv_prog_cc_cross
++
++ac_exeext=
++ac_objext=o
++if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
++ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
++ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
++ ac_n= ac_c='
++' ac_t=' '
++ else
++ ac_n=-n ac_c= ac_t=
++ fi
++else
++ ac_n= ac_c='\c' ac_t=
++fi
++
++
++
++ac_aux_dir=
++for ac_dir in ../../../.. $srcdir/../../../..; do
++ if test -f $ac_dir/install-sh; then
++ ac_aux_dir=$ac_dir
++ ac_install_sh="$ac_aux_dir/install-sh -c"
++ break
++ elif test -f $ac_dir/install.sh; then
++ ac_aux_dir=$ac_dir
++ ac_install_sh="$ac_aux_dir/install.sh -c"
++ break
++ fi
++done
++if test -z "$ac_aux_dir"; then
++ { echo "configure: error: can not find install-sh or install.sh in ../../../.. $srcdir/../../../.." 1>&2; exit 1; }
++fi
++ac_config_guess=$ac_aux_dir/config.guess
++ac_config_sub=$ac_aux_dir/config.sub
++ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
++
++
++# Find a good install program. We prefer a C program (faster),
++# so one script is as good as another. But avoid the broken or
++# incompatible versions:
++# SysV /etc/install, /usr/sbin/install
++# SunOS /usr/etc/install
++# IRIX /sbin/install
++# AIX /bin/install
++# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
++# AFS /usr/afsws/bin/install, which mishandles nonexistent args
++# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
++# ./install, which can be erroneously created by make from ./install.sh.
++echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
++echo "configure:586: checking for a BSD compatible install" >&5
++if test -z "$INSTALL"; then
++if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
++ echo $ac_n "(cached) $ac_c" 1>&6
++else
++ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":"
++ for ac_dir in $PATH; do
++ # Account for people who put trailing slashes in PATH elements.
++ case "$ac_dir/" in
++ /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
++ *)
++ # OSF1 and SCO ODT 3.0 have their own names for install.
++ # Don't use installbsd from OSF since it installs stuff as root
++ # by default.
++ for ac_prog in ginstall scoinst install; do
++ if test -f $ac_dir/$ac_prog; then
++ if test $ac_prog = install &&
++ grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
++ # AIX install. It has an incompatible calling convention.
++ :
++ else
++ ac_cv_path_install="$ac_dir/$ac_prog -c"
++ break 2
++ fi
++ fi
++ done
++ ;;
++ esac
++ done
++ IFS="$ac_save_IFS"
++
++fi
++ if test "${ac_cv_path_install+set}" = set; then
++ INSTALL="$ac_cv_path_install"
++ else
++ # As a last resort, use the slow shell script. We don't cache a
++ # path for INSTALL within a source directory, because that will
++ # break other packages using the cache if that directory is
++ # removed, or if the path is relative.
++ INSTALL="$ac_install_sh"
++ fi
++fi
++echo "$ac_t""$INSTALL" 1>&6
++
++# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
++# It thinks the first close brace ends the variable substitution.
++test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
++
++test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
++
++test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
++
++echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6
++echo "configure:639: checking whether build environment is sane" >&5
++# Just in case
++sleep 1
++echo timestamp > conftestfile
++# Do `set' in a subshell so we don't clobber the current shell's
++# arguments. Must try -L first in case configure is actually a
++# symlink; some systems play weird games with the mod time of symlinks
++# (eg FreeBSD returns the mod time of the symlink's containing
++# directory).
++if (
++ set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null`
++ if test "$*" = "X"; then
++ # -L didn't work.
++ set X `ls -t $srcdir/configure conftestfile`
++ fi
++ if test "$*" != "X $srcdir/configure conftestfile" \
++ && test "$*" != "X conftestfile $srcdir/configure"; then
++
++ # If neither matched, then we have a broken ls. This can happen
++ # if, for instance, CONFIG_SHELL is bash and it inherits a
++ # broken ls alias from the environment. This has actually
++ # happened. Such a system could not be considered "sane".
++ { echo "configure: error: ls -t appears to fail. Make sure there is not a broken
++alias in your environment" 1>&2; exit 1; }
++ fi
++
++ test "$2" = conftestfile
++ )
++then
++ # Ok.
++ :
++else
++ { echo "configure: error: newly created file is older than distributed files!
++Check your system clock" 1>&2; exit 1; }
++fi
++rm -f conftest*
++echo "$ac_t""yes" 1>&6
++if test "$program_transform_name" = s,x,x,; then
++ program_transform_name=
++else
++ # Double any \ or $. echo might interpret backslashes.
++ cat <<\EOF_SED > conftestsed
++s,\\,\\\\,g; s,\$,$$,g
++EOF_SED
++ program_transform_name="`echo $program_transform_name|sed -f conftestsed`"
++ rm -f conftestsed
++fi
++test "$program_prefix" != NONE &&
++ program_transform_name="s,^,${program_prefix},; $program_transform_name"
++# Use a double $ so make ignores it.
++test "$program_suffix" != NONE &&
++ program_transform_name="s,\$\$,${program_suffix},; $program_transform_name"
++
++# sed with no file args requires a program.
++test "$program_transform_name" = "" && program_transform_name="s,x,x,"
++
++echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
++echo "configure:696: checking whether ${MAKE-make} sets \${MAKE}" >&5
++set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
++if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
++ echo $ac_n "(cached) $ac_c" 1>&6
++else
++ cat > conftestmake <<\EOF
++all:
++ @echo 'ac_maketemp="${MAKE}"'
++EOF
++# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
++eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=`
++if test -n "$ac_maketemp"; then
++ eval ac_cv_prog_make_${ac_make}_set=yes
++else
++ eval ac_cv_prog_make_${ac_make}_set=no
++fi
++rm -f conftestmake
++fi
++if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
++ echo "$ac_t""yes" 1>&6
++ SET_MAKE=
++else
++ echo "$ac_t""no" 1>&6
++ SET_MAKE="MAKE=${MAKE-make}"
++fi
++
++if test $host != $build; then
++ ac_tool_prefix=${host_alias}-
++else
++ ac_tool_prefix=
++fi
++
++echo $ac_n "checking for Cygwin environment""... $ac_c" 1>&6
++echo "configure:729: checking for Cygwin environment" >&5
++if eval "test \"`echo '$''{'ac_cv_cygwin'+set}'`\" = set"; then
++ echo $ac_n "(cached) $ac_c" 1>&6
++else
++ cat > conftest.$ac_ext <<EOF
++#line 734 "configure"
++#include "confdefs.h"
++
++int main() {
++
++#ifndef __CYGWIN__
++#define __CYGWIN__ __CYGWIN32__
++#endif
++return __CYGWIN__;
++; return 0; }
++EOF
++if { (eval echo configure:745: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
++ rm -rf conftest*
++ ac_cv_cygwin=yes
++else
++ echo "configure: failed program was:" >&5
++ cat conftest.$ac_ext >&5
++ rm -rf conftest*
++ ac_cv_cygwin=no
++fi
++rm -f conftest*
++rm -f conftest*
++fi
++
++echo "$ac_t""$ac_cv_cygwin" 1>&6
++CYGWIN=
++test "$ac_cv_cygwin" = yes && CYGWIN=yes
++echo $ac_n "checking for mingw32 environment""... $ac_c" 1>&6
++echo "configure:762: checking for mingw32 environment" >&5
++if eval "test \"`echo '$''{'ac_cv_mingw32'+set}'`\" = set"; then
++ echo $ac_n "(cached) $ac_c" 1>&6
++else
++ cat > conftest.$ac_ext <<EOF
++#line 767 "configure"
++#include "confdefs.h"
++
++int main() {
++return __MINGW32__;
++; return 0; }
++EOF
++if { (eval echo configure:774: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
++ rm -rf conftest*
++ ac_cv_mingw32=yes
++else
++ echo "configure: failed program was:" >&5
++ cat conftest.$ac_ext >&5
++ rm -rf conftest*
++ ac_cv_mingw32=no
++fi
++rm -f conftest*
++rm -f conftest*
++fi
++
++echo "$ac_t""$ac_cv_mingw32" 1>&6
++MINGW32=
++test "$ac_cv_mingw32" = yes && MINGW32=yes
++
++# Check whether --enable-multilib or --disable-multilib was given.
++if test "${enable_multilib+set}" = set; then
++ enableval="$enable_multilib"
++ case "${enableval}" in
++ yes) multilib=yes ;;
++ no) multilib=no ;;
++ *) { echo "configure: error: bad value ${enableval} for multilib option" 1>&2; exit 1; } ;;
++ esac
++else
++ multilib=yes
++fi
++
++# Check whether --enable-target-optspace or --disable-target-optspace was given.
++if test "${enable_target_optspace+set}" = set; then
++ enableval="$enable_target_optspace"
++ case "${enableval}" in
++ yes) target_optspace=yes ;;
++ no) target_optspace=no ;;
++ *) { echo "configure: error: bad value ${enableval} for target-optspace option" 1>&2; exit 1; } ;;
++ esac
++else
++ target_optspace=
++fi
++
++# Check whether --enable-malloc-debugging or --disable-malloc-debugging was given.
++if test "${enable_malloc_debugging+set}" = set; then
++ enableval="$enable_malloc_debugging"
++ case "${enableval}" in
++ yes) malloc_debugging=yes ;;
++ no) malloc_debugging=no ;;
++ *) { echo "configure: error: bad value ${enableval} for malloc-debugging option" 1>&2; exit 1; } ;;
++ esac
++else
++ malloc_debugging=
++fi
++
++# Check whether --enable-newlib-mb or --disable-newlib-mb was given.
++if test "${enable_newlib_mb+set}" = set; then
++ enableval="$enable_newlib_mb"
++ case "${enableval}" in
++ yes) newlib_mb=yes ;;
++ no) newlib_mb=no ;;
++ *) { echo "configure: error: bad value ${enableval} for newlib-mb option" 1>&2; exit 1; } ;;
++ esac
++else
++ newlib_mb=
++fi
++
++# Check whether --enable-newlib-multithread or --disable-newlib-multithread was given.
++if test "${enable_newlib_multithread+set}" = set; then
++ enableval="$enable_newlib_multithread"
++ case "${enableval}" in
++ yes) newlib_multithread=yes ;;
++ no) newlib_multithread=no ;;
++ *) { echo "configure: error: bad value ${enableval} for newlib-multithread option" 1>&2; exit 1; } ;;
++ esac
++else
++ newlib_multithread=yes
++fi
++
++# Check whether --enable-newlib-elix-level or --disable-newlib-elix-level was given.
++if test "${enable_newlib_elix_level+set}" = set; then
++ enableval="$enable_newlib_elix_level"
++ case "${enableval}" in
++ 0) newlib_elix_level=0 ;;
++ 1) newlib_elix_level=1 ;;
++ 2) newlib_elix_level=2 ;;
++ 3) newlib_elix_level=3 ;;
++ 4) newlib_elix_level=4 ;;
++ *) { echo "configure: error: bad value ${enableval} for newlib-elix-level option" 1>&2; exit 1; } ;;
++ esac
++else
++ newlib_elix_level=0
++fi
++
++# Check whether --enable-newlib-io-float or --disable-newlib-io-float was given.
++if test "${enable_newlib_io_float+set}" = set; then
++ enableval="$enable_newlib_io_float"
++ case "${enableval}" in
++ yes) newlib_io_float=yes ;;
++ no) newlib_io_float=no ;;
++ *) { echo "configure: error: bad value ${enableval} for newlib-io-float option" 1>&2; exit 1; } ;;
++ esac
++else
++ newlib_io_float=yes
++fi
++
++
++
++test -z "${with_target_subdir}" && with_target_subdir=.
++
++if test "${srcdir}" = "."; then
++ if test "${with_target_subdir}" != "."; then
++ newlib_basedir="${srcdir}/${with_multisrctop}../../../.."
++ else
++ newlib_basedir="${srcdir}/${with_multisrctop}../../.."
++ fi
++else
++ newlib_basedir="${srcdir}/../../.."
++fi
++
++
++
++# Do some error checking and defaulting for the host and target type.
++# The inputs are:
++# configure --host=HOST --target=TARGET --build=BUILD NONOPT
++#
++# The rules are:
++# 1. You are not allowed to specify --host, --target, and nonopt at the
++# same time.
++# 2. Host defaults to nonopt.
++# 3. If nonopt is not specified, then host defaults to the current host,
++# as determined by config.guess.
++# 4. Target and build default to nonopt.
++# 5. If nonopt is not specified, then target and build default to host.
++
++# The aliases save the names the user supplied, while $host etc.
++# will get canonicalized.
++case $host---$target---$nonopt in
++NONE---*---* | *---NONE---* | *---*---NONE) ;;
++*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;;
++esac
++
++
++# Make sure we can run config.sub.
++if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
++else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
++fi
++
++echo $ac_n "checking host system type""... $ac_c" 1>&6
++echo "configure:921: checking host system type" >&5
++
++host_alias=$host
++case "$host_alias" in
++NONE)
++ case $nonopt in
++ NONE)
++ if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
++ else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
++ fi ;;
++ *) host_alias=$nonopt ;;
++ esac ;;
++esac
++
++host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
++host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
++host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
++host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
++echo "$ac_t""$host" 1>&6
++
++echo $ac_n "checking target system type""... $ac_c" 1>&6
++echo "configure:942: checking target system type" >&5
++
++target_alias=$target
++case "$target_alias" in
++NONE)
++ case $nonopt in
++ NONE) target_alias=$host_alias ;;
++ *) target_alias=$nonopt ;;
++ esac ;;
++esac
++
++target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias`
++target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
++target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
++target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
++echo "$ac_t""$target" 1>&6
++
++echo $ac_n "checking build system type""... $ac_c" 1>&6
++echo "configure:960: checking build system type" >&5
++
++build_alias=$build
++case "$build_alias" in
++NONE)
++ case $nonopt in
++ NONE) build_alias=$host_alias ;;
++ *) build_alias=$nonopt ;;
++ esac ;;
++esac
++
++build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias`
++build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
++build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
++build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
++echo "$ac_t""$build" 1>&6
++
++test "$host_alias" != "$target_alias" &&
++ test "$program_prefix$program_suffix$program_transform_name" = \
++ NONENONEs,x,x, &&
++ program_prefix=${target_alias}-
++
++
++
++PACKAGE=newlib
++
++VERSION=1.11.0
++
++if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
++ { echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; }
++fi
++cat >> confdefs.h <<EOF
++#define PACKAGE "$PACKAGE"
++EOF
++
++cat >> confdefs.h <<EOF
++#define VERSION "$VERSION"
++EOF
++
++
++
++missing_dir=`cd $ac_aux_dir && pwd`
++echo $ac_n "checking for working aclocal""... $ac_c" 1>&6
++echo "configure:1003: checking for working aclocal" >&5
++# Run test in a subshell; some versions of sh will print an error if
++# an executable is not found, even if stderr is redirected.
++# Redirect stdin to placate older versions of autoconf. Sigh.
++if (aclocal --version) < /dev/null > /dev/null 2>&1; then
++ ACLOCAL=aclocal
++ echo "$ac_t""found" 1>&6
++else
++ ACLOCAL="$missing_dir/missing aclocal"
++ echo "$ac_t""missing" 1>&6
++fi
++
++echo $ac_n "checking for working autoconf""... $ac_c" 1>&6
++echo "configure:1016: checking for working autoconf" >&5
++# Run test in a subshell; some versions of sh will print an error if
++# an executable is not found, even if stderr is redirected.
++# Redirect stdin to placate older versions of autoconf. Sigh.
++if (autoconf --version) < /dev/null > /dev/null 2>&1; then
++ AUTOCONF=autoconf
++ echo "$ac_t""found" 1>&6
++else
++ AUTOCONF="$missing_dir/missing autoconf"
++ echo "$ac_t""missing" 1>&6
++fi
++
++echo $ac_n "checking for working automake""... $ac_c" 1>&6
++echo "configure:1029: checking for working automake" >&5
++# Run test in a subshell; some versions of sh will print an error if
++# an executable is not found, even if stderr is redirected.
++# Redirect stdin to placate older versions of autoconf. Sigh.
++if (automake --version) < /dev/null > /dev/null 2>&1; then
++ AUTOMAKE=automake
++ echo "$ac_t""found" 1>&6
++else
++ AUTOMAKE="$missing_dir/missing automake"
++ echo "$ac_t""missing" 1>&6
++fi
++
++echo $ac_n "checking for working autoheader""... $ac_c" 1>&6
++echo "configure:1042: checking for working autoheader" >&5
++# Run test in a subshell; some versions of sh will print an error if
++# an executable is not found, even if stderr is redirected.
++# Redirect stdin to placate older versions of autoconf. Sigh.
++if (autoheader --version) < /dev/null > /dev/null 2>&1; then
++ AUTOHEADER=autoheader
++ echo "$ac_t""found" 1>&6
++else
++ AUTOHEADER="$missing_dir/missing autoheader"
++ echo "$ac_t""missing" 1>&6
++fi
++
++echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6
++echo "configure:1055: checking for working makeinfo" >&5
++# Run test in a subshell; some versions of sh will print an error if
++# an executable is not found, even if stderr is redirected.
++# Redirect stdin to placate older versions of autoconf. Sigh.
++if (makeinfo --version) < /dev/null > /dev/null 2>&1; then
++ MAKEINFO=makeinfo
++ echo "$ac_t""found" 1>&6
++else
++ MAKEINFO="$missing_dir/missing makeinfo"
++ echo "$ac_t""missing" 1>&6
++fi
++
++
++
++# FIXME: We temporarily define our own version of AC_PROG_CC. This is
++# copied from autoconf 2.12, but does not call AC_PROG_CC_WORKS. We
++# are probably using a cross compiler, which will not be able to fully
++# link an executable. This should really be fixed in autoconf
++# itself.
++
++
++
++# Extract the first word of "gcc", so it can be a program name with args.
++set dummy gcc; ac_word=$2
++echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
++echo "configure:1080: checking for $ac_word" >&5
++if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
++ echo $ac_n "(cached) $ac_c" 1>&6
++else
++ if test -n "$CC"; then
++ ac_cv_prog_CC="$CC" # Let the user override the test.
++else
++ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
++ ac_dummy="$PATH"
++ for ac_dir in $ac_dummy; do
++ test -z "$ac_dir" && ac_dir=.
++ if test -f $ac_dir/$ac_word; then
++ ac_cv_prog_CC="gcc"
++ break
++ fi
++ done
++ IFS="$ac_save_ifs"
++fi
++fi
++CC="$ac_cv_prog_CC"
++if test -n "$CC"; then
++ echo "$ac_t""$CC" 1>&6
++else
++ echo "$ac_t""no" 1>&6
++fi
++
++if test -z "$CC"; then
++ # Extract the first word of "cc", so it can be a program name with args.
++set dummy cc; ac_word=$2
++echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
++echo "configure:1110: checking for $ac_word" >&5
++if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
++ echo $ac_n "(cached) $ac_c" 1>&6
++else
++ if test -n "$CC"; then
++ ac_cv_prog_CC="$CC" # Let the user override the test.
++else
++ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
++ ac_prog_rejected=no
++ ac_dummy="$PATH"
++ for ac_dir in $ac_dummy; do
++ test -z "$ac_dir" && ac_dir=.
++ if test -f $ac_dir/$ac_word; then
++ if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
++ ac_prog_rejected=yes
++ continue
++ fi
++ ac_cv_prog_CC="cc"
++ break
++ fi
++ done
++ IFS="$ac_save_ifs"
++if test $ac_prog_rejected = yes; then
++ # We found a bogon in the path, so make sure we never use it.
++ set dummy $ac_cv_prog_CC
++ shift
++ if test $# -gt 0; then
++ # We chose a different compiler from the bogus one.
++ # However, it has the same basename, so the bogon will be chosen
++ # first if we set CC to just the basename; use the full file name.
++ shift
++ set dummy "$ac_dir/$ac_word" "$@"
++ shift
++ ac_cv_prog_CC="$@"
++ fi
++fi
++fi
++fi
++CC="$ac_cv_prog_CC"
++if test -n "$CC"; then
++ echo "$ac_t""$CC" 1>&6
++else
++ echo "$ac_t""no" 1>&6
++fi
++
++ test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
++fi
++
++echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
++echo "configure:1159: checking whether we are using GNU C" >&5
++if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
++ echo $ac_n "(cached) $ac_c" 1>&6
++else
++ cat > conftest.c <<EOF
++#ifdef __GNUC__
++ yes;
++#endif
++EOF
++if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1168: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
++ ac_cv_prog_gcc=yes
++else
++ ac_cv_prog_gcc=no
++fi
++fi
++
++echo "$ac_t""$ac_cv_prog_gcc" 1>&6
++
++if test $ac_cv_prog_gcc = yes; then
++ GCC=yes
++ ac_test_CFLAGS="${CFLAGS+set}"
++ ac_save_CFLAGS="$CFLAGS"
++ CFLAGS=
++ echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
++echo "configure:1183: checking whether ${CC-cc} accepts -g" >&5
++if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
++ echo $ac_n "(cached) $ac_c" 1>&6
++else
++ echo 'void f(){}' > conftest.c
++if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
++ ac_cv_prog_cc_g=yes
++else
++ ac_cv_prog_cc_g=no
++fi
++rm -f conftest*
++
++fi
++
++echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
++ if test "$ac_test_CFLAGS" = set; then
++ CFLAGS="$ac_save_CFLAGS"
++ elif test $ac_cv_prog_cc_g = yes; then
++ CFLAGS="-g -O2"
++ else
++ CFLAGS="-O2"
++ fi
++else
++ GCC=
++ test "${CFLAGS+set}" = set || CFLAGS="-g"
++fi
++
++
++# Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args.
++set dummy ${ac_tool_prefix}as; ac_word=$2
++echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
++echo "configure:1214: checking for $ac_word" >&5
++if eval "test \"`echo '$''{'ac_cv_prog_AS'+set}'`\" = set"; then
++ echo $ac_n "(cached) $ac_c" 1>&6
++else
++ if test -n "$AS"; then
++ ac_cv_prog_AS="$AS" # Let the user override the test.
++else
++ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
++ ac_dummy="$PATH"
++ for ac_dir in $ac_dummy; do
++ test -z "$ac_dir" && ac_dir=.
++ if test -f $ac_dir/$ac_word; then
++ ac_cv_prog_AS="${ac_tool_prefix}as"
++ break
++ fi
++ done
++ IFS="$ac_save_ifs"
++ test -z "$ac_cv_prog_AS" && ac_cv_prog_AS="as"
++fi
++fi
++AS="$ac_cv_prog_AS"
++if test -n "$AS"; then
++ echo "$ac_t""$AS" 1>&6
++else
++ echo "$ac_t""no" 1>&6
++fi
++
++
++
++# Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
++set dummy ${ac_tool_prefix}ar; ac_word=$2
++echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
++echo "configure:1246: checking for $ac_word" >&5
++if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then
++ echo $ac_n "(cached) $ac_c" 1>&6
++else
++ if test -n "$AR"; then
++ ac_cv_prog_AR="$AR" # Let the user override the test.
++else
++ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
++ ac_dummy="$PATH"
++ for ac_dir in $ac_dummy; do
++ test -z "$ac_dir" && ac_dir=.
++ if test -f $ac_dir/$ac_word; then
++ ac_cv_prog_AR="${ac_tool_prefix}ar"
++ break
++ fi
++ done
++ IFS="$ac_save_ifs"
++ test -z "$ac_cv_prog_AR" && ac_cv_prog_AR="ar"
++fi
++fi
++AR="$ac_cv_prog_AR"
++if test -n "$AR"; then
++ echo "$ac_t""$AR" 1>&6
++else
++ echo "$ac_t""no" 1>&6
++fi
++
++
++
++# Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
++set dummy ${ac_tool_prefix}ranlib; ac_word=$2
++echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
++echo "configure:1278: checking for $ac_word" >&5
++if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
++ echo $ac_n "(cached) $ac_c" 1>&6
++else
++ if test -n "$RANLIB"; then
++ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
++else
++ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
++ ac_dummy="$PATH"
++ for ac_dir in $ac_dummy; do
++ test -z "$ac_dir" && ac_dir=.
++ if test -f $ac_dir/$ac_word; then
++ ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
++ break
++ fi
++ done
++ IFS="$ac_save_ifs"
++fi
++fi
++RANLIB="$ac_cv_prog_RANLIB"
++if test -n "$RANLIB"; then
++ echo "$ac_t""$RANLIB" 1>&6
++else
++ echo "$ac_t""no" 1>&6
++fi
++
++
++if test -z "$ac_cv_prog_RANLIB"; then
++if test -n "$ac_tool_prefix"; then
++ # Extract the first word of "ranlib", so it can be a program name with args.
++set dummy ranlib; ac_word=$2
++echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
++echo "configure:1310: checking for $ac_word" >&5
++if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
++ echo $ac_n "(cached) $ac_c" 1>&6
++else
++ if test -n "$RANLIB"; then
++ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
++else
++ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
++ ac_dummy="$PATH"
++ for ac_dir in $ac_dummy; do
++ test -z "$ac_dir" && ac_dir=.
++ if test -f $ac_dir/$ac_word; then
++ ac_cv_prog_RANLIB="ranlib"
++ break
++ fi
++ done
++ IFS="$ac_save_ifs"
++ test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
++fi
++fi
++RANLIB="$ac_cv_prog_RANLIB"
++if test -n "$RANLIB"; then
++ echo "$ac_t""$RANLIB" 1>&6
++else
++ echo "$ac_t""no" 1>&6
++fi
++
++else
++ RANLIB=":"
++fi
++fi
++
++
++# Find a good install program. We prefer a C program (faster),
++# so one script is as good as another. But avoid the broken or
++# incompatible versions:
++# SysV /etc/install, /usr/sbin/install
++# SunOS /usr/etc/install
++# IRIX /sbin/install
++# AIX /bin/install
++# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
++# AFS /usr/afsws/bin/install, which mishandles nonexistent args
++# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
++# ./install, which can be erroneously created by make from ./install.sh.
++echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
++echo "configure:1355: checking for a BSD compatible install" >&5
++if test -z "$INSTALL"; then
++if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
++ echo $ac_n "(cached) $ac_c" 1>&6
++else
++ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":"
++ for ac_dir in $PATH; do
++ # Account for people who put trailing slashes in PATH elements.
++ case "$ac_dir/" in
++ /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
++ *)
++ # OSF1 and SCO ODT 3.0 have their own names for install.
++ # Don't use installbsd from OSF since it installs stuff as root
++ # by default.
++ for ac_prog in ginstall scoinst install; do
++ if test -f $ac_dir/$ac_prog; then
++ if test $ac_prog = install &&
++ grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
++ # AIX install. It has an incompatible calling convention.
++ :
++ else
++ ac_cv_path_install="$ac_dir/$ac_prog -c"
++ break 2
++ fi
++ fi
++ done
++ ;;
++ esac
++ done
++ IFS="$ac_save_IFS"
++
++fi
++ if test "${ac_cv_path_install+set}" = set; then
++ INSTALL="$ac_cv_path_install"
++ else
++ # As a last resort, use the slow shell script. We don't cache a
++ # path for INSTALL within a source directory, because that will
++ # break other packages using the cache if that directory is
++ # removed, or if the path is relative.
++ INSTALL="$ac_install_sh"
++ fi
++fi
++echo "$ac_t""$INSTALL" 1>&6
++
++# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
++# It thinks the first close brace ends the variable substitution.
++test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
++
++test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
++
++test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
++
++
++echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6
++echo "configure:1409: checking whether to enable maintainer-specific portions of Makefiles" >&5
++ # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given.
++if test "${enable_maintainer_mode+set}" = set; then
++ enableval="$enable_maintainer_mode"
++ USE_MAINTAINER_MODE=$enableval
++else
++ USE_MAINTAINER_MODE=no
++fi
++
++ echo "$ac_t""$USE_MAINTAINER_MODE" 1>&6
++
++
++if test $USE_MAINTAINER_MODE = yes; then
++ MAINTAINER_MODE_TRUE=
++ MAINTAINER_MODE_FALSE='#'
++else
++ MAINTAINER_MODE_TRUE='#'
++ MAINTAINER_MODE_FALSE=
++fi
++ MAINT=$MAINTAINER_MODE_TRUE
++
++
++
++# We need AC_EXEEXT to keep automake happy in cygnus mode. However,
++# at least currently, we never actually build a program, so we never
++# need to use $(EXEEXT). Moreover, the test for EXEEXT normally
++# fails, because we are probably configuring with a cross compiler
++# which can't create executables. So we include AC_EXEEXT to keep
++# automake happy, but we don't execute it, since we don't care about
++# the result.
++if false; then
++
++
++echo $ac_n "checking for executable suffix""... $ac_c" 1>&6
++echo "configure:1443: checking for executable suffix" >&5
++if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then
++ echo $ac_n "(cached) $ac_c" 1>&6
++else
++ if test "$CYGWIN" = yes || test "$MINGW32" = yes; then
++ ac_cv_exeext=.exe
++else
++ rm -f conftest*
++ echo 'int main () { return 0; }' > conftest.$ac_ext
++ ac_cv_exeext=
++ if { (eval echo configure:1453: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
++ for file in conftest.*; do
++ case $file in
++ *.c | *.o | *.obj | *.ilk | *.pdb) ;;
++ *) ac_cv_exeext=`echo $file | sed -e s/conftest//` ;;
++ esac
++ done
++ else
++ { echo "configure: error: installation or configuration problem: compiler cannot create executables." 1>&2; exit 1; }
++ fi
++ rm -f conftest*
++ test x"${ac_cv_exeext}" = x && ac_cv_exeext=no
++fi
++fi
++
++EXEEXT=""
++test x"${ac_cv_exeext}" != xno && EXEEXT=${ac_cv_exeext}
++echo "$ac_t""${ac_cv_exeext}" 1>&6
++ac_exeext=$EXEEXT
++
++fi
++
++. ${newlib_basedir}/configure.host
++
++newlib_cflags="${newlib_cflags} -fno-builtin"
++
++NEWLIB_CFLAGS=${newlib_cflags}
++
++
++LDFLAGS=${ldflags}
++
++
++
++
++if test x${newlib_elix_level} = x0; then
++ ELIX_LEVEL_0_TRUE=
++ ELIX_LEVEL_0_FALSE='#'
++else
++ ELIX_LEVEL_0_TRUE='#'
++ ELIX_LEVEL_0_FALSE=
++fi
++
++
++if test x${newlib_elix_level} = x1; then
++ ELIX_LEVEL_1_TRUE=
++ ELIX_LEVEL_1_FALSE='#'
++else
++ ELIX_LEVEL_1_TRUE='#'
++ ELIX_LEVEL_1_FALSE=
++fi
++
++
++if test x${newlib_elix_level} = x2; then
++ ELIX_LEVEL_2_TRUE=
++ ELIX_LEVEL_2_FALSE='#'
++else
++ ELIX_LEVEL_2_TRUE='#'
++ ELIX_LEVEL_2_FALSE=
++fi
++
++
++if test x${newlib_elix_level} = x3; then
++ ELIX_LEVEL_3_TRUE=
++ ELIX_LEVEL_3_FALSE='#'
++else
++ ELIX_LEVEL_3_TRUE='#'
++ ELIX_LEVEL_3_FALSE=
++fi
++
++
++if test x${newlib_elix_level} = x4; then
++ ELIX_LEVEL_4_TRUE=
++ ELIX_LEVEL_4_FALSE='#'
++else
++ ELIX_LEVEL_4_TRUE='#'
++ ELIX_LEVEL_4_FALSE=
++fi
++
++
++
++if test x${use_libtool} = xyes; then
++ USE_LIBTOOL_TRUE=
++ USE_LIBTOOL_FALSE='#'
++else
++ USE_LIBTOOL_TRUE='#'
++ USE_LIBTOOL_FALSE=
++fi
++
++# Hard-code OBJEXT. Normally it is set by AC_OBJEXT, but we
++# use oext, which is set in configure.host based on the target platform.
++OBJEXT=${oext}
++
++
++
++
++
++
++
++
++
++
++trap '' 1 2 15
++cat > confcache <<\EOF
++# This file is a shell script that caches the results of configure
++# tests run on this system so they can be shared between configure
++# scripts and configure runs. It is not useful on other systems.
++# If it contains results you don't want to keep, you may remove or edit it.
++#
++# By default, configure uses ./config.cache as the cache file,
++# creating it if it does not exist already. You can give configure
++# the --cache-file=FILE option to use a different cache file; that is
++# what configure does when it calls configure scripts in
++# subdirectories, so they share the cache.
++# Giving --cache-file=/dev/null disables caching, for debugging configure.
++# config.status only pays attention to the cache file if you give it the
++# --recheck option to rerun configure.
++#
++EOF
++# The following way of writing the cache mishandles newlines in values,
++# but we know of no workaround that is simple, portable, and efficient.
++# So, don't put newlines in cache variables' values.
++# Ultrix sh set writes to stderr and can't be redirected directly,
++# and sets the high bit in the cache file unless we assign to the vars.
++(set) 2>&1 |
++ case `(ac_space=' '; set | grep ac_space) 2>&1` in
++ *ac_space=\ *)
++ # `set' does not quote correctly, so add quotes (double-quote substitution
++ # turns \\\\ into \\, and sed turns \\ into \).
++ sed -n \
++ -e "s/'/'\\\\''/g" \
++ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
++ ;;
++ *)
++ # `set' quotes correctly as required by POSIX, so do not add quotes.
++ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
++ ;;
++ esac >> confcache
++if cmp -s $cache_file confcache; then
++ :
++else
++ if test -w $cache_file; then
++ echo "updating cache $cache_file"
++ cat confcache > $cache_file
++ else
++ echo "not updating unwritable cache $cache_file"
++ fi
++fi
++rm -f confcache
++
++trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
++
++test "x$prefix" = xNONE && prefix=$ac_default_prefix
++# Let make expand exec_prefix.
++test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
++
++# Any assignment to VPATH causes Sun make to only execute
++# the first set of double-colon rules, so remove it if not needed.
++# If there is a colon in the path, we need to keep it.
++if test "x$srcdir" = x.; then
++ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
++fi
++
++trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
++
++# Transform confdefs.h into DEFS.
++# Protect against shell expansion while executing Makefile rules.
++# Protect against Makefile macro expansion.
++cat > conftest.defs <<\EOF
++s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g
++s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g
++s%\[%\\&%g
++s%\]%\\&%g
++s%\$%$$%g
++EOF
++DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '`
++rm -f conftest.defs
++
++
++# Without the "./", some shells look in PATH for config.status.
++: ${CONFIG_STATUS=./config.status}
++
++echo creating $CONFIG_STATUS
++rm -f $CONFIG_STATUS
++cat > $CONFIG_STATUS <<EOF
++#! /bin/sh
++# Generated automatically by configure.
++# Run this file to recreate the current configuration.
++# This directory was configured as follows,
++# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
++#
++# $0 $ac_configure_args
++#
++# Compiler output produced by configure, useful for debugging
++# configure, is in ./config.log if it exists.
++
++ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
++for ac_option
++do
++ case "\$ac_option" in
++ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
++ echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
++ exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
++ -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
++ echo "$CONFIG_STATUS generated by autoconf version 2.13"
++ exit 0 ;;
++ -help | --help | --hel | --he | --h)
++ echo "\$ac_cs_usage"; exit 0 ;;
++ *) echo "\$ac_cs_usage"; exit 1 ;;
++ esac
++done
++
++ac_given_srcdir=$srcdir
++ac_given_INSTALL="$INSTALL"
++
++trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
++EOF
++cat >> $CONFIG_STATUS <<EOF
++
++# Protect against being on the right side of a sed subst in config.status.
++sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
++ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
++$ac_vpsub
++$extrasub
++s%@SHELL@%$SHELL%g
++s%@CFLAGS@%$CFLAGS%g
++s%@CPPFLAGS@%$CPPFLAGS%g
++s%@CXXFLAGS@%$CXXFLAGS%g
++s%@FFLAGS@%$FFLAGS%g
++s%@DEFS@%$DEFS%g
++s%@LDFLAGS@%$LDFLAGS%g
++s%@LIBS@%$LIBS%g
++s%@exec_prefix@%$exec_prefix%g
++s%@prefix@%$prefix%g
++s%@program_transform_name@%$program_transform_name%g
++s%@bindir@%$bindir%g
++s%@sbindir@%$sbindir%g
++s%@libexecdir@%$libexecdir%g
++s%@datadir@%$datadir%g
++s%@sysconfdir@%$sysconfdir%g
++s%@sharedstatedir@%$sharedstatedir%g
++s%@localstatedir@%$localstatedir%g
++s%@libdir@%$libdir%g
++s%@includedir@%$includedir%g
++s%@oldincludedir@%$oldincludedir%g
++s%@infodir@%$infodir%g
++s%@mandir@%$mandir%g
++s%@newlib_basedir@%$newlib_basedir%g
++s%@host@%$host%g
++s%@host_alias@%$host_alias%g
++s%@host_cpu@%$host_cpu%g
++s%@host_vendor@%$host_vendor%g
++s%@host_os@%$host_os%g
++s%@target@%$target%g
++s%@target_alias@%$target_alias%g
++s%@target_cpu@%$target_cpu%g
++s%@target_vendor@%$target_vendor%g
++s%@target_os@%$target_os%g
++s%@build@%$build%g
++s%@build_alias@%$build_alias%g
++s%@build_cpu@%$build_cpu%g
++s%@build_vendor@%$build_vendor%g
++s%@build_os@%$build_os%g
++s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
++s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g
++s%@INSTALL_DATA@%$INSTALL_DATA%g
++s%@PACKAGE@%$PACKAGE%g
++s%@VERSION@%$VERSION%g
++s%@ACLOCAL@%$ACLOCAL%g
++s%@AUTOCONF@%$AUTOCONF%g
++s%@AUTOMAKE@%$AUTOMAKE%g
++s%@AUTOHEADER@%$AUTOHEADER%g
++s%@MAKEINFO@%$MAKEINFO%g
++s%@SET_MAKE@%$SET_MAKE%g
++s%@CC@%$CC%g
++s%@AS@%$AS%g
++s%@AR@%$AR%g
++s%@RANLIB@%$RANLIB%g
++s%@MAINTAINER_MODE_TRUE@%$MAINTAINER_MODE_TRUE%g
++s%@MAINTAINER_MODE_FALSE@%$MAINTAINER_MODE_FALSE%g
++s%@MAINT@%$MAINT%g
++s%@EXEEXT@%$EXEEXT%g
++s%@NEWLIB_CFLAGS@%$NEWLIB_CFLAGS%g
++s%@ELIX_LEVEL_0_TRUE@%$ELIX_LEVEL_0_TRUE%g
++s%@ELIX_LEVEL_0_FALSE@%$ELIX_LEVEL_0_FALSE%g
++s%@ELIX_LEVEL_1_TRUE@%$ELIX_LEVEL_1_TRUE%g
++s%@ELIX_LEVEL_1_FALSE@%$ELIX_LEVEL_1_FALSE%g
++s%@ELIX_LEVEL_2_TRUE@%$ELIX_LEVEL_2_TRUE%g
++s%@ELIX_LEVEL_2_FALSE@%$ELIX_LEVEL_2_FALSE%g
++s%@ELIX_LEVEL_3_TRUE@%$ELIX_LEVEL_3_TRUE%g
++s%@ELIX_LEVEL_3_FALSE@%$ELIX_LEVEL_3_FALSE%g
++s%@ELIX_LEVEL_4_TRUE@%$ELIX_LEVEL_4_TRUE%g
++s%@ELIX_LEVEL_4_FALSE@%$ELIX_LEVEL_4_FALSE%g
++s%@USE_LIBTOOL_TRUE@%$USE_LIBTOOL_TRUE%g
++s%@USE_LIBTOOL_FALSE@%$USE_LIBTOOL_FALSE%g
++s%@OBJEXT@%$OBJEXT%g
++s%@oext@%$oext%g
++s%@aext@%$aext%g
++s%@libm_machine_dir@%$libm_machine_dir%g
++s%@machine_dir@%$machine_dir%g
++s%@sys_dir@%$sys_dir%g
++
++CEOF
++EOF
++
++cat >> $CONFIG_STATUS <<\EOF
++
++# Split the substitutions into bite-sized pieces for seds with
++# small command number limits, like on Digital OSF/1 and HP-UX.
++ac_max_sed_cmds=60 # Maximum number of lines to put in a sed script.
++ac_file=1 # Number of current file.
++ac_beg=1 # First line for current file.
++ac_end=$ac_max_sed_cmds # Line after last line for current file.
++ac_more_lines=:
++ac_sed_cmds=""
++while $ac_more_lines; do
++ if test $ac_beg -gt 1; then
++ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
++ else
++ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
++ fi
++ if test ! -s conftest.s$ac_file; then
++ ac_more_lines=false
++ rm -f conftest.s$ac_file
++ else
++ if test -z "$ac_sed_cmds"; then
++ ac_sed_cmds="sed -f conftest.s$ac_file"
++ else
++ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
++ fi
++ ac_file=`expr $ac_file + 1`
++ ac_beg=$ac_end
++ ac_end=`expr $ac_end + $ac_max_sed_cmds`
++ fi
++done
++if test -z "$ac_sed_cmds"; then
++ ac_sed_cmds=cat
++fi
++EOF
++
++cat >> $CONFIG_STATUS <<EOF
++
++CONFIG_FILES=\${CONFIG_FILES-"Makefile"}
++EOF
++cat >> $CONFIG_STATUS <<\EOF
++for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
++ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
++ case "$ac_file" in
++ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
++ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
++ *) ac_file_in="${ac_file}.in" ;;
++ esac
++
++ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
++
++ # Remove last slash and all that follows it. Not all systems have dirname.
++ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
++ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
++ # The file is in a subdirectory.
++ test ! -d "$ac_dir" && mkdir "$ac_dir"
++ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
++ # A "../" for each directory in $ac_dir_suffix.
++ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
++ else
++ ac_dir_suffix= ac_dots=
++ fi
++
++ case "$ac_given_srcdir" in
++ .) srcdir=.
++ if test -z "$ac_dots"; then top_srcdir=.
++ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
++ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
++ *) # Relative path.
++ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
++ top_srcdir="$ac_dots$ac_given_srcdir" ;;
++ esac
++
++ case "$ac_given_INSTALL" in
++ [/$]*) INSTALL="$ac_given_INSTALL" ;;
++ *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
++ esac
++
++ echo creating "$ac_file"
++ rm -f "$ac_file"
++ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
++ case "$ac_file" in
++ *Makefile*) ac_comsub="1i\\
++# $configure_input" ;;
++ *) ac_comsub= ;;
++ esac
++
++ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
++ sed -e "$ac_comsub
++s%@configure_input@%$configure_input%g
++s%@srcdir@%$srcdir%g
++s%@top_srcdir@%$top_srcdir%g
++s%@INSTALL@%$INSTALL%g
++" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
++fi; done
++rm -f conftest.s*
++
++EOF
++cat >> $CONFIG_STATUS <<EOF
++
++EOF
++cat >> $CONFIG_STATUS <<\EOF
++
++exit 0
++EOF
++chmod +x $CONFIG_STATUS
++rm -fr confdefs* $ac_clean_files
++test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
++
+diff -urN ../newlib-1.11.0.orig/newlib/libc/sys/mipsunknown/configure.in ./newlib/libc/sys/mipsunknown/configure.in
+--- ../newlib-1.11.0.orig/newlib/libc/sys/mipsunknown/configure.in Wed Dec 31 19:00:00 1969
++++ ./newlib/libc/sys/mipsunknown/configure.in Mon Nov 24 20:33:46 2003
+@@ -0,0 +1,12 @@
++dnl This is the newlib/libc/sys/mipsunknown configure.in file.
++dnl Process this file with autoconf to produce a configure script.
++
++AC_PREREQ(2.5)
++AC_INIT(syscalls.c)
++
++dnl Can't be done in NEWLIB_CONFIGURE because that confuses automake.
++AC_CONFIG_AUX_DIR(../../../..)
++
++NEWLIB_CONFIGURE(../../..)
++
++AC_OUTPUT(Makefile)
+diff -urN ../newlib-1.11.0.orig/newlib/libc/sys/mipsunknown/crt0.c ./newlib/libc/sys/mipsunknown/crt0.c
+--- ../newlib-1.11.0.orig/newlib/libc/sys/mipsunknown/crt0.c Wed Dec 31 19:00:00 1969
++++ ./newlib/libc/sys/mipsunknown/crt0.c Mon Nov 24 21:03:56 2003
+@@ -0,0 +1,7 @@
++/* This is just here to make the build proccess happy. The real crt0.c is included in the
++ mips2java dist and will replace this after mips2java is installed */
++
++extern void puts(const char *s);
++void _start() {
++ puts("Your build is broken... you shouldn't be using the crt0.c in newlib");
++}
+diff -urN ../newlib-1.11.0.orig/newlib/libc/sys/mipsunknown/sys/dirent.h ./newlib/libc/sys/mipsunknown/sys/dirent.h
+--- ../newlib-1.11.0.orig/newlib/libc/sys/mipsunknown/sys/dirent.h Wed Dec 31 19:00:00 1969
++++ ./newlib/libc/sys/mipsunknown/sys/dirent.h Mon Nov 24 22:46:36 2003
+@@ -0,0 +1,24 @@
++#ifndef _SYS_DIRENT_H
++#define _SYS_DIRENT_H
++
++#include <sys/types.h>
++
++struct dirent {
++ long d_ino;
++ char d_name[1024];
++};
++
++typedef struct {
++ int dd_fd;
++ int dd_pos;
++ struct dirent ent;
++} DIR;
++
++# define __dirfd(dp) ((dp)->dd_fd)
++
++DIR *opendir (const char *);
++struct dirent *readdir (DIR *);
++void rewinddir (DIR *);
++int closedir (DIR *);
++
++#endif
+diff -urN ../newlib-1.11.0.orig/newlib/libc/sys/mipsunknown/sys/utime.h ./newlib/libc/sys/mipsunknown/sys/utime.h
+--- ../newlib-1.11.0.orig/newlib/libc/sys/mipsunknown/sys/utime.h Wed Dec 31 19:00:00 1969
++++ ./newlib/libc/sys/mipsunknown/sys/utime.h Tue Nov 25 09:45:17 2003
+@@ -0,0 +1,20 @@
++#ifndef _SYS_UTIME_H
++#define _SYS_UTIME_H
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++struct utimbuf
++{
++ time_t actime;
++ time_t modtime;
++};
++
++extern int utime(const char *file, const struct utimbuf *buf);
++
++#ifdef __cplusplus
++};
++#endif
++
++#endif /* _SYS_UTIME_H */
+diff -urN ../newlib-1.11.0.orig/newlib/libc/sys/mipsunknown/syscalls.c ./newlib/libc/sys/mipsunknown/syscalls.c
+--- ../newlib-1.11.0.orig/newlib/libc/sys/mipsunknown/syscalls.c Wed Dec 31 19:00:00 1969
++++ ./newlib/libc/sys/mipsunknown/syscalls.c Tue Nov 25 09:33:57 2003
+@@ -0,0 +1,49 @@
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <utime.h>
++#include <errno.h>
++#undef errno
++
++/* These are just connectors for the reent versions */
++
++extern int _mkdir_r(struct _reent *ptr, const char *path, mode_t mode);
++int mkdir(const char *path, mode_t mode) { return _mkdir_r(_REENT, path, mode); }
++
++extern int _utime_r(struct _reent *ptr, const char *file, struct utimbuf *buf);
++int utime(const char *file, const struct utimbuf *buf) { return _utime_r(_REENT,file,buf); }
++
++extern int _lstat_r(struct _reent *ptr, const char *path, struct stat *sb);
++int lstat(const char *path, struct stat *sb) { return _lstat_r(_REENT,path,sb); }
++
++extern int _chdir_r(struct _reent *ptr, const char *path);
++int chdir(const char *path) { return _chdir_r(_REENT,path); }
++
++extern int _pipe_r(struct _reent *ptr, int *filedes);
++int pipe(int *filedes) { return _pipe_r(_REENT,filedes); }
++
++extern int _dup2_r(struct _reent *ptr, int oldd, int newd);
++int dup2(int oldd,int newd) { return _dup2_r(_REENT,oldd,newd); }
++
++extern int _waitpid_r(struct _reent *ptr, pid_t pid, int *status, int opts);
++int waitpid(pid_t pid, int *status, int opts) { return _waitpid_r(_REENT,pid,status,opts); }
++
++extern char* _getcwd_r(struct _reent *ptr, char *buf, size_t size);
++char* getcwd(char *buf, size_t size) { return _getcwd_r(_REENT,buf,size); }
++
++extern int _symlink_r(struct _reent *ptr, const char *name1, const char *name2);
++int symlink(const char *name1, const char *name2) { return _symlink_r(_REENT,name1,name2); }
++
++extern int _readlink_r(struct _reent *ptr, const char *path, const char *buf, int bufsize);
++int readlink(const char *path, const char *buf, int bufsize) { return _readlink_r(_REENT,path,buf,bufsize); }
++
++extern int _chown_r(struct _reent *ptr, const char *path, uid_t uid, gid_t gid);
++int chown(const char *path, uid_t uid, gid_t gid) { return _chown_r(_REENT,path,uid,gid); }
++
++extern int _fchown_r(struct _reent *ptr, int fd, uid_t uid, gid_t gid);
++int fchown(int fd, uid_t uid, gid_t gid) { return _fchown_r(_REENT,fd,uid,gid); }
++
++extern int _chmod_r(struct _reent *ptr, const char *path, mode_t mode);
++int chmod(const char *path, mode_t mode) { return _chmod_r(_REENT,path,mode); }
++
++extern int _fchmod_r(struct _reent *ptr, int fd, mode_t mode);
++int fchmod(int fd, mode_t mode) { return _fchmod_r(_REENT,fd,mode); }
--- /dev/null
+===================================================================
+RCS file: /cvs/src/src/newlib/libc/time/tzset_r.c,v
+retrieving revision 1.2
+retrieving revision 1.3
+diff -u -r1.2 -r1.3
+--- newlib/libc/time/tzset_r.c 2002/08/26 18:56:09 1.2
++++ snewlib/libc/time/tzset_r.c 2003/06/03 18:42:09 1.3
+@@ -28,7 +28,8 @@
+ struct _reent *reent_ptr)
+ {
+ char *tzenv;
+- int hh, mm, ss, sign, m, w, d, n;
++ unsigned short hh, mm, ss, m, w, d;
++ int sign, n;
+ int i, ch;
+
+ if ((tzenv = _getenv_r (reent_ptr, "TZ")) == NULL)
--- /dev/null
+JAVAC = javac
+sources = $(shell find src -name '*.java')
+classes = $(sources:src/%.java=build/%.class)
+dats = org/ibex/net/ssl/rootcerts.dat
+
+jar_sources = \
+ $(shell find src/org/ibex/crypto -name '*.java') \
+ src/org/ibex/net/SSL.java \
+ src/org/ibex/net/ssl/RootCerts.java
+jar_classes = $(jar_sources:src/%.java=build/%.class)
+jar = BriSSL.jar
+
+all: $(classes) $(dats:%=build/%)
+
+$(classes): $(sources)
+ @mkdir -p build
+ $(JAVAC) -d build $(sources)
+
+build/%.dat: src/%.dat
+ @mkdir -p `dirname $@`
+ cp $^ $@
+
+$(jar): $(classes)
+ cd build && jar cf ../$@ $(jar_classes:build/%.class=%*.class)
+
+test: all
+ java -cp build org.ibex.net.ssl.Test www.paypal.com 443
+
+clean:
+ rm -rf build/*
+
+# This stuff is only for Brian to use
+# We should probably verify this file somehow
+tmp/.havecacertrs:
+ @mkdir -p tmp
+ wget -O - http://ftp.debian.org/debian/pool/main/c/ca-certificates/ca-certificates_20020323.tar.gz | gzip -dc | tar -C tmp -xf-
+ cd tmp/ca-certificates/mozilla && \
+ make all \
+ for f in *.pem; do \
+ openssl x509 -in "$$f" -out "$$f.der" -outform der; \
+ done
+ touch $@
+
+update-rootcerts: tmp/.havecacerts src/org/ibex/net/ssl/GenCompactCAList.java
+ java -cp build org.ibex.net.ssl.GenCompactCAList binary tmp/ca-certificates/mozilla/*.der > src/org/ibex/net/ssl/rootcerts.dat
+ java -cp build org.ibex.net.ssl.GenCompactCAList class tmp/ca-certificates/mozilla/*.der > src/org/ibex/net/ssl/RootCerts.java
+
+sizecheck:
+ @for c in $(jar_classes); do \
+ for f in `echo $$c|sed 's,\.class$$,,;'`*.class; do gzip -c $$f; done | wc -c | tr -d '\n'; \
+ echo -e "\t`echo $$c | sed 's,build/org/ibex,,;s,\.class$$,,;s,/,.,g;'`"; \
+ done | sort -rn | awk '{ sum += $$1; print } END { print sum,"Total"; }'
--- /dev/null
+src/com/brian_web/*
+-------------------
+src/com/brian_web/net/SSL.java is Copyright 2004 Brian Alliet and
+Copyright 2003 Adam Megacz. It is released under the GNU Lesser
+General Public License with the exception of the portion of clause 6a
+after the semicolon (aka the "obnoxious relink clause")
+
+src/com/brian_web/{x509,der} are Copyright 2004 Brian Alliet and
+Copyright 2000 The Legion Of The Bouncy Castle
+(http://www.bouncycastle.org) and is released under the Bouncy
+Castle License below.
+
+The rest of src/com/brian_web is Copyright 2004 Brian Alliet
+are released under the GNU Lesser General Public License (below).
+
+src/org/bouncycastle/*
+----------------------
+src/org/bouncycastle is Copyright 2000 The Legion Of The Bouncy Castle
+(http://www.bouncycastle.org) and is released under the following license:
+
+-- Bouncy Castle License --
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to
+deal in the Software without restriction, including without limitation the
+rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN THE SOFTWARE.
+-- End --
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+\f
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+\f
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+\f
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+\f
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+\f
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+\f
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+\f
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+\f
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+\f
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
+
+
--- /dev/null
+package org.ibex.crypto;
+
+public class Base36 {
+ public static String encode(long l) {
+ StringBuffer ret = new StringBuffer();
+ while (l > 0) {
+ if ((l % 36) < 10) ret.append((char)(((int)'0') + (int)(l % 36)));
+ else ret.append((char)(((int)'A') + (int)((l % 36) - 10)));
+ l /= 36;
+ }
+ return ret.toString();
+ }
+}
--- /dev/null
+package org.ibex.crypto;
+
+public class Base64
+{
+ private static final byte[] encodingTable =
+ {
+ (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G',
+ (byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L', (byte)'M', (byte)'N',
+ (byte)'O', (byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U',
+ (byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z',
+ (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g',
+ (byte)'h', (byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n',
+ (byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t', (byte)'u',
+ (byte)'v',
+ (byte)'w', (byte)'x', (byte)'y', (byte)'z',
+ (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6',
+ (byte)'7', (byte)'8', (byte)'9',
+ (byte)'+', (byte)'/'
+ };
+
+ /**
+ * encode the input data producong a base 64 encoded byte array.
+ *
+ * @return a byte array containing the base 64 encoded data.
+ */
+ public static byte[] encode(
+ byte[] data)
+ {
+ byte[] bytes;
+
+ int modulus = data.length % 3;
+ if (modulus == 0)
+ {
+ bytes = new byte[4 * data.length / 3];
+ }
+ else
+ {
+ bytes = new byte[4 * ((data.length / 3) + 1)];
+ }
+
+ int dataLength = (data.length - modulus);
+ int a1, a2, a3;
+ for (int i = 0, j = 0; i < dataLength; i += 3, j += 4)
+ {
+ a1 = data[i] & 0xff;
+ a2 = data[i + 1] & 0xff;
+ a3 = data[i + 2] & 0xff;
+
+ bytes[j] = encodingTable[(a1 >>> 2) & 0x3f];
+ bytes[j + 1] = encodingTable[((a1 << 4) | (a2 >>> 4)) & 0x3f];
+ bytes[j + 2] = encodingTable[((a2 << 2) | (a3 >>> 6)) & 0x3f];
+ bytes[j + 3] = encodingTable[a3 & 0x3f];
+ }
+
+ /*
+ * process the tail end.
+ */
+ int b1, b2, b3;
+ int d1, d2;
+
+ switch (modulus)
+ {
+ case 0: /* nothing left to do */
+ break;
+ case 1:
+ d1 = data[data.length - 1] & 0xff;
+ b1 = (d1 >>> 2) & 0x3f;
+ b2 = (d1 << 4) & 0x3f;
+
+ bytes[bytes.length - 4] = encodingTable[b1];
+ bytes[bytes.length - 3] = encodingTable[b2];
+ bytes[bytes.length - 2] = (byte)'=';
+ bytes[bytes.length - 1] = (byte)'=';
+ break;
+ case 2:
+ d1 = data[data.length - 2] & 0xff;
+ d2 = data[data.length - 1] & 0xff;
+
+ b1 = (d1 >>> 2) & 0x3f;
+ b2 = ((d1 << 4) | (d2 >>> 4)) & 0x3f;
+ b3 = (d2 << 2) & 0x3f;
+
+ bytes[bytes.length - 4] = encodingTable[b1];
+ bytes[bytes.length - 3] = encodingTable[b2];
+ bytes[bytes.length - 2] = encodingTable[b3];
+ bytes[bytes.length - 1] = (byte)'=';
+ break;
+ }
+
+ return bytes;
+ }
+
+ /*
+ * set up the decoding table.
+ */
+ private static final byte[] decodingTable;
+
+ static
+ {
+ decodingTable = new byte[128];
+
+ for (int i = 'A'; i <= 'Z'; i++)
+ {
+ decodingTable[i] = (byte)(i - 'A');
+ }
+
+ for (int i = 'a'; i <= 'z'; i++)
+ {
+ decodingTable[i] = (byte)(i - 'a' + 26);
+ }
+
+ for (int i = '0'; i <= '9'; i++)
+ {
+ decodingTable[i] = (byte)(i - '0' + 52);
+ }
+
+ decodingTable['+'] = 62;
+ decodingTable['/'] = 63;
+ }
+
+ /**
+ * decode the base 64 encoded input data.
+ *
+ * @return a byte array representing the decoded data.
+ */
+ public static byte[] decode(
+ byte[] data)
+ {
+ byte[] bytes;
+ byte b1, b2, b3, b4;
+
+ if (data[data.length - 2] == '=')
+ {
+ bytes = new byte[(((data.length / 4) - 1) * 3) + 1];
+ }
+ else if (data[data.length - 1] == '=')
+ {
+ bytes = new byte[(((data.length / 4) - 1) * 3) + 2];
+ }
+ else
+ {
+ bytes = new byte[((data.length / 4) * 3)];
+ }
+
+ for (int i = 0, j = 0; i < data.length - 4; i += 4, j += 3)
+ {
+ b1 = decodingTable[data[i]];
+ b2 = decodingTable[data[i + 1]];
+ b3 = decodingTable[data[i + 2]];
+ b4 = decodingTable[data[i + 3]];
+
+ bytes[j] = (byte)((b1 << 2) | (b2 >> 4));
+ bytes[j + 1] = (byte)((b2 << 4) | (b3 >> 2));
+ bytes[j + 2] = (byte)((b3 << 6) | b4);
+ }
+
+ if (data[data.length - 2] == '=')
+ {
+ b1 = decodingTable[data[data.length - 4]];
+ b2 = decodingTable[data[data.length - 3]];
+
+ bytes[bytes.length - 1] = (byte)((b1 << 2) | (b2 >> 4));
+ }
+ else if (data[data.length - 1] == '=')
+ {
+ b1 = decodingTable[data[data.length - 4]];
+ b2 = decodingTable[data[data.length - 3]];
+ b3 = decodingTable[data[data.length - 2]];
+
+ bytes[bytes.length - 2] = (byte)((b1 << 2) | (b2 >> 4));
+ bytes[bytes.length - 1] = (byte)((b2 << 4) | (b3 >> 2));
+ }
+ else
+ {
+ b1 = decodingTable[data[data.length - 4]];
+ b2 = decodingTable[data[data.length - 3]];
+ b3 = decodingTable[data[data.length - 2]];
+ b4 = decodingTable[data[data.length - 1]];
+
+ bytes[bytes.length - 3] = (byte)((b1 << 2) | (b2 >> 4));
+ bytes[bytes.length - 2] = (byte)((b2 << 4) | (b3 >> 2));
+ bytes[bytes.length - 1] = (byte)((b3 << 6) | b4);
+ }
+
+ return bytes;
+ }
+
+ /**
+ * decode the base 64 encoded String data.
+ *
+ * @return a byte array representing the decoded data.
+ */
+ public static byte[] decode(
+ String data)
+ {
+ byte[] bytes;
+ byte b1, b2, b3, b4;
+
+ if (data.charAt(data.length() - 2) == '=')
+ {
+ bytes = new byte[(((data.length() / 4) - 1) * 3) + 1];
+ }
+ else if (data.charAt(data.length() - 1) == '=')
+ {
+ bytes = new byte[(((data.length() / 4) - 1) * 3) + 2];
+ }
+ else
+ {
+ bytes = new byte[((data.length() / 4) * 3)];
+ }
+
+ for (int i = 0, j = 0; i < data.length() - 4; i += 4, j += 3)
+ {
+ b1 = decodingTable[data.charAt(i)];
+ b2 = decodingTable[data.charAt(i + 1)];
+ b3 = decodingTable[data.charAt(i + 2)];
+ b4 = decodingTable[data.charAt(i + 3)];
+
+ bytes[j] = (byte)((b1 << 2) | (b2 >> 4));
+ bytes[j + 1] = (byte)((b2 << 4) | (b3 >> 2));
+ bytes[j + 2] = (byte)((b3 << 6) | b4);
+ }
+
+ if (data.charAt(data.length() - 2) == '=')
+ {
+ b1 = decodingTable[data.charAt(data.length() - 4)];
+ b2 = decodingTable[data.charAt(data.length() - 3)];
+
+ bytes[bytes.length - 1] = (byte)((b1 << 2) | (b2 >> 4));
+ }
+ else if (data.charAt(data.length() - 1) == '=')
+ {
+ b1 = decodingTable[data.charAt(data.length() - 4)];
+ b2 = decodingTable[data.charAt(data.length() - 3)];
+ b3 = decodingTable[data.charAt(data.length() - 2)];
+
+ bytes[bytes.length - 2] = (byte)((b1 << 2) | (b2 >> 4));
+ bytes[bytes.length - 1] = (byte)((b2 << 4) | (b3 >> 2));
+ }
+ else
+ {
+ b1 = decodingTable[data.charAt(data.length() - 4)];
+ b2 = decodingTable[data.charAt(data.length() - 3)];
+ b3 = decodingTable[data.charAt(data.length() - 2)];
+ b4 = decodingTable[data.charAt(data.length() - 1)];
+
+ bytes[bytes.length - 3] = (byte)((b1 << 2) | (b2 >> 4));
+ bytes[bytes.length - 2] = (byte)((b2 << 4) | (b3 >> 2));
+ bytes[bytes.length - 1] = (byte)((b3 << 6) | b4);
+ }
+
+ return bytes;
+ }
+}
--- /dev/null
+/*
+ * org.ibex.der.* - By Brian Alliet
+ * Copyright (C) 2004 Brian Alliet
+ *
+ * Based on Bouncy Castle by The Legion Of The Bouncy Castle
+ * Copyright (c) 2000 The Legion Of The Bouncy Castle
+ * (http://www.bouncycastle.org)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDER.S BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+package org.ibex.crypto;
+import java.io.IOException;
+import java.io.*;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+import java.math.BigInteger;
+
+public class DER {
+ public static class Null {
+ final static Null instance = new Null();
+ private Null() { /* noop */ }
+ public boolean equals(Object o) { return o == this; }
+ }
+
+ public static class TaggedObject {
+ public final Object object;
+ public final int tag;
+ public TaggedObject(int tag, Object object) { this.tag = tag; this.object = object; }
+ }
+
+ public static class UnknownObject {
+ public final byte[] data;
+ public final int tag;
+ public UnknownObject(int tag,byte[] data) { this.tag = tag; this.data = data; }
+ }
+
+ public static class BitString {
+ public final int paddingBits;
+ public final byte[] data;
+
+ public BitString(int paddingBits, byte[] data) {
+ this.paddingBits = paddingBits;
+ this.data = data;
+ }
+ }
+
+ public static class Exception extends java.io.IOException {
+ public Exception(String s) { super(s); }
+ }
+
+ public static class InputStream extends FilterInputStream {
+ private static final int MAX_OBJECT_SIZE = 4*1024*1024;
+
+ private int limit;
+ public int bytesLeft() { return limit < 0 ? Integer.MAX_VALUE : limit-pos; }
+ private int pos;
+ public int getPos() { return pos; }
+
+ // hack around gcj bug
+ public static DER.InputStream New(java.io.InputStream is) { return new DER.InputStream(is); }
+ public InputStream(java.io.InputStream is) { this(is,-1); }
+ public InputStream(java.io.InputStream is, int limit) {
+ super(is);
+ this.limit = limit;
+ }
+
+ public int read() throws IOException {
+ if(limit >= 0 && pos >= limit) return -1;
+ int n = super.read();
+ if(n != -1) {
+ pos++;
+ }
+ return n;
+ }
+
+ public int read(byte[] buf, int start, int len) throws IOException {
+ if(limit >= 0) {
+ if(pos >= limit) return -1;
+ len = Math.min(len,limit-pos);
+ }
+ int n = super.read(buf,start,len);
+ if(n != -1) {
+ pos += n;
+ }
+ return n;
+ }
+
+ protected void readFully(byte[] buf) throws IOException {
+ int pos = 0;
+ int left = buf.length;
+ while(left > 0) {
+ int n = read(buf,pos,left);
+ if(n == -1) throw new EOFException();
+ pos += n;
+ left -=n;
+ }
+ }
+
+ protected int readByte() throws IOException {
+ int n = read();
+ if(n == -1) throw new EOFException();
+ return n;
+ }
+
+ // From bouncycastle
+ private int readLength() throws IOException {
+ int length = read();
+ if (length < 0) throw new IOException("EOF found when length expected");
+ if (length == 0x80) return -1; // indefinite-length encoding
+ if (length > 127) {
+ int size = length & 0x7f;
+ length = 0;
+ for (int i = 0; i < size; i++) {
+ int next = read();
+ if (next < 0) throw new IOException("EOF found reading length");
+ length = (length << 8) + next;
+ }
+ }
+ return length;
+ }
+
+ public InputStream getSequenceStream() throws IOException {
+ int tag = readByte();
+ int length = readLength();
+ if(length < 0) throw new Exception("Indefinite length objects not supported");
+ if(tag != (CONSTRUCTED|0x10)) throw new Exception("Constructed Sequence expected");
+ return new InputStream(this,length);
+ }
+
+ private static final int CONSTRUCTED = 0x20;
+ public Object readObject() throws IOException {
+ int tag = readByte();
+ int length = readLength();
+ if(length < 0) throw new Exception("Indefinite length objects not supported");
+ if(length > MAX_OBJECT_SIZE) throw new Exception("Object too large");
+
+ switch(tag) {
+ case 0x01: return buildBoolean(length); // Boolean
+ case 0x02: return buildInteger(length); // Integer
+ case 0x03: return buildBitString(length); // Bit String
+ case 0x04: return buildOctetString(length); // Octet String
+ case 0x05: return Null.instance; // NULL
+ case 0x06: return buildObjectIdentifier(length); // Object Identifier
+
+ case 0x13: // PrintableString
+ // It is incorrect to treat this as an IA5String but the T.61 standard is way too old and backwards
+ // to be worth supporting
+ case 0x14: // T.61 String
+ case 0x16: // IA5String
+ return buildIA5String(length);
+ case 0x17: return buildTime(length,false);// UTC Time
+ case 0x18: return buildTime(length,true); // Generalizd Time
+
+ case CONSTRUCTED | 0x10: // Constructed Sequence
+ case CONSTRUCTED | 0x11: // Constructed Set
+ {
+ return buildSequence(length);
+ }
+ default: {
+ if((tag & 0x80) != 0) {
+ if ((tag & 0x1f) == 0x1f) throw new Exception("Unsupported high tag ecountered");
+ // tagged object - bottom 5 bits are tag
+ if(length == 0)
+ return new TaggedObject(tag&0x1,((tag & CONSTRUCTED) == 0) ? (Object)Null.instance : (Object)new Vector());
+ if((tag & CONSTRUCTED) == 0)
+ return new TaggedObject(tag&0x1f,buildOctetString(length));
+
+ InputStream dis = new InputStream(this,length);
+ Object o = dis.readObject();
+ if(dis.bytesLeft() == 0) return new TaggedObject(tag&0x1f,o);
+ Vector v = new Vector();
+ v.add(o);
+ return buildSequence(dis,v);
+ } else {
+ return new UnknownObject(tag,readBytes(length));
+ }
+ }
+ }
+ }
+
+ protected Vector buildSequence(int length) throws IOException { return buildSequence(new InputStream(this,length),new Vector()); }
+ protected Vector buildSequence(InputStream dis,Vector v) throws IOException {
+ try {
+ for(;;) v.add(dis.readObject());
+ } catch(EOFException e) {
+ return v;
+ }
+ }
+
+ protected byte[] readBytes(int length) throws IOException {
+ byte[] buf = new byte[length];
+ readFully(buf);
+ return buf;
+ }
+
+ protected BigInteger buildInteger(int length) throws IOException { return new BigInteger(readBytes(length)); }
+
+ // From bouncycastle
+ protected String buildObjectIdentifier(int length) throws IOException {
+ byte[] bytes = readBytes(length);
+ StringBuffer objId = new StringBuffer();
+ int value = 0;
+ boolean first = true;
+
+ for (int i = 0; i != bytes.length; i++)
+ {
+ int b = bytes[i] & 0xff;
+
+ value = value * 128 + (b & 0x7f);
+ if ((b & 0x80) == 0) // end of number reached
+ {
+ if (first)
+ {
+ switch (value / 40)
+ {
+ case 0:
+ objId.append('0');
+ break;
+ case 1:
+ objId.append('1');
+ value -= 40;
+ break;
+ default:
+ objId.append('2');
+ value -= 80;
+ }
+ first = false;
+ }
+
+ objId.append('.');
+ objId.append(Integer.toString(value));
+ value = 0;
+ }
+ }
+ return objId.toString();
+ }
+
+ protected String buildIA5String(int length) throws IOException {
+ byte[] buf = readBytes(length);
+ char[] buf2 = new char[buf.length];
+ for(int i=0;i<buf.length;i++) buf2[i] = (char)(buf[i]&0xff);
+ return new String(buf2);
+ }
+
+ private static final SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMddHHmmssz");
+ protected Date buildTime(int length, boolean generalized) throws IOException {
+ String s = buildIA5String(length);
+ if(!generalized && s.length() > 0) {
+ if(s.charAt(0) < '5') s = "20" + s;
+ else s = "19" + s;
+ }
+ switch(s.length()) {
+ case 13: s = s.substring(0,12) + "00GMT+00:00"; break; // YYYYMMDDhhmmZ
+ case 15: s = s.substring(0,14) + "GMT+00:00"; break; // YYYYMMDDhhmmssZ
+ case 17: s = s.substring(0,12) + "00GMT" + s.substring(12,15) + ":" + s.substring(15,17); break; // YYYYMMDDhhmm+hh'mm'
+ case 19: s = s.substring(0,14) + "GMT" + s.substring(14, 17) + ":" + s.substring(17, 19); // YYYYMMDDhhmmss+hh'mm'
+ default: throw new Exception("Unknown time format " + s);
+ }
+ try {
+ return dateF.parse(s);
+ } catch(ParseException e) {
+ throw new Exception("Coudln't parse time: " + e.getMessage());
+ }
+ }
+
+ protected BitString buildBitString(int length) throws IOException {
+ if(length < 1) throw new Exception("bit string too short");
+ int padding = read();
+ if(padding == -1) throw new IOException("unexpected eof");
+ return new BitString(padding,readBytes(length-1));
+ }
+
+ protected byte[] buildOctetString(int length) throws IOException { return readBytes(length); }
+
+ protected Boolean buildBoolean(int length) throws IOException {
+ byte[] bytes = readBytes(length);
+ return bytes[0] != 0 ? Boolean.TRUE : Boolean.FALSE;
+ }
+
+ /*
+ public static void main(String[] args) throws Exception {
+ InputStream is = new InputStream(new FileInputStream(args[0]));
+ try {
+ for(;;) dump(is.readObject(),"");
+ } catch(EOFException e) {
+ System.err.println("EOF");
+ }
+ }
+ public static void dump(Object o, String indent) {
+ if(o instanceof Vector) {
+ Vector v = (Vector) o;
+ System.out.println(indent + "Sequence/Set");
+ for(int i=0;i<v.size();i++) {
+ dump(v.elementAt(i),indent + i + ": ");
+ }
+ } else if(o instanceof TaggedObject){
+ dump(((TaggedObject)o).object,indent + "Tagged object: ");
+ } else if(o instanceof byte[]) {
+ System.err.println(indent + "<Byte Array>");
+ } else {
+ System.err.println(indent + o.toString());
+ }
+ }*/
+ }
+}
--- /dev/null
+/* Copyright (c) 2000 The Legion Of The Bouncy Castle
+ * (http://www.bouncycastle.org)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDER.S BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+package org.ibex.crypto;
+
+/**
+ * base implementation of MD4 family style digest as outlined in
+ * "Handbook of Applied Cryptography", pages 344 - 347.
+ */
+public abstract class Digest {
+ private byte[] xBuf;
+ private int xBufOff;
+ private long byteCount;
+
+ protected Digest() { xBuf = new byte[4]; xBufOff = 0; }
+ public void update(byte in) {
+ xBuf[xBufOff++] = in;
+ if (xBufOff == xBuf.length) {
+ processWord(xBuf, 0);
+ xBufOff = 0;
+ }
+ byteCount++;
+ }
+
+ public void update(byte[] in, int inOff, int len) {
+ // fill the current word
+ while ((xBufOff != 0) && (len > 0)) {
+ update(in[inOff]);
+ inOff++;
+ len--;
+ }
+
+ // process whole words.
+ while (len > xBuf.length) {
+ processWord(in, inOff);
+ inOff += xBuf.length;
+ len -= xBuf.length;
+ byteCount += xBuf.length;
+ }
+
+ // load in the remainder.
+ while (len > 0) {
+ update(in[inOff]);
+ inOff++;
+ len--;
+ }
+ }
+
+ protected void finish() {
+ long bitLength = (byteCount << 3);
+ // add the pad bytes.
+ update((byte)128);
+ while (xBufOff != 0) update((byte)0);
+ processLength(bitLength);
+ processBlock();
+ }
+
+ public void reset() {
+ byteCount = 0;
+ xBufOff = 0;
+ for ( int i = 0; i < xBuf.length; i++) xBuf[i] = 0;
+ }
+
+ protected abstract void processWord(byte[] in, int inOff);
+ protected abstract void processLength(long bitLength);
+ protected abstract void processBlock();
+ public abstract int getDigestSize();
+ public abstract void doFinal(byte[] out, int outOff);
+}
--- /dev/null
+package org.ibex.crypto;
+
+public class HMAC extends Digest {
+ private final Digest h;
+ private final byte[] digest;
+ private final byte[] k_ipad = new byte[64];
+ private final byte[] k_opad = new byte[64];
+
+ public int getDigestSize() { return h.getDigestSize(); }
+ public HMAC(Digest h, byte[] key) {
+ this.h = h;
+ if(key.length > 64) {
+ h.reset();
+ h.update(key,0,key.length);
+ key = new byte[h.getDigestSize()];
+ h.doFinal(key,0);
+ }
+ digest = new byte[h.getDigestSize()];
+ for(int i=0;i<64;i++) {
+ byte b = i < key.length ? key[i] : 0;
+ k_ipad[i] = (byte)(b ^ 0x36);
+ k_opad[i] = (byte)(b ^ 0x5C);
+ }
+ reset();
+ }
+ public void reset() {
+ h.reset();
+ h.update(k_ipad,0,64);
+ }
+ public void update(byte[] b, int off, int len) { h.update(b,off,len); }
+ public void doFinal(byte[] out, int off){
+ h.doFinal(digest,0);
+ h.update(k_opad,0,64);
+ h.update(digest,0,digest.length);
+ h.doFinal(out,off);
+ reset();
+ }
+ protected void processWord(byte[] in, int inOff) {}
+ protected void processLength(long bitLength) {}
+ protected void processBlock() {}
+}
--- /dev/null
+/* Copyright (c) 2000 The Legion Of The Bouncy Castle
+ * (http://www.bouncycastle.org)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDER.S BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+package org.ibex.crypto;
+
+/* implementation of MD2
+ * as outlined in RFC1319 by B.Kaliski from RSA Laboratories April 1992
+ */
+public class MD2 extends Digest
+{
+ private static final int DIGEST_LENGTH = 16;
+
+ /* X buffer */
+ private byte[] X = new byte[48];
+ private int xOff;
+ /* M buffer */
+ private byte[] M = new byte[16];
+ private int mOff;
+ /* check sum */
+ private byte[] C = new byte[16];
+ //private int COff;
+
+ public MD2()
+ {
+ reset();
+ }
+
+ /**
+ * return the size, in bytes, of the digest produced by this message digest.
+ *
+ * @return the size, in bytes, of the digest produced by this message digest.
+ */
+ public int getDigestSize()
+ {
+ return DIGEST_LENGTH;
+ }
+ /**
+ * close the digest, producing the final digest value. The doFinal
+ * call leaves the digest reset.
+ *
+ * @param out the array the digest is to be copied into.
+ * @param outOff the offset into the out array the digest is to start at.
+ */
+ public void doFinal(byte[] out, int outOff)
+ {
+ // add padding
+ byte paddingByte = (byte)(M.length-mOff);
+ for (int i=mOff;i<M.length;i++)
+ {
+ M[i] = paddingByte;
+ }
+ //do final check sum
+ processCheckSum(M);
+ // do final block process
+ processBlock(M);
+
+ processBlock(C);
+
+ System.arraycopy(X,xOff,out,outOff,16);
+
+ reset();
+ }
+ /**
+ * reset the digest back to it's initial state.
+ */
+ public void reset()
+ {
+ xOff = 0;
+ for (int i = 0; i != X.length; i++)
+ {
+ X[i] = 0;
+ }
+ mOff = 0;
+ for (int i = 0; i != M.length; i++)
+ {
+ M[i] = 0;
+ }
+ //COff = 0;
+ for (int i = 0; i != C.length; i++)
+ {
+ C[i] = 0;
+ }
+ }
+ /**
+ * update the message digest with a single byte.
+ *
+ * @param in the input byte to be entered.
+ */
+ public void update(byte in)
+ {
+ M[mOff++] = in;
+
+ if (mOff == 16)
+ {
+ processCheckSum(M);
+ processBlock(M);
+ mOff = 0;
+ }
+ }
+
+ /**
+ * update the message digest with a block of bytes.
+ *
+ * @param in the byte array containing the data.
+ * @param inOff the offset into the byte array where the data starts.
+ * @param len the length of the data.
+ */
+ public void update(byte[] in, int inOff, int len)
+ {
+ //
+ // fill the current word
+ //
+ while ((mOff != 0) && (len > 0))
+ {
+ update(in[inOff]);
+ inOff++;
+ len--;
+ }
+
+ //
+ // process whole words.
+ //
+ while (len > 16)
+ {
+ System.arraycopy(in,inOff,M,0,16);
+ processCheckSum(M);
+ processBlock(M);
+ len -= 16;
+ inOff += 16;
+ }
+
+ //
+ // load in the remainder.
+ //
+ while (len > 0)
+ {
+ update(in[inOff]);
+ inOff++;
+ len--;
+ }
+ }
+ protected void processCheckSum(byte[] m)
+ {
+ int L = C[15];
+ for (int i=0;i<16;i++)
+ {
+ C[i] ^= S[(m[i] ^ L) & 0xff];
+ L = C[i];
+ }
+ }
+ protected void processBlock(byte[] m)
+ {
+ for (int i=0;i<16;i++)
+ {
+ X[i+16] = m[i];
+ X[i+32] = (byte)(m[i] ^ X[i]);
+ }
+ // encrypt block
+ int t = 0;
+
+ for (int j=0;j<18;j++)
+ {
+ for (int k=0;k<48;k++)
+ {
+ t = X[k] ^= S[t];
+ t = t & 0xff;
+ }
+ t = (t + j)%256;
+ }
+ }
+ // 256-byte random permutation constructed from the digits of PI
+ private static final byte[] S = {
+ (byte)41,(byte)46,(byte)67,(byte)201,(byte)162,(byte)216,(byte)124,
+ (byte)1,(byte)61,(byte)54,(byte)84,(byte)161,(byte)236,(byte)240,
+ (byte)6,(byte)19,(byte)98,(byte)167,(byte)5,(byte)243,(byte)192,
+ (byte)199,(byte)115,(byte)140,(byte)152,(byte)147,(byte)43,(byte)217,
+ (byte)188,(byte)76,(byte)130,(byte)202,(byte)30,(byte)155,(byte)87,
+ (byte)60,(byte)253,(byte)212,(byte)224,(byte)22,(byte)103,(byte)66,
+ (byte)111,(byte)24,(byte)138,(byte)23,(byte)229,(byte)18,(byte)190,
+ (byte)78,(byte)196,(byte)214,(byte)218,(byte)158,(byte)222,(byte)73,
+ (byte)160,(byte)251,(byte)245,(byte)142,(byte)187,(byte)47,(byte)238,
+ (byte)122,(byte)169,(byte)104,(byte)121,(byte)145,(byte)21,(byte)178,
+ (byte)7,(byte)63,(byte)148,(byte)194,(byte)16,(byte)137,(byte)11,
+ (byte)34,(byte)95,(byte)33,(byte)128,(byte)127,(byte)93,(byte)154,
+ (byte)90,(byte)144,(byte)50,(byte)39,(byte)53,(byte)62,(byte)204,
+ (byte)231,(byte)191,(byte)247,(byte)151,(byte)3,(byte)255,(byte)25,
+ (byte)48,(byte)179,(byte)72,(byte)165,(byte)181,(byte)209,(byte)215,
+ (byte)94,(byte)146,(byte)42,(byte)172,(byte)86,(byte)170,(byte)198,
+ (byte)79,(byte)184,(byte)56,(byte)210,(byte)150,(byte)164,(byte)125,
+ (byte)182,(byte)118,(byte)252,(byte)107,(byte)226,(byte)156,(byte)116,
+ (byte)4,(byte)241,(byte)69,(byte)157,(byte)112,(byte)89,(byte)100,
+ (byte)113,(byte)135,(byte)32,(byte)134,(byte)91,(byte)207,(byte)101,
+ (byte)230,(byte)45,(byte)168,(byte)2,(byte)27,(byte)96,(byte)37,
+ (byte)173,(byte)174,(byte)176,(byte)185,(byte)246,(byte)28,(byte)70,
+ (byte)97,(byte)105,(byte)52,(byte)64,(byte)126,(byte)15,(byte)85,
+ (byte)71,(byte)163,(byte)35,(byte)221,(byte)81,(byte)175,(byte)58,
+ (byte)195,(byte)92,(byte)249,(byte)206,(byte)186,(byte)197,(byte)234,
+ (byte)38,(byte)44,(byte)83,(byte)13,(byte)110,(byte)133,(byte)40,
+ (byte)132, 9,(byte)211,(byte)223,(byte)205,(byte)244,(byte)65,
+ (byte)129,(byte)77,(byte)82,(byte)106,(byte)220,(byte)55,(byte)200,
+ (byte)108,(byte)193,(byte)171,(byte)250,(byte)36,(byte)225,(byte)123,
+ (byte)8,(byte)12,(byte)189,(byte)177,(byte)74,(byte)120,(byte)136,
+ (byte)149,(byte)139,(byte)227,(byte)99,(byte)232,(byte)109,(byte)233,
+ (byte)203,(byte)213,(byte)254,(byte)59,(byte)0,(byte)29,(byte)57,
+ (byte)242,(byte)239,(byte)183,(byte)14,(byte)102,(byte)88,(byte)208,
+ (byte)228,(byte)166,(byte)119,(byte)114,(byte)248,(byte)235,(byte)117,
+ (byte)75,(byte)10,(byte)49,(byte)68,(byte)80,(byte)180,(byte)143,
+ (byte)237,(byte)31,(byte)26,(byte)219,(byte)153,(byte)141,(byte)51,
+ (byte)159,(byte)17,(byte)131,(byte)20
+ };
+
+
+ protected void processWord(byte[] in, int inOff) {}
+ protected void processLength(long bitLength) {}
+ protected void processBlock() {}
+}
--- /dev/null
+/* Copyright (c) 2000 The Legion Of The Bouncy Castle
+ * (http://www.bouncycastle.org)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDER.S BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+package org.ibex.crypto;
+
+/**
+ * implementation of MD5 as outlined in "Handbook of Applied Cryptography", pages 346 - 347.
+ */
+public class MD5
+ extends Digest
+{
+ private static final int DIGEST_LENGTH = 16;
+
+ private int H1, H2, H3, H4; // IV's
+
+ private int[] X = new int[16];
+ private int xOff;
+
+ /**
+ * Standard constructor
+ */
+ public MD5()
+ {
+ reset();
+ }
+
+ public int getDigestSize()
+ {
+ return DIGEST_LENGTH;
+ }
+
+ protected void processWord(
+ byte[] in,
+ int inOff)
+ {
+ X[xOff++] = (in[inOff] & 0xff) | ((in[inOff + 1] & 0xff) << 8)
+ | ((in[inOff + 2] & 0xff) << 16) | ((in[inOff + 3] & 0xff) << 24);
+
+ if (xOff == 16)
+ {
+ processBlock();
+ }
+ }
+
+ protected void processLength(
+ long bitLength)
+ {
+ if (xOff > 14)
+ {
+ processBlock();
+ }
+
+ X[14] = (int)(bitLength & 0xffffffff);
+ X[15] = (int)(bitLength >>> 32);
+ }
+
+ private void unpackWord(
+ int word,
+ byte[] out,
+ int outOff)
+ {
+ out[outOff] = (byte)word;
+ out[outOff + 1] = (byte)(word >>> 8);
+ out[outOff + 2] = (byte)(word >>> 16);
+ out[outOff + 3] = (byte)(word >>> 24);
+ }
+
+ public void doFinal(
+ byte[] out,
+ int outOff)
+ {
+ finish();
+
+ unpackWord(H1, out, outOff);
+ unpackWord(H2, out, outOff + 4);
+ unpackWord(H3, out, outOff + 8);
+ unpackWord(H4, out, outOff + 12);
+
+ reset();
+ }
+
+ /**
+ * reset the chaining variables to the IV values.
+ */
+ public void reset()
+ {
+ super.reset();
+
+ H1 = 0x67452301;
+ H2 = 0xefcdab89;
+ H3 = 0x98badcfe;
+ H4 = 0x10325476;
+
+ xOff = 0;
+
+ for (int i = 0; i != X.length; i++)
+ {
+ X[i] = 0;
+ }
+ }
+
+ /*
+ * rotate int x left n bits.
+ */
+ private int rotateLeft(
+ int x,
+ int n)
+ {
+ return (x << n) | (x >>> (32 - n));
+ }
+
+ /*
+ * F, G, H and I are the basic MD5 functions.
+ */
+ private int F(
+ int u,
+ int v,
+ int w)
+ {
+ return (u & v) | (~u & w);
+ }
+
+ private int G(
+ int u,
+ int v,
+ int w)
+ {
+ return (u & w) | (v & ~w);
+ }
+
+ private int H(
+ int u,
+ int v,
+ int w)
+ {
+ return u ^ v ^ w;
+ }
+
+ private int K(
+ int u,
+ int v,
+ int w)
+ {
+ return v ^ (u | ~w);
+ }
+
+ protected void processBlock()
+ {
+ int a = H1;
+ int b = H2;
+ int c = H3;
+ int d = H4;
+
+ //
+ // Round 1 - F cycle, 16 times.
+ //
+ a = rotateLeft((a + F(b, c, d) + X[ 0] + 0xd76aa478), 7) + b;
+ d = rotateLeft((d + F(a, b, c) + X[ 1] + 0xe8c7b756), 12) + a;
+ c = rotateLeft((c + F(d, a, b) + X[ 2] + 0x242070db), 17) + d;
+ b = rotateLeft((b + F(c, d, a) + X[ 3] + 0xc1bdceee), 22) + c;
+ a = rotateLeft((a + F(b, c, d) + X[ 4] + 0xf57c0faf), 7) + b;
+ d = rotateLeft((d + F(a, b, c) + X[ 5] + 0x4787c62a), 12) + a;
+ c = rotateLeft((c + F(d, a, b) + X[ 6] + 0xa8304613), 17) + d;
+ b = rotateLeft((b + F(c, d, a) + X[ 7] + 0xfd469501), 22) + c;
+ a = rotateLeft((a + F(b, c, d) + X[ 8] + 0x698098d8), 7) + b;
+ d = rotateLeft((d + F(a, b, c) + X[ 9] + 0x8b44f7af), 12) + a;
+ c = rotateLeft((c + F(d, a, b) + X[10] + 0xffff5bb1), 17) + d;
+ b = rotateLeft((b + F(c, d, a) + X[11] + 0x895cd7be), 22) + c;
+ a = rotateLeft((a + F(b, c, d) + X[12] + 0x6b901122), 7) + b;
+ d = rotateLeft((d + F(a, b, c) + X[13] + 0xfd987193), 12) + a;
+ c = rotateLeft((c + F(d, a, b) + X[14] + 0xa679438e), 17) + d;
+ b = rotateLeft((b + F(c, d, a) + X[15] + 0x49b40821), 22) + c;
+
+ //
+ // Round 2 - G cycle, 16 times.
+ //
+ a = rotateLeft((a + G(b, c, d) + X[ 1] + 0xf61e2562), 5) + b;
+ d = rotateLeft((d + G(a, b, c) + X[ 6] + 0xc040b340), 9) + a;
+ c = rotateLeft((c + G(d, a, b) + X[11] + 0x265e5a51), 14) + d;
+ b = rotateLeft((b + G(c, d, a) + X[ 0] + 0xe9b6c7aa), 20) + c;
+ a = rotateLeft((a + G(b, c, d) + X[ 5] + 0xd62f105d), 5) + b;
+ d = rotateLeft((d + G(a, b, c) + X[10] + 0x02441453), 9) + a;
+ c = rotateLeft((c + G(d, a, b) + X[15] + 0xd8a1e681), 14) + d;
+ b = rotateLeft((b + G(c, d, a) + X[ 4] + 0xe7d3fbc8), 20) + c;
+ a = rotateLeft((a + G(b, c, d) + X[ 9] + 0x21e1cde6), 5) + b;
+ d = rotateLeft((d + G(a, b, c) + X[14] + 0xc33707d6), 9) + a;
+ c = rotateLeft((c + G(d, a, b) + X[ 3] + 0xf4d50d87), 14) + d;
+ b = rotateLeft((b + G(c, d, a) + X[ 8] + 0x455a14ed), 20) + c;
+ a = rotateLeft((a + G(b, c, d) + X[13] + 0xa9e3e905), 5) + b;
+ d = rotateLeft((d + G(a, b, c) + X[ 2] + 0xfcefa3f8), 9) + a;
+ c = rotateLeft((c + G(d, a, b) + X[ 7] + 0x676f02d9), 14) + d;
+ b = rotateLeft((b + G(c, d, a) + X[12] + 0x8d2a4c8a), 20) + c;
+
+ //
+ // Round 3 - H cycle, 16 times.
+ //
+ a = rotateLeft((a + H(b, c, d) + X[ 5] + 0xfffa3942), 4) + b;
+ d = rotateLeft((d + H(a, b, c) + X[ 8] + 0x8771f681), 11) + a;
+ c = rotateLeft((c + H(d, a, b) + X[11] + 0x6d9d6122), 16) + d;
+ b = rotateLeft((b + H(c, d, a) + X[14] + 0xfde5380c), 23) + c;
+ a = rotateLeft((a + H(b, c, d) + X[ 1] + 0xa4beea44), 4) + b;
+ d = rotateLeft((d + H(a, b, c) + X[ 4] + 0x4bdecfa9), 11) + a;
+ c = rotateLeft((c + H(d, a, b) + X[ 7] + 0xf6bb4b60), 16) + d;
+ b = rotateLeft((b + H(c, d, a) + X[10] + 0xbebfbc70), 23) + c;
+ a = rotateLeft((a + H(b, c, d) + X[13] + 0x289b7ec6), 4) + b;
+ d = rotateLeft((d + H(a, b, c) + X[ 0] + 0xeaa127fa), 11) + a;
+ c = rotateLeft((c + H(d, a, b) + X[ 3] + 0xd4ef3085), 16) + d;
+ b = rotateLeft((b + H(c, d, a) + X[ 6] + 0x04881d05), 23) + c;
+ a = rotateLeft((a + H(b, c, d) + X[ 9] + 0xd9d4d039), 4) + b;
+ d = rotateLeft((d + H(a, b, c) + X[12] + 0xe6db99e5), 11) + a;
+ c = rotateLeft((c + H(d, a, b) + X[15] + 0x1fa27cf8), 16) + d;
+ b = rotateLeft((b + H(c, d, a) + X[ 2] + 0xc4ac5665), 23) + c;
+
+ //
+ // Round 4 - K cycle, 16 times.
+ //
+ a = rotateLeft((a + K(b, c, d) + X[ 0] + 0xf4292244), 6) + b;
+ d = rotateLeft((d + K(a, b, c) + X[ 7] + 0x432aff97), 10) + a;
+ c = rotateLeft((c + K(d, a, b) + X[14] + 0xab9423a7), 15) + d;
+ b = rotateLeft((b + K(c, d, a) + X[ 5] + 0xfc93a039), 21) + c;
+ a = rotateLeft((a + K(b, c, d) + X[12] + 0x655b59c3), 6) + b;
+ d = rotateLeft((d + K(a, b, c) + X[ 3] + 0x8f0ccc92), 10) + a;
+ c = rotateLeft((c + K(d, a, b) + X[10] + 0xffeff47d), 15) + d;
+ b = rotateLeft((b + K(c, d, a) + X[ 1] + 0x85845dd1), 21) + c;
+ a = rotateLeft((a + K(b, c, d) + X[ 8] + 0x6fa87e4f), 6) + b;
+ d = rotateLeft((d + K(a, b, c) + X[15] + 0xfe2ce6e0), 10) + a;
+ c = rotateLeft((c + K(d, a, b) + X[ 6] + 0xa3014314), 15) + d;
+ b = rotateLeft((b + K(c, d, a) + X[13] + 0x4e0811a1), 21) + c;
+ a = rotateLeft((a + K(b, c, d) + X[ 4] + 0xf7537e82), 6) + b;
+ d = rotateLeft((d + K(a, b, c) + X[11] + 0xbd3af235), 10) + a;
+ c = rotateLeft((c + K(d, a, b) + X[ 2] + 0x2ad7d2bb), 15) + d;
+ b = rotateLeft((b + K(c, d, a) + X[ 9] + 0xeb86d391), 21) + c;
+
+ H1 += a;
+ H2 += b;
+ H3 += c;
+ H4 += d;
+
+ //
+ // reset the offset and clean out the word buffer.
+ //
+ xOff = 0;
+ for (int i = 0; i != X.length; i++)
+ {
+ X[i] = 0;
+ }
+ }
+}
--- /dev/null
+package org.ibex.crypto;
+import java.security.SecureRandom;
+
+public class PKCS1 {
+ private final RSA rsa;
+ private final SecureRandom srand;
+ public PKCS1(RSA rsa) { this(rsa,new SecureRandom()); }
+ public PKCS1(RSA rsa,SecureRandom srand) { this.rsa = rsa; this.srand = srand; }
+
+ public byte[] encode(byte[] in) {
+ int size = rsa.getInputBlockSize();
+ if(in.length > size - 11) throw new IllegalArgumentException("message too long");
+ byte[] buf = new byte[size];
+ byte[] rand = new byte[size - in.length - 2];
+ srand.nextBytes(rand);
+ for(int i=0;i<rand.length;i++) while(rand[i] == 0) rand[i] = (byte)srand.nextInt();
+ int p=0;
+ buf[p++] = 0x02;
+ System.arraycopy(rand,0,buf,p,rand.length);
+ p+=rand.length;
+ buf[p++] = 0x0;
+ System.arraycopy(in,0,buf,p,in.length);
+
+ return rsa.process(buf);
+ }
+
+ public byte[] decode(byte[] in) throws Exn {
+ byte[] buf = rsa.process(in);
+ if(buf.length < 10) throw new Exn("Data too short");
+ if(buf[0] != 2 && buf[0] != 1) throw new Exn("Data not in correct format " + (buf[0]&0xff));
+ int start = 9;
+ while(start < buf.length && buf[start] != 0) start++;
+ if(start == buf.length) throw new Exn("No null separator");
+ start++;
+ byte[] ret = new byte[buf.length - start];
+ System.arraycopy(buf,start,ret,0,ret.length);
+ return ret;
+ }
+
+ public static class Exn extends Exception { public Exn(String s) { super(s); } }
+}
--- /dev/null
+package org.ibex.crypto;
+
+
+public class RC4 {
+ private final byte[] s = new byte[256];
+ private int x,y;
+
+ public RC4(byte[] k) {
+ for(int i=0;i<256;i++) s[i] = (byte)i;
+ for(int i=0,j=0;i<256;i++) {
+ j = (j + (s[i]&0xff) + (k[i%k.length]&0xff))&0xff;
+ byte tmp = s[i];
+ s[i] = s[j];
+ s[j] = tmp;
+ }
+ }
+
+ public void process(byte[] in, int ip, byte[] out, int op, int len) {
+ int x = this.x;
+ int y = this.y;
+ byte[] s = this.s;
+ for(int i=0;i<len;i++) {
+ x = (x + 1) & 0xff;
+ y = (y + (s[x]&0xff)) & 0xff;
+ byte tmp = s[x];
+ s[x] = s[y];
+ s[y] = tmp;
+ int t = ((s[x]&0xff) + (s[y]&0xff))&0xff;
+ int k = s[t];
+ out[op+i] = (byte)((in[ip+i]&0xff)^k);
+ }
+ this.x = x;
+ this.y = y;
+ }
+}
--- /dev/null
+package org.ibex.crypto;
+import java.math.BigInteger;
+import java.util.*;
+
+public class RSA {
+ private final BigInteger pq;
+ private final BigInteger e;
+ private final boolean reverse;
+
+ public RSA(BigInteger pq, BigInteger e, boolean reverse) {
+ this.pq = pq;
+ this.e = e;
+ this.reverse = reverse;
+ }
+
+ public int getInputBlockSize() { return (pq.bitLength()+7) / 8 - (reverse ? 0 : 1); }
+ public int getOutputBlockSize() { return (pq.bitLength()+7) / 8 - (reverse ? 1 : 0); }
+
+ public byte[] process(byte[] in) {
+ // output block is the same size as the modulus (rounded up)
+ int outSize = getOutputBlockSize();
+ BigInteger t = new BigInteger(1,in);
+ BigInteger c = t.modPow(e,pq);
+ byte[] cbytes = c.toByteArray();
+ if(cbytes.length > outSize || (reverse && cbytes[0] == 0)) {
+ if(cbytes[0] != 0) throw new RuntimeException("should never happen");
+ byte[] buf = new byte[outSize];
+ System.arraycopy(cbytes,1,buf,0,outSize);
+ return buf;
+ } else if(!reverse && cbytes.length < outSize) {
+ // output needs to be exactly outSize in length
+ byte[] buf = new byte[outSize];
+ System.arraycopy(cbytes,0,buf,outSize-cbytes.length,cbytes.length);
+ return buf;
+ } else {
+ return cbytes;
+ }
+ }
+
+ public static class PublicKey {
+ public final BigInteger modulus;
+ public final BigInteger exponent;
+
+ public PublicKey(Object o) {
+ Vector seq = (Vector) o;
+ modulus = (BigInteger) seq.elementAt(0);
+ exponent = (BigInteger) seq.elementAt(1);
+ }
+ }
+
+}
--- /dev/null
+/* Copyright (c) 2000 The Legion Of The Bouncy Castle
+ * (http://www.bouncycastle.org)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDER.S BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+package org.ibex.crypto;
+
+/**
+ * implementation of SHA-1 as outlined in "Handbook of Applied Cryptography", pages 346 - 349.
+ *
+ * It is interesting to ponder why the, apart from the extra IV, the other difference here from MD5
+ * is the "endienness" of the word processing!
+ */
+public class SHA1
+ extends Digest
+{
+ private static final int DIGEST_LENGTH = 20;
+
+ private int H1, H2, H3, H4, H5;
+
+ private int[] X = new int[80];
+ private int xOff;
+
+ /**
+ * Standard constructor
+ */
+ public SHA1()
+ {
+ reset();
+ }
+
+ public int getDigestSize()
+ {
+ return DIGEST_LENGTH;
+ }
+
+ protected void processWord(
+ byte[] in,
+ int inOff)
+ {
+ X[xOff++] = ((in[inOff] & 0xff) << 24) | ((in[inOff + 1] & 0xff) << 16)
+ | ((in[inOff + 2] & 0xff) << 8) | ((in[inOff + 3] & 0xff));
+
+ if (xOff == 16)
+ {
+ processBlock();
+ }
+ }
+
+ private void unpackWord(
+ int word,
+ byte[] out,
+ int outOff)
+ {
+ out[outOff] = (byte)(word >>> 24);
+ out[outOff + 1] = (byte)(word >>> 16);
+ out[outOff + 2] = (byte)(word >>> 8);
+ out[outOff + 3] = (byte)word;
+ }
+
+ protected void processLength(
+ long bitLength)
+ {
+ if (xOff > 14)
+ {
+ processBlock();
+ }
+
+ X[14] = (int)(bitLength >>> 32);
+ X[15] = (int)(bitLength & 0xffffffff);
+ }
+
+ public void doFinal(
+ byte[] out,
+ int outOff)
+ {
+ finish();
+
+ unpackWord(H1, out, outOff);
+ unpackWord(H2, out, outOff + 4);
+ unpackWord(H3, out, outOff + 8);
+ unpackWord(H4, out, outOff + 12);
+ unpackWord(H5, out, outOff + 16);
+
+ reset();
+ }
+
+ /**
+ * reset the chaining variables
+ */
+ public void reset()
+ {
+ super.reset();
+
+ H1 = 0x67452301;
+ H2 = 0xefcdab89;
+ H3 = 0x98badcfe;
+ H4 = 0x10325476;
+ H5 = 0xc3d2e1f0;
+
+ xOff = 0;
+ for (int i = 0; i != X.length; i++)
+ {
+ X[i] = 0;
+ }
+ }
+
+ private int f(
+ int u,
+ int v,
+ int w)
+ {
+ return ((u & v) | ((~u) & w));
+ }
+
+ private int h(
+ int u,
+ int v,
+ int w)
+ {
+ return (u ^ v ^ w);
+ }
+
+ private int g(
+ int u,
+ int v,
+ int w)
+ {
+ return ((u & v) | (u & w) | (v & w));
+ }
+
+ private int rotateLeft(
+ int x,
+ int n)
+ {
+ return (x << n) | (x >>> (32 - n));
+ }
+
+ protected void processBlock()
+ {
+ //
+ // expand 16 word block into 80 word block.
+ //
+ for (int i = 16; i <= 79; i++)
+ {
+ X[i] = rotateLeft((X[i - 3] ^ X[i - 8] ^ X[i - 14] ^ X[i - 16]), 1);
+ }
+
+ //
+ // set up working variables.
+ //
+ int A = H1;
+ int B = H2;
+ int C = H3;
+ int D = H4;
+ int E = H5;
+
+ //
+ // round 1
+ //
+ for (int j = 0; j <= 19; j++)
+ {
+ int t = rotateLeft(A, 5) + f(B, C, D) + E + X[j] + 0x5a827999;
+
+ E = D;
+ D = C;
+ C = rotateLeft(B, 30);
+ B = A;
+ A = t;
+ }
+
+ //
+ // round 2
+ //
+ for (int j = 20; j <= 39; j++)
+ {
+ int t = rotateLeft(A, 5) + h(B, C, D) + E + X[j] + 0x6ed9eba1;
+
+ E = D;
+ D = C;
+ C = rotateLeft(B, 30);
+ B = A;
+ A = t;
+ }
+
+ //
+ // round 3
+ //
+ for (int j = 40; j <= 59; j++)
+ {
+ int t = rotateLeft(A, 5) + g(B, C, D) + E + X[j] + 0x8f1bbcdc;
+
+ E = D;
+ D = C;
+ C = rotateLeft(B, 30);
+ B = A;
+ A = t;
+ }
+
+ //
+ // round 4
+ //
+ for (int j = 60; j <= 79; j++)
+ {
+ int t = rotateLeft(A, 5) + h(B, C, D) + E + X[j] + 0xca62c1d6;
+
+ E = D;
+ D = C;
+ C = rotateLeft(B, 30);
+ B = A;
+ A = t;
+ }
+
+ H1 += A;
+ H2 += B;
+ H3 += C;
+ H4 += D;
+ H5 += E;
+
+ //
+ // reset the offset and clean out the word buffer.
+ //
+ xOff = 0;
+ for (int i = 0; i != X.length; i++)
+ {
+ X[i] = 0;
+ }
+ }
+}
--- /dev/null
+/*
+ * com.brian_web.x509.* - By Brian Alliet
+ * Copyright (C) 2004 Brian Alliet
+ *
+ * Based on Bouncy Castle by The Legion Of The Bouncy Castle
+ * Copyright (c) 2000 The Legion Of The Bouncy Castle
+ * (http://www.bouncycastle.org)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDER.S BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+package org.ibex.crypto;
+
+import java.io.*;
+import java.util.*;
+
+public class X509 {
+ public static class Certificate {
+ public static final String RSA_ENCRYPTION = "1.2.840.113549.1.1.1";
+ public static final String MD2_WITH_RSA_ENCRYPTION = "1.2.840.113549.1.1.2";
+ public static final String MD4_WITH_RSA_ENCRYPTION = "1.2.840.113549.1.1.3";
+ public static final String MD5_WITH_RSA_ENCRYPTION = "1.2.840.113549.1.1.4";
+ public static final String SHA1_WITH_RSA_ENCRYPTION = "1.2.840.113549.1.1.5";
+
+ public static final String BASIC_CONSTRAINTS = "2.5.29.19";
+
+ private final byte[] certBytes;
+ private final byte[] tbsCertBytes;
+
+ public final Number version;
+ public final Number serialNo;
+ public final X509.Name issuer;
+ public final Date startDate;
+ public final Date endDate;
+ public final X509.Name subject;
+
+ public final AlgorithmIdentifier publicKeyAlgorithm;
+ public final DER.BitString publicKey;
+
+ public final Object issuerUniqueID;
+ public final Object subjectUniqueID;
+
+ public final Vector extensions;
+
+ public final DER.BitString signature;
+ public final AlgorithmIdentifier signatureAlgorithm;
+
+ public final BC basicContraints;
+
+
+ public Certificate(InputStream is) throws IOException {
+ int i;
+ RecordingInputStream certIS = new RecordingInputStream(is);
+ DER.InputStream certSequence = DER.InputStream.New(certIS).getSequenceStream();
+ RecordingInputStream tbsCertIS = new RecordingInputStream(certSequence);
+
+ try {
+ Vector tbsSequence = (Vector) DER.InputStream.New(tbsCertIS).readObject();
+ tbsCertBytes = tbsCertIS.getBytes();
+ signatureAlgorithm = new AlgorithmIdentifier(certSequence.readObject());
+ signature = (DER.BitString) certSequence.readObject();
+
+ i=0;
+ if(tbsSequence.elementAt(i) instanceof DER.TaggedObject)
+ version = (Number)((DER.TaggedObject)tbsSequence.elementAt(i++)).object;
+ else
+ version = new Integer(0);
+
+ serialNo = (Number) tbsSequence.elementAt(i++);
+ AlgorithmIdentifier signatureAlgorithm2 = new AlgorithmIdentifier(tbsSequence.elementAt(i++));
+ if(!signatureAlgorithm2.equals(signatureAlgorithm))
+ throw new DER.Exception("AlgoritmIdentifier mismatch " + signatureAlgorithm + " vs " + signatureAlgorithm2);
+ issuer = new X509.Name(tbsSequence.elementAt(i++));
+
+ Vector validity = (Vector) tbsSequence.elementAt(i++);
+ startDate = (Date) validity.elementAt(0);
+ endDate = (Date) validity.elementAt(1);
+
+ subject = new X509.Name(tbsSequence.elementAt(i++));
+
+ Vector publicKeyInfo = (Vector) tbsSequence.elementAt(i++);
+ publicKeyAlgorithm = new AlgorithmIdentifier(publicKeyInfo.elementAt(0));
+ publicKey = (DER.BitString) publicKeyInfo.elementAt(1);
+
+ Object issuerUniqueID_=null,subjectUniqueID_=null;
+ Vector extensions_=null;
+ for(;i < tbsSequence.size();i++) {
+ DER.TaggedObject to = (DER.TaggedObject) tbsSequence.elementAt(i);
+ switch(to.tag) {
+ case 1: issuerUniqueID_ = to.object; break;
+ case 2: subjectUniqueID_ = to.object; break;
+ case 3: extensions_ = (Vector) to.object; break;
+ }
+ }
+ issuerUniqueID = issuerUniqueID_;
+ subjectUniqueID = subjectUniqueID_;
+ extensions = extensions_;
+
+ BC bc = null;
+
+ if(extensions != null) {
+ for(Enumeration e = extensions.elements(); e.hasMoreElements(); ) {
+ Vector extension = (Vector) e.nextElement();
+ String oid = (String) extension.elementAt(0);
+ byte[] data = (byte[]) extension.elementAt(extension.size()-1);
+ if(oid.equals(BASIC_CONSTRAINTS))
+ bc = new BC(DER.InputStream.New(new ByteArrayInputStream(data)).readObject());
+ }
+ }
+ basicContraints = bc;
+ } catch(RuntimeException e) {
+ e.printStackTrace();
+ throw new DER.Exception("Invalid x509 Certificate");
+ }
+ certBytes = certIS.getBytes();
+ }
+
+
+ public String getSubjectField(String fieldID) { return subject.get(fieldID); }
+ public String getCN() { return getSubjectField(X509.Name.CN); }
+
+ public boolean isValid() {
+ Date now = new Date();
+ return !now.after(endDate) && !now.before(startDate);
+ }
+
+ public RSA.PublicKey getRSAPublicKey() throws DER.Exception {
+ if(!RSA_ENCRYPTION.equals(publicKeyAlgorithm.id)) throw new DER.Exception("This isn't an RSA public key");
+ try {
+ return new RSA.PublicKey(DER.InputStream.New(new ByteArrayInputStream(publicKey.data)).readObject());
+ } catch(IOException e) {
+ throw new DER.Exception(e.getMessage());
+ } catch(RuntimeException e) {
+ throw new DER.Exception("Invalid RSA Public Key " + e.getMessage());
+ }
+ }
+
+ public boolean isSignedBy(Certificate signer) throws DER.Exception {
+ return isSignedWith(signer.getRSAPublicKey());
+ }
+ public boolean isSignedWith(RSA.PublicKey rsapk) throws DER.Exception {
+ try {
+ Digest digest;
+ if(signatureAlgorithm.id.equals(MD5_WITH_RSA_ENCRYPTION)) digest = new MD5();
+ else if(signatureAlgorithm.id.equals(SHA1_WITH_RSA_ENCRYPTION)) digest = new SHA1();
+ else if(signatureAlgorithm.id.equals(MD2_WITH_RSA_ENCRYPTION)) digest = new MD2();
+ else throw new DER.Exception("Unknown signing algorithm: " + signatureAlgorithm.id);
+
+ PKCS1 pkcs1 = new PKCS1(new RSA(rsapk.modulus,rsapk.exponent,true));
+ byte[] d = pkcs1.decode(signature.data);
+
+ Vector v = (Vector) DER.InputStream.New(new ByteArrayInputStream(d)).readObject();
+ byte[] signedDigest = (byte[]) v.elementAt(1);
+
+ if(signedDigest.length != digest.getDigestSize()) return false;
+
+ digest.update(tbsCertBytes,0,tbsCertBytes.length);
+ byte[] ourDigest = new byte[digest.getDigestSize()];
+ digest.doFinal(ourDigest,0);
+
+ for(int i=0;i<digest.getDigestSize();i++) if(ourDigest[i] != signedDigest[i]) return false;
+ return true;
+ }
+ catch(RuntimeException e) { e.printStackTrace(); return false; }
+ catch(PKCS1.Exn e) { e.printStackTrace(); return false; }
+ catch(IOException e) { e.printStackTrace(); return false; }
+ }
+
+ public byte[] getMD5Fingerprint() { return getFingerprint(new MD5()); }
+ public byte[] getSHA1Fingerprint() { return getFingerprint(new SHA1()); }
+ public byte[] getFingerprint(Digest h) {
+ h.update(certBytes,0,certBytes.length);
+ byte[] digest = new byte[h.getDigestSize()];
+ h.doFinal(digest,0);
+ return digest;
+ }
+
+ private class RecordingInputStream extends FilterInputStream {
+ public ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ private boolean on = true;
+ public void on() { on = true; }
+ public void off() { on = false; }
+ public RecordingInputStream(InputStream is) { super(is); }
+ public int read() throws IOException {
+ int n = super.read();
+ if(n != -1 && on) baos.write(n);
+ return n;
+ }
+ public int read(byte[] buf, int off, int len) throws IOException {
+ int n = super.read(buf,off,len);
+ if(n != -1 && on) baos.write(buf,off,n);
+ return n;
+ }
+ public byte[] getBytes() { return baos.toByteArray(); }
+ }
+
+ public static class BC {
+ public final boolean isCA;
+ public final Number pathLenConstraint;
+ BC(Object o) {
+ Vector seq = (Vector) o;
+ isCA = seq.size() > 0 ? ((Boolean) seq.elementAt(0)).booleanValue() : false;
+ pathLenConstraint = seq.size() > 1 ? (Number) seq.elementAt(1) : null;
+ }
+ }
+
+ public static class AlgorithmIdentifier {
+ public final String id;
+ public final Object parameters;
+
+ AlgorithmIdentifier(Object o) {
+ Vector seq = (Vector) o;
+ id = (String) seq.elementAt(0);
+ parameters = seq.elementAt(1);
+ }
+ public boolean equals(Object o_) {
+ if(o_ == this) return true;
+ if(!(o_ instanceof AlgorithmIdentifier)) return false;
+ AlgorithmIdentifier o = (AlgorithmIdentifier) o_;
+ return o.id.equals(id) && o.parameters.equals(parameters);
+ }
+ public int hashCode() { return id.hashCode() ^ parameters.hashCode(); }
+ }
+
+ /*public static void main(String[] args) throws Exception {
+ Certificate cert = new Certificate(new FileInputStream(args[0]));
+ System.err.println("CN: " + cert.getCN());
+ System.err.println("Subject: " + cert.subject);
+ System.err.println("Issuer: " + cert.issuer);
+ System.err.println("Start Date: " + cert.startDate);
+ System.err.println("End Date: " + cert.endDate);
+ System.err.println("SHA1 Fingerprint: " + prettyBytes(cert.getSHA1Fingerprint()));
+ RSA.PublicKey key = cert.getRSA.PublicKey();
+ System.err.println("Modulus: " + prettyBytes(key.modulus.toByteArray()));
+ System.err.println("Exponent: " + key.exponent);
+ System.err.println("Signature: " + prettyBytes(cert.signature.data));
+ }
+
+ public static String prettyBytes(byte[] fp) {
+ StringBuffer sb = new StringBuffer(fp.length*3);
+ for(int i=0;i<fp.length;i++) {
+ if(i>0) sb.append(":");
+ sb.append("0123456789abcdef".charAt((fp[i] & 0xf0) >>> 4));
+ sb.append("0123456789abcdef".charAt((fp[i] & 0x0f) >>> 0));
+ }
+ return sb.toString();
+ }*/
+ }
+
+ public static class Name {
+ // Some common OIDs
+ public static final String C = "2.5.4.6";
+ public static final String O = "2.5.4.10";
+ public static final String T = "2.5.4.12";
+ public static final String SN = "2.5.4.5";
+ public static final String L = "2.5.4.7";
+ public static final String ST = "2.5.4.8";
+ public static final String OU = "2.5.4.11";
+ public static final String CN = "2.5.4.3";
+ public static final String E = "1.2.840.113549.1.9.1";
+
+ private final Vector keys = new Vector();
+ private final Vector values = new Vector();
+
+ public Name(Object seq_) throws DER.Exception {
+ try {
+ Vector seq = (Vector) seq_;
+ for(Enumeration e = seq.elements();e.hasMoreElements();) {
+ Vector component = (Vector) ((Vector)e.nextElement()).elementAt(0);
+ keys.add(component.elementAt(0));
+ values.add(component.elementAt(1));
+ }
+ } catch(RuntimeException e) {
+ e.printStackTrace();
+ throw new DER.Exception("Invalid Name " + e.toString());
+ }
+ }
+
+ public boolean equals(Object o_) {
+ if(o_ instanceof String) return toString().equals(o_);
+ if(!(o_ instanceof Name)) return false;
+ Name o = (Name) o_;
+ if(keys.size() != o.keys.size()) return false;
+ int size = keys.size();
+ for(int i=0;i<size;i++) {
+ String oid = (String) keys.elementAt(i);
+ String oid2 = (String) o.keys.elementAt(i);
+ if(!oid.equals(oid2)) return false;
+
+ String val1 = (String) values.elementAt(i);
+ String val2 = (String) o.values.elementAt(i);
+ if(val1.equals(val2)) continue;
+
+ val1 = val1.trim().toLowerCase();
+ val2 = val2.trim().toLowerCase();
+ if(val1.equals(val2)) continue;
+
+ val1 = removeExtraSpaces(val1);
+ val2 = removeExtraSpaces(val2);
+ if(val1.equals(val2)) continue;
+
+ return false;
+ }
+ return true;
+ }
+
+ public int hashCode() { return keys.hashCode() ^ values.hashCode(); }
+
+ public String get(String fieldID) {
+ int i = keys.indexOf(fieldID);
+ return i == -1 ? null : (String)values.elementAt(i);
+ }
+
+ public String[] getOIDs() {
+ String[] ret = new String[keys.size()];
+ keys.copyInto(ret);
+ return ret;
+ }
+
+ public String[] getValues() {
+ String[] ret = new String[values.size()];
+ values.copyInto(ret);
+ return ret;
+ }
+
+ private static String removeExtraSpaces(String s) {
+ if(s.indexOf(' ') == -1) return s;
+ StringBuffer sb = new StringBuffer(s.length());
+ int l = s.length();
+ boolean inWhitespace = false;
+ for(int i=0;i<l;i++) {
+ if(s.charAt(i) == ' ') {
+ if(inWhitespace) continue;
+ inWhitespace = true;
+ } else if(inWhitespace) {
+ inWhitespace = false;
+ }
+ sb.append(s.charAt(i));
+ }
+ return sb.toString();
+ }
+
+ private final static Hashtable oidMap = new Hashtable();
+ static {
+ oidMap.put(Name.C,"C");
+ oidMap.put(Name.O,"O");
+ oidMap.put(Name.T,"T");
+ oidMap.put(Name.SN,"SN");
+ oidMap.put(Name.L,"L");
+ oidMap.put(Name.ST,"ST");
+ oidMap.put(Name.OU,"OU");
+ oidMap.put(Name.CN,"CN");
+ oidMap.put(Name.E,"E");
+ }
+
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ int size = keys.size();
+ for(int i=0;i<size;i++) {
+ if(sb.length() > 0) sb.append(",");
+ String fieldID = (String) keys.elementAt(i);
+ String fieldName = (String) oidMap.get(fieldID);
+ sb.append(fieldName != null ? fieldName : fieldID).append("=").append(values.elementAt(i));
+ }
+ return sb.toString();
+ }
+ }
+}
--- /dev/null
+/*
+ * org.ibex.net.SSL - By Brian Alliet
+ * Copyright (C) 2004 Brian Alliet
+ *
+ * Based on TinySSL by Adam Megacz
+ * Copyright (C) 2003 Adam Megacz <adam@xwt.org> all rights reserved.
+ *
+ * You may modify, copy, and redistribute this code under the terms of
+ * the GNU Lesser General Public License version 2.1, with the exception
+ * of the portion of clause 6a after the semicolon (aka the "obnoxious
+ * relink clause")
+ */
+
+package org.ibex.net;
+
+import org.ibex.crypto.*;
+import java.security.SecureRandom;
+
+import java.net.Socket;
+import java.net.SocketException;
+
+import java.io.*;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Random;
+import java.util.Vector;
+
+// FEATURE: Server socket
+
+public class SSL extends Socket {
+ private String hostname;
+
+ private int negotiated;
+
+ private boolean tls = true;
+ private boolean sha;
+
+ private final DataInputStream rawIS;
+ private final DataOutputStream rawOS;
+
+ private final InputStream sslIS;
+ private final OutputStream sslOS;
+
+ private byte[] sessionID;
+
+ private Digest clientWriteMACDigest;
+ private Digest serverWriteMACDigest;
+ private byte[] masterSecret;
+
+ private RC4 writeRC4;
+ private RC4 readRC4;
+
+ private long serverSequenceNumber;
+ private long clientSequenceNumber;
+
+ private int warnings;
+ private boolean closed;
+
+ // These are only used during negotiation
+ private byte[] serverRandom;
+ private byte[] clientRandom;
+ private byte[] preMasterSecret;
+
+ // Buffers
+ private byte[] mac;
+
+ private byte[] pending = new byte[16384];
+ private int pendingStart;
+ private int pendingLength;
+
+ private byte[] sendRecordBuf = new byte[16384];
+
+ private int handshakeDataStart;
+ private int handshakeDataLength;
+ private byte[] readRecordBuf = new byte[16384+20]; // 20 == sizeof(sha1 hash)
+ private byte[] readRecordScratch = new byte[16384+20];
+
+ private ByteArrayOutputStream handshakesBuffer;
+
+ // End Buffers
+
+ // Static variables
+ private final static byte[] pad1 = new byte[48];
+ private final static byte[] pad2 = new byte[48];
+ private final static byte[] pad1_sha = new byte[40];
+ private final static byte[] pad2_sha = new byte[40];
+
+ static {
+ for(int i=0; i<pad1.length; i++) pad1[i] = (byte)0x36;
+ for(int i=0; i<pad2.length; i++) pad2[i] = (byte)0x5C;
+ for(int i=0; i<pad1_sha.length; i++) pad1_sha[i] = (byte)0x36;
+ for(int i=0; i<pad2_sha.length; i++) pad2_sha[i] = (byte)0x5C;
+ }
+
+ private final static Hashtable caKeys = new Hashtable();
+ private static VerifyCallback verifyCallback;
+
+ //
+ // Constructors
+ //
+ public SSL(String host) throws IOException { this(host,443); }
+ public SSL(String host, int port) throws IOException { this(host,port,true); }
+ public SSL(String host, int port, boolean negotiate) throws IOException { this(host,port,negotiate,null); }
+ public SSL(String host, int port, State state) throws IOException { this(host,port,true,state); }
+ public SSL(String host, int port, boolean negotiate, State state) throws IOException {
+ super(host,port);
+ hostname = host;
+ rawIS = new DataInputStream(new BufferedInputStream(super.getInputStream()));
+ rawOS = new DataOutputStream(new BufferedOutputStream(super.getOutputStream()));
+ sslIS = new SSLInputStream();
+ sslOS = new SSLOutputStream();
+ if(negotiate) negotiate(state);
+ }
+
+ public synchronized void setTLS(boolean b) { if(negotiated!=0) throw new IllegalStateException("already negotiated"); tls = b; }
+
+ public void negotiate() throws IOException { negotiate(null); }
+ public synchronized void negotiate(State state) throws IOException {
+ if(negotiated != 0) throw new IllegalStateException("already negotiated");
+
+ handshakesBuffer = new ByteArrayOutputStream();
+
+ try {
+ sendClientHello(state != null ? state.sessionID : null);
+ flush();
+ debug("sent ClientHello (" + (tls?"TLSv1.0":"SSLv3.0")+")");
+
+ receiveServerHello();
+ debug("got ServerHello (" + (tls?"TLSv1.0":"SSLv3.0")+")");
+
+ boolean resume =
+ state != null && sessionID.length == state.sessionID.length &&
+ eq(state.sessionID,0,sessionID,0,sessionID.length);
+
+ if(resume)
+ negotiateResume(state);
+ else
+ negotiateNew();
+
+ // we're done with these now
+ clientRandom = serverRandom = preMasterSecret = null;
+ handshakesBuffer = null;
+
+ log("Negotiation with " + hostname + " complete (" + (tls?"TLSv1.0":"SSLv3.0")+")");
+ } finally {
+ if((negotiated & 3) != 3) {
+ negotiated = 0;
+ try { super.close(); } catch(IOException e) { /* ignore */ }
+ closed = true;
+ }
+ }
+ }
+
+ private void negotiateResume(State state) throws IOException {
+ masterSecret = state.masterSecret;
+
+ initCrypto();
+ log("initializec crypto");
+
+ receiveChangeCipherSpec();
+ debug("Received ChangeCipherSpec");
+ negotiated |= 2;
+ receieveFinished();
+ debug("Received Finished");
+
+ sendChangeCipherSpec();
+ debug("Sent ChangeCipherSpec");
+ negotiated |= 1;
+ sendFinished();
+ debug("Sent Finished");
+ }
+
+ private void negotiateNew() throws IOException {
+ X509.Certificate[] certs = receiveServerCertificates();
+ debug("got Certificate");
+
+ boolean gotCertificateRequest = false;
+ OUTER: for(;;) {
+ byte[] buf = readHandshake();
+ switch(buf[0]) {
+ case 14: // ServerHelloDone
+ if(buf.length != 4) throw new Exn("ServerHelloDone contained trailing garbage");
+ debug("got ServerHelloDone");
+ break OUTER;
+ case 13: // CertificateRequest
+ debug("Got a CertificateRequest message but we don't suport client certificates");
+ gotCertificateRequest = true;
+ break;
+ default:
+ throw new Exn("unknown handshake type " + buf[0]);
+ }
+ }
+
+ if(gotCertificateRequest)
+ sendHandshake((byte)11,new byte[3]); // send empty cert list
+
+ try {
+ if(!hostname.equalsIgnoreCase(certs[0].getCN()))
+ throw new Exn("Certificate is for " + certs[0].getCN() + " not " + hostname);
+ verifyCerts(certs);
+ } catch(Exn e) {
+ if(verifyCallback == null) throw e;
+ synchronized(SSL.class) {
+ if(!verifyCallback.checkCerts(certs,hostname,e)) throw e;
+ }
+ }
+
+ computeMasterSecret();
+
+ sendClientKeyExchange(certs[0]);
+ debug("sent ClientKeyExchange");
+
+ initCrypto();
+
+ sendChangeCipherSpec();
+ debug("sent ChangeCipherSpec");
+ negotiated |= 1;
+ sendFinished();
+ debug("sent Finished");
+ flush();
+
+ receiveChangeCipherSpec();
+ debug("got ChangeCipherSpec");
+ negotiated |= 2;
+ receieveFinished();
+ debug("got Finished");
+ }
+
+ public State getSessionState() {
+ if((negotiated&3)!=3 || !closed || warnings != 0) return null;
+ return new State(sessionID,masterSecret);
+ }
+ public boolean isActive() { return !closed; }
+ public boolean isNegotiated() { return (negotiated&3) == 3; }
+
+ private void sendClientHello(byte[] sessionID) throws IOException {
+ if(sessionID != null && sessionID.length > 256) throw new IllegalArgumentException("sessionID");
+ // 2 = version, 32 = randomvalue, 1 = sessionID size, 2 = cipher list size, 4 = the two ciphers,
+ // 2 = compression length/no compression
+ int p = 0;
+ byte[] buf = new byte[2+32+1+(sessionID == null ? 0 : sessionID.length)+2+2+4];
+ buf[p++] = 0x03; // major version
+ buf[p++] = tls ? (byte)0x01 : (byte)0x00;
+
+ clientRandom = new byte[32];
+ int now = (int)(System.currentTimeMillis() / 1000L);
+ new Random().nextBytes(clientRandom);
+ clientRandom[0] = (byte)(now>>>24);
+ clientRandom[1] = (byte)(now>>>16);
+ clientRandom[2] = (byte)(now>>>8);
+ clientRandom[3] = (byte)(now>>>0);
+ System.arraycopy(clientRandom,0,buf,p,32);
+ p += 32;
+
+ buf[p++] = sessionID != null ? (byte)sessionID.length : 0;
+ if(sessionID != null && sessionID.length != 0) System.arraycopy(sessionID,0,buf,p,sessionID.length);
+ p += sessionID != null ? sessionID.length : 0;
+ buf[p++] = 0x00; // 4 bytes of ciphers
+ buf[p++] = 0x04;
+ buf[p++] = 0x00; // SSL_RSA_WITH_RC4_128_SHA
+ buf[p++] = 0x05;
+ buf[p++] = 0x00; // SSL_RSA_WITH_RC4_128_MD5
+ buf[p++] = 0x04;
+
+ buf[p++] = 0x01;
+ buf[p++] = 0x00;
+
+ sendHandshake((byte)1,buf);
+ flush();
+ }
+
+ private void receiveServerHello() throws IOException {
+ // ServerHello
+ byte[] buf = readHandshake();
+ if(buf[0] != 2) throw new Exn("expected a ServerHello message");
+
+ if(buf.length < 6 + 32 + 1) throw new Exn("ServerHello too small");
+ if(buf.length < 6 + 32 + 1 + buf[6+32] + 3) throw new Exn("ServerHello too small " + buf.length+" "+buf[6+32]);
+
+ if(buf[4] != 0x03 || !(buf[5]==0x00 || buf[5]==0x01)) throw new Exn("server wants to use version " + buf[4] + "." + buf[5]);
+ tls = buf[5] == 0x01;
+ int p = 6;
+ serverRandom = new byte[32];
+ System.arraycopy(buf,p,serverRandom,0,32);
+ p += 32;
+ sessionID = new byte[buf[p++]&0xff];
+ if(sessionID.length != 0) System.arraycopy(buf,p,sessionID,0,sessionID.length);
+ p += sessionID.length;
+ int cipher = ((buf[p]&0xff)<<8) | (buf[p+1]&0xff);
+ p += 2;
+ switch(cipher) {
+ case 0x0004: sha = false; debug("Using SSL_RSA_WITH_RC4_128_MD5"); break;
+ case 0x0005: sha = true; debug("Using SSL_RSA_WITH_RC4_128_SHA"); break;
+ default: throw new Exn("Unsupported cipher " + cipher);
+ }
+ mac = new byte[sha ? 20 : 16];
+ if(buf[p++] != 0x0) throw new Exn("unsupported compression " + buf[p-1]);
+ }
+
+ private X509.Certificate[] receiveServerCertificates() throws IOException {
+ byte[] buf = readHandshake();
+ if(buf[0] != 11) throw new Exn("expected a Certificate message");
+ if((((buf[4]&0xff)<<16)|((buf[5]&0xff)<<8)|((buf[6]&0xff)<<0)) != buf.length-7) throw new Exn("size mismatch in Certificate message");
+ int p = 7;
+ int count = 0;
+
+ for(int i=p;i<buf.length-3;i+=((buf[p+0]&0xff)<<16)|((buf[p+1]&0xff)<<8)|((buf[p+2]&0xff)<<0)) count++;
+ if(count == 0) throw new Exn("server didn't provide any certificates");
+ X509.Certificate[] certs = new X509.Certificate[count];
+ count = 0;
+ while(p < buf.length) {
+ int len = ((buf[p+0]&0xff)<<16)|((buf[p+1]&0xff)<<8)|((buf[p+2]&0xff)<<0);
+ p += 3;
+ if(p + len > buf.length) throw new Exn("Certificate message cut short");
+ certs[count++] = new X509.Certificate(new ByteArrayInputStream(buf,p,len));
+ p += len;
+ }
+ return certs;
+ }
+
+ private void sendClientKeyExchange(X509.Certificate serverCert) throws IOException {
+ byte[] encryptedPreMasterSecret;
+ RSA.PublicKey pks = serverCert.getRSAPublicKey();
+ PKCS1 pkcs1 = new PKCS1(new RSA(pks.modulus,pks.exponent,false),random);
+ encryptedPreMasterSecret = pkcs1.encode(preMasterSecret);
+ byte[] buf;
+ if(tls) {
+ buf = new byte[encryptedPreMasterSecret.length+2];
+ buf[0] = (byte) (encryptedPreMasterSecret.length>>>8);
+ buf[1] = (byte) (encryptedPreMasterSecret.length>>>0);
+ System.arraycopy(encryptedPreMasterSecret,0,buf,2,encryptedPreMasterSecret.length);
+ } else {
+ // ugh... netscape didn't send the length bytes and now every SSLv3 implementation
+ // must implement this bug
+ buf = encryptedPreMasterSecret;
+ }
+ sendHandshake((byte)16,buf);
+ }
+
+ private void sendChangeCipherSpec() throws IOException {
+ sendRecord((byte)20,new byte[] { 0x01 });
+ }
+
+ private void computeMasterSecret() {
+ preMasterSecret = new byte[48];
+ preMasterSecret[0] = 0x03; // version_high
+ preMasterSecret[1] = tls ? (byte) 0x01 : (byte) 0x00; // version_low
+ randomBytes(preMasterSecret,2,46);
+
+ if(tls) {
+ masterSecret = tlsPRF(48,preMasterSecret,getBytes("master secret"),concat(clientRandom,serverRandom));
+ } else {
+ masterSecret = concat(new byte[][] {
+ md5(new byte[][] { preMasterSecret,
+ sha1(new byte[][] { new byte[] { 0x41 }, preMasterSecret, clientRandom, serverRandom })}),
+ md5(new byte[][] { preMasterSecret,
+ sha1(new byte[][] { new byte[] { 0x42, 0x42 }, preMasterSecret, clientRandom, serverRandom })}),
+ md5(new byte[][] { preMasterSecret,
+ sha1(new byte[][] { new byte[] { 0x43, 0x43, 0x43 }, preMasterSecret, clientRandom, serverRandom })})
+ } );
+ }
+ }
+
+ public void initCrypto() {
+ byte[] keyMaterial;
+
+ if(tls) {
+ keyMaterial = tlsPRF(
+ (mac.length + 16 + 0)*2, // MAC len + key len + iv len
+ masterSecret,
+ getBytes("key expansion"),
+ concat(serverRandom,clientRandom)
+ );
+ } else {
+ keyMaterial = new byte[] { };
+ for(int i=0; keyMaterial.length < 72; i++) {
+ byte[] crap = new byte[i + 1];
+ for(int j=0; j<crap.length; j++) crap[j] = (byte)(((byte)0x41) + ((byte)i));
+ keyMaterial = concat(new byte[][] { keyMaterial,
+ md5(new byte[][] { masterSecret,
+ sha1(new byte[][] { crap, masterSecret, serverRandom, clientRandom }) }) });
+ }
+ }
+
+ byte[] clientWriteMACSecret = new byte[mac.length];
+ byte[] serverWriteMACSecret = new byte[mac.length];
+ byte[] clientWriteKey = new byte[16];
+ byte[] serverWriteKey = new byte[16];
+
+ int p = 0;
+ System.arraycopy(keyMaterial, p, clientWriteMACSecret, 0, mac.length); p += mac.length;
+ System.arraycopy(keyMaterial, p, serverWriteMACSecret, 0, mac.length); p += mac.length;
+ System.arraycopy(keyMaterial, p, clientWriteKey, 0, 16); p += 16;
+ System.arraycopy(keyMaterial, p, serverWriteKey, 0, 16); p += 16;
+
+ Digest inner;
+
+ writeRC4 = new RC4(clientWriteKey);
+ inner = sha ? (Digest)new SHA1() : (Digest)new MD5();
+ clientWriteMACDigest = tls ? (Digest) new HMAC(inner,clientWriteMACSecret) : (Digest)new SSLv3HMAC(inner,clientWriteMACSecret);
+
+ readRC4 = new RC4(serverWriteKey);
+ inner = sha ? (Digest)new SHA1() : (Digest)new MD5();
+ serverWriteMACDigest = tls ? (Digest)new HMAC(inner,serverWriteMACSecret) : (Digest)new SSLv3HMAC(inner,serverWriteMACSecret);
+ }
+
+ private void sendFinished() throws IOException {
+ byte[] handshakes = handshakesBuffer.toByteArray();
+ if(tls) {
+ sendHandshake((byte)20, tlsPRF(
+ 12,
+ masterSecret,
+ getBytes("client finished"),
+ concat(md5(handshakes),sha1(handshakes))));
+
+ } else {
+ sendHandshake((byte)20, concat(new byte[][] {
+ md5(new byte[][] { masterSecret, pad2,
+ md5(new byte[][] { handshakes, new byte[] { (byte)0x43, (byte)0x4C, (byte)0x4E, (byte)0x54 },
+ masterSecret, pad1 }) }),
+ sha1(new byte[][] { masterSecret, pad2_sha,
+ sha1(new byte[][] { handshakes, new byte[] { (byte)0x43, (byte)0x4C, (byte)0x4E, (byte)0x54 },
+ masterSecret, pad1_sha } ) })
+ }));
+ }
+ }
+
+ private void receiveChangeCipherSpec() throws IOException {
+ int size = readRecord((byte)20);
+ if(size == -1) throw new Exn("got eof when expecting a ChangeCipherSpec message");
+ if(size != 1 || readRecordBuf[0] != 0x01) throw new Exn("Invalid ChangeCipherSpec message");
+ }
+
+ private void receieveFinished() throws IOException {
+ byte[] handshakes = handshakesBuffer.toByteArray();
+ byte[] buf = readHandshake();
+ if(buf[0] != 20) throw new Exn("expected a Finished message");
+ byte[] expected;
+
+ if(tls) {
+ if(buf.length != 4 + 12) throw new Exn("Finished message too short");
+ expected = tlsPRF(
+ 12,masterSecret,
+ getBytes("server finished"),
+ concat(md5(handshakes),sha1(handshakes)));
+ } else {
+ if(buf.length != 4 + 16 +20) throw new Exn("Finished message too short");
+ expected = concat(new byte[][] {
+ md5(new byte[][] { masterSecret, pad2,
+ md5(new byte[][] { handshakes, new byte[] { (byte)0x53, (byte)0x52, (byte)0x56, (byte)0x52 },
+ masterSecret, pad1 }) }),
+ sha1(new byte[][] { masterSecret, pad2_sha,
+ sha1(new byte[][] { handshakes, new byte[] { (byte)0x53, (byte)0x52, (byte)0x56, (byte)0x52 },
+ masterSecret, pad1_sha } ) } ) } );
+ }
+ if(!eq(expected,0,buf,4,expected.length)) throw new Exn("server finished message mismatch");
+ }
+
+ private void flush() throws IOException { rawOS.flush(); }
+
+ private void sendHandshake(byte type, byte[] payload) throws IOException {
+ if(payload.length > (1<<24)) throw new IllegalArgumentException("payload.length");
+ byte[] buf = new byte[4+payload.length];
+ buf[0] = type;
+ buf[1] = (byte)(payload.length>>>16);
+ buf[2] = (byte)(payload.length>>>8);
+ buf[3] = (byte)(payload.length>>>0);
+ System.arraycopy(payload,0,buf,4,payload.length);
+ handshakesBuffer.write(buf);
+ sendRecord((byte)22,buf);
+ }
+
+ private void sendRecord(byte proto, byte[] buf) throws IOException { sendRecord(proto,buf,0,buf.length); }
+ private void sendRecord(byte proto, byte[] payload, int off, int totalLen) throws IOException {
+ int macLength = (negotiated & 1) != 0 ? mac.length : 0;
+ while(totalLen > 0) {
+ int len = min(totalLen,16384-macLength);
+ rawOS.writeByte(proto);
+ rawOS.writeShort(tls ? 0x0301 : 0x0300);
+ if((negotiated & 1) != 0) {
+ computeMAC(proto,payload,off,len,clientWriteMACDigest,clientSequenceNumber);
+ // FEATURE: Encode in place
+ writeRC4.process(payload,off,sendRecordBuf,0,len);
+ writeRC4.process(mac,0,sendRecordBuf,len,macLength);
+ rawOS.writeShort(len + macLength);
+ rawOS.write(sendRecordBuf,0, len +macLength);
+ clientSequenceNumber++;
+ } else {
+ rawOS.writeShort(len);
+ rawOS.write(payload,off,len);
+ }
+ totalLen -= len;
+ off += len;
+ }
+ }
+
+ private byte[] readHandshake() throws IOException {
+ if(handshakeDataLength == 0) {
+ handshakeDataStart = 0;
+ handshakeDataLength = readRecord((byte)22);
+ if(handshakeDataLength == -1) throw new Exn("got eof when expecting a handshake packet");
+ }
+ byte[] buf = readRecordBuf;
+ int len = ((buf[handshakeDataStart+1]&0xff)<<16)|((buf[handshakeDataStart+2]&0xff)<<8)|((buf[handshakeDataStart+3]&0xff)<<0);
+ // Handshake messages can theoretically span multiple records, but in practice this does not occur
+ if(len > handshakeDataLength) {
+ sendAlert(true,10); // 10 == unexpected message
+ throw new Exn("handshake message size too large " + len + " vs " + (handshakeDataLength-handshakeDataStart));
+ }
+ byte[] ret = new byte[4+len];
+ System.arraycopy(buf,handshakeDataStart,ret,0,ret.length);
+ handshakeDataLength -= ret.length;
+ handshakeDataStart += ret.length;
+ handshakesBuffer.write(ret);
+ return ret;
+ }
+
+ private int readRecord(byte reqProto) throws IOException {
+ int macLength = (negotiated & 2) != 0 ? mac.length : 0;
+ for(;;) {
+ byte proto;
+ int version, len;
+
+ try {
+ proto = rawIS.readByte();
+ } catch(EOFException e) {
+ // this may or may not be an error. it is up to the application protocol
+ closed = true;
+ super.close();
+ throw new PrematureCloseExn();
+ }
+ try {
+ version = rawIS.readShort();
+ if(version != 0x0300 && version != 0x0301) throw new Exn("invalid version ");
+ len = rawIS.readShort();
+ if(len <= 0 || len > 16384+((negotiated&2)!=0 ? macLength : 0)) throw new Exn("invalid length " + len);
+ rawIS.readFully((negotiated&2)!=0 ? readRecordScratch : readRecordBuf,0,len);
+ } catch(EOFException e) {
+ // an EOF here is always an error (we don't pass the EOF back on to the app
+ // because it isn't a "legitimate" eof)
+ throw new Exn("Hit EOF too early");
+ }
+
+ if((negotiated & 2) != 0) {
+ if(len < macLength) throw new Exn("packet size < macLength");
+ // FEATURE: Decode in place
+ readRC4.process(readRecordScratch,0,readRecordBuf,0,len);
+ computeMAC(proto,readRecordBuf,0,len-macLength,serverWriteMACDigest,serverSequenceNumber);
+ for(int i=0;i<macLength;i++)
+ if(mac[i] != readRecordBuf[len-macLength+i])
+ throw new Exn("mac mismatch");
+ len -= macLength;
+ serverSequenceNumber++;
+ }
+
+ if(proto == reqProto) return len;
+
+ switch(proto) {
+ case 21: { // ALERT
+ if(len != 2) throw new Exn("invalid lengh for alert");
+ int level = readRecordBuf[0];
+ int desc = readRecordBuf[1];
+ if(level == 1) {
+ if(desc == 0) { // CloseNotify
+ debug("Server requested connection closure");
+ try {
+ sendCloseNotify();
+ } catch(SocketException e) { /* incomplete close, thats ok */ }
+ closed = true;
+ super.close();
+ return -1;
+ } else {
+ warnings++;
+ log("SSL ALERT WARNING: desc: " + desc);
+ }
+ } else if(level == 2) {
+ throw new Exn("SSL ALERT FATAL: desc: " +desc);
+ } else {
+ throw new Exn("invalid alert level");
+ }
+ break;
+ }
+ case 22: { // Handshake
+ int type = readRecordBuf[0];
+ int hslen = ((readRecordBuf[1]&0xff)<<16)|((readRecordBuf[2]&0xff)<<8)|((readRecordBuf[3]&0xff)<<0);
+ if(hslen > len - 4) throw new Exn("Multiple sequential handshake messages received after negotiation");
+ if(type == 0) { // HellloRequest
+ if(tls) sendAlert(false,100); // politely refuse, 100 == NoRegnegotiation
+ } else {
+ throw new Exn("Unexpected Handshake type: " + type);
+ }
+ }
+ default: throw new Exn("Unexpected protocol: " + proto);
+ }
+ }
+ }
+
+ private static void longToBytes(long l, byte[] buf, int off) {
+ for(int i=0;i<8;i++) buf[off+i] = (byte)(l>>>(8*(7-i)));
+ }
+ private void computeMAC(byte proto, byte[] payload, int off, int len, Digest digest, long sequenceNumber) {
+ if(tls) {
+ longToBytes(sequenceNumber,mac,0);
+ mac[8] = proto;
+ mac[9] = 0x03; // version
+ mac[10] = 0x01;
+ mac[11] = (byte)(len>>>8);
+ mac[12] = (byte)(len>>>0);
+
+ digest.update(mac,0,13);
+ digest.update(payload,off,len);
+ digest.doFinal(mac,0);
+ } else {
+ longToBytes(sequenceNumber, mac, 0);
+ mac[8] = proto;
+ mac[9] = (byte)(len>>>8);
+ mac[10] = (byte)(len>>>0);
+
+ digest.update(mac, 0, 11);
+ digest.update(payload, off, len);
+ digest.doFinal(mac, 0);
+ }
+ }
+
+ private void sendCloseNotify() throws IOException { sendRecord((byte)21, new byte[] { 0x01, 0x00 }); }
+ private void sendAlert(boolean fatal, int message) throws IOException {
+ byte[] buf = new byte[] { fatal ? (byte)2 :(byte)1, (byte)message };
+ sendRecord((byte)21,buf);
+ flush();
+ }
+
+ //
+ // Hash functions
+ //
+
+ // Shared digest objects
+ private MD5 masterMD5 = new MD5();
+ private SHA1 masterSHA1 = new SHA1();
+
+ private byte[] md5(byte[] in) { return md5( new byte[][] { in }); }
+ private byte[] md5(byte[][] inputs) {
+ masterMD5.reset();
+ for(int i=0; i<inputs.length; i++) masterMD5.update(inputs[i], 0, inputs[i].length);
+ byte[] ret = new byte[masterMD5.getDigestSize()];
+ masterMD5.doFinal(ret, 0);
+ return ret;
+ }
+
+ private byte[] sha1(byte[] in) { return sha1(new byte[][] { in }); }
+ private byte[] sha1(byte[][] inputs) {
+ masterSHA1.reset();
+ for(int i=0; i<inputs.length; i++) masterSHA1.update(inputs[i], 0, inputs[i].length);
+ byte[] ret = new byte[masterSHA1.getDigestSize()];
+ masterSHA1.doFinal(ret, 0);
+ return ret;
+ }
+
+ /* RFC-2246
+ PRF(secret, label, seed) = P_MD5(S1, label + seed) XOR P_SHA-1(S2, label + seed);
+ L_S = length in bytes of secret;
+ L_S1 = L_S2 = ceil(L_S / 2);
+
+ The secret is partitioned into two halves (with the possibility of
+ one shared byte) as described above, S1 taking the first L_S1 bytes
+ and S2 the last L_S2 bytes.
+
+ P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) +
+ HMAC_hash(secret, A(2) + seed) +
+ HMAC_hash(secret, A(3) + seed) + ...
+
+ A(0) = seed
+ A(i) = HMAC_hash(secret, A(i-1))
+ */
+ private byte[] tlsPRF(int size,byte[] secret, byte[] label, byte[] seed) {
+ if(size > 112) throw new IllegalArgumentException("size > 112");
+ seed = concat(label,seed);
+
+ int half_length = (secret.length + 1) / 2;
+ byte[] s1 = new byte[half_length];
+ System.arraycopy(secret,0,s1,0,half_length);
+ byte[] s2 = new byte[half_length];
+ System.arraycopy(secret,secret.length - half_length, s2, 0, half_length);
+
+ Digest hmac_md5 = new HMAC(new MD5(),s1);
+ Digest hmac_sha = new HMAC(new SHA1(),s2);
+
+ byte[] md5out = new byte[112];
+ byte[] shaout = new byte[120];
+ byte[] digest = new byte[20];
+ int n;
+
+ n = 0;
+ hmac_md5.update(seed,0,seed.length);
+ hmac_md5.doFinal(digest,0);
+
+ // digest == md5_a_1
+ while(n < size) {
+ hmac_md5.update(digest,0,16);
+ hmac_md5.update(seed,0,seed.length);
+ hmac_md5.doFinal(md5out,n);
+ hmac_md5.update(digest,0,16);
+ hmac_md5.doFinal(digest,0);
+ n += 16;
+ }
+
+ n = 0;
+ hmac_sha.update(seed,0,seed.length);
+ hmac_sha.doFinal(digest,0);
+
+ while(n < size) {
+ hmac_sha.update(digest,0,20);
+ hmac_sha.update(seed,0,seed.length);
+ hmac_sha.doFinal(shaout,n);
+ hmac_sha.update(digest,0,20);
+ hmac_sha.doFinal(digest,0);
+ n += 20;
+ }
+
+ byte[] ret = new byte[size];
+ for(int i=0;i<size;i++) ret[i] = (byte)(md5out[i] ^ shaout[i]);
+ return ret;
+ }
+
+ public static class SSLv3HMAC extends Digest {
+ private final Digest h;
+ private final byte[] digest;
+ private final byte[] key;
+ private final int padSize;
+
+ public int getDigestSize() { return h.getDigestSize(); }
+
+ public SSLv3HMAC(Digest h, byte[] key) {
+ this.h = h;
+ this.key = key;
+ switch(h.getDigestSize()) {
+ case 16: padSize = 48; break;
+ case 20: padSize = 40; break;
+ default: throw new IllegalArgumentException("unsupported digest size");
+ }
+ digest = new byte[h.getDigestSize()];
+ reset();
+ }
+ public void reset() {
+ h.reset();
+ h.update(key,0,key.length);
+ h.update(pad1,0,padSize);
+ }
+ public void update(byte[] b, int off, int len) { h.update(b,off,len); }
+ public void doFinal(byte[] out, int off){
+ h.doFinal(digest,0);
+ h.update(key,0,key.length);
+ h.update(pad2,0,padSize);
+ h.update(digest,0,digest.length);
+ h.doFinal(out,off);
+ reset();
+ }
+ protected void processWord(byte[] in, int inOff) {}
+ protected void processLength(long bitLength) {}
+ protected void processBlock() {}
+ }
+
+ //
+ // Static Methods
+ //
+
+ private static SecureRandom random = new SecureRandom();
+ public static synchronized void randomBytes(byte[] buf, int off, int len) {
+ byte[] bytes = new byte[len];
+ random.nextBytes(bytes);
+ System.arraycopy(bytes,0,buf,off,len);
+ }
+
+ public static byte[] concat(byte[] a, byte[] b) { return concat(new byte[][] { a, b }); }
+ public static byte[] concat(byte[] a, byte[] b, byte[] c) { return concat(new byte[][] { a, b, c }); }
+ public static byte[] concat(byte[][] inputs) {
+ int total = 0;
+ for(int i=0; i<inputs.length; i++) total += inputs[i].length;
+ byte[] ret = new byte[total];
+ for(int i=0,pos=0; i<inputs.length;pos+=inputs[i].length,i++)
+ System.arraycopy(inputs[i], 0, ret, pos, inputs[i].length);
+ return ret;
+ }
+
+ public static byte[] getBytes(String s) {
+ try {
+ return s.getBytes("US-ASCII");
+ } catch (UnsupportedEncodingException e) {
+ return null; // will never happen
+ }
+ }
+
+ public static boolean eq(byte[] a, int aoff, byte[] b, int boff, int len){
+ for(int i=0;i<len;i++) if(a[aoff+i] != b[boff+i]) return false;
+ return true;
+ }
+
+ //
+ // InputStream/OutputStream/Socket interfaces
+ //
+ public OutputStream getOutputStream() { return sslOS; }
+ public InputStream getInputStream() { return sslIS; }
+ public synchronized void close() throws IOException {
+ if(!closed) {
+ if(negotiated != 0) {
+ sendCloseNotify();
+ flush();
+ // don't bother sending a close_notify back to the server
+ // this is an incomplete close which is allowed by the spec
+ }
+ super.close();
+ closed = true;
+ }
+ }
+
+ private int read(byte[] buf, int off, int len) throws IOException {
+ if(pendingLength == 0) {
+ if(closed) return -1;
+ int readLen = readRecord((byte)23);
+ if(readLen == -1) return -1; // EOF
+ len = min(len,readLen);
+ System.arraycopy(readRecordBuf,0,buf,off,len);
+ if(readLen > len) System.arraycopy(readRecordBuf,len,pending,0,readLen-len);
+ pendingStart = 0;
+ pendingLength = readLen - len;
+ return len;
+ } else {
+ len = min(len,pendingLength);
+ System.arraycopy(pending,pendingStart,buf,off,len);
+ pendingLength -= len;
+ pendingStart += len;
+ return len;
+ }
+ }
+
+ private void write(byte[] buf, int off, int len) throws IOException {
+ if(closed) throw new SocketException("Socket closed");
+ sendRecord((byte)23,buf,off,len);
+ flush();
+ }
+
+ private class SSLInputStream extends InputStream {
+ public int available() throws IOException {
+ synchronized(SSL.this) {
+ return negotiated != 0 ? pendingLength : rawIS.available();
+ }
+ }
+ public int read() throws IOException {
+ synchronized(SSL.this) {
+ if(negotiated==0) return rawIS.read();
+ if(pendingLength > 0) {
+ pendingLength--;
+ return pending[pendingStart++];
+ } else {
+ byte[] buf = new byte[1];
+ int n = read(buf);
+ return n == -1 ? -1 : buf[0]&0xff;
+ }
+ }
+ }
+ public int read(byte[] buf, int off, int len) throws IOException {
+ synchronized(SSL.this) {
+ return negotiated!=0 ? SSL.this.read(buf,off,len) : rawIS.read(buf,off,len);
+ }
+ }
+ public long skip(long n) throws IOException {
+ synchronized(SSL.this) {
+ if(negotiated==0) return rawIS.skip(n);
+ if(pendingLength > 0) {
+ n = min((int)n,pendingLength);
+ pendingLength -= n;
+ pendingStart += n;
+ return n;
+ }
+ return super.skip(n);
+ }
+ }
+ }
+
+ private class SSLOutputStream extends OutputStream {
+ public void flush() throws IOException { rawOS.flush(); }
+ public void write(int b) throws IOException { write(new byte[] { (byte)b }); }
+ public void write(byte[] buf, int off, int len) throws IOException {
+ synchronized(SSL.this) {
+ if(negotiated!=0)
+ SSL.this.write(buf,off,len);
+ else
+ rawOS.write(buf,off,len);
+ }
+ }
+ }
+
+ public static class Exn extends IOException { public Exn(String s) { super(s); } }
+ public static class PrematureCloseExn extends Exn {
+ public PrematureCloseExn() { super("Connection was closed by the remote WITHOUT a close_noify"); }
+ }
+
+ public static boolean debugOn = false;
+ private static void debug(Object o) { if(debugOn) System.err.println("[BriSSL-Debug] " + o.toString()); }
+ private static void log(Object o) { System.err.println("[BriSSL] " + o.toString()); }
+
+ private static void verifyCerts(X509.Certificate[] certs) throws DER.Exception, Exn {
+ try {
+ verifyCerts_(certs);
+ } catch(RuntimeException e) {
+ e.printStackTrace();
+ throw new Exn("Error while verifying certificates: " + e);
+ }
+ }
+
+ private static void verifyCerts_(X509.Certificate[] certs) throws DER.Exception, Exn {
+ boolean ignoreLast = false;
+ for(int i=0;i<certs.length;i++) {
+ debug("Cert " + i + ": " + certs[i].subject + " ok");
+ if(!certs[i].isValid())
+ throw new Exn("Certificate " + i + " in certificate chain is not valid (" + certs[i].startDate + " - " + certs[i].endDate + ")");
+ if(i != 0) {
+ X509.Certificate.BC bc = certs[i].basicContraints;
+ if(bc == null) {
+ if(i == certs.length - 1) {
+ ignoreLast = true;
+ break;
+ }
+ throw new Exn("CA-cert lacks Basic Constraints");
+ } else {
+ if(!bc.isCA) throw new Exn("non-CA certificate used for signing");
+ if(bc.pathLenConstraint != null && bc.pathLenConstraint.longValue() < i-1) throw new Exn("CA cert can't be used this deep");
+ }
+ }
+ if(i != certs.length - 1) {
+ if(!certs[i].issuer.equals(certs[i+1].subject))
+ throw new Exn("Issuer for certificate " + i + " does not match next in chain");
+ if(!certs[i].isSignedBy(certs[i+1]))
+ throw new Exn("Certificate " + i + " in chain is not signed by the next certificate");
+ }
+ }
+
+ X509.Certificate cert = certs[ignoreLast ? certs.length - 2 : certs.length-1];
+
+ RSA.PublicKey pks = (RSA.PublicKey) caKeys.get(cert.issuer);
+ if(pks == null) throw new Exn("Certificate is signed by an unknown CA (" + cert.issuer + ")");
+ if(!cert.isSignedWith(pks)) throw new Exn("Certificate is not signed by its CA");
+ log("" + cert.subject + " is signed by " + cert.issuer);
+ }
+
+ public static void addCACert(byte[] b) throws IOException { addCACert(new ByteArrayInputStream(b)); }
+ public static void addCACert(InputStream is) throws IOException { addCACert(new X509.Certificate(is)); }
+ public static void addCACert(X509.Certificate cert) throws DER.Exception { addCAKey(cert.subject,cert.getRSAPublicKey()); }
+ public static void addCAKey(X509.Name subject, RSA.PublicKey pks) {
+ synchronized(caKeys) {
+ if(caKeys.get(subject) != null)
+ throw new IllegalArgumentException(subject.toString() + " already exists!");
+ caKeys.put(subject,pks);
+ }
+ }
+
+ static {
+ try {
+ // This will force a <clinit> which'll load the certs
+ Class.forName("org.ibex.net.ssl.RootCerts");
+ log("Loaded root keys from org.ibex.net.ssl.RootCerts");
+ } catch(ClassNotFoundException e) {
+ InputStream is = SSL.class.getClassLoader().getResourceAsStream("org.ibex/net/ssl/rootcerts.dat");
+ if(is != null) {
+ try {
+ addCompactCAKeys(is);
+ log("Loaded root certs from rootcerts.dat");
+ } catch(IOException e2) {
+ log("Error loading certs from rootcerts.dat: " + e2.getMessage());
+ }
+ }
+ }
+ }
+
+ public static int addCompactCAKeys(InputStream is) throws IOException {
+ synchronized(caKeys) {
+ try {
+ Vector seq = (Vector) new DER.InputStream(is).readObject();
+ for(Enumeration e = seq.elements(); e.hasMoreElements();) {
+ Vector seq2 = (Vector) e.nextElement();
+ X509.Name subject = new X509.Name(seq2.elementAt(0));
+ RSA.PublicKey pks = new RSA.PublicKey(seq2.elementAt(1));
+ addCAKey(subject,pks);
+ }
+ return seq.size();
+ } catch(RuntimeException e) {
+ e.printStackTrace();
+ throw new IOException("error while reading stream: " + e);
+ }
+ }
+ }
+
+ public static synchronized void setVerifyCallback(VerifyCallback cb) { verifyCallback = cb; }
+
+ // State Info
+ public static class State {
+ byte[] sessionID;
+ byte[] masterSecret;
+ State(byte[] sessionID, byte[] masterSecret) {
+ this.sessionID = sessionID;
+ this.masterSecret = masterSecret;
+ }
+ }
+
+ public interface VerifyCallback {
+ public boolean checkCerts(X509.Certificate[] certs, String hostname, Exn exn);
+ }
+
+ // Helper methods
+ private static final int min(int a, int b) { return a < b ? a : b; }
+}
--- /dev/null
+package org.ibex.net.ssl;
+
+import java.io.*;
+//import org.bouncycastle.asn1.*;
+//import org.bouncycastle.asn1.x509.*;
+
+public class GenCompactCAList {
+ /*
+ public static void main(String[] args) throws Exception {
+ if(args.length < 2) throw new Exception("Usage: GenCAList format file(s)");
+ String format = args[0];
+ DER.EncodableVector vec = new DEREncodableVector();
+ for(int i=1;i<args.length;i++) {
+ X509.CertificateStructure x509 = new X509.CertificateStructure((ASN1Sequence) new ASN1InputStream(new FileInputStream(args[i])).readObject());
+ X509.Name subject = x509.getSubject();
+ SubjectPublicKeyInfo pki = x509.getSubjectPublicKeyInfo();
+ RSA.PublicKeyStructure rsa = new RSA.PublicKeyStructure((ASN1Sequence) pki.getPublicKey());
+ DER.EncodableVector vec2 = new DEREncodableVector();
+ vec2.add(subject);
+ vec2.add(rsa);
+ vec.add(new DERSequence(vec2));
+ }
+ if(format.equals("binary")) {
+ DER.OutputStream dos = new DEROutputStream(System.out);
+ dos.writeObject(new DERSequence(vec));
+ dos.close();
+ } else if(format.equals("class")){
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ DER.OutputStream dos = new DEROutputStream(baos);
+ dos.writeObject(new DERSequence(vec));
+ dos.close();
+ baos.close();
+ byte[] buf = baos.toByteArray();
+ StringBuffer sb = new StringBuffer();
+ for(int i=0;i<buf.length;i+=7) {
+ long l = 0;
+ for(int j=0;j<7;j++) {
+ l <<= 8;
+ byte b = (i+j < buf.length) ? buf[i+j] : -1;
+ l |= (b & 0xffL);
+ }
+ for(int j=0;j<8;j++) {
+ char c = (char) ((l>>>(7*(7-j)))&0x7f);
+ if(c=='\n') sb.append("\\n");
+ else if(c=='\r') sb.append("\\r");
+ else if(c=='\\') sb.append("\\\\");
+ else if(c=='"') sb.append("\\\"");
+ else if(c >= 32 && c <= 126) sb.append(c);
+ else sb.append("\\" + toOctal3(c));
+ }
+ }
+ System.out.println("package org.ibex.net.ssl;");
+ System.out.println("public final class RootCerts {");
+ System.out.println(" private final static String DATA = \"" + sb.toString() + "\";");
+ System.out.print(
+ " static {\n" +
+ " try {\n" +
+ " org.ibex.net.SSL.addCompactCAKeys(new java.io.ByteArrayInputStream(unpack(DATA)));\n" +
+ " } catch(Exception e) {\n" +
+ " System.err.println(\"Error loading root CA keys: \" + e.getMessage());\n" +
+ " }\n" +
+ " }\n");
+ System.out.println(" public static void load() { }"); // force clinit
+ System.out.print(
+ " private static byte[] unpack(String s) {\n" +
+ " int len = s.length();\n" +
+ " if(len % 8 != 0) throw new IllegalArgumentException(\"not a multiple of 8\");\n" +
+ " byte[] ret = new byte[(len / 8) * 7];\n" +
+ " for(int i=0; i<len; i += 8) {\n" +
+ " long l = 0;\n" +
+ " for(int j=0;j<8;j++) {\n" +
+ " l <<= 7;\n" +
+ " l |= (s.charAt(i + j) & 0x7fL);\n" +
+ " }\n" +
+ " int base = (i / 8) * 7;\n" +
+ " for(int j=6; j>=0; j--) {\n" +
+ " ret[base + j] = (byte)(l & 0xff);\n" +
+ " l >>>= 8;\n" +
+ " }\n" +
+ " }\n" +
+ " return ret;\n" +
+ " }");
+ System.out.println("}");
+ } else {
+ throw new Error("unknown format");
+ }
+ }
+
+ private final static String toOctal3(int n) {
+ char[] buf = new char[3];
+ for(int i=2;i>=0;i--) {
+ buf[i] = (char) ('0' + (n & 7));
+ n >>= 3;
+ }
+ return new String(buf);
+ }
+ */
+}
--- /dev/null
+package org.ibex.net.ssl;
+public final class RootCerts {
+ private final static String DATA = "\030 Oi\031B\004\001M\014\020\030ID\0260\004A@5(\020\014\023\001\025*3\010,`\011\003\000jP &\002\"\020f\021\031@\"\006\001U @8L\024W0\\m\006K9Nt7[F\0219@*\006\001U @PL\034A!\020%d*\r\036M\026\010\011\024r\014\\1\014L\002p0\r*\004\001Db\004\n\011\002.\"Piti\001$o7]\004\004\032\004b$\030\010@`I*\014HC=aP\010$\002\026\nX,Fk%\\@2\032,w\033%Nt9\035.7!9Fo6L\020 \010(\005\002\000@ \013\016L#`<U(08!\031K\002P@\016\0206\006F\036y\022;UX\rS\006V7Sv\007\034C3@1\"\r#_<f4\024,eA+\026)a\014`(\0034D$`\033\005 *J%C%\035V\032[~p6(t\021NIq>4\nHEq?\037L\014\027H{ajbF\036G^\013I0h_F\037\011@A&:@*zgGl\017=5x=q(\030:BLZ\016T[\032}4\"K{\003\031^\004\nh~yVzLF(,r\036\011\002 hJ\031\035:rYad\025\ngPV/\000s*_}Z}VBYv9\026\034G\013\007:')i^nsg-b\003TN\011!32\022*e6F1\033g\004UF;3K_K\026[\010>\005f\011W\014)&\nZ\002S\017\"e,m\037\014ogh\000B-Jt\024\026:2T>%%'o~x o\027W\011#i;H/\037y1P\011c\"gT\0241!\001\001\001\000`\020\000\004a\002\000_f\006yD\0260\004A@5(\020\014\023\001\024hS\010P`\022\003\000jP (&\013 Y\014E#Ijs:\010\010\024\021DL0\022\001@5(\020\026\023\016P,F\"Qdu9]\004\004+ahe9\033L\026a\001(T(\010\011f+Qno9\032f\022\021@@\006\001U @\030L2A2\031\nG\023Uft\020\021/\007#\025dn0[\004\004\032\004@R7[nC\004\010\002\n\001 @\020\010\002ow\r\014|o\020\000\010-\034x\011e_4?<6\003y[/hG6g7S1\011N/$\024S\017Y\034~zJ^$}P\030kG\017gy-U\002k-\027\024e\013(\005A\022zmKR_mc\025?\033N\005Qqz\"AV\\\nl?A\036?t\014Sg&+\021\020*:8ex=q\035M\020\007@u1C*/\005\021yt\036Bj(7\032yR:^\005YiN\031$qc3(\030\001,8N:8\003a@*G&Pi\023\006\022\nZ2`O\021jg$|\0231_g'|\026K>wW!5m4'\023\017-w\033(\025{I4q\004\rv7K\026HYP%\006\1778\000^\ra$N-V@prmE\025\004.\021:*>mvM6\023],fDhK>$W]!@\004_S\006ri5\026\0041\r^N3GUNUOW\032)kQVpQ-K6iPMq-Jp{}{}\025jO*4-\011` \030\004\000\001\030 @\027)AJ1\005L\001\0200\r*\004\003\004`%\032\024b\024\030\004@`\032T\010\n\011Bh\026#\021(r:\\nB\002\005\0041\016L\00300\r*\004\005DbD\013\021HT9\035.7!\001(T(\010\011f+Qno9\032f\022\011@>\006\001U @\030L0A2\031\nG\023Uft\020\020mF\013Mf \030H\0104\011\001$o7]\006\010\020\004\024\002A\000 \020\004Z-T\020R,\016\023/PA\003C\033l'\0038\023\021s8\023.\037wV'\004!&:{j\006-ZtPAm6)\013\016\\x=Hh\006bo\000Z(\ry\002eJ\"\nw\006\021\001^uSm\037xZV`E9n\031\032:\025\027\004\03704<`\004o)vF\035S\1771N+GJ{^lVbm5:\027%R:\036CF7IH~pA$S\026\0136\0320\004#n\023}\031\020W\014~\004]b-L\\R]\021yE;\021y`\001D.=1g_RK_5\026rb\0252H\037#+\031S^oK\036\026upa[\026\011\002-_,j54$\0310\005B.!\036]\004\022\033\024h+]^\013\032\036[Bv\034fTDL:\030tW[TIU\0173\033i\016\013I]\0101L:HpKw/DM\031\\1aWC\005xcG4*h\016.,|3d\\7Zp$\030l,5lI~cx\0119\025\0318??&@@0\010\000\0020A\000.C\003\020b\013\030\002 `\032T\010\006\011@J4)D(0\011\001@5(\020\024\023\005P,F\"Qdu9]\004\004\n\010b\035\030\006``\032T\010\013\011E\010\026#\021(r:\\nB\002Q(P\020\023LW#]^r5L$\003\000x\014\003*A\0001\030]\002d2\025\016'+Mh (\035,&c%F !P$\005\023=^t\030 @\020P\n\004\001\000@\035\021QB\037\003D\005\030\022\006`y\033GFo`\033RwZ4thj/b\035B\006\0042\005\r\024^f*\020\n^Vl>J+;Sr\033;h9eh7\026\177I}y.adf\014x9xq;\024h\017`CE\0223\002\020a\1776&9\036Xp\014\\\016\027|uc\002aAz\016=\007L!v\031\027@~_,'>M\010\036\023}GtZ\022g7\0346'\021{\003*QI\034`; \001ScyE\011nvG8\011g]fD2Bax\010|_cCgn\007\034\177J\031\024\\\026[\004\027fH0\006[\010Kzllj{#\177n\037>(&jtwVw\020\000F\036O\007k\0253y;+QH\010Y\027.8dR?\010lo\011\004\020@R-D=wFB\007vjR\022\r\001@9O@>,\017sgI\010y7 \016\\Q\013k2e\r\024\005k\001UZ.\027'h\020#(uL Y4Q\034X\020cS}\003\003z\002\001@ \000\011B\004\001;L\014s\010,`\011\003\000jP \030&\002)Q&\021!@$\006\001U @PL\026A2\031\nG\023Uft\020\020(#\010t`\033\003\000jP ,&\024 Y\014E#Ijs:\010\nE\"@@N2]\016v{IV1\021L\004\0200\r*\004\001Dc$\013\021HT9\035.7!\001\"u0[\r\0263%Jd\020\020h\022\002I^o:\014\020 \010(\005\002\000@ \016 z5~n\002+(=\022>G_\004+z|\020i[1\017\017\027E_R0Z{\001Aa+\010\026\177x\035G\017.\025u\010[]Tx6#R\011\006\005THT\003BR\010B<8EI\177\021\004S+L98/\0043n\026UMN\001,|+T7N`xR}Ad\023kF\177\rs\032\017\005\\Q}\025:Sk\035Br\004U?>l=Rc8\025(\0375GD3 7\\\004WqyRJ?Cd-G>Z\010\010fE\031O\006TD\"fB%qz:m)?\034z\001uP/x\022n\007`Lq-^\005$_\016[\035+Q0\006\0351>?`\177E\013\037d\022'YC_\011E OW\037hK\"\037@`t:o\011;\037>M\001mR\001B,!oC\021`UF_\000S8e\033\002-j]\020\017G\032t8 \031Ll[:IMT\027D$k![i7\014St4\016{\"6v*\000\177L\013mKK\0271i\001\000`\020\000\004a\002\000GF\010\014<b\013\030\002 `\032T\010\006\011@JU\031DN0\022A@5(\020\024\023\017\020-V+IRc0[D\004+a`r2\\n2\002\r^m8\030-gI0@I7\030ec\011\030`$\003\000jP ,&\035 [,W\023%Fa7\010\010WCAde9\\d\005#\025Fh7\033mF{\035Re9L%s\0014\014\003*A\0001\031\031\002m2\\M\026\033\005\\ \"^\016\007\023\025fs\020\020lW\023QRf4Xl\027#\024@A:]\r\006{IRt<L\020\030H\n\003\001\0002>$LJ\013J~E%\033(\032lDv?\021\n\037J\rN\177E\011r r%ya\010x\034r\017>]\0322\027\001'3**8$)\031.]-MJ<5\031\036AP\"n\023/Z\000)d*#zD_\004\024\000_\033\025\014\034x/r7-\031s^H\177Rd\037\\\022V\r\037 0\0017DbE\021L\003\002:&\017\\<f\007|[l\030=\011e[yZ\017\006\033\0313)dmln\010VdH\033\013\037\020\020\014\002\000\000L\020 \r\034a\001K\014!3\000$\014\003*A\000a\030\011*S\030If\002(\030\006U\002\002B1r\005Ze9\032,6\0138@E<\034\016&+Mf ![mW\003\005\\y\026\010\011\026s\014\\1\023\014\004@0\r*\004\005DcT\0135Jr4Xl\026q\001\nx8\034LW\033L@T2Xm\006s=Xo3Z,W\031Dl0\032\001@5(\020\006\023\026P-V+IRc0[D\004+a`r2\\n2\002\035Xo1\030-B\002\rJr:\032,fK\rBt2H\010\027+QPo9\032.GIB\004\001\005\000P \010\004\001p\022\011LbwoVJ9\\*8J\037\026&\036\024r)\"3\025BBm!_F\r/=\027JCvPbnWWC\000\0017jA6H)^qU\004\\f\0231m\n\034*&i3-(e14;\002u$\001@Q\013\005\011(# _\036RVs |\031q\0250Q47E\022I2e\027\036H\0350m\177\011\017kpz)t\033z\017J\023F\014iuW\002@2_?F\013>[\03393u\025vcgym\033R\021\007i\0315u\037D\ru$r/zb\034HS<kF\020'\00582\030f\n~\014*Z+.X\026 :9S*e^2\0020o;(=vw8<i\013Y)%\002g+e\026oD\"o6y@p\000\007_\032yIAZ3d&gW~\0251cVY\021ZZwd\005C=\034\006,-\030(ec\021\011Q9-~G{fY2Rh\033g7E\\*K7T@\026x+\017Xm<~(H\010}5P\020\014\002\000\000L\020 \013\\`g\030Bf\000H\030\006U\002\001B0\022%\n1\011\014\002\0000\r*\004\005\004a\024\023\005Xt4[-w\023\024b\023\030\004 `\032T\010\013\011BH7K\011Jr*\034NW\033Pb/\030\013 `\032T\010\003\011IH&\0131hi6[n&)\001\006y1\031.%#Ijs:\010\0106{\021J )Z,vs%\\g\020\024Mv{Pa\002\000B@(\020\004\002\000d\0343!@J\034zm~3/b\006_Xy=\001\030u4\177~3MgMV$LPXl'l_!\034s\000<V-gO\nF}B=qD[\035'p'\020Ei\000\034zP*Fh_hQ6<\013V>g!\017s\002<\022\002\035SU/rTw\000/]\016]\025a^\032=\023\014;\032mZ jI\003Wz$N^\r\010\024P+!wi8-v3BD\027\022@c\\3u\022\002\035:n\"G;\010ZNv=;gT\023CIlZ#]N/.@M!daU,\004\023WDz,\001UA\035\026\0079CZqjC=/L&Q,Hg\013O\024\021D;WN;\023oP\010FN4\002k\020I\026\003v~|A~h@\001\007\000Xl\036;j=4\013\036\n\035a\032-\020\011K6<vj$E\024\005F+R\033i\014q\023\177@b]kF\\,dm\002\".\034g@`fa8dk2l6>xJ`]6h\010\006\001\000\000&\010\017<`a\030Bf\000H\030\006U\002\001B0\022%\n1\011\014\002\0000\r*\004\005\004a\024\023\005Xt4[-w\023\024b\023\030\004 `\032T\010\013\011BH7K\011Jr*\034NW\033Pb)\030\011``\032T\010\003\011H\010&\0131hi6[n&)\001\006y1\031.%#Ijs:\010\011V{\011Rl2H\n&{=h0@b (\014\004\001#6l'\00553y5+\010;l\004A:&#`Xgl<? Bce{^SB\034\016|DAy\"`/\\i\024V}\010D 2?PD9q|+6\032-+FS\001\026G#\n n5^Aj/`Ju\036\002/\026f\011\r\026\006)#ZF+UjEItG\0206\011^\000Z\"P\027XmBh$c^\004)%q\030$\035q\011@^0=>\"\017^Kw4R]O-\n\001jZ\0274\"\030@@0\010\000\0020A\000-#\002hb\013\030\002 `\032T\010\006\011@I\024)D$0\010\001@5(\020\024\023\004PL\026cQRm7\\LS\010L`\021\003\000jP ,&\n!^,&+I(r:\\nC\011\010` \003\000jP \014&\031!\030-G#%Zo9\031$\004\033eDe9\025\016'+Mh )\033mw!B\004\001\005\000P \010\004\001#\002.d*\\`zWt\011N)UUsT\024x\\\036DV\0011X8k8q,S\03227t\025o6`\011\002[;2A;\034bQ\030_k$#4\022uN\0352\014w\000A\025@*'\\!oS\016#x{Uf\02155\002<w\037 \"@St9LS\n\032-rca:2C%((0e\016WVV%CbS)0rRg\\\017aM/_rR\011Kx!^U`px#x\001\026(\rKM8;\034QMtwk>\035KOEPD!\022\002=\026\003\005$W\027L\017uZL\005~-\033P:d\005T,F\023\006\037VJcp$\001Gjvd\006=<p^W/(\003W\027PCr\177~\025vZ7OIdlr:snu\0227gIH\013\027\023o\027\022#)Ocr$`B\\\003f%\033n\030uls[PcS..t1LwV@`cp<#.k\177r=\016.JPj:6!\\\023FG\020\020\014\002\000\000L\020 \rda\001T\014!3\000$\014\003*A\000a\030\011\006A\030Bf\000H\030\006U\002\002\0020\022=\0341\010\014\001`0\r*\004\003D`u#=do7\035\rs\010``\026\003\000jP (&\017!\030-fZ\025\\g4[LR\002%\\c\027\014%\023\001\034\014\003*A\0011\031\001\006e9\035\r\0263%Fa:\032-vq\001\002u:\032\rw\023%hy\020\021\r\0273%fi7[F\021\031@\"\006\001U @\030L\024b0[M6+9Ni7\031&\022\001@<\006\004JPdD\033n\r\000B \0210EFa \030L\026s-Jn3Z-f)9Fo6L\020 \010(\005\002\000@ \r<\013PM \011:\177B\023\027bPuH,< .VmL\036u<\010B3^\034)U\0251EB\003yu\036_/ \023&#\nC{z<G\033f:ww*nP\030G\013\014\030(Ndo\033*I=%st}:\007^bvdReLm\036IMov95t\017Vhe\011D$B\011\025\017\0262\0275b\027,?53\r\023\024dL?p\016brlMIt+'\031q\031\023yj\016:\0353)M`/=,_\005#8V`C>O^#_3B\005\011zC+qW2\025\023\\*55.Ayu^\032xN\003\027-G6{ZO#$o\011UAF\007\017>J\037\")o\03038\016S\\CoD@D\\#\003m T\004\032\007s\013i+KGC\006W>\000e\013 `\rCE\031>rTJ\031Iq6\n\007pO(=\006\034-MH`.2V2W(yMa|%1m\021O \025cy{77869\025\001\000`\020\000\004a\002\000RF\010\rlb\013\030\002 `\032T\010\006\011@H$)D\"0\007A@5(\020\016\023\004\020N'+Mfe6\034f\021\031@\"\006\001U @PL\024B2[\n6K\035\\ '\025F\023A@l\006\001U @XL^B2[\n6K\035\\ 'XM&+\rh (\035,&c%fh4[Lr\002\rJr:\032,fK\rBt2H\010\027+QPo9\032.GIDJ0\021A@5(\020\006\023\016\020LVbMRg7\010\011v\023)Jc:\010\n\007+\011Xi9Z\r\026s\034@C L$3\001\004\014\011\025!I\0107\\\032\001\004@\"a#]Jb6X.7#\025d@1\031-G\033%Nn\027\030LS\004\006\022\002@` \014!8?6_{P$\006ws7\027\020:Yp\026bZh\011OF\022T\007\033~2l\035r/_~t&?h=f\021OH6ApIqm_\013evlY|JE~m\027E@\002}0--BH<?\\g2+#XD\016vgOY,\020\002`\021\000('p\014IGl*H\007\005_:)X\020{\010h5i`\022`D\025`,hYX\030~3?9\021)oPO$t5l!IPd>\013U\"D\004\003\000@\000\023\004\010\002B\030 63\010,`\011\003\000jP \030&\002!\021&\021\011@\036\006\001U @8L\020B9\035.7\033\025Xs\030Df\001\010\030\006U\002\002B0R\011Jl)Z,vq\001\034V\030M\006\003\020\030\006U\002\002b2Z\011Jl)Z,vq\001&e1].&)\001&e9\035LW\021\001\006e9\035\r\0263%Fa:\031$\004\013Uhh7\\M\027#db!\030\007``\032T\010\003\011F\010&+1&i3[D\005\033\025Fu9\031$\005\033\025dv2\\D\004\032\004b#\030\010 `I*\014HC=aP\010$\002\026\n\035lV\0235Bs:\031.$\003\011Jl9Z,vq9De\030 1\020\024\006\002\000k\000\"'DKp\004!\037y\0349\n\007|>\021n\003\001-\022\013\037\rH\011\001#4!9`j?\026\023\"\026 0\n?}:MF\022,dvm\026f=\034]kZ@\033mfto\0141\n8\014e8\002SY\037fD@E_i( :\032\026XuY@C\020$\014p\n\011<E\026\011\020\013~b\0241;-'BF\0311E9G\032X\026\000o \003\037xb\002##(2Cyw\022_Vn{|&RN` \030\004\000\001\030 @\033IB\003(\030Bf\000H\030\006U\002\001B0\022\r\0021\005L\001\0200\r*\004\004\004`$z8b\020\030\003@`\032T\010\007\011AjF{I^n:\033f\021A@,\006\001U @PL\036C2\\ND+9Ni7\031$\004K9F.\030J&\0028\030\006U\002\002b2\002\rJr:\032,fK\rBt4[mb\002\005jt4\033n&KQr \"\032.fKMRo7\014\"3\000D\014\003*A\0001\030)Fe9\035\014Vs\035Rn2L$\003\000x\014\011\025!I\0107\\\032\001\004@\"a\013\rB@1Y.'#\025\\g4[LRs\r^m\030 @\020P\n\004\001\000@\035Z&]\"\024PZ<Vo[_]\037]\006g*b7^\0320Lo\011Ig,Oi\r\001S\005O0.Zq~\003N$|G\010#\0317\025]\031?\035f%g$1a#zL\013D\021Zm\037\021$AxHHhhjQ:\030\021\007\020\035Fj[.6?\014gPu!i\010us\013\026%i]l#Fsd2Zc@ hw\021kD$pR\000-=3Hlj)\027\036L \032aL=\017)`\003\016HsNn\037S3.\000Sbx\001\010I2r1\004p\177C73(**mk3\0321\022*\001-G\021!,\\0FH\\P\013\002\n3\"?!_u\177s\037\014T O\030z\005\002\007\035`~('e\035o0rN`)\006b80bF\013\001Q\006*M!]\003\024UnP\r:d-_uymE=0R\005t\005u#1u8}YYB{q\010l5:u\021Yi%,{\023E\004sG\023s</\"\036\002\001@ \000\011B\003{\030\033&\020Y@\022\006\001U @0L\004D\"L#C\000h\014\003*A\001!\030M\010e:]\0166\033!J *\031-F+-^m\020\020(s\010t`\033\003\000jP ,&\024*\031-F*MJc\020\025\016'+Mh !Y-g#\025d1\020L\003p0\r*\004\001Dc\004#\025jt9Xm\006)\001(e6\031-6{4@R7[nB\002\r\0020@b (\014\004\001]\002K\037\020-Nr\022kZ.\037?),0\004\025bD\033nv\032N\033%u;\007/bzQ\r>qY\003\026{\031\031n\016\006e9R\005\000IBCPp|#FYSu\023A0G+\032vh\014\030J_5\\w2S>hF\001t\004El*Qy?_t$+t+}|\005.ik-\000=\005L\011W\0314!IJV\022\020\\\001\022g\021%_C\003P\000\r/\017qW=\024 \031\017\010\035\007\0309D@@0\010\000\0020@tF\0041D\0260\004A@5(\020\014\023\001\025*3\011\020`\"\003\000jP (&\033\"\032,vKQBl\020\024m\026;9Bt:\\LR\002Qdu9]\004\004\033<\\1\010L\001p0\r*\004\005Da\004\"M(C H\010S\011B\003\007\001 0\020\005\001Y\001TsfAq\023;~C\n\031Mt\014_y/5\010-\027!h`3\004s\0000rRQ\011\032-s\nVrI9\000\001\007vNJb\"\rdIL?3\003$#s\026lT';!NedJ:\0207`nk\007\177{C=|.l\034oM\017@Li^\037\034GPx>\000\0316\016%\010'8Z*TSy\022MvhT;p\011\030\000e\000U\016p\004\00412\003j\"hMhv\033-/+!5b\002\000@f\010\020\006t0@j&\020Y@\022\006\001U @0L\004u9L!S\000,\014\003*A\001\001\030\021*t0Z\006\0219@*\006\001U @8L\034S0[\016B\0021Bk2H\0106KQr1\022\014\004 0\r*\004\005\004c4#%Ni:\030-B\002MRg7\030.G+IJ *\034NW\033P@C7KF\021\011@\036\006\001U @XL\020D)U\0104\011\00101\030EF\001 \030\006U\002\000b0j\021&T\020\024Mv{Q\006A\020\026\006\023\011\004`\037\003\002%(2\"\rw\006@!\020\010X$c0P\014FK\035fi3]\016'+Mh.1[mS\004\010\002\n\001 @\020\010\003%F\023-\\z)w\003D45*\006zO\no$Da\033E<XHFE\r*\030]>Z|teg)?0(1422\177q\033TUa|PF\0363gI\017n[o,K4\np31Iw$DFunB\0034n\002GZ25\\+\010\031N}\026 wp,l\\l Y\024\017#\005\026\030\022Cr\025+ lja\002\017\031Ah\035]\036)JA\"hh\000e[\014\002}#l\024V\004&5\006J8#K\010,WBN\0265ET\013?-\004sr\023\004&)\017[\026\011\024VI\033\036k\\\011l,\037S\022zI\010}Q\033\036\005.\"KH^+yd?Bg2F\020CL<Hh5W8\003@\025v<pH\003Iu\0167\030\022|9\0212\020\032 k>\r\026Hi[\025fQca3FiKg'\033\037]\024e\001\0020+\010\014p\021l~Gg9\013Y2\002k4M*HCg\011XD IY8n^ \030\004\000\001\030 :#\002\030b\013\030\002 `\032T\010\006\011@JU\031DH0\021\001@5(\020\024\023\rQ\r\026;%ha6\010\n6K\035\\a:\035.&)\001(r:\\nB\002\r^.\030D&\000x\030\006U\002\002b0B\021&T!P$\004)Ha\001C@P\030\010\002\177\023GEr.yL&\030uD\017tpZ\177\177\003#e(-q=y\022)DHEX\0077`pkp\032o\"oW\037H.S\030G81`joY [a\034\"vNu \003ag\007\026hA(DFB~sz;BRG\n\017yms\027a(8}ir32\031<c-=}r$O\177$\nO^B4\007LclJ,0\\b\023\035m)]^#\011vaCdBVh\031\035sd+8\0066)\035\001\000 3\004\010\003:\030 5\023\010,`\011\003\000jP \030&\002:\\f\020i@\026\006\001U @@L\010U:\030-\003\010\\`\025\003\000jP \034&\016)X-G!\001\030a5Y$\004\033%hy\030I\006\002\020\030\006U\002\002B1Z\021Rg4]\014\026a\001&i3[L\027#Ude\020\025\016'+Mh ![ec\010D`\017\003\000jP ,&\010\"\024jD\032\004@X\031\014\"c\000P\014\003*A\0001\0305\010S*\010\n&{=hC H\013\003\021DB0\017AA\022T\031\021\006{C \020H\004,\0221X(\006#%Ns4YnG\023Uft\027\030mviB\004\001\005\000P \010\004\001\\:|\021L\003V-\032`\030Cr7_\011aM:\\\0053M7\031f@(J@\"mUSvC `s\022%\036\0248\016\013jw=\024\026G\007~5+c1y&t\r\036BL>d`^k8mk*3\025*IOi\024\000r-g\026`\005M\003b_K-2r+<_#OrThw\003cq\004\014_|N~By6v\005cs\021/\\\002.\000D\017{%N\004\023{\021.$JFI\027Jb4w\034^p\001%=\031BuW(\n\013'2\024\005\\(d20`\011[<NOz.Lk+\033(-\033T kPTB\r3\\[j\034*\026{\007\017kn\024\026\025\031PP)9\031s\r\036)\005m'hc\020]-ey:lchK~Cmf\035w>?\027\001FM\026\0342A\024&hy\007d\nB^lW\010FBvUVnAnO\033CYJHm\002%\026#\014E9}Qnh,2\014DeB;0\020\014\002\000\000L\020 \np`L\030Bf\000H\030\006U\002\001B0\023\rB1\011\014\002\0000\r*\004\005\004a\024)5\006e9\035\r\0263db\022\030\004\000`\032T\010\013\011B)\024!\001\006e7\035\014W\021D*0\011A@5(\020\006\023\006\021%T\033\025dt4YO\022\002\r\0020A\000! \024\010\002\001\000.S:3F\000U:\022%\025+X7G\033%&\002aH\022Qw\014\024F[\"\016Gl\n\001!;}_(M\010\026jX\007%.P\021(c(\010\005|m8\004\007\020(f\rI\\\027\000$A\023y4\016\0270hE\\9.V\017,1\rMi]Ef\"7#X\0224!e\034egJOf\"\003>lUc!)HEnl\r9~\031\025iE\022Lqa\n[ \005*&\016$ey\002dEb3em\036[z\034\0260ta>56Z'\033\177!37\002mR\001K&\036F_dB~Mi@\035\\|3~O\034~o'G@\034\r$_j3pR6&T*Y\033_\007\"\033nG\006\nx\007M\033\023\001LKg=0L-\0212U\006\020X>:\026\035\023e?wCUT@MQ\023e1b=K=\032#AAB\014\017M\013T\177d)\\kXNc\\@'B2y<\025G\rjh\025h4\rW[*\032\013nB,\004\003\000@\000\023\004\010\002\\\030\023\006\020Y@\022\006\001U @0L\004c0L\"#\000@\014\003*A\001!\030%\n-!Y.'#%Ly\030DF\001\000\030\006U\002\002b0J%\010 !Y-g#\025d1\nL\00200\r*\004\001DaD)5\006e9\035\r\0263d@R L\020 \010(\005\002\000@ \reBn%}{AKVbFr\"\003e*\037\r\020\004h}\006\007 \030\020\016/Mxs5^\005\032\022RuFZ&2\000\rE~/\006|.\027t{$\006PQW}ds\001~01W\006r}4OVl\n*\0002\001^U)J@\0332^>+Ts\016n\031[4 r=CEPg\014]sa\032dv9#8O\024R`K=\0249\003KL\022\036\034\0160m\0318i\025\020&h:r!0;oK \003vRb\013a/8\021\035\004\027wc\nc\014\014 nvV\030\016\007C-?F\021\007?OWxVso!\002A,yO\025\031}pr7W!%\034\034~UYu/\0179^+\034&;M3'&\024\023ra\017\033:UD;3yVJGi7G[*?D\035o0\002\n<XA!3&E8bp#\"*uu\030T`8WF#E@eC1[\030%-0`5\014-gj>c\010Q?BDaj\031{\001\000`\020\000\004a\002\000Pf\010\rPb\024\030\004@`\032T\010\n\011BhVsQdu9]\005fs\025h1 \014\007`0\r*\004\005E\006w;]n.2[NG\023Uft\027\033LW!=\016C!P+t\032A& 4[L6{I`.\020\030O\022\003IJf\027\010\005\006c%Zi:\034d\006c%Bb\027\n&\022)@F\006\001U @XL8(1J$\003\021@`0\020\021-g#Ijs:\013Mf+P@L4[-\027#\025H1\031L\006\0200\r*\004\001De$+9hr:\\nBs9Jt\020\020mFK\025\\t\020\020lW\023QRf4Xl\027#%^n\020\020.W#!^r4]\017\023\004\006\022\002@` \011\033Ri6r1)=5\005P\17715=O:E/39\022S\017.B\023IVXyTiU\"jB5\025\\K!ro\\:b\035\\\036\\\\\022\024\"?\nPK\004WJ%9\177\016\001blr{\\2\025\0224D$\013`\014__j)i[_f\007<K\025\011<NIWtU\002A\\XKkU$\010Ug?cpz6fYfVm\022R%,o,o/dOdJYzc|J\000^y\r\017R\\\024\004\003\000@\000\023\004\010\002I\030 7#\010P`\022\003\000jP (&\013\"[NG\023Uft\027\033LW!D~0\036A@5(\020\026\024\033\035nw99Jn:\034NW\033P\\n2]\005u\032M\030_!T\n2\003%\\c7\\N\002q\001Dy\020\034LV18@(6\032-VKQf 6\032,\026\0218R1\022L\00400\r*\004\005DcBC\014R \031\014\006\003\001\001\nn:\034NW\033P\\n2]\004\004c%Zi:\031,C\011h`8\003\000jP \014&1\"[NG\023Uft\027\033LW!\001&e1].&)\001&e9\035LW\021\001\006e9\035\r\0263%Fa:\032-vq\001\002u:\032\rw\023%hy\030 1\020\024\006\002\000cp+tsGcNx\030\020`~I0\177iLrrh^Du\030-2f!\030^haQ\025:CWL\0003M\nys\027\016\"M\\|m\036t\020\016\033U5\"*\032\002l^\177U\0173U.WF$\rDV\014}\013%Pa,HE-\032M\011d)N=+\0360v .\023rl|\034\001{N\033}\037\032\\@h\030\005Yjg\011Bs~B\\mH.@\006ms\030)Z7\035Cty^\031\002\011b \030\004\000\001\030 @\034)B\0034\030E\006\001\020\030\006U\002\002B0Z\025\\t9\035.7!9\\e:\014(\003\001x\014\003*A\0011!]nw;KLVsQdu9]\005fs\025h/!T\n5yH`4\034\010\r\026s\r^r8\013D\006\023d@r2YEb\001!Xi6Z.G\031\001Xi0XEbIDJ0\021A@5(\020\026\023\016\n\0142I\000b9\034N$\004+9hr:\\nBs9Jt\020\023\r\026k%he2\014&3\001D\014\003*A\0001\031)\nn:\034NW\033P\\n2]\004\004\033\025dt4YM\026\033\005hi7[D\004\013Uhh7\\M\027#d@(\031\014\006CA$a\002\000B@(\020\004\002\000VS):HJ\r2u(d\0008T,d\025\ni=\r|\026J&c]X\003ZJg[^\010\014\003M\005H40\0335\031/:^\\\035S\003,N\026\032N_\0023P8>[[GY~)\020(\036X`5\030kvqL5R`?\010\010\031\\Ui(\002 \001~tJ(3PA&g\010\005}0w<u+Mr0om;)I+BE\020i*n.2(\033g\\EiL\014q\177\027[B'\002vDR#\037n\002Q=Dhlr~\032?<8F,\013A7R,dd\016f3n)bW^\032f*M:<k'\026,y$\007y\027i\n\013\026Q\021N\002LJXWvdd&\003\\I@\035k[?ww\020BUA\005\030\n?\027Z\"HiC8fSxz\014]=\036B[o<\001\016\nHJA8\002 &Io\001dK\"#?|\021z9lU\005A\007\023;vy\033\037C\014\010,&2\raVjp\000~\010\010\006\001\000\000&\010\020\005,0@r&\020Y@\022\006\001U @0L\004U)L\"C\000H\014\003*A\001!\030-\nn:\034NW\033P\\n2]\006\024AA\014\006\001U @XP~w;]ef+9hr:\\nBs9Jt\027PmFK\025\\t/Ph\025z%\\f7Kh5\002L@i7\030mw\023@\\ 1\036$\007\023\025L.\020\033\r\026k%hs\020\033\r\026\013\010\\1\022L\00400\r*\004\005DcBC\014R \030N'\023I\001\nn:\034NW\033P\\n2]\004\004c%Zi:\031,C\011L`1\003\000jP \014&*\"[NG\023Uft\027\033LW!\001\006l4Y-g!\001\006e9\035\r\0263%Fa:\032-vq\001\002u:\032\rw\023%hy\030 0p\024\006\002\000d\016S\025qD/_V\011my\003oH\031\177Q43&\0137AT\023~\006G*\011}O]/\034~\006\024QJ+xu8\r\016dO+0!Zk4\177\033^\010{Y^0\022K3Xa\033w_R\006\014\n\032If<U|>v\0369C=\003Y.Go\016V\022;\035a7*SPY~\037L-j|F*n\0035\000tj,XV#F\000E\026h\034\020Iol9\004oC_F9@*'\031\036^{b` \010\014a\002\000T\006\010\016\014b\013\030\002 `\032T\010\006\011@JU\031D(0\011\001@5(\020\024\023\005Q-g#Ijs:\013Mf+Pb;\030\016 `\032T\010\013\011LNw;\\\\e7\035\016'+Mh.7\031.Bz\r S\020\032-f\033=dp\027\010\014'I\001de3\013D\002C1Rm4]\0162\0031Ra1\013E\023\011\024`#\003\000jP ,&\034\024\030e\022\001Dr9\034H\010VsQdu9]\005fs\025h &\032-VKQJd\030NF\003@\030\006U\002\000b3\n\025\\t9\035.7!9\\e:\010\n6+\rjr2H\n6+Ile9\010\0106+Ihi3\032,6\013QRo7\010\010\027+QPo9\032.GIB\003\007\001 0\020\0064Q\003\032\025\0038OL\037/\033d&\037}<b`dj\035\013\020AQmOyr37D\024d]Q~P \\~##S8R8f\002&\006\025\016 l [Y\017fB)}rfqi`\003\023z\035L{F\r%\r\025d\025_\0226SM2As\001=\026Z3?_\004Jl\n2\"3\023#dL\033\007 \004+j4MY?\016o\014!\177~n\011\025FrA^A\016-8\rD,\0310n*K7\031\006\002\000@f\010\016t`O\030Bf\000H\030\006U\002\001B0\022U&1\010\014\001`0\r*\004\005\004`t+Eji3\030/\003\0118`,\003\000jP ,&%\"\\.VK\031Bx\020\024\016&+5Ru6H\0106+Ihi3\032,6\013QJ ].FC=di:\036&\010\014$\005\001@@\031j\010\032\034\006f\002\001<\014\032Q^\0205!PvD\033DOzM-MO\0042#P\rxT\"H\011^N\005Ao\033\027fR<fn^kW<~\031\0260?X[<U3SqJ!PJ~=4$+x\022\020zcv4JpF\006\034zB8]`\027MHG.e~do!\">ky\007IO3fF\023\024\030}l\0225@^),\014pCa=L#&+\022x.Wz-Ej5\177_\004\014\005X\010\006\001\000\000&\010\016p`N\030Bf\000H\030\006U\002\001B0\022U&1\010\014\001`0\r*\004\005\004`t+Eji3\030/\003\0114`+\003\000jP ,&$\"\\.VK\031Bx\020\024lV\033Ude\020\020lW\023QRf4Xl\027#\024@A:]\r\006{IRt<L\020\030H\n\003\001\0000+[\naN\0101;T\011Q4>\0106d\"FD`\024\036\1776@FxN\010b\020pz\027f:>\005p.\000\037\0028ilq\"RP#\022Yq5Tkp-O\026g@/h \024;}]\000B=N\010\000(O~>~\000fu\007:-J|\021|\001a\031\nUr17D\037\0275-x&A\0149L&V&\nbD<;WJzns\r\n{bv+u\006KFP\007NQ\016=|)}p1w\020\020\014\002\000\000L\020\036AA41\005L\001\0200\r*\004\003\004`%*Lb\034\030\006@`\032T\010\n\011DhW\013URf0^\004\005\033\025Fu9\031$\004K9F.\030K&\002X\030\006U\002\000b2\"\025bu4YL\027A\001&e1].&)\001\016l7XL\026a\001JB:\\m\026s\025fs\020\020h\022iDa\001D@P\030\010\002ug\013d\000&-DhU\036\0228%\016W?'hMq}\017\036\002s TL\011\\vB\027\023\036\025\\=GP&J\014V]qN\032:\027v~)Si4sL(kNOn\024s\rW\034|\035~\000lfj>M1/\001w|f5&\035\nbG\001\003zN\"Dt\022\036\033\021%RR\010pmp8Y\006=dEej\013\034\0064g\035\037hrn\\\024f!\016\017Ccs\001\\vN\031p\\.#\006a\001\000`\020\000\004a\001pL\n3\010,`\011\003\000jP \030&\002*Tf\021a@4\006\001U @PL&E8]-\0263\005p )Y,7+IJ $[L2qDL0\022\001@5(\020\006\023\016Q.\027+%La<\010\n6+\rjr2H\014T\023Ufi7\031.7\031\001\006A\026L&\010\014$\005\001@@\031bxfx\027[]{i\035%>Z\006Eis h\031\030z\010[\025NS\010h#<\026C.\026\n\003\0201Ut-\024BQ\"P=12`l27xJ\006\023\023s}(g\025\"&gi\035AJPpQ\007&\022\034\r\rHh\001\\ZP6(.phC\025|TIE*k\n\017\034\023hoS7p.\032uCWg/EpX\0350\014E$',_\"\035sS:V_\025\016\014 \025@${\177#t`\030\010\006\001\000\000&\010\016p`N\030Bf\000H\030\006U\002\001B0\022U&1\013L\002P0\r*\004\005\004ad+Eji3\030/\002\002MJc:\\LS\011\030`$\003\000jP ,&\035\"\\.VK\031Bx\020\024lV\033Ude\020\031('+MRn2\\n2\002\r\002-\031\014\020\030H\n\003\001\0009\007\023LL<R\003\006e\0037be#\024q=XuH#=\177:|{#S\005\017\177A<}Lt\r?\0112\007pwK-Q\022,B\035vEf\011E5\026\022d`\022\r\017\024\010k\024\016LEFXM\013\\\0246 8\014U$\0066M\026/q\016\0239|\011s[P$CH\0344\036\027\030+\n\000H\027eRwxZ_(nqf\007\031\0039js\027))uL+(I\024''\017<~\001UVoH7P\020\014\002\000\000L\020 \025da\001T\014!3\000$\014\003*A\000a\030\011\006A\030Bf\000H\030\006U\002\002\0020\022=\0341\010\014\001`0\r*\004\003D`u#=do7\035\rs\010``\026\003\000jP (&\017#\033n'\"\025\\g4[LR\002%\\c\027\014%\023\001\034\014\003*A\0011\031\001\006e9\035\r\0263%Fa:\032-vq\001\002u:\032\rw\023%hy\020\021\r\0273%fi7[F\021\031@\"\006\001U @\030L\024f7\\NF+9Ni7\031&\022\001@<\006\004JPdD\033n\r\000B \0210EFa \031Mw\023QJn3Z-f)9Fo6L\020 \020(\005\002\001\000 \014U{\014nN\000xqk?8F\rhi\001aoRb@\022\014Pu\006l{]o`\033,\032BP\025\034yzW&W\024\022Rn>\021;Q\007&#-\035]VGY\024W-{\034y\020\016iN-8\021FY\022U#\0075Q\"M\034iI:\027\027s~ #k\016R\027/o\0215Ug.g@yq\021oitZi0r\0230oj\n8g5\032Wz;\021Q\007\\l.Rr@4\034|.)\014\027D=\024t\030\035AX%\033\016,\000\026$-\006\002\017\006hAW8\027hHy\004Z2 H\020\027;q\004<pN~|v\024\\\011\021sav\002g\03531O\026La],\007KW1\022b\016\017\007\033#D&FS;3l8\030\014;\022\006 \006R\0368mwy\004yva3,oAdG\007!W\\p\006=&\016\010YaH/G\011+K\n`WU\\WB\025[9869z0\007\003dQ\021\014,\001{\004=q\n\031\003lky\027\0307Of\013h\005\023J6\013^\000E\014T/\"({@\024pY\033\020>\035<+<n[\006d(~WC\027Z`\020\020)(\\\010\020\003z2L\032G_q\035G.G\031(%/V6&\003y\003z>\024EL\016E@\016=\001SK%\025dFP{(Z|(@Eh\027\0335L\010n&\031\023h&\022\017i\034C2V`\024]P~_=*09SUr\005\034(NtRY8zI\031)Np*`CF$z\020S[pqCA\036\016,K7\010\020\001PgEz\033\\J3\036*:\010\rvm-\022\037PoVjUb97\016Y\027\025:\035\017ydu\031n \037cU\033HQh\010\032 A\r\011'\011`c\034Xw?@63\031\036Gl9\024\0307}\\\0273\"dRq\031E\002\037yy65\022=5MZOm;\021/lLt\027wB\003DwP\007#\003\nAo\007K\035S>aiM\010\010\006\001\000\000&\010\020\004\0060:L!3\000$\014\003*A\000a\030\011*S\030F\006\0010\030\006U\002\002B0z\035(E\020\020mw\023A^r0]\r\026{8b'\030\011 `\032T\010\013\011GHu\"\024@C<XLW\022Qdu9]\004\005\033=Xu:\032-vsLX $[L2qDF0\020A@5(\020\006\023\r\021jD)\001\006y1\031.%#Ijs:\010\010vc=Da6\010\n&{=h0@b (\014\004\001\025\007h\026o\002B9h=1q\014nt.\016\027,\022M\000lz\016{%\030\010TS\016\006d$\022|EaH\032=\037MCbOB7\024\034l\007}J.S\003gj?K51\024i+qVl!O\000s;6).=d1e)#G\025i8\002sY\010.?fR,k\016AZd5\005*\022\000'\0364p~\001BUaUD\035\013xia5)\033$M\0058\022\020\003xH+G<m\003p)<vbL@@0\010\000\0020@wf\005\011D\0260\004A@5(\020\014\023\001\022J\003\010|`\035\003\000jP (&\026!^,&+I(r:\\nB\002)Bp0[EB\002%\\c\027\014$\023\000|\014\003*A\0001\030a\006y1\031.%#Ijs:\010\011$\nA\002N\020\024Mv{P@C L\020\030H\n\003\001\000-u_f)\016\020;\"?V=3Hs\003\037\020\024Xw-5>\003Hz\1772LT:j\030Ok\026_gd,6\026aPk\r{n,E9 \026!-7NOvqp.C\021B$c|\"\037n$wU}yM\030C.\026~c5\023SH6<\027H\001,h]+-Ay0v\037dK\021D\035@\010Bu .:68fu\"C1$+H_*+U<@>\r\007b:NA{as!\004g.]p\020\014\002\000\000L\020\036AA41\005L\001\0200\r*\004\003\004`$R@b\037\030\007 `\032T\010\n\011EH7K\011Jr*\034NW\033P@J0\\\014\026q0@I7\030ec\011(`(\003\000jP \014&!!^,&+I(r:\\nB\002)\002P SD\005\033\025Fu9\031$\005\033\025dv2\\D\004\032\004a\001D@P\030\010\002X&Qh7\006{+\000,\011>;3\010\026%g~~ZH\rRqU\02552\017WA\006e~\004B\\W3790wF6\031]\037/\000\017\017y\021\\6\0309y3sd#b\032\011Q\037gOK\006&JCa?\004x(\007\020[\n|\022w\007b(l\031XZ\177\032_C\016\037\007L\\slt/j\"uE=*TkQNo;/H[KF\030]Ps\022\035_\020\0228\0344\001\"\013i\027\031\002mI\001\000`\020\000\004a\002\000`\006\007\001D\0260\004A@5(\020\014\023\001\025*3\010``\026\003\000jP (&\017#U\010R\002\r^r8\033n&\013QRo7\014$s\001\024\014\003*A\0011\030y\016T\"H\0107K\011Jr*\034NW\033P@S7[\016W#%^n9K\004\004K9F.\030GF\001`\030\006U\002\000b1*\035(E\020\020o\026\023\025dT9\035.7!\001$o7]\004\003)B\004\001\005\000P \010\004\001<\011\033GxSqu\027\000{\003kYe4\002z\036\010J\022 7\016=R*'UavGYkrI[>w\026}\nm&*rp\034J\034wk|$\024\"@;J\177d0\013;8'rsH\0235#CW\025\016.*_@\031fZS:q\027,r \032\n1\rA{~\\Ei$w\017Na\001\006.{a@]vk0pz\025J\036\036&A)Uy:\035L{\034\177\026G\014z\013v5YZR,\177b\037\014\013|\026T\025\032G(\rPFyl*\010%\002i\016C(x3e\\nwx~\007W\\\026(\035-K\003m\032%7!<1f\006\014<$\033$-Bsr9\025-[~4\016?=sN{\006|9\010gW*>\014e}\003\037s\016yQ\026\036q\003\031[mdpg\001E\034\005@\034m\013U95$-\010\011T\023\033\025u+_\nL\017nG\0261{8\037MK(\037y|#-z\016i^,~\031?D\020\020\014\002\000\000L\020\035\031A\n1\005L\001\0200\r*\004\003\004`%*Lb\030\030\005@`\032T\010\n\011Chu\"\024@C7\\N\006{IBt4[mc\010p`\032\003\000jP \014&\023#U\010R\002\rrb2\\JG\023Uft\020\024Mv{Pa\001D@P\030\010\002qf'n[9Cqb|WQ\026}\030=\rY292<\n\n\035G]\0221S)5ugEo<P)E3FXKa gn?'\037hA\0264\021,\036\033J#8?%|\014e&Sz+\177j\025J(zZ\022\032\005X4\023\032\0238T\014hWo?\013\005O`)ze+ HYBw\005\010D]\"=\013*co<Y6\177sTT#H,a\023\000\036HIi++4\r\0001N8J\022xp\003\001\000`\020\000\004a\002\000[f\005yD\0260\004A@5(\020\014\023\001\020HS\010d`\027\003\000jP (&\020#[\rv\023\005XS4Ymb\0039l-9X&\021!@$\006\001U @XL\026P0\\NFs\025ds\020\020h\023\010|`\035\003\000jP \014&\026#[\rv\023\005XS4Ymb\002ABr:\033LW\023L@C L\020 \010(\005\002\000@ \r\0213p2V\022B'Q_\020)Hi5hc8<\016`\r\0068G\024fq\013\007\017\010##\006\030\032\024\005a1zc\024A\023v\031T|\001xc\004&\\3%w\030\001+ \0004!Yg&\014e\000\004 NF\017av7\013UG<\031.q\rs\0300\016(\001R;'Zx\024\033L\007R\026|{\177:_[\020Pk\013\037Y\177\032\neL\020zDt`\036@\0019g%\002gTklM\"[X@h^i\r]IEgszl\004K\005mQ\002\000F$\000VnxrvSFEW=1\025Sr\033$Va,C\026\000O\014c<Q(\004J\014$+\0261W#\"E\003!,scjA\003\0067H\ro7w\035S\014xf,d?[\032/\033#rGU%,7\006\013oAw#\022rnM@\014!\026\ny\013;f)L\nBP\023\025#\013Z}}_`/\017KD8F/\013\"Y)4`YG\023\010\035\013\nV=\001\000`\020\000\004a\002\000_&\006iD\0260\004A@5(\020\014\023\001\020HS\010d`\027\003\000jP (&\020#[\rv\023\005XS4Ymb\0039l-9X&\021Y@2\006\001U @XL$P9\032-V\013Ir ![\014\027\033L@1\020\020h\023\011\030`$\003\000jP \014&\035#[\rv\023\005XS4Ymb\002Adi6X.'I\001\006l0\\n2\001D@C L\020 \010(\005\002\000@ \013i\000jGhJ\032`E\014$9\021Qa[k@BR\007\025f\031-\030hW5{\017d\033g\006\006)\022\031[eVC\031^v\003s\025s\037W7\034MRs\\E\020A\023I8|h\030\001!&[\027\002fm\035\017yL=\0102Z\035'>\020X\017f]oOiJ&\n\021r\032:Q<\006\nY\nm!#\007W\026.M$\011-s/.YAP0\024\0268u\032MlZ=\002,k~QNwl|\030)C|rb9\\w=N<X uJ\030\034 \017F[\032)s6{\"\013$\017w]4|Bt2\033dp1y\027}\007)S;}\021\020WF$\035hH`\026\002@F\027f?y&`D\011w*\033LhK-\025VMsL\013mL%K^b+N@~\022a\026\027/!c\030Sp]\013jVY3J\1778@?W*Ao&_k\004Ol3\003H%?]SB\006;\177FV\011\\Im#h\023E9\021)\001\000`\020\000\004a\002\000_&\006iD\0260\004A@5(\020\014\023\001\020HS\010d`\027\003\000jP (&\020#[\rv\023\005XS4Ymb\0039l-9X&\021Y@2\006\001U @XL$P9\032-V\013Ir ![\014\027\033L@2\020\020h\023\011\030`$\003\000jP \014&\035#[\rv\023\005XS4Ymb\002Adi6X.'I\001\006l0\\n2\001H@C L\020 \010(\005\002\000@ \011\0243}oz\0211a:\005]|l/d\026},\r\035)0%@\004t\177\016Bn\017tT>{ 1JY$I\036\\ZA=\016N\022V%\177a45'M\nmzjg0 \"?\r2c\027L:9juXw:q&|~m;\024\0208\002\027m\034H\r\001R-=\177/O\\v7SB<v\r\"\033JT\017{x\011mv\027\177\0348Cqt\004V_0NKSc\023\0222\025@\005\177w\007!L%!VO:Z\nnFpP\022(=u\002$t\\$\034~a\020.{K#2\022$\035\003!|q\030$6\026\007\000st(>\017$l`\000k>\0367$v9\025b]\rC[>\024l\025Jg\014D\027)?D]=(\000-{B:,o0J8fq^&Tj\014p\037#R(t}pl\005Yfs[95kp~|f;\011x\031\034K\1778\024\036h\032ek\004\003\031K\002fz\023\r\000)I\037M\025\006w\001\000`\020\000\004a\002\000_&\006iD\0260\004A@5(\020\014\023\001\020HS\010d`\027\003\000jP (&\020#[\rv\023\005XS4Ymb\0039l-9X&\021Y@2\006\001U @XL$P9\032-V\013Ir ![\014\027\033L@3\020\020h\023\011\030`$\003\000jP \014&\035#[\rv\023\005XS4Ymb\002Adi6X.'I\001\006l0\\n2\001L@C L\020 \010(\005\002\000@ \011\ny,ek0\030\000$r~Gb\027\0177QD\003y,%S\036\030r\010/n\025QzoU3\001jPlejj'\014:rU\0368G\002Q\010\005\014\014I3({WqNx5-t'W\033r[H/\0256#>oaWP\032\0246tY\024uJ]p*=KD\0020lH::\nHc\025L\020So%;9\002\032\005$k/\007nHH#(8~\013#f6\001\034\177us^L[npR1Xi<xj Q%y_\014{a\0119\022\027,{\037 \037\017\022(\013>\024.\0147\034\017\0242\031}Cv \177\"\002)I'\023h={\035,o^@j\007deO$\\O\022\026`\011]\004k?\010o>1^\030\037\005~\016x-H\026+yUH7E\021*!p9\022;afD\"xPWmk\1773p~c0-\021\026;LDDP\n@(jWW=,@3]dm;\0118ZqP\023Jw\030;)@uW\001\000`\020\000\004a\002\000Yf\0059D\0260\004A@5(\020\014\023\001\020HS\010d`\027\003\000jP (&\020#[\rv\023\005XS4Ymb\0039l-9X&\021\001@\034\006\001U @XL\016R7[nB\002\r\0021\rL\003\0200\r*\004\001Db$;1^b0[\n6K\035\\ )\033mw!\001\006A\030 @\020P\n\004\001\000@\033 w\0323\rg(|4|)}{xbp2+/TH\017|%+\005f*\021\002/>\006\036GDg33cMn<6H\025{QXL:5/\024`\014Z_'\016-\0112u1b1`\007PO!#\0064+\r'~\033]$1 \025\016;j\016v\020]w~:*/\024E{`6u&S\0049<C9|H\036NUUcY\"'%1dpo\003\017\021\006JlTMbijKC2\023LM~'LW\027{\011zDGI\023b-Vn\035\ri\032\021CQFqhk\023T\035\006t\0061-+5YU<\005RZ\027'\020\n\034:~\" M\036s*$b8)h7<\017\r\026XX\026\0319;bv\035X|A\021UB*6tC\034{\033]\027\027\002\036\"\"(XbgM:c. IA\014@dWQ#*I\r3\020UWAM\037ra+\002l\014Pi <\027OS>=D\026G?Ur)'oy\034C\036\002\001@ \000\011B\004\001\\L\020\032AD\0260\004A@5(\020\014\023\001\020h\023\010,`\011\003\000jP &\002'SF\021\001@\034\006\001U @8L\016T7\\MvsQ^1\014\014\002`0\r*\004\005\004atk\005Rl\"[LvK9J $[L2qDR0\023A@5(\020\026\023\020\020lW\023QRf4Xl\027#%^n\020\020.W#!^r4]\017\022\002\021Rv4\\m\026{8b\023\030\004 `\032T\010\003\011BMV\013%Xe7\031m\026s\024b \030\007@`I*\014HC=aP\010$\002\026\010Xl\024\0035Bi6\031-f;%\\e\027\030mviB\004\001\005\000P \010\004\001)<gv\024}\027\017c\"fOji]=Q&;\023'.GT.=?{kf\020\031\014I}&7uQ>S\rn\034b]e\022&\\>-+!^:1-\013\013pMc!v)W\037w\005Oakz5\1775Z\023=}a\r(\r\0246Q,dP\034%\031)nL'H&\014\031O\033v('h&`h\006aB[\r,YcBE\000k%\013q{\rY~\025X\027\177Lc 2b#nseLTV?blJ\014*9fhPtX\020\002\006E;i\024\011=U*K4V6h5k\036EW\036/0\016\021\023G\036aQ Vo\014AE$'~%*\\M28S]g[(\013>\020;eMS\021+\027\010{\001z\0342\016H]\030sN*R\013S\027<]x8@\027\026\030$#Z12]T\002`\031.FB1^k/a8\031pmC\032\005S\032z\031:>\001V\025v6Ua(G_\016q\0076O1o\020\020\014\002\000\000L\020 \n,a\001^\014!3\000$\014\003*A\000a\030\011\010E\030D\006\000p\030\006U\002\002\0020:!Bm1\035.&9D 0\007\001@5(\020\016\023\003R\014\026k\011jr3L'#\001`\014\003*A\001!\031E(C\020\025\016'+MhC2[NF+H@f7\\D\005\033\025Fu9\032.GI\001Rn\020\021\014\027#\004@N2]\016v{IVs\020\021mV\022 b\"\030\010\000`\032T\010\013\011F*D\031\001(r:\\nD\033\025\\t2\\D\004\0331Bs9H\006\002\002\r\0021\024L\004p0$U\006$!^ph\004\022\001\013\006L6+Ihi3\032,6\013QJ@:\034NW\033QFe7\035\014W\0219He\030 1\020\024\006\002\000o_<ku\177+p\027[)`vGA\r\005_g5'\"\025bX'e\014,+\r9YLd\177)\037\024\032&\025\002&]RdFYG);\037PB\013%@Ej\016\010i\034Bh\030G@G7[5Ie0I(0N 3\023w\010eO\031:(OC~\0071\013\021r\0143\\(C+.7Co$794\0140`W\037QU4P~@\020A,\002\0176Mk:Qb\014g\034u|U\177kH~f(` \030\004\000\001\030 @\024YB\003<\030Bf\000H\030\006U\002\001B0\022\021\n1\010\014\001`0\r*\004\004\004`tC\005Zb:\\Ls\010@`\016\003\000jP \034&\007$\030-V\023Udg\030NF\003@\030\006U\002\002B3\nQ\006 *\034NW\033Q\006e7\035\014W\021\001Lo9\010\n6+\rjr4]\017\022\003%\\ \"\030.F\011\001\034e:\035mw\023-f #[,$ADD0\020\001@5(\020\026\023\014U\0102\002Qdu9]\0106+9he9\010\0106c\005fs\020\014$\004\032\004b)\030\011``I*\014HC=aP\010$\002\026\r\030lW\023QRf4Xl\027#\025\000t9\035.7#\rJn:\031.\"s\021J0@b (\014\004\0010\024zvG5N]W[\026vEw\036{cXg\011\020\"]7!Uv/q\030o{:0j{\016;G>-\000%\013U\n!z#w],($@x\n\017V\"\027!>\035\000R\177&\000\021tRRf\\C$I\0069<eTQdE\005G\026d\004\020S\003%.t\"p\013(6\033*=p\032\nwiET$FQ2sqE|h3\014Mb#7X2\0332(\034W@bDd(l\034Pn@6\017@@0\010\000\0020A\000)3\004\006x1\005L\001\0200\r*\004\003\004`$\"\024b\020\030\003@`\032T\010\010\011Ai\006\0135Du9\031f\021\001@\034\006\001U @8L\016H0[,'+IN1\035\014\007\0000\r*\004\005\004f\025\"\014@T9\035.7\"\rJn:\031.\"\003\031^r\020\024lV\033Udi:\036$\006K8@D0]\014\022\0029Jt;[n&[L@G6XI\003\011\010` \003\000jP ,&\031*\020d\005#Ijs:\020lVsQJr\020\020mF\013Mf \031\010\0104\011DR0\023AA\022T\031\021\006{C \020H\004,\0321Y.'#%Li1X.F*\001hr:\\nF\033\025\\t2\\Ef#\024a\001D@P\030\010\00348t;& \001%c\003\000C7x`\0079Zc+'\032%&\024/jbkFB}!F1=,kn*\"\"v*CU\016\\{3(lP4rw\026IX<\011E/\025V-ca!3\000r$NA5\031 \0277no_7\034\016\030Rp\005)|S/\"Z\026ZO!2=\rR\004VW\0237:B-.\026^?_\005D{p)Fl\017<kc\022OV\"lpgF9{~\025s5:q\036\r\001\000`\020\000\004a\002\000Rf\010\rpb\013\030\002 `\032T\010\006\011@HD)D 0\007\001@5(\020\020\023\003R\014\026k\011jr3L\"\003\0008\014\003*A\000q\030\035\020a6XNW\023\034b:\030\016\000`\032T\010\n\011L*D\031\001(r:\\nD\033\025\\t2\\D\0063=d )Y,7+IRt<H\r\026q\001\010a:\030$\004s\025hw7\\M7\031\001\016m1\022\006\022\021@@\006\001U @XL2T!H\nG\023Uft!Y-g#\025d ![\014\027\033L@3\020\020h\023\011$`'\003\002%(2\"\rw\006@!\020\010X4c2\\NFK\031Rc0]\014T\003Qdu9]\0146+9he9\013LF)B\003\011\001 0\020\005ZiA\032A%`l7Y \032C@q\036LPI\032j\001X\037<.s]YN\006ky\004T\027QF\033(VMlS@'0G\002\013y#/\034P\002mqX\003Z\177]\020.=Wjm\027TXO?WLt\031Q)3*b-&pGH%%\030mH?)J,q\024\n\0258i\"\r_]{\\0ctaVaTU8ztO\0345p\024>8\025VW$Q\0266w)IOi#O%\003]n\002\001@ \000\011B\004\001%L\020\033aD\0260\004A@5(\020\014\023\001\021\010S\010@`\016\003\000jP &\007$\030-V\023Udg\030D\006\000p\030\006U\002\001b0:!Bm1\035.&9Dt0\034\001@5(\020\024\023\030U\0102\002Qdu9]\0106+9he9\010\014f{H@S2XnW\023%hy\020\032-b\002\021Bt0H\011f+Qno9\032n2\002\035Zb$\014$#\001\000\014\003*A\0011\030e(C\020\025\016'+MhC2[NF+H@C6\030.7\031\000h !P&\022I@N\006\004JPdD\033n\r\000B \0210iFe9\035\r\0263%Fa:\031(\007#Ijs:\030lVsQJr\027\031\014S\004\006\022\002@` \013y=GV\033\036v nM+u2\033\034b*w\r4d\005\027\")b\007k+\030TU-%K#z\010s\034\022.sPfU\014z5\016A#TLe77\022{-;l]U`IiCbmAu\024ie\023!d\014&0T\036ERw<\rma^@7\025x\027KJF`U.NahJ\022S-?\000+w\004\022\023bRE}av\026\031Vuq2\"\027vLz3+C(tRL(|~&bT\004\003\000@\000\023\004\010\002Z\030 93\010,`\011\003\000jP \030&\002-\020&\021)@&\006\001U @@L\030W2\\nF+I\\ !X.\006)D$0\010\001@5(\020\016\023\004Pl\027\003\024@T7]mc\010h`\030\003\000jP (&\021*\032\014\027;QJ ![mg\033UXt4[Ls\011 `&\003\000jP ,&\037!Y.'#%Li1X.FK=\\ )Y.'3%Fe9H\010FKYRs4[mc\011\004`\037\003\000jP \014&\030*\032\014\027;QJ (\031.'\033=\\a6\010\010&\013MRc\020\020h\023\011 `&\003\002%(2\"\rw\006@!\020\010X2p2\\N6{9Bl\026XL\027\033%F@:\032\014\027;QJ.1[mS\004\006\022\002@` \013er&S6p\n\004|\010+f$%\006Z2j|o!>At?9nu971TLn,WP\036\032LQ}#34Br\0270\\D\007KZXE\014M\027`F{fy-\004\030Mm\r\022\001h^\023\027p\r'\005:+\001t\004\034\035\023b\021vP?\0303)\007\014GSD\004(b?T\026\007\007.{]\013|@\nD.*`Y89\000m<<9q'^\024^BHOXm6\030hod9\031\004\004\003\000@\000\023\004\010\002`\030 :\023\010,`\011\003\000jP \030&\002-\020&\021)@&\006\001U @@L\030W2\\nF+I\\ !X.\006)D$0\010\001@5(\020\016\023\004Pl\027\003\024@T7]mc\010h`\030\003\000jP (&\021*\032\014\027;QJ ![mg\033UXt4[Ls\011 `&\003\000jP ,&\037!Y.'#%Li1X.FK=\\ )Y.'3%Fe9H\010FKYRs4[mc\011\020`\"\003\000jP \014&\033*\032\014\027;QJ (\031.'\033=\\a6\010\010g\023\025Jm0Z-B\002\r\0021\025L\005\0200$U\006$!^ph\004\022\001\013\007\016\006+Ifo7\030-Bk\031de2[,\026K1\000t4\030.w#\024\\c7[&\010\014$\005\001@@\032FN_)0J\031\0137\017%\017X\006\0246nSJ#0B\027ORh6\036{\0117pR+TPt\035\020EF\031\036?\025=R}wpf\016\035C:T=mg\035\0262\006X!#9\011,>9Q~B4\036q\017P\007\n0\002G\007<=_\031$\031=-u0\013g7/2\024QW-gSp\031%%U/p0dR\177O&Dm+*v8\022\002\r)F\036cZQf\022\037kg7e-1\003KH\010\006\001\000\000&\010\020\005<0@sf\020Y@\022\006\001U @0L\004Z L\"S\000L\014\003*A\001\001\0301.e9]\014W\0238@C0\\\014S\010H`\020\003\000jP \034&\011!X.\006)\001(o;[F\021Q@0\006\001U @PL\"T4\030.w#\024@C7[N7+1hi7\031f\022A@L\006\001U @XL>C2\\NFK\031Rc0]\r\026{8@S2\\NfK\rJs\020\021\r\0273%fi7[F\022\031@B\006\001U @\030L4T4\030.w#\024@P2\\N6{9Bl\020\024\016&+5Ru6H\0104\011DT0\024\001A\022T\031\021\006{C \020H\004,\0338\031.'\033=\\a6\013.\007\023\025Zi:[(\007#!Bw:\031%f\033=Z0@b (\014\004\001I36?\000:\023\0379F\013^\n\017<&E6\001;}q\034,Q\033\020\"\026c0wm\177\004\017Q\024{K\033!&_f\001G\006f[\\g$E9\035P\031\rrHET\0336l|~$&g+\010\0117.doH5|7HcgWG1\030\"S@q\007<,Bh\020nVj+=bU2&\037x|\000p>\031Yq\001\024\021:};@\016J\030\006f\023D\"S])7rL7&d\025K5\010:@@0\010\000\0020A\000+S\004\007\0341\005L\001\0200\r*\004\003\004`%R\004b\025\030\004``\032T\010\010\011C\nv+Mhe9\033D\004\033\005`e\030DF\001\000\030\006U\002\001b0J\rBp2H\nF{]\\1\016L\00300\r*\004\005\004bE#!Bw:\031$\004\033=\\s:[\016FK9N 1Xf\022A@L\006\001U @XL>C2\\NFK\031Rc0]\r\026{8@S2\\NfK\rJs\020\021\r\0273%fi7[F\022\011@>\006\001U @\030L0T4\030.w#\024@P9\031-VKUZ )Y.'3\025d !P&\022A@L\006\004JPdD\033n\r\000B \0210e`r2[-\027+4Zs2\\Nf+I\000t4\030.w#\024\\c7[&\010\014$\005\001@@\032#1YU\013kpK9vj\002A1#g\016r$\010Uk4\035q`n*\026#{c\004ATtRz\nm 4<v/u\025\\:|\032\033\036\013}sk#\025j\002&{y0M\010BQl&z\006>Bt\rI\001BG\036R'KKJ@\011bq\034\014^>BU\027sdD76B\024S8\021\037\027K<?M(u\0069mHe\032c\021\011\002o01\raf?U\001q_\"\011\033g '#C8\010\006\001\000\000&\010\020\005&0@q\006\020Y@\022\006\001U @0L\004Z L\"S\000L\014\003*A\001\001\0301.e9]\014W\0238@C0\\\014S\010H`\020\003\000jP \034&\011!X.\006)\001(o;[F\021i@6\006\001U @PL(T4\030.w#\024@C7[N7+1hi7\031d\006\033\014b(\030\011@`\032T\010\013\011Gh6+Ihi3\032,6\013QRo7\010\n6+Ili1Y.2\002\021Rv4\\m\026{8b\031\030\005``\032T\010\003\011D\nFC\005nt2H\n6+Ile9\010\0104\011DL0\022\001A\022T\031\021\006{C \020H\004,\0279Y.'3\025d-1Y.'#M\000t4\030.w#\024\\c7[&\010\014$\005\001@@\032:\"A]H\177UM>6=;6u\003\r\007*\036E*a6PB/rQt#T;(-T@tJ!C`{W\023i\004\030>P34`n\nF .JK\000bmS3\031w\011T\014\"\016\031_u{Fd\004\\\030_uEV)[\013i\034Ao('\002\011\"\0119?O\0206p\005\004\024g.L!wX?)\005ZTOW85G\007\001dlVv\013Frh{oMG,\025UL\"\0115Pph\010\006\001\000\000&\010\020\00440@bf\020Y@\022\006\001U @0L\004Z L\"S\000L\014\003*A\001\001\0301.e9]\014W\0238@C0\\\014S\010P`\022\003\000jP \034&\013\"\035.&\023\005\\v4[\rF)D\0360\006A@5(\020\024\023\003\025\r\006\013]he\030G&\001X\030\006U\002\002b1\"QPa;]\014R\002\rJr:\032,fK\rBt4[mc\010|`\035\003\000jP \014&\026*\032\014\027;QJ *\032-V+Mha6\\\r\026s\034@C L\020\030H\n\003\001\0005E5CaBEC\024}##m#\034vl\034bp`\035~p\027u\002>NiIp\037\013\024pX\034s*\030\030\027\177Z>.tNPR Ty[#A\014<\034{\011\024\r\026[tckgY!G'A\003ir%md\037o\002GN0k\020 \017l|Q_<oRK\\vl\024qHp]=%\003`&)\017\033\001,5\013y>\0078Qy\013,8d@\013$A\003\030}W}_U\\]\n|\"\006p\020\014\002\000\000L\020 C\034`W\030Cf\000h\030\006U\002\002B02QPa;]\014S\011\004`\037\003\000jP ,&\030*\032\014\027;QJ *[M\0273\025ds0[\004\004\032\004@R7[nC\011\004`\037\003\000jP \014&\030*\032\014\027;QJ *[M\0273\025ds0[\004\004\032\004@R7[nC\004\010\020\n\001 A\000\010\003E\011\002[87}6M\011\035?w<>6:7Xx:\"\010z6a\025\005<wZ]\036U\0364\027?Ndz>S/\035K%5'\032\013\000]0[K{\ny#h@.\027WSro6d!gM{#om)p**\030q\032\034-4[,!Vb\037_(_kSm\020TY\0074S\025K\035'-T\036CTztp}p\025E&qYNI\026>K<]wm\017{EjV V&^YM4f(|Z*\030+\003\014g\034kA\013<[\014Jc\022\033\017w\037eVUR\\d\026%\003H\025(\034N\011om|hnD\020)P\010yt\032\026/uN,\032?dG\177\035sH\003NdU>vH\014L\0177n\00602em|JJ\025=\005TNxUh!\014J\011\031DVVPymDEv)\020\0031=:\017|C=S\037\024'U(hB\030n\007\002g<U3\0375)$n255K\027\"8\0070'a[\036\037V:@<\005)\013:v;{\021moS\036y\021\0337\0258\017k\031\004)gCqSwD\013kD5F4Is\021rM \021\"(\001@M\026Fc.]\013\r0t=\020$x\026*=&ey\023G\037%(<&&\030-CS /\"!Y\017\016`WAo_d*x\0025AeNf:X3\030Z)!$d2d\036\027\0267ZjVp[\030a\".,R,d \"#)*GkOvb\030i@wKK\\$\005><\004+gUQ\016\027\022C8;i\013\"zX\0344KEh\026U7\013_ WaHQ=g\006HXu\010o~\036M|&\010{Db\006YM\004xz}tfA\023q\"hNVBgH*it^\034f\033\003ri_\024Wt\001*%&T0YDan\016\002a4R\036\037T\016qs4TTr\025!)\011bCEZYT'2k\\\017_m\014~\011!\\\017pMT\030\026F\177T;x8F9J&xd9jE\037xFys\032\031B4Cl\0201W%&|D[$9LJ\022\017Jv\025ojD@B \r^PgDk}j\007?>)\031\n\0042{R\177o\020FI\034&$\0141\010QA\014L^\014\005\031\"t\"\016bQT|b\r^q\005=fP[XTLr|.>vSP\036I\037dWjH\026o\031\023owpH]\027\031&+\"\021\003s>t\030}Qr2~U\010W\016\n|BT[S}v\0035\014f|%\rNW,\003t7mg4I\033N?gE>b2\010\016aRH\020\004\024?G>$Q\014\014Q1\010c\000?\ra*lr_\023rA\031\030mx\010\022.%\004%{\011\035Z7)<\036\0013\007bgFwpw\025>\017Zg~j\011#;)\024Bzq\"g(CuK\022HM/\003\034j:\021\011]\000\027'\007\n{&m\005\022\026f*\\\022>r\034\rA?\013TQCeOs\024!>\027\007\\\035\003R\037JIril2eY#;F7wH\024\000z%$G#'ba(0@]m%s\013lpFbC\"A\013!OF\006^cj\024\016vk-\014J a:Y\002}r-b;\032q\014\035\001\npZ\034&'a*2}[r2fioY\020p\"~)XXN?$\017zdPV23oG\005\003Zq. n:r\016\024\022L02\0245\016\020i\033+M{|^$fWEz\17774|2MbZCrR\026\\+vKqZ=\024\001K\002>DV\0219hH\rrE(ek76?=W0\023rSCmV\017\n\r\177a~\r\004\nQ\016;Pi'%L\\0\\\007V\003Z\021E$\n\\\034\021\025'\177\017P\023\027\0240\010o:8\026%\016}`}8$::\014\025g\003_ f\006sco\0040y7u\003-]KE\030\033q]\004i=0`A]4Li#\030V]8d&\021\"92'<\026~}c\035}Mf&nViX\031*`KRwD&5}tPv\025\"~\000\004(\020EL'Fl\020Ty?\036C'\017\r\017\016\020j|t@4Kn\013G2DF\022?=6FQl8Yn${\036C\0357\022ST#\023p\"L|$\016\024Y\021\027eDWQo\035bg-\000|\020\010n\002\\Wrs\013bZ\034\010qS&[N\023&?]`\035=\026AD\006=D\017BO\030 \0229}5{1%\"L\022f\037\033J\\\032SI\005DvZc(|H8]_4>%_JW*Tt^[E\021\002+\025d-a\022#\025\030l\rq\\G4\0000Zm@Dsz9ZB;\030\017SoJ\035D)\n45B)d.\006t\022)0\036H)\035rpK3X[\014\014p0\027\026\004~fa$\023\000Gz''s|Aw0\177%+[\035\022Q@2*D986IbVo\034\\/x'\005\003Cps\005(I\001$.ACmCI}\026-\013+\005_\001\022X\0009}\023;\030\030~\005\\\005\020Q}.<\\\036'L)h9Z;@\002?@\027*E\027:2X\177O\r-aarTZ4k\001\020p\011\002%\036K\005\013m/]P\022\r<gpb3\007O;\027*e0c=g\036JFR_\r14\036lZ\0245{29q=%^mJ\035h}\007O\035IY\003T4Ja`R>C`o\022Du+cL\021.(\001\025\003F\r\nn\026+#y8=\010\020\007\033\007\016%M1\037)f8\026[\027.<UXd@\000^ N\021laN?8;\004`6!@y\011trD\006a\013x_gB\000cXU\000J\0022R.c=.gVc!dj%\002\036(Vjx\0037\027\010\004>3)\020\014gQ\004\025\030e\004rGeByA\023M*L%n\001\"\006\016\027,\n\00068K!}Tq1\006I\007U<X\022w:$0\\'[}x@\003\013C\002.\rC2Q7(\007Bi5Sng~M'\"\014@T2c@\0174h\034 \011\\Kn=@a|gLA\011p7q!GBfsT\004vg\026\033~T]eIdNwSA\022gv#}&}w:5\004}+=h@4\005\032RU\023x_/Hg\035\007:j^\027)[gs\\$?\011\016\016\026u\011cIF,h,959&NCj,Y?M6\000\007u6i~\020doWTPn\177!{\027q\023w4P Me%\013\177._XVO#H\003Bef\010yG\005\0315\013`\020\014t>L(w\007HVWo?q\016\177\013#^[Ut6\007,$J\\w\nGa]/\002L\011NN\005M\017}js|D\003h\1778\011\010r .\031#Y5'\035n\017\nhbevh\r\013\021W\rmX\000cFYfz\002%1QKa}J\023e#8\013Snp:\\2h\016ghX\037Uf<lkBO\011zkT\027_\025QGP\010K(Q@\034a\rq\\\0372\005!\033Zv1?SnLi\\^dR8uaQ&)*6=N\"\033C\000\035];\035\177msUC|7)w,3N&\024N>2n\017.\022Sg\027N3\r8|D\017>gB6qR\0014\r\031'&N?G~Bi!qL*e/1tD_L+\006\0168]K7<4A|m\006a\037mQ?k\010-\r[`%\024vv;v\032\014.\026o79 \0045\"\036@M\031!\007H5L\002uiJp)\032nNmQl(J;\006\013\n'b$<O\023&6z\031V\010lL)\006Fwi{\022\025FK\026=Rf_\022\032(S\030EMy\0329\\\022L&E\024P$-2v0\037[)\026*\036\013\\\002\027T#=d\016Il8\0115\r !B27y\024\030\0119xc9>E\026-q`DgW \030\004\000\001\030 @\033yB\003.\030Bf\000H\030\006U\002\001B0\022\r\0021\005L\001\0200\r*\004\004\004`$z8b\020\030\003@`\032T\010\007\011AjF{I^n:\033f\021Q@0\006\001U @PL\"T9\030,F+I\nn3Z-f)\001\022n1KF\022I@N\006\001U @XL@C2\\NFK\031Rc0]\r\026{8@A:]\r\006{IRt<H\010FKYRs4[mc\010T`\023\003\000jP \014&\014:\034L\026#\025de7\031m\026s\024b\"\030\010\000`I*\014HC=aP\010$\002\026\011Xl\024\003Qda2\031.&+9Ni7\031%f\033=Z0A\000! \024\010\002\001\0003d_J\001\0379$7v8\006gk?>:>GL?D\024\007\026-q5a\nHZe)\177-m\177F\037\023/\011;V&#e\177%*8]U\0078/=\017}xWP3.<Z\024\036<,\005\030@A\034Z<D\026\031z\016=< Aq_8M\020\036jEo\022Z#n0FYdd\027n\014*\034miD?b^(\007uV\013>Q)I;%+dN2$sj\004pM\020\n\010b\020LY`\021+M\002yd\037~1et\007#=2&!v\007Qpv\004\016w\"z]O)*\024W8\035i|t\027\004\024\036\020P$X_\006\013|f(\036<:W})Q>%I[I\033\021\026=;/\006amoxDjPw\020&Q\r\037MGXLA*\021\0047n2p\022\003\026qx\007(\007\000\006\0273G\ns\034|e\007qR\011U|$*u|[^\034\037j%&ya\007;\0002k\032\033\0024Vd\010I)<\004\003\000@\000\023\004\007x07\014!3\000$\014\003*A\000a\030\011*S\030I&\002\030\030\006U\002\002B1bU\\i:\031,B\002Mha:\031.2\002A^s:\030-B\002MJr;\032,6)D20\013A@5(\020\026\023\010\035nw99js8\034ef\033=Z/!T\n3\010t`\033\003\000jP \014&\024*Tj\005\031\001 r7Y\016V\033QRo7\010\0104\011\000b0@b (\014\004\001Fk.={\022LqJi\035aFaXP0a4\005\000\023abN\006b(,:dO3H\002\004}$]4\036[\036\010D\003-iFFjj\030_\"Mm(iZg(_Xz*\027Jh\037\037`mb\022>A=t\014\013\0111J^\177&Qa\024\013t\004\034=kt\177v;GozUT<<sI\036\0263Z1\021S?+XHT\004BE\036XQ\nB\005\177aW0\014?'2b\024*#}_P'@@0\010\000\0020@}\006\0061D\0260\004A@5(\020\014\023\001\025*3\011\024`#\003\000jP (&\034*[M\027#\025H )]\014\027#\025f (\033n7#\005X )Y.'3%Fe\030F&\0018\030\006U\002\002b1\003]nw\027\035.7\003L\\c7[%t\032A&1\nL\00200\r*\004\001DaE*M S\020\024Mv{P@C L\020\030H\n\003\001\000-u\022-1GZX$Yy!Z`\004\177EMg0\0217uc\017\023|5e\004&*~r7\014\024\"edX$xF\021=\033\177\nO\004RITEOj\0379\rSF&.}(1!\032s^\036\033%F7U&}o9\ne=JDyzx6MS+n$rle\017tyo\026q\003Xp(\017\031i(}Ro`G\001\026\026\\f_zaf_y\022\006^*\021\027P?5 \001t\021[X\022v\032\020\020\014\002\000\000L\020 \n(a\001]L$C\001\010\014\003*A\000q\030m,a6\032(6+Ih +\030-FK\021Bt4[mb\0029Jt;[n&YD.0\nA@5(\020\024\023\007\025L\026c%\006e9\035\005B\002%\\c\027\014&S\001L\014\003*A\0011\0311,a6\032(6+Ih ![\014\027\033L@1\020\024\rvc%Fy\020\025L\026c%Ha:\032-vq\001\002u:\032\rw\023%hy\030H&\001x\030\006U\002\000b1C!ht8\016Er{]nw\027\035L\026c%Fe9\035\005f\033=Z/\030H\006\001p\030\022*C\022\020o84\002\011\000EB\026K9Lo \035L\026c%Fe9\035\005f\033=Z0@b (\014\004\001X,`O(Mb-:S\013m\006z`]'*\007\000fwSU\r$/\006\031 _as'/\026+AV$vX4\024Z(\007.\000\001DD!H#q\177\010Hs<p\037k?4FDor;SQ?g%D\000u2h7)_\005EB:\032Gtg\177\016p2\006@j\001n\001k;H)Q!\0207\030\036pa~H\n0;DV\002Cc\004opA\002h\\jW$5lrP\0073Qn\003:?8@@0\010\000\0020A\000)#\004\006v1\022\014\004 0\r*\004\003Dc53\005Xi!Y.'!\001,a6\032,F\013QRo7\010\011f+Qno9\032f\0219@*\006\001U @PL\034V0[\r\024\033\025dt\026\010\011\026s\014\\1\032L\00600\r*\004\005DeE3\005Xi!Y.'!\001\006l0\\n2\001H@P7[\r\026\033d@V0[\r\026#\005hi7[D\004\013Uhh7\\M\027#db!\030\007``\032T\010\003\011F\r\007#Q`:\027Knw;\\\\v0[\r\026\033\025dt\027\030mvi<b \030\007@`I*\014HC=aP\010$\002\026\010Z-f3=\000v0[\r\026\033\025dt\027\030mviB\003\011\001 0\020\0068tqe95<Bf$Ukj{\007 ;snl}JT:eJG\007\001*]g.06\036\027\n5nLaO\034;\027T\014'Z%!\002$FX)=3>7*\"j3MTk\037+%M%KT$DeR\"48P7m8\030*Pw~8y\0325b\013s\000p$# Rlr63|gu+p6?Z\027lG\031SG4\011/pv'c4\022\177Md|\rM\007;w^mbs'n\002\001@ \000\011B\004\001%\014\020\033YDH0\021\001@5(\020\016\023\rUL\026c%\006e9\035\004\0053\005Xi2\030.FK=\\ '\031.G;=dk\030Ef\001(\030\006U\002\002B0rYBl4PlW\023PX $[L2qDj0\031A@5(\020\026\023\026\025L\026c%\006e9\035\004\004\0331Bs9H\0062\002A^l4Xo\022\002YBl4Y\014\027#%^n\020\020.W#!^r4]\017\023\011\004`\037\003\000jP \014&\0304\035\016G\001h^/;]nrsYBl4XlW\023P\\c7[%s\011\000`\036\003\002%(2\"\rw\006@!\020\010X\"i7\031Mt\003YBl4XlW\023P\\c7[&\010\014$\005\001@@\0349BF,\034t56\0204\005TWa\\NY\035/\037\036S?\03612K,-&gfT% \\\004&Ai\030Q`Su;M|{=-;_\033\034\"IL?9BI<<v\004J/ll\022\033K~\004\004 c\011\024BB0`Z;\0336\025gO;^O\004\016\032\014#\016[MP-\\UBq\016\n{US\031/\036G\002\027\016W\010*0$L\n4tJfK]|-h6\023\007gSq4\nSx\010\006\001\000\000&\010\020\005\0020@lF\022!@D\006\001U @8L6V0[\r\024\033\025dt\020\025L\026c%Ha:\032-vq\001\034e:\035mw\023,b\027\030\005 `\032T\010\n\011CJf\0131RC2\\NBa\001\022n1KF\022a@T\006\001U @XLFC6\030.7\031\000b +\030-FK\021Bt4[mb\002\005jt4\033n&KQr \026H\011t\032M 1\020L\003p0\r*\004\001Dc\006CQhp\035\013ew;]n.;\030-FK\rJr:\013Mf+P^1\020\014\003`0$U\006$!^ph\004\022\001\013\004-\026s\031^@;\030-FK\rJr:\013L6{4a\001D@P\030\010\003\017\014\027ix4\004\034v=kq\023%@QH\naB\007\026\020k\037Ruj>\026KR\025J\007\026Nle\011$Nh<xGUWq&\016.t:=\021'\007-c8\000\005o*f\0229nL0[\021/d\000l-)J\017\")$(I$VPG![4TDslL:u)v\027\037\023\177=}\004He\036x(;-&*\001\025g7#Ko\017B\033s\007\n<\016\177`)oh'\1771A\177iEY\001\000`\020\000\004a\001vL\013s\010,`\011\003\000jP \030&\002*Tf\0219@*\006\001U @PL\034V2\\M\025\033%Nn\026\010\011\026s\014\\1\033L\006P0\r*\004\005Ded\0331Bs9H\006B\002Ajb6\032,2\002Adi6X.'I\001\006e9\035\r\0263%Fa:\032-vq\001\002u:\032\rw\023%hy\030 1\020\024\006\002\000h,N_3c!.-\024\036NJBS\037F5}y\014Qahi\011\022\0074&\013Vok\034`\010\\e\000x'24=r4eNGrzu\177S\006:Xd\010Mv\000XNA\001Im#\002$tB|S\013b{|\026C\006vTyq\000tQN_O6G{\011^y\014\n3%#w}'K\003\n\036J.N{Y+\036\036\023\\p'M5\034M\033v0g7Ve\033<6f}\001(\007Gp#j \030\004\000\001\030 =S\002|b\013\030\002 `\032T\010\006\011@JU\031D.0\nA@5(\020\024\023\007\025LW\023%&i3[EB\002%\\c\027\014&s\001T\014\003*A\0011\0319\006l0\\n2\001D@P:XMFK\014@P9\032-V\013Ir !Y.'#%Li1X.FK=\\ ].FC=di:\036&\010\014$\005\001@@\034QM}[#+\030%YJ!cv3wW\030o.o\036C \001)\010;t8\022khhD\013JsT(\0232\"t\032\037f\031-`eC VB\006\020yP\0326\020P\\{{\"`rk70>a.VQ(\037jB 44c,?l\006M<<hgD\0029Q GDN\"UM\021{`\005\000m7\010y\011&v6dXkL/\003.-C^t\0339J`{\030.E\"yFUnQY{-X\010\006\001\000\000&\010\020\005 0@p&\020Y@\022\006\001U @0L\004U)L\"s\000T\014\003*A\001!\0309,e9\032*6K\035\\,\020\022-f\0318b<\030\016@`\032T\010\013\011Lh6c\005fs\020\014$\005\003UDl4Xd\005\003IRm0\\O\022\002\rJr:\032,fK\rBt4[mb\002\005jt4\033n&KQr \026H\010s\021Dt0\034\001@5(\020\026\023\030J\0142I\000b9\034N\004\0053\025di)Z,vq0@I7\030eb\0014@F7\\D\006\013Uhh7\\M\027S\025H :\\lR\003=\\l<L#s\000t\014\003*A\0011\030Y,e9\032*6K\035\\ *\034NW\033P@N2]\016v{IV0@b (\014\004\001*h.Wa16q\003j2Z }ql1e%\033\001lN\030V\001/\033\026xi^R\033\033NU0)+SoPpr\010EK\n?#wR\016yV2\037FpC$T\013\035 M=9\027.-]U\026'p\nM[\031'{<^\021)5\020`n8J0W\037H\"ztel:8>x\031\004G5\027\033+\r\033vmCm\"a7)Ox>#E7rM\033D\014#T\011 /N9\021uWg:@@0\010\000\0020A\000;3\004\007\0241\005L\001\0200\r*\004\003\004`%*Lb\027\030\005 `\032T\010\n\011CJf+IRS4Ymba\001\022n1KF\021y@:\006\001U @XL,V2\\M\025\033%Nn\020\025\016'+Mh '\031.G;=dk\030NF\003@\030\006U\002\002b3\011!F)\020\014'\023Id@V2\\M\025\033%Nn\026\010\011\026s\014\\ \026H\010f{H@a:]\r\006{IRz2Y\004\007+MJ 7[MGIE\n0!A@5(\020\006\023\036\025LW\023%&i3[D\004\0331Bs9H\006\022\002Ajb6\032,2\002Adi6X.'I\001\006e9\035\r\0263%Fa:\032-vq\001\002u:\032\rw\023%hy\020\013$\0049La\002\000B@(\020\004\002\000na\032KMSs'l<`GDs<=n\033\00216eu]\022\024,l\006\034LY\006k\000`F\n)Q\031G~\010\031T>n\rr\033jS8*N*\011}|#45l\005xao\002\022JWcP\013\001u\r\016\0378{\014\01736)H\014\016=_r\0100Voy\011DHApN\000]FV\030Hm]3/\000\020!ZFU454#0&Y+\020IJ@54\177J\n8\025LU4\014\035Jx_\011oG@`\177pOw)-\031Lm?PyI\007U:\177\017JM>I2xmO\rl}\000&\000\r.\004z\017\022|gK2T\014-N9]d]3nYB4_Qs;\032s`2?\021z+MY&{-*r\0035$1Gvt)],9\\$\\QJ#`\026g6\037\035m\032pzY\017\001\nA\011*|\014OQbV\021\014\016wm*Shc\rS\"Tm\010T<\033{\025W\037K\035Z\023h\010\006\001\000\000&\010\020\004l0@if\0219@*\006\001U @PL\034V2\\M\025\033%Nn\026\010\011\026s\014\\1\017L\003P0\r*\004\005Dbe3\025di)Z,vq\001(r:\\nB\0029Jt;[n&YDv0\034A@5(\020\026\023\031\025\014W\0235f 7YD\007+MJ 0]\004\006CQhp9NEr{]nw\027\035LW\023%fi3[Ef\033=Z/)\024\010\022\001!F)\030\014\006\022q@X\006\001U @\030LJC6\030.7\031\000b (\035,&c%F (\034M\026k\005dy\020\023h5\032@@R2\\n\006{9He9\014\020\030H\n\003\001\000.=Ushtw/sKsRKyM2=n\033+=U\026c\0262%,Q:/-KX\021\017(M\neip\023gY4Do\036B2\177u4Ql^fr2+\000'\037A\0006R[\003\003\0268-u]%(P\022\022Xbsi\031!-MjB!\004b\037P^\003\0075\036bpm\010Z\006Wx\016b 1^\1774mz\014\003.\011<9#Hf\021a\n\036z\032o\023l &<_\024m,c:\000P\020\014\002\000\000L\020\036iA>1\005L\001\0200\r*\004\003\004`%*Lb\027\030\005 `\032T\010\n\011CJf+IRS4Ymba\001\022n1KF\0239@j\006\001U @XL\\C6\030.7\031\000d (\035,&c%F (\034M\026k\005dy\020\020lW\023QRf4Xl\027#%^n\020\020.W#!^r4]\017\023\004\006\022\002@` \0132j\027#\006ZD8\034\001WO\034a~B\010Lf\006&\0114.jT%\027bip\013Oj\007A\020(\037\"xT\032|PX\r7sdYz\003\003g*wX6oXt_ry!$_A_)<#jox3\007p\005'roBG\026)!\"]\rQM$wd\014D\007;\n`\0225g/OL\004\033\007suM\025|\177RmB\036U!\002\023\021\003\030q\017\006qu\006$D8\022<u_r\024`\000|\004\003\000@\000\023\004\010\002P\030 8\023\010,`\011\003\000jP \030&\002*Tf\0219@*\006\001U @PL\034V2\\M\025\033%Nn\026\010\011\026s\014\\1\036\014\007 0\r*\004\005Df4\0331Bs9H\006\"\002Ajb6\032,2\002Adi6X.'I\001\006e9\035\r\0263%Fa:\032-vq\001\002u:\032\rw\023%hy\020\013$\0049Hb:\030\016\000`\032T\010\013\011L%\006\031$@1\034N'\002\002YJr4Tm\026;8X $[L2q\000Z #\033n\"\003\005jt4\033n&KiJd\020\035.6)\001^n6\036&\021y@:\006\001U @XL,V2\\M\025\033%Nn\020\025\016'+Mh '\031.G;=dk\030 1\020\024\006\002\000Sb\000\022\013PYg\r\000~\011G\006.<\007H!\017\014s7\027tf_L\020\020\014\023_\027j,F0<,\011\025EK@\005R,f&#zmB-.<A\036!\031g\002{L.A\002g#\005\004\011K\025&O$\023tcj *\"\013\004#'R[\017\000:E{\030[\031\0363>2'\003}<o\"1q\0366zhh7js\006dU\036+\026\022_T#\007\013,HTa\177\006[\036Rh9[N?]` \030\004\000\001\030 @\035YB\003J\030Bf\000H\030\006U\002\001B0\022U&1\013L\002P0\r*\004\005\004ae3\025di)Z,vq0@I7\030ec\010|`\035\003\000jP ,&\026+\031.&JMRg7\010\nG\023Uft\020\023LW#]^r5L'#\001`\014\003*A\0011\031DPc\024H\006\023Idr +\031.&JMRg7\013\004\004K9F.\020\013$\0043=d 0].FC=di=\031,B\003Ufe\020\033mfcdbE\030\020``\032T\010\003\011O\nf+IRS4Ymb\002\rXa9\\d\003\021\001 u1\033\r\026\031\001 r4[,\027\023d@C2\\NFK\031Rc0]\r\026{8@A:]\r\006{IRt<H\005R\002\034f0A\000! \024\010\002\001\000+a n\013*,mYw\022o\026('ni7n\005A\033\017YX*cfYyCz3'h6.E\010q8;\n#'\0135q/x\0322\035 ^#\0161=,Zu57E\027q\0068N\023O\001(yYEt\023l\007{\035\030\010o\013VK\010\177\004:\002\006SC&\000g/n<\007H\003]cI\rnR@Y\005^\017\022V4S\030QF\006\"{\005u\"0\004nyoaR\007d3\000A\005\02552\01366\027 f\014[[?u\000UY\024\003E5;\031\r;S8r\0026N1;;m\011\024* \036\004 *k\0255S#)4\0311f\020F=\017f?dg ,cG1A\010wXcvi>\\W6vj\034I(i\034n4\003M435\026MjGk\016C3J!\002MAP1:\02420.mi+\014c|Z\031`B5\006oy\0113E|D,\nB|\010}y\006^b*\011B\017b\022W\003t$\004\003\000@\000\023\004\010\0026\030 4s\010\\`\025\003\000jP (&\016+\031.&JMRg7\013\004\004K9F.\030Gf\001h\030\006U\002\002b12YJr4Tm\026;8@T9\035.7!\001\034e:\035mw\023,b;\030\016 `\032T\010\013\011LJF+IZs\020\033lb\003Ufe\020\030.B\003!ht8\034g\"y=nw;KNf+IRs4Ymbs\r^m\027TJ\004\011\000Pc\024L\006\003\0118`,\003\000jP \014&%![\014\027\033L@2\020\024\016V\0231Rc\020\024\016&K5Br<H\011t\032M )\031.7\003=\\d2\\F\010\014$\005\001@@\032\014S\014ba?Q\006G`\025z\013\036ZR\014[e\026w\005\017i<9\017K@1\013/icx}\010Cd:\ng!\032IChRi\004+:\004R@GxdoS\011\177\030T\016\022j{Hnm\017\0165\025\005\023\004\031`\034\001\001\033W.=\013]UOF7S\024C\"b1JME!{\032E\017bI*.gEd\001\"hc>i\037x-++\nw?9V\006r\035:\0036(b\021;\011~'\177\030\030\010\006\001\000\000&\010\0174`_\030Bf\000H\030\006U\002\001B0\022U&1\013L\002P0\r*\004\005\004ae3\025di)Z,vq0@I7\030ec\011\\`5\003\000jP ,&.![\014\027\033L@3\020\024\016V\0231Rc\020\024\016&K5Br<H\0106+Ihi3\032,6\013QRo7\010\010\027+QPo9\032.GIB\003\011\001 0\020\006%8YO<C8P\004)4\0107`D\006oFWWZHT\004>\010\014\005t&=Nd#Ow\000K\001y\027n*T\021\000ZW0\006\037<\037si\035f4\000U\010o]52\013\"1Q8w\021\037\031t&1NW\016Hso'P^\007.|\025\020c#D\006|`\037xV\010kw\001$m$da\\{\014hAK)i0^9v|}M?DD)O8v\n{!z\023EHL2KP\026B\026N\002\001@ \000\011B\004\001(\014\020\034\011D\0260\004A@5(\020\014\023\001\025*3\010\\`\025\003\000jP (&\016+\031.&JMRg7\013\004\004K9F.\030O\006\003P\030\006U\002\002b3\032\rXa9\\d\003\031\001 u1\033\r\026\031\001 r4[,\027\023d@C2\\NFK\031Rc0]\r\026{8@A:]\r\006{IRt<H\005R\002\034d1\035\014\007\0000\r*\004\005Df\022C\014R \030N'\023A\001,e9\032*6K\035\\,\020\022-f\0318@-\020\021Mw\021\001Bu:\032\rw\023%te2\010\016W\033\024@o7\033\017\023\010|`\035\003\000jP ,&\026+\031.&JMRg7\010\nG\023Uft\020\023LW#]^r5L\020\030H\n\003\001\0003\013m\010E:\\4t\025=\035eTLLGk\031AB\034\026BH\010fj\034\177TBH\020N\0136gxR;!O\010\\\036;|i\177\022._\003OB\030~'c\017\037\"#|XeYN\034d \001\r\014\014\002rd\016\021.|>a]uJJ'E\007 iW<\007u\013S5\007\021JchU:y}E}rT@'/U\027\033U\006\006}l\002G\031\014y]b^6d4X?\011Xt9\011'W\014p\020\014\002\000\000L\020 \016la\001e\014!3\000$\014\003*A\000a\030\011*S\030Ef\001(\030\006U\002\002B0rYJr4Tm\026;8X $[L2qD>0\016A@5(\020\026\023\013\025LW\023%&i3[D\005#Ijs:\010\011f+Qno9\032f\023Q@p\006\001U @XLb(1J$\003\011dr9\020\025LW\023%&i3[EB\002%\\c\027\010\005R\002\031^r\020\030.W#!^r4^LV!\001js2H\rvs1r1\"L\01000\r*\004\001DgE3\025di)Z,vq\001\006l0\\n2\001L@P:XMFK\014@P9\032-V\013Ir !Y.'#%Li1X.FK=\\ ].FC=di:\036$\002i\001\0163\030 @\020P\n\004\001\000@\031;Tq%|<\007c!s<679o?\014K.(\022\030\023~\0032\037kPHB^Q>\"Ja`EH\004on\024aH9.b\006\004\"\006>jeFu\033j\021 c_\"m4Ta,i\014r23!h^\024K7\001\000\010Xh^Y\032#&y\003\013Y\025P,.yP,3QXgWWp!\022!9l\\Ng\031\033\\\032tL*\0348/\004\004i<1^I\"\035\006d\025.\021\r:/n\031\030\"TQ\0212e,\017\0240Dz\033ME\017Z*@\017owK\025.>\nH\014`A>+\023_jHr}!\r\027x\004\\/v\010\024+(yNn5]\r7q\0034le#\006L,U1\0367!&\\\016:S_\003\010,\013Sr+pgC=B;3U\177;+ez iT#\030S\023e=\030z9s\010oUBY3`w\031&$:\006kahI&[cK\034x\032$v\025W\"M\013J^.\002\001@ \000\011B\004\001\033\014\020\0329D.0\nA@5(\020\024\023\007\025LW\023%&i3[EB\002%\\c\027\014#s\000t\014\003*A\0011\030Y,e9\032*6K\035\\ *\034NW\033P@N2]\016v{IV1\035L\007\0200\r*\004\005Df%#\025dm9H\rv1\001js2H\014\027!\001Pt:\034\0163Q<^w;]eg3\025di9Z,vq9Fo6Kj%\002\004@(1J&\003\001D\\0\026\001@5(\020\006\023\022PmF\013Mf \031H\n\007+\011Xi1H\n\007\023%Za9\036$\004z\r&P\020\024LW\033A^n2\031.#\004\006\022\002@` \017\017\020\020\016Ann^\032#K8mi^\013M/R<11kc*o \002*\004;\014NE-9;\022w\032[kMM]=A@&Y}VX\002LZb8scx}eZ\031\024soX\"y{vl\030]7\034\036@>5aw\0350\007c([ZxF\020y|\021\030\\Gk!OYgF}V3C\004\"-\023\024es\007o'A ^?\002v`B\r\177BE3?GK<\013ZZ\\\005B[JT\004\003\000@\000\023\004\010\002P\030 8\023\010,`\011\003\000jP \030&\002*Tf\0219@*\006\001U @PL\034V2\\M\025\033%Nn\026\010\011\026s\014\\1\036\014\007 0\r*\004\005Df4\0331Bs9H\006B\002Ajb6\032,2\002Adi6X.'I\001\006e9\035\r\0263%Fa:\032-vq\001\002u:\032\rw\023%hy\020\013$\0049Hb:\030\016\000`\032T\010\013\011L%\006\031$@1\034N'\002\002YJr4Tm\026;8X $[L2q\000Z #\033n\"\003\005jt4\033n&KiJd\020\035.6)\001^n6\036&\021y@:\006\001U @XL,V2\\M\025\033%Nn\020\025\016'+Mh '\031.G;=dk\030 1\020\024\006\002\000]<\034L\177g\011.BU\027\020:_s\017b_m\001\017c\010\027X\021\033N\031AgU\025\030E+FC\030\034vJ\0137uuU\\Yd$LR\005D<~\000@\033xp,1J\0012w3:E-^X\"vb8a\006x\024&rRC\017(1 ;EZ*UAP-\rnY?JWbl%4\003C6Z&h1a}t\006\037l\000zHz22q^8P,bcQ\030\035!Z81cf\000\024G` \030\004\000\001\030 @\035YB\003J\030Bf\000H\030\006U\002\001B0\022U&1\013L\002P0\r*\004\005\004ae3\025di)Z,vq0@I7\030ec\010|`\035\003\000jP ,&\026+\031.&JMRg7\010\nG\023Uft\020\023LW#]^r5L'#\001`\014\003*A\0011\031DPc\024H\006\023Idr +\031.&JMRg7\013\004\004K9F.\020\013$\0043=d 0].FC=di=\031,B\003Ufe\020\033mfcdbE\030\020``\032T\010\003\011O\nf+IRS4Ymb\002\rXa9\\d\003!\001 u1\033\r\026\031\001 r4[,\027\023d@C2\\NFK\031Rc0]\r\026{8@A:]\r\006{IRt<H\005R\002\034f0A\000! \024\010\002\001\000+9:(ESF,j~\030}T2\017+3YK(|AdO\011DT_\001feDV;m\004\017Iu\007m7:oEyh\020\177\034N@3\\|\"HC\0274Jh\023[H\0130OiC.T<TXl\027\004*k7Lc6J6\002z*\022&\003r8iZ#dAvB\014R{\014SD\n`<\"^s(V\024T\020nh\031[U\035\013\031p\0107\nG\034,\011!#\014f5`]\0019O\023:?\035y+\003t,1\030riy\032K\010R\003\\ Kri\024q\000\0200\026xy9Fq:,`F\003y\020\006m\0331\026\027:\005O@Ff8\006YTi_+\022#-vqn\027L'\016\r\026%ZP\013alR!lmf\004\177ul.>Nd\013\rR\036e#^.\001\037\004dv44! \014jkQ5O\003-Uo'\027\177\001\014\010<81M\014e\006P}\0239~F\014\033\032[\177IK2~x\014\004\003\000@\000\023\004\007R0/L!3\000$\014\003*A\000a\030\011*S\030H\006\001p\030\006U\002\002B1:I&A\020\021\014\027#\004@S2XnW\023%hy\026\010\011\026s\014\\1\027\014\005@0\r*\004\005DdU\033\025Fu9\031$\005\033\025dv2\\D\004\033\025dt4YM\026\033\005hi7[D\004\013Uhh7\\M\027#da\001B@O`\004K\034z`kP3rjU\011AUuB(\005l\014VkQba_\035k\032^\014E \017K\004 \0249\033|<\021bE A\r\020Z\0147*z6\022\010\nZv4 3 -\011\027I%I,b\022YY\010\003c~x\ne[\004\003Y.\001\033El>M]iN\032B\022VL\022\027\021m\034R\032\011KI!\nf8\036\nu)\025!1f:4`V\0319f8m8\031i\016.t[Vd\007O0\020\014\002\000\000L\020 \0114a\001O\014\"s\000T\014\003*A\001!\0309,e9\032*6K\035\\,\020\022-f\0318b\037\030\007 `\032T\010\013\011EJf+IRS4Ymb\002Qdu9]\004\004s\025hw7\\M3\011l`9\003\000jP ,&2*\031.&kL@o3\010\016W\033\024@a:\010\r\007#Q`s\035\013ew;]n.;\031.&KMRg7\013L6{4^R(\020$\002C\014R0\030\014$S\001\014\014\003*A\0001\030q&e1].&)\001&e9\035LW\021\001\036C)T\004\005\023\025fp7[LF+Ha\001D@P\030\010\002pQLY\020Pw:f\n4<\027v\033X:Sz\177\024\027D0gnO}\027cNj6\017&Qu\030y\003PK\"/9lkn!Q\030:\022\014!\025w\011\0247W_4L;\177\\\177r+-&\033dW3\034,\030\036\006jQ\\B\000\011\035D\"S\r$cI6=O0\003\037D=\023/P!\036\024qk3!K'E4rH*i\025\"q\026\036:h\023W\034e;\001iV=B^lk\\\0101\026\037\001\000`\020\000\004a\002\000M\006\010\r\024b\027\030\005 `\032T\010\n\011CJf+IRS4Ymba\001\022n1KF\021y@:\006\001U @XL,V2\\M\025\033%Nn\020\025\016'+Mh '\031.G;=dk\030Nf\003H\030\006U\002\002b3\022QJr6\\d\006{\030@u9Y$\006\013P@h:\035\016\007\031h^/;]nrsYJr4\\m\026;8\\c7[%w\023AB \024\030e\023\001@b,\030\n@`\032T\010\003\011Hjf+IRS4Ymb\002QRm2H\n7#\005Zp4[Lr\002\005jt4\033n&KQr !P&\010\014$\005\001@@\032!LuOB\000\010+\026\026:h\011\021\021\r\030W`JZm{![9Y|Np.rCt@K\007a\030(rNfzT\\\030yBcuS4\031M^C8\0365AnP\nOg\001q\035P$w\020ItFQ?Q\030!#S6\n_2y\023\001Q\001\030\0374\032r(B\003\024^AiyfY('oKU\013~.!\014F]);g\013PDCs<d\010(Jnt=\004@\026\025$\0177;\023\007(\010\006\001\000\000&\010\020\005:0&L!3\000$\014\003*A\000a\030\011*S\030C&\000X\030\006U\002\002B0\"Y\022S L%s\0014\014\003*A\0011\031\031,i9X$\004K9he9\033L\027#%^n0[\004\005\033\025dv4XlR\002\005fs7Xm\026\013QRo7\014\020 \010(\005\002\000@ \014(u\032s e<\022\005QXlg\031}'(\032YD\0020L\002x\"%O\020;-jN%b&+(_]Ul\031xJB9\037OH;O\"%=S\n+4mp/?G(Z-BwBO f\036q4H\021EjH\\\025`#Q\020G`pz #\001H4\034\025ek.x ;aJ5Kw\0028e8Vf.m\014L\n8J1\022Mty\"\032\n`#{T\r\024t26hPMf\011\026$B/4\"T\r4\022RX&C\0355)vt\n#\022\037,\025zr\007`;\027Y\031Qr9\036ms#%\000\030=Q\177s('\033u`\037jJH \004fJBqU\001\"x+AkX\032_\003%pi2\036\032q'8'XQ|_w+\004plj\011V-;\"\020\0313C]>\r~y\016M:Y\011'&mL|\0050Y\0335Lw\025l\"p\\ Ll#([|r\016Jn{\177#4;91w\001\000`\020\000\004a\002\000\\&\006\011D\0260\004A@5(\020\014\023\001\025*3\0104`\013\003\000jP (&\004+\022*4\011D^0\026A@5(\020\026\023\023\025M\027\033\004@I7\035\014W\0239Bt4[mf\0130@S2\\NfK\rJ \\n6{\rRa:\032-vqD$0\010\001@5(\020\006\023\004Qj\002\002I^o:\010\006#\004\010\002\n\001 @\020\010\002R\0018-5,\"\003a+5\011L\027Hd\001|_ffuH2^o2\006\177\rTV($4Lb\027\006+FV:(Bu;\0218 \0038:n{Fn;{jx\026NA\023$XA\032\177\"]E\011.,\016Rh\\HiqPL\016'9iVU`\nmD Qa}[$/i\rxF9Soe#L=(\026\025+\007-]\031s-\0214P\020kuZNph\\\031\011=sE|,\002NK\016_Z\003\007%\014\017^0|5\034|?Ku\031QHJ\013wd\n7Qk=YV\017MlD\006vaI\03468E`\011^eg\017EDr\177AQKZ#x- \025Ggm\017p!5\024`%d9\0116v?.=\034b26XaHTtc\016z\"u-\005\030\"\036\r\006$7aJW]\n}s41Uzlv(O%+;\004kC#K\022RX2Bm\014@ny\003;XM\030`\014\030ddjg` \030\004\000\001\030 @\027\011AB1\005L\001\0200\r*\004\003\004`%*Lb\r\030\002``\032T\010\n\011A\ndJM\0021\027L\005P0\r*\004\005Dde3%fa\020\022-g#\025dn0]\r\026{9Bl\020\024lW\023YRc2H\010\027\033M^c4X.FK=\\1\011\014\002\0000\r*\004\001Da\024:@@R7[nB\001La\002\000B@(\020\004\002\000];\010;ASU#3wnpH|4\020Q\007U\024tU\030tsC\033Ff\0321PU~Br$iO#$E\014HL>&\022\027{q}F8 \004Ea8\ra>x)L+sD\026\027\027RK3~J.\024Zn&c\007\010uIT\010Lu2\021]#Z3IR+\\_\034*C6T^\034G#/Z\0308\023\002U%7#at \020\034\005:~[\0022^Fldn~NX;,z7},F$\013\031\017\001b5;HI4\003^h\004P\022L\025\\fIAy9\032q4@7H\006\007R\001[4y\034kw\005<}uo0\nD\030'c\177 \034H:=C5)GaZGLBp>.#\\BFbU\026\011\00331l+,\027g\003Qg'lI>}\007l\013C\032^\007\003\037GPJCf!\037KSD-cTEH7\013zm\006-ma\006\025r~\011\032\036)B\024~.,:'J%bIC(\010\006\001\000\000&\010\017<`a\030Bf\000H\030\006U\002\001B0\022U&1\006L\00100\r*\004\005\004`E2%&A\030Kf\002h\030\006U\002\002b22YRs0H\011\026sQJr7\030.FK=\\a6\010\n6+Ili1Y$\004\013Mfo1Z,\027#%^n\030DF\001\000\030\006U\002\000b0J\035 )\033mw!\000h0@b (\014\004\0018u|\021z\007\033cc\000\017kg\024z\\\004\007}\011|v+4b\031z]eV\013\003v\027\016\021\033 7\037!W.&\033\037vMG[1\rH\0302\000a\034\016A+pp\003 \014F|\177[I[\0221ftjyOi4-F]\002Fy\031g\033|\"O\017\000/`\n\022\035D us%'*\\\032$\021o=eS6nSA|_U\005eDZnajBu\r\032@GR+\033G7:0\023]\033 @@0\010\000\0020@{f\006\011D\0260\004A@5(\020\014\023\001\025*3\0104`\013\003\000jP (&\004+\022*4\011D^0\026A@5(\020\026\023\023\025M\027\033\004@I7\035\014W\0239Bt4[mf\0130@S2\\NfK\rJ \\n6{\rRa:\032-vqD$0\010\001@5(\020\006\023\004Qj\002\002I^o:\010\006S\004\006\022\002@` \nh\001]rP\037\006\021\010q\0030\033cp:\022\017\027\027/@D\010H5]<\025,>\032+\023_XG\022Zg\024v<n\017fU\017L\024\007,`Im('\025LH8fKd\020>\025bO}P\000y\016XSap3p\026\023pX#:^JL\n^m\003QPo\0117x\006\\\007J])eC\022B\"~\035D(fN\036\004v]3Gxk\037-\003GP.\017U\032YFL\033Ldc,7b&Y\014\004\003\000@\000\023\004\010\003\035\030 1C\010,`\011\003\000jP \030&\002*Tf\020i@\026\006\001U @@L\010U:\030-\003\010\\`\025\003\000jP \034&\016)X-G!\001\030a5Y$\004\033%hy\030F\006\0010\030\006U\002\002B0zaFe9\035\004\004*h@b<H\010E\032Pb\030\030\005@`\032T\010\003\011Ck\006\033\025dt\020\021+\"\003\011r \"\024jC\011\004`\037\003\002%(2\"\rw\006@!\020\010X$c0P\014FK\035fi3]\016'+Mh.1[mS\004\010\002\n\001 @\020\010\002ZT\0147VK\177^[h:*]X[r\037Bj\035#-,\022s61?\021\036\177\022.aI>c[G\0054G\032'S`1\013wSu\016\031;D,\017w\r(\002w8\03540\0165\005\023A\003.' 6\n\011\032\016\177R\014(E\0270\025e*5mM\031E-r\036\016\031>VT/yE\013*T'\026iAm'\033C\022+h\024\035\0308j\011Z\010xDuh6\002\000{6\002??GQ}\177 \000E6h\0075\0301%\nij{2K\004\001\013f\016x|*\003F\r-\r\"W\032_)k\000\025L~`*I>6c:\017z\003zC~:9\006\004\005@|t\010.LEP%/qWx9gS\025\000\030\005\013|\014Y@sWVm9X-g0!nnG\034O2\022C17W\026T\035rV9\\p,\034oc2\023N\030C3\005\034tvy_k\r:>\035\032%kU-+:)\024%\r}$|w\034 \030\004\000\001\030 @\024Y@v1\020L\003p0\r*\004\005\004c\005C\rJr:\010\011\026sQJr7\030.FK=\\a6\010\011\026s\014\\1\013\014\002@0\r*\004\005DaUC\rJr:\010\n&{=h !P&\010\020\004\024\002A\000 \020\005\"haEG#CtAvp\031\020\rXh[\02450X6^\027l+Iz\010+h\010o\036\"N+\025;[\003! \031wB\025\030h\022\017\035FB:NR\017L,=eU\025&EBTN]\\yR;!\001;w\017\025`VWD\004\022;-$jc]A($\031\011\177?8\027Z2E\025*(\020\022r4L>O?\036P\005\000hF^r\023\002 S '\013+\000djz\r1LTL\010SB\037.t\0142'\026cooEFK0YpZ?UH\030>Q\"^(8\021K\006E\020\0043Vrj\024(ZLun jDW;/I~\006\034 IWlH=hj~Y\002J\035R\032\nD1J}\030YA\024=\r\025[&=d\036\004}l\005\005Aj ox&\022-[\"\033a\007#wN`2W\"M6`Of:\020BO92`f)/\033U\014S&E>G\001HUoEL9*RCEQ\022bKh@@0\010\000\0020@sF\004\001DB0\017A@5(\020\024\023\014\026\0146+Ih $[NF+I\\a:\032-vs\005X $[L2qD60\014A@5(\020\026\023\011\026\0146+Ih )\033mw!\001\006A\020\014&\003\021Pa\001D@P\030\010\003->\033b\"\032M\013nG\026\nYvP\000Le\024\021\024HW\023= !U3\024#.xn\\1yl3\016mSt\033xYA,I\021\\'T+SE\021^\032\010\004\027V[%EDLTXN\0339\005B\025\036)r#[L\"-@o|;\011N,k3vg$DX`Ob@R\016\001\007\014TJ\016\031 \017HV\006\034+\010jU#q\030\026w2D\016)\034WI\016K\031a\001\027\016\023+he{k\001\000`\020\000\004a\002\000SF\003qDB0\017A@5(\020\024\023\014\026\0146+Ih $[NF+I\\a:\032-vs\005X $[L2qD20\013A@5(\020\026\023\010\026\0146+Ih )\033mw!\001\006A\020\035F\023\004\010\002\n\001 @\020\010\003\003\022U|Vc)X\004H\007a>Dq>\004efR\027k\r\\{3=kW#\021R\014<L/\177\013\005wwBf=A\0319a9\rRHin\016\"\011fH\031nC]\017lnLJq|\030\037%\027(Aip&.=2|\017\036sG\032,J\035:bV\177\035Ef!L`{\02055OJJ'\026< &#j#\rU|8C`\030|v]dg\013Dva\"\007tK)\"\016O\003p]LGf`2dI[0!&fE\032j\034u'\017{GH\031UX6\035\004\027\036sJ\007\006\036o\023\004j\033\001x.\011ar\026f_\004#\027yoQH\177\032[u&\030[J\031z5#9\0178Z+3\023p\001U<\0061\025}mvA3\001~p\\p\001b:F\024a|^!^jU|\034c\027ci\027\020C#\036B~(\036j xx\006?4\002P\0307/iw,r\1771\020/(R&b\025]\021M${` \030\004\000\001\030 :\023\002\014b!\030\007``\032T\010\n\011F\013\006\033\025dt\020\022-g#\025dn0]\r\026{9Bl\020\022-f\0318b\036\030\007\000`\032T\010\013\011E+\006\033\025dt\020\024Mv{P@C H\016c\011\000b0\031\r\006\010\014$\005\001@@\024pN\017%)S\006.\016a'RE=M\\\016Q{\023\0318\020\032\0333\003i]\021qk\027Lt=%_\r,0\007\033\000.6\020\n>6ElFxh\0318\032\025)\030\014so9Qcpt\031LgzI\024@(\023\027%\007\n\032\014 \036L\005:_\031\033z\037zHD\0023vsj7\022g'Q\035d5\007#9=\001x0pp\016;06Dw=<#\017B)bqO>\025\007/yExU\0179wh\010\006\001\000\000&\010\020\005T0-\014!3\000$\014\003*A\000a\030\011.W\030DF\001\000\030\006U\002\002B0K\011JT)\025*5#\025H1\rL\003\0200\r*\004\001Db&\023\025(R*TjF+\020@R7[nB\002\r\002s\030FF\001@\030\006U\002\000b1\013\011JT)\025*5#\025H )\033mw!\001\006A\030 @\020P\n\004\001\000@\032K#Mt\023\005\016\nP\rz\022Vpe\023m%y5k%\r\016Q[\004SDpk!\006\001\005pH\177m\032\017Ry\003\r0Q\020~G7\022X}?\0229V}\037j\037\r/_AMufxuyVz%\026='K-`t\014t\030<\035t<\177\037hM9v\023#Xh;>JTyr\004_\005O\037\011\n&`2\034e,q.\037{\010\023\017U11|c\002@s%5g\003xUe?Q%vw\007\"_b?\005@dgVTd\023\034@r-4k|\014,$m>c~\031\007 c8fqpE3M\007_%<9\rr\033->i\002fgM-\014\034X]_\011\032\177|tv\000d\022s{]M\177~.0:;1T<;W4aQ\034j:1~V!z\027\013eZ}zAe|k_o\0116IoC\021Az\031\001\\\\q\0017R,CN\031n1<C0\0117\030uDUXGD\000h5Z'\023\n\002\001@ \000\017\177\177\177";
+ static {
+ try {
+ org.ibex.net.SSL.addCompactCAKeys(new java.io.ByteArrayInputStream(unpack(DATA)));
+ } catch(Exception e) {
+ System.err.println("Error loading root CA keys: " + e.getMessage());
+ }
+ }
+ public static void load() { /* force clinit */ }
+ private static byte[] unpack(String s) {
+ int len = s.length();
+ if(len % 8 != 0) throw new IllegalArgumentException("not a multiple of 8");
+ byte[] ret = new byte[(len / 8) * 7];
+ for(int i=0; i<len; i += 8) {
+ long l = 0;
+ for(int j=0;j<8;j++) {
+ l <<= 7;
+ l |= (s.charAt(i + j) & 0x7fL);
+ }
+ int base = (i / 8) * 7;
+ for(int j=6; j>=0; j--) {
+ ret[base + j] = (byte)(l & 0xff);
+ l >>>= 8;
+ }
+ }
+ return ret;
+ }}
--- /dev/null
+package org.ibex.net.ssl;
+
+import javax.swing.*;
+
+import java.awt.*;
+
+import org.ibex.net.SSL;
+import org.ibex.crypto.*;
+
+public class SwingVerifyCallback extends JDialog implements SSL.VerifyCallback {
+ private Component owner;
+
+ public SwingVerifyCallback(Component owner) {
+ this.owner = owner;
+ }
+ /*
+ super(owner,"Certificate Verification",true);
+ setModal(true);
+
+ JTextPane tp = new JTextPane();
+ doc = tp.getStyledDocument();
+ JScrollPane sp = new JScrollPane();
+ sp.setPreferredSize(new Dimension(400,300));
+ sp.setViewportView(tp);
+ sp.setAutoscrolls(false);
+
+ this.setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE);
+ JComponent bottom = new JPanel(new FlowLayout(FlowLayout.RIGHT));
+ JButton accept = new JButton("Accept");
+ JButton reject = new JButton("Reject");
+ accept.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) {
+ accepted = true;
+ hide();
+ }});
+ reject.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) {
+ accepted = false;
+ hide();
+ }});
+ bottom.add(accept);
+ bottom.add(reject);
+ getContentPane().add(BorderLayout.CENTER,sp);
+ getContentPane().add(BorderLayout.SOUTH,bottom);
+ pack();
+ }*/
+
+ public static String prettyFingerprint(byte[] fp) {
+ StringBuffer sb = new StringBuffer(fp.length*3);
+ for(int i=0;i<fp.length;i++) {
+ if(i>0) sb.append(":");
+ sb.append("0123456789abcdef".charAt((fp[i] & 0xf0) >>> 4));
+ sb.append("0123456789abcdef".charAt((fp[i] & 0x0f) >>> 0));
+ }
+ return sb.toString();
+ }
+
+ public synchronized boolean checkCerts(X509.Certificate[] certs, String hostname, SSL.Exn exn) {
+ final boolean[] ret = new boolean[1];
+ JTextArea ta = new JTextArea();
+ ta.append("Subject: " + certs[0].subject + "\n");
+ ta.append("Issuer: " + certs[0].issuer + "\n");
+ ta.append("Start Date: " + certs[0].startDate + "\n");
+ ta.append("End Date: " + certs[0].endDate + "\n");
+ ta.append("MD5: " + prettyFingerprint(certs[0].getMD5Fingerprint()) + "\n");
+ ta.append("SHA1: " + prettyFingerprint(certs[0].getSHA1Fingerprint()) + "\n");
+ ta.setEditable(false);
+ ta.setOpaque(false);
+ JScrollPane sp = new JScrollPane(ta);
+ sp.setPreferredSize(new Dimension(300,150));
+ final Object[] messages = new Object[] {
+ "The SSL Certificate the server presented could not be verified.",
+ exn.getMessage(),
+ sp,
+ };
+ Runnable r = new Runnable() { public void run() {
+ int n = JOptionPane.showOptionDialog(
+ owner,
+ messages,
+ "Confirm Server Certificate",
+ 0,
+ JOptionPane.WARNING_MESSAGE,
+ null,
+ new Object[] { "Accept", "Reject" },
+ "Accept");
+ ret[0] = n == 0;
+
+ } };
+ if(SwingUtilities.isEventDispatchThread()) {
+ r.run();
+ } else {
+ try {
+ SwingUtilities.invokeAndWait(r);
+ } catch(Exception e) {
+ e.printStackTrace();
+ }
+ }
+ return ret[0];
+ }
+
+}
--- /dev/null
+package org.ibex.net.ssl;
+
+import org.ibex.net.SSL;
+import java.io.*;
+
+public class Test {
+ public static void main(String[] args) throws Exception {
+ SSL.debugOn = true;
+ if(args.length < 2) { System.err.println("Usage: SSL host port"); }
+ String host = args[0];
+ int port = Integer.parseInt(args[1]);
+ SSL ssl = new SSL(host,port);
+ //ssl.setTLS(false);
+ ssl.getOutputStream().write(SSL.getBytes("GET / HTTP/1.0\r\nHost: " + host + "\r\n\r\n"));
+ cat(ssl.getInputStream());
+ ssl.close();
+
+ // try to resume
+ ssl = new SSL(host,port,ssl.getSessionState());
+ ssl.getOutputStream().write(SSL.getBytes("GET / HTTP/1.0\r\nHost: " + host + "\r\n\r\n"));
+ cat(ssl.getInputStream());
+ ssl.close();
+ }
+ private static void cat(InputStream is) throws IOException {
+ BufferedReader br = new BufferedReader(new InputStreamReader(is));
+ String line;
+ int count = 100;
+ try {
+ while((line = br.readLine()) != null && --count >= 0) System.out.println(line);
+ } catch(SSL.PrematureCloseExn e) { /* ignore */ }
+ }
+}