예제 #1
0
/* duplicate the first n bytes of a string and terminate it */
const char *vtkParse_CacheString(StringCache *cache, const char *in, size_t n)
{
  char *res = NULL;

  res = vtkParse_NewString(cache, n);
  strncpy(res, in, n);
  res[n] = '\0';

  return res;
}
예제 #2
0
/* read options from a file, return zero on error */
static int read_option_file(
  StringCache *strings, const char *filename, int *argn, char ***args)
{
  static int option_file_stack_max = 10;
  static int option_file_stack_size = 0;
  static const char *option_file_stack[10];
  FILE *fp;
  char *line;
  const char *ccp;
  char *argstring;
  char *arg;
  size_t maxlen = 15;
  size_t i, n;
  int j;
  int in_string;

  line = (char *)malloc(maxlen);

  fp = fopen(filename, "r");

  if (fp == NULL)
    {
    return 0;
    }

  /* read the file line by line */
  while (fgets(line, (int)maxlen, fp))
    {
    n = strlen(line);

    /* if buffer not long enough, increase it */
    while (n == maxlen-1 && line[n-1] != '\n' && !feof(fp))
      {
      maxlen *= 2;
      line = (char *)realloc(line, maxlen);
      if (!fgets(&line[n], (int)(maxlen-n), fp)) { break; }
      n += strlen(&line[n]);
      }

    /* allocate a string to hold the parsed arguments */
    argstring = vtkParse_NewString(strings, n);
    arg = argstring;
    i = 0;

    /* break the line into individual options */
    ccp = line;
    in_string = 0;
    while (*ccp != '\0')
      {
      for (;;)
        {
        if (*ccp == '\\')
          {
          ccp++;
          }
        else if (*ccp == '\"' || *ccp == '\'')
          {
          if (!in_string)
            {
            in_string = *ccp++;
            continue;
            }
          else if (*ccp == in_string)
            {
            in_string = 0;
            ccp++;
            continue;
            }
          }
        else if (!in_string && isspace(*ccp))
          {
          do { ccp++; } while (isspace(*ccp));
          break;
          }
        if (*ccp == '\0')
          {
          break;
          }
        /* append character to argument */
        arg[i++] = *ccp++;
        }
      arg[i++] = '\0';

      if (arg[0] == '@')
        {
        /* recursively expand '@file' option */
        if (option_file_stack_size == option_file_stack_max)
          {
          fprintf(stderr, "%s: @file recursion is too deep.\n",
                  (*args)[0]);
          exit(1);
          }
        /* avoid reading the same file recursively */
        option_file_stack[option_file_stack_size++] = filename;
        for (j = 0; j < option_file_stack_size; j++)
          {
          if (strcmp(&arg[1], option_file_stack[j]) == 0)
            {
            break;
            }
          }
        if (j < option_file_stack_size)
          {
          parse_append_arg(argn, args, arg);
          }
        else if (read_option_file(strings, &arg[1], argn, args) == 0)
          {
          parse_append_arg(argn, args, arg);
          }
        option_file_stack_size--;
        }
      else if (arg[0] != '\0')
        {
        parse_append_arg(argn, args, arg);
        }
      /* prepare for next arg */
      arg += i;
      i = 0;
      }
    }

  return 1;
}
예제 #3
0
/* try to resolve "Using" declarations with the given class. */
void vtkParseMerge_MergeUsing(
  FileInfo *finfo, MergeInfo *info, ClassInfo *merge,
  const ClassInfo *super, unsigned long depth)
{
  unsigned long i, j, k, ii, n, m;
  char *cp;
  size_t l;
  int match;
  UsingInfo *u;
  UsingInfo *v;
  FunctionInfo *func;
  FunctionInfo *f2;
  ValueInfo *param;
  const char *lastval;
  int is_constructor;

  /* if scope matches, rename scope to "Superclass", */
  /* this will cause any inherited scopes to match */
  match = 0;
  for (ii = 0; ii < merge->NumberOfUsings; ii++)
    {
    u = merge->Usings[ii];
    if (u->Scope)
      {
      match = 1;
      if (strcmp(u->Scope, super->Name) == 0)
        {
        u->Scope = "Superclass";
        }
      }
    }
  if (!match)
    {
    /* nothing to do! */
    return;
    }

  m = merge->NumberOfFunctions;
  n = super->NumberOfFunctions;
  for (i = 0; i < n; i++)
    {
    func = super->Functions[i];

    if (!func->Name)
      {
      continue;
      }

    /* destructors cannot be used */
    if (func->Name[0] == '~' && strcmp(&func->Name[1], super->Name) == 0)
      {
      continue;
      }

    /* constructors can be used, with limitations */
    is_constructor = 0;
    if (strcmp(func->Name, super->Name) == 0)
      {
      is_constructor = 1;
      if (func->Template)
        {
        /* templated constructors cannot be "used" */
        continue;
        }
      }

    /* check that the function is being "used" */
    match = 0;
    for (ii = 0; ii < merge->NumberOfUsings; ii++)
      {
      u = merge->Usings[ii];
      if (u->Scope && strcmp(u->Scope, "Superclass") == 0)
        {
        if (u->Name && strcmp(u->Name, func->Name) == 0)
          {
          match = 1;
          break;
          }
        }
      }
    if (!match)
      {
      continue;
      }

    /* look for override of this signature */
    match = 0;
    for (j = 0; j < m; j++)
      {
      f2 = merge->Functions[j];
      if (f2->Name &&
          ((is_constructor && strcmp(f2->Name, merge->Name) == 0) ||
           (!is_constructor && strcmp(f2->Name, func->Name) == 0)))
        {
        if (vtkParse_CompareFunctionSignature(func, f2) != 0)
          {
          match = 1;
          break;
          }
        }
      }
    if (!match)
      {
      /* copy into the merge */
      if (is_constructor)
        {
        /* constructors require special default argument handling, there
         * is a different used constructor for each arg with a default */
        for (j = func->NumberOfParameters; j > 0; j--)
          {
          param = func->Parameters[0];
          if (j == 1 && param->TypeName &&
              strcmp(param->TypeName, super->Name) == 0 &&
              (param->Type & VTK_PARSE_POINTER_MASK) == 0)
            {
            /* it is a copy constructor, it will not be "used" */
            continue;
            }
          f2 = (FunctionInfo *)malloc(sizeof(FunctionInfo));
          vtkParse_InitFunction(f2);
          f2->Access = u->Access;
          f2->Name = merge->Name;
          f2->Class = merge->Name;
          f2->Comment = func->Comment;
          f2->IsExplicit = func->IsExplicit;
          l = vtkParse_FunctionInfoToString(f2, NULL, VTK_PARSE_EVERYTHING);
          cp = vtkParse_NewString(finfo->Strings, l);
          vtkParse_FunctionInfoToString(f2, cp, VTK_PARSE_EVERYTHING);
          f2->Signature = cp;
          for (k = 0; k < j; k++)
            {
            param = (ValueInfo *)malloc(sizeof(ValueInfo));
            vtkParse_CopyValue(param, func->Parameters[k]);
            lastval = param->Value;
            param->Value = NULL; /* clear default parameter value */
            vtkParse_AddParameterToFunction(f2, param);
            }
          vtkParse_AddFunctionToClass(merge, f2);
          if (info)
            {
            vtkParseMerge_PushFunction(info, depth);
            }
          if (lastval == NULL)
            {
            /* continue if last parameter had a default value */
            break;
            }
          }
        }
      else
        {
        /* non-constructor methods are simple */
        f2 = (FunctionInfo *)malloc(sizeof(FunctionInfo));
        vtkParse_CopyFunction(f2, func);
        f2->Access = u->Access;
        f2->Class = merge->Name;
        vtkParse_AddFunctionToClass(merge, f2);
        if (info)
          {
          vtkParseMerge_PushFunction(info, depth);
          }
        }
      }
    }

  /* remove any using declarations that were satisfied */
  for (i = 0; i < merge->NumberOfUsings; i++)
    {
    u = merge->Usings[i];
    if (u->Scope && strcmp(u->Scope, "Superclass") == 0)
      {
      match = 0;
      for (j = 0; j < super->NumberOfUsings && !match; j++)
        {
        v = super->Usings[j];
        if (v->Name && u->Name && strcmp(u->Name, v->Name) == 0)
          {
          /* get the new scope so that recursion will occur */
          u->Scope = v->Scope;
          match = 1;
          }
        }
      for (j = 0; j < super->NumberOfFunctions && !match; j++)
        {
        func = super->Functions[j];
        if (u->Name && func->Name && strcmp(func->Name, u->Name) == 0)
          {
          /* ignore this "using" from now on */
          merge->Usings[i]->Name = NULL;
          merge->Usings[i]->Scope = NULL;
          match = 1;
          }
        }
      }
    }
}