text:
Welcome Welcome to www.cadenceatwoodmont.org. This site (the "Site") is owned by Cadence Neighborhood Association, Inc.. This Privacy Policy is designed to tell you about our practices regarding collection, use and disclosure of information that we may collect from and about you. Please be sure to read this entire Privacy Policy before using or submitting information to this Site. This Site is intended for use by residents of the United States.
Your Consent By using this Site, you agree with the terms of this Privacy Policy. Whenever you submit information via this Site, you consent to the collection, use and disclosure of that information in accordance with this Privacy Policy, the Terms of Service and any specific provisions of this Site that may be presented at the time information is collected. About Children The Site is a general audience site. We do not knowingly collect any personal information from children under the age of thirteen on the Site. If in the future, we collect personally identifiable information from children, we will do so in compliance with the Children's Online Privacy Protection Act of 1998 (15 U.S.C. 6501 et seq.). The Internet offers children wonderful educational and entertainment resources. Your guidance and involvement are essential to help ensure that children have a safe and rewarding online experience. We encourage you to visit the Direct Marketing Association's Web site (www.the-dma.org) and explore the Get CyberSavvy! Program as well as the GetNetWise Web site (www.getnetwise.org) to learn more about parental control tools. Active Information Collection Like many Web sites, this Site actively collects information from its visitors both by asking them specific questions and by permitting them to communicate directly with us via e-mail, feedback forms, chat rooms and so forth. Some of the information that you submit may be personally identifiable information (that is, information that can be uniquely identified with you, such as your full name, address, e-mail address, phone number and so on). Some areas of this Site may require you to submit information in order for you to benefit from the specified features (such as newsletter subscriptions, tips/pointers, order processing and so forth) or to participate in a particular activity (such as sweepstakes or other promotions and so forth). You will be informed at each information collection point what information is required and what information is optional. Passive Information Collection As you navigate through this Site and/or receive emails in connection with this Site, certain information may be passively collected (that is, gathered without your actively providing the information) using various technologies and means, including, without limitation, those described below: Cookies As with many Websites, the Site uses standard technology called "cookies," which are small data files that are transferred to your computer when you allow your browser to accept cookies. Cookies automatically identify your Web browser to the Site whenever you visit the Site, and make using the Site easier for you by saving your passwords, purchases, and preferences. By tracking how and when you use the Site, cookies help us determine which areas are popular and which are not. Many improvements and updates to the Site are based on data obtained from cookies. Accepting cookies allows you, among other things, to personalize your experience on the Site. Cookies may also allow the Site to present to you information which may be of interest to you. If you do not want information collected through the use of cookies, you generally can opt out of providing this information by turning the cookies off in your browser; however, some areas of the Site may not provide you with a personalized experience or access if you have disabled the use of cookies. IP Addresses and Automatic Information We may collect IP addresses and/or automatic information for purposes of system administration and to report aggregate information to our advertisers and sponsors. An IP address is a number that is automatically assigned to your computer whenever you access the Internet. Our computers identify your computer by its IP address. When you request Web pages from the Site, our computers log your IP address. Automatic information is information collected by our computers when you request Web pages from the Site. Automatic information may include such information as the page served, the time, the source of the request, the type of browser making the request, the preceding page view and other such information. When analyzed, this data helps us analyze how visitors arrive at the Site, what type of content is most popular, what type of visitors in the aggregate are interested in particular kinds of content and advertising, and the like.
Information From Other Sources From time to time we, and/or our operational partners may receive information about you from other sources and add it to the data previously collected about you. Use and Disclosure of Information Except as otherwise stated, Cadence Neighborhood Association, Inc. may use information you provide to improve the content of our Site, to customize the display of the Site to your preferences, to communicate information to you (if you have requested it), for our marketing and research purposes, and for the purposes specified in this Privacy Policy. If you provide personally identifiable information to this Site, we may combine such information with other actively collected information unless specified otherwise at the point of collection on this Site. We may combine personally identifiable information with passively collected information. Access and Correction To keep your personally identifiable information accurate, current and complete, please contact us as specified below. We will take reasonable steps to update or correct personally identifiable information in our possession that you have previously submitted via this Site. Security We will take reasonable steps to protect your personally identifiable information as you transmit your information from your computer to our Site and to protect such information from loss, misuse and unauthorized access, disclosure, alteration or destruction in accordance with this Privacy Policy and the Terms of Use. You should keep in mind that no Internet transmission is ever 100% secure or error-free. In particular, email sent to or from this Site may not be secure, and you should therefore take special care in deciding what information you send to us via e-mail. Moreover, where you use passwords, usernames, ID numbers or other special access features on this Site, it is your responsibility to safeguard them. Links to Other Web Sites You should be aware that when you are on the Site you could be directed to other sites beyond our control. For example, if you "click" on a banner advertisement, the "click" may take you off the Site onto a different Web site. This includes links from advertisers, sponsors and partners that may use the Site's logo as part of a co-branding agreement. These other Web sites may send their own cookies to you, independently collect data or solicit personal information and may or may not have their own published privacy policies. If you visit a Website that is linked to our Site, you should consult that site's privacy policy before providing any personal information. Other Terms Your use of this Site is subject to the Terms of Use. If you choose to use this Site, your visit and any dispute over privacy and data collection is subject to this Privacy Policy and our Terms of Use including limitations on damages and application of the law of the State of Georgia. How to Contact Us If you have any questions, comments or concerns about this Privacy Policy or the information practices of this Site, please contact us as follows: Cadence Neighborhood Association, Inc. c/o Heritage Property Management Services, Inc. 500 Sugarmill Rd #200B Atlanta, GA 30350 firstname.lastname@example.com Changes to This Privacy Policy If this Privacy Policy changes, the revised policy will be posted on this Site. Please check back periodically, and especially before you provide any personally identifiable information. This Privacy Policy was last updated on the date shown at the top of this page.


text:
Homes For Rent
Find the Perfect Home
We want to make your experience in finding your next dream home an enjoyable one! Find houses for rent by selecting from our list of rental homes, or by entering your search criteria below. Give us a call today and we will help you find the perfect rental property!

subset: commoncrawl


text:
- Swarovski style # 1028 Xilion Round Stones
- size equivalency: 16pp :7ss :2.2-2.3mm (25mm=1 inch)
- Amethyst is the February birthstone color and is a medium to dark reddish purple tone and blends nicely with Lilac and Light Amethyst
- This special order item from Austria usually ships in 9-14 days.
- Swarovski® Crystal Round Stones are loose crystals like a diamond, with a round profile and pointed back, making them easy to apply in metal claw settings or pre-set cavities to create gorgeous jewelry. Round Stones are available in a plethora of sizes, Colors and Effects to choose from and most stones have a thin foil on the back, providing you with exceptional quality jewelry. All Swarovski Round Stones are made with Advanced Crystal, an innovative, lead-free* formula.


text:
Cats rarely display their pain, but cats with feline stomatitis are often the exception. If your cat appears to have mouth pain, is reluctant to eat, doesn't want to groom, is drooling, and doesn't want you to open its mouth, it may be suffering from this debilitating, degenerative oral condition, and prompt treatment is a must.
Stomatitis refers to an inflammation of the oral mucosa, the mucous membranes that line a cat's mouth. This layer of cells can become inflamed for a variety of reasons. The more frequent causes of inflammation are gingivitis and periodontal disease. In the case of stomatitis, the exact cause isn't known, but it is suspected to be an immune-mediated disease. Depending on the extent of lesions, this condition is also called faucitis and caudal mucositis, if the areas in the back of the mouth behind the teeth are affected. Stomatitis affects all breeds of cats, and can occur in any age.
Treatment for oral inflammation depends on the severity of the disease. Milder cases can be treated by having a dental prophylaxis under anesthesia. Once the teeth are cleaned, you may be asked to apply a chlorhexidene gel to help keep the bacteria under control. Taking dental X-rays is important in all these cases as a degeneration of the tooth termed resorption, may occur in the crown or root of the tooth. This resorption can cause pain and inflammation.
More advanced cases of feline stomatitis generally call for extraction of all or a majority of the affected teeth. While this approach might sound extreme, it can also be highly effective at curing the stomatitis altogether, instead of merely keeping it in check. If extractions of the molars and pre-molars doesn't resolve the problem, further extractions of the canines and incisors very well might. Some cat owners decide to spare their cats a possible future surgery by having these teeth removed with the others. X-rays of the teeth during extraction are critical because any piece of a tooth is left behind, the inflammation will persist.
Your cat's stomatitis may also involve the bone surrounding the teeth, leading to a condition called osteomyelitis. This is a serious infection of the bone surrounding the teeth which is treated by removing the diseased bone and then allowing healthy tissue to regenerate in its place.
Deforge, D. H., VMD, "One Clinician's Experience With A New Treatment For Feline Stomatitis," Veterinary Practice News
Kirby, Naomi, DVM, MS, "Managing Feline Stomatitis," IVC Journal.
Lews, John, VMD, FAVD, DIPL. AVDC., "Why Teeth Removal is Best When Your Patient Has Feline Stomatitis," Veterinary Practice News.
Merck Veterinary Manuals, "Oral Inflammatory and Ulcerative Disease in Small Animals."


text:
Greeting.* 1Paul, an apostle of Christ Jesus by the will of God, to the holy ones who are [in Ephesus]* faithful in Christ Jesus:a 2grace to you and peace from God our Father and the Lord Jesus Christ.b
The Father's Plan of Salvation. 3* Blessed be the God and Father of our Lord Jesus Christ,c who has blessed us in Christ with every spiritual blessing in the heavens,* 4as he chose us in him, before the foundation of the world, to be holy and without blemish before him.d In love 5he destined us for adoption to himself through Jesus Christ, in accord with the favor of his will,e 6for the praise of the glory of his grace that he granted us in the beloved.f
Fulfillment through Christ. 7In him we have redemption by his blood, the forgiveness of transgressions, in accord with the riches of his graceg 8that he lavished upon us. In all wisdom and insight,h 9he has made known to us the mystery* of his will in accord with his favor that he set forth in himi 10as a plan for the fullness of times, to sum up all things in Christ, in heaven and on earth.j
Inheritance through the Spirit. 11In him we were also chosen, destined in accord with the purpose of the One who accomplishes all things according to the intention of his will,k 12so that we might exist for the praise of his glory, we who first hoped* in Christ. 13In him you also, who have heard the word of truth, the gospel of your salvation, and have believed in him, were sealed* with the promised holy Spirit,l 14which is the first installment* of our inheritance toward redemption as God's possession, to the praise of his glory.m
II. Unity of the Church in Christ
The Church as Christ's Body.* 15Therefore, I, too, hearing of your faith in the Lord Jesus and of your love* for all the holy ones,n 16do not cease giving thanks for you, remembering you in my prayers,o 17that the God of our Lord Jesus Christ, the Father of glory, may give you a spirit of wisdom and revelation resulting in knowledge of him.p 18May the eyes of [your] hearts be enlightened, that you may know what is the hope that belongs to his call, what are the riches of glory in his inheritance among the holy ones,q 19and what is the surpassing greatness of his power for us who believe, in accord with the exercise of his great might,r 20which he worked in Christ, raising him from the dead and seating him at his right hand in the heavens,s 21far above every principality, authority, power, and dominion, and every name that is named not only in this age but also in the one to come.t 22And he put all things beneath his feet and gave him as head over all things to the church,u 23which is his body,* the fullness of the one who fills all things in every way.v
* [1:1–2] For the epistolary form used at the beginning of letters, see note on Rom 1:1–7. Twenty-two of the thirty Greek words in Eph 1:1–2 also occur in Col 1:1–2.
* [1:1] [In Ephesus]: the phrase is lacking in important early witnesses such as P46 (3rd cent.), and Sinaiticus and Vaticanus (4th cent.), appearing in the latter two as a fifth-century addition. Basil and Origen mention its absence from manuscripts. See Introduction. Without the phrase, the Greek can be rendered, as in Col 1:2, "to the holy ones and faithful brothers in Christ."
* [1:3–14] While a Pauline letter usually continues after the greeting with a prayer of thanksgiving, as in Eph 1:15–23 below, Ephesians first inserts a blessing of God for the blessings Christians have experienced, as in 2 Cor 1:3–4 and 1 Pt 1:3–12. The blessing here, akin to a Jewish berakah, is rich in images almost certainly drawn from hymns and liturgy. Many ideas here are also found in Col 1:3–23. Certain phrases are frequently repeated, such as in Christ (Eph 1:3, 10, 12) or in him (Eph 1:4, 7, 9, 11, 13) or in the beloved (Eph 1:6) and (for) the praise of (his) glory (Eph 1:6, 12, 14). Some terms like chose (Eph 1:4) and destined (Eph 1:5) reflect Old Testament theology (Dt 7:7; 9:4–6; 23:5) or Pauline themes (redemption, Eph 1:7, 14; grace, Eph 1:6, 7) or specific emphases in Colossians (forgiveness, Col 1:14). A triadic structure is discernible in Eph 1:3–14: God the Father (Eph 1:3–6, 8, 11), Christ (Eph 1:3, 5, 7–10, 12), and the Spirit (Eph 1:13–14). The spiritual blessings Christians have received through Christ (Eph 1:3) are gratefully enumerated: the call to holiness (Eph 1:4; cf. Col 1:22); the gift of divine adoption establishing a unique spiritual relationship with God the Father through Christ (Eph 1:5; cf. Gal 4:5); liberation from sin through Christ's sacrificial death (Eph 1:7); revelation of God's plan of salvation in Christ (Eph 1:9; cf. Eph 3:3–4; Rom 16:25); the gift of election and faith in Christ bestowed upon Jewish Christians (see note on Eph 1:12, we who first hoped in Christ); and finally, the same gift granted to Gentiles (Eph 1:13, you also). In the Christ-centered faith and existence of the Christian communities the apostle sees the predetermined plan of God to bring all creation under the final rule of Christ (Eph 1:4–5, 9–10) being made known (Eph 1:9) and carried through, to God's glory (Eph 1:6, 12, 14).
* [1:3] In the heavens: literally, "in the heavenlies" or "in the heavenly places," a term in Ephesians for the divine realm.
* [1:9] Mystery: as in Rom 16:25; Col 1:26, 27 and elsewhere, a secret of God now revealed in the plan to save and sum up all things in Christ (Eph 1:10); cf. Eph 3:3–6.
* [1:12] We who first hoped: probably Jewish Christians (contrast Eph 1:13, you, the Gentiles); possibly the people of Israel, "we who already enjoyed the hope of Christ," or perhaps present hope in contrast to future redemption (cf. Eph 1:14).
* [1:13] Sealed: by God, in baptism; cf. Eph 4:30; 2 Cor 1:22.
* [1:14] First installment: down payment by God on full salvation, as at 2 Cor 1:22.
* [1:15–23] See note on Rom 1:8 for the thanksgiving form in a letter. Much of the content parallels thoughts in Col 1:3–20. The prayer moves from God and Christ (Eph 1:17, 20–21) to the Ephesians (Eph 1:17–19) and the church (Eph 1:22–23). Paul asks that the blessing imparted by God the Father (Eph 1:3) to the Ephesians will be strengthened in them through the message of the gospel (Eph 1:13, 17–19). Those blessings are seen in the context of God's might in establishing the sovereignty of Christ over all other creatures (Eph 1:19–21) and in appointing him head of the church (Eph 1:22–23). For the allusion to angelic spirits in Eph 1:21, see Rom 8:38 and Col 1:16. Here, as in 1 Cor 15:24–25 and Col 2:15, every such principality and power is made subject to Christ.
* [1:15] Your faith…your love: some manuscripts omit the latter phrase, but cf. Col 1:4.
* [1:23] His body: the church (Eph 1:22); cf. note on Col 1:18. Only in Ephesians and Colossians is Christ the head of the body, in contrast to the view in 1 Cor 12 and Rom 12:4–8 where Christ is equated with the entire body or community. Fullness: see note on Col 1:19. Some take the one who fills as God, others as Christ (cf. Eph 4:10). If in Christ "dwells the fullness of the deity bodily" (Col 2:9), then, as God "fills" Christ, Christ in turn fills the church and the believer (Eph 3:19; 5:18). But the difficult phrases here may also allow the church to be viewed as the "complement" of Christ who is "being filled" as God's plan for the universe is carried out through the church (cf. Eph 3:9–10).
a. [1:1] Rom 1:7; 1 Cor 1:1–2; Col 1:1.
d. [1:4] 5:27; Jn 15:16; 17:24; Rom 8:29; 2 Thes 2:13.
g. [1:7] 2:7–13; Rom 3:24; Col 1:14, 20.
j. [1:10] Gal 4:4; Col 1:16, 20.
k. [1:11] Is 46:10; Rom 8:28; Col 1:12; Rev 4:11.
l. [1:13] 4:30; Acts 2:33; Col 1:5–6.
m. [1:14] 2 Cor 1:22; 5:5.
n. [1:15] Col 1:3–4; Phlm 4–5.
p. [1:17] 3:14, 16; Col 1:9–10; 1 Jn 5:20.
r. [1:19] 2 Cor 13:4; Col 1:11; 2:12.
t. [1:21] Phil 2:9; Col 1:16; 1 Pt 3:22.
Copyright 2019-2024 USCCB, please review our Privacy Policy


text:
Boston bomb suspect captured, brother killed
WATERTOWN, Mass. - A 19-year-old Massachusetts college student wanted in the Boston Marathon bombing was captured hiding in a boat parked in a backyard Friday night and his older brother lay dead in a furious 24-hour drama that transfixed the nation and paralyzed the Boston area.
"CAPTURED!!!" the Boston police tweeted in news that set off celebrations across the metropolitan area and finally broke the tension. "The hunt is over. The search is done. The terror is over. And justice has won. Suspect in custody."
The bloody endgame came four days after the bombing and just a day after the FBI released surveillance-camera images of two young men suspected of planting the pressure-cooker explosives that ripped through the crowd at the marathon finish line, killing three people and wounding more than 180.
The two men were identified by authorities and relatives as ethnic Chechens from southern Russia who had been in the U.S. for about a decade and were believed to be living in Cambridge, Mass. But investigators gave no details on the motive for the bombing.
Early Friday morning, 26-year-old Tamerlan Tsarnaev was killed in a ferocious gun battle and car chase during which he and his younger brother hurled explosives at police from a stolen car, authorities said. The younger brother managed to escape.
During the getaway attempt, the brothers killed an MIT policeman and severely wounded another officer, authorities said.
After a tense, all-day manhunt and house-to-house search by thousands of SWAT team officers with rifles and armored vehicles, Dzhokhar Tsarnaev was cornered in a homeowner's yard, where he exchanged gunfire with police while holed up in a boat, authorities said.
He was seized around 9 p.m. and hospitalized in serious condition with unspecified injuries, police said.
A cheer went up from a crowd of bystanders in Watertown.
"Everyone wants him alive," said Kathleen Paolillo, a teacher.
Boston Mayor Tom Menino tweeted, "We got him," along with a photo of himself talking to the police commissioner.
"Tonight, our family applauds the entire law enforcement community for a job well done, and trust that our justice system will now do its job," said the family of 8-year-old Martin Richard, who died in the bombing.
Police said three other people were taken into custody for questioning at an off-campus housing complex at the University of the Massachusetts at Dartmouth where the younger man may have lived.
Up until the younger man's capture, it was looking like a grim day for police. As night fell, they announced that they were scaling back the hunt and lifting the stay-indoors order across Boston and some of its suburbs because they had come up empty-handed.
But then a break came in a Watertown neighborhood when a homeowner saw blood on his boat, pulled back the tarp and saw the bloody suspect hiding inside, police said.
Chechnya has been the scene of two wars between Russian forces and separatists since 1994, in which tens of thousands were killed in heavy Russian bombing. That spawned an Islamic insurgency that has carried out deadly bombings in Russia and the region, although not in the West.
The older brother had strong political views about the United States, said Albrecht Ammon, 18, a downstairs-apartment neighbor in Cambridge. Ammon quoted Tsarnaev as saying that the U.S. uses the Bible as "an excuse for invading other countries."
Also, the FBI interviewed the older brother at the request of a foreign government in 2011, and nothing derogatory was found, according to a federal law enforcement official who was not authorized to discuss the case publicly and spoke on condition of anonymity.
The official did not identify the foreign country or say why it made the request.
The FBI was swamped with tips after the release of the surveillance-camera photos - 300,000 per minute - but what role those played in the capture was unclear. State Police spokesman Dave Procopio said police realized they were dealing with the bombing suspects based on what the two men told a carjacking victim during their long night of crime.
The search for the younger brother all but paralyzed the Boston area. Officials shut down all mass transit, including Amtrak trains to New York, advised businesses not to open, and warned close to 1 million people in the entire city and some of its suburbs to stay inside and unlock their doors only for uniformed police.
"We believe this man to be a terrorist," Boston Police Commissioner Ed Davis said. "We believe this to be a man who's come here to kill people."
Around midday, the suspects' uncle Ruslan Tsarni of Montgomery Village, Md., pleaded on television: "Dzhokhar, if you are alive, turn yourself in and ask for forgiveness."
Authorities said the man dubbed Suspect No. 1 - the one in sunglasses and a dark baseball cap in the surveillance-camera pictures - was Tamerlan Tsarnaev, while Suspect No. 2, the one in a white baseball cap worn backward, was his younger brother.
Exactly how the long night of crime began was unclear. But police said the brothers carjacked a man in a Mercedes-Benz in Cambridge, just across the Charles River from Boston, then released him unharmed at a gas station.
They also shot to death a Massachusetts Institute of Technology police officer, 26-year-old Sean Collier, while he was responding to a report of a disturbance, investigators said.
The search for the Mercedes led to a chase that ended in Watertown, where authorities said the suspects threw explosive devices from the car and exchanged gunfire with police. A transit police officer, 33-year-old Richard Donohue, was shot and critically wounded, authorities said.
Some 200 spent shells were found afterward.
Dzhokhar Tsarnaev somehow slipped away. He ran over his already wounded brother as he fled, according to two law enforcement officials who spoke on condition of anonymity because they were not authorized to discuss the investigation. At some point, he abandoned his car and ran away.
Tamerlan Tsarnaev died at a Boston hospital after suffering what doctors said were multiple gunshot wounds and a possible blast injury.
The brothers had built an arsenal of pipe bombs, grenades and improvised explosive devices and used some of the weapons in trying to make their getaway, said Rep. Dutch Ruppersberger, D-Md., a member of the House Intelligence Committee.
Watertown resident Kayla Dipaolo said she was woken up overnight by gunfire and a large explosion that sounded "like it was right next to my head ... and shook the whole house."
She said she was looking at the front door when a bullet came through the side paneling. SWAT team officers were running all over her yard, she said.
"It was very scary," she said. "There are two bullet holes in the side of my house, and by the front door there is another."
Tamerlan Tsarnaev had studied accounting as a part-time student at Bunker Hill Community College in Boston for three semesters from 2006 to 2008, the school said.
Dzhokhar Tsarnaev was registered as a student at the University of Massachusetts Dartmouth. Students said he was on campus this week after the Boston Marathon bombing. The campus closed down Friday along with colleges around the Boston area.
The men's father, Anzor Tsarnaev, said in a telephone interview with AP from the Russian city of Makhachkala that his younger son, Dzhokhar, is "a true angel." He said his son was studying medicine.
"He is such an intelligent boy," the father said. "We expected him to come on holidays here."
The city of Cambridge announced two years ago that it had awarded a $2,500 scholarship to him. At the time, he was a senior at Cambridge Rindge & Latin School, a highly regarded public school whose alumni include Matt Damon, Ben Affleck and NBA Hall of Famer Patrick Ewing.
Tsarni, the men's uncle, said the brothers traveled here together from Russia. He called his nephews "losers" and said they had struggled to settle in the U.S. and ended up "thereby just hating everyone."


