Felipe Tonello » C http://felipetonello.com/blog Compartilhe, ajude e cresça Thu, 07 Jul 2011 04:13:08 +0000 en hourly 1 http://wordpress.org/?v=3.2.1 Awesome C/C++ auto-completion in Emacs http://felipetonello.com/blog/2011/06/07/awesome-c-cpp-auto-completion-in-emacs/ http://felipetonello.com/blog/2011/06/07/awesome-c-cpp-auto-completion-in-emacs/#comments Tue, 07 Jun 2011 12:42:53 +0000 Felipe Tonello http://felipetonello.com/blog/?p=370 Emacs is a great editor, no body doubts that. But there is no powerful auto-completion by default, like Eclipse or other IDE.

Parsing C++ is very hard and using tools like ctags works well for C but not so much for C++.
LLVM/Clang is a compiler architecture supported by Apple, Google, Adobe and others that seeks to become a serious alternative to GCC. The project started just a few years ago but it already provides a high quality C and Objective C compiler that performs better than GCC in several benchmarks. The C++ support is still not complete but good to compile boost. Clang is not just a compiler, it also has includes great tools for code analysis. Clang is BSD licensed which enables close interaction with third part applications without licensing issues.

Ok, so let's merge all these things. To accomplish that we need 3 Emacs extensions:

  • auto-complete-mode
  • yasnippet
  • auto-complete-clang

auto-complete-mode

