예제 #1
0
char *
wildcard_expansion (char *wc, char *o)
{
#   define PATH_SIZE    1024
    struct AnchorPath * apath;

    if ( (apath = AllocMem (sizeof (struct AnchorPath) + PATH_SIZE,
            MEMF_CLEAR))
        )
    {
        apath->ap_Strlen = PATH_SIZE;

        if (MatchFirst (wc, apath) == 0)
        {
            do
            {
                o = variable_buffer_output (o, apath->ap_Buf,
                        strlen (apath->ap_Buf));
                o = variable_buffer_output (o, " ",1);
            } while (MatchNext (apath) == 0);
        }

        MatchEnd (apath);
        FreeMem (apath, sizeof (struct AnchorPath) + PATH_SIZE);
    }

    return o;
}
예제 #2
0
파일: expand.c 프로젝트: dezelin/kBuild
static char *
variable_append (const char *name, unsigned int length,
                 const struct variable_set_list *set)
{
  const struct variable *v;
  char *buf = 0;

  /* If there's nothing left to check, return the empty buffer.  */
  if (!set)
    return initialize_variable_output ();

  /* Try to find the variable in this variable set.  */
  v = lookup_variable_in_set (name, length, set->set);

  /* If there isn't one, look to see if there's one in a set above us.  */
  if (!v)
    return variable_append (name, length, set->next);

  /* If this variable type is append, first get any upper values.
     If not, initialize the buffer.  */
  if (v->append)
    buf = variable_append (name, length, set->next);
  else
    buf = initialize_variable_output ();

  /* Append this value to the buffer, and return it.
     If we already have a value, first add a space.  */
  if (buf > variable_buffer)
    buf = variable_buffer_output (buf, " ", 1);
#ifdef CONFIG_WITH_VALUE_LENGTH
  assert (v->value_length == strlen (v->value));
#endif

  /* Either expand it or copy it, depending.  */
  if (! v->recursive)
#ifdef CONFIG_WITH_VALUE_LENGTH
    return variable_buffer_output (buf, v->value, v->value_length);
#else
    return variable_buffer_output (buf, v->value, strlen (v->value));
#endif

#ifdef CONFIG_WITH_VALUE_LENGTH
  variable_expand_string_2 (buf, v->value, v->value_length, &buf);
  return buf;
#else
  buf = variable_expand_string (buf, v->value, strlen (v->value));
  return (buf + strlen (buf));
#endif
}
예제 #3
0
파일: expand.c 프로젝트: chaosAD/remake
__inline
#endif
static char *
reference_variable (char *o, const char *name, unsigned int length)
{
  struct variable *v;
  char *value;

  v = lookup_variable (name, length);

  if (v == 0)
    warn_undefined (name, length);

  /* If there's no variable by that name or it has no value, stop now.  */
  if (v == 0 || (*v->value == '\0' && !v->append))
    return o;

  value = (v->recursive ? recursively_expand (v) : v->value);

  o = variable_buffer_output (o, value, strlen (value));

  if (v->recursive)
    free (value);

  return o;
}
예제 #4
0
파일: expand.c 프로젝트: dezelin/kBuild
/* Static worker for reference_variable() that expands the recursive
   variable V. The main difference between this and
   recursively_expand[_for_file] is that this worker avoids the temporary
   buffer and outputs directly into the current variable buffer (O).  */
static char *
reference_recursive_variable (char *o, struct variable *v)
{
  const struct floc *this_var;
  const struct floc **saved_varp;
  int set_reading = 0;

  /* Don't install a new location if this location is empty.
     This can happen for command-line variables, builtin variables, etc.  */
  saved_varp = expanding_var;
  if (v->fileinfo.filenm)
    {
      this_var = &v->fileinfo;
      expanding_var = &this_var;
    }

  /* If we have no other file-reading context, use the variable's context. */
  if (!reading_file)
    {
      set_reading = 1;
      reading_file = &v->fileinfo;
    }

  if (v->expanding)
    {
      if (!v->exp_count)
        /* Expanding V causes infinite recursion.  Lose.  */
        fatal (*expanding_var,
               _("Recursive variable `%s' references itself (eventually)"),
               v->name);
      --v->exp_count;
    }

  v->expanding = 1;
  if (!v->append)
    /* Expand directly into the variable buffer.  */
    variable_expand_string_2 (o, v->value, v->value_length, &o);
  else
    {
      /* XXX: Feel free to optimize appending target variables as well.  */
      char *value = allocated_variable_append (v);
      unsigned int value_len = strlen (value);
      o = variable_buffer_output (o, value, value_len);
      free (value);
    }
  v->expanding = 0;

  if (set_reading)
    reading_file = 0;

  expanding_var = saved_varp;

  return o;
}
예제 #5
0
파일: expand.c 프로젝트: dezelin/kBuild
/* Expands the specified string, appending it to the specified
   variable value. */
