LCOV - code coverage report
Current view: top level - src/ctlib/unittests - rpc_ct_param.c (source / functions) Hit Total Coverage
Test: FreeTDS coverage Lines: 195 234 83.3 %
Date: 2025-01-18 11:50:39 Functions: 3 3 100.0 %

          Line data    Source code
       1             : #include "common.h"
       2             : 
       3             : #define MAX(X,Y)      (((X) > (Y)) ? (X) : (Y))
       4             : #define MIN(X,Y)      (((X) < (Y)) ? (X) : (Y))
       5             : 
       6             : static CS_INT ex_display_dlen(CS_DATAFMT * column);
       7             : static CS_RETCODE ex_display_header(CS_INT numcols, CS_DATAFMT columns[]);
       8             : 
       9             : typedef struct _ex_column_data
      10             : {
      11             :         CS_SMALLINT indicator;
      12             :         CS_CHAR *value;
      13             :         CS_INT valuelen;
      14             : }
      15             : EX_COLUMN_DATA;
      16             : 
      17             : /* Testing: array binding of result set */
      18             : int
      19           8 : main(void)
      20             : {
      21             :         CS_CONTEXT *ctx;
      22             :         CS_CONNECTION *conn;
      23             :         CS_COMMAND *cmd;
      24           8 :         int verbose = 0;
      25             : 
      26             :         CS_RETCODE ret;
      27             :         CS_INT res_type;
      28             :         CS_INT num_cols;
      29             : 
      30             :         CS_CHAR cmdbuf[4096];
      31             : 
      32             :         CS_DATAFMT datafmt;
      33             :         CS_DATAFMT srcfmt;
      34             :         CS_DATAFMT destfmt;
      35             :         CS_INT intvar;
      36             :         CS_SMALLINT smallintvar;
      37             :         CS_FLOAT floatvar;
      38             :         CS_MONEY moneyvar;
      39             :         CS_BINARY binaryvar;
      40           8 :         CS_BIT bitvar = 1;
      41             :         char moneystring[10];
      42             :         char rpc_name[15];
      43             :         CS_INT destlen;
      44             :         CS_INT i;
      45             :         CS_INT j;
      46           8 :         CS_INT row_count = 0;
      47             :         CS_INT rows_read;
      48             :         CS_INT disp_len;
      49             :         EX_COLUMN_DATA *coldata;
      50             :         CS_DATAFMT *outdatafmt;
      51             :         CS_SMALLINT msg_id;
      52             : 
      53             : 
      54             : 
      55           8 :         printf("%s: submit a stored procedure using ct_param \n", __FILE__);
      56             :         if (verbose) {
      57             :                 printf("Trying login\n");
      58             :         }
      59           8 :         check_call(try_ctlogin, (&ctx, &conn, &cmd, verbose));
      60           8 :         error_to_stdout = true;
      61             : 
      62             :         /* do not test error */
      63           8 :         ret = run_command(cmd, "IF OBJECT_ID('sample_rpc') IS NOT NULL DROP PROCEDURE sample_rpc");
      64             : 
      65           8 :         strcpy(cmdbuf, "create proc sample_rpc (@intparam int, \
      66             :         @sintparam smallint output, @floatparam float output, \
      67             :         @moneyparam money output,  \
      68             :         @dateparam datetime output, @charparam char(20) output, @empty varchar(20) output, \
      69             :         @binaryparam    binary(20) output, @bitparam bit) \
      70             :         as ");
      71             : 
      72           8 :         strcat(cmdbuf, "select @intparam, @sintparam, @floatparam, @moneyparam, \
      73             :         @dateparam, @charparam, @binaryparam \
      74             :         select @sintparam = @sintparam + @intparam \
      75             :         select @floatparam = @floatparam + @intparam \
      76             :         select @moneyparam = @moneyparam + convert(money, @intparam) \
      77             :         select @dateparam = getdate() \
      78             :         select @charparam = \'The char parameters\' \
      79             :         select @empty = \'\' \
      80             :         select @binaryparam = @binaryparam \
      81             :         print \'This is the message printed out by sample_rpc.\'");
      82             : 
      83           8 :         check_call(run_command, (cmd, cmdbuf));
      84             : 
      85             :         /*
      86             :          * Assign values to the variables used for parameter passing.
      87             :          */
      88             : 
      89           8 :         intvar = 2;
      90           8 :         smallintvar = 234;
      91           8 :         floatvar = 0.12;
      92           8 :         binaryvar = (CS_BINARY) 0xff;
      93           8 :         strcpy(rpc_name, "sample_rpc");
      94           8 :         strcpy(moneystring, "300.90");
      95             : 
      96             :         /*
      97             :          * Clear and setup the CS_DATAFMT structures used to convert datatypes.
      98             :          */
      99             : 
     100           8 :         memset(&srcfmt, 0, sizeof(CS_DATAFMT));
     101             :         srcfmt.datatype = CS_CHAR_TYPE;
     102           8 :         srcfmt.maxlength = strlen(moneystring);
     103           8 :         srcfmt.precision = 5;
     104           8 :         srcfmt.scale = 2;
     105             :         srcfmt.locale = NULL;
     106             : 
     107           8 :         memset(&destfmt, 0, sizeof(CS_DATAFMT));
     108           8 :         destfmt.datatype = CS_MONEY_TYPE;
     109           8 :         destfmt.maxlength = sizeof(CS_MONEY);
     110           8 :         destfmt.precision = 5;
     111           8 :         destfmt.scale = 2;
     112             :         destfmt.locale = NULL;
     113             : 
     114             :         /*
     115             :          * Convert the string representing the money value
     116             :          * to a CS_MONEY variable. Since this routine does not have the
     117             :          * context handle, we use the property functions to get it.
     118             :          */
     119           8 :         check_call(ct_cmd_props, (cmd, CS_GET, CS_PARENT_HANDLE, &conn, CS_UNUSED, NULL));
     120           8 :         check_call(ct_con_props, (conn, CS_GET, CS_PARENT_HANDLE, &ctx, CS_UNUSED, NULL));
     121           8 :         check_call(cs_convert, (ctx, &srcfmt, (CS_VOID *) moneystring, &destfmt, &moneyvar, &destlen));
     122             : 
     123             :         /*
     124             :          * Send the RPC command for our stored procedure.
     125             :          */
     126           8 :         check_call(ct_command, (cmd, CS_RPC_CMD, rpc_name, CS_NULLTERM, CS_NO_RECOMPILE));
     127             : 
     128             :         /*
     129             :          * Clear and setup the CS_DATAFMT structure, then pass
     130             :          * each of the parameters for the RPC.
     131             :          */
     132           8 :         memset(&datafmt, 0, sizeof(datafmt));
     133           8 :         strcpy(datafmt.name, "@intparam");
     134           8 :         datafmt.namelen = CS_NULLTERM;
     135           8 :         datafmt.datatype = CS_INT_TYPE;
     136           8 :         datafmt.maxlength = CS_UNUSED;
     137           8 :         datafmt.status = CS_INPUTVALUE;
     138             :         datafmt.locale = NULL;
     139             : 
     140           8 :         check_call(ct_param, (cmd, &datafmt, (CS_VOID *) & intvar, CS_SIZEOF(CS_INT), 0));
     141             : 
     142           8 :         strcpy(datafmt.name, "@sintparam");
     143           8 :         datafmt.namelen = CS_NULLTERM;
     144           8 :         datafmt.datatype = CS_SMALLINT_TYPE;
     145           8 :         datafmt.maxlength = 255;
     146           8 :         datafmt.status = CS_RETURN;
     147           8 :         datafmt.locale = NULL;
     148             : 
     149           8 :         check_call(ct_param, (cmd, &datafmt, (CS_VOID *) & smallintvar, CS_SIZEOF(CS_SMALLINT), 0));
     150             : 
     151           8 :         strcpy(datafmt.name, "@floatparam");
     152           8 :         datafmt.namelen = CS_NULLTERM;
     153           8 :         datafmt.datatype = CS_FLOAT_TYPE;
     154           8 :         datafmt.maxlength = 255;
     155           8 :         datafmt.status = CS_RETURN;
     156           8 :         datafmt.locale = NULL;
     157             : 
     158           8 :         check_call(ct_param, (cmd, &datafmt, (CS_VOID *) & floatvar, CS_SIZEOF(CS_FLOAT), 0));
     159             : 
     160           8 :         strcpy(datafmt.name, "@moneyparam");
     161           8 :         datafmt.namelen = CS_NULLTERM;
     162           8 :         datafmt.datatype = CS_MONEY_TYPE;
     163           8 :         datafmt.maxlength = 255;
     164           8 :         datafmt.status = CS_RETURN;
     165           8 :         datafmt.locale = NULL;
     166             : 
     167           8 :         check_call(ct_param, (cmd, &datafmt, (CS_VOID *) & moneyvar, CS_SIZEOF(CS_MONEY), 0));
     168             : 
     169           8 :         strcpy(datafmt.name, "@dateparam");
     170           8 :         datafmt.namelen = CS_NULLTERM;
     171           8 :         datafmt.datatype = CS_DATETIME4_TYPE;
     172           8 :         datafmt.maxlength = 255;
     173           8 :         datafmt.status = CS_RETURN;
     174           8 :         datafmt.locale = NULL;
     175             : 
     176             :         /*
     177             :          * The datetime variable is filled in by the RPC so pass NULL for
     178             :          * the data, 0 for data length, and -1 for the indicator arguments.
     179             :          */
     180           8 :         check_call(ct_param, (cmd, &datafmt, NULL, 0, -1));
     181           8 :         strcpy(datafmt.name, "@charparam");
     182           8 :         datafmt.namelen = CS_NULLTERM;
     183           8 :         datafmt.datatype = CS_CHAR_TYPE;
     184           8 :         datafmt.maxlength = 60;
     185           8 :         datafmt.status = CS_RETURN;
     186           8 :         datafmt.locale = NULL;
     187             : 
     188             :         /*
     189             :          * The character string variable is filled in by the RPC so pass NULL
     190             :          * for the data 0 for data length, and -1 for the indicator arguments.
     191             :          */
     192           8 :         check_call(ct_param, (cmd, &datafmt, NULL, 0, -1));
     193             : 
     194           8 :         strcpy(datafmt.name, "@empty");
     195           8 :         datafmt.namelen = CS_NULLTERM;
     196           8 :         datafmt.datatype = CS_VARCHAR_TYPE;
     197           8 :         datafmt.maxlength = 60;
     198           8 :         datafmt.status = CS_RETURN;
     199           8 :         datafmt.locale = NULL;
     200             : 
     201             :         /*
     202             :          * The character string variable is filled in by the RPC so pass NULL
     203             :          * for the data 0 for data length, and -1 for the indicator arguments.
     204             :          */
     205           8 :         check_call(ct_param, (cmd, &datafmt, NULL, 0, -1));
     206             : 
     207           8 :         strcpy(datafmt.name, "@binaryparam");
     208           8 :         datafmt.namelen = CS_NULLTERM;
     209           8 :         datafmt.datatype = CS_BINARY_TYPE;
     210           8 :         datafmt.maxlength = 255;
     211           8 :         datafmt.status = CS_RETURN;
     212           8 :         datafmt.locale = NULL;
     213             : 
     214           8 :         check_call(ct_param, (cmd, &datafmt, (CS_VOID *) & binaryvar, CS_SIZEOF(CS_BINARY), 0));
     215             : 
     216           8 :         strcpy(datafmt.name, "@bitparam");
     217           8 :         datafmt.namelen = CS_NULLTERM;
     218           8 :         datafmt.datatype = CS_BIT_TYPE;
     219           8 :         datafmt.maxlength = 1;
     220           8 :         datafmt.status = 0;
     221           8 :         datafmt.locale = NULL;
     222             : 
     223           8 :         check_call(ct_param, (cmd, &datafmt, (CS_VOID *) & bitvar, CS_SIZEOF(CS_BIT), 0));
     224             : 
     225             :         /*
     226             :          * Send the command to the server
     227             :          */
     228           8 :         check_call(ct_send, (cmd));
     229             : 
     230             :         /*
     231             :          * Process the results of the RPC.
     232             :          */
     233          64 :         while ((ret = ct_results(cmd, &res_type)) == CS_SUCCEED) {
     234          48 :                 switch ((int) res_type) {
     235          24 :                 case CS_ROW_RESULT:
     236             :                 case CS_PARAM_RESULT:
     237             :                 case CS_STATUS_RESULT:
     238             :                         /*
     239             :                          * Print the result header based on the result type.
     240             :                          */
     241          24 :                         switch ((int) res_type) {
     242           8 :                         case CS_ROW_RESULT:
     243           8 :                                 printf("\nROW RESULTS\n");
     244           8 :                                 break;
     245             : 
     246           8 :                         case CS_PARAM_RESULT:
     247           8 :                                 printf("\nPARAMETER RESULTS\n");
     248           8 :                                 break;
     249             : 
     250           8 :                         case CS_STATUS_RESULT:
     251           8 :                                 printf("\nSTATUS RESULTS\n");
     252           8 :                                 break;
     253             :                         }
     254          24 :                         fflush(stdout);
     255             : 
     256             :                         /*
     257             :                          * All three of these result types are fetchable.
     258             :                          * Since the result model for rpcs and rows have
     259             :                          * been unified in the New Client-Library, we
     260             :                          * will use the same routine to display them
     261             :                          */
     262             : 
     263             :                         /*
     264             :                          * Find out how many columns there are in this result set.
     265             :                          */
     266          24 :                         check_call(ct_res_info, (cmd, CS_NUMDATA, &num_cols, CS_UNUSED, NULL));
     267             : 
     268             :                         /*
     269             :                          * Make sure we have at least one column
     270             :                          */
     271          24 :                         if (num_cols <= 0) {
     272           0 :                                 fprintf(stderr, "ct_res_info(CS_NUMDATA) returned zero columns");
     273           0 :                                 return 1;
     274             :                         }
     275             : 
     276             :                         /*
     277             :                          * Our program variable, called 'coldata', is an array of
     278             :                          * EX_COLUMN_DATA structures. Each array element represents
     279             :                          * one column.  Each array element will re-used for each row.
     280             :                          * 
     281             :                          * First, allocate memory for the data element to process.
     282             :                          */
     283          24 :                         coldata = (EX_COLUMN_DATA *) malloc(num_cols * sizeof(EX_COLUMN_DATA));
     284          24 :                         if (coldata == NULL) {
     285           0 :                                 fprintf(stderr, "malloc coldata failed \n");
     286           0 :                                 return 1;
     287             :                         }
     288             : 
     289          24 :                         outdatafmt = (CS_DATAFMT *) malloc(num_cols * sizeof(CS_DATAFMT));
     290          24 :                         if (outdatafmt == NULL) {
     291           0 :                                 fprintf(stderr, "malloc outdatafmt failed \n");
     292           0 :                                 return 1;
     293             :                         }
     294             : 
     295         120 :                         for (i = 0; i < num_cols; i++) {
     296         120 :                                 check_call(ct_describe, (cmd, (i + 1), &outdatafmt[i]));
     297             : 
     298         120 :                                 outdatafmt[i].maxlength = ex_display_dlen(&outdatafmt[i]) + 1;
     299         120 :                                 outdatafmt[i].datatype = CS_CHAR_TYPE;
     300         120 :                                 outdatafmt[i].format = CS_FMT_NULLTERM;
     301             : 
     302         120 :                                 coldata[i].value = (CS_CHAR *) malloc(outdatafmt[i].maxlength);
     303         120 :                                 if (coldata[i].value == NULL) {
     304           0 :                                         fprintf(stderr, "malloc coldata.value failed \n");
     305           0 :                                         return 1;
     306             :                                 }
     307         120 :                                 coldata[i].value[0] = 0;
     308             : 
     309         120 :                                 check_call(ct_bind, (cmd, (i + 1), &outdatafmt[i], coldata[i].value, &coldata[i].valuelen,
     310             :                                               & coldata[i].indicator));
     311             :                         }
     312             : 
     313          24 :                         ex_display_header(num_cols, outdatafmt);
     314             : 
     315          72 :                         while (((ret = ct_fetch(cmd, CS_UNUSED, CS_UNUSED, CS_UNUSED,
     316          24 :                                                 &rows_read)) == CS_SUCCEED) || (ret == CS_ROW_FAIL)) {
     317             :                                 /*
     318             :                                  * Increment our row count by the number of rows just fetched.
     319             :                                  */
     320          24 :                                 row_count = row_count + rows_read;
     321             : 
     322             :                                 /*
     323             :                                  * Check if we hit a recoverable error.
     324             :                                  */
     325          24 :                                 if (ret == CS_ROW_FAIL) {
     326           0 :                                         printf("Error on row %d.\n", row_count);
     327           0 :                                         fflush(stdout);
     328             :                                 }
     329             : 
     330             :                                 /*
     331             :                                  * We have a row.  Loop through the columns displaying the
     332             :                                  * column values.
     333             :                                  */
     334         120 :                                 for (i = 0; i < num_cols; i++) {
     335             :                                         /*
     336             :                                          * Display the column value
     337             :                                          */
     338         120 :                                         printf("%s", coldata[i].value);
     339         120 :                                         fflush(stdout);
     340             : 
     341             :                                         /*
     342             :                                          * If not last column, Print out spaces between this
     343             :                                          * column and next one.
     344             :                                          */
     345         120 :                                         if (i != num_cols - 1) {
     346          96 :                                                 disp_len = ex_display_dlen(&outdatafmt[i]);
     347          96 :                                                 disp_len -= coldata[i].valuelen - 1;
     348        1822 :                                                 for (j = 0; j < disp_len; j++) {
     349        1726 :                                                         fputc(' ', stdout);
     350             :                                                 }
     351             :                                         }
     352             :                                 }
     353          24 :                                 printf("\n");
     354          24 :                                 fflush(stdout);
     355             :                         }
     356             : 
     357             :                         /*
     358             :                          * Free allocated space.
     359             :                          */
     360         120 :                         for (i = 0; i < num_cols; i++) {
     361         120 :                                 free(coldata[i].value);
     362             :                         }
     363          24 :                         free(coldata);
     364          24 :                         free(outdatafmt);
     365             : 
     366             :                         /*
     367             :                          * We're done processing rows.  Let's check the final return
     368             :                          * value of ct_fetch().
     369             :                          */
     370          24 :                         switch ((int) ret) {
     371          24 :                         case CS_END_DATA:
     372             :                                 /*
     373             :                                  * Everything went fine.
     374             :                                  */
     375          24 :                                 printf("All done processing rows.\n");
     376          24 :                                 fflush(stdout);
     377             :                                 break;
     378             : 
     379           0 :                         case CS_FAIL:
     380             :                                 /*
     381             :                                  * Something terrible happened.
     382             :                                  */
     383           0 :                                 fprintf(stderr, "ct_fetch returned CS_FAIL\n");
     384           0 :                                 return 1;
     385             :                                 break;
     386             : 
     387           0 :                         default:
     388             :                                 /*
     389             :                                  * We got an unexpected return value.
     390             :                                  */
     391           0 :                                 fprintf(stderr, "ct_fetch returned %d\n", ret);
     392           0 :                                 return 1;
     393             :                                 break;
     394             : 
     395             :                         }
     396          24 :                         break;
     397             : 
     398           0 :                 case CS_MSG_RESULT:
     399           0 :                         check_call(ct_res_info, (cmd, CS_MSGTYPE, (CS_VOID *) & msg_id, CS_UNUSED, NULL));
     400           0 :                         printf("ct_result returned CS_MSG_RESULT where msg id = %d.\n", msg_id);
     401           0 :                         fflush(stdout);
     402           0 :                         break;
     403             : 
     404             :                 case CS_CMD_SUCCEED:
     405             :                         /*
     406             :                          * This means no rows were returned.
     407             :                          */
     408             :                         break;
     409             : 
     410             :                 case CS_CMD_DONE:
     411             :                         /*
     412             :                          * Done with result set.
     413             :                          */
     414             :                         break;
     415             : 
     416           0 :                 case CS_CMD_FAIL:
     417             :                         /*
     418             :                          * The server encountered an error while
     419             :                          * processing our command.
     420             :                          */
     421           0 :                         fprintf(stderr, "ct_results returned CS_CMD_FAIL.");
     422           0 :                         break;
     423             : 
     424           0 :                 default:
     425             :                         /*
     426             :                          * We got something unexpected.
     427             :                          */
     428           0 :                         fprintf(stderr, "ct_results returned unexpected result type.");
     429           0 :                         return CS_FAIL;
     430             :                 }
     431             :         }
     432             : 
     433             :         /*
     434             :          * We're done processing results. Let's check the
     435             :          * return value of ct_results() to see if everything
     436             :          * went ok.
     437             :          */
     438           8 :         switch ((int) ret) {
     439             :         case CS_END_RESULTS:
     440             :                 /*
     441             :                  * Everything went fine.
     442             :                  */
     443             :                 break;
     444             : 
     445           0 :         case CS_FAIL:
     446             :                 /*
     447             :                  * Something failed happened.
     448             :                  */
     449           0 :                 fprintf(stderr, "ct_results failed.");
     450           0 :                 break;
     451             : 
     452           0 :         default:
     453             :                 /*
     454             :                  * We got an unexpected return value.
     455             :                  */
     456           0 :                 fprintf(stderr, "ct_results returned unexpected result type.");
     457           0 :                 break;
     458             :         }
     459             : 
     460           8 :         run_command(cmd, "DROP PROCEDURE sample_rpc");
     461             : 
     462             :         if (verbose) {
     463             :                 printf("Trying logout\n");
     464             :         }
     465           8 :         check_call(try_ctlogout, (ctx, conn, cmd, verbose));
     466             : 
     467           8 :         return 0;
     468             : }
     469             : 
     470             : static CS_INT
     471         456 : ex_display_dlen(CS_DATAFMT * column)
     472             : {
     473             : CS_INT len;
     474             : 
     475         456 :         switch ((int) column->datatype) {
     476         360 :         case CS_CHAR_TYPE:
     477             :         case CS_VARCHAR_TYPE:
     478             :         case CS_TEXT_TYPE:
     479             :         case CS_IMAGE_TYPE:
     480         360 :                 len = MIN(column->maxlength, 1024);
     481         360 :                 break;
     482             : 
     483          16 :         case CS_BINARY_TYPE:
     484             :         case CS_VARBINARY_TYPE:
     485          16 :                 len = MIN((2 * column->maxlength) + 2, 1024);
     486          16 :                 break;
     487             : 
     488             :         case CS_BIT_TYPE:
     489             :         case CS_TINYINT_TYPE:
     490             :                 len = 3;
     491             :                 break;
     492             : 
     493          16 :         case CS_SMALLINT_TYPE:
     494          16 :                 len = 6;
     495          16 :                 break;
     496             : 
     497          16 :         case CS_INT_TYPE:
     498          16 :                 len = 11;
     499          16 :                 break;
     500             : 
     501          16 :         case CS_REAL_TYPE:
     502             :         case CS_FLOAT_TYPE:
     503          16 :                 len = 20;
     504          16 :                 break;
     505             : 
     506          16 :         case CS_MONEY_TYPE:
     507             :         case CS_MONEY4_TYPE:
     508          16 :                 len = 24;
     509          16 :                 break;
     510             : 
     511          16 :         case CS_DATETIME_TYPE:
     512             :         case CS_DATETIME4_TYPE:
     513          16 :                 len = 30;
     514          16 :                 break;
     515             : 
     516           0 :         case CS_NUMERIC_TYPE:
     517             :         case CS_DECIMAL_TYPE:
     518           0 :                 len = (CS_MAX_PREC + 2);
     519           0 :                 break;
     520             : 
     521           0 :         default:
     522           0 :                 len = 12;
     523           0 :                 break;
     524             :         }
     525             : 
     526         456 :         return MAX((CS_INT) (strlen(column->name) + 1), len);
     527             : }
     528             : 
     529             : static CS_RETCODE
     530          24 : ex_display_header(CS_INT numcols, CS_DATAFMT columns[])
     531             : {
     532             : CS_INT i;
     533             : CS_INT l;
     534             : CS_INT j;
     535             : CS_INT disp_len;
     536             : 
     537          24 :         fputc('\n', stdout);
     538         144 :         for (i = 0; i < numcols; i++) {
     539         120 :                 disp_len = ex_display_dlen(&columns[i]);
     540         120 :                 printf("%s", columns[i].name);
     541         120 :                 fflush(stdout);
     542         120 :                 l = disp_len - strlen(columns[i].name);
     543        6728 :                 for (j = 0; j < l; j++) {
     544        6608 :                         fputc(' ', stdout);
     545        6608 :                         fflush(stdout);
     546             :                 }
     547             :         }
     548          24 :         fputc('\n', stdout);
     549          24 :         fflush(stdout);
     550         144 :         for (i = 0; i < numcols; i++) {
     551         120 :                 disp_len = ex_display_dlen(&columns[i]);
     552         120 :                 l = disp_len - 1;
     553        7168 :                 for (j = 0; j < l; j++) {
     554        7048 :                         fputc('-', stdout);
     555             :                 }
     556         120 :                 fputc(' ', stdout);
     557             :         }
     558          24 :         fputc('\n', stdout);
     559             : 
     560          24 :         return CS_SUCCEED;
     561             : }

Generated by: LCOV version 1.13