Школоло / Говнокод #8744 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33
  34. 34
  35. 35
  36. 36
  37. 37
  38. 38
  39. 39
  40. 40
  41. 41
  42. 42
  43. 43
  44. 44
  45. 45
  46. 46
  47. 47
  48. 48
  49. 49
  50. 50
  51. 51
  52. 52
  53. 53
  54. 54
  55. 55
  56. 56
  57. 57
  58. 58
  59. 59
  60. 60
  61. 61
  62. 62
  63. 63
  64. 64
  65. 65
  66. 66
  67. 67
  68. 68
  69. 69
  70. 70
  71. 71
  72. 72
  73. 73
  74. 74
  75. 75
  76. 76
  77. 77
  78. 78
  79. 79
  80. 80
  81. 81
  82. 82
  83. 83
  84. 84
  85. 85
  86. 86
  87. 87
  88. 88
  89. 89
  90. 90
  91. 91
procedure _FinalizeArray(p: Pointer; typeInfo: Pointer; elemCount: Cardinal);
asm
        CMP     ECX, 0                        { no array -> nop }
        JE      @@zerolength

        PUSH    EAX
        PUSH    EBX
        PUSH    ESI
        PUSH    EDI
        MOV     EBX,EAX
        MOV     ESI,EDX
        MOV     EDI,ECX

        XOR     EDX,EDX
        MOV     AL,[ESI]
        MOV     DL,[ESI+1]

        CMP     AL,tkLString
        JE      @@LString

        CMP     AL,tkWString
        JE      @@WString

        CMP     AL,tkVariant
        JE      @@Variant

        CMP     AL,tkArray
        JE      @@Array

        CMP     AL,tkRecord
        JE      @@Record

        CMP     AL,tkInterface
        JE      @@Interface

        CMP     AL,tkDynArray
        JE      @@DynArray

        JMP     @@error

@@LString:
        CMP     ECX,1
        MOV     EAX,EBX
        JG      @@LStringArray
        CALL    _LStrClr
        JMP     @@exit
@@LStringArray:
        MOV     EDX,ECX
        CALL    _LStrArrayClr
        JMP     @@exit

@@WString:
        CMP     ECX,1
        MOV     EAX,EBX
        JG      @@WStringArray
        CALL    _WStrClr
        JMP     @@exit
@@WStringArray:
        MOV     EDX,ECX
        CALL    _WStrArrayClr
        JMP     @@exit
@@Variant:
        MOV     EAX,EBX
        ADD     EBX,16
        CALL    _VarClr
        DEC     EDI
        JG      @@Variant
        JMP     @@exit
@@Array:
        PUSH    EBP
        MOV     EBP,EDX
@@ArrayLoop:
        MOV     EDX,[ESI+EBP+2+8]
        MOV     EAX,EBX
        ADD     EBX,[ESI+EBP+2]
        MOV     ECX,[ESI+EBP+2+4]
        MOV     EDX,[EDX]
        CALL    _FinalizeArray
        DEC     EDI
        JG      @@ArrayLoop
        POP     EBP
        JMP     @@exit

@@Record:
        PUSH    EBP
        MOV     EBP,EDX
@@RecordLoop:
        { inv: EDI = number of array elements to finalize }

        MOV     EAX,EBX
        ADD     EBX,[ESI+EBP+2]

Это так в дельфах автофинализация строк, длиннострок, вариантов, массивов, записей, интерфейсов, динмассивов реализована.
Вместо того, чтобы напрямую вызвать деструктор, там в рантайме (ПИЗДЕЦ, В РАНТАЙМЕ БЛЯТЬ!!!) проверяется тип поля, требующего финализацию и через три таких жопы наконец-то вызывается деструктор. И это, блять, я ещё создал свой TInterfacedObject, потому что иначе бы деструктор вызывался не через три жопы, а через четыре, и одна из них - системный вызов.
Да, это при включённой оптимизации всё, если чё.

Запостил: TarasB TarasB, (Updated )

