Evince
Evince is a document viewer capable of displaying multiple and single page document formats like PDF and Postscript.
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
pagesel.c File Reference
#include <config.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <limits.h>
#include "mdvi.h"
#include "private.h"
+ Include dependency graph for pagesel.c:

Go to the source code of this file.

Data Structures

struct  _DviPageSpec
 

Functions

DviRangemdvi_parse_range (const char *format, DviRange *limit, int *nitems, char **endptr)
 
DviPageSpecmdvi_parse_page_spec (const char *format)
 
int mdvi_page_selected (DviPageSpec *spec, PageNum page, int dvipage)
 
void mdvi_free_page_spec (DviPageSpec *spec)
 
int mdvi_in_range (DviRange *range, int nitems, int value)
 
int mdvi_range_length (DviRange *range, int nitems)
 

Variables

char * program_name = "page"
 

Function Documentation

void mdvi_free_page_spec ( DviPageSpec spec)

Definition at line 292 of file pagesel.c.

293 {
294  int i;
295 
296  for(i = 0; i < 11; i++)
297  if(spec[i]) {
298  mdvi_free(spec[i]->ranges);
299  mdvi_free(spec[i]);
300  }
301  mdvi_free(spec);
302 }
int mdvi_in_range ( DviRange range,
int  nitems,
int  value 
)

Definition at line 304 of file pagesel.c.

305 {
306  DviRange *r;
307 
308  for(r = range; r < range + nitems; r++) {
309  int cond;
310 
311  switch(r->type) {
312  case MDVI_RANGE_BOUNDED:
313  if(value == r->from)
314  return (r - range);
315  if(r->step < 0)
316  cond = (value <= r->from) && (value >= r->to);
317  else
318  cond = (value <= r->to) && (value >= r->from);
319  if(cond && ((value - r->from) % r->step) == 0)
320  return (r - range);
321  break;
322  case MDVI_RANGE_LOWER:
323  if(value == r->from)
324  return (r - range);
325  if(r->step < 0)
326  cond = (value < r->from);
327  else
328  cond = (value > r->from);
329  if(cond && ((value - r->from) % r->step) == 0)
330  return (r - range);
331  break;
332  case MDVI_RANGE_UPPER:
333  if(value == r->to)
334  return (r - range);
335  if(r->step < 0)
336  cond = (value > r->to);
337  else
338  cond = (value < r->to);
339  if(cond && ((value - r->to) % r->step) == 0)
340  return (r - range);
341  break;
343  if((value % r->step) == 0)
344  return (r - range);
345  break;
346  }
347  }
348  return -1;
349 }

+ Here is the caller graph for this function:

int mdvi_page_selected ( DviPageSpec spec,
PageNum  page,
int  dvipage 
)

Definition at line 268 of file pagesel.c.

269 {
270  int i;
271  int not_found;
272 
273  if(spec == NULL)
274  return 1;
275  if(spec[0]) {
276  not_found = mdvi_in_range(spec[0]->ranges,
277  spec[0]->nranges, dvipage);
278  if(not_found < 0)
279  return 0;
280  }
281  for(i = 1; i <= 10; i++) {
282  if(spec[i] == NULL)
283  continue;
284  not_found = mdvi_in_range(spec[i]->ranges,
285  spec[i]->nranges, (int)page[i]);
286  if(not_found < 0)
287  return 0;
288  }
289  return 1;
290 }

+ Here is the caller graph for this function:

DviPageSpec* mdvi_parse_page_spec ( const char *  format)

Definition at line 190 of file pagesel.c.

191 {
192  /*
193  * a page specification looks like this:
194  * '{'RANGE_SPEC'}' for a DVI spec
195  * '{'RANGE_SPEC'}' '.' ... for a TeX spec
196  */
197  DviPageSpec *spec;
198  DviRange *range;
199  int count;
200  int i;
201  char *ptr;
202 
203  spec = xnalloc(struct _DviPageSpec *, 11);
204  for(i = 0; i < 11; i++)
205  spec[i] = NULL;
206 
207  /* check what kind of spec we're parsing */
208  if(*format != '*') {
209  range = mdvi_parse_range(format, NULL, &count, &ptr);
210  if(ptr == format) {
211  if(range) mdvi_free(range);
212  mdvi_error(_("invalid page specification `%s'\n"), format);
213  return NULL;
214  }
215  } else
216  range = NULL;
217 
218  if(*format == 'D' || *format == 'd' || *ptr != '.')
219  i = 0;
220  else
221  i = 1;
222 
223  if(range) {
224  spec[i] = xalloc(struct _DviPageSpec);
225  spec[i]->ranges = range;
226  spec[i]->nranges = count;
227  } else
228  spec[i] = NULL;
229 
230  if(*ptr != '.') {
231  if(*ptr)
232  mdvi_warning(_("garbage after DVI page specification ignored\n"));
233  return spec;
234  }
235 
236  for(i++; *ptr == '.' && i <= 10; i++) {
237  ptr++;
238  if(*ptr == '*') {
239  ptr++;
240  range = NULL;
241  } else {
242  char *end;
243 
244  range = mdvi_parse_range(ptr, NULL, &count, &end);
245  if(end == ptr) {
246  if(range) mdvi_free(range);
247  range = NULL;
248  } else
249  ptr = end;
250  }
251  if(range != NULL) {
252  spec[i] = xalloc(struct _DviPageSpec);
253  spec[i]->ranges = range;
254  spec[i]->nranges = count;
255  } else
256  spec[i] = NULL;
257  }
258 
259  if(i > 10)
260  mdvi_warning(_("more than 10 counters in page specification\n"));
261  else if(*ptr)
262  mdvi_warning(_("garbage after TeX page specification ignored\n"));
263 
264  return spec;
265 }
DviRange* mdvi_parse_range ( const char *  format,
DviRange limit,
int *  nitems,
char **  endptr 
)

