home *** CD-ROM | disk | FTP | other *** search
- /*
- field.c
-
- % field object routines
-
- C-scape 3.2
- Copyright (c) 1986-1989, by Oakland Group, Inc.
- ALL RIGHTS RESERVED.
-
- Revision History:
- -----------------
- 03/07/86 sng rewrote for speed so that the merge is now in the data
- structure instead of being constructed from the spec and
- record (field_GetMerge was a bottleneck while profiling).
- 03/24/86 sng added #defines; added field_merge2record.
- 04/28/86 sng added integer data item (to support marking).
- 05/05/86 sng record variable is now passed in open.
- 05/06/86 sng disabled merge cacheing, removed checks on record.
- 05/12/86 sng reversed the last two changes (!) so that types can now
- be supported.
- 07/08/86 sng put asserts on single line for easier grep'ing.
- 07/09/86 sng #defined out xprint to save space.
- 10/30/86 jmd removed ifdefs.
- 11/04/86 sng made field_Ok static.
- 11/05/86 sng made field_Open return NULL if out of memory.
- 11/16/86 sng now handles variable length fields ("string too short").
- 2/21/87 jmd replaced asserts
- 4/21/87 jmd got rid of spec
- 4/27/87 jmd added data array to field
- 5/04/87 jmd Replaced the grid
- 9/11/87 jmd Added '\0' check to SetString
-
- 3/07/88 jmd Fixed assert in NextChar and PrevChar (reclen vs mergelen)
- 3/07/88 jmd Added mergeless fields. This saves runtime space
- Set merge to NULL for fields that are all writeable
- 4/10/88 jmd field_Open no longer takes row and col as args
- 4/11/88 jmd added scrollable fields
- 5/09/88 jmd added WIDE fields
- 6/23/88 jmd converted generic pointers to VOID*
- 8/16/88 jmd added calls to omalloc
- 8/20/88 jmd changed args to field_Open
- chaned merglen calculation
- added bob objects
- 8/24/88 jmd added field_GetBox
- 9/19/88 jmd added field name support
- 10/17/88 jdc added bob_Close to field_Close
-
- 4/11/89 jmd renamed protect to avoid Zortech conflict
- 9/06/89 jmd added ubit initialization
- 9/11/89 jmd removed asserts for fieldpos
-
- 11/29/89 jmd added casts for DG
- 3/28/90 jmd ansi-fied
- 10/25/90 jmd added test for NULL string in field_SetString
- */
-
- #include "field.h"
-
- /***** Creators *****/
-
- field_type field_Open(char *spec, int width, int dcount)
- /*
- effects: Creates a new field with the data given.
- returns: The new field. If there isn't enough memory to create the
- field, returns NULL.
- notes: The space for the new field is allocated in one chunk
- to save time.
- If there are no non-writeable positions the field is opened
- as a "merge-less" field. (merge is set to NULL).
- If width is (-1) then set field->width equal to mergelen
- */
- {
- field_type f;
- register int i;
- char *s, *p;
- int recpos, specpos, reclen, mergelen;
- boolean merge_less;
-
- /* Calculate record and merge length. */
- reclen = 0;
- mergelen = 0;
- for (s = spec; *s != '\0'; s++) {
- mergelen++;
- if (*s == CS_INPUT) {
- reclen++;
- }
- }
-
- if (mergelen == reclen) {
- merge_less = TRUE;
- /* (Mergeless field) Allocate space for: */
- p = (char *) omalloc(
- CSA_FIELD,
- sizeof(struct field_struct) + /* the structure, */
- dcount * sizeof(VOID *) + /* the data pointer array, */
- reclen + 1 ); /* and the record. */
- }
- else {
- merge_less = FALSE;
- /* (Normal field) Allocate space for: */
- p = (char *) omalloc(
- CSA_FIELD,
- sizeof(struct field_struct) + /* the structure, */
- reclen * sizeof(int) + /* record to merge map, */
- dcount * sizeof(VOID *) + /* the data pointer array, */
- reclen + 1 + /* the record, */
- mergelen + 1 ); /* and the merge. */
- }
-
- if (p == NULL) {
- return(NULL);
- }
-
- /* Set the pointers for the structure _and_ the pointers in the
- structure.
- */
- f = (field_type) p;
- p += sizeof(struct field_struct);
-
- f->mergelen = mergelen; /* non-ptrs are done first */
- f->reclen = reclen; /* so they can lie on word bounds */
-
- if (merge_less) {
- f->r2m = NULL;
- }
- else {
- f->r2m = (int *) p;
- p += sizeof(int) * reclen;
- }
-
- f->dcount = dcount;
- f->data = (VOID **) p;
- p += dcount * sizeof(VOID *);
-
- f->record = p;
- p += reclen + 1;
- memset((VOID *) f->record, '\0', reclen+1);
-
- if (merge_less) {
- f->merge = NULL;
- }
- else {
- f->merge = p;
- memset((VOID *) f->merge, MRGPADCHAR, mergelen);
- f->merge[mergelen] = '\0';
-
- /* Make the maps and the merge. */
- for (recpos = specpos = 0; specpos < mergelen; specpos++) {
- if (spec[specpos] == CS_INPUT) {
- f->r2m[recpos++] = specpos;
- }
- else {
- f->merge[specpos] = spec[specpos];
- }
- }
- }
-
- /* Initialize data. */
- for (i = 0; i < dcount; i++) {
- f->data[i] = NULL;
- }
-
- field_SetProtected(f, FALSE);
-
- f->var = NULL;
- f->funcs = NULL;
- f->bob = NULL;
- f->row = 0;
- f->col = 0;
- f->nameno = -1;
-
- f->width = (width < 0) ? mergelen : width;
- f->xoffset = 0;
-
- f->marked = FALSE;
- f->reg = (char) 0;
- f->sel = (char) 0;
- f->ubit = FALSE;
- f->hicharon = FALSE;
- f->hicharno = 0;
-
- f->gcol = 0;
- f->right = -1;
- f->left = -1;
-
- return(f);
- }
-
- /**** Mutators *****/
-
- void field_SetString(field_type f, char *string)
- /*
- * modifies: The field passed.
- *
- * effects: Sets the record of the field to the string given. The string
- * can be less than or equal to the length of the record.
- */
- {
- int recpos;
- boolean inrec;
-
- cs_Assert(field_Ok(f), CS_FLD_SS_FLD, 0);
-
- /* test for NULL string */
- if (string != NULL) {
- if (string[0] == '\0' && f->record[0] == '\0') {
- /* no sense in setting the record */
- return;
- }
-
- inrec = TRUE;
- }
- else {
- /* NULL string, clear the record */
- inrec = FALSE;
- }
-
- for (recpos = 0; recpos < f->reclen; recpos++) {
- if (inrec && string[recpos] == '\0') {
- inrec = FALSE;
- }
- f->record[recpos] = inrec ? string[recpos] : '\0';
- if (f->merge != NULL) {
- f->merge[f->r2m[recpos]] = inrec ? string[recpos] : MRGPADCHAR;
- }
- }
- }
-
- void field_SetChar(field_type f, int recpos, char c)
- /*
- * requires: The column passed must be within the span of the
- * field.
- *
- * modifies: The field given.
- *
- * effects: Sets a character at the given record position of the field.
- *
- */
- {
- register int len;
-
- cs_Assert(field_Ok(f), CS_FLD_SC_FLD, 0);
-
- if (recpos >= 0 && recpos < f->reclen) {
- len = strlen(f->record);
-
- /* Need to pad with spaces? */
- if (len < recpos) {
- memset((VOID *) (f->record + len), RECPADCHAR, recpos - len);
- }
-
- f->record[recpos] = c;
- if (f->merge != NULL) {
- f->merge[f->r2m[recpos]] = c;
- }
- }
- }
-
- boolean field_SetData(field_type field, int datano, VOID *data)
- /*
- Sets the appropriate field data to data.
- If datano > field->dcount return FALSE.
- */
- {
- cs_Assert(field_Ok(field), CS_FLD_FSD_FLD, 0);
-
- if (datano < 0 || datano >= field->dcount) {
- return(FALSE);
- }
-
- field->data[datano] = data;
- return(TRUE);
- }
-
- /**** Observers *****/
-
- VOID *field_GetData(field_type field, int datano)
- /*
- Returns the appropriate data pointer for the field.
- If datano > field->dcount return NULL.
- */
- {
- cs_Assert(field_Ok(field), CS_FLD_FGD_FLD, 0);
-
- if (datano < 0 || datano >= field->dcount) {
- return(NULL);
- }
-
- return(field->data[datano]);
- }
-
- int field_FirstChar(field_type field)
- /*
- * effects: Finds the first writeable record position from the one given.
- * If there are no writeable positions, return -1.
- *
- * returns: The first writeable position.
- */
- {
- cs_Assert(field_Ok(field), CS_FLD_FC_FLD, 0);
-
- return(field->reclen > 0 ? 0 : -1);
- }
-
- int field_LastChar(field_type field)
- /*
- * effects: Finds the last writeable record position from the one given.
- *
- * returns: The last position with a character in it. If the field has
- * no record (i.e. writeable) positions, return -1.
- *
- */
- {
- cs_Assert(field_Ok(field), CS_FLD_LC_FLD, 0);
-
- return(field->reclen > 0 ? (int) strlen(field->record) : -1);
- }
-
- int field_NextChar(field_type field, int fieldpos)
- /*
- * requires: The position passed must be within the span of the writeable
- * positions.
- *
- * effects: Finds the next record position after the one given. If
- * there are no more positions, return -1.
- *
- * returns: The next record position.
- *
- */
- {
- cs_Assert(field_Ok(field), CS_FLD_NC_FLD, 0);
-
- if (fieldpos >= 0 && fieldpos < field->reclen) {
- return(fieldpos + 1 < field->reclen ? fieldpos + 1 : -1);
- }
- else {
- return(-1);
- }
- }
-
- int field_PrevChar(field_type field, int fieldpos)
- /*
- * requires: The position passed must be within the span of the field.
- *
- * effects: Finds the previous writeable position from the one given. If
- * we're at the first position, return -1.
- *
- * returns: The previous writeable position.
- */
- {
- if (fieldpos >= 0 && fieldpos < field->reclen) {
- return(fieldpos > 0 ? fieldpos - 1 : -1);
- }
- else {
- return(-1);
- }
- }
-
- boolean field_Ok(field_type f)
- /*
- * effects: Checks the validity of a field.
- *
- * returns: TRUE if a field is okay, FALSE if it ain't.
- */
- {
- return (f != NULL && f->record != NULL);
- }
-
- void field_SetHiChar(field_type f, int mergepos)
- /*
- Enables field character highlighting.
- mergepos is the character to highlight.
- use mergepos < 0 to turn off higlighting
- Note: currently only values of 0-15 are supported.
- */
- {
- if (mergepos < 0 || mergepos > 15 || mergepos >= f->mergelen) {
- f->hicharon = FALSE;
- }
- else {
- f->hicharon = TRUE;
- f->hicharno = mergepos;
- }
- }
-