LCOV - code coverage report
Current view: top level - libreoffice/dmake - dmake.c (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 212 403 52.6 %
Date: 2012-12-17 Functions: 11 18 61.1 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             : --
       3             : -- SYNOPSIS
       4             : --      The main program.
       5             : --
       6             : -- DESCRIPTION
       7             : --
       8             : --  dmake [-#dbug_string] [ options ]
       9             : --          [ macro definitions ] [ target ... ]
      10             : --
      11             : --  This file contains the main command line parser for the
      12             : --  make utility.  The valid flags recognized are as follows:
      13             : --
      14             : --  -f file         - use file as the makefile
      15             : --  -C file     - duplicate console output to file (MSDOS only)
      16             : --  -K file     - .KEEP_STATE file
      17             : --  -#dbug_string   - dump out debugging info, see below
      18             : --  -v[cdfimrtw]    - verbose, print what we are doing, as we do it
      19             : --  -m[trae]    - measure timing information
      20             : --
      21             : --   options: (can be catenated, ie -irn == -i -r -n)
      22             : --
      23             : --  -A      - enable AUGMAKE special target mapping
      24             : --  -B      - enable non-use of TABS to start recipe lines
      25             : --  -c      - use non-standard comment scanning
      26             : --      -d              - do not use directory cache
      27             : --  -i              - ignore errors
      28             : --  -n              - trace and print, do not execute commands
      29             : --  -t              - touch, update dates without executing commands
      30             : --  -T              - do not apply transitive closure on inference rules
      31             : --  -r              - don't use internal rules
      32             : --  -s              - do your work silently
      33             : --  -S      - force Sequential make, overrides -P
      34             : --  -q              - check if target is up to date.  Does not
      35             : --            do anything.  Returns 0 if up to date, -1
      36             : --            otherwise.
      37             : --  -p              - print out a version of the makefile
      38             : --  -P#     - set value of MAXPROCESS
      39             : --  -E              - define environment strings as macros
      40             : --  -e              - as -E but done after parsing makefile
      41             : --  -u              - force unconditional update of target
      42             : --  -k              - make all independent targets even if errors
      43             : --  -V              - print out this make version number
      44             : --  -M      - Microsoft make compatibility, (* disabled *)
      45             : --  -h              - print out usage info
      46             : --  -x      - export macro defs to environment
      47             : --      -X              - ignore #! lines found in makefile
      48             : --
      49             : --  NOTE:  - #ddbug_string is only availabe for versions of dmake that
      50             : --      have been compiled with -DDBUG switch on.  Not the case for
      51             : --      distributed versions.  Any such versions must be linked
      52             : --      together with a version of Fred Fish's debug code.
      53             : --
      54             : --  NOTE:  - in order to compile the code the include file stddef.h
      55             : --      must be shipped with the bundled code.
      56             : --
      57             : -- AUTHOR
      58             : --      Dennis Vadura, dvadura@dmake.wticorp.com
      59             : --
      60             : -- WWW
      61             : --      http://dmake.wticorp.com/
      62             : --
      63             : -- COPYRIGHT
      64             : --      Copyright (c) 1996,1997 by WTI Corp.  All rights reserved.
      65             : --
      66             : --      This program is NOT free software; you can redistribute it and/or
      67             : --      modify it under the terms of the Software License Agreement Provided
      68             : --      in the file <distribution-root>/readme/license.txt.
      69             : --
      70             : -- LOG
      71             : --      Use cvs log to obtain detailed change logs.
      72             : */
      73             : 
      74             : /* Set this flag to one, and the global variables in vextern.h will not
      75             :  * be defined as 'extern', instead they will be defined as global vars
      76             :  * when this module is compiled. */
      77             : #define _DEFINE_GLOBALS_ 1
      78             : 
      79             : #include "extern.h" /* this includes config.h */
      80             : #include "sysintf.h"
      81             : 
      82             : #ifndef MSDOS
      83             : #define USAGE \
      84             : "Usage:\n%s [-P#] [-{f|K} file] [-{w|W} target ...] [macro[!][[*][+][:]]=value ...]\n"
      85             : #define USAGE2 \
      86             : "%s [-v[cdfimrtw]] [-m[trae]] [-ABcdeEghiknpqrsStTuVxX] [target ...]\n"
      87             : #else
      88             : #define USAGE \
      89             : "Usage:\n%s [-P#] [-{f|C|K} file] [-{w|W} target ...] [macro[!][[*][+][:]]=value ...]\n"
      90             : #define USAGE2 \
      91             : "%s [-v[cdfimrtw]] [-m[trae]] [-ABcdeEghiknpqrsStTuVxX] [target ...]\n"
      92             : #endif
      93             : 
      94             : /* We don't use va_end at all, so define it out so that it doesn't produce
      95             :  * lots of "Value not used" warnings. */
      96             : #ifdef va_end
      97             : #undef va_end
      98             : #endif
      99             : #define va_end(expand_to_null)
     100             : 
     101             : /* Make certain that ARG macro is correctly defined. */
     102             : #ifdef ARG
     103             : #undef ARG
     104             : #endif
     105             : #define ARG(a,b) a b
     106             : 
     107             : static char *sccid = "Copyright (c) 1990,...,1997 by WTI Corp.";
     108             : static char _warn  = TRUE;      /* warnings on by default */
     109             : 
     110             : static  void    _do_VPATH();
     111             : static  void    _do_ReadEnvironment();
     112             : #if !defined(__GNUC__) && !defined(__IBMC__)
     113             : static  void    _do_f_flag ANSI((char, char *, char **));
     114             : #else
     115             : static  void    _do_f_flag ANSI((int, char *, char **));
     116             : #endif
     117             : 
     118             : PUBLIC int
     119         188 : main(argc, argv)
     120             : int  argc;
     121             : char **argv;
     122             : {
     123             : #ifdef MSDOS
     124             :    char*   std_fil_name = NIL(char);
     125             : #endif
     126             : 
     127         188 :    char*   fil_name = NIL(char);
     128         188 :    char*   state_name = NIL(char);
     129         188 :    char*   whatif = NIL(char);
     130             :    char*   cmdmacs;
     131             :    char*   targets;
     132         188 :    STRINGPTR cltarget = NIL(STRING); /* list of targets from command line. */
     133         188 :    STRINGPTR cltarget_first = NIL(STRING); /* Pointer to first element. */
     134             :    FILE*   mkfil;
     135             :    int     ex_val;
     136             :    int     m_export;
     137             : 
     138             :    /* Uncomment the following line to pass commands to the DBUG engine
     139             :     * before the command line switches (-#..) are evaluated. */
     140             :    /*
     141             :    DB_PUSH("d,path");
     142             :     */
     143             :    DB_ENTER("main");
     144             : 
     145             :    /* Initialize Global variables to their default values       */
     146         188 :    Prolog(argc, argv);
     147             :    /* Set internal macros to their initial values, some are changed
     148             :     * later again by Make_rules() that parses the values from ruletab.c. */
     149         188 :    Create_macro_vars();
     150         188 :    Catch_signals(Quit);
     151             : 
     152             :    /* This macro is only defined for some OSs, see sysintf.c for details *
     153             :     * and NULL if undefined.                                             */
     154         188 :    Def_macro("ABSMAKECMD", AbsPname, M_PRECIOUS|M_NOEXPORT|M_EXPANDED );
     155             : 
     156         188 :    Def_macro( "MAKECMD", Pname, M_PRECIOUS|M_NOEXPORT|M_EXPANDED );
     157         188 :    Pname = Basename(Pname);
     158             : 
     159             :    DB_PROCESS(Pname);
     160         188 :    (void) setvbuf(stdout, NULL, _IOLBF, BUFSIZ); /* stdout line buffered */
     161             : 
     162         188 :    Continue  = FALSE;
     163         188 :    Comment   = FALSE;
     164         188 :    Get_env   = FALSE;
     165         188 :    Force     = FALSE;
     166         188 :    Target    = FALSE;
     167         188 :    If_expand = FALSE;
     168         188 :    Listing   = FALSE;
     169         188 :    Readenv   = FALSE;
     170         188 :    Rules     = TRUE;
     171         188 :    Trace     = FALSE;
     172         188 :    Touch     = FALSE;
     173         188 :    Check     = FALSE;
     174         188 :    Microsoft = FALSE;
     175         188 :    Makemkf   = FALSE;
     176         188 :    UseWinpath= FALSE;
     177         188 :    No_exec   = FALSE;
     178         188 :    m_export  = FALSE;
     179         188 :    cmdmacs   = NIL(char);
     180         188 :    targets   = NIL(char);
     181         188 :    Is_exec_shell = FALSE;
     182         188 :    Shell_exec_target = NIL(CELL);
     183         188 :    stdout_redir = NIL(FILE);
     184             : 
     185             :    /* Get fd for for @@-recipe silencing. */
     186         188 :    if( (zerofd = open(NULLDEV, O_WRONLY)) == -1 )
     187           0 :       Fatal( "Error opening %s !", NULLDEV );
     188             : 
     189         188 :    Verbose     = V_NOFLAG;
     190         188 :    Measure     = M_NOFLAG;
     191         188 :    Transitive  = TRUE;
     192         188 :    Nest_level  = 0;
     193         188 :    Line_number = 0;
     194         188 :    Suppress_temp_file = FALSE;
     195         188 :    Skip_to_eof = FALSE;
     196             : 
     197         560 :    while( --argc > 0 ) {
     198             :       register char *p;
     199             :       char *q;
     200             : 
     201         188 :       if( *(p = *++argv) == '-' ) {
     202         188 :          if( p[1] == '\0' ) Fatal("Missing option letter");
     203             : 
     204             :          /* copy options to Buffer for $(MFLAGS), strip 'f' and 'C'*/
     205         188 :          q = strchr(Buffer, '\0');
     206         936 :          while (*p != '\0') {
     207         560 :         char c = (*q++ = *p++);
     208         560 :             if( c == 'f' || c == 'C' ) q--;
     209             :      }
     210             : 
     211         188 :      if( *(q-1) == '-' )
     212           0 :         q--;
     213             :      else
     214         188 :             *q++ = ' ';
     215             : 
     216         188 :      *q = '\0';
     217             : 
     218         372 :          for( p = *argv+1; *p; p++) switch (*p) {
     219             :         case 'f':
     220           0 :            _do_f_flag( 'f', *++argv, &fil_name ); argc--;
     221           0 :            break;
     222             : 
     223             : #if defined(MSDOS) && !defined(OS2)
     224             :         case 'C':
     225             :            _do_f_flag( 'C', *++argv, &std_fil_name ); argc--;
     226             :            Hook_std_writes( std_fil_name );
     227             :            break;
     228             : #endif
     229             : 
     230             :         case 'K':
     231           0 :            _do_f_flag( 'K', *++argv, &state_name ); argc--;
     232           0 :            Def_macro(".KEEP_STATE", state_name, M_EXPANDED|M_PRECIOUS);
     233           0 :            break;
     234             : 
     235             :         case 'W':
     236             :         case 'w': {
     237             :            CELLPTR wif;
     238           0 :            _do_f_flag( 'w', *++argv, &whatif ); argc--;
     239           0 :            wif = Def_cell(whatif);
     240           0 :            wif->ce_attr |= A_WHATIF;
     241           0 :            whatif = NIL(char);
     242             : 
     243           0 :            if ( *p == 'W')
     244           0 :           break;
     245             :         }
     246             :         /*FALLTHRU*/
     247             : 
     248             :         case 'n':
     249           0 :            Trace = TRUE;
     250           0 :            break;
     251             : 
     252           0 :         case 'k': Continue   = TRUE;  break;
     253           0 :         case 'c': Comment    = TRUE;  break;
     254           0 :         case 'p': Listing    = TRUE;  break;
     255           0 :         case 'r': Rules      = FALSE; break;
     256           0 :         case 't': Touch      = TRUE;  break;
     257           0 :         case 'q': Check      = TRUE;  break;
     258           0 :         case 'u': Force      = TRUE;  break;
     259           0 :         case 'x': m_export   = TRUE;  break;
     260           0 :         case 'X': No_exec    = TRUE;  break;
     261           0 :         case 'T': Transitive = FALSE; break;
     262           0 :         case 'e': Get_env    = 'e';   break;
     263           0 :         case 'E': Get_env    = 'E';   break;
     264             : 
     265           4 :         case 'V': Version();  Quit(0);  break;
     266           0 :         case 'A': Def_macro("AUGMAKE", "y", M_EXPANDED); break;
     267           0 :         case 'B': Def_macro(".NOTABS", "y", M_EXPANDED); break;
     268           0 :         case 'i': Def_macro(".IGNORE", "y", M_EXPANDED); break;
     269           0 :         case 's': Def_macro(".SILENT", "y", M_EXPANDED); break;
     270           0 :         case 'S': Def_macro(".SEQUENTIAL", "y", M_EXPANDED); break;
     271           0 :         case 'g': Def_macro(".IGNOREGROUP","y", M_EXPANDED); break;
     272           0 :         case 'd': Def_macro(".DIRCACHE",NIL(char),M_EXPANDED); break;
     273             : 
     274             :         case 'v':
     275           0 :            if( p[-1] != '-' ) Usage(TRUE);
     276           0 :            while( p[1] ) switch( *++p ) {
     277           0 :           case 'c': Verbose |= V_DIR_CACHE; break;
     278           0 :           case 'd': Verbose |= V_DIR_SET;   break;
     279           0 :           case 'f': Verbose |= V_FILE_IO;   break;
     280           0 :           case 'i': Verbose |= V_INFER;     break;
     281           0 :           case 'm': Verbose |= V_MAKE;      break;
     282           0 :                   case 'r': Verbose |= V_FORCEECHO; break;
     283           0 :           case 't': Verbose |= V_LEAVE_TMP; break;
     284           0 :                   case 'w': Verbose |= V_WARNALL;   break;
     285             : 
     286           0 :           default: Usage(TRUE); break;
     287             :            }
     288           0 :            if( !Verbose ) Verbose = V_ALL;
     289           0 :                if( Verbose & V_FORCEECHO ) {
     290             :                  HASHPTR hp;
     291             :                  /* This cleans the .SILENT setting */
     292           0 :                  hp = Def_macro(".SILENT", "", M_EXPANDED);
     293             :                  /* This overrides the bitmask for further occurrences of
     294             :                   * .SILENT to "no bits allowed", see bit variables in the
     295             :                   * set_macro_value() definition in dag.c.
     296             :                   * The bitmask is already set by Create_macro_vars() in
     297             :                   * imacs.c and is overridden for the V_FORCEECHO case. */
     298           0 :                  hp->MV_MASK  = A_DEFAULT;
     299             :                }
     300           0 :            break;
     301             : 
     302             :         case 'm':
     303           0 :            if( p[-1] != '-' ) Usage(TRUE);
     304           0 :            while( p[1] ) switch( *++p ) {
     305           0 :           case 't': Measure |= M_TARGET;    break;
     306           0 :           case 'r': Measure |= M_RECIPE;    break;
     307           0 :           case 'a': Measure |= M_ABSPATH;   break;
     308           0 :           case 'e': Measure |= M_SHELLESC;  break;
     309             : 
     310           0 :           default: Usage(TRUE); break;
     311             :            }
     312           0 :            if( !Measure ) Measure = M_TARGET;
     313           0 :            break;
     314             : 
     315             :         case 'P':
     316         184 :            if( p[1] ) {
     317             :           /* Only set MAXPROCESS if -S flag is *not* used. */
     318         184 :           if( !(Glob_attr & A_SEQ) ) {
     319         184 :              Def_macro( "MAXPROCESS", p+1, M_MULTI|M_EXPANDED );
     320             :           }
     321         184 :           p += strlen(p)-1;
     322             :            }
     323             :            else
     324           0 :           Fatal( "Missing number for -P flag" );
     325         184 :            break;
     326             : 
     327             : #ifdef DBUG
     328             :         case '#':
     329             :            DB_PUSH(p+1);
     330             :            p += strlen(p)-1;
     331             :            break;
     332             : #endif
     333             : 
     334           0 :         case 'h': Usage(FALSE); break;
     335           0 :         case 0:   break;    /* lone - */
     336           0 :         default:  Usage(TRUE);  break;
     337             :      }
     338             :       }
     339           0 :       else if( (q = strchr(p, '=')) != NIL(char) ) {
     340           0 :      cmdmacs = DmStrAdd( cmdmacs, DmStrDup2(p), TRUE );
     341             :      /* Macros defined on the command line are marked precious.
     342             :       * FIXME: The exception for += appears to be bogus. */
     343           0 :      Parse_macro( p, (q[-1]!='+')?M_PRECIOUS:M_DEFAULT );
     344             :       }
     345             :       else {
     346             :      /* Remember the targets from the command line. */
     347             :      register STRINGPTR nsp;
     348             : 
     349           0 :      targets = DmStrAdd( targets, DmStrDup(p), TRUE );
     350             : 
     351           0 :      TALLOC(nsp, 1, STRING);
     352           0 :      nsp->st_string = DmStrDup( p );
     353           0 :      nsp->st_next = NIL(STRING);
     354             : 
     355           0 :      if(cltarget != NIL(STRING) )
     356           0 :         cltarget->st_next = nsp;
     357             :      else
     358           0 :         cltarget_first = nsp;
     359             : 
     360           0 :      cltarget = nsp;
     361             :       }
     362             :    }
     363             : 
     364         184 :    Def_macro( "MAKEMACROS",  cmdmacs, M_PRECIOUS|M_NOEXPORT );
     365         184 :    Def_macro( "MAKETARGETS", targets, M_PRECIOUS|M_NOEXPORT );
     366         184 :    if( cmdmacs != NIL(char) ) FREE(cmdmacs);
     367         184 :    if( targets != NIL(char) ) FREE(targets);
     368             : 
     369         184 :    Def_macro( "MFLAGS", Buffer, M_PRECIOUS|M_NOEXPORT );
     370         184 :    Def_macro( "%", "$@", M_PRECIOUS|M_NOEXPORT );
     371             : 
     372         184 :    if( *Buffer ) Def_macro( "MAKEFLAGS", Buffer+1, M_PRECIOUS|M_NOEXPORT );
     373             : 
     374         184 :    _warn  = FALSE;  /* disable warnings for builtin rules */
     375         184 :    Target = TRUE;   /* make sure we don't mark any of the default rules as
     376             :              * potential targets. */
     377         184 :    Make_rules();    /* Parse the strings stored in Rule_tab. */
     378         184 :    _warn = TRUE;
     379             : 
     380             :    /* If -r was not given find and parse startup-makefile. */
     381         184 :    if( Rules )
     382             :    {
     383         184 :      char *fname = NIL(char);
     384             : 
     385             :      /* Search_file() also checks the environment variable. */
     386         184 :      if( (mkfil=Search_file("MAKESTARTUP", &fname)) != NIL(FILE) )
     387             :      {
     388         184 :        Parse(mkfil);
     389         184 :        Def_macro( "MAKESTARTUP", fname, M_EXPANDED|M_MULTI|M_FORCE );
     390             :      }
     391             :      else
     392           0 :        Fatal( "Configuration file `%s' not found", fname );
     393         184 :      if ( fname != NIL(char)) { FREE( fname ); fname = NIL(char); }
     394             :    }
     395             : 
     396             :    /* Define the targets set on the command line now. */
     397         184 :    Target = FALSE;  /* Will be set to TRUE when the default targets are set. */
     398         368 :    for( cltarget = cltarget_first; cltarget != NIL(STRING); ) {
     399             :       CELLPTR cp;
     400           0 :       STRINGPTR nta = cltarget->st_next;
     401             : 
     402           0 :       Add_prerequisite(Targets, cp = Def_cell(cltarget->st_string),
     403             :                FALSE, FALSE);
     404           0 :       cp->ce_flag |= F_TARGET;
     405           0 :       cp->ce_attr |= A_FRINGE;
     406           0 :       Target = TRUE;
     407             : 
     408           0 :       FREE(cltarget->st_string);
     409           0 :       FREE(cltarget);
     410           0 :       cltarget = nta;
     411             :    }
     412             : 
     413         184 :    if( Get_env == 'E' ) _do_ReadEnvironment();
     414             : 
     415             :    /* Search for and parse user makefile. */
     416         184 :    if( fil_name != NIL(char) )
     417           0 :       mkfil = Openfile( fil_name, FALSE, TRUE );
     418             :    else {
     419             :       /* Search .MAKEFILES dependent list looking for a makefile.
     420             :        */
     421             :       register CELLPTR cp;
     422             : 
     423         184 :       cp = Def_cell( ".MAKEFILES" );
     424         184 :       mkfil = TryFiles(cp->CE_PRQ);
     425             :    }
     426             : 
     427         184 :    if( mkfil != NIL(FILE) ) {
     428         184 :       char *f = Filename();
     429             :       char *p;
     430             : 
     431         184 :       if( strcmp(f, "stdin") == 0 ) f = "-";
     432         184 :       Def_macro( "MAKEFILE", p = DmStrAdd( "-f", f, FALSE ), M_PRECIOUS|M_NOEXPORT ); FREE(p);
     433         184 :       Parse( mkfil );
     434             :    }
     435           0 :    else if( !Rules )
     436           0 :       Fatal( "No `makefile' present" );
     437             : 
     438         184 :    if( Nest_level     ) Fatal( "Missing .END for .IF" );
     439         184 :    if( Get_env == 'e' ) _do_ReadEnvironment();
     440             : 
     441         184 :    _do_VPATH();                 /* kludge it up with .SOURCE    */
     442             : 
     443         184 :    if( Listing ) Dump();        /* print out the structures     */
     444         184 :    if( Trace ) Glob_attr &= ~A_SILENT;  /* make sure we see the trace   */
     445             : 
     446         184 :    if( !Target )
     447           0 :       Fatal( "No target" );
     448             :    else {
     449         184 :       Test_circle( Root, TRUE );
     450         184 :       Check_circle_dfa();
     451             :    }
     452             : 
     453         184 :    if( m_export ) {
     454             :       int i;
     455             : 
     456           0 :       for( i=0; i<HASH_TABLE_SIZE; ++i ) {
     457           0 :      HASHPTR hp = Macs[i];
     458             : 
     459           0 :      while( hp ) {
     460           0 :         if( !(hp->ht_flag & M_NOEXPORT) && hp->ht_value != NIL(char) )
     461           0 :            if( Write_env_string(hp->ht_name, hp->ht_value) != 0 )
     462           0 :            Warning( "Could not export %s", hp->ht_name );
     463           0 :         hp = hp->ht_next;
     464             :      }
     465             :       }
     466             :    }
     467             : 
     468         184 :    if( Buffer != NIL(char) ) {FREE( Buffer ); Buffer = NIL(char);}
     469         184 :    if( Trace ) Def_macro(".SEQUENTIAL", "y", M_EXPANDED);
     470             : 
     471         184 :    ex_val = Make_targets();
     472             : 
     473         184 :    Clear_signals();
     474             : 
     475             :    /* Close fd for for @@-recipe silencing. */
     476         184 :    if( close(zerofd) )
     477           0 :       Fatal( "Error closing %s !", NULLDEV );
     478         184 :    Epilog(ex_val);      /* Does not return -- EVER */
     479           0 :    return 0;
     480             : }
     481             : 
     482             : 
     483             : static void
     484           0 : _do_f_flag( flag, name, fname )
     485             : char   flag;
     486             : char  *name;
     487             : char **fname;
     488             : {
     489           0 :    if( *fname == NIL(char) ) {
     490           0 :       if( name != NIL(char) ) {
     491           0 :      *fname = name;
     492             :       } else
     493           0 :      Fatal("No file name for -%c", flag);
     494             :    } else
     495           0 :       Fatal("Only one `-%c file' allowed", flag);
     496           0 : }
     497             : 
     498             : 
     499             : static void
     500           0 : _do_ReadEnvironment()
     501             : {
     502           0 :    t_attr saveattr = Glob_attr;
     503             : 
     504           0 :    Glob_attr |= A_SILENT;
     505           0 :    ReadEnvironment();
     506           0 :    Glob_attr = saveattr;
     507           0 : }
     508             : 
     509             : 
     510             : static void
     511         184 : _do_VPATH()
     512             : {
     513             :    HASHPTR hp;
     514             :    char    *_rl[2];
     515             :    extern char **Rule_tab;
     516             : 
     517         184 :    hp = GET_MACRO("VPATH");
     518         368 :    if( hp == NIL(HASH) ) return;
     519             : 
     520           0 :    _rl[0] = ".SOURCE :^ $(VPATH:s/:/ /)";
     521           0 :    _rl[1] = NIL(char);
     522             : 
     523           0 :    Rule_tab = _rl;
     524           0 :    Parse( NIL(FILE) );
     525             : }
     526             : 
     527             : 
     528             : /*  The file table and pointer to the next FREE slot for use by both
     529             :     Openfile and Closefile.  Each open stacks the new file onto the open
     530             :     file stack, and a corresponding close will close the passed file, and
     531             :     return the next file on the stack.  The maximum number of nested
     532             :     include files is limited by the value of MAX_INC_DEPTH */
     533             : 
     534             : static struct {
     535             :    FILE         *file;      /* file pointer                 */
     536             :    char         *name;      /* name of file                 */
     537             :    int          numb;       /* line number                  */
     538             : } ftab[ MAX_INC_DEPTH ];
     539             : 
     540             : static int next_file_slot = 0;
     541             : 
     542             : /* Set the proper macro value to reflect the depth of the .INCLUDE directives
     543             :  * and the name of the file we are reading.
     544             :  */
     545             : static void
     546        9184 : _set_inc_depth()
     547             : {
     548             :    char buf[10];
     549        9184 :    sprintf( buf, "%d", next_file_slot );
     550        9184 :    Def_macro( "INCDEPTH", buf, M_MULTI|M_NOEXPORT );
     551       18000 :    Def_macro( "INCFILENAME",
     552       18000 :               next_file_slot ? ftab[next_file_slot-1].name : "",
     553             :               M_MULTI|M_NOEXPORT|M_EXPANDED );
     554        9184 : }
     555             : 
     556             : 
     557             : PUBLIC FILE *
     558       14398 : Openfile(name, mode, err)/*
     559             : ===========================
     560             :    This routine opens a file for input or output depending on mode.
     561             :    If the file name is `-' then it returns standard input.
     562             :    The file is pushed onto the open file stack.  */
     563             : char *name;
     564             : int  mode;
     565             : int  err;
     566             : {
     567             :    FILE *fil;
     568             : 
     569             :    DB_ENTER("Openfile");
     570             : 
     571       14398 :    if( name == NIL(char) || !*name ) {
     572         552 :       if( !err )
     573         552 :          DB_RETURN(NIL(FILE));
     574             :       else
     575           0 :          Fatal( "Openfile:  NIL filename" );
     576             :    }
     577             : 
     578       13846 :    if( next_file_slot == MAX_INC_DEPTH )
     579           0 :       Fatal( "Too many open files. Max nesting level is %d.", MAX_INC_DEPTH);
     580             : 
     581             :    DB_PRINT( "io", ("Opening file [%s], in slot %d", name, next_file_slot) );
     582             : 
     583       13846 :    if( strcmp("-", name) == 0 ) {
     584           0 :       name = "stdin";
     585           0 :       fil = stdin;
     586             :    }
     587             :    else
     588       13846 :       fil = fopen( name, mode ? "w":"r" );
     589             : 
     590       13846 :    if( Verbose & V_FILE_IO )
     591           0 :       printf( "%s:  Openning [%s] for %s", Pname, name, mode?"write":"read" );
     592             : 
     593       13846 :    if( fil == NIL(FILE) ) {
     594        9254 :       if( Verbose & V_FILE_IO ) printf( " (fail)\n" );
     595        9254 :       if( err )
     596           0 :          Fatal( mode ? "Cannot open file %s for write" : "File %s not found",
     597             :         name );
     598             :    }
     599             :    else {
     600        4592 :       if( Verbose & V_FILE_IO ) printf( " (success)\n" );
     601        4592 :       ftab[next_file_slot].file   = fil;
     602        4592 :       ftab[next_file_slot].numb   = Line_number;
     603        4592 :       ftab[next_file_slot++].name = DmStrDup(name);
     604        4592 :       Line_number = 0;
     605        4592 :       _set_inc_depth();
     606             :    }
     607             : 
     608       13846 :    DB_RETURN(fil);
     609             : }
     610             : 
     611             : 
     612             : PUBLIC FILE *
     613        4596 : Closefile()/*
     614             : =============
     615             :    This routine is used to close the last file opened.  This forces make
     616             :    to open files in a last open first close fashion.  It returns the
     617             :    file pointer to the next file on the stack, and NULL if the stack is empty.*/
     618             : {
     619             :    DB_ENTER("Closefile");
     620             : 
     621        4596 :    if( !next_file_slot )
     622           4 :       DB_RETURN( NIL(FILE) );
     623             : 
     624        4592 :    if( ftab[--next_file_slot].file != stdin ) {
     625             :       DB_PRINT( "io", ("Closing file in slot %d", next_file_slot) );
     626             : 
     627        4592 :       if( Verbose & V_FILE_IO )
     628           0 :      printf( "%s:  Closing [%s]\n", Pname, ftab[next_file_slot].name );
     629             : 
     630        4592 :       fclose( ftab[next_file_slot].file );
     631        4592 :       FREE( ftab[next_file_slot].name );
     632             :    }
     633             : 
     634        4592 :    _set_inc_depth();
     635             : 
     636        4592 :    if( next_file_slot > 0 ) {
     637        4224 :       Line_number = ftab[next_file_slot].numb;
     638        4224 :       DB_RETURN( ftab[next_file_slot-1].file );
     639             :    }
     640             :    else
     641         368 :       Line_number = 0;
     642             : 
     643         368 :    DB_RETURN( NIL(FILE) );
     644             : }
     645             : 
     646             : 
     647             : PUBLIC FILE *
     648         368 : Search_file( macname, rname )
     649             : char *macname;
     650             : char **rname;
     651             : {
     652             :    HASHPTR hp;
     653         368 :    FILE *fil = NIL(FILE);
     654         368 :    char *fname = NIL(char);
     655         368 :    char *ename = NIL(char);
     656             : 
     657             :    /* order of precedence is:
     658             :     *
     659             :     *   MACNAME  from command line (precious is marked)
     660             :     *        ... via MACNAME:=filename definition.
     661             :     *   MACNAME  from environment
     662             :     *   MACNAME  from builtin rules (not precious)
     663             :     */
     664             : 
     665         368 :    if( (hp = GET_MACRO(macname)) != NIL(HASH) ) {
     666             :      /* Only expand if needed. */
     667         368 :      if( hp->ht_flag & M_EXPANDED ) {
     668         368 :        ename = fname = DmStrDup(hp->ht_value);
     669             :      } else {
     670           0 :        ename = fname = Expand(hp->ht_value);
     671             :      }
     672             : 
     673         368 :      if( hp->ht_flag & M_PRECIOUS ) fil = Openfile(fname, FALSE, FALSE);
     674             :    }
     675             : 
     676         368 :    if( fil == NIL(FILE) ) {
     677         368 :      fname=Expand(Read_env_string(macname));
     678         368 :      if( (fil = Openfile(fname, FALSE, FALSE)) != NIL(FILE) ) FREE(ename);
     679             :    }
     680             : 
     681         368 :    if( fil == NIL(FILE) && hp != NIL(HASH) ) {
     682         368 :      if ( fname != NIL(char) ) { FREE(fname); fname = NIL(char); }
     683         368 :      fil = Openfile(fname=ename, FALSE, FALSE);
     684             :    }
     685             : 
     686         368 :    if( rname ) *rname = fname;
     687             : 
     688         368 :    return(fil);
     689             : }
     690             : 
     691             : 
     692             : PUBLIC char *
     693         186 : Filename()/*
     694             : ============
     695             :    Return name of file on top of stack */
     696             : {
     697         186 :    return( next_file_slot==0 ? NIL(char) : ftab[next_file_slot-1].name );
     698             : }
     699             : 
     700             : 
     701             : PUBLIC int
     702           0 : Nestlevel()/*
     703             : =============
     704             :    Return the file nesting level */
     705             : {
     706           0 :    return( next_file_slot );
     707             : }
     708             : 
     709             : 
     710             : PUBLIC FILE *
     711         740 : TryFiles(lp)/*
     712             : ==============
     713             :    Try to open a makefile, try to make it if needed and return a
     714             :    filepointer to the first successful found or generated file.
     715             :    The function returns NIL(FILE) if nothing was found. */
     716             : LINKPTR lp;
     717             : {
     718         740 :    FILE *mkfil = NIL(FILE);
     719             : 
     720         740 :    if( lp != NIL(LINK) ) {
     721             :       int s_n, s_t, s_q;
     722             : 
     723         740 :       s_n = Trace;
     724         740 :       s_t = Touch;
     725         740 :       s_q = Check;
     726             : 
     727         740 :       Trace = Touch = Check = FALSE;
     728             :       /* We are making a makefile. Wait for it. */
     729         740 :       Makemkf = Wait_for_completion = TRUE;
     730         740 :       mkfil = NIL(FILE);
     731             : 
     732        1480 :       for(;  lp != NIL(LINK) && mkfil == NIL(FILE); lp=lp->cl_next) {
     733         740 :      if( lp->cl_prq->ce_attr & A_FRINGE ) continue;
     734             : 
     735         740 :      mkfil = Openfile( lp->cl_prq->CE_NAME, FALSE, FALSE );
     736             : 
     737             :      /* Note that no error handling for failed Make() calls is possible
     738             :       * as expected errors (no rule to make the makefile) or unexpected
     739             :       * errors both return -1. */
     740         740 :      if( mkfil == NIL(FILE) && Make(lp->cl_prq, NIL(CELL)) != -1 ) {
     741           2 :         mkfil = Openfile( lp->cl_prq->CE_NAME, FALSE, FALSE );
     742             :         /* Remove flags that indicate that the target was already made.
     743             :          * This is also needed to avoid conflicts with the circular
     744             :          * dependency check in rulparse(), see issues 62118 and 81296
     745             :          * for details. */
     746           2 :         Unmake(lp->cl_prq);
     747             :      }
     748             :       }
     749             : 
     750         740 :       Trace = s_n;
     751         740 :       Touch = s_t;
     752         740 :       Check = s_q;
     753         740 :       Makemkf = Wait_for_completion = FALSE;
     754             :    }
     755             : 
     756         740 :    return(mkfil);
     757             : }
     758             : 
     759             : 
     760             : /*
     761             : ** print error message from variable arg list
     762             : */
     763             : 
     764             : static int errflg = TRUE;
     765             : static int warnflg = FALSE;
     766             : 
     767             : static void
     768         186 : errargs(fmt, args)
     769             : char    *fmt;
     770             : va_list  args;
     771             : {
     772         186 :    int warn = _warn && warnflg && !(Glob_attr & A_SILENT);
     773             : 
     774         186 :    if( errflg || warn ) {
     775           2 :       char *f = Filename();
     776             : 
     777           2 :       fprintf( stderr, "%s:  ", Pname );
     778           2 :       if( f != NIL(char) ) fprintf(stderr, "%s:  line %d:  ", f, Line_number);
     779             : 
     780           2 :       if( errflg )
     781           0 :          fprintf(stderr, "Error: -- ");
     782           2 :       else if( warn )
     783           2 :          fprintf(stderr, "Warning: -- ");
     784             : 
     785           2 :       vfprintf( stderr, fmt, args );
     786           2 :       putc( '\n', stderr );
     787           2 :       if( errflg && !Continue ) Quit(0);
     788             :    }
     789         186 : }
     790             : 
     791             : 
     792             : /*
     793             : ** Print error message and abort
     794             : */
     795             : PUBLIC void
     796           0 : Fatal(ARG(char *,fmt), ARG(va_alist_type,va_alist))
     797             : DARG(char *,fmt)
     798             : DARG(va_alist_type,va_alist)
     799             : {
     800             :    va_list args;
     801             : 
     802           0 :    va_start(args, fmt);
     803           0 :    Continue = FALSE;
     804           0 :    errargs(fmt, args);
     805             :    va_end(args);
     806           0 : }
     807             : 
     808             : /*
     809             : ** error message and exit (unless -k)
     810             : */
     811             : PUBLIC void
     812           0 : Error(ARG(char *,fmt), ARG(va_alist_type,va_alist))
     813             : DARG(char *,fmt)
     814             : DARG(va_alist_type,va_alist)
     815             : {
     816             :    va_list args;
     817             : 
     818           0 :    va_start(args, fmt);
     819           0 :    errargs(fmt, args);
     820             :    va_end(args);
     821           0 : }
     822             : 
     823             : 
     824             : /*
     825             : ** non-fatal message
     826             : */
     827             : PUBLIC void
     828         186 : Warning(ARG(char *,fmt), ARG(va_alist_type,va_alist))
     829             : DARG(char *,fmt)
     830             : DARG(va_alist_type,va_alist)
     831             : {
     832             :    va_list args;
     833             : 
     834         186 :    va_start(args, fmt);
     835         186 :    warnflg = TRUE;
     836         186 :    errflg = FALSE;
     837         186 :    errargs(fmt, args);
     838         186 :    errflg = TRUE;
     839         186 :    warnflg = FALSE;
     840             :    va_end(args);
     841         186 : }
     842             : 
     843             : 
     844             : PUBLIC void
     845           0 : No_ram()
     846             : {
     847           0 :    Fatal( "No more memory" );
     848           0 : }
     849             : 
     850             : 
     851             : PUBLIC void
     852           0 : Usage( eflag )
     853             : int eflag;
     854             : {
     855             :    register char *p;
     856             :    char *fill;
     857             : 
     858           0 :    fill = DmStrDup(Pname);
     859           0 :    for(p=fill; *p; p++) *p=' ';
     860             : 
     861           0 :    if( eflag ) {
     862           0 :       fprintf(stderr, USAGE, Pname);
     863           0 :       fprintf(stderr, USAGE2, fill);
     864             :    }
     865             :    else {
     866           0 :    printf(USAGE, Pname);
     867           0 :    printf(USAGE2, fill);
     868           0 :    puts("    -P#        - set max number of child processes for parallel make");
     869           0 :    puts("    -f file    - use file as the makefile");
     870             : #ifdef MSDOS
     871             :    puts("    -C [+]file - duplicate console output to file, ('+' => append)");
     872             : #endif
     873           0 :    puts("    -K file    - use file as the .KEEP_STATE file");
     874           0 :    puts("    -w target  - show what you would do if 'target' were out of date");
     875           0 :    puts("    -W target  - rebuild pretending that 'target' is out of date");
     876           0 :    puts("    -v[cdfimrtw] - verbose, indicate what we are doing, (-v => -vcdfimrtw)");
     877           0 :    puts("                   c => dump directory cache info only" );
     878           0 :    puts("                   d => dump change of directory info only" );
     879           0 :    puts("                   f => dump file open/close info only" );
     880           0 :    puts("                   i => dump inference information only" );
     881           0 :    puts("                   m => dump make of target information only" );
     882           0 :    puts("                   r => Force output of recipe lines and warnings," );
     883           0 :    puts("                        overrides -s" );
     884           0 :    puts("                   t => keep temporary files when done" );
     885           0 :    puts("                   w => issue non-essential warnings\n" );
     886             : 
     887           0 :    puts("    -m[trae] - Measure timing information, (-m => -mt)");
     888           0 :    puts("               t => display the start and end time of each target" );
     889           0 :    puts("               r => display the start and end time of each recipe" );
     890           0 :    puts("               a => display the target as an absolute path" );
     891           0 :    puts("               e => display the timing of shell escape macros\n" );
     892             : 
     893           0 :    puts("Options: (can be catenated, ie -irn == -i -r -n)");
     894           0 :    puts("    -A   - enable AUGMAKE special target mapping");
     895           0 :    puts("    -B   - enable the use of spaces instead of tabs to start recipes");
     896           0 :    puts("    -c   - use non standard comment scanning");
     897           0 :    puts("    -d   - do not use directory cache");
     898           0 :    puts("    -E   - define environment strings as macros");
     899           0 :    puts("    -e   - same as -E but done after parsing makefile");
     900           0 :    puts("    -g   - disable the special meaning of [ ... ] for group recipes");
     901           0 :    puts("    -h   - print out usage info");
     902           0 :    puts("    -i   - ignore errors");
     903           0 :    puts("    -k   - make independent targets, even if errors");
     904           0 :    puts("    -n   - trace and print, do not execute commands");
     905           0 :    puts("    -p   - print out a version of the makefile");
     906           0 :    puts("    -q   - check if target is up to date.  Does not do");
     907           0 :    puts("           anything.  Returns 0 if up to date, 1 otherwise");
     908           0 :    puts("    -r   - don't use internal rules");
     909           0 :    puts("    -s   - do your work silently");
     910           0 :    puts("    -S   - disable parallel (force sequential) make, overrides -P");
     911           0 :    puts("    -t   - touch, update time stamps without executing commands");
     912           0 :    puts("    -T   - do not apply transitive closure on inference rules");
     913           0 :    puts("    -u   - force unconditional update of target");
     914           0 :    puts("    -V   - print out version number");
     915           0 :    puts("    -x   - export macro values to environment");
     916           0 :    puts("    -X   - ignore #! lines at start of makefile");
     917             :    }
     918           0 :    FREE(fill);
     919             : 
     920           0 :    Quit(0);
     921           0 : }
     922             : 
     923             : 
     924             : PUBLIC void
     925           4 : Version()
     926             : {
     927             :    extern char **Rule_tab;
     928             :    char **p;
     929             : 
     930           4 :    printf("%s - Version %s (%s)\n", Pname, VERSION, BUILDINFO);
     931           4 :    printf("%s\n\n", sccid);
     932             : 
     933           4 :    puts("Default Configuration:");
     934          32 :    for (p=Rule_tab;  *p != NIL(char);  p++)
     935          28 :       printf("\t%s\n", *p);
     936             : 
     937           4 :    printf("\n");
     938             : 
     939             : #if defined(HAVE_SPAWN_H) || defined(__CYGWIN__)
     940             :    /* Only systems that have spawn ar concerned whether spawn or fork/exec
     941             :     * are used. */
     942             : #if ENABLE_SPAWN
     943             :       printf("Subprocesses are executed using: spawn.\n\n");
     944             : #else
     945           4 :       printf("Subprocesses are executed using: fork/exec.\n\n");
     946             : #endif
     947             : #endif
     948             : 
     949           4 :       printf("Please read the NEWS file for the latest release notes.\n");
     950           4 : }

Generated by: LCOV version 1.10