Комментарии (116) RSS

  • Говнокод из 91 строки на асме.
    ТБ, ты занимаешься нечестивым блудом
    Ответить
    • Хорошо, смотри на цепочку из CMP... JE...
      Сразу вызвать метод по указателю слабо, видимо, надо прокрутить все варианты обязательно.
      Ответить
      • какой вжопу метод по указателю? строки в делфи объектами не являются.
        И методов не имеют.
        Прежде чем гневно высирать кирпичи, изучите матчасть.
        Ответить
        • Тролль?
          То, что строки формально не являются классами, не означает, что их нельзя на уровне той части компилятора, что отвечает за автодеструкторы, представлять как классы с методами.
          Ответить
            • В данном случае все поняли мыслю, нет блять надо доебаться, что строка в дельфях это не класс, и что у классов нет автодеструкторов. Тут все учёные, к словам цепляться незачем.
              Ответить
              • Это не доебка до слов, это суть.
                Объекты автоматически не разрушаются и не финализируются.
                Финализируются только те типы, которые перечислены в сабже, все они никакого отношения к классам не имеют, они не реализованы через классы, более того - далеко не все являются даже ссылочными.
                Ответить
                • Ну ты пиздец.
                  Тут и без тебя все знают про строки и интерфейсы, понимаешь? Мой пост про "сразу без перебора вызвать метод по указателю" сводится к тому, что вместо того, чтобы записывать информацию о типе переменной (строка это или интерфейс) можно сразу записать указатель на процедуру, которая корректно финализирует эту переменную (т.е. процедуру, принимающую один указатель), и сразу её вызвать, без перебора. А ещё лучше вообще вызвать деструктор напрямую, без указателя, это вполне реально. Собсна все поняли, что я сказал, до тебя теперь тоже дошло?
                  Ответить
                  • Пиздец - это ты. Хамло потому что.
                    Иди нахуй. Ничего не буду тебе объяснять, если тупой.
                    Ебись сам.

                    Y_F
                    Ответить
                    • охлол
                      и минус нажать не забыл ^^
                      Ты производишь впечатление человека, который хорошо знает формально, что что делает, но не умеет врубаться в суть. Тут таких не любят.
                      Ответить
                      • > охлол
                        Тебе сколько лет, ребенок?

                        > ^^
                        блондинка?

                        > Ты производишь впечатление человека, который хорошо знает формально, что что делает, но не умеет врубаться в суть.
                        Взаимоисключающие параграфы.
                        > Тут таких не любят.
                        Тут это где? Не любят? Кто не любят? Говори за себя.
                        Ответить
                        • Теперь слушай. По поводу замечания, что строка в дельфях синтаксически не является классом. Так вот, мне похуй на синтаксис. Семантически строка - это самый настоящий класс, а процедура _LStrArrayClr - это блять самый что ни на есть метод этого самого что ни на есть класса. Да-да, мой юный друг, даже если ты просто опишешь структуру (record) и несколько процедур, делающих операции над этой структурой, то ты на самом деле описал класс и несколько методов. Если ты перенёс структуру в интерфейс, не забыв дописать процедуру, вызываемую при выходе этого интерфейса из зоны видимости - то ты этим реализовал самый настоящий класс с автодеструктором, потому что семантически это и есть самый настоящий класс. И когда мы говорим о семантике, то синтаксис нас должен волновать не больше, чем проблемы негров волнуют шерифа в колхозе в центре Техаса. Поэтому твои выкрики про то, что "строка - не класс" звучат как выкрики с места особо наглого школьника, считающего себя умнее учителя, знаешь, в каждом классе есть такой придурок, над которым все смеются, слышая его вопросы и самоуверенный тон, когда он поправляет учителя не по делу.
                          Я понимаю, что на твоём этапе развития важнее козырнуть очень ценными знаниями про синтаксис дельфей, но поверь мне, тут все это сто лет знают, все этот этап уже прошли и поэтому твой комментарий тут попросту не в тему.
                          Ответить
                          • Поддержу Тараса. Новички очень скрупулёзно относятся к терминам. Услышали краем уха новое слово, и повторяют его определение из учебника направо и налево, чтобы умными казаться. Не вижу причин, чтобы не употреблять слова вроде объект/метод/финализация объекта хотя бы просто фигурально/в широком смысле.
                            Ответить
                            • тащем-то тамошние строки это обычный структурированный тип, обвешанный managed магией
                              Ответить
    • Ошибка деления на огурец. Переустановите вселенную и перезагрузитесь.
      Ответить
    • В этом месте должен набижать DimonSoft и начать рассказывать, как в Дельфи всё распиздато и продумано и спросить, а сколько компиляторов написал я.
      Ответить
        • На Мат-Мехе.
          На отделении чистой математики - точно нет.
          На математическом обеспечении - может быть.
          Я сейчас книгу дракона медленно читаю, если что.
          Ответить
  • О, Тарас. Я тоже удивлен что ты ругаешь дэлфи.
    Переходи уж на Спп, пооптимизируешь 🙂
    Ответить
    • Кстати, в крестах кокомпилятором тоже нехилое такое говно из-за исключений вырабатывается.
      Но там всё сводится к массиву указателей на деструкторы, тут всё-таки чуть говнистее.
      Ответить
      • что плохого в том, чтобы по мере создания объектов наполнять отдельный массив/стек указателями на деструкторы, и по мере умирания этих объектов аккуратно подчищать массив, но при исключении - вызвать все деструкторы с конца до нужной точки
        как бы ты это улучшил?
        Ответить
        • Да никак, это всё из-за исключений, тут лучше не сделать.
          Просто это показывает то, что тезис про "мы не платимза то, что не используем" - пиздёж.
          Ответить
          • каждый делает выбор сам, С++ даёт много вариантов
            либо очень много геморроя, но всё без исключений
            либо геморроя сильно меньше, но не без него - экономим на исключениях в своем собственном коде (каждый раз рекомендуем компилятору, что мы считаем наш код не генерящим исключения, а он думает соглашаться или нет)
            либо никакого геморроя и забиваем на лишние 10-20 инструкций по сохранению указателей деструкторов - сколько там на самом деле, кстати?
            думаю, что исключения - далеко не самое узкое горлышко при работе обычной программы, и их + перевешивают -
            Ответить
        • В gcc вроде бы ничего никуда не сохраняется. Вроде как он составляет фрагменты кода, которые занимаются раскруткой стека, и рантайм вызывает нужные куски, согласно позиции, где произошло исключение.

          P.S. конечно я могу ошибаться
          Ответить
            • Не совсем:
              int test(int n)
              {
                  vector<int> v;
                  if (n > 2) throw exception();
                  return v.size();
              }


              Вот такой код оно генерит:
              http://pastebin.com/drDhybL7

              А вот та самая табличка, по которой принимается решение, куда перейдет управление при возникновении экцепшена:
              http://pastebin.com/8U8p5HEE

              Как я понимаю там тупо прописаны диапазоны кода в которых произошел экцепшн и точка в которую при этом прыгать. Т.е. в нашем случае - если экцепшен вылетел начиная с .LEHB1 по .LEHE1 то прыгаем на .L5.

              Так что по идее нормальный путь ничего не платит за поддержку исключений.
              Ответить
              • То есть в обработчике исключения проверяется адрес и в зависимости от него вызываются деструкторы?
                Интересненько...
                Ответить
                • Ну походу да. Кстати landing-pad'ы для catch скорее всего реализованы тем же способом.
                  Ответить
                • try
                  {
                      test(argc);
                  }
                  catch (exception &e)
                  {
                       cout << "Exception!" << endl;
                  }


                  Вот код, в который компилируется catch (.L12):
                  http://pastebin.com/SnU3c5QZ

                  Здесь видно проверку типа исключения (cmp edx, 1) и собственно обработку.
                  Ответить
    • Ну у Тараса угроза "я отправлю твой кот на гамнокот" стандартная, чем он собственно и занимается пеарит гамнокот на гейдеве, а заодно мстит своим "обидчикам"
      Ответить
      • может быть причина в том, что гейдев.ру и код, отчаянно похожий на говно - как неразлучные братья?
        Ответить
      • > Ну у Тараса угроза "я отправлю твой кот на гамнокот" стандартная

        Исключительно в шутку.

        > чем он собственно и занимается

        Примеры, ссылки.

        > занимается пеарит гамнокот на гейдеве

        Примеры, ссылки

        > а заодно мстит своим "обидчикам"

        Примеры, ссылки
        Ответить
  • дежурное дерьмо из потрохов VCL. кого это еще удивляет? и как если бы это самым говнистым местом было.
    Ответить
  • Вот крестушок сраный. Как не стыдно святую Дельфи ругать?
    Ответить
    • Это слово ещё не стало употребимым, было только на грушечке - вывод - ты с гдрушечки.
      Ответить
      • Да ты латентная крестаблядь! Чё на дельфи без оснований гонишь?
        Ответить
        • За такие серьёзные обвинения, сударь, канделябром по голове бьют.
          Ответить
          • Наконец, сам дошёл, что нечего так серьёзно обвинять дельфи без причин. А то я щас каднделябр то принесу. Крестушок, не шали больше.
            Ответить
  • дааа

    космические корабли бороздят, а тарас все над компилятором дельфей смеется.
    Ответить
    • тарас, шол бы ты си учить или жабу или шарпы на худой конец
      хватит лысого на мертвый язык гонять
      Ответить
      • он дрочет терь на другой мертвый йазык - йазык ада
        Ответить
        • Если б ты видел, какой красивый код на Аде, ты бы тоже на этот код дрочил.
          Ответить
            • Да ты не врубаешься.
              Просто у любого адского кода читабельность абсолютная, я когда исходники библиотек посмотрел, то охренел просто. Сравни с крестоисходниками микрософта.
              Особенно круто, когда вся логика зашита в разделе описания переменных.
              .
                 function Lorenze (ml: TLine_Pos; ep, ev: TPoint) return TPoint is
                    r  : constant TPoint := ep-ml.p;
                    l  : constant f80    := Length (r);
                    f  : constant TPoint := (ml.n*(l**2) - 3.0*(ml.n*r)*r)/(l**5);
                 begin
                    return ev**f;
                 end;

              Вот бы ещё модификатор const был по умолчанию (а mutable - наоборот)!
              Ответить
              • Эквивалентный код на Scala:
                def lorenze(ml: LinePos, ep: Point, ev: Point): Point = {
                  val r = ep - ml.p
                  val l = r.length
                  val f = (ml.n * (l ** 2) - 3.0 * (ml.n * r) * r) / (l ** 5)
                  ev ** f
                }
                val - это как const. Вывод типов автоматический. Минимум лишних слов и значков.
                Ответить
                • Да, вывода типов не хватает.
                  Слово val - ну почему константность не по умолчанию?
                  Ну и названия типов в заголовке - зачем? Не лучше ли, чтобы тип результата сам определялся, и чтобы конкретные типы подставлялись компилятором только в месте вызова функции, чтобы она работала для любых типов, над которыми определены эти операции?
                  Т.е. хотелось бы так:
                  lorenze := func(ml,ep,ev) {
                    r := ep - ml.p
                    l := r.length
                    f := (ml.n * (l ** 2) - 3.0 * (ml.n * r) * r) / (l ** 5)
                    ev ** f
                  }
                  Ответить
                  • > Ну и названия типов в заголовке - зачем? Не лучше ли, чтобы тип результата сам определялся
                    В ООП системах почему-то сложно реализовать такие сложные выводы типов.
                    Так может Haskell, но про ООП там нужно забыть. Там вообще типы редко нужно указывать, он сам будет выводить наиболее общие возможные типы аргументов и возврощаемого значения. И всё из коробки lazy и immutable.
                    Ответить
                    • В ООП, когда возникает неясность, имею ли я в виду сам класс или наследника, надо заставлять указывать.
                      Хаскелл прикольный, но кусорт на нём выглядит как полное говно (я про нормальный кусорт, а не про позерский).
                      И хочется ещё эффективности. Ада, если верить шутауту, её обеспечивает (хотя по асмокоду смотрю - какой-то пиздец там происходит, да ещё и гццшный асм затрудняет понимание), а Хаскелл?
                      И типизацию бы постатичнее. Хотя, с другой стороны, хотелось бы иметь возможность в рантайме заводить процедуры с сигнатурами, не известными при компиляции (чтобы проверка и компиляция происходила по ходу выполнения), чтобы компиляторы на таком языке записывались в наиболее естественной форме.
                      Ответить
                      • Да, Haskell по производительности иногда может сливать в 2-3 раза. Код стабильно получается короче во столько же раз. Читать его порой трудно, это да. Благо его мало.
                        http://shootout.alioth.debian.org/u32/benchmark.php?test=all&lang=gnat&lang2=g hc
                        давайте попинаем Страйко чтобы он наконец сделал нормальную поддержку ссылок
                        Ответить
                        • Да, я вижу. Только странно, компилятор низкоуровневой части одинаковый (gcc), разнице взяться не с чего. Ну разве что со стековой аллокации, которая в Аде родная.
                          Ответить
                  • т.е. на Haskell можно так:
                    lorenze ml ep ev = len r  = ep - (p ml)
                                           l  = length r
                                           nm = n ml
                                           f  = (nm * (l ** 2) - 3.0 * nm * r * r) / (l ** 5)
                                       in ev ** f
                    И будет const и мощный вывод типов.
                    Ответить
                  • > Слово val - ну почему константность не по умолчанию
                    кстати, тут просто нет понятия по-умолчанию. Таков синтаксис определений.
                    val a = "A" // определить константу
                    var b = "B" // определить переменную
                    lazy val с = someLongCalculation() // определить "ленивую" константу
                    Причём создатели языка призывают всячески избегать var
                    Ответить
                    • Это мне тоже не по нраву, потому что объявление занимает больше символов, чем изменение, то есть язык подталкивает к мутабельности.
                      Надо наоборот.
                      То есть
                      b := c+4; // определение константы
                      mut a := b+c; // определение переменной
                      chg a := a+1; // изменение


                      Либо ололо, := для определения, а просто = для изменения.
                      Правда, тогда неясен для lvalue кортежей:
                      mut a :=1;
                      (chg a, b) := GetMousePosition()
                      Так как изменение зашито не в значке, который общий для всех, а в префиксе, который индивидуален для элемента кортежа.
                      Ну не (a=,b:=)GetMousePosition() же писать?
                      Ответить
                • > пидор
                  > Чтоб тебя в жопу выебли
                  я думаю, что если он пидор, то ему это только за счастье
                  Ответить
                    • Зря ты так горячишься, радоваться надо.
                      К тому же часто +/- не по содержимому поста, а по юзернейму.
                      Ответить
                      • Да я в курсе про тайный легион стадных долбоёбов. Я хочу отправить его в биореактор.
                        Ответить
            • for I in Results'Range loop
              ....
                 end loop;
              
                    if Depth > 0 then
              ...
                    else
              ...
                    end if;
              
                 function Create
              ....
                 is
                 begin
                    return Create_Ex
                      (...);
                 end Create;

              А потом еще говорят, что у бейсика код плохой.

              Впрочем весьма читабельный язык.
              Кстати, вопрос к Тарасу - with - это импорт какой-то?
              И какой аналог паскалёвского with в аде?
              Ответить
              • with - это как uses из Паскаля
                А use - это как using namespace из C++

                В Аде если ты подключил модуль, то его содержимое напрямую не видно, видно только через имя модуля и точку, а вот use открывает видимость.
                Ответить
                • В clojure такая же фишка есть для работы с нэймспэйсами
                  (:require module) - сделать NS доступным
                  (:use module) - импортировать содержимое NS в область видимости

                  Полезная фича, да. А псевдонимы можно модулям назначать?
                  Ответить
                  • Мне вот это понравилось.
                    if Depth > 0 then
                    	Result.all := (Left => Create (Pool, 2 * Item - 1, Depth - 1),
                                           Right => Create (Pool, 2 * Item, Depth - 1),
                                           Value => Item);
                    else
                    	Result.all := (Left | Right => null, 
                             Value => Item);
                    end if;
                    return Result;

                    правда я не совсем въехал.
                    Ответить
                    • Это агрегаты такие.
                      То есть вместо
                      p.x:=1.0;
                      p.y:=2.0;
                      можно не писать лишнее и сразу
                      p:=(x=>1.0,y=>2.0);

                      Result.all - это так в Аде разыменовываются указатели.

                      Кстати, в стандарте 2012 можно написать
                      return(if Depth > 0 then
                      	(Left => Create (Pool, 2 * Item - 1, Depth - 1),
                                             Right => Create (Pool, 2 * Item, Depth - 1),
                                             Value => Item);
                      else
                      	(Left | Right => null, 
                               Value => Item));


                      Left|Right=>null - это сразу два поля инициализируем нулевым указателем.
                      Ещё есть
                      x=> <>
                      символ <> означает что-то типа "пофиг" или "по умолчанию".

                      Ещё есть
                      others=>1.0
                      Это значит, "все остальные поля задать равными единице". Для инициализации массивов применяется, например. Только жаль, что нельзя параметризовываться индексом, типа так:
                      others i=>i*2
                      Ответить
                      • Ещё раз встретил идею, что структуры - это просто мапы с фиксированными ключами. Раньше встречал её только в лиспе 🙂
                        Ответить
                        • Ну это только выглядит так.
                          А мапы в Аде сделаны уже средствами языка
                          И выглядят так:
                          i := M.GetElement("Key")
                          Короче, тупо класс такой, ну ты понял.
                          А чтобы объявить мапу, надо подключать модуль, определять функции Hash и EqualKeys, параметризовать модуль, и объявлять как
                          M: MyCoolPackage.Map;
                          Короче, возня та ещё.

                          Но это ладно, вполне оправдано, потому что у карт может быть слишком много разных реализаций, чтобы встраивать их в универсальный язык. Вот обидно, что динмассивы в язык не встроены, то есть которые могут менять свою длину, у них-то свободы в реализации мало. В языке же дохрена фич заточено под массивы, вообще массивы в Аде - это что-то такое сверхважное, как списки в Лиспе, а динмассив почему-то не сделали. Да и чтобы этот динмассив при резервировании места не вызывал конструкторы для всех объектов - такое сделать средствами языка дико геморно, а если вшить, то будет как родное.
                          Ответить
                      • >Это агрегаты такие.
                        Во. Это ж об чем я и спрашивал выше насичот with.

                        >Кстати, в стандарте 2012 можно написать
                        Идея, когда if-then да и всё прочее тоже возвращает значение мне всегда была близка.
                        Или это тернарник такой?
                        Ответить
                        • Нет, это тернарник.
                          Ещё есть эн-арник, то есть case с возвратом значения.
                          А with не имеет паскального смысла и вообще к сожалению паскального with в Аде нет.
                          Ответить
                          • >Ещё есть эн-арник, то есть case с возвратом значения.

                            Хорошая вещь. Мало где есть.
                            Конечно в Nemerle покруче - там такой же тернарник, но он макросный, и сводится к матчу:
                            match (val)
                            {
                              | 1 => "адын"
                              | 2 => "джва"
                              | _ => "else"
                            }

                            Который по сути и есть эн-нарник.
                            Ответить
                  • Псевдонимы можно, как-то так:
                    package IIM renames Integer_Integer_Maps;

                    Так же можно функциям псевдонимы давать. А вот типам нельзя походу
                    Ответить
  • нормально тарас, в жабе вон в рантайме всегда типы чекаются
    ну подумаешь -- CMP сделал и джамп потом

    современному процу это что два пальца об асфальт
    а ты бы купил уже себе пентиум, хватит на тройке сидеть
    Ответить
  • да, не гуд конечно. по-хорошему, при компиляции нужно было создать конструктор и деструктор для элементов массивов - для инта, дабла, указателя - пустые, для строки или массива - очистка, для структуры - очистка полей. при этом размер памяти, выделяемой под массив не изменилась бы - вместо размера элемента можно хранить указатель на структурку с размером, конструктором и деструктором.
    Однако сомнительно, что это работало бы существенно быстрее, т.к. основные затраты времени - непосредственно работа с памятью.
    Ответить
    • > Однако сомнительно, что это работало бы существенно быстрее

      Думаешь?
      Надо как-нибудь проверить, но я не знаю, как.
      Ответить
      • Сделать руками - выделить память через GetMem под нужные структуры, заполнить их, через FreeMem удалить.
        заинтересовал:)
        Ответить
        • Ну типа того.
          Меня куда больше даже не память волнует, а всякие HBitmap или HGDIObj
          Ответить
          • Проверил для HBitmap размером 800 на 600, разница составила 5%, многовато, мне кажется, но некритично.
            Ответить
            • да, в подавляющем большинстве разница не критична
              Ответить
  • Ох, господи .. и не надоело эту тему поднимать? многие вызывались предложить замену, только вечно где-то что-то не так работало ... QC и форумы ем-ро засраны нерабочими идеями. И ты, Тарас, отметься там ... чисто поржать.
    Ответить
  • ш)QE,A!C X:T)Q?V(B:V)T?OQ,Q)E,YX)JG?K?X!XJ,Q:R!W)RG,U)W)Y)C"F"L!C$RA$V?N(J:N M"X)A)F)D!R:G?RI$Q)H,F.IO E C!X F:H M.B,A:W"Y(E!W M"Y?K)FJ"E.I?O:L"E,S!R)V!Q)U,E,G)V.D)W)J"M,K.E,O Z,Y)R!Y!F:O X.E:Y:L$Z:V:GT,S?L$W!U,C!N(G"HНLFRWCSFUGBORZGDLNAMQMNZLPGQCOFANAWLXCNEXRDAZAXQZXJABBXETRQTGEYSO
    Ответить

Добавить комментарий

Семь раз отмерь — один отрежь, guest!

    А не использовать ли нам bbcode?


    8