text:
Stock Availability | : | Pre-Order |
Qty | : |
DIM: 43cm (w) x 43cm (d) x 105cm (h) x 75cm (sh)
Material: Mild Steel
1. Pre-order 6 weeks.
2. If need custom color, kindly contact sales person for more information. (only availble for project sale, not for home user)
3. For Uph item, please don't refer internet photo color as your wanted color, you have to pick a material code from our sale person before purchase it.
4. business.moredesign.com product only available within Malaysia, excluded oversea delivery.
Color of the product might look different from different screen.
If you are particilar with the color tone, you are advisable to reconfirm the color at your store before purchase it.
Some of the icon photo are edited, lighten up or retone. You are advisable to refer back our project photo or actual photo (without edit) before purchase.
Once you confirm, no cash refund, but we allow client use back the credit to enjoy other item.


text:
Health Insurance Specialist, LLC About Us
Health Insurance Specialist, LLC is an independent insurance agency that has been and continues to be dedicated to overseeing the insurance needs of Wichita for many years. Whether we provide your family with homeowners or car insurance, protect your commercial property, or provide coverage for your employee health plans, our insurance specialists are available throughout the year to offer professional assistance with insurance claims, payment options, policy upgrades and many other services.
Personalized Service
We work side by side with clients to ensure they receive fair and efficient payment for claims and that coverage meets their needs. Linked with our select group of reputable insurance providers, Health Insurance Specialist, LLC continuously strives to find the best insurance products for employers, family members and individuals.
Access to a Wide Range of Insurance Policies in One Place
Everyone needs insurance protection. Yet coverage can vary significantly when it comes to personal and business insurance policies. No one single insurance could adequately provide an entirely comprehensive range of coverage options to suit every single requirement.
Fortunately, Health Insurance Specialist, LLC is connected to a wide range of carriers that provide insurance plans and financial services that are readily available to the residents of Wichita. Contacting one of our experienced and trustworthy advisers gives you instant access to a comprehensive selection of insurance options for all of your personal or business needs. In addition, Health Insurance Specialist, LLC agents do all of the research and comparisons for the coverage that meets your specific needs and offers the most competitive rates. In today's market, you want an insurance adviser who efficiently wades through all the paperwork, clarifies your coverage options, designs a personalized plan and ultimately looks out for your best interests by providing the insurance solutions you need.
Call to find out what we can offer you!
Whether you require home, car, business, health or life insurance, call the Wichita insurance experts at Health Insurance Specialist, LLC for protection and peace of mind. We will work tirelessly so you get the coverage that brings you security without costing an arm and a leg.
Making sure that you, your business, or family are protected is what we do! Contact us today! We look forward to hearing from you!
A 2024 Small Business Award Finalist
Health Insurance Specialists LLC is proud to have been recognized as an outstanding local small business by the Wichita Chamber of Commerce.
During a June 2024 event, the Chamber announced the finalists for the 20th Anniversary Small Business Awards. These companies were picked in part due to their business performance, community involvement and work culture.
Our company was listed in the top 3 companies in our tier! CEO and Insurance Agent Steven Elliott accepted this honor given by President & CEO of the Wichita Regional Chamber of Commerce John Rolfe.


text:
The idea of your pet being infested with parasites is a disturbing thought, but it's also a medical issue that can have serious consequences if not properly dealt with or prevented. Parasites pose a variety of health issues for our pets, who can be very susceptible to certain parasites depending on age, region, and other factors.
At Del Mar Veterinary Hospital, we emphasize the importance of preventing parasites. Through preventative measures, you can successfully protect your pet. But pets that are not protected often develop parasites, leading to serious problems for them and their owners.
The cost of prevention is minimal compared to the cost of treatment, which can be expensive and stressful on your pet. Parasites like heartworm can even be fatal, so preventing parasites is of the utmost importance.


text:
Watertown, Delano, Rockford Group Health Insurance
With the face of healthcare changing, there is a lot to know and likely many questions when it comes to creating a Group Health plan for your company. Pysick Insurance Agency is here to help guide you.
Group health insurance is one of the most important employee benefits offered and consistently the most popular.
Employers have a number of plan options including Preferred Provider Organization (PPO), a Health Maintenance Organization (HMO) and Consumer Driven Health Plan (CDHP). You'll also want to consider part time employees or those who don't qualify for the same benefits as full time employees as. There are plans to accommodate your diverse work force.
Group Health coverage in Watertown, Delano, Rockford
- Health Insurance
- Dental Insurance
- Vision coverage
- Health Savings Accounts
It's important for you to have an advisor you trust to provide the right information as well as the insurance company partners to build reliable options at a cost that makes sense for your business or company.
Pysick Insurance Agency has been that trusted advisor to many of the businesses and companies in Watertown and throughout the state of Minnesota. Give us a call or take advantage of our secure quote request form and allow us to earn your trust.


text:
BREMERTON, Wash. – Police in Washington state say a man suspected of taking $9,200 worth of clubs and other merchandise from the pro shop at Gold Mountain Golf Course had no criminal history, but appears to be addicted to golf.
Bremerton police detectives spotted some of the stolen gear for sale online and arrested the suspect Wednesday in Kirkland.
Police Chief Steve Strachan (stran) said in a news release that robberies are often the result of addictions, but this is the first one police have seen "that looks like a golf addiction."
The Kitsap Sun reports (http://bit.ly/1oZGK3Z) other property that was stolen from the pro shop on Memorial Day was recovered from the suspect's apartment.
Information from: Kitsap Sun, http://www.kitsapsun.com/


text:
No booking fees!
FREE cancellation in most cases!
Please fill in the form below with your transfer details. Once you fill in the start and end point and number of people, you will get a price for your transfer and you can make an instant transfer booking, pay by credit card or paypal and print your transfer confirmation.
We have online prices for the most popular destinations. For the others, please submit an inquiry and a member of our team will quote a transfer price.


text:
Tensions over fishing rights and border checks are driving officials in Spain and Britain to consider legal options in their newly escalated dispute over the status of Gibraltar.
In recent weeks, Spain has insisted on performing comprehensive border checks that slow traffic to Gibraltar, a rocky outcropping of land at the southern tip of the Iberian Peninsula, in a move seen as an answer to Gibraltar's creation of a concrete reef in disputed waters.
The British government is considering legal action against Spain that a Downing Street spokesman calls an "unprecedented step." Spanish officials said Monday that their border controls are a legitimate attempt to stop smuggling.
The spat has continued despite talks on the issue last week between British Prime Minister David Cameron and Spanish Prime Minister Mariano Rajoy.
From Madrid, Lauren Frayer filed this report for NPR's Newscast unit:
"Many who drive back and forth into the 2 1/2-square-mile peninsula of Gibraltar are now facing five-hour lines at the border. Spain has beefed up security in retaliation for Gibraltar's construction of an offshore reef — which Spanish fishermen say blocks their boats.
"Madrid doesn't recognize any Gibraltarian right to nearby waters — and may take its case to the U.N. London says it's weighing legal action as well. This, after the prime ministers of the two countries pledged last week to defuse tensions.
"But British navy vessels are en route to Gibraltar this week. The peninsula at Spain's southern tip has been British soil for 300 years — a claim many Spaniards have never recognized."
Those British warships include the HMS Illustrious, a helicopter and commando carrier, and the HMS Westminster, a frigate, which are scheduled to continue on to the Mediterranean. Along the way, they'll also stop at a Spanish naval base, according to BBC diplomatic correspondent James Robbins.
Copyright 2021 NPR. To see more, visit https://www.npr.org.


text:
Updated As of April, 6 2015.
DICK'S Sporting Goods, Inc. and its Family of Businesses, including Blue Sombrero, LLC (collectively, "DICK'S") provide this privacy policy (this "Policy") to inform you of: (1) the types of information we collect; (2) your choices surrounding such information; and (3) how we collect, use, share, update and secure such information. This Policy applies to information obtained in connection with DICK'S operations at or through our websites, our mobile/tablet sites, our social media presence, our applications, our stores and other DICK'S controlled digital properties that link to this Policy. For purposes of this Policy, our websites, our mobile/tablet sites, our social media presence, our applications, and our other digital properties are referred to collectively as, our "Websites." Emails, social media, marketing campaigns and online advertising are referred to collectively as, our "Internet Marketing Channels."
This Policy does not create a contractual obligation between you and DICK'S, and it is subject to our Terms of Use. If you have questions about this Policy, please contact us by using the "Contact Customer Service" link below.
We receive information you voluntarily provide to us when you: (1) open an account with us; (2) utilize our services; (3) apply for a credit card; (4) make a purchase; (5) apply for a license (e.g., hunting, fishing, etc.) or conduct a similar type transaction; (6) contact us via any customer service method; (7) submit user-generated content (via our Websites, Internet Marketing Channels or otherwise); (8) participate in customer research, surveys, sweepstakes or promotions; or (9) otherwise communicate information to us.
Some of the information is considered "Personal Information." Personal Information includes your name, mailing address, e-mail address, driver's license number, social security number, credit/debit card information (and related payment information) and/or telephone number. We may also collect other information such as permit number(s), credit application information and demographic/lifestyle information (including date of birth, personal interests and product/buying preferences).
The collection of certain types of Personal Information may be necessary and/or required for governmental compliance (e.g., hunting, fishing or firearms licensing or purchasing).
Additionally, we may receive Personal Information and other information you provide on behalf of third parties, or third parties provide on behalf of you, including gift recipients, online registrations/purchases, ship-from-store, in-store pick-up, or registries. We may also receive Personal Information and other information from sources assisting us with updating, improving and/or analyzing our records or with detecting fraud or theft. Additionally, we may receive information from various consumer reporting agencies and related service providers.
We may collect "Automated Information" through Cookies (as defined below), Web Beacons (as defined below) and other related automated means (collectively, "Information Technologies"). Automated Information we collect via Information Technologies includes internet protocol address(es), operating system(s) and browser specifics of your device, device characteristics, geographic information, user ID(s), and specifics regarding your interactions with (i.e., the path you take through) our Websites and our Internet Marketing Channels.
We use Information Technologies to recognize you and your preferences as you return to our Websites or utilize our Internet Marketing Channels. "Cookies" are small text files sent to your device as you visit our Websites or utilize our Internet Marketing Channels and saved on your device via your browser or hard drive. "Web Beacons" (also known as pixel tags) are a form of technology placed within our Websites and our Internet Marketing Channels to monitor visits to certain pages within, interactions with, and the effectiveness of, our Websites and our Internet Marketing Channels.
Automated Information enables the tailoring of advertisements and offers specifically for you. In addition to such tailoring, we use Automated Information to ensure that our online presence operates properly and efficiently for you and for your individual customer experience, to evaluate the use and benefit of such presence, and to support our Websites and our Internet Marketing Channels.
The browser on your device may offer you preferences regarding a website's collection of your personal information or your online activities over time and/or across different websites or online services. At this time, our Websites do not respond to these preferences, and our Websites may continue to collect information in the manner described in this Policy.
We may enable third parties to collect information in connection with our Websites. This Policy does not apply to, and we are not responsible for, any collection of information by third parties on our Websites.
We use, collect and disclose your information consistent with this Policy, as updated from time to time, and you consent to such use, collection and disclosure by your use of our: (1) Websites; (2) Internet Marketing Channels; and (3) marketing programs (e.g., loyalty programs).
You may unsubscribe to future e-mail communications by clicking on the unsubscribe link provided in our e-mail communications. Regardless of your decision to opt-out of future e-mail communications, we may still contact you to respond to an inquiry, regarding transactions and for transactional purposes (e.g., recalls, product information and service/reminder notices). In addition, you may use the methods set forth in the "Contact Customer Service" link below to opt-out or update certain preferences.
Based upon your visit(s) to our Websites and elsewhere on the Internet and your interaction with our Internet Marketing Channels, we may personalize your experience via our Websites and via our Internet Marketing Channels. However, you have choices relating to how your device interacts with our Websites and our Internet Marketing Channels. You may choose to access our Websites and our Internet Marketing Channels without accepting certain Information Technologies on your device(s), and you may opt-out or modify certain elements that are tailored specifically to you and served to you based upon your browsing history. If you choose to restrict Information Technologies, you may access our Websites and Internet Marketing Channels, but you will NOT be able to take full advantage of certain features. Please note, even if you choose to restrict, opt-out or modify, you may still see or receive DICK'S advertisements on our Websites, on our Internet Marketing Channels and on other sites, but such advertisements will not be based upon your browsing history.
Additionally, we work with advertising networks that utilize the browsing history of your visits to our Websites, Internet Marketing Channels and across other sites to serve you DICK'S advertisements across the Internet and through other channels. We do not permit such networks to provide your browsing history on any of our Websites to any other site. Some of these networks may participate in the Digital Advertising Alliance's ("DAA") Self-Regulatory Program. To learn more about your choices relating to networks that participate in the DAA Program, please click here.
We do not sell, rent or trade your Personal Information to third parties. We use your information in ways consistent with this Policy, as disclosed at the time of collection, and in the following ways:
In doing so, we:
We may share your information in ways consistent with this Policy, as disclosed at the time of collection, and in the following ways:
For certain types of information, we offer you several ways to access or update such information:
Please note:
In our efforts to maintain accurate and complete information, we utilize third party entities to assist us with updating and maintaining current contact information (e.g., National Change of Address or NCOA).
We use a variety of security measures to help protect your information and online transactions with us. Our Websites utilize encryption technology, including Secure Sockets Layer, to protect your information that we transport across the internet. Your personal online and mobile account(s) with us are password protected with restricted online access.
Additionally, we use a variety of security measures to help protect your information that we maintain at our facilities. While no company can guarantee your information will not be accessible by unauthorized individuals, we use physical, administrative and technical controls that are consistent with retail practices in an attempt to mitigate such risks.
Our Websites are "general audience" websites and not directed toward children. We do not knowingly collect Personal Information from children under the age of 13 without express parental consent. If you are a parent or guardian and think we have unauthorized information about your child who is under the age of 13, please let us know by contacting us through the "Contact Customer Service" link below.
Our Websites and our Internet Marketing Channels may link to other sites that we do not control. These other sites are governed by their own privacy policies. Be sure to review these privacy policies when visiting such sites. We are not responsible for the content of privacy practices of such third parties' sites.
We may, from time to time, update and revise this Policy. Please periodically check this Policy for any updates or revisions. In the event we make a material change to how we use your information, we will provide you with advance notice and the opportunity to opt-out of such use.


text:
This webpage doesn't work with Internet Explorer. Please use the latest version of Google Chrome, Microsoft Edge, Mozilla Firefox or Safari.
The information presented in this cross reference is based on TOSHIBA's selection criteria and should be treated as a suggestion only. Please carefully review the latest versions of all relevant information on the TOSHIBA products, including without limitation data sheets and validate all operating parameters of the TOSHIBA products to ensure that the suggested TOSHIBA products are truly compatible with your design and application.
Please note that this cross reference is based on TOSHIBA's estimate of compatibility with other manufacturers' products, based on other manufacturers' published data, at the time the data was collected.
TOSHIBA is not responsible for any incorrect or incomplete information. Information is subject to change at any time without notice.
器件型號 | Authorized Distributor | Stock Quantity | Date | Shopping Cart |


text:
Diagnosing arthritis may be difficult. There are more than 100 different types of arthritis. Many symptoms are similar among the different conditions affecting the joints. Arthritis may be generally categorized into the following groups: degenerative arthritis, inflammatory arthritis, metabolic arthritis, and infectious arthritis. Osteoarthritis (also known as degenerative arthritis) is the most common type. Rheumatoid arthritis and gout are 2 other more common types. To make an accurate diagnosis, a healthcare provider may need to:
Review your health history and current symptoms
Examine you, with close attention to your joints
Order lab tests, X-rays, and other imaging tests, such as an ultrasound or MRI
Remove fluid from a joint (arthrocentesis)
When reviewing your health history, your healthcare provider may ask the following questions:
Have you had any illnesses or injuries that may explain the pain?
Is there a family history of arthritis or other rheumatic diseases?
What medicines are you currently taking?
Your healthcare provider may also ask:
What symptoms are you having? For example, pain, stiffness, trouble with movement, or swelling.
About your pain:
Where is it?
How long have you had it?
When do you have pain and how long does it last?
Describe your pain (constant, dull, throbbing, stabbing)
How intense is it? (On a scale of 1 to 10, with 1 being no pain, and 10, the worst pain)
What reduces the pain?
What makes it worse?
Is your pain worse certain times of the day?
In addition to a complete health history and physical exam, the following are common lab tests:
Antinuclear antibody. This test measures blood levels of various antibodies, which may be present in people with some types of arthritis.
Arthrocentesis (joint aspiration). This is an exam of joint fluid. A thin needle is put into the joint. Synovial fluid is removed with a syringe and looked at for cell counts, crystal analysis, culture, and other tests.
Complement tests. This test measures the level of complement, a group of proteins in the blood. It is used to help diagnose and monitor systemic lupus erythematosus (SLE) and rheumatoid arthritis.
Complete blood count (CBC). Measures the number of white blood cells, red blood cells, and platelets present in a sample of blood. A low white blood count (leukopenia), low red blood count (anemia), or low platelet count (thrombocytopenia) are linked to some forms of arthritis or the medicines to treat them.
Creatinine. A blood test to monitor for underlying kidney disease.
C-reactive protein (CRP). This protein is high or is elevated when there is inflammation in the body, as in some types of arthritis.
Erythrocyte sedimentation rate (ESR or sed rate). This measures how quickly red blood cells fall to the bottom of a test tube. A high ESR level occurs when there is inflammation in the body. This occurs in some types of arthritis.
Hematocrit (PCV, packed cell volume). Measures the number of red blood cells present in a sample of blood. Low levels of red blood cells (anemia) are common in people with some types of arthritis.
Rheumatoid factor. Checks for an antibody that is present in most people with rheumatoid arthritis.
Urinalysis. Lab exam of urine to check for kidney disease that may be linked to several types of arthritis.
Uric acid. High levels of uric acid are linked to gout.
Imaging methods may give your healthcare provider a clearer picture of what is happening to your joints. Imaging methods may include:
X-ray. X-rays may show joint changes and bone damage found in some types of arthritis. Other imaging tests may also be done.
Ultrasound. Ultrasound uses sound waves (not radiation) to show detailed pictures of soft tissue, tendons, ligaments, and joints.
MRI. MRI images are more detailed than X-rays without using radiation. They may show damage to joints, including muscles, ligaments, and cartilage.
Arthroscopy. This surgical procedure uses a thin tube containing a light and camera (arthroscope) to look inside the joint. The arthroscope is inserted into the joint through a small cut or incision. Images of the inside of the joint are projected onto a screen. It's used to assess any degenerative or arthritic changes in the joint, to find bone diseases and tumors, to figure out the cause of bone pain and inflammation, and to treat certain conditions.


text:
Use this section of 304 Stainless Steel Pipe for any project.
Works extremely well for intercooler pipe fabrication or exhaust fabrication. Stainless steel is extremely durable and will not rust, and is easy to weld to many other components with common welding tools.
It has an incredible mirror finish so reflective that it is difficult to photograph. The appearance of this pipe will vary based on its surroundings. It does not have a coating and is 0.08" thick. The extra thickness of these pipes allows for easier welding and improved durability.
This stainless steel pipe is 2' long.


text:
Loan-Related Closing Costs
Loan Origination Fee This covers the administrative expenses in setting-up and processing the loan. The loan origination fee may be a percentage of the mortgage amount.
Points (optional) An option for the home buyer is to pay points to lower the interest rate at which the loan will be repaid. Each point equals 1 percent of the mortgage amount. For example: on a $150,000 loan, 1 point would equal $1,500.
Appraisal Fee The fee for having the house appraised may be incorporated into the closing costs or payment may be required by the lender at the time the loan application is submitted.
Credit Report The lender uses a credit report to determine the creditworthiness of the loan applicant. This fee is often paid when the loan application is submitted.
Interest Payment Typically the buyer is required to pay interest on the mortgage loan to cover the time between the closing date and when the first mortgage payment period begins. For example: If closing is on May 15. Your first monthly payment begins to accrue interest on June 1 with your first mortgage payment due July 1. At closing an interest payment covering the accrual period between May 15 and May 31 may be required.
Escrow Account At closing a payment may be required to fund the escrow account if the lender is paying home insurance, property taxes and/or other expenses out of the escrow account.


text:
Program input
Hsffig acts as a filter (in Unix sense) which means that it consumes all its input information on its standard input (stdin), and produces its output on standard output (stdout). No other files are involved.
The hsffig program is invoked as follows:
gcc -E -dD header.h | hsffig > HEADER_H.hsc
The -E option instructs gcc only to preprocess (no compilation) its input file, and the -dD option instructs it to emit #define preprocessor statements along with the preprocessed header (without -dD, autogenerated binding module will not contain import statements for constants defined this way).
Preprocessor requirements
It is assumed that majority of hsffig users will use tools from the GNU Compiler Collection (GCC), whose preprocessor complies with the hsffig requirements. For other preprocessors from other vendors, the following is expected:
- The very first line of preprocessor output will contain the following construct:
# 1 header.h
where header.h is the name of the "toplevel" header file; number following after the hash sign does not matter.
Since hsffig does not take any command line arguments, the only way to determine the name of the module is the preprocessor output itself. When hsffig encounters a line like shown above (starting with hash sign and number), it derives the autogenerated Haskell module name by stripping the directory part from the header file name (as in basename(1)), uppercasing all characters (therefore the header file name cannot start with a digit), and replacing dots with underscores. Therefore, for a header file header.h, the autogenerated module will be named HEADER_H.
If compilant preprocessor is not available, and control lines like discussed above cannot appear in the preprocessor output (with gcc, this may be simulated with -P option), a special token @@MODULENAME@@ will be used in the Module statement. Later, it may be substituted with anything desirable with a program like sed(1). Also, if hsffig is unable to determine the header file name from its input, constants defined via #define will not be imported.
Program output
Hsffig outputs hsc code on its standard output, to be redirected to a file or (possibly) to some other filter program. The output is ready for processing by hsc2hs. Description of hsc2hs input file format may be found here:
The output file will contain the following sections:
- Special Definitions for hsc2hs
- Module header
- Constants defined with #define
- For each structure/union imported, an instance of the above mentioned class to access each member
- Constants defined via enumerations
- Import declarations for each function/extern variable declared
The preprocessor outputs preprocessed contents of not only the header file specified on its command line, but also of all other header files included within. This results in importing of some extra stuff (for instance, if a header file has #include <stdio.h> inside, everything defined in stdio.h will be imported as well). This merely gives the Haskell compiler which "connects" the library to an application written in Haskell the same look as the C compiler would have if it were "connecting" the library to an application written in C.
In first lines of generated hsc code, an #include statement is present to include the same header file that was consumed by hsffig. If hsffig is unable to determine header file name from its input (see Preprocessor Requirements), a special token @@INCLUDEFILE@@ will be placed with the #include statement instead. Similarly to the module name substitute, it may be later converted into a real header file name with a program like sed.
Special definitions for hsc2hs
In generated hsc code, the following hsc2hs macros are used to access members of structures/unions:
- #peek
- #poke
- #ptr
These macros take type declaration of the structure whose members are being accessed, as its first argument.
Consider the following structure declaration (a slightly modified fragment of BerkeleyDB's db.h):
struct __dbc { DB *dbp; /* Related DB access method. */ DB_TXN *txn; /* Associated transaction. */ struct { DBC *tqe_next, **tqe_prev; } links; /* . . . other members . . . */ }
To access members of the {{{struct ___dbc}}}, e. g. to peek a value of dbp, the following hsc2hs macro will be used:
(#peek struct __dbc, dbp)
But links is declared "anonymously", i. e. its structure type is not named. The only way to construct a #peek/#poke/#ptr macro is to put the whole structure declaration as its first argument:
(#peek struct {DBC *tqe_next, **tqe_prev;}, tqe_next)
This will cause an error because the C preprocessor macro that hsc2hs converts the above construct into, takes only two arguments, but comma in the structure declaration will be recognized as argument separator, i. e. there will be three arguments.
To work this around, hsffig makes the following declaration at the beginning of generated hsc code:
#ifndef __quote__ #define __quote__(x...) x #endif
This is a gcc feature called "macro varargs". The only thing this macro does is to represent its arguments whatever is their number, as a single token for the preprocessor.
So the macros from the example above will look:
(#peek __quote__(struct __dbc), dbp) (#peek __quote__(struct {DBC *tqe_next, **tqe_prev;}), tqe_next)
Additionally, the template file that hsc2hs needs to convert hsc to Haskell code needs to be modified. It uses the offsetof macro which also takes two arguments, but passing anonymously declared structure type containing commas will cause the same problems. So in the modified template file, the same __quote__ macro is used with offsetof:
#define hsc_peek(t, f) \ printf ("(\\hsc_ptr -> peekByteOff hsc_ptr %ld)", (long) offsetof (__quote__(t), f));
These special definitions are placed in the very beginning of every file that hsffig generates. A separate template file for hsc2hs is no longer needed. So, to generate importable Haskell code, a command like one below needs to be issued:
hsc2hs -t /dev/null HEADER_H.hsc -o HEADER_H.hs
Specifyiing /dev/null as template file name causes hsc2hs not to use any template file.
Splitting large modules
Considering that hsffig generates import statements for everything it encounters in all header files included within the toplevel header file, amount of generated Haskell code may be quite large, so it cannot be compiled by ghc at once due to memory limitations. To overcome this, a special utility, splitter is included with hsffig. In generated hsc code, the following comments are inserted:
-- Split begin/DB_H {-# OPTIONS -fglasgow-exts -ffi #-} #include "db.h" #ifndef __quote__ #define __quote__(x...) x #endif module DB_H( module DB_H, {-- #SPLIT# module DB_H_C, module DB_H_S, module DB_H_F, module DB_H_E, module DB_H_S_cnt, #SPLIT# --} module Foreign, module Foreign.C.String, module Foreign.C.Types) where import Foreign import Foreign.Ptr import Foreign.C.Types import Foreign.C.String {-- #SPLIT# import DB_H_C import DB_H_S import DB_H_F import DB_H_E import DB_H_S_cnt #SPLIT# --} -- Split end
This example is found in the very begining of generated hsc code. The splitter program reads its input file line by line. Comments like {{{-- Split begin/DB_H}}} redirect all subsequent lines in a file whose name is composed of characters following after '/' with '.hs' appended. Comments like {{{-- Split end}}} close output file: input lines are lost until another Split begin comment is met. Lines {{{ {-- #SPLIT# }}} and {{{ #SPLIT# --} }}} are removed from output, so enclosed pieces of Haskell code are uncommented.
As a result, one large module is split into many parts:
- The "Root" module to be imported into an application: name derived from the header file name, see above, e. g. DB_H
- A separate module containing import statements for constants declared with #define: name is derived from the header file name and postfixed with "_C", e. g. DB_H_C
- A separate module containing import statements for constants declared via enumerations: name is postfixed with "_E", e. g. DB_H_E
- A separate module containing import statements for variables and functions: name is postfixed with "_F", e. g. DB_H_F
- A separate module containing declaration of a multiparameter class and datatypes necessary to access members of structures/unions: name is postfixed with "_S_cnt", e. g. DB_H_S_cnt (Note: as of the patchlevel 2, instead of a single module postfixed with "_S_cnt", three separated modules are created, positixed with: "_S_n" for newtype declarations, "_S_t" for type aliases, and "_S_d" for declarations of structure member selector datatypes (V_..., X_..., D_...).
- A separate module for each structure/union defined in the header file and files included within: name is postfixed with "_S_" and followed by the structure type identifier derived by hsffig, e. g. DB_H_S_S{{{___}}}db_dbt for {{{struct __db_dbt}}}, or module DB_H_S_S_1142 for a structure declared anonymously (hsffig assigns unique numeric identifiers to such structures).
However, application developers do not need to know all these module names: all they still need to know is name of the "root" module (DB_H in our example) to be imported.
It is recommended to use ghc with --make option: this forces the compiler to chase all module dependencies automatically. Since all the modules created by splitter contain correct import statements, no module will be left behind.
FFI import details
Naming conventions
A significant difference between C and Haskell is that C does not force starting character of its variable, function, or type identifiers to be of certain case while Haskell has requirements of this kind. To resolve this problem, the following rules apply when an identifier declared in a C library is imported in a Haskell application.
All identifiers imported from a C library, or created to make import easier, are prefixed as shown in the table below:
Prefix | Purpose | Sort of Import | ||||||
Constant | Variable | Function Pointer |
Function | Structure Type |
Structure Member | |||
c_ | Constant imported with #define | Yes | No | No | No | No | No | |
e_ | Constant imported with enum | Yes | No | No | No | No | No | |
f_ | Standalone function | No | No | No | Yes | No | No | |
p_ | Pointer (memory address) of a variable | No | Yes | Yes | No | No | No | |
v_ | Value of a variable | No | Yes | Yes | No | No | No | |
s_ | Set a variable | No | Yes | Yes | No | No | No | |
x_ | Function pointed to by a variable | No | No | Yes | No | No | No | |
w_ | Wrapper for a function argument | No | No | Yes | Yes | No | No | |
S_, U_ | Structure/Union type as imported | No | No | No | No | Yes | No | |
V_ | Member of a structure (value) | No | No | No | No | No | Yes | |
D_ | Member of a structure - arrays only (dimensions) | No | No | No | No | No | Yes | |
X_ | Member of a structure (callable) | No | No | No | No | No | Yes | |
T_ | C Type Alias (typedef) as imported | No | No | No | No | No | No |
The table summarizes all prefixes hsffig adds to imported identifiers, and corresponding types of import. Flags Yes and No show whether given prefix and import purpose is suitable for each sort of imported entity.
C types declared with the typedef statement are imported as type aliases prefixed with "T_". These type aliases may be more convenient to use in certain situations.
The following C declaration:
typedef union { struct { int a:1; int b:1; int c:1; int d:1; } x; int y; } *PBF;
imports as:
type T_PBF = Ptr (U_9) newtype S_5 = S_5 () newtype U_9 = U_9 () -- instances to access S_5 and U_9 members follow
In the following Haskell program:
module Main where import BF_H main = do putStrLn $ "Test of Bit Fields" alloca $ \(bfu :: T_PBF) -> do x <- (bfu --> V_x) (x, V_a) <-- fromIntegral 1 (x, V_b) <-- fromIntegral 0 (x, V_c) <-- fromIntegral 0 (x, V_d) <-- fromIntegral 1 y <- (bfu --> V_y) putStrLn $ "y = " ++ (show y)
it is necessary to declare the type of bfu because there is no foreign import declaration that would drive the type inference mechanism. Since the union is declared anonymously, the type derived by hsffig contains a numeric identifier that is hard to remember. Imported typedef helps because it may be used instead, and is controlled by a developer (Ptr U_9 couls be used with the same effect).
Per FFI Addendum, the following typedefs are imported as they are (the Addendum defines names of Haskell types equivalent to them):
* ptrdiff_t * size_t * wchar_t * sig_atomic_t * clock_t * time_t * FILE * fpos_t * jmp_buf
Constants (#define)
For each constant declared with #define, generated hsc code looks as follows:
#define BIG_ENDIAN __BIG_ENDIAN #define PDP_ENDIAN __PDP_ENDIAN #define BYTE_ORDER __BYTE_ORDER #define S_IREAD S_IRUSR #define S_IRGRP (S_IRUSR >> 3) #define S_IROTH (S_IRGRP >> 3)
c_BIG_ENDIAN = #const BIG_ENDIAN c_PDP_ENDIAN = #const PDP_ENDIAN c_BYTE_ORDER = #const BYTE_ORDER c_S_IREAD = #const S_IREAD c_S_IRGRP = #const S_IRGRP c_S_IROTH = #const S_IROTH
that is, hsffig does not deal with actual value of the constant: it is left to hsc2hs.
However, arbitrary #define cannot be imported this way. Some preprocessor macros have parameters, or contain C statements, or otherwise cannot be assignment expression's RHS. To rule such preprocessor macros out, for each #define hsffig encounters on its input, a short C program is created, like this:
#include "header.h" static int a = BIG_ENDIAN;
for #define BIG_ENDIAN __BIG_ENDIAN. The command line for gcc is:
gcc -pipe -x c -q -fsyntax-only - 2>/dev/null
If this program passes syntax check, the constant is imported, otherwise not imported.
This explains why without being able to determine the header file name from its input, hsffig is unable to import #define 'd constants. This also shows that processing time for a header will be rougly linear to the number of #define preprocessor statements in the header.
Constants are not in the IO monad, and may be used in any function. Bit operations (from Foreign.C.Bits) may be applied to them:
dbperm = c_S_IRUSR .|. c_S_IWUSR .|. c_S_IRGRP .|. c_S_IWGRP .|. c_S_IROTH
may be used to specify file permissions {{{rw-rw-r--}}}
Constants (enum)
Enumerations are imported similarly to preprocessor-defined constants, but identifiers are prefixed with "e_".
An example showing usage of both #define and enumeration constants:
dbop <- dbp --> V_open ret <- withCString "access.db" $ \dbname -> do r <- dbop dbp nullPtr dbname nullPtr (fromIntegral e_DB_BTREE) (fromIntegral c_DB_CREATE) (fromIntegral dbperm) return r
fromIntegral may be necessary to apply to constants when calling foreign functions because the Haskell compiler infers the type for the following sort of expressions:
c_DB_CREATE = 1 e_DB_BTREE = 1
as Integer while the function referred to by dbop in the example above requires CInt, CUInt, CInt for its last three arguments.
Regular variables
Regular variables contain either values or pointers to other variables (not functions). For this sort of imports, the following identifiers are created:
- a pointer to the variable itself: prefix is "p_"
- a nullary function returning variable's value in the IO monad: prefix is "v_"
- a unary function taking a value and assigning it to the variable (in the IO monad): prefix is "s_"
So, for a variable declared as
extern int a;
FFI import declarations will be as follows:
foreign import ccall "header.h &a" ___2___ :: Ptr (CInt) p_a = ___2___ v_a = peek ___2___ s_a = poke ___2___
where ___2___ is one of internal unique names that hsffig assigns to all identifiers it encounters in the header file.
So, to retrieve value from a variable, v_a is used:
x <- v_a -- equivalent to peek p_a
To update the variable value, s_a is used:
s_a 4 -- equivalent to poke p_a 4
If a variable contains pointer to a value, e. g
extern int *ap;
then it is imported as follows:
foreign import ccall "header.h &ap" ___3___ :: Ptr (Ptr (CInt)) p_ap = ___3___ v_ap = peek ___3___ s_ap = poke ___3___
so to dereference the pointer, additional peek is needed:
c <- v_ap >>= peek
and s_ap will update the variable itself with new address, rather than the value it points to.
Function pointers
Function pointers contain pointers to executable code.
For this sort of imports, the following identifiers are created:
- pointer to the variable itself: prefix is "p_"
- a function the variable points to (with proper arity and type signature): prefix is "x_"
- a nullary function returning the function pointed to by the variable (in the IO monad): prefix is "v_"
- a unary function updating the variable with new function reference: prefix is "s_"
- optionally: wrapper functions for arguments taking function references: prefix is "w_"
A variable declared as:
int (*c)(long,int);
is imported as follows:
foreign import ccall "header.h &c" ___8___ :: Ptr (FunPtr (CLong -> CInt -> IO CInt)) p_c = ___8___ foreign import ccall "dynamic" ___8___mk___ :: FunPtr (CLong -> CInt -> IO CInt) -> (CLong -> CInt -> IO CInt) foreign import ccall "wrapper" ___8___wr___ :: (CLong -> CInt -> IO CInt) -> IO (FunPtr (CLong -> CInt -> IO CInt)) x_c _1 _2 = peek ___8___ >>= \s -> ___8___mk___ s _1 _2 v_c = peek ___8___ >>= (return . ___8___mk___) s_c = \s -> ___8___wr___ s >>= poke ___8___
Note that the function referred to by c returns IO CInt. It is assumed that all functions imported from a C library are unsafe, and therefore forced to be monadic. Based on the same assumption, all calls are considered "safe": this also allows calling Haskell functions from C code.
A variable declared as a function pointer in C , from the Haskell point of view contains a FunPtr i. e. virtual address of some foreign function's entry point. This cannot be used by a Haskell application directly, so a special dynamic import function needs to be declared. Such a pseudo-function (only its name and type signature need to be declared: the Haskell compiler does the rest) converts a FunPtr into a function usable by Haskell applications. Another pseudo-function, wrapper import does the opposite: converts a Haskell function into a monadic value containing a FunPtr i. e. a virtual address of an entry point usable by foreign functions (useful for callbacks).
For the variable - function pointer c, p_c returns pointer to the variable, just like for a regular variable. However, v_c returns the variable value passed through the dynamic import pseudo-function, so it may be used directly in Haskell applications. The setter function, s_c takes a Haskell function with proper type signature and updates the c variable value with new function address. The function x_c is the foreign function c points to.
The difference between v_c and x_c is illustrated below:
pc1 <- v_c r1 <- pc1 33::CLong 21::CInt -- but r2 <- x_c 33::CLong 21::CInt
v_c is a monadic value; x_c is not.
Optionally additional wrapper imports are created if a function pointed to by a variable takes other functions as arguments.
Consider the following:
typedef int (*F2) (long); typedef float (*X2) (double); F2 (*ee) (X2);
The variable ee is a pointer to a function taking a function from double to float, and returning a function from long to int.
The import looks as follows:
foreign import ccall "header.h &ee" ___40___ :: Ptr (FunPtr (FunPtr (CDouble -> IO CFloat) -> IO (FunPtr (CLong -> IO CInt)))) p_ee = ___40___ foreign import ccall "dynamic" ___40___mk___ :: FunPtr (FunPtr (CDouble -> IO CFloat) -> IO (FunPtr (CLong -> IO CInt))) -> (FunPtr (CDouble -> IO CFloat) -> IO (FunPtr (CLong -> IO CInt))) foreign import ccall "wrapper" ___40___wr___ :: (FunPtr (CDouble -> IO CFloat) -> IO (FunPtr (CLong -> IO CInt))) -> IO (FunPtr (FunPtr (CDouble -> IO CFloat) -> IO (FunPtr (CLong -> IO CInt)))) x_ee _1 = peek ___40___ >>= \s -> ___40___mk___ s _1 v_ee = peek ___40___ >>= (return . ___40___mk___) s_ee = \s -> ___40___wr___ s >>= poke ___40___ foreign import ccall "wrapper" w_ee_1 :: (CDouble -> IO CFloat) -> IO (FunPtr (CDouble -> IO CFloat))
An additional import declaration, w_ee_1 has been created. It may be used if ee is called, and some Haskell function is passed as a parameter:
mydoublefloat :: CDouble -> IO CFloat mydoublefloat = {-- function body here --} mydoublefloat_wrapped <- w_ee_1 mydoublefloat foo <- x_ee mydoublefloat_wrapped -- or foo <- w_ee_1 mydoublefloat >>= x_ee
Note that in the current version, hsffig does not create a dynamic import when a function imported returns a FunPtr.
Name of autogenerated wrapper import for function arguments ends with "_1". If a function takes more than one argument - function then more than one wrapper import will be created (one per function type). For example:
void (*psetpdf)(double (*df)(double,double),int,long,void(*)(int));
imports as:
foreign import ccall "header.h &psetpdf" ___6___ :: Ptr (FunPtr (FunPtr (CDouble -> CDouble -> IO CDouble) -> CInt -> CLong -> FunPtr (CInt -> IO ()) -> IO ())) p_psetpdf = ___6___ foreign import ccall "dynamic" ___6___mk___ :: FunPtr (FunPtr (CDouble -> CDouble -> IO CDouble) -> CInt -> CLong -> FunPtr (CInt -> IO ()) -> IO ()) -> (FunPtr (CDouble -> CDouble -> IO CDouble) -> CInt -> CLong -> FunPtr (CInt -> IO ()) -> IO ()) foreign import ccall "wrapper" ___6___wr___ :: (FunPtr (CDouble -> CDouble -> IO CDouble) -> CInt -> CLong -> FunPtr (CInt -> IO ()) -> IO ()) -> IO (FunPtr (FunPtr (CDouble -> CDouble -> IO CDouble) -> CInt -> CLong -> FunPtr (CInt -> IO ()) -> IO ())) x_psetpdf _1 _2 _3 _4 = peek ___6___ >>= \s -> ___6___mk___ s _1 _2 _3 _4 v_psetpdf = peek ___6___ >>= (return . ___6___mk___) s_psetpdf = \s -> ___6___wr___ s >>= poke ___6___ foreign import ccall "wrapper" w_psetpdf_1 :: (CDouble -> CDouble -> IO CDouble) -> IO (FunPtr (CDouble -> CDouble -> IO CDouble)) foreign import ccall "wrapper" w_psetpdf_2 :: (CInt -> IO ()) -> IO (FunPtr (CInt -> IO ()))
The function pointed to by setpdf takes two arguments-functions of different types, therefore two wrapper imports have been created.
Enumeration of wrappers created for arguments does not correspond to positional numbers of arguments.
Functions are imported under their own names prefixed by "f_". Similarly to the situation described above (variables holding function pointers), additional wrappers will be created for arguments representing other functions. Examples of import:
double dplus(double,double);
imports as:
foreign import ccall "static header.h dplus" f_dplus :: CDouble -> CDouble -> IO CDouble
A function taking another function as argument:
int db_env_set_func_yield (int (*)(void)) ;
imports as:
foreign import ccall "static header.h db_env_set_func_yield" f_db_env_set_func_yield :: FunPtr (IO CInt) -> IO CInt foreign import ccall "wrapper" w_db_env_set_func_yield_1 :: (IO CInt) -> IO (FunPtr (IO CInt))
Rules for creation and naming of wrapper imports are the same as defined for variables containing function pointers.
Structures and unions
Basic information
C structures/unions are different from Haskell records with labeled fields: different structure types may contain members with same names. Therefore direct mapping of C structures to Haskell records is not possible.
Some structures are declared with struct statement:
struct foo { int bar; long baz; };
Some structures are declared with typedef statement:
typedef struct foo { int bar; long baz; } foo_t;
In some cases, structure name in the typedef statement may be omitted:
typedef struct { int bar; long baz; } foo_t;
There also may be structures/unions declared within another structures/unions without explicit structure type name declaration:
typedef struct { int bar; long baz; struct { float faa; size_t taa; } str_anon; } foo_t;
Datatypes and combinators for structure members access
Structure types are imported using the newtype Haskell statement. Type name is prefixed with "S_" for structures and "U_" for unions. If a structure was declared as struct foo, Haskell type name will be S_foo. If a structure was declared anonymously (struct without identifier), a unique numeric identifier will be used as structure type name, e. g. S_65.
A imported structure type declaration looks like: newtype S_foo = S_foo (). Indeed, this type name serves only identification purpose.
In practice, Haskell application developers using hsffig do not need to memorize these clumsy type identifiers: Haskell type inference system carries most of the burden.
To access imported structure members, two algebraic data types are declared for each member identifier hsffig encounters in its input:
- V_member_id: to get/set value of a structure member member_id
- X_member_id: if a member holds function pointer, to invoke the function member_id points to
Unlike variables, there is no "S_" prefixed item.
A multi-parameter class with functional dependencies is declared to enable access to structures/unions members. Because of this, Haskell-98 extensions must be enabled in the compiler processing output of hsffig. The definition of this class is placed in the HSFFIG.FieldAccess module of the Haskell library coming with the package.
class FieldAccess a b c | a c -> b where (==>) :: Ptr a -> c -> b (-->) :: Ptr a -> c -> IO b (<--) :: (Ptr a, c) -> b -> IO () (==>) _ _ = error " illegal context for ==>" (-->) _ _ = error " illegal context for -->" (<--) _ _ = error " illegal context for <--"
The functional dependencies a b c | a c -> b specify that type of b depends entirely on the types a and c, and there may be only one type of b for every possible combination of a and c.
Indeed, a is the type of an imported structure/union. The type c is the data type associated with a structure/union member identifier. The type b is type of the member as represented to a Haskell program. In a C structure/union cannot be more than one member with same name (and different types). That's what the functional dependencies mean in this case. This information is sufficient for the Haskell compiler to infer the type of a value retrieved from a structure/union member.
The multiparameter class mentioned above is not used by Haskell applications directly. All imported types of structures/unions are instances of this class.
So, for a simple structure (note that the structure type and one of its members have the same name):
struct abc { int abc; };
the datatypes are:
newtype S_abc = S_abc () -- for the structure itself data V_abc = V_abc deriving (Show) -- for the member `abc' data X_abc = X_abc deriving (Show) -- not used
To get/set the member abc of the structure abc, the following instance is defined:
instance FieldAccess S_abc (CInt) V_abc where z --> V_abc = (#peek __quote__(struct abc), abc) z (z, V_abc) <-- v = (#poke __quote__(struct abc), abc) z v
So, for this instance, a = S_abc, b = CInt, and c = V_abc. Which is semantically equivalent to the above declaration of the member abc of the struct abc.
The --> combinator retrieves value of the given member from the structure pointed to by the given pointer. Thus, to access the value of abc, a Haskell application contains:
r <- z --> V_abc
Because of the multiparameter class and the instance declaration, the compiler is able to determine the type of the {{{z --> V_abc}}} expression correctly.
Assume another structure declaration:
struct def { void (*abc)(char *,int); };
perfectly legal from the C standpoint. Not only do the two different structures have a member with the same name abc, but these members have different types: one is a scalar integer value; another is a function pointer.
The import for struct def is (its part of the interest):
newtype S_def = S_def () instance FieldAccess S_def ((Ptr (CChar) -> CInt -> IO ())) V_abc where z --> V_abc = (#peek __quote__(struct def), abc) z >>= (return . ___60___S_def___mk) (z, V_abc) <-- v = (___60___S_def___wr v) >>= (#poke __quote__(struct def), abc) z
For this instance, a = S_def, b = Ptr (CChar) -> CInt -> IO (), and c = V_abc i. e. the same as for abc in struct abc.
So, in
r <- z --> abc t <- x --> abc
if x and z point to structures abc and def respectively, types of values bound to r and t will be different.
The <-- combinator is used for updating structure/union members with new values. This is a "real" update, not simulated by Haskell state mechanisms.
The code
(z,V_abc) <-- 4 -- fixme: is fromIntegral needed for a constant?
is equivalent to C code:
z -> abc = 4;
The ==> combinator is used to call functions pointed to by structre/union members. While --> may be applied only to "V_" prefixed identifiers, the ==> combinator may be applied only to "X_" prefixed identifiers.
The difference between "V_" and "X_" prefixed structure member identifiers is similar to that for imported variables holding function pointers:
fclose <- dbp --> V_close ret <- fclose dbp 0 -- but ret <- (dbp ==> X_close) dbp 0
The following is complete set of import statements that hsffig generates for struct def:
instance FieldAccess S_def ((Ptr (CChar) -> CInt -> IO ())) V_abc where z --> V_abc = (#peek __quote__(struct def), abc) z >>= (return . ___62___S_def___mk) (z, V_abc) <-- v = (___62___S_def___wr v) >>= (#poke __quote__(struct def), abc) z foreign import ccall "dynamic" ___62___S_def___mk :: (FunPtr (Ptr (CChar) -> CInt -> IO ())) -> ((Ptr (CChar) -> CInt -> IO ())) foreign import ccall "wrapper" ___62___S_def___wr :: ((Ptr (CChar) -> CInt -> IO ())) -> IO (FunPtr (Ptr (CChar) -> CInt -> IO ()) instance FieldAccess S_def ((Ptr (CChar) -> CInt -> IO ())) X_abc where z ==> X_abc = \_1 _2 -> do x <- z --> V_abc r <- x _1 _2 return r
So, z ==> X_abc> returns a function with type Ptr (CChar) -> CInt -> IO (). Because instance with V_abc is defined with only --> combinator, and instance with X_abc is defined with only ==> combinator, and instance with X_abc is declared only for members holding pointers to functions, attempt to use wrong combinator-member combination will result in compilation or runtime error.
Members of structures/unions which are structures/unions themselves are imported so that --> combinator returns a Ptr to the member, and <-- combinator is not allowed. Example (from bfd.h):
typedef struct lineno_cache_entry { unsigned int line_number; /* Linenumber from start of function*/ union { struct symbol_cache_entry *sym; /* Function name */ unsigned long offset; /* Offset into section */ } u; } alent;
imports as:
newtype S_lineno_cache_entry = S_lineno_cache_entry () newtype U_40 = U_40 () instance FieldAccess S_lineno_cache_entry (Ptr U_40) V_u where z --> V_u = return $ (#ptr __quote__(struct lineno_cache_entry), u) z (z, V_u) <-- v = error $ "field u is a structure: cannot be set" instance FieldAccess S_lineno_cache_entry (CUInt) V_line_number where z --> V_line_number = (#peek __quote__(struct lineno_cache_entry), line_number) z (z, V_line_number) <-- v = (#poke __quote__(struct lineno_cache_entry), line_number) z v instance FieldAccess S_lineno_cache_entry (CInt) V_sizeof where z --> V_sizeof = return $ (#size __quote__(struct lineno_cache_entry)) -- instance FieldAccess U_40 (CULong) V_offset where z --> V_offset = (#peek __quote__(union {struct symbol_cache_entry *sym; unsigned long offset; }), offset) z (z, V_offset) <-- v = (#poke __quote__(union {struct symbol_cache_entry *sym; unsigned long offset; }), offset) z v instance FieldAccess U_40 (Ptr (S_symbol_cache_entry)) V_sym where z --> V_sym = (#peek __quote__(union {struct symbol_cache_entry *sym; unsigned long offset; }), sym) z (z, V_sym) <-- v = (#poke __quote__(union {struct symbol_cache_entry *sym; unsigned long offset; }), sym) z v instance FieldAccess U_40 (CInt) V_sizeof where z --> V_sizeof = return $ (#size __quote__(union {struct symbol_cache_entry *sym; unsigned long offset; }))
So, to achieve the same as C code below does:
alent *pal; /* ... */ off = pal -> u.offset
a Haskell program would contain:
pal <- -- whatever returns IO (Ptr S_lineno_cache_entry) off <- (pal --> V_u) >>= \u -> (u --> V_offset)
Bit fields
Bit fields (declared as int somefield:n) are supported by hsffig, but there are some additional things that need attention.
There is no such thing as offsetof for bit fields. To implement the --> and <-- combinators, special inline C functions are embedded in the hsc code hsffig generates. This is achieved with the #def macro that hsc2hs recognizes.
These functions are placed in a special C file. This file must be compiled and linked to the final executable. Consider the following C header (bf.h):
union bitfields { struct { int a:1; int b:1; int c:1; int d:1; } x; int y; };
and the Haskell program (bftest.hs):
-- Test for bit fields. module Main where import BF_H main = do putStrLn $ "Test of Bit Fields" alloca $ \(bfu :: Ptr U_bitfields) -> do x <- (bfu --> V_x) (x, V_a) <-- fromIntegral 1 (x, V_b) <-- fromIntegral 0 (x, V_c) <-- fromIntegral 0 (x, V_d) <-- fromIntegral 1 y <- (bfu --> V_y) putStrLn $ "y = " ++ (show y)
When hsffig processes bf.h it creates BF_H.hsc. When hsc2hs processes BF_H.hsc it creates BF_H.hs, and additionally BF_H_hsc.h and BF_H_hsc.c. The latter is recommended to compile with ghc:
ghc -c BF_H_hsc.c
which provides correct compilation environment, so necessary paths for the runtime header files will be passed to gcc properly.
After all, the executable may be compiled and linked:
ghc -ffi -fglasgow-exts -package HSFFIG --make bftest.hs BF_H_hsc.o -o bftest
If bftest is run, it prints "9", as one might expect (at least on the x86 architecture).
Foreign structures/unions as storables and alloca
It is often necessary to pre-allocate a foreign (C) structure/union, so a foreign function can use it. The alloca and malloc functions are defined in Haskell FFI for this purpose. They require an argument belonging to the class Storable.
So, for every structure type imported by hsffig, iinstance of Storable is declared (for struct abc used in the example above):
instance Storable S_abc where sizeOf _ = (#size __quote__(struct abc)) alignment _ = 1 peek _ = error $ "peek and poke cannot be used with struct abc" poke _ = error $ "peek and poke cannot be used with struct abc"
These four methods are minimally required implementation of Storable per the FFI Addendum.
Actually, only sizeOf plays a role here, returning the same value as C expression sizeof (struct abc) would return.
An example below (retrieval of data from Berkeley DB) shows the use of everything discussed above:
(ret, ks, vs) <- alloca $ \dbkey -> -- dbkey = alloca (sizeof (DBT)) alloca $ \dbdata -> -- dbdata = alloca (sizeof (DBT)) withCStringLen "fruit" $ \fruit -> do -- (address, length) (dbkey,V_data) <-- fst fruit -- dbkey -> data set to the string address (dbkey,V_size) <-- (fromIntegral $ snd fruit) -- dbkey -> size set to the string length r <- (dbp ==> X_get) dbp nullPtr dbkey dbdata 0 -- r = dbp -> get (dbp, NULL, dbkey, dbdata, 0) ksc <- (dbkey --> V_data) :: IO CString -- ksc = dbkey -> data kss <- dbkey --> V_size -- kss = dbkey -> size if (r == 0) then do dsc <- (dbdata --> V_data) :: IO CString -- dsc = dbdata -> data dss <- dbdata --> V_size -- dss = dbdata -> size ks <- peekCStringLen (ksc, fromIntegral kss) vs <- peekCStringLen (dsc, fromIntegral dss) return (r, ks, vs) else return (r, undefined, undefined)
It may be noted again that a Haskell application developer does not need to remember type identifiers of foreign structures involved. The compiler, using FFI import statements and the multiparameter class' functional dependencies, correctly infers all necessary type information. In fact, type of dbkey and dbdata in the example above should be Ptr S_'_'_db_dbt (as defined in the header: typedef struct __db_dbt { ... } DBT;). But this type is not mentioned explicitly in the code.
Compilation of applications using bindings created with HSFFIG
Applications using bindings created with hsffig must be compiled/linked with the option -package HSFFIG passed to ghc. In the example below, the application consists of a single module containing the main funstion: main.hs, and the C library header file is header.h. The library file name is library.a.
The main.hs file must contain an import statement:
import HEADER_H
When hsffig processes header.h it creates HEADER_H.hsc. When hsc2hs processes HEADER_H.hsc it creates HEADER_H.hs, and additionally HEADER_H_hsc.h and HEADER_H_hsc.c. The latter is recommended to compile with ghc:
ghc -c HEADER_H_hsc.c
which provides correct compilation environment, so necessary paths for the runtime header files will be passed to gcc properly.
After all, the executable may be compiled and linked:
ghc -ffi -fglasgow-exts -package HSFFIG --make main.hs HEADER_H_hsc.o library.a -o main
The library of the package HSFFIG contains definition of the multiparameter class (HSFFIG.Field'Access.Field'Access) and the combinators necessary to access members of C structures/unions (see above). It is not necessary to directly import the hsffig modules in the application modules because the binding module re-exports them. It is however necessary to use the -fglasgow-exts options of ghc.
So, in the simplest case, the following steps are necessary:
gcc -E -dD header.h | hsffig > HEADER_H.hsc hsc2hs -t /dev/null HEADER_H.hsc -o HEADER_H.hs ghc -c HEADER_H_hsc.c ghc -ffi -fglasgow-exts -package HSFFIG --make main.hs HEADER_HSC.o library.a -o main
In some cases, size of the autogenerated Haskell code of the binding module is too large so it cannot be compiled due to lack of system resources. In this case, the binding module has to be split (see above, Splitting Large Modules). Steps to compile and build an executable now are:
gcc -E -dD header.h | hsffig > HEADER_H.hsc hsc2hs -t /dev/null HEADER_H.hsc -o HEADER_H.hs_unsplit splitter HEADER_H.hs_unsplit ghc -c HEADER_H_hsc.c ghc -ffi -fglasgow-exts -package HSFFIG --make main.hs HEADER_HSC.o library.a -o main
The only one step added is running splitter over the Haskell source code generated by hsc2hs. The way the final executable is linked does not change.
Known problems and workarounds
Variadic functions
C functions whose argument list ends with an ellipsis (...) in other words taking variable number of arguments cannot be imported by hsffig. A common example is printf. If hsffig encounters such a function, it places a comment in its output explaining why the function could not be imported. However if a variable or a structure/union member is defined as a pointer to a variadic function is imported as a pointer to a function with type IO () i. e. void (*p)(void). This preserves the ability to query/set function pointer from a Haskell program.
int (*pvard)(int,int,...); int vard (int,int,...);
imports as:
foreign import ccall "header.h &pvard" ___58___ :: Ptr (FunPtr (IO ())) p_pvard = ___58___ foreign import ccall "dynamic" ___58___mk___ :: FunPtr (IO ()) -> (IO ()) foreign import ccall "wrapper" ___58___wr___ :: (IO ()) -> IO (FunPtr (IO ())) x_pvard = peek ___58___ >>= \s -> ___58___mk___ s v_pvard = peek ___58___ >>= (return . ___58___mk___) s_pvard = \s -> ___58___wr___ s >>= poke ___58___ -- -- -- import of function/variable/structure member(s) vard :: WrongVariadicFunction is not possible -- because of the following reason(s): -- function is variadic
Functions/variables of structure type
If a function or a variable has a structure (not structure pointer) type, hsffig cannot import it. If hsffig encounters such a function, it places a comment in its output explaining why the function could not be imported. However, if a structure/union member is itself a structure/union, it is imported so that the --> combinator returns a Ptr to that member. However the <-- combinator is not defined for such members.
struct {int a,b,c,d;} *allocs(int,int,int,int); struct {int a,b,c,d;} directs(int,int,int,int);
imports as:
foreign import ccall "static header.h allocs" f_allocs :: CInt -> CInt -> CInt -> CInt -> IO (Ptr (S_56)) -- -- -- import of function/variable/structure member(s) directs :: CInt -> CInt -> CInt -> CInt -> @S_58 is not possible -- because of the following reason(s): -- function takes/returns structure(s) directly --
Note that while these two functions have return types looking the same, they are not the same from the C compiler standpoint, nor are they the same from the hsffig standpoint.
Unresolved symbols When linking
As mentioned above, hsffig generates FFI import declarations for every function it finds a prototype for. It may rarely happen, the header file has prototypes for functions not defined by the library the header is related to. As an example, consider the following short program printing "Hello World" using the low-level write function of the standard C POSIX library:
module Main where import UNISTD_H main = withCStringLen "Hello World\n" $ \hello -> do f_write (fromIntegral 0) (fst hello) (fromIntegral $ snd hello)
The prototype for write is contained in the unistd.h include file usually located in /usr/include. However if the program above is compiled and linked the "usual" way, two symbols remain unresolved by the linker: __ftruncate, and pthread_atfork *. As a result, the linker fails to create the executable file.
The possible workarounds are:
- To find the library where missing symbols are defined, and specify it on the ghc command line to link the executable.
- To tell the linker to ignore the unresolved symbols and build the executable no matter what.
- To use the -split-objs option that ghc provides (Note: See also HsffigLinkageOptimization for more detailed discussion of object file splitting possibilities).
The first option provides the best consistency, but it may be hard sometimes to find the correct library, especially for such low-level functions perhaps not assumed to be called directly.
The second option is a "short-cut" indeed: it leaves the problem open. If the developer is cofident that none of the unresolved symbols will be used for a whole life cycle of the apllication being developed, this may be acceptable, but this should not be considered an universal solution.
The third option is kind of a compromise: it leads to creation of consistent executable (and even the file size may be reduced significantly), but it also complicates the compliation/linkage process.
When given an option, -split-objs, ghc invokes a special script on the assembly files generated during compilation which cuts them into large number of small pieces. For this example program, UNISTD_H.hs was split into more than 700 object files.
These object files are placed in the special subdirectory whose name is derived from the module name: e. g. UNISTD_H_split for UNISTD_H. This directory is not autocreated: explicit mkdir command is necessary. The next step is to create a static library containing all those object files (ar -cq). The library must be specified later on the ghc command line to link the executable.
To tell more, this applies to the situation when splitter is not invoked, and there remains only one Haskell module with FFI declarations. If the module is split (this is "source split", not "object split, one not to be confused with another), then it makes sense to apply -split-objs only to the submodule containing FFI import declarations for functions (i. e. whose name is postfixed with "_F", UNISTD_H_F in this example): structures/unions, constants, and enumerations are compile-time items not dealt with by the linker.
The bottom line: uniform processing of object files with ghc --make is no longer available. Even worse, --make does not recognize libraries as compilation targets: if the module Main imports UNISTD_H, and there is UNISTD_H.hs, and libUNISTD_H.a, but no UNISTD_H.o, ghc --make will try to compile UNISTD_H to UNISTD_H.o and will ignore existence of the library.
The Makefile for this example program is shown below. It features the second and the third ways to work around the unresolved symbols problem.
GCC = gcc GHC = ghc HSFFIGDIR = /path/to/installed/hsffig-1.0 HSFFIG = $(HSFFIGDIR)/bin/hsffig # The command line to invoke hsc2hs: HSC2HS = hsc2hs -t /dev/null all: syscall UNISTD_H.hsc: /usr/include/unistd.h $(GCC) -E -dD /usr/include/unistd.h | $(HSFFIG) > UNISTD_H.hsc UNISTD_H.hs: UNISTD_H.hsc $(HSC2HS) UNISTD_H.hsc -o UNISTD_H.hs # The target to build the split-objects library: libUNISTD_H.a: UNISTD_H.hs -mkdir UNISTD_H_split $(GHC) -c -split-objs -package HSFFIG UNISTD_H.hs ar cq libUNISTD_H.a UNISTD_H_split/*.o syscall: syscall.hs libUNISTD_H.a UNISTD_H_hsc.o $(GHC) -c UNISTD_H_hsc.c # The second workaround: ignore unresolved symbols. The linker option to do this may depend on the version # of binutils used. In this example, it is --noinhibit-exec. Note how -optl and -Wl are combined. $(GHC) -ffi -package HSFFIG -fglasgow-exts --make syscall.hs UNISTD_H_hsc.o \ -optl -Wl,--warn-once -optl -Wl,--noinhibit-exec -o syscall-1 # The third workaround: link against the library. The --make option of ghc is not available. $(GHC) -package HSFFIG -fglasgow-exts syscall.hs UNISTD_H_hsc.o libUNISTD_H.a -o syscall-2 clean: rm -rf syscall-1 syscall-2 libUNISTD_H.a UNISTD_H* UNISTD_H_split *.o *.hi
- Note: This is of course OS-dependent situation: the situation described was observed on Linux with glibc 2.1.x. This example is provided here to illustrate how unresolved symbols problem may be worked around.