Rename an Ada package - ada

Is it possible to have a different file name for a package than its actual name? I have tried to use the pragmas below but get errors like "pragma source_file_name_project argument has incorrect identifier"
package Parent_With_Very_Long_Name is end Parent_with_Very_Long_Name;
...
package Parent_With_Very_Long_Name.Child is
pragma Source_File_Name_Project("parent-child.ads");
end Parent_With_Very_Long_Name.Child;
Source_File_Name_Project
Source_File_Name

The actual storage of Ada source text is technically an implementation detail of the compiler.
Looking at the file names your compiler expects, I would guess that you are using GNAT (GCC-Ada). GNAT allows you to override the default naming scheme in project files:
project Short_File_Names is
package Naming is
for Specification ("Parent_With_Very_Long_Name.Child")
use "parent-child.ads";
end Naming;
end Short_File_Names;

The documentation for pragma Source_File_Name says the syntax is
pragma Source_File_Name (
[Unit_Name =>] unit_NAME,
Spec_File_Name => STRING_LITERAL,
[Index => INTEGER_LITERAL]);
pragma Source_File_Name (
[Unit_Name =>] unit_NAME,
Body_File_Name => STRING_LITERAL,
[Index => INTEGER_LITERAL]);
so the reason the compiler is complaining is that you've used incorrect syntax. Using the correct syntax, that would be
package Parent_With_Very_Long_Name.Child is
pragma Source_File_Name
(Parent_With_Very_Long_Name.Child, Spec_File_Name => "parent-child.ads");
end Parent_With_Very_Long_Name.Child;
but the compiler now says
parent-child.ads:2:01: incorrect placement for configuration pragma "Source_File_Name"
The proper placement for this configuration pragma is before the unit:
pragma Source_File_Name
(Parent_With_Very_Long_Name.Child, Spec_File_Name => "parent-child.ads");
package Parent_With_Very_Long_Name.Child is
end Parent_With_Very_Long_Name.Child;
which is all very well, but how are other units going to know this? (GNAT has a source-based compilation model). One answer is to put the pragma in a configuration file, gnat.adc by default. A better answer is to use GNAT project files and package Naming, as suggested by Jacob Sparre Andersen.

Related

Julia - Metaprogramming for using several modules

I'm using Julia to autograde students' work. I have all of their files Student1.jl, Student2.jl, etc. as separate modules Student1, Student2, etc in a directory that is part of LOAD_PATH. What I want to be able to do works completely fine in the REPL, but fails in a file.
macro Student(number)
return Meta.parse("Main.Student$number")
end
using Student1
#Student(1).call_function(inputs)
works completely fine in the REPL. However, since I'm running this in a script, I need to be able to include the modules with more metaprogramming that is currently not working. I would have thought that the exact same script above would have worked in a file Autograder.jl by calling
#eval(using Student1)
#Student(1).call_function(inputs)
in a module Autograder. But I get either an UndefVarError: Student1 not defined or LoadError: cannot replace module Student1 during compilation depending on how I tweak things.
Is there something small in Julia metaprogramming I'm missing here to make this autograding system work out? Thanks for any advice.
The code just as you have written works for me on julia versions 1.1.0, 1.3.1, 1.5.1, 1.6.0 and 1.7.0. By that I mean, if I add an inputs variable and put your first code block in a file Autograder.jl and run JULIA_LOAD_PATH="modules:$JULIA_LOAD_PATH" julia Autograder.jl with the student modules in the modules directory I get the output of the call_function function in the Student1 module.
However if Autograder.jl actually contains a module then the Student$number module is not required into Main and your macro needs to be modified accordingly:
module Autograder
macro Student(number)
return Meta.parse("Student$number") # or "Autograder.Student$number"
end
inputs = []
#eval(using Student1)
#Student(1).call_function(inputs)
end
Personally I wouldn't use a macro to accomplish this, here is one possible alternative:
student(id) = Base.require(Main, Symbol("Student$(id)"))
let student_module = student(1)
student_module.call_function(inputs)
end
or without modifying the LOAD_PATH:
student(id) = include("modules/Student$(id).jl")
let student_module = student(1)
student_module.call_function(inputs)
end

