//------------------------------------------------------------------------- // Sort the line table. void SortLines(int Type) { int i, j; int (*Compare)(const void *, const void *); // Sort the entries based upon the architecture if (Type == SORT_YUL) Compare = CompareLineAGC; else if (Type == SORT_LEMAP) Compare = CompareLineAGS; else if (Type == SORT_ASM) Compare = CompareLineASM; else { printf("Invalid architecture type given.\n"); return; } qsort(LineTable, LineTableSize, sizeof(SymbolLine_t), Compare); // Remove duplicates from the line table. I think this is a completely // normal situation because multiple passes are made throug the code // when compiling. printf("Removing the duplicated lines... "); for (i = 1; i < LineTableSize;) { if (!Compare((const void *) &LineTable[i - 1].CodeAddress, (const void *) &LineTable[i].CodeAddress)) { AddressPrint(&LineTable[i - 1].CodeAddress); for (j = i; j < LineTableSize; j++) LineTable[j - 1] = LineTable[j]; LineTableSize--; } else i++; } printf("\n"); }
//------------------------------------------------------------------------ // Print the symbol table. void PrintSymbolsToFile(FILE *fp) { int i; char *status = ""; fprintf(fp, "Symbol Table\n------------\n"); if (Block1) { fprintf(fp, "(Legend: I=Invalid, C=Constant, E=Erasable, F=Fixed, ?=Error)\n\n"); } if (HtmlOut != NULL) { fprintf(HtmlOut, "</pre>\n\n<h1>SymbolTable</h1>\n<pre>\n"); if (Block1) { fprintf(fp, "<i>(Legend: I=Invalid, C=Constant, E=Erasable, F=Fixed, ?=Error)</i><br><br>\n"); } } for (i = 0; i < SymbolTableSize; i++) { if (!(i & 3) && i != 0) { fprintf(fp, "\n"); if (HtmlOut != NULL) fprintf(HtmlOut, "\n"); } if (SymbolTable[i].Value.Invalid) status = ",I"; else if (SymbolTable[i].Value.Constant) status = ",C"; else if (SymbolTable[i].Value.Erasable) status = ",E"; else if (SymbolTable[i].Value.Fixed) status = ",F"; else status = ",?"; fprintf(fp, "%6d%s: %-*s ", i + 1, status, MAX_LABEL_LENGTH, SymbolTable[i].Name); if (HtmlOut) { char *normalized; int width; width = MAX_LABEL_LENGTH; normalized = NormalizeString(SymbolTable[i].Name); if (NULL != strstr(normalized, "&")) width += 4; if (SymbolTable[i].FileName[0]) { fprintf(HtmlOut, "%06d%s: <a href=\"%s.html#%s\">%-*s</a> ", i + 1, status, SymbolTable[i].FileName, NormalizeAnchor(SymbolTable[i].Name), width, normalized); } else { fprintf(HtmlOut, "%06d%s: %-*s ", i + 1, status, width, normalized); } } AddressPrint(&SymbolTable[i].Value); if (3 != (i & 3)) { fprintf(fp, "\t\t"); if (HtmlOut != NULL) fprintf(HtmlOut, "%s", NormalizeString("\t")); } } fprintf(fp, "\n"); if (HtmlOut != NULL) fprintf(HtmlOut, "\n"); }
void DatabaseCreate(struct Connection *conn){ for (int i=0; i < MAX_ROWS; i++){ struct Address addr = {.id = i, .set = 0}; conn->db->rows[i] = addr; } } void DatabaseSet(struct Connection *conn, int id, const char *name, const char *email){ struct Address *addr = &conn->db->rows[id]; if(addr->set) die("Allready set, delete it first"); addr->set = 1; char *res = strncpy(addr->name, name, MAX_DATA); if (!res) die("Name copy fialed"); res = strncpy(addr->email, email, MAX_DATA); if (!res) die("Email copy failed"); } void DatabaseGet(struct Connection *conn, int id){ struct Address *addr = &conn->db->rows[id]; if(addr->set){ AddressPrint(addr); } else { die("ID is not set"); } } void DatabaseDelete(struct Connection *conn, int id){ struct Address addr = {.id = id, .set = 0}; conn->db->rows[id] = addr; } void DatabaseList(struct Connection *conn){ struct Database *db = conn->db; for (int i=0; i<MAX_ROWS; i++){ struct Address *cur = &db->rows[i]; if(cur->set){ AddressPrint(cur); } } } int main(int argc, char *argv[]){ if(argc < 3) die("USAGE: ext17 <dbfile> <action> [action params]"); char *filename = argv[2]; char action = argv[1][0]; struct Connection *conn = DatabaseOpen(filename, action); int id = 0; if(argc > 3) id = atoi(argv[3]); if(id >= MAX_ROWS) die("There is not that many records."); switch(action){ case 'c': DatabaseCreate(conn); DatabaseWrite(conn); break; case 'g': if (argc != 4) die("Need an id to get"); DatabaseGet(conn, id); break; case 's': if(argc != 6) die("Need id, name, email to set."); DatabaseSet(conn, id, argv[4], argv[5]); DatabaseWrite(conn); break; case 'd': if(argc != 4) die("Need id to delete"); DatabaseDelete(conn, id); DatabaseWrite(conn); break; case 'l': DatabaseList(conn); break; default: die("Invalid action:\nc=create\ng=get\ns=set\nd=del\nl=list"); } DatabaseClose(conn); return 0; }
void DatabaseCreate(struct Connection* conn ) { int i = 0; for(i = 0; i < MAX_ROWS; i++) { //make a prototype to initialise it struct Address addr = {.id = i, .set =0}; //then just assign it conn->db->rows[i] = addr; } } void DatabaseSet(struct Connection* conn, int id, const char* name, const char* email) { struct Address* addr = &conn->db->rows[id]; if(addr->set) Die("Already set, deleted it first!", conn); addr->set =1; //WARNING: bug, read the "How to break it" section and fix this char* res = strncpy(addr->name,name,MAX_DATA); //demonstrate the strncpy bug if(!res) Die("Name copy failed", conn); res = strncpy(addr->email,email,MAX_DATA); if(!res) Die("Email copy failed", conn); } void DatabaseGet(struct Connection* conn, int id) { struct Address* addr = &conn->db->rows[id]; if(addr->set) { AddressPrint(addr); } else { Die("Id is not set.", conn); } } void DatabaseDelete(struct Connection* conn, int id) { struct Address addr = {.id = id, .set = 0}; conn->db->rows[id] = addr; } void DatabaseList(struct Connection* conn) { int i = 0; struct Database* db = conn->db; for(i=0;i<MAX_ROWS;i++) { struct Address* cur = &db->rows[i]; if(cur->set) AddressPrint(cur); } } int main(int argc, char* argv[]) { if(argc<3) Die("USAGE: ex17 <dbfile> <action> [action params]", conn); char* filename = argv[1]; char action = argv[2][0]; struct Connection* conn = DatabaseOpen(filename, action); int id =0; if(argc>3) id = atoi(argv[3]); if(id>=MAX_ROWS) Die("There's not that many records.", conn); switch(action) { case 'c': DatabaseCreate(conn); DatabaseWrite(conn); break; case 'g': if(argc != 4) Die("Need an id to get", conn); DatabaseGet(conn, id); break; case 's': if(argc != 6) Die("Need id, name, email to set.", conn); DatabaseSet(conn, id, argv[4], argv[5]); DatabaseWrite(conn); break; case 'd': if(argc != 4) Die("Need id to delete", conn); DatabaseDelete(conn, id); DatabaseWrite(conn); break; case 'l': DatabaseList(conn); break; default: Die("Invalid action, only: c=create, g=get, s=set, d=del, l=list", conn); }//end switch action DatabaseClose(conn); return 0; }//end main