1 /* $NetBSD: type_alpha.c,v 1.11 2004/11/24 11:57:09 blymn 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 <sys/cdefs.h> 33 __RCSID("$NetBSD: type_alpha.c,v 1.11 2004/11/24 11:57:09 blymn Exp $"); 34 35 #include <stdlib.h> 36 #include <string.h> 37 #include <ctype.h> 38 #include "form.h" 39 #include "internals.h" 40 41 /* 42 * The alpha type handling. 43 */ 44 45 typedef struct 46 { 47 unsigned width; 48 } alpha_args; 49 50 /* 51 * Create the alpha arguments structure from the given args. Return NULL 52 * if the call fails, otherwise return a pointer to the structure allocated. 53 */ 54 static char * 55 create_alpha_args(va_list *args) 56 { 57 alpha_args *new; 58 59 new = (alpha_args *) malloc(sizeof(alpha_args)); 60 61 if (new != NULL) 62 new->width = va_arg(*args, int); 63 64 return (void *) new; 65 } 66 67 /* 68 * Copy the alpha argument structure. 69 */ 70 static char * 71 copy_alpha_args(char *args) 72 { 73 alpha_args *new; 74 75 new = (alpha_args *) malloc(sizeof(alpha_args)); 76 77 if (new != NULL) 78 new->width = ((alpha_args *) (void *) args)->width; 79 80 return (void *) new; 81 } 82 83 /* 84 * Free the allocated storage associated with the type arguments. 85 */ 86 static void 87 free_alpha_args(char *args) 88 { 89 if (args != NULL) 90 free(args); 91 } 92 93 /* 94 * Check the contents of the field buffer are alphanumeric only. 95 */ 96 static int 97 alpha_check_field(FIELD *field, char *args) 98 { 99 int width, start, cur, end; 100 char *buf, *new; 101 102 width = ((alpha_args *) (void *) field->args)->width; 103 buf = args; 104 start = 0; 105 106 if (buf == NULL) 107 return FALSE; 108 109 /* skip leading white space */ 110 while ((buf[start] != '\0') 111 && ((buf[start] == ' ') || (buf[start] == '\t'))) 112 start++; 113 114 /* no good if we have hit the end */ 115 if (buf[start] == '\0') 116 return FALSE; 117 118 /* find the end of the non-whitespace stuff */ 119 cur = start; 120 while(isalpha((unsigned char)buf[cur])) 121 cur++; 122 123 /* no good if it exceeds the width */ 124 if ((cur - start) > width) 125 return FALSE; 126 127 end = cur; 128 129 /* check there is only trailing whitespace */ 130 while ((buf[cur] != '\0') 131 && ((buf[cur] == ' ') || (buf[cur] == '\t'))) 132 cur++; 133 134 /* no good if we are not at the end of the string */ 135 if (buf[cur] != '\0') 136 return FALSE; 137 138 /* set buffer 0 to the new string */ 139 if ((new = (char *) malloc(sizeof(char) * (end - start))) == NULL) 140 return FALSE; 141 142 if ((end - start) >= 1) { 143 strncpy(new, &buf[start], (size_t) (end - start - 1)); 144 new[end] = '\0'; 145 } else 146 new[0] = '\0'; 147 148 149 set_field_buffer(field, 0, new); 150 free(new); 151 152 /* otherwise all was ok */ 153 return TRUE; 154 } 155 156 /* 157 * Check the given character is alphabetic, return TRUE if it is. 158 */ 159 static int 160 alpha_check_char(/* ARGSUSED1 */ int c, char *args) 161 { 162 return (isalpha(c) ? TRUE : FALSE); 163 } 164 165 static FIELDTYPE builtin_alpha = { 166 _TYPE_HAS_ARGS | _TYPE_IS_BUILTIN, /* flags */ 167 0, /* refcount */ 168 NULL, /* link */ 169 create_alpha_args, /* make_args */ 170 copy_alpha_args, /* copy_args */ 171 free_alpha_args, /* free_args */ 172 alpha_check_field, /* field_check */ 173 alpha_check_char, /* char_check */ 174 NULL, /* next_choice */ 175 NULL /* prev_choice */ 176 }; 177 178 FIELDTYPE *TYPE_ALPHA = &builtin_alpha; 179 180 181