void
append_expanded_string_to_variable (struct variable *v, const char *value,
                                    unsigned int value_len, int append)
{
  char *p = (char *) memchr (value, '$', value_len);
  if (!p)
    /* fast path */
    append_string_to_variable (v,value, value_len, append);
  else if (value_len)
    {
      unsigned int off_dollar = p - (char *)value;

      /* Install a fresh variable buffer. */
      char *saved_buffer;
      unsigned int saved_buffer_length;
      install_variable_buffer (&saved_buffer, &saved_buffer_length);

      p = variable_buffer;
      if (append || !v->value_length)
        {
          /* Copy the current value into it and append a space. */
          if (v->value_length)
            {
              p = variable_buffer_output (p, v->value, v->value_length);
              p = variable_buffer_output (p, " ", 1);
            }

          /* Append the assignment value. */
          p = variable_buffer_output (p, value, off_dollar);
          variable_expand_string_2 (p, value + off_dollar, value_len - off_dollar, &p);
        }
      else
        {
          /* Expand the assignemnt value. */
          p = variable_buffer_output (p, value, off_dollar);
          variable_expand_string_2 (p, value + off_dollar, value_len - off_dollar, &p);

          /* Append a space followed by the old value. */
          p = variable_buffer_output (p, " ", 1);
          p = variable_buffer_output (p, v->value, v->value_length + 1) - 1;
        }

      /* Replace the variable with the variable buffer. */
#ifdef CONFIG_WITH_RDONLY_VARIABLE_VALUE
      if (v->rdonly_val)
        v->rdonly_val = 0;
      else
#endif
        free (v->value);
      v->value = variable_buffer;
      v->value_length = p - v->value;
      v->value_alloc_len = variable_buffer_length;

      /* Restore the variable buffer, but without freeing the current. */
      variable_buffer = NULL;
      restore_variable_buffer (saved_buffer, saved_buffer_length);
    }
  /* else: Drop empty strings. Use $(NO_SUCH_VARIABLE) if a space is wanted. */
}
예제 #6
0
파일: expand.c 프로젝트: alanfalloon/make
static char *
variable_append (const char *name, unsigned int length,
                 const struct variable_set_list *set, int local)
{
    const struct variable *v;
    char *buf = 0;
    /* If this set is local and the next is not a parent, then next is local.  */
    int nextlocal = local && set->next_is_parent == 0;

    /* If there's nothing left to check, return the empty buffer.  */
    if (!set)
        return initialize_variable_output ();

    /* Try to find the variable in this variable set.  */
    v = lookup_variable_in_set (name, length, set->set);

    /* If there isn't one, or this one is private, try the set above us.  */
    if (!v || (!local && v->private_var))
        return variable_append (name, length, set->next, nextlocal);

    /* If this variable type is append, first get any upper values.
       If not, initialize the buffer.  */
    if (v->append)
        buf = variable_append (name, length, set->next, nextlocal);
    else
        buf = initialize_variable_output ();

    /* Append this value to the buffer, and return it.
       If we already have a value, first add a space.  */
    if (buf > variable_buffer)
        buf = variable_buffer_output (buf, " ", 1);

    /* Either expand it or copy it, depending.  */
    if (! v->recursive)
        return variable_buffer_output (buf, v->value, strlen (v->value));

    buf = variable_expand_string (buf, v->value, strlen (v->value));
    return (buf + strlen (buf));
}
예제 #7
0
파일: expand.c 프로젝트: dezelin/kBuild
__inline
#endif
static char *
#endif
reference_variable (char *o, const char *name, unsigned int length)
{
  struct variable *v;
#ifndef CONFIG_WITH_VALUE_LENGTH
  char *value;
#endif

  v = lookup_variable (name, length);

  if (v == 0)
    warn_undefined (name, length);

  /* If there's no variable by that name or it has no value, stop now.  */
  if (v == 0 || (*v->value == '\0' && !v->append))
    return o;

#ifdef CONFIG_WITH_VALUE_LENGTH
  assert (v->value_length == strlen (v->value));
  if (!v->recursive)
    o = variable_buffer_output (o, v->value, v->value_length);
  else
    o = reference_recursive_variable (o, v);
#else  /* !CONFIG_WITH_VALUE_LENGTH */
  value = (v->recursive ? recursively_expand (v) : v->value);

  o = variable_buffer_output (o, value, strlen (value));

  if (v->recursive)
    free (value);
#endif /* !CONFIG_WITH_VALUE_LENGTH */

  return o;
}
예제 #8
0
파일: expand.c 프로젝트: dezelin/kBuild
char *
variable_expand (const char *line)
{
#ifndef CONFIG_WITH_VALUE_LENGTH
  return variable_expand_string(NULL, line, (long)-1);
#else  /* CONFIG_WITH_VALUE_LENGTH */
  char *s;

  /* this function is abused a lot like this: variable_expand(""). */
  if (!*line)
    {
      s = variable_buffer_output (initialize_variable_output (), "\0", 2);
      return s - 2;
    }
  return variable_expand_string_2 (NULL, line, (long)-1, &s);
#endif /* CONFIG_WITH_VALUE_LENGTH */
}
예제 #9
0
파일: expand.c 프로젝트: OpenValley/vizmake
static char *
reference_variable (char *o, const char *name, unsigned int length)
{
  // fprintf(stderr, "reference variable for name=%s, length=%d, o=%s\n", name, length, o);
  struct variable *v;
  char *value;

  v = lookup_variable (name, length);

  if (v == 0)
    warn_undefined (name, length);

  /* If there's no variable by that name or it has no value, stop now.  */
  if (v == 0 || (*v->value == '\0' && !v->append)) {

    // Vizmake
    if (!v) {
      char buf[BSIZE];
      if (length > BSIZE) length = BSIZE - 1;
      strncpy(buf, name, length);
      buf[length] = '\0';
      vprint("VAR REF END---UNDEFINED---%s", buf);
    }
    else
      vprint_var(v, "");

    return o;
  }

  value = (v->recursive ? recursively_expand (v) : v->value);

  // Wenbin
  vprint_var(v, value);

  o = variable_buffer_output (o, value, strlen (value));

  // fprintf(stderr, "wenbin: %s: %s=%s => %s\n", name, v->name, v->value, o);

  if (v->recursive)
    free (value);

  return o;
}
예제 #10
0
파일: expand.c 프로젝트: chaosAD/remake
static char *
allocated_variable_append (const struct variable *v)
{
  char *val;

  /* Construct the appended variable value.  */

  char *obuf = variable_buffer;
  unsigned int olen = variable_buffer_length;

  variable_buffer = 0;

  val = variable_append (v->name, strlen (v->name), current_variable_set_list);
  variable_buffer_output (val, "", 1);
  val = variable_buffer;

  variable_buffer = obuf;
  variable_buffer_length = olen;

  return val;
}
예제 #11
0
파일: expand.c 프로젝트: chaosAD/remake
/* Scan STRING for variable references and expansion-function calls.  Only
   LENGTH bytes of STRING are actually scanned.  If LENGTH is -1, scan until
   a null byte is found.

   Write the results to LINE, which must point into `variable_buffer'.  If
   LINE is NULL, start at the beginning of the buffer.
   Return a pointer to LINE, or to the beginning of the buffer if LINE is
   NULL.
 */
char *
variable_expand_string (char *line, const char *string, long length)
{
  struct variable *v;
  const char *p, *p1;
  char *abuf = NULL;
  char *o;
  unsigned int line_offset;

  if (!line)
    line = initialize_variable_output();
  o = line;
  line_offset = line - variable_buffer;

  if (length == 0)
    {
      variable_buffer_output (o, "", 1);
      return (variable_buffer);
    }

  /* If we want a subset of the string, allocate a temporary buffer for it.
     Most of the functions we use here don't work with length limits.  */
  if (length > 0 && string[length] != '\0')
    {
      abuf = xmalloc(length+1);
      memcpy(abuf, string, length);
      abuf[length] = '\0';
      string = abuf;
    }
  p = string;

  while (1)
    {
      /* Copy all following uninteresting chars all at once to the
         variable output buffer, and skip them.  Uninteresting chars end
	 at the next $ or the end of the input.  */

      p1 = strchr (p, '$');

      o = variable_buffer_output (o, p, p1 != 0 ? (unsigned int)(p1 - p) : strlen (p) + 1);

      if (p1 == 0)
	break;
      p = p1 + 1;

      /* Dispatch on the char that follows the $.  */

      switch (*p)
	{
	case '$':
	  /* $$ seen means output one $ to the variable output buffer.  */
	  o = variable_buffer_output (o, p, 1);
	  break;

	case '(':
	case '{':
	  /* $(...) or ${...} is the general case of substitution.  */
	  {
	    char openparen = *p;
	    char closeparen = (openparen == '(') ? ')' : '}';
            const char *begp;
	    const char *beg = p + 1;
	    char *op;
            char *abeg = NULL;
	    const char *end, *colon;

	    op = o;
	    begp = p;
	    if (handle_function (&op, &begp))
	      {
		o = op;
		p = begp;
		break;
	      }

	    /* Is there a variable reference inside the parens or braces?
	       If so, expand it before expanding the entire reference.  */

	    end = strchr (beg, closeparen);
	    if (end == 0)
              /* Unterminated variable reference.  */
              fatal (*expanding_var, _("unterminated variable reference"));
	    p1 = lindex (beg, end, '$');
	    if (p1 != 0)
	      {
		/* BEG now points past the opening paren or brace.
		   Count parens or braces until it is matched.  */
		int count = 0;
		for (p = beg; *p != '\0'; ++p)
		  {
		    if (*p == openparen)
		      ++count;
		    else if (*p == closeparen && --count < 0)
		      break;
		  }
		/* If COUNT is >= 0, there were unmatched opening parens
		   or braces, so we go to the simple case of a variable name
		   such as `$($(a)'.  */
		if (count < 0)
		  {
		    abeg = expand_argument (beg, p); /* Expand the name.  */
		    beg = abeg;
		    end = strchr (beg, '\0');
		  }
	      }
	    else
	      /* Advance P to the end of this reference.  After we are
                 finished expanding this one, P will be incremented to
                 continue the scan.  */
	      p = end;

	    /* This is not a reference to a built-in function and
	       any variable references inside are now expanded.
	       Is the resultant text a substitution reference?  */

	    colon = lindex (beg, end, ':');
	    if (colon)
	      {
		/* This looks like a substitution reference: $(FOO:A=B).  */
		const char *subst_beg, *subst_end, *replace_beg, *replace_end;

		subst_beg = colon + 1;
		subst_end = lindex (subst_beg, end, '=');
		if (subst_end == 0)
		  /* There is no = in sight.  Punt on the substitution
		     reference and treat this as a variable name containing
		     a colon, in the code below.  */
		  colon = 0;
		else
		  {
		    replace_beg = subst_end + 1;
		    replace_end = end;

		    /* Extract the variable name before the colon
		       and look up that variable.  */
		    v = lookup_variable (beg, colon - beg);
		    if (v == 0)
		      warn_undefined (beg, colon - beg);

                    /* If the variable is not empty, perform the
                       substitution.  */
		    if (v != 0 && *v->value != '\0')
		      {
			char *pattern, *replace, *ppercent, *rpercent;
			char *value = (v->recursive
                                       ? recursively_expand (v)
				       : v->value);

                        /* Copy the pattern and the replacement.  Add in an
                           extra % at the beginning to use in case there
                           isn't one in the pattern.  */
                        pattern = alloca (subst_end - subst_beg + 2);
                        *(pattern++) = '%';
                        memcpy (pattern, subst_beg, subst_end - subst_beg);
                        pattern[subst_end - subst_beg] = '\0';

                        replace = alloca (replace_end - replace_beg + 2);
                        *(replace++) = '%';
                        memcpy (replace, replace_beg,
                               replace_end - replace_beg);
                        replace[replace_end - replace_beg] = '\0';

                        /* Look for %.  Set the percent pointers properly
                           based on whether we find one or not.  */
			ppercent = find_percent (pattern);
			if (ppercent)
                          {
                            ++ppercent;
                            rpercent = find_percent (replace);
                            if (rpercent)
                              ++rpercent;
                          }
			else
                          {
                            ppercent = pattern;
                            rpercent = replace;
                            --pattern;
                            --replace;
                          }

                        o = patsubst_expand_pat (o, value, pattern, replace,
                                                 ppercent, rpercent);

			if (v->recursive)
			  free (value);
		      }
		  }
	      }

	    if (colon == 0)
	      /* This is an ordinary variable reference.
		 Look up the value of the variable.  */
		o = reference_variable (o, beg, end - beg);

	  if (abeg)
	    free (abeg);
	  }
	  break;

	case '\0':
	  break;

	default:
	  if (isblank ((unsigned char)p[-1]))
	    break;

	  /* A $ followed by a random char is a variable reference:
	     $a is equivalent to $(a).  */
          o = reference_variable (o, p, 1);

	  break;
	}

      if (*p == '\0')
	break;

      ++p;
    }

  if (abuf)
    free (abuf);

  variable_buffer_output (o, "", 1);
  return (variable_buffer + line_offset);
}
예제 #12
0
/*==============================================================================================================
 *
 *   NAME
 *	wake_builtin_date - Formats a date.
 *
 *   PROTOTYPE
 *	$(<date> [ format [, time] ] )
 *	$(<gmdate> [ format [, time] ] )
 *
 *   DESCRIPTION
 *	Formats a time value.
 *
 *   PARAMETERS
 *	format -
 *		A format string, that accepts the same specifiers than the PHP date() function.
 *		If not specified, the default format is 'Y-m-d H:i:s'.
 * 
 *	time -
 *		A time value. If not specified, the current Unix time is used.
 *
 *==============================================================================================================*/
static char *	__wake_builtin_date ( char *  output, char * format, time_t  time_value, int  is_localtime )
   {
	struct tm *	tm		=  ( is_localtime ) ?  localtime ( & time_value ) : gmtime ( & time_value ) ;
	char *		p		=  format ;
	int		ap_hour ;
	char		buffer [128] ;
	char *		buffer_p ;
	int		iso_year, iso_week ;
	int		iso_values_set	=  0,
			tz_set		=  0 ;


	tm -> tm_year		+=  1900 ;
	ap_hour			 =  ( tm -> tm_hour  %  12 ) ?  tm -> tm_hour % 12 : 12 ; 

	while  ( * p )
	   {
		buffer_p	=  NULL ;
		* buffer	=  0 ;

		switch ( * p )
		   {
			// 'a' : lowercase "am" or "pm"
			case	'a' :
				buffer_p	=  ( tm -> tm_hour  >=  12 ) ?  "pm" : "am" ;
				break ;

			// 'A' : uppercase "AM" or "PM"
			case	'A' :
				buffer_p	=  ( tm -> tm_hour  >=  12 ) ?  "PM" : "AM" ;
				break ;

			// 'B' : internet Swatch hour
			case	'B' :
			   {
				int	result		=
				   (
				      (
					 (
					    time_value -
						( time_value - 
						   (
						     ( time_value % 86400 ) + 3600
						    )
						 )
					  ) * 10
				       ) / 864
				    ) ;

				while  ( result  <  0 )
					result	+=  1000 ;

				result	%=  1000 ;
				sprintf ( buffer, "%03d", result ) ;
				break ;
			    }

			// 'c' : Full date, in ISO8601 format
			case	'c' :
				sprintf ( buffer, "%04d-%02d-%02dT%02d:%02d:%02d%s",
						tm -> tm_year, tm -> tm_mon + 1, tm -> tm_mday,
						tm -> tm_hour, tm -> tm_min, tm -> tm_sec,
						gmtoffset ( is_localtime, tm -> tm_gmtoff, 1 ) 
					 ) ;
				break ;

			// 'd' : day of month, as a two-digits number
			case	'd' : 
				sprintf ( buffer, "%02d", tm -> tm_mday ) ;
				break ;
			
			// 'D' : short day name
			case	'D' :
				buffer_p	=  short_day_names [ tm -> tm_wday ] ;
				break ;

			// 'e' : Timezone name
			case	'e' :
				if  ( ! tz_set )
					tzset ( ) ;

				buffer_p	=  tzname [0] ;
				break ;

			// 'F' : Long month name
			case	'F' :
				buffer_p	=  long_month_names [ tm -> tm_mon ] ;
				break ;

			// 'g' : Hour without leading zero (1..12)
			case	'g' :
				sprintf ( buffer, "%d", ap_hour ) ;
				break ;

			// 'G' : Hour without leading zero (0..23)
			case	'G' :
				sprintf ( buffer, "%d", tm -> tm_hour ) ;
				break ;
			
			// 'h' : Hour with leading zero (01..12)
			case	'h' :
				sprintf ( buffer, "%02d", ap_hour ) ;
				break ;

			// 'H' : Hour with leading zero (00..23)
			case	'H' :
				sprintf ( buffer, "%02d", tm -> tm_hour ) ;
				break ;
			
			// 'i' : Minute, with leading zero (00..59)
			case	'i' :
				sprintf ( buffer, "%02d", tm -> tm_min ) ;
				break ;

			// 'I' : 1 if daylight savings time is active, 0 otherwise
			case	'I' :
				sprintf ( buffer, "%d", tm -> tm_isdst ) ;
				break ;

			// 'j' : day of month, without the leading zero
			case	'j' : 
				sprintf ( buffer, "%d", tm -> tm_mday ) ;
				break ;

			// 'l' : Long day name
			case	'l' :
				buffer_p	=  long_day_names [ tm -> tm_wday ] ;
				break ;

			// 'L' : 1 is the year is leap, 0 otherwise
			case	'L' :
				sprintf ( buffer, "%d", IS_LEAP ( tm -> tm_year ) ) ;
				break ;

			// 'M' : short month name 
			case	'M' :
				buffer_p	=  short_month_names [ tm -> tm_mon ] ;
				break ;

			// 'm' : month of year, as a two-digits number
			case	'm' :
				sprintf ( buffer, "%02d", tm -> tm_mon + 1 ) ;
				break ;
			
			// 'n' : month of year, without the leading zero
			case	'n' :
				sprintf ( buffer, "%d", tm -> tm_mon + 1 ) ;
				break ;
			
			// 'N' : day of week, from 1 (monday) to 7 (sunday)
			case	'N' :
				sprintf ( buffer, "%d", ( tm -> tm_wday ) ?  tm -> tm_wday : 7 ) ;
				break ;

			// 'o' : ISO8601 year
			case	'o' :
				if  ( ! iso_values_set )
				   {
					isoweek_from_date ( tm -> tm_year, tm -> tm_mon, tm -> tm_mday, & iso_week, & iso_year ) ;
					iso_values_set	=  1 ;
				    }

				sprintf ( buffer, "%d", iso_year ) ;
				break ;

			// 'O' : GMT offset in ISO8601 format (+0200)
			case	'O' :
				buffer_p	=  gmtoffset ( is_localtime, tm -> tm_gmtoff, 0 ) ;
				break ;

			// 'P' : GMT offset in RFC822 format (+02:00)
			case	'P' :
				buffer_p	=  gmtoffset ( is_localtime, tm -> tm_gmtoff, 1 ) ;
				break ;

			// 'r' : RFC822 date
			case	'r' :
				sprintf ( buffer, "%3s %02d %3s %04d %02d:%02d:%02d %s", 
						short_day_names [ tm -> tm_wday ],
						tm -> tm_mday,
						short_month_names [ tm -> tm_mon ],
						tm -> tm_year,
						tm -> tm_hour, tm -> tm_min, tm -> tm_sec,
						gmtoffset ( is_localtime, tm -> tm_gmtoff, 0 ) 
					 ) ;
				break ;

			// 's' : Seconds, with leading zero (00..59)
			case	's' :
				sprintf ( buffer, "%02d", tm -> tm_sec ) ;
				break ;

			// 'S' : 2-letters english suffix for a day of month
			case	'S' :
				buffer_p	=  english_suffix ( tm -> tm_mday ) ;
				break ;

			// 't' : month length
			case	't' :
				sprintf ( buffer, "%d", MONTH_LENGTH ( tm -> tm_year, tm -> tm_mon ) ) ;
				break ;

			// 'T' : Timezone abbreviation
			case	'T' :
				if  ( ! tz_set )
					tzset ( ) ;

				buffer_p	=  tzname [1] ;
				break ;

			// 'u' : microsecond time. Always return '000000' since we accept an integer value as time
			case	'u' :
				buffer_p	=  "000000" ;
				break ;

			// 'U' : Unix time
			case	'U' :
				sprintf ( buffer, "%d", ( int ) time_value ) ;
				break ;

			// 'w' : day of week, from 0 (sunday) to 6 (saturday)
			case	'w' :
				sprintf ( buffer, "%d", tm -> tm_wday ) ;
				break ;

			// 'W' : ISO8601 week number (were weeks start on monday)
			case	'W' :
				if  ( ! iso_values_set )
				   {
					isoweek_from_date ( tm -> tm_year, tm -> tm_mon, tm -> tm_mday, & iso_week, & iso_year ) ;
					iso_values_set	=  1 ;
				    }

				sprintf ( buffer, "%d", iso_week ) ;
				break ;

			// 'y' : 2-digits year
			case	'y' :
				sprintf ( buffer, "%02d", ( tm -> tm_year % 100 ) ) ;
				break ;

			// 'Y' : 4-digits year
			case	'Y' :
				sprintf ( buffer, "%04d", tm -> tm_year ) ;
				break ;

			// 'z' : day of year, from 0 to 365
			case	'z' :
				sprintf ( buffer, "%d", tm -> tm_yday ) ;
				break ;

			// 'Z' : GMT offset in seconds
			case	'Z' :
				sprintf ( buffer, "%d", ( int ) tm -> tm_gmtoff ) ;
				break ;

			// Escape character : copy the next one without interpretation unless this is the last one
			case	'\\' :
				if  ( * ( p + 1 ) )
					p ++ ;
				/* Intentionally fall through the default case */

			// Other characters : copy as is
			default :
				buffer [0]	=  * p ;
				buffer [1]	=  0 ;
				break ;
		    }

		if  ( buffer_p  ==  NULL )
			buffer_p	=  buffer ;

		output	=  variable_buffer_output ( output, buffer_p, strlen ( buffer_p ) ) ;
		p ++ ;	
	    }	

	return ( output ) ;
    }
예제 #13
0
파일: remake.c 프로젝트: mturk/gnumake
static const char *
library_search (const char *lib, FILE_TIMESTAMP *mtime_ptr)
{
  static char *dirs[] =
    {
#ifndef _AMIGA
      "/lib",
      "/usr/lib",
#endif
#if defined(WINDOWS32) && !defined(LIBDIR)
/*
 * This is completely up to the user at product install time. Just define
 * a placeholder.
 */
#define LIBDIR "."
#endif
      LIBDIR,			/* Defined by configuration.  */
      0
    };

  const char *file = 0;
  char *libpatterns;
  FILE_TIMESTAMP mtime;

  /* Loop variables for the libpatterns value.  */
  char *p;
  const char *p2;
  unsigned int len;
  unsigned int liblen;

  /* Information about the earliest (in the vpath sequence) match.  */
  unsigned int best_vpath = 0, best_path = 0;

  char **dp;

  libpatterns = xstrdup (variable_expand ("$(.LIBPATTERNS)"));

  /* Skip the '-l'.  */
  lib += 2;
  liblen = strlen (lib);

  /* Loop through all the patterns in .LIBPATTERNS, and search on each one.
     To implement the linker-compatible behavior we have to search through
     all entries in .LIBPATTERNS and choose the "earliest" one.  */
  p2 = libpatterns;
  while ((p = find_next_token (&p2, &len)) != 0)
    {
      static char *buf = NULL;
      static unsigned int buflen = 0;
      static int libdir_maxlen = -1;
      static unsigned int std_dirs = 0;
      char *libbuf = variable_expand ("");

      /* Expand the pattern using LIB as a replacement.  */
      {
	char c = p[len];
	char *p3, *p4;

	p[len] = '\0';
	p3 = find_percent (p);
	if (!p3)
	  {
	    /* Give a warning if there is no pattern.  */
	    error (NILF, _(".LIBPATTERNS element '%s' is not a pattern"), p);
            p[len] = c;
	    continue;
	  }
	p4 = variable_buffer_output (libbuf, p, p3-p);
	p4 = variable_buffer_output (p4, lib, liblen);
	p4 = variable_buffer_output (p4, p3+1, len - (p3-p));
	p[len] = c;
      }

      /* Look first for 'libNAME.a' in the current directory.  */
      mtime = name_mtime (libbuf);
      if (mtime != NONEXISTENT_MTIME)
	{
	  if (mtime_ptr != 0)
	    *mtime_ptr = mtime;
	  file = strcache_add (libbuf);
          /* This by definition will have the best index, so stop now.  */
          break;
	}

      /* Now try VPATH search on that.  */

      {
        unsigned int vpath_index, path_index;
        const char* f = vpath_search (libbuf, mtime_ptr ? &mtime : NULL,
                                      &vpath_index, &path_index);
        if (f)
          {
            /* If we have a better match, record it.  */
            if (file == 0 ||
                vpath_index < best_vpath ||
                (vpath_index == best_vpath && path_index < best_path))
              {
                file = f;
                best_vpath = vpath_index;
                best_path = path_index;

                if (mtime_ptr != 0)
                  *mtime_ptr = mtime;
              }
          }
      }

      /* Now try the standard set of directories.  */

      if (!buflen)
        {
          for (dp = dirs; *dp != 0; ++dp)
            {
              int l = strlen (*dp);
              if (l > libdir_maxlen)
                libdir_maxlen = l;
              std_dirs++;
            }
          buflen = strlen (libbuf);
          buf = xmalloc(libdir_maxlen + buflen + 2);
        }
      else if (buflen < strlen (libbuf))
        {
          buflen = strlen (libbuf);
          buf = xrealloc (buf, libdir_maxlen + buflen + 2);
        }

      {
        /* Use the last std_dirs index for standard directories. This
           was it will always be greater than the VPATH index.  */
        unsigned int vpath_index = ~((unsigned int)0) - std_dirs;

        for (dp = dirs; *dp != 0; ++dp)
	  {
            sprintf (buf, "%s/%s", *dp, libbuf);
            mtime = name_mtime (buf);
            if (mtime != NONEXISTENT_MTIME)
	      {
                if (file == 0 || vpath_index < best_vpath)
                  {
                    file = strcache_add (buf);
                    best_vpath = vpath_index;

                    if (mtime_ptr != 0)
                      *mtime_ptr = mtime;
                  }
              }

            vpath_index++;
          }
      }

    }

  free (libpatterns);
  return file;
}
예제 #14
0
파일: expand.c 프로젝트: dezelin/kBuild
/* Scan STRING for variable references and expansion-function calls.  Only
   LENGTH bytes of STRING are actually scanned.  If LENGTH is -1, scan until
   a null byte is found.

   Write the results to LINE, which must point into `variable_buffer'.  If
   LINE is NULL, start at the beginning of the buffer.
   Return a pointer to LINE, or to the beginning of the buffer if LINE is
   NULL. Set EOLP to point to the string terminator.
 */
