I tried to use fn:string-pad() xquery function it throws error undefined function, using Marklogic version 9
https://docs.marklogic.com/fn:string-pad
fn:string-pad() was only defined in an early draft of XQuery and was later removed. That early (May 2003) draft was supported in the 0.9-ml dialect. If you have XQuery modules in this dialect you should really migrate them to either the strict standards-compliant dialect 1.0 or the extended version 1.0-ml. I would recommend the latter, unless you have a particular reason not to. At some point support for 0.9-ml will be removed. In the meantime you can add an explicit version declaration to the top of your module to use the old syntax (and therefore the availability of this obsolete function): xquery version "0.9-ml"
With respect to this function in particular: it was removed because it is trivial to write, even with all the error checking:
declare function local:string-pad($pad-string as xs:string?, $pad-count as xs:integer) as xs:string?
{
if (empty($pad-string)) then ()
else if ($pad-count lt 0) then error((),"Invalid pad count")
else if ($pad-count eq 0) then ""
else string-join(for $i in 1 to $pad-count return $pad-string,"")
};
Related
Posting for two reasons: (1) I was stuck on unhelpful compiler errors for far too long for such a simple issue and I want the next person to google those messages to come upon my (or other) answers, and (2) I still don't understand disallowing a use clause, so my own answer is really incomplete.
In order to call a program in two places with mostly the same arguments, I want to use the '&' to append to a default list inline:
declare
Exit_Code : constant Integer := GNAT.OS_Lib.Spawn (Program_Name => "gprbuild", Args => (Default_GPR_Arguments & new String'(File_Name_Parameter)));
begin
if Exit_Code /= 0 then
raise Program_Error with "Exit code:" & Exit_Code'Image;
end if;
end;
However, the compiler complains that System.Strings.String_List needs a use clause:
operator for type "System.Strings.String_List" is not directly visible
use clause would make operation legal
But inserting use System.Strings.String_List yields:
"System.Strings.String_List" is not allowed in a use clause
I also got this warning:
warning: "System.Strings" is an internal GNAT unit
warning: use "GNAT.Strings" instead
So I substituted GNAT for System in the with and the use clause and got an extra error in addition to the original 'you need a use clause for System.Strings.String_List' one:
"GNAT.Strings.String_List" is not allowed in a use clause
Why is GNAT.Strings.String_List not allowed in a use clause? Section 8.5 on use clauses doesn't seem to state anything on disallowed packages, so is this a compiler bug? Is it possible to define a new package that cannot have a use clause?
In a use clause of the form
use Name;
Name must be a package name. GNAT.Strings.String_List is a subtype name, not a package name.
There are a number of ways to invoke "&" for String_List. The simplest is to use the full name:
GNAT.Strings."&" (Left, Right)
but presumably you want to be able to use it as an operator in infix notation, Left & Right. Ways to achieve this, in decreasing specificity:
function "&" (Left : GNAT.Strings.String_List; Right : GNAT.Strings.String_List) return GNAT.Strings.String_List renames GNAT.Strings."&"; This makes this specific function directly visible.
use type GNAT.Strings.String_List; This makes all primitive operators of the type directly visible.
use all type GNAT.Strings.String_List; This makes all primitive operations of the type (including non-operator operations) directly visible.
use GNAT.Strings; This makes everything in the package directly visible.
Looks like it is a design decision. And many other packages in System follows this rule. From the s-string.ads (package specification for System.String):
-- Note: this package is in the System hierarchy so that it can be directly
-- be used by other predefined packages. User access to this package is via
-- a renaming of this package in GNAT.String (file g-string.ads).
My guess why this is done in that way: because it isn't in the Ada specification, but extension from GNAT.
Porting some old code to a newer CentOs Linux machine.
I am using linux gnat with a couple of flags:
Default_Switches ("ada") use ("-fstack-check", "-g", "-gnatVr", "-gnato", "-gnatE", "-gnatwmuv", "-gnata", "-m32");
and I have the gnat version:
gcc-gnat.i686 4.8.5-11.el7
So these are the preconditions.
I have now an for sure working self-written storage manager which is called by
St_Wa.Alloc(StoragePool, BitSize)
So now to my problem and to be honest I do not really get the point why the compiler is failing, so I would be really grateful for a detailed explanation why it is not working!
function AllocMem(StoragePool : in St_Wa.Mem_Pool_Type;
Option: in Option_Type)
return Option_Ref is
subtype New_Type is Option_Type (Option.Kind);
New_Option : New_Type;
for New_Option use at St_Wa.Alloc( StoragePool => StoragePool,
BitSize => New_Type'Size)
begin
Bl_Bl.Move( ... sth happens here ... )
return Pointer(New_Option'Address);
end AllocMem;
Whereas:
type Option_Type ( Kind : Option_Kind_Type := Marker) is
record
Next : Option_Ref;
case Kind is
when First_Procedure => First_Procedure : First_Procedure_Type;
when Sec_Procedure => Sec_Procedure : Sec_Procedure_Type;
end case;
end record;
And I get the following Error:
invalid address clause for initialized object "New_Option"
function "Alloc" is not pure (RM 13.1 (22))
Do I get this error because I have a switch case in the type with conditions and therefore the size is only determined depending on kind? How can I avoid this without rewriting everything?
Do I get this error because I have a switch case in the type with conditions and therefore the size is only determined depending on kind?
No. The paragraph referenced by the error message (RM 13.1 (22)) in the LRM reads:
An implementation need not support representation items containing nonstatic expressions, except that an implementation should support a representation item for a given entity if each nonstatic expression in the representation item is a name that statically denotes a constant declared before the entity.
Now, the representation item here is the call to Alloc since your code:
for New_Option use at St_Wa.Alloc(StoragePool => StoragePool,
BitSize => New_Type'Size);
is Ada83-style for
for New_Option'Address use St_Wa.Alloc(StoragePool => StoragePool,
BitSize => New_Type'Size);
And since Alloc (...) is a function call, it is not a static expression, since static functions are, according to RM 4.9:
a predefined operator whose parameter and result types are all scalar types none of which are descendants of formal scalar types;
a predefined concatenation operator whose result type is a string type;
an enumeration literal;
a language-defined attribute that is a function, if the prefix denotes a static scalar subtype, and if the parameter and result types are scalar.
Since Alloc is none of the above, as RM 13.1 states, the implementation does not need to support it in the representation item. However, the actual error message tells us that "Alloc" is not pure, so GNAT tells it it would support this if Alloc was pure.
So one way to fix this would be to make Alloc pure, which means: Add pragma Pure; to the package St_Wa, which contains Alloc. Whether this is possible depends on the package and it might require additional changes.
If this is not feasible, RM 13.1 (22) hints at another way: A nonstatic expression should be supported if it denotes a constant declared before the entity. Thus, this should work:
My_Address : constant System.Address :=
St_Wa.Alloc(StoragePool => StoragePool, BitSize => New_Type'Size);
New_Option : New_Type;
for New_Option use at My_Address;
Using BaseX 8.6 the following use of the serialize function with a map as the second argument works fine:
serialize(<root><foo><bar>test</bar></foo></root>, map { 'indent' : 'yes'})
and outputs the indented code
<root>
<foo>
<bar>test</bar>
</foo>
</root>
However, when I try to run the same code with Saxon 9.7 or AltovaXML Spy they don't compile the query and complain about map { 'indent' : 'yes'} not being a boolean value but a string. https://www.w3.org/TR/xpath-functions-31/#func-serialize defines
indent xs:boolean? true() means "yes", false() means "no"
so I am not quite sure whether that allows only a boolean and is meant to explain its meaning in relation to the serialization values of yes/no or whether it also means using yes or no is allowed.
In BaseX, the map argument was added before it was integrated in the XQFO 3.1 specification. Back then, the most obvious choice was to use the syntax for output declarations in the query prolog (in which only strings can be used for values of serialization parameters). – The new official syntax will be made available in a future version of BaseX.
I get this warning:
WARNING - restricted index type
found : string
required: number
someArray[ index ].doSomething();
This happens after a closure compiler upgrade to the latest version.
It looks like the use of a string type indexes for arrays are not recommended by closure compiler.
What would be the recommended solution to this problem?
BTW. Is there a way to disable check for these warning types (I looked through the CC flags list and can't find anything)?
If your index variable is of type string, you should parse it first.
Try
someArray[parseInt(index)].doSomething();
Additionally, I assume that the reason it's a string in the first place is that it comes from somewhere like a DOM attribute or an HTML input. You might want to make sure the value is valid, before using it.
const parsedIndex = parseInt(index);
if (isNaN(parsedIndex) || index < 0) {
throw 'Invalid index';
}
someArray[parsedIndex].doSomething();
I have just started using Ada, and I'm finding the generic package declarations to be rather silly. Maybe I'm not doing it right, so I'm looking for better options.
Take a look at the below example.
package STD_Code_Maps is new
Ada.Containers.Map(Key_Type => STD_Code_Type;
Element_Type => Ada.Strings.Unbounded.Unbounded_String);
STD_Code_Map : STD_Code_Maps.Map;
-- . . .
procedure Do_Something is
Item : Ada.Strings.Unbounded.Unbounded_String;
begin
Item := STD_Code_Maps.Element(STD_Code_Maps.First(STD_Code_Map));
-- Do something with the Item
-- . . .
end Do_Something;
It would be much cleaner to simply be able to write STD_Code_Map.First.Element instead of the godforsaken STD_Code_Maps.Element(STD_Code_Maps.First(STD_Code_Map));
Obviously I'm doing this wrong -- I think. I'm repeating the phrase STD_Code_Map at least thrice over there. I'm all for verbosity and everything, but really the code I'm writing seems bad and silly to me.
I was wondering if there is solution that doesn't require you to rename the package to something like package Map renames STD_Code_Maps; which would of course shorten the code but I don't want to do this on each and every procedure entry. I really think something like STD_Code_Map.First.Element would be much simpler. Can this be done in Ada 2012?
Note: Using the Unbounded_String package by default is also so difficult. Did the standard library designers actually give much thought to the ridiculous and overly long package hierarchy?
Thanks for reading this, and potentially helping me out. I'm new to Ada.
GNAT GPL 2012 and 2013, and FSF GCC 4.7 and 4.8, support the new container indexing scheme of Ada 2012, which means that you can write
Item := STD_Code_Map ({some Cursor});
And you can do this even with the -gnat05 switch to force Ada 2005 mode! (which has to be a bug).
Ada 2005 allows you to call a primitive function of a tagged type using object.function notation, provided that the first operand is of the tagged type; so you can write STD_Code_Map.First as shorthand for STD_Code_Maps.First (STD_Code_Map).
Putting these together, you can write
Item := STD_Code_Map (STD_Code_Map.First);
which is quite short!
The issue has nothing to do with generics. As Simon pointed out, you can say STD_Code_Map.First, since the type of STD_Code_Map is a tagged type and Ada supports this notation for tagged types. On the other hand, the type of STD_Code_Map.First is a Cursor type, which isn't tagged (making it tagged would have caused problems declaring certain operations that take both a Cursor and a Map). But even without the Ada 2012 container indexing that Simon mentioned, you can say
STD_Code_Maps.Element(STD_Code_Map.First);
which is a little better. Besides renaming a package, you can also rename the function:
function Elem (Position : STD_Code_Maps.Cursor) return STD_Code_Maps.Element_Type
renames STD_Code_Maps.Element;
and you can now use just Elem instead of STD_Code_Maps.Element wherever the renaming is directly visible. (You could call it Element if you want to. The renaming name can be the same or it can be different.) This could be helpful if you use that function a lot.
Ada was designed for readability and maintainability. (written once, read & maintained for much longer) This means that it does get a little verbose at times. If you prefer terse & cryptic there are plenty of other languages out there !
If you want to avoid typing STD_Code_Map all the time, just use a use clause:
use STD_Code_Map;
which would mean your code of
Item := STD_Code_Maps.Element(STD_Code_Maps.First(STD_Code_Map));
would become
Item := Element(First(STD_Code_Map));
Getting names nice and readable in Ada can sometimes be tricky. Often times language designers made the task worse than it had to be, by designing Ada standard library packages for use with Ada use clauses, without a thought to how they'd look to some poor sap who either can't or doesn't want to use that feature.
In this case though, there are things you can do on your own end.
For example "_Maps.Map" is redundant, so why not get rid of it from the package name? Why not use names so that you can write:
package STD_Code is new
Ada.Containers.Map(Key_Type => STD_Code_Type;
Element_Type => Ada.Strings.Unbounded.Unbounded_String);
Map : STD_Code.Map;
-- . . .
procedure Do_Something is
Item : Ada.Strings.Unbounded.Unbounded_String;
begin
Item := STD_Code.Element(STD_Code.First(Map));
-- Do something with the Item
-- . . .
end Do_Something;
Now Code looks like a bit of a null-meaning word too. Everything in a program is a code. So I'd consider ditching it as well. Unsually I name my Ada container packages something that says their basic theoretical function (eg: STD_to_String), while objects are more specific nouns.
Also, I should point out that if your map is constant and you can live with names that look like identifiers, often times you can get rid of maps to strings entirely by using an enumerated type and the 'image attribute.
If you're using Ada 2012 the STD_Code_Maps.Element(STD_Code_Maps.First(STD_Code_Map)); could become:
Function Get_First( Map : STD_Code_Maps.Map ) return Unbounded_String is
( STD_Code_Maps.Element(Map.First) );
That is an example of the new Expression-functions, which were mainly introduced for pre- and post-conditions.
Of course, if you're using Ada 2012 then the precise map you'd likely want is Ada.Containers.Indefinite_Ordered_Maps -- the Indefinite_* containers are those that [can] have indefinite elements, like String.
In addition to TED's comment, using an enumeration when the maps are constant have even more advantages, namely case coverage: the compiler will flag as an error any case-statement that doesn't cover all alternatives. So if you add a new code it will flag all the case-statements that you need to modify. (Of course this benefit is lost when you use the others case.)