This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

is this possible

It happened again.

I have many cases of modules with something like
#ifdef TYPEA
... many lines
#endif
#ifdef TYPEB
... many similar lines
#endif
#ifdef TYPEC
... many similar lines
#endif

It happens that I am looking at the type b code trying to figure out something in type a (the codes are VERY similar).

To avoid this, I have tried

blah,blah // comment TYPEA

and that "kind of works"

Now, the ideal would be if for type a I could do the following:
#ifdef TYPEA
#define ATYPE
#define BTYPE //
#define CTYPE //
#endif

and then just make it
ATYPE blah,blah // comment

Of course this does not work.
Does anyone have a trick that makes this possible?

Erik

Parents
  • "Already done where practical." One idea I have depends on why the separate files are impractical. Could you elaborate, please?

    I have modules that are, say, 80% different fron group a to groupb to groupn and those are in separate modules that the .bat make select based on which of the 47 versions is to be build.

    for modules that are, say, 20% different and have very many flavors, maintaining the common code in that many modules would be extremely impractical.

    To the greatest extent possible where the difference is, say, a function, that function have been separated out.

    The issues where the original query relate are where you have, say a function that is 93% the same, but in minor details is different.

    This all relates to a) an inherited project which was a total mess, but now with some use of macros etc i quite a bit cleaner and b) to my new design wher the 'mess' is geatly reduced, but everything can be improved on.

    Thanks for the interest

    Erik

Reply
  • "Already done where practical." One idea I have depends on why the separate files are impractical. Could you elaborate, please?

    I have modules that are, say, 80% different fron group a to groupb to groupn and those are in separate modules that the .bat make select based on which of the 47 versions is to be build.

    for modules that are, say, 20% different and have very many flavors, maintaining the common code in that many modules would be extremely impractical.

    To the greatest extent possible where the difference is, say, a function, that function have been separated out.

    The issues where the original query relate are where you have, say a function that is 93% the same, but in minor details is different.

    This all relates to a) an inherited project which was a total mess, but now with some use of macros etc i quite a bit cleaner and b) to my new design wher the 'mess' is geatly reduced, but everything can be improved on.

    Thanks for the interest

    Erik

