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

Sub String in Pre-Processor?

Does anyone know how to get the pre-processor to spit out a substring? In this case, I want to include only the year from the __DATE__ macro.
Something like:

#define YEAR=substr(8,4,__DATE__)
const char code ROMSTRING={"COPYRIGHT " YEAR "by such and such company. Compiled on " __DATE__};

where the #define is something the pre-processor can handle.

Thanks

Parents Reply Children
  • As Per says, the 'C' preprocessor has no such functionality.

    However, in the specific case of copyright, this depends on the date that the text was written - not the date that it was compiled!

  • I was afraid of that.

    Anyone know a neat trick to automagically imbed just the year the software was compiled?

    (Of course manually #defining it works fine, but it will surely get done wrong at some time.)

    The only thing I can think of is to post process the HEX file.

  • As Andy noted, the copyright does not follow the build year.

    If you develop some source code during 5 years, all that code are not covered by the same copyright year. You normally write 2003, 2004, 2005, 2006, 2007 or 2003-2007 in the copyright notice. Then, you must separately have source code versioning to be able to deduce which code lines where from 2003, since their copyright expires earlier. For some countries, you must register your copyright. For some countries, it is enough to add the copyright notice and make sure that you can back up the year with secondary data.

  • Thanks.
    I did oversimplify the case just to get to the issue faster. Actually, the intended date is a range, where the compiled date is one end of the range.

    const char code ROMSTRING[]="COPYRIGHT 2001-2007"

    We don't re-roll the package unless there is a change, so usually, the copyright year must change the first time a new package is realeased each year, and we always forget to do it.

    If it could be automated it would be better than having something say "COPYRIGHT 2001-2006, compiled on Oct 20, 2007." Which is not what we really want.

    Also, the issue of passing a substring of a literal to the compiler as part of an initialization has utility in several other ROM structures we are building. Whatever got me the YEAR characters from __DATE__ would work there too.

    As it stands now, we are abusing the bug in the compiler where the terminating null can be supressed in a definition:
    const code char s1[]="ABCD" // this is 5 chars long (with NULL)
    const code char s2[4]="ABCD" // this 4 chars long (NO NULL)

    This can be abused to concat strings, and is especially useful when part of the data is "literal" (__FILE__ etc.) and part of it is single chars some of which may be #defined themselves. (info[]={MODULE_TYPE,SER,0x33,0x34})

    Maybe I should just pre-process with M4.

    (or change the entire data structure to something more appropriate for including in a ROM table.)

    But alas, the issue still exists that I don't want the whole __DATE__, or __FILE__, or __TIME__. I just need a few characters of them.

    So I was looking for an alternative to #defineing each one of them manually.

  • As it stands now, we are abusing the bug in the compiler where the terminating null can be supressed in a definition:

    const code char s1[]="ABCD" // this is 5 chars long (with NULL)
    const code char s2[4]="ABCD" // this 4 chars long (NO NULL)
    


    That is not a bug. That is expected behaviour - a special case for initializing character arrays. You can do it with all (non-broken) C compilers.

  • The ISO/IEC 9899:1999(E) document says in paragraph 6.7.8 note 14:

    "An array of character type may be initialized by a character string literal, optionally enclosed in braces. Successive characters of the character string literal (including the terminating null character if there is room or if the array is of unknown size)initialize the elements of the array."

  • Sounds like more of a job for the build tool and version control system, not the compiler itself. You could write a script that takes the latest date of a checkin, or one that runs on every checkin, and update a file that contains the copyright year. Perhaps you devote a file just to this purpose, so it can easily be automatically generated. Maybe all the file has is the one line

    Copyright.h
    --
    #define LAST_COPYRIGHT_YEAR  "2006"
    

    I don't know if (legally) you update the copyright without changing the source. That is, does mere compilation update the copyright date? Or is it just changes to the source?

    With current US law, I think updating the copyright date is both unnecessary and useless. Copyright for anything created since 1977 lasts until 70 years after the author's death, not a fixed time since "last touched". Anonymous works and works for hire (most software) are protected for 95 years from initial publication or 120 years from creation (whichever expires first), so again the "last touched" date has no effect on extended the copyright.

    www.copyright.gov/.../faq-duration.html

    So perhaps it's not worth knocking yourself out to solve the problem.

  • Compilation should not affect a copyright. Only modified/new code gets a new copyright year.

  • so usually, the copyright year must change the first time a new package is realeased each year,

    No, it need not. It must change for, and only for, those files that were changed in the new year. You don't get a new copyright year just because your calendar passed New Year.

    and we always forget to do it.

    That's a problem completely outside the domain of Keil, or compilers in general. This is a task for your version control system. It should be quite easy to implement an automatic check that any C file you check in, if it has a copyright string at all, mentions the current year in it.

  • Thanks everyone for all the input. You have all brought up some very good points.

    A few clarifications:
    1.) Currently each file has it's own manually updated (ideally RCS updated -- Thanks Drew!) Copyright date string. These strings exist as a comment, and are not currently included in the ROM image (due to space limitiations.) These dates are only changed if the individual file containing them is changed.

    2.) The Copyright string I was really talking about is "global" (the only one embedded in the resultant ROM image), it should update whenever any file used to create it is changed. The underlying assumption, (which I admit need not hold true) is that at least one file changed, or you would not be rebuilding the package. Again, the idea of using the checkin date is a much better approach.

    Thanks Per, for the clarification on the ANSI C variable definitions. I feel better about using the technique knowing it is 'supposed' to be portable.

    Thanks Andy, for the links. The issue at hand (how to automatically generate a substring literal pre-compile) would make several other ROM structures much easier to build up. Since the solutions all utilize external utility type programs, I am seriously considereing adding a pre-preprocessor stage like M4 etc.

    Thanks Drew, for the idea of making the date be checkin based, rather than compile based.

  • Tom, Love and miss you. Hope all is well and you are happy. Pray this is my nephew. Please contact me by email or call me. I am at same addresss and phone number. This is my answered prayer that you are still alive and well. God Bless you. Aunt Verea