Re: Good Use of GOTO
- Posted by Jim Brown <jbrown105 at linuxbuddhi?t.?et> Jun 05, 2008
- 867 views
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; }