Example #1
0
Lptr AppendLptr (Lptr list1, Lptr list2)
{
  Lptr ptr;

#ifdef DEBUG_APPEND
  {
    Lptr ptr1, ptr2;
    for (ptr1 = list1; ptr1; ptr1 = ptr1->next)
      {
        for (ptr2 = list2; ptr2; ptr2 = ptr2->next)
          {
            if (ptr1 == ptr2)
              Punt ("ptr1 == ptr2 found");
            if (free_list == 0)
              {
                if (ptr1->ptr == ptr2->ptr)
                  Punt ("ptr1->ptr == ptr2->ptr found");
              }
          }
      }
  }
#endif
  if (list1 == 0)
    return list2;
  for (ptr = list1; ptr->next != 0; ptr = ptr->next)
    ;
  ptr->next = list2;
  return list1;
}
Example #2
0
Lint AppendLint (Lint list1, Lint list2)
{
  Lint ptr;

#ifdef DEBUG_APPEND
  {
    Lint ptr1, ptr2;
    for (ptr1 = list1; ptr1; ptr1 = ptr1->next)
      {
        for (ptr2 = list2; ptr2; ptr2 = ptr2->next)
          {
            if (ptr1 == ptr2)
              Punt ("ptr1 == ptr2 found");
            if (free_list == 0)
              {
                if (ptr1->id == ptr2->id)
                  Punt ("ptr1->id == ptr2->id found");
              }
          }
      }
  }
#endif
  if (list1 == 0)
    return list2;
  for (ptr = list1; ptr->next != 0; ptr = ptr->next)
    ;
  ptr->next = list2;
  return list1;
}
Example #3
0
/*
 *      Apple trace selection on a given graph.
 */
void
TraceSelection (FGraph graph, int method, double min_prob)
{
  if (graph == 0)
    Punt ("TraceSelection: nil graph");
  if ((min_prob < 0.0) || (min_prob > 1.0))
    Punt ("TraceSelection: min_prob must be within [0..1]");
#ifdef DEBUG
  printf ("### BEFORE\n");
  WriteGraph ("stdout", graph);
#endif
  /*
   *  The old selection program.
   */
  switch (method)
    {
    case SELECT_BY_NODE_WEIGHT:
      best_successor_of = best_successor_1;
      best_predecessor_of = best_predecessor_1;
      min_prob_requirement = 0;
      SelectTraces (graph);
      PlaceTraces (graph);
      break;
    case SELECT_BY_ARC_WEIGHT:
      best_successor_of = best_successor_2;
      best_predecessor_of = best_predecessor_2;
      min_prob_requirement = 0;
      SelectTraces (graph);
      PlaceTraces (graph);
      break;
    case SELECT_BY_MIN_PROB:
      best_successor_of = best_successor_3;
      best_predecessor_of = best_predecessor_3;
      min_prob_requirement = min_prob;
      SelectTraces (graph);
      PlaceTraces (graph);
      break;
    case SELECT_BY_MAX_ARC:
      SelectBySortArc (graph);
      PlaceTraces (graph);
      break;
    default:
      Punt ("TraceSelection: illegal selection method");
    }
#ifdef DEBUG
  printf ("### AFTER\n");
  WriteGraph ("stdout", graph);
#endif
}
Example #4
0
File: util.c Project: aosm/X11
void DeleteFileAndCheck(char *name)
{
    if (strcmp(name, "/dev/null") != 0 && unlink(name) == -1) {
	char str[500];
	perror(progName);
	(void)sprintf(str, "DeleteFileAndCheck(%s) failed!", name);
	Punt(str);
    }
}
Example #5
0
File: util.c Project: aosm/X11
FILEPTR FOpenAndCheck(char *name, char *mode)
{
    FILEPTR result;
    result = myfopen(name, mode);
    if (result == NULL) {
	char str[500];
	perror(progName);
	(void)sprintf(str, "Error in FOpenAndCheck(%s, %s)", name, mode);
	Punt(str);
    }
    return result;
}
Example #6
0
File: util.c Project: aosm/X11
void RenameAndCheck(char *from, char *to)
{
    if (rename(from, to) == -1) {
	if (errno != EXDEV) {
	    char str[500];
	    perror(progName);
	    (void)sprintf(str, "RenameAndCheck(%s->%s) failed!", from, to);
	    Punt(str);
	}
	CopyFileAndCheck(from, to);
	DeleteFileAndCheck(from);
    }
}
Example #7
0
Lint NewLint (int id)
{
  Lint new_lint;
  if (d_lint != 0)
    {
      new_lint = d_lint;
      d_lint = d_lint->next;
    }
  else
    {
      new_lint = (Lint) L_alloc (Lint_Pool);
      if (new_lint == 0)
        Punt ("NewLint: out of memory space");
    }
  new_lint->next = 0;
  new_lint->id = id;
  return new_lint;
}
Example #8
0
File: util.c Project: aosm/X11
void CopyFileAndCheck(char *from, char *to)
{
    int fromfid, tofid, n;
    char buf[512];
    fromfid = myopen(from, O_RDONLY, 0666);
    tofid = myopen(to, O_WRONLY | O_TRUNC | O_CREAT, 0666);
    if (fromfid < 0 || tofid < 0) {
	perror(progName);
	(void)sprintf(buf, "CopyFileAndCheck(%s->%s) failed!", from, to);
	Punt(buf);
    }
    do {
	n = read(fromfid, buf, 512);
	if (n) (void) write(tofid, buf, n);
    } while (n);
    myclose(fromfid);
    myclose(tofid);
}
Example #9
0
Lptr NewLptr (void * ptr)
{
  Lptr new_ptr;
  if (d_lptr != 0)
    {
      new_ptr = d_lptr;
      d_lptr = d_lptr->next;
    }
  else
    {
      if (!Lptr_Pool)
	Init_NewLptr();
      new_ptr = (Lptr) L_alloc (Lptr_Pool);
      if (new_ptr == 0)
        Punt ("NewLptr: out of memory space");
    }
  new_ptr->next = 0;
  new_ptr->ptr = ptr;
  return new_ptr;
}
Example #10
0
void
meta_compat_start(void)
{
#ifdef USE_FILEMON_ONCE
    /*
     * We need to re-open filemon for each cmd.
     */
    BuildMon *pbm = &Mybm;
    
    if (pbm->mfp != NULL && useFilemon) {
	filemon_open(pbm);
    } else {
	pbm->mon_fd = pbm->filemon_fd = -1;
    }
#endif
    if (pipe(childPipe) < 0)
	Punt("Cannot create pipe: %s", strerror(errno));
    /* Set close-on-exec flag for both */
    (void)fcntl(childPipe[0], F_SETFD, 1);
    (void)fcntl(childPipe[1], F_SETFD, 1);
}
Example #11
0
/*
 *      Places traces in a particular linear order
 *      to maximize sequential transition.
 *      A good way to achieve this is to construct a
 *      higher level graph, using traces as nodes.
 *      An arc is added between traces whose head
 *      and tail are connected by a transition.
 */
