xref: /netbsd/lib/libform/type_alpha.c (revision bf9ec67e)
1 /*	$NetBSD: type_alpha.c,v 1.6 2001/06/13 10:45:59 wiz Exp $	*/
2 
3 /*-
4  * Copyright (c) 1998-1999 Brett Lymn
5  *                         (blymn@baea.com.au, brett_lymn@yahoo.com.au)
6  * All rights reserved.
7  *
8  * This code has been donated to The NetBSD Foundation by the Author.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. The name of the author may not be used to endorse or promote products
16  *    derived from this software without specific prior written permission
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  *
29  *
30  */
31 
32 #include <stdlib.h>
33 #include <string.h>
34 #include <ctype.h>
35 #include "form.h"
36 #include "internals.h"
37 
38 /*
39  * The alpha type handling.
40  */
41 
42 typedef struct
43 {
44 	unsigned width;
45 } alpha_args;
46 
47 /*
48  * Create the alpha arguments structure from the given args.  Return NULL
49  * if the call fails, otherwise return a pointer to the structure allocated.
50  */
51 static char *
52 create_alpha_args(va_list *args)
53 {
54 	alpha_args *new;
55 
56 	new = (alpha_args *) malloc(sizeof(alpha_args));
57 
58 	if (new != NULL)
59 		new->width = va_arg(*args, int);
60 
61 	return (void *) new;
62 }
63 
64 /*
65  * Copy the the alpha argument structure.
66  */
67 static char *
68 copy_alpha_args(char *args)
69 {
70 	alpha_args *new;
71 
72 	new = (alpha_args *) malloc(sizeof(alpha_args));
73 
74 	if (new != NULL)
75 		new->width = ((alpha_args *) (void *) args)->width;
76 
77 	return (void *) new;
78 }
79 
80 /*
81  * Free the allocated storage associated with the type arguments.
82  */
83 static void
84 free_alpha_args(char *args)
85 {
86 	if (args != NULL)
87 		free(args);
88 }
89 
90 /*
91  * Check the contents of the field buffer are alphanumeric only.
92  */
93 static int
94 alpha_check_field(FIELD *field, char *args)
95 {
96 	int width, start, cur, end;
97 	char *buf, *new;
98 
99 	width = ((alpha_args *) (void *) field->args)->width;
100 	buf = args;
101 	start = 0;
102 
103 	if (buf == NULL)
104 		return FALSE;
105 
106 	  /* skip leading white space */
107 	while ((buf[start] != '\0')
108 	       && ((buf[start] == ' ') || (buf[start] == '\t')))
109 		start++;
110 
111 	  /* no good if we have hit the end */
112 	if (buf[start] == '\0')
113 		return FALSE;
114 
115 	  /* find the end of the non-whitespace stuff */
116 	cur = start;
117 	while((buf[cur] != '\0') && isalpha(buf[cur]))
118 		cur++;
119 
120 	  /* no good if it exceeds the width */
121 	if ((cur - start) > width)
122 		return FALSE;
123 
124 	end = cur;
125 
126 	  /* check there is only trailing whitespace */
127 	while ((buf[cur] != '\0')
128 	       && ((buf[cur] == ' ') || (buf[cur] == '\t')))
129 		cur++;
130 
131 	  /* no good if we are not at the end of the string */
132 	if (buf[cur] != '\0')
133 		return FALSE;
134 
135 	  /* set buffer 0 to the new string */
136 	if ((new = (char *) malloc(sizeof(char) * (end - start))) == NULL)
137 		return FALSE;
138 
139 	if ((end - start) >= 1) {
140 		strncpy(new, &buf[start], (unsigned) end - start - 1);
141 		new[end] = '\0';
142 	} else
143 		new[0] = '\0';
144 
145 
146 	set_field_buffer(field, 0, new);
147 	free(new);
148 
149 	  /* otherwise all was ok */
150 	return TRUE;
151 }
152 
153 /*
154  * Check the given character is alphabetic, return TRUE if it is.
155  */
156 static int
157 alpha_check_char(/* ARGSUSED1 */ int c, char *args)
158 {
159 	return (isalpha(c) ? TRUE : FALSE);
160 }
161 
162 static FIELDTYPE builtin_alpha = {
163 	_TYPE_HAS_ARGS | _TYPE_IS_BUILTIN,  /* flags */
164 	0,                                  /* refcount */
165 	NULL,                               /* link */
166 	create_alpha_args,                  /* make_args */
167 	copy_alpha_args,                    /* copy_args */
168 	free_alpha_args,                    /* free_args */
169 	alpha_check_field,                  /* field_check */
170 	alpha_check_char,                   /* char_check */
171 	NULL,                               /* next_choice */
172 	NULL                                /* prev_choice */
173 };
174 
175 FIELDTYPE *TYPE_ALPHA = &builtin_alpha;
176 
177 
178