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-02-21 09:36:06 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          10 : main(void)
      20             : {
      21             :         CS_CONTEXT *ctx;
      22             :         CS_CONNECTION *conn;
      23             :         CS_COMMAND *cmd;
      24          10 :         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          10 :         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          10 :         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          10 :         printf("%s: submit a stored procedure using ct_param \n", __FILE__);
      56             :         if (verbose) {
      57             :                 printf("Trying login\n");
      58             :         }
      59          10 :         check_call(try_ctlogin, (&ctx, &conn, &cmd, verbose));
      60          10 :         error_to_stdout = true;
      61             : 
      62             :         /* do not test error */
      63          10 :         ret = run_command(cmd, "IF OBJECT_ID('sample_rpc') IS NOT NULL DROP PROCEDURE sample_rpc");
      64             : 
      65          10 :         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          10 :         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          10 :         check_call(run_command, (cmd, cmdbuf));
      84             : 
      85             :         /*
      86             :          * Assign values to the variables used for parameter passing.
      87             :          */
      88             : 
      89          10 :         intvar = 2;
      90          10 :         smallintvar = 234;
      91          10 :         floatvar = 0.12;
      92          10 :         binaryvar = (CS_BINARY) 0xff;
      93          10 :         strcpy(rpc_name, "sample_rpc");
      94          10 :         strcpy(moneystring, "300.90");
      95             : 
      96             :         /*
      97             :          * Clear and setup the CS_DATAFMT structures used to convert datatypes.
      98             :          */
      99             : 
     100          10 :         memset(&srcfmt, 0, sizeof(CS_DATAFMT));
     101             :         srcfmt.datatype = CS_CHAR_TYPE;
     102          10 :         srcfmt.maxlength = strlen(moneystring);
     103          10 :         srcfmt.precision = 5;
     104          10 :         srcfmt.scale = 2;
     105             :         srcfmt.locale = NULL;
     106             : 
     107          10 :         memset(&destfmt, 0, sizeof(CS_DATAFMT));
     108          10 :         destfmt.datatype = CS_MONEY_TYPE;
     109          10 :         destfmt.maxlength = sizeof(CS_MONEY);
     110          10 :         destfmt.precision = 5;
     111          10 :         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          10 :         check_call(ct_cmd_props, (cmd, CS_GET, CS_PARENT_HANDLE, &conn, CS_UNUSED, NULL));
     120          10 :         check_call(ct_con_props, (conn, CS_GET, CS_PARENT_HANDLE, &ctx, CS_UNUSED, NULL));
     121          10 :         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          10 :         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          10 :         memset(&datafmt, 0, sizeof(datafmt));
     133          10 :         strcpy(datafmt.name, "@intparam");
     134          10 :         datafmt.namelen = CS_NULLTERM;
     135          10 :         datafmt.datatype = CS_INT_TYPE;
     136          10 :         datafmt.maxlength = CS_UNUSED;
     137          10 :         datafmt.status = CS_INPUTVALUE;
     138             :         datafmt.locale = NULL;
     139             : 
     140          10 :         check_call(ct_param, (cmd, &datafmt, (CS_VOID *) & intvar, CS_SIZEOF(CS_INT), 0));
     141             : 
     142          10 :         strcpy(datafmt.name, "@sintparam");
     143          10 :         datafmt.namelen = CS_NULLTERM;
     144          10 :         datafmt.datatype = CS_SMALLINT_TYPE;
     145          10 :         datafmt.maxlength = 255;
     146          10 :         datafmt.status = CS_RETURN;
     147          10 :         datafmt.locale = NULL;
     148             : 
     149          10 :         check_call(ct_param, (cmd, &datafmt, (CS_VOID *) & smallintvar, CS_SIZEOF(CS_SMALLINT), 0));
     150             : 
     151          10 :         strcpy(datafmt.name, "@floatparam");
     152          10 :         datafmt.namelen = CS_NULLTERM;
     153          10 :         datafmt.datatype = CS_FLOAT_TYPE;
     154          10 :         datafmt.maxlength = 255;
     155          10 :         datafmt.status = CS_RETURN;
     156          10 :         datafmt.locale = NULL;
     157             : 
     158          10 :         check_call(ct_param, (cmd, &datafmt, (CS_VOID *) & floatvar, CS_SIZEOF(CS_FLOAT), 0));
     159             : 
     160          10 :         strcpy(datafmt.name, "@moneyparam");
     161          10 :         datafmt.namelen = CS_NULLTERM;
     162          10 :         datafmt.datatype = CS_MONEY_TYPE;
     163          10 :         datafmt.maxlength = 255;
     164          10 :         datafmt.status = CS_RETURN;
     165          10 :         datafmt.locale = NULL;
     166             : 
     167          10 :         check_call(ct_param, (cmd, &datafmt, (CS_VOID *) & moneyvar, CS_SIZEOF(CS_MONEY), 0));
     168             : 
     169          10 :         strcpy(datafmt.name, "@dateparam");
     170          10 :         datafmt.namelen = CS_NULLTERM;
     171          10 :         datafmt.datatype = CS_DATETIME4_TYPE;
     172          10 :         datafmt.maxlength = 255;
     173          10 :         datafmt.status = CS_RETURN;
     174          10 :         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          10 :         check_call(ct_param, (cmd, &datafmt, NULL, 0, -1));
     181          10 :         strcpy(datafmt.name, "@charparam");
     182          10 :         datafmt.namelen = CS_NULLTERM;
     183          10 :         datafmt.datatype = CS_CHAR_TYPE;
     184          10 :         datafmt.maxlength = 60;
     185          10 :         datafmt.status = CS_RETURN;
     186          10 :         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          10 :         check_call(ct_param, (cmd, &datafmt, NULL, 0, -1));
     193             : 
     194          10 :         strcpy(datafmt.name, "@empty");
     195          10 :         datafmt.namelen = CS_NULLTERM;
     196          10 :         datafmt.datatype = CS_VARCHAR_TYPE;
     197          10 :         datafmt.maxlength = 60;
     198          10 :         datafmt.status = CS_RETURN;
     199          10 :         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          10 :         check_call(ct_param, (cmd, &datafmt, NULL, 0, -1));
     206             : 
     207          10 :         strcpy(datafmt.name, "@binaryparam");
     208          10 :         datafmt.namelen = CS_NULLTERM;
     209          10 :         datafmt.datatype = CS_BINARY_TYPE;
     210          10 :         datafmt.maxlength = 255;
     211          10 :         datafmt.status = CS_RETURN;
     212          10 :         datafmt.locale = NULL;
     213             : 
     214          10 :         check_call(ct_param, (cmd, &datafmt, (CS_VOID *) & binaryvar, CS_SIZEOF(CS_BINARY), 0));
     215             : 
     216          10 :         strcpy(datafmt.name, "@bitparam");
     217          10 :         datafmt.namelen = CS_NULLTERM;
     218          10 :         datafmt.datatype = CS_BIT_TYPE;
     219          10 :         datafmt.maxlength = 1;
     220          10 :         datafmt.status = 0;
     221          10 :         datafmt.locale = NULL;
     222             : 
     223          10 :         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          10 :         check_call(ct_send, (cmd));
     229             : 
     230             :         /*
     231             :          * Process the results of the RPC.
     232             :          */
     233          80 :         while ((ret = ct_results(cmd, &res_type)) == CS_SUCCEED) {
     234          60 :                 switch ((int) res_type) {
     235          30 :                 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          30 :                         switch ((int) res_type) {
     242          10 :                         case CS_ROW_RESULT:
     243          10 :                                 printf("\nROW RESULTS\n");
     244          10 :                                 break;
     245             : 
     246          10 :                         case CS_PARAM_RESULT:
     247          10 :                                 printf("\nPARAMETER RESULTS\n");
     248          10 :                                 break;
     249             : 
     250          10 :                         case CS_STATUS_RESULT:
     251          10 :                                 printf("\nSTATUS RESULTS\n");
     252          10 :                                 break;
     253             :                         }
     254          30 :                         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          30 :                         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          30 :                         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          30 :                         coldata = (EX_COLUMN_DATA *) malloc(num_cols * sizeof(EX_COLUMN_DATA));
     284          30 :                         if (coldata == NULL) {
     285           0 :                                 fprintf(stderr, "malloc coldata failed \n");
     286           0 :                                 return 1;
     287             :                         }
     288             : 
     289          30 :                         outdatafmt = (CS_DATAFMT *) malloc(num_cols * sizeof(CS_DATAFMT));
     290          30 :                         if (outdatafmt == NULL) {
     291           0 :                                 fprintf(stderr, "malloc outdatafmt failed \n");
     292           0 :                                 return 1;
     293             :                         }
     294             : 
     295         150 :                         for (i = 0; i < num_cols; i++) {
     296         150 :                                 check_call(ct_describe, (cmd, (i + 1), &outdatafmt[i]));
     297             : 
     298         150 :                                 outdatafmt[i].maxlength = ex_display_dlen(&outdatafmt[i]) + 1;
     299         150 :                                 outdatafmt[i].datatype = CS_CHAR_TYPE;
     300         150 :                                 outdatafmt[i].format = CS_FMT_NULLTERM;
     301             : 
     302         150 :                                 coldata[i].value = (CS_CHAR *) malloc(outdatafmt[i].maxlength);
     303         150 :                                 if (coldata[i].value == NULL) {
     304           0 :                                         fprintf(stderr, "malloc coldata.value failed \n");
     305           0 :                                         return 1;
     306             :                                 }
     307         150 :                                 coldata[i].value[0] = 0;
     308             : 
     309         150 :                                 check_call(ct_bind, (cmd, (i + 1), &outdatafmt[i], coldata[i].value, &coldata[i].valuelen,
     310             :                                               & coldata[i].indicator));
     311             :                         }
     312             : 
     313          30 :                         ex_display_header(num_cols, outdatafmt);
     314             : 
     315          90 :                         while (((ret = ct_fetch(cmd, CS_UNUSED, CS_UNUSED, CS_UNUSED,
     316          30 :                                                 &rows_read)) == CS_SUCCEED) || (ret == CS_ROW_FAIL)) {
     317             :                                 /*
     318             :                                  * Increment our row count by the number of rows just fetched.
     319             :                                  */
     320          30 :                                 row_count = row_count + rows_read;
     321             : 
     322             :                                 /*
     323             :                                  * Check if we hit a recoverable error.
     324             :                                  */
     325          30 :                                 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         150 :                                 for (i = 0; i < num_cols; i++) {
     335             :                                         /*
     336             :                                          * Display the column value
     337             :                                          */
     338         150 :                                         printf("%s", coldata[i].value);
     339         150 :                                         fflush(stdout);
     340             : 
     341             :                                         /*
     342             :                                          * If not last column, Print out spaces between this
     343             :                                          * column and next one.
     344             :                                          */
     345         150 :                                         if (i != num_cols - 1) {
     346         120 :                                                 disp_len = ex_display_dlen(&outdatafmt[i]);
     347         120 :                                                 disp_len -= coldata[i].valuelen - 1;
     348        2258 :                                                 for (j = 0; j < disp_len; j++) {
     349        2138 :                                                         fputc(' ', stdout);
     350             :                                                 }
     351             :                                         }
     352             :                                 }
     353          30 :                                 printf("\n");
     354          30 :                                 fflush(stdout);
     355             :                         }
     356             : 
     357             :                         /*
     358             :                          * Free allocated space.
     359             :                          */
     360         150 :                         for (i = 0; i < num_cols; i++) {
     361         150 :                                 free(coldata[i].value);
     362             :                         }
     363          30 :                         free(coldata);
     364          30 :                         free(outdatafmt);
     365             : 
     366             :                         /*
     367             :                          * We're done processing rows.  Let's check the final return
     368             :                          * value of ct_fetch().
     369             :                          */
     370          30 :                         switch ((int) ret) {
     371          30 :                         case CS_END_DATA:
     372             :                                 /*
     373             :                                  * Everything went fine.
     374             :                                  */
     375          30 :                                 printf("All done processing rows.\n");
     376          30 :                                 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          30 :                         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          10 :         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          10 :         run_command(cmd, "DROP PROCEDURE sample_rpc");
     461             : 
     462             :         if (verbose) {
     463             :                 printf("Trying logout\n");
     464             :         }
     465          10 :         check_call(try_ctlogout, (ctx, conn, cmd, verbose));
     466             : 
     467          10 :         return 0;
     468             : }
     469             : 
     470             : static CS_INT
     471         570 : ex_display_dlen(CS_DATAFMT * column)
     472             : {
     473             : CS_INT len;
     474             : 
     475         570 :         switch ((int) column->datatype) {
     476         450 :         case CS_CHAR_TYPE:
     477             :         case CS_VARCHAR_TYPE:
     478             :         case CS_TEXT_TYPE:
     479             :         case CS_IMAGE_TYPE:
     480         450 :                 len = MIN(column->maxlength, 1024);
     481         450 :                 break;
     482             : 
     483          20 :         case CS_BINARY_TYPE:
     484             :         case CS_VARBINARY_TYPE:
     485          20 :                 len = MIN((2 * column->maxlength) + 2, 1024);
     486          20 :                 break;
     487             : 
     488             :         case CS_BIT_TYPE:
     489             :         case CS_TINYINT_TYPE:
     490             :                 len = 3;
     491             :                 break;
     492             : 
     493          20 :         case CS_SMALLINT_TYPE:
     494          20 :                 len = 6;
     495          20 :                 break;
     496             : 
     497          20 :         case CS_INT_TYPE:
     498          20 :                 len = 11;
     499          20 :                 break;
     500             : 
     501          20 :         case CS_REAL_TYPE:
     502             :         case CS_FLOAT_TYPE:
     503          20 :                 len = 20;
     504          20 :                 break;
     505             : 
     506          20 :         case CS_MONEY_TYPE:
     507             :         case CS_MONEY4_TYPE:
     508          20 :                 len = 24;
     509          20 :                 break;
     510             : 
     511          20 :         case CS_DATETIME_TYPE:
     512             :         case CS_DATETIME4_TYPE:
     513          20 :                 len = 30;
     514          20 :                 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         570 :         return MAX((CS_INT) (strlen(column->name) + 1), len);
     527             : }
     528             : 
     529             : static CS_RETCODE
     530          30 : 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          30 :         fputc('\n', stdout);
     538         180 :         for (i = 0; i < numcols; i++) {
     539         150 :                 disp_len = ex_display_dlen(&columns[i]);
     540         150 :                 printf("%s", columns[i].name);
     541         150 :                 fflush(stdout);
     542         150 :                 l = disp_len - strlen(columns[i].name);
     543        8410 :                 for (j = 0; j < l; j++) {
     544        8260 :                         fputc(' ', stdout);
     545        8260 :                         fflush(stdout);
     546             :                 }
     547             :         }
     548          30 :         fputc('\n', stdout);
     549          30 :         fflush(stdout);
     550         180 :         for (i = 0; i < numcols; i++) {
     551         150 :                 disp_len = ex_display_dlen(&columns[i]);
     552         150 :                 l = disp_len - 1;
     553        8960 :                 for (j = 0; j < l; j++) {
     554        8810 :                         fputc('-', stdout);
     555             :                 }
     556         150 :                 fputc(' ', stdout);
     557             :         }
     558          30 :         fputc('\n', stdout);
     559             : 
     560          30 :         return CS_SUCCEED;
     561             : }

Generated by: LCOV version 1.13