Children
  • "The issues where the original query relate are where you have, say a function that is 93% the same, but in minor details is different."

    And you want to see the details each variant's 7% difference, just without all the preprocessor conditional directives?

  • oK, There is a communication problem here, I'll try again.

    The system works beautifully and there is no problem except one purely 'administrative':

    let me try an example:

    Say there is a module with 4 identicallly named functions with slight diffreneces each function is ~100 lines long and enclosed by #ifdef and #endif. I am checking something in another section of the program and come acroos a read of the global varibale "phred". Now I get curious as to where it get written and do a search and, since it get written in the above funtion(s) I get 4 hits:
    L11 Phred = 47;
    L111 Phred = 48;
    L211 Phred = 49;
    L311 Phred = 23;

    and I have to go hunt for the #ifdefs to see which line apply to the build I am working with

    if it was possible (I know it is not, just using it as a descriptor, to have for build b
    #define builda //
    #define buildb
    #define buildc //
    #define buildd //

    the above search would look like this
    L11 builda Phred = 47;
    L111 buildb Phred = 48;
    L211 buildc Phred = 49;
    L311 buildd Phred = 23;

    and the process would be simple.

    Erik

  • Knowing that little bit more, I'm going to suggest not altering the code and instead using a source code analysis, browsing, and reverse engineering tool that has the (configurable) ability to ignore inactive code. With this kind of tool, you have it go through the code with the same TYPEA/TYPEB/TYPEx setting that you are currently using and it will record references (var read, var modified, func calls/callby, etc.) only where that TYPEx setting is active. In fact even for unrecorded references, it can search while ignoring inactive code, or only in comments, only statements, or only strings.

    See scitools.com/.../features.php

    It is for C too, in fact that's how I use it. I don't use its editor, but instead, have added a toolbar button so that when I have found the area of interest, I click the button and it brings up the file in "my favorite editor" with the cursor position at the identical location.

    I have used this tool to try to understand the intricacies of client code >500,000 lines over hundreds of source files with approximately 80 #ifdef build/feature options, but I use it for small projects too. It just makes things so much faster. You probably owe it to yourself to use their evaluation for awhile to see what I mean.

  • thanks, Dan
    You probably owe it to yourself to use their evaluation for awhile to see what I mean.
    will do next time this hits.

    Erik

  • oK, There is a communication problem here, I'll try again.

    Indeed. And I'm afraid I have to state it's on your end of the line. I described a method that would do exactly what you ask for: exactly that file format, and it would work if you just bothered to try --- and what's the reaction? You pull a new problem out of the hat that has nothing to do with what you're asking about.

  • i agree you did, after the second post I saw how it worked and I posted "I guess the extra parentheses would be confoosing, i will write a few lines and judge"

    I am sorry, I should have stated that it was, indeed 'confusing" the extra paranthesises did obfusciate some lines, I fot distracted at the "critical time" and thus did never reply re trying it.

    thanks for the suggestion, I am looking for clarity and your suggestion, while providing clarity where I wanted it, muddles certain other things, and to go through a full change of the conditionals to get one gain and an, albeil smaller, loss, does not seem worth it,\.

    Thanks for the suggestion, sorry about not giving "the report" sooner.

    Erik

    PS
    You pull a new problem out of the hat
    what new problem?

  • Now you've expanded your reply to my first suggestion, I suggest you re-read my second suggestion more thoroughly (posted 13-Oct-2006 12:23).

  • I understand the post (13-Oct-2006 12:23) as follows. I read it as "look at something else (a 'sanitized' file) than where you are to do the changes (the 'combined' file)".

    If I understand this incorrectly, please explaun further.

    Erik

  • I read it as "look at something else (a 'sanitized' file) than where you are to do the changes (the 'combined' file)".

    That's the exact opposite of what I described. You would keep, edit and look-at only one file. Let's call that combined.c-in. It would have exactly the format you wanted from the get-go. Then you would have a build system (batch script, makefile, whatever floats your boat), that builds the three variants like this:

    sed -e 's/^TYPEA//' -e 's/^TYPE/\/\/TYPE/' combined.c-in > typeA.c
    C51 %options% typea.c
    if errorlevel 1 del typeA.c
    

    The overall idea is that only one source file is kept around. But instead of the C preprocessor you use some other tool to select the lines that form one of the three build variants --- I've picked "sed". Removing typeA.c immediately after a succesful compile makes sure that you never accidentally look at the wrong source --- because it simply doesn't exist.

  • Then you would have a build system ... that builds the three variants
    I have that already.

    Hans-Bernhard,

    The build works just fine, there is no problem there, if you understand this to be a build problem, this thread must have gone astray.

    as I started the thread "It happens that I am looking at the type b code trying to figure out something in type a (the codes are VERY similar)."

    What I hoped for was a source file where it was crystal clear for every line which build it belonged to.

    This thread was originated because I made some changes in a ~200 line segment for type q which should have been inserted in the ~200 line segment for type x.

    I recovered without any problems, just it would be nice not to repeat.

    Now that I iunderstand that you are talking 'build' wher I am reading 'edit' it becomes obvious why I have misunderstood you.

    Erik

  • The build works just fine, there is no problem there, if you understand this to be a build problem, this thread must have gone astray.

    It went astray when you failed to notice that changes to the build system are exactly what it takes to solve your authoring confusion. You want to modify the syntax of the file you edit, to make more explicit which variant each line of that file belongs to. So far, so good. But the you want to do that, this file would be incompatible with C source file structure. So it has to be input to something else than the C compiler: a preprocessor is needed. That's exactly what I proposed 'sed' for: it can handle the file structure you want, and turn it into compilable C.

    This thread was originated because I made some changes in a ~200 line segment for type q which should have been inserted in the ~200 line segment for type x.

    In this particular case, I really can't see why you want to keep all these variants in one file --- 200 lines is well worth starting a new file. This would be a lot easier by putting these segments into separate files, and then in the main file just writing

    #if defined(VARIANT_A)
    # include "fragment_foo_A.c"
    #elif defined(VARIANT_B)
    # include "fragment_foo_B.c"
    #elif defined(VARIANT_C)
    # include "fragment_foo_C.c"
    #endif
    

  • "This would be a lot easier by putting these segments into separate files, and then in the main file just writing ..."

    And for #include, the preprocessing tokens after include in the directive are processed just as in normal text (i.e., subject to macro replacement), so one can locate all the names in the source file's front matter or separate header file, leaving the code in the function's body relatively clean and free of #if/#elif/#else/#endif if that's desireable.

    #if defined(VARIANT_A)
    # define FRAGMENT_FOO1  "fragment_foo1_A.c"
    # define FRAGMENT_FOO2  "fragment_foo2_A.c"
    # define FRAGMENT_FOO3  "fragment_foo3_A.c"
    #elif defined(VARIANT_B)
    # define FRAGMENT_FOO1  "fragment_foo1_B.c"
    # define FRAGMENT_FOO2  "fragment_foo2_B.c"
    # define FRAGMENT_FOO3  "fragment_foo3_B.c"
    #elif defined(VARIANT_C)
    # define FRAGMENT_FOO1  "fragment_foo1_C.c"
    # define FRAGMENT_FOO2  "fragment_foo2_C.c"
    # define FRAGMENT_FOO3  "fragment_foo3_C.c"
    #endif
    
    void foo(void)
    {
        #include FRAGMENT_FOO1
        /*
         * ... some code ...
         */
        #include FRAGMENT_FOO2
        /*
         * ... some more code ...
         */
        #include FRAGMENT_FOO3
    }
    

  • In this particular case, I really can't see why you want to keep all these variants in one file --- 200 lines is well worth starting a new file. This would be a lot easier by putting these segments into separate files, and then in the main file just writing

    #if defined(VARIANT_A)
    # include "fragment_foo_A.c"

    Anyhow, Hans-Bernhard, I do appreaciate your efforts, believe me. However I was looking for a simple solution to something that happens about once or twice a year.

    As to the #include, I do that by a switch in the ,bat file like this fragemet show

    IF "%1"=="b" goto lcb
    IF "%1"=="ba" goto lcba
    ......

    :lcb
    copy ..\ss\usmainb.c usmain.c >..\trash\trashbin
    copy ..\ss\usledst1.c usledstb.c >..\trash\trashbin
    copy ..\ss\ussgndv1.c ussgndvr.c >..\trash\trashbin
    goto lxx

    Again, I apprecieate your efforts and am sure that your solutions work, but none accomplish the original desire of a simple solution, not to a problem, but to an annoyance.

    Lets us stop here

    Erik