I am using libtidy and need to retrieve the current value of a string-based option (for example, TidyOptErrFile, a.k.a. error-file).
Even after reading through the tidy source code, I cannot figure out which function to use to read the current value of such an option.
The TidyOptGetVal() function seemed promising, but no matter what I do, it always returns a null pointer. Here is my minimalist attempt (in C++ so I can use the auto keyword):
#include <iostream>
#include <tidy.h>
#include <tidybuffio.h>
#include <tidyenum.h>
using namespace std;
int main(int argc, const char * argv[]) {
auto tidyDoc = tidyCreate();
// The following should set the `error-file` property to `Foobar`
tidyOptParseValue(tidyDoc, "TidyErrFile", "Foobar");
// The type is `ctmbstr` which is just an alias for `const char*`
auto errorFile = tidyOptGetValue(tidyDoc, TidyErrFile);
if (errorFile==nullptr) {
cout << "Null pointer" << endl;
} else {
cout << errorFile << endl;
}
tidyRelease(tidyDoc);
return 0;
}
I found the reason for the problem, which I will post for future reference.
The function tidyOptParseValue() takes as its second argument the name of the option as given in the API.
So, for example, the option name in this case should be error-file (not the name of the enumeration found in the source code).
The corrected line should be
tidyOptParseValue(tidyDoc, "error-file", "Foobar");
Using that fix, the word Foobar is printed, as expected.
Related
In book "C++ Primer" fifth edition, there is a line "Entities with the same name defined in an outer scope are hidden" in the second page of Section 18.2.2. This sentence is underlined with red as follows:
I tried to repeat the claim in an experiment. The experimental code is as follows:
#include <cstdlib>
#include <iostream>
#include <cmath>
int abs(int n) {
std::cout << "here" << std::endl;
return 0;
}
void test() {
using std::abs;
std::cout << abs(7) << std::endl;
}
int main(int argc, char** argv) {
test();
return 0;
}
using std::abs is a using declaration, so, if the claim in "C++ Primer" is correct, the user-defined abs() function should be hidden by std::abs(). But the result is that it is the user-defined abs() function that is called. So, if the book is correct, there must be something wrong in my experiment. How do I write the experimental code to confirm the sentence in "C++ Primer"? If the book is incorrect, what should the correct exposition be that can replace the sentence? Thank you.
PS: I tried in both Windows10+VS2015 and Ubuntu 18.04+g++7.4. Both called user-defined abs() and printed out "here".
The book could do a better job of explaining it, but it isn't wrong. It's just that the lookup rules for overloads are somewhat more nuanced, because overloads of the same name may coexist in the same scope normally, so a using declaration mingles well with that.
If you were to indeed define a new entity that is not an overload, for instance
void test() {
int abs = 0;
std::cout << abs(7) << std::endl;
}
Then that call expression would be ill-formed, because the outer callable entities are hidden by the inner int variable. The way to work around it would be with a using declaration
void test() {
int abs = 0;
{
using std::abs; // Let the name refer to the functions again
using ::abs; // the variable abs is hidden
std::cout << abs(7) << std::endl;
}
}
This experiment should illustrate what the book meant.
I'm using boost::tokenizer to tokenize a string in C++, then I want to pass it to execv.
Consider the following code snippet (compilable):
#include <iostream>
#include <cstdlib>
#include <vector>
#include <boost/tokenizer.hpp>
// I will put every token into this vector
std::vector<const char*> argc;
// this is the command I want to parse
std::string command = "/bin/ls -la -R";
void test_tokenizer() {
// tokenizer is needed because arguments can be in quotes
boost::tokenizer<boost::escaped_list_separator<char> > scriptArguments(
command,
boost::escaped_list_separator<char>("\\", " ", "\""));
boost::tokenizer<boost::escaped_list_separator<char> >::iterator argument;
for(argument = scriptArguments.begin();
argument!=scriptArguments.end();
++argument) {
argc.push_back(argument->c_str());
std::cout << argument->c_str() << std::endl;
}
argc.push_back(NULL);
}
void test_raw() {
argc.push_back("/bin/ls");
argc.push_back("-l");
argc.push_back("-R");
argc.push_back(NULL);
}
int main() {
// this works OK
/*test_raw();
execv(argc[0], (char* const*)&argc[0]);
std::cerr << "execv failed";
_exit(1);
*/
// this is not working
test_tokenizer();
execv(argc[0], (char* const*)&argc[0]);
std::cerr << "execv failed";
_exit(2);
}
When I run this script it calls test_tokenizer(), it will print 'execv failed'. (Although it prints the arguments nicely).
However if I change test_tokenizer to test_raw it runs fine.
It must be some easy solution but I didn't find it.
PS.: I also drop this into an online compiler with boost support here.
boost::tokenizer saves the token by value (and by default as std::string) in the token iterator.
Therefore the character array that argument->c_str() points to may be modified or invalidated when the iterator is modified and its lifetime will end with that of argument at the latest.
Consequently your program has undefined behavior when you try to use argc.
If you want to keep using boost::tokenizer, I would suggest to keep the tokens in a std::vector<std::string> and transform them to a pointer array afterwards.
I read code in buf0buf.cc of mysql's innodb buffer source code here:
link from git hub
And I got this:
&buf_pool->watch[0]
What is the value of the statement? address? or another value?
What does the code mean?(grammar meaning)
Due to operator precedence, this expression is parsed like:
&( (buf_pool->watch)[0] )
In English, the value is the address of the first element of the watch member container in buf_pool.
You can find out.
First of all, let's take the buf_bool variable and look for its declaration. As you can see a few lines above, it's a function parameter:
const buf_pool_t* buf_pool
This means we have to find the definition of the buf_pool_t type. With a mere full-text search, the type definition is not revealed. However, googling for "mysql buf_pool_t" gets us to http://www.iskm.org/mysql56/structbuf__pool__t.html, which in turn tells us that the type is defined in a file called buf0buf.h. That one's also included in the source file you've linked to:
#include "buf0buf.h"
It does indeed contain the definition we are looking for, and that definition includes a member called watch:
struct buf_pool_t{
(...)
buf_page_t* watch;
(...)
};
watch is a pointer to buf_page_t.
So if we go back to the statement in your question:
&buf_pool->watch[0]
watch is interpreted as a pointer to the first element of a buf_page_t array, watch[0] is the first element itself, and the address-of operator yields a pointer to that first element.
So the whole statement reads as:
a pointer to the first element of a buf_page_t array.
Curiously, &buf_pool->watch[0] is equal to buf_pool->watch. Here is a simple (C++11) toy program to verify all of this:
#include <iostream>
#include <typeinfo>
using buf_page_t = int;
struct buf_pool_t {
buf_page_t* watch;
};
int main()
{
const buf_pool_t example = { new buf_page_t[1] };
const buf_pool_t* buf_pool = &example;
std::cout << typeid(&buf_pool->watch[0]).name() << "\n";
std::cout << typeid(buf_pool->watch).name() << "\n";
std::cout << (&buf_pool->watch[0] == buf_pool->watch) << "\n"; // prints 1
}
&buf_pool->watch[0] is the the address of the member 0 of watch contained in the struct buf_bool. Which is watch itself.
It is parsed like that because the whole buf_pool->watch[0] gets under the & (address of) sign.
You can check with this snippet:
#include <iostream>
#include <stdio.h>
using namespace std;
struct hello_t
{
int before;
int array[5];
};
int main() {
// your code goes here
struct hello_t hello;
hello.array[0] = 100;
struct hello_t* ptr_hello;
ptr_hello = &hello;
printf("ptr_hello = %X\n", ptr_hello);
printf("&ptr_hello = %X\n", &ptr_hello);
printf("&ptr_hello->before = %X\n", &ptr_hello->before);
printf("&ptr_hello->array[0] = %X\n", &ptr_hello->array[0]);
printf("");
return 0;
}
https://ideone.com/fwDnoz
I am a java programmer trying to teach myself c++. Please cut me a little slack if I ask simple questions at first.
I would like to understand how the structure dereference operator works. Specifically, can anyone tell me what the following line of code does in explicit terms?
if (elements[i]->test(arga, argb)) {}
test(arga,argb) is a Boolean function in the same class, and elements is a vector of instances of the element class. Here is the code that immediately surrounds the line above, about which I am interested:
for (unsigned i = 0; i < elements.size(); ++i) {
T arga = INFINITY, argb = INFINITY;
//using namespace std;
//std::cout >> elements[i] >> std::endl;
//std::cout >> test(arga, argb) >> std::endl;
if (elements[i]->test(arga, argb)) {
//some code
}
}
It seems that the if line is testing to see whether or not the boolean returned by test(arga,argb) is part of the given instance of the elements class. But when I try to expose the underlying values of elements[i] or test(arga,argb) with the cout lines above, the compiler throws errors until I comment those lines out. In java, I would be able to fiddle around with this until I found values of each that correspond with each other, and then I would understand the line of code. But I do not know how to figure out what this line of code does in C++. Can anyone give me a clear explanation, preferably supported by a link or two to some references online?
elements[i]->test (arga, argb)
If we break down the statement, reading from left-to-right, we will end up with the below:
access the ith element in an array (or array-like) entity named elements
the element accessed (elements[i]) is a pointer to an object
call the member-function named test on elements[i] and pass it two arguments; arga and argb
if we disregard the fact that you wrote std::cout >> instead of std::cout << (the latter is the correct form), we end up with two reasons for your described errors:
your compiler complains about std::cout << element[i] because no suitable overload is found to handle an entity of the type of element[i] and an std::ostream& (which is the underlying type of std::cout).
your compiler complains about std::cout << test (arga, argb) because there is no function in scope named test that takes two arguments corresponding to arga, argv. test, in your snippet, is a member-function that belongs to an entity, it's not callable by its own.
Welcome to C++.
First, the syntax for output is:
cout<<
instead of
cout>>
You are right in guessing that test is a function that returns boolean.Here elements[i] is a pointer pointing to a struct element which has this test function.
To learn C++, you can use these articles that I wrote.Good luck!
Since numerous respondents told me that I need to provide the code before they can answer, I looked deeper in the code, and re-wrote something which tells me that the line:
if (elements[i]->test(arga, argb)) {}
is a test to see whether or not the boolean member function of elements[i] is true.
The c++ program that I wrote to identify the meaning of -> in this context is:
#include "stdafx.h"
#include <vector>
#include <string>
#include <iostream>
template<typename T>
class Bone
{
public:
std::string myName;
int mySize;
Bone(const std::string &name, const int &size) : myName(name), mySize(size)
{}
bool isBigger(const int &testSize) const
{
if (testSize > mySize) return false;
else return true;
}
};
int main(int argc, char **argv)
{
std::vector<Bone<float> *> bones;
// name, location, size
bones.push_back(new Bone<float>("femur", 10));
bones.push_back(new Bone<float>("ulna", 4));
bones.push_back(new Bone<float>("maxilla", 3));
int testSize = 6;
// test each bone to see if it is bigger than testSize
for (unsigned i = 0; i < bones.size(); ++i) {
if (bones[i]->isBigger(testSize)) {
std::cout << bones[i]->myName; std::cout << " is bigger than testSize! " << std::endl;
}
}
while (!bones.empty()) {
Bone<float> *thisBone = bones.back();
bones.pop_back();
delete thisBone;
}
return 0;
}
Thank you to everyone who led me to figure this out.
I am asked to create "customizable exception framework" using boost::exception. Till date I used only simple exceptions defined by me. So std::exception,boost::exception are new to me. The code is below.
#include <iterator>
#include<string>
#include <algorithm>
#include<errno.h>
struct My_exception:public virtual boost::exception
{
};
int main()
{
std::string fileName="tmp.txt";
std::string mode="r";
try
{
if(fopen(fileName.c_str(),mode.c_str()))
std::cout << " file opened " << std::endl ;
else
{
My_exception e;
e << boost::errinfo_api_function("fopen") << boost::errinfo_file_name(fileName)
<< boost::errinfo_file_open_mode(mode) << boost::errinfo_errno(errno);
throw e;
}
}
catch(My_exception e)
{
// extract the details here //
}
return 1;
}
Now, I want to know that how to extract the data from that caught exception. Can anybody guide me in the path of boost::exception
First of all, your code has error, for example you cannot write this:
e << boost::errinfo_api_function("fopen")
Because errinfo_api_function can be used with int only. So do something like this:
e << boost::errinfo_api_function(100) //say 100 is error code for api error
See the second type parameter to errinfo_api_function1, it's int. Similarly, check other error class templates. I've given the link to each of them you're using, at the end of this post!
1. It seems there're two version of this class template, one which takes int, other which takes const char*. Compare version 1.40.0 errinfo_api_function with version 1.45.0 errinfo_api_function. Thanks to dalle who pointed it out in the comment. :-)
Use get_error_info function template to get data from boost::exception.
See what boost::exception documentation says,
To retrieve data from a
boost::exception object, use the
get_error_info function template.
Sample code:
//since second type of errinfo_file_name is std::string
std::string fileError = get_error_info<errinfo_file_name>(e);
//since second type of errinfo_errno is int
int errno = get_error_info<errinfo_errno>(e);
//since second type of errinfo_file_open_mode is std::string
std::string mode = get_error_info<errinfo_file_open_mode>(e);
//since second type of errinfo_api_function is int
int apiError = get_error_info<errinfo_api_function>(e);
See these for better understanding:
errinfo_file_name
errinfo_errno
errinfo_file_open_mode
errinfo_api_function