| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366 |
- /*
- * This file is part of the PikaPython project.
- * http://github.com/pikastech/pikapython
- *
- * MIT License
- *
- * Copyright (c) 2021 lyon liang6516@outlook.com
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
- #include "dataStrs.h"
- #include "PikaPlatform.h"
- #include "dataString.h"
- Args* New_strBuff(void) {
- return New_args(NULL);
- }
- char* strsRemovePrefix(Args* buffs_p, char* inputStr, char* prefix) {
- int32_t size = strGetSize(inputStr);
- char* buff = args_getBuff(buffs_p, size);
- return strRemovePrefix(inputStr, prefix, buff);
- }
- char* strsGetDirectStr(Args* buffs_p, char* argPath) {
- char* directStr = NULL;
- directStr = strsCut(buffs_p, argPath, '"', '"');
- if (NULL != directStr) {
- return directStr;
- }
- directStr = strsCut(buffs_p, argPath, '\'', '\'');
- if (NULL != directStr) {
- return directStr;
- }
- return NULL;
- }
- char* strsAppend(Args* buffs_p, char* strOrigin, char* strToAppend) {
- pika_assert(NULL != strToAppend);
- pika_assert(NULL != strOrigin);
- int32_t size = strGetSize(strOrigin) + strGetSize(strToAppend);
- char* buff = args_getBuff(buffs_p, size);
- char* strOut = strCopy(buff, strOrigin);
- strAppend(strOut, strToAppend);
- return strOut;
- }
- char* strsReturnOut(Args* buffs, Args* outbuffs, char* str) {
- char* line_out = strsCopy(outbuffs, str);
- strsDeinit(buffs);
- return line_out;
- }
- char* strsGetLastToken(Args* buffs_p, char* argPath, char sign) {
- int32_t size = strGetSize(argPath);
- char* buff = args_getBuff(buffs_p, size);
- return strGetLastToken(buff, argPath, sign);
- }
- char* strsCut(Args* buffs_p, char* strIn, char startSign, char endSign) {
- int32_t size = strGetSize(strIn);
- char* buff = args_getBuff(buffs_p, size);
- return strCut(buff, strIn, startSign, endSign);
- }
- char* strsDeleteChar(Args* buffs_p, char* strIn, char ch) {
- int32_t size = strGetSize(strIn);
- return strDeleteChar(args_getBuff(buffs_p, size), strIn, ch);
- }
- static uint32_t getSizeOfFirstToken(char* str, char sign) {
- uint32_t size = strGetSize(str);
- for (uint32_t i = 0; i < size; i++) {
- if (str[i] == sign) {
- return i;
- }
- }
- return size;
- }
- char* strsGetFirstToken(Args* buffs_p, char* strIn, char sign) {
- int32_t size = getSizeOfFirstToken(strIn, sign);
- return strGetFirstToken(args_getBuff(buffs_p, size), strIn, sign);
- }
- char* strsPopToken(Args* buffs_p, char** tokens, char sign) {
- return strsCopy(buffs_p, strPopFirstToken(tokens, sign));
- }
- char* strsPopLine(Args* buffs_p, char** tokens) {
- return strsCopy(buffs_p, strPopFirstToken(tokens, '\n'));
- }
- char* strsCopy(Args* buffs_p, char* source) {
- pika_assert(source != NULL);
- int32_t size = strGetSize(source);
- char* buff = args_getBuff(buffs_p, size);
- return strCopy(buff, source);
- }
- char* strsCacheArg(Args* buffs_p, Arg* arg) {
- pika_assert(arg != NULL);
- char* res = strsCopy(buffs_p, arg_getStr(arg));
- arg_deinit(arg);
- return res;
- }
- char* strsFormat(Args* buffs_p, uint16_t buffSize, const char* fmt, ...) {
- va_list args;
- va_start(args, fmt);
- char* res = args_getBuff(buffs_p, buffSize);
- pika_platform_vsnprintf(res, buffSize, fmt, args);
- va_end(args);
- return res;
- }
- Arg* arg_strAppend(Arg* arg_in, char* str_to_append) {
- pika_assert(NULL != str_to_append);
- Args buffs = {0};
- char* str_out = strsAppend(&buffs, arg_getStr(arg_in), str_to_append);
- Arg* arg_out = arg_newStr(str_out);
- arg_deinit(arg_in);
- strsDeinit(&buffs);
- return arg_out;
- }
- char* strsReplace(Args* buffs_p, char* orig, char* rep, char* with) {
- char* result; // the return string
- char* ins; // the next insert point
- char* tmp; // varies
- int len_rep; // length of rep (the string to remove)
- int len_with; // length of with (the string to replace rep with)
- int len_front; // distance between rep and end of last rep
- int count; // number of replacements
- pika_assert(NULL != orig);
- pika_assert(NULL != rep);
- /* no need replace, skip */
- if (NULL == strstr(orig, rep)) {
- return orig;
- }
- // sanity checks and initialization
- if (!orig || !rep)
- return NULL;
- len_rep = strlen(rep);
- if (len_rep == 0)
- return NULL; // empty rep causes infinite loop during count
- if (!with)
- with = "";
- len_with = strlen(with);
- // count the number of replacements needed
- ins = orig;
- tmp = strstr(ins, rep);
- count = 0;
- while (tmp) {
- count++;
- ins = tmp + len_rep;
- tmp = strstr(ins, rep);
- }
- tmp =
- args_getBuff(buffs_p, strlen(orig) + (len_with - len_rep) * count + 1);
- result = tmp;
- if (NULL == result) {
- return NULL;
- }
- // first time through the loop, all the variable are set correctly
- // from here on,
- // tmp points to the end of the result string
- // ins points to the next occurrence of rep in orig
- // orig points to the remainder of orig after "end of rep"
- while (count--) {
- ins = strstr(orig, rep);
- len_front = ins - orig;
- tmp = strncpy(tmp, orig, len_front) + len_front;
- tmp = strcpy(tmp, with) + len_with;
- orig += len_front + len_rep; // move to next "end of rep"
- }
- strcpy(tmp, orig);
- return result;
- }
- char* strsGetLine(Args* buffs_p, char* code) {
- int32_t lineSize = strGetLineSize(code);
- char* line_buff = args_getBuff(buffs_p, lineSize + 1);
- return strGetLine(line_buff, code);
- }
- void strsDeinit(Args* buffs_p) {
- link_deinit_stack(buffs_p);
- }
- char* strsPathFormat(Args* buffs_p, char* input) {
- int32_t size = strGetSize(input);
- char* buff = args_getBuff(buffs_p, size);
- strPathFormat(input, buff);
- return buff;
- }
- char* strsPathJoin(Args* buffs_p, char* input1, char* input2) {
- int32_t size = strGetSize(input1) + strGetSize(input2) + 1;
- char* buff = args_getBuff(buffs_p, size);
- strPathJoin(input1, input2, buff);
- return buff;
- }
- char* strsPathGetFolder(Args* buffs_p, char* input) {
- int32_t size = strGetSize(input);
- char* buff = args_getBuff(buffs_p, size);
- strPathGetFolder(input, buff);
- return buff;
- }
- char* strsPathGetFileName(Args* buffs_p, char* input) {
- int32_t size = strGetSize(input);
- char* buff = args_getBuff(buffs_p, size);
- strPathGetFileName(input, buff);
- return buff;
- }
- char* strsTransfer(Args* buffs, char* str, size_t* iout_p) {
- char* transfered_str = args_getBuff(buffs, strGetSize(str));
- size_t i_out = 0;
- size_t len = strGetSize(str);
- for (size_t i = 0; i < len; i++) {
- /* eg. replace '\x33' to '3' */
- if ((str[i] == '\\') && (str[i + 1] == 'x')) {
- char hex_str[] = "0x00";
- hex_str[2] = str[i + 2];
- hex_str[3] = str[i + 3];
- char hex = (char)strtoll(hex_str, NULL, 0);
- transfered_str[i_out++] = hex;
- i += 3;
- continue;
- }
- if (str[i] == '\\') {
- switch (str[i + 1]) {
- case 'r':
- transfered_str[i_out++] = '\r';
- break;
- case 'n':
- transfered_str[i_out++] = '\n';
- break;
- case 't':
- transfered_str[i_out++] = '\t';
- break;
- case 'b':
- transfered_str[i_out++] = '\b';
- break;
- case '\\':
- transfered_str[i_out++] = '\\';
- break;
- case '\'':
- transfered_str[i_out++] = '\'';
- break;
- case '\"':
- transfered_str[i_out++] = '\"';
- break;
- case '?':
- transfered_str[i_out++] = '\?';
- break;
- default:
- transfered_str[i_out++] = str[i];
- break;
- }
- i += 1;
- continue;
- }
- /* normal char */
- transfered_str[i_out++] = str[i];
- }
- *iout_p = i_out;
- return transfered_str;
- }
- char* strsFilePreProcess_ex(Args* outbuffs, char* lines, char* endwith) {
- Args buffs = {0};
- /* replace the "\r\n" to "\n" */
- lines = strsReplace(&buffs, lines, "\r\n", "\n");
- /* clear the void line */
- lines = strsReplace(&buffs, lines, "\n\n", "\n");
- /* add '\n' at the end */
- lines = strsAppend(&buffs, lines, endwith);
- char* result = strsCopy(outbuffs, lines);
- strsDeinit(&buffs);
- return result;
- }
- char* strsFilePreProcess(Args* outbuffs, char* lines) {
- return strsFilePreProcess_ex(outbuffs, lines, "\n\n");
- }
- char* strsSubStr(Args* buffs_p, char* name_start, char* name_end) {
- int32_t size = name_end - name_start;
- char* buff = args_getBuff(buffs_p, size + 1);
- for (int32_t i = 0; i < size; i++) {
- buff[i] = name_start[i];
- }
- buff[size] = '\0';
- return buff;
- }
- char* strsRepeat(Args* buffs, char* str, int num) {
- int32_t size = strGetSize(str) * num;
- char* buff = args_getBuff(buffs, size + 1);
- for (int32_t i = 0; i < num; i++) {
- for (int32_t j = 0; j < strGetSize(str); j++) {
- buff[i * strGetSize(str) + j] = str[j];
- }
- }
- buff[size] = '\0';
- return buff;
- }
- static void _add_indentation(const char* input, int spaces, char* output) {
- if (input == NULL || output == NULL || spaces < 0) {
- return;
- }
- const char* current = input;
- int output_index = 0;
- // Iterate over the input string
- while (*current) {
- // Add spaces at the beginning of each new line
- if (current == input || *(current - 1) == '\n') {
- for (int i = 0; i < spaces; ++i) {
- output[output_index++] = ' ';
- }
- }
- // Copy the current character
- output[output_index++] = *current++;
- }
- // Add the null terminator to the string
- output[output_index] = '\0';
- }
- char* strsAddIndentation(Args* buffs, char* str, int spaces) {
- int lines = 1;
- for (const char* current = str; *current; current++) {
- if (*current == '\n') {
- lines++;
- }
- }
- int output_length = strGetSize(str) + spaces * lines;
- char* buff = args_getBuff(buffs, output_length + 1);
- _add_indentation(str, spaces, buff);
- return buff;
- }
|