how to access value in tcl script from .cc files - c++

I'm trying to get value from .cc. In my file ,
AgentCPU.h and AgentCPU.cc
there is a integer called "npkts_" and a function "recv" for receive Packets
when I finally finished a packet , I will increase the "npkts_" 1
In further , in my tcl script I want to access the "npkts_"
my code is like this
set cpu [new Agent\AgentCPU]
puts [format "%d" "$cpu set npkts_"]
However , ther value is not correct
it is same to the value when I construct my AgentCPU like this
AgentCPU::AgentCPU(): Agent(PT_TASK)
{
...
npkts_=199;
...}
the value will be 199,
and in the "recv" function , I use "printf" to check if there is any problem
...
npkts_++;
printf("npkts is %d\n",npkts);
...
and the value here is correct,every time I receive Packet will increase the "npkts"
Is there any code wrong??
On the other hand, I use another way to debug
In my "recv" function
...
npkts_++;
Tcl& tcl = Tcl:;instance();
tcl.evalf("puts \" npkts is %d""",npkts_);
..
In this way the message will be 1, and stop to print
Can sombody give me a hand?
How to get the correct value from .cc file?
Any suggestion will be very thankful!!

In Tcl, every script evaluation produces a result value (which could be the empty value, or could be something else, depending on what happened). That result value may be retrieved from the interpreter context with Tcl_GetStringResult or Tcl_GetObjResult; the former produces (effectively) a const char * and the latter a Tcl_Obj * (i.e., a Tcl value reference; the name Tcl_Obj is for historical reasons). That value is there until the next piece of script is evaluated. Do not modify the Tcl_Obj* returned (except via Tcl's API) unless you know exactly what you're doing (i.e., are writing code to extend Tcl itself). Integers may be efficiently retrieved from a Tcl_Obj* using Tcl_GetIntFromObj (assuming that the value is an integer), floating point numbers with Tcl_GetDoubleFromObj, and a const char * can be retrieved from a Tcl_Obj* using Tcl_GetString or Tcl_GetStringFromObj (slightly different API).
There are also variables in Tcl. You can read those directly with Tcl_GetVar — which returns another const char * — or Tcl_GetVar2Ex (with an ugly name but convenient API) that returns another Tcl_Obj *.
These are all C API functions and all take a Tcl_Interp * (which is a reference to a Tcl evaluation context, which is always bound to a single thread). How they have been wrapped in the C++ API… I can't tell you that.

You are using some weird C++ library you are not giving any information about. However, when using Tcl from a C/C++ program when you evaluate some Tcl code the result is available attached to the interpreter object. You access this using Tcl_GetObjResult and then use an appropriate Tcl_GetIntFromObj or Tcl_GetDoubleFromObj or whatever to read the Tcl_Obj value into some C++ form.

Related

Dealing with special characters in CLI11

I have code like the following
flags->add_option("--name", name_, "The name.")->required();
I want to be able to pass strings like "aa$p$aa" to the --name parameter. However, this does not seem to work with CLI11, and the name gets truncated to just "aa". I need to escape the $ characters to properly read the strings. So aa\$p\$aa works fine, and I get the expected string ("aa$p$aa").
Changing the function to add_flag() does not work either.
Is there a way to be able to pass arbitrary strings to a parameter as with either function calls above?
Your operating system takes the command you type in and executes the given program, passing the parameters to it.
The interpolation, and the handling of $ characters in typed-in commands is handled by your operating system as part of executing the typed-in command. Your compiled C++ program receives the transformed arguments, as parameters. Your C++ program has no means to control what has happened before it was even executed.

How can I replicate compile time hex string interpretation at run time!? c++

In my code the following line gives me data that performs the task its meant for:
const char *key = "\xf1`\xf8\a\\\x9cT\x82z\x18\x5\xb9\xbc\x80\xca\x15";
The problem is that it gets converted at compile time according to rules that I don't fully understand. How does "\x" work in a String?
What I'd like to do is to get the same result but from a string exactly like that fed in at run time. I have tried a lot of things and looked for answers but none that match closely enough for me to be able to apply.
I understand that \x denotes a hex number. But I don't know in which form that gets 'baked out' by the compiler (gcc).
What does that ` translate into?
Does the "\a" do something similar to "\x"?
This is indeed provided by the compiler, but this part is not member of the standard library. That means that you are left with 3 ways:
dynamically write a C++ source file containing the string, and writing it on its standard output. Compile it and (providing popen is available) execute it from your main program and read its input. Pretty ugly isn't it...
use the source of an existing compiler, or directly its internal libraries. Clang is probably a good starting point because it has been designed to be modular. But it could require a good amount of work to find where that damned specific point is coded and how to use that...
just mimic what the compiler does, and write your own parser by hand. It is not that hard, and will learn you why tests are useful...
If it was not clear until here, I strongly urge you to use the third way ;-)
If you want to translate "escape" codes in strings that you get as input at run-time then you need to do it yourself, explicitly.
One way is to read the input into one string. Then copy the characters from that source string into a new destination string, one by one. If you see a backslash then you discard it, fetch the next character, and if it's an x you can use e.g. std::stoi to convert the next few characters into its corresponding integer value, and append that number to the destination string (either adding it with std::to_string, or using output string streams and the normal "output" operator <<).

C++ passing variable number of locations from a given array to a function

The following piece of code works in C++ when running on Windows:
void* paramsList[MAX_PARAMS_NUM] = { 0 };
...some code to populate paramsList (p.s MAX_PARAMS_NUM is a constant)
vsnprintf((char*)pStr, MAXLEN, (char*)pTempFormat, (va_list)paramsList);
This code works fine on Windows, but i am trying to make it run on Linux and the program crushes because this conversion of paramsList to va_list doesn't work there.
Now the setting of this scenario is that i get a format string from a server that i don't control. The format string ('pTempFormat') is like the one used in printf of unknown number of % in it (maximum is MAX_PARAMS_NUM) and i populate the paramsList accordingly and then i use vsnprintf to create a string from the format string i got and the values populated in paramsList.(those values can be anything from integers, to hex to char * (aka strings) and any combination of them, according to the format string received from the server).
i don't know how many locations paramsList to pass to vsnprintf until i finish populating it according to the format string received from the server. So i need to somehow either pass a variable number of locations from paramsListto vsnprintf or to convert those locations into va_list (which i couldn't figure out how to do from what i read online).
I also considered using a combination of variadic templates and va_list - to somehow pass a variable number of locations from paramsListto a variadic function and to pass them on to vsnprintf. But i couldn't figure out how to pass certain locations from a given array to a variadic function either.
Update:
I use Visual Studio 2015 to compile on Windows, and GCC 4.9 on Ubuntu.
The error i am getting when trying to compile this code on Linux is: error: ISO C++ forbids casting to an array type 'va_list {aka __va_list_tag [1]}'
va_list is an unspecified type. That means it may be a void* [] or something else entirely.
That it worked by chance in some cases is just that va_list is compatible with void* [] on one particular platform for one compiler, it is by no means indication that this is legal.
The correct way to deal with this is, unfortunately, to stop using the printf family and parse the format string yourself, there is no standard functionality to reach in and fetch the parsed format string to use for yourself.

sqlite3 bind variables syntax

I am trying to implement a C++11 wrapper to C API of SQLite, particularly to sqlite3_bind functions. I would like it to be something in the shape of this (example from my code):
sqlt3::exec<void>(
_db,
"INSERT OR REPLACE INTO window VALUES('position', ?3, ?4);\n"
"INSERT OR REPLACE INTO window VALUES('size', ?1, ?2);\n"
"INSERT OR REPLACE INTO window VALUES('maximized', ?5, '0');\n",
size.x,
size.y,
position.x,
position.y,
static_cast<int>(IsMaximized())
);
The problem here is that ? are shared between different statements. The exec function internally prepares subsequent SQL statements one by one. So I cannot determine which parameters should be bound to which statements, because there is no API to get which statement slots the statement contains. I can get the count of slots n (a max NNN from all ?NNNs) but I am unable to determine whether particular slots from zero to the n are actually occupied. It is because there can be single ? with no number and sqlite3_bind_parameter_name returns NULL for both the nameless parameter and the lack of parameter. Ideally I would like to have some function that returns a list of indexes of binding points that are used in the given statement or at least some way to discriminate whether given index has associated 'nameless' binding point or no binding point at all.
One solution that I came upon is to bind all parameters, in the order they are passed to the exec, to all of the statements but I didn't found in the documentation is it legal to bind to nonexistent parameter. Another drawback is that the complexity is v times s where v is number of variables to be bound and s is number of statements.
So, I came with another workaround to just parse whole string passed to exec and gather info about binding points (?, ?NNN, :VVV etc.). But, I think it isn't quite trivial task because that special symbol are not special in some contexts like string and quatations. So, what are another contexts in SQL statements, in which special tokens ?, ?NNN, etc. have not meaning of binding points?
Some explanations:
"Trying to parse SQL is pointless."
I do not want to parse SQL, only detect presence and indexes of arguments (binding points).
"Do you really think v*s will become large enough that it matters?"
In common case no, but still I do not know if it is legal to bind parameter to slot that wasn't occurred in statement. And there is a problem with ?, if it occurs at the beginning of second sentence, it should not has index 1, it should rather have index of the last binding point in previous sentence increased by 1.
"And why do you want to allow multiple statements in a single function call?"
I found ability to do that very handy, especially when you need to execute them in one transaction.

How to print elements from tcl_obj in gdb?

I am debugging a c++-tcl interface application and I need to see the elements of Tcl_Obj objv.
I tried doing print *(objv[1]) and so on but it doesnt seem helping.
Is there any way to see Tcl_Obj elements in gdb?
It's not particularly easy to understand a Tcl_Obj * from GDB as the data structure uses polymorphic pointers with shrouded types. (Yeah, this is tricky C magic.) However, there are definitely some things you can try. (I'll pretend that the pointer is called objPtr below, and that it is of type Tcl_Obj *.)
Firstly, check out what the objPtr->typePtr points to, if anything. A NULL objPtr->typePtr means that the object just has something in the objPtr->bytes field, which is a UTF-8 string containing objPtr->length bytes with a \0 at objPtr->bytes[objPtr->length]. A Tcl_Obj * should never have both its objPtr->bytes and objPtr->typePtr being NULL at the same time.
If the objPtr->typePtr is not NULL, it points to a static constant structure that defines the basic polymorphic type operations on the Tcl_Obj * (think of it as being like a vtable). Of initial interest to you is going to be the name field though; that's a human-readable const char * string, and it will probably help you a lot. The other things in that structure include a definition of how to duplicate the object and how to serialize the object. (The objPtr->bytes field really holds the serialization.)
The objPtr->typePtr defines the interpretation of the objPtr->internalRep, which is a C union that is big enough to hold two generic pointers (and a few other things besides, like a long and double; you'll also see a Tcl_WideInt, which is probably a long long but that depends on the compiler). How this happens is up to the implementation of the type so it's difficult to be all-encompassing here, but it's basically the case that small integers have the objPtr->internalRep.longValue field as meaningful, floating point numbers have the objPtr->internalRep.doubleValue as meaningful, and more complex types hang a structure off the side.
With a list, the structure actually hangs off the objPtr->internalRep.twoPtrValue.ptr1 and is really a struct List (which is declared in tclInt.h and is not part of Tcl's public API). The struct List in turn has a variable-length array in it, the elements field; don't modify inside there or you'll break things. Dictionaries are similar, but use a struct Dict instead (which contains a variation on the theme of hash tables) and which is declared just inside tclDictObj.c; even the rest of Tcl's implementation can't see how they work internally. That's deliberate.
If you want to debug into a Tcl_Obj *, you'll have to proceed carefully, look at the typePtr, apply relevant casts where necessary, and make sure you're using a debug build of Tcl with all the symbol and type information preserved.
There's nothing about this that makes debugging a whole array of values particularly easy. The simplest approach is to print the string view of the object, like this:
print Tcl_GetString(objv[1])
Be aware that this does potentially trigger the serialization of the object (including memory allocation) so it's definitely not perfect. It is, however, really easy to do. (Tcl_GetString generates the serialization if necessary — storing it in the objPtr->bytes field of course — and returns a pointer to it. This means that the value returned is definitely UTF-8. Well, Tcl's internal variation on UTF-8 that's slightly denormalized in a couple of places that probably don't matter to you right now.)
Note that you can read some of this information from scripts in Tcl 8.6 (the current recommended release) with the ::tcl::unsupported::representation command. As you can guess from the name, it's not supported (because it violates a good number of Tcl's basic semantic model rules) but it can help with debugging before you break out the big guns of attaching gdb.