101e04c3fSmrg/* 201e04c3fSmrg * Copyright © 2010 Intel Corporation 301e04c3fSmrg * 401e04c3fSmrg * Permission is hereby granted, free of charge, to any person obtaining a 501e04c3fSmrg * copy of this software and associated documentation files (the "Software"), 601e04c3fSmrg * to deal in the Software without restriction, including without limitation 701e04c3fSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 801e04c3fSmrg * and/or sell copies of the Software, and to permit persons to whom the 901e04c3fSmrg * Software is furnished to do so, subject to the following conditions: 1001e04c3fSmrg * 1101e04c3fSmrg * The above copyright notice and this permission notice (including the next 1201e04c3fSmrg * paragraph) shall be included in all copies or substantial portions of the 1301e04c3fSmrg * Software. 1401e04c3fSmrg * 1501e04c3fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1601e04c3fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1701e04c3fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1801e04c3fSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 1901e04c3fSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 2001e04c3fSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 2101e04c3fSmrg * DEALINGS IN THE SOFTWARE. 2201e04c3fSmrg */ 2301e04c3fSmrg 2401e04c3fSmrg#include <stdio.h> 2501e04c3fSmrg#include <string.h> 2601e04c3fSmrg#include <errno.h> 2701e04c3fSmrg#include <getopt.h> 2801e04c3fSmrg 2901e04c3fSmrg#include "glcpp.h" 3001e04c3fSmrg#include "main/mtypes.h" 3101e04c3fSmrg#include "main/shaderobj.h" 3201e04c3fSmrg#include "util/strtod.h" 3301e04c3fSmrg 3401e04c3fSmrgextern int glcpp_parser_debug; 3501e04c3fSmrg 3601e04c3fSmrgvoid 3701e04c3fSmrg_mesa_reference_shader(struct gl_context *ctx, struct gl_shader **ptr, 3801e04c3fSmrg struct gl_shader *sh) 3901e04c3fSmrg{ 4001e04c3fSmrg (void) ctx; 4101e04c3fSmrg *ptr = sh; 4201e04c3fSmrg} 4301e04c3fSmrg 4401e04c3fSmrg/* Read from fp until EOF and return a string of everything read. 4501e04c3fSmrg */ 4601e04c3fSmrgstatic char * 4701e04c3fSmrgload_text_fp (void *ctx, FILE *fp) 4801e04c3fSmrg{ 4901e04c3fSmrg#define CHUNK 4096 5001e04c3fSmrg char *text = NULL; 5101e04c3fSmrg size_t text_size = 0; 5201e04c3fSmrg size_t total_read = 0; 5301e04c3fSmrg size_t bytes; 5401e04c3fSmrg 5501e04c3fSmrg while (1) { 5601e04c3fSmrg if (total_read + CHUNK + 1 > text_size) { 5701e04c3fSmrg text_size = text_size ? text_size * 2 : CHUNK + 1; 5801e04c3fSmrg text = reralloc_size (ctx, text, text_size); 5901e04c3fSmrg if (text == NULL) { 6001e04c3fSmrg fprintf (stderr, "Out of memory\n"); 6101e04c3fSmrg return NULL; 6201e04c3fSmrg } 6301e04c3fSmrg } 6401e04c3fSmrg bytes = fread (text + total_read, 1, CHUNK, fp); 6501e04c3fSmrg total_read += bytes; 6601e04c3fSmrg 6701e04c3fSmrg if (bytes < CHUNK) { 6801e04c3fSmrg break; 6901e04c3fSmrg } 7001e04c3fSmrg } 7101e04c3fSmrg 7201e04c3fSmrg text[total_read] = '\0'; 7301e04c3fSmrg 7401e04c3fSmrg return text; 7501e04c3fSmrg} 7601e04c3fSmrg 7701e04c3fSmrgstatic char * 7801e04c3fSmrgload_text_file(void *ctx, const char *filename) 7901e04c3fSmrg{ 8001e04c3fSmrg char *text; 8101e04c3fSmrg FILE *fp; 8201e04c3fSmrg 8301e04c3fSmrg if (filename == NULL || strcmp (filename, "-") == 0) 8401e04c3fSmrg return load_text_fp (ctx, stdin); 8501e04c3fSmrg 8601e04c3fSmrg fp = fopen (filename, "r"); 8701e04c3fSmrg if (fp == NULL) { 8801e04c3fSmrg fprintf (stderr, "Failed to open file %s: %s\n", 8901e04c3fSmrg filename, strerror (errno)); 9001e04c3fSmrg return NULL; 9101e04c3fSmrg } 9201e04c3fSmrg 9301e04c3fSmrg text = load_text_fp (ctx, fp); 9401e04c3fSmrg 9501e04c3fSmrg fclose(fp); 9601e04c3fSmrg 9701e04c3fSmrg return text; 9801e04c3fSmrg} 9901e04c3fSmrg 10001e04c3fSmrg/* Initialize only those things that glcpp cares about. 10101e04c3fSmrg */ 10201e04c3fSmrgstatic void 10301e04c3fSmrginit_fake_gl_context (struct gl_context *gl_ctx) 10401e04c3fSmrg{ 1057ec681f3Smrg memset(gl_ctx, 0, sizeof(*gl_ctx)); 10601e04c3fSmrg gl_ctx->API = API_OPENGL_COMPAT; 10701e04c3fSmrg gl_ctx->Const.DisableGLSLLineContinuations = false; 10801e04c3fSmrg} 10901e04c3fSmrg 11001e04c3fSmrgstatic void 11101e04c3fSmrgusage (void) 11201e04c3fSmrg{ 11301e04c3fSmrg fprintf (stderr, 11401e04c3fSmrg "Usage: glcpp [OPTIONS] [--] [<filename>]\n" 11501e04c3fSmrg "\n" 11601e04c3fSmrg "Pre-process the given filename (stdin if no filename given).\n" 11701e04c3fSmrg "The following options are supported:\n" 11801e04c3fSmrg " --disable-line-continuations Do not interpret lines ending with a\n" 11901e04c3fSmrg " backslash ('\\') as a line continuation.\n"); 12001e04c3fSmrg} 12101e04c3fSmrg 12201e04c3fSmrgenum { 12301e04c3fSmrg DISABLE_LINE_CONTINUATIONS_OPT = CHAR_MAX + 1 12401e04c3fSmrg}; 12501e04c3fSmrg 12601e04c3fSmrgstatic const struct option 12701e04c3fSmrglong_options[] = { 12801e04c3fSmrg {"disable-line-continuations", no_argument, 0, DISABLE_LINE_CONTINUATIONS_OPT }, 12901e04c3fSmrg {"debug", no_argument, 0, 'd'}, 13001e04c3fSmrg {0, 0, 0, 0 } 13101e04c3fSmrg}; 13201e04c3fSmrg 13301e04c3fSmrgint 13401e04c3fSmrgmain (int argc, char *argv[]) 13501e04c3fSmrg{ 13601e04c3fSmrg char *filename = NULL; 13701e04c3fSmrg void *ctx = ralloc(NULL, void*); 13801e04c3fSmrg char *info_log = ralloc_strdup(ctx, ""); 13901e04c3fSmrg const char *shader; 14001e04c3fSmrg int ret; 14101e04c3fSmrg struct gl_context gl_ctx; 14201e04c3fSmrg int c; 14301e04c3fSmrg 14401e04c3fSmrg init_fake_gl_context (&gl_ctx); 14501e04c3fSmrg 14601e04c3fSmrg while ((c = getopt_long(argc, argv, "d", long_options, NULL)) != -1) { 14701e04c3fSmrg switch (c) { 14801e04c3fSmrg case DISABLE_LINE_CONTINUATIONS_OPT: 14901e04c3fSmrg gl_ctx.Const.DisableGLSLLineContinuations = true; 15001e04c3fSmrg break; 15101e04c3fSmrg case 'd': 15201e04c3fSmrg glcpp_parser_debug = 1; 15301e04c3fSmrg break; 15401e04c3fSmrg default: 15501e04c3fSmrg usage (); 15601e04c3fSmrg exit (1); 15701e04c3fSmrg } 15801e04c3fSmrg } 15901e04c3fSmrg 16001e04c3fSmrg if (optind + 1 < argc) { 16101e04c3fSmrg printf ("Unexpected argument: %s\n", argv[optind+1]); 16201e04c3fSmrg usage (); 16301e04c3fSmrg exit (1); 16401e04c3fSmrg } 16501e04c3fSmrg if (optind < argc) { 16601e04c3fSmrg filename = argv[optind]; 16701e04c3fSmrg } 16801e04c3fSmrg 16901e04c3fSmrg shader = load_text_file (ctx, filename); 17001e04c3fSmrg if (shader == NULL) 17101e04c3fSmrg return 1; 17201e04c3fSmrg 17301e04c3fSmrg _mesa_locale_init(); 17401e04c3fSmrg 17501e04c3fSmrg ret = glcpp_preprocess(ctx, &shader, &info_log, NULL, NULL, &gl_ctx); 17601e04c3fSmrg 17701e04c3fSmrg printf("%s", shader); 17801e04c3fSmrg fprintf(stderr, "%s", info_log); 17901e04c3fSmrg 18001e04c3fSmrg ralloc_free(ctx); 18101e04c3fSmrg 18201e04c3fSmrg return ret; 18301e04c3fSmrg} 184