1. Pascal / Говнокод #13329

    +97

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    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
    {$APPTYPE CONSOLE} {$IFDEF FPC}{$MODE DELPHI}{$ENDIF}
    uses SysUtils, Classes, IniFiles, Variants;
    
    type TGetToken = function(var p: pointer): LongInt;
    procedure ParseData(var p: pointer; isKey: boolean); forward;
    procedure AdvanceIndex(var i: LongInt); forward;
    
    function GetIntegerToken(var p: pointer): LongInt;
    var value: LongInt = 0;
        negative: boolean;
    begin
      Inc(p);
      negative := PByte(p)^ = ord('-');
      if negative then Inc(p);
      repeat
        value := value * 10 + LongInt(PByte(p)^ - $30);
        Inc(p)
      until PChar(p)^ = 'e';
      Inc(p);
      if negative then value := - value;
      Result := value
    end;
    
    function GetListToken(var p: pointer): LongInt;
    var index: Integer = 0;
    begin
      Inc(p);
      while PChar(p)^ <> 'e' do begin
        AdvanceIndex(index);
        ParseData(p, false);
      end;
      Inc(p);
      Result := -1
    end;
    
    function GetDictToken(var p: pointer): LongInt;
    begin
      Inc(p);
      while PChar(p)^ <> 'e' do begin
        ParseData(p, true);
        ParseData(p, false);
      end;
      Inc(p);
      Result := -1
    end;
    
    function ParseError(var p: pointer): LongInt;
    begin
      Writeln('TYIIINTE CBET');
      Result := -1;
      Halt(Result)
    end;
    
    const FuncTable: array[0..3] of TGetToken = (ParseError, GetDictToken, GetIntegerToken, GetListToken);
    
    function GetStringToken(var p: pointer): string;
    var value: ShortString;
        length: LongInt = 0;
    begin
      repeat
        length := length * 10 + LongInt(PByte(p)^ - $30);
        Inc(p)
      until PChar(p)^ = ':';
      if length in [1..255] then begin
        PByte(p)^ := length;
        Move(p^, value, length+1);
        Result := value;
      end else Result := 'BINARY DATA';
      Inc(p, length + 1);
    end;
    
    var sl: TStringList;
        outf: TIniFile;
    
    procedure AdvanceIndex(var i: LongInt);
    begin
      sl.Add(IntToStr(i));
      Inc(i);
    end;

    type TSaveData = procedure(value: Variant);

    procedure SaveData(value: Variant);
    var
    key: string = '';
    i: LongInt;
    begin
    for i := 0 to sl.Count - 1 do key := key + '.' + sl[i];
    Delete(key, 1, 1);
    outf.WriteString('Torrent', key, VarToStr(value));
    if sl.Count > 0 then sl.Delete(sl.Count - 1);
    end;

    procedure PushKey(value: Variant);
    begin
    sl.Add(value)
    end;

    procedure PopKey(value: Variant);
    begin
    if sl.Count > 0 then sl.Delete(sl.Count - 1);
    end;

    procedure NOP(value: Variant);
    begin
    end;

    const SaveDataTable: array[0..3] of TSaveData = (SaveData, PushKey, PopKey, NOP);

    procedure ParseData(var p: pointer; isKey: boolean);
    var
    OpCode: ShortInt;
    value: Variant;
    begin
    OpCode := PByte(p)^;
    if OpCode >= $60 then value := FuncTable[OpCode shr 2 and 3](p)
    else if Opcode in [$30..$39] then value := GetStringToken(p)
    else ParseError(p);

    SaveDataTable[ord(isKey) + 2*ord(chr(OpCode) in ['d', 'l'])](value);
    end;

    var f: TFileStream;
    s: LongInt;
    p, cp: pointer;
    begin
    if ParamCount <> 1 then Writeln('Usage: ', ParamStr(0), ' filename.torrent')
    else
    try
    f := TFileStream.Create(ParamStr(1), fmOpenRead);
    s:= f.Size;
    GetMem(p, s + 1);
    f.ReadBuffer(p^, s);
    cp := p;
    outf := TIniFile.Create(ChangeFileExt(ParamStr(1), '.ini'));
    sl := TStringList.Create;
    ParseData(cp, false);
    finally
    if sl <> nil then sl.Destroy();
    if outf <> nil then outf.Destroy();
    if p <> nil then FreeMem(p);
    if f <> nil then f.Destroy()
    end
    end.

    Парсер torrent-файлов и сохранялка в INI-файл (пока без сумм фрагментов). Опа-лаба-стайл, писано левой ногой анскильного питуха.

    Запостил: inkanus-gray, 09 Июля 2013

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

    • Распидорасило.
      Ответить
    • Бляяядь, что ты наделал?
      Ответить
    • overflow
      Ответить
    • Уважаемые зрители, этот код говно и сейчас я это докажу:
      1. В целях никому не нужной оптимизации была произведена никому не нужная байтомагия, поэтому некоторые ошибки синтаксиса будут проигнорированы. Так, например, неправильный код 'f' будет интерпретирован так же, как и код 'd'.

      2. Генерация ключа в SaveData будет тормозить, потому что каждый раз пробегают весь цикл только питухи.

      3. TIniFile — оверинженеринг. В данном контексте хватило бы и обычного printf WriteLn.

      4. Рекурсия — говно. Пацан бы написал глобальный цикл и свой ручной стек.

      5. Совмещают в одном коде парсер и анпарсер, минуя AST, только неосиляторы.

      Dixi. Зато у меня нет свича на 200 строк.
      Ответить
      • Лажа-стайл.
        Ответить
      • Ну вот же еще:
        if sl <> nil then sl.Destroy();
        if outf <> nil then outf.Destroy();
        вместо sl.Free;outf.Free;
        Ответить
        • >>
          sl.Free;outf.Free;


          а если так
          правда, на Делфи:
          begin
            try
            // здесь основной код
            finally
              try
                sl.Free;
                outf.Free;
              except 
              end;
            end;
          end;
          Ответить
          • procedure TfmMain.ApplicationEvents1Exception(Sender: TObject; E: Exception);
            begin
              //do nothing;
            end;
            Ответить
            • Мда. Что еще сказать. Это глобальный перехват всех ошибок?
              Ответить
              • Только за то, что консолечка, уже можно ставить ЖЫРНЫЙ МИНУЗЗ/
                Ответить
    • SVN там=>
      Ответить
    • Вит поморщился. Жалость? Не её он хотел получить от Руслана. Увидел у него в руках эти грёбаные таблетки и решил, что Вит опять собирается накачаться? Нет, пора было расставить все точки над "i" и прекратить этот невиданный аттракцион благотворительности.
      Ответить

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