How to get the node name with Graphviz and libcgraph? - c

I'm trying to update some old code which used to work with Graphviz 2.26 and iterated over all the nodes of a graph and did something with their names:
for (Agnode_t *n = agfstnode(graph); n; n = agnxtnode(graph, n)) {
... use n->name ...
}
However in recent (2.30+?) versions of Graphviz, cgraph library is used for node representation and it doesn't have name field in its Agnode_t struct.
I know about agnode() function which allows to lookup the node by name, but there doesn't seem to be any function to go in the other direction. Am I missing something or is there really no way to access the name of the existing node with cgraph?

You can use the function agnameof, which is listed in the "Generic Objects" section of the cgraph manpage:
char *agnameof(void*);

Related

How to create a soap_dom_element to assign it to __any with gSOAP in C?

I am trying to port these C++ line to C with gSOAP library:
trt__Capabilities *capabilities = ctx->getMediaServiceCapabilities(this->soap);
tds__GetServicesResponse.Service.back()->Capabilities->__any = soap_dom_element(this->soap, NULL, "trt:Capabilities", capabilities, capabilities->soap_type());
I thought this would do it but soap_dom_element cannot be used like this in the C gSOAP API
tds__GetServicesResponse->Service[1].Capabilities->__any = soap_dom_element(soap, NULL, "trt:Capabilities", capabilities, SOAP_TYPE__tds__Service_Capabilities);
Another thing I tried that compiles but crash at runtime
struct trt__Capabilities *capabilities = fillServiceCapabilities(ctx, soap);
char * tag = "trt:Capabilities";
char * type = "";
int id = -1;
soap_element_begin_out(soap, tag, soap_embedded_id(soap, id, capabilities,
SOAP_TYPE_trt__Capabilities), type);
void * elt = soap_element_end_out(soap, tag);
soap_add_elt(&tds__GetServicesResponse->Service[1].Capabilities->__any, elt);
Please someone help me find the correct way to create a new dom element and assign it to a "struct soap_dom_element __any" object.
Thanks!
All you need to do is simply set the __any member to a dynamically allocated DOM node with soap_elt_new:
tds__GetServicesResponse->Service[1].Capabilities->__any = soap_elt_new(soap, NULL, "trt:Capabilities”);
and then set the serializable "node" and "type" values of this DOM node to the serializable C capabilities data of type tds__Service_Capabilities:
soap_elt_node(tds__GetServicesResponse->Service[1].Capabilities->__any, capabilities, SOAP_TYPE__tds__Service_Capabilities);
This serializes capabilities as element <trt:Capabilities>.
See the gsoap C DOM API documentation.
EDIT: I meant soap_elt_node rather than soap_dom_node as corrected above.

How to visualize a graph made with igraph in C?

I started to learn igraph in C and I was wondering how can I visualize a graph made with this library. I've seen that with igraph R one just use the plot function and the graph is plotted but if I use C, should I print the graph in a file and then use another program to visualize it or which is the usual way?
Thanks!
edit: This kind of graph.
Follow the Unix philosophy, and have your program output the description of the graph (in text format, or in an easily processed form if no pure text format is easily available).
(Note that this also applies to image formats; the NetPBM (.pnm, or .pbm, .pgm, and .ppm) formats are easy to generate in pure C (to e.g. standard output), and if necessary, the NetPBM tools can be used to convert to any other image format you might wish.)
For example, if your program outputs
graph {
rankdir=LR;
"6" -- "4";
"4" -- "5";
"3" -- "4";
"3" -- "2";
"5" -- "2";
"5" -- "1";
"2" -- "1";
}
then redirecting the output to e.g. output.dot and running dot -Tx11 output.dot will output a graph similar to the one shown in the Wikipedia Graph article,
You mention that you are using igraph, and luckily this library already supports writing graphs in the DOT format. See the igraph_write_graph_dot() function.
The DOT language is specified here, but it really is quite simple. -- denotes an undirected edge, and -> a directed edge. The rankdir=LR; line is a graph attribute, and tells DOT that it should try to order the nodes seen from left to right. The default is from top to bottom. You can add node attributes too, for example "6" [ label="Six" ]; would change the label of node "6" to Six. Edge attributes work exactly the same way; so using "2" -- "1" [ taillabel="Z" ]; adds "Z" near node "2" end of the edge between nodes "2" and "1". It is best to quote node names, even though the quotes are not necessary if the node name starts with a letter and does not match a graph attribute name.
Here is a useful hint, when printing trees or linked lists:
Use %p (a pointer to the node) as the node name, and label="value" to set the visible label of the node to value. For example, if you have
struct node {
struct node *left;
struct node *right;
int value;
};
then a simple function pair,
void print_tree_recursive(FILE *out, struct node *curr)
{
fprintf(out, " \"%p\" [ label=\"%d\" ];\n", (void *)curr, curr->value);
if (curr->left) {
print_tree_recursive(out, curr->left);
fprintf(out, " \"%p\" -> \"%p\" [ taillabel="L" ];\n", curr, curr->left);
}
if (curr->right) {
print_tree_recursive(out, curr->right);
fprintf(out, " \"%p\" -> \"%p\" [ taillabel="R" ];\n", curr, curr->right);
}
}
void print_tree(FILE *out, struct node *tree)
{
fprintf(out, "digraph {\n");
if (tree)
print_tree_recursive(out, tree);
fprintf(out, "}\n");
fflush(out);
}
will print a nice directed graph of any tree. It is easy to modify to print linked lists (both singly and doubly linked). Note how the helper function describes the node first (the fprintf with label=), and the edges separately (the fprintfs with taillabel=).
If you print the graph to standard output, you can either redirect the output to a file and display or convert it using dot -Tformat filename, or you can pipe the output directly to | dot -Tx11 to see the generated graph.
I frequently use the Graphviz DOT format for checking whether my mental picture of data structure linkage matches the reality. I find it an extremely useful tool, and keep recommending it for anyone working with complex data structures.
To plot directed graphs try GraphViz (https://www.graphviz.org).
Alternatively you could use a tool like Gephi (https://gephi.org) if you are willing to write the data into a file in a manner compliant with one of their supported formats (https://gephi.org/users/supported-graph-formats/). GML looks pretty straight forward.

delete all entries from concurrent hashmap in linux kernel

I'm writing a kernel module, that uses a module-wide hashmap to store connections. I want to release all these connections, when the module is unloaded, delete them from the hashmap and then delete the whole map.
I defined the hashmap:
#define CONNECTIONS_HASH_BITS 10
static DEFINE_HASHTABLE(connection_hashtable, CONNECTIONS_HASH_BITS);
add entries with
hash_add_rcu(connection_hashtable, &con->t_hash,
oat_hash(&con->key, sizeof(struct hash_key)));
and finally want to delete all entries:
struct connection *result = NULL;
struct hlist_node *node;
unsigned int i;
hash_for_each_rcu(connection_hashtable, i, node, result, t_hash)
{
hash_del_rcu(node);
}
My questions:
Can I delete in the for loop hash_for_each_rcu?
How do I make this threadsafe?
Do I need to call something like free_hash for hashmap? (My guess here is no as it is an array and no kalloc was called, but I'm not that good with c)
Bonus: Do you have a good/easy tutorial on RCU in the Linux Kernel?
Thank you

Function overriding in C

I have a requirement in C similar to function overriding. I have 2 devices with different device IDs. I have a process which just calls device_create(device_id). The process doesn't know which device_create to call. It is upto driver of the device to execute device_create if the device_id matches to driver's device Id. Is there any way to do it in C?
If you use different shared objects (or dlls) to implement the function you could handle this programatically on your own. You could create a plugin like structure and use something like the Command pattern.
Not exactly simple, but can help with your problem.
Cheers.
OK. Understand I'm still of the mark, but leave this post for now.
You do not know the ID when process starts. When HW is attached you read the ID and want to call correct function based on the ID but without using the ID directly?
The closest I can think of as a simple solution is by using an array of function pointers:
void (*funs[3])(void) = {
&device_create100,
&device_create200,
NULL
};
But then only if you can normalize the ID to match index of the array. Say all ID's are in the range 1000-1032 that would be an 32 long function pointer array where you can use ID - 1000.
As this is rather unlikely you could resort to a sorted list, binary tree, hash table or the like on which you do a lookup.
struct node {
int (*fun)(void);
int id;
struct *node left;
struct *node right;
}
This is of course then assuming you have a rather big list of possible ID's and a switch is out of the question.
Old post.
What about function pointers:
int (*device_create)(int);
int device_create_init(int id)
{
switch (id) {
case 0x0a:
device_create = &device_create_100;
break;
case 0x0b:
device_create = &device_create_200;
break;
}
/* After first call, the now set device_create_xxx function will be
invoked on device_create() */
return device_create(id);
}
int main(void)
{
device_create = &device_create_init;
/* Loop */
return 0;
}

keyboard interrupt handler giving null value

I am learning Linux Kernel Module programming(Interrupt Handler) and using the tutorial (http://tldp.org/LDP/lkmpg/2.6/html/) exact module link(http://tldp.org/LDP/lkmpg/2.6/html/x1256.html).
In the tutorial I am getting error when I used
INIT_WORK(&task, got_char, &scancode);
The error was "error: macro "INIT_WORK" passed 3 arguments, but takes just 2"
So I found one solution and use the below line
INIT_WORK(&task, got_char);
It's working fine but the output I am getting is null. I am expecting the key number from the keyboard.
Any body have any idea ?
If it is not clear please let me know I will try to interpret more.
Thanks
Add a structure like follows,
struct getchar_info {
/* Other info ... */
struct work_struct work;
unsigned int scancode;
/* Other info ... */
};
static struct getchar_info gci; /* Statically declare or use kmalloc() */
Change got_char() to,
static void got_char(struct work_struct *work)
{
struct getchar_info *info = container_of(work, struct getchar_info, work);
info->scancode = my_val;
/* ... */
Initialize it like INIT_WORK(&gci.work, got_char);
This is a common Linux kernel paradigm or design pattern. The work queue code needs to manage this structure pointer so it is easy to provide to your got_char routine. Your driver must allocate it as part of a larger structure (it is inheritence in OO terms; it looks like composition as 'C' only supports that). The container_of is like a C++ dynamic_cast<> (with single inheritance in case any C++ gurus are looking). It lets you get the composed structure from the sub-structure.

Resources