Skip to content

Commit 1b92ff4

Browse files
authored
Merge pull request #2609 from pi-hole/tweak/autocomplete
Fix default value autocomplete suggestions
2 parents 07b55cd + bbed576 commit 1b92ff4

File tree

1 file changed

+170
-115
lines changed

1 file changed

+170
-115
lines changed

src/args.c

Lines changed: 170 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -1419,139 +1419,194 @@ void suggest_complete(const int argc, char *argv[])
14191419
if(strcmp(conf_item->k, argv[4]) == 0)
14201420
{
14211421
// See if we can suggest a value
1422-
if(conf_item->t == CONF_BOOL || conf_item->t == CONF_ALL_DEBUG_BOOL)
1422+
switch(conf_item->t)
14231423
{
1424-
// pihole-FTL --config <boolean option>> ...
1425-
const char *options[] = {
1426-
"true", "false"
1427-
};
1424+
case CONF_BOOL:
1425+
case CONF_ALL_DEBUG_BOOL:
1426+
{
1427+
// pihole-FTL --config <boolean option>> ...
1428+
const char *options[] = {
1429+
"true", "false"
1430+
};
1431+
1432+
// Provide matching suggestions
1433+
list_matches(last_word, options, ArraySize(options), false);
1434+
break;
1435+
}
14281436

1429-
// Provide matching suggestions
1430-
list_matches(last_word, options, ArraySize(options), false);
1431-
}
1432-
else if(conf_item->t == CONF_INT ||
1433-
conf_item->t == CONF_UINT ||
1434-
conf_item->t == CONF_UINT16 ||
1435-
conf_item->t == CONF_LONG ||
1436-
conf_item->t == CONF_DOUBLE ||
1437-
conf_item->t == CONF_STRING ||
1438-
conf_item->t == CONF_STRING_ALLOCATED ||
1439-
conf_item->t == CONF_JSON_STRING_ARRAY)
1440-
{
1441-
// pihole-FTL --config ... <int/long/double/string>
1442-
// Provide the default value as suggestion
1443-
char *value = NULL;
1444-
cJSON *val = addJSONConfValue(conf_item->t, &conf_item->d);
1445-
if(val != NULL && (value = cJSON_PrintUnformatted(val)) != NULL)
1437+
case CONF_INT:
1438+
case CONF_UINT:
1439+
case CONF_UINT16:
1440+
case CONF_LONG:
1441+
case CONF_DOUBLE:
1442+
case CONF_STRING:
1443+
case CONF_STRING_ALLOCATED:
1444+
case CONF_JSON_STRING_ARRAY:
14461445
{
1447-
// Add '' to the output if it is a string
1448-
if(conf_item->t == CONF_STRING ||
1449-
conf_item->t == CONF_STRING_ALLOCATED ||
1450-
conf_item->t == CONF_JSON_STRING_ARRAY)
1446+
// pihole-FTL --config ... <int/long/double/string>
1447+
// Provide the default value as suggestion
1448+
char *value = NULL;
1449+
cJSON *val = addJSONConfValue(conf_item->t, &conf_item->d);
1450+
if(val != NULL && (value = cJSON_PrintUnformatted(val)) != NULL)
14511451
{
1452-
// If the value is a string, we need to add quotes
1453-
if(value[0] != '\'')
1452+
// Add '' to the output if it is a string
1453+
if(conf_item->t == CONF_JSON_STRING_ARRAY)
14541454
{
1455-
char *tmp = malloc(strlen(value) + 3);
1455+
// Count number of ' in the string
1456+
char *p = value;
1457+
unsigned int count = 0;
1458+
while(p != NULL && *p != '\0')
1459+
{
1460+
if(*p == '\'')
1461+
count++;
1462+
p++;
1463+
}
1464+
1465+
// Allocate enough space for the new string
1466+
char *tmp = calloc(strlen(value) + 5*count + 3, sizeof(char));
14561467
if(tmp != NULL)
14571468
{
1458-
sprintf(tmp, "'%s'", value);
1469+
memcpy(tmp + 1, value, strlen(value) + 1);
1470+
// Scan for ' characters ...
1471+
p = tmp + 1;
1472+
while(*p != '\0')
1473+
{
1474+
if(*p == '\'')
1475+
{
1476+
// ... and replace them by '"'"'
1477+
memmove(p + 4, p, strlen(p) + 1);
1478+
*(p++) = '\'';
1479+
*(p++) = '"';
1480+
*(p++) = '\'';
1481+
*(p++) = '"';
1482+
}
1483+
p++;
1484+
}
1485+
1486+
tmp[0] = '\'';
1487+
tmp[strlen(tmp)] = '\'';
14591488
free(value);
14601489
value = tmp;
14611490
}
14621491
}
1463-
}
14641492

1465-
// If the default value starts with the last word we are trying to complete,
1466-
// print it as a suggestion
1467-
// If the last word is empty, print the value anyway
1468-
if(strStartsWith(value, last_word) || strlen(last_word) == 0)
1469-
puts(value);
1470-
free(value);
1471-
}
1472-
cJSON_Delete(val);
1473-
}
1474-
else if(conf_item->t == CONF_ENUM_PTR_TYPE)
1475-
{
1476-
// Provide matching suggestions
1477-
for(size_t j = 0; j < PTR_MAX; j++)
1478-
{
1479-
const char *ptr = get_ptr_type_str(j);
1480-
if(strStartsWithIgnoreCase(ptr, last_word) || strlen(last_word) == 0)
1481-
puts(ptr);
1482-
}
1483-
}
1484-
else if(conf_item->t == CONF_ENUM_BUSY_TYPE)
1485-
{
1486-
// Provide matching suggestions
1487-
for(size_t j = 0; j < BUSY_MAX; j++)
1488-
{
1489-
const char *busy = get_busy_reply_str(j);
1490-
if(strStartsWithIgnoreCase(busy, last_word) || strlen(last_word) == 0)
1491-
puts(busy);
1492-
}
1493-
}
1494-
else if(conf_item->t == CONF_ENUM_BLOCKING_MODE)
1495-
{
1496-
// Provide matching suggestions
1497-
for(size_t j = 0; j < MODE_MAX; j++)
1498-
{
1499-
const char *mode = get_blocking_mode_str(j);
1500-
if(strStartsWithIgnoreCase(mode, last_word) || strlen(last_word) == 0)
1501-
puts(mode);
1502-
}
1503-
}
1504-
else if(conf_item->t == CONF_ENUM_REFRESH_HOSTNAMES)
1505-
{
1506-
// Provide matching suggestions
1507-
for(size_t j = 0; j < REFRESH_MAX; j++)
1508-
{
1509-
const char *refresh = get_refresh_hostnames_str(j);
1510-
if(strStartsWithIgnoreCase(refresh, last_word) || strlen(last_word) == 0)
1511-
puts(refresh);
1512-
}
1513-
}
1514-
else if(conf_item->t == CONF_ENUM_LISTENING_MODE)
1515-
{
1516-
// Provide matching suggestions
1517-
for(size_t j = 0; j < LISTEN_MAX; j++)
1518-
{
1519-
const char *listen = get_listeningMode_str(j);
1520-
if(strStartsWithIgnoreCase(listen, last_word) || strlen(last_word) == 0)
1521-
puts(listen);
1493+
// If the default value starts with the last word we are trying to complete,
1494+
// print it as a suggestion
1495+
// If the last word is empty, print the value anyway
1496+
if(strStartsWith(value, last_word) || strlen(last_word) == 0)
1497+
puts(value);
1498+
free(value);
1499+
}
1500+
cJSON_Delete(val);
1501+
break;
15221502
}
1523-
}
1524-
else if(conf_item->t == CONF_ENUM_WEB_THEME)
1525-
{
1526-
// pihole-FTL --config webserver.interface.theme ...
15271503

1528-
// Provide matching suggestions
1529-
for(size_t j = 0; j < THEME_MAX; j++)
1530-
{
1531-
const char *theme = get_web_theme_str(j);
1532-
if(strStartsWithIgnoreCase(theme, last_word) || strlen(last_word) == 0)
1533-
puts(theme);
1534-
}
1535-
}
1536-
else if(conf_item->t == CONF_ENUM_BLOCKING_EDNS_MODE)
1537-
{
1538-
// Provide matching suggestions
1539-
for(size_t j = 0; j < EDNS_MODE_MAX; j++)
1504+
case CONF_ENUM_PTR_TYPE:
1505+
// Provide matching suggestions
1506+
for(size_t j = 0; j < PTR_MAX; j++)
1507+
{
1508+
const char *ptr = get_ptr_type_str(j);
1509+
if(strStartsWithIgnoreCase(ptr, last_word) || strlen(last_word) == 0)
1510+
puts(ptr);
1511+
}
1512+
break;
1513+
1514+
case CONF_ENUM_BUSY_TYPE:
1515+
// Provide matching suggestions
1516+
for(size_t j = 0; j < BUSY_MAX; j++)
1517+
{
1518+
const char *busy = get_busy_reply_str(j);
1519+
if(strStartsWithIgnoreCase(busy, last_word) || strlen(last_word) == 0)
1520+
puts(busy);
1521+
}
1522+
break;
1523+
1524+
case CONF_ENUM_BLOCKING_MODE:
1525+
// Provide matching suggestions
1526+
for(size_t j = 0; j < MODE_MAX; j++)
1527+
{
1528+
const char *mode = get_blocking_mode_str(j);
1529+
if(strStartsWithIgnoreCase(mode, last_word) || strlen(last_word) == 0)
1530+
puts(mode);
1531+
}
1532+
break;
1533+
1534+
case CONF_ENUM_REFRESH_HOSTNAMES:
1535+
// Provide matching suggestions
1536+
for(size_t j = 0; j < REFRESH_MAX; j++)
1537+
{
1538+
const char *refresh = get_refresh_hostnames_str(j);
1539+
if(strStartsWithIgnoreCase(refresh, last_word) || strlen(last_word) == 0)
1540+
puts(refresh);
1541+
}
1542+
break;
1543+
1544+
case CONF_ENUM_LISTENING_MODE:
1545+
// Provide matching suggestions
1546+
for(size_t j = 0; j < LISTEN_MAX; j++)
1547+
{
1548+
const char *listen = get_listeningMode_str(j);
1549+
if(strStartsWithIgnoreCase(listen, last_word) || strlen(last_word) == 0)
1550+
puts(listen);
1551+
}
1552+
break;
1553+
1554+
case CONF_ENUM_WEB_THEME:
1555+
// pihole-FTL --config webserver.interface.theme ...
1556+
1557+
// Provide matching suggestions
1558+
for(size_t j = 0; j < THEME_MAX; j++)
1559+
{
1560+
const char *theme = get_web_theme_str(j);
1561+
if(strStartsWithIgnoreCase(theme, last_word) || strlen(last_word) == 0)
1562+
puts(theme);
1563+
}
1564+
break;
1565+
1566+
case CONF_ENUM_BLOCKING_EDNS_MODE:
1567+
// Provide matching suggestions
1568+
for(size_t j = 0; j < EDNS_MODE_MAX; j++)
1569+
{
1570+
const char *edns = get_edns_mode_str(j);
1571+
if(strStartsWithIgnoreCase(edns, last_word) || strlen(last_word) == 0)
1572+
puts(edns);
1573+
}
1574+
break;
1575+
1576+
case CONF_ENUM_TEMP_UNIT:
1577+
// Provide matching suggestions
1578+
for(size_t j = 0; j < TEMP_UNIT_MAX; j++)
1579+
{
1580+
const char *temp = get_temp_unit_str(j);
1581+
if(strStartsWithIgnoreCase(temp, last_word) || strlen(last_word) == 0)
1582+
puts(temp);
1583+
}
1584+
break;
1585+
1586+
case CONF_ENUM_PRIVACY_LEVEL:
1587+
// This enum is in reality a numeric value
1588+
printf("%d\n", (int)conf_item->d.privacy_level);
1589+
break;
1590+
1591+
case CONF_PASSWORD:
1592+
// No suggestions
1593+
break;
1594+
1595+
case CONF_STRUCT_IN_ADDR:
15401596
{
1541-
const char *edns = get_edns_mode_str(j);
1542-
if(strStartsWithIgnoreCase(edns, last_word) || strlen(last_word) == 0)
1543-
puts(edns);
1597+
char ip[INET_ADDRSTRLEN] = { 0 };
1598+
inet_ntop(AF_INET, &conf_item->d.in_addr.s_addr, ip, sizeof(ip));
1599+
printf("%s\n", ip);
15441600
}
1545-
}
1546-
else if(conf_item->t == CONF_ENUM_TEMP_UNIT)
1547-
{
1548-
// Provide matching suggestions
1549-
for(size_t j = 0; j < TEMP_UNIT_MAX; j++)
1601+
break;
1602+
1603+
case CONF_STRUCT_IN6_ADDR:
15501604
{
1551-
const char *temp = get_temp_unit_str(j);
1552-
if(strStartsWithIgnoreCase(temp, last_word) || strlen(last_word) == 0)
1553-
puts(temp);
1605+
char ip[INET6_ADDRSTRLEN] = { 0 };
1606+
inet_ntop(AF_INET6, &conf_item->d.in6_addr, ip, sizeof(ip));
1607+
printf("%s\n", ip);
15541608
}
1609+
break;
15551610
}
15561611
}
15571612
}

0 commit comments

Comments
 (0)