| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404 |
- /******************************************************************************
- * This file is part of TinTin++ *
- * *
- * Copyright 2004-2019 Igor van den Hoven *
- * *
- * TinTin++ is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 3 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with TinTin++. If not, see https://www.gnu.org/licenses. *
- ******************************************************************************/
- /******************************************************************************
- * (T)he K(I)cki(N) (T)ickin D(I)kumud Clie(N)t *
- * *
- * coded by Bill Reiss 1993 *
- * recoded by Igor van den Hoven 2004 *
- ******************************************************************************/
- #include "tintin.h"
- DO_COMMAND(do_variable)
- {
- char arg1[BUFFER_SIZE], *str;
- struct listroot *root = ses->list[LIST_VARIABLE];
- struct listnode *node;
- arg = sub_arg_in_braces(ses, arg, arg1, GET_NST, SUB_VAR|SUB_FUN);
- if (*arg1 == 0)
- {
- show_list(root, 0);
- }
- else if (*arg == 0)
- {
- node = search_nest_node(root, arg1);
- if (node)
- {
- if (node->root)
- {
- char *str_result;
- str_result = str_dup("");
- view_nest_node(node, &str_result, 0, 1);
- print_lines(ses, SUB_NONE, COLOR_TINTIN "%c" COLOR_COMMAND "%s " COLOR_BRACE "{" COLOR_STRING "%s" COLOR_BRACE "}\n{\n" COLOR_STRING "%s" COLOR_BRACE "}" COLOR_RESET "\n", gtd->tintin_char, list_table[LIST_VARIABLE].name, node->arg1, str_result);
- str_free(str_result);
- }
- else
- {
- tintin_printf2(ses, COLOR_TINTIN "%c" COLOR_COMMAND "%s " COLOR_BRACE "{" COLOR_STRING "%s" COLOR_BRACE "} {" COLOR_STRING "%s" COLOR_BRACE "}" COLOR_RESET "\n", gtd->tintin_char, list_table[LIST_VARIABLE].name, node->arg1, node->arg2);
- }
- }
- else if (show_node_with_wild(ses, arg1, ses->list[LIST_VARIABLE]) == FALSE)
- {
- show_message(ses, LIST_VARIABLE, "#VARIABLE: NO MATCH(ES) FOUND FOR {%s}.", arg1);
- }
- }
- else
- {
- if (!valid_variable(ses, arg1))
- {
- show_message(ses, LIST_VARIABLE, "#VARIABLE: INVALID VARIALBE NAME {%s}.", arg1);
- return ses;
- }
- str = str_alloc(UMAX(strlen(arg), BUFFER_SIZE));
- arg = sub_arg_in_braces(ses, arg, str, GET_ALL, SUB_VAR|SUB_FUN);
- node = set_nest_node(root, arg1, "%s", str);
- while (*arg)
- {
- arg = sub_arg_in_braces(ses, arg, str, GET_ALL, SUB_VAR|SUB_FUN);
- if (*str)
- {
- add_nest_node(root, arg1, "%s", str);
- }
- }
- show_nest_node(node, &str, 1);
- show_message(ses, LIST_VARIABLE, "#OK. VARIABLE {%s} HAS BEEN SET TO {%s}.", arg1, str);
- str_free(str);
- }
- return ses;
- }
- DO_COMMAND(do_local)
- {
- char arg1[BUFFER_SIZE], *str;
- struct listroot *root;
- struct listnode *node;
- root = local_list(ses);
- arg = sub_arg_in_braces(ses, arg, arg1, GET_NST, SUB_VAR|SUB_FUN);
- if (*arg1 == 0)
- {
- show_list(root, 0);
- }
- else if (*arg1 && *arg == 0)
- {
- root = search_nest_base_ses(ses, arg1);
- if (root)
- {
- node = search_nest_node_ses(ses, arg1);
- }
- else
- {
- root = local_list(ses);
- node = NULL;
- }
- if (node)
- {
- show_node(root, node, 0);
- }
- else if (show_node_with_wild(ses, arg1, root) == FALSE)
- {
- show_message(ses, LIST_VARIABLE, "#LOCAL: NO MATCH(ES) FOUND FOR {%s}.", arg1);
- }
- }
- else
- {
- str = str_alloc(UMAX(strlen(arg), BUFFER_SIZE));
- arg = sub_arg_in_braces(ses, arg, str, GET_ALL, SUB_VAR|SUB_FUN);
- node = set_nest_node(root, arg1, "%s", str);
- while (*arg)
- {
- arg = sub_arg_in_braces(ses, arg, str, GET_ALL, SUB_VAR|SUB_FUN);
- if (*str)
- {
- add_nest_node(root, arg1, "%s", str);
- }
- }
- show_nest_node(node, &str, 1);
- show_message(ses, LIST_VARIABLE, "#OK. LOCAL VARIABLE {%s} HAS BEEN SET TO {%s}.", arg1, str);
- str_free(str);
- SET_BIT(gtd->flags, TINTIN_FLAG_LOCAL);
- }
- return ses;
- }
- DO_COMMAND(do_unvariable)
- {
- char arg1[BUFFER_SIZE];
- arg = sub_arg_in_braces(ses, arg, arg1, GET_ALL, SUB_VAR|SUB_FUN);
- do
- {
- if (delete_nest_node(ses->list[LIST_VARIABLE], arg1))
- {
- show_message(ses, LIST_VARIABLE, "#OK. {%s} IS NO LONGER A VARIABLE.", arg1);
- }
- else
- {
- delete_node_with_wild(ses, LIST_VARIABLE, arg1);
- }
- arg = sub_arg_in_braces(ses, arg, arg1, GET_ALL, SUB_VAR|SUB_FUN);
- }
- while (*arg1);
- return ses;
- }
- DO_COMMAND(do_cat)
- {
- char arg1[BUFFER_SIZE], *str;
- struct listnode *node;
- arg = sub_arg_in_braces(ses, arg, arg1, GET_NST, SUB_VAR|SUB_FUN);
- if (*arg1 == 0 || *arg == 0)
- {
- show_error(ses, LIST_COMMAND, "#SYNTAX: CAT {<VARIABLE>} {<ARGUMENT>}");
- }
- else
- {
- str = str_alloc(UMAX(strlen(arg), BUFFER_SIZE));
- if ((node = search_nest_node_ses(ses, arg1)) == NULL)
- {
- arg = sub_arg_in_braces(ses, arg, str, GET_ALL, SUB_VAR|SUB_FUN);
- node = set_nest_node(ses->list[LIST_VARIABLE], arg1, "%s", str);
- }
- while (*arg)
- {
- arg = sub_arg_in_braces(ses, arg, str, GET_ALL, SUB_VAR|SUB_FUN);
- check_all_events(ses, SUB_ARG, 1, 2, "VARIABLE UPDATE %s", arg1, arg1, str);
- if (*str)
- {
- str_cat(&node->arg2, str);
- }
- }
- check_all_events(ses, SUB_ARG, 1, 1, "VARIABLE UPDATED %s", arg1, arg1, str);
- show_message(ses, LIST_VARIABLE, "#CAT: VARIABLE {%s} HAS BEEN SET TO {%s}.", arg1, node->arg2);
- str_free(str);
- }
- return ses;
- }
- DO_COMMAND(do_replace)
- {
- char arg1[BUFFER_SIZE], arg2[BUFFER_SIZE], arg3[BUFFER_SIZE], tmp[BUFFER_SIZE], *pti, *ptm, *str;
- struct listnode *node;
- arg = sub_arg_in_braces(ses, arg, arg1, GET_NST, SUB_VAR|SUB_FUN);
- arg = sub_arg_in_braces(ses, arg, arg2, GET_ONE, SUB_VAR|SUB_FUN);
- arg = sub_arg_in_braces(ses, arg, arg3, GET_ALL, SUB_VAR|SUB_FUN);
- if (*arg1 == 0 || *arg2 == 0)
- {
- show_error(ses, LIST_VARIABLE, "#SYNTAX: #REPLACE {VARIABLE} {OLD TEXT} {NEW TEXT}");
- return ses;
- }
- if ((node = search_nest_node_ses(ses, arg1)) == NULL)
- {
- show_error(ses, LIST_VARIABLE, "#REPLACE: VARIABLE {%s} NOT FOUND.", arg1);
- return ses;
- }
- if (tintin_regexp(ses, NULL, node->arg2, arg2, 0, REGEX_FLAG_CMD) == FALSE)
- {
- show_message(ses, LIST_VARIABLE, "#REPLACE: {%s} NOT FOUND IN {%s}.", arg2, node->arg2);
- }
- else
- {
- pti = node->arg2;
- str = str_dup("");
- do
- {
- if (*gtd->cmds[0] == 0) // Set by tintin_regexp
- {
- break;
- }
- ptm = strstr(pti, gtd->cmds[0]);
- if (ptm == NULL)
- {
- break;
- }
- *ptm = 0;
- substitute(ses, arg3, tmp, SUB_CMD);
- str_cat_printf(&str, "%s%s", pti, tmp);
- pti = ptm + strlen(gtd->cmds[0]);
- }
- while (tintin_regexp(ses, NULL, pti, arg2, 0, REGEX_FLAG_CMD));
- str_cat(&str, pti);
- str_cpy(&node->arg2, str);
- str_free(str);
- }
- return ses;
- }
- int valid_variable(struct session *ses, char *arg)
- {
- if (*arg == 0)
- {
- return FALSE;
- }
- if (is_math(ses, arg))
- {
- return FALSE;
- }
- return TRUE;
- }
- /*
- support routines for #format
- */
- unsigned long long generate_hash_key(char *str)
- {
- unsigned long long len, h = 4321;
- for (len = 0 ; *str != 0 ; str++, len++)
- {
- h = ((h << 5) + h) + *str;
- }
- h += len;
- return h;
- }
- void numbertocharacter(struct session *ses, char *str)
- {
- if (get_number(ses, str) < 256)
- {
- sprintf(str, "%c", (int) get_number(ses, str));
- }
- else if (HAS_BIT(ses->charset, CHARSET_FLAG_EUC))
- {
- sprintf(str, "%c%c", (unsigned int) get_number(ses, str) % 256, (unsigned int) get_number(ses, str) / 256);
- }
- else if (HAS_BIT(ses->charset, CHARSET_FLAG_UTF8))
- {
- unicode_to_utf8((int) get_number(ses, str), str);
- }
- else
- {
- sprintf(str, "%c", (int) get_number(ses, str));
- }
- }
- void charactertonumber(struct session *ses, char *str)
- {
- int result;
- if (HAS_BIT(ses->charset, CHARSET_FLAG_EUC) && is_euc_head(ses, str))
- {
- if (get_euc_size(ses, str) == 4)
- {
- result = (unsigned char) str[0] + (unsigned char) str[1] * 256 + (unsigned char) str[2] * 256 * 256 + (unsigned char) str[3] * 256 * 256 * 256;
- }
- else
- {
- result = (unsigned char) str[0] + (unsigned char) str[1] * 256;
- }
- }
- else if (HAS_BIT(ses->charset, CHARSET_FLAG_UTF8) && is_utf8_head(str))
- {
- get_utf8_index(str, &result);
- }
- else
- {
- result = (unsigned char) str[0];
- }
- sprintf(str, "%d", result);
- }
- void charactertohex(struct session *ses, char *str)
- {
- if (HAS_BIT(ses->charset, CHARSET_FLAG_EUC) && is_euc_head(ses, str))
- {
- if (get_euc_size(ses, str) == 4)
- {
- sprintf(str, "%u", (unsigned char) str[0] + (unsigned char) str[1] * 256 + (unsigned char) str[2] * 256 * 256 + (unsigned char) str[3] * 256 * 256 * 256);
- }
- else
- {
- sprintf(str, "%u", (unsigned char) str[0] + (unsigned char) str[1] * 256);
- }
- }
- else if (HAS_BIT(ses->charset, CHARSET_FLAG_UTF8) && is_utf8_head(str))
- {
- int result;
- get_utf8_index(str, &result);
- sprintf(str, "%u", result);
- }
- else if (!is_math(ses, str))
- {
- sprintf(str, "%u", (unsigned int) str[0]);
- }
- }
- void colorstring(struct session *ses, char *str)
- {
- char result[BUFFER_SIZE];
- get_color_names(ses, str, result);
- strcpy(str, result);
- }
- int translate_color_names(struct session *ses, char *string, char *result)
- {
- int cnt;
- *result = 0;
- if (*string == '<')
- {
- strcpy(result, string);
- return TRUE;
- }
- if (*string == '\\')
- {
- strcpy(result, string);
- return TRUE;
- }
- while (*string)
- {
- if (isalpha(*string))
- {
- for (cnt = 0 ; *color_table[cnt].name ; cnt++)
- {
- if (!strncmp(color_table[cnt].name, string, color_table[cnt].len))
- {
- result += sprintf(result, "%s", color_table[cnt].code);
- break;
- }
- }
- if (*color_table[cnt].name == 0)
- {
- for (cnt = 0 ; *color_table[cnt].name ; cnt++)
- {
- if (!strncasecmp(color_table[cnt].name, string, color_table[cnt].len))
- {
- result += sprintf(result, "%s", color_table[cnt].code);
- break;
- }
- }
- if (*color_table[cnt].name == 0)
- {
- return FALSE;
- }
- }
- string += strlen(color_table[cnt].name);
- }
- switch (*string)
- {
- case ' ':
- case ';':
- case ',':
- case '{':
- case '}':
- string++;
- break;
- case 0:
- return TRUE;
- default:
- return FALSE;
- }
- }
- return TRUE;
- }
- int get_color_names(struct session *ses, char *string, char *result)
- {
- int cnt;
- *result = 0;
- if (*string == '<')
- {
- substitute(ses, string, result, SUB_COL);
- return TRUE;
- }
- if (*string == '\\')
- {
- substitute(ses, string, result, SUB_ESC);
- return TRUE;
- }
- while (*string)
- {
- if (isalpha(*string))
- {
- for (cnt = 0 ; *color_table[cnt].name ; cnt++)
- {
- if (!strncmp(color_table[cnt].name, string, color_table[cnt].len))
- {
- substitute(ses, color_table[cnt].code, result, SUB_COL);
- result += strlen(result);
- break;
- }
- }
- if (*color_table[cnt].name == 0)
- {
- for (cnt = 0 ; *color_table[cnt].name ; cnt++)
- {
- if (!strncasecmp(color_table[cnt].name, string, color_table[cnt].len))
- {
- substitute(ses, color_table[cnt].code, result, SUB_COL);
- result += strlen(result);
- break;
- }
- }
- if (*color_table[cnt].name == 0)
- {
- return FALSE;
- }
- }
- string += strlen(color_table[cnt].name);
- }
- switch (*string)
- {
- case ' ':
- case ';':
- case ',':
- case '{':
- case '}':
- string++;
- break;
- case 0:
- return TRUE;
- default:
- return FALSE;
- }
- }
- return TRUE;
- }
- void headerstring(struct session *ses, char *str)
- {
- char buf[BUFFER_SIZE], fill[BUFFER_SIZE];
- int len, max;
- len = string_raw_str_len(ses, str, 0, BUFFER_SIZE);
- max = get_scroll_cols(ses);
- if (len > max - 2)
- {
- str[max] = 0;
- return;
- }
- memset(fill, '#', max);
- sprintf(buf, "%.*s%s%.*s%s", (max - len) / 2, fill, str, (max - len) / 2, fill, (max - len) % 2 ? "#" : "");
- strcpy(str, buf);
- }
- void lowerstring(char *str)
- {
- char *pts;
- for (pts = str ; *pts ; pts++)
- {
- *pts = tolower((int) *pts);
- }
- }
- void upperstring(char *str)
- {
- char *pts;
- for (pts = str ; *pts ; pts++)
- {
- *pts = toupper((int) *pts);
- }
- }
- void hexstring(char *str)
- {
- unsigned long long result = hex_number_64bit(str);
- unicode_to_utf8(result, str);
- }
- void reversestring(char *str)
- {
- char t;
- int a = 0, z = strlen(str) - 1;
- while (z > a)
- {
- t = str[z];
- str[z--] = str[a];
- str[a++] = t;
- }
- z = strlen(str) - 1;
- for (a = 1 ; a < z ; a++)
- {
- if (str[a] == '\\' && str[a + 1] != '\\')
- {
- str[a] = str[a - 1];
- str[a - 1] = '\\';
- }
- }
- }
- void mathstring(struct session *ses, char *str)
- {
- get_number_string(ses, str, str);
- }
- void thousandgroupingstring(struct session *ses, char *str)
- {
- char result[BUFFER_SIZE], strold[BUFFER_SIZE];
- int cnt1, cnt2, cnt3, cnt4;
- get_number_string(ses, str, strold);
- cnt1 = strlen(strold);
- cnt2 = BUFFER_SIZE / 2;
- cnt4 = strchr(strold, '.') ? 1 : 0;
- result[cnt2+1] = 0;
- for (cnt3 = 0 ; cnt1 >= 0 ; cnt1--, cnt2--)
- {
- if (cnt3++ % 3 == 0 && cnt3 != 1 && cnt4 == 0 && isdigit((int) strold[cnt1]))
- {
- result[cnt2--] = ',';
- }
- result[cnt2] = strold[cnt1];
- if (!isdigit((int) result[cnt2]))
- {
- cnt4 = 0;
- cnt3 = 0;
- continue;
- }
- }
- strcpy(str, result + cnt2 + 1);
- }
- void chronosgroupingstring(struct session *ses, char *str)
- {
- char *sign = "-";
- long long val = (long long) get_number(ses, str);
- int days, hours, minutes, seconds;
- if (val < 0)
- {
- val *= -1;
- }
- else
- {
- sign = "";
- }
- seconds = val % 60;
- val /= 60;
- minutes = val % 60;
- val /= 60;
- hours = val % 24;
- val /= 24;
- days = val;
- if (days)
- {
- sprintf(str, "%s%d:%02d:%02d:%02d", sign, days, hours, minutes, seconds);
- }
- else if (hours)
- {
- sprintf(str, "%s%d:%02d:%02d", sign, hours, minutes, seconds);
- }
- else
- {
- sprintf(str, "%s%d:%02d", sign, minutes, seconds);
- }
- }
- void metricgroupingstring(struct session *ses, char *str)
- {
- char big[] = {' ', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y', '?', '?', '?', '?', '?', '?', '?', '?'};
- char small[] = {' ', 'm', 'u', 'n', 'p', 'f', 'a', 'z', 'y', '?', '?', '?', '?', '?', '?', '?', '?'};
- char tmp[NUMBER_SIZE];
- long double val = get_number(ses, str);
- int index = 0;
- if (val >= 1000)
- {
- while (val >= 1000)
- {
- val = val / 1000;
- index++;
- }
- if (val >= 100)
- {
- sprintf(tmp, " %Lf", val);
- }
- else
- {
- sprintf(tmp, "%Lf", val);
- }
- sprintf(str, "%.4s%c", tmp, big[index]);
- }
- else if (val > 0 && val < 0.01)
- {
- while (val < 0.01)
- {
- val = val * 1000;
- index++;
- }
- sprintf(tmp, "%Lf", val);
- sprintf(str, "%.4s%c", tmp, small[index]);
- }
- else if (val >= 0)
- {
- if (val >= 100)
- {
- sprintf(tmp, " %Lf", val);
- }
- else
- {
- sprintf(tmp, "%Lf", val);
- }
- sprintf(str, "%.4s%c", tmp, big[index]);
- }
- else if (val <= -0.01 && val > -1000)
- {
- if (val <= -100)
- {
- sprintf(tmp, " %Lf", val);
- }
- else
- {
- sprintf(tmp, "%Lf", val);
- }
- sprintf(str, "%.5s%c", tmp, small[index]);
- }
- else if (val <= -1000)
- {
- while (val <= -100)
- {
- if (val <= -10000)
- {
- val = (long double) ((long long) val / 100LL * 100LL);
- }
- val = val / 1000;
- index++;
- }
- sprintf(tmp, "%Lf", val);
- sprintf(str, "%.5s%c", tmp, big[index]);
- }
- else if (val < 0 /*&& val > -0.01*/)
- {
- while (val > -0.01)
- {
- val = val * 1000;
- index++;
- }
- sprintf(tmp, "%Lf", val);
- sprintf(str, "%.5s%c", tmp, small[index]);
- }
- }
- void stripspaces(char *str)
- {
- int cnt;
- for (cnt = strlen(str) - 1 ; cnt >= 0 ; cnt--)
- {
- if (!isspace((int) str[cnt]))
- {
- break;
- }
- str[cnt] = 0;
- }
- for (cnt = 0 ; str[cnt] != 0 ; cnt++)
- {
- if (!isspace((int) str[cnt]))
- {
- break;
- }
- }
- memmove(str, &str[cnt], strlen(&str[cnt]) + 1);
- // strcpy(str, &str[cnt]);
- }
- void wrapstring(struct session *ses, char *str, char *wrap)
- {
- char arg1[BUFFER_SIZE], arg2[BUFFER_SIZE];
- char *pts, *pte, *arg;
- int cnt, width, height;
- push_call("wrapstring(%p,%p,%p)",ses,str,wrap);
- arg = sub_arg_in_braces(ses, str, arg1, GET_ALL, SUB_COL);
- if (*arg == COMMAND_SEPARATOR)
- {
- arg++;
- }
- arg = get_arg_in_braces(ses, arg, arg2, GET_ALL);
- if (*arg2)
- {
- cnt = get_number(ses, arg2);
- }
- else if (*wrap)
- {
- cnt = atoi(wrap);
- }
- else
- {
- cnt = get_scroll_cols(ses);
- }
- if (cnt <= 0)
- {
- cnt = get_scroll_cols(ses) + cnt;
- if (cnt <= 0)
- {
- show_error(ses, LIST_VARIABLE, "#FORMAT %w: INVALID LENTGH {%s}", arg2);
- pop_call();
- return;
- }
- }
- word_wrap_split(ses, arg1, arg2, cnt, 0, 0, 0, &height, &width);
- pts = pte = arg2;
- str[0] = cnt = 0;
- while (*pte != 0)
- {
- if (*pte == '\n')
- {
- *pte++ = 0;
- cat_sprintf(str, "{%d}{%s}", ++cnt, pts);
- pts = pte;
- }
- else
- {
- pte++;
- }
- }
- cat_sprintf(str, "{%d}{%s}", ++cnt, pts);
- pop_call();
- return;
- }
- int stringlength(struct session *ses, char *str)
- {
- char temp[BUFFER_SIZE];
- substitute(ses, str, temp, SUB_COL|SUB_ESC);
- return strip_vt102_strlen(ses, temp);
- }
- // stripped range raw return
- int string_str_raw_len(struct session *ses, char *str, int start, int end)
- {
- int raw_cnt, str_cnt, ret_cnt, tmp_cnt, tot_len, width, col_len;
- raw_cnt = str_cnt = ret_cnt = 0;
- tot_len = strlen(str);
- while (raw_cnt < tot_len)
- {
- if (skip_vt102_codes(&str[raw_cnt]))
- {
- ret_cnt += (str_cnt >= start) ? skip_vt102_codes(&str[raw_cnt]) : 0;
- raw_cnt += skip_vt102_codes(&str[raw_cnt]);
- continue;
- }
- col_len = is_color_code(&str[raw_cnt]);
-
- if (col_len)
- {
- ret_cnt += (str_cnt >= start) ? col_len : 0;
- raw_cnt += col_len;
- continue;
- }
- if (str_cnt >= end)
- {
- break;
- }
- if (str[raw_cnt] == '\\')
- {
- ret_cnt += (str_cnt >= start) ? 1 : 0;
- raw_cnt++;
-
- if (str[raw_cnt] == '\\')
- {
- ret_cnt += (str_cnt >= start) ? 1 : 0;
- raw_cnt++;
- str_cnt++;
- }
- continue;
- }
- if (HAS_BIT(ses->charset, CHARSET_FLAG_UTF8) && is_utf8_head(&str[raw_cnt]))
- {
- tmp_cnt = get_utf8_width(&str[raw_cnt], &width);
- if (str_cnt >= start)
- {
- ret_cnt += tmp_cnt;
- }
- raw_cnt += tmp_cnt;
- str_cnt += width;
- }
- else
- {
- ret_cnt += (str_cnt >= start) ? 1 : 0;
- raw_cnt++;
- str_cnt++;
- }
- }
- return ret_cnt;
- }
- // raw range stripped return
- int string_raw_str_len(struct session *ses, char *str, int raw_start, int raw_end)
- {
- int raw_cnt, ret_cnt, tot_len, width, col_len;
- raw_cnt = raw_start;
- ret_cnt = 0;
- tot_len = strlen(str);
- while (raw_cnt < tot_len)
- {
- if (raw_cnt >= raw_end)
- {
- break;
- }
- if (skip_vt102_codes(&str[raw_cnt]))
- {
- raw_cnt += skip_vt102_codes(&str[raw_cnt]);
- continue;
- }
- col_len = is_color_code(&str[raw_cnt]);
-
- if (col_len)
- {
- raw_cnt += col_len;
- continue;
- }
- if (str[raw_cnt] == '\\')
- {
- raw_cnt++;
- if (str[raw_cnt] == '\\')
- {
- raw_cnt++;
- ret_cnt++;
- }
- continue;
- }
- if (HAS_BIT(gtd->ses->charset, CHARSET_FLAG_EUC) && is_euc_head(ses, &str[raw_cnt]))
- {
- raw_cnt += get_euc_width(ses, &str[raw_cnt], &width);
- ret_cnt += width;
- }
- else if (HAS_BIT(gtd->ses->charset, CHARSET_FLAG_UTF8) && is_utf8_head(&str[raw_cnt]))
- {
- raw_cnt += get_utf8_width(&str[raw_cnt], &width);
- ret_cnt += width;
- }
- else
- {
- raw_cnt++;
- ret_cnt++;
- }
- }
- return ret_cnt;
- }
- void timestring(struct session *ses, char *str)
- {
- char arg1[BUFFER_SIZE], arg2[BUFFER_SIZE], *arg;
- struct tm timeval_tm;
- time_t timeval_t;
- arg = get_arg_in_braces(ses, str, arg1, GET_ALL);
- if (*arg == COMMAND_SEPARATOR)
- {
- arg++;
- }
- arg = get_arg_in_braces(ses, arg, arg2, GET_ALL);
- if (*arg2)
- {
- timeval_t = (time_t) get_number(ses, arg2);
- }
- else
- {
- timeval_t = gtd->time;
- }
- timeval_tm = *localtime(&timeval_t);
- strftime(str, BUFFER_SIZE, arg1, &timeval_tm);
- }
- void justify_string(struct session *ses, char *in, char *out, int align, int cut)
- {
- char temp[BUFFER_SIZE];
- if (align < 0)
- {
- sprintf(temp, "%%%d.%ds", align - ((int) strlen(in) - string_raw_str_len(ses, in, 0, BUFFER_SIZE)), string_str_raw_len(ses, in, 0, cut));
- }
- else
- {
- sprintf(temp, "%%%d.%ds", align + ((int) strlen(in) - string_raw_str_len(ses, in, 0, BUFFER_SIZE)), string_str_raw_len(ses, in, 0, cut));
- }
- sprintf(out, temp, in);
- }
- void format_string(struct session *ses, char *format, char *arg, char *out)
- {
- char argformat[BUFFER_SIZE], newformat[BUFFER_SIZE], arglist[30][20000], *ptf, *ptt, *pts, *ptn;
- struct tm timeval_tm;
- time_t timeval_t;
- int i;
- for (i = 0 ; i < 30 ; i++)
- {
- arg = sub_arg_in_braces(ses, arg, arglist[i], GET_ONE, SUB_VAR|SUB_FUN);
- }
- i = 0;
- ptf = format;
- ptn = newformat;
- while (*ptf)
- {
- if (i == 30)
- {
- break;
- }
- if (*ptf == '%')
- {
- pts = ptn;
- *ptn++ = *ptf++;
- if (*ptf == 0)
- {
- *ptn++ = '%';
- break;
- }
- else if (*ptf == '%')
- {
- *ptn++ = *ptf++;
- }
- else if (*ptf == ' ')
- {
- *ptn++ = '%';
- }
- else
- {
- while (!isalpha((int) *ptf))
- {
- if (*ptf == 0)
- {
- break;
- }
- *ptn++ = *ptf++;
- }
- *ptn = 0;
- if (*ptf == 0)
- {
- show_error(ses, LIST_VARIABLE, "#FORMAT STRING: UNKNOWN ARGUMENT {%s}.", pts);
- continue;
- }
- if (*ptf == 'd' || *ptf == 'f' || *ptf == 'X')
- {
- strcpy(argformat, pts);
- ptn = pts + 1;
- *ptn = 0;
- }
- else if (*ptf == 'w')
- {
- strcpy(argformat, pts+1);
- ptn = pts + 1;
- *ptn = 0;
- }
- else if (pts[1])
- {
- char arg1[BUFFER_SIZE], arg2[BUFFER_SIZE];
- ptt = arg1;
- ptn = pts + 1;
- while (*ptn && *ptn != '.')
- {
- *ptt++ = *ptn++;
- }
- *ptt = 0;
- if (*ptn == 0)
- {
- if (atoi(arg1) < 0)
- {
- sprintf(argformat, "%%%d", atoi(arg1) - ((int) strlen(arglist[i]) - string_raw_str_len(ses, arglist[i], 0, BUFFER_SIZE)));
- }
- else
- {
- sprintf(argformat, "%%%d", atoi(arg1) + ((int) strlen(arglist[i]) - string_raw_str_len(ses, arglist[i], 0, BUFFER_SIZE)));
- }
- }
- else
- {
- ptt = arg2;
- ptn = ptn + 1;
- while (*ptn)
- {
- *ptt++ = *ptn++;
- }
- *ptt = 0;
- if (atoi(arg1) < 0)
- {
- sprintf(argformat, "%%%d.%d",
- atoi(arg1) - ((int) strlen(arglist[i]) - string_raw_str_len(ses, arglist[i], 0, BUFFER_SIZE)),
- string_str_raw_len(ses, arglist[i], 0, atoi(arg2)));
- }
- else
- {
- sprintf(argformat, "%%%d.%d",
- atoi(arg1) + ((int) strlen(arglist[i]) - string_raw_str_len(ses, arglist[i], 0, BUFFER_SIZE)),
- string_str_raw_len(ses, arglist[i], 0, atoi(arg2)));
- }
- }
- ptt = argformat;
- ptn = pts;
- while (*ptt)
- {
- *ptn++ = *ptt++;
- }
- *ptn = 0;
- }
- switch (*ptf)
- {
- case 'a':
- numbertocharacter(ses, arglist[i]);
- // sprintf(arglist[i], "%c", (char) get_number(ses, arglist[i]));
- break;
- case 'c':
- colorstring(ses, arglist[i]);
- break;
- case 'd':
- strcat(argformat, "lld");
- sprintf(arglist[i], argformat, (long long) get_number(ses, arglist[i]));
- break;
- case 'f':
- strcat(argformat, "Lf");
- sprintf(arglist[i], argformat, get_double(ses, arglist[i]));
- break;
- case 'g':
- thousandgroupingstring(ses, arglist[i]);
- break;
- case 'h':
- headerstring(ses, arglist[i]);
- break;
- case 'l':
- lowerstring(arglist[i]);
- break;
- case 'm':
- mathstring(ses, arglist[i]);
- break;
- case 'n':
- arglist[i][0] = toupper((int) arglist[i][0]);
- break;
- case 'p':
- stripspaces(arglist[i]);
- break;
- case 'r':
- reversestring(arglist[i]);
- break;
- case 's':
- break;
- case 't':
- timestring(ses, arglist[i]);
- break;
- case 'u':
- upperstring(arglist[i]);
- break;
- case 'w':
- substitute(ses, arglist[i], arglist[i], SUB_VAR|SUB_FUN);
- wrapstring(ses, arglist[i], argformat);
- break;
- case 'x':
- hexstring(arglist[i]);
- break;
- case 'A':
- charactertonumber(ses, arglist[i]);
- break;
- case 'C':
- chronosgroupingstring(ses, arglist[i]);
- break;
- case 'D':
- sprintf(arglist[i], "%llu", hex_number_64bit(arglist[i]));
- break;
- /* case 'D':
- timeval_t = (time_t) *arglist[i] ? atoll(arglist[i]) : gtd->time;
- timeval_tm = *localtime(&timeval_t);
- strftime(arglist[i], BUFFER_SIZE, "%d", &timeval_tm);
- break;
- */
- case 'G':
- thousandgroupingstring(ses, arglist[i]);
- break;
- case 'H':
- sprintf(arglist[i], "%llu", generate_hash_key(arglist[i]));
- break;
- case 'L':
- sprintf(arglist[i], "%d", stringlength(ses, arglist[i]));
- break;
- case 'M':
- metricgroupingstring(ses, arglist[i]);
- break;
- case 'R':
- tintin_printf2(ses, "\e[1;31m#echo/#format %%R please use #screen {get} {rows} to get screen height.");
- sprintf(arglist[i], "%d", gtd->screen->rows);
- break;
- case 'S':
- sprintf(arglist[i], "%d", spellcheck_count(ses, arglist[i]));
- break;
- case 'T':
- sprintf(arglist[i], "%ld", gtd->time);
- break;
- case 'U':
- sprintf(arglist[i], "%lld", utime());
- break;
- case 'X':
- strcat(argformat, "llX");
- charactertohex(ses, arglist[i]);
- sprintf(arglist[i], argformat, (unsigned long long) get_number(ses, arglist[i]));
- break;
- // undocumented
- case 'Y': // print the year, experimental
- timeval_t = (time_t) *arglist[i] ? atoll(arglist[i]) : gtd->time;
- timeval_tm = *localtime(&timeval_t);
- strftime(arglist[i], BUFFER_SIZE, "%Y", &timeval_tm);
- break;
- default:
- show_error(ses, LIST_VARIABLE, "#FORMAT STRING: UNKNOWN ARGUMENT {%s%c}.", pts, *ptf);
- break;
- }
- *ptn++ = 's';
- i++;
- ptf++;
- }
- }
- else
- {
- *ptn++ = *ptf++;
- }
- }
- *ptn = 0;
- snprintf(out, BUFFER_SIZE - 1, newformat, arglist[0], arglist[1], arglist[2], arglist[3], arglist[4], arglist[5], arglist[6], arglist[7], arglist[8], arglist[9], arglist[10], arglist[11], arglist[12], arglist[13], arglist[14], arglist[15], arglist[16], arglist[17], arglist[18], arglist[19], arglist[20], arglist[21], arglist[22], arglist[23], arglist[24], arglist[25], arglist[26], arglist[27], arglist[28], arglist[29]);
- return;
- }
- DO_COMMAND(do_format)
- {
- char destvar[BUFFER_SIZE], format[BUFFER_SIZE], result[BUFFER_SIZE];
- arg = sub_arg_in_braces(ses, arg, destvar, GET_NST, SUB_VAR|SUB_FUN);
- arg = sub_arg_in_braces(ses, arg, format, GET_ONE, SUB_VAR|SUB_FUN);
- if (*destvar == 0)
- {
- show_error(ses, LIST_VARIABLE, "#SYNTAX: #format {variable} {format} {arg1} {arg2}");
- return ses;
- }
- format_string(ses, format, arg, result);
- set_nest_node_ses(ses, destvar, "%s", result);
- show_message(ses, LIST_VARIABLE, "#OK. VARIABLE {%s} HAS BEEN SET TO {%s}.", destvar, result);
- return ses;
- }
|