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

📄 function.c

📁 DSP网络驱动开发_TMS3206
💻 C
📖 第 1 页 / 共 3 页
字号:
  /* make sure that CreateProcess() has Path it needs */  sync_Path_environment();  if (!process_begin(hProcess, command_argv, envp, command_argv[0], NULL))    *pid_p = (int) hProcess;  else    fatal (NILF, _("windows32_openpipe (): unable to launch process (e=%d)\n"),	   process_last_err(hProcess));  /* set up to read data from child */  pipedes[0] = _open_osfhandle((long) hChildOutRd, O_RDONLY);  /* this will be closed almost right away */  pipedes[1] = _open_osfhandle((long) hChildOutWr, O_APPEND);}#endif#ifdef __MSDOS__FILE *msdos_openpipe (int* pipedes, int *pidp, char *text){  FILE *fpipe=0;  /* MSDOS can't fork, but it has `popen'.  */  struct variable *sh = lookup_variable ("SHELL", 5);  int e;  extern int dos_command_running, dos_status;  /* Make sure not to bother processing an empty line.  */  while (isblank (*text))    ++text;  if (*text == '\0')    return 0;  if (sh)    {      char buf[PATH_MAX + 7];      /* This makes sure $SHELL value is used by $(shell), even	 though the target environment is not passed to it.  */      sprintf (buf, "SHELL=%s", sh->value);      putenv (buf);    }  e = errno;  errno = 0;  dos_command_running = 1;  dos_status = 0;  /* If dos_status becomes non-zero, it means the child process     was interrupted by a signal, like SIGINT or SIGQUIT.  See     fatal_error_signal in commands.c.  */  fpipe = popen (text, "rt");  dos_command_running = 0;  if (!fpipe || dos_status)    {      pipedes[0] = -1;      *pidp = -1;      if (dos_status)	errno = EINTR;      else if (errno == 0)	errno = ENOMEM;      shell_function_completed = -1;    }  else    {      pipedes[0] = fileno (fpipe);      *pidp = 42; /* Yes, the Meaning of Life, the Universe, and Everything! */      errno = e;      shell_function_completed = 1;    }  return fpipe;}#endif/*  Do shell spawning, with the naughty bits for different OSes. */#ifdef VMS/* VMS can't do $(shell ...)  */#define func_shell 0#else#ifndef _AMIGAstatic char *func_shell (o, argv, funcname)     char *o;     char **argv;     const char *funcname;{  char* batch_filename = NULL;  int i;#ifdef __MSDOS__  FILE *fpipe;#endif  char **command_argv;  char *error_prefix;  char **envp;  int pipedes[2];  int pid;#ifndef __MSDOS__  /* Construct the argument list.  */  command_argv = construct_command_argv (argv[0],					 (char **) NULL, (struct file *) 0,                                         &batch_filename);  if (command_argv == 0)    return o;#endif  /* Using a target environment for `shell' loses in cases like:     export var = $(shell echo foobie)     because target_environment hits a loop trying to expand $(var)     to put it in the environment.  This is even more confusing when     var was not explicitly exported, but just appeared in the     calling environment.  */  envp = environ;  /* For error messages.  */  if (reading_file != 0)    {      error_prefix = (char *) alloca (strlen(reading_file->filenm)+11+4);      sprintf (error_prefix,	       "%s:%lu: ", reading_file->filenm, reading_file->lineno);    }  else    error_prefix = "";#ifdef WINDOWS32  windows32_openpipe (pipedes, &pid, command_argv, envp);#else /* WINDOWS32 */# ifdef __MSDOS__  fpipe = msdos_openpipe (pipedes, &pid, argv[0]);  if (pipedes[0] < 0)    {      perror_with_name (error_prefix, "pipe");      return o;    }# else  if (pipe (pipedes) < 0)    {      perror_with_name (error_prefix, "pipe");      return o;    }  pid = vfork ();  if (pid < 0)    perror_with_name (error_prefix, "fork");  else if (pid == 0)    child_execute_job (0, pipedes[1], command_argv, envp);  else# endif /* ! __MSDOS__ */#endif /* WINDOWS32 */    {      /* We are the parent.  */      char *buffer;      unsigned int maxlen;      int cc;      /* Record the PID for reap_children.  */      shell_function_pid = pid;#ifndef  __MSDOS__      shell_function_completed = 0;      /* Free the storage only the child needed.  */      free (command_argv[0]);      free ((char *) command_argv);      /* Close the write side of the pipe.  */      (void) close (pipedes[1]);#endif      /* Set up and read from the pipe.  */      maxlen = 200;      buffer = (char *) xmalloc (maxlen + 1);      /* Read from the pipe until it gets EOF.  */      i = 0;      do	{	  if (i == maxlen)	    {	      maxlen += 512;	      buffer = (char *) xrealloc (buffer, maxlen + 1);	    }	  errno = 0;	  cc = read (pipedes[0], &buffer[i], maxlen - i);	  if (cc > 0)	    i += cc;	}      while (cc > 0 || EINTR_SET);      /* Close the read side of the pipe.  */#ifdef  __MSDOS__      if (fpipe)	(void) pclose (fpipe);#else      (void) close (pipedes[0]);#endif      /* Loop until child_handler sets shell_function_completed	 to the status of our child shell.  */      while (shell_function_completed == 0)	reap_children (1, 0);      if (batch_filename) {	if (debug_flag)	  printf(_("Cleaning up temporary batch file %s\n"), batch_filename);	remove(batch_filename);	free(batch_filename);      }      shell_function_pid = 0;      /* The child_handler function will set shell_function_completed	 to 1 when the child dies normally, or to -1 if it	 dies with status 127, which is most likely an exec fail.  */      if (shell_function_completed == -1)	{	  /* This most likely means that the execvp failed,	     so we should just write out the error message	     that came in over the pipe from the child.  */	  fputs (buffer, stderr);	  fflush (stderr);	}      else	{	  /* The child finished normally.  Replace all	     newlines in its output with spaces, and put	     that in the variable output buffer.  */	  fold_newlines (buffer, &i);	  o = variable_buffer_output (o, buffer, i);	}      free (buffer);    }  return o;}#else	/* _AMIGA *//* Do the Amiga version of func_shell.  */static char *func_shell (char *o, char **argv, const char *funcname){  /* Amiga can't fork nor spawn, but I can start a program with     redirection of my choice.  However, this means that we     don't have an opportunity to reopen stdout to trap it.  Thus,     we save our own stdout onto a new descriptor and dup a temp     file's descriptor onto our stdout temporarily.  After we     spawn the shell program, we dup our own stdout back to the     stdout descriptor.  The buffer reading is the same as above,     except that we're now reading from a file.  */#include <dos/dos.h>#include <proto/dos.h>  BPTR child_stdout;  char tmp_output[FILENAME_MAX];  unsigned int maxlen = 200;  int cc, i;  char * buffer, * ptr;  char ** aptr;  int len = 0;  char* batch_filename = NULL;  /* Construct the argument list.  */  command_argv = construct_command_argv (argv[0], (char **) NULL,                                         (struct file *) 0, &batch_filename);  if (command_argv == 0)    return o;  strcpy (tmp_output, "t:MakeshXXXXXXXX");  mktemp (tmp_output);  child_stdout = Open (tmp_output, MODE_NEWFILE);  for (aptr=command_argv; *aptr; aptr++)    len += strlen (*aptr) + 1;  buffer = xmalloc (len + 1);  ptr = buffer;  for (aptr=command_argv; *aptr; aptr++)    {      strcpy (ptr, *aptr);      ptr += strlen (ptr) + 1;      *ptr ++ = ' ';      *ptr = 0;    }  ptr[-1] = '\n';  Execute (buffer, NULL, child_stdout);  free (buffer);  Close (child_stdout);  child_stdout = Open (tmp_output, MODE_OLDFILE);  buffer = xmalloc (maxlen);  i = 0;  do    {      if (i == maxlen)	{	  maxlen += 512;	  buffer = (char *) xrealloc (buffer, maxlen + 1);	}      cc = Read (child_stdout, &buffer[i], maxlen - i);      if (cc > 0)	i += cc;    } while (cc > 0);  Close (child_stdout);  fold_newlines (buffer, &i);  o = variable_buffer_output (o, buffer, i);  free (buffer);  return o;}#endif  /* _AMIGA */#endif  /* !VMS */#ifdef EXPERIMENTAL/*  equality. Return is string-boolean, ie, the empty string is false. */static char *func_eq (char* o, char **argv, char *funcname){  int result = ! strcmp (argv[0], argv[1]);  o = variable_buffer_output (o,  result ? "1" : "", result);  return o;}/*  string-boolean not operator. */static char *func_not (char* o, char **argv, char *funcname){  char * s = argv[0];  int result = 0;  while (isspace (*s))    s++;  result = ! (*s);  o = variable_buffer_output (o,  result ? "1" : "", result);  return o;}#endif#define STRING_SIZE_TUPLE(_s) (_s), (sizeof(_s)-1)/* Lookup table for builtin functions.   This doesn't have to be sorted; we use a straight lookup.  We might gain   some efficiency by moving most often used functions to the start of the   table.   If REQUIRED_ARGS is positive, the function takes exactly that many   arguments.  All subsequent text is included with the last argument.  So,   since $(sort a,b,c) takes only one argument, it will be the full string   "a,b,c".  If the value is negative, it's the minimum number of arguments.   A function can have more, but if it has less an error is generated.   EXPAND_ARGS means that all arguments should be expanded before invocation.   Functions that do namespace tricks (foreach) don't automatically expand.  */static char *func_call PARAMS((char *o, char **argv, const char *funcname));static struct function_table_entry function_table[] ={ /* Name/size */                    /* ARG EXP? Function */  { STRING_SIZE_TUPLE("addprefix"),     2,  1,  func_addsuffix_addprefix},  { STRING_SIZE_TUPLE("addsuffix"),     2,  1,  func_addsuffix_addprefix},  { STRING_SIZE_TUPLE("basename"),      1,  1,  func_basename_dir},  { STRING_SIZE_TUPLE("dir"),           1,  1,  func_basename_dir},  { STRING_SIZE_TUPLE("notdir"),        1,  1,  func_notdir_suffix},  { STRING_SIZE_TUPLE("subst"),         3,  1,  func_subst},  { STRING_SIZE_TUPLE("suffix"),        1,  1,  func_notdir_suffix},  { STRING_SIZE_TUPLE("filter"),        2,  1,  func_filter_filterout},  { STRING_SIZE_TUPLE("filter-out"),    2,  1,  func_filter_filterout},  { STRING_SIZE_TUPLE("findstring"),    2,  1,  func_findstring},  { STRING_SIZE_TUPLE("firstword"),     1,  1,  func_firstword},  { STRING_SIZE_TUPLE("join"),          2,  1,  func_join},  { STRING_SIZE_TUPLE("patsubst"),      3,  1,  func_patsubst},  { STRING_SIZE_TUPLE("shell"),         1,  1,  func_shell},  { STRING_SIZE_TUPLE("sort"),          1,  1,  func_sort},  { STRING_SIZE_TUPLE("strip"),         1,  1,  func_strip},  { STRING_SIZE_TUPLE("wildcard"),      1,  1,  func_wildcard},  { STRING_SIZE_TUPLE("word"),          2,  1,  func_word},  { STRING_SIZE_TUPLE("wordlist"),      3,  1,  func_wordlist},  { STRING_SIZE_TUPLE("words"),         1,  1,  func_words},  { STRING_SIZE_TUPLE("origin"),        1,  1,  func_origin},  { STRING_SIZE_TUPLE("foreach"),       3,  0,  func_foreach},  { STRING_SIZE_TUPLE("call"),         -1,  1,  func_call},  { STRING_SIZE_TUPLE("error"),         1,  1,  func_error},  { STRING_SIZE_TUPLE("warning"),       1,  1,  func_error},  { STRING_SIZE_TUPLE("if"),           -2,  0,  func_if},#ifdef EXPERIMENTAL  { STRING_SIZE_TUPLE("eq"),            2,  1,  func_eq},  { STRING_SIZE_TUPLE("not"),           1,  1,  func_not},#endif  { 0 }};/* These must come after the definition of function_table[].  */static char *expand_builtin_function (o, argc, argv, entry_p)     char *o;     int argc;     char **argv;     struct function_table_entry *entry_p;{  int min = (entry_p->required_args > 0             ? entry_p->required_args             : -entry_p->required_args);  if (argc < min)    fatal (reading_file,           _("Insufficient number of arguments (%d) to function `%s'"),           argc, entry_p->name);  if (!entry_p->func_ptr)    fatal (reading_file, _("Unimplemented on this platform: function `%s'"),           entry_p->name);  return entry_p->func_ptr (o, argv, entry_p->name);}/* Check for a function invocation in *STRINGP.  *STRINGP points at the   opening ( or { and is not null-terminated.  If a function invocation   is found, expand it into the buffer at *OP, updating *OP, incrementing   *STRINGP past the reference and returning nonzero.  If not, return zero.  */inthandle_function (op, stringp)     char **op;     char **stringp;{  const struct function_table_entry *entry_p;  char openparen = (*stringp)[0];  char closeparen = openparen == '(' ? ')' : '}';  char *beg = *stringp + 1;  char *endref;  int count = 0;  char *argbeg;  register char *p;  char **argv, **argvp;  int nargs;  entry_p = lookup_function (function_table, beg);  if (!entry_p)    return 0;  /* We have found a call to a builtin function.  Find the end of the     arguments, and do the function.  */  endref = beg + entry_p->len;  /* Space after function name isn't part of the args.  */  p = next_token (endref);  argbeg = p;  /* Find the end of the function invocation, counting nested use of     whichever kind of parens we use.  Since we're looking, count commas     to get a rough estimate of how many arguments we might have.  The     count might be high, but it'll never be low.  */  for (nargs=1; *p != '\0'; ++p)    if (*p == ',')      ++nargs;    else if (*p == openparen)      ++count;    else if (*p == closeparen && --count < 0)      break;  if (count >= 0)    fatal (reading_file,	   _("unterminated call to function `%s': missing `%c'"),	   entry_p->name, closeparen);  /* Get some memory to store the arg pointers.  */  argvp = argv = (char **) alloca (sizeof(char *) * (nargs + 2));  /* Chop the string into arguments, then store the end pointer and a nul.     If REQUIRED_ARGS is positive, as soon as we hit that many assume the     rest of the string is part of the last argument.  */  *argvp = argbeg;  nargs = 1;  while (entry_p->required_args < 0 || nargs < entry_p->required_args)    {      char *next = find_next_argument (openparen, closeparen, *argvp, p);      if (!next)	break;      *(++argvp) = next+1;      ++nargs;    }  *(++argvp) = p+1;  *(++argvp) = 0;  /* If we should expand, do it.  */  if (entry_p->expand_args)    {      for (argvp=argv; argvp[1] != 0; ++argvp)	*argvp = expand_argument (*argvp, argvp[1]-1);      /* end pointer doesn't make sense for expanded stuff.  */      *argvp = 0;    }  /* Finally!  Run the function...  */  *op = expand_builtin_function (*op, nargs, argv, entry_p);  /* If we allocated memory for the expanded args, free it again.  */  if (entry_p->expand_args)    for (argvp=argv; *argvp != 0; ++argvp)      free (*argvp);  *stringp = p;  return 1;}/* User-defined functions.  Expand the first argument as either a builtin   function or a make variable, in the context of the rest of the arguments   assigned to $1, $2, ... $N.  $0 is the name of the function.  */static char *func_call (o, argv, funcname)     char *o;     char **argv;     const char *funcname;{  char *fname;  int flen;  char *body;  int i;  const struct function_table_entry *entry_p;  /* Calling nothing is a no-op.  */  if (*argv[0] == '\0')    return o;  /* There is no way to define a variable with a space in the name, so strip     trailing whitespace as a favor to the user.  */  flen = strlen (argv[0]);  fname = argv[0] + flen - 1;  while (isspace (*fname))    --fname;  fname[1] = '\0';  flen = fname - argv[0] + 1;  fname = argv[0];  /* Are we invoking a builtin function?  */  entry_p = lookup_function (function_table, fname);  if (entry_p)    {      for (i=0; argv[i+1]; ++i)	;      return expand_builtin_function (o, i, argv + 1, entry_p);    }  /* No, so the first argument is the name of a variable to be expanded and     interpreted as a function.  Create the variable reference.  */  body = alloca (flen + 4);  body[0]='$';  body[1]='(';  strcpy (body + 2, fname);  body[flen+2]=')';  body[flen+3]= '\0';  /* Set up arguments $(1) .. $(N).  $(0) is the function name.  */  push_new_variable_scope ();  for (i=0; *argv; ++i, ++argv)    {      char num[11];      sprintf (num, "%d", i);      define_variable (num, strlen (num), *argv, o_automatic, 0);    }  /* Expand the body in the context of the arguments, adding the result to     the variable buffer.  */  o = variable_expand_string (o, body, flen+3);  pop_variable_scope ();  return o + strlen(o);}

⌨️ 快捷键说明

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