Porting make.c ke D

Walter Bright adalah "diktator seumur hidup yang baik hati" dari bahasa pemrograman D dan pendiri Digital Mars . Dia memiliki lebih dari belasan tahun pengalaman dalam mengembangkan compiler dan interpreter untuk beberapa bahasa, termasuk Zortech C ++, compiler C ++ native pertama. Dia juga pencipta Kekaisaran , inspirasi utama untuk Peradaban Sid Meier.



Seri C yang lebih baik
  1. D C
  2. ,
  3. make.c D


C yang lebih baik adalah cara untuk memindahkan proyek C yang ada ke D secara konsisten. Artikel ini memandu Anda melalui proses langkah demi langkah untuk mengubah proyek non-sepele dari C ke D dan menunjukkan kepada Anda masalah umum yang muncul.



Meskipun frontend dari kompilator D dmd telah diubah menjadi D, ini adalah proyek yang sangat besar sehingga sulit untuk menutupinya sepenuhnya. Saya membutuhkan proyek yang lebih kecil dan lebih sederhana yang dapat dipahami sepenuhnya tanpa menjadi contoh spekulatif.



Sebuah program make lama yang saya tulis untuk kompiler Datalight C di awal 1980-an muncul di benak saya . Ini adalah implementasi nyata dari program make klasik, yang telah digunakan secara konstan sejak awal 1980-an. Itu ditulis dalam C bahkan sebelum standarisasi, porting dari satu sistem ke sistem lain, dan hanya cocok di 1961 baris kode, termasuk komentar. Itu masih digunakan secara teratur sampai sekarang.



Berikut dokumentasi dan kode sumbernya . Ukuran eksekusi make.exe adalah 49.692 byte dan terakhir diubah pada 19 Agustus 2012.



Rencana Jahat Kami:



  1. Minimalkan perbedaan antara versi C dan D. Dengan demikian, jika perilaku program berbeda, akan lebih mudah menemukan sumber perbedaannya.
  2. C. β„– 1.
  3. . , . β„– 1.
  4. C , .
  5. , β„– 4.


, , , ..



!



C D. β€” 52 252 ( β€” 49 692 ). , , - NEWOBJ ( C- ) DMC 2012 .





. 664 1961, β€” , , , , .



#include D: , #include <stdio.h> import core.stdc.stdio;. , Digital Mars C, D ( ). , 29- 64-. (. import).



#if _WIN32 version (Windows). (. ).



extern(C): C. (. ).



debug1, debug2 debug3 debug prinf. , #ifdef DEBUG debug. (. debug).



/* Delete these old C macro definitions...
#ifdef DEBUG
-#define debug1(a)       printf(a)
-#define debug2(a,b)     printf(a,b)
-#define debug3(a,b,c)   printf(a,b,c)
-#else
-#define debug1(a)
-#define debug2(a,b)
-#define debug3(a,b,c)
-#endif
*/

// And replace their usage with the debug statement
// debug2("Returning x%lx\n",datetime);
debug printf("Returning x%lx\n",datetime);


TRUE, FALSE NULL true, false null.



ESC . (. ).



// #define ESC     '!'
enum ESC =      '!';


NEWOBJ .



// #define NEWOBJ(type)    ((type *) mem_calloc(sizeof(type)))
type* NEWOBJ(type)() { return cast(type*) mem_calloc(type.sizeof); }


filenamecmp .



.



D (thread-local storage, TLS). make β€” , __gshared. (. __gshared).



// int CMDLINELEN;
__gshared int CMDLINELEN


D , typedef . alias. (. alias). , struct.



/*
typedef struct FILENODE
        {       char            *name,genext[EXTMAX+1];
                char            dblcln;
                char            expanding;
                time_t          time;
                filelist        *dep;
                struct RULE     *frule;
                struct FILENODE *next;
        } filenode;
*/
struct FILENODE
{
        char            *name;
        char[EXTMAX1]  genext;
        char            dblcln;
        char            expanding;
        time_t          time;
        filelist        *dep;
        RULE            *frule;
        FILENODE        *next;
}

alias filenode = FILENODE;


D macro β€” , MACRO.



C, D , :



// char *name,*text;
// In D, the * is part of the type and 
// applies to each symbol in the declaration.
char* name, text;


C D. (. D).



static D . C D, , . __gshared, . (. static).



/*
static ignore_errors = FALSE;
static execute = TRUE;
static gag = FALSE;
static touchem = FALSE;
static debug = FALSE;
static list_lines = FALSE;
static usebuiltin = TRUE;
static print = FALSE;
...
*/

__gshared
{
    bool ignore_errors = false;
    bool execute = true;
    bool gag = false;
    bool touchem = false;
    bool xdebug = false;
    bool list_lines = false;
    bool usebuiltin = true;
    bool print = false;
    ...
}


D . , , , .



make- .



, , , D .



// int cdecl main(int argc,char *argv[])
int main(int argc,char** argv)


mem_init() , .



C , D , .



void cmderr(const char* format, const char* arg) {...}

// cmderr("can't expand response file\n");
cmderr("can't expand response file\n", null);


- (->) C (.), D .



version.



/*
 #if TERMCODE
    ...
 #endif
*/
    version (TERMCODE)
    {
        ...
    }


. D .



// doswitch(p)
// char *p;
void doswitch(char* p)


D debug . xdebug.



C \n\ . D .



/+ +/. (. , ).



static if #if. (. static if).



D , .ptr.



// utime(name,timep);
utime(name,timep.ptr);


const C D, D . (. const immutable).



// linelist **readmakefile(char *makefile,linelist **rl)
linelist **readmakefile(const char *makefile,linelist **rl)


void* char* D .



// buf = mem_realloc(buf,bufmax);
buf = cast(char*)mem_realloc(buf,bufmax);


unsigned uint.



inout , «» . const, , . (. inout-).



// char *skipspace(p) {...}
inout(char) *skipspace(inout(char)* p) {...}


arraysize .length. (. ).



// useCOMMAND  |= inarray(p,builtin,arraysize(builtin));
useCOMMAND  |= inarray(p,builtin.ptr,builtin.length)


(immutable), , . (. ).



// static char envname[] = "@_CMDLINE";
char[10] envname = "@_CMDLINE";


.sizeof sizeof() C. (. .sizeof).



// q = (char *) mem_calloc(sizeof(envname) + len);
q = cast(char *) mem_calloc(envname.sizeof + len)


Windows .



char * void*.



! , . , , β€” , .



man.c, , make -man. , D, .



make , make-:



\dmd2.079\windows\bin\dmd make.d dman.d -O -release -betterC -I. -I\dmd2.079\src\druntime\import\ shell32.lib




C D, . .



, , :



  • #include import;
  • D- ;
  • ->;
  • :

    • ,
    • ,
    • ,
    • ,
    • ;
  • ;
  • ;
  • ;
  • ;
  • ;
  • C D.


:



  • ,
  • ,
  • ,
  • ,
  • .




, Better C, , :





Beraksi



Jika Anda tahu bahasa Inggris, kunjungi Forum D dan beri tahu kami bagaimana kemajuan proyek Better C Anda!




All Articles