/** * Adds the indicated linking record to the Module. * * @param rec the linking record to be added * * @refcode * OB, LM * @errtest * @errmsg * ES.44, ES.45, ES.46 * @author Mark Mathis * @creation May 21, 2011 * @modlog * @teststandard Andrew Buelow * @codestandard Mark Mathis */ public void AddRecord(Linking rec) { // relocate the address as we add it int address = rec.Location; address += RelocateValue; if (!(0 <= address && address <= 1023)) { // error, address will be relocated out of the range of memory throw new Error(ErrCat.Serious, 44); } if (address < HeaderRecord.LinkerLoadAddress || address > HeaderRecord.LinkerLoadAddress + HeaderRecord.ModuleLength) { // error, address will be relocated out of the range of the module throw new Error(ErrCat.Serious, 45); } rec.Location = address; // add the record to the module if (linkingRecords.ContainsKey(rec.Location)) { // error, multiple linking records with same location counter value throw new Error(ErrCat.Serious, 46); } else { linkingRecords.Add(rec.Location, rec); } }
/** * Parses a single linking record. * * @param rec the linking record to be parsed * @param mod the module this linking record will be a part of * * @refcode * OB2 * @errtest * @errmsg * EW.10, ES.09, ES.10, ES.11, ES.12, ES.13, ES.14, ES.15 * @author Mark Mathis * @creation May 19, 2011 * @modlog * @teststandard Andrew Buelow * @codestandard Mark Mathis */ public void ParseLink(string rec, Module mod) { string[] field = rec.Split(':'); Linking linkRecord = new Linking(); // check if record has the correct number of fields if (field.Length != 4) { // error, wrong number of fields errPrinter.PrintError(ErrCat.Serious, 9); } // check that Entry name is valid string entry = field[1]; /* Regular expression used to determine if all characters in the token are * letters or numbers. */ Regex alphaNumeric = new Regex(@"[^0-9a-zA-Z]"); if (2 <= entry.Length && entry.Length <= 32) { if (!(!alphaNumeric.IsMatch(entry) && char.IsLetter(entry[0]))) { // entry name is not a valid label errPrinter.PrintError(ErrCat.Serious, 10); } } else { // entry name is not the right length errPrinter.PrintError(ErrCat.Serious, 10); } // add entry name to linker linking record linkRecord.EntryName = entry; // get the location within the program string prgmLoc = field[2].ToUpper(); // check length, should be 4 digit hex number if (prgmLoc.Length != 4) { // error, wrong length errPrinter.PrintError(ErrCat.Warning, 10); } //check that it is valid hex int prgmLocVal = 0; try { prgmLocVal = Convert.ToInt32(prgmLoc, 16); } catch (FormatException) { // error, not valid hex throw new Error(ErrCat.Serious, 11); } // check that it is in the correct range if (prgmLocVal < 0 || prgmLocVal > 1023) { // error, must be between 0 and 1023 errPrinter.PrintError(ErrCat.Serious, 12); } // add location to linking header record linkRecord.Location = prgmLocVal; // make sure the program name is properly formatted // and in the symbol table string pgmName = field[3]; if (2 <= pgmName.Length && pgmName.Length <= 32) { if (!(!alphaNumeric.IsMatch(pgmName) && char.IsLetter(pgmName[0]))) { // program name is not a valid label throw new Error(ErrCat.Serious, 13); } } else { // program name is not the right length throw new Error(ErrCat.Serious, 13); } // check that program name is in symbol table if (mod.ModuleName != pgmName) { // error, program name at end of linking record must match program name // of program being parsed throw new Error(ErrCat.Serious, 14); } if (!symb.ContainsSymbol(pgmName)) { // error, program name not in the symbol table errPrinter.PrintError(ErrCat.Serious, 15); } // add entry to symbol table mod.AddRecord(linkRecord); }