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 */
267 cdbSymbol (sym, cdbFile, FALSE, FALSE);
268 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 */
274 /* symbol is local */
275 fprintf (map->oFile, "L%s$", (sym->localof ? sym->localof->name : "-null-"));
276 fprintf (map->oFile, "%s$%d$%d", sym->name, sym->level, sym->block);
279 /* if it has an initial value then do it only if
280 it is a global variable */
281 if (sym->ival && sym->level == 0) {
282 if (SPEC_OCLS(sym->etype)==xidata) {
283 // create a new "XINIT (CODE)" symbol, that will be emitted later
284 newSym=copySymbol (sym);
285 SPEC_OCLS(newSym->etype)=xinit;
286 SNPRINTF (newSym->name, sizeof(newSym->name), "__xinit_%s", sym->name);
287 SNPRINTF (newSym->rname, sizeof(newSym->rname), "__xinit_%s", sym->rname);
288 SPEC_CONST(newSym->etype)=1;
289 SPEC_STAT(newSym->etype)=1;
290 resolveIvalSym(newSym->ival);
292 // add it to the "XINIT (CODE)" segment
293 addSet(&xinit->syms, newSym);
296 if (IS_AGGREGATE (sym->type)) {
297 ival = initAggregates (sym, sym->ival, NULL);
299 if (getNelements(sym->type, sym->ival)>1) {
300 werror (W_EXCESS_INITIALIZERS, "scalar",
301 sym->name, sym->lineDef);
303 ival = newNode ('=', newAst_VALUE (symbolVal (sym)),
304 decorateType (resolveSymbols (list2expr (sym->ival))));
306 codeOutFile = statsg->oFile;
309 // set ival's lineno to where the symbol was defined
310 setAstLineno (ival, lineno=sym->lineDef);
311 // check if this is not a constant expression
312 if (!constExprTree(ival)) {
313 werror (E_CONST_EXPECTED, "found expression");
314 // but try to do it anyway
317 eBBlockFromiCode (iCodeFromAst (ival));
324 /* if is has an absolute address then generate
325 an equate for this no need to allocate space */
326 if (SPEC_ABSA (sym->etype))
330 fprintf (map->oFile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
332 if (TARGET_IS_XA51) {
335 } else if (map==bit || map==sfrbit) {
339 fprintf (map->oFile, "%s\t%s\t0x%04x\n",
341 SPEC_ADDR (sym->etype));
344 int size = getSize (sym->type);
346 werror(E_UNKNOWN_SIZE,sym->name);
350 fprintf (map->oFile, "==.\n");
352 if (IS_STATIC (sym->etype))
353 tfprintf (map->oFile, "!slabeldef\n", sym->rname);
355 tfprintf (map->oFile, "!labeldef\n", sym->rname);
356 tfprintf (map->oFile, "\t!ds\n",
357 (unsigned int) size & 0xffff);
362 /*-----------------------------------------------------------------*/
363 /* initPointer - pointer initialization code massaging */
364 /*-----------------------------------------------------------------*/
366 initPointer (initList * ilist, sym_link *toType)
369 ast *expr = list2expr (ilist);
374 /* try it the oldway first */
375 if ((val = constExprValue (expr, FALSE)))
378 /* ( ptr + constant ) */
379 if (IS_AST_OP (expr) &&
380 (expr->opval.op == '+' || expr->opval.op == '-') &&
381 IS_AST_SYM_VALUE (expr->left) &&
382 (IS_ARRAY(expr->left->ftype) || IS_PTR(expr->left->ftype)) &&
383 compareType(toType, expr->left->ftype) &&
384 IS_AST_LIT_VALUE (expr->right)) {
385 return valForCastAggr (expr->left, expr->left->ftype,
391 if (IS_AST_OP(expr) && expr->opval.op==CAST &&
392 IS_AST_OP(expr->right) && expr->right->opval.op=='&') {
393 if (compareType(toType, expr->left->ftype)!=1) {
394 werror (W_INIT_WRONG);
395 printFromToType(expr->left->ftype, toType);
401 /* no then we have to do these cludgy checks */
402 /* pointers can be initialized with address of
403 a variable or address of an array element */
404 if (IS_AST_OP (expr) && expr->opval.op == '&') {
405 /* address of symbol */
406 if (IS_AST_SYM_VALUE (expr->left)) {
407 val = copyValue (AST_VALUE (expr->left));
408 val->type = newLink (DECLARATOR);
409 if (SPEC_SCLS (expr->left->etype) == S_CODE) {
410 DCL_TYPE (val->type) = CPOINTER;
412 else if (SPEC_SCLS (expr->left->etype) == S_XDATA)
413 DCL_TYPE (val->type) = FPOINTER;
414 else if (SPEC_SCLS (expr->left->etype) == S_XSTACK)
415 DCL_TYPE (val->type) = PPOINTER;
416 else if (SPEC_SCLS (expr->left->etype) == S_IDATA)
417 DCL_TYPE (val->type) = IPOINTER;
418 else if (SPEC_SCLS (expr->left->etype) == S_EEPROM)
419 DCL_TYPE (val->type) = EEPPOINTER;
421 DCL_TYPE (val->type) = POINTER;
422 val->type->next = expr->left->ftype;
423 val->etype = getSpec (val->type);
427 /* if address of indexed array */
428 if (IS_AST_OP (expr->left) && expr->left->opval.op == '[')
429 return valForArray (expr->left);
431 /* if address of structure element then
433 if (IS_AST_OP (expr->left) &&
434 expr->left->opval.op == '.') {
435 return valForStructElem (expr->left->left,
440 (&some_struct)->element */
441 if (IS_AST_OP (expr->left) &&
442 expr->left->opval.op == PTR_OP &&
443 IS_ADDRESS_OF_OP (expr->left->left)) {
444 return valForStructElem (expr->left->left->left,
448 /* case 3. (((char *) &a) +/- constant) */
449 if (IS_AST_OP (expr) &&
450 (expr->opval.op == '+' || expr->opval.op == '-') &&
451 IS_AST_OP (expr->left) && expr->left->opval.op == CAST &&
452 IS_AST_OP (expr->left->right) &&
453 expr->left->right->opval.op == '&' &&
454 IS_AST_LIT_VALUE (expr->right)) {
456 return valForCastAggr (expr->left->right->left,
457 expr->left->left->opval.lnk,
458 expr->right, expr->opval.op);
461 /* case 4. (char *)(array type) */
462 if (IS_CAST_OP(expr) && IS_AST_SYM_VALUE (expr->right) &&
463 IS_ARRAY(expr->right->ftype)) {
465 val = copyValue (AST_VALUE (expr->right));
466 val->type = newLink (DECLARATOR);
467 if (SPEC_SCLS (expr->right->etype) == S_CODE) {
468 DCL_TYPE (val->type) = CPOINTER;
470 else if (SPEC_SCLS (expr->right->etype) == S_XDATA)
471 DCL_TYPE (val->type) = FPOINTER;
472 else if (SPEC_SCLS (expr->right->etype) == S_XSTACK)
473 DCL_TYPE (val->type) = PPOINTER;
474 else if (SPEC_SCLS (expr->right->etype) == S_IDATA)
475 DCL_TYPE (val->type) = IPOINTER;
476 else if (SPEC_SCLS (expr->right->etype) == S_EEPROM)
477 DCL_TYPE (val->type) = EEPPOINTER;
479 DCL_TYPE (val->type) = POINTER;
480 val->type->next = expr->right->ftype->next;
481 val->etype = getSpec (val->type);
485 werror (E_INCOMPAT_PTYPES);
490 /*-----------------------------------------------------------------*/
491 /* printChar - formats and prints a characater string with DB */
492 /*-----------------------------------------------------------------*/
494 printChar (FILE * ofile, char *s, int plen)
497 int len = strlen (s);
502 while (len && pplen < plen)
505 while (i && *s && pplen < plen)
507 if (*s < ' ' || *s == '\"' || *s=='\\')
511 tfprintf (ofile, "\t!ascii\n", buf);
512 tfprintf (ofile, "\t!db !constbyte\n", (unsigned char)*s);
527 tfprintf (ofile, "\t!ascii\n", buf);
536 tfprintf (ofile, "\t!db !constbyte\n", 0);
539 /*-----------------------------------------------------------------*/
540 /* return the generic pointer high byte for a given pointer type. */
541 /*-----------------------------------------------------------------*/
543 pointerTypeToGPByte (const int p_type, const char *iname, const char *oname)
551 werror (E_CANNOT_USE_GENERIC_POINTER,
552 iname ? iname : "<null>",
553 oname ? oname : "<null>");
560 return GPTYPE_XSTACK;
562 fprintf (stderr, "*** internal error: unknown pointer type %d in GPByte.\n",
570 /*-----------------------------------------------------------------*/
571 /* printPointerType - generates ival for pointer type */
572 /*-----------------------------------------------------------------*/
574 _printPointerType (FILE * oFile, const char *name)
576 /* if (TARGET_IS_DS390) */
577 if (options.model == MODEL_FLAT24)
579 fprintf (oFile, "\t.byte %s,(%s >> 8),(%s >> 16)", name, name, name);
583 fprintf (oFile, "\t.byte %s,(%s >> 8)", name, name);
587 /*-----------------------------------------------------------------*/
588 /* printPointerType - generates ival for pointer type */
589 /*-----------------------------------------------------------------*/
591 printPointerType (FILE * oFile, const char *name)
593 _printPointerType (oFile, name);
594 fprintf (oFile, "\n");
597 /*-----------------------------------------------------------------*/
598 /* printGPointerType - generates ival for generic pointer type */
599 /*-----------------------------------------------------------------*/
601 printGPointerType (FILE * oFile, const char *iname, const char *oname,
602 const unsigned int type)
604 _printPointerType (oFile, iname);
605 fprintf (oFile, ",#0x%02x\n", pointerTypeToGPByte (type, iname, oname));
608 /*-----------------------------------------------------------------*/
609 /* printIvalType - generates ival for int/char */
610 /*-----------------------------------------------------------------*/
612 printIvalType (symbol *sym, sym_link * type, initList * ilist, FILE * oFile)
616 /* if initList is deep */
617 if (ilist->type == INIT_DEEP)
618 ilist = ilist->init.deep;
620 if (!IS_AGGREGATE(sym->type) && getNelements(type, ilist)>1) {
621 werror (W_EXCESS_INITIALIZERS, "scalar", sym->name, sym->lineDef);
624 if (!(val = list2val (ilist))) {
625 // assuming a warning has been thrown
629 if (val->type != type) {
630 val = valCastLiteral(type, floatFromVal(val));
633 switch (getSize (type)) {
636 tfprintf (oFile, "\t!db !constbyte\n", 0);
638 tfprintf (oFile, "\t!dbs\n",
639 aopLiteral (val, 0));
643 if (port->use_dw_for_init)
644 tfprintf (oFile, "\t!dws\n", aopLiteralLong (val, 0, 2));
646 fprintf (oFile, "\t.byte %s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1));
650 tfprintf (oFile, "\t!dw !constword\n", 0);
651 tfprintf (oFile, "\t!dw !constword\n", 0);
654 fprintf (oFile, "\t.byte %s,%s,%s,%s\n",
655 aopLiteral (val, 0), aopLiteral (val, 1),
656 aopLiteral (val, 2), aopLiteral (val, 3));
662 /*-----------------------------------------------------------------*/
663 /* printIvalBitFields - generate initializer for bitfields */
664 /*-----------------------------------------------------------------*/
665 void printIvalBitFields(symbol **sym, initList **ilist, FILE * oFile)
669 initList *lilist = *ilist ;
670 unsigned long ival = 0;
676 val = list2val(lilist);
678 if (SPEC_BLEN(lsym->etype) > 8) {
679 size += ((SPEC_BLEN (lsym->etype) / 8) +
680 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
683 size = ((SPEC_BLEN (lsym->etype) / 8) +
684 (SPEC_BLEN (lsym->etype) % 8 ? 1 : 0));
686 i = (unsigned long)floatFromVal(val);
687 i <<= SPEC_BSTR (lsym->etype);
689 if (! ( lsym->next &&
690 (IS_BITFIELD(lsym->next->type)) &&
691 (SPEC_BSTR(lsym->next->etype)))) break;
693 lilist = lilist->next;
697 tfprintf (oFile, "\t!db !constbyte\n",ival);
701 tfprintf (oFile, "\t!dw !constword\n",ival);
704 tfprintf (oFile, "\t!db !constword,!constword\n",
705 (ival >> 8) & 0xffff, (ival & 0xffff));
712 /*-----------------------------------------------------------------*/
713 /* printIvalStruct - generates initial value for structures */
714 /*-----------------------------------------------------------------*/
716 printIvalStruct (symbol * sym, sym_link * type,
717 initList * ilist, FILE * oFile)
722 sflds = SPEC_STRUCT (type)->fields;
723 if (ilist->type != INIT_DEEP) {
724 werror (E_INIT_STRUCT, sym->name);
728 iloop = ilist->init.deep;
730 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL)) {
731 if (IS_BITFIELD(sflds->type)) {
732 printIvalBitFields(&sflds,&iloop,oFile);
734 printIval (sym, sflds->type, iloop, oFile);
738 werror (W_EXCESS_INITIALIZERS, "struct", sym->name, sym->lineDef);
743 /*-----------------------------------------------------------------*/
744 /* printIvalChar - generates initital value for character array */
745 /*-----------------------------------------------------------------*/
747 printIvalChar (sym_link * type, initList * ilist, FILE * oFile, char *s)
755 val = list2val (ilist);
756 /* if the value is a character string */
757 if (IS_ARRAY (val->type) && IS_CHAR (val->etype))
759 if (!DCL_ELEM (type))
760 DCL_ELEM (type) = strlen (SPEC_CVAL (val->etype).v_char) + 1;
762 printChar (oFile, SPEC_CVAL (val->etype).v_char, DCL_ELEM (type));
764 if ((remain = (DCL_ELEM (type) - strlen (SPEC_CVAL (val->etype).v_char) - 1)) > 0)
766 tfprintf (oFile, "\t!db !constbyte\n", 0);
774 printChar (oFile, s, strlen (s) + 1);
778 /*-----------------------------------------------------------------*/
779 /* printIvalArray - generates code for array initialization */
780 /*-----------------------------------------------------------------*/
782 printIvalArray (symbol * sym, sym_link * type, initList * ilist,
786 int lcnt = 0, size = 0;
789 /* take care of the special case */
790 /* array of characters can be init */
792 if (IS_CHAR (type->next)) {
793 if (!IS_LITERAL(list2val(ilist)->etype)) {
794 werror (E_CONST_EXPECTED);
797 if (printIvalChar (type,
798 (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
799 oFile, SPEC_CVAL (sym->etype).v_char))
802 /* not the special case */
803 if (ilist->type != INIT_DEEP)
805 werror (E_INIT_STRUCT, sym->name);
809 iloop = ilist->init.deep;
810 lcnt = DCL_ELEM (type);
811 for (last_type = type->next;
812 last_type && IS_DECL(last_type) && DCL_ELEM (last_type);
813 last_type = last_type->next) {
814 lcnt *= DCL_ELEM (last_type);
820 printIval (sym, type->next, iloop, oFile);
821 iloop = (iloop ? iloop->next : NULL);
824 /* if not array limits given & we */
825 /* are out of initialisers then */
826 if (!DCL_ELEM (type) && !iloop)
829 /* no of elements given and we */
830 /* have generated for all of them */
832 /* if initializers left */
834 werror (W_EXCESS_INITIALIZERS, "array", sym->name, sym->lineDef);
840 /* if we have not been given a size */
841 if (!DCL_ELEM (type))
842 DCL_ELEM (type) = size;
847 /*-----------------------------------------------------------------*/
848 /* printIvalFuncPtr - generate initial value for function pointers */
849 /*-----------------------------------------------------------------*/
851 printIvalFuncPtr (sym_link * type, initList * ilist, FILE * oFile)
856 val = list2val (ilist);
859 // an error has been thrown allready
863 if (IS_LITERAL(val->etype)) {
864 if (compareType(type,val->etype)==0) {
865 werror (E_INCOMPAT_TYPES);
866 printFromToType (val->type, type);
868 printIvalCharPtr (NULL, type, val, oFile);
872 /* check the types */
873 if ((dLvl = compareType (val->type, type->next)) <= 0)
875 tfprintf (oFile, "\t!dw !constword\n", 0);
879 /* now generate the name */
882 if (port->use_dw_for_init)
884 tfprintf (oFile, "\t!dws\n", val->name);
888 printPointerType (oFile, val->name);
891 else if (port->use_dw_for_init)
893 tfprintf (oFile, "\t!dws\n", val->sym->rname);
897 printPointerType (oFile, val->sym->rname);
903 /*-----------------------------------------------------------------*/
904 /* printIvalCharPtr - generates initial values for character pointers */
905 /*-----------------------------------------------------------------*/
907 printIvalCharPtr (symbol * sym, sym_link * type, value * val, FILE * oFile)
911 /* PENDING: this is _very_ mcs51 specific, including a magic
913 It's also endin specific.
915 size = getSize (type);
917 if (val->name && strlen (val->name))
919 if (size == 1) /* This appears to be Z80 specific?? */
922 "\t!dbs\n", val->name);
924 else if (size == FPTRSIZE)
926 if (port->use_dw_for_init)
928 tfprintf (oFile, "\t!dws\n", val->name);
932 printPointerType (oFile, val->name);
935 else if (size == GPTRSIZE)
938 if (IS_PTR (val->type)) {
939 type = DCL_TYPE (val->type);
941 type = PTR_TYPE (SPEC_OCLS (val->etype));
943 if (val->sym && val->sym->isstrlit) {
944 // this is a literal string
947 printGPointerType (oFile, val->name, sym->name, type);
951 fprintf (stderr, "*** internal error: unknown size in "
952 "printIvalCharPtr.\n");
957 // these are literals assigned to pointers
961 tfprintf (oFile, "\t!dbs\n", aopLiteral (val, 0));
964 if (port->use_dw_for_init)
965 tfprintf (oFile, "\t!dws\n", aopLiteralLong (val, 0, size));
967 tfprintf (oFile, "\t.byte %s,%s\n",
968 aopLiteral (val, 0), aopLiteral (val, 1));
971 if (IS_GENPTR(type) && floatFromVal(val)!=0) {
972 // non-zero mcs51 generic pointer
973 werror (E_LITERAL_GENERIC);
975 fprintf (oFile, "\t.byte %s,%s,%s\n",
978 aopLiteral (val, 2));
981 if (IS_GENPTR(type) && floatFromVal(val)!=0) {
982 // non-zero ds390 generic pointer
983 werror (E_LITERAL_GENERIC);
985 fprintf (oFile, "\t.byte %s,%s,%s,%s\n",
989 aopLiteral (val, 3));
996 if (val->sym && val->sym->isstrlit && !isinSet(statsg->syms, val->sym)) {
997 addSet (&statsg->syms, val->sym);
1003 /*-----------------------------------------------------------------*/
1004 /* printIvalPtr - generates initial value for pointers */
1005 /*-----------------------------------------------------------------*/
1007 printIvalPtr (symbol * sym, sym_link * type, initList * ilist, FILE * oFile)
1013 if (ilist->type == INIT_DEEP)
1014 ilist = ilist->init.deep;
1016 /* function pointer */
1017 if (IS_FUNC (type->next))
1019 printIvalFuncPtr (type, ilist, oFile);
1023 if (!(val = initPointer (ilist, type)))
1026 /* if character pointer */
1027 if (IS_CHAR (type->next))
1028 if (printIvalCharPtr (sym, type, val, oFile))
1031 /* check the type */
1032 if (compareType (type, val->type) == 0) {
1033 werror (W_INIT_WRONG);
1034 printFromToType (val->type, type);
1037 /* if val is literal */
1038 if (IS_LITERAL (val->etype))
1040 switch (getSize (type))
1043 tfprintf (oFile, "\t!db !constbyte\n", (unsigned int) floatFromVal (val) & 0xff);
1046 if (port->use_dw_for_init)
1047 tfprintf (oFile, "\t!dws\n", aopLiteralLong (val, 0, 2));
1049 tfprintf (oFile, "\t.byte %s,%s\n", aopLiteral (val, 0), aopLiteral (val, 1));
1051 case 3: // how about '390??
1052 fprintf (oFile, "\t.byte %s,%s,#0x%d\n",
1053 aopLiteral (val, 0), aopLiteral (val, 1), GPTYPE_CODE);
1059 size = getSize (type);
1061 if (size == 1) /* Z80 specific?? */
1063 tfprintf (oFile, "\t!dbs\n", val->name);
1065 else if (size == FPTRSIZE)
1067 if (port->use_dw_for_init) {
1068 tfprintf (oFile, "\t!dws\n", val->name);
1070 printPointerType (oFile, val->name);
1073 else if (size == GPTRSIZE)
1075 printGPointerType (oFile, val->name, sym->name,
1076 (IS_PTR (val->type) ? DCL_TYPE (val->type) :
1077 PTR_TYPE (SPEC_OCLS (val->etype))));
1082 /*-----------------------------------------------------------------*/
1083 /* printIval - generates code for initial value */
1084 /*-----------------------------------------------------------------*/
1086 printIval (symbol * sym, sym_link * type, initList * ilist, FILE * oFile)
1091 /* update line number for error msgs */
1092 lineno=sym->lineDef;
1094 /* if structure then */
1095 if (IS_STRUCT (type))
1097 printIvalStruct (sym, type, ilist, oFile);
1101 /* if this is a pointer */
1104 printIvalPtr (sym, type, ilist, oFile);
1108 /* if this is an array */
1109 if (IS_ARRAY (type))
1111 printIvalArray (sym, type, ilist, oFile);
1115 /* if type is SPECIFIER */
1118 printIvalType (sym, type, ilist, oFile);
1123 /*-----------------------------------------------------------------*/
1124 /* emitStaticSeg - emitcode for the static segment */
1125 /*-----------------------------------------------------------------*/
1127 emitStaticSeg (memmap * map, FILE * out)
1131 /* fprintf(out, "\t.area\t%s\n", map->sname); */
1133 /* for all variables in this segment do */
1134 for (sym = setFirstItem (map->syms); sym;
1135 sym = setNextItem (map->syms))
1138 /* if it is "extern" then do nothing */
1139 if (IS_EXTERN (sym->etype))
1142 /* if it is not static add it to the public
1144 if (!IS_STATIC (sym->etype))
1146 addSetHead (&publics, sym);
1149 /* print extra debug info if required */
1150 if (options.debug) {
1151 cdbSymbol (sym, cdbFile, FALSE, FALSE);
1154 if (IS_STATIC (sym->etype))
1155 fprintf (out, "F%s$", moduleName); /* scope is file */
1157 fprintf (out, "G$"); /* scope is global */
1160 /* symbol is local */
1161 fprintf (out, "L%s$",
1162 (sym->localof ? sym->localof->name : "-null-"));
1163 fprintf (out, "%s$%d$%d", sym->name, sym->level, sym->block);
1166 /* if it has an absolute address */
1167 if (SPEC_ABSA (sym->etype))
1170 fprintf (out, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1172 fprintf (out, "%s\t=\t0x%04x\n",
1174 SPEC_ADDR (sym->etype));
1179 fprintf (out, " == .\n");
1181 /* if it has an initial value */
1184 fprintf (out, "%s:\n", sym->rname);
1186 resolveIvalSym (sym->ival);
1187 printIval (sym, sym->type, sym->ival, out);
1189 /* if sym is a simple string and sym->ival is a string,
1190 WE don't need it anymore */
1191 if (IS_ARRAY(sym->type) && IS_CHAR(sym->type->next) &&
1192 IS_AST_SYM_VALUE(list2expr(sym->ival)) &&
1193 list2val(sym->ival)->sym->isstrlit) {
1194 freeStringSymbol(list2val(sym->ival)->sym);
1198 /* allocate space */
1199 int size = getSize (sym->type);
1202 werror(E_UNKNOWN_SIZE,sym->name);
1204 fprintf (out, "%s:\n", sym->rname);
1205 /* special case for character strings */
1206 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
1207 SPEC_CVAL (sym->etype).v_char)
1209 SPEC_CVAL (sym->etype).v_char,
1210 strlen (SPEC_CVAL (sym->etype).v_char) + 1);
1212 tfprintf (out, "\t!ds\n", (unsigned int) size & 0xffff);
1218 /*-----------------------------------------------------------------*/
1219 /* emitMaps - emits the code for the data portion the code */
1220 /*-----------------------------------------------------------------*/
1225 /* no special considerations for the following
1226 data, idata & bit & xdata */
1227 emitRegularMap (data, TRUE, TRUE);
1228 emitRegularMap (idata, TRUE, TRUE);
1229 emitRegularMap (bit, TRUE, FALSE);
1230 emitRegularMap (xdata, TRUE, TRUE);
1231 if (port->genXINIT) {
1232 emitRegularMap (xidata, TRUE, TRUE);
1234 emitRegularMap (sfr, FALSE, FALSE);
1235 emitRegularMap (sfrbit, FALSE, FALSE);
1236 emitRegularMap (home, TRUE, FALSE);
1237 emitRegularMap (code, TRUE, FALSE);
1239 emitStaticSeg (statsg, code->oFile);
1240 if (port->genXINIT) {
1241 tfprintf (code->oFile, "\t!area\n", xinit->sname);
1242 emitStaticSeg (xinit, code->oFile);
1247 /*-----------------------------------------------------------------*/
1248 /* flushStatics - flush all currently defined statics out to file */
1249 /* and delete. Temporary function */
1250 /*-----------------------------------------------------------------*/
1254 emitStaticSeg (statsg, codeOutFile);
1255 statsg->syms = NULL;
1258 /*-----------------------------------------------------------------*/
1259 /* createInterruptVect - creates the interrupt vector */
1260 /*-----------------------------------------------------------------*/
1262 createInterruptVect (FILE * vFile)
1265 mainf = newSymbol ("main", 0);
1268 /* only if the main function exists */
1269 if (!(mainf = findSymWithLevel (SymbolTab, mainf)))
1271 if (!options.cc_only && !noAssemble && !options.c1mode)
1276 /* if the main is only a prototype ie. no body then do nothing */
1277 if (!IFFUNC_HASBODY(mainf->type))
1279 /* if ! compile only then main function should be present */
1280 if (!options.cc_only && !noAssemble)
1285 tfprintf (vFile, "\t!areacode\n", CODE_NAME);
1286 fprintf (vFile, "__interrupt_vect:\n");
1289 if (!port->genIVT || !(port->genIVT (vFile, interrupts, maxInterrupts)))
1291 /* "generic" interrupt table header (if port doesn't specify one).
1292 * Look suspiciously like 8051 code to me...
1295 fprintf (vFile, "\tljmp\t__sdcc_gsinit_startup\n");
1298 /* now for the other interrupts */
1299 for (; i < maxInterrupts; i++)
1302 fprintf (vFile, "\tljmp\t%s\n\t.ds\t5\n", interrupts[i]->rname);
1304 fprintf (vFile, "\treti\n\t.ds\t7\n");
1311 ";--------------------------------------------------------\n"
1312 "; File Created by SDCC : FreeWare ANSI-C Compiler\n"};
1316 ";--------------------------------------------------------\n"};
1319 /*-----------------------------------------------------------------*/
1320 /* initialComments - puts in some initial comments */
1321 /*-----------------------------------------------------------------*/
1323 initialComments (FILE * afile)
1327 fprintf (afile, "%s", iComments1);
1328 fprintf (afile, "; Version %s %s\n", VersionString, asctime (localtime (&t)));
1329 fprintf (afile, "%s", iComments2);
1332 /*-----------------------------------------------------------------*/
1333 /* printPublics - generates .global for publics */
1334 /*-----------------------------------------------------------------*/
1336 printPublics (FILE * afile)
1340 fprintf (afile, "%s", iComments2);
1341 fprintf (afile, "; Public variables in this module\n");
1342 fprintf (afile, "%s", iComments2);
1344 for (sym = setFirstItem (publics); sym;
1345 sym = setNextItem (publics))
1346 tfprintf (afile, "\t!global\n", sym->rname);
1349 /*-----------------------------------------------------------------*/
1350 /* printExterns - generates .global for externs */
1351 /*-----------------------------------------------------------------*/
1353 printExterns (FILE * afile)
1357 fprintf (afile, "%s", iComments2);
1358 fprintf (afile, "; Externals used\n");
1359 fprintf (afile, "%s", iComments2);
1361 for (sym = setFirstItem (externs); sym;
1362 sym = setNextItem (externs))
1363 tfprintf (afile, "\t!extern\n", sym->rname);
1366 /*-----------------------------------------------------------------*/
1367 /* emitOverlay - will emit code for the overlay stuff */
1368 /*-----------------------------------------------------------------*/
1370 emitOverlay (FILE * afile)
1374 if (!elementsInSet (ovrSetSets))
1375 tfprintf (afile, "\t!area\n", port->mem.overlay_name);
1377 /* for each of the sets in the overlay segment do */
1378 for (ovrset = setFirstItem (ovrSetSets); ovrset;
1379 ovrset = setNextItem (ovrSetSets))
1384 if (elementsInSet (ovrset))
1386 /* output the area informtion */
1387 fprintf (afile, "\t.area\t%s\n", port->mem.overlay_name); /* MOF */
1390 for (sym = setFirstItem (ovrset); sym;
1391 sym = setNextItem (ovrset))
1393 /* if extern then it is in the publics table: do nothing */
1394 if (IS_EXTERN (sym->etype))
1397 /* if allocation required check is needed
1398 then check if the symbol really requires
1399 allocation only for local variables */
1400 if (!IS_AGGREGATE (sym->type) &&
1401 !(sym->_isparm && !IS_REGPARM (sym->etype))
1402 && !sym->allocreq && sym->level)
1405 /* if global variable & not static or extern
1406 and addPublics allowed then add it to the public set */
1407 if ((sym->_isparm && !IS_REGPARM (sym->etype))
1408 && !IS_STATIC (sym->etype))
1410 addSetHead (&publics, sym);
1413 /* if extern then do nothing or is a function
1415 if (IS_FUNC (sym->type))
1418 /* print extra debug info if required */
1421 cdbSymbol (sym, cdbFile, FALSE, FALSE);
1425 if (IS_STATIC (sym->etype))
1426 fprintf (afile, "F%s$", moduleName); /* scope is file */
1428 fprintf (afile, "G$"); /* scope is global */
1431 /* symbol is local */
1432 fprintf (afile, "L%s$",
1433 (sym->localof ? sym->localof->name : "-null-"));
1434 fprintf (afile, "%s$%d$%d", sym->name, sym->level, sym->block);
1437 /* if is has an absolute address then generate
1438 an equate for this no need to allocate space */
1439 if (SPEC_ABSA (sym->etype))
1443 fprintf (afile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
1445 fprintf (afile, "%s\t=\t0x%04x\n",
1447 SPEC_ADDR (sym->etype));
1450 int size = getSize(sym->type);
1453 werror(E_UNKNOWN_SIZE,sym->name);
1456 fprintf (afile, "==.\n");
1458 /* allocate space */
1459 tfprintf (afile, "!labeldef\n", sym->rname);
1460 tfprintf (afile, "\t!ds\n", (unsigned int) getSize (sym->type) & 0xffff);
1467 /*-----------------------------------------------------------------*/
1468 /* glue - the final glue that hold the whole thing together */
1469 /*-----------------------------------------------------------------*/
1475 FILE *ovrFile = tempfile ();
1477 addSetHead (&tmpfileSet, ovrFile);
1478 /* print the global struct definitions */
1480 cdbStructBlock (0, cdbFile);
1482 vFile = tempfile ();
1483 /* PENDING: this isnt the best place but it will do */
1484 if (port->general.glue_up_main)
1486 /* create the interrupt vector table */
1487 createInterruptVect (vFile);
1490 addSetHead (&tmpfileSet, vFile);
1492 /* emit code for the all the variables declared */
1494 /* do the overlay segments */
1495 emitOverlay (ovrFile);
1497 /* now put it all together into the assembler file */
1498 /* create the assembler file name */
1500 /* -o option overrides default name? */
1501 if ((noAssemble || options.c1mode) && fullDstFileName)
1503 strncpyz (scratchFileName, fullDstFileName, PATH_MAX);
1507 strncpyz (scratchFileName, dstFileName, PATH_MAX);
1508 strncatz (scratchFileName, port->assembler.file_ext, PATH_MAX);
1511 if (!(asmFile = fopen (scratchFileName, "w")))
1513 werror (E_FILE_OPEN_ERR, scratchFileName);
1517 /* initial comments */
1518 initialComments (asmFile);
1520 /* print module name */
1521 tfprintf (asmFile, "\t!module\n", moduleName);
1522 tfprintf (asmFile, "\t!fileprelude\n");
1524 /* Let the port generate any global directives, etc. */
1525 if (port->genAssemblerPreamble)
1527 port->genAssemblerPreamble (asmFile);
1530 /* print the global variables in this module */
1531 printPublics (asmFile);
1532 if (port->assembler.externGlobal)
1533 printExterns (asmFile);
1535 /* copy the sfr segment */
1536 fprintf (asmFile, "%s", iComments2);
1537 fprintf (asmFile, "; special function registers\n");
1538 fprintf (asmFile, "%s", iComments2);
1539 copyFile (asmFile, sfr->oFile);
1541 /* copy the sbit segment */
1542 fprintf (asmFile, "%s", iComments2);
1543 fprintf (asmFile, "; special function bits \n");
1544 fprintf (asmFile, "%s", iComments2);
1545 copyFile (asmFile, sfrbit->oFile);
1547 /*JCF: Create the areas for the register banks*/
1548 if(port->general.glue_up_main &&
1549 (TARGET_IS_MCS51 || TARGET_IS_DS390 || TARGET_IS_XA51))
1551 if(RegBankUsed[0]||RegBankUsed[1]||RegBankUsed[2]||RegBankUsed[3])
1553 fprintf (asmFile, "%s", iComments2);
1554 fprintf (asmFile, "; overlayable register banks \n");
1555 fprintf (asmFile, "%s", iComments2);
1557 fprintf (asmFile, "\t.area REG_BANK_0\t(REL,OVR,DATA)\n\t.ds 8\n");
1558 if(RegBankUsed[1]||options.parms_in_bank1)
1559 fprintf (asmFile, "\t.area REG_BANK_1\t(REL,OVR,DATA)\n\t.ds 8\n");
1561 fprintf (asmFile, "\t.area REG_BANK_2\t(REL,OVR,DATA)\n\t.ds 8\n");
1563 fprintf (asmFile, "\t.area REG_BANK_3\t(REL,OVR,DATA)\n\t.ds 8\n");
1567 /* copy the data segment */
1568 fprintf (asmFile, "%s", iComments2);
1569 fprintf (asmFile, "; internal ram data\n");
1570 fprintf (asmFile, "%s", iComments2);
1571 copyFile (asmFile, data->oFile);
1574 /* create the overlay segments */
1576 fprintf (asmFile, "%s", iComments2);
1577 fprintf (asmFile, "; overlayable items in internal ram \n");
1578 fprintf (asmFile, "%s", iComments2);
1579 copyFile (asmFile, ovrFile);
1582 /* create the stack segment MOF */
1583 if (mainf && IFFUNC_HASBODY(mainf->type))
1585 fprintf (asmFile, "%s", iComments2);
1586 fprintf (asmFile, "; Stack segment in internal ram \n");
1587 fprintf (asmFile, "%s", iComments2);
1588 fprintf (asmFile, "\t.area\tSSEG\t(DATA)\n"
1589 "__start__stack:\n\t.ds\t1\n\n");
1592 /* create the idata segment */
1594 fprintf (asmFile, "%s", iComments2);
1595 fprintf (asmFile, "; indirectly addressable internal ram data\n");
1596 fprintf (asmFile, "%s", iComments2);
1597 copyFile (asmFile, idata->oFile);
1600 /* copy the bit segment */
1601 fprintf (asmFile, "%s", iComments2);
1602 fprintf (asmFile, "; bit data\n");
1603 fprintf (asmFile, "%s", iComments2);
1604 copyFile (asmFile, bit->oFile);
1606 /* if external stack then reserve space of it */
1607 if (mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack)
1609 fprintf (asmFile, "%s", iComments2);
1610 fprintf (asmFile, "; external stack \n");
1611 fprintf (asmFile, "%s", iComments2);
1612 fprintf (asmFile, "\t.area XSEG (XDATA)\n"); /* MOF */
1613 fprintf (asmFile, "\t.ds 256\n");
1617 /* copy xtern ram data */
1618 fprintf (asmFile, "%s", iComments2);
1619 fprintf (asmFile, "; external ram data\n");
1620 fprintf (asmFile, "%s", iComments2);
1621 copyFile (asmFile, xdata->oFile);
1623 /* copy xternal initialized ram data */
1624 fprintf (asmFile, "%s", iComments2);
1625 fprintf (asmFile, "; external initialized ram data\n");
1626 fprintf (asmFile, "%s", iComments2);
1627 copyFile (asmFile, xidata->oFile);
1629 /* copy the interrupt vector table */
1630 if (mainf && IFFUNC_HASBODY(mainf->type))
1632 fprintf (asmFile, "%s", iComments2);
1633 fprintf (asmFile, "; interrupt vector \n");
1634 fprintf (asmFile, "%s", iComments2);
1635 copyFile (asmFile, vFile);
1638 /* copy global & static initialisations */
1639 fprintf (asmFile, "%s", iComments2);
1640 fprintf (asmFile, "; global & static initialisations\n");
1641 fprintf (asmFile, "%s", iComments2);
1643 /* Everywhere we generate a reference to the static_name area,
1644 * (which is currently only here), we immediately follow it with a
1645 * definition of the post_static_name area. This guarantees that
1646 * the post_static_name area will immediately follow the static_name
1649 tfprintf (asmFile, "\t!area\n", port->mem.static_name); /* MOF */
1650 tfprintf (asmFile, "\t!area\n", port->mem.post_static_name);
1651 tfprintf (asmFile, "\t!area\n", port->mem.static_name);
1653 if (mainf && IFFUNC_HASBODY(mainf->type))
1655 fprintf (asmFile, "__sdcc_gsinit_startup:\n");
1656 /* if external stack is specified then the
1657 higher order byte of the xdatalocation is
1658 going into P2 and the lower order going into
1660 if (options.useXstack)
1662 fprintf (asmFile, "\tmov\tP2,#0x%02x\n",
1663 (((unsigned int) options.xdata_loc) >> 8) & 0xff);
1664 fprintf (asmFile, "\tmov\t_spx,#0x%02x\n",
1665 (unsigned int) options.xdata_loc & 0xff);
1668 /* initialise the stack pointer. JCF: aslink takes care of the location */
1669 fprintf (asmFile, "\tmov\tsp,#__start__stack - 1\n"); /* MOF */
1671 fprintf (asmFile, "\tlcall\t__sdcc_external_startup\n");
1672 fprintf (asmFile, "\tmov\ta,dpl\n");
1673 fprintf (asmFile, "\tjz\t__sdcc_init_data\n");
1674 fprintf (asmFile, "\tljmp\t__sdcc_program_startup\n");
1675 fprintf (asmFile, "__sdcc_init_data:\n");
1677 // if the port can copy the XINIT segment to XISEG
1678 if (port->genXINIT) {
1679 port->genXINIT(asmFile);
1683 copyFile (asmFile, statsg->oFile);
1685 if (port->general.glue_up_main && mainf && IFFUNC_HASBODY(mainf->type))
1687 /* This code is generated in the post-static area.
1688 * This area is guaranteed to follow the static area
1689 * by the ugly shucking and jiving about 20 lines ago.
1691 tfprintf (asmFile, "\t!area\n", port->mem.post_static_name);
1692 fprintf (asmFile, "\tljmp\t__sdcc_program_startup\n");
1698 "%s", iComments2, iComments2);
1699 tfprintf (asmFile, "\t!areahome\n", HOME_NAME);
1700 copyFile (asmFile, home->oFile);
1702 /* copy over code */
1703 fprintf (asmFile, "%s", iComments2);
1704 fprintf (asmFile, "; code\n");
1705 fprintf (asmFile, "%s", iComments2);
1706 tfprintf (asmFile, "\t!areacode\n", CODE_NAME);
1707 if (mainf && IFFUNC_HASBODY(mainf->type))
1710 /* entry point @ start of CSEG */
1711 fprintf (asmFile, "__sdcc_program_startup:\n");
1713 /* put in the call to main */
1714 fprintf (asmFile, "\tlcall\t_main\n");
1715 if (options.mainreturn)
1718 fprintf (asmFile, ";\treturn from main ; will return to caller\n");
1719 fprintf (asmFile, "\tret\n");
1725 fprintf (asmFile, ";\treturn from main will lock up\n");
1726 fprintf (asmFile, "\tsjmp .\n");
1729 copyFile (asmFile, code->oFile);
1731 if (port->genAssemblerEnd) {
1732 port->genAssemblerEnd(asmFile);
1740 /** Creates a temporary file with unoque file name
1742 - TMP, TEMP, TMPDIR env. varibles
1743 - if Un*x system: /usr/tmp and /tmp
1744 - root directory using mkstemp() if avaliable
1745 - default location using tempnam()
1748 tempfileandname(char *fname, size_t len)
1750 #define TEMPLATE "sdccXXXXXX"
1751 #define TEMPLATE_LEN ((sizeof TEMPLATE) - 1)
1753 const char *tmpdir = NULL;
1756 if ((tmpdir = getenv ("TMP")) == NULL)
1757 if ((tmpdir = getenv ("TEMP")) == NULL)
1758 tmpdir = getenv ("TMPDIR");
1762 /* try with /usr/tmp and /tmp on Un*x systems */
1763 struct stat statbuf;
1765 if (tmpdir == NULL) {
1766 if (stat("/usr/tmp", &statbuf) != -1)
1767 tmpdir = "/usr/tmp";
1768 else if (stat("/tmp", &statbuf) != -1)
1776 char fnamebuf[PATH_MAX];
1779 if (fname == NULL || len == 0) {
1781 len = sizeof fnamebuf;
1785 name_len = strlen(tmpdir) + 1 + TEMPLATE_LEN;
1787 assert(name_len < len);
1788 if (!(name_len < len)) /* in NDEBUG is defined */
1789 return -1; /* buffer too small, temporary file can not be created */
1791 sprintf(fname, "%s" DIR_SEPARATOR_STRING TEMPLATE, tmpdir);
1794 name_len = TEMPLATE_LEN;
1796 assert(name_len < len);
1797 if (!(name_len < len)) /* in NDEBUG is defined */
1798 return -1; /* buffer too small, temporary file can not be created */
1800 strcpy(fname, TEMPLATE);
1803 fd = mkstemp(fname);
1807 char *name = tempnam(tmpdir, "sdcc");
1810 perror("Can't create temporary file name");
1814 assert(strlen(name) < len);
1815 if (!(strlen(name) < len)) /* in NDEBUG is defined */
1816 return -1; /* buffer too small, temporary file can not be created */
1818 strcpy(fname, name);
1820 fd = open(name, O_CREAT | O_EXCL | O_RDWR, S_IREAD | S_IWRITE);
1822 fd = open(name, O_CREAT | O_EXCL | O_RDWR, S_IRUSR | S_IWUSR);
1828 perror("Can't create temporary file");
1836 /** Create a temporary file name
1842 static char fnamebuf[PATH_MAX];
1844 if ((fd = tempfileandname(fnamebuf, sizeof fnamebuf)) == -1) {
1845 fprintf(stderr, "Can't create temporary file name!");
1856 /** Create a temporary file and add it to tmpfileNameSet,
1857 so that it is removed explicitly by rm_tmpfiles()
1858 or implicitly at program extit.
1866 char fnamebuf[PATH_MAX];
1868 if ((fd = tempfileandname(fnamebuf, sizeof fnamebuf)) == -1) {
1869 fprintf(stderr, "Can't create temporary file!");
1873 tmp = Safe_strdup(fnamebuf);
1875 addSetHead(&tmpfileNameSet, tmp);
1877 if ((fp = fdopen(fd, "w+b")) == NULL) {
1878 perror("Can't create temporary file!");