Ao implementar uma alteração no kernel OpenVOS, deparei-me com a tarefa de modificar cerca de 150 arquivos. Isso significava reservá-los no sistema de controle de código-fonte, atualizar os direitos autorais, adicionar uma linha de histórico de modificações e fazer a alteração no código (que era adicionar uma instrução do pré-processador #include). Eu sabia que, se simplesmente começasse a fazer esse trabalho manualmente, levaria uma eternidade. Então, usei alguns atalhos para concluir o trabalho mais rapidamente.
O primeiro truque que usei foi criar uma lista de todos os arquivos que precisava editar. Usei nosso sistema de controle de código-fonte para gerar essa lista, mas ela não estava em um formato que eu pudesse usar facilmente. Então, capturei a saída do comando e usei uma macro de teclado do emacs para transformá-la em uma macro de comando. Se você nunca usou uma macro de teclado do emacs antes, vai adorar. Se já usou, pode pular esta parte e passar para o próximo truque.
O editor emacs possui um comando que pode gravar solicitações de edição à medida que são inseridas. Tanto no OpenVOS emacs quanto no GNU emacs, o comando para iniciar a gravação de comandos é “ESC-(”. Todos os comandos digitados após isso são executados e gravados. Quando estiver pronto para interromper a gravação, digite “ESC-)”. Você pode executar a macro do teclado uma única vez digitando “ESC-m” (no OpenVOS emacs) ou “^X-e” (no GNU emacs). As macros do teclado são ótimas para editar arquivos altamente repetitivos, que era exatamente o caso que eu enfrentava. Aqui está um exemplo simplificado, usando uma lista das funções POSIX que começam com a letra “a”:
lista
Arquivos: 17, Blocos: 19
r abort.c
1 access.c
r 1 adjtime.c
1 aio_cancel.c
1 aio_error.c
1 aio_fsync.c
r 1 aio_read.c
r 1 aio_return.c
1 aio_suspend.c
1 aio_write.c
r 2 alarm.c
r 1 altzone.c
1 asctime.c
r 1 asctime_r.c
r 1 asprintf.c
r 1 assert.c
r 1 atexit.c
Eu precisava editar esse buffer para que cada linha ficasse assim:
corrigir abort.c
onde fixup.cm era uma macro de comando que realizava várias tarefas (mais sobre isso posteriormente). Então, apaguei as primeiras linhas para que tudo o que restasse no buffer do emacs fosse a lista repetitiva de arquivos. Com o cursor no início da primeira linha, digitei “ESC-(” para iniciar a gravação e, em seguida, editei a linha para excluir as duas primeiras “palavras” e substituí-las pela string “fixup”. Em seguida, deixei o cursor no início da linha seguinte e encerrei a gravação com “ESC-)”. Aqui está a sequência exata que digitei (usando as combinações de teclas do OpenVOS emacs):
ESC-( ESC-d ESC-d correção ^N ^A ESC-)
Agora, a primeira linha foi editada e meu cursor está no início da segunda linha. Como tudo funcionou bem, digitei:
ESC-99 ESC-m
para editar o restante do arquivo. Como o buffer tem menos de 99 linhas, essa macro é executada até chegar ao final do buffer e, então, é interrompida. Em seguida, gravei o buffer como “fixup_all.cm”.
O próximo passo foi escrever a macro de comando “fixup.cm”. Decidi que ela atualizaria os direitos autorais, atualizaria o histórico de modificações e, em seguida, entraria no emacs para que eu pudesse adicionar manualmente a instrução #include. Enquanto ainda estava no emacs, criei uma nova macro de teclado para inserir a instrução #include necessária no cursor:
ESC-( #include “sample.h” ESC-)
Como eu entraria e sairia do emacs para cada arquivo, precisei salvar essa macro permanentemente e vinculá-la a uma tecla. O comando do emacs para salvar a macro de teclado atual como uma macro permanente é “save_macro”, mas ele não tem uma tecla padrão vinculada. Para executá-lo uma vez, digite
ESC-r salvar_macro
e será solicitado que você digite o nome a ser associado a essa nova macro. Chamei minha macro de “add_include_file”. Em seguida, editei meu arquivo start_up.emacs para incluir a linha:
definir_chave ^z-i adicionar_arquivo_incluído
Então, saí do emacs e o reiniciei, para ter certeza de que a instrução set_key funcionaria corretamente. Em seguida, inseri o texto do fixup.cm. Usei o editor de linha porque achei que era a maneira mais fácil de atualizar o histórico de modificações.
&início_parâmetros
nome do caminho do arquivo,req
&end_parameters
!adicionar_direitos_autorais &arquivo&
&anexar_entrada
!line_edit &file& -no_backup –no_verbose
l/Fim do histórico de modificações/
-1
i
/* Modificado em 10-05-17 por Paul Green para … */
.
escrever
sair
&detach_input
emacs &arquivo&
&retornar
Esta macro irá adicionar (ou atualizar) as informações de direitos autorais, adicionar a linha do histórico de modificações logo antes do comentário que usamos para marcar o fim da seção do histórico de modificações e, em seguida, entrar no emacs para que eu possa encontrar manualmente o local para adicionar a instrução %include.
Agora tenho duas macros de comando: “fixup_all.cm” e “fixup.cm”. A primeira invoca a segunda uma vez para cada arquivo que precisa ser modificado. Então, comecei minha maratona de edição digitando “fixup_all” e tudo o que precisei fazer foi encontrar o local para inserir a instrução #include, digitar “^Z-i”, gravar o arquivo e sair. As macros fizeram o resto do trabalho.
Mesmo com o tempo que levei para escrever as macros, ainda economizei muito tempo e esforço (e provavelmente alguns erros de digitação) ao criar essas macros de editor e comando. Isso também transformou uma tarefa enfadonha em uma tarefa muito mais interessante.
Espero que essas informações sejam úteis. Por enquanto é só isso.
