0999158088e0fb3715eb27703c8c4f7123d77144
galt
  Mon Sep 21 16:51:20 2015 -0700
added GNU-C attributes to function declarations in src/inc, src/hg/inc, and some CGIs so that the compiler can catch errors where the parameter list given by the user does not match their format string. These var-args functions are like printf.

diff --git src/inc/dyOut.h src/inc/dyOut.h
index ba84fe3..7a5244d 100644
--- src/inc/dyOut.h
+++ src/inc/dyOut.h
@@ -1,141 +1,145 @@
 // dyOut - DYnamic string stack based OUTput
 //
 // CAUTION: Inclusion of this header will convert printfs to dyOutPrintfs!!!
 //          This is an Experimental/Test strategy only.  When dyOut is adopted,
 //          direct calls to dyOut functions should be used and printf macros removed.
 //
 // This module relies upon a dyString based stack of buffers which accumulate output
 // for later printing.  As a stack, only the top buffer can be filled and flushed out
 // (duOutFlush).  When flushing, the top buffer's content is appended to the next
 // lower buffer, unless explicitly requested otherwise (dyOutDirectly).
 // If the stack is empty, dyOutPrintf will be equivalent to printf.
 //
 // Output goes to STDOUT unless a single alternative out file is registered.
 
 #ifdef DSPRINT_H      // NEVER INCLUDE TWICE.  ONLY INCLUDE DIRECTLY IN C FILES.
 #error Including dyOut.h twice! Only include directly in C files as this redefines printf !!!
 #else//ifndef DSPRINT_H
 #define DSPRINT_H
 
 #include "common.h"
 #include "dystring.h"
 
 int dyOutOpen(int initialBufSize);
 // Allocate dynamic string and puts at top of stack
 // returns token to be used for later stack accounting asserts
 
-int dyOutPrintf(char *format, ...);
+int dyOutPrintf(char *format, ...)
 // Prints into end of the top ds buffer, and return resulting string length
 // If there is no current buffer, this acts like a simple printf and returns -1
+#if defined(__GNUC__)
+__attribute__((format(printf, 1, 2)))
+#endif
+;
 #define dyOutPuts(str) dyOutPrintf("%s\n",str)
 #define dyOutPutc(chr) dyOutPrintf("%c",chr)
 #define SWAP_PRINTF
 #ifdef SWAP_PRINTF
 #define printf dyOutPrintf
 #define puts dyOutPuts
 #undef putc
 #define putc dyOutPutc
 #endif//def SWAP_PRINTF
 
 int dyOutPrintDirectly(int token,FILE *file);
 // Prints the contents of the top buffer directly to a file.
 // Will leave the filled buffer at top of stack
 // Returns the length printed.
 
 int dyOutFlush(int token);
 // Flushes the top buffer to the next lower one and empties top buffer.
 // If there is no lower buffer then the content is printed to STDOUT (or registered out).
 // Returns the length flushed.
 
 int dyOutClose(int token);
 // Abandons the top buffer and its content, freeing memory.
 // Returns the length abandoned.
 #define dyOutAbandon(token) dyOutClose(token)
 
 int dyOutFlushAndClose(int token);
 // Flushes the top buffer to the next lower one and frees the top buffer.
 // If there is no lower buffer then the content is printed to STDOUT (or registered out).
 // Returns the length flushed.
 
 int dyOutFlushAndCloseAll();
 // CAUTION: Bad practice to not Open/Close levels in turn!
 // flushes, frees and closes all stacked buffers
 // returns length flushed
 
 char * dyOutContent(int token);
 // returns the content of the current buffer as a string, but does not flush or free it
 // NOTE: returned pointer is not cloned memory and will be changed by successive dyOut calls
 
 int dyOutEmpty(int token);
 // Empties the top buffer in stack (abandoning content), but leave buffer in place
 // Returns the length abandoned.
 #define dyOutAbandonContent(token) dyOutEmpty(token)
 
 int dyOutSize(int token);
 // Returns the current length of the buffer starting at the level corresponding to token.
 // Unlike other cases, the token does not have to correspond to the top of the stack!
 #define dyOutIsEmpty(token) (dyOutSize(token) == 0)
 
 int dyOutSizeAll();
 // returns combined current size of all buffers
 #define dyOutIsAllEmpty(token) (dyOutSizeAll() == 0)
 
 int dyOutStackDepth();
 // Returns the current dyOut buffer stack depth
 #define dyOutIsOpen() (dyOutStackDepth() > 0)
 
 void dyOutRegisterAltStream(FILE *out);
 // Registers an alternative to STDOUT.  After registering, all dyOut out goes to this file.
 // NOTE: There is no stack. Register/Unregister serially.
 
 void dyOutUnregisterAltStream(FILE *out);
 // Unregisters the alternative to STDOUT.  After unregistering all dyOut out goes to STDOUT.
 // NOTE: There is no stack. Register/Unregister serially.
 
 char *dyOutCannibalizeAndClose(int token);
 // Closes the top stack buffer returning content.  Returned string should be freed.
 
 char *dyOutCannibalizeAndCloseAll();
 // CAUTION: Bad practice to not Open/Close levels in turn!
 // Closes all stack buffers and returns a single string that is the full content.  
 // Returned string should be freed.
 
 void *dyOutStackPop(int token);
 // CAUTION: Not for the faint of heart: print buffer surgery is no substitute for proper coding.
 // Returns a pointer which can be dyOutStackPush'd back into place.
 // Pop/Push is useful for inserting print immediately before a dyOutOpen'd print buffer
 
 void dyOutStackPush(int token,void *dyOutPointer);
 // CAUTION: Not for the faint of heart: print buffer surgery is no substitute for proper coding.
 // Push a previously dyOutStackPop'd print buffer back onto the stack
 // Pop/Push is useful for inserting print immediately before a dyOutOpen'd print buffer
 
 
 #ifdef NOT_NOW
 // Requires regex function added to dystring.c which has been successfully tested.
 boolean dyOutRegexReplace(int token, char *regExpression, char *replaceWith);
 // CAUTION: Not for the faint of heart: print buffer surgery is no substitute for proper coding.
 // Looks for and replaces a single instance of a wildcard match in the current dyOut print buffer
 // regex follows normal EXTENDED (egrep) rules except:
 // ^ - at beginning of the regExpression only and matches beginning of buffer (not of line)
 // $ - at end of regExpression only and matches end of buffer (not end of line)
 // \n - newlines in the body of the regExpression will match newlines in the current print buffer
 // Returns TRUE on success
 // CAUTION: Wildcards match largest sub-string [w.*d] matches all of "wild wild world"
 
 
 //void dyOutTest();
 // Tests of dyOut functions
 #endif///def NOT_NOW
 
 /* Next steps:
  * 1) DONE WITH MACROS: in cheapCgi.c replace all printfs with dyOutPrintf
  * 2) DONE WITH MACROS: in hui.c replace all printfs with dyOutPrintf
  * 3) DONE WITH MACROS: in hgTrackUi replace all printfs with dyOutPrintf
  * 4) DONE: After 1-3, add opens and closes to hgTrackUi
  * 5) DONE: Handle boxing cfg with dyOutPrintf (successful test)
  * 6) Handle isConfigurable tests with dyOutPrintf and throw away results
  *    This one will require making hgTrackUi Cfgs all lib code.
  */
 
 #endif /* DSPRINT_H */