Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4680 | right-hear | 1 | #include "fitz.h" |
2 | #include "muxps.h" |
||
3 | |||
4 | static inline int xps_tolower(int c) |
||
5 | { |
||
6 | if (c >= 'A' && c <= 'Z') |
||
7 | return c + 32; |
||
8 | return c; |
||
9 | } |
||
10 | |||
11 | int |
||
12 | xps_strcasecmp(char *a, char *b) |
||
13 | { |
||
14 | while (xps_tolower(*a) == xps_tolower(*b)) |
||
15 | { |
||
16 | if (*a++ == 0) |
||
17 | return 0; |
||
18 | b++; |
||
19 | } |
||
20 | return xps_tolower(*a) - xps_tolower(*b); |
||
21 | } |
||
22 | |||
23 | #define SEP(x) ((x)=='/' || (x) == 0) |
||
24 | |||
25 | static char * |
||
26 | xps_clean_path(char *name) |
||
27 | { |
||
28 | char *p, *q, *dotdot; |
||
29 | int rooted; |
||
30 | |||
31 | rooted = name[0] == '/'; |
||
32 | |||
33 | /* |
||
34 | * invariants: |
||
35 | * p points at beginning of path element we're considering. |
||
36 | * q points just past the last path element we wrote (no slash). |
||
37 | * dotdot points just past the point where .. cannot backtrack |
||
38 | * any further (no slash). |
||
39 | */ |
||
40 | p = q = dotdot = name + rooted; |
||
41 | while (*p) |
||
42 | { |
||
43 | if(p[0] == '/') /* null element */ |
||
44 | p++; |
||
45 | else if (p[0] == '.' && SEP(p[1])) |
||
46 | p += 1; /* don't count the separator in case it is nul */ |
||
47 | else if (p[0] == '.' && p[1] == '.' && SEP(p[2])) |
||
48 | { |
||
49 | p += 2; |
||
50 | if (q > dotdot) /* can backtrack */ |
||
51 | { |
||
52 | while(--q > dotdot && *q != '/') |
||
53 | ; |
||
54 | } |
||
55 | else if (!rooted) /* /.. is / but ./../ is .. */ |
||
56 | { |
||
57 | if (q != name) |
||
58 | *q++ = '/'; |
||
59 | *q++ = '.'; |
||
60 | *q++ = '.'; |
||
61 | dotdot = q; |
||
62 | } |
||
63 | } |
||
64 | else /* real path element */ |
||
65 | { |
||
66 | if (q != name+rooted) |
||
67 | *q++ = '/'; |
||
68 | while ((*q = *p) != '/' && *q != 0) |
||
69 | p++, q++; |
||
70 | } |
||
71 | } |
||
72 | |||
73 | if (q == name) /* empty string is really "." */ |
||
74 | *q++ = '.'; |
||
75 | *q = '\0'; |
||
76 | |||
77 | return name; |
||
78 | } |
||
79 | |||
80 | void |
||
81 | xps_absolute_path(char *output, char *base_uri, char *path, int output_size) |
||
82 | { |
||
83 | if (path[0] == '/') |
||
84 | { |
||
85 | fz_strlcpy(output, path, output_size); |
||
86 | } |
||
87 | else |
||
88 | { |
||
89 | fz_strlcpy(output, base_uri, output_size); |
||
90 | fz_strlcat(output, "/", output_size); |
||
91 | fz_strlcat(output, path, output_size); |
||
92 | } |
||
93 | xps_clean_path(output); |
||
94 | }=> |