"Fossies" - the Fresh Open Source Software Archive

Member "ncc-2.8/preproc.C" (11 Oct 2008, 13152 Bytes) of package /linux/privat/old/ncc-2.8.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 #include <sys/types.h>
    2 #include <sys/mman.h>
    3 #include <sys/stat.h>
    4 #include <fcntl.h>
    5 #include <sys/types.h>
    6 #include <stdlib.h>
    7 #include <string.h>
    8 #include <stdio.h>
    9 #include <unistd.h>
   10 #include <ctype.h>
   11 #include <sys/wait.h>
   12 #include <signal.h>
   13 #include "global.h"
   14 
   15 bool        usage_only, multiple, include_strings, quiet = false;
   16 bool        abs_paths = false, report_structs = true, pseudo_code = false;
   17 bool        halt_on_error = false, no_error = false;
   18 char        *sourcefile, *preprocfile = PREPROCESSOR_OUTPUT, *cwd;
   19 static char **ncc_key;
   20 
   21 static bool issource (char *f)
   22 {
   23     char *e = f + strlen (f) - 1;
   24     if (*(e-1) == '.')
   25         return *e == 'c' || *e == 'h' || *e == 'C' || *e == 'i';
   26     return *(e-3) == '.' && (*(e-2) == 'c' || *(e-2) == 'C');
   27 }
   28 
   29 static bool isobj (char *f)
   30 {
   31     int i = strlen (f);
   32     return (f [i-1] == 'o' || f [i-1] == 'a') && f [i-2] == '.';
   33 }
   34 
   35 static char *objfile (char *f)
   36 {
   37     char *r = strdup (f);
   38     char *p = rindex (r, '.');
   39     if (p) strcpy (p, ".o");
   40     return r;
   41 }
   42 
   43 FILE *report_stream;
   44 
   45 static void openout (char *f, char *mode = "w")
   46 {
   47     if (!f) return;
   48     char *c = (char*) alloca (strlen (f) + sizeof OUTPUT_EXT);
   49     report_stream = fopen (strcat (strcpy (c, f), OUTPUT_EXT), mode);
   50     fprintf (stderr, "ncc: output file is ["COLS"%s"COLE"]\n", c);
   51 }
   52 
   53 static void stripout (char *f)
   54 {
   55     if (report_stream != stdout) {
   56         fclose (report_stream);
   57         char tmp [1024];
   58         sprintf (tmp, "nccstrip2.py %s"OUTPUT_EXT" %s"OUTPUT_EXT, f, f);
   59         system (tmp);
   60     }
   61     report_stream = stdout;
   62 }
   63 
   64 static void CATFILE (char *data, int len, FILE *out)
   65 {
   66     /* writing out a huge mmaped file with fwrite takes
   67        a lot of time for some reason.  */
   68 #define MAXWRITE 16 * 1024
   69 
   70     if (len <= MAXWRITE) {
   71         fwrite (data, 1, len, out);
   72         return;
   73     }
   74 
   75     CATFILE (data, len / 2, out);
   76     CATFILE (data + len / 2, len - len / 2, out);
   77 }
   78 
   79 #define NCCOBJ "# nccobj "
   80 
   81 static void LINK (char **obj, int objn)
   82 {
   83     int i;
   84     for (i = 0; i < objn; i++) {
   85         char *ncobj = (char*) alloca (strlen (obj [i]) + 10 + sizeof OUTPUT_EXT);
   86         strcat (strcpy (ncobj, obj [i]), OUTPUT_EXT);
   87         load_file L (ncobj);
   88         if (L.success == ZC_OK) {
   89             fprintf (stderr, "ncc: Linking object file ["COLS"%s"COLE"] (%i bytes)\n",
   90                  ncobj, L.len);
   91             PRINTF (NCCOBJ"%s\n", ncobj);
   92             CATFILE (L.data, L.len, report_stream);
   93         }
   94     }
   95 }
   96 
   97 static void RUN (char *outfile, char **argv)
   98 {
   99     int i;
  100     if (!quiet) {
  101         fprintf (stderr, "Running: ");
  102         for (i = 0; argv [i]; i++)
  103             fprintf (stderr, "%s ", argv [i]);
  104         fprintf (stderr, "\n");
  105     }
  106 
  107     int pid = fork ();
  108     if (pid == 0) {
  109         if (outfile) {
  110             if (!freopen (outfile, "w", stdout))
  111                 exit (127);
  112         }
  113         execvp (argv [0], argv);
  114         exit (127);
  115     }
  116     int status;
  117     waitpid (pid, &status, 0);
  118     if (WEXITSTATUS (status) != 0) {
  119         fprintf (stderr, "[%s] Program failed..\n", argv[0]);
  120         exit (1);
  121     }
  122 }
  123 
  124 /*************************************************************
  125 #
  126 # binutils emulation mode.
  127 # happens to work in some cases...
  128 #
  129 *************************************************************/
  130 
  131 static char *ext (char *f)
  132 {
  133     char *f2 = (char*) alloca (strlen (f) + 10 + sizeof OUTPUT_EXT);
  134     return StrDup (strcat (strcpy (f2, f), OUTPUT_EXT));
  135 }
  136 
  137 static bool startswith (char *s, char *h)
  138 {
  139     return strncmp (s, h, strlen (h)) == 0;
  140 }
  141 
  142 static void nccar_x (int argc, char **argv)
  143 {
  144     /* ar x archive [members]
  145      * extract into current directory. At the moment we extract all members.
  146      */
  147     argc--, ++argv;
  148     FILE *F = fopen (ext (argv [0]), "r"), *OUTF = 0;
  149     argc--, ++argv;
  150 
  151     int i;
  152     char tmp [1024], n [500];
  153     if (!F) return;
  154     while (fgets (tmp, sizeof tmp, F)) {
  155         if (startswith (tmp, NCCOBJ)) {
  156             strcpy (n, tmp + sizeof NCCOBJ - 1);
  157             n [strlen (n) - 1] = 0;
  158             if (OUTF) fclose (OUTF);
  159             OUTF = fopen (n, "w");
  160             fprintf (stderr, "ncc: extract ["COLS"%s"COLE"]\n", n);
  161         }
  162         if (OUTF)
  163             fputs (tmp, OUTF);
  164     }
  165     if (OUTF) fclose (OUTF);
  166 }
  167 
  168 static void nccar (int argc, char **argv)
  169 {
  170     /*
  171      * we take the simple usage:
  172      *   ar [max-four-options] archive-file.[ao] obj1.o obj2.o ...
  173      */
  174     int i, j;
  175 
  176     if (strchr (argv [1], 'x'))
  177         return nccar_x (argc-1, argv+1);
  178 
  179     if (!strchr (argv [1], 'r')) {
  180         for (i = 1; i < 5 && i < argc; i++)
  181             if (isobj (argv [i])) {
  182                 openout (argv [i], "a");
  183                 LINK (&argv [i + 1], argc - i - 1);
  184                 stripout (argv [i]);
  185                 return;
  186             }
  187         fprintf (stderr, "nccar: Nothing to do\n");
  188     } else {
  189         for (i = 1; i < 5 && i < argc; i++)
  190             if (isobj (argv [i]))
  191                 break;
  192 
  193 #define TMPARCH "tmp.nccarchive"
  194         char *archive = ext (argv [i]);
  195         link (archive, TMPARCH);
  196         unlink (archive);
  197         FILE *oldarch = fopen (TMPARCH, "r");
  198         if (!oldarch) {
  199             openout (argv [i], "a");
  200             LINK (&argv [i + 1], argc - i - 1);
  201             stripout (argv [i]);
  202             return;
  203         }
  204 
  205         /* replacing members in the archive */
  206         char *outfile = argv [i];
  207         openout (outfile, "w");
  208         bool skipping = false;
  209         char l [512], n [512];
  210         while (fgets (l, 500, oldarch)) {
  211             if (startswith (l, NCCOBJ)) {
  212                 strcpy (n, l + sizeof NCCOBJ - 1);
  213                 n [strlen (n) - sizeof OUTPUT_EXT] = 0;
  214                 skipping = false;
  215                 for (j = i; j < argc; j++)
  216                     if (!strcmp (argv [j], n)) {
  217                         LINK (&argv [j], 1);
  218                         argv [j] = " ";
  219                         skipping = true;
  220                         break;
  221                     }
  222             }
  223             if (!skipping)
  224                 fputs (l, report_stream);
  225         }
  226         fclose (oldarch);
  227         unlink (TMPARCH);
  228         for (j = i + 1; j < argc; j++)
  229             if (strcmp (argv [j], " "))
  230                 LINK (&argv [j], 1);
  231         stripout (outfile);
  232     }
  233 }
  234 
  235 static void nccld (int argc, char **argv)
  236 {
  237     /* 
  238      * 'c++'/'g++' is sometimes used as a linker
  239      * we only do the job if there are object files
  240      */
  241     int i, objfileno = 0;
  242     char *ofile = 0, **objfiles = (char**) alloca (argc * sizeof *objfiles);
  243     for (i = 1; i < argc; i++)
  244         if (argv [i][0] == '-') {
  245             if (argv [i][1] == 'o' && argv [i][2] == 0)
  246                 ofile = argv [++i];
  247         } else if (isobj (argv [i]))
  248             objfiles [objfileno++] = argv [i];
  249     if (ofile && objfileno) {
  250         openout (ofile);
  251         LINK (objfiles, objfileno);
  252         stripout (ofile);
  253     } else fprintf (stderr, "%s: Nothing to do\n", argv [0]);
  254 }
  255 
  256 static void emubinutils (int argc, char **argv)
  257 {
  258     if (0);
  259 #define PROGNAME(x, y) else if (!strcmp (argv [0] + strlen (argv [0])  + 1 - sizeof x, x)) {\
  260     argv [0] = x;\
  261     RUN (NULL, argv);\
  262     ncc ## y (argc, argv);\
  263     }
  264 #define SPROGNAME(x) PROGNAME(#x,x)
  265     SPROGNAME(ar)
  266     SPROGNAME(ld)
  267     PROGNAME("c++", ld)
  268     PROGNAME("g++", ld)
  269     else return;
  270     fflush (stdout);
  271     exit (0);
  272 }
  273 
  274 const char help [] =
  275 "ncc "NCC_VERSION"  -  The new/next generation C compiler\n"
  276 "The user is the only one responsible for any damages\n"
  277 "Written by Stelios Xanthakis\n"
  278 "Homepage: http://students.ceid.upatras.gr/~sxanth/ncc/\n"
  279 "\n"
  280 "Options starting with '-nc' are ncc options, while the rest gcc:\n"
  281 "   -ncgcc : also run gcc compiler (produces useful object file)\n"
  282 "   -ncgcc=PROG : use PROG instead of \"gcc\"\n"
  283 "   -nccpp=PROG : use PROG for preprocessing\n"
  284 " Files:\n"
  285 "   -ncld : emulate object file output: write the output to <objectfile>"OUTPUT_EXT"\n"
  286 "   -ncoo : write the output to sourcefile.c"OUTPUT_EXT"\n"
  287 "   -ncspp : keep sourcefile.i preprocessor output instead of "
  288                 PREPROCESSOR_OUTPUT"\n"
  289 " Output:\n"
  290 "   -nccc : compile and produce virtual bytecode\n"
  291 "   -ncmv : display multiple uses of functions and variables\n"
  292 "   -ncpc : like -ncmv but also produce pseudo-code data\n"
  293 "   -ncnrs : do not report structure declaration locations (lots of data)\n"
  294 "   -ncerr : halt ncc on the first expression error detected\n"
  295 " Switches:\n"
  296 "   -nc00 : do not include constant values (faster/less memory)\n"
  297 " Extras:\n"
  298 "   -nckey : scan source file for additional output (see doc)\n"
  299 " Filenames:\n"
  300 "   -ncfabs : report absolute pathnames in the output\n"
  301 "   -nc- : ignored option\n"
  302 "\nncc can also be called as 'nccar', 'nccld', 'nccc++', 'nccg++'\n"
  303 "In these cases it will invoke the programs 'ar', 'ld', 'c++' and 'g++'\n"
  304 "and then attempt to collect and link object files with the extension "OUTPUT_EXT"\n"
  305 ;
  306 
  307 void preproc (int argc, char**argv)
  308 {
  309     int i;
  310 
  311     report_stream = stdout;
  312 
  313     for (i = 0; i < argc; i++)
  314         if (!strcmp (argv [i], "-ncquiet")) {
  315             quiet = true;
  316             for (--argc; i < argc; i++)
  317                 argv [i] = argv [i + 1];
  318             argv [i] = 0;
  319         }
  320 
  321 
  322     if (1 && !quiet) {
  323         fprintf (stderr, "Invoked: ");
  324         for (i = 0; i < argc; i++) fprintf (stderr, "%s ", argv [i]);
  325         fprintf (stderr, "\n");
  326     }
  327 
  328     /* emulate ar, ld, ... */
  329     emubinutils (argc, argv);
  330 
  331     bool spp = false, dontdoit = false, mkobj = false, ncclinker = false;
  332     bool rungcc = false;
  333     char *keys [10];
  334     char **gccopt, **cppopt, **nccopt, **files, **objfiles, **nofileopt;
  335     char *ofile = 0;
  336     int gccno, cppno, nccno, filesno, objfileno, nofileno, keyno;
  337 
  338     cppopt = (char**) alloca ((8 + argc) * sizeof (char*));
  339     nccopt = (char**) alloca ((3 + argc) * sizeof (char*));
  340     gccopt = (char**) alloca ((3 + argc) * sizeof (char*));
  341     files = (char**) alloca (argc * sizeof (char*));
  342     objfiles = (char**) alloca (argc * sizeof (char*));
  343     nofileopt = (char**) alloca ((3 + argc) * sizeof (char*));
  344 
  345     cppopt [0] = gccopt [0] = "gcc";
  346     cppopt [1] = "-E";
  347     cppopt [2] = "-D__NCC__";
  348     cppopt [3] = "-imacros";
  349     cppopt [4] = NOGNU;
  350     nofileopt [0] = "ncc";
  351     files [0] = NULL;
  352     cppno = 5;
  353     gccno = 1;
  354     keyno = filesno = nccno = objfileno = 0;
  355     nofileno = 1;
  356     for (i = 1; i < argc; i++)
  357         if (argv [i][0] == '-' && argv [i][1] == 'n'
  358         && argv [i][2] == 'c') {
  359             nccopt [nccno++] =
  360              (nofileopt [nofileno++] = argv[i]) + 3;
  361             if (!strcmp (argv [i], "-ncld"))
  362                 ncclinker = true;
  363             else if (!strcmp (argv [i], "-ncgcc"))
  364                 rungcc = true;
  365         }
  366         else {
  367             gccopt [gccno++] = argv [i];
  368             if (issource (argv [i]))
  369                 cppopt [cppno++] = files [filesno++] = argv [i];
  370             else {
  371                 nofileopt [nofileno++] = argv [i];
  372                 if (isobj (argv [i]))
  373                     objfiles [objfileno++] = argv [i];
  374                 if (argv [i][0] == '-')
  375                 if (argv [i][1] == 'O' || argv [i][1] == 'm') goto addit;
  376                 else if (argv [i][1] == 'D' || argv [i][1] == 'I')
  377                     if (argv [i][2] == 0) goto separate;
  378                     else addit: cppopt [cppno++] = argv [i];
  379                 else if (argv [i][1] == 'i') {
  380                 separate:
  381                     cppopt [cppno++] = argv [i++];
  382                     gccopt [gccno++] = cppopt [cppno++] =
  383                                argv [i];
  384                 } else if (argv [i][1] == 'E')
  385                     dontdoit = true;
  386             }
  387             if (!strcmp (argv [i], "-o"))
  388                 gccopt [gccno++] = ofile = argv [++i];
  389             else if (!strcmp (argv [i], "-c")) mkobj = 1;
  390         }
  391     if (!mkobj && ncclinker)
  392         nofileopt [nofileno++] = "-c";
  393 
  394     nccopt [nccno] = gccopt [gccno] = cppopt [cppno] =
  395     nofileopt [nofileno + 1] = NULL;
  396 
  397     if (!ofile)
  398         ofile = mkobj ? filesno != 1 ? 0 : objfile (files [0]) : (char*) "a.out";
  399 
  400     if (filesno > 1) {
  401         if (rungcc)
  402             RUN (NULL, gccopt);
  403         fprintf (stderr, "Multiple files. Forking\n");
  404         if (ofile)
  405             for (i = 0; i < nofileno; i++)
  406                 if (!strcmp (nofileopt [i], "-o"))
  407                     nofileopt [i] = "-c";
  408         if (rungcc)
  409             for (i = 0; i < nofileno; i++)
  410                 if (!strcmp (nofileopt [i], "-ncgcc"))
  411                     nofileopt [i] = "-nc-";
  412         for (i = 0; i < filesno; i++) {
  413             nofileopt [nofileno] = files [i];
  414             RUN (NULL, nofileopt);
  415             if (ncclinker)
  416                 objfiles [objfileno++] = objfile (files [i]);
  417         }
  418         if (ncclinker) {
  419             if (ofile) openout (ofile);
  420             LINK (objfiles, objfileno);
  421             if (ofile) stripout (ofile);
  422         }
  423         exit (0);
  424     }
  425 
  426     include_values = usage_only = true;
  427     multiple = false;
  428     for (i = 0; i < nccno; i++)
  429         if (0);
  430 #define     NCCOPT(x) else if (!strcmp (nccopt [i], x))
  431 #define     NCCPOPT(x) else if (!strncmp (nccopt [i], x, sizeof x - 1))
  432         NCCPOPT("gcc=") {
  433             gccopt [0] = nccopt [i] + 4;
  434             RUN (NULL, gccopt);
  435         }
  436         NCCOPT ("-");
  437         NCCOPT ("gcc")  RUN (NULL, gccopt);
  438         NCCOPT ("cc")   usage_only = false;
  439         NCCOPT ("err")  halt_on_error = true;
  440         NCCOPT ("noerr")no_error = true;
  441         NCCOPT ("mv")   multiple = true;
  442         NCCOPT ("pc")   multiple = pseudo_code = true;
  443         NCCOPT ("oo")   openout (files [0]);
  444         NCCOPT ("ld")   openout (ofile);
  445         NCCOPT ("00")   include_values = false;
  446         NCCOPT ("spp")  spp = true;
  447         NCCOPT ("fabs") abs_paths = true;
  448         NCCOPT ("nrs")  report_structs = false;
  449         NCCPOPT ("cpp=") cppopt [0] = nccopt [i] + 4;
  450         NCCPOPT ("key")  keys [keyno++] = nccopt [i] + 3;
  451         NCCOPT ("quiet");
  452         else {
  453             fputs (help, stderr);
  454             exit (strcmp (nccopt [i], "help") != 0);
  455         }
  456 
  457     if (!(sourcefile = files [0])) {
  458         if (objfileno) {
  459             LINK (objfiles, objfileno);
  460             if (ofile)
  461                 stripout (ofile);
  462         } else fprintf (stderr, "ncc: No C source file\n");
  463         exit (0);
  464     }
  465     if (dontdoit) {
  466         fprintf (stderr, "ncc: '-E'. Won't do it...\n");
  467         exit (0);
  468     }
  469     if (spp) {
  470         preprocfile = StrDup (sourcefile);
  471         preprocfile [strlen (preprocfile) - 1] = 'i';
  472     }
  473     if (keyno) {
  474         ncc_key = new char* [keyno + 1];
  475         for (i = 0; i < keyno; i++) ncc_key [i] = keys [i];
  476         ncc_key [i] = NULL;
  477     }
  478     if (usage_only) set_usage_report ();
  479     else set_compilation ();
  480 
  481     include_strings = include_values || ncc_key;
  482 
  483     if (objfileno)
  484         LINK (objfiles, objfileno);
  485 
  486     RUN (preprocfile, cppopt);
  487 }
  488 
  489 void ncc_keys ()
  490 {
  491 #define KSZ (sizeof NCC_INFILE_KEY - 1)
  492     int i, j;
  493     if (ncc_key)
  494     for (i = 0; i < C_Nstrings; i++)
  495     if (!strncmp (C_Strings [i], NCC_INFILE_KEY, KSZ)) {
  496         for (j = 0; ncc_key [j]; j++)
  497             if (!strncmp (C_Strings [i] + KSZ, ncc_key [j],
  498                       strlen (ncc_key [j]))) break;
  499         if (ncc_key [j])
  500             PRINTF ("%s", C_Strings [i] + KSZ +
  501                 strlen (ncc_key [j]));
  502     }
  503 }