Files
Sprinter-SDCC/applications/Volkov/tests/p1_platform/p1_dir.c
T
snark13 8e389c03f8 Volkov: добавить Sprinter Commander
Реализовать двухпанельный Commander от платформенного PoC до этапов P6-P20: EMM-каталог, сортировку и выбор, операции с файлами и деревьями, транзакционное копирование, метаданные, политику конфликтов и предварительную проверку свободного места.

Добавить проектную документацию, HDD/MAME-сценарии и проверенные артефакты. Расширить libc операцией bank_write_page, исправлением режима O_RDONLY и связанными регрессионными проверками.
2026-09-10 10:45:30 +03:00

174 lines
5.1 KiB
C

/*
* p1_dir.c — наблюдаемая проверка CURDIR/CHDIR/F_FIRST/F_NEXT.
*
* Тест не меняет файлы. chdir(".") используется только для проверки
* сохранения текущего каталога.
*/
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <dir.h>
#include "p1_platform.h"
#define P1_FIND_ATTRS (FA_RDONLY | FA_HIDDEN | FA_SYSTEM | FA_DIREC | FA_ARCH)
#define P1_FIND_LIMIT 4096u
static char cwd_before[256];
static char cwd_after[256];
static ffblk_t find_buf;
static int scan_pattern(const char *pattern, uint16_t *out_count,
uint8_t *out_dot, uint8_t *out_dotdot)
{
uint16_t count = 0;
uint8_t dot = 0;
uint8_t dotdot = 0;
int rc;
int end_errno;
errno = 0;
rc = ffirst(pattern, &find_buf, P1_FIND_ATTRS);
if (rc != 0) {
if (errno == ENOENT) {
printf("Pattern %-4s: empty (ffirst errno=%d)\n", pattern, errno);
*out_count = 0;
*out_dot = 0;
*out_dotdot = 0;
return 0;
}
printf("ffirst(%s) failed: errno=%d\n", pattern, errno);
return -1;
}
for (;;) {
if (strcmp(find_buf.found_name, ".") == 0) dot = 1;
if (strcmp(find_buf.found_name, "..") == 0) dotdot = 1;
if (count < 20) {
printf(" %02X %10lu %04X/%04X %s\n",
(unsigned)find_buf.found_attr,
(unsigned long)find_buf.size,
(unsigned)find_buf.date,
(unsigned)find_buf.time,
find_buf.found_name);
}
count++;
if (count >= P1_FIND_LIMIT) {
puts("Enumeration limit reached: possible F_NEXT loop.");
return -1;
}
errno = 0;
if (fnext(&find_buf) != 0) break;
}
end_errno = errno;
printf("Pattern %-4s: count=%u dot=%u dotdot=%u end_errno=%d\n",
pattern, (unsigned)count, (unsigned)dot, (unsigned)dotdot,
end_errno);
/* MAME 0.287 / BIOS 3.06 подтвердил ENOENT (3) для конца F_NEXT.
* Код 0x0F из старого описания DSS здесь не является штатным. */
if (end_errno != ENOENT) {
puts("Unexpected F_NEXT termination code.");
return -1;
}
*out_count = count;
*out_dot = dot;
*out_dotdot = dotdot;
return 0;
}
int p1_test_directory(void)
{
uint16_t count_star_dot;
uint16_t count_star;
uint8_t dot1, dotdot1, dot2, dotdot2;
int failed = 0;
p1_heading("Directory: CURDIR, CHDIR, F_FIRST/F_NEXT");
errno = 0;
if (getcwd(cwd_before, sizeof(cwd_before)) == 0) {
printf("getcwd failed: errno=%d\n", errno);
return -1;
}
printf("CWD before: %s\n", cwd_before);
if (chdir(".") != 0) {
printf("chdir(.) failed: errno=%d\n", errno);
failed++;
}
if (getcwd(cwd_after, sizeof(cwd_after)) == 0) {
printf("second getcwd failed: errno=%d\n", errno);
return -1;
}
printf("CWD after : %s\n", cwd_after);
if (strcmp(cwd_before, cwd_after) != 0) {
puts("CWD changed after chdir(.).");
failed++;
}
puts("\nFirst entries for *.*:");
if (scan_pattern("*.*", &count_star_dot, &dot1, &dotdot1) != 0) {
failed++;
}
puts("\nFirst entries for *:");
if (scan_pattern("*", &count_star, &dot2, &dotdot2) != 0) {
failed++;
}
if (count_star != count_star_dot) {
printf("NOTE: * count (%u) differs from *.* count (%u).\n",
(unsigned)count_star, (unsigned)count_star_dot);
}
if (dot1 != dot2 || dotdot1 != dotdot2) {
puts("NOTE: dot entries differ between patterns.");
}
printf("Directory checks failed: %u\n", (unsigned)failed);
return failed ? -1 : 0;
}
int p1_test_disk_info(void)
{
P1DiskInfo info;
uint32_t cluster_bytes;
uint32_t total_bytes;
uint32_t free_bytes;
p1_heading("DSKINFO: current disk");
errno = 0;
if (p1_disk_info(0xFF, &info) != 0) {
printf("DSKINFO failed: errno=%d\n", errno);
return -1;
}
cluster_bytes = (uint32_t)info.sectors_per_cluster *
(uint32_t)info.bytes_per_sector;
total_bytes = cluster_bytes * (uint32_t)info.total_clusters;
free_bytes = cluster_bytes * (uint32_t)info.free_clusters;
printf("Sectors/cluster : %u\n", (unsigned)info.sectors_per_cluster);
printf("Bytes/sector : %u\n", (unsigned)info.bytes_per_sector);
printf("Total clusters : %u\n", (unsigned)info.total_clusters);
printf("Free clusters : %u\n", (unsigned)info.free_clusters);
printf("Cluster bytes : %lu\n", (unsigned long)cluster_bytes);
printf("Total bytes : %lu\n", (unsigned long)total_bytes);
printf("Free bytes : %lu\n", (unsigned long)free_bytes);
if (info.sectors_per_cluster == 0 || info.bytes_per_sector == 0 ||
info.total_clusters == 0 || info.free_clusters > info.total_clusters) {
puts("DSKINFO returned inconsistent values.");
return -1;
}
return 0;
}