Re: Good Use of GOTO

new topic     » goto parent     » topic index » view thread      » older message » newer message

c.k.lester wrote:
> 
> After hearing from both sides, I've come to the conclusion that the goto
> being implemented is unnecessary. We are getting loop constructs that
> handle most of what GOTO would be used for, aren't we?
> 
>    continue, exit, retry, etc...
> 
> These all lend themselves to maintenance, program flow, structure, while a
> GOTO does not.
> 
> Can somebody show me a case (with sample code) where a GOTO would be
> significantly better than using another construct? Also, please explain
> why Euphoria would need GOTO if we add PCRE to the interpreter.

How would you implement/rewrite the following functions (from Linux kernel
2.6.11 source) ? Even if you had the full repretiore of eu 4.0 keywords? (which,
admittedly, the author of this code did not have)

static struct dentry *vfat_lookup(struct inode *dir, struct dentry *dentry,
                                  struct nameidata *nd)
{       
        int res;
        struct vfat_slot_info sinfo;
        struct inode *inode;
        struct dentry *alias;
        struct buffer_head *bh = NULL
        struct msdos_dir_entry *de;
        int table;

        lock_kernel();
        table = (MSDOS_SB(dir->i_sb)->options.name_check == 's') ? 2 : 0;
        dentry->d_op = &vfat_dentry_ops[table];

        inode = NULL;
        res = vfat_find(dir, &dentry->d_name, &sinfo, &bh, &de);
        if (res < 0) {
                table++;
                goto error;
        }
        inode = fat_build_inode(dir->i_sb, de, sinfo.i_pos, &res);
        brelse(bh);        if (res) {
                unlock_kernel();
                return ERR_PTR(res);
        }
        alias = d_find_alias(inode);
        if (alias) {
                if (d_invalidate(alias) == 0)
                        dput(alias);
                else {  
                        iput(inode);
                        unlock_kernel();
                        return alias;
                }
        
        }
error:  
        unlock_kernel();
        dentry->d_op = &vfat_dentry_ops[table];
        dentry->d_time = dentry->d_parent->d_inode->i_version;
        dentry = d_splice_alias(inode, dentry);               
        if (dentry) {                                         
                dentry->d_op = &vfat_dentry_ops[table];
                dentry->d_time = dentry->d_parent->d_inode->i_version;
        }
        return dentry;
}

static int vfat_create(struct inode *dir, struct dentry *dentry, int mode,
                       struct nameidata *nd)
{
        struct super_block *sb = dir->i_sb;
        struct inode *inode = NULL;
        struct buffer_head *bh = NULL;
        struct msdos_dir_entry *de;
        struct vfat_slot_info sinfo;
        int res;

        lock_kernel();
        res = vfat_add_entry(dir, &dentry->d_name, 0, &sinfo, &bh, &de);
        if (res < 0)
                goto out;
        inode = fat_build_inode(sb, de, sinfo.i_pos, &res);
        brelse(bh);
        if (!inode)
                goto out;
        res = 0;
        inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
        mark_inode_dirty(inode);
        inode->i_version++;
        dir->i_version++;
        dentry->d_time = dentry->d_parent->d_inode->i_version;
        d_instantiate(dentry, inode);
out:
        unlock_kernel();
        return res;
}

static int vfat_build_slots(struct inode *dir, const unsigned char *name,
                            int len, struct msdos_dir_slot *ds,
                            int *slots, int is_dir)
{       
        struct msdos_sb_info *sbi = MSDOS_SB(dir->i_sb);
        struct fat_mount_options *opts = &sbi->options;
        struct msdos_dir_slot *ps;
        struct msdos_dir_entry *de;
        unsigned long page;
        unsigned char cksum, lcase;
        unsigned char msdos_name[MSDOS_NAME];
        wchar_t *uname;
        int res, slot, ulen, usize, i;
        loff_t offset;

        *slots = 0;
        res = vfat_valid_longname(name, len);
        if (res)
                return res;

        page = __get_free_page(GFP_KERNEL);
        if (!page)
                return -ENOMEM;                               

        uname = (wchar_t *)page;
        res = xlate_to_uni(name, len, (unsigned char *)uname, &ulen, &usize,
                           opts->unicode_xlate, opts->utf8, sbi->nls_io);
        if (res < 0)
                goto out_free;
        
        res = vfat_is_used_badchars(uname, ulen);
        if (res < 0) 
                goto out_free;
        
        res = vfat_create_shortname(dir, sbi->nls_disk, uname, ulen,
                                    msdos_name, &lcase);
        if (res < 0) 
                goto out_free;
        else if (res == 1) { 
                de = (struct msdos_dir_entry *)ds;
                res = 0;
                goto shortname;                               
        }                                                     

        /* build the entry of long file name */
        *slots = usize / 13;
        for (cksum = i = 0; i < 11; i++)
                cksum = (((cksum&1)<<7)|((cksum&0xfe)>>1)) + msdos_name[i];
        
        for (ps = ds, slot = *slots; slot > 0; slot--, ps++) {
                ps->id = slot;
                ps->attr = ATTR_EXT;
                ps->reserved = 0;
                ps->alias_checksum = cksum;
                ps->start = 0; 
                offset = (slot - 1) * 13;
                fatwchar_to16(ps->name0_4, uname + offset, 5);
                fatwchar_to16(ps->name5_10, uname + offset + 5, 6);
                fatwchar_to16(ps->name11_12, uname + offset + 11, 2);
        }
        ds[0].id |= 0x40;
        de = (struct msdos_dir_entry *)ps;

shortname: 
        /* build the entry of 8.3 alias name */
        (*slots)++;
        memcpy(de->name, msdos_name, MSDOS_NAME);
        de->attr = is_dir ? ATTR_DIR : ATTR_ARCH;
        de->lcase = lcase;
        de->adate = de->cdate = de->date = 0;
        de->ctime = de->time = 0;
        de->ctime_ms = 0;
        de->start = 0;
        de->starthi = 0;
        de->size = 0;

out_free:
        free_page(page);
        return res;
}

new topic     » goto parent     » topic index » view thread      » older message » newer message

Search



Quick Links

User menu

Not signed in.

Misc Menu