v6.0 Mike Kinghan 2014-08-25

  • DEF0117: Diagnostics that cited an input line in its supposedly original form did not include any extensions of the line after a line-continuation.
  • DEF0118: The --filter option was broken for filenames that include multiple '.', by seeking to match extensions from the first '.' in the leafname rather than the last. Thus --filter cpp would fail to match a filename a.b.cpp.
  • DEF0119: The comma-operator was not accepted in preprocessor expressions.
  • DEF0120: Macro expansion was broken when arguments shadow formal parameters. Macro-expansion has been re-written from scratch.
  • DEF0121: False positives for circular symbol definitions. A function-like macro that invoked with an argument that is another call to the same macro was falsely diagnosed as having a circular definition. Fixed in macro-expansion re-write.
  • DEF0122: Ternary conditional expressions were not simplified when they could be.
  • DEF0123: Ill-formed expressions provoked diagnostics only in the `source` command. The other the other commands correctly evaluated them as insoluble but do not diagnose them.
  • DEF0124: Diagnostics may truncate a cited input line. Diagnostics that cited an input line in its supposedly original form did not include any extensions of the line after a line-continuation.
  • DEF0125: The associativity of arithmetic operators was wrongly right-to-left, not left-to-right, so an arithmetic expression in three or more unparenthisized operands of co-precedent operators was wrongly calculated, e.g. 2-21-21 as 2 instead of -40.
  • DEF0126: Garbage in #if/​#elif not an error. Coan issues a warning if excess tokens follow a directive. Where the directive is #if or #elif the argument must be an expression, so an error should be diagnosed.
  • DEF0127: Macro calls to unconfigured symbols not diagnosed. A function-like macro call e.g. FOO(x) with FOO not a configured symbol was not diagnosed. The call was silently unresolved.
  • DEF0128: Evaluation of a character literal was skipped when it was the very first token in a directive argument
  • DEF0129: C++11 character literal prefixes 'u' and 'U' were not recognized.
  • DEF0130: UCN character literals, e.g. \u89AB,\U6789ABCD were not recognized and cause a knock-on parsing bug by leaving the parser in a false "in-quotation"-state after the end of the UCN literal.
  • DEF0131: Coan fails to allow the expansion of a macro argument to a system-include name or quoted string, thus faulting a valid macro call such a HAS_INCLUDE() or HAS_INCLUDE("string")
  • TST0007: The test suite is migrated from perl to python.
  • TST0008: The test suite is migrated from the autotools serial harness to the parallel harness.
  • REW0018: --explain option reworked. The --explain option of the symbols command is re-thought to show much more clearly and concisely the derivation of each macro expansion. It now reports successive steps of macro replacement for the explained invocation rather than recursively reporting the "most resolved form" of each macro invocation in the expained invocation.
  • REW0019: Reporting for the symbols command now always reports the provenance of a reported symbol: configured global, configured transient or unconfigured.
  • REW0020: The --once option is removed and replaced by two new options --once-only and --once-per-file. The former is equivalent to the old --once. The latter causes each distinct reported item to be reported just once per input file.
  • REW0021: Lexical scanning and expression parsing are re-written more efficiently, with the result that coan 6.0 processes files on average about twice as fast as coan 5.2
  • REW0022: Coan 6.0 is written entirely to the C++11 standard. Preprocessor differentiation to support compiler versions that lag the standard is removed and distro-versions that ship such compiler versions are not supported.
  • FEA0033: The --evalsyms option of the symbols command is removed and replaced with the --expand option. --evalsyms reported the "most resolved form" of a symbol invocation, which was of little investigative use. --expand reports the full macro expansion of a symbol invocation, and the integer to which it evaluates, if any.
  • FEA0034: The new command lines is added, which causes coan to report #line directives. A corresponding option --lns is provided for the `symbols` command, causing coan to consider only #line directives for reporting symbols.
  • FEA0035: The alternative operator keywords, and, or, not, etc. are now supported.
  • FEA0036: Coan now issues an informational diagnostic whenever a #define or #undef retrospectively affects the meaning of previously defined symbols.

v5.2 Mike Kinghan 2013-09-07

  • DEF0110: Coan deleted indentation from simplified directives
  • DEF0111: UTF-8 encodings of 4 bytes were not identified.
  • DEF0112: The output of the symbols command with option --evalsyms could be corrupted by retention of logically deleted characters.
  • DEF0113: The spin command was broken on OS X due to a parochially Linux assumption about the errno set by mkdir() failure for an already-existing directory.
  • DEF0114: With the --replace option a rewritten input file could have changed permissions.
  • DEF0115: Symbols could be prematurely marked up-to-date for resolution, causing out-of-date resolved values to be reported with symbols --evalsyms or new resolved values to go unreported with --once.
  • DEF0116: Symbols were not reported for symbols --evalsyms when encountered in the resolution of another symbol.
  • FEA0031: Added option --explain for the sybols command. In reporting theresolved value of a symbol sym, coan will also recursively report the resolution of each symbol that is resolved in the course of resolving sym.
  • FEA0032: Added option --select name1[*][,name2[*]...] for the symbols command. Restricts reported symbols to those that match one of the listed names or wildcard name prefixes.