static void
PlaceTraces (FGraph graph)
{
  FGraph new_graph;
  Node node, current;
  Node node_order[MAX_GRAPH_SIZE];
  int i, size;
#ifndef SECOND_LEVEL_SELECT
  int min_trace_id, max_trace_id;
#endif
  if (graph->nodes == 0)
    return;
#ifdef SECOND_LEVEL_SELECT
  new_graph = NewGraph ();      /* create a high level graph */
  for (node = graph->nodes; node != 0; node = nextNode (node))
    {
      int trace_id;
      Node temp;
      trace_id = nodeType (node);
      temp = FindNode (new_graph, trace_id);
      if (temp == 0)
        {
          temp = NewNode ();
          nodeId (temp) = trace_id;
          AddNode (new_graph, temp);
        }
      if (node == graph->root)
        new_graph->root = temp;
    }
  for (node = graph->nodes; node != 0; node = nextNode (node))
    {
      Arc arc;
      if (!(nodeStatus (node) & TRACE_TAIL))
        continue;
      /*
       *      Find transitions to the head of other traces.
       *      Inner loop back-edge is not considered.
       */
      for (arc = destinationArcs (node); arc != 0; arc = nextArc (arc))
        {
          Node dest;
          dest = destinationNode (arc);
          if ((nodeType (dest) != nodeType (node)) &&
              (nodeStatus (dest) & TRACE_HEAD))
            {
              /*
               *      Add a link (trace[node]->trace[dest])
               */
              int src_trace_id, dest_trace_id;
              Node src_node, dest_node;
              Arc ar;
              src_trace_id = nodeType (node);
              dest_trace_id = nodeType (dest);
              src_node = FindNode (new_graph, src_trace_id);
              dest_node = FindNode (new_graph, dest_trace_id);
              ConnectNodes (src_node, dest_node, 0);
              ar = FindSrcArc (src_node, dest_node, 0);
              arcWeight (ar) = arcWeight (arc);
              ar = FindDestArc (src_node, dest_node, 0);
              arcWeight (ar) = arcWeight (arc);
            }
        }
    }
  /*
   *  Simply assign the node weights to max(connecting arc)
   */
  for (node = new_graph->nodes; node != 0; node = nextNode (node))
    {
      Arc arc;
      double max = 1.0;
      for (arc = sourceArcs (node); arc != 0; arc = nextArc (arc))
        if (arcWeight (arc) > max)
          max = arcWeight (arc);
      for (arc = destinationArcs (node); arc != 0; arc = nextArc (arc))
        if (arcWeight (arc) > max)
          max = arcWeight (arc);
      nodeWeight (node) = max;
    }
  /*
   *  Apply SelectTraces() on the new graph.
   *  Use SELECT_BY_ARC_WEIGHT
   */
  best_successor_of = best_successor_2;
  best_predecessor_of = best_predecessor_2;
  SelectTraces (new_graph);
  /*
   *  Determine the best sequential order of the traces.
   *  Essentially, we have the original problem again.
   *  However, after the second level trace selection,
   *  we expect most of the sequential transitions are
   *  captured. A naive heuristic is sufficient here.
   *  The sequential order must start with the ENTRY trace.
   */
#ifdef DEBUG_TRACE1
  printf ("... second level graph = \n");
  WriteGraph ("stdout", new_graph);
#endif
  /*
   *  Clear the valid bit of all nodes.
   */
  for (node = new_graph->nodes; node != 0; node = nextNode (node))
    {
      nodeStatus (node) &= ~VISITED;
    }
  /*
   *  Start from the root node.
   */
  size = 0;
  current = new_graph->root;
  while (current != 0)
    {
      Node ptr;
      Arc ar;
      int trace_id;
      if (nodeStatus (current) & VISITED)
        Punt ("PlaceTraces: reached a VISITed node");
      nodeStatus (current) |= VISITED;
      trace_id = nodeId (current);
      /*
       *      Layout the trace.
       */
      for (ptr = graph->nodes; ptr != 0; ptr = nextNode (ptr))
        {
          if ((nodeType (ptr) == trace_id) && (nodeStatus (ptr) & TRACE_HEAD))
            break;              /* find the starting node of the trace */
        }
      if (ptr == 0)
        Punt ("PlaceTraces: internal error (1)");
      while (ptr != 0)
        {
          Arc next;
          node_order[size++] = ptr;
          /*
           *  Follow the in-trace transition.
           */
          if (nodeStatus (ptr) & TRACE_TAIL)
            break;              /* reached the end of trace */
          for (next = destinationArcs (ptr); next != 0; next = nextArc (next))
            {
              if (arcType (next) == nodeType (ptr))
                break;          /* find a in-trace transition */
            }
          if (next == 0)
            break;
          ptr = destinationNode (next);
        }
      /*
       *      Select the next trace to be visited next.
       *      Follow an in-trace transition (of the higher level
       *      graph) if possible. 
       */
      for (ar = destinationArcs (current); ar != 0; ar = nextArc (ar))
        {
          if (arcType (ar) == nodeType (current))
            break;              /* find an in-trace transition */
        }
      if (ar != 0)
        {                       /* transition is still in-trace */
          current = destinationNode (ar);
        }
      else
        {                       /* must find another trace */
          /*
           *  Find the most important trace left.
           */
          Node nn, best;
          best = 0;
          for (nn = new_graph->nodes; nn != 0; nn = nextNode (nn))
            {
              if (nodeStatus (nn) & VISITED)
                continue;       /* skip over VISITED nodes */
              if (!(nodeStatus (nn) & TRACE_HEAD))
                continue;       /* skip over non-trace headers */
              if (best == 0)
                {
                  best = nn;
                }
              else
                {
                  if (nodeWeight (nn) > nodeWeight (best))
                    best = nn;
                }
            }
          current = best;       /* go out of trace if best=0 */
        }
    }
  /*
   *  Make sure that all traces have been layout.
   */
  for (node = new_graph->nodes; node != 0; node = nextNode (node))
    {
      if (!(nodeStatus (node) & VISITED))
        {
          Punt ("PlaceTraces: missing some traces");
        }
    }
  /*
   *  No longer need the higher level graph.
   */
  FreeGraph (&new_graph);       /* destroy the high level graph */
#else
  min_trace_id = 0x1FFFFFFF;
  max_trace_id = -0x1FFFFFFF;
  for (node = graph->nodes; node != 0; node = nextNode (node))
    {
      int trace_id;
      trace_id = nodeType (node);
      if (trace_id > max_trace_id)
        max_trace_id = trace_id;
      if (trace_id < min_trace_id)
        min_trace_id = trace_id;
    }
  for (node = graph->nodes; node != 0; node = nextNode (node))
    {
      nodeStatus (node) &= ~VISITED;
    }
  size = 0;
  for (i = min_trace_id; i <= max_trace_id; i++)
    {
      Node ptr;
      /*
       * 1. find the trace header.
       */
      for (ptr = graph->nodes; ptr != 0; ptr = nextNode (ptr))
        {
          if ((nodeType (ptr) == i) & ((nodeStatus (ptr) & TRACE_HEAD) != 0))
            break;
        }
      if (ptr == 0)
        continue;
      while (ptr != 0)
        {
          Arc next;
          if (nodeStatus (ptr) & VISITED)
            Punt ("PlaceTraces: visited a node twice");
          nodeStatus (ptr) |= VISITED;
          node_order[size++] = ptr;
          if (nodeStatus (ptr) & TRACE_TAIL)
            break;
          for (next = destinationArcs (ptr); next != 0; next = nextArc (next))
            {
              if (arcType (next) == nodeType (ptr))
                break;
            }
          if (next == 0)
            break;
          ptr = destinationNode (next);
        }
    }
  /*
   *  Make sure that all traces have been layout.
   */
  for (node = graph->nodes; node != 0; node = nextNode (node))
    {
      if (!(nodeStatus (node) & VISITED))
        {
          fprintf (stderr, "min trace id = %d\n", min_trace_id);
          fprintf (stderr, "max trace id = %d\n", max_trace_id);
          fprintf (stderr, "size = %d\n", size);
          WriteGraph ("stderr", graph);
          Punt ("PlaceTraces: missing some traces");
        }
    }
#endif
  /*
   *  Rearrange the order of nodes, according to the
   *  node_order[] order.
   */
  node_order[size] = 0;
  for (i = 0; i < size; i++)
    {
      nextNode (node_order[i]) = node_order[i + 1];
    }
  graph->nodes = node_order[0];
}
Example #12
0
static void
AddExtensionFields (FGraph graph)
{
  Node ptr;
  Arc arc;
  struct Ext *ext;
  int change;
  Set all;
  FreeExtensionFields ();
  if (graph->nodes == 0)
    return;
  if (graph->root == 0)
    Punt ("no root node");
  all = 0;
  for (ptr = graph->nodes; ptr != 0; ptr = nextNode (ptr))
    {
      nodeExt (ptr) = (others + n_others);
      others[n_others].dominator = 0;
      others[n_others].level = -1;
      others[n_others].order = n_others;
      all = Set_add (all, n_others);
      n_others += 1;
    }
  ext = (struct Ext *) nodeExt (graph->root);
  ext->level = 0;
  ext->dominator = Set_add (0, ext->order);
  for (ptr = graph->nodes; ptr != 0; ptr = nextNode (ptr))
    {
      if (ptr == graph->root)
        continue;
      ext = (struct Ext *) nodeExt (ptr);
      ext->dominator = Set_union (0, all);
    }
  /*
   *  compute dominators.
   */
  change = 1;
  while (change != 0)
    {
      change = 0;
      for (ptr = graph->nodes; ptr != 0; ptr = nextNode (ptr))
        {
          Set dom, temp;
          if (ptr == graph->root)
            continue;
          arc = sourceArcs (ptr);
          if (arc == 0)
            {
              dom = 0;
            }
          else
            {
              dom = Set_union (all, 0);
              for (; arc != 0; arc = nextArc (arc))
                {
                  ext = (struct Ext *) nodeExt (sourceNode (arc));
                  temp = Set_intersect (dom, ext->dominator);
                  Set_dispose (dom);
                  dom = temp;
                  temp = 0;
                }
              ext = (struct Ext *) nodeExt (ptr);
              dom = Set_add (dom, ext->order);
              if (Set_same (dom, ext->dominator))
                {
                  Set_dispose (dom);
                }
              else
                {
                  Set_dispose (ext->dominator);
                  ext->dominator = dom;
                  change += 1;
                }
            }
        }
    }
  all = Set_dispose (all);
  /*
   *  compute level.
   */
  change = 1;
  while (change != 0)
    {
      change = 0;
      for (ptr = graph->nodes; ptr != 0; ptr = nextNode (ptr))
        {
          int max;
          ext = (struct Ext *) nodeExt (ptr);
          if (ext->level >= 0)
            continue;
          max = -1;
          for (arc = sourceArcs (ptr); arc != 0; arc = arc->next)
            {
              Node src;
              struct Ext *ex;
              src = sourceNode (arc);
              ex = (struct Ext *) nodeExt (src);
              /* ignore back-edges */
              if (ex->order >= ext->order)
                continue;
              if (ex->level < 0)
                break;
              if (ex->level > max)
                max = ex->level;
            }
          if (arc == 0)
            {                   /* all source have been visited */
              ext->level = max + 1;
              change += 1;
            }
        }
    }
#ifdef DEBUG
  printf ("--------------------------------------------------\n");
  for (ptr = graph->nodes; ptr != 0; ptr = nextNode (ptr))
    {
      ext = nodeExt (ptr);
      printf ("# id=%d, order=%d, level=%d, ",
              ptr->id, ext->order, ext->level);
      PrintSet (stdout, "dominator", ext->dominator);
    }
#endif
}
Example #13
0
/*
 *      Trace selection by sorting all arcs and
 *      select from the most important to the least important.
 */
