示例#1
0
文件: slpath.c 项目: parke/slang
/* If path looks like: A/B/C/D/whatever, it returns A/B/C/D as a malloced
 * string.
 */
char *SLpath_dirname (SLFUTURE_CONST char *file)
{
   SLCONST char *b;

   if (file == NULL) return NULL;
   b = file + strlen (file);

   while (b != file)
     {
	b--;
	if (IS_PATH_SEP(*b))
	  {
#ifdef VMS
	     b++;		       /* make sure final ] is included */
#else
	     if (b == file) b++;
#endif
	     break;
	  }

#ifdef DRIVE_SPECIFIER
	if (*b == DRIVE_SPECIFIER)
	  {
	     b++;
	     break;
	  }
#endif
     }

   if (b == file)
     return SLmake_string (THIS_DIR_STRING);

   return SLmake_nstring (file, (unsigned int) (b - file));
}
示例#2
0
文件: slscanf.c 项目: ebichu/dd-wrt
static int parse_range (SLFUTURE_CONST char **sp, SLFUTURE_CONST char *smax, SLFUTURE_CONST char **fp, char **str)
{
   SLFUTURE_CONST char *s, *s0;
   char *range;
   SLFUTURE_CONST char *f;
   unsigned char map[256];
   unsigned char reverse;

   /* How can one represent a range with just '^'?  The naive answer is
    * is [^].  However, this may be interpreted as meaning any character
    * but ']' and others.  Let's assume that the user will not use a range
    * to match '^'.
    */
   f = *fp;
   /* f is a pointer to (one char after) [...]. */
   if (*f == '^')
     {
	f++;
	reverse = 1;
     }
   else reverse = 0;

   s0 = f;
   if (*f == ']')
     f++;

   while (1)
     {
	char ch = *f;

	if (ch == 0)
	  {
	     _pSLang_verror (SL_INVALID_PARM, "Unexpected end of range in format");
	     return -1;
	  }
	if (ch == ']')
	  break;
	f++;
     }
   if (NULL == (range = SLmake_nstring (s0, (unsigned int) (f - s0))))
     return -1;
   *fp = f + 1;			       /* skip ] */
   
   SLmake_lut (map, (unsigned char *) range, reverse);
   SLfree (range);

   s0 = s = *sp;
   while ((s < smax) && map [(unsigned char) *s])
     s++;
   
   if (NULL == (*str = SLang_create_nslstring (s0, (unsigned int) (s - s0))))
     return -1;
   
   *sp = s;
   return 1;
}
示例#3
0
/* This is used if the key is not UTF-8, or it is but the search is case-sensitive */
static SLsearch_Type *bm_open_search (SLuchar_Type *key, int flags)
{
   SLsearch_Type *st;
   size_t keylen;

   keylen = strlen ((char *)key);
   if (NULL == (st = (SLsearch_Type *)SLcalloc (1, sizeof (SLsearch_Type))))
     return NULL;

   st->free_fun = bm_free;

   /* If the search is case-insensitive, then it must either be all ascii, or
    * it is not unicode.  In either case, the UPPER_CASE and LOWER_CASE macros
    * should be ok to use.
    */
   if (flags & SLSEARCH_CASELESS)
     {
	char *keyup = SLmake_nstring ((char *)key, keylen);
	if (keyup != NULL)
	  {
	     unsigned char *k = (unsigned char *)keyup;
	     while (*k != 0)
	       {
		  *k = UPPER_CASE(*k);
		  k++;
	       }
	     st->s.bm.key = (SLuchar_Type *)SLang_create_slstring (keyup);
	     SLfree (keyup);
	  }
	else st->s.bm.key = NULL;
     }
   else st->s.bm.key = (SLuchar_Type*) SLang_create_slstring ((char *)key);

   if (st->s.bm.key == NULL)
     {
        SLsearch_delete (st);
        return NULL;
     }
   st->s.bm.key_len = keylen;
   st->flags = flags;

   st->search_fun = bm_search;

   init_skip_table (st->s.bm.key, st->s.bm.key_len, st->s.bm.fskip_table, 1, flags);
   init_skip_table (st->s.bm.key, st->s.bm.key_len, st->s.bm.bskip_table, -1, flags);
   return st;
}
示例#4
0
static void path_extname (char *path)
{
#ifdef VMS
   char *p;
#endif

   path = SLpath_extname (path);
#ifndef VMS
   SLang_push_string (path);
#else
   p = strchr (path, ';');
   if (p == NULL)
     (void)SLang_push_string (p);
   else
     (void)SLang_push_malloced_string (SLmake_nstring (path, (unsigned int)(p - path)));
#endif
}
示例#5
0
SLsearch_Type *SLsearch_new (SLuchar_Type *key, int flags)
{
   SLsearch_Type *st, *bf_st;
   SLuchar_Type *key_upper, *key_lower, *non_ascii;
   size_t len, upper_len, lower_len;

   if (Case_Tables_Ok == 0)
     SLang_init_case_tables ();

   if (key == NULL)
     return NULL;

   if ((0 == (flags & SLSEARCH_CASELESS))
       || (0 == (flags & SLSEARCH_UTF8)))
     return bm_open_search (key, flags);

   /* Otherwise the key is UTF-8 and the search is case-insensitive */
   len = strlen ((char *)key);
   key_upper = SLutf8_strup (key, key + len);
   if (key_upper == NULL)
     return NULL;

   upper_len = strlen ((char *)key_upper);

   if (is_bm_ok (key_upper, upper_len, &non_ascii))
     {
        st = bm_open_search (key_upper, flags);
        SLang_free_slstring ((char *)key_upper);
        return st;
     }

   /* Tricky part */

   if (NULL == (key_lower = SLutf8_strlo (key, key + len)))
     {
        SLang_free_slstring ((char *)key_upper);
        return NULL;
     }

   lower_len = strlen ((char *)key_lower);

   /* Try a case-less search */
   if ((lower_len == upper_len)
       && (0 == strcmp ((char *)key_upper, (char *)key_lower)))
     {
        flags &= ~SLSEARCH_CASELESS;
        st = bm_open_search (key_upper, flags);
        SLang_free_slstring ((char *)key_upper);
        SLang_free_slstring ((char *)key_lower);
        return st;
     }

   /* Now Perform a brute-force search. */

   /* If the first few characters of the search string are ascii, then
    * use BM for that portion
    */
   bf_st = NULL;
   if (non_ascii - key_upper >= 3)
     {
        SLuchar_Type *key1 = (SLuchar_Type *) SLmake_nstring ((char *)key_upper, non_ascii - key_upper);

        /* ok to propagate NULL below */
        bf_st = SLsearch_new (key1, flags);
        SLfree ((char *)key1);
        if (bf_st == NULL)
          {
             SLang_free_slstring ((char *)key_upper);
             SLang_free_slstring ((char *)key_lower);
             return NULL;
          }

        key1 = (SLuchar_Type *) SLang_create_slstring ((char *)non_ascii);
        non_ascii = key_lower + (non_ascii - key_upper);
        SLang_free_slstring ((char *)key_upper);
        key_upper = key1;

        key1 = (SLuchar_Type *)SLang_create_slstring ((char *)non_ascii);
        SLang_free_slstring ((char *)key_lower);
        key_lower = key1;

        if ((key_lower == NULL) || (key_upper == NULL))
          {
             SLang_free_slstring ((char *)key_upper);
             SLang_free_slstring ((char *)key_lower);
             SLsearch_delete (bf_st);
             return NULL;
          }
        upper_len = strlen ((char *)key_upper);
        lower_len = strlen ((char *)key_lower);
     }

   st = (SLsearch_Type *)SLcalloc (sizeof (SLsearch_Type), 1);
   if (st == NULL)
     goto return_error;
   st->free_fun = bf_free;
   st->flags = flags;
   st->search_fun = bf_search;

   st->s.bf.st = bf_st;  bf_st = NULL;

   if (NULL == (st->s.bf.lower_chars = make_string_array (key_lower, lower_len, &st->s.bf.nlower_chars)))
     goto return_error;

   if (NULL == (st->s.bf.upper_chars = make_string_array (key_upper, upper_len, &st->s.bf.nupper_chars)))
     goto return_error;

   SLang_free_slstring ((char *)key_upper);
   SLang_free_slstring ((char *)key_lower);
   return st;

   return_error:
   SLsearch_delete (st);
   SLsearch_delete (bf_st);
   SLang_free_slstring ((char *)key_upper);
   SLang_free_slstring ((char *)key_lower);
   return NULL;
}
示例#6
0
int SLcmd_execute_string (char *str, SLcmd_Cmd_Table_Type *table)
{
   char *s, *arg_type, *last_str, *cmd_name;
   SLcmd_Cmd_Type *cmd;
   char *buf;
   int token_present;
   int i;
   int status;
   unsigned int len;
   int argc;
   unsigned int 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))))
     {
	SLang_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);
		  len = strlen (buf);
	       }
	     else if ((*b == '\'') && (len > 1))
	       {
		  char ch;
		  b++;
		  len -= 2;
		  b[len] = 0;
		  guess_type = SLANG_INT_TYPE;
		  ch = *b;
		  if (ch == '\\')
		    (void) _SLexpand_escaped_char (b, &ch);
		  sprintf (buf, "%d", (unsigned char) 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)
	       {
		  SLang_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)
	       {
		  SLang_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))
	       {
		  SLang_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))
	       {
		  SLang_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)
	       {
		  SLang_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 (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;
}
示例#7
0
/* If path looks like: A/B/C/D/whatever, it returns A/B/C/D as a malloced
 * string.
 */
char *SLpath_dirname (SLFUTURE_CONST char *drivefile)
{
   SLCONST char *b;
   const char *file;
   char *dir, *drivedir;
   size_t len;

   if (drivefile == NULL) return NULL;
   file = skip_drive (drivefile);

   b = file + strlen (file);

   while (b != file)
     {
	b--;
	if (0 == IS_PATH_SEP(*b))
	  continue;

#ifdef VMS
	b++;		       /* make sure final ] is included */
#else
	/* collapse multiple slashes */
	while ((b != file) && IS_PATH_SEP(*(b-1)))
	  b--;

	if (b == file) b++;
#endif
	break;
     }

   /* now b should point to the character after the slash:
    *    file="zzz/xxxx"
    *       b------^
    */
   if (b == file)
     {
	/* pathological cases -- what is the parent?  For simplicity
	 * simply return the current directory.
	 */
	len = file - drivefile;
	if (NULL == (dir = SLmalloc (len + 1 + strlen(THIS_DIR_STRING))))
	  return NULL;
	strncpy (dir, drivefile, len);
	strcpy (dir + len, THIS_DIR_STRING);
	return dir;
     }

   if (NULL == (drivedir = SLmake_nstring (drivefile, b - drivefile)))
     return NULL;

   dir = drivedir + (file - drivefile);
   len = b - file;		       /* len is from start of file on drive */

#ifndef VMS
   /* handle special cases
    *    /foo/.   --> /foo
    *    /.       --> /
    *    /foo/..  --> /
    * C:/.
    */
   while ((len > 1) && (dir[len-1] == '.'))
     {
	if (IS_PATH_SEP(dir[len-2]))
	  {
	     len--;		       /* lose "." */
	     while ((len > 1) && IS_PATH_SEP(dir[len-1]))
	       len--;		       /* lose "/" */
	     dir[len] = 0;
	     continue;
	  }
	if ((len > 2) && (dir[len-2] == '.') && IS_PATH_SEP(dir[len-3]))
	  {
	     len -= 2;		       /* lose ".." */
	     if (len > 1)
	       {
		  len--;		       /* lose "/" */
		  dir[len] = 0;
		  b = SLpath_basename (dir);   /* will not fail: zzz/xxx --> zzz/x */
		  len = b - dir;
		  while ((len > 1) && IS_PATH_SEP(dir[len-1]))
		    len--;
	       }
	     dir[len] = 0;
	     continue;
	  }

	break;
     }
#endif				       /* not VMS */
   return drivedir;
}
示例#8
0
char *SLrline_get_line (SLrline_Type *rli)
{
   if (rli == NULL)
     return NULL;
   return SLmake_nstring ((char *)rli->buf, rli->len);
}
示例#9
0
char *SLrline_read_line (SLrline_Type *rli, SLFUTURE_CONST char *prompt, unsigned int *lenp)
{
   unsigned char *p, *pmax;
   SLang_Key_Type *key;
   int last_input_char;
   unsigned int dummy_len_buf;

   if (lenp == NULL)
     lenp = &dummy_len_buf;

   *lenp = 0;

   if (rli == NULL)
     return NULL;

   if (rli->state == RLI_LINE_IN_PROGRESS)
     {
	*lenp = 0;
	return NULL;
     }

   if (prompt == NULL)
     prompt = "";

   if ((rli->prompt == NULL)
       || strcmp (rli->prompt, prompt))
     {
	if (NULL == (prompt = SLmake_string (prompt)))
	  return NULL;
	
	SLfree ((char *)rli->prompt);
	rli->prompt = prompt;
     }

   SLang_Rline_Quit = 0;
   p = rli->old_upd; pmax = p + rli->edit_width;
   while (p < pmax) *p++ = ' ';

   if (rli->state != RLI_LINE_SET)
     {
	rli->len = 0;
	rli->point = 0;
	*rli->buf = 0;
     }
   rli->state = RLI_LINE_IN_PROGRESS;

   rli->curs_pos = rli->start_column = 0;
   rli->new_upd_len = rli->old_upd_len = 0;

   rli->last_fun = NULL;
   if (rli->update_hook == NULL)
     putc ('\r', stdout);

   rli->is_modified = 0;
   rli->last = NULL;

   RLupdate (rli);

   last_input_char = 0;
   while (1)
     {
	SLrline_Type *save_rli = Active_Rline_Info;

	key = SLang_do_key (RL_Keymap, (int (*)(void)) rli->getkey);

	if ((key == NULL) || (key->f.f == NULL))
	  {
	     rl_beep ();
	     continue;
	  }

	if ((*key->str != 2) || (key->str[1] != rli->eof_char))
	  last_input_char = 0;
	else
	  {
	     if ((rli->len == 0) && (last_input_char != rli->eof_char))
	       {
		  rli->buf[rli->len] = 0;
		  rli->state = RLI_LINE_READ;
		  *lenp = 0;
		  return NULL;	       /* EOF */
	       }
	     
	     last_input_char = rli->eof_char;
	  }

	Active_Rline_Info = rli;
	if (key->type == SLKEY_F_INTRINSIC)
	  {
	     int (*func)(SLrline_Type *);
	     func = (int (*)(SLrline_Type *)) key->f.f;
	     
	     (void) (*func)(rli);

	     RLupdate (rli);
	     
	     if ((rli->flags & SL_RLINE_BLINK_MATCH)
		 && (rli->input_pending != NULL))
	       blink_match (rli);
	  }
	else if (key->type == SLKEY_F_SLANG)
	  {
	     (void) SLexecute_function (key->f.slang_fun);
	     RLupdate (rli);
	  }
	Active_Rline_Info = save_rli;

	if ((SLang_Rline_Quit) || _pSLang_Error)
	  {
	     if (_pSLang_Error)
	       {
		  rli->len = 0;
	       }
	     rli->buf[rli->len] = 0;
	     rli->state = RLI_LINE_READ;
	     *lenp = rli->len;
	     
	     free_history_item (rli->saved_line);
	     rli->saved_line = NULL;
	     
	     if (_pSLang_Error)
	       return NULL;

	     return SLmake_nstring ((char *)rli->buf, rli->len);
	  }
	if (key != NULL)
	  rli->last_fun = key->f.f;
     }
}