I want to load a lisp script located in a subdirectory in current working folder. The relative path is ./crossover-operators/ER.lisp.
In Linux this is done by:
(load "./crossover-operators/ER.lisp")
In Windows is done by:
(load ".\\crossover-operators\\ER.lisp")
How can I make a function which loads ER.lisp script independently of the operating system in which my Common Lisp script is running?
First of all, 19.1.1 Namestrings as Filenames says that indeed, namestring (strings as pathnames) are not portable.
A conforming program must never unconditionally use a literal namestring other than a logical pathname namestring because Common Lisp does not define any namestring syntax other than that for logical pathnames that would be guaranteed to be portable.
Note also that if you ask the user for filenames, you can use them portably:
However, a conforming program can, if it is careful, successfully manipulate user-supplied data which contains or refers to non-portable namestrings.
You have two options, which are not exclusive one to the other: using pathname constructors, and/or using logical pathnames.
Pathnames constructors
Build pathnames with make-pathname, merge-pathnames. A pathname is a structure with different components (directory, name, type, etc.) which can be combined together. They are build with a prototypal inheritance approach, where you create new pathnames by copying an existing one and changing some of its components.
make-pathname is just like a struct constructor, except it has a :defaults argument that gives a pathname to use as a prototype.
merge-pathnames is a bit different, since it also performs semantic operations.
For example, if *default-pathname-defaults*, the special variable that holds the default pathname, is set as follows:
USER> (setf *default-pathname-defaults*
(make-pathname :directory '(:relative "crossover-operator")))
#P"crossover-operator/"
Then you have two different behaviours.
USER> (make-pathname :directory '(:relative "tmp")
:defaults *default-pathname-defaults*)
#P"tmp/"
make-pathname replaces the directory component of the original pathname.
USER> (merge-pathnames *)
#P"crossover-operator/tmp/"
merge-pathnames takes a pathname (here, the one we just built, denoted by *), and merge the directory relatively to the one in *default-pathname-defaults*.
Logical pathnames
Logical pathnames are a bit like URLs (Uniform Resource Locator) and only indirectly represents files. The programmer must define translation functions from logical pathnames to actual, physical pathnames, based on the HOST part of the address.
The printed representation of pathnames (namestrings), are not portable, except for logical pathnames. See 19.3.1 Syntax of Logical Pathname Namestrings.
Other than having a defined syntax and translation functions (from logical to physical pathnames), they behave as other pathnames, so you can call merge-pathnames as seen above.
Pathnames translations can map to non-portable namestrings (but you can setup the translations differently on different hosts), but also logical or physical pathnames. The hyperspec for LOGICAL-PATHNAME-TRANSLATIONS has some examples on how to use logical pathnames, like this one:
;;;A more complex example, dividing the files among two file servers
;;;and several different directories. This Unix doesn't support
;;;:WILD-INFERIORS in the directory, so each directory level must
;;;be translated individually. No file name or type translations
;;;are required except for .MAIL to .MBX.
;;;The namestring syntax on the right-hand side is implementation-dependent.
(setf (logical-pathname-translations "prog")
'(("RELEASED;*.*.*" "MY-UNIX:/sys/bin/my-prog/")
("RELEASED;*;*.*.*" "MY-UNIX:/sys/bin/my-prog/*/")
("EXPERIMENTAL;*.*.*" "MY-UNIX:/usr/Joe/development/prog/")
("EXPERIMENTAL;DOCUMENTATION;*.*.*"
"MY-VAX:SYS$DISK:[JOE.DOC]")
("EXPERIMENTAL;*;*.*.*" "MY-UNIX:/usr/Joe/development/prog/*/")
("MAIL;**;*.MAIL" "MY-VAX:SYS$DISK:[JOE.MAIL.PROG...]*.MBX")))
;;;Sample use of that logical pathname. The return value
;;;is implementation-dependent.
(translate-logical-pathname "prog:mail;save;ideas.mail.3")
=> #P"MY-VAX:SYS$DISK:[JOE.MAIL.PROG.SAVE]IDEAS.MBX.3"
Based on #coredump answer and other research, one fast answer is:
(load (make-pathname :name "ER"
:type "lisp"
:defaults (make-pathname :directory '(:relative "crossover-operators"))))
Related
I have two tools in C to parse data from a database to an XML file or a normal text file. Both files contain the same function names but with different implementations, so I am working on merging them both in a single tool and the output type (XML or text) will depend on the input from the user.
So, the problem is having same function (and struct) names but with different implementations. How can I overcome this situation without having to rename everything because that will lead to a mess.
Thank you.
If you have to use both sets of types and functions in the same program at the same time, and if those type and function names have to be visible outside of their enclosing source file(s)1 (i.e., you have a .h file with those type definitions and function declarations), then you must rename at least one set of them. No other choice. C doesn't provide user-definable namespaces2, so anything with external linkage must have a globally unique name.
If those type and function names don't have to be visible outside of their source file3 (i.e., they don't have to be called by a function defined outside of their source file), then you can declare the functions as static - that will limit their visibility to the enclosing source file. If the type names are local to the source file (you haven't put them in a .h that must be included by another source file), then they won't be exported.
If you only need to use one set or the other, but which set isn't known until runtime, you can put each in a shared library and then load the correct one at runtime (using dlopen on the *nix side - not sure what the Windows equivalent would be).
A fourth option would be to switch to C++ and wrap each set in a unique namespace; depending on what you're doing that may be the fastest option.
The function names have what is known as external linkage.
C has four namespaces - label names, tag names, struct and union member names, and all other identifiers (variable names, function names, typedef names, enumeration constants, etc.). Those namespaces are fixed, and you can't create any more.
The function names have either internal or no linkage.
You can enclose each of the function definitions in a different namespace. You won't have to change intra-namespace function calls, but you will have to preface inter-namespace function calls with the "other" namespace.
It is difficult to find an appropriate title because I do not understand why I have the following issue.
When I require my package, I would like to assign a specific function according to some packages. The idea is to set a variable as follow:
(cond ((find-package 'foo) (setf *special-function* #'foo:foo-function))
((find-package 'bar) (setf *special-function* #'bar:bar-function))
(t (warn "The package FOO or BAR is required to enable the special function.")))
Then, the evaluation of this piece of code returns:
There is no package named "FOO" with CCL
Package FOO does not exist with SBCL
The main reason I want to do that is that it exists different packages which provide the same function, and I want to let the user be free to make its own choice by loading the package FOO or BAR (with a preference according to the order in the condition clauses).
Think about the execution/evaluation of the following form:
(if (find-package 'foo)
(foo:foo-function))
Lisp
reads the code
and then evaluates the code.
Your error happens in phase 1: Reading. The form can't be read, when the package does not exist.
A typical way around it would be this:
(if (find-package 'foo)
(funcall (find-symbol "FOO-FUNCTION" "FOO")))
We are then looking up the symbol at runtime. Note that function and package names are by default in uppercase.
In your case you would need to call
(symbol-function (find-symbol "FOO-FUNCTION" "FOO"))
to get the function object. Note though that sometimes it's preferred to just get the symbol.
funcall and apply can call global functions as function object or as symbol:
(funcall 'sin 2.1d0)
or
(funcall #'sin 2.1d0)
Thus when the thing needs to be called later, a symbol offers another source of indirection and will point to the current definition, where the function object can also be an older version of the function.
This almost looks like you want to define a wrapper function for functionality available under different names in different implementations.
Since, as Rainer wrote, we need to distinguish the cases already at read time, we can use reader conditionals for that. Conveniently, all implementations push their name onto *features*, so that we can do it like this:
(defun special-function (&rest args)
#+sbcl (apply #'foo:foo-function args)
#+ccl (apply #'bar:bar-function args)
#-(or sbcl ccl) (error "not implemented))
If instead you want to allow different libraries to fill in your functionality, you can either rely on the user to load one of those before loading your system, if those libraries push their own symbols to *features*, or you can define little wrapper systems that add the optional dependency:
Example: your (asdf) system is named yoursys, then you could define another system yoursys/foo-backend and yoursys/bar-backend, both of which would set your special-function to their respective implementations, and depend on the needed library.
I'm writing a small tool that should be able to inspect an arbitrary process of interest and check if any of its statically linked functions were trampolined. (An example of a trampoline could be what Microsoft Detours does to a process.)
For that I parse the PE header of the target process and retrieve all of its imported DLLs with all imported functions in them. Then I can compare the following between DLLs on disk and the DLLs loaded in the target process memory:
A. Entries in the Import Address Table for each imported function.
B. First N bytes of each function's machine code.
And if any of the above do not match, this will most certainly mean that a trampoline was applied to a particular function (or WinAPI.)
This works well, except of one situation when a target process can import a global variable instead of a function. For example _acmdln is such global variable. You can still find it in msvcrt.dll and use it as such:
//I'm not sure why you'd want to do it this way,
//but it will give you the current command line.
//So just to prove the concept ...
HMODULE hMod = ::GetModuleHandle(L"msvcrt.dll");
char* pVar = (char*)::GetProcAddress(hMod, "_acmdln");
char* pCmdLine = pVar ? *(char**)pVar : NULL;
So, what this means for my trampoline checking tool is that I need to differentiate between an imported function (WinAPI) and a global variable. Any idea how?
PS. If I don't do that, my algorithm that I described above will compare a global variable's "code bytes" as if it was a function, which is just a pointer to a command line that will most certainly be different, and then flag it as a trampolined function.
PS2. Not exactly my code, but a similar way to parse PE header can be found here. (Search for DumpImports function for extracting DLL imports.)
Global variables will be in the .data section not the .text section, in addition the section will not have execute permissions if it's not a function. Therefore you can use both of these characteristics to filter.
[VS10] The aim is to copy the drive literal string into the *.dst thus
TCHAR *driveIDBase;
...
wcscpy_s (driveIDBase, MAX_PATH-3, L"\\\\?\\C:\\*");
This produces the error
IntelliSense: no instance of overloaded function "wcscpy_s" matches
the argument list
Note that the ANSI version works well enough:
strcpy_s (driveIDBase, MAX_PATH-3, "C:\\*");
Supposing we try the obvious workaround:
strcpy_s (driveIDBase, MAX_PATH-3, "\\?\C:\");
can we call the cast (wchar_t *) driveIDBase reliable? That is, WIN32_FIND_DATAW will interpret that string as "C:\"?
Also what is meant by this quote from MSDN?
The "\\?\" prefix turns off automatic expansion of the path string,
It's worth noting the Stack Overflow definition of TCHAR:
A #define for either char or wchar_t, used for porting ancient windows
applications.
The code being assembled is not an ancient port, albeit the initial reason for including it in the current project was that it was recommended (in older threads) for the purposes of conversion in certain API functions.
Due to the phase out of MBCS, building a project these days is preferable in Unicode as Bo suggests above, which renders the usage of the TCHAR macro redundant.
As for the second part of the question, suppose a wide char directory is created thus:
%USERPROFILE%\This Is A SubDirectory of %USERPROFILE% Not C-Colon-Backslash-Users-Backslash-MyUserName-- Being the Expanded Directory Path We Intended to Use
We note that under \\?\ the given subdirectory would not be created in "C:\Users\MyUserName". In fact it could not in most cases, as C:\Users would never have been created with a \\?\ prefix in the first instance.
Concluding this part of the answer with another question: Regarding another statement from the same page in MSDN which states:
The maximum path of 32,767 characters is approximate, because the
"\\?\" prefix may be expanded to a longer string by the system at run
time, and this expansion applies to the total length,
is the expansion at run time not automatic?
Suppose I would like to declare a set of constants in C (representing error codes of an application). how would you divide them into files ? would you use enum in external file and include it ?
Thanks,
James
Yes, #defines or enums in a .h file is the way to go. Enums are useful if you're debugging with a debugger like gdb as you'll see a more descriptive value than a number.
If it's a set of related numeric values, then an enum is the correct approach. If the values are C strings or otherwise not representable by an enum (or if they don't sensibly form a set of related values), you can use one of two approaches.
Either use preprocessor #define statements, or use extern const-marked variables. The former is resolved at compile-time, so you can use it to specify array lengths or to actively call code when used. The latter, however, allows you to change the value of the constant (by specifying it in a .c file rather than a .h file) without having to recompile every file that uses it.
Because extern const-marked variables can be changed in that fashion, they are preferable in code that is reused across many projects, or code that is distributed as a library. Changes to the library are then possible without forcing programs to be recompiled.
If it's a set of values an enumeration declared in a header file would suffice (some people use #defines but since the value doesn't matter an enumeration works just fine in this case). If you simply want to compare to error codes this is a good method.