text: /*  Copyright © 2018, Roboti LLC
  
      This file is licensed under the MuJoCo Resource License (the "License").
      You may not use this file except in compliance with the License.
      You may obtain a copy of the License at
  
          https://www.roboti.us/resourcelicense.txt
  */
  
  
  #include "mujoco.h"
  #include <stdlib.h>
  #include <stdio.h>
  #include <string.h>
  #include <ctype.h>
  
  
  // help
  const char helpstring[] = 
      "\n Usage:  compile infile outfile\n"
      "   infile can be in mjcf, urdf, mjb format\n"
      "   outfile can be in mjcf, mjb, txt format\n\n"
      " Example:  compile model.xml model.mjb\n";
  
  
  // deallocate and print message
  int finish(const char* msg = 0, mjModel* m = 0)
  {
      // deallocated everything
      if( m )
          mj_deleteModel(m);
      mj_deactivate();
  
      // print message
      if( msg )
          printf("%s\n", msg);
  
      return 0;
  }
  
  
  // possible file types
  enum
  {
      typeUNKNOWN = 0,
      typeXML,
      typeMJB,
      typeTXT
  };
  
  
  // determine file type
  int filetype(const char* filename)
  {
      // convert to lower case for string comparison
      char lower[1000];
      size_t i=0;
      while( i<strlen(filename) && i<999 )
      {
          lower[i] = (char)tolower(filename[i]);
          i++;
      }
      lower[i] = 0;
  
      // find last dot
      int dot = (int)strlen(lower);
      while( dot>=0 && lower[dot]!='.' )
          dot--;
  
      // no dot found
      if( dot<0 )
          return typeUNKNOWN;
  
      // check extension
      if( !strcmp(lower+dot, ".xml") || !strcmp(lower+dot, ".urdf") )
          return typeXML;
      else if( !strcmp(lower+dot, ".mjb") )
          return typeMJB;
      else if( !strcmp(lower+dot, ".txt") )
          return typeTXT;
      else
          return typeUNKNOWN;
  }
  
  
  
  // main function
  int main(int argc, const char** argv)
  {
      // model and error
      mjModel* m = 0;
      char error[1000];
  
      // print help if arguments are missing
      if( argc!=3 )
          return finish(helpstring);
  
      // activate MuJoCo Pro license (this must be *your* activation key)
      mj_activate("mjkey.txt");
  
      // determine file types
      int type1 = filetype(argv[1]);
      int type2 = filetype(argv[2]);
  
      // check types
      if( type1==typeUNKNOWN || type1==typeTXT || 
          type2==typeUNKNOWN || (type1==typeMJB && type2==typeXML) )
          return finish("Illegal combination of file formats");
  
      // make sure output file does not exist
      FILE* fp = fopen(argv[2], "r");
      if( fp )
      {
          fclose(fp);
          return finish("Output file already exists");
      }
  
      // load model
      if( type1==typeXML )
          m = mj_loadXML(argv[1], 0, error, 1000);
      else
          m = mj_loadModel(argv[1], 0);
  
      // check error
      if( !m )
      {
          if( type1==typeXML )
              return finish(error, 0);
          else
              return finish("Could not load model", 0);
      }
  
      // save model
      if( type2==typeXML )
      {
          if( mj_saveLastXML(argv[2], m, error, 1000) )
              return finish(error, m);
      }
      else if( type2==typeMJB )
          mj_saveModel(m, argv[2], 0, 0);
      else
          mj_printModel(m, argv[2]);
  
      // finalize
      return finish("Done", m);
  }
  