Merge release-4-6 into master
[alexxy/gromacs.git] / src / gromacs / utility / errorformat.cpp
1 /*
2  *
3  *                This source code is part of
4  *
5  *                 G   R   O   M   A   C   S
6  *
7  *          GROningen MAchine for Chemical Simulations
8  *
9  * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
10  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
11  * Copyright (c) 2001-2009, The GROMACS development team,
12  * check out http://www.gromacs.org for more information.
13  *
14  * This program is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU General Public License
16  * as published by the Free Software Foundation; either version 2
17  * of the License, or (at your option) any later version.
18  *
19  * If you want to redistribute modifications, please consider that
20  * scientific software is very special. Version control is crucial -
21  * bugs must be traceable. We will be happy to consider code for
22  * inclusion in the official distribution, but derived work must not
23  * be called official GROMACS. Details are found in the README & COPYING
24  * files - if they are missing, get the official version at www.gromacs.org.
25  *
26  * To help us fund GROMACS development, we humbly ask that you cite
27  * the papers on the package - you can find them in the top README file.
28  *
29  * For more info, check our website at http://www.gromacs.org
30  */
31 /*! \internal \file
32  * \brief
33  * Implements functions declared in errorformat.h.
34  *
35  * \author Teemu Murtola <teemu.murtola@cbr.su.se>
36  * \ingroup module_utility
37  */
38 #ifdef HAVE_CONFIG_H
39 #include "config.h"
40 #endif
41
42 #include "errorformat.h"
43
44 #include <cctype>
45 #include <cstdio>
46 #include <cstring>
47
48 #include "gromacs/legacyheaders/copyrite.h"
49
50 #include "gromacs/utility/programinfo.h"
51 #include "gromacs/utility/stringutil.h"
52
53 namespace gmx
54 {
55
56 /*! \cond internal */
57 namespace internal
58 {
59
60 void printFatalErrorHeader(FILE *fp, const char *title,
61                            const char *func, const char *file, int line)
62 {
63     // In case ProgramInfo is not initialized and there is an issue with the
64     // initialization, fall back to "GROMACS".
65     const char *programName = "GROMACS";
66     try
67     {
68         programName = ProgramInfo::getInstance().programName().c_str();
69     }
70     catch (const std::exception &)
71     {
72     }
73
74     std::fprintf(fp, "\n-------------------------------------------------------\n");
75     std::fprintf(fp, "Program:     %s, %s\n", programName, GromacsVersion());
76     if (file != NULL)
77     {
78         // TODO: Check whether this works on Windows. If it doesn't, perhaps
79         // add Path::startsWith().
80         if (startsWith(file, CMAKE_SOURCE_DIR))
81         {
82             file += std::strlen(CMAKE_SOURCE_DIR);
83             if (file[0] == '/' || file[0] == '\\')
84             {
85                 ++file;
86             }
87         }
88         std::fprintf(fp, "Source file: %s (line %d)\n", file, line);
89     }
90     if (func != NULL)
91     {
92         std::fprintf(fp, "Function:    %s\n", func);
93     }
94     std::fprintf(fp, "\n");
95     std::fprintf(fp, "%s:\n", title);
96 }
97
98 void printFatalErrorMessageLine(FILE *fp, const char *text, int indent)
99 {
100     gmx::TextLineWrapper wrapper;
101     wrapper.settings().setLineLength(78 - indent);
102     size_t lineStart = 0;
103     size_t length = std::strlen(text);
104     while (lineStart < length)
105     {
106         size_t nextLineStart = wrapper.findNextLine(text, lineStart);
107         int lineLength = static_cast<int>(nextLineStart - lineStart);
108         while (lineLength > 0 && std::isspace(text[lineStart + lineLength - 1]))
109         {
110             --lineLength;
111         }
112         std::fprintf(fp, "%*s%.*s\n", indent, "", lineLength, text + lineStart);
113         lineStart = nextLineStart;
114     }
115 }
116
117 void printFatalErrorFooter(FILE *fp)
118 {
119     std::fprintf(fp, "\n");
120     std::fprintf(fp, "For more information and tips for troubleshooting, please check the GROMACS\n"
121                      "website at http://www.gromacs.org/Documentation/Errors");
122     std::fprintf(fp, "\n-------------------------------------------------------\n");
123 }
124
125 } // namespace internal
126 //! \endcond
127
128 } // namespace gmx