Spec-Zone.ru › Perl 5.32

perlclib

СОДЕРЖАНИЕ

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

ИМЯ

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

ОПИСАНИЕ

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

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

Соглашения

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

t

— тип.

p

— указатель.

n

— число.

s

— строка.

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

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

Вместо функций из stdio.h следует использовать перловский абстрактный уровень. Вместо типов 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)

Обратите внимание, что перловские аналоги 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)        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)               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–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.32.0/perlclib

Spec-Zone.ru

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