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.
Большую часть времени вам нужно работать с SV внутри, а не с сырыми 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) toLOWER_LC(c)
toupper(c) toUPPER(c) toUPPER_LC(c) Чтобы подчеркнуть, что вы работаете только с ASCII символами, можно добавить _A к каждому из макросов в столбце ASCII: isALPHA_A, isDIGIT_A, и так далее.
(В столбце Latin1 нет записи для isascii, хотя есть isASCII_L1, которая идентична isASCII; последнее имя более понятно. В столбце Latin1 нет записи для toupper потому что результат может быть не-Latin1. Вам нужно использовать toUPPER_uni, как описано в "Изменение регистра символов" в 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) my_atof3(s, &nv, &p) is the closest we have
strtol(s, &p, n) grok_atoUV(s, &uv, &e)
strtoul(s, &p, n) grok_atoUV(s, &uv, &e) Типичное использование — проверка диапазона 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).
СМОТРИТЕ ТАКЖЕ
© 1993–2020 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.30.3/perlclib