first commit
This commit is contained in:
160
extern/stdcxx/4.2.1/util/diagnostic.cpp
vendored
Normal file
160
extern/stdcxx/4.2.1/util/diagnostic.cpp
vendored
Normal file
@@ -0,0 +1,160 @@
|
||||
/***************************************************************************
|
||||
*
|
||||
* diagnostic.cpp
|
||||
*
|
||||
* $Id: diagnostic.cpp 448754 2006-09-22 00:42:16Z sebor $
|
||||
*
|
||||
***************************************************************************
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed
|
||||
* with this work for additional information regarding copyright
|
||||
* ownership. The ASF licenses this file to you under the Apache
|
||||
* License, Version 2.0 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*
|
||||
* Copyright 2001-2006 Rogue Wave Software.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include "diagnostic.h"
|
||||
#include "scanner.h" // for Scanner::token_t
|
||||
#include "loc_exception.h"
|
||||
|
||||
#include <cstdarg> // for va_list, ...
|
||||
#include <cstdio> // for puts(), fprintf(), ...
|
||||
#include <set> // for set
|
||||
|
||||
|
||||
// set of disabled warnings
|
||||
static std::set<int> disabled;
|
||||
|
||||
static bool warn = true; // warnings (on by default)
|
||||
static bool info = false; // info messages (off by default)
|
||||
|
||||
|
||||
// write a warning or error message to standard output. If it is a warning
|
||||
// that is issued and that warning has not been disabled then return true.
|
||||
bool issue_diag (int type, bool, const Scanner::token_t *token,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
bool enabled = false;
|
||||
|
||||
if (0 == fmt) {
|
||||
|
||||
// special treatment when format string is 0: a request
|
||||
// to enable or disable this type of diagnostic, e.g.,
|
||||
// in response to a command line option
|
||||
|
||||
if (W_DISABLE == type) {
|
||||
// disable all warnings
|
||||
enabled = warn;
|
||||
warn = false;
|
||||
}
|
||||
else if (I_ENABLE == type) {
|
||||
// enable all informational messages
|
||||
enabled = info;
|
||||
info = true;
|
||||
}
|
||||
else {
|
||||
// disable a specific warning and return its previous
|
||||
// setting (i.e., enabled or disabled)
|
||||
enabled = disabled.find (type) == disabled.end ();
|
||||
disabled.insert (type);
|
||||
}
|
||||
|
||||
return enabled;
|
||||
}
|
||||
|
||||
const bool is_info = I_FIRST <= type && type <= I_LAST;
|
||||
const bool is_warn = !is_info && W_FIRST <= type && type <= W_LAST;
|
||||
const bool is_error = !is_info && !is_warn;
|
||||
|
||||
if (is_warn && (!warn || disabled.end () != disabled.find (type))) {
|
||||
// warning disabled
|
||||
return enabled;
|
||||
}
|
||||
|
||||
if (is_info && !info) {
|
||||
// info disabled
|
||||
return enabled;
|
||||
}
|
||||
|
||||
// all errors and those warnings that are not disabled
|
||||
// must be issued
|
||||
enabled = true;
|
||||
|
||||
if (token && token->file)
|
||||
std::fprintf (stderr, "%s:%d: ", token->file, token->line);
|
||||
|
||||
if (is_error)
|
||||
std::fprintf (stderr, "Error %-3d: ", type);
|
||||
else if (is_warn)
|
||||
std::fprintf (stderr, "Warning %-3d: ", type);
|
||||
else
|
||||
std::fprintf (stderr, "Note %-3d: ", type);
|
||||
|
||||
// get the variable sized argument and pass it to vfprintf
|
||||
// to be printed
|
||||
std::va_list va;
|
||||
va_start (va, fmt);
|
||||
std::vfprintf (stderr, fmt, va);
|
||||
va_end (va);
|
||||
|
||||
// if the token pointer is non-zero, find the file and line
|
||||
// the token appears on and print it out, followed by a line
|
||||
// underscoring the token that caused the diagnostic with
|
||||
// a string of carets ('^')
|
||||
|
||||
std::FILE* const ftok = token ? std::fopen (token->file, "r") : 0;
|
||||
|
||||
if (ftok) {
|
||||
int i;
|
||||
char line [1024]; // FIXME: handle longer lines
|
||||
|
||||
// advance to the specified line in the file
|
||||
for (i = 0; i < token->line; ++i) {
|
||||
if (0 == std::fgets (line, 1024, ftok)) {
|
||||
*line = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == token->line && '\0' != *line) {
|
||||
std::fputs ("\t\t", stderr);
|
||||
std::fputs (line, stderr);
|
||||
std::fputs ("\t\t", stderr);
|
||||
|
||||
// tok->col is the column number where the first character
|
||||
// in the token begins. Go through the line saving tabs
|
||||
// so that the '^' will line up with the token
|
||||
|
||||
for (i = 0; i < token->column; ++i)
|
||||
std::fputc (line [i] == '\t' ? '\t' : ' ', stderr);
|
||||
|
||||
for (unsigned j = 0; j < token->name.size (); ++j)
|
||||
std::fputc ('^', stderr);
|
||||
|
||||
std::fputc ('\n', stderr);
|
||||
}
|
||||
|
||||
std::fclose (ftok);
|
||||
}
|
||||
|
||||
if (is_error) {
|
||||
// throw an exception if the diagnostic is a hard error
|
||||
throw loc_exception ();
|
||||
}
|
||||
|
||||
// return otherwise (i.e., the diagnostic is not an error)
|
||||
return enabled;
|
||||
}
|
||||
Reference in New Issue
Block a user