void
SelectBySortArc (FGraph graph)
{
#define MAX_SIZE (MAX_GRAPH_SIZE*2)
  ST_Entry sorted_list[MAX_SIZE];       /* expected fan-out = 2 */
  register int list_length;
  Node node_list[MAX_GRAPH_SIZE];
  register int node_list_length;
  register Node ptr;
  register Arc arc;
  register int i;
  int next_trace_id;
  /*
   *  Mark all nodes unvisited.
   *  Also clear all status bits.
   */
  node_list_length = 0;
  for (ptr = graph->nodes; ptr != 0; ptr = nextNode (ptr))
    {
      node_list[node_list_length++] = ptr;
      if (node_list_length >= MAX_GRAPH_SIZE)
        Punt ("SelectBySortArc: graph is too large");
      nodeType (ptr) = 0;       /* trace id = 0 */
      nodeStatus (ptr) = NOT_VISITED;
      for (arc = sourceArcs (ptr); arc != 0; arc = nextArc (arc))
        arcType (arc) = 0;
      for (arc = destinationArcs (ptr); arc != 0; arc = nextArc (arc))
        arcType (arc) = 0;
    }
  /*
   *  Place all outgoing arcs in the list.
   *  Sort all arcs by weight.
   */
  list_length = 0;
  for (ptr = graph->nodes; ptr != 0; ptr = nextNode (ptr))
    {
      for (arc = destinationArcs (ptr); arc != 0; arc = nextArc (arc))
        {
          sorted_list[list_length].weight = arcWeight (arc);
          sorted_list[list_length].ptr = arc;
          list_length += 1;
          if (list_length >= MAX_SIZE)
            Punt ("SelectBySortArc: graph is too large");
        }
    }
  max_sort (sorted_list, list_length);  /* library/sort.c */
  /*
   *  From the most important arc to the least important arc,
   *  connect basic blocks into traces.
   */
  next_trace_id = 1;
  for (i = 0; i < list_length; i++)
    {
      int trace_id;
      Node src, dest;
      arc = (Arc) sorted_list[i].ptr;
      src = sourceNode (arc);
      dest = destinationNode (arc);
      /*
       *      Check if this arc can still be selected.
       *      dest cannot be the root of the graph.
       *      case1 : src = free node, dest = free node
       *      case2 : src is a tail node, dest is a head node,
       *              except when src and dest belong to the same trace.
       */
      if (dest == graph->root)
        continue;
      if (!
          ((nodeStatus (src) == NOT_VISITED)
           || (nodeStatus (src) & TRACE_TAIL)))
        continue;
      if (!
          ((nodeStatus (dest) == NOT_VISITED)
           || (nodeStatus (dest) & TRACE_HEAD)))
        continue;
      /*
       *      If both src and dest are defined (in some trace),
       *      we do not allow this connection if src and dest
       *      belong to the same trace.
       *      This takes care of self-recursions.
       */
      if ((nodeStatus (src) & TRACE_TAIL) && (nodeStatus (dest) & TRACE_HEAD))
        if (nodeType (src) == nodeType (dest))
          continue;
      /*
       *      It is also not allow to connect, when src and dest
       *      are the same node.
       */
      if (src == dest)
        continue;
      /*
       *      After connection, src will no longer be tail, and
       *      dest will no longer be head.
       */
      nodeStatus (src) &= ~TRACE_TAIL;
      nodeStatus (dest) &= ~TRACE_HEAD;
      /*
       *      Now this arc can be selected.
       */
      if (nodeStatus (src) & VISITED)
        {
          trace_id = nodeType (src);
          arcType (arc) = trace_id;
          /*
           *  If the dest node is in another trace, need to
           *  combine the two traces.
           */
          if (nodeStatus (dest) & VISITED)
            {
              register int j;
              register int bad_id = nodeType (dest);
              /*
               * For all nodes of type (nodeType(dest)), change
               * to trace_id.
               */
              for (j = 0; j < node_list_length; j++)
                if (nodeType (node_list[j]) == bad_id)
                  nodeType (node_list[j]) = trace_id;
              /*
               * For all arcs of type (nodeType(dest)), change
               * to trace_id.
               */
              for (j = 0; j < list_length; j++)
                {
                  Arc ac;
                  ac = (Arc) sorted_list[j].ptr;
                  if (arcType (ac) == bad_id)
                    arcType (ac) = trace_id;
                }
            }
          else
            {
              /*
               * If dest is still a free node, it becomes the
               * trace tail.
               */
              nodeStatus (dest) |= (VISITED | TRACE_TAIL);
              nodeType (dest) = trace_id;
            }
        }
      else if (nodeStatus (dest) & VISITED)
        {
          trace_id = nodeType (dest);
          arcType (arc) = trace_id;
          /*
           *  Since src is a free node, src becomes a trace head.
           */
          nodeStatus (src) |= (VISITED | TRACE_HEAD);
          nodeType (src) = trace_id;
        }
      else
        {
          trace_id = next_trace_id++;
          arcType (arc) = trace_id;
          nodeStatus (src) |= (VISITED | TRACE_HEAD);
          nodeType (src) = trace_id;
          nodeStatus (dest) |= (VISITED | TRACE_TAIL);
          nodeType (dest) = trace_id;
        }
    }
  /*
   *  The remaining NOT_VISITED nodes, each forms a trace.
   */
  for (ptr = graph->nodes; ptr != 0; ptr = nextNode (ptr))
    {
      if (nodeStatus (ptr) & VISITED)
        continue;
      nodeStatus (ptr) |= (VISITED | TRACE_HEAD | TRACE_TAIL);
      nodeType (ptr) = next_trace_id++;
    }
  /*
   *  Detect inner loops.
   */
  for (ptr = graph->nodes; ptr != 0; ptr = nextNode (ptr))
    {
      if (!(nodeStatus (ptr) & TRACE_TAIL))
        continue;
      for (arc = destinationArcs (ptr); arc != 0; arc = nextArc (arc))
        {
          Node dest;
          dest = destinationNode (arc);
          if ((nodeStatus (dest) & TRACE_HEAD) &&
              (nodeType (dest) == nodeType (ptr)))
            {
              nodeStatus (dest) |= LOOP_HEAD;
              break;
            }
        }
    }
}
Example #14
0
/*-
 * MainParseArgs --
 *	Parse a given argument vector. Called from main() and from
 *	Main_ParseArgLine() when the MAKEFLAGS target is used.
 *
 *	XXX: Deal with command line overriding MAKEFLAGS in makefile
 *
 * Results:
 *	None
 *
 * Side Effects:
 *	Various global and local flags will be set depending on the flags
 *	given
 */
static void
MainParseArgs(int argc, char **argv)
{
	int c;
	string_t argstr;

	optind = 1;	/* since we're called more than once */
rearg:	while((c = getopt(argc, argv, "D:I:L:NPSd:ef:ij:knqrstv")) != EOF) {
		switch(c) {
		case 'D':
			argstr = string_create(optarg);
			Var_Set(argstr, string_create("1"), VAR_GLOBAL);
			Var_Append(sMAKEFLAGS, string_create("-D"),
				   VAR_GLOBAL);
			Var_Append(sMAKEFLAGS, argstr, VAR_GLOBAL);
			string_deref(argstr);
			break;
		case 'I':
			argstr = string_create(optarg);
			Parse_AddIncludeDir(argstr);
			Var_Append(sMAKEFLAGS, string_create("-I"),
				   VAR_GLOBAL);
			Var_Append(sMAKEFLAGS, argstr, VAR_GLOBAL);
			string_deref(argstr);
			break;
		case 'L':
			maxLocal = atoi(optarg);
			Var_Append(sMAKEFLAGS, string_create("-L"),
				   VAR_GLOBAL);
			argstr = string_create(optarg);
			Var_Append(sMAKEFLAGS, argstr, VAR_GLOBAL);
			string_deref(argstr);
			break;
		case 'N':
			noisy = TRUE;
			Var_Append(sMAKEFLAGS, string_create("-N"),
				   VAR_GLOBAL);
			break;
		case 'S':
			keepgoing = FALSE;
			Var_Append(sMAKEFLAGS, string_create("-S"),
				   VAR_GLOBAL);
			break;
		case 'd': {
			char *modules = optarg;

			for (; *modules; ++modules)
				switch (*modules) {
				case 'A':
					debug = ~0;
					break;
				case 'a':
					debug |= DEBUG_ARCH;
					break;
				case 'c':
					debug |= DEBUG_COND;
					break;
				case 'd':
					debug |= DEBUG_DIR;
					break;
				case 'g':
					if (modules[1] == '1') {
						debug |= DEBUG_GRAPH1;
						++modules;
					}
					else if (modules[1] == '2') {
						debug |= DEBUG_GRAPH2;
						++modules;
					}
					break;
				case 'j':
					debug |= DEBUG_JOB;
					break;
				case 'm':
					debug |= DEBUG_MAKE;
					break;
				case 's':
					debug |= DEBUG_SUFF;
					break;
				case 't':
					debug |= DEBUG_TARG;
					break;
				case 'v':
					debug |= DEBUG_VAR;
					break;
				}
			Var_Append(sMAKEFLAGS, string_create("-d"),
				   VAR_GLOBAL);
			argstr = string_create(optarg);
			Var_Append(sMAKEFLAGS, argstr, VAR_GLOBAL);
			string_deref(argstr);
			break;
		}
		case 'e':
			checkEnvFirst = TRUE;
			Var_Append(sMAKEFLAGS, string_create("-e"),
				   VAR_GLOBAL);
			break;
		case 'f':
			(void)Lst_AtEnd(makefiles, (ClientData)optarg);
			break;
		case 'i':
			ignoreErrors = TRUE;
			Var_Append(sMAKEFLAGS, string_create("-i"),
				   VAR_GLOBAL);
			break;
		case 'j':
			maxJobs = atoi(optarg);
			Var_Append(sMAKEFLAGS, string_create("-j"),
				   VAR_GLOBAL);
			argstr = string_create(optarg);
			Var_Append(sMAKEFLAGS, argstr, VAR_GLOBAL);
			string_deref(argstr);
			break;
		case 'k':
			keepgoing = TRUE;
			Var_Append(sMAKEFLAGS, string_create("-k"),
				   VAR_GLOBAL);
			break;
		case 'n':
			noExecute = TRUE;
			Var_Append(sMAKEFLAGS, string_create("-n"),
				   VAR_GLOBAL);
			break;
		case 'q':
			queryFlag = TRUE;
			/* Kind of nonsensical, wot? */
			Var_Append(sMAKEFLAGS, string_create("-q"),
				   VAR_GLOBAL);
			break;
		case 'r':
			noBuiltins = TRUE;
			Var_Append(sMAKEFLAGS, string_create("-r"),
				   VAR_GLOBAL);
			break;
		case 's':
			beSilent = TRUE;
			Var_Append(sMAKEFLAGS, string_create("-s"),
				   VAR_GLOBAL);
			break;
		case 't':
			touchFlag = TRUE;
			Var_Append(sMAKEFLAGS, string_create("-t"),
				   VAR_GLOBAL);
			break;
		case 'v':
			ui_print_revision();
			exit(2);
		default:
		case '?':
			usage();
		}
	}

	oldVars = TRUE;

	/*
	 * See if the rest of the arguments are variable assignments and
	 * perform them if so. Else take them to be targets and stuff them
	 * on the end of the "create" list.
	 */
	for (argv += optind, argc -= optind; *argv; ++argv, --argc)
		if (Parse_DoVar(*argv, VAR_CMD) != 0) {
			if (!**argv)
				Punt("illegal (null) argument.");
			if (**argv == '-') {
				optind = 0;
				goto rearg;
			}
			(void)Lst_AtEnd(create,
					(ClientData)string_create(*argv));
		}
}
Example #15
0
File: job.c Project: UNGLinux/Obase
static Job *
prepare_job(GNode *gn, int flags)
{
	bool cmdsOK;     	/* true if the nodes commands were all right */
	bool noExec;     	/* Set true if we decide not to run the job */

	/*
	 * Check the commands now so any attributes from .DEFAULT have a chance
	 * to migrate to the node
	 */
	cmdsOK = Job_CheckCommands(gn);
	expand_commands(gn);

	if ((gn->type & OP_MAKE) || (!noExecute && !touchFlag)) {
		/*
		 * We're serious here, but if the commands were bogus, we're
		 * also dead...
		 */
		if (!cmdsOK)
			job_failure(gn, Punt);

		if (Lst_IsEmpty(&gn->commands))
			noExec = true;
		else
			noExec = false;

	} else if (noExecute) {
		if (!cmdsOK || Lst_IsEmpty(&gn->commands))
			noExec = true;
		else
			noExec = false;
	} else {
		/*
		 * Just touch the target and note that no shell should be
		 * executed.  Check
		 * the commands, too, but don't die if they're no good -- it
		 * does no harm to keep working up the graph.
		 */
		Job_Touch(gn);
		noExec = true;
	}

	/*
	 * If we're not supposed to execute a shell, don't.
	 */
	if (noExec) {
		/*
		 * We only want to work our way up the graph if we aren't here
		 * because the commands for the job were no good.
		 */
		if (cmdsOK && !aborting) {
			gn->built_status = MADE;
			Make_Update(gn);
		}
		return NULL;
	} else {
		Job *job;       	/* new job descriptor */
		job = emalloc(sizeof(Job));
		if (job == NULL)
			Punt("JobStart out of memory");

		job->node = gn;

		/*
		 * Set the initial value of the flags for this job based on the
		 * global ones and the node's attributes... Any flags supplied
		 * by the caller are also added to the field.
		 */
		job->flags = flags;

		if (gn->type & OP_CHEAP)
			return job;
		if ((gn->type & OP_EXPENSIVE) || 
		    expensive_commands(&gn->expanded))
			job->flags |= JOB_IS_EXPENSIVE;

		return job;
	}
}
Example #16
0
File: job.c Project: UNGLinux/Obase
/*-
 *-----------------------------------------------------------------------
 * JobExec --
 *	Execute the shell for the given job. Called from JobStart
 *
 * Side Effects:
 *	A shell is executed, outputs is altered and the Job structure added
 *	to the job table.
 *-----------------------------------------------------------------------
 */
