4 * Copyright (C) 2012-2014 by Werner Lemberg.
6 * This file is part of the ttfautohint library, and may only be used,
7 * modified, and distributed under the terms given in `COPYING'. By
8 * continuing to use, modify, or distribute this file you indicate that you
9 * have read `COPYING' and understand and accept it fully.
11 * The file `COPYING' mentioned in the previous paragraph is distributed
12 * with the ttfautohint library.
22 #include <numberset.h>
26 number_set_new(int start
,
44 if (start
< min
|| end
> max
)
45 return NUMBERSET_INVALID_RANGE
;
47 nr
= (number_range
*)malloc(sizeof (number_range
));
49 return NUMBERSET_ALLOCATION_ERROR
;
60 number_set_prepend(number_range
* list
,
61 number_range
* element
)
66 if (element
->start
<= list
->end
)
68 if (element
->end
< list
->start
)
69 return NUMBERSET_NOT_ASCENDING
;
71 return NUMBERSET_OVERLAPPING_RANGES
;
75 && element
->start
== list
->end
+ 1)
77 /* merge adjacent ranges */
78 list
->end
= element
->end
;
92 number_set_reverse(number_range
* list
)
116 number_set_parse(const char* s
,
117 number_range
** number_set
,
121 number_range
* cur
= NULL
;
122 number_range
* new_range
;
125 const char* last_pos
= s
;
129 number_range
* error_code
= NULL
;
166 else if (isdigit(*s
))
174 || (n
== INT_MAX
/ 10 && digit
> 5))
176 error_code
= NUMBERSET_OVERFLOW
;
182 } while (isdigit(*s
));
191 break; /* end of data */
194 error_code
= NUMBERSET_INVALID_CHARACTER
;
212 || (m
== INT_MAX
/ 10 && digit
> 5))
214 error_code
= NUMBERSET_OVERFLOW
;
220 } while (isdigit(*s
));
239 if (n
< min
|| m
> max
)
241 error_code
= NUMBERSET_INVALID_RANGE
;
248 error_code
= NUMBERSET_NOT_ASCENDING
;
250 error_code
= NUMBERSET_OVERLAPPING_RANGES
;
255 && last_end
+ 1 == n
)
257 /* merge adjacent ranges */
264 new_range
= (number_range
*)malloc(sizeof (number_range
));
267 error_code
= NUMBERSET_ALLOCATION_ERROR
;
271 /* prepend new range to list */
272 new_range
->start
= n
;
274 new_range
->next
= cur
;
285 number_set_free(cur
);
289 *number_set
= error_code
;
293 /* success; now reverse list to have elements in ascending order */
294 number_range
* list
= NULL
;
314 number_set_free(number_range
* number_set
)
316 number_range
* nr
= number_set
;
332 number_set_show(number_range
* number_set
,
341 number_range
* nr
= number_set
;
360 /* we return an empty string for an empty number set */
361 /* (this is, number_set == NULL or unsuitable `min' and `max' values) */
362 s
= (char*)malloc(1);
376 comma
= (s_len
== 1) ? "" : ", ";
378 if (nr
->start
== nr
->end
)
379 tmp_len
= sprintf(tmp
, "%s%i",
381 else if (nr
->start
<= min
383 tmp_len
= sprintf(tmp
, "-");
384 else if (nr
->start
<= min
)
385 tmp_len
= sprintf(tmp
, "-%i",
387 else if (nr
->end
>= max
)
388 tmp_len
= sprintf(tmp
, "%s%i-",
391 tmp_len
= sprintf(tmp
, "%s%i-%i",
392 comma
, nr
->start
, nr
->end
);
394 s_len_new
= s_len
+ tmp_len
;
395 s_new
= (char*)realloc(s
, s_len_new
);
401 strcpy(s_new
+ s_len
- 1, tmp
);
414 number_set_is_element(number_range
* number_set
,
417 number_range
* nr
= number_set
;
422 if (number
< nr
->start
)
424 if (nr
->start
<= number
425 && number
<= nr
->end
)
435 number_set_get_first(number_set_iter
* iter_p
)
437 if (!iter_p
|| !iter_p
->range
)
440 iter_p
->val
= iter_p
->range
->start
;
447 number_set_get_next(number_set_iter
* iter_p
)
449 if (!iter_p
|| !iter_p
->range
)
454 if (iter_p
->val
> iter_p
->range
->end
)
456 iter_p
->range
= iter_p
->range
->next
;
459 iter_p
->val
= iter_p
->range
->start
;
465 /* end of numberset.c */