vim syntax checking whitespace - regex

I want configuring my .vimrc for do somes auto syntax checking.
That is my problem, i want auto change somes syntax by another.
I deal with the specific caracter in computer programation like = ; , . ( { [ <.
An exemple it's better than words :
void bibi(int param1,char *words)
{
unsigned int locale=param;
cout<<words<<endl;
}
became :
void bibi( int param1,char* words)
{
unsigned int locale = param;
cout << words << endl;
}
Just formating with add or remove some whitespaces.
I write this :
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Formating of text in code
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
function! ChangeSpaces()
"" search and replace "= " or " =" or "= " to " = "
silent! %s/\s*[=]\s*/ = /g
endfunction
""autocmd CursorMovedI * call ChangeSpaces()
""autocmd BufWrite * call ChangeSpaces()
autocmd FileAppendPre * call ChangeSpaces()
But i have not the result, in this case, if i write " i=e" , they do nothing but if i write 'i= ', it's work, the regex doesn't run, they replace after the end of the "pattern".
By the way if you have a more "sexy way" to do what i want, let me know.
In fact, when i want add some other specific caracter the code became :
"function! ChangeSpaces()
"" search and replace "= " or " =" or "= " to " = "
"silent! %s/\s*[=]\s*/ = /g
""" search and replace "( " or " (" or "(" to " ( "
"" silent! %s/\s*[(]\s*/ ( /g
""" search and replace "[ " or " [" or "[" to " [ "
"" silent! %s/\s*[[]\s*/ [ /g
""" search and replace ", " or " ," or "," to " , "
"" silent! %s/\s*[,]\s*/ , /g
""" search and replace "== " or " ==" or "==" to " == "
"" silent! %s/\s*[==]\s*/ = /g
""" search and replace "> " or " >" or ">" to " > "
"" silent! %s/\s*[>]\s*/ > /g
""" search and replace ">= " or " >=" or ">=" to " >= "
" silent! %s/\s*[>=]\s*/ >= /g
""" search and replace "< " or " <" or "<" to " < "
"" silent! %s/\s*[<]\s*/ < /g
""" search and replace "<= " or " <=" or "<=" to " <= "
"" silent! %s/\s*[=]\s*/ <= /g
"" let repl=substitute(cline,\s*[= ]\s*," = ", "g")
"" call setline(".",repl)
"" let cline=line(".")
"" let ccol=col(".")
"" call cursor(cline, ccol)
"endfunction
""autocmd CursorMovedI * call ChangeSpaces()
""autocmd BufWrite * call ChangeSpaces()
"autocmd FileAppendPre * call ChangeSpaces()
Best regards.
PS: my bad, i want this kind of formating, for every language i use, not just C++.

What about filtering your file through an external C++ indenter? While GNU indent says it was not designed for C++ it works reasonably well. If it doesn't, you might try astyle. Then all you have to do is
map <F8> :w<CR>m':%!astyle<CR>`'
That way even folks using other editors can use the same indent style.

Related

std::regex - lookahead assertion not always working

I'm writing a module that's making some string substitutions into text to give to a scripting language. The language's syntax is vaugely lisp-y, so expressions are bounded by parentheses and symbols separated by spaces, most of them starting with '$'. A regular expression like this seems like it should give matches at the appropriate symbol boundaries:
auto re_match_abc = std::regex{ "(?=.*[[:space:]()])\\$abc(?=[()[:space:]].*)" };
But in my environment (Visual C++ 2017, 15.9.19, targetting C++-17) it can match strings without a suitable boundary in front of them:
std::cout << " $abc -> " << std::regex_replace(" $abc ", re_match_abc, "***") << std::endl;
std::cout << " ($abc) -> " << std::regex_replace("($abc)", re_match_abc, "***") << std::endl;
std::cout << "xyz$abc -> " << std::regex_replace("xyz$abc ", re_match_abc, "***") << std::endl;
std::cout << " $abcdef -> " << std::regex_replace(" $abcdef", re_match_abc, "***") << std::endl;
// Result from VC++ 2017:
//
// $abc -> ***
// ($abc) -> (***)
// xyz$abc -> xyz*** <= What's going wrong here?
// $abcdef -> $abcdef
Why is that regex ignoring the positive-lookahead requirement to have at least one space or parenthesis before the matching text?
[I realize that there are other ways to do this job and to do it really robustly maybe I should use something to turn the string into a token stream, but for the immediate job I have (and because the person authoring the strings that get processed is sitting next to me, so we can coordinate) I thought that regex replacements would do for now.]
You need to use a positive lookbehind instead. What you really want is this:
auto re_match_abc = std::regex{ "(?<=[[:space:]()])\\$abc(?=[()[:space:]])" };
You can try it out on a website like https://regex101.com/ (just remove the escaped backslash that's required for the C++ string). It explains what each piece of the regex is doing and shows you everything that matches.
Keep in mind that this will also match things like )$abc)
Edit: std::regex apparently does not support lookbehind. For you specific case you might try something like this:
auto re_match_abc = std::regex{ "([[:space:]()])\\$abc(?=[()[:space:]])" };
std::cout << " $abc -> " << std::regex_replace(" $abc ", re_match_abc, "$1***") << std::endl;
std::cout << " ($abc) -> " << std::regex_replace("($abc)", re_match_abc, "$1***") << std::endl;
std::cout << "xyz$abc -> " << std::regex_replace("xyz$abc ", re_match_abc, "$1***") << std::endl;
std::cout << " $abcdef -> " << std::regex_replace(" $abcdef", re_match_abc, "$1***") << std::endl;
output:
$abc -> ***
($abc) -> (***)
xyz$abc -> xyz$abc
$abcdef -> $abcdef
try it here
Here instead of a lookbehind we have a normal capture group. In the replacement we're emitting whatever we captured (a parenthesis or space) followed by the actual string we want to replace $abc with.

Modifying strings in an Array of strings

I have an array of strings and I would like to modify its elements at will. This is the code:
char pieces[9][4] = { " ", " o ", " a ", " ", " ", " ", " b ", " ", " " };
pieces[2] = { " x " };
As I know, the elements in pieces[] are string literal, so they can't be changed (I'm not sure why this is like this). Maybe it could be solved using std::string or vectors. However, I would like to know if this kind of operation, or very similar operations, can be done using an array of strings. Can be done something like this using just an array of strings?
In your specific situation, it looks like you always have some character surrounded by spaces, so you could simply do pieces[2][1] = 'x'; to modify that one element. However...
You are correct to assume this can be made easier with std::string and std::vector, but since we already know the size, an std::array will probably be better here:
std::array<std::string, 9> pieces = { " ", " o ", " a ", " ", " ", " ", " b ", " ", " " };
pieces[2] = " x ";
You may notice that the subscript operator still works on std::array's. This means that even if you switch to std::array's, you probably won't even have to change too much in your other code (just the parts dealing with c-strings to be dealing with std::strings)
You can use strcpy();
See following example code. See working code here:
int main(void)
{
char pieces[9][4] = { " ", " o ", " a ", " ", " ", " ", " b ", " ", " " };
printf("At point 1: %s\n",pieces[2]);
strcpy(pieces[2]," x ");
printf("At point 2: %s",pieces[2]);
return 0;
}
Output:
At point 1: a
At point 2: x
Does
pieces[2][0] = ' ';
pieces[2][1] = 'x';
pieces[2][2] = ' ';
pieces[2][3] = '\0';
do what you want?
Firstly, using curly brackets like pieces[2] = { " x " }; is the way of initialization, so you can't do that.
Secondly, pieces[2] is an char array, so it is not modifiable l-value.
You can either change its content element by element or by using strcpy() function.
Just to sumarize the different solutions given by different users, the options are:
Modify one char element at a time. Example: pieces[2][1] = 'x'
Use strcpy(). Example: strcpy(pieces[2]," x ")
Another types: std::array, std::string, std::vector

c++: concat constant string with macro-defined string

I want to concat the constant string and the macro defined string.
#define DEEP_DRIVE_NET "C:/Users/tumh/hookv/deep_drive_model.prototxt"
#define DEEP_DRIVE_WEIGHT "C:/Users/tumh/hookv/caffe_deep_drive_train_iter_35352.caffemodel"
CHECK(file_exist(DEEP_DRIVE_WEIGHT)) << "Net Weight " + DEEP_DRIVE_WEIGHT + " Not Found";
CHECK(file_exist(DEEP_DRIVE_NET)) << "Net definition " + DEEP_DRIVE_NET + " Not Found";
the compile error from msvc 2013 compiler is
C:\Users\tumh\hookv\samples\Test\Inference.cpp(28): error C2110: '+' : cannot add two pointers [C:\Users\tumh\hookv\build\NativeTrainer.vcxproj]
C:\Users\tumh\hookv\samples\Test\Inference.cpp(29): error C2110: '+' : cannot add two pointers [C:\Users\tumh\hookv\build\NativeTrainer.vcxproj]
How can I concatenate such strings?
Thanks.
Just omit the + operations to concatenate c-style string literals:
CHECK(file_exist(DEEP_DRIVE_WEIGHT)) << "Net Weight " DEEP_DRIVE_WEIGHT " Not Found";
CHECK(file_exist(DEEP_DRIVE_NET)) << "Net definition " DEEP_DRIVE_NET " Not Found";

When try to insert into table i am getting QSqlError("", "Parameter count mismatch", "") here is my query

QSqlQuery insert_emi_query;
insert_emi_query.prepare("INSERT INTO emi_info (emi-info_id, customer_id, down_payment, emi_start_date, emi_end_date, emi_amount, toatl_emi, intrest_rate, total_emi_amount) "
"VALUES(:emi-info_id, :customer_id, :down_payment, :emi_start_date, :emi_end_date, :emi_amount, :toatl_emi, :intrest_rate, :total_emi_amount)");
insert_emi_query.bindValue(":emi-info_id",emi_id);
insert_emi_query.bindValue(":customer_id",cutomer_id);
insert_emi_query.bindValue(":down_payment",ui->txtEMIDownPayment->text().toInt());
insert_emi_query.bindValue(":emi_start_date",ui->dateEMIStart->date());
insert_emi_query.bindValue(":emi_end_date",ui->dateEMIEnd->date());
insert_emi_query.bindValue(":emi_amount",ui->txtEMIPerMonth->text().toInt());
insert_emi_query.bindValue(":toatl_emi",ui->spinEMI->text().toInt());
insert_emi_query.bindValue(":intrest_rate",ui->txtEMIRate->text().toInt());
insert_emi_query.bindValue(":total_emi_amount",ui->txtEMIAfterPayment->text().toInt());
if(insert_emi_query.exec()){
qDebug() << "EMI Info Added---------------------";
}else{
qDebug() << "EMi not inserted" << insert_emi_query.lastError();
}
:emi-info_id is not a valid parameter name (- is not allowed in unquoted identifiers, and parameter names cannot be quoted).
I was not able to edit your question. May be you want to edit it yourself, using the following snippet, to improve comprehension.
1) Is the dash symbol in "emi-info_id" right? Most databases do not allow a dash in a column name.
2) May be you want to check if you have specified values for all mandatory columns of the table.
QSqlQuery insert_emi_query;
insert_emi_query.prepare(" "
" "
"INSERT INTO emi_info ( "
" emi-info_id, customer_id, down_payment, emi_start_date, "
" emi_end_date, emi_amount, toatl_emi, intrest_rate, "
" total_emi_amount) "
" "
" "
"VALUES( "
" :emi-info_id, :customer_id, :down_payment, :emi_start_date, "
" :emi_end_date, :emi_amount, :toatl_emi, :intrest_rate, "
" :total_emi_amount) "
" "
);
insert_emi_query.bindValue(":emi-info_id",emi_id);
insert_emi_query.bindValue(":customer_id",cutomer_id);
insert_emi_query.bindValue(":down_payment",ui->txtEMIDownPayment->text().toInt());
insert_emi_query.bindValue(":emi_start_date",ui->dateEMIStart->date());
insert_emi_query.bindValue(":emi_end_date",ui->dateEMIEnd->date());
insert_emi_query.bindValue(":emi_amount",ui->txtEMIPerMonth->text().toInt());
insert_emi_query.bindValue(":toatl_emi",ui->spinEMI->text().toInt());
insert_emi_query.bindValue(":intrest_rate",ui->txtEMIRate->text().toInt());
insert_emi_query.bindValue(":total_emi_amount",ui->txtEMIAfterPayment->text().toInt());
if(insert_emi_query.exec()) {
qDebug() << "EMI Info Added---------------------";
}
else{
qDebug() << "EMi not inserted" << insert_emi_query.lastError();
}
It seems that column name emi-info_id is typo in you query. It should be emi_info_id. Because column name with - is invalid.
If you are using Qt5(I didn't know what is there in qt4) or above then you can get error type like
insert_emi_query.lastError().type()
In above case it should be QSqlError::StatementError because there is typo in name of column.

clojure regex to match words and everything inbetween

This is more of a regex question than Clojure, but I am testing it in Clojure.
(re-seq #"\w+" "This is a test. Only a test!")
produces:
("This" "is" "a" "test" "Only" "a" "test")
I want to have this:
("This" " " "is" " " "a" "test" ". " "Only" " " "a" " " "test" "!")
Where I get all the words, but everything else between the words is included too.
I don't care for the period and space if they are seperate "." " " or together ". "
Is this simple to do with a regex?
Try using the following regex:
\w+|\W+
> (re-seq #"\w+|\W+" "This is a test. Only a test!")
("This" " " "is" " " "a" " " "test" ". " "Only" " " "a" " " "test" "!")
You probably could use \b which matches word boundaries and use string/split. The only problem is that it will match the beginning of the string too:
(rest (clojure.string/split "This is a test. Only a test!" #"\b"))
This won't be lazy either.