/************************************************************************************ * txtBuffer.c * * synopsis: Code for making and updating entries in the text (ASCII) buffers. * See the comments in txtBuffer.h for a more complete description. * * in this file: txtAddString, padBuffer, txtNewBufferEntry, txtAddBufferEntry, * txtMarkBufferRead. * * Caution: strlen does not include the terminating NULL character. * * Revision history: * 18-Apr-2000: Changed name from dspXxxx to txtXxxx. * 09-May-2000: First CVS release (1.0) * * Written by: Tom Meyer, Iowa State University, meyer@iastate.edu ************************************************************************************/ #include #include #include #include #include #include "memoryPartitions.h" #include "resources.h" #include "txtBuffer.h" #pragma CODE_SECTION(txtAddString, "xcode"); #pragma CODE_SECTION(padBuffer, "xcode"); #pragma CODE_SECTION(txtNewBufferEntry, "xcode"); #pragma CODE_SECTION(txtAddBufferEntry, "xcode"); #pragma CODE_SECTION(txtMarkBufferRead, "xcode"); /************************************************************************************ * txtAddString: Copy a string into a text buffer, checking for wraparound. * * *buffer: a pointer to the destination buffer (errBuffer, infoBuffer, or * diagBuffer) [INPUT/OUTPUT] * *string: s a pointer to the string to be copied. [INPUT] * * modifications/bugs: * - Swap the ordering of the bytes within a word for the Rev. E SDSPs; for * some bizarre reason sprintf on these DSPs reverses the order. 07.08.03 dpsf ************************************************************************************/ #if ( (defined(I_AM_MASTER_DSP))||((defined(REV_B))||(defined(REV_C))) ) INT32 txtAddString(struct TXTBUFFER *buffer, const char* string) { #elif (defined(REV_E)) INT32 txtAddString(struct TXTBUFFER *buffer, char* string) { UINT8 j; #endif INT32 buffToEnd; /* Bytes to end of buffer */ INT32 i; buffToEnd = buffer->dataEnd -buffer->writeIndx +1; /* wraparound? */ if ((strlen(string)+1)>buffToEnd) { /* String longer than space left in buffer? */ for (i=0; idata[(buffer->writeIndx)++]=string[i]; } if (OVERWRITE == buffer->overwrite) { /* Wrap around */ buffer->writeIndx=0; for (i=buffToEnd; idata[buffer->writeIndx++]=string[i]; } buffer->readIndx = buffer->writeIndx; buffer->wrap = WRAPAROUND; } else { /* Put \0 at end of full linear buffer */ buffer->data[buffer->dataEnd]='\0'; } } else if ((strlen(string)+1) == buffToEnd) { strcat(buffer->data, string); buffer->data[buffer->dataEnd] = SPC; /* Pad with blanks */ buffer->data[0] = '\000'; /* will be overwritten if another string is appended to entry*/ buffer->writeIndx = 1; } else { if (0==buffer->writeIndx) { strcpy(buffer->data, string); } else { strcpy(&buffer->data[buffer->writeIndx], string); } buffer->writeIndx+= strlen(string); } if ((buffer->wrap) && (buffer->writeIndx > buffer->readIndx)) { buffer->readIndx= buffer->writeIndx; } return(0); } /************************************************************************************ * padBuffer: Pad the buffer with spaces up to a word boundary. * * *buffer: a pointer to a text buffer. [INPUT/OUTPUT] ************************************************************************************/ INT32 padBuffer(struct TXTBUFFER *buffer) { INT32 bytesToPad, i; /* Bytes to next word boundary, index */ bytesToPad= 4 -((buffer->writeIndx) & 3); if (bytesToPad < 4) { for (i=0; idata[buffer->writeIndx++]= SPC; //i=0 overwrote the string-ending zero, so replace it. buffer->data[buffer->writeIndx]= 0; //dpsf: redo if ((buffer->writeIndx > buffer->dataEnd)&&buffer->overwrite) { buffer->writeIndx = 0; buffer->wrap = WRAPAROUND; } if (buffer->wrap && (buffer->writeIndx > buffer->readIndx)) { buffer->readIndx = buffer->writeIndx; } } return(0); } /************************************************************************************ * txtNewBufferEntry: Add a new entry to the designated buffer, prepending a marker * string [MDSP: file, line]::\n to signify that this is the * start of a new entry. * INPUT: * * *buffer: a pointer to the designated buffer (e.g. errBuffer, infoBuffer, or * diagBuffer). * * *srcFile: a pointer to a string containing the name of the source file * * line: an integer giving the line number in the source file. * * *txtMessage: a pointer to a string created by the user with a call to sprintf, * which may contain any text the user feels appropriate, such as an * error number, varable values, or register settings. * * Return value: none (may become an error return in the future). * * modifications/bugs * - Added an ID to the slave DSPs' init strings, using getSlvID. 05.05.02 dpsf * - Mark the buffer for processing in the status register (to speed * up the main polling loop; it does not have to make a call). 14.10.02 dpsf * - Removed the STX character; new entries will be identified by the MDSP/SDSP (#) * in the prefix string. The prefix string is now formatted to include the * file/line identifying information. 13.08.03 dpsf ************************************************************************************/ INT32 txtNewBufferEntry(struct TXTBUFFER *buffer, char* srcFile, INT32 line, char* txtMessage) { char str[16]; #ifdef I_AM_SLAVE_DSP UINT32 slvDspID; #endif //txtAddString(buffer, startString); #ifdef I_AM_MASTER_DSP txtAddString(buffer, "[MDSP: "); #endif #ifdef I_AM_SLAVE_DSP slvDspID= getSlvID(); sprintf(str,"[SDSP %d: ",slvDspID); txtAddString(buffer, str); #endif txtAddString(buffer, srcFile); sprintf(str, ", %5d]::\n", line); txtAddString(buffer, str); txtAddString(buffer, txtMessage); txtAddString(buffer, "\n"); padBuffer(buffer); buffer->state= BUFFER_OCCUPIED; setTxtBuffProc(buffer->id); return(0); } /************************************************************************************ * txtAddBufferEntry: This function appends an entry to the designated buffer. It * functions like txtNewBufferEntry except that it does not * place a MDSP/SDSP in the prefix string. * INPUT: * * *buffer: a pointer to the designated buffer (e.g. errBuffer, infoBuffer, or * diagBuffer). * * *srcFile: a pointer to a string containing the name of the source file * * line: an integer giving the line number in the source file. * * *txtMessage: a pointer to a string created by the user with a call to sprintf, * which may contain any text the user feels appropriate, such as an * error number, varable values, or register settings. * * Return value: none (may become an error return in the future). * * modifications/bugs * - The AddBufferEntry prefix string resembles the NBE one, except it lacks the * MDSP/SDSP identifier & the special marker (for host search) "::\n" at the * end. Buffer management has been simplified & moved inside txtAddString: if a * buffer is a ring buffer over-writing is allowed via the wrap & no over-writing * is permitted in linear buffers. All buffers are split into two sub-buffers * which toggle to prevent any text being lost by the FROZEN buglet: the rest of * the code has no knowledge of this state so it dumps more text into the buffer, * and upon completion of the read the pointers are reset. The toggling * sub-buffers will prevent any text being lost except for if a buffer overflows; * this will also be invisible to the rest of the program. tbd xx.08.03 dpsf ************************************************************************************/ INT32 txtAddBufferEntry(struct TXTBUFFER *buffer, char* srcFile, INT32 line, char* txtMessage) { char str[16]; txtAddString(buffer, "["); txtAddString(buffer, srcFile); sprintf(str, ", %5d]\n", line); txtAddString(buffer, str); txtAddString(buffer, txtMessage); txtAddString(buffer, "\n"); padBuffer(buffer); return(0); } #ifdef COMMENTED //dpsf put into txtAddString char lineString[8]; /* String to hold line number after conversion to ASCII */ INT32 unwrittenLength; /* Bytes not yet copied to buffer */ INT32 buffSize; /* Total bytes in buffer */ register char* stringStart; /* Pointer to source string */ sprintf(lineString,"%5d", line); unwrittenLength = strlen(file) + strlen(lineString) + strlen(txtMessage); /* Buffer size is really dataEnd+1 but we subtract one byte to account for the start-of-entry character */ buffSize = buffer->dataEnd; /* If the length to be written is larger than the buffer, we keep only the first or last bufferfull, depending on the overwrite parameter. */ if (unwrittenLength>buffSize) { /* OVERFLOW */ unwrittenLength = buffSize; if (OVERWRITE == buffer->overwrite) { /* OVERWRITE */ /* If start is in txtMessage... */ if (strlen(txtMessage)>buffSize) { stringStart = txtMessage + strlen(txtMessage)-buffSize; txtAddString(buffer,stringStart); } /* If start is in lineString... */ else if ((strlen(txtMessage)+strlen(lineString))>buffSize) { /* ...count back from end of buffer to find where to start writing. */ stringStart = lineString + (strlen(txtMessage)+ strlen(lineString)-buffSize); txtAddString(buffer,stringStart); stringStart = txtMessage; txtAddString(buffer,stringStart); } /* Start is in file */ else { stringStart = file + (strlen(file)+strlen(lineString)+ strlen(txtMessage)- buffSize); txtAddString(buffer,stringStart); stringStart = lineString; txtAddString(buffer,stringStart); stringStart = txtMessage; txtAddString(buffer,stringStart); } } /* OVERWRITE */ else { /* NOOVERWRITE */ txtAddString(buffer, file); txtAddString(buffer, lineString); txtAddString(buffer, txtMessage); } buffer->overflow = TXT_BFR_OVERFLOW; } /* OVERFLOW */ else { /*NO OVERFLOW */ txtAddString(buffer, file); txtAddString(buffer, lineString); txtAddString(buffer, txtMessage); if (buffer->writeIndx < buffer->dataEnd) { buffer->overflow = TXT_BFR_NOOVERFLOW; } else { buffer->overflow = TXT_BFR_OVERFLOW; } } padBuffer(buffer); return(0); } #endif /************************************************************************************ * txtMarkBufferRead: Mark the designated buffer as being read. It sets the * read and write pointers to the same value. If it is a * linear buffer, they are set to the start of the buffer. For a circular buffer, * readIndx is set equal to the current writeIndx. ************************************************************************************/ INT32 txtMarkBufferRead(struct TXTBUFFER *buffer) { if (RINGBUFF==buffer->mode) { buffer->readIndx= buffer->writeIndx; } else { buffer->readIndx= 0; buffer->writeIndx= 0; } buffer->overflow= TXT_BFR_NOOVERFLOW; buffer->wrap= NOWRAPAROUND; buffer->state= BUFFER_EMPTY; return(0); }