4 * Copyright (C) 2012-2017 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.
25 #include <numberset.h>
29 number_set_new(int start
,
47 if (start
< min
|| end
> max
)
48 return NUMBERSET_INVALID_RANGE
;
50 nr
= (number_range
*)malloc(sizeof (number_range
));
52 return NUMBERSET_ALLOCATION_ERROR
;
63 number_set_prepend(number_range
* list
,
64 number_range
* element
)
72 if (element
->start
<= list
->end
)
74 if (element
->end
< list
->start
)
75 return NUMBERSET_NOT_ASCENDING
;
77 return NUMBERSET_OVERLAPPING_RANGES
;
80 if (element
->start
== list
->end
+ 1)
82 /* merge adjacent ranges */
83 list
->end
= element
->end
;
97 number_set_insert(number_range
* list
,
98 number_range
* element
)
100 number_range
* nr
= list
;
113 if (element
->start
<= nr
->end
114 && element
->end
>= nr
->start
)
115 return NUMBERSET_OVERLAPPING_RANGES
;
117 /* merge adjacent ranges */
118 if (element
->start
== nr
->end
+ 1)
120 nr
->end
= element
->end
;
126 if (element
->end
+ 1 == nr
->start
)
128 nr
->start
= element
->start
;
136 if (element
->start
> nr
->end
)
139 prev
->next
= element
;
142 return prev
? list
: element
;
150 prev
->next
= element
;
151 element
->next
= NULL
;
158 number_set_normalize(number_range
* list
)
171 return list
; /* only a single element, nothing to do */
175 if (prev
->end
+ 1 == cur
->start
)
180 prev
->end
= cur
->end
;
200 number_set_reverse(number_range
* list
)
224 number_set_parse(const char* s
,
225 number_range
** number_set
,
229 number_range
* cur
= NULL
;
230 number_range
* new_range
;
232 const char* last_pos
= s
;
236 number_range
* error_code
= NULL
;
273 else if (isdigit(*s
))
281 || (n
== INT_MAX
/ 10 && digit
> 5))
283 error_code
= NUMBERSET_OVERFLOW
;
289 } while (isdigit(*s
));
298 break; /* end of data */
301 error_code
= NUMBERSET_INVALID_CHARACTER
;
319 || (m
== INT_MAX
/ 10 && digit
> 5))
321 error_code
= NUMBERSET_OVERFLOW
;
327 } while (isdigit(*s
));
346 if (n
< min
|| m
> max
)
348 error_code
= NUMBERSET_INVALID_RANGE
;
355 error_code
= NUMBERSET_NOT_ASCENDING
;
357 error_code
= NUMBERSET_OVERLAPPING_RANGES
;
362 && last_end
+ 1 == n
)
364 /* merge adjacent ranges */
371 new_range
= (number_range
*)malloc(sizeof (number_range
));
374 error_code
= NUMBERSET_ALLOCATION_ERROR
;
378 /* prepend new range to list */
379 new_range
->start
= n
;
381 new_range
->next
= cur
;
392 number_set_free(cur
);
396 *number_set
= error_code
;
402 *number_set
= number_set_normalize(number_set_reverse(cur
));
410 number_set_free(number_range
* number_set
)
412 number_range
* nr
= number_set
;
428 number_set_show(number_range
* number_set
,
436 number_range
* nr
= number_set
;
464 comma
= *s
? ", " : "";
466 if (nr
->start
== nr
->end
)
467 s
= sdscatprintf(s
, "%s%i", comma
, nr
->start
);
468 else if (nr
->start
<= min
470 s
= sdscatprintf(s
, "-");
471 else if (nr
->start
<= min
)
472 s
= sdscatprintf(s
, "-%i", nr
->end
);
473 else if (nr
->end
>= max
)
474 s
= sdscatprintf(s
, "%s%i-", comma
, nr
->start
);
476 s
= sdscatprintf(s
, "%s%i-%i", comma
, nr
->start
, nr
->end
);
486 /* we return an empty string for an empty number set */
487 /* (this is, number_set == NULL or unsuitable `min' and `max' values) */
489 res
= (char*)malloc(len
);
500 number_set_is_element(number_range
* number_set
,
503 number_range
* nr
= number_set
;
508 if (number
< nr
->start
)
510 if (nr
->start
<= number
511 && number
<= nr
->end
)
521 number_set_get_first(number_set_iter
* iter_p
)
523 if (!iter_p
|| !iter_p
->range
)
526 iter_p
->val
= iter_p
->range
->start
;
533 number_set_get_next(number_set_iter
* iter_p
)
535 if (!iter_p
|| !iter_p
->range
)
540 if (iter_p
->val
> iter_p
->range
->end
)
542 iter_p
->range
= iter_p
->range
->next
;
545 iter_p
->val
= iter_p
->range
->start
;
551 /* end of numberset.c */