Как предотвратить бесконечный цикл, связанный с файлами?

Тема в разделе "LANGS.C", создана пользователем s3dworld, 1 ноя 2011.

  1. s3dworld

    s3dworld Сергей

    Публикаций:
    0
    Регистрация:
    16 мар 2010
    Сообщения:
    387
    Адрес:
    Ртищево
    Всем доброго вечера!

    Долго думал как назвать тему, и ничего лучшего не придумал. Собственно так же думал в каком разделе её создать, решил что лучше всего в этом. Решил для занятия себе хоть чем-то, а заодно и для того чтобы получше научиться работать с процессором, написать свой ассемблер, который, как мне кажется, никогда не будет закончен. Писать решил на C++ и решил писать операционно-независимый код, то есть чтобы можно было с лёгкостью собрать программу и на Windows и на Linux (у меня на одном компе стоит Windows, на другом Debian). По сути вся работа ассемблера сводится к тому, чтобы считывать данные из файла/файлов, работать с данными в памяти и записывать данные в другой файл (выходной файл). Раз кроссплатформенность, то отпадает использование Win32 API (CreateFile(), ReadFile(), WriteFile() и CloseHandle()). Остаётся лишь stdio (fopen(), fread(), fwrite(), fclose()). Но это всё ерунда. Проблему я нашёл вот в чём. Давайте предположим что пользователь (а лучше назвать его программистом) написал некий листинг 00.a:

    Код (Text):
    1. #bit 16
    2. mov EAX,10h
    3. #include "01.a"
    Видим подгрузку листинга 01.a:

    Код (Text):
    1. mov EBX,10h
    2. #include "00.a"
    Всё, так я зациклю программу (а скорее всего она упадёт от нехватки памяти). Как бы Вы мне посоветовали разрешить данную проблему?

    Я уже собирался выстраивать дерево вызовов файлов из файлов, чтобы в памяти каждый файл знал кто его вызвал и если этот файл вызывает тот файл, который вызвал любой из файлов предка этого файла (либо его самого), то давать ошибку ассемблирования. Но тут возник вопрос, а как же я могу сравнить эти файлы. Просто по пути не катит. Так как один и тот же файл может быть вызван как ../00.a и как ../../00.a разными файлами. В общем при множественном #include как предотвратить бесконечный файловый цикл?
     
  2. shchetinin

    shchetinin Member

    Публикаций:
    0
    Регистрация:
    27 май 2011
    Сообщения:
    715
    s3dworld
    вам не надо сравнивать путь . В файле должны быть крестражи вот по ним и ориентироватся надо
    типо
    а ну еще надо будет pragma once суппортить.
     
  3. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    s3dworld
    Нет ничего проще - нужно просто не делать бесконечный файловый цикл.
     
  4. s3dworld

    s3dworld Сергей

    Публикаций:
    0
    Регистрация:
    16 мар 2010
    Сообщения:
    387
    Адрес:
    Ртищево
    shchetinin
    Да, так делает C/С++. Но не видел такого ни в одном ассемблере. Тем более #pragma once для асемблера не нужен.

    _DEN_
    Ну а всё же если сделали.

    Вот смотрите, когда я FASM'у скармливаю 00.asm:

    Код (Text):
    1. mov EAX,10h
    2. include "01.asm"
    01.asm:

    Код (Text):
    1. mov EBX,10h
    2. include "00.asm"
    Он мне тут же возвращает информацию об ошибке, а не фигачит пока не кончится память. Как он это определяет?
     
  5. valentin_p

    valentin_p New Member

    Публикаций:
    0
    Регистрация:
    11 фев 2011
    Сообщения:
    382
    не сразу понял о чем вообще вы спрашиваете. вопрос об "архитектуре" программы: типа "есть куча модулей использующих друг друга и как сделать так что бы грузить каждый только один раз?" Ответ - грузите их один раз. вообще. и используйте для всей программы. а эм.. сравнение по пути - возможно по абсолютному. + если вы хотите просто "сравнить" - ADLER32\CRC...

    > чтобы получше научиться работать с процессором, написать свой ассемблер, который, как мне кажется, никогда не будет закончен. Писать решил на C++ и решил
    < )))))))) работать с процессором - это мануалы. Зачем писать ассемблер? напишите дизассемблер - хоть какая-то польза будет.
     
  6. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    s3dworld

    Сделай как делает студия: у нее есть просто лимит на глубину вложенности инклудов. Там какое-то космическое число по дефолту, но его можно менять через ключик. Предел памяти для вложенных инклудов имеет больший запас, чем здравый смысл. Памяти хватит и на 10000 вложенностей, однако вряд ли даже самый индусский код имеет глубину больше 100.
     
  7. shchetinin

    shchetinin Member

    Публикаций:
    0
    Регистрация:
    27 май 2011
    Сообщения:
    715
    s3dworld
    Ну тогда создать список уже включенных файлов ... соответсвенно есть нет до грузить и добавлять в список если есть то скипать.
     
  8. s3dworld

    s3dworld Сергей

    Публикаций:
    0
    Регистрация:
    16 мар 2010
    Сообщения:
    387
    Адрес:
    Ртищево
    Я не могу понять как мне файлы различать. То что я сую в fopen() ему то всё равно. Например как можно было бы получить полный путь к файлу?
     
  9. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    shchetinin

    Не катит - инклуды могут быть по условию.
     
  10. shchetinin

    shchetinin Member

    Публикаций:
    0
    Регистрация:
    27 май 2011
    Сообщения:
    715
    _DEN_
    А это смотря где этот список хранить если ассоциированно с файлами то все будет норм.

    s3dworld
    А вам и не надо брать полный путь .. так как хватит ..\..\file.asm vs ..\dbg\file.asm
     
  11. s3dworld

    s3dworld Сергей

    Публикаций:
    0
    Регистрация:
    16 мар 2010
    Сообщения:
    387
    Адрес:
    Ртищево
    shchetinin
    Структура:

    C:/ 00 / 01 /
    | | - 01.asm (вызывает "../00.asm")
    |
    | ----- 00.asm (вызывает "01/01.asm")

    И как я определю?
     
  12. s3dworld

    s3dworld Сергей

    Публикаций:
    0
    Регистрация:
    16 мар 2010
    Сообщения:
    387
    Адрес:
    Ртищево
    Не правильно показал. Вот хороший пример.

    E:/Source
    |
    | -------- core
    | |
    | | -------- string.asm
    | |
    | | -------- vector.asm
    |
    | -------- tables
    | |
    | | -------- use.asm
    | |
    | | -------- sys.asm
    |
    | -------- main.asm
    |
    | -------- application.asm
    |
    | -------- error.asm

    Начинается всё с main.asm. main.asm подключается application.asm. application.asm подключает string.asm. string.asm подключает vector.asm. vector.asm подключает use.asm. use.asm подключает sys.asm. А sys.asm подключает string.asm. Получаем:

    1. main.asm
    2. application.asm
    3. string.asm
    4. vector.asm
    5. use.asm
    6. sys.asm
    7. goto 3
    8. Никогда не выполнится

    Вызывается так:

    1. main.asm
    2. application.asm
    3. core/string.asm
    4. vector.asm
    5. ../tables/use.asm
    6. sys.asm
    7. ../core/string.asm (goto 3)
    8. Никогда не выполнится

    И как тут предотвратить?
     
  13. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    s3dworld

    Чем тебе не нравится ограничение на глубину рекурсии как в студии?
     
  14. s3dworld

    s3dworld Сергей

    Публикаций:
    0
    Регистрация:
    16 мар 2010
    Сообщения:
    387
    Адрес:
    Ртищево
    _DEN_
    Считаю это недостойным вариантом (особенно для них).
     
  15. shchetinin

    shchetinin Member

    Публикаций:
    0
    Регистрация:
    27 май 2011
    Сообщения:
    715
    s3dworld
    Так добавляй к относительный путь то и есть сделай выравнивание
    5. ../tables/use.asm
    6. sys.asm

    ../tables/sys.asm.

    Ты же не делаешь смену текущей директории для fopen().
     
  16. shchetinin

    shchetinin Member

    Публикаций:
    0
    Регистрация:
    27 май 2011
    Сообщения:
    715
    _DEN_
    s3dworld
    Рекурсия для инклюдов это фича языка.
     
  17. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    А в чём проблема использовать для проверки абсолютные пути файлов?
     
  18. s3dworld

    s3dworld Сергей

    Публикаций:
    0
    Регистрация:
    16 мар 2010
    Сообщения:
    387
    Адрес:
    Ртищево
    shchetinin
    Кстати, делать буду не через fopen, а через std::fstream. Но это разницы не имеет.

    Booster
    А как мне получить абсолютный путь?
     
  19. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    А чего его получать-то? На крайняк можно самому вычислять по мере обработки. В винде - GetFullPathName
     
  20. s3dworld

    s3dworld Сергей

    Публикаций:
    0
    Регистрация:
    16 мар 2010
    Сообщения:
    387
    Адрес:
    Ртищево
    Booster
    То есть она вернёт путь преобразуя со всеми ../? А для других ОС что тогда?