v5.1.2 Mike Kinghan 2012-06-04

  • DEF0109: Coan erroneously required whitespace to be found between the definiendum of a macro and the definiens, faulting such valid cases as #define FOO/*Comment*/ or #define MACRO/*Comment*/bar
  • REW0018: Support for the clang C++ compiler >= v3.1 is introduced.

v5.1.1 Mike Kinghan 2012-04-25

  • DEF0105: Deletion of superflous parentheses could in some cases leave no whitespace between a directive keyword and the simplified body of the directive.
  • DEF0106: The --line option was ineffective in conjunction with --replace.
  • DEF0107: The --line option was accepted together with either --discard blank or --discard comment although these pairs of are options are mutually exclusive.
  • DEF0107: The --discard blank and--discard comment options were ineffective in the spin command.
  • DEF0108: The parser parameter to stop at a double-quote is set for parsing #include directives but not cleared when done, so that if a string literal containing a comment-opener token, e.g. "/*" is scanned before any other directive the opening quote stops the parser and a new scan immediately commences which detects the opening of a genuine comment. Text is then erroneously discarded until some condition forces comment-parsing to stop.

Coan v5.1 Mike Kinghan 2012-02-01

  • DEF0104: The --debug option withdrawn in v5.0 remains documented in the man page and --help output.
  • FEA0030: An in-source #define SYM or #undef SYM directive is transiently treated as a -DSYM or -USYM option within the source file where it is found. Provide an option to suppress this behaviour at the user's risk, possibly causing coan's keep-or-drop decisions to deviate from those the preprocessor would make. Requested by Qualcomm UK.

Coan v5.0 Mike Kinghan 2011-12-06

  • DEF0096: Coan will parse without comment and evaluate either of:

    1)A boolean disjunction whose first operand is true and whose second operand is garbage - evaluated as true.

    2) A boolean conjunction whose first operand is false and whose second operand is garbage - evaluated as false. E.g.

    #if (TRUE_VAL || *!Nonsense%@)
    // Keep this code ...
    #endif
    #if !(FALSE_VAL && *!Nonsense%@)
    // Keep this code...
    #endif
    

    This occurs because short-cirtcuiting the operator is applied too soon, when the operation is identified and its first operand evaluated. Both operands should be parsed and short-circuiting deferred until the operation is applied.

    This bug has existed in every version.

  • DEF0097: Coan will mis-diagnose a missing right parenthesis in certain cases when the entire argument of an #if is enclosed in pathentheses, e.g. the legal code:
    #define LOCAL_MACRO
    #undef UNDEF_LOCAL_MACRO
    #if (defined (LOCAL_MACRO) && !defined (UNDEF_LOCAL_MACRO))
    does_coan_keep_this_1();
    #endif
    
    produces the error:
    line 3: error 0x043b0: Missing ")" in \
    "#if (defined (LOCAL_MACRO) && !defined (UNDEF_LOCAL_MACRO))"
    

    This occurs because the recursive xpression parser's logic for deleting redundant parentheses is faulty: it assumes a) that parentheses are always to be sought for deletion around an expression that, when simplified, contains no binary operator, and b) that the outermost parentheses in any such expression must surround it. But both (a) and (b) are false in the case of defined(NAME) expressions, among others, which contain no binary operator before or after simplification, and contain outermost parentheses which do not surround the expression.

    Parentheses are eligible for deletion when they actually become redundant as a result of eliminating an operand of a binary expression. In these cases the redundant parentheses *will* surround the simplified expression, and only in these cases will coan reliably determine the positions of the parentheses to delete.

    Coan erroneously attempts to delete redundant parentheses, which do not exist, from around the defined(NAME) operands in the conjunction above, and since the limits of the operands are not reliably determined in this setting, the "outermost" parentheses of the operands are detected and deleted at the positions marked ^ here:

    (defined ^LOCAL_MACRO^ && !defined ^UNDEF_LOCAL_MACRO)^
    

    - leaving the rightmost parenthesis of the whole expression unmatched whenthe parser looks for it next.

    The fix is to avoid attempting to delete redundant parentheses when it is not actually warranted.

  • DEF0098: Misevaluation of unary minus on unsigned integer constants, Sourceforge bug #3440713. The application of unary minus to an unsigned integer constant, e.g. -2U, is incorrectly evaluated as a negative signed integer. The result should remain unsigned.
  • DEF0099:The application of unary minus to an unsigned integer constant, e.g. -2U, is incorrectly evaluated as a negative signed integer. The result should remain unsigned.
  • DEF0100: Coan may crash when processing a #define directive where the definition of the symbol is continued over multiple lines.

    Coan sizes an initial allocation of heap buffer from the length of the first line of the definition and then consumes discardable characters before begining to parse the definition. But If the first line of the multi-line definition consists only of whitespace and a line-continuation, then consumption of discardable characters brings parsing to the start of the next line, which may be longer than the initial buffer, causing parsing of the next line to overrun the initial heap allocation. A crash results on the next attempted heap allocation.

    The fix is not to discard any characters before the parsing loop is entered, since accounting of heap resource is done accurately within it.

  • DEF0101: Coan fails to terminate a symbol's definition when it is followed adjacently by a multi-line comment, e.g. in:
    #define NUM_OF_BITS_FOR_UL_CCCH_MSG_TYPE 0x02/* space before the comment
    	or a single line comment and it's OK */
    #ifdef FEATURE_MODEM_MBMS
    #define NUM_OF_BITS_FOR_DL_MCCH_MSG_TYPE 0x04 /* Number of bits for MCCH
    Message type*/
    

    with the effect that the definition of NUM_OF_BITS_FOR_UL_CCCH_MSG_TYPE is parsed as: "0x02 #ifdef FEATURE_MODEM_MBMS"

    It looks like a parse error but actually isn't. Other examples with the same feature are parsed correctly. It is caused when the line-buffer gets reallocated between the calculations of the first and second pointers that are used to locate the definition in the buffer. This can result in the calculated length of the definition being arbitrarily inaccurate.

    The fix to is ensure the delimiting pointers reflect any reallocation of the line-buffer.

  • DEF0102: Bug report:
    #if (T_XXXXX && L_M)
    #endif
    
    #if ( T_XXXXX && L_M )
    #endif
    
    At the first #if containing the symbol L_M, coan terminates with the error:
    
    Missing ")" in "#if (T_XXXXX && L_M)"
    
    This parse error can occur for any symbol beginning with 'L'. Failure to parse a wide-character constant from that point terminates the parse, but it should resume from the 'L' to attempt to parse a symbol.
  • DEF0103: The "?:" operator is now supported.
  • FEA0028: Macro-expansion supported. Macro-definitions that are encountered in source are now parsed and will be used to expand macro-invocations when evaluating directives. There is no support for user-defined macros in the commandline options.
  • FEA0028: A new coan comand `spin' is supported. With the new option --dir DIRANME, this command acts like the `source' command, with the addition that all output files are written under the directory DIRNAME with the same relative structure that the input files have in the root filesystem.
  • REW0017:Coan is ported to C++. The porting is of variable thoroughness and leaves countless infelicties to be addressed. Work in progress.
  • DOC0003:Wholesale re-writing of the Doxygen documentation.

