libcvd-members
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[libcvd-members] gvars3 Makefile.in src/GUI_language.cc


From: Edward Rosten
Subject: [libcvd-members] gvars3 Makefile.in src/GUI_language.cc
Date: Thu, 21 Feb 2008 19:29:21 +0000

CVSROOT:        /cvsroot/libcvd
Module name:    gvars3
Changes by:     Edward Rosten <edrosten>        08/02/21 19:29:21

Modified files:
        .              : Makefile.in 
Added files:
        src            : GUI_language.cc 

Log message:
        A few basic language constructs. This is an excellent illustration as 
to 
        why language design should be left to computer scientists.
        
        Examples:
        
        function foo
        . echo hello
        . echo world
        . a=4
        endfunction
        
        foo
        
        if_equal a 4
        . echo yes, a is 4
        else
        . echo dang
        . if_equal a 3
        . . echo OK, a is 3
        . endif
        endif
        
        Bear in mind that . is simply a perfectly normal registered command.
        
        Essentially, "function" is a command that says "rember stuff"
        "." shoves a line in to a list of lines from the last rememberes point
        "endfunction" then saves the remembered stuff permenantly and registeres
        a command to ParseLine it one line at a time.
        
        if is similar.
        
        Now imagine what happens if you interleave scoping bits. Or how the 
quoting 
        works (how many times is a particular line evaluated...?)
        
        It's thread safe, although some bits of GUI it calls aren't.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gvars3/Makefile.in?cvsroot=libcvd&r1=1.23&r2=1.24
http://cvs.savannah.gnu.org/viewcvs/gvars3/src/GUI_language.cc?cvsroot=libcvd&rev=1.1

Patches:
Index: Makefile.in
===================================================================
RCS file: /cvsroot/libcvd/gvars3/Makefile.in,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -b -r1.23 -r1.24
--- Makefile.in 21 Feb 2008 14:34:08 -0000      1.23
+++ Makefile.in 21 Feb 2008 19:29:21 -0000      1.24
@@ -81,6 +81,7 @@
        src/GUI.o                               \
        src/GStringUtil.o               \
        src/gvars2.o                    \
+       src/GUI_language.o              \
        src/serialize.o                 \
        src/GUI_none.o                  \
        src/inst.o                              \
@@ -90,6 +91,7 @@
        src/GUI.o                               \
        src/GStringUtil.o               \
        src/gvars2.o                    \
+       src/GUI_language.o              \
        src/serialize.o                 \
        src/@address@hidden          \
        src/GUI_non_readline.o  \

Index: src/GUI_language.cc
===================================================================
RCS file: src/GUI_language.cc
diff -N src/GUI_language.cc
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ src/GUI_language.cc 21 Feb 2008 19:29:21 -0000      1.1
@@ -0,0 +1,245 @@
+/*                       
+       This file is part of the GVars3 Library.
+
+       Copyright (C) 2005 The Authors
+
+       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., 
+    51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+#include "gvars3/instances.h"
+#include "gvars3/GStringUtil.h"
+#include <vector>
+#include <iostream>
+#include <set>
+#include <pthread.h>
+
+using namespace std;
+
+namespace GVars3
+{
+
+       template<class C> class ThreadLocal
+       {
+               private:
+                       pthread_key_t key;
+
+                       static void deleter(void* v)
+                       {
+                               delete static_cast<C*>(v);
+                       }
+               
+               public:
+                       ThreadLocal()
+                       {
+                               pthread_key_create(&key, deleter);
+                               pthread_setspecific(key, new C);
+                       }
+
+                       ~ThreadLocal()
+                       {
+                               deleter(pthread_getspecific(key));
+                               pthread_setspecific(key, 0);
+                               pthread_key_delete(key);
+                       }
+
+
+                       C& operator()()
+                       {
+                               return 
*static_cast<C*>(pthread_getspecific(key));
+                       }
+       };
+
+       template<class A, class B> class MutexMap
+       {
+               private:
+                       map<A, B> _map;
+                       pthread_mutex_t mutex;
+
+               public:
+                       MutexMap()
+                       {
+                               pthread_mutex_init(&mutex, 0);
+                       }
+
+                       ~MutexMap()
+                       {
+                               pthread_mutex_destroy(&mutex);
+                       }
+
+                       B get(const A& a)
+                       {
+                               B b;
+                               pthread_mutex_lock(&mutex);
+                               b = _map[a];
+                               pthread_mutex_unlock(&mutex);
+                               return b;
+                       }
+
+                       void set(const A&a, const B& b)
+                       {
+                               pthread_mutex_lock(&mutex);
+                               _map[a] = b;
+                               pthread_mutex_unlock(&mutex);
+                       }
+       };
+
+
+       class GUI_language
+       {
+               
+               public:
+                       GUI_language()
+                       {
+                               GUI.RegisterCommand(".", collect_lineCB, this);
+                               GUI.RegisterCommand("function", functionCB, 
this);
+                               GUI.RegisterCommand("endfunction", 
endfunctionCB, this);
+                               GUI.RegisterCommand("if_equal", gui_if_equalCB, 
this);
+                               GUI.RegisterCommand("else", gui_if_elseCB, 
this);
+                               GUI.RegisterCommand("endif", gui_endifCB, this);
+                       }
+
+
+                       ~GUI_language()
+                       {
+                       }
+
+
+               private:
+                       pthread_mutex_t  functionlist_mutex;
+
+                       ThreadLocal<string> current_function, if_gvar, 
if_string;
+                       ThreadLocal<vector<string> > collection, ifbit, elsebit;
+                       MutexMap<string, vector<string> > functions;
+
+                       static GUI_language& C(void* v)
+                       {
+                               return *static_cast<GUI_language*>(v);
+                       }
+
+                       
+                       #define CallBack(X) static void X##CB(void* t, string 
a, string b){C(t).X(a, b);} 
+
+                       CallBack(collect_line);
+                       void collect_line(string, string l)
+                       {
+                               collection().push_back(l);
+                       }
+
+
+                       
+                       CallBack(function);
+                       void function(string name, string args)
+                       {
+
+                               vector<string> vs = ChopAndUnquoteString(args);
+                               if(vs.size() != 1)
+                               {
+                                       cerr << "Error: " << name << " takes 1 
argument: " << name << " name\n";
+                                       return;
+                               }
+
+                               current_function()=vs[0];
+                               collection().clear();
+                       }
+
+                       CallBack(endfunction)
+                       void endfunction(string name, string args)
+                       {
+                               if(current_function() == "")
+                               {
+                                       cerr << "Error: " << name << ": no 
current function.\n";
+                                       return;
+                               }
+
+                               vector<string> vs = ChopAndUnquoteString(args);
+                               if(vs.size() != 0)
+                                       cerr << "Warning: " << name << " takes 
0 arguments.\n";
+
+                               functions.set(current_function(), collection());
+
+                               GUI.RegisterCommand(current_function(), 
runfuncCB, this);
+
+                               current_function().clear();
+                               collection().clear();
+                       }
+                       
+                       CallBack(runfunc)
+                       void runfunc(string name, string args)
+                       {
+                               vector<string> v = functions.get(name);
+                               for(unsigned int i=0; i < v.size(); i++)
+                                       GUI.ParseLine(v[i]);
+                       }
+
+
+                       CallBack(gui_if_equal)
+                       void gui_if_equal(string name, string args)
+                       {
+                               vector<string> vs = ChopAndUnquoteString(args);
+                               if(vs.size() != 2)
+                               {
+                                       cerr << "Error: " << name << " takes 2 
arguments: " << name << " gvar string\n";
+                                       return;
+                               }
+
+                               collection().clear();
+                               if_gvar() = vs[0];
+                               if_string() = vs[1];
+                       }
+
+
+                       CallBack(gui_if_else)
+                       void gui_if_else(string name, string args)
+                       {
+                               ifbit() = collection();
+                               if(ifbit().empty())
+                                       ifbit().push_back("");
+                               collection().clear();
+                       }
+                       
+                       CallBack(gui_endif)
+                       void gui_endif(string name, string args)
+                       {
+                               if(ifbit().empty())
+                                       ifbit() = collection();
+                               else 
+                                       elsebit() = collection();
+
+                               collection().clear();
+                               
+                               //Save a copy, since it canget trashed
+                               vector<string> ib = ifbit(), eb = elsebit();
+                               string gv = if_gvar(), st = if_string();
+
+                               ifbit().clear();
+                               elsebit().clear();
+                               if_gvar().clear();
+                               if_string().clear();
+
+                               if(GV3::get_var(gv) == st)
+                                       for(unsigned int i=0; i < ib.size(); 
i++)
+                                               GUI.ParseLine(ib[i]);
+                               else
+                                       for(unsigned int i=0; i < eb.size(); 
i++)
+                                               GUI.ParseLine(eb[i]);
+                       }
+
+
+
+       };
+               
+       GUI_language GUI_language_instance;
+
+}




reply via email to

[Prev in Thread] Current Thread [Next in Thread]