I am working on some Qt app, whose main window consists of QPlainTextEdit subclassed log window for outputting events. I have three types of messages:
Information message, which represents a QString that begins with [INFO] substring
Warning message, which represents a QString that begins with [WARNING] substring
Error message, which represents a QString that begins with [ERROR] substring
Now, what I want to achieve with QSyntaxHighlighter class is to change color of these messages according to their type (INFO type - Qt::DarkBlue color, WARNING type - Qt::DarkYellow color, ERROR type - Qt::DarkRed color) and here is code chunk, which should have done the task:
void UeLogWindowTextHighlighter::ueSetupRules()
{
UeHighlightRule* ueRuleInfo=new UeHighlightRule(this);
UeHighlightRule* ueRuleWarning=new UeHighlightRule(this);
UeHighlightRule* ueRuleError=new UeHighlightRule(this);
this->ueInfoStartExpression()->setPattern("^[INFO].\*"); // FIRST WARNING
this->ueWarningStartExpression()->setPattern("^[WARNING].\*"); // SECOND WARNING
this->ueErrorStartExpression()->setPattern("^[ERROR].\*"); // THIRD WARNING
this->ueInfoExpressionCharFormat()->setForeground(Qt::darkGray);
this->ueWarningExpressionCharFormat()->setForeground(Qt::darkYellow);
this->ueErrorExpressionCharFormat()->setForeground(Qt::darkRed);
ueRuleInfo->ueSetPattern(this->ueInfoStartExpression());
ueRuleInfo->ueSetTextCharFormat(this->ueInfoExpressionCharFormat());
this->ueHighlightRules()->append(ueRuleInfo);
ueRuleWarning->ueSetPattern(this->ueWarningStartExpression());
ueRuleWarning->ueSetTextCharFormat(this->ueWarningExpressionCharFormat());
this->ueHighlightRules()->append(ueRuleWarning);
ueRuleError->ueSetPattern(this->ueErrorStartExpression());
ueRuleError->ueSetTextCharFormat(this->ueErrorExpressionCharFormat());
this->ueHighlightRules()->append(ueRuleError);
} // ueSetupRules
However, when I compile the project, I get following warnings:
../../../gui/uelogwindowtexthighlighter.cpp: In member function 'void UeLogWindowTextHighlighter::ueSetupRules()': ../../../gui/uelogwindowtexthighlighter.cpp:58:47: warning: unknown escape sequence: '\*' [enabled by default]
this->ueInfoStartExpression()->setPattern("^[INFO].\*");
^ ../../../gui/uelogwindowtexthighlighter.cpp:59:50: warning: unknown escape sequence: '\*' [enabled by default]
this->ueWarningStartExpression()->setPattern("^[WARNING].\*");
^ ../../../gui/uelogwindowtexthighlighter.cpp:60:48: warning: unknown escape sequence: '\*' [enabled by default]
this->ueErrorStartExpression()->setPattern("^[ERROR].\*");
^
and consequently the messages are not colored (that is my suspicion). What is wrong with my regular expressions? I was following this question and answer on SO.
Star (*) didn't have to be escaped. Remove the \ or if you need the \ it should be escaped and write double \ (\\).
Related
I want to pass a raw string literals to [[deprecated(message)]] attribute as the message. The message is used again and again. So I want to avoid code repeat.
First, I tried to use static constexpr variable.
static constexpr auto str = R"(
Use this_func()
Description: ...
Parameter: ...
)";
[[deprecated(str)]]
void test1() {
}
I got the error "deprecated message is not a string". It seems that static constexpr variable isn't accepted by [[deprecated(message)]].
I tried to define the row string literals as preprocessor macro.
#define STR R"(
Use this_func()
Description: ...
Parameter: ...
)"
[[deprecated(STR)]]
void test2() {
}
It works as I expected as follows on clang++ 8.0.0.
prog.cc:38:5: warning: 'test2' is deprecated:
Use this_func()
Description: ...
Parameter: ...
[-Wdeprecated-declarations]
test2();
^
Demo: https://wandbox.org/permlink/gN4iOrul8Y0F76TZ
But g++ 9.2.0 outputs the compile error as follows:
prog.cc:19:13: error: unterminated raw string
19 | #define STR R"(
| ^
prog.cc:23:2: warning: missing terminating " character
23 | )"
| ^
https://wandbox.org/permlink/e62pQ2Dq9vTuG6Or
#define STR R"( \
Use this_func() \
Description: ... \
Parameter: ... \
)"
If I add backslashes on the tail of each line, no compile error occurred but output message is different from I expected as follows:
prog.cc:38:11: warning: 'void test2()' is deprecated: \\nUse this_func() \\nDescription: ... \\nParameter: ... \\n [-Wdeprecated-declarations]
I'm not sure which compiler works correctly.
Is there any way to pass the raw string literals variable/macro to [[deprecated]] attribute?
There is no such thing as a "raw string literal variable". There may be a variable which points to a string literal, but it is a variable, not the literal itself. The deprecated attribute does not take a C++ constant expression evaluating to a string. It takes a string literal: an actual token sequence.
So the most you can do is use a macro to contain your string literal. Of course, macros and raw string literals don't play nice together, since the raw string is supposed to consume the entire text. So the \ characters will act as both continuations for the macro and be part of the string.
I'm trying to compile a program written in the year 2001 in C++. When I run the setup script (ie ./setup) in the terminal, I get the error shown below. I have searched for a solution but the idea I get is that this type of error is produced by later versions of gcc ie versions 4 and above. How can I edit the code where the compiler shows errors so that it runs without the error.
david#david-Satellite-C55-B:~$ cd Desktop/WebTraff/WebTraff && ./setup
Making executables in root directory
make: Nothing to be done for 'all'.
Making ProWGen
g++ -c -g stream.cc
stream.cc: In member function ‘unsigned int* RequestStream::GeneratePopularities()’:
stream.cc:104:39: error: array bound forbidden after parenthesized type-id
if ((popularity = new (unsigned int)[noofDistinctDocs]) == NULL)
^
stream.cc:104:39: note: try removing the parentheses around the type-id
stream.cc: In member function ‘unsigned int* RequestStream::GenerateFileSizes()’:
stream.cc:173:49: error: array bound forbidden after parenthesized type-id
unsigned int *filesizes = new (unsigned int)[noofDistinctDocs];
^
stream.cc:173:49: note: try removing the parentheses around the type-id
stream.cc: In member function ‘void RequestStream::GenerateUniqueDocs(Node*, int, Node*, int)’:
stream.cc:378:28: error: array bound forbidden after parenthesized type-id
uniqueDoc = new (Request*)[noofDistinctDocs];
^
stream.cc:378:28: note: try removing the parentheses around the type-id
Makefile:11: recipe for target 'stream.o' failed
make: *** [stream.o] Error 1
cp: cannot stat 'ProWGen': No such file or directory
Making CacheDriver
g++ -c CacheDriver.cc
g++ -c lru.cc
lru.cc: In constructor ‘Lru::Lru(unsigned int)’:
lru.cc:21:36: error: array bound forbidden after parenthesized type-id
if ( (hash_table = new (LruNode*)[MAX_SIZE]) == NULL)
^
lru.cc:21:36: note: try removing the parentheses around the type-id
lru.cc:23:61: warning: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings]
ErrorMessage("Not enough memory to allocate hash table");
^
lru.cc: In member function ‘LruNode* Lru::get_new_node(unsigned int, unsigned int)’:
lru.cc:143:59: warning: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings]
ErrorMessage("Cannot allocate more memory for new nodes");
^
lru.cc: In member function ‘void Lru::found_update(LruNode*)’:
lru.cc:270:66: warning: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings]
if((loc != head)&&(succloc == NULL)) ErrorMessage("\nright here");
^
Makefile:8: recipe for target 'CacheDriver' failed
make: *** [CacheDriver] Error 1
cp: cannot stat 'CacheDriver': No such file or directory
Making popularity
gcc -o popularity main.o getch.o gettoken.o hash.o -lm
Making lrustack and freqsize
make: Nothing to be done for 'all'.
new (unsigned int)[noofDistinctDocs] is a syntax error. I'm guessing you meant:
new unsigned int[noofDistinctDocs]
which allocates an array of unsigned int. There are the same sort of error later in the code too.
Here is my enum declaration :
enum connection_primary_identifier_e : uint64_t
{
INVALID_IDENTIFIER = std::numeric_limits<std::underlying_type<connection_primary_identifier_e>::type>::max(),
}
(same happens if I use uint64_t directly as the type, also if I use -1 or -1ULL)
When I try to compile the file I get the following errors / warnings :
error: integer constant is so large that it is unsigned [-Werror]
error: narrowing conversion of ‘18446744073709551615I128’ from ‘__int128’ to ‘unsigned int’ inside { } [-Werror=narrowing]
error: large integer implicitly truncated to unsigned type [-Werror=overflow]
cc1plus: all warnings being treated as errors
The really weird thing is, the errors are actually produced for non-existing lines (line number is 3 after the last line on file) on another file (which uses the enum), I made sure it isn't a missing parentheses or anything like that.
Update:
Using uint32_t doesn't produce the error.
Using g++ (GCC) 4.8.3
Might be because std::underlying_type was initially underspecified and didn't require a complete type. This unintentionally allowed precisely this code, which uses connection_primary_identifier_e while it's still incomplete.
Starting with C++17, your code is definitely illegal.
I'm trying to test gcc preprocessor for its macro expansion.
I write following code: (just for testing)
#include <stdio.h>
#define QUOTE "
#define TMPL hello
int main(){
printf(QUOTE TMPL QUOTE);
return 0;
}
the compiling result is:
$ gcc main.c -o main
main.c:3:15: warning: missing terminating " character
main.c: In function ‘main’:
main.c:7: error: missing terminating " character
main.c:7: error: missing terminating " character
main.c:7: error: ‘hello’ undeclared (first use in this function)
main.c:7: error: (Each undeclared identifier is reported only once
main.c:7: error: for each function it appears in.)
main.c:7: warning: format not a string literal and no format arguments
main.c:7: warning: format not a string literal and no format arguments
$
Then I try to have a look at the preprocessed result
$ gcc -E main.c -o tmp.c
main.c:3:15: warning: missing terminating " character
$
Though giving a warning, it somehow produces correct preprocessed code in tmp.c
int main(){
printf(" hello ");
return 0;
}
And I compiler tmp.c, hello is correctly printed.
I'm wondering why gcc -E could produce correct code, while using gcc compiling directly failed. Is there difference between the two method of gcc preprocessor?
$ gcc --version
i686-apple-darwin11-llvm-gcc-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.11.00)
As I commented, a preprocessor macro should expand into a sequence of lexer tokens. Withing GCC source code, the libcpp (in charge of preprocessing and tokenizing) is producing a stream of tokens (not plain chars). A recent GCC 4.8, when run as gcc -Wall endyul.c -o endyl on your example, gives quite helpful diagnostics:
endyul.c:3:15: warning: missing terminating " character [enabled by default]
#define QUOTE "
^
endyul.c: In function 'main':
endyul.c:7:5: error: missing terminating " character
printf(QUOTE TMPL QUOTE);
^
endyul.c:7:5: error: missing terminating " character
endyul.c:4:14: error: 'hello' undeclared (first use in this function)
#define TMPL hello
^
endyul.c:7:18: note: in expansion of macro 'TMPL'
printf(QUOTE TMPL QUOTE);
^
endyul.c:4:14: note: each undeclared identifier is reported only once for each function it appears in
#define TMPL hello
^
endyul.c:7:18: note: in expansion of macro 'TMPL'
printf(QUOTE TMPL QUOTE);
^
Your GCC 4.2 is very old. You should consider upgrading it.
And clang (3.3) gives also a good diagnostic:
clang -Wall endyul.c -o endyul
endyul.c:3:15: warning: missing terminating '"' character [-Winvalid-pp-token]
#define QUOTE "
^
endyul.c:7:12: error: expected expression
printf(QUOTE TMPL QUOTE);
^
endyul.c:3:15: note: expanded from macro 'QUOTE'
1 warning and 1 error generated.
Read again the CPP manual of GCC, notably the chapters on Stringification and Concatenation.
I am new in using benchmarks and makefiles. I have downloaded Dhrystone benchmark from the below link and I am trying to compile it, but I am facing weird errors. I tried to solve it,but I am unsuccessful. Can someone help me in running the dhrystone benchmark?
Below are the 2 different ways that I tried to compile. But both are giving the same error result :(
Link: http://fossies.org/unix/privat/old/dhrystone-2.1.tar.gz/
compile commands tried:
gcc -g dhry.h dhry_1.c dhry_2.c -o dhrystonex
make all
error:
gcc -O -DTIMES -DHZ=60 dhry_1.c dhry_2.c -o gcc_dry2
dhry_1.c:31:18: warning: conflicting types for built-in function ‘malloc’ [enabled by default]
dhry_1.c:48:17: error: conflicting types for ‘times’
/usr/include/i386-linux-gnu/sys/times.h:49:16: note: previous declaration of ‘times’ was here
dhry_1.c: In function ‘main’:
dhry_1.c:98:3: warning: incompatible implicit declaration of built-in function ‘strcpy’ [enabled by default]
dhry_1.c:124:11: warning: ignoring return value of ‘scanf’, declared with attribute warn_unused_result [-Wunused-result]
make: *** [gcc_dry2] Error 1
Make the following changes. A line with a - before it indicates one you should remove. A line with a + before it indicates one you should add. In total, you will replace two lines (by preceding them with //) and add one new line (a #include):
diff -bup orig/dhry_1.c new/dhry_1.c
--- orig/dhry_1.c 2012-03-30 11:30:41.984107303 -0700
+++ new/dhry_1.c 2012-03-30 11:31:29.256002567 -0700
## -28,7 +28,7 ## char Ch_1_Glob,
int Arr_1_Glob [50];
int Arr_2_Glob [50] [50];
-extern char *malloc ();
+// extern char *malloc ();
Enumeration Func_1 ();
/* forward declaration necessary since Enumeration may not simply be int */
## -45,7 +45,7 ## Enumeration Func_1 ();
#ifdef TIMES
struct tms time_info;
-extern int times ();
+// extern int times ();
/* see library function "times" */
#define Too_Small_Time (2*HZ)
/* Measurements should last at least about 2 seconds */
diff -bup orig/dhry.h new/dhry.h
--- orig/dhry.h 2012-03-30 11:30:41.984107303 -0700
+++ new/dhry.h 2012-03-30 11:31:29.256002567 -0700
## -392,6 +392,7 ##
/* General definitions: */
#include <stdio.h>
+#include <string.h>
/* for strcpy, strcmp */
#define Null 0