Coan v4.2.4 Mike Kinghan 2011-06-29

  • DEF0092: The --evalsyms option of the symbols command is discharged too late when a symbol FOO that is not configured by the commandline is encountered in an in-source #define FOO [definition] or #undef FOO that is eligible for reporting. In this case the symbol is transiently added to the defined/undefined symbols table for the course of the file and the symbol should be evaluated for --evalsyms *after* that has been done, but it is evaluated beforehand. This bug means that FOO will be reported for --evalsyms as insoluble, whereas it should be resolved to the value it assumes from the directive.
  • DEF0093: Defective code composes the diagnostic that complains of a -D option contradicting a prior -U option and will seg fault if executed.
  • DEF0094: coan fails to diagnose the commandline usage error of e.g. -DFOO -UFOO
  • DEF0095: If an input file is broken symbolic link it is misidentified as a directory. If --recurse if not specified if is reported as an ignored directory. If --recurse is specified a segfault ensues.

Coan v4.2.3 Mike Kinghan 2011-04-27

  • FEA0027: A 64-bit build for Windows is now supported.
  • DEF0085: Coan failed to swallow the complete argument-list of a the macro call due to fumbling macro arguments that contain operators. Then attempted to parse on from position inside the macro call causing a spurious error.
  • DEF0086: Symbols that are #define-ed or #undef-ed in-source were added to the configured symbols table for the current file in cases when they should not. They were added if the directives containing them are not going to be dropped. They should be added only if the directives containing them are not going to be dropped and are not in the scope of an insoluble conditional directive.
  • DEF0087: asserts() have been added to several source files that are followed by declarations within the same scope. Standard C forbids declarations following statements in the same scope. Visual C++ barfs on these errors.
  • DEF0088: Visual C++ (correctly) gives unresolved symbol errors for the get_options symbols optind, optopt and optarg, which were declared extern but not elsewhere defined. Now defined in get_otpions.c.
  • DEF0089: Fixed various possible-data-loss warnings in arithmetic for 64-bit build.
  • DEF0090: mingw32 gcc 4.4.1 on windows does not recognize the "ll" printf format for long long ints, breaking the build. "I64" format now used on condition that GNUWIN is defined.
  • DEF0091: The test script coan_symbol_rewind_tester.pl fails to run on Windows (rather than Wine) because it does not take options to indicate a Windows environment.
  • DOC0002: The README file in coan/test_coan was out of date and garbled.

