implementation module ReadState import StdEnv, State, ReadWriteState, pdReadState //import DebugUtilities; F a b :== b; import ExtFile; // expected is the file of the executable ReadState :: !String !*State !*Files -> (!*State,!*Files) ReadState application_name state files // #! state // = EmptyState; #! (path, file_name_with_extension) = ExtractPathAndFile application_name #! (file_name, _) = ExtractPathFileAndExtension file_name_with_extension #! state_file_name = construct_path path (file_name +++ ".dat") #! (ok, input, files) = fopen state_file_name FReadData files | not ok #! state = AddMessage (LinkerWarning ("could not read complement " +++ state_file_name)) state = (state,files) // check if complement is up-to-date #! (exists_dat_file,is_it_up_to_date,state) = isComplementUpToDate state_file_name state | exists_dat_file && (not is_it_up_to_date) #! state = AddMessage (LinkerError ("complement " +++ state_file_name +++ " is not up-to-date")) state #! (_,files) = fclose input files; = (state,files) // check if complement exists | not exists_dat_file #! state = AddMessage (LinkerError ("complement " +++ state_file_name +++ " doesn't exists")) state #! (_,files) = fclose input files; = (state,files) // check header #! (read_minor,input,state) = ReadComplementVersion state_file_name ComplementVersion input state; #! (ok,state) = IsErrorOccured state; | not ok = (state,files); // skip raw data within complement #! (ok_freadi,object_size,input) = freadi input #! (ok_fseek, input) = fseek input object_size FSeekSet | not (ok_freadi || ok_fseek) #! state = AddMessage (LinkerError ("error reading complement " +++ state_file_name)) state #! (_,files) = fclose input files; = (state,files) // read counters #! (_,n_libraries,input) = freadi input #! (_,n_xcoff_files,input) = freadi input #! (_,n_xcoff_symbols,input) = freadi input #! (_,n_library_symbols,input) = freadi input // read libraries #! (library_list,input) = ReadLibraryList n_libraries EmptyLibraryList input #! (library_file_names,input) = ReadLibraryFileNames n_libraries input; // read marked_bool_a #! (marked_bool_a,input) = loopAfillOnInput read_bool input // read_marked_offset_a #! (marked_offset_a,input) = loopAfillOnInput read_int input // read module_offset_a #! (module_offset_a,input) = loopAfillOnInput read_int input // read xcoff_a #! (xcoff_a,input) = loopAurfillOnInput (read_xcoff state_file_name) input // read namestable #! (namestable,input) = ReadNamesTable create_names_table input // update state #! state = { state & // linker tables n_libraries = n_libraries , n_xcoff_files = n_xcoff_files , n_xcoff_symbols = n_xcoff_symbols , n_library_symbols = n_library_symbols , marked_bool_a = marked_bool_a , marked_offset_a = marked_offset_a , module_offset_a = module_offset_a , xcoff_a = xcoff_a , namestable = namestable // dynamic libraries , library_list = library_list , library_file_names = library_file_names }; #! (_,files) = fclose input files; = (state,files); where read_bool :: !Int !*{#Bool} !*File -> !(!*{#Bool},!*File) read_bool i marked_bool_a input #! (_,c,input) = freadc input; = ({ marked_bool_a & [i] = c == 'T' }, input); isComplementUpToDate :: !String !*State -> (!Bool,!Bool,!*State); isComplementUpToDate file_name state #! msg = "isComplementUpToDate (ReadState): not yet implemented"; = (True,True,AddMessage (LinkerWarning msg) state); // = F "isComplementUpToDate: not yet implemented" (True,True); /* # file_name_without_extension = fst (ExtractPathFileAndExtension file_name); # (found,time_low,time_high) = FetchFileTime (file_name_without_extension +++ ".exe"); # (found2,time_low2,time_high2) = FetchFileTime (file_name_without_extension +++ ".dat"); #! result = CompareFileTimes time_low2 time_high2 time_low time_high; // .dat: just as old or newer as .exe = (found2,result > (-1)); */ // ReadNamesTable ReadNamesTable :: !*NamesTable !*File -> (!*NamesTable,!*File) ReadNamesTable namestable input = read_names_table_elements 0 /* n_names_table_elements*/ 1 namestable input where read_names_table_elements i limit namestable input #! (end,input) = fend input | end = (namestable,input) /* ** Read NamesTableElement from input */ #! (s,input) = freadline input #! (_,i0,input) = freadi input #! (_,i1,input) = freadi input #! namestable = insert_symbol_in_symbol_table (s % (0, size s - 2)) i0 i1 namestable = read_names_table_elements (inc i) limit namestable input ReadLibraryList :: !Int !LibraryList !*File -> (!LibraryList,!*File) ReadLibraryList n_libraries ll input | n_libraries == 0 = (ll,input) #! (s,input) = freadline input //pc #! (_,i0,input) = freadi input #! (lsl,input) = ReadLibrarySymbolsList input #! (_,i1,input) = freadi input = ReadLibraryList (dec n_libraries) (Library (s % (0, size s - 2)) /* mac */ i0 lsl i1 ll) input where ReadLibrarySymbolsList input #! (_,n_library_symbols,input) = freadi input #! (lsl,input) = read_library_symbols_list n_library_symbols EmptyLibrarySymbolsList input = (lsl,input) where read_library_symbols_list n_library_symbols lsl input | n_library_symbols == 0 = (lsl,input) #! (s,input) = freadline input = read_library_symbols_list (dec n_library_symbols) (LibrarySymbol (s % (0, size s - 2)) lsl) input ReadLibraryFileNames :: !Int !*File -> !([String],!*File) ReadLibraryFileNames n_libraries input | n_libraries == 0 = ([],input) #! (_,s_lib_name,input) = freadi input #! (lib_name,input) = freads input s_lib_name #! (libs,input) = ReadLibraryFileNames (dec n_libraries) input = F lib_name ([lib_name:libs],input)