The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NOMBRE

perlclib - Sustitutos internos de funciones de la biblioteca estándar de C

DESCRIPCIÓN

Los miembros del equipo de desarrollo principal (Perl porters) deben tener en cuenta que en perl no se usa mucho la biblioteca estándar de C internamente; por ejemplo, ctype.h se usa muy poco. Esto se debe a que en el desarrollo de Perl se ha seguido la tendencia de reimplementar o abstraer funciones de la biblioteca estándar, para controlar cómo van a funcionar exactamente.

Este documento es una hoja de referencia para programadores que conocen la biblioteca de C y desean hacer las cosas al estilo de Perl. Indica las funciones que deben usar en lugar de las funciones de C de uso común.

Convenciones

En las tablas siguientes:

t

es un tipo.

p

es un puntero.

n

es un número.

s

es una cadena.

sv, av, hv, etc. representan variables de sus tipos respectivos.

Operaciones con archivos

En lugar de las funciones de stdio.h debe usar la abstracción de capas de Perl. En lugar de tipos FILE* debe manipular tipos PerlIO*. No olvide que con PerlIO, la nueva abstracción de E/S en capas, los tipos FILE* podrían no estar disponibles. Vea también la documentación de perlapio para obtener más información acerca de las siguientes funciones:

    En lugar de:                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) (obsoleta)
    fflush(stream)              PerlIO_flush(perlio)
    fclose(stream)              PerlIO_close(perlio)

Entrada/salida de archivo

    En lugar de:                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)

Tenga en cuenta que en PerlIO las funciones equivalentes a fread y fwrite son ligeramente distintas de sus homólogas de la biblioteca de 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)

No existe nada equivalente a fgets; en su lugar, debe usar sv_gets:

    fgets(s, n, stream)         sv_gets(sv, perlio, append)

Posición en archivo

    En lugar de:                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)

Administración de memoria y manipulación de cadenas

    En lugar de:                        Use:

    t* p = malloc(n)                    Newx(id, p, n, t)
    t* p = calloc(n, s)                 Newxz(id, 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) (Atención: strndup no existe)

    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)

Observe que el orden de los argumentos de Copy y Move es distinto del de los argumentos de memcpy y memmove.

Sin embargo, generalmente deseará manipular valores SV internamente, en lugar de manipular cadenas char * sin procesar:

    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, ...)

Tenga en cuenta que también están disponibles sv_catpvf y sv_vcatpvfn, que combinan la concatenación con la aplicación de formato.

A veces, en lugar de inicializar en cero el montículo (heap) asignado mediante Newxz(), podría preferir la opción de "envenenar" los datos. El envenenamiento de datos consiste en escribir en los datos un patrón de bits que no que sean válidos como punteros (ni como números de punto flotante), ni (esperamos que de forma sorprendente) como enteros, a fin de que todo código que intente usar los datos sin la preparación necesaria genere un error cuanto antes. El envenenamiento se puede realizar mediante las macros Poison(), que tienen argumentos similares a los de Zero():

    PoisonWith(dst, n, t, b)    "garabatea" el byte b en la memoria
    PoisonNew(dst, n, t)        igual que PoisonWith(dst, n, t, 0xAB)
    PoisonFree(dst, n, t)       igual que PoisonWith(dst, n, t, 0xEF)
    Poison(dst, n, t)           igual que PoisonFree(dst, n, t)

Pruebas de clases de caracteres

Perl implementa dos tipos de pruebas de clases de caracteres: las de un tipo usan variables char y, por tanto, no son compatibles con Unicode (y, en consecuencia, son obsoletas a menos que esté seguro de que debe usarlas) y las del otro tipo usan variables UV y saben lo que son las propiedades Unicode. En la tabla siguiente, c es un char y u es un código de carácter Unicode.

    En lugar de:                Use:            O mejor:

    isalnum(c)                  isALNUM(c)      isALNUM_uni(u)
    isalpha(c)                  isALPHA(c)      isALPHA_uni(u)
    iscntrl(c)                  isCNTRL(c)      isCNTRL_uni(u)
    isdigit(c)                  isDIGIT(c)      isDIGIT_uni(u)
    isgraph(c)                  isGRAPH(c)      isGRAPH_uni(u)
    islower(c)                  isLOWER(c)      isLOWER_uni(u)
    isprint(c)                  isPRINT(c)      isPRINT_uni(u)
    ispunct(c)                  isPUNCT(c)      isPUNCT_uni(u)
    isspace(c)                  isSPACE(c)      isSPACE_uni(u)
    isupper(c)                  isUPPER(c)      isUPPER_uni(u)
    isxdigit(c)                 isXDIGIT(c)     isXDIGIT_uni(u)

    tolower(c)                  toLOWER(c)      toLOWER_uni(u)
    toupper(c)                  toUPPER(c)      toUPPER_uni(u)

Funciones de stdlib.h

    En lugar de:                Use: 

    atof(s)                     Atof(s)
    atol(s)                     Atol(s)
    strtod(s, &p)               Ninguna. No la use.
    strtol(s, &p, n)            Strtol(s, &p, n)
    strtoul(s, &p, n)           Strtoul(s, &p, n)

También están disponibles las funciones grok_bin, grok_hex y grok_oct de numeric.c para convertir cadenas que representan números en sus respectivas bases en valores NV.

En teoría, Strtol y Strtoul no se pueden definir si el equipo en el que se ha compilado perl no dispone de strtol y strtoul. Pero como estas dos funciones forman parte de la especificación de ANSI C del año 1989, sospechamos que actualmente estarán disponibles en todas partes.

    int rand()                  double Drand01()
    srand(n)                    { seedDrand01((Rand_seed_t)n); 
                                  PL_srand_called = TRUE; }

    exit(n)                     my_exit(n)
    system(s)                   No la use. Vea pp_system o use my_popen

    getenv(s)                   PerlEnv_getenv(s)
    setenv(s, val)              my_putenv(s, val)

Funciones varias

Ni se le ocurra usar las funciones de setjmp.h. Si esto no le disuade de sus intenciones, al menos plantéese usar la pila JMPENV de scope.h en su lugar.

Para signal/sigaction, use rsignal(signo, handler).

VEA TAMBIÉN

perlapi, perlapio, perlguts

TRADUCTORES

  • Joaquín Ferrero (Tech Lead)

  • Enrique Nell (Language Lead)