программирование

99 бутылок: Оберон-2, Ox

16. Oberon-2. Язык Оберон был создан автором Паскаля и Модулы-2 Никлаусом Виртом в 1987 году. В 1992 году Вирт и Ханспетер Мёссенбёк добавили в язык ряд новых средств. Так родился Оберон-2.

Считается, что язык это крайне простой и аскетичный. Лично мне он не понравился. Уж не знаю чем. Впечатлил меня транслятор. Использовал я JOB v0.75 С.Свердлова. Интересен он тем, что переводит программу на Оберон-2 в байт-коды Java, т. е. файл с расширением .class, который, в свою очередь, можно запустить на любой Java-машине.

Отсюда и, встречающиеся в листинге, строчки «javalang» и «javalang.PString». Думаю, транслятор этот пригодится Pascal-ориентированным программистам, которым понадобилось написать пару апплетов или классов Java.

Программа, выводящая песню о пиве (Oberon-2).

(* Beer song. Written by Stepanischev E.V.*)

MODULE Beer;

IMPORT javalang, Out;

PROCEDURE PrintBeer( n : INTEGER );
BEGIN
   IF n#0 THEN Out.Int (n,1) ELSE Out.String ("No") END;
   Out.String (" bottle");
   IF n#1 THEN Out.Char ("s"); END;

   Out.String (" of beer");
END PrintBeer;


PROCEDURE main*( VAR args : ARRAY OF javalang.PString );
VAR beer: INTEGER;
BEGIN
   Out.Open;
   FOR beer:=99 TO 1 BY -1 DO
      PrintBeer (beer);
      Out.String(" on the wall,");
      PrintBeer (beer); Out.Char ("."); Out.Ln;
      Out.String ("Take one and pass it around,"); Out.Ln;
      PrintBeer (beer-1);
      Out.String (" on the wall."); Out.Ln; Out.Ln;
   END;
   Out.String ("No more bottles of beer..."); Out.Ln;
   Out.String ("Go to the store and buy some more..."); Out.Ln;
   Out.String ("99 bottles of beer.");

END main;

END Beer.

17. Ox («Окс») — объектно-ориентированный язык с обширными математическими и статистическими библиотеками. Например, в языке, напрямую, можно перемножать две матрицы или производить инверсию. К другим особенностям можно отнести способность языка импортировать некоторые распространённые форматы данных. Например, такие типы, как in7, xls, wks, dht, fmt, можно сразу прочитать в матрицу. Синтаксис Ox, по утверждению авторов, похож на языки Си, Си++ и Java. Интерпретаторы и трансляторы в Си этого языка существуют под Windows, MS DOS, Linux, SunOS, Dec-Unix, Irix, HP-UX и IBM AIX. Лично я пользовался бесплатным консольным интерпретатором версии 2.20 под Windows.

Программа на языке Ox.

// Beer song. Written by Evgeny Stepanischev
#include <oxstd.h>

printbeer (const beer)
{
    print (beer?beer:"No", " bottle", beer-1?"s":"");
}


main()
{
    decl beer;

    for (beer = 99; beer > 0;)
    {
         printbeer (beer);
         print(" on the wall, ");
         printbeer (beer);
         print (".\nTake one and pass it around,\n");
         beer--;
         printbeer (beer);
         print (" on the wall.\n\n");
    }

    print ("No more bottles of beer...\n",
    "Go to the store and buy some more...\n",
    "99 bottles of beer.");
}


Оставить комментарий

ЯузОС, прежний FreeInet, «Полиглот»

Яуз О

«ЯузОС» (Кодовое название «Dead Fish») — новейшая операционная система. Как и положено новейшим программам, она полностью 64-х разрядная, т. к. создавшие её программисты были не ниже 64-го разряда квалификации. «ЯузОС» базируется на ядре от Царь-пушки версии 1.02.33…

Нравится? :)) Ссылочка «на почитать» в конце заметки.

***

Ожила страничка о бесплатном доступе в Интернет по своему прежнему адресу. Так что страничек, посвященных этому удивительному явлению, теперь целых две. Ссылочка, как и водится, ниже, в «ссылках по теме».

Ссылка предоставлена Cyber Lirik

***

Как вам такое? Программа, написанная сразу на 7 языках: COBOL, ISO Pascal, ANSI Fortran, ANSI C, PostScript, Shell Script и машинном языке процессора 8086. Все инструкции по запуску — в комментариях листинга. Две пустые в начале программы обязательны для нормального функционирования!

Листинг программы «Полиглот»

(*O/*_/
Cu  #%* )pop mark/CuG 4 def/# 2 def%%%%@@P[TX---P\P_SXPY!Ex(mx2ex("SX!Ex4P)Ex=
CuG #%*                                                                  *+Ex=
CuG #%*------------------------------------------------------------------*+Ex=
CuG #%*   POLYGLOT - a program in seven languages      15 February 1991  *+Ex=
CuG #%*                                                                  *+Ex=
CuG #%*   Written by Kevin Bungard, Peter Lisle, and Chris Tham          *+Ex=
CuG #%*                                                                  *+Ex=
CuG #%*   We have successfully run this program using the following:     *+Ex=
CuG #%*     ANSI COBOL:            MicroFocus COBOL85 (not COBOL74)      *+Ex=
CuG #%*     ISO  Pascal:           Turbo Pascal (DOS &amp; Mac), Unix PC,    *+Ex=
CuG #%*                            AIX VS Pascal                         *+Ex=
CuG #%*     ANSI Fortran:          Unix f77, AIX VS Fortran              *+Ex=
CuG #%*     ANSI C (lint free):    Microsoft C, Unix CC, GCC, Turbo C++, *+Ex=
CuG #%*                            Think C (Mac)                         *+Ex=
CuG #%*     PostScript:            GoScript, HP/Adobe cartridge,         *+Ex=
CuG #%*                            Apple LaserWriter                     *+Ex=
CuG #%*     Shell script:          gnu bash, sh (SysV, BSD, MKS), ksh    *+Ex=
CuG #%*     8086 machine language: MS-DOS 2.00, 3.03, 4.01, 5.00 beta    *+Ex=
CuG #%*                            VPix &amp; DOS Merge (under unix)         *+Ex=
CuG #%*                            SoftPC (on a Mac), MKS shell          *+Ex=
CuG #%*                                                                  *+Ex=
CuG #%*   Usage:                                                         *+Ex=
CuG #%*     1. Rename this file to polyglot.[cob|pas|f77|c|ps|sh|com]    *+Ex=
CuG #%*     2. Compile and/or run with appropriate compiler and          *+Ex=
CuG #%*        operating system                                          *+Ex=
CuG #%*                                                                  *+Ex=
CuG #%*   Notes:                                                         *+Ex=
CuG #%*     1. We have attempted to use only standard language features. *+Ex=
CuG #%*        Without the -traditional flag gcc will issue a warning.   *+Ex=
CuG #%*                                                                  *+Ex=
CuG #%*     2. This text is a comment block in all seven languages.      *+Ex=
CuG #%*                                                                  *+Ex=
CuG #%*     3. When run as a .COM file with MS-DOS it makes certain      *+Ex=
CuG #%*        (not unreasonable) assumptions about the contents of      *+Ex=
CuG #%*        the registers.                                            *+Ex=
CuG #%*                                                                  *+Ex=
CuG #%*     4. When transfering from Unix to DOS make sure that a LF     *+Ex=
CuG #%*        is correctly translated into a CR/LF.                     *+Ex=
CuG #%*                                                                  *+Ex=
CuG #%*   Please mail any comments, corrections or additions to          *+Ex=
CuG #%*   peril@extro.ucc.su.oz.au                                       *+Ex=
CuG #%*                                                                  *+Ex=
CuG #%*------------------------------------------------------------------*QuZ=
CuG #%*                                                                  *+Ex=
CuG #%*!Mx)ExQX4ZPZ4SP5n#5X!)Ex+ExPQXH,B+ExP[-9Z-9Z)GA(W@'UTTER_XYZZY'CPK*+
CuG #(*                                                                  *(
C   # */);                                                              /*(
C   # *)  program        polyglot (output);                             (*+
C   #     identification division.
C   #     program-id.    polyglot.
C   #
C   #     data           division.
C   #     procedure      division.
C   #
C   # * ))cleartomark   /Bookman-Demi findfont 36 scalefont setfont     (
C   # *                                                                 (
C   #
C   # *                  hello polyglots$
C   #     main.
C   #         perform
C     * ) 2>_$$; echo   "hello polyglots"; rm _$$; exit
              print
C             stop run.
     -*,                'hello polyglots'
C
C         print.
C             display   "hello polyglots".                              (
C     */  int i;                                                        /*
C     */  main () {                                                     /*
C     */      i=printf ("hello polyglots\n"); O= &amp;i; return *O;         /*
C     *)                                                                (*
C     *)  begin                                                         (*
C     *)      writeln  ('hello polyglots');                             (*
C     *)                                                                (* )
C     * ) pop 60 360                                                    (
C     * ) pop moveto    (hello polyglots) show                          (
C     * ) pop showpage                                                  ((
C     *)
           end                                                          .(* )
C)pop%     program       polyglot.                                      *){*/}