static void
JobExec(Job *job)
{
	pid_t cpid; 	/* ID of new child */
	struct job_pid *p;
	int fds[4];
	int *fdout = fds;
	int *fderr = fds+2;
	int i;

	banner(job, stdout);

	setup_engine(1);

	/* Create the pipe by which we'll get the shell's output.
	 */
	if (pipe(fdout) == -1)
		Punt("Cannot create pipe: %s", strerror(errno));

	if (pipe(fderr) == -1)
		Punt("Cannot create pipe: %s", strerror(errno));

	block_signals();
	if ((cpid = fork()) == -1) {
		Punt("Cannot fork");
		unblock_signals();
	} else if (cpid == 0) {
		supervise_jobs = false;
		/* standard pipe code to route stdout and stderr */
		close(fdout[0]);
		if (dup2(fdout[1], 1) == -1)
			Punt("Cannot dup2(outPipe): %s", strerror(errno));
		if (fdout[1] != 1)
			close(fdout[1]);
		close(fderr[0]);
		if (dup2(fderr[1], 2) == -1)
			Punt("Cannot dup2(errPipe): %s", strerror(errno));
		if (fderr[1] != 2)
			close(fderr[1]);

		/*
		 * We want to switch the child into a different process family
		 * so we can kill it and all its descendants in one fell swoop,
		 * by killing its process family, but not commit suicide.
		 */
		(void)setpgid(0, getpid());

		if (random_delay)
			if (!(nJobs == 1 && no_jobs_left()))
				usleep(random() % random_delay);

		setup_all_signals(SigHandler, SIG_DFL);
		unblock_signals();
		/* this exits directly */
		run_gnode_parallel(job->node);
		/*NOTREACHED*/
	} else {
		supervise_jobs = true;
		job->pid = cpid;

		/* we set the current position in the buffers to the beginning
		 * and mark another stream to watch in the outputs mask
		 */
		for (i = 0; i < 2; i++)
			prepare_pipe(&job->in[i], fds+2*i);
	}
	/*
	 * Now the job is actually running, add it to the table.
	 */
	nJobs++;
	Lst_AtEnd(&runningJobs, job);
	if (job->flags & JOB_IS_EXPENSIVE)
		expensive_job = true;
	p = emalloc(sizeof(struct job_pid));
	p->pid = cpid;
	Lst_AtEnd(&job_pids, p);
	job->p = Lst_Last(&job_pids);

	unblock_signals();
	if (DEBUG(JOB)) {
		LstNode ln;

		(void)fprintf(stdout, "Running %ld (%s)\n", (long)cpid,
		    job->node->name);
		for (ln = Lst_First(&job->node->commands); ln != NULL ;
		    ln = Lst_Adv(ln))
		    	fprintf(stdout, "\t%s\n", (char *)Lst_Datum(ln));
		(void)fflush(stdout);
	}

}
Example #17
0
/*-
 * MainParseArgs --
 *	Parse a given argument vector. Called from main() and from
 *	Main_ParseArgLine() when the .MAKEFLAGS target is used.
 *
 *	XXX: Deal with command line overriding .MAKEFLAGS in makefile
 *
 * Results:
 *	None
 *
 * Side Effects:
 *	Various global and local flags will be set depending on the flags
 *	given
 */
static void
MainParseArgs(int argc, char **argv)
{
	char *p;
	int c;
	int arginc;
	char *argvalue;
	const char *getopt_def;
	char *optscan;
	Boolean inOption, dashDash = FALSE;
	char found_path[MAXPATHLEN + 1];	/* for searching for sys.mk */

#ifdef REMOTE
# define OPTFLAGS "BD:I:J:L:NPST:V:WXd:ef:ij:km:nqrst"
#else
# define OPTFLAGS "BD:I:J:NPST:V:WXd:ef:ij:km:nqrst"
#endif
#undef optarg
#define optarg argvalue	
/* Can't actually use getopt(3) because rescanning is not portable */

	getopt_def = OPTFLAGS;
rearg:	
	inOption = FALSE;
	optscan = NULL;
	while(argc > 1) {
		char *getopt_spec;
		if(!inOption)
			optscan = argv[1];
		c = *optscan++;
		arginc = 0;
		if(inOption) {
			if(c == '\0') {
				++argv;
				--argc;
				inOption = FALSE;
				continue;
			}
		} else {
			if (c != '-' || dashDash)
				break;
			inOption = TRUE;
			c = *optscan++;
		}
		/* '-' found at some earlier point */
		getopt_spec = strchr(getopt_def, c);
		if(c != '\0' && getopt_spec != NULL && getopt_spec[1] == ':') {
			/* -<something> found, and <something> should have an arg */
			inOption = FALSE;
			arginc = 1;
			argvalue = optscan;
			if(*argvalue == '\0') {
				if (argc < 3) {
					(void)fprintf(stderr,
					    "%s: option requires "
					    "an argument -- %c\n",
					    progname, c);
					usage();
				}
				argvalue = argv[2];
				arginc = 2;
			}
		} else {
			argvalue = NULL; 
		}
		switch(c) {
		case '\0':
			arginc = 1;
			inOption = FALSE;
			break;
		case 'B':
			compatMake = TRUE;
			Var_Append(MAKEFLAGS, "-B", VAR_GLOBAL);
			break;
		case 'D':
			Var_Set(optarg, "1", VAR_GLOBAL, 0);
			Var_Append(MAKEFLAGS, "-D", VAR_GLOBAL);
			Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
			break;
		case 'I':
			Parse_AddIncludeDir(optarg);
			Var_Append(MAKEFLAGS, "-I", VAR_GLOBAL);
			Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
			break;
		case 'J':
			if (sscanf(optarg, "%d,%d", &job_pipe[0], &job_pipe[1]) != 2) {
			    /* backslash to avoid trigraph ??) */
			    (void)fprintf(stderr,
				"%s: internal error -- J option malformed (%s?\?)\n",
				progname, optarg);
				usage();
			}
			if ((fcntl(job_pipe[0], F_GETFD, 0) < 0) ||
			    (fcntl(job_pipe[1], F_GETFD, 0) < 0)) {
#if 0
			    (void)fprintf(stderr,
				"%s: warning -- J descriptors were closed!\n",
				progname);
#endif
			    job_pipe[0] = -1;
			    job_pipe[1] = -1;
			    compatMake = TRUE;
			} else {
			    Var_Append(MAKEFLAGS, "-J", VAR_GLOBAL);
			    Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
			    jobServer = TRUE;
			}
			break;
#ifdef REMOTE
		case 'L':
			maxLocal = strtol(optarg, &p, 0);
			if (*p != '\0' || maxLocal < 1) {
			    (void)fprintf(stderr, "%s: illegal argument to -L -- must be positive integer!\n",
				progname);
			    exit(1);
			}
			Var_Append(MAKEFLAGS, "-L", VAR_GLOBAL);
			Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
			break;
#endif
		case 'N':
			noExecute = TRUE;
			noRecursiveExecute = TRUE;
			Var_Append(MAKEFLAGS, "-N", VAR_GLOBAL);
			break;
		case 'P':
			usePipes = FALSE;
			Var_Append(MAKEFLAGS, "-P", VAR_GLOBAL);
			break;
		case 'S':
			keepgoing = FALSE;
			Var_Append(MAKEFLAGS, "-S", VAR_GLOBAL);
			break;
		case 'T':
			tracefile = estrdup(optarg);
			Var_Append(MAKEFLAGS, "-T", VAR_GLOBAL);
			Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
			break;
		case 'V':
			printVars = TRUE;
			(void)Lst_AtEnd(variables, (ClientData)optarg);
			Var_Append(MAKEFLAGS, "-V", VAR_GLOBAL);
			Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
			break;
		case 'W':
			parseWarnFatal = TRUE;
			break;
		case 'X':
			varNoExportEnv = TRUE;
			Var_Append(MAKEFLAGS, "-X", VAR_GLOBAL);
			break;
		case 'd': {
			char *modules = optarg;

			for (; *modules; ++modules)
				switch (*modules) {
				case 'A':
					debug = ~0;
					break;
				case 'a':
					debug |= DEBUG_ARCH;
					break;
				case 'c':
					debug |= DEBUG_COND;
					break;
				case 'd':
					debug |= DEBUG_DIR;
					break;
				case 'e':
					debug |= DEBUG_ERROR;
					break;
				case 'f':
					debug |= DEBUG_FOR;
					break;
				case 'g':
					if (modules[1] == '1') {
						debug |= DEBUG_GRAPH1;
						++modules;
					}
					else if (modules[1] == '2') {
						debug |= DEBUG_GRAPH2;
						++modules;
					}
					else if (modules[1] == '3') {
						debug |= DEBUG_GRAPH3;
						++modules;
					}
					break;
				case 'j':
					debug |= DEBUG_JOB;
					break;
				case 'm':
					debug |= DEBUG_MAKE;
					break;
				case 'n':
					debug |= DEBUG_SCRIPT;
					break;
				case 's':
					debug |= DEBUG_SUFF;
					break;
				case 't':
					debug |= DEBUG_TARG;
					break;
				case 'v':
					debug |= DEBUG_VAR;
					break;
				case 'x':
					debug |= DEBUG_SHELL;
					break;
				default:
					(void)fprintf(stderr,
				"%s: illegal argument to d option -- %c\n",
					    progname, *modules);
					usage();
				}
			Var_Append(MAKEFLAGS, "-d", VAR_GLOBAL);
			Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
			break;
		}
		case 'e':
			checkEnvFirst = TRUE;
			Var_Append(MAKEFLAGS, "-e", VAR_GLOBAL);
			break;
		case 'f':
			(void)Lst_AtEnd(makefiles, (ClientData)optarg);
			break;
		case 'i':
			ignoreErrors = TRUE;
			Var_Append(MAKEFLAGS, "-i", VAR_GLOBAL);
			break;
		case 'j':
			forceJobs = TRUE;
			maxJobs = strtol(optarg, &p, 0);
			if (*p != '\0' || maxJobs < 1) {
				(void)fprintf(stderr, "%s: illegal argument to -j -- must be positive integer!\n",
				    progname);
				exit(1);
			}
#ifndef REMOTE
			maxLocal = maxJobs;
#endif
			Var_Append(MAKEFLAGS, "-j", VAR_GLOBAL);
			Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
			break;
		case 'k':
			keepgoing = TRUE;
			Var_Append(MAKEFLAGS, "-k", VAR_GLOBAL);
			break;
		case 'm':
			/* look for magic parent directory search string */
			if (strncmp(".../", optarg, 4) == 0) {
				if (!Dir_FindHereOrAbove(curdir, optarg+4,
				    found_path, sizeof(found_path)))
					break;		/* nothing doing */
				(void)Dir_AddDir(sysIncPath, found_path);
				
			} else {
				(void)Dir_AddDir(sysIncPath, optarg);
			}
			Var_Append(MAKEFLAGS, "-m", VAR_GLOBAL);
			Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL);
			break;
		case 'n':
			noExecute = TRUE;
			Var_Append(MAKEFLAGS, "-n", VAR_GLOBAL);
			break;
		case 'q':
			queryFlag = TRUE;
			/* Kind of nonsensical, wot? */
			Var_Append(MAKEFLAGS, "-q", VAR_GLOBAL);
			break;
		case 'r':
			noBuiltins = TRUE;
			Var_Append(MAKEFLAGS, "-r", VAR_GLOBAL);
			break;
		case 's':
			beSilent = TRUE;
			Var_Append(MAKEFLAGS, "-s", VAR_GLOBAL);
			break;
		case 't':
			touchFlag = TRUE;
			Var_Append(MAKEFLAGS, "-t", VAR_GLOBAL);
			break;
		case '-':
			dashDash = TRUE;
			break;
		default:
		case '?':
#ifndef MAKE_NATIVE
			fprintf(stderr, "getopt(%s) -> %d (%c)\n",
				OPTFLAGS, c, c);
#endif
			usage();
		}
		argv += arginc;
		argc -= arginc;
	}

	oldVars = TRUE;

	/*
	 * See if the rest of the arguments are variable assignments and
	 * perform them if so. Else take them to be targets and stuff them
	 * on the end of the "create" list.
	 */
	for (; argc > 1; ++argv, --argc)
		if (Parse_IsVar(argv[1])) {
			Parse_DoVar(argv[1], VAR_CMD);
		} else {
			if (!*argv[1])
				Punt("illegal (null) argument.");
			if (*argv[1] == '-' && !dashDash)
				goto rearg;
			(void)Lst_AtEnd(create, (ClientData)estrdup(argv[1]));
		}
}
Example #18
0
/*
 *      Heuristic solution to the trace selection problem.
 */
