Code

Fixed signed/unsigned problem with precision calc. Fixes bug #399604.
[inkscape.git] / src / extract-uri.cpp
1 #include <string.h>
2 #include <glib.h>
4 // FIXME: kill this ugliness when we have a proper CSS parser
6 // Functions as per 4.3.4 of CSS 2.1
7 // http://www.w3.org/TR/CSS21/syndata.html#uri
8 gchar *extract_uri( gchar const *s, gchar const** endptr )
9 {
10     if (!s)
11         return NULL;
13     gchar* result = NULL;
14     gchar const *sb = s;
15     if ( strlen(sb) < 4 || strncmp(sb, "url", 3) != 0 ) {
16         return NULL;
17     }
19     sb += 3;
21     if ( endptr ) {
22         *endptr = 0;
23     }
25     // This first whitespace technically is not allowed.
26     // Just left in for now for legacy behavior.
27     while ( ( *sb == ' ' ) ||
28             ( *sb == '\t' ) )
29     {
30         sb++;
31     }
33     if ( *sb == '(' ) {
34         sb++;
35         while ( ( *sb == ' ' ) ||
36                 ( *sb == '\t' ) )
37         {
38             sb++;
39         }
41         gchar delim = ')';
42         if ( (*sb == '\'' || *sb == '"') ) {
43             delim = *sb;
44             sb++;
45         }
46         gchar const* se = sb + 1;
47         while ( *se && (*se != delim) ) {
48             se++;
49         }
51         // we found the delimiter
52         if ( *se ) {
53             if ( delim == ')' ) {
54                 if ( endptr ) {
55                     *endptr = se + 1;
56                 }
58                 // back up for any trailing whitespace
59                 se--;
60                 while ( ( se[-1] == ' ' ) ||
61                         ( se[-1] == '\t' ) )
62                 {
63                     se--;
64                 }
66                 result = g_strndup(sb, se - sb + 1);
67             } else {
68                 gchar const* tail = se + 1;
69                 while ( ( *tail == ' ' ) ||
70                         ( *tail == '\t' ) )
71                 {
72                     tail++;
73                 }
74                 if ( *tail == ')' ) {
75                     if ( endptr ) {
76                         *endptr = tail + 1;
77                     }
78                     result = g_strndup(sb, se - sb);
79                 }
80             }
81         }
82     }
84     return result;
85 }
87 /*
88   Local Variables:
89   mode:c++
90   c-file-style:"stroustrup"
91   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
92   indent-tabs-mode:nil
93   fill-column:99
94   End:
95 */
96 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :