From: Stephen Powell on 15 Apr 2010 15:00 On Wed, 14 Apr 2010 23:10:55 -0400 (EDT), Boyd Stephen Smith Jr. wrote: > On Tuesday 13 April 2010 17:16:03 Stephen Powell wrote: >> What I need to do is to have two structures overlay each other; so that >> they occupy the same storage. To be specific, here is a structure which >> describes the volume label for an OS-formatted disk: >> >> struct __attribute__ ((packed)) volume_label { >> char volkey[4]; /* volume key = volume label */ >> ... >> }; >> >> And here is a structure which describes the volume label for a >> CMS-formatted disk: >> >> struct __attribute__ ((packed)) cms_label { >> char label_id[4]; /* Label identifier */ >> ... >> }; >> > > union any_label { > struct volume_label vl; > struct cms_label cl; > }; >> >> Note that both structures have as their first member a character variable >> of length 4. In the case of the "volume_label" structure it is "volkey" >> and in the case of the "cms_label" structure it is "label_id". If the >> value of this variable is "VOL1" (in EBCDIC) then it is the first structure >> which maps the storage. If the value of this variable is "CMS1" (in >> EBCDIC) then it is the second structure which maps the storage. The >> volume_label structure is apparently a based structure, as references to >> the volkey variable look something like this: > > union any_label *label = /* Initialize somehow */; > struct volume_label *maybe_vl = &label->vl; > struct cms_label *maybe_cl = &label->cl; > > if (strncmp(maybe_vl->volkey, "VOL1", 4) == 0) { > maybe_cl = NULL; > /* Use maybe_vl all you want, e.g. */ > maybe_vl->security = 0xFF; > } else if (strncmp(maybe_cl->label_id, "CMS1", 4) == 0) { > maybe_vl = NULL; > /* Use maybe_cl all you want, e.g. */ > printf("%lu\n", (unsigned long) maybe_cl->disk_offset); > } else { > assert(("Unrecognized disk!", 0)); > } > > Hope that helps. Thanks, Boyd. Your response comes the closest so far to what I'm looking for. Based on what I know from other programming languages, I don't think it's going to be necessary to explicitly declare a union. They will overlap each other implicitly because their pointers are the same. Both structure mappings occupy exactly 80 bytes of storage. And the storage for one of them is already allocated somehow. What I need to do is associate a pointer with the new structure and assign a value to the pointer that matches the pointer for the other structure. That will implicitly cause the two structures to overlap in storage. Here are examples from two other languages that I do know: s390 assembler language and PL/I. Here is the assembler example: ---------- ... CLC LABELIDA,=C'VOL1' Is this structure type A? BE VOL1CODE Yes - branch to label VOL1CODE LA 3,STRUCTA No - load the address of STRUCTA into register 3 USING STRUCTB,3 Tell the assembler that the address of STRUCTB is in register 3 L 4,FIELDB2 Load the fullword at FIELDB2 into register 4 ... Perform additional processing DROP 3 Tell the assembler that it can no longer assume that register 3 points to STRUCTB B COMCODE Rejoin common code VOL1CODE DS 0H ... Proceed with processing for structure type A COMCODE DS 0H ... STRUCTA DS 0CL12 LABELIDA DS CL4 FIELDA1 DS CL8 ... STRUCTB DSECT , Start a dummy control section (based structure) LABELIDB DS CL4 FIELDB1 DS F FIELDB2 DS F ... ---------- Here is the PL/I example: ---------- DCL 1 STRUCTA, 2 LABELIDA CHAR (4), 2 FIELDA1 CHAR (8); DCL ADDR BUILTIN; DCL B_PTR POINTER; DCL 1 STRUCTB BASED (B_PTR), 2 LABELIDB CHAR (4), 2 FIELDB1 FIXED BINARY (31,0), 2 FIELDB2 FIXED BINARY (31,0); ... IF LABELIDA = 'VOL1' THEN DO; /* Processing that refers to elements of STRUCTA */ END; ELSE DO; B_PTR = ADDR(STRUCTA); /* Processing that refers to elements of STRUCTB */ END; ---------- Now back to C. At the point in the code where I need to make a reference to the "disk_offset" member of the "cms_label" structure, I know that I can validly reference the "volkey" variable of the "volume_label" structure like this: disk_specific->anchor->vlabel->volkey What I need to do is declare that "cms_label" is a based structure and associate a pointer variable, say "cms_ptr", with it. But I don't want any storage to be allocated for the structure: only for the pointer. Storage should be allocated for the pointer, but it should not be initialized to anything. Then I can assign a value to the pointer, with something like: cms_ptr = disk_specific->anchor->vlabel; Then I can make references to members of the cms_label structure implicitly using the cms_ptr pointer variable. No storage is ever allocated to the "cms_label" structure. It overlays the "volume_label" structure implicitly via the assignment of a value to its associated pointer variable. I know how to do something like this in s390 assembler language and PL/I. Surely there must be a way to do this in C, right? In short, I need to (a) declare "cms_label" as a based structure, (b) declare a pointer variable called "cms_ptr" and associate it with the "cms_label" structure, (c) make sure that the compiler does not attempt to allocate any storage for the "cms_label" structure, (d) make sure that the compiler automatically acquires storage for the "cms_ptr" pointer variable itself, (e) assign the address of the "volume_label" structure to the "cms_ptr" pointer variable at an appropriate point in the code, and (f) make references to the members of the cms_label structure. How do I do this? (Man, I wish I knew C!) -- .''`. Stephen Powell : :' : `. `'` `- -- To UNSUBSCRIBE, email to debian-user-REQUEST(a)lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmaster(a)lists.debian.org Archive: http://lists.debian.org/749326468.47646.1271357760265.JavaMail.root(a)md01.wow.synacor.com
From: Boyd Stephen Smith Jr. on 15 Apr 2010 17:40 On Thursday 15 April 2010 13:56:00 Stephen Powell wrote: > On Wed, 14 Apr 2010 23:10:55 -0400 (EDT), Boyd Stephen Smith Jr. wrote: > > On Tuesday 13 April 2010 17:16:03 Stephen Powell wrote: > >> What I need to do is to have two structures overlay each other; so that > >> they occupy the same storage. To be specific, here is a structure > >> which describes the volume label for an OS-formatted disk: > >> > >> struct __attribute__ ((packed)) volume_label { > >> char volkey[4]; /* volume key = volume label */ > >> ... > >> }; > >> > >> And here is a structure which describes the volume label for a > >> CMS-formatted disk: > >> > >> struct __attribute__ ((packed)) cms_label { > >> char label_id[4]; /* Label identifier */ > >> ... > >> }; > > > > union any_label { > > struct volume_label vl; > > struct cms_label cl; > > }; > > > >> Note that both structures have as their first member a character > >> variable of length 4. In the case of the "volume_label" structure it is > >> "volkey" and in the case of the "cms_label" structure it is "label_id". > >> If the value of this variable is "VOL1" (in EBCDIC) then it is the first > >> structure which maps the storage. If the value of this variable is > >> "CMS1" (in EBCDIC) then it is the second structure which maps the > >> storage. > > > > union any_label *label = /* Initialize somehow */; > > struct volume_label *maybe_vl = &label->vl; > > struct cms_label *maybe_cl = &label->cl; > > > > if (strncmp(maybe_vl->volkey, "VOL1", 4) == 0) { > > maybe_cl = NULL; > > /* Use maybe_vl all you want, e.g. */ > > maybe_vl->security = 0xFF; > > } else if (strncmp(maybe_cl->label_id, "CMS1", 4) == 0) { > > maybe_vl = NULL; > > /* Use maybe_cl all you want, e.g. */ > > printf("%lu\n", (unsigned long) maybe_cl->disk_offset); > > } else { > > assert(("Unrecognized disk!", 0)); > > } > > Thanks, Boyd. Your response comes the closest so far to what I'm looking > for. Based on what I know from other programming languages, I don't think > it's going to be necessary to explicitly declare a union. It's possible, but I would generally do it for clarity. I like using the types of variables/arguments as documentation, so I would store any data where the real type was unknown in the union. Then access it though a "struct cms_label *" or "struct volume_label *" one I had determined the correct type. Since C unions are not tagged, a C union is the same size as it's largest member. (NB: Not really sure how __attribute__((__packed__)) changes things, if at all; it's possible you need it on the union to prevent padding from being added after the space occupied by the largest member.) > In short, I need to (a) declare "cms_label" as a based structure, (above; timmmed) > (b) > declare a pointer variable called "cms_ptr" and associate it with the > "cms_label" structure, struct cms_label *cms_ptr; Initialization optional, but recommended. > (c) make sure that the compiler does not attempt > to allocate any storage for the "cms_label" structure, Since you are declaring a pointer to a structure, and not declaring an object with type "struct cms_label", no space will be allocated for a cms_label. > (d) make sure that > the compiler automatically acquires storage for the "cms_ptr" pointer > variable itself, Make your declaration a definition and that'll be handled. (Declarations and definitions look very similar for non-function types; the code given above is actually a definition if it is not within a struct/union type.) > (e) assign the address of the "volume_label" structure > to the "cms_ptr" pointer variable at an appropriate point in the code, > and struct volume_label vl; struct cms_label *cms_ptr; /* Load data into vl */ /* Determine that the data is actually a cms_label */ cms_ptr = (void *) &vl; Or, in your specific case, you should be able to do something like: struct cms_label *cms_ptr = (void *) disk_specific->anchor->vlabel; Since you are already dealing with a "struct volume_label *", there's no need for the address-of operator (&). > (f) make references to the members of the cms_label structure. cms_ptr->label_id; /* Or any other member. */ > How do I do this? (Man, I wish I knew C!) Examples above good? Please let me know if I can provide further assistance. -- Boyd Stephen Smith Jr. ,= ,-_-. =. bss(a)iguanasuicide.net ((_/)o o(\_)) ICQ: 514984 YM/AIM: DaTwinkDaddy `-'(. .)`-' http://iguanasuicide.net/ \_/
From: Stephen Powell on 15 Apr 2010 20:40 On Thu, 15 Apr 2010 17:39:42 -0400 (EDT), Boyd Stephen Smith Jr. wrote: > Stephen Powell wrote: >> In short, I need to >> (a) declare "cms_label" as a based structure, > > (above; trimmmed) >> >> (b) >> declare a pointer variable called "cms_ptr" and associate it with the >> "cms_label" structure, > > struct cms_label *cms_ptr; > > Initialization optional, but recommended. >> >> (c) >> make sure that the compiler does not attempt >> to allocate any storage for the "cms_label" structure, > > Since you are declaring a pointer to a structure, and not declaring an object > with type "struct cms_label", no space will be allocated for a cms_label. >> >> (d) >> make sure that the compiler automatically acquires storage for the >> "cms_ptr" pointer variable itself, > > Make your declaration a definition and that'll be handled. (Declarations and > definitions look very similar for non-function types; the code given above is > actually a definition if it is not within a struct/union type.) >> >> (e) >> assign the address of the "volume_label" structure >> to the "cms_ptr" pointer variable at an appropriate point in the code, >> and > > struct volume_label vl; > struct cms_label *cms_ptr; > > /* Load data into vl */ > /* Determine that the data is actually a cms_label */ > cms_ptr = (void *) &vl; > > Or, in your specific case, you should be able to do something like: > > struct cms_label *cms_ptr = (void *) disk_specific->anchor->vlabel; > > Since you are already dealing with a "struct volume_label *", there's no need > for the address-of operator (&). >> >> (f) >> make references to the members of the cms_label structure. > > cms_ptr->label_id; /* Or any other member. */ >> >> How do I do this? (Man, I wish I knew C!) > > Examples above good? Please let me know if I can provide further assistance. Yahoo! It works! Thanks a bunch, Boyd. I'm going to be filing a bug report against parted for (a) miscalculating the starting block of the implicit partition on an ldl (Linux Disk Layout) formatted disk on the s390 architecture when the block size is other than 4096, and (b) no support for CMS-formatted disks. I'm going to include my patch files for the fix in the bug report. Would you like to be in the credits? Or would you prefer to remain anonymous? -- .''`. Stephen Powell : :' : `. `'` `- -- To UNSUBSCRIBE, email to debian-user-REQUEST(a)lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmaster(a)lists.debian.org Archive: http://lists.debian.org/1876691691.55741.1271378240260.JavaMail.root(a)md01.wow.synacor.com
From: Ron Johnson on 15 Apr 2010 20:50 On 2010-04-15 19:37, Stephen Powell wrote: [snip] > > I'm going to be filing a bug report against parted for (a) miscalculating the starting > block of the implicit partition on an ldl (Linux Disk Layout) formatted disk on the > s390 architecture when the block size is other than 4096, and (b) no support for > CMS-formatted disks. If practical, I hope you file 2 bugs. -- Dissent is patriotic, remember? -- To UNSUBSCRIBE, email to debian-user-REQUEST(a)lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmaster(a)lists.debian.org Archive: http://lists.debian.org/4BC7B2A9.3070904(a)cox.net
From: Stephen Powell on 15 Apr 2010 21:20 On Thu, 15 Apr 2010 20:43:21 -0400 (EDT), Ron Johnson wrote: > On 2010-04-15 19:37, Stephen Powell wrote: >> >> I'm going to be filing a bug report against parted for (a) miscalculating >> the starting block of the implicit partition on an ldl (Linux Disk Layout) >> formatted disk on the s390 architecture when the block size is other than >> 4096, and (b) no support for CMS-formatted disks. > > If practical, I hope you file 2 bugs. I hear you. I'll have to look at the code to see if that's easily separated out. I started with the purpose of adding an enhancement to support CMS formatted disks. I stumbled across the bug in the starting block calculation for ldl formatted disks in the process. CMS formatted disks are handled *exactly* the same as ldl formatted disks if the disk is not reserved. I would have had to fix that bug anyway to add support for CMS disks, since I wanted the CMS support to be correct. The only wrinkle was correctly handling reserved CMS disks. To do that I had to access the reserved block offset in the CMS label, which prompted this thread. All of this is specific to the s390 architecture and has no bearing on i386, amd64, ia64, etc. I hope upstream (GNU, I believe) will accept the fix. I have no reason to believe that they won't. -- .''`. Stephen Powell : :' : `. `'` `- -- To UNSUBSCRIBE, email to debian-user-REQUEST(a)lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmaster(a)lists.debian.org Archive: http://lists.debian.org/65674052.56609.1271380183436.JavaMail.root(a)md01.wow.synacor.com
First
|
Prev
|
Next
|
Last
Pages: 1 2 3 4 Prev: recent mobo recommendation Next: Does bcm4310 work with Debian Lenny? |