Ioannis Vranos said:
Interesting question. However any standard library headers #included,
in reality they can be like a switch, with no actual header file
existing.
Normally, I don't consider using libraries such as stdio or iostream
as cheating, since they're part of programming in C or C++. But I
don't mind using C or C++ compilers for what they are, some passable
portable assemblers, and writting raw assembly code we don't need any
header, since we always have access to the instructions of the POSIX
virtual machine, namely write(2) which is all we need to "print" some
text.
Here is a simplistic solution. When you edit it, you replace the
contents of quine[] by the new sources, escaping " and \ and putting
each line in a string. Then you update the literal 19 correponding to
the number of the first line of the initializer of quine[].
----------------------------quine.c++----------------------------------
// No header, no library.
// But we'll use the OS to "print" our sources.
extern "C"{ int write(int fd,const char* buffer,int size); }
int len(const char* str){
int l=0; while((*str)!=0){++str;++l;}
return(l);}
void escape(char* dst,const char* src){
int i=0;
for(int j=0;src[j]!=0;++j){
switch(src[j]){
case '"': case '\\': dst[i++]='\\'; // fallthru
default: dst[i++]=src[j]; }}
dst
=0;}
int main(void){
char left []=" \"";
char right []="\",*";
char newline[]="*";
char buffer[128];
char* quine []={
"// No header, no library.",
"// But we'll use the OS to \"print\" our sources.",
"extern \"C\"{ int write(int fd,const char* buffer,int size); }",
"int len(const char* str){",
" int l=0; while((*str)!=0){++str;++l;} ",
" return(l);}",
"void escape(char* dst,const char* src){",
" int i=0;",
" for(int j=0;src[j]!=0;++j){",
" switch(src[j]){",
" case '\"': case '\\\\': dst[i++]='\\\\'; // fallthru",
" default: dst[i++]=src[j]; }}",
" dst=0;}",
"int main(void){",
" char left []=\" \\\"\";",
" char right []=\"\\\",*\";",
" char newline[]=\"*\";",
" char buffer[128];",
" char* quine []={",
" };",
" right[2]=10;",
" newline[0]=10;",
" for(int i=0;i<sizeof(quine)/sizeof(quine[0]);++i){",
" if(i==19){",
" for(int j=0;j<sizeof(quine)/sizeof(quine[0]);++j){",
" write(1,&left[0],len(left));",
" escape(buffer,quine[j]);",
" write(1,buffer,len(buffer));",
" write(1,&right[0],len(right));",
" }",
" }",
" write(1,quine,len(quine));",
" write(1,&newline[0],len(newline));",
" }",
" return(0);",
"}",
};
right[2]=10;
newline[0]=10;
for(int i=0;i<sizeof(quine)/sizeof(quine[0]);++i){
if(i==19){
for(int j=0;j<sizeof(quine)/sizeof(quine[0]);++j){
write(1,&left[0],len(left));
escape(buffer,quine[j]);
write(1,buffer,len(buffer));
write(1,&right[0],len(right));
}
}
write(1,quine,len(quine));
write(1,&newline[0],len(newline));
}
return(0);
}
----------------------------quine.c++----------------------------------
g++ quine.c++ -o quine && ./quine > quine.out && diff quine.c++ quine.out
--
__Pascal Bourguignon__ http://www.informatimago.com/
"What is this talk of "release"? Klingons do not make software
"releases". Our software "escapes" leaving a bloody trail of
designers and quality assurance people in its wake."