diff options
Diffstat (limited to 'rpmio/sexp/sexp-output.c')
-rw-r--r-- | rpmio/sexp/sexp-output.c | 642 |
1 files changed, 0 insertions, 642 deletions
diff --git a/rpmio/sexp/sexp-output.c b/rpmio/sexp/sexp-output.c deleted file mode 100644 index cf2b23522..000000000 --- a/rpmio/sexp/sexp-output.c +++ /dev/null @@ -1,642 +0,0 @@ -/* SEXP implementation code sexp-output.c - * Ron Rivest - * 5/5/1997 - */ - -#include <stdio.h> -#include <malloc.h> -#include "sexp.h" - -/*@access sexpOutputStream @*/ -/*@access sexpSimpleString @*/ - -/*@access sexpList @*/ -/*@access sexpString @*/ -/*@access sexpObject @*/ - -struct sexpOutputStream_s { - long int column; /* column where next character will go */ - long int maxcolumn; /* max usable column, or -1 if no maximum */ - long int indent; /* current indentation level (starts at 0) */ - void (*putChar)(); /* output a character */ - void (*newLine)(); /* go to next line (and indent) */ - int byteSize; /* 4 or 6 or 8 depending on output mode */ - int bits; /* bits waiting to go out */ - int nBits; /* number of bits waiting to go out */ - long int base64Count; /* number of hex or base64 chars printed - this region */ - int mode; /* ADVANCED, BASE64, or CANONICAL */ -/*@shared@*/ /*@relnull@*/ - FILE *outputFile; /* where to put output, if not stdout */ -}; - -/*@unchecked@*/ /*@observer@*/ -static char *hexDigits = "0123456789ABCDEF"; - -/*@unchecked@*/ /*@observer@*/ -static char *base64Digits = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - -/***********************/ -/* SEXP Output Streams */ -/***********************/ - -/* putChar(os,c) - * Puts the character c out on the output stream os. - * Keeps track of the "column" the next output char will go to. - */ -void putChar(sexpOutputStream os, int c) -{ - (void) putc(c,os->outputFile); - os->column++; -} - -/* varPutChar(os,c) - * putChar with variable sized output bytes considered. - */ -void varPutChar(sexpOutputStream os, int c) -{ - c &= 0xFF; - os->bits = (os->bits << 8) | c; - os->nBits += 8; - while (os->nBits >= os->byteSize) { - if ((os->byteSize==6 || os->byteSize==4 - || c == '}' || c == '{' || c == '#' || c == '|') - && os->maxcolumn > 0 - && os->column >= os->maxcolumn) - os->newLine(os,os->mode); - if (os->byteSize == 4) - os->putChar(os, - hexDigits[(os->bits >> (os->nBits-4)) & 0x0F]); - else if (os->byteSize == 6) - os->putChar(os, - base64Digits[(os->bits >> (os->nBits-6)) & 0x3F]); - else if (os->byteSize == 8) - os->putChar(os,os->bits & 0xFF); - os->nBits -= os->byteSize; - os->base64Count++; - } -} - -/* changeOutputByteSize(os,newByteSize,mode) - * Change os->byteSize to newByteSize - * record mode in output stream for automatic line breaks - */ -void changeOutputByteSize(sexpOutputStream os, int newByteSize, int mode) -{ - if (newByteSize != 4 && newByteSize !=6 && newByteSize !=8) - ErrorMessage(ERROR,"Illegal output base %d.",newByteSize); - if (newByteSize !=8 && os->byteSize != 8) - ErrorMessage(ERROR,"Illegal change of output byte size from %d to %d.", - os->byteSize, newByteSize); - os->byteSize = newByteSize; - os->nBits = 0; - os->bits = 0; - os->base64Count = 0; - os->mode = mode; -} - -/* flushOutput(os) - * flush out any remaining bits - */ -void flushOutput(sexpOutputStream os) -{ if (os->nBits > 0) - { - if (os->byteSize == 4) - os->putChar(os,hexDigits[(os->bits << (4 - os->nBits)) & 0x0F]); - else if (os->byteSize == 6) - os->putChar(os,base64Digits[(os->bits << (6 - os->nBits)) & 0x3F]); - else if (os->byteSize == 8) - os->putChar(os,os->bits & 0xFF); - os->nBits = 0; - os->base64Count++; - } - if (os->byteSize == 6) /* and add switch here */ - while ((os->base64Count & 3) != 0) - { if (os->maxcolumn > 0 && os->column >= os->maxcolumn) - os->newLine(os,os->mode); - os->putChar(os,'='); - os->base64Count++; - } -} - -/* newLine(os,mode) - * Outputs a newline symbol to the output stream os. - * For ADVANCED mode, also outputs indentation as one blank per - * indentation level (but never indents more than half of maxcolumn). - * Resets column for next output character. - */ -void newLine(sexpOutputStream os, int mode) -{ - if (mode == ADVANCED || mode == BASE64) { - os->putChar(os, '\n'); - os->column = 0; - } - if (mode == ADVANCED) { - int i; - for (i=0; i<os->indent && (4*i)<os->maxcolumn; i++) - os->putChar(os, ' '); - } -} - -void sexpOFnewLine(sexpOutputStream os, int mode) -{ - os->newLine(os, mode); -} - -void sexpOFwidth(sexpOutputStream os, int width) -{ - if (width >= 0) - os->maxcolumn = width; -} - -/* sexpOFopen() - * Creates and initializes new sexpOutputStream object. - */ -sexpOutputStream sexpOFopen(const char * ofn, const char * fmode) -{ - sexpOutputStream os; - os = (sexpOutputStream) sexpAlloc(sizeof(*os)); - os->column = 0; - os->maxcolumn = DEFAULTLINELENGTH; - os->indent = 0; - os->putChar = putChar; - os->newLine = newLine; - os->byteSize = 8; - os->bits = 0; - os->nBits = 0; - os->mode = CANONICAL; - - if (ofn == NULL) { -/*@-assignexpose@*/ - os->outputFile = stdout; -/*@=assignexpose@*/ - } else { - os->outputFile = fopen(ofn, fmode); - if (os->outputFile == NULL) - ErrorMessage(ERROR, "Can't open output file %s.", ofn); - } - return os; -} - -/*******************/ -/* OUTPUT ROUTINES */ -/*******************/ - -/* printDecimal(os,n) - * print out n in decimal to output stream os - */ -void printDecimal(sexpOutputStream os, long int n) -{ - char buffer[50]; - int i; - -/*@-bufferoverflowhigh@*/ - sprintf(buffer, "%ld", n); -/*@=bufferoverflowhigh@*/ - for (i=0; buffer[i]!=0; i++) - varPutChar(os, buffer[i]); -} - -/********************/ -/* CANONICAL OUTPUT */ -/********************/ - -/* canonicalPrintVerbatimSimpleString(os,ss) - * Print out simple string ss on output stream os as verbatim string. - */ -void canonicalPrintVerbatimSimpleString(sexpOutputStream os, sexpSimpleString ss) -{ - octet * c = simpleStringString(ss); - size_t len = simpleStringLength(ss); - size_t i; - - if (c == NULL) - ErrorMessage(ERROR, "Can't print NULL string verbatim"); - /* print out len: */ - printDecimal(os, (long int)len); - varPutChar(os, ':'); - /* print characters in fragment */ - for (i=0; i<len; i++) varPutChar(os, (int)*c++); -} - -/* canonicalPrintString(os,s) - * Prints out sexp string s onto output stream os - */ -void canonicalPrintString(sexpOutputStream os, sexpString s) -{ - sexpSimpleString ph = sexpStringPresentationHint(s); - sexpSimpleString ss; - - if (ph != NULL) { - varPutChar(os, '['); - canonicalPrintVerbatimSimpleString(os,ph); - varPutChar(os, ']'); - } - ss = sexpStringString(s); - if (ss == NULL) - ErrorMessage(ERROR,"NULL string can't be printed."); - else - canonicalPrintVerbatimSimpleString(os, ss); -} - -/* canonicalPrintList(os,list) - * Prints out the list "list" onto output stream os - */ -void canonicalPrintList(sexpOutputStream os, sexpList list) -{ - sexpIter iter = sexpListIter(list); - sexpObject object; - varPutChar(os, '('); - while (iter != NULL) { - object = sexpIterObject(iter); - if (object != NULL) - canonicalPrintObject(os, object); - iter = sexpIterNext(iter); - } - varPutChar(os, ')'); -} - -/* canonicalPrintObject(os,object) - * Prints out object on output stream os - * Note that this uses the common "type" field of lists and strings. - */ -void canonicalPrintObject(sexpOutputStream os, sexpObject object) -{ - if (isObjectString(object)) - canonicalPrintString(os, (sexpString)object); - else if (isObjectList(object)) - canonicalPrintList(os, (sexpList)object); - else ErrorMessage(ERROR,"NULL object can't be printed."); -} - -/* *************/ -/* BASE64 MODE */ -/* *************/ -/* Same as canonical, except all characters get put out as base 64 ones */ - -void base64PrintWholeObject(sexpOutputStream os, sexpObject object) -{ - changeOutputByteSize(os, 8, BASE64); - varPutChar(os,'{'); - changeOutputByteSize(os, 6, BASE64); - canonicalPrintObject(os, object); - flushOutput(os); - changeOutputByteSize(os, 8, BASE64); - varPutChar(os,'}'); -} - -/*****************/ -/* ADVANCED MODE */ -/*****************/ - -/* TOKEN */ - -/* canPrintAsToken(ss) - * Returns TRUE if simple string ss can be printed as a token. - * Doesn't begin with a digit, and all characters are tokenchars. - */ -int canPrintAsToken(sexpOutputStream os, sexpSimpleString ss) -{ - octet * c = simpleStringString(ss); - size_t len = simpleStringLength(ss); - size_t i; - - if (c == NULL) return FALSE; -/*@-unsignedcompare@*/ /* XXX len now unsigned size_t. */ - if (len <= 0) return FALSE; -/*@=unsignedcompare@*/ - if (isDecDigit((int)*c)) return FALSE; - if (os->maxcolumn > 0 && os->column + len >= os->maxcolumn) - return FALSE; - for (i=0; i<len; i++) - if (!isTokenChar((int)(*c++))) return FALSE; - return TRUE; -} - -/* advancedPrintTokenSimpleString(os,ss) - * Prints out simple string ss as a token (assumes that this is OK). - * May run over max-column, but there is no fragmentation allowed... - */ -void advancedPrintTokenSimpleString(sexpOutputStream os, sexpSimpleString ss) -{ - octet * c = simpleStringString(ss); - size_t len = simpleStringLength(ss); - size_t i; - - if (os->maxcolumn>0 && os->column > (os->maxcolumn - len)) - os->newLine(os, ADVANCED); - for (i=0; i<len; i++) - os->putChar(os, (int)(*c++)); -} - -/* advancedLengthSimpleStringToken(ss) - * Returns length for printing simple string ss as a token - */ -size_t advancedLengthSimpleStringToken(sexpSimpleString ss) -{ - return simpleStringLength(ss); -} - - -/* VERBATIM */ - -/* advancedPrintVerbatimSimpleString(os,ss) - * Print out simple string ss on output stream os as verbatim string. - * Again, can't fragment string, so max-column is just a suggestion... - */ -void advancedPrintVerbatimSimpleString(sexpOutputStream os, sexpSimpleString ss) -{ - octet * c = simpleStringString(ss); - size_t len = simpleStringLength(ss); - size_t i; - - if (c == NULL) - ErrorMessage(ERROR, "Can't print NULL string verbatim"); - if (os->maxcolumn>0 && os->column > (os->maxcolumn - len)) - os->newLine(os, ADVANCED); - printDecimal(os, (long int)len); - os->putChar(os, ':'); - for (i=0; i<len; i++) os->putChar(os, (int)*c++); -} - -/* advancedLengthSimpleStringVerbatim(ss) - * Returns length for printing simple string ss in verbatim mode - */ -size_t advancedLengthSimpleStringVerbatim(sexpSimpleString ss) -{ - size_t len = simpleStringLength(ss); - size_t i = 1; - while (len > 9L) { i++; len = len / 10; } - return (i+1+len); -} - -/* BASE64 */ - -/* advancedPrintBase64SimpleString(os,ss) - * Prints out simple string ss as a base64 value. - */ -void advancedPrintBase64SimpleString(sexpOutputStream os, sexpSimpleString ss) -{ - octet * c = simpleStringString(ss); - size_t len = simpleStringLength(ss); - size_t i; - - if (c == NULL) - ErrorMessage(ERROR, "Can't print NULL string base 64"); - varPutChar(os,'|'); - changeOutputByteSize(os, 6, ADVANCED); - for (i=0; i<len; i++) - varPutChar(os, (int)(*c++)); - flushOutput(os); - changeOutputByteSize(os, 8, ADVANCED); - varPutChar(os,'|'); -} - -/* HEXADECIMAL */ - -/* advancedPrintHexSimpleString(os,ss) - * Prints out simple string ss as a hexadecimal value. - */ -void advancedPrintHexSimpleString(sexpOutputStream os, sexpSimpleString ss) -{ - octet * c = simpleStringString(ss); - size_t len = simpleStringLength(ss); - size_t i; - - if (c == NULL) - ErrorMessage(ERROR, "Can't print NULL string hexadecimal"); - os->putChar(os, '#'); - changeOutputByteSize(os, 4, ADVANCED); - for (i=0; i<len; i++) - varPutChar(os, (int)(*c++)); - flushOutput(os); - changeOutputByteSize(os, 8, ADVANCED); - os->putChar(os, '#'); -} - -/* advancedLengthSimpleStringHexadecimal(ss) - * Returns length for printing simple string ss in hexadecimal mode - */ -int advancedLengthSimpleStringHexadecimal(sexpSimpleString ss) -{ - size_t len = simpleStringLength(ss); - - return (1+2*len+1); -} - -/* QUOTED STRING */ - -/* canPrintAsQuotedString(ss) - * Returns TRUE if simple string ss can be printed as a quoted string. - * Must have only tokenchars and blanks. - */ -int canPrintAsQuotedString(sexpSimpleString ss) -{ - octet * c = simpleStringString(ss); - size_t len = simpleStringLength(ss); - size_t i; - - if (c == NULL) return FALSE ; -/*@-unsignedcompare@*/ /* XXX len now unsigned size_t. */ - if (len < 0) return FALSE; -/*@=unsignedcompare@*/ - for (i=0; i<len; i++,c++) { - if (!isTokenChar((int)(*c)) && *c != ' ') - return FALSE; - } - return TRUE; -} - -/* advancedPrintQuotedStringSimpleString(os,ss) - * Prints out simple string ss as a quoted string - * This code assumes that all characters are tokenchars and blanks, - * so no escape sequences need to be generated. - * May run over max-column, but there is no fragmentation allowed... - */ -void advancedPrintQuotedStringSimpleString(sexpOutputStream os, sexpSimpleString ss) -{ - octet * c = simpleStringString(ss); - size_t len = simpleStringLength(ss); - size_t i; - - os->putChar(os, '\"'); - for (i=0; i<len; i++) { - if ( os->maxcolumn>0 && os->column >= os->maxcolumn-2 ) { - os->putChar(os, '\\'); - os->putChar(os, '\n'); - os->column = 0; - } - os->putChar(os, *c++); - } - os->putChar(os, '\"'); -} - -/* advancedLengthSimpleStringQuotedString(ss) - * Returns length for printing simple string ss in quoted-string mode - */ -int advancedLengthSimpleStringQuotedString(sexpSimpleString ss) -{ - size_t len = simpleStringLength(ss); - - return (1+len+1); -} - -/* SIMPLE STRING */ - -/* advancedPrintSimpleString(os,ss) - * Prints out simple string ss onto output stream ss - */ -void advancedPrintSimpleString(sexpOutputStream os, sexpSimpleString ss) -{ - size_t len = simpleStringLength(ss); - - if (canPrintAsToken(os, ss)) - advancedPrintTokenSimpleString(os, ss); - else if (canPrintAsQuotedString(ss)) - advancedPrintQuotedStringSimpleString(os, ss); - else if (len <= 4 && os->byteSize == 8) - advancedPrintHexSimpleString(os,ss); - else if (os->byteSize == 8) - advancedPrintBase64SimpleString(os, ss); - else - ErrorMessage(ERROR,"Can't print advanced mode with restricted output character set."); -} - -/* advancedPrintString(os,s) - * Prints out sexp string s onto output stream os - */ -void advancedPrintString(sexpOutputStream os, sexpString s) -{ - sexpSimpleString ph = sexpStringPresentationHint(s); - sexpSimpleString ss = sexpStringString(s); - - if (ph != NULL) { - os->putChar(os, '['); - advancedPrintSimpleString(os, ph); - os->putChar(os, ']'); - } - if (ss == NULL) - ErrorMessage(ERROR, "NULL string can't be printed."); - else - advancedPrintSimpleString(os, ss); -} - -/* advancedLengthSimpleStringBase64(ss) - * Returns length for printing simple string ss as a base64 string - */ -int advancedLengthSimpleStringBase64(sexpSimpleString ss) -{ - return (2+4*((simpleStringLength(ss)+2)/3)); -} - -/* advancedLengthSimpleString(os,ss) - * Returns length of printed image of s - */ -size_t advancedLengthSimpleString(sexpOutputStream os, sexpSimpleString ss) -{ - size_t len = simpleStringLength(ss); - - if (canPrintAsToken(os,ss)) - return advancedLengthSimpleStringToken(ss); - else if (canPrintAsQuotedString(ss)) - return advancedLengthSimpleStringQuotedString(ss); - else if (len <= 4 && os->byteSize == 8) - return advancedLengthSimpleStringHexadecimal(ss); - else if (os->byteSize == 8) - return advancedLengthSimpleStringBase64(ss); - else - return 0; /* an error condition */ -} - -/* advancedLengthString(os,s) - * Returns length of printed image of string s - */ -size_t advancedLengthString(sexpOutputStream os, sexpString s) -{ - sexpSimpleString ph = sexpStringPresentationHint(s); - sexpSimpleString ss = sexpStringString(s); - size_t len = 0; - - if (ph != NULL) - len += 2+advancedLengthSimpleString(os, ph); - if (ss != NULL) - len += advancedLengthSimpleString(os, ss); - return len; -} - -/* advancedLengthList(os,list) - * Returns length of printed image of list given as iterator - */ -size_t advancedLengthList(sexpOutputStream os, sexpList list) -{ - sexpIter iter = sexpListIter(list); - sexpObject object; - size_t len = 1; /* for left paren */ - - while (iter != NULL) { - object = sexpIterObject(iter); - if (object != NULL) { - if (isObjectString(object)) - len += advancedLengthString(os, ((sexpString)object)); - /* else */ - if (isObjectList(object)) - len += advancedLengthList(os, ((sexpList)object)); - len++; /* for space after item */ - } - iter = sexpIterNext(iter); - } - return len+1; /* for final paren */ -} - -/* advancedPrintList(os,list) - * Prints out the list "list" onto output stream os. - * Uses print-length to determine length of the image. If it all fits - * on the current line, then it is printed that way. Otherwise, it is - * written out in "vertical" mode, with items of the list starting in - * the same column on successive lines. - */ -void advancedPrintList(sexpOutputStream os, sexpList list) -{ - int vertical = FALSE; - int firstelement = TRUE; - sexpIter iter; - sexpObject object; - - os->putChar(os,'('); - os->indent++; - if (advancedLengthList(os,list) > os->maxcolumn - os->column) - vertical = TRUE; - iter = sexpListIter(list); - while (iter != NULL) { - object = sexpIterObject(iter); - if (object != NULL) { - if (!firstelement) { - if (vertical) os->newLine(os,ADVANCED); - else os->putChar(os,' '); - } - advancedPrintObject(os, object); - } - iter = sexpIterNext(iter); - firstelement = FALSE; - } - if (os->maxcolumn>0 && os->column>os->maxcolumn-2) - os->newLine(os, ADVANCED); - os->indent--; - os->putChar(os,')'); -} - -/* advancedPrintObject(os,object) - * Prints out object on output stream os - */ -void advancedPrintObject(sexpOutputStream os, sexpObject object) -{ - if (os->maxcolumn>0 && os->column>os->maxcolumn-4) - os->newLine(os, ADVANCED); - if (isObjectString(object)) - advancedPrintString(os, (sexpString)object); - else if (isObjectList(object)) - advancedPrintList(os, (sexpList)object); - else - ErrorMessage(ERROR, "NULL object can't be printed."); -} |