LCOV - code coverage report
Current view: top level - lib - dlt_env_ll.c (source / functions) Coverage Total Hit
Test: dlt_final_coverage.info Lines: 6.3 % 126 8
Test Date: 2025-03-25 20:53:42 Functions: 16.7 % 12 2

            Line data    Source code
       1              : /*
       2              :  * SPDX license identifier: MPL-2.0
       3              :  *
       4              :  * Copyright (C) 2015  Intel Corporation
       5              :  *
       6              :  * This file is part of COVESA Project DLT - Diagnostic Log and Trace.
       7              :  *
       8              :  * This Source Code Form is subject to the terms of the
       9              :  * Mozilla Public License (MPL), v. 2.0.
      10              :  * If a copy of the MPL was not distributed with this file,
      11              :  * You can obtain one at http://mozilla.org/MPL/2.0/.
      12              :  *
      13              :  * For further information see http://www.covesa.org/.
      14              :  */
      15              : 
      16              : /*!
      17              :  * \author Stefan Vacek <stefan.vacek@intel.com> Intel Corporation
      18              :  *
      19              :  * \copyright Copyright © 2015 Intel Corporation. \n
      20              :  * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/.
      21              :  *
      22              :  * \file dlt_env_ll.c
      23              :  */
      24              : 
      25              : #include "dlt_user.h"
      26              : #include <string.h>
      27              : #include <stdlib.h>
      28              : 
      29              : #define DLT_ENV_LL_SET_INCREASE 10
      30              : 
      31              : 
      32              : /* a generic entry looks like:
      33              :  * ll_item ::= apid:ctid:ll
      34              :  * ll_set  ::= ll_item |
      35              :  *             ll_set;ll_item
      36              :  */
      37              : 
      38              : /**
      39              :  * @brief extract id out of given string
      40              :  *
      41              :  * Extract 4-byte string out of given environment string, the pointer of the
      42              :  * environment string is moved to the next un-used character and the extracted
      43              :  * id is copied into \param id
      44              :  *
      45              :  * Example:
      46              :  * env[] = "abcd:1234:3"
      47              :  * char res[4u];
      48              :  * char * tmp = &env[0];
      49              :  * int ret = extract_id(&tmp, res);
      50              :  * assert(ret == 0);
      51              :  * assert(*tmp == ':');
      52              :  * assert(res[3] == 'd');
      53              :  *
      54              :  * @param env    Environment variable
      55              :  * @param id     Extracted ID
      56              :  * @return 0 if successful, -1 else
      57              :  */
      58            0 : int dlt_env_extract_id(char **const env, char *id)
      59              : {
      60              :     int i;
      61              : 
      62            0 :     if (!env || !id) {
      63              :         return -1;
      64              :     }
      65              : 
      66            0 :     if (!(*env)) {
      67              :         return -1;
      68              :     }
      69              : 
      70              :     memset(id, 0, 4);
      71              : 
      72            0 :     for (i = 0; (i < 4) && (**env != ':') && (**env != 0); ++i) {
      73            0 :         *id++ = *((*env)++);
      74              :     }
      75              : 
      76              :     /* the next/last character must be ':' */
      77            0 :     if ((0 != **env) && (':' == **env)) {
      78              :         return 0;
      79              :     }
      80              : 
      81              :     return -1;
      82              : }
      83              : 
      84              : 
      85              : /**
      86              :  * @brief convert a given string to lower-case
      87              :  *
      88              :  * Stops end of string or if ';' is detected
      89              :  */
      90            0 : int dlt_env_helper_to_lower(char **const env, char *result, int const res_len)
      91              : {
      92              :     int count = 0;
      93              :     char ch;
      94              : 
      95            0 :     if (!env || !result) {
      96              :         return -1;
      97              :     }
      98              : 
      99            0 :     if (!(*env)) {
     100              :         return -1;
     101              :     }
     102              : 
     103            0 :     ch = *(*env);
     104              : 
     105            0 :     while (ch && (count < res_len - 1) && (ch != ';')) {
     106            0 :         if ((ch >= 'A') && (ch <= 'Z')) {
     107            0 :             result[count] = ch + 'a' - 'A';
     108              :         } else {
     109            0 :             result[count] = ch;
     110              :         }
     111              : 
     112            0 :         ch = *(++(*env));
     113            0 :         ++count;
     114              :     }
     115              : 
     116            0 :     result[count] = 0;
     117              : 
     118            0 :     if (!ch || (ch == ';')) { /* full input was parsed */
     119              :         return 0;
     120              :     } else {
     121              :         return -1;
     122              :     }
     123              : }
     124              : 
     125              : 
     126            0 : int dlt_env_extract_symbolic_ll(char **const env, int8_t *ll)
     127            0 : {
     128              :     char result[strlen("verbose") + 1];
     129              : 
     130            0 :     if (!env || !ll) {
     131              :         return -1;
     132              :     }
     133              : 
     134            0 :     if (!(*env)) {
     135              :         return -1;
     136              :     }
     137              : 
     138            0 :     if (dlt_env_helper_to_lower(env, &result[0], sizeof(result)) == 0) {
     139            0 :         if (strncmp("default", result, sizeof(result)) == 0) {
     140            0 :             *ll = -1;
     141            0 :         } else if (strncmp("off", result, sizeof(result)) == 0) {
     142            0 :             *ll = 0;
     143            0 :         } else if (strncmp("fatal", result, sizeof(result)) == 0) {
     144            0 :             *ll = 1;
     145            0 :         } else if (strncmp("error", result, sizeof(result)) == 0) {
     146            0 :             *ll = 2;
     147            0 :         } else if (strncmp("warning", result, sizeof(result)) == 0) {
     148            0 :             *ll = 3;
     149            0 :         } else if (strncmp("info", result, sizeof(result)) == 0) {
     150            0 :             *ll = 4;
     151            0 :         } else if (strncmp("debug", result, sizeof(result)) == 0) {
     152            0 :             *ll = 5;
     153            0 :         } else if (strncmp("verbose", result, sizeof(result)) == 0) {
     154            0 :             *ll = 6;
     155              :         } else {
     156              :             return -1;
     157              :         }
     158              : 
     159            0 :         if (**env != 0) {
     160            0 :             (*env)++;
     161              :         }
     162              : 
     163            0 :         return 0;
     164              :     } else {
     165              :         return -1;
     166              :     }
     167              : }
     168              : 
     169              : 
     170              : /**
     171              :  * @brief extract log-level out of given string
     172              :  *
     173              :  * A valid log-level is a numeric value in the range of -1 .. 6, with:
     174              :  * -1: default
     175              :  *  0: off
     176              :  *  1: fatal
     177              :  *  2: error
     178              :  *  3: warning
     179              :  *  4: info
     180              :  *  5: debug
     181              :  *  6: verbose
     182              :  * During parsing, the environment string is moved to the next un-used character and the extracted
     183              :  * log-level is written into \param ll
     184              :  *
     185              :  * Example:
     186              :  * env[] = "abcd:1234:6"
     187              :  * int ll;
     188              :  * char ** tmp = &env[10]; // tmp points to '6'!
     189              :  * int ret = extract_ll(&tmp, &ll);
     190              :  * assert(ret == 0);
     191              :  * assert(*tmp == NULL);
     192              :  * assert(ll == 6);
     193              :  *
     194              :  * @param env    Environment variable
     195              :  * @param ll     Extracted log level
     196              :  * @return 0 if successful, -1 else
     197              :  */
     198            0 : int dlt_env_extract_ll(char **const env, int8_t *ll)
     199              : {
     200            0 :     if (!env || !ll) {
     201              :         return -1;
     202              :     }
     203              : 
     204            0 :     if (!(*env)) {
     205              :         return -1;
     206              :     }
     207              : 
     208              :     /* extract number */
     209            0 :     if (**env == '-') {
     210            0 :         (*env)++;
     211              : 
     212            0 :         if (**env == '1') {
     213            0 :             *ll = -1;
     214            0 :             (*env)++;
     215              :         }
     216              :     } else {
     217            0 :         if ((**env >= '0') && (**env < '7')) {
     218            0 :             *ll = **env - '0';
     219            0 :             (*env)++;
     220            0 :         } else if (dlt_env_extract_symbolic_ll(env, ll) != 0) {
     221              :             return -1;
     222              :         }
     223              :     }
     224              : 
     225              :     /* check end, either next char is NULL or ';' */
     226            0 :     if ((**env == ';') || (**env == 0)) {
     227              :         return 0;
     228              :     }
     229              : 
     230              :     return -1;
     231              : }
     232              : 
     233              : 
     234              : /**
     235              :  * @brief extract one item out of string
     236              :  *
     237              :  * @return 0 if successful, -1 else
     238              :  */
     239            0 : int dlt_env_extract_ll_item(char **const env, dlt_env_ll_item *const item)
     240              : {
     241              :     int ret = -1;
     242              : 
     243            0 :     if (!env || !item) {
     244              :         return -1;
     245              :     }
     246              : 
     247            0 :     if (!(*env)) {
     248              :         return -1;
     249              :     }
     250              : 
     251              :     memset(item, 0, sizeof(dlt_env_ll_item));
     252            0 :     ret = dlt_env_extract_id(env, item->appId);
     253              : 
     254            0 :     if (ret == -1) {
     255              :         return -1;
     256              :     }
     257              : 
     258            0 :     (*env)++;
     259            0 :     ret = dlt_env_extract_id(env, item->ctxId);
     260              : 
     261            0 :     if (ret == -1) {
     262              :         return -1;
     263              :     }
     264              : 
     265            0 :     (*env)++;
     266            0 :     ret = dlt_env_extract_ll(env, &item->ll);
     267              : 
     268            0 :     if (ret == -1) {
     269              :         return -1;
     270              :     }
     271              : 
     272              :     return 0;
     273              : }
     274              : 
     275              : 
     276              : /**
     277              :  * @brief initialize ll_set
     278              :  *
     279              :  * Must call release_ll_set before exit to release all memory
     280              :  *
     281              :  * @return -1 if memory could not be allocated
     282              :  * @return 0 on success
     283              :  */
     284            0 : int dlt_env_init_ll_set(dlt_env_ll_set *const ll_set)
     285              : {
     286            0 :     if (!ll_set) {
     287              :         return -1;
     288              :     }
     289              : 
     290            0 :     ll_set->array_size = DLT_ENV_LL_SET_INCREASE;
     291            0 :     ll_set->item = (dlt_env_ll_item *)malloc(sizeof(dlt_env_ll_item) * ll_set->array_size);
     292              : 
     293            0 :     if (!ll_set->item) {
     294              :         /* should trigger a warning: no memory left */
     295            0 :         ll_set->array_size = 0;
     296            0 :         return -1;
     297              :     }
     298              : 
     299            0 :     ll_set->num_elem = 0u;
     300            0 :     return 0;
     301              : }
     302              : 
     303              : 
     304              : /**
     305              :  * @brief release ll_set
     306              :  */
     307        21213 : void dlt_env_free_ll_set(dlt_env_ll_set *const ll_set)
     308              : {
     309        21213 :     if (!ll_set) {
     310              :         return;
     311              :     }
     312              : 
     313        21213 :     if (ll_set->item != NULL) {
     314            0 :         free(ll_set->item);
     315            0 :         ll_set->item = NULL;
     316              :     }
     317              : 
     318        21213 :     ll_set->array_size = 0u;
     319        21213 :     ll_set->num_elem = 0u;
     320              : }
     321              : 
     322              : 
     323              : /**
     324              :  * @brief increase size of ll_set by LL_SET_INCREASE elements
     325              :  *
     326              :  * @return -1 if memory could not be allocated
     327              :  * @return 0 on success
     328              :  */
     329            0 : int dlt_env_increase_ll_set(dlt_env_ll_set *const ll_set)
     330              : {
     331              :     dlt_env_ll_item *old_set;
     332              :     size_t old_size;
     333              : 
     334            0 :     if (!ll_set) {
     335              :         return -1;
     336              :     }
     337              : 
     338            0 :     old_set = ll_set->item;
     339            0 :     old_size = ll_set->array_size;
     340              : 
     341            0 :     ll_set->array_size += DLT_ENV_LL_SET_INCREASE;
     342            0 :     ll_set->item = (dlt_env_ll_item *)malloc(sizeof(dlt_env_ll_item) * ll_set->array_size);
     343              : 
     344            0 :     if (!ll_set->item) {
     345              :         /* should trigger a warning: no memory left */
     346            0 :         ll_set->array_size -= DLT_ENV_LL_SET_INCREASE;
     347            0 :         return -1;
     348              :     } else {
     349            0 :         memcpy(ll_set->item, old_set, sizeof(dlt_env_ll_item) * old_size);
     350            0 :         free(old_set);
     351            0 :         return 0;
     352              :     }
     353              : }
     354              : 
     355              : 
     356              : /**
     357              :  * @brief extract all items out of string
     358              :  *
     359              :  * The given set is initialized within this function (memory is allocated).
     360              :  * Make sure, that the caller frees this memory when it is no longer needed!
     361              :  *
     362              :  * @return 0 if successful, -1 else
     363              :  */
     364            0 : int dlt_env_extract_ll_set(char **const env, dlt_env_ll_set *const ll_set)
     365              : {
     366            0 :     if (!env || !ll_set) {
     367              :         return -1;
     368              :     }
     369              : 
     370            0 :     if (!(*env)) {
     371              :         return -1;
     372              :     }
     373              : 
     374            0 :     if (dlt_env_init_ll_set(ll_set) == -1) {
     375              :         return -1;
     376              :     }
     377              : 
     378              :     do {
     379            0 :         if (ll_set->num_elem == ll_set->array_size) {
     380            0 :             if (dlt_env_increase_ll_set(ll_set) == -1) {
     381              :                 return -1;
     382              :             }
     383              :         }
     384              : 
     385            0 :         if (dlt_env_extract_ll_item(env, &ll_set->item[ll_set->num_elem++]) == -1) {
     386              :             return -1;
     387              :         }
     388              : 
     389            0 :         if (**env == ';') {
     390            0 :             (*env)++;
     391              :         }
     392            0 :     } while (**env != 0);
     393              : 
     394              :     return 0;
     395              : }
     396              : 
     397              : 
     398              : /**
     399              :  * @brief check if two ids match
     400              :  *
     401              :  * @return 1 if matching, 0 if not
     402              :  */
     403            0 : int dlt_env_ids_match(char const *const a, char const *const b)
     404              : {
     405            0 :     if (a[0] != b[0]) {
     406              :         return 0;
     407              :     }
     408              : 
     409            0 :     if (a[1] != b[1]) {
     410              :         return 0;
     411              :     }
     412              : 
     413            0 :     if (a[2] != b[2]) {
     414              :         return 0;
     415              :     }
     416              : 
     417            0 :     if (a[3] != b[3]) {
     418            0 :         return 0;
     419              :     }
     420              : 
     421              :     return 1;
     422              : }
     423              : 
     424              : 
     425              : /**
     426              :  * @brief check if (and how) apid and ctid match with given item
     427              :  *
     428              :  * Resulting priorities:
     429              :  * - no apid, no ctid only ll given in item: use ll with prio 1
     430              :  * - no apid, ctid matches: use ll with prio 2
     431              :  * - no ctid, apid matches: use ll with prio 3
     432              :  * - apid, ctid matches: use ll with prio 4
     433              :  *
     434              :  * In case of error, -1 is returned.
     435              :  */
     436            0 : int dlt_env_ll_item_get_matching_prio(dlt_env_ll_item const *const item,
     437              :                                       char const *const apid,
     438              :                                       char const *const ctid)
     439              : {
     440            0 :     if ((!item) || (!apid) || (!ctid)) {
     441              :         return -1;
     442              :     }
     443              : 
     444            0 :     if (item->appId[0] == 0) {
     445            0 :         if (item->ctxId[0] == 0) {
     446              :             return 1;
     447            0 :         } else if (dlt_env_ids_match(item->ctxId, ctid)) {
     448              :             return 2;
     449              :         }
     450            0 :     } else if (dlt_env_ids_match(item->appId, apid)) {
     451            0 :         if (item->ctxId[0] == 0) {
     452              :             return 3;
     453            0 :         } else if (dlt_env_ids_match(item->ctxId, ctid)) {
     454              :             return 4;
     455              :         }
     456              :     }
     457              : 
     458              :     return 0;
     459              : }
     460              : 
     461              : 
     462              : /**
     463              :  * @brief adjust log-level based on values given through environment
     464              :  *
     465              :  * Iterate over the set of items, and find the best match (\see ll_item_get_matching_prio)
     466              :  * For any item that matches, the one with the highest priority is selected and that
     467              :  * log-level is returned.
     468              :  *
     469              :  * If no item matches or in case of error, the original log-level (\param ll) is returned
     470              :  */
     471          205 : int dlt_env_adjust_ll_from_env(dlt_env_ll_set const *const ll_set,
     472              :                                char const *const apid,
     473              :                                char const *const ctid,
     474              :                                int const ll)
     475              : {
     476          205 :     if ((!ll_set) || (!apid) || (!ctid)) {
     477              :         return ll;
     478              :     }
     479              : 
     480              :     int res = ll;
     481              :     int prio = 0; /* no match so far */
     482              :     size_t i;
     483              : 
     484          205 :     for (i = 0; i < ll_set->num_elem; ++i) {
     485            0 :         int p = dlt_env_ll_item_get_matching_prio(&ll_set->item[i], apid, ctid);
     486              : 
     487            0 :         if (p > prio) {
     488              :             prio = p;
     489            0 :             res = ll_set->item[i].ll;
     490              : 
     491            0 :             if (p == 4) { /* maximum reached, immediate return */
     492            0 :                 return res;
     493              :             }
     494              :         }
     495              :     }
     496              : 
     497              :     return res;
     498              : }
     499              : 
     500              : 
        

Generated by: LCOV version 2.0-1