Fix for UBSan build
[platform/upstream/doxygen.git] / src / message.cpp
1 /******************************************************************************
2  *
3  * $Id: message.cpp,v 1.9 2001/03/19 19:27:41 root Exp $
4  *
5  * Copyright (C) 1997-2012 by Dimitri van Heesch.
6  *
7  * Permission to use, copy, modify, and distribute this software and its
8  * documentation under the terms of the GNU General Public License is hereby 
9  * granted. No representations are made about the suitability of this software 
10  * for any purpose. It is provided "as is" without express or implied warranty.
11  * See the GNU General Public License for more details.
12  *
13  * Documents produced by Doxygen are derivative works derived from the
14  * input used in their production; they are not affected by this license.
15  *
16  */
17
18 #include <stdarg.h>
19 #include <stdio.h>
20 #include <qdatetime.h>
21 #include "config.h"
22 #include "util.h"
23 #include "debug.h"
24 #include "doxygen.h"
25 #include "portable.h"
26
27 static QCString outputFormat;
28 //static int warnFormatOrder; // 1 = $file,$line,$text
29 //                            // 2 = $text,$line,$file
30 //                            // 3 = $line,$text,$file
31 //                            // 4 = $file,$text,$line
32 //                            // 5 = $text,$file,$line
33 //                            // 6 = $line,$file,$text
34
35 static FILE *warnFile = stderr;
36
37 void initWarningFormat()
38 {
39 //  int filePos = Config_getString("WARN_FORMAT").find("$file");
40 //  int linePos = Config_getString("WARN_FORMAT").find("$line");
41 //  int textPos = Config_getString("WARN_FORMAT").find("$text");
42 //
43 //  // sort items on position (there are 6 cases)
44 //  warnFormatOrder = 1;
45 //  if (filePos>linePos && filePos>textPos)
46 //  {
47 //    if (linePos>textPos) // $text,$line,$file
48 //    {
49 //      warnFormatOrder = 2;
50 //    }
51 //    else                 // $line,$text,$file
52 //    {
53 //      warnFormatOrder = 3;
54 //    }
55 //  }
56 //  else if (filePos<linePos && filePos<textPos)
57 //  {
58 //    if (linePos>textPos) // $file,$text,$line
59 //    {
60 //      warnFormatOrder = 4;
61 //    }
62 //  }
63 //  else if (filePos<linePos && filePos>textPos) // $text,$file,$line
64 //  {
65 //    warnFormatOrder = 5;
66 //  }
67 //  else // $line,$file,$text
68 //  {
69 //    warnFormatOrder = 6;
70 //  }
71 //  outputFormat = 
72 //      substitute(
73 //        substitute(
74 //          substitute( 
75 //            Config_getString("WARN_FORMAT"),
76 //           "$file","%s"
77 //          ),
78 //          "$text","%s"
79 //        ),
80 //        "$line","%d"
81 //      )+'\n';
82
83   //    replace(QRegExp("\\$file"),"%s").
84   //    replace(QRegExp("\\$text"),"%s").
85   //    replace(QRegExp("\\$line"),"%d")+
86   //    '\n';
87
88   outputFormat = Config_getString("WARN_FORMAT");
89
90   if (!Config_getString("WARN_LOGFILE").isEmpty())
91   {
92     warnFile = portable_fopen(Config_getString("WARN_LOGFILE"),"w");
93   }
94   if (!warnFile) // point it to something valid, because warn() relies on it
95   {
96     warnFile = stderr;
97   }
98 }
99
100
101 void msg(const char *fmt, ...)
102 {
103   if (!Config_getBool("QUIET"))
104   {
105     if (Debug::isFlagSet(Debug::Time))
106     {
107       printf("%.3f sec: ",((double)Doxygen::runningTime.elapsed())/1000.0);
108     }
109     va_list args;
110     va_start(args, fmt);
111     vfprintf(stdout, fmt, args);
112     va_end(args); 
113   }
114 }
115
116 static void format_warn(const char *file,int line,const char *text)
117 {
118   QCString fileSubst = file==0 ? "<unknown>" : file;
119   QCString lineSubst; lineSubst.setNum(line);
120   QCString textSubst = text;
121   QCString versionSubst;
122   if (file) // get version from file name
123   {
124     bool ambig;
125     FileDef *fd=findFileDef(Doxygen::inputNameDict,file,ambig);
126     if (fd)
127     {
128       versionSubst = fd->getVersion();
129     }
130   }
131   // substitute markers by actual values
132   QCString msgText = 
133       substitute(
134         substitute(
135           substitute(
136             substitute( 
137               outputFormat,
138               "$file",fileSubst
139             ),
140             "$text",textSubst
141           ),
142           "$line",lineSubst
143         ),
144         "$version",versionSubst
145       )+'\n';
146
147   // print resulting message
148   fwrite(msgText.data(),1,msgText.length(),warnFile);
149 }
150
151 static void do_warn(const char *tag, const char *file, int line, const char *fmt, va_list args)
152 {
153   if (!Config_getBool(tag)) return; // warning type disabled
154   char text[4096];
155   vsnprintf(text, 4096, fmt, args);
156   text[4095]='\0';
157   format_warn(file,line,text);
158 }
159
160 void warn(const char *file,int line,const char *fmt, ...)
161 {
162   va_list args;
163   va_start(args, fmt);
164   do_warn("WARNINGS", file, line, fmt, args);
165   va_end(args); 
166 }
167
168 void warn_simple(const char *file,int line,const char *text)
169 {
170   if (!Config_getBool("WARNINGS")) return; // warning type disabled
171   format_warn(file,line,text);
172 }
173
174 void warn_undoc(const char *file,int line,const char *fmt, ...)
175 {
176   va_list args;
177   va_start(args, fmt);
178   do_warn("WARN_IF_UNDOCUMENTED", file, line, fmt, args);
179   va_end(args);
180 }
181   
182 void warn_doc_error(const char *file,int line,const char *fmt, ...)
183 {
184   va_list args;
185   va_start(args, fmt);
186   do_warn("WARN_IF_DOC_ERROR", file, line, fmt, args);
187   va_end(args);
188 }
189
190 void err(const char *fmt, ...)
191 {
192   va_list args;
193   va_start(args, fmt);
194   vfprintf(warnFile, fmt, args);
195   va_end(args); 
196 }