Frama-C: Add Annotation in Plugin - plugins

I am writing a Frama-C-plugin. In this plugin, I want to add annotations to functions (e.g. if function name = "test", add a requires clause, saying parameter == 1).
I found the function Annotations.add_requires, but I don't know some of the parameters (Emitter.t, Identified_predicates). Is the string-parameter the function name or an own name for the predicate?
How do I use this function?
Can anyone show an example?

The emitter identify your plugin and has to declare what it is suppose to modify. In your case, as you want to add properties to the specifications, you can build it with:
let emitter = Emitter.create "My plugin" [ Emitter.Funspec ]
~correctness:[] ~tuning:[]
Now, for a kernel_function this is an example of how to build a precondition saying that the first parameter is equal to one:
let add_pre kf = match Kernel_function.get_formals kf with
| [] -> ()
| c_var::_ ->
let l_var = Cil.cvar_to_lvar c_var in
let var_term = Logic_const.tvar l_var in
let cnst_term = Logic_const.tinteger 1 in
let eq_pred = Logic_const.prel (Cil_types.Req, var_term, cnst_term) in
let pred = Logic_const.new_predicate eq_pred in
let bname = Cil.default_behavior_name in
Annotations.add_requires emitter kf ~behavior:bname [pred]

Related

How to Specify field MongoDB Definition dynamically using a string in F#

I started out using quite strongly typed definitions
let coll: IMongoCollection<NZPostDataItem> = MongoUtil.getNzpostCollection()
let filter = Builders<NZPostDataItem>.Filter.And(
Builders<NZPostDataItem>.Filter.Gte((fun n -> n.dateLodged),DateTime(2020,10,1)),
Builders<NZPostDataItem>.Filter.Eq((fun n -> n.eshipMatched.Value) , true)
)// ... etc
The problem is, I need to dynamically run a query because one of the objects contains a BSONDocument
let coll: IMongoCollection<NZPostDataItem> = MongoUtil.getNzpostCollection()
let t = Nullable<bool> true
let filter =
FilterDefinition<BsonDocument>.op_Implicit(
"{
eshipMatched:true,
'eship.order.carrier_service_code':'TDEAUS',
dateLodged: {$gte: new Date('01-Oct-2020')}}
)"
)
Which works directly on MongoDB. But when I try and query it, I get a compile time error.
let results = coll.Find(filter).Limit(10000).ToList<NZPostDataItem>()
Severity Code Description Project File Line Suppression State
Error FS0041 No overloads match for method 'Find'.
Known type of argument: FilterDefinition
Available overloads:
- (extension) IMongoCollection.Find<'TDocument>(filter: FilterDefinition<'TDocument>,?options:
FindOptions) : IFindFluent<'TDocument,'TDocument> // Argument 'filter' doesn't match
- (extension) IMongoCollection.Find<'TDocument>(filter:
Linq.Expressions.Expression<Func<'TDocument,bool>>,?options: FindOptions) :
IFindFluent<'TDocument,'TDocument> // Argument 'filter' doesn't match
So - I can sort of see what is wrong - maybe 2 types of definitions - but I need to filter dynamically but return a strongly typed object.
As you said, you want the filter to be both dynamic and strongly-typed, so that's what you should create:
let filter =
FilterDefinition<NZPostDataItem>.op_Implicit("{ ... }")

Use Measurement for input in NSTextFieldCell

I want to be able to nicely use a Measurement and MeasurementFormatter for output and input with a NSTextFieldCell.
I am able to display the measurement correctly with...
let areaFormatter = MeasurementFormatter()
areaFormatter.unitStyle = .medium
areaFormatter.unitOptions = .providedUnit
let area = Measurement<UnitArea>( value: 123.43, unit: .squareInches)
let editInput = NSTextFieldCell
editInput.objectValue = area
editInput.formatter = areaFormatter
This displays something like
123.43 in^2
The problem starts when I want to read this back in with
var inputArea = editInput.objectValue as! Measurement<UnitArea>
I think because the get Object value of the Measurement Formatter is not defined.
open func getObjectValue(_ obj: AutoreleasingUnsafeMutablePointer<AnyObject?>?, for string: String, errorDescription error: AutoreleasingUnsafeMutablePointer<NSString?>?) -> Bool
Is my understanding correct? Are there any examples in Swift where this function has been defined for measurements?
Right now the user can edit the entire string including the text in the units. Is there a good way to block the units in the NSTextFieldCell? I would like the user to be able to edit the number but not the units and then return the measurement with
var inputArea = editInput.objectValue as! Measurement<UnitArea>
so this gets displayed
123.43 in^2
but only the 123.43 can be edited.

