clean up directory entries

This commit is contained in:
Erik Osheim 2024-09-20 10:57:03 -04:00
parent 7fcd7ad635
commit 1998e6cccc
1 changed files with 54 additions and 40 deletions

View File

@ -76,26 +76,62 @@ reset(UxnFile *c)
} }
static Uint16 static Uint16
get_entry(char *p, Uint16 len, const char *pathname, const char *basename, int fail_nonzero) stat_fill(Uint16 addr, Uint16 len, char c)
{ {
struct stat st; Uint16 i;
if(len < strlen(basename) + 8) for (i = 0; i < len; i++)
return 0; uxn.ram[(addr + i) & 0xffff] = c;
if(stat(pathname, &st)) return len;
return fail_nonzero ? snprintf(p, len, "!!!! %s\n", basename) : 0;
else if(S_ISDIR(st.st_mode))
return snprintf(p, len, "---- %s/\n", basename);
else if(st.st_size < 0x10000)
return snprintf(p, len, "%04x %s\n", (unsigned int)st.st_size, basename);
else
return snprintf(p, len, "???? %s\n", basename);
} }
static Uint16 static Uint16
file_read_dir(UxnFile *c, char *dest, Uint16 len) stat_size(Uint16 addr, Uint16 len, off_t size)
{
Uint16 i;
for (i = 1; i <= len; i++) {
char c = '0' + (Uint8)(size & 0xf);
uxn.ram[(addr + len - i) & 0xffff] = c;
size = size >> 4;
}
if (size > 0)
stat_fill(addr, len, '?');
return len;
}
static Uint16
stat_entry(Uint16 addr, char sym, off_t size, const char *s)
{
Uint16 pos = addr;
pos += sym ? stat_fill(pos, 4, sym) : stat_size(pos, 4, size);
uxn.ram[(pos++) & 0xffff] = ' ';
while(*s)
uxn.ram[(pos++) & 0xffff] = *(s++);
uxn.ram[(pos++) & 0xffff] = '\n';
/* like printf and friends, we don't count the trailing null */
uxn.ram[pos & 0xffff] = '\0';
return pos - addr;
}
static Uint16
get_entry(Uint16 addr, Uint16 len, const char *pathname, const char *basename)
{
struct stat st;
if(len < strlen(basename) + 8) return 0;
char sym = 0;
off_t size = 0;
if(stat(pathname, &st)) sym = '!';
else if(S_ISDIR(st.st_mode)) sym = '-';
else if(st.st_size >= 0x10000) sym = '?';
else size = st.st_size;
return stat_entry(addr, sym, size, basename);
}
static Uint16
file_read_dir(UxnFile *c, Uint16 addr, Uint16 len)
{ {
static char pathname[4352]; static char pathname[4352];
char *p = dest; Uint16 pos = addr;
char cwd[PATH_MAX] = {'\0'}, *t;
if(c->de == NULL) c->de = readdir(c->dir); if(c->de == NULL) c->de = readdir(c->dir);
for(; c->de != NULL; c->de = readdir(c->dir)) { for(; c->de != NULL; c->de = readdir(c->dir)) {
Uint16 n; Uint16 n;
@ -103,7 +139,6 @@ file_read_dir(UxnFile *c, char *dest, Uint16 len)
continue; continue;
if(strcmp(c->de->d_name, "..") == 0) { if(strcmp(c->de->d_name, "..") == 0) {
/* hide "sandbox/.." */ /* hide "sandbox/.." */
char cwd[PATH_MAX] = {'\0'}, *t;
/* Note there's [currently] no way of chdir()ing from uxn, so $PWD /* Note there's [currently] no way of chdir()ing from uxn, so $PWD
* is always the sandbox top level. */ * is always the sandbox top level. */
getcwd(cwd, sizeof(cwd)); getcwd(cwd, sizeof(cwd));
@ -119,12 +154,12 @@ file_read_dir(UxnFile *c, char *dest, Uint16 len)
snprintf(pathname, sizeof(pathname), "%s/%s", c->current_filename, c->de->d_name); snprintf(pathname, sizeof(pathname), "%s/%s", c->current_filename, c->de->d_name);
else else
pathname[0] = '\0'; pathname[0] = '\0';
n = get_entry(p, len, pathname, c->de->d_name, 1); n = get_entry(pos, len, pathname, c->de->d_name);
if(!n) break; if(!n) break;
p += n; pos += n;
len -= n; len -= n;
} }
return p - dest; return pos - addr;
} }
static char * static char *
@ -221,7 +256,7 @@ file_read(UxnFile *c, Uint16 addr, int len)
if(c->state == FILE_READ) if(c->state == FILE_READ)
return file_read_file(addr, len, c->f); return file_read_file(addr, len, c->f);
if(c->state == DIR_READ) if(c->state == DIR_READ)
return file_read_dir(c, (char *)&uxn.ram[addr], len); return file_read_dir(c, addr, len);
return 0; return 0;
} }
@ -293,27 +328,6 @@ file_write(UxnFile *c, Uint16 addr, Uint16 len, Uint8 flags)
return ret; return ret;
} }
static Uint16
stat_fill(Uint16 addr, Uint16 len, char c)
{
Uint16 i;
for (i = 0; i < len; i++)
uxn.ram[(addr + i) & 0xffff] = c;
return len;
}
static Uint16
stat_size(Uint16 addr, Uint16 len, off_t size)
{
Uint16 i;
for (i = 1; i <= len; i++) {
char c = '0' + (Uint8)(size & 0xf);
uxn.ram[(addr + len - i) & 0xffff] = c;
size = size >> 4;
}
return size == 0 ? len : stat_fill(addr, len, '?');
}
static Uint16 static Uint16
file_stat(UxnFile *c, Uint16 addr, Uint16 len) file_stat(UxnFile *c, Uint16 addr, Uint16 len)
{ {