static void
SelectTraces (FGraph graph)
{
  ST_Entry sorted_list[MAX_GRAPH_SIZE];
  int list_length;
  Node ptr;
  Arc arc;
  int n, trace_id;
  Node ENTRY;
  Node seed, current, last;
  struct Ext *extCurrent, *extNext;
  /*
   *  Compute level information.
   */
  AddExtensionFields (graph);
  /*
   *  Mark all nodes unvisited.
   *  Also clear all status bits.
   */
  for (ptr = graph->nodes; ptr != 0; ptr = nextNode (ptr))
    {
      nodeType (ptr) = 0;       /* trace id = 0 */
      nodeStatus (ptr) = NOT_VISITED;
      for (arc = sourceArcs (ptr); arc != 0; arc = nextArc (arc))
        arcType (arc) = 0;
      for (arc = destinationArcs (ptr); arc != 0; arc = nextArc (arc))
        arcType (arc) = 0;
    }
  /*
   *  Sort all nodes according to the node weight.
   *  From the most important node to the least important node.
   */
  list_length = 0;
  for (ptr = graph->nodes; ptr != 0; ptr = nextNode (ptr))
    {
      sorted_list[list_length].weight = nodeWeight (ptr);
      sorted_list[list_length].ptr = ptr;
      sorted_list[list_length].index = list_length;
      list_length += 1;
      if (list_length >= MAX_GRAPH_SIZE)
        Punt ("SelectTrace: graph is too large");
    }
  max_sort (sorted_list, list_length);  /* library/sort.c */
#ifdef WEIGHT_BASED
  /*
   *  Give higher priority to the execution weight.
   */
  ENTRY = graph->root;
  trace_id = 1;
  for (n = 0; n < list_length; n++)
    {
      /*
       *      Select the highest weight un-visited node.
       */
      seed = sorted_list[n].ptr;
      if (nodeStatus (seed) & VISITED)  /* if visited, try next */
        continue;               /* highest node */
      /*
       *      Start a new trace.
       *      Mark seed visited.
       */
      nodeType (seed) = trace_id++;
      nodeStatus (seed) |= VISITED;
      /*
       *      Grow the trace forward.
       */
      current = seed;
      for (;;)
        {
          Arc ln, arc;
          Node dest;
          ln = best_successor_of (current);
          if (ln == 0)
            {
              nodeStatus (current) |= TRACE_TAIL;
              break;
            }
          /*
           *  Cannot include ENTRY node.
           */
          dest = destinationNode (ln);
          if (dest == ENTRY)
            {
              nodeStatus (current) |= TRACE_TAIL;
              break;
            }
          /*
           *  Can not include a dominator.
           */
          extCurrent = nodeExt (current);
          extNext = nodeExt (dest);
          if ((extCurrent == 0) | (extNext == 0))
            {
              Punt ("corrupted extension field");
            }
          if (Set_in (extCurrent->dominator, extNext->order))
            {
              nodeStatus (current) |= TRACE_TAIL;
              break;
            }
          /*
           *  Mark the link selected.
           */
          arc = FindSrcArc (current, dest, 0);
          if (arc != 0)
            {
              arcType (arc) = nodeType (seed);
            }
          else
            Punt ("SelectTraces: corrupted source link");
          arc = FindDestArc (current, dest, 0);
          if (arc != 0)
            {
              arcType (arc) = nodeType (seed);
            }
          else
            Punt ("SelectTraces: corrupted destination link");
          /*
           *  Add it to the trace.
           */
          nodeType (dest) = nodeType (seed);
          nodeStatus (dest) |= VISITED;
          current = dest;
        }
      /*
       *      Grow the trace backward.
       */
      current = seed;
      for (;;)
        {
          Arc ln, arc;
          Node src;
          /*
           *  Cannot grow from the ENTRY node.
           */
          if (current == ENTRY)
            {
              nodeStatus (current) |= TRACE_HEAD;
              break;
            }
          ln = best_predecessor_of (current);
          if (ln == 0)
            {
              nodeStatus (current) |= TRACE_HEAD;
              break;
            }
          src = sourceNode (ln);
          /*
           *  Can not include a dominee.
           */
          extCurrent = nodeExt (current);
          extNext = nodeExt (src);
          if ((extCurrent == 0) | (extNext == 0))
            {
              Punt ("corrupted extension field");
            }
          if (Set_in (extNext->dominator, extCurrent->order))
            {
              nodeStatus (current) |= TRACE_HEAD;
              break;
            }
          /*
           *  Mark the link selected.
           */
          arc = FindSrcArc (src, current, 0);
          if (arc != 0)
            {
              arcType (arc) = nodeType (seed);
            }
          else
            Punt ("SelectTraces: corrupted source link");
          arc = FindDestArc (src, current, 0);
          if (arc != 0)
            {
              arcType (arc) = nodeType (seed);
            }
          else
            Punt ("SelectTraces: corrupted destination link");
          /*
           *  Add it to the trace.
           */
          nodeType (src) = nodeType (seed);
          nodeStatus (src) |= VISITED;
          current = src;
        }
    }
#else
  /*
   *  Give more attention to the natural flow of the
   *  program.
   */
  ENTRY = graph->root;
  trace_id = 1;
  current = ENTRY;              /* start from the entry block */
  last = 0;
  for (n = 0; n < list_length; n++)
    {
      if (!(nodeStatus (current) & VISITED))
        {
          /*
           *  1) start from the start node first.
           */
          seed = current;
        }
      else
        {
          /*
           *  2) select a fall_thru node if possible.
           *  3) select the most important node.
           */
          Node best, dest;
          Arc pc;
          if (last == 0)
            Punt ("this should not happen");
          best = 0;
          for (pc = destinationArcs (last); pc != 0; pc = nextArc (pc))
            {
              dest = destinationNode (pc);
              if (nodeStatus (dest) & VISITED)
                continue;
              if (best == 0)
                {
                  best = dest;
                }
              else
                if (successor_node_weight (last, dest)
                    > successor_node_weight (last, best))
                {
                  best = dest;
                }
            }
          if (best == 0)
            {
              int k;
              for (k = 0; k < list_length; k++)
                {
                  dest = (Node) sorted_list[k].ptr;
                  if (nodeStatus (dest) & VISITED)
                    continue;
                  best = dest;
                  break;
                }
            }
          if (best == 0)
            {
              break;
            }
          seed = best;
        }
      if (nodeStatus (seed) & VISITED)
        Punt ("incorrect seed selection");
      /*
       *      Start a new trace.
       *      Mark seed visited.
       */
      nodeType (seed) = trace_id++;
      nodeStatus (seed) |= VISITED;
      /*
       *      Grow the trace forward.
       */
      current = seed;
      for (;;)
        {
          Arc ln, arc;
          Node dest;
          ln = best_successor_of (current);
          if (ln == 0)
            {
              nodeStatus (current) |= TRACE_TAIL;
              break;
            }
          /*
           *  Cannot include ENTRY node.
           */
          dest = destinationNode (ln);
          if (dest == ENTRY)
            {
              nodeStatus (current) |= TRACE_TAIL;
              break;
            }
          /*
           *  Can not include a dominator.
           */
          extCurrent = (struct Ext *) nodeExt (current);
          extNext = (struct Ext *) nodeExt (dest);
          if ((extCurrent == 0) || (extNext == 0))
            {
              Punt ("corrupted extension field");
            }
          if (Set_in (extCurrent->dominator, extNext->order))
            {
              nodeStatus (current) |= TRACE_TAIL;
              break;
            }
          /*
           *  Mark the link selected.
           */
          arc = FindSrcArc (current, dest, 0);
          if (arc != 0)
            {
              arcType (arc) = nodeType (seed);
            }
          else
            Punt ("SelectTraces: corrupted source link");
          arc = FindDestArc (current, dest, 0);
          if (arc != 0)
            {
              arcType (arc) = nodeType (seed);
            }
          else
            Punt ("SelectTraces: corrupted destination link");
          /*
           *  Add it to the trace.
           */
          nodeType (dest) = nodeType (seed);
          nodeStatus (dest) |= VISITED;
          current = dest;
        }
      last = current;
      /*
       *      Grow the trace backward.
       */
      current = seed;
      for (;;)
        {
          Arc ln, arc;
          Node src;
          /*
           *  Cannot grow from the ENTRY node.
           */
          if (current == ENTRY)
            {
              nodeStatus (current) |= TRACE_HEAD;
              break;
            }
          ln = best_predecessor_of (current);
          if (ln == 0)
            {
              nodeStatus (current) |= TRACE_HEAD;
              break;
            }
          src = sourceNode (ln);
          /*
           *  Can not include a dominee.
           */
          extCurrent = (struct Ext *) nodeExt (current);
          extNext = (struct Ext *) nodeExt (src);
          if ((extCurrent == 0) || (extNext == 0))
            {
              Punt ("corrupted extension field");
            }
          if (Set_in (extNext->dominator, extCurrent->order))
            {
              nodeStatus (current) |= TRACE_HEAD;
              break;
            }
          /*
           *  Mark the link selected.
           */
          arc = FindSrcArc (src, current, 0);
          if (arc != 0)
            {
              arcType (arc) = nodeType (seed);
            }
          else
            Punt ("SelectTraces: corrupted source link");
          arc = FindDestArc (src, current, 0);
          if (arc != 0)
            {
              arcType (arc) = nodeType (seed);
            }
          else
            Punt ("SelectTraces: corrupted destination link");
          /*
           *  Add it to the trace.
           */
          nodeType (src) = nodeType (seed);
          nodeStatus (src) |= VISITED;
          current = src;
        }
    }
#endif
  /*
   *  Make sure that all nodes have been visited.
   */
  for (ptr = graph->nodes; ptr != 0; ptr = nextNode (ptr))
    {
      if (!(nodeStatus (ptr) & VISITED))
        Punt ("SelectTraces: failed to select all nodes");
    }
  /*  
   *  Detect inner loops.
   */
  for (ptr = graph->nodes; ptr != 0; ptr = nextNode (ptr))
    {
      Arc ln;
      if (!(nodeStatus (ptr) & TRACE_TAIL))
        continue;
      for (ln = destinationArcs (ptr); ln != 0; ln = nextArc (ln))
        {
          Node dest;
          dest = destinationNode (ln);
          if ((nodeStatus (dest) & TRACE_HEAD) &&
              (nodeType (dest) == nodeType (ptr)))
            {
              nodeStatus (dest) |= LOOP_HEAD;
              break;
            }
        }
    }
}
Example #19
0
int RunPlay(){

	Team *O, *D; //Pointers to offence and defense

	if(state == Aoff){ 	// if A is on offense
		O = A;
		D = B;
	} else {		//if B is on offense
		O = B;
		D = A;
	}


	int yrds, thrw;

	cout << "SELECTING PLAY " << play << endl;

	switch(play){

		case PUNT:	
			cout << "Team punts" << endl;
			pos = pos + Punt(D->kr, O->p);
			punt++;

			//If the ball is kicked into the endzome then it is a touchback
			//and the other team gets it at the 20 yard line
			if(pos>99){
				cout << "Touchback" << endl;
				pos=80;
			}
			pos = 100-pos;
			state = Boff;
			return 1;
			break;
		case FIELDGOAL:
			if(Fieldgoal(O->k, (100-pos+17))){
				cout << "Fieldgoal is good!" << endl;
				state = Akick;
				*fg++;
				score[0] += 3;
			} else {
				cout << "Fieldgoal is no good!" << endl;
				pos = 100-pos;
				Turnover();
			}
			return 1;
			break;

		case DEEPPASS:
			//determines how many yards the pass will gain IF completeld
			yrds = PassYards(play, O->qb, O->wr1, D->cb1);

			//the time_left will go down as plays happen, this was just a simple temporary fix, will put
			//a more detailed function in later
			time_left -= (yrds/TIME);

			//if this is true then the QB was sacked. Team A loses 5 yards and the down
			if(Blitz(O->rde, D->lt) || Blitz(O->rde, D->lt) || Blitz(O->rde, D->lt)){
				*sack++;
				pos -= 5;

			}else{
				//This determines the outcome of the pass, a 0 means the qb missed or the receiver 
				//dropped the ball, and 1 means the defender swatted the pass away, a 2 means the 
				//defender intercepted the pass which means team B is then on offence, and a 3 means 
				//team A's receiver successfully caught the ball
				thrw=Pass(O->qb, O->wr1, D->cb1, yrds, time_left);
				*att++;

				//miss or dropped
				if(thrw==0){
					*miss++;
					cout << "Incomplete!" << endl;
				}

				//pass swatted
				else if(thrw==1){
					*swat++;
					cout << "Pass defended!" << endl;
				}

				//pass intercepted
				else if(thrw==2){
					*pick++;
					down=0;
					tofirst=10;
					state = Boff;
					pos = 100-pos-yrds;
					if(pos<1){
						//If the ball is intercepted in the endzome then it is a
						//touchback and the other team gets it at the 20 yard line
						cout << "Touchback" << endl;
						pos=20;
					}
					cout << "Interception!" << endl;
				}

				//pass caught
				else if(thrw==3){
					*cth++;
					passyrds += yrds;
					cout << "Pass completed for " << yrds << " yards!" << endl;
					pos = pos + yrds;
				}

			}
			break;


	}
	return 1;
}
Example #20
0
/**
 * Replace the current process.
 */
