Пример #1
0
/*
 * This creates a new CDK screen.
 */
CDKSCREEN *initCDKScreen (WINDOW *window)
{
   ALL_SCREENS *item;
   CDKSCREEN *screen = 0;

   /* initialization, for the first time */
   if (all_screens == 0)
   {
      /* Set up basic curses settings. */
#ifdef HAVE_SETLOCALE
      setlocale (LC_ALL, "");
#endif
      noecho ();
      cbreak ();
   }

   if ((item = typeMalloc (ALL_SCREENS)) != 0)
   {
      if ((screen = typeCalloc (CDKSCREEN)) != 0)
      {
	 item->link = all_screens;
	 item->screen = screen;
	 all_screens = item;

	 /* Initialize the CDKSCREEN pointer. */
	 screen->objectCount = 0;
	 screen->objectLimit = 2;
	 screen->object = typeMallocN (CDKOBJS *, screen->objectLimit);
	 screen->window = window;

	 /* OK, we are done. */
      }
      else
      {
Пример #2
0
link_fieldtype(FIELDTYPE *type1, FIELDTYPE *type2)
{
  FIELDTYPE *nftyp = (FIELDTYPE *)0;

  T((T_CALLED("link_fieldtype(%p,%p)"), type1, type2));
  if (type1 && type2)
    {
      nftyp = typeMalloc(FIELDTYPE, 1);

      if (nftyp)
	{
	  T((T_CREATE("fieldtype %p"), nftyp));
	  *nftyp = *_nc_Default_FieldType;
	  nftyp->status |= _LINKED_TYPE;
	  if ((type1->status & _HAS_ARGS) || (type2->status & _HAS_ARGS))
	    nftyp->status |= _HAS_ARGS;
	  if ((type1->status & _HAS_CHOICE) || (type2->status & _HAS_CHOICE))
	    nftyp->status |= _HAS_CHOICE;
	  nftyp->left = type1;
	  nftyp->right = type2;
	  type1->ref++;
	  type2->ref++;
	}
      else
	{
	  SET_ERROR(E_SYSTEM_ERROR);
	}
    }
  else
    {
      SET_ERROR(E_BAD_ARGUMENT);
    }
  returnFieldType(nftyp);
}
Пример #3
0
/*---------------------------------------------------------------------------
|   Facility      :  libnform  
|   Function      :  static void *Make_Enum_Type( va_list * ap )
|   
|   Description   :  Allocate structure for enumeration type argument.
|
|   Return Values :  Pointer to argument structure or NULL on error
+--------------------------------------------------------------------------*/
static void *
Make_Enum_Type(va_list *ap)
{
  enumARG *argp = typeMalloc(enumARG, 1);

  if (argp)
    {
      int cnt = 0;
      char **kp = (char **)0;
      int ccase, cunique;

      T((T_CREATE("enumARG %p"), argp));
      argp->kwds = va_arg(*ap, char **);
      ccase = va_arg(*ap, int);
      cunique = va_arg(*ap, int);

      argp->checkcase = ccase ? TRUE : FALSE;
      argp->checkunique = cunique ? TRUE : FALSE;

      kp = argp->kwds;
      while (kp && (*kp++))
	cnt++;
      argp->count = cnt;
    }
  return (void *)argp;
}
Пример #4
0
/*---------------------------------------------------------------------------
|   Facility      :  libnform
|   Function      :  static void *Generic_This_Type(void * arg)
|
|   Description   :  Allocate structure for numeric type argument.
|
|   Return Values :  Pointer to argument structure or NULL on error
+--------------------------------------------------------------------------*/
static void *
Generic_This_Type(void *arg)
{
  thisARG *argn = (thisARG *) 0;
  thisPARM *args = (thisPARM *) arg;

  if (args)
    {
      argn = typeMalloc(thisARG, 1);

      if (argn)
	{
	  T((T_CREATE("thisARG %p"), (void *)argn));
	  argn->precision = args->precision;
	  argn->low = args->low;
	  argn->high = args->high;

#if HAVE_LOCALE_H
	  argn->L = localeconv();
#else
	  argn->L = NULL;
#endif
	}
    }
  return (void *)argn;
}
Пример #5
0
NCURSES_SP_NAME(new_form) (NCURSES_SP_DCLx FIELD **fields)
{
    int err = E_SYSTEM_ERROR;
    FORM *form = (FORM *)0;

    T((T_CALLED("new_form(%p,%p)"), (void *)SP_PARM, (void *)fields));

    if (IsValidScreen(SP_PARM))
    {
        form = typeMalloc(FORM, 1);

        if (form)
        {
            T((T_CREATE("form %p"), (void *)form));
            *form = *_nc_Default_Form;
            /* This ensures win and sub are always non-null,
               so we can derive always the SCREEN that this form is
               running on. */
            form->win = StdScreen(SP_PARM);
            form->sub = StdScreen(SP_PARM);
            if ((err = Associate_Fields(form, fields)) != E_OK)
            {
                free_form(form);
                form = (FORM *)0;
            }
        }
    }

    if (!form)
        SET_ERROR(err);

    returnForm(form);
}
Пример #6
0
new_fieldtype(bool (*const field_check) (FIELD *, const void *),
	      bool (*const char_check) (int, const void *))
{
  FIELDTYPE *nftyp = (FIELDTYPE *)0;

  T((T_CALLED("new_fieldtype(%p,%p)"), field_check, char_check));
  if ((field_check) || (char_check))
    {
      nftyp = typeMalloc(FIELDTYPE, 1);

      if (nftyp)
	{
	  T((T_CREATE("fieldtype %p"), nftyp));
	  *nftyp = default_fieldtype;
	  nftyp->fcheck = field_check;
	  nftyp->ccheck = char_check;
	}
      else
	{
	  SET_ERROR(E_SYSTEM_ERROR);
	}
    }
  else
    {
      SET_ERROR(E_BAD_ARGUMENT);
    }
  returnFieldType(nftyp);
}
Пример #7
0
/*	Create list.
*/
HTList *HTList_new(void)
{
    HTList *newList;

    if ((newList = typeMalloc(HTList)) == NULL)
	  outofmem(__FILE__, "HTList_new");

    newList->object = NULL;
    newList->next = NULL;

    return newList;
}
Пример #8
0
/*---------------------------------------------------------------------------
|   Facility      :  libnform
|   Function      :  static void *Make_This_Type(va_list *ap)
|
|   Description   :  Allocate structure for alphanumeric type argument.
|
|   Return Values :  Pointer to argument structure or NULL on error
+--------------------------------------------------------------------------*/
static void *
Make_This_Type(va_list *ap)
{
  thisARG *argp = typeMalloc(thisARG, 1);

  if (argp)
    {
      T((T_CREATE("thisARG %p"), argp));
      argp->width = va_arg(*ap, int);
    }

  return ((void *)argp);
}
Пример #9
0
/*---------------------------------------------------------------------------
|   Facility      :  libnform
|   Function      :  static void *Copy_ThisType(const void *argp)
|
|   Description   :  Copy structure for alphanumeric type argument.
|
|   Return Values :  Pointer to argument structure or NULL on error.
+--------------------------------------------------------------------------*/
static void *
Copy_This_Type(const void *argp)
{
  const thisARG *ap = (const thisARG *)argp;
  thisARG *result = typeMalloc(thisARG, 1);

  if (result)
    {
      T((T_CREATE("thisARG %p"), result));
      *result = *ap;
    }

  return ((void *)result);
}
Пример #10
0
/*---------------------------------------------------------------------------
|   Facility      :  libnform  
|   Function      :  static void *Make_This_Type( va_list * ap )
|   
|   Description   :  Allocate structure for integer type argument.
|
|   Return Values :  Pointer to argument structure or NULL on error
+--------------------------------------------------------------------------*/
static void *
Make_This_Type(va_list *ap)
{
  thisARG *argp = typeMalloc(thisARG, 1);

  if (argp)
    {
      T((T_CREATE("thisARG %p"), argp));
      argp->precision = va_arg(*ap, int);
      argp->low = va_arg(*ap, long);
      argp->high = va_arg(*ap, long);
    }
  return (void *)argp;
}
Пример #11
0
dup_field(FIELD *field, int frow, int fcol)
{
  FIELD *New_Field = (FIELD *)0;
  int err = E_BAD_ARGUMENT;

  T((T_CALLED("dup_field(%p,%d,%d)"), (void *)field, frow, fcol));
  if (field && (frow >= 0) && (fcol >= 0) &&
      ((err = E_SYSTEM_ERROR) != 0) &&	/* trick : this resets the default error */
      (New_Field = typeMalloc(FIELD, 1)))
    {
      T((T_CREATE("field %p"), (void *)New_Field));
      *New_Field = *_nc_Default_Field;
      New_Field->frow = (short) frow;
      New_Field->fcol = (short) fcol;
      New_Field->link = New_Field;
      New_Field->rows = field->rows;
      New_Field->cols = field->cols;
      New_Field->nrow = field->nrow;
      New_Field->drows = field->drows;
      New_Field->dcols = field->dcols;
      New_Field->maxgrow = field->maxgrow;
      New_Field->nbuf = field->nbuf;
      New_Field->just = field->just;
      New_Field->fore = field->fore;
      New_Field->back = field->back;
      New_Field->pad = field->pad;
      New_Field->opts = field->opts;
      New_Field->usrptr = field->usrptr;

      if (_nc_Copy_Type(New_Field, field))
	{
	  size_t i, len;

	  len = Total_Buffer_Size(New_Field);
	  if ((New_Field->buf = (FIELD_CELL *)malloc(len)))
	    {
	      for (i = 0; i < len; ++i)
		New_Field->buf[i] = field->buf[i];
	      returnField(New_Field);
	    }
	}
    }

  if (New_Field)
    free_field(New_Field);

  SET_ERROR(err);
  returnField((FIELD *)0);
}
Пример #12
0
/*---------------------------------------------------------------------------
|   Facility      :  libnform
|   Function      :  static void *Make_RegularExpression_Type(va_list * ap)
|
|   Description   :  Allocate structure for regex type argument.
|
|   Return Values :  Pointer to argument structure or NULL on error
+--------------------------------------------------------------------------*/
static void *
Make_RegularExpression_Type(va_list *ap)
{
#if HAVE_REGEX_H_FUNCS
  char *rx = va_arg(*ap, char *);
  RegExp_Arg *preg;

  preg = typeMalloc(RegExp_Arg, 1);

  if (preg)
    {
      T((T_CREATE("RegExp_Arg %p"), preg));
      if (((preg->pRegExp = typeMalloc(regex_t, 1)) != 0)
	  && !regcomp(preg->pRegExp, rx,
		      (REG_EXTENDED | REG_NOSUB | REG_NEWLINE)))
	{
	  T((T_CREATE("regex_t %p"), preg->pRegExp));
	  preg->refCount = typeMalloc(unsigned long, 1);

	  *(preg->refCount) = 1;
	}
      else
	{
	  if (preg->pRegExp)
Пример #13
0
/*---------------------------------------------------------------------------
|   Facility      :  libnform
|   Function      :  static void *Generic_This_Type(va_list *ap)
|
|   Description   :  Allocate structure for alpha type argument.
|
|   Return Values :  Pointer to argument structure or NULL on error
+--------------------------------------------------------------------------*/
static void *
Generic_This_Type(void *arg)
{
  thisARG *argp = (thisARG *) 0;

  if (arg)
    {
      argp = typeMalloc(thisARG, 1);

      if (argp)
	{
	  T((T_CREATE("thisARG %p"), (void *)argp));
	  argp->width = *((int *)arg);
	}
    }
  return ((void *)argp);
}
Пример #14
0
/*      Add object to START of list (so it is pointed to by the head).
*/
void HTList_addObject(HTList *me, void *newObject)
{
    HTList *newNode;

    if (me) {
	if ((newNode = typeMalloc(HTList)) == NULL)
	      outofmem(__FILE__, "HTList_addObject");

	newNode->object = newObject;
	newNode->next = me->next;
	me->next = newNode;

    } else {
	CTRACE((tfp, "HTList: Trying to add object %p to a nonexisting list\n",
		newObject));
    }

    return;
}
Пример #15
0
/*---------------------------------------------------------------------------
|   Facility      :  libnform  
|   Function      :  static void *Copy_Enum_Type( const void * argp )
|   
|   Description   :  Copy structure for enumeration type argument.  
|
|   Return Values :  Pointer to argument structure or NULL on error.
+--------------------------------------------------------------------------*/
static void *
Copy_Enum_Type(const void *argp)
{
  enumARG *result = (enumARG *)0;

  if (argp)
    {
      const enumARG *ap = (const enumARG *)argp;

      result = typeMalloc(enumARG, 1);

      if (result)
	{
	  T((T_CREATE("enumARG %p"), result));
	  *result = *ap;
	}
    }
  return (void *)result;
}
Пример #16
0
/*---------------------------------------------------------------------------
|   Facility      :  libnform
|   Function      :  static TypeArgument *GenericArgument(
|                      const FIELDTYPE* typ,
|                      int (*argiterator)(void**),
|                      int* err)
|
|   Description   :  The iterator callback must browse through all fieldtype
|                    parameters that have an argument associated with the
|                    type. The iterator returns 1 if the operation to get
|                    the next element was successfull, 0 otherwise. If the
|                    iterator could move to the next argument, it fills
|                    the void* pointer representing the argument into the
|                    location provided as argument to the iterator.
|                    The err reference is used to keep track of errors.
|
|   Return Values :  Pointer to argument structure
+--------------------------------------------------------------------------*/
static TypeArgument *
GenericArgument(const FIELDTYPE *typ,
		int (*argiterator) (void **), int *err)
{
  TypeArgument *res = (TypeArgument *)0;

  if (typ != 0 && (typ->status & _HAS_ARGS) != 0 && err != 0 && argiterator != 0)
    {
      if (typ->status & _LINKED_TYPE)
	{
	  /* Composite fieldtypes keep track internally of their own memory */
	  TypeArgument *p = typeMalloc(TypeArgument, 1);

	  if (p)
	    {
	      p->left = GenericArgument(typ->left, argiterator, err);
	      p->right = GenericArgument(typ->right, argiterator, err);
	      return p;
	    }
	  else
	    *err += 1;
	}
      else
	{
	  assert(typ->genericarg != (void *)0);
	  if (typ->genericarg == 0)
	    *err += 1;
	  else
	    {
	      void *argp;
	      int valid = argiterator(&argp);

	      if (valid == 0 || argp == 0 ||
		  !(res = (TypeArgument *)typ->genericarg(argp)))
		{
		  *err += 1;
		}
	    }
	}
    }
  return res;
}
Пример #17
0
/*	Insert an object into the list at a specified position.
 *      If position is 0, this places the object at the head of the list
 *      and is equivalent to HTList_addObject().
 */
void HTList_insertObjectAt(HTList *me, void *newObject,
			   int pos)
{
    HTList *newNode;
    HTList *temp = me;
    HTList *prevNode;
    int Pos = pos;

    if (!temp) {
	CTRACE((tfp, "HTList: Trying to add object %p to a nonexisting list\n",
		newObject));
	return;
    }
    if (Pos < 0) {
	Pos = 0;
	CTRACE((tfp, "HTList: Treating negative object position %d as %d.\n",
		pos, Pos));
    }

    prevNode = temp;
    while ((temp = temp->next)) {
	if (Pos == 0) {
	    if ((newNode = typeMalloc(HTList)) == NULL)
		  outofmem(__FILE__, "HTList_addObjectAt");

	    assert(newNode != NULL);

	    newNode->object = newObject;
	    newNode->next = temp;
	    if (prevNode)
		prevNode->next = newNode;
	    return;
	}
	prevNode = temp;
	Pos--;
    }
    if (Pos >= 0)
	HTList_addObject(prevNode, newObject);

    return;
}
Пример #18
0
_nc_generic_fieldtype(bool (*const field_check) (FORM *, FIELD *, const void *),
		      bool (*const char_check) (int, FORM *, FIELD *, const
						void *),
		      bool (*const next) (FORM *, FIELD *, const void *),
		      bool (*const prev) (FORM *, FIELD *, const void *),
		      void (*freecallback) (void *))
{
  int code = E_SYSTEM_ERROR;
  FIELDTYPE *res = (FIELDTYPE *)0;

  T((T_CALLED("_nc_generic_fieldtype(%p,%p,%p,%p,%p)"),
     field_check, char_check, next, prev, freecallback));

  if (field_check || char_check)
    {
      res = typeMalloc(FIELDTYPE, 1);

      if (res)
	{
	  *res = *_nc_Default_FieldType;
	  res->status |= (_HAS_ARGS | _GENERIC);
	  res->fieldcheck.gfcheck = field_check;
	  res->charcheck.gccheck = char_check;
	  res->genericarg = Generic_This_Type;
	  res->freearg = freecallback;
	  res->enum_next.gnext = next;
	  res->enum_prev.gprev = prev;
	  code = E_OK;
	}
    }
  else
    code = E_BAD_ARGUMENT;

  if (E_OK != code)
    SET_ERROR(code);

  returnFieldType(res);
}
Пример #19
0
new_form(FIELD **fields)
{
    int err = E_SYSTEM_ERROR;

    FORM *form = typeMalloc(FORM, 1);

    T((T_CALLED("new_form(%p)"), fields));
    if (form)
    {
        T((T_CREATE("form %p"), form));
        *form = *_nc_Default_Form;
        if ((err = Associate_Fields(form, fields)) != E_OK)
        {
            free_form(form);
            form = (FORM *)0;
        }
    }

    if (!form)
        SET_ERROR(err);

    returnForm(form);
}
Пример #20
0
_nc_resolve_uses2(bool fullresolve, bool literal)
/* try to resolve all use capabilities */
{
    ENTRY *qp, *rp, *lastread = 0;
    bool keepgoing;
    unsigned i;
    int unresolved, total_unresolved, multiples;

    DEBUG(2, ("RESOLUTION BEGINNING"));

    /*
     * Check for multiple occurrences of the same name.
     */
    multiples = 0;
    for_entry_list(qp) {
	int matchcount = 0;

	for_entry_list(rp) {
	    if (qp > rp
		&& _nc_entry_match(qp->tterm.term_names, rp->tterm.term_names)) {
		matchcount++;
		if (matchcount == 1) {
		    (void) fprintf(stderr, "Name collision between %s",
				   _nc_first_name(qp->tterm.term_names));
		    multiples++;
		}
		if (matchcount >= 1)
		    (void) fprintf(stderr, " %s", _nc_first_name(rp->tterm.term_names));
	    }
	}
	if (matchcount >= 1)
	    (void) putc('\n', stderr);
    }
    if (multiples > 0)
	return (FALSE);

    DEBUG(2, ("NO MULTIPLE NAME OCCURRENCES"));

    /*
     * First resolution stage: compute link pointers corresponding to names.
     */
    total_unresolved = 0;
    _nc_curr_col = -1;
    for_entry_list(qp) {
	unresolved = 0;
	for (i = 0; i < qp->nuses; i++) {
	    bool foundit;
	    char *child = _nc_first_name(qp->tterm.term_names);
	    char *lookfor = qp->uses[i].name;
	    long lookline = qp->uses[i].line;

	    foundit = FALSE;

	    _nc_set_type(child);

	    /* first, try to resolve from in-core records */
	    for_entry_list(rp) {
		if (rp != qp
		    && _nc_name_match(rp->tterm.term_names, lookfor, "|")) {
		    DEBUG(2, ("%s: resolving use=%s (in core)",
			      child, lookfor));

		    qp->uses[i].link = rp;
		    foundit = TRUE;
		}
	    }

	    /* if that didn't work, try to merge in a compiled entry */
	    if (!foundit) {
		TERMTYPE thisterm;
		char filename[PATH_MAX];

		memset(&thisterm, 0, sizeof(thisterm));
		if (_nc_read_entry(lookfor, filename, &thisterm) == 1) {
		    DEBUG(2, ("%s: resolving use=%s (compiled)",
			      child, lookfor));

		    rp = typeMalloc(ENTRY, 1);
		    if (rp == 0)
			_nc_err_abort(MSG_NO_MEMORY);
		    rp->tterm = thisterm;
		    rp->nuses = 0;
		    rp->next = lastread;
		    lastread = rp;

		    qp->uses[i].link = rp;
		    foundit = TRUE;
		}
	    }

	    /* no good, mark this one unresolvable and complain */
	    if (!foundit) {
		unresolved++;
		total_unresolved++;

		_nc_curr_line = lookline;
		_nc_warning("resolution of use=%s failed", lookfor);
		qp->uses[i].link = 0;
	    }
	}
    }
    if (total_unresolved) {
	/* free entries read in off disk */
	_nc_free_entries(lastread);
	return (FALSE);
    }

    DEBUG(2, ("NAME RESOLUTION COMPLETED OK"));

    /*
     * OK, at this point all (char *) references in `name' members
     * have been successfully converted to (ENTRY *) pointers in
     * `link' members.  Time to do the actual merges.
     */
    if (fullresolve) {
	do {
	    TERMTYPE merged;

	    keepgoing = FALSE;

	    for_entry_list(qp) {
		if (qp->nuses > 0) {
		    DEBUG(2, ("%s: attempting merge",
			      _nc_first_name(qp->tterm.term_names)));
		    /*
		     * If any of the use entries we're looking for is
		     * incomplete, punt.  We'll catch this entry on a
		     * subsequent pass.
		     */
		    for (i = 0; i < qp->nuses; i++)
			if (qp->uses[i].link->nuses) {
			    DEBUG(2, ("%s: use entry %d unresolved",
				      _nc_first_name(qp->tterm.term_names), i));
			    goto incomplete;
			}

		    /*
		     * First, make sure there is no garbage in the
		     * merge block.  As a side effect, copy into
		     * the merged entry the name field and string
		     * table pointer.
		     */
		    _nc_copy_termtype(&merged, &(qp->tterm));

		    /*
		     * Now merge in each use entry in the proper
		     * (reverse) order.
		     */
		    for (; qp->nuses; qp->nuses--)
			_nc_merge_entry(&merged,
					&qp->uses[qp->nuses - 1].link->tterm);

		    /*
		     * Now merge in the original entry.
		     */
		    _nc_merge_entry(&merged, &qp->tterm);

		    /*
		     * Replace the original entry with the merged one.
		     */
		    FreeIfNeeded(qp->tterm.Booleans);
		    FreeIfNeeded(qp->tterm.Numbers);
		    FreeIfNeeded(qp->tterm.Strings);
#if NCURSES_XNAMES
		    FreeIfNeeded(qp->tterm.ext_Names);
#endif
		    qp->tterm = merged;
		    _nc_wrap_entry(qp, TRUE);

		    /*
		     * We know every entry is resolvable because name resolution
		     * didn't bomb.  So go back for another pass.
		     */
		    /* FALLTHRU */
		  incomplete:
		    keepgoing = TRUE;
		}
	    }
	} while
	    (keepgoing);

	DEBUG(2, ("MERGES COMPLETED OK"));
    }

    /*
     * We'd like to free entries read in off disk at this point, but can't.
     * The merge_entry() code doesn't copy the strings in the use entries,
     * it just aliases them.  If this ever changes, do a
     * free_entries(lastread) here.
     */

    DEBUG(2, ("RESOLUTION FINISHED"));

    if (fullresolve)
	if (_nc_check_termtype != 0) {
	    _nc_curr_col = -1;
	    for_entry_list(qp) {
		_nc_curr_line = qp->startline;
		_nc_set_type(_nc_first_name(qp->tterm.term_names));
		_nc_check_termtype2(&qp->tterm, literal);
	    }
	    DEBUG(2, ("SANITY CHECK FINISHED"));
	}
Пример #21
0
/*
 * Syntax for -m:
 * [port-type][test baudrate]:terminal-type
 * The baud rate tests are: >, <, @, =, !
 */
static void
add_mapping(const char *port, char *arg)
{
    MAP *mapp;
    char *copy, *p;
    const char *termp;
    char *base = 0;

    copy = strdup(arg);
    mapp = typeMalloc(MAP, 1);
    if (copy == 0 || mapp == 0)
	failed("malloc");

    assert(copy != 0);
    assert(mapp != 0);

    mapp->next = 0;
    if (maplist == 0)
	cur = maplist = mapp;
    else {
	cur->next = mapp;
	cur = mapp;
    }

    mapp->porttype = arg;
    mapp->conditional = 0;

    arg = strpbrk(arg, "><@=!:");

    if (arg == 0) {		/* [?]term */
	mapp->type = mapp->porttype;
	mapp->porttype = 0;
	goto done;
    }

    if (arg == mapp->porttype)	/* [><@=! baud]:term */
	termp = mapp->porttype = 0;
    else
	termp = base = arg;

    for (;; ++arg) {		/* Optional conditionals. */
	switch (*arg) {
	case '<':
	    if (mapp->conditional & GT)
		goto badmopt;
	    mapp->conditional |= LT;
	    break;
	case '>':
	    if (mapp->conditional & LT)
		goto badmopt;
	    mapp->conditional |= GT;
	    break;
	case '@':
	case '=':		/* Not documented. */
	    mapp->conditional |= EQ;
	    break;
	case '!':
	    mapp->conditional |= NOT;
	    break;
	default:
	    goto next;
	}
    }

  next:
    if (*arg == ':') {
	if (mapp->conditional)
	    goto badmopt;
	++arg;
    } else {			/* Optional baudrate. */
	arg = strchr(p = arg, ':');
	if (arg == 0)
	    goto badmopt;
	*arg++ = '\0';
	mapp->speed = tbaudrate(p);
    }

    mapp->type = arg;

    /* Terminate porttype, if specified. */
    if (termp != 0)
	*base = '\0';

    /* If a NOT conditional, reverse the test. */
    if (mapp->conditional & NOT)
	mapp->conditional = ~mapp->conditional & (EQ | GT | LT);

    /* If user specified a port with an option flag, set it. */
  done:
    if (port) {
	if (mapp->porttype) {
	  badmopt:
	    err("illegal -m option format: %s", copy);
	}
	mapp->porttype = port;
    }
    free(copy);
#ifdef MAPDEBUG
    (void) printf("port: %s\n", mapp->porttype ? mapp->porttype : "ANY");
    (void) printf("type: %s\n", mapp->type);
    (void) printf("conditional: ");
    p = "";
    if (mapp->conditional & GT) {
	(void) printf("GT");
	p = "/";
    }
    if (mapp->conditional & EQ) {
	(void) printf("%sEQ", p);
	p = "/";
    }
    if (mapp->conditional & LT)
	(void) printf("%sLT", p);
    (void) printf("\nspeed: %d\n", mapp->speed);
#endif
}
Пример #22
0
_nc_hash_map(void)
{
    HASHMAP *sp;
    register int i;
    int start, shift, size;

    if (screen_lines > lines_alloc) {
	if (hashtab)
	    free(hashtab);
	hashtab = typeMalloc(HASHMAP, (screen_lines + 1) * 2);
	if (!hashtab) {
	    if (oldhash) {
		FreeAndNull(oldhash);
	    }
	    lines_alloc = 0;
	    return;
	}
	lines_alloc = screen_lines;
    }

    if (oldhash && newhash) {
	/* re-hash only changed lines */
	for (i = 0; i < screen_lines; i++) {
	    if (PENDING(i))
		newhash[i] = hash(NEWTEXT(i));
	}
    } else {
	/* re-hash all */
	if (oldhash == 0)
	    oldhash = typeCalloc(unsigned long, (unsigned) screen_lines);
	if (newhash == 0)
	    newhash = typeCalloc(unsigned long, (unsigned) screen_lines);
	if (!oldhash || !newhash)
	    return;		/* malloc failure */
	for (i = 0; i < screen_lines; i++) {
	    newhash[i] = hash(NEWTEXT(i));
	    oldhash[i] = hash(OLDTEXT(i));
	}
    }

#ifdef HASH_VERIFY
    for (i = 0; i < screen_lines; i++) {
	if (newhash[i] != hash(NEWTEXT(i)))
	    fprintf(stderr, "error in newhash[%d]\n", i);
	if (oldhash[i] != hash(OLDTEXT(i)))
	    fprintf(stderr, "error in oldhash[%d]\n", i);
    }
#endif

    /*
     * Set up and count line-hash values.
     */
    memset(hashtab, '\0', sizeof(*hashtab) * (screen_lines + 1) * 2);
    for (i = 0; i < screen_lines; i++) {
	unsigned long hashval = oldhash[i];

	for (sp = hashtab; sp->hashval; sp++)
	    if (sp->hashval == hashval)
		break;
	sp->hashval = hashval;	/* in case this is a new entry */
	sp->oldcount++;
	sp->oldindex = i;
    }
    for (i = 0; i < screen_lines; i++) {
	unsigned long hashval = newhash[i];

	for (sp = hashtab; sp->hashval; sp++)
	    if (sp->hashval == hashval)
		break;
	sp->hashval = hashval;	/* in case this is a new entry */
	sp->newcount++;
	sp->newindex = i;

	OLDNUM(i) = _NEWINDEX;	/* initialize old indices array */
    }

    /*
     * Mark line pairs corresponding to unique hash pairs.
     *
     * We don't mark lines with offset 0, because it can make fail
     * extending hunks by cost_effective. Otherwise, it does not
     * have any side effects.
     */
    for (sp = hashtab; sp->hashval; sp++)
	if (sp->oldcount == 1 && sp->newcount == 1
	    && sp->oldindex != sp->newindex) {
	    TR(TRACE_UPDATE | TRACE_MOVE,
	       ("new line %d is hash-identical to old line %d (unique)",
		sp->newindex, sp->oldindex));
	    OLDNUM(sp->newindex) = sp->oldindex;
	}

    grow_hunks();

    /*
     * Eliminate bad or impossible shifts -- this includes removing
     * those hunks which could not grow because of conflicts, as well
     * those which are to be moved too far, they are likely to destroy
     * more than carry.
     */
    for (i = 0; i < screen_lines;) {
	while (i < screen_lines && OLDNUM(i) == _NEWINDEX)
	    i++;
	if (i >= screen_lines)
	    break;
	start = i;
	shift = OLDNUM(i) - i;
	i++;
	while (i < screen_lines && OLDNUM(i) != _NEWINDEX && OLDNUM(i) - i
	       == shift)
	    i++;
	size = i - start;
	if (size < 3 || size + min(size / 8, 2) < abs(shift)) {
	    while (start < i) {
		OLDNUM(start) = _NEWINDEX;
		start++;
	    }
	}
    }

    /* After clearing invalid hunks, try grow the rest. */
    grow_hunks();
}
Пример #23
0
wresize(WINDOW *win, int ToLines, int ToCols)
{
    int col, row, size_x, size_y;
    struct ldat *pline;
    struct ldat *new_lines = 0;

#ifdef TRACE
    T((T_CALLED("wresize(%p,%d,%d)"), win, ToLines, ToCols));
    if (win) {
	TR(TRACE_UPDATE, ("...beg (%ld, %ld), max(%ld,%ld), reg(%ld,%ld)",
			  (long) win->_begy, (long) win->_begx,
			  (long) win->_maxy, (long) win->_maxx,
			  (long) win->_regtop, (long) win->_regbottom));
	if (USE_TRACEF(TRACE_UPDATE)) {
	    _tracedump("...before", win);
	    _nc_unlock_global(tracef);
	}
    }
#endif

    if (!win || --ToLines < 0 || --ToCols < 0)
	returnCode(ERR);

    size_x = win->_maxx;
    size_y = win->_maxy;

    if (ToLines == size_y
	&& ToCols == size_x)
	returnCode(OK);

    if ((win->_flags & _SUBWIN)) {
	/*
	 * Check if the new limits will fit into the parent window's size.  If
	 * not, do not resize.  We could adjust the location of the subwindow,
	 * but the application may not like that.
	 */
	if (win->_pary + ToLines > win->_parent->_maxy
	    || win->_parx + ToCols > win->_parent->_maxx) {
	    returnCode(ERR);
	}
	pline = win->_parent->_line;
    } else {
	pline = 0;
    }

    /*
     * Allocate new memory as needed.  Do the allocations without modifying
     * the original window, in case an allocation fails.  Always allocate
     * (at least temporarily) the array pointing to the individual lines.
     */
    new_lines = typeCalloc(struct ldat, (unsigned) (ToLines + 1));
    if (new_lines == 0)
	returnCode(ERR);

    /*
     * For each line in the target, allocate or adjust pointers for the
     * corresponding text, depending on whether this is a window or a
     * subwindow.
     */
    for (row = 0; row <= ToLines; ++row) {
	int begin = (row > size_y) ? 0 : (size_x + 1);
	int end = ToCols;
	NCURSES_CH_T *s;

	if (!(win->_flags & _SUBWIN)) {
	    if (row <= size_y) {
		if (ToCols != size_x) {
		    if ((s = typeMalloc(NCURSES_CH_T, ToCols + 1)) == 0)
			returnCode(cleanup_lines(new_lines, row));
		    for (col = 0; col <= ToCols; ++col) {
			s[col] = (col <= size_x
				  ? win->_line[row].text[col]
				  : win->_nc_bkgd);
		    }
		} else {
		    s = win->_line[row].text;
		}
	    } else {
		if ((s = typeMalloc(NCURSES_CH_T, ToCols + 1)) == 0)
		    returnCode(cleanup_lines(new_lines, row));
		for (col = 0; col <= ToCols; ++col)
		    s[col] = win->_nc_bkgd;
	    }
	} else {
	    s = &pline[win->_pary + row].text[win->_parx];
	}

	if_USE_SCROLL_HINTS(new_lines[row].oldindex = row);
	if (row <= size_y) {
	    new_lines[row].firstchar = win->_line[row].firstchar;
	    new_lines[row].lastchar = win->_line[row].lastchar;
	}
	if ((ToCols != size_x) || (row > size_y)) {
	    if (end >= begin) {	/* growing */
		if (new_lines[row].firstchar < begin)
		    new_lines[row].firstchar = begin;
	    } else {		/* shrinking */
		new_lines[row].firstchar = 0;
	    }
	    new_lines[row].lastchar = ToCols;
	}
	new_lines[row].text = s;
    }

    /*
     * Dispose of unwanted memory.
     */
    if (!(win->_flags & _SUBWIN)) {
	if (ToCols == size_x) {
	    for (row = ToLines + 1; row <= size_y; row++) {
		free(win->_line[row].text);
	    }
	} else {
	    for (row = 0; row <= size_y; row++) {
		free(win->_line[row].text);
	    }
	}
    }

    free(win->_line);
    win->_line = new_lines;

    /*
     * Finally, adjust the parameters showing screen size and cursor
     * position:
     */
    win->_maxx = ToCols;
    win->_maxy = ToLines;

    if (win->_regtop > win->_maxy)
	win->_regtop = win->_maxy;
    if (win->_regbottom > win->_maxy
	|| win->_regbottom == size_y)
	win->_regbottom = win->_maxy;

    if (win->_curx > win->_maxx)
	win->_curx = win->_maxx;
    if (win->_cury > win->_maxy)
	win->_cury = win->_maxy;

    /*
     * Check for subwindows of this one, and readjust pointers to our text,
     * if needed.
     */
    repair_subwindows(win);

#ifdef TRACE
    TR(TRACE_UPDATE, ("...beg (%ld, %ld), max(%ld,%ld), reg(%ld,%ld)",
		      (long) win->_begy, (long) win->_begx,
		      (long) win->_maxy, (long) win->_maxx,
		      (long) win->_regtop, (long) win->_regbottom));
    if (USE_TRACEF(TRACE_UPDATE)) {
	_tracedump("...after:", win);
	_nc_unlock_global(tracef);
    }
#endif
    returnCode(OK);
}
Пример #24
0
/*---------------------------------------------------------------------------
|   Facility      :  libnform
|   Function      :  static int Connect_Fields(FORM *form, FIELD **fields)
|
|   Description   :  Set association between form and array of fields.
|
|   Return Values :  E_OK            - no error
|                    E_CONNECTED     - a field is already connected
|                    E_BAD_ARGUMENT  - Invalid form pointer or field array
|                    E_SYSTEM_ERROR  - not enough memory
+--------------------------------------------------------------------------*/
static int
Connect_Fields(FORM *form, FIELD **fields)
{
    int field_cnt, j;
    int page_nr;
    int maximum_row_in_field, maximum_col_in_field;
    _PAGE *pg;

    T((T_CALLED("Connect_Fields(%p,%p)"), (void *)form, (void *)fields));

    assert(form);

    form->field = fields;
    form->maxfield = 0;
    form->maxpage = 0;

    if (!fields)
        RETURN(E_OK);

    page_nr = 0;
    /* store formpointer in fields and count pages */
    for (field_cnt = 0; fields[field_cnt]; field_cnt++)
    {
        if (fields[field_cnt]->form)
            RETURN(E_CONNECTED);
        if (field_cnt == 0 ||
                (fields[field_cnt]->status & _NEWPAGE))
            page_nr++;
        fields[field_cnt]->form = form;
    }
    if (field_cnt == 0 || (short)field_cnt < 0)
        RETURN(E_BAD_ARGUMENT);

    /* allocate page structures */
    if ((pg = typeMalloc(_PAGE, page_nr)) != (_PAGE *) 0)
    {
        T((T_CREATE("_PAGE %p"), (void *)pg));
        form->page = pg;
    }
    else
        RETURN(E_SYSTEM_ERROR);

    /* Cycle through fields and calculate page boundaries as well as
       size of the form */
    for (j = 0; j < field_cnt; j++)
    {
        if (j == 0)
            pg->pmin = (short) j;
        else
        {
            if (fields[j]->status & _NEWPAGE)
            {
                pg->pmax = (short) (j - 1);
                pg++;
                pg->pmin = (short) j;
            }
        }

        maximum_row_in_field = fields[j]->frow + fields[j]->rows;
        maximum_col_in_field = fields[j]->fcol + fields[j]->cols;

        if (form->rows < maximum_row_in_field)
            form->rows = (short) maximum_row_in_field;
        if (form->cols < maximum_col_in_field)
            form->cols = (short) maximum_col_in_field;
    }

    pg->pmax = (short) (field_cnt - 1);
    form->maxfield = (short) field_cnt;
    form->maxpage = (short) page_nr;

    /* Sort fields on form pages */
    for (page_nr = 0; page_nr < form->maxpage; page_nr++)
    {
        FIELD *fld = (FIELD *)0;

        for (j = form->page[page_nr].pmin; j <= form->page[page_nr].pmax; j++)
        {
            fields[j]->index = (short) j;
            fields[j]->page = (short) page_nr;
            fld = Insert_Field_By_Position(fields[j], fld);
        }
        if (fld)
        {
            form->page[page_nr].smin = fld->index;
            form->page[page_nr].smax = fld->sprev->index;
        }
        else
        {
            form->page[page_nr].smin = 0;
            form->page[page_nr].smax = 0;
        }
    }
    RETURN(E_OK);
}