Friday, January 20, 2012
Notes about an overheard conversation between a blogger and his lovely and talented copy editor
“I think you miscounted.”
“Here?”
“Yes. There are only two problems … cache invalidation … ”
“Uh huh.”
“Naming things … ”
“Yeah … ”
“and off-by-one errors … oh. Oh! D'oh!”
99 ways to program a hex, Part 12: C99, const and restrict correctness, assertive, GCC extenstions
And today's code is identical to part 10 save again for one line—it too uses a GCC extension per yesterday's code.
This also marks the end of the C versions for a couple of days.
/************************************************************************* * * Copyright 2012 by Sean Conner. All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * Comments, questions and criticisms can be sent to: sean@conman.org * *************************************************************************/ /* Style: C99, const and restrict correctness, assertive, GCC extenstions */ #include <stdio.h> #include <ctype.h> #include <string.h> #include <stdlib.h> #include <assert.h> #define LINESIZE 16 static void do_dump (FILE *const restrict,FILE *const restrict) __attribute__((nonnull,nothrow)); /****************************************************************/ int main(const int argc,char *const restrict argv[]) { assert(argc >= 1); assert(argv != NULL); assert(argv[0] != NULL); if (argc == 1) do_dump(stdin,stdout); else { for (int i = 1 ; i < argc ; i++) { FILE *fp = fopen(argv[i],"rb"); if (fp == NULL) { perror(argv[i]); continue; } printf("-----%s-----\n",argv[i]); do_dump(fp,stdout); fclose(fp); } } return EXIT_SUCCESS; } /******************************************************************/ static void do_dump(FILE *const restrict fpin,FILE *const restrict fpout) { unsigned char buffer[BUFSIZ]; size_t offset; size_t bread; assert(fpin != NULL); assert(fpout != NULL); offset = 0; while((bread = fread(buffer,1,BUFSIZ,fpin)) > 0) { unsigned char *pbyte = buffer; while (bread > 0) { char ascii[LINESIZE + 1]; fprintf(fpout,"%08lX: ",(unsigned long)offset); size_t j = 0; do { fprintf(fpout,"%02X ",*pbyte); if (isprint(*pbyte)) ascii [j] = *pbyte; else ascii [j] = '.'; pbyte ++; offset ++; j ++; bread --; } while ((j < LINESIZE) && (bread > 0)); ascii [j] = '\0'; if (j < LINESIZE) for (size_t i = j ; i < LINESIZE ; i++) fprintf(fpout," "); fprintf(fpout,"%s\n",ascii); } if (fflush(fpout) == EOF) { perror("output"); exit(EXIT_FAILURE); } } } /***************************************************************/