void slug::slugout(int col) { static int numout = 0; if (seen++) ERROR "%s slug #%d seen %d times [%s]\n", type_name(), serialno(), seen, headstr() WARNING; if (type == TM) { char *p; if ((p = strindex(bufptr(dp), (char *)"x X TM "))) p += strlen("x X TM "); // skip junk else ERROR "strange TM [%s]\n", headstr() FATAL; fprintf(stderr, "%d\t", userpn); // page # as prefix for ( ; p < bufptr((this+1)->dp); p++) putc(*p, stderr); } else if (type == COORD) { for (char *p = bufptr(dp); p < bufptr((this+1)->dp) && *p != '\n'; p++) putc(*p, stdout); printf(" # P %d X %d", userpn, hpos + col*offset); return; } else if (type == VBOX) { if (numout++ > 0) // BUG??? might miss something printf("s%d\nf%d\n", size, font); printf("H%d\n", hpos + col*offset); } fwrite(bufptr(dp), sizeof(char), (this+1)->dp - dp, stdout); }
HBufC8* CmsUtils::CreateDEREncodingLC(const CASN1EncBase& aEncoding) { TUint len = aEncoding.LengthDER(); HBufC8* buf = HBufC8::NewMaxLC(len); TUint pos = 0; TPtr8 bufptr(buf->Des()); aEncoding.WriteDERL(bufptr, pos); return buf; }
STATIC void move_buffer(struct buffer FAR *bp, size_t firstbp) { /* connect bp->b_prev and bp->b_next */ b_next(bp)->b_prev = bp->b_prev; b_prev(bp)->b_next = bp->b_next; /* insert bp between firstbp and firstbp->b_prev */ bp->b_prev = bufptr(firstbp)->b_prev; bp->b_next = firstbp; b_next(bp)->b_prev = FP_OFF(bp); b_prev(bp)->b_next = FP_OFF(bp); }
/** This method should only be used by CImapAtomParser. During parsing, a ReAllocL() may be required on the heap buffer that this atom and its descendants' string data descriptor points at. This happens when the heap buffer needs to be expanded. If this causes the heap buffer's address to change, then this atom and its descendants' pointer descriptors need updating. @param The address of the new heap buffer @param The address of the data within the heap buffer before the ReAllocL took place. */ void CImapAtom::FixupL(const HBufC8 *aNewBuffer, const TText8 *aOldBuffer) { // Fixup descriptor pointers CArrayFixFlat<CImapAtom*>* atomStack = new (ELeave) CArrayFixFlat<CImapAtom*>(10); CleanupStack::PushL(atomStack); atomStack->AppendL(this); CImapAtom* currentAtom; while (atomStack->Count() != 0) { // Pop the top atom off of the stack currentAtom = (*atomStack)[atomStack->Count() - 1]; atomStack->ResizeL(atomStack->Count() - 1); // Fix up the current atom if (currentAtom->iAtom.Length()>0) { // Find offset from start of old buffer TInt start=(currentAtom->iAtom.Ptr()-aOldBuffer); // Make new descriptor & assign it TPtrC8 bufptr(aNewBuffer->Ptr()+start,currentAtom->iAtom.Length()); currentAtom->iAtom.Set(bufptr); // Note that we are setting the real iAtom not the copy returned by Atom() } // Add the first sibling to the stack, // subsequent siblings are added when this sibling is visited CImapAtom* siblingAtom = currentAtom->Next(); if (siblingAtom) { atomStack->AppendL(siblingAtom); } // Add child to the stack CImapAtom* childAtom = currentAtom->Child(); if (childAtom) { atomStack->AppendL(childAtom); } } CleanupStack::PopAndDestroy(atomStack); }
char *slug::headstr() { const int HEADLEN = 65; static char buf[2*HEADLEN]; int j = 0; char *s = bufptr(dp); int n = (this+1)->dp - dp; if (n >= HEADLEN) n = HEADLEN; for (int i = 0; i < n; i++) switch (s[i]) { case '\n': case '\t': case '\0': case ' ': break; default: buf[j++] = s[i]; break; } buf[j] = 0; return buf; }
// ---------------------------------------------------------------------------- // CURIContainer::DoInternalizeL // ---------------------------------------------------------------------------- // void CURIContainer::DoInternalizeL(RReadStream& aReadStream) { TInt length(aReadStream.ReadUint32L()); HBufC8* buffer = HBufC8::NewLC(length); TPtr8 bufptr(buffer->Des()); aReadStream.ReadL(bufptr, length); if(SIPHeaderLookup::ConvertToSIPURI()) { if(FindSIP(bufptr)) { iSIPURI = CSIPURI::DecodeL(bufptr); } else { iUri8 = CreateUri8L(bufptr); } } else { iUri8 = CreateUri8L(bufptr); } CleanupStack::PopAndDestroy(buffer); }
// Add the last atom, given a length void CImapIO::AddAtomL(const TInt aLength) { // Note buffer position in an atom TPtrC8 bufptr(iBuffer->Ptr()+iAtomStart,aLength); // Make a new current atom CImapAtom *newAtom=new (ELeave) CImapAtom(); iAtomArray.AppendL(newAtom); // Set pointers in it newAtom->Set(bufptr); // Add it as a child/sibling to the current atom if (iNextIsChild) iAtom->AddChild(newAtom); else iAtom->AddNext(newAtom); // The next item should be a sibling iNextIsChild=EFalse; // Make new current iAtom=newAtom; }
void MorphErode::erodeU8( Image& dst, const Image& src, size_t radius ) const { size_t step = radius * 2 + 1; size_t curbuf; size_t w = src.width(); size_t h = src.height(); SIMD* simd = SIMD::instance(); size_t bstride = Math::pad16( w ); uint8_t** buf; size_t i; IMapScoped<uint8_t> mapdst( dst ); IMapScoped<const uint8_t> mapsrc( src ); /* allocate and fill buffer */ ScopedBuffer<uint8_t,true> bufmem( bstride * step ); ScopedBuffer<uint8_t*,true> bufptr( step ); buf = bufptr.ptr(); buf[ 0 ] = bufmem.ptr(); for( i = 0; i < step; i++ ) { if( i != 0 ) buf[ i ] = buf[ i - 1 ] + bstride; simd->erodeSpanU8( buf[ i ], mapsrc.ptr(), w, radius ); mapsrc++; } /* upper border */ simd->MinValueVertU8( mapdst.ptr(), ( const uint8_t** ) buf, radius + 1, w ); for( i = 1; i < radius; i++ ) { uint8_t* prev = mapdst.ptr(); mapdst++; simd->MinValueU8( mapdst.ptr(), ( const uint8_t* ) prev, ( const uint8_t* ) buf[ radius + 1 + i ], w ); } mapdst++; /* center */ curbuf = 0; i = h - 2 * radius - 1; simd->MinValueVertU8( mapdst.ptr(), ( const uint8_t** ) buf, step, w ); mapdst++; while( i-- ) { simd->erodeSpanU8( buf[ curbuf ], mapsrc.ptr(), w, radius ); curbuf = ( curbuf + 1 ) % step; simd->MinValueVertU8( mapdst.ptr(), ( const uint8_t** ) buf, step, w ); mapdst++; mapsrc++; } /* lower border */ /* reorder buffer */ ScopedBuffer<uint8_t*,true> bufptr2( step ); uint8_t** buf2 = bufptr2.ptr(); for( i = 0; i < step; i++ ) buf2[ i ] = buf[ ( curbuf + i ) % step ]; for( i = 1; i <= radius; i++ ) { simd->MinValueVertU8( mapdst.ptr(), ( const uint8_t** ) ( buf2 + i ), step - i, w ); mapdst++; } }
void CX520AttributeTypeAndValue::ConstructL(TAttributeType aType, const TDesC8& aValue) { // iType is string representation of OID corresponding to the aType. TPtrC ptr; TInt maxlen = 64; // a reasonable default TTagType type = EASN1PrintableString; // the default for all except email, unstructured name and domain component switch(aType) { case ECommonName: ptr.Set(KX520CommonName); maxlen = KX520MaxCNLength; break; case ELocalityName: ptr.Set(KX520LocalityName); maxlen = KX520MaxLLength; break; case EStateOrProvinceName: ptr.Set(KX520StateOrProvinceName); maxlen = KX520MaxSOPLength; break; case EPostalCode: ptr.Set(KX520PostalCode); maxlen = KX520MaxPostalCodeLength; break; case EOrganizationName: ptr.Set(KX520OrganizationName); maxlen = KX520MaxOLength; break; case EOrganizationalUnitName: ptr.Set(KX520OrganizationalUnitName); maxlen = KX520MaxOULength; break; case ETitle: ptr.Set(KX520Title); maxlen = KX520MaxTLength; break; case EDNQualifier: ptr.Set(KX520DNQualifier); maxlen = 64; // no information was found on this one, so set to a safe minimum break; case ECountryName: ptr.Set(KX520CountryName); maxlen = KX520MaxCNLength; break; case EGivenName: ptr.Set(KX520GivenName); maxlen = KX520MaxGNLength; break; case ESurname: ptr.Set(KX520Surname); maxlen = KX520MaxSLength; break; case EInitials: ptr.Set(KX520Initials); maxlen = KX520MaxILength; break; case EGenerationQualifier: ptr.Set(KX520GenerationQualifier); maxlen = KX520MaxGQLength; break; case EPKCS9EmailAddress: ptr.Set(KPKCS9EmailAddress); maxlen = KPKCS9MaxEmailAddressLength; type = EASN1IA5String; break; case ESerialNumber: ptr.Set(KX520SerialNumber); maxlen = KX520MaxSNLength; break; case ERFC2247DomainComponent: ptr.Set(KRFC2247DomainComponent); maxlen = KRFC2247MaxDomainComponentLength; type = EASN1IA5String; break; case ERFC2256Street: ptr.Set(KRFC2256Street); maxlen = KRFC2256StreetLength; break; case EPKCS9UnstructuredName: { ptr.Set(KPKCS9UnstructuredName); maxlen = KPKCS9MaxUnstructuredNameLength; // Determine the encoded value. It could be a IA5String or a UTF8String TASN1DecGeneric decoderGeneric(aValue); decoderGeneric.InitL(); type = decoderGeneric.Tag(); break; } case EX520Description: { ptr.Set(KX520Description); maxlen = KX520MaxDescriptionLength; break; } default: User::Leave(KErrArgument); } // Verify if the passed length is within limits if(aValue.Length() > maxlen) User::Leave(KErrArgument); // Allocate OID string for iType iType = ptr.AllocL(); // iValue must be stored in ASN.1-encoded form CASN1EncOctetString* enc = CASN1EncOctetString::NewLC(aValue); enc->SetTag(type, EUniversal); TUint len = enc->LengthDER(); HBufC8* buf = HBufC8::NewMaxLC(len); TUint pos = 0; TPtr8 bufptr(buf->Des()); enc->WriteDERL(bufptr, pos); iValue = bufptr.AllocL(); CleanupStack::PopAndDestroy(2); }
STATIC struct buffer FAR *searchblock(ULONG blkno, COUNT dsk) { int fat_count = 0; struct buffer FAR *bp; size_t lastNonFat = 0; size_t uncacheBuf = 0; seg bufseg = FP_SEG(firstbuf); size_t firstbp = FP_OFF(firstbuf); #ifdef DISPLAY_GETBLOCK printf("[searchblock %d, blk %ld, buf ", dsk, blkno); #endif /* Search through buffers to see if the required block */ /* is already in a buffer */ bp = MK_FP(bufseg, firstbp); do { if ((bp->b_blkno == blkno) && (bp->b_flag & BFR_VALID) && (bp->b_unit == dsk)) { /* found it -- rearrange LRU links */ #ifdef DISPLAY_GETBLOCK printf("HIT %04x:%04x]\n", FP_SEG(bp), FP_OFF(bp)); #endif bp->b_flag &= ~BFR_UNCACHE; /* reset uncache attribute */ if (FP_OFF(bp) != firstbp) { *(UWORD *)&firstbuf = FP_OFF(bp); move_buffer(bp, firstbp); } return bp; } if (bp->b_flag & BFR_UNCACHE) uncacheBuf = FP_OFF(bp); if (bp->b_flag & BFR_FAT) fat_count++; else lastNonFat = FP_OFF(bp); bp = b_next(bp); } while (FP_OFF(bp) != firstbp); /* now take either the last buffer in chain (not used recently) or, if we are low on FAT buffers, the last non FAT buffer */ if (uncacheBuf) { bp = bufptr(uncacheBuf); } else if (bp->b_flag & BFR_FAT && fat_count < 3 && lastNonFat) { bp = bufptr(lastNonFat); } else { bp = b_prev(bufptr(firstbp)); } bp->b_flag |= BFR_UNCACHE; /* set uncache attribute */ #ifdef DISPLAY_GETBLOCK printf("MISS, replace %04x:%04x]\n", FP_SEG(bp), FP_OFF(bp)); #endif if (FP_OFF(bp) != firstbp) /* move to front */ { move_buffer(bp, firstbp); *(UWORD *)&firstbuf = FP_OFF(bp); } return bp; }
// Process the received buffer, creating atoms as we go void CImapIO::ProcessBufferL() { // Process the buffer TChar byte; DBG((LogText(_L8("CImapIO::ProcessBuffer(iParserState=%d, Length=%d)"),iParserState,iReceive.Length()))); for(TInt pos=0;pos<iReceive.Length();pos++) { // Note that we've processed stuff iBytesRead++; // Byte to process byte=iReceive[pos]; switch(iParserState) { case EIOStateAtomWait: switch(byte) { case '(': case '[': case '<': { // Make a new current atom CImapAtom *newAtom=new (ELeave) CImapAtom(); iAtomArray.AppendL(newAtom); // Add it as a sibling to the current atom if (iNextIsChild) iAtom->AddChild(newAtom); else iAtom->AddNext(newAtom); // The next item should be a child iNextIsChild=ETrue; // Push current atom onto atom stack, make new current iAtom=newAtom; PushL(iAtom); // Store the open bracket in the buffer, so we can tell what it is TPtrC8 bufptr(iBuffer->Ptr()+iBuffer->Length(),1); BufferAppendL(byte); iAtom->Set(bufptr); break; } case ')': case ']': // End of this nesting level: pop last atom off stack and // make it the new current one iAtom=PopL(); // Any new atoms will be siblings, not children iNextIsChild=EFalse; break; case '{': // Start of a literal length iLiteralLength=0; iParserState=EIOStateLiteralLength; break; case ' ': // Whitespace. Ignore! This state only happens with whitespace // after a close )] or a endquote " break; case '\r': // Newline after a close )] or endquote " iParserState=EIOStateWaitLF; break; case '\"': // Quotes: we don't keep them, so the atom starts at the next // character. iAtomStart=iBuffer->Length(); iParserState=EIOStateInAtom; iParserQuoted=ETrue; iGotEscape=EFalse; break; default: // Start new atom in buffer iAtomStart=iBuffer->Length(); BufferAppendL(byte); iParserState=EIOStateInAtom; iParserQuoted=EFalse; break; } break; case EIOStateInAtom: if (iParserQuoted) { // Look for another quote if (byte=='\"') { // Just had an escape character? if (iGotEscape) { // Add the character BufferAppendL(byte); iGotEscape=EFalse; } else { // It's the terminator: Add the atom, minus the quotes AddAtomL(); iParserState=EIOStateAtomWait; } } // fix for INC51597 and DEF053082:if a " has been missed out by the server, this will end the atom at a \r else if(!iGotEscape && byte == '\r') { AddAtomL(); iParserState = EIOStateWaitLF; } else { // Escape character? if (!iGotEscape && byte=='\\') { // Got one iGotEscape=ETrue; } else { // Add to buffer BufferAppendL(byte); iGotEscape=EFalse; } } } else { if (byte==' ' || byte=='\r') { AddAtomL(); // Either go back to looking for an atom, or a LF iParserState=(byte=='\r')?EIOStateWaitLF:EIOStateAtomWait; } else if (byte=='(' || byte=='[') { // Add this atom AddAtomL(); // Make a new current atom CImapAtom *newAtom=new (ELeave) CImapAtom(); iAtomArray.AppendL(newAtom); // Add it as a sibling to the current atom if (iNextIsChild) iAtom->AddChild(newAtom); else iAtom->AddNext(newAtom); // The next item should be a child iNextIsChild=ETrue; // Push current atom onto atom stack, make new current iAtom=newAtom; PushL(iAtom); // Store the open bracket in the buffer, so we can tell what it is TPtrC8 bufptr(iBuffer->Ptr()+iBuffer->Length(),1); BufferAppendL(byte); iAtom->Set(bufptr); iParserState=EIOStateAtomWait; } else if (byte==')' || byte==']' || byte == '>') { // Although these bytes usually indicate the end of an atom, // they can also legitimately appear in a text field. // If this is the end of an atom, then it must be a child or // sibling atom in which case there will be an entry on the atom // stack. If there is no entry on the atom stack, then this must // be a text field so just add the byte to the buffer. if (iAtomStack.Count() > 0) { // Add this atom AddAtomL(); // End of this nesting level: pop last atom off stack and // make it the new current one iAtom=PopL(); // Any new atoms will be siblings, not children iNextIsChild=EFalse; iParserState=EIOStateAtomWait; } else { BufferAppendL(byte); } } else { // Add to buffer BufferAppendL(byte); } } break; case EIOStateWaitLF: // After LF, this is end of line, finish! if (byte=='\n') { // Remove everything from the buffer, we've finished iReceive.Delete(0,pos+1); // Reset bytes read count & complete iBytesRead=0; // Complete with KErrFoundEOL DBG((LogText(_L8("CImapIO::ProcessBuffer: Complete in EIOStateWaitLF")))); Complete(KErrFoundEOL); return; } break; case EIOStateLiteralLength: // Digit? if (byte.IsDigit()) { // Add it to the total iLiteralLength=(iLiteralLength*10)+(byte-(TChar)'0'); if (iLiteralLength <0) User::Leave(KErrCorrupt); } else if (byte=='}') { // Need to skip CR, LF iLiteralSkip=2; iParserState=EIOStateLiteralSkip; // Add the atom (with the length we know, but no data) to the // structure now, so that the partial structure can be parsed. iAtomStart=iBuffer->Length(); AddAtomL(iLiteralLength); } break; case EIOStateLiteralSkip: // Skipping... if (--iLiteralSkip==0) { // Is literal 0 bytes long? if (iLiteralLength==0) { // Nothing to follow iParserState=EIOStateAtomWait; } else { // Non-empty literal: go into fetch state iParserState=EIOStateLiteralFetch; } } break; case EIOStateLiteralFetch: // Fetching TInt fetchLength(0); if(KReceiveBuffer<iLiteralLength) { fetchLength = KReceiveBuffer; } else { fetchLength = iLiteralLength; } if(fetchLength > iReceive.Length()-pos) { fetchLength = iReceive.Length()-pos; } // need to extend buffer ? DBG((LogText(_L8(">>> CImapIO::ProcessBufferL(1):buflen=%d:buffsize=%d:litlen=%d:fetchlen=%d"), iBuffer->Length(),iBufferSize, iLiteralLength,fetchLength))); if (iBuffer->Length() + iLiteralLength > iBufferSize) { HBufC8 *oldbuffer=iBuffer; const TText8 *oldbufptr=iBuffer->Ptr(); // Extend by extra amount + round up by KIOBufferGranularity iBufferSize += iLiteralLength; iBufferSize += (KIOBufferGranularity - (iBufferSize % KIOBufferGranularity)); iBuffer=iBuffer->ReAllocL(iBufferSize); // Buffer moved? if (iBuffer!=oldbuffer) { // Fixup buffer tree pointers iRootAtom->FixupL(iBuffer,oldbufptr); } DBG((LogText(_L8(">>> CImapIO::ProcessBufferL(2):buflen=%d:buffsize=%d:litlen=%d:fetchlen=%d"), iBuffer->Length(),iBufferSize, iLiteralLength,fetchLength))); } iBuffer->Des().Append(iReceive.Mid(pos,fetchLength)); // adjust loop to account for data copy pos+=fetchLength-1; iLiteralLength-=fetchLength; DBG((LogText(_L8(">>> CImapIO::ProcessBufferL(3):buflen=%d:buffsize=%d:litlen=%d:fetchlen=%d"), iBuffer->Length(),iBufferSize, iLiteralLength,fetchLength))); if (iLiteralLength==0) { // Atom is already saved (we add literal atoms before they // are stored) iParserState=EIOStateAtomWait; } break; } } iReceive.Zero(); // At start of line, or if we're not doing a partial return, we need to // queue another read here if (iBytesRead==0 || !iReturnPartialLine) { // We've processed this buffer: queue a read. We only complete (above) // when we've had a whole reply, including terminating CRLF. DBG((LogText(_L8("CImapIO::ProcessBufferL(): queuing read, iBytesRead=%d, iReturnPartialLine is %d"), iBytesRead, iReturnPartialLine))); QueueRead(); } else { // Have we got 'enough' of the partial line? if (iBytesRead<iBytesToRead) { // Not enough yet: queue another partial read, for the remainder iBytesToRead-=iBytesRead; QueueRead(); } else { // Partial line parsed: return success (client will requeue) DBG((LogText(_L8("CImapIO::ProcessBuffer: Complete on partial line")))); Complete(KErrNone); } } }
static void morphTemplate( Image& dst, const Image& src, size_t radius, void ( SIMD::*hfunc )( TYPE*, const TYPE*, size_t, size_t ) const, void ( SIMD::*hfuncborder )( TYPE*, const TYPE*, const TYPE*, size_t ) const, void ( SIMD::*vfunc )( TYPE*, const TYPE**, size_t, size_t ) const ) { SIMD* simd = SIMD::instance(); const size_t boxsize = radius * 2 + 1; size_t curbuf; size_t w = src.width(); size_t h = src.height(); size_t bstride = Math::pad16( sizeof( TYPE ) * w ) / sizeof( TYPE ); //FIXME: does this always work - it should TYPE** buf; size_t i; IMapScoped<TYPE> mapdst( dst ); IMapScoped<const TYPE> mapsrc( src ); /* allocate and fill buffer */ ScopedBuffer<TYPE,true> bufmem( bstride * boxsize ); ScopedBuffer<TYPE*,true> bufptr( boxsize ); buf = bufptr.ptr(); buf[ 0 ] = bufmem.ptr(); for( i = 0; i < boxsize; i++ ) { if( i != 0 ) buf[ i ] = buf[ i - 1 ] + bstride; ( simd->*hfunc )( buf[ i ], mapsrc.ptr(), w, radius ); mapsrc++; } /* upper border */ ( simd->*vfunc )( mapdst.ptr(), ( const TYPE** ) buf, radius + 1, w ); for( i = 1; i < radius; i++ ) { TYPE* prev = mapdst.ptr(); mapdst++; ( simd->*hfuncborder )( mapdst.ptr(), ( const TYPE* ) prev, ( const TYPE* ) buf[ radius + 1 + i ], w ); } mapdst++; /* center */ curbuf = 0; i = h - 2 * radius - 1; ( simd->*vfunc )( mapdst.ptr(), ( const TYPE** ) buf, boxsize, w ); mapdst++; while( i-- ) { ( simd->*hfunc )( buf[ curbuf ], mapsrc.ptr(), w, radius ); curbuf = ( curbuf + 1 ) % boxsize; ( simd->*vfunc )( mapdst.ptr(), ( const TYPE** ) buf, boxsize, w ); mapdst++; mapsrc++; } /* lower border */ /* reorder buffer */ ScopedBuffer<TYPE*,true> bufptr2( boxsize ); TYPE** buf2 = bufptr2.ptr(); for( i = 0; i < boxsize; i++ ) buf2[ i ] = buf[ ( curbuf + i ) % boxsize ]; for( i = 1; i <= radius; i++ ) { ( simd->*vfunc )( mapdst.ptr(), ( const TYPE** ) ( buf2 + i ), boxsize - i, w ); mapdst++; } }
slug getslug(FILE *fp) { if (inbuf == NULL) { if ((inbuf = (char *)malloc(ninbuf = DELTABUF)) == NULL) ERROR "no room for %ld character input buffer\n", ninbuf FATAL; inbp = inbuf; } if (wherebuf() > (ssize_t)(ninbuf-5000)) { // this is still flaky -- lines can be very long int where = wherebuf(); // where we were if ((inbuf = (char *)realloc(inbuf, ninbuf += DELTABUF)) == NULL) ERROR "no room for %ld character input buffer\n", ninbuf FATAL; ERROR "grew input buffer to %ld characters\n", ninbuf WARNING; inbp = inbuf + where; // same offset in new array } static int baseV = 0; // first V command of preceding slug static int curV = 0, curH = 0; static int font = 0, size = 0; static int baseadj = 0; static int ncol = 1, offset = 0; // multi-column stuff char str[1000], str2[1000], buf[3000], *p; int firstV = 0, firstH = 0; int maxV = curV; int ocurV = curV, mxv = 0, dx = 0; int sawD = 0; // > 0 if have seen D... slug ret; ret.serialnum = serialnum++; ret.type = VBOX; // use the same as last by default ret.dv = curV - baseV; ret.hpos = curH; ret.base = ret.parm = ret.parm2 = ret.seen = 0; ret.font = font; ret.size = size; ret.dp = wherebuf(); ret.ncol = ncol; ret.offset = offset; ret.linenum = linenum; // might be low for (;;) { int c, m, n; // for input values int sign; // hoisted from case 'h' below switch (c = getc(fp)) { case EOF: ret.type = EOF; ret.dv = 0; if (baseadj) printf("# adjusted %d bases\n", baseadj); printf("# %d characters, %d lines\n", wherebuf(), linenum); return ret; case 'V': fscanf(fp, "%d", &n); if (firstV++ == 0) { ret.dv = n - baseV; baseV = n; } else { sprintf(buf, "v%d", n - curV); adds(buf); } curV = n; maxV = max(maxV, curV); break; case 'H': // absolute H motion fscanf(fp, "%d", &n); if (firstH++ == 0) { ret.hpos = n; } else { sprintf(buf, "h%d", n - curH); adds(buf); } curH = n; break; case 'h': // relative H motion addc(c); sign = 1; if ((c = getc(fp)) == '-') { addc(c); sign = -1; c = getc(fp); } for (n = 0; isdigit(c); c = getc(fp)) { addc(c); n = 10 * n + c - '0'; } curH += n * sign; ungetc(c, fp); break; case 'x': // device control: x ... addc(c); fgets(buf, sizeof(buf), fp); linenum++; adds(buf); if (buf[0] == ' ' && buf[1] == 'X') { // x X ... if (2 != sscanf(buf+2, "%s %d", str, &n)) n = 0; if (eq(str, "SP")) { // X SP n ret.type = SP; // paddable SPace ret.dv = n; // of height n } else if (eq(str, "BS")) { ret.type = BS; // Breakable Stream ret.parm = n; // >=n VBOXES on a page } else if (eq(str, "BF")) { ret.type = BF; // Breakable Float ret.parm = ret.parm2 = n; // n = pref center (as UF) } else if (eq(str, "US")) { ret.type = US; // Unbreakable Stream ret.parm = n; } else if (eq(str, "UF")) { ret.type = UF; // Unbreakable Float ret.parm = ret.parm2 = n; // n = preferred center // to select several, // use several UF lines } else if (eq(str, "PT")) { ret.type = PT; // Page Title ret.parm = n; } else if (eq(str, "BT")) { ret.type = BT; // Bottom Title ret.parm = n; } else if (eq(str, "END")) { ret.type = END; ret.parm = n; } else if (eq(str, "TM")) { ret.type = TM; // Terminal Message ret.dv = 0; } else if (eq(str, "COORD")) { ret.type = COORD;// page COORDinates ret.dv = 0; } else if (eq(str, "NE")) { ret.type = NE; // NEed to break page ret.dv = n; // if <n units left } else if (eq(str, "MC")) { ret.type = MC; // Multiple Columns sscanf(buf+2, "%s %d %d", str, &ncol, &offset); ret.ncol = ncol; ret.offset = offset; } else if (eq(str, "CMD")) { ret.type = CMD; // CoMmaNd sscanf(buf+2, "%s %s", str2, str); if (eq(str, "FC")) // Freeze 2-Col ret.parm = FC; else if (eq(str, "FL")) // FLush ret.parm = FL; else if (eq(str, "BP")) // Break Page ret.parm = BP; else ERROR "unknown command %s\n", str WARNING; } else if (eq(str, "PARM")) { ret.type = PARM;// PARaMeter sscanf(buf+2, "%s %s %d", str2, str, &ret.parm2); if (eq(str, "NP")) // New Page ret.parm = NP; else if (eq(str, "FO")) // FOoter ret.parm = FO; else if (eq(str, "PL")) // Page Length ret.parm = PL; else if (eq(str, "MF")) // MinFull ret.parm = MF; else if (eq(str, "CT")) // ColTol ret.parm = CT; else if (eq(str, "WARN")) //WARNings? ret.parm = WARN; else if (eq(str, "DBG"))// DeBuG ret.parm = DBG; else ERROR "unknown parameter %s\n", str WARNING; } else break; // out of switch if (firstV > 0) ERROR "weird x X %s in mid-VBOX\n", str WARNING; return ret; } break; case 'n': // end of line fscanf(fp, "%d %d", &n, &m); ret.ht = n; ret.base = m; getc(fp); // newline linenum++; sprintf(buf, "n%d %d\n", ret.ht, ret.base); adds(buf); if (!firstV++) baseV = curV; // older incarnations of this program used ret.base // in complicated and unreliable ways; // example: if ret.ht + ret.base < ret.dv, ret.base = 0 // this was meant to avoid double-counting the space // around displayed equations; it didn't work // Now, we believe ret.base = 0, otherwise we give it // a value we have computed. if (ret.base == 0 && sawD == 0) return ret; // don't fiddle 0-bases if (ret.base != maxV - baseV) { ret.base = maxV - baseV; baseadj++; } if (ret.type != VBOX) ERROR "%s slug (type %d) has base = %d\n", ret.type_name(), ret.type, ret.base WARNING; return ret; case 'p': // new page fscanf(fp, "%d", &n); ret.type = PAGE; curV = baseV = ret.dv = 0; ret.parm = n; // just in case someone needs it return ret; case 's': // size change snnn fscanf(fp, "%d", &size); sprintf(buf, "s%d\n", size); adds(buf); break; case 'f': // font fnnn fscanf(fp, "%d", &font); sprintf(buf, "f%d\n", font); adds(buf); break; case '\n': linenum++; /* fall through */ case ' ': addc(c); break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': // two motion digits plus a character addc(c); n = c - '0'; addc(c = getc(fp)); curH += 10 * n + c - '0'; addc(getc(fp)); if (!firstV++) baseV = curV; break; case 'c': // single ascii character addc(c); addc(getc(fp)); if (!firstV++) baseV = curV; break; case 'C': // Cxyz\n case 'N': // Nnnn\n addc(c); while ((c = getc(fp)) != ' ' && c != '\n') addc(c); addc(c); if (!firstV++) baseV = curV; linenum++; break; case 'D': // draw function: D.*\n sawD++; p = bufptr(wherebuf()); // where does the D start addc(c); while ((c = getc(fp)) != '\n') addc(c); addc(c); if (!firstV++) baseV = curV; ocurV = curV, mxv = 0, dx = 0; curV += getDy(p, &dx, &mxv); // figure out how big it is maxV = max(max(maxV, curV), ocurV+mxv); curH += dx; linenum++; break; case 'v': // relative vertical vnnn addc(c); if (!firstV++) baseV = curV; sign = 1; if ((c = getc(fp)) == '-') { addc(c); sign = -1; c = getc(fp); } for (n = 0; isdigit(c); c = getc(fp)) { addc(c); n = 10 * n + c - '0'; } ungetc(c, fp); curV += n * sign; maxV = max(maxV, curV); addc('\n'); break; case 'w': // word space addc(c); break; case '#': // comment addc(c); while ((c = getc(fp)) != '\n') addc(c); addc('\n'); linenum++; break; default: ERROR "unknown input character %o %c (%50.50s)\n", c, c, bufptr(wherebuf()-50) WARNING; break; } } }