Sqlite (within SqliteStudio): invalid command name "parray"

I am discovering writing functions in TCL for Sqlite (https://github.com/pawelsalawa/sqlitestudio/wiki/ScriptingTcl).
I wanted to play a basic exemple found in the official page of sqlite(http://sqlite.org/tclsqlite.html):
db eval {SELECT * FROM MyTable ORDER BY MyID} values {
parray values
puts ""
}
I get the following error:
Error while requesting the database « -- » : invalid command name "parray"
Help is very welcome :)
SqliteStudio does not seem to fully initialise Tcl, as you would expect it from a non-embedded installation:
Using external Tcl packages or modules is not possible, because Tcl
interpreters are not initialized with "init.tcl".
See Wiki.
Background
Standard Tcl sources init.tcl, early as part of an Tcl interpreter's initialisation. init.tcl, in turn, registers a number of Tcl procs for autoloading. parray is one of those lazily acquired procs.
Ways forward
I am not familiar with SqliteStudio. Why not stick with sqlite's standard Tcl frontend, which gives you full Tcl and comes with Tcl distributions free house? But this certainly depends on your requirements.
That said, you could attempt to force-load init.tcl in SqliteStudio's embedded Tcl, but I don't know (and can't test) whether the distribution has not pruned these scripts or whether they were effectively relocated. From the top of my head (untested):
source [file join $tcl_library init.tcl]
# ...
db eval {SELECT * FROM MyTable ORDER BY MyID} values {
parray values
puts ""
}

Error: cannot generate code for file random.ads (package spec)

I somehow cannot compile (neither run) my Ada code in GPS. I get an error:
cannot generate code for file random.ads (package spec)
gprbuild: *** compilation phase failed
The random.ads file looks like this:
with Ada.Numerics.Float_Random;
use Ada.Numerics.Float_Random;
package random is
protected randomOut is
procedure Inicializal;
entry Parcel(
randomout: out Positive;
from: in Positive;
to: in Positive := 1
);
private
G: Generator;
Inicializalt: Boolean := False;
end randomOut;
task print is
entry write(what: in String);
end print;
end random;
The .gpr file looks as follows:
project Default is
package Compiler is
for Default_Switches ("ada") use ("-g", "-O2");
end Compiler;
for Main use ("hunting.adb");
end Default;
What does this mean? How can I fix it? Thank you!
You can't generate code for a package specification.
This is normal and expected.
You can compile the package body, random.adb, and generate code for it - but there's usually no need.
Just compile your main program, (or your test harness if you're unit testing) and let the compiler find all its dependencies.
(If it can't, either you haven't written them yet, or it's looking in the wrong place. If you need help with that, add relevant info to the question).
The problem is caused by
task print is
entry write(what: in String);
end print;
As any task is specified as a body, the compiler had trouble deciding: it had a body, that has to be compiled, in a spec file, which does not. Moving the task to the .adb file solved the issue.

Call Rmath via Ctypes from Ocaml on OS X

I want to use R's mathematical functions as provided in libRmath from Ocaml. I successfully installed the library via brew tap homebrew science && brew install --with-librmath-only r. I end up with a .dylib in /usr/local/lib and a .h in /usr/local/include. Following the Ocaml ctypes tutorial, i do this in utop
#require "ctypes.foreign";;
open Ctypes;;
open Foreign;;
let test_pow = foreign "pow_di" (float #-> int #-> returning float);;
this complains that it can't find the symbol. What am I doing wrong? Do I need to open the dynamic library first? Set some environment variables? After googling, I also did this:
nm -gU /usr/local/lib/libRmath.dylib
which gives a bunch of symbols all with a leading underscore including 00000000000013ff T _R_pow_di. In the header file, pow_di is defined via some #define directive from _R_pow_di. I did try variations of the name like "R_pow_di" etc.
Edit: I tried compiling a simple C program using Rmath using Xcode. After setting the include path manually to include /usr/local/include, Xcode can find the header file Rmath.h. However, inside the header file, there is an include of R_ext/Boolean.h which does not seem to exist. This error is flagged by Xcode and compilation stops.
Noob alert: this may be totally obvious to a C programmer...
In order to use external library you still need to link. There're at least two different ways, either link using compiler, or link even more dynamically using dlopen.
For the first method use the following command (as an initial approximation):
ocamlbuild -pkg ctypes.foreign -lflags -cclib,-lRmath yourapp.native
under premise that your code is put into yourapp.ml file.
The second method is to use ctypes interface to dlopen to open the library. Using the correct types and name for the C function call, this goes like this:
let library = Dl.dlopen ~filename:"libRmath.dylib" ~flags:[]
let test_pow = foreign ~from:library "R_pow_di" (double #-> int #-> returning double)

ADA File Names vs. Package Names

I inherited an ADA program where the source file names and package file names don't follow the default naming convention. ADA is new to me, so I may be missing something simple, but I can't see it in the GNAT Pro User's Guide. (This similar question didn't help me.)
Here are a couple of examples:
File Name: C_Comm_Config_S.Ada
Package Name: Comm_Configuration
File Name: D_Bus_Buffers_S.Ada
Package Name: Bus_Buffers
I think I have the _S.Ada and _B.Ada sorted out, but I can't find anything in the program source or build files that show the binding between the Package Name and the rest of the File Name.
When I compile a file that doesn't use any other packages, I get a warning: file name does not match unit name... This appears to be from the prefix of C_ or D_, in this particular case.
Also, I'm not clear if the prefixes C_ and D_ have any special meaning in the context of ADA, but if it does, I'd like to know about it.
So I appear to have two issues, the Prefix of C_ or D_ and in some cases the rest of the file name doesn't match the package.
You could use gnatname: see the User’s Guide.
I copied subdirectories a/ and d/ from the ACATS test suite to a working directory and created a project file p.gpr:
project p is
for source_dirs use ("a", "d");
end p;
and ran gnatname with
gnatname -P p -d a -d d \*.ada
which resulted in an edited p.gpr and two new files, p_naming.gpr and p_source_list.txt. These are rather long, but look like
p.gpr:
with "p_naming.gpr";
project P is
for Source_List_File use "p_source_list.txt";
for Source_Dirs use ("a", "d");
package Naming renames P_Naming.Naming;
end P;
p_naming.gpr:
project P_Naming is
for Source_Files use ();
package Naming is
for Body ("d4a004b") use "d4a004b.ada";
for Body ("d4a004a") use "d4a004a.ada";
for Body ("d4a002b") use "d4a002b.ada";
...
for Body ("aa2010a_parent.boolean") use "aa2010a.ada" at 4;
for Body ("aa2010a_parent") use "aa2010a.ada" at 3;
for Spec ("aa2010a_parent") use "aa2010a.ada" at 2;
for Spec ("aa2010a_typedef") use "aa2010a.ada" at 1;
...
for Body ("a22006d") use "a22006d.ada";
for Body ("a22006c") use "a22006c.ada";
for Body ("a22006b") use "a22006b.ada”;
end Naming;
end P_Naming;
The for Body ("aa2010a_parent") use "aa2010a.ada" at 3; is used when there’s more than one unit in the source file.
p_source_list.txt:
a22006b.ada
a22006c.ada
a22006d.ada
a27003a.ada
a29003a.ada
...
d4a002b.ada
d4a004a.ada
d4a004b.ada
When building, for example, test d4a004b, you have to use the file name and suffix:
gnatmake -P p d4a004b.ada
The Ada standard does not say anything about source file naming conventions. As it appears that you use GNAT, I assume that you mean the "GNAT default naming convention".
You can tell GNAT about alternatively named files in a Naming package inside your project files.
A simple example:
project OpenID is
...
package Naming is
for Implementation ("Util.Log.Loggers.Traceback")
use "util-log-loggers-traceback-gnat.adb";
for Implementation ("Util.Serialize.IO.XML.Get_Location")
use "util-serialize-io-xml-get_location-xmlada-4.adb";
end Naming;
end OpenID;

Resources