Common Lisp: getting version of an ASDF package - version

I know I can get the version number of ASDF itself with (asdf:asdf-version). But the same does not work with all other packages I load using ASDF, e.g. (my-system:my-system-version). Is there any programmatic way to get the value of a :version keyword in a system definition?
(defsystem my-system
...
:version "0.1"
...)
I am writing a simple HTTP server and would like to include the version number in the Server HTTP header. Anyway, it is a common need for any program to be able to print out its version number somewhere for user information. Of course, I'd like the version number to be defined only in one place, since I may forget to update it in multiple places.

(slot-value (asdf:find-system 'my-system) 'asdf:version)

Related

Correct way to use the iterate package in Common Lisp

On my Windows XP box with sbcl-1.4.14 I've installed the ASDF using
(load "C:\\Program Files\\clisp-2.49\\asdf\\asdf.lisp")
(require :asdf)
(push "C:\\Documents and Settings\\mayhem\\lisp\\iterate\\" asdf:*central-registry*)
On SLIME
(require :iterate)
(iterate (for i from 1 to 5) (collect (* i i)))
gives The variable I is unbound error
If I do (in-package :iterate), the code above works fine but this time familiar functions such as exit and other functions which I've defined in .sbclrc cease to work, they give The function ITERATE::EXIT is undefined type of errors, for example.
If I do (use-package :iterate), then it gives [Condition of type NAME-CONFLICT] error.
So I began to use the package like this:
(iterate:iterate (iterate:for i from 1 to 5) (iterate:collect (* i i)))
But I think you'll agree that it's a bad style.
How to use the iterate correctly?
Note: I've seen the post about the very similar problem but it didn't help. There aren't many posts or articles about this particular problem.
You need to say (use-package :iterate) before you try to refer to unqualified symbols from the iterate package.
What has happened in your case is this.
You've loaded the iterate system into the running Lisp, creating a package called "ITERATE".
In the "CL-USER" package you've typed (iterate ...), and the reader has worked out that it needs to find or create a symbol whose name is "ITERATE" and which is accessible in the "CL-USER" package.
There is no such symbol, so it creates a new one, CL-USER::ITERATE.
This is not ITERATE:ITERATE so you get an error from the evaluator as it's trying to evaluate the arguments to a function (which doesn't exist, but it doesn't know that yet). In fact the error you're getting is while it's evaluating the first argument in the (for i ...) subform.
Now you say (use-package :iterate) to tell the system to add the "ITERATE" package to "CL-USER"'s search list.
Now there's a conflict: should iterate refer to the existing CL-USER::ITERATE or the newly-accessible ITERATE::ITERATE? (And there are some other conflicts too, probably).
So the system signals an error, and there should be some useful ways to proceed from that, one of which is probably 'unintern all the conflicting "CL-USER" symbols', but you didn't take that option, I suppose.
So now everything is messed up.
And the answer is: use the packages you want to refer to unqualified symbols from before you try to refer to those symbols unqualified.
(Also: Windows XP? I'm impressed by your retroness.)

Doxygen: Outputting Version Numbers

I would like to have Doxygen display the source code version number as part of the main page or the title header.
Presently, our code has the version defined as a text literal:
/*!
* \brief Text literal containing the build number portion of the
* ESG Application Version.
*/
static const char build_version_text[] = "105";
I have searched the internet for a method to get the 105 from the above statement into the Doxygen main page (or header) with no luck.
Background
We have a build server that updates the text string as part of a nightly build operation. The file is updated, then checked into the Software Configuration Management system. The build server is also capable of generating the documentation. We would also like to have the developers be able to check out the code, the build the Doxygen documentation at their workstations.
We are using Doxygen version 1.8.11.
What you're looking for is to set the PROJECT_NUMBER config option based on the value in your source. I don't think this can be done, but the way I would go about achieving the same result is as follows.
Since the project version is updated when a build script runs, have the build script generate an extra file, for example Doxyversion. Have the content of the file be:
PROJECT_NUMBER = "<versiontext>"
Update your main Doxyfile and replace
PROJECT_NUMBER =
with
#INCLUDE = "<pathToDoxyversion>"
Edit:
A solution I can think of that does not require duplicating the version string requires parsing the version string out from the file into an environment variable. Then you can set PROJECT_NUMBER to
PROJECT_NUMBER=$(ENV_VAR)
Another option is you can call doxygen with
( cat Doxyfile ; echo "PROJECT_NUMBER=$ENV_VAR" ) | doxygen
Both solutions would require the developers to know to do this when generating the documentation, or wrapping the entire doxygen call in a script. Also potential portability issues.
Full solution below, from a real example.
Main page
In the documentation for the main page (or anywhere, really), use special markers for the text to substitute dynamically.
Main page source:
https://github.com/mysql/mysql-server/blob/8.0/sql/mysqld.cc#L22
See the special ${DOXYGEN_GENERATION_DATE} markers
Doxygen input filters
In the doxygen configuration file, define an input filter for the file containing the special markers. For example,
FILTER_PATTERNS = "*/sql/mysqld.cc=./doxygen-filter-mysqld"
Implement the doxygen-filter-mysqld script to:
Find the dynamic value to substitute (in your case, parse the value of build_version_text)
Replace (sed) the special marker with the value
Output the result to stdout
For example:
CMD1="s/\\\${DOXYGEN_GENERATION_DATE}/"`date -I`"/g"
...
sed -e ${CMD1} -e ${CMD2} -e ${CMD3} $1
Results
Result is at
http://devdocs.no.oracle.com/mysql-server/8.0.0/
See Also
All this is a work around for that I think should be a good Doxygen feature.
See bug#769679 (Feature Request: doxygen command to expand an environment variable) that was entered for this.
https://bugzilla.gnome.org/show_bug.cgi?id=769679

How do I trace coreutils down to a syscall?

I am trying to navigate and understand whoami (and other coreutils) all the way down to the lowest level source code, just as an exercise.
My dive so far:
Where is the actual binary?
which whoami
/usr/bin/whoami
Where is it maintained?
http://www.gnu.org/software/coreutils/coreutils.html
How do I get source?
git clone git://git.sv.gnu.org/coreutils
Where is whoami source code within the repository?
# find . | grep whoami
./man/whoami.x
./man/whoami.1
./src/whoami.c
./src/whoami
./src/whoami.o
./src/.deps/src_libsinglebin_whoami_a-whoami.Po
./src/.deps/whoami.Po
relevant line (84):
uid = geteuid ();
This is approximately where my rabbit hole stops. geteuid() is mentioned in gnulib/lib/euidaccess.c, but not explicitly defined AFAICT. It's also referenced in /usr/local/unistd.h as extern but there's no heavy lifting related to grabbing a uid that I can see.
I got here by mostly grepping for geteuid within known system headers and includes as I'm having trouble backtracing its definition.
Question: How can I dive down further and explore the source code of geteuid()? What is the most efficient way to explore this codebase quickly without grepping around?
I'm on Ubuntu server 15.04 using Vim and some ctags (which hasn't been very helpful for navigating existing system headers). I'm a terrible developer and this is my method of learning, though I can't get through this roadblock.
Normally you should read the documentation for geteuid. You can either read GNU documentation, the specification from the Open Group or consult the man page.
If that doesn't help you could install the debug symbols for the c-library (it's called libc6-dbg or something similar) and download the source code for libc6) then you point out the path to the source file when you step into the library.
In this case I don't think this would take you much further, what probably happens in geteuid is that it simply issues an actual syscall and then it's into kernel space. You cannot debug that (kernel) code in the same way as you would debug a normal program.
So in your case you should better consult the documentation and read it carefully and try to figure out why geteuid doesn't return what you expect. Probably this will lead to you changing your expectation of what geteuid should return to match what's actually returned.

GSSAPI: gss_export_name returns a blank

I am having a problem with exporting a name using gss_export_name, I though that once the name is exported I should be able to just print it but I am turning up a blank Literaly
EXPORTED NAME: , EXPORTED NAME LENGTH: 47
Here is my code
OM_uint32 major_status;
gss_cred_usage_t usage;
OM_uint32 lifetime;
gss_name_t inquired_name;
major_status = gss_inquire_cred(&minor_status, GSS_C_NO_CREDENTIAL, &inquired_name,
&lifetime, &usage, &oid_set);
gss_buffer_desc exported_name_buffer;
major_status = gss_export_name(&minor_status, inquired_name, &exported_name_buffer);
printf("EXPORTED NAME: %s, EXPORTED NAME LENGTH: %d\n",
exported_name_buffer.value, exported_name_buffer.length);
for clarity I decided not to include checks, but I also take care to make sure that major_status is always == GSS_S_COMPLETE
Appreciate any ideas
Unfortunately the buffer output by gss_export_name is an ASN.1 data structure not a human-readable string. Se section 3.2 of RFC 2743. You'd need to skip over the header of that structure and then parse the name in a mechanism-dependent manner.
Some of the GSS-API developers strongly recommend doing this. As an example, the gss-api patches to Openssh do this for parsing Kerberos names. This is the theoretically correct approach. In practice though, using gss_display_name and handling the output of that call produces more portable results in practice, even though it may produce strange results in a multi-mechanism application. You'll get significant arguments over how to handle this in the GSS-API community. Everyone will agree that you should use gss_display_name for producing output for debugging and logs. The question is what should you do if you want a name for searching on an access control list. If you can directly use the output of gss_export_name and do binary comparisons, do that. However if you need to compare against input entered by a human, I'd argue that using the output of gss_display_name is better, while others will argue that parsing the gss_export_name output is better.

Retrieving Global Variable Values from Command Line

In one particular project, we're trying to embed version information into shared object files. We'd like to be able to use some standard linux tool to parse the shared object to determine the version for automated testing.
Currently I have "const int plugin_version = 14;". I can use 'nm' and 'objdump' and verify that it's there:
00000000000dcfbc r plugin_version
I can't, however, seem to be able to get the value of that variable easily from command line. I figured there'd be a POSIX tool for showing the initialized values for globals. I have contemplated using a format for the variable as the information itself, ie, plugin_version_14, but that seems like a huge hack. Embedding the information in the filename unfortunately is NOT an option. Any other suggestions welcome.
You could embed it as a string
"MAGIC MARKER STRING VERSION: 4.56 END OF MAGIC" then just look for "MAGIC MARKER STRING" in the file and extract the version information that comes after it.
if you make it a standard, you could easily make command line tool to find these embeded strings on all your software.
if you require it also to be an int, a little macro magic will construct both the int and magic string to make sure they are never out of synch.
There's a couple of options I think.
My first instinct is to make sure the version information lives in its own section in the ELF file. You can use objdump -s -j name of section /bin/whatever.
This rather relies on objdump being available of course.
Alternatively you can do what Keith suggested, and just use 'strings', along with a magical marker string. This feels a little hackish, but should work quite well.
Finally, why don't you just add a --version command line option? You can then store the version information however you like, and trivially retrieve it using the one tool which is certain to be installed on any system which has your software.
A terrible hack that I've used in the past is to embed the version information in a variable name, so nm will show:
00000000000dcfbc r plugin_version_14
Why not writing your own tool to get that version in C/C++ ? You could Use dlopen, then dlsym to get the symbol and print its value to standard output. This way you also verify if the symbol is already there. It looks like 20 ~ 30 lines of code to me and about 20 minutes of your life :)
I know that the question is about command line, but writing such a tool yourself should be easy (especially if such a command line tool does not exist).
If the binary is not stripped, you could use gdb to print the variable. (I just tried to script gdb, but it seems to refuse work if stdin is not a tty, maybe expect will do the job ? )
If you can accept using python, this might help:
import struct
import sys
import subprocess
if __name__ == '__main__':
so = sys.argv[1]
sym = sys.argv[2]
addr = subprocess.check_output('nm %s | grep %s' % (so, sym), shell=True)
addr = int(addr.split()[0], 16)
so_file = open(so)
so_file.seek(addr)
data = so_file.read(4)
print struct.unpack('#i', data)[0]
Disclaimer: This script doesn't do any error checking (if you like it I'm sure you can come up with some ;)). It also assumes you're reading a 4-byte native int value.
$ cat global.c
const int plugin_version = 14;
$ python readsym.py global.so plugin_version
14

Resources