|  | /* | 
|  | Redistribution and use in source and binary forms, with or without | 
|  | modification, are permitted provided that the following conditions are met: | 
|  |  | 
|  | * Redistributions of source code must retain the above copyright | 
|  | notice, this list of conditions and the following disclaimer. | 
|  |  | 
|  | * Redistributions in binary form must reproduce the above copyright | 
|  | notice, this list of conditions and the following disclaimer in the | 
|  | documentation and/or other materials provided with the distribution. | 
|  |  | 
|  | * Neither the name of "The Computer Language Benchmarks Game" nor the | 
|  | name of "The Computer Language Shootout Benchmarks" nor the names of | 
|  | its contributors may be used to endorse or promote products derived | 
|  | from this software without specific prior written permission. | 
|  |  | 
|  | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | 
|  | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 
|  | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 
|  | ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | 
|  | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | 
|  | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 
|  | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 
|  | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 
|  | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 
|  | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 
|  | POSSIBILITY OF SUCH DAMAGE. | 
|  | */ | 
|  |  | 
|  | /* | 
|  | * The Computer Language Benchmarks Game | 
|  | * http://shootout.alioth.debian.org | 
|  | * | 
|  | * contributed by Bob W | 
|  | */ | 
|  |  | 
|  | #include <stdio.h> | 
|  | #include <stdlib.h> | 
|  |  | 
|  | #define JBFSIZE 82      // line input buffer size | 
|  | #define QBFSIZE 5200     // output buffer initial size | 
|  | #define Z16     "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" | 
|  | #define V32     "\0TVGH\0\0CD\0\0M\0KN\0\0\0YSA\0BW\0R\0\0\0\0\0\0" | 
|  | #define VALL    Z16 Z16 Z16 Z16 V32 V32 Z16 Z16 Z16 Z16 Z16 Z16 Z16 Z16 | 
|  |  | 
|  | int errex(char *s, int n) {      // error message+value, return 1 | 
|  | fprintf(stderr,"\n*** Error: %s [%d]!\n", s, n); | 
|  | return 1; | 
|  | } | 
|  |  | 
|  | int main () {                    // ***** main ***** | 
|  | char *pj, *pq, *pr;            // buffer pointers: inp,out,/out | 
|  | char *jjj = malloc(JBFSIZE);   // allocate input line buffer | 
|  | char *qqq = malloc(QBFSIZE);   // output buffer (dyn. size) | 
|  | char *pqstop = qqq+QBFSIZE;    // end-of-buffer pointer | 
|  | char xtab[256] = VALL;         // char conversion table | 
|  |  | 
|  | if (!jjj || !qqq) | 
|  | return errex("Buffer allocation", !jjj + !qqq); | 
|  | pj = fgets(jjj,JBFSIZE,stdin);         // fetch 1st line | 
|  | if (!pj) | 
|  | return errex("No input data",0); | 
|  | if (*jjj != '>') | 
|  | return errex("1st char not '>'", 0); | 
|  |  | 
|  | while (pj) {                           // MAIN LOOP: process data | 
|  | fputs(jjj, stdout);                  // output ID line | 
|  |  | 
|  | for (pq=qqq+1, pr=pqstop; ; pq++) {  // LOOP: fill output buffer | 
|  | pj = fgets(jjj, JBFSIZE, stdin);   // get line from stdin | 
|  | if (!pj || (*jjj=='>'))  break;    // EOF or new ID line | 
|  | if (pr <= (pq+61)) {               // need to resize buffer | 
|  | char *newstop = pqstop + 12777888; | 
|  | char *newptr  = realloc(qqq, newstop-qqq); | 
|  | if (!newptr) | 
|  | return errex("Out of memory", 0); | 
|  | if (newptr != qqq) {             // new base: adj. pointers | 
|  | size_t x = newptr-qqq;         // offset for pointer update | 
|  | pq+=x;  pr+=x;  qqq+=x; | 
|  | newstop+=x;  pqstop+=x; | 
|  | } | 
|  | pr = __builtin_memmove(newstop-(pqstop-pr), pr, pqstop-pr); | 
|  | pqstop = newstop;                // buffer resize complete | 
|  | } | 
|  | while (*pj) {                      // LOOP: conv. & revert line | 
|  | char c = xtab[(unsigned char)(*pj++)]; | 
|  | if (c)                           // conversion valid | 
|  | *(--pr) = c; | 
|  | } | 
|  | } | 
|  |  | 
|  | for (pq = qqq; pr<pqstop; ) {        // LOOP: format output | 
|  | size_t x = (pqstop-pr)<60 ? pqstop-pr : 60; | 
|  | __builtin_memmove(pq,pr,x);        // move line to free space | 
|  | pr+=x;  pq+=x;  *(pq++) = 0xA;     // adjust pointers, add LF | 
|  | } | 
|  | fwrite(qqq, 1, pq-qqq, stdout);      // output converted data | 
|  | } | 
|  | return 0; | 
|  | } |