249 lines
4.6 KiB
C
249 lines
4.6 KiB
C
#include "expand_line.h"
|
|
#include "utils.h"
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
|
|
#define DELIMS "\t []{}<>=+-*/%!&|^.,:;()\\"
|
|
|
|
char *_compute_expanded_line(void *def_map, char *line);
|
|
int _concat_expanded_token_to_line(void *def_map, char *token, char **line);
|
|
int _concat_delim_to_line(char *delim, int delim_size, char **line);
|
|
char *_get_expanded_token(void *def_map, char *token);
|
|
int _concat_delim_to_line(char *delim, int delim_size, char **line);
|
|
int _concat_expanded_token_to_line(void *def_map, char *token, char **line);
|
|
int _is_delim_at_str_start(char *token, char *str_start);
|
|
int _compute_delim_start(char *token, char *line);
|
|
int _compute_delim_end(char *token, char *line, char *line_copy);
|
|
|
|
int write_expanded_line(void *def_map, char *line, FILE *out)
|
|
{
|
|
char *exp_line;
|
|
int line_len;
|
|
int ret;
|
|
|
|
exp_line = get_expanded_line(def_map, line);
|
|
if (!exp_line)
|
|
return PP_FAILED;
|
|
|
|
line_len = strlen(exp_line);
|
|
|
|
ret = fprintf(out, "%s", exp_line);
|
|
free(exp_line);
|
|
|
|
if (ret < 0)
|
|
return PP_FAILED;
|
|
return ret == line_len ? PP_OK : PP_FAILED;
|
|
}
|
|
|
|
char *get_expanded_line(void *def_map, char *line)
|
|
{
|
|
char *exp_line;
|
|
char *prev_exp_line;
|
|
|
|
exp_line = NULL;
|
|
prev_exp_line = NULL;
|
|
|
|
exp_line = _compute_expanded_line(def_map, line);
|
|
if (!exp_line)
|
|
return NULL;
|
|
|
|
prev_exp_line = l_strdup(line);
|
|
if (!prev_exp_line)
|
|
goto free_and_exit;
|
|
|
|
while (strcmp(prev_exp_line, exp_line)) {
|
|
free(prev_exp_line);
|
|
prev_exp_line = exp_line;
|
|
|
|
exp_line = _compute_expanded_line(def_map, prev_exp_line);
|
|
if (!exp_line)
|
|
goto free_and_exit;
|
|
}
|
|
|
|
free(prev_exp_line);
|
|
return exp_line;
|
|
|
|
free_and_exit:
|
|
free(prev_exp_line);
|
|
free(exp_line);
|
|
return NULL;
|
|
}
|
|
|
|
char *_compute_expanded_line(void *def_map, char *line)
|
|
{
|
|
char *_line;
|
|
char *line_start;
|
|
char *line_copy;
|
|
char *token;
|
|
char *exp_line;
|
|
|
|
int delim_start;
|
|
int delim_end;
|
|
int ret;
|
|
int token_len;
|
|
|
|
_line = NULL;
|
|
line_copy = NULL;
|
|
exp_line = NULL;
|
|
|
|
_line = l_strdup(line);
|
|
if (!_line)
|
|
goto free_and_exit;
|
|
|
|
line_start = _line;
|
|
|
|
line_copy = l_strdup(_line);
|
|
if (!line_copy)
|
|
goto free_and_exit;
|
|
|
|
exp_line = calloc(1, sizeof(char));
|
|
if (!exp_line)
|
|
goto free_and_exit;
|
|
|
|
token = strtok(_line, DELIMS);
|
|
|
|
if (_is_delim_at_str_start(token, line_start)) {
|
|
ret = _concat_delim_to_line(
|
|
line_start,
|
|
token - line_start,
|
|
&exp_line
|
|
);
|
|
if (ret == PP_FAILED)
|
|
goto free_and_exit;
|
|
}
|
|
|
|
ret = _concat_expanded_token_to_line(def_map, token, &exp_line);
|
|
if (ret == PP_FAILED)
|
|
goto free_and_exit;
|
|
|
|
while (token) {
|
|
delim_start = _compute_delim_start(token, _line);
|
|
token = strtok(NULL, DELIMS);
|
|
delim_end = _compute_delim_end(token, _line, line_copy);
|
|
|
|
ret = _concat_delim_to_line(
|
|
line_copy + delim_start,
|
|
delim_end - delim_start,
|
|
&exp_line
|
|
);
|
|
if (ret == PP_FAILED)
|
|
goto free_and_exit;
|
|
|
|
if (token) {
|
|
token_len = strlen(token);
|
|
if (token[token_len - 1] == '\n')
|
|
token[token_len - 1] = 0x00;
|
|
|
|
_concat_expanded_token_to_line(
|
|
def_map,
|
|
token,
|
|
&exp_line
|
|
);
|
|
|
|
if (token[token_len - 1] == 0x00) {
|
|
token[token_len - 1] = '\n';
|
|
_concat_delim_to_line("\n", 1, &exp_line);
|
|
}
|
|
|
|
if (ret == PP_FAILED)
|
|
goto free_and_exit;
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
|
|
free(line_copy);
|
|
free(_line);
|
|
return exp_line;
|
|
|
|
free_and_exit:
|
|
free(_line);
|
|
free(line_copy);
|
|
free(exp_line);
|
|
|
|
return NULL;
|
|
}
|
|
char *_get_expanded_token(void *def_map, char *token)
|
|
{
|
|
char *exp;
|
|
char *exp_copy;
|
|
|
|
int ret;
|
|
int token_len;
|
|
|
|
exp = NULL;
|
|
exp_copy = NULL;
|
|
|
|
ret = hashmap_get(def_map, token, &exp);
|
|
|
|
if (ret != MAP_OK) {
|
|
token_len = strlen(token);
|
|
|
|
exp_copy = calloc(token_len + 1, sizeof(char));
|
|
if (!exp_copy)
|
|
goto free_and_exit;
|
|
|
|
strcpy(exp_copy, token);
|
|
} else {
|
|
exp_copy = l_strdup(exp);
|
|
if (!exp_copy)
|
|
goto free_and_exit;
|
|
}
|
|
|
|
return exp_copy;
|
|
|
|
free_and_exit:
|
|
free(exp_copy);
|
|
return NULL;
|
|
}
|
|
|
|
int _concat_delim_to_line(char *delim, int delim_size, char **line)
|
|
{
|
|
char *_delim;
|
|
int ret;
|
|
|
|
_delim = NULL;
|
|
|
|
_delim = calloc(delim_size + 1, sizeof(char));
|
|
if (!_delim)
|
|
return PP_FAILED;
|
|
|
|
strncpy(_delim, delim, delim_size);
|
|
|
|
ret = a_strcat(line, _delim);
|
|
free(_delim);
|
|
|
|
return ret == -1 ? PP_FAILED : PP_OK;
|
|
}
|
|
|
|
int _concat_expanded_token_to_line(void *def_map, char *token, char **line)
|
|
{
|
|
char *exp;
|
|
int ret;
|
|
|
|
exp = _get_expanded_token(def_map, token);
|
|
if (!exp)
|
|
return PP_FAILED;
|
|
|
|
ret = a_strcat(line, exp);
|
|
free(exp);
|
|
|
|
return ret == -1 ? PP_FAILED : PP_OK;
|
|
}
|
|
|
|
int _is_delim_at_str_start(char *token, char *str_start)
|
|
{
|
|
return token - str_start;
|
|
}
|
|
|
|
int _compute_delim_start(char *token, char *line)
|
|
{
|
|
return token - line + strlen(token);
|
|
}
|
|
|
|
int _compute_delim_end(char *token, char *line, char *line_copy)
|
|
{
|
|
return token != NULL ? token - line : (int) strlen(line_copy);
|
|
}
|
|
|