Coan v4.2.2 Mike Kinghan 2010-12-20

  • DEF0080: The fix for DEF0077 is inadequate and swallowed newlines can still result from simplification of #if-diectives. The defective function print_line_cut() is now rewritten robustly from scratch.
  • DEF0081: Coan seg faults when a command is issued that will read input from stdin and then CTRL-D is hit, e.g. $ coan source -DFOO. This bug has been lurking for years. Is caused by not reckoning with EOF at start of file when checking for newline at at EOF.
  • DEF0082: Coan seg faults when a command is issued to read input redirected from /dev/null, e.g. $ coan source -D FOO < /dev/null. Same cause as DEF0081.
  • DEF0084: No Doxygen documentation was generated for the header file integer_ops.h.

Coan v4.2.1 Mike Kinghan 2010-12-18

  • DEF0077: The implementation of FEA0026 causes a regression. A newline can be swallowed at the end of simplified directive, concatenating it with the following line and yielding uncompilable code.
  • DEF0078: The number of backup files left by the test script coan_symbol_rewind_tester.pl would increase forever unless manually deleted.
  • DEF0079: The Doxygen configuration continued to give a version number of 4.1 for 4.2

Coan v4.2 2010-12-12

  • DEF0063: When the --discard comment option is in effect for the source command, discarded lines should be commented out by prefixing //coan <. If a block of lines to be discarded consists of a multi-line C-comment, then only the first of them is commented in that style and the remainder are output unchanged as illegal text.
  • DEF0064: When a line-continuation occurs within single-quotation, 2 bytes should be discounted from the length of the quotation, i.e. 1 for the line-continuation character and 1 for the following newline, but only 1 byte was deducted, causing parse errors in these contexts.
  • DEF0065: Parsing a string opened by double-quotes should terminate if a non-escaped newline is encountered but did not.
  • DEF0066: Parsing macro-arguments failed to detect the end in the simple case "(arg)", causing parse errors.
  • DEF0067: Any call to the previously unused function symbol_undefine() would seg fault when it in turn called eval_result_set_value(sym,0). The 2nd argument of eval_result_set_value() must be a non-null pointer to an int_spec_t.
  • DEF0068: The macro ptr_set_count() returned garbage due to invalidly casting ptr_set_h to ptr_vector_h. Now implemented as a function.
  • DEF0069: Dynamically adjust configuration to input source. Allow #define and #undef directives encountered in a translation unit to be treated as transient --define and --undef options for the course of that translation unit. In the absence of this capability the resolution of directives that involve symbols that have been define-ed or undef-ed earlier in a translation unit may be false with respect to the C preprocessor.
  • DEF0070: The --discard blank option of the source command ought to ensure that the number of source lines output equals the number input, but the implementation failed to emit blank lines to compensate for lines lost through simplification of directives, as distinct from lines simply dropped.
  • DEF0071: When the --discard comment option of the source command is given, an #if-block that is to be commented out will be output as garbage if the controlling #if condition has been simplified.
  • DEF0072: Coan did not complain if an #if/#elif directive had no argument, simply evaluating the directive as insoluble.
  • DEF0073: Coan's return codes inappropriately encoded the "lines dropped" summary for commands other than source.
  • DEF0074: make distcheck was broken in the man target by some autotools upgrade since Coan 4.1. Requires commands for the rule coan.1: man_pod.pl to refer to man_pod.pl as $< rather than as man_pod.pl.
  • DEF0075: distclean on the man target did not have clean as a requisite, causing the built man files to remain after distclean.
  • DEF0076: Corrected typos referring to coan (formerly sunifdef) as "sunidef" in the test scripts' help output.
  • REW0011: Eliminate all of the line-types LT_CONSISTENT_DEFINE_KEEP, LT_CONSISTENT_DEFINE_DROP, LT_CONTRADICTORY_DEFINE, LT_DIFFERING_DEFINE, LT_CONSISTENT_UNDEF_KEEP, LT_CONSISTENT_UNDEF_DROP, LT_CONTRADICTORY_UNDEF, LT_INCLUDE_KEEP, LT_INCLUDE_DROP for which if-control has no handlers together with the Categorical module's independant handler for these types. Reduce them all to 2 line-types, LT_DIRECTIVE_DROP and LT_DIRECTIVE_KEEP which get handled en passant upstream of if-control. The Categorical module's surviving functions will pertain solely to handling condictions between commandline -D or -U options and in-source #define or #undef directives. Accordingly rename the module "Contradiction".
  • REW0012: Simplify the tortuous implementation for evaluating #include directives and diagnosing errors therein while accomodating the possibility that the argument of the directive can be a defined symbol.
  • REW0013: Simplify the tortuous recursive implementation for obtaining the most-resolved form of a symbol. Just exhaustively expand the symbol's definition and then replace each maximally large expression in that expansion with its integer value.
  • REW0014: Absorb all responsibilities for setting or resetting the defined/undefined status of a symbol and diagnosing related errors into a new function, symbol_evaluate_status(), eliminating the present diaspora of these responsibilities.
  • REW0015: The most-resolved form of a symbol that has a circular definition is now reported as "insoluble" and no longer a partial resolution of the symbol's definition.
  • REW0016: The coan man page is now built compressed, i.e. coan.1.gz instead of coan.1, as required by packaging rules for most distros.
  • TST0006: Scripts wine_cast_tester.sh, wine_bulk_tester.sh, wine_symbol_rewind_tester.sh have been added to test_coan to enable running respectively of coan_case_tester.pl, coan_bulk_tester.pl, coan_symbol_rewind_tester.pl against mingw32 builds under wine.
  • FEA0026: Simplification of directives should preserve parentheses for readability where the meaning will otherwise depend on operator precedence.

