1 /*-------------------------------------------------------------------------
3 SDCCglue.c - glues everything we have done together into one file.
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
38 symbol *interrupts[256];
40 void printIval (symbol *, sym_link *, initList *, FILE *);
41 set *publics = NULL; /* public variables */
42 set *externs = NULL; /* Varibles that are declared as extern */
44 /* TODO: this should be configurable (DS803C90 uses more than 6) */
45 unsigned maxInterrupts = 6;
48 extern char *VersionString;
49 set *pipeSet = NULL; /* set of pipes */
50 set *tmpfileSet = NULL; /* set of tmp file created by the compiler */
51 set *tmpfileNameSet = NULL; /* All are unlinked at close. */
53 /*-----------------------------------------------------------------*/
54 /* closePipes - closes all pipes created by the compiler */
55 /*-----------------------------------------------------------------*/
56 DEFSETFUNC (closePipes)
69 /*-----------------------------------------------------------------*/
70 /* closeTmpFiles - closes all tmp files created by the compiler */
71 /* because of BRAIN DEAD MS/DOS & CYGNUS Libraries */
72 /*-----------------------------------------------------------------*/
73 DEFSETFUNC (closeTmpFiles)
86 /*-----------------------------------------------------------------*/
87 /* rmTmpFiles - unlinks all tmp files created by the compiler */
88 /* because of BRAIN DEAD MS/DOS & CYGNUS Libraries */
89 /*-----------------------------------------------------------------*/
90 DEFSETFUNC (rmTmpFiles)
104 /*-----------------------------------------------------------------*/
105 /* rm_tmpfiles - close and remove temporary files and delete sets */
106 /*-----------------------------------------------------------------*/
110 /* close temporary files */
111 applyToSet (pipeSet, closePipes);
112 /* close temporary files */
113 deleteSet (&pipeSet);
115 applyToSet (tmpfileSet, closeTmpFiles);
116 /* remove temporary files */
117 applyToSet (tmpfileNameSet, rmTmpFiles);
118 /* delete temorary file sets */
119 deleteSet (&tmpfileSet);
120 deleteSet (&tmpfileNameSet);
123 /*-----------------------------------------------------------------*/
124 /* copyFile - copies source file to destination file */
125 /*-----------------------------------------------------------------*/
127 copyFile (FILE * dest, FILE * src)
133 if ((ch = fgetc (src)) != EOF)
138 aopLiteralLong (value * val, int offset, int size)
147 // assuming we have been warned before
151 /* if it is a float then it gets tricky */
152 /* otherwise it is fairly simple */
153 if (!IS_FLOAT (val->type)) {
154 unsigned long v = (unsigned long) floatFromVal (val);
159 tsprintf (buffer, sizeof(buffer),
160 "!immedbyte", (unsigned int) v & 0xff);
163 tsprintf (buffer, sizeof(buffer),
164 "!immedword", (unsigned int) v & 0xffff);
167 /* Hmm. Too big for now. */
170 return Safe_strdup (buffer);
173 /* PENDING: For now size must be 1 */
176 /* it is type float */
177 fl.f = (float) floatFromVal (val);
178 #ifdef WORDS_BIGENDIAN
179 tsprintf (buffer, sizeof(buffer),
180 "!immedbyte", fl.c[3 - offset]);
182 tsprintf (buffer, sizeof(buffer),
183 "!immedbyte", fl.c[offset]);
185 return Safe_strdup (buffer);
188 /*-----------------------------------------------------------------*/
189 /* aopLiteral - string from a literal value */
190 /*-----------------------------------------------------------------*/
192 aopLiteral (value * val, int offset)
194 return aopLiteralLong (val, offset, 1);
197 /*-----------------------------------------------------------------*/
198 /* emitRegularMap - emit code for maps with no special cases */
199 /*-----------------------------------------------------------------*/
201 emitRegularMap (memmap * map, bool addPublics, bool arFlag)
211 /* PENDING: special case here - should remove */
212 if (!strcmp (map->sname, CODE_NAME))
213 tfprintf (map->oFile, "\t!areacode\n", map->sname);
214 else if (!strcmp (map->sname, DATA_NAME))
215 tfprintf (map->oFile, "\t!areadata\n", map->sname);
216 else if (!strcmp (map->sname, HOME_NAME))
217 tfprintf (map->oFile, "\t!areahome\n", map->sname);
219 tfprintf (map->oFile, "\t!area\n", map->sname);
222 for (sym = setFirstItem (map->syms); sym;
223 sym = setNextItem (map->syms))
227 /* if extern then add it into the extern list */
228 if (IS_EXTERN (sym->etype))
230 addSetHead (&externs, sym);
234 /* if allocation required check is needed
235 then check if the symbol really requires
236 allocation only for local variables */
238 if (arFlag && !IS_AGGREGATE (sym->type) &&
239 !(sym->_isparm && !IS_REGPARM (sym->etype)) &&
240 !sym->allocreq && sym->level)
243 /* for bitvar locals and parameters */
244 if (!arFlag && !sym->allocreq && sym->level
245 && !SPEC_ABSA (sym->etype)) {
249 /* if global variable & not static or extern
250 and addPublics allowed then add it to the public set */
251 if ((sym->level == 0 ||
252 (sym->_isparm && !IS_REGPARM (sym->etype))) &&
254 !IS_STATIC (sym->etype) &&
255 (IS_FUNC(sym->type) ? (sym->used || IFFUNC_HASBODY(sym->type)) : 1))
257 addSetHead (&publics, sym);
260 /* if extern then do nothing or is a function
262 if (IS_FUNC (sym->type))
265 /* print extra debug info if required */
268 if (!sym->level) /* global */
270 if (IS_STATIC (sym->etype))
271 fprintf (map->oFile, "F%s$", moduleName); /* scope is file */
273 fprintf (map->oFile, "G$"); /* scope is global */
277 /* symbol is local */
278 fprintf (map->oFile, "L%s$", (sym->localof ? sym->localof->name : "-null-"));
280 fprintf (map->oFile, "%s$%d$%d", sym->name, sym->level, sym->block);
283 /* if it has an initial value then do it only if
284 it is a global variable */
285 if (sym->ival && sym->level == 0) {
286 if (SPEC_OCLS(sym->etype)==xidata) {
287 // create a new "XINIT (CODE)" symbol, that will be emitted later
288 newSym=copySymbol (sym);
289 SPEC_OCLS(newSym->etype)=xinit;
290 SNPRINTF (newSym->name, sizeof(newSym->name), "__xinit_%s", sym->name);
291 SNPRINTF (newSym->rname, sizeof(newSym->rname), "__xinit_%s", sym->rname);
292 SPEC_CONST(newSym->etype)=1;
293 SPEC_STAT(newSym->etype)=1;
294 resolveIvalSym(newSym->ival);
296 // add it to the "XINIT (CODE)" segment
297 addSet(&xinit->syms, newSym);
300 if (IS_AGGREGATE (sym->type)) {
301 ival = initAggregates (sym, sym->ival, NULL);
303 if (getNelements(sym->type, sym->ival)>1) {
304 werror (W_EXCESS_INITIALIZERS, "scalar",
305 sym->name, sym->lineDef);
307 ival = newNode ('=', newAst_VALUE (symbolVal (sym)),
308 decorateType (resolveSymbols (list2expr (sym->ival))));
310 codeOutFile = statsg->oFile;
313 // set ival's lineno to where the symbol was defined
314 setAstLineno (ival, lineno=sym->lineDef);
315 // check if this is not a constant expression
316 if (!constExprTree(ival)) {
317 werror (E_CONST_EXPECTED, "found expression");
318 // but try to do it anyway
321 eBBlockFromiCode (iCodeFromAst (ival));
328 /* if is has an absolute address then generate
329 an equate for this no need to allocate space */
330 if (SPEC_ABSA (sym->etype))
334 fprintf (map->oFile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
336 if (TARGET_IS_XA51) {
339 } else if (map==bit || map==sfrbit) {
343 fprintf (map->oFile, "%s\t%s\t0x%04x\n",
345 SPEC_ADDR (sym->etype));
348 int size = getSize (sym->type);
350 werror(E_UNKNOWN_SIZE,sym->name);
354 fprintf (map->oFile, "==.\n");
356 if (IS_STATIC (sym->etype))
357 tfprintf (map->oFile, "!slabeldef\n", sym->rname);
359 tfprintf (map->oFile, "!labeldef\n", sym->rname);
360 tfprintf (map->oFile, "\t!ds\n",
361 (unsigned int) size & 0xffff);
366 /*-----------------------------------------------------------------*/
367 /* initPointer - pointer initialization code massaging */
368 /*-----------------------------------------------------------------*/
370 initPointer (initList * ilist, sym_link *toType)
373 ast *expr = list2expr (ilist);
378 /* try it the oldway first */
379 if ((val = constExprValue (expr, FALSE)))
382 /* ( ptr + constant ) */
383 if (IS_AST_OP (expr) &&
384 (expr->opval.op == '+' || expr->opval.op == '-') &&
385 IS_AST_SYM_VALUE (expr->left) &&
386 (IS_ARRAY(expr->left->ftype) || IS_PTR(expr->left->ftype)) &&
387 compareType(toType, expr->left->ftype) &&
388 IS_AST_LIT_VALUE (expr->right)) {
389 return valForCastAggr (expr->left, expr->left->ftype,
395 if (IS_AST_OP(expr) && expr->opval.op==CAST &&
396 IS_AST_OP(expr->right) && expr->right->opval.op=='&') {
397 if (compareType(toType, expr->left->ftype)!=1) {
398 werror (W_INIT_WRONG);
399 printFromToType(expr->left->ftype, toType);
405 /* no then we have to do these cludgy checks */
406 /* pointers can be initialized with address of
407 a variable or address of an array element */
408 if (IS_AST_OP (expr) && expr->opval.op == '&') {
409 /* address of symbol */
410 if (IS_AST_SYM_VALUE (expr->left)) {
411 val = copyValue (AST_VALUE (expr->left));
412 val->type = newLink (DECLARATOR);
413 if (SPEC_SCLS (expr->left->etype) == S_CODE) {
414 DCL_TYPE (val->type) = CPOINTER;
415 DCL_PTR_CONST (val->type) = port->mem.code_ro;
417 else if (SPEC_SCLS (expr->left->etype) == S_XDATA)
418 DCL_TYPE (val->type) = FPOINTER;
419 else if (SPEC_SCLS (expr->left->etype) == S_XSTACK)
420 DCL_TYPE (val->type) = PPOINTER;
421 else if (SPEC_SCLS (expr->left->etype) == S_IDATA)
422 DCL_TYPE (val->type) = IPOINTER;
423 else if (SPEC_SCLS (expr->left->etype) == S_EEPROM)
424 DCL_TYPE (val->type) = EEPPOINTER;
426 DCL_TYPE (val->type) = POINTER;
427 val->type->next = expr->left->ftype;
428 val->etype = getSpec (val->type);
432 /* if address of indexed array */
433 if (IS_AST_OP (expr->left) && expr->left->opval.op == '[')
434 return valForArray (expr->left);
436 /* if address of structure element then
438 if (IS_AST_OP (expr->left) &&
439 expr->left->opval.op == '.') {
440 return valForStructElem (expr->left->left,
445 (&some_struct)->element */
446 if (IS_AST_OP (expr->left) &&
447 expr->left->opval.op == PTR_OP &&
448 IS_ADDRESS_OF_OP (expr->left->left)) {
449 return valForStructElem (expr->left->left->left,
453 /* case 3. (((char *) &a) +/- constant) */
454 if (IS_AST_OP (expr) &&
455 (expr->opval.op == '+' || expr->opval.op == '-') &&
456 IS_AST_OP (expr->left) && expr->left->opval.op == CAST &&
457 IS_AST_OP (expr->left->right) &&
458 expr->left->right->opval.op == '&' &&
459 IS_AST_LIT_VALUE (expr->right)) {
461 return valForCastAggr (expr->left->right->left,
462 expr->left->left->opval.lnk,
463 expr->right, expr->opval.op);
466 /* case 4. (char *)(array type) */
467 if (IS_CAST_OP(expr) && IS_AST_SYM_VALUE (expr->right) &&
468 IS_ARRAY(expr->right->ftype)) {
470 val = copyValue (AST_VALUE (expr->right));
471 val->type = newLink (DECLARATOR);
472 if (SPEC_SCLS (expr->right->etype) == S_CODE) {
473 DCL_TYPE (val->type) = CPOINTER;
474 DCL_PTR_CONST (val->type) = port->mem.code_ro;
476 else if (SPEC_SCLS (expr->right->etype) == S_XDATA)
477 DCL_TYPE (val->type) = FPOINTER;
478 else if (SPEC_SCLS (expr->right->etype) == S_XSTACK)
479 DCL_TYPE (val->type) = PPOINTER;
480 else if (SPEC_SCLS (expr->right->etype) == S_IDATA)
481 DCL_TYPE (val->type) = IPOINTER;
482 else if (SPEC_SCLS (expr->right->etype) == S_EEPROM)
483 DCL_TYPE (val->type) = EEPPOINTER;
485 DCL_TYPE (val->type) = POINTER;
486 val->type->next = expr->right->ftype->next;
487 val->etype = getSpec (val->type);
491 werror (E_INCOMPAT_PTYPES);
496 /*-----------------------------------------------------------------*/
497 /* printChar - formats and prints a characater string with DB */
498 /*-----------------------------------------------------------------*/
500 printChar (FILE * ofile, char *s, int plen)
503 int len = strlen (s);
508 while (len && pplen < plen)
511 while (i && *s && pplen < plen)
513 if (*s < ' ' || *s == '\"' || *s=='\\')
517 tfprintf (ofile, "\t!ascii\n", buf);
518 tfprintf (ofile, "\t!db !constbyte\n", (unsigned char)*s);
533 tfprintf (ofile, "\t!ascii\n", buf);
542 tfprintf (ofile, "\t!db !constbyte\n", 0);
545 /*-----------------------------------------------------------------*/
546 /* return the generic pointer high byte for a given pointer type. */
547 /*-----------------------------------------------------------------*/
549 pointerTypeToGPByte (const int p_type, const char *iname, const char *oname)
557 werror (E_CANNOT_USE_GENERIC_POINTER,
558 iname ? iname : "<null>",
559 oname ? oname : "<null>");
566 return GPTYPE_XSTACK;
568 fprintf (stderr, "*** internal error: unknown pointer type %d in GPByte.\n",
576 /*-----------------------------------------------------------------*/
577 /* printPointerType - generates ival for pointer type */
578 /*-----------------------------------------------------------------*/
580 _printPointerType (FILE * oFile, const char *name)
582 /* if (TARGET_IS_DS390) */
583 if (options.model == MODEL_FLAT24)
585 fprintf (oFile, "\t.byte %s,(%s >> 8),(%s >> 16)", name, name, name);
589 fprintf (oFile, "\t.byte %s,(%s >> 8)", name, name);
593 /*-----------------------------------------------------------------*/
594 /* printPointerType - generates ival for pointer type */
595 /*-----------------------------------------------------------------*/
597 printPointerType (FILE * oFile, const char *name)
599 _printPointerType (oFile, name);
600 fprintf (oFile, "\n");
603 /*-----------------------------------------------------------------*/
604 /* printGPointerType - generates ival for generic pointer type */
605 /*-----------------------------------------------------------------*/
607 printGPointerType (FILE * oFile, const char *iname, const char *oname,
608 const unsigned int type)
610 _printPointerType (oFile, iname);
611 fprintf (oFile, ",#0x%02x\n", pointerTypeToGPByte (type, iname, oname));
614 /*-----------------------------------------------------------------*/
615 /* printIvalType - generates ival for int/char */
616 /*-----------------------------------------------------------------*/
618 printIvalType (symbol *sym, sym_link * type, initList * ilist, FILE * oFile)
622 /* if initList is deep */
623 if (ilist->type == INIT_DEEP)
624 ilist = ilist->init.deep;
626 if (!IS_AGGREGATE(sym->type) && getNelements(type, ilist)>1) {
627 werror (W_EXCESS_INITIALIZERS, "scalar", sym->name, sym->lineDef);
630 if (!(val = list2val (ilist))) {
631 // assuming a warning has been thrown
635 if (val->type != type) {
636 val = valCastLiteral(type, floatFromVal(val));
639 switch (getSize (type)) {
642 tfprintf (oFile, "\t!db !constbyte\n", 0);
644 tfprintf (oFile, "\t!dbs\n",
645 aopLiteral (val, 0));
649 if (port->use_dw_for_init)
650 tfprintf (oFile, "\t!dws\n", aopLiteralLong (val, 0, 2));
652 fprintf (oFile, "\t.byte %s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1));
656 tfprintf (oFile, "\t!dw !constword\n", 0);
657 tfprintf (oFile, "\t!dw !constword\n", 0);
660 fprintf (oFile, "\t.byte %s,%s,%s,%s\n",
661 aopLiteral (val, 0), aopLiteral (val, 1),
662 aopLiteral (val, 2), aopLiteral (val, 3));
668 /*-----------------------------------------------------------------*/
669 /* printIvalBitFields - generate initializer for bitfields */
670 /*-----------------------------------------------------------------*/
671 void printIvalBitFields(symbol **sym, initList **ilist, FILE * oFile)
675 initList *lilist = *ilist ;
676 unsigned long ival = 0;
682 val = list2val(lilist);
684 if (SPEC_BLEN(lsym->etype) > 8) {
685 size += ((SPEC_BLEN (lsym->etype) / 8) +
686 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
689 size = ((SPEC_BLEN (lsym->etype) / 8) +
690 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
692 i = (unsigned long)floatFromVal(val);
693 i <<= SPEC_BSTR (lsym->etype);
695 if (! ( lsym->next &&
696 (IS_BITFIELD(lsym->next->type)) &&
697 (SPEC_BSTR(lsym->next->etype)))) break;
699 lilist = lilist->next;
703 tfprintf (oFile, "\t!db !constbyte\n",ival);
707 tfprintf (oFile, "\t!dw !constword\n",ival);
710 tfprintf (oFile, "\t!db !constword,!constword\n",
711 (ival >> 8) & 0xffff, (ival & 0xffff));
718 /*-----------------------------------------------------------------*/
719 /* printIvalStruct - generates initial value for structures */
720 /*-----------------------------------------------------------------*/
722 printIvalStruct (symbol * sym, sym_link * type,
723 initList * ilist, FILE * oFile)
728 sflds = SPEC_STRUCT (type)->fields;
729 if (ilist->type != INIT_DEEP) {
730 werror (E_INIT_STRUCT, sym->name);
734 iloop = ilist->init.deep;
736 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL)) {
737 if (IS_BITFIELD(sflds->type)) {
738 printIvalBitFields(&sflds,&iloop,oFile);
740 printIval (sym, sflds->type, iloop, oFile);
744 werror (W_EXCESS_INITIALIZERS, "struct", sym->name, sym->lineDef);
749 /*-----------------------------------------------------------------*/
750 /* printIvalChar - generates initital value for character array */
751 /*-----------------------------------------------------------------*/
753 printIvalChar (sym_link * type, initList * ilist, FILE * oFile, char *s)
761 val = list2val (ilist);
762 /* if the value is a character string */
763 if (IS_ARRAY (val->type) && IS_CHAR (val->etype))
765 if (!DCL_ELEM (type))
766 DCL_ELEM (type) = strlen (SPEC_CVAL (val->etype).v_char) + 1;
768 printChar (oFile, SPEC_CVAL (val->etype).v_char, DCL_ELEM (type));
770 if ((remain = (DCL_ELEM (type) - strlen (SPEC_CVAL (val->etype).v_char) - 1)) > 0)
772 tfprintf (oFile, "\t!db !constbyte\n", 0);
780 printChar (oFile, s, strlen (s) + 1);
784 /*-----------------------------------------------------------------*/
785 /* printIvalArray - generates code for array initialization */
786 /*-----------------------------------------------------------------*/
788 printIvalArray (symbol * sym, sym_link * type, initList * ilist,
792 int lcnt = 0, size = 0;
795 /* take care of the special case */
796 /* array of characters can be init */
798 if (IS_CHAR (type->next)) {
799 if (!IS_LITERAL(list2val(ilist)->etype)) {
800 werror (E_CONST_EXPECTED);
803 if (printIvalChar (type,
804 (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
805 oFile, SPEC_CVAL (sym->etype).v_char))
808 /* not the special case */
809 if (ilist->type != INIT_DEEP)
811 werror (E_INIT_STRUCT, sym->name);
815 iloop = ilist->init.deep;
816 lcnt = DCL_ELEM (type);
817 for (last_type = type->next;
818 last_type && IS_DECL(last_type) && DCL_ELEM (last_type);
819 last_type = last_type->next) {
820 lcnt *= DCL_ELEM (last_type);
826 printIval (sym, type->next, iloop, oFile);
827 iloop = (iloop ? iloop->next : NULL);
830 /* if not array limits given & we */
831 /* are out of initialisers then */
832 if (!DCL_ELEM (type) && !iloop)
835 /* no of elements given and we */
836 /* have generated for all of them */
838 /* if initializers left */
840 werror (W_EXCESS_INITIALIZERS, "array", sym->name, sym->lineDef);
846 /* if we have not been given a size */
847 if (!DCL_ELEM (type))
848 DCL_ELEM (type) = size;
853 /*-----------------------------------------------------------------*/
854 /* printIvalFuncPtr - generate initial value for function pointers */
855 /*-----------------------------------------------------------------*/
857 printIvalFuncPtr (sym_link * type, initList * ilist, FILE * oFile)
862 val = list2val (ilist);
865 // an error has been thrown allready
869 if (IS_LITERAL(val->etype)) {
870 if (compareType(type,val->etype)==0) {
871 werror (E_INCOMPAT_TYPES);
872 printFromToType (val->type, type);
874 printIvalCharPtr (NULL, type, val, oFile);
878 /* check the types */
879 if ((dLvl = compareType (val->type, type->next)) <= 0)
881 tfprintf (oFile, "\t!dw !constword\n", 0);
885 /* now generate the name */
888 if (port->use_dw_for_init)
890 tfprintf (oFile, "\t!dws\n", val->name);
894 printPointerType (oFile, val->name);
897 else if (port->use_dw_for_init)
899 tfprintf (oFile, "\t!dws\n", val->sym->rname);
903 printPointerType (oFile, val->sym->rname);
909 /*-----------------------------------------------------------------*/
910 /* printIvalCharPtr - generates initial values for character pointers */
911 /*-----------------------------------------------------------------*/
913 printIvalCharPtr (symbol * sym, sym_link * type, value * val, FILE * oFile)
917 /* PENDING: this is _very_ mcs51 specific, including a magic
919 It's also endin specific.
921 size = getSize (type);
923 if (val->name && strlen (val->name))
925 if (size == 1) /* This appears to be Z80 specific?? */
928 "\t!dbs\n", val->name);
930 else if (size == FPTRSIZE)
932 if (port->use_dw_for_init)
934 tfprintf (oFile, "\t!dws\n", val->name);
938 printPointerType (oFile, val->name);
941 else if (size == GPTRSIZE)
944 if (IS_PTR (val->type)) {
945 type = DCL_TYPE (val->type);
947 type = PTR_TYPE (SPEC_OCLS (val->etype));
949 if (val->sym && val->sym->isstrlit) {
950 // this is a literal string
953 printGPointerType (oFile, val->name, sym->name, type);
957 fprintf (stderr, "*** internal error: unknown size in "
958 "printIvalCharPtr.\n");
963 // these are literals assigned to pointers
967 tfprintf (oFile, "\t!dbs\n", aopLiteral (val, 0));
970 if (port->use_dw_for_init)
971 tfprintf (oFile, "\t!dws\n", aopLiteralLong (val, 0, size));
973 tfprintf (oFile, "\t.byte %s,%s\n",
974 aopLiteral (val, 0), aopLiteral (val, 1));
977 if (IS_GENPTR(type) && floatFromVal(val)!=0) {
978 // non-zero mcs51 generic pointer
979 werror (E_LITERAL_GENERIC);
981 fprintf (oFile, "\t.byte %s,%s,%s\n",
984 aopLiteral (val, 2));
987 if (IS_GENPTR(type) && floatFromVal(val)!=0) {
988 // non-zero ds390 generic pointer
989 werror (E_LITERAL_GENERIC);
991 fprintf (oFile, "\t.byte %s,%s,%s,%s\n",
995 aopLiteral (val, 3));
1002 if (val->sym && val->sym->isstrlit && !isinSet(statsg->syms, val->sym)) {
1003 addSet (&statsg->syms, val->sym);
1009 /*-----------------------------------------------------------------*/
1010 /* printIvalPtr - generates initial value for pointers */
1011 /*-----------------------------------------------------------------*/
1013 printIvalPtr (symbol * sym, sym_link * type, initList * ilist, FILE * oFile)
1019 if (ilist->type == INIT_DEEP)
1020 ilist = ilist->init.deep;
1022 /* function pointer */
1023 if (IS_FUNC (type->next))
1025 printIvalFuncPtr (type, ilist, oFile);
1029 if (!(val = initPointer (ilist, type)))
1032 /* if character pointer */
1033 if (IS_CHAR (type->next))
1034 if (printIvalCharPtr (sym, type, val, oFile))
1037 /* check the type */
1038 if (compareType (type, val->type) == 0) {
1039 werror (W_INIT_WRONG);
1040 printFromToType (val->type, type);
1043 /* if val is literal */
1044 if (IS_LITERAL (val->etype))
1046 switch (getSize (type))
1049 tfprintf (oFile, "\t!db !constbyte\n", (unsigned int) floatFromVal (val) & 0xff);
1052 if (port->use_dw_for_init)
1053 tfprintf (oFile, "\t!dws\n", aopLiteralLong (val, 0, 2));
1055 tfprintf (oFile, "\t.byte %s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1));
1057 case 3: // how about '390??
1058 fprintf (oFile, "\t.byte %s,%s,#0x%d\n",
1059 aopLiteral (val, 0), aopLiteral (val, 1), GPTYPE_CODE);
1065 size = getSize (type);
1067 if (size == 1) /* Z80 specific?? */
1069 tfprintf (oFile, "\t!dbs\n", val->name);
1071 else if (size == FPTRSIZE)
1073 if (port->use_dw_for_init) {
1074 tfprintf (oFile, "\t!dws\n", val->name);
1076 printPointerType (oFile, val->name);
1079 else if (size == GPTRSIZE)
1081 printGPointerType (oFile, val->name, sym->name,
1082 (IS_PTR (val->type) ? DCL_TYPE (val->type) :
1083 PTR_TYPE (SPEC_OCLS (val->etype))));
1088 /*-----------------------------------------------------------------*/
1089 /* printIval - generates code for initial value */
1090 /*-----------------------------------------------------------------*/
1092 printIval (symbol * sym, sym_link * type, initList * ilist, FILE * oFile)
1097 /* update line number for error msgs */
1098 lineno=sym->lineDef;
1100 /* if structure then */
1101 if (IS_STRUCT (type))
1103 printIvalStruct (sym, type, ilist, oFile);
1107 /* if this is a pointer */
1110 printIvalPtr (sym, type, ilist, oFile);
1114 /* if this is an array */
1115 if (IS_ARRAY (type))
1117 printIvalArray (sym, type, ilist, oFile);
1121 /* if type is SPECIFIER */
1124 printIvalType (sym, type, ilist, oFile);
1129 /*-----------------------------------------------------------------*/
1130 /* emitStaticSeg - emitcode for the static segment */
1131 /*-----------------------------------------------------------------*/
1133 emitStaticSeg (memmap * map, FILE * out)
1137 /* fprintf(out, "\t.area\t%s\n", map->sname); */
1139 /* for all variables in this segment do */
1140 for (sym = setFirstItem (map->syms); sym;
1141 sym = setNextItem (map->syms))
1144 /* if it is "extern" then do nothing */
1145 if (IS_EXTERN (sym->etype))
1148 /* if it is not static add it to the public
1150 if (!IS_STATIC (sym->etype))
1152 addSetHead (&publics, sym);
1155 /* print extra debug info if required */
1156 if (options.debug) {
1160 if (IS_STATIC (sym->etype))
1161 fprintf (out, "F%s$", moduleName); /* scope is file */
1163 fprintf (out, "G$"); /* scope is global */
1166 /* symbol is local */
1167 fprintf (out, "L%s$",
1168 (sym->localof ? sym->localof->name : "-null-"));
1169 fprintf (out, "%s$%d$%d", sym->name, sym->level, sym->block);
1172 /* if it has an absolute address */
1173 if (SPEC_ABSA (sym->etype))
1176 fprintf (out, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1178 fprintf (out, "%s\t=\t0x%04x\n",
1180 SPEC_ADDR (sym->etype));
1185 fprintf (out, " == .\n");
1187 /* if it has an initial value */
1190 fprintf (out, "%s:\n", sym->rname);
1192 resolveIvalSym (sym->ival);
1193 printIval (sym, sym->type, sym->ival, out);
1195 /* if sym is a simple string and sym->ival is a string,
1196 WE don't need it anymore */
1197 if (IS_ARRAY(sym->type) && IS_CHAR(sym->type->next) &&
1198 IS_AST_SYM_VALUE(list2expr(sym->ival)) &&
1199 list2val(sym->ival)->sym->isstrlit) {
1200 freeStringSymbol(list2val(sym->ival)->sym);
1204 /* allocate space */
1205 int size = getSize (sym->type);
1208 werror(E_UNKNOWN_SIZE,sym->name);
1210 fprintf (out, "%s:\n", sym->rname);
1211 /* special case for character strings */
1212 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1213 SPEC_CVAL (sym->etype).v_char)
1215 SPEC_CVAL (sym->etype).v_char,
1216 strlen (SPEC_CVAL (sym->etype).v_char) + 1);
1218 tfprintf (out, "\t!ds\n", (unsigned int) size & 0xffff);
1224 /*-----------------------------------------------------------------*/
1225 /* emitMaps - emits the code for the data portion the code */
1226 /*-----------------------------------------------------------------*/
1231 /* no special considerations for the following
1232 data, idata & bit & xdata */
1233 emitRegularMap (data, TRUE, TRUE);
1234 emitRegularMap (idata, TRUE, TRUE);
1235 emitRegularMap (bit, TRUE, FALSE);
1236 emitRegularMap (xdata, TRUE, TRUE);
1237 if (port->genXINIT) {
1238 emitRegularMap (xidata, TRUE, TRUE);
1240 emitRegularMap (sfr, FALSE, FALSE);
1241 emitRegularMap (sfrbit, FALSE, FALSE);
1242 emitRegularMap (home, TRUE, FALSE);
1243 emitRegularMap (code, TRUE, FALSE);
1245 emitStaticSeg (statsg, code->oFile);
1246 if (port->genXINIT) {
1247 tfprintf (code->oFile, "\t!area\n", xinit->sname);
1248 emitStaticSeg (xinit, code->oFile);
1253 /*-----------------------------------------------------------------*/
1254 /* flushStatics - flush all currently defined statics out to file */
1255 /* and delete. Temporary function */
1256 /*-----------------------------------------------------------------*/
1260 emitStaticSeg (statsg, codeOutFile);
1261 statsg->syms = NULL;
1264 /*-----------------------------------------------------------------*/
1265 /* createInterruptVect - creates the interrupt vector */
1266 /*-----------------------------------------------------------------*/
1268 createInterruptVect (FILE * vFile)
1271 mainf = newSymbol ("main", 0);
1274 /* only if the main function exists */
1275 if (!(mainf = findSymWithLevel (SymbolTab, mainf)))
1277 if (!options.cc_only && !noAssemble && !options.c1mode)
1282 /* if the main is only a prototype ie. no body then do nothing */
1283 if (!IFFUNC_HASBODY(mainf->type))
1285 /* if ! compile only then main function should be present */
1286 if (!options.cc_only && !noAssemble)
1291 tfprintf (vFile, "\t!areacode\n", CODE_NAME);
1292 fprintf (vFile, "__interrupt_vect:\n");
1295 if (!port->genIVT || !(port->genIVT (vFile, interrupts, maxInterrupts)))
1297 /* "generic" interrupt table header (if port doesn't specify one).
1298 * Look suspiciously like 8051 code to me...
1301 fprintf (vFile, "\tljmp\t__sdcc_gsinit_startup\n");
1304 /* now for the other interrupts */
1305 for (; i < maxInterrupts; i++)
1308 fprintf (vFile, "\tljmp\t%s\n\t.ds\t5\n", interrupts[i]->rname);
1310 fprintf (vFile, "\treti\n\t.ds\t7\n");
1317 ";--------------------------------------------------------\n"
1318 "; File Created by SDCC : FreeWare ANSI-C Compiler\n"};
1322 ";--------------------------------------------------------\n"};
1325 /*-----------------------------------------------------------------*/
1326 /* initialComments - puts in some initial comments */
1327 /*-----------------------------------------------------------------*/
1329 initialComments (FILE * afile)
1333 fprintf (afile, "%s", iComments1);
1334 fprintf (afile, "; Version %s %s\n", VersionString, asctime (localtime (&t)));
1335 fprintf (afile, "%s", iComments2);
1338 /*-----------------------------------------------------------------*/
1339 /* printPublics - generates .global for publics */
1340 /*-----------------------------------------------------------------*/
1342 printPublics (FILE * afile)
1346 fprintf (afile, "%s", iComments2);
1347 fprintf (afile, "; Public variables in this module\n");
1348 fprintf (afile, "%s", iComments2);
1350 for (sym = setFirstItem (publics); sym;
1351 sym = setNextItem (publics))
1352 tfprintf (afile, "\t!global\n", sym->rname);
1355 /*-----------------------------------------------------------------*/
1356 /* printExterns - generates .global for externs */
1357 /*-----------------------------------------------------------------*/
1359 printExterns (FILE * afile)
1363 fprintf (afile, "%s", iComments2);
1364 fprintf (afile, "; Externals used\n");
1365 fprintf (afile, "%s", iComments2);
1367 for (sym = setFirstItem (externs); sym;
1368 sym = setNextItem (externs))
1369 tfprintf (afile, "\t!extern\n", sym->rname);
1372 /*-----------------------------------------------------------------*/
1373 /* emitOverlay - will emit code for the overlay stuff */
1374 /*-----------------------------------------------------------------*/
1376 emitOverlay (FILE * afile)
1380 if (!elementsInSet (ovrSetSets))
1381 tfprintf (afile, "\t!area\n", port->mem.overlay_name);
1383 /* for each of the sets in the overlay segment do */
1384 for (ovrset = setFirstItem (ovrSetSets); ovrset;
1385 ovrset = setNextItem (ovrSetSets))
1390 if (elementsInSet (ovrset))
1392 /* output the area informtion */
1393 fprintf (afile, "\t.area\t%s\n", port->mem.overlay_name); /* MOF */
1396 for (sym = setFirstItem (ovrset); sym;
1397 sym = setNextItem (ovrset))
1399 /* if extern then it is in the publics table: do nothing */
1400 if (IS_EXTERN (sym->etype))
1403 /* if allocation required check is needed
1404 then check if the symbol really requires
1405 allocation only for local variables */
1406 if (!IS_AGGREGATE (sym->type) &&
1407 !(sym->_isparm && !IS_REGPARM (sym->etype))
1408 && !sym->allocreq && sym->level)
1411 /* if global variable & not static or extern
1412 and addPublics allowed then add it to the public set */
1413 if ((sym->_isparm && !IS_REGPARM (sym->etype))
1414 && !IS_STATIC (sym->etype))
1416 addSetHead (&publics, sym);
1419 /* if extern then do nothing or is a function
1421 if (IS_FUNC (sym->type))
1424 /* print extra debug info if required */
1429 if (IS_STATIC (sym->etype))
1430 fprintf (afile, "F%s$", moduleName); /* scope is file */
1432 fprintf (afile, "G$"); /* scope is global */
1435 /* symbol is local */
1436 fprintf (afile, "L%s$",
1437 (sym->localof ? sym->localof->name : "-null-"));
1438 fprintf (afile, "%s$%d$%d", sym->name, sym->level, sym->block);
1441 /* if is has an absolute address then generate
1442 an equate for this no need to allocate space */
1443 if (SPEC_ABSA (sym->etype))
1447 fprintf (afile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1449 fprintf (afile, "%s\t=\t0x%04x\n",
1451 SPEC_ADDR (sym->etype));
1454 int size = getSize(sym->type);
1457 werror(E_UNKNOWN_SIZE,sym->name);
1460 fprintf (afile, "==.\n");
1462 /* allocate space */
1463 tfprintf (afile, "!labeldef\n", sym->rname);
1464 tfprintf (afile, "\t!ds\n", (unsigned int) getSize (sym->type) & 0xffff);
1471 /*-----------------------------------------------------------------*/
1472 /* glue - the final glue that hold the whole thing together */
1473 /*-----------------------------------------------------------------*/
1479 FILE *ovrFile = tempfile ();
1481 addSetHead (&tmpfileSet, ovrFile);
1482 /* print the global struct definitions */
1486 vFile = tempfile ();
1487 /* PENDING: this isnt the best place but it will do */
1488 if (port->general.glue_up_main)
1490 /* create the interrupt vector table */
1491 createInterruptVect (vFile);
1494 addSetHead (&tmpfileSet, vFile);
1496 /* emit code for the all the variables declared */
1498 /* do the overlay segments */
1499 emitOverlay (ovrFile);
1501 outputDebugSymbols();
1503 /* now put it all together into the assembler file */
1504 /* create the assembler file name */
1506 /* -o option overrides default name? */
1507 if ((noAssemble || options.c1mode) && fullDstFileName)
1509 strncpyz (scratchFileName, fullDstFileName, PATH_MAX);
1513 strncpyz (scratchFileName, dstFileName, PATH_MAX);
1514 strncatz (scratchFileName, port->assembler.file_ext, PATH_MAX);
1517 if (!(asmFile = fopen (scratchFileName, "w")))
1519 werror (E_FILE_OPEN_ERR, scratchFileName);
1523 /* initial comments */
1524 initialComments (asmFile);
1526 /* print module name */
1527 tfprintf (asmFile, "\t!module\n", moduleName);
1528 tfprintf (asmFile, "\t!fileprelude\n");
1530 /* Let the port generate any global directives, etc. */
1531 if (port->genAssemblerPreamble)
1533 port->genAssemblerPreamble (asmFile);
1536 /* print the global variables in this module */
1537 printPublics (asmFile);
1538 if (port->assembler.externGlobal)
1539 printExterns (asmFile);
1541 /* copy the sfr segment */
1542 fprintf (asmFile, "%s", iComments2);
1543 fprintf (asmFile, "; special function registers\n");
1544 fprintf (asmFile, "%s", iComments2);
1545 copyFile (asmFile, sfr->oFile);
1547 /* copy the sbit segment */
1548 fprintf (asmFile, "%s", iComments2);
1549 fprintf (asmFile, "; special function bits \n");
1550 fprintf (asmFile, "%s", iComments2);
1551 copyFile (asmFile, sfrbit->oFile);
1553 /*JCF: Create the areas for the register banks*/
1554 if(port->general.glue_up_main &&
1555 (TARGET_IS_MCS51 || TARGET_IS_DS390 || TARGET_IS_XA51))
1557 if(RegBankUsed[0]||RegBankUsed[1]||RegBankUsed[2]||RegBankUsed[3])
1559 fprintf (asmFile, "%s", iComments2);
1560 fprintf (asmFile, "; overlayable register banks \n");
1561 fprintf (asmFile, "%s", iComments2);
1563 fprintf (asmFile, "\t.area REG_BANK_0\t(REL,OVR,DATA)\n\t.ds 8\n");
1564 if(RegBankUsed[1]||options.parms_in_bank1)
1565 fprintf (asmFile, "\t.area REG_BANK_1\t(REL,OVR,DATA)\n\t.ds 8\n");
1567 fprintf (asmFile, "\t.area REG_BANK_2\t(REL,OVR,DATA)\n\t.ds 8\n");
1569 fprintf (asmFile, "\t.area REG_BANK_3\t(REL,OVR,DATA)\n\t.ds 8\n");
1573 /* copy the data segment */
1574 fprintf (asmFile, "%s", iComments2);
1575 fprintf (asmFile, "; internal ram data\n");
1576 fprintf (asmFile, "%s", iComments2);
1577 copyFile (asmFile, data->oFile);
1580 /* create the overlay segments */
1582 fprintf (asmFile, "%s", iComments2);
1583 fprintf (asmFile, "; overlayable items in internal ram \n");
1584 fprintf (asmFile, "%s", iComments2);
1585 copyFile (asmFile, ovrFile);
1588 /* create the stack segment MOF */
1589 if (mainf && IFFUNC_HASBODY(mainf->type))
1591 fprintf (asmFile, "%s", iComments2);
1592 fprintf (asmFile, "; Stack segment in internal ram \n");
1593 fprintf (asmFile, "%s", iComments2);
1594 fprintf (asmFile, "\t.area\tSSEG\t(DATA)\n"
1595 "__start__stack:\n\t.ds\t1\n\n");
1598 /* create the idata segment */
1600 fprintf (asmFile, "%s", iComments2);
1601 fprintf (asmFile, "; indirectly addressable internal ram data\n");
1602 fprintf (asmFile, "%s", iComments2);
1603 copyFile (asmFile, idata->oFile);
1606 /* copy the bit segment */
1607 fprintf (asmFile, "%s", iComments2);
1608 fprintf (asmFile, "; bit data\n");
1609 fprintf (asmFile, "%s", iComments2);
1610 copyFile (asmFile, bit->oFile);
1612 /* if external stack then reserve space of it */
1613 if (mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack)
1615 fprintf (asmFile, "%s", iComments2);
1616 fprintf (asmFile, "; external stack \n");
1617 fprintf (asmFile, "%s", iComments2);
1618 fprintf (asmFile, "\t.area XSEG (XDATA)\n"); /* MOF */
1619 fprintf (asmFile, "\t.ds 256\n");
1623 /* copy xtern ram data */
1624 fprintf (asmFile, "%s", iComments2);
1625 fprintf (asmFile, "; external ram data\n");
1626 fprintf (asmFile, "%s", iComments2);
1627 copyFile (asmFile, xdata->oFile);
1629 /* copy xternal initialized ram data */
1630 fprintf (asmFile, "%s", iComments2);
1631 fprintf (asmFile, "; external initialized ram data\n");
1632 fprintf (asmFile, "%s", iComments2);
1633 copyFile (asmFile, xidata->oFile);
1635 /* copy the interrupt vector table */
1636 if (mainf && IFFUNC_HASBODY(mainf->type))
1638 fprintf (asmFile, "%s", iComments2);
1639 fprintf (asmFile, "; interrupt vector \n");
1640 fprintf (asmFile, "%s", iComments2);
1641 copyFile (asmFile, vFile);
1644 /* copy global & static initialisations */
1645 fprintf (asmFile, "%s", iComments2);
1646 fprintf (asmFile, "; global & static initialisations\n");
1647 fprintf (asmFile, "%s", iComments2);
1649 /* Everywhere we generate a reference to the static_name area,
1650 * (which is currently only here), we immediately follow it with a
1651 * definition of the post_static_name area. This guarantees that
1652 * the post_static_name area will immediately follow the static_name
1655 tfprintf (asmFile, "\t!area\n", port->mem.static_name); /* MOF */
1656 tfprintf (asmFile, "\t!area\n", port->mem.post_static_name);
1657 tfprintf (asmFile, "\t!area\n", port->mem.static_name);
1659 if (mainf && IFFUNC_HASBODY(mainf->type))
1661 fprintf (asmFile, "__sdcc_gsinit_startup:\n");
1662 /* if external stack is specified then the
1663 higher order byte of the xdatalocation is
1664 going into P2 and the lower order going into
1666 if (options.useXstack)
1668 fprintf (asmFile, "\tmov\tP2,#0x%02x\n",
1669 (((unsigned int) options.xdata_loc) >> 8) & 0xff);
1670 fprintf (asmFile, "\tmov\t_spx,#0x%02x\n",
1671 (unsigned int) options.xdata_loc & 0xff);
1674 /* initialise the stack pointer. JCF: aslink takes care of the location */
1675 fprintf (asmFile, "\tmov\tsp,#__start__stack - 1\n"); /* MOF */
1677 fprintf (asmFile, "\tlcall\t__sdcc_external_startup\n");
1678 fprintf (asmFile, "\tmov\ta,dpl\n");
1679 fprintf (asmFile, "\tjz\t__sdcc_init_data\n");
1680 fprintf (asmFile, "\tljmp\t__sdcc_program_startup\n");
1681 fprintf (asmFile, "__sdcc_init_data:\n");
1683 // if the port can copy the XINIT segment to XISEG
1684 if (port->genXINIT) {
1685 port->genXINIT(asmFile);
1689 copyFile (asmFile, statsg->oFile);
1691 if (port->general.glue_up_main && mainf && IFFUNC_HASBODY(mainf->type))
1693 /* This code is generated in the post-static area.
1694 * This area is guaranteed to follow the static area
1695 * by the ugly shucking and jiving about 20 lines ago.
1697 tfprintf (asmFile, "\t!area\n", port->mem.post_static_name);
1698 fprintf (asmFile, "\tljmp\t__sdcc_program_startup\n");
1704 "%s", iComments2, iComments2);
1705 tfprintf (asmFile, "\t!areahome\n", HOME_NAME);
1706 copyFile (asmFile, home->oFile);
1708 /* copy over code */
1709 fprintf (asmFile, "%s", iComments2);
1710 fprintf (asmFile, "; code\n");
1711 fprintf (asmFile, "%s", iComments2);
1712 tfprintf (asmFile, "\t!areacode\n", CODE_NAME);
1713 if (mainf && IFFUNC_HASBODY(mainf->type))
1716 /* entry point @ start of CSEG */
1717 fprintf (asmFile, "__sdcc_program_startup:\n");
1719 /* put in the call to main */
1720 fprintf (asmFile, "\tlcall\t_main\n");
1721 if (options.mainreturn)
1724 fprintf (asmFile, ";\treturn from main ; will return to caller\n");
1725 fprintf (asmFile, "\tret\n");
1731 fprintf (asmFile, ";\treturn from main will lock up\n");
1732 fprintf (asmFile, "\tsjmp .\n");
1735 copyFile (asmFile, code->oFile);
1737 if (port->genAssemblerEnd) {
1738 port->genAssemblerEnd(asmFile);
1746 /** Creates a temporary file with unoque file name
1748 - TMP, TEMP, TMPDIR env. varibles
1749 - if Un*x system: /usr/tmp and /tmp
1750 - root directory using mkstemp() if avaliable
1751 - default location using tempnam()
1754 tempfileandname(char *fname, size_t len)
1756 #define TEMPLATE "sdccXXXXXX"
1757 #define TEMPLATE_LEN ((sizeof TEMPLATE) - 1)
1759 const char *tmpdir = NULL;
1762 if ((tmpdir = getenv ("TMP")) == NULL)
1763 if ((tmpdir = getenv ("TEMP")) == NULL)
1764 tmpdir = getenv ("TMPDIR");
1768 /* try with /usr/tmp and /tmp on Un*x systems */
1769 struct stat statbuf;
1771 if (tmpdir == NULL) {
1772 if (stat("/usr/tmp", &statbuf) != -1)
1773 tmpdir = "/usr/tmp";
1774 else if (stat("/tmp", &statbuf) != -1)
1782 char fnamebuf[PATH_MAX];
1785 if (fname == NULL || len == 0) {
1787 len = sizeof fnamebuf;
1791 name_len = strlen(tmpdir) + 1 + TEMPLATE_LEN;
1793 assert(name_len < len);
1794 if (!(name_len < len)) /* in NDEBUG is defined */
1795 return -1; /* buffer too small, temporary file can not be created */
1797 sprintf(fname, "%s" DIR_SEPARATOR_STRING TEMPLATE, tmpdir);
1800 name_len = TEMPLATE_LEN;
1802 assert(name_len < len);
1803 if (!(name_len < len)) /* in NDEBUG is defined */
1804 return -1; /* buffer too small, temporary file can not be created */
1806 strcpy(fname, TEMPLATE);
1809 fd = mkstemp(fname);
1813 char *name = tempnam(tmpdir, "sdcc");
1816 perror("Can't create temporary file name");
1820 assert(strlen(name) < len);
1821 if (!(strlen(name) < len)) /* in NDEBUG is defined */
1822 return -1; /* buffer too small, temporary file can not be created */
1824 strcpy(fname, name);
1826 fd = open(name, O_CREAT | O_EXCL | O_RDWR, S_IREAD | S_IWRITE);
1828 fd = open(name, O_CREAT | O_EXCL | O_RDWR, S_IRUSR | S_IWUSR);
1834 perror("Can't create temporary file");
1842 /** Create a temporary file name
1848 static char fnamebuf[PATH_MAX];
1850 if ((fd = tempfileandname(fnamebuf, sizeof fnamebuf)) == -1) {
1851 fprintf(stderr, "Can't create temporary file name!");
1862 /** Create a temporary file and add it to tmpfileNameSet,
1863 so that it is removed explicitly by rm_tmpfiles()
1864 or implicitly at program extit.
1872 char fnamebuf[PATH_MAX];
1874 if ((fd = tempfileandname(fnamebuf, sizeof fnamebuf)) == -1) {
1875 fprintf(stderr, "Can't create temporary file!");
1879 tmp = Safe_strdup(fnamebuf);
1881 addSetHead(&tmpfileNameSet, tmp);
1883 if ((fp = fdopen(fd, "w+b")) == NULL) {
1884 perror("Can't create temporary file!");