Spec-Zone.ru › Perl 5.34

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. Но поскольку эти две функции являются частью спецификации 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.34.0/perlclib

Spec-Zone.ru

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