/* * Copyright (c) 1987 Fujitsu * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ /* listing.c -- Routines to generate a Macross assembly listing. Chip Morningstar -- Lucasfilm Ltd. 10-February-1985 */ #include "macrossTypes.h" #include "macrossGlobals.h" #include "emitStuff.h" #include "lexer.h" #include "listing.h" #include "semanticMisc.h" #include #include static char lineBuffer1[LINE_BUFFER_SIZE]; static char lineBuffer2[LINE_BUFFER_SIZE]; int cumulativeLineNumber = 0; static char macroLineBuffer[LINE_BUFFER_SIZE]; static char nextMacroLineBuffer[LINE_BUFFER_SIZE]; static int macroAddress; static int nextMacroAddress; static int macroDepth; static int nextMacroDepth; void outputListing(void) { rewind(saveFileForPass2); rewind(indexFileForPass2); rewind(macroFileForPass2); generateListing(); } void terminateListingFiles(void) { saveLineForListing("\n"); saveIndexForListing(NULL_STATEMENT, cumulativeLineNumber); saveLineForListing("\n"); saveIndexForListing(NULL_STATEMENT, cumulativeLineNumber); } #define advanceSourceFile() \ if (nextSourceAddress == -1) {\ readSourceFileLine(&sourceAddress, &sourceDepth,\ sourceText = lineBuffer1, saveFileForPass2);\ readSourceFileLine(&nextSourceAddress,\ &nextSourceDepth, nextSourceText =\ lineBuffer2, saveFileForPass2);\ sourceLineNumber++;\ } else {\ sourceAddress = nextSourceAddress;\ sourceDepth = nextSourceDepth;\ tempText = sourceText;\ sourceText = nextSourceText;\ nextSourceText = tempText;\ if (tempText == NULL)\ nextSourceText = (sourceText==lineBuffer1) ?\ lineBuffer2 : lineBuffer1;\ readSourceFileLine(&nextSourceAddress,\ &nextSourceDepth, nextSourceText,\ saveFileForPass2);\ sourceLineNumber++;\ } #define advanceIndexFile() {\ indexAddress = nextIndexAddress;\ indexLineNumber = nextIndexLineNumber;\ indexKind = nextIndexKind;\ readIndexFileLine(&nextIndexKind, &nextIndexAddress,\ &nextIndexLineNumber);\ } /* This is the most horrible piece of code I have ever written in my entire life -- cbm */ void generateListing(void) { int sourceAddress; int sourceDepth; char *sourceText = lineBuffer1; int nextSourceAddress; int nextSourceDepth; char *nextSourceText = lineBuffer2; int sourceLineNumber; int indexAddress; int indexLineNumber; statementKindType indexKind; int nextIndexAddress; int nextIndexLineNumber; statementKindType nextIndexKind; bool firstLine; bool alreadyListingMacroExpansion; bool finishingListingMacroExpansion; bool nullMacroLine; int callLineNumber; int targetLineNumber; bool mifEndFlag; int numberOfBytesToList; int numberOfBytesListed; char *tempText; sourceLineNumber = 1; alreadyListingMacroExpansion = FALSE; readSourceFileLine(&sourceAddress, &sourceDepth, sourceText, saveFileForPass2); readSourceFileLine(&nextSourceAddress, &nextSourceDepth, nextSourceText, saveFileForPass2); if (expandMacros) readSourceFileLine(&nextMacroAddress, &nextMacroDepth, nextMacroLineBuffer, macroFileForPass2); readIndexFileLine(&indexKind, &indexAddress, &indexLineNumber); readIndexFileLine(&nextIndexKind, &nextIndexAddress, &nextIndexLineNumber); currentCodeMode = RELOCATABLE_BUFFER; if (indexKind == ORG_STATEMENT || indexKind == ALIGN_STATEMENT || indexKind == REL_STATEMENT) { if (indexKind == ORG_STATEMENT) { currentCodeMode = ABSOLUTE_BUFFER; } advanceIndexFile(); } while (!feof(saveFileForPass2) && !feof(indexFileForPass2)) { mifEndFlag = FALSE; if ((int)indexKind == -1) { advanceIndexFile(); if ((int)indexKind == -1) currentCodeMode = ABSOLUTE_BUFFER; else currentCodeMode = RELOCATABLE_BUFFER; advanceIndexFile(); sourceLineNumber = indexLineNumber; if (nextIndexKind == ORG_STATEMENT || nextIndexKind == ALIGN_STATEMENT || nextIndexKind == REL_STATEMENT) { if (nextIndexKind == ORG_STATEMENT) { currentCodeMode = ABSOLUTE_BUFFER; } else if (nextIndexKind == REL_STATEMENT) { currentCodeMode = RELOCATABLE_BUFFER; } advanceIndexFile(); } } if (indexKind == MACRO_STATEMENT || indexKind == FUNCTION_STATEMENT || indexKind == STRUCT_STATEMENT) { while (sourceLineNumber < indexLineNumber) { printListingLine(0, indexAddress, sourceText, indexKind); advanceSourceFile(); } } else if (!alreadyListingMacroExpansion && isBlockOpener( indexKind)) { while (sourceLineNumber < nextIndexLineNumber) { printListingLine(0, indexAddress, sourceText, indexKind); advanceSourceFile(); } readIndexFileLine(&nextIndexKind, &nextIndexAddress, &nextIndexLineNumber); } while ((indexLineNumber == nextIndexLineNumber && !alreadyListingMacroExpansion && (int)nextIndexKind != -1 && indexKind != ORG_STATEMENT) || (indexKind == NULL_STATEMENT && nextSourceAddress == -1)) { while (nextSourceAddress == -1) { printListingLine(0, indexAddress, sourceText, indexKind); advanceSourceFile(); } readIndexFileLine(&nextIndexKind, &nextIndexAddress, &nextIndexLineNumber); } if (nextIndexLineNumber >= 0) { targetLineNumber = alreadyListingMacroExpansion ? callLineNumber : sourceLineNumber; while (nextIndexLineNumber < targetLineNumber && !isBlockOpener(indexKind)) { readIndexFileLine(&nextIndexKind, &nextIndexAddress, &nextIndexLineNumber); } } while (nextIndexAddress == -1 && !feof(indexFileForPass2)) { readIndexFileLine(&nextIndexKind, &nextIndexAddress, &nextIndexLineNumber); mifEndFlag = TRUE; } numberOfBytesToList = nextIndexAddress - indexAddress; firstLine = TRUE; nullMacroLine = FALSE; while (numberOfBytesToList > 0 || nextSourceAddress == -1 || firstLine) { firstLine = FALSE; if (alreadyListingMacroExpansion) { if (nullMacroLine) { numberOfBytesListed = printListingLine( numberOfBytesToList, indexAddress, NULL, indexKind); nullMacroLine = FALSE; } else { numberOfBytesListed = printMacroLine( numberOfBytesToList, indexAddress, indexKind); } } else if (!feof(indexFileForPass2)) { numberOfBytesListed = printListingLine( numberOfBytesToList, indexAddress, sourceText, indexKind); } numberOfBytesToList -= numberOfBytesListed; indexAddress += numberOfBytesListed; if (nextSourceAddress == -1 || (sourceLineNumber < indexLineNumber && indexKind == INSTRUCTION_STATEMENT && !alreadyListingMacroExpansion)) { advanceSourceFile(); firstLine = TRUE; } else if (!alreadyListingMacroExpansion && nextIndexLineNumber >= 0) { sourceText = NULL; } else if (alreadyListingMacroExpansion && numberOfBytesToList > 0) { nullMacroLine = TRUE; } } while (mifEndFlag && sourceLineNumber+10; spaces--) { putc(' ', listFileOutput); column++; } } else { putc(*text, listFileOutput); column++; } text++; } } void printNTimes(char aChar, int times) { while (times-- > 0) moreText("%c", aChar, 0, 0); } void tabIndent(void) { printNTimes('\t', tabCount); } static char expressionString[LINE_BUFFER_SIZE] = { '\0' }; static char *expressionStringPtr = expressionString; static char expansionString[LINE_BUFFER_SIZE] = { '\0' }; static char *expansionStringPtr = expansionString; static char labelString[LINE_BUFFER_SIZE] = { '\0' }; static char *labelStringPtr = labelString; bool labeledLine(void) { return(labelStringPtr != labelString); } void vaddText(char *buffer, char **bufferPtr, char *format, va_list ap) { vsprintf(*bufferPtr, format, ap); *bufferPtr = buffer + strlen(buffer); } void addText(char *buffer, char **bufferPtr, char *format, ...) { va_list ap; va_start(ap, format); vaddText(buffer, bufferPtr, format, ap); va_end(ap); } void moreTextOptional(char *buffer, char **bufferPtr, char *format, ...) { va_list ap; va_start(ap, format); if (buffer == NULL) vaddText(expansionString, &expansionStringPtr, format, ap); else vaddText(buffer, bufferPtr, format, ap); va_end(ap); } void moreText(char *format, ...) { va_list ap; va_start(ap, format); vaddText(expansionString, &expansionStringPtr, format, ap); va_end(ap); } void moreLabel(char *format, int arg1) { sprintf(labelStringPtr, format, arg1); labelStringPtr = labelString + strlen(labelString); } static addressType savedCurrentLocationCounterValue; static int savedIncludeNestingDepth; void startLine(void) { printNTimes('+', macroCallDepth); savedCurrentLocationCounterValue = currentLocationCounter.value; savedIncludeNestingDepth = includeNestingDepth; } void endLine(void) { if (amListing()) { putw(savedCurrentLocationCounterValue, macroFileForPass2); putw(savedIncludeNestingDepth, macroFileForPass2); fprintf(macroFileForPass2, "%s\n", expansionString); } expansionStringPtr = expansionString; *expansionStringPtr = '\0'; } void flushExpressionString(void) { expressionStringPtr = expressionString; *expressionStringPtr = '\0'; } void expandExpression(char *toBuffer, char **toBufferPtr) { if (toBuffer == NULL) moreText("%s", expressionString, 0, 0); else addText(toBuffer, toBufferPtr, "%s", expressionString, 0, 0); flushExpressionString(); } void expandNum(char *buffer, char **bufferPtr, int n) { moreTextOptional(buffer, bufferPtr, "%d", n, 0, 0); } void flushOperand(int n) { moreText("%s", operandBuffer[n], 0, 0); operandBuffer[n][0] = '\0'; } void expandOperands(int op) { int i; if (op > 0) { flushOperand(0); for (i=1; i