auto-complete-mode is an awesome extension for Emacs. It provides an intelligent auto-completion. To install, just follow these steps:

  1. Download it at http://cx4a.org/software/auto-complete/
  2. Copy all .el to ~/.emacs.d or other personal folder that you keep your Emacs extensions
  3. Add the following code to your ~/.emacs:
    (require 'auto-complete-config)
    (add-to-list 'ac-dictionary-directories "~/.emacs.d/ac-dict")

    Note: change the ac-dictionary-directories as specified in step 2.

yasnippet

yasnippet is a template system for Emacs. Installation process:

  1. Download the yasnippet-bundle at http://code.google.com/p/yasnippet/
  2. Uncompress it at ~/.emacs.d or other personal folder that you keep your Emacs extensions
  3. Add the following code to your ~/.emacs:
    (require 'yasnippet-bundle)

auto-complete-clang

auto-complete-clang unites the power of auto-complete, clang and yasnippet.

  1. Download the .el file at https://github.com/brianjcj/auto-complete-clang
  2. Copy it at ~/.emacs.d or other personal folder that you keep your Emacs extensions
  3. Add the following code to your ~/.emacs:
  4. (require 'auto-complete-clang)
  5. Since auto-complete-clang calls clang to every auto-complete command, we need to trigger it with some key. In my example here I'm using C-Tab
  6. (setq ac-auto-start nil)
    (setq ac-quick-help-delay 0.5)
    (define-key ac-mode-map  [(control tab)] 'auto-complete)
  7. Setting some properties:
  8. (defun my-ac-config ()
    (setq ac-clang-flags (split-string "-I/path/to/headers"))
    (setq-default ac-sources '(ac-source-abbrev ac-source-dictionary ac-source-words-in-same-mode-buffers))
    (add-hook 'emacs-lisp-mode-hook 'ac-emacs-lisp-mode-setup)
    (add-hook 'c-mode-common-hook 'ac-cc-mode-setup)
    (add-hook 'ruby-mode-hook 'ac-ruby-mode-setup)
    (add-hook 'css-mode-hook 'ac-css-mode-setup)
    (add-hook 'auto-complete-mode-hook 'ac-common-setup)
    (global-auto-complete-mode t))
    (defun my-ac-cc-mode-setup ()
    (setq ac-sources (append '(ac-source-clang ac-source-yasnippet) ac-sources)))
    (add-hook 'c-mode-common-hook 'my-ac-cc-mode-setup)
    (my-ac-config)

    There is basically one important thing here, the ac-clang-flags. You must pass all your include paths in order to clang parses everything correctly. Even the stdc++ headers. For example:

    (setq ac-clang-flags (split-string "-I/usr/include/c++/4.5 -I/usr/include -I/usr/local/include -I/usr/local/qt4/include -I/usr/local/qt4/include/QtCore -I/usr/local/qt4/include/QtGui"))
  9. Since my background color is black, I had to change the ac-cursor-color in auto-complete.el. To do that find the first occurrence of ac-cursor-color and change nil to the desired color. For example:
  10. (defvar ac-cursor-color "blanched almond"
    "Old cursor color.")

Troubleshoot

If you get some error with bits/c++config.h in *clang error* buffer, like:
fatal error: 'bits/c++config.h' file not found
You might need to create a symbolic link from the machine hardware name(i686, etc) c++ bits includes to the c++ bits:
# ln -s /usr/include/c++/4.5/`uname -m`-linux-gnu/bits/* /usr/include/c++/4.5/bits

To inspire you, here is my .emacs file:

; auto-complete-mode
; --------------
(require 'auto-complete-config)
(add-to-list 'ac-dictionary-directories "~/Dropbox/elisp/ac-dict")
 
; yasnippet
; --------------
(require 'yasnippet-bundle)
 
; auto-complete-clang
; --------------
(require 'auto-complete-clang)
 
(setq ac-auto-start nil)
(setq ac-quick-help-delay 0.5)
;; (ac-set-trigger-key "TAB")
(define-key ac-mode-map  [(control tab)] 'auto-complete)
(defun my-ac-config ()
  (setq ac-clang-flags (split-string "-I/usr/include/c++/4.5 -I/usr/include -I/usr/local/include -I/usr/local/kdchart4/include -I/usr/local/rog/include -I/usr/local/qt4/include -I/usr/local/qt4/include/QtCore -I/usr/local/qt4/include/QtGui"))
  (setq-default ac-sources '(ac-source-abbrev ac-source-dictionary ac-source-words-in-same-mode-buffers))
  (add-hook 'emacs-lisp-mode-hook 'ac-emacs-lisp-mode-setup)
  (add-hook 'c-mode-common-hook 'ac-cc-mode-setup)
  (add-hook 'ruby-mode-hook 'ac-ruby-mode-setup)
  (add-hook 'css-mode-hook 'ac-css-mode-setup)
  (add-hook 'auto-complete-mode-hook 'ac-common-setup)
  (global-auto-complete-mode t))
(defun my-ac-cc-mode-setup ()
  (setq ac-sources (append '(ac-source-clang ac-source-yasnippet) ac-sources)))
(add-hook 'c-mode-common-hook 'my-ac-cc-mode-setup)
;; ac-source-gtags
(my-ac-config)

Working with Qt 1

 

Working with Qt 2

 

It also works with the C++ Standard Library

 

That's it.

]]>
http://felipetonello.com/blog/2011/06/07/awesome-c-cpp-auto-completion-in-emacs/feed/ 3
String replace in C http://felipetonello.com/blog/2011/05/31/string-replace-in-c/ http://felipetonello.com/blog/2011/05/31/string-replace-in-c/#comments Tue, 31 May 2011 17:15:28 +0000 Felipe Tonello http://felipetonello.com/blog/?p=366 I had this "homework" to make a string compressor using some specific hashes. Than it comes the necessity to create a function that replaces all matches of a string to another string.

Well, it turns out that this function is quite interesting. Lemme show my implementation:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
void string_replace_all(const char *old, const char new, char *str)
{
	int i, j;
	int old_len = strlen(old);
	int str_len = strlen(str);
	int k = -1;
	char sub1[BUF];
 
	for (i = 0, j = 0; i < str_len; ++i) {
		if (str[i] == old[j]) {
			if (k == -1) {
				k = i;
			}
			++j;
		} else {
			if (str[i] == old[0]) {
				k = i;
				j = 1;
			} else {
				k = -1;
				j = 0;
			}
		}
		if (j == old_len) {
 
 
			memcpy(sub1, str, k);
 
			sub1[k] = new;
			sub1[k + 1] = '\0';
 
			strcat(sub1, (str + (k + j)));
 
			strcpy(str, sub1);
 
			string_replace_all(old, new, (str + (k + 1)));
		}
	}
}

Off course there is more interesting implementations. Why don't you show us yours?

]]>
http://felipetonello.com/blog/2011/05/31/string-replace-in-c/feed/ 0
looong #fail no GCC http://felipetonello.com/blog/2010/07/29/looong-fail-no-gcc/ http://felipetonello.com/blog/2010/07/29/looong-fail-no-gcc/#comments Thu, 29 Jul 2010 17:34:25 +0000 Felipe Tonello http://felipetonello.com/blog/?p=313 O uso do long long como tipo de dado foi introduzido no padrão ISO C99. Isso acabou gerando uma revolta na comunidade acadêmica que achava o cúmulo ter de usar long long ao invéz de um nome específico, argumentando "qual será a próxima? long long long, long long long long ... ".

Bom, o que parece é que o pessoal do GCC também não foi muito com a cara desse long long não.

long long long no gcc

long long long #fail no gcc

#FAIL para a ISO C99 ou pro GCC? Fica a dúvida.

]]>
http://felipetonello.com/blog/2010/07/29/looong-fail-no-gcc/feed/ 0
Problema 3n + 1 no UVa http://felipetonello.com/blog/2010/06/09/problema-3n-1-no-uva/ http://felipetonello.com/blog/2010/06/09/problema-3n-1-no-uva/#comments Wed, 09 Jun 2010 04:28:44 +0000 Felipe Tonello http://felipetonello.com/blog/?p=262 Esse é um dos problemas mais simples que tem no UVa mas ao mesmo tempo é muito interessante. O problema 3n + 1, também chamado de Conjectura de Collatz, é um problema da matemática que nunca foi resolvido.

Basicamente é o seguinte:

  • Se o número é par, então divida por dois.
  • Se o número é ímpar, então multiplique por três e some por um.
  • f(n) = \begin{cases} n/2 &\mbox{se } n \equiv 0 \pmod{2}\\ 3n+1 & \mbox{se } n\equiv 1 \pmod{2} \end{cases}

Agora que temos a função definida, vamos realizar essa operação repetidamente, começando com um inteiro positivo e depois usando o resultado em cada passo:

a_i = \begin{cases}n & \mbox{para } i = 0 \\ f(a_{i-1}) & \mbox{para } i > 0. \end{cases}

O interessante é que essa seqüência parece sempre resultar em a_i = 1.

Programando

O desafio enunciado no UVa Online Judge pede para se contar o maior número de m-cíclos em um determinado intervalo de inteiros n, m.

Como eu gosto de coisas simples, fiz um algoritmo em C bem simples. Não recomendo algoritmo complexos.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <stdio.h>
 
int collatz(int n) {
	int i = 1;
	while(n > 1) {
		if((n % 2) != 0)
			n = (3*n) + 1;
		else
			n = n/2;
		++i;
	}
	return i;
}
 
int main (int argc, char const *argv[])
{
	int i, j;
	while(scanf("%d %d", &i, &j) == 2) {
		int i2, j2, k;
		int max = 0;
 
		if (j < i) {
			i2 = j;
			j2 = i;
		} else {
			i2 = i;
			j2 = j;
		}
 
		for (k = i2; k <= j2; ++k) {
			int atual = collatz(k);
			if (max < atual) {
				max = atual;
			}
		}
 
		printf("%d %d %d\n", i, j, max);
	}
	return 0;
}

ou pelo pastebin

Testando as seguintes entradas
1 10
100 200
201 210
900 1000
1 999999
1000 900

temos
1 10 20
100 200 125
201 210 89
900 1000 174
1 999999 476
1000 900 174

Parece tudo certo! :D

Agora fica de exercício descobrir a complexidade desse algoritmo. :)

]]>
http://felipetonello.com/blog/2010/06/09/problema-3n-1-no-uva/feed/ 4
6º Encontro da comunidade de C e C++ Brasil http://felipetonello.com/blog/2010/01/21/6%c2%ba-encontro-da-comunidade-de-c-e-c-brasil/ http://felipetonello.com/blog/2010/01/21/6%c2%ba-encontro-da-comunidade-de-c-e-c-brasil/#comments Fri, 22 Jan 2010 00:56:03 +0000 Felipe Tonello http://felipetonello.com/blog/?p=252 Pessoal, dia 6 de Março de 2010 haverá o 6º encontro da comunidade brasileira de C e C++ em São Paulo.

Eu tive o privilégio de ser convidado para palestrar sobre o RobotQt. O título da palestra é: Simulador de robótica com Qt Framework.

Não perca esse evento. Faça a inscrição aqui!

]]>
http://felipetonello.com/blog/2010/01/21/6%c2%ba-encontro-da-comunidade-de-c-e-c-brasil/feed/ 0