// $Id: Main.cpp,v 1.17 2002-05-18 07:56:47 geuzaine Exp $ // // Copyright (C) 1997 - 2002 C. Geuzaine, J.-F. Remacle // // 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 <signal.h> #if !defined(WIN32) || defined(__CYGWIN__) #include <sys/time.h> #include <sys/resource.h> #ifdef __APPLE__ #define RUSAGE_SELF 0 #define RUSAGE_CHILDREN -1 #endif /* __APPLE__ */ #endif #include "ParUtil.h" #include "PluginManager.h" #include "Gmsh.h" #include "GmshVersion.h" #include "Numeric.h" #include "Geo.h" #include "Mesh.h" #include "Views.h" #include "Parser.h" #include "Context.h" #include "Options.h" #include "OpenFile.h" #include "GetOptions.h" #include "MinMax.h" char yyname[256]; int yyerrorstate; Context_T CTX ; Mesh M, *THEM=NULL, *LOCAL=NULL; // Dummy definitions for link purposes. These should be removed as // soon as the library structure will be cleaned. void AddViewInUI(int, char *, int){} void draw_polygon_2d (double, double, double, int, double *, double *, double *){} void set_r(int, double){} void CreateOutputFile(char *, int){} // Print some help/info messages void Info (int level, char *arg0){ switch(level){ case 0 : if(ParUtil::Instance()->master()){ fprintf(stderr, "%s\n", gmsh_progname); fprintf(stderr, "%s\n", gmsh_copyright); Print_Usage(arg0); } ParUtil::Instance()->Exit(); case 1: if(ParUtil::Instance()->master()) fprintf(stderr, "%d.%d.%d\n", GMSH_MAJOR_VERSION, GMSH_MINOR_VERSION, GMSH_PATCH_VERSION); ParUtil::Instance()->Exit(); case 2: if(ParUtil::Instance()->master()){ fprintf(stderr, "%s%d.%d.%d\n", gmsh_version, GMSH_MAJOR_VERSION, GMSH_MINOR_VERSION, GMSH_PATCH_VERSION); fprintf(stderr, "%s\n", gmsh_os); fprintf(stderr, "%s\n", gmsh_date); fprintf(stderr, "%s\n", gmsh_host); fprintf(stderr, "%s\n", gmsh_packager); fprintf(stderr, "%s\n", gmsh_url); fprintf(stderr, "%s\n", gmsh_email); } ParUtil::Instance()->Exit(); default : break; } } // Main routine for the batch (black box) version int main(int argc, char *argv[]){ int i, nbf; ParUtil::Instance()->init(argc,argv); Init_Options(0); if(argc < 2) Info(0,argv[0]); Get_Options(argc, argv, &nbf); M.Vertices = NULL ; M.VertexEdges = NULL ; M.Simplexes = NULL ; M.Points = NULL ; M.Curves = NULL ; M.SurfaceLoops = NULL ; M.EdgeLoops = NULL ; M.Surfaces = NULL ; M.Volumes = NULL ; M.PhysicalGroups = NULL ; M.Metric = NULL ; signal(SIGINT, Signal); signal(SIGSEGV, Signal); signal(SIGFPE, Signal); if(CTX.default_plugins) GMSH_PluginManager::Instance()->RegisterDefaultPlugins(); OpenProblem(CTX.filename); if(yyerrorstate) ParUtil::Instance()->Abort(); else{ for(i=1;i<nbf;i++) MergeProblem(TheFileNameTab[i]); if(TheBgmFileName){ MergeProblem(TheBgmFileName); if(List_Nbr(CTX.post.list)) BGMWithView((Post_View*)List_Pointer(CTX.post.list, List_Nbr(CTX.post.list)-1)); else fprintf(stderr, ERROR_STR "Invalid background mesh (no view)\n"); exit(1); } if(CTX.batch > 0){ mai3d(THEM, CTX.batch); Print_Mesh(THEM,CTX.output_filename,CTX.mesh.format); } else Print_Geo(THEM, CTX.output_filename); if(CTX.mesh.histogram) Print_Histogram(THEM->Histogram[0]); ParUtil::Instance()->Barrier(__LINE__,__FILE__); ParUtil::Instance()->Exit(); return 1; } ParUtil::Instance()->Barrier(__LINE__,__FILE__); ParUtil::Instance()->Exit(); return 1; } // Handle signals. We should not use Msg functions in these... void Signal (int sig_num){ switch (sig_num){ case SIGSEGV : Msg(FATAL, "Segmentation violation (invalid memory reference)"); break; case SIGFPE : Msg(FATAL, "Floating point exception (division by zero?)"); break; case SIGINT : Msg(FATAL, "Interrupt (generated from terminal special char)"); break; default : Msg(FATAL, "Unknown signal"); break; } } // General purpose message routine void Msg(int level, char *fmt, ...){ va_list args; int abort=0; int nb, nbvis; va_start (args, fmt); switch(level){ case DIRECT : if(CTX.verbosity >=2 && ParUtil::Instance()->master()) { vfprintf(stdout, fmt, args); fprintf(stdout, "\n"); } break; case FATAL : case FATAL1 : case FATAL2 : case FATAL3 : fprintf(stderr,"On processor %d : ", ParUtil::Instance()->rank()); fprintf(stderr, FATAL_STR); vfprintf(stderr, fmt, args); fprintf(stderr, "\n"); abort = 1 ; break ; case GERROR : case GERROR1 : case GERROR2 : case GERROR3 : fprintf(stderr,"On processor %d : ", ParUtil::Instance()->rank()); fprintf(stderr, ERROR_STR); vfprintf(stderr, fmt, args); fprintf(stderr, "\n"); break ; case WARNING : case WARNING1 : case WARNING2 : case WARNING3 : if(CTX.verbosity >= 1){ fprintf(stderr,"On processor %d : ", ParUtil::Instance()->rank()); fprintf(stderr, WARNING_STR); vfprintf(stderr, fmt,args); fprintf(stderr, "\n"); } break; case PARSER_ERROR : if(ParUtil::Instance()->master()){ fprintf(stderr, PARSER_ERROR_STR); vfprintf(stderr, fmt, args); fprintf(stderr, "\n"); } break ; case PARSER_INFO : if(CTX.verbosity >= 2 && ParUtil::Instance()->master()){ fprintf(stderr, PARSER_INFO_STR); vfprintf(stderr, fmt, args); fprintf(stderr, "\n"); } break ; case DEBUG : case DEBUG1 : case DEBUG2 : case DEBUG3 : if(CTX.verbosity >= 3 && ParUtil::Instance()->master()){ fprintf(stderr, DEBUG_STR); vfprintf(stderr, fmt, args); fprintf(stderr, "\n"); } break; default : if(CTX.verbosity >= 1 && ParUtil::Instance()->master()){ fprintf(stderr, INFO_STR); vfprintf(stderr, fmt, args); fprintf(stderr, "\n"); } break; } va_end (args); if(abort) exit(1); } // CPU time computation void GetResources(long *s, long *us, long *mem){ #if !defined(WIN32) || defined(__CYGWIN__) static struct rusage r; getrusage(RUSAGE_SELF,&r); *s = (long)r.ru_utime.tv_sec ; *us = (long)r.ru_utime.tv_usec ; *mem = (long)r.ru_maxrss ; #else *s = *us = *mem = 0; #endif } double Cpu(void){ long s, us, mem; GetResources(&s, &us, &mem); return (double)s + (double)us/1.e6 ; }