void
Proc_Exec(const ProcStuff *ps)
{

	if (ps->in != STDIN_FILENO) {
		/*
		 * Redirect the child's stdin to the input fd
		 * and reset it to the beginning (again).
		 */
		if (dup2(ps->in, STDIN_FILENO) == -1)
			Punt("Cannot dup2: %s", strerror(errno));
		lseek(STDIN_FILENO, (off_t)0, SEEK_SET);
	}

	if (ps->out != STDOUT_FILENO) {
		/*
		 * Redirect the child's stdout to the output fd.
		 */
		if (dup2(ps->out, STDOUT_FILENO) == -1)
			Punt("Cannot dup2: %s", strerror(errno));
		close(ps->out);
	}

	if (ps->err != STDERR_FILENO) {
		/*
		 * Redirect the child's stderr to the err fd.
		 */
		if (dup2(ps->err, STDERR_FILENO) == -1)
			Punt("Cannot dup2: %s", strerror(errno));
		close(ps->err);
	}

	if (ps->merge_errors) {
		/*
		 * Send stderr to parent process too.
		 */
		if (dup2(STDOUT_FILENO, STDERR_FILENO) == -1)
			Punt("Cannot dup2: %s", strerror(errno));
	}

	if (commandShell->unsetenv) {
		/* for the benfit of ksh */
		unsetenv("ENV");
	}

	/*
	 * The file descriptors for stdin, stdout, or stderr might
	 * have been marked close-on-exec.  Clear the flag on all
	 * of them.
	 */
	fcntl(STDIN_FILENO, F_SETFD,
	    fcntl(STDIN_FILENO, F_GETFD) & (~FD_CLOEXEC));
	fcntl(STDOUT_FILENO, F_SETFD,
	    fcntl(STDOUT_FILENO, F_GETFD) & (~FD_CLOEXEC));
	fcntl(STDERR_FILENO, F_SETFD,
	    fcntl(STDERR_FILENO, F_GETFD) & (~FD_CLOEXEC));

	if (ps->pgroup) {
#ifdef USE_PGRP
		/*
		 * Become a process group leader, so we can kill it and all
		 * its descendants in one fell swoop, by killing its process
		 * family, but not commit suicide.
		 */
#if defined(SYSV)
		setsid();
#else
		setpgid(0, getpid());
#endif
#endif /* USE_PGRP */
	}

	if (ps->searchpath) {
		execvp(ps->argv[0], ps->argv);

		write(STDERR_FILENO, ps->argv[0], strlen(ps->argv[0]));
		write(STDERR_FILENO, ": ", 2);
		write(STDERR_FILENO, strerror(errno), strlen(strerror(errno)));
		write(STDERR_FILENO, "\n", 1);
	} else {
		execv(commandShell->path, ps->argv);

		write(STDERR_FILENO,
		    "Could not execute shell\n",
		    sizeof("Could not execute shell"));
	}

	/*
	 * Since we are the child process, exit without flushing buffers.
	 */
	_exit(1);
}
Example #21
0
/*
 *      Measure the trace selection result.
 *      Trace selection must have been applied.
 */
void
ReportSelectionResult (FGraph graph, double *matrix)
{
  int i;
  Node node;
  Arc arc;
  if (graph == 0)
    Punt ("ReportSelectionResult: nil graph");
  if (matrix == 0)
    return;
  for (i = 0; i <= N_LEAF; i++)
    matrix[i] = 0.0;
  /*
   *  Compute the sequential locality.
   */
  for (node = graph->nodes; node != 0; node = nextNode (node))
    {
      Arc ptr;
      Node next_node;
      next_node = nextNode (node);
      if (next_node == 0)       /* ignore the last node */
        break;
      for (ptr = destinationArcs (node); ptr != 0; ptr = nextArc (ptr))
        {
          if (destinationNode (ptr) == next_node)
            {
              matrix[W_SEQUENTIAL] += arcWeight (ptr);
            }
        }
    }
  /*
   *  Measure various transition counts.
   */
  for (node = graph->nodes; node != 0; node = nextNode (node))
    {
      for (arc = destinationArcs (node); arc != 0; arc = nextArc (arc))
        {
          Node src, dest;
          int Sh, St, Dh, Dt;
          src = sourceNode (arc);
          dest = destinationNode (arc);
          Sh = nodeStatus (src) & TRACE_HEAD;
          St = nodeStatus (src) & TRACE_TAIL;
          Dh = nodeStatus (dest) & TRACE_HEAD;
          Dt = nodeStatus (dest) & TRACE_TAIL;
          if ((arcType (arc) != 0) && (arcType (arc) == nodeType (node)))
            {
              /*
               *      In-trace.
               */
              matrix[W_E] += arcWeight (arc);
            }
          else if (arcType (arc) != 0)
            {
              Punt ("ReportSelectionResult: illegal arc type");
            }
          else
            {
              if (St && Dh)
                {               /* terminal to head */
                  matrix[W_A] += arcWeight (arc);
                  /* detect loop back-edge */
                  if (nodeType (src) == nodeType (dest))
                    {
                      matrix[W_BACK_EDGE] += arcWeight (arc);
                    }
                }
              else if (St && !Dh)
                {               /* terminal to middle */
                  matrix[W_B] += arcWeight (arc);
                }
              else if (!St && Dh)
                {               /* middle to head */
                  matrix[W_C] += arcWeight (arc);
                }
              else
                {               /* middle to middle */
                  matrix[W_D] += arcWeight (arc);
                }
            }
        }
    }
#ifdef DEBUG_TRACE2
  if (matrix[W_E] > matrix[W_SEQUENTIAL])
    {
      WriteGraph ("zzz.debug", graph);
      fprintf (stderr, "in-trace = %f\n", matrix[W_E]);
      fprintf (stderr, "sequential = %f\n", matrix[W_SEQUENTIAL]);
      Punt ("ReportSelection: incorrect in-trace");
    }
#endif
  /*
   *  Measure several graph parameters.
   */
  for (node = graph->nodes; node != 0; node = nextNode (node))
    {
      nodeStatus (node) &= ~VISITED;    /* borrow the valid bit */
      matrix[N_NODES] += 1.0;
      matrix[W_NODES] += nodeWeight (node);
      if (destinationArcs (node) == 0)
        {
          matrix[N_LEAF] += 1.0;
        }
      if (sourceArcs (node) == 0)
        {
          matrix[N_ROOT] += 1.0;
        }
      for (arc = destinationArcs (node); arc != 0; arc = nextArc (arc))
        {
          matrix[N_ARCS] += 1.0;
          matrix[W_ARCS] += arcWeight (arc);
        }
    }
  for (node = graph->nodes; node != 0; node = nextNode (node))
    {
      Node ptr;
      int trace_id, loop, size;
      if (nodeStatus (node) & VISITED)
        continue;
      trace_id = nodeType (node);
      loop = 0;
      size = 0;
      for (ptr = graph->nodes; ptr != 0; ptr = nextNode (ptr))
        {
          if (nodeType (ptr) == trace_id)
            {
              nodeStatus (ptr) |= VISITED;
              size++;
              loop |= (nodeStatus (node) & LOOP_HEAD);
            }
        }
      matrix[N_TRACE] += 1.0;
      matrix[L_TRACE] += size;
      if (loop)
        {
          matrix[N_LOOP] += 1.0;
          matrix[L_LOOP] += size;
        }
    }
  if (matrix[L_TRACE] != matrix[N_NODES])
    Punt ("ReportSelectionResult: incorrect accounting");
  if (matrix[N_TRACE] != 0.0)
    matrix[L_TRACE] /= matrix[N_TRACE];
  if (matrix[N_LOOP] != 0.0)
    matrix[L_LOOP] /= matrix[N_LOOP];
}
Example #22
0
File: util.c Project: aosm/X11
void myclose(int fid)
{
    if (close(fid) < 0) Punt("Error in myclose!");
    DEBUG1( "# %d : <Closed>\n", fid)
}
Example #23
0
/*-
 *-----------------------------------------------------------------------
 * Make_Update  --
 *	Perform update on the parents of a node. Used by JobFinish once
 *	a node has been dealt with and by MakeStartJobs if it finds an
 *	up-to-date node.
 *
 * Input:
 *	cgn		the child node
 *
 * Results:
 *	Always returns 0
 *
 * Side Effects:
 *	The unmade field of pgn is decremented and pgn may be placed on
 *	the toBeMade queue if this field becomes 0.
 *
 * 	If the child was made, the parent's flag CHILDMADE field will be
 *	set true.
 *
 *	If the child is not up-to-date and still does not exist,
 *	set the FORCE flag on the parents.
 *
 *	If the child wasn't made, the cmgn field of the parent will be
 *	altered if the child's mtime is big enough.
 *
 *	Finally, if the child is the implied source for the parent, the
 *	parent's IMPSRC variable is set appropriately.
 *
 *-----------------------------------------------------------------------
 */
