Back to index

texmacs  1.0.7.15
texmacs.cpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : texmacs.cpp
00004 * DESCRIPTION: main program
00005 * COPYRIGHT  : (C) 1999  Joris van der Hoeven
00006 *******************************************************************************
00007 * This software falls under the GNU general public license version 3 or later.
00008 * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
00009 * in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
00010 ******************************************************************************/
00011 
00012 #include <sys/types.h>
00013 #include <sys/stat.h>
00014 #include <fcntl.h>
00015 #include <unistd.h>
00016 #include <locale.h> // for setlocale
00017 #include <signal.h>
00018 
00019 #include "boot.hpp"
00020 #include "file.hpp"
00021 #include "server.hpp"
00022 #include "timer.hpp"
00023 #include "data_cache.hpp"
00024 #include "tm_window.hpp"
00025 #ifdef AQUATEXMACS
00026 void mac_fix_paths ();
00027 #endif
00028 
00029 #ifdef QTTEXMACS
00030 #include "Qt/qt_utilities.hpp"
00031 #include <QApplication>
00032 #include <QDir>
00033 #endif
00034 
00035 #ifdef MACOSX_EXTENSIONS
00036 #include "MacOS/mac_utilities.h"
00037 #endif
00038 
00039 #if defined(X11TEXMACS) && defined(MACOSX_EXTENSIONS)
00040 #include "MacOS/mac_app.h"
00041 #endif
00042 
00043 extern bool   char_clip;
00044 extern bool   reverse_colors;
00045 
00046 extern url    tm_init_file;
00047 extern url    tm_init_buffer_file;
00048 extern string my_init_cmds;
00049 
00050 extern int geometry_w, geometry_h;
00051 extern int geometry_x, geometry_y;
00052 
00053 extern tree the_et;
00054 extern bool texmacs_started;
00055 
00056 tm_ostream& cout= tm_ostream::cout;
00057 tm_ostream& cerr= tm_ostream::cerr;
00058 
00059 /******************************************************************************
00060 * For testing
00061 ******************************************************************************/
00062 
00063 //#define ENABLE_TESTS
00064 #ifdef ENABLE_TESTS
00065 void
00066 test_routines () {
00067   extern void test_math ();
00068   test_math ();
00069 }
00070 #endif
00071 
00072 /******************************************************************************
00073 * Clean exit on segmentation faults
00074 ******************************************************************************/
00075 
00076 void 
00077 clean_exit_on_segfault (int sig_num) {
00078   FAILED ("segmentation fault");
00079 }
00080 
00081 /******************************************************************************
00082 * Texmacs paths
00083 ******************************************************************************/
00084 
00085 void
00086 TeXmacs_init_paths (int& argc, char** argv) {
00087   (void) argc; (void) argv;
00088 #ifdef QTTEXMACS
00089   url exedir = url_system (qt_application_directory ());
00090 #else
00091   url exedir = url_system(argv[0]) * ".." ;
00092   if (! is_rooted(exedir)) {
00093     exedir = url_pwd() * exedir ;
00094   }
00095 #endif
00096 
00097 #if (defined(QTTEXMACS) && defined(Q_WS_MAC)) 
00098   // the following line can inibith external plugin loading
00099   // QCoreApplication::setLibraryPaths(QStringList());
00100   // ideally we would like to control the external plugins
00101   // and add the most useful (gif, jpeg, svg converters)
00102   // to the bundle package. I still do not have a reliable solution
00103   // so just allow everything that is reachable.
00104        
00105   // plugins need to be installed in TeXmacs.app/Contents/Plugins     
00106        QCoreApplication::addLibraryPath( QDir::cleanPath(QCoreApplication::applicationDirPath().append("/../Plugins")) );
00107   // cout << from_qstring ( QCoreApplication::libraryPaths () .join("\n") ) << LF;
00108        {
00109     // ensure that private versions of the Qt frameworks have priority on
00110     // other instances.
00111     // in the event that we load qt plugins which could possibly link to
00112     // other instances of the Qt libraries
00113     string buf;
00114     buf = as_string(exedir * "../Frameworks");
00115     if (get_env("DYLD_FRAMEWORK_PATH") != "") buf = buf * ":" * get_env("DYLD_FRAMEWORK_PATH");    
00116     set_env ("DYLD_FRAMEWORK_PATH", buf);    
00117     buf = as_string(exedir * "../Resources/lib");
00118     if (get_env("DYLD_LIBRARY_PATH") != "") buf = buf * ":" * get_env("DYLD_LIBRARY_PATH");    
00119     set_env ("DYLD_LIBRARY_PATH", buf);    
00120   }
00121 #endif
00122 
00123 #if defined(AQUATEXMACS) ||(defined(QTTEXMACS) && defined(Q_WS_MAC)) || (defined(X11TEXMACS) && defined (MACOSX_EXTENSIONS))
00124   // Mac bundle environment initialization
00125   // We set some environment variables when the executable
00126   // is in a .app bundle on MacOSX
00127   if (get_env ("TEXMACS_PATH") == "")
00128     set_env ("TEXMACS_PATH", as_string(exedir * "../Resources/share/TeXmacs"));
00129   //cout << get_env("PATH") * ":" * as_string(url("$PWD") * argv[0]
00130   // * "../../Resources/share/TeXmacs/bin") << LF;
00131   if (exists("/bin/bash")) {
00132     string shell_env =  eval_system("PATH='' /bin/bash -l -c 'echo $PATH'");
00133     set_env ("PATH", get_env("PATH") * ":" * shell_env * ":" *
00134            as_string (exedir * "../Resources/share/TeXmacs/bin"));
00135   } else {
00136     set_env ("PATH", get_env("PATH") * ":" *
00137                as_string (exedir * "../Resources/share/TeXmacs/bin"));
00138   }
00139   // system("set");
00140 #endif
00141 
00142 #ifdef __MINGW32__
00143   // Win bundle environment initialization
00144   // TEXMACS_PATH is set by assuming that the executable is in TeXmacs/bin/
00145   // HOME is set to USERPROFILE
00146   // PWD is set to HOME
00147   // if PWD is lacking, then the path resolution machinery may not work
00148   
00149   if (get_env ("TEXMACS_PATH") == "")
00150     set_env ("TEXMACS_PATH", as_string (exedir * ".."));
00151   if (get_env ("HOME") == "")
00152     set_env ("HOME", get_env("USERPROFILE"));
00153   // HACK
00154   // In WINE the variable PWD is already in the outer Unix environment 
00155   // so we need to override it to have a correct behaviour
00156   if ((get_env ("PWD") == "") || (get_env ("PWD")[0] == '/'))  {
00157     set_env ("PWD", as_string (exedir));
00158     // set_env ("PWD", get_env("HOME"));
00159   }
00160   // system("set");
00161 #endif
00162 }
00163 
00164 /******************************************************************************
00165 * Real main program for encaptulation of guile
00166 ******************************************************************************/
00167 
00168 void
00169 TeXmacs_main (int argc, char** argv) {
00170   int i;
00171   bool flag= true;
00172   string the_default_font;
00173   for (i=1; i<argc; i++)
00174     if (argv[i][0] == '\0') argc= i;
00175     else if (((argv[i][0] == '-') ||
00176              (argv[i][0] == '+')) && (argv[i][1] != '\0'))
00177     {
00178       string s= argv[i];
00179       if ((N(s)>=2) && (s(0,2)=="--")) s= s (1, N(s));
00180       if ((s == "-s") || (s == "-silent")) flag= false;
00181       else if ((s == "-V") || (s == "-verbose"))
00182        debug (DEBUG_FLAG_VERBOSE, true);
00183       else if ((s == "-d") || (s == "-debug")) debug (DEBUG_FLAG_STD, true);
00184       else if (s == "-debug-events") debug (DEBUG_FLAG_EVENTS, true);
00185       else if (s == "-debug-io") debug (DEBUG_FLAG_IO, true);
00186       else if (s == "-debug-bench") debug (DEBUG_FLAG_BENCH, true);
00187       else if (s == "-debug-history") debug (DEBUG_FLAG_HISTORY, true);
00188       else if (s == "-debug-qt") debug (DEBUG_FLAG_QT, true);
00189       else if (s == "-debug-keyboard") debug (DEBUG_FLAG_KEYBOARD, true);
00190       else if (s == "-debug-packrat") debug (DEBUG_FLAG_PACKRAT, true);
00191       else if (s == "-debug-flatten") debug (DEBUG_FLAG_FLATTEN, true);
00192       else if (s == "-debug-correct") debug (DEBUG_FLAG_CORRECT, true);
00193       else if (s == "-debug-all") {
00194        debug (DEBUG_FLAG_EVENTS, true);
00195        debug (DEBUG_FLAG_STD, true);
00196        debug (DEBUG_FLAG_IO, true);
00197        debug (DEBUG_FLAG_HISTORY, true);
00198        debug (DEBUG_FLAG_BENCH, true);
00199        debug (DEBUG_FLAG_QT, true);
00200       }
00201       else if ((s == "-fn") || (s == "-font")) {
00202        i++;
00203        if (i<argc) the_default_font= argv[i];
00204       }
00205       else if ((s == "-g") || (s == "-geometry")) {
00206        i++;
00207        if (i<argc) {
00208          string g= argv[i];
00209          int j=0, j1, j2, j3;
00210          for (j=0; j<N(g); j++)
00211            if (g[j] == 'x') break;
00212          j1=j; if (j<N(g)) j++;
00213          for (; j<N(g); j++)
00214            if ((g[j] == '+') || (g[j] == '-')) break;
00215          j2=j; if (j<N(g)) j++;
00216          for (; j<N(g); j++)
00217            if ((g[j] == '+') || (g[j] == '-')) break;
00218          j3=j;
00219          if (j1<N(g)) {
00220            geometry_w= max (as_int (g (0, j1)), 320);
00221            geometry_h= max (as_int (g (j1+1, j2)), 200);
00222          }
00223          if (j3<N(g)) {
00224            if (g[j2] == '-') geometry_x= as_int (g (j2, j3)) - 1;
00225            else geometry_x= as_int (g (j2+1, j3));
00226            if (g[j3] == '-') geometry_y= as_int (g (j3, N(g))) - 1;
00227            else geometry_y= as_int (g (j3+1, N(g)));
00228          }
00229        }
00230       }
00231       else if ((s == "-b") || (s == "-initialize-buffer")) {
00232        i++;
00233        if (i<argc) tm_init_buffer_file= url_system (argv[i]);
00234       }
00235       else if ((s == "-i") || (s == "-initialize")) {
00236        i++;
00237        if (i<argc) tm_init_file= url_system (argv[i]);
00238       }
00239       else if ((s == "-v") || (s == "-version")) {
00240        cout << "\n";
00241        cout << "TeXmacs version " << TEXMACS_VERSION << "\n";
00242        cout << TEXMACS_COPYRIGHT << "\n";
00243        cout << "\n";
00244        exit (0);
00245       }
00246       else if ((s == "-p") || (s == "-path")) {
00247        cout << get_env ("TEXMACS_PATH") << "\n";
00248        exit (0);
00249       }
00250       else if ((s == "-bp") || (s == "-binpath")) {
00251        cout << get_env ("TEXMACS_BIN_PATH") << "\n";
00252        exit (0);
00253       }
00254       else if ((s == "-q") || (s == "-quit"))
00255        my_init_cmds= my_init_cmds * " (quit-TeXmacs)";
00256       else if ((s == "-r") || (s == "-reverse"))
00257        reverse_colors= true;
00258       else if ((s == "-c") || (s == "-convert")) {
00259        i+=2;
00260        if (i<argc) {
00261          url in  ("$PWD", argv[i-1]);
00262          url out ("$PWD", argv[ i ]);
00263          my_init_cmds= my_init_cmds * " " *
00264            "(texmacs-load-buffer " * scm_quote (as_string (in)) *
00265            " \"generic\" 0 #f) " *
00266            "(export-buffer " * scm_quote (as_string (out)) * ")";
00267        }
00268       }
00269       else if ((s == "-x") || (s == "-execute")) {
00270        i++;
00271        if (i<argc) my_init_cmds= (my_init_cmds * " ") * argv[i];
00272       }
00273       else if (s == "-log-file") i++;
00274       else if ((s == "-Oc") || (s == "-no-char-clipping")) char_clip= false;
00275       else if ((s == "+Oc") || (s == "-char-clipping")) char_clip= true;
00276       else if ((s == "-S") || (s == "-setup") ||
00277               (s == "-delete-cache") || (s == "-delete-font-cache") ||
00278               (s == "-delete-style-cache") || (s == "-delete-file-cache") ||
00279               (s == "-delete-doc-cache"));
00280       else if (starts (s, "-psn"));
00281       else {
00282        cout << "\n";
00283        cout << "Options for TeXmacs:\n\n";
00284        cout << "  -b [file]  Specify scheme buffers initialization file\n";
00285        cout << "  -c [i] [o] Convert file 'i' into file 'o'\n";
00286        cout << "  -d         For debugging purposes\n";
00287        cout << "  -fn [font] Set the default TeX font\n";
00288        cout << "  -g [geom]  Set geometry of window in pixels\n";
00289        cout << "  -h         Display this help message\n";
00290        cout << "  -i [file]  Specify scheme initialization file\n";
00291        cout << "  -p         Get the TeXmacs path\n";
00292        cout << "  -q         Shortcut for -x \"(quit-TeXmacs)\"\n";
00293        cout << "  -r         Reverse video mode\n";
00294        cout << "  -s         Suppress information messages\n";
00295        cout << "  -S         Rerun TeXmacs setup program before starting\n";
00296        cout << "  -v         Display current TeXmacs version\n";
00297        cout << "  -V         Show some informative messages\n";
00298        cout << "  -x [cmd]   Execute scheme command\n";
00299        cout << "  -Oc        TeX characters bitmap clipping off\n";
00300        cout << "  +Oc        TeX characters bitmap clipping on (default)\n";
00301        cout << "\nPlease report bugs to <bugs@texmacs.org>\n";
00302        cout << "\n";
00303        exit (0);
00304       }
00305     }
00306   if (flag) debug (DEBUG_FLAG_AUTO, true);
00307 
00308   if (DEBUG_STD) cout << "TeXmacs] Installing internal plug-ins...\n";
00309   bench_start ("initialize plugins");
00310   init_plugins ();
00311   bench_cumul ("initialize plugins");
00312   if (DEBUG_STD) cout << "TeXmacs] Opening display...\n";
00313   
00314 #if defined(X11TEXMACS) && defined(MACOSX_EXTENSIONS)
00315   init_mac_application ();
00316 #endif
00317     
00318   gui_open (argc, argv);
00319   set_default_font (the_default_font);
00320   if (DEBUG_STD) cout << "TeXmacs] Starting server...\n";
00321   { // opening scope for server sv
00322   server sv;
00323 
00324   // HACK:
00325   // Qt and Guile want to change the locale. 
00326   // We need to force it to C to parse correctly the configuration files
00327   // (see as_double() in string.cpp)
00328   setlocale(LC_NUMERIC, "C");    
00329     
00330   for (i=1; i<argc; i++) {
00331     if (argv[i] == NULL) break;
00332     string s= argv[i];
00333     if ((N(s)>=2) && (s(0,2)=="--")) s= s (1, N(s));
00334     if ((s[0] != '-') && (s[0] != '+')) {
00335       if (DEBUG_STD) cout << "TeXmacs] Loading " << s << "...\n";
00336       load_buffer (url_system (s), "generic", 1);
00337     }
00338     if ((s == "-b") || (s == "-initialize-buffer") ||
00339        (s == "-c") || (s == "-convert") ||
00340        (s == "-fn") || (s == "-font") ||
00341        (s == "-i") || (s == "-initialize") ||
00342        (s == "-g") || (s == "-geometry") ||
00343        (s == "-x") || (s == "-execute") ||
00344        (s == "-log-file")) i++;
00345   }
00346   if (install_status == 1) {
00347     if (DEBUG_STD) cout << "TeXmacs] Loading welcome message...\n";
00348     load_buffer ("$TEXMACS_PATH/doc/about/welcome/first.en.tm", "help", 1);
00349   }
00350   else if (install_status == 2) {
00351     if (DEBUG_STD) cout << "TeXmacs] Loading upgrade message...\n";
00352     load_buffer (
00353       "$TEXMACS_HOME_PATH/doc/about/changes/changes-recent.en.tm", "help", 1);
00354   }
00355   if (no_bufs ()) {
00356     if (DEBUG_STD) cout << "TeXmacs] Creating 'no name' buffer...\n";
00357     open_window ();
00358   }
00359 
00360   bench_print ();
00361   bench_reset ("initialize texmacs");
00362   bench_reset ("initialize plugins");
00363   bench_reset ("initialize scheme");
00364 
00365   if (DEBUG_STD) cout << "TeXmacs] Starting event loop...\n";
00366   texmacs_started= true;
00367   signal (SIGSEGV, clean_exit_on_segfault);
00368   gui_start_loop ();
00369 
00370   if (DEBUG_STD) cout << "TeXmacs] Stopping server...\n";
00371   } // ending scope for server sv
00372 
00373   if (DEBUG_STD) cout << "TeXmacs] Closing display...\n";
00374   gui_close ();
00375   
00376 #if defined(X11TEXMACS) && defined(MACOSX_EXTENSIONS)
00377   finalize_mac_application ();
00378 #endif
00379   
00380   if (DEBUG_STD) cout << "TeXmacs] Good bye...\n";
00381 }
00382 
00383 /******************************************************************************
00384 * Main program
00385 ******************************************************************************/
00386 
00387 void
00388 immediate_options (int argc, char** argv) {
00389   if (get_env ("TEXMACS_HOME_PATH") == "")
00390 #ifdef __MINGW32__
00391     set_env ("TEXMACS_HOME_PATH", get_env ("APPDATA") * "/TeXmacs");
00392 #else
00393   set_env ("TEXMACS_HOME_PATH", get_env ("HOME") * "/.TeXmacs");
00394 #endif
00395   if (get_env ("TEXMACS_HOME_PATH") == "") return;
00396   for (int i=1; i<argc; i++) {
00397     string s= argv[i];
00398     if ((N(s)>=2) && (s(0,2)=="--")) s= s (1, N(s));
00399     if ((s == "-S") || (s == "-setup")) {
00400       remove (url ("$TEXMACS_HOME_PATH/system/settings.scm"));
00401       remove (url ("$TEXMACS_HOME_PATH/system/setup.scm"));
00402       remove (url ("$TEXMACS_HOME_PATH/system/cache") * url_wildcard ("*"));
00403       remove (url ("$TEXMACS_HOME_PATH/fonts/error") * url_wildcard ("*"));
00404     }
00405     else if (s == "-delete-cache")
00406       remove (url ("$TEXMACS_HOME_PATH/system/cache") * url_wildcard ("*"));
00407     else if (s == "-delete-style-cache")
00408       remove (url ("$TEXMACS_HOME_PATH/system/cache") * url_wildcard ("__*"));
00409     else if (s == "-delete-font-cache")
00410       remove (url ("$TEXMACS_HOME_PATH/system/cache/font_cache.scm"));
00411     else if (s == "-delete-doc-cache") {
00412       remove (url ("$TEXMACS_HOME_PATH/system/cache/doc_cache"));
00413       remove (url ("$TEXMACS_HOME_PATH/system/cache/dir_cache.scm"));
00414       remove (url ("$TEXMACS_HOME_PATH/system/cache/stat_cache.scm"));
00415     }
00416     else if (s == "-delete-file-cache") {
00417       remove (url ("$TEXMACS_HOME_PATH/system/cache/doc_cache"));
00418       remove (url ("$TEXMACS_HOME_PATH/system/cache/file_cache"));
00419       remove (url ("$TEXMACS_HOME_PATH/system/cache/dir_cache.scm"));
00420       remove (url ("$TEXMACS_HOME_PATH/system/cache/stat_cache.scm"));
00421     }
00422     else if (s == "-log-file" && i + 1 < argc) {
00423       i++;
00424       char* log_file = argv[i];
00425       FILE* f= fopen (log_file, "w");
00426       if (! f || ! cout.open (f) || ! cerr.open (f))
00427         cerr << "TeXmacs] Error: could not open " << log_file << "\n";
00428     }
00429   }
00430 }
00431 
00432 #include <cstdio>
00433 
00434 int
00435 main (int argc, char** argv) {
00436   windows_delayed_refresh (1000000000);
00437   immediate_options (argc, argv);
00438   set_env ("LC_NUMERIC", "POSIX");
00439 #ifdef MACOSX_EXTENSIONS
00440   // Reset TeXmacs if Alt is pressed during startup
00441   if (mac_alternate_startup()) {
00442     cout << "TeXmacs] Performing setup (Alt on startup)" << LF; 
00443     remove (url ("$TEXMACS_HOME_PATH/system/settings.scm"));
00444     remove (url ("$TEXMACS_HOME_PATH/system/setup.scm"));
00445     remove (url ("$TEXMACS_HOME_PATH/system/cache") * url_wildcard ("*"));
00446     remove (url ("$TEXMACS_HOME_PATH/fonts/error") * url_wildcard ("*"));    
00447   }
00448 #endif
00449 #ifdef QTTEXMACS
00450   // initialize the Qt application infrastructure
00451   new QApplication (argc, argv);
00452 #endif
00453   TeXmacs_init_paths (argc, argv);
00454   //cout << "Bench  ] Started TeXmacs\n";
00455   the_et     = tuple ();
00456   the_et->obs= ip_observer (path ());
00457   cache_initialize ();
00458   bench_start ("initialize texmacs");
00459   init_texmacs ();
00460   bench_cumul ("initialize texmacs");
00461 #ifdef ENABLE_TESTS
00462   test_routines ();
00463 #endif
00464 //#ifdef EXPERIMENTAL
00465 //  test_environments ();
00466 //#endif
00467   start_scheme (argc, argv, TeXmacs_main);
00468   cout.close ();
00469   cerr.close ();
00470   return 0;
00471 }