Section file_id.
Class FileId := { file_id : Type; stdin : file_id; stdout : file_id }.
Context {FI : FileId}.
Context {E : Type -> Type} `{IO_event(file_id := file_id) -< E} {CS : compspecs}.
Class FileStruct := { abs_file :> FileId; FILEid : ident; reent : ident; f_stdin : ident; f_stdout : ident }.
Context {FS : FileStruct}.
Definition get_reent_spec :=
WITH p : val
PRE [ ]
PROP ()
LOCAL ()
SEP (reent_struct p)
POST [ tptr (Tstruct reent noattr) ]
PROP ()
LOCAL (temp ret_temp p)
SEP (reent_struct p).
Definition fprintf_spec_parametrized FILEid (fmtz: list Z) :=
let fl := interpret_format_string fmtz in
NDmk_funspec
(((1%positive, tptr (Tstruct FILEid noattr)) ::
(2%positive, tptr tschar) ::
format_argtys 3%positive fl),
tint)
{|cc_vararg:=true; cc_unproto:=false; cc_structret:=false|}
(val * share * list byte * val * format_stuff fl * (file_id * IO_itree))
(fun x : (val * share * list byte * val * format_stuff fl * (file_id * IO_itree)) =>
match x with (outp,sh,fmt,fmtp,stuff,(out,k)) =>
PROPx (readable_share sh :: (fmt = map Byte.repr fmtz) ::
PROP_of_format fl stuff)
(LOCALx (temp 1 outp ::
LOCAL_of_format fl 3%positive stuff)
(SEPx (cstring sh fmt fmtp :: file_at out outp :: ITREE (write_list out (string_of_format fl stuff);; k) :: SEP_of_format  fl stuff)))
end)
(fun x : (val * share * list byte * val * format_stuff fl * (file_id * IO_itree)) =>
match x with (outp,sh,fmt,fmtp,stuff,(out,k)) =>
EX n:int,
PROPx nil
(LOCALx (temp ret_temp (Vint n)::nil)
(SEPx (cstring sh fmt fmtp :: file_at out outp :: ITREE k :: SEP_of_format fl stuff)))
end).
Definition printf_spec_parametrized (fmtz: list Z) :=
let fl := interpret_format_string fmtz in
NDmk_funspec
(((1%positive, tptr tschar) ::
format_argtys 2%positive fl),
tint)
{|cc_vararg:=true; cc_unproto:=false; cc_structret:=false|}
(val * share * list byte * val * format_stuff fl * IO_itree)
(fun x : (val * share * list byte * val * format_stuff fl * IO_itree) =>
match x with (outp,sh,fmt,fmtp,stuff,k) =>
PROPx (readable_share sh :: (fmt = map Byte.repr fmtz) ::
PROP_of_format fl stuff)
(LOCALx (LOCAL_of_format fl 2%positive stuff)
(SEPx (cstring sh fmt fmtp :: ITREE (write_list stdout (string_of_format fl stuff);; k) :: SEP_of_format  fl stuff)))
end)
(fun x : (val * share * list byte * val * format_stuff fl * IO_itree) =>
match x with (outp,sh,fmt,fmtp,stuff,k) =>
EX n:int,
PROPx nil
(LOCALx (temp ret_temp (Vint n)::nil)
(SEPx (cstring sh fmt fmtp :: ITREE k :: SEP_of_format fl stuff)))
end).
Definition fprintf_placeholder_spec FILEid : funspec :=
NDmk_funspec
(((1%positive, tptr (Tstruct FILEid noattr)) ::
(2%positive, tptr tschar) :: nil),
tint)
{|cc_vararg:=true; cc_unproto:=false; cc_structret:=false|}
unit
(fun x : unit =>  PROP (False) LOCAL () SEP ())
(fun x : unit =>  PROP () LOCAL () SEP ()).
Definition printf_placeholder_spec : funspec :=
NDmk_funspec
(((1%positive, tptr tschar) :: nil),
tint)
{|cc_vararg:=true; cc_unproto:=false; cc_structret:=false|}
unit
(fun x : unit =>  PROP (False) LOCAL () SEP ())
(fun x : unit =>  PROP () LOCAL () SEP ()).

Axiom printf_spec_sub:
forall fmtz,
funspec_sub (printf_placeholder_spec)
(printf_spec_parametrized fmtz).