void
Make_Update(GNode *cgn)
{
    GNode 	*pgn;	/* the parent node */
    char  	*cname;	/* the child's name */
    LstNode	ln; 	/* Element in parents and iParents lists */
    time_t	mtime = -1;
    char	*p1;
    Lst		parents;
    GNode	*centurion;

    /* It is save to re-examine any nodes again */
    checked++;

    cname = Var_Value(TARGET, cgn, &p1);
    free(p1);

    if (DEBUG(MAKE))
	fprintf(debug_file, "Make_Update: %s%s\n", cgn->name, cgn->cohort_num);

    /*
     * If the child was actually made, see what its modification time is
     * now -- some rules won't actually update the file. If the file still
     * doesn't exist, make its mtime now.
     */
    if (cgn->made != UPTODATE) {
	mtime = Make_Recheck(cgn);
    }

    /*
     * If this is a `::' node, we must consult its first instance
     * which is where all parents are linked.
     */
    if ((centurion = cgn->centurion) != NULL) {
	if (!Lst_IsEmpty(cgn->parents))
		Punt("%s%s: cohort has parents", cgn->name, cgn->cohort_num);
	centurion->unmade_cohorts -= 1;
	if (centurion->unmade_cohorts < 0)
	    Error("Graph cycles through centurion %s", centurion->name);
    } else {
	centurion = cgn;
    }
    parents = centurion->parents;

    /* If this was a .ORDER node, schedule the RHS */
    Lst_ForEach(centurion->order_succ, MakeBuildParent, Lst_First(toBeMade));

    /* Now mark all the parents as having one less unmade child */
    if (Lst_Open(parents) == SUCCESS) {
	while ((ln = Lst_Next(parents)) != NULL) {
	    pgn = (GNode *)Lst_Datum(ln);
	    if (DEBUG(MAKE))
		fprintf(debug_file, "inspect parent %s%s: flags %x, "
			    "type %x, made %d, unmade %d ",
			pgn->name, pgn->cohort_num, pgn->flags,
			pgn->type, pgn->made, pgn->unmade-1);

	    if (!(pgn->flags & REMAKE)) {
		/* This parent isn't needed */
		if (DEBUG(MAKE))
		    fprintf(debug_file, "- not needed\n");
		continue;
	    }
	    if (mtime == 0 && !(cgn->type & OP_WAIT))
		pgn->flags |= FORCE;

	    /*
	     * If the parent has the .MADE attribute, its timestamp got
	     * updated to that of its newest child, and its unmake
	     * child count got set to zero in Make_ExpandUse().
	     * However other things might cause us to build one of its
	     * children - and so we mustn't do any processing here when
	     * the child build finishes.
	     */
	    if (pgn->type & OP_MADE) {
		if (DEBUG(MAKE))
		    fprintf(debug_file, "- .MADE\n");
		continue;
	    }

	    if ( ! (cgn->type & (OP_EXEC|OP_USE|OP_USEBEFORE))) {
		if (cgn->made == MADE)
		    pgn->flags |= CHILDMADE;
		(void)Make_TimeStamp(pgn, cgn);
	    }

	    /*
	     * A parent must wait for the completion of all instances
	     * of a `::' dependency.
	     */
	    if (centurion->unmade_cohorts != 0 || centurion->made < MADE) {
		if (DEBUG(MAKE))
		    fprintf(debug_file,
			    "- centurion made %d, %d unmade cohorts\n",
			    centurion->made, centurion->unmade_cohorts);
		continue;
	    }

	    /* One more child of this parent is now made */
	    pgn->unmade -= 1;
	    if (pgn->unmade < 0) {
		if (DEBUG(MAKE)) {
		    fprintf(debug_file, "Graph cycles through %s%s\n",
			pgn->name, pgn->cohort_num);
		    Targ_PrintGraph(2);
		}
		Error("Graph cycles through %s%s", pgn->name, pgn->cohort_num);
	    }

	    /* We must always rescan the parents of .WAIT and .ORDER nodes. */
	    if (pgn->unmade != 0 && !(centurion->type & OP_WAIT)
		    && !(centurion->flags & DONE_ORDER)) {
		if (DEBUG(MAKE))
		    fprintf(debug_file, "- unmade children\n");
		continue;
	    }
	    if (pgn->made != DEFERRED) {
		/*
		 * Either this parent is on a different branch of the tree,
		 * or it on the RHS of a .WAIT directive
		 * or it is already on the toBeMade list.
		 */
		if (DEBUG(MAKE))
		    fprintf(debug_file, "- not deferred\n");
		continue;
	    }
	    if (pgn->order_pred
		    && Lst_ForEach(pgn->order_pred, MakeCheckOrder, 0)) {
		/* A .ORDER rule stops us building this */
		continue;
	    }
	    if (DEBUG(MAKE)) {
		static int two = 2;
		fprintf(debug_file, "- %s%s made, schedule %s%s (made %d)\n",
			cgn->name, cgn->cohort_num,
			pgn->name, pgn->cohort_num, pgn->made);
		Targ_PrintNode(pgn, &two);
	    }
	    /* Ok, we can schedule the parent again */
	    pgn->made = REQUESTED;
	    (void)Lst_EnQueue(toBeMade, pgn);
	}
	Lst_Close(parents);
    }

    /*
     * Set the .PREFIX and .IMPSRC variables for all the implied parents
     * of this node.
     */
    if (Lst_Open(cgn->iParents) == SUCCESS) {
	char	*cpref = Var_Value(PREFIX, cgn, &p1);

	while ((ln = Lst_Next(cgn->iParents)) != NULL) {
	    pgn = (GNode *)Lst_Datum(ln);
	    if (pgn->flags & REMAKE) {
		Var_Set(IMPSRC, cname, pgn, 0);
		if (cpref != NULL)
		    Var_Set(PREFIX, cpref, pgn, 0);
	    }
	}
	free(p1);
	Lst_Close(cgn->iParents);
    }
}
Example #24
0
File: util.c Project: aosm/X11
void myfclose(FILE *file)
{
    int fid = fileno(file);
    if (fclose(file) < 0) Punt("Error in myfclose!");
    DEBUG1("# %d : <Closed>\n", fid)
}
Example #25
0
/*-
 * MainParseArgs --
 *	Parse a given argument vector. Called from main() and from
 *	Main_ParseArgLine() when the .MAKEFLAGS target is used.
 *
 *	XXX: Deal with command line overriding .MAKEFLAGS in makefile
 *
 * Results:
 *	None
 *
 * Side Effects:
 *	Various global and local flags will be set depending on the flags
 *	given
 */
