Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Kitware
GitHub Repository: Kitware/CMake
Path: blob/master/Source/CursesDialog/form/frm_def.c
5020 views
1
/****************************************************************************
2
* Copyright (c) 1998 Free Software Foundation, Inc. *
3
* *
4
* Permission is hereby granted, free of charge, to any person obtaining a *
5
* copy of this software and associated documentation files (the *
6
* "Software"), to deal in the Software without restriction, including *
7
* without limitation the rights to use, copy, modify, merge, publish, *
8
* distribute, distribute with modifications, sublicense, and/or sell *
9
* copies of the Software, and to permit persons to whom the Software is *
10
* furnished to do so, subject to the following conditions: *
11
* *
12
* The above copyright notice and this permission notice shall be included *
13
* in all copies or substantial portions of the Software. *
14
* *
15
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS *
16
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
17
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. *
18
* IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
19
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
20
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR *
21
* THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
22
* *
23
* Except as contained in this notice, the name(s) of the above copyright *
24
* holders shall not be used in advertising or otherwise to promote the *
25
* sale, use or other dealings in this Software without prior written *
26
* authorization. *
27
****************************************************************************/
28
29
/****************************************************************************
30
* Author: Juergen Pfeifer <[email protected]> 1995,1997 *
31
****************************************************************************/
32
33
#include "form.priv.h"
34
35
MODULE_ID("$Id$")
36
37
/* this can't be readonly */
38
static FORM default_form = {
39
0, /* status */
40
0, /* rows */
41
0, /* cols */
42
0, /* currow */
43
0, /* curcol */
44
0, /* toprow */
45
0, /* begincol */
46
-1, /* maxfield */
47
-1, /* maxpage */
48
-1, /* curpage */
49
ALL_FORM_OPTS, /* opts */
50
(WINDOW *)0, /* win */
51
(WINDOW *)0, /* sub */
52
(WINDOW *)0, /* w */
53
(FIELD **)0, /* field */
54
(FIELD *)0, /* current */
55
(_PAGE *)0, /* page */
56
(char *)0, /* usrptr */
57
NULL, /* forminit */
58
NULL, /* formterm */
59
NULL, /* fieldinit */
60
NULL /* fieldterm */
61
};
62
63
FORM *_nc_Default_Form = &default_form;
64
65
/*---------------------------------------------------------------------------
66
| Facility : libnform
67
| Function : static FIELD *Insert_Field_By_Position(
68
| FIELD *new_field,
69
| FIELD *head )
70
|
71
| Description : Insert new_field into sorted fieldlist with head "head"
72
| and return new head of sorted fieldlist. Sorting
73
| criteria is (row,column). This is a circular list.
74
|
75
| Return Values : New head of sorted fieldlist
76
+--------------------------------------------------------------------------*/
77
static FIELD *Insert_Field_By_Position(FIELD *newfield, FIELD *head)
78
{
79
FIELD *current, *newhead;
80
81
assert(newfield != 0);
82
83
if (!head)
84
{ /* empty list is trivial */
85
newhead = newfield->snext = newfield->sprev = newfield;
86
}
87
else
88
{
89
newhead = current = head;
90
while((current->frow < newfield->frow) ||
91
((current->frow==newfield->frow) &&
92
(current->fcol < newfield->fcol)) )
93
{
94
current = current->snext;
95
if (current==head)
96
{ /* We cycled through. Reset head to indicate that */
97
head = (FIELD *)0;
98
break;
99
}
100
}
101
/* we leave the loop with current pointing to the field after newfield*/
102
newfield->snext = current;
103
newfield->sprev = current->sprev;
104
newfield->snext->sprev = newfield;
105
newfield->sprev->snext = newfield;
106
if (current==head)
107
newhead = newfield;
108
}
109
return(newhead);
110
}
111
112
/*---------------------------------------------------------------------------
113
| Facility : libnform
114
| Function : static void Disconnect_Fields(FORM *form)
115
|
116
| Description : Break association between form and array of fields.
117
|
118
| Return Values : -
119
+--------------------------------------------------------------------------*/
120
static void Disconnect_Fields( FORM * form )
121
{
122
if (form->field)
123
{
124
FIELD **fields;
125
126
for(fields=form->field;*fields;fields++)
127
{
128
if (form == (*fields)->form)
129
(*fields)->form = (FORM *)0;
130
}
131
132
form->rows = form->cols = 0;
133
form->maxfield = form->maxpage = -1;
134
form->field = (FIELD **)0;
135
if (form->page)
136
free(form->page);
137
form->page = (_PAGE *)0;
138
}
139
}
140
141
/*---------------------------------------------------------------------------
142
| Facility : libnform
143
| Function : static int Connect_Fields(FORM *form, FIELD **fields)
144
|
145
| Description : Set association between form and array of fields.
146
|
147
| Return Values : E_OK - no error
148
| E_CONNECTED - a field is already connected
149
| E_BAD_ARGUMENT - Invalid form pointer or field array
150
| E_SYSTEM_ERROR - not enough memory
151
+--------------------------------------------------------------------------*/
152
static int Connect_Fields(FORM * form, FIELD ** fields)
153
{
154
int field_cnt, j;
155
int page_nr;
156
int maximum_row_in_field, maximum_col_in_field;
157
_PAGE *pg;
158
159
assert(form != 0);
160
161
form->field = fields;
162
form->maxfield = 0;
163
form->maxpage = 0;
164
165
if (!fields)
166
RETURN(E_OK);
167
168
page_nr = 0;
169
/* store formpointer in fields and count pages */
170
for(field_cnt=0;fields[field_cnt];field_cnt++)
171
{
172
if (fields[field_cnt]->form)
173
RETURN(E_CONNECTED);
174
if ( field_cnt==0 ||
175
(fields[field_cnt]->status & _NEWPAGE))
176
page_nr++;
177
fields[field_cnt]->form = form;
178
}
179
if (field_cnt==0)
180
RETURN(E_BAD_ARGUMENT);
181
182
/* allocate page structures */
183
if ( (pg = (_PAGE *)malloc(page_nr * sizeof(_PAGE))) != (_PAGE *)0 )
184
{
185
form->page = pg;
186
}
187
else
188
RETURN(E_SYSTEM_ERROR);
189
190
/* Cycle through fields and calculate page boundaries as well as
191
size of the form */
192
for(j=0;j<field_cnt;j++)
193
{
194
if (j==0)
195
pg->pmin = j;
196
else
197
{
198
if (fields[j]->status & _NEWPAGE)
199
{
200
pg->pmax = j-1;
201
pg++;
202
pg->pmin = j;
203
}
204
}
205
206
maximum_row_in_field = fields[j]->frow + fields[j]->rows;
207
maximum_col_in_field = fields[j]->fcol + fields[j]->cols;
208
209
if (form->rows < maximum_row_in_field)
210
form->rows = maximum_row_in_field;
211
if (form->cols < maximum_col_in_field)
212
form->cols = maximum_col_in_field;
213
}
214
215
pg->pmax = field_cnt-1;
216
form->maxfield = field_cnt;
217
form->maxpage = page_nr;
218
219
/* Sort fields on form pages */
220
for(page_nr = 0;page_nr < form->maxpage; page_nr++)
221
{
222
FIELD *fld = (FIELD *)0;
223
#ifdef __clang_analyzer__
224
/* Tell clang-analyzer the loop body runs at least once. */
225
assert(form->page[page_nr].pmin <= form->page[page_nr].pmax);
226
#endif
227
for(j = form->page[page_nr].pmin;j <= form->page[page_nr].pmax;j++)
228
{
229
fields[j]->index = j;
230
fields[j]->page = page_nr;
231
fld = Insert_Field_By_Position(fields[j],fld);
232
}
233
form->page[page_nr].smin = fld->index;
234
form->page[page_nr].smax = fld->sprev->index;
235
}
236
RETURN(E_OK);
237
}
238
239
/*---------------------------------------------------------------------------
240
| Facility : libnform
241
| Function : static int Associate_Fields(FORM *form, FIELD **fields)
242
|
243
| Description : Set association between form and array of fields.
244
| If there are fields, position to first active field.
245
|
246
| Return Values : E_OK - success
247
| any other - error occurred
248
+--------------------------------------------------------------------------*/
249
INLINE static int Associate_Fields(FORM *form, FIELD **fields)
250
{
251
int res = Connect_Fields(form,fields);
252
if (res == E_OK)
253
{
254
if (form->maxpage>0)
255
{
256
form->curpage = 0;
257
form_driver(form,FIRST_ACTIVE_MAGIC);
258
}
259
else
260
{
261
form->curpage = -1;
262
form->current = (FIELD *)0;
263
}
264
}
265
return(res);
266
}
267
268
/*---------------------------------------------------------------------------
269
| Facility : libnform
270
| Function : FORM *new_form( FIELD **fields )
271
|
272
| Description : Create new form with given array of fields.
273
|
274
| Return Values : Pointer to form. NULL if error occurred.
275
+--------------------------------------------------------------------------*/
276
FORM *new_form(FIELD ** fields)
277
{
278
int err = E_SYSTEM_ERROR;
279
280
FORM *form = (FORM *)malloc(sizeof(FORM));
281
282
if (form)
283
{
284
*form = *_nc_Default_Form;
285
if ((err=Associate_Fields(form,fields))!=E_OK)
286
{
287
free_form(form);
288
form = (FORM *)0;
289
}
290
}
291
292
if (!form)
293
SET_ERROR(err);
294
295
return(form);
296
}
297
298
/*---------------------------------------------------------------------------
299
| Facility : libnform
300
| Function : int free_form( FORM *form )
301
|
302
| Description : Release internal memory associated with form.
303
|
304
| Return Values : E_OK - no error
305
| E_BAD_ARGUMENT - invalid form pointer
306
| E_POSTED - form is posted
307
+--------------------------------------------------------------------------*/
308
int free_form(FORM * form)
309
{
310
if ( !form )
311
RETURN(E_BAD_ARGUMENT);
312
313
if ( form->status & _POSTED)
314
RETURN(E_POSTED);
315
316
Disconnect_Fields( form );
317
if (form->page)
318
free(form->page);
319
free(form);
320
321
RETURN(E_OK);
322
}
323
324
/*---------------------------------------------------------------------------
325
| Facility : libnform
326
| Function : int set_form_fields( FORM *form, FIELD **fields )
327
|
328
| Description : Set a new association of an array of fields to a form
329
|
330
| Return Values : E_OK - no error
331
| E_BAD_ARGUMENT - invalid form pointer
332
| E_POSTED - form is posted
333
+--------------------------------------------------------------------------*/
334
int set_form_fields(FORM * form, FIELD ** fields)
335
{
336
FIELD **old;
337
int res;
338
339
if ( !form )
340
RETURN(E_BAD_ARGUMENT);
341
342
if ( form->status & _POSTED )
343
RETURN(E_POSTED);
344
345
old = form->field;
346
Disconnect_Fields( form );
347
348
if( (res = Associate_Fields( form, fields )) != E_OK )
349
Connect_Fields( form, old );
350
351
RETURN(res);
352
}
353
354
/*---------------------------------------------------------------------------
355
| Facility : libnform
356
| Function : FIELD **form_fields( const FORM *form )
357
|
358
| Description : Retrieve array of fields
359
|
360
| Return Values : Pointer to field array
361
+--------------------------------------------------------------------------*/
362
FIELD **form_fields(const FORM * form)
363
{
364
return (Normalize_Form( form )->field);
365
}
366
367
/*---------------------------------------------------------------------------
368
| Facility : libnform
369
| Function : int field_count( const FORM *form )
370
|
371
| Description : Retrieve number of fields
372
|
373
| Return Values : Number of fields, -1 if none are defined
374
+--------------------------------------------------------------------------*/
375
int field_count(const FORM * form)
376
{
377
return (Normalize_Form( form )->maxfield);
378
}
379
380
/* frm_def.c ends here */
381
382