changeset 53:fbabd1957c89

Merge
author daveb
date Fri, 06 Aug 2010 09:38:36 +0930
parents 4dadc3c03b7e (diff) 576b9fba4677 (current diff)
children 30ecedfe2ce2
files
diffstat 6 files changed, 152 insertions(+), 262 deletions(-) [+]
line wrap: on
line diff
--- a/doodle/core/backtrace.d	Thu Aug 05 22:49:41 2010 +0930
+++ b/doodle/core/backtrace.d	Fri Aug 06 09:38:36 2010 +0930
@@ -12,201 +12,19 @@
 //
 
 private {
-    import core.sys.posix.unistd;
-    import core.sys.posix.fcntl;
-    import core.sys.posix.sys.stat;
-    import core.sys.posix.sys.mman;
-
-    import core.stdc.string;
-    import core.stdc.signal;
-
-    import core.runtime;
-
-    import std.stdio;
-    import std.string;
-    import std.demangle;
-    import std.algorithm;
-
-    immutable int EI_NIDENT  = 16;
-
-    immutable int SHT_SYMTAB = 2;
-    immutable int SHT_STRTAB = 3;
-
-    immutable int STT_FUNC   = 2;
-
-    alias ushort Elf32_Half;
-    alias uint   Elf32_Word;
-    alias uint   Elf32_Addr;
-    alias uint   Elf32_Off;
-    alias ushort Elf32_Section;
-
-    struct Elf32_Ehdr {
-        ubyte[EI_NIDENT] e_ident;             /* Magic number and other info */
-        Elf32_Half    e_type;                 /* Object file type */
-        Elf32_Half    e_machine;              /* Architecture */
-        Elf32_Word    e_version;              /* Object file version */
-        Elf32_Addr    e_entry;                /* Entry point virtual address */
-        Elf32_Off     e_phoff;                /* Program header table file offset */
-        Elf32_Off     e_shoff;                /* Section header table file offset */
-        Elf32_Word    e_flags;                /* Processor-specific flags */
-        Elf32_Half    e_ehsize;               /* ELF header size in bytes */
-        Elf32_Half    e_phentsize;            /* Program header table entry size */
-        Elf32_Half    e_phnum;                /* Program header table entry count */
-        Elf32_Half    e_shentsize;            /* Section header table entry size */
-        Elf32_Half    e_shnum;                /* Section header table entry count */
-        Elf32_Half    e_shstrndx;             /* Section header string table index */
-    };
-
-    struct Elf32_Shdr {
-        Elf32_Word    sh_name;                /* Section name (string tbl index) */
-        Elf32_Word    sh_type;                /* Section type */
-        Elf32_Word    sh_flags;               /* Section flags */
-        Elf32_Addr    sh_addr;                /* Section virtual addr at execution */
-        Elf32_Off     sh_offset;              /* Section file offset */
-        Elf32_Word    sh_size;                /* Section size in bytes */
-        Elf32_Word    sh_link;                /* Link to another section */
-        Elf32_Word    sh_info;                /* Additional section information */
-        Elf32_Word    sh_addralign;           /* Section alignment */
-        Elf32_Word    sh_entsize;             /* Entry size if section holds table */
-    };
-
-    struct Elf32_Sym {
-        Elf32_Word    st_name;                /* Symbol name (string tbl index) */
-        Elf32_Addr    st_value;               /* Symbol value */
-        Elf32_Word    st_size;                /* Symbol size */
-        ubyte         st_info;                /* Symbol type and binding */
-        ubyte         st_other;               /* Symbol visibility */
-        Elf32_Section st_shndx;               /* Section index */
-    };
-
-    extern (C) int backtrace(void**, size_t);
-
-    struct Symbol {
-        this(void * a, size_t s, char * n) {
-            address = a;
-            size = s;
-            name = n;
-        }
-        void * address;
-        size_t size;
-        char * name;
-        void * end_address() { return address + size; }
-    };
-
-    // Newton-Raphson
-    Symbol nr_lookup(Symbol[] symbols, void * addr, int depth = 0) {
-        if (symbols.length == 0 ||
-            addr < symbols[0].address ||
-            addr >= symbols[$-1].end_address)
-        {
-            throw new Exception("Symbol not found");
-        }
-        else if (symbols.length == 1) {
-            return symbols[0];
-        }
-        else {
-            void * begin_addr = symbols[0].address;
-            void * end_addr = symbols[$-1].end_address;
 
-            int i = ((addr - begin_addr) * symbols.length) / (end_addr - begin_addr);
-            if (!(depth % 2) && i < symbols.length - 1) { ++i; }        // Some wiggle to force convergence
-
-            if (addr < symbols[i].address) {
-                return nr_lookup(symbols[0..i], addr, depth + 1);
-            }
-            else {
-                return nr_lookup(symbols[i..$], addr, depth + 1);
-            }
-        }
-    }
-
-    int generate(void*[] addresses, scope int delegate(ref char[]) dg) {
-        static char[] get_exe() {
-            char buf[1024];
-            ssize_t s = readlink("/proc/self/exe", buf.ptr, buf.length);
-            if (s == -1) { throw new Exception(""); }
-            return buf[0..s];
-        }
-
-        int fd = open(toStringz(get_exe()), O_RDONLY);
-        if (fd == -1) { throw new Exception(""); }
-        scope(exit) close(fd);
-
-        stat_t st;
-        if (fstat(fd, &st) == -1) { throw new Exception(""); }
-
-        void * contents = mmap(null, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
-        if (!contents) { throw new Exception(""); }
-        scope(exit) munmap(contents, st.st_size);
-
-        Elf32_Ehdr * elf_hdr = cast(Elf32_Ehdr *)(contents);
-
-        Elf32_Shdr * sec_hdr = cast(Elf32_Shdr *)(contents + elf_hdr.e_shoff);
-
-        int symtab_idx = 0;
-        for (int i = 0; i < elf_hdr.e_shnum; ++i) {
-            if (sec_hdr[i].sh_type == SHT_SYMTAB) {
-                symtab_idx = i;
-                break;
-            }
-        }
-        if (symtab_idx == 0) { throw new Exception(""); }
-
-        int strtab_idx = sec_hdr[symtab_idx].sh_link;
-        if (strtab_idx == 0) { throw new Exception(""); }        // No associated string table
+    import core.stdc.signal;
+    import core.stdc.stdlib : free;
+    import core.stdc.string : strlen;
+    import core.runtime;
+    import std.demangle;
+    import std.string;
 
-        if (sec_hdr[strtab_idx].sh_type != SHT_STRTAB) { throw new Exception(""); } // invalid string table
-
-        Elf32_Sym * sym_ent = cast(Elf32_Sym *)(contents + sec_hdr[symtab_idx].sh_offset);
-        char * strtab = cast(char *)(contents + sec_hdr[strtab_idx].sh_offset);
-        int num_syms = sec_hdr[symtab_idx].sh_size / sec_hdr[symtab_idx].sh_entsize;
-
-        if (num_syms == 0) { throw new Exception(""); }      // No symbols
-
-        Symbol symbols[];
-
-        for (int i = 0; i < num_syms; ++i) {
-            if ((sym_ent[i].st_info & 0xf) != STT_FUNC) {
-                continue;
-            }
-
-            if (sym_ent[i].st_shndx == 0) {
-                continue;
-            }
-
-            void * address = cast(void *)(sym_ent[i].st_value);       // inclusive
-            size_t size    = sym_ent[i].st_size;
-            char * name    = strtab + sym_ent[i].st_name;
-
-            symbols ~= Symbol(address, size, name);
-        }
-
-        sort!("a.address < b.address")(symbols);
-
-        int ret;
-        foreach (address; addresses) {
-            string str = format("[0x%0.8x] ", address);
-            try {
-                Symbol symbol = nr_lookup(symbols, address);
-                char[] s1 = symbol.name[0..strlen(symbol.name)];
-                str ~= format("%s", demangle(s1.idup));
-            }
-            catch (Exception e) {
-                str ~= "<unknown>";
-            }
-            char[] cstr = str.dup;
-            ret = dg(cstr);
-            if (ret) {
-                break;
-            }
-        }
-
-        return ret;
-    }
-
+    extern (C) int    backtrace(void**, size_t);
+    extern (C) char** backtrace_symbols(void**, int);
 
     // signal handler for otherwise-fatal thread-specific signals 
-    extern (C) void arghh(int sig) {
+    extern (C) void signal_handler(int sig) {
         string name() {
             switch (sig) {
             case SIGSEGV: return "SIGSEGV";
@@ -222,40 +40,63 @@
 
     shared static this() {
         // set up shared signal handlers for fatal thread-specific signals
-        //writeln("setting up shared signal handlers for ABRT, FPE, ILL, SEGV");
-        signal(SIGABRT, &arghh);
-        signal(SIGFPE,  &arghh);
-        signal(SIGILL,  &arghh);
-        signal(SIGSEGV, &arghh);
+        signal(SIGABRT, &signal_handler);
+        signal(SIGFPE,  &signal_handler);
+        signal(SIGILL,  &signal_handler);
+        signal(SIGSEGV, &signal_handler);
     }
 
     static this() {
         // register our trace handler for each thread
-        //writeln("installing our traceHandler");
         Runtime.traceHandler = &traceHandler;
     }
 
-    // Captures backtrace info at the point of construction, stripping
-    // off the bits that concern itself and the ininteresting early stuff.
-    // Also provides opApply to traverse a nice text representation of the backtrace.
-    class TraceInfo : Throwable.TraceInfo {
-        void*[256] callstack;
-        int numframes;
-
-        this() {
-            numframes = backtrace(callstack.ptr, callstack.length);
-        }
-
-        override string toString() const {
-            return "Why does dmd require an override of this?";
-        }
-
-        override int opApply(scope int delegate(ref char[]) dg) {
-            return generate(callstack[4..numframes-5], dg);
-        }
-    }
-
     Throwable.TraceInfo traceHandler(void * ptr = null) {
         return new TraceInfo;
     }
+
+    class TraceInfo : Throwable.TraceInfo {
+        this() {
+            immutable MAXFRAMES = 128;
+            void*[MAXFRAMES] callstack;
+
+            numframes = backtrace(callstack.ptr, MAXFRAMES);
+            framelist = backtrace_symbols(callstack.ptr, numframes);
+        }
+
+        ~this() {
+            free(framelist);
+        }
+
+        override string toString() const { return null; }   // Why does toString require overriding?
+
+        override int opApply(scope int delegate(ref char[]) dg) {
+            // NOTE: The first 5 frames with the current implementation are
+            //       inside core.runtime and the object code, so eliminate
+            //       these for readability.
+            immutable FIRSTFRAME = 5;
+            int ret = 0;
+
+            for(int i = FIRSTFRAME; i < numframes; ++i) {
+                char[] text = framelist[i][0 .. strlen(framelist[i])];
+
+                int a = text.lastIndexOf('(');
+                int b = text.lastIndexOf('+');
+
+                if (a != -1 && b != -1) {
+                    ++a;
+                    text = format("%s%s%s", text[0..a], demangle(text[a..b].idup), text[b..$]).dup;
+                }
+
+                ret = dg(text);
+                if (ret)
+                    break;
+            }
+            return ret;
+        }
+
+    private:
+        int    numframes; 
+        char** framelist;
+    }
 }
--- a/doodle/core/logging.d	Thu Aug 05 22:49:41 2010 +0930
+++ b/doodle/core/logging.d	Fri Aug 06 09:38:36 2010 +0930
@@ -31,7 +31,7 @@
     mixin(defineEnum!("Severity",
                       "TRACE", "INFO", "MESSAGE", "WARNING", "ERROR", "FATAL"));
 
-    string mod_string(in Severity s) {
+    string severityString(in Severity s) {
         switch (s) {
         case Severity.TRACE:
             return modifierString(Modifier.DIM) ~ fgColorString(Color.CYAN);
@@ -52,7 +52,7 @@
     }
 
     void log(in Severity severity, in string message) {
-        write(mod_string(severity));
+        write(severityString(severity));
         write(message);
         writeln(modifierString(Modifier.RESET));
     }
@@ -78,11 +78,11 @@
         WHITE   = 7
     }
 
-    string modifierString(Modifier m) { return std.string.format("\033[%dm", 0 + m); }
-    string fgColorString(Color c)    { return std.string.format("\033[%dm", 30 + c); }
-    string bgColorString(Color c)    { return std.string.format("\033[%dm", 40 + c); }
+    string modifierString(in Modifier m) { return std.string.format("\033[%dm", 0 + m); }
+    string fgColorString(in Color c)     { return std.string.format("\033[%dm", 30 + c); }
+    string bgColorString(in Color c)     { return std.string.format("\033[%dm", 40 + c); }
 
-    private const(char)[] right(in char[] str, int n) {
+    private string right(in string str, in int n) {
         int pos = str.length < n ? 0 : str.length - n;
         return str[pos..$];
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doodle/gtk/palette.d	Fri Aug 06 09:38:36 2010 +0930
@@ -0,0 +1,61 @@
+module doodle.gtk.palette;
+
+public {
+    import doodle.tk.palette;
+    import gtk.Toolbar;
+}
+
+private {
+    import gtk.ToolButton;
+    import glib.ListSG;
+    import std.stdio;
+    import gtk.RadioToolButton;
+    import gtk.Image;
+}
+
+class Palette : Toolbar, IPalette {
+    this() {
+        setIconSize(GtkIconSize.LARGE_TOOLBAR);
+        setStyle(GtkToolbarStyle.ICONS);
+        setOrientation(GtkOrientation.HORIZONTAL);
+        setTooltips(true);
+    }
+
+    //void set(
+
+    int add(in string iconPath, in string tooltipText, void delegate(int) dg) {
+        auto button = new RadioToolButton(_group);
+        auto image = new Image(iconBase ~ "/" ~ iconPath);
+        button.setLabelWidget(image);
+        int * i = new int;
+        *i = _delegates.length;
+        _delegates[*i] = dg;
+        button.objectGSetDataFull(indexStr, cast(gpointer)i);
+        button.addOnClicked(&onClicked);
+        insert(button);
+        return *i;
+    }
+
+    void remove(in int id) {
+    }
+
+    void activate(in int id) {
+    }
+
+    private {
+        immutable iconBase = "/home/daveb/source/d/doodle/source/doodle/gtk/data";
+        immutable indexStr = "index";
+        ListSG _group;
+        void delegate(int) _delegates[int];
+
+        void onClicked(ToolButton tool_button) {
+            int * i = cast(int *)tool_button.getData(indexStr);
+            _delegates[*i](*i);
+        }
+
+        /*
+        ToolButton find(int index) {
+        }
+        */
+    }
+}
--- a/doodle/main/prog/doodler.d	Thu Aug 05 22:49:41 2010 +0930
+++ b/doodle/main/prog/doodler.d	Fri Aug 06 09:38:36 2010 +0930
@@ -10,6 +10,7 @@
 
     import doodle.gtk.canvas;
     import doodle.gtk.toolbar;
+    import doodle.gtk.palette;
 
     import gtk.Main;
     import gtk.MainWindow;
@@ -19,47 +20,39 @@
 }
 
 void main(string[] args) {
-    trace("Test trace");
+    Main.init(args);
+    auto window = new MainWindow("Doodle");
+    auto vbox = new VBox(false, 0);
     /+
-    trace("Test trace");
-    info("Test trace");
-    message("Test trace");
-    warning("Test trace");
-    error("Test trace");
-    fatal("Test trace");
+    auto toolBar = new ToolBar;
+    vbox.packStart(toolBar, false, false, 0);
     +/
 
-    trace("Test trace1");
-    Main.init(args);
-    trace("Test trace2");
-    auto window = new MainWindow("Doodle");
-    trace("Test trace3");
-    auto vbox = new VBox(false, 0);
-    trace("Test trace4");
-    auto toolBar = new ToolBar;
-    trace("Test trace5");
-    vbox.packStart(toolBar, false, false, 0);
+    auto palette = new Palette;
+    palette.add("select.svg", "tooltip-text", (int i){ writefln("Wow %s", i); });
+    palette.add("select.svg", "tooltip-text", (int i){ writefln("Wow %s", i); });
+    palette.add("select.svg", "tooltip-text", (int i){ writefln("Wow %s", i); });
+    palette.add("select.svg", "tooltip-text", (int i){ writefln("Wow %s", i); });
+    palette.add("select.svg", "tooltip-text", (int i){ writefln("Wow %s", i); });
+    vbox.packStart(palette, false, false, 0);
+
     Tool[] tools;
     tools ~= new PanTool;
     tools ~= new ZoomTool;
     tools ~= new LassoTool;
-    trace("Test trace4");
     auto toolLayer = new ToolLayer(tools, "Tools");
+
     auto gridLayer = new GridLayer("Grid");
+
     Layer[] layers;
-    trace("Test trace5");
     layers ~= new PageLayer("Page");
     layers ~= gridLayer;
     layers ~= toolLayer;
-    trace("Test trace6");
     auto canvas = new Canvas(layers, toolLayer, gridLayer, 120.0);
-    trace("Test trace7");
+
     vbox.packStart(canvas, true, true, 0);
-    trace("Test trace8");
     window.add(vbox);
-    trace("Test trace9");
     window.setDefaultSize(380, 380);
     window.showAll();
-    trace("Test trace8");
     Main.run();
 }
--- a/doodle/tk/geometry.d	Thu Aug 05 22:49:41 2010 +0930
+++ b/doodle/tk/geometry.d	Fri Aug 06 09:38:36 2010 +0930
@@ -24,15 +24,9 @@
 //
 
 struct Point {
-    static immutable Point DEFAULT;
-
-    static this() {
-        DEFAULT = Point(0.0, 0.0);
-    }
+    static immutable Point DEFAULT = Point(0.0, 0.0);
 
     this(in double x, in double y) {
-        assert(!isnan(x));
-        assert(!isnan(y));
         _x = x;
         _y = y;
     }
@@ -74,15 +68,9 @@
 //
 
 struct Vector {
-    static Vector DEFAULT;
-
-    static this() {
-        DEFAULT = Vector(0.0, 0.0);
-    }
+    static Vector DEFAULT = Vector(0.0, 0.0);
 
     this(in double x, in double y) {
-        assert(!isnan(x));
-        assert(!isnan(y));
         _x = x;
         _y = y;
     }
@@ -344,7 +332,7 @@
     }
 
     private {
-        Point _point;           // Arbitrary point along line
+        Point  _point;           // Arbitrary point along line
         Vector _gradient;
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doodle/tk/palette.d	Fri Aug 06 09:38:36 2010 +0930
@@ -0,0 +1,7 @@
+module doodle.tk.palette;
+
+interface IPalette {
+    int add(in string iconPath, in string tooltipText, void delegate(int) dg);
+    void remove(in int id);
+    void activate(in int id);
+}