⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 function.c

📁 DSP网络驱动开发_TMS3206
💻 C
📖 第 1 页 / 共 3 页
字号:
/* Builtin function expansion for GNU Make.Copyright (C) 1988,89,91,92,93,94,95,96,97 Free Software Foundation, Inc.This file is part of GNU Make.GNU Make is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2, or (at your option)any later version.GNU Make is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with GNU Make; see the file COPYING.  If not, write tothe Free Software Foundation, Inc., 59 Temple Place - Suite 330,Boston, MA 02111-1307, USA.  */#include "make.h"#include "filedef.h"#include "variable.h"#include "dep.h"#include "job.h"#include "commands.h"#ifdef _AMIGA#include "amiga.h"#endifstruct function_table_entry  {    const char *name;    int len;    int required_args;    int expand_args;    char *(*func_ptr) PARAMS((char *output, char **argv, const char*funcname));  };/* Store into VARIABLE_BUFFER at O the result of scanning TEXT and replacing   each occurrence of SUBST with REPLACE. TEXT is null-terminated.  SLEN is   the length of SUBST and RLEN is the length of REPLACE.  If BY_WORD is   nonzero, substitutions are done only on matches which are complete   whitespace-delimited words.  If SUFFIX_ONLY is nonzero, substitutions are   done only at the ends of whitespace-delimited words.  */char *subst_expand (o, text, subst, replace, slen, rlen, by_word, suffix_only)     char *o;     char *text;     char *subst, *replace;     unsigned int slen, rlen;     int by_word, suffix_only;{  register char *t = text;  register char *p;  if (slen == 0 && !by_word && !suffix_only)    {      /* The first occurrence of "" in any string is its end.  */      o = variable_buffer_output (o, t, strlen (t));      if (rlen > 0)	o = variable_buffer_output (o, replace, rlen);      return o;    }  do    {      if ((by_word | suffix_only) && slen == 0)	/* When matching by words, the empty string should match	   the end of each word, rather than the end of the whole text.  */	p = end_of_token (next_token (t));      else	{	  p = sindex (t, 0, subst, slen);	  if (p == 0)	    {	      /* No more matches.  Output everything left on the end.  */	      o = variable_buffer_output (o, t, strlen (t));	      return o;	    }	}      /* Output everything before this occurrence of the string to replace.  */      if (p > t)	o = variable_buffer_output (o, t, p - t);      /* If we're substituting only by fully matched words,	 or only at the ends of words, check that this case qualifies.  */      if ((by_word	   && ((p > t && !isblank (p[-1]))	       || (p[slen] != '\0' && !isblank (p[slen]))))	  || (suffix_only	      && (p[slen] != '\0' && !isblank (p[slen]))))	/* Struck out.  Output the rest of the string that is	   no longer to be replaced.  */	o = variable_buffer_output (o, subst, slen);      else if (rlen > 0)	/* Output the replacement string.  */	o = variable_buffer_output (o, replace, rlen);      /* Advance T past the string to be replaced.  */      t = p + slen;    } while (*t != '\0');  return o;}/* Store into VARIABLE_BUFFER at O the result of scanning TEXT   and replacing strings matching PATTERN with REPLACE.   If PATTERN_PERCENT is not nil, PATTERN has already been   run through find_percent, and PATTERN_PERCENT is the result.   If REPLACE_PERCENT is not nil, REPLACE has already been   run through find_percent, and REPLACE_PERCENT is the result.  */char *patsubst_expand (o, text, pattern, replace, pattern_percent, replace_percent)     char *o;     char *text;     register char *pattern, *replace;     register char *pattern_percent, *replace_percent;{  unsigned int pattern_prepercent_len, pattern_postpercent_len;  unsigned int replace_prepercent_len, replace_postpercent_len = 0;  char *t;  unsigned int len;  int doneany = 0;  /* We call find_percent on REPLACE before checking PATTERN so that REPLACE     will be collapsed before we call subst_expand if PATTERN has no %.  */  if (replace_percent == 0)    replace_percent = find_percent (replace);  if (replace_percent != 0)    {      /* Record the length of REPLACE before and after the % so	 we don't have to compute these lengths more than once.  */      replace_prepercent_len = replace_percent - replace;      replace_postpercent_len = strlen (replace_percent + 1);    }  else    /* We store the length of the replacement       so we only need to compute it once.  */    replace_prepercent_len = strlen (replace);  if (pattern_percent == 0)    pattern_percent = find_percent (pattern);  if (pattern_percent == 0)    /* With no % in the pattern, this is just a simple substitution.  */    return subst_expand (o, text, pattern, replace,			 strlen (pattern), strlen (replace), 1, 0);  /* Record the length of PATTERN before and after the %     so we don't have to compute it more than once.  */  pattern_prepercent_len = pattern_percent - pattern;  pattern_postpercent_len = strlen (pattern_percent + 1);  while ((t = find_next_token (&text, &len)) != 0)    {      int fail = 0;      /* Is it big enough to match?  */      if (len < pattern_prepercent_len + pattern_postpercent_len)	fail = 1;      /* Does the prefix match? */      if (!fail && pattern_prepercent_len > 0	  && (*t != *pattern	      || t[pattern_prepercent_len - 1] != pattern_percent[-1]	      || !strneq (t + 1, pattern + 1, pattern_prepercent_len - 1)))	fail = 1;      /* Does the suffix match? */      if (!fail && pattern_postpercent_len > 0	  && (t[len - 1] != pattern_percent[pattern_postpercent_len]	      || t[len - pattern_postpercent_len] != pattern_percent[1]	      || !strneq (&t[len - pattern_postpercent_len],			  &pattern_percent[1], pattern_postpercent_len - 1)))	fail = 1;      if (fail)	/* It didn't match.  Output the string.  */	o = variable_buffer_output (o, t, len);      else	{	  /* It matched.  Output the replacement.  */	  /* Output the part of the replacement before the %.  */	  o = variable_buffer_output (o, replace, replace_prepercent_len);	  if (replace_percent != 0)	    {	      /* Output the part of the matched string that		 matched the % in the pattern.  */	      o = variable_buffer_output (o, t + pattern_prepercent_len,					  len - (pattern_prepercent_len						 + pattern_postpercent_len));	      /* Output the part of the replacement after the %.  */	      o = variable_buffer_output (o, replace_percent + 1,					  replace_postpercent_len);	    }	}      /* Output a space, but not if the replacement is "".  */      if (fail || replace_prepercent_len > 0	  || (replace_percent != 0 && len + replace_postpercent_len > 0))	{	  o = variable_buffer_output (o, " ", 1);	  doneany = 1;	}    }  if (doneany)    /* Kill the last space.  */    --o;  return o;}/* Look up a function by name.   The table is currently small enough that it's not really worthwhile to use   a fancier lookup algorithm.  If it gets larger, maybe...*/static const struct function_table_entry *lookup_function (table, s)     const struct function_table_entry *table;     const char *s;{  int len = strlen(s);  for (; table->name != NULL; ++table)    if (table->len <= len        && (isblank (s[table->len]) || s[table->len] == '\0')        && strneq (s, table->name, table->len))      return table;  return NULL;}/* Return 1 if PATTERN matches STR, 0 if not.  */intpattern_matches (pattern, percent, str)     register char *pattern, *percent, *str;{  unsigned int sfxlen, strlength;  if (percent == 0)    {      unsigned int len = strlen (pattern) + 1;      char *new_chars = (char *) alloca (len);      bcopy (pattern, new_chars, len);      pattern = new_chars;      percent = find_percent (pattern);      if (percent == 0)	return streq (pattern, str);    }  sfxlen = strlen (percent + 1);  strlength = strlen (str);  if (strlength < (percent - pattern) + sfxlen      || !strneq (pattern, str, percent - pattern))    return 0;  return !strcmp (percent + 1, str + (strlength - sfxlen));}/* Find the next comma or ENDPAREN (counting nested STARTPAREN and   ENDPARENtheses), starting at PTR before END.  Return a pointer to   next character.   If no next argument is found, return NULL.*/static char *find_next_argument (startparen, endparen, ptr, end)     char startparen;     char endparen;     const char *ptr;     const char *end;{  int count = 0;  for (; ptr < end; ++ptr)    if (*ptr == startparen)      ++count;    else if (*ptr == endparen)      {	--count;	if (count < 0)	  return NULL;      }    else if (*ptr == ',' && !count)      return (char *)ptr;  /* We didn't find anything.  */  return NULL;}/* Glob-expand LINE.  The returned pointer is   only good until the next call to string_glob.  */static char *string_glob (line)     char *line;{  static char *result = 0;  static unsigned int length;  register struct nameseq *chain;  register unsigned int idx;  chain = multi_glob (parse_file_seq		      (&line, '\0', sizeof (struct nameseq),		       /* We do not want parse_file_seq to strip `./'s.			  That would break examples like:			  $(patsubst ./%.c,obj/%.o,$(wildcard ./?*.c)).  */		       0),		      sizeof (struct nameseq));  if (result == 0)    {      length = 100;      result = (char *) xmalloc (100);    }  idx = 0;  while (chain != 0)    {      register char *name = chain->name;      unsigned int len = strlen (name);      struct nameseq *next = chain->next;      free ((char *) chain);      chain = next;      /* multi_glob will pass names without globbing metacharacters	 through as is, but we want only files that actually exist.  */      if (file_exists_p (name))	{	  if (idx + len + 1 > length)	    {	      length += (len + 1) * 2;	      result = (char *) xrealloc (result, length);	    }	  bcopy (name, &result[idx], len);	  idx += len;	  result[idx++] = ' ';	}      free (name);    }  /* Kill the last space and terminate the string.  */  if (idx == 0)    result[0] = '\0';  else    result[idx - 1] = '\0';  return result;}/*  Builtin functions */static char *func_patsubst (o, argv, funcname)     char *o;     char **argv;     const char *funcname;{  o = patsubst_expand (o, argv[2], argv[0], argv[1], (char *) 0, (char *) 0);  return o;}static char *func_join(o, argv, funcname)     char *o;     char **argv;     const char *funcname;{  int doneany = 0;  /* Write each word of the first argument directly followed     by the corresponding word of the second argument.     If the two arguments have a different number of words,     the excess words are just output separated by blanks.  */  register char *tp;  register char *pp;  char *list1_iterator = argv[0];  char *list2_iterator = argv[1];  do    {      unsigned int len1, len2;      tp = find_next_token (&list1_iterator, &len1);      if (tp != 0)	o = variable_buffer_output (o, tp, len1);      pp = find_next_token (&list2_iterator, &len2);      if (pp != 0)	o = variable_buffer_output (o, pp, len2);      if (tp != 0 || pp != 0)	{	  o = variable_buffer_output (o, " ", 1);	  doneany = 1;	}    }  while (tp != 0 || pp != 0);  if (doneany)    /* Kill the last blank.  */    --o;  return o;}static char *func_origin(o, argv, funcname)     char *o;     char **argv;     const char *funcname;{  /* Expand the argument.  */  register struct variable *v = lookup_variable (argv[0], strlen (argv[0]));  if (v == 0)    o = variable_buffer_output (o, "undefined", 9);  else    switch (v->origin)      {      default:      case o_invalid:	abort ();	break;      case o_default:	o = variable_buffer_output (o, "default", 7);	break;      case o_env:	o = variable_buffer_output (o, "environment", 11);	break;      case o_file:	o = variable_buffer_output (o, "file", 4);	break;      case o_env_override:	o = variable_buffer_output (o, "environment override", 20);	break;      case o_command:	o = variable_buffer_output (o, "command line", 12);	break;      case o_override:	o = variable_buffer_output (o, "override", 8);	break;      case o_automatic:	o = variable_buffer_output (o, "automatic", 9);	break;      }  return o;}#ifdef VMS#define IS_PATHSEP(c) ((c) == ']')#else#if defined(__MSDOS__) || defined(WINDOWS32)#define IS_PATHSEP(c) ((c) == '/' || (c) == '\\')#else#define IS_PATHSEP(c) ((c) == '/')#endif#endifstatic char *func_notdir_suffix(o, argv, funcname)     char *o;     char **argv;     const char *funcname;{  /* Expand the argument.  */  char *list_iterator = argv[0];  char *p2 =0;  int doneany =0;  int len=0;  int is_suffix = streq(funcname, "suffix");  int is_notdir = !is_suffix;  while ((p2 = find_next_token (&list_iterator, &len)) != 0)    {      char *p = p2 + len;      while (p >= p2 && (!is_suffix || *p != '.'))	{	  if (IS_PATHSEP (*p))	    break;	  --p;	}      if (p >= p2)	{	  if (is_notdir)	    ++p;	  else if (*p != '.')	    continue;	  o = variable_buffer_output (o, p, len - (p - p2));	}#if defined(WINDOWS32) || defined(__MSDOS__)      /* Handle the case of "d:foo/bar".  */      else if (streq(funcname, "notdir") && p2[0] && p2[1] == ':')	{	  p = p2 + 2;	  o = variable_buffer_output (o, p, len - (p - p2));	}#endif      else if (is_notdir)	o = variable_buffer_output (o, p2, len);      if (is_notdir || p >= p2)	{	  o = variable_buffer_output (o, " ", 1);	  doneany = 1;	}    }  if (doneany)    /* Kill last space.  */    --o;  return o;}static char *func_basename_dir(o, argv, funcname)     char *o;     char **argv;     const char *funcname;{  /* Expand the argument.  */  char *p3 = argv[0];  char *p2=0;  int doneany=0;  int len=0;  char *p=0;  int is_basename= streq(funcname, "basename");  int is_dir= !is_basename;  while ((p2 = find_next_token (&p3, &len)) != 0)	{	  p = p2 + len;	  while (p >= p2 && (!is_basename  || *p != '.'))	    {	      if (IS_PATHSEP(*p))		break;	      	    --p;	    }	  if (p >= p2 && (is_dir))	    o = variable_buffer_output (o, p2, ++p - p2);	  else if (p >= p2 && (*p == '.'))	    o = variable_buffer_output (o, p2, p - p2);#if defined(WINDOWS32) || defined(__MSDOS__)	/* Handle the "d:foobar" case */	  else if (p2[0] && p2[1] == ':' && is_dir)	    o = variable_buffer_output (o, p2, 2);#endif	  else if (is_dir)#ifdef VMS	    o = variable_buffer_output (o, "[]", 2);#else#ifndef _AMIGA	    o = variable_buffer_output (o, "./", 2);#else	    ; /* Just a nop...  */#endif /* AMIGA */#endif /* !VMS */	  else	    /* The entire name is the basename.  */	    o = variable_buffer_output (o, p2, len);	  o = variable_buffer_output (o, " ", 1);	  doneany = 1;	}      if (doneany)	/* Kill last space.  */	--o; return o;}static char *func_addsuffix_addprefix(o, argv, funcname)     char *o;     char **argv;     const char *funcname;{  int fixlen = strlen (argv[0]);  char *list_iterator = argv[1];  int is_addprefix = streq (funcname, "addprefix");  int is_addsuffix = !is_addprefix;  int doneany =0;  char *p=0;  int len =0;  while ((p = find_next_token (&list_iterator, &len)) != 0)    {      if (is_addprefix)	o = variable_buffer_output (o, argv[0], fixlen);      o = variable_buffer_output (o, p, len);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -