1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /* Copyright (c) 1988 AT&T */
23 /* All Rights Reserved */
24
25
26 /*
27 * Copyright (c) 1997, by Sun Microsystems, Inc.
28 * All rights reserved.
29 */
30
31 /*
32 * Copyright (c) 2018, Joyent, Inc.
33 */
34
35 /*LINTLIBRARY*/
36
37 #include <sys/types.h>
38 #include <stdlib.h>
39 #include "utility.h"
40
41 /*
42 * default field
43 */
44
45 static FIELD default_field =
46 {
47 0, /* status */
48 0, /* rows */
49 0, /* cols */
50 0, /* frow */
51 0, /* fcol */
52 0, /* drows */
53 0, /* dcols */
54 0, /* maxgrow */
55 0, /* nrow */
56 0, /* nbuf */
57 NO_JUSTIFICATION, /* just */
58 0, /* page */
59 0, /* index */
60 ' ', /* pad */
61 A_NORMAL, /* fore */
62 A_NORMAL, /* back */
63 O_VISIBLE |
64 O_ACTIVE |
65 O_PUBLIC |
66 O_EDIT |
67 O_WRAP |
68 O_BLANK |
69 O_AUTOSKIP |
70 O_NULLOK |
71 O_PASSOK |
72 O_STATIC, /* opts */
73 (FIELD *)0, /* snext */
74 (FIELD *)0, /* sprev */
75 (FIELD *)0, /* link */
76 (FORM *)0, /* form */
77 (FIELDTYPE *)0, /* type */
78 (char *)0, /* arg */
79 (char *)0, /* buf */
80 (char *)0, /* usrptr */
81 };
82
83 FIELD * _DEFAULT_FIELD = &default_field;
84
85 /*
86 * MakeType
87 */
88
89 static int
MakeType(FIELD * f,va_list * ap)90 MakeType(FIELD *f, va_list *ap)
91 {
92 int err = 0;
93
94 f->arg = MakeArg(f, ap, &err); /* pick off type specific args */
95
96 if (err) {
97 FreeArg(f); /* release type specific args */
98 f->type = (FIELDTYPE *)0;
99 f->arg = (char *)0;
100 return (FALSE);
101 }
102 IncrType(f->type); /* increment reference count */
103 return (TRUE);
104 }
105
106 /*
107 * CopyType
108 */
109
110 static int
CopyType(FIELD * f,FIELD * fsrc)111 CopyType(FIELD *f, FIELD *fsrc)
112 {
113 int err = 0;
114
115 f->type = fsrc->type; /* copy field type */
116 f->arg = CopyArg(fsrc, &err); /* copy type specific info */
117
118 if (err) {
119 FreeArg(f); /* release type specific args */
120 f->type = (FIELDTYPE *)0;
121 f->arg = (char *)0;
122 return (FALSE);
123 }
124 IncrType(f->type); /* increment reference count */
125 return (TRUE);
126 }
127
128 /*
129 * FreeType
130 */
131
132 static void
FreeType(FIELD * f)133 FreeType(FIELD *f)
134 {
135 DecrType(f->type); /* decrement reference count */
136 FreeArg(f); /* release type specific args */
137 }
138
139 /*
140 * new_field
141 */
142
143 FIELD *
new_field(int rows,int cols,int frow,int fcol,int nrow,int nbuf)144 new_field(int rows, int cols, int frow, int fcol, int nrow, int nbuf)
145
146 /* int rows; number of visible rows */
147 /* int cols; number of visible cols */
148 /* int frow; first row relative to form origin */
149 /* int fcol; first col relative to form origin */
150 /* int nrow; number of off screen rows */
151 /* int nbuf; number of additional buffers */
152 {
153 FIELD *f = (FIELD *) 0;
154 int i, size;
155
156 if (rows > 0 && cols > 0 && frow >= 0 && fcol >= 0 && nrow >= 0 &&
157 nbuf >= 0 && Alloc(f, FIELD)) {
158 *f = *_DEFAULT_FIELD;
159
160 f->rows = rows;
161 f->cols = cols;
162 f->frow = frow;
163 f->fcol = fcol;
164 f->drows = rows + nrow;
165 f->dcols = cols;
166 f->nrow = nrow;
167 f->nbuf = nbuf;
168 f->link = f;
169
170 if (CopyType(f, _DEFAULT_FIELD)) {
171 size = TotalBuf(f);
172
173 if (arrayAlloc(Buf(f), size, char)) {
174 (void) memset(Buf(f), ' ', size);
175
176 for (i = 0; i <= f->nbuf; ++i)
177 *(Buffer(f, i + 1) - 1) = '\0';
178 return (f);
179 }
180 }
181 }
182 (void) free_field(f);
183 return ((FIELD *) 0);
184 }
185
186 /*
187 * dup_field
188 */
189
190 FIELD *
dup_field(FIELD * field,int frow,int fcol)191 dup_field(FIELD *field, int frow, int fcol)
192
193 /* FIELD * field; field to duplicate */
194 /* int frow; first row relative to form origin */
195 /* int fcol; first col relative to form origin */
196 {
197 FIELD *f = (FIELD *) 0;
198 int size;
199
200 if (field && frow >= 0 && fcol >= 0 && Alloc(f, FIELD)) {
201 *f = *_DEFAULT_FIELD;
202
203 f->frow = frow;
204 f->fcol = fcol;
205 f->link = f;
206
207 f->rows = field->rows;
208 f->cols = field->cols;
209 f->drows = field->drows;
210 f->dcols = field->dcols;
211 f->maxgrow = field->maxgrow;
212 f->nrow = field->nrow;
213 f->nbuf = field->nbuf;
214 f->just = field->just;
215 f->fore = field->fore;
216 f->back = field->back;
217 f->pad = field->pad;
218 f->opts = field->opts;
219 f->usrptr = field->usrptr;
220 f->status = Status(field, GROWABLE);
221
222 if (CopyType(f, field)) {
223 size = TotalBuf(f);
224
225 if (arrayAlloc(Buf(f), size, char)) {
226 (void) memcpy(Buf(f), Buf(field), size);
227 return (f);
228 }
229 }
230 }
231 (void) free_field(f);
232 return ((FIELD *) 0);
233 }
234
235 /*
236 * link_field
237 */
238
239 FIELD *
link_field(FIELD * field,int frow,int fcol)240 link_field(FIELD *field, int frow, int fcol)
241
242 /* FIELD * field; field to link to */
243 /* int frow; first row relative to form origin */
244 /* int fcol; first col relative to form origin */
245 {
246 FIELD *f = (FIELD *) 0;
247
248 if (field && frow >= 0 && fcol >= 0 && Alloc(f, FIELD)) {
249 *f = *_DEFAULT_FIELD;
250
251 f->frow = frow;
252 f->fcol = fcol;
253
254 f->link = field->link;
255 field->link = f; /* add field to linked list */
256
257 f->buf = field->buf;
258 f->rows = field->rows;
259 f->cols = field->cols;
260 f->drows = field->drows;
261 f->dcols = field->dcols;
262 f->maxgrow = field->maxgrow;
263 f->nrow = field->nrow;
264 f->nbuf = field->nbuf;
265 f->just = field->just;
266 f->fore = field->fore;
267 f->back = field->back;
268 f->pad = field->pad;
269 f->opts = field->opts;
270 f->usrptr = field->usrptr;
271 f->status = Status(field, GROWABLE);
272
273 if (CopyType(f, field))
274 return (f);
275 }
276 (void) free_field(f);
277 return ((FIELD *) 0);
278 }
279
280 /*
281 * free_field
282 */
283
284 int
free_field(FIELD * f)285 free_field(FIELD *f)
286 {
287 FIELD *p;
288
289 if (!f)
290 return (E_BAD_ARGUMENT);
291
292 if (f->form)
293 return (E_CONNECTED);
294
295 if (f->link != f) { /* check for linked field */
296 for (p = f->link; p->link != f; p = p->link)
297 ;
298 p->link = f->link; /* delete from list */
299 } else
300 Free(Buf(f)); /* free buffer space */
301
302 FreeType(f);
303 Free(f);
304 return (E_OK);
305 }
306
307 /*
308 * field_info
309 */
310
311 int
field_info(FIELD * f,int * rows,int * cols,int * frow,int * fcol,int * nrow,int * nbuf)312 field_info(FIELD *f, int *rows, int *cols, int *frow, int *fcol,
313 int *nrow, int *nbuf)
314
315 /* FIELD *f; field whose information is wanted */
316 /* int *rows; number of visible rows */
317 /* int *cols; number of visible cols */
318 /* int *frow; first row relative to form origin */
319 /* int *fcol; first col relative to form origin */
320 /* int *nrow; number of off screen rows */
321 /* int *nbuf; number of additional buffers */
322 {
323 if (!f)
324 return (E_BAD_ARGUMENT);
325
326 *rows = f->rows;
327 *cols = f->cols;
328 *frow = f->frow;
329 *fcol = f->fcol;
330 *nrow = f->nrow;
331 *nbuf = f->nbuf;
332 return (E_OK);
333 }
334
335 /*
336 * set_max_field
337 */
338
339 int
set_max_field(FIELD * f,int max)340 set_max_field(FIELD *f, int max)
341 {
342 BOOLEAN onerow;
343
344 if (f == NULL)
345 return (E_BAD_ARGUMENT);
346
347 onerow = OneRow(f);
348
349 if (max && ((onerow && f->dcols > max) ||
350 (!onerow && f->drows > max)))
351 return (E_BAD_ARGUMENT);
352
353 f->maxgrow = max;
354 Clr(f, GROWABLE);
355
356 if (!Opt(f, O_STATIC) && ((!max || onerow && f->dcols < max) ||
357 (!onerow && f->drows < max))) {
358 Set(f, GROWABLE);
359 }
360
361 return (E_OK);
362 }
363
364 /*
365 * dynamic_field_info
366 */
367
368 int
dynamic_field_info(FIELD * f,int * drows,int * dcols,int * max)369 dynamic_field_info(FIELD *f, int *drows, int *dcols, int *max)
370
371 /* FIELD *f; field whose information is wanted */
372 /* int *drows; number of actual rows */
373 /* int *dcols; number of actual cols */
374 /* int *max; maximum growth allowable, else -1 */
375 {
376 if (!f)
377 return (E_BAD_ARGUMENT);
378
379 *drows = f->drows;
380 *dcols = f->dcols;
381 *max = f->maxgrow;
382 return (E_OK);
383 }
384
385 /*
386 * move_field
387 */
388
389 int
move_field(FIELD * f,int frow,int fcol)390 move_field(FIELD *f, int frow, int fcol)
391
392 /* FIELD *f; field to move */
393 /* int frow; first row relative to form origin */
394 /* int fcol; first col relative to form origin */
395 {
396 if (! f || frow < 0 || fcol < 0)
397 return (E_BAD_ARGUMENT);
398
399 if (f->form)
400 return (E_CONNECTED);
401
402 f->frow = frow;
403 f->fcol = fcol;
404 return (E_OK);
405 }
406
407 /*
408 * set_field_type
409 */
410
411 int
set_field_type(FIELD * f,FIELDTYPE * ft,...)412 set_field_type(FIELD *f, FIELDTYPE *ft, ...)
413 {
414 va_list ap;
415 int v = E_SYSTEM_ERROR;
416
417 va_start(ap, ft);
418 f = Field(f);
419 FreeType(f); /* free old type */
420 f->type = ft;
421
422 if (MakeType(f, &ap)) /* set up new type */
423 v = E_OK;
424 va_end(ap);
425 return (v);
426 }
427
428 FIELDTYPE *
field_type(FIELD * f)429 field_type(FIELD *f)
430 {
431 return (Field(f)->type);
432 }
433
434 char *
field_arg(FIELD * f)435 field_arg(FIELD *f)
436 {
437 return (Field(f)->arg);
438 }
439
440 /*
441 * set_new_page
442 */
443
444 int
set_new_page(FIELD * f,int flag)445 set_new_page(FIELD *f, int flag)
446 {
447 f = Field(f);
448
449 if (f->form)
450 return (E_CONNECTED);
451
452 if (flag)
453 Set(f, NEW_PAGE);
454 else
455 Clr(f, NEW_PAGE);
456
457 return (E_OK);
458 }
459
460 int
new_page(FIELD * f)461 new_page(FIELD *f)
462 {
463 if (Status(Field(f), NEW_PAGE))
464 return (TRUE);
465 else
466 return (FALSE);
467 }
468