Beispiel #1
0
/**
 * Compares two FileItems.
 *
 * Based on 'ustricmp' of Allegro. It makes sure that eg "foo.bar"
 * comes before "foo-1.bar", and also that "foo9.bar" comes before
 * "foo10.bar".
 */
int FileItem::compare(const FileItem& that) const
{
  if (IS_FOLDER(this)) {
    if (!IS_FOLDER(&that))
      return -1;
  }
  else if (IS_FOLDER(&that))
    return 1;

  {
    int c1, c2;
    int x1, x2;
    char *t1, *t2;
    const char* s1 = this->displayname.c_str();
    const char* s2 = that.displayname.c_str();

    for (;;) {
      c1 = utolower(ugetxc(&s1));
      c2 = utolower(ugetxc(&s2));

      if ((c1 >= '0') && (c1 <= '9') && (c2 >= '0') && (c2 <= '9')) {
        x1 = ustrtol(s1 - ucwidth(c1), &t1, 10);
        x2 = ustrtol(s2 - ucwidth(c2), &t2, 10);
        if (x1 != x2)
          return x1 - x2;
        else if (t1 - s1 != t2 - s2)
          return (t2 - s2) - (t1 - s1);
        s1 = t1;
        s2 = t2;
      }
      else if (c1 != c2) {
        if (!c1)
          return -1;
        else if (!c2)
          return 1;
        else if (c1 == '.')
          return -1;
        else if (c2 == '.')
          return 1;
        return c1 - c2;
      }

      if (!c1)
        return 0;
    }
  }

  return -1;
}
Beispiel #2
0
/* ustrfilecmp:
  *  ustricmp for filenames: makes sure that eg "foo.bar" comes before
  *  "foo-1.bar", and also that "foo9.bar" comes before "foo10.bar".
  */
static int ustrfilecmp(AL_CONST char *s1, AL_CONST char *s2)
{
    int c1, c2;
    int x1, x2;
    char *t1, *t2;
    
    for(;;)
    {
        c1 = utolower(ugetxc(&s1));
        c2 = utolower(ugetxc(&s2));
        
        if((c1 >= '0') && (c1 <= '9') && (c2 >= '0') && (c2 <= '9'))
        {
            x1 = ustrtol(s1 - ucwidth(c1), &t1, 10);
            x2 = ustrtol(s2 - ucwidth(c2), &t2, 10);
            
            if(x1 != x2)
                return x1 - x2;
            else if(t1 - s1 != t2 - s2)
                return (t2 - s2) - (t1 - s1);
                
            s1 = t1;
            s2 = t2;
        }
        else if(c1 != c2)
        {
            if(!c1)
                return -1;
            else if(!c2)
                return 1;
            else if(c1 == '.')
                return -1;
            else if(c2 == '.')
                return 1;
                
            return c1 - c2;
        }
        
        if(!c1)
            return 0;
    }
}
Beispiel #3
0
/* parse_extension_string:
  *  Parses the extension string, possibly containing attribute characters.
  */
