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 set *pipeSet = NULL; /* set of pipes */
49 set *tmpfileSet = NULL; /* set of tmp file created by the compiler */
50 set *tmpfileNameSet = NULL; /* All are unlinked at close. */
52 /*-----------------------------------------------------------------*/
53 /* closePipes - closes all pipes created by the compiler */
54 /*-----------------------------------------------------------------*/
55 DEFSETFUNC (closePipes)
68 /*-----------------------------------------------------------------*/
69 /* closeTmpFiles - closes all tmp files created by the compiler */
70 /* because of BRAIN DEAD MS/DOS & CYGNUS Libraries */
71 /*-----------------------------------------------------------------*/
72 DEFSETFUNC (closeTmpFiles)
85 /*-----------------------------------------------------------------*/
86 /* rmTmpFiles - unlinks all tmp files created by the compiler */
87 /* because of BRAIN DEAD MS/DOS & CYGNUS Libraries */
88 /*-----------------------------------------------------------------*/
89 DEFSETFUNC (rmTmpFiles)
103 /*-----------------------------------------------------------------*/
104 /* rm_tmpfiles - close and remove temporary files and delete sets */
105 /*-----------------------------------------------------------------*/
109 /* close temporary files */
110 applyToSet (pipeSet, closePipes);
111 /* close temporary files */
112 deleteSet (&pipeSet);
114 applyToSet (tmpfileSet, closeTmpFiles);
115 /* remove temporary files */
116 applyToSet (tmpfileNameSet, rmTmpFiles);
117 /* delete temorary file sets */
118 deleteSet (&tmpfileSet);
119 deleteSet (&tmpfileNameSet);
122 /*-----------------------------------------------------------------*/
123 /* copyFile - copies source file to destination file */
124 /*-----------------------------------------------------------------*/
126 copyFile (FILE * dest, FILE * src)
132 if ((ch = fgetc (src)) != EOF)
137 aopLiteralLong (value * val, int offset, int size)
146 // assuming we have been warned before
150 /* if it is a float then it gets tricky */
151 /* otherwise it is fairly simple */
152 if (!IS_FLOAT (val->type)) {
153 unsigned long v = (unsigned long) floatFromVal (val);
158 tsprintf (buffer, sizeof(buffer),
159 "!immedbyte", (unsigned int) v & 0xff);
162 tsprintf (buffer, sizeof(buffer),
163 "!immedword", (unsigned int) v & 0xffff);
166 /* Hmm. Too big for now. */
169 return Safe_strdup (buffer);
172 /* PENDING: For now size must be 1 */
175 /* it is type float */
176 fl.f = (float) floatFromVal (val);
177 #ifdef WORDS_BIGENDIAN
178 tsprintf (buffer, sizeof(buffer),
179 "!immedbyte", fl.c[3 - offset]);
181 tsprintf (buffer, sizeof(buffer),
182 "!immedbyte", fl.c[offset]);
184 return Safe_strdup (buffer);
187 /*-----------------------------------------------------------------*/
188 /* aopLiteral - string from a literal value */
189 /*-----------------------------------------------------------------*/
191 aopLiteral (value * val, int offset)
193 return aopLiteralLong (val, offset, 1);
196 /*-----------------------------------------------------------------*/
197 /* emitRegularMap - emit code for maps with no special cases */
198 /*-----------------------------------------------------------------*/
200 emitRegularMap (memmap * map, bool addPublics, bool arFlag)
210 /* PENDING: special case here - should remove */
211 if (!strcmp (map->sname, CODE_NAME))
212 tfprintf (map->oFile, "\t!areacode\n", map->sname);
213 else if (!strcmp (map->sname, DATA_NAME))
214 tfprintf (map->oFile, "\t!areadata\n", map->sname);
215 else if (!strcmp (map->sname, HOME_NAME))
216 tfprintf (map->oFile, "\t!areahome\n", map->sname);
218 tfprintf (map->oFile, "\t!area\n", map->sname);
221 for (sym = setFirstItem (map->syms); sym;
222 sym = setNextItem (map->syms))
226 /* if extern then add it into the extern list */
227 if (IS_EXTERN (sym->etype))
229 addSetHead (&externs, sym);
233 /* if allocation required check is needed
234 then check if the symbol really requires
235 allocation only for local variables */
237 if (arFlag && !IS_AGGREGATE (sym->type) &&
238 !(sym->_isparm && !IS_REGPARM (sym->etype)) &&
239 !sym->allocreq && sym->level)
242 /* for bitvar locals and parameters */
243 if (!arFlag && !sym->allocreq && sym->level
244 && !SPEC_ABSA (sym->etype)) {
248 /* if global variable & not static or extern
249 and addPublics allowed then add it to the public set */
250 if ((sym->level == 0 ||
251 (sym->_isparm && !IS_REGPARM (sym->etype))) &&
253 !IS_STATIC (sym->etype) &&
254 (IS_FUNC(sym->type) ? (sym->used || IFFUNC_HASBODY(sym->type)) : 1))
256 addSetHead (&publics, sym);
259 /* if extern then do nothing or is a function
261 if (IS_FUNC (sym->type))
264 /* print extra debug info if required */
267 if (!sym->level) /* global */
269 if (IS_STATIC (sym->etype))
270 fprintf (map->oFile, "F%s$", moduleName); /* scope is file */
272 fprintf (map->oFile, "G$"); /* scope is global */
276 /* symbol is local */
277 fprintf (map->oFile, "L%s$", (sym->localof ? sym->localof->name : "-null-"));
279 fprintf (map->oFile, "%s$%d$%d", sym->name, sym->level, sym->block);
282 /* if it has an initial value then do it only if
283 it is a global variable */
284 if (sym->ival && sym->level == 0) {
285 if (SPEC_OCLS(sym->etype)==xidata) {
286 // create a new "XINIT (CODE)" symbol, that will be emitted later
287 newSym=copySymbol (sym);
288 SPEC_OCLS(newSym->etype)=xinit;
289 SNPRINTF (newSym->name, sizeof(newSym->name), "__xinit_%s", sym->name);
290 SNPRINTF (newSym->rname, sizeof(newSym->rname), "__xinit_%s", sym->rname);
291 SPEC_CONST(newSym->etype)=1;
292 SPEC_STAT(newSym->etype)=1;
293 resolveIvalSym(newSym->ival);
295 // add it to the "XINIT (CODE)" segment
296 addSet(&xinit->syms, newSym);
299 if (IS_AGGREGATE (sym->type)) {
300 ival = initAggregates (sym, sym->ival, NULL);
302 if (getNelements(sym->type, sym->ival)>1) {
303 werror (W_EXCESS_INITIALIZERS, "scalar",
304 sym->name, sym->lineDef);
306 ival = newNode ('=', newAst_VALUE (symbolVal (sym)),
307 decorateType (resolveSymbols (list2expr (sym->ival))));
309 codeOutFile = statsg->oFile;
312 // set ival's lineno to where the symbol was defined
313 setAstLineno (ival, lineno=sym->lineDef);
314 // check if this is not a constant expression
315 if (!constExprTree(ival)) {
316 werror (E_CONST_EXPECTED, "found expression");
317 // but try to do it anyway
320 eBBlockFromiCode (iCodeFromAst (ival));
327 /* if is has an absolute address then generate
328 an equate for this no need to allocate space */
329 if (SPEC_ABSA (sym->etype))
333 fprintf (map->oFile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
335 if (TARGET_IS_XA51) {
338 } else if (map==bit || map==sfrbit) {
342 fprintf (map->oFile, "%s\t%s\t0x%04x\n",
344 SPEC_ADDR (sym->etype));
347 int size = getSize (sym->type);
349 werror(E_UNKNOWN_SIZE,sym->name);
353 fprintf (map->oFile, "==.\n");
355 if (IS_STATIC (sym->etype))
356 tfprintf (map->oFile, "!slabeldef\n", sym->rname);
358 tfprintf (map->oFile, "!labeldef\n", sym->rname);
359 tfprintf (map->oFile, "\t!ds\n",
360 (unsigned int) size & 0xffff);
365 /*-----------------------------------------------------------------*/
366 /* initPointer - pointer initialization code massaging */
367 /*-----------------------------------------------------------------*/
369 initPointer (initList * ilist, sym_link *toType)
372 ast *expr = list2expr (ilist);
377 /* try it the oldway first */
378 if ((val = constExprValue (expr, FALSE)))
381 /* ( ptr + constant ) */
382 if (IS_AST_OP (expr) &&
383 (expr->opval.op == '+' || expr->opval.op == '-') &&
384 IS_AST_SYM_VALUE (expr->left) &&
385 (IS_ARRAY(expr->left->ftype) || IS_PTR(expr->left->ftype)) &&
386 compareType(toType, expr->left->ftype) &&
387 IS_AST_LIT_VALUE (expr->right)) {
388 return valForCastAggr (expr->left, expr->left->ftype,
394 if (IS_AST_OP(expr) && expr->opval.op==CAST &&
395 IS_AST_OP(expr->right) && expr->right->opval.op=='&') {
396 if (compareType(toType, expr->left->ftype)!=1) {
397 werror (W_INIT_WRONG);
398 printFromToType(expr->left->ftype, toType);
404 /* no then we have to do these cludgy checks */
405 /* pointers can be initialized with address of
406 a variable or address of an array element */
407 if (IS_AST_OP (expr) && expr->opval.op == '&') {
408 /* address of symbol */
409 if (IS_AST_SYM_VALUE (expr->left)) {
410 val = copyValue (AST_VALUE (expr->left));
411 val->type = newLink (DECLARATOR);
412 if (SPEC_SCLS (expr->left->etype) == S_CODE) {
413 DCL_TYPE (val->type) = CPOINTER;
414 DCL_PTR_CONST (val->type) = port->mem.code_ro;
416 else if (SPEC_SCLS (expr->left->etype) == S_XDATA)
417 DCL_TYPE (val->type) = FPOINTER;
418 else if (SPEC_SCLS (expr->left->etype) == S_XSTACK)
419 DCL_TYPE (val->type) = PPOINTER;
420 else if (SPEC_SCLS (expr->left->etype) == S_IDATA)
421 DCL_TYPE (val->type) = IPOINTER;
422 else if (SPEC_SCLS (expr->left->etype) == S_EEPROM)
423 DCL_TYPE (val->type) = EEPPOINTER;
425 DCL_TYPE (val->type) = POINTER;
426 val->type->next = expr->left->ftype;
427 val->etype = getSpec (val->type);
431 /* if address of indexed array */
432 if (IS_AST_OP (expr->left) && expr->left->opval.op == '[')
433 return valForArray (expr->left);
435 /* if address of structure element then
437 if (IS_AST_OP (expr->left) &&
438 expr->left->opval.op == '.') {
439 return valForStructElem (expr->left->left,
444 (&some_struct)->element */
445 if (IS_AST_OP (expr->left) &&
446 expr->left->opval.op == PTR_OP &&
447 IS_ADDRESS_OF_OP (expr->left->left)) {
448 return valForStructElem (expr->left->left->left,
452 /* case 3. (((char *) &a) +/- constant) */
453 if (IS_AST_OP (expr) &&
454 (expr->opval.op == '+' || expr->opval.op == '-') &&
455 IS_AST_OP (expr->left) && expr->left->opval.op == CAST &&
456 IS_AST_OP (expr->left->right) &&
457 expr->left->right->opval.op == '&' &&
458 IS_AST_LIT_VALUE (expr->right)) {
460 return valForCastAggr (expr->left->right->left,
461 expr->left->left->opval.lnk,
462 expr->right, expr->opval.op);
465 /* case 4. (char *)(array type) */
466 if (IS_CAST_OP(expr) && IS_AST_SYM_VALUE (expr->right) &&
467 IS_ARRAY(expr->right->ftype)) {
469 val = copyValue (AST_VALUE (expr->right));
470 val->type = newLink (DECLARATOR);
471 if (SPEC_SCLS (expr->right->etype) == S_CODE) {
472 DCL_TYPE (val->type) = CPOINTER;
473 DCL_PTR_CONST (val->type) = port->mem.code_ro;
475 else if (SPEC_SCLS (expr->right->etype) == S_XDATA)
476 DCL_TYPE (val->type) = FPOINTER;
477 else if (SPEC_SCLS (expr->right->etype) == S_XSTACK)
478 DCL_TYPE (val->type) = PPOINTER;
479 else if (SPEC_SCLS (expr->right->etype) == S_IDATA)
480 DCL_TYPE (val->type) = IPOINTER;
481 else if (SPEC_SCLS (expr->right->etype) == S_EEPROM)
482 DCL_TYPE (val->type) = EEPPOINTER;
484 DCL_TYPE (val->type) = POINTER;
485 val->type->next = expr->right->ftype->next;
486 val->etype = getSpec (val->type);
490 werror (E_INCOMPAT_PTYPES);
495 /*-----------------------------------------------------------------*/
496 /* printChar - formats and prints a characater string with DB */
497 /*-----------------------------------------------------------------*/
499 printChar (FILE * ofile, char *s, int plen)
502 int len = strlen (s);
507 while (len && pplen < plen)
510 while (i && *s && pplen < plen)
512 if (*s < ' ' || *s == '\"' || *s=='\\')
516 tfprintf (ofile, "\t!ascii\n", buf);
517 tfprintf (ofile, "\t!db !constbyte\n", (unsigned char)*s);
532 tfprintf (ofile, "\t!ascii\n", buf);
541 tfprintf (ofile, "\t!db !constbyte\n", 0);
544 /*-----------------------------------------------------------------*/
545 /* return the generic pointer high byte for a given pointer type. */
546 /*-----------------------------------------------------------------*/
548 pointerTypeToGPByte (const int p_type, const char *iname, const char *oname)
556 werror (E_CANNOT_USE_GENERIC_POINTER,
557 iname ? iname : "<null>",
558 oname ? oname : "<null>");
565 return GPTYPE_XSTACK;
567 fprintf (stderr, "*** internal error: unknown pointer type %d in GPByte.\n",
575 /*-----------------------------------------------------------------*/
576 /* printPointerType - generates ival for pointer type */
577 /*-----------------------------------------------------------------*/
579 _printPointerType (FILE * oFile, const char *name)
581 /* if (TARGET_IS_DS390) */
582 if (options.model == MODEL_FLAT24)
584 fprintf (oFile, "\t.byte %s,(%s >> 8),(%s >> 16)", name, name, name);
588 fprintf (oFile, "\t.byte %s,(%s >> 8)", name, name);
592 /*-----------------------------------------------------------------*/
593 /* printPointerType - generates ival for pointer type */
594 /*-----------------------------------------------------------------*/
596 printPointerType (FILE * oFile, const char *name)
598 _printPointerType (oFile, name);
599 fprintf (oFile, "\n");
602 /*-----------------------------------------------------------------*/
603 /* printGPointerType - generates ival for generic pointer type */
604 /*-----------------------------------------------------------------*/
606 printGPointerType (FILE * oFile, const char *iname, const char *oname,
607 const unsigned int type)
609 _printPointerType (oFile, iname);
610 fprintf (oFile, ",#0x%02x\n", pointerTypeToGPByte (type, iname, oname));
613 /*-----------------------------------------------------------------*/
614 /* printIvalType - generates ival for int/char */
615 /*-----------------------------------------------------------------*/
617 printIvalType (symbol *sym, sym_link * type, initList * ilist, FILE * oFile)
621 /* if initList is deep */
622 if (ilist->type == INIT_DEEP)
623 ilist = ilist->init.deep;
625 if (!IS_AGGREGATE(sym->type) && getNelements(type, ilist)>1) {
626 werror (W_EXCESS_INITIALIZERS, "scalar", sym->name, sym->lineDef);
629 if (!(val = list2val (ilist))) {
630 // assuming a warning has been thrown
634 if (val->type != type) {
635 val = valCastLiteral(type, floatFromVal(val));
638 switch (getSize (type)) {
641 tfprintf (oFile, "\t!db !constbyte\n", 0);
643 tfprintf (oFile, "\t!dbs\n",
644 aopLiteral (val, 0));
648 if (port->use_dw_for_init)
649 tfprintf (oFile, "\t!dws\n", aopLiteralLong (val, 0, 2));
651 fprintf (oFile, "\t.byte %s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1));
655 tfprintf (oFile, "\t!dw !constword\n", 0);
656 tfprintf (oFile, "\t!dw !constword\n", 0);
659 fprintf (oFile, "\t.byte %s,%s,%s,%s\n",
660 aopLiteral (val, 0), aopLiteral (val, 1),
661 aopLiteral (val, 2), aopLiteral (val, 3));
667 /*-----------------------------------------------------------------*/
668 /* printIvalBitFields - generate initializer for bitfields */
669 /*-----------------------------------------------------------------*/
670 void printIvalBitFields(symbol **sym, initList **ilist, FILE * oFile)
674 initList *lilist = *ilist ;
675 unsigned long ival = 0;
681 val = list2val(lilist);
683 if (SPEC_BLEN(lsym->etype) > 8) {
684 size += ((SPEC_BLEN (lsym->etype) / 8) +
685 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
688 size = ((SPEC_BLEN (lsym->etype) / 8) +
689 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
691 i = (unsigned long)floatFromVal(val);
692 i <<= SPEC_BSTR (lsym->etype);
694 if (! ( lsym->next &&
695 (IS_BITFIELD(lsym->next->type)) &&
696 (SPEC_BSTR(lsym->next->etype)))) break;
698 lilist = lilist->next;
702 tfprintf (oFile, "\t!db !constbyte\n",ival);
706 tfprintf (oFile, "\t!dw !constword\n",ival);
709 tfprintf (oFile, "\t!db !constword,!constword\n",
710 (ival >> 8) & 0xffff, (ival & 0xffff));
717 /*-----------------------------------------------------------------*/
718 /* printIvalStruct - generates initial value for structures */
719 /*-----------------------------------------------------------------*/
721 printIvalStruct (symbol * sym, sym_link * type,
722 initList * ilist, FILE * oFile)
727 sflds = SPEC_STRUCT (type)->fields;
728 if (ilist->type != INIT_DEEP) {
729 werror (E_INIT_STRUCT, sym->name);
733 iloop = ilist->init.deep;
735 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL)) {
736 if (IS_BITFIELD(sflds->type)) {
737 printIvalBitFields(&sflds,&iloop,oFile);
739 printIval (sym, sflds->type, iloop, oFile);
743 werror (W_EXCESS_INITIALIZERS, "struct", sym->name, sym->lineDef);
748 /*-----------------------------------------------------------------*/
749 /* printIvalChar - generates initital value for character array */
750 /*-----------------------------------------------------------------*/
752 printIvalChar (sym_link * type, initList * ilist, FILE * oFile, char *s)
760 val = list2val (ilist);
761 /* if the value is a character string */
762 if (IS_ARRAY (val->type) && IS_CHAR (val->etype))
764 if (!DCL_ELEM (type))
765 DCL_ELEM (type) = strlen (SPEC_CVAL (val->etype).v_char) + 1;
767 printChar (oFile, SPEC_CVAL (val->etype).v_char, DCL_ELEM (type));
769 if ((remain = (DCL_ELEM (type) - strlen (SPEC_CVAL (val->etype).v_char) - 1)) > 0)
771 tfprintf (oFile, "\t!db !constbyte\n", 0);
779 printChar (oFile, s, strlen (s) + 1);
783 /*-----------------------------------------------------------------*/
784 /* printIvalArray - generates code for array initialization */
785 /*-----------------------------------------------------------------*/
787 printIvalArray (symbol * sym, sym_link * type, initList * ilist,
791 int lcnt = 0, size = 0;
794 /* take care of the special case */
795 /* array of characters can be init */
797 if (IS_CHAR (type->next)) {
798 if (!IS_LITERAL(list2val(ilist)->etype)) {
799 werror (E_CONST_EXPECTED);
802 if (printIvalChar (type,
803 (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
804 oFile, SPEC_CVAL (sym->etype).v_char))
807 /* not the special case */
808 if (ilist->type != INIT_DEEP)
810 werror (E_INIT_STRUCT, sym->name);
814 iloop = ilist->init.deep;
815 lcnt = DCL_ELEM (type);
816 for (last_type = type->next;
817 last_type && IS_DECL(last_type) && DCL_ELEM (last_type);
818 last_type = last_type->next) {
819 lcnt *= DCL_ELEM (last_type);
825 printIval (sym, type->next, iloop, oFile);
826 iloop = (iloop ? iloop->next : NULL);
829 /* if not array limits given & we */
830 /* are out of initialisers then */
831 if (!DCL_ELEM (type) && !iloop)
834 /* no of elements given and we */
835 /* have generated for all of them */
837 /* if initializers left */
839 werror (W_EXCESS_INITIALIZERS, "array", sym->name, sym->lineDef);
845 /* if we have not been given a size */
846 if (!DCL_ELEM (type))
847 DCL_ELEM (type) = size;
852 /*-----------------------------------------------------------------*/
853 /* printIvalFuncPtr - generate initial value for function pointers */
854 /*-----------------------------------------------------------------*/
856 printIvalFuncPtr (sym_link * type, initList * ilist, FILE * oFile)
861 val = list2val (ilist);
864 // an error has been thrown allready
868 if (IS_LITERAL(val->etype)) {
869 if (compareType(type,val->etype)==0) {
870 werror (E_INCOMPAT_TYPES);
871 printFromToType (val->type, type);
873 printIvalCharPtr (NULL, type, val, oFile);
877 /* check the types */
878 if ((dLvl = compareType (val->type, type->next)) <= 0)
880 tfprintf (oFile, "\t!dw !constword\n", 0);
884 /* now generate the name */
887 if (port->use_dw_for_init)
889 tfprintf (oFile, "\t!dws\n", val->name);
893 printPointerType (oFile, val->name);
896 else if (port->use_dw_for_init)
898 tfprintf (oFile, "\t!dws\n", val->sym->rname);
902 printPointerType (oFile, val->sym->rname);
908 /*-----------------------------------------------------------------*/
909 /* printIvalCharPtr - generates initial values for character pointers */
910 /*-----------------------------------------------------------------*/
912 printIvalCharPtr (symbol * sym, sym_link * type, value * val, FILE * oFile)
916 /* PENDING: this is _very_ mcs51 specific, including a magic
918 It's also endin specific.
920 size = getSize (type);
922 if (val->name && strlen (val->name))
924 if (size == 1) /* This appears to be Z80 specific?? */
927 "\t!dbs\n", val->name);
929 else if (size == FPTRSIZE)
931 if (port->use_dw_for_init)
933 tfprintf (oFile, "\t!dws\n", val->name);
937 printPointerType (oFile, val->name);
940 else if (size == GPTRSIZE)
943 if (IS_PTR (val->type)) {
944 type = DCL_TYPE (val->type);
946 type = PTR_TYPE (SPEC_OCLS (val->etype));
948 if (val->sym && val->sym->isstrlit) {
949 // this is a literal string
952 printGPointerType (oFile, val->name, sym->name, type);
956 fprintf (stderr, "*** internal error: unknown size in "
957 "printIvalCharPtr.\n");
962 // these are literals assigned to pointers
966 tfprintf (oFile, "\t!dbs\n", aopLiteral (val, 0));
969 if (port->use_dw_for_init)
970 tfprintf (oFile, "\t!dws\n", aopLiteralLong (val, 0, size));
972 tfprintf (oFile, "\t.byte %s,%s\n",
973 aopLiteral (val, 0), aopLiteral (val, 1));
976 if (IS_GENPTR(type) && floatFromVal(val)!=0) {
977 // non-zero mcs51 generic pointer
978 werror (E_LITERAL_GENERIC);
980 fprintf (oFile, "\t.byte %s,%s,%s\n",
983 aopLiteral (val, 2));
986 if (IS_GENPTR(type) && floatFromVal(val)!=0) {
987 // non-zero ds390 generic pointer
988 werror (E_LITERAL_GENERIC);
990 fprintf (oFile, "\t.byte %s,%s,%s,%s\n",
994 aopLiteral (val, 3));
1001 if (val->sym && val->sym->isstrlit && !isinSet(statsg->syms, val->sym)) {
1002 addSet (&statsg->syms, val->sym);
1008 /*-----------------------------------------------------------------*/
1009 /* printIvalPtr - generates initial value for pointers */
1010 /*-----------------------------------------------------------------*/
1012 printIvalPtr (symbol * sym, sym_link * type, initList * ilist, FILE * oFile)
1018 if (ilist->type == INIT_DEEP)
1019 ilist = ilist->init.deep;
1021 /* function pointer */
1022 if (IS_FUNC (type->next))
1024 printIvalFuncPtr (type, ilist, oFile);
1028 if (!(val = initPointer (ilist, type)))
1031 /* if character pointer */
1032 if (IS_CHAR (type->next))
1033 if (printIvalCharPtr (sym, type, val, oFile))
1036 /* check the type */
1037 if (compareType (type, val->type) == 0) {
1038 werror (W_INIT_WRONG);
1039 printFromToType (val->type, type);
1042 /* if val is literal */
1043 if (IS_LITERAL (val->etype))
1045 switch (getSize (type))
1048 tfprintf (oFile, "\t!db !constbyte\n", (unsigned int) floatFromVal (val) & 0xff);
1051 if (port->use_dw_for_init)
1052 tfprintf (oFile, "\t!dws\n", aopLiteralLong (val, 0, 2));
1054 tfprintf (oFile, "\t.byte %s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1));
1056 case 3: // how about '390??
1057 fprintf (oFile, "\t.byte %s,%s,#0x%d\n",
1058 aopLiteral (val, 0), aopLiteral (val, 1), GPTYPE_CODE);
1064 size = getSize (type);
1066 if (size == 1) /* Z80 specific?? */
1068 tfprintf (oFile, "\t!dbs\n", val->name);
1070 else if (size == FPTRSIZE)
1072 if (port->use_dw_for_init) {
1073 tfprintf (oFile, "\t!dws\n", val->name);
1075 printPointerType (oFile, val->name);
1078 else if (size == GPTRSIZE)
1080 printGPointerType (oFile, val->name, sym->name,
1081 (IS_PTR (val->type) ? DCL_TYPE (val->type) :
1082 PTR_TYPE (SPEC_OCLS (val->etype))));
1087 /*-----------------------------------------------------------------*/
1088 /* printIval - generates code for initial value */
1089 /*-----------------------------------------------------------------*/
1091 printIval (symbol * sym, sym_link * type, initList * ilist, FILE * oFile)
1096 /* update line number for error msgs */
1097 lineno=sym->lineDef;
1099 /* if structure then */
1100 if (IS_STRUCT (type))
1102 printIvalStruct (sym, type, ilist, oFile);
1106 /* if this is a pointer */
1109 printIvalPtr (sym, type, ilist, oFile);
1113 /* if this is an array */
1114 if (IS_ARRAY (type))
1116 printIvalArray (sym, type, ilist, oFile);
1120 /* if type is SPECIFIER */
1123 printIvalType (sym, type, ilist, oFile);
1128 /*-----------------------------------------------------------------*/
1129 /* emitStaticSeg - emitcode for the static segment */
1130 /*-----------------------------------------------------------------*/
1132 emitStaticSeg (memmap * map, FILE * out)
1136 /* fprintf(out, "\t.area\t%s\n", map->sname); */
1138 /* for all variables in this segment do */
1139 for (sym = setFirstItem (map->syms); sym;
1140 sym = setNextItem (map->syms))
1143 /* if it is "extern" then do nothing */
1144 if (IS_EXTERN (sym->etype))
1147 /* if it is not static add it to the public
1149 if (!IS_STATIC (sym->etype))
1151 addSetHead (&publics, sym);
1154 /* print extra debug info if required */
1155 if (options.debug) {
1159 if (IS_STATIC (sym->etype))
1160 fprintf (out, "F%s$", moduleName); /* scope is file */
1162 fprintf (out, "G$"); /* scope is global */
1165 /* symbol is local */
1166 fprintf (out, "L%s$",
1167 (sym->localof ? sym->localof->name : "-null-"));
1168 fprintf (out, "%s$%d$%d", sym->name, sym->level, sym->block);
1171 /* if it has an absolute address */
1172 if (SPEC_ABSA (sym->etype))
1175 fprintf (out, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1177 fprintf (out, "%s\t=\t0x%04x\n",
1179 SPEC_ADDR (sym->etype));
1184 fprintf (out, " == .\n");
1186 /* if it has an initial value */
1189 fprintf (out, "%s:\n", sym->rname);
1191 resolveIvalSym (sym->ival);
1192 printIval (sym, sym->type, sym->ival, out);
1194 /* if sym is a simple string and sym->ival is a string,
1195 WE don't need it anymore */
1196 if (IS_ARRAY(sym->type) && IS_CHAR(sym->type->next) &&
1197 IS_AST_SYM_VALUE(list2expr(sym->ival)) &&
1198 list2val(sym->ival)->sym->isstrlit) {
1199 freeStringSymbol(list2val(sym->ival)->sym);
1203 /* allocate space */
1204 int size = getSize (sym->type);
1207 werror(E_UNKNOWN_SIZE,sym->name);
1209 fprintf (out, "%s:\n", sym->rname);
1210 /* special case for character strings */
1211 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1212 SPEC_CVAL (sym->etype).v_char)
1214 SPEC_CVAL (sym->etype).v_char,
1215 strlen (SPEC_CVAL (sym->etype).v_char) + 1);
1217 tfprintf (out, "\t!ds\n", (unsigned int) size & 0xffff);
1223 /*-----------------------------------------------------------------*/
1224 /* emitMaps - emits the code for the data portion the code */
1225 /*-----------------------------------------------------------------*/
1230 /* no special considerations for the following
1231 data, idata & bit & xdata */
1232 emitRegularMap (data, TRUE, TRUE);
1233 emitRegularMap (idata, TRUE, TRUE);
1234 emitRegularMap (bit, TRUE, FALSE);
1235 emitRegularMap (xdata, TRUE, TRUE);
1236 if (port->genXINIT) {
1237 emitRegularMap (xidata, TRUE, TRUE);
1239 emitRegularMap (sfr, FALSE, FALSE);
1240 emitRegularMap (sfrbit, FALSE, FALSE);
1241 emitRegularMap (home, TRUE, FALSE);
1242 emitRegularMap (code, TRUE, FALSE);
1244 emitStaticSeg (statsg, code->oFile);
1245 if (port->genXINIT) {
1246 tfprintf (code->oFile, "\t!area\n", xinit->sname);
1247 emitStaticSeg (xinit, code->oFile);
1252 /*-----------------------------------------------------------------*/
1253 /* flushStatics - flush all currently defined statics out to file */
1254 /* and delete. Temporary function */
1255 /*-----------------------------------------------------------------*/
1259 emitStaticSeg (statsg, codeOutFile);
1260 statsg->syms = NULL;
1263 /*-----------------------------------------------------------------*/
1264 /* createInterruptVect - creates the interrupt vector */
1265 /*-----------------------------------------------------------------*/
1267 createInterruptVect (FILE * vFile)
1270 mainf = newSymbol ("main", 0);
1273 /* only if the main function exists */
1274 if (!(mainf = findSymWithLevel (SymbolTab, mainf)))
1276 if (!options.cc_only && !noAssemble && !options.c1mode)
1281 /* if the main is only a prototype ie. no body then do nothing */
1282 if (!IFFUNC_HASBODY(mainf->type))
1284 /* if ! compile only then main function should be present */
1285 if (!options.cc_only && !noAssemble)
1290 tfprintf (vFile, "\t!areacode\n", CODE_NAME);
1291 fprintf (vFile, "__interrupt_vect:\n");
1294 if (!port->genIVT || !(port->genIVT (vFile, interrupts, maxInterrupts)))
1296 /* "generic" interrupt table header (if port doesn't specify one).
1297 * Look suspiciously like 8051 code to me...
1300 fprintf (vFile, "\tljmp\t__sdcc_gsinit_startup\n");
1303 /* now for the other interrupts */
1304 for (; i < maxInterrupts; i++)
1307 fprintf (vFile, "\tljmp\t%s\n\t.ds\t5\n", interrupts[i]->rname);
1309 fprintf (vFile, "\treti\n\t.ds\t7\n");
1316 ";--------------------------------------------------------\n"
1317 "; File Created by SDCC : FreeWare ANSI-C Compiler\n"};
1321 ";--------------------------------------------------------\n"};
1324 /*-----------------------------------------------------------------*/
1325 /* initialComments - puts in some initial comments */
1326 /*-----------------------------------------------------------------*/
1328 initialComments (FILE * afile)
1332 fprintf (afile, "%s", iComments1);
1333 fprintf (afile, "; Version " SDCC_VERSION_STR " %s\n", asctime (localtime (&t)));
1334 fprintf (afile, "%s", iComments2);
1337 /*-----------------------------------------------------------------*/
1338 /* printPublics - generates .global for publics */
1339 /*-----------------------------------------------------------------*/
1341 printPublics (FILE * afile)
1345 fprintf (afile, "%s", iComments2);
1346 fprintf (afile, "; Public variables in this module\n");
1347 fprintf (afile, "%s", iComments2);
1349 for (sym = setFirstItem (publics); sym;
1350 sym = setNextItem (publics))
1351 tfprintf (afile, "\t!global\n", sym->rname);
1354 /*-----------------------------------------------------------------*/
1355 /* printExterns - generates .global for externs */
1356 /*-----------------------------------------------------------------*/
1358 printExterns (FILE * afile)
1362 fprintf (afile, "%s", iComments2);
1363 fprintf (afile, "; Externals used\n");
1364 fprintf (afile, "%s", iComments2);
1366 for (sym = setFirstItem (externs); sym;
1367 sym = setNextItem (externs))
1368 tfprintf (afile, "\t!extern\n", sym->rname);
1371 /*-----------------------------------------------------------------*/
1372 /* emitOverlay - will emit code for the overlay stuff */
1373 /*-----------------------------------------------------------------*/
1375 emitOverlay (FILE * afile)
1379 if (!elementsInSet (ovrSetSets))
1380 tfprintf (afile, "\t!area\n", port->mem.overlay_name);
1382 /* for each of the sets in the overlay segment do */
1383 for (ovrset = setFirstItem (ovrSetSets); ovrset;
1384 ovrset = setNextItem (ovrSetSets))
1389 if (elementsInSet (ovrset))
1391 /* output the area informtion */
1392 fprintf (afile, "\t.area\t%s\n", port->mem.overlay_name); /* MOF */
1395 for (sym = setFirstItem (ovrset); sym;
1396 sym = setNextItem (ovrset))
1398 /* if extern then it is in the publics table: do nothing */
1399 if (IS_EXTERN (sym->etype))
1402 /* if allocation required check is needed
1403 then check if the symbol really requires
1404 allocation only for local variables */
1405 if (!IS_AGGREGATE (sym->type) &&
1406 !(sym->_isparm && !IS_REGPARM (sym->etype))
1407 && !sym->allocreq && sym->level)
1410 /* if global variable & not static or extern
1411 and addPublics allowed then add it to the public set */
1412 if ((sym->_isparm && !IS_REGPARM (sym->etype))
1413 && !IS_STATIC (sym->etype))
1415 addSetHead (&publics, sym);
1418 /* if extern then do nothing or is a function
1420 if (IS_FUNC (sym->type))
1423 /* print extra debug info if required */
1428 if (IS_STATIC (sym->etype))
1429 fprintf (afile, "F%s$", moduleName); /* scope is file */
1431 fprintf (afile, "G$"); /* scope is global */
1434 /* symbol is local */
1435 fprintf (afile, "L%s$",
1436 (sym->localof ? sym->localof->name : "-null-"));
1437 fprintf (afile, "%s$%d$%d", sym->name, sym->level, sym->block);
1440 /* if is has an absolute address then generate
1441 an equate for this no need to allocate space */
1442 if (SPEC_ABSA (sym->etype))
1446 fprintf (afile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1448 fprintf (afile, "%s\t=\t0x%04x\n",
1450 SPEC_ADDR (sym->etype));
1453 int size = getSize(sym->type);
1456 werror(E_UNKNOWN_SIZE,sym->name);
1459 fprintf (afile, "==.\n");
1461 /* allocate space */
1462 tfprintf (afile, "!labeldef\n", sym->rname);
1463 tfprintf (afile, "\t!ds\n", (unsigned int) getSize (sym->type) & 0xffff);
1471 /*-----------------------------------------------------------------*/
1472 /* spacesToUnderscores - replace spaces with underscores */
1473 /*-----------------------------------------------------------------*/
1475 spacesToUnderscores (char *dest, const char *src, size_t len)
1480 assert(dest != NULL);
1481 assert(src != NULL);
1485 for (p = dest, i = 0; *src != '\0' && i < len; ++src, ++i) {
1486 *p++ = isspace(*src) ? '_' : *src;
1494 /*-----------------------------------------------------------------*/
1495 /* glue - the final glue that hold the whole thing together */
1496 /*-----------------------------------------------------------------*/
1502 FILE *ovrFile = tempfile ();
1503 char moduleBuf[PATH_MAX];
1505 addSetHead (&tmpfileSet, ovrFile);
1506 /* print the global struct definitions */
1510 vFile = tempfile ();
1511 /* PENDING: this isnt the best place but it will do */
1512 if (port->general.glue_up_main)
1514 /* create the interrupt vector table */
1515 createInterruptVect (vFile);
1518 addSetHead (&tmpfileSet, vFile);
1520 /* emit code for the all the variables declared */
1522 /* do the overlay segments */
1523 emitOverlay (ovrFile);
1525 outputDebugSymbols();
1527 /* now put it all together into the assembler file */
1528 /* create the assembler file name */
1530 /* -o option overrides default name? */
1531 if ((noAssemble || options.c1mode) && fullDstFileName)
1533 strncpyz (scratchFileName, fullDstFileName, PATH_MAX);
1537 strncpyz (scratchFileName, dstFileName, PATH_MAX);
1538 strncatz (scratchFileName, port->assembler.file_ext, PATH_MAX);
1541 if (!(asmFile = fopen (scratchFileName, "w")))
1543 werror (E_FILE_OPEN_ERR, scratchFileName);
1547 /* initial comments */
1548 initialComments (asmFile);
1550 /* print module name */
1551 tfprintf (asmFile, "\t!module\n",
1552 spacesToUnderscores (moduleBuf, moduleName, sizeof moduleBuf));
1553 tfprintf (asmFile, "\t!fileprelude\n");
1555 /* Let the port generate any global directives, etc. */
1556 if (port->genAssemblerPreamble)
1558 port->genAssemblerPreamble (asmFile);
1561 /* print the global variables in this module */
1562 printPublics (asmFile);
1563 if (port->assembler.externGlobal)
1564 printExterns (asmFile);
1566 /* copy the sfr segment */
1567 fprintf (asmFile, "%s", iComments2);
1568 fprintf (asmFile, "; special function registers\n");
1569 fprintf (asmFile, "%s", iComments2);
1570 copyFile (asmFile, sfr->oFile);
1572 /* copy the sbit segment */
1573 fprintf (asmFile, "%s", iComments2);
1574 fprintf (asmFile, "; special function bits \n");
1575 fprintf (asmFile, "%s", iComments2);
1576 copyFile (asmFile, sfrbit->oFile);
1578 /*JCF: Create the areas for the register banks*/
1579 if(port->general.glue_up_main &&
1580 (TARGET_IS_MCS51 || TARGET_IS_DS390 || TARGET_IS_XA51))
1582 if(RegBankUsed[0]||RegBankUsed[1]||RegBankUsed[2]||RegBankUsed[3])
1584 fprintf (asmFile, "%s", iComments2);
1585 fprintf (asmFile, "; overlayable register banks \n");
1586 fprintf (asmFile, "%s", iComments2);
1588 fprintf (asmFile, "\t.area REG_BANK_0\t(REL,OVR,DATA)\n\t.ds 8\n");
1589 if(RegBankUsed[1]||options.parms_in_bank1)
1590 fprintf (asmFile, "\t.area REG_BANK_1\t(REL,OVR,DATA)\n\t.ds 8\n");
1592 fprintf (asmFile, "\t.area REG_BANK_2\t(REL,OVR,DATA)\n\t.ds 8\n");
1594 fprintf (asmFile, "\t.area REG_BANK_3\t(REL,OVR,DATA)\n\t.ds 8\n");
1598 /* copy the data segment */
1599 fprintf (asmFile, "%s", iComments2);
1600 fprintf (asmFile, "; internal ram data\n");
1601 fprintf (asmFile, "%s", iComments2);
1602 copyFile (asmFile, data->oFile);
1605 /* create the overlay segments */
1607 fprintf (asmFile, "%s", iComments2);
1608 fprintf (asmFile, "; overlayable items in internal ram \n");
1609 fprintf (asmFile, "%s", iComments2);
1610 copyFile (asmFile, ovrFile);
1613 /* create the stack segment MOF */
1614 if (mainf && IFFUNC_HASBODY(mainf->type))
1616 fprintf (asmFile, "%s", iComments2);
1617 fprintf (asmFile, "; Stack segment in internal ram \n");
1618 fprintf (asmFile, "%s", iComments2);
1619 fprintf (asmFile, "\t.area\tSSEG\t(DATA)\n"
1620 "__start__stack:\n\t.ds\t1\n\n");
1623 /* create the idata segment */
1625 fprintf (asmFile, "%s", iComments2);
1626 fprintf (asmFile, "; indirectly addressable internal ram data\n");
1627 fprintf (asmFile, "%s", iComments2);
1628 copyFile (asmFile, idata->oFile);
1631 /* copy the bit segment */
1632 fprintf (asmFile, "%s", iComments2);
1633 fprintf (asmFile, "; bit data\n");
1634 fprintf (asmFile, "%s", iComments2);
1635 copyFile (asmFile, bit->oFile);
1637 /* if external stack then reserve space of it */
1638 if (mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack)
1640 fprintf (asmFile, "%s", iComments2);
1641 fprintf (asmFile, "; external stack \n");
1642 fprintf (asmFile, "%s", iComments2);
1643 fprintf (asmFile, "\t.area XSEG (XDATA)\n"); /* MOF */
1644 fprintf (asmFile, "\t.ds 256\n");
1648 /* copy xtern ram data */
1649 fprintf (asmFile, "%s", iComments2);
1650 fprintf (asmFile, "; external ram data\n");
1651 fprintf (asmFile, "%s", iComments2);
1652 copyFile (asmFile, xdata->oFile);
1654 /* copy xternal initialized ram data */
1655 fprintf (asmFile, "%s", iComments2);
1656 fprintf (asmFile, "; external initialized ram data\n");
1657 fprintf (asmFile, "%s", iComments2);
1658 copyFile (asmFile, xidata->oFile);
1660 /* copy the interrupt vector table */
1661 if (mainf && IFFUNC_HASBODY(mainf->type))
1663 fprintf (asmFile, "%s", iComments2);
1664 fprintf (asmFile, "; interrupt vector \n");
1665 fprintf (asmFile, "%s", iComments2);
1666 copyFile (asmFile, vFile);
1669 /* copy global & static initialisations */
1670 fprintf (asmFile, "%s", iComments2);
1671 fprintf (asmFile, "; global & static initialisations\n");
1672 fprintf (asmFile, "%s", iComments2);
1674 /* Everywhere we generate a reference to the static_name area,
1675 * (which is currently only here), we immediately follow it with a
1676 * definition of the post_static_name area. This guarantees that
1677 * the post_static_name area will immediately follow the static_name
1680 tfprintf (asmFile, "\t!area\n", port->mem.static_name); /* MOF */
1681 tfprintf (asmFile, "\t!area\n", port->mem.post_static_name);
1682 tfprintf (asmFile, "\t!area\n", port->mem.static_name);
1684 if (mainf && IFFUNC_HASBODY(mainf->type))
1686 fprintf (asmFile, "__sdcc_gsinit_startup:\n");
1687 /* if external stack is specified then the
1688 higher order byte of the xdatalocation is
1689 going into P2 and the lower order going into
1691 if (options.useXstack)
1693 fprintf (asmFile, "\tmov\tP2,#0x%02x\n",
1694 (((unsigned int) options.xdata_loc) >> 8) & 0xff);
1695 fprintf (asmFile, "\tmov\t_spx,#0x%02x\n",
1696 (unsigned int) options.xdata_loc & 0xff);
1699 /* initialise the stack pointer. JCF: aslink takes care of the location */
1700 fprintf (asmFile, "\tmov\tsp,#__start__stack - 1\n"); /* MOF */
1702 fprintf (asmFile, "\tlcall\t__sdcc_external_startup\n");
1703 fprintf (asmFile, "\tmov\ta,dpl\n");
1704 fprintf (asmFile, "\tjz\t__sdcc_init_data\n");
1705 fprintf (asmFile, "\tljmp\t__sdcc_program_startup\n");
1706 fprintf (asmFile, "__sdcc_init_data:\n");
1708 // if the port can copy the XINIT segment to XISEG
1709 if (port->genXINIT) {
1710 port->genXINIT(asmFile);
1714 copyFile (asmFile, statsg->oFile);
1716 if (port->general.glue_up_main && mainf && IFFUNC_HASBODY(mainf->type))
1718 /* This code is generated in the post-static area.
1719 * This area is guaranteed to follow the static area
1720 * by the ugly shucking and jiving about 20 lines ago.
1722 tfprintf (asmFile, "\t!area\n", port->mem.post_static_name);
1723 fprintf (asmFile, "\tljmp\t__sdcc_program_startup\n");
1729 "%s", iComments2, iComments2);
1730 tfprintf (asmFile, "\t!areahome\n", HOME_NAME);
1731 copyFile (asmFile, home->oFile);
1733 /* copy over code */
1734 fprintf (asmFile, "%s", iComments2);
1735 fprintf (asmFile, "; code\n");
1736 fprintf (asmFile, "%s", iComments2);
1737 tfprintf (asmFile, "\t!areacode\n", CODE_NAME);
1738 if (mainf && IFFUNC_HASBODY(mainf->type))
1741 /* entry point @ start of CSEG */
1742 fprintf (asmFile, "__sdcc_program_startup:\n");
1744 /* put in the call to main */
1745 fprintf (asmFile, "\tlcall\t_main\n");
1746 if (options.mainreturn)
1749 fprintf (asmFile, ";\treturn from main ; will return to caller\n");
1750 fprintf (asmFile, "\tret\n");
1756 fprintf (asmFile, ";\treturn from main will lock up\n");
1757 fprintf (asmFile, "\tsjmp .\n");
1760 copyFile (asmFile, code->oFile);
1762 if (port->genAssemblerEnd) {
1763 port->genAssemblerEnd(asmFile);
1771 /** Creates a temporary file with unoque file name
1773 - TMP, TEMP, TMPDIR env. varibles
1774 - if Un*x system: /usr/tmp and /tmp
1775 - root directory using mkstemp() if avaliable
1776 - default location using tempnam()
1779 tempfileandname(char *fname, size_t len)
1781 #define TEMPLATE "sdccXXXXXX"
1782 #define TEMPLATE_LEN ((sizeof TEMPLATE) - 1)
1784 const char *tmpdir = NULL;
1787 if ((tmpdir = getenv ("TMP")) == NULL)
1788 if ((tmpdir = getenv ("TEMP")) == NULL)
1789 tmpdir = getenv ("TMPDIR");
1793 /* try with /usr/tmp and /tmp on Un*x systems */
1794 struct stat statbuf;
1796 if (tmpdir == NULL) {
1797 if (stat("/usr/tmp", &statbuf) != -1)
1798 tmpdir = "/usr/tmp";
1799 else if (stat("/tmp", &statbuf) != -1)
1807 char fnamebuf[PATH_MAX];
1810 if (fname == NULL || len == 0) {
1812 len = sizeof fnamebuf;
1816 name_len = strlen(tmpdir) + 1 + TEMPLATE_LEN;
1818 assert(name_len < len);
1819 if (!(name_len < len)) /* in NDEBUG is defined */
1820 return -1; /* buffer too small, temporary file can not be created */
1822 sprintf(fname, "%s" DIR_SEPARATOR_STRING TEMPLATE, tmpdir);
1825 name_len = TEMPLATE_LEN;
1827 assert(name_len < len);
1828 if (!(name_len < len)) /* in NDEBUG is defined */
1829 return -1; /* buffer too small, temporary file can not be created */
1831 strcpy(fname, TEMPLATE);
1834 fd = mkstemp(fname);
1838 char *name = tempnam(tmpdir, "sdcc");
1841 perror("Can't create temporary file name");
1845 assert(strlen(name) < len);
1846 if (!(strlen(name) < len)) /* in NDEBUG is defined */
1847 return -1; /* buffer too small, temporary file can not be created */
1849 strcpy(fname, name);
1851 fd = open(name, O_CREAT | O_EXCL | O_RDWR, S_IREAD | S_IWRITE);
1853 fd = open(name, O_CREAT | O_EXCL | O_RDWR, S_IRUSR | S_IWUSR);
1859 perror("Can't create temporary file");
1867 /** Create a temporary file name
1873 static char fnamebuf[PATH_MAX];
1875 if ((fd = tempfileandname(fnamebuf, sizeof fnamebuf)) == -1) {
1876 fprintf(stderr, "Can't create temporary file name!");
1887 /** Create a temporary file and add it to tmpfileNameSet,
1888 so that it is removed explicitly by rm_tmpfiles()
1889 or implicitly at program extit.
1897 char fnamebuf[PATH_MAX];
1899 if ((fd = tempfileandname(fnamebuf, sizeof fnamebuf)) == -1) {
1900 fprintf(stderr, "Can't create temporary file!");
1904 tmp = Safe_strdup(fnamebuf);
1906 addSetHead(&tmpfileNameSet, tmp);
1908 if ((fp = fdopen(fd, "w+b")) == NULL) {
1909 perror("Can't create temporary file!");