char *
variable_expand_string_2 (char *line, const char *string, long length, char **eolp)
{
  struct variable *v;
  const char *p, *p1, *eos;
  char *o;
  unsigned int line_offset;

  if (!line)
    line = initialize_variable_output();
  o = line;
  line_offset = line - variable_buffer;

  if (length < 0)
    length = strlen (string);
  else
    MY_ASSERT_MSG (string + length == (p1 = memchr (string, '\0', length)) || !p1, ("len=%ld p1=%p %s\n", length, p1, line));

  /* Simple 1: Emptry string. */

  if (length == 0)
    {
      o = variable_buffer_output (o, "\0", 2);
      *eolp = o - 2;
      return (variable_buffer + line_offset);
    }

  /* Simple 2: Nothing to expand. ~50% if the kBuild calls. */

  p1 = (const char *)memchr (string, '$', length);
  if (p1 == 0)
    {
      o = variable_buffer_output (o, string, length);
      o = variable_buffer_output (o, "\0", 2);
      *eolp = o - 2;
      assert (strchr (variable_buffer + line_offset, '\0') == *eolp);
      return (variable_buffer + line_offset);
    }

  p = string;
  eos = p + length;

  while (1)
    {
      /* Copy all following uninteresting chars all at once to the
         variable output buffer, and skip them.  Uninteresting chars end
	 at the next $ or the end of the input.  */

      o = variable_buffer_output (o, p, p1 != 0 ? (p1 - p) : (eos - p));

      if (p1 == 0)
	break;
      p = p1 + 1;

      /* Dispatch on the char that follows the $.  */

      switch (*p)
	{
	case '$':
	  /* $$ seen means output one $ to the variable output buffer.  */
	  o = variable_buffer_output (o, p, 1);
	  break;

	case '(':
	case '{':
	  /* $(...) or ${...} is the general case of substitution.  */
	  {
	    char openparen = *p;
	    char closeparen = (openparen == '(') ? ')' : '}';
            const char *begp;
	    const char *beg = p + 1;
	    char *op;
            char *abeg = NULL;
            unsigned int alen = 0;
	    const char *end, *colon;

	    op = o;
	    begp = p;
            end = may_be_function_name (p + 1, eos);
	    if (    end
                &&  handle_function (&op, &begp, end, eos))
	      {
		o = op;
		p = begp;
                MY_ASSERT_MSG (!(p1 = memchr (variable_buffer + line_offset, '\0', o - (variable_buffer + line_offset))),
                               ("line=%p o/exp_end=%p act_end=%p\n", variable_buffer + line_offset, o, p1));
		break;
	      }

	    /* Is there a variable reference inside the parens or braces?
	       If so, expand it before expanding the entire reference.  */

	    end = memchr (beg, closeparen, eos - beg);
	    if (end == 0)
              /* Unterminated variable reference.  */
              fatal (*expanding_var, _("unterminated variable reference"));
	    p1 = lindex (beg, end, '$');
	    if (p1 != 0)
	      {
		/* BEG now points past the opening paren or brace.
		   Count parens or braces until it is matched.  */
		int count = 0;
		for (p = beg; p < eos; ++p)
		  {
		    if (*p == openparen)
		      ++count;
		    else if (*p == closeparen && --count < 0)
		      break;
		  }
		/* If COUNT is >= 0, there were unmatched opening parens
		   or braces, so we go to the simple case of a variable name
		   such as `$($(a)'.  */
		if (count < 0)
		  {
                    unsigned int len;
                    char saved;

                     /* Expand the name.  */
                    saved = *p;
                    *(char *)p = '\0'; /* XXX: proove that this is safe! XXX2: shouldn't be necessary any longer! */
                    abeg = allocated_variable_expand_3 (beg, p - beg, &len, &alen);
                    beg = abeg;
                    end = beg + len;
                    *(char *)p = saved;
		  }
	      }
	    else
	      /* Advance P to the end of this reference.  After we are
                 finished expanding this one, P will be incremented to
                 continue the scan.  */
	      p = end;

	    /* This is not a reference to a built-in function and
	       any variable references inside are now expanded.
	       Is the resultant text a substitution reference?  */

	    colon = lindex (beg, end, ':');
	    if (colon)
	      {
		/* This looks like a substitution reference: $(FOO:A=B).  */
		const char *subst_beg, *subst_end, *replace_beg, *replace_end;

		subst_beg = colon + 1;
		subst_end = lindex (subst_beg, end, '=');
		if (subst_end == 0)
		  /* There is no = in sight.  Punt on the substitution
		     reference and treat this as a variable name containing
		     a colon, in the code below.  */
		  colon = 0;
		else
		  {
		    replace_beg = subst_end + 1;
		    replace_end = end;

		    /* Extract the variable name before the colon
		       and look up that variable.  */
		    v = lookup_variable (beg, colon - beg);
		    if (v == 0)
		      warn_undefined (beg, colon - beg);

                    /* If the variable is not empty, perform the
                       substitution.  */
		    if (v != 0 && *v->value != '\0')
		      {
			char *pattern, *replace, *ppercent, *rpercent;
			char *value = (v->recursive
                                       ? recursively_expand (v)
				       : v->value);

                        /* Copy the pattern and the replacement.  Add in an
                           extra % at the beginning to use in case there
                           isn't one in the pattern.  */
                        pattern = alloca (subst_end - subst_beg + 2);
                        *(pattern++) = '%';
                        memcpy (pattern, subst_beg, subst_end - subst_beg);
                        pattern[subst_end - subst_beg] = '\0';

                        replace = alloca (replace_end - replace_beg + 2);
                        *(replace++) = '%';
                        memcpy (replace, replace_beg,
                               replace_end - replace_beg);
                        replace[replace_end - replace_beg] = '\0';

                        /* Look for %.  Set the percent pointers properly
                           based on whether we find one or not.  */
			ppercent = find_percent (pattern);
			if (ppercent)
                          {
                            ++ppercent;
                            rpercent = find_percent (replace);
                            if (rpercent)
                              ++rpercent;
                          }
			else
                          {
                            ppercent = pattern;
                            rpercent = replace;
                            --pattern;
                            --replace;
                          }

                        o = patsubst_expand_pat (o, value, pattern, replace,
                                                 ppercent, rpercent);

			if (v->recursive)
			  free (value);
		      }
		  }
	      }

	    if (colon == 0)
	      /* This is an ordinary variable reference.
		 Look up the value of the variable.  */
		o = reference_variable (o, beg, end - beg);

	  if (abeg)
            recycle_variable_buffer (abeg, alen);
	  }
	  break;

	case '\0':
          assert (p == eos);
          break;

	default:
	  if (isblank ((unsigned char)p[-1])) /* XXX: This looks incorrect, previous is '$' */
	    break;

	  /* A $ followed by a random char is a variable reference:
	     $a is equivalent to $(a).  */
          o = reference_variable (o, p, 1);

	  break;
	}

      if (++p >= eos)
	break;
      p1 = memchr (p, '$', eos - p);
    }

  o = variable_buffer_output (o, "\0", 2); /* KMK: compensate for the strlen + 1 that was removed above. */
  *eolp = o - 2;
  MY_ASSERT_MSG (strchr (variable_buffer + line_offset, '\0') == *eolp,
                 ("expected=%d actual=%d\nlength=%ld string=%.*s\n",
                  (int)(*eolp - variable_buffer + line_offset), (int)strlen(variable_buffer + line_offset),
                  length, (int)length, string));
  return (variable_buffer + line_offset);
}