Spracherkennung für: .y vermutete Sprache: Masm {Masm[60] PHP[45] ABAP[36]} [Methode: maximale Elemente, drei Dimensionen]
%{
/*
*
This is a plug-in
for GIMP.
*
* Generates clickable image maps.
*
* Copyright (C)
1998-
2005 Maurits Rijk lpeek.mrijk@consunet.nl
*
*
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 3 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, see <
https://www.gnu.org/licenses/>.
*
*/
#
include <stdlib.h>
#
include <
string.h>
#
include <glib/gstdio.h>
#
include <gtk/gtk.h>
#
include "imap_circle.h"
#
include "imap_file.h"
#
include "imap_main.h"
#
include "imap_polygon.h"
#
include "imap_rectangle.h"
#
include "imap_string.h"
extern int csim_lex(void)
;
extern int csim_restart(FILE *csim_in)
;
static void csim_error(char* s)
;
static gchar * unescape_text(gchar *input)
;
static enum {UNDEFINED, RECTANGLE, CIRCLE, POLYGON} current_type
;
static Object_t *current_object
;
static MapInfo_t *_map_info
;
%}
%
union {
int val
;
double value
;
char *id
;
}
%token<val> IMG SRC
WIDTH HEIGHT BORDER USEMAP
%token<val> START_MAP END_MAP NAME AREA SHAPE COORDS ALT HREF NOHREF
%token<val> TARGET ONMOUSEOVER ONMOUSEOUT ONFOCUS ONBLUR ONCLICK
%token<val> ACCESSKEY TABINDEX AUTHOR DESCRIPTION BEGIN_COMMENT END_COMMENT
%token<value> FLOAT
%token<id>
STRING
%type<val> integer_value
%%
csim_file : image start_map comment_lines area_list end_map
;
image :
'<' IMG SRC
'=' STRING image_tags xhtml_close
{
g_strreplace(&_map_info->image_name, $
5)
;
g_free ($
5)
;
}
;
image_tags : /* Empty */
| image_tags image_tag
;
image_tag : image_width
| image_height
| BORDER
'=' integer_value {}
| USEMAP
'=' STRING { g_free ($
3)
; }
| ALT
'=' STRING { g_free ($
3)
; }
;
image_width :
WIDTH '=' integer_value
{
_map_info->old_image_width = $
3;
}
;
image_height : HEIGHT
'=' integer_value
{
_map_info->old_image_height = $
3;
}
;
integer_value : FLOAT
{
$$ = (gint) $
1;
}
|
STRING
{
$$ = (gint) g_ascii_strtod ($
1, NULL)
;
g_free ($
1)
;
}
;
start_map :
'<' START_MAP NAME
'=' STRING '>'
{
g_strreplace(&_map_info->
title, $
5)
;
g_free ($
5)
;
}
;
comment_lines : /* empty */
| comment_lines comment_line
;
comment_line : author_line
| description_line
| real_comment
;
real_comment : BEGIN_COMMENT
STRING END_COMMENT
{
g_free ($
2)
;
}
;
author_line : AUTHOR
STRING END_COMMENT
{
g_strreplace(&_map_info->author, $
2)
;
g_free ($
2)
;
}
;
description_line: DESCRIPTION
STRING END_COMMENT
{
gchar *description
;
description = g_strconcat(_map_info->description, $
2,
"\n",
NULL)
;
g_strreplace(&_map_info->description, description)
;
g_free ($
2)
;
}
;
area_list : /* empty */
| area_list area
;
area :
'<' AREA tag_list xhtml_close
{
if (current_type != UNDEFINED)
add_shape(current_object)
;
}
;
xhtml_close :
'>'
|
'/' '>'
;
tag_list : /* Empty */
| tag_list tag
;
tag : shape_tag
| coords_tag
| href_tag
| nohref_tag
| alt_tag
| target_tag
| onmouseover_tag
| onmouseout_tag
| onfocus_tag
| onblur_tag
| onclick_tag
| accesskey_tag
| tabindex_tag
;
shape_tag : SHAPE
'=' STRING
{
if (!g_ascii_strcasecmp($
3,
"RECT")) {
current_object = create_rectangle(
0,
0,
0,
0)
;
current_type = RECTANGLE
;
}
else if (!g_ascii_strcasecmp($
3,
"CIRCLE")) {
current_object = create_circle(
0,
0,
0)
;
current_type = CIRCLE
;
}
else if (!g_ascii_strcasecmp($
3,
"POLY")) {
current_object = create_polygon(NULL)
;
current_type = POLYGON
;
}
else if (!g_ascii_strcasecmp($
3,
"DEFAULT")) {
current_type = UNDEFINED
;
}
g_free ($
3)
;
}
;
coords_tag : COORDS
'=' STRING
{
char *p
;
if (current_type == RECTANGLE) {
Rectangle_t *rectangle
;
rectangle = ObjectToRectangle(current_object)
;
p = strtok($
3,
",")
;
rectangle->x = atoi(p)
;
p = strtok(NULL,
",")
;
rectangle->y = atoi(p)
;
p = strtok(NULL,
",")
;
rectangle->
width = atoi(p) - rectangle->x
;
p = strtok(NULL,
",")
;
rectangle->height = atoi(p) - rectangle->y
;
}
else if (current_type == CIRCLE) {
Circle_t *circle
;
circle = ObjectToCircle(current_object)
;
p = strtok($
3,
",")
;
circle->x = atoi(p)
;
p = strtok(NULL,
",")
;
circle->y = atoi(p)
;
p = strtok(NULL,
",")
;
circle->r = atoi(p)
;
}
else if (current_type == POLYGON) {
Polygon_t *polygon = ObjectToPolygon(current_object)
;
GList *points
;
GdkPoint *point, *first
;
gint x, y
;
p = strtok($
3,
",")
;
x = atoi(p)
;
p = strtok(NULL,
",")
;
y = atoi(p)
;
point = new_point(x, y)
;
points = g_list_append(NULL, (gpointer) point)
;
while(
1) {
p = strtok(NULL,
",")
;
if (!p)
break
;
x = atoi(p)
;
p = strtok(NULL,
",")
;
y = atoi(p)
;
point = new_point(x, y)
;
points = g_list_append(points, (gpointer) point)
;
}
/* Remove last point
if duplicate */
first = (GdkPoint*) points->
data;
polygon->points = points
;
if (first->x == point->x && first->y == point->y)
polygon_remove_last_point(polygon)
;
polygon->points = points
;
}
g_free ($
3)
;
}
;
href_tag : HREF
'=' STRING
{
if (current_type == UNDEFINED) {
g_strreplace(&_map_info->default_url, $
3)
;
}
else {
object_set_url(current_object, unescape_text($
3))
;
}
g_free ($
3)
;
}
;
nohref_tag : NOHREF optional_value
{
}
;
optional_value : /* Empty */
|
'=' STRING
{
g_free ($
2)
;
}
;
alt_tag : ALT
'=' STRING
{
object_set_comment(current_object, unescape_text($
3))
;
g_free ($
3)
;
}
;
target_tag : TARGET
'=' STRING
{
object_set_target(current_object, unescape_text($
3))
;
g_free ($
3)
;
}
;
onmouseover_tag : ONMOUSEOVER
'=' STRING
{
object_set_mouse_over(current_object, unescape_text($
3))
;
g_free ($
3)
;
}
;
onmouseout_tag : ONMOUSEOUT
'=' STRING
{
object_set_mouse_out(current_object, unescape_text($
3))
;
g_free ($
3)
;
}
;
onfocus_tag : ONFOCUS
'=' STRING
{
object_set_focus(current_object, unescape_text($
3))
;
g_free ($
3)
;
}
;
onblur_tag : ONBLUR
'=' STRING
{
object_set_blur(current_object, unescape_text($
3))
;
g_free ($
3)
;
}
;
onclick_tag : ONCLICK
'=' STRING
{
object_set_click(current_object, unescape_text($
3))
;
g_free ($
3)
;
}
;
accesskey_tag : ACCESSKEY
'=' STRING
{
object_set_accesskey(current_object, unescape_text($
3))
;
g_free ($
3)
;
}
;
tabindex_tag : TABINDEX
'=' STRING
{
object_set_tabindex(current_object, unescape_text($
3))
;
g_free ($
3)
;
}
;
end_map :
'<' END_MAP
'>'
;
%%
static void
csim_error(char* s)
{
extern FILE *csim_in
;
csim_restart(csim_in)
;
}
gboolean
load_csim (const char*
filename)
{
gboolean status
;
extern FILE *csim_in
;
csim_in = g_fopen(
filename,
"r")
;
if (csim_in) {
_map_info = get_map_info()
;
status = !csim_parse()
;
fclose(csim_in)
;
}
else {
status = FALSE
;
}
return status
;
}
static gchar*
unescape_text (gchar *input)
{
/*
* We
"unescape" simple things
"in place", knowing that unescaped
* strings always are shorter than the original input.
*
* It is a shame there is no g_markup_unescape_text() function, but
* instead you have to create a full GMarkupParser/Context.
*/
struct token {
const char *escaped
;
const char unescaped
;
}
;
const struct token tab[] = {
{
""", '"' },
{
"'", '\'' },
{
"&", '&' },
{
"<", '<' },
{
">", '>' }
}
;
size_t i
;
for (i =
0; i < (sizeof tab / sizeof tab[0]); i++)
{
const size_t escaped_len = strlen (tab[i].escaped)
;
char *p
;
/* FIXME: The following
code does not perform a UTF-
8 substring
search. */
for (p = strstr (input, tab[i].escaped)
;
p != NULL
;
p = strstr (p, tab[i].escaped))
{
size_t copy_len
;
*p++ = tab[i].unescaped
;
copy_len = strlen (p) - escaped_len +
2;
memmove (p, p + escaped_len -
1, copy_len)
;
if (*p ==
0)
break
;
}
}
return input
;
}