Marcado como: C Ativar/desativar aninhamento de comentários | Atalhos do Teclado

  • Fm4lloc 9:35 pm em 25 de April de 2015 Link Permanente | Resposta
    Tags: C, , , , parser, url   

    Simple parse-url in C 

    Simples URL parser que escrevi em C para exercitar o uso de expressões regulares.

    Modo de usar: ./parseurl url

    Exemplo de uso:

    $ ./parseurl 'scheme://username:password@subdomain.domain.tld:80/path/file-name.suffix?query-string#hash'
    

    Saída:

    +SCHEME: scheme
    +AUTHORITY: username:password@subdomain.domain.tld:80
     +USERINFO: username:password
      -USERNAME: username
      -PASSWORD: password
     -HOST: subdomain.domain.tld
     -PORT: 80
      +PATH: /path/file-name.suffix
       -FILENAME: file-name.suffix
       -QUERY: query-string
       -FRAGMENT: hash
    

    O código esta no Github. Para baixar use o comando:

    $ git clone https://github.com/fm4lloc/parse-url.git
    

    ou acesse a página https://github.com/fm4lloc/parse-url

    Após o download do código entre na pasta parse-url e compile.

    $ cd ./parse-url && make
    

    Recomendo ler esse post que escrevi sobre expresões regulares para entender melhor o funcionamento do programa: https://fm4lloc.wordpress.com/2014/01/06/usando-expressoes-regulares-em-c/

    Anúncios
     
  • Fm4lloc 4:10 pm em 2 de February de 2015 Link Permanente | Resposta
    Tags: C, encoder, , projeto   

    Projeto Cryptus 

    Sobre o projeto

    Cryptus é um multi-encoder que estou escrevendo em C. A ideia nasceu com um script arcaico feito em Perl contendo características parecidas, gostei tanto dele que achei interessante criar algo mais robusto e com uma interface gráfica.

    O Cryptus foi publicado no github, muitas funções já então funcionando, nos meus tempos livres estarei atualizando o código.

    https://github.com/fm4lloc/cryptus

    cryptus

    Como compilar no Debian e derivados

    1. Instale as dependências:

    $ sudo apt-get install build-essential pkg-config libgtk2.0-dev libgdk-pixbuf2.0-dev libssl-dev git
    

    2. Obtenha os sources:

    $ git clone https://github.com/fm4lloc/cryptus.git
    $ cd ./cryptus
    

    3. Compile:

    $ make
    
     
    • ZACHARiAS 10:23 am em 24 de fevereiro de 2015 Link Permanente | Resposta

      oi, bom dia.
      encoder de quê comopanheiro? obrigado por seguires o meu cantinho também.

      • fm4lloc 8:44 pm em 17 de abril de 2015 Link Permanente | Resposta

        É um multi-encoder de strings. É usado para codificar e criptografar strings. Também conta com ferramentas variadas e de utilidade rotineira para ofuscar scripts, links e textos em geral.

        Ainda estou escrevendo! Não esta 100% funcional.

  • Fm4lloc 10:32 pm em 27 de January de 2015 Link Permanente | Resposta
    Tags: C, generico, makefile   

    Makefile genérico para projetos pequenos 

    Escrever Makefiles para projetos pequenos em C no Linux é uma tarefa cansativa, naqueles onde os arquivos estão jogados em varias pastas é pior. A minha ideia foi agilizar essas compilações escrevendo um Makefile bem genérico e que consiga entrar em sub-diretórios, construir vários arquivos e juntar tudo. O trabalho é esta obra prima do horror, munida de más praticas.

    Nota: Crie uma pasta chamada src para colocar os arquivos-fonte do seu projeto. O Makefile fica no mesmo diretório dela.

    Observe:
    tree

    # Simple generic Makefile 1.0 - (Fm4lloc)
    #
    # ======================================================================
    # This Makefile was written with bad practices. Not recommend  using 
    # it on big projects.
    # ======================================================================
    #
     
    #-----------------------------------------------------------------------
    # EDIT HERE
    #-----------------------------------------------------------------------
    RM          = /bin/rm -f
    CC          = gcc
    DEFS        = -O3 -Wall -fmessage-length=0
    PROGNAME    = generic
    INCLUDES    = 
    LIBS        = 
    #-----------------------------------------------------------------------
     
    DEFINES     = $(INCLUDES) $(DEFS)
    CFLAGS      = $(DEFINES)
     
    SRC         = $(wildcard src/*.c) $(wildcard src/**/*.c)
    HEADERS     = $(wildcard src/*.h) $(wildcard src/**/*.h)
    OBJS        = $(SRC:.c=.o)
     
    DATE        = $(shell date +%Y-%d-%m)
     
    .c.o:
        @echo 'Building file: $<'
        @echo 'Invoking: Cross GCC Compiler'
        $(CC) $(CFLAGS) -c $*.c -o $*.o
        @echo 'Finished building: $<'
        @echo ' '
         
    all: $(PROGNAME)
     
    $(PROGNAME) : $(OBJS)
        @echo 'Building target: $@'
        @echo 'Invoking: Cross GCC Linker'
        $(CC) $(LIBS) $(OBJS) -o $(PROGNAME)
        @echo 'Finished building target: $@'
        @echo ' '
         
    .PHONY: clean tar
    clean:
        $(RM) $(PROGNAME) $(OBJS)
        @echo ' '
         
    tar:
        tar cvjf $(PROGNAME)_src_$(DATE).tar.bz2 $(SRC) $(HEADERS) Makefile
        @echo ' '
    
     
  • Fm4lloc 6:57 pm em 5 de February de 2014 Link Permanente | Resposta
    Tags: C, , examplo, gnome, libxml2, , mit, opensource, parse, parsing, xml   

    Analisando arquivos XML locais e remotos com libxml2. 

    libxml2 é uma biblioteca de software feita para  analisar documentos XML , escrita em C e disponibilizada sob a licença MIT. Mesmo construído em  C, fornece “ligações” para outras linguagens.

    A biblioteca também é conhecida pela portabilidade, compilação fácil e alta velocidade.

    A instalação através dos repositórios do Debian fica:

    $ sudo apt-get install libxml2-dev
    

    O código abaixo foi escrito para analisar arquivos remotos ou locais, ele fazia parte de um projeto que eu estava desenvolvendo para buscar músicas no site 4shared, mas foi descontinuado.

    Como a postagem não trata-se de tutorial, vou dispensar as explicações. O código é pequeno e de fácil compreensão após breve exercício mental.

    Recomendo a leitura da documentação oficial da libxml2.

    Para compilar:

    $ gcc $(xml2-config --cflags --libs) ./parse.c -o ./parse
    

    O layout do arquivo XML analisado pelo código é:

    <!-- ROOT -->
    <search-result>
    	<!-- MAIN -->
    	<query/>
    	<total-files>8975</total-files>
    	<page-number>1</page-number>
    	<pages-total>897</pages-total>
    	<start>0</start>
    	<files-per-page>10</files-per-page>
    	<files-approx-count>16219367</files-approx-count>
    	<!-- FILE -->
    	<result-files>
    		<file>
    			<name>Foo</name>
    		</file>
    		<file>
    			<name>Bar</name>
    		</file>
    		<file>
    			<name>Qux</name>
    		</file>
    	</result-files>
    </search-result>
    

    O mesmo modelo é usado no documento gerado na página: https://search.4shared.com/network/searchXml.jsp

    O programa:

    #include <stdio.h>
    #include <stdlib.h>
     
    #include <libxml/tree.h>
    #include <libxml/parser.h>
     
    /*
     * Copyright (C) 2014 Fm4lloc <fm4lloc@gmail.com>
     *
     * This program is free software: you can redistribute it and/or modify
     * it under the terms of the GNU General Public License as published by
     * the Free Software Foundation, either version 3 of the License, or
     * (at your option) any later version.
     *
     */
     
    void cleanAll(xmlDocPtr doc)
    {
        xmlFreeDoc (doc);
        /*
         * Free the global variables that may
         * have been allocated by the parser.
         */
        xmlCleanupParser ();
    }
     
    void printXmlContent (xmlDocPtr doc, xmlNodePtr cur)
    {
        xmlChar *key = NULL;
     
        if ((key = xmlNodeListGetString (doc,
            cur->xmlChildrenNode, 1)))
        {
            printf("%s\n", key);
            xmlFree (key);
        }
    }
     
    static void eachFile (xmlDocPtr doc, xmlNodePtr cur)
    {
        cur = cur->xmlChildrenNode;
        while (cur != NULL)
        {
            /* <search-result>
             *      ...
             *      <result-files>
             *          <file>
             *              <name>
             */
            if ((!xmlStrcmp (cur->name, (const xmlChar *) "name")))
                printXmlContent (doc, cur);
     
            cur = cur->next;
        }
    }
     
    static void parseFile (xmlDocPtr doc, xmlNodePtr cur)
    {
        cur = cur->xmlChildrenNode;
        while (cur != NULL)
        {
            if ((!xmlStrcmp (cur->name, (const xmlChar *) "file")))
                eachFile (doc, cur);
     
            cur = cur->next;
        }
    }
     
    static void parseMainInfo (xmlDocPtr doc, xmlNodePtr cur)
    {
        cur = cur->xmlChildrenNode;
        while (cur != NULL)
        {
                if (cur->type == XML_ELEMENT_NODE)
                {
                    /* Stop when you find the node: result-files */
                    if ((!xmlStrcmp (cur->name, (const xmlChar *) "result-files")))
                        break;
     
                    printXmlContent (doc, cur);
                }       
     
            cur = cur->next;
        }
    }
     
    /**
     * parseDoc:
     * @filename: A filename or an URL
     *
     * Parse XML
     *
     * Returns int
     */
    static int parseDoc (const char *filename)
    {
        xmlDocPtr  doc = NULL;
        xmlNodePtr cur = NULL;
     
        doc = xmlReadFile (filename, NULL, 0);
        if (doc == NULL)
        {
                fprintf (stderr, "Document not parsed.\n");
                return 1;
        }
     
        /* Get the root element node */
        cur = xmlDocGetRootElement(doc);
        if (cur == NULL)
        {
                fprintf (stderr,"empty document\n");
                cleanAll (doc);
                return 1;
        }
     
        /* Check if node root == "search-result" */
        if (xmlStrcmp (cur->name, (const xmlChar *) "search-result"))
        {
                fprintf (stderr,"document of the wrong type, root node != %s\n", cur->name);
                cleanAll (doc);
                return 1;
        }
     
        /* <search-result> */
        parseMainInfo (doc, cur);
     
        /* <search-result>
         *      ...
         *      <result-files> */
        cur = cur->xmlChildrenNode;
        while (cur != NULL)
        {
            if ((!xmlStrcmp (cur->name, (const xmlChar *) "result-files")))
            {
            /* <search-result>
             *      <result-files>
             *          <file>
             */
                parseFile (doc, cur);
            }
     
            cur = cur->next;
        }
     
        cleanAll (doc);
     
        return 0;
    }
     
    int main(void)
    {
        if (parseDoc ("./content.xml") != 0)
            return -1;
     
        return 0;
    }
    

    Saída padrão:

    8975
    1
    897
    0
    10
    16219367
    Foo
    Bar
    Qux
    
     
  • Fm4lloc 4:34 am em 6 de January de 2014 Link Permanente | Resposta
    Tags: artigo, C, , exemplos, expressão regular, expression, , open source, regex, regexp, regular, tutorial   

    Usando expressões regulares em C 

    O presente artigo procura explicar o uso de expressões regulares em conjunto com a linguagem C, desmistificando funções e ensinando a extrair o máximo delas. Adianto que a leitura não é recomendado para elite programmers ou iniciantes, mas pessoas com conhecimento prévio em expressões regulares.

    Definir regras e encontrar padrões demandam códigos extensos e de difícil manutenção. As expressões regulares aparecem é nesse cenário, facilitando e transformando o raciocínio lógico do programador em uma composição de símbolos recheada de significados.

    É normal que programadores novatos ou pessoas que tiveram os primeiros contatos com expressões regulares em Perl, Python ou até mesmo PHP, sejam assombradas quando escultam o termo regex e C na mesma frase. Ocorre que as linguagens destacas anteriormente, com exceção de C, além de serem interpretadas, nasceram prontas para trabalhar com o melhor que concerne a expressões regulares.

     

    O PRIMEIRO CÓDIGO

    O código ulterior compila a expressão e testa se a string casa com um padrão.

    #include <stdio.h>
    #include <regex.h>
    
    /*
     *  Written by: fm4lloc <fm4lloc@gmail.com>
     *
     *  This program is free software; you can redistribute it and/or modify
     *  it under the terms of the GNU General Public License as published by
     *  the Free Software Foundation; either version 2 of the License, or
     *  (at your option) any later version.
     *
     */
    
    int main ()
    {
    	regex_t preg;
    	reg_errcode_t err;
    	const char regex[]  = "^(([^:/?#]+):)?"       \
    						  "(//([^/?#]*))?"        \
    						  "([^?#]*)(\\?([^#]*))?" \
    						  "(#(.*))?"; 
    
    	const char string[]	= "https://fm4lloc.wordpress.com/";
    
    	if ( ( err = regcomp (&preg, regex, REG_EXTENDED|REG_NOSUB) ) != REG_NOERROR)
    		return err;
    
    	if ( (err = regexec (&preg, string, 0 , NULL, 0 ) ) != REG_NOERROR )
    		printf ("No match!");
    	else
    		printf ("Match!");
    
    	regfree (&preg);
    	return 0;
    }
    

    A função regcomp () compila a expressão.
    Esta é a declaração de regcomp ():

    int regcomp(regex_t *preg, const char *regex, int cflags);
    

    *preg é um ponteiro para pattern buffer, ele aponta para o bloco de memória contento o padrão de pesquisa preparado por regcomp () através dos parâmetros fornecidos.

    *regex aponta para um vetor de char contento a expressão regular, enquanto cflags é utilizado para determinar o tipo de compilação através de flags.

    As flags são:

    REG_EXTENDED Usa o padrão POSIX Expressão Regulares Estendidas na interpretação da regex. Quando ela é usada os metacaracteres não precisam ser escapados com a barra invertida (\) para serem identificados. O escape é usado apenas para transformar metacaractere em literal.
    O uso da flag permite isso:

    ^(a.*)$

    Quando omitida, a expressão é tratada através do padrão POSIX Expressões Regulares Básicas. Esse padrão necessita do uso de barras invertidas para a identificação dos metacaracteres.

    ^\\(a.*\\)$

    Recomendo estes links para aprofundar no tema:
    Link1
    Link2

    REG_ICASE Não diferencia letras maiúsculas de minúsculas.
    REG_NOSUB Ignora suporte aos parâmetros nmatch e pmatch usados pela função regexec().Esta flag é fixada quando se deseja apenas testar a entrada de dados com um padrão sem coletar informações adicionais.
    REG_NEWLINE Trata a entrada de dados com várias linhas individualmente.
    Exemplo:

    char string[] = “Olá\nMundo”;
    
    const char regex[] = "^O(.*)$";
    

    Como a entrada possui quebra de linha, a palavra “Olá” e “Mundo” são tratadas individualmente.

    Se omitida, a entrada será tratada como um todo, resultando em “Olá\\nMundo”.

    Voltando a explicação do código, a função regexec() avalia e busca os dados correspondentes a expressão.

    A declaração é:

    int regexec(const regex_t *preg, const char *string,
    		size_t nmatch, regmatch_t pmatch[], int eflags);
    
    *preg Ponteiro para pattern buffer.
    *string Ponteiro para os dados de entrada.
    nmatch Número de matchs, isto é, quantidade casada.
    *pmach[] Ponteiro para um array de regmatch_t.
    eflags
    REG_NOTBOL Ignora o metacaractere circunflexo ‘^’ (inicio de linha).
    REG_NOTEOL Ignora o metacaractere cifrão ‘$’ (final da linha)

    A estrutura de *pmach[] guarda em seus elementos informações sobre o casamento.

    A declaração de regmatch_t em regex.h é:

    typedef struct
    {
    	/* Posição do primeiro byte da sub-string casada
    	 */
    	regoff_t rm_so;
    
    	/* Posição do último byte da sub-string casada
    	 */
    	regoff_t rm_eo;
    } regmatch_t;
    

    A última função presente no código em analise é regfree (), que liberar o pattern buffer.

    Declaração:

    void regfree(regex_t *preg);
    

     

    EXIBINDO AS SUB-STRINGS ENCONTRADAS

    Leia os comentários para entender o código, recomento que compile e faça alterações se achar valido.

    #include <stdio.h>
    #include <stdlib.h>
    #include <regex.h>
    
    /*
     *  Written by: fm4lloc <fm4lloc@gmail.com>
     *
     *  This program is free software; you can redistribute it and/or modify
     *  it under the terms of the GNU General Public License as published by
     *  the Free Software Foundation; either version 3 of the License, or
     *  (at your option) any later version.
     *
     */
    
    int main ()
    {
    	regex_t preg;
    	reg_errcode_t err;
    	regmatch_t *pmatch = NULL;
    	size_t nmatch, i;
    
    	const char regex[]  =	"^(([^:/?#]+):)?"       \
    							"(//([^/?#]*))?"        \
    							"([^?#]*)(\\?([^#]*))?" \
    							"(#(.*))?";
    
    	const char string[]	= "https://fm4lloc.wordpress.com/";
    
    	if( ( err = regcomp (&preg, regex, REG_EXTENDED) ) != REG_NOERROR)
    		return err;
    
    	/*
    	 * Pega o número de matchs e aloca uma lista de regmatch_t.
    	 * ======================================================================
    	 * Soma-se 1 para obter a quantidade total de matchs, pois a
    	 * contagem inicia em zero.
    	 *
    	 * Os elementos contidos em pmatch[0] guardam a posição do primeiro
    	 * e último byte da string, os demais registros correspondem
    	 * aos grupos representados pelo metacaratere (parênteses).
    	 *
    	 * Cada sub-string é capturada por um grupo.
    	 */
    	nmatch = preg.re_nsub + 1;
    
    	/* aloca pmatch */
    	pmatch = (regmatch_t *) malloc (sizeof(regmatch_t) * nmatch);
    
    	if ( (err = regexec (&preg, string, nmatch , pmatch, 0 ) ) != REG_NOERROR )
    	{
    		free (pmatch);
    		return err;
    	}
    
    	/* mostra as sub-strings */
    	for(i = 0; i < nmatch; i++)
    	{
    		printf ("pmatch[%ld] (%d : %d)\t=> %.*s\n",
    			i,
    			pmatch[i].rm_so,pmatch[i].rm_eo,
    			pmatch[i].rm_eo - pmatch[i].rm_so,
    			string + pmatch[i].rm_so);
    	}
    
    	free (pmatch);
    	regfree (&preg);
    	return 0;
    }
    

    Retorno:

    pmatch[0] (0 : 29) => https://fm4lloc.wordpress.com/
    pmatch[1] (0 : 5) => http:
    pmatch[2] (0 : 4) => http
    pmatch[3] (5 : 28) => //fm4lloc.wordpress.com
    pmatch[4] (7 : 28) => fm4lloc.wordpress.com
    pmatch[5] (28 : 29) => /
    pmatch[6] (-1 : -1) =>
    pmatch[7] (-1 : -1) =>
    pmatch[8] (-1 : -1) =>
    pmatch[9] (-1 : -1) =>

    As sub-strings inexistentes recebem (-1, -1).

    Grupos:

    ^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?
    _12____________3__4__________5_______6__7________8_9____
    

     

    ENCONTRANDO NA STRING TODAS AS OCORRÊNCIAS DO PADRÃO.

    No começo do artigo comentei que Perl nasceu pronto para trabalhar com o melhor que concerne a expressões regulares, não mentei, vou provar no próximo código.

    Para encontrar todas as ocorrências do padrão em Perl:

    #!/usr/bin/perl
    
    use warnings;
    use strict;
    
    my $string	=	"1991/04;".
    				"1992/12;".
    				"1992/05;".
    				"1994/03;".
    				"1995/09;";
    
    for ($string =~ m/([0-9]+)\/([0-9]+)/g)
    {
    	print "$_\n";
    }
    
    Saída
    1991
    04
    1992
    12
    1992
    05
    1994
    03
    1995
    09

    Tudo é simplificado, bastou o uso da opção “g” ao final da expressão. Em C as coisas ficam um pouco mais complexas.

    A mesma ideia em C:

    #include <stdio.h>
    #include <stdlib.h>
    #include <regex.h>
    #include <string.h>
    /*
     *  Written by: fm4lloc <fm4lloc@gmail.com>
     *
     *  This program is free software; you can redistribute it and/or modify
     *  it under the terms of the GNU General Public License as published by
     *  the Free Software Foundation; either version 2 of the License, or
     *  (at your option) any later version.
     *
     */
    
    int main ()
    {
    	regex_t preg;
    	reg_errcode_t err;
    	regmatch_t *pmatch = NULL;
    	size_t	offset = 0, nmatch, i, j;
    
    	const char regex[]  =	"([0-9]+)/([0-9]+)";
    
    	const char string[]	=	"1991/04;" \
    							"1992/12;" \
    							"1992/05;" \
    							"1994/03;" \
    							"1995/09;";
    
    	if( ( err = regcomp (&preg, regex, REG_EXTENDED) ) != REG_NOERROR)
    		return err;
    
    	nmatch = preg.re_nsub + 1;
    	/*
    	 * Define o modo de impressão das sub-strings.
    	 * Só imprime sub-strings do índice zero se não
    	 * existir grupos.
    	 */
    	if (nmatch == 1)
    		j = 0;
    	else
    		j = 1;
    
    	pmatch = (regmatch_t *) malloc (sizeof(regmatch_t) * nmatch);
    
    	/* Tenta casar enquanto não for retornado erro.
    	 *
    	 * O endereço de string é incrementado com offset para evitar
    	 * buscas no mesmo trecho.
    	 */
    	while ((err = regexec (&preg, string + offset,
    		nmatch ,pmatch, 0 )) == REG_NOERROR)
    	{
    		/* mostra as sub-strings.
    		 */
    		for(i = j; i < nmatch; i++)
    			printf ("%.*s\n", pmatch[i].rm_eo - pmatch[i].rm_so,
    				string + pmatch[i].rm_so + offset);
    
    		/* offset: variável auxiliar – usada para pular fragmentos já
    		 * analisados.
    		 *
    		 * Ela recebe o valor referente a posição
    		 * do último byte do pedaço casado anteriormente.
    		 */
    		if (pmatch[0].rm_eo)
    			offset += pmatch[0].rm_eo;
    		else
    			break;
    	}
    
    	free (pmatch);
    	regfree (&preg);
    
    	return 0;
    }
    

    Os códigos escritos no artigo são feitos para facilitar o entendimento, podem ser otimizados ao extremo.

    Exemplo com outras expressões e strings:

    Exemplo 1:

    Regex “^([0-9]+)/([0-9]+);$”
    String “1991/04;\n” \
    “1992/12;\n” \
    “1992/05;\n” \
    “1994/03;\n” \
    “1995/09;\n”;
    regcomp() flags REG_EXTENDED | REG_NEWLINE
    Saída 1991
    04
    1992
    12
    1992
    05
    1994
    03
    1995
    09

    Exemplo 2:

    regex “^[0-9]+/[0-9]+;”
    string “1991/04;” \
    “1992/12;” \
    “1992/05;” \
    “1994/03;” \
    “1995/09;”;
    regcomp() flags REG_EXTENDED
    Saída 1991/04;
    1992/12;
    1992/05;
    1994/03;
    1995/09;

    Exemplo 3:

    regex “^[0-9]+/[0-9]+;”
    string “1991/04;\n” \
    “1992/12;\n” \
    “1992/05;\n” \
    “1994/03;\n” \
    “1995/09;\n”;
    regcomp() flags REG_EXTENDED
    Saída 1991/04;\n

     

    EXIBINDO ERROS

    As funções regcomp () e regexec () retornam um inteiro indicando o ocorrido ao final de cada execução, o retorno é chamado de error code e é declarado no header regex.h assim:

    typedef enum
    {
    #if defined _XOPEN_SOURCE || defined __USE_XOPEN2K
      REG_ENOSYS = -1,	/* This will never happen for this implementation.  */
    #endif
    
      REG_NOERROR = 0,	/* Success.  */
      REG_NOMATCH,		/* Didn't find a match (for regexec).  */
    
      /* POSIX regcomp return error codes.  (In the order listed in the
         standard.)  */
      REG_BADPAT,		/* Invalid pattern.  */
      REG_ECOLLATE,		/* Inalid collating element.  */
      REG_ECTYPE,		/* Invalid character class name.  */
      REG_EESCAPE,		/* Trailing backslash.  */
      REG_ESUBREG,		/* Invalid back reference.  */
      REG_EBRACK,		/* Unmatched left bracket.  */
      REG_EPAREN,		/* Parenthesis imbalance.  */
      REG_EBRACE,		/* Unmatched \{.  */
      REG_BADBR,		/* Invalid contents of \{\}.  */
      REG_ERANGE,		/* Invalid range end.  */
      REG_ESPACE,		/* Ran out of memory.  */
      REG_BADRPT,		/* No preceding re for repetition op.  */
    
      /* Error codes we've added.  */
      REG_EEND,		/* Premature end.  */
      REG_ESIZE,		/* Compiled pattern bigger than 2^16 bytes.  */
      REG_ERPAREN		/* Unmatched ) or \); not returned from regcomp.  */
    } reg_errcode_t;
    

    Pequena rotina que exibe a mensagem correspondente ao error code.

    Observe, regerror () aparece duas vezes na rotina, na primeira ela é chamada para determinar o comprimento da mensagem, enquanto na segunda é invocada com o intuito de copiar a mensagem para *errbuff.

    /*
     *  Written by: fm4lloc <fm4lloc@gmail.com>
     *
     *  This program is free software; you can redistribute it and/or modify
     *  it under the terms of the GNU General Public License as published by
     *  the Free Software Foundation; either version 3 of the License, or
     *  (at your option) any later version.
     *
     */
    
    void c_regerror (reg_errcode_t err, const regex_t *preg)
    {
    	size_t errbuf_size;
    	char *errbuf = NULL;
    
    	errbuf_size  = regerror (err, preg, NULL, 0);
    	errbuf = (char *) calloc (errbuf_size, sizeof(char));
    
    	regerror (err, preg, errbuf, errbuf_size);
    
    	fprintf (stderr, "%s\n", errbuf);
    	free (errbuf);
    }
    

    Declaração de regerror ():

    size_t regerror(int errcode, const regex_t *preg, char *errbuf,
                           size_t errbuf_size);
    
    errcode O error code retornado por regcomp () ou regexec ()
    *preg Aponta para o pattern buffer
    *errbuf Ponteiro para a mensagem de erro
    errbuf_size Número de bytes que serão copiados para *errbuff
     
c
escrever novo post
j
post seguinte/ comentário seguinte
k
post anterior/comentário anterior
r
Resposta
e
Editar
o
mostrar/esconder comentários
t
voltar ao topo
l
vá para login
h
mostrar/ocultar ajuda
shift + esc
Cancelar