123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126(**************************************************************************)(* *)(* This file is part of Frama-C. *)(* *)(* Copyright (C) 2007-2023 *)(* CEA (Commissariat à l'énergie atomique et aux énergies *)(* alternatives) *)(* *)(* you can redistribute it and/or modify it under the terms of the GNU *)(* Lesser General Public License as published by the Free Software *)(* Foundation, version 2.1. *)(* *)(* It is distributed in the hope that it will be useful, *)(* but WITHOUT ANY WARRANTY; without even the implied warranty of *)(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *)(* GNU Lesser General Public License for more details. *)(* *)(* See the GNU Lesser General Public License version 2.1 *)(* for more details (enclosed in the file licenses/LGPLv2.1). *)(* *)(**************************************************************************)typeenv={mutablecurrent_section:string;mutableis_markdown:bool;mutablecurrent_markdown:stringlist;(* markdown lines of current element, in reverse order. *)mutableremarks:Markdown.elementlistDatatype.String.Map.t}letdkey=Mdr_params.register_category"remarks"letempty_env()={current_section="";is_markdown=false;current_markdown=[];remarks=Datatype.String.Map.empty}letadd_channelenvchan=trywhiletruedolets=input_linechaninenv.current_markdown<-s::env.current_markdown;done;withEnd_of_file->()letbeg_markdown=Str.regexp_string"<!-- BEGIN_REMARK -->"letend_markdown=Str.regexp_string"<!-- END_REMARK -->"letinclude_markdown=Str.regexp"<!-- INCLUDE \\(.*\\) -->"letis_section=Str.regexp"^#[^{]*{#+\\([^}]*\\)}"letcleanup_blanksl=letrecaux=function""::l->auxl|l->linaux(List.rev(auxl))letparse_lineenvline=ifenv.is_markdownthenbeginifStr.string_matchend_markdownline0thenbeginletremark=cleanup_blanksenv.current_markdowninletremark=matchremarkwith|[]->Mdr_params.debug~dkey"Empty remark for section %s"env.current_section;[]|_->letres=Markdown.Rawremarkinletpage=""inMdr_params.debug~dkey"Remark for section %s:@\n%a"env.current_section(Markdown.pp_element~page)res;[res]inenv.remarks<-Datatype.String.Map.addenv.current_sectionremarkenv.remarks;env.current_markdown<-[];env.is_markdown<-falseendelseifStr.string_matchinclude_markdownline0thenbeginletf=Str.matched_group1lineinMdr_params.debug~dkey"Remark for section %s in file %s"env.current_sectionf;tryletchan=open_infinadd_channelenvchan;close_inchanwithSys_errorerr->Mdr_params.error"Unable to open included remarks file %s (%s), Ignoring."ferrendelsebeginenv.current_markdown<-line::env.current_markdown;endendelseifStr.string_matchbeg_markdownline0thenbeginMdr_params.debug~dkey"Checking remarks for section %s"env.current_section;env.is_markdown<-trueendelseifStr.string_matchis_sectionline0thenbeginletsec=Str.matched_group1lineinMdr_params.debug~dkey"Entering section %s"sec;env.current_section<-secendletparse_remarksenvchan=trywhiletruedolets=input_linechaninparse_lineenvsdone;assertfalsewithEnd_of_file->close_inchan;envletget_remarksf=Mdr_params.debug~dkey"Using remarks file %a"Filepath.Normalized.prettyf;tryletchan=open_in(f:>string)inlet{remarks}=parse_remarks(empty_env())chaninremarkswithSys_errorerr->Mdr_params.error"Unable to open remarks file %a (%s). \
No additional remarks will be included in the report."Filepath.Normalized.prettyferr;Datatype.String.Map.empty