Commit 405b0c4f authored by Jürg Billeter's avatar Jürg Billeter Committed by Jürg Billeter

support file comments, BREAK, CONTINUE support break and continue, add

2006-05-21  Jürg Billeter  <j@bitron.ch>

	* vala/scanner.l: support file comments, BREAK, CONTINUE
	* vala/parser.y: support break and continue, add more comments
	* vala/valacodecontext.vala: find cyclic header dependencies
	* vala/valasourcefile.vala: add get_namespaces method, add dependency
	  information, add add_symbol_dependency method, add
	  SourceFileDependencyType enum
	* vala/valasourcefilecycle.vala
	* vala/valacodevisitor.vala: support break and continue statements
	* vala/valaparser.vala: support file comments
	* vala/valasemanticanalyzer.vala: record dependency information
	* vala/valacodegenerator.vala: add include directives, type forward
	  declarations, once section, enum values, method return types, and more
	  comments
	* vala/valablock.vala, vala/valadeclarationstatement.vala,
	  vala/valaemptystatement.vala, vala/valaexpressionstatement.vala,
	  vala/valaforeachstatement.vala, vala/valaforstatement.vala,
	  vala/valaifstatement.vala, vala/valareturnstatement.vala,
	  vala/valastatement.vala, vala/valawhilestatement.vala: move
	  source_reference property to Statement class
	* vala/valaclass.vala, vala/valaenum.vala, vala/valastruct.vala,
	  vala/valatype.vala: move name, source_reference, namespace, and
	  get_cheader_filenames to Type class
	* vala/valabreakstatement.vala
	* vala/valacontinuestatement.vala
	* vala/valaenum.vala: fix cname, add get_upper_case_cname method
	* vala/valaenumvalue.vala: add get_cname method
	* vala/valafield.vala: add access field
	* vala/valanamespace.vala: add get_structs, get_classes, and
	  get_cheader_filenames methods, support cheader_filename attribute
	* vala/valastruct.vala: support cheader_filename attribute
	* vala/valatypereference.vala: support void cname
	* vala/vala.h: update
	* ccode/valaccodeblock.vala: support comments before statements
	* ccode/valaccodeenum.vala: optionally use typedef
	* ccode/valaccodefunction.vala: add copy method
	* ccode/valaccodenewline.vala
	* ccode/valaccodeoncesection.vala
	* ccode/valaccodewriter.vala: use whole line for comments
	* bindings/glib-2.0.vala: add cheader_filename attributes, extend string
	  types
	* valac/generator.c: fix private field access, include string.h

