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