Estoy buscando una herramienta de línea de comandos/GUI de Windows o un complemento de Visual Studio donde pueda automatizar la extracción de bloques de código C++, agregar algunos pasos de refactorización/cambio de nombre e insertarlo en algún otro archivo C++. Una vez que esto esté configurado, quiero mantener la fuente/destino de los bloques de código sincronizados y/o verificar las diferencias.
EDITAR : Estoy tratando de mantener las cosas en mi proyecto lo más simples posible. Así que espero una solución con un bajo nivel de complejidad. Preferiría una solución que utilice varias herramientas de una sola tarea (tal vez ya incluidas con mi sistema operativo/IDE/SCM) en lugar de una herramienta multitarea rica en funciones que está diseñada para manejar mucho más.
Para dar un ejemplo muy simple, y no estoy seguro de si la herramienta en cuestión necesitaría comprender la sintaxis de C++ para hacer algo como esto:
OldClass.cpp
class OldClass
{
public:
...
void MyFunctionToReuse()
{
...
// Start OldClass::MyFunctionToReuse() block
mVarOldName = ...;
// End OldClass::MyFunctionToReuse() block
...
}
};
NuevaClase.cpp
class NewClass
{
public:
...
void SomeFunction()
{
...
// Start OldClass::MyFunctionToReuse() block
// file OldClass.cpp, line 100 - 110
// renamed mVarOldName to mVarNewName
mVarNewName = ...;
// End OldClass::MyFunctionToReuse() block
...
}
};
Veo cuatro formas posibles de hacer esto:
OldClass
aNewClass
Tengo un proyecto C++ de modelo/vista/controlador de larga duración en el que la parte de la vista ahora se intercambiará/moverá a una aplicación separada. El antiguo código base es reutilizable en un 80%, pero no puedo tomar las clases tal como están actualmente. Así que ahora estoy en un punto en el que me ramifico de mi antiguo proyecto para comenzar con el nuevo código.
Pero el antiguo proyecto aún se mantendrá durante varios años. Entonces, si empiezo con los cambios necesarios para/refactorización del nuevo proyecto, estoy buscando algo para mantener sincronizados ambos flujos de código/ramas (principalmente para corregir errores).
Y los grandes cambios en el producto anterior son solo el último recurso, porque significaría, incluso con una buena cobertura de código con pruebas unitarias, volver a probar partes importantes del producto que se envía actualmente.
Las listas de características de
Terminé usando el precompilador de Visual Studio para traducir mis archivos fuente a través de definiciones de macros. En un segundo paso, estoy usando PowerShell para reemplazar/agregar algunos caracteres de formato especiales que el precompilador eliminaría/ignoraría.
Como estoy usando CMake, aquí está el script que probé:
cmake_minimum_required(VERSION 2.8.9)
project(CppTranslationDemo)
if(NOT MSVC_VERSION GREATER 1699)
message(FATAL_ERROR "Only tested with VS2012 or above")
endif()
set(
inFiles
OldClass.cpp
)
unset(outFiles)
find_program(
POWERSHELL_EXE
NAMES powershell.exe
PATHS C:/Windows/System32
PATH_SUFFIXES WindowsPowerShell/v1.0
)
if (NOT POWERSHELL_EXE)
message(FATAL_ERROR "Couldn't find powershell.exe")
endif()
foreach(_file IN ITEMS ${inFiles})
file(TO_NATIVE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/${_file}" _file_native_path)
file(TO_NATIVE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/TranslationMacros.h" _macro_file_native_path)
file(TO_NATIVE_PATH "${CMAKE_CXX_COMPILER}" _compiler_native_path)
get_filename_component(_file_name "${_file}" NAME)
get_filename_component(_file_ext "${_file}" EXT)
string(REPLACE "Old" "New" _file_name "${_file_name}")
set(_out_file "${CMAKE_BINARY_DIR}/${_file_name}")
set(
_powershell_cmd_list
"$i = 1;"
# NOTE: increase column width to prevent word wrap after 80 chararcters
"$Host.UI.RawUI.BufferSize = New-Object Management.Automation.Host.Size (500, 25);"
"$nl = [Environment]::NewLine;"
"& '${_compiler_native_path}' /nologo /EP /C /FI${_macro_file_native_path} ${_file_native_path}"
"|"
"Foreach-Object"
"{"
"$_"
"-replace '@NL@', $nl"
"-replace '@TAB@', ' '"
"-replace '@H@', '#'"
"-replace '@C@', '//'"
"-replace '@CB@', '/*'"
"-replace '@CE@', '*/'"
"-replace '@.*@', ''"
"}"
"|"
"where"
"{"
"if ($_ -eq '')"
"{"
"$i++;"
"}"
"else"
"{"
"$i = 0;"
"}"
"($i -lt 2)"
"};"
"exit $LASTEXITCODE"
)
string(REGEX REPLACE ";([^;])" " \\1" _powershell_cmd "${_powershell_cmd_list}")
add_custom_command(
OUTPUT ${_out_file}
COMMAND "${POWERSHELL_EXE}" -Command "${_powershell_cmd}" 1> "${_out_file}"
DEPENDS ${_file}
TranslationMacros.h
COMMENT "${_out_file}"
)
list(APPEND outFiles "${_out_file}")
endforeach()
add_custom_target(
${PROJECT_NAME}
DEPENDS ${outFiles}
SOURCES
TranslationMacros.h
${inFiles}
)
set_source_files_properties(${outFiles} PROPERTIES GENERATED 1)
add_library(
${PROJECT_NAME}Test
${outFiles}
)
add_dependencies(
${PROJECT_NAME}Test
${PROJECT_NAME}
)
Combinado con
TraducciónMacros.h
#define OldClass NewClass
#define MyFunctionToReuse SomeFunction
#define mVarOldName mVarNewName
Traduce
OldClass.cpp
class OldClass
{
public:
OldClass() : mVarOldName(0) {}
void MyFunctionToReuse()
{
// Some test comment
mVarOldName = 1;
}
int mVarOldName;
};
En
NuevaClase.cpp
class NewClass
{
public:
NewClass() : mVarNewName(0) {}
void SomeFunction()
{
// Some test comment
mVarNewName = 1;
}
int mVarNewName;
};
Referencias
Estudio visual
Potencia Shell
Ira Baxter
florián
Ira Baxter
florián
Tomás Weller