Ссылки по теме

Яуз ОС
Старый FreeInet

Оставить комментарий

99 бутылок: Small C, dbPager

14. Small C. Написав в предыдущей серии программу, выводящую песню о пиве, на Си—, я заинтересовался классом малоизвестных си-подобных языков. Благо Интернет и поисковые машины под рукой.

Первое, что мне попалось — это Small C. Впервые сведения о этом языке появились в октябре 1999 года в Dr. Dobb’s Journal. Язык простой и удобный, настолько отличен от Си, что перечислять эти отличия тут я не буду. Подробности можно найти в документации, доступной там же, на сайте.

Интересно, что исполнение программ происходит, как и в Java, в два этапа. На первом программа прекомпилируется в байт-коды, на втором — байт-коды интерпретируются или, если используется JIT, компилируются в машинный код и исполняются.

Несколько матерных слов в адрес компилятора. Отвратительная диагностика, странная реакция на символы табуляции, лишние переводы строки и символы «^», неработоспособность конструкции «a?b:c» и так далее. Компиляция моего небольшого примера заняла на Pentium-II 333 примерно 10 секунд. А теперь сам листинг.

Программа, выводящая песню о пиве (Small C).

/* 99 beer song. Written by Stepanischev E.V. Small C */
#include <console>

printbeer (b)
{
     if (b) printf ("%d",b); else printf ("No")
     printf (" bottle")
     if (b!=1) printf ("s")
     printf (" of beer")
}

main ()
{
     for (new i = 99; i > 0;)
     {
           printbeer (i)
           printf (" on the wall, ")
           printbeer (i)
           printf (".^nTake one and pass it around,^n")
           i--
           printbeer (i)
           printf (" on the wall.^n^n")
     }

     printf ("No more bottles of beer...^n");
     printf ("Go to the store and buy some more...^n");
     printf ("99 bottles of beer.");
}

15. Язык dbPager. Предназначен для динамической генерации страничек под MS IIS. Инструкцию по настройке прекомпилятора под IIS5 я не нашел, так что тестировал под версией для командной строки. Язык несколько, на мой взгляд, необычен своей концепцией блочников и некоторыми конструкциями, но, в целом, очень хорошо читается и воспринимается.

Скрипт, выводящий песню о пиве (beer.dbp).

// Beer song. Written by Stepanischev E.V. (dbPager)
var "beer=99"
    var "LoopLimit=99" :: while 1
        var ""
            @beer:printbeer
        %Space%on the wall,
        var ""
            @beer:printbeer
        .%CrLf%
        Take one and pass it around,%CrLf%
        set "beer=[%beer%-1]"
        var ""
            @beer:printbeer
        %Space%on the wall.%CrLf%%CrLf%

No more bottles of beer...%CrLf%
Go to the store and buy some more...%CrLf%
99 bottles of beer.

:printbeer
    switch %beer%
        #0 :: No
        #else :: %beer%
    %Space%bottle
    switch %beer%
        #1 :: 
        #else :: s
    %Space%of beer


Оставить комментарий

99 бутылок: C-​-, WSH

12. Sphinx C-​-. Есть язык Си, есть Си++, а есть, оказывается, Си-​-. Язык, занимающий промежуточное положение между Си и ассемблером. Его автором является Peter Cellik (Канада), в данный момент поддержкой и расширением синтаксиса языка занимается Михаил Шекер (Россия).

Язык мне показался обычным ассемблером, с внедрёнными элементами синтаксиса Си. Этакий навороченный макроассемблер. Попался бы мне такой лет так пять назад — оторвал бы с руками, а сейчас… Но, хотя на ассемблере теперь я пишу только мелочь, а мелочь лучше писать без применения всяческих прилад, стирать все же не буду — вдруг пригодится.

P.S. Кстати, на страничке языка можно скачать архиватор HA, переписанный на Си-​-. Работать он после такой модификации стал в полтора раза быстрее. Заслуга языка и компилятора или автора модификации?

Программа, выводящая песню о пиве.

?use80486
?include "WRITE.h--"

void PRINTBEER ()
{
    $PUSH AX;
    IF (AX) WRITEWORD (AX); ELSE WRITESTR ("No");
    WRITESTR (" bottle");
    $POP AX;
    IF (AX<>1) WRITE ('s');
    WRITESTR (" of beer");
}

void main()
byte bott;
byte beer = 99;
{
    WHILE (beer)
    {
        PRINTBEER (beer);
        WRITESTR  (" on the wall, ");
        PRINTBEER (beer);
        WRITESTR  (".\nTake one and pass it around,\n");
        beer--;
        PRINTBEER (beer);
        WRITESTR  (" on the wall.\n\n");
    };

    WRITESTR ("No more bottles of beer...\n");
    WRITESTR ("Go to the store and buy some more...\n");
    WRITESTR ("99 bottles of beer.");

    AX = 0x4C;
    $INT 0x21;
}

13. Windows Script Host — технология, заботливо упрятанная в недра вашей Windows заботливой компанией Microsoft. Скрипт написан с применением второй версии технологии, которая распространяется вместе с Windows 2000. Впрочем, ничего не мешает поставить его на любую другую ОС этого семейства. Базируется она на JScript или VBScript и позиционируется как замена пакетному (batch) языку DOS.

Способ запуска: wscript.exe beer.js. Во время выполнения настоятельно не рекомендуется переключать окна.

Скрипт, выводящий песню о пиве (beer.js).

function PrintBeer(i)
{
    return (i?i:"No")+" bottle"+(i-1?'s':'')+" of beer"
}

WshShell = WScript.CreateObject("WScript.Shell")
with (WshShell)
{
    Run("notepad.exe")
    WScript.Sleep(100)
    AppActivate("Untitled - Notepad")

    for (i = 99; i>0;)
    {
        SendKeys (PrintBeer (i)+" of beer on the wall, ")
        SendKeys (PrintBeer (i)+".~")
        SendKeys ("Take one and pass it around,~")
        i--
        SendKeys (PrintBeer (i)+" on the wall.~~")
    }

    SendKeys ("No more bottles of beer...~")
    SendKeys ("Go to the store and buy some more...~")
    SendKeys ("99 bottles of beer.")
}


Оставить комментарий

99 бутылок: Microsoft Dialer

11. Microsoft Dialer. Можно только удивляться, сколько языков программирования можно найти у себя на компьютере. Эта песнь о пиве написана на языке программирования SCP-файлов, файлов, руководящих соединением через модем. Насколько я понял в этом языке есть примитивная арифметика, вывод, циклы и ветвление (правда без else), но нет преобразования типов. Так что переменная цикла nB используется только для упрощения. Но как бы то ни было, написать программу у меня получилось. :)

Скрипт, выводящий песню о пиве.

