Ao implementar uma mudança no núcleo do OpenVOS, me deparei com a tarefa de modificar cerca de 150 arquivos. Isto 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 do código (que era para adicionar uma declaração #incluindo o pré-processador. Eu sabia que se eu simplesmente começasse a fazer este trabalho à mão, isso levaria uma eternidade. Assim, usei alguns atalhos para fazer o trabalho mais rápido.
O primeiro truque que usei foi criar uma lista de todos os arquivos que eu precisava editar. Usei nosso sistema de controle de fonte para gerar essa lista, mas não estava em uma forma que eu pudesse usar facilmente. Então eu capturei a saída do comando e usei uma macro de teclado emacs para massageá-la em uma macro de comando. Se você nunca usou uma macro de teclado emacs antes, você vai ter um deleite. Se você já as usou, pode pular esta parte e passar para o próximo truque.
O editor emacs tem um comando que pode registrar os pedidos de edição à medida que eles são inseridos. Tanto no OpenVOS emacs quanto no GNU emacs, o comando para começar a gravar comandos é "ESC-(". Todo comando que você digita depois disso é executado e gravado. Quando você estiver pronto para parar de gravar, 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 de teclado são ótimas para editar arquivos altamente repetitivos, o que foi exatamente o caso que eu enfrentei. Aqui está um exemplo simplificado, usando uma lista das funções do POSIX que começam com a letra "a":
lista
Arquivos: 17, Blocos: 19
r 2 abort.c
r 1 acesso.c
r 1 adjtime.c
r 1 aio_cancel.c
r 1 aio_error.c
r 1 aio_fsync.c
r 1 aio_read.c
r 1 aio_retorno.c
r 1 aio_suspend.c
r 1 aio_write.c
r 2 alarme.c
r 1 altzone.c
r 1 asctime.c
r 1 asctime_r.c
r 1 asprintf.c
r 1 assert.c
r 1 atexit.c
Eu precisava editar este buffer para que cada linha fosse parecida com esta:
abort.c
onde fixup.cm era uma macro de comando que realizaria várias tarefas (mais sobre isso mais tarde). Assim, eu apaguei as primeiras linhas para que tudo o que restava no buffer emacs fosse a lista repetitiva de arquivos. Com meu cursor no início da primeira linha, eu digitei "ESC-(" para iniciar a gravação, e então procedi à edição da linha para apagar as duas primeiras "palavras" e substituí-las pela string "fixup". Depois deixei o cursor no início da próxima linha, e terminei a gravação com "ESC-)". Aqui está a seqüência exata que eu digitei (usando as teclas emacs do OpenVOS):
ESC-( Fixação ESC-d ESC-d ^N ^A ESC-)
Agora a primeira linha foi editada e meu cursor está no início da segunda linha. Como tudo funcionou bem, eu então digitei:
ESC-99 ESC-m
para editar o resto do arquivo. Como o buffer tem menos de 99 linhas, esta macro corre até atingir o final do buffer, e depois pára. Depois escrevi 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 depois entraria no emacs para que eu pudesse adicionar manualmente a declaração #include. Enquanto eu ainda estava no emacs, criei uma nova macro de teclado para inserir a declaração #include necessária no cursor:
ESC-( #incluir "amostra.h" ESC-)
Como eu estaria entrando e saindo do emacs para cada arquivo, tive que salvar permanentemente esta macro e ligá-la a uma chave. A solicitação emacs para salvar a macro do teclado atual como macro permanente é "save_macro", mas não tem ligação padrão de teclas. Para executá-la uma vez, digite
ESC-r salvar_macro
e lhe solicitará o nome para associar-se a esta nova macro. Eu chamei minha macro de "add_include_file". Depois editei meu arquivo start_up.emacs para conter a linha:
set_key ^z-i add_include_file
Por isso, agora desisti do emacs e o reiniciei, para que eu pudesse ter certeza de que a declaração set_key funcionaria corretamente. Em seguida, entrei com o texto de fixup.cm. Usei o editor de linha porque achei que era a maneira mais fácil de atualizar a história da modificação.
&begin_parâmetros_de_parâmetros
arquivo pathname,req
&parâmetros_de_envio
!add_copyright & file&
&attach_input
!line_edit & file& -no_backup -no_verbose
l/End do histórico de modificações/
-1
i
/* Modificado 10-05-17 por Paul Green para ... */
.
escreva
desista
&detach_input
emacs & file&
& Retorno
Esta macro adicionará (ou atualizará) as informações de direitos autorais, adicionará a linha do histórico de modificações imediatamente antes do comentário que usamos para marcar o final da seção do histórico de modificações, e então entrará em emacs para que eu possa encontrar manualmente o local para adicionar a declaração %include.
Agora eu tenho duas macros de comando: "fixup_all.cm" e "fixup.cm". A primeira invoca a segunda uma vez para cada arquivo que tem que ser modificado. Comecei então minha maratona de edição digitando "fixup_all" e tudo o que eu tinha que fazer era encontrar o lugar para inserir a declaração #include, digitar "^Z-i", escrever o arquivo e desistir. As macros fizeram o resto do trabalho.
Mesmo com o tempo que levou para escrever as macros, ainda economizei muito tempo e esforço (e provavelmente alguns erros de digitação) ao criar estas macros de edição e comando. Também transformou uma tarefa monótona em uma tarefa muito mais interessante.
Espero que você considere estas informações úteis. Isso é tudo por enquanto.