How to build a query object for Realm

I am building an iOS app using Swift.
I am using Realm as database.
I am currently building a search functionality for a tableview.
This is my filter query
items = realm.objects(Book).filter(predicate).filter("state IN {'pending','activated','completed','closed'}")
I am saving what states a user wants to filter on in another model called Filter.
How can I build this {'pending','activated','completed','closed'} from the output of the following filter query (title is the attribute)? What is this object called?
realm.objects(Filter).filter("type = 'filter' AND activated = 'true'")
The right-hand side of the IN operator can take a substitution placeholder (%#) that can have an NSArray (or other enumerable object) substituted in.
Assuming your Filter model looks something like:
class Filter: Object {
dynamic var type: String = ""
dynamic var activated: bool = false
dynamic var state: String = ""
}
You can do something like the following to construct the query you're after:
let activeFilters = realm.objects(Filter).filter("type = 'filter' AND activated = 'true'")
let activeStates = activeFilters.valueForKey("state") as! [String]!
let items = realm.objects(Book).filter(predicate).filter("state IN %#", activeStates)

Is it possible to expand a tuple expression into a comma-separated list in a Rust syntax extension with quasiquoting?

I'm writing a syntax extension for Rust and I want to generate a tuple expression using quote_expr!. What I do now is:
let tuple_values: Vec<P<Expr>> = ...;
let tuple_expr: cx.expr_tuple(sp, tuple_value);
let e = quote_stmt!(cx, let v = $tuple_expr);
It works, but I want to write something like:
let tuple_values: Vec<P<Expr>> = ...;
let e = quote_stmt!(cx, let v = ($tuple_values..));
i.e. expand tuple_values into a comma-separated list. Is it possible?

Change variable during runtime

I have an enum:
type Tool =
| Rectangle = 0
| Circle = 1
And a variable to hold a enum value:
let mutable selectedTool : Tool = Tool.Rectangle
I have two buttons:
let btn (location:Point) (size:Size) =
let bt = new Button()
do bt.Location <- location
do bt.Size <- size
bt
// These badboys right here:
let rectangleButton = btn (Point(0, 0)) (Size(50,50))
let ellipseButton = btn (Point(50, 0)) (Size(50,50))
They each have an event connected to them:
let btnRectEvent = rectangleButton.Click.Add(fun(x) -> selectedTool <-Tool.Rectangle)
let btnElliEvent = ellipseButton.Click.Add(fun(x) -> selectedTool <- Tool.Circle)
I want my events to change the value of the selectedTool variable.
Currently, it doesen't work.
I then record my MouseDown event on my drawing area to draw a shape using this event:
let mouseEvent =
let x = selectedTool
form.MouseDown
|> Event.add ( fun (evArgs1) ->
if x = Tool.Circle then
graphics.Graphics.DrawEllipse(whitePen, evArgs1.X, evArgs1.Y, 15, 15)
else
graphics.Graphics.DrawRectangle(whitePen, evArgs1.X, evArgs1.Y, 15, 15)
form.Refresh())
form is running as follows:
form.Controls.Add(rectangleButton)
form.Controls.Add(ellipseButton)
form.Show()
while form.Created do
Application.DoEvents()
Bonus Question but not in need of answering:
Is it possible to catch a click event on the button, wait for a mousedown event on the drawing area, place the first corner of my shape, have a preview of the shape when I'm moving my mouse around, and set the second corner on mouseUp, in an not-too-overkill way?
TL;DR bonus question: Can I easily make the rectangledrawing work like in MSPaint?
So I spotted the problem:
when you do
let x = selectedTool
form.MouseDown
|> Event.add ( fun (evArgs1) ->
Something goes here
Inside the lambda x won't change. You probably want to either get rid of the let x = ... before the lambda or use a ref cell like this:
let selectedTool = ref Rectangle
then you assign with
selectedTool := Circle
and get the value with
if (!selectedTool) = Circle
Although a match would be more common - like so
form.MouseDown
|> Event.add ( fun (evArgs1) ->
match (!selectedTool) with
|Circle -> graphics.Graphics.DrawEllipse(whitePen, evArgs1.X, evArgs1.Y, 15, 15)
|Rectangle -> graphics.Graphics.DrawRectangle(whitePen, evArgs1.X, evArgs1.Y, 15,15)
form.Refresh())