LCOV - code coverage report
Current view: top level - lib - dlt_env_ll.c (source / functions) Hit Total Coverage
Test: dlt_final_coverage.info Lines: 8 132 6.1 %
Date: 2024-11-20 10:17:27 Functions: 2 12 16.7 %

          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           0 :         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           0 :         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           0 :         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           0 :         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       18475 : void dlt_env_free_ll_set(dlt_env_ll_set *const ll_set)
     308             : {
     309       18475 :     if (!ll_set) {
     310             :         return;
     311             :     }
     312             : 
     313       18475 :     if (ll_set->item != NULL) {
     314           0 :         free(ll_set->item);
     315           0 :         ll_set->item = NULL;
     316             :     }
     317             : 
     318       18475 :     ll_set->array_size = 0u;
     319       18475 :     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           0 :             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           0 :             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 1.14