~ubuntu-branches/debian/sid/frama-c/sid

« back to all changes in this revision

Viewing changes to src/project/project.mli

  • Committer: Bazaar Package Importer
  • Author(s): Mehdi Dogguy
  • Date: 2009-06-03 08:19:25 UTC
  • Revision ID: james.westby@ubuntu.com-20090603081925-kihvxvt0wy3zc4ar
Tags: upstream-20081201.dfsg
ImportĀ upstreamĀ versionĀ 20081201.dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
(**************************************************************************)
 
2
(*                                                                        *)
 
3
(*  This file is part of Frama-C.                                         *)
 
4
(*                                                                        *)
 
5
(*  Copyright (C) 2007-2008                                               *)
 
6
(*    CEA (Commissariat ļæ½ l'ļæ½nergie Atomique)                             *)
 
7
(*                                                                        *)
 
8
(*  you can redistribute it and/or modify it under the terms of the GNU   *)
 
9
(*  Lesser General Public License as published by the Free Software       *)
 
10
(*  Foundation, version 2.1.                                              *)
 
11
(*                                                                        *)
 
12
(*  It is distributed in the hope that it will be useful,                 *)
 
13
(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)
 
14
(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *)
 
15
(*  GNU Lesser General Public License for more details.                   *)
 
16
(*                                                                        *)
 
17
(*  See the GNU Lesser General Public License version 2.1                 *)
 
18
(*  for more details (enclosed in the file licenses/LGPLv2.1).            *)
 
19
(*                                                                        *)
 
20
(**************************************************************************)
 
21
 
 
22
(* $Id: project.mli,v 1.28 2008/12/12 12:46:33 uid581 Exp $ *)
 
23
 
 
24
(** Projects management.
 
25
 
 
26
    A project groups together all the internal states of Frama-C. An internal
 
27
    state is roughly the result of a computation which depends of an AST. It is
 
28
    possible to have many projects at the same time. For registering a new
 
29
    state in the Frama-C projects, apply the functor {!Computation.Register}.
 
30
 
 
31
    @plugin development guide *)
 
32
 
 
33
val set_debug_level: int -> unit
 
34
  (** Set the level of debug: 0 = no level; 1 = small debugging messages and so
 
35
      on. *)
 
36
 
 
37
(* ************************************************************************* *)
 
38
(** {2 Datatypes} *)
 
39
(* ************************************************************************* *)
 
40
 
 
41
type t
 
42
  (** Type of a project.
 
43
      @plugin development guide *)
 
44
 
 
45
type project = t
 
46
    (** Alias for the project type. *)
 
47
 
 
48
val repr: t Type.t
 
49
  (** Identifier for type [t]. *)
 
50
 
 
51
val dummy: t
 
52
  (** A dummy project: should only be used to initialized reference but must
 
53
      never be put something inside. *)
 
54
 
 
55
(* ************************************************************************* *)
 
56
(** {2 Kinds dealing with Project}
 
57
 
 
58
    There are two kinds of kinds in Frama-C: datatypes and computations. They
 
59
    are merely used for theirs dependencies:
 
60
    - The datatypes dependencies are useful when loading: mainly we have to
 
61
    re-hashcons all the values in a "good" order.
 
62
    - The computations dependencies are useful for actions which use
 
63
    selection (e.g. project copying): for example, we have to be able to
 
64
    copying some states with all their dependencies. *)
 
65
(* ************************************************************************* *)
 
66
 
 
67
(** Common signature of kinds.
 
68
    @see <kind.html> kind. *)
 
69
module type KIND = sig
 
70
 
 
71
  type t
 
72
    (** Type of kinds. *)
 
73
 
 
74
  val dummy : t
 
75
    (** A dummy kind.
 
76
        @plugin development guide *)
 
77
 
 
78
  val name: t -> string
 
79
    (** Name of a kind. *)
 
80
 
 
81
  val add_dependency: t -> t -> unit
 
82
    (** [add_dependency k1 k2] indicates that the state kind [k1] depends on
 
83
        the state kind [k2], that is an action of the state kind [k2] must be
 
84
        done before one of the state kind [k1]. Actions are cleaning, copying,
 
85
        loading and saving.
 
86
        @plugin development guide *)
 
87
 
 
88
end
 
89
 
 
90
val identity: 'a -> 'a
 
91
  (** The identity function. *)
 
92
 
 
93
val is_identity: ('a -> 'a) -> bool
 
94
  (** @return true iff the given function is (physically) {!identity}. *)
 
95
 
 
96
(** Datatype implementation and how to register them. *)
 
97
module Datatype : sig
 
98
 
 
99
  module type INPUT = sig
 
100
 
 
101
    type t
 
102
      (** The datatype to register. *)
 
103
 
 
104
    val rehash: t -> t
 
105
      (** How to rehashcons the datatype. *)
 
106
 
 
107
    val copy: t -> t
 
108
      (** How to deeply copy the datatype.
 
109
          The following invariant must hold: forall (p:t), copy s != s. *)
 
110
 
 
111
    val name: string
 
112
      (** Name of the datatype.
 
113
          Have to be different of others registered datatypes. *)
 
114
 
 
115
  end
 
116
 
 
117
  (** Output of {!Datatype.Register}. *)
 
118
  module type S = sig
 
119
 
 
120
    include INPUT
 
121
      (** Exportation of inputs (easier use of [Datatype.Register]). *)
 
122
 
 
123
    val register_comparable:
 
124
      ?compare:(t -> t -> int) ->
 
125
      ?equal:(t -> t -> bool) ->
 
126
      ?hash:(t -> int) ->
 
127
      ?physical_hash:(t -> int) ->
 
128
      unit -> unit
 
129
      (** Allow to register a specific [compare], [equal], [hash] and
 
130
          [physical_hash] functions for the datatype.
 
131
 
 
132
          [hash] and [equal] have to be compatible, that is:
 
133
          forall x y, equal x y ==> hash x = hash y.
 
134
 
 
135
          [physical_hash] has to be compatible with physical equality (==),
 
136
          that is:
 
137
          forall x y, x == y ==> physical_hash x = physical_hash y.
 
138
 
 
139
          - default value for [compare] is [Pervasives.compare];
 
140
          - default value for [equal] is [fun x y -> compare x y = 0] if
 
141
          [compare] is provided; (=) otherwise.
 
142
          - default value for [hash] is Hashtbl.hash;
 
143
          - default value for [physical_hash] is [hash] if it is provided;
 
144
          [Hashtbl.hash] otherwise.
 
145
 
 
146
          Never call [registered_comparable] is equivalent to call
 
147
          [register_comparable ()].
 
148
 
 
149
          Note that, as usual in ocaml, the default values for [equal] and
 
150
          [hash] are not compatible for all datastructures (though for the most
 
151
          ones). *)
 
152
 
 
153
    val is_comparable_set: unit -> bool
 
154
      (** @return false if [register_comparable] has never been called. *)
 
155
 
 
156
    (** {3 Access to the functions registered by [registered_comparable]} *)
 
157
 
 
158
    val hash: t -> int
 
159
    val physical_hash: t -> int
 
160
    val equal: t -> t -> bool
 
161
    val compare: t -> t -> int
 
162
 
 
163
  end
 
164
 
 
165
  (** Register a new kind of datatype by side-effects.
 
166
      @plugin development guide *)
 
167
  module Register(Datatype:INPUT) : S with type t = Datatype.t
 
168
 
 
169
  (** Register a single datatype, not affected by hashconsing.
 
170
      @plugin development guide *)
 
171
  module Imperative(X:sig type t val copy: t -> t val name: string end) :
 
172
    S with type t = X.t
 
173
 
 
174
  (** Register a single datatype, not affected by hashconsing and copying.
 
175
      @plugin development guide *)
 
176
  module Persistent(X:sig type t val name: string end) :
 
177
    S with type t = X.t
 
178
 
 
179
  (** {3 Create a name from predefined ones}
 
180
 
 
181
      See module {!Namespace}. *)
 
182
 
 
183
  val extend_name: string -> string -> string
 
184
  val extend_name2: string -> string -> string -> string
 
185
  val extend_name3: string -> string -> string -> string -> string
 
186
 
 
187
end
 
188
 
 
189
(** Internal state (aka Computation) representation and how to register them.
 
190
    An internal state contains the result of a computation. *)
 
191
module Computation : sig
 
192
 
 
193
  include KIND
 
194
    (** Common operations. *)
 
195
 
 
196
  type selection
 
197
    (** Just an alias for [Project.Selection.t]. *)
 
198
 
 
199
  (** Main input signature of {!Computation.Register}. *)
 
200
  module type INPUT = sig
 
201
 
 
202
    type t
 
203
      (** Type of the state to register. *)
 
204
 
 
205
    val create: unit -> t
 
206
      (** How to create a new fresh state which must be equal to the initial
 
207
          state: that is, if you never change the state, [create ()] and [get
 
208
          ()] must be equal (see invariant 1 below). *)
 
209
 
 
210
    val clear: t -> unit
 
211
      (** How to clear a state. After cleaning, the state should be
 
212
          observationaly the same that after its creation (see invariant 2
 
213
          below).
 
214
          @plugin development guide *)
 
215
 
 
216
    val get: unit -> t
 
217
      (** How to access to the current state. Be aware of invariants 3 and 4
 
218
          below. *)
 
219
 
 
220
    val set: t -> unit
 
221
      (** How to change the current state. Be aware of invariants 3 and 4
 
222
          below. *)
 
223
 
 
224
  (** The four following invariants must hold.
 
225
      {ol
 
226
      {- [create ()] returns a fresh value}
 
227
      {- forall [(p:t)] [copy p] returns a fresh value}
 
228
      {- forall [(p:t)], [create () = (clear p; set p; get ())]}
 
229
      {- forall [(p1:t),(p2:t)] such that [p1 != p2], [(set p1; get ()) != s2]}
 
230
      } *)
 
231
  end
 
232
 
 
233
  (** Some additional informations used by {!Computation.Register}. *)
 
234
  module type INFO = sig
 
235
    val name: string (** Name of the internal state. *)
 
236
    val dependencies : t list (** Dependencies of this internal state. *)
 
237
  end
 
238
 
 
239
  (** Output signature of {!Computation.Register}. *)
 
240
  module type OUTPUT = sig
 
241
 
 
242
    val self: t
 
243
      (** The kind of the registered state.
 
244
          @plugin development guide *)
 
245
 
 
246
    val select: Kind.how -> selection -> selection
 
247
      (** [select sel] add the registered state to the given selection in a
 
248
          functional way. *)
 
249
 
 
250
    val depend: t -> unit
 
251
      (** [depend k] adds a dependencies from [k] to [me]. *)
 
252
 
 
253
    val mark_as_computed: ?project:project -> unit -> unit
 
254
      (** Indicate that the registered state will not change again for the
 
255
          given project (default is [current ()]). *)
 
256
 
 
257
    val is_computed: ?project:project -> unit -> bool
 
258
      (** Returns [true] iff the registered state will not change again for the
 
259
          given project (default is [current ()]). *)
 
260
 
 
261
    val do_not_save: unit -> unit
 
262
      (** Call this function if the registered state must not be save/load
 
263
          on/from disk. When loading, a new state (generated using [create]) is
 
264
          used instead. *)
 
265
 
 
266
    (** Exportation of some inputs (easier use of [Computation.Register]). *)
 
267
 
 
268
    module Datatype: Datatype.S
 
269
    val name: string
 
270
 
 
271
  end
 
272
 
 
273
  (** [Register(Datatype)(State)(Info)] registers a new kind of computation by
 
274
      side-effect.
 
275
      [Datatype] represents the datatype of a state, [State] explains how to
 
276
      deal with a state and [Info] mainly details the dependencies of the
 
277
      computation (i.e. what computations should be done before this one).
 
278
      @plugin development guide *)
 
279
  module Register
 
280
    (Datatype: Datatype.S)
 
281
    (State: INPUT with type t = Datatype.t)
 
282
    (Info: INFO)
 
283
    : OUTPUT with module Datatype = Datatype
 
284
 
 
285
  val dump_dependencies:
 
286
    ?only:selection -> ?except:selection -> string -> unit
 
287
    (** Debugging purpose only. *)
 
288
 
 
289
end
 
290
 
 
291
(** Selection of kinds of computation.
 
292
    @plugin development guide *)
 
293
module Selection : Kind.SELECTION with type kind = Computation.t
 
294
                                  and type t = Computation.selection
 
295
 
 
296
(* ************************************************************************* *)
 
297
(** {2 Operations on all projects} *)
 
298
(* ************************************************************************* *)
 
299
 
 
300
val create: string -> t
 
301
  (** Create a new project with the given name and attach it after the existing
 
302
      projects (so the current project, if existing, is unchanged).
 
303
      The given name may be already used by another project.
 
304
      @plugin development guide *)
 
305
 
 
306
val register_create_hook: (t -> unit) -> unit
 
307
  (** [register_create_hook f] adds a hook on function [create]: each time a
 
308
      new project [p] is created, [f p] is applied.
 
309
 
 
310
      The order in which hooks are applied is the same than the order in which
 
311
      hooks are registered. *)
 
312
 
 
313
exception NoProject
 
314
  (** May be raised by [current]. *)
 
315
 
 
316
val current: unit -> t
 
317
  (** The current project.
 
318
      @raise NoProject if there is no project.
 
319
      @plugin development guide *)
 
320
 
 
321
val is_current: t -> bool
 
322
  (** Check whether the given project is the current one or not. *)
 
323
 
 
324
val iter_on_projects: (t -> unit) -> unit
 
325
  (** iteration on project starting with the current one. *)
 
326
 
 
327
val find_all: string -> t list
 
328
  (** Find all projects with the given name. *)
 
329
 
 
330
val clear_all: unit -> unit
 
331
  (** Clear all the projects: all the internal states of all the projects are
 
332
      now empty (wrt the action registered with {!register_todo_on_clear}). *)
 
333
 
 
334
(** {3 Inputs/Outputs} *)
 
335
 
 
336
exception IOError of string
 
337
  (** @plugin development guide *)
 
338
 
 
339
val save_all: string -> unit
 
340
  (** Save all the projects in a file.
 
341
      @raise IOError a project cannot be saved.
 
342
  *)
 
343
 
 
344
val load_all: string -> unit
 
345
  (** Load all the projects from a file.
 
346
      For each project to load, the specification is the same than
 
347
      {!Project.load}.
 
348
      @raise IOError if a project cannot be loaded.
 
349
      @plugin development guide *)
 
350
 
 
351
val register_before_load_hook: (unit -> unit) -> unit
 
352
  (** [register_before_load_hook f] adds a hook called just before loading
 
353
      **each project** (more precisely, the project exists but is empty while
 
354
      the hook is applied): if [n] projects are on disk, the same hook will be
 
355
      called [n] times (one call by project).
 
356
 
 
357
      Besides, for each project, the order in which the hooks are applied is
 
358
      the same than the order in which hooks are registered. *)
 
359
 
 
360
val register_after_load_hook: (unit -> unit) -> unit
 
361
  (** [register_before_load_hook f] adds a hook called just after loading
 
362
      **each project**: if [n] projects are on disk, the same hook will be
 
363
      called [n] times (one call by project).
 
364
 
 
365
      Besides, for each project, the order in which the hooks are applied is
 
366
      the same than the order in which hooks are registered. *)
 
367
 
 
368
(* ************************************************************************* *)
 
369
(** {2 Operations on one project}
 
370
 
 
371
    Most operations have two optional arguments, called [only] and [except] of
 
372
    type [selection].
 
373
    - If [only] is specified, only the selected state kinds are copied.
 
374
    - If [except] is specified, those selected state kinds are not copied (even
 
375
    if they are also selected by [only]).
 
376
    Use it carefuly because Frama-C may become lost and inconsistent if these
 
377
    specifications are incorrects. *)
 
378
(* ************************************************************************* *)
 
379
 
 
380
val name: t -> string
 
381
  (** Project name. Two projects may have the same name. *)
 
382
 
 
383
val unique_name: t -> string
 
384
  (** Return a project name based on {!name} but different of each others
 
385
      [unique_name]. *)
 
386
 
 
387
val from_unique_name: string -> t
 
388
  (** Return a project based on {!unique_name}.
 
389
      @raise Not_found if no project has this unique name.
 
390
  *)
 
391
 
 
392
val set_current: ?only:Selection.t -> ?except:Selection.t -> t -> unit
 
393
  (** Set the current project with the given one.
 
394
      @raise Invalid_argument if the given project does not exist anymore.
 
395
      @plugin development guide *)
 
396
 
 
397
val register_after_set_current_hook: user_only:bool -> (unit -> unit) -> unit
 
398
  (** [register_after_set_current_hook f] adds a hook on function
 
399
      {!set_current}.
 
400
      - If [user_only] is [true], then each time {!set_current} is directly
 
401
      called by an user of this library, [f ()] is applied.
 
402
      - If [user_only] is [false], then each time {!set_current} is applied
 
403
      (even indirectly through {!Project.on}), [f ()] is applied.
 
404
      The order in which each hook is applied is unspecified. *)
 
405
 
 
406
val on:
 
407
  ?only:Selection.t -> ?except:Selection.t -> t -> ('a -> 'b) -> 'a -> 'b
 
408
  (** [on p f x] sets the current project to [p], computes [f x] then
 
409
      restores the current project. You should use this function if you use a
 
410
      project different of [current ()].
 
411
      @plugin development guide *)
 
412
 
 
413
val copy:
 
414
  ?only:Selection.t -> ?except:Selection.t -> ?src:t -> t -> unit
 
415
  (** Copy a project into another one. Default project for [src] is [current
 
416
      ()]. Replace the destination by [src].
 
417
      @plugin development guide *)
 
418
 
 
419
val clear:
 
420
  ?only:Selection.t -> ?except:Selection.t -> ?project:t -> unit -> unit
 
421
  (** Clear the given project. Default project is [current ()]. All the
 
422
      internal states of the given project are now empty (wrt the action
 
423
      registered with {!register_todo_on_clear}). *)
 
424
 
 
425
val register_todo_on_clear: (unit -> unit) -> unit
 
426
  (** Register action to perform just before clearing a project. *)
 
427
 
 
428
val remove: ?project:t -> unit -> unit
 
429
  (** Default project is [current ()]. If the current project is removed, then
 
430
      the new current project is the previous current project if it still
 
431
      exists (and so on). *)
 
432
 
 
433
(** {3 Projects are comparable values} *)
 
434
 
 
435
val compare: t -> t -> int
 
436
val equal: t -> t -> bool
 
437
val hash: t -> int
 
438
 
 
439
(** {3 Inputs/Outputs} *)
 
440
 
 
441
val save:
 
442
  ?only:Selection.t -> ?except:Selection.t -> ?project:t -> string -> unit
 
443
  (** Save a given project in a file. Default project is [current ()].
 
444
      @raise IOError if the project cannot be saved.
 
445
      @plugin development guide *)
 
446
 
 
447
val load:
 
448
  ?only:Selection.t -> ?except:Selection.t -> name:string -> string -> t
 
449
  (** Load a file into a new project given by its name.
 
450
      More precisely, [load only except name file]:
 
451
      {ol
 
452
      {- creates a new project;}
 
453
      {- performs all the registered [before_load] actions, following the
 
454
      datatype dependencies;}
 
455
      {- loads the (specified) states of the project and rehashcons them
 
456
      (following the computation dependencies); and}
 
457
      {- performs all the registered [after_load] actions.}
 
458
      }
 
459
      @raise IOError if the project cannot be loaded
 
460
      @return the new project containing the loaded data.
 
461
      @plugin development guide *)
 
462
 
 
463
(*
 
464
  Local Variables:
 
465
  compile-command: "LC_ALL=C make -C ../.. -j"
 
466
  End:
 
467
*)