Formatting.
This commit is contained in:
		
							parent
							
								
									44c7063033
								
							
						
					
					
						commit
						255e5458be
					
				
							
								
								
									
										117
									
								
								browse.h
									
									
									
									
									
								
							
							
						
						
									
										117
									
								
								browse.h
									
									
									
									
									
								
							| @ -12,15 +12,63 @@ char *web_search_news(char *q) { | ||||
|   const int MAX_RETRIES = 3; | ||||
|   for (int retry = 0; retry < MAX_RETRIES; retry++) { | ||||
|     char *news = malloc(4096); | ||||
|     if (!news) return NULL; | ||||
|     if (!news) | ||||
|       return NULL; | ||||
|     news[0] = 0; | ||||
|     char *q_encoded = url_encode(q); | ||||
|     snprintf(news, 4096, "https://search.molodetz.nl/search?q=%s&format=json&categories=news&preferences=eJx1WMuy4zYO_Zp4o4ormaRqahZepZL5gexVFAlLiEhCzYdt3a8PoIdFWt2Ldl8fkCCIxwForRL0FBDirQcPQdmLVb7PqoebyokulrSycPP2Il81uclCgtvlrh6oybcBItkHhNsFHW9qp0Cv-faXshEuDtJA5vb_P_--RHWHCCro4fbLJQ3g4BZRdF1YQbYptqzLw7NNqtt2G8JDOyn-eqXQX9ZtbUyz3UzU4BOEVlnsveO_t_3KPJTXYNrt3BX9liHMLfo2YWIFK4j-jh4Ta9WBrN3QdZ8YplcvzazKgk63v0OGy0BphDneDNwV3-CSg23vFJxKCX1_mwKkNF8MRtVZtgJ8j57d_L9e9W0bSaOyjQOD6qf__MG366CJ7OCxbRdHxhptHmiA2nb571OmskGWuRxRi8hOfFJj0edXMyk9ijpWm0TmvYqN3Asf0LZ3tOtJ09g4DIFCibGfG_6UU0K52CuOvFGbSo8vis0TR9yADi3Kv8LaDlOX9QhpX5IM9v2hcvHDVWt9NVBs0xN78Q4BOI7bTg5QjAyyCzUKztgMU7M6rXCegJxQDMknAwbgi9Pk7SYDMamEvIA4IQMjEOiJ5vhu2GT519NZfSFbzS3MLmS1BQf-BCWHHGet3nZq4uX8KdY4-gcnccyx6tdXYcLdBBJzdydyDps0qOS4usplAThR6J6eKkBjMHAGSy6v_rwH9CMqXW6Y58IJPeDXwPVQIFw5qtvjQQY6CP32lWXAgSS3fycyAZQptxP1fNXJqlmyKx4XKCWOHgilU7muIEjNCO2UkRhUF5R8bEcOnPEQVsevALzeycNK4lWKZfmOznSHYej6HArF6FVxPnr-EynH72N7VnHEAlPJXOj5B-NAxzFcHEGFuRG-jVhc31IXE1zDbjfTp9KT8nudTbtT_azUsY3MHKGsGprAb4ccpwrICoFqKMBEhQkrW2Dc65TLb2XBcwEcoirHp9xxDT-2_QGMwXSiu0ApMVETx5SgSA0mS51jvE4zN4793loZM0tKubw5drEMfx7IwglfbZKsbOTjjTrlE-omat6lQskeicaZEnGMRvH17ook9-TlKr_vlqp0EcaLE-glTQ91JhvwxyouYoDx7L4Nr3y35PyEltKxP-Ru7sHtOTEBhJS7MtyLU3n1yJufT-gK0az0fD46ZMcdqVhmuRdEDn2JPemFI3mOZRNnT34WTtmN4nwbQ237Cp3OWuETQ8ZHL5lXLHwwlS0da7vonJ2zc1U1R2VEykHDkN9pOvbXnva8u4CvWy4PMC_lTRAm3aYcYVzJ3bVJFs1LBU6TsgeHFz7K-Ko4llo6VqyVmw4GEGUbbRfLeCT4_H721oJWbl2Qk_u6qSuVSSHzkBRL1tcD3Efi8eXtQW0pmzsnPygsd3NHfRrJnRLk7lmt4eEG4QORtjyXGPsfuczYhWWjNH3DI5LMV7gQd7GehKmbIe_NRBSymdvgVawUnxqVKpce3bREefaCubIU0uyICdEXCXy3qMeS63k5ljTeCz3tbYKb2mHj2qTKA7a2dYrmhlfx3LBTRDf8O_Q0bOcth49stoplzwDn5mYnwZWKaq5dV-QI4Ucy7gDpRzLRzK44i79-freYty1bY6M7b_Nc4LH0hkghBeWj5SZc-o9D0z-q0DrFI6ch_wOz3-JBxYF5-jsrzN49HL6WxD9C6-hrqArAPZkP6-N5JIJ9npDqUjw1Sf5FSBXZ7zLuepxRasvwWh4TD2CJZ7p9sJuM8PexaOKXhHS7TYrymoFY1tAkhFJky_L9ulzouNeEMt10qojIRMxNkUvCyAi0J_-7c5d3Ptr5npuFbLldY7hfo1_z_HhCHEbmzomVxcXmaafVb08mhlLnAtS1sUKnMlrhU8UExZNX0zF5xXKqD9gPqTGqIoX1Zm6OWGde5G6rdl8czYkyc3qdNPxU0CMxyd4tPfdWEcfcZZ_y3pUyz345vhMnChNO8igujySLhufvsFbV96aNY3H2kYfhOJTPGjVQdbcFqB05U_6YEd7I-_Gj0DItSsIWyx7oqkfmE7v5k4Y7ojF-gtXxAnzLVLt6mZaWtn1C9xmqgsWyaoCVpdLkllGv1vCg-cPLggp1cTleTwlVCk9pVQo_3tWlaInbEb4n2XtQjl_eQ92jUKcv8pVtjkcpxw-w5k2GphT_-ttv_30dmiN8eeWq_cvkWCJePSTpypyoG_OTgvE4FgMcn62reuRul-QBKYo-yPSprB34CP_hQ8c9vTolpXDFYvbldvCorr4A54Cs8HnKWeDP9lnpS7_vPyIcP7RMNvPYF2-k2vUnpGfgsl86aUzsy7XeKLQ8IunxPSzu28QzPJW08nNO4EA91uFJWZ05VhSWsuQ3Dbc4FqVtHrb3Fv2d5BSp11XZhZ8WzP-3fwFOiVFV", q_encoded); | ||||
|     snprintf( | ||||
|         news, 4096, | ||||
|         "https://search.molodetz.nl/" | ||||
|         "search?q=%s&format=json&categories=news&preferences=eJx1WMuy4zYO_" | ||||
|         "Zp4o4ormaRqahZepZL5gexVFAlLiEhCzYdt3a8PoIdFWt2Ldl8fkCCIxwForRL0FBDirQc" | ||||
|         "PQdmLVb7PqoebyokulrSycPP2Il81uclCgtvlrh6oybcBItkHhNsFHW9qp0Cv-" | ||||
|         "faXshEuDtJA5vb_P_--RHWHCCro4fbLJQ3g4BZRdF1YQbYptqzLw7NNqtt2G8JDOyn-" | ||||
|         "eqXQX9ZtbUyz3UzU4BOEVlnsveO_t_3KPJTXYNrt3BX9liHMLfo2YWIFK4j-" | ||||
|         "jh4Ta9WBrN3QdZ8YplcvzazKgk63v0OGy0BphDneDNwV3-CSg23vFJxKCX1_" | ||||
|         "mwKkNF8MRtVZtgJ8j57d_L9e9W0bSaOyjQOD6qf__" | ||||
|         "MG366CJ7OCxbRdHxhptHmiA2nb571OmskGWuRxRi8hOfFJj0edXMyk9ijpWm0TmvYqN3As" | ||||
|         "f0LZ3tOtJ09g4DIFCibGfG_" | ||||
|         "6UU0K52CuOvFGbSo8vis0TR9yADi3Kv8LaDlOX9QhpX5IM9v2hcvHDVWt9NVBs0xN78Q4B" | ||||
|         "OI7bTg5QjAyyCzUKztgMU7M6rXCegJxQDMknAwbgi9Pk7SYDMamEvIA4IQMjEOiJ5vhu2G" | ||||
|         "T519NZfSFbzS3MLmS1BQf-BCWHHGet3nZq4uX8KdY4-" | ||||
|         "gcnccyx6tdXYcLdBBJzdydyDps0qOS4usplAThR6J6eKkBjMHAGSy6v_" | ||||
|         "rwH9CMqXW6Y58IJPeDXwPVQIFw5qtvjQQY6CP32lWXAgSS3fycyAZQptxP1fNXJqlmyKx4" | ||||
|         "XKCWOHgilU7muIEjNCO2UkRhUF5R8bEcOnPEQVsevALzeycNK4lWKZfmOznSHYej6HArF6" | ||||
|         "FVxPnr-EynH72N7VnHEAlPJXOj5B-NAxzFcHEGFuRG-" | ||||
|         "jVhc31IXE1zDbjfTp9KT8nudTbtT_" | ||||
|         "azUsY3MHKGsGprAb4ccpwrICoFqKMBEhQkrW2Dc65TLb2XBcwEcoirHp9xxDT-2_" | ||||
|         "QGMwXSiu0ApMVETx5SgSA0mS51jvE4zN4793loZM0tKubw5drEMfx7IwglfbZKsbOTjjTr" | ||||
|         "lE-omat6lQskeicaZEnGMRvH17ook9-TlKr_vlqp0EcaLE-" | ||||
|         "glTQ91JhvwxyouYoDx7L4Nr3y35PyEltKxP-Ru7sHtOTEBhJS7MtyLU3n1yJufT-" | ||||
|         "gK0az0fD46ZMcdqVhmuRdEDn2JPemFI3mOZRNnT34WTtmN4nwbQ237Cp3OWuETQ8ZHL5lX" | ||||
|         "LHwwlS0da7vonJ2zc1U1R2VEykHDkN9pOvbXnva8u4CvWy4PMC_" | ||||
|         "lTRAm3aYcYVzJ3bVJFs1LBU6TsgeHFz7K-Ko4llo6VqyVmw4GEGUbbRfLeCT4_" | ||||
|         "H721oJWbl2Qk_" | ||||
|         "u6qSuVSSHzkBRL1tcD3Efi8eXtQW0pmzsnPygsd3NHfRrJnRLk7lmt4eEG4QORtjyXGPsf" | ||||
|         "uczYhWWjNH3DI5LMV7gQd7GehKmbIe_" | ||||
|         "NRBSymdvgVawUnxqVKpce3bREefaCubIU0uyICdEXCXy3qMeS63k5ljTeCz3tbYKb2mHj2" | ||||
|         "qTKA7a2dYrmhlfx3LBTRDf8O_Q0bOcth49stoplzwDn5mYnwZWKaq5dV-" | ||||
|         "QI4Ucy7gDpRzLRzK44i79-freYty1bY6M7b_Nc4LH0hkghBeWj5SZc-o9D0z-" | ||||
|         "q0DrFI6ch_wOz3-JBxYF5-jsrzN49HL6WxD9C6-hrqArAPZkP6-" | ||||
|         "N5JIJ9npDqUjw1Sf5FSBXZ7zLuepxRasvwWh4TD2CJZ7p9sJuM8PexaOKXhHS7TYrymoFY" | ||||
|         "1tAkhFJky_L9ulzouNeEMt10qojIRMxNkUvCyAi0J_-7c5d3Ptr5npuFbLldY7hfo1_z_" | ||||
|         "HhCHEbmzomVxcXmaafVb08mhlLnAtS1sUKnMlrhU8UExZNX0zF5xXKqD9gPqTGqIoX1Zm6" | ||||
|         "OWGde5G6rdl8czYkyc3qdNPxU0CMxyd4tPfdWEcfcZZ_" | ||||
|         "y3pUyz345vhMnChNO8igujySLhufvsFbV96aNY3H2kYfhOJTPGjVQdbcFqB05U_6YEd7I-" | ||||
|         "_Gj0DItSsIWyx7oqkfmE7v5k4Y7ojF-" | ||||
|         "gtXxAnzLVLt6mZaWtn1C9xmqgsWyaoCVpdLkllGv1vCg-cPLggp1cTleTwlVCk9pVQo_" | ||||
|         "3tWlaInbEb4n2XtQjl_eQ92jUKcv8pVtjkcpxw-w5k2GphT_-ttv_30dmiN8eeWq_" | ||||
|         "cvkWCJePSTpypyoG_OTgvE4FgMcn62reuRul-QBKYo-yPSprB34CP_" | ||||
|         "hQ8c9vTolpXDFYvbldvCorr4A54Cs8HnKWeDP9lnpS7_vPyIcP7RMNvPYF2-" | ||||
|         "k2vUnpGfgsl86aUzsy7XeKLQ8IunxPSzu28QzPJW08nNO4EA91uFJWZ05VhSWsuQ3Dbc4F" | ||||
|         "qVtHrb3Fv2d5BSp11XZhZ8WzP-3fwFOiVFV", | ||||
|         q_encoded); | ||||
|     free(q_encoded); | ||||
| 
 | ||||
|     char *ret = curl_get(news); | ||||
|     free(news); | ||||
|     if (!ret) continue; | ||||
|     if (!ret) | ||||
|       continue; | ||||
| 
 | ||||
|     json_object *json_ret = json_tokener_parse(ret); | ||||
|     if (!json_ret) { | ||||
| @ -44,15 +92,63 @@ char *web_search(char *q) { | ||||
|   const int MAX_RETRIES = 3; | ||||
|   for (int retry = 0; retry < MAX_RETRIES; retry++) { | ||||
|     char *news = malloc(4096); | ||||
|     if (!news) return NULL; | ||||
|     if (!news) | ||||
|       return NULL; | ||||
|     news[0] = 0; | ||||
|     char *q_encoded = url_encode(q); | ||||
|     snprintf(news, 4096, "https://search.molodetz.nl/search?q=%s&format=json&preferences=eJx1WMuy4zYO_Zp4o4ormaRqahZepZL5gexVFAlLiEhCzYdt3a8PoIdFWt2Ldl8fkCCIxwForRL0FBDirQcPQdmLVb7PqoebyokulrSycPP2Il81uclCgtvlrh6oybcBItkHhNsFHW9qp0Cv-faXshEuDtJA5vb_P_--RHWHCCro4fbLJQ3g4BZRdF1YQbYptqzLw7NNqtt2G8JDOyn-eqXQX9ZtbUyz3UzU4BOEVlnsveO_t_3KPJTXYNrt3BX9liHMLfo2YWIFK4j-jh4Ta9WBrN3QdZ8YplcvzazKgk63v0OGy0BphDneDNwV3-CSg23vFJxKCX1_mwKkNF8MRtVZtgJ8j57d_L9e9W0bSaOyjQOD6qf__MG366CJ7OCxbRdHxhptHmiA2nb571OmskGWuRxRi8hOfFJj0edXMyk9ijpWm0TmvYqN3Asf0LZ3tOtJ09g4DIFCibGfG_6UU0K52CuOvFGbSo8vis0TR9yADi3Kv8LaDlOX9QhpX5IM9v2hcvHDVWt9NVBs0xN78Q4BOI7bTg5QjAyyCzUKztgMU7M6rXCegJxQDMknAwbgi9Pk7SYDMamEvIA4IQMjEOiJ5vhu2GT519NZfSFbzS3MLmS1BQf-BCWHHGet3nZq4uX8KdY4-gcnccyx6tdXYcLdBBJzdydyDps0qOS4usplAThR6J6eKkBjMHAGSy6v_rwH9CMqXW6Y58IJPeDXwPVQIFw5qtvjQQY6CP32lWXAgSS3fycyAZQptxP1fNXJqlmyKx4XKCWOHgilU7muIEjNCO2UkRhUF5R8bEcOnPEQVsevALzeycNK4lWKZfmOznSHYej6HArF6FVxPnr-EynH72N7VnHEAlPJXOj5B-NAxzFcHEGFuRG-jVhc31IXE1zDbjfTp9KT8nudTbtT_azUsY3MHKGsGprAb4ccpwrICoFqKMBEhQkrW2Dc65TLb2XBcwEcoirHp9xxDT-2_QGMwXSiu0ApMVETx5SgSA0mS51jvE4zN4793loZM0tKubw5drEMfx7IwglfbZKsbOTjjTrlE-omat6lQskeicaZEnGMRvH17ook9-TlKr_vlqp0EcaLE-glTQ91JhvwxyouYoDx7L4Nr3y35PyEltKxP-Ru7sHtOTEBhJS7MtyLU3n1yJufT-gK0az0fD46ZMcdqVhmuRdEDn2JPemFI3mOZRNnT34WTtmN4nwbQ237Cp3OWuETQ8ZHL5lXLHwwlS0da7vonJ2zc1U1R2VEykHDkN9pOvbXnva8u4CvWy4PMC_lTRAm3aYcYVzJ3bVJFs1LBU6TsgeHFz7K-Ko4llo6VqyVmw4GEGUbbRfLeCT4_H721oJWbl2Qk_u6qSuVSSHzkBRL1tcD3Efi8eXtQW0pmzsnPygsd3NHfRrJnRLk7lmt4eEG4QORtjyXGPsfuczYhWWjNH3DI5LMV7gQd7GehKmbIe_NRBSymdvgVawUnxqVKpce3bREefaCubIU0uyICdEXCXy3qMeS63k5ljTeCz3tbYKb2mHj2qTKA7a2dYrmhlfx3LBTRDf8O_Q0bOcth49stoplzwDn5mYnwZWKaq5dV-QI4Ucy7gDpRzLRzK44i79-freYty1bY6M7b_Nc4LH0hkghBeWj5SZc-o9D0z-q0DrFI6ch_wOz3-JBxYF5-jsrzN49HL6WxD9C6-hrqArAPZkP6-N5JIJ9npDqUjw1Sf5FSBXZ7zLuepxRasvwWh4TD2CJZ7p9sJuM8PexaOKXhHS7TYrymoFY1tAkhFJky_L9ulzouNeEMt10qojIRMxNkUvCyAi0J_-7c5d3Ptr5npuFbLldY7hfo1_z_HhCHEbmzomVxcXmaafVb08mhlLnAtS1sUKnMlrhU8UExZNX0zF5xXKqD9gPqTGqIoX1Zm6OWGde5G6rdl8czYkyc3qdNPxU0CMxyd4tPfdWEcfcZZ_y3pUyz345vhMnChNO8igujySLhufvsFbV96aNY3H2kYfhOJTPGjVQdbcFqB05U_6YEd7I-_Gj0DItSsIWyx7oqkfmE7v5k4Y7ojF-gtXxAnzLVLt6mZaWtn1C9xmqgsWyaoCVpdLkllGv1vCg-cPLggp1cTleTwlVCk9pVQo_3tWlaInbEb4n2XtQjl_eQ92jUKcv8pVtjkcpxw-w5k2GphT_-ttv_30dmiN8eeWq_cvkWCJePSTpypyoG_OTgvE4FgMcn62reuRul-QBKYo-yPSprB34CP_hQ8c9vTolpXDFYvbldvCorr4A54Cs8HnKWeDP9lnpS7_vPyIcP7RMNvPYF2-k2vUnpGfgsl86aUzsy7XeKLQ8IunxPSzu28QzPJW08nNO4EA91uFJWZ05VhSWsuQ3Dbc4FqVtHrb3Fv2d5BSp11XZhZ8WzP-3fwFOiVFV", q_encoded); | ||||
|     snprintf( | ||||
|         news, 4096, | ||||
|         "https://search.molodetz.nl/" | ||||
|         "search?q=%s&format=json&preferences=eJx1WMuy4zYO_" | ||||
|         "Zp4o4ormaRqahZepZL5gexVFAlLiEhCzYdt3a8PoIdFWt2Ldl8fkCCIxwForRL0FBDirQc" | ||||
|         "PQdmLVb7PqoebyokulrSycPP2Il81uclCgtvlrh6oybcBItkHhNsFHW9qp0Cv-" | ||||
|         "faXshEuDtJA5vb_P_--RHWHCCro4fbLJQ3g4BZRdF1YQbYptqzLw7NNqtt2G8JDOyn-" | ||||
|         "eqXQX9ZtbUyz3UzU4BOEVlnsveO_t_3KPJTXYNrt3BX9liHMLfo2YWIFK4j-" | ||||
|         "jh4Ta9WBrN3QdZ8YplcvzazKgk63v0OGy0BphDneDNwV3-CSg23vFJxKCX1_" | ||||
|         "mwKkNF8MRtVZtgJ8j57d_L9e9W0bSaOyjQOD6qf__" | ||||
|         "MG366CJ7OCxbRdHxhptHmiA2nb571OmskGWuRxRi8hOfFJj0edXMyk9ijpWm0TmvYqN3As" | ||||
|         "f0LZ3tOtJ09g4DIFCibGfG_" | ||||
|         "6UU0K52CuOvFGbSo8vis0TR9yADi3Kv8LaDlOX9QhpX5IM9v2hcvHDVWt9NVBs0xN78Q4B" | ||||
|         "OI7bTg5QjAyyCzUKztgMU7M6rXCegJxQDMknAwbgi9Pk7SYDMamEvIA4IQMjEOiJ5vhu2G" | ||||
|         "T519NZfSFbzS3MLmS1BQf-BCWHHGet3nZq4uX8KdY4-" | ||||
|         "gcnccyx6tdXYcLdBBJzdydyDps0qOS4usplAThR6J6eKkBjMHAGSy6v_" | ||||
|         "rwH9CMqXW6Y58IJPeDXwPVQIFw5qtvjQQY6CP32lWXAgSS3fycyAZQptxP1fNXJqlmyKx4" | ||||
|         "XKCWOHgilU7muIEjNCO2UkRhUF5R8bEcOnPEQVsevALzeycNK4lWKZfmOznSHYej6HArF6" | ||||
|         "FVxPnr-EynH72N7VnHEAlPJXOj5B-NAxzFcHEGFuRG-" | ||||
|         "jVhc31IXE1zDbjfTp9KT8nudTbtT_" | ||||
|         "azUsY3MHKGsGprAb4ccpwrICoFqKMBEhQkrW2Dc65TLb2XBcwEcoirHp9xxDT-2_" | ||||
|         "QGMwXSiu0ApMVETx5SgSA0mS51jvE4zN4793loZM0tKubw5drEMfx7IwglfbZKsbOTjjTr" | ||||
|         "lE-omat6lQskeicaZEnGMRvH17ook9-TlKr_vlqp0EcaLE-" | ||||
|         "glTQ91JhvwxyouYoDx7L4Nr3y35PyEltKxP-Ru7sHtOTEBhJS7MtyLU3n1yJufT-" | ||||
|         "gK0az0fD46ZMcdqVhmuRdEDn2JPemFI3mOZRNnT34WTtmN4nwbQ237Cp3OWuETQ8ZHL5lX" | ||||
|         "LHwwlS0da7vonJ2zc1U1R2VEykHDkN9pOvbXnva8u4CvWy4PMC_" | ||||
|         "lTRAm3aYcYVzJ3bVJFs1LBU6TsgeHFz7K-Ko4llo6VqyVmw4GEGUbbRfLeCT4_" | ||||
|         "H721oJWbl2Qk_" | ||||
|         "u6qSuVSSHzkBRL1tcD3Efi8eXtQW0pmzsnPygsd3NHfRrJnRLk7lmt4eEG4QORtjyXGPsf" | ||||
|         "uczYhWWjNH3DI5LMV7gQd7GehKmbIe_" | ||||
|         "NRBSymdvgVawUnxqVKpce3bREefaCubIU0uyICdEXCXy3qMeS63k5ljTeCz3tbYKb2mHj2" | ||||
|         "qTKA7a2dYrmhlfx3LBTRDf8O_Q0bOcth49stoplzwDn5mYnwZWKaq5dV-" | ||||
|         "QI4Ucy7gDpRzLRzK44i79-freYty1bY6M7b_Nc4LH0hkghBeWj5SZc-o9D0z-" | ||||
|         "q0DrFI6ch_wOz3-JBxYF5-jsrzN49HL6WxD9C6-hrqArAPZkP6-" | ||||
|         "N5JIJ9npDqUjw1Sf5FSBXZ7zLuepxRasvwWh4TD2CJZ7p9sJuM8PexaOKXhHS7TYrymoFY" | ||||
|         "1tAkhFJky_L9ulzouNeEMt10qojIRMxNkUvCyAi0J_-7c5d3Ptr5npuFbLldY7hfo1_z_" | ||||
|         "HhCHEbmzomVxcXmaafVb08mhlLnAtS1sUKnMlrhU8UExZNX0zF5xXKqD9gPqTGqIoX1Zm6" | ||||
|         "OWGde5G6rdl8czYkyc3qdNPxU0CMxyd4tPfdWEcfcZZ_" | ||||
|         "y3pUyz345vhMnChNO8igujySLhufvsFbV96aNY3H2kYfhOJTPGjVQdbcFqB05U_6YEd7I-" | ||||
|         "_Gj0DItSsIWyx7oqkfmE7v5k4Y7ojF-" | ||||
|         "gtXxAnzLVLt6mZaWtn1C9xmqgsWyaoCVpdLkllGv1vCg-cPLggp1cTleTwlVCk9pVQo_" | ||||
|         "3tWlaInbEb4n2XtQjl_eQ92jUKcv8pVtjkcpxw-w5k2GphT_-ttv_30dmiN8eeWq_" | ||||
|         "cvkWCJePSTpypyoG_OTgvE4FgMcn62reuRul-QBKYo-yPSprB34CP_" | ||||
|         "hQ8c9vTolpXDFYvbldvCorr4A54Cs8HnKWeDP9lnpS7_vPyIcP7RMNvPYF2-" | ||||
|         "k2vUnpGfgsl86aUzsy7XeKLQ8IunxPSzu28QzPJW08nNO4EA91uFJWZ05VhSWsuQ3Dbc4F" | ||||
|         "qVtHrb3Fv2d5BSp11XZhZ8WzP-3fwFOiVFV", | ||||
|         q_encoded); | ||||
|     free(q_encoded); | ||||
| 
 | ||||
|     char *ret = curl_get(news); | ||||
|     free(news); | ||||
|     if (!ret) continue; | ||||
|     if (!ret) | ||||
|       continue; | ||||
| 
 | ||||
|     json_object *json_ret = json_tokener_parse(ret); | ||||
|     if (!json_ret) { | ||||
| @ -76,12 +172,15 @@ char *web_search_engine(char *q) { | ||||
|   const int MAX_RETRIES = 3; | ||||
|   for (int retry = 0; retry < MAX_RETRIES; retry++) { | ||||
|     char *searx = malloc(4096); | ||||
|     if (!searx) return NULL; | ||||
|     if (!searx) | ||||
|       return NULL; | ||||
|     searx[0] = 0; | ||||
|     snprintf(searx, 4096, "https://searx.molodetz.nl/search?q=%s&format=json", q); | ||||
|     snprintf(searx, 4096, "https://searx.molodetz.nl/search?q=%s&format=json", | ||||
|              q); | ||||
|     char *ret = curl_get(searx); | ||||
|     free(searx); | ||||
|     if (!ret) continue; | ||||
|     if (!ret) | ||||
|       continue; | ||||
| 
 | ||||
|     json_object *json_ret = json_tokener_parse(ret); | ||||
|     if (!json_ret) { | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| #include "db_utils.h" | ||||
| #include <sqlite3.h> | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <sqlite3.h> | ||||
| 
 | ||||
| void db_initialize() { | ||||
|   sqlite3 *db; | ||||
|  | ||||
							
								
								
									
										40
									
								
								db_utils.h
									
									
									
									
									
								
							
							
						
						
									
										40
									
								
								db_utils.h
									
									
									
									
									
								
							| @ -22,8 +22,6 @@ json_object *db_set(const char *key, const char *value); | ||||
| json_object *db_get(const char *key); | ||||
| json_object *db_query(const char *query); | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| void db_initialize() { | ||||
|   sqlite3 *db; | ||||
|   int rc = sqlite3_open(db_file_expanded(), &db); | ||||
| @ -32,12 +30,14 @@ void db_initialize() { | ||||
|     return; | ||||
|   } | ||||
| 
 | ||||
|    db_execute("CREATE TABLE IF NOT EXISTS kv_store (key TEXT PRIMARY KEY, value TEXT);"); | ||||
|    db_execute("CREATE TABLE IF NOT EXISTS file_version_history ( id INTEGER PRIMARY KEY AUTOINCREMENT," | ||||
|     "path TEXT NOT NULL," | ||||
|     "content TEXT," | ||||
|     "date DATETIME DEFAULT CURRENT_TIMESTAMP" | ||||
|     ");"); | ||||
|   db_execute("CREATE TABLE IF NOT EXISTS kv_store (key TEXT PRIMARY KEY, value " | ||||
|              "TEXT);"); | ||||
|   db_execute("CREATE TABLE IF NOT EXISTS file_version_history ( id INTEGER " | ||||
|              "PRIMARY KEY AUTOINCREMENT," | ||||
|              "path TEXT NOT NULL," | ||||
|              "content TEXT," | ||||
|              "date DATETIME DEFAULT CURRENT_TIMESTAMP" | ||||
|              ");"); | ||||
| 
 | ||||
|   sqlite3_close(db); | ||||
| } | ||||
| @ -180,18 +180,20 @@ json_object *db_execute(const char *query) { | ||||
|   sqlite3_close(db); | ||||
|   return result; | ||||
| } | ||||
| void db_store_file_version(const char * path) { | ||||
|     char * expanded = expand_home_directory(path); | ||||
| void db_store_file_version(const char *path) { | ||||
|   char *expanded = expand_home_directory(path); | ||||
| 
 | ||||
|     char * content = read_file(expanded); | ||||
|     if(!content) { | ||||
|         return; | ||||
|     } | ||||
|     fprintf(stderr, "Creating backup:: %s\n", expanded); | ||||
|     char * formatted = sqlite3_mprintf("INSERT INTO file_version_history (path, content) VALUES (%Q, %Q)", expanded, content); | ||||
|     db_execute(formatted); | ||||
|     sqlite3_free(formatted);     | ||||
|     free(content); | ||||
|   char *content = read_file(expanded); | ||||
|   if (!content) { | ||||
|     return; | ||||
|   } | ||||
|   fprintf(stderr, "Creating backup:: %s\n", expanded); | ||||
|   char *formatted = sqlite3_mprintf( | ||||
|       "INSERT INTO file_version_history (path, content) VALUES (%Q, %Q)", | ||||
|       expanded, content); | ||||
|   db_execute(formatted); | ||||
|   sqlite3_free(formatted); | ||||
|   free(content); | ||||
| } | ||||
| char *db_get_schema() { | ||||
|   json_object *tables = | ||||
|  | ||||
| @ -76,8 +76,8 @@ char *curl_post(const char *url, const char *data) { | ||||
|     curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&response); | ||||
|     res = curl_easy_perform(curl); | ||||
|     if (res != CURLE_OK) { | ||||
|       fprintf(stderr, "Url: %s\n",data); | ||||
|       fprintf(stderr, "Data: %s\n",data); | ||||
|       fprintf(stderr, "Url: %s\n", data); | ||||
|       fprintf(stderr, "Data: %s\n", data); | ||||
|       fprintf(stderr, "An error occurred: %s\n", curl_easy_strerror(res)); | ||||
|     } | ||||
|     curl_slist_free_all(headers); | ||||
|  | ||||
							
								
								
									
										176
									
								
								indexer.h
									
									
									
									
									
								
							
							
						
						
									
										176
									
								
								indexer.h
									
									
									
									
									
								
							| @ -12,101 +12,123 @@ | ||||
| #define MAX_PATH 4096 | ||||
| 
 | ||||
| static const char *extensions[] = { | ||||
|     ".c", ".cpp", ".h", ".py", ".java", ".js", ".mk", ".html", | ||||
|     "Makefile", ".css", ".json", ".cs", ".csproj", ".sln", ".toml", ".rs", | ||||
|     ".go", ".rb", ".swift", ".php", ".pl", ".sh", ".bash", ".sql", | ||||
|     ".xml", ".yaml", ".yml", ".kt", ".dart", ".scala", ".clj", ".asm", | ||||
|     ".m", ".r", ".lua", ".groovy", ".v", ".pas", ".d", ".f90", ".f95", | ||||
|     ".for", ".s", ".tcl", ".vhdl", ".verilog", ".coffee", ".less", ".scss", | ||||
|     ".ps1", ".psm1", ".cmd", ".bat", ".json5", ".cxx", ".cc", ".hpp", | ||||
|     ".hxx", ".inc", ".nsi", ".ninja", ".cmake", ".cmake.in", ".mk.in", | ||||
|     ".make", ".makefile", ".gyp", ".gypi", ".pro", ".qml", ".ui", ".wxs", | ||||
|     ".wxl", ".wxi", ".wxl", ".wxs", ".wxi", ".wxl", ".wxs", ".wxi" | ||||
| }; | ||||
|     ".c",      ".cpp",   ".h",        ".py",      ".java",   ".js", | ||||
|     ".mk",     ".html",  "Makefile",  ".css",     ".json",   ".cs", | ||||
|     ".csproj", ".sln",   ".toml",     ".rs",      ".go",     ".rb", | ||||
|     ".swift",  ".php",   ".pl",       ".sh",      ".bash",   ".sql", | ||||
|     ".xml",    ".yaml",  ".yml",      ".kt",      ".dart",   ".scala", | ||||
|     ".clj",    ".asm",   ".m",        ".r",       ".lua",    ".groovy", | ||||
|     ".v",      ".pas",   ".d",        ".f90",     ".f95",    ".for", | ||||
|     ".s",      ".tcl",   ".vhdl",     ".verilog", ".coffee", ".less", | ||||
|     ".scss",   ".ps1",   ".psm1",     ".cmd",     ".bat",    ".json5", | ||||
|     ".cxx",    ".cc",    ".hpp",      ".hxx",     ".inc",    ".nsi", | ||||
|     ".ninja",  ".cmake", ".cmake.in", ".mk.in",   ".make",   ".makefile", | ||||
|     ".gyp",    ".gypi",  ".pro",      ".qml",     ".ui",     ".wxs", | ||||
|     ".wxl",    ".wxi",   ".wxl",      ".wxs",     ".wxi",    ".wxl", | ||||
|     ".wxs",    ".wxi"}; | ||||
| static const size_t ext_count = sizeof(extensions) / sizeof(extensions[0]); | ||||
| 
 | ||||
| typedef struct { | ||||
|     char name[MAX_PATH]; | ||||
|     char modification_date[20]; | ||||
|     char creation_date[20]; | ||||
|     char type[10]; | ||||
|     size_t size_bytes; | ||||
|   char name[MAX_PATH]; | ||||
|   char modification_date[20]; | ||||
|   char creation_date[20]; | ||||
|   char type[10]; | ||||
|   size_t size_bytes; | ||||
| } FileInfo; | ||||
| 
 | ||||
| static FileInfo file_list[MAX_FILES]; | ||||
| static size_t file_count = 0; | ||||
| 
 | ||||
| static int is_valid_extension(const char *filename) { | ||||
|     const char *dot = strrchr(filename, '.'); | ||||
|     if (!dot) dot = filename; | ||||
|     for (size_t i = 0; i < ext_count; i++) { | ||||
|         if (strcmp(dot, extensions[i]) == 0) return 1; | ||||
|     } | ||||
|     return 0; | ||||
|   const char *dot = strrchr(filename, '.'); | ||||
|   if (!dot) | ||||
|     dot = filename; | ||||
|   for (size_t i = 0; i < ext_count; i++) { | ||||
|     if (strcmp(dot, extensions[i]) == 0) | ||||
|       return 1; | ||||
|   } | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| static int is_ignored_directory(const char *dir_name) { | ||||
|     const char *ignored_dirs[] = {"env", ".venv", "node_modules", "venv", "virtualenv"}; | ||||
|     for (size_t i = 0; i < sizeof(ignored_dirs) / sizeof(ignored_dirs[0]); i++) { | ||||
|         if (strcmp(dir_name, ignored_dirs[i]) == 0) return 1; | ||||
|     } | ||||
|     return 0; | ||||
|   const char *ignored_dirs[] = {"env", ".venv", "node_modules", "venv", | ||||
|                                 "virtualenv"}; | ||||
|   for (size_t i = 0; i < sizeof(ignored_dirs) / sizeof(ignored_dirs[0]); i++) { | ||||
|     if (strcmp(dir_name, ignored_dirs[i]) == 0) | ||||
|       return 1; | ||||
|   } | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| static void get_file_info(const char *path) { | ||||
|     struct stat file_stat; | ||||
|     if (stat(path, &file_stat) == 0) { | ||||
|         FileInfo info; | ||||
|         strncpy(info.name, path, MAX_PATH - 1); | ||||
|         info.name[MAX_PATH - 1] = '\0'; | ||||
|         strftime(info.modification_date, sizeof(info.modification_date), "%Y-%m-%d %H:%M:%S", localtime(&file_stat.st_mtime)); | ||||
|         strftime(info.creation_date, sizeof(info.creation_date), "%Y-%m-%d %H:%M:%S", localtime(&file_stat.st_ctime)); | ||||
|         strncpy(info.type, S_ISDIR(file_stat.st_mode) ? "directory" : "file", sizeof(info.type) - 1); | ||||
|         info.type[sizeof(info.type) - 1] = '\0'; | ||||
|         info.size_bytes = file_stat.st_size; | ||||
|         file_list[file_count++] = info; | ||||
|     } | ||||
|   struct stat file_stat; | ||||
|   if (stat(path, &file_stat) == 0) { | ||||
|     FileInfo info; | ||||
|     strncpy(info.name, path, MAX_PATH - 1); | ||||
|     info.name[MAX_PATH - 1] = '\0'; | ||||
|     strftime(info.modification_date, sizeof(info.modification_date), | ||||
|              "%Y-%m-%d %H:%M:%S", localtime(&file_stat.st_mtime)); | ||||
|     strftime(info.creation_date, sizeof(info.creation_date), | ||||
|              "%Y-%m-%d %H:%M:%S", localtime(&file_stat.st_ctime)); | ||||
|     strncpy(info.type, S_ISDIR(file_stat.st_mode) ? "directory" : "file", | ||||
|             sizeof(info.type) - 1); | ||||
|     info.type[sizeof(info.type) - 1] = '\0'; | ||||
|     info.size_bytes = file_stat.st_size; | ||||
|     file_list[file_count++] = info; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| char *index_directory(const char *dir_path) { | ||||
|     DIR *dir = opendir(dir_path); | ||||
|     if (!dir) { | ||||
|         perror("Failed to open directory"); | ||||
|         return NULL; | ||||
|   DIR *dir = opendir(dir_path); | ||||
|   if (!dir) { | ||||
|     perror("Failed to open directory"); | ||||
|     return NULL; | ||||
|   } | ||||
| 
 | ||||
|   struct dirent *entry; | ||||
|   json_object *jarray = json_object_new_array(); | ||||
| 
 | ||||
|   while ((entry = readdir(dir)) != NULL) { | ||||
|     if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) | ||||
|       continue; | ||||
|     if (entry->d_name[0] == '.' || is_ignored_directory(entry->d_name)) | ||||
|       continue; | ||||
| 
 | ||||
|     char full_path[MAX_PATH]; | ||||
|     snprintf(full_path, sizeof(full_path), "%s/%s", dir_path, entry->d_name); | ||||
| 
 | ||||
|     if (entry->d_type == DT_DIR) { | ||||
|       char *subdir_json = index_directory(full_path); | ||||
|       if (subdir_json) { | ||||
|         json_object *jsubdir = json_object_new_string(subdir_json); | ||||
|         json_object_array_add(jarray, jsubdir); | ||||
|         free(subdir_json); | ||||
|       } | ||||
|     } else if (is_valid_extension(entry->d_name)) { | ||||
|       get_file_info(full_path); | ||||
|       json_object *jfile = json_object_new_object(); | ||||
|       json_object_object_add( | ||||
|           jfile, "file_name", | ||||
|           json_object_new_string(file_list[file_count - 1].name)); | ||||
|       json_object_object_add( | ||||
|           jfile, "modification_date", | ||||
|           json_object_new_string(file_list[file_count - 1].modification_date)); | ||||
|       json_object_object_add( | ||||
|           jfile, "creation_date", | ||||
|           json_object_new_string(file_list[file_count - 1].creation_date)); | ||||
|       json_object_object_add( | ||||
|           jfile, "type", | ||||
|           json_object_new_string(file_list[file_count - 1].type)); | ||||
|       json_object_object_add( | ||||
|           jfile, "size_bytes", | ||||
|           json_object_new_int64(file_list[file_count - 1].size_bytes)); | ||||
| 
 | ||||
|       json_object_array_add(jarray, jfile); | ||||
|     } | ||||
|   } | ||||
|   closedir(dir); | ||||
| 
 | ||||
|     struct dirent *entry; | ||||
|     json_object *jarray = json_object_new_array(); | ||||
| 
 | ||||
|     while ((entry = readdir(dir)) != NULL) { | ||||
|         if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue; | ||||
|         if (entry->d_name[0] == '.' || is_ignored_directory(entry->d_name)) continue; | ||||
| 
 | ||||
|         char full_path[MAX_PATH]; | ||||
|         snprintf(full_path, sizeof(full_path), "%s/%s", dir_path, entry->d_name); | ||||
| 
 | ||||
|         if (entry->d_type == DT_DIR) { | ||||
|             char *subdir_json = index_directory(full_path); | ||||
|             if (subdir_json) { | ||||
|                 json_object *jsubdir = json_object_new_string(subdir_json); | ||||
|                 json_object_array_add(jarray, jsubdir); | ||||
|                 free(subdir_json); | ||||
|             } | ||||
|         } else if (is_valid_extension(entry->d_name)) { | ||||
|             get_file_info(full_path); | ||||
|             json_object *jfile = json_object_new_object(); | ||||
|             json_object_object_add(jfile, "file_name", json_object_new_string(file_list[file_count - 1].name)); | ||||
|             json_object_object_add(jfile, "modification_date", json_object_new_string(file_list[file_count - 1].modification_date)); | ||||
|             json_object_object_add(jfile, "creation_date", json_object_new_string(file_list[file_count - 1].creation_date)); | ||||
|             json_object_object_add(jfile, "type", json_object_new_string(file_list[file_count - 1].type)); | ||||
|             json_object_object_add(jfile, "size_bytes", json_object_new_int64(file_list[file_count - 1].size_bytes)); | ||||
| 
 | ||||
|             json_object_array_add(jarray, jfile); | ||||
|         } | ||||
|     } | ||||
|     closedir(dir); | ||||
| 
 | ||||
|     char *result = strdup(json_object_to_json_string(jarray)); | ||||
|     json_object_put(jarray); | ||||
|     return result; | ||||
|   char *result = strdup(json_object_to_json_string(jarray)); | ||||
|   json_object_put(jarray); | ||||
|   return result; | ||||
| } | ||||
							
								
								
									
										374
									
								
								main.c
									
									
									
									
									
								
							
							
						
						
									
										374
									
								
								main.c
									
									
									
									
									
								
							| @ -1,18 +1,18 @@ | ||||
| #include "r.h" | ||||
| #include <locale.h> | ||||
| #include <signal.h> | ||||
| #include <stdbool.h> | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <locale.h> | ||||
| #include <unistd.h> | ||||
| 
 | ||||
| #include "db_utils.h" | ||||
| #include "line.h" | ||||
| #include "markdown.h" | ||||
| #include "openai.h" | ||||
| #include "utils.h" | ||||
| #include "db_utils.h" | ||||
| #include "tools.h" | ||||
| #include "utils.h" | ||||
| 
 | ||||
| volatile sig_atomic_t sigint_count = 0; | ||||
| time_t first_sigint_time = 0; | ||||
| @ -25,232 +25,244 @@ bool openai_include(const char *); | ||||
| char *strreplace(const char *, const char *, const char *); | ||||
| 
 | ||||
| char *get_prompt_from_stdin(char *prompt) { | ||||
|     int index = 0; | ||||
|     char c; | ||||
|     while ((c = getchar()) != EOF) { | ||||
|         prompt[index++] = c; | ||||
|     } | ||||
|     prompt[index] = '\0'; | ||||
|     return prompt; | ||||
|   int index = 0; | ||||
|   char c; | ||||
|   while ((c = getchar()) != EOF) { | ||||
|     prompt[index++] = c; | ||||
|   } | ||||
|   prompt[index] = '\0'; | ||||
|   return prompt; | ||||
| } | ||||
| 
 | ||||
| char *get_prompt_from_args(int argc, char **argv) { | ||||
|     char *prompt = malloc(10 * 1024 * 1024 + 1); | ||||
|     char *system = malloc(1024 * 1024); | ||||
|     if (!prompt || !system) { | ||||
|         fprintf(stderr, "Error: Memory allocation failed.\n"); | ||||
|         free(prompt); | ||||
|         free(system); | ||||
|         return NULL; | ||||
|     } | ||||
|   char *prompt = malloc(10 * 1024 * 1024 + 1); | ||||
|   char *system = malloc(1024 * 1024); | ||||
|   if (!prompt || !system) { | ||||
|     fprintf(stderr, "Error: Memory allocation failed.\n"); | ||||
|     free(prompt); | ||||
|     free(system); | ||||
|     return NULL; | ||||
|   } | ||||
| 
 | ||||
|     bool get_from_std_in = false; | ||||
|   bool get_from_std_in = false; | ||||
| 
 | ||||
|     for (int i = 1; i < argc; i++) { | ||||
|         if (strcmp(argv[i], "--stdin") == 0) { | ||||
|             fprintf(stderr, "Reading from stdin.\n"); | ||||
|             get_from_std_in = true; | ||||
|         } else if (strcmp(argv[i], "--verbose") == 0) { | ||||
|             is_verbose = true; | ||||
|         } else if (strcmp(argv[i], "--py") == 0 && i + 1 < argc) { | ||||
|             char *py_file_path = expand_home_directory(argv[++i]); | ||||
|             fprintf(stderr, "Including \"%s\".\n", py_file_path); | ||||
|             openai_include(py_file_path); | ||||
|             free(py_file_path); | ||||
|         } else if (strcmp(argv[i], "--free") == 0) { | ||||
|             auth_free(); | ||||
|         } else if (strcmp(argv[i], "--context") == 0 && i + 1 < argc) { | ||||
|             char *context_file_path = argv[++i]; | ||||
|             fprintf(stderr, "Including \"%s\".\n", context_file_path); | ||||
|             openai_include(context_file_path); | ||||
|         } else if (strcmp(argv[i], "--api") == 0) { | ||||
|             API_MODE = true; | ||||
|         } else if (strcmp(argv[i], "--nh") == 0) { | ||||
|             SYNTAX_HIGHLIGHT_ENABLED = false; | ||||
|             fprintf(stderr, "Syntax highlighting disabled.\n"); | ||||
|         } else { | ||||
|             strcat(system, argv[i]); | ||||
|             strcat(system, (i < argc - 1) ? " " : "."); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     if (get_from_std_in) { | ||||
|         if (*system) openai_system(system); | ||||
|         prompt = get_prompt_from_stdin(prompt); | ||||
|   for (int i = 1; i < argc; i++) { | ||||
|     if (strcmp(argv[i], "--stdin") == 0) { | ||||
|       fprintf(stderr, "Reading from stdin.\n"); | ||||
|       get_from_std_in = true; | ||||
|     } else if (strcmp(argv[i], "--verbose") == 0) { | ||||
|       is_verbose = true; | ||||
|     } else if (strcmp(argv[i], "--py") == 0 && i + 1 < argc) { | ||||
|       char *py_file_path = expand_home_directory(argv[++i]); | ||||
|       fprintf(stderr, "Including \"%s\".\n", py_file_path); | ||||
|       openai_include(py_file_path); | ||||
|       free(py_file_path); | ||||
|     } else if (strcmp(argv[i], "--free") == 0) { | ||||
|       auth_free(); | ||||
|     } else if (strcmp(argv[i], "--context") == 0 && i + 1 < argc) { | ||||
|       char *context_file_path = argv[++i]; | ||||
|       fprintf(stderr, "Including \"%s\".\n", context_file_path); | ||||
|       openai_include(context_file_path); | ||||
|     } else if (strcmp(argv[i], "--api") == 0) { | ||||
|       API_MODE = true; | ||||
|     } else if (strcmp(argv[i], "--nh") == 0) { | ||||
|       SYNTAX_HIGHLIGHT_ENABLED = false; | ||||
|       fprintf(stderr, "Syntax highlighting disabled.\n"); | ||||
|     } else { | ||||
|         free(prompt); | ||||
|         prompt = system; | ||||
|       strcat(system, argv[i]); | ||||
|       strcat(system, (i < argc - 1) ? " " : "."); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|     if (!*prompt) { | ||||
|         free(prompt); | ||||
|         return NULL; | ||||
|     } | ||||
|     return prompt; | ||||
|   if (get_from_std_in) { | ||||
|     if (*system) | ||||
|       openai_system(system); | ||||
|     prompt = get_prompt_from_stdin(prompt); | ||||
|   } else { | ||||
|     free(prompt); | ||||
|     prompt = system; | ||||
|   } | ||||
| 
 | ||||
|   if (!*prompt) { | ||||
|     free(prompt); | ||||
|     return NULL; | ||||
|   } | ||||
|   return prompt; | ||||
| } | ||||
| 
 | ||||
| bool try_prompt(int argc, char *argv[]) { | ||||
|     char *prompt = get_prompt_from_args(argc, argv); | ||||
|     if (prompt) { | ||||
|         char *response = openai_chat("user", prompt); | ||||
|         if (!response) { | ||||
|             printf("Could not get response from server\n"); | ||||
|             free(prompt); | ||||
|             return false; | ||||
|         } | ||||
|         render(response); | ||||
|         free(response); | ||||
|         free(prompt); | ||||
|         return true; | ||||
|   char *prompt = get_prompt_from_args(argc, argv); | ||||
|   if (prompt) { | ||||
|     char *response = openai_chat("user", prompt); | ||||
|     if (!response) { | ||||
|       printf("Could not get response from server\n"); | ||||
|       free(prompt); | ||||
|       return false; | ||||
|     } | ||||
|     return false; | ||||
|     render(response); | ||||
|     free(response); | ||||
|     free(prompt); | ||||
|     return true; | ||||
|   } | ||||
|   return false; | ||||
| } | ||||
| 
 | ||||
| char **get_parameters(const char *content, const char *delimiter) { | ||||
|     char *start = NULL; | ||||
|     char **parameters = NULL; | ||||
|     int count = 0; | ||||
|   char *start = NULL; | ||||
|   char **parameters = NULL; | ||||
|   int count = 0; | ||||
| 
 | ||||
|     while ((start = strstr(content, delimiter)) != NULL) { | ||||
|         start += 3; | ||||
|         char *end = strstr(start, delimiter); | ||||
|         char *parameter = malloc(end - start + 1); | ||||
|   while ((start = strstr(content, delimiter)) != NULL) { | ||||
|     start += 3; | ||||
|     char *end = strstr(start, delimiter); | ||||
|     char *parameter = malloc(end - start + 1); | ||||
| 
 | ||||
|         memcpy(parameter, start, end - start); | ||||
|         parameter[end - start] = '\0'; | ||||
|     memcpy(parameter, start, end - start); | ||||
|     parameter[end - start] = '\0'; | ||||
| 
 | ||||
|         content = end + 3; | ||||
|         count++; | ||||
|         parameters = realloc(parameters, sizeof(char *) * (count + 1)); | ||||
|         parameters[count - 1] = parameter; | ||||
|         parameters[count] = NULL; | ||||
|     } | ||||
|     content = end + 3; | ||||
|     count++; | ||||
|     parameters = realloc(parameters, sizeof(char *) * (count + 1)); | ||||
|     parameters[count - 1] = parameter; | ||||
|     parameters[count] = NULL; | ||||
|   } | ||||
| 
 | ||||
|     return parameters; | ||||
|   return parameters; | ||||
| } | ||||
| 
 | ||||
| void render(const char *content) { | ||||
|     if (SYNTAX_HIGHLIGHT_ENABLED) { | ||||
|         parse_markdown_to_ansi(content); | ||||
|     } else { | ||||
|         printf("%s", content); | ||||
|     } | ||||
|   if (SYNTAX_HIGHLIGHT_ENABLED) { | ||||
|     parse_markdown_to_ansi(content); | ||||
|   } else { | ||||
|     printf("%s", content); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| void repl() { | ||||
|     line_init(); | ||||
|     char *line = NULL; | ||||
|   line_init(); | ||||
|   char *line = NULL; | ||||
| 
 | ||||
|     while (true) { | ||||
|         line = line_read("> "); | ||||
|         if (!line || !*line) continue; | ||||
|   while (true) { | ||||
|     line = line_read("> "); | ||||
|     if (!line || !*line) | ||||
|       continue; | ||||
| 
 | ||||
|         if (!strncmp(line, "!dump", 5)) { | ||||
|             printf("%s\n", message_json()); | ||||
|             continue; | ||||
|         } | ||||
|         if (!strncmp(line, "!verbose", 8)) { | ||||
|             is_verbose = !is_verbose; | ||||
|             fprintf(stderr, "%s\n", is_verbose ? "Verbose mode enabled" : "Verbose mode disabled"); | ||||
|             continue; | ||||
|         } | ||||
|         if (line && *line != '\n') line_add_history(line); | ||||
|         if(!strncmp(line, "!tools", 6)) { | ||||
|             printf("Available tools: %s\n", json_object_to_json_string(tools_descriptions())); | ||||
|             continue; | ||||
|         } | ||||
|         if (!strncmp(line, "!models", 7)) { | ||||
|             printf("Current model: %s\n", openai_fetch_models()); | ||||
|             continue; | ||||
|         } | ||||
|         if (!strncmp(line, "!model", 6)) { | ||||
|             if (line[6] == ' ') { | ||||
|                 set_prompt_model(line + 7); | ||||
|             } | ||||
|             printf("Current model: %s\n", get_prompt_model()); | ||||
|             continue; | ||||
|         } | ||||
|         if (!strncmp(line, "exit", 4)) exit(0); | ||||
| 
 | ||||
|         while (line && *line != '\n') { | ||||
|             char *response = openai_chat("user", line); | ||||
|             if (response) { | ||||
|                 render(response); | ||||
|                 printf("\n"); | ||||
|                 if (strstr(response, "_STEP_")) { | ||||
|                     line = "continue"; | ||||
|                 } else { | ||||
|                     line = NULL; | ||||
|                 } | ||||
|                 free(response); | ||||
|             } else { | ||||
|                 exit(0); | ||||
|             } | ||||
|         } | ||||
|     if (!strncmp(line, "!dump", 5)) { | ||||
|       printf("%s\n", message_json()); | ||||
|       continue; | ||||
|     } | ||||
|     if (!strncmp(line, "!verbose", 8)) { | ||||
|       is_verbose = !is_verbose; | ||||
|       fprintf(stderr, "%s\n", | ||||
|               is_verbose ? "Verbose mode enabled" : "Verbose mode disabled"); | ||||
|       continue; | ||||
|     } | ||||
|     if (line && *line != '\n') | ||||
|       line_add_history(line); | ||||
|     if (!strncmp(line, "!tools", 6)) { | ||||
|       printf("Available tools: %s\n", | ||||
|              json_object_to_json_string(tools_descriptions())); | ||||
|       continue; | ||||
|     } | ||||
|     if (!strncmp(line, "!models", 7)) { | ||||
|       printf("Current model: %s\n", openai_fetch_models()); | ||||
|       continue; | ||||
|     } | ||||
|     if (!strncmp(line, "!model", 6)) { | ||||
|       if (line[6] == ' ') { | ||||
|         set_prompt_model(line + 7); | ||||
|       } | ||||
|       printf("Current model: %s\n", get_prompt_model()); | ||||
|       continue; | ||||
|     } | ||||
|     if (!strncmp(line, "exit", 4)) | ||||
|       exit(0); | ||||
| 
 | ||||
|     while (line && *line != '\n') { | ||||
|       char *response = openai_chat("user", line); | ||||
|       if (response) { | ||||
|         render(response); | ||||
|         printf("\n"); | ||||
|         if (strstr(response, "_STEP_")) { | ||||
|           line = "continue"; | ||||
|         } else { | ||||
|           line = NULL; | ||||
|         } | ||||
|         free(response); | ||||
|       } else { | ||||
|         exit(0); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| char *strreplace(const char *content, const char *what, const char *with) { | ||||
|     char *pos = strstr(content, what); | ||||
|     if (!pos) return strdup(content); | ||||
|   char *pos = strstr(content, what); | ||||
|   if (!pos) | ||||
|     return strdup(content); | ||||
| 
 | ||||
|     size_t result_size = strlen(content) + strlen(with) - strlen(what) + 1; | ||||
|     char *result = malloc(result_size); | ||||
|     snprintf(result, result_size, "%.*s%s%s", (int)(pos - content), content, with, pos + strlen(what)); | ||||
|     return result; | ||||
|   size_t result_size = strlen(content) + strlen(with) - strlen(what) + 1; | ||||
|   char *result = malloc(result_size); | ||||
|   snprintf(result, result_size, "%.*s%s%s", (int)(pos - content), content, with, | ||||
|            pos + strlen(what)); | ||||
|   return result; | ||||
| } | ||||
| 
 | ||||
| bool openai_include(const char *path) { | ||||
|     char *file_content = read_file(path); | ||||
|     if (!file_content) return false; | ||||
|   char *file_content = read_file(path); | ||||
|   if (!file_content) | ||||
|     return false; | ||||
| 
 | ||||
|     openai_system(file_content); | ||||
|     free(file_content); | ||||
|     return true; | ||||
|   openai_system(file_content); | ||||
|   free(file_content); | ||||
|   return true; | ||||
| } | ||||
| 
 | ||||
| void init() { | ||||
|     setbuf(stdout, NULL); | ||||
|     line_init(); | ||||
|     auth_init(); | ||||
|     db_initialize(); | ||||
|     char *schema = db_get_schema(); | ||||
|     char payload[1024 * 1024] = {0}; | ||||
|     snprintf(payload, sizeof(payload), | ||||
|              "Your have a database that you can mutate using the query tool and the get and set tool. This is the schema in json format: %s. Dialect is sqlite.", | ||||
|              schema); | ||||
|     free(schema); | ||||
|   setbuf(stdout, NULL); | ||||
|   line_init(); | ||||
|   auth_init(); | ||||
|   db_initialize(); | ||||
|   char *schema = db_get_schema(); | ||||
|   char payload[1024 * 1024] = {0}; | ||||
|   snprintf(payload, sizeof(payload), | ||||
|            "Your have a database that you can mutate using the query tool and " | ||||
|            "the get and set tool. This is the schema in json format: %s. " | ||||
|            "Dialect is sqlite.", | ||||
|            schema); | ||||
|   free(schema); | ||||
| 
 | ||||
|     fprintf(stderr, "Loading... 4e6"); | ||||
|     openai_system(payload); | ||||
|     if (!openai_include(".rcontext.txt")) { | ||||
|         openai_include("~/.rcontext.txt"); | ||||
|     } | ||||
|     fprintf(stderr, "\r                          \r"); | ||||
|   fprintf(stderr, "Loading... 4e6"); | ||||
|   openai_system(payload); | ||||
|   if (!openai_include(".rcontext.txt")) { | ||||
|     openai_include("~/.rcontext.txt"); | ||||
|   } | ||||
|   fprintf(stderr, "\r                          \r"); | ||||
| } | ||||
| 
 | ||||
| void handle_sigint(int sig) { | ||||
|     time_t current_time = time(NULL); | ||||
|     printf("\n"); | ||||
|     if (sigint_count == 0) { | ||||
|         first_sigint_time = current_time; | ||||
|         sigint_count++; | ||||
|   time_t current_time = time(NULL); | ||||
|   printf("\n"); | ||||
|   if (sigint_count == 0) { | ||||
|     first_sigint_time = current_time; | ||||
|     sigint_count++; | ||||
|   } else { | ||||
|     if (difftime(current_time, first_sigint_time) <= 1) { | ||||
|       exit(0); | ||||
|     } else { | ||||
|         if (difftime(current_time, first_sigint_time) <= 1) { | ||||
|             exit(0); | ||||
|         } else { | ||||
|             sigint_count = 1; | ||||
|             first_sigint_time = current_time; | ||||
|         } | ||||
|       sigint_count = 1; | ||||
|       first_sigint_time = current_time; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| int main(int argc, char *argv[]) { | ||||
|     signal(SIGINT, handle_sigint); | ||||
|   signal(SIGINT, handle_sigint); | ||||
| 
 | ||||
|     init(); | ||||
|     if (try_prompt(argc, argv)) return 0; | ||||
| 
 | ||||
|     repl(); | ||||
|   init(); | ||||
|   if (try_prompt(argc, argv)) | ||||
|     return 0; | ||||
| 
 | ||||
|   repl(); | ||||
|   return 0; | ||||
| } | ||||
							
								
								
									
										23
									
								
								messages.h
									
									
									
									
									
								
							
							
						
						
									
										23
									
								
								messages.h
									
									
									
									
									
								
							| @ -25,10 +25,10 @@ | ||||
| #ifndef R_MESSAGES_H | ||||
| #define R_MESSAGES_H | ||||
| 
 | ||||
| #include "db_utils.h" | ||||
| #include "json-c/json.h" | ||||
| #include "tools.h" | ||||
| #include <string.h> | ||||
| #include "db_utils.h" | ||||
| struct json_object *message_array = NULL; | ||||
| 
 | ||||
| struct json_object *message_list() { | ||||
| @ -66,7 +66,7 @@ struct json_object *message_add_tool_result(const char *tool_call_id, | ||||
|   json_object_object_add(message, "tool_call_id", | ||||
|                          json_object_new_string(tool_call_id)); | ||||
| 
 | ||||
|   if(strlen(tool_result) > 104000){ | ||||
|   if (strlen(tool_result) > 104000) { | ||||
|     tool_result[104000] = '\0'; | ||||
|   } | ||||
| 
 | ||||
| @ -82,25 +82,26 @@ void message_add_object(json_object *message) { | ||||
|   json_object_array_add(messages, message); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| struct json_object *message_add(const char *role, const char *content); | ||||
| 
 | ||||
| struct json_object *message_add(const char *role, const char *content) { | ||||
|   struct json_object *messages = message_list(); | ||||
|   struct json_object *message = json_object_new_object(); | ||||
|   json_object_object_add(message, "role", json_object_new_string(role)); | ||||
|    | ||||
|   if(content){ | ||||
|     char * formatted_content = strdup(content); | ||||
|     if(strlen(formatted_content) > 1048570){ | ||||
|         formatted_content[1048570] = '\0'; | ||||
| 
 | ||||
|   if (content) { | ||||
|     char *formatted_content = strdup(content); | ||||
|     if (strlen(formatted_content) > 1048570) { | ||||
|       formatted_content[1048570] = '\0'; | ||||
|     } | ||||
|     json_object_object_add(message, "content", json_object_new_string(formatted_content)); | ||||
|   free(formatted_content); | ||||
|     json_object_object_add(message, "content", | ||||
|                            json_object_new_string(formatted_content)); | ||||
|     free(formatted_content); | ||||
|   } | ||||
|   if (!strcmp(role, "user")) { | ||||
|     json_object_object_add(message, "tools", tools_descriptions()); | ||||
|     json_object_object_add(message, "parallel_tool_calls", json_object_new_boolean(true)); | ||||
|     json_object_object_add(message, "parallel_tool_calls", | ||||
|                            json_object_new_boolean(true)); | ||||
|   } | ||||
| 
 | ||||
|   json_object_array_add(messages, message); | ||||
|  | ||||
							
								
								
									
										6
									
								
								openai.h
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								openai.h
									
									
									
									
									
								
							| @ -46,7 +46,7 @@ bool openai_system(char *message_content) { | ||||
| 
 | ||||
| struct json_object *openai_process_chat_message(const char *api_url, | ||||
|                                                 const char *json_data) { | ||||
|     char *response = curl_post(api_url, json_data); | ||||
|   char *response = curl_post(api_url, json_data); | ||||
|   if (!response) { | ||||
|     fprintf(stderr, "Failed to get response.\n"); | ||||
|     return NULL; | ||||
| @ -128,8 +128,8 @@ char *openai_chat(const char *user_role, const char *message_content) { | ||||
|       message_add_tool_call(tool_call_result); | ||||
|     } | ||||
|     char *tool_calls_result_str = chat_json(NULL, NULL); | ||||
|     message_object = | ||||
|         openai_process_chat_message(get_completions_api_url(), tool_calls_result_str); | ||||
|     message_object = openai_process_chat_message(get_completions_api_url(), | ||||
|                                                  tool_calls_result_str); | ||||
|     if (message_object == NULL) { | ||||
|       return NULL; | ||||
|     } | ||||
|  | ||||
							
								
								
									
										89
									
								
								r.h
									
									
									
									
									
								
							
							
						
						
									
										89
									
								
								r.h
									
									
									
									
									
								
							| @ -11,58 +11,57 @@ char *completions_api_url = "https://api.openai.com/v1/chat/completions"; | ||||
| char *advanced_model = "gpt-4o-mini"; | ||||
| char *fast_model = "gpt-3.5-turbo"; | ||||
| 
 | ||||
| //char *models_api_url = "https://api.openai.com/v1/models";
 | ||||
| //char *completions_api_url = "https://api.anthropic.com/v1/chat/completions";
 | ||||
| //char *advanced_model = "claude-3-5-haiku-20241022";
 | ||||
| //char *advanced_model = "meta-llama/Meta-Llama-3.1-8B-Instruct";
 | ||||
| //char *advanced_model = "google/gemini-1.5-flash";
 | ||||
| //char *fast_model = "claude-3-5-haiku-20241022";
 | ||||
| // char *models_api_url = "https://api.openai.com/v1/models";
 | ||||
| // char *completions_api_url = "https://api.anthropic.com/v1/chat/completions";
 | ||||
| // char *advanced_model = "claude-3-5-haiku-20241022";
 | ||||
| // char *advanced_model = "meta-llama/Meta-Llama-3.1-8B-Instruct";
 | ||||
| // char *advanced_model = "google/gemini-1.5-flash";
 | ||||
| // char *fast_model = "claude-3-5-haiku-20241022";
 | ||||
| 
 | ||||
| //#endif
 | ||||
| //#ifdef OLLAMA
 | ||||
| //char *models_api_url = "https://ollama.molodetz.nl/v1/models";
 | ||||
| //char *completions_api_url = "https://ollama.molodetz.nl/v1/chat/completions";
 | ||||
| //char *advanced_model = "qwen2.5:3b";
 | ||||
| //char *advanced_model = "qwen2.5-coder:0.5b";
 | ||||
| //char *fast_model = "qwen2.5:0.5b";
 | ||||
| //#endif
 | ||||
| // #endif
 | ||||
| // #ifdef OLLAMA
 | ||||
| // char *models_api_url = "https://ollama.molodetz.nl/v1/models";
 | ||||
| // char *completions_api_url = "https://ollama.molodetz.nl/v1/chat/completions";
 | ||||
| // char *advanced_model = "qwen2.5:3b";
 | ||||
| // char *advanced_model = "qwen2.5-coder:0.5b";
 | ||||
| // char *fast_model = "qwen2.5:0.5b";
 | ||||
| // #endif
 | ||||
| 
 | ||||
| char *_model = NULL; | ||||
| 
 | ||||
| #define DB_FILE "~/.r.db" | ||||
| #define PROMPT_TEMPERATURE 0.1 | ||||
| 
 | ||||
| bool get_use_strict(){ | ||||
|     if(getenv("R_USE_STRICT") != NULL) { | ||||
|         const char * value = getenv("R_USE_STRICT"); | ||||
|         if(!strcmp(value, "true")) { | ||||
|             return true; | ||||
|         } | ||||
|         if(!strcmp(value, "false")) { | ||||
|             return false; | ||||
|         } | ||||
|         if(!strcmp(value, "1")) { | ||||
|             return true; | ||||
|         } | ||||
|         if(!strcmp(value, "0")) { | ||||
|             return false; | ||||
|         } | ||||
|     }  | ||||
|     return true; | ||||
|      | ||||
| bool get_use_strict() { | ||||
|   if (getenv("R_USE_STRICT") != NULL) { | ||||
|     const char *value = getenv("R_USE_STRICT"); | ||||
|     if (!strcmp(value, "true")) { | ||||
|       return true; | ||||
|     } | ||||
|     if (!strcmp(value, "false")) { | ||||
|       return false; | ||||
|     } | ||||
|     if (!strcmp(value, "1")) { | ||||
|       return true; | ||||
|     } | ||||
|     if (!strcmp(value, "0")) { | ||||
|       return false; | ||||
|     } | ||||
|   } | ||||
|   return true; | ||||
| } | ||||
| 
 | ||||
| char * get_completions_api_url() { | ||||
|     if(getenv("R_BASE_URL") != NULL) { | ||||
|         return joinpath(getenv("R_BASE_URL"), "v1/chat/completions"); | ||||
|     } | ||||
|     return completions_api_url; | ||||
| char *get_completions_api_url() { | ||||
|   if (getenv("R_BASE_URL") != NULL) { | ||||
|     return joinpath(getenv("R_BASE_URL"), "v1/chat/completions"); | ||||
|   } | ||||
|   return completions_api_url; | ||||
| } | ||||
| char * get_models_api_url() { | ||||
|     if(getenv("R_BASE_URL") != NULL) { | ||||
|         return joinpath(getenv("R_BASE_URL"), "v1/models"); | ||||
|     } | ||||
|     return models_api_url; | ||||
| char *get_models_api_url() { | ||||
|   if (getenv("R_BASE_URL") != NULL) { | ||||
|     return joinpath(getenv("R_BASE_URL"), "v1/models"); | ||||
|   } | ||||
|   return models_api_url; | ||||
| } | ||||
| 
 | ||||
| void set_prompt_model(const char *model) { | ||||
| @ -73,11 +72,11 @@ void set_prompt_model(const char *model) { | ||||
| } | ||||
| 
 | ||||
| const char *get_prompt_model() { | ||||
|   if(_model == NULL && getenv("R_MODEL") != NULL) { | ||||
|   if (_model == NULL && getenv("R_MODEL") != NULL) { | ||||
|     _model = getenv("R_MODEL"); | ||||
|   } | ||||
|   if(_model){ | ||||
|     return _model;  | ||||
|   if (_model) { | ||||
|     return _model; | ||||
|   } | ||||
|   if (auth_type != AUTH_TYPE_API_KEY) { | ||||
|     if (_model == NULL) { | ||||
|  | ||||
							
								
								
									
										155
									
								
								tools.h
									
									
									
									
									
								
							
							
						
						
									
										155
									
								
								tools.h
									
									
									
									
									
								
							| @ -12,23 +12,21 @@ | ||||
| #ifndef R_TOOLS_H | ||||
| #define R_TOOLS_H | ||||
| 
 | ||||
| 
 | ||||
| #include "http_curl.h" | ||||
| #include "r.h" | ||||
| #include "utils.h" | ||||
| #include <dirent.h> | ||||
| #include <errno.h> | ||||
| #include <glob.h> | ||||
| #include <json-c/json.h> | ||||
| #include <json-c/json_object.h> | ||||
| #include <stdbool.h> | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <sys/stat.h> | ||||
| #include <time.h> | ||||
| #include <unistd.h> | ||||
| #include <errno.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| 
 | ||||
| #include "browse.h" | ||||
| #include "db_utils.h" | ||||
| @ -120,8 +118,9 @@ struct json_object *tool_description_web_search_news() { | ||||
| 
 | ||||
|   json_object_object_add(function, "parameters", parameters); | ||||
| 
 | ||||
|   if(get_use_strict()) | ||||
|   json_object_object_add(function, "strict", json_object_new_boolean(get_use_strict())); | ||||
|   if (get_use_strict()) | ||||
|     json_object_object_add(function, "strict", | ||||
|                            json_object_new_boolean(get_use_strict())); | ||||
| 
 | ||||
|   json_object_object_add(root, "function", function); | ||||
| 
 | ||||
| @ -176,8 +175,9 @@ struct json_object *tool_description_web_search() { | ||||
| 
 | ||||
|   json_object_object_add(function, "parameters", parameters); | ||||
| 
 | ||||
|   if(get_use_strict()) | ||||
|   json_object_object_add(function, "strict", json_object_new_boolean(get_use_strict())); | ||||
|   if (get_use_strict()) | ||||
|     json_object_object_add(function, "strict", | ||||
|                            json_object_new_boolean(get_use_strict())); | ||||
| 
 | ||||
|   json_object_object_add(root, "function", function); | ||||
| 
 | ||||
| @ -224,13 +224,14 @@ struct json_object *tool_description_db_get() { | ||||
|   json_object_array_add(required, json_object_new_string("key")); | ||||
|   json_object_object_add(parameters, "required", required); | ||||
| 
 | ||||
|  json_object_object_add(parameters, "additionalProperties", | ||||
|   json_object_object_add(parameters, "additionalProperties", | ||||
|                          json_object_new_boolean(0)); | ||||
| 
 | ||||
|   json_object_object_add(function, "parameters", parameters); | ||||
| 
 | ||||
|   if(get_use_strict()) | ||||
|   json_object_object_add(function, "strict", json_object_new_boolean(get_use_strict())); | ||||
|   if (get_use_strict()) | ||||
|     json_object_object_add(function, "strict", | ||||
|                            json_object_new_boolean(get_use_strict())); | ||||
| 
 | ||||
|   json_object_object_add(root, "function", function); | ||||
| 
 | ||||
| @ -276,13 +277,14 @@ struct json_object *tool_description_db_query() { | ||||
|   json_object_array_add(required, json_object_new_string("query")); | ||||
|   json_object_object_add(parameters, "required", required); | ||||
| 
 | ||||
|  json_object_object_add(parameters, "additionalProperties", | ||||
|   json_object_object_add(parameters, "additionalProperties", | ||||
|                          json_object_new_boolean(0)); | ||||
| 
 | ||||
|   json_object_object_add(function, "parameters", parameters); | ||||
| 
 | ||||
|   if(get_use_strict()) | ||||
|   json_object_object_add(function, "strict", json_object_new_boolean(get_use_strict())); | ||||
|   if (get_use_strict()) | ||||
|     json_object_object_add(function, "strict", | ||||
|                            json_object_new_boolean(get_use_strict())); | ||||
| 
 | ||||
|   json_object_object_add(root, "function", function); | ||||
| 
 | ||||
| @ -335,13 +337,14 @@ struct json_object *tool_description_db_set() { | ||||
|   json_object_array_add(required, json_object_new_string("value")); | ||||
|   json_object_object_add(parameters, "required", required); | ||||
| 
 | ||||
|     json_object_object_add(parameters, "additionalProperties", | ||||
|   json_object_object_add(parameters, "additionalProperties", | ||||
|                          json_object_new_boolean(0)); | ||||
| 
 | ||||
|   json_object_object_add(function, "parameters", parameters); | ||||
| 
 | ||||
|   if(get_use_strict()) | ||||
|   json_object_object_add(function, "strict", json_object_new_boolean(get_use_strict())); | ||||
|   if (get_use_strict()) | ||||
|     json_object_object_add(function, "strict", | ||||
|                            json_object_new_boolean(get_use_strict())); | ||||
| 
 | ||||
|   json_object_object_add(root, "function", function); | ||||
| 
 | ||||
| @ -367,18 +370,16 @@ char *tool_function_linux_terminal(char *command) { | ||||
| 
 | ||||
|   char stderr_command[1024] = {0}; | ||||
| 
 | ||||
|   if(!strstr(command, "2>")) { | ||||
|   if (!strstr(command, "2>")) { | ||||
|     snprintf(stderr_command, sizeof(stderr_command), "%s 2>&1", command); | ||||
|     command = stderr_command; | ||||
|   }  | ||||
|      | ||||
|   } | ||||
| 
 | ||||
|   fp = popen(command, "r"); | ||||
|   if (fp == NULL) { | ||||
|     perror("popen failed"); | ||||
|     return strdup("Popen failed!"); | ||||
|   } | ||||
|    | ||||
| 
 | ||||
|   while (fgets(buffer, sizeof(buffer), fp) != NULL) { | ||||
|     size_t chunk_size = strlen(buffer); | ||||
| @ -482,8 +483,9 @@ struct json_object *tool_description_chdir() { | ||||
| 
 | ||||
|   json_object_object_add(function, "parameters", parameters); | ||||
| 
 | ||||
|   if(get_use_strict()) | ||||
|   json_object_object_add(function, "strict", json_object_new_boolean(get_use_strict())); | ||||
|   if (get_use_strict()) | ||||
|     json_object_object_add(function, "strict", | ||||
|                            json_object_new_boolean(get_use_strict())); | ||||
| 
 | ||||
|   json_object_object_add(root, "function", function); | ||||
| 
 | ||||
| @ -519,13 +521,14 @@ struct json_object *tool_description_index_source_directory() { | ||||
|   struct json_object *required = json_object_new_array(); | ||||
|   json_object_array_add(required, json_object_new_string("path")); | ||||
|   json_object_object_add(parameters, "required", required); | ||||
|      json_object_object_add(parameters, "additionalProperties", | ||||
|   json_object_object_add(parameters, "additionalProperties", | ||||
|                          json_object_new_boolean(0)); | ||||
| 
 | ||||
|   json_object_object_add(function, "parameters", parameters); | ||||
| 
 | ||||
|   if(get_use_strict()) | ||||
|   json_object_object_add(function, "strict", json_object_new_boolean(get_use_strict())); | ||||
|   if (get_use_strict()) | ||||
|     json_object_object_add(function, "strict", | ||||
|                            json_object_new_boolean(get_use_strict())); | ||||
| 
 | ||||
|   json_object_object_add(root, "function", function); | ||||
| 
 | ||||
| @ -569,8 +572,9 @@ struct json_object *tool_description_linux_terminal_interactive() { | ||||
| 
 | ||||
|   json_object_object_add(function, "parameters", parameters); | ||||
| 
 | ||||
|   if(get_use_strict()) | ||||
|   json_object_object_add(function, "strict", json_object_new_boolean(get_use_strict())); | ||||
|   if (get_use_strict()) | ||||
|     json_object_object_add(function, "strict", | ||||
|                            json_object_new_boolean(get_use_strict())); | ||||
| 
 | ||||
|   json_object_object_add(root, "function", function); | ||||
| 
 | ||||
| @ -614,8 +618,9 @@ struct json_object *tool_description_directory_rglob() { | ||||
| 
 | ||||
|   json_object_object_add(function, "parameters", parameters); | ||||
| 
 | ||||
|   if(get_use_strict()) | ||||
|   json_object_object_add(function, "strict", json_object_new_boolean(get_use_strict())); | ||||
|   if (get_use_strict()) | ||||
|     json_object_object_add(function, "strict", | ||||
|                            json_object_new_boolean(get_use_strict())); | ||||
| 
 | ||||
|   json_object_object_add(root, "function", function); | ||||
| 
 | ||||
| @ -651,12 +656,13 @@ struct json_object *tool_description_read_file() { | ||||
|   json_object_object_add(parameters, "required", required); | ||||
| 
 | ||||
|   json_object_object_add(parameters, "additionalProperties", | ||||
|                      json_object_new_boolean(0)); | ||||
|                          json_object_new_boolean(0)); | ||||
| 
 | ||||
|   json_object_object_add(function, "parameters", parameters); | ||||
| 
 | ||||
|   if(get_use_strict()) | ||||
|   json_object_object_add(function, "strict", json_object_new_boolean(get_use_strict())); | ||||
|   if (get_use_strict()) | ||||
|     json_object_object_add(function, "strict", | ||||
|                            json_object_new_boolean(get_use_strict())); | ||||
| 
 | ||||
|   json_object_object_add(root, "function", function); | ||||
| 
 | ||||
| @ -709,8 +715,9 @@ struct json_object *tool_description_write_file() { | ||||
| 
 | ||||
|   json_object_object_add(function, "parameters", parameters); | ||||
| 
 | ||||
|   if(get_use_strict()) | ||||
|   json_object_object_add(function, "strict", json_object_new_boolean(get_use_strict())); | ||||
|   if (get_use_strict()) | ||||
|     json_object_object_add(function, "strict", | ||||
|                            json_object_new_boolean(get_use_strict())); | ||||
| 
 | ||||
|   json_object_object_add(root, "function", function); | ||||
| 
 | ||||
| @ -721,16 +728,17 @@ char *tool_function_index_source_directory(char *path) { | ||||
|   return index_directory(path); | ||||
| } | ||||
| 
 | ||||
| char * tool_function_mkdir(char *path); | ||||
| char *tool_function_mkdir(char *path); | ||||
| 
 | ||||
| void ensure_parent_directory_exists(char *path_including_file_name) { | ||||
|   if(!path_including_file_name) return; | ||||
|   if (!path_including_file_name) | ||||
|     return; | ||||
| 
 | ||||
|     char *path = strdup(path_including_file_name); | ||||
|   char *path = strdup(path_including_file_name); | ||||
|   char *last_slash = strrchr(path, '/'); | ||||
|   if (last_slash != NULL) { | ||||
|     *last_slash = '\0'; | ||||
|     free(tool_function_mkdir(path));  | ||||
|     free(tool_function_mkdir(path)); | ||||
|   } | ||||
|   free(path); | ||||
| } | ||||
| @ -765,8 +773,8 @@ char *tool_function_read_file(char *path) { | ||||
| 
 | ||||
| char *tool_function_write_file(char *path, char *content) { | ||||
|   db_store_file_version(path); | ||||
|     ensure_parent_directory_exists(path); | ||||
|     FILE *fp = fopen(path, "w+"); | ||||
|   ensure_parent_directory_exists(path); | ||||
|   FILE *fp = fopen(path, "w+"); | ||||
|   if (fp == NULL) { | ||||
|     perror("fopen failed"); | ||||
|     return strdup("Failed to open file for writing!"); | ||||
| @ -883,8 +891,8 @@ char *tool_function_directory_rglob(char *target_dir) { | ||||
|   results.gl_pathc = 0; | ||||
|   struct stat file_stat; | ||||
|   char mod_time[20], create_time[20]; | ||||
|   | ||||
|   if(!strcmp(target_dir, ".")) { | ||||
| 
 | ||||
|   if (!strcmp(target_dir, ".")) { | ||||
|     target_dir[0] = '*'; | ||||
|   } | ||||
| 
 | ||||
| @ -1005,11 +1013,12 @@ struct json_object *tool_description_http_get() { | ||||
|   json_object_object_add(parameters, "required", required); | ||||
| 
 | ||||
|   json_object_object_add(parameters, "additionalProperties", | ||||
|                      json_object_new_boolean(0)); | ||||
|                          json_object_new_boolean(0)); | ||||
| 
 | ||||
|   json_object_object_add(function, "parameters", parameters); | ||||
|   if(get_use_strict()) | ||||
|   json_object_object_add(function, "strict", json_object_new_boolean(get_use_strict())); | ||||
|   if (get_use_strict()) | ||||
|     json_object_object_add(function, "strict", | ||||
|                            json_object_new_boolean(get_use_strict())); | ||||
| 
 | ||||
|   json_object_object_add(root, "function", function); | ||||
| 
 | ||||
| @ -1052,8 +1061,9 @@ struct json_object *tool_description_directory_glob() { | ||||
| 
 | ||||
|   json_object_object_add(function, "parameters", parameters); | ||||
| 
 | ||||
|   if(get_use_strict()) | ||||
|   json_object_object_add(function, "strict", json_object_new_boolean(get_use_strict())); | ||||
|   if (get_use_strict()) | ||||
|     json_object_object_add(function, "strict", | ||||
|                            json_object_new_boolean(get_use_strict())); | ||||
| 
 | ||||
|   json_object_object_add(root, "function", function); | ||||
| 
 | ||||
| @ -1089,12 +1099,13 @@ struct json_object *tool_description_linux_terminal() { | ||||
|   json_object_object_add(parameters, "required", required); | ||||
| 
 | ||||
|   json_object_object_add(parameters, "additionalProperties", | ||||
|                      json_object_new_boolean(0)); | ||||
|                          json_object_new_boolean(0)); | ||||
| 
 | ||||
|   json_object_object_add(function, "parameters", parameters); | ||||
| 
 | ||||
|   if(get_use_strict()) | ||||
|   json_object_object_add(function, "strict", json_object_new_boolean(get_use_strict())); | ||||
|   if (get_use_strict()) | ||||
|     json_object_object_add(function, "strict", | ||||
|                            json_object_new_boolean(get_use_strict())); | ||||
| 
 | ||||
|   json_object_object_add(root, "function", function); | ||||
| 
 | ||||
| @ -1102,26 +1113,26 @@ struct json_object *tool_description_linux_terminal() { | ||||
| } | ||||
| 
 | ||||
| char *tool_function_mkdir(char *path) { | ||||
|     char temp[2048]; | ||||
|     char *p = NULL; | ||||
|     size_t len; | ||||
|   char temp[2048]; | ||||
|   char *p = NULL; | ||||
|   size_t len; | ||||
| 
 | ||||
|     snprintf(temp, sizeof(temp), "%s", path); | ||||
|     len = strlen(temp); | ||||
|      | ||||
|     if (temp[len - 1] == '/') { | ||||
|         temp[len - 1] = '\0'; | ||||
|     } | ||||
|   snprintf(temp, sizeof(temp), "%s", path); | ||||
|   len = strlen(temp); | ||||
| 
 | ||||
|     for (p = temp + 1; *p; p++) { | ||||
|         if (*p == '/') { | ||||
|             *p = '\0'; | ||||
|             if (mkdir(temp, 0777) != 0 && errno != EEXIST) { | ||||
|                 return strdup("Failed to create directory!"); | ||||
|             } | ||||
|             *p = '/'; | ||||
|         } | ||||
|   if (temp[len - 1] == '/') { | ||||
|     temp[len - 1] = '\0'; | ||||
|   } | ||||
| 
 | ||||
|   for (p = temp + 1; *p; p++) { | ||||
|     if (*p == '/') { | ||||
|       *p = '\0'; | ||||
|       if (mkdir(temp, 0777) != 0 && errno != EEXIST) { | ||||
|         return strdup("Failed to create directory!"); | ||||
|       } | ||||
|       *p = '/'; | ||||
|     } | ||||
|   } | ||||
|   return strdup("Directory successfully created."); | ||||
| } | ||||
| 
 | ||||
| @ -1133,7 +1144,8 @@ struct json_object *tool_description_mkdir() { | ||||
|   json_object_object_add(function, "name", json_object_new_string("mkdir")); | ||||
|   json_object_object_add( | ||||
|       function, "description", | ||||
|       json_object_new_string("Creates a new directory with the specified path.")); | ||||
|       json_object_new_string( | ||||
|           "Creates a new directory with the specified path.")); | ||||
| 
 | ||||
|   struct json_object *parameters = json_object_new_object(); | ||||
|   json_object_object_add(parameters, "type", json_object_new_string("object")); | ||||
| @ -1157,8 +1169,9 @@ struct json_object *tool_description_mkdir() { | ||||
| 
 | ||||
|   json_object_object_add(function, "parameters", parameters); | ||||
| 
 | ||||
|   if(get_use_strict()) | ||||
|   json_object_object_add(function, "strict", json_object_new_boolean(get_use_strict())); | ||||
|   if (get_use_strict()) | ||||
|     json_object_object_add(function, "strict", | ||||
|                            json_object_new_boolean(get_use_strict())); | ||||
| 
 | ||||
|   json_object_object_add(root, "function", function); | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										103
									
								
								utils.h
									
									
									
									
									
								
							
							
						
						
									
										103
									
								
								utils.h
									
									
									
									
									
								
							| @ -21,87 +21,86 @@ | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| 
 | ||||
| 
 | ||||
| #ifdef _WIN32 | ||||
| #include <windows.h> | ||||
| #else | ||||
| #include <unistd.h> | ||||
| #include <limits.h> | ||||
| #include <pwd.h> | ||||
| #include <unistd.h> | ||||
| #endif | ||||
| 
 | ||||
| void get_current_directory() { | ||||
|     char buffer[PATH_MAX]; | ||||
|   char buffer[PATH_MAX]; | ||||
| 
 | ||||
| #ifdef _WIN32 | ||||
|     DWORD length = GetCurrentDirectory(PATH_MAX, buffer); | ||||
|     if (length > 0 && length < PATH_MAX) { | ||||
|         printf("Current Directory: %s\n", buffer); | ||||
|     } else { | ||||
|         printf("Error getting current directory.\n"); | ||||
|     } | ||||
|   DWORD length = GetCurrentDirectory(PATH_MAX, buffer); | ||||
|   if (length > 0 && length < PATH_MAX) { | ||||
|     printf("Current Directory: %s\n", buffer); | ||||
|   } else { | ||||
|     printf("Error getting current directory.\n"); | ||||
|   } | ||||
| #else | ||||
|     if (getcwd(buffer, sizeof(buffer)) != NULL) { | ||||
|         printf("Current Directory: %s\n", buffer); | ||||
|     } else { | ||||
|         perror("Error getting current directory"); | ||||
|     } | ||||
|   if (getcwd(buffer, sizeof(buffer)) != NULL) { | ||||
|     printf("Current Directory: %s\n", buffer); | ||||
|   } else { | ||||
|     perror("Error getting current directory"); | ||||
|   } | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| char* expand_home_directory(const char* path) { | ||||
|     if (path[0] != '~') { | ||||
|         return strdup(path); // Return the original path if it doesn't start with ~
 | ||||
|     } | ||||
| char *expand_home_directory(const char *path) { | ||||
|   if (path[0] != '~') { | ||||
|     return strdup(path); // Return the original path if it doesn't start with ~
 | ||||
|   } | ||||
| 
 | ||||
|     char* home_dir; | ||||
|   char *home_dir; | ||||
| 
 | ||||
| #ifdef _WIN32 | ||||
|     home_dir = getenv("USERPROFILE"); // Get home directory on Windows
 | ||||
|   home_dir = getenv("USERPROFILE"); // Get home directory on Windows
 | ||||
| #else | ||||
|     struct passwd* pw = getpwuid(getuid()); | ||||
|     home_dir = pw->pw_dir; // Get home directory on Linux
 | ||||
|   struct passwd *pw = getpwuid(getuid()); | ||||
|   home_dir = pw->pw_dir; // Get home directory on Linux
 | ||||
| #endif | ||||
| 
 | ||||
|     if (home_dir == NULL) { | ||||
|         return NULL; // Error getting home directory
 | ||||
|     } | ||||
|   if (home_dir == NULL) { | ||||
|     return NULL; // Error getting home directory
 | ||||
|   } | ||||
| 
 | ||||
|     // Allocate memory for the expanded path
 | ||||
|     size_t expanded_size = strlen(home_dir) + strlen(path); | ||||
|     char* expanded_path = (char *)malloc(expanded_size); | ||||
|     if (expanded_path == NULL) { | ||||
|         return NULL; // Memory allocation error
 | ||||
|     } | ||||
|   // Allocate memory for the expanded path
 | ||||
|   size_t expanded_size = strlen(home_dir) + strlen(path); | ||||
|   char *expanded_path = (char *)malloc(expanded_size); | ||||
|   if (expanded_path == NULL) { | ||||
|     return NULL; // Memory allocation error
 | ||||
|   } | ||||
| 
 | ||||
|     // Construct the expanded path
 | ||||
|     snprintf(expanded_path, expanded_size, "%s%s", home_dir, path + 1); | ||||
|     return expanded_path; | ||||
|   // Construct the expanded path
 | ||||
|   snprintf(expanded_path, expanded_size, "%s%s", home_dir, path + 1); | ||||
|   return expanded_path; | ||||
| } | ||||
| 
 | ||||
| unsigned long hash(const char *str) { | ||||
|     unsigned long hash = 5381; // Starting value
 | ||||
|     int c; | ||||
|   unsigned long hash = 5381; // Starting value
 | ||||
|   int c; | ||||
| 
 | ||||
|     while ((c = *str++)) { | ||||
|         hash = ((hash << 5) + hash) + c; // hash * 33 + c
 | ||||
|     } | ||||
|   while ((c = *str++)) { | ||||
|     hash = ((hash << 5) + hash) + c; // hash * 33 + c
 | ||||
|   } | ||||
| 
 | ||||
|     return hash; | ||||
|   return hash; | ||||
| } | ||||
| 
 | ||||
| char * joinpath(const char *base_url, const char *path) { | ||||
|     static char result[1024]; | ||||
|     result[0] = '\0'; | ||||
|     strcat(result, base_url); | ||||
|     if(base_url[strlen(base_url) - 1] != '/') { | ||||
|         strcat(result, "/"); | ||||
|     } | ||||
|     if(path[0] == '/') { | ||||
|         path++; | ||||
|     } | ||||
|     strcat(result, path); | ||||
|     return result; | ||||
| char *joinpath(const char *base_url, const char *path) { | ||||
|   static char result[1024]; | ||||
|   result[0] = '\0'; | ||||
|   strcat(result, base_url); | ||||
|   if (base_url[strlen(base_url) - 1] != '/') { | ||||
|     strcat(result, "/"); | ||||
|   } | ||||
|   if (path[0] == '/') { | ||||
|     path++; | ||||
|   } | ||||
|   strcat(result, path); | ||||
|   return result; | ||||
| } | ||||
| 
 | ||||
| char *read_file(const char *path) { | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user