Cross Reference: msggen.c
xref
: /
osnet-11
/
usr
/
src
/
cmd
/
ast
/
msgcc
/
msggen.c
Home
History
Annotate
Line#
Navigate
Download
Search
only in
./
1
N/A
/***********************************************************************
1
N/A
* *
1
N/A
* This software is part of the ast package *
1
N/A
* Copyright (c) 2000-2010 AT&T Intellectual Property *
1
N/A
* and is licensed under the *
1
N/A
* Common Public License, Version 1.0 *
1
N/A
* by AT&T Intellectual Property *
1
N/A
* *
1
N/A
* A copy of the License is available at *
1
N/A
*
http://www.opensource.org/licenses/cpl1.0.txt
*
1
N/A
* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
1
N/A
* *
1
N/A
* Information and Software Systems Research *
1
N/A
* AT&T Research *
1
N/A
* Florham Park NJ *
1
N/A
* *
1
N/A
* Glenn Fowler <gsf@research.att.com> *
1
N/A
* *
1
N/A
***********************************************************************/
1
N/A
#
pragma
prototyped
1
N/A
/*
1
N/A
* Glenn Fowler
1
N/A
* AT&T Research
1
N/A
*/
1
N/A
1
N/A
static
const
char
usage
[] =
1
N/A
"[-?\n@(#)$Id: msggen (AT&T Research) 2002-03-11 $\n]"
1
N/A
USAGE_LICENSE
1
N/A
"[+NAME?msggen - generate a machine independent formatted message catalog]"
1
N/A
"[+DESCRIPTION?\bmsggen\b merges the message text source files \amsgfile\a"
1
N/A
" into a machine independent formatted message catalog \acatfile\a."
1
N/A
" The file \acatfile\a will be created if it does not already exist."
1
N/A
" If \acatfile\a does exist, its messages will be included in the new"
1
N/A
" \acatfile\a. If set and message numbers collide, the new message"
1
N/A
" text defined in \amsgfile\a will replace the old message text"
1
N/A
" currently contained in \acatfile\a. Non-ASCII characters must be"
1
N/A
" UTF-8 encoded. \biconv\b(1) can be used to convert
to
/
from
UTF-8.]"
1
N/A
"[f:format?List the \bprintf\b(3) format signature for each message in"
1
N/A
" \acatfile\a. A format signature is one line containing one character"
1
N/A
" per format specification:]{"
1
N/A
" [c?char]"
1
N/A
" [d?double]"
1
N/A
" [D?long double]"
1
N/A
" [f?float]"
1
N/A
" [h?short]"
1
N/A
" [i?int]"
1
N/A
" [j?long long]"
1
N/A
" [l?long]"
1
N/A
" [p?void*]"
1
N/A
" [s?string]"
1
N/A
" [t?ptrdiff_t]"
1
N/A
" [z?size_t]"
1
N/A
" [???unknown]"
1
N/A
"}"
1
N/A
"[l:list?List \acatfile\a in UTF-8 \amsgfile\a form.]"
1
N/A
"[s:set?Convert the \acatfile\a operand to a message set number and"
1
N/A
" print the number on the standard output.]"
1
N/A
"[+EXTENDED DESCRIPTION?Message text source files are in \bgencat\b(1)"
1
N/A
" format, defined as follows. Note that the fields of a message text"
1
N/A
" source line are separated by a single blank character. Any other"
1
N/A
" blank characters are considered as being part of the subsequent"
1
N/A
" field. The \bNL_*\b constants are defined in one or both of"
1
N/A
" \b<
limits.h
>\b and \b<
nl_types.h
>\b.]{"
1
N/A
" [+$ \acomment\a?A line beginning with \b$\b followed by a"
1
N/A
" blank character is treated as a comment.]"
1
N/A
" [+$delset \an\a \acomment\a?This line deletes message set"
1
N/A
" \an\a from an existing message catalog. \an\a"
1
N/A
" denotes the set number [1, \bNL_SETMAX\b]]. Any"
1
N/A
" text following the set number is treated as a"
1
N/A
" comment.]"
1
N/A
" [+$quote \ac\a?This line specifies an optional quote"
1
N/A
" character \ac\a, which can be used to surround"
1
N/A
" \amessage-text\a so that trailing spaces or"
1
N/A
" empty messages are visible in a message source"
1
N/A
" line. By default, or if an empty \b$quote\b"
1
N/A
" directive is supplied, no quoting of \amessage-text\a"
1
N/A
" will be recognized.]"
1
N/A
" [+$set \an\a \acomment\a?This line specifies the set"
1
N/A
" identifier of the following messages until the next"
1
N/A
" \b$set\b or end-of-file appears. \an\a denotes the set"
1
N/A
" identifier, which is defined as a number in the range"
1
N/A
" [1, \bNL_SETMAX\b]]. Set numbers need not be"
1
N/A
" contiguous. Any text following the set identifier is"
1
N/A
" treated as a comment. If no \b$set\b directive is"
1
N/A
" specified in a message text source file, all messages"
1
N/A
" will be located in message set \b1\b.]"
1
N/A
" [+$translation \aidentification\a \aYYYY-MM-DD\a[,...]]?Append"
1
N/A
" translation info to the message catalog header. Only"
1
N/A
" the newest date for a given \aidentification\a"
1
N/A
" is retained in the catalog. Multiple translation lines"
1
N/A
" are combined into a single \b,\b separated list.]"
1
N/A
" [+\am\a \amessage-text\a?\am\a denotes the message identifier,"
1
N/A
" which is defined as a number in the range"
1
N/A
" [1, \bNL_MSGMAX\b]]. The message-text is stored in the"
1
N/A
" message catalogue with the set identifier specified by"
1
N/A
" the last \b$set\b directive, and with message"
1
N/A
" identifier \am\a. If the \amessage-text\a is empty,"
1
N/A
" and a blank character field separator is present, an"
1
N/A
" empty string is stored in the message catalogue. If a"
1
N/A
" message source line has a message number, but neither"
1
N/A
" a field separator nor \amessage-text\a, the existing"
1
N/A
" message with that number (if any) is deleted from the"
1
N/A
" catalogue. Message identifiers need not be contiguous."
1
N/A
" There are no \amessage-text\a length restrictions.]"
1
N/A
"}"
1
N/A
1
N/A
"\n"
1
N/A
"\ncatfile [ msgfile ]\n"
1
N/A
"\n"
1
N/A
1
N/A
"[+SEE ALSO?\bgencat\b(1), \biconv\b(1), \bmsgcc\b(1), \btranslate\b(1),"
1
N/A
" \bfmtfmt\b(3)]"
1
N/A
;
1
N/A
1
N/A
#
include
<
ast.h
>
1
N/A
#
include
<
ctype.h
>
1
N/A
#
include
<
ccode.h
>
1
N/A
#
include
<
error.h
>
1
N/A
#
include
<
mc.h
>
1
N/A
1
N/A
typedef
struct
Xl_s
1
N/A
{
1
N/A
struct
Xl_s
*
next
;
1
N/A
char
*
date
;
1
N/A
char
name
[
1
];
1
N/A
}
Xl_t
;
1
N/A
1
N/A
/*
1
N/A
* append s to the translation list
1
N/A
*/
1
N/A
1
N/A
static
Xl_t
*
1
N/A
translation
(
Xl_t
*
xp
,
register
char
* s)
1
N/A
{
1
N/A
register
Xl_t
*
px
;
1
N/A
register
char
* t;
1
N/A
char
* d;
1
N/A
char
* e;
1
N/A
1
N/A
do
1
N/A
{
1
N/A
for
(;
isspace
(*s); s++);
1
N/A
for
(d = e = 0, t = s; *t; t++)
1
N/A
if
(*t ==
','
)
1
N/A
{
1
N/A
e = t;
1
N/A
*e++ = 0;
1
N/A
break
;
1
N/A
}
1
N/A
else
if
(
isspace
(*t))
1
N/A
d = t;
1
N/A
if
(d)
1
N/A
{
1
N/A
*d++ = 0;
1
N/A
for
(
px
=
xp
;
px
;
px
=
px
->
next
)
1
N/A
if
(
streq
(
px
->
name
, s))
1
N/A
{
1
N/A
if
(
strcoll
(
px
->
date
, d) < 0)
1
N/A
{
1
N/A
free
(
px
->
date
);
1
N/A
if
(!(
px
->
date
=
strdup
(d)))
1
N/A
error
(
ERROR_SYSTEM
|
3
,
"out of space [translation]"
);
1
N/A
}
1
N/A
break
;
1
N/A
}
1
N/A
if
(!
px
)
1
N/A
{
1
N/A
if
(!(
px
=
newof
(0,
Xl_t
,
1
,
strlen
(s))) || !(
px
->
date
=
strdup
(d)))
1
N/A
error
(
ERROR_SYSTEM
|
3
,
"out of space [translation]"
);
1
N/A
strcpy
(
px
->
name
, s);
1
N/A
px
->
next
=
xp
;
1
N/A
xp
=
px
;
1
N/A
}
1
N/A
}
1
N/A
}
while
(s = e);
1
N/A
return
xp
;
1
N/A
}
1
N/A
1
N/A
/*
1
N/A
* sfprintf() with ccmaps(from,to)
1
N/A
*/
1
N/A
1
N/A
static
int
1
N/A
ccsfprintf
(
int
from
,
int
to
,
Sfio_t
*
sp
,
const
char
*
format
, ...)
1
N/A
{
1
N/A
va_list
ap
;
1
N/A
Sfio_t
*
tp
;
1
N/A
char
* s;
1
N/A
int
n;
1
N/A
1
N/A
va_start
(
ap
,
format
);
1
N/A
if
(
from
==
to
)
1
N/A
n =
sfvprintf
(
sp
,
format
,
ap
);
1
N/A
else
if
(
tp
=
sfstropen
())
1
N/A
{
1
N/A
n =
sfvprintf
(
tp
,
format
,
ap
);
1
N/A
s =
sfstrbase
(
tp
);
1
N/A
ccmaps
(s, n,
from
,
to
);
1
N/A
n =
sfwrite
(
sp
, s, n);
1
N/A
sfstrclose
(
tp
);
1
N/A
}
1
N/A
else
1
N/A
n = -
1
;
1
N/A
return
n;
1
N/A
}
1
N/A
1
N/A
int
1
N/A
main
(
int
argc
,
char
**
argv
)
1
N/A
{
1
N/A
register
Mc_t
*
mc
;
1
N/A
register
char
* s;
1
N/A
register
char
* t;
1
N/A
register
int
c;
1
N/A
register
int
q;
1
N/A
register
int
i;
1
N/A
int
num
;
1
N/A
char
* b;
1
N/A
char
* e;
1
N/A
char
*
catfile
;
1
N/A
char
*
msgfile
;
1
N/A
Sfio_t
*
sp
;
1
N/A
Sfio_t
*
mp
;
1
N/A
Sfio_t
*
tp
;
1
N/A
Xl_t
*
px
;
1
N/A
Xl_t
*
bp
;
1
N/A
1
N/A
Xl_t
*
xp
= 0;
1
N/A
int
format
= 0;
1
N/A
int
list
= 0;
1
N/A
int
set
= 0;
1
N/A
1
N/A
NoP
(
argc
);
1
N/A
error_info
.
id
=
"msggen"
;
1
N/A
for
(;;)
1
N/A
{
1
N/A
switch
(
optget
(
argv
,
usage
))
1
N/A
{
1
N/A
case
'f'
:
1
N/A
format
=
list
=
1
;
1
N/A
continue
;
1
N/A
case
'l'
:
1
N/A
list
=
1
;
1
N/A
continue
;
1
N/A
case
's'
:
1
N/A
set
=
1
;
1
N/A
continue
;
1
N/A
case
'?'
:
1
N/A
error
(
ERROR_USAGE
|
4
,
"%s"
,
opt_info
.
arg
);
1
N/A
continue
;
1
N/A
case
':'
:
1
N/A
error
(
2
,
"%s"
,
opt_info
.
arg
);
1
N/A
continue
;
1
N/A
}
1
N/A
break
;
1
N/A
}
1
N/A
argv
+=
opt_info
.
index
;
1
N/A
if
(
error_info
.
errors
|| !(
catfile
= *
argv
++))
1
N/A
error
(
ERROR_USAGE
|
4
,
"%s"
,
optusage
(
NiL
));
1
N/A
1
N/A
/*
1
N/A
* set and list only need catfile
1
N/A
*/
1
N/A
1
N/A
if
(
set
)
1
N/A
{
1
N/A
sfprintf
(
sfstdout
,
"%d\n"
,
mcindex
(
catfile
,
NiL
,
NiL
,
NiL
));
1
N/A
return
error_info
.
errors
!= 0;
1
N/A
}
1
N/A
else
if
(
list
)
1
N/A
{
1
N/A
if
(!(
sp
=
sfopen
(
NiL
,
catfile
,
"r"
)))
1
N/A
error
(
ERROR_SYSTEM
|
3
,
"%s: cannot read catalog"
,
catfile
);
1
N/A
if
(!(
mc
=
mcopen
(
sp
)))
1
N/A
error
(
ERROR_SYSTEM
|
3
,
"%s: catalog content error"
,
catfile
);
1
N/A
sfclose
(
sp
);
1
N/A
if
(
format
)
1
N/A
{
1
N/A
for
(
set
=
1
;
set
<=
mc
->
num
;
set
++)
1
N/A
if
(
mc
->
set
[
set
].
num
)
1
N/A
{
1
N/A
sfprintf
(
sfstdout
,
"$set %d\n"
,
set
);
1
N/A
for
(
num
=
1
;
num
<=
mc
->
set
[
set
].
num
;
num
++)
1
N/A
if
(s =
mc
->
set
[
set
].
msg
[
num
])
1
N/A
sfprintf
(
sfstdout
,
"%d \"%s\"\n"
,
num
,
fmtfmt
(s));
1
N/A
}
1
N/A
}
1
N/A
else
1
N/A
{
1
N/A
if
(*
mc
->
translation
)
1
N/A
{
1
N/A
ccsfprintf
(
CC_NATIVE
,
CC_ASCII
,
sfstdout
,
"$translation "
);
1
N/A
sfprintf
(
sfstdout
,
"%s"
,
mc
->
translation
);
1
N/A
ccsfprintf
(
CC_NATIVE
,
CC_ASCII
,
sfstdout
,
"\n"
);
1
N/A
}
1
N/A
ccsfprintf
(
CC_NATIVE
,
CC_ASCII
,
sfstdout
,
"$quote \"\n"
);
1
N/A
for
(
set
=
1
;
set
<=
mc
->
num
;
set
++)
1
N/A
if
(
mc
->
set
[
set
].
num
)
1
N/A
{
1
N/A
ccsfprintf
(
CC_NATIVE
,
CC_ASCII
,
sfstdout
,
"$set %d\n"
,
set
);
1
N/A
for
(
num
=
1
;
num
<=
mc
->
set
[
set
].
num
;
num
++)
1
N/A
if
(s =
mc
->
set
[
set
].
msg
[
num
])
1
N/A
{
1
N/A
ccsfprintf
(
CC_NATIVE
,
CC_ASCII
,
sfstdout
,
"%d \""
,
num
);
1
N/A
while
(c = *s++)
1
N/A
{
1
N/A
/*INDENT...*/
1
N/A
1
N/A
switch
(c)
1
N/A
{
1
N/A
case
0x22
:
/* " */
1
N/A
case
0x5C
:
/* \ */
1
N/A
sfputc
(
sfstdout
,
0x5C
);
1
N/A
break
;
1
N/A
case
0x07
:
/* \a */
1
N/A
c =
0x61
;
1
N/A
sfputc
(
sfstdout
,
0x5C
);
1
N/A
break
;
1
N/A
case
0x08
:
/* \b */
1
N/A
c =
0x62
;
1
N/A
sfputc
(
sfstdout
,
0x5C
);
1
N/A
break
;
1
N/A
case
0x0A
:
/* \n */
1
N/A
c =
0x6E
;
1
N/A
sfputc
(
sfstdout
,
0x5C
);
1
N/A
break
;
1
N/A
case
0x0B
:
/* \v */
1
N/A
c =
0x76
;
1
N/A
sfputc
(
sfstdout
,
0x5C
);
1
N/A
break
;
1
N/A
case
0x0C
:
/* \f */
1
N/A
c =
0x66
;
1
N/A
sfputc
(
sfstdout
,
0x5C
);
1
N/A
break
;
1
N/A
case
0x0D
:
/* \r */
1
N/A
c =
0x72
;
1
N/A
sfputc
(
sfstdout
,
0x5C
);
1
N/A
break
;
1
N/A
}
1
N/A
1
N/A
/*...UNDENT*/
1
N/A
sfputc
(
sfstdout
, c);
1
N/A
}
1
N/A
ccsfprintf
(
CC_NATIVE
,
CC_ASCII
,
sfstdout
,
"\"\n"
);
1
N/A
}
1
N/A
}
1
N/A
}
1
N/A
mcclose
(
mc
);
1
N/A
return
error_info
.
errors
!= 0;
1
N/A
}
1
N/A
else
if
(!(
msgfile
= *
argv
++) || *
argv
)
1
N/A
error
(
3
,
"exactly one message file must be specified"
);
1
N/A
1
N/A
/*
1
N/A
* open the files and handles
1
N/A
*/
1
N/A
1
N/A
if
(!(
tp
=
sfstropen
()))
1
N/A
error
(
ERROR_SYSTEM
|
3
,
"out of space [string stream]"
);
1
N/A
if
(!(
mp
=
sfopen
(
NiL
,
msgfile
,
"r"
)))
1
N/A
error
(
ERROR_SYSTEM
|
3
,
"%s: cannot read message file"
,
msgfile
);
1
N/A
sp
=
sfopen
(
NiL
,
catfile
,
"r"
);
1
N/A
if
(!(
mc
=
mcopen
(
sp
)))
1
N/A
error
(
ERROR_SYSTEM
|
3
,
"%s: catalog content error"
,
catfile
);
1
N/A
if
(
sp
)
1
N/A
sfclose
(
sp
);
1
N/A
xp
=
translation
(
xp
,
mc
->
translation
);
1
N/A
1
N/A
/*
1
N/A
* read the message file
1
N/A
*/
1
N/A
1
N/A
q = 0;
1
N/A
set
=
1
;
1
N/A
error_info
.
file
=
msgfile
;
1
N/A
while
(s =
sfgetr
(
mp
,
'\n'
,
1
))
1
N/A
{
1
N/A
error_info
.
line
++;
1
N/A
if
(!*s)
1
N/A
continue
;
1
N/A
if
(*s ==
'$'
)
1
N/A
{
1
N/A
if
(!*++s ||
isspace
(*s))
1
N/A
continue
;
1
N/A
for
(t = s; *s && !
isspace
(*s); s++);
1
N/A
if
(*s)
1
N/A
*s++ = 0;
1
N/A
if
(
streq
(t,
"delset"
))
1
N/A
{
1
N/A
while
(
isspace
(*s))
1
N/A
s++;
1
N/A
num
= (
int
)
strtol
(s,
NiL
, 0);
1
N/A
if
(
num
<
mc
->
num
&&
mc
->
set
[
num
].
num
)
1
N/A
for
(i =
1
; i <=
mc
->
set
[
num
].
num
; i++)
1
N/A
mcput
(
mc
,
num
, i,
NiL
);
1
N/A
}
1
N/A
else
if
(
streq
(t,
"quote"
))
1
N/A
q = *s ? *s : 0;
1
N/A
else
if
(
streq
(t,
"set"
))
1
N/A
{
1
N/A
while
(
isspace
(*s))
1
N/A
s++;
1
N/A
num
= (
int
)
strtol
(s, &e, 0);
1
N/A
if
(e != s)
1
N/A
set
=
num
;
1
N/A
else
1
N/A
error
(
2
,
"set number expected"
);
1
N/A
}
1
N/A
else
if
(
streq
(t,
"translation"
))
1
N/A
xp
=
translation
(
xp
, s);
1
N/A
}
1
N/A
else
1
N/A
{
1
N/A
t = s +
sfvalue
(
mp
);
1
N/A
num
= (
int
)
strtol
(s, &e, 0);
1
N/A
if
(e != s)
1
N/A
{
1
N/A
s = e;
1
N/A
if
(!*s)
1
N/A
{
1
N/A
if
(
mcput
(
mc
,
set
,
num
,
NiL
))
1
N/A
error
(
2
,
"(%d,%d): cannot delete message"
,
set
,
num
);
1
N/A
}
1
N/A
else
if
(
isspace
(*s++))
1
N/A
{
1
N/A
if
(t > (s +
1
) && *(t -=
2
) ==
'\\'
)
1
N/A
{
1
N/A
sfwrite
(
tp
, s, t - s);
1
N/A
while
(s =
sfgetr
(
mp
,
'\n'
, 0))
1
N/A
{
1
N/A
error_info
.
line
++;
1
N/A
t = s +
sfvalue
(
mp
);
1
N/A
if
(t <= (s +
1
) || *(t -=
2
) !=
'\\'
)
1
N/A
break
;
1
N/A
sfwrite
(
tp
, s, t - s);
1
N/A
}
1
N/A
if
(!(s =
sfstruse
(
tp
)))
1
N/A
error
(
ERROR_SYSTEM
|
3
,
"out of space"
);
1
N/A
}
1
N/A
if
(q)
1
N/A
{
1
N/A
if
(*s++ != q)
1
N/A
{
1
N/A
error
(
2
,
"(%d,%d): %c quote expected"
,
set
,
num
, q);
1
N/A
continue
;
1
N/A
}
1
N/A
b = t = s;
1
N/A
while
(c = *s++)
1
N/A
{
1
N/A
if
(c ==
'\\'
)
1
N/A
{
1
N/A
c =
chresc
(s -
1
, &e);
1
N/A
s = e;
1
N/A
if
(c)
1
N/A
*t++ = c;
1
N/A
else
1
N/A
error
(
1
,
"nul character ignored"
);
1
N/A
}
1
N/A
else
if
(c == q)
1
N/A
break
;
1
N/A
else
1
N/A
*t++ = c;
1
N/A
}
1
N/A
if
(*s)
1
N/A
{
1
N/A
error
(
2
,
"(%d,%d): characters after quote not expected"
,
set
,
num
);
1
N/A
continue
;
1
N/A
}
1
N/A
*t = 0;
1
N/A
s = b;
1
N/A
}
1
N/A
if
(
mcput
(
mc
,
set
,
num
, s))
1
N/A
error
(
2
,
"(%d,%d): cannot add message"
,
set
,
num
);
1
N/A
}
1
N/A
else
1
N/A
error
(
2
,
"message text expected"
);
1
N/A
}
1
N/A
else
1
N/A
error
(
2
,
"message number expected"
);
1
N/A
}
1
N/A
}
1
N/A
error_info
.
file
= 0;
1
N/A
error_info
.
line
= 0;
1
N/A
1
N/A
/*
1
N/A
* fix up the translation record
1
N/A
*/
1
N/A
1
N/A
if
(
xp
)
1
N/A
{
1
N/A
t =
""
;
1
N/A
for
(;;)
1
N/A
{
1
N/A
for
(
bp
= 0,
px
=
xp
;
px
;
px
=
px
->
next
)
1
N/A
if
(
px
->
date
&& (!
bp
||
strcoll
(
bp
->
date
,
px
->
date
) < 0))
1
N/A
bp
=
px
;
1
N/A
if
(!
bp
)
1
N/A
break
;
1
N/A
sfprintf
(
tp
,
"%s%s %s"
, t,
bp
->
name
,
bp
->
date
);
1
N/A
t =
", "
;
1
N/A
bp
->
date
= 0;
1
N/A
}
1
N/A
if
(!(
mc
->
translation
=
sfstruse
(
tp
)))
1
N/A
error
(
ERROR_SYSTEM
|
3
,
"out of space"
);
1
N/A
}
1
N/A
1
N/A
/*
1
N/A
* dump the catalog to a local temporary
1
N/A
* rename if no errors
1
N/A
*/
1
N/A
1
N/A
if
(!(s =
pathtemp
(
NiL
, 0,
""
,
error_info
.
id
,
NiL
)) || !(
sp
=
sfopen
(
NiL
, s,
"w"
)))
1
N/A
error
(
ERROR_SYSTEM
|
3
,
"%s: cannot write catalog file"
,
catfile
);
1
N/A
if
(
mcdump
(
mc
,
sp
) ||
mcclose
(
mc
) ||
sfclose
(
sp
))
1
N/A
{
1
N/A
remove
(s);
1
N/A
error
(
ERROR_SYSTEM
|
3
,
"%s: temporary catalog file write error"
, s);
1
N/A
}
1
N/A
remove
(
catfile
);
1
N/A
if
(
rename
(s,
catfile
))
1
N/A
error
(
ERROR_SYSTEM
|
3
,
"%s: cannot rename from temporary catalog file %s"
,
catfile
, s);
1
N/A
return
error_info
.
errors
!= 0;
1
N/A
}