Conditional Windows comments in Common Lisp - common-lisp

What's the canonical Windows/Not-windows conditional comment in Common Lisp?
#-win32 (non-windows-stuff) #+win32 (usually-some-horrific-hack)
seems to work correctly on SBCL and LispWorks (whether the underlying platform is 32 or 64 bit), but CCL only seems to understand
#-windows (non-windows-stuff) #+windows (usually-some-horrific-hack)
How do I dispatch on platform in a portable (across implementations) way? Is there a reference for standard comment flags somewhere?

There is no canonical element of *features* that works across all implementations. The trivial-features project normalizes features across platforms and implementations so, after loading trivial-features, you can use #+windows anywhere to mean Windows.

#+ and #- tests the presence of the symbol in the *features* list. Try checking it's value on the repl of the implementations/platforms you're targeting to see if you can find something in common.
You can also use #+(or windows win32) to test for either of them.

I use:
#+(OR WIN32 WINDOWS MSWINDOWS) ...
Also
#+(and (not windows) (or win32 mswindows))(pushnew :windows *features*)
and then
#+windows ...

Related

How can the mouse be moved programatically in Common Lisp?

The code should run on Windows 10. I tried asking on Reddit, but the ideas are Unix/Linux only. There's also CFFI, but I didn't understand how to use it for this problem (the main usability part of the documentation I found is just an elaborate example not related to this problem).
I also looked through the SetCursorPos of Python, and found that it calls ctypes.windll.user32.SetCursorPos(x, y), but I have no clue what that would look like in CL.
And finally, there's CommonQt, but while there seems to be QtCursor::setPos in Qt, I couldn't find the CL version.
The function called by the Python example seems to be documented here. It is part of a shared library user32.dll, which you can load with CFFI,
(ql:quickload :cffi)
#+win32
(progn
(cffi:define-foreign-library user32
(:windows "user32.dll"))
(cffi:use-foreign-library user32))
The #+win32 means that this is only evaluated on Windows.
Then you can declare the foreign SetCursorPos-function with CFFI:DEFCFUN. According to the documentation, it takes in two ints and returns a BOOL. CFFI has a :BOOL-type, however the Windows BOOL seems to actually be an int. You could probably use cffi-grovel to automatically find the typedef from some Windows header, but I'll just use :INT directly here.
#+win32
(cffi:defcfun ("SetCursorPos" %set-cursor-pos) (:boolean :int)
(x :int)
(y :int))
I put a % in the name to indicate this is an internal function that should not be called directly (because it is only available on Windows). You should then write a wrapper that works on different platforms (actually implementing it on other platforms is left out here).
(defun set-cursor-pos (x y)
(check-type x integer)
(check-type y integer)
#+win32 (%set-cursor-pos x y)
#-win32 (error "Not supported on this platform"))
Now calling (set-cursor-pos 100 100) should move the mouse near the top left corner.
There are two problems here:
How to move the mouse in windows
How to call that function from CL.
It seems you have figured out a suitable win32 function exists so the challenge is to load the relevant library, declare the functions name and type, and then call it. I can’t really help you with that unfortunately.
Some other solutions you might try:
Write and compile a trivial C library to call the function you want and see if you can call that from CL (maybe this is easier?)
Write and compile a trivial C library and see if you can work out how to call it from CL
Write/find some trivial program in another language to move the mouse based on arguments/stdin and run that from CL

How to find all available systems?

There are good functions I use to study Common Lisp projects:
CL-USER> (list-all-packages)
CL-USER> (describe (asdf:find-system "asdf"))
How to list all systems know for asdf, quicklisp or sbcl?
I've tried to dig it from documentation but did not find it yet.
All systems registered in ASDF:
(asdf:registered-systems)
I found that one by typing asdf:systems and letting auto-completion suggests a name. The symbol is exported, so it is fair game. Apparently it is undocumented.
Quicklisp has a notion of distributions, dists.
(ql-dist:all-dists)
Each dist has different versions (http://blog.quicklisp.org/2011/08/going-back-in-dist-time.html):
(ql-dist:available-versions (ql-dist:dist "quicklisp"))
Each dist provides systems:
(ql-dist:provided-systems (ql-dist:dist "quicklisp"))
Each system has a release, you can list all releases:
(ql-dist:provided-releases (ql-dist:dist "quicklisp"))
Conforming implementation have a list of *MODULES*, which is useful notably for systems that are available as built-ins by your implementation; for SBCL:
CL-USER> (require 'sb-mpfr)
("SB-MPFR" "SB-GMP")
CL-USER> *modules*
("SB-GMP" "SB-MPFR" ...)
Also, you can use to have a convenient search through all quickdist's systems, lookup their documentation and dependencies:
http://quickdocs.org

gperftools failing to identify files

Is there a way to avoid Google Performance Tools listing files as "??:?", that is, failing to locate which file contains the function it is reporting on? How can I work out which library contains the function being called?
$ env LD_PRELOAD="/usr/lib/libprofiler.so.0" \
CPUPROFILE=output.prof python script.py
$ google-pprof --text --files /usr/bin/python output.prof
Using local file /usr/bin/python.
Using local file output.prof.
Removing _L_unlock_13 from all stack traces.
Total: 433 samples
362 83.6% 83.6% 362 83.6% dtrsm_ ??:?
58 13.4% 97.0% 58 13.4% dgemm_ ??:?
1 0.2% 97.2% 1 0.2% PyDict_GetItem /.../Objects/dictobject.c
1 0.2% 97.5% 1 0.2% PyParser_AddToken /.../Parser/parser.c
...
I am aiming to be able to profile the C code in a python package that has many compiled C extension modules. In the toy example above, what would I do to track down where "dtrsm_" is defined? If there are multiple loaded libraries that contain functions with that same name, is there any way to tell which version is being called?
C/C++ won't compile if the same pre-processed sourcefile (e.g. with #includes expanded) contains duplicate definitions for the same symbol. (Note that in the case of C++, symbols are mangled, according to compiler-specific schemes, to incorporate the argument signature so as to facilitate overloaded functions, which could not otherwise be differentiated.)
The linker is only concerned with unresolved symbols (so there ought be nothings preventing multiple libraries concurrently calling their own respective internally-defined functions with coincident names). If a file invokes a declared but undefined function, and multiple available libraries implement that symbol, then the linker is free to choose (say by precedence in a search-path) which version gets substituted in. (Incidentally, this is the same mechanism by which profilers such as gperftools or hpctoolkit are able to inject themselves and alter the normal behaviour of another application.)
Since different libraries are mapped to separate pages of memory, it ought to be possible to identify (from memory addresses) which library contains the executing version of a function. Indeed, the GNU debugger can identify the library that code is contained by, even when it fails to name a function.
$ gdb python
(gdb) run -c "from numpy import *; linalg.inv(random.random((1000,1000)))"
CTRL-C
(gdb) backtrace
#0 0x00007ffff5ba9df8 in dtrsm_ () from /usr/lib/libblas.so.3
...
#3 0x00007ffff420df83 in ?? () from /.../numpy/linalg/_umath_linalg.so
Linux (or rather the GNU C library) provides the "backtrace" call (for getting a list of pointers from the call stack), and the "backtrace_symbols" call for automatically converting each of those pointers to a descriptive string such as:
"/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf5) [0x7fc429929ec5]"
Gperftools can (judging from a query on the github mirror) call the generic "backtrace", but instead of "backtrace_symbols" it "forks out to pprof to do the actual symbolizing". This is a fairly-epic perl script, and looks likely where the "??" comes from.
Crucially, google-pprof is trying to report on the source-file (and line-number) which defines the function, not the binary-file containing the machine-code (that is typically quoted in stack traces). It invokes the "nm" utility. On my system it appears (by running "nm -l -D") that libblas, unlike libc and the python binary, has been stripped of such debugging symbols (presumably for optimisation), explaining the result.
To answer the original question: the call-stack samples should definitively and explicitly specify which version is being called. These can probably be dumped using an option which was added in google-pprof several months ago, or (for time-intensive functions) can be roughly ascertained by manual resampling using gdb. (It's even conceivable that g-pprof can be adjusted to explicitly identify the binaries paths in its output summaries.) Alternatively one can run "nm" (and grep) on the candidate binaries/libraries (of which a short-list can be obtained by running "strings" on the profiler's raw output, among other methods). If the source is accessible (to grep) or the libraries are popular (on the web) then of course (and per Mike Dunlavey) it may be easiest to just query for the function name. In theory the "??:?" may be addressed by carefully recompiling the offending objects.
Just Google the offending function names. The ones you show above are defined in LAPACK. dtrsm is for solving a matrix equation. dgemm is for multiplying matrices.
What you need to know is 1) why they are being called, and 2) how big the matrices are.
To find out why they are being called, what I do is just examine individual stack samples, as here.
The reason matrix size matters is if they are small, these LAPACK routines can actually spend a relatively large fraction of their time just classifying their inputs, such as by calling a function LSAME.

How to denote that a command line argument is optional when printing usage

Assume that I have a script that can be run in either of the following ways.
./foo arg1 arg2
./foo
Is there a generally accepted way to denote that arg1 and arg2 aren't mandatory arguments when printing the correct usage of the command?
I've sometimes noticed usage printed with the arguments wrapped in brackets like in the following usage printout.
Usage: ./foo [arg1] [arg2]
Do these brackets mean that the argument is optional or is there another generally accepted way to denote that an argument is optional?
I suppose this is as much a standard as anything.
The Open Group Base Specifications Issue 7
IEEE Std 1003.1, 2013 Edition
Copyright © 2001-2013 The IEEE and The Open Group
Ch. 12 - Utility Conventions
Although it doesn't seem to mention many things I have commonly seen over the years used to denote various meanings:
square brackets [optional option]
angle brackets <required argument>
curly braces {default values}
parenthesis (miscellaneous info)
Edit: I should add, that these are just conventions. The important thing is to pick a convention which is sensible, clearly state your convention, and stick to it consistently. Be flexible and create conventions which seem to be most frequently encountered on your target platform(s). They will be the easiest for users to adapt to.
I personally have not seen a 'standard' that denotes that a switch is optional (like how there's a standard that defines how certain languages are written for example), as it really is personal choice, but according to IBM's docs and the Wiki, along with numerous shell scripts I've personally seen (and command line options from various programs), and the IEEE, the 'defacto' is to treat square bracketed ([]) parameters as optional parameters. Example from Linux:
ping (output trimmed...)
usage: ping [-c count] [-t ttl] host
where [-c count] and [-t ttl] are optional parameters but host is not (as defined in the help).
I personally follow the defacto as well by using [] to mean they are optional parameters and make sure to note that in the usage of that script/program.
I should note that a computer standard should define how something happens and its failure paths (either true fail or undefined behavior). Something along the lines of the command line interpreter _shall_ treat arguments as optional when enclosed in square brackets, and _shall_ treat X as Y when Z, etc.. Much like the ISO C standard says how a function shall be formed for it to be valid (otherwise it fails). Given that there are no command line interpreters, from ASH to ZSH and everything in between, that fail a script for treating [] as anything but optional, one could say there is not a true standard.
Yes, the square brackets indicate optional arguments in Unix man pages.
From "man man":
[-abc] any or all arguments within [ ] are optional.
I've never wondered if they're formally specified somewhere, I've always just assumed they come from conventions used in abstract algebra, in particular, in BNF grammars.

ASDF initialize-source-registry bug?

I've been banging my head against ASDF2 and just want a sanity check. When I eval (asdf:initialize-source-registry) with no arguments or with any argument, I get no value. When I check source-registry, I get an empty hash table. Is this a bug?
I'm on AllegroCL Enterprise 64-bit on Windows 7.
This sounds mostly correct to me. In my SBCL init file, I have:
(pushnew #p"/home/paulnath/.asdf/" asdf:*central-registry* :test #'equal)
(push #p"/home/paulnath/.asdf/" asdf:*central-registry*)
Check section 7.9 in the ASDF manual.
Checking the source of asdf.lisp, the source path ends with a (values), which of course returns no values. So I expect to not return anything.
Old question, but yes, that behavior is correct.
If you provide an argument to asdf::initialize-source-registry, then asdf::source-registry will (probably, you may have no .asd files...) not be empty. Also note that lisp distributions may put their own stuff into asdf::source-registry. For example, SBCL puts its internals into it.
The answer given doesn't really answer the question, as asdf::central-registry is a different (and supposedly deprecated even though it takes precedence over asdf::source-registry) mechanism.

Resources