; "99 beer" song by Evgeny V. Stepanischev
proc main
    string szA = "9"
    string szB = "9"
    string szS = " bottles"
    string szX = ""
    string szY = ""

    integer nB = 99

    set screen keyboard on
    delay 2

    ; Эту строчку ждет мой провайдер
    ; У вас она может быть другой
    transmit "@D^M^M"

    while Nb>0 do

    if szA!="0" then
    transmit szA
    endif

    transmit szB

    szS = " bottles"
    if nB==1 then
    szS = " bottle"
    endif

    transmit szS
    transmit " of beer on the wall, "

    if szA!="0" then
    transmit szA
    endif

    transmit szB
    transmit szS
    transmit " of beer.^M"
    transmit "Take one and pass it around,^M"

    szX = szA

    if szB=="0" then
        if szA=="1" then
        szX = "0"
        endif

        if szA=="2" then
        szX = "1"
        endif

        if szA=="3" then
        szX = "2"
        endif

        if szA=="4" then
        szX = "3"
        endif

        if szA=="5" then
        szX = "4"
        endif

        if szA=="6" then
        szX = "5"
        endif

        if szA=="7" then
        szX = "6"
        endif

        if szA=="8" then
        szX = "7"
        endif

        if szA=="9" then
        szX = "8"
        endif

    szY = "9"

    endif

    if szB=="1" then
    szY = "0"
    endif

    if szB=="2" then
    szY = "1"
    endif

    if szB=="3" then
    szY = "2"
    endif

    if szB=="4" then
    szY = "3"
    endif

    if szB=="5" then
    szY = "4"
    endif

    if szB=="6" then
    szY = "5"
    endif

    if szB=="7" then
    szY = "6"
    endif

    if szB=="8" then
    szY = "7"
    endif

    if szB=="9" then
    szY = "8"
    endif

    szA = szX
    szB = szY

    nB = nB - 1

    if nB==0 then
    transmit "No more bottles of beer on the wall.^M"
    endif

    if nB!=0 then
    if szA!="0" then
    transmit szA
    endif

    transmit szB

    szS = " bottles"
    if nB==1 then
    szS = " bottle"
    endif

    transmit szS
    transmit " of beer on the wall.^M^M"
    endif

    endwhile


    transmit "No more bottles of beer...^M"
    transmit "Go to the store and buy some more...^M"
    transmit "99 bottles of beer.^M"

    delay 99
endproc

Оставить комментарий

IE 5.5: новые классы CSS

Скриншот окна браузера Internet Explorer с открытой страницей сайта pixelCO, где крупно отображается логотип «pixelCO» и надпись «THE ARTISTRY WEB».
Screenshot. Шоколадные полосы прокрутки.

Сегодня я зашел на сайт PixelCore под своим IE 5.5 и увидел там полосу прокрутки… шоколадного цвета! Мыслей возникло две — новые возможности новой версии и глюк браузера.

Версию о глюке я отложил в сторону и стал смотреть откуда растут шоколадные ноги у полос прокрутки. Под подозрение попал PixelCore’вский CSS-файл. Скачав его себе, я увидел внутри вожделенные свойства, начинающиеся со слова scrollbar. «Так,» — подумал я — «пора сходить на MSDN».

На MSDN’е мне вежливо объяснили, что браузере IE5.5 от мамы с папой при рождении получил, кроме нового в области фильтров и JavaScript, еще и новые атрибуты к евойному CSS, о чем подробнее можно почитать «здесь, там и еще вот тут». Я проникся уважением от такой заботы к разработчикам и с удовольствием почитал. И вот, что я узнал.

scrollbar-face-color, scrollbar-shadow-color, scrollbar-highlight-color, scrollbar-3dlight-color, scrollbar-darkshadow-color, scrollbar-track-color, scrollbar-arrow-color — весьма многочисленная группа атрибутов, управляющая цветами элементов прокрутки. Назначение каждого, думаю, понятно из названия или англо-русского словаря. Может быть применен к любому тегу, имеющему полосы прокрутки, например BODY или TEXTAREA.

word-wrap — управляет разбиением текста в контейнере. Возможные значения — normal и word-break. Второе указывает на то, что текст, не поместившийся в контейнер по ширине будет принудительно разбит на несколько строк. Помните, как слишком длинные слова «раздвигали» таблицу? Теперь это поправимо средствами CSS.

writing-mode — переключает между режимами написания «слева-направо, сверху-вниз» и «сверху-вниз, слева-направо», т. е. текст пишется горизонтально. Возможные значения — lr-tb и tb-lr. Соотвественно может применяться везде, где есть текстовое наполнение (вплоть до INPUT).

white-space — может принимать значения normal или nowrap. normal задает обычный режимом вывода (текст, не поместившийся по ширине, автоматически разбивается на строки по пробелам и знакам препинания), nowrap — режим, при котором не поместившийся текст увеличивает ширину контейнера.

text-underline-position — управляет стилем подчеркивания текста. Принимает значения below (линия под текстом) и above (линия над текстом).

zoom — как и следует из названия, атрибут, предназначенный для _масштабирования_ содержимого тега. Значения указываются в процентах (например, 110%, 200%, 14%) или как коэффициент масштабирования (например, 1.1, 2, 0.14). Масштабировать можно все, что имеет содержание (например BODY).

Кроме того в IE 5.5 наконец-то появились псевдоклассы :first-line и :first-letter, описанные еще в CSS1. Первый позволяет назначить стиль для первой строки, второй — для первой буквы абзаца.

Оставить комментарий

JavaScript: Недосказанное Нетскейпом

Не оставляя надежду найти аналог CollectGarbage в Netscape, я сегодня расковырял интерпретатор JavaScript’а своего браузера на предмет наличия всего недокументированного. Ковырять вручную было лениво и я сначала написал небольшую программку, вычесывающую все текстовое из файла, на Перле, а потом небольшой скриптик под JUnix, который проверил, что из найденного относится к JavaScript. Ничего похожего на вызов сборщика мусора я так и не нашел, зато нашел кое-что другое. Результатами хочу поделиться.

Script(string) — создает кусок JavaScript-кода, который можно вызвать как обычную функцию. Разница между этим конструктором и Function заключается в том, что из кода, созданного конструктором Script, нельзя получить доступ к arguments и прочим свойствам и методам, специфическим для функций.

Пример использования Script:

AX      = new Script ("alert('TEST')")
AX      ()                      // Нaпечатает "TEST"

Call() — создает пустой объект типа Window. Практической пользы маловато, но, как это можно применить я могу придумать.

Пример того, что можно сделать с Call:

AX      = window
AX.BX   = "TEST"
alert (window.BX)                       // Напечатает "TEST"

window.BX = "TEST1"
AX      = new Call()
AX.BX   = window.BX
window.BX = "TEST2"
alert (AX.BX)                   // Напечатает "TEST2"

AX.open = window.open
AX.open ("about:blank")         // Откроет новое окно

BX      = {}
BX.open = window.open
BX.open ("about:blank")         // Вызовет ошибку

With(object) — достаточно странная функция. Копирует объект на новое место. Конструктор не вызывается, операция сравнения без приведения утверждает, что был создан новый объект, но изменения в одном экземпляре вызывают изменения в другом. Вообще-то, можно ее вызвать, как конструктор без параметров, в этом случае она создаст объект типа Object.

Пример вызова функции With:

function probe ()
{
        alert ('Create.')
        this.let = let
        this.val = val
}

function let (n)
{
        this.val = n
}

AX      = new probe()           // Напечатает "Create"
BX      = AX
alert   (AX===BX)                       // Напечатает "true"

BX      = With (AX)
BX.let  ("TEST")
alert   (AX.val)                        // Напечатает "TEST"
alert   (AX===BX)                       // Напечатает "false"

Closure(function_object) — очень похожа на With, но с парой отличий. Во-первых, Closure работает только с объектами Function, а во-вторых, ее можно вызвать как конструктор. И вот тут начинается самое странное. Внимание на пример.

Пример вызова функции и конструктора Closure:

function let (n)
{
        this.val = n
}

Function.prototype.let = let
AX      = new Function ("","")

BX      = AX
alert   (AX===BX)                       // "true". Объекты одинаковые.
AX.let  ("TEST1")
alert   (BX.val)                        // "TEST1". И это логично.