static void parse_extension_string(AL_CONST char *ext)
{
    attrb_state_t state;
    char ext_tokens[32], attrb_char[32];
    char *last, *p, *attrb_p;
    int c, c2, i;
    
    i = 0;
    fext_size = 0;
    fext_p = NULL;
    attrb_p = NULL;
    
    if(!ext)
        return;
        
    fext = ustrdup(ext);
    
    /* Tokenize the extension string and record the pointers to the
      * beginning of each token in a dynamically growing array.
      * ???? We rely on the implementation of ustrtok_r() which writes
      * null characters in the string to delimit the tokens. Yuck.
      */
    c = usetc(ext_tokens, ' ');
    c += usetc(ext_tokens+c, ',');
    c += usetc(ext_tokens+c, ';');
    usetc(ext_tokens+c, 0);
    
    p = ustrtok_r(fext, ext_tokens, &last);
    
    if(p == NULL || !ugetc(p))
        return;
        
    do
    {
        /* Set of attribute characters. */
        if(ugetc(p) == '/')
        {
            attrb_p = p + ucwidth('/');
            continue;
        }
        
        /* Dynamically grow the array if needed. */
        if(i >= fext_size)
        {
            fext_size = (fext_size ? fext_size*2 : 2);
            fext_p = (char **)_al_sane_realloc(fext_p, fext_size * sizeof(char *));
        }
        
        /* Record a pointer to the beginning of the token. */
        fext_p[i++] = p;
        
    }
    while((p = ustrtok_r(NULL, ext_tokens, &last))!=NULL);
    
    /* This is the meaningful size now. */
    fext_size = i;
    
    if(attrb_p)
    {
        state = ATTRB_SET;
        c = usetc(attrb_char, 'r');
        c += usetc(attrb_char+c, 'h');
        c += usetc(attrb_char+c, 's');
        c += usetc(attrb_char+c, 'd');
        c += usetc(attrb_char+c, 'a');
        c += usetc(attrb_char+c, '+');
        c += usetc(attrb_char+c, '-');
        usetc(attrb_char+c, 0);
        
        /* Scan the string. */
        while((c = utolower(ugetx(&attrb_p)))!=0)
        {
            p = attrb_char;
            
            for(i = 0; (c2 = ugetx(&p))!=0; i++)
            {
                if(c == c2)
                {
                    if(i < ATTRB_MAX)
                        attrb_state[i] = state;
                    else
                        state = (i == ATTRB_MAX) ? ATTRB_SET : ATTRB_UNSET;
                        
                    break;
                }
            }
        }
    }
}
Beispiel #4
0
/* fs_flist_putter:
 *  Callback routine for for_each_file() to fill the file selector listbox.
 */
