Spec-Zone.ru › Perl 5.28

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)        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)               Nothing.  Just don't use it.
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;
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–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.28.3/perlclib

Spec-Zone.ru

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