void debug( int level, const wchar_t *msg, ... ) { va_list va; string_buffer_t sb; string_buffer_t sb2; int errno_old = errno; if( level > debug_level ) return; CHECK( msg, ); sb_init( &sb ); sb_init( &sb2 ); sb_printf( &sb, L"%ls: ", program_name ); va_start( va, msg ); sb_vprintf( &sb, msg, va ); va_end( va ); write_screen( (wchar_t *)sb.buff, &sb2 ); fwprintf( stderr, L"%ls", sb2.buff ); sb_destroy( &sb ); sb_destroy( &sb2 ); errno = errno_old; }
int ff_ctl_close(void) { sb_destroy(sb_in); sb_destroy(sb_out); ctrl_fd = -1; serv_fd = -1; return 0; }
static anna_node_t *anna_macro_attribute_expand(anna_node_call_t *node, anna_node_call_t *attr) { int i; for(i = attr->child_count-1; i >= 0; i--) { if(attr->child[i]->node_type == ANNA_NODE_IDENTIFIER) { anna_node_identifier_t *nam = (anna_node_identifier_t *)attr->child[i]; string_buffer_t sb; sb_init(&sb); sb_printf(&sb, L"%lsAttribute", nam->name); node = anna_node_create_call2( &node->location, anna_node_create_identifier( &nam->location, sb_content(&sb)), node); sb_destroy(&sb); /* anna_message(L"FADFADS\n"); anna_node_print(5, nam); anna_message(L"\n\n"); */ } } return (anna_node_t *)node; }
int luaamf_save(lua_State * L) { int result = LUAAMF_EFAILURE; luaamf_SaveBuffer sb; { void * alloc_ud = NULL; lua_Alloc alloc_fn = lua_getallocf(L, &alloc_ud); sb_init(&sb, alloc_fn, alloc_ud); } result = save_value(&sb, L, 1, 1); if (result != LUAAMF_ESUCCESS) { switch (result) { case LUAAMF_EBADTYPE: lua_pushliteral(L, "can't save: unsupported type detected"); break; case LUAAMF_ETOODEEP: lua_pushliteral(L, "can't save: nesting is too deep"); break; case LUAAMF_ETOOLONG: lua_pushliteral(L, "can't save: not enough memory"); break; default: /* Should not happen */ lua_pushliteral(L, "save failed"); break; } sb_destroy(&sb); return result; } { size_t len = 0UL; const unsigned char * buf = sb_buffer(&sb, &len); lua_pushlstring(L, (const char *)buf, len); sb_destroy(&sb); } return LUAAMF_ESUCCESS; }
int linda_close(linda *l) { if (!l) return 0; if (l->st) store_close(l->st); if (l->sl) sb_destroy(l->sl); free(l); return 1; }
/** For wgettext: Internal shutdown function. Automatically called on shutdown if the library has been initialized. */ static void wgettext_destroy() { int i; if( !wgettext_is_init ) return; wgettext_is_init = 0; for(i=0; i<BUFF_COUNT; i++ ) sb_destroy( &buff[i] ); free( wcs2str_buff ); }
/** Replace/append/insert the selection with/at/after the specified string. \param begin beginning of selection \param end end of selection \param insert the string to insert \param append_mode can be one of REPLACE_MODE, INSERT_MODE or APPEND_MODE, affects the way the test update is performed */ static void replace_part( const wchar_t *begin, const wchar_t *end, wchar_t *insert, int append_mode ) { const wchar_t *buff = get_buffer(); string_buffer_t out; int out_pos=get_cursor_pos(); sb_init( &out ); sb_append_substring( &out, buff, begin-buff ); switch( append_mode) { case REPLACE_MODE: { sb_append( &out, insert ); out_pos = wcslen( insert ) + (begin-buff); break; } case APPEND_MODE: { sb_append_substring( &out, begin, end-begin ); sb_append( &out, insert ); break; } case INSERT_MODE: { int cursor = get_cursor_pos() -(begin-buff); sb_append_substring( &out, begin, cursor ); sb_append( &out, insert ); sb_append_substring( &out, begin+cursor, end-begin-cursor ); out_pos += wcslen( insert ); break; } } sb_append( &out, end ); reader_set_buffer( (wchar_t *)out.buff, out_pos ); sb_destroy( &out ); }
int main (int argc, char *argv[]){ char hostname[20]; int port ; int lastopt=0; int longindex=0; int msg_type=EQUEUE_QUEUE; char topic[255]; char message[255]; SAPO_BROKER_T * conn=0; int role = ROLE_NONE; strcpy(topic, "/sapo/adword\0"); strcpy (message, "Hello world\0"); strcpy(hostname,DEFAULT_HOST); port = DEFAULT_PORT; while (1) { lastopt = getopt_long(argc,argv,"q:h:p:t:m:ris",long_options,&longindex); if (lastopt == -1) break; switch (lastopt) { case 0: break; case 'h': printf ("hostname = %s\n", optarg); strncpy(hostname, optarg, 20); break; case 'p': printf ("port = %s\n", optarg); port = atoi(optarg); break; case 't': printf ("Using topic : %s\n",optarg); strcpy(topic, optarg); break; case 'm': printf ("Using message: %s\n", optarg); strcpy(message, optarg); break; case 'r': if (role){ printf("Cannot be receiver and sender/interactive at the same time\n"); exit(1); } printf ("Will subscribe the topic and receive only\n"); role = ROLE_RECEIVER; break; case 'c': count = 0; break; case 'i': if (role){ printf("Cannot be interactive and sender/receiver at the same time\n"); exit(1); } printf("Showing interactive menu\n"); role = ROLE_INTERACTIVE; break; case 's': if (role){ printf("Cannot be sender and interactive/receiver at the same time\n"); exit(1); } printf("Will send to the topic only\n"); role = ROLE_SENDER; break; case 'q': msg_type = atoi(optarg); if ((msg_type< 1) || (msg_type>3)){ printf("Invalid message type %d. Only valid 1,2 or 3",msg_type); usage(argv[0]); exit(0); } break; case '?': usage(argv[0]); exit(0); default: printf ("Bad param %c \n", lastopt); usage(argv[0]); exit(1); } } conn = sb_new(hostname , port, SB_TYPE_TCP); switch(role){ case ROLE_INTERACTIVE: interactive(conn, msg_type, topic, message); break; case ROLE_SENDER: sender(conn, msg_type, topic, message); break; case ROLE_RECEIVER : receiver(conn, msg_type, topic); break; default: printf("No role provided. Defaulting to interactive\n"); interactive(conn, msg_type, topic, message); } if (conn) sb_destroy(conn); return 0; }
/** The complete builtin. Used for specifying programmable tab-completions. Calls the functions in complete.c for any heavy lifting. Defined in builtin_complete.c */ static int builtin_complete( wchar_t **argv ) { int res=0; int argc=0; int result_mode=SHARED; int remove = 0; int authoritative = -1; int flags = COMPLETE_AUTO_SPACE; string_buffer_t short_opt; array_list_t gnu_opt, old_opt; wchar_t *comp=L"", *desc=L"", *condition=L""; wchar_t *do_complete = 0; array_list_t cmd; array_list_t path; static int recursion_level=0; if( !is_interactive_session ) { debug( 1, _(L"%ls: Command only available in interactive sessions"), argv[0] ); } al_init( &cmd ); al_init( &path ); sb_init( &short_opt ); al_init( &gnu_opt ); al_init( &old_opt ); argc = builtin_count_args( argv ); woptind=0; while( res == 0 ) { const static struct woption long_options[] = { { L"exclusive", no_argument, 0, 'x' } , { L"no-files", no_argument, 0, 'f' } , { L"require-parameter", no_argument, 0, 'r' } , { L"path", required_argument, 0, 'p' } , { L"command", required_argument, 0, 'c' } , { L"short-option", required_argument, 0, 's' } , { L"long-option", required_argument, 0, 'l' } , { L"old-option", required_argument, 0, 'o' } , { L"description", required_argument, 0, 'd' } , { L"arguments", required_argument, 0, 'a' } , { L"erase", no_argument, 0, 'e' } , { L"unauthoritative", no_argument, 0, 'u' } , { L"authoritative", no_argument, 0, 'A' } , { L"condition", required_argument, 0, 'n' } , { L"do-complete", optional_argument, 0, 'C' } , { L"help", no_argument, 0, 'h' } , { 0, 0, 0, 0 } } ; int opt_index = 0; int opt = wgetopt_long( argc, argv, L"a:c:p:s:l:o:d:frxeuAn:C::h", long_options, &opt_index ); if( opt == -1 ) break; switch( opt ) { case 0: if(long_options[opt_index].flag != 0) break; sb_printf( sb_err, BUILTIN_ERR_UNKNOWN, argv[0], long_options[opt_index].name ); builtin_print_help( argv[0], sb_err ); res = 1; break; case 'x': result_mode |= EXCLUSIVE; break; case 'f': result_mode |= NO_FILES; break; case 'r': result_mode |= NO_COMMON; break; case 'p': case 'c': { wchar_t *a = unescape( woptarg, 1); if( a ) { al_push( (opt=='p'?&path:&cmd), a ); } else { sb_printf( sb_err, L"%ls: Invalid token '%ls'\n", argv[0], woptarg ); res = 1; } break; } case 'd': desc = woptarg; break; case 'u': authoritative=0; break; case 'A': authoritative=1; break; case 's': sb_append( &short_opt, woptarg ); break; case 'l': al_push( &gnu_opt, woptarg ); break; case 'o': al_push( &old_opt, woptarg ); break; case 'a': comp = woptarg; break; case 'e': remove = 1; break; case 'n': condition = woptarg; break; case 'C': do_complete = woptarg?woptarg:reader_get_buffer(); break; case 'h': builtin_print_help( argv[0], sb_out ); return 0; case '?': builtin_unknown_option( argv[0], argv[woptind-1] ); res = 1; break; } } if( !res ) { if( condition && wcslen( condition ) ) { if( parser_test( condition, 0, 0, 0 ) ) { sb_printf( sb_err, L"%ls: Condition '%ls' contained a syntax error\n", argv[0], condition ); parser_test( condition, 0, sb_err, argv[0] ); res = 1; } } } if( !res ) { if( comp && wcslen( comp ) ) { if( parser_test_args( comp, 0, 0 ) ) { sb_printf( sb_err, L"%ls: Completion '%ls' contained a syntax error\n", argv[0], comp ); parser_test_args( comp, sb_err, argv[0] ); res = 1; } } } if( !res ) { if( do_complete ) { array_list_t *comp; int i; const wchar_t *prev_temporary_buffer = temporary_buffer; wchar_t *token; parse_util_token_extent( do_complete, wcslen( do_complete ), &token, 0, 0, 0 ); temporary_buffer = do_complete; if( recursion_level < 1 ) { recursion_level++; comp = al_halloc( 0 ); complete( do_complete, comp ); for( i=0; i<al_get_count( comp ); i++ ) { completion_t *next = (completion_t *)al_get( comp, i ); wchar_t *prepend; if( next->flags & COMPLETE_NO_CASE ) { prepend = L""; } else { prepend = token; } if( next->description ) { sb_printf( sb_out, L"%ls%ls\t%ls\n", prepend, next->completion, next->description ); } else { sb_printf( sb_out, L"%ls%ls\n", prepend, next->completion ); } } halloc_free( comp ); recursion_level--; } temporary_buffer = prev_temporary_buffer; } else if( woptind != argc ) { sb_printf( sb_err, _( L"%ls: Too many arguments\n" ), argv[0] ); builtin_print_help( argv[0], sb_err ); res = 1; } else if( (al_get_count( &cmd) == 0 ) && (al_get_count( &path) == 0 ) ) { /* No arguments specified, meaning we print the definitions of * all specified completions to stdout.*/ complete_print( sb_out ); } else { if( remove ) { builtin_complete_remove( &cmd, &path, (wchar_t *)short_opt.buff, &gnu_opt, &old_opt ); } else { builtin_complete_add( &cmd, &path, (wchar_t *)short_opt.buff, &gnu_opt, &old_opt, result_mode, authoritative, condition, comp, desc, flags ); } } } al_foreach( &cmd, &free ); al_foreach( &path, &free ); al_destroy( &cmd ); al_destroy( &path ); sb_destroy( &short_opt ); al_destroy( &gnu_opt ); al_destroy( &old_opt ); return res; }
/** This function is executed by the child process created by a call to fork(). It should be called after \c setup_child_process. It calls execve to replace the fish process image with the command specified in \c p. It never returns. */ static void launch_process( process_t *p ) { FILE* f; int err; // debug( 1, L"exec '%ls'", p->argv[0] ); char **argv = wcsv2strv( (const wchar_t **) p->argv); char **envv = env_export_arr( 0 ); execve ( wcs2str(p->actual_cmd), argv, envv ); err = errno; /* Something went wrong with execve, check for a ":", and run /bin/sh if encountered. This is a weird predecessor to the shebang that is still sometimes used since it is supported on Windows. */ f = wfopen(p->actual_cmd, "r"); if( f ) { char begin[1] = {0}; size_t read; read = fread(begin, 1, 1, f); fclose( f ); if( (read==1) && (begin[0] == ':') ) { int count = 0; int i = 1; wchar_t **res; char **res_real; while( p->argv[count] != 0 ) count++; res = malloc( sizeof(wchar_t*)*(count+2)); res[0] = L"/bin/sh"; res[1] = p->actual_cmd; for( i=1; p->argv[i]; i++ ){ res[i+1] = p->argv[i]; } res[i+1] = 0; p->argv = res; p->actual_cmd = L"/bin/sh"; res_real = wcsv2strv( (const wchar_t **) res); execve ( wcs2str(p->actual_cmd), res_real, envv ); } } errno = err; debug( 0, _( L"Failed to execute process '%ls'. Reason:" ), p->actual_cmd ); switch( errno ) { case E2BIG: { size_t sz = 0; char **p; string_buffer_t sz1; string_buffer_t sz2; long arg_max = -1; sb_init( &sz1 ); sb_init( &sz2 ); for(p=argv; *p; p++) { sz += strlen(*p)+1; } for(p=envv; *p; p++) { sz += strlen(*p)+1; } sb_format_size( &sz1, sz ); arg_max = sysconf( _SC_ARG_MAX ); if( arg_max > 0 ) { sb_format_size( &sz2, arg_max ); debug( 0, L"The total size of the argument and environment lists (%ls) exceeds the operating system limit of %ls.", (wchar_t *)sz1.buff, (wchar_t *)sz2.buff); } else { debug( 0, L"The total size of the argument and environment lists (%ls) exceeds the operating system limit.", (wchar_t *)sz1.buff); } debug( 0, L"Try running the command again with fewer arguments."); sb_destroy( &sz1 ); sb_destroy( &sz2 ); exit(STATUS_EXEC_FAIL); break; } case ENOEXEC: { wperror(L"exec"); debug(0, L"The file '%ls' is marked as an executable but could not be run by the operating system.", p->actual_cmd); exit(STATUS_EXEC_FAIL); } case ENOENT: { wchar_t *interpreter = get_interpreter( p->actual_cmd ); if( interpreter && waccess( interpreter, X_OK ) ) { debug(0, L"The file '%ls' specified the interpreter '%ls', which is not an executable command.", p->actual_cmd, interpreter ); } else { debug(0, L"The file '%ls' or a script or ELF interpreter does not exist, or a shared library needed for file or interpreter cannot be found.", p->actual_cmd); } exit(STATUS_EXEC_FAIL); } case ENOMEM: { debug(0, L"Out of memory"); exit(STATUS_EXEC_FAIL); } default: { wperror(L"exec"); // debug(0, L"The file '%ls' is marked as an executable but could not be run by the operating system.", p->actual_cmd); exit(STATUS_EXEC_FAIL); } } }
/* Returns 0 on success, non-zero on failure */ static int save_table( lua_State * L, luaamf_SaveBuffer * sb, int index ) { luaamf_SaveBuffer numeric; luaamf_SaveBuffer associative; int result = LUAAMF_ESUCCESS; int numeric_index = 1; int key_value_pairs_number = 0; { void * alloc_ud = NULL; lua_Alloc alloc_fn = lua_getallocf(L, &alloc_ud); sb_init(&numeric, alloc_fn, alloc_ud); sb_init(&associative, alloc_fn, alloc_ud); } lua_pushnil(L); while (result == LUAAMF_ESUCCESS && lua_next(L, index) != 0) { int value_pos = lua_gettop(L); /* We need absolute values */ int key_pos = value_pos - 1; if(lua_type(L, key_pos) == LUA_TNUMBER && lua_tonumber(L, key_pos) == (float)numeric_index) { /* Save enumerated value. */ result = save_value(&numeric, L, value_pos, 1); numeric_index++; } else { /* Save associative key. */ result = save_value(&associative, L, key_pos, 0); /* Save associative value. */ if (result == LUAAMF_ESUCCESS) { result = save_value(&associative, L, value_pos, 1); key_value_pairs_number++; } } if (result == LUAAMF_ESUCCESS) { /* Remove value from stack, leave key for the next iteration. */ lua_pop(L, 1); } else { return result; } } /* write serilization here */ sb_writechar(sb, LUAAMF_ARRAY); encode_int(sb, 2 * key_value_pairs_number + 1); sb_write(sb, sb_buffer(&associative, &(associative.buf_size)), associative.buf_size); sb_writechar(sb, 0x001); sb_write(sb, sb_buffer(&numeric, &(numeric.buf_size)), numeric.buf_size); result = LUAAMF_ESUCCESS; sb_destroy(&numeric); sb_destroy(&associative); return result; }
/** The commandline builtin. It is used for specifying a new value for the commandline. */ static int builtin_commandline( wchar_t **argv ) { int buffer_part=0; int cut_at_cursor=0; int argc = builtin_count_args( argv ); int append_mode=0; int function_mode = 0; int tokenize = 0; int cursor_mode = 0; int line_mode = 0; int search_mode = 0; wchar_t *begin, *end; current_buffer = (wchar_t *)builtin_complete_get_temporary_buffer(); if( current_buffer ) { current_cursor_pos = wcslen( current_buffer ); } else { current_buffer = reader_get_buffer(); current_cursor_pos = reader_get_cursor_pos(); } if( !get_buffer() ) { if (is_interactive_session) { /* Prompt change requested while we don't have a prompt, most probably while reading the init files. Just ignore it. */ return 1; } sb_append( sb_err, argv[0], L": Can not set commandline in non-interactive mode\n", (void *)0 ); builtin_print_help( argv[0], sb_err ); return 1; } woptind=0; while( 1 ) { static const struct woption long_options[] = { { L"append", no_argument, 0, 'a' } , { L"insert", no_argument, 0, 'i' } , { L"replace", no_argument, 0, 'r' } , { L"current-job", no_argument, 0, 'j' } , { L"current-process", no_argument, 0, 'p' } , { L"current-token", no_argument, 0, 't' } , { L"current-buffer", no_argument, 0, 'b' } , { L"cut-at-cursor", no_argument, 0, 'c' } , { L"function", no_argument, 0, 'f' } , { L"tokenize", no_argument, 0, 'o' } , { L"help", no_argument, 0, 'h' } , { L"input", required_argument, 0, 'I' } , { L"cursor", no_argument, 0, 'C' } , { L"line", no_argument, 0, 'L' } , { L"search-mode", no_argument, 0, 'S' } , { 0, 0, 0, 0 } } ; int opt_index = 0; int opt = wgetopt_long( argc, argv, L"abijpctwforhI:CLS", long_options, &opt_index ); if( opt == -1 ) break; switch( opt ) { case 0: if(long_options[opt_index].flag != 0) break; sb_printf( sb_err, BUILTIN_ERR_UNKNOWN, argv[0], long_options[opt_index].name ); builtin_print_help( argv[0], sb_err ); return 1; case L'a': append_mode = APPEND_MODE; break; case L'b': buffer_part = STRING_MODE; break; case L'i': append_mode = INSERT_MODE; break; case L'r': append_mode = REPLACE_MODE; break; case 'c': cut_at_cursor=1; break; case 't': buffer_part = TOKEN_MODE; break; case 'j': buffer_part = JOB_MODE; break; case 'p': buffer_part = PROCESS_MODE; break; case 'f': function_mode=1; break; case 'o': tokenize=1; break; case 'I': current_buffer = woptarg; current_cursor_pos = wcslen( woptarg ); break; case 'C': cursor_mode = 1; break; case 'L': line_mode = 1; break; case 'S': search_mode = 1; break; case 'h': builtin_print_help( argv[0], sb_out ); return 0; case L'?': builtin_unknown_option( argv[0], argv[woptind-1] ); return 1; } } if( function_mode ) { int i; /* Check for invalid switch combinations */ if( buffer_part || cut_at_cursor || append_mode || tokenize || cursor_mode || line_mode || search_mode ) { sb_printf(sb_err, BUILTIN_ERR_COMBO, argv[0] ); builtin_print_help( argv[0], sb_err ); return 1; } if( argc == woptind ) { sb_printf( sb_err, BUILTIN_ERR_MISSING, argv[0] ); builtin_print_help( argv[0], sb_err ); return 1; } for( i=woptind; i<argc; i++ ) { wint_t c = input_function_get_code( argv[i] ); if( c != -1 ) { /* input_unreadch inserts the specified keypress or readline function at the top of the stack of unused keypresses */ input_unreadch(c); } else { sb_printf( sb_err, _(L"%ls: Unknown input function '%ls'\n"), argv[0], argv[i] ); builtin_print_help( argv[0], sb_err ); return 1; } } return 0; } /* Check for invalid switch combinations */ if( (search_mode || line_mode || cursor_mode) && (argc-woptind > 1) ) { sb_append( sb_err, argv[0], L": Too many arguments\n", (void *)0 ); builtin_print_help( argv[0], sb_err ); return 1; } if( (buffer_part || tokenize || cut_at_cursor) && (cursor_mode || line_mode || search_mode) ) { sb_printf( sb_err, BUILTIN_ERR_COMBO, argv[0] ); builtin_print_help( argv[0], sb_err ); return 1; } if( (tokenize || cut_at_cursor) && (argc-woptind) ) { sb_printf( sb_err, BUILTIN_ERR_COMBO2, argv[0], L"--cut-at-cursor and --tokenize can not be used when setting the commandline" ); builtin_print_help( argv[0], sb_err ); return 1; } if( append_mode && !(argc-woptind) ) { sb_printf( sb_err, BUILTIN_ERR_COMBO2, argv[0], L"insertion mode switches can not be used when not in insertion mode" ); builtin_print_help( argv[0], sb_err ); return 1; } /* Set default modes */ if( !append_mode ) { append_mode = REPLACE_MODE; } if( !buffer_part ) { buffer_part = STRING_MODE; } if( cursor_mode ) { if( argc-woptind ) { wchar_t *endptr; int new_pos; errno = 0; new_pos = wcstol( argv[woptind], &endptr, 10 ); if( *endptr || errno ) { sb_printf( sb_err, BUILTIN_ERR_NOT_NUMBER, argv[0], argv[woptind] ); builtin_print_help( argv[0], sb_err ); } current_buffer = reader_get_buffer(); new_pos = maxi( 0, mini( new_pos, wcslen( current_buffer ) ) ); reader_set_buffer( current_buffer, new_pos ); return 0; } else { sb_printf( sb_out, L"%d\n", reader_get_cursor_pos() ); return 0; } } if( line_mode ) { int pos = reader_get_cursor_pos(); wchar_t *buff = reader_get_buffer(); sb_printf( sb_out, L"%d\n", parse_util_lineno( buff, pos ) ); return 0; } if( search_mode ) { return !reader_search_mode(); } switch( buffer_part ) { case STRING_MODE: { begin = get_buffer(); end = begin+wcslen(begin); break; } case PROCESS_MODE: { parse_util_process_extent( get_buffer(), get_cursor_pos(), &begin, &end ); break; } case JOB_MODE: { parse_util_job_extent( get_buffer(), get_cursor_pos(), &begin, &end ); break; } case TOKEN_MODE: { parse_util_token_extent( get_buffer(), get_cursor_pos(), &begin, &end, 0, 0 ); break; } } switch(argc-woptind) { case 0: { write_part( begin, end, cut_at_cursor, tokenize ); break; } case 1: { replace_part( begin, end, argv[woptind], append_mode ); break; } default: { string_buffer_t sb; int i; sb_init( &sb ); sb_append( &sb, argv[woptind] ); for( i=woptind+1; i<argc; i++ ) { sb_append( &sb, L"\n" ); sb_append( &sb, argv[i] ); } replace_part( begin, end, (wchar_t *)sb.buff, append_mode ); sb_destroy( &sb ); break; } } return 0; }
/** Output the specified selection. \param begin start of selection \param end end of selection \param cut_at_cursor whether printing should stop at the surrent cursor position \param tokenize whether the string should be tokenized, printing one string token on every line and skipping non-string tokens */ static void write_part( const wchar_t *begin, const wchar_t *end, int cut_at_cursor, int tokenize ) { tokenizer tok; string_buffer_t out; wchar_t *buff; int pos; pos = get_cursor_pos()-(begin-get_buffer()); if( tokenize ) { buff = wcsndup( begin, end-begin ); // fwprintf( stderr, L"Subshell: %ls, end char %lc\n", buff, *end ); sb_init( &out ); for( tok_init( &tok, buff, TOK_ACCEPT_UNFINISHED ); tok_has_next( &tok ); tok_next( &tok ) ) { if( (cut_at_cursor) && (tok_get_pos( &tok)+wcslen(tok_last( &tok)) >= pos) ) break; switch( tok_last_type( &tok ) ) { case TOK_STRING: { wchar_t *tmp = unescape( tok_last( &tok ), UNESCAPE_INCOMPLETE ); sb_append( &out, tmp, L"\n", (void *)0 ); free( tmp ); break; } } } sb_append( sb_out, (wchar_t *)out.buff ); free( buff ); tok_destroy( &tok ); sb_destroy( &out ); } else { wchar_t *buff, *esc; if( cut_at_cursor ) { end = begin+pos; } buff = wcsndup( begin, end-begin ); esc = unescape( buff, UNESCAPE_INCOMPLETE ); // debug( 0, L"woot2 %ls -> %ls", buff, esc ); sb_append( sb_out, esc ); sb_append( sb_out, L"\n" ); free( esc ); free( buff ); } }
/** * ngt_embed - Turn one or more template files into C code for embedding into programs */ int ngt_embed(const char* code_template, FILE* out, int argc, char** argv) { int i; ngt_template* tpl; ngt_dictionary* dict; char* output; char file[PATH_MAX]; char name[PATH_MAX]; if (argc == 1) { fprintf(stderr, "USAGE: ngtembed file1[=name1] file2[=name2] ... fileN[=nameN] [>out_file]\n"); return -1; } tpl = ngt_new(); dict = ngt_dictionary_new(); ngt_add_modifier(tpl, "breakup_lines", _breakup_lines_modifier_cb); ngt_set_delimiters(tpl, "@", "@"); ngt_set_dictionary(tpl, dict); tpl->tmpl = (char*)code_template; for (i = 1; i < argc; i++) { char* p; int m, has_name; p = argv[i]; m = 0; has_name = 0; while (*p) { if (m < PATH_MAX && *p == '=') { // Setting an explicit name. Throw out what we've done so far has_name = 1; m = 0; p++; continue; } if (*p == '.' || *p == '\\' || *p == '/') { name[m] = '_'; } else { name[m] = *p; } if (!has_name) { file[m] = *p; file[m+1] = '\0'; } p++; m++; } name[m] = '\0'; if (m) { stringbuilder* sb; FILE* fd; int ch; fd = fopen(file, "r"); if (!fd) { fprintf(stderr, "Could not open '%s' for reading\n", file); return -1; } ngt_dictionary* section = ngt_dictionary_new(); ngt_set_string(section, "TemplateName", name); sb = sb_new(); while ((ch = fgetc(fd)) != EOF) { sb_append_ch(sb, (char)ch); } ngt_set_string(section, "TemplateBody", sb_cstring(sb)); sb_destroy(sb, 1); ngt_add_dictionary(dict, "Template", section, NGT_SECTION_VISIBLE); fclose(fd); } } ngt_expand(tpl, &output); fprintf(out, "%s\n", output); ngt_destroy(tpl); ngt_dictionary_destroy(dict); free(output); }