programing

정의/정의되지 않은 값을 기준으로 #ifdef 블록을 제거하는 C 프리프로세서가 있습니까?

padding 2023. 6. 7. 22:12
반응형

정의/정의되지 않은 값을 기준으로 #ifdef 블록을 제거하는 C 프리프로세서가 있습니까?

원래 질문

제가 원하는 것은 표준 C 전처리기가 아니라 -DNAME1 및 -UNAME2 옵션을 통해 명령줄을 사용할 수 있는 변형입니다. 매크로가 정의된 후 데드 코드를 제거할 수 있습니다.

몇 가지 예를 들어보면 제가 추구하는 것을 이해하는 것이 더 쉬울 수 있습니다.

#ifdef NAME1
#define ALBUQUERQUE "ambidextrous"
#else
#define PHANTASMAGORIA "ghostly"
#endif

명령이 '-DNAME1'로 실행된 경우 출력은 다음과 같습니다.

#define ALBUQUERQUE "ambidextrous"

명령이 '-UNAME1'로 실행된 경우 출력은 다음과 같습니다.

#define PHANTASMAGORIA "ghostly"

두 옵션을 모두 사용하지 않고 명령을 실행한 경우 출력은 입력과 동일합니다.

이것은 간단한 사례입니다. 코드가 더 복잡한 사례도 처리할 수 있기를 바랍니다.

실제 사례를 사용하여 설명합니다.

#ifdef USE_VOID
#ifdef PLATFORM1
#define VOID void
#else
#undef VOID
typedef void    VOID;
#endif /* PLATFORM1 */
typedef void *  VOIDPTR;
#else
typedef mint     VOID;
typedef char *  VOIDPTR;
#endif /* USE_VOID */

를 실니다명행합을로 -DUSE_VOID -UPLATFORM1출력을 가져옵니다.

#undef VOID
typedef void    VOID;
typedef void *  VOIDPTR;

다른 예:

#ifndef DOUBLEPAD
#if (defined NT) || (defined OLDUNIX)
#define DOUBLEPAD 8
#else
#define DOUBLEPAD 0
#endif /* NT */
#endif /* !DOUBLEPAD */

이상적으로, 저는 당신과 함께 달리고 싶습니다.-UOLDUNIX출력을 가져옵니다.

#ifndef DOUBLEPAD
#if (defined NT)
#define DOUBLEPAD 8
#else
#define DOUBLEPAD 0
#endif /* NT */
#endif /* !DOUBLEPAD */

이것은 내 운을 재촉하는 것일지도 모릅니다!

동기부여: 많은 조건부 코드가 있는 크고 오래된 코드 기반.많은 조건이 더 이상 적용되지 않습니다. 예를 들어 OLDUNIX 플랫폼은 더 이상 만들어지지 않으며 더 이상 지원되지 않으므로 코드에 이에 대한 참조가령 OLDUNIX 플랫폼은 더 이상 지원되지 않습니다.다른 조건은 항상 참입니다.예를 들어, 기능을 사용할 수 없는 소프트웨어의 이전 버전과 사용 가능한 최신 버전 모두에 대해 단일 버전의 코드를 사용할 수 있도록 조건부 컴파일 기능이 추가됩니다.결국 기능이 없는 이전 버전은 더 이상 지원되지 않으므로 기능이 있는지 여부에 대한 조건을 제거해야 하며 '기능이 없을 때' 코드도 제거해야 합니다.수동으로 작업하는 것보다 더 빠르고 안정적이기 때문에 자동으로 작업을 수행할 수 있는 도구가 필요합니다(코드 기반에 21,500개의 소스 파일이 포함된 경우에는 매우 중요함).

