Merge branch 'vendor/BINUTILS220' into bu220
[dragonfly.git] / usr.bin / mandoc / out.c
1 /*      $Id: out.c,v 1.1 2009/10/21 19:13:51 schwarze Exp $ */
2 /*
3  * Copyright (c) 2009 Kristaps Dzonsons <kristaps@kth.se>
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 #include <sys/types.h>
18
19 #include <ctype.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22
23 #include "out.h"
24
25
26 /*
27  * Convert a `scaling unit' to a consistent form, or fail.  Scaling
28  * units are documented in groff.7, mdoc.7, man.7.
29  */
30 int
31 a2roffsu(const char *src, struct roffsu *dst, enum roffscale def)
32 {
33         char             buf[BUFSIZ], hasd;
34         int              i;
35         enum roffscale   unit;
36
37         if ('\0' == *src)
38                 return(0);
39
40         i = hasd = 0;
41
42         switch (*src) {
43         case ('+'):
44                 src++;
45                 break;
46         case ('-'):
47                 buf[i++] = *src++;
48                 break;
49         default:
50                 break;
51         }
52
53         if ('\0' == *src)
54                 return(0);
55
56         while (i < BUFSIZ) {
57                 if ( ! isdigit((u_char)*src)) {
58                         if ('.' != *src)
59                                 break;
60                         else if (hasd)
61                                 break;
62                         else
63                                 hasd = 1;
64                 }
65                 buf[i++] = *src++;
66         }
67
68         if (BUFSIZ == i || (*src && *(src + 1)))
69                 return(0);
70
71         buf[i] = '\0';
72
73         switch (*src) {
74         case ('c'):
75                 unit = SCALE_CM;
76                 break;
77         case ('i'):
78                 unit = SCALE_IN;
79                 break;
80         case ('P'):
81                 unit = SCALE_PC;
82                 break;
83         case ('p'):
84                 unit = SCALE_PT;
85                 break;
86         case ('f'):
87                 unit = SCALE_FS;
88                 break;
89         case ('v'):
90                 unit = SCALE_VS;
91                 break;
92         case ('m'):
93                 unit = SCALE_EM;
94                 break;
95         case ('\0'):
96                 if (SCALE_MAX == def)
97                         return(0);
98                 unit = SCALE_BU;
99                 break;
100         case ('u'):
101                 unit = SCALE_BU;
102                 break;
103         case ('M'):
104                 unit = SCALE_MM;
105                 break;
106         case ('n'):
107                 unit = SCALE_EN;
108                 break;
109         default:
110                 return(0);
111         }
112
113         if ((dst->scale = atof(buf)) < 0)
114                 dst->scale = 0;
115         dst->unit = unit;
116         dst->pt = hasd;
117
118         return(1);
119 }