perlclib
СОДЕРЖАНИЕ
ИМЯ
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).
СМОТРИТЕ ТАКЖЕ
© 1993–2023 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.38.0/perlclib