BX      = Closure (AX)
alert   (AX===BX)                       // "false". Объекты разные.
AX.let  ("OTHER")
alert   (BX.val)                        // "TEST2". И это тоже логично.

BX      = new Closure (AX)
alert   (AX===BX)                       // "false". Объекты разные.
AX.let  ("TEST2")
alert   (BX.val)                        // "TEST2". И это странно.

Arguments(объект) — в принципе можно применять для дублирования массива аргументов. Если применить как функцию, а не как конструктор, то Netscape может обидится и сказать GPF. А вообще во время экспериментов с этим объектом мой NC 4.7 падал настолько часто, что можно сказать — это его больное место, трогать которое не рекомендуется.

Пример вызова конструктора Arguments:

AX      = new Function ("", "return new Arguments(arguments)")
alert   (AX("TEST1").length)            // "1"
alert   (AX("TEST1","TEST2").length)    // "2"

Желающим испытать свое терпение и способности к обобщению, предлагается выяснить, какие функции несет каждый объект, свойство или метод из списка: __count__, __parent__, __proto__, __name__, __length__, __arity__, __call__, __caller__, __callee__. Кое-что совсем очевидно, но кое с чем придется серьезно помучиться. :))

Мое мнение — все, что я накопал, это усы от внутренней объектной модели браузера. Результат попытки упихать все, что только возможно, в объекты.

P.S. Мучал я Netscape версии 4.7. Как нибудь, надеюсь, руки дойдут до чего-нибудь более современного. Кстати, было бы интересно рассмотреть все эти, вырванные с мясом куски, на предмет дыр в безопасности и crash code.

Оставить комментарий

CollectGarbage. И все-таки она работает!

Сегодня я решился все-таки выяснить, работает ли, найденная мной в MSIE, недокументированная функция CollectGarbage(). Я довольно долго размышлял, как бы мне это сделать, поскольку был уверен в наличии у интерпретаторов JavaScript автоматического сборщика мусора. «Стоит мне удалить объект» — размышлял я — «и сборщик мусора тут же освободит память. Я ничего не смогу проверить».

Монитор. Расход памяти

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

Скажу сразу — функция работает! Но самое интересное не это. Оказалось, что если в MSIE (ровно, как и в Netscape, позднее я повторил эксперимент и под ним тоже) и есть сборщик мусора, то он очень неторопливый. В одном из экспериментов я прождал около 20 минут, прежде чем мое терпение кончилось!

Более того, если нажать «Create» несколько раз подряд, то память будет выделяться после каждого раза. То есть в программах на JavaScript, постоянно создающих структуры большого объема, вызов этой функции жизненно необходим! Я, например, сегодня же выпущу новую версию JUnix с демоном сборки мусора. К сожалению, как я не старался, мне не удалось найти ничего похожего в версии JavaScript от Netscape. Так что вопрос об высвобождении памяти под этим браузером остается открытым.

Демонстрационный пример:

<SCRIPT>
function Create()
{
        Arr = new Array ()
        for (i = 0; i&lt;100000; i++)
        Arr[i] = '01234567890123456789012345678901234567890'+
        '12345678901234567890123456789012345678901234567890'+
        '12345678901234567890123456789012345678901234567890'+
        '12345678901234567890123456789012345678901234567890123456789'
}

function Drop()
{
        delete Arr
}

function Collect()
{
        CollectGarbage()
}
</SCRIPT>
<BODY>
<FORM>
<INPUT TYPE=BUTTON onClick="Create()" VALUE=Create>
<INPUT TYPE=BUTTON onClick="Drop()" VALUE=Drop>
<INPUT TYPE=BUTTON onClick="Collect()" VALUE=Collect>
</FORM>
</BODY>

Оставить комментарий

Микрософт жива. mod_cgisock, JScript и CK-22B6

Для начала, о событии, так меня заинтересовавшем в позапрошлом выпуске. Вчера на ZDNet.com я, наконец-то, смог прочитать, что же, все-таки, случилось в сетевом хозяйстве Майкрософт.

Оказывается, во всем был виноват (а я был в чем-то прав!) плохой дядя Роутер. Именно он содержал «configuration error» и оставлял запросы к внутренней сети компании «unanswered». Целый день. Вот такой бяка этот роутер. Там еще много чего написано, любопытствующих отсылаю к источнику.

Веб-мастера, имеющие отношение к Apache, знают что такое Fast CGI. Если не вдаваться в подробности — это метод, позволяющий держать CGIs сразу в памяти и выполнять их по мере необходимости.

А теперь скажите мне, что такое mod_cgisock. Так вот, это модуль Apache, который предоставляет возможность работать с CGI через обычные юниксовые сокеты. CGI в этом случае пишется на языке, способном работать с сокетами, и, насколько я понимаю, выступает в роли сервера, обслуживающего запросы Apache. Утверждается, что такой способ позволяет существенно экономить память и выполнять приложения гораздо быстрее.

Весьма любопытно, тем более, что слышу я об этом впервые, но для PHP (а он у меня скомпилирован как модуль), который мне в последнее время так полюбился, абсолютно бесполезно. :)

Есть у меня телевизор Samsung CK-22B6SR. Локализация выполнена довольно странным способом. Многие не замечают или не обращают внимания, но факт — при нажатии на кнопку «меню», это самое меню появляется сначала на английском языке, а уже потом затирается и пишется локалью (в моем случае — по-русски). Лично мне это не мешает, тем более, что все это едва заметно на глаз, но интересно — что помешало выполнить локализацию нормально, не прибегая к таким кривохитрым ходам?

Кстати, загляните на сайт Самсунг. Там, у телевизора есть забавная характеристика — кривизна экрана… Я долго смеялся. Тем, кто юмора не понял, объяснять ничего не буду. Не способен. :)

Маленькое продолжение темы недокументированных возможностей. На этот раз порадовал Microsoft Internet Explorer 5.0 и 5.5. Случайно обнаружил, что в JScript интерпретаторе этого браузера есть две, нигде не описанные, но, тем не менее, судя по всему, прекрасно работающие фичи.

Во-первых, это константа условной компиляции @_microsoft, имеющая значение true. Фича, абсолютно пока бесполезная, но интересная самим фактом своего существования. Возможно, не за горами времена, когда она примет значение false.

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

А на сегодня это все. :)

Оставить комментарий

Java и JavaScript. Близнецы или братья?

Сегодня, когда мне в триста тысяч двадцать седьмой раз сказали, что Java и JavaScript — это одно и тоже, я не выдержал, и решил высказаться со своей относительно высокой трибуны.

Господа! Java и JavaScript — языки разные, что я намерен сейчас доказать.

Большинство, в качестве защиты своей точки зрения, приводит такой аргумент, буквально: «посмотри на название, если ты не видишь сходства…» и т. д. Странная точка зрения, тем более, что это самое большинство вполне допускает, что C и C++ — языки разные. Разубеждать таких людей бесполезно, у них сформировалась своя точка зрения, менять которую они не собираются, в голове их путаница, и чтобы их еще больше запутать, я скажу, что JavaScript — это не один язык, а три. Есть JavaScript от Netscape, JavaScript от Microsoft, который еще называется JScript, и EMCAScript, который тоже является JavaScriptом. Вот эти три языка весьма похожи, хотя и не совместимы между собой полностью.

А теперь, собственно, перейдем к сути. Начнем с базового языка. Корни этих двух языков уходят куда-то в C, так что синтаксически они довольно близки. По крайней мере, что касается инструкций if, while, switch и прочих им подобных, в обоих языках записываются они одинаково. Но вот если коснуться описания функций, объектов, переменных, то тут эти языки весьма существенно различаются.

Простой пример на JavaScript:

function somefunct (s)
{
        Arr    = new Array (2)
        var k = parseInt (s) + '99'
        alert (k)
}

вопрос к знатокам Java — какая из этих строчек, исключая скобки, не вызовет ошибки в интерпретаторе? Правильно, вызовут все. Думаю, лучшего доказательства и не придумаешь. Кстати, обратите внимание: в JavaScript точка с запятой элемент необязательный и ставится лишь там, где действительно нужна (например, после пустого цикла for).

Если кто не понял, тут я создал объект типа Array и переменную k. Преобразовал s в число, а потом сложил со строкой «99». В результате, опять получил строку и при помощи alert вывел на экран. Тут я подхожу к еще одному отличию JavaScript от Java: первый язык с нестрогой типизацией данных. Переменная в разные моменты времени может хранить строку, целое или любой другой объект. Кстати, строка, число и прочие типы в JavaScript являются объектом, а «базовые» функции — методами объекта Global. Чего не скажешь о Java. Да, и кстати, вспомните о том, как выполняется конкатенация в Java. И вот, проделайте мне еще такую штуку в Java:

Регулярные выражения:

function somefunct2 (s)
{
        if (/\d+\s+/.test(s)) alert ('Ok!'); else
        s = s.replace (/(\d)/g,'\\1!')
}

99,9999% людей такое объяснение удовлетворит, а вот самые стойкие, знаю по опыту, приведут мне примеры блоков try и вызовов Java-методов из JavaScript в Netscape. Последовательно.

Блок try — catch поддерживается только JScript 5.0 и Netscape JavaScript 1.4, т. е. введение это довольно недавнее. Кроме того, этот блок имеет синтаксис отличный от принятого в Java. Наверное достаточно будет сказать о наличии у try, по крайней мере в версии от Microsoft, блока else при отсутствии finally, а так же о том, что catch возвращает специальный объект Error с двумя (в 5.5 — тремя) свойствами, что уже совсем никак не похоже на Java.

Теперь относительно вызовов Java-методов. Вызов Java-методов из JavaScript в NC называется LiveConnect и к самому языку непосредственного отношения не имеет. Пользуясь LiveConnect я, теоретически, могу вызвать Java из Flash, Flash из JavaScript, JavaScript и DOC-viewer и так далее. Для этого эта технология и предназначена. Надеюсь, это не повод мешать все перечисленное в одну кучу?

Ну а самых упорных я отсылаю на сайты фирм Sun и Microsoft, где они, скачав себе документацию, смогут воочию убедиться в разнице между этими языками.

Оставить комментарий

Базы данных. Наведем порядок

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

Устав бороться со своей и чужой ленью, я решил принять какие-то меры, чтобы облегчить жизнь себе и другим. Одна из таких мер — файл описания таблиц, который мы теперь вкладываем в корневой директорий каждого проекта. Я обычно называю его .tables (естественно в настройках Apache прописывается запрет на получение этого файла через Web), где в достаточно свободном формате описываются таблицы, поля, связи между ними и все остальные объекты.

Естественно, что файл предназначен для описания достаточно небольших баз данных (менее 7—10 таблиц). В этом случае больших баз без хорошо составленной наглядной документации все равно не обойтись. Не надейтесь. :)

Четкий формат представления имеют пока только таблицы, в силу того, что остальными объектами приходится пользоваться достаточно редко, да и синтаксис их описания различается для разных СУБД, но, возможно, в следующих версиях формата появятся правила и их описания тоже.

Вот пример описания двух таблиц, связанных между собой

[/usr/local/pgsql/bin/psql eshop]

items / товары
-----------------------
id              serial / идентификатор
gid             int4   / категория товара -> group.id
name            text   / наименование
price           real   / цена
comment         text   / описание товара

CREATE INDEX items_price_idx ON items (price)

group / категории
-----------------------
id              serial  / идентификатор -> items.gid
parent          int4    / родитель в дереве. -1, если верхний уровень -> id
name            text    / наименование

Думаю из примера и так все понятно, но я все-таки дам пару комментариев.

Строчка, заключенная в квадратные скобки, — команда, принимающая данные. Пустые строки и строки, начинающиеся с двух минусов игнорируются. В абзаце, где описывается таблица, первым идет ее имя, ниже — описания ее полей: наименования, через табуляцию тип. В конце каждой значимой строки через пробел и слеш находится ее краткое описание.

Инструкции заведения секвенсоров, представлений и хранимых процедур записываются в одну строку.

Так как формат файла представлений достаточно легко может быть разобран и преобразован в команды мониторов mSQL, PostgreSQL и MySQL я, пару дней назад, выбрав время, написал небольшую программку на Перле. Правда толком ее еще не обкатал, но не думаю, что с ее эксплуатацией возникнут какие-то проблемы.

Интепретатор файлов таблиц: intp.pl

#!/usr/bin/perl

sub StripComment
{
        my ($line) = @_;
        unless ($line=~s{^([^/]*)\s+/.+}{$1}o)
        {
                print "Предупреждение: не указан комментарий [ $line ].\n"
                unless ($line=~/^CREATE/o);
        };

        return $line;
};

sub AddData
{
        my ($table, @query) = @_;
        my $query  = join ',', @query;
        my $result = '';

        if ($todrop)
        {
                for (@query)
                {
                        if (/([^ ]+) serial$/)
                        {
                        $result.= "DROP SEQUENCE ${table}_${1}_seq\\g\n";
                        last;
                        };
                };


                $result.= "DROP TABLE $table\\g\n";
        };

        $result.= "CREATE TABLE $table ($query)\\g\n";

        return $result."\n";
};

sub AddDrop
{
        my $table = $_[0];

        if ($todrop && $table=~/^CREATE ([^ ]+ +[^ ]+)/o)
        {
                return "DROP $1\\g\n$table\\g\n";
        } else
        {
                return "$table\\g\n";
        };
};

unless (open F, (shift or '.tables'))
{
        print <DATA>;
        die "\n"
};

@query  = ();
$table  = '';
$result = '';
$comm   = '';
$todrop = shift or 0;

while (<F>)
{
        chomp;
        next if ($_ eq '' || /^\-\-/);

        if (/^\[(.+?)\]$/)
        {
                $comm = $1;
                next;
        };


        @data =  split (/       +/,StripComment $_);
        if (@data < 2)
        {
                $result.= @query?AddData($table, @query):AddDrop ($table)
                if ($table ne '');

                $table  = $data[0];
                @query  = ();
        } else
        {
                push @query, "$data[0] $data[1]";
        };
};

close F;

$result.= AddData ($table, @query) if (@query);

if ($result ne '')
{
        if ($comm ne '')
        {
                open  F, "|$comm";
                print F "$result\\q";
                close F;
        } else
        {
                print "Ошибка: не указана команда для приема данных.";
        };
} else
{
        print "Ошибка: файл для обработки пуст.";
};

__END__

Интерпретатор файлов таблиц для СУБД.
Написал Евгений Степанищев (2000 год).

Использование: inpt.pl имя_файла [DROP]

DROP - предварительно сделать DROP для таблиц и SEQUENCE

Формат:

-- БД stat                              комментарий

tablename / описание                    имя таблицы
---------------------                   оформительский элемент

поле1   тип / описание                  поля таблицы,
поле2   тип / описание                  описание интепретатор игнорирует
и т.д.

[/usr/local/mysql/bin/mysql stat]       комманда, принимающая данные

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

Оставить комментарий

99 бутылок: ASP (JScript и JavaScript), Parser

Жаждались? Судя по кислым лицам — нет. Итак, представляю очередную серию из мыльного сериала «99 бутылок пива на стене». На этот раз, на стене амбициозный Парсер с хорошей родословной, но плохой внешностью и братья-почти-что-близнецы JavaScript и ASP.

9. Parser (втрой версии) студии Артемии Лебедева. Предпроцессор для генерации Веб-страниц «на лету».

^var[i;99]
^while[i>0;

^var[i] bottle^if[i!=1;s;] of beer on the wall, ^var[i]
bottle^if[i==1;s;] of beer.<BR>
Take one and pass it around,<BR>
^var[i;-;1]
^if[i;^var[i];No] bottle^if[i!=1;s;] of beer on the wall.<BR>
<BR>
]
No more bottles of beer...<BR>
Go to the store and buy some more...<BR>
99 bottles of beer.

10. ASP JScript и JavaScript. Одновременно. Первый — серверный язык, второй — клиентский. Испытано под IE 5.0, Opera 5.01, Netscape 4.75, Netscape 6.0 и IIS5.

<!-- <%@ LANGUAGE = JScript %>

<% //>
//</%> --> <SCRIPT LANGUAGE=JavaScript>
for (k = ' of beer on the wall',o='', i = 99; i>0; i--)
{
    a = i+' bottle'+(i-1?'s':'')
    o+= a+k+', '+a+' of beer...<BR>'+
    'Take one down, pass it around.<BR>'+
    (i-1?i-1:'No ')+' bottle'+(i-2?'s':'')+k+'.'+
    '<BR><BR>'
}

o+= 'No more bottles of beer...<br>'+
'Go to the store and buy some more...<br>'+
'99 bottles of beer.'

if (typeof(document)!='undefined') document.write (o); else
if (typeof(Response)!='undefined') Response.Write (o)
// </SCRIPT> <!-- // < %> -->


Оставить комментарий

Opera 5.01. Опять Парсер. Etc

Только что узнал о выходе Opera 5.01. С чем и поздравляю всех немногочисленных пока поклонников этого, потенциально популярного браузера. Краткий список изменений со слов сайта «Абсолютно все о браузере Opera» выглядит так:

  • Добавлены функции поиска на кнопку «Go» (ввод)
  • Новые shotcuts в почтовой программе
  • Исправлены проблемы с прокси
  • Оптимизирована работа ICQ
  • Косметические изменения в окне новостей
  • Изменения в самом файле Оперы
  • Исправлена ошибка в Ecmascript

Да, чуть не забыл представить эту замечательную программу тем, кто с ней еще не знаком: это очень маленький, быстрый браузер с поддержкой практически всего чего только можно. Для программистов и верстальщиков: к сожалению пока нет нормальной поддержки DOM, в HTML— и WAP— отрисовке еще множество глюков. Радует, что проект быстро развивается, возможно к версии так 6-й из него получится мощная альтернатива Internet Explorer.

Лебедевский «Parser» до сих пор не дает покоя сетевым обозревателям. Сегодня журнал «Интернет.Ру» разродился интервью с создателем Парсера Константином Моршневым. Интервью коротенькое (а о чем говорить-то?), но для меня интересное. Интересное тем, что в нем упоминается о другой разработке студии Лебедева — «Imprimatur!». Как вам фраза: «этот продукт совершенно не похож на все остальные наши разработки — его нет в какой-то стандартной версии, он подгоняется под каждый конкретный сайт»? Которую любой человек, имеющий какой-то опыт создания Веб-интерфейсов, с легкостью расшифрует как: «это не продукт, а обычный Веб-интерфейс к сайту, каких — тысячи, для каждого сайта на базе предыдущих создается новый Веб-интерфейс».

По-моему, ход гениальный. Завтра же вставлю в свои коммерческие предложения: доступ к вашему сайту будет осуществляться по нашему оригинальному протоколу «Русская Линия», базирующемся на HTTP и FTP, поисковая машина «Ванга», которую мы каждый раз переписываем под конкретный сайт, ну и так далее. :)

В той же статье Моршнев обещает открыть нам глаза на другое свое детище — уже упомянутый мною «Imprimatur!». Не нужно быть семи пядей во лбу, чтобы догадаться, какой доменный адрес будет иметь сайт ему посвященный. Я — догадался. Правда на сам сайт войти не получится, доступ запрещен. Но работа над подпиткой утихающей уже шумихи вокруг лебедевской студии продолжается.

Оставить комментарий

Баннерная реклама. Только не бейте…

К сожалению, фильтровать рекламу «в телевизоре» мы не научились, зато худо-бедно фильтруем рекламу в Интернете. Кто-то ставит AtGuard, кто-то настраивает Squid, кто-то — надеется на «ускорители Интернет». О том как очистить свой виртуальный мирок от баннеров сказано достаточно. Я же хочу восстановить справедливость — защитить владельцев сайтов от программ вырезающих баннеры.

Для начала отмазка. Почему-то считается, что баннеры — это зло. Они засоряют канал и снижают скорость загрузки любимого ресурса. Никто и не задумывается, как и на какие деньги, эти самые «любимые ресурсы» существуют. Так вот, открою вам глаза. Любимые ресурсы существуют за счет показов так нелюбимых баннеров. А внося свой вклад в урезание баннерных показов, вы тем самым способствуете банкротству Веб-проектов.

Итак. Для начала надо разобраться, как собственно осуществляется фильтрация подобного рода. Все очень просто. Пользователь (или изготовитель фильтра) прописывает некий набор правил, согласно которым, программа определяет, что есть баннер, а что — нет. Напрашивается вывод: чтобы ваши баннеры проходили «фейс-контроль» надо:

  1. Либо назвать их так или сунуть в такой каталог, что бы правила, заданные в программе, их не опознали;
  2. Либо сделать что-то, что бы добавить правило (а значит отличить баннер от не-баннера) не представлялось возможным.

Первый вариант отметаем сразу. По очевидным соображениям — если правил, заданных в программе, не хватает для опознания, пользователь добавит новое. Вариант номер два кажется более привлекательным, только как достичь того о чем я говорю?

Нужно будет внести кое-какие изменения в баннерную систему и в настройки Веб-сервера. Начнем с баннерной системы.

Во-первых, баннеры нужно называть совершенно произвольным образом, не придерживаясь никаких правил. Например: tri-gusia-i-utka.gif, a.gif, 1808500.jpg и т. д.

Во-вторых, скрипт, показывающий баннеры, должен подставлять в атрибут SRC правильные имена баннеров и случайным образом полученные пути. Должно получаться что-то вроде:

<IMG SRC=http://your.host.ru/aa12/a.gif>
<IMG SRC=http://your.host.ru/priale/sila/duaa1/1808500.jpg>

и т. д.

Популярные Веб-сервера (по крайней мере Apache и IIS) предоставляют возможность задать произвольную реакцию на ошибку 404 (файл не найден). Изготавливается скрипт, который будет вести себя следующим образом: при запуске он проверяет какая страница была запрошена, если это GIF— или JPEG-файл (для Apache — анализируется переменная REQUEST_URI), то скрипт пытается найти баннер с таким именем. Если находит — показывает, не находит — сообщает об ошибке «файл не найден».

Остается добавить, что схема успешно испытана и скоро будет запущена под одним из региональных порталов. Парочку подводных камней предлагается найти и разбить самостоятельно. Чтобы жизнь малиной не казалась. :)

Оставить комментарий

Парсим Лебедева, Emax, PHP 4.0.4

Артемий Лебедев и компания опубликовали язык своего заочно знаменитого Парсера. Непонятно, чем они так гордились? С точки зрения программиста — обычный предпроцессор, тот же PHP — гораздо логичнее, понятнее и функциональнее, а с точки зрения не программиста, как мне кажется, — кошмарное нагромождение скобочек, стрелочек и значков «@». Нет, увольте.

Сегодня я решился все-таки посмотреть то, о чем говорит весь РуНет уже примерно неделю, — на проект Emax’a («Три сестры»). Я абсолютно не понял почему вокруг всего этого столько шуму. Будем считать, что идеей этого проекта я не проникся. Зато проникся идеей соседнего → www.sight.ru. Для того чтобы понять, что представляет из себя сайт, достаточно взглянуть на несколько работ, там представленных. Вот список наиболее понравившихся мне из просмотренных:

  • Девушка молодая, задумчивая;
  • Пора пришла;
  • Я птица слабая, мне тяжело лететь;
  • Двое в сторонке;
  • Дуб Ангела;
  • Монастырь.

Особенно понравилась первая, причем до такой степени, что я, активный противник фотографий и рисунков на десктопе, не удержался. Хотя понимаю, что ставить такое на десктоп — кощунство, ничего поделать с собой не могу.

Не скажу, что с нетерпением этого ожидал, но все-таки выход каждой новой версии PHP для меня — событие. Вот и сегодня, узнав о выходе PHP 4.0.4, я внимательно изучил change log, выкачал новую версию и документацию. Несмотря на то, что изменилась лишь вторая цифра после запятой, изменений довольно много. Если оценивать с точки зрения количества, то на моем домашнем разрешении (800×600) список занимает девять экранов. Качественного, как и ожидалось, скачка нет, обширный список багфиксов, с редкими вкраплениями новых возможностей. Особенно меня заинтересовала поддержка новой версией модуля OpenSSL и ключ «F» к функции preg_replace (за что он отвечает посмотрите сами), из багфиксов, цитирую, «fixed mysql_close(), pg_close(), msql_close() and sybase_close() — they weren’t properly closing the SQL connections». При всем уважении к создателям PHP у меня просто нет слов…

Оставить комментарий

Софт. FAR 1.70b2, MySQL, PostgreSQL…

Новость дня — вышел FAR 1.70b2 build 321. С некоторый пор этот, один из лучших (скажу лучший — заклюют :) файловых менеджеров, разрабатывается не одним человеком, а группой разработчиков (FAR Team). С этих же самых пор список WhatsNew каждой новой версии поражает своим размером. Вот и на этот раз, я насчитал 64 пункта! Приставки Beta бояться не нужно, FAR Team обещает выпустить release только в случае полного отсутствия багов. То есть никогда :). Так что — качать!

Продолжая тему FARa. 14-го декабря появилась новая версия одного из моих любимых плагинов к FARy — ProxyNews 1.0 b8. Исправление только одно — пофиксен баг с листингом сообщений.

Смешно, но факт — я знаю людей, которые пользуются FARом, начиная чуть ли не с первой версии и не знают о существовании такий вещи, как плагины. На всякий случай, сообщу. Сам FAR — это еще не все. К нему существуют «довески», называемые плагинами, которые сильно расширяют его функциональность. Например, есть плагины для чтения почты, работы с FTP через Proxy-сервер, проигрывания музыкальных файлов (точнее управления WinAMP’ом) и многого другого. Плагины можно взять на сайте PlugRing, ссылка на который есть в конце статьи (см. «ссылки по теме»).

Из других новостей мира вареза — появление MySQL 3.23.29a-gamma. В списке изменений — в основном исправление ошибок.

Почему-то, MySQL считается лидером по производительности в мире Веба. По-моему, мнение это распространяется за счет испытаний на время обработки одного простейшего запроса. На мой взгляд, у PostgreSQL достоинств гораздо больше. Во-первых, он производительнее MySQL, если запросов несколько (надо только запустить его в асинхронном режиме), при условии, что сайты, обращающиеся к СУБД, достаточно посещаемы, наличие нескольких запросов одновременно — обычное дело. Во-вторых, в PostgreSQL есть несколько встроенных языков для определения хранимых процедур. В-третьих, в PSQL есть подзапросы, в отличие от MySQL, где их можно найти только в TODO list. В-четвертых, в PSQL есть UNION. В MySQL приходится пользоваться временными таблицами. Да и вообще, что перечислять? В MySQL есть, на мой взгляд, только две вещи, которых нет в Postgres: переменные (которые, кстати, не везде могут быть использованы) и условие IF (которое с успехом заменятся CASE и процедурами).

Так что, если будете выбирать СУБД для Веба… вы знаете, что я бы посоветовал.

Оставить комментарий

99 бутылок: SHS SSI, Price Convertor Small Talk

Эпопея о бутылках с пивом продолжается. Сегодня вашему вниманию предлагается тексты программы, выводящие песню о бутылках на языках Small HTTP Server SSI и Price Convertor Short Talk 2.00rc2.

7. Small HTTP Server SSI. Вариант реализации SSI для SHS, написанного Максом Фиоктистовым. Файл должен называться index.shtm.

<!--#if expr="$b=No" -->
<BODY BGCOLOR=BLACK TEXT=WHITE>
No more bottles of beer...<BR>
Go to the store and buy some more...<BR>
99 bottles of beer.</BODY>
<!--#break -->
<!--#endif -->
<!--#set var="" value="" -->
<!--#set var="N" value="No" -->
<!--#set var="9" value="8" -->
<!--#set var="8" value="7" -->
<!--#set var="7" value="6" -->
<!--#set var="6" value="5" -->
<!--#set var="5" value="4" -->
<!--#set var="4" value="3" -->
<!--#set var="3" value="2" -->
<!--#set var="2" value="1" -->
<!--#set var="1" value="0" -->
<!--#set var="0" value="9" -->

<!--#if expr="!$a" -->
<!--#set var="a" value="9" -->
<!--#set var="b" value="9" -->
<!--#set var="s" value="bottles" -->
<!--#set var="m" value="$s" -->
<!--#endif -->
<!--#set var="t" value="$a" -->

<!--#if expr="$b=0" -->
<!--#set var="c" value="$a" -->
<!--#elif expr="$a>0" -->
<!--#set var="c" value="t" -->
<!--#endif -->
<!--#set var="d" value="$b" -->

<!--#if expr="$a=||$a=0||$c=1" -->
<!--#set var="c" value="" -->
<!--#endif -->

<!--#if expr="$d=1&&$c=" -->
<!--#set var="d" value="N" -->
<!--#elif expr="$d=2&&$c=" -->
<!--#set var="m" value="bottle" -->
<!--#endif -->

<HEAD>
<META HTTP-EQUIV="Refresh" Content="1;URL=index.shtm?a=<!--#echo var="$c" -->
&b=<!--#echo var="$d" -->&m=<!--#echo var="m" -->
&s=<!--#echo var="m" -->">
</HEAD>
<BODY BGCOLOR=BLACK TEXT=WHITE>
<!--#echo var="a" --><!--#echo var="b" -->
<!--#echo var="s" --> of beer on the wall,<BR>
Take one and pass it around,<BR>
<!--#echo var="$c" --><!--#echo var="$d" -->
<!--#echo var="m" --> of beer on the wall.
</BODY>

8. Price Contertor Small Talk 2.00rc2. Этот язык я придумал сам, реализован он был примерно в 1998 году, как внутреннее средство управления программой обработки прайсов, представленных виде файлов Excel.

BEGIN
    "99"
    mov a "bottle(s) of beer on the wall."
END
WORK    "*"
    eq "No"
    if
        echo "No more bottles of beer..."
        echo "Go to the store and buy some more..."
        echo "99 bottles of beer."
        break ""
    endif

    else
        delete
        mov Y a
        .
        echo
        echo "Take one and pass it around,"
        mov Y "1"
        -
        eq "0"
        if
            mov Y "No"
        endif

        delete
        mov Y a
        .
        echo
    endelse
    prev
END


Оставить комментарий

HTA (HTML application)

После появления на свет WebICQ, я получил множество писем с просьбами рассказать, что такое HTA и WScript. О WScript как-нибудь в другой раз, а сегодня я расскажу о том что такое HTA.

HTA (или HTML Application) — так называемые «безбраузерные приложения», выполнение которых — одна из возможностей браузера Internet Explorer 5.0. С точки зрения пользователя, такая программа ничем (кроме, разве что, расширения) не отличается от любой другой: имеет заголовок окна, свою иконку, отображается в панели задач и т. п.

С точки зрения программиста, HTA — обычная Веб-страничка: для ее создания используются все те же HTML, CSS, JScript и VBScript. Единственное, что ее отличает от всего того, что можно увидеть на любом сайте, это наличие заголовочного тега (в общем случае он может отсутствовать) и полное отсутствие системы безопасности (как и в любом нормальном приложении).

Тег заголовка позволяет программисту управлять некоторыми параметрами созданного приложения. Выглядит он, как простой XML-тег, расположенный внутри тела программы (обратите внимание пробел перед «/>» обязателен!): <HTA:APPLICATION... />.

Параметры перечисляются внутри тега, например, так, как это показано ниже:

<HTA:APPLICATION ID="oHTA"
APPLICATIONNAME="myApp"
VERSION="1.0"
WINDOWSTATE="maximize" />

Хотя параметров довольно много (все они перечислены в Таблице 1), мне, например, очень не хватает еще двух: WIDTH и HEIGHT, которые позволили бы задавать размер окна, не вызывая методов JScript или VBScript.

Таблица 1

Параметр В JavaScript Назначение Значения
APPLICATIONNAME applicationName Имя приложения строка
BORDER border Тип бордюрa thin, dialog, none, thin
BORDERSTYLE borderStyle Стиль бордюра внутри HTA normal, complex, raised, static, sunken
CAPTION caption Наличие заголовка yes, no
commandLine Содержимое командной строки
CONTEXTMENU contextMenu Управляет наличием меню правой кнопки мыши yes, no
ICON icon Задает иконку приложения URL (строка)
INNERBORDER innerBorder Внутренний бордюр yes, no
MAXIMIZEBUTTON maximizeButton Управляет кнопкой «развернуть» yes, no
MINIMIZEBUTTON minimizeButton Управляет кнопкой «свернуть» yes, no
NAVIGABLE (только для IE 5.5) navigable Переход по ссылке произойдет в окне HTA no, yes
SCROLL scroll Наличие scroll bars yes, no, auto
SCROLLFLAT scrollFlat Управление стилем scroll bars no, yes
SELECTION selection Управляет возможностью выделения текста внутри HTA yes, no
SHOWINTASKBAR showInTaskBar Отображать ли в панели задач yes, no
SINGLEINSTANCE singleInstance Запретить запуск второго экземпляра? no, yes
SYSMENU sysMenu Управляет наличием системного меню yes, no
VERSION version Версия HTA строка
WINDOWSTATE windowState Начальный размер окна normal, minimize, maximize

Как видно из таблицы, все параметры приложения (большинство в режиме read-only) доступны из скриптовых языков. Что бы было понятно, как это делается, приведу небольшой пример для applicationName: oHTA.applicationName (oHTA — ID, заданный в заголовке).

Отсутствие системы безопасности означает, что разработчику предоставлена полная свобода доступа к ActiveX, а значит файловой системе и WScript. Кроме того, программист имеет возможность, при помощи атрибута APPLICATION, явно указать содержимое какого из внутренних фреймов может получить доступ к объектам приложения: <IFRAME SRC=content.htm APPLICATION=yes>.

Исходя из концепции безбраузерного приложения, Microsoft исключила из HTA функцию автозаполнения (AutoComplete of form) и закрыла доступ к объекту external.

Более подробно о HTA (на английском языке) можно почитать на сайте Microsoft MSDN.

Оставить комментарий

О безопасности в Unix

О безопасности Unix-систем.

Сегодня побывал в шкуре киношного кул хацкера, из тех, что подбирают пароли с третьего раза. Правда, попыток я сделал побольше, да и пароль не подобрал… в общем, все по порядку.

Сидел я у нашего постмастера Сергея, консультировался по поводу мультидоменной настройки sendmail. Примерно на середине разговора нас прервали — зашел его начальник, Сергей ушел с ним забрать какие-то бумаги, естественно, заблокировав консоль. Решив хоть как себя занять, я сел за его компьютер и, в лучших традициях фильмов о хакерах, стал меланхолично забивать вместо пароля слова (9-тисимвольные, длину пароля я знал), написанные на кружках, часах, мониторах и прочих вещах, стоящих в пределах прямой видимости.

Примерно через 5—10 минут (я как раз вбивал какое-то нечитаемое наименование с коробки из-под монитора), система меня пустила… Думаете я подобрал пароль? Если бы. СИСТЕМА МЕНЯ ПУСТИЛА, но, как будет видно ниже, Я НЕ НАБРАЛ ПРАВИЛЬНЫЙ ПАРОЛЬ.

Теория о том, что совпала hash-сумма, или, что я нашел «инженерный» пароль, не подтвердилась. После прихода Сергея мы провели «следственный эксперимент» — он заблокировал консоль и ввел ту же комбинацию.

Так что единственное разумное объяснение, которое пришло мне в голову, заключается в следующем. Похоже разработчики включили в свой продукт одну недокументированную особенность — система пускает человека, который в течение долгого времени вводит парольные последовательности, некоторая часть которых совпадает по буквенному составу и/или длине с правильным паролем. «Cчитая», что хозяин забыл пароль.

Остается только догадываться, сколько еще таких «недокументированных возможностей» зашито в софт, которому мы привыкли доверять безопасность нашего компьютера.

4 комментария

Недокументированные… Окончание.

Вместо предисловия.

Сегодня Google выдал мне все-таки страницу, URL которой я так жаждал получить. На нем, английским по белому, написано, что теги NSCP_CLOSE, NSCP_OPEN, NSCP_REBLOCK, MQUOTE, CELL, SUBDOC, CERTIFICATE, INLINEINPUTTHICK, INLINEINPUTDOTTED, COLORMAP, HYPE, SPELL и NSDT более не поддерживаются.

Так что в списке подозреваемых на полезную нагрузку остались: CHARLES, JEAN, UNKNOWN и INPUT TYPE=JOT.

Внимательное изучение этой самой страницы увеличило вышеприведенный список еще на два экземпляра: INPUT TYPE=READONLY и INPUT TYPE=OBJECT. Что означает первый, стало понятно после полевого испытания — создается текстовое поле, которое нельзя редактировать. Для чего служит второй, станет понятно ниже. Кроме того, на той же странице я с удивлением узнал, что у тега INPUT есть атрибут HEIGHT.

Все вышеперечисленное вдохнуло в меня новые силы и я, с утроенной энергией, взялся за поисковые машины…

Через пару минут поиска, видимо найдя все-таки с Google общий язык, я нашел остальную интересующую меня информацию, перевод и компиляцию которой я размещаю ниже.

Атрибут JOT предназначен для вывода поля перьевого ввода произвольного размера (атрибут SIZE="xsize,ysize"), размер по умолчанию 200×50, перешел в Netscape, судя по всему, из браузера Mosaic. Используется совместно с атрибутом SRC.

OBJECT создает невизуальный элемент формы для сбора данных от заданного Java-компонента, расположенного на странице. Java-компонент задается при помощи атрибута NAME, который должен быть равен атрибуту ID предыдущего объявления компонента. Его данные попадут на сервер когда пользователь нажмет на кнопку SUBMIT (немного сумбурный перевод, но, думаю, смысл ясен).

Чтение исходников (спасибо AllTheWeb) показало, что тег UNKNOWN — никакой не тег, а абстрактное обозначение любого неизвестного тега, встречающегося в заголовке документа. Сделан этот финт ушами для пропуска контента неизвестных контейнеров. CHARLES и JEAN — это не что иное, как загадочные, но уже не поддерживаемые «теги» INLINEINPUTDOTTED и INLINEINPUTTHICK.

Теги, начинающиеся с букв NSCP были предназначены для внутренних целей браузера, в частности, NSCP_CLOSE закрывал все незакрытые теги, что позволяло «сливать» воедино два незавершенных документа.

Из тех же исходников, кстати, видно, что побочным действием тега HR является закрытие блочного тега P, что действительно имеет место.

Что касается тега COLORMAP, то тут не все так кристально ясно. Это, безусловно, тег, что подтверждает чтение исходников, у него есть атрибут SRC и нет закрывающей пары. Судя по комментариям в коде, этот тег задает карту цвета, которая будет использоваться для всех картинок страницы. Но для чего это нужно, и каков формат этой карты ссылок — неясно. Кроме того сама, процедура обработки тега стоит под #IFNDEF, так что непонятно, работает он в текущей версии Netscape или отключен.

Тег HYPE был введен «just for fun» и работает (-ал), судя по исходникам, только на Mac и Unix-платформах.

Из других любопытных открытий — существование атрибута SUPPRESS, который заставляет (его значения — TRUE и FALSE) тег LAYER игнорировать свое содержимое до закрывающей пары и того же атрибута у тега A (anchor), только с другим значением — его использование ведет к появлению рамки вокруг ссылки в момент нажатия, как в MSIE. Только непонятно, исходники какой из версий я смотрел — одной из будущих, или какой-то из прошлых, потому что в текущей это не работает.

В общем, я остался доволен сегодняшним результатом поиска. :) И хотя, остались еще кое-какие мелкие вопросы, я уже порядком подустал, так что объявляю свое виртуальное расследование завершенным.

Оставить комментарий

← 1 62 63 64 65 66 67 →