]> rtime.felk.cvut.cz Git - frescor/forb.git/commitdiff
Remote requests works, but there are some issues
authorMichal Sojka <sojkam1@fel.cvut.cz>
Sat, 27 Sep 2008 22:43:31 +0000 (00:43 +0200)
committerMichal Sojka <sojkam1@fel.cvut.cz>
Sat, 27 Sep 2008 22:43:31 +0000 (00:43 +0200)
One issue is: It is possible, that the request arrives before the server\
discovers the client, so the reply cannot be sent.

15 files changed:
Makefile.omk
cdr.c
forb-idl/forb-idl-c-stubs.c
forb.c
forb.h
iop.c
iop.h
proto.c
proto.h
request.c
request.h
request_gavl.c [new file with mode: 0644]
tests/Makefile.omk
tests/hello_remote.c [new file with mode: 0644]
ul_log_domains [new file with mode: 0755]

index 28ed8a135ab76b625515db7a2922b3a679da4b5c..fdce5dc155822888e57e810eee3d242dbd57e66b 100644 (file)
@@ -1,6 +1,8 @@
 SUBDIRS = tests-idl tests
 EXTRA_RULES_SUBDIRS = forb-idl
 
+CFLAGS += -I.
+
 IDL_COMPILER += --pidl
 
 lib_LIBRARIES += forb
@@ -37,3 +39,18 @@ default_CONFIG = CONFIG_FORB_PROTO_UNIX=y \
 config_include_HEADERS = forb/config.h
 config_DEFINES = CONFIG_FORB_PROTO_UNIX \
                 CONFIG_FORB_RECV_BUF_SIZE
+
+include-pass_HOOKS = log_domains.inc request_gavl.inc
+
+log_domains.inc:
+       @echo "  UL_LOG  $@"
+       $(Q)$(SOURCES_DIR)/ul_log_domains $(SOURCES_DIR) > $@
+
+clean-custom:
+       $(Q)rm log_domains.inc
+
+request_gavl.inc: $(SOURCES_DIR)/request_gavl.c
+       @echo "  CPP     $@"
+       $(Q)$(c_o_COMPILE) -o $@.tmp -E $<
+       $(Q)tail -n 1 $@.tmp|indent > $@
+
diff --git a/cdr.c b/cdr.c
index 126638026dbeef8a2855ebd8ea999b3bd6a666a3..29a5aed9eed44f5373d6fab2f8a712071a29e0ca 100644 (file)
--- a/cdr.c
+++ b/cdr.c
@@ -455,7 +455,9 @@ CDR_codec_init(void)
        CDR_Codec *c;
 
        c=forb_malloc(sizeof(CDR_Codec));
-       CDR_codec_init_static(c);
+       if (c) {
+               CDR_codec_init_static(c);
+       }
 
        return(c);
 }
