Traverse my data structure, and enter random values to it - python

I am having a very big data structure.
Only 1 structure.
Now, this structure has many sub-structures under it and so on.
I have to put random values to each variable of this structure.
I would have done it manually, but there are more than 10000 variables under it.
It's a long and deep structure, that have structure under structure.
for eg -> This is just an example, actual structure is very big
struct qwerty{
unsigned short catch;
unsigned short port;
MediaAuthType_e mediaAuth;
typeShortNatmr NAT;
typeDynEpDom domain;
typeRDomList domainlist;
typeDom domainSize;
};
Now each of these data types has substructure under it
eg for MediaAuthType_e data type above we have a structre as
struct MediaAuthType_e
{
int nunkhdr;
msg_body_list* unknown_msg_body;
int unknown_msg_body_count;
SipLssHandle Handle;
InfoEntry *dfo;
char* ua_uri;
char* accept;
void* s_contact;
char* branch;
char* chargeNum;
int 100Supported;
int 100Required;
};
and so on .
Can someone please help?
I just have to store random values to each of my variables?
Can I automate this process?
EDIT:
Why I am doing this is,
I have to encode the data to xdr format and decode it to get the same value

Following pseudo code will assign random values. However, the pointers will not be valid pointers! It just fills the whole memory area with sequential values.
unsigned long int i; // in case your structure is too Big!
struct MediaAuthType_e *my_MediaAuthType_e;
my_MediaAuthType_e = malloc(sizeof(struct MediaAuthType_e));
char *tmp = (char *)my_MediaAuthType_e;
for(i = 0; i < sizeof(struct MediaAuthType_e); i++)
{
*tmp = (i%255); // Assign some values at each byte, use your logic to assign random values.
tmp++;
}

Related

Multiple functions with pointer as argument, false calculations

I have an numpy-array (arr) of type integer which is passed to a C-function with ctypes. I narrowed it down to a simple example. I have this three functions:
int fun(void *arr, void *arr_out){
fun2(arr,arr_out);
return(1);
}
void fun2(int *arr, double *arr_out){
for(int i = 0; i<10; i++){
*(arr_out+i) = calc((arr+i));
}
}
double calc(int *in){
return (double)((log(*in)*-0.15)/1.76);
}
Do I use the pointers in right way? My outputs looks kind of random. As if the pointer itself is in someway part of the calculation and not the value?

Python to C conversion, reading columns of csv into arrays

I am looking to read a csv file line by line and write each column to arrays in C. Essentially I want to convert the following Python code to C:
import csv
date = []
x = []
y = []
with open("file.csv") as old:
read = csv.reader(old,delimiter = ',')
for row in read:
date.append(row[0])
x.append(float(row[1]))
y.append(float(row[2]))
The csv file has 128 rows and three columns; date,x,y. My thoughts:
char Date[];
int Date[128], i;
for(i = 0; i < 128; i++)
{
Date[i] = x;
}
This is a simple example I have attempted to fill an array with values within a for loop. I want to know how I can modify this to fill arrays with each line of a csv file split by the ',' delimiter? I want to use the fscanf function but am unsure about how to incorporate it into the above setting?
Attempt:
FILE* f = fopen("file.csv", "r");
fscanf(f, "%char, %f %f", time, &value, &value);
Update:
The following code reads in a text file of my data and outputs to the screen:
#include <stdio.h>
int main(void)
{
char buff[128];
FILE * myfile;
myfile = fopen("File.txt","r");
while (!feof(myfile))
{
fgets(buff,128,myfile);
printf("%s",buff);
}
fclose(myfile);
return 0;
}
Instead of outputting to the screen, I want to store each column as an array. Any suggestions on how to do this?
Update 2.
I have updated the code as follows:
#include <stdio.h>
#include<string.h>
int main(void)
{
char buff[128];
char * entry;
FILE * myfile;
myfile = fopen("file.txt","r");
while(fgets(buff,128,myfile)){
puts(buffer);
entry = strtok(buff,",");
while(entry!=NULL)
{
printf("%s\n",entry) ;
entry = strtok(NULL,",");
}
}
return 0;
}
Final Update.
I have found an example that does something very similar and is much more intuitive for me (given my limited ability in C)
https://cboard.cprogramming.com/c-programming/139377-confused-parsing-csv-txt-file-strtok-fgets-sscanf.html
Updated code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char line[200];
int i = 0;
int x[50];
int y[50];
int z[50];
FILE *myFile;
myFile = fopen("file.txt", "rt");
while(fgets(line, sizeof line, myFile) != NULL)
{
if(sscanf(line, "%d,%d,%d", &x[i], &y[i],&z[i]) == 3)
{
++i;
}
}
//Close the file
fclose(myFile);
getch();
return 0;
}
This code works for me provided $x$, $y$ and $z$ are integers/floats. However, when $x$ is a date, I am unable to parse it. The date is of the form $Year-Month-day-Time$.
My attempt
I have tried changing the line
if(sscanf(line, "%d,%d,%d", &x[i], &y[i],&z[i]) == 3)
to
if(sscanf(line, "%d-%d-%d-%d",&year[i],&month[i], &day[i],&time[i], "%d,%d", &y[i],&z[i]) == 3)
and have declared new arrays
int year, int month, int day, int time
However, this approach gives garbage as the output. Any suggestions on how to modify this code to read and parse dates correctly?
You can use strtok to split a string by delimiter.
This describes the function. It includes a simple example.
Each call gives you a substring, ending where the delimiter was found. You can then copy that substring into a string in an array of strings (of max length, if you know the max length) (or you can have an array of pointers to strings, and allocate memory for each one before the copy to strlen(substring) + 1 (+1 for NULL terminator).
Note that strtok temporarily modifies the existing string, so you must either use it right away or copy it. If you just save a pointer to what strtok returns, when you finish the sequence of strtok calls the string will be restored to its original form and your "substrings" will not be what you expect. (See answer to this question for an explanation.)
And, please do not use !feof(myfile) to control the exit from your loop. See this post for an explanation. Since BradS gave an alternative in his comment, and it is not your main question, I won't repeat him here.
OK, looking at your sscanf approach and your question about dates:
I have used the various scanf and printf functions many times; I have never seen two different format strings in the same call, with parameters in the middle. From the function prototypes, this can't work. I think the only reason it compiles is because the variable parameter list in a variadic function does not have type checking. It will simply ignore these parameters: "%d,%d", &y[i],&z[i], because these are output parameters which do not correspond to anything in the format string. You can do something like:
if(sscanf(line, "%d-%d-%d-%d,%d,%d",&year[i],&month[i], &day[i],&time[i],&y[i],&z[i]) == 6)
This includes all the parameters in the format string.
Also, you mention creating arrays like this:
int year, int month, int day, int time
Those are not arrays. They are simple integers. You can declare an array like:
int year[MAX_SIZE];
I personally have found the scanf set of functions rather difficult to deal with; if the format string doesn't quite match the reality in the string you won't get what you expect/need. That is why I like strtok. But not everyone is comfortable with it; it is not the most obvious or intuitive interface.

printing struct array in lldb python

Following the question here: Writing a Python script to print out an array of recs in lldb
I would like to be able to create a type summary for an array of a given struct in lldb. Problem is that I am not able to access array correctly through python-lldb. Some data is incorrect.
I have the following test code in C:
#include <stdio.h>
#include <stdlib.h>
struct Buffer
{
struct Buffer* next;
struct Buffer* prev;
};
struct Base
{
struct Buffer* buffers;
int count;
};
void fill(struct Buffer* buf, int count)
{
for (int i = 0; i < count; ++i)
{
struct Buffer t = {(void*)0xdeadbeef,(void*)i};
buf[i] = t;
}
}
void foo(struct Base* base)
{
printf("break here\n");
}
int main(int argc, char** argv)
{
int c = 20;
void* buf = malloc(sizeof (struct Buffer) * c);
struct Base base = {.buffers = buf, .count = c};
fill(base.buffers, base.count);
foo(&base);
return 0;
}
In lldb:
(lldb) b foo
(lldb) r
(lldb) script
>>> debugger=lldb.debugger
>>> target=debugger.GetSelectedTarget()
>>> frame=lldb.frame
>>> base=frame.FindVariable('base')
>>> buffers=base.GetChildMemberWithName('buffers')
Now, buffers should point to array of struct Buffer and I should be able to access each and every Buffer via the buffers.GetChildAtIndex function, but the data is corrupted in the first 2 items.
>>> print buffers.GetChildAtIndex(0,0,1)
(Buffer *) next = 0x00000000deadbeef
>>> print buffers.GetChildAtIndex(1,0,1)
(Buffer *) prev = 0x0000000000000000
>>> print buffers.GetChildAtIndex(2,0,1)
(Buffer) [2] = {
next = 0x00000000deadbeef
prev = 0x0000000000000002
}
Only the buffers[2] and up items are ok.
Why does print buffers.GetChildAtIndex(1,0,1) points to buffers[0].count item instead of buffers[1]?
What am I doing wrong?
GetChildAtIndex is trying to be a little over-helpful for your purposes here. It is in accord with the help, which says:
Pointers differ depending on what they point to. If the pointer
points to a simple type, the child at index zero
is the only child value available, unless synthetic_allowed
is true, in which case the pointer will be used as an array
and can create 'synthetic' child values using positive or
negative indexes. If the pointer points to an aggregate type
(an array, class, union, struct), then the pointee is
transparently skipped and any children are going to be the indexes
of the child values within the aggregate type. For example if
we have a 'Point' type and we have a SBValue that contains a
pointer to a 'Point' type, then the child at index zero will be
the 'x' member, and the child at index 1 will be the 'y' member
(the child at index zero won't be a 'Point' instance).
So really, buffers.GetChildAtIndex(2,0,1) should have returned "No Value". Either that or passing 1 for the allow-synthetic argument should turn off this peek-through behavior. In either case, this is a bug, please file it with http://bugreporter.apple.com.
In the mean time you should be able to get the same effect by walking your array by hand and using "SBTarget.CreateValueFromAddress to create the values. Start by getting the address of the array with buffers.GetAddress(); and the size of Buffers by getting the type of buffers, getting its Pointee type & calling GetByteSize on that. Then just increment the address by the size count times to create all the values.

OUT argument internally allocated to return an array of structs

I'm new to swig and I have the following function which i cant fix:
int get_list(IN const char * string, OUT struct entry ** results);
where struct entry is defined:
struct flux_entry
{
char * addr_str;
char cc[2];
};
the entry struct is properly converted to a python class.
I googled but couldn't find any explanation i could use.
I want to make it return a tuple of: (original get_list int return value, python list of entry python objects, based on the results buffer), but don't know how to convert the C entry to a python object in the argout code snippet.
I've managed to get thus far:
%typemap(argout) struct entry **
{
PyObject *o = PyList_New(0);
int i;
for(i=0; $1[i] ; i++)
{
PyList_Append(o, SWIG_HOW_TO_CONVERT_TO_PYOBJECT($1[i]));
}
$result = o;
}
what should i replace SWIG_HOW_TO_CONVERT_TO_PYOBJECT with?
passed results is supposed to be a pointer to a (struct entry *) type, set to NULL before calling get_list and should be set to an allocated array of struct entry * pointers. maybe a small wrapper function could make that easier?
the struct entry array is allocated within the C function using malloc, after calculating (inside get_list) how many elements are needed, and ends with a NULL pointer to indicate the end of the array.
i'd also like to make sure it's freed somewhere :)
thanks!
This should at least give you a starting point that works. I still wasn't sure how the data was returned, since to return an array of pointers so that the final one was NULL I'd think you'd need a struct entry ***, so I just set addr_str = NULL on the last one as a sentinel, and just put some dummy data partially based on the input string into the fields. Modify as needed to suit your needs:
%module example
// Insert the structure definition and function to wrap into the wrapper code.
%{
struct entry {
char* addr_str;
char cc[2];
};
int get_list(const char* string, struct entry** results)
{
*results = malloc(3 * sizeof(struct entry));
(*results)[0].addr_str = malloc(10);
strcpy((*results)[0].addr_str,"hello");
(*results)[0].cc[0] = string[0];
(*results)[0].cc[1] = string[1];
(*results)[1].addr_str = malloc(10);
strcpy((*results)[1].addr_str,"there");
(*results)[1].cc[0] = string[2];
(*results)[1].cc[1] = string[3];
(*results)[2].addr_str = NULL;
return 0;
}
%}
#include <typemaps.i>
// Define the structure for SWIG
struct entry {
char* addr_str;
char cc[2];
};
// Define a set of typemaps to be used for an output parameter.
// This typemap suppresses requiring the parameter as an input.
// A temp variable is created and passed instead.
%typemap(in,numinputs=0) struct entry **OUTPUT (struct entry* temp) %{
$1 = &temp;
%}
// Build a list of tuples containing the two entries from the struct.
// Append the new Python list object to the existing "int" result.
%typemap(argout) struct entry **OUTPUT {
int i = 0;
PyObject* out = PyList_New(0);
while((*$1)[i].addr_str != NULL)
{
//PyObject* t = PyTuple_New(2);
//PyTuple_SET_ITEM(t,0,PyBytes_FromString((*$1)[i].addr_str));
//PyTuple_SET_ITEM(t,1,PyBytes_FromStringAndSize((*$1)[i].cc,2));
//PyList_Append(out,t);
//Py_DECREF(t);
PyObject* s = SWIG_NewPointerObj(*$1+i,$descriptor(struct entry*),0);
PyList_Append(out,s);
Py_DECREF(s);
++i;
}
$result = SWIG_AppendOutput($result,out);
}
// Since a Python object was created and the data copied for each entry struct,
// free the memory returned in the structure.
//%typemap(freearg) struct entry **OUTPUT {
// int i=0;
// while((*$1)[i].addr_str != NULL) {
// free((*$1)[i].addr_str);
// ++i;
// }
// free(*$1);
//}
// Apply the OUTPUT typemap set to the "results" parameter.
%apply struct entry **OUTPUT {struct entry** results};
// Finally, define the function for SWIG
int get_list(const char* string, struct entry** results);
Demo (Python 3.3):
>>> import example
>>> example.get_list('abcd')
[0, [(b'hello', b'ab'), (b'there', b'cd')]]
Hope that helps.
Edit:
I commented out the tuple creation and just save the entry* proxy instead. This doesn't leak Python objects, but the memory malloced for use by an entry* is not freed. I'm not sure where to put that, although I'm experimenting with %extend.

Writing a Python C extension: how to correctly load a PyListObject?

While attempting to read a Python list filled with float numbers and to populate real channels[7] with their values (I'm using F2C, so real is just a typedef for float), all I am able to retrieve from it are zero values. Can you point out the error in the code below?
static PyObject *orbital_spectra(PyObject *self, PyObject *args) {
PyListObject *input = (PyListObject*)PyList_New(0);
real channels[7], coefficients[7], values[240];
int i;
if (!PyArg_ParseTuple(args, "O!", &PyList_Type, &input)) {
return NULL;
}
for (i = 0; i < PyList_Size(input); i++) {
printf("%f\n", PyList_GetItem(input, (Py_ssize_t)i)); // <--- Prints zeros
}
//....
}
PyList_GetItem will return a PyObject*. You need to convert that to a number C understands. Try changing your code to this:
printf("%f\n", PyFloat_AsDouble(PyList_GetItem(input, (Py_ssize_t)i)));
Few things I see in this code.
You leak a reference, don't create that empty list at the beginning, it's not needed.
You don't need to cast to PyListObject.
PyList_GetItem returns a PyObject, not a float. Use PyFloat_AsDouble to extract the value.
If PyList_GetItem returns NULL, then an exception has been thrown, and you should check for it.

Categories