Coan v4.1 2010-04-04

  • DEF0059: cpp syntax error diagnostics could contain garbage. When a cpp syntax error was diagnosed in an #if expression that has already been subject to some simplification, the diagnostic message displayed garbage instead of the offending content, because the line-buffer printed at this point contained non-ascii simplification codes.
  • DEF0060: If coan was given 2 or more fully qualified filenames as input that did not share a common root directory then it would construct a garbage input file tree and fail, e.g. coan CMD [OPTIONS] /usr/include/errno.h /home/chevillot/test.h.
  • DEF0061: If source contained the character constant '\'' coan emitted a bogus "stray '\'" warning.
  • DEF0062: A severe regression on v3.x: the source command stripped #include directives from output.
  • TST0004:Some case-test commandlines relied on unix/linux shell syntax and did not run on Windows. All case-tests now run on Windows.
  • TST0005: The test harness relied non-portably on Linux-like output of `uname -m` to determine host wordsize for *nix hosts and prescribed 32 bit for Windows hosts. Now wordsize is portably determined for all hosts.
  • REW0005: v4.0.1 introduced a restrictive dependency on header linux/limits.h for non-Windows builds. This was unnecessary and use of limits.h has been reinstated.
  • RET0001: Withdraw the --constant {unk|eval[,del]} option and replace it a -e, --evalconsts option with the effect that constants occurring as truth-functional operands will be evaluated and eliminated, while by default they are not. Replace the existing --eval option with --evalsyms so that it will not be parsed as a short match to --evalconsts. This amounts roughly to re-instating Unifdef's handling of constants, with --evalconsts equating to Unifdef's -k
  • FEA0026: Allow a configuration to undefine all symbols that are not defined. The -m, --implicit option for all commands implicitly --undef-s any symbol that is not --define-ed. The option enables the user to express the blanket assumption that a symbol is undefined unless it is explicitly defined.

Coan v4.0.1 2010-03-09

  • DEF0052: A preprocessor directive found at end-of-file with a missing newline caused coan to abend confused.
  • DEF0053: When a configured symbol that is defined as some unconfigured symbol appears in an expression coan concludes that the expression is illegal after the configured symbol is parsed and issues a spurious diagnostic, which may be a warning or error depending on the context. Coan ought to find that the expression is simply insoluble, if it is in fact legal
  • DEF0054: The implementation of preprocessor arithmetic was slapdash. All integer values were construed as int or else too-big. 'U'/'u' and 'L'/'l' integer type-suffixes were parsed but ignored. The implementation now correctly construes and calculates with values of all the C integral types from char through unsigned long long. The integer promotions and the usual arithmetic conversions are applied.
  • DEF0055: Regression. Coan seg-faulted if the same symbol was -D-ed or -U-ed more than once on the commandline.
  • DEF0056: A symbol used as an argument to the #include directive (which is legal when the symbol resolves as a header file name) would not be detected by the symbols command.
  • DEF0057: The man page incorrectly prescribed -l as a short form of the --line option.There is no short form.
  • DEF0058: make distcheck was broken due to use of the obselete environment variable SUNIFDEF_PKGDIR where COAN_PKGDIR should have been used.
  • REW0006: Coan would erase obfuscatory line-continuations embedded within identifiers simply for convenience of parsing. It now preserves them.
  • REW0007: The already swollen evaluator module became further bloated with the addition of support for evaluating character constants. Two new modules have been detached from it: the integer_ops module, which deals with evaluation of integer operations, and the integer_constant module, which deals with evaluation of integer constants, including character constants.
  • REW0008: A new module has been introduced, the lexicon module, to centralise the recognition of preprocessor keywords and operators.
  • FEA0027: Character constants are now parsed as integer values. Multi-byte utf8 character constants and character constants expressed as escaped hex or octal codes, as well as ascii characters, are correctly evaluated.

