summaryrefslogtreecommitdiff
path: root/Build/source/utils/asymptote/main.cc
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2009-05-16 00:19:13 +0000
committerKarl Berry <karl@freefriends.org>2009-05-16 00:19:13 +0000
commitbab45528d65eaafe68a705dbb2a57075c7b7cbd8 (patch)
tree10b4ae2b5195c8dede153ab89359ec00f55f325f /Build/source/utils/asymptote/main.cc
parent8643d90372e9c31e0f461c15c596b60a545bd7d3 (diff)
asymptote 1.72 sources (not integrated into build yet)
git-svn-id: svn://tug.org/texlive/trunk@13110 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/utils/asymptote/main.cc')
-rw-r--r--Build/source/utils/asymptote/main.cc196
1 files changed, 196 insertions, 0 deletions
diff --git a/Build/source/utils/asymptote/main.cc b/Build/source/utils/asymptote/main.cc
new file mode 100644
index 00000000000..f5ea21128e5
--- /dev/null
+++ b/Build/source/utils/asymptote/main.cc
@@ -0,0 +1,196 @@
+/************
+*
+* This file is part of the vector graphics language Asymptote
+* Copyright (C) 2004 Andy Hammerlindl, John C. Bowman, Tom Prince
+* http://asymptote.sourceforge.net
+*
+* This program 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 3 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 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, see <http://www.gnu.org/licenses/>.
+*
+*************/
+
+#include <iostream>
+#include <csignal>
+#include <cstdlib>
+#include <cerrno>
+#include <sys/wait.h>
+#include <sys/types.h>
+
+#include "common.h"
+
+#ifdef HAVE_LIBSIGSEGV
+#include <sigsegv.h>
+#endif
+
+#include "errormsg.h"
+#include "fpu.h"
+#include "settings.h"
+#include "locate.h"
+#include "interact.h"
+#include "process.h"
+
+#include "stack.h"
+
+using namespace settings;
+
+errorstream em;
+using interact::interactive;
+
+namespace run {
+void purge();
+}
+
+#ifdef HAVE_LIBSIGSEGV
+void stackoverflow_handler (int, stackoverflow_context_t)
+{
+ em.runtime(vm::getPos());
+ cerr << "Stack overflow" << endl;
+ abort();
+}
+
+int sigsegv_handler (void *, int emergency)
+{
+ if(!emergency) return 0; // Really a stack overflow
+ em.runtime(vm::getPos());
+ if(gl::glthread)
+ cerr << "Stack overflow or segmentation fault: rerun with -nothreads"
+ << endl;
+ else
+ cerr << "Segmentation fault" << endl;
+ abort();
+}
+#endif
+
+void setsignal(RETSIGTYPE (*handler)(int))
+{
+#ifdef HAVE_LIBSIGSEGV
+ char mystack[16384];
+ stackoverflow_install_handler(&stackoverflow_handler,
+ mystack,sizeof (mystack));
+ sigsegv_install_handler(&sigsegv_handler);
+#endif
+ signal(SIGBUS,handler);
+ signal(SIGFPE,handler);
+}
+
+void signalHandler(int)
+{
+ // Print the position and trust the shell to print an error message.
+ em.runtime(vm::getPos());
+
+ signal(SIGBUS,SIG_DFL);
+ signal(SIGFPE,SIG_DFL);
+}
+
+void interruptHandler(int)
+{
+ em.Interrupt(true);
+}
+
+// Run the config file.
+void doConfig(string file)
+{
+ bool autoplain=getSetting<bool>("autoplain");
+ bool listvariables=getSetting<bool>("listvariables");
+ if(autoplain) Setting("autoplain")=false; // Turn off for speed.
+ if(listvariables) Setting("listvariables")=false;
+
+ runFile(file);
+
+ if(autoplain) Setting("autoplain")=true;
+ if(listvariables) Setting("listvariables")=true;
+}
+
+struct Args
+{
+ int argc;
+ char **argv;
+ Args(int argc, char **argv) : argc(argc), argv(argv) {}
+};
+
+void *asymain(void *A)
+{
+ setsignal(signalHandler);
+
+ Args *args=(Args *) A;
+ fpu_trap(trap());
+
+ if(interactive) {
+ signal(SIGINT,interruptHandler);
+ processPrompt();
+ } else if (getSetting<bool>("listvariables") && numArgs()==0) {
+ try {
+ doUnrestrictedList();
+ } catch(handled_error) {
+ em.statusError();
+ }
+ } else {
+ int n=numArgs();
+ if(n == 0)
+ processFile("-");
+ else
+ for(int ind=0; ind < n; ind++) {
+ processFile(string(getArg(ind)),n > 1);
+ try {
+ if(ind < n-1)
+ setOptions(args->argc,args->argv);
+ } catch(handled_error) {
+ em.statusError();
+ }
+ }
+ }
+
+ if(getSetting<bool>("wait")) {
+ int status;
+ while(wait(&status) > 0);
+ }
+ exit(em.processStatus() || interact::interactive ? 0 : 1);
+}
+
+int main(int argc, char *argv[])
+{
+ setsignal(signalHandler);
+
+ try {
+ setOptions(argc,argv);
+ } catch(handled_error) {
+ em.statusError();
+ }
+
+ Args args(argc,argv);
+#ifdef HAVE_LIBGL
+ gl::glthread=getSetting<bool>("threads");
+#ifdef HAVE_LIBPTHREAD
+
+ if(gl::glthread) {
+ pthread_t thread;
+ try {
+ if(pthread_create(&thread,NULL,asymain,&args) == 0) {
+ gl::mainthread=pthread_self();
+ while(true) {
+ gl::endwait(gl::readySignal,gl::readyLock);
+ gl::endwait(gl::quitSignal,gl::quitLock);
+ gl::wait(gl::initSignal,gl::initLock);
+ camp::glrenderWrapper();
+ gl::initialize=true;
+ }
+ }
+ } catch(std::bad_alloc&) {
+ outOfMemory();
+ }
+ }
+#endif
+ gl::glthread=false;
+#endif
+ asymain(&args);
+}