home *** CD-ROM | disk | FTP | other *** search
/ PC PowerPlay 58 / pcpp58a.iso / extras / quake 3 source / Q3A_ToolSource.exe / Main / scriplib.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-01-02  |  6.6 KB  |  355 lines

  1. // scriplib.c
  2.  
  3. #include "cmdlib.h"
  4. #include "scriplib.h"
  5.  
  6. /*
  7. =============================================================================
  8.  
  9.                         PARSING STUFF
  10.  
  11. =============================================================================
  12. */
  13.  
  14. typedef struct
  15. {
  16.     char    filename[1024];
  17.     char    *buffer,*script_p,*end_p;
  18.     int     line;
  19. } script_t;
  20.  
  21. #define    MAX_INCLUDES    8
  22. script_t    scriptstack[MAX_INCLUDES];
  23. script_t    *script;
  24. int            scriptline;
  25.  
  26. char    token[MAXTOKEN];
  27. qboolean endofscript;
  28. qboolean tokenready;                     // only qtrue if UnGetToken was just called
  29.  
  30. /*
  31. ==============
  32. AddScriptToStack
  33. ==============
  34. */
  35. void AddScriptToStack( const char *filename ) {
  36.     int            size;
  37.  
  38.     script++;
  39.     if (script == &scriptstack[MAX_INCLUDES])
  40.         Error ("script file exceeded MAX_INCLUDES");
  41.     strcpy (script->filename, ExpandPath (filename) );
  42.  
  43.     size = LoadFile (script->filename, (void **)&script->buffer);
  44.  
  45.     printf ("entering %s\n", script->filename);
  46.  
  47.     script->line = 1;
  48.  
  49.     script->script_p = script->buffer;
  50.     script->end_p = script->buffer + size;
  51. }
  52.  
  53.  
  54. /*
  55. ==============
  56. LoadScriptFile
  57. ==============
  58. */
  59. void LoadScriptFile( const char *filename ) {
  60.     script = scriptstack;
  61.     AddScriptToStack (filename);
  62.  
  63.     endofscript = qfalse;
  64.     tokenready = qfalse;
  65. }
  66.  
  67.  
  68. /*
  69. ==============
  70. ParseFromMemory
  71. ==============
  72. */
  73. void ParseFromMemory (char *buffer, int size)
  74. {
  75.     script = scriptstack;
  76.     script++;
  77.     if (script == &scriptstack[MAX_INCLUDES])
  78.         Error ("script file exceeded MAX_INCLUDES");
  79.     strcpy (script->filename, "memory buffer" );
  80.  
  81.     script->buffer = buffer;
  82.     script->line = 1;
  83.     script->script_p = script->buffer;
  84.     script->end_p = script->buffer + size;
  85.  
  86.     endofscript = qfalse;
  87.     tokenready = qfalse;
  88. }
  89.  
  90.  
  91. /*
  92. ==============
  93. UnGetToken
  94.  
  95. Signals that the current token was not used, and should be reported
  96. for the next GetToken.  Note that
  97.  
  98. GetToken (qtrue);
  99. UnGetToken ();
  100. GetToken (qfalse);
  101.  
  102. could cross a line boundary.
  103. ==============
  104. */
  105. void UnGetToken (void)
  106. {
  107.     tokenready = qtrue;
  108. }
  109.  
  110.  
  111. qboolean EndOfScript (qboolean crossline)
  112. {
  113.     if (!crossline)
  114.         Error ("Line %i is incomplete\n",scriptline);
  115.  
  116.     if (!strcmp (script->filename, "memory buffer"))
  117.     {
  118.         endofscript = qtrue;
  119.         return qfalse;
  120.     }
  121.  
  122.     free (script->buffer);
  123.     if (script == scriptstack+1)
  124.     {
  125.         endofscript = qtrue;
  126.         return qfalse;
  127.     }
  128.     script--;
  129.     scriptline = script->line;
  130.     printf ("returning to %s\n", script->filename);
  131.     return GetToken (crossline);
  132. }
  133.  
  134. /*
  135. ==============
  136. GetToken
  137. ==============
  138. */
  139. qboolean GetToken (qboolean crossline)
  140. {
  141.     char    *token_p;
  142.  
  143.     if (tokenready)                         // is a token allready waiting?
  144.     {
  145.         tokenready = qfalse;
  146.         return qtrue;
  147.     }
  148.  
  149.     if (script->script_p >= script->end_p)
  150.         return EndOfScript (crossline);
  151.  
  152. //
  153. // skip space
  154. //
  155. skipspace:
  156.     while (*script->script_p <= 32)
  157.     {
  158.         if (script->script_p >= script->end_p)
  159.             return EndOfScript (crossline);
  160.         if (*script->script_p++ == '\n')
  161.         {
  162.             if (!crossline)
  163.                 Error ("Line %i is incomplete\n",scriptline);
  164.             scriptline = script->line++;
  165.         }
  166.     }
  167.  
  168.     if (script->script_p >= script->end_p)
  169.         return EndOfScript (crossline);
  170.  
  171.     // ; # // comments
  172.     if (*script->script_p == ';' || *script->script_p == '#'
  173.         || ( script->script_p[0] == '/' && script->script_p[1] == '/') )
  174.     {
  175.         if (!crossline)
  176.             Error ("Line %i is incomplete\n",scriptline);
  177.         while (*script->script_p++ != '\n')
  178.             if (script->script_p >= script->end_p)
  179.                 return EndOfScript (crossline);
  180.         scriptline = script->line++;
  181.         goto skipspace;
  182.     }
  183.  
  184.     // /* */ comments
  185.     if (script->script_p[0] == '/' && script->script_p[1] == '*')
  186.     {
  187.         if (!crossline)
  188.             Error ("Line %i is incomplete\n",scriptline);
  189.         script->script_p+=2;
  190.         while (script->script_p[0] != '*' && script->script_p[1] != '/')
  191.         {
  192.             if ( *script->script_p == '\n' ) {
  193.                 scriptline = script->line++;
  194.             }
  195.             script->script_p++;
  196.             if (script->script_p >= script->end_p)
  197.                 return EndOfScript (crossline);
  198.         }
  199.         script->script_p += 2;
  200.         goto skipspace;
  201.     }
  202.  
  203. //
  204. // copy token
  205. //
  206.     token_p = token;
  207.  
  208.     if (*script->script_p == '"')
  209.     {
  210.         // quoted token
  211.         script->script_p++;
  212.         while (*script->script_p != '"')
  213.         {
  214.             *token_p++ = *script->script_p++;
  215.             if (script->script_p == script->end_p)
  216.                 break;
  217.             if (token_p == &token[MAXTOKEN])
  218.                 Error ("Token too large on line %i\n",scriptline);
  219.         }
  220.         script->script_p++;
  221.     }
  222.     else    // regular token
  223.     while ( *script->script_p > 32 && *script->script_p != ';')
  224.     {
  225.         *token_p++ = *script->script_p++;
  226.         if (script->script_p == script->end_p)
  227.             break;
  228.         if (token_p == &token[MAXTOKEN])
  229.             Error ("Token too large on line %i\n",scriptline);
  230.     }
  231.  
  232.     *token_p = 0;
  233.  
  234.     if (!strcmp (token, "$include"))
  235.     {
  236.         GetToken (qfalse);
  237.         AddScriptToStack (token);
  238.         return GetToken (crossline);
  239.     }
  240.  
  241.     return qtrue;
  242. }
  243.  
  244.  
  245. /*
  246. ==============
  247. TokenAvailable
  248.  
  249. Returns qtrue if there is another token on the line
  250. ==============
  251. */
  252. qboolean TokenAvailable (void) {
  253.     int        oldLine;
  254.     qboolean    r;
  255.  
  256.     oldLine = script->line;
  257.     r = GetToken( qtrue );
  258.     if ( !r ) {
  259.         return qfalse;
  260.     }
  261.     UnGetToken();
  262.     if ( oldLine == script->line ) {
  263.         return qtrue;
  264.     }
  265.     return qfalse;
  266. }
  267.  
  268.  
  269. //=====================================================================
  270.  
  271.  
  272. void MatchToken( char *match ) {
  273.     GetToken( qtrue );
  274.  
  275.     if ( strcmp( token, match ) ) {
  276.         Error( "MatchToken( \"%s\" ) failed at line %i", match, scriptline );
  277.     }
  278. }
  279.  
  280.  
  281. void Parse1DMatrix (int x, vec_t *m) {
  282.     int        i;
  283.  
  284.     MatchToken( "(" );
  285.  
  286.     for (i = 0 ; i < x ; i++) {
  287.         GetToken( qfalse );
  288.         m[i] = atof(token);
  289.     }
  290.  
  291.     MatchToken( ")" );
  292. }
  293.  
  294. void Parse2DMatrix (int y, int x, vec_t *m) {
  295.     int        i;
  296.  
  297.     MatchToken( "(" );
  298.  
  299.     for (i = 0 ; i < y ; i++) {
  300.         Parse1DMatrix (x, m + i * x);
  301.     }
  302.  
  303.     MatchToken( ")" );
  304. }
  305.  
  306. void Parse3DMatrix (int z, int y, int x, vec_t *m) {
  307.     int        i;
  308.  
  309.     MatchToken( "(" );
  310.  
  311.     for (i = 0 ; i < z ; i++) {
  312.         Parse2DMatrix (y, x, m + i * x*y);
  313.     }
  314.  
  315.     MatchToken( ")" );
  316. }
  317.  
  318.  
  319. void Write1DMatrix (FILE *f, int x, vec_t *m) {
  320.     int        i;
  321.  
  322.     fprintf (f, "( ");
  323.     for (i = 0 ; i < x ; i++) {
  324.         if (m[i] == (int)m[i] ) {
  325.             fprintf (f, "%i ", (int)m[i]);
  326.         } else {
  327.             fprintf (f, "%f ", m[i]);
  328.         }
  329.     }
  330.     fprintf (f, ")");
  331. }
  332.  
  333. void Write2DMatrix (FILE *f, int y, int x, vec_t *m) {
  334.     int        i;
  335.  
  336.     fprintf (f, "( ");
  337.     for (i = 0 ; i < y ; i++) {
  338.         Write1DMatrix (f, x, m + i*x);
  339.         fprintf (f, " ");
  340.     }
  341.     fprintf (f, ")\n");
  342. }
  343.  
  344.  
  345. void Write3DMatrix (FILE *f, int z, int y, int x, vec_t *m) {
  346.     int        i;
  347.  
  348.     fprintf (f, "(\n");
  349.     for (i = 0 ; i < z ; i++) {
  350.         Write2DMatrix (f, y, x, m + i*(x*y) );
  351.     }
  352.     fprintf (f, ")\n");
  353. }
  354.  
  355.