Example #1
0
static int tcap_getent (SLCONST char *term, SLterminfo_Type *ti)
{
   unsigned char *termcap, ch;
   unsigned char *buf, *b;
   unsigned char *t;
   int len;

   if (SLtt_Try_Termcap == 0) return -1;
#if 1
   /* XFREE86 xterm sets the TERMCAP environment variable to an invalid
    * value.  Specifically, it lacks the tc= string.
    */
   if (!strncmp (term, "xterm", 5))
     return -1;
#endif
   termcap = (unsigned char *) getenv ("TERMCAP");
   if ((termcap == NULL) || (*termcap == '/')) return -1;

   /* SUN Solaris 7&8 have bug in tset program under tcsh,
    * eval `tset -s -A -Q` sets value of TERMCAP to ":",
    *  under other shells it works fine.
    *  SUN was informed, they marked it as duplicate of bug 4086585
    *  but didn't care to fix it... <*****@*****.**>
    */
   if ((termcap[0] == ':') && (termcap[1] == 0))
     return -1;

   /* We have a termcap so lets use it provided it does not have a reference
    * to another terminal via tc=.  In that case, use terminfo.  The alternative
    * would be to parse the termcap file which I do not want to do right now.
    * Besides, this is a terminfo based system and if the termcap were parsed
    * terminfo would almost never get a chance to run.  In addition, the tc=
    * thing should not occur if tset is used to set the termcap entry.
    */
   t = termcap;
   while ((len = tcap_extract_field (t)) != -1)
     {
	if ((len > 3) && (t[0] == 't') && (t[1] == 'c') && (t[2] == '='))
	  return -1;
	t += (len + 1);
     }

   /* malloc some extra space just in case it is needed. */
   len = strlen ((char *) termcap) + 256;
   if (NULL == (buf = (unsigned char *) SLmalloc ((unsigned int) len)))
     return -1;

   b = buf;

   /* The beginning of the termcap entry contains the names of the entry.
    * It is terminated by a colon.
    */

   ti->terminal_names = (char *) b;
   t = termcap;
   len = tcap_extract_field (t);
   if (len < 0)
     {
	SLfree ((char *)buf);
	return -1;
     }
   strncpy ((char *) b, (char *) t, (unsigned int) len);
   b[len] = 0;
   b += len + 1;
   ti->name_section_size = len;

   /* Now, we are really at the start of the termcap entries.  Point the
    * termcap variable here since we want to refer to this a number of times.
    */
   termcap = t + (len + 1);

   /* Process strings first. */
   ti->string_table = (char *) b;
   t = termcap;
   while (-1 != (len = tcap_extract_field (t)))
     {
	unsigned char *b1;
	unsigned char *tmax;

	/* We are looking for: XX=something */
	if ((len < 4) || (t[2] != '=') || (*t == '.'))
	  {
	     t += len + 1;
	     continue;
	  }
	tmax = t + len;
	b1 = b;

	while (t < tmax)
	  {
	     ch = *t++;
	     if ((ch == '\\') && (t < tmax))
	       {
		  SLwchar_Type wch;

		  t = (unsigned char *) _pSLexpand_escaped_char ((char *) t, (char *) tmax, &wch, NULL);
		  if (t == NULL)
		    {
		       SLfree ((char *)buf);
		       return -1;
		    }
		  ch = (char) wch;
	       }
	     else if ((ch == '^') && (t < tmax))
	       {
		  ch = *t++;
		  if (ch == '?') ch = 127;
		  else ch = (ch | 0x20) - ('a' - 1);
	       }
	     *b++ = ch;
	  }
	/* Null terminate it. */
	*b++ = 0;
	len = (int) (b - b1);
	b1[2] = (unsigned char) len;    /* replace the = by the length */
	/* skip colon to next field. */
	t++;
     }
   ti->string_table_size = (int) (b - (unsigned char *) ti->string_table);

   /* Now process the numbers. */

   t = termcap;
   ti->numbers = b;
   while (-1 != (len = tcap_extract_field (t)))
     {
	unsigned char *b1;
	unsigned char *tmax;

	/* We are looking for: XX#NUMBER */
	if ((len < 4) || (t[2] != '#') || (*t == '.'))
	  {
	     t += len + 1;
	     continue;
	  }
	tmax = t + len;
	b1 = b;

	while (t < tmax)
	  {
	     *b++ = *t++;
	  }
	/* Null terminate it. */
	*b++ = 0;
	len = (int) (b - b1);
	b1[2] = (unsigned char) len;    /* replace the # by the length */
	t++;
     }
   ti->num_numbers = (int) (b - ti->numbers);

   /* Now process the flags. */
   t = termcap;
   ti->boolean_flags = b;
   while (-1 != (len = tcap_extract_field (t)))
     {
	/* We are looking for: XX#NUMBER */
	if ((len != 2) || (*t == '.') || (*t <= ' '))
	  {
	     t += len + 1;
	     continue;
	  }
	b[0] = t[0];
	b[1] = t[1];
	t += 3;
	b += 2;
     }
   ti->boolean_section_size = (int) (b - ti->boolean_flags);
   ti->flags = SLTERMCAP;
   return 0;
}
Example #2
0
File: slcmd.c Project: parke/slang
int SLcmd_execute_string (SLFUTURE_CONST char *str, SLcmd_Cmd_Table_Type *table)
{
   SLFUTURE_CONST char *s, *arg_type, *last_str, *cmd_name;
   SLcmd_Cmd_Type *cmd;
   char *buf;
   int token_present;
   int i;
   int status;
   SLstrlen_Type len;
   int argc;
   SLstrlen_Type space;

   table->argc = 0;
   table->string_args = NULL;
   table->int_args = NULL;
   table->double_args = NULL;
   table->arg_type = NULL;

   buf = SLmake_string (str);
   if (buf == NULL)
     return -1;

   status = extract_token (&str, buf);
   if (status <= 0)
     {
	SLfree (buf);
	return status;
     }

   if (((len = strlen (buf)) >= 32)
       || (NULL == (cmd = SLcmd_find_command (buf, table->table))))
     {
	_pSLang_verror (SL_UNDEFINED_NAME,"%s: invalid command", buf);
	SLfree (buf);
	return -1;
     }

   if (NULL == (cmd_name = SLmake_string (buf)))
     {
	SLfree (buf);
	return -1;
     }

   space = 0;
   argc = 0;
   if (-1 == allocate_arg_space (table, argc, &space))
     {
	SLfree (buf);
	return -1;
     }
   table->arg_type[argc] = SLANG_STRING_TYPE;
   table->string_args[argc++] = cmd_name;

   arg_type = cmd->arg_type;
   status = -1;
   while (*arg_type)
     {
	int guess_type = 0;

	last_str = str;

	if (-1 == allocate_arg_space (table, argc, &space))
	  goto error;

	if (-1 == (token_present = extract_token (&str, buf)))
	  goto error;

	table->string_args[argc] = NULL;

	if (token_present)
	  {
	     char *b = buf;
	     len = strlen (b);

	     if ((*b == '"') && (len > 1))
	       {
		  b++;
		  len -= 2;
		  b[len] = 0;
		  guess_type = SLANG_STRING_TYPE;
		  SLexpand_escaped_string (buf, b, b + len, -1);
		  len = strlen (buf);
	       }
	     else if ((*b == '\'') && (len > 1))
	       {
		  SLwchar_Type ch;
		  b++;
		  len -= 2;
		  b[len] = 0;
		  guess_type = SLANG_INT_TYPE;
		  ch = *b;
		  if (ch == '\\')
		    {
		       if (NULL == _pSLexpand_escaped_char (b, b+len, &ch, NULL))
			 goto error;
		    }
		  sprintf (buf, "%lu", (unsigned long)ch);
		  len = strlen (buf);
	       }
	     else guess_type = SLang_guess_type (buf);
	  }

	switch (*arg_type++)
	  {
	     /* variable argument number */
	   case 'v':
	     if (token_present == 0) break;
	   case 'V':
	     if (token_present == 0)
	       {
		  _pSLang_verror (SL_INVALID_PARM, "%s: Expecting argument", cmd_name);
		  goto error;
	       }

	     while (*last_str == ' ') last_str++;
	     len = strlen (last_str);
	     str = last_str + len;

	     s = SLmake_nstring (last_str, len);
	     if (s == NULL) goto error;

	     table->arg_type[argc] = SLANG_STRING_TYPE;
	     table->string_args[argc++] = s;
	     break;

	   case 's':
	     if (token_present == 0) break;
	   case 'S':
	     if (token_present == 0)
	       {
		  _pSLang_verror (SL_TYPE_MISMATCH, "%s: Expecting string argument", cmd_name);
		  goto error;
	       }

	     s = SLmake_nstring (buf, len);
	     if (s == NULL) goto error;
	     table->arg_type[argc] = SLANG_STRING_TYPE;
	     table->string_args[argc++] = s;
	     break;

	     /* integer argument */
	   case 'i':
	     if (token_present == 0) break;
	   case 'I':
	     if ((token_present == 0) || (SLANG_INT_TYPE != guess_type))
	       {
		  _pSLang_verror (SL_TYPE_MISMATCH, "%s: Expecting integer argument", cmd_name);
		  goto error;
	       }

	     table->arg_type[argc] = SLANG_INT_TYPE;
	     table->int_args[argc++] = SLatoi((unsigned char *) buf);
	     break;

	     /* floating point arg */
#if SLANG_HAS_FLOAT
	   case 'f':
	     if (token_present == 0) break;
	   case 'F':
	     if ((token_present == 0) || (SLANG_STRING_TYPE == guess_type))
	       {
		  _pSLang_verror (SL_TYPE_MISMATCH, "%s: Expecting double argument", cmd_name);
		  goto error;
	       }
	     table->arg_type[argc] = SLANG_DOUBLE_TYPE;
	     table->double_args[argc++] = atof(buf);
	     break;
#endif
	     /* Generic type */
	   case 'g':
	     if (token_present == 0) break;
	   case 'G':
	     if (token_present == 0)
	       {
		  _pSLang_verror (SL_TYPE_MISMATCH, "%s: Expecting argument", cmd_name);
		  goto error;
	       }

	     switch (guess_type)
	       {
		case SLANG_INT_TYPE:
		  table->arg_type[argc] = SLANG_INT_TYPE;
		  table->int_args[argc++] = SLatoi((unsigned char *) buf);
		  break;

		case SLANG_STRING_TYPE:
		  s = SLmake_nstring (buf, len);
		  if (s == NULL) goto error;

		  table->arg_type[argc] = SLANG_STRING_TYPE;
		  table->string_args[argc++] = s;
		  break;
#if SLANG_HAS_FLOAT
		case SLANG_DOUBLE_TYPE:
		  table->arg_type[argc] = SLANG_DOUBLE_TYPE;
		  table->double_args[argc++] = atof(buf);
#endif
	       }
	     break;
	  }
     }

   /*                 call function */
   status = (*cmd->cmdfun)(argc, table);

   error:
   if (table->string_args != NULL) for (i = 0; i < argc; i++)
     {
	if (NULL != table->string_args[i])
	  {
	     SLfree ((char *) table->string_args[i]);
	     table->string_args[i] = NULL;
	  }
     }
   SLfree ((char *)table->string_args); table->string_args = NULL;
   SLfree ((char *)table->double_args); table->double_args = NULL;
   SLfree ((char *)table->int_args); table->int_args = NULL;
   SLfree ((char *)table->arg_type); table->arg_type = NULL;

   SLfree (buf);
   return status;
}