/* NEEDS.P */ section $-need => needs; /* SPECIFICATION ------------- 'needs' is a replacement for 'uses' - see HELP USES. Unlike 'uses', it does not require its libraries to set a variable of the same name. Hence it is more convenient to use. Also, it loads all files into the top-level section, pop-section. This is useful if you 'need' the same file from inside several different sections, and it isn't itself a section with an absolute name. PUBLIC macro needs: 'needs' takes one argument, the name of a file. If it hasn't loaded the file before, it searches 'popuseslist' for the first directory containing it. When found, it loads the file, first switching section to pop_section. Files are given the default extension .P . */ /* IMPLEMENTATION -------------- 'needs' is a macro which reads one item, the name of a library. It checks whether it has been called with this before, by looking at Defined(): if the library has been previously loaded by 'needs', this will be true, else false. If the library hasn't been loaded already, 'needs' does so by calling 'loadlib'. It changes section to pop_section first, and changes it back after loading. The code is based on 'uses', but with the addition of section-switching, and with the use of a property rather than variables for marking whether a library is already loaded. There is a HELP file, HELP NEEDS, for this module. Make sure that you update it if you change anything. */ vars Defined; if isundef(Defined) then newproperty( [], 50, false, true ) -> Defined; endif; /* The check on isundef prevents us reassigning to Defined, and losing old values in the table, if the user loads NEEDS.P more than once. */ define global macro needs; vars LibName, ThisSection; readitem() -> LibName; if not(Defined(LibName)) then true -> Defined(LibName); /* Mark file as loaded: do so here to avoid recursive a-needs-b-needs-a loops. */ current_section -> ThisSection; pop_section -> current_section; loadlib($-need$-LibName><''); /* Switch to pop_section and load file. Catenate LibName with '' to make it into a string, rather than a word. */ $-need$-ThisSection -> current_section; /* Switch back to original section. */ endif; enddefine; endsection;