1 /*
2 * Functions necessary to handle pandoc URLs.
3 * Copyright (C) 2018 Michael Goehler
4 *
5 * This file is part of mdp.
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 *
20 */
21
22 #include <stdlib.h>
23 #include <assert.h>
24 #include <wchar.h>
25 #include <stdio.h>
26
27 #include "url.h"
28
29 static void url_del_elem(url_t *elem);
30 static void url_print(url_t *u);
31
32 static url_t *list;
33 static int index_max;
34 static int init_ok;
35
url_init(void)36 void url_init(void) {
37 list = NULL;
38 index_max = 0;
39 init_ok = 1;
40 }
41
url_add(const wchar_t * link_name,int link_name_length,const wchar_t * target,int target_length,int x,int y)42 int url_add(const wchar_t *link_name, int link_name_length, const wchar_t *target, int target_length, int x, int y) {
43 if (!init_ok) return -1;
44
45 url_t *tmp = NULL;
46 int i = 0;
47
48 if (list) {
49 tmp = list;
50 while (tmp->next) {
51 tmp = tmp->next;
52 i++;
53 }
54 tmp->next = malloc(sizeof(url_t));
55 assert(tmp->next);
56 tmp = tmp->next;
57 } else {
58 list = malloc(sizeof(url_t));
59 tmp = list;
60 assert(tmp);
61 }
62
63 tmp -> link_name = calloc(link_name_length+1, sizeof(wchar_t));
64 assert(tmp->link_name);
65 wcsncpy(tmp->link_name, link_name, link_name_length);
66 tmp->link_name[link_name_length] = '\0';
67
68 tmp->target = calloc(target_length+1, sizeof(wchar_t));
69 assert(tmp->target);
70 wcsncpy(tmp->target, target, target_length);
71 tmp->target[target_length] = '\0';
72
73 tmp->x = x;
74 tmp->y = y;
75 tmp->next = NULL;
76
77 index_max++;
78
79 return index_max-1;
80 }
81
url_get_target(int index)82 wchar_t * url_get_target(int index) {
83 if (!init_ok) return NULL;
84
85 url_t *tmp = list;
86
87 if (!tmp) return NULL;
88
89 while (index > 0 && tmp && tmp->next) {
90 tmp = tmp->next;
91 index--;
92 }
93
94 if (!index) {
95 return tmp->target;
96 } else return NULL;
97 }
98
url_get_name(int index)99 wchar_t * url_get_name(int index) {
100 url_t *tmp = list;
101
102 while (index > 0 && tmp && tmp->next) {
103 tmp = tmp->next;
104 index --;
105 }
106
107 if (!index) {
108 return tmp->link_name;
109 } else return NULL;
110 }
111
url_purge()112 void url_purge() {
113 url_del_elem(list);
114 list = NULL;
115 index_max = 0;
116 init_ok = 0;
117 }
118
url_del_elem(url_t * elem)119 static void url_del_elem(url_t *elem) {
120 if (!elem) return;
121
122 if (elem->next) {
123 url_del_elem(elem->next);
124 elem->next = NULL;
125 }
126
127 if (elem->target) {
128 free(elem->target);
129 elem->target = NULL;
130 }
131
132 if (elem->link_name) {
133 free(elem->link_name);
134 elem->link_name = NULL;
135 }
136
137 free(elem);
138 }
139
url_dump(void)140 void url_dump(void) {
141 if (!list) return;
142
143 url_t *tmp = list;
144
145 while (tmp) {
146 url_print(tmp);
147 if (tmp->next)
148 tmp = tmp->next;
149 else break;
150 }
151 }
152
url_print(url_t * u)153 static void url_print(url_t *u) {
154 printf("url_t @ %p\n", u);
155 }
156
url_get_amount(void)157 int url_get_amount(void) {
158 return index_max;
159 }
160
url_count_inline(const wchar_t * line)161 int url_count_inline(const wchar_t *line) {
162 int count = 0;
163 const wchar_t *i = line;
164
165 for (; *i; i++) {
166 if (*i == '\\') {
167 i++;
168 } else if ( *i == '[' && *(i+1) && *(i+1) != ']') {
169 while (*i && *i != ']') i++;
170 i++;
171 if (*i == '(' && wcschr(i, ')')) {
172 count ++;
173 i = wcschr(i, ')');
174 }
175 }
176 }
177
178 return count;
179 }
180
url_len_inline(const wchar_t * value)181 int url_len_inline(const wchar_t *value) {
182 int count = 0;
183 const wchar_t *i = value;
184
185 for (; *i; i++) {
186 if (*i == '\\') {
187 i++;
188 } else if ( *i == '[' && *(i+1) && *(i+1) != ']') {
189 while (*i && *i != ']') i++;
190 i++;
191 if (*i == '(' && wcschr(i, ')')) {
192 while (*i && *i != ')') {
193 count++;
194 i++;
195 }
196 }
197 }
198 }
199
200 return count;
201 }
202