Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
MariaDB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
192ad598
Commit
192ad598
authored
Jan 10, 2003
by
bar@bar.mysql.r18.ru
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
xml.c:
new file
parent
492eba03
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
374 additions
and
0 deletions
+374
-0
strings/xml.c
strings/xml.c
+374
-0
No files found.
strings/xml.c
0 → 100644
View file @
192ad598
/* Copyright (C) 2000 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "my_global.h"
#include "m_string.h"
#include "my_xml.h"
#define MY_XML_EOF 'E'
#define MY_XML_STRING 'S'
#define MY_XML_IDENT 'I'
#define MY_XML_EQ '='
#define MY_XML_LT '<'
#define MY_XML_GT '>'
#define MY_XML_SLASH '/'
#define MY_XML_COMMENT 'C'
#define MY_XML_TEXT 'T'
#define MY_XML_QUESTION '?'
#define MY_XML_EXCLAM '!'
typedef
struct
xml_attr_st
{
const
char
*
beg
;
const
char
*
end
;
}
MY_XML_ATTR
;
static
const
char
*
lex2str
(
int
lex
)
{
switch
(
lex
)
{
case
MY_XML_EOF
:
return
"EOF"
;
case
MY_XML_STRING
:
return
"STRING"
;
case
MY_XML_IDENT
:
return
"IDENT"
;
case
MY_XML_EQ
:
return
"'='"
;
case
MY_XML_LT
:
return
"'<'"
;
case
MY_XML_GT
:
return
"'>'"
;
case
MY_XML_SLASH
:
return
"'/'"
;
case
MY_XML_COMMENT
:
return
"COMMENT"
;
case
MY_XML_TEXT
:
return
"TEXT"
;
case
MY_XML_QUESTION
:
return
"'?'"
;
case
MY_XML_EXCLAM
:
return
"'!'"
;
}
return
"UNKNOWN"
;
}
static
void
my_xml_norm_text
(
MY_XML_ATTR
*
a
)
{
for
(
;
(
a
->
beg
<
a
->
end
)
&&
strchr
(
"
\t\r\n
"
,
a
->
beg
[
0
])
;
a
->
beg
++
);
for
(
;
(
a
->
beg
<
a
->
end
)
&&
strchr
(
"
\t\r\n
"
,
a
->
end
[
-
1
])
;
a
->
end
--
);
}
static
int
my_xml_scan
(
MY_XML_PARSER
*
p
,
MY_XML_ATTR
*
a
)
{
int
lex
;
for
(
;
(
p
->
cur
<
p
->
end
)
&&
strchr
(
"
\t\r\n
"
,
p
->
cur
[
0
])
;
p
->
cur
++
);
if
(
p
->
cur
>=
p
->
end
)
{
a
->
beg
=
p
->
end
;
a
->
end
=
p
->
end
;
lex
=
MY_XML_EOF
;
goto
ret
;
}
a
->
beg
=
p
->
cur
;
a
->
end
=
p
->
cur
;
if
(
!
memcmp
(
p
->
cur
,
"<!--"
,
4
))
{
for
(
;
(
p
->
cur
<
p
->
end
)
&&
memcmp
(
p
->
cur
,
"-->"
,
3
);
p
->
cur
++
);
if
(
!
memcmp
(
p
->
cur
,
"-->"
,
3
))
p
->
cur
+=
3
;
a
->
end
=
p
->
cur
;
lex
=
MY_XML_COMMENT
;
}
else
if
(
strchr
(
"?=/<>!"
,
p
->
cur
[
0
]))
{
p
->
cur
++
;
a
->
end
=
p
->
cur
;
lex
=
a
->
beg
[
0
];
}
else
if
(
(
p
->
cur
[
0
]
==
'"'
)
||
(
p
->
cur
[
0
]
==
'\''
)
)
{
p
->
cur
++
;
for
(
;
(
p
->
cur
<
p
->
end
)
&&
(
p
->
cur
[
0
]
!=
a
->
beg
[
0
]);
p
->
cur
++
);
a
->
end
=
p
->
cur
;
if
(
a
->
beg
[
0
]
==
p
->
cur
[
0
])
p
->
cur
++
;
a
->
beg
++
;
my_xml_norm_text
(
a
);
lex
=
MY_XML_STRING
;
}
else
{
for
(
;
(
p
->
cur
<
p
->
end
)
&&
!
strchr
(
"?'
\"
=/<>
\t\r\n
"
,
p
->
cur
[
0
]);
p
->
cur
++
);
a
->
end
=
p
->
cur
;
my_xml_norm_text
(
a
);
lex
=
MY_XML_IDENT
;
}
#if 0
printf("LEX=%s[%d]\n",lex2str(lex),a->end-a->beg);
#endif
ret:
return
lex
;
}
static
int
my_xml_value
(
MY_XML_PARSER
*
st
,
const
char
*
str
,
uint
len
)
{
return
(
st
->
value
)
?
(
st
->
value
)(
st
,
str
,
len
)
:
MY_XML_OK
;
}
static
int
my_xml_enter
(
MY_XML_PARSER
*
st
,
const
char
*
str
,
uint
len
)
{
if
(
(
st
->
attrend
-
st
->
attr
+
len
+
1
)
>
sizeof
(
st
->
attr
))
{
sprintf
(
st
->
errstr
,
"To deep XML"
);
return
MY_XML_ERROR
;
}
if
(
st
->
attrend
>
st
->
attr
)
{
st
->
attrend
[
0
]
=
'.'
;
st
->
attrend
++
;
}
memcpy
(
st
->
attrend
,
str
,
len
);
st
->
attrend
+=
len
;
st
->
attrend
[
0
]
=
'\0'
;
return
st
->
enter
?
st
->
enter
(
st
,
st
->
attr
,
st
->
attrend
-
st
->
attr
)
:
MY_XML_OK
;
}
static
void
mstr
(
char
*
s
,
const
char
*
src
,
uint
l1
,
uint
l2
)
{
l1
=
l1
<
l2
?
l1
:
l2
;
memcpy
(
s
,
src
,
l1
);
s
[
l1
]
=
'\0'
;
}
static
int
my_xml_leave
(
MY_XML_PARSER
*
p
,
const
char
*
str
,
uint
slen
)
{
char
*
e
;
uint
glen
;
char
s
[
32
];
char
g
[
32
];
int
rc
;
/* Find previous '.' or beginning */
for
(
e
=
p
->
attrend
;
(
e
>
p
->
attr
)
&&
(
e
[
0
]
!=
'.'
)
;
e
--
);
glen
=
(
e
[
0
]
==
'.'
)
?
(
p
->
attrend
-
e
-
1
)
:
p
->
attrend
-
e
;
if
(
str
&&
(
slen
!=
glen
))
{
mstr
(
s
,
str
,
sizeof
(
s
)
-
1
,
slen
);
mstr
(
g
,
e
+
1
,
sizeof
(
g
)
-
1
,
glen
),
sprintf
(
p
->
errstr
,
"'</%s>' unexpected ('</%s>' wanted)"
,
s
,
g
);
return
MY_XML_ERROR
;
}
rc
=
p
->
leave
?
p
->
leave
(
p
,
p
->
attr
,
p
->
attrend
-
p
->
attr
)
:
MY_XML_OK
;
*
e
=
'\0'
;
p
->
attrend
=
e
;
return
rc
;
}
int
my_xml_parse
(
MY_XML_PARSER
*
p
,
const
char
*
str
,
uint
len
)
{
p
->
attrend
=
p
->
attr
;
p
->
beg
=
str
;
p
->
cur
=
str
;
p
->
end
=
str
+
len
;
while
(
p
->
cur
<
p
->
end
)
{
MY_XML_ATTR
a
;
if
(
p
->
cur
[
0
]
==
'<'
)
{
int
lex
;
int
question
=
0
;
int
exclam
=
0
;
lex
=
my_xml_scan
(
p
,
&
a
);
if
(
MY_XML_COMMENT
==
lex
)
{
continue
;
}
lex
=
my_xml_scan
(
p
,
&
a
);
if
(
MY_XML_SLASH
==
lex
)
{
if
(
MY_XML_IDENT
!=
(
lex
=
my_xml_scan
(
p
,
&
a
)))
{
sprintf
(
p
->
errstr
,
"1: %s unexpected (ident wanted)"
,
lex2str
(
lex
));
return
MY_XML_ERROR
;
}
if
(
MY_XML_OK
!=
my_xml_leave
(
p
,
a
.
beg
,
a
.
end
-
a
.
beg
))
return
MY_XML_ERROR
;
lex
=
my_xml_scan
(
p
,
&
a
);
goto
gt
;
}
if
(
MY_XML_EXCLAM
==
lex
)
{
lex
=
my_xml_scan
(
p
,
&
a
);
exclam
=
1
;
}
else
if
(
MY_XML_QUESTION
==
lex
)
{
lex
=
my_xml_scan
(
p
,
&
a
);
question
=
1
;
}
if
(
MY_XML_IDENT
==
lex
)
{
if
(
MY_XML_OK
!=
my_xml_enter
(
p
,
a
.
beg
,
a
.
end
-
a
.
beg
))
return
MY_XML_ERROR
;
}
else
{
sprintf
(
p
->
errstr
,
"3: %s unexpected (ident or '/' wanted)"
,
lex2str
(
lex
));
return
MY_XML_ERROR
;
}
while
((
MY_XML_IDENT
==
(
lex
=
my_xml_scan
(
p
,
&
a
)))
||
(
MY_XML_STRING
==
lex
))
{
MY_XML_ATTR
b
;
if
(
MY_XML_EQ
==
(
lex
=
my_xml_scan
(
p
,
&
b
)))
{
lex
=
my_xml_scan
(
p
,
&
b
);
if
(
(
lex
==
MY_XML_IDENT
)
||
(
lex
=
MY_XML_STRING
)
)
{
if
((
MY_XML_OK
!=
my_xml_enter
(
p
,
a
.
beg
,
a
.
end
-
a
.
beg
))
||
(
MY_XML_OK
!=
my_xml_value
(
p
,
b
.
beg
,
b
.
end
-
b
.
beg
))
||
(
MY_XML_OK
!=
my_xml_leave
(
p
,
a
.
beg
,
a
.
end
-
a
.
beg
)))
return
MY_XML_ERROR
;
}
else
{
sprintf
(
p
->
errstr
,
"4: %s unexpected (ident or string wanted)"
,
lex2str
(
lex
));
return
MY_XML_ERROR
;
}
}
else
if
(
(
MY_XML_STRING
==
lex
)
||
(
MY_XML_IDENT
==
lex
)
)
{
if
((
MY_XML_OK
!=
my_xml_enter
(
p
,
a
.
beg
,
a
.
end
-
a
.
beg
))
||
(
MY_XML_OK
!=
my_xml_leave
(
p
,
a
.
beg
,
a
.
end
-
a
.
beg
)))
return
MY_XML_ERROR
;
}
else
break
;
}
if
(
lex
==
MY_XML_SLASH
)
{
if
(
MY_XML_OK
!=
my_xml_leave
(
p
,
NULL
,
0
))
return
MY_XML_ERROR
;
lex
=
my_xml_scan
(
p
,
&
a
);
}
gt:
if
(
question
)
{
if
(
lex
!=
MY_XML_QUESTION
)
{
sprintf
(
p
->
errstr
,
"6: %s unexpected ('?' wanted)"
,
lex2str
(
lex
));
return
MY_XML_ERROR
;
}
if
(
MY_XML_OK
!=
my_xml_leave
(
p
,
NULL
,
0
))
return
MY_XML_ERROR
;
lex
=
my_xml_scan
(
p
,
&
a
);
}
if
(
exclam
)
{
if
(
MY_XML_OK
!=
my_xml_leave
(
p
,
NULL
,
0
))
return
MY_XML_ERROR
;
}
if
(
lex
!=
MY_XML_GT
)
{
sprintf
(
p
->
errstr
,
"5: %s unexpected ('>' wanted)"
,
lex2str
(
lex
));
return
MY_XML_ERROR
;
}
}
else
{
a
.
beg
=
p
->
cur
;
for
(
;
(
p
->
cur
<
p
->
end
)
&&
(
p
->
cur
[
0
]
!=
'<'
)
;
p
->
cur
++
);
a
.
end
=
p
->
cur
;
my_xml_norm_text
(
&
a
);
if
(
a
.
beg
!=
a
.
end
)
{
my_xml_value
(
p
,
a
.
beg
,
a
.
end
-
a
.
beg
);
}
}
}
return
MY_XML_OK
;
}
void
my_xml_parser_create
(
MY_XML_PARSER
*
p
)
{
bzero
((
void
*
)
p
,
sizeof
(
p
[
0
]));
}
void
my_xml_parser_free
(
MY_XML_PARSER
*
p
__attribute__
((
unused
)))
{
}
void
my_xml_set_value_handler
(
MY_XML_PARSER
*
p
,
int
(
*
action
)(
MY_XML_PARSER
*
p
,
const
char
*
s
,
uint
l
))
{
p
->
value
=
action
;
}
void
my_xml_set_enter_handler
(
MY_XML_PARSER
*
p
,
int
(
*
action
)(
MY_XML_PARSER
*
p
,
const
char
*
s
,
uint
l
))
{
p
->
enter
=
action
;
}
void
my_xml_set_leave_handler
(
MY_XML_PARSER
*
p
,
int
(
*
action
)(
MY_XML_PARSER
*
p
,
const
char
*
s
,
uint
l
))
{
p
->
leave
=
action
;
}
void
my_xml_set_user_data
(
MY_XML_PARSER
*
p
,
void
*
user_data
)
{
p
->
user_data
=
user_data
;
}
const
char
*
my_xml_error_string
(
MY_XML_PARSER
*
p
)
{
return
p
->
errstr
;
}
uint
my_xml_error_pos
(
MY_XML_PARSER
*
p
)
{
const
char
*
beg
=
p
->
beg
;
const
char
*
s
;
for
(
s
=
p
->
beg
;
s
<
p
->
cur
;
s
++
)
if
(
s
[
0
]
==
'\n'
)
beg
=
s
;
return
p
->
cur
-
beg
;
}
uint
my_xml_error_lineno
(
MY_XML_PARSER
*
p
)
{
uint
res
=
0
;
const
char
*
s
;
for
(
s
=
p
->
beg
;
s
<
p
->
cur
;
s
++
)
if
(
s
[
0
]
==
'\n'
)
res
++
;
return
res
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment