blob: 9d289fb45ff2405adaeb0aa97130993c4f1d7e5b [file] [log] [blame]
------------------------------------------------------------------------------
-- --
-- GNAT COMPILER COMPONENTS --
-- --
-- J S O N _ U T I L S --
-- --
-- B o d y --
-- --
-- Copyright (C) 1992-2025, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
-- ware Foundation; either version 3, or (at your option) any later ver- --
-- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
-- for more details. You should have received a copy of the GNU General --
-- Public License distributed with GNAT; see file COPYING3. If not, go to --
-- http://www.gnu.org/licenses for a complete copy of the license. --
-- --
-- GNAT was originally developed by the GNAT team at New York University. --
-- Extensive contributions were provided by Ada Core Technologies Inc. --
-- --
------------------------------------------------------------------------------
with Namet; use Namet;
with Osint;
with Output; use Output;
with System.OS_Lib;
package body JSON_Utils is
-----------------
-- Begin_Block --
-----------------
procedure Begin_Block is
begin
Indent_Level := Indent_Level + 1;
end Begin_Block;
---------------
-- End_Block --
---------------
procedure End_Block is
begin
Indent_Level := Indent_Level - 1;
end End_Block;
procedure Indent is begin
if JSON_FORMATTING then
for I in 1 .. INDENT_SIZE * Indent_Level loop
Write_Char (' ');
end loop;
end if;
end Indent;
-------------------
-- NL_And_Indent --
-------------------
procedure NL_And_Indent is
begin
if JSON_FORMATTING then
Write_Eol;
Indent;
end if;
end NL_And_Indent;
-----------------
-- To_File_Uri --
-----------------
function To_File_Uri (Path : String) return String is
function Normalize_Uri (Path : String) return String;
-- Construct a normalized URI from the path name by replacing reserved
-- URI characters that can appear in paths with their escape character
-- combinations.
--
-- According to the URI standard reserved charcthers within the paths
-- should be percent encoded:
--
-- https://www.rfc-editor.org/info/rfc3986
--
-- Reserved charcters are defined as:
--
-- reserved = gen-delims / sub-delims
-- gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@"
-- sub-delims = "!" / "$" / "&" / "’" / "(" / ")"
-- / "*" / "+" / "," / ";" / "="
-------------------
-- Normalize_Uri --
-------------------
function Normalize_Uri (Path : String) return String is
Buf : Bounded_String;
begin
for C of Path loop
case C is
when '\' =>
-- Use forward slashes instead of backward slashes as
-- separators on Windows and on Linux simply encode the
-- symbol if part of a directory name.
if Osint.On_Windows then
Append (Buf, '/');
else
Append (Buf, "%5C");
end if;
when ' ' =>
Append (Buf, "%20");
when '!' =>
Append (Buf, "%21");
when '#' =>
Append (Buf, "%23");
when '$' =>
Append (Buf, "%24");
when '&' =>
Append (Buf, "%26");
when ''' =>
Append (Buf, "%27");
when '(' =>
Append (Buf, "%28");
when ')' =>
Append (Buf, "%29");
when '*' =>
Append (Buf, "%2A");
when '+' =>
Append (Buf, "%2A");
when ',' =>
Append (Buf, "%2A");
when '/' =>
-- Forward slash is a valid file separator on both Unix and
-- Windows based machines and should be treated as such
-- within a path.
Append (Buf, '/');
when ':' =>
Append (Buf, "%3A");
when ';' =>
Append (Buf, "%3B");
when '=' =>
Append (Buf, "%3D");
when '?' =>
Append (Buf, "%3F");
when '@' =>
Append (Buf, "%40");
when '[' =>
Append (Buf, "%5B");
when ']' =>
Append (Buf, "%5D");
when others =>
Append (Buf, C);
end case;
end loop;
return To_String (Buf);
end Normalize_Uri;
Norm_Uri : constant String := Normalize_Uri (Path);
-- Start of processing for To_File_Uri
begin
if System.OS_Lib.Is_Absolute_Path (Path) then
-- URI-s using the file scheme should start with the following
-- prefix:
--
-- "file:///"
if Osint.On_Windows then
return "file:///" & Norm_Uri;
else
-- Full paths on linux based systems already start with '/'
return "file://" & Norm_Uri;
end if;
else
return Norm_Uri;
end if;
end To_File_Uri;
-----------------------------
-- Write_Boolean_Attribute --
-----------------------------
procedure Write_Boolean_Attribute (Name : String; Value : Boolean) is
begin
Write_Str ("""" & Name & """" & ": ");
Write_Str (if Value then "true" else "false");
end Write_Boolean_Attribute;
-------------------------
-- Write_Int_Attribute --
-------------------------
procedure Write_Int_Attribute (Name : String; Value : Int) is
begin
Write_Str ("""" & Name & """" & ": ");
Write_Int (Value);
end Write_Int_Attribute;
-------------------------------
-- Write_JSON_Escaped_String --
-------------------------------
procedure Write_JSON_Escaped_String (Str : String) is
begin
for C of Str loop
if C = '"' or else C = '\' then
Write_Char ('\');
end if;
Write_Char (C);
end loop;
end Write_JSON_Escaped_String;
----------------------------
-- Write_String_Attribute --
----------------------------
procedure Write_String_Attribute (Name : String; Value : String) is
begin
Write_Str ("""" & Name & """" & ": ");
Write_Char ('"');
Write_JSON_Escaped_String (Value);
Write_Char ('"');
end Write_String_Attribute;
end JSON_Utils;