static void fs_flist_putter(AL_CONST char *str, int attrib, int param)
{
   char ext_tokens[32];
   char *s, *ext, *tok, *name;
   char tmp[512], tmp2[32];
   int c, c2, i, k, sign;

   /* attribute flags (rhsda order)
    * 0 = not required, 1 = must be set, -1 = must be unset
    */
   int attr_flag[5+5] = {
      0, -1, -1, 0, 0,
      FA_RDONLY, FA_HIDDEN, FA_SYSTEM, FA_DIREC, FA_ARCH
   };

   c = usetc(ext_tokens, ' ');
   c += usetc(ext_tokens+c, ',');
   c += usetc(ext_tokens+c, ';');
   usetc(ext_tokens+c, 0);

   s = get_filename(str);
   fix_filename_case(s);

   if (fext) {
      ustrcpy(tmp, fext);
      ustrtok(tmp, ext_tokens);
      c = (ustrtok(NULL, ext_tokens) ? 1 : 0);
      if (!c) {
	 if (!ustrchr(fext, '/'))
	    c = 1;
      }

      if (c && (!(attrib & FA_DIREC))) {
	 ustrcpy(tmp, fext);
	 ext = get_extension(s);
	 tok = ustrtok(tmp, ext_tokens);

	 while (tok) {
	    if (ustricmp(ext, tok) == 0)
	       break;

	    tok = ustrtok(NULL, ext_tokens);
	 }

	 if (!tok)
	    return;
      }

      c = usetc(ext_tokens, ' ');
      c += usetc(ext_tokens+c, ',');
      c += usetc(ext_tokens+c, ';');
      c += usetc(ext_tokens+c, '/');
      usetc(ext_tokens+c, 0);

      ustrcpy(tmp, fext);
      tok = ustrchr(tmp, '/');

      if (tok)
	 tok = ustrtok(tok, ext_tokens);

      if (tok) {
	 sign = 1;
	 c = usetc(tmp2, 'r');
	 c += usetc(tmp2+c, 'h');
	 c += usetc(tmp2+c, 's');
	 c += usetc(tmp2+c, 'd');
	 c += usetc(tmp2+c, 'a');
	 c += usetc(tmp2+c, '+');
	 c += usetc(tmp2+c, '-');
	 usetc(tmp2+c, 0);

	 /* scan the string */
	 i = 0;
	 while ((c = utolower(ugetat(tok, i)))) {
	    k = 0;
	    while ((c2 = ugetat(tmp2, k))!=0) {
	       if (c == c2) {
		  if (k<5) {
		     attr_flag[k] = sign;
		     break;
		  }
		  else
		     sign = (k==5) ? 1 : -1;
	       }
	       k++;
	    }
	    i++;
	 }
      }
   }

   /* check if file attributes match */
   if (!(attr_flag[3+5] & attrib)) {
      /* if not a directory, we check all attributes except FA_DIREC */
      for (c=0; c<5; c++) {
	 if (c == 3)
	    continue;
	 if ((attr_flag[c] == 1) && (!(attrib & attr_flag[c+5])))
	    return;
	 if ((attr_flag[c] == -1) && (attrib & attr_flag[c+5]))
	    return;
      }
   }
   else {
      /* if a directory, we check only FA_DIREC */
      if (attr_flag[3] == -1)
	 return;
   }

   if ((flist->size < FLIST_SIZE) && ((ugetc(s) != '.') || (ugetat(s, 1)))) {
      name = malloc(ustrsizez(s) + ((attrib & FA_DIREC) ? ucwidth(OTHER_PATH_SEPARATOR) : 0));
      if (!name)
	 return;

      for (c=0; c<flist->size; c++) {
	 if (ugetat(flist->name[c], -1) == OTHER_PATH_SEPARATOR) {
	    if (attrib & FA_DIREC)
	       if (ustrfilecmp(s, flist->name[c]) < 0)
		  break;
	 }
	 else {
	    if (attrib & FA_DIREC)
	       break;
	    if (ustrfilecmp(s, flist->name[c]) < 0)
	       break;
	 }
      }

      for (c2=flist->size; c2>c; c2--)
	 flist->name[c2] = flist->name[c2-1];

      flist->name[c] = name;
      ustrcpy(flist->name[c], s);

      if (attrib & FA_DIREC)
	 put_backslash(flist->name[c]);

      flist->size++;
   }
}
Beispiel #5
0
int main(int argc, char *argv[])
{
   int c;

   if (install_allegro(SYSTEM_NONE, &errno, atexit) != 0)
      return 1;

   for (c=1; c<argc; c++) {
      if (argv[c][0] == '-') {
	 switch (utolower(argv[c][1])) {

	    case 'a':
	       opt_allegro = TRUE; 
	       break;

	    case 'b':
	       opt_binary = TRUE;
	       break;

	    case 'c':
	       opt_compress = TRUE;
	       break;

	    case 'd':
	       opt_delete = TRUE;
	       break;

	    case 'x':
	       opt_extract = TRUE;
	       break;

	    case '0':
	       if ((opt_password) || (c >= argc-1)) {
		  usage();
		  return 1;
	       }
	       opt_password = argv[++c];
	       break;

	    default:
	       printf("Unknown option '%s'\n", argv[c]);
	       return 1;
	 }
      }
      else {
	 if (!opt_filename)
	    opt_filename = argv[c];
	 else if (!opt_dataname)
	    opt_dataname = argv[c];
	 else {
	    usage();
	    return 1;
	 }
      }
   }

   if ((!opt_filename) || 
       ((opt_allegro) && (opt_binary)) || 
       ((opt_delete) && (opt_extract))) {
      usage();
      return 1;
   }

   if (opt_password)
      packfile_password(opt_password);

   if (opt_delete) {
      if (opt_dataname) {
	 usage();
	 return 1;
      }
      update_file(opt_filename, NULL);
   }
   else if (opt_extract) {
      if (!opt_dataname) {
	 usage();
	 return 1;
      }
      if ((!opt_allegro) && (!opt_binary)) {
	 printf("The -x option must be used together with -a or -b\n");
	 return 1;
      }
      extract_data();
   }
   else {
      if (opt_dataname)
	 update_file(opt_filename, opt_dataname);
      else
	 show_stats();
   }

   return err;
}