Logo Search packages:      
Sourcecode: vala version File versions

valaccodecompiler.c

/* valaccodecompiler.vala
 *
 * Copyright (C) 2007  Jürg Billeter
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.

 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.

 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
 *
 * Author:
 *    Jürg Billeter <j@bitron.ch>
 */

#include "valaccodecompiler.h"
#include <vala/valareport.h>
#include <vala/valasourcereference.h>
#include <gee/collection.h>
#include <vala/valasourcefile.h>
#include <glib/gstdio.h>

enum  {
      VALA_CCODE_COMPILER_DUMMY_PROPERTY
};
static gpointer vala_ccode_compiler_parent_class = NULL;


ValaCCodeCompiler* vala_ccode_compiler_new (void)
{
      ValaCCodeCompiler * self;
      self = g_object_newv (VALA_TYPE_CCODE_COMPILER, 0, NULL);
      return self;
}


/**
 * Compile generated C code to object code and optionally link object
 * files.
 *
 * @param context a code context
 */
void vala_ccode_compiler_compile (ValaCCodeCompiler* self, ValaCodeContext* context, const char* cc_command, char** cc_options)
{
      GError * inner_error;
      char* pc;
      char* __temp1;
      char* pkgflags;
      gint exit_status;
      const char* __temp6;
      char* cmdline;
      char* __temp9;
      char* __temp8;
      char* __temp15;
      char* __temp14;
      GeeCollection* source_files;
      g_return_if_fail (VALA_IS_CCODE_COMPILER (self));
      g_return_if_fail (VALA_IS_CODE_CONTEXT (context));
      inner_error = NULL;
      pc = g_strdup ("pkg-config --cflags");
      if (!vala_code_context_get_compile_only (context)) {
            char* __temp0;
            __temp0 = NULL;
            pc = (__temp0 = g_strconcat (pc, (" --libs"), NULL), (pc = (g_free (pc), NULL)), __temp0);
      }
      __temp1 = NULL;
      pc = (__temp1 = g_strconcat (pc, (" gobject-2.0"), NULL), (pc = (g_free (pc), NULL)), __temp1);
      if (vala_code_context_get_thread (context)) {
            char* __temp2;
            __temp2 = NULL;
            pc = (__temp2 = g_strconcat (pc, (" gthread-2.0"), NULL), (pc = (g_free (pc), NULL)), __temp2);
      }
      {
            GeeCollection* pkg_collection;
            GeeIterator* pkg_it;
            pkg_collection = vala_code_context_get_packages (context);
            pkg_it = gee_iterable_iterator (GEE_ITERABLE (pkg_collection));
            while (gee_iterator_next (pkg_it)) {
                  char* pkg;
                  pkg = gee_iterator_get (pkg_it);
                  {
                        char* __temp4;
                        char* __temp3;
                        __temp4 = NULL;
                        __temp3 = NULL;
                        pc = (__temp4 = g_strconcat (pc, (__temp3 = (g_strconcat (" ", pkg, NULL))), NULL), (pc = (g_free (pc), NULL)), __temp4);
                        (__temp3 = (g_free (__temp3), NULL));
                        (pkg = (g_free (pkg), NULL));
                  }
            }
            (pkg_collection == NULL ? NULL : (pkg_collection = (g_object_unref (pkg_collection), NULL)));
            (pkg_it == NULL ? NULL : (pkg_it = (g_object_unref (pkg_it), NULL)));
      }
      pkgflags = NULL;
      exit_status = 0;
      {
            g_spawn_command_line_sync (pc, &pkgflags, NULL, &exit_status, &inner_error);
            if (inner_error != NULL) {
                  if (inner_error->domain == G_SPAWN_ERROR) {
                        goto __catch0_g_spawn_error;
                  }
                  g_critical ("file %s: line %d: uncaught error: %s", __FILE__, __LINE__, inner_error->message);
                  g_clear_error (&inner_error);
            }
            if (exit_status != 0) {
                  char* __temp5;
                  __temp5 = NULL;
                  vala_report_error (NULL, (__temp5 = g_strdup_printf ("pkg-config exited with status %d", exit_status)));
                  (__temp5 = (g_free (__temp5), NULL));
                  (pc = (g_free (pc), NULL));
                  (pkgflags = (g_free (pkgflags), NULL));
                  return;
            }
      }
      goto __finally0;
      __catch0_g_spawn_error:
      {
            GError * e;
            e = inner_error;
            inner_error = NULL;
            {
                  vala_report_error (NULL, e->message);
                  (pc = (g_free (pc), NULL));
                  (pkgflags = (g_free (pkgflags), NULL));
                  return;
            }
      }
      __finally0:
      ;
      /* TODO compile the C code files in parallel*/
      if (cc_command == NULL) {
            cc_command = "cc";
      }
      __temp6 = NULL;
      cmdline = (__temp6 = cc_command, (__temp6 == NULL ? NULL : g_strdup (__temp6)));
      if (vala_code_context_get_debug (context)) {
            char* __temp7;
            __temp7 = NULL;
            cmdline = (__temp7 = g_strconcat (cmdline, (" -g"), NULL), (cmdline = (g_free (cmdline), NULL)), __temp7);
      }
      __temp9 = NULL;
      __temp8 = NULL;
      cmdline = (__temp9 = g_strconcat (cmdline, (__temp8 = (g_strdup_printf (" -O%d", vala_code_context_get_optlevel (context)))), NULL), (cmdline = (g_free (cmdline), NULL)), __temp9);
      (__temp8 = (g_free (__temp8), NULL));
      if (vala_code_context_get_compile_only (context)) {
            char* __temp10;
            __temp10 = NULL;
            cmdline = (__temp10 = g_strconcat (cmdline, (" -c"), NULL), (cmdline = (g_free (cmdline), NULL)), __temp10);
      } else {
            if (vala_code_context_get_output (context) != NULL) {
                  char* __temp13;
                  char* __temp12;
                  char* __temp11;
                  __temp13 = NULL;
                  __temp12 = NULL;
                  __temp11 = NULL;
                  cmdline = (__temp13 = g_strconcat (cmdline, (__temp12 = (g_strconcat (" -o ", (__temp11 = g_shell_quote (vala_code_context_get_output (context))), NULL))), NULL), (cmdline = (g_free (cmdline), NULL)), __temp13);
                  (__temp12 = (g_free (__temp12), NULL));
                  (__temp11 = (g_free (__temp11), NULL));
            }
      }
      __temp15 = NULL;
      __temp14 = NULL;
      cmdline = (__temp15 = g_strconcat (cmdline, (__temp14 = (g_strconcat (" ", pkgflags, NULL))), NULL), (cmdline = (g_free (cmdline), NULL)), __temp15);
      (__temp14 = (g_free (__temp14), NULL));
      if (cc_options != NULL) {
            {
                  char** cc_option_collection;
                  char** cc_option_it;
                  cc_option_collection = cc_options;
                  for (cc_option_it = cc_option_collection; *cc_option_it != NULL; cc_option_it = cc_option_it + 1) {
                        const char* __temp18;
                        char* cc_option;
                        __temp18 = NULL;
                        cc_option = (__temp18 = *cc_option_it, (__temp18 == NULL ? NULL : g_strdup (__temp18)));
                        {
                              char* __temp17;
                              char* __temp16;
                              __temp17 = NULL;
                              __temp16 = NULL;
                              cmdline = (__temp17 = g_strconcat (cmdline, (__temp16 = (g_strconcat (" ", cc_option, NULL))), NULL), (cmdline = (g_free (cmdline), NULL)), __temp17);
                              (__temp16 = (g_free (__temp16), NULL));
                              (cc_option = (g_free (cc_option), NULL));
                        }
                  }
            }
      }
      /* we're only interested in non-pkg source files */
      source_files = vala_code_context_get_source_files (context);
      {
            GeeCollection* file_collection;
            GeeIterator* file_it;
            file_collection = source_files;
            file_it = gee_iterable_iterator (GEE_ITERABLE (file_collection));
            while (gee_iterator_next (file_it)) {
                  ValaSourceFile* file;
                  file = gee_iterator_get (file_it);
                  {
                        if (!vala_source_file_get_pkg (file)) {
                              char* __temp22;
                              char* __temp21;
                              char* __temp20;
                              char* __temp19;
                              __temp22 = NULL;
                              __temp21 = NULL;
                              __temp20 = NULL;
                              __temp19 = NULL;
                              cmdline = (__temp22 = g_strconcat (cmdline, (__temp21 = (g_strconcat (" ", (__temp20 = g_shell_quote ((__temp19 = vala_source_file_get_csource_filename (file)))), NULL))), NULL), (cmdline = (g_free (cmdline), NULL)), __temp22);
                              (__temp21 = (g_free (__temp21), NULL));
                              (__temp20 = (g_free (__temp20), NULL));
                              (__temp19 = (g_free (__temp19), NULL));
                        }
                        (file == NULL ? NULL : (file = (g_object_unref (file), NULL)));
                  }
            }
            (file_it == NULL ? NULL : (file_it = (g_object_unref (file_it), NULL)));
      }
      {
            g_spawn_command_line_sync (cmdline, NULL, NULL, &exit_status, &inner_error);
            if (inner_error != NULL) {
                  if (inner_error->domain == G_SPAWN_ERROR) {
                        goto __catch1_g_spawn_error;
                  }
                  g_critical ("file %s: line %d: uncaught error: %s", __FILE__, __LINE__, inner_error->message);
                  g_clear_error (&inner_error);
            }
            if (exit_status != 0) {
                  char* __temp23;
                  __temp23 = NULL;
                  vala_report_error (NULL, (__temp23 = g_strdup_printf ("cc exited with status %d", exit_status)));
                  (__temp23 = (g_free (__temp23), NULL));
            }
      }
      goto __finally1;
      __catch1_g_spawn_error:
      {
            GError * e;
            e = inner_error;
            inner_error = NULL;
            {
                  vala_report_error (NULL, e->message);
            }
      }
      __finally1:
      ;
      {
            GeeCollection* file_collection;
            GeeIterator* file_it;
            file_collection = source_files;
            file_it = gee_iterable_iterator (GEE_ITERABLE (file_collection));
            while (gee_iterator_next (file_it)) {
                  ValaSourceFile* file;
                  file = gee_iterator_get (file_it);
                  {
                        /* remove generated C source and header files */
                        if (!vala_source_file_get_pkg (file)) {
                              char* __temp24;
                              char* __temp25;
                              __temp24 = NULL;
                              g_unlink ((__temp24 = vala_source_file_get_csource_filename (file)));
                              (__temp24 = (g_free (__temp24), NULL));
                              __temp25 = NULL;
                              g_unlink ((__temp25 = vala_source_file_get_cheader_filename (file)));
                              (__temp25 = (g_free (__temp25), NULL));
                        }
                        (file == NULL ? NULL : (file = (g_object_unref (file), NULL)));
                  }
            }
            (file_it == NULL ? NULL : (file_it = (g_object_unref (file_it), NULL)));
      }
      (pc = (g_free (pc), NULL));
      (pkgflags = (g_free (pkgflags), NULL));
      (cmdline = (g_free (cmdline), NULL));
      (source_files == NULL ? NULL : (source_files = (g_object_unref (source_files), NULL)));
}


static void vala_ccode_compiler_class_init (ValaCCodeCompilerClass * klass)
{
      vala_ccode_compiler_parent_class = g_type_class_peek_parent (klass);
}


static void vala_ccode_compiler_init (ValaCCodeCompiler * self)
{
}


GType vala_ccode_compiler_get_type (void)
{
      static GType vala_ccode_compiler_type_id = 0;
      if (G_UNLIKELY (vala_ccode_compiler_type_id == 0)) {
            static const GTypeInfo g_define_type_info = { sizeof (ValaCCodeCompilerClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) vala_ccode_compiler_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (ValaCCodeCompiler), 0, (GInstanceInitFunc) vala_ccode_compiler_init };
            vala_ccode_compiler_type_id = g_type_register_static (G_TYPE_OBJECT, "ValaCCodeCompiler", &g_define_type_info, 0);
      }
      return vala_ccode_compiler_type_id;
}





Generated by  Doxygen 1.6.0   Back to index