index 0742cd9836d0bb1a4074201b40e2c1302f28250a..b18f8aa6396c4985fc22fcc26d82b3e5b578c0e7 100644 (file)
@@ -65,12 +65,9 @@ cs_output_stub (IDL_tree     tree,
        
        fprintf(of, "  } else {\n");
        fprintf(of, "    /* remote object */\n"
-                   "    CDR_Codec codec;\n"
-                   "    forb_request_t req;\n"
-                   "    CDR_codec_init_static(&codec);\n"
-                   "    ex_on_fail(CDR_buffer_init(&codec, 256, forb_iop_MESSAGE_HEADER_SIZE), FORB_EX_NO_MEMORY);\n");
-       fprintf(of, "    ex_on_fail(forb_request_init(&req, _obj->orb) == 0, FORB_EX_INTERNAL);\n");
-       fprintf(of, "    forb_iop_prepare_request(&req, &codec, \"%s\", _obj, FORB_METHOD_INDEX(%s), ev);\n",
+                   "    forb_request_t req;\n");
+       fprintf(of, "    ex_on_fail(forb_request_init(&req, _obj) == 0, FORB_EX_INTERNAL);\n");
+       fprintf(of, "    forb_iop_prepare_request(&req, \"%s\", FORB_METHOD_INDEX(%s), ev);\n",
                iface_id, opname);
        fprintf(of, "    if (forb_exception_occured(ev)) goto exception;\n");
        for (sub = IDL_OP_DCL (tree).parameter_dcls; sub; sub = IDL_LIST (sub).next) {
@@ -81,7 +78,7 @@ cs_output_stub (IDL_tree     tree,
                  char *name = IDL_IDENT(IDL_PARAM_DCL(parm).simple_declarator).str;
                  fprintf(of, "    ex_on_fail(");
                  forb_cbe_write_typespec(of, IDL_PARAM_DCL(parm).param_type_spec);
-                 fprintf(of, "_serialize(&codec, %s%s), FORB_EX_IMP_LIMIT);\n",
+                 fprintf(of, "_serialize(&req.cdr_request, %s%s), FORB_EX_IMP_LIMIT);\n",
                          role == DATA_IN ? "&":"",
                          name);
                }
@@ -106,10 +103,9 @@ cs_output_stub (IDL_tree     tree,
                  fprintf(of, "_deserialize(req.cdr_reply, %s);\n", name);
                }
        }
-       fprintf(of, "exception:\n"
-                   "    forb_request_signal_processed(&req);\n"
-                   "    forb_request_destroy(&req);\n"
-                   "    CDR_codec_release_buffer(&codec);\n");
+       fprintf(of, "    forb_request_signal_processed(&req);\n"
+                   "exception:\n"
+                   "    forb_request_destroy(&req);\n");
        fprintf(of, "  }\n");
        if (has_retval) {
                fprintf(of, "  return " FORB_RETVAL_VAR_NAME ";\n");
diff --git a/forb.c b/forb.c
index f96ee31e42132f5be244850a1edece4383423f56..89ff20a763596b22cea266048bd50e80d1e9cb7e 100644 (file)
--- a/forb.c
+++ b/forb.c
@@ -1,3 +1,5 @@
+#define _BSD_SOURCE            /* Because of on_exit()  */
+#include <stdlib.h>
 #include <forb/forb-internal.h>
 #include <forb/forb.h>
 #include <string.h>
@@ -6,23 +8,37 @@
 #include <forb/iop.h>
 #include <forb/config.h>
 #include <forb/proto.h>
+#include <ul_logreg.h>
 #ifdef CONFIG_FORB_PROTO_UNIX
 #include <forb/proto_unix.h>
 #endif
 #include <stdio.h>
 
+#define UL_LOGL_DEF UL_LOGL_ERR
+#include "log_domains.inc"
+
+static void
+destroy_forb_on_exit(int exitcode, void *arg)
+{
+       forb_orb orb = arg;
+       forb_destroy(orb);
+}
+
 forb_orb forb_init(void)
 {
        forb_orb object;
        forb_t *forb;
 
-       object = forb_malloc(sizeof(*object));       
+       object = forb_object_new(NULL, NULL, 0); /* TODO: Initialize this after forb_t, so that we can fill server_id */
        if (!object) goto err;
-       memset(object, 0, sizeof(*object));
        
        forb = forb_malloc(sizeof(*forb));
        if (!forb) goto err1;
        memset(forb, 0, sizeof(*forb));
+
+       /* Initialize ULUT logging facility */
+       ul_logreg_domains_static(ul_log_domains_array,
+                                sizeof(ul_log_domains_array)/sizeof(ul_log_domains_array[0]));
        
        object->instance_data = forb;
        forb_server_id_init(&forb->server_id);
@@ -46,7 +62,7 @@ forb_orb forb_init(void)
                }
        }
 #endif
-       /* TODO: atexit(destroy_all_forbs); */
+       on_exit(destroy_forb_on_exit, object);
        return object;
 
 err2:  forb_free(forb);
@@ -93,6 +109,7 @@ forb_object_new(forb_orb orb,
 {
        forb_object obj = forb_malloc(sizeof(*obj));
        if (obj) {
+               memset(obj, 0, sizeof(*obj));
                obj->orb = orb;
                if (key == 0) {
                        obj->objkey = (forb_object_key)(unsigned)obj;
@@ -102,7 +119,9 @@ forb_object_new(forb_orb orb,
                if (server_id) {
                        obj->server = *server_id;
                } else {
-                       obj->server = forb_obj_to_forb(obj)->server_id;
+                       if (orb) {
+                               obj->server = forb_obj_to_forb(obj)->server_id;
+                       }
                }
        }
        return obj;
diff --git a/forb.h b/forb.h
index 34cff71fc3c82a798cc2f9b05df29c1d8fbaf26a..c255ccddde4d189c453d624b693def62b6d3fc94 100644 (file)
--- a/forb.h
+++ b/forb.h
  * exceptions.
  */
 enum forb_exception {
-       FORB_EX_NONE,
-       FORB_EX_UNKNOWN,
-       FORB_EX_BAD_PARAM,
-       FORB_EX_NO_MEMORY,
-       FORB_EX_IMP_LIMIT,
-       FORB_EX_COMM_FAILURE,
-       FORB_EX_INV_OBJREF,
-       FORB_EX_NO_PERMISSION,
-       FORB_EX_INTERNAL,
-       FORB_EX_MARSHAL,
-       FORB_EX_INITIALIZE,
-       FORB_EX_NO_IMPLEMENT,
-       FORB_EX_BAD_OPERATION,
-       FORB_EX_NO_RESOURCES,
-       FORB_EX_NO_RESPONSE,
-       FORB_EX_TRANSIENT,
-       FORB_EX_FREE_MEM,
-       FORB_EX_INV_IDENT,
-       FORB_EX_INV_FLAG,
-       FORB_EX_DATA_CONVERSION,
-       FORB_EX_OBJECT_NOT_EXIST,
-       FORB_EX_TIMEOUT,
+       FORB_EX_NONE,           /* 0 */
+       FORB_EX_UNKNOWN,        /* 1 */
+       FORB_EX_BAD_PARAM,      /* 2 */
+       FORB_EX_NO_MEMORY,      /* 3 */
+       FORB_EX_IMP_LIMIT,      /* 4 */
+       FORB_EX_COMM_FAILURE,   /* 5 */
+       FORB_EX_INV_OBJREF,     /* 6 */
+       FORB_EX_NO_PERMISSION,  /* 7 */
+       FORB_EX_INTERNAL,       /* 8 */
+       FORB_EX_MARSHAL,        /* 9 */
+       FORB_EX_INITIALIZE,     /* 10 */
+       FORB_EX_NO_IMPLEMENT,   /* 11 */
+       FORB_EX_BAD_OPERATION,  /* 12 */
+       FORB_EX_NO_RESOURCES,   /* 13 */
+       FORB_EX_NO_RESPONSE,    /* 14 */
+       FORB_EX_TRANSIENT,      /* 15 */
+       FORB_EX_FREE_MEM,       /* 16 */
+       FORB_EX_INV_IDENT,      /* 17 */
+       FORB_EX_INV_FLAG,       /* 18 */
+       FORB_EX_DATA_CONVERSION,  /* 19 */
+       FORB_EX_OBJECT_NOT_EXIST, /* 20 */
+       FORB_EX_TIMEOUT,          /* 21 */
 };
 
 struct forb_env {
diff --git a/iop.c b/iop.c
index 3c71f53f2cad89607592070d43abb2431d08868a..ef0ca9fb24d87d139cb1b8277d200264ff208282 100644 (file)
--- a/iop.c
+++ b/iop.c
@@ -35,9 +35,7 @@ forb_iop_prepend_message_header(CDR_Codec *codec, forb_iop_message_type mt)
 
 CORBA_boolean
 forb_iop_prepare_request(forb_request_t *req,
-                        CDR_Codec *codec,
                         char *iface,
-                        forb_object obj,
                         unsigned method_ind,
                         CORBA_Environment *env)
 {
@@ -46,9 +44,10 @@ forb_iop_prepare_request(forb_request_t *req,
 
        rh.request_id = req->request_id;
        rh.iface = iface;
-       rh.objkey = forb_object_to_key(obj);
+       rh.objkey = forb_object_to_key(req->obj);
        rh.method_index = method_ind;
-       ret = forb_iop_request_header_serialize(codec, &rh);
+       rh.source = forb_obj_to_forb(req->obj)->server_id;
+       ret = forb_iop_request_header_serialize(&req->cdr_request, &rh);
        return ret;
 }
 
diff --git a/iop.h b/iop.h
index 4de33925697b848f0f2a9cc9019bbcdc9557c447..9bf416e0c1d5c1120de65f96d6b2bbe01367d034 100644 (file)
--- a/iop.h
+++ b/iop.h
@@ -11,9 +11,7 @@ forb_iop_prepend_message_header(CDR_Codec *codec, forb_iop_message_type mt);
 
 CORBA_boolean
 forb_iop_prepare_request(forb_request_t *req,
-                        CDR_Codec *codec,
                         char *iface,
-                        forb_object obj,
                         unsigned method_ind,
                         CORBA_Environment *env);
 
diff --git a/proto.c b/proto.c
index 916a5a9cd6666d114f41b3fb3d1503f6b3efa8f9..59acae647790d690f2dd41a05511f6958194abe1 100644 (file)
--- a/proto.c
+++ b/proto.c
@@ -5,7 +5,7 @@
 #include <stdio.h>
 #include <ul_log.h>
 
-UL_LOG_CUST(ulogd_proto);
+extern UL_LOG_CUST(ulogd_proto);
 
 GAVL_CUST_NODE_INT_IMP(forb_peer_nolock,/* cust_prefix */
                       forb_t,          /* cust_root_t */
@@ -25,7 +25,7 @@ forb_exception_serialize(CDR_Codec *codec, struct forb_env *env)
 static inline CORBA_boolean
 forb_exception_deserialize(CDR_Codec *codec, struct forb_env *env)
 {
-       /* FIXME: Declare exceptions in IDL and don't typecast here. */
+       /* TODO: Declare exceptions in IDL and don't typecast here. */
        return CORBA_long_deserialize(codec, (CORBA_long*)&env->major);
 }
 
@@ -60,6 +60,7 @@ send_reply(forb_t *forb,
 
        peer = forb_get_next_hop(forb, dest);
        if (!peer) {
+               ul_logerr("Reply destination not found\n");
                goto err;
        }
        forb_proto_send(peer, codec);
@@ -84,7 +85,7 @@ process_request(forb_port_t *port, CDR_Codec *codec)
                              forb_iop_REPLY_HEADER_SIZE);
        if (!ret) {
                /* Without codec, we cannot send any reply so return silently. */
-               ul_logerr("No memory for reply buffer");
+               ul_logerr("No memory for reply buffer\n");
                return;
        }
        
@@ -108,7 +109,7 @@ process_request(forb_port_t *port, CDR_Codec *codec)
                goto out;
        }
        env.major = FORB_EX_NONE;
-       /* TODO: Introduce forb_request_processor and acompanying
+       /* TODO: Introduce forb_executor_t and acompanying
         * stuff to execute skeletons and implementation in a separate thread. */
        obj->interface->skeletons[request_header.method_index](codec, &reply_codec, obj, &env);
 out:
@@ -126,7 +127,7 @@ process_reply(forb_port_t *port, CDR_Codec *codec)
        forb_iop_reply_header_deserialize(codec, &rh);
        req = forb_request_find(forb, &rh.request_id);
        if (!req) {
-               ul_logerr("Received reply to unknown request_id %ud\n", rh.request_id);
+               ul_logerr("Received reply to unknown request_id %u\n", rh.request_id);
                return;
        }
        if (rh.flags & forb_iop_FLAG_EXCEPTION) {
@@ -452,7 +453,7 @@ forb_proto_send_request(forb_request_t *req, CORBA_Environment *env)
 
        req->env = env;     /* Remember, where to return exceptions */
 
-       ret = forb_iop_prepend_message_header(req->cdr_request, forb_iop_REQUEST);
+       ret = forb_iop_prepend_message_header(&req->cdr_request, forb_iop_REQUEST);
        if (!ret) {
                /* This should never happen */
                env->major = FORB_EX_INTERNAL;
@@ -460,13 +461,21 @@ forb_proto_send_request(forb_request_t *req, CORBA_Environment *env)
        }
        peer = forb_get_next_hop(forb, &req->obj->server);
        if (!peer) {
+               char str[50];
+               ul_logerr("Cannot find peer for server: %s",
+                         forb_server_id_to_string(str, &req->obj->server, sizeof(str)));
                env->major = FORB_EX_TRANSIENT;
                return;
        }
        
-       forb_request_insert(forb, req);
+       ret = forb_request_insert(forb, req);
+       if (ret <= 0) {
+               ul_logerr("Insert request error %d\n", ret);
+               env->major = FORB_EX_INTERNAL;
+               return;
+       }
 
-       size = forb_proto_send(peer, req->cdr_request);
+       size = forb_proto_send(peer, &req->cdr_request);
        if (size <= 0) {
                forb_request_delete(forb, req);
                env->major = FORB_EX_COMM_FAILURE;
diff --git a/proto.h b/proto.h
index 197ee748b3b9b3bf9487093aaef3ab08ed0f1684..cbf1a78a61307ca19d3afbb7d04b7c10e7f5165e 100644 (file)
--- a/proto.h
+++ b/proto.h
@@ -14,6 +14,9 @@
 #include <forb/forb-internal.h>
 #include "syncobj.h"
 #include "request.h"
+#include <ul_logbase.h>
+
+extern ul_log_domain_t ulogd_proto;
 
 typedef struct forb_proto forb_proto_t;
 typedef struct forb_port forb_port_t;
index be371a2c462a4940cdfdbbdf7bfbe21e3e26d9fb..44aae4d96cb368f85fd3dd1ece0911bc4a7d882b 100644 (file)
--- a/request.c
+++ b/request.c
@@ -1,13 +1,15 @@
 #include <forb/forb-internal.h>
 #include "request.h"
+#include <forb/iop-idl.h>
 
 static inline int forb_request_cmp(CORBA_unsigned_long *a, CORBA_unsigned_long *b)
 {
-       return (a<b) ? -1 :
-               (a>b) ? +1 :
-               0;
+       return (*a<*b) ? -1 :
+               ((*a>*b) ? +1 :
+                0);
 }
 
+#if 0
 GAVL_CUST_NODE_INT_IMP(forb_request_nolock /* cust_prefix */,
                       forb_t /* cust_root_t */,
                       forb_request_t /* cust_item_t */,
@@ -16,7 +18,9 @@ GAVL_CUST_NODE_INT_IMP(forb_request_nolock /* cust_prefix */,
                       node /* cust_item_node */,
                       request_id /* cust_item_key */,
                       forb_request_cmp/* cust_cmp_fnc */);
-
+#else
+#include "request_gavl.inc"
+#endif 
 
 /** 
  * Initializes @a req structure for sending new request to object @a obj.
@@ -30,13 +34,22 @@ int
 forb_request_init(forb_request_t *req, forb_object obj)
 {
        int ret = 0;
-       
        forb_t *forb = forb_obj_to_forb(obj);
+       CORBA_boolean bret;
+
+       memset(req, 0, sizeof(*req));
        req->obj = obj;
+
        fosa_mutex_lock(&forb->id_mutex);
-       req->request_id = forb_data(obj->orb)->request_id++;
+       req->request_id = forb->request_id++;
        fosa_mutex_unlock(&forb->id_mutex);
 
+       CDR_codec_init_static(&req->cdr_request);
+       bret = CDR_buffer_init(&req->cdr_request, 256, forb_iop_MESSAGE_HEADER_SIZE);
+       if (bret == CORBA_FALSE) {
+               return FOSA_ENOMEM;
+       }
+       
        ret = forb_syncobj_init(&req->reply_ready, 0);
        return ret;
 }
@@ -44,6 +57,7 @@ forb_request_init(forb_request_t *req, forb_object obj)
 void
 forb_request_destroy(forb_request_t *req)
 {
+       CDR_codec_release_buffer(&req->cdr_request);
        forb_syncobj_destroy(&req->reply_ready);
 }
 
index a49a89a0a52506e20eccdb4c87ecdae40018b8c3..a860c9a4dbe0c0f2425c5053a8336d05f5d84d86 100644 (file)
--- a/request.h
+++ b/request.h
@@ -13,7 +13,7 @@
  */
 struct forb_request {
        CORBA_unsigned_long request_id;
-       CDR_Codec *cdr_request;
+       CDR_Codec cdr_request;
        CDR_Codec *cdr_reply;
        gavl_node_t node;
        forb_object obj;
@@ -34,12 +34,14 @@ GAVL_CUST_NODE_INT_DEC(forb_request_nolock /* cust_prefix */,
                       request_id /* cust_item_key */,
                       forb_request_cmp/* cust_cmp_fnc */);
 
-static inline void
+static inline int
 forb_request_insert(forb_t *forb, forb_request_t *req)
 {
+       int ret;
        fosa_mutex_lock(&forb->request_mutex);
-       forb_request_nolock_insert(forb, req);
+       ret = forb_request_nolock_insert(forb, req);
        fosa_mutex_unlock(&forb->request_mutex);
+       return ret;
 }
 
 static inline void
diff --git a/request_gavl.c b/request_gavl.c
new file mode 100644 (file)
index 0000000..e9e4822
--- /dev/null
@@ -0,0 +1,10 @@
+#include <ul_gavlcust.h>
+
+GAVL_CUST_NODE_INT_IMP(forb_request_nolock /* cust_prefix */,
+                      forb_t /* cust_root_t */,
+                      forb_request_t /* cust_item_t */,
+                      CORBA_unsigned_long /* cust_key_t */,
+                      requests /* cust_root_node */,
+                      node /* cust_item_node */,
+                      request_id /* cust_item_key */,
+                      forb_request_cmp/* cust_cmp_fnc */);
index 6fa31d3326b96d175e374502fb48d0049cac26ed..548f98bdbc0ade4b0d8af45f92602d99cc03181a 100644 (file)
@@ -1,6 +1,6 @@
 SUBDIRS = $(ALL_OMK_SUBDIRS)
 
-test_PROGRAMS = hello_inproc proto_unix discovery 
+test_PROGRAMS = hello_inproc hello_remote proto_unix discovery 
 CFLAGS += -DTEST
 
 lib_LOADLIBES = forb ulut fosa rt
@@ -9,6 +9,10 @@ hello_inproc_SOURCES = hello_inproc.c hello_impl.c
 hello_inproc_CLIENT_IDL = hello.idl
 hello_inproc_SERVER_IDL = hello.idl
 
+hello_remote_SOURCES = hello_remote.c hello_impl.c
+hello_remote_CLIENT_IDL = hello.idl
+hello_remote_SERVER_IDL = hello.idl
+
 include_GEN_HEADERS = hello.h
 
 # test_PROGRAMS += hello_client
diff --git a/tests/hello_remote.c b/tests/hello_remote.c
new file mode 100644 (file)
index 0000000..850ad73
--- /dev/null
@@ -0,0 +1,80 @@
+/**
+ * @file   hello_remote.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date   Thu Sep 25 16:05:27 2008
+ * 
+ * @brief  Test of remote invocation.
+ *
+ * In this test, two FORBs are created, one for running the server of
+ * hello interface and the second for running the client code. Since
+ * the client and server are registered in different FORBs, remote
+ * communication is used even if the two FORBs share the same
+ * memory. This way we can easily test remote communication without
+ * writing separate applications for client and server.
+ */
+
+#include <hello.h>
+#include "hello_impl.h"
+#include <forb/forb.h>
+#include <error.h>
+#include <fosa.h>
+#include <forb/executor.h>
+
+void *server_thread(void *arg)
+{
+       hello hobj = arg;
+
+       forb_execute_object(hobj);
+       return NULL;
+}
+
+char *start_server()
+{
+       forb_orb orb;
+       hello hobj;
+
+       fosa_thread_id_t tid;
+
+       orb = forb_init();
+       hobj = hello_impl_initialize(orb);
+       fosa_thread_create(&tid, NULL, server_thread, hobj);
+
+       return forb_object_to_string(hobj);
+}
+
+
+
+void client(void *arg)
+{
+       forb_orb orb;
+       hello hobj;
+       struct forb_env env;
+       char *objref = arg;
+       
+       orb = forb_init();
+
+       sleep(1);               /* Hack to wait for dicovery of the two peers */
+
+       hobj = forb_string_to_object(orb, objref);
+       if (!hobj) {
+               error(1, 0, "Cannot create object reference from the string (%s)\n", objref);
+       }
+
+       hello_message(hobj, "Hello world!", &env);
+       if (forb_exception_occured(&env)) {
+               error(1, 0, "FORB exception %d", env.major);
+       }
+
+}
+
+int main(int argc, char *argv[])
+{
+
+       char *objref_str;
+       
+       objref_str = start_server();
+
+       client(objref_str);
+               
+       return 0;       
+}
diff --git a/ul_log_domains b/ul_log_domains
new file mode 100755 (executable)
index 0000000..f3092e9
--- /dev/null
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+DOMAINS=$(find -L $1 '(' -name '*.c' -o -name '*.cc' ')' -exec grep UL_LOG_CUST '{}' ';' | \
+  sed -n -e 's/^.*UL_LOG_CUST(\([^)]*\)).*$/\1/p' | sort -u )
+
+#echo $DOMAINS
+
+#echo -e "#define UL_LOGL_DEF UL_LOGL_DEB\n"
+
+echo "/*"
+echo " * This is generated file, do not edit it directly."
+echo " * Take it from standard output of \"ul_log_domains\""
+echo " * script called in the top level project directory"
+echo " */"
+
+for i in $DOMAINS ; do
+  echo "ul_log_domain_t $i     = {UL_LOGL_DEF, \"$(echo -n $i | sed -n -e 's/ulogd_\(.*\)/\1/pg' )\"};"
+done
+
+echo
+echo "ul_log_domain_t *ul_log_domains_array[] = {"
+
+for i in $DOMAINS ; do
+  echo "  &$i,"
+done
+
+echo "};"