`number_set_parse': Improve diagnostics.
[ttfautohint.git] / lib / numberset.h
blob06943b4aae9bc36f5bbd4881df70096437825bfe
1 /* numberset.h */
3 /*
4 * Copyright (C) 2012 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.
16 #ifndef __NUMBERSET_H__
17 #define __NUMBERSET_H__
19 #ifdef __cplusplus
20 extern "C" {
21 #endif
24 * A structure defining an integer range, to be used as a linked list. It
25 * gets allocated by a successful call to `parse_number_set'. Use
26 * `number_set_free' to deallocate it.
29 typedef struct number_range_
31 int start;
32 int end;
34 struct number_range_* next;
35 } number_range;
39 * Parse a description in string `s' for a set of non-negative integers
40 * within the limits given by the input parameters `min' and `max', and
41 * which consists of the following ranges, separated by commas (`n' and `m'
42 * are non-negative integers):
44 * -n min <= x <= n
45 * n x = n; this is a shorthand for `n-n'
46 * n-m n <= x <= m (or m <= x <= n if m < n)
47 * m- m <= x <= max
48 * - min <= x <= max
50 * Superfluous commas are ignored, as is whitespace around numbers, dashes,
51 * and commas. The ranges must be ordered, without overlaps. As a
52 * consequence, `-n' and `m-' can occur at most once and must be then the
53 * first and last range, respectively; similarly, `-' cannot be paired with
54 * any other range.
56 * In the following examples, `min' is 4 and `max' is 12:
58 * - -> 4, 5, 6, 7, 8, 9, 10, 11, 12
59 * -3, 5- -> invalid first range
60 * 4, 6-8, 10- -> 4, 6, 7, 8, 10, 11, 12
61 * 4-8, 6-10 -> invalid overlapping ranges
63 * In case of success (this is, the number set description in `s' is valid)
64 * the return value is a pointer to the final zero byte in string `s'. In
65 * case of an error, the return value is a pointer to the beginning position
66 * of the offending range in string `s'.
68 * If the user provides a non-NULL `number_set' value, `number_set_parse'
69 * stores a linked list of ordered number ranges in `*number_set', allocated
70 * with `malloc'. If there is no range at all (for example, an empty string
71 * or whitespace and commas only) no data gets allocated, and `*number_set'
72 * is set to NULL. In case of error, `*number_set' returns an error code;
73 * you should use the following macros to compare with.
75 * NUMBERSET_INVALID_CHARACTER invalid character in description string
76 * NUMBERSET_OVERFLOW numerical overflow
77 * NUMBERSET_INVALID_RANGE invalid range, exceeding `min' or `max'
78 * NUMBERSET_OVERLAPPING_RANGES overlapping ranges
79 * NUMBERSET_NOT_ASCENDING not ascending ranges or values
80 * NUMBERSET_ALLOCATION_ERROR allocation error
82 * Note that a negative value for `min' is replaced with zero, and a
83 * negative value for `max' with the largest representable integer, INT_MAX.
86 #define NUMBERSET_INVALID_CHARACTER (number_range*)-1
87 #define NUMBERSET_OVERFLOW (number_range*)-2
88 #define NUMBERSET_INVALID_RANGE (number_range*)-3
89 #define NUMBERSET_OVERLAPPING_RANGES (number_range*)-4
90 #define NUMBERSET_NOT_ASCENDING (number_range*)-5
91 #define NUMBERSET_ALLOCATION_ERROR (number_range*)-6
93 const char*
94 number_set_parse(const char* s,
95 number_range** number_set,
96 int min,
97 int max);
101 * Free the allocated data in `number_set'.
104 void
105 number_set_free(number_range* number_set);
109 * Return a string representation of `number_set', viewed through a
110 * `window', so to say, spanned up by the parameters `min' and `max'. After
111 * use, the string should be deallocated with a call to `free'. In case of
112 * an allocation error, the return value is NULL.
114 * Note that a negative value for `min' is replaced with zero, and a
115 * negative value for `max' with the largest representable integer, INT_MAX.
118 char*
119 number_set_show(number_range* number_set,
120 int min,
121 int max);
125 * Return value 1 if `number' is element of `number_set', zero otherwise.
129 number_set_is_element(number_range* number_set,
130 int number);
132 #ifdef __cplusplus
133 } /* extern "C" */
134 #endif
136 #endif /* __NUMBERSET_H__ */
138 /* end of numberset.h */