svn path=/trunk/; revision=31
parent 5c602d5a
2006-05-21 Jürg Billeter <j@bitron.ch>
* vala/scanner.l: support file comments, BREAK, CONTINUE
* vala/parser.y: support break and continue, add more comments
* vala/valacodecontext.vala: find cyclic header dependencies
* vala/valasourcefile.vala: add get_namespaces method, add dependency
information, add add_symbol_dependency method, add
SourceFileDependencyType enum
* vala/valasourcefilecycle.vala
* vala/valacodevisitor.vala: support break and continue statements
* vala/valaparser.vala: support file comments
* vala/valasemanticanalyzer.vala: record dependency information
* vala/valacodegenerator.vala: add include directives, type forward
declarations, once section, enum values, method return types, and more
comments
* vala/valablock.vala, vala/valadeclarationstatement.vala,
vala/valaemptystatement.vala, vala/valaexpressionstatement.vala,
vala/valaforeachstatement.vala, vala/valaforstatement.vala,
vala/valaifstatement.vala, vala/valareturnstatement.vala,
vala/valastatement.vala, vala/valawhilestatement.vala: move
source_reference property to Statement class
* vala/valaclass.vala, vala/valaenum.vala, vala/valastruct.vala,
vala/valatype.vala: move name, source_reference, namespace, and
get_cheader_filenames to Type class
* vala/valabreakstatement.vala
* vala/valacontinuestatement.vala
* vala/valaenum.vala: fix cname, add get_upper_case_cname method
* vala/valaenumvalue.vala: add get_cname method
* vala/valafield.vala: add access field
* vala/valanamespace.vala: add get_structs, get_classes, and
get_cheader_filenames methods, support cheader_filename attribute
* vala/valastruct.vala: support cheader_filename attribute
* vala/valatypereference.vala: support void cname
* vala/vala.h: update
* ccode/valaccodeblock.vala: support comments before statements
* ccode/valaccodeenum.vala: optionally use typedef
* ccode/valaccodefunction.vala: add copy method
* ccode/valaccodenewline.vala
* ccode/valaccodeoncesection.vala
* ccode/valaccodewriter.vala: use whole line for comments
* bindings/glib-2.0.vala: add cheader_filename attributes, extend string
types
* valac/generator.c: fix private field access, include string.h
2006-05-19 Jürg Billeter <j@bitron.ch>
* vala/valacodegenerator.vala: include header file in corresponding
......
......@@ -20,85 +20,93 @@
* Jürg Billeter <j@bitron.ch>
*/
[CCode (cname = "gboolean")]
[CCode (cname = "gboolean", cheader_filename = "glib.h")]
public struct bool {
}
[CCode (cname = "gpointer")]
[CCode (cname = "gpointer", cheader_filename = "glib.h")]
public struct pointer {
}
[CCode (cheader_filename = "glib.h")]
public struct char {
}
[CCode (cname = "unsigned char")]
[CCode (cname = "unsigned char", cheader_filename = "glib.h")]
public struct uchar {
}
[CCode (cheader_filename = "glib.h")]
public struct int {
}
[CCode (cname = "unsigned int")]
[CCode (cname = "unsigned int", cheader_filename = "glib.h")]
public struct uint {
}
[CCode (cheader_filename = "glib.h")]
public struct short {
}
[CCode (cname = "unsigned short")]
[CCode (cname = "unsigned short", cheader_filename = "glib.h")]
public struct ushort {
}
[CCode (cheader_filename = "glib.h")]
public struct long {
}
[CCode (cname = "unsigned long")]
[CCode (cname = "unsigned long", cheader_filename = "glib.h")]
public struct ulong {
}
[CCode (cname = "gint8")]
[CCode (cname = "gint8", cheader_filename = "glib.h")]
public struct int8 {
}
[CCode (cname = "guint8")]
[CCode (cname = "guint8", cheader_filename = "glib.h")]
public struct uint8 {
}
[CCode (cname = "gint16")]
[CCode (cname = "gint16", cheader_filename = "glib.h")]
public struct int16 {
}
[CCode (cname = "guint16")]
[CCode (cname = "guint16", cheader_filename = "glib.h")]
public struct uint16 {
}
[CCode (cname = "gint32")]
[CCode (cname = "gint32", cheader_filename = "glib.h")]
public struct int32 {
}
[CCode (cname = "guint32")]
[CCode (cname = "guint32", cheader_filename = "glib.h")]
public struct uint32 {
}
[CCode (cname = "gint64")]
[CCode (cname = "gint64", cheader_filename = "glib.h")]
public struct int64 {
}
[CCode (cname = "guint64")]
[CCode (cname = "guint64", cheader_filename = "glib.h")]
public struct uint64 {
}
[CCode (cname = "gunichar")]
[CCode (cname = "gunichar", cheader_filename = "glib.h")]
public struct unichar {
[CCode (cname = "g_unichar_isalnum")]
public bool isalnum ();
[CCode (cname = "g_unichar_isupper")]
public bool isupper ();
[CCode (cname = "g_unichar_toupper")]
public unichar toupper ();
[CCode (cname = "g_unichar_tolower")]
public unichar tolower ();
}
[ReferenceType ()]
[AllowPointerArithmetic ()]
[CCode (cname = "char")]
[CCode (cname = "char", cheader_filename = "string.h,glib.h")]
public struct astring {
[CCode (cname = "g_str_has_suffix")]
public bool has_suffix (string suffix);
......@@ -123,7 +131,7 @@ public struct astring {
}
[ReferenceType ()]
[CCode (cname = "char")]
[CCode (cname = "char", cheader_filename = "string.h,glib.h")]
public struct string {
[CCode (cname = "g_str_has_suffix")]
public bool has_suffix (string suffix);
......@@ -135,6 +143,9 @@ public struct string {
public ref string ndup (int n);
[CCode (cname = "g_strcompress")]
public ref string compress ();
[CCode (cname = "g_strsplit")]
public ref string[] split (string delimiter, int max_tokens /* = 0 */);
[CCode (cname = "g_utf8_next_char")]
public string next_char ();
[CCode (cname = "g_utf8_get_char")]
......@@ -142,10 +153,14 @@ public struct string {
[CCode (cname = "g_utf8_offset_to_pointer")]
[PlusOperator ()]
public string offset (long offset);
[CCode (cname = "g_utf8_pointer_to_offset")]
public long pointer_to_offset (string pos);
[CCode (cname = "g_utf8_prev_char")]
public string prev_char ();
[CCode (cname = "g_utf8_strlen")]
public long len (long max /*= -1*/);
[CCode (cname = "g_utf8_strchr")]
public string chr (long len, unichar c);
[CCode (cname = "g_utf8_strup")]
public ref string up (long len /*= -1*/);
......@@ -154,7 +169,7 @@ public struct string {
}
[Import ()]
[CCode (cprefix = "G", lower_case_cprefix = "g_", include_filename = "glib.h")]
[CCode (cprefix = "G", lower_case_cprefix = "g_", cheader_filename = "glib.h")]
namespace GLib {
public struct Path {
public static ref string get_basename (string file_name);
......@@ -168,7 +183,8 @@ namespace GLib {
public struct ObjectConstructParam {
}
public class Object {
[CCode (cheader_filename = "glib-object.h")]
public abstract class Object {
public virtual Object constructor (Type type, uint n_construct_properties, ObjectConstructParam[] construct_properties);
}
......@@ -176,8 +192,10 @@ namespace GLib {
public struct Error {
}
public static void return_if_fail (bool expr);
[ReferenceType ()]
[CCode (cname = "FILE")]
[CCode (cname = "FILE", cheader_filename = "stdio.h")]
public struct File {
[CCode (cname = "fopen")]
public static ref File open (string path, string mode);
......@@ -193,7 +211,7 @@ namespace GLib {
public void close ();
}
[CCode (cname = "stderr")]
[CCode (cname = "stderr", cheader_filename = "stdio.h")]
public static GLib.File stderr;
[Unknown (reference_type = true)]
......@@ -268,6 +286,8 @@ namespace GLib {
public pointer nth_data (uint n);
public List<G> nth_prev (uint n);
public List<G> find_custom (G data, CompareFunc func);
public List<G> find (G data);
public int position (List<G> llink);
public int index (G data);
......@@ -277,6 +297,12 @@ namespace GLib {
public List<G> prev;
}
public struct CompareFunc {
}
[CCode (cname = "strcmp")]
public static GLib.CompareFunc strcmp;
[ReferenceType ()]
public struct HashTable<K,V> {
public static ref HashTable new (HashFunc hash_func, EqualFunc key_equal_func);
......@@ -298,8 +324,10 @@ namespace GLib {
[ReferenceType ()]
public struct String {
public static ref String new (string init);
public void append_c (char c);
public void append_unichar (unichar wc);
public String append (string val);
public String append_c (char c);
public String append_unichar (unichar wc);
public String erase (long pos, long len);
public string str;
public long len;
......
......@@ -24,15 +24,16 @@ using GLib;
namespace Vala {
public class CCodeBlock : CCodeStatement {
ref List<ref CCodeStatement> statements;
List<CCodeNode> statements;
public void add_statement (string statement) {
public void add_statement (CCodeNode statement) {
/* allow generic nodes to include comments */
statements.append (statement);
}
public override void write (CCodeWriter writer) {
writer.write_begin_block ();
foreach (CCodeStatement statement in statements) {
foreach (CCodeNode statement in statements) {
if (statement != null) {
statement.write (writer);
}
......
......@@ -28,20 +28,32 @@ namespace Vala {
List<string> values;
public void add_value (string name, string value) {
values.append ("%s = %s".printf (name, value));
if (value == null) {
values.append (name);
} else {
values.append ("%s = %s".printf (name, value));
}
}
public override void write (CCodeWriter writer) {
if (name != null) {
writer.write_string ("typedef ");
}
writer.write_string ("enum ");
writer.write_string (name);
writer.write_begin_block ();
foreach (string value in values) {
writer.write_indent ();
writer.write_string (value);
writer.write_string (",\n");
writer.write_string (",");
writer.write_newline ();
}
writer.write_end_block ();
writer.write_string (";\n");
if (name != null) {
writer.write_string (" ");
writer.write_string (name);
}
writer.write_string (";");
writer.write_newline ();
}
}
}
......@@ -34,8 +34,16 @@ namespace Vala {
parameters.append (param);
}
public ref CCodeFunction copy () {
var func = new CCodeFunction (name = name, return_type = return_type);
func.modifiers = modifiers;
func.parameters = parameters.copy ();
func.block = block;
return func;
}
public override void write (CCodeWriter writer) {
writer.write_newline ();
writer.write_indent ();
if ((modifiers & CCodeModifiers.STATIC) == CCodeModifiers.STATIC) {
writer.write_string ("static ");
}
......@@ -60,6 +68,7 @@ namespace Vala {
} else {
writer.write_newline ();
block.write (writer);
writer.write_newline ();
}
writer.write_newline ();
}
......
/* valaccodenewline.vala
*
* Copyright (C) 2006 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>
*/
using GLib;
namespace Vala {
public class CCodeNewline : CCodeNode {
public override void write (CCodeWriter writer) {
writer.write_newline ();
}
}
}
/* valaccodeoncesection.vala
*
* Copyright (C) 2006 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>
*/
using GLib;
namespace Vala {
public class CCodeOnceSection : CCodeFragment {
public string define { get; construct; }
public override void write (CCodeWriter writer) {
writer.write_indent ();
writer.write_string ("#ifndef ");
writer.write_string (define);
writer.write_newline ();
writer.write_string ("#define ");
writer.write_string (define);
writer.write_newline ();
foreach (CCodeNode node in children) {
node.write (writer);
}
writer.write_indent ();
writer.write_string ("#endif");
writer.write_newline ();
}
}
}
......@@ -74,7 +74,9 @@ namespace Vala {
}
public void write_comment (string text) {
write_indent ();
stream.printf ("/*%s*/", text);
write_newline ();
}
}
}
......@@ -137,9 +137,11 @@ static void yyerror (YYLTYPE *locp, ValaParser *parser, const char *msg);
%token PERCENT "%"
%token ABSTRACT "abstract"
%token BREAK "break"
%token CLASS "class"
%token CONST "const"
%token CONSTRUCT "construct"
%token CONTINUE "continue"
%token ELSE "else"
%token ENUM "enum"
%token VALA_FALSE "false"
......@@ -229,6 +231,8 @@ static void yyerror (YYLTYPE *locp, ValaParser *parser, const char *msg);
%type <list> statement_expression_list
%type <statement> foreach_statement
%type <statement> jump_statement
%type <statement> break_statement
%type <statement> continue_statement
%type <statement> return_statement
%type <namespace> namespace_declaration
%type <class> class_declaration
......@@ -323,10 +327,7 @@ boolean_literal
;
compilation_unit
: comment opt_using_directives opt_outer_declarations
{
current_source_file->comment = $1;
}
: opt_using_directives opt_outer_declarations
;
type_name
......@@ -659,6 +660,7 @@ opt_expression
expression
: conditional_expression
| assignment
;
statement
......@@ -709,9 +711,9 @@ empty_statement
;
declaration_statement
: local_variable_declaration
: comment local_variable_declaration
{
$$ = VALA_STATEMENT (vala_declaration_statement_new ($1, src(@1)));
$$ = VALA_STATEMENT (vala_declaration_statement_new ($2, src_com(@2, $1)));
}
;
......@@ -749,9 +751,9 @@ local_variable_type
;
expression_statement
: statement_expression SEMICOLON
: comment statement_expression SEMICOLON
{
$$ = VALA_STATEMENT (vala_expression_statement_new ($1, src(@1)));
$$ = VALA_STATEMENT (vala_expression_statement_new ($2, src_com(@2, $1)));
}
;
......@@ -825,7 +827,23 @@ foreach_statement
;
jump_statement
: return_statement
: break_statement
| continue_statement
| return_statement
;
break_statement
: BREAK SEMICOLON
{
$$ = VALA_STATEMENT (vala_break_statement_new (src(@1)));
}
;
continue_statement
: CONTINUE SEMICOLON
{
$$ = VALA_STATEMENT (vala_continue_statement_new (src(@1)));
}
;
return_statement
......@@ -929,6 +947,7 @@ class_declaration
{
GList *l;
current_struct = VALA_STRUCT (vala_class_new ($6, src_com (@6, $1)));
VALA_CODE_NODE(current_struct)->attributes = $2;
for (l = $7; l != NULL; l = l->next) {
vala_struct_add_type_parameter (current_struct, l->data);
}
......@@ -938,7 +957,7 @@ class_declaration
}
class_body
{
$$ = current_struct;
$$ = VALA_CLASS (current_struct);
current_struct = NULL;
}
;
......@@ -1077,6 +1096,9 @@ field_declaration
: comment opt_attributes opt_access_modifier opt_modifiers opt_ref type variable_declarator SEMICOLON
{
$$ = vala_field_new (vala_variable_declarator_get_name ($7), $6, vala_variable_declarator_get_initializer ($7), src_com (@6, $1));
if ($3 != 0) {
$$->access = $3;
}
}
;
......
......@@ -28,6 +28,8 @@
#define YY_DECL int yylex (YYSTYPE *yylval_param, YYLTYPE *yylloc_param, ValaParser *parser)
#define uploc { yylloc->first_column = yylloc->last_column + 1; yylloc->last_column += strlen (yytext); }
static gboolean file_comment = FALSE;
%}
%option yylineno
......@@ -47,13 +49,13 @@ literal ({literal_integer}|{literal_character}|{literal_string})
%%
"/*" { uploc; BEGIN (IN_COMMENT); }
<IN_COMMENT>[^*\n]* { uploc; yymore (); }
<IN_COMMENT>"*"+[^*/\n]* { uploc; yymore (); }
"/*" { uploc; file_comment = (yylineno == 1); BEGIN (IN_COMMENT); }
<IN_COMMENT>"*/" { uploc; BEGIN (INITIAL); yytext[strlen (yytext) - 2] = '\0'; vala_parser_push_comment (parser, g_strdup (yytext), file_comment); }
<IN_COMMENT>[^*\n]+ { uploc; yymore (); }
<IN_COMMENT>"*" { uploc; yymore (); }
<IN_COMMENT>\n { yylloc->first_line = yylloc->last_line = yylineno; yylloc->first_column = 1; yylloc->last_column = 0; yymore (); }
<IN_COMMENT>"*/" { uploc; BEGIN (INITIAL); yytext[strlen (yytext) - 2] = '\0'; vala_parser_push_comment (parser, g_strdup (yytext)); }
"//".* { uploc; vala_parser_push_comment (parser, g_strdup (yytext + 2)); }
"//".* { uploc; vala_parser_push_comment (parser, g_strdup (yytext + 2), FALSE); }
"{" { uploc; return OPEN_BRACE; }
"}" { uploc; return CLOSE_BRACE; }
......@@ -108,9 +110,11 @@ literal ({literal_integer}|{literal_character}|{literal_string})
"@"[[:alnum:]_]+ { uploc; yylval->str = strdup (yytext + 1); return IDENTIFIER; }
"abstract" { uploc; return ABSTRACT; }
"break" { uploc; return BREAK; }
"class" { uploc; return CLASS; }
"const" { uploc; return CONST; }
"construct" { uploc; return CONSTRUCT; }
"continue" { uploc; return CONTINUE; }
"else" { uploc; return ELSE; }
"enum" { uploc; return ENUM; }
"false" { uploc; return VALA_FALSE; }
......
......@@ -3,12 +3,14 @@
#include <vala/valabinaryexpression.h>
#include <vala/valablock.h>
#include <vala/valabooleanliteral.h>
#include <vala/valabreakstatement.h>
#include <vala/valacastexpression.h>
#include <vala/valacharacterliteral.h>
#include <vala/valaclass.h>
#include <vala/valacodecontext.h>
#include <vala/valaconditionalexpression.h>
#include <vala/valaconstant.h>
#include <vala/valacontinuestatement.h>
#include <vala/valadeclarationstatement.h>
#include <vala/valaemptystatement.h>
#include <vala/valaenum.h>
......
......@@ -25,7 +25,6 @@ using GLib;
namespace Vala {
public class Block : Statement {
public List<Statement> statement_list { get; construct; }
public SourceReference source_reference { get; construct; }
public static ref Block new (List<Statement> statement_list, SourceReference source) {
return (new Block (statement_list = statement_list, source_reference = source));
......
/* valabreakstatement.vala
*
* Copyright (C) 2006 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>
*/
using GLib;
namespace Vala {
public class BreakStatement : Statement {
public static ref BreakStatement new (SourceReference source) {
return (new BreakStatement (source_reference = source));
}
public override void accept (CodeVisitor visitor) {
visitor.visit_break_statement (this);
}
}
}
......@@ -24,7 +24,6 @@ using GLib;
namespace Vala {
public class Class : Struct {
public SourceReference source_reference { get; construct; }
public List<TypeReference> base_types;
public Class base_class;
......
......@@ -27,6 +27,8 @@ namespace Vala {
List<SourceFile> source_files;
public Symbol root = new Symbol ();
List<SourceFileCycle> cycles;
public ref List<SourceFile> get_source_files () {
return source_files.copy ();
}
......@@ -40,5 +42,117 @@ namespace Vala {
file.accept (visitor);
}
}
public void find_header_cycles () {
/* find cycles in dependencies between source files */
foreach (SourceFile file in source_files) {
/* we're only interested in internal source files */
if (!file.pkg) {
if (file.mark == 0) {
visit (file, null);
}
}
}
/* find one head for each cycle, it must not have any
* hard dependencies on other files in the cycle
*/
foreach (SourceFileCycle cycle in cycles) {
cycle.head = find_cycle_head ((SourceFile) cycle.files.data);
cycle.head.is_cycle_head = true;
}
/* connect the source files in a non-cyclic way
* cycle members connect to the head of their cycle
*/
foreach (SourceFile file2 in source_files) {
/* we're only interested in internal source files */
if (!file2.pkg) {
foreach (SourceFile dep in file2.header_internal_dependencies) {
if (file2.cycle != null && dep.cycle == file2.cycle) {
/* in the same cycle */
if (!file2.is_cycle_head) {
/* include header of cycle head */
file2.header_internal_includes.append (file2.cycle.head.get_cheader_filename ());
}
} else {
/* we can just include the headers if they are not in a cycle or not in the same cycle as the current file */
file2.header_internal_includes.append (dep.get_cheader_filename ());
}
}
}
}
}
private SourceFile find_cycle_head (SourceFile file) {
foreach (SourceFile dep in file.header_internal_full_dependencies) {
foreach (SourceFile cycle_file in file.cycle.files) {
if (dep == cycle_file) {
return find_cycle_head (dep);
}
}
}
/* no hard dependencies on members of the same cycle found
* source file suitable as cycle head
*/
return file;
}
private void visit (SourceFile file, List<SourceFile> chain) {
var l = chain.copy ();
l.append (file);
/* mark file as currently being visited */
file.mark = 1;
foreach (SourceFile dep in file.header_internal_dependencies) {
if (file != dep) {
if (dep.mark == 1) {
/* found cycle */
var cycle = new SourceFileCycle ();
cycles.append (cycle);
bool cycle_start_found = false;
foreach (SourceFile cycle_file in l) {
if (!cycle_start_found) {