Changes in / [5fb32c5:921b84f] in mainline


Ignore:
Files:
24 edited

Legend:

Unmodified
Added
Removed
  • HelenOS.config

    r5fb32c5 r921b84f  
    7070@ "pentium4" Pentium 4
    7171@ "pentium3" Pentium 3
     72@ "i486" i486
    7273@ "core" Core Solo/Duo
    7374@ "athlon_xp" Athlon XP
    7475@ "athlon_mp" Athlon MP
    75 @ "i486" i486
    7676! [PLATFORM=ia32] PROCESSOR (choice)
    7777
  • abi/include/ipc/methods.h

    r5fb32c5 r921b84f  
    9696 *                       error is sent back to caller. Otherwise
    9797 *                       the call is accepted and the response is sent back.
     98 *                     - the hash of the client task is passed to userspace
     99 *                       (on the receiving side) as ARG4 of the call.
    98100 *                     - the hash of the allocated phone is passed to userspace
    99101 *                       (on the receiving side) as ARG5 of the call.
  • kernel/arch/ia32/Makefile.inc

    r5fb32c5 r921b84f  
    4444#
    4545
    46 ifeq ($(PROCESSOR),i486)
    47         CMN2 = -march=i486
    48 endif
    49 
    5046ifeq ($(PROCESSOR),athlon_xp)
    5147        CMN2 = -march=athlon-xp
     
    6662        CMN2 = -march=pentium4
    6763        SUNCC_CFLAGS += -xarch=sse2
     64endif
     65
     66ifeq ($(PROCESSOR),i486)
     67        CMN2 = -march=i486
    6868endif
    6969
  • kernel/arch/ia32/include/asm.h

    r5fb32c5 r921b84f  
    312312
    313313#ifndef PROCESSOR_i486
    314 
    315314/** Write to MSR */
    316315NO_TRACE static inline void write_msr(uint32_t msr, uint64_t value)
     
    337336        return ((uint64_t) dx << 32) | ax;
    338337}
    339 
    340 #endif /* PROCESSOR_i486 */
     338#endif
    341339
    342340
  • kernel/arch/ia32/include/boot/boot.h

    r5fb32c5 r921b84f  
    4343#define MULTIBOOT_HEADER_FLAGS  0x00010003
    4444
    45 #define MULTIBOOT_LOADER_MAGIC  0x2BADB002
    46 
    4745#ifndef __ASM__
    4846
  • kernel/arch/ia32/src/asm.S

    r5fb32c5 r921b84f  
    407407#ifdef PROCESSOR_i486
    408408        jz 0f
    409                 movl %eax, %ebp
    410         0:
     409        movl %eax, %ebp
     4100:
    411411#else
    412412        cmovnzl %eax, %ebp
  • kernel/arch/ia32/src/boot/boot.S

    r5fb32c5 r921b84f  
    9999#include "vesa_prot.inc"
    100100       
    101 #ifndef PROCESSOR_i486
    102        
    103         pm_status $status_prot2
    104        
    105         movl $(INTEL_CPUID_LEVEL), %eax
    106         cpuid
    107         cmp $0x0, %eax  /* any function > 0? */
    108         jbe pse_unsupported
    109        
    110         movl $(INTEL_CPUID_STANDARD), %eax
    111         cpuid
    112         bt $(INTEL_PSE), %edx
    113         jnc pse_unsupported
    114                
    115                 /* Map kernel and turn paging on */
    116                 pm_status $status_pse
    117                 call map_kernel_pse
    118                 jmp stack_init
    119        
    120 #endif /* PROCESSOR_i486 */
    121        
    122         pse_unsupported:
    123                
    124                 /* Map kernel and turn paging on */
    125                 pm_status $status_non_pse
    126                 call map_kernel
    127        
    128         stack_init:
     101        /* Map kernel and turn paging on */
     102        call map_kernel
    129103       
    130104        /* Create the first stack frame */
     
    132106        movl %esp, %ebp
    133107       
    134         pm2_status $status_prot3
     108        pm2_status $status_prot2
    135109       
    136110        /* Call arch_pre_main(grub_eax, grub_ebx) */
     
    150124                jmp hlt0
    151125
    152 /** Setup mapping for the kernel (PSE variant)
    153  *
    154  * Setup mapping for both the unmapped and mapped sections
    155  * of the kernel. For simplicity, we map the entire 4G space.
    156  *
    157  */
    158 .global map_kernel_pse
    159 map_kernel_pse:
    160         /* Paging features */
    161         movl %cr4, %ecx
    162         orl $(1 << 4), %ecx      /* PSE on */
    163         andl $(~(1 << 5)), %ecx  /* PAE off */
    164         movl %ecx, %cr4
    165        
    166         movl $(page_directory + 0), %esi
    167         movl $(page_directory + 2048), %edi
    168         xorl %ecx, %ecx
    169         xorl %ebx, %ebx
    170        
    171         floop_pse:
    172                 movl $((1 << 7) | (1 << 1) | (1 << 0)), %eax
    173                 orl %ebx, %eax
    174                 /* Mapping 0x00000000 + %ecx * 4M => 0x00000000 + %ecx * 4M */
    175                 movl %eax, (%esi, %ecx, 4)
    176                 /* Mapping 0x80000000 + %ecx * 4M => 0x00000000 + %ecx * 4M */
    177                 movl %eax, (%edi, %ecx, 4)
    178                 addl $(4 * 1024 * 1024), %ebx
    179                
    180                 incl %ecx
    181                 cmpl $512, %ecx
    182                 jl floop_pse
    183        
    184         movl %esi, %cr3
    185        
    186         movl %cr0, %ebx
    187         orl $(1 << 31), %ebx  /* paging on */
    188         movl %ebx, %cr0
     126/** Calculate unmapped address of the end of the kernel. */
     127calc_end_of_kernel:
     128        movl $hardcoded_load_address, %edi
     129        andl $0x7fffffff, %edi
     130        movl (%edi), %esi
     131        andl $0x7fffffff, %esi
     132       
     133        movl $hardcoded_ktext_size, %edi
     134        andl $0x7fffffff, %edi
     135        addl (%edi), %esi
     136        andl $0x7fffffff, %esi
     137       
     138        movl $hardcoded_kdata_size, %edi
     139        andl $0x7fffffff, %edi
     140        addl (%edi), %esi
     141        andl $0x7fffffff, %esi
     142        movl %esi, end_of_kernel
    189143        ret
    190144
    191 /** Setup mapping for the kernel (non-PSE variant).
     145/** Find free 2M (+4k for alignment) region where to store page tables */
     146find_mem_for_pt:
     147        /* Check if multiboot info is present */
     148        cmpl $0x2BADB002, grub_eax
     149        je check_multiboot_map
     150        ret
     151check_multiboot_map:
     152        /* Copy address of the multiboot info to ebx */
     153        movl grub_ebx, %ebx
     154        /* Check if memory map flag is present */
     155        movl (%ebx), %edx
     156        andl $(1 << 6), %edx
     157        jnz use_multiboot_map
     158        ret
     159use_multiboot_map:
     160        /* Copy address of the memory map to edx */
     161        movl 48(%ebx), %edx
     162        movl %edx, %ecx
     163        addl 44(%ebx), %ecx
     164        /* Find a free region at least 2M in size */
     165        check_memmap_loop:
     166                /* Is this a free region? */
     167                cmp $1, 20(%edx)
     168                jnz next_region
     169                /* Check size */
     170                cmp $0, 16(%edx)
     171                jnz next_region
     172                cmpl $(2 * 1024 * 1024 + 4 * 1024), 12(%edx)
     173                jbe next_region
     174                cmp $0, 8(%edx)
     175                jz found_region
     176        next_region:
     177                cmp %ecx, %edx
     178                jbe next_region_do
     179                ret
     180        next_region_do:
     181                addl (%edx), %edx
     182                addl $4, %edx
     183                jmp check_memmap_loop
     184        found_region:
     185                /* Use end of the found region */
     186                mov 4(%edx), %ecx
     187                add 12(%edx), %ecx
     188                sub $(2 * 1024 * 1024), %ecx
     189                mov %ecx, free_area
     190        ret
     191               
     192
     193/** Setup mapping for the kernel.
    192194 *
    193195 * Setup mapping for both the unmapped and mapped sections
     
    202204        movl %ecx, %cr4
    203205       
    204         call calc_kernel_end
     206        call calc_end_of_kernel
    205207        call find_mem_for_pt
    206        
    207         mov kernel_end, %esi
     208        mov end_of_kernel, %esi
    208209        mov free_area, %ecx
    209        
    210210        cmpl %esi, %ecx
    211         jbe use_kernel_end
    212                
    213                 mov %ecx, %esi
    214                
    215                 /* Align address down to 4k */
    216                 andl $(~4095), %esi
    217                
    218         use_kernel_end:
    219                
    220                 /* Align address to 4k */
    221                 addl $4095, %esi
    222                 andl $(~4095), %esi
    223                
    224                 /* Allocate space for page tables */
    225                 movl %esi, pt_loc
    226                 movl $ballocs, %edi
    227                 andl $0x7fffffff, %edi
    228                
    229                 movl %esi, (%edi)
    230                 addl $4, %edi
    231                 movl $(2 * 1024 * 1024), (%edi)
    232                
    233                 /* Fill page tables */
    234                 xorl %ecx, %ecx
    235                 xorl %ebx, %ebx
    236                
    237                 floop_pt:
    238                         movl $((1 << 1) | (1 << 0)), %eax
    239                         orl %ebx, %eax
    240                         movl %eax, (%esi, %ecx, 4)
    241                         addl $(4 * 1024), %ebx
    242                        
    243                         incl %ecx
    244                         cmpl $(512 * 1024), %ecx
    245                        
    246                         jl floop_pt
    247                
    248                 /* Fill page directory */
    249                 movl $(page_directory + 0), %esi
    250                 movl $(page_directory + 2048), %edi
    251                 xorl %ecx, %ecx
    252                 movl pt_loc, %ebx
    253                
    254                 floop:
    255                         movl $((1 << 1) | (1 << 0)), %eax
    256                         orl %ebx, %eax
    257                        
    258                         /* Mapping 0x00000000 + %ecx * 4M => 0x00000000 + %ecx * 4M */
    259                         movl %eax, (%esi, %ecx, 4)
    260                        
    261                         /* Mapping 0x80000000 + %ecx * 4M => 0x00000000 + %ecx * 4M */
    262                         movl %eax, (%edi, %ecx, 4)
    263                         addl $(4 * 1024), %ebx
    264                        
    265                         incl %ecx
    266                         cmpl $512, %ecx
    267                        
    268                         jl floop
    269                
    270                 movl %esi, %cr3
    271                
    272                 movl %cr0, %ebx
    273                 orl $(1 << 31), %ebx  /* paging on */
    274                 movl %ebx, %cr0
    275                
    276                 ret
    277 
    278 /** Calculate unmapped address of the end of the kernel. */
    279 calc_kernel_end:
    280         movl $hardcoded_load_address, %edi
     211        jbe use_end_of_kernel
     212        mov %ecx, %esi
     213        /* Align address down to 4k */
     214        andl $(~4095), %esi
     215use_end_of_kernel:
     216       
     217        /* Align address to 4k */
     218        addl $4095, %esi
     219        andl $(~4095), %esi
     220       
     221        /* Allocate space for page tables*/     
     222        movl %esi, pt_loc
     223        movl $ballocs, %edi
    281224        andl $0x7fffffff, %edi
    282         movl (%edi), %esi
    283         andl $0x7fffffff, %esi
    284        
    285         movl $hardcoded_ktext_size, %edi
    286         andl $0x7fffffff, %edi
    287         addl (%edi), %esi
    288         andl $0x7fffffff, %esi
    289        
    290         movl $hardcoded_kdata_size, %edi
    291         andl $0x7fffffff, %edi
    292         addl (%edi), %esi
    293         andl $0x7fffffff, %esi
    294         movl %esi, kernel_end
    295        
     225        movl %esi, (%edi)
     226        addl $4, %edi
     227        movl $(2*1024*1024), (%edi)
     228       
     229        /* Fill page tables */
     230        xorl %ecx, %ecx
     231        xorl %ebx, %ebx
     232       
     233        floop_pt:
     234                movl $((1 << 1) | (1 << 0)), %eax
     235                orl %ebx, %eax
     236                movl %eax, (%esi, %ecx, 4)
     237                addl $(4 * 1024), %ebx
     238               
     239                incl %ecx
     240                cmpl $(512 * 1024), %ecx
     241                jl floop_pt
     242       
     243        /* Fill page directory */
     244        movl $(page_directory + 0), %esi
     245        movl $(page_directory + 2048), %edi
     246        xorl %ecx, %ecx
     247        movl pt_loc, %ebx
     248       
     249        floop:
     250                movl $((1 << 1) | (1 << 0)), %eax
     251                orl %ebx, %eax
     252                /* Mapping 0x00000000 + %ecx * 4M => 0x00000000 + %ecx * 4M */
     253                movl %eax, (%esi, %ecx, 4)
     254                /* Mapping 0x80000000 + %ecx * 4M => 0x00000000 + %ecx * 4M */
     255                movl %eax, (%edi, %ecx, 4)
     256                addl $(4 * 1024), %ebx
     257               
     258                incl %ecx
     259                cmpl $512, %ecx
     260                jl floop
     261       
     262        movl %esi, %cr3
     263       
     264        movl %cr0, %ebx
     265        orl $(1 << 31), %ebx  /* paging on */
     266        movl %ebx, %cr0
    296267        ret
    297 
    298 /** Find free 2M (+4k for alignment) region where to store page tables */
    299 find_mem_for_pt:
    300         /* Check if multiboot info is present */
    301         cmpl $MULTIBOOT_LOADER_MAGIC, grub_eax
    302         je check_multiboot_map
    303                
    304                 ret
    305        
    306         check_multiboot_map:
    307                
    308                 /* Copy address of the multiboot info to ebx */
    309                 movl grub_ebx, %ebx
    310                
    311                 /* Check if memory map flag is present */
    312                 movl (%ebx), %edx
    313                 andl $(1 << 6), %edx
    314                 jnz use_multiboot_map
    315                        
    316                         ret
    317                
    318         use_multiboot_map:
    319                
    320                 /* Copy address of the memory map to edx */
    321                 movl 48(%ebx), %edx
    322                 movl %edx, %ecx
    323                
    324                 addl 44(%ebx), %ecx
    325                
    326                 /* Find a free region at least 2M in size */
    327                 check_memmap_loop:
    328                        
    329                         /* Is this a free region? */
    330                         cmp $1, 20(%edx)
    331                         jnz next_region
    332                        
    333                         /* Check size */
    334                         cmp $0, 16(%edx)
    335                         jnz next_region
    336                        
    337                         cmpl $(2 * 1024 * 1024 + 4 * 1024), 12(%edx)
    338                         jbe next_region
    339                        
    340                         cmp $0, 8(%edx)
    341                         jz found_region
    342                
    343                 next_region:
    344                        
    345                         cmp %ecx, %edx
    346                         jbe next_region_do
    347                        
    348                                 ret
    349                
    350                 next_region_do:
    351                        
    352                         addl (%edx), %edx
    353                         addl $4, %edx
    354                         jmp check_memmap_loop
    355                        
    356                 found_region:
    357                        
    358                         /* Use end of the found region */
    359                         mov 4(%edx), %ecx
    360                         add 12(%edx), %ecx
    361                         sub $(2 * 1024 * 1024), %ecx
    362                         mov %ecx, free_area
    363                        
    364                         ret
    365268
    366269/** Print string to EGA display (in light red) and halt.
     
    707610grub_eax:
    708611        .long 0
     612
    709613grub_ebx:
    710614        .long 0
     
    712616pt_loc:
    713617        .long 0
    714 kernel_end:
     618end_of_kernel:
    715619        .long 0
    716620free_area:
    717621        .long 0
    718622
     623err_pse:
     624        .asciz "Page Size Extension not supported. System halted."
     625
    719626status_prot:
    720627        .asciz "[prot] "
    721 status_pse:
    722         .asciz "[pse] "
    723 status_non_pse:
    724         .asciz "[non_pse] "
    725628status_vesa_copy:
    726629        .asciz "[vesa_copy] "
     
    731634status_prot2:
    732635        .asciz "[prot2] "
    733 status_prot3:
    734         .asciz "[prot3] "
    735636status_main:
    736637        .asciz "[main] "
  • kernel/arch/ia32/src/syscall.c

    r5fb32c5 r921b84f  
    4040
    4141#ifndef PROCESSOR_i486
    42 
    4342/** Enable & setup support for SYSENTER/SYSEXIT */
    4443void syscall_setup_cpu(void)
     
    5150        write_msr(IA32_MSR_SYSENTER_EIP, (uint32_t) sysenter_handler);
    5251}
    53 
    54 #endif /* PROCESSOR_i486 */
     52#endif
    5553
    5654/** @}
  • kernel/generic/include/ipc/ipc.h

    r5fb32c5 r921b84f  
    9898typedef struct {
    9999        sysarg_t args[IPC_CALL_LEN];
    100         /**
    101          * Task which made or forwarded the call with IPC_FF_ROUTE_FROM_ME,
    102          * or the task which answered the call.
    103          */
     100        /** Task which made or forwarded the call with IPC_FF_ROUTE_FROM_ME. */
    104101        task_id_t task_id;
    105102        /** Phone which made or last masqueraded this call. */
  • kernel/generic/src/ipc/ipc.c

    r5fb32c5 r921b84f  
    230230                }
    231231        }
    232 
    233         call->data.task_id = TASK->taskid;
    234232       
    235233        if (do_lock)
  • kernel/generic/src/ipc/sysipc.c

    r5fb32c5 r921b84f  
    253253                        /* The connection was accepted */
    254254                        phone_connect(phoneid, &answer->sender->answerbox);
     255                        /* Set 'task ID' as arg3 and arg4 of response */
     256                        IPC_SET_ARG3(answer->data, LOWER32(TASK->taskid));
     257                        IPC_SET_ARG4(answer->data, UPPER32(TASK->taskid));
    255258                        /* Set 'phone hash' as arg5 of response */
    256259                        IPC_SET_ARG5(answer->data,
  • uspace/app/bdsh/compl.c

    r5fb32c5 r921b84f  
    11/*
    22 * Copyright (c) 2011 Jiri Svoboda
    3  * Copyright (c) 2011 Martin Sucha
    43 * All rights reserved.
    54 *
     
    3837#include "compl.h"
    3938#include "exec.h"
    40 #include "tok.h"
    4139
    4240static int compl_init(wchar_t *text, size_t pos, size_t *cstart, void **state);
     
    9088{
    9189        compl_t *cs = NULL;
     90        size_t p;
    9291        size_t pref_size;
    9392        char *stext = NULL;
     
    9796        static const char *dirlist_arg[] = { ".", NULL };
    9897        int retval;
    99         tokenizer_t tok;
    100         token_t tokens[WORD_MAX];
    101         unsigned int current_token;
    102         size_t tokens_length;
    10398
    10499        cs = calloc(1, sizeof(compl_t));
     
    108103        }
    109104
     105        /*
     106         * Copy token pointed to by caret from start up to the caret.
     107         * XXX Ideally we would use the standard tokenizer.
     108         */
     109        p = pos;
     110        while (p > 0 && text[p - 1] != (wchar_t) ' ')
     111                --p;
     112        *cstart = p;
     113
    110114        /* Convert text buffer to string */
    111         stext = wstr_to_astr(text);
     115        stext = wstr_to_astr(text + *cstart);
    112116        if (stext == NULL) {
    113117                retval = ENOMEM;
    114118                goto error;
    115119        }
    116        
    117         /* Tokenize the input string */
    118         retval = tok_init(&tok, stext, tokens, WORD_MAX);
    119         if (retval != EOK) {
    120                 goto error;
    121         }
    122        
    123         retval = tok_tokenize(&tok, &tokens_length);
    124         if (retval != EOK) {
    125                 goto error;
    126         }
    127        
    128         /* Find the current token */
    129         for (current_token = 0; current_token < tokens_length; current_token++) {
    130                 token_t *t = &tokens[current_token];
    131                 size_t end = t->char_start + t->char_length;
    132                 /* Check if the caret lies inside the token or immediately
    133                  * after it
    134                  */
    135                 if (t->char_start <= pos && pos <= end) {
    136                         break;
    137                 }
    138         }
    139        
    140         if (tokens[current_token].type != TOKTYPE_SPACE) {
    141                 *cstart = tokens[current_token].char_start;
    142         }
    143         else {
    144                 *cstart = pos;
    145         }
    146        
    147         /* Extract the prefix being completed
    148          * XXX: handle strings, etc.
    149          */
     120
     121        /* Extract the prefix being completed */
    150122        pref_size = str_lsize(stext, pos - *cstart);
    151123        prefix = malloc(pref_size + 1);
     
    155127        }
    156128
    157         str_ncpy(prefix, pref_size + 1, stext +
    158             tokens[current_token].byte_start, pref_size);
     129        str_ncpy(prefix, pref_size + 1, stext, pref_size);
    159130
    160131        /*
     
    162133         * We look at the previous token. If there is none or it is a pipe
    163134         * ('|'), it is a command, otherwise it is an argument.
     135         * XXX Again we should use the standard tokenizer/parser.
    164136         */
    165137
    166138        /* Skip any whitespace before current token */
    167         int prev_token = current_token - 1;
    168         if (prev_token != -1 && tokens[prev_token].type == TOKTYPE_SPACE) {
    169                 prev_token--;
    170         }
     139        while (p > 0 && text[p - 1] == (wchar_t) ' ')
     140                --p;
    171141
    172142        /*
     
    174144         * follows a pipe token.
    175145         */
    176         if (prev_token == -1 || tokens[prev_token].type == TOKTYPE_SPACE)
     146        if (p == 0 || text[p - 1] == '|')
    177147                cs->is_command = true;
    178148        else
     
    219189
    220190        cs->prefix_len = str_length(cs->prefix);
    221        
    222         tok_fini(&tok);
    223191
    224192        *state = cs;
     
    227195error:
    228196        /* Error cleanup */
    229        
    230         tok_fini(&tok);
    231197
    232198        if (cs != NULL && cs->path_list != NULL) {
  • uspace/app/bdsh/input.c

    r5fb32c5 r921b84f  
    22 * Copyright (c) 2008 Tim Post
    33 * Copyright (c) 2011 Jiri Svoboda
    4  * Copyright (c) 2011 Martin Sucha
    54 * All rights reserved.
    65 *
     
    6867{
    6968        char *cmd[WORD_MAX];
    70         token_t tokens_space[WORD_MAX];
    71         token_t *tokens = tokens_space;
    7269        int rc = 0;
    7370        tokenizer_t tok;
    74         unsigned int i, pipe_count, processed_pipes;
    75         unsigned int pipe_pos[2];
     71        int i, pipe_count, processed_pipes;
     72        int pipe_pos[2];
     73        char **actual_cmd;
    7674        char *redir_from = NULL;
    7775        char *redir_to = NULL;
     
    8078                return CL_EFAIL;
    8179
    82         rc = tok_init(&tok, usr->line, tokens, WORD_MAX);
     80        rc = tok_init(&tok, usr->line, cmd, WORD_MAX);
    8381        if (rc != EOK) {
    8482                goto finit;
    8583        }
    8684       
    87         size_t tokens_length;
    88         rc = tok_tokenize(&tok, &tokens_length);
     85        rc = tok_tokenize(&tok);
    8986        if (rc != EOK) {
    9087                goto finit;
    91         }
    92        
    93         if (tokens_length > 0 && tokens[0].type == TOKTYPE_SPACE) {
    94                 tokens++;
    95                 tokens_length--;
    96         }
    97        
    98         if (tokens_length > 0 && tokens[tokens_length-1].type == TOKTYPE_SPACE) {
    99                 tokens_length--;
    10088        }
    10189       
     
    10593         * First find the pipes and check that there are no more
    10694         */
    107         for (i = 0, pipe_count = 0; i < tokens_length; i++) {
    108                 if (tokens[i].type == TOKTYPE_PIPE) {
     95        int cmd_length = 0;
     96        for (i = 0, pipe_count = 0; cmd[i] != NULL; i++, cmd_length++) {
     97                if (cmd[i][0] == '|') {
    10998                        if (pipe_count >= 2) {
    11099                                print_pipe_usage();
     
    117106        }
    118107       
    119         unsigned int cmd_token_start = 0;
    120         unsigned int cmd_token_end = tokens_length;
    121        
     108        actual_cmd = cmd;
    122109        processed_pipes = 0;
    123110       
    124111        /* Check if the first part (from <file> |) is present */
    125         if (pipe_count > 0 && (pipe_pos[0] == 3 || pipe_pos[0] == 4) && str_cmp(tokens[0].text, "from") == 0) {
     112        if (pipe_count > 0 && pipe_pos[0] == 2 && str_cmp(cmd[0], "from") == 0) {
    126113                /* Ignore the first three tokens (from, file, pipe) and set from */
    127                 redir_from = tokens[2].text;
    128                 cmd_token_start = pipe_pos[0]+1;
     114                redir_from = cmd[1];
     115                actual_cmd = cmd + 3;
    129116                processed_pipes++;
    130117        }
     
    132119        /* Check if the second part (| to <file>) is present */
    133120        if ((pipe_count - processed_pipes) > 0 &&
    134             (pipe_pos[processed_pipes] == tokens_length - 4 ||
    135             (pipe_pos[processed_pipes] == tokens_length - 5 &&
    136             tokens[tokens_length-4].type == TOKTYPE_SPACE )) &&
    137             str_cmp(tokens[tokens_length-3].text, "to") == 0) {
     121            pipe_pos[processed_pipes] == cmd_length - 3 &&
     122            str_cmp(cmd[cmd_length-2], "to") == 0) {
    138123                /* Ignore the last three tokens (pipe, to, file) and set to */
    139                 redir_to = tokens[tokens_length-1].text;
    140                 cmd_token_end = pipe_pos[processed_pipes];
     124                redir_to = cmd[cmd_length-1];
     125                cmd[cmd_length-3] = NULL;
     126                cmd_length -= 3;
    141127                processed_pipes++;
    142128        }
     
    148134        }
    149135       
    150         /* Convert tokens of the command to string array */
    151         unsigned int cmd_pos = 0;
    152         for (i = cmd_token_start; i < cmd_token_end; i++) {
    153                 if (tokens[i].type != TOKTYPE_SPACE) {
    154                         cmd[cmd_pos++] = tokens[i].text;
    155                 }
    156         }
    157         cmd[cmd_pos++] = NULL;
    158        
    159         if (cmd[0] == NULL) {
     136        if (actual_cmd[0] == NULL) {
    160137                print_pipe_usage();
    161138                rc = ENOTSUP;
     
    193170        }
    194171
    195         if (str_cmp(cmd[0], "batch") == 0 && cmd[1] != NULL) {
    196                 FILE *batch = fopen(cmd[1], "r");
     172        if (str_cmp(actual_cmd[0], "batch") == 0 && actual_cmd[1] != NULL) {
     173                FILE *batch = fopen(actual_cmd[1], "r");
    197174                if (batch == NULL) {
    198                         printf("Cannot open file %s\n", cmd[1]);
     175                        printf("Cannot open file %s\n", actual_cmd[1]);
    199176                        rc = errno;
    200177                } else {
     
    234211                }
    235212        } else {
    236                 rc = run_command(cmd, usr, &new_iostate);
    237         }
     213                rc = run_command(actual_cmd, usr, &new_iostate);
     214        }       
    238215       
    239216finit_with_files:
  • uspace/app/bdsh/tok.c

    r5fb32c5 r921b84f  
    4242static bool tok_pending_chars(tokenizer_t *);
    4343static int tok_finish_string(tokenizer_t *);
    44 static void tok_start_token(tokenizer_t *, token_type_t);
    4544
    4645/** Initialize the token parser
     
    5150 * @param max_tokens number of elements of the out_tokens array
    5251 */
    53 int tok_init(tokenizer_t *tok, char *input, token_t *out_tokens,
     52int tok_init(tokenizer_t *tok, char *input, char **out_tokens,
    5453    size_t max_tokens)
    5554{       
    5655        tok->in = input;
    5756        tok->in_offset = 0;
    58         tok->last_in_offset = 0;
    59         tok->in_char_offset = 0;
    60         tok->last_in_char_offset = 0;
    6157       
    6258        tok->outtok = out_tokens;
    6359        tok->outtok_offset = 0;
    64         tok->outtok_size = max_tokens;
     60        /* Leave one slot for a null terminator */
     61        assert(max_tokens > 0);
     62        tok->outtok_size = max_tokens - 1;
    6563       
    6664        /* Prepare a buffer where all the token strings will be stored */
     
    8987
    9088/** Tokenize the input string into the tokens */
    91 int tok_tokenize(tokenizer_t *tok, size_t *tokens_length)
     89int tok_tokenize(tokenizer_t *tok)
    9290{
    9391        int rc;
    94         wchar_t next_char;
     92        wchar_t cur_char;
    9593       
    9694        /* Read the input line char by char and append tokens */
    97         while ((next_char = tok_look_char(tok)) != 0) {
    98                 if (next_char == ' ') {
    99                         /* Push the token if there is any.
     95        while ((cur_char = tok_get_char(tok)) != 0) {
     96                if (cur_char == ' ') {
     97                        /* Spaces delimit tokens, but are not processed in any way
     98                         * Push the token if there is any.
    10099                         * There may not be any pending char for a token in case
    101100                         * there are several spaces in the input.
     
    107106                                }
    108107                        }
    109                         tok_start_token(tok, TOKTYPE_SPACE);
    110                         /* Eat all the spaces */
    111                         while (tok_look_char(tok) == ' ') {
    112                                 tok_push_char(tok, tok_get_char(tok));
    113                         }
    114                         tok_push_token(tok);
    115                        
    116                 }
    117                 else if (next_char == '|') {
    118                         /* Pipes are tokens that are delimiters and should be
    119                          * output as a separate token
     108                }
     109                else if (cur_char == '|') {
     110                        /* Pipes are tokens that are delimiters and should be output
     111                         * as a separate token
    120112                         */
    121113                        if (tok_pending_chars(tok)) {
     
    126118                        }
    127119                       
    128                         tok_start_token(tok, TOKTYPE_PIPE);
    129                        
    130                         rc = tok_push_char(tok, tok_get_char(tok));
     120                        rc = tok_push_char(tok, '|');
    131121                        if (rc != EOK) {
    132122                                return rc;
     
    138128                        }
    139129                }
    140                 else if (next_char == '\'') {
     130                else if (cur_char == '\'') {
    141131                        /* A string starts with a quote (') and ends again with a quote.
    142132                         * A literal quote is written as ''
    143133                         */
    144                         tok_start_token(tok, TOKTYPE_TEXT);
    145                         /* Eat the quote */
    146                         tok_get_char(tok);
    147134                        rc = tok_finish_string(tok);
    148135                        if (rc != EOK) {
     
    151138                }
    152139                else {
    153                         if (!tok_pending_chars(tok)) {
    154                                 tok_start_token(tok, TOKTYPE_TEXT);
    155                         }
    156140                        /* If we are handling any other character, just append it to
    157141                         * the current token.
    158142                         */
    159                         rc = tok_push_char(tok, tok_get_char(tok));
     143                        rc = tok_push_char(tok, cur_char);
    160144                        if (rc != EOK) {
    161145                                return rc;
     
    172156        }
    173157       
    174         *tokens_length = tok->outtok_offset;
     158        /* We always have a space for the terminator, as we
     159         * reserved it in tok_init */
     160        tok->outtok[tok->outtok_offset] = 0;
    175161       
    176162        return EOK;
     
    181167{
    182168        int rc;
    183         wchar_t next_char;
    184        
    185         while ((next_char = tok_look_char(tok)) != 0) {
    186                 if (next_char == '\'') {
    187                         /* Eat the quote */
    188                         tok_get_char(tok);
     169        wchar_t cur_char;
     170       
     171        while ((cur_char = tok_get_char(tok)) != 0) {
     172                if (cur_char == '\'') {
    189173                        if (tok_look_char(tok) == '\'') {
    190174                                /* Encode a single literal quote */
     
    203187                }
    204188                else {
    205                         rc = tok_push_char(tok, tok_get_char(tok));
     189                        rc = tok_push_char(tok, cur_char);
    206190                        if (rc != EOK) {
    207191                                return rc;
     
    217201wchar_t tok_get_char(tokenizer_t *tok)
    218202{
    219         tok->in_char_offset++;
    220203        return str_decode(tok->in, &tok->in_offset, STR_NO_LIMIT);
    221204}
     
    224207wchar_t tok_look_char(tokenizer_t *tok)
    225208{
    226         unsigned int old_offset = tok->in_offset;
    227         unsigned int old_char_offset = tok->in_char_offset;
     209        size_t old_offset = tok->in_offset;
    228210        wchar_t ret = tok_get_char(tok);
    229211        tok->in_offset = old_offset;
    230         tok->in_char_offset = old_char_offset;
    231212        return ret;
    232213}
     
    238219}
    239220
    240 void tok_start_token(tokenizer_t *tok, token_type_t type)
    241 {
    242         tok->current_type = type;
    243 }
    244 
    245221/** Push the current token to the output array */
    246222int tok_push_token(tokenizer_t *tok)
     
    255231       
    256232        tok->outbuf[tok->outbuf_offset++] = 0;
    257         token_t *tokinfo = &tok->outtok[tok->outtok_offset++];
    258         tokinfo->type = tok->current_type;
    259         tokinfo->text = tok->outbuf + tok->outbuf_last_start;
    260         tokinfo->byte_start = tok->last_in_offset;
    261         tokinfo->byte_length = tok->in_offset - tok->last_in_offset;
    262         tokinfo->char_start = tok->last_in_char_offset;
    263         tokinfo->char_length = tok->in_char_offset - tok->last_in_char_offset;
     233        tok->outtok[tok->outtok_offset++] = tok->outbuf + tok->outbuf_last_start;
    264234        tok->outbuf_last_start = tok->outbuf_offset;
    265        
    266         /* We have consumed the first char of the next token already */
    267         tok->last_in_offset = tok->in_offset;
    268         tok->last_in_char_offset = tok->in_char_offset;
    269235       
    270236        return EOK;
  • uspace/app/bdsh/tok.h

    r5fb32c5 r921b84f  
    3030#define TOK_H
    3131
    32 typedef enum {
    33         TOKTYPE_TEXT,
    34         TOKTYPE_PIPE,
    35         TOKTYPE_SPACE
    36 } token_type_t;
    37 
    38 typedef struct {
    39         char *text;
    40         unsigned int byte_start;
    41         unsigned int char_start;
    42         size_t byte_length;
    43         size_t char_length;
    44         token_type_t type;
    45 } token_t;
    46 
    4732typedef struct {
    4833        char *in;
    49         unsigned int in_offset;
    50         unsigned int last_in_offset;
    51         unsigned int in_char_offset;
    52         unsigned int last_in_char_offset;
     34        size_t in_offset;
    5335       
    5436        char *outbuf;
     
    5739        size_t outbuf_last_start;
    5840       
    59         token_t *outtok;
    60         token_type_t current_type;
     41        char **outtok;
    6142        size_t outtok_offset;
    6243        size_t outtok_size;
    6344} tokenizer_t;
    6445
    65 extern int tok_init(tokenizer_t *, char *, token_t *, size_t);
     46extern int tok_init(tokenizer_t *, char *, char **, size_t);
    6647extern void tok_fini(tokenizer_t *);
    67 extern int tok_tokenize(tokenizer_t *, size_t *);
     48extern int tok_tokenize(tokenizer_t *);
    6849
    6950#endif
  • uspace/lib/c/arch/ia32/Makefile.common

    r5fb32c5 r921b84f  
    2828
    2929CLANG_ARCH = i386
    30 
    3130ifeq ($(PROCESSOR),i486)
    32         GCC_CFLAGS += -march=i486 -fno-omit-frame-pointer
     31GCC_CFLAGS += -march=i486 -fno-omit-frame-pointer
    3332else
    34         GCC_CFLAGS += -march=pentium -fno-omit-frame-pointer
     33GCC_CFLAGS += -march=pentium -fno-omit-frame-pointer
    3534endif
    3635
  • uspace/lib/c/arch/ia32/src/entry.S

    r5fb32c5 r921b84f  
    4646        mov %ax, %fs
    4747        # Do not set %gs, it contains descriptor that can see TLS
    48        
     48
    4949#ifndef PROCESSOR_i486 
    5050        # Detect the mechanism used for making syscalls
     
    5353        bt $(INTEL_SEP), %edx
    5454        jnc 0f
    55                 leal __syscall_fast_func, %eax
    56                 movl $__syscall_fast, (%eax)
    57         0:
     55        leal __syscall_fast_func, %eax
     56        movl $__syscall_fast, (%eax)
     570:
    5858#endif
    59        
    6059        #
    6160        # Create the first stack frame.
  • uspace/lib/c/generic/async.c

    r5fb32c5 r921b84f  
    9898#include <ipc/ipc.h>
    9999#include <async.h>
    100 #include "private/async.h"
    101100#undef LIBC_ASYNC_C_
    102101
     
    114113#include <stdlib.h>
    115114#include <macros.h>
     115#include "private/async.h"
    116116
    117117#define CLIENT_HASH_TABLE_BUCKETS  32
     
    996996        session_ns->arg3 = 0;
    997997       
    998         fibril_mutex_initialize(&session_ns->remote_state_mtx);
    999         session_ns->remote_state_data = NULL;
    1000        
    1001998        list_initialize(&session_ns->exch_list);
    1002999        fibril_mutex_initialize(&session_ns->mutex);
     
    14751472                return ENOENT;
    14761473       
     1474        task_id_t task_id;
     1475        sysarg_t task_id_lo;
     1476        sysarg_t task_id_hi;
    14771477        sysarg_t phone_hash;
    1478         sysarg_t rc;
    1479 
    1480         aid_t req;
    1481         ipc_call_t answer;
    1482         req = async_send_3(exch, IPC_M_CONNECT_TO_ME, arg1, arg2, arg3,
    1483             &answer);
    1484         async_wait_for(req, &rc);
     1478        int rc = async_req_3_5(exch, IPC_M_CONNECT_TO_ME, arg1, arg2, arg3,
     1479            NULL, NULL, &task_id_lo, &task_id_hi, &phone_hash);
    14851480        if (rc != EOK)
    1486                 return (int) rc;
    1487 
    1488         phone_hash = IPC_GET_ARG5(answer);
    1489 
     1481                return rc;
     1482
     1483        task_id = (task_id_t) MERGE_LOUP32(task_id_lo, task_id_hi);
     1484       
    14901485        if (client_receiver != NULL)
    1491                 async_new_connection(answer.in_task_id, phone_hash, 0, NULL,
     1486                async_new_connection(task_id, phone_hash, 0, NULL,
    14921487                    client_receiver, carg);
    14931488       
     
    15641559        sess->arg3 = 0;
    15651560       
    1566         fibril_mutex_initialize(&sess->remote_state_mtx);
    1567         sess->remote_state_data = NULL;
    1568        
    15691561        list_initialize(&sess->exch_list);
    15701562        fibril_mutex_initialize(&sess->mutex);
     
    16481640        sess->arg3 = arg3;
    16491641       
    1650         fibril_mutex_initialize(&sess->remote_state_mtx);
    1651         sess->remote_state_data = NULL;
    1652        
    16531642        list_initialize(&sess->exch_list);
    16541643        fibril_mutex_initialize(&sess->mutex);
     
    17011690        sess->arg3 = arg3;
    17021691       
    1703         fibril_mutex_initialize(&sess->remote_state_mtx);
    1704         sess->remote_state_data = NULL;
    1705        
    17061692        list_initialize(&sess->exch_list);
    17071693        fibril_mutex_initialize(&sess->mutex);
     
    17341720        sess->arg2 = 0;
    17351721        sess->arg3 = 0;
    1736        
    1737         fibril_mutex_initialize(&sess->remote_state_mtx);
    1738         sess->remote_state_data = NULL;
    17391722       
    17401723        list_initialize(&sess->exch_list);
     
    24012384        sess->arg3 = 0;
    24022385       
    2403         fibril_mutex_initialize(&sess->remote_state_mtx);
    2404         sess->remote_state_data = NULL;
    2405        
    24062386        list_initialize(&sess->exch_list);
    24072387        fibril_mutex_initialize(&sess->mutex);
     
    24502430        sess->arg3 = 0;
    24512431       
    2452         fibril_mutex_initialize(&sess->remote_state_mtx);
    2453         sess->remote_state_data = NULL;
    2454        
    24552432        list_initialize(&sess->exch_list);
    24562433        fibril_mutex_initialize(&sess->mutex);
     
    24942471        sess->arg2 = 0;
    24952472        sess->arg3 = 0;
    2496        
    2497         fibril_mutex_initialize(&sess->remote_state_mtx);
    2498         sess->remote_state_data = NULL;
    24992473       
    25002474        list_initialize(&sess->exch_list);
     
    25382512}
    25392513
    2540 /** Lock and get session remote state
    2541  *
    2542  * Lock and get the local replica of the remote state
    2543  * in stateful sessions. The call should be paired
    2544  * with async_remote_state_release*().
    2545  *
    2546  * @param[in] sess Stateful session.
    2547  *
    2548  * @return Local replica of the remote state.
    2549  *
    2550  */
    2551 void *async_remote_state_acquire(async_sess_t *sess)
    2552 {
    2553         fibril_mutex_lock(&sess->remote_state_mtx);
    2554         return sess->remote_state_data;
    2555 }
    2556 
    2557 /** Update the session remote state
    2558  *
    2559  * Update the local replica of the remote state
    2560  * in stateful sessions. The remote state must
    2561  * be already locked.
    2562  *
    2563  * @param[in] sess  Stateful session.
    2564  * @param[in] state New local replica of the remote state.
    2565  *
    2566  */
    2567 void async_remote_state_update(async_sess_t *sess, void *state)
    2568 {
    2569         assert(fibril_mutex_is_locked(&sess->remote_state_mtx));
    2570         sess->remote_state_data = state;
    2571 }
    2572 
    2573 /** Release the session remote state
    2574  *
    2575  * Unlock the local replica of the remote state
    2576  * in stateful sessions.
    2577  *
    2578  * @param[in] sess Stateful session.
    2579  *
    2580  */
    2581 void async_remote_state_release(async_sess_t *sess)
    2582 {
    2583         assert(fibril_mutex_is_locked(&sess->remote_state_mtx));
    2584        
    2585         fibril_mutex_unlock(&sess->remote_state_mtx);
    2586 }
    2587 
    2588 /** Release the session remote state and end an exchange
    2589  *
    2590  * Unlock the local replica of the remote state
    2591  * in stateful sessions. This is convenience function
    2592  * which gets the session pointer from the exchange
    2593  * and also ends the exchange.
    2594  *
    2595  * @param[in] exch Stateful session's exchange.
    2596  *
    2597  */
    2598 void async_remote_state_release_exchange(async_exch_t *exch)
    2599 {
    2600         if (exch == NULL)
    2601                 return;
    2602        
    2603         async_sess_t *sess = exch->sess;
    2604         assert(fibril_mutex_is_locked(&sess->remote_state_mtx));
    2605        
    2606         async_exchange_end(exch);
    2607         fibril_mutex_unlock(&sess->remote_state_mtx);
    2608 }
    2609 
    26102514/** @}
    26112515 */
  • uspace/lib/c/generic/async_obsolete.c

    r5fb32c5 r921b84f  
    3838#include <async.h>
    3939#include <async_obsolete.h>
    40 #include "private/async.h"
    4140#undef LIBC_ASYNC_C_
    4241#undef LIBC_ASYNC_OBSOLETE_C_
     
    4544#include <malloc.h>
    4645#include <errno.h>
     46#include "private/async.h"
    4747
    4848/** Send message and return id of the sent message.
  • uspace/lib/c/generic/ipc.c

    r5fb32c5 r921b84f  
    4747#include <futex.h>
    4848#include <fibril.h>
    49 #include <macros.h>
    5049
    5150/**
     
    612611/** Request callback connection.
    613612 *
    614  * The @a task_id and @a phonehash identifiers returned
     613 * The @a taskhash and @a phonehash identifiers returned
    615614 * by the kernel can be used for connection tracking.
    616615 *
     
    619618 * @param arg2      User defined argument.
    620619 * @param arg3      User defined argument.
    621  * @param task_id   Identifier of the client task.
     620 * @param taskhash  Opaque identifier of the client task.
    622621 * @param phonehash Opaque identifier of the phone that will
    623622 *                  be used for incoming calls.
     
    627626 */
    628627int ipc_connect_to_me(int phoneid, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3,
    629     task_id_t *task_id, sysarg_t *phonehash)
    630 {
    631         ipc_call_t data;
    632         int rc = __SYSCALL6(SYS_IPC_CALL_SYNC_FAST, phoneid,
    633             IPC_M_CONNECT_TO_ME, arg1, arg2, arg3, (sysarg_t) &data);
    634         if (rc == EOK) {
    635                 *task_id = data.in_task_id;
    636                 *phonehash = IPC_GET_ARG5(data);
    637         }       
    638         return rc;
     628    sysarg_t *taskhash, sysarg_t *phonehash)
     629{
     630        return ipc_call_sync_3_5(phoneid, IPC_M_CONNECT_TO_ME, arg1, arg2,
     631            arg3, NULL, NULL, NULL, taskhash, phonehash);
    639632}
    640633
  • uspace/lib/c/generic/private/async.h

    r5fb32c5 r921b84f  
    3636#define LIBC_PRIVATE_ASYNC_H_
    3737
    38 #include <async.h>
     38#include <ipc/common.h>
    3939#include <adt/list.h>
    4040#include <fibril.h>
    41 #include <fibril_synch.h>
    4241#include <sys/time.h>
    4342#include <bool.h>
    44 
    45 /** Session data */
    46 struct _async_sess {
    47         /** List of inactive exchanges */
    48         list_t exch_list;
    49        
    50         /** Exchange management style */
    51         exch_mgmt_t mgmt;
    52        
    53         /** Session identification */
    54         int phone;
    55        
    56         /** First clone connection argument */
    57         sysarg_t arg1;
    58        
    59         /** Second clone connection argument */
    60         sysarg_t arg2;
    61        
    62         /** Third clone connection argument */
    63         sysarg_t arg3;
    64        
    65         /** Exchange mutex */
    66         fibril_mutex_t mutex;
    67        
    68         /** Number of opened exchanges */
    69         atomic_t refcnt;
    70        
    71         /** Mutex for stateful connections */
    72         fibril_mutex_t remote_state_mtx;
    73        
    74         /** Data for stateful connections */
    75         void *remote_state_data;
    76 };
    77 
    78 /** Exchange data */
    79 struct _async_exch {
    80         /** Link into list of inactive exchanges */
    81         link_t sess_link;
    82        
    83         /** Link into global list of inactive exchanges */
    84         link_t global_link;
    85        
    86         /** Session pointer */
    87         async_sess_t *sess;
    88        
    89         /** Exchange identification */
    90         int phone;
    91 };
    9243
    9344/** Structures of this type are used to track the timeout events. */
  • uspace/lib/c/include/async.h

    r5fb32c5 r921b84f  
    4242#include <ipc/common.h>
    4343#include <fibril.h>
     44#include <fibril_synch.h>
    4445#include <sys/time.h>
    4546#include <atomic.h>
     
    9596} exch_mgmt_t;
    9697
    97 /** Forward declarations */
    98 struct _async_exch;
    99 struct _async_sess;
    100 
    101 typedef struct _async_sess async_sess_t;
    102 typedef struct _async_exch async_exch_t;
     98/** Session data */
     99typedef struct {
     100        /** List of inactive exchanges */
     101        list_t exch_list;
     102       
     103        /** Exchange management style */
     104        exch_mgmt_t mgmt;
     105       
     106        /** Session identification */
     107        int phone;
     108       
     109        /** First clone connection argument */
     110        sysarg_t arg1;
     111       
     112        /** Second clone connection argument */
     113        sysarg_t arg2;
     114       
     115        /** Third clone connection argument */
     116        sysarg_t arg3;
     117       
     118        /** Exchange mutex */
     119        fibril_mutex_t mutex;
     120       
     121        /** Number of opened exchanges */
     122        atomic_t refcnt;
     123} async_sess_t;
     124
     125/** Exchange data */
     126typedef struct {
     127        /** Link into list of inactive exchanges */
     128        link_t sess_link;
     129       
     130        /** Link into global list of inactive exchanges */
     131        link_t global_link;
     132       
     133        /** Session pointer */
     134        async_sess_t *sess;
     135       
     136        /** Exchange identification */
     137        int phone;
     138} async_exch_t;
    103139
    104140extern atomic_t threads_in_ipc_wait;
     
    449485extern int async_state_change_finalize(ipc_callid_t, async_exch_t *);
    450486
    451 extern void *async_remote_state_acquire(async_sess_t *);
    452 extern void async_remote_state_update(async_sess_t *, void *);
    453 extern void async_remote_state_release(async_sess_t *);
    454 extern void async_remote_state_release_exchange(async_exch_t *);
    455 
    456487#endif
    457488
  • uspace/lib/c/include/ipc/ipc.h

    r5fb32c5 r921b84f  
    254254    sysarg_t, sysarg_t, void *, ipc_async_callback_t, bool);
    255255
    256 extern int ipc_connect_to_me(int, sysarg_t, sysarg_t, sysarg_t, task_id_t *,
     256extern int ipc_connect_to_me(int, sysarg_t, sysarg_t, sysarg_t, sysarg_t *,
    257257    sysarg_t *);
    258258extern int ipc_connect_me(int);
  • uspace/lib/clui/tinput.c

    r5fb32c5 r921b84f  
    591591}
    592592
    593 /* Print a list of completions */
    594 static void tinput_show_completions(tinput_t *ti, char **compl, size_t cnum)
    595 {
    596         unsigned int i;
    597         /* Determine the maximum length of the completion in chars */
    598         size_t max_length = 0;
    599         for (i = 0; i < cnum; i++)
    600                 max_length = max(max_length, str_length(compl[i]));
    601        
    602         unsigned int cols = max(1, (ti->con_cols + 1) / (max_length + 1));
    603         unsigned int col_width = ti->con_cols / cols;
    604         unsigned int rows = cnum / cols + ((cnum % cols) != 0);
    605        
    606         unsigned int row, col;
    607        
    608         for (row = 0; row < rows; row++) {
    609                 bool wlc = false;
    610                 for (col = 0; col < cols; col++) {
    611                         size_t compl_idx = col * rows + row;
    612                         if (compl_idx >= cnum)
    613                                 break;
    614                         if (col)
    615                                 printf(" ");
    616                         printf("%s", compl[compl_idx]);
    617                         size_t compl_len = str_length(compl[compl_idx]);
    618                         if (col == cols -1) {
    619                                 wlc = (compl_len == max_length);
    620                         }
    621                         else {
    622                                 for (i = compl_len; i < col_width; i++) {
    623                                         printf(" ");
    624                                 }
    625                         }
    626                 }
    627                 if (!wlc) printf("\n");
    628         }
    629 }
    630 
    631 
    632593static void tinput_text_complete(tinput_t *ti)
    633594{
     
    715676
    716677                        tinput_jump_after(ti);
    717                         tinput_show_completions(ti, compl, cnum);
     678                        for (i = 0; i < cnum; i++)
     679                                printf("%s\n", compl[i]);
    718680                        tinput_display(ti);
    719681                }
Note: See TracChangeset for help on using the changeset viewer.