LCOV - code coverage report
Current view: top level - ccode - valaccodefunction.vala (source / functions) Coverage Total Hit
Test: vala 0.57.0.298-a8cae1 Lines: 98.9 % 175 173
Test Date: 2024-04-25 11:34:36 Functions: - 0 0

            Line data    Source code
       1              : /* valaccodefunction.vala
       2              :  *
       3              :  * Copyright (C) 2006-2012  Jürg Billeter
       4              :  *
       5              :  * This library is free software; you can redistribute it and/or
       6              :  * modify it under the terms of the GNU Lesser General Public
       7              :  * License as published by the Free Software Foundation; either
       8              :  * version 2.1 of the License, or (at your option) any later version.
       9              : 
      10              :  * This library is distributed in the hope that it will be useful,
      11              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      12              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13              :  * Lesser General Public License for more details.
      14              : 
      15              :  * You should have received a copy of the GNU Lesser General Public
      16              :  * License along with this library; if not, write to the Free Software
      17              :  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
      18              :  *
      19              :  * Author:
      20              :  *      Jürg Billeter <j@bitron.ch>
      21              :  */
      22              : 
      23              : using GLib;
      24              : 
      25              : /**
      26              :  * Represents a function declaration in the C code.
      27              :  */
      28       141345 : public class Vala.CCodeFunction : CCodeNode {
      29              :         /**
      30              :          * The name of this function.
      31              :          */
      32       255197 :         public string name { get; set; }
      33              : 
      34              :         /**
      35              :          * The function return type.
      36              :          */
      37       244996 :         public string return_type { get; set; }
      38              : 
      39        58974 :         public bool is_declaration { get; set; }
      40              : 
      41              :         /**
      42              :          * The function body.
      43              :          */
      44       435679 :         public CCodeBlock block { get; set; }
      45              : 
      46              :         /**
      47              :          * The current line directive.
      48              :          */
      49       328719 :         public CCodeLineDirective current_line { get; set; }
      50              : 
      51              :         /**
      52              :          * The current block to be written into.
      53              :          */
      54       292838 :         public CCodeBlock current_block { get; set; }
      55              : 
      56       140460 :         private List<CCodeParameter> parameters = new ArrayList<CCodeParameter> ();
      57              : 
      58       140460 :         List<CCodeStatement> statement_stack = new ArrayList<CCodeStatement> ();
      59              : 
      60       210690 :         public CCodeFunction (string name, string return_type = "void") {
      61        70230 :                 this.name = name;
      62        70230 :                 this.return_type = return_type;
      63        70230 :                 this.block = new CCodeBlock ();
      64        70230 :                 current_block = block;
      65              :         }
      66              : 
      67              :         /**
      68              :          * Appends the specified parameter to the list of function parameters.
      69              :          *
      70              :          * @param param a formal parameter
      71              :          */
      72        61727 :         public void add_parameter (CCodeParameter param) {
      73        61727 :                 parameters.add (param);
      74              :         }
      75              : 
      76            0 :         public void insert_parameter (int position, CCodeParameter param) {
      77            0 :                 parameters.insert (position, param);
      78              :         }
      79              : 
      80           33 :         public int get_parameter_count () {
      81           33 :                 return parameters.size;
      82              :         }
      83              : 
      84           64 :         public CCodeParameter get_parameter (int position) {
      85           64 :                 return parameters[position];
      86              :         }
      87              : 
      88              :         /**
      89              :          * Returns a copy of this function.
      90              :          *
      91              :          * @return copied function
      92              :          */
      93        26318 :         public CCodeFunction copy () {
      94        26318 :                 var func = new CCodeFunction (name, return_type);
      95        26318 :                 func.modifiers = modifiers;
      96              : 
      97              :                 /* no deep copy for lists available yet
      98              :                  * func.parameters = parameters.copy ();
      99              :                  */
     100        91222 :                 foreach (CCodeParameter param in parameters) {
     101        32452 :                         func.parameters.add (param);
     102              :                 }
     103              : 
     104        26318 :                 func.is_declaration = is_declaration;
     105        26318 :                 func.block = block;
     106        26318 :                 return func;
     107              :         }
     108              : 
     109        33000 :         public override void write (CCodeWriter writer) {
     110        33000 :                 writer.write_indent (line);
     111        33000 :                 if (CCodeModifiers.INTERNAL in modifiers) {
     112          418 :                         writer.write_string (GNUC_INTERNAL);
     113        32582 :                 } else if (is_declaration && CCodeModifiers.EXTERN in modifiers) {
     114         7029 :                         writer.write_string ("VALA_EXTERN ");
     115              :                 }
     116        33000 :                 if (!is_declaration && CCodeModifiers.NO_INLINE in modifiers) {
     117            5 :                         writer.write_string (GNUC_NO_INLINE);
     118              :                 }
     119        33000 :                 if (CCodeModifiers.STATIC in modifiers) {
     120        17860 :                         writer.write_string ("static ");
     121              :                 }
     122        33000 :                 if (CCodeModifiers.INLINE in modifiers) {
     123          454 :                         writer.write_string ("inline ");
     124              :                 }
     125        33000 :                 writer.write_string (return_type);
     126        33000 :                 if (is_declaration) {
     127        14056 :                         writer.write_string (" ");
     128              :                 } else {
     129        18944 :                         writer.write_newline ();
     130              :                 }
     131        33000 :                 writer.write_string (name);
     132        33000 :                 writer.write_string (" (");
     133        33000 :                 int param_pos_begin = (is_declaration ? return_type.char_count () + 1 : 0 ) + name.char_count () + 2;
     134              : 
     135        33000 :                 bool has_args = (CCodeModifiers.PRINTF in modifiers || CCodeModifiers.SCANF in modifiers);
     136        33000 :                 int i = 0;
     137        33000 :                 int format_arg_index = -1;
     138        33000 :                 int args_index = -1;
     139       138648 :                 foreach (CCodeParameter param in parameters) {
     140        52824 :                         if (i > 0) {
     141        27235 :                                 writer.write_string (",");
     142        27235 :                                 writer.write_newline ();
     143        27235 :                                 writer.write_nspaces (param_pos_begin);
     144              :                         }
     145        52824 :                         param.write (writer);
     146        52824 :                         if (CCodeModifiers.FORMAT_ARG in param.modifiers) {
     147           46 :                                 format_arg_index = i;
     148              :                         }
     149        52824 :                         if (has_args && param.ellipsis) {
     150              :                                 args_index = i;
     151        52792 :                         } else if (has_args && param.type_name == "va_list" && format_arg_index < 0) {
     152           14 :                                 format_arg_index = i - 1;
     153              :                         }
     154        52824 :                         i++;
     155              :                 }
     156        33000 :                 if (i == 0) {
     157         7411 :                         writer.write_string ("void");
     158              :                 }
     159              : 
     160        33000 :                 writer.write_string (")");
     161              : 
     162        33000 :                 if (is_declaration) {
     163        14056 :                         if (CCodeModifiers.DEPRECATED in modifiers) {
     164           14 :                                 writer.write_string (GNUC_DEPRECATED);
     165              :                         }
     166              : 
     167        14056 :                         if (CCodeModifiers.PRINTF in modifiers) {
     168           21 :                                 format_arg_index = (format_arg_index >= 0 ? format_arg_index + 1 : args_index);
     169           21 :                                 writer.write_string (GNUC_PRINTF.printf (format_arg_index, args_index + 1));
     170        14035 :                         } else if (CCodeModifiers.SCANF in modifiers) {
     171            5 :                                 format_arg_index = (format_arg_index >= 0 ? format_arg_index + 1 : args_index);
     172            5 :                                 writer.write_string (GNUC_SCANF.printf (format_arg_index, args_index + 1));
     173        14030 :                         } else if (format_arg_index >= 0) {
     174            5 :                                 writer.write_string (GNUC_FORMAT.printf (format_arg_index + 1));
     175              :                         }
     176              : 
     177        14056 :                         if (CCodeModifiers.CONST in modifiers) {
     178         1123 :                                 writer.write_string (GNUC_CONST);
     179              :                         }
     180        14056 :                         if (CCodeModifiers.UNUSED in modifiers) {
     181           64 :                                 writer.write_string (GNUC_UNUSED);
     182              :                         }
     183              : 
     184        14056 :                         if (CCodeModifiers.CONSTRUCTOR in modifiers) {
     185            2 :                                 writer.write_string (" __attribute__((constructor))");
     186        14054 :                         } else if (CCodeModifiers.DESTRUCTOR in modifiers) {
     187            2 :                                 writer.write_string (" __attribute__((destructor))");
     188              :                         }
     189              : 
     190        14056 :                         writer.write_string (";");
     191              :                 } else {
     192        18944 :                         writer.write_newline ();
     193        18944 :                         block.write (writer);
     194        18944 :                         writer.write_newline ();
     195              :                 }
     196        33000 :                 writer.write_newline ();
     197              :         }
     198              : 
     199       198207 :         public void add_statement (CCodeNode stmt) {
     200       198207 :                 stmt.line = current_line;
     201       198207 :                 current_block.add_statement (stmt);
     202              :         }
     203              : 
     204         4362 :         public void open_block () {
     205         2181 :                 statement_stack.add (current_block);
     206         2181 :                 var parent_block = current_block;
     207              : 
     208         2181 :                 current_block = new CCodeBlock ();
     209              : 
     210         2181 :                 parent_block.add_statement (current_block);
     211              :         }
     212              : 
     213        22544 :         public void open_if (CCodeExpression condition) {
     214        11272 :                 statement_stack.add (current_block);
     215        11272 :                 var parent_block = current_block;
     216              : 
     217        11272 :                 current_block = new CCodeBlock ();
     218              : 
     219        11272 :                 var cif = new CCodeIfStatement (condition, current_block);
     220        11272 :                 cif.line = current_line;
     221        11272 :                 statement_stack.add (cif);
     222              : 
     223        11272 :                 parent_block.add_statement (cif);
     224              :         }
     225              : 
     226         8244 :         public void add_else () {
     227         4122 :                 current_block = new CCodeBlock ();
     228              : 
     229         4122 :                 var cif = (CCodeIfStatement) statement_stack[statement_stack.size - 1];
     230         4122 :                 cif.line = current_line;
     231         4122 :                 assert (cif.false_statement == null);
     232         4122 :                 cif.false_statement = current_block;
     233              :         }
     234              : 
     235         1330 :         public void else_if (CCodeExpression condition) {
     236          665 :                 var parent_if = (CCodeIfStatement) statement_stack.remove_at (statement_stack.size - 1);
     237          665 :                 assert (parent_if.false_statement == null);
     238              : 
     239          665 :                 current_block = new CCodeBlock ();
     240              : 
     241          665 :                 var cif = new CCodeIfStatement (condition, current_block);
     242          665 :                 cif.line = current_line;
     243          665 :                 parent_if.false_statement = cif;
     244          665 :                 statement_stack.add (cif);
     245              :         }
     246              : 
     247         1324 :         public void open_while (CCodeExpression condition) {
     248          662 :                 statement_stack.add (current_block);
     249          662 :                 var parent_block = current_block;
     250              : 
     251          662 :                 current_block = new CCodeBlock ();
     252              : 
     253          662 :                 var cwhile = new CCodeWhileStatement (condition, current_block);
     254          662 :                 cwhile.line = current_line;
     255          662 :                 parent_block.add_statement (cwhile);
     256              :         }
     257              : 
     258          984 :         public void open_for (CCodeExpression? initializer, CCodeExpression condition, CCodeExpression? iterator) {
     259          492 :                 statement_stack.add (current_block);
     260          492 :                 var parent_block = current_block;
     261              : 
     262          492 :                 current_block = new CCodeBlock ();
     263              : 
     264          492 :                 var cfor = new CCodeForStatement (condition, current_block);
     265          492 :                 cfor.line = current_line;
     266          492 :                 if (initializer != null) {
     267          455 :                         cfor.add_initializer (initializer);
     268              :                 }
     269          492 :                 if (iterator != null) {
     270          492 :                         cfor.add_iterator (iterator);
     271              :                 }
     272              : 
     273          492 :                 parent_block.add_statement (cfor);
     274              :         }
     275              : 
     276         1276 :         public void open_switch (CCodeExpression expression) {
     277          638 :                 statement_stack.add (current_block);
     278          638 :                 var parent_block = current_block;
     279              : 
     280          638 :                 var cswitch = new CCodeSwitchStatement (expression);
     281          638 :                 cswitch.line = current_line;
     282          638 :                 current_block = cswitch;
     283              : 
     284          638 :                 parent_block.add_statement (cswitch);
     285              :         }
     286              : 
     287          547 :         public void add_label (string label) {
     288          547 :                 add_statement (new CCodeLabel (label));
     289              :         }
     290              : 
     291         1282 :         public void add_case (CCodeExpression expression) {
     292         1282 :                 add_statement (new CCodeCaseStatement (expression));
     293              :         }
     294              : 
     295          634 :         public void add_default () {
     296          634 :                 add_statement (new CCodeLabel ("default"));
     297              :         }
     298              : 
     299          545 :         public void add_goto (string target) {
     300          545 :                 add_statement (new CCodeGotoStatement (target));
     301              :         }
     302              : 
     303       118446 :         public void add_expression (CCodeExpression expression) {
     304       118446 :                 add_statement (new CCodeExpressionStatement (expression));
     305              :         }
     306              : 
     307        75054 :         public void add_assignment (CCodeExpression left, CCodeExpression right) {
     308        75054 :                 add_expression (new CCodeAssignment (left, right));
     309              :         }
     310              : 
     311        10994 :         public void add_return (CCodeExpression? expression = null) {
     312        10994 :                 add_statement (new CCodeReturnStatement (expression));
     313              :         }
     314              : 
     315         1872 :         public void add_break () {
     316         1872 :                 add_statement (new CCodeBreakStatement ());
     317              :         }
     318              : 
     319           41 :         public void add_continue () {
     320           41 :                 add_statement (new CCodeContinueStatement ());
     321              :         }
     322              : 
     323       127308 :         public void add_declaration (string type_name, CCodeDeclarator declarator, CCodeModifiers modifiers = 0) {
     324        63654 :                 var stmt = new CCodeDeclaration (type_name);
     325        63654 :                 stmt.add_declarator (declarator);
     326        63654 :                 stmt.modifiers = modifiers;
     327        63654 :                 add_statement (stmt);
     328              :         }
     329              : 
     330        15098 :         public void close () {
     331        67546 :                 do {
     332        26224 :                         var top = statement_stack.remove_at (statement_stack.size - 1);
     333        41322 :                         current_block = top as CCodeBlock;
     334        26224 :                 } while (current_block == null);
     335              :         }
     336              : }
        

Generated by: LCOV version 2.0-1