static void
MainParseArgs(int argc, char **argv)
{
	char *p;
	int c = '?';
	int arginc;
	char *argvalue;
	const char *getopt_def;
	char *optscan;
	Boolean inOption, dashDash = FALSE;
	char found_path[MAXPATHLEN + 1];	/* for searching for sys.mk */

#define OPTFLAGS "BC:D:I:J:NST:V:WXd:ef:ij:km:nqrstw"
/* Can't actually use getopt(3) because rescanning is not portable */

	getopt_def = OPTFLAGS;
rearg:	
	inOption = FALSE;
	optscan = NULL;
	while(argc > 1) {
		char *getopt_spec;
		if(!inOption)
			optscan = argv[1];
		c = *optscan++;
		arginc = 0;
		if(inOption) {
			if(c == '\0') {
				++argv;
				--argc;
				inOption = FALSE;
				continue;
			}
		} else {
			if (c != '-' || dashDash)
				break;
			inOption = TRUE;
			c = *optscan++;
		}
		/* '-' found at some earlier point */
		getopt_spec = strchr(getopt_def, c);
		if(c != '\0' && getopt_spec != NULL && getopt_spec[1] == ':') {
			/* -<something> found, and <something> should have an arg */
			inOption = FALSE;
			arginc = 1;
			argvalue = optscan;
			if(*argvalue == '\0') {
				if (argc < 3)
					goto noarg;
				argvalue = argv[2];
				arginc = 2;
			}
		} else {
			argvalue = NULL; 
		}
		switch(c) {
		case '\0':
			arginc = 1;
			inOption = FALSE;
			break;
		case 'B':
			compatMake = TRUE;
			Var_Append(MAKEFLAGS, "-B", VAR_GLOBAL);
			Var_Set(MAKE_MODE, "compat", VAR_GLOBAL, 0);
			break;
		case 'C':
			if (chdir(argvalue) == -1) {
				(void)fprintf(stderr,
					      "%s: chdir %s: %s\n",
					      progname, argvalue,
					      strerror(errno));
				exit(1);
			}
			if (getcwd(curdir, MAXPATHLEN) == NULL) {
				(void)fprintf(stderr, "%s: %s.\n", progname, strerror(errno));
				exit(2);
			}
			ignorePWD = TRUE;
			break;
		case 'D':
			if (argvalue == NULL || argvalue[0] == 0) goto noarg;
			Var_Set(argvalue, "1", VAR_GLOBAL, 0);
			Var_Append(MAKEFLAGS, "-D", VAR_GLOBAL);
			Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
			break;
		case 'I':
			if (argvalue == NULL) goto noarg;
			Parse_AddIncludeDir(argvalue);
			Var_Append(MAKEFLAGS, "-I", VAR_GLOBAL);
			Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
			break;
		case 'J':
			if (argvalue == NULL) goto noarg;
			if (sscanf(argvalue, "%d,%d", &jp_0, &jp_1) != 2) {
			    (void)fprintf(stderr,
				"%s: internal error -- J option malformed (%s)\n",
				progname, argvalue);
				usage();
			}
			if ((fcntl(jp_0, F_GETFD, 0) < 0) ||
			    (fcntl(jp_1, F_GETFD, 0) < 0)) {
#if 0
			    (void)fprintf(stderr,
				"%s: ###### warning -- J descriptors were closed!\n",
				progname);
			    exit(2);
#endif
			    jp_0 = -1;
			    jp_1 = -1;
			    compatMake = TRUE;
			} else {
			    Var_Append(MAKEFLAGS, "-J", VAR_GLOBAL);
			    Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
			    jobServer = TRUE;
			}
			break;
		case 'N':
			noExecute = TRUE;
			noRecursiveExecute = TRUE;
			Var_Append(MAKEFLAGS, "-N", VAR_GLOBAL);
			break;
		case 'S':
			keepgoing = FALSE;
			Var_Append(MAKEFLAGS, "-S", VAR_GLOBAL);
			break;
		case 'T':
			if (argvalue == NULL) goto noarg;
			tracefile = bmake_strdup(argvalue);
			Var_Append(MAKEFLAGS, "-T", VAR_GLOBAL);
			Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
			break;
		case 'V':
			if (argvalue == NULL) goto noarg;
			printVars = TRUE;
			(void)Lst_AtEnd(variables, argvalue);
			Var_Append(MAKEFLAGS, "-V", VAR_GLOBAL);
			Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
			break;
		case 'W':
			parseWarnFatal = TRUE;
			break;
		case 'X':
			varNoExportEnv = TRUE;
			Var_Append(MAKEFLAGS, "-X", VAR_GLOBAL);
			break;
		case 'd':
			if (argvalue == NULL) goto noarg;
			/* If '-d-opts' don't pass to children */
			if (argvalue[0] == '-')
			    argvalue++;
			else {
			    Var_Append(MAKEFLAGS, "-d", VAR_GLOBAL);
			    Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
			}
			parse_debug_options(argvalue);
			break;
		case 'e':
			checkEnvFirst = TRUE;
			Var_Append(MAKEFLAGS, "-e", VAR_GLOBAL);
			break;
		case 'f':
			if (argvalue == NULL) goto noarg;
			(void)Lst_AtEnd(makefiles, argvalue);
			break;
		case 'i':
			ignoreErrors = TRUE;
			Var_Append(MAKEFLAGS, "-i", VAR_GLOBAL);
			break;
		case 'j':
			if (argvalue == NULL) goto noarg;
			forceJobs = TRUE;
			maxJobs = strtol(argvalue, &p, 0);
			if (*p != '\0' || maxJobs < 1) {
				(void)fprintf(stderr, "%s: illegal argument to -j -- must be positive integer!\n",
				    progname);
				exit(1);
			}
			Var_Append(MAKEFLAGS, "-j", VAR_GLOBAL);
			Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
			Var_Set(".MAKE.JOBS", argvalue, VAR_GLOBAL, 0);
			maxJobTokens = maxJobs;
			break;
		case 'k':
			keepgoing = TRUE;
			Var_Append(MAKEFLAGS, "-k", VAR_GLOBAL);
			break;
		case 'm':
			if (argvalue == NULL) goto noarg;
			/* look for magic parent directory search string */
			if (strncmp(".../", argvalue, 4) == 0) {
				if (!Dir_FindHereOrAbove(curdir, argvalue+4,
				    found_path, sizeof(found_path)))
					break;		/* nothing doing */
				(void)Dir_AddDir(sysIncPath, found_path);
			} else {
				(void)Dir_AddDir(sysIncPath, argvalue);
			}
			Var_Append(MAKEFLAGS, "-m", VAR_GLOBAL);
			Var_Append(MAKEFLAGS, argvalue, VAR_GLOBAL);
			break;
		case 'n':
			noExecute = TRUE;
			Var_Append(MAKEFLAGS, "-n", VAR_GLOBAL);
			break;
		case 'q':
			queryFlag = TRUE;
			/* Kind of nonsensical, wot? */
			Var_Append(MAKEFLAGS, "-q", VAR_GLOBAL);
			break;
		case 'r':
			noBuiltins = TRUE;
			Var_Append(MAKEFLAGS, "-r", VAR_GLOBAL);
			break;
		case 's':
			beSilent = TRUE;
			Var_Append(MAKEFLAGS, "-s", VAR_GLOBAL);
			break;
		case 't':
			touchFlag = TRUE;
			Var_Append(MAKEFLAGS, "-t", VAR_GLOBAL);
			break;
		case 'w':
			enterFlag = TRUE;
			Var_Append(MAKEFLAGS, "-w", VAR_GLOBAL);
			break;
		case '-':
			dashDash = TRUE;
			break;
		default:
		case '?':
#ifndef MAKE_NATIVE
			fprintf(stderr, "getopt(%s) -> %d (%c)\n",
				OPTFLAGS, c, c);
#endif
			usage();
		}
		argv += arginc;
		argc -= arginc;
	}

	oldVars = TRUE;

	/*
	 * See if the rest of the arguments are variable assignments and
	 * perform them if so. Else take them to be targets and stuff them
	 * on the end of the "create" list.
	 */
	for (; argc > 1; ++argv, --argc)
		if (Parse_IsVar(argv[1])) {
			Parse_DoVar(argv[1], VAR_CMD);
		} else {
			if (!*argv[1])
				Punt("illegal (null) argument.");
			if (*argv[1] == '-' && !dashDash)
				goto rearg;
			(void)Lst_AtEnd(create, bmake_strdup(argv[1]));
		}

	return;
noarg:
	(void)fprintf(stderr, "%s: option requires an argument -- %c\n",
	    progname, c);
	usage();
}
Example #26
0
/*-
 * MainParseArgs --
 *	Parse a given argument vector. Called from main() and from
 *	Main_ParseArgLine() when the .MAKEFLAGS target is used.
 *
 *	XXX: Deal with command line overriding .MAKEFLAGS in makefile
 *
 * Side Effects:
 *	Various global and local flags will be set depending on the flags
 *	given
 */
static void
MainParseArgs(int argc, char **argv)
{
	int c, optend;

#define OPTFLAGS "BC:D:I:SV:d:ef:ij:km:npqrst"
#define OPTLETTERS "BSiknpqrst"

	if (pledge("stdio rpath wpath cpath proc exec", NULL) == -1)
		err(2, "pledge");

	optind = 1;	/* since we're called more than once */
	optreset = 1;
	optend = 0;
	while (optind < argc) {
		if (!optend && argv[optind][0] == '-') {
			if (argv[optind][1] == '\0')
				optind++;	/* ignore "-" */
			else if (argv[optind][1] == '-' &&
			    argv[optind][2] == '\0') {
				optind++;	/* ignore "--" */
				optend++;	/* "--" denotes end of flags */
			}
		}
		c = optend ? -1 : getopt(argc, argv, OPTFLAGS);
		switch (c) {
		case 'C':
			break;
		case 'D':
			Var_Set(optarg, "1");
			record_option(c, optarg);
			break;
		case 'I':
			Parse_AddIncludeDir(optarg);
			record_option(c, optarg);
			break;
		case 'V':
			Lst_AtEnd(&varstoprint, optarg);
			record_option(c, optarg);
			break;
		case 'd': {
			char *modules = optarg;

			for (; *modules; ++modules)
				switch (*modules) {
				case 'A':
					debug = ~0;
					break;
				case 'a':
					debug |= DEBUG_ARCH;
					break;
				case 'c':
					debug |= DEBUG_COND;
					break;
				case 'd':
					debug |= DEBUG_DIR;
					break;
				case 'D':
					debug |= DEBUG_DOUBLE;
					break;
				case 'e':
					debug |= DEBUG_EXPENSIVE;
					break;
				case 'f':
					debug |= DEBUG_FOR;
					break;
				case 'g':
					if (modules[1] == '1') {
						debug |= DEBUG_GRAPH1;
						++modules;
					}
					else if (modules[1] == '2') {
						debug |= DEBUG_GRAPH2;
						++modules;
					}
					break;
				case 'h':
					debug |= DEBUG_HELDJOBS;
					break;
				case 'j':
					debug |= DEBUG_JOB | DEBUG_KILL;
					break;
				case 'J':
					/* ignore */
					break;
				case 'k':
					debug |= DEBUG_KILL;
					break;
				case 'l':
					debug |= DEBUG_LOUD;
					break;
				case 'm':
					debug |= DEBUG_MAKE;
					break;
				case 'n':
					debug |= DEBUG_NAME_MATCHING;
					break;
				case 'p':
					debug |= DEBUG_PARALLEL;
					break;
				case 'q':
					debug |= DEBUG_QUICKDEATH;
					break;
				case 's':
					debug |= DEBUG_SUFF;
					break;
				case 't':
					debug |= DEBUG_TARG;
					break;
				case 'T':
					debug |= DEBUG_TARGGROUP;
					break;
				case 'v':
					debug |= DEBUG_VAR;
					break;
				default:
					(void)fprintf(stderr,
				"make: illegal argument to -d option -- %c\n",
					    *modules);
					usage();
				}
			record_option(c, optarg);
			break;
		}
		case 'f':
			Lst_AtEnd(&makefiles, optarg);
			break;
		case 'j': {
		   char *endptr;

			forceJobs = true;
			maxJobs = strtol(optarg, &endptr, 0);
			if (endptr == optarg) {
				fprintf(stderr,
					"make: illegal argument to -j option -- %s -- not a number\n",
					optarg);
				usage();
			}
			record_option(c, optarg);
			break;
		}
		case 'm':
			Dir_AddDir(systemIncludePath, optarg);
			record_option(c, optarg);
			break;
		case -1:
			/* Check for variable assignments and targets. */
			if (argv[optind] != NULL &&
			    !Parse_CmdlineVar(argv[optind])) {
				if (!*argv[optind])
					Punt("illegal (null) argument.");
				Lst_AtEnd(create, estrdup(argv[optind]));
			}
			optind++;	/* skip over non-option */
			break;
		default:
			posixParseOptLetter(c);
		}
	}
}