Definition at line 36 of file pagesel.c.

37 {
38  int quoted;
39  int size;
40  int curr;
41  int done;
42  int lower;
43  int upper;
44  int type;
45  char * cp;
46  char * copy;
47  char * text;
48  DviRange one;
49  DviRange *range;
50 
51  quoted = (*format == '{');
52  if(quoted) format++;
53 
54  size = 0;
55  curr = 0;
56  range = NULL;
57  copy = mdvi_strdup(format);
58  done = 0;
59  lower = 0;
60  upper = 0;
61  type = MDVI_RANGE_UNBOUNDED;
62 
63  if(limit) {
64  switch(limit->type) {
65  case MDVI_RANGE_BOUNDED:
66  lower = limit->from;
67  upper = limit->to;
68  break;
69  case MDVI_RANGE_UPPER:
70  lower = INT_MIN;
71  upper = limit->to;
72  break;
73  case MDVI_RANGE_LOWER:
74  lower = limit->from;
75  upper = INT_MAX;
76  break;
78  lower = INT_MIN;
79  upper = INT_MAX;
80  break;
81  }
82  type = limit->type;
83  } else {
84  lower = INT_MIN;
85  upper = INT_MAX;
86  type = MDVI_RANGE_UNBOUNDED;
87  }
88  one.type = type;
89  one.from = lower;
90  one.to = upper;
91  one.step = 1;
92  for(cp = text = copy; !done; cp++) {
93  char *p;
94  int f, t, s;
95  int ch;
96  int this_type;
97  int lower_given = 0;
98  int upper_given = 0;
99 
100  if(*cp == 0 || *cp == '.' || (*cp == '}' && quoted))
101  done = 1;
102  else if(*cp != ',')
103  continue;
104 
105  if(text == cp)
106  continue;
107  ch = *cp;
108  *cp = 0;
109  f = lower;
110  t = upper;
111  s = 1;
112 
113  p = strchr(text, ':');
114  if(p) *p++ = 0;
115  if(*text) {
116  lower_given = 1;
117  f = strtol(text, NULL, 0);
118  }
119  if(p == NULL) {
120  if(lower_given) {
121  upper_given = 1;
122  t = f; s = 1;
123  }
124  goto finish;
125  }
126  text = p;
127  p = strchr(text, ':');
128  if(p) *p++ = 0;
129  if(*text) {
130  upper_given = 1;
131  t = strtol(text, NULL, 0);
132  }
133  if(p == NULL)
134  goto finish;
135  text = p;
136  if(*text)
137  s = strtol(text, NULL, 0);
138 finish:
139  if(lower_given && upper_given)
140  this_type = MDVI_RANGE_BOUNDED;
141  else if(lower_given) {
142  if(!RANGE_HAS_UPPER(type))
143  this_type = MDVI_RANGE_LOWER;
144  else
145  this_type = MDVI_RANGE_BOUNDED;
146  t = upper;
147  } else if(upper_given) {
148  if(RANGE_HAS_UPPER(one.type)) {
149  one.to++;
150  this_type = MDVI_RANGE_BOUNDED;
151  } else {
152  one.to = lower;
153  if(!RANGE_HAS_LOWER(type))
154  this_type = MDVI_RANGE_UPPER;
155  else
156  this_type = MDVI_RANGE_BOUNDED;
157  }
158  f = one.to;
159  } else {
160  this_type = type;
161  f = lower;
162  t = upper;
163  }
164  one.type = this_type;
165  one.to = t;
166  one.from = f;
167  one.step = s;
168 
169  if(curr == size) {
170  size += 8;
171  range = mdvi_realloc(range, size * sizeof(DviRange));
172  }
173  memcpy(&range[curr++], &one, sizeof(DviRange));
174  *cp = ch;
175  text = cp + 1;
176  }
177  if(done)
178  cp--;
179  if(quoted && *cp == '}')
180  cp++;
181  if(endptr)
182  *endptr = (char *)format + (cp - copy);
183  if(curr && curr < size)
184  range = mdvi_realloc(range, curr * sizeof(DviRange));
185  *nitems = curr;
186  mdvi_free(copy);
187  return range;
188 }

+ Here is the caller graph for this function:

int mdvi_range_length ( DviRange range,
int  nitems 
)

Definition at line 351 of file pagesel.c.

352 {
353  int count = 0;
354  DviRange *r;
355 
356  for(r = range; r < range + nitems; r++) {
357  int n;
358 
359  if(r->type != MDVI_RANGE_BOUNDED)
360  return -2;
361  n = (r->to - r->from) / r->step;
362  if(n < 0)
363  n = 0;
364  count += n + 1;
365  }
366  return count;
367 }

Variable Documentation

char* program_name = "page"

Definition at line 29 of file pagesel.c.