program to reproduce itself and be useful -- not a quine

282 views Asked by At

I have a program which performs a useful task. Now I want to produce the plain-text source code when the compiled executable runs, in addition to performing the original task. This is not a quine, but is probably related.

This capability would be useful in general, but my specific program is written in Fortran 90 and uses Mako Templates. When compiled it has access to the original source code files, but I want to be able to ensure that the source exists when a user runs the executable.

Is this possible to accomplish?

Here is an example of a simple Fortran 90 which does a simple task.

program exampl
  implicit none
  write(*,*) 'this is my useful output'
end program exampl

Can this program be modified such that it performs the same task (outputs a string when compiled) and outputs a Fortran 90 text file containing the source?

Thanks in advance

2

There are 2 answers

3
Loren Pechtel On BEST ANSWER

It's been so long since I have touched Fortran (and I've never dealt with Fortran 90) that I'm not certain but I see a basic approach that should work so long as the language supports string literals in the code.

Include your entire program inside itself in a block of literals. Obviously you can't include the literals within this, instead you need some sort of token that tells your program to include the block of literals.

Obviously this means you have two copies of the source, one inside the other. As this is ugly I wouldn't do it that way, but rather store your source with the include_me token in it and run it through a program that builds the nested files before you compile it. Note that this program will share a decent amount of code with the routine that recreates the code from the block of literals. If you're going to go this route I would also make the program spit out the source for this program so whoever is trying to modify the files doesn't need to deal with the two copies.

0
Ben On

My original program (see question) is edited: add an include statement

Call this file "exampl.f90"

program exampl
  implicit none
  write(*,*) "this is my useful output"
  open(unit=2,file="exampl_out.f90")
  include "exampl_source.f90"
  close(2)
end program exampl

Then another program (written in Python in this case) reads that source

import os
f=open('exampl.f90') # read in exampl.f90
g=open('exampl_source.f90','w') # and replace each line with write(*,*) 'line'
for line in f:
  #print 'write(2,*) \''+line.rstrip()+'\'\n',
  g.write('write(2,*) \''+line.rstrip()+'\'\n')
f.close
g.close
# then complie exampl.f90 (which includes exampl_source.f90)
os.system('gfortran exampl.f90')
os.system('/bin/rm exampl_source.f90')

Running this python script produces an executable. When the executable is run, it performs the original task AND prints the source code.