Coan v4.0 2009-03-14

  • DEF0047: If a commandline option of the form -DSYM=VAL is given coan should recognise #define FOO TEXT as equivalent to the commandline option if TEXT equates to VAL when embedded comments are re stripped out, but failed to do so, falsely diagnosing a differing redefintion of FOO.
  • DEF0048: A string could be erroneously identified as a symbol although not beginning with an alphabetic character or underscore.
  • DEF0049: The state of the #if-control module was re-initialised too late on reaching a new input file and was not re-initialised at all on entering or leaving a new directory. Consequently the progress messages emitted on reaching a new file or on entering or leaving a directory would have a spurious trailer like (#if line 44 depth 1) falling through from the processing of the previous input file if that processing had ended with an parse error.
  • DEF0050: A missing newline at end of file was diagnosed as an error if encountered while processing a directive but otherwise not diagnosed at all. This was illogical as in either case the event indicates that the file may have been truncated, and in either case it merits only a warning if nothing else is wrong. The event is now always diagnosed as a warning.
  • DEF0051: A file extension EXT given to the --filter option would be matched by any file whose extension had EXT as a terminal segment.
  • DEF0052: Source code containing an escaped double-quote, e.g. char ch == '\"'; would cause a spurious "stray \" warning.
  • FEA0018:The commandline interface now supports a range of operating modes or commands. The command is selected by the the first option on the commandline, which is a keyword without a '-' or '--' prefix. This new regime avoids a proliferation of cases in which options associated with one modality are meaningless or incompatible with another modality but may still be intermixed.
  • FEA0019: The former default mode of operation (editing the input source to output as implied by the specified configuration) is now one the several operating modes and is selected by the source command. The source command has the options:
    • -r, --replace
      • Overwrite input file with output file. Implied by --recurse. With -r, stdin supplies the input filenames. Otherwise stdin supplies an input file; the output file is stdout.
    • -BSUFFIX, --backup SUFFIX
      • Backup each input file by appending SUFFIX to the name. Applies only with -r.
    • -kd, --discard drop
      • Drop discarded lines from output.
    • -kb, --discard blank
      • Blank discarded lines on output.
    • -kc, --discard comment
      • Comment out discarded lines on output.
    • -xd, --conflict delete
      • Delete #defines and #undefs that contradict -D or -U options.
    • -xc, --conflict comment
      • Insert diagnostic comments on contradictions as per -xd. (Default.)
    • -xe, --conflict error
      • Insert diagnostic #errors on contradictions as per -xd.
    • --line
      • Generate #line directives to make CPP line-numbering of output agree with input even of lines are dropped.
    • -c, --complement
      • Complement. Retain the lines that ought to be dropped and vice versa. (Retained #-directives will still be simplified where possible.)
  • FEA0020: The former --symbols option has been promoted to the symbols command. The symbols command supports the options:
    • -i, --ifs
      • List symbols that occur #if[[n]def]/#elif directives.
    • -d, --defs
      • List symbols that occur in #define directives.
    • -u, --undefs
      • List symbols that occur in #undef directives.(Default: -i -d -u)
    • -o, --once
      • List only the first occurrence of each symbol. (Default: List all occurrences.)
    • -A, --active
      • List only symbols from operative directives
    • -I, --inactive
      • List only symbols from inoperative directives
    • -L, --locate
      • Report the source file and line number of each listed occurrence.
    • -e, --eval
      • Report the resolved value of each symbol.
  • FEA0021: The 'includes' command is provided for reporting occurrences of #include directives. The command has the options:
    • -s, --system
      • List system headers, i.e. <header.h>
    • -L, --local
      • List local headers, i.e. "header.h" (Default: -s -L)
    • -o, --once
      • List only the first occurrence of each header. (Default: List all occurrences.)
    • -A --active
      • List only headers from operative directives.
    • -I --inactive
      • List only headers from inoperative directives.
    • -L, --locate
      • Report the source file and line number of each listed occurrence.
  • FEA0022: The 'defs' command is provided for reporting occurrences of '#define' and '#undef' directives. The command has the options:
    • -o, --once
      • List only the first occurrence of each distinct #define or #undef directive (Default: List all occurrences.)
    • -A --active
      • List only operative #define and #undef directives.
    • -I --inactive
      • List only inoperative #define and #undef directives.
    • -L, --locate
      • Report the source file and line number of each listed occurrence.
  • FEA0023: The pragmas command is provided for reporting occurrences of the #pragma directive. The command has the same options as defs.
  • FEA0024: The errors command is provided for reporting occurrences of the #error directive. The command has the same options as defs.
  • FEA0025: The directives command is provided for reporting occurrences of any directives. The directives command accepts any of the options of includes, defs, pragmas and errors commands and combines their effects.

Sunifdef v3.1.3 2008-01-23

  • DEF0041: When -DSYM=VAL is specified with VAL a hex integer constant, rather than a decimal constant, coan would fail to resolve SYM in expressions unless the --constant eval was specified, which should be unnecessary. The anomaly ocurred because eval_symbol() anticipated constant values only as decimal constants and, upon encountering a hex-prefix "0x" or "OX" would attempt to parse the token as an expression, invoking eval_table() and ultimately eval_unary(). The latter function would resolve a hex constant, but only if --constant eval is in effect, since the function is assumed to operate on source text rather than on the definiens of -DSYM=VAL. The fix consists in recognising hex constants as such in eval_symbol().
  • DEF0042: When -DSYM=VAL is specified with VAL a soluble expression containing at least one integer constant operand, coan would fail to resolve SYM in expressions unless --constant eval was specified. The reason is the same as in bug DEF0041. The fix consists in recording the origin of the text upon which eval_unary() is called - source text or else the definiens of a --defined symbol - and always resolving integer contstants in the latter case.
  • DEF0043: coan did not distinguish octal numerals as integer constants and evaluated them as decimal numerals.
  • DEF0044: coan did not recognise the suffixes u/U, l/L as belonging to integer constants. These suffixes are now recognised; however, coan still evaluates all integer constants as ints and performs signed integer arithmetic upon them. This is an unfixed bug.
  • DEF0045: coan did not detect integer overflow in evaluating constants. Now detects overflow whenever the value of a constant will exceed INT_MAX and leaves the constant unresolved with a warning to that effect.
  • DEF0046: The --help message contained an occurrence of '--constants' that ought to have been '--constant'.

Sunifdef v3.1.2 2007-11-19

  • DEF0040: Defective filename matching could lead to a file being mistaken for a directory when building the input file tree, if a directory name was an initial substring of a filename at the same level.

Sunifdef v3.1.1 2007-11-17

  • DEF0036: Failed to detect unexpected end of file within an unmatched if when missing newline at end of file.
  • DEF0037: Summary counts of files reached and files abandoned would be short by 1 if a parse error was encountered without the --keepgoing option in force.
  • DEF0038: The extension-matching code supporting the --filter option was broken, allowing --filter EXT to match any file whose extension ended in EXT, even if not identical with EXT.
  • DEF0039: The current if-depth and if-line number were irrelevantly reported on progress messages.
  • TST0004: The test framework is ported from shell script to perl for portability to Windows.

Sunifdef v3.1 2007-05-06

  • FEA0017: Now can cope with multi-line C-comments embedded within directives.
  • RET0003: The --obfusc option is withdrawn because the contexts formerly classified as obfuscated are now handled in normal parsing.
  • DEF0030: -DSYM=VAL or -USYM=VAL arguments when reported by the --verbose option do not include the =VAL part.
  • DEF0031: The --constant policy should apply to constants only in truth-functional contexts but was applied in all contexts. In arithmetic contexts constants should always be treated as integers. (Falsely recorded as fixed DEF0010).
  • DEF0032: With the --file option the "Building input tree" diagnostic was emitted even without --verbose and could not be suppressed.
  • DEF0032: The --line option was not documented either in the man page or in the --help output.
  • DEF0033: Return codes expressed all severities 1 level greater than the true level.
  • DEF0034: A false verdict of differently redefined symbol would be returned when the definiens of the symbol was not itself a symbol.
  • DEF0035: Use of the --line option did not set the SUMMARY_CHANGED_LINES flag in output.
  • DOC0003: The man page is rationalised so that short and long variants of options are listed together rather in separate groups.

Sunifdef v3.0

  • FEA0009: Unbalanced parentheses in expressions now provoke parse errors rather than merely causing the expression to be unresolved.
  • FEA0010: Every output message now has a reason code.
  • FEA0011: coan is now agnostic between Unix and Windows line-ends.
  • FEA0012: New --recurse option enables recursion into input directories.
  • FEA0013: Progress messages are a new category of messages with a severity lower than informational messages.
  • FEA0014: New --filter option enables input files to be filtered by file extension.
  • FEA0015: New --keepgoing option makes coan continue processing subsequent input files after errors.
  • FEA0016: Hex and octal constants are now recognised in preprocessor directives.
  • RET0002: The --gag 0xXXXX variant of --gag option is withdrawn.
  • DEF0024: Usage gave -gw as default instead of -gi
  • DEF0025: The --symbols option could produce spurious warnings of contradictions.
  • DEF0026: The length of formatted output messages was unsafely assumed not to exceed 2K. Their length is now limited only by available heap.
  • DEF0027: A symbol for which --undef SYM was specified was evaluated as an insoluble expression. This was at odds with the C Standard, which stipulates the preprocessor will evaluate an undefined symbol as 0. The behaviour now agrees with the Standard.
  • DEF0028: The state of the chew module was not fully reinitialised at entry to each input file, causing any newline-within-quotation error to be spuriously repeated for subsequent input files.
  • DEF0029: An unarranted simplification was applied to any compound truth functional expression containing more than 1 operator where the order of evaluation was determined by precedence rather than by parentheses.
  • REW0003: The inefficiently recursive formatting of output messages is reworked.
  • REW0004: Source files diagnostic.* renamed to report.* to reflect broader function
  • REW0005: The range of message reason codes is widened from 6 to 7 bits to accomodate additional diagnostics.
  • TST0003: The test framework is extended to cover recursive processing of large source trees.
  • DOC0002: An extensive EXAMPLES section has been added to the man page.

Sunifdef v2.1.2

  • DEF0022: Fixed warnings for 64-bit build and unused function results.
  • DEF0023: Fixed infringements of C89

Sunifdef v2.1.1

  • DEF0021: Evaluation of unparenthesised compound binary truth-functions "...op...op..." lost information of unresolved operands causing incorrect simplifications.

Sunifdef v2.1

  • DEF0001: All usage errors now emit a diagnosis
  • DEF0017: --symbols option failed to list FOO when occurring in ifdef FOO or ifndef FOO.
  • DEF0018: Unnecessary insistence on --replace option to process multiple files with --symbols option.
  • DEF0019: Lingering reference to --ignore in usage diagnostic should have been changed to --podsym.
  • DEF0020: The man page is more complete and correct.
  • FEA0001: Enable discarded lines to be output in the form of comments.
  • FEA0002: --symbols option now has arguments all, first and locate. all causes all occurrences of symbols to be listed. first causes only the first occurrence of each symbol to be listed. locate causes the file name and line number to be appended to each listed occurrence.
  • FEA0003 New --line option generates line directives to make CPP line-numbering of output agree with input even of lines are dropped.
  • RET0001 The --podsym option, formerly the --ignore option, is dropped as not being plausibly worthwhile.

Sunifdef v2.0

  • DEF0015: Truth-functional simplification was broken for constant operands when --constant eval in force.
  • DEF0016: Clarified murky evaluation of the --podsym attribute over && and ||.
  • REW0001: Parser substantially simplified and much more powerful. Previously only evaluated truth-functions and relational operators; could evaluate FOO defined -DFOO=VAL only where VAL was an integer constant. Now can evaluate all C operators except the conditional operator; can evaluate FOO provided VAL can be recursively evaluated, but will determine that circularly defined symbol -DFOO=BAR -DBAR=FOO is unresolved rather than loop forever.

Sunifdef v1.0.1

Trivial fixes to sunifdef; significant fixes to the test framework.
  • DEF0012: Warnings fixed to compile clean with -Wall
  • DEF0013: Removed needless redefinition of PATH_MAX from Windows build.
  • DEF0014: make check always reported success even if the tests reported failures
  • TST0002: The test driver test_coan is strengthened:
    • To work without relying on system() to return a true exit code from the executed command
    • To work without relaying on system() to distinguish output redirectors from the arguments of the command.
    • To work in a Wine (Windows on Unix) emulator environment when the input pathnames are not Windified
    • To work in a Cygwin (Unix on Windows) emulator environment when the input pathnames are not Windified.

Sunifdef v1.0

Initial stable release.
  • REW0002: The -i | --ignore option is renamed -p | --podsym to indicate better that the option causes lines to be treated as Plain Old data. The -t | --text option is renamed -P | --pod for the same reason.
  • REW0003: The implementation of the --constant policy, though consistent, was not conceptually coherent. Reworked.
  • FEA0006: The -p | --podsym option is honoured for if defined and if !defined directives as well as ifdef and ifndef.
  • DEF0004: Overlooked occurrence of "unifdef" rather than "sunifdef" in diagnostic output.
  • DEF0005: The dropped lines count was not incremented for conflicts in the presence of the --conflict delete option.
  • DEF0006: The SUMMARY_ERRORED_LINES status flag (return code & 64) was not set in respect of the --conflict error option.
  • DEF0007: The --conflict error option was not followed through for the case where it causes an unconditional error to be output (return code & 128).
  • DEF0009: printline_cut() was capable of leaving non-printable house-keeping bytes in the tidied up output buffer.
  • DEF0010: The --constant policy should apply to constants only in truth-functional contexts but was applied in all contexts. In arithmetic contexts constants should always be treated as integers: the constant policy does not apply.
  • DEF0011: Parentheses rendered redundant by simplification were not deleted in all cases where they safely could be.
  • TST0001: Automated test framework provided. Executes with make check.

Sunifdef v0.1.4

Bug fix release.

  • DEF0002: memmove() miscalculation could cause seg fault in symbol table lookups.
  • DEF0003: Mis-ordering of insertions into the symbol table could cause lookups to fail erroneously.

Sunifdef v0.1.3

Initial Public Offering