(정말 똑똑한 버전의 도구는 다음과 같습니다.)#include명령줄에서 -D 또는 -U로 지정된 제어 매크로가 해당 파일에 정의되어 있는지 여부를 확인하는 'd 파일.백업 진단을 제외하고는 그게 정말 도움이 되는지 모르겠습니다.그러나 의사 사전 프로세서가 무엇을 하든지 간에 매크로를 확장하거나 파일을 문자 그대로 포함해서는 안 됩니다.출력은 입력 코드와 비슷하지만 일반적으로 입력 코드보다 단순해야 합니다.)

상태 보고서(1년 후)

1년간 사용한 후 선택한 답변에서 추천한 'sunifdef'에 매우 만족합니다.그것은 아직 실수하지 않았고, 저는 그것이 실수할 것이라고 예상하지 않습니다.내가 그것에 대해 가지고 있는 유일한 문제는 문체적인 것입니다.다음과 같은 입력이 주어질 경우:

#if (defined(A) && defined(B)) || defined(C) || (defined(D) && defined(E))

'-UC'로 실행(C는 정의되지 않음), 출력은 다음과 같습니다.

#if defined(A) && defined(B) || defined(D) && defined(E)

이는 '&&'이 '|'보다 더 엄격하게 결합하기 때문에 기술적으로는 맞지만, 혼란에 대한 공개적인 초대입니다.저는 원본에서와 같이 '&&' 조건 집합 주위에 괄호를 포함하는 것을 훨씬 선호합니다.

#if (defined(A) && defined(B)) || (defined(D) && defined(E))

하지만, 제가 사용해야 하는 코드의 모호함을 고려할 때, 그것이 가장 큰 트집이 되는 것은 강력한 칭찬입니다. 그것은 저에게 귀중한 도구입니다.


뉴 키드 온 더 블록

위의 정보에 포함된 URL을 확인해보니 (예상대로) 'sunifdef'의 뒤를 잇는 Coan이라는 새로운 프로그램이 있습니다.2010년 1월부터 소스포지에서 사용할 수 있습니다.제가 확인해 보겠습니다...올해 말, 어쩌면 내년, 언젠가, 혹은 절대로 추가적인 보고를 하지 않을 수도 있습니다.

저는 C에 대해 전혀 알지 못하지만, 당신이 찾는 것처럼 들립니다. 2000년 이후로 업데이트되지 않았지만, "Son of unifdef" (sunifdef)라는 후계자가 있습니다.

또한 이 도구를 사용할 수 있습니다. http://coan2.sourceforge.net/

ifdef 블록을 제거합니다.

coan source -UYOUR_FLAG --filter c,h --Recurse YourSourceTree

저는 몇 년 전에 당신이 설명한 문제에 대해 unifdef를 사용했고, 잘 작동했습니다.2000년 이후로 업데이트가 되지 않았더라도, defs의 구문은 그 이후로 실질적으로 변하지 않았기 때문에 여전히 당신이 원하는 것을 할 수 있을 것으로 기대합니다.패키지가 최근에 나온 것처럼 보이지만 컴파일에 문제가 있을 수 있습니다.

sunifdef를 사용한 적이 없어서 직접적으로 언급할 수 없습니다.

2004년경에 저는 당신이 찾고 있는 것을 정확히 해주는 도구를 썼습니다.도구를 배포할 시간은 없었지만 코드는 다음에서 찾을 수 있습니다.

http://casey.dnsalias.org/exifdef-0.2.zip (그것은 DSL 링크입니다)

약 1.7k 줄이며 바이슨과 플렉스를 사용하여 전처리기 문, 주석 및 문자열을 구문 분석할 수 있는 충분한 C 문법을 구현합니다.

전처리기와 유사한 것이 필요한 경우 유연한 솔루션은 Wave(부스트에서)입니다.C-preprocessor와 같은 도구(C++03 및 C++0x 프리프로세서 등)를 구축하도록 설계된 라이브러리입니다.라이브러리이므로 입력 및 출력 코드에 연결할 수 있습니다.

언급URL : https://stackoverflow.com/questions/525283/is-there-a-c-pre-processor-which-eliminates-ifdef-blocks-based-on-values-define

반응형