コード例 #1
0
/* Parse one Texinfo file and create manpages according to the
   embedded instructions.  */
static void
parse_file (const char *fname, FILE *fp, char **section_name, int in_pause)
{
  char *line;
  int lnr = 0;
  /* Fixme: The following state variables don't carry over to include
     files. */
  int skip_to_end = 0;        /* Used to skip over menu entries. */
  int skip_sect_line = 0;     /* Skip after @mansect.  */
  int item_indent = 0;        /* How far is the current @item indented.  */

  /* Helper to define a macro. */
  char *macroname = NULL;
  char *macrovalue = NULL;
  size_t macrovaluesize = 0;
  size_t macrovalueused = 0;

  line = xmalloc (LINESIZE);
  while (fgets (line, LINESIZE, fp))
    {
      size_t n = strlen (line);
      int got_line = 0;
      char *p, *pend;

      lnr++;
      if (!n || line[n-1] != '\n')
        {
          err ("%s:%d: trailing linefeed missing, line too long or "
               "embedded Nul character", fname, lnr);
          break;
        }
      line[--n] = 0;

      /* Kludge to allow indentation of tables.  */
      for (p=line; *p == ' ' || *p == '\t'; p++)
        ;
      if (*p)
        {
          if (*p == '@' && !strncmp (p+1, "item", 4))
            item_indent = p - line;  /* Set a new indent level.  */
          else if (p - line < item_indent)
            item_indent = 0;         /* Switch off indention.  */

          if (item_indent)
            {
              memmove (line, line+item_indent, n - item_indent + 1);
              n -= item_indent;
            }
        }


      if (*line == '@')
        {
          for (p=line+1, n=1; *p && *p != ' ' && *p != '\t'; p++)
            n++;
          while (*p == ' ' || *p == '\t')
            p++;
        }
      else
        p = line;

      /* Take action on macro.  */
      if (macroname)
        {
          if (n == 4 && !memcmp (line, "@end", 4)
              && (line[4]==' '||line[4]=='\t'||!line[4])
              && !strncmp (p, "macro", 5)
              && (p[5]==' '||p[5]=='\t'||!p[5]))
            {
              if (macrovalueused)
                macrovalue[--macrovalueused] = 0; /* Kill the last LF. */
              macrovalue[macrovalueused] = 0;     /* Terminate macro. */
              macrovalue = xrealloc (macrovalue, macrovalueused+1);

              set_macro (macroname, macrovalue);
              macrovalue = NULL;
              free (macroname);
              macroname = NULL;
            }
          else
            {
              if (macrovalueused + strlen (line) + 2 >= macrovaluesize)
                {
                  macrovaluesize += strlen (line) + 256;
                  macrovalue = xrealloc (macrovalue,  macrovaluesize);
                }
              strcpy (macrovalue+macrovalueused, line);
              macrovalueused += strlen (line);
              macrovalue[macrovalueused++] = '\n';
            }
          continue;
        }


      if (n >= 5 && !memcmp (line, "@node", 5)
          && (line[5]==' '||line[5]=='\t'||!line[5]))
        {
          /* Completey ignore @node lines.  */
          continue;
        }


      if (skip_sect_line)
        {
          skip_sect_line = 0;
          if (!strncmp (line, "@section", 8)
              || !strncmp (line, "@subsection", 11)
              || !strncmp (line, "@chapheading", 12))
            continue;
        }

      /* We only parse lines we need and ignore the rest.  There are a
         few macros used to control this as well as one @ifset
         command.  Parts we know about are saved away into containers
         separate for each section. */

      /* First process ifset/ifclear commands. */
      if (*line == '@')
        {
          if (n == 6 && !memcmp (line, "@ifset", 6)
                   && (line[6]==' '||line[6]=='\t'))
            {
              for (p=line+7; *p == ' ' || *p == '\t'; p++)
                ;
              if (!*p)
                {
                  err ("%s:%d: name missing after \"@ifset\"", fname, lnr);
                  continue;
                }
              for (pend=p; *pend && *pend != ' ' && *pend != '\t'; pend++)
                ;
              *pend = 0;  /* Ignore rest of the line.  */
              push_condition (p, 1, fname, lnr);
              continue;
            }
          else if (n == 8 && !memcmp (line, "@ifclear", 8)
                   && (line[8]==' '||line[8]=='\t'))
            {
              for (p=line+9; *p == ' ' || *p == '\t'; p++)
                ;
              if (!*p)
                {
                  err ("%s:%d: name missing after \"@ifsclear\"", fname, lnr);
                  continue;
                }
              for (pend=p; *pend && *pend != ' ' && *pend != '\t'; pend++)
                ;
              *pend = 0;  /* Ignore rest of the line.  */
              push_condition (p, 0, fname, lnr);
              continue;
            }
          else if (n == 4 && !memcmp (line, "@end", 4)
                   && (line[4]==' '||line[4]=='\t')
                   && !strncmp (p, "ifset", 5)
                   && (p[5]==' '||p[5]=='\t'||!p[5]))
            {
              pop_condition (1, fname, lnr);
              continue;
            }
          else if (n == 4 && !memcmp (line, "@end", 4)
                   && (line[4]==' '||line[4]=='\t')
                   && !strncmp (p, "ifclear", 7)
                   && (p[7]==' '||p[7]=='\t'||!p[7]))
            {
              pop_condition (0, fname, lnr);
              continue;
            }
        }

      /* Take action on ifset/ifclear.  */
      if (!cond_is_active)
        continue;

      /* Process commands. */
      if (*line == '@')
        {
          if (skip_to_end
              && n == 4 && !memcmp (line, "@end", 4)
              && (line[4]==' '||line[4]=='\t'||!line[4]))
            {
              skip_to_end = 0;
            }
          else if (cond_in_verbatim)
            {
                got_line = 1;
            }
          else if (n == 6 && !memcmp (line, "@macro", 6))
            {
              macroname = xstrdup (p);
              macrovalue = xmalloc ((macrovaluesize = 1024));
              macrovalueused = 0;
            }
          else if (n == 8 && !memcmp (line, "@manpage", 8))
            {
              free (*section_name);
              *section_name = NULL;
              finish_page ();
              start_page (p);
              in_pause = 0;
            }
          else if (n == 8 && !memcmp (line, "@mansect", 8))
            {
              if (!thepage.name)
                err ("%s:%d: section outside of a man page", fname, lnr);
              else
                {
                  free (*section_name);
                  *section_name = ascii_strupr (xstrdup (p));
                  in_pause = 0;
                  skip_sect_line = 1;
                }
            }
          else if (n == 9 && !memcmp (line, "@manpause", 9))
            {
              if (!*section_name)
                err ("%s:%d: pausing outside of a man section", fname, lnr);
              else if (in_pause)
                err ("%s:%d: already pausing", fname, lnr);
              else
                in_pause = 1;
            }
          else if (n == 8 && !memcmp (line, "@mancont", 8))
            {
              if (!*section_name)
                err ("%s:%d: continue outside of a man section", fname, lnr);
              else if (!in_pause)
                err ("%s:%d: continue while not pausing", fname, lnr);
              else
                in_pause = 0;
            }
          else if (n == 5 && !memcmp (line, "@menu", 5)
                   && (line[5]==' '||line[5]=='\t'||!line[5]))
            {
              skip_to_end = 1;
            }
          else if (n == 8 && !memcmp (line, "@include", 8)
                   && (line[8]==' '||line[8]=='\t'||!line[8]))
            {
              char *incname = xstrdup (p);
              FILE *incfp = fopen (incname, "r");

              if (!incfp && opt_include && *opt_include && *p != '/')
                {
                  free (incname);
                  incname = xmalloc (strlen (opt_include) + 1
                                     + strlen (p) + 1);
                  strcpy (incname, opt_include);
                  if ( incname[strlen (incname)-1] != '/' )
                    strcat (incname, "/");
                  strcat (incname, p);
                  incfp = fopen (incname, "r");
                }

              if (!incfp)
                err ("can't open include file '%s':%s",
                     incname, strerror (errno));
              else
                {
                  parse_file (incname, incfp, section_name, in_pause);
                  fclose (incfp);
                }
              free (incname);
            }
          else if (n == 4 && !memcmp (line, "@bye", 4)
                   && (line[4]==' '||line[4]=='\t'||!line[4]))
            {
              break;
            }
          else if (!skip_to_end)
            got_line = 1;
        }
      else if (!skip_to_end)
        got_line = 1;

      if (got_line && cond_in_verbatim)
        add_content (*section_name, line, 1);
      else if (got_line && thepage.name && *section_name && !in_pause)
        add_content (*section_name, line, 0);

    }
  if (ferror (fp))
    err ("%s:%d: read error: %s", fname, lnr, strerror (errno));
  free (macroname);
  free (macrovalue);
  free (line);
}
コード例 #2
0
ファイル: multi.cpp プロジェクト: malikcpp/nCorpsTipe
bool config_file_parser(const char ** config_args, GlUniversEns* env) {
  bool succeeded = true;
  const char * c_type = config_args[1];
  const char * c_operation = config_args[2];
  const char * c_name = config_args[30];
  float c_p_x, c_p_y, c_p_z;
  float c_g_mass, c_g_radius;
  //argument -p
  bool c_p = ! ( strcmp(config_args[10], "") == 0 && strcmp(config_args[12], "") == 0 && strcmp(config_args[14], "") == 0 );
  if ( c_p ) {
    sscanf(config_args[10], "%f", &c_p_x);
    sscanf(config_args[12], "%f", &c_p_y);
    sscanf(config_args[14], "%f", &c_p_z);
  }
  //arguments -r et -m
  bool c_g = ! ( strcmp(config_args[4], "") == 0 && strcmp(config_args[8], "") == 0 );
  if ( c_g ) {
    sscanf(config_args[4], "%f", &c_g_mass);
    sscanf(config_args[7], "%f", &c_g_radius);
  }
  //commanes sur univers
  if ( strcmp(c_type, "univers") == 0 ) {
    if ( strcmp(c_operation, "set") == 0 ) {
      //pour l'instant on ne fait rien
      cout << "warning : nothing done on : 'univers set " << c_name << "'" << endl;
    }
    else if ( strcmp(c_operation, "add") == 0 ) {
      //adpatation des arguments :
      //m : méthode de calcul
      //r : type de de rendu
      //p_x : dt
      //p_y : nmax pour iocsv
      //p_z : pas encore décidé
      GlUnivers new_u;
      if ( c_g ) {
        GlUnivers new_u = GlUnivers((Univers::methode) (int) c_g_mass, 
                                    5, 
                                    (GlUnivers::glUniversMode) (int) c_g_radius);
      } 
      else {
        cout << "adding : univers warning : methodes (rendu & calcul) not specified";
        cout << endl;
        cout << "adding : univers default : U_2D & PFD:" << endl;
        GlUnivers new_u = GlUnivers();
      }
      if ( c_p ) {
        new_u.Univers::init(c_p_x);

        time_t rawtime; //fichier log unique : date & heure + nom de l'univers
        struct tm * timeinfo;
        time ( &rawtime );
        timeinfo = localtime ( &rawtime );
        stringstream logfilename;
        logfilename << c_name << "::" << asctime(timeinfo);
        string filename_ = logfilename.str();
        filename_.erase(filename_.end() - 2, filename_.end());
        filename_ += ".csv";

        new_u.Univers::start_CSVstream(filename_, c_p_y);
      } 
      else {
        cout << "adding : univers warning : nmax & dt not specified" << endl;
        cout << "adding : univers default : dt=5, nmax=-1 (no output)" << endl;
      }
      env->add_univers((string) c_name, &new_u);
      cout << "adding : univers : '" << c_name << "'" << endl;
    }
    else if ( strcmp(c_operation, "delete") == 0 ) {
      //pour l'instant on ne fait rien
      cout << "warning : nothing done on : 'univers delete " << c_name << "'" << endl;
    }
    else {
      //message d'erreur
      succeeded = false;
    } 
  }
  //commandes sur astres
  else if ( strcmp(c_type, "astre") == 0 ) {
    const char * c_parent_name = config_args[33];
    float c_v_x, c_v_y, c_v_z;
    float c_a_x, c_a_y, c_a_z;
    //argument -v
    bool c_v = ! ( strcmp(config_args[17], "") == 0 && strcmp(config_args[19], "") == 0 && strcmp(config_args[21], "") == 0 );
    if ( c_v ) {
      sscanf(config_args[17], "%f", &c_v_x);
      sscanf(config_args[19], "%f", &c_v_y);
      sscanf(config_args[21], "%f", &c_v_z);
    }
    //argument -a
    bool c_a = ! ( strcmp(config_args[24], "") == 0 && strcmp(config_args[26], "") == 0 && strcmp(config_args[28], "") == 0 );
    if ( c_a ) {
      sscanf(config_args[24], "%f", &c_a_x);
      sscanf(config_args[26], "%f", &c_a_y);
      sscanf(config_args[28], "%f", &c_a_z);
    }
    //parent_name doit être spécfier pour les opérations sur les astres
    if ( strlen(c_parent_name) > 0 ) {
      if ( strcmp(c_operation, "set") == 0 ) {
        if ( (c_p || c_v || c_a) && !c_g ) {
          GlAstre * a = env->get_astre_by_name((string) c_name, (string) c_parent_name);
          set_macro(a, 
                    c_p, c_p_x, c_p_y, c_p_z, 
                    c_v, c_v_x, c_v_y, c_v_z, 
                    c_a, c_a_x, c_a_y, c_a_z);

          cout << "updated : astre : " << c_name << " in " << c_parent_name << endl;
        }
        else {
          //message d'erreur
          cerr << "error : astre : set : mass and radius cannot be set && one of position, vitesse and acceleration must be set" << endl;
          succeeded = false;
        }
      }
      else if ( strcmp(c_operation, "add") == 0 ) {
        if ( c_g && c_p ) {
          Astre new_a = Astre (
                               Vector(true, c_p_x, c_p_y, c_p_z), 
                               c_g_mass, 
                               c_g_radius
                               );
          GlAstre gl_new_a =  GlAstre (new_a);
          env->add_astre((string) c_name, (string) c_parent_name, &gl_new_a);
          set_macro(&gl_new_a, 
                    false, 0, 0, 0, 
                    c_v, c_v_x, c_v_y, c_v_z, 
                    c_a, c_a_x, c_a_y, c_a_z);
          cout << "adding : astre : '" << c_name << "' in '" << c_parent_name << "'" << endl;
        }
        else {
          //message d'erreur
          cerr << "error : astre add : mass and radius && position must be set" << endl;
          succeeded = false;
        }
      }
      else if ( strcmp(c_operation, "delete") == 0 ) {
        env->delete_astre((string) c_name, (string) c_parent_name);
        cout << "deleting : astre : '" << c_name << "' in '" << c_parent_name << "'" << endl;
      }
      else {
        //message d'erreur
        succeeded = false;
      } 
    }
    else {
      //message d'erreu
      cerr << "error : astre " << c_name << " : no univers have been specified" << endl; 
      succeeded = false;
    }
  }
  else {
    // message d'erreur
    succeeded = false;
  } 
  return succeeded;
}