Author Topic: C, inter modules dependencies  (Read 29519 times)

0 Members and 1 Guest are viewing this topic.

Offline Kjelt

  • Super Contributor
  • ***
  • Posts: 6459
  • Country: nl
Re: C, inter modules dependencies
« Reply #75 on: September 14, 2015, 09:06:36 pm »
There are ofcourse a lot of third party bounds checkers and static code analyzers.
The problem becomes personal taste. Some prefer extreme strict checks others not.
 For instance Lint can find very good things but more often is nitpicking and whining about proper C.
 :-//
 

Offline C

  • Super Contributor
  • ***
  • Posts: 1346
  • Country: us
Re: C, inter modules dependencies
« Reply #76 on: September 14, 2015, 09:41:34 pm »
I have seen a few Pascal implementation trying to "embed" the string length within the string, and the trick is very easy: it uses the first cell to store the length! Oh well, this implies a maximal length limited to 255 chars. It seems a good idea.

This is real common

Each option or change creates new problems and cures for problems.
By having a length you remove the need to read the string to find it length and as you are not using a CHR(0) to mark the end you can have that character in the string.
A lot of the first pascals reserved space for each string to be 255 char long.
So you had two varables
Max_string_length
Current_string_length
Some let you define a shorter string length.
Some would use a pool of memory and  recreate the string with a new max_length when needed.
FreePascal adds a string type with a 16bit length, and adds a wide string type so you can have 16 bit wide unicode characters. Adds a C type of string where chr(0) marks the end.
All needed at times and all can be a source for errors.

C


 

Offline legacyTopic starter

  • Super Contributor
  • ***
  • !
  • Posts: 4415
  • Country: ch
Re: C, inter modules dependencies
« Reply #77 on: September 14, 2015, 10:34:37 pm »
code used to check my dev_tool:

-------------------------------------------------
app.c
Code: [Select]
#include "types.h"
void_t main()
{
    reset();
}

lib_A.c
Code: [Select]
#include "lib_A.h"

private char_t module[] = "lib_A";

#include "lib_A.private"

void_t foo_A0()
{
}

void_t foo_A1()
{
    foo_B1();
}

void_t foo_A2()
{
    foo_C1();
}

void_t foo_A3()
{
}

lib_B.c
Code: [Select]
#include "lib_B.h"

private char_t module[] = "lib_B";

#include "lib_B.private"

void_t foo_B0()
{
}

void_t foo_B1()
{
}

void_t foo_B2()
{
}

void_t foo_B3()
{
}

void_t foo_B4()
{
}



lib_C.c
Code: [Select]
#include "lib_C.h"

private char_t module[] = "lib_C";

#include "lib_C.private"

void_t foo_C0()
{
}

void_t foo_C1()
{
}

void_t foo_C2()
{
}

void_t foo_C3()
{
}

void_t foo_C4()
{
}

reset.c
Code: [Select]
void halt()
{
    /*
     * ...
     */
}

void soft_reset()
{
    /*
     * hAllo, buddy
     * the stack is now compromised
     * but I am the machine reset written in assembly inline
     * see you later, reboot is coming ^_^
     */

    //..assembly code
    printf("soft_reset\n");
}

void reset()
{
    void *jump[] = { halt, soft_reset };

    /*
     * wtf is it ? assembly branch?
     *   looking at the asm level
     *   it is translated into bra foo2
     *   which is an uncodnditional branch
     *   it's not a function call
     * so what about the stack?
     * no doubt it gets compromised
     * does it make sense? so why they allow this crap?
     * oh, just to invoke the soft_reset
     * so it really makes sense
     */
    goto *jump[1];
}
-------------------------------------------------

output:

Code: [Select]
registering ...
module0: [app]
module1: [reset]
module2: [lib_A]
module3: [lib_C]
module4: [lib_B]

methods
   0: [main] .k=1 i=0
   1: [halt] .k=1 i=1
   2: [soft_reset] .k=1 i=1
   3: [reset] .k=1 i=1
   4: [foo_A0] .k=1 i=2
   5: [foo_A1] .k=1 i=2
   6: [foo_A2] .k=1 i=2
   7: [foo_A3] .k=1 i=2
   8: [foo_C0] .k=1 i=3
   9: [foo_C1] .k=1 i=3
  10: [foo_C2] .k=1 i=3
  11: [foo_C3] .k=1 i=3
  12: [foo_C4] .k=1 i=3
  13: [foo_B0] .k=1 i=4
  14: [foo_B1] .k=1 i=4
  15: [foo_B2] .k=1 i=4
  16: [foo_B3] .k=1 i=4
  17: [foo_B4] .k=1 i=4

dependencies:
module0, needs module1
module2, needs module3
module2, needs module4

first results achieved by my dev_tool, perhaps the first mile stone, because it seems working, but it's a draft version and of course it needs a lot of improvement and more tests.

steps
  • create a list of all the C modules (*.c), and add them to a list (module_list)
  • extract all the public functions, and add them to a list (method_list)
  • for each item in the module_list, parse it, and see if there is a function which is owned by a module in the module_list, if so, mark a dependency

it seems decent enough, and to parse each module I am using a list_library and a tokenizer library which I have developed time ago, happy to see that it's useful code.

Code: [Select]
    ...
    p_file = file_open(filename, file_is_text_ro);

    if (p_file isNotEqualTo NULL)
    {
        is_done = False;
        while (is_done isEqualTo False)
        {
            ans = linea_get_from_file(p_file, p_linea);
            if (ans isEqualTo True)
            {
                if (p_linea->len > 0)
                {
                    tokener_init_linea(p_tokener, linea_body);

                    i = 0;
                    while (ans isEqualTo True)
                    {
                        p_token = get_address(token[i]);
                        tokener_init_item(p_tokener, p_token);
                        ans = token_get(p_tokener);

                        switch (p_token->type)
                        {
                        case token_StrictAlphaNum:
                        case token_AlphaNum:
                            /*
                             * functions and variables are token_StrictAlphaNum
                             * keywords_training still needs to learn them: feature disabled!
                             */

    ...

I think the next feature, that I will try to add is: look for a dead code (are there functions never called?). it's an other task often assigned to me in my job, and it's extremely boring to have to check for the dead code  :palm: :palm: :palm:
« Last Edit: September 15, 2015, 01:36:32 pm by legacy »
 

Offline helius

  • Super Contributor
  • ***
  • Posts: 3632
  • Country: us
Re: C, inter modules dependencies
« Reply #78 on: September 14, 2015, 11:04:06 pm »
computed goto to a function pointer is not legal even in non-portable GCC extensions.
 

Online Mechatrommer

  • Super Contributor
  • ***
  • Posts: 11541
  • Country: my
  • reassessing directives...
Re: C, inter modules dependencies
« Reply #79 on: September 14, 2015, 11:08:24 pm »
Why isn't optional automated bounds checking part of C for instance?
because a good programmer can easily make that in code, library, or a more advanced memory management class. do you remember that? the once famous technique, company own brew memory manager in Win311 era? 100 companies and you have 100 memory manager classes in a system? today, most noobs code monkeys expect the system should manage their app memory, with high level of security.... and dont hesitate to care whats going on in the middle, in the runtime environment engine.
Nature: Evolution and the Illusion of Randomness (Stephen L. Talbott): Its now indisputable that... organisms “expertise” contextualizes its genome, and its nonsense to say that these powers are under the control of the genome being contextualized - Barbara McClintock
 

Offline legacyTopic starter

  • Super Contributor
  • ***
  • !
  • Posts: 4415
  • Country: ch
Re: C, inter modules dependencies
« Reply #80 on: September 14, 2015, 11:26:33 pm »
computed goto to a function pointer is not legal even in non-portable GCC extensions.

sure, strong emotions if you dare to compile and execute the code above, including a pretty "segmentation fault" served as dessert :D
 

Online Marco

  • Super Contributor
  • ***
  • Posts: 6694
  • Country: nl
Re: C, inter modules dependencies
« Reply #81 on: September 14, 2015, 11:54:13 pm »
because a good programmer can easily make that in code

But considering you are too competent to actually need it it's still too much work right? ;)

That's why we had/have the original string functions, it's all those other coders who just can't seem to get it right.
« Last Edit: September 15, 2015, 12:02:55 am by Marco »
 

Offline C

  • Super Contributor
  • ***
  • Posts: 1346
  • Country: us
Re: C, inter modules dependencies
« Reply #82 on: September 15, 2015, 08:43:29 pm »

Would some report from GCC help you get the information you need?
or
something like this
 GCC-XML, the XML output extension to GCC!
http://gccxml.github.io/HTML/Index.html

C
 

Offline legacyTopic starter

  • Super Contributor
  • ***
  • !
  • Posts: 4415
  • Country: ch
Re: C, inter modules dependencies
« Reply #83 on: September 16, 2015, 08:47:03 pm »
@C
yes, gccxml can help a lot!
Thank you for your link  :-+
 

Offline C

  • Super Contributor
  • ***
  • Posts: 1346
  • Country: us
Re: C, inter modules dependencies
« Reply #84 on: September 16, 2015, 10:47:14 pm »
Found GCC-XML with a quick idea, no idea how good it is.
Note that site now says
Quote
Note: GCC-XML has been succeeded by CastXML.

If you find it missing something you need you might think of trying to find a complete praiser to get what you need.
 
C

 

Offline legacyTopic starter

  • Super Contributor
  • ***
  • !
  • Posts: 4415
  • Country: ch
Re: C, inter modules dependencies
« Reply #85 on: September 16, 2015, 10:54:16 pm »
Or to code what I need by myself, but I find other tools interesting because I usually learn from them  :-+
 

Offline tggzzz

  • Super Contributor
  • ***
  • Posts: 19284
  • Country: gb
  • Numbers, not adjectives
    • Having fun doing more, with less
Re: C, inter modules dependencies
« Reply #86 on: September 17, 2015, 07:05:19 am »
Would some report from GCC help you get the information you need?
or
something like this
 GCC-XML, the XML output extension to GCC!
http://gccxml.github.io/HTML/Index.html

Apparently, it is not uncommon for different compiler and library writers to interpret the C/C++ standards is subtly different ways. So this might not reflect the implementation of other compilers.

Source: those that have been bitten repeatedly.
There are lies, damned lies, statistics - and ADC/DAC specs.
Glider pilot's aphorism: "there is no substitute for span". Retort: "There is a substitute: skill+imagination. But you can buy span".
Having fun doing more, with less
 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4196
  • Country: us
Re: C, inter modules dependencies
« Reply #87 on: September 17, 2015, 05:14:48 pm »
Quote
it is not uncommon for different compiler and library writers to interpret the C/C++ standards is subtly different ways
I was going to say that that would be unlikely to affect dependencies (this used to be about dependencies, right?), but then I remember that we ran into EXACTLY that sort of thing.
We had this idea of "components", which were independently compiled things not-quite-like libraries.  And there would be code off in #includes like
#define COMPONENT_SOURCE ../../../components/
#define COMPONENT_VERSION 1

so that you could write your include like:

#include COMPONENT(ip, tcp)

And the compiler would go off and use a combination of concatenation and stringification to produce
#include "../../../components/ip/v1/tcp.h"
and it would include the file and everything would be swell.   In gcc 2.95 or so.

Pre-processor behavior is one of those things that is not really completely defined in the C standards (AFAIK.)  (Or perhaps it wasn't, and became so.)   In any case, sometime before gcc 4.5, the processing order of stringification/concatenation vs #include CHANGED in ways incompatible with the "component" macros, and it all stopped working :-(
 

Offline C

  • Super Contributor
  • ***
  • Posts: 1346
  • Country: us
Re: C, inter modules dependencies
« Reply #88 on: September 17, 2015, 06:46:40 pm »
Remember the C Pre-processor  is text-in to text-out.

Some output is new text
Some output is a text replace

A text replace can easily cause problems. If the c compiler does not catch an error from the text replace, you could have just created a unchecked logic error.
How many people read the output of the C Pre-processor to see if it's really valid?
How many people assume it's all valid changes?

C
 

Offline helius

  • Super Contributor
  • ***
  • Posts: 3632
  • Country: us
Re: C, inter modules dependencies
« Reply #89 on: September 18, 2015, 03:39:35 am »
Quote
Remember the C Pre-processor  is text-in to text-out.
Technically, it's tokens-in to tokens-out. Fragments of tokens like unterminated strings are not valid data to the preprocessor.
 

Offline richardman

  • Frequent Contributor
  • **
  • Posts: 427
  • Country: us
Re: C, inter modules dependencies
« Reply #90 on: October 05, 2015, 10:34:40 am »
... but then I remember that we ran into EXACTLY that sort of thing.
We had this idea of "components", which were independently compiled things not-quite-like libraries.  And there would be code off in #includes like
#define COMPONENT_SOURCE ../../../components/
#define COMPONENT_VERSION 1

so that you could write your include like:

#include COMPONENT(ip, tcp)

And the compiler would go off and use a combination of concatenation and stringification to produce
#include "../../../components/ip/v1/tcp.h"
and it would include the file and everything would be swell.   In gcc 2.95 or so.

Pre-processor behavior is one of those things that is not really completely defined in the C standards (AFAIK.)  (Or perhaps it wasn't, and became so.)   In any case, sometime before gcc 4.5, the processing order of stringification/concatenation vs #include CHANGED in ways incompatible with the "component" macros, and it all stopped working :-(

Actually, the C preprocessor behaviors are fairly well defined in the C Standards. I don't know exactly how the COMPONENTS macro is defined and what the expectations were, but C clearly states that if the #include filename part isn't a double quote string or <> quoted, then it is macro-expanded, and the process of macro expansion will handle the stringizing and token pasting operators.
// richard http://imagecraft.com/
JumpStart C++ for Cortex (compiler/IDE/debugger): the fastest easiest way to get productive on Cortex-M.
Smart.IO: phone App for embedded systems with no app or wireless coding
 

Offline legacyTopic starter

  • Super Contributor
  • ***
  • !
  • Posts: 4415
  • Country: ch
Re: C, inter modules dependencies
« Reply #91 on: October 05, 2015, 01:51:36 pm »
Code: [Select]
=======> opening file=[cavia/reset.h], module=[reset]
:: >0,[#ifndef]
:: >0,[_reset_]
:: >0,[#define]
:: >0,[_reset_]
:: >0,[#include]
:: >0,[types.h]
:: >0,[typedef]
:: >1,[union]
:: >2,[{]
brace_balance=1
:: >3,[struct]
:: >3,[{]
brace_balance=2
:: >1,[uint32_t]
:: >4,[xxeta]
:: >5,[;]
:: >3,[struct]
:: >3,[{]
brace_balance=3
:: >1,[sint32_t]
:: >4,[oota]
:: >5,[;]
:: >3,[}]
brace_balance=2
:: >4,[zzeta]
:: >5,[;]
:: >3,[}]
brace_balance=1
:: >4,[f_a1]
:: >5,[;]
:: >3,[struct]
:: >3,[{]
brace_balance=2
:: >1,[uint32_t]
:: >4,[yyellow]
:: >5,[;]
:: >3,[}]
brace_balance=1
:: >4,[f_b1]
:: >5,[;]
:: >3,[}]
brace_balance=0
:: >4,[my_reset_t]
########## new type ###########[my_reset_t]
:: >5,[;]
:: >0,[typedef]
:: >1,[my_reset_t]
needs my_reset_t
:: >4,[*]
:: >4,[p_my_reset_t]
########## new type ###########[p_my_reset_t]
:: >5,[;]
:: >0,[typedef]
:: >1,[device_handler_ans_t]
needs device_handler_ans_t
:: >4,[(]
:: >4,[*]
:: >4,[device_handler_DO_init_t]
########## new type ###########[device_handler_DO_init_t]
:: >5,[)]
:: >5,[(]
:: >5,[p_this_t]
:: >5,[p_this_A]
:: >5,[)]
:: >5,[;]
:: >0,[typedef]
:: >1,[device_handler_ans_t]
needs device_handler_ans_t
:: >4,[(]
:: >4,[*]
:: >4,[device_handler_DO_done_t]
########## new type ###########[device_handler_DO_done_t]
:: >5,[)]
:: >5,[(]
:: >5,[p_this_t]
:: >5,[p_this]
:: >5,[)]
:: >5,[;]
:: >0,[typedef]
:: >1,[device_handler_ans_t]
needs device_handler_ans_t
:: >4,[(]
:: >4,[*]
:: >4,[device_handler_DO_open_t]
########## new type ###########[device_handler_DO_open_t]
:: >5,[)]
:: >5,[(]
:: >5,[p_this_t]
:: >5,[p_this]
:: >5,[)]
:: >5,[;]
:: >0,[typedef]
:: >1,[device_handler_ans_t]
needs device_handler_ans_t
:: >4,[(]
:: >4,[*]
:: >4,[device_handler_DO_close_t]
########## new type ###########[device_handler_DO_close_t]
:: >5,[)]
:: >5,[(]
:: >5,[p_this_t]
:: >5,[p_this]
:: >5,[)]
:: >5,[;]
:: >0,[typedef]
:: >1,[device_handler_ans_t]
needs device_handler_ans_t
:: >4,[(]
:: >4,[*]
:: >4,[device_handler_DO_reset_t]
########## new type ###########[device_handler_DO_reset_t]
:: >5,[)]
:: >5,[(]
:: >5,[p_this_t]
:: >5,[p_this]
:: >5,[)]
:: >5,[;]
:: >0,[#include]
:: >0,[reset.interface]
:: >0,[#endif]
debug console, verbose mode

Code: [Select]
cat guineapig/reset.h
#ifndef _reset_
#define _reset_

#include "types.h"

typedef union
{
struct
    {
    uint32_t xxeta;
    struct
    {
sint32_t oota;
} zzeta;
} f_a1;
struct
    {
    uint32_t yyellow;
} f_b1;
} my_reset_t;

typedef my_reset_t* p_my_reset_t;

typedef device_handler_ans_t (*device_handler_DO_init_t)(p_this_t p_this_A);
typedef device_handler_ans_t (*device_handler_DO_done_t)(p_this_t p_this);
typedef device_handler_ans_t (*device_handler_DO_open_t)(p_this_t p_this);
typedef device_handler_ans_t (*device_handler_DO_close_t)(p_this_t p_this);
typedef device_handler_ans_t (*device_handler_DO_reset_t)(p_this_t p_this);


#include "reset.interface"

#endif
guinea-pig code, used as source to test the algorithm 

Code: [Select]
########## new type ###########[my_reset_t]
########## new type ###########[p_my_reset_t]
########## new type ###########[device_handler_DO_init_t]
########## new type ###########[device_handler_DO_done_t]
########## new type ###########[device_handler_DO_open_t]
########## new type ###########[device_handler_DO_close_t]
########## new type ###########[device_handler_DO_reset_t]
debug console, verbose mode, focusing on results (types identified)

little free time, but more progress: it's now able to correctly identify "types" (what comes defined by "typedef") in order to fill a giant sparse matrix of dependencies, so the tool has the complete vision of the inter-module dependencies, both interface dependencies (C prototypes) and types (typedef).

I just need to care about global public variables (extern), and constants (#define ...), but that at the current state of art, that tool is almost already working  :-+
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf