Spec-Zone.ru › Perl 5.36

perlclib

СОДЕРЖАНИЕ

  • ИМЯ
  • ОПИСАНИЕ
    • Соглашения
    • Операции с файлами
    • Ввод и вывод файлов
    • Позиционирование в файле
    • Управление памятью и обработка строк
    • Тестирование на принадлежность к классу символов
    • Функции из stdlib.h
    • Разные функции
  • СМОТРИТЕ ТАКЖЕ

ИМЯ

perlclib - Внутренние замены функций стандартной библиотеки C

ОПИСАНИЕ

Perl-разработчики должны помнить, что perl не так часто использует стандартную библиотеку C; вы увидите очень мало использования, например, функций из ctype.h. Это потому, что Perl обычно переопределяет или абстрагирует функции стандартной библиотеки, чтобы точно знать, как они будут работать.

Это справочная карточка для людей, знакомых с библиотекой C, которые хотят делать вещи по-Perl'ски; чтобы сказать им, какие функции следует использовать вместо обычных функций C.

Соглашения

В следующих таблицах:

t

— это тип.

p

— это указатель.

n

— это число.

s

— это строка.

sv, av, hv, и т. д. представляют переменные соответствующих типов.

Операции с файлами

Вместо функций из stdio.h следует использовать Perl-абстракцию. Вместо типов FILE*, вам нужно работать с типами PerlIO*. Не забывайте, что с новой PerlIO-абстракцией ввода-вывода слоёв типы FILE* могут вообще быть недоступны. Также см. документацию по perlapio, чтобы узнать больше о следующих функциях:

Instead Of:                 Use:

stdin                       PerlIO_stdin()
stdout                      PerlIO_stdout()
stderr                      PerlIO_stderr()

fopen(fn, mode)             PerlIO_open(fn, mode)
freopen(fn, mode, stream)   PerlIO_reopen(fn, mode, perlio) (Dep-
                              recated)
fflush(stream)              PerlIO_flush(perlio)
fclose(stream)              PerlIO_close(perlio)

Ввод и вывод файлов

Instead Of:                 Use:

fprintf(stream, fmt, ...)   PerlIO_printf(perlio, fmt, ...)

[f]getc(stream)             PerlIO_getc(perlio)
[f]putc(stream, n)          PerlIO_putc(perlio, n)
ungetc(n, stream)           PerlIO_ungetc(perlio, n)

Обратите внимание, что PerlIO-аналоги fread и fwrite немного отличаются от функций стандартной библиотеки C:

fread(p, size, n, stream)   PerlIO_read(perlio, buf, numbytes)
fwrite(p, size, n, stream)  PerlIO_write(perlio, buf, numbytes)

fputs(s, stream)            PerlIO_puts(perlio, s)

Нет эквивалента fgets; следует использовать sv_gets:

fgets(s, n, stream)         sv_gets(sv, perlio, append)

Позиционирование в файле

Instead Of:                 Use:

feof(stream)                PerlIO_eof(perlio)
fseek(stream, n, whence)    PerlIO_seek(perlio, n, whence)
rewind(stream)              PerlIO_rewind(perlio)

fgetpos(stream, p)          PerlIO_getpos(perlio, sv)
fsetpos(stream, p)          PerlIO_setpos(perlio, sv)

ferror(stream)              PerlIO_error(perlio)
clearerr(stream)            PerlIO_clearerr(perlio)

Управление памятью и обработка строк

Instead Of:                    Use:

t* p = malloc(n)               Newx(p, n, t)
t* p = calloc(n, s)            Newxz(p, n, t)
p = realloc(p, n)              Renew(p, n, t)
memcpy(dst, src, n)            Copy(src, dst, n, t)
memmove(dst, src, n)           Move(src, dst, n, t)
memcpy(dst, src, sizeof(t))    StructCopy(src, dst, t)
memset(dst, 0, n * sizeof(t))  Zero(dst, n, t)
memzero(dst, 0)                Zero(dst, n, char)
free(p)                        Safefree(p)

strdup(p)                      savepv(p)
strndup(p, n)                  savepvn(p, n) (Hey, strndup doesn't
                                              exist!)

strstr(big, little)            instr(big, little)
strcmp(s1, s2)                 strLE(s1, s2) / strEQ(s1, s2)
                                             / strGT(s1,s2)
strncmp(s1, s2, n)             strnNE(s1, s2, n) / strnEQ(s1, s2, n)

memcmp(p1, p2, n)              memNE(p1, p2, n)
!memcmp(p1, p2, n)             memEQ(p1, p2, n)

Обратите внимание на разный порядок аргументов для Copy и Move по сравнению с memcpy и memmove.

В большинстве случаев вам нужно будет работать с внутренними SVs, а не со строками char *.

strlen(s)                   sv_len(sv)
strcpy(dt, src)             sv_setpv(sv, s)
strncpy(dt, src, n)         sv_setpvn(sv, s, n)
strcat(dt, src)             sv_catpv(sv, s)
strncat(dt, src)            sv_catpvn(sv, s)
sprintf(s, fmt, ...)        sv_setpvf(sv, fmt, ...)

Также обратите внимание на существование sv_catpvf и sv_vcatpvfn, объединяющих конкатенацию со форматированием.

Иногда вместо обнуления выделенной кучи с помощью Newxz() следует рассмотреть "отравление" данных. Это означает запись в него битового шаблона, который должен быть недопустимым как указатель (и числа с плавающей точкой), а также, надеюсь, достаточно необычным как целые числа, так что любой код, пытающийся использовать данные без продуманности, сломается скорее раньше, чем позже. Отравление можно выполнить с помощью макросов Poison(), имеющих аналогичные аргументы, как Zero():

PoisonWith(dst, n, t, b)    scribble memory with byte b
PoisonNew(dst, n, t)        equal to PoisonWith(dst, n, t, 0xAB)
PoisonFree(dst, n, t)       equal to PoisonWith(dst, n, t, 0xEF)
Poison(dst, n, t)           equal to PoisonFree(dst, n, t)

Тестирование на принадлежность к классу символов

Perl реализует несколько типов тестов принадлежности к классу символов. Здесь описаны только те, что напрямую соответствуют функциям библиотеки C, работающим с 8-битными символами, но есть аналоги, работающие с широкими символами и строками UTF-8. Все они более подробно описаны в "Классификация символов" в perlapi и "Преобразование регистра символов" в perlapi.

Функции библиотеки C, представленные в таблице ниже, возвращают значения, основанные на текущем локали. Используйте записи в последнем столбце для этой функциональности. Два других столбца всегда предполагают POSIX (или C) локаль. Записи в столбце ASCII имеют смысл только для входных данных ASCII, возвращая FALSE для чего-либо ещё. Используйте их только тогда, когда вы **точно** знаете, что хотите. Записи в столбце Latin1 предполагают, что не-ASCII 8-битные символы определены так же, как Unicode, так же, как ISO-8859-1, часто называемый Latin 1.

Instead Of:  Use for ASCII:   Use for Latin1:      Use for locale:

isalnum(c)  isALPHANUMERIC(c) isALPHANUMERIC_L1(c) isALPHANUMERIC_LC(c)
isalpha(c)  isALPHA(c)        isALPHA_L1(c)        isALPHA_LC(u )
isascii(c)  isASCII(c)                             isASCII_LC(c)
isblank(c)  isBLANK(c)        isBLANK_L1(c)        isBLANK_LC(c)
iscntrl(c)  isCNTRL(c)        isCNTRL_L1(c)        isCNTRL_LC(c)
isdigit(c)  isDIGIT(c)        isDIGIT_L1(c)        isDIGIT_LC(c)
isgraph(c)  isGRAPH(c)        isGRAPH_L1(c)        isGRAPH_LC(c)
islower(c)  isLOWER(c)        isLOWER_L1(c)        isLOWER_LC(c)
isprint(c)  isPRINT(c)        isPRINT_L1(c)        isPRINT_LC(c)
ispunct(c)  isPUNCT(c)        isPUNCT_L1(c)        isPUNCT_LC(c)
isspace(c)  isSPACE(c)        isSPACE_L1(c)        isSPACE_LC(c)
isupper(c)  isUPPER(c)        isUPPER_L1(c)        isUPPER_LC(c)
isxdigit(c) isXDIGIT(c)       isXDIGIT_L1(c)       isXDIGIT_LC(c)

tolower(c)  toLOWER(c)        toLOWER_L1(c)
toupper(c)  toUPPER(c)

Чтобы подчеркнуть, что вы работаете только с ASCII-символами, вы можете добавить _A к каждому из макросов в столбце ASCII: isALPHA_A, isDIGIT_A, и так далее.

(Нет записи в столбце Latin1 для isascii, хотя есть isASCII_L1, который идентичен isASCII; последнее имя более понятно. Нет записи в столбце Latin1 для toupper, потому что результат может быть не Latin1. Вам нужно использовать toUPPER_uvchr, как описано в "Преобразование регистра символов" в perlapi.)

Функции из stdlib.h

Instead Of:                 Use:

atof(s)                     Atof(s)
atoi(s)                     grok_atoUV(s, &uv, &e)
atol(s)                     grok_atoUV(s, &uv, &e)
strtod(s, &p)               Strtod(s, &p)
strtol(s, &p, n)            Strtol(s, &p, b)
strtoul(s, &p, n)           Strtoul(s, &p, b)

Типичное использование - выполнение проверок диапазона на uv перед преобразованием:

int i; UV uv;
char* end_ptr = input_end;
if (grok_atoUV(input, &uv, &end_ptr)
    && uv <= INT_MAX)
  i = (int)uv;
  ... /* continue parsing from end_ptr */
} else {
  ... /* parse error: not a decimal integer in range 0 .. MAX_IV */
}

Обратите также внимание на функции grok_bin, grok_hex и grok_oct в numeric.c для преобразования строк, представляющих числа в указанных системах счисления, в NV. Обратите внимание, что grok_atoUV() не обрабатывает отрицательные входные данные или ведущие пробелы (намеренно строгий).

Обратите внимание, что strtol() и strtoul() могут быть замаскированы как Strtol(), Strtoul(), Atol(), Atoul(). Избегайте и их.

В теории Strtol и Strtoul могут не быть определены, если машина, на которой построен perl, не имеет strtol и strtoul. Но поскольку эти 2 функции входят в спецификацию ANSI C 1989, мы предполагаем, что вы их найдёте практически везде.

int rand()                  double Drand01()
srand(n)                    { seedDrand01((Rand_seed_t)n);
                              PL_srand_called = TRUE; }

exit(n)                     my_exit(n)
system(s)                   Don't. Look at pp_system or use my_popen.

getenv(s)                   PerlEnv_getenv(s)
setenv(s, val)              my_setenv(s, val)

Разные функции

Вам даже **не следует** использовать функции из setjmp.h, но если вы считаете, что это необходимо, используйте стек JMPENV в scope.h вместо этого.

Для signal/sigaction используйте rsignal(signo, handler).

СМОТРИТЕ ТАКЖЕ

perlapi, perlapio, perlguts

© 1993–2021 Larry Wall and others
Licensed under the GNU General Public License version 1 or later, or the Artistic License.
The Perl logo is a trademark of the Perl Foundation.
https://perldoc.perl.org/5.36.0/perlclib

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API