AntKrotov / oberon-07-compiler

Oberon-07 compiler for x64 (Windows, Linux), x86 (Windows, Linux, KolibriOS), MSP430x{1,2}xx, STM32 Cortex-M3
BSD 2-Clause "Simplified" License
61 stars 5 forks source link

Ошибка при записи файла Linux #20

Open prospero78 opened 1 year ago

prospero78 commented 1 year ago
PROCEDURE FileWrite():BOOLEAN;
    VAR
        strAdr: INTEGER;
        res: INTEGER;
        ind: INTEGER;
    BEGIN
        isErr:=FALSE;
        strToWrite:="Проверка текста";
        strAdr:=SYSTEM.ADR(strToWrite[0]);
        res:=File.Write(fileID, strAdr, SYSTEM.SIZE(WCHAR));
        IF res # 0 THEN
            Out.String("Main.FileWrite(): bad write file"); Out.Ln();
            isErr:=TRUE;
        END;
        RETURN isErr
    END FileWrite;

Что-то идёт не так. Даже одну литеру записать не могу.

AntKrotov commented 1 year ago

Функция File.Write возвращает количество байт, которые были записаны. Поэтому проверка

    IF res # 0 THEN
    (* ошибка записи *)
    END;

здесь будет неправильна. Надо сравнить res не с нулем, а с размером данных, которые должны быть записаны.

prospero78 commented 1 year ago

Антон, ну вот очень плохо, что нет вообще никаких в коде комментариев. И реквесты ты толком не принимаешь.

З.Ы. Подправил код, бесполезно. Я в печали.

AntKrotov commented 1 year ago

Не знаю, в чем может быть проблема. У меня такой код работает:

MODULE test;

IMPORT SYSTEM, File, Out;

VAR
    fileID: INTEGER;

PROCEDURE FileWrite(fileID: INTEGER):BOOLEAN;
    VAR
        strAdr: INTEGER;
        res: INTEGER;
        ind: INTEGER;
        dataSize: INTEGER;
        isErr: BOOLEAN;
        strToWrite: ARRAY 64 OF CHAR;
    BEGIN
        isErr:=FALSE;
        strToWrite:="Проверка текста";
        dataSize := LENGTH(strToWrite)*SYSTEM.SIZE(CHAR);
        strAdr:=SYSTEM.ADR(strToWrite[0]);
        res:=File.Write(fileID, strAdr, dataSize);
        IF res # dataSize THEN
            Out.String("Main.FileWrite(): bad write file"); Out.Ln();
            isErr:=TRUE;
        END;
        RETURN isErr
    END FileWrite;

BEGIN
    fileID := File.Create("/home/live/test.txt");
    IF FileWrite(fileID) THEN
    (* error *)
    END;
    File.Close(fileID)
END test.

Я только заменил ARRAY OF WCHAR на ARRAY OF CHAR и SYSTEM.SIZE(WCHAR) на SYSTEM.SIZE(CHAR), чтобы текст был записан в естественной для Linux кодировке UTF8 (иначе будет UCS-2) для удобного просмотра в простом редакторе. Ну и конечно следует подставить нормальное имя файла, вместо "/home/live/test.txt".

prospero78 commented 1 year ago

Хм. Ок, посмотрю. На счёт WCHAR и CHAR -- важное замечание. Если я правильно понял, то ошибки ОС не возвращаются. Опасненько.

AntKrotov commented 1 year ago

Модуль File - это просто обертка над libc. В основном, функции этого модуля возвращают то же, что и соответствующие функции libc. Да, и напомню, что файл с исходным кодом тоже надо сохранять в UTF8 (и лучше с BOM).