Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
GIMP
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
2,764
Issues
2,764
List
Boards
Labels
Service Desk
Milestones
Merge Requests
39
Merge Requests
39
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Packages & Registries
Packages & Registries
Container Registry
Analytics
Analytics
CI / CD
Repository
Value Stream
External Wiki
External Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
GNOME
GIMP
Commits
297ff1ea
Commit
297ff1ea
authored
Nov 29, 2013
by
Michael Natterer
😴
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
plug-ins: port file-csource to GIO
parent
e0edc568
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
318 additions
and
161 deletions
+318
-161
plug-ins/common/file-csource.c
plug-ins/common/file-csource.c
+318
-161
No files found.
plug-ins/common/file-csource.c
View file @
297ff1ea
...
...
@@ -38,7 +38,6 @@
typedef
struct
{
gchar
*
file_name
;
gchar
*
prefixed_name
;
gchar
*
comment
;
gboolean
use_comment
;
...
...
@@ -58,7 +57,8 @@ static void run (const gchar *name,
gint
*
nreturn_vals
,
GimpParam
**
return_vals
);
static
gboolean
save_image
(
Config
*
config
,
static
gboolean
save_image
(
GFile
*
file
,
Config
*
config
,
gint32
image_ID
,
gint32
drawable_ID
,
GError
**
error
);
...
...
@@ -75,7 +75,6 @@ const GimpPlugInInfo PLUG_IN_INFO =
static
Config
config
=
{
NULL
,
/* file_name */
"gimp_image"
,
/* prefixed_name */
NULL
,
/* comment */
FALSE
,
/* use_comment */
...
...
@@ -116,6 +115,7 @@ query (void)
save_args
,
NULL
);
gimp_register_file_handler_mime
(
SAVE_PROC
,
"text/x-csrc"
);
gimp_register_file_handler_uri
(
SAVE_PROC
);
gimp_register_save_handler
(
SAVE_PROC
,
"c"
,
""
);
}
...
...
@@ -150,16 +150,12 @@ run (const gchar *name,
gint32
drawable_ID
=
param
[
2
].
data
.
d_int32
;
GimpParasite
*
parasite
;
gchar
*
x
;
GimpImageType
drawable_type
=
gimp_drawable_type
(
drawable_ID
);
gimp_get_data
(
SAVE_PROC
,
&
config
);
config
.
prefixed_name
=
"gimp_image"
;
config
.
comment
=
NULL
;
config
.
file_name
=
param
[
3
].
data
.
d_string
;
config
.
alpha
=
(
drawable_type
==
GIMP_RGBA_IMAGE
||
drawable_type
==
GIMP_GRAYA_IMAGE
||
drawable_type
==
GIMP_INDEXEDA_IMAGE
);
config
.
alpha
=
gimp_drawable_has_alpha
(
drawable_ID
);
parasite
=
gimp_image_get_parasite
(
image_ID
,
"gimp-comment"
);
if
(
parasite
)
...
...
@@ -202,7 +198,8 @@ run (const gchar *name,
}
}
if
(
!
save_image
(
&
config
,
image_ID
,
drawable_ID
,
&
error
))
if
(
!
save_image
(
g_file_new_for_uri
(
param
[
3
].
data
.
d_string
),
&
config
,
image_ID
,
drawable_ID
,
&
error
))
{
status
=
GIMP_PDB_EXECUTION_ERROR
;
...
...
@@ -297,101 +294,145 @@ rl_encode_rgbx (guint8 *bp,
return
bp
;
}
static
inline
void
save_rle_decoder
(
FILE
*
fp
,
const
gchar
*
macro_name
,
const
gchar
*
s_uint
,
const
gchar
*
s_uint_8
,
guint
n_ch
)
{
fprintf
(
fp
,
"#define %s_RUN_LENGTH_DECODE(image_buf, rle_data, size, bpp) do
\\\n
"
,
macro_name
);
fprintf
(
fp
,
"{ %s __bpp; %s *__ip; const %s *__il, *__rd;
\\\n
"
,
s_uint
,
s_uint_8
,
s_uint_8
);
fprintf
(
fp
,
" __bpp = (bpp); __ip = (image_buf); __il = __ip + (size) * __bpp;
\\\n
"
);
fprintf
(
fp
,
" __rd = (rle_data); if (__bpp > 3) { /* RGBA */
\\\n
"
);
static
gboolean
print
(
GOutputStream
*
stream
,
GError
**
error
,
const
gchar
*
format
,
...)
G_GNUC_PRINTF
(
3
,
4
);
fprintf
(
fp
,
" while (__ip < __il) { %s __l = *(__rd++);
\\\n
"
,
s_uint
);
fprintf
(
fp
,
" if (__l & 128) { __l = __l - 128;
\\\n
"
);
fprintf
(
fp
,
" do { memcpy (__ip, __rd, 4); __ip += 4; } while (--__l); __rd += 4;
\\\n
"
);
fprintf
(
fp
,
" } else { __l *= 4; memcpy (__ip, __rd, __l);
\\\n
"
);
fprintf
(
fp
,
" __ip += __l; __rd += __l; } }
\\\n
"
);
static
gboolean
print
(
GOutputStream
*
stream
,
GError
**
error
,
const
gchar
*
format
,
...)
{
va_list
args
;
gboolean
success
;
fprintf
(
fp
,
" } else { /* RGB */
\\\n
"
);
va_start
(
args
,
format
);
success
=
gimp_output_stream_vprintf
(
stream
,
NULL
,
NULL
,
error
,
format
,
args
);
va_end
(
args
);
fprintf
(
fp
,
" while (__ip < __il) { %s __l = *(__rd++);
\\\n
"
,
s_uint
);
fprintf
(
fp
,
" if (__l & 128) { __l = __l - 128;
\\\n
"
);
fprintf
(
fp
,
" do { memcpy (__ip, __rd, 3); __ip += 3; } while (--__l); __rd += 3;
\\\n
"
);
fprintf
(
fp
,
" } else { __l *= 3; memcpy (__ip, __rd, __l);
\\\n
"
);
fprintf
(
fp
,
" __ip += __l; __rd += __l; } }
\\\n
"
);
return
success
;
}
fprintf
(
fp
,
" } } while (0)
\n
"
);
static
inline
gboolean
save_rle_decoder
(
GOutputStream
*
output
,
const
gchar
*
macro_name
,
const
gchar
*
s_uint
,
const
gchar
*
s_uint_8
,
guint
n_ch
,
GError
**
error
)
{
return
print
(
output
,
error
,
"#define %s_RUN_LENGTH_DECODE(image_buf, rle_data, size, bpp) do
\\\n
"
,
macro_name
)
&&
print
(
output
,
error
,
"{ %s __bpp; %s *__ip; const %s *__il, *__rd;
\\\n
"
,
s_uint
,
s_uint_8
,
s_uint_8
)
&&
print
(
output
,
error
,
" __bpp = (bpp); __ip = (image_buf); __il = __ip + (size) * __bpp;
\\\n
"
" __rd = (rle_data); if (__bpp > 3) { /* RGBA */
\\\n
"
" while (__ip < __il) { %s __l = *(__rd++);
\\\n
"
,
s_uint
)
&&
print
(
output
,
error
,
" if (__l & 128) { __l = __l - 128;
\\\n
"
" do { memcpy (__ip, __rd, 4); __ip += 4; } while (--__l); __rd += 4;
\\\n
"
" } else { __l *= 4; memcpy (__ip, __rd, __l);
\\\n
"
" __ip += __l; __rd += __l; } }
\\\n
"
" } else { /* RGB */
\\\n
"
" while (__ip < __il) { %s __l = *(__rd++);
\\\n
"
,
s_uint
)
&&
print
(
output
,
error
,
" if (__l & 128) { __l = __l - 128;
\\\n
"
" do { memcpy (__ip, __rd, 3); __ip += 3; } while (--__l); __rd += 3;
\\\n
"
" } else { __l *= 3; memcpy (__ip, __rd, __l);
\\\n
"
" __ip += __l; __rd += __l; } }
\\\n
"
" } } while (0)
\n
"
);
}
static
inline
guint
save_uchar
(
FILE
*
fp
,
guint
c
,
guint8
d
,
Config
*
config
)
static
inline
gboolean
save_uchar
(
GOutputStream
*
output
,
guint
*
c
,
guint8
d
,
Config
*
config
,
GError
**
error
)
{
static
guint8
pad
=
0
;
if
(
c
>
74
)
if
(
*
c
>
74
)
{
if
(
!
config
->
use_macros
)
if
(
!
config
->
use_macros
)
{
fprintf
(
fp
,
"
\"\n
\"
"
);
c
=
3
;
if
(
!
print
(
output
,
error
,
"
\"\n
\"
"
))
return
FALSE
;
*
c
=
3
;
}
else
{
fprintf
(
fp
,
"
\"\n
\"
"
);
c
=
2
;
if
(
!
print
(
output
,
error
,
"
\"\n
\"
"
))
return
FALSE
;
*
c
=
2
;
}
}
if
(
d
<
33
||
d
>
126
)
{
fprintf
(
fp
,
"
\\
%o"
,
d
);
c
+=
1
+
1
+
(
d
>
7
)
+
(
d
>
63
);
if
(
!
print
(
output
,
error
,
"
\\
%o"
,
d
))
return
FALSE
;
*
c
+=
1
+
1
+
(
d
>
7
)
+
(
d
>
63
);
pad
=
d
<
64
;
return
c
;
return
TRUE
;
}
if
(
d
==
'\\'
)
{
fputs
(
"
\\\\
"
,
fp
);
c
+=
2
;
if
(
!
print
(
output
,
error
,
"
\\\\
"
))
return
FALSE
;
*
c
+=
2
;
}
else
if
(
d
==
'"'
)
{
fputs
(
"
\\\"
"
,
fp
);
c
+=
2
;
if
(
!
print
(
output
,
error
,
"
\\\"
"
))
return
FALSE
;
*
c
+=
2
;
}
else
if
(
pad
&&
d
>=
'0'
&&
d
<=
'9'
)
{
fputs
(
"
\"\"
"
,
fp
);
fputc
(
d
,
fp
);
c
+=
3
;
if
(
!
print
(
output
,
error
,
"
\"\"
%c"
,
d
))
return
FALSE
;
*
c
+=
3
;
}
else
{
fputc
(
d
,
fp
);
c
+=
1
;
if
(
!
print
(
output
,
error
,
"%c"
,
d
))
return
FALSE
;
*
c
+=
1
;
}
pad
=
0
;
return
c
;
return
TRUE
;
}
static
gboolean
save_image
(
Config
*
config
,
save_image
(
GFile
*
file
,
Config
*
config
,
gint32
image_ID
,
gint32
drawable_ID
,
GError
**
error
)
{
GOutputStream
*
output
;
GeglBuffer
*
buffer
;
FILE
*
fp
;
GimpImageType
drawable_type
=
gimp_drawable_type
(
drawable_ID
);
gchar
*
s_uint_8
,
*
s_uint
,
*
s_char
,
*
s_null
;
guint
c
;
...
...
@@ -404,13 +445,18 @@ save_image (Config *config,
gint
x
,
y
,
pad
,
n_bytes
,
bpp
;
gint
drawable_bpp
;
fp
=
g_fopen
(
config
->
file_name
,
"w"
);
if
(
!
fp
)
output
=
G_OUTPUT_STREAM
(
g_file_replace
(
file
,
NULL
,
FALSE
,
0
,
NULL
,
error
));
if
(
output
)
{
GOutputStream
*
buffered
;
buffered
=
g_buffered_output_stream_new
(
output
);
g_object_unref
(
output
);
output
=
buffered
;
}
else
{
g_set_error
(
error
,
G_FILE_ERROR
,
g_file_error_from_errno
(
errno
),
_
(
"Could not open '%s' for writing: %s"
),
gimp_filename_to_utf8
(
config
->
file_name
),
g_strerror
(
errno
));
return
FALSE
;
}
...
...
@@ -529,150 +575,261 @@ save_image (Config *config,
macro_name
=
g_ascii_strup
(
config
->
prefixed_name
,
-
1
);
basename
=
g_
path_get_basename
(
config
->
file_nam
e
);
basename
=
g_
file_get_basename
(
fil
e
);
fprintf
(
fp
,
"/* GIMP %s C-Source image dump %s(%s) */
\n\n
"
,
config
->
alpha
?
"RGBA"
:
"RGB"
,
config
->
use_rle
?
"1-byte-run-length-encoded "
:
""
,
basename
);
if
(
!
print
(
output
,
error
,
"/* GIMP %s C-Source image dump %s(%s) */
\n\n
"
,
config
->
alpha
?
"RGBA"
:
"RGB"
,
config
->
use_rle
?
"1-byte-run-length-encoded "
:
""
,
basename
))
goto
fail
;
g_free
(
basename
);
if
(
config
->
use_rle
&&
!
config
->
use_macros
)
save_rle_decoder
(
fp
,
macro_name
,
config
->
glib_types
?
"guint"
:
"unsigned int"
,
config
->
glib_types
?
"guint8"
:
"unsigned char"
,
config
->
alpha
?
4
:
3
);
{
if
(
!
save_rle_decoder
(
output
,
macro_name
,
config
->
glib_types
?
"guint"
:
"unsigned int"
,
config
->
glib_types
?
"guint8"
:
"unsigned char"
,
config
->
alpha
?
4
:
3
,
error
))
goto
fail
;
}
if
(
!
config
->
use_macros
)
{
fprintf
(
fp
,
"static const struct {
\n
"
);
fprintf
(
fp
,
" %s
\t
width;
\n
"
,
s_uint
);
fprintf
(
fp
,
" %s
\t
height;
\n
"
,
s_uint
);
fprintf
(
fp
,
" %s
\t
bytes_per_pixel; /* 2:RGB16, 3:RGB, 4:RGBA */
\n
"
,
s_uint
);
if
(
!
print
(
output
,
error
,
"static const struct {
\n
"
" %s
\t
width;
\n
"
" %s
\t
height;
\n
"
" %s
\t
bytes_per_pixel; /* 2:RGB16, 3:RGB, 4:RGBA */
\n
"
,
s_uint
,
s_uint
,
s_uint
))
goto
fail
;
if
(
config
->
use_comment
)
fprintf
(
fp
,
" %s
\t
*comment;
\n
"
,
s_char
);
fprintf
(
fp
,
" %s
\t
%spixel_data["
,
s_uint_8
,
config
->
use_rle
?
"rle_"
:
""
);
{
if
(
!
print
(
output
,
error
,
" %s
\t
*comment;
\n
"
,
s_char
))
goto
fail
;
}
if
(
!
print
(
output
,
error
,
" %s
\t
%spixel_data["
,
s_uint_8
,
config
->
use_rle
?
"rle_"
:
""
))
goto
fail
;
if
(
config
->
use_rle
)
fprintf
(
fp
,
"%u + 1];
\n
"
,
(
guint
)
(
img_buffer_end
-
img_buffer
));
{
if
(
!
print
(
output
,
error
,
"%u + 1];
\n
"
,
(
guint
)
(
img_buffer_end
-
img_buffer
)))
goto
fail
;
}
else
fprintf
(
fp
,
"%u * %u * %u + 1];
\n
"
,
width
,
height
,
config
->
rgb565
?
2
:
(
config
->
alpha
?
4
:
3
));
fprintf
(
fp
,
"} %s = {
\n
"
,
config
->
prefixed_name
);
fprintf
(
fp
,
" %u, %u, %u,
\n
"
,
width
,
height
,
config
->
rgb565
?
2
:
(
config
->
alpha
?
4
:
3
));
{
if
(
!
print
(
output
,
error
,
"%u * %u * %u + 1];
\n
"
,
width
,
height
,
config
->
rgb565
?
2
:
(
config
->
alpha
?
4
:
3
)))
goto
fail
;
}
if
(
!
print
(
output
,
error
,
"} %s = {
\n
"
,
config
->
prefixed_name
))
goto
fail
;
if
(
!
print
(
output
,
error
,
" %u, %u, %u,
\n
"
,
width
,
height
,
config
->
rgb565
?
2
:
(
config
->
alpha
?
4
:
3
)))
goto
fail
;
}
else
/* use macros */
{
fprintf
(
fp
,
"#define %s_WIDTH (%u)
\n
"
,
macro_name
,
width
);
fprintf
(
fp
,
"#define %s_HEIGHT (%u)
\n
"
,
macro_name
,
height
);
fprintf
(
fp
,
"#define %s_BYTES_PER_PIXEL (%u) /* 3:RGB, 4:RGBA */
\n
"
,
macro_name
,
config
->
alpha
?
4
:
3
);
if
(
!
print
(
output
,
error
,
"#define %s_WIDTH (%u)
\n
"
"#define %s_HEIGHT (%u)
\n
"
"#define %s_BYTES_PER_PIXEL (%u) /* 3:RGB, 4:RGBA */
\n
"
,
macro_name
,
width
,
macro_name
,
height
,
macro_name
,
config
->
alpha
?
4
:
3
))
{
goto
fail
;
}
}
if
(
config
->
use_comment
&&
!
config
->
comment
)
{
if
(
!
config
->
use_macros
)
fprintf
(
fp
,
" %s,
\n
"
,
s_null
);
else
/* use macros */
fprintf
(
fp
,
"#define %s_COMMENT (%s)
\n
"
,
macro_name
,
s_null
);
if
(
!
config
->
use_macros
)
{
if
(
!
print
(
output
,
error
,
" %s,
\n
"
,
s_null
))
goto
fail
;
}
else
{
if
(
!
print
(
output
,
error
,
"#define %s_COMMENT (%s)
\n
"
,
macro_name
,
s_null
))
goto
fail
;
}
}
else
if
(
config
->
use_comment
)
{
gchar
*
p
=
config
->
comment
-
1
;
if
(
config
->
use_macros
)
fprintf
(
fp
,
"#define %s_COMMENT
\\\n
"
,
macro_name
);
fprintf
(
fp
,
"
\"
"
);
{
if
(
!
print
(
output
,
error
,
"#define %s_COMMENT
\\\n
"
,
macro_name
))
goto
fail
;
}
if
(
!
print
(
output
,
error
,
"
\"
"
))
goto
fail
;
while
(
*
(
++
p
))
if
(
*
p
==
'\\'
)
fprintf
(
fp
,
"
\\\\
"
);
else
if
(
*
p
==
'"'
)
fprintf
(
fp
,
"
\\\"
"
);
else
if
(
*
p
==
'\n'
&&
p
[
1
])
fprintf
(
fp
,
"
\\
n
\"
%s
\n
\"
"
,
config
->
use_macros
?
"
\\
"
:
""
);
else
if
(
*
p
==
'\n'
)
fprintf
(
fp
,
"
\\
n"
);
else
if
(
*
p
==
'\r'
)
fprintf
(
fp
,
"
\\
r"
);
else
if
(
*
p
==
'\b'
)
fprintf
(
fp
,
"
\\
b"
);
else
if
(
*
p
==
'\f'
)
fprintf
(
fp
,
"
\\
f"
);
else
if
(
*
p
>=
32
&&
*
p
<=
126
)
fprintf
(
fp
,
"%c"
,
*
p
);
else
fprintf
(
fp
,
"
\\
%03o"
,
*
p
);
if
(
!
config
->
use_macros
)
fprintf
(
fp
,
"
\"
,
\n
"
);
else
/* use macros */
fprintf
(
fp
,
"
\"\n
"
);
{
gboolean
success
=
FALSE
;
if
(
*
p
==
'\\'
)
success
=
print
(
output
,
error
,
"
\\\\
"
);
else
if
(
*
p
==
'"'
)
success
=
print
(
output
,
error
,
"
\\\"
"
);
else
if
(
*
p
==
'\n'
&&
p
[
1
])
success
=
print
(
output
,
error
,
"
\\
n
\"
%s
\n
\"
"
,
config
->
use_macros
?
"
\\
"
:
""
);
else
if
(
*
p
==
'\n'
)
success
=
print
(
output
,
error
,
"
\\
n"
);
else
if
(
*
p
==
'\r'
)
success
=
print
(
output
,
error
,
"
\\
r"
);
else
if
(
*
p
==
'\b'
)
success
=
print
(
output
,
error
,
"
\\
b"
);
else
if
(
*
p
==
'\f'
)
success
=
print
(
output
,
error
,
"
\\
f"
);
else
if
(
*
p
>=
32
&&
*
p
<=
126
)
success
=
print
(
output
,
error
,
"%c"
,
*
p
);
else
success
=
print
(
output
,
error
,
"
\\
%03o"
,
*
p
);
if
(
!
success
)
goto
fail
;
}
if
(
!
config
->
use_macros
)
{
if
(
!
print
(
output
,
error
,
"
\"
,
\n
"
))
goto
fail
;
}
else
{
if
(
!
print
(
output
,
error
,
"
\"\n
"
))
goto
fail
;
}
}
if
(
config
->
use_macros
)
{
fprintf
(
fp
,
"#define %s_%sPIXEL_DATA ((%s*) %s_%spixel_data)
\n
"
,
macro_name
,
config
->
use_rle
?
"RLE_"
:
""
,
s_uint_8
,
macro_name
,
config
->
use_rle
?
"rle_"
:
""
);
if
(
!
print
(
output
,
error
,
"#define %s_%sPIXEL_DATA ((%s*) %s_%spixel_data)
\n
"
,
macro_name
,
config
->
use_rle
?
"RLE_"
:
""
,
s_uint_8
,
macro_name
,
config
->
use_rle
?
"rle_"
:
""
))
goto
fail
;
if
(
config
->
use_rle
)
save_rle_decoder
(
fp
,
macro_name
,
s_uint
,
s_uint_8
,
config
->
alpha
?
4
:
3
);
fprintf
(
fp
,
"static const %s %s_%spixel_data["
,
s_uint_8
,
macro_name
,
config
->
use_rle
?
"rle_"
:
""
);
{
if
(
!
save_rle_decoder
(
output
,
macro_name
,
s_uint
,
s_uint_8
,
config
->
alpha
?
4
:
3
,
error
))
goto
fail
;
}
if
(
!
print
(
output
,
error
,
"static const %s %s_%spixel_data["
,
s_uint_8
,
macro_name
,
config
->
use_rle
?
"rle_"
:
""
))
goto
fail
;
if
(
config
->
use_rle
)
fprintf
(
fp
,
"%u] =
\n
"
,
(
guint
)
(
img_buffer_end
-
img_buffer
));
{
if
(
!
print
(
output
,
error
,
"%u] =
\n
"
,
(
guint
)
(
img_buffer_end
-
img_buffer
)))
goto
fail
;
}
else
fprintf
(
fp
,
"%u * %u * %u + 1] =
\n
"
,
width
,
height
,
config
->
alpha
?
4
:
3
);
fprintf
(
fp
,
"(
\"
"
);
{
if
(
!
print
(
output
,
error
,
"%u * %u * %u + 1] =
\n
"
,
width
,
height
,
config
->
alpha
?
4
:
3
))
goto
fail
;
}
if
(
!
print
(
output
,
error
,
"(
\"
"
))
goto
fail
;
c
=
2
;
}
else
{
fprintf
(
fp
,
"
\"
"
);
if
(
!
print
(
output
,
error
,
"
\"
"
))
goto
fail
;
c
=
3
;
}
switch
(
drawable_type
)
{
case
GIMP_RGB_IMAGE
:
case
GIMP_RGBA_IMAGE
:
do
c
=
save_uchar
(
fp
,
c
,
*
(
img_buffer
++
),
config
);
{
if
(
!
save_uchar
(
output
,
&
c
,
*
(
img_buffer
++
),
config
,
error
))
goto
fail
;
}
while
(
img_buffer
<
img_buffer_end
);
break
;
default:
g_warning
(
"unhandled drawable type (%d)"
,
drawable_type
);
fclose
(
fp
);
return
FALSE
;
goto
fail
;
}
if
(
!
config
->
use_macros
)
fprintf
(
fp
,
"
\"
,
\n
};
\n\n
"
);
else
/* use macros */
fprintf
(
fp
,
"
\"
);
\n\n
"
);
fclose
(
fp
);
if
(
!
config
->
use_macros
)
{
if
(
!
print
(
output
,
error
,
"
\"
,
\n
};
\n\n
"
))
goto
fail
;
}
else