/***********************************************************************
* OS2 and PCDOS share a lot of common codes. However, sometimes
* OS2 needs codes similar to those of UNIX. NOTPCDOS is used in these
* situations
*/
#ifdef OS2
#define PCDOS
#define NOTPCDOS
#else /* OS2 */
#ifndef PCDOS
#define NOTPCDOS
#endif /* PCDOS */
#endif /* OS2 */
#define RETURN(result) return (result);}
int myfunction1(args) {
int x = 0;
// do something
RETURN(x)
int myfunction2(args) {
int y = 0;
// do something
RETURN(y)
int myfunction3(args) {
int z = 0;
// do something
RETURN(z)
是的,没错,在任何函数中都没有括号。语法突显是一团糟,所以他用 vi 来编辑(不是 vim,它有语法着色!)
ADDRESS alloc(nbytes)
POS nbytes;
{
REG POS rbytes = round(nbytes+BYTESPERWORD,BYTESPERWORD);
LOOP INT c=0;
REG BLKPTR p = blokp;
REG BLKPTR q;
REP IF !busy(p)
THEN WHILE !busy(q = p->word) DO p->word = q->word OD
IF ADR(q)-ADR(p) >= rbytes
THEN blokp = BLK(ADR(p)+rbytes);
IF q > blokp
THEN blokp->word = p->word;
FI
p->word=BLK(Rcheat(blokp)|BUSY);
return(ADR(p+1));
FI
FI
q = p; p = BLK(Rcheat(p->word)&~BUSY);
PER p>q ORF (c++)==0 DONE
addblok(rbytes);
POOL
}
void DisplayLoadError()
{
#if defined __TIMETABLE_EDITOR
MessageBox("Timetable Editor failed to load the correct timetable", MB_ERROR);
#else if defined __SCHEDULESET_EDITOR
MessageBox("Schedule Set Editor faied to load the correct Schedule Set", MB_ERROR);
#else if defined __ROSTER_EDITOR
MessageBox("Roster Editor failed to load the correct Roster", MB_ERROR);
#endif
}
// Macro: Stringize
//
// Converts the parameter into a string
//
#define Stringize( L ) #L
// Macro: MakeString
//
// Converts the contents of a macro into a string
//
#define MakeString( L ) Stringize(L)
// Macro: $LINE
//
// Gets the line number as a string
//
#define $LINE MakeString( __LINE__ )
// Macro: $FILE_POS
//
// Gets the current file name and current line number in a format the Visual Studio
// can interpret and output goto
//
// NOTE: For VS to properly interpret this, it must be at the start of the line (can only have whitespace before)
//
#define $FILE_POS __FILE__ "(" $LINE ") : "
我曾经不得不将一个 C 应用程序从 unix 移植到 windows 上,为了保护有罪的人,这个应用程序的具体性质将保持匿名。编写这个程序的人是一位不习惯编写产品代码的教授,而且很明显是从其他语言学到 C 的。英语也不是他的母语,尽管他来自的国家大多数人都说得很好。
他的应用程序大量使用预处理器将 C 语言转换成他能更好理解的格式。但是他使用最多的宏是在一个名为‘ Thing.h’(严肃地说)的头文件中定义的,其中包括以下内容:
#define I Any void_me
#define thou Any void_thee
#define iam(klas) klas me = (klas) void_me
#define thouart(klas) klas thee = (klas) void_thee
#define my me ->
#define thy thee ->
#define his him ->
#define our my methods ->
#define your thy methods ->
然后他用来写下如下的怪物:
void Thing_setName (I, const char *name) {
iam (Thing);
if (name != my name) {
Melder_free (my name);
my name = Melder_wcsdup (name);
}
our nameChanged (me);
}
void Thing_overrideClass (I, void *klas) {
iam (Thing);
my methods = (Thing_Table)klas;
if (! ((Thing_Table) klas) -> destroy)
((Thing_Table) klas) -> _initialize (klas);
}
整个项目(约60,000 LOC)都是以类似的风格编写的—— Marco hell、怪异的名字、古老的英语术语等等。幸运的是,我们能够扔掉代码,因为我发现一个 OSS 库,执行相同的算法快了几十倍。
许多年前,我有一项有趣的任务,就是将原始运输大亨从个人电脑移植到 Mac 电脑上。PC 版本完全是用汇编语言编写的,所以我们必须遍历整个源代码,并首先将其移植到“ PC”C 代码,然后再将其移植到 Mac。大部分代码都是可以的,甚至在某些地方面向对象也是可以的。然而,世界渲染系统是令人难以置信的。对于任何没有玩过这个游戏的人来说,这个世界可以在三个变焦级别中的一个看到。其代码大致如下:
macro DrawMacro <list of arguments>
a couple of thousand lines of assembler with loads of conditionals
based on the macro arguments
DrawZoomLevel1:
DrawMacro <list of magic numbers>
DrawZoomLevel2:
DrawMacro <list of more magic numbers>
DrawZoomLevel3:
DrawMacro <list of even more magic numbers>
/* Internal symbols are prefixed to avoid clashes with other libraries */
#define TYDYAPPEND(str1,str2) str1##str2
#define TY_(str) TYDYAPPEND(prvTidy,str)
TY_(DocParseStream)(bar,foo);
问题是,可视化工作室2005年,也许其他的 IDE go to definition和 go to declaration功能只找到 #define TY_(...),而不是想要的 DocParseStream声明。
#define crBegin static int state=0; switch(state) { case 0:
#define crReturn(i,x) do { state=i; return x; case i:; } while (0)
#define crFinish }
int function(void) {
static int i;
crBegin;
for (i = 0; i < 10; i++)
crReturn(1, i);
crFinish;
}
int decompressor(void) {
static int c, len;
crBegin;
while (1) {
c = getchar();
if (c == EOF)
break;
if (c == 0xFF) {
len = getchar();
c = getchar();
while (len--)
crReturn(c);
} else
crReturn(c);
}
crReturn(EOF);
crFinish;
}
void parser(int c) {
crBegin;
while (1) {
/* first char already in c */
if (c == EOF)
break;
if (isalpha(c)) {
do {
add_to_token(c);
crReturn( );
} while (isalpha(c));
got_token(WORD);
}
add_to_token(c);
got